From e36c97536658cdcdae9f3010c31c60126c2b6da1 Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Sun, 27 May 2012 13:30:06 -0400 Subject: [PATCH] Create a node in a DOM document and use it to implement the same unescape technique in Firefox as we currently use in the connectors. This may cause some data mismatches initially. --- chrome/content/zotero/xpcom/utilities.js | 75 ++++++++++++++++-------- 1 file changed, 50 insertions(+), 25 deletions(-) diff --git a/chrome/content/zotero/xpcom/utilities.js b/chrome/content/zotero/xpcom/utilities.js index ada58a34c..1a5e3a4a3 100644 --- a/chrome/content/zotero/xpcom/utilities.js +++ b/chrome/content/zotero/xpcom/utilities.js @@ -339,33 +339,58 @@ Zotero.Utilities = { * Decodes HTML entities within a string, returning plain text * @type String */ - "unescapeHTML":function(/**String*/ str) { - // If no tags, no need to unescape - if(str.indexOf("<") === -1 && str.indexOf("&") === -1) return str; + "unescapeHTML":new function() { + var nsIScriptableUnescapeHTML, node; - if(Zotero.isFx && !Zotero.isBookmarklet) { - if(!Zotero.Utilities._nsISUHTML) { - Zotero.Utilities._nsISUHTML = Components.classes["@mozilla.org/feed-unescapehtml;1"] - .getService(Components.interfaces.nsIScriptableUnescapeHTML); - } - return Zotero.Utilities._nsISUHTML.unescape(str); - } else if(Zotero.isNode) { - /*var doc = require('jsdom').jsdom(str, null, { - "features":{ - "FetchExternalResources":false, - "ProcessExternalResources":false, - "MutationEvents":false, - "QuerySelector":false + return function(/**String*/ str) { + // If no tags, no need to unescape + if(str.indexOf("<") === -1 && str.indexOf("&") === -1) return str; + + if(Zotero.isFx && !Zotero.isBookmarklet) { + // Create a node and use the textContent property to do unescaping where + // possible, because this approach preserves
+ if(node === undefined) { + var platformVersion = Components.classes["@mozilla.org/xre/app-info;1"] + .getService(Components.interfaces.nsIXULAppInfo).platformVersion; + if(Components.classes["@mozilla.org/xpcom/version-comparator;1"] + .getService(Components.interfaces.nsIVersionComparator) + .compare(platformVersion, "12.0") >= 0) { + var parser = Components.classes["@mozilla.org/xmlextras/domparser;1"] + .createInstance(Components.interfaces.nsIDOMParser); + domDocument = parser.parseFromString("", + "text/html"); + node = domDocument.createElement("div"); + } else { + node = false; + } } - }); - if(!doc.documentElement) return str; - return doc.documentElement.textContent;*/ - return Zotero.Utilities.cleanTags(str); - } else { - var node = document.createElement("div"); - node.innerHTML = str; - return ("innerText" in node ? node.innerText : node.textContent).replace(/ {2,}/g, " "); - } + + if(!node) { + node.innerHTML = str; + return node.textContent.replace(/ {2,}/g, " "); + } else if(!nsIScriptableUnescapeHTML) { + nsIScriptableUnescapeHTML = Components.classes["@mozilla.org/feed-unescapehtml;1"] + .getService(Components.interfaces.nsIScriptableUnescapeHTML); + } + return nsIScriptableUnescapeHTML.unescape(str); + } else if(Zotero.isNode) { + /*var doc = require('jsdom').jsdom(str, null, { + "features":{ + "FetchExternalResources":false, + "ProcessExternalResources":false, + "MutationEvents":false, + "QuerySelector":false + } + }); + if(!doc.documentElement) return str; + return doc.documentElement.textContent;*/ + return Zotero.Utilities.cleanTags(str); + } else { + if(!node) node = document.createElement("div"); + node.innerHTML = str; + return ("innerText" in node ? node.innerText : node.textContent).replace(/ {2,}/g, " "); + } + }; }, /**