Index: gc_lang/fr/build.py ================================================================== --- gc_lang/fr/build.py +++ gc_lang/fr/build.py @@ -28,14 +28,14 @@ def _createOptionsForWebExtension (dVars): sHTML = "" sLang = dVars['sDefaultUILang'] for sSection, lOpt in dVars['lStructOpt']: - sHTML += f'\n
\n

{dVars["dOptLabel"][sLang][sSection][0]}

\n' + sHTML += '\n
\n

{dVars["dOptLabel"][sLang][sSection][0]}

\n' for lLineOpt in lOpt: for sOpt in lLineOpt: - sHTML += f'

\n' + sHTML += '

\n' sHTML += '
\n' return sHTML def createFirefoxExtension (sLang, dVars): 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 @@ -296,5 +296,30 @@ /* Start */ oGrammalecte.listenRightClick(); oGrammalecte.createMenus(); + +/* + When a textarea is added via jascript we add the menu :) +*/ +let observer = new MutationObserver(function(mutations) { + mutations.forEach(function(mutation) { + for(let i = 0; i < mutation.addedNodes.length; i++){ + if ( mutation.addedNodes[i].getElementsByTagName ){ + if ( mutation.addedNodes[i].tagName == "TEXTAREA" ) { + oGrammalecte.lMenu.push(new GrammalecteMenu(oGrammalecte.nMenu, mutation.addedNodes[i])); + oGrammalecte.nMenu += 1; + } else { + for (let xNode of mutation.addedNodes[i].getElementsByTagName("textarea")) { + oGrammalecte.lMenu.push(new GrammalecteMenu(oGrammalecte.nMenu, xNode)); + oGrammalecte.nMenu += 1; + } + } + } + } + }); +}); +observer.observe(document.body, { + childList: true, + subtree: true +}); 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 @@ -6,10 +6,11 @@ /* Button */ .grammalecte_menu_main_button { position: absolute; + box-sizing: border-box; display: none; margin: -8px 0 0 -8px; width: 8px; height: 8px; background-color: hsla(210, 80%, 80%, .5); @@ -61,10 +62,12 @@ border: 3px solid hsl(210, 50%, 30%); 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; + line-height: 21px; } .grammalecte_menu_close_button { float: right; margin: 2px 2px 0 0; @@ -73,10 +76,11 @@ background-color: hsl(0, 50%, 50%); color: hsl(0, 20%, 90%); font-size: 12px; font-weight: bold; cursor: pointer; + height: 20px; } .grammalecte_menu_close_button:hover { background-color: hsl(0, 60%, 50%); color: hsl(0, 30%, 96%); } 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 @@ -4,74 +4,90 @@ class GrammalecteMenu { constructor (nMenu, xNode) { + this.xNode = xNode; this.sMenuId = "grammalecte_menu" + nMenu; 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(xNode); - this._insertAfter(this.xButton, xNode); - this._insertAfter(this.xMenu, xNode); - this._createListenersOnReferenceNode(xNode); + this.xMenu = this._createMenu(); + + let style = window.getComputedStyle(this.xNode); + let topMargin = -1 * (8 + parseInt(style.marginBottom.replace('px', ''), 10)); + + let insAfterThis = this.xNode; + if ( document.location.host == "twitter.com" && this.xNode.classList.contains('rich-editor')){ + insAfterThis = this.xNode.parentNode; + } + + this._insertAfter(this.xButton, insAfterThis); + this.xButton.style.marginTop = topMargin + 'px'; + + this._insertAfter(this.xMenu, insAfterThis); + this.xMenu.style.marginTop = (topMargin + 8) + 'px'; + + this._createListenersOnReferenceNode(); } _insertAfter (xNewNode, xReferenceNode) { xReferenceNode.parentNode.insertBefore(xNewNode, xReferenceNode.nextSibling); } - _createListenersOnReferenceNode (xNode) { - xNode.addEventListener('focus', (e) => { + _createListenersOnReferenceNode () { + this.xNode.addEventListener('focus', (e) => { this.xButton.style.display = "block"; }); - xNode.addEventListener('blur', (e) => { + this.xNode.addEventListener('blur', (e) => { window.setTimeout(() => {this.xButton.style.display = "none";}, 300); }); } - _createMenu (xNode) { + _getText () { + return (this.xNode.tagName == "TEXTAREA") ? this.xNode.value : this.xNode.innerText; + } + + _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 = () => { this.switchMenu(); } xMenu.appendChild(xCloseButton); xMenu.appendChild(oGrammalecte.createNode("div", {className: "grammalecte_menu_header", textContent: "GRAMMALECTE"})); // Text formatter - if (xNode.tagName == "TEXTAREA") { + if (this.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.start(this.xNode); oGrammalecte.oTFPanel.show(); }; xMenu.appendChild(xTFButton); } // lexicographe let xLxgButton = oGrammalecte.createNode("div", {className: "grammalecte_menu_item", textContent: "Lexicographe"}); xLxgButton.onclick = () => { this.switchMenu(); - let sText = (xNode.tagName == "TEXTAREA") ? xNode.value : xNode.innerText; oGrammalecte.startLxgPanel(); xGrammalectePort.postMessage({ sCommand: "getListOfTokens", - dParam: {sText: sText}, - dInfo: {sTextAreaId: xNode.id} + dParam: {sText: this._getText()}, + dInfo: {sTextAreaId: this.xNode.id} }); }; xMenu.appendChild(xLxgButton); // Grammar checker let xGCButton = oGrammalecte.createNode("div", {className: "grammalecte_menu_item", textContent: "Correction grammaticale"}); xGCButton.onclick = () => { this.switchMenu(); - let sText = (xNode.tagName == "TEXTAREA") ? xNode.value : xNode.innerText; - oGrammalecte.startGCPanel(xNode); + oGrammalecte.startGCPanel(this.xNode); xGrammalectePort.postMessage({ sCommand: "parseAndSpellcheck", - dParam: {sText: sText, sCountry: "FR", bDebug: false, bContext: false}, - dInfo: {sTextAreaId: xNode.id} + dParam: {sText: this._getText(), sCountry: "FR", bDebug: false, bContext: false}, + dInfo: {sTextAreaId: this.xNode.id} }); }; xMenu.appendChild(xGCButton); // Conjugation tool let xConjButton = oGrammalecte.createNode("div", {className: "grammalecte_menu_item_block", textContent: "Conjugueur"});