commit b919d27d1e3b43d5bb488400890aa5fda55e95b8
parent f9978e8f026fa16315a76cfe3359bfef27de4f46
Author: aurimasv <aurimas.dev@gmail.com>
Date: Tue, 29 Jan 2013 03:25:05 -0600
Allow web translators to monitor DOM nodes for changes in order to re-trigger detectWeb
Diffstat:
2 files changed, 62 insertions(+), 9 deletions(-)
diff --git a/chrome/content/zotero/browser.js b/chrome/content/zotero/browser.js
@@ -46,6 +46,7 @@ var Zotero_Browser = new function() {
this.toggleCollapsed = toggleCollapsed;
this.chromeLoad = chromeLoad;
this.contentLoad = contentLoad;
+ this.itemUpdated = itemUpdated;
this.contentHide = contentHide;
this.tabClose = tabClose;
this.resize = resize;
@@ -344,7 +345,7 @@ var Zotero_Browser = new function() {
if(isHTML) {
var contentWin = doc.defaultView;
if(!contentWin.haveZoteroEventListener) {
- contentWin.addEventListener("ZoteroItemUpdated", itemUpdated, false);
+ contentWin.addEventListener("ZoteroItemUpdated", function(event) { itemUpdated(event.originalTarget) }, false);
contentWin.haveZoteroEventListener = true;
}
}
@@ -380,14 +381,13 @@ var Zotero_Browser = new function() {
/**
* Called when item should be updated due to a DOM event
*/
- function itemUpdated(event) {
+ function itemUpdated(doc) {
try {
- var doc = event.originalTarget;
- var rootDoc = (doc instanceof HTMLDocument ? doc.defaultView.top.document : doc);
- var browser = Zotero_Browser.tabbrowser.getBrowserForDocument(rootDoc);
- var tab = _getTabObject(browser);
- if(doc == tab.page.document || doc == rootDoc) tab.clear();
- tab.detectTranslators(rootDoc, doc);
+ var rootDoc = (doc instanceof HTMLDocument ? doc.defaultView.top.document : doc);
+ var browser = Zotero_Browser.tabbrowser.getBrowserForDocument(rootDoc);
+ var tab = _getTabObject(browser);
+ if(doc == tab.page.document || doc == rootDoc) tab.clear();
+ tab.detectTranslators(rootDoc, doc);
} catch(e) {
Zotero.debug(e);
}
@@ -649,6 +649,7 @@ Zotero_Browser.Tab.prototype.detectTranslators = function(rootDoc, doc) {
var translate = new Zotero.Translate.Web();
translate.setDocument(doc);
translate.setHandler("translators", function(obj, item) { me._translatorsAvailable(obj, item) });
+ translate.setHandler("pageModified", function(translate, doc) { Zotero_Browser.itemUpdated(doc) });
translate.getTranslators(true);
} else if(doc.documentURI.substr(0, 7) == "file://") {
this._attemptLocalFileImport(doc);
diff --git a/chrome/content/zotero/xpcom/translation/translate.js b/chrome/content/zotero/xpcom/translation/translate.js
@@ -635,6 +635,52 @@ Zotero.Translate.Sandbox = {
// call super
Zotero.Translate.Sandbox.Base._itemDone(translate, item);
+ },
+
+ /**
+ * Tells Zotero to monitor changes to the DOM and re-trigger detectWeb
+ * Can only be set during the detectWeb call
+ * @param {DOMNode} target Document node to monitor for changes
+ * @param {MutationObserverInit} [config] specifies which DOM mutations should be reported
+ */
+ "monitorDOMChanges":function(translate, target, config) {
+ if(translate._currentState != "detect") {
+ Zotero.debug("Translate: monitorDOMChanges can only be called during the 'detect' stage");
+ return;
+ }
+
+ var window = translate.document.defaultView
+ var mutationObserver = window && ( window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver );
+ if(!mutationObserver) {
+ Zotero.debug("Translate: This browser does not support mutation observers.");
+ return;
+ }
+
+ var translator = translate._potentialTranslators[0];
+ if(!translate._registeredDOMObservers[translator.translatorID])
+ translate._registeredDOMObservers[translator.translatorID] = [];
+ var obs = translate._registeredDOMObservers[translator.translatorID];
+
+ //do not re-register observer by the same translator for the same node
+ if(obs.indexOf(target) != -1) {
+ Zotero.debug("Translate: Already monitoring this node");
+ return;
+ }
+
+ obs.push(target);
+
+ var observer = new mutationObserver(function(mutations, observer) {
+ obs.splice(obs.indexOf(target),1);
+ observer.disconnect();
+
+ Zotero.debug("Translate: Page modified.");
+ //we don't really care what got updated
+ var doc = mutations[0].target.ownerDocument;
+ translate._runHandler("pageModified", doc);
+ });
+
+ observer.observe(target, config || {childList: true, subtree: true});
+ Zotero.debug("Translate: Mutation observer registered on <" + target.nodeName + "> node");
}
},
@@ -843,6 +889,11 @@ Zotero.Translate.Base.prototype = {
* complete
* passed: an array of appropriate translators
* returns: N/A
+ * pageModified
+ * valid: web
+ * called: when a web page has been modified
+ * passed: the document object for the modified page
+ * returns: N/A
* @param {Function} handler Callback function. All handlers will be passed the current
* translate instance as the first argument. The second argument is dependent on the handler.
*/
@@ -909,7 +960,7 @@ Zotero.Translate.Base.prototype = {
if(this._handlers[type]) {
// compile list of arguments
if(this._parentTranslator) {
- // if there is a parent translator, make sure we don't the Zotero.Translate
+ // if there is a parent translator, make sure we don't pass the Zotero.Translate
// object, since it could open a security hole
var args = [null];
} else {
@@ -1528,6 +1579,7 @@ Zotero.Translate.Base.prototype = {
* this Translate instance.
*/
Zotero.Translate.Web = function() {
+ this._registeredDOMObservers = {}
this.init();
}
Zotero.Translate.Web.prototype = new Zotero.Translate.Base();