Grammalecte  Diff

Differences From Artifact [410ff2e6bf]:

To Artifact [a133afff43]:


49
50
51
52
53
54
55

56
57
58
59
60
61
62
63
64
65
66
67
68
69

    constructor (...args) {
        super(...args);
        this.aIgnoredErrors = new Set();
        this.createMenu()
        // Editor
        this.xGCPanelContent = oGrammalecte.createNode("div", {id: "grammalecte_gc_panel_content"});

        this.xParagraphList = oGrammalecte.createNode("div", {id: "grammalecte_paragraph_list"});
        this.xGCPanelContent.appendChild(this.xParagraphList);
        this.xPanelContent.addEventListener("click", onGrammalecteGCPanelClick, false);
        this.oTooltip = new GrammalecteTooltip(this.xParent, this.xGCPanelContent);
        this.xPanelContent.appendChild(this.xGCPanelContent);
        this.xNode = null;
        this.oNodeControl = new GrammalecteNodeControl();
        // Lexicographer
        this.nLxgCount = 0;
        this.xLxgPanelContent = oGrammalecte.createNode("div", {id: "grammalecte_lxg_panel_content"});
        this.xPanelContent.appendChild(this.xLxgPanelContent);
        // Conjugueur
        this.xConjPanelContent = oGrammalecte.createNode("div", {id: "grammalecte_conj_panel_content"});
        this.xConjPanelContent.innerHTML = sGrammalecteConjugueurHTML;  // @Reviewers: sGrammalecteConjugueurHTML is a const value defined in <content_scripts/html_src.js>







>






|







49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

    constructor (...args) {
        super(...args);
        this.aIgnoredErrors = new Set();
        this.createMenu()
        // Editor
        this.xGCPanelContent = oGrammalecte.createNode("div", {id: "grammalecte_gc_panel_content"});
        this.xGCPanelContent.style.marginBottom = "10px";
        this.xParagraphList = oGrammalecte.createNode("div", {id: "grammalecte_paragraph_list"});
        this.xGCPanelContent.appendChild(this.xParagraphList);
        this.xPanelContent.addEventListener("click", onGrammalecteGCPanelClick, false);
        this.oTooltip = new GrammalecteTooltip(this.xParent, this.xGCPanelContent);
        this.xPanelContent.appendChild(this.xGCPanelContent);
        this.xNode = null;
        this.oTextControl = new GrammalecteTextControl();
        // Lexicographer
        this.nLxgCount = 0;
        this.xLxgPanelContent = oGrammalecte.createNode("div", {id: "grammalecte_lxg_panel_content"});
        this.xPanelContent.appendChild(this.xLxgPanelContent);
        // Conjugueur
        this.xConjPanelContent = oGrammalecte.createNode("div", {id: "grammalecte_conj_panel_content"});
        this.xConjPanelContent.innerHTML = sGrammalecteConjugueurHTML;  // @Reviewers: sGrammalecteConjugueurHTML is a const value defined in <content_scripts/html_src.js>
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130



131
132


133
134
135

136
137


138
139
140
141
142

143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
        this.xTFButton = oGrammalecte.createNode("div", {className: "grammalecte_menu_button", textContent: "Formateur de texte"});
        this.xEditorButton = oGrammalecte.createNode("div", {className: "grammalecte_menu_button", textContent: "Éditeur"});
        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 = () => {
            if (!this.bWorking) {
                if (this.xNode && (this.xNode.tagName == "TEXTAREA" || this.xNode.tagName == "INPUT" || this.xNode.isContentEditable)) {
                    oGrammalecte.createTFPanel();
                    oGrammalecte.oTFPanel.start(this);
                    oGrammalecte.oTFPanel.show();
                } else {
                    oGrammalecte.showMessage("Aucune zone de texte éditable sur laquelle appliquer le formatage de texte.")
                }
            }
        };
        this.xEditorButton.onclick = () => {
            if (!this.bWorking) {
                this.showEditor();
            }
        };
        this.xLxgButton.onclick = () => {
            if (!this.bWorking) {
                this.showLexicographer();
                this.clearLexicographer();
                this.startWaitIcon();
                xGrammalectePort.postMessage({
                    sCommand: "getListOfTokens",
                    dParam: {sText: this.getParsedText()},
                    dInfo: ((this.xNode) ? {sTextAreaId: this.xNode.id} : {})
                });
            }
        };
        this.xConjButton.onclick = () => {
            if (!this.bWorking) {
                this.showConjugueur();
            }
        };
        this.xLEButton.onclick = () => {
            xGrammalectePort.postMessage({sCommand: "openLexiconEditor", dParam: null, dInfo: null});
        };
        this.xMenu.appendChild(this.xTFButton)
        this.xMenu.appendChild(this.xEditorButton)
        this.xMenu.appendChild(this.xLxgButton)
        this.xMenu.appendChild(this.xConjButton)
        this.xMenu.appendChild(this.xLEButton)
        this.xPanelBar.appendChild(this.xMenu);
    }

    start (xNode=null) {
        this.xNode = xNode;
        this.oTooltip.hide();
        this.bWorking = false;
        this.clear();



        if (xNode) {
            this.oNodeControl.setNode(xNode);


            if (!(xNode.tagName == "TEXTAREA" || xNode.tagName == "INPUT")) {
                this.showMessage("La zone de texte analysée est un champ textuel enrichi susceptible de contenir des éléments non textuels qui seront effacés lors de la correction.");
            }

        } else {
            this.oNodeControl.clear();


        }
    }

    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.tagName == "INPUT") ? this.xNode.value.normalize("NFC") : this.xNode.innerText.normalize("NFC");
        } else {
            return oGrammalecte.getPageText();
        }
    }

    showEditor () {
        this.switchContentOn(this.xGCPanelContent, this.xEditorButton);
        this.switchContentOff(this.xLxgPanelContent, this.xLxgButton);
        this.switchContentOff(this.xConjPanelContent, this.xConjButton);
    }

    showLexicographer () {







<
|
|
|
<
<
<














|




















|
<



>
>
>
|
|
>
>
|
<
<
>

|
>
>





>




|




<
<
<
<
<
<
<
<







78
79
80
81
82
83
84

85
86
87



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
131
132
133
134


135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154








155
156
157
158
159
160
161
        this.xTFButton = oGrammalecte.createNode("div", {className: "grammalecte_menu_button", textContent: "Formateur de texte"});
        this.xEditorButton = oGrammalecte.createNode("div", {className: "grammalecte_menu_button", textContent: "Éditeur"});
        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 = () => {
            if (!this.bWorking) {

                oGrammalecte.createTFPanel();
                oGrammalecte.oTFPanel.start();
                oGrammalecte.oTFPanel.show();



            }
        };
        this.xEditorButton.onclick = () => {
            if (!this.bWorking) {
                this.showEditor();
            }
        };
        this.xLxgButton.onclick = () => {
            if (!this.bWorking) {
                this.showLexicographer();
                this.clearLexicographer();
                this.startWaitIcon();
                xGrammalectePort.postMessage({
                    sCommand: "getListOfTokens",
                    dParam: {sText: this.oTextControl.getText()},
                    dInfo: ((this.xNode) ? {sTextAreaId: this.xNode.id} : {})
                });
            }
        };
        this.xConjButton.onclick = () => {
            if (!this.bWorking) {
                this.showConjugueur();
            }
        };
        this.xLEButton.onclick = () => {
            xGrammalectePort.postMessage({sCommand: "openLexiconEditor", dParam: null, dInfo: null});
        };
        this.xMenu.appendChild(this.xTFButton)
        this.xMenu.appendChild(this.xEditorButton)
        this.xMenu.appendChild(this.xLxgButton)
        this.xMenu.appendChild(this.xConjButton)
        this.xMenu.appendChild(this.xLEButton)
        this.xPanelBar.appendChild(this.xMenu);
    }

    start (what) {

        this.oTooltip.hide();
        this.bWorking = false;
        this.clear();
        this.hideMessage();
        if (typeof(what) === "string") {
            // text
            this.xNode = null;
            this.oTextControl.setText(what);
        } else if (what.nodeType && what.nodeType === 1) {
            // node
            this.xNode = what;


            this.oTextControl.setNode(this.xNode);
        } else {
            // error
            oGrammalecte.oMessageBox.showMessage("[BUG] Analyse d’un élément inconnu…");
            console.log("Grammalecte [bug]:", what);
        }
    }

    recheckAll () {
        this.oTooltip.hide();
        this.showEditor();
        this.clear();
        this.startWaitIcon();
        xGrammalectePort.postMessage({
            sCommand: "parseAndSpellcheck",
            dParam: {sText: this.oTextControl.getText(), sCountry: "FR", bDebug: false, bContext: false},
            dInfo: ((this.xNode) ? {sTextAreaId: this.xNode.id} : {})
        });
    }









    showEditor () {
        this.switchContentOn(this.xGCPanelContent, this.xEditorButton);
        this.switchContentOff(this.xLxgPanelContent, this.xLxgButton);
        this.switchContentOff(this.xConjPanelContent, this.xConjButton);
    }

    showLexicographer () {
195
196
197
198
199
200
201



202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
        while (this.xParagraphList.firstChild) {
            this.xParagraphList.removeChild(this.xParagraphList.firstChild);
        }
        this.aIgnoredErrors.clear();
    }

    hide () {



        this.xPanel.style.display = "none";
        this.oNodeControl.clear();
    }

    addParagraphResult (oResult) {
        try {
            if (oResult && (oResult.sParagraph.trim() !== "" || oResult.aGrammErr.length > 0 || oResult.aSpellErr.length > 0)) {
                let xNodeDiv = oGrammalecte.createNode("div", {className: "grammalecte_paragraph_block"});
                // actions
                let xActionsBar = oGrammalecte.createNode("div", {className: "grammalecte_paragraph_actions"});
                xActionsBar.appendChild(oGrammalecte.createNode("div", {id: "grammalecte_check" + oResult.iParaNum, className: "grammalecte_paragraph_button grammalecte_green", textContent: "↻", title: "Réanalyser…"}, {para_num: oResult.iParaNum}));
                xActionsBar.appendChild(oGrammalecte.createNode("div", {id: "grammalecte_hide" + oResult.iParaNum, className: "grammalecte_paragraph_button grammalecte_red", textContent: "×", title: "Cacher", style: "font-weight: bold;"}));
                // 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) {
                    window.clearTimeout(parseInt(xParagraph.dataset.timer_id));
                    xParagraph.dataset.timer_id = window.setTimeout(this.recheckParagraph.bind(this), 3000, oResult.iParaNum);
                    let [nStart, nEnd] = oGrammalecte.getCaretPosition(xParagraph);
                    xParagraph.dataset.caret_position_start = nStart;
                    xParagraph.dataset.caret_position_end = nEnd;
                    this.oNodeControl.setParagraph(parseInt(xEvent.target.dataset.para_num), this.purgeText(xEvent.target.textContent));
                    this.oNodeControl.write();
                }.bind(this)
                , true);
                this._tagParagraph(xParagraph, oResult.sParagraph, oResult.iParaNum, oResult.aGrammErr, oResult.aSpellErr);
                // creation
                xNodeDiv.appendChild(xActionsBar);
                xNodeDiv.appendChild(xParagraph);
                this.xParagraphList.appendChild(xNodeDiv);







>
>
>

|




















|
|







190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
        while (this.xParagraphList.firstChild) {
            this.xParagraphList.removeChild(this.xParagraphList.firstChild);
        }
        this.aIgnoredErrors.clear();
    }

    hide () {
        if (oGrammalecte.oTFPanel) { oGrammalecte.oTFPanel.hide(); }
        if (oGrammalecte.oMessageBox) { oGrammalecte.oMessageBox.hide(); }
        oGrammalecte.clearRightClickedNode();
        this.xPanel.style.display = "none";
        this.oTextControl.clear();
    }

    addParagraphResult (oResult) {
        try {
            if (oResult && (oResult.sParagraph.trim() !== "" || oResult.aGrammErr.length > 0 || oResult.aSpellErr.length > 0)) {
                let xNodeDiv = oGrammalecte.createNode("div", {className: "grammalecte_paragraph_block"});
                // actions
                let xActionsBar = oGrammalecte.createNode("div", {className: "grammalecte_paragraph_actions"});
                xActionsBar.appendChild(oGrammalecte.createNode("div", {id: "grammalecte_check" + oResult.iParaNum, className: "grammalecte_paragraph_button grammalecte_green", textContent: "↻", title: "Réanalyser…"}, {para_num: oResult.iParaNum}));
                xActionsBar.appendChild(oGrammalecte.createNode("div", {id: "grammalecte_hide" + oResult.iParaNum, className: "grammalecte_paragraph_button grammalecte_red", textContent: "×", title: "Cacher", style: "font-weight: bold;"}));
                // 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) {
                    window.clearTimeout(parseInt(xParagraph.dataset.timer_id));
                    xParagraph.dataset.timer_id = window.setTimeout(this.recheckParagraph.bind(this), 3000, oResult.iParaNum);
                    let [nStart, nEnd] = oGrammalecte.getCaretPosition(xParagraph);
                    xParagraph.dataset.caret_position_start = nStart;
                    xParagraph.dataset.caret_position_end = nEnd;
                    this.oTextControl.setParagraph(parseInt(xEvent.target.dataset.para_num), this.purgeText(xEvent.target.textContent));
                    this.oTextControl.write();
                }.bind(this)
                , true);
                this._tagParagraph(xParagraph, oResult.sParagraph, oResult.iParaNum, oResult.aGrammErr, oResult.aSpellErr);
                // creation
                xNodeDiv.appendChild(xActionsBar);
                xNodeDiv.appendChild(xParagraph);
                this.xParagraphList.appendChild(xNodeDiv);
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
        this.blockParagraph(xParagraph);
        let sText = this.purgeText(xParagraph.textContent);
        xGrammalectePort.postMessage({
            sCommand: "parseAndSpellcheck1",
            dParam: {sText: sText, sCountry: "FR", bDebug: false, bContext: false},
            dInfo: {sParagraphId: sParagraphId}
        });
        this.oNodeControl.setParagraph(iParaNum, sText);
        this.oNodeControl.write();
    }

    refreshParagraph (sParagraphId, oResult) {
        try {
            let xParagraph = this.xParent.getElementById(sParagraphId);
            xParagraph.className = (oResult.aGrammErr.length || oResult.aSpellErr.length) ? "grammalecte_paragraph softred" : "grammalecte_paragraph";
            xParagraph.textContent = "";







|
|







241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
        this.blockParagraph(xParagraph);
        let sText = this.purgeText(xParagraph.textContent);
        xGrammalectePort.postMessage({
            sCommand: "parseAndSpellcheck1",
            dParam: {sText: sText, sCountry: "FR", bDebug: false, bContext: false},
            dInfo: {sParagraphId: sParagraphId}
        });
        this.oTextControl.setParagraph(iParaNum, sText);
        this.oTextControl.write();
    }

    refreshParagraph (sParagraphId, oResult) {
        try {
            let xParagraph = this.xParent.getElementById(sParagraphId);
            xParagraph.className = (oResult.aGrammErr.length || oResult.aSpellErr.length) ? "grammalecte_paragraph softred" : "grammalecte_paragraph";
            xParagraph.textContent = "";
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
    constructor (xParent, xGCPanelContent) {
        this.xParent = xParent;
        this.sErrorId = null;
        this.bDebug = false;
        this.xTooltip = oGrammalecte.createNode("div", {id: "grammalecte_tooltip"});
        this.xTooltipArrow = oGrammalecte.createNode("img", {
            id: "grammalecte_tooltip_arrow",
            src: " data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwAAADsABataJCQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xNzNun2MAAAAnSURBVChTY/j//z8cq/kW/wdhZDEMSXRFWCVhGKwAmwQyHngFxf8B5fOGYfeFpYoAAAAASUVORK5CYII=",
            alt: "^",
        });
        // message
        let xMessageBlock = oGrammalecte.createNode("div", {id: "grammalecte_tooltip_message_block"});
        xMessageBlock.appendChild(oGrammalecte.createNode("div", {id: "grammalecte_tooltip_rule_id"}));
        xMessageBlock.appendChild(oGrammalecte.createNode("div", {id: "grammalecte_tooltip_message", textContent: "Erreur."}));
        this.xTooltip.appendChild(xMessageBlock);







|







708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
    constructor (xParent, xGCPanelContent) {
        this.xParent = xParent;
        this.sErrorId = null;
        this.bDebug = false;
        this.xTooltip = oGrammalecte.createNode("div", {id: "grammalecte_tooltip"});
        this.xTooltipArrow = oGrammalecte.createNode("img", {
            id: "grammalecte_tooltip_arrow",
            src: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwAAADsABataJCQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xNzNun2MAAAAnSURBVChTY/j//z8cq/kW/wdhZDEMSXRFWCVhGKwAmwQyHngFxf8B5fOGYfeFpYoAAAAASUVORK5CYII=",
            alt: "^",
        });
        // message
        let xMessageBlock = oGrammalecte.createNode("div", {id: "grammalecte_tooltip_message_block"});
        xMessageBlock.appendChild(oGrammalecte.createNode("div", {id: "grammalecte_tooltip_rule_id"}));
        xMessageBlock.appendChild(oGrammalecte.createNode("div", {id: "grammalecte_tooltip_message", textContent: "Erreur."}));
        this.xTooltip.appendChild(xMessageBlock);
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884



885






886
887
888
889
890
891
892
893
894
895
896
897








898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918

919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
            xSuggBlock.appendChild(document.createTextNode("# Oups. Le mécanisme de suggestion orthographique a rencontré un bug… (Ce module est encore en phase β.)"));
            showError(e);
        }
    }
}


class GrammalecteNodeControl {

    constructor () {
        this.xNode = null;
        this.dParagraph = new Map();
        this.bTextArea = null;
    }

    setNode (xNode) {
        this.clear();
        this.xNode = xNode;
        this.bTextArea = (xNode.tagName == "TEXTAREA" || xNode.tagName == "INPUT");



        this.xNode.disabled = true;






        this._loadText();
    }

    clear () {
        if (this.xNode !== null) {
            this.xNode.disabled = false;
            this.bTextArea = false;
            this.xNode = null;
        }
        this.dParagraph.clear();
    }









    setParagraph (iParagraph, sText) {
        if (this.xNode !== null) {
            this.dParagraph.set(iParagraph, sText);
        }
    }

    _loadText () {
        let sText = (this.bTextArea) ? this.xNode.value : this.xNode.innerText;
        let i = 0;
        let iStart = 0;
        let iEnd = 0;
        sText = sText.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/­/g, "").normalize("NFC");
        while ((iEnd = sText.indexOf("\n", iStart)) !== -1) {
            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));
    }


    eraseContent () {
        while (this.xNode.firstChild) {
            this.xNode.removeChild(this.xNode.firstChild);
        }
    }

    write () {
        if (this.xNode !== null) {
            let sText = "";
            if (this.bTextArea) {
                this.dParagraph.forEach(function (val, key) {
                    sText += val + "\n";
                });
                this.xNode.value = sText.slice(0,-1).normalize("NFC");
            } else {
                this.eraseContent();
                this.dParagraph.forEach((val, key) => {
                    this.xNode.appendChild(document.createTextNode(val.normalize("NFC")));
                    this.xNode.appendChild(document.createElement("br"));
                });
            }
        }
    }
}







