diff --git a/chrome/content/zotero/xpcom/translation/translate.js b/chrome/content/zotero/xpcom/translation/translate.js index c521fc3093..4cbb049793 100644 --- a/chrome/content/zotero/xpcom/translation/translate.js +++ b/chrome/content/zotero/xpcom/translation/translate.js @@ -240,7 +240,7 @@ Zotero.Translate.Sandbox = { if(!Zotero.isBookmarklet) arg = JSON.parse(JSON.stringify(arg)); return translation.setSearch(arg); }; - safeTranslator.setDocument = function(arg) { return translation.setDocument(arg) }; + safeTranslator.setDocument = function(arg) { return translation.setDocument(new XPCNativeWrapper(arg)) }; var errorHandlerSet = false; safeTranslator.setHandler = function(arg1, arg2) { if(arg1 === "error") errorHandlerSet = true; @@ -249,14 +249,6 @@ Zotero.Translate.Sandbox = { try { item = item.wrappedJSObject ? item.wrappedJSObject : item; if(arg1 == "itemDone") { - var sbZotero = translate._sandboxManager.sandbox.Zotero; - if(sbZotero.wrappedJSObject) sbZotero = sbZotero.wrappedJSObject; - if(Zotero.isFx && !Zotero.isBookmarklet - && (translate instanceof Zotero.Translate.Web - || translate instanceof Zotero.Translate.Search)) { - // Necessary to get around object wrappers in Firefox - item = translate._sandboxManager._copyObject(item); - } item.complete = translate._sandboxZotero.Item.prototype.complete; } arg2(obj, item); @@ -346,7 +338,6 @@ Zotero.Translate.Sandbox = { if(!Zotero.Utilities.isEmpty(sandbox.exports)) { sandbox.exports.Zotero = sandbox.Zotero; sandbox = sandbox.exports; - if(Zotero.isFx && sandbox.wrappedJSObject) sandbox = sandbox.wrappedJSObject; } else { translate._debug("COMPAT WARNING: "+translation.translator[0].label+" does "+ "not export any properties. Only detect"+translation._entryFunctionSuffix+ @@ -389,10 +380,11 @@ Zotero.Translate.Sandbox = { if(Zotero.isFx && Zotero.platformMajorVersion >= 33) { for(var i in safeTranslator) { if (typeof(safeTranslator[i]) === "function") { - var func = safeTranslator[i]; - safeTranslator[i] = translate._sandboxManager._makeContentForwarder(function() { - func.apply(safeTranslator, this.args.wrappedJSObject); - }); + safeTranslator[i] = translate._sandboxManager._makeContentForwarder(function(func) { + return function() { + func.apply(safeTranslator, this.args.wrappedJSObject); + } + }(safeTranslator[i])); } } } @@ -442,7 +434,7 @@ Zotero.Translate.Sandbox = { */ "selectItems":function(translate, items, callback) { function transferObject(obj) { - return Zotero.isFx ? translate._sandboxManager._copyObject(obj) : obj; + return Zotero.isFx ? translate._sandboxManager.copyObject(obj) : obj; } if(Zotero.Utilities.isEmpty(items)) { @@ -1502,7 +1494,11 @@ Zotero.Translate.Base.prototype = { */ "_generateSandbox":function() { Zotero.debug("Translate: Binding sandbox to "+(typeof this._sandboxLocation == "object" ? this._sandboxLocation.document.location : this._sandboxLocation), 4); - this._sandboxManager = new Zotero.Translate.SandboxManager(this._sandboxLocation); + if (this._parentTranslator && this._parentTranslator._sandboxManager.newChild) { + this._sandboxManager = this._parentTranslator._sandboxManager.newChild(); + } else { + this._sandboxManager = new Zotero.Translate.SandboxManager(this._sandboxLocation); + } const createArrays = "['creators', 'notes', 'tags', 'seeAlso', 'attachments']"; var src = "var Zotero = {};"+ "Zotero.Item = function (itemType) {"+ @@ -2274,7 +2270,7 @@ Zotero.Translate.Search.prototype.complete = function(returnValue, error) { */ Zotero.Translate.Search.prototype._getParameters = function() { if(Zotero.isFx) { - return [this._sandboxManager._copyObject(this.search)]; + return [this._sandboxManager.copyObject(this.search)]; } return [this.search]; }; diff --git a/chrome/content/zotero/xpcom/translation/translate_firefox.js b/chrome/content/zotero/xpcom/translation/translate_firefox.js index b2de56159f..c3f69cfdf0 100644 --- a/chrome/content/zotero/xpcom/translation/translate_firefox.js +++ b/chrome/content/zotero/xpcom/translation/translate_firefox.js @@ -471,13 +471,13 @@ Zotero.Translate.SandboxManager.prototype = { } } if(passAsFirstArgument) args.unshift(passAsFirstArgument); - return me._copyObject(object[localKey].apply(object, args)); + return me.copyObject(object[localKey].apply(object, args)); }); } else { attachTo[localKey] = function() { var args = Array.prototype.slice.apply(arguments); if(passAsFirstArgument) args.unshift(passAsFirstArgument); - return me._copyObject(object[localKey].apply(object, args)); + return me.copyObject(object[localKey].apply(object, args)); }; } } else { @@ -514,7 +514,7 @@ Zotero.Translate.SandboxManager.prototype = { * @param {Object} obj * @return {Object} */ - "_copyObject":function(obj, wm) { + "copyObject":function(obj, wm) { if(!this._canCopy(obj)) return obj; if(!wm) wm = new WeakMap(); var obj2 = (obj.constructor.name === "Array" ? this.sandbox.Array() : this.sandbox.Object()); @@ -526,7 +526,7 @@ Zotero.Translate.SandboxManager.prototype = { if(this._canCopy(prop1)) { var prop2 = wm.get(prop1); if(prop2 === undefined) { - prop2 = this._copyObject(prop1, wm); + prop2 = this.copyObject(prop1, wm); wm.set(prop1, prop2); } wobj2[i] = prop2; @@ -535,6 +535,53 @@ Zotero.Translate.SandboxManager.prototype = { } } return obj2; + }, + + "newChild":function() { + return new Zotero.Translate.ChildSandboxManager(this); + } +} + +Zotero.Translate.ChildSandboxManager = function(parent) { + this._wrappedSandbox = new parent.sandbox.Object(); + this._wrappedSandbox.Zotero = new parent.sandbox.Object(); + this.sandbox = this._wrappedSandbox.wrappedJSObject; + this._parent = parent; +} +Zotero.Translate.ChildSandboxManager.prototype = { + "eval":function(code, functions, path) { + // eval in sandbox scope + if(functions) { + for(var i = 0; i < functions.length; i++) { + delete this.sandbox[functions[i]]; + } + } + this._parent.sandbox._withSandbox = this._wrappedSandbox; + Components.utils.evalInSandbox("with(_withSandbox){"+code+"};", this._parent.sandbox, "1.8", path, 1); + if(functions) { + for(var i = 0; i < functions.length; i++) { + try { + this._wrappedSandbox[functions[i]] = Components.utils.evalInSandbox(functions[i], this._parent.sandbox); + } catch(e) {} + } + } + this._parent.sandbox._withSandbox = undefined; + }, + "importObject":function(object, passAsFirstArgument, attachTo) { + if(!attachTo) attachTo = this.sandbox.Zotero; + // Zotero.debug(object); + // Zotero.debug(attachTo); + this._parent.importObject(object, passAsFirstArgument, attachTo); + // Zotero.debug(attachTo); + }, + "copyObject":function(obj) { + return this._parent.copyObject(obj); + }, + "newChild":function() { + return this._parent.newChild(); + }, + "_makeContentForwarder":function(f) { + return this._parent._makeContentForwarder(f); } }