Grammalecte  Check-in [8bb3b9bc37]

Overview
Comment:[fx] remove old Firefox extension from source
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk | fx
Files: files | file ages | folders
SHA3-256: 8bb3b9bc3767544148dbface0a5f951160231c2cbc5d4effc4136d81c25de8ad
User & Date: olr on 2018-08-20 08:00:41
Other Links: manifest | tags
Context
2018-08-20
08:08
[build][fr] remove dead code for old Firefox extension check-in: be90ac8704 user: olr tags: trunk, fr, build
08:00
[fx] remove old Firefox extension from source check-in: 8bb3b9bc37 user: olr tags: trunk, fx
07:56
[tb] move Hunspell dictionaries from old Firefox extension to Thunberbird extension source check-in: d07aeb0b28 user: olr tags: trunk, tb
Changes

Deleted gc_lang/fr/xpi/README.txt version [2d1b4f42d1].

1
2
3
4
5
6
7
8
9
10
11
12
13
14

= GRAMMALECTE =

French grammar checker
By Olivier R. (olivier /at/ grammalecte /dot/ net)

Website: http://www.dicollecte.org/grammalecte

License: GPL 3 -- http://www.gnu.org/copyleft/gpl.html

Grammalecte for Firefox is a derivative tool born from the version
for LibreOffice written in Python.

Written in JavaScript ES6/ES7.
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























Deleted gc_lang/fr/xpi/chrome.manifest version [84f3dd0c20].

1
2
3
# https://developer.mozilla.org/en-US/docs/Chrome_Registration
content promiseworker ./
resource grammalecte ./grammalecte/
<
<
<






Deleted gc_lang/fr/xpi/data/about_panel.css version [01be88bd1f].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
/* panel.css */

@import url("common.css");

header {
    background-color: hsl(0, 0%, 96%);
    border-bottom: 1px solid hsl(0, 0%, 90%);
    padding: 10px 0;
    font-family: "Verdana", sans-serif;
    color: hsl(0, 0%, 0%);
}

body {
	background-color: hsl(0, 0%, 86%);
	font-family: "Trebuchet MS", sans-serif;
	overflow-x: hidden;
    color: hsl(0, 0%, 0%);
}

h1 {
    font-size: 20px;
    color: hsl(210, 30%, 40%);
    font-family: "Trebuchet MS", sans-serif;
}

p.underline {
    padding: 5px 0;
    background-color: hsl(210, 5%, 92%);
    margin-bottom: 10px;
    color: hsl(0, 0%, 0%);
}

.key {
    display: inline-block;
    width: 170px;
    letter-spacing: -0.08em;
}
.goto {
    letter-spacing: -0.08em;
}

#links {
    padding: 6px 0 3px 0;
}

a.link {
    color: hsl(210, 30%, 40%);
    text-decoration: none;
}
a.link:hover {
    color: hsl(210, 30%, 30%);
    text-shadow: 0 0 3px hsl(210, 30%, 40%);
}

#dictionaries_info {
    margin: 10px 0;
    padding: 10px;
    border-radius: 3px;
    background-color: hsl(0, 50%, 40%);
    color: hsl(0, 10%, 96%);
}
.dict_section {
    padding: 10px;
    margin-bottom: 10px;
    border-radius: 5px;
}
.dict_section label {
    font-size: 16px;
    line-height: 20px;
    color: hsl(210, 20%, 50%);
    font-weight: bold;
}
.dict_description {
    padding: 5px 0 0 20px;
    color: hsl(0, 0%, 0%);
}

#help_section {
    background-color: hsl(0, 0%, 98%);
    padding: 10px;
}

#spelling_section {
    display: none;
    background-color: hsl(0, 0%, 98%);
    padding: 10px;
}

#grammar_section {
    display: none;
    background-color: hsl(0, 0%, 98%);
    padding: 10px;
}

.opt_subsection {
    margin: 5px 0;
    padding: 10px;
    background-color: hsl(0, 0%, 92%);
    border-radius: 3px;
}

.opt_subsection h2 {
    color: hsl(210, 30%, 50%);
    margin-bottom: 3px;
    font-size: 16px;
    font-family: "Trebuchet MS", sans-serif;
}
.opt_subsection p {
    padding: 2px 3px;
    display:flex;
    align-items:center;
}
.opt_subsection p:hover {
    background-color: hsl(210, 10%, 86%);
    border-radius: 2px;
}
.opt_subsection label {
    flex: 1;
}
.opt_subsection input {
    order: 1
}

#grammar_section a {
    padding: 5px 10px;
    background-color: hsl(210, 40%, 50%);
    color: hsl(0, 0%, 96%);
    text-decoration: none;
    border-radius: 3px;
    font-size: 16px;
}
#grammar_section a:hover {
    background-color: hsl(210, 50%, 40%);
    color: color: hsl(0, 10%, 98%);
}

a.bluebutton {
    padding: 2px 5px;
    background-color: hsl(210, 40%, 50%);
    color: hsl(210, 0%, 96%);
    text-decoration: none;
    border-radius: 3px;
}
a.bluebutton:hover {
    background-color: hsl(210, 50%, 55%);
    color: hsl(210, 0%, 100%);
}

a.redbutton {
    padding: 2px 5px;
    background-color: hsl(0, 40%, 50%);
    color: hsl(0, 0%, 96%);
    text-decoration: none;
    border-radius: 3px;
}
a.redbutton:hover {
    background-color: hsl(0, 50%, 55%);
    color: hsl(0, 0%, 100%);
}

a.greenbutton {
    padding: 2px 5px;
    background-color: hsl(150, 40%, 40%);
    color: hsl(150, 0%, 96%);
    text-decoration: none;
    border-radius: 3px;
}
a.greenbutton:hover {
    background-color: hsl(150, 50%, 45%);
    color: hsl(0, 0%, 100%);
}

a.simplelink {
    color: hsl(180, 50%, 20%);
    text-decoration: none;
    text-shadow: 0 0 1px hsl(180, 20%, 50%);
}
a.simplelink:hover {
    color: hsl(180, 80%, 20%);
    text-shadow: 0 0 1px hsl(180, 50%, 10%);
}

footer#promo {
    background-color: hsl(0, 0%, 92%);
    border-top: 1px solid hsl(0, 0%, 86%);
    padding: 10px;
}

footer#thanks {
    background-color: hsl(0, 0%, 86%);
    border-top: 1px solid hsl(0, 0%, 80%);
    padding: 15px 15px;
}
footer#thanks p {
    margin: 3px 0;
    font-size: 14px;
}

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































































































































Deleted gc_lang/fr/xpi/data/about_panel.html version [d97e8549df].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<!DOCTYPE HTML>
<html>
    <head>
        <link rel="stylesheet" type="text/css" href="about_panel.css" />
        <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
    </head>
    
    <body class="panel">
        <header>
            <p class="center"><img src="img/logo120_text.png" alt="Grammalecte"></p>
            <p class="underline center">
                <b>Version ${version}</b>
            </p>
            <p id="links" class="center">
                <a id="spelling" class="bluebutton" href="#" onclick="return false;" data-l10n-id="spelling"></a> ·
                <a id="grammar" class="bluebutton" href="#" onclick="return false;" data-l10n-id="grammar"></a> ·
                <a id="conjugueur" class="redbutton" href="#" onclick="return false;" data-l10n-id="conjugueur"></a>
            </p>
        </header>
        
        <div id="help_section">
            <p data-l10n-id="useContextMenu"></p>
            <p class="right"><img src="img/contextmenu.png" title="menu contextuel sur zone de texte" /></p>
            <p><b data-l10n-id="shortcuts"></b></p>
            <p><span class="key" data-l10n-id="keyTF"></span> &#10097; <span class="goto" data-l10n-id="keyLabelTF"></span></p>
            <p><span class="key" data-l10n-id="keyGC"></span> &#10097; <span class="goto" data-l10n-id="keyLabelGC"></span></p>
            <p><span class="key" data-l10n-id="keyCJ"></span> &#10097; <span class="goto" data-l10n-id="keyLabelCJ"></span></p>
        </div>

        <div id="grammar_section">
            <h1 class="center" data-l10n-id="grammar_options"></h1>
            ${optionsHTML}
            <p class="center" style="margin: 10px 0;"><a id="default_options" href="#" onclick="return false;" data-l10n-id="default_options"></a></p>
        </div>
        
        <div id="spelling_section">
            <h1 class="center" data-l10n-id="spelling_options"></h1>
            <p id="dictionaries_info" data-l10n-id="dictionaries_info"></p>
            <div class="dict_section" id="fr-FR-modern_box">
                <p><input type="checkbox" id="fr-FR-modern" /> <label for="fr-FR-modern" data-l10n-id="dict_modern"></label></p>
                <p class="dict_description" data-l10n-id="dict_modern_descr"></p>
            </div>
            <div class="dict_section" id="fr-FR-classic_box">
                <p><input type="checkbox" id="fr-FR-classic" /> <label for="fr-FR-classic" data-l10n-id="dict_classic"></label></p>
                <p class="dict_description" data-l10n-id="dict_classic_descr"></p>
            </div>
            <div class="dict_section" id="fr-FR-reform_box">
                <p><input type="checkbox" id="fr-FR-reform" /> <label for="fr-FR-reform" data-l10n-id="dict_reform"></label></p>
                <p class="dict_description" data-l10n-id="dict_reform_descr"></p>
            </div>
            <div class="dict_section" id="fr-FR-classic-reform_box">
                <p><input type="checkbox" id="fr-FR-classic-reform" /> <label for="fr-FR-classic-reform" data-l10n-id="dict_classic_reform"></label></p>
                <p class="dict_description" data-l10n-id="dict_classic_reform_descr"></p>
            </div>
        </div>

        <footer id="promo">
            <p class="center">
                <span data-l10n-id="general_info"></span> &nbsp; · &nbsp;
                <a id="website" class="simplelink" href="#" onclick="return false;" data-l10n-id="website"></a>
            </p>
        </footer>
        
        <footer id="thanks">
            <p class="center" data-l10n-id="thanks1"></p>
            <p class="center">
                <a id="mainsponsor" href="#" onclick="return false;">
                    <img src="img/LaMouette.png" style="border: 1px solid #C0C0C0" />
                </a>
            </p>
            <p class="center">
                <a id="mainsponsor2" href="#" onclick="return false;">
                    <img src="img/Algoo_logo.png" style="border: 1px solid #C0C0C0" />
                </a>
            </p>
            <p class="center">
                <a id="othersponsors" class="link" href="https://www.dicollecte.org/#thanks" onclick="return false;">
                    <b data-l10n-id="thanks2"></b>
                </a>
            </p>
        </footer>
    </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































Deleted gc_lang/fr/xpi/data/about_panel.js version [167eaa05ef].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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
// JavaScript

let nDefaultPanelHeight = 0;


/*
	Events
*/

self.port.on("sendGrammarOptionsToPanel", function (sGCOptions) {
	setGrammarOptionsOnPanel(JSON.parse(sGCOptions));
});

self.port.on("sendSpellingOptionsToPanel", function (bDicMod, bDicClas, bDicRef, bDicAll) {
	setPanelDictOption("fr-FR-modern", bDicMod);
	setPanelDictOption("fr-FR-classic", bDicClas);
	setPanelDictOption("fr-FR-reform", bDicRef);
	setPanelDictOption("fr-FR-classic-reform", bDicAll);
});

self.port.on("showHelp", function () {
	showHelp();
});

self.port.on("calcDefaultPanelHeight", function () {
	nDefaultPanelHeight = calcPanelHeight();
});

document.getElementById('grammar').addEventListener("click", function(event) {
	if (document.getElementById('grammar_section').style.display === "none" || document.getElementById('grammar_section').style.display === "") {
		self.port.emit("loadGrammarOptions");
		showGrammarOptions();
	} else {
		showHelp();
	}
});

document.getElementById('spelling').addEventListener("click", function(event) {
	if (document.getElementById('spelling_section').style.display === "none" || document.getElementById('spelling_section').style.display === "") {
		self.port.emit("loadSpellingOptions");
		showSpellingOptions();
	} else {
		showHelp();
	}
});

document.getElementById('default_options').addEventListener("click", function (event) {
	self.port.emit('resetOptions');
});

document.getElementById('conjugueur').addEventListener("click", function (event) {
	self.port.emit('openConjugueur');
});

document.getElementById('website').addEventListener("click", function (event) {
	self.port.emit('openURL', "http://www.dicollecte.org/?from=grammalecte-fx");
});

document.getElementById('mainsponsor').addEventListener("click", function (event) {
	self.port.emit('openURL', "http://lamouette.org/?from=grammalecte-fx");
});
document.getElementById('mainsponsor2').addEventListener("click", function (event) {
	self.port.emit('openURL', "https://www.algoo.fr/?from=grammalecte-fx");
});

document.getElementById('othersponsors').addEventListener("click", function (event) {
	self.port.emit('openURL', "http://www.dicollecte.org/#thanks");
});


window.addEventListener(
	"click",
	function (xEvent) {
		let xElem = xEvent.target;
		if (xElem.id) {
			if (xElem.id.startsWith("option_") && xElem.tagName === "INPUT") {
				self.port.emit("setOption", xElem.id.slice(7), xElem.checked);
			}
			if (xElem.id.startsWith("fr-FR-") && xElem.tagName === "INPUT") {
				setPanelDictOption(xElem.id, xElem.checked);
				self.port.emit("changeDictSetting", xElem.id, xElem.checked);
			}
		}
	},
	false
);


/*
	Actions
*/

function calcPanelHeight () {
	return document.getElementById("thanks").offsetTop + document.getElementById("thanks").offsetHeight;
}

function setHeight (n) {
	self.port.emit("setHeight", n);
}

function showHelp () {
	document.getElementById('spelling_section').style.display = "none";
	document.getElementById('grammar_section').style.display = "none";
	document.getElementById('help_section').style.display = "block";
	setHeight(nDefaultPanelHeight);
}

function showGrammarOptions () {
	document.getElementById('grammar_section').style.display = "block";
	document.getElementById('spelling_section').style.display = "none";
	document.getElementById('help_section').style.display = "none";
	setHeight(1000);
}

function showSpellingOptions () {
	document.getElementById('spelling_section').style.display = "block";
	document.getElementById('grammar_section').style.display = "none";
	document.getElementById('help_section').style.display = "none";
	setHeight(1000);
}

function setGrammarOptionsOnPanel (oOptions) {
	for (let sParam in oOptions) {
		//console.log(sParam + ":" + oOptions[sParam]);
		if (document.getElementById("option_"+sParam) !== null) {
			document.getElementById("option_"+sParam).checked = oOptions[sParam];
		}
	}
}

function setPanelDictOption (sNode, bValue) {
	document.getElementById(sNode).checked = bValue;
	document.getElementById(sNode+"_box").style = bValue ? "background-color: hsl(210, 30%, 90%)" : "background-color: hsl(210, 15%, 96%)";
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































Deleted gc_lang/fr/xpi/data/common.css version [51e0dbac23].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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
/*
    common.css
*/

/* reset */

* { margin: 0; padding: 0; }
img { border: none; }


/* Generic classes */

.fleft {
    float: left;
}
.fright {
    float: right;
}
.center {
    text-align: center;
}
.right {
    text-align: right;
}
.left {
    text-align: left;
}
.justify {
    text-align: justify;
}
.hidden {
    display: none;
}

.clearer { 
    clear: both;
    font-size: 0;
    height: 0;
}


/* Common */

#movewindow {
    position: fixed;
    right: 0;
    top: 50;
    width: 16px;
    margin-top: 60px;
    z-index: 100;
}
#movewindow .arrow {
    background-color: hsl(180, 60%, 50%);
    cursor: pointer;
    padding: 1px 3px;
    font-size: 10px;
    font-weight: bold;
    text-align: center;
    color: hsl(180, 50%, 90%);
}
#movewindow .arrow:hover {
    background-color: hsl(180, 70%, 40%);
    cursor: hsl(180, 50%, 96%);
}


#rightcorner {
    position: absolute;
    top: 0;
    right: 0;
}
a.rightcornerbutton1 {
    float: right;
    padding: 2px 10px 5px 10px;
    border-radius: 0 0 0 3px;
    font-size: 18px;
    text-decoration: none;
}
a.rightcornerbutton {
    float: right;
    padding: 2px 10px 5px 10px;
    font-size: 18px;
    text-decoration: none;
}

.red {
    background-color: hsl(0, 50%, 50%);
    color: hsl(0, 0%, 96%);
}
.red:hover {
    background-color: hsl(0, 60%, 40%);
    color: hsl(0, 0%, 100%);
}
.cyan {
    background-color: hsl(180, 50%, 50%);
    color: hsl(0, 0%, 96%);
}
.cyan:hover {
    background-color: hsl(180, 60%, 40%);
    color: hsl(0, 0%, 100%);
}
.green {
    background-color: hsl(120, 50%, 40%);
    color: hsl(120, 10%, 96%);
}
.green:hover {
    background-color: hsl(120, 60%, 30%);
    color: hsl(120, 10%, 96%);
}
.blue {
    background-color: hsl(210, 50%, 50%);
    color: hsl(210, 10%, 96%);
}
.blue:hover {
    background-color: hsl(210, 60%, 40%);
    color: hsl(210, 10%, 96%);
}


/*
    CSS Spinner
    Double bounce
    http://tobiasahlin.com/spinkit/
*/
.spinner {
    width: 40px;
    height: 40px;
    position: absolute;
    top: 2px;
    right: 120px;
}
.double-bounce1, .double-bounce2 {
    width: 100%;
    height: 100%;
    border-radius: 50%;
    background-color: hsl(180, 50%, 75%);
    opacity: 0.6;
    position: absolute;
    top: 0;
    left: 0;
    animation: sk-bounce 2.0s infinite ease-in-out;
}
.double-bounce2 {
    animation-delay: -1.0s;
}

@keyframes sk-bounce {
    0%, 100% { 
        transform: scale(0.0);
    } 50% { 
        transform: scale(1.0);
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































Deleted gc_lang/fr/xpi/data/conj_panel.css version [35f12336a2].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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
/*
   CSS Document
   White
   Design par Olivier R.
*/

@import url("common.css");

body {
	background: #FFFFFF url(img/lines.png);
	font: normal 16px Tahoma, "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", sans-serif;
	color: #505050;
	/*text-rendering: optimizeLegibility;*/
}

.mainflow {
    width: 500px;
    margin: 0 auto 0 auto;
}

.logo {
    position: absolute;
    background-color: #FFFFFF;
    border: 3px solid #F0F0F0;
    border-radius: 50px;
    padding: 4px 4px 0 4px;
}


/* MAIN ====================================================================== */

#main .inbox {
    width: 500px;
    margin: 10px auto 10px auto;
    padding: 0 10px 10px 10px;
    background: #FFFFFF;
    border: 2px solid #F0F0F0;
    border-radius: 20px;
}

#main h1 {
    margin: 5px 0 2px 0;
    color: hsl(210, 50%, 50%);
    font: bold 30px Tahoma, "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", sans-serif;
}
#main h2 {
    margin: 5px 0 2px 0;
    color: hsl(0, 50%, 50%);
    font: bold 16px Tahoma, "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", sans-serif;
}
#main h3 {
    margin: 5px 0 2px 0;
    color: hsl(210, 50%, 50%);
    font: bold 14px Tahoma, "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", sans-serif;
}

#main .colonne {
    float: left;
    width: 240px;
}
#main .colsep {
    float: left;
    width: 20px;
}

.colonne p {
    font-size: 12px;
}

/*.box {
    border-left: 2px solid #8BC5EF;
    border-bottom: 2px solid #8BC5EF;
    border-radius: 5px;
    padding: 0 0 2px 10px;
}*/

input#verb {
    display: inline-block;
    width: 230px;
    margin-left: 5px;
    padding: 5px 10px;
    border: 2px solid hsl(0, 0%, 80%);
    border-radius: 3px;
    height: 24px;
    background: transparent;
    font: normal 20px Tahoma, "Ubuntu Condensed";
    color: hsl(0, 0%, 30%);
}
input[placeholder]#verb {
    color: hsl(0, 0%, 70%);
}

a#conjugate {
    display: inline-block;
    padding: 7px 10px;
    font-size: 20px;
    background-color: hsl(0, 30%, 30%);
    color: hsl(0, 30%, 60%);
    border-radius: 3px;
    text-transform: uppercase;
    text-align: center;
    text-decoration: none;
}
a#conjugate:hover {
    background-color: hsl(0, 60%, 40%);
    color: hsl(0, 60%, 70%);
    box-shadow: 0 0 2px hsl(0, 60%, 50%);
}

#options {
    margin: 10px 5px 0 5px;
    font-size: 16px;
    text-align: center;
}

#smallnote {
    float: right;
    width: 190px;
    margin: 15px 0 0 0;
    padding: 0 5px;
    font-size: 8.5px;
    color: hsl(0, 0%, 60%);
    text-align: center;
}

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































































































