|











>
>
>

>
>
>
>
>
>
|











>
>
>
>
>
>
>
>

<
|
|
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|









<
<
<
|

|








864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913

914
915
916

917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942



943
944
945
946
947
948
949
950
951
952
953
            xSuggBlock.appendChild(document.createTextNode("# Oups. Le mécanisme de suggestion orthographique a rencontré un bug… (Ce module est encore en phase β.)"));
            showError(e);
        }
    }
}


class GrammalecteTextControl {

    constructor () {
        this.xNode = null;
        this.dParagraph = new Map();
        this.bTextArea = null;
    }

    setNode (xNode) {
        this.clear();
        this.xNode = xNode;
        this.bTextArea = (xNode.tagName == "TEXTAREA" || xNode.tagName == "INPUT");
        if (!this.bTextArea) {
            oGrammalecte.oGCPanel.showMessage("La zone de texte analysée est un champ textuel enrichi susceptible de contenir des éléments non textuels qui seront effacés lors de la correction.");
        }
        this.xNode.disabled = true;
        this.loadText((this.bTextArea) ? this.xNode.value : this.xNode.innerText);
    }

    setText (sText) {
        this.clear();
        oGrammalecte.oGCPanel.showMessage("Le texte analysé n’appartient pas à un champ textuel défini. Les modifications ne seront pas répercutées sur la zone d’où le texte a été extrait. Vous pouvez néanmoins récupérer l’ensemble du texte corrigé avec le bouton 📋.");
        this.loadText(sText);
    }

