1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5function watchForTag(tagName, cb) { 6 if (!document.body) 7 return; 8 9 function findChildTags(queryNode) { 10 $Array.forEach(queryNode.querySelectorAll(tagName), function(node) { 11 cb(node); 12 }); 13 } 14 // Query tags already in the document. 15 findChildTags(document.body); 16 17 // Observe the tags added later. 18 var documentObserver = new MutationObserver(function(mutations) { 19 $Array.forEach(mutations, function(mutation) { 20 $Array.forEach(mutation.addedNodes, function(addedNode) { 21 if (addedNode.nodeType == Node.ELEMENT_NODE) { 22 if (addedNode.tagName == tagName) 23 cb(addedNode); 24 findChildTags(addedNode); 25 } 26 }); 27 }); 28 }); 29 documentObserver.observe(document, {subtree: true, childList: true}); 30} 31 32// Expose a function to watch the |tagName| introduction via mutation observer. 33// 34// We employee mutation observer to watch on any introduction of |tagName| 35// within document so that we may handle it accordingly (either creating it or 36// reporting error due to lack of permission). 37// Think carefully about when to call this. On one hand, mutation observer 38// functions on document, so we need to make sure document is finished 39// parsing. To satisfy this, document.readyState has to be "interactive" or 40// after. On the other hand, we intend to do this as early as possible so that 41// developer would have no chance to bring in any conflicted property. To meet 42// this requirement, we choose "readystatechange" event of window and use 43// capturing way. 44function addTagWatcher(tagName, cb) { 45 var useCapture = true; 46 window.addEventListener('readystatechange', function listener(event) { 47 if (document.readyState == 'loading') 48 return; 49 50 watchForTag(tagName, cb); 51 window.removeEventListener(event.type, listener, useCapture); 52 }, useCapture); 53} 54 55exports.addTagWatcher = addTagWatcher; 56