Deleted gc_lang/fr/xpi/data/conj_panel.html version [d63ac8e3c4].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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
167
168
169
170
171
172
173
174
175
176
177
178
179
<!DOCTYPE HTML>
<html>
    <head>
        <link rel="stylesheet" type="text/css" href="conj_panel.css" />
        <title>Grammalecte · Conjugueur</title>
        <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
    </head>
    
    <div id="rightcorner">
        <a class="rightcornerbutton1 red" id="close" href="#"><b>×</b></a>
    </div>
    <body>
        <header>
            <div class="mainflow">
                <div class="logo" style="margin: -5px 0 0 0px;">
                    <img src="img/logo2.png" alt="" />
                </div>
            </div>
        </header>

        <div id="main">
            <div class="inbox">

                <p class="right" style="margin: 10px 30px 0 0">
                    <input type="text" id="verb" name="verb" maxlength="40" value="" placeholder="entrez un verbe" autofocus />
                    <a id="conjugate" href="#" onclick="return false;">Conjuguer</a>
                <p>

                <div class="clearer"></div>

                <p id="smallnote" hidden>Ce verbe n’a pas encore été vérifié. C’est pourquoi les options “pronominal” et “temps composés” sont désactivées.</p>
                <p id="options">
                    <label for="oneg">Négation</label> <input type="checkbox" id="oneg" name="oneg" value="ON"  /> 
                    · <label id="opro_lbl" for="opro">Pronominal</label> <input type="checkbox" id="opro" name="opro" value="ON"  />
                    · <label for="ofem">Féminin</label> <input type="checkbox" id="ofem" name="ofem" value="ON"  />
                    <br/> <label for="oint">Interrogatif</label> <input type="checkbox" id="oint" name="oint" value="ON"  />
                    · <label id="otco_lbl" for="otco">Temps composés</label> <input type="checkbox" id="otco" name="otco" value="ON"  />
                </p>
                    

                <h1 id="verb_title" class="center">&nbsp;</h1>
                <p id="info" class="center">&nbsp;</p>

                <!-- section 1 -->
                <div class="colonne">
                    <div id="infinitif" class="box">
                        <h2 id="infinitif_title">Infinitif</h2>
                        <p id="infi">&nbsp;</p>
                    </div>
                    <div id="imperatif" class="box">
                        <h2 id="imperatif_title">Impératif</h2>
                        <h3 id="impe_temps">Présent</h3>
                        <p id="impe1">&nbsp;</p>
                        <p id="impe2">&nbsp;</p>
                        <p id="impe3">&nbsp;</p>
                    </div>
                </div>
                
                <div class="colsep">&nbsp;</div>
                
                <div class="colonne">
                    <div id="partpre" class="box">
                        <h2 id="partpre_title">Participe présent</h2>
                        <p id="ppre">&nbsp;</p>
                    </div>
                    <div id="partpas" class="box">
                        <h2 id="partpas_title">Participes passés</h2>
                        <p id="ppas1">&nbsp;</p>
                        <p id="ppas2">&nbsp;</p>
                        <p id="ppas3">&nbsp;</p>
                        <p id="ppas4">&nbsp;</p>
                    </div>
                </div>

                <div class="clearer"></div>

                <!-- section 2 -->
                <div class="colonne">
                    <div id="indicatif" class="box">
                        <h2 id="indicatif_title">Indicatif</h2>
                        <div id="ipre">
                            <h3 id="ipre_temps">Présent</h3>
                            <p id="ipre1">&nbsp;</p>
                            <p id="ipre2">&nbsp;</p>
                            <p id="ipre3">&nbsp;</p>
                            <p id="ipre4">&nbsp;</p>
                            <p id="ipre5">&nbsp;</p>
                            <p id="ipre6">&nbsp;</p>
                        </div>
                        <div id="iimp">
                            <h3 id="iimp_temps">Imparfait</h3>
                            <p id="iimp1">&nbsp;</p>
                            <p id="iimp2">&nbsp;</p>
                            <p id="iimp3">&nbsp;</p>
                            <p id="iimp4">&nbsp;</p>
                            <p id="iimp5">&nbsp;</p>
                            <p id="iimp6">&nbsp;</p>
                        </div>
                        <div id="ipsi">
                            <h3 id="ipsi_temps">Passé simple</h3>
                            <p id="ipsi1">&nbsp;</p>
                            <p id="ipsi2">&nbsp;</p>
                            <p id="ipsi3">&nbsp;</p>
                            <p id="ipsi4">&nbsp;</p>
                            <p id="ipsi5">&nbsp;</p>
                            <p id="ipsi6">&nbsp;</p>
                        </div>
                        <div id="ifut">
                            <h3 id="ifut_temps">Futur</h3>
                            <p id="ifut1">&nbsp;</p>
                            <p id="ifut2">&nbsp;</p>
                            <p id="ifut3">&nbsp;</p>
                            <p id="ifut4">&nbsp;</p>
                            <p id="ifut5">&nbsp;</p>
                            <p id="ifut6">&nbsp;</p>
                        </div>
                    </div>
                </div>
                
                <div class="colsep">&nbsp;</div>
                
                <div class="colonne">
                    <div id="subjonctif" class="box">
                        <h2 id="subjontif_title">Subjonctif</h2>
                        <div id="spre">
                            <h3 id="spre_temps">Présent</h3>
                            <p id="spre1">&nbsp;</p>
                            <p id="spre2">&nbsp;</p>
                            <p id="spre3">&nbsp;</p>
                            <p id="spre4">&nbsp;</p>
                            <p id="spre5">&nbsp;</p>
                            <p id="spre6">&nbsp;</p>
                        </div>
                        <div id="simp">
                            <h3 id="simp_temps">Imparfait</h3>
                            <p id="simp1">&nbsp;</p>
                            <p id="simp2">&nbsp;</p>
                            <p id="simp3">&nbsp;</p>
                            <p id="simp4">&nbsp;</p>
                            <p id="simp5">&nbsp;</p>
                            <p id="simp6">&nbsp;</p>
                        </div>
                    </div>
                    <div id="conditionnel" class="box">
                        <h2 id="conditionnel_title">Conditionnel</h2>
                        <div id="conda">
                            <h3 id="conda_temps">Présent</h3>
                            <p id="conda1">&nbsp;</p>
                            <p id="conda2">&nbsp;</p>
                            <p id="conda3">&nbsp;</p>
                            <p id="conda4">&nbsp;</p>
                            <p id="conda5">&nbsp;</p>
                            <p id="conda6">&nbsp;</p>
                        </div>
                        <div id="condb">
                            <h3 id="condb_temps">&nbsp;</h3>
                            <p id="condb1">&nbsp;</p>
                            <p id="condb2">&nbsp;</p>
                            <p id="condb3">&nbsp;</p>
                            <p id="condb4">&nbsp;</p>
                            <p id="condb5">&nbsp;</p>
                            <p id="condb6">&nbsp;</p>
                        </div>
                    </div>
                </div>

                <div class="clearer"></div>

            </div>


        </div>

    </body>
    
</html>



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































Deleted gc_lang/fr/xpi/data/conj_panel.js version [eb75f474de].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
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
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
// JavaScript

let oVerb = null;

self.port.on("conjugate", function (sVerb) {
    createVerbAndConjugate(sVerb);
});

self.port.on("start", function () {
    self.port.emit("setHeight", document.getElementById("main").offsetTop + document.getElementById("main").offsetHeight + 20);
    document.getElementById("verb").focus();
});

// close
document.getElementById('close').addEventListener("click", function (event) {
    self.port.emit('closePanel');
});

// button
document.getElementById('conjugate').addEventListener("click", function (event) {
    createVerbAndConjugate(document.getElementById('verb').value);
});

// text field
document.getElementById('verb').addEventListener("change", function (event) {
    createVerbAndConjugate(document.getElementById('verb').value);
});

// options
document.getElementById('oneg').addEventListener("click", function (event) {
    _displayResults();
});
document.getElementById('opro').addEventListener("click", function (event) {
    _displayResults();
});
document.getElementById('oint').addEventListener("click", function (event) {
    _displayResults();
});
document.getElementById('ofem').addEventListener("click", function (event) {
    _displayResults();
});
document.getElementById('otco').addEventListener("click", function (event) {
    _displayResults();
});

function createVerbAndConjugate (sVerb) {
    try {
        document.getElementById('oneg').checked = false;
        document.getElementById('opro').checked = false;
        document.getElementById('oint').checked = false;
        document.getElementById('otco').checked = false;
        document.getElementById('ofem').checked = false;
        document.getElementById('smallnote').hidden = true;

        // request analyzing
        sVerb = sVerb.trim().toLowerCase().replace(/’/g, "'").replace(/  +/g, " ");
        if (sVerb) {
            if (sVerb.startsWith("ne pas ")) {
                document.getElementById('oneg').checked = true;
                sVerb = sVerb.slice(7);
            }
            if (sVerb.startsWith("se ")) {
                document.getElementById('opro').checked = true;
                sVerb = sVerb.slice(3);
            } else if (sVerb.startsWith("s'")) {
                document.getElementById('opro').checked = true;
                sVerb = sVerb.slice(2);
            }
            if (sVerb.endsWith("?")) {
                document.getElementById('oint').checked = true;
                sVerb = sVerb.slice(0,-1).trim();
            }

            if (!conj.isVerb(sVerb)) {
                document.getElementById('verb').style = "color: #BB4411;";
            } else {
                self.port.emit("show");
                document.getElementById('verb_title').textContent = sVerb;
                document.getElementById('verb').style = "color: #999999;";
                document.getElementById('verb').value = "";
                oVerb = new Verb(sVerb);
                let sRawInfo = oVerb._sRawInfo;
                document.getElementById('info').textContent = oVerb.sInfo;
                document.getElementById('opro').textContent = "pronominal";
                if (sRawInfo.endsWith("zz")) {
                    document.getElementById('opro').checked = false;
                    document.getElementById('opro').disabled = true;
                    document.getElementById('opro_lbl').style = "color: #CCC;";
                    document.getElementById('otco').checked = false;
                    document.getElementById('otco').disabled = true;
                    document.getElementById('otco_lbl').style = "color: #CCC;";
                    document.getElementById('smallnote').hidden = false;
                } else {
                    if (sRawInfo[5] == "_") {
                        document.getElementById('opro').checked = false;
                        document.getElementById('opro').disabled = true;
                        document.getElementById('opro_lbl').style = "color: #CCC;";
                    } else if (["q", "u", "v", "e"].includes(sRawInfo[5])) {
                        document.getElementById('opro').checked = false;
                        document.getElementById('opro').disabled = false;
                        document.getElementById('opro_lbl').style = "color: #000;";
                    } else if (sRawInfo[5] == "p" || sRawInfo[5] == "r") {
                        document.getElementById('opro').checked = true;
                        document.getElementById('opro').disabled = true;
                        document.getElementById('opro_lbl').style = "color: #CCC;";
                    } else if (sRawInfo[5] == "x") {
                        document.getElementById('opro').textContent = "cas particuliers";
                        document.getElementById('opro').checked = false;
                        document.getElementById('opro').disabled = true;
                        document.getElementById('opro_lbl').style = "color: #CCC;";
                    } else {
                        document.getElementById('opro').textContent = "# erreur #";
                        document.getElementById('opro').checked = false;
                        document.getElementById('opro').disabled = true;
                        document.getElementById('opro_lbl').style = "color: #CCC;";
                    }
                    document.getElementById('otco').disabled = false;
                    document.getElementById('otco_lbl').style = "color: #000;";
                }
                _displayResults();
            }
        }
    }
    catch (e) {
        console.error("\n" + e.fileName + "\n" + e.name + "\nline: " + e.lineNumber + "\n" + e.message);
    }
}

function _displayResults () {
    if (oVerb === null) {
        return;
    }
    try {
    	let opro = document.getElementById('opro').checked;
    	let oneg = document.getElementById('oneg').checked;
    	let otco = document.getElementById('otco').checked;
    	let oint = document.getElementById('oint').checked;
    	let ofem = document.getElementById('ofem').checked;
        // titles
        _setTitles()
        // participes passés
        document.getElementById('ppas1').textContent = oVerb.participePasse(":Q1") || " "; // something or nbsp
        document.getElementById('ppas2').textContent = oVerb.participePasse(":Q2") || " ";
        document.getElementById('ppas3').textContent = oVerb.participePasse(":Q3") || " ";
        document.getElementById('ppas4').textContent = oVerb.participePasse(":Q4") || " ";
        // infinitif
        document.getElementById('infi').textContent = oVerb.infinitif(opro, oneg, otco, oint, ofem);
        // participe présent
        document.getElementById('ppre').textContent = oVerb.participePresent(opro, oneg, otco, oint, ofem) || " ";
        // conjugaisons
        document.getElementById('ipre1').textContent = oVerb.conjugue(":Ip", ":1s", opro, oneg, otco, oint, ofem) || " ";
        document.getElementById('ipre2').textContent = oVerb.conjugue(":Ip", ":2s", opro, oneg, otco, oint, ofem) || " ";
        document.getElementById('ipre3').textContent = oVerb.conjugue(":Ip", ":3s", opro, oneg, otco, oint, ofem) || " ";
        document.getElementById('ipre4').textContent = oVerb.conjugue(":Ip", ":1p", opro, oneg, otco, oint, ofem) || " ";
        document.getElementById('ipre5').textContent = oVerb.conjugue(":Ip", ":2p", opro, oneg, otco, oint, ofem) || " ";
        document.getElementById('ipre6').textContent = oVerb.conjugue(":Ip", ":3p", opro, oneg, otco, oint, ofem) || " ";
        document.getElementById('iimp1').textContent = oVerb.conjugue(":Iq", ":1s", opro, oneg, otco, oint, ofem) || " ";
        document.getElementById('iimp2').textContent = oVerb.conjugue(":Iq", ":2s", opro, oneg, otco, oint, ofem) || " ";
        document.getElementById('iimp3').textContent = oVerb.conjugue(":Iq", ":3s", opro, oneg, otco, oint, ofem) || " ";
        document.getElementById('iimp4').textContent = oVerb.conjugue(":Iq", ":1p", opro, oneg, otco, oint, ofem) || " ";
        document.getElementById('iimp5').textContent = oVerb.conjugue(":Iq", ":2p", opro, oneg, otco, oint, ofem) || " ";
        document.getElementById('iimp6').textContent = oVerb.conjugue(":Iq", ":3p", opro, oneg, otco, oint, ofem) || " ";
        document.getElementById('ipsi1').textContent = oVerb.conjugue(":Is", ":1s", opro, oneg, otco, oint, ofem) || " ";
        document.getElementById('ipsi2').textContent = oVerb.conjugue(":Is", ":2s", opro, oneg, otco, oint, ofem) || " ";
        document.getElementById('ipsi3').textContent = oVerb.conjugue(":Is", ":3s", opro, oneg, otco, oint, ofem) || " ";
        document.getElementById('ipsi4').textContent = oVerb.conjugue(":Is", ":1p", opro, oneg, otco, oint, ofem) || " ";
        document.getElementById('ipsi5').textContent = oVerb.conjugue(":Is", ":2p", opro, oneg, otco, oint, ofem) || " ";
        document.getElementById('ipsi6').textContent = oVerb.conjugue(":Is", ":3p", opro, oneg, otco, oint, ofem) || " ";
        document.getElementById('ifut1').textContent = oVerb.conjugue(":If", ":1s", opro, oneg, otco, oint, ofem) || " ";
        document.getElementById('ifut2').textContent = oVerb.conjugue(":If", ":2s", opro, oneg, otco, oint, ofem) || " ";
        document.getElementById('ifut3').textContent = oVerb.conjugue(":If", ":3s", opro, oneg, otco, oint, ofem) || " ";
        document.getElementById('ifut4').textContent = oVerb.conjugue(":If", ":1p", opro, oneg, otco, oint, ofem) || " ";
        document.getElementById('ifut5').textContent = oVerb.conjugue(":If", ":2p", opro, oneg, otco, oint, ofem) || " ";
        document.getElementById('ifut6').textContent = oVerb.conjugue(":If", ":3p", opro, oneg, otco, oint, ofem) || " ";
        document.getElementById('conda1').textContent = oVerb.conjugue(":K", ":1s", opro, oneg, otco, oint, ofem) || " ";
        document.getElementById('conda2').textContent = oVerb.conjugue(":K", ":2s", opro, oneg, otco, oint, ofem) || " ";
        document.getElementById('conda3').textContent = oVerb.conjugue(":K", ":3s", opro, oneg, otco, oint, ofem) || " ";
        document.getElementById('conda4').textContent = oVerb.conjugue(":K", ":1p", opro, oneg, otco, oint, ofem) || " ";
        document.getElementById('conda5').textContent = oVerb.conjugue(":K", ":2p", opro, oneg, otco, oint, ofem) || " ";
        document.getElementById('conda6').textContent = oVerb.conjugue(":K", ":3p", opro, oneg, otco, oint, ofem) || " ";
        if (!oint) {
            document.getElementById('spre1').textContent = oVerb.conjugue(":Sp", ":1s", opro, oneg, otco, oint, ofem) || " ";
            document.getElementById('spre2').textContent = oVerb.conjugue(":Sp", ":2s", opro, oneg, otco, oint, ofem) || " ";
            document.getElementById('spre3').textContent = oVerb.conjugue(":Sp", ":3s", opro, oneg, otco, oint, ofem) || " ";
            document.getElementById('spre4').textContent = oVerb.conjugue(":Sp", ":1p", opro, oneg, otco, oint, ofem) || " ";
            document.getElementById('spre5').textContent = oVerb.conjugue(":Sp", ":2p", opro, oneg, otco, oint, ofem) || " ";
            document.getElementById('spre6').textContent = oVerb.conjugue(":Sp", ":3p", opro, oneg, otco, oint, ofem) || " ";
            document.getElementById('simp1').textContent = oVerb.conjugue(":Sq", ":1s", opro, oneg, otco, oint, ofem) || " ";
            document.getElementById('simp2').textContent = oVerb.conjugue(":Sq", ":2s", opro, oneg, otco, oint, ofem) || " ";
            document.getElementById('simp3').textContent = oVerb.conjugue(":Sq", ":3s", opro, oneg, otco, oint, ofem) || " ";
            document.getElementById('simp4').textContent = oVerb.conjugue(":Sq", ":1p", opro, oneg, otco, oint, ofem) || " ";
            document.getElementById('simp5').textContent = oVerb.conjugue(":Sq", ":2p", opro, oneg, otco, oint, ofem) || " ";
            document.getElementById('simp6').textContent = oVerb.conjugue(":Sq", ":3p", opro, oneg, otco, oint, ofem) || " ";
            document.getElementById('impe1').textContent = oVerb.imperatif(":2s", opro, oneg, otco, ofem) || " ";
            document.getElementById('impe2').textContent = oVerb.imperatif(":1p", opro, oneg, otco, ofem) || " ";
            document.getElementById('impe3').textContent = oVerb.imperatif(":2p", opro, oneg, otco, ofem) || " ";
        } else {
            document.getElementById('spre_temps').textContent = " ";
            document.getElementById('spre1').textContent = " ";
            document.getElementById('spre2').textContent = " ";
            document.getElementById('spre3').textContent = " ";
            document.getElementById('spre4').textContent = " ";
            document.getElementById('spre5').textContent = " ";
            document.getElementById('spre6').textContent = " ";
            document.getElementById('simp_temps').textContent = " ";
            document.getElementById('simp1').textContent = " ";
            document.getElementById('simp2').textContent = " ";
            document.getElementById('simp3').textContent = " ";
            document.getElementById('simp4').textContent = " ";
            document.getElementById('simp5').textContent = " ";
            document.getElementById('simp6').textContent = " ";
            document.getElementById('impe_temps').textContent = " ";
            document.getElementById('impe1').textContent = " ";
            document.getElementById('impe2').textContent = " ";
            document.getElementById('impe3').textContent = " ";
        }
        if (otco) {
            document.getElementById('condb1').textContent = oVerb.conjugue(":Sq", ":1s", opro, oneg, otco, oint, ofem) || " ";
            document.getElementById('condb2').textContent = oVerb.conjugue(":Sq", ":2s", opro, oneg, otco, oint, ofem) || " ";
            document.getElementById('condb3').textContent = oVerb.conjugue(":Sq", ":3s", opro, oneg, otco, oint, ofem) || " ";
            document.getElementById('condb4').textContent = oVerb.conjugue(":Sq", ":1p", opro, oneg, otco, oint, ofem) || " ";
            document.getElementById('condb5').textContent = oVerb.conjugue(":Sq", ":2p", opro, oneg, otco, oint, ofem) || " ";
            document.getElementById('condb6').textContent = oVerb.conjugue(":Sq", ":3p", opro, oneg, otco, oint, ofem) || " ";
        } else {
            document.getElementById('condb1').textContent = " ";
            document.getElementById('condb2').textContent = " ";
            document.getElementById('condb3').textContent = " ";
            document.getElementById('condb4').textContent = " ";
            document.getElementById('condb5').textContent = " ";
            document.getElementById('condb6').textContent = " ";
        }
        document.getElementById('verb').Text = "";
    }
    catch (e) {
        console.error("\n" + e.fileName + "\n" + e.name + "\nline: " + e.lineNumber + "\n" + e.message);
    }
}

function _setTitles () {
    try {
        if (!document.getElementById('otco').checked) {
            document.getElementById('ipre_temps').textContent = "Présent";
            document.getElementById('ifut_temps').textContent = "Futur";
            document.getElementById('iimp_temps').textContent = "Imparfait";
            document.getElementById('ipsi_temps').textContent = "Passé simple";
            document.getElementById('spre_temps').textContent = "Présent";
            document.getElementById('simp_temps').textContent = "Imparfait";
            document.getElementById('conda_temps').textContent = "Présent";
            document.getElementById('condb_temps').textContent = " ";
            document.getElementById('impe_temps').textContent = "Présent";
        } else {
            document.getElementById('ipre_temps').textContent = "Passé composé";
            document.getElementById('ifut_temps').textContent = "Futur antérieur";
            document.getElementById('iimp_temps').textContent = "Plus-que-parfait";
            document.getElementById('ipsi_temps').textContent = "Passé antérieur";
            document.getElementById('spre_temps').textContent = "Passé";
            document.getElementById('simp_temps').textContent = "Plus-que-parfait";
            document.getElementById('conda_temps').textContent = "Passé (1ʳᵉ forme)";
            document.getElementById('condb_temps').textContent = "Passé (2ᵉ forme)";
            document.getElementById('impe_temps').textContent = "Passé";
        }
    }
    catch (e) {
        console.error("\n" + e.fileName + "\n" + e.name + "\nline: " + e.lineNumber + "\n" + e.message);
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































































































































































































































































































Deleted gc_lang/fr/xpi/data/gc_panel.css version [75ceec5406].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
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
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
/* panel.css */

@import url("common.css");

header {
    background-color: hsl(0, 0%, 96%);
    padding: 10px 20px;
    border-bottom: 1px solid hsl(0, 0%, 90%);
    color: hsl(0, 0%, 0%);
}

body {
    background-color: hsl(0, 0%, 98%);
    font-family: Tahoma, "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", sans-serif;
    overflow-x: hidden;
    color: hsl(0, 0%, 0%);
}

#special_message {
    display: none;
    margin: 0 20px 0 20px;
    padding: 60px 20px 10px 20px;
    border-radius: 3px;
    background-color: hsl(0, 50%, 50%);
    font: bold 18px "Trebuchet MS", sans-serif;
    color: hsl(0, 10%, 190%);
}
#special_message a {
    color: hsl(0, 50%, 80%);
    text-shadow: 0 0 3px hsl(0, 50%, 20%);
    text-decoration: none;
}
#special_message a:hover {
    color: hsl(0, 70%, 90%);
    text-shadow: 0 0 3px hsl(0, 80%, 10%);
}

#messagebox {
    position: absolute;
    display: none;
    left: 50%;
    width: 250px;
    margin-left: -125px;
    top: 50px;
    background-color: hsla(0, 50%, 20%, .8);
    border: 2px solid hsla(0, 50%, 10%, .8);
    border-radius: 5px;
    text-align: center;
    color: hsla(0, 0%, 100%, .9);
    font-size: 16px;
    font-weight: bold;
}
#message {
    padding: 10px 20px;
}


/*
    Error list
*/

#errorlist {
    padding: 60px 20px 30px 20px;
}

