commit 9d03697591669ba1de595142e2938fd17844101c
parent ebd8dfeb65f091458b62908fcf14021776751e29
Author: Dan Stillman <dstillman@zotero.org>
Date: Mon, 4 Mar 2013 17:02:58 -0500
Merge branch '3.0' into 3.1
Diffstat:
2 files changed, 65 insertions(+), 11 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;
@@ -306,7 +307,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;
}
}
@@ -342,14 +343,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);
}
@@ -694,6 +694,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
@@ -636,6 +636,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");
}
},
@@ -844,6 +890,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.
*/
@@ -910,7 +961,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 {
@@ -1366,6 +1417,7 @@ Zotero.Translate.Base.prototype = {
this._generateSandbox();
}
+ this._currentTranslator = translator;
this._runningAsyncProcesses = 0;
this._returnValue = undefined;
this._aborted = false;
@@ -1445,8 +1497,8 @@ Zotero.Translate.Base.prototype = {
this._sandboxManager.sandbox.Zotero.isConnector = Zotero.isConnector || false;
this._sandboxManager.sandbox.Zotero.isServer = Zotero.isServer || false;
this._sandboxManager.sandbox.Zotero.parentTranslator = this._parentTranslator
- && this._parentTranslator.translator && this._parentTranslator.translator[0] ?
- this._parentTranslator.translator[0].translatorID : null;
+ && this._parentTranslator._currentTranslator ?
+ this._parentTranslator._currentTranslator.translatorID : null;
// create shortcuts
this._sandboxManager.sandbox.Z = this._sandboxManager.sandbox.Zotero;
@@ -1533,6 +1585,7 @@ Zotero.Translate.Base.prototype = {
* this Translate instance.
*/
Zotero.Translate.Web = function() {
+ this._registeredDOMObservers = {}
this.init();
}
Zotero.Translate.Web.prototype = new Zotero.Translate.Base();