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 @@ -71,29 +71,31 @@ text-align: center; cursor: pointer; } div.grammalecte_copy_button { border-radius: 2px; - color: hsla(210, 0%, 100%, .5); + color: hsla(210, 0%, 100%, .4); margin-right: 10px; } div.grammalecte_copy_button:hover { - background-color: hsl(210, 90%, 35%, .5); + background-color: hsl(210, 50%, 55%); color: hsla(210, 0%, 100%, 1); } div.grammalecte_move_button { padding: 1px 5px; border-radius: 16px; color: hsl(180, 0%, 100%); - opacity: .5; + opacity: .2; } div.grammalecte_move_button_changeWidth { - padding: 3px 5px; + padding: 1px 10px; + background: center no-repeat url('data:image/svg+xml;utf8,'); } div.grammalecte_move_button_changeHeight { - padding: 3px 5px; + padding: 1px 10px; margin-right: 10px; + background: center no-repeat url('data:image/svg+xml;utf8,'); } div.grammalecte_move_button_center { padding: 1px 10px; background: center no-repeat url('data:image/svg+xml;utf8,') ; } @@ -101,15 +103,15 @@ padding: 1px 10px; background: center no-repeat url('data:image/svg+xml;utf8,'); } div.grammalecte_move_button_right { padding: 1px 10px; - background: center no-repeat url('data:image/svg+xml;utf8,'); + background: center no-repeat url('data:image/svg+xml;utf8,'); } div.grammalecte_move_button_down { padding: 1px 10px; - background: center no-repeat url('data:image/svg+xml;utf8,'); + background: center no-repeat url('data:image/svg+xml;utf8,'); } div.grammalecte_move_button_left { padding: 1px 10px; background: center no-repeat url('data:image/svg+xml;utf8,'); } 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 @@ -66,15 +66,16 @@ _createButtons () { let xButtonLine = oGrammalecte.createNode("div", {className: "grammalecte_panel_commands"}); xButtonLine.appendChild(this.xWaitIcon); if (this.sId === "grammalecte_gc_panel") { - xButtonLine.appendChild(this._createCopyButton()); + this.xClipboardButton = this._createCopyButton(); + xButtonLine.appendChild(this.xClipboardButton); } if (this.bFlexible) { - this.xWidthButton = this._createMoveButton("changeWidth", "L", "Étendre en largeur"); - this.xHeightButton = this._createMoveButton("changeHeight", "H", "Étendre en hauteur"); + this.xWidthButton = this._createMoveButton("changeWidth", " ", "Étendre en largeur"); + this.xHeightButton = this._createMoveButton("changeHeight", " ", "Étendre en hauteur"); xButtonLine.appendChild(this.xWidthButton); xButtonLine.appendChild(this.xHeightButton); } xButtonLine.appendChild(this._createMoveButton("up", " ", "Monter")); // use char ⏶ when Windows 10 be vast majority of OS (Trebuchet MS not updated on other OS) xButtonLine.appendChild(this._createMoveButton("left", " ", "À gauche")); // use char ⏴ when Windows 10 be vast majority of OS (Trebuchet MS not updated on other OS) @@ -183,12 +184,12 @@ } setSizeAndPosition () { // size if (this.xWidthButton && this.xHeightButton) { - this.xWidthButton.style.opacity = (this.bHorizStrech) ? .9 : .5; - this.xHeightButton.style.opacity = (this.bVertStrech) ? .9 : .5; + this.xWidthButton.style.opacity = (this.bHorizStrech) ? ".9" : ""; + this.xHeightButton.style.opacity = (this.bVertStrech) ? ".9" : ""; } let nWidth = Math.min(this.nWidth, window.innerWidth-200); let nHeight = ([4, 5, 6].includes(this.nPosition)) ? Math.min(this.nHeight, window.innerHeight-100) : Math.floor(window.innerHeight*0.45); if (this.bFlexible) { if (this.bHorizStrech) { 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 @@ -215,18 +215,31 @@ // paragraph let xParagraph = oGrammalecte.createNode("p", {id: "grammalecte_paragraph"+oResult.iParaNum, className: "grammalecte_paragraph", lang: "fr", contentEditable: "true"}, {para_num: oResult.iParaNum}); xParagraph.setAttribute("spellcheck", "false"); // doesn’t seem possible to use “spellcheck” as a common attribute. xParagraph.dataset.timer_id = "0"; xParagraph.addEventListener("input", function (xEvent) { + // timer for refreshing analysis window.clearTimeout(parseInt(xParagraph.dataset.timer_id)); xParagraph.dataset.timer_id = window.setTimeout(this.recheckParagraph.bind(this), 3000, oResult.iParaNum); + // save caret position let [nStart, nEnd] = oGrammalecte.getCaretPosition(xParagraph); xParagraph.dataset.caret_position_start = nStart; xParagraph.dataset.caret_position_end = nEnd; + // write text this.oTextControl.setParagraph(parseInt(xEvent.target.dataset.para_num), this.purgeText(xEvent.target.textContent)); this.oTextControl.write(); }.bind(this) + , true); + xParagraph.addEventListener("blur", function (xEvent) { + // remove timer for refreshing analysis + window.clearTimeout(parseInt(xParagraph.dataset.timer_id)); + // unset caret position + xParagraph.dataset.caret_position_start = "-1"; + xParagraph.dataset.caret_position_end = "-1"; + // recheck + this.recheckParagraph(oResult.iParaNum); + }.bind(this) , true); this._tagParagraph(xParagraph, oResult.sParagraph, oResult.iParaNum, oResult.aGrammErr, oResult.aSpellErr); // creation xNodeDiv.appendChild(xActionsBar); xNodeDiv.appendChild(xParagraph); @@ -333,13 +346,15 @@ this.xParent.getElementById("grammalecte_check"+xParagraph.dataset.para_num).style.animation = "grammalecte-pulse 1s linear infinite"; } freeParagraph (xParagraph) { xParagraph.contentEditable = "true"; - let nStart = parseInt(xParagraph.dataset.caret_position_start); - let nEnd = parseInt(xParagraph.dataset.caret_position_end); - oGrammalecte.setCaretPosition(xParagraph, nStart, nEnd); + if (xParagraph.dataset.caret_position_start !== "-1") { + let nStart = parseInt(xParagraph.dataset.caret_position_start); + let nEnd = parseInt(xParagraph.dataset.caret_position_end); + oGrammalecte.setCaretPosition(xParagraph, nStart, nEnd); + } this.xParent.getElementById("grammalecte_check"+xParagraph.dataset.para_num).textContent = "↻"; this.xParent.getElementById("grammalecte_check"+xParagraph.dataset.para_num).style.backgroundColor = ""; this.xParent.getElementById("grammalecte_check"+xParagraph.dataset.para_num).style.animation = ""; setTimeout(() => { this.xParent.getElementById("grammalecte_check"+xParagraph.dataset.para_num).style.boxShadow = ""; }, 500); } @@ -387,41 +402,42 @@ } copyTextToClipboard () { this.startWaitIcon(); try { - let sText = ""; // Dans un shadow, n’existe pas. let xElem = this.xParent.getElementById("grammalecte_gc_panel"); for (let xNode of xElem.getElementsByClassName("grammalecte_paragraph")) { sText += xNode.textContent + "\n"; } this._sendTextToClipboard(sText); - } catch (e) { showError(e); } this.stopWaitIcon(); } _sendTextToClipboard (sText) { - let xClipboardButton = this.xParent.getElementById("grammalecte_clipboard_button"); - xClipboardButton.textContent = "⇒ presse-papiers"; + this.xClipboardButton.textContent = "⇒ presse-papiers"; // Firefox 63+, Chrome 66+ // Working draft: https://developer.mozilla.org/en-US/docs/Web/API/Clipboard - navigator.clipboard.writeText(sText) - .then( - (res) => { window.setTimeout(() => { xClipboardButton.textContent = "📋"; }, 2000); } - ) - .catch( - (e) => { console.error(e); this._sendTextToClipboard(sText, xClipboardButton); } - ); + if (navigator.clipboard && navigator.clipboard.writeText) { + navigator.clipboard.writeText(sText) + .then( + (res) => { window.setTimeout(() => { this.xClipboardButton.textContent = "📋"; }, 2000); } + ) + .catch( + (e) => { console.error(e); this._sendTextToClipboard(sText); } + ); + } else { + this._sendTextToClipboardFallback(sText); + } } - _sendTextToClipboardFallback (sText, xClipboardButton) { + _sendTextToClipboardFallback (sText) { try { // Copy to clipboard fallback // recipe from https://github.com/mdn/webextensions-examples/blob/master/context-menu-copy-link-with-types/clipboard-helper.js function setClipboardData (xEvent) { document.removeEventListener("copy", setClipboardData, true); @@ -429,11 +445,11 @@ xEvent.preventDefault(); xEvent.clipboardData.setData("text/plain", sText); } document.addEventListener("copy", setClipboardData, true); document.execCommand("copy"); - window.setTimeout(() => { xClipboardButton.textContent = "📋"; }, 2000); + window.setTimeout(() => { this.xClipboardButton.textContent = "📋"; }, 2000); } catch (e) { console.error(e); } }