1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/addon-sdk/source/lib/sdk/l10n/html.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,111 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 +"use strict"; 1.8 + 1.9 +module.metadata = { 1.10 + "stability": "unstable" 1.11 +}; 1.12 + 1.13 +const { Ci, Cu } = require("chrome"); 1.14 +const events = require("../system/events"); 1.15 +const core = require("./core"); 1.16 + 1.17 +const assetsURI = require('../self').data.url(); 1.18 +const { Services } = Cu.import("resource://gre/modules/Services.jsm"); 1.19 + 1.20 +const hideContentStyle = "data:text/css,:root {visibility: hidden !important;}"; 1.21 +const hideSheetUri = Services.io.newURI(hideContentStyle, null, null); 1.22 + 1.23 +// Taken from Gaia: 1.24 +// https://github.com/andreasgal/gaia/blob/04fde2640a7f40314643016a5a6c98bf3755f5fd/webapi.js#L1470 1.25 +function translateElement(element) { 1.26 + element = element || document; 1.27 + 1.28 + // check all translatable children (= w/ a `data-l10n-id' attribute) 1.29 + var children = element.querySelectorAll('*[data-l10n-id]'); 1.30 + var elementCount = children.length; 1.31 + for (var i = 0; i < elementCount; i++) { 1.32 + var child = children[i]; 1.33 + 1.34 + // translate the child 1.35 + var key = child.dataset.l10nId; 1.36 + var data = core.get(key); 1.37 + if (data) 1.38 + child.textContent = data; 1.39 + } 1.40 +} 1.41 +exports.translateElement = translateElement; 1.42 + 1.43 +function onDocumentReady2Translate(event) { 1.44 + let document = event.target; 1.45 + document.removeEventListener("DOMContentLoaded", onDocumentReady2Translate, 1.46 + false); 1.47 + 1.48 + translateElement(document); 1.49 + 1.50 + try { 1.51 + // Finally display document when we finished replacing all text content 1.52 + if (document.defaultView) { 1.53 + let winUtils = document.defaultView.QueryInterface(Ci.nsIInterfaceRequestor) 1.54 + .getInterface(Ci.nsIDOMWindowUtils); 1.55 + winUtils.removeSheet(hideSheetUri, winUtils.USER_SHEET); 1.56 + } 1.57 + } 1.58 + catch(e) { 1.59 + console.exception(e); 1.60 + } 1.61 +} 1.62 + 1.63 +function onContentWindow(event) { 1.64 + let document = event.subject; 1.65 + 1.66 + // Accept only HTML documents 1.67 + if (!(document instanceof Ci.nsIDOMHTMLDocument)) 1.68 + return; 1.69 + 1.70 + // Bug 769483: data:URI documents instanciated with nsIDOMParser 1.71 + // have a null `location` attribute at this time 1.72 + if (!document.location) 1.73 + return; 1.74 + 1.75 + // Accept only document from this addon 1.76 + if (document.location.href.indexOf(assetsURI) !== 0) 1.77 + return; 1.78 + 1.79 + try { 1.80 + // First hide content of the document in order to have content blinking 1.81 + // between untranslated and translated states 1.82 + let winUtils = document.defaultView.QueryInterface(Ci.nsIInterfaceRequestor) 1.83 + .getInterface(Ci.nsIDOMWindowUtils); 1.84 + winUtils.loadSheet(hideSheetUri, winUtils.USER_SHEET); 1.85 + } 1.86 + catch(e) { 1.87 + console.exception(e); 1.88 + } 1.89 + // Wait for DOM tree to be built before applying localization 1.90 + document.addEventListener("DOMContentLoaded", onDocumentReady2Translate, 1.91 + false); 1.92 +} 1.93 + 1.94 +// Listen to creation of content documents in order to translate them as soon 1.95 +// as possible in their loading process 1.96 +const ON_CONTENT = "document-element-inserted"; 1.97 +let enabled = false; 1.98 +function enable() { 1.99 + if (!enabled) { 1.100 + events.on(ON_CONTENT, onContentWindow); 1.101 + enabled = true; 1.102 + } 1.103 +} 1.104 +exports.enable = enable; 1.105 + 1.106 +function disable() { 1.107 + if (enabled) { 1.108 + events.off(ON_CONTENT, onContentWindow); 1.109 + enabled = false; 1.110 + } 1.111 +} 1.112 +exports.disable = disable; 1.113 + 1.114 +require("sdk/system/unload").when(disable);