Index: gc_core/js/helpers.js
==================================================================
--- gc_core/js/helpers.js
+++ gc_core/js/helpers.js
@@ -72,11 +72,10 @@
// conversions
objectToMap: function (obj) {
let m = new Map();
for (let param in obj) {
- //console.log(param + " " + obj[param]);
m.set(param, obj[param]);
}
return m;
},
Index: gc_lang/fr/build.py
==================================================================
--- gc_lang/fr/build.py
+++ gc_lang/fr/build.py
@@ -31,11 +31,11 @@
sLang = dVars['sDefaultUILang']
for sSection, lOpt in dVars['lStructOpt']:
sHTML += f'\n
\n
{dVars["dOptLabel"][sLang][sSection][0]}
\n'
for lLineOpt in lOpt:
for sOpt in lLineOpt:
- sHTML += f'
\n'
+ sHTML += f'
\n'
sHTML += '
\n'
return sHTML
def createFirefoxExtension (sLang, dVars):
Index: gc_lang/fr/data/phonet_simil.txt
==================================================================
--- gc_lang/fr/data/phonet_simil.txt
+++ gc_lang/fr/data/phonet_simil.txt
@@ -631,10 +631,11 @@
reflux reflue reflues refluent
régal régals régale régale régalent
reine reines renne rennes rêne rênes
relai relais relaie relaies relaient relaye relayes relayent
remblai remblais remblaie remblaies remblaient
+remord remords
renvoi renvois renvoie renvoies renvoient
repaire repaires repère repères repèrent reperds reperd
repli replis replie replies replient
ressenti ressentis ressentit
resserre resserres resserrent ressers ressert
Index: gc_lang/fr/modules-js/conj.js
==================================================================
--- gc_lang/fr/modules-js/conj.js
+++ gc_lang/fr/modules-js/conj.js
@@ -81,18 +81,18 @@
return null;
}
return this._lVtyp[this._dVerb[sVerb][0]];
},
- getSimil: function (sWord, sMorph, sFilter=null) {
+ getSimil: function (sWord, sMorph, bSubst=false) {
if (!sMorph.includes(":V")) {
return new Set();
}
let sInfi = sMorph.slice(1, sMorph.indexOf(" "));
let tTags = this._getTags(sInfi);
let aSugg = new Set();
- if (sMorph.includes(":Q") || sMorph.includes(":Y")) {
+ if (!bSubst) {
// we suggest conjugated forms
if (sMorph.includes(":V1")) {
aSugg.add(sInfi);
aSugg.add(this._getConjWithTags(sInfi, tTags, ":Ip", ":3s"));
aSugg.add(this._getConjWithTags(sInfi, tTags, ":Ip", ":2p"));
@@ -124,13 +124,10 @@
aSugg.delete("");
// if there is only one past participle (epi inv), unreliable.
if (aSugg.size === 1) {
aSugg.clear();
}
- if (sMorph.includes(":V1")) {
- aSugg.add(sInfi);
- }
}
return aSugg;
},
_getTags: function (sVerb) {
@@ -485,16 +482,19 @@
}
// Initialization
if (!conj.bInit && typeof(browser) !== 'undefined') {
- // WebExtension (but not in Worker)
+ // WebExtension Standard (but not in Worker)
conj.init(helpers.loadFile(browser.extension.getURL("grammalecte/fr/conj_data.json")));
+} else if (!conj.bInit && typeof(chrome) !== 'undefined') {
+ // WebExtension Chrome (but not in Worker)
+ conj.init(helpers.loadFile(chrome.extension.getURL("grammalecte/fr/conj_data.json")));
} else if (!conj.bInit && typeof(require) !== 'undefined') {
// Add-on SDK and Thunderbird
conj.init(helpers.loadFile("resource://grammalecte/fr/conj_data.json"));
-} else if ( !conj.bInit && typeof(self) !== 'undefined' && typeof(self.port) !== 'undefined' && typeof(self.port.on) !== "undefined") {
+} else if (!conj.bInit && typeof(self) !== 'undefined' && typeof(self.port) !== 'undefined' && typeof(self.port.on) !== "undefined") {
// used within Firefox content script (conjugation panel).
// can’t load JSON from here, so we do it in ui.js and send it here.
self.port.on("provideConjData", function (sJSONData) {
conj.init(sJSONData);
});
Index: gc_lang/fr/modules-js/gce_suggestions.js
==================================================================
--- gc_lang/fr/modules-js/gce_suggestions.js
+++ gc_lang/fr/modules-js/gce_suggestions.js
@@ -488,16 +488,16 @@
function hasSimil (sWord, sPattern=null) {
return phonet.hasSimil(sWord, sPattern);
}
-function suggSimil (sWord, sPattern) {
+function suggSimil (sWord, sPattern=null, bSubst=false) {
// return list of words phonetically similar to sWord and whom POS is matching sPattern
let aSugg = phonet.selectSimil(sWord, sPattern);
for (let sMorph of _dAnalyses.gl_get(sWord, [])) {
- for (let e of conj.getSimil(sWord, sMorph, sPattern)) {
- aSugg.add(e);
+ for (let e of conj.getSimil(sWord, sMorph, bSubst)) {
+ aSugg.add(e);
}
}
if (aSugg.size > 0) {
return Array.from(aSugg).join("|");
}
Index: gc_lang/fr/modules-js/phonet.js
==================================================================
--- gc_lang/fr/modules-js/phonet.js
+++ gc_lang/fr/modules-js/phonet.js
@@ -64,11 +64,11 @@
}
return [];
},
selectSimil: function (sWord, sPattern) {
- // return list of words phonetically similar to sWord and whom POS is matching sPattern
+ // return a set of words phonetically similar to sWord and whom POS is matching sPattern
if (!sPattern) {
return new Set(this.getSimil(sWord));
}
let aSelect = new Set();
for (let sSimil of this.getSimil(sWord)) {
Index: gc_lang/fr/modules/conj.py
==================================================================
--- gc_lang/fr/modules/conj.py
+++ gc_lang/fr/modules/conj.py
@@ -53,17 +53,18 @@
if sVerb not in _dVerb:
return None
return _lVtyp[_dVerb[sVerb][0]]
-def getSimil (sWord, sMorph, sFilter=None):
+def getSimil (sWord, sMorph, bSubst=False):
if ":V" not in sMorph:
return set()
sInfi = sMorph[1:sMorph.find(" ")]
tTags = _getTags(sInfi)
aSugg = set()
- if ":Q" in sMorph or ":Y" in sMorph:
+ #if ":Q" in sMorph or ":Y" in sMorph:
+ if not bSubst:
# we suggest conjugated forms
if ":V1" in sMorph:
aSugg.add(sInfi)
aSugg.add(_getConjWithTags(sInfi, tTags, ":Ip", ":3s"))
aSugg.add(_getConjWithTags(sInfi, tTags, ":Ip", ":2p"))
@@ -93,12 +94,10 @@
aSugg.add(_getConjWithTags(sInfi, tTags, ":PQ", ":Q4"))
aSugg.discard("")
# if there is only one past participle (epi inv), unreliable.
if len(aSugg) == 1:
aSugg.clear()
- if ":V1" in sMorph:
- aSugg.add(sInfi)
return aSugg
def getConjSimilInfiV1 (sInfi):
if sInfi not in _dVerb:
Index: gc_lang/fr/modules/gce_suggestions.py
==================================================================
--- gc_lang/fr/modules/gce_suggestions.py
+++ gc_lang/fr/modules/gce_suggestions.py
@@ -371,18 +371,17 @@
def hasSimil (sWord, sPattern=None):
return phonet.hasSimil(sWord, sPattern)
-def suggSimil (sWord, sPattern=None):
+def suggSimil (sWord, sPattern=None, bSubst=False):
"return list of words phonetically similar to sWord and whom POS is matching sPattern"
# we don’t check if word exists in _dAnalyses, for it is assumed it has been done before
aSugg = phonet.selectSimil(sWord, sPattern)
for sMorph in _dAnalyses.get(sWord, []):
- for e in conj.getSimil(sWord, sMorph, sPattern):
- aSugg.add(e)
- #aSugg = aSugg.union(conj.getSimil(sWord, sMorph))
+ aSugg.update(conj.getSimil(sWord, sMorph, bSubst))
+ break
if aSugg:
return "|".join(aSugg)
return ""
Index: gc_lang/fr/modules/phonet.py
==================================================================
--- gc_lang/fr/modules/phonet.py
+++ gc_lang/fr/modules/phonet.py
@@ -37,11 +37,11 @@
return _lSet[_dWord[sWord]]
return []
def selectSimil (sWord, sPattern):
- "return list of words phonetically similar to sWord and whom POS is matching sPattern"
+ "return a set of words phonetically similar to sWord and whom POS is matching sPattern"
if not sPattern:
return set(getSimil(sWord))
aSelect = set()
for sSimil in getSimil(sWord):
for sMorph in _dMorph.get(sSimil, []):
Index: gc_lang/fr/oxt/TextFormatter/tf_tabrep.py
==================================================================
--- gc_lang/fr/oxt/TextFormatter/tf_tabrep.py
+++ gc_lang/fr/oxt/TextFormatter/tf_tabrep.py
@@ -370,11 +370,11 @@
("(?<=\\b[XVICL][XVICL][XVICL][XVICL])(i?[èe]me|è|ᵉ)\\b", "e", True, True),
("(?<=\\b[XVICL][XVICL][XVICL])(i?[èe]me|è|ᵉ)\\b", "e", True, True),
("(?<=\\b[XVICL][XVICL])(i?[èe]me|è|ᵉ)\\b", "e", True, True),
("(?<=\\b[XVICL])(i?[èe]me|è|ᵉ)\\b", "e", True, True),
("(?<=\\b[1I])ᵉʳ\\b", "er", True, True),
- ("(?<=\\b[1I])ʳᵉ\\b", "er", True, True)
+ ("(?<=\\b[1I])ʳᵉ\\b", "re", True, True)
],
"misc2": [
("etc(…|[.][.][.]?)", "etc.", True, True),
("(?> =suggSimil(\2, ":[NA].*:[pi]") # Incohérence : les mots “\1” et “\2” ne devraient pas se succéder.
+ <<- -2>> =suggSimil(\2, ":[NA].*:[pi]", True) # Incohérence : les mots “\1” et “\2” ne devraient pas se succéder.
__[s](incohérences_globales2)__
([cC]e(?:tte|t|)|[mtsMTS]a|[mM]on) ([cdlmst]es|[nv]os|cettes?|[mts]a|mon|je|tu|ils?|elle?|[vn]ous|on) @@0,$
- <<- -2>> =suggSimil(\2, ":[NA].*:[si]") # Incohérence : les mots “\1” et “\2” ne devraient pas se succéder.
+ <<- -2>> =suggSimil(\2, ":[NA].*:[si]", True) # Incohérence : les mots “\1” et “\2” ne devraient pas se succéder.
TEST: {{Ces}} {{cette}} canaille qui nous a donné tant de fil à retordre.
TEST: Mon {{il}} est une merveille.
__[s](incohérence_globale_au_qqch)__
([aA]u) ({w2}) @@0,$
<<- not \2.isupper() >>>
<<- morph(\2, ">(?:[cdlmst]es|[nv]os|cettes?|[mts]a|mon|je|tu|ils?|elle?|[vn]ous|on|parce) ", False)
- -2>> =suggSimil(\2, ":[NA].*:[si]") # Incohérence : les mots “\1” et “\2” ne devraient pas se succéder.
+ -2>> =suggSimil(\2, ":[NA].*:[si]", True) # Incohérence : les mots “\1” et “\2” ne devraient pas se succéder.
<<- __else__ and morph(\2, ">quelle ", False) ->> auquel|auxquels|auxquelles # Incohérence. Soudez les deux mots.|https://fr.wiktionary.org/wiki/auquel
<<- __else__ and \2 == "combien" and morph(word(1), ":[AY]", False) -1>> ô # Incohérence probable.|https://fr.wiktionary.org/wiki/%C3%B4_combien
TEST: au {{nos}} enfants.
TEST: {{Au quel}} faut-il s’adresser ?
@@ -2529,11 +2529,11 @@
__[s](incohérence_globale_aux_qqch)__
([aA]ux) ({w2}) @@0,$
<<- not \2.isupper() >>>
<<- morph(\2, ">(?:[cdlmst]es|[nv]os|cettes?|[mts]a|mon|je|tu|ils?|elle?|[vn]ous|on|parce) ", False)
- -2>> =suggSimil(\2, ":[NA].*:[pi]") # Incohérence : les mots “\1” et “\2” ne devraient pas se succéder.
+ -2>> =suggSimil(\2, ":[NA].*:[pi]", True) # Incohérence : les mots “\1” et “\2” ne devraient pas se succéder.
<<- __else__ and morph(\2, ">quelle ", False) ->> auxquels|auxquelles # Incohérence. Soudez les deux mots.|https://fr.wiktionary.org/wiki/auquel
<<- __else__ and \2 == "combien" and morph(word(1), ":[AY]", False) -1>> ô # Incohérence probable.|https://fr.wiktionary.org/wiki/%C3%B4_combien
TEST: ils jouent aux {{des}}.
TEST: {{Aux quels}} a-t-il adressé sa requête. ?
@@ -2540,12 +2540,12 @@
TEST: Des individus {{aux}} combien sensibles aux usages.
__[s](incohérences_globales3)__
([dD]es) ([cdlmst]es|[nv]os|cettes?|[mts]a|mon|je|tu|ils?|elle?|[vn]ous|on) @@0,$
- <<- -2>> =suggSimil(\2, ":[NA].*:[pi]") # Incohérence : les mots “\1” et “\2” ne devraient pas se succéder.
- <<- -1>> de # Incohérence : les mots “\1” et “\2” ne devraient pas se succéder.
+ <<- -2>> =suggSimil(\2, ":[NA].*:[pi]", True) # Incohérence : les mots “\1” et “\2” ne devraient pas se succéder.
+ <<- -1>> de # Incohérence : les mots “\1” et “\2” ne devraient pas se succéder.
TEST: je ne sais {{des}} {{ses}} choses.
@@ -2865,29 +2865,29 @@
TEST: {{en n’}}{{envoient}} que peu.
__[i]/conf(conf_malgré_le_la_les)__
malgré l(?:es? +|a +|’)({w_3}) @@$
- <<- morphex(\1, ":", ":[GNAWM]") -1>> =suggSimil(\1, ":[NA]") # Incohérence : après “malgré”, on devrait trouver un groupe nominal.
+ <<- morphex(\1, ":", ":[GNAWM]") -1>> =suggSimil(\1, ":[NA]", True) # Incohérence : après “malgré”, on devrait trouver un groupe nominal.
TEST: malgré l’{{arrête}} qui interdisait le port
__[i]/conf(conf_ma_ta_cette_verbe)__
([mt]a|cette) +({w_2}) @@0,$
<<- morphex(\2, ":V.*:(?:Y|[123][sp])", ":[NAQ]") and \2[0].islower()
- -2>> =suggSimil(\2, ":[NA]:[fe]:[si]") # Incohérence avec « \1 » : « \2 » est un verbe.
+ -2>> =suggSimil(\2, ":[NA]:[fe]:[si]", True) # Incohérence avec « \1 » : « \2 » est un verbe.
TEST: Cette {{pèle}} est trop fragile.
__[i]/conf(conf_sa_verbe)__
(sa) ({w_2}) @@0,3
<<- morphex(\2, ":V.*:(?:Y|[123][sp])", ":N.*:[fe]|:[AW]") and \2[0].islower() or \2 == "va"
-1>> ça # Confusion : « \2 » est un verbe. Exemples : sa jambe, ça vient.
<<- morphex(\2, ":V.*:(?:Y|[123][sp])", ":[NAQ]") and \2[0].islower() and hasSimil(\2)
- -2>> =suggSimil(\2, ":[NA]:[fe]:[si]") # Incohérence avec « \1 » : « \2 » est un verbe.
+ -2>> =suggSimil(\2, ":[NA]:[fe]:[si]", True) # Incohérence avec « \1 » : « \2 » est un verbe.
TEST: {{sa}} devient difficile.
TEST: il me tendit {{sa}} {{pèche}}.
@@ -2898,67 +2898,67 @@
__[i]/conf(conf_du_cet_au_verbe)__
(du|cet|au) +({w_2}) @@0,$
<<- morphex(\2, ":V.*:(?:Y|[123][sp])", ":[NAQ]") and \2[0].islower() and not (\2 == "sortir" and re.search(r"(?i)au", \1))
- -2>> =suggSimil(\2, ":[NA]:[me]:[si]") # Incohérence avec « \1 » : « \2 » est un verbe.
+ -2>> =suggSimil(\2, ":[NA]:[me]:[si]", True) # Incohérence avec « \1 » : « \2 » est un verbe.
TEST: cet {{plaît}} est infectée.
__[i]/conf(conf_ce_verbe)__
(ce) +(?!faire|peut)({w_2}) @@0,$
<<- morphex(\2, ":V.*:(?:Y|[123][sp])", ":[NAQ]:.:[si]|:V0e.*:3[sp]|>devoir") and \2[0].islower() and hasSimil(\2)
- -2>> =suggSimil(\2, ":[NA]:[me]:[si]") # Incohérence avec « \1 » : « \2 » est un verbe.
+ -2>> =suggSimil(\2, ":[NA]:[me]:[si]", True) # Incohérence avec « \1 » : « \2 » est un verbe.
TEST: {{ce}} {{rappelle}} n’en finit pas.
__[i]/conf(conf_mon_verbe)__
(mon) +({w_2}) @@0,$
<<- morphex(\2, ":V.*:(?:Y|[123][sp])", ":[NAQ]") and \2[0].islower()
- -2>> =suggSimil(\2, ":[NA]:.:[si]") # Incohérence avec « \1 » : « \2 » est un verbe.
+ -2>> =suggSimil(\2, ":[NA]:.:[si]", True) # Incohérence avec « \1 » : « \2 » est un verbe.
TEST: mon {{rackette}} n’a pas porté les fruits espérés.
TEST: Belle qui tient mon vit captif entre tes doigts.
__[i]/conf(conf_ton_son_verbe)__
[st]on ({w_2}) @@4
<<- morph(\1, ":V.*:(?:Y|[123][sp])") and \1[0].islower() and isStart()
- -1>> =suggSimil(\1, ":[NA]:[me]:[si]") # Incohérence : « \1 » est un verbe.
+ -1>> =suggSimil(\1, ":[NA]:[me]:[si]", True) # Incohérence : « \1 » est un verbe.
TEST: ton {{recèle}} a été dévoilé
__[i]/conf(conf_det_plur_verbe)__
([dcmts]es|quelques|aux|[nv]os) +({w_2}) @@0,$
<<- morphex(\2, ":V.*:(?:Y|[123][sp])", ":[NAQ]") and \2[0].islower() and not re.search(r"(?i)^quelques? soi(?:ent|t|s)\b", \0)
- -2>> =suggSimil(\2, ":[NA]:.:[pi]") # Incohérence avec « \1 » : « \2 » est un verbe.
+ -2>> =suggSimil(\2, ":[NA]:.:[pi]", True) # Incohérence avec « \1 » : « \2 » est un verbe.
TEST: la crainte des {{attentas}} fait feu de tout bois.
__[i]/conf(conf_auxdits_verbe)__
(auxdits) +({w_2}) @@0,$
<<- morphex(\2, ":V.*:(?:Y|[123][sp])", ":[NAQ]") and \2[0].islower()
- -2>> =suggSimil(\2, ":[NA]:[me]:[pi]") # Incohérence avec « \1 » : « \2 » est un verbe.
+ -2>> =suggSimil(\2, ":[NA]:[me]:[pi]", True) # Incohérence avec « \1 » : « \2 » est un verbe.
TEST: elle se rendit auxdits {{jardinais}}
__[i]/conf(conf_auxdites_verbe)__
(auxdites) +({w_2}) @@0,$
<<- morphex(\2, ":V.*:(?:Y|[123][sp])", ":[NAQ]") and \2[0].islower()
- -2>> =suggSimil(\2, ":[NA]:[fe]:[pi]") # Incohérence avec « \1 » : « \2 » est un verbe.
+ -2>> =suggSimil(\2, ":[NA]:[fe]:[pi]", True) # Incohérence avec « \1 » : « \2 » est un verbe.
TEST: auxdites {{scelles}}, il ne prêta pas attention.
__[i]/conf(conf_de_la_vconj)__ de la ({w_2}) @@6
<<- morphex(\1, ":[123][sp]", ":[NAQ]")
- -1>> =suggSimil(\1, ":(?:[NA]:[fe]:[si])") # Incohérence : « \1 » est un verbe.
+ -1>> =suggSimil(\1, ":(?:[NA]:[fe]:[si])", True) # Incohérence : « \1 » est un verbe.
TEST: les petits esprits de la {{pensait}} religieuse
TEST: pour les insulter au sortir du seul troquet dispensateur d’oubli liquide du coin
@@ -2966,78 +2966,78 @@
__[i]/conf(conf_de_le_nom_ou_vconj)__
(de le) ({w_2}) @@0,6
<<- morphex(\2, ":[NAQ].*:[me]", ":[YG]") and \2[0].islower() -1>> du # Incohérence : « \2 » est un nom ou un adjectif.
- <<- morph(\2, ":[123][sp]", False) -2>> =suggSimil(\2, ":Y") # Incohérence : « \2 » est une forme verbale conjuguée.
+ <<- morph(\2, ":[123][sp]", False) -2>> =suggVerbInfi(\2) # Incohérence : « \2 » est une forme verbale conjuguée.
TEST: {{de le}} vin ->> du
TEST: il n’est pas interdit de le {{pensait}}
__[i]/conf(conf_de_l_vconj)__
de l’({w_2}) @@5
- <<- morphex(\1, ":[123][sp]", ":[NAQ]") -1>> =suggSimil(\1, ":(?:[NA]:.:[si])") # Incohérence : « \1 » est une forme verbale conjuguée.
+ <<- morphex(\1, ":[123][sp]", ":[NAQ]") -1>> =suggSimil(\1, ":[NA]:.:[si]", True) # Incohérence : « \1 » est une forme verbale conjuguée.
TEST: de l’{{entra}}
__[i]/conf(conf_un_verbe)__
(?> =suggSimil(\1, ":[NAQ]:[me]:[si]") # Incohérence : « \1 » est une forme verbale conjuguée.
+ -1>> =suggSimil(\1, ":[NAQ]:[me]:[si]", True) # Incohérence : « \1 » est une forme verbale conjuguée.
TEST: un {{maintient}} difficile.
__[i]/conf(conf_de_dès_par_vconj)__
(?:d(?:e|ès)|par) ({w_2}) @@$
- <<- \1[0].islower() and morph(\1, ":V.*:[123][sp]") -1>> =suggSimil(\1, ":[NA]") # Incohérence : « \1 » est une forme verbale conjuguée.
+ <<- \1[0].islower() and morph(\1, ":V.*:[123][sp]") -1>> =suggSimil(\1, ":[NA]", True) # Incohérence : « \1 » est une forme verbale conjuguée.
TEST: par {{bloque}} de données
TEST: il s’agit de {{mette}} en évidence.
__[i]/conf(conf_d_une_vconj)__
d’(?:une? +|)({w_2}) @@$
<<- \1[0].islower() and morphex(\1, ":V.*:[123][sp]", ":[GNA]") and not before(r"(?i)\b(?:plus|moins) +$")
- -1>> =suggSimil(\1, ":[NA]") # Incohérence : « \1 » est une forme verbale conjuguée.
+ -1>> =suggSimil(\1, ":[NA]", True) # Incohérence : « \1 » est une forme verbale conjuguée.
TEST: d’une {{habille}} femme
TEST: plus d’un ont été traumatisés
TEST: plus d’une sont parties aussi vite qu’elles étaient venues
__[i]/conf(conf_il_on_pas_verbe)__
(?> =suggSimil(\1, ":(?:3s|Oo)") # Incohérence : « \1 » devrait être un verbe, un pronom objet, un adverbe de négation, etc.
+ -1>> =suggSimil(\1, ":(?:3s|Oo)", False) # Incohérence : « \1 » devrait être un verbe, un pronom objet, un adverbe de négation, etc.
TEST: il {{et}} parti.
__[i]/conf(conf_ils_pas_verbe)__
(?> =suggSimil(\1, ":(?:3p|Oo)") # Incohérence avec « ils » : « \1 » devrait être un verbe, un pronom objet, un adverbe de négation, etc.
+ -1>> =suggSimil(\1, ":(?:3p|Oo)", False) # Incohérence avec « ils » : « \1 » devrait être un verbe, un pronom objet, un adverbe de négation, etc.
TEST: ils {{son}} du même bois.
TEST: Ils {{étai}} partie au {{restaurent}}
__[i]/conf(conf_je_pas_verbe)__
je (?!soussigné)(?:l’|l(?:es?|a|eur|ui) +|[nv]ous +|)({w_2}) @@$
<<- morphex(\1, ":", ":(?:[123][sp]|O[onw]|X)") and morphex(word(-1), ":", ":1s", True)
- -1>> =suggSimil(\1, ":(?:1s|Oo)") # Incohérence avec « je » : « \1 » devrait être un verbe, un pronom objet, un adverbe de négation, etc.
+ -1>> =suggSimil(\1, ":(?:1s|Oo)", False) # Incohérence avec « je » : « \1 » devrait être un verbe, un pronom objet, un adverbe de négation, etc.
TEST: Je {{travail}}.
__[i]/conf(conf_tu_pas_verbe)__
tu (?:l’|l(?:es?|a|eur|ui) +|[nv]ous +|)({w_2}) @@$
<<- morphex(\1, ":", ":(?:[123][sp]|O[onw]|X)") and morphex(word(-1), ":", ":(?:2s|V0e)", True)
- -1>> =suggSimil(\1, ":(?:2s|Oo)") # Incohérence avec « tu » : « \1 » devrait être un verbe, un pronom objet, un adverbe de négation, etc.
+ -1>> =suggSimil(\1, ":(?:2s|Oo)", False) # Incohérence avec « tu » : « \1 » devrait être un verbe, un pronom objet, un adverbe de négation, etc.
TEST: tu {{croix}} que tu sais quelque chose, mais tu ne sais rien.
TEST: elles seules peuvent s’en sortir.
@@ -3064,11 +3064,11 @@
# # Incohérence avec « très » : « \2 » n’est ni un adjectif, ni un participe passé, ni un adverbe.
__[i]/conf(conf_très_verbe)__
très +(?!envie)({w_2}) @@$
- <<- morphex(\1, ":(?:Y|[123][sp])", ":[AQW]") -1>> =suggSimil(\1, ":[AW]") # Incohérence avec « très » : « \1 » n’est ni un adjectif, ni un participe passé, ni un adverbe.
+ <<- morphex(\1, ":(?:Y|[123][sp])", ":[AQW]") -1>> =suggSimil(\1, ":[AW]", True) # Incohérence avec « très » : « \1 » n’est ni un adjectif, ni un participe passé, ni un adverbe.
TEST: Il est très {{cite}}.
TEST: très {{suivit}} par ce détective
TEST: il était très {{habille}}
@@ -3109,11 +3109,11 @@
__[i]/conf(conf_si_vconj)__
si +({w2}) @@$
<<- morphex(\1, ":[123][sp]", ":[GNAQWMT]") and morphex(word(1), ":", ":D", True)
- -1>> =suggSimil(\1, ":[AWGT]") # Incohérence avec « si » : « \1 » ne devrait pas être une forme verbale conjuguée.
+ -1>> =suggSimil(\1, ":[AWGT]", True) # Incohérence avec « si » : « \1 » ne devrait pas être une forme verbale conjuguée.
TEST: Ces gens sont si {{prit}} par leur travail qu’ils en oublient de vivre.
TEST: Ça ira mieux demain, surtout si émerge une demande forte de la part des consommateurs.
@@ -3464,11 +3464,11 @@
__[s]/conf(conf_c_est3)__
([scSC]es) (?:qu(?:lle|el?|)|comme|ce(?:t|tte|)|[nv]os|les?|eux|elles) @@0
<<- -1>> c’est # Confusion probable. Écrivez « c’est » pour dire « ceci est… ».
__[s]/conf(conf_c_est4)__
([scSC]es) ({w_1}) ({w_1}) @@0,w,$
- <<- morph(\2, ":[WX]", False) and morph(\3, ":[RD]|>pire ", False) -1>> c’est # Confusion probable. Écrivez « c’est » pour dire « ceci est… ».
+ <<- morph(\2, ":[WX]", ":N:.*:[pi]") and morph(\3, ":[RD]|>pire ", False) -1>> c’est # Confusion probable. Écrivez « c’est » pour dire « ceci est… ».
__[i]/conf(conf_ces_ses)__
(c’est) ({w_2}) @@0,6 <<- morphex(\2, ":N.*:p", ":(?:G|W|M|A.*:[si])") -1>> ces|ses # Confusion. Exemples : c’est facile ; ces chats (désignation) ; ses chats (possession)…
TEST: {{ses}} au-dessus de ses forces.
TEST: {{ces}} comme la peste
@@ -3475,10 +3475,11 @@
TEST: car {{ses}} d’avance perdu
TEST: {{ces}} qu’il y a tant de pertes
TEST: {{ces}} jamais une bonne idée.
TEST: {{c’est}} {{délires}} nous ennuient
TEST: En 2015, c’est Paris et son agglomération qui…
+TEST: Ses pas de danse.
# date / datte
__[i]/conf(conf_date1)__
dates
@@ -4045,44 +4046,44 @@
__[i](p_m_enfin)__ m’enfin <<- ~>> *
__[i]/conf(conf_j_y_en_qqch)__
(j’(?:en +|y +|))({w_1}) @@0,$
<<- morphex(\2, ":", ":(?:[123][sp]|O[onw])")
- -2>> =suggSimil(\2, ":1s") # Incohérence avec « \1 » : « \2 » devrait être un verbe.
+ -2>> =suggSimil(\2, ":1s", False) # Incohérence avec « \1 » : « \2 » devrait être un verbe.
__[i]/conf(conf_ne_qqch)__
(n(?:e +|’))({w_1}) @@0,$
<<- morphex(\2, ":", ":(?:[123][sp]|Y|P|O[onw]|X)|>(?:[lmtsn]|surtout|guère|presque|même|tout|parfois|vraiment|réellement) ") and not re.search("(?i)-(?:ils?|elles?|[nv]ous|je|tu|on|ce)$", \2)
- -2>> =suggSimil(\2, ":(?:[123][sp]|Oo|Y)") # Incohérence avec « \1 » : « \2 » devrait être un verbe ou un pronom personnel objet.
+ -2>> =suggSimil(\2, ":(?:[123][sp]|Oo|Y)", False) # Incohérence avec « \1 » : « \2 » devrait être un verbe ou un pronom personnel objet.
__[i]/conf(conf_n_y_en_qqch)__
(n’(?:en|y)) ({w_1}) @@0,$
<<- morphex(\2, ":", ":(?:[123][sp]|Y|P|O[onw]|X)") and not re.search("(?i)-(?:ils?|elles?|[nv]ous|je|tu|on|ce)$", \2)
- -2>> =suggSimil(\2, ":(?:[123][sp]|Y)") # Incohérence avec « \1 » : « \2 » devrait être un verbe.
+ -2>> =suggSimil(\2, ":(?:[123][sp]|Y)", False) # Incohérence avec « \1 » : « \2 » devrait être un verbe.
__[i]/conf(conf_ne_pronom_qqch)__
(ne (?:l(?:es? +|eur +|a +|’)|[nv]ous))({w_1}) @@0,$
<<- morphex(\2, ":", ":(?:[123][sp]|Y|P|O[onw]|X)") and not re.search("(?i)-(?:ils?|elles?|[nv]ous|je|tu|on|ce)$", \2)
- -2>> =suggSimil(\2, ":(?:[123][sp]|Y)") # Incohérence avec « \1 » : « \2 » devrait être un verbe.
+ -2>> =suggSimil(\2, ":(?:[123][sp]|Y)", False) # Incohérence avec « \1 » : « \2 » devrait être un verbe.
__[i]/conf(conf_me_te_se_qqch)__
([mts]e +(?:les? |la |l’|))(?!voi(?:là|ci))({w_1}) @@0,$
<<- not re.search("(?i)^se que?", \0)
and morphex(\2, ":", ":(?:[123][sp]|Y|P|Oo)|>[lmts] ") and not re.search("(?i)-(?:ils?|elles?|[nv]ous|je|tu|on|ce)$", \2)
- -2>> =suggSimil(\2, ":(?:[123][sp]|Oo|Y)") # Incohérence avec « \1 » : « \2 » devrait être un verbe ou un pronom personnel objet.
+ -2>> =suggSimil(\2, ":(?:[123][sp]|Oo|Y)", False) # Incohérence avec « \1 » : « \2 » devrait être un verbe ou un pronom personnel objet.
__[i]/conf(conf_m_t_s_y_en_qqch)__
([mts]’(?:en|y)) (?!voilà)({w_1}) @@0,$
<<- morphex(\2, ":", ":(?:[123][sp]|Y|P|Oo)") and not re.search("(?i)-(?:ils?|elles?|[nv]ous|je|tu|on|ce)$", \2)
- -2>> =suggSimil(\2, ":(?:[123][sp]|Y)") # Incohérence avec « \1 » : « \2 » devrait être un verbe.
+ -2>> =suggSimil(\2, ":(?:[123][sp]|Y)", False) # Incohérence avec « \1 » : « \2 » devrait être un verbe.
__[i]/conf(conf_m_s_qqch)__
([ms]’)({w_1}) @@0,2
<<- morphex(\2, ":", ":(?:[123][sp]|Y|P)|>(?:en|y|ils?) ") and not re.search("(?i)-(?:ils?|elles?|[nv]ous|je|tu|on|ce)$", \2)
- -2>> =suggSimil(\2, ":(?:[123][sp]|Y)") # Incohérence avec « \1 » : « \2 » devrait être un verbe.
+ -2>> =suggSimil(\2, ":(?:[123][sp]|Y)", False) # Incohérence avec « \1 » : « \2 » devrait être un verbe.
__[i]/conf(conf_t_qqch)__
(t’)({w_1}) @@0,2
<<- morphex(\2, ":", ":(?:[123][sp]|Y|P)|>(?:en|y|ils?|elles?) ") and not re.search("(?i)-(?:ils?|elles?|[nv]ous|je|tu|on|ce)$", \2)
- -2>> =suggSimil(\2, ":(?:[123][sp]|Y)") # Incohérence avec « \1 » : « \2 » devrait être un verbe.
+ -2>> =suggSimil(\2, ":(?:[123][sp]|Y)", False) # Incohérence avec « \1 » : « \2 » devrait être un verbe.
__[i]/conf(conf_c_ç_qqch)__
([cç]’)({w_1}) @@0,2
<<- morphex(\2, ":", ":[123][sp]|>(?:en|y|que?) ") and not re.search("(?i)-(?:ils?|elles?|[nv]ous|je|tu|on|dire)$", \2)
- -2>> =suggSimil(\2, ":3s") # Incohérence avec « \1 » : « \2 » devrait être un verbe.
+ -2>> =suggSimil(\2, ":3s", False) # Incohérence avec « \1 » : « \2 » devrait être un verbe.
TEST: ne l’{{oubli}} pas
TEST: elle ne la {{croix}} pas
TEST: ils me les {{laissés}}.
TEST: ne {{pensée}} rien, jamais
@@ -4742,10 +4743,11 @@
__[i](p_chili_con_carne)__ chilis? (con carne) @@$ <<- ~1>> *
__[i](p_chef_d_œuvre)__ chefs?(-d’œuvre) @@$ <<- ~1>> *
__[i](p_clair_comme)__ claire?s? (comme (?:de l’eau de (?:boudin|roche|source)|du (?:cristal|jus de (?:boudin|chaussettes?|chique)))) @@$ <<- ~1>> *
__[i](p_commis_d_office)__ commise?s? (d’office) @@$ <<- ~1>> *
__[i](p_convention)__ conventions? (récepteur|générateur) @@$ <<- ~1>> *
+__[i](p_con_comme)__ con(?:ne|)s? (comme (?:un balai|une valise sans poignées?|la lune)) @@$ <<- ~1>> *
__[i](p_coup_de)__
coups? (de (?:balai|bol|cœur|foudre|fil|grâce|jarnac|théâtre|coude|genou|main|p(?:atte|ied|oing|oker|ouce)|tête)|d’(?:avance|éclat|État|œil|épaule)|du sort) @@$
<<- ~1>> *
__[i](p_course_contre_la_montre)__ courses? (contre la montre) @@$ <<- ~1>> *
__[i](p_cousu_main)__ cousue?s? +(main) @@$ <<- ~1>> *
@@ -4819,12 +4821,16 @@
<<- ~1>> *
__[i](p_oiseau_de)__ oiseaux? (de (?:malheur|nuit|proie|mauvais augure)) @@$ <<- ~1>> *
__[i](p_onde_de_choc)__ ondes? (de choc) @@$ <<- ~1>> *
__[i](p_orge)__ orge (perlé|mondé|carré) @@$ <<- ~1>> *
__[i](p_noire_comme)__ noire?s? (comme (?:la nuit|une nuit sans lune)) @@$ <<- ~1>> *
-__[i](p_pièce_de)__ pièces? (de (?:théâtre|monnaie|\d+ (?:euros?|centimes?|cents?|livres? sterling|shillings?))) @@$ <<- ~1>> *
__[i](p_partie_de_jambe_en_l_air)__ parties? (de jambes en l’air) @@$ <<- ~1>> *
+__[i](p_papier_à_lettre)__
+ papiers? (([àa]) lettres?) @@$,w
+ <<- \2 == "a" -2>> à # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
+ <<- ~1>> *
+__[i](p_pièce_de)__ pièces? (de (?:théâtre|monnaie|\d+ (?:euros?|centimes?|cents?|livres? sterling|shillings?))) @@$ <<- ~1>> *
__[i](p_porte_de)__ portes? (de (?:service|garage)) @@$ <<- ~1>> *
__[i](p_poudre_aux_yeux)__ poudres? (aux yeux) @@$ <<- ~1>> *
__[i](p_preuve_du_contraire)__ preuves? +(?:suffisantes? +|)(du contraire) @@$ <<- ~1>> *
__[i](p_quelqu_un_d_autre)__ quelqu un (d’autre) @@$ <<- ~1>> *
__[i](loc_remire_à_plat)__
@@ -4894,10 +4900,11 @@
TEST: cette fille {{a}} papa nous pourrit la vie.
TEST: Les conséquences des gaz {{a}} effet de serre.
TEST: devant la machine {{a}} café.
TEST: Achète un moule {{a}} gaufres.
TEST: Fais la mise {{a}} jour
+TEST: Amenez-moi du papier {{a}} lettres.
TEST: Elle mit du rouge {{a}} lèvres.
TEST: on a besoin d’une remise {{a}} plat.
TEST: passe-moi mon sac {{a}} dos.
TEST: dans le silo {{a}} grain.
TEST: sa chambre, c’est une vraie soue {{a}} cochons.
@@ -5202,11 +5209,11 @@
## Simplication des locutions verbales
__[i](p_donner_sens)__
((?:re|)donn\w+) +(sens) @@0,$
<<- morph(\1, ">(?:re|)donner ", False) ~2>> *
__[i](p_faire_qqch)__
- (f[aiîeo]\w*) +(tous(?: deux| trois|) +|)(allusion|assaut|bonne figure|confiance|compliqué|chaud|débat|demi-tour|fausse route|froid|gr(?:ise mine|and cas)|h(?:alte|onte)|ma(?:chine|rche) arrière|p(?:art(?:ie(?: intégrante|)|)|eur|laisir|rofil bas)|rage|salle comble|sens|table rase|volte-face|ce que bon (?:me|te|lui|leur|nous|vous) semble) @@0,*,$
+ (f[aiîeo]\w*) +(tous(?: deux| trois|) +|)(allusion|assaut|bonne figure|confiance|compliqué|chaud|débat|demi-tour|fausse route|froid|gr(?:ise mine|and cas)|h(?:alte|onte)|illusion|ma(?:chine|rche) arrière|p(?:art(?:ie(?: intégrante|)|)|eur|laisir|rofil bas)|rage|salle comble|sens|table rase|volte-face|ce que bon (?:me|te|lui|leur|nous|vous) semble) @@0,*,$
<<- morph(\1, ">faire ", False) ~2>> *
<<- __also__ ~3>> *
__[i](loc_mettre_à_qqch)__
(m(?:et|[iî][mst])\w*) +(([àa]) (?:jour|niveau|plat|l’écart)) @@0,$,w
<<- morph(\1, ">mettre ", False) >>>
@@ -5227,10 +5234,15 @@
(rest\w+) (lettre morte) @@0,$
<<- morph(\1, ">rester ", False) ~2>> *
__[i](p_sembler_paraitre_être)__
(sembl\w+|par[au]\w+) +(être|avoir été) +({w_2}) @@0,w,$
<<- morph(\1, ">(?:sembler|para[îi]tre) ") and morphex(\3, ":A", ":G") ~2>> *
+__[i](loc_suivre_de_près)__
+ (suiv\w+) +((?:ça +|ce(?:ci|la) +|)de (pr[èé]s?|prêts?)) @@0,$,$
+ <<- morph(\1, ">suivre ", False) >>>
+ <<- \3 != "près" -3>> près # Confusion : écrivez “près” pour dire “proche de quelque chose”.|https://fr.wiktionary.org/wiki/pr%C3%A8s
+ <<- ~2>> *
__[i](loc_tenir_à_distance)__
(t[eiî]\w+) +(([àa]) distance) d(?:es?|u) @@0,$,w
<<- morph(\1, ">tenir ", False) >>>
<<- \3 == "a" -3>> à # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
<<- ~2>> *
@@ -5245,10 +5257,11 @@
(v[eiî]\w+) ((?:on ne sait|je ne sais) (?:pas |)(?:trop |)d’où) @@0,$
<<- morph(\1, ">venir ", False) ~2>> *
TEST: il faut tenir {{contes}} des faits au lieu de nos impressions.
TEST: prendre {{a}} la légère ce test serait une erreur.
+TEST: on va suivre ça de {{prêt}}.
TEST: il faut se tenir {{a}} distance de ces gens-là.
# Autres tests contre les faux positifs
TEST: pourquoi faire compliqué quand on peut faire simple
@@ -5309,11 +5322,11 @@
TEST: ce que c’est : le signe évident d’une politique volontaire
TEST: On aura carte blanche.
TEST: La seule façon de redonner sens à des notions…
TEST: Les longues tresses que j’ai pris l’habitude de porter depuis quelque temps et qu’il faut cinq heures pour parfaire.
TEST: Il est pieds nus.
-TEST: des dossiers secrets {{défense}}
+TEST: des dossiers secrets défense
#
# //////////////////////////////////////// RÈGLES DE CONTRÔLE ////////////////////////////////////////
#
@@ -11462,31 +11475,31 @@
__[i]/inte(inte_je)__
({w1})-je @@0
<<- morphex(\1, ":V", ":1[sśŝ]") -1>> =suggVerb(@, ":1ś") # Forme interrogative : « \1 » n’est pas un verbe à la 1ʳᵉ personne du singulier.
- <<- not morph(\1, ":V", False) -1>> =suggSimil(\1, ":1[sśŝ]") # Forme interrogative : « \1 » n’est pas un verbe à la 1ʳᵉ personne du singulier.
+ <<- not morph(\1, ":V", False) -1>> =suggSimil(\1, ":1[sśŝ]", False) # Forme interrogative : « \1 » n’est pas un verbe à la 1ʳᵉ personne du singulier.
TEST: {{Vas}}-je ->> Vais
TEST: {{Prit}}-je ->> Pris
TEST: {{prix}}-je le temps d’y parvenir ? Oui.
__[i]/inte(inte_tu)__
({w1})-tu @@0
<<- morphex(\1, ":V", ":[ISK].*:2s") -1>> =suggVerb(@, ":2s") # Forme interrogative. « \1 » n’est pas un verbe à la 2ᵉ personne du singulier.
- <<- not morph(\1, ":V", False) -1>> =suggSimil(\1, ":2s") # Forme interrogative : « \1 » n’est pas un verbe à la 2ᵉ personne du singulier.
+ <<- not morph(\1, ":V", False) -1>> =suggSimil(\1, ":2s", False) # Forme interrogative : « \1 » n’est pas un verbe à la 2ᵉ personne du singulier.
TEST: {{Peut}}-tu ->> Peux
TEST: {{peu}}-tu revenir chez moi ?
__[i]/inte(inte_il_elle_on)__
({w1})-(?:t-|)(il|elle|on) @@0,$
<<- morphex(\1, ":V", ":3s") -1>> =suggVerb(@, ":3s") # Forme interrogative : « \1 » n’est pas un verbe à la 3ᵉ personne du singulier.
<<- \1 != "t" and (not \1.endswith("oilà") or \2 != "il") and morphex(\1, ":", ":V")
- -1>> =suggSimil(\1, ":3s") # Forme interrogative : « \1 » n’est pas un verbe à la 3ᵉ personne du singulier.
+ -1>> =suggSimil(\1, ":3s", False) # Forme interrogative : « \1 » n’est pas un verbe à la 3ᵉ personne du singulier.
<<- not \2.endswith(("n", "N")) and morphex(\1, ":3p", ":3s") -2>> \2s # Forme interrogative : accordez “\2” avec le verbe à la 3ᵉ personne du pluriel.
TEST: {{Peux}}-il ->> Peut
TEST: {{Attaques}}-t-on ->> Attaque
TEST: {{Prends}}-elle ->> Prend
@@ -11496,11 +11509,11 @@
__[s]/inte(inte_ce)__
({w_2})-([cs]e) @@0,$
<<- morphex(\1, ":V", ":(?:3s|V0e.*:3p)") -1>> =suggVerb(@, ":3s") # Forme interrogative : « \1 » n’est pas un verbe à la 3ᵉ personne du singulier.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=4132
- <<- morphex(\1, ":", ":V") -1>> =suggSimil(\1, ":3s") # Forme interrogative : « \1 » n’est pas un verbe à la 3ᵉ personne du singulier.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=4132
+ <<- morphex(\1, ":", ":V") -1>> =suggSimil(\1, ":3s", False) # Forme interrogative : « \1 » n’est pas un verbe à la 3ᵉ personne du singulier.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=4132
<<- \2 == "se" -2>> ce # Forme interrogative. Confusion.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=4132
TEST: était-{{se}} cela, la vérité ineffable ?
TEST: {{étai}}-ce notre destinée de souffrir ?
TEST: étaient-{{se}} ces hommes-là qui allaient nous guider dans les montagnes ?
@@ -11509,20 +11522,20 @@
__[i]/inte(inte_nous)__
({w1})-nous @@0
<<- morphex(\1, ":V", ":(?:1p|E:2[sp])") -1>> =suggVerb(@, ":1p") # Forme interrogative ou impérative incorrecte.
- <<- morphex(\1, ":", ":V|>chez ") -1>> =suggSimil(\1, ":1p") # Forme interrogative ou impérative incorrecte.
+ <<- morphex(\1, ":", ":V|>chez ") -1>> =suggSimil(\1, ":1p", False) # Forme interrogative ou impérative incorrecte.
TEST: {{Prendront}}-nous ->> Prendrons
TEST: {{Attendront}}-nous le train ->> Attendrons
__[i]/inte(inte_vous)__
({w1})-vous @@0
<<- morphex(\1, ":V", ":2p") -1>> =suggVerb(@, ":2p") # Forme interrogative ou impérative incorrecte.
- <<- not morph(\1, ":V|>chez ", False) -1>> =suggSimil(\1, ":2p") # Forme interrogative ou impérative incorrecte.
+ <<- not morph(\1, ":V|>chez ", False) -1>> =suggSimil(\1, ":2p", False) # Forme interrogative ou impérative incorrecte.
TEST: {{Attaquait}}-vous ->> Attaquiez
TEST: Elle a de nombreux rendez-vous ce matin.
TEST: êtes-vous là ?
@@ -11530,11 +11543,11 @@
__[i]/inte(inte_ils_elles)__
({w1})-(?:ils|elles) @@0
<<- morphex(\1, ":V", ":3p") and spell(\1)
-1>> =suggVerb(@, ":3p") # Forme interrogative : « \1 » n’est pas un verbe à la 3ᵉ personne du pluriel.
<<- \1 != "t" and not morph(\1, ":V", False) and spell(\1)
- -1>> =suggSimil(\1, ":3p") # Forme interrogative : « \1 » n’est pas un verbe à la 3ᵉ personne du pluriel.
+ -1>> =suggSimil(\1, ":3p", False) # Forme interrogative : « \1 » n’est pas un verbe à la 3ᵉ personne du pluriel.
TEST: {{attaquant}}-ils ->> attaquent
TEST: {{prendrons}}-elles un verre avec moi ?
Index: gc_lang/fr/webext/background.js
==================================================================
--- gc_lang/fr/webext/background.js
+++ gc_lang/fr/webext/background.js
@@ -5,10 +5,18 @@
function showError (e) {
console.error(e.fileName + "\n" + e.name + "\nline: " + e.lineNumber + "\n" + e.message);
}
+// Chrome don’t follow the W3C specification:
+// https://browserext.github.io/browserext/
+let bChrome = false;
+if (typeof(browser) !== "object") {
+ var browser = chrome;
+ bChrome = true;
+}
+
/*
Worker (separate thread to avoid freezing Firefox)
*/
let xGCEWorker = new Worker("gce_worker.js");
@@ -17,11 +25,11 @@
// https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent
try {
let {sActionDone, result, dInfo} = e.data;
switch (sActionDone) {
case "init":
- browser.storage.local.set({"gc_options": result});
+ storeGCOptions(result);
break;
case "parse":
case "parseAndSpellcheck":
case "parseAndSpellcheck1":
case "getListOfTokens":
@@ -42,16 +50,19 @@
break;
case "getOptions":
case "getDefaultOptions":
case "resetOptions":
// send result to panel
+ storeGCOptions(result);
+ if (bChrome) {
+ e.data.result = helpers.mapToObject(e.data.result);
+ }
browser.runtime.sendMessage(e.data);
- browser.storage.local.set({"gc_options": result});
break;
case "setOptions":
case "setOption":
- browser.storage.local.set({"gc_options": result});
+ storeGCOptions(result);
break;
default:
console.log("[background] Unknown command: " + sActionDone);
console.log(e.data);
}
@@ -59,22 +70,27 @@
catch (e) {
showError(e);
}
};
+function initGrammarChecker (dSavedOptions) {
+ let dOptions = (dSavedOptions.hasOwnProperty("gc_options")) ? dSavedOptions.gc_options : null;
+ xGCEWorker.postMessage({
+ sCommand: "init",
+ dParam: {sExtensionPath: browser.extension.getURL(""), dOptions: dOptions, sContext: "Firefox"},
+ dInfo: {}
+ });
+}
function init () {
+ if (bChrome) {
+ browser.storage.local.get("gc_options", initGrammarChecker);
+ return;
+ }
let xPromise = browser.storage.local.get("gc_options");
xPromise.then(
- function (dSavedOptions) {
- let dOptions = (dSavedOptions.hasOwnProperty("gc_options")) ? dSavedOptions.gc_options : null;
- xGCEWorker.postMessage({
- sCommand: "init",
- dParam: {sExtensionPath: browser.extension.getURL("."), dOptions: dOptions, sContext: "Firefox"},
- dInfo: {}
- });
- },
+ initGrammarChecker,
function (e) {
showError(e);
xGCEWorker.postMessage({
sCommand: "init",
dParam: {sExtensionPath: browser.extension.getURL("."), dOptions: null, sContext: "Firefox"},
@@ -247,10 +263,19 @@
/*
Actions
*/
+
+function storeGCOptions (dOptions) {
+ if (bChrome) {
+ // JS crap again. Chrome can’t store Map object.
+ dOptions = helpers.mapToObject(dOptions);
+ }
+ browser.storage.local.set({"gc_options": dOptions});
+}
+
function parseAndSpellcheckSelectedText (iTab, sText) {
// send message to the tab
let xTabPort = dConnx.get(iTab);
xTabPort.postMessage({sActionDone: "openGCPanel", result: null, dInfo: null, bEnd: false, bError: false});
// send command to the worker
@@ -272,20 +297,35 @@
dInfo: {iReturnPort: iTab}
});
}
function openConjugueurTab () {
+ if (bChrome) {
+ browser.tabs.create({
+ url: browser.extension.getURL("panel/conjugueur.html")
+ });
+ return;
+ }
let xConjTab = browser.tabs.create({
url: browser.extension.getURL("panel/conjugueur.html")
});
xConjTab.then(onCreated, onError);
}
function openConjugueurWindow () {
+ if (bChrome) {
+ browser.windows.create({
+ url: browser.extension.getURL("panel/conjugueur.html"),
+ type: "popup",
+ width: 710,
+ height: 980
+ });
+ return;
+ }
let xConjWindow = browser.windows.create({
url: browser.extension.getURL("panel/conjugueur.html"),
- type: "detached_panel",
+ type: "popup",
width: 710,
height: 980
});
xConjWindow.then(onCreated, onError);
}
Index: gc_lang/fr/webext/content_scripts/init.js
==================================================================
--- gc_lang/fr/webext/content_scripts/init.js
+++ gc_lang/fr/webext/content_scripts/init.js
@@ -12,23 +12,18 @@
function showError (e) {
console.error(e.fileName + "\n" + e.name + "\nline: " + e.lineNumber + "\n" + e.message);
}
-function createNode (sType, oAttr, oDataset=null) {
- try {
- let xNode = document.createElement(sType);
- Object.assign(xNode, oAttr);
- if (oDataset) {
- Object.assign(xNode.dataset, oDataset);
- }
- return xNode;
- }
- catch (e) {
- showError(e);
- }
-}
+// Chrome don’t follow the W3C specification:
+// https://browserext.github.io/browserext/
+let bChrome = false;
+if (typeof(browser) !== "object") {
+ var browser = chrome;
+ bChrome = true;
+}
+
/*
function loadImage (sContainerClass, sImagePath) {
let xRequest = new XMLHttpRequest();
xRequest.open('GET', browser.extension.getURL("")+sImagePath, false);
@@ -53,12 +48,14 @@
oGCPanel: null,
createMenus: function () {
let lNode = document.getElementsByTagName("textarea");
for (let xNode of lNode) {
- this.lMenu.push(new GrammalecteMenu(this.nMenu, xNode));
- this.nMenu += 1;
+ if (xNode.style.display !== "none" && xNode.style.visibility !== "hidden") {
+ this.lMenu.push(new GrammalecteMenu(this.nMenu, xNode));
+ this.nMenu += 1;
+ }
}
},
createMenus2 () {
let lNode = document.querySelectorAll("[contenteditable]");
@@ -98,10 +95,24 @@
createGCPanel: function () {
if (this.oGCPanel === null) {
this.oGCPanel = new GrammalecteGrammarChecker("grammalecte_gc_panel", "Grammalecte", 500, 700);
this.oGCPanel.insertIntoPage();
}
+ },
+
+ createNode: function (sType, oAttr, oDataset=null) {
+ try {
+ let xNode = document.createElement(sType);
+ Object.assign(xNode, oAttr);
+ if (oDataset) {
+ Object.assign(xNode.dataset, oDataset);
+ }
+ return xNode;
+ }
+ catch (e) {
+ showError(e);
+ }
}
}
/*
Index: gc_lang/fr/webext/content_scripts/menu.css
==================================================================
--- gc_lang/fr/webext/content_scripts/menu.css
+++ gc_lang/fr/webext/content_scripts/menu.css
@@ -18,11 +18,11 @@
border-radius: 50%;
text-align: center;
cursor: pointer;
box-shadow: 0 0 0 0 hsla(210, 50%, 50%, .5);
z-index: 2147483640; /* maximum is 2147483647: https://stackoverflow.com/questions/491052/minimum-and-maximum-value-of-z-index */
- animation: grammalecte-spin 2s ease infinite;
+ animation: grammalecte-spin 2s ease 3;
}
.grammalecte_menu_main_button:hover {
border: 4px solid hsla(210, 80%, 35%, .5);
background-color: hsla(210, 80%, 55%, .5);
animation: grammalecte-spin .5s linear infinite;
Index: gc_lang/fr/webext/content_scripts/menu.js
==================================================================
--- gc_lang/fr/webext/content_scripts/menu.js
+++ gc_lang/fr/webext/content_scripts/menu.js
@@ -5,11 +5,11 @@
class GrammalecteMenu {
constructor (nMenu, xNode) {
this.sMenuId = "grammalecte_menu" + nMenu;
- this.xButton = createNode("div", {className: "grammalecte_menu_main_button", textContent: " "});
+ this.xButton = oGrammalecte.createNode("div", {className: "grammalecte_menu_main_button", textContent: " "});
this.xButton.onclick = () => { this.switchMenu(); };
this.xMenu = this._createMenu(xNode);
this._insertAfter(this.xButton, xNode);
this._insertAfter(this.xMenu, xNode);
}
@@ -19,25 +19,25 @@
}
_createMenu (xNode) {
try {
let sText = (xNode.tagName == "TEXTAREA") ? xNode.value : xNode.textContent;
- let xMenu = createNode("div", {id: this.sMenuId, className: "grammalecte_menu"});
- xMenu.appendChild(createNode("div", {className: "grammalecte_menu_header", textContent: "GRAMMALECTE"}));
+ let xMenu = oGrammalecte.createNode("div", {id: this.sMenuId, className: "grammalecte_menu"});
+ xMenu.appendChild(oGrammalecte.createNode("div", {className: "grammalecte_menu_header", textContent: "GRAMMALECTE"}));
// Text formatter
if (xNode.tagName == "TEXTAREA") {
- let xTFButton = createNode("div", {className: "grammalecte_menu_item", textContent: "Formateur de texte"});
+ let xTFButton = oGrammalecte.createNode("div", {className: "grammalecte_menu_item", textContent: "Formateur de texte"});
xTFButton.onclick = () => {
this.switchMenu();
oGrammalecte.createTFPanel();
oGrammalecte.oTFPanel.start(xNode);
oGrammalecte.oTFPanel.show();
};
xMenu.appendChild(xTFButton);
}
// lexicographe
- let xLxgButton = createNode("div", {className: "grammalecte_menu_item", textContent: "Lexicographe"});
+ let xLxgButton = oGrammalecte.createNode("div", {className: "grammalecte_menu_item", textContent: "Lexicographe"});
xLxgButton.onclick = () => {
this.switchMenu();
oGrammalecte.createLxgPanel();
oGrammalecte.oLxgPanel.clear();
oGrammalecte.oLxgPanel.show();
@@ -48,11 +48,11 @@
dInfo: {sTextAreaId: xNode.id}
});
};
xMenu.appendChild(xLxgButton);
// Grammar checker
- let xGCButton = createNode("div", {className: "grammalecte_menu_item", textContent: "Correction grammaticale"});
+ let xGCButton = oGrammalecte.createNode("div", {className: "grammalecte_menu_item", textContent: "Correction grammaticale"});
xGCButton.onclick = () => {
this.switchMenu();
oGrammalecte.createGCPanel();
oGrammalecte.oGCPanel.start(xNode);
oGrammalecte.oGCPanel.show();
@@ -63,27 +63,27 @@
dInfo: {sTextAreaId: xNode.id}
});
};
xMenu.appendChild(xGCButton);
// Conjugation tool
- let xConjButton = createNode("div", {className: "grammalecte_menu_item_block", textContent: "Conjugueur"});
- let xConjButtonTab = createNode("div", {className: "grammalecte_menu_button", textContent: "Onglet"});
+ let xConjButton = oGrammalecte.createNode("div", {className: "grammalecte_menu_item_block", textContent: "Conjugueur"});
+ let xConjButtonTab = oGrammalecte.createNode("div", {className: "grammalecte_menu_button", textContent: "Onglet"});
xConjButtonTab.onclick = () => {
this.switchMenu();
xGrammalectePort.postMessage({sCommand: "openConjugueurTab", dParam: null, dInfo: null});
};
- let xConjButtonWin = createNode("div", {className: "grammalecte_menu_button", textContent: "Fenêtre"});
+ let xConjButtonWin = oGrammalecte.createNode("div", {className: "grammalecte_menu_button", textContent: "Fenêtre"});
xConjButtonWin.onclick = () => {
this.switchMenu();
xGrammalectePort.postMessage({sCommand: "openConjugueurWindow", dParam: null, dInfo: null});
};
xConjButton.appendChild(xConjButtonTab);
xConjButton.appendChild(xConjButtonWin);
xMenu.appendChild(xConjButton);
- //xMenu.appendChild(createNode("img", {scr: browser.extension.getURL("img/logo-16.png")}));
+ //xMenu.appendChild(oGrammalecte.createNode("img", {scr: browser.extension.getURL("img/logo-16.png")}));
// can’t work, due to content-script policy: https://bugzilla.mozilla.org/show_bug.cgi?id=1267027
- xMenu.appendChild(createNode("div", {className: "grammalecte_menu_footer"}));
+ xMenu.appendChild(oGrammalecte.createNode("div", {className: "grammalecte_menu_footer"}));
return xMenu;
}
catch (e) {
showError(e);
}
Index: gc_lang/fr/webext/content_scripts/panel.css
==================================================================
--- gc_lang/fr/webext/content_scripts/panel.css
+++ gc_lang/fr/webext/content_scripts/panel.css
@@ -94,40 +94,44 @@
overflow: auto;
}
/*
- CSS Spinner
- Double bounce
- http://tobiasahlin.com/spinkit/
+ Spinner
*/
.grammalecte_spinner {
visibility: hidden;
- width: 40px;
- height: 40px;
- position: absolute;
- top: 2px;
- right: 180px;
-}
-.grammalecte_spinner .bounce1,
-.grammalecte_spinner .bounce2 {
- width: 100%;
- height: 100%;
- border-radius: 50%;
- background-color: hsl(0, 50%, 75%);
- opacity: 0.6;
- position: absolute;
- top: 0;
- left: 0;
- animation: grammalecte-sk-bounce 2.0s infinite ease-in-out;
-}
-.grammalecte_spinner .bounce2 {
- animation-delay: -1.0s;
-}
-
-@keyframes grammalecte-sk-bounce {
- 0%, 100% {
- transform: scale(0.0);
- } 50% {
- transform: scale(1.0);
+ width: 20px;
+ height: 20px;
+ position: absolute;
+ top: 0px;
+ right: 200px;
+ background-color: hsla(210, 80%, 80%, .5);
+ border: 10px solid hsla(210, 80%, 60%, .5);
+ border-top: 10px solid hsla(210, 100%, 40%, .7);
+ border-bottom: 10px solid hsla(210, 100%, 40%, .7);
+ border-radius: 50%;
+ text-align: center;
+ cursor: pointer;
+ box-shadow: 0 0 0 0 hsla(210, 50%, 50%, .5);
+ animation: grammalecte-spin-big .5s linear infinite;
+}
+
+@keyframes grammalecte-spin-big {
+ 0% {
+ transform: rotate(0deg) scale(1);
+ border-top: 10px solid hsla(210, 100%, 40%, .7);
+ border-bottom: 10px solid hsla(210, 100%, 40%, .7);
+ }
+ 70% {
+ transform: rotate(180deg) scale(.8);
+ border-top: 10px solid hsla(0, 100%, 40%, .7);
+ border-bottom: 10px solid hsla(0, 100%, 40%, .7);
+ box-shadow: 0 0 0 20px hsla(210, 50%, 50%, 0);
+ }
+ 100% {
+ transform: rotate(360deg) scale(1);
+ border-top: 10px solid hsla(210, 100%, 40%, .7);
+ border-bottom: 10px solid hsla(210, 100%, 40%, .7);
+ box-shadow: 0 0 0 0 hsla(210, 50%, 50%, 0);
}
}
Index: gc_lang/fr/webext/content_scripts/panel.js
==================================================================
--- gc_lang/fr/webext/content_scripts/panel.js
+++ gc_lang/fr/webext/content_scripts/panel.js
@@ -9,24 +9,24 @@
constructor (sId, sTitle, nWidth, nHeight, bFlexible=true) {
this.sId = sId;
this.nWidth = nWidth;
this.nHeight = nHeight;
this.bFlexible = bFlexible;
- this.xPanelBar = createNode("div", {className: "grammalecte_panel_bar"});
- this.xPanelContent = createNode("div", {className: "grammalecte_panel_content"});
+ this.xPanelBar = oGrammalecte.createNode("div", {className: "grammalecte_panel_bar"});
+ this.xPanelContent = oGrammalecte.createNode("div", {className: "grammalecte_panel_content"});
this.xWaitIcon = this._createWaitIcon();
this.xPanel = this._createPanel(sTitle);
this.center();
}
_createPanel (sTitle) {
try {
- let xPanel = createNode("div", {id: this.sId, className: "grammalecte_panel"});
+ let xPanel = oGrammalecte.createNode("div", {id: this.sId, className: "grammalecte_panel"});
this.xPanelBar.appendChild(this._createButtons());
- let xTitle = createNode("div", {className: "grammalecte_panel_title"});
+ let xTitle = oGrammalecte.createNode("div", {className: "grammalecte_panel_title"});
xTitle.appendChild(this._createLogo());
- xTitle.appendChild(createNode("div", {className: "grammalecte_panel_label", textContent: sTitle}));
+ xTitle.appendChild(oGrammalecte.createNode("div", {className: "grammalecte_panel_label", textContent: sTitle}));
this.xPanelBar.appendChild(xTitle);
xPanel.appendChild(this.xPanelBar);
xPanel.appendChild(this.xPanelContent);
return xPanel;
}
@@ -40,11 +40,11 @@
xImg.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAC8UlEQVQ4jX3TbUgTcRwH8P89ddu5u9tt082aZmpFEU4tFz0QGTUwCi0heniR9MSUIKRaD0RvIlKigsooo+iNFa0XJYuwIjEK19OcDtPElsG0ktyp591t7u7+vUh7MPX3+vf5/n8/+P0BmKJIPUUVlh2rdVVeesWlzEybqg+bFOsoylnqPmNavGFfknV2Omu2Lvja3vxAURKJib3opHizu8riLK6gjRyuKgmoSoMRFENRUqfXTzvBGK62LC2uoFkOl4RhjQ8+qWt7dPNE3sbdp+2LXbsGe9qb4rIo/BfwFy6nWQ4ThWGNDzbcfu29dMDh2nHU7CypYNLmzTda0/L5cNuzmDQi/A4Y27k6eQxLI79wS/11D0AAMNvs6XT6ojVJjJEgTbMy2BT77xBMp09KcpaWV1uc41jQoi0NdUHfjeOO9WWn7AVF7s7n986SithPJGeupBh2PCSP/xxqxAp3eq6wuUV7Wc6MSZIEhA8vHjbfOe/OcW3zmAuKy+nUzAyD2bow8ODaEROFq8AyZ5WBYdEZXGqGxZ61HJV+9HYCJRbTNA0QBA40HWunaKN5dKg/DBKxeCIe09Th/m4MJwiMSZmLEzMQAABQRuNqgu8NYX3doTcMpvCkLbtQZ2AJkrPOZG1zlnY13T+Hy9EehY90h57eqcorcZ/lctZuMzAsOjLEqwNv66/6vZcPYRBC+C3cGaBxhSet2av1BpYgTTY7k5y2JPT41slIR6Axv8R9nnOs+4Pf+2r992uOxGVJwgAAAEINfgt3BGgsESWtWas1iGDyl+CT/u7WpvxNFRc4x7qtBoZFhSFejb7z1fq9NYfjsiT+cwcQavBruCOgU4SIGo18amuoq3Js3FNlynVtH385+s53ze+t8cRkURx3yMTTRBAEQVAUXbFlf3XystJKA2NExeFBdWASDAAA+MQACCEEmqbJ0b6PMC7JwhDU8YFHV5u9NZ64LErT/oW/63tPV6uJwmKoOND78u7Fg5NhAAD4CVbzY9cwrWQrAAAAAElFTkSuQmCC";
return xImg;
}
_createButtons () {
- let xButtonLine = createNode("div", {className: "grammalecte_panel_commands"});
+ let xButtonLine = oGrammalecte.createNode("div", {className: "grammalecte_panel_commands"});
xButtonLine.appendChild(this.xWaitIcon);
if (this.sId === "grammalecte_gc_panel") {
xButtonLine.appendChild(this._createCopyButton());
}
xButtonLine.appendChild(this._createMoveButton("stickToTop", "¯", "Coller en haut"));
@@ -55,30 +55,30 @@
xButtonLine.appendChild(this._createCloseButton());
return xButtonLine;
}
_createWaitIcon () {
- let xWaitIcon = createNode("div", {className: "grammalecte_spinner"});
- xWaitIcon.appendChild(createNode("div", {className: "bounce1"}));
- xWaitIcon.appendChild(createNode("div", {className: "bounce2"}));
+ let xWaitIcon = oGrammalecte.createNode("div", {className: "grammalecte_spinner"});
+ //xWaitIcon.appendChild(oGrammalecte.createNode("div", {className: "bounce1"}));
+ //xWaitIcon.appendChild(oGrammalecte.createNode("div", {className: "bounce2"}));
return xWaitIcon;
}
_createCopyButton () {
- let xButton = createNode("div", {id: "grammalecte_clipboard_button", className: "grammalecte_copy_button", textContent: "∑", title: "Copier dans le presse-papiers"});
+ let xButton = oGrammalecte.createNode("div", {id: "grammalecte_clipboard_button", className: "grammalecte_copy_button", textContent: "∑", title: "Copier dans le presse-papiers"});
xButton.onclick = function () { this.copyTextToClipboard(); }.bind(this);
return xButton;
}
_createMoveButton (sAction, sLabel, sTitle) {
- let xButton = createNode("div", {className: "grammalecte_move_button", textContent: sLabel, title: sTitle});
+ let xButton = oGrammalecte.createNode("div", {className: "grammalecte_move_button", textContent: sLabel, title: sTitle});
xButton.onclick = function () { this[sAction](); }.bind(this);
return xButton;
}
_createCloseButton () {
- let xButton = createNode("div", {className: "grammalecte_close_button", textContent: "×", title: "Fermer la fenêtre"});
+ let xButton = oGrammalecte.createNode("div", {className: "grammalecte_close_button", textContent: "×", title: "Fermer la fenêtre"});
xButton.onclick = function () { this.hide(); }.bind(this); // better than writing “let that = this;” before the function?
return xButton;
}
insertIntoPage () {
Index: gc_lang/fr/webext/content_scripts/panel_gc.js
==================================================================
--- gc_lang/fr/webext/content_scripts/panel_gc.js
+++ gc_lang/fr/webext/content_scripts/panel_gc.js
@@ -44,12 +44,12 @@
*/
constructor (...args) {
super(...args);
this.aIgnoredErrors = new Set();
- this.xContentNode = createNode("div", {id: "grammalecte_gc_panel_content"});
- this.xParagraphList = createNode("div", {id: "grammalecte_paragraph_list"});
+ this.xContentNode = oGrammalecte.createNode("div", {id: "grammalecte_gc_panel_content"});
+ this.xParagraphList = oGrammalecte.createNode("div", {id: "grammalecte_paragraph_list"});
this.xContentNode.appendChild(this.xParagraphList);
this.xPanelContent.addEventListener("click", onGrammalecteGCPanelClick, false);
this.oTooltip = new GrammalecteTooltip(this.xContentNode);
this.xPanelContent.appendChild(this.xContentNode);
this.oTAC = new GrammalecteTextAreaControl();
@@ -76,17 +76,17 @@
}
addParagraphResult (oResult) {
try {
if (oResult && (oResult.sParagraph.trim() !== "" || oResult.aGrammErr.length > 0 || oResult.aSpellErr.length > 0)) {
- let xNodeDiv = createNode("div", {className: "grammalecte_paragraph_block"});
+ let xNodeDiv = oGrammalecte.createNode("div", {className: "grammalecte_paragraph_block"});
// actions
- let xActionsBar = createNode("div", {className: "grammalecte_paragraph_actions"});
- xActionsBar.appendChild(createNode("div", {id: "grammalecte_check" + oResult.iParaNum, className: "grammalecte_paragraph_button grammalecte_green", textContent: "Réanalyser"}, {para_num: oResult.iParaNum}));
- xActionsBar.appendChild(createNode("div", {id: "grammalecte_hide" + oResult.iParaNum, className: "grammalecte_paragraph_button grammalecte_red", textContent: "×", style: "font-weight: bold;"}));
+ let xActionsBar = oGrammalecte.createNode("div", {className: "grammalecte_paragraph_actions"});
+ xActionsBar.appendChild(oGrammalecte.createNode("div", {id: "grammalecte_check" + oResult.iParaNum, className: "grammalecte_paragraph_button grammalecte_green", textContent: "Réanalyser"}, {para_num: oResult.iParaNum}));
+ xActionsBar.appendChild(oGrammalecte.createNode("div", {id: "grammalecte_hide" + oResult.iParaNum, className: "grammalecte_paragraph_button grammalecte_red", textContent: "×", style: "font-weight: bold;"}));
// paragraph
- let xParagraph = createNode("p", {id: "grammalecte_paragraph"+oResult.iParaNum, className: "grammalecte_paragraph", lang: "fr", contentEditable: "true"}, {para_num: oResult.iParaNum});
+ let xParagraph = oGrammalecte.createNode("p", {id: "grammalecte_paragraph"+oResult.iParaNum, className: "grammalecte_paragraph", lang: "fr", contentEditable: "true"}, {para_num: oResult.iParaNum});
xParagraph.setAttribute("spellcheck", "false"); // doesn’t seem possible to use “spellcheck” as a common attribute.
xParagraph.addEventListener("keyup", function (xEvent) {
this.oTAC.setParagraph(parseInt(xEvent.target.dataset.para_num), this.purgeText(xEvent.target.textContent));
this.oTAC.write();
}.bind(this)
@@ -235,11 +235,11 @@
addSummary () {
// todo
}
addMessage (sMessage) {
- let xNode = createNode("div", {className: "grammalecte_gc_panel_message", textContent: sMessage});
+ let xNode = oGrammalecte.createNode("div", {className: "grammalecte_gc_panel_message", textContent: sMessage});
this.xParagraphList.appendChild(xNode);
}
_copyToClipboard (sText) {
// recipe from https://github.com/mdn/webextensions-examples/blob/master/context-menu-copy-link-with-types/clipboard-helper.js
@@ -277,26 +277,26 @@
class GrammalecteTooltip {
constructor (xContentNode) {
this.sErrorId = null;
- this.xTooltip = createNode("div", {id: "grammalecte_tooltip"});
- this.xTooltipArrow = createNode("img", {
+ this.xTooltip = oGrammalecte.createNode("div", {id: "grammalecte_tooltip"});
+ this.xTooltipArrow = oGrammalecte.createNode("img", {
id: "grammalecte_tooltip_arrow",
src: " data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwAAADsABataJCQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xNzNun2MAAAAnSURBVChTY/j//z8cq/kW/wdhZDEMSXRFWCVhGKwAmwQyHngFxf8B5fOGYfeFpYoAAAAASUVORK5CYII=",
alt: "^",
});
- this.xTooltipSuggBlock = createNode("div", {id: "grammalecte_tooltip_sugg_block"});
- let xMessageBlock = createNode("div", {id: "grammalecte_tooltip_message_block"});
- xMessageBlock.appendChild(createNode("p", {id: "grammalecte_tooltip_rule_id"}));
- xMessageBlock.appendChild(createNode("p", {id: "grammalecte_tooltip_message", textContent: "Erreur."}));
- let xActions = xMessageBlock.appendChild(createNode("div", {id: "grammalecte_tooltip_actions"}));
- xActions.appendChild(createNode("div", {id: "grammalecte_tooltip_ignore", textContent: "Ignorer"}));
- xActions.appendChild(createNode("div", {id: "grammalecte_tooltip_url", textContent: "Voulez-vous en savoir plus ?…"}, {url: ""}));
+ this.xTooltipSuggBlock = oGrammalecte.createNode("div", {id: "grammalecte_tooltip_sugg_block"});
+ let xMessageBlock = oGrammalecte.createNode("div", {id: "grammalecte_tooltip_message_block"});
+ xMessageBlock.appendChild(oGrammalecte.createNode("p", {id: "grammalecte_tooltip_rule_id"}));
+ xMessageBlock.appendChild(oGrammalecte.createNode("p", {id: "grammalecte_tooltip_message", textContent: "Erreur."}));
+ let xActions = xMessageBlock.appendChild(oGrammalecte.createNode("div", {id: "grammalecte_tooltip_actions"}));
+ xActions.appendChild(oGrammalecte.createNode("div", {id: "grammalecte_tooltip_ignore", textContent: "Ignorer"}));
+ xActions.appendChild(oGrammalecte.createNode("div", {id: "grammalecte_tooltip_url", textContent: "Voulez-vous en savoir plus ?…"}, {url: ""}));
xMessageBlock.appendChild(xActions);
this.xTooltip.appendChild(xMessageBlock);
- this.xTooltip.appendChild(createNode("div", {id: "grammalecte_tooltip_sugg_title", textContent: "SUGGESTIONS :"}));
+ this.xTooltip.appendChild(oGrammalecte.createNode("div", {id: "grammalecte_tooltip_sugg_title", textContent: "SUGGESTIONS :"}));
this.xTooltip.appendChild(this.xTooltipSuggBlock);
xContentNode.appendChild(this.xTooltip);
xContentNode.appendChild(this.xTooltipArrow);
}
Index: gc_lang/fr/webext/content_scripts/panel_lxg.js
==================================================================
--- gc_lang/fr/webext/content_scripts/panel_lxg.js
+++ gc_lang/fr/webext/content_scripts/panel_lxg.js
@@ -5,11 +5,11 @@
class GrammalecteLexicographer extends GrammalectePanel {
constructor (...args) {
super(...args);
this._nCount = 0;
- this._xContentNode = createNode("div", {id: "grammalecte_lxg_panel_content"});
+ this._xContentNode = oGrammalecte.createNode("div", {id: "grammalecte_lxg_panel_content"});
this.xPanelContent.appendChild(this._xContentNode);
}
clear () {
this._nCount = 0;
@@ -18,24 +18,24 @@
}
}
addSeparator (sText) {
if (this._xContentNode.textContent !== "") {
- this._xContentNode.appendChild(createNode("div", {className: "grammalecte_lxg_separator", textContent: sText}));
+ this._xContentNode.appendChild(oGrammalecte.createNode("div", {className: "grammalecte_lxg_separator", textContent: sText}));
}
}
addMessage (sClass, sText) {
- this._xContentNode.appendChild(createNode("div", {className: sClass, textContent: sText}));
+ this._xContentNode.appendChild(oGrammalecte.createNode("div", {className: sClass, textContent: sText}));
}
addListOfTokens (lTokens) {
try {
if (lTokens) {
this._nCount += 1;
- let xNodeDiv = createNode("div", {className: "grammalecte_lxg_list_of_tokens"});
- xNodeDiv.appendChild(createNode("div", {className: "grammalecte_lxg_list_num", textContent: this._nCount}));
+ let xNodeDiv = oGrammalecte.createNode("div", {className: "grammalecte_lxg_list_of_tokens"});
+ xNodeDiv.appendChild(oGrammalecte.createNode("div", {className: "grammalecte_lxg_list_num", textContent: this._nCount}));
for (let oToken of lTokens) {
xNodeDiv.appendChild(this._createTokenNode(oToken));
}
this._xContentNode.appendChild(xNodeDiv);
}
@@ -44,19 +44,19 @@
showError(e);
}
}
_createTokenNode (oToken) {
- let xTokenNode = createNode("div", {className: "grammalecte_lxg_token_block"});
- xTokenNode.appendChild(createNode("div", {className: "grammalecte_lxg_token grammalecte_lxg_token_" + oToken.sType, textContent: oToken.sValue}));
- xTokenNode.appendChild(createNode("div", {className: "grammalecte_lxg_token_colon", textContent: ":"}));
+ let xTokenNode = oGrammalecte.createNode("div", {className: "grammalecte_lxg_token_block"});
+ xTokenNode.appendChild(oGrammalecte.createNode("div", {className: "grammalecte_lxg_token grammalecte_lxg_token_" + oToken.sType, textContent: oToken.sValue}));
+ xTokenNode.appendChild(oGrammalecte.createNode("div", {className: "grammalecte_lxg_token_colon", textContent: ":"}));
if (oToken.aLabel.length === 1) {
xTokenNode.appendChild(document.createTextNode(oToken.aLabel[0]));
} else {
- let xTokenList = createNode("div", {className: "grammalecte_lxg_morph_list"});
+ let xTokenList = oGrammalecte.createNode("div", {className: "grammalecte_lxg_morph_list"});
for (let sLabel of oToken.aLabel) {
- xTokenList.appendChild(createNode("div", {className: "grammalecte_lxg_morph_elem", textContent: "• " + sLabel}));
+ xTokenList.appendChild(oGrammalecte.createNode("div", {className: "grammalecte_lxg_morph_elem", textContent: "• " + sLabel}));
}
xTokenNode.appendChild(xTokenList);
}
return xTokenNode;
}
Index: gc_lang/fr/webext/content_scripts/panel_tf.js
==================================================================
--- gc_lang/fr/webext/content_scripts/panel_tf.js
+++ gc_lang/fr/webext/content_scripts/panel_tf.js
@@ -15,12 +15,12 @@
_createTextFormatter () {
let xTFNode = document.createElement("div");
try {
// Options
- let xOptions = createNode("div", {id: "grammalecte_tf_options"});
- let xColumn1 = createNode("div", {className: "grammalecte_tf_column"});
+ let xOptions = oGrammalecte.createNode("div", {id: "grammalecte_tf_options"});
+ let xColumn1 = oGrammalecte.createNode("div", {className: "grammalecte_tf_column"});
let xSSP = this._createFieldset("group_ssp", true, "Espaces surnuméraires");
xSSP.appendChild(this._createBlockOption("o_start_of_paragraph", true, "En début de paragraphe"));
xSSP.appendChild(this._createBlockOption("o_end_of_paragraph", true, "En fin de paragraphe"));
xSSP.appendChild(this._createBlockOption("o_between_words", true, "Entre les mots"));
xSSP.appendChild(this._createBlockOption("o_before_punctuation", true, "Avant les points (.), les virgules (,)"));
@@ -36,11 +36,11 @@
xNBSP.appendChild(this._createBlockOption("o_nbsp_before_symbol", true, "Avant % ‰ € $ £ ¥ ˚C"));
xNBSP.appendChild(this._createBlockOption("o_nbsp_within_numbers", true, "À l’intérieur des nombres"));
xNBSP.appendChild(this._createBlockOption("o_nbsp_before_units", true, "Avant les unités de mesure"));
let xDelete = this._createFieldset("group_delete", true, "Suppressions");
xDelete.appendChild(this._createBlockOption("o_erase_non_breaking_hyphens", true, "Tirets conditionnels"));
- let xColumn2 = createNode("div", {className: "grammalecte_tf_column"});
+ let xColumn2 = oGrammalecte.createNode("div", {className: "grammalecte_tf_column"});
let xTypo = this._createFieldset("group_typo", true, "Signes typographiques");
xTypo.appendChild(this._createBlockOption("o_ts_apostrophe", true, "Apostrophe (’)"));
xTypo.appendChild(this._createBlockOption("o_ts_ellipsis", true, "Points de suspension (…)"));
xTypo.appendChild(this._createBlockOption("o_ts_dash_middle", true, "Tirets d’incise :"));
xTypo.appendChild(this._createRadioBoxHyphens("o_ts_m_dash_middle", "o_ts_n_dash_middle", false));
@@ -68,20 +68,20 @@
xColumn2.appendChild(xMisc);
xColumn2.appendChild(xStruct);
xOptions.appendChild(xColumn1);
xOptions.appendChild(xColumn2);
// Actions
- let xActions = createNode("div", {id: "grammalecte_tf_actions"});
- let xDefaultButton = createNode("div", {id: "grammalecte_tf_reset", textContent: "Par défaut", className: "grammalecte_tf_button"});
+ let xActions = oGrammalecte.createNode("div", {id: "grammalecte_tf_actions"});
+ let xDefaultButton = oGrammalecte.createNode("div", {id: "grammalecte_tf_reset", textContent: "Par défaut", className: "grammalecte_tf_button"});
xDefaultButton.addEventListener("click", () => { this.reset(); });
- let xApplyButton = createNode("div", {id: "grammalecte_tf_apply", textContent: "Appliquer", className: "grammalecte_tf_button"});
+ let xApplyButton = oGrammalecte.createNode("div", {id: "grammalecte_tf_apply", textContent: "Appliquer", className: "grammalecte_tf_button"});
xApplyButton.addEventListener("click", () => { this.saveOptions(); this.apply(); });
xActions.appendChild(xDefaultButton);
- xActions.appendChild(createNode("progress", {id: "grammalecte_tf_progressbar"}));
- xActions.appendChild(createNode("span", {id: "grammalecte_tf_time_res", textContent: "…"}));
+ xActions.appendChild(oGrammalecte.createNode("progress", {id: "grammalecte_tf_progressbar"}));
+ xActions.appendChild(oGrammalecte.createNode("span", {id: "grammalecte_tf_time_res", textContent: "…"}));
xActions.appendChild(xApplyButton);
- //xActions.appendChild(createNode("div", {id: "grammalecte_infomsg", textContent: "blabla"}));
+ //xActions.appendChild(oGrammalecte.createNode("div", {id: "grammalecte_infomsg", textContent: "blabla"}));
// create result
xTFNode.appendChild(xOptions);
xTFNode.appendChild(xActions);
}
catch (e) {
@@ -90,50 +90,50 @@
return xTFNode;
}
// Common options
_createFieldset (sId, bDefault, sLabel) {
- let xFieldset = createNode("div", {id: sId, className: "grammalecte_tf_groupblock"});
- let xGroupOption = createNode("div", {id: "o_"+sId, className: "grammalecte_tf_option grammalecte_tf_option_title_off", textContent: sLabel}, {selected: "false", default: bDefault, linked_ids: ""});
+ let xFieldset = oGrammalecte.createNode("div", {id: sId, className: "grammalecte_tf_groupblock"});
+ let xGroupOption = oGrammalecte.createNode("div", {id: "o_"+sId, className: "grammalecte_tf_option grammalecte_tf_option_title_off", textContent: sLabel}, {selected: "false", default: bDefault, linked_ids: ""});
xGroupOption.addEventListener("click", (xEvent) => { this.switchOption(xEvent.target.id); this.switchGroup(xEvent.target.id); });
xFieldset.appendChild(xGroupOption);
return xFieldset;
}
_createBlockOption (sId, bDefault, sLabel) {
- let xLine = createNode("div", {className: "grammalecte_tf_blockopt grammalecte_tf_underline"});
+ let xLine = oGrammalecte.createNode("div", {className: "grammalecte_tf_blockopt grammalecte_tf_underline"});
xLine.appendChild(this._createOption(sId, bDefault, sLabel));
- xLine.appendChild(createNode("div", {id: "res_"+sId, className: "grammalecte_tf_result", textContent: "·"}));
+ xLine.appendChild(oGrammalecte.createNode("div", {id: "res_"+sId, className: "grammalecte_tf_result", textContent: "·"}));
return xLine;
}
_createOption (sId, bDefault, sLabel, sLinkedOptionsId="") {
- let xOption = createNode("div", {id: sId, className: "grammalecte_tf_option grammalecte_tf_option_off", textContent: sLabel}, {selected: "false", default: bDefault, linked_ids: sLinkedOptionsId});
+ let xOption = oGrammalecte.createNode("div", {id: sId, className: "grammalecte_tf_option grammalecte_tf_option_off", textContent: sLabel}, {selected: "false", default: bDefault, linked_ids: sLinkedOptionsId});
xOption.addEventListener("click", (xEvent) => { this.switchOption(xEvent.target.id); });
return xOption;
}
// Hyphens
_createRadioBoxHyphens (sIdEmDash, sIdEnDash, bDefaultEmDash) {
- let xLine = createNode("div", {className: "grammalecte_tf_blockopt grammalecte_tf_indent"});
+ let xLine = oGrammalecte.createNode("div", {className: "grammalecte_tf_blockopt grammalecte_tf_indent"});
xLine.appendChild(this._createOption(sIdEmDash, bDefaultEmDash, "cadratin (—)", sIdEnDash));
xLine.appendChild(this._createOption(sIdEnDash, !bDefaultEmDash, "demi-cadratin (—)", sIdEmDash));
return xLine;
}
// Ligatures
_createRadioBoxLigatures () {
- let xLine = createNode("div", {className: "grammalecte_tf_blockopt grammalecte_tf_underline"});
+ let xLine = oGrammalecte.createNode("div", {className: "grammalecte_tf_blockopt grammalecte_tf_underline"});
xLine.appendChild(this._createOption("o_ts_ligature", true, "Ligatures"));
xLine.appendChild(this._createOption("o_ts_ligature_do", false, "faire", "o_ts_ligature_undo"));
xLine.appendChild(this._createOption("o_ts_ligature_undo", true, "défaire", "o_ts_ligature_do"));
- xLine.appendChild(createNode("div", {id: "res_"+"o_ts_ligature", className: "grammalecte_tf_result", textContent: "·"}));
+ xLine.appendChild(oGrammalecte.createNode("div", {id: "res_"+"o_ts_ligature", className: "grammalecte_tf_result", textContent: "·"}));
return xLine;
}
_createLigaturesSelection () {
- let xLine = createNode("div", {className: "grammalecte_tf_blockopt grammalecte_tf_indent"});
+ let xLine = oGrammalecte.createNode("div", {className: "grammalecte_tf_blockopt grammalecte_tf_indent"});
xLine.appendChild(this._createOption("o_ts_ligature_ff", true, "ff"));
xLine.appendChild(this._createOption("o_ts_ligature_fi", true, "fi"));
xLine.appendChild(this._createOption("o_ts_ligature_ffi", true, "ffi"));
xLine.appendChild(this._createOption("o_ts_ligature_fl", true, "fl"));
xLine.appendChild(this._createOption("o_ts_ligature_ffl", true, "ffl"));
@@ -142,32 +142,36 @@
return xLine;
}
// Apostrophes
_createSingleLetterOptions () {
- let xLine = createNode("div", {className: "grammalecte_tf_blockopt grammalecte_tf_indent"});
+ let xLine = oGrammalecte.createNode("div", {className: "grammalecte_tf_blockopt grammalecte_tf_indent"});
xLine.appendChild(this._createOption("o_ma_1letter_lowercase", false, "lettres isolées (j’ n’ m’ t’ s’ c’ d’ l’)"));
xLine.appendChild(this._createOption("o_ma_1letter_uppercase", false, "Maj."));
return xLine;
}
// Ordinals
_createOrdinalOptions () {
- let xLine = createNode("div", {className: "grammalecte_tf_blockopt grammalecte_tf_underline"});
+ let xLine = oGrammalecte.createNode("div", {className: "grammalecte_tf_blockopt grammalecte_tf_underline"});
xLine.appendChild(this._createOption("o_ordinals_no_exponant", true, "Ordinaux (15e, XXIe…)"));
xLine.appendChild(this._createOption("o_ordinals_exponant", true, "e → ᵉ"));
- xLine.appendChild(createNode("div", {id: "res_"+"o_ordinals_no_exponant", className: "grammalecte_tf_result", textContent: "·"}));
+ xLine.appendChild(oGrammalecte.createNode("div", {id: "res_"+"o_ordinals_no_exponant", className: "grammalecte_tf_result", textContent: "·"}));
return xLine;
}
/*
Actions
*/
start (xTextArea) {
this.xTextArea = xTextArea;
- let xPromise = browser.storage.local.get("tf_options");
- xPromise.then(this.setOptions.bind(this), this.reset.bind(this));
+ if (bChrome) {
+ browser.storage.local.get("tf_options", this.setOptions.bind(this));
+ } else {
+ let xPromise = browser.storage.local.get("tf_options");
+ xPromise.then(this.setOptions.bind(this), this.reset.bind(this));
+ }
}
switchGroup (sOptName) {
if (document.getElementById(sOptName).dataset.selected == "true") {
document.getElementById(sOptName.slice(2)).style.opacity = 1;
Index: gc_lang/fr/webext/manifest.json
==================================================================
--- gc_lang/fr/webext/manifest.json
+++ gc_lang/fr/webext/manifest.json
@@ -9,10 +9,12 @@
"id": "French-GC@grammalecte.net",
"strict_min_version": "57.0"
}
},
+ "minimum_chrome_version": "61",
+
"author": "Olivier R.",
"homepage_url": "https://grammalecte.net",
"description": "Correcteur grammatical pour le français.",
"default_locale": "fr",
@@ -31,10 +33,11 @@
"browser_style": false
},
"background": {
"scripts": [
+ "grammalecte/helpers.js",
"background.js"
]
},
"content_scripts": [
@@ -90,17 +93,17 @@
],
"commands": {
"conjugueur_tab": {
"suggested_key": {
- "default": "Ctrl+Shift+F6"
+ "default": "Ctrl+Shift+6"
},
"description": "Ouvre le conjugueur dans un onglet"
},
"conjugueur_window": {
"suggested_key": {
- "default": "Ctrl+Shift+F7"
+ "default": "Ctrl+Shift+7"
},
"description": "Ouvre le conjugueur dans une fenêtre"
}
},
@@ -121,10 +124,12 @@
"chrome_settings_overrides": {
"search_provider": {
"name": "Grammalecte",
"search_url": "https://www.dicollecte.org/dictionary.php?prj=fr&lemma={searchTerms}",
- "keyword": "disc",
- "favicon_url": "https://www.dicollecte.org/favicon.ico"
+ "keyword": "gram",
+ "favicon_url": "https://www.dicollecte.org/favicon.ico",
+ "encoding": "UTF-8",
+ "is_default": false
}
}
}
Index: gc_lang/fr/webext/panel/main.css
==================================================================
--- gc_lang/fr/webext/panel/main.css
+++ gc_lang/fr/webext/panel/main.css
@@ -122,11 +122,11 @@
overflow: auto;
}
#page h1 {
margin: 0 0 10px 0;
color: hsl(210, 50%, 50%);
- font: bold 30px 'Yanone Kaffeesatz', "Liberation Sans Narrow", sans-serif;
+ font: bold 30px 'Yanone Kaffeesatz', "Oswald", "Liberation Sans Narrow", sans-serif;
}
/*
Home
@@ -158,11 +158,11 @@
#help_page {
display: none;
padding: 20px;
}
#help_page h2 {
- font: bold 20px 'Yanone Kaffeesatz', "Liberation Sans Narrow", sans-serif;
+ font: bold 20px 'Yanone Kaffeesatz', "Oswald", "Liberation Sans Narrow", sans-serif;
color: hsl(210, 50%, 50%);
}
#help_page .shortcut {
margin-top: 10px;
font-weight: bold;
Index: gc_lang/fr/webext/panel/main.html
==================================================================
--- gc_lang/fr/webext/panel/main.html
+++ gc_lang/fr/webext/panel/main.html
@@ -57,13 +57,13 @@
Pour les autres zones de texte (HTML éditable), il faut sélectionner le texte et utiliser le menu contextuel.
Raccourcis clavier
- CTRL+MAJ+F6
+ CTRL+MAJ+6
Conjugueur (dans un onglet)
- CTRL+MAJ+F7
+ CTRL+MAJ+7
Conjugueur (dans une fenêtre)
Index: gc_lang/fr/webext/panel/main.js
==================================================================
--- gc_lang/fr/webext/panel/main.js
+++ gc_lang/fr/webext/panel/main.js
@@ -5,10 +5,18 @@
function showError (e) {
console.error(e.fileName + "\n" + e.name + "\nline: " + e.lineNumber + "\n" + e.message);
}
+// Chrome don’t follow the W3C specification:
+// https://browserext.github.io/browserext/
+let bChrome = false;
+if (typeof(browser) !== "object") {
+ var browser = chrome;
+ bChrome = true;
+}
+
/*
Events
*/
window.addEventListener(
@@ -123,27 +131,38 @@
function showTestResult (sText) {
document.getElementById("tests_result").textContent = sText;
}
+
function setGCOptionsFromStorage () {
+ if (bChrome) {
+ browser.storage.local.get("gc_options", _setGCOptions);
+ return;
+ }
let xPromise = browser.storage.local.get("gc_options");
- xPromise.then(
- function (dSavedOptions) {
- if (dSavedOptions.hasOwnProperty("gc_options")) {
- setGCOptions(dSavedOptions.gc_options);
- }
- },
- function (e) {
- showError(e);
- }
- );
+ xPromise.then(_setGCOptions, showError);
+}
+
+function _setGCOptions (dSavedOptions) {
+ if (dSavedOptions.hasOwnProperty("gc_options")) {
+ setGCOptions(dSavedOptions.gc_options);
+ }
}
function setGCOptions (dOptions) {
+ // dOptions is supposed to be a Map
+ if (bChrome) {
+ // JS crap again. Chrome can’t store/send Map object.
+ let m = new Map();
+ for (let param in dOptions) {
+ m.set(param, dOptions[param]);
+ }
+ dOptions = m;
+ }
for (let [sOpt, bVal] of dOptions) {
if (document.getElementById("option_"+sOpt)) {
document.getElementById("option_"+sOpt).checked = bVal;
}
}
}