Index: gc_core/js/ibdawg.js
==================================================================
--- gc_core/js/ibdawg.js
+++ gc_core/js/ibdawg.js
@@ -214,15 +214,13 @@
}
_suggest (sRemain, nMaxDel=0, nDeep=0, iAddr=0, sNewWord="", bAvoidLoop=false) {
// returns a set of suggestions
// recursive function
- //show(nDeep, sNewWord + ":" + sRemain)
let aSugg = new Set();
if (sRemain == "") {
if (this._convBytesToInteger(this.byDic.slice(iAddr, iAddr+this.nBytesArc)) & this._finalNodeMask) {
- //show(nDeep, "___" + sNewWord + "___");
aSugg.add(sNewWord);
}
for (let sTail of this._getTails(iAddr)) {
aSugg.add(sNewWord+sTail);
}
@@ -298,18 +296,16 @@
_suggestWithCrushedUselessChars (sWord, nDeep=0, iAddr=0, sNewWord="", bAvoidLoop=false) {
let aSugg = new Set();
if (sWord.length == 0) {
if (this._convBytesToInteger(this.byDic.slice(iAddr, iAddr+this.nBytesArc)) & this._finalNodeMask) {
- show(nDeep, "!!! " + sNewWord + " !!!");
aSugg.add(sNewWord);
}
return aSugg;
}
let cCurrent = sWord.slice(0, 1);
for (let [cChar, jAddr] of this._getSimilarArcsAndCrushedChars(cCurrent, iAddr)) {
- show(nDeep, cChar);
aSugg.gl_update(this._suggestWithCrushedUselessChars(sWord.slice(1), nDeep+1, jAddr, sNewWord+cChar));
}
return aSugg;
}
Index: gc_lang/fr/webext/background.js
==================================================================
--- gc_lang/fr/webext/background.js
+++ gc_lang/fr/webext/background.js
@@ -174,28 +174,69 @@
/*
Context Menu
*/
+
+// Selected text
browser.contextMenus.create({
- id: "getListOfTokens",
- title: "Analyser",
+ id: "rightClickLxgSelectedText",
+ title: "Lexicographe (sélection)",
contexts: ["selection"]
});
browser.contextMenus.create({
- id: "parseAndSpellcheck",
- title: "Corriger",
+ id: "rightClickGCSelectedText",
+ title: "Correction grammaticale (sélection)",
contexts: ["selection"]
});
browser.contextMenus.create({
- id: "separator1",
+ id: "separator_selection",
type: "separator",
contexts: ["selection"]
});
+// Editable content
+browser.contextMenus.create({
+ id: "rightClickLxgEditableNode",
+ title: "Lexicographe (zone de texte)",
+ contexts: ["editable"]
+});
+
+browser.contextMenus.create({
+ id: "rightClickGCEditableNode",
+ title: "Correction grammaticale (zone de texte)",
+ contexts: ["editable"]
+});
+
+browser.contextMenus.create({
+ id: "separator_editable",
+ type: "separator",
+ contexts: ["editable"]
+});
+
+// Page
+browser.contextMenus.create({
+ id: "rightClickLxgPage",
+ title: "Lexicographe (page)",
+ contexts: ["page"]
+});
+
+browser.contextMenus.create({
+ id: "rightClickGCPage",
+ title: "Correction grammaticale (page)",
+ contexts: ["page"]
+});
+
+browser.contextMenus.create({
+ id: "separator_page",
+ type: "separator",
+ contexts: ["page"]
+});
+
+// Conjugueur
browser.contextMenus.create({
id: "conjugueur_window",
title: "Conjugueur [fenêtre]",
contexts: ["all"]
});
@@ -204,39 +245,62 @@
id: "conjugueur_tab",
title: "Conjugueur [onglet]",
contexts: ["all"]
});
+// Rescan page
browser.contextMenus.create({
- id: "separator2",
+ id: "separator_rescan",
type: "separator",
contexts: ["editable"]
});
browser.contextMenus.create({
id: "rescanPage",
title: "Rechercher à nouveau les zones de texte",
contexts: ["editable"]
});
+
browser.contextMenus.onClicked.addListener(function (xInfo, xTab) {
// xInfo = https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/contextMenus/OnClickData
// xTab = https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/tabs/Tab
// confusing: no way to get the node where we click?!
switch (xInfo.menuItemId) {
- case "parseAndSpellcheck":
- parseAndSpellcheckSelectedText(xTab.id, xInfo.selectionText);
+ // editable node
+ // page
+ case "rightClickGCEditableNode":
+ case "rightClickLxgEditableNode":
+ case "rightClickGCPage":
+ case "rightClickLxgPage":
+ sendCommandToTab(xInfo.menuItemId, xTab.id);
+ break;
+ // selected text
+ case "rightClickGCSelectedText":
+ sendCommandToTab("rightClickGCSelectedText", xTab.id);
+ xGCEWorker.postMessage({
+ sCommand: "parseAndSpellcheck",
+ dParam: {sText: xInfo.selectionText, sCountry: "FR", bDebug: false, bContext: false},
+ dInfo: {iReturnPort: xTab.id}
+ });
break;
- case "getListOfTokens":
- getListOfTokensFromSelectedText(xTab.id, xInfo.selectionText);
+ case "rightClickLxgSelectedText":
+ sendCommandToTab("rightClickLxgSelectedText", xTab.id);
+ xGCEWorker.postMessage({
+ sCommand: "getListOfTokens",
+ dParam: {sText: xInfo.selectionText},
+ dInfo: {iReturnPort: xTab.id}
+ });
break;
+ // conjugueur
case "conjugueur_window":
openConjugueurWindow();
break;
case "conjugueur_tab":
openConjugueurTab();
break;
+ // rescan page
case "rescanPage":
let xPort = dConnx.get(xTab.id);
xPort.postMessage({sActionDone: "rescanPage"});
break;
default:
@@ -272,32 +336,13 @@
dOptions = helpers.mapToObject(dOptions);
}
browser.storage.local.set({"gc_options": dOptions});
}
-function parseAndSpellcheckSelectedText (iTab, sText) {
- // send message to the tab
- let xTabPort = dConnx.get(iTab);
- xTabPort.postMessage({sActionDone: "openGCPanel", result: null, dInfo: null, bEnd: false, bError: false});
- // send command to the worker
- xGCEWorker.postMessage({
- sCommand: "parseAndSpellcheck",
- dParam: {sText: sText, sCountry: "FR", bDebug: false, bContext: false},
- dInfo: {iReturnPort: iTab}
- });
-}
-
-function getListOfTokensFromSelectedText (iTab, sText) {
- // send message to the tab
- let xTabPort = dConnx.get(iTab);
- xTabPort.postMessage({sActionDone: "openLxgPanel", result: null, dInfo: null, bEnd: false, bError: false});
- // send command to the worker
- xGCEWorker.postMessage({
- sCommand: "getListOfTokens",
- dParam: {sText: sText},
- dInfo: {iReturnPort: iTab}
- });
+function sendCommandToTab (sCommand, iTab) {
+ let xTabPort = dConnx.get(iTab);
+ xTabPort.postMessage({sActionDone: sCommand, result: null, dInfo: null, bEnd: false, bError: false});
}
function openConjugueurTab () {
if (bChrome) {
browser.tabs.create({
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
@@ -44,10 +44,24 @@
lMenu: [],
oTFPanel: null,
oLxgPanel: null,
oGCPanel: null,
+
+ xRightClickedNode: 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) {
+ this.xRightClickedNode = xEvent.target;
+ }.bind(this), true);
+ },
+
+ clearRightClickedNode: function () {
+ this.xRightClickedNode = null;
+ },
createMenus: function () {
let lNode = document.getElementsByTagName("textarea");
for (let xNode of lNode) {
if (xNode.style.display !== "none" && xNode.style.visibility !== "hidden") {
@@ -54,20 +68,30 @@
this.lMenu.push(new GrammalecteMenu(this.nMenu, xNode));
this.nMenu += 1;
}
}
},
+
+ createMenus2 () {
+ let lNode = document.querySelectorAll("[contenteditable]");
+ for (let xNode of lNode) {
+ this.lMenu.push(new GrammalecteMenu(this.nMenu, xNode));
+ this.nMenu += 1;
+ }
+ },
rescanPage: function () {
if (this.oTFPanel !== null) { this.oTFPanel.hide(); }
if (this.oLxgPanel !== null) { this.oLxgPanel.hide(); }
if (this.oGCPanel !== null) { this.oGCPanel.hide(); }
for (let oMenu of this.lMenu) {
oMenu.deleteNodes();
}
this.lMenu.length = 0; // to clear an array
+ this.listenRightClick();
this.createMenus();
+ this.createMenus2();
},
createTFPanel: function () {
if (this.oTFPanel === null) {
this.oTFPanel = new GrammalecteTextFormatter("grammalecte_tf_panel", "Formateur de texte", 760, 600, false);
@@ -88,10 +112,34 @@
if (this.oGCPanel === null) {
this.oGCPanel = new GrammalecteGrammarChecker("grammalecte_gc_panel", "Grammalecte", 500, 700);
this.oGCPanel.insertIntoPage();
}
},
+
+ startGCPanel: function (xNode=null) {
+ oGrammalecte.createGCPanel();
+ oGrammalecte.oGCPanel.clear();
+ oGrammalecte.oGCPanel.show();
+ oGrammalecte.oGCPanel.start(xNode);
+ oGrammalecte.oGCPanel.startWaitIcon();
+ },
+
+ startLxgPanel: function () {
+ oGrammalecte.createLxgPanel();
+ oGrammalecte.oLxgPanel.clear();
+ oGrammalecte.oLxgPanel.show();
+ oGrammalecte.oLxgPanel.startWaitIcon();
+ },
+
+ getPageText: function () {
+ let sPageText = document.body.innerText;
+ let nPos = sPageText.indexOf("__grammalecte_panel__");
+ if (nPos >= 0) {
+ sPageText = sPageText.slice(0, nPos);
+ }
+ return sPageText;
+ },
createNode: function (sType, oAttr, oDataset=null) {
try {
let xNode = document.createElement(sType);
Object.assign(xNode, oAttr);
@@ -112,10 +160,11 @@
*/
let xGrammalectePort = browser.runtime.connect({name: "content-script port"});
xGrammalectePort.onMessage.addListener(function (oMessage) {
let {sActionDone, result, dInfo, bEnd, bError} = oMessage;
+ let sText = "";
switch (sActionDone) {
case "parseAndSpellcheck":
if (!bEnd) {
oGrammalecte.oGCPanel.addParagraphResult(result);
} else {
@@ -133,25 +182,71 @@
}
break;
case "getSpellSuggestions":
oGrammalecte.oGCPanel.oTooltip.setSpellSuggestionsFor(result.sWord, result.aSugg, dInfo.sErrorId);
break;
- // Design WTF: context menus are made in background, not in content-script.
- // Commands from context menu received here to initialize panels
- case "openGCPanel":
- oGrammalecte.createGCPanel();
- oGrammalecte.oGCPanel.clear();
- oGrammalecte.oGCPanel.show();
- oGrammalecte.oGCPanel.start();
- oGrammalecte.oGCPanel.startWaitIcon();
- break;
- case "openLxgPanel":
- oGrammalecte.createLxgPanel();
- oGrammalecte.oLxgPanel.clear();
- oGrammalecte.oLxgPanel.show();
- oGrammalecte.oLxgPanel.startWaitIcon();
- break;
+ /*
+ Commands received from the context menu
+ (Context menu are initialized in background)
+ */
+ // Grammar checker commands
+ case "rightClickGCEditableNode":
+ if (oGrammalecte.xRightClickedNode !== null) {
+ oGrammalecte.startGCPanel(oGrammalecte.xRightClickedNode);
+ sText = (oGrammalecte.xRightClickedNode.tagName == "TEXTAREA") ? oGrammalecte.xRightClickedNode.value : oGrammalecte.xRightClickedNode.innerText;
+ xGrammalectePort.postMessage({
+ sCommand: "parseAndSpellcheck",
+ dParam: {sText: sText, sCountry: "FR", bDebug: false, bContext: false},
+ dInfo: {sTextAreaId: oGrammalecte.xRightClickedNode.id}
+ });
+ } else {
+ oGrammalecte.startGCPanel();
+ oGrammalecte.oGCPanel.addMessage("Erreur. Node introuvable… Sélectionnez le texte à corriger et relancez le correcteur via le menu contextuel.");
+ oGrammalecte.oGCPanel.stopWaitIcon();
+ }
+ break;
+ case "rightClickGCPage":
+ oGrammalecte.startGCPanel();
+ xGrammalectePort.postMessage({
+ sCommand: "parseAndSpellcheck",
+ dParam: {sText: oGrammalecte.getPageText(), sCountry: "FR", bDebug: false, bContext: false},
+ dInfo: {}
+ });
+ break;
+ case "rightClickGCSelectedText":
+ oGrammalecte.startGCPanel();
+ // selected text is sent to the GC worker in the background script.
+ break;
+ // Lexicographer commands
+ case "rightClickLxgEditableNode":
+ if (oGrammalecte.xRightClickedNode !== null) {
+ oGrammalecte.startLxgPanel();
+ sText = (oGrammalecte.xRightClickedNode.tagName == "TEXTAREA") ? oGrammalecte.xRightClickedNode.value : oGrammalecte.xRightClickedNode.textContent;
+ xGrammalectePort.postMessage({
+ sCommand: "getListOfTokens",
+ dParam: {sText: sText},
+ dInfo: {sTextAreaId: oGrammalecte.xRightClickedNode.id}
+ });
+ } else {
+ oGrammalecte.startLxgPanel();
+ oGrammalecte.oLxgPanel.addMessage("Erreur. Node introuvable… Sélectionnez le texte à analyser et relancez le lexicographe via le menu contextuel.");
+ oGrammalecte.oLxgPanel.stopWaitIcon();
+ }
+ break;
+ case "rightClickLxgPage":
+ oGrammalecte.startLxgPanel();
+ xGrammalectePort.postMessage({
+ sCommand: "getListOfTokens",
+ dParam: {sText: oGrammalecte.getPageText()},
+ dInfo: {}
+ });
+ break;
+ case "rightClickLxgSelectedText":
+ oGrammalecte.startLxgPanel();
+ // selected text is sent to the GC worker in the background script.
+ break;
+ // rescan page command
case "rescanPage":
oGrammalecte.rescanPage();
break;
default:
console.log("[Content script] Unknown command: " + sActionDone);
@@ -160,6 +255,8 @@
/*
Start
*/
+oGrammalecte.listenRightClick();
oGrammalecte.createMenus();
+oGrammalecte.createMenus2();
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
@@ -18,11 +18,11 @@
border-radius: 50%;
text-align: center;
cursor: pointer;
box-shadow: 0 0 0 0 hsla(210, 50%, 50%, .5);
z-index: 2147483640; /* maximum is 2147483647: https://stackoverflow.com/questions/491052/minimum-and-maximum-value-of-z-index */
- animation: grammalecte-spin 2s ease 3;
+ animation: grammalecte-spin 2s ease 1;
}
.grammalecte_menu_main_button:hover {
border: 4px solid hsla(210, 80%, 35%, .5);
background-color: hsla(210, 80%, 55%, .5);
animation: grammalecte-spin .5s linear infinite;
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
@@ -3,81 +3,77 @@
"use strict";
class GrammalecteMenu {
- constructor (nMenu, xTextArea) {
+ constructor (nMenu, xNode) {
this.sMenuId = "grammalecte_menu" + nMenu;
this.xButton = oGrammalecte.createNode("div", {className: "grammalecte_menu_main_button", textContent: " "});
this.xButton.onclick = () => { this.switchMenu(); };
- this.xMenu = this._createMenu(xTextArea);
- this._insertAfter(this.xButton, xTextArea);
- this._insertAfter(this.xMenu, xTextArea);
+ this.xMenu = this._createMenu(xNode);
+ this._insertAfter(this.xButton, xNode);
+ this._insertAfter(this.xMenu, xNode);
}
_insertAfter (xNewNode, xReferenceNode) {
xReferenceNode.parentNode.insertBefore(xNewNode, xReferenceNode.nextSibling);
}
- _createMenu (xTextArea) {
+ _createMenu (xNode) {
try {
+ let sText = (xNode.tagName == "TEXTAREA") ? xNode.value : xNode.textContent;
let xMenu = oGrammalecte.createNode("div", {id: this.sMenuId, className: "grammalecte_menu"});
+ xMenu.appendChild(oGrammalecte.createNode("div", {className: "grammalecte_menu_header", textContent: "GRAMMALECTE"}));
// Text formatter
- let xTFButton = oGrammalecte.createNode("div", {className: "grammalecte_menu_item", textContent: "Formateur de texte"});
- xTFButton.onclick = () => {
- this.switchMenu();
- oGrammalecte.createTFPanel();
- oGrammalecte.oTFPanel.start(xTextArea);
- oGrammalecte.oTFPanel.show();
- };
+ if (xNode.tagName == "TEXTAREA") {
+ let xTFButton = oGrammalecte.createNode("div", {className: "grammalecte_menu_item", textContent: "Formateur de texte"});
+ xTFButton.onclick = () => {
+ this.switchMenu();
+ oGrammalecte.createTFPanel();
+ oGrammalecte.oTFPanel.start(xNode);
+ oGrammalecte.oTFPanel.show();
+ };
+ xMenu.appendChild(xTFButton);
+ }
// lexicographe
let xLxgButton = oGrammalecte.createNode("div", {className: "grammalecte_menu_item", textContent: "Lexicographe"});
xLxgButton.onclick = () => {
- this.switchMenu();
- oGrammalecte.createLxgPanel();
- oGrammalecte.oLxgPanel.clear();
- oGrammalecte.oLxgPanel.show();
- oGrammalecte.oLxgPanel.startWaitIcon();
+ this.switchMenu();
+ oGrammalecte.startLxgPanel();
xGrammalectePort.postMessage({
sCommand: "getListOfTokens",
- dParam: {sText: xTextArea.value},
- dInfo: {sTextAreaId: xTextArea.id}
+ dParam: {sText: sText},
+ dInfo: {sTextAreaId: xNode.id}
});
};
+ xMenu.appendChild(xLxgButton);
// Grammar checker
let xGCButton = oGrammalecte.createNode("div", {className: "grammalecte_menu_item", textContent: "Correction grammaticale"});
xGCButton.onclick = () => {
- this.switchMenu();
- oGrammalecte.createGCPanel();
- oGrammalecte.oGCPanel.start(xTextArea);
- oGrammalecte.oGCPanel.show();
- oGrammalecte.oGCPanel.startWaitIcon();
+ this.switchMenu();
+ oGrammalecte.startGCPanel(xNode);
xGrammalectePort.postMessage({
sCommand: "parseAndSpellcheck",
- dParam: {sText: xTextArea.value, sCountry: "FR", bDebug: false, bContext: false},
- dInfo: {sTextAreaId: xTextArea.id}
+ dParam: {sText: sText, sCountry: "FR", bDebug: false, bContext: false},
+ dInfo: {sTextAreaId: xNode.id}
});
};
+ xMenu.appendChild(xGCButton);
// Conjugation tool
let xConjButton = oGrammalecte.createNode("div", {className: "grammalecte_menu_item_block", textContent: "Conjugueur"});
let xConjButtonTab = oGrammalecte.createNode("div", {className: "grammalecte_menu_button", textContent: "Onglet"});
xConjButtonTab.onclick = () => {
- this.switchMenu();
- xGrammalectePort.postMessage({sCommand: "openConjugueurTab", dParam: null, dInfo: null});
+ this.switchMenu();
+ xGrammalectePort.postMessage({sCommand: "openConjugueurTab", dParam: null, dInfo: null});
};
let xConjButtonWin = oGrammalecte.createNode("div", {className: "grammalecte_menu_button", textContent: "Fenêtre"});
xConjButtonWin.onclick = () => {
- this.switchMenu();
- xGrammalectePort.postMessage({sCommand: "openConjugueurWindow", dParam: null, dInfo: null});
+ this.switchMenu();
+ xGrammalectePort.postMessage({sCommand: "openConjugueurWindow", dParam: null, dInfo: null});
};
xConjButton.appendChild(xConjButtonTab);
xConjButton.appendChild(xConjButtonWin);
- // Create
- xMenu.appendChild(oGrammalecte.createNode("div", {className: "grammalecte_menu_header", textContent: "GRAMMALECTE"}));
- xMenu.appendChild(xTFButton);
- xMenu.appendChild(xLxgButton);
- xMenu.appendChild(xGCButton);
xMenu.appendChild(xConjButton);
//xMenu.appendChild(oGrammalecte.createNode("img", {scr: browser.extension.getURL("img/logo-16.png")}));
// can’t work, due to content-script policy: https://bugzilla.mozilla.org/show_bug.cgi?id=1267027
xMenu.appendChild(oGrammalecte.createNode("div", {className: "grammalecte_menu_footer"}));
return xMenu;
@@ -91,9 +87,9 @@
this.xMenu.parentNode.removeChild(this.xMenu);
this.xButton.parentNode.removeChild(this.xButton);
}
switchMenu () {
- let xMenu = document.getElementById(this.sMenuId);
+ let xMenu = document.getElementById(this.sMenuId);
xMenu.style.display = (xMenu.style.display == "block") ? "none" : "block";
}
}
Index: gc_lang/fr/webext/content_scripts/panel.css
==================================================================
--- gc_lang/fr/webext/content_scripts/panel.css
+++ gc_lang/fr/webext/content_scripts/panel.css
@@ -39,10 +39,16 @@
}
.grammalecte_panel_label {
display: inline-block;
padding: 0 10px;
}
+.grammalecte_panel_invisible_marker {
+ position: absolute;
+ /*visibility: hidden;*/
+ font-size: 6px;
+ color: hsl(210, 0%, 90%); /* same color than panel_bar background */
+}
.grammalecte_panel_commands {
float: right;
}
.grammalecte_copy_button {
@@ -91,10 +97,19 @@
position: absolute;
min-width: 100%;
height: calc(100% - 55px); /* panel height - title_bar */
overflow: auto;
}
+
+.grammalecte_panel_message {
+ margin: 10px;
+ padding: 10px;
+ border-radius: 5px;
+ background-color: hsl(0, 50%, 40%);
+ color: hsl(0, 50%, 96%);
+ font-size: 20px;
+}
/*
Spinner
*/
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
@@ -19,10 +19,11 @@
}
_createPanel (sTitle) {
try {
let xPanel = oGrammalecte.createNode("div", {id: this.sId, className: "grammalecte_panel"});
+ this.xPanelBar.appendChild(oGrammalecte.createNode("div", {className: "grammalecte_panel_invisible_marker", textContent: "__grammalecte_panel__"}));
this.xPanelBar.appendChild(this._createButtons());
let xTitle = oGrammalecte.createNode("div", {className: "grammalecte_panel_title"});
xTitle.appendChild(this._createLogo());
xTitle.appendChild(oGrammalecte.createNode("div", {className: "grammalecte_panel_label", textContent: sTitle}));
this.xPanelBar.appendChild(xTitle);
@@ -89,10 +90,11 @@
this.xPanel.style.display = "block";
}
hide () {
this.xPanel.style.display = "none";
+ oGrammalecte.clearRightClickedNode();
}
center () {
let nHeight = (this.bFlexible) ? window.innerHeight-100 : this.nHeight;
this.xPanel.style = `top: 50%; left: 50%; width: ${this.nWidth}px; height: ${nHeight}px; margin-top: -${nHeight/2}px; margin-left: -${this.nWidth/2}px;`;
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
@@ -53,15 +53,15 @@
this.oTooltip = new GrammalecteTooltip(this.xContentNode);
this.xPanelContent.appendChild(this.xContentNode);
this.oTAC = new GrammalecteTextAreaControl();
}
- start (xTextArea=null) {
+ start (xNode=null) {
this.oTooltip.hide();
this.clear();
- if (xTextArea) {
- this.oTAC.setTextArea(xTextArea);
+ if (xNode && xNode.tagName == "TEXTAREA") {
+ this.oTAC.setTextArea(xNode);
}
}
clear () {
while (this.xParagraphList.firstChild) {
@@ -235,11 +235,11 @@
addSummary () {
// todo
}
addMessage (sMessage) {
- let xNode = oGrammalecte.createNode("div", {className: "grammalecte_gc_panel_message", textContent: sMessage});
+ let xNode = oGrammalecte.createNode("div", {className: "grammalecte_panel_message", textContent: sMessage});
this.xParagraphList.appendChild(xNode);
}
_copyToClipboard (sText) {
// recipe from https://github.com/mdn/webextensions-examples/blob/master/context-menu-copy-link-with-types/clipboard-helper.js
@@ -448,11 +448,11 @@
this._dParagraph.set(i, sText.slice(iStart, iEnd));
i++;
iStart = iEnd+1;
}
this._dParagraph.set(i, sText.slice(iStart));
- console.log("Paragraphs number: " + (i+1));
+ //console.log("Paragraphs number: " + (i+1));
}
write () {
if (this._xTextArea !== null) {
let sText = "";
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
@@ -22,12 +22,13 @@
if (this._xContentNode.textContent !== "") {
this._xContentNode.appendChild(oGrammalecte.createNode("div", {className: "grammalecte_lxg_separator", textContent: sText}));
}
}
- addMessage (sClass, sText) {
- this._xContentNode.appendChild(oGrammalecte.createNode("div", {className: sClass, textContent: sText}));
+ addMessage (sMessage) {
+ let xNode = oGrammalecte.createNode("div", {className: "grammalecte_panel_message", textContent: sMessage});
+ this._xContentNode.appendChild(xNode);
}
addListOfTokens (lTokens) {
try {
if (lTokens) {
DELETED gc_lang/fr/webext/gce_sharedworker.js
Index: gc_lang/fr/webext/gce_sharedworker.js
==================================================================
--- gc_lang/fr/webext/gce_sharedworker.js
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- WORKER:
- https://developer.mozilla.org/en-US/docs/Web/API/Worker
- https://developer.mozilla.org/en-US/docs/Web/API/DedicatedWorkerGlobalScope
-
-
- JavaScript sucks.
- No module available in WebExtension at the moment! :(
- No require, no import/export.
-
- In Worker, we have importScripts() which imports everything in this scope.
-
- In order to use the same base of code with XUL-addon for Thunderbird and SDK-addon for Firefox,
- all modules have been “objectified”. And while they are still imported via “require”
- in the previous extensions, they are loaded as background scripts in WebExtension sharing
- the same memory space…
-
- When JavaScript become a modern language, “deobjectify” the modules…
-
- ATM, import/export are not available by default:
- — Chrome 60 – behind the Experimental Web Platform flag in chrome:flags.
- — Firefox 54 – behind the dom.moduleScripts.enabled setting in about:config.
- — Edge 15 – behind the Experimental JavaScript Features setting in about:flags.
-
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export
-*/
-
-"use strict";
-
-
-console.log("GC Engine SharedWorker [start]");
-//console.log(self);
-
-importScripts("grammalecte/helpers.js");
-importScripts("grammalecte/str_transform.js");
-importScripts("grammalecte/ibdawg.js");
-importScripts("grammalecte/text.js");
-importScripts("grammalecte/tokenizer.js");
-importScripts("grammalecte/fr/conj.js");
-importScripts("grammalecte/fr/mfsp.js");
-importScripts("grammalecte/fr/phonet.js");
-importScripts("grammalecte/fr/cregex.js");
-importScripts("grammalecte/fr/gc_options.js");
-importScripts("grammalecte/fr/gc_rules.js");
-importScripts("grammalecte/fr/gc_engine.js");
-importScripts("grammalecte/fr/lexicographe.js");
-importScripts("grammalecte/tests.js");
-/*
- Warning.
- Initialization can’t be completed at startup of the worker,
- for we need the path of the extension to load data stored in JSON files.
- This path is retrieved in background.js and passed with the event “init”.
-*/
-
-
-/*
- Message Event Object
- https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent
-*/
-
-let xPort = null;
-
-function createResponse (sActionDone, result, dInfo, bError=false) {
- return {
- "sActionDone": sActionDone,
- "result": result, // can be of any type
- "dInfo": dInfo,
- "bError": bError
- };
-}
-
-function createErrorResult (e, sDescr="no description") {
- return {
- "sType": "error",
- "sDescription": sDescr,
- "sMessage": e.fileName + "\n" + e.name + "\nline: " + e.lineNumber + "\n" + e.message
- };
-}
-
-function showData (e) {
- for (let sParam in e) {
- console.log(sParam);
- console.log(e[sParam]);
- }
-}
-
-onconnect = function (e) {
- console.log("[Sharedworker] START CONNECTION");
- xPort = e.ports[0];
-
- xPort.onmessage = function (e) {
- console.log("[Sharedworker] ONMESSAGE");
- let {sCommand, dParam, dInfo} = e.data;
- console.log(e.data);
- switch (sCommand) {
- case "init":
- init(dParam.sExtensionPath, dParam.sOptions, dParam.sContext, dInfo);
- break;
- case "parse":
- parse(dParam.sText, dParam.sCountry, dParam.bDebug, dParam.bContext, dInfo);
- break;
- case "parseAndSpellcheck":
- parseAndSpellcheck(dParam.sText, dParam.sCountry, dParam.bDebug, dParam.bContext, dInfo);
- break;
- case "getOptions":
- getOptions(dInfo);
- break;
- case "getDefaultOptions":
- getDefaultOptions(dInfo);
- break;
- case "setOptions":
- setOptions(dParam.sOptions, dInfo);
- break;
- case "setOption":
- setOption(dParam.sOptName, dParam.bValue, dInfo);
- break;
- case "resetOptions":
- resetOptions(dInfo);
- break;
- case "textToTest":
- textToTest(dParam.sText, dParam.sCountry, dParam.bDebug, dParam.bContext, dInfo);
- break;
- case "fullTests":
- fullTests('{"nbsp":true, "esp":true, "unit":true, "num":true}', dInfo);
- break;
- case "getListOfTokens":
- getListOfTokens(dParam.sText, dInfo);
- break;
- default:
- console.log("Unknown command: " + sCommand);
- showData(e.data);
- }
- }
- //xPort.start();
-}
-
-let bInitDone = false;
-
-let oDict = null;
-let oTokenizer = null;
-let oLxg = null;
-let oTest = null;
-
-
-function init (sExtensionPath, sGCOptions="", sContext="JavaScript", dInfo={}) {
- try {
- if (!bInitDone) {
- console.log("[Sharedworker] Loading… Extension path: " + sExtensionPath);
- conj.init(helpers.loadFile(sExtensionPath + "/grammalecte/fr/conj_data.json"));
- phonet.init(helpers.loadFile(sExtensionPath + "/grammalecte/fr/phonet_data.json"));
- mfsp.init(helpers.loadFile(sExtensionPath + "/grammalecte/fr/mfsp_data.json"));
- console.log("[Sharedworker] Modules have been initialized…");
- gc_engine.load(sContext, sExtensionPath+"grammalecte/_dictionaries");
- oDict = gc_engine.getDictionary();
- oTest = new TestGrammarChecking(gc_engine, sExtensionPath+"/grammalecte/fr/tests_data.json");
- oLxg = new Lexicographe(oDict);
- if (sGCOptions !== "") {
- gc_engine.setOptions(helpers.objectToMap(JSON.parse(sGCOptions)));
- }
- oTokenizer = new Tokenizer("fr");
- //tests();
- bInitDone = true;
- } else {
- console.log("[Sharedworker] Already initialized…")
- }
- // we always retrieve options from the gc_engine, for setOptions filters obsolete options
- xPort.postMessage(createResponse("init", gc_engine.getOptions().gl_toString(), dInfo));
- }
- catch (e) {
- helpers.logerror(e);
- xPort.postMessage(createResponse("init", createErrorResult(e, "init failed"), dInfo, true));
- }
-}
-
-function parse (sText, sCountry, bDebug, bContext, dInfo={}) {
- let aGrammErr = gc_engine.parse(sText, sCountry, bDebug, bContext);
- xPort.postMessage({sActionDone: "parse", result: aGrammErr, dInfo: dInfo});
-}
-
-function parseAndSpellcheck (sText, sCountry, bDebug, bContext, dInfo={}) {
- let aGrammErr = gc_engine.parse(sText, sCountry, bDebug, bContext);
- let aSpellErr = oTokenizer.getSpellingErrors(sText, oDict);
- xPort.postMessage(createResponse("parseAndSpellcheck", {aGrammErr: aGrammErr, aSpellErr: aSpellErr}, dInfo));
-}
-
-function getOptions (dInfo={}) {
- xPort.postMessage(createResponse("getOptions", gc_engine.getOptions().gl_toString(), dInfo));
-}
-
-function getDefaultOptions (dInfo={}) {
- xPort.postMessage(createResponse("getDefaultOptions", gc_engine.getDefaultOptions().gl_toString(), dInfo));
-}
-
-function setOptions (sGCOptions, dInfo={}) {
- gc_engine.setOptions(helpers.objectToMap(JSON.parse(sGCOptions)));
- xPort.postMessage(createResponse("setOptions", gc_engine.getOptions().gl_toString(), dInfo));
-}
-
-function setOption (sOptName, bValue, dInfo={}) {
- gc_engine.setOptions(new Map([ [sOptName, bValue] ]));
- xPort.postMessage(createResponse("setOption", gc_engine.getOptions().gl_toString(), dInfo));
-}
-
-function resetOptions (dInfo={}) {
- gc_engine.resetOptions();
- xPort.postMessage(createResponse("resetOptions", gc_engine.getOptions().gl_toString(), dInfo));
-}
-
-function tests () {
- console.log(conj.getConj("devenir", ":E", ":2s"));
- console.log(mfsp.getMasForm("emmerdeuse", true));
- console.log(mfsp.getMasForm("pointilleuse", false));
- console.log(phonet.getSimil("est"));
- let aRes = gc_engine.parse("Je suit...");
- for (let oErr of aRes) {
- console.log(text.getReadableError(oErr));
- }
-}
-
-function textToTest (sText, sCountry, bDebug, bContext, dInfo={}) {
- if (!gc_engine || !oDict) {
- xPort.postMessage(createResponse("textToTest", "# Grammar checker or dictionary not loaded.", dInfo));
- return;
- }
- let aGrammErr = gc_engine.parse(sText, sCountry, bDebug, bContext);
- let sMsg = "";
- for (let oErr of aGrammErr) {
- sMsg += text.getReadableError(oErr) + "\n";
- }
- xPort.postMessage(createResponse("textToTest", sMsg, dInfo));
-}
-
-function fullTests (sGCOptions="", dInfo={}) {
- if (!gc_engine || !oDict) {
- xPort.postMessage(createResponse("fullTests", "# Grammar checker or dictionary not loaded.", dInfo));
- return;
- }
- let dMemoOptions = gc_engine.getOptions();
- if (sGCOptions) {
- gc_engine.setOptions(helpers.objectToMap(JSON.parse(sGCOptions)));
- }
- let sMsg = "";
- for (let sRes of oTest.testParse()) {
- sMsg += sRes + "\n";
- console.log(sRes);
- }
- gc_engine.setOptions(dMemoOptions);
- xPort.postMessage(createResponse("fullTests", sMsg, dInfo));
-}
-
-
-// Lexicographer
-
-function getListOfTokens (sText, dInfo={}) {
- try {
- let aElem = [];
- let aRes = null;
- for (let oToken of oTokenizer.genTokens(sText)) {
- aRes = oLxg.getInfoForToken(oToken);
- if (aRes) {
- aElem.push(aRes);
- }
- }
- xPort.postMessage(createResponse("getListOfTokens", aElem, dInfo));
- }
- catch (e) {
- helpers.logerror(e);
- xPort.postMessage(createResponse("getListOfTokens", createErrorResult(e, "no tokens"), dInfo, true));
- }
-}
Index: gc_lang/fr/webext/panel/main.html
==================================================================
--- gc_lang/fr/webext/panel/main.html
+++ gc_lang/fr/webext/panel/main.html
@@ -15,13 +15,13 @@
Grammalecte affiche un bouton d’accès au menu en bas à gauche des zones de texte usuelles pour accéder aux fonctionnalités existantes.
Pour les autres zones de texte (HTML éditable), il faut sélectionner le texte et utiliser le menu contextuel.