Allow web translators to monitor DOM nodes for changes in order to re-trigger detectWeb
This commit is contained in:
parent
f9978e8f02
commit
b919d27d1e
2 changed files with 62 additions and 9 deletions
|
@ -46,6 +46,7 @@ var Zotero_Browser = new function() {
|
||||||
this.toggleCollapsed = toggleCollapsed;
|
this.toggleCollapsed = toggleCollapsed;
|
||||||
this.chromeLoad = chromeLoad;
|
this.chromeLoad = chromeLoad;
|
||||||
this.contentLoad = contentLoad;
|
this.contentLoad = contentLoad;
|
||||||
|
this.itemUpdated = itemUpdated;
|
||||||
this.contentHide = contentHide;
|
this.contentHide = contentHide;
|
||||||
this.tabClose = tabClose;
|
this.tabClose = tabClose;
|
||||||
this.resize = resize;
|
this.resize = resize;
|
||||||
|
@ -344,7 +345,7 @@ var Zotero_Browser = new function() {
|
||||||
if(isHTML) {
|
if(isHTML) {
|
||||||
var contentWin = doc.defaultView;
|
var contentWin = doc.defaultView;
|
||||||
if(!contentWin.haveZoteroEventListener) {
|
if(!contentWin.haveZoteroEventListener) {
|
||||||
contentWin.addEventListener("ZoteroItemUpdated", itemUpdated, false);
|
contentWin.addEventListener("ZoteroItemUpdated", function(event) { itemUpdated(event.originalTarget) }, false);
|
||||||
contentWin.haveZoteroEventListener = true;
|
contentWin.haveZoteroEventListener = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -380,14 +381,13 @@ var Zotero_Browser = new function() {
|
||||||
/**
|
/**
|
||||||
* Called when item should be updated due to a DOM event
|
* Called when item should be updated due to a DOM event
|
||||||
*/
|
*/
|
||||||
function itemUpdated(event) {
|
function itemUpdated(doc) {
|
||||||
try {
|
try {
|
||||||
var doc = event.originalTarget;
|
var rootDoc = (doc instanceof HTMLDocument ? doc.defaultView.top.document : doc);
|
||||||
var rootDoc = (doc instanceof HTMLDocument ? doc.defaultView.top.document : doc);
|
var browser = Zotero_Browser.tabbrowser.getBrowserForDocument(rootDoc);
|
||||||
var browser = Zotero_Browser.tabbrowser.getBrowserForDocument(rootDoc);
|
var tab = _getTabObject(browser);
|
||||||
var tab = _getTabObject(browser);
|
if(doc == tab.page.document || doc == rootDoc) tab.clear();
|
||||||
if(doc == tab.page.document || doc == rootDoc) tab.clear();
|
tab.detectTranslators(rootDoc, doc);
|
||||||
tab.detectTranslators(rootDoc, doc);
|
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
Zotero.debug(e);
|
Zotero.debug(e);
|
||||||
}
|
}
|
||||||
|
@ -649,6 +649,7 @@ Zotero_Browser.Tab.prototype.detectTranslators = function(rootDoc, doc) {
|
||||||
var translate = new Zotero.Translate.Web();
|
var translate = new Zotero.Translate.Web();
|
||||||
translate.setDocument(doc);
|
translate.setDocument(doc);
|
||||||
translate.setHandler("translators", function(obj, item) { me._translatorsAvailable(obj, item) });
|
translate.setHandler("translators", function(obj, item) { me._translatorsAvailable(obj, item) });
|
||||||
|
translate.setHandler("pageModified", function(translate, doc) { Zotero_Browser.itemUpdated(doc) });
|
||||||
translate.getTranslators(true);
|
translate.getTranslators(true);
|
||||||
} else if(doc.documentURI.substr(0, 7) == "file://") {
|
} else if(doc.documentURI.substr(0, 7) == "file://") {
|
||||||
this._attemptLocalFileImport(doc);
|
this._attemptLocalFileImport(doc);
|
||||||
|
|
|
@ -635,6 +635,52 @@ Zotero.Translate.Sandbox = {
|
||||||
|
|
||||||
// call super
|
// call super
|
||||||
Zotero.Translate.Sandbox.Base._itemDone(translate, item);
|
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
|
* complete
|
||||||
* passed: an array of appropriate translators
|
* passed: an array of appropriate translators
|
||||||
* returns: N/A
|
* 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
|
* @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.
|
* 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]) {
|
if(this._handlers[type]) {
|
||||||
// compile list of arguments
|
// compile list of arguments
|
||||||
if(this._parentTranslator) {
|
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
|
// object, since it could open a security hole
|
||||||
var args = [null];
|
var args = [null];
|
||||||
} else {
|
} else {
|
||||||
|
@ -1528,6 +1579,7 @@ Zotero.Translate.Base.prototype = {
|
||||||
* this Translate instance.
|
* this Translate instance.
|
||||||
*/
|
*/
|
||||||
Zotero.Translate.Web = function() {
|
Zotero.Translate.Web = function() {
|
||||||
|
this._registeredDOMObservers = {}
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
Zotero.Translate.Web.prototype = new Zotero.Translate.Base();
|
Zotero.Translate.Web.prototype = new Zotero.Translate.Base();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue