From 16b51b9c2f0899fa6488ed84291061d0875af6c0 Mon Sep 17 00:00:00 2001 From: Neil Rashbrook Date: Fri, 21 Feb 2014 00:17:13 +0000 Subject: [PATCH] Bug 956657 Share more charset menu code between the view source window and the browser r=Unfocused --- browser/base/content/browser-charsetmenu.inc | 12 +- browser/base/content/browser.js | 99 ++----------- .../viewsource/content/viewSource.js | 77 +--------- .../viewsource/content/viewSource.xul | 7 +- toolkit/modules/CharsetMenu.jsm | 135 ++++++++++-------- 5 files changed, 101 insertions(+), 229 deletions(-) diff --git a/browser/base/content/browser-charsetmenu.inc b/browser/base/content/browser-charsetmenu.inc index 379e95780955..4153bb18d97c 100644 --- a/browser/base/content/browser-charsetmenu.inc +++ b/browser/base/content/browser-charsetmenu.inc @@ -2,20 +2,18 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -#filter substitution - -#expand + onpopupshown="UpdateCurrentCharset(this);"> diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 3525f3a170e4..8abd9c7a9b08 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -5139,55 +5139,15 @@ function handleDroppedLink(event, url, name) event.preventDefault(); }; -function MultiplexHandler(event) -{ try { - var node = event.target; - var name = node.getAttribute('name'); - - if (name == 'detectorGroup') { - BrowserCharsetReload(); - SelectDetector(event, false); - } else if (name == 'charsetGroup') { - var charset = node.getAttribute('id'); - charset = charset.substring(charset.indexOf('charset.') + 'charset.'.length); - BrowserSetForcedCharacterSet(charset); - } else if (name == 'charsetCustomize') { - //do nothing - please remove this else statement, once the charset prefs moves to the pref window - } else { - BrowserSetForcedCharacterSet(node.getAttribute('id')); - } - } catch(ex) { alert(ex); } -} - -function SelectDetector(event, doReload) -{ - var uri = event.target.getAttribute("id"); - var prefvalue = uri.substring(uri.indexOf('chardet.') + 'chardet.'.length); - if ("off" == prefvalue) { // "off" is special value to turn off the detectors - prefvalue = ""; - } - - try { - var str = Cc["@mozilla.org/supports-string;1"]. - createInstance(Ci.nsISupportsString); - - str.data = prefvalue; - gPrefService.setComplexValue("intl.charset.detector", Ci.nsISupportsString, str); - if (doReload) - window.content.location.reload(); - } - catch (ex) { - dump("Failed to set the intl.charset.detector preference.\n"); - } -} - function BrowserSetForcedCharacterSet(aCharset) { - gBrowser.docShell.gatherCharsetMenuTelemetry(); - gBrowser.docShell.charset = aCharset; - // Save the forced character-set - if (!PrivateBrowsingUtils.isWindowPrivate(window)) - PlacesUtils.setCharsetForURI(getWebNavigation().currentURI, aCharset); + if (aCharset) { + gBrowser.docShell.gatherCharsetMenuTelemetry(); + gBrowser.docShell.charset = aCharset; + // Save the forced character-set + if (!PrivateBrowsingUtils.isWindowPrivate(window)) + PlacesUtils.setCharsetForURI(getWebNavigation().currentURI, aCharset); + } BrowserCharsetReload(); } @@ -5196,8 +5156,8 @@ function BrowserCharsetReload() BrowserReloadWithFlags(nsIWebNavigation.LOAD_FLAGS_CHARSET_CHANGE); } -function charsetMenuGetElement(parent, id) { - return parent.getElementsByAttribute("id", id)[0]; +function charsetMenuGetElement(parent, charset) { + return parent.getElementsByAttribute("charset", charset)[0]; } function UpdateCurrentCharset(target) { @@ -5207,54 +5167,19 @@ function UpdateCurrentCharset(target) { // Uncheck previous item if (gPrevCharset) { - var pref_item = charsetMenuGetElement(target, "charset." + gPrevCharset); + var pref_item = charsetMenuGetElement(target, gPrevCharset); if (pref_item) pref_item.setAttribute('checked', 'false'); } - var menuitem = charsetMenuGetElement(target, "charset." + FoldCharset(wnd.document.characterSet)); + var menuitem = charsetMenuGetElement(target, CharsetMenu.foldCharset(wnd.document.characterSet)); if (menuitem) { menuitem.setAttribute('checked', 'true'); } } -function FoldCharset(charset) { - // For substantially similar encodings, treat two encodings as the same - // for the purpose of the check mark. - if (charset == "ISO-8859-8-I") { - return "windows-1255"; - } - - if (charset == "gb18030") { - return "gbk"; - } - - return charset; -} - -function UpdateCharsetDetector(target) { - var prefvalue; - - try { - prefvalue = gPrefService.getComplexValue("intl.charset.detector", Ci.nsIPrefLocalizedString).data; - } - catch (ex) {} - - if (!prefvalue) - prefvalue = "off"; - - var menuitem = charsetMenuGetElement(target, "chardet." + prefvalue); - if (menuitem) - menuitem.setAttribute("checked", "true"); -} - -function UpdateMenus(event) { - UpdateCurrentCharset(event.target); - UpdateCharsetDetector(event.target); -} - function charsetLoadListener() { - var charset = FoldCharset(window.content.document.characterSet); + var charset = CharsetMenu.fold(window.content.document.characterSet); if (charset.length > 0 && (charset != gLastBrowserCharset)) { gPrevCharset = gLastBrowserCharset; diff --git a/toolkit/components/viewsource/content/viewSource.js b/toolkit/components/viewsource/content/viewSource.js index 715cbfabc1d2..f22efe19398f 100644 --- a/toolkit/components/viewsource/content/viewSource.js +++ b/toolkit/components/viewsource/content/viewSource.js @@ -657,84 +657,13 @@ function BrowserCharsetReload() } } -function BrowserSetForcedCharacterSet(aCharset) +function BrowserSetCharacterSet(aEvent) { - gBrowser.docShell.charset = aCharset; + if (aEvent.target.hasAttribute("charset")) + gBrowser.docShell.charset = aEvent.target.getAttribute("charset"); BrowserCharsetReload(); } -function MultiplexHandler(event) -{ - var node = event.target; - var name = node.getAttribute("name"); - - if (name == "detectorGroup") { - SelectDetector(event); - BrowserCharsetReload(); - } else if (name == "charsetGroup") { - var charset = node.getAttribute("id"); - charset = charset.substring(charset.indexOf("charset.") + "charset.".length); - BrowserSetForcedCharacterSet(charset); - } -} - -function SelectDetector(event) -{ - var uri = event.target.getAttribute("id"); - var prefvalue = uri.substring(uri.indexOf("chardet.") + "chardet.".length); - if ("off" == prefvalue) { // "off" is special value to turn off the detectors - prefvalue = ""; - } - - try { - var str = Cc["@mozilla.org/supports-string;1"]. - createInstance(Ci.nsISupportsString); - str.data = prefvalue; - gPrefService.setComplexValue("intl.charset.detector", Ci.nsISupportsString, str); - } - catch (ex) { - dump("Failed to set the intl.charset.detector preference.\n"); - } -} - -function FoldCharset(charset) { - // For substantially similar encodings, treat two encodings as the same - // for the purpose of the check mark. - if (charset == "ISO-8859-8-I") { - return "windows-1255"; - } else if (charset == "gb18030") { - return "gbk"; - } - return charset; -} - -function UpdateCurrentCharset() { - var menuitem = document.getElementById("charset." + FoldCharset(content.document.characterSet)); - if (menuitem) - menuitem.setAttribute("checked", "true"); -} - -function UpdateCharsetDetector() { - var prefvalue; - - try { - prefvalue = gPrefService.getComplexValue("intl.charset.detector", Ci.nsIPrefLocalizedString).data; - } - catch (ex) {} - - if (!prefvalue) - prefvalue = "off"; - - var menuitem = document.getElementById("chardet." + prefvalue); - if (menuitem) - menuitem.setAttribute("checked", "true"); -} - -function UpdateMenus() { - UpdateCurrentCharset(); - UpdateCharsetDetector(); -} - function BrowserForward(aEvent) { try { gBrowser.goForward(); diff --git a/toolkit/components/viewsource/content/viewSource.xul b/toolkit/components/viewsource/content/viewSource.xul index 3fcb57efb245..6dbc87870144 100644 --- a/toolkit/components/viewsource/content/viewSource.xul +++ b/toolkit/components/viewsource/content/viewSource.xul @@ -201,11 +201,10 @@ - - + onpopupshown="CharsetMenu.update(event, content.document.characterSet);"> + kEncodings.delete(x)); +function CharsetComparator(a, b) { + // Normal sorting sorts the part in parenthesis in an order that + // happens to make the less frequently-used items first. + let titleA = a.label.replace(/\(.*/, "") + b.value; + let titleB = b.label.replace(/\(.*/, "") + a.value; + // Secondarily reverse sort by encoding name to sort "windows" or + // "shift_jis" first. + return titleA.localeCompare(titleB) || b.value.localeCompare(a.value); +} + +function SetDetector(event) { + let str = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString); + str.data = event.target.getAttribute("detector"); + Services.prefs.setComplexValue("intl.charset.detector", Ci.nsISupportsString, str); +} + +function UpdateDetectorMenu(event) { + event.stopPropagation(); + let detector = Services.prefs.getComplexValue("intl.charset.detector", Ci.nsIPrefLocalizedString); + let menuitem = this.getElementsByAttribute("detector", detector).item(0); + if (menuitem) { + menuitem.setAttribute("checked", "true"); + } +} let gDetectorInfoCache, gCharsetInfoCache, gPinnedInfoCache; let CharsetMenu = { - build: function(parent, idPrefix="", showAccessKeys=true) { + build: function(parent, showAccessKeys=true, showDetector=true) { function createDOMNode(doc, nodeInfo) { let node = doc.createElement("menuitem"); node.setAttribute("type", "radio"); - node.setAttribute("name", nodeInfo.name); + node.setAttribute("name", nodeInfo.name + "Group"); + node.setAttribute(nodeInfo.name, nodeInfo.value); node.setAttribute("label", nodeInfo.label); if (showAccessKeys && nodeInfo.accesskey) { node.setAttribute("accesskey", nodeInfo.accesskey); } - if (idPrefix) { - node.id = idPrefix + nodeInfo.id; - } else { - node.id = nodeInfo.id; - } return node; } - if (parent.childElementCount > 0) { + if (parent.hasChildNodes()) { // Detector menu or charset menu already built return; } + this._ensureDataReady(); let doc = parent.ownerDocument; - let menuNode = doc.createElement("menu"); - menuNode.setAttribute("label", gBundle.GetStringFromName("charsetMenuAutodet")); - if (showAccessKeys) { - menuNode.setAttribute("accesskey", gBundle.GetStringFromName("charsetMenuAutodet.key")); + if (showDetector) { + let menuNode = doc.createElement("menu"); + menuNode.setAttribute("label", gBundle.GetStringFromName("charsetMenuAutodet")); + if (showAccessKeys) { + menuNode.setAttribute("accesskey", gBundle.GetStringFromName("charsetMenuAutodet.key")); + } + parent.appendChild(menuNode); + + let menuPopupNode = doc.createElement("menupopup"); + menuNode.appendChild(menuPopupNode); + menuPopupNode.addEventListener("command", SetDetector); + menuPopupNode.addEventListener("popupshown", UpdateDetectorMenu); + + gDetectorInfoCache.forEach(detectorInfo => menuPopupNode.appendChild(createDOMNode(doc, detectorInfo))); + parent.appendChild(doc.createElement("menuseparator")); } - parent.appendChild(menuNode); - let menuPopupNode = doc.createElement("menupopup"); - menuNode.appendChild(menuPopupNode); - - this._ensureDataReady(); - gDetectorInfoCache.forEach(detectorInfo => menuPopupNode.appendChild(createDOMNode(doc, detectorInfo))); - parent.appendChild(doc.createElement("menuseparator")); gPinnedInfoCache.forEach(charsetInfo => parent.appendChild(createDOMNode(doc, charsetInfo))); parent.appendChild(doc.createElement("menuseparator")); gCharsetInfoCache.forEach(charsetInfo => parent.appendChild(createDOMNode(doc, charsetInfo))); @@ -147,58 +172,30 @@ let CharsetMenu = { if (!gDetectorInfoCache) { gDetectorInfoCache = this.getDetectorInfo(); gPinnedInfoCache = this.getCharsetInfo(kPinned, false); - gCharsetInfoCache = this.getCharsetInfo([...kEncodings]); + gCharsetInfoCache = this.getCharsetInfo(kEncodings); } }, getDetectorInfo: function() { return kAutoDetectors.map(([detectorName, nodeId]) => ({ - id: "chardet." + nodeId, label: this._getDetectorLabel(detectorName), accesskey: this._getDetectorAccesskey(detectorName), - name: "detectorGroup", + name: "detector", + value: nodeId })); }, getCharsetInfo: function(charsets, sort=true) { - let list = charsets.map(charset => ({ - id: "charset." + charset, + let list = [{ label: this._getCharsetLabel(charset), accesskey: this._getCharsetAccessKey(charset), - name: "charsetGroup", - })); + name: "charset", + value: charset + } for (charset of charsets)]; - if (!sort) { - return list; + if (sort) { + list.sort(CharsetComparator); } - - list.sort(function (a, b) { - let titleA = a.label; - let titleB = b.label; - // Normal sorting sorts the part in parenthesis in an order that - // happens to make the less frequently-used items first. - let index; - if ((index = titleA.indexOf("(")) > -1) { - titleA = titleA.substring(0, index); - } - if ((index = titleB.indexOf("(")) > -1) { - titleA = titleB.substring(0, index); - } - let comp = titleA.localeCompare(titleB); - if (comp) { - return comp; - } - // secondarily reverse sort by encoding name to sort "windows" or - // "shift_jis" first. This works regardless of localization, because - // the ids aren't localized. - if (a.id < b.id) { - return 1; - } - if (b.id < a.id) { - return -1; - } - return 0; - }); return list; }, @@ -235,6 +232,30 @@ let CharsetMenu = { } catch (ex) {} return ""; }, + + /** + * For substantially similar encodings, treat two encodings as the same + * for the purpose of the check mark. + */ + foldCharset: function(charset) { + switch (charset) { + case "ISO-8859-8-I": + return "windows-1255"; + + case "gb18030": + return "gbk"; + + default: + return charset; + } + }, + + update: function(event, charset) { + let menuitem = event.target.getElementsByAttribute("charset", this.foldCharset(charset)).item(0); + if (menuitem) { + menuitem.setAttribute("checked", "true"); + } + }, }; Object.freeze(CharsetMenu);