Index: gc_lang/fr/webext/background.js ================================================================== --- gc_lang/fr/webext/background.js +++ gc_lang/fr/webext/background.js @@ -1,6 +1,10 @@ -// Background +// Background + +/* jshint esversion:6, -W097 */ +/* jslint esversion:6 */ +/* global GrammalectePanel, oGrammalecte, helpers, showError, Worker, chrome, console */ "use strict"; function showError (e) { @@ -250,10 +254,11 @@ console.log("[background] Unknown command: " + sCommand); console.log(oRequest); } }); //xPort.postMessage({sActionDone: "newId", result: iPortId}); + xPort.postMessage({sActionDone: "init", sUrl: browser.extension.getURL("")}); } browser.runtime.onConnect.addListener(handleConnexion); @@ -327,11 +332,11 @@ break; default: console.log("[Background] Unknown menu id: " + xInfo.menuItemId); console.log(xInfo); console.log(xTab); - } + } }); /* Keyboard shortcuts Index: gc_lang/fr/webext/content_scripts/init.js ================================================================== --- gc_lang/fr/webext/content_scripts/init.js +++ gc_lang/fr/webext/content_scripts/init.js @@ -1,7 +1,11 @@ // Modify page +/* jshint esversion:6, -W097 */ +/* jslint esversion:6 */ +/* global GrammalectePanel, GrammalecteMenu, GrammalecteTextFormatter, GrammalecteLexicographer, GrammalecteGrammarChecker, GrammalecteMessageBox, showError, MutationObserver, chrome, document, console */ + /* JS sucks (again, and again, and again, and again…) Not possible to load content from within the extension: https://bugzilla.mozilla.org/show_bug.cgi?id=1267027 No SharedWorker, no images allowed for now… @@ -51,10 +55,12 @@ oMessageBox: null, xRightClickedNode: null, xObserver: null, + + sExtensionUrl: null, listenRightClick: function () { // Node where a right click is done // Bug report: https://bugzilla.mozilla.org/show_bug.cgi?id=1325814 document.addEventListener('contextmenu', function (xEvent) { @@ -208,11 +214,11 @@ } catch (e) { showError(e); } } -} +}; /* Connexion to the background */ @@ -220,10 +226,13 @@ xGrammalectePort.onMessage.addListener(function (oMessage) { let {sActionDone, result, dInfo, bEnd, bError} = oMessage; let sText = ""; switch (sActionDone) { + case "init": + oGrammalecte.sExtensionUrl = oMessage.sUrl; + break; case "parseAndSpellcheck": if (!bEnd) { oGrammalecte.oGCPanel.addParagraphResult(result); } else { oGrammalecte.oGCPanel.stopWaitIcon(); Index: gc_lang/fr/webext/content_scripts/menu.css ================================================================== --- gc_lang/fr/webext/content_scripts/menu.css +++ gc_lang/fr/webext/content_scripts/menu.css @@ -46,10 +46,15 @@ /* Menu */ +div.grammalecte_abs { + display: none; + position: absolute; +} + div.grammalecte_menu { all: initial; display: none; position: absolute; margin-left: -10px; @@ -58,10 +63,11 @@ box-shadow: 0px 0px 2px hsla(210, 10%, 10%, .5); background-color: hsl(210, 50%, 30%); font-family: "Trebuchet MS", "Fira Sans", "Liberation Sans", sans-serif; z-index: 2147483640; /* maximum is 2147483647: https://stackoverflow.com/questions/491052/minimum-and-maximum-value-of-z-index */ text-align: left; + width: 220px; } @media print { .grammalecte_menu { display: none; } } Index: gc_lang/fr/webext/content_scripts/menu.js ================================================================== --- gc_lang/fr/webext/content_scripts/menu.js +++ gc_lang/fr/webext/content_scripts/menu.js @@ -1,15 +1,20 @@ // JavaScript +/* jshint esversion:6, -W097 */ +/* jslint esversion:6 */ +/* global oGrammalecte, xGrammalectePort, showError, window, document */ + "use strict"; class GrammalecteMenu { constructor (nMenu, xNode) { this.xNode = xNode; this.sMenuId = "grammalecte_menu" + nMenu; + this.bShadow = document.body.createShadowRoot || document.body.attachShadow; this.xButton = oGrammalecte.createNode("div", {className: "grammalecte_menu_main_button", textContent: " "}); this.xButton.onclick = () => { this.switchMenu(); }; this.xButton.style.zIndex = (xNode.style.zIndex.search(/^[0-9]+$/) !== -1) ? (parseInt(xNode.style.zIndex) + 1).toString() : xNode.style.zIndex; this.xMenu = this._createMenu(); @@ -19,12 +24,30 @@ let xNodeInsertAfter = this.xNode; if (document.location.host == "twitter.com" && this.xNode.classList.contains('rich-editor')) { xNodeInsertAfter = this.xNode.parentNode; } - this._insertAfter(this.xButton, xNodeInsertAfter, nMarginTop); - this._insertAfter(this.xMenu, xNodeInsertAfter, nMarginTop + 8); + if (this.bShadow){ + this.oShadowBtn = oGrammalecte.createNode("div", {className: "grammalecte_abs", style: "width:16px;height:16px;"}); + this.oShadowBtnNode = this.oShadowBtn.attachShadow({mode: "open"}); + this.oShadowBtnNode.appendChild( + oGrammalecte.createNode("link", {rel: "stylesheet", type: "text/css", media: "all", href: oGrammalecte.sExtensionUrl + "content_scripts/menu.css"}) + ); + this.oShadowBtnNode.appendChild(this.xButton); + this._insertAfter(this.oShadowBtn, xNodeInsertAfter, nMarginTop); + + this.oShadowMenu = oGrammalecte.createNode("div", {id: this.sMenuId+"_shadow", className: "grammalecte_abs", style: "width:0;height:0;"}); + this.oShadowMenuNode = this.oShadowMenu.attachShadow({mode: "open"}); + this.oShadowMenuNode.appendChild( + oGrammalecte.createNode("link", {rel: "stylesheet", type: "text/css", media: "all", href: oGrammalecte.sExtensionUrl + "content_scripts/menu.css"}) + ); + this.oShadowMenuNode.appendChild(this.xMenu); + this._insertAfter(this.oShadowMenu, xNodeInsertAfter, nMarginTop + 8); + } else { + this._insertAfter(this.xButton, xNodeInsertAfter, nMarginTop); + this._insertAfter(this.xMenu, xNodeInsertAfter, nMarginTop + 8); + } this._createListeners(); } _insertAfter (xNewNode, xReferenceNode, nMarginTop) { xReferenceNode.parentNode.insertBefore(xNewNode, xReferenceNode.nextSibling); @@ -31,10 +54,13 @@ xNewNode.style.marginTop = nMarginTop + "px"; } _createListeners () { this.xNode.addEventListener('focus', (e) => { + if (this.bShadow){ + this.oShadowBtn.style.display = "block"; + } this.xButton.style.display = "block"; }); /*this.xNode.addEventListener('blur', (e) => { window.setTimeout(() => {this.xButton.style.display = "none";}, 300); });*/ @@ -47,10 +73,13 @@ _createMenu () { try { let xMenu = oGrammalecte.createNode("div", {id: this.sMenuId, className: "grammalecte_menu"}); let xCloseButton = oGrammalecte.createNode("div", {className: "grammalecte_menu_close_button", textContent: "×"} ); xCloseButton.onclick = () => { + if (this.bShadow){ + this.oShadowBtn.style.display = "none"; + } this.xButton.style.display = "none"; this.switchMenu(); } xMenu.appendChild(xCloseButton); xMenu.appendChild(oGrammalecte.createNode("div", {className: "grammalecte_menu_header", textContent: "GRAMMALECTE"})); @@ -113,13 +142,21 @@ showError(e); } } deleteNodes () { - this.xMenu.parentNode.removeChild(this.xMenu); - this.xButton.parentNode.removeChild(this.xButton); + if (this.bShadow){ + this.oShadowMenu.parentNode.removeChild(this.oShadowMenu); + this.oShadowBtn.parentNode.removeChild(this.oShadowBtn); + } else { + this.xMenu.parentNode.removeChild(this.xMenu); + this.xButton.parentNode.removeChild(this.xButton); + } } switchMenu () { + if (this.bShadow){ + this.oShadowMenu.style.display = (this.oShadowMenu.style.display == "block") ? "none" : "block"; + } this.xMenu.style.display = (this.xMenu.style.display == "block") ? "none" : "block"; } } Index: gc_lang/fr/webext/content_scripts/message_box.js ================================================================== --- gc_lang/fr/webext/content_scripts/message_box.js +++ gc_lang/fr/webext/content_scripts/message_box.js @@ -1,15 +1,29 @@ // JavaScript // Panel creator +/* jshint esversion:6, -W097 */ +/* jslint esversion:6 */ +/* global oGrammalecte, xGrammalectePort, showError, window, document, console */ + "use strict"; class GrammalecteMessageBox { constructor (sId, sTitle) { this.sId = sId; + + this.bShadow = document.body.createShadowRoot || document.body.attachShadow; + if (this.bShadow){ + this.oShadowPanel = oGrammalecte.createNode("div", {id: this.sId+"_shadow", style: "width:0;height:0;"}); + this.oShadow = this.oShadowPanel.attachShadow({mode: "open"}); + this.oParent = this.oShadow; + } else { + this.oParent = document; + } + this.xMessageBoxBar = oGrammalecte.createNode("div", {className: "grammalecte_message_box_bar"}); this.xMessageBoxContent = oGrammalecte.createNode("div", {className: "grammalecte_message_box_content"}); this.xMessageBox = this._createPanel(sTitle); } @@ -48,11 +62,22 @@ xButton.onclick = function () { this.hide(); }.bind(this); // better than writing “let that = this;” before the function? return xButton; } insertIntoPage () { - document.body.appendChild(this.xMessageBox); + if (this.bShadow){ + this.oShadow.appendChild( + oGrammalecte.createNode("link", {rel: "stylesheet", type: "text/css", media: "all", href: oGrammalecte.sExtensionUrl + "content_scripts/panel.css"}) + ); + this.oShadow.appendChild( + oGrammalecte.createNode("link", {rel: "stylesheet", type: "text/css", media: "all", href: oGrammalecte.sExtensionUrl + "content_scripts/message_box.css"}) + ); + this.oShadow.appendChild(this.xMessageBox); + document.body.appendChild(this.oShadowPanel); + } else { + document.body.appendChild(this.xMessageBox); + } } show () { this.xMessageBox.style.display = "block"; } Index: gc_lang/fr/webext/content_scripts/panel.js ================================================================== --- gc_lang/fr/webext/content_scripts/panel.js +++ gc_lang/fr/webext/content_scripts/panel.js @@ -1,8 +1,12 @@ // JavaScript // Panel creator +/* jshint esversion:6, -W097 */ +/* jslint esversion:6 */ +/* global GrammalectePanel, oGrammalecte, xGrammalectePort, showError, window, document, console */ + "use strict"; class GrammalectePanel { @@ -9,10 +13,20 @@ constructor (sId, sTitle, nWidth, nHeight, bFlexible=true) { this.sId = sId; this.nWidth = nWidth; this.nHeight = nHeight; this.bFlexible = bFlexible; + + this.bShadow = document.body.createShadowRoot || document.body.attachShadow; + if (this.bShadow){ + this.oShadowPanel = oGrammalecte.createNode("div", {id: this.sId+"_shadow", style: "width:0;height:0;"}); + this.oShadow = this.oShadowPanel.attachShadow({mode: "open"}); + this.oParent = this.oShadow; + } else { + this.oParent = document; + } + this.xPanelBar = oGrammalecte.createNode("div", {className: "grammalecte_panel_bar"}); this.xPanelContent = oGrammalecte.createNode("div", {className: "grammalecte_panel_content"}); this.xWaitIcon = this._createWaitIcon(); this.xPanel = this._createPanel(sTitle); this.center(); @@ -81,11 +95,28 @@ xButton.onclick = function () { this.hide(); }.bind(this); // better than writing “let that = this;” before the function? return xButton; } insertIntoPage () { - document.body.appendChild(this.xPanel); + if (this.bShadow){ + this.oShadow.appendChild( + oGrammalecte.createNode("link", {rel: "stylesheet", type: "text/css", media: "all", href: oGrammalecte.sExtensionUrl + "content_scripts/panel.css"}) + ); + this.oShadow.appendChild( + oGrammalecte.createNode("link", {rel: "stylesheet", type: "text/css", media: "all", href: oGrammalecte.sExtensionUrl + "content_scripts/panel_gc.css"}) + ); + this.oShadow.appendChild( + oGrammalecte.createNode("link", {rel: "stylesheet", type: "text/css", media: "all", href: oGrammalecte.sExtensionUrl + "content_scripts/panel_lxg.css"}) + ); + this.oShadow.appendChild( + oGrammalecte.createNode("link", {rel: "stylesheet", type: "text/css", media: "all", href: oGrammalecte.sExtensionUrl + "content_scripts/panel_tf.css"}) + ); + this.oShadow.appendChild(this.xPanel); + document.body.appendChild(this.oShadowPanel); + } else { + document.body.appendChild(this.xPanel); + } } show () { this.xPanel.style.display = "block"; } @@ -137,11 +168,11 @@ logInnerHTML () { // for debugging console.log(this.xPanel.innerHTML); } - + startWaitIcon () { this.xWaitIcon.style.visibility = "visible"; } stopWaitIcon () { Index: gc_lang/fr/webext/content_scripts/panel_gc.js ================================================================== --- gc_lang/fr/webext/content_scripts/panel_gc.js +++ gc_lang/fr/webext/content_scripts/panel_gc.js @@ -1,7 +1,11 @@ // JavaScript +/* jshint esversion:6, -W097 */ +/* jslint esversion:6 */ +/* global GrammalectePanel, oGrammalecte, xGrammalectePort, showError, window, document, console */ + "use strict"; function onGrammalecteGCPanelClick (xEvent) { try { let xElem = xEvent.target; @@ -48,11 +52,11 @@ this.aIgnoredErrors = new Set(); this.xContentNode = oGrammalecte.createNode("div", {id: "grammalecte_gc_panel_content"}); this.xParagraphList = oGrammalecte.createNode("div", {id: "grammalecte_paragraph_list"}); this.xContentNode.appendChild(this.xParagraphList); this.xPanelContent.addEventListener("click", onGrammalecteGCPanelClick, false); - this.oTooltip = new GrammalecteTooltip(this.xContentNode); + this.oTooltip = new GrammalecteTooltip(this.oParent, this.xContentNode); this.xPanelContent.appendChild(this.xContentNode); this.oNodeControl = new GrammalecteNodeControl(); } start (xNode=null) { @@ -106,11 +110,11 @@ } } recheckParagraph (iParaNum) { let sParagraphId = "grammalecte_paragraph" + iParaNum; - let xParagraph = document.getElementById(sParagraphId); + let xParagraph = this.oParent.getElementById(sParagraphId); this.blockParagraph(xParagraph); let sText = this.purgeText(xParagraph.textContent); xGrammalectePort.postMessage({ sCommand: "parseAndSpellcheck1", dParam: {sText: sText, sCountry: "FR", bDebug: false, bContext: false}, @@ -120,11 +124,11 @@ this.oNodeControl.write(); } refreshParagraph (sParagraphId, oResult) { try { - let xParagraph = document.getElementById(sParagraphId); + let xParagraph = this.oParent.getElementById(sParagraphId); xParagraph.className = (oResult.aGrammErr.length || oResult.aSpellErr.length) ? "grammalecte_paragraph softred" : "grammalecte_paragraph"; xParagraph.textContent = ""; this._tagParagraph(xParagraph, oResult.sParagraph, sParagraphId.slice(21), oResult.aGrammErr, oResult.aSpellErr); this.freeParagraph(xParagraph); } @@ -193,28 +197,28 @@ return xNodeErr; } blockParagraph (xParagraph) { xParagraph.contentEditable = "false"; - document.getElementById("grammalecte_check"+xParagraph.dataset.para_num).textContent = "Analyse…"; - document.getElementById("grammalecte_check"+xParagraph.dataset.para_num).style.backgroundColor = "hsl(0, 50%, 50%)"; - document.getElementById("grammalecte_check"+xParagraph.dataset.para_num).style.boxShadow = "0 0 0 3px hsla(0, 100%, 50%, .2)"; + this.oParent.getElementById("grammalecte_check"+xParagraph.dataset.para_num).textContent = "Analyse…"; + this.oParent.getElementById("grammalecte_check"+xParagraph.dataset.para_num).style.backgroundColor = "hsl(0, 50%, 50%)"; + this.oParent.getElementById("grammalecte_check"+xParagraph.dataset.para_num).style.boxShadow = "0 0 0 3px hsla(0, 100%, 50%, .2)"; } freeParagraph (xParagraph) { xParagraph.contentEditable = "true"; - document.getElementById("grammalecte_check"+xParagraph.dataset.para_num).textContent = "Réanalyser"; - document.getElementById("grammalecte_check"+xParagraph.dataset.para_num).style.backgroundColor = "hsl(120, 30%, 50%)"; - document.getElementById("grammalecte_check"+xParagraph.dataset.para_num).style.boxShadow = "none"; + this.oParent.getElementById("grammalecte_check"+xParagraph.dataset.para_num).textContent = "Réanalyser"; + this.oParent.getElementById("grammalecte_check"+xParagraph.dataset.para_num).style.backgroundColor = "hsl(120, 30%, 50%)"; + this.oParent.getElementById("grammalecte_check"+xParagraph.dataset.para_num).style.boxShadow = "none"; } applySuggestion (sNodeSuggId) { // sugg try { - let sErrorId = document.getElementById(sNodeSuggId).dataset.error_id; + let sErrorId = this.oParent.getElementById(sNodeSuggId).dataset.error_id; //let sParaNum = sErrorId.slice(0, sErrorId.indexOf("-")); - let xNodeErr = document.getElementById("grammalecte_err" + sErrorId); - xNodeErr.textContent = document.getElementById(sNodeSuggId).textContent; + let xNodeErr = this.oParent.getElementById("grammalecte_err" + sErrorId); + xNodeErr.textContent = this.oParent.getElementById(sNodeSuggId).textContent; xNodeErr.className = "grammalecte_error_corrected"; xNodeErr.removeAttribute("style"); this.oTooltip.hide(); this.recheckParagraph(parseInt(sErrorId.slice(0, sErrorId.indexOf("-")))); } @@ -223,12 +227,12 @@ } } ignoreError (sIgnoreButtonId) { // ignore try { - let sErrorId = document.getElementById(sIgnoreButtonId).dataset.error_id; - let xNodeErr = document.getElementById("grammalecte_err" + sErrorId); + let sErrorId = this.oParent.getElementById(sIgnoreButtonId).dataset.error_id; + let xNodeErr = this.oParent.getElementById("grammalecte_err" + sErrorId); this.aIgnoredErrors.add(xNodeErr.dataset.ignored_key); xNodeErr.className = "grammalecte_error_ignored"; this.oTooltip.hide(); } catch (e) { @@ -254,23 +258,23 @@ function setClipboardData (xEvent) { document.removeEventListener("copy", setClipboardData, true); xEvent.stopImmediatePropagation(); xEvent.preventDefault(); xEvent.clipboardData.setData("text/plain", sText); - }; + } document.addEventListener("copy", setClipboardData, true); document.execCommand("copy"); } copyTextToClipboard () { this.startWaitIcon(); try { - let xClipboardButton = document.getElementById("grammalecte_clipboard_button"); + let xClipboardButton = this.oParent.getElementById("grammalecte_clipboard_button"); xClipboardButton.textContent = "->>"; let sText = ""; - for (let xNode of document.getElementsByClassName("grammalecte_paragraph")) { + for (let xNode of this.oParent.getElementsByClassName("grammalecte_paragraph")) { sText += xNode.textContent + "\n"; } this._copyToClipboard(sText); xClipboardButton.textContent = "OK"; window.setTimeout(function() { xClipboardButton.textContent = "∑"; } , 2000); @@ -283,11 +287,12 @@ } class GrammalecteTooltip { - constructor (xContentNode) { + constructor (oParent, xContentNode) { + this.oParent = oParent; this.sErrorId = null; this.bDebug = false; this.xTooltip = oGrammalecte.createNode("div", {id: "grammalecte_tooltip"}); this.xTooltipArrow = oGrammalecte.createNode("img", { id: "grammalecte_tooltip_arrow", @@ -314,11 +319,11 @@ xContentNode.appendChild(this.xTooltipArrow); } show (sNodeErrorId) { // err try { - let xNodeErr = document.getElementById(sNodeErrorId); + let xNodeErr = this.oParent.getElementById(sNodeErrorId); this.sErrorId = xNodeErr.dataset.error_id; // we store error_id here to know if spell_suggestions are given to the right word. let nTooltipLeftLimit = oGrammalecte.oGCPanel.getWidth() - 330; // paragraph width - tooltip width let nArrowLimit = oGrammalecte.oGCPanel.getWidth() - 20; this.xTooltipArrow.style.top = (xNodeErr.offsetTop + 16) + "px"; let nUsefulErrorWidth = ((xNodeErr.offsetLeft + xNodeErr.offsetWidth) > nArrowLimit) ? (nArrowLimit - xNodeErr.offsetLeft) : xNodeErr.offsetWidth; @@ -325,31 +330,31 @@ this.xTooltipArrow.style.left = (xNodeErr.offsetLeft + Math.floor((nUsefulErrorWidth / 2)) - 4) + "px"; // 4 is half the width of the arrow. this.xTooltip.style.top = (xNodeErr.offsetTop + 20) + "px"; this.xTooltip.style.left = (xNodeErr.offsetLeft > nTooltipLeftLimit) ? nTooltipLeftLimit + "px" : xNodeErr.offsetLeft + "px"; if (xNodeErr.dataset.error_type === "grammar") { // grammar error - document.getElementById("grammalecte_tooltip_db_search").style.display = "none"; + this.oParent.getElementById("grammalecte_tooltip_db_search").style.display = "none"; if (xNodeErr.dataset.gc_message.includes(" ##")) { this.bDebug = true; // display rule id let n = xNodeErr.dataset.gc_message.indexOf(" ##"); - document.getElementById("grammalecte_tooltip_message").textContent = xNodeErr.dataset.gc_message.slice(0, n); - document.getElementById("grammalecte_tooltip_rule_id").textContent = "Règle : " + xNodeErr.dataset.gc_message.slice(n+2); - document.getElementById("grammalecte_tooltip_rule_id").style.display = "block"; + this.oParent.getElementById("grammalecte_tooltip_message").textContent = xNodeErr.dataset.gc_message.slice(0, n); + this.oParent.getElementById("grammalecte_tooltip_rule_id").textContent = "Règle : " + xNodeErr.dataset.gc_message.slice(n+2); + this.oParent.getElementById("grammalecte_tooltip_rule_id").style.display = "block"; } else { this.bDebug = false; - document.getElementById("grammalecte_tooltip_message").textContent = xNodeErr.dataset.gc_message; - document.getElementById("grammalecte_tooltip_rule_id").style.display = "none"; + this.oParent.getElementById("grammalecte_tooltip_message").textContent = xNodeErr.dataset.gc_message; + this.oParent.getElementById("grammalecte_tooltip_rule_id").style.display = "none"; } if (xNodeErr.dataset.gc_url != "") { - document.getElementById("grammalecte_tooltip_url").dataset.url = xNodeErr.dataset.gc_url; - document.getElementById("grammalecte_tooltip_url").style.display = "inline"; + this.oParent.getElementById("grammalecte_tooltip_url").dataset.url = xNodeErr.dataset.gc_url; + this.oParent.getElementById("grammalecte_tooltip_url").style.display = "inline"; } else { - document.getElementById("grammalecte_tooltip_url").dataset.url = ""; - document.getElementById("grammalecte_tooltip_url").style.display = "none"; + this.oParent.getElementById("grammalecte_tooltip_url").dataset.url = ""; + this.oParent.getElementById("grammalecte_tooltip_url").style.display = "none"; } - document.getElementById("grammalecte_tooltip_ignore").dataset.error_id = xNodeErr.dataset.error_id; + this.oParent.getElementById("grammalecte_tooltip_ignore").dataset.error_id = xNodeErr.dataset.error_id; let iSugg = 0; this.clearSuggestionBlock(); if (xNodeErr.dataset.suggestions.length > 0) { for (let sSugg of xNodeErr.dataset.suggestions.split("|")) { this.xTooltipSuggBlock.appendChild(this._createSuggestion(xNodeErr.dataset.error_id, 0, iSugg, sSugg)); @@ -360,20 +365,20 @@ this.xTooltipSuggBlock.textContent = "Aucune."; } } if (xNodeErr.dataset.error_type === "spelling") { // spelling mistake - document.getElementById("grammalecte_tooltip_message").textContent = "Mot inconnu du dictionnaire."; - document.getElementById("grammalecte_tooltip_ignore").dataset.error_id = xNodeErr.dataset.error_id; - document.getElementById("grammalecte_tooltip_rule_id").style.display = "none"; - document.getElementById("grammalecte_tooltip_url").dataset.url = ""; - document.getElementById("grammalecte_tooltip_url").style.display = "none"; + this.oParent.getElementById("grammalecte_tooltip_message").textContent = "Mot inconnu du dictionnaire."; + this.oParent.getElementById("grammalecte_tooltip_ignore").dataset.error_id = xNodeErr.dataset.error_id; + this.oParent.getElementById("grammalecte_tooltip_rule_id").style.display = "none"; + this.oParent.getElementById("grammalecte_tooltip_url").dataset.url = ""; + this.oParent.getElementById("grammalecte_tooltip_url").style.display = "none"; if (this.bDebug) { - document.getElementById("grammalecte_tooltip_db_search").style.display = "inline"; - document.getElementById("grammalecte_tooltip_db_search").dataset.url = "https://www.dicollecte.org/dictionary.php?prj=fr&lemma="+xNodeErr.textContent; + this.oParent.getElementById("grammalecte_tooltip_db_search").style.display = "inline"; + this.oParent.getElementById("grammalecte_tooltip_db_search").dataset.url = "https://www.dicollecte.org/dictionary.php?prj=fr&lemma="+xNodeErr.textContent; } else { - document.getElementById("grammalecte_tooltip_db_search").style.display = "none"; + this.oParent.getElementById("grammalecte_tooltip_db_search").style.display = "none"; } this.clearSuggestionBlock(); this.xTooltipSuggBlock.textContent = "Recherche de graphies possibles…"; xGrammalectePort.postMessage({ sCommand: "getSpellSuggestions", @@ -415,11 +420,11 @@ setSpellSuggestionsFor (sWord, aSugg, iSuggBlock, sErrorId) { // spell checking suggestions try { if (sErrorId === this.sErrorId) { - let xSuggBlock = document.getElementById("grammalecte_tooltip_sugg_block"); + let xSuggBlock = this.oParent.getElementById("grammalecte_tooltip_sugg_block"); if (iSuggBlock == 0) { xSuggBlock.textContent = ""; } if (!aSugg || aSugg.length == 0) { if (iSuggBlock == 0) { @@ -437,11 +442,11 @@ } } } } catch (e) { - let xSuggBlock = document.getElementById("grammalecte_tooltip_sugg_block"); + let xSuggBlock = this.oParent.getElementById("grammalecte_tooltip_sugg_block"); xSuggBlock.appendChild(document.createTextNode("# Oups. Le mécanisme de suggestion orthographique a rencontré un bug… (Ce module est encore en phase β.)")); showError(e); } } } Index: gc_lang/fr/webext/content_scripts/panel_lxg.js ================================================================== --- gc_lang/fr/webext/content_scripts/panel_lxg.js +++ gc_lang/fr/webext/content_scripts/panel_lxg.js @@ -1,7 +1,11 @@ // JavaScript +/* jshint esversion:6, -W097 */ +/* jslint esversion:6 */ +/* global GrammalectePanel, oGrammalecte, showError, console */ + "use strict"; class GrammalecteLexicographer extends GrammalectePanel { @@ -83,10 +87,11 @@ showError(e); } } setHidden (sClass, bHidden) { - for (let xNode of document.getElementsByClassName(sClass)) { + let elmOpt = this.oParent.getElementById('grammalecte_panel_content'); + for (let xNode of elmOpt.getElementsByClassName(sClass)) { xNode.hidden = bHidden; } } } Index: gc_lang/fr/webext/content_scripts/panel_tf.js ================================================================== --- gc_lang/fr/webext/content_scripts/panel_tf.js +++ gc_lang/fr/webext/content_scripts/panel_tf.js @@ -1,8 +1,12 @@ // JavaScript // Text formatter +/* jshint esversion:6, -W097 */ +/* jslint esversion:6 */ +/* global GrammalectePanel, oGrammalecte, TextFormatter, bChrome, browser, showError, document, console */ + "use strict"; class GrammalecteTextFormatter extends GrammalectePanel { @@ -180,20 +184,20 @@ } } } switchGroup (sOptName) { - if (document.getElementById(sOptName).dataset.selected == "true") { - document.getElementById(sOptName.slice(2)).style.opacity = 1; + if (this.oParent.getElementById(sOptName).dataset.selected == "true") { + this.oParent.getElementById(sOptName.slice(2)).style.opacity = 1; } else { - document.getElementById(sOptName.slice(2)).style.opacity = 0.3; + this.oParent.getElementById(sOptName.slice(2)).style.opacity = 0.3; } this.resetProgressBar(); } switchOption (sOptName) { - let xOption = document.getElementById(sOptName); + let xOption = this.oParent.getElementById(sOptName); if (xOption.dataset.linked_ids === "") { xOption.dataset.selected = (xOption.dataset.selected == "true") ? "false" : "true"; xOption.className = (xOption.dataset.selected == "true") ? xOption.className.replace("_off", "_on") : xOption.className.replace("_on", "_off"); } else { this.setOption(sOptName, true); @@ -202,60 +206,64 @@ } } } setOption (sOptName, bValue) { - let xOption = document.getElementById(sOptName); + let xOption = this.oParent.getElementById(sOptName); xOption.dataset.selected = bValue; xOption.className = (xOption.dataset.selected == "true") ? xOption.className.replace("_off", "_on") : xOption.className.replace("_on", "_off"); } reset () { this.resetProgressBar(); - for (let xOption of document.getElementsByClassName("grammalecte_tf_option")) { + //on Shadow DOM getElementsByClassName don't work directly ;) + let elmOpt = this.oParent.getElementById('grammalecte_tf_options'); + for (let xOption of elmOpt.getElementsByClassName("grammalecte_tf_option")) { xOption.dataset.selected = xOption.dataset.default; xOption.className = (xOption.dataset.selected == "true") ? xOption.className.replace("_off", "_on") : xOption.className.replace("_on", "_off"); if (xOption.id.startsWith("o_group_")) { this.switchGroup(xOption.id); } } } resetProgressBar () { - document.getElementById('grammalecte_tf_progressbar').value = 0; - document.getElementById('grammalecte_tf_time_res').textContent = ""; + this.oParent.getElementById('grammalecte_tf_progressbar').value = 0; + this.oParent.getElementById('grammalecte_tf_time_res').textContent = ""; } setOptions (oOptions) { if (oOptions.hasOwnProperty("tf_options")) { oOptions = oOptions.tf_options; } - for (let xOption of document.getElementsByClassName("grammalecte_tf_option")) { + let elmOpt = this.oParent.getElementById('grammalecte_tf_options'); + for (let xOption of elmOpt.getElementsByClassName("grammalecte_tf_option")) { //console.log(xOption.id + " > " + oOptions.hasOwnProperty(xOption.id) + ": " + oOptions[xOption.id] + " [" + xOption.dataset.default + "]"); xOption.dataset.selected = (oOptions.hasOwnProperty(xOption.id)) ? oOptions[xOption.id] : xOption.dataset.default; xOption.className = (xOption.dataset.selected == "true") ? xOption.className.replace("_off", "_on") : xOption.className.replace("_on", "_off"); - if (document.getElementById("res_"+xOption.id) !== null) { - document.getElementById("res_"+xOption.id).textContent = ""; + if (this.oParent.getElementById("res_"+xOption.id) !== null) { + this.oParent.getElementById("res_"+xOption.id).textContent = ""; } if (xOption.id.startsWith("o_group_")) { this.switchGroup(xOption.id); } } } saveOptions () { let oOptions = {}; - for (let xOption of document.getElementsByClassName("grammalecte_tf_option")) { + let elmOpt = this.oParent.getElementById('grammalecte_tf_options'); + for (let xOption of elmOpt.getElementsByClassName("grammalecte_tf_option")) { oOptions[xOption.id] = (xOption.dataset.selected == "true"); //console.log(xOption.id + ": " + xOption.checked); } browser.storage.local.set({"tf_options": oOptions}); } isSelected (sOptName) { - if (document.getElementById(sOptName)) { - return (document.getElementById(sOptName).dataset.selected === "true"); + if (this.oParent.getElementById(sOptName)) { + return (this.oParent.getElementById(sOptName).dataset.selected === "true"); } return false; } apply () { @@ -262,161 +270,161 @@ try { const t0 = Date.now(); //window.setCursor("wait"); // change pointer this.resetProgressBar(); let sText = this.xTextArea.value.normalize("NFC"); - document.getElementById('grammalecte_tf_progressbar').max = 7; + this.oParent.getElementById('grammalecte_tf_progressbar').max = 7; let n1 = 0, n2 = 0, n3 = 0, n4 = 0, n5 = 0, n6 = 0, n7 = 0; // Restructuration if (this.isSelected("o_group_struct")) { if (this.isSelected("o_remove_hyphens_at_end_of_paragraphs")) { [sText, n1] = this.removeHyphenAtEndOfParagraphs(sText); - document.getElementById('res_o_remove_hyphens_at_end_of_paragraphs').textContent = n1; + this.oParent.getElementById('res_o_remove_hyphens_at_end_of_paragraphs').textContent = n1; } if (this.isSelected("o_merge_contiguous_paragraphs")) { [sText, n1] = this.mergeContiguousParagraphs(sText); - document.getElementById('res_o_merge_contiguous_paragraphs').textContent = n1; + this.oParent.getElementById('res_o_merge_contiguous_paragraphs').textContent = n1; } this.setOption("o_group_struct", false); this.switchGroup("o_group_struct"); } - document.getElementById('grammalecte_tf_progressbar').value = 1; + this.oParent.getElementById('grammalecte_tf_progressbar').value = 1; // espaces surnuméraires if (this.isSelected("o_group_ssp")) { if (this.isSelected("o_end_of_paragraph")) { [sText, n1] = this.formatText(sText, "end_of_paragraph"); - document.getElementById('res_o_end_of_paragraph').textContent = n1; + this.oParent.getElementById('res_o_end_of_paragraph').textContent = n1; } if (this.isSelected("o_between_words")) { [sText, n1] = this.formatText(sText, "between_words"); - document.getElementById('res_o_between_words').textContent = n1; + this.oParent.getElementById('res_o_between_words').textContent = n1; } if (this.isSelected("o_start_of_paragraph")) { [sText, n1] = this.formatText(sText, "start_of_paragraph"); - document.getElementById('res_o_start_of_paragraph').textContent = n1; + this.oParent.getElementById('res_o_start_of_paragraph').textContent = n1; } if (this.isSelected("o_before_punctuation")) { [sText, n1] = this.formatText(sText, "before_punctuation"); - document.getElementById('res_o_before_punctuation').textContent = n1; + this.oParent.getElementById('res_o_before_punctuation').textContent = n1; } if (this.isSelected("o_within_parenthesis")) { [sText, n1] = this.formatText(sText, "within_parenthesis"); - document.getElementById('res_o_within_parenthesis').textContent = n1; + this.oParent.getElementById('res_o_within_parenthesis').textContent = n1; } if (this.isSelected("o_within_square_brackets")) { [sText, n1] = this.formatText(sText, "within_square_brackets"); - document.getElementById('res_o_within_square_brackets').textContent = n1; + this.oParent.getElementById('res_o_within_square_brackets').textContent = n1; } if (this.isSelected("o_within_quotation_marks")) { [sText, n1] = this.formatText(sText, "within_quotation_marks"); - document.getElementById('res_o_within_quotation_marks').textContent = n1; + this.oParent.getElementById('res_o_within_quotation_marks').textContent = n1; } this.setOption("o_group_ssp", false); this.switchGroup("o_group_ssp"); } - document.getElementById('grammalecte_tf_progressbar').value = 2; + this.oParent.getElementById('grammalecte_tf_progressbar').value = 2; // espaces insécables if (this.isSelected("o_group_nbsp")) { if (this.isSelected("o_nbsp_before_punctuation")) { [sText, n1] = this.formatText(sText, "nbsp_before_punctuation"); [sText, n2] = this.formatText(sText, "nbsp_repair"); - document.getElementById('res_o_nbsp_before_punctuation').textContent = n1 - n2; + this.oParent.getElementById('res_o_nbsp_before_punctuation').textContent = n1 - n2; } if (this.isSelected("o_nbsp_within_quotation_marks")) { [sText, n1] = this.formatText(sText, "nbsp_within_quotation_marks"); - document.getElementById('res_o_nbsp_within_quotation_marks').textContent = n1; + this.oParent.getElementById('res_o_nbsp_within_quotation_marks').textContent = n1; } if (this.isSelected("o_nbsp_before_symbol")) { [sText, n1] = this.formatText(sText, "nbsp_before_symbol"); - document.getElementById('res_o_nbsp_before_symbol').textContent = n1; + this.oParent.getElementById('res_o_nbsp_before_symbol').textContent = n1; } if (this.isSelected("o_nbsp_within_numbers")) { [sText, n1] = this.formatText(sText, "nbsp_within_numbers"); - document.getElementById('res_o_nbsp_within_numbers').textContent = n1; + this.oParent.getElementById('res_o_nbsp_within_numbers').textContent = n1; } if (this.isSelected("o_nbsp_before_units")) { [sText, n1] = this.formatText(sText, "nbsp_before_units"); - document.getElementById('res_o_nbsp_before_units').textContent = n1; + this.oParent.getElementById('res_o_nbsp_before_units').textContent = n1; } if (this.isSelected("o_nbsp_titles")) { [sText, n1] = this.formatText(sText, "nbsp_titles"); - document.getElementById('res_o_nbsp_titles').textContent = n1; + this.oParent.getElementById('res_o_nbsp_titles').textContent = n1; } this.setOption("o_group_nbsp", false); this.switchGroup("o_group_nbsp"); } - document.getElementById('grammalecte_tf_progressbar').value = 3; + this.oParent.getElementById('grammalecte_tf_progressbar').value = 3; // espaces manquants if (this.isSelected("o_group_typo")) { if (this.isSelected("o_ts_units")) { [sText, n1] = this.formatText(sText, "ts_units"); - document.getElementById('res_o_ts_units').textContent = n1; + this.oParent.getElementById('res_o_ts_units').textContent = n1; } } if (this.isSelected("o_group_space")) { if (this.isSelected("o_add_space_after_punctuation")) { [sText, n1] = this.formatText(sText, "add_space_after_punctuation"); [sText, n2] = this.formatText(sText, "add_space_repair"); - document.getElementById('res_o_add_space_after_punctuation').textContent = n1 - n2; + this.oParent.getElementById('res_o_add_space_after_punctuation').textContent = n1 - n2; } if (this.isSelected("o_add_space_around_hyphens")) { [sText, n1] = this.formatText(sText, "add_space_around_hyphens"); - document.getElementById('res_o_add_space_around_hyphens').textContent = n1; + this.oParent.getElementById('res_o_add_space_around_hyphens').textContent = n1; } this.setOption("o_group_space", false); this.switchGroup("o_group_space"); } - document.getElementById('grammalecte_tf_progressbar').value = 4; + this.oParent.getElementById('grammalecte_tf_progressbar').value = 4; // suppression if (this.isSelected("o_group_delete")) { if (this.isSelected("o_erase_non_breaking_hyphens")) { [sText, n1] = this.formatText(sText, "erase_non_breaking_hyphens"); - document.getElementById('res_o_erase_non_breaking_hyphens').textContent = n1; + this.oParent.getElementById('res_o_erase_non_breaking_hyphens').textContent = n1; } this.setOption("o_group_delete", false); this.switchGroup("o_group_delete"); } - document.getElementById('grammalecte_tf_progressbar').value = 5; + this.oParent.getElementById('grammalecte_tf_progressbar').value = 5; // signes typographiques if (this.isSelected("o_group_typo")) { if (this.isSelected("o_ts_apostrophe")) { [sText, n1] = this.formatText(sText, "ts_apostrophe"); - document.getElementById('res_o_ts_apostrophe').textContent = n1; + this.oParent.getElementById('res_o_ts_apostrophe').textContent = n1; } if (this.isSelected("o_ts_ellipsis")) { [sText, n1] = this.formatText(sText, "ts_ellipsis"); - document.getElementById('res_o_ts_ellipsis').textContent = n1; + this.oParent.getElementById('res_o_ts_ellipsis').textContent = n1; } if (this.isSelected("o_ts_dash_start")) { if (this.isSelected("o_ts_m_dash_start")) { [sText, n1] = this.formatText(sText, "ts_m_dash_start"); } else { [sText, n1] = this.formatText(sText, "ts_n_dash_start"); } - document.getElementById('res_o_ts_dash_start').textContent = n1; + this.oParent.getElementById('res_o_ts_dash_start').textContent = n1; } if (this.isSelected("o_ts_dash_middle")) { if (this.isSelected("o_ts_m_dash_middle")) { [sText, n1] = this.formatText(sText, "ts_m_dash_middle"); } else { [sText, n1] = this.formatText(sText, "ts_n_dash_middle"); } - document.getElementById('res_o_ts_dash_middle').textContent = n1; + this.oParent.getElementById('res_o_ts_dash_middle').textContent = n1; } if (this.isSelected("o_ts_quotation_marks")) { [sText, n1] = this.formatText(sText, "ts_quotation_marks"); - document.getElementById('res_o_ts_quotation_marks').textContent = n1; + this.oParent.getElementById('res_o_ts_quotation_marks').textContent = n1; } if (this.isSelected("o_ts_spell")) { [sText, n1] = this.formatText(sText, "ts_spell"); - document.getElementById('res_o_ts_spell').textContent = n1; + this.oParent.getElementById('res_o_ts_spell').textContent = n1; } if (this.isSelected("o_ts_ligature")) { // ligatures typographiques : fi, fl, ff, ffi, ffl, ft, st if (this.isSelected("o_ts_ligature_do")) { if (this.isSelected("o_ts_ligature_ffi")) { @@ -462,55 +470,55 @@ } if (this.isSelected("o_ts_ligature_st")) { [sText, n7] = this.formatText(sText, "ts_ligature_st_undo"); } } - document.getElementById('res_o_ts_ligature').textContent = n1 + n2 + n3 + n4 + n5 + n6 + n7; + this.oParent.getElementById('res_o_ts_ligature').textContent = n1 + n2 + n3 + n4 + n5 + n6 + n7; } this.setOption("o_group_typo", false); this.switchGroup("o_group_typo"); } - document.getElementById('grammalecte_tf_progressbar').value = 6; + this.oParent.getElementById('grammalecte_tf_progressbar').value = 6; // divers if (this.isSelected("o_group_misc")) { if (this.isSelected("o_ordinals_no_exponant")) { if (this.isSelected("o_ordinals_exponant")) { [sText, n1] = this.formatText(sText, "ordinals_exponant"); } else { [sText, n1] = this.formatText(sText, "ordinals_no_exponant"); } - document.getElementById('res_o_ordinals_no_exponant').textContent = n1; + this.oParent.getElementById('res_o_ordinals_no_exponant').textContent = n1; } if (this.isSelected("o_etc")) { [sText, n1] = this.formatText(sText, "etc"); - document.getElementById('res_o_etc').textContent = n1; + this.oParent.getElementById('res_o_etc').textContent = n1; } if (this.isSelected("o_missing_hyphens")) { [sText, n1] = this.formatText(sText, "missing_hyphens"); - document.getElementById('res_o_missing_hyphens').textContent = n1; + this.oParent.getElementById('res_o_missing_hyphens').textContent = n1; } if (this.isSelected("o_ma_word")) { [sText, n1] = this.formatText(sText, "ma_word"); if (this.isSelected("o_ma_1letter_lowercase")) { [sText, n1] = this.formatText(sText, "ma_1letter_lowercase"); if (this.isSelected("o_ma_1letter_uppercase")) { [sText, n1] = this.formatText(sText, "ma_1letter_uppercase"); } } - document.getElementById('res_o_ma_word').textContent = n1; + this.oParent.getElementById('res_o_ma_word').textContent = n1; } this.setOption("o_group_misc", false); this.switchGroup("o_group_misc"); } - document.getElementById('grammalecte_tf_progressbar').value = document.getElementById('grammalecte_tf_progressbar').max; + this.oParent.getElementById('grammalecte_tf_progressbar').value = this.oParent.getElementById('grammalecte_tf_progressbar').max; // end of processing //window.setCursor("auto"); // restore pointer const t1 = Date.now(); - document.getElementById('grammalecte_tf_time_res').textContent = this.getTimeRes((t1-t0)/1000); + this.oParent.getElementById('grammalecte_tf_time_res').textContent = this.getTimeRes((t1-t0)/1000); this.xTextArea.value = sText; } catch (e) { showError(e); } Index: gc_lang/fr/webext/manifest.json ================================================================== --- gc_lang/fr/webext/manifest.json +++ gc_lang/fr/webext/manifest.json @@ -114,10 +114,15 @@ "description": "Ouvre l’éditeur lexical" } }, "web_accessible_resources": [ + "content_scripts/panel.css", + "content_scripts/panel_tf.css", + "content_scripts/panel_gc.css", + "content_scripts/panel_lxg.css", + "content_scripts/menu.css", "grammalecte/_dictionaries/French.json", "grammalecte/fr/conj_data.json", "grammalecte/fr/mfsp_data.json", "grammalecte/fr/phonet_data.json", "grammalecte/fr/tests_data.json",