    clear () {
        if (this.xNode !== null) {
            this.xNode.disabled = false;
            this.bTextArea = false;
            this.xNode = null;
        }
        this.dParagraph.clear();
    }

    getText () {
        let sText = "";
        this.dParagraph.forEach(function (val, key) {
            sText += val + "\n";
        });
        return sText.slice(0,-1).normalize("NFC");
    }

    setParagraph (iParagraph, sText) {

        this.dParagraph.set(iParagraph, sText);
    }


    loadText (sText) {
        if (typeof(sText) === "string") {
            let i = 0;
            let iStart = 0;
            let iEnd = 0;
            sText = sText.replace(/\r\n/g, "\n").replace(/\r/g, "\n").normalize("NFC");
            while ((iEnd = sText.indexOf("\n", iStart)) !== -1) {
                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));
        }
    }

    eraseNodeContent () {
        while (this.xNode.firstChild) {
            this.xNode.removeChild(this.xNode.firstChild);
        }
    }

    write () {
        if (this.xNode !== null) {
            let sText = "";
            if (this.bTextArea) {



                this.xNode.value = this.getText();
            } else {
                this.eraseNodeContent();
                this.dParagraph.forEach((val, key) => {
                    this.xNode.appendChild(document.createTextNode(val.normalize("NFC")));
                    this.xNode.appendChild(document.createElement("br"));
                });
            }
        }
    }
}