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,10 +1,10 @@ // Modify page /* jshint esversion:6, -W097 */ /* jslint esversion:6 */ -/* global GrammalectePanel, GrammalecteMenu, GrammalecteTextFormatter, GrammalecteLexicographer, GrammalecteGrammarChecker, GrammalecteMessageBox, showError, MutationObserver, chrome, document, console */ +/* global GrammalectePanel, GrammalecteButton, 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 @@ -71,32 +71,32 @@ clearRightClickedNode: function () { this.xRightClickedNode = null; }, - createMenus: function () { + createButtons: function () { if (bChrome) { - browser.storage.local.get("ui_options", this._createMenus.bind(this)); + browser.storage.local.get("ui_options", this._createButtons.bind(this)); return; } - browser.storage.local.get("ui_options").then(this._createMenus.bind(this), showError); + browser.storage.local.get("ui_options").then(this._createButtons.bind(this), showError); }, - _createMenus: function (oOptions) { + _createButtons: function (oOptions) { if (oOptions.hasOwnProperty("ui_options")) { this.oOptions = oOptions.ui_options; if (this.oOptions.textarea) { for (let xNode of document.getElementsByTagName("textarea")) { if (xNode.style.display !== "none" && xNode.style.visibility !== "hidden" && xNode.getAttribute("spellcheck") !== "false") { - this.lMenu.push(new GrammalecteMenu(this.nMenu, xNode)); + this.lMenu.push(new GrammalecteButton(this.nMenu, xNode)); this.nMenu += 1; } } } if (this.oOptions.editablenode) { for (let xNode of document.querySelectorAll("[contenteditable]")) { - this.lMenu.push(new GrammalecteMenu(this.nMenu, xNode)); + this.lMenu.push(new GrammalecteButton(this.nMenu, xNode)); this.nMenu += 1; } } } }, @@ -107,17 +107,17 @@ this.xObserver = new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { for (let i = 0; i < mutation.addedNodes.length; i++){ if (mutation.addedNodes[i].tagName == "TEXTAREA") { if (that.oOptions === null || that.oOptions.textarea) { - oGrammalecte.lMenu.push(new GrammalecteMenu(oGrammalecte.nMenu, mutation.addedNodes[i])); + oGrammalecte.lMenu.push(new GrammalecteButton(oGrammalecte.nMenu, mutation.addedNodes[i])); oGrammalecte.nMenu += 1; } } else if (mutation.addedNodes[i].getElementsByTagName) { if (that.oOptions === null || that.oOptions.textarea) { for (let xNode of mutation.addedNodes[i].getElementsByTagName("textarea")) { - oGrammalecte.lMenu.push(new GrammalecteMenu(oGrammalecte.nMenu, xNode)); + oGrammalecte.lMenu.push(new GrammalecteButton(oGrammalecte.nMenu, xNode)); oGrammalecte.nMenu += 1; } } } } @@ -136,16 +136,16 @@ for (let oMenu of this.lMenu) { oMenu.deleteNodes(); } this.lMenu.length = 0; // to clear an array this.listenRightClick(); - this.createMenus(); + this.createButtons(); }, createTFPanel: function () { if (this.oTFPanel === null) { - this.oTFPanel = new GrammalecteTextFormatter("grammalecte_tf_panel", "Formateur de texte", 760, 600, false); + this.oTFPanel = new GrammalecteTextFormatter("grammalecte_tf_panel", "Formateur de texte", 760, 595, false); //this.oTFPanel.logInnerHTML(); this.oTFPanel.insertIntoPage(); window.setTimeout(function(self){ self.oTFPanel.adjustHeight(); }, 50, this); @@ -173,23 +173,10 @@ this.oGCPanel.showEditor(); this.oGCPanel.start(xNode); this.oGCPanel.startWaitIcon(); }, - startLxgPanel: function () { - this.createGCPanel(); - this.oGCPanel.clearLexicographer(); - this.oGCPanel.showLexicographer(); - this.oGCPanel.startWaitIcon(); - }, - - startFTPanel: function (xNode=null) { - this.createTFPanel(); - this.oTFPanel.start(xNode); - this.oTFPanel.show(); - }, - showMessage: function (sMessage) { this.createMessageBox(); this.oMessageBox.show(); this.oMessageBox.setMessage(sMessage); }, @@ -306,11 +293,11 @@ switch (sActionDone) { case "init": oGrammalecte.sExtensionUrl = oMessage.sUrl; // Start oGrammalecte.listenRightClick(); - oGrammalecte.createMenus(); + oGrammalecte.createButtons(); oGrammalecte.observePage(); break; case "parseAndSpellcheck": if (!bEnd) { oGrammalecte.oGCPanel.addParagraphResult(result); 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 @@ -5,11 +5,11 @@ /* global oGrammalecte, xGrammalectePort, showError, window, document */ "use strict"; -class GrammalecteMenu { +class GrammalecteButton { constructor (nMenu, xNode) { this.xNode = xNode; this.xButton = oGrammalecte.createNode("div", {className: "grammalecte_menu_main_button", textContent: " "}); this.xButton.onclick = () => { 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 @@ -26,10 +26,11 @@ } this.xPanelBar = oGrammalecte.createNode("div", {className: "grammalecte_panel_bar"}); this.xPanelContent = oGrammalecte.createNode("div", {className: "grammalecte_panel_content"}); this.xWaitIcon = this._createWaitIcon(); + this.xCloseButton = null; this.xPanel = this._createPanel(sTitle); this.center(); } _createPanel (sTitle) { @@ -65,11 +66,12 @@ xButtonLine.appendChild(this._createMoveButton("stickToTop", "⏶", "Coller en haut")); xButtonLine.appendChild(this._createMoveButton("stickToLeft", "⏴", "Coller à gauche")); xButtonLine.appendChild(this._createMoveButton("center", "•", "Centrer")); xButtonLine.appendChild(this._createMoveButton("stickToRight", "⏵", "Coller à droite")); xButtonLine.appendChild(this._createMoveButton("stickToBottom", "⏷", "Coller en bas")); - xButtonLine.appendChild(this._createCloseButton()); + this.xCloseButton = this._createCloseButton(); + xButtonLine.appendChild(this.xCloseButton); return xButtonLine; } _createWaitIcon () { let xWaitIcon = oGrammalecte.createNode("div", {className: "grammalecte_spinner"}); 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 @@ -73,22 +73,15 @@ this.xLxgButton = oGrammalecte.createNode("div", {className: "grammalecte_menu_button", textContent: "Lexicographe"}); this.xConjButton = oGrammalecte.createNode("div", {className: "grammalecte_menu_button", textContent: "Conjugueur "}); this.xLEButton = oGrammalecte.createNode("div", {className: "grammalecte_menu_button", textContent: "Éditeur lexical "}); this.xTFButton.onclick = () => { oGrammalecte.createTFPanel(); - if (this.xNode) { - oGrammalecte.oTFPanel.start(this.xNode); + if (this.xNode && (this.xNode.tagName == "TEXTAREA" || this.xNode.tagName == "INPUT" || this.xNode.isContentEditable)) { + oGrammalecte.oTFPanel.start(this); oGrammalecte.oTFPanel.show(); - this.start(this.xNode); - this.startWaitIcon(); - xGrammalectePort.postMessage({ - sCommand: "parseAndSpellcheck", - dParam: {sText: this.getParsedText(), sCountry: "FR", bDebug: false, bContext: false}, - dInfo: ((this.xNode) ? {sTextAreaId: this.xNode.id} : {}) - }); } else { - oGrammalecte.showMessage("Aucun node sur lequel appliquer le formatage de texte.") + oGrammalecte.showMessage("Aucune zone de texte éditable sur laquelle appliquer le formatage de texte.") } }; this.xEditorButton.onclick = () => { this.showEditor(); }; @@ -113,24 +106,35 @@ this.xMenu.appendChild(this.xLEButton) this.xPanelBar.appendChild(this.xMenu); } start (xNode=null) { + this.xNode = xNode; this.oTooltip.hide(); this.clear(); - this.xNode = xNode; if (xNode) { this.oNodeControl.setNode(xNode); if (!(xNode.tagName == "TEXTAREA" || xNode.tagName == "INPUT")) { this.addMessage("Note : cette zone de texte n’est pas un champ de formulaire “textarea” mais un node HTML éditable. Une telle zone de texte est susceptible de contenir des éléments non textuels qui seront effacés lors de la correction."); } } } + + recheckAll () { + this.oTooltip.hide(); + this.clear(); + this.startWaitIcon(); + xGrammalectePort.postMessage({ + sCommand: "parseAndSpellcheck", + dParam: {sText: this.getParsedText(), sCountry: "FR", bDebug: false, bContext: false}, + dInfo: ((this.xNode) ? {sTextAreaId: this.xNode.id} : {}) + }); + } getParsedText () { if (this.xNode) { - return (this.xNode.tagName == "TEXTAREA") ? this.xNode.value.normalize("NFC") : this.xNode.innerText.normalize("NFC"); + return (this.xNode.tagName == "TEXTAREA" || this.xNode.tagName == "INPUT") ? this.xNode.value.normalize("NFC") : this.xNode.innerText.normalize("NFC"); } else { return oGrammalecte.getPageText(); } } 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 @@ -12,18 +12,27 @@ constructor (...args) { super(...args); this.xTFNode = this._createTextFormatter(); this.xPanelContent.appendChild(this.xTFNode); - this.xTextArea = null; + this.xTextNode = null; this.xPanel.style.zIndex = 2147483647; /* maximum is 2147483647: https://stackoverflow.com/questions/491052/minimum-and-maximum-value-of-z-index */ + this.bTextChanged = false; this.TextFormatter = new TextFormatter(); this.formatText = this.TextFormatter.formatTextRuleCount; this.removeHyphenAtEndOfParagraphs = this.TextFormatter.removeHyphenAtEndOfParagraphsCount; this.mergeContiguousParagraphs = this.TextFormatter.mergeContiguousParagraphsCount; this.getParagraph = this.TextFormatter.getParagraph; + + this.xCloseButton.onclick = () => { + if (this.bTextChanged) { + // recheck text after modification + this.xGCPanel.recheckAll(); + this.hide(); + } + }; } _createTextFormatter () { let xTFNode = document.createElement("div"); try { @@ -172,21 +181,35 @@ } /* Actions */ - start (xNode) { - if (xNode !== null && xNode.tagName == "TEXTAREA") { - this.xTextArea = xNode; + start (xGCPanel) { + if (xGCPanel.xNode !== null && (xGCPanel.xNode.tagName == "TEXTAREA" || xGCPanel.xNode.tagName == "INPUT" || xGCPanel.xNode.isContentEditable)) { + this.xTextNode = xGCPanel.xNode; + this.xGCPanel = xGCPanel; if (bChrome) { browser.storage.local.get("tf_options", this.setOptions.bind(this)); } else { let xPromise = browser.storage.local.get("tf_options"); xPromise.then(this.setOptions.bind(this), this.reset.bind(this)); } } } + + getNodeText () { + return (this.xTextNode.tagName == "TEXTAREA" || this.xTextNode.tagName == "INPUT") ? this.xTextNode.value.normalize("NFC") : this.xTextNode.innerText.normalize("NFC"); + } + + setNodeText (sText) { + if (this.xTextNode.tagName == "TEXTAREA" || this.xTextNode.tagName == "INPUT") { + this.xTextNode.value = sText; + } else { + this.xTextNode.textContent = sText; + } + this.bTextChanged = true; + } switchGroup (sOptName) { if (this.xParent.getElementById(sOptName).dataset.selected == "true") { this.xParent.getElementById(sOptName.slice(2)).style.opacity = 1; } else { @@ -270,11 +293,11 @@ apply () { try { const t0 = Date.now(); //window.setCursor("wait"); // change pointer this.resetProgressBar(); - let sText = this.xTextArea.value.normalize("NFC"); + let sText = this.getNodeText(); this.xParent.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")) { @@ -516,11 +539,11 @@ //window.setCursor("auto"); // restore pointer const t1 = Date.now(); this.xParent.getElementById('grammalecte_tf_time_res').textContent = this.getTimeRes((t1-t0)/1000); - this.xTextArea.value = sText; + this.setNodeText(sText); } catch (e) { showError(e); } } Index: gc_lang/fr/webext/manifest.json ================================================================== --- gc_lang/fr/webext/manifest.json +++ gc_lang/fr/webext/manifest.json @@ -78,11 +78,11 @@ } ], "commands": { "grammar_checker": { - "suggested_key": { "default": "Ctrl+Shift+Z" }, + "suggested_key": { "default": "Ctrl+Shift+F" }, "description": "Ouvre le correcteur grammatical" }, "conjugueur_tab": { "suggested_key": { "default": "Ctrl+Shift+6" }, "description": "Ouvre le conjugueur" Index: gc_lang/fr/webext/panel/main.html ================================================================== --- gc_lang/fr/webext/panel/main.html +++ gc_lang/fr/webext/panel/main.html @@ -86,11 +86,11 @@

Ces zones de texte sont des sections de page web éditables. Il est fréquent que ces zones de texte apparaissent comme des “textareas” standard. Il est aussi fréquent que ces zones de texte soient couplées avec toutes sortes de logiciels (de simples scripts d’aide à la mise en page ou des applications complexes). Ces zones de texte permettent l’affichage de texte enrichi (italique, gras, hyperlien, images, etc.).

Raccourcis clavier

-

CTRL+MAJ+Z

+

CTRL+MAJ+F

Correcteur grammatical

CTRL+MAJ+6

Conjugueur

CTRL+MAJ+7

Éditeur lexical