#errorlist p.message {
    margin-top: 20px;
    padding: 10px 10px;
    background-color: hsla(240, 10%, 50%, 1);
    font-size: 18px;
    color: hsla(240, 0%, 96%, 1);
    border-radius: 3px;
    text-align: center;
}

#errorlist p.green {
    background-color: hsla(120, 10%, 50%, 1);
    color: hsla(120, 0%, 96%, 1);
}

.paragraph_block {
    margin: 0 0 10px 0;
}

.paragraph {
    background-color: hsla(0, 0%, 90%, 1);
    padding: 10px;
    border-radius: 2px;
    font-size: 14px;
    font-family : "Courier New", Courier, "Lucida Sans Typewriter", "Lucida Typewriter", monospace;
    color: hsl(0, 0%, 0%);
}
.softred {
    background-color: hsla(0, 20%, 90%, 1);
}
.softgreen {
    background-color: hsla(120, 15%, 90%, 1);
}

.paragraph a {
    background-color: hsla(210, 50%, 50%, 1);
    padding: 1px 5px;
    border-radius: 2px;
    color: hsla(210, 0%, 96%, 1);
    cursor: pointer;
    text-decoration: none;
}
.paragraph a:hover {
    background-color: hsla(210, 60%, 40%, 1);
    color: hsla(0, 0%, 100%, 1);
    text-shadow: 0 0 3px hsl(210, 30%, 60%);
}

.paragraph u {
    text-decoration: none;
}

.paragraph u.corrected,
.paragraph u.ignored {
    background-color: hsla(120, 50%, 70%, 1);
    color: hsla(0, 0%, 4%, 1);
    border-radius: 2px;
    text-decoration: none;
}
.paragraph u.ignored {
    background-color: hsla(30, 20%, 80%, 1);
}

.paragraph u.error {
    position: relative;
    cursor: pointer;
    border-radius: 2px;
    text-decoration: none; /* to remove for wavy underlines */
}
.paragraph u.error:hover {
    cursor: pointer;
}


/* 
    TOOLTIPS
*/
.tooltip {
    position: absolute;
    display: none;
    width: 300px;
    border-radius: 5px;
    box-shadow: 0 0 6px hsla(0, 0%, 0%, 0.3);
    font-family: Tahoma, "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", sans-serif;
    font-size: 12px;
    line-height: 18px;
    cursor: default;
    text-decoration: none;
}
#gc_tooltip {
    border: 3px solid hsl(210, 50%, 30%);
    color: hsla(210, 10%, 20%, 1);
}
#sc_tooltip {
    border: 3px solid hsl(0, 50%, 30%);
    color: hsla(0, 10%, 20%, 1);
}
#gc_tooltip_arrow, #sc_tooltip_arrow {
    position: absolute;
    display: none;
}
#gc_tooltip #gc_rule_id {
    display: none;
    margin: 0 0 5px 0;
    border: 1px solid hsl(210, 50%, 60%);
    background-color: hsl(210, 50%, 40%);
    padding: 2px 5px;
    border-radius: 2px;
    color: hsla(210, 0%, 96%, 1);
    font-size: 11px;
    font-style: normal;
    text-align: center;
}
#gc_message_block {
    padding: 5px 10px 10px 10px;
    background-color: hsl(210, 50%, 30%);
    color: hsl(210, 50%, 96%);
}
#sc_message_block {
    padding: 5px 10px 10px 10px;
    background-color: hsl(0, 50%, 30%);
    color: hsl(0, 50%, 96%);
}
#gc_message, #sc_message {
    font-size: 15px;
    margin-bottom: 5px;
}
a#gc_ignore, a#sc_ignore {
    padding: 0 2px;
    background-color: hsla(30, 30%, 40%, 1);
    color: hsla(30, 0%, 96%, 1);
    border-radius: 2px;
    cursor: pointer;
    text-decoration: none;
}
a#gc_ignore:hover, a#sc_ignore:hover {
    background-color: hsla(30, 30%, 50%, 1);
    color: hsla(0, 0%, 100%, 1);
    text-shadow: 0 0 3px hsl(30, 30%, 60%);
}
a#gc_url {
    padding: 0 2px;
    background-color: hsla(210, 50%, 50%, 1);
    color: hsla(210, 0%, 96%, 1);
    border-radius: 2px;
    cursor: pointer;
    text-decoration: none;
}
a#gc_url:hover {
    background-color: hsla(210, 50%, 60%, 1);
    color: hsla(0, 0%, 100%, 1);
    text-shadow: 0 0 3px hsl(210, 30%, 60%);
}
#gc_sugg_title {
    padding: 0 10px;
    background-color: hsl(210, 10%, 90%);
    color: hsl(210, 50%, 30%);
    font-size: 10px;
    font-weight: bold;
}
#sc_sugg_title {
    padding: 0 10px;
    background-color: hsl(0, 10%, 90%);
    color: hsl(0, 50%, 30%);
    font-size: 9px;
    font-weight: bold;
}
#gc_sugg_block {
    padding: 10px;
    background-color: hsl(210, 10%, 96%);
    border-radius: 0 0 2px 2px;
    line-height: 20px;
}
#sc_sugg_block {
    padding: 10px;
    background-color: hsl(0, 10%, 96%);
    border-radius: 0 0 2px 2px;
    line-height: 20px;
}
#gc_sugg_block a.sugg {
    padding: 1px 6px;
    background-color: hsla(180, 60%, 40%, 1);
    color: hsla(180, 0%, 96%, 1);
    border-radius: 2px;
    cursor: pointer;
    text-decoration: none;
}
#gc_sugg_block a.sugg:hover {
    background-color: hsla(180, 70%, 45%, 1);
    color: hsla(0, 0%, 100%, 1);
}
#sc_sugg_block a.sugg {
    padding: 1px 6px;
    background-color: hsla(30, 90%, 45%, 1);
    color: hsla(30, 0%, 96%, 1);
    border-radius: 2px;
    cursor: pointer;
    text-decoration: none;
}
#sc_sugg_block a.sugg:hover {
    background-color: hsla(30, 100%, 50%, 1);
    color: hsla(0, 0%, 100%, 1);
}

/*
    Action buttons
*/

.actions {
    margin: 0 0 5px 10px;
}

.actions .button {
    background-color: hsl(0, 0%, 50%);
    text-align: center;
    float: right;
    margin-left: 2px;
    padding: 1px 4px 3px 4px;
    /*width: 18px;
    height: 18px;*/
    cursor: pointer;
    font-size: 14px;
    color: hsl(0, 0%, 96%);
    border-radius: 2px;
}
.actions .button:hover {
    background-color: hsl(0, 0%, 40%);
    color: hsl(0, 0%, 100%);
}

.actions .green {
    background-color: hsl(120, 30%, 50%);
    color: hsl(0, 0%, 96%);
}
.actions .green:hover {
    background-color: hsl(120, 50%, 40%);
    color: hsl(0, 0%, 100%);
}
.actions .red {
    background-color: hsl(0, 30%, 50%);
    color: hsl(0, 0%, 96%);
}
.actions .red:hover {
    background-color: hsl(0, 50%, 40%);
    color: hsl(0, 0%, 100%);
}
.actions .orange {
    background-color: hsl(30, 50%, 50%);
    color: hsl(30, 0%, 96%);
}
.actions .orange:hover {
    background-color: hsl(30, 70%, 40%);
    color: hsl(30, 0%, 100%);
}
.actions .bold {
    font-weight: bold;
}


/*
    ERRORS
*/

.error {
    /* default color */
    background-color: hsl(240, 10%, 50%);
    color: hsl(240, 0%, 96%);
}
.error:hover {
    background-color: hsl(240, 10%, 40%);
    color: hsl(240, 0%, 100%);
}

/* elems */
.WORD {
    background-color: hsl(0, 50%, 50%);
    color: hsl(0, 0%, 96%);
    /*text-decoration: underline wavy hsl(0, 50%, 50%);*/
}
.WORD:hover {
    background-color: hsl(0, 60%, 40%);
    color: hsl(0, 0%, 100%);
}

/* elems */
.typo, .esp, .nbsp, .eif, .maj, .virg, .tu, .num, .unit, .nf, .liga, .mapos, .chim {
    background-color: hsl(30, 70%, 50%);
    color: hsl(30, 10%, 96%);
    /*text-decoration: underline wavy hsl(30, 70%, 50%);*/
}
.typo:hover, .esp:hover, .nbsp:hover, .eif:hover, .maj:hover, .virg:hover, .tu:hover, .num:hover, .unit:hover, .nf:hover, .liga:hover, .mapos:hover, .chim:hover {
    background-color: hsl(30, 80%, 45%);
    color: hsl(30, 10%, 96%);
}

/* elems */
.apos {
    background-color: hsl(40, 90%, 50%);
    color: hsl(40, 10%, 96%);
    /*text-decoration: underline wavy hsl(40, 70%, 45%);*/
}
.apos:hover {
    background-color: hsl(40, 100%, 45%);
    color: hsl(40, 10%, 96%);
}

/* elems */
.gn, .sgpl {
    background-color: hsl(210, 50%, 50%);
    color: hsl(210, 10%, 96%);
    /*text-decoration: underline wavy hsl(210, 50%, 50%);*/
}
.gn:hover, .sgpl:hover {
    background-color: hsl(210, 60%, 40%);
    color: hsl(210, 10%, 96%);
}

/* elems */
.conj, .infi, .imp, .inte, .ppas, .vmode  {
    background-color: hsl(300, 30%, 40%);
    color: hsl(300, 10%, 96%);
    /*text-decoration: underline wavy hsl(300, 40%, 40%);*/
}
.conj:hover, .infi:hover, .imp:hover, .inte:hover, .ppas:hover, .vmode:hover {
    background-color: hsl(300, 40%, 30%);
    color: hsl(300, 10%, 96%);
}

/* elems */
.conf, .ocr {
    background-color: hsl(270, 40%, 30%);
    color: hsl(270, 10%, 96%);
    /*text-decoration: underline wavy hsl(270, 40%, 30%);*/
}
.conf:hover, .ocr:hover {
    background-color: hsl(270, 50%, 20%);
    color: hsl(270, 10%, 96%);
}

/* elems */
.bs, .pleo, .neg, .redon1, .redon2, .mc, .date, .notype {
    background-color: hsl(180, 50%, 40%);
    color: hsl(180, 10%, 96%);
    /*text-decoration: underline wavy hsl(180, 50%, 40%);*/
}
.bs:hover, .pleo:hover, .neg:hover, .redon1:hover, .redon2:hover, .mc:hover, .date:hover, .notype:hover {
    background-color: hsl(180, 60%, 30%);
    color: hsl(180, 10%, 96%);
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































































































































































































































































































































































































































































































































































































Deleted gc_lang/fr/xpi/data/gc_panel.html version [3af19d97ff].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<!DOCTYPE HTML>
<html>
    <head>
        <link rel="stylesheet" type="text/css" href="gc_panel.css" />
        <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
    </head>
    <body class="panel">
        <div style="position: fixed; width: 100%">
            <div id="rightcorner">
                <a class="rightcornerbutton red" id="close" href="#" title="Fermer"><b>×</b></a>
                <a class="rightcornerbutton cyan" id="expand_reduce" href="#" title="Réduire/Agrandir"><b>−</b></a>
                <a class="rightcornerbutton1 green" id="copy_to_clipboard" href="#" style="display: none;" onclick="return false;" title="Copier dans le presse-papiers">
                    <b id="clipboard_msg">∑</b>
                </a>
            </div>
            <header>
                <div id="waiticon" class="spinner">
                    <div class="double-bounce1"></div>
                    <div class="double-bounce2"></div>
                </div>
                <!--<div id="waiticon" class="fright" style="margin-right: 50px">
                    <img src="./img/spinner32.png" />
                </div>-->

                <h2>Grammalecte</h2>
                
            </header>
            <div id="messagebox"><a id="closemsg" class="rightcornerbutton1 red" href="#" onclick="return false;"><b>×</b></a><p id="message"></p></div>
        </div>

        <div id="movewindow">
            <div id="resize_h_bigger" class="arrow" style="border-radius: 2px 0 0 0">↓</div>
            <div id="resize_h_smaller" class="arrow">↑</div>
            <div id="resize_w_bigger" class="arrow">←</div>
            <div id="resize_w_smaller" class="arrow" style="border-radius: 0 0 0 2px">→</div>
        </div>
        
        <div id="special_message">
            <p class="center">Grammalecte a besoin de vous<br>pour poursuivre sa route.</p>
            <p class="center" style="margin: 10px 0"><a href="https://fr.ulule.com/grammalecte-2/" onclick="return false;">Campagne de financement participatif…</a></p>
        </div>

        <div id="errorlist">
            <!-- result comes here -->
        </div>

        <img id="gc_tooltip_arrow" src="img/gc_tooltip_arrow.png" alt="^">
        <img id="sc_tooltip_arrow" src="img/sc_tooltip_arrow.png" alt="^">

        <div id="gc_tooltip" class="tooltip">
            <!-- grammar error -->
            <div id="gc_message_block">
                <p id="gc_rule_id"></p>
                <p id="gc_message">Erreur grammaticale.</p>
                <a id="gc_ignore" href="#">Ignorer</a> &nbsp; 
                <a id="gc_url" href="" onclick="return false;">Voulez-vous en savoir plus ?…</a>
            </div>
            <div id="gc_sugg_title">SUGGESTIONS :</div>
            <div id="gc_sugg_block"></div>
        </div>

        <div id="sc_tooltip" class="tooltip">
            <!-- spelling error -->
            <div id="sc_message_block">
                <p id="sc_message">Mot inconnu du dictionnaire.</p>
                <a id="sc_ignore" href="#">Ignorer</a>
            </div>
            <div id="sc_sugg_title">SUGGESTIONS :</div>
            <div id="sc_sugg_block"></div>
        </div>
    </body>
</html>


        
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































Deleted gc_lang/fr/xpi/data/gc_panel.js version [01fa41331e].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
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
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
// JavaScript

let nPanelWidth = 0;  // must be set at launch
let bExpanded = true;

/*
    Ignored errors
    idendified by <sIgnoredKey>
    sIgnoredKey: <iParagraph:nStart:nEnd:sUnderlined> 
*/
let aIgnoredErrors = new Set();


/*
    Events
*/

showSpecialMessage();


document.getElementById('close').addEventListener("click", function (event) {
    bExpanded = true; // size is reset in ui.js
    self.port.emit('closePanel');
});

document.getElementById('expand_reduce').addEventListener("click", function (event) {
    if (bExpanded) {
        self.port.emit("resize", "reduce", 10); // the number has no meaning here
        bExpanded = false;
    } else {
        self.port.emit("resize", "expand", 10); // the number has no meaning here
        bExpanded = true;
    }
});

document.getElementById('copy_to_clipboard').addEventListener("click", function (event) {
    copyToClipboard();
});

document.getElementById('closemsg').addEventListener("click", function (event) {
    closeMessageBox();
});

self.port.on("setPanelWidth", function (n) {
    nPanelWidth = n;
});

self.port.on("addMessage", function (sClass, sText) {
    addMessage(sClass, sText);
});

self.port.on("addParagraph", function (sText, iParagraph, sJSON) {
    addParagraph(sText, iParagraph, sJSON);
});

self.port.on("refreshParagraph", function (sText, sIdParagr, sJSON) {
    refreshParagraph(sText, sIdParagr, sJSON);
});

self.port.on("showMessage", function (sText) {
    document.getElementById("message").textContent = sText;
    document.getElementById("messagebox").style.display = "block";
    window.setTimeout(closeMessageBox, 20000);
});

self.port.on("clearErrors", function (sHtml) {
    document.getElementById("errorlist").textContent = "";
    aIgnoredErrors.clear();
    hideAllTooltips();
});

self.port.on("start", function() {
    startWaitIcon();
});

self.port.on("end", function() {
    stopWaitIcon();
    document.getElementById("copy_to_clipboard").style.display = "block";
});

self.port.on("suggestionsFor", function (sWord, sSuggestions, sErrId) {
    setSpellSuggestionsFor(sWord, sSuggestions, sErrId);
});


window.addEventListener(
    "click",
    function (xEvent) {
        try {
            let xElem = xEvent.target;
            if (xElem.id) {
                if (xElem.id.startsWith("sugg")) {
                    applySuggestion(xElem.id);
                } else if (xElem.id.endsWith("_ignore")) {
                    ignoreError(xElem.id);
                } else if (xElem.id.startsWith("check")) {
                    sendBackAndCheck(xElem.id);
                /*} else if (xElem.id.startsWith("edit")) {
                    switchEdition(xElem.id);*/
                } else if (xElem.id.startsWith("end")) {
                    document.getElementById(xElem.id).parentNode.parentNode.style.display = "none";
                } else if (xElem.tagName === "U" && xElem.id.startsWith("err")
                           && xElem.className !== "corrected" && xElem.className !== "ignored") {
                    showTooltip(xElem.id);
                } else if (xElem.id.startsWith("resize")) {
                    self.port.emit("resize", xElem.id, 10);
                } else if (xElem.id === "gc_url") {
                    self.port.emit("openURL", xElem.getAttribute("href"));
                } else {
                    hideAllTooltips();
                }
            } else if (xElem.tagName === "A") {
                self.port.emit("openURL", xElem.getAttribute("href"));
            } else {
                hideAllTooltips();
            }
        }
        catch (e) {
            showError(e);
        }
    },
    false
);


/*
    Actions
*/

function showError (e) {
    console.error("\n" + e.fileName + "\n" + e.name + "\nline: " + e.lineNumber + "\n" + e.message);
}

function closeMessageBox () {
    document.getElementById("messagebox").style.display = "none";
    document.getElementById("message").textContent = "";
}

function addMessage (sClass, sText) {
    let xNode = document.createElement("p");
    xNode.className = sClass;
    xNode.textContent = sText;
    document.getElementById("errorlist").appendChild(xNode);
}

function addParagraph (sText, iParagraph, sJSON) {
    try {
        let xNodeDiv = document.createElement("div");
        xNodeDiv.className = "paragraph_block";
        // actions
        let xDivActions = document.createElement("div");
        xDivActions.className = "actions";
        let xDivClose = document.createElement("div");
        xDivClose.id = "end" + iParagraph.toString();
        xDivClose.className = "button red bold";
        xDivClose.textContent = "×";
        xDivActions.appendChild(xDivClose);
        /*let xDivEdit = document.createElement("div");
        xDivEdit.id = "edit" + iParagraph.toString();
        xDivEdit.className = "button";
        xDivEdit.textContent = "Éditer";
        xDivActions.appendChild(xDivEdit);*/
        let xDivCheck = document.createElement("div");
        xDivCheck.id = "check" + iParagraph.toString();
        xDivCheck.className = "button green";
        xDivCheck.textContent = "Réanalyser";
        xDivCheck.setAttribute("title", "Réanalyser le texte");
        xDivActions.appendChild(xDivCheck);
        xNodeDiv.appendChild(xDivActions);
        // paragraph
        let xParagraph = document.createElement("p");
        xParagraph.id = "paragr" + iParagraph.toString();
        xParagraph.lang = "fr";
        xParagraph.setAttribute("spellcheck", false);
        xParagraph.setAttribute("contenteditable", true);
        let oErrors = JSON.parse(sJSON);
        xParagraph.className = (oErrors.aGrammErr.length || oErrors.aSpellErr.length) ? "paragraph softred" : "paragraph";
        _tagParagraph(sText, xParagraph, iParagraph, oErrors.aGrammErr, oErrors.aSpellErr);
        xNodeDiv.appendChild(xParagraph);
        document.getElementById("errorlist").appendChild(xNodeDiv);
    }
    catch (e) {
        showError(e);
    }
}

function refreshParagraph (sText, sIdParagr, sJSON) {
    try {
        let xParagraph = document.getElementById("paragr"+sIdParagr);
        let oErrors = JSON.parse(sJSON);
        xParagraph.className = (oErrors.aGrammErr.length || oErrors.aSpellErr.length) ? "paragraph softred" : "paragraph softgreen";
        xParagraph.textContent = "";
        _tagParagraph(sText, xParagraph, sIdParagr, oErrors.aGrammErr, oErrors.aSpellErr);
    }
    catch (e) {
        showError(e);
    }
}

function _tagParagraph (sParagraph, xParagraph, iParagraph, aSpellErr, aGrammErr) {
    try {
        if (aGrammErr.length === 0  &&  aSpellErr.length === 0) {
            xParagraph.textContent = sParagraph;
            return;
        }
        aGrammErr.push(...aSpellErr);
        aGrammErr.sort(function (a, b) {
            if (a["nStart"] < b["nStart"])
                return -1;
            if (a["nStart"] > b["nStart"])
                return 1;
            return 0;
        });

        let nErr = 0; // we count errors to give them an identifier
        let nEndLastErr = 0;
        for (let oErr of aGrammErr) {
            let nStart = oErr["nStart"];
            let nEnd = oErr["nEnd"];
            if (nStart >= nEndLastErr) {
                oErr['sErrorId'] = iParagraph.toString() + "_" + nErr.toString(); // error identifier
                oErr['sIgnoredKey'] = iParagraph.toString() + ":" + nStart.toString() + ":" + nEnd.toString() + ":" + sParagraph.slice(nStart, nEnd);
                if (nEndLastErr < nStart) {
                    xParagraph.appendChild(document.createTextNode(sParagraph.slice(nEndLastErr, nStart)));
                }
                xParagraph.appendChild(_createError(sParagraph.slice(nStart, nEnd), oErr));
                xParagraph.insertAdjacentHTML("beforeend", "<!-- err_end -->");
                nEndLastErr = nEnd;
            }
            nErr += 1;
        }
        if (nEndLastErr <= sParagraph.length) {
            xParagraph.appendChild(document.createTextNode(sParagraph.slice(nEndLastErr)));
        }
    }
    catch (e) {
        showError(e);
    }
}

function _createError (sUnderlined, oErr) {
    let xNodeErr = document.createElement("u");
    xNodeErr.id = "err" + oErr['sErrorId'];
    xNodeErr.textContent = sUnderlined;
    xNodeErr.dataset.error_id = oErr['sErrorId'];
    xNodeErr.dataset.ignored_key = oErr['sIgnoredKey'];
    xNodeErr.dataset.error_type = (oErr['sType'] === "WORD") ? "spelling" : "grammar";
    /*xNodeErr.setAttribute("href", "#");
    xNodeErr.setAttribute("onclick", "return false;");*/
    if (xNodeErr.dataset.error_type === "grammar") {
        xNodeErr.dataset.gc_message = oErr['sMessage'];
        xNodeErr.dataset.gc_url = oErr['URL'];
        if (xNodeErr.dataset.gc_message.includes(" #")) {
            xNodeErr.dataset.line_id = oErr['sLineId'];
            xNodeErr.dataset.rule_id = oErr['sRuleId'];
        }
        xNodeErr.dataset.suggestions = oErr["aSuggestions"].join("|");
    }
    xNodeErr.className = (aIgnoredErrors.has(xNodeErr.dataset.ignored_key)) ? "ignored" : "error " + oErr['sType'];
    return xNodeErr;
}

function applySuggestion (sSuggId) { // sugg
    try {
        let sErrorId = document.getElementById(sSuggId).dataset.error_id;
        let sIdParagr = sErrorId.slice(0, sErrorId.indexOf("_"));
        startWaitIcon("paragr"+sIdParagr);
        let xNodeErr = document.getElementById("err" + sErrorId);
        xNodeErr.textContent = document.getElementById(sSuggId).textContent;
        xNodeErr.className = "corrected";
        xNodeErr.removeAttribute("style");
        self.port.emit("correction", sIdParagr, getPurgedTextOfParagraph("paragr"+sIdParagr));
        hideAllTooltips();
        stopWaitIcon("paragr"+sIdParagr);
    }
    catch (e) {
        showError(e);
    }
}

function ignoreError (sIgnoreButtonId) {  // ignore
    try {
        //console.log("ignore button: " + sIgnoreButtonId + " // error id: " + document.getElementById(sIgnoreButtonId).dataset.error_id);
        let xNodeErr = document.getElementById("err"+document.getElementById(sIgnoreButtonId).dataset.error_id);
        aIgnoredErrors.add(xNodeErr.dataset.ignored_key);
        xNodeErr.className = "ignored";
        xNodeErr.removeAttribute("style");
        hideAllTooltips();
    }
    catch (e) {
        showError(e);
    }
}

function showTooltip (sNodeErrorId) {  // err
    try {
        hideAllTooltips();
        let xNodeErr = document.getElementById(sNodeErrorId);
        let sTooltipId = (xNodeErr.dataset.error_type === "grammar") ? "gc_tooltip" : "sc_tooltip";
        let xNodeTooltip = document.getElementById(sTooltipId);
        let xNodeTooltipArrow = document.getElementById(sTooltipId+"_arrow"); 
        let nLimit = nPanelWidth - 330; // paragraph width - tooltip width
        xNodeTooltipArrow.style.top = (xNodeErr.offsetTop + 16) + "px"
        xNodeTooltipArrow.style.left = (xNodeErr.offsetLeft + Math.floor((xNodeErr.offsetWidth / 2))-4) + "px" // 4 is half the width of the arrow.
        xNodeTooltip.style.top = (xNodeErr.offsetTop + 20) + "px";
        xNodeTooltip.style.left = (xNodeErr.offsetLeft > nLimit) ? nLimit + "px" : xNodeErr.offsetLeft + "px";
        if (xNodeErr.dataset.error_type === "grammar") {
            // grammar error
            if (xNodeErr.dataset.gc_message.includes(" ##")) {
                let n = xNodeErr.dataset.gc_message.indexOf(" ##");
                document.getElementById("gc_message").textContent = xNodeErr.dataset.gc_message.slice(0, n);
                document.getElementById("gc_rule_id").textContent = "Règle : " + xNodeErr.dataset.gc_message.slice(n+2);
                document.getElementById("gc_rule_id").style.display = "block";
            } else {
                document.getElementById("gc_message").textContent = xNodeErr.dataset.gc_message;
            }
            if (xNodeErr.dataset.gc_url != "") {
                document.getElementById("gc_url").style.display = "inline";
                document.getElementById("gc_url").setAttribute("href", xNodeErr.dataset.gc_url);
            } else {
                document.getElementById("gc_url").style.display = "none";
            }
            document.getElementById("gc_ignore").dataset.error_id = xNodeErr.dataset.error_id;
            let iSugg = 0;
            let xGCSugg = document.getElementById("gc_sugg_block");
            xGCSugg.textContent = "";
            if (xNodeErr.dataset.suggestions.length > 0) {
                for (let sSugg of xNodeErr.dataset.suggestions.split("|")) {
                    xGCSugg.appendChild(_createSuggestion(xNodeErr.dataset.error_id, iSugg, sSugg));
                    xGCSugg.appendChild(document.createTextNode(" "));
                    iSugg += 1;
                }
            } else {
                xGCSugg.textContent = "Aucune.";
            }
        }
        xNodeTooltipArrow.style.display = "block";
        xNodeTooltip.style.display = "block";
        if (xNodeErr.dataset.error_type === "spelling") {
            // spelling mistake
            document.getElementById("sc_ignore").dataset.error_id = xNodeErr.dataset.error_id;
            //console.log("getSuggFor: " + xNodeErr.textContent.trim() + " // error_id: " + xNodeErr.dataset.error_id);
            self.port.emit("getSuggestionsForTo", xNodeErr.textContent.trim(), xNodeErr.dataset.error_id);
        }
    }
    catch (e) {
        showError(e);
    }
}

function _createSuggestion (sErrId, iSugg, sSugg) {
    let xNodeSugg = document.createElement("a");
    xNodeSugg.id = "sugg" + sErrId + "-" + iSugg.toString();
    xNodeSugg.className = "sugg";
    /*xNodeSugg.setAttribute("href", "#");
    xNodeSugg.setAttribute("onclick", "return false;");*/
    xNodeSugg.dataset.error_id = sErrId;
    xNodeSugg.textContent = sSugg;
    return xNodeSugg;
}

/*function switchEdition (sEditButtonId) {  // edit
    let xParagraph = document.getElementById("paragr" + sEditButtonId.slice(4));
    if (xParagraph.hasAttribute("contenteditable") === false
        || xParagraph.getAttribute("contenteditable") === "false") {
        xParagraph.setAttribute("contenteditable", true);
        document.getElementById(sEditButtonId).className = "button orange";
        xParagraph.focus();
    } else {
        xParagraph.setAttribute("contenteditable", false);
        document.getElementById(sEditButtonId).className = "button";
    }
}*/

function sendBackAndCheck (sCheckButtonId) {  // check
    startWaitIcon();
    let sIdParagr = sCheckButtonId.slice(5);
    self.port.emit("modifyAndCheck", sIdParagr, getPurgedTextOfParagraph("paragr"+sIdParagr));
    stopWaitIcon();
}

function hideAllTooltips () {
    document.getElementById("gc_tooltip").style.display = "none";
    document.getElementById("gc_rule_id").style.display = "none";
    document.getElementById("sc_tooltip").style.display = "none";
    document.getElementById("gc_tooltip_arrow").style.display = "none";
    document.getElementById("sc_tooltip_arrow").style.display = "none";
}

function setSpellSuggestionsFor (sWord, sSuggestions, sErrId) {
    // spell checking suggestions
    try {
        // console.log("setSuggestionsFor: " + sWord + " > " + sSuggestions + " // " + sErrId);
        let xSuggBlock = document.getElementById("sc_sugg_block");
        xSuggBlock.textContent = "";
        if (sSuggestions === "") {
            xSuggBlock.appendChild(document.createTextNode("Aucune."));
        } else if (sSuggestions.startsWith("#")) {
            xSuggBlock.appendChild(document.createTextNode(sSuggestions));
        } else {
            let lSugg = sSuggestions.split("|");
            let iSugg = 0;
            for (let sSugg of lSugg) {
                xSuggBlock.appendChild(_createSuggestion(sErrId, iSugg, sSugg));
                xSuggBlock.appendChild(document.createTextNode(" "));
                iSugg += 1;
            }
        }
    }
    catch (e) {
        showError(e);
    }
}

function getPurgedTextOfParagraph (sNodeParagrId) {
    let sText = document.getElementById(sNodeParagrId).textContent;
    sText = sText.replace(/&nbsp;/g, " ").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&amp;/g, "&");
    return sText;
}

function copyToClipboard () {
    startWaitIcon();
    try {
        let xClipboardButton = document.getElementById("clipboard_msg");
        xClipboardButton.textContent = "copie en cours…";
        let sText = "";
        for (let xNode of document.getElementById("errorlist").getElementsByClassName("paragraph")) {
            sText += xNode.textContent + "\n";
        }
        self.port.emit('copyToClipboard', sText);
        xClipboardButton.textContent = "-> presse-papiers";
        window.setTimeout(function() { xClipboardButton.textContent = "∑"; } , 3000);
    }
    catch (e) {
        console.log(e.lineNumber + ": " +e.message);
    }
    stopWaitIcon();
}

function startWaitIcon (sIdParagr=null) {
    if (sIdParagr) {
        document.getElementById(sIdParagr).disabled = true;
        document.getElementById(sIdParagr).style.opacity = .3;
    }
    document.getElementById("waiticon").hidden = false;
}

function stopWaitIcon (sIdParagr=null) {
    if (sIdParagr) {
        document.getElementById(sIdParagr).disabled = false;
        document.getElementById(sIdParagr).style.opacity = 1;
    }
    document.getElementById("waiticon").hidden = true;
}

function showSpecialMessage () {
    if (Date.now() < Date.UTC(2017, 6, 12)) {
        try {
            document.getElementById('special_message').style.display = "block";
            document.getElementById('errorlist').style.padding = "20px 20px 30px 20px";
        } catch (e) {
            showError(e);
        }
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted gc_lang/fr/xpi/data/img/Algoo_logo.png version [59954b3904].

cannot compute difference between binary files

Deleted gc_lang/fr/xpi/data/img/LaMouette.png version [e3c6d9c279].

cannot compute difference between binary files

Deleted gc_lang/fr/xpi/data/img/contextmenu.png version [b35dd4b3cf].

cannot compute difference between binary files

Deleted gc_lang/fr/xpi/data/img/gc_tooltip_arrow.png version [07b309ad1f].

cannot compute difference between binary files

Deleted gc_lang/fr/xpi/data/img/icon-16.png version [dcb1bf8ae0].

cannot compute difference between binary files

Deleted gc_lang/fr/xpi/data/img/icon-32.png version [cbbaf9ff64].

cannot compute difference between binary files

Deleted gc_lang/fr/xpi/data/img/icon-48.png version [73a119e8c1].

cannot compute difference between binary files

Deleted gc_lang/fr/xpi/data/img/icon-64.png version [53bd99349a].

cannot compute difference between binary files

Deleted gc_lang/fr/xpi/data/img/lines.png version [e4f15f2e8d].

cannot compute difference between binary files

Deleted gc_lang/fr/xpi/data/img/logo120_text.png version [c438dd0680].

cannot compute difference between binary files

Deleted gc_lang/fr/xpi/data/img/logo2.png version [c8ddc58e4e].

cannot compute difference between binary files

Deleted gc_lang/fr/xpi/data/img/logo_texte.png version [a446454b58].

cannot compute difference between binary files

Deleted gc_lang/fr/xpi/data/img/sc_tooltip_arrow.png version [ff68f117f3].

cannot compute difference between binary files

Deleted gc_lang/fr/xpi/data/img/spinner32.png version [8fe345304b].

cannot compute difference between binary files

Deleted gc_lang/fr/xpi/data/img/spinner64.png version [962bcf56c9].

cannot compute difference between binary files

Deleted gc_lang/fr/xpi/data/lxg_panel.css version [3d666aa76c].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/* lxgpanel.css */

@import url("common.css");

header {
    background-color: hsl(0, 0%, 96%);
    padding: 10px 20px;
    border-bottom: 1px solid hsl(0, 0%, 90%);
    color: hsl(0, 0%, 0%);
}


body {
    background-color: hsl(0, 0%, 98%);
    font-family: "Trebuchet MS", sans-serif;
    overflow-x: hidden;
    color: hsl(0, 0%, 0%);
}



#wordlist {
    padding: 50px 10px 10px 10px;
}

#wordlist .paragraph {
    background-color: hsla(0, 0%, 90%, 1);
    padding: 10px;
    border-radius: 2px;
    margin: 10px 5px;
}

#wordlist p {
    margin: 8px;
}
#wordlist p.separator {
    margin: 20px 0;
    padding: 5px 50px;
    background-color: hsla(0, 0%, 75%, 1);
    color: hsla(0, 0%, 96%, 1);
    border-radius: 5px;
    text-align: center;
    font-size: 20px;
}
#wordlist .token {
    margin: 8px;
}
#wordlist ul {
    margin: 0 0 5px 40px;
}
#wordlist b {
    background-color: hsla(150, 10%, 50%, 1);
    color: hsla(0, 0%, 96%, 1);
    padding: 2px 5px;
    border-radius: 2px;
    text-decoration: none;
}
#wordlist b.WORD {
    background-color: hsla(150, 50%, 50%, 1);
}
#wordlist b.ELPFX {
    background-color: hsla(150, 30%, 50%, 1);
}
#wordlist b.UNKNOWN {
    background-color: hsla(0, 50%, 50%, 1);
}
#wordlist b.NUM {
    background-color: hsla(180, 50%, 50%, 1);
}
#wordlist b.COMPLEX {
    background-color: hsla(60, 50%, 50%, 1);
}
#wordlist b.SEPARATOR {
    background-color: hsla(210, 50%, 50%, 1);
}
#wordlist b.LINK {
    background-color: hsla(270, 50%, 50%, 1);
}
#wordlist s {
    color: hsla(0, 0%, 60%, 1);
    text-decoration: none;
}
#wordlist .textline {
    text-decoration: bold;
}

#wordlist p.message {
    margin-top: 20px;
    padding: 10px 10px;
    background-color: hsla(240, 10%, 50%, 1);
    font-size: 18px;
    color: hsla(240, 0%, 96%, 1);
    border-radius: 3px;
    text-align: center;
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































Deleted gc_lang/fr/xpi/data/lxg_panel.html version [0371eb4f06].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<!DOCTYPE HTML>
<html>
    <head>
        <link rel="stylesheet" type="text/css" href="lxg_panel.css" />
        <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
    </head>
    
    <body class="panel">
        <div style="position: fixed; width: 100%">
            <div id="rightcorner">
                <a class="rightcornerbutton red" id="close" href="#"><b>×</b></a>
                <a class="rightcornerbutton1 cyan" id="expand_reduce" href="#"><b>−</b></a>
            </div>
            
            <header>
                <div id="waiticon" class="spinner">
                  <div class="double-bounce1"></div>
                  <div class="double-bounce2"></div>
                </div>
                <h2>Grammalecte · Lexicographe</h2>
            </header>
        </div>

        <div id="movewindow">
            <div id="resize_h_bigger" class="arrow" style="border-radius: 2px 0 0 0">↓</div>
            <div id="resize_h_smaller" class="arrow">↑</div>
            <div id="resize_w_bigger" class="arrow">←</div>
            <div id="resize_w_smaller" class="arrow" style="border-radius: 0 0 0 2px">→</div>
        </div>

        <div id="wordlist"></div>

        <div class="clearer"></div>
    </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































Deleted gc_lang/fr/xpi/data/lxg_panel.js version [4bd6c52064].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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
// JavaScript

let bExpanded = true;

// events

document.getElementById('close').addEventListener("click", function (event) {
    bExpanded = true; // size is reset in ui.js
    self.port.emit('closePanel');
});

document.getElementById('expand_reduce').addEventListener("click", function (event) {
    if (bExpanded) {
        self.port.emit("resize", "reduce", 10); // the number has no meaning here
        bExpanded = false;
    } else {
        self.port.emit("resize", "expand", 10); // the number has no meaning here
        bExpanded = true;
    }
});

/*
// Conjugueur
document.getElementById('conjugueur').addEventListener("click", function (event) {
    self.port.emit('openConjugueur');
});
*/

self.port.on("addSeparator", function (sText) {
    addSeparator(sText);
});

self.port.on("addParagraphElems", function (sJSON) {
    addParagraphElems(sJSON);
});

self.port.on("addMessage", function (sClass, sText) {
    addMessage(sClass, sText);
});

self.port.on("clear", function (sHtml) {
    document.getElementById("wordlist").textContent = "";
});

self.port.on("startWaitIcon", function() {
    document.getElementById("waiticon").hidden = false;
});

self.port.on("stopWaitIcon", function() {
    document.getElementById("waiticon").hidden = true;
});


window.addEventListener(
    "click",
    function (xEvent) {
        let xElem = xEvent.target;
        if (xElem.id) {
            if (xElem.id.startsWith("resize")) {
                self.port.emit("resize", xElem.id, 10);
            }
        }
    },
    false
);


/*
    Actions
*/

function addSeparator (sText) {
    if (document.getElementById("wordlist").textContent !== "") {
        let xElem = document.createElement("p");
        xElem.className = "separator";
        xElem.textContent = sText;
        document.getElementById("wordlist").appendChild(xElem);
    }
}

function addMessage (sClass, sText) {
    let xNode = document.createElement("p");
    xNode.className = sClass;
    xNode.textContent = sText;
    document.getElementById("wordlist").appendChild(xNode);
}

function addParagraphElems (sJSON) {
    try {
        let xNodeDiv = document.createElement("div");
        xNodeDiv.className = "paragraph";
        let lElem = JSON.parse(sJSON);
        for (let oToken of lElem) {
            xNodeDiv.appendChild(createTokenNode(oToken));
        }
        document.getElementById("wordlist").appendChild(xNodeDiv);
    }
    catch (e) {
        console.error("\n" + e.fileName + "\n" + e.name + "\nline: " + e.lineNumber + "\n" + e.message);
        console.error(sJSON);
    }
}

function createTokenNode (oToken) {
    let xTokenNode = document.createElement("div");
    xTokenNode.className = "token " + oToken.sType;
    let xTokenValue = document.createElement("b");
    xTokenValue.className = oToken.sType;
    xTokenValue.textContent = oToken.sValue;
    xTokenNode.appendChild(xTokenValue);
    let xSep = document.createElement("s");
    xSep.textContent = " : ";
    xTokenNode.appendChild(xSep);
    if (oToken.aLabel.length === 1) {
        xTokenNode.appendChild(document.createTextNode(oToken.aLabel[0]));
    } else {
        let xTokenList = document.createElement("ul");
        for (let sLabel of oToken.aLabel) {
            let xTokenLine = document.createElement("li");
            xTokenLine.textContent = sLabel;
            xTokenList.appendChild(xTokenLine);
        }
        xTokenNode.appendChild(xTokenList);
    }
    return xTokenNode;
}


// display selection

function displayClasses () {
    setHidden("ok", document.getElementById("ok").checked);
    setHidden("mbok", document.getElementById("mbok").checked);
    setHidden("nb", document.getElementById("nb").checked);
    setHidden("unknown", document.getElementById("unknown").checked);
}

function setHidden (sClass, bHidden) {
    for (let i = 0; i < document.getElementsByClassName(sClass).length; i++) {
        document.getElementsByClassName(sClass)[i].hidden = bHidden;
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































Deleted gc_lang/fr/xpi/data/replace_text.js version [b8f077eb6b].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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
// replace text in active worker

const dParagraphs = new Map();

let xActiveTextZone = null;
let xCloseButton = null;
let xParentElement = null;

/* events */

self.port.on("setActiveElement", function (bSendTextBack=false) {
	setActiveElement(bSendTextBack);
});

self.port.on("setParagraph", function (iParagraph, sText) {
	dParagraphs.set(iParagraph, sText);
});

self.port.on("getParagraph", function (iParagraph) {
	let sText = dParagraphs.has(iParagraph) ? dParagraphs.get(iParagraph) : getNthParagraph(iParagraph);
	self.port.emit("emitParagraph", iParagraph, sText);
});

self.port.on("rewrite", function () {
	rewrite();
});

self.port.on("getText", function () {
	if (xActiveTextZone !== null) {
		self.port.emit("emitText", xActiveTextZone.value);
	}
});

self.port.on("write", function (sText) {
	if (xActiveTextZone !== null) {
		xActiveTextZone.value = sText;
	}
});

self.port.on("clear", function () {
	clear();
});


/* actions */

function setActiveElement (bSendTextBack=false) {
	try {
		if (document.activeElement.tagName === "TEXTAREA" || document.activeElement.tagName === "INPUT") {
			xActiveTextZone = document.activeElement;
			if (bSendTextBack) {
				self.port.emit("yesThisIsTextZone", xActiveTextZone.value);
			} else {
				self.port.emit("yesThisIsTextZone", "");
			}
			createCloseButton(xActiveTextZone);
			xActiveTextZone.disabled = true;
		} else {
			xActiveTextZone = null;
		}
		dParagraphs.clear();
	} catch (e) {
		console.error("\n" + e.fileName + "\n" + e.name + "\nline: " + e.lineNumber + "\n" + e.message);
	}
}

function rewrite () {
	try {
		if (xActiveTextZone !== null) {
			let sText = "";
			let i = 0;
			for (let sParagraph of xActiveTextZone.value.split("\n")) {
				sText += (dParagraphs.has(i)) ? dParagraphs.get(i) + "\n" : sParagraph + "\n";
				i += 1;
			}
			xActiveTextZone.value = sText.slice(0,-1);
		}
	} catch (e) {
		console.error("\n" + e.fileName + "\n" + e.name + "\nline: " + e.lineNumber + "\n" + e.message);
	}
}

function clear () {
	try {
		if (xActiveTextZone !== null) {
			xActiveTextZone.disabled = false;
		}
		if (xCloseButton !== null) {
			xParentElement.removeChild(xCloseButton);
			xParentElement = null;
			xCloseButton = null;
		}
		xActiveTextZone = null;
		dParagraphs.clear();
	} catch (e) {
		console.error("\n" + e.fileName + "\n" + e.name + "\nline: " + e.lineNumber + "\n" + e.message);
	}
}

function getNthParagraph (iParagraph) {
	if (xActiveTextZone !== null) {
		let sText = xActiveTextZone.value;
		let i = 0;
		let iStart = 0;
		while (i < iParagraph && ((iStart = sText.indexOf("\n", iStart)) !== -1)) {
			i++;
			iStart++;
		}
		if (i === iParagraph) {
			return ((iEnd = sText.indexOf("\n", iStart)) !== -1) ? sText.slice(iStart, iEnd) : sText.slice(iStart);
		}
		return "# Erreur. Paragraphe introuvable.";
	}
	return "# Erreur. Zone de texte introuvable.";
}

function createCloseButton (xActiveTextZone) {
	xParentElement = xActiveTextZone.parentElement;
	xCloseButton = document.createElement("p");
	xCloseButton.textContent = "× | Débloquer la zone de texte.";
	xCloseButton.title = "Cette action clot le panneau de correction de Grammalecte."
	xCloseButton.style = "padding: 5px; color: #FFF; background-color: #F80; border-radius: 3px; cursor: pointer";
	xCloseButton.onclick = function() {
		self.port.emit("closeGCPanel");
		self.port.emit("closeTFPanel");
		if (xParentElement !== null) {
			xParentElement.removeChild(xCloseButton);
			xParentElement = null;
			xCloseButton = null;
		}
		clear();
	};
	xParentElement.insertBefore(xCloseButton, xActiveTextZone);
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































Deleted gc_lang/fr/xpi/data/test_panel.css version [0ca7283e7e].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/* panel.css */

@import url("common.css");

header {
    background-color: hsl(0, 0%, 96%);
    border-bottom: 1px solid hsl(0, 0%, 90%);
    padding: 10px 20px;
    color: hsl(0, 0%, 0%);
}


body {
	background-color: hsl(0, 0%, 86%);
	font-family: "Trebuchet MS", sans-serif;
	overflow-x: hidden;
    color: hsl(0, 0%, 0%);
}

#cmd {
    padding: 15px;
    background-color: hsl(0, 0%, 92%);
    border-bottom: 1px solid hsl(0, 0%, 86%);
}

#cmd h1 {
    margin: 5px 0;
}

#cmd textarea {
    width: 100%;
    border: 2px solid hsl(0, 0%, 89%);
    border-radius: 3px;
    resize: vertical;
}

#results {
    padding: 15px;
    background-color: hsl(0, 0%, 96%);
}

.button {
    display: inline-block;
    padding: 5px 10px;
    width: 80px;
    border-radius: 3px;
    font-size: 12px;
    text-align: center;
    cursor: pointer;
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































Deleted gc_lang/fr/xpi/data/test_panel.html version [70fc3d08d4].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!DOCTYPE HTML>
<html>
    <head>
        <link rel="stylesheet" type="text/css" href="test_panel.css" />
        <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
    </head>
    
    <body class="panel">
        <div style="position: fixed; width: 100%">
            <div id="rightcorner">
                <a class="rightcornerbutton1 red" id="close" href="#"><b>×</b></a>
            </div>
        </div>

        <div id="cmd">
            <h1 data-l10n-id="testzone"></h1>
            <textarea id="text" rows="10"></textarea>
            <div id="testall" class="button blue" data-l10n-id="testall"></div> <div id="parse" class="button green fright" data-l10n-id="parse"></div>
        </div>

        <div id="results">
        </div>
        
    </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































Deleted gc_lang/fr/xpi/data/test_panel.js version [c07ad2c400].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// JavaScript

/*
	Events
*/

self.port.on("addElem", function (sText) {
	let xElem = document.createElement("pre");
	xElem.textContent = sText;
	document.getElementById("results").appendChild(xElem);
});

self.port.on("clear", function () {
	document.getElementById("results").textContent = "";
});

document.getElementById('testall').addEventListener("click", function (event) {
	self.port.emit('allGCTests');
});

document.getElementById('parse').addEventListener("click", function (event) {
	self.port.emit('checkText', document.getElementById('text').value);
});

document.getElementById('close').addEventListener("click", function (event) {
    self.port.emit('closePanel');
});


/*
	Actions
*/
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































Deleted gc_lang/fr/xpi/data/tf_panel.css version [5322259150].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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
/* lxgpanel.css */

@import url("common.css");

header {
    background-color: hsl(0, 0%, 94%);
    padding: 10px 20px;
    border-bottom: 1px solid hsl(0, 0%, 90%);
    color: hsl(0, 0%, 0%);
}


body {
    background-color: hsl(120, 10%, 92%);
    font-family: "Trebuchet MS", sans-serif;
    overflow-x: hidden;
    color: hsl(0, 0%, 0%);
}

#options {
    background-color: hsl(0, 0%, 96%);
    padding: 40px 15px 5px 15px;
}

.column {
    display: inline-block;
    vertical-align: top;
    width: 370px;
}

fieldset {
    margin: 5px 0;
    padding: 5px 10px 10px 10px;
    background-color: hsl(0, 0%, 92%);
    border-radius: 3px;
}

legend {
    font-size: 20px;
    color: hsla(210, 20%, 50%, .8);
    font-weight: bold;
}
legend span {
    display: none;
}

fieldset h2 {
    color: hsl(210, 80%, 40%);
}

fieldset .blockopt {
    padding: 2px 3px;
    font-size: 12.5px;
}
fieldset .underline:hover {
    background-color: hsl(180, 10%, 86%);
    border-radius: 2px;
}

fieldset .option {
    margin: 1px 3px 0 0;
    float: left;
}
legend .option {
    margin: 7px 5px 0 3px;
    float: left;
}

fieldset .opt_lbl {
    display: inline-block;
    color: hsl(0, 0%, 20%);
}


fieldset .largew {
    width: 300px;
}
fieldset .reducedw {
    width: 200px;
}
fieldset .smallw {
    width: 90px;
}

fieldset .secondoption {
    display: inline-block;
}

fieldset label span {
    display: none;
}

.groupblock {
    opacity: 0.3;
}

.inlineblock {
    display: inline-block;
}
.indent {
    margin-left: 15px;
}

#actions {
    background-color: hsl(120, 10%, 92%);
    padding: 15px;
    border-top: 1px solid hsl(120, 20%, 86%);
}

.button {
    display: inline-block;
    padding: 5px 10px;
    width: 100px;
    border-radius: 3px;
    font-size: 16px;
    font-weight: bold;
    text-align: center;
    cursor: pointer;
}

#progressbarbox {
    display: inline-block;
    padding: 10px 20px;
}

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































































































































Deleted gc_lang/fr/xpi/data/tf_panel.html version [3aa41a0998].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
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
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
<!DOCTYPE HTML>
<html>
    <head>
        <link rel="stylesheet" type="text/css" href="tf_panel.css" />
        <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
    </head>
    
    <body class="panel">
        <div style="position: fixed; width: 100%">
            <div id="rightcorner">
                <a class="rightcornerbutton1 red" id="close" href="#"><b>×</b></a>
            </div>
            
            <header>
                <h2>Grammalecte · <span data-l10n-id="tf_title"></span></h2>
            </header>
        </div>

        <div id="options">

            <div class="column" style="margin-right: 5px;">
                <!-- Supernumerary spaces -->
                <fieldset>
                    <legend><input type="checkbox" id="o_group_ssp" class="option" data-default="true" /><label for="o_group_ssp" data-l10n-id="tf_ssp"></label></legend>
                    <div id="group_ssp" class="groupblock">
                        <div class="blockopt underline">
                            <div id="res_o_start_of_paragraph" class="result fright"></div>
                            <input type="checkbox" id="o_start_of_paragraph" class="option" data-default="true" />
                            <label for="o_start_of_paragraph" class="opt_lbl largew" data-l10n-id="tf_start_of_paragraph"></label>
                        </div>
                        <div class="blockopt underline">
                            <div id="res_o_end_of_paragraph" class="result fright"></div>
                            <input type="checkbox" id="o_end_of_paragraph" class="option" data-default="true" />
                            <label for="o_end_of_paragraph" class="opt_lbl largew" data-l10n-id="tf_end_of_paragraph"></label>
                        </div>
                        <div class="blockopt underline">
                            <div id="res_o_between_words" class="result fright"></div>
                            <input type="checkbox" id="o_between_words" class="option" data-default="true" />
                            <label for="o_between_words" class="opt_lbl largew" data-l10n-id="tf_between_words"></label>
                        </div>
                        <div class="blockopt underline">
                            <div id="res_o_before_punctuation" class="result fright"></div>
                            <input type="checkbox" id="o_before_punctuation" class="option" data-default="true" />
                            <label for="o_before_punctuation" class="opt_lbl largew" data-l10n-id="tf_before_punctuation"></label>
                        </div>
                        <div class="blockopt underline">
                            <div id="res_o_within_parenthesis" class="result fright"></div>
                            <input type="checkbox" id="o_within_parenthesis" class="option" data-default="true" />
                            <label for="o_within_parenthesis" class="opt_lbl largew" data-l10n-id="tf_within_parenthesis"></label>
                        </div>
                        <div class="blockopt underline">
                            <div id="res_o_within_square_brackets" class="result fright"></div>
                            <input type="checkbox" id="o_within_square_brackets" class="option" data-default="true" />
                            <label for="o_within_square_brackets" class="opt_lbl largew" data-l10n-id="tf_within_square_brackets"></label>
                        </div>
                        <div class="blockopt underline">
                            <div id="res_o_within_quotation_marks" class="result fright"></div>
                            <input type="checkbox" id="o_within_quotation_marks" class="option" data-default="true" />
                            <label for="o_within_quotation_marks" class="opt_lbl largew" data-l10n-id="tf_within_quotation_marks"></label>
                        </div>
                    </div>
                </fieldset>

                <!-- Missing spaces -->
                <fieldset>
                    <legend><input type="checkbox" id="o_group_space" class="option" data-default="true" /><label for="o_group_space" data-l10n-id="tf_space"></label></legend>
                    <div id="group_space" class="groupblock">
                        <div class="blockopt underline">
                            <div id="res_o_add_space_after_punctuation" class="result fright"></div>
                            <input type="checkbox" id="o_add_space_after_punctuation" class="option" data-default="true" />
                            <label for="o_add_space_after_punctuation" class="opt_lbl reducedw" data-l10n-id="tf_add_space_after_punctuation"></label>
                        </div>
                        <div class="blockopt underline">
                            <div id="res_o_add_space_around_hyphens" class="result fright"></div>
                            <input type="checkbox" id="o_add_space_around_hyphens" class="option" data-default="true" />
                            <label for="o_add_space_around_hyphens" class="opt_lbl largew" data-l10n-id="tf_add_space_around_hyphens"></label>
                        </div>
                    </div>
                </fieldset>

                <!-- Non breaking spaces -->
                <fieldset>
                    <legend><input type="checkbox" id="o_group_nbsp" class="option" data-default="true" /><label for="o_group_nbsp" data-l10n-id="tf_nbsp"></label></legend>
                    <div id="group_nbsp" class="groupblock">
                        <div class="blockopt underline">
                            <div id="res_o_nbsp_before_punctuation" class="result fright"></div>
                            <input type="checkbox" id="o_nbsp_before_punctuation" class="option" data-default="true" />
                            <label for="o_nbsp_before_punctuation" class="opt_lbl reducedw" data-l10n-id="tf_nbsp_before_punctuation"></label>
                            <!--<div class="secondoption">
                                <input type="checkbox" id="o_nnbsp_before_punctuation" class="option" />
                                <label for="o_nnbsp_before_punctuation" class="opt_lbl smallw">fines<span>sauf avec “:”</span></label>
                            </div>-->
                        </div>
                        <div class="blockopt underline">
                            <div id="res_o_nbsp_within_quotation_marks" class="result fright"></div>
                            <input type="checkbox" id="o_nbsp_within_quotation_marks" class="option" data-default="true" />
                            <label for="o_nbsp_within_quotation_marks" class="opt_lbl reducedw" data-l10n-id="tf_nbsp_within_quotation_marks"></label>
                            <!--<div class="secondoption">
                                <input type="checkbox" id="o_nnbsp_within_quotation_marks" class="option" />
                                <label for="o_nnbsp_within_quotation_marks" class="opt_lbl smallw">fines</label>
                            </div>-->
                        </div>
                        <div class="blockopt underline">
                            <div id="res_o_nbsp_before_symbol" class="result fright"></div>
                            <input type="checkbox" id="o_nbsp_before_symbol" class="option" data-default="true" />
                            <label for="o_nbsp_before_symbol" class="opt_lbl largew" data-l10n-id="tf_nbsp_before_symbol"></label>
                        </div>
                        <div class="blockopt underline">
                            <div id="res_o_nbsp_within_numbers" class="result fright"></div>
                            <input type="checkbox" id="o_nbsp_within_numbers" class="option" data-default="true" />
                            <label for="o_nbsp_within_numbers" class="opt_lbl reducedw" data-l10n-id="tf_nbsp_within_numbers"></label>
                            <!--<div class="secondoption">
                                <input type="checkbox" id="o_nnbsp_within_numbers" class="option" />
                                <label for="o_nnbsp_within_numbers" class="opt_lbl smallw">fines</label>
                            </div>-->
                        </div>
                        <div class="blockopt underline">
                            <div id="res_o_nbsp_before_units" class="result fright"></div>
                            <input type="checkbox" id="o_nbsp_before_units" class="option" data-default="true" />
                            <label for="o_nbsp_before_units" class="opt_lbl largew" data-l10n-id="tf_nbsp_before_units"></label>
                        </div>
                    </div>
                </fieldset>

                <!-- Deletions -->
                <fieldset>
                    <legend><input type="checkbox" id="o_group_delete" class="option" data-default="true" /><label for="o_group_delete" data-l10n-id="tf_delete"></label></legend>
                    <div id="group_delete" class="groupblock">
                        <div class="blockopt underline">
                            <div id="res_o_erase_non_breaking_hyphens" class="result fright"></div>
                            <input type="checkbox" id="o_erase_non_breaking_hyphens" class="option" data-default="true" />
                            <label for="o_erase_non_breaking_hyphens" class="opt_lbl largew" data-l10n-id="tf_erase_non_breaking_hyphens"></label>
                        </div>
                    </div>
                </fieldset>
            </div>

            <div class="column">
                <!-- Typographical signs -->
                <fieldset>
                    <legend><input type="checkbox" id="o_group_typo" class="option" data-default="true" /><label for="o_group_typo" data-l10n-id="tf_typo"></label></legend>
                    <div id="group_typo" class="groupblock">
                        <div class="blockopt underline">
                            <div id="res_o_ts_apostrophe" class="result fright"></div>
                            <input type="checkbox" id="o_ts_apostrophe" class="option" data-default="true" />
                            <label for="o_ts_apostrophe" class="opt_lbl largew" data-l10n-id="tf_ts_apostrophe"></label>
                        </div>
                        <div class="blockopt underline">
                            <div id="res_o_ts_ellipsis" class="result fright"></div>
                            <input type="checkbox" id="o_ts_ellipsis" class="option" data-default="true" />
                            <label for="o_ts_ellipsis" class="opt_lbl largew" data-l10n-id="tf_ts_ellipsis"></label>
                        </div>
                        <div class="blockopt underline">
                            <div id="res_o_ts_dash_middle" class="result fright"></div>
                            <input type="checkbox" id="o_ts_dash_middle" class="option" data-default="true" />
                            <label for="o_ts_dash_middle" class="opt_lbl largew" data-l10n-id="tf_ts_dash_middle"></label>
                        </div>
                        <div class="blockopt">
                            <div class="inlineblock indent">
                                <input type="radio" name="hyphen1" id="o_ts_m_dash_middle" class="option" data-default="false" /><label for="o_ts_m_dash_middle" class="opt_lbl" data-l10n-id="tf_emdash"></label>
                            </div>
                            <div class="inlineblock indent">
                                <input type="radio" name="hyphen1" id="o_ts_n_dash_middle" class="option" data-default="true" /><label for="o_ts_n_dash_middle" class="opt_lbl" data-l10n-id="tf_endash"></label>
                            </div>
                        </div>
                        <div class="blockopt underline">
                            <div id="res_o_ts_dash_start" class="result fright"></div>
                            <input type="checkbox" id="o_ts_dash_start" class="option" data-default="true" />
                            <label for="o_ts_dash_start" class="opt_lbl largew" data-l10n-id="tf_ts_dash_start"></label>
                        </div>
                        <div class="blockopt">
                            <div class="inlineblock indent">
                                <input type="radio" name="hyphen2" id="o_ts_m_dash_start" class="option"  data-default="true" /><label for="o_ts_m_dash_start" class="opt_lbl" data-l10n-id="tf_emdash"></label>
                            </div>
                            <div class="inlineblock indent">
                                <input type="radio" name="hyphen2" id="o_ts_n_dash_start" class="option" data-default="false" /><label for="o_ts_n_dash_start" class="opt_lbl" data-l10n-id="tf_endash"></label>
                            </div>
                        </div>
                        <div class="blockopt underline">
                            <div id="res_o_ts_quotation_marks" class="result fright"></div>
                            <input type="checkbox" id="o_ts_quotation_marks" class="option" data-default="true" />
                            <label for="o_ts_quotation_marks" class="opt_lbl largew" data-l10n-id="tf_ts_quotation_marks"></label>
                        </div>
                        <div class="blockopt underline">
                            <div id="res_o_ts_units" class="result fright"></div>
                            <input type="checkbox" id="o_ts_units" class="option" data-default="true" />
                            <label for="o_ts_units" class="opt_lbl largew" data-l10n-id="tf_ts_units"></label>
                        </div>
                        <div class="blockopt underline">
                            <div id="res_o_ts_spell" class="result fright"></div>
                            <input type="checkbox" id="o_ts_spell" class="option" data-default="true" />
                            <label for="o_ts_spell" class="opt_lbl largew" data-l10n-id="tf_ts_spell"></label>
                        </div>
                        <div class="blockopt underline">
                            <div id="res_o_ts_ligature" class="result fright"></div>
                            <div class="inlineblock">
                                <input type="checkbox" id="o_ts_ligature" class="option" data-default="false" />
                                <label for="o_ts_ligature" class="opt_lbl" data-l10n-id="tf_ts_ligature"></label>
                            </div>
                            <div class="inlineblock indent">
                                <input type="radio" id="o_ts_ligature_do" name="liga" class="option" data-default="false" />
                                <label for="o_ts_ligature_do" class="opt_lbl" data-l10n-id="tf_ts_ligature_do"></label>
                            </div>
                            <div class="inlineblock indent">
                                <input type="radio" id="o_ts_ligature_undo" name="liga" class="option" data-default="true" />
                                <label for="o_ts_ligature_undo" class="opt_lbl" data-l10n-id="tf_ts_ligature_undo"></label>
                            </div>
                        </div>

                        <div class="blockopt">
                            <div class="inlineblock indent"><input type="checkbox" id="o_ts_ligature_ff" class="option" data-default="true" /><label for="o_ts_ligature_ff" class="opt_lbl">ff</label></div>
                            &nbsp; <div class="inlineblock"><input type="checkbox" id="o_ts_ligature_fi" class="option" data-default="true" /><label for="o_ts_ligature_fi" class="opt_lbl">fi</label></div>
                            &nbsp; <div class="inlineblock"><input type="checkbox" id="o_ts_ligature_ffi" class="option" data-default="true" /><label for="o_ts_ligature_ffi" class="opt_lbl">ffi</label></div>
                            &nbsp; <div class="inlineblock"><input type="checkbox" id="o_ts_ligature_fl" class="option" data-default="true" /><label for="o_ts_ligature_fl" class="opt_lbl">fl</label></div>
                            &nbsp; <div class="inlineblock"><input type="checkbox" id="o_ts_ligature_ffl" class="option" data-default="true" /><label for="o_ts_ligature_ffl" class="opt_lbl">ffl</label></div>
                            &nbsp; <div class="inlineblock"><input type="checkbox" id="o_ts_ligature_ft" class="option" data-default="true" /><label for="o_ts_ligature_ft" class="opt_lbl">ft</label></div>
                            &nbsp; <div class="inlineblock"><input type="checkbox" id="o_ts_ligature_st" class="option" data-default="false" /><label for="o_ts_ligature_st" class="opt_lbl">st</label></div>
                        </div>
                    </div>
                </fieldset>

                <!-- Misc -->
                <fieldset>
                    <legend><input type="checkbox" id="o_group_misc" class="option" data-default="true" /><label for="o_group_misc" data-l10n-id="tf_misc"></label></legend>
                    <div id="group_misc" class="groupblock">
                        <div class="blockopt underline">
                            <div id="res_o_ordinals_no_exponant" class="result fright"></div>
                            <input type="checkbox" id="o_ordinals_no_exponant" class="option" data-default="true" />
                            <label for="o_ordinals_no_exponant" class="opt_lbl reducedw" data-l10n-id="tf_ordinals_no_exponant"></label>
                            <div class="secondoption">
                                <input type="checkbox" id="o_ordinals_exponant" class="option" data-default="true" />
                                <label for="o_ordinals_exponant" class="opt_lbl smallw" data-l10n-id="tf_ordinals_exponant"></label>
                            </div>
                        </div>
                        <div class="blockopt underline">
                            <div id="res_o_etc" class="result fright"></div>
                            <input type="checkbox" id="o_etc" class="option" data-default="true" />
                            <label for="o_etc" class="opt_lbl largew" data-l10n-id="tf_etc"></label>
                        </div>
                        <div class="blockopt underline">
                            <div id="res_o_missing_hyphens" class="result fright"></div>
                            <input type="checkbox" id="o_missing_hyphens" class="option" data-default="true" />
                            <label for="o_missing_hyphens" class="opt_lbl largew" data-l10n-id="tf_missing_hyphens"></label>
                        </div>
                        <div class="blockopt underline">
                            <div id="res_o_ma_word" class="result fright"></div>
                            <input type="checkbox" id="o_ma_word" class="option" data-default="true" />
                            <label for="o_ma_word" class="opt_lbl largew" data-l10n-id="tf_ma_word"></label>
                        </div>
                        <div class="blockopt">
                            <div class="inlineblock indent">
                                <input type="checkbox" id="o_ma_1letter_lowercase" class="option" />
                                <label for="o_ma_1letter_lowercase" class="opt_lbl" data-l10n-id="tf_ma_1letter_lowercase"></label>
                            </div>
                            <div class="inlineblock indent">
                                <input type="checkbox" id="o_ma_1letter_uppercase" class="option" />
                                <label for="o_ma_1letter_uppercase" class="opt_lbl" data-l10n-id="tf_ma_1letter_uppercase"></label>
                            </div>
                        </div>
                    </div>
                </fieldset>

                <!-- Restructuration -->
                <fieldset>
                    <legend><input type="checkbox" id="o_group_struct" class="option" data-default="false" /><label for="o_group_struct" data-l10n-id="tf_struct"></label></legend>
                    <div id="group_struct" class="groupblock">
                        <div class="blockopt underline">
                            <div id="res_o_remove_hyphens_at_end_of_paragraphs" class="result fright"></div>
                            <input type="checkbox" id="o_remove_hyphens_at_end_of_paragraphs" class="option" data-default="false" />
                            <label for="o_remove_hyphens_at_end_of_paragraphs" class="opt_lbl largew"  data-l10n-id="tf_remove_hyphens_at_end_of_paragraphs"></label>
                        </div>
                        <div class="blockopt underline">
                            <div id="res_o_merge_contiguous_paragraphs" class="result fright"></div>
                            <input type="checkbox" id="o_merge_contiguous_paragraphs" class="option" data-default="false" />
                            <label for="o_merge_contiguous_paragraphs" class="opt_lbl largew" data-l10n-id="tf_merge_contiguous_paragraphs"></label>
                        </div>
                    </div>
                </fieldset>
            </div>
        </div>

        <div id="actions">
            <div id="reset" class="button blue" data-l10n-id="tf_default"></div>
            <div id="apply" class="button green fright" data-l10n-id="tf_apply"></div>
            <div id="progressbarbox"><progress id="progressbar" style="width: 400px;"></progress> <span id="time_res"></span></div>
            <!--<div class="clearer"></div>
            <div id="infomsg" data-l10n-id="tf_infomsg"></div>-->
        </div>

    </body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































































































































































































































Deleted gc_lang/fr/xpi/data/tf_panel.js version [870535c123].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
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
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
// JavaScript


/*
    Events
*/
self.port.on("receiveTextToFormat", function (sText) {
    self.port.emit("applyFormattedText", applyOptions(sText));
});

self.port.on("start", function (sTFOptions) {
    self.port.emit("setHeight", document.getElementById("actions").offsetTop + document.getElementById("actions").offsetHeight);
    if (sTFOptions !== "") {
        setOptionsInPanel(JSON.parse(sTFOptions));
    } else {
        reset();
    }
    resetProgressBar();
    document.getElementById('apply').focus();
});

document.getElementById('close').addEventListener("click", function (event) {
    self.port.emit('closePanel');
});

document.getElementById('reset').addEventListener("click", function (event) {
    reset();
});

document.getElementById('apply').addEventListener("click", function (event) {
    saveOptions();
    self.port.emit("getTextToFormat");
});

window.addEventListener("click", function (xEvent) {
    let xElem = xEvent.target;
    if (xElem.id) {
        if (xElem.id.startsWith("resize")) {
            self.port.emit("resize", xElem.id, 10);
        } else if (xElem.id.startsWith("o_group_")) {
            switchGroup(xElem.id);
            resetProgressBar();
        }
    }
}, false);


/*
    Actions
*/
function switchGroup (sOptName) {
    if (document.getElementById(sOptName).checked) {
        document.getElementById(sOptName.slice(2)).style.opacity = 1;
    } else {
        document.getElementById(sOptName.slice(2)).style.opacity = 0.3;
    }
}

function reset () {
    resetProgressBar();
    for (let xNode of document.getElementsByClassName("option")) {
        xNode.checked = (xNode.dataset.default === "true");
        if (xNode.id.startsWith("o_group_")) {
            switchGroup(xNode.id);
        }
    }
}

function resetProgressBar () {
    document.getElementById('progressbar').value = 0;
    document.getElementById('time_res').textContent = "";
}

function setOptionsInPanel (oOptions) {
    for (let sOptName in oOptions) {
        //console.log(sOptName + ":" + oOptions[sOptName]);
        if (document.getElementById(sOptName) !== null) {
            document.getElementById(sOptName).checked = oOptions[sOptName];
            if (sOptName.startsWith("o_group_")) {
                switchGroup(sOptName);
            } 
            if (document.getElementById("res_"+sOptName) !== null) {
                document.getElementById("res_"+sOptName).textContent = "";
            }
        }
    }
}

function saveOptions () {
    let oOptions = {};
    for (let xNode of document.getElementsByClassName("option")) {
        oOptions[xNode.id] = xNode.checked;
    }
    self.port.emit("saveOptions", JSON.stringify(oOptions));
}

function applyOptions (sText) {
    try {
        const t0 = Date.now();
        //window.setCursor("wait"); // change pointer
        resetProgressBar();
        document.getElementById('progressbar').max = 7;
        let n1 = 0, n2 = 0, n3 = 0, n4 = 0, n5 = 0, n6 = 0, n7 = 0;
        
        // Restructuration
        if (document.getElementById("o_group_struct").checked) {
            if (document.getElementById("o_remove_hyphens_at_end_of_paragraphs").checked) {
                [sText, n1] = removeHyphenAtEndOfParagraphs(sText);
                document.getElementById('res_o_remove_hyphens_at_end_of_paragraphs').textContent = n1;
            }
            if (document.getElementById("o_merge_contiguous_paragraphs").checked) {
                [sText, n1] = mergeContiguousParagraphs(sText);
                document.getElementById('res_o_merge_contiguous_paragraphs').textContent = n1;
            }
            document.getElementById("o_group_struct").checked = false;
            switchGroup("o_group_struct");
        }
        document.getElementById('progressbar').value = 1;

        // espaces surnuméraires
        if (document.getElementById("o_group_ssp").checked) {
            if (document.getElementById("o_end_of_paragraph").checked) {
                [sText, n1] = formatText(sText, "end_of_paragraph");
                document.getElementById('res_o_end_of_paragraph').textContent = n1;
            }
            if (document.getElementById("o_between_words").checked) {
                [sText, n1] = formatText(sText, "between_words");
                document.getElementById('res_o_between_words').textContent = n1;
            }
            if (document.getElementById("o_start_of_paragraph").checked) {
                [sText, n1] = formatText(sText, "start_of_paragraph");
                document.getElementById('res_o_start_of_paragraph').textContent = n1;
            }
            if (document.getElementById("o_before_punctuation").checked) {
                [sText, n1] = formatText(sText, "before_punctuation");
                document.getElementById('res_o_before_punctuation').textContent = n1;
            }
            if (document.getElementById("o_within_parenthesis").checked) {
                [sText, n1] = formatText(sText, "within_parenthesis");
                document.getElementById('res_o_within_parenthesis').textContent = n1;
            }
            if (document.getElementById("o_within_square_brackets").checked) {
                [sText, n1] = formatText(sText, "within_square_brackets");
                document.getElementById('res_o_within_square_brackets').textContent = n1;
            }
            if (document.getElementById("o_within_quotation_marks").checked) {
                [sText, n1] = formatText(sText, "within_quotation_marks");
                document.getElementById('res_o_within_quotation_marks').textContent = n1;
            }
            document.getElementById("o_group_ssp").checked = false;
            switchGroup("o_group_ssp");
        }
        document.getElementById('progressbar').value = 2;

        // espaces typographiques
        if (document.getElementById("o_group_nbsp").checked) {
            if (document.getElementById("o_nbsp_before_punctuation").checked) {
                [sText, n1] = formatText(sText, "nbsp_before_punctuation");
                [sText, n2] = formatText(sText, "nbsp_repair");
                document.getElementById('res_o_nbsp_before_punctuation').textContent = n1 - n2;
            }
            if (document.getElementById("o_nbsp_within_quotation_marks").checked) {
                [sText, n1] = formatText(sText, "nbsp_within_quotation_marks");
                document.getElementById('res_o_nbsp_within_quotation_marks').textContent = n1;
            }
            if (document.getElementById("o_nbsp_before_symbol").checked) {
                [sText, n1] = formatText(sText, "nbsp_before_symbol");
                document.getElementById('res_o_nbsp_before_symbol').textContent = n1;
            }
            if (document.getElementById("o_nbsp_within_numbers").checked) {
                [sText, n1] = formatText(sText, "nbsp_within_numbers");
                document.getElementById('res_o_nbsp_within_numbers').textContent = n1;
            }
            if (document.getElementById("o_nbsp_before_units").checked) {
                [sText, n1] = formatText(sText, "nbsp_before_units");
                document.getElementById('res_o_nbsp_before_units').textContent = n1;
            }
            document.getElementById("o_group_nbsp").checked = false;
            switchGroup("o_group_nbsp");
        }
        document.getElementById('progressbar').value = 3;

        // espaces manquants
        if (document.getElementById("o_group_typo").checked) {
            if (document.getElementById("o_ts_units").checked) {
                [sText, n1] = formatText(sText, "ts_units");
                document.getElementById('res_o_ts_units').textContent = n1;
            }
        }
        if (document.getElementById("o_group_space").checked) {
            if (document.getElementById("o_add_space_after_punctuation").checked) {
                [sText, n1] = formatText(sText, "add_space_after_punctuation");
                [sText, n2] = formatText(sText, "add_space_repair");
                document.getElementById('res_o_add_space_after_punctuation').textContent = n1 - n2;
            }
            if (document.getElementById("o_add_space_around_hyphens").checked) {
                [sText, n1] = formatText(sText, "add_space_around_hyphens");
                document.getElementById('res_o_add_space_around_hyphens').textContent = n1;
            }
            document.getElementById("o_group_space").checked = false;
            switchGroup("o_group_space");
        }
        document.getElementById('progressbar').value = 4;

        // suppression
        if (document.getElementById("o_group_delete").checked) {
            if (document.getElementById("o_erase_non_breaking_hyphens").checked) {
                [sText, n1] = formatText(sText, "erase_non_breaking_hyphens");
                document.getElementById('res_o_erase_non_breaking_hyphens').textContent = n1;
            }
            document.getElementById("o_group_delete").checked = false;
            switchGroup("o_group_delete");
        }
        document.getElementById('progressbar').value = 5;

        // signes typographiques
        if (document.getElementById("o_group_typo").checked) {
            if (document.getElementById("o_ts_apostrophe").checked) {
                [sText, n1] = formatText(sText, "ts_apostrophe");
                document.getElementById('res_o_ts_apostrophe').textContent = n1;
            }
            if (document.getElementById("o_ts_ellipsis").checked) {
                [sText, n1] = formatText(sText, "ts_ellipsis");
                document.getElementById('res_o_ts_ellipsis').textContent = n1;
            }
            if (document.getElementById("o_ts_dash_start").checked) {
                if (document.getElementById("o_ts_m_dash_start").checked) {
                    [sText, n1] = formatText(sText, "ts_m_dash_start");
                } else {
                    [sText, n1] = formatText(sText, "ts_n_dash_start");
                }
                document.getElementById('res_o_ts_dash_start').textContent = n1;
            }
            if (document.getElementById("o_ts_dash_middle").checked) {
                if (document.getElementById("o_ts_m_dash_middle").checked) {
                    [sText, n1] = formatText(sText, "ts_m_dash_middle");
                } else {
                    [sText, n1] = formatText(sText, "ts_n_dash_middle");
                }
                document.getElementById('res_o_ts_dash_middle').textContent = n1;
            }
            if (document.getElementById("o_ts_quotation_marks").checked) {
                [sText, n1] = formatText(sText, "ts_quotation_marks");
                document.getElementById('res_o_ts_quotation_marks').textContent = n1;
            }
            if (document.getElementById("o_ts_spell").checked) {
                [sText, n1] = formatText(sText, "ts_spell");
                document.getElementById('res_o_ts_spell').textContent = n1;
            }
            if (document.getElementById("o_ts_ligature").checked) {
                // ligatures typographiques : fi, fl, ff, ffi, ffl, ft, st
                if (document.getElementById("o_ts_ligature_do").checked) {
                    if (document.getElementById("o_ts_ligature_ffi").checked) {
                        [sText, n1] = formatText(sText, "ts_ligature_ffi_do");
                    }
                    if (document.getElementById("o_ts_ligature_ffl").checked) {
                        [sText, n2] = formatText(sText, "ts_ligature_ffl_do");
                    }
                    if (document.getElementById("o_ts_ligature_fi").checked) {
                        [sText, n3] = formatText(sText, "ts_ligature_fi_do");
                    }
                    if (document.getElementById("o_ts_ligature_fl").checked) {
                        [sText, n4] = formatText(sText, "ts_ligature_fl_do");
                    }
                    if (document.getElementById("o_ts_ligature_ff").checked) {
                        [sText, n5] = formatText(sText, "ts_ligature_ff_do");
                    }
                    if (document.getElementById("o_ts_ligature_ft").checked) {
                        [sText, n6] = formatText(sText, "ts_ligature_ft_do");
                    }
                    if (document.getElementById("o_ts_ligature_st").checked) {
                        [sText, n7] = formatText(sText, "ts_ligature_st_do");
                    }
                }
                if (document.getElementById("o_ts_ligature_undo").checked) {
                    if (document.getElementById("o_ts_ligature_ffi").checked) {
                        [sText, n1] = formatText(sText, "ts_ligature_ffi_undo");
                    }
                    if (document.getElementById("o_ts_ligature_ffl").checked) {
                        [sText, n2] = formatText(sText, "ts_ligature_ffl_undo");
                    }
                    if (document.getElementById("o_ts_ligature_fi").checked) {
                        [sText, n3] = formatText(sText, "ts_ligature_fi_undo");
                    }
                    if (document.getElementById("o_ts_ligature_fl").checked) {
                        [sText, n4] = formatText(sText, "ts_ligature_fl_undo");
                    }
                    if (document.getElementById("o_ts_ligature_ff").checked) {
                        [sText, n5] = formatText(sText, "ts_ligature_ff_undo");
                    }
                    if (document.getElementById("o_ts_ligature_ft").checked) {
                        [sText, n6] = formatText(sText, "ts_ligature_ft_undo");
                    }
                    if (document.getElementById("o_ts_ligature_st").checked) {
                        [sText, n7] = formatText(sText, "ts_ligature_st_undo");
                    }
                }
                document.getElementById('res_o_ts_ligature').textContent = n1 + n2 + n3 + n4 + n5 + n6 + n7;
            }
            document.getElementById("o_group_typo").checked = false;
            switchGroup("o_group_typo");
        }
        document.getElementById('progressbar').value = 6;

        // divers
        if (document.getElementById("o_group_misc").checked) {
            if (document.getElementById("o_ordinals_no_exponant").checked) {
                if (document.getElementById("o_ordinals_exponant").checked) {
                    [sText, n1] = formatText(sText, "ordinals_exponant");
                } else {
                    [sText, n1] = formatText(sText, "ordinals_no_exponant");
                }
                document.getElementById('res_o_ordinals_no_exponant').textContent = n1;
            }
            if (document.getElementById("o_etc").checked) {
                [sText, n1] = formatText(sText, "etc");
                document.getElementById('res_o_etc').textContent = n1;
            }
            if (document.getElementById("o_missing_hyphens").checked) {
                [sText, n1] = formatText(sText, "missing_hyphens");
                document.getElementById('res_o_missing_hyphens').textContent = n1;
            }
            if (document.getElementById("o_ma_word").checked) {
                [sText, n1] = formatText(sText, "ma_word");
                if (document.getElementById("o_ma_1letter_lowercase").checked) {
                    [sText, n1] = formatText(sText, "ma_1letter_lowercase");
                    if (document.getElementById("o_ma_1letter_uppercase").checked) {
                        [sText, n1] = formatText(sText, "ma_1letter_uppercase");
                    }
                }
                document.getElementById('res_o_ma_word').textContent = n1;
            }
            document.getElementById("o_group_misc").checked = false;
            switchGroup("o_group_misc");
        }
        document.getElementById('progressbar').value = document.getElementById('progressbar').max;
        // end of processing

        //window.setCursor("auto"); // restore pointer

        const t1 = Date.now();
        document.getElementById('time_res').textContent = this.getTimeRes((t1-t0)/1000);
    }
    catch (e) {
        console.error("\n" + e.fileName + "\n" + e.name + "\nline: " + e.lineNumber + "\n" + e.message);
    }
    return sText;
}

function formatText (sText, sOptName) {
    let nCount = 0;
    try {
        if (!oReplTable.hasOwnProperty(sOptName)) {
            console.log("# Error. TF: there is no option “" + sOptName+ "”.");
            return [sText, nCount];
        }
        for (let [zRgx, sRep] of oReplTable[sOptName]) {
            nCount += (sText.match(zRgx) || []).length;
            sText = sText.replace(zRgx, sRep);
        }
        document.getElementById('progressbar').value += 1;
    }
    catch (e) {
        console.error("\n" + e.fileName + "\n" + e.name + "\nline: " + e.lineNumber + "\n" + e.message);
    }
    return [sText, nCount];
};

function removeHyphenAtEndOfParagraphs (sText) {
    let nCount = (sText.match(/-[  ]*\n/gm) || []).length;
    sText = sText.replace(/-[  ]*\n/gm, "");
    /*
    sText = sText.replace(/-[  ]+$/gm, "-"); // remove spaces at end of paragraphs if - is the last character
    let m = null;
    let zRegExp = /([a-zA-Zà-ö0-9À-Öø-ÿØ-ßĀ-ʯ]+)-\n([a-zA-Zà-ö0-9À-Öø-ÿØ-ßĀ-ʯ]+)/g;
    while ((m = zRegExp.exec(sText)) !== null) {
        console.log("+");
        sText = sText.slice(0, m.index) + m[1] + m[2] + sText.slice(RegExp.lastIndex);
    }*/
    return [sText, nCount];
}

function mergeContiguousParagraphs (sText) {
    let nCount = 0;
    sText = sText.replace(/^[  ]+$/gm, ""); // clear empty paragraphs
    let s = "";
    for (let sParagraph of getParagraph(sText)) {
        if (sParagraph === "") {
            s += "\n";
        } else {
            s += sParagraph + " ";
            nCount += 1;
        }
    }
    s = s.replace(/  +/g, " ").replace(/ $/gm, "");
    return [s, nCount];
}

function* getParagraph (sText) {
    // generator: returns paragraphs of text
    let iStart = 0;
    let iEnd = 0;
    while ((iEnd = sText.indexOf("\n", iStart)) !== -1) {
        yield sText.slice(iStart, iEnd);
        iStart = iEnd + 1;
    }
    yield sText.slice(iStart);
}

function getTimeRes (n) {
    // returns duration in seconds as string
    if (n < 10) {
        return n.toFixed(3).toString() + " s";
    }
    if (n < 100) {
        return n.toFixed(2).toString() + " s";
    }
    if (n < 1000) {
        return n.toFixed(1).toString() + " s";
    }
    return n.toFixed().toString() + " s";
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted gc_lang/fr/xpi/gce_worker.js version [32ac3727dc].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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
// JavaScript

// Grammar checker engine
// PromiseWorker
// This code is executed in a separate thread (×20 faster too!!!)

// Firefox WTF: it’s impossible to use require as in the main thread here,
// so it is required to declare a resource in the file “chrome.manifest”.


"use strict";

// copy/paste
// https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/PromiseWorker.jsm

importScripts("resource://gre/modules/workers/require.js");
let PromiseWorker = require("resource://gre/modules/workers/PromiseWorker.js");

// Instantiate AbstractWorker (see below).
let worker = new PromiseWorker.AbstractWorker();

worker.dispatch = function(method, args = []) {
  // Dispatch a call to method `method` with args `args`
  return self[method](...args);
};
worker.postMessage = function(...args) {
  // Post a message to the main thread
  self.postMessage(...args);
};
worker.close = function() {
  // Close the worker
  self.close();
};
worker.log = function(...args) {
  // Log (or discard) messages (optional)
  dump("Worker: " + args.join(" ") + "\n");
};

// Connect it to message port.
self.addEventListener("message", msg => worker.handleMessage(msg));

// end of copy/paste


// no console here, use “dump”

let gce = null; // module: grammar checker engine
let text = null;
let tkz = null; // module: tokenizer
let lxg = null; // module: lexicographer
let helpers = null;

let oTokenizer = null;
let oDict = null;
let oLxg = null;

function loadGrammarChecker (sGCOptions="", sContext="JavaScript") {
    if (gce === null) {
        try {
            gce = require("resource://grammalecte/fr/gc_engine.js");
            helpers = require("resource://grammalecte/helpers.js");
            text = require("resource://grammalecte/text.js");
            tkz = require("resource://grammalecte/tokenizer.js");
            lxg = require("resource://grammalecte/fr/lexicographe.js");
            oTokenizer = new tkz.Tokenizer("fr");
            helpers.setLogOutput(worker.log);
            gce.load(sContext);
            oDict = gce.getDictionary();
            oLxg = new lxg.Lexicographe(oDict);
            if (sGCOptions !== "") {
                gce.setOptions(helpers.objectToMap(JSON.parse(sGCOptions)));
            }
            // we always retrieve options from the gce, for setOptions filters obsolete options
            return gce.getOptions().gl_toString();
        }
        catch (e) {
            worker.log("# Error: " + e.fileName + "\n" + e.name + "\nline: " + e.lineNumber + "\n" + e.message);
        }
    }
}

function parse (sText, sCountry, bDebug, bContext) {
    let aGrammErr = gce.parse(sText, sCountry, bDebug, bContext);
    return JSON.stringify(aGrammErr);
}

function parseAndSpellcheck (sText, sCountry, bDebug, bContext) {
    let aGrammErr = gce.parse(sText, sCountry, bDebug, bContext);
    let aSpellErr = oTokenizer.getSpellingErrors(sText, oDict);
    return JSON.stringify({ aGrammErr: aGrammErr, aSpellErr: aSpellErr });
}

function getOptions () {
    return gce.getOptions().gl_toString();
}

function getDefaultOptions () {
    return gce.getDefaultOptions().gl_toString();
}

function setOptions (sGCOptions) {
    gce.setOptions(helpers.objectToMap(JSON.parse(sGCOptions)));
    return gce.getOptions().gl_toString();
}

function setOption (sOptName, bValue) {
    gce.setOptions(new Map([ [sOptName, bValue] ]));
    return gce.getOptions().gl_toString();
}

function resetOptions () {
    gce.resetOptions();
    return gce.getOptions().gl_toString();
}

function fullTests (sGCOptions="") {
    if (!gce || !oDict) {
        return "# Error: grammar checker or dictionary not loaded."
    }
    let dMemoOptions = gce.getOptions();
    if (sGCOptions) {
        gce.setOptions(helpers.objectToMap(JSON.parse(sGCOptions)));
    }
    let tests = require("resource://grammalecte/tests.js");
    let oTest = new tests.TestGrammarChecking(gce);
    let sAllRes = "";
    for (let sRes of oTest.testParse()) {
        dump(sRes+"\n");
        sAllRes += sRes+"\n";
    }
    gce.setOptions(dMemoOptions);
    return sAllRes;
}


// Lexicographer

function getListOfElements (sText) {
    try {
        let aElem = [];
        let aRes = null;
        for (let oToken of oTokenizer.genTokens(sText)) {
            aRes = oLxg.getInfoForToken(oToken);
            if (aRes) {
                aElem.push(aRes);
            }
        }
        return JSON.stringify(aElem);
    }
    catch (e) {
        helpers.logerror(e);
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































Deleted gc_lang/fr/xpi/locale/en.properties version [d81be224ab].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
mainTitle = Grammalecte [fr]
subTitle = Grammar checker for the French language
noErrorFound = No error detected.
paragraphsParsed = Paragraphs parsed: 
numberOfParagraphs = Number of Paragraphs: 
numberOfWords = Number of words:
error = Oops, an error has occurred. :(
checkText = French grammar checking
buttonTooltip = Grammalecte · French grammar checker
lexicographer = Lexicographer
textFormatter = Text Formatter
website = Web site
conjugueur = Conjugation
general_info = License: GPL 3
useContextMenu = Use the context menu to launch the grammar checker (right click on a text area or on the selected text).
thanks1 = Grammalecte thanks
thanks2 = and all those who supported us…
separator = New text area
testzone = Test Zone
parse = Parse
testall = Parse all
edit_error = Edit error. The proofreader has detected an edition error. The original text hasn’t been modified.

shortcuts = SHORTCUTS
keyTF = CTRL+SHIFT+F6 (on text area)
keyGC = CTRL+SHIFT+F7 (on text area)
keyCJ = CTRL+SHIFT+F8
keyLabelTF = Text Formatter
keyLabelGC = Grammar checking
keyLabelCJ = Conjugation tool

tf_title = Text Formatter
tf_ssp = Supernumerary spaces
tf_start_of_paragraph = At the beginning of paragraph
tf_between_words = Between words
tf_end_of_paragraph = At the end of paragraph
tf_before_punctuation = Before dots (.), commas (,)
tf_within_parenthesis = Within parenthesis
tf_within_square_brackets = Within square brackets
tf_within_quotation_marks = Within “ and ”
tf_space = Missing spaces
tf_add_space_after_punctuation = After , ; : ? ! . …
tf_add_space_around_hyphens = Surrounding dashes
tf_nbsp = Non breaking spaces
tf_nbsp_before_punctuation = Before : ; ? and !
tf_nbsp_within_quotation_marks = With quoting marks « and »
tf_nbsp_before_symbol = Before % ‰ € $ £ ¥ ˚C
tf_nbsp_within_numbers = Within numbers
tf_nbsp_before_units = Before units of measurement
tf_delete = Deletions
tf_erase_non_breaking_hyphens = Soft hyphens
tf_typo = Typographical signs
tf_ts_apostrophe = Apostrophe (’)
tf_ts_ellipsis = Ellipsis (…)
tf_ts_dash_middle = Dashes:
tf_ts_dash_start = Dashes at beginning of paragraph:
tf_emdash = em dash (—)
tf_endash = en dash (–)
tf_ts_quotation_marks = Change quotation marks (" and ')
tf_ts_units = Interpuncts in units (N·m, Ω·m…)
tf_ts_spell = Ligatures (cœur…) and diacritics (ça, État…)
tf_ts_ligature = Ligatures
tf_ts_ligature_do = Set
tf_ts_ligature_undo = Unset
tf_misc = Miscellaneous
tf_ordinals_no_exponant = Ordinals (15e, XXIe…)
tf_ordinals_exponant = e → ᵉ
tf_etc = Et cætera, etc.
tf_missing_hyphens = Missing hyphens
tf_ma_word = Missing apostrophes
tf_ma_1letter_lowercase = single letters (j’ n’ m’ t’ s’ c’ d’ l’)
tf_ma_1letter_uppercase = Cap.
tf_struct = Restructuration [!]
tf_remove_hyphens_at_end_of_paragraphs = Remove syllabification hyphens at EOL/EOP
tf_merge_contiguous_paragraphs = Merge contiguous paragraphs [!]
tf_apply = Apply
tf_default = Default
tf_infomsg = The text formatter is a tool which automates correction of typographical errors. Use this tool with caution. Check your text after use.

options = Options
grammar_options = Grammar options
spelling_options = Spelling options
spelling = Spelling
grammar = Grammar
dictionaries_info = Select dictionaries you want to see in textareas list. Selected dictionaries are added instantly. Whereas unselected dictionnaries will be removed only at Firefox’s restart.
dict_classic = “Classic” (recommended)
dict_classic_descr = This is the “Modern” dictionary plus classical spellings, some of them still widely used, others obsolete. This is the recommended dictionary if French is your native language.
dict_modern = “Modern”
dict_modern_descr = This dictionary offers the French spelling as it is written nowadays most often. This is the recommended dictionary if French is not your mother tongue or if you want only one correct spelling per word.
dict_reform = “Reform 1990”
dict_reform_descr = With this dictionary, only the reformed spelling is recognized. As many of reformed spellings are considered erroneous for many people, this dictionary is unadvised. Reformed spellings commonly used are already included in the “Modern” dictionary.
dict_classic_reform = “All variants”
dict_classic_reform_descr = This dictionary contains all spelling variants, classical and reformed, and some others even rarer. This dictionary is unadvised for those who don’t know very well the French language.
default_options = Reset options
${en}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































Deleted gc_lang/fr/xpi/locale/fr.properties version [a1dfa8a988].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
mainTitle = Grammalecte [fr]
subTitle = Correcteur grammatical pour la langue française
noErrorFound = Aucune erreur détectée.
paragraphsParsed = Paragraphes analysés : 
numberOfParagraphs = Nombre de paragraphes : 
numberOfWords = Nombre de mots :
error = Oups, une erreur s’est produite. :(
checkText = Correction grammaticale [fr]
buttonTooltip = Grammalecte · Correcteur grammatical
lexicographer = Lexicographe
textFormatter = Formateur de texte
website = Site web
conjugueur = Conjugueur
general_info = Licence : GPL 3
useContextMenu = Utilisez le menu contextuel pour lancer le correcteur (clic droit sur une zone de texte ou un texte sélectionné).
thanks1 = Grammalecte remercie
thanks2 = et tous ceux qui l’ont soutenu…
separator = Nouvelle section de texte
testzone = Zone de test
parse = Analyser
testall = Tout tester
edit_error = Erreur d’édition. Le correcteur a repéré une erreur d’édition. Le texte originel n’a pas été modifié.

shortcuts = RACCOURCIS
keyTF = CTRL+MAJ+F6 (sur zone de texte)
keyGC = CTRL+MAJ+F7 (sur zone de texte)
keyCJ = CTRL+MAJ+F8
keyLabelTF = Formateur de texte
keyLabelGC = Correction grammaticale
keyLabelCJ = Conjugueur

tf_title = Formateur de texte
tf_ssp = Espaces surnuméraires
tf_start_of_paragraph = En début de paragraphe
tf_between_words = Entre les mots
tf_end_of_paragraph = En fin de paragraphe
tf_before_punctuation = Avant les points (.), les virgules (,)
tf_within_parenthesis = À l’intérieur des parenthèses
tf_within_square_brackets = À l’intérieur des crochets
tf_within_quotation_marks = À l’intérieur des guillemets “ et ”
tf_space = Espaces manquants
tf_add_space_after_punctuation = Après , ; : ? ! . …
tf_add_space_around_hyphens = Autour des tirets d’incise
tf_nbsp = Espaces insécables
tf_nbsp_before_punctuation = Avant : ; ? et !
tf_nbsp_within_quotation_marks = Avec les guillemets « et »
tf_nbsp_before_symbol = Avant % ‰ € $ £ ¥ ˚C
tf_nbsp_within_numbers = À l’intérieur des nombres
tf_nbsp_before_units = Avant les unités de mesure
tf_delete = Suppressions
tf_erase_non_breaking_hyphens = Tirets conditionnels
tf_typo = Signes typographiques
tf_ts_apostrophe = Apostrophe (’)
tf_ts_ellipsis = Points de suspension (…)
tf_ts_dash_middle = Tirets d’incise :
tf_ts_dash_start = Tirets en début de paragraphe :
tf_emdash = cadratin (—)
tf_endash = demi-cadratin (–)
tf_ts_quotation_marks = Modifier les guillemets droits (" et ')
tf_ts_units = Points médians des unités (N·m, Ω·m…)
tf_ts_spell = Ligatures (cœur…) et diacritiques (ça, État…)
tf_ts_ligature = Ligatures
tf_ts_ligature_do = Faire
tf_ts_ligature_undo = Défaire
tf_misc = Divers
tf_ordinals_no_exponant = Ordinaux (15e, XXIe…)
tf_ordinals_exponant = e → ᵉ
tf_etc = Et cætera, etc.
tf_missing_hyphens = Traits d’union manquants
tf_ma_word = Apostrophes manquantes
tf_ma_1letter_lowercase = lettres isolées (j’ n’ m’ t’ s’ c’ d’ l’)
tf_ma_1letter_uppercase = Maj.
tf_struct = Restructuration [!]
tf_remove_hyphens_at_end_of_paragraphs = Enlever césures en fin de ligne/paragraphe [!]
tf_merge_contiguous_paragraphs = Fusionner les paragraphes contigus [!]
tf_apply = Appliquer
tf_default = Par défaut
tf_infomsg = Le formateur de texte est un outil qui automatise la correction d’erreurs typographiques. Utilisez l’outil avec prudence. Vérifiez votre texte après emploi.


options = Options
grammar_options = Options grammaticales
spelling_options = Options orthographiques
spelling = Orthographe
grammar = Grammaire
dictionaries_info = Cochez les dictionnaires que vous voulez voir apparaître dans la liste des zones de texte. L’ajout des dictionnaires se fait instantanément. En revanche, les dictionnaires ôtés ne disparaîtront qu’au redémarrage de Firefox.
dict_classic = “Classique” (recommandé)
dict_classic_descr = Il s’agit du dictionnaire “Moderne”, avec des graphies classiques en sus, certaines encore communément utilisées, d’autres désuètes. C’est le dictionnaire recommandé si le français est votre langue maternelle.
dict_modern = “Moderne”
dict_modern_descr = Ce dictionnaire propose l’orthographe telle qu’elle est écrite aujourd’hui le plus couramment. C’est le dictionnaire recommandé si le français n’est pas votre langue maternelle ou si vous ne désirez qu’une seule graphie correcte par mot.
dict_reform = “Réforme 1990”
dict_reform_descr = Avec ce dictionnaire, seule l’orthographe réformée est reconnue. Attendu que bon nombre de graphies réformées sont considérées comme erronées par beaucoup, ce dictionnaire est déconseillé. Les graphies passées dans l’usage sont déjà incluses dans le dictionnaire “Moderne”.
dict_classic_reform = “Toutes variantes”
dict_classic_reform_descr = Ce dictionnaire contient les variantes graphiques, classiques, réformées, ainsi que d’autres plus rares encore. Ce dictionnaire est déconseillé à ceux qui ne connaissent pas très bien la langue française.
default_options = Options par défaut
${fr}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































Deleted gc_lang/fr/xpi/package.json version [5d59e1b94f].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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
{
  "name": "grammalecte-fr",
  "title": "Grammalecte [fr]",
  "id": "French-GC@grammalecte.net",
  "version": "0.5.19",
  "description": "Correcteur grammatical pour le français",
  "homepage": "http://www.dicollecte.org/grammalecte",
  "main": "ui.js",
  "icon": "data/img/icon-48.png",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Olivier R.",
  "license": "GPL-3.0 (http://www.gnu.org/licenses/gpl-3.0.html)",
  "engines": {
    "firefox": ">=52.0"
  },
  "unpack": true,
  "permissions": {
    "multiprocess": true,
    "private-browsing": true
  },

  "preferences": [
    {
      "name": "sDictSuggestLocale",
      "title": "*",
      "hidden": true,
      "type": "string",
      "value": "fr-FR-classic"
    },
    {
      "name": "bDictModern",
      "title": "*",
      "hidden": true,
      "type": "bool",
      "value": false
    },
    {
      "name": "bDictClassic",
      "title": "*",
      "hidden": true,
      "type": "bool",
      "value": true
    },
    {
      "name": "bDictReform",
      "title": "*",
      "hidden": true,
      "type": "bool",
      "value": false
    },
    {
      "name": "bDictClassicReform",
      "title": "*",
      "hidden": true,
      "type": "bool",
      "value": false
    },
    {
      "name": "nGCPanelWidth",
      "title": "*",
      "hidden": true,
      "type": "integer",
      "value": 520
    },
    {
      "name": "nGCPanelHeight",
      "title": "*",
      "hidden": true,
      "type": "integer",
      "value": 600
    },
    {
      "name": "nLxgPanelWidth",
      "title": "*",
      "hidden": true,
      "type": "integer",
      "value": 520
    },
    {
      "name": "nLxgPanelHeight",
      "title": "*",
      "hidden": true,
      "type": "integer",
      "value": 500
    },
    {
      "name": "sGCOptions",
      "title": "*",
      "hidden": true,
      "type": "string",
      "value": ""
    },
    {
      "name": "sTFOptions",
      "title": "*",
      "hidden": true,
      "type": "string",
      "value": ""
    }
  ]
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































Deleted gc_lang/fr/xpi/spellchecker.js version [c120dbdcc5].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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
/*
	Hunspell wrapper

	XPCOM obsolete (?), but there is nothing else...
	Overly complicated and weird. To throw away ASAP if possible.

	And you can’t access to this from a PromiseWorker (it sucks).

	https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/mozISpellCheckingEngine
	https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XUL/Using_spell_checking_in_XUL
	https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFile
	https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/FileUtils.jsm
*/

"use strict";


const {Cc, Ci, Cu} = require("chrome");

const FileUtils = Cu.import("resource://gre/modules/FileUtils.jsm").FileUtils;
const AddonManager = Cu.import("resource://gre/modules/AddonManager.jsm").AddonManager;

/*
const parser = Cc["@mozilla.org/parserutils;1"].getService(Ci.nsIParserUtils);
const persodict = Cc["@mozilla.org/spellchecker/personaldictionary;1"].getService(Ci.mozIPersonalDictionary);
*/

const system = require("sdk/system");

const helpers = require("resource://grammalecte/helpers.js");


let xSCEngine = null;


function initSpellChecker () {
	if (xSCEngine === null) {
		try {
			let sSpellchecker = "@mozilla.org/spellchecker/myspell;1";
			if ("@mozilla.org/spellchecker/hunspell;1" in Cc) {
			    sSpellchecker = "@mozilla.org/spellchecker/hunspell;1";
			}
			if ("@mozilla.org/spellchecker/engine;1" in Cc) {
			    sSpellchecker = "@mozilla.org/spellchecker/engine;1";
			}
			xSCEngine = Cc[sSpellchecker].getService(Ci.mozISpellCheckingEngine);
		}
		catch (e) {
			console.error("Can’t initiate the spellchecker.");
			helpers.logerror(e);
		}
	}
}

function getDictionariesList () {
	initSpellChecker();
	try {
		let l = {};
		let c = {};
		xSCEngine.getDictionaryList(l, c);
		return l.value;
	}
	catch (e) {
		helpers.logerror(e);
		return [];
	}
}

function setDictionary (sLocale) {
	if (getDictionariesList().includes(sLocale)) {
		try {
			xSCEngine.dictionary = sLocale; // en-US, fr, etc.
			return true;
		}
		catch (e) {
			helpers.logerror(e);
			return false;
		}
	} else {
		console.error("Warning. No dictionary for locale: " + sLocale);
		console.error("Existing dictionaries: " + getDictionariesList().join(" | "));
	}
	return false;
}

function check (sWord) {
	// todo: check in personal dict?
	try {
		return xSCEngine.check(sWord);
	}
	catch (e) {
		helpers.logerror(e);
		return false;
	}
}

function suggest (sWord) {
	try {
		let lSugg = {};
		xSCEngine.suggest(sWord, lSugg, {});
		return lSugg.value;
	   	// lSugg.value is a JavaScript Array of strings
	}
	catch (e) {
		helpers.logerror(e);
		return ['#Erreur.'];
	}
}

function addDirectory (sFolder) {
	try {
		let xNsiFolder = new FileUtils.File(sFolder);
		xSCEngine.addDirectory(xNsiFolder);
	}
	catch (e) {
		console.error("Unable to add directory: " + sFolder);
		helpers.logerror(e);
	}
}

function removeDirectory (sFolder) {
	// does not work but no exception raised (bug?)
	try {
		let xNsiFolder = new FileUtils.File(sFolder);
		xSCEngine.removeDirectory(xNsiFolder);
	}
	catch (e) {
		console.error("Unable to remove directory: " + sFolder);
		helpers.logerror(e);
	}
}


function setExtensionDictFolder (sDictName, bActivate) {
	try {
		let sPath = "/data/dictionaries/" + sDictName;
		AddonManager.getAddonByID("French-GC@grammalecte.net", function(addon) {
			let xURI = addon.getResourceURI(sPath);
			//console.log("> " + xURI.path);
			let sFolder = xURI.path;
			if (system.platform === "winnt") {
				sFolder = sFolder.slice(1).replace(/\//g, "\\\\");
			}
			//console.log("> " + sFolder);
			if (bActivate) {
				addDirectory(sFolder);
			} else {
				removeDirectory(sFolder);
			}
		});
	}
	catch (e) {
		console.error("Unable to add extension folder");
		helpers.logerror(e);
	}
}


exports.initSpellChecker = initSpellChecker;
exports.getDictionariesList = getDictionariesList;
exports.setDictionary = setDictionary;
exports.check = check;
exports.suggest = suggest;
exports.addDirectory = addDirectory;
exports.removeDirectory = removeDirectory;
exports.setExtensionDictFolder = setExtensionDictFolder;
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































































Deleted gc_lang/fr/xpi/ui.js version [b479190f2b].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
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
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
/*
    GRAMMALECTE [fr] FOR FIREFOX
    Author: Olivier R.
    License: GPL 3
    Website: http://www.dicollecte.org/grammalecte
*/

//// FIREFOX UI

"use strict";


const tabs = require("sdk/tabs");
const toggle = require("sdk/ui/button/toggle");
const panel = require("sdk/panel");
const self = require("sdk/self");
const core = require("sdk/view/core");
const contextmenu = require("sdk/context-menu");
const _ = require("sdk/l10n").get;
const hotkeys = require("sdk/hotkeys");
const sp = require("sdk/simple-prefs");
const clipboard = require("sdk/clipboard");
//const selection = require("sdk/selection");

const { Cu } = require("chrome");
const { BasePromiseWorker } = Cu.import('resource://gre/modules/PromiseWorker.jsm', {});

// Grammalecte
const sce = require("./spellchecker.js");
const text = require("./grammalecte/text.js");
const helpers = require("./grammalecte/helpers.js");
const tests = require("./grammalecte/tests.js");


/*
    Add dictionaries
*/
sce.initSpellChecker();
if (sp.prefs['bDictClassic']) sce.setExtensionDictFolder("fr-FR-classic", true);
if (sp.prefs['bDictModern']) sce.setExtensionDictFolder("fr-FR-modern", true);
if (sp.prefs['bDictReform']) sce.setExtensionDictFolder("fr-FR-reform", true);
if (sp.prefs['bDictClassicReform']) sce.setExtensionDictFolder("fr-FR-classic-reform", true);

function setExtensionDictFolder (sDictOption, bValue) {
    sce.setExtensionDictFolder(sDictOption, bValue);
    switch (sDictOption) {
        case "fr-FR-classic": sp.prefs["bDictClassic"] = bValue; break;
        case "fr-FR-modern": sp.prefs["bDictModern"] = bValue; break;
        case "fr-FR-reform": sp.prefs["bDictReform"] = bValue; break;
        case "fr-FR-classic-reform": sp.prefs["bDictClassicReform"] = bValue; break;
        default: console.error("# Unknown dictionary: " + sDictOption);
    }
    if (sp.prefs["bDictClassic"]) {
        sp.prefs["sDictSuggestLocale"] = "fr-FR-classic";
    } else if (sp.prefs["bDictClassicReform"]) {
        sp.prefs["sDictSuggestLocale"] = "fr-FR-classic-reform";
    } else if (sp.prefs["bDictReform"]) {
        sp.prefs["sDictSuggestLocale"] = "fr-FR-reform";
    } else if (sp.prefs["bDictModern"]) {
        sp.prefs["sDictSuggestLocale"] = "fr-FR-modern";
    } else {
        sp.prefs["sDictSuggestLocale"] = "";
    }
}


/*
    lazy loading
*/
let ibdawg = null   // module: indexable binary direct acyclic word graph
let lxg = null;     // module: lexicographer
let tf = null;      // module: text formatter

let xGCEWorker = null;  // PromiseWorker to get jobs done in a separate thread (it’s 20 times faster too!!!)
let oDict = null;
let oLxg = null;
let oTF = null;


function loadGrammarChecker (bSetPanelOptions=false) {
    if (xGCEWorker === null) {
        // Grammar checker
        xGCEWorker = new BasePromiseWorker('chrome://promiseworker/content/gce_worker.js');
        let xPromise = xGCEWorker.post('loadGrammarChecker', [sp.prefs["sGCOptions"], "Firefox"]);
        xPromise.then(
            function (aVal) {
                sp.prefs["sGCOptions"] = aVal;
                if (bSetPanelOptions) {
                    xAboutPanel.port.emit("sendGrammarOptionsToPanel", aVal);
                }
            },
            function (aReason) {
                console.error('Promise rejected - ', aReason);
            }
        ).catch(
            function (aCaught) {
                console.error('Promise Error - ', aCaught);
            }
        );
    } else if (bSetPanelOptions) {
        xAboutPanel.port.emit("sendGrammarOptionsToPanel", sp.prefs["sGCOptions"]);
    }
    return true;
}

function loadLexicographe () {
    if (ibdawg === null || lxg === null || oDict === null || oLxg === null) {
        lxg = require("./grammalecte/fr/lexicographe.js");
        ibdawg = require("resource://grammalecte/ibdawg.js");
        oDict = new ibdawg.IBDAWG("fr");
        oLxg = new lxg.Lexicographe(oDict);
    }
}

function loadTextFormatter () {
    if (tf === null || oTF === null) {
        tf = require("./grammalecte/fr/textformatter.js");
        oTF = new tf.TextFormatter();
    }
}


/*
    Current state
*/
let xActiveWorker = null;
let bDictActive = false;


/*
    Main Button
*/
const xMainButton = toggle.ToggleButton({
    id: "grammalecte-mainbutton",
    label: _("mainTitle"),
    tooltip: _("buttonTooltip"),
    icon: {
        "16": "./img/icon-16.png",
        "32": "./img/icon-32.png",
        "64": "./img/icon-64.png"
    },
    // Note: it is not possible to distinguish between left/right click
    // https://blog.mozilla.org/addons/2014/03/13/new-add-on-sdk-australis-ui-features-in-firefox-29/comment-page-1/#comment-178621,
    onClick: function (state) {
        createAboutPanel();
        xAboutPanel.show({position: xMainButton});
    }
});


/*
    About
*/

let xAboutPanel = null;

function createAboutPanel () {
    if (xAboutPanel === null) {
        xAboutPanel = panel.Panel({
            contentURL: self.data.url("about_panel.html"),
            contentScriptFile: self.data.url("about_panel.js"),
            onHide: function () {
                xMainButton.state("window", {checked: false});
                xAboutPanel.port.emit("showHelp");
            },
            position: {
                right: 0,
                bottom: 0
            },
            width: 340,
            height: 730
        });

        xAboutPanel.port.emit("calcDefaultPanelHeight");

        xAboutPanel.port.on("setHeight", function (n) {
            xAboutPanel.resize(320, n);
        });

        xAboutPanel.port.on("openConjugueur", function () {
            createConjPanel();
            xConjPanel.show({position: xMainButton});
            xConjPanel.port.emit("conjugate", "être");
        });

        xAboutPanel.port.on("openURL", function (sURL) {
            tabs.open(sURL);
        });

        xAboutPanel.port.on("loadGrammarOptions", function () {
            loadGrammarChecker(true);
        });

        xAboutPanel.port.on("loadSpellingOptions", function () {
            xAboutPanel.port.emit("sendSpellingOptionsToPanel",
                                  sp.prefs["bDictModern"], sp.prefs["bDictClassic"],
                                  sp.prefs["bDictReform"], sp.prefs["bDictClassicReform"]);
        });

        xAboutPanel.port.on("changeDictSetting", function (sDictOption, bValue) {
            setExtensionDictFolder(sDictOption, bValue);
        });

        xAboutPanel.port.on("setOption", function (sOptionId, bValue) {
            let xPromise = xGCEWorker.post('setOption', [sOptionId, bValue]);
            xPromise.then(
                function (aVal) {
                    sp.prefs["sGCOptions"] = aVal;
                },
                function (aReason) {
                    console.error('Promise rejected - ', aReason);
                }
            ).catch(
                function (aCaught) {
                    console.error('Promise Error - ', aCaught);
                }
            );
        });

        xAboutPanel.port.on("resetOptions", function () {
            let xPromise = xGCEWorker.post('resetOptions');
            xPromise.then(
                function (aVal) {
                    sp.prefs["sGCOptions"] = aVal;
                    xAboutPanel.port.emit("sendGrammarOptionsToPanel", sp.prefs["sGCOptions"]);
                },
                function (aReason) {
                    console.error('Promise rejected - ', aReason);
                }
            ).catch(
                function (aCaught) {
                    console.error('Promise Error - ', aCaught);
                }
            );
        });
    }
}


/*
    Grammar Checker
*/

let xGCPanel = null;

function createGCPanel () {
    if (xGCPanel === null) {
        xGCPanel = panel.Panel({
            contentURL: self.data.url("gc_panel.html"),
            contentScriptFile: self.data.url("gc_panel.js"),
            onShow: function () {
                xGCPanel.port.emit("setPanelWidth", sp.prefs["nGCPanelWidth"]);
                if (sp.prefs["sDictSuggestLocale"] !== "") {
                    bDictActive = sce.setDictionary(sp.prefs["sDictSuggestLocale"]);
                }
                if (!bDictActive) {
                    bDictActive = sce.setDictionary("fr"); // default dictionary in French version of Firefox
                }
            },
            onHide: function () {
                xGCPanel.port.emit("clearErrors");
                xGCPanel.resize(sp.prefs["nGCPanelWidth"], sp.prefs["nGCPanelHeight"]);
                xMainButton.state("window", {checked: false});
            },
            //contextMenu: true, /* ugly, look for contextMenuContentData */
            position: {
                right: 0,
                bottom: 0
            },
            width: sp.prefs["nGCPanelWidth"],
            height: sp.prefs["nGCPanelHeight"]
        });

        core.getActiveView(xGCPanel).setAttribute("noautohide", true);
        //core.getActiveView(xGCPanel).setAttribute("backdrag", true);
        //core.getActiveView(xGCPanel).setAttribute("level", 'floating');

        xGCPanel.port.on("closePanel", function () {
            if (xActiveWorker) {
                xActiveWorker.port.emit("clear");
                xActiveWorker = null;
            }
            xGCPanel.hide();
        });

        xGCPanel.port.on("openURL", function (sURL) {
            tabs.open(sURL);
        });

        xGCPanel.port.on("correction", function (sIdParagraph, sText) {
            if (xActiveWorker) {
                xActiveWorker.port.emit("setParagraph", parseInt(sIdParagraph), sText);
                xActiveWorker.port.emit("rewrite");
            }
        });

        xGCPanel.port.on("modifyAndCheck", function (sIdParagraph, sText) {
            if (checkConsistency(sText)) {
                if (xActiveWorker) {
                    xActiveWorker.port.emit("setParagraph", parseInt(sIdParagraph), sText);
                    xActiveWorker.port.emit("rewrite");
                }
                checkAndSendToPanel(sIdParagraph, sText);
            } else {
                if (xActiveWorker) {
                    xActiveWorker.port.emit("getParagraph", parseInt(sIdParagraph));
                }
                xGCPanel.port.emit("showMessage", _("edit_error"));
            }
        });

        xGCPanel.port.on("getSuggestionsForTo", function (sWord, sTooltipId) {
            if (bDictActive) {
                let lSugg = sce.suggest(sWord);
                xGCPanel.port.emit("suggestionsFor", sWord, lSugg.join('|'), sTooltipId);
            } else {
                xGCPanel.port.emit("suggestionsFor", sWord, "# Erreur : dictionnaire orthographique introuvable.", sTooltipId);
            }
        });

        xGCPanel.port.on("copyToClipboard", function (sText) {
            clipboard.set(sText);
        });

        xGCPanel.port.on("resize", function(sCmd, n) {
            if (sCmd == "expand") {
                xGCPanel.resize(sp.prefs["nGCPanelWidth"], sp.prefs["nGCPanelHeight"]);
            } else if (sCmd == "reduce") {
                xGCPanel.resize(280, 50);
            } else {
                switch (sCmd) {
                    case "resize_h_bigger":  if (sp.prefs["nGCPanelHeight"] < 1200) { sp.prefs["nGCPanelHeight"] += n; } break;
                    case "resize_h_smaller": if (sp.prefs["nGCPanelHeight"] > 250)  { sp.prefs["nGCPanelHeight"] -= n } break;
                    case "resize_w_bigger":  if (sp.prefs["nGCPanelWidth"]  < 1200) { sp.prefs["nGCPanelWidth"] += n; } break;
                    case "resize_w_smaller": if (sp.prefs["nGCPanelWidth"]  > 400)  { sp.prefs["nGCPanelWidth"] -= n; } break;
                }
                xGCPanel.resize(sp.prefs["nGCPanelWidth"], sp.prefs["nGCPanelHeight"]);
                xGCPanel.port.emit("setPanelWidth", sp.prefs["nGCPanelWidth"]);
            }
        });
    }
}

function checkConsistency (sText) {
    if (sText.includes("<!-- err_end -->") || sText.includes('<span id="tooltip') || sText.includes('<u id="err')) {
        return false;
    }
    return true;
}

function checkAndSendToPanel (sIdParagraph, sText) {
    let xPromise = xGCEWorker.post('parseAndSpellcheck', [sText, "FR", false, false]);
    xPromise.then(
        function (aVal) {
            xGCPanel.port.emit("refreshParagraph", sText, sIdParagraph, aVal);
        },
        function (aReason) {
            console.error('Promise rejected - ', aReason);
        }
    ).catch(
        function (aCaught) {
            console.error('Promise Error - ', aCaught);
        }
    );
}

const xHotkeyGrammarChecker = hotkeys.Hotkey({
    combo: "accel-shift-f7",
    onPress: function () {
        createGCPanel();
        xActiveWorker = tabs.activeTab.attach({
            contentScriptFile: self.data.url("replace_text.js")
        });
        xActiveWorker.port.emit("setActiveElement", true);
        xActiveWorker.port.on("yesThisIsTextZone", function (sText) {
            if (!xGCPanel.isShowing) {
                xGCPanel.show({position: xMainButton});
            }
            sendTextToPanel(sText);
        });
        xActiveWorker.port.on("emitParagraph", function (iParagraph, sParagraph) {
            checkAndSendToPanel(iParagraph.toString(), sParagraph);
        });
        xActiveWorker.port.on("closeGCPanel", function() {
            xActiveWorker = null;
            xGCPanel.hide();
        });
    }
});

const xHotkeyGC = hotkeys.Hotkey({
    // Quick test
    combo: "accel-shift-f11",
    onPress: function () {
        createGCPanel();
        if (!xGCPanel.isShowing) {
            xGCPanel.show({position: xMainButton});
        }
        xActiveWorker = null;
        sendTextToPanel('"Je" connait ma <i>destinées</i>. Un jour s’attachera à mon nom le souvenir de quelque chose de formidable, '
                      + "- le souvenir d'une crise comme il n'y en eut jamaiss sur terre, le souvenir de la plus profonde collision des consciences, "
                      + "le souvenirs d’un jugement prononcé contre tout tout se qui jusqu’à présent à été cru, exigé, sanctifié. "
                      + "Je ne sui pas un homme, je suis de la dynamite. Et, avec cela, il n’y a en moi rien d’un fondateur de religion. "
                      + "Les religions sont les affaires de la populace. "
                      + "J’aie besoin de me laver les mains, après avoir été en contact avec des hommes religieux...\n"
                      + "Vous, je parie que vous n’appriéciez guère le concept de vidéoprotection. Y a t’il pourtant rien de plus sécurisant ?");
    }
});

async function sendTextToPanel (sText) {
    xGCPanel.port.emit("clearErrors");
    xGCPanel.port.emit("start");
    loadGrammarChecker();
    let iParagraph = 0; // index of paragraphs, used for identification
    let nParagraph = 0; // non empty paragraphs
    let sRes = "";
    try {
        sText = sText.normalize("NFC"); // remove combining diacritics
        for (let sParagraph of text.getParagraph(sText)) {
            if (sParagraph.trim() !== "") {
                sRes = await xGCEWorker.post('parseAndSpellcheck', [sParagraph, "FR", false, false]);
                xGCPanel.port.emit("addParagraph", sParagraph, iParagraph, sRes);
                nParagraph += 1;
            }
            iParagraph += 1;
        }
        xGCPanel.port.emit("addMessage", 'message', _("numberOfParagraphs") + " " + nParagraph);
    }
    catch (e) {
        xGCPanel.port.emit("addMessage", 'bug', e.message);
    }
    xGCPanel.port.emit("end");
}


/*
    Text Formatter
*/

let xTFPanel = null;

function createTFPanel () {
    if (xTFPanel === null) {
        xTFPanel = panel.Panel({
            contentURL: self.data.url("tf_panel.html"),
            contentScriptFile: [self.data.url("tf_panel.js"), self.data.url("../grammalecte/fr/textformatter.js")],
            onShow: function () {
                xTFPanel.port.emit("start", sp.prefs["sTFOptions"]);
            },
            position: {
                bottom: 30,
                right: 30
            },
            width: 800,
            height: 595
        });

        core.getActiveView(xTFPanel).setAttribute("noautohide", true);

        xTFPanel.port.on("setHeight", function (n) {
            xTFPanel.resize(800, n);
        });

        xTFPanel.port.on("saveOptions", function (sOptions) {
            sp.prefs["sTFOptions"] = sOptions;
        });

        xTFPanel.port.on("getTextToFormat", function () {
            if (xActiveWorker) {
                xActiveWorker.port.emit("getText");
            } else {
                xTFPanel.hide();
            }
        });

        xTFPanel.port.on("applyFormattedText", function (sText) {
            if (xActiveWorker) {
                xActiveWorker.port.emit("write", sText);
            } else {
                xTFPanel.hide();
            }
        });

        xTFPanel.port.on("closePanel", function () {
            if (xActiveWorker) {
                xActiveWorker.port.emit("clear");
                xActiveWorker = null;
            }
            xTFPanel.hide();
        });
    }
}

const xHotkeyTextFormatter = hotkeys.Hotkey({
    combo: "accel-shift-f6",
    onPress: function () {
        loadTextFormatter();
        createTFPanel();
        xActiveWorker = tabs.activeTab.attach({
            contentScriptFile: self.data.url("replace_text.js")
        });
        xActiveWorker.port.emit("setActiveElement", false);
        xActiveWorker.port.on("yesThisIsTextZone", function (sText) {
            xTFPanel.show({position: xMainButton});
        });
        xActiveWorker.port.on("emitText", function (sText) {
            xTFPanel.port.emit("receiveTextToFormat", sText);
        });
        xActiveWorker.port.on("closeTFPanel", function() {
            xActiveWorker = null;
            xTFPanel.hide();
        });
    }
});


/*
    Lexicographer
*/

let xLxgPanel = null;

function createLxgPanel () {
    if (xLxgPanel === null) {
        xLxgPanel = panel.Panel({
            contentURL: self.data.url("lxg_panel.html"),
            contentScriptFile: self.data.url("lxg_panel.js"),
            onHide: function () {
                xLxgPanel.port.emit("clear");
                xMainButton.state("window", {checked: false});
            },
            position: {
                bottom: 20,
                right: 30
            },
            width: sp.prefs["nLxgPanelWidth"],
            height: sp.prefs["nLxgPanelHeight"]
        });

        core.getActiveView(xLxgPanel).setAttribute("noautohide", true);

        xLxgPanel.port.on("closePanel", function () {
            xLxgPanel.resize(sp.prefs["nLxgPanelWidth"], sp.prefs["nLxgPanelHeight"]);
            xLxgPanel.hide();
        });

        xLxgPanel.port.on("resize", function(sCmd, n) {
            if (sCmd == "expand") {
                xLxgPanel.resize(sp.prefs["nLxgPanelWidth"], sp.prefs["nLxgPanelHeight"]);
            } else if (sCmd == "reduce") {
                xLxgPanel.resize(280, 50);
            } else {
                switch (sCmd) {
                    case "resize_h_bigger":  if (sp.prefs["nLxgPanelHeight"] < 1200) { sp.prefs["nLxgPanelHeight"] += n; } break;
                    case "resize_h_smaller": if (sp.prefs["nLxgPanelHeight"] > 250)  { sp.prefs["nLxgPanelHeight"] -= n } break;
                    case "resize_w_bigger":  if (sp.prefs["nLxgPanelWidth"]  < 1200) { sp.prefs["nLxgPanelWidth"] += n; } break;
                    case "resize_w_smaller": if (sp.prefs["nLxgPanelWidth"]  > 300)  { sp.prefs["nLxgPanelWidth"] -= n; } break;
                }
                xLxgPanel.resize(sp.prefs["nLxgPanelWidth"], sp.prefs["nLxgPanelHeight"]);
            }
        });
    }
}

async function analyzeWords (sText) {
    xLxgPanel.port.emit("startWaitIcon");
    xLxgPanel.port.emit("addSeparator", _("separator"));
    loadGrammarChecker();
    let nParagraph = 0; // non empty paragraphs
    let sRes = "";
    try {
        for (let sParagraph of text.getParagraph(sText)) {
            if (sParagraph.trim() !== "") {
                sRes = await xGCEWorker.post('getListOfElements', [sParagraph]);
                xLxgPanel.port.emit("addParagraphElems", sRes);
                nParagraph += 1;
            }
        }
        xLxgPanel.port.emit("addMessage", 'message', _("numberOfParagraphs") + " " + nParagraph);
    }
    catch (e) {
        xLxgPanel.port.emit("addMessage", 'bug', e.message);
    }
    xLxgPanel.port.emit("stopWaitIcon");
}


/*
    Conjugueur
*/

let xConjPanel = null;

function createConjPanel () {
    if (xConjPanel === null) {
        let sConjData = self.data.load("../grammalecte/fr/conj_data.json");

        xConjPanel = panel.Panel({
            contentURL: self.data.url("conj_panel.html"),
            contentScriptFile: [self.data.url("conj_panel.js"), self.data.url("../grammalecte/fr/conj.js")],
            onShow: function () {
                xConjPanel.port.emit("start");
            },
            onHide: function () {
                xMainButton.state("window", {checked: false});
            },
            position: {
                bottom: 30,
                right: 30
            },
            width: 550,
            height: 880
        });

        core.getActiveView(xConjPanel).setAttribute("noautohide", true);

        xConjPanel.port.on("show", function () {
            if (!xConjPanel.isShowing) {
                xConjPanel.show({position: xMainButton});
            }
        });

        xConjPanel.port.on("setHeight", function (n) {
            xConjPanel.resize(550, n);
        });

        xConjPanel.port.on("closePanel", function () {
            xConjPanel.hide();
        });

        xConjPanel.port.emit("provideConjData", sConjData);
    }
}

const xHotkeyConj = hotkeys.Hotkey({
    combo: "accel-shift-f8",
    onPress: function () {
        createConjPanel();
        xConjPanel.port.emit("conjugate", "être");
    }
});


/*
    Tests
*/

let xTestPanel = null;

function createTestPanel () {
    if (xTestPanel === null) {
        xTestPanel = panel.Panel({
            contentURL: self.data.url("test_panel.html"),
            contentScriptFile: self.data.url("test_panel.js"),
            onHide: function () {
                xMainButton.state("window", {checked: false});
            },
            position: {
                bottom: 30,
                right: 30
            },
            width: 350,
            height: 700
        });

        core.getActiveView(xTestPanel).setAttribute("noautohide", true);

        xTestPanel.port.on("checkText", function (sText) {
            loadGrammarChecker();
            xTestPanel.port.emit("clear");
            let xPromise = xGCEWorker.post('parse', [sText, "FR", true, false]);
            xPromise.then(
                function (aVal) {
                    let lErr = JSON.parse(aVal);
                    if (lErr.length > 0) {
                        for (let dErr of lErr) {
                            xTestPanel.port.emit("addElem", text.getReadableError(dErr));
                        }
                    } else {
                        xTestPanel.port.emit("addElem", _('noErrorFound'));
                    }
                },
                function (aReason) {
                    xTestPanel.port.emit("addElem", 'Promise rejected');
                    xTestPanel.port.emit("addElem", aReason);
                }
            ).catch(
                function (aCaught) {
                    xTestPanel.port.emit("addElem", 'Promise Error');
                    xTestPanel.port.emit("addElem", aCaught);
                }
            );
        });

        xTestPanel.port.on("allGCTests", function () {
            xTestPanel.port.emit("clear");
            xTestPanel.port.emit("addElem", 'Performing tests… Wait…');
            loadGrammarChecker();
            let xPromise = xGCEWorker.post('fullTests', ['{"nbsp":true, "esp":true, "unit":true, "num":true}']);
            xPromise.then(
                function (aVal) {
                    xTestPanel.port.emit("addElem", 'Done.');
                    xTestPanel.port.emit("addElem", aVal);
                },
                function (aReason) {
                    xTestPanel.port.emit("addElem", 'Promise rejected');
                    xTestPanel.port.emit("addElem", aReason);
                }
            ).catch(
                function (aCaught) {
                    xTestPanel.port.emit("addElem", 'Promise Error');
                    xTestPanel.port.emit("addElem", aCaught);
                }
            )
        });

        xTestPanel.port.on("closePanel", function () {
            xTestPanel.hide();
        });
    }
}

const xHotkeyFullTests = hotkeys.Hotkey({
    combo: "accel-shift-f12",
    onPress: function () {
        createTestPanel();
        xTestPanel.show({position: xMainButton});
    }
});



/*
    Context menu
*/

// Grammar checker
const xMenuItemTextAreaGC = contextmenu.Item ({
    label: _("checkText"),
    image: self.data.url("./img/icon-16.png"),
    contentScript: 'self.on("click", function (node, data) {' +
                   '  self.postMessage(node.value);' +
                   '});',
    accessKey: "g",
    onMessage: function (sText) {
        createGCPanel();
        if (!xGCPanel.isShowing) {
            xGCPanel.show({position: xMainButton});
        } else {
            xGCPanel.port.emit("clearErrors");
        }
        xActiveWorker = tabs.activeTab.attach({
            contentScriptFile: self.data.url("replace_text.js")
        });
        xActiveWorker.port.emit("setActiveElement", false);
        xActiveWorker.port.on("emitParagraph", function (iParagraph, sParagraph) {
            checkAndSendToPanel(iParagraph.toString(), sParagraph);
        });
        xActiveWorker.port.on("closeGCPanel", function() {
            xActiveWorker = null;
            xGCPanel.hide();
        });
        sendTextToPanel(sText);
    }
});

const xMenuItemSelectionGC = contextmenu.Item ({
    label: _("checkText"),
    image: self.data.url("./img/icon-16.png"),
    contentScript: 'self.on("click", function () {' +
                   '  let sText = window.getSelection().toString();' +
                   '  self.postMessage(sText);' +
                   '});',
    accessKey: "g",
    onMessage: function (sText) {
        createGCPanel();
        if (!xGCPanel.isShowing) {
            xGCPanel.show({position: xMainButton});
        } else {
            xGCPanel.port.emit("clearErrors");
        }
        xActiveWorker = null;
        sendTextToPanel(sText);
    }
});

// Text Formatter
const xMenuItemTextFormatter = contextmenu.Item ({
    label: _("textFormatter"),
    image: self.data.url("./img/icon-16.png"),
    context: contextmenu.SelectorContext("textarea"),
    contentScript: 'self.on("click", function (node, data) {' +
                   '  self.postMessage(node.value);' +
                   '});',
    accessKey: "c",
    onMessage: function (sValue) {
        loadTextFormatter();
        createTFPanel();
        xActiveWorker = tabs.activeTab.attach({
            contentScriptFile: self.data.url("replace_text.js")
        });
        xActiveWorker.port.emit("setActiveElement", false);
        xActiveWorker.port.on("emitText", function (sText) {
            xTFPanel.port.emit("receiveTextToFormat", sText);
        });
        xActiveWorker.port.on("closeTFPanel", function() {
            xActiveWorker = null;
            xTFPanel.hide();
        });
        xTFPanel.show({position: xMainButton});
    }
});

// Lexicographer
const xMenuItemSelectionLxg = contextmenu.Item ({
    label: _("lexicographer"),
    image: self.data.url("./img/icon-16.png"),
    contentScript: 'self.on("click", function () {' +
                   '  let sText = window.getSelection().toString();' +
                   '  self.postMessage(sText);' +
                   '});',
    accessKey: "l",
    onMessage: function (sText) {
        createLxgPanel();
        xLxgPanel.show({position: xMainButton});
        analyzeWords(sText);
    }
});

const xMenuItemTextAreaLxg = contextmenu.Item ({
    label: _("lexicographer"),
    image: self.data.url("./img/icon-16.png"),
    contentScript: 'self.on("click", function (node, data) {' +
                   '  self.postMessage(node.value);' +
                   '});',
    accessKey: "l",
    onMessage: function (sText) {
        createLxgPanel();
        xLxgPanel.show({position: xMainButton});
        analyzeWords(sText);
    }
});


// TextArea
const xMenuTextArea = contextmenu.Menu({
    label: "Grammalecte",
    image: self.data.url("./img/icon-16.png"),
    context: contextmenu.SelectorContext("textarea, input[type='text']"),
    accessKey: "g",
    items: [xMenuItemTextAreaGC, xMenuItemTextFormatter, xMenuItemTextAreaLxg]
});

// Selection
const xMenuSelection = contextmenu.Menu({
    label: "Grammalecte",
    image: self.data.url("./img/icon-16.png"),
    context: [contextmenu.SelectionContext(), contextmenu.PredicateContext(function (context) {
        if (context.targetName === "textarea" || context.targetName == "input") {
            return false;
        }
        return true;
    })],
    accessKey: "g",
    items: [xMenuItemSelectionGC, xMenuItemSelectionLxg]
});
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<