Grammalecte  Check-in [dd167e6841]

Overview
Comment:[fx] API update + fixes + doc
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk | fx
Files: files | file ages | folders
SHA3-256: dd167e6841c7f76cdcfc489e121b74860bfe7e0a9a2fd98ac22c19c25321486a
User & Date: olr on 2020-03-18 13:20:17
Other Links: manifest | tags
Context
2020-03-18
13:28
[doc] Web API update check-in: a52df75d7d user: olr tags: trunk, doc
13:20
[fx] API update + fixes + doc check-in: dd167e6841 user: olr tags: trunk, fx
2020-03-17
13:18
[fr] ajustements check-in: d20401e35a user: olr tags: trunk, fr
Changes

Added doc/API_web.md version [add53b7581].











































































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# API for the web

If Grammalecte is installed by the user on his browser (like Firefox or Chrome), you can call
several functions for a better integration of grammar checking for your website. This is mostly usefull
if your use a non-standard textarea.


### Detecting if Grammalecte API is here

Every call to the Grammalecte API will be done via an object called `oGrammalecteAPI`.

    if (typeof(oGrammalecteAPI) === "object") {
        ...
    }


### Disabling the Grammalecte button (the spinning pearl)

By default, Grammalecte inserts a button (a spinning pearl) on each textarea node and editable node (unless the user disabled it).
You can tell Grammalete not to create these buttons on your text areas with the property: `data-grammalecte_button="false"`.


### Open the Grammalecte panel for a node

If you have disabled the spinning buttons, you may launch the Grammalecte panel with your custom button

    oGrammalecteAPI.openPanelForNode("node_id")
    oGrammalecteAPI.openPanelForNode(node)

The node can be a textarea, an editable node or an iframe.
If the node is an iframe, the content won’t be modified by Grammalecte.


### Open the Grammalecte panel for any text

    oGrammalecteAPI.openPanelForText("your text")

This method won’t send back any result or modified text.


### Open Grammalecte panel

    oGrammalecteAPI.openPanel(param)

Depending of what `param` is, this method will call `openPanelForNode()` or `openPanelForText()`.


### Prevent Grammalecte to modify the node content

If you don’t want Grammalecte to modify directly the node content, add the property: `data-grammalecte_result_via_event="true"`.

With this property, Grammalecte will send an event to the node each times the text is modified within the panel.
The text can be retrieved with:

    node.addEventListener("GrammalecteResult", function (event) {
        if (event.detail.sType  &&  event.detail.sType == "text") {
            let sText = event.detail.sText;
            ...
        }
    }


### Parse a node and get errors

    oGrammalecteAPI.parseNode("node_id")
    oGrammalecteAPI.parseNode(node)

The node can be a textarea, an editable node or an iframe. The node must have an identifier.
Results will be sent with a succession of events at the node.

    node.addEventListener("GrammalecteResult", function (event) {
        if (event.detail.sType  &&  event.detail.sType == "errors") {
            let oResult = event.detail.oResult; // null when the text parsing is finished
            ...
        }
    }

For the last event, `oResult` will be `null`.


### Get spelling suggestions

`oGrammalecteAPI.getSpellingSuggestions(word, destination, error_identifier)`

Parameters:

- word (string)

- destination: node_id (string)

- error_identifier: a custom identifier (string)

Suggestions will be sent within an event at the node identified by `destination`.

    node.addEventListener("GrammalecteResult", function (event) {
        if (event.detail.sType  &&  event.detail.sType == "spellsugg") {
            let oResult = event.detail.oResult;
            let oInfo = event.detail.oInfo; // object containing the destination and the error_identifier
            ...
        }
    }


### Version of the Grammalecte Web API

    oGrammalecteAPI.sVersion

Modified gc_lang/fr/webext/background.js from [b8162f6122] to [3d2146a610].

447
448
449
450
451
452
453
454

455
456
457
458
459
460
461
462

463
464
465
466
467
468
469
447
448
449
450
451
452
453

454
455
456
457
458
459
460
461

462
463
464
465
466
467
468
469







-
+







-
+







    xTabPort.postMessage({sActionDone: sCommand, result: result, dInfo: null, bEnd: false, bError: false});
}

function sendCommandToCurrentTab (sCommand) {
    if (bChrome) {
        browser.tabs.query({ currentWindow: true, active: true }, (lTabs) => {
            for (let xTab of lTabs) {
                console.log(xTab);
                //console.log(xTab);
                browser.tabs.sendMessage(xTab.id, {sActionRequest: sCommand});
            }
        });
        return;
    }
    browser.tabs.query({ currentWindow: true, active: true }).then((lTabs) => {
        for (let xTab of lTabs) {
            console.log(xTab);
            //console.log(xTab);
            browser.tabs.sendMessage(xTab.id, {sActionRequest: sCommand});
        }
    }, showError);
}

function sendCommandToAllTabs (sCommand) {
    for (let [iTab, xTabPort] of dConnx.entries()) {

Modified gc_lang/fr/webext/content_scripts/api.js from [52f71e590a] to [938cca0bac].

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
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







-
+




+




















-
-
-
+
+
+
+

+
+
+
+
+
-
+





+








-
-
-
+
+
+
+
+
+

+
+
+
+
+
-
-
+
+




+
+
+
+
+
-
+



-
+



// JavaScript

"use strict";


const oGrammalecteAPI = {
    // functions callable from within pages
    // to be sent to the content-cript via an event GrammalecteCall
    // to be sent to the content-cript via an event GrammalecteCall

    sVersion: "1.0",

    openPanel: function (arg1) {
        //  Parameter: a text, a node, or the identifier of a node.
        let xNode = null;
        if (typeof(arg1) === 'string') {
            if (document.getElementById(arg1)) {
                xNode = document.getElementById(arg1);
            } else {
                this.openPanelForText(arg1);
            }
        }
        else if (arg1 instanceof HTMLElement) {
            xNode = arg1;
        }
        if (xNode) {
            if (xNode.tagName == "INPUT"  ||  xNode.tagName == "TEXTAREA"  ||  xNode.tagName == "IFRAME"  ||  xNode.isContentEditable) {
                this.openPanelForNode(xNode);
            } else {
                this.openPanelForText(xNode.innerText);
            }
        }
    },

    openPanelForNode: function (xNode) {
        if (xNode instanceof HTMLElement) {
            let xEvent = new CustomEvent("GrammalecteCall", { detail: {sCommand: "openPanelForNode", xNode: xNode} });
    openPanelForNode: function (vNode) {
        //  Parameter: a HTML node or the identifier of a HTML node
        if (vNode instanceof HTMLElement) {
            let xEvent = new CustomEvent("GrammalecteCall", { detail: {sCommand: "openPanelForNode", xNode: vNode} });
            document.dispatchEvent(xEvent);
        }
        else if (typeof(vNode) === "string" && document.getElementById(vNode)) {
            let xEvent = new CustomEvent("GrammalecteCall", { detail: {sCommand: "openPanelForNode", xNode: document.getElementById(vNode)} });
            document.dispatchEvent(xEvent);
        }
        } else {
        else {
            console.log("[Grammalecte API] Error: parameter is not a HTML node.");
        }
    },

    openPanelForText: function (sText) {
        //  Parameter: text to analyze
        if (typeof(sText) === "string") {
            let xEvent = new CustomEvent("GrammalecteCall", { detail: {sCommand: "openPanelForText", sText: sText} });
            document.dispatchEvent(xEvent);
        } else {
            console.log("[Grammalecte API] Error: parameter is not a text.");
        }
    },

    parseNode: function (xNode) {
        if (xNode instanceof HTMLElement) {
            let xEvent = new CustomEvent("GrammalecteCall", { detail: {sCommand: "parseNode", xNode: xNode} });
    parseNode: function (vNode) {
        /*  Parameter: a HTML node (with a identifier) or the identifier of a HTML node.
            The result will be sent as an event “GrammalecteResult” to the node.
        */
        if (vNode instanceof HTMLElement  &&  vNode.id) {
            let xEvent = new CustomEvent("GrammalecteCall", { detail: {sCommand: "parseNode", xNode: vNode} });
            document.dispatchEvent(xEvent);
        }
        else if (typeof(vNode) === "string" && document.getElementById(vNode)) {
            let xEvent = new CustomEvent("GrammalecteCall", { detail: {sCommand: "parseNode", xNode: document.getElementById(vNode)} });
            document.dispatchEvent(xEvent);
        }
        } else {
            console.log("[Grammalecte API] Error: parameter is not a HTML node.");
        else {
            console.log("[Grammalecte API] Error: parameter is not a HTML node or doesn’t have an identifier.");
        }
    },

    getSpellSuggestions: function (sWord, sDestination, sErrorId) {
        /* parameters:
            - sWord (string)
            - sDestination: HTML identifier (string) -> the result will be sent as an event “GrammalecteResult” to destination node
            - sErrorId: identifier for the error (string)
        */
        if (typeof(sWord) === "string") {
        if (typeof(sWord) === "string"  &&  typeof(sDestination) === "string"  &&  typeof(sErrorId) === "string") {
            let xEvent = new CustomEvent("GrammalecteCall", { detail: {sCommand: "getSpellSuggestions", sWord: sWord, sDestination: sDestination, sErrorId: sErrorId} });
            document.dispatchEvent(xEvent);
        } else {
            console.log("[Grammalecte API] Error: parameter is not a text.");
            console.log("[Grammalecte API] Error: one or several parameters aren’t string.");
        }
    }
}

Modified gc_lang/fr/webext/content_scripts/init.js from [96d14d059f] to [39a18c330c].

387
388
389
390
391
392
393
394

395
396
397
398
399
400
401
387
388
389
390
391
392
393

394
395
396
397
398
399
400
401







-
+







                            oGrammalecte.oGCPanel.addParagraphResult(result);
                        } else {
                            oGrammalecte.oGCPanel.stopWaitIcon();
                            oGrammalecte.oGCPanel.endTimer();
                        }
                    }
                    else if (dInfo.sDestination  &&  document.getElementById(dInfo.sDestination)) {
                        const xEvent = new CustomEvent("GrammalecteResult", { detail: JSON.stringify({ result: result, info: dInfo }) });
                        const xEvent = new CustomEvent("GrammalecteResult", { detail: JSON.stringify({ sType: "errors", oResult: result, oInfo: dInfo }) });
                        document.getElementById(dInfo.sDestination).dispatchEvent(xEvent);
                    }
                    break;
                case "parseAndSpellcheck1":
                    if (dInfo.sDestination == "__GrammalectePanel__") {
                        oGrammalecte.oGCPanel.refreshParagraph(dInfo.sParagraphId, result);
                    }
412
413
414
415
416
417
418
419

420
421
422
423
424
425
426
412
413
414
415
416
417
418

419
420
421
422
423
424
425
426







-
+







                    }
                    break;
                case "getSpellSuggestions":
                    if (dInfo.sDestination == "__GrammalectePanel__") {
                        oGrammalecte.oGCPanel.oTooltip.setSpellSuggestionsFor(result.sWord, result.aSugg, result.iSuggBlock, dInfo.sErrorId);
                    }
                    else if (dInfo.sDestination  &&  document.getElementById(dInfo.sDestination)) {
                        const xEvent = new CustomEvent("GrammalecteResult", { detail: JSON.stringify({ result: result, info: dInfo }) });
                        const xEvent = new CustomEvent("GrammalecteResult", { detail: JSON.stringify({ sType: "spellsugg", oResult: result, oInfo: dInfo }) });
                        document.getElementById(dInfo.sDestination).dispatchEvent(xEvent);
                    }
                    break;
                case "getVerb":
                    if (dInfo.bStart) {
                        oGrammalecte.oGCPanel.conjugateWith(result.oVerb, result.oConjTable);
                    } else {
534
535
536
537
538
539
540
541

542
543
544
545
546
547
548
534
535
536
537
538
539
540

541
542
543
544
545
546
547
548







-
+







                    else {
                        oGrammalecteBackgroundPort.parseAndSpellcheck(oCommand.xNode.innerText, oCommand.xNode.id);
                    }
                }
                break;
            case "getSpellSuggestions":
                if (oCommand.sWord) {
                    oGrammalecteBackgroundPort.getSpellSuggestions(sWord, oCommand.sDestination, oCommand.sErrorId);
                    oGrammalecteBackgroundPort.getSpellSuggestions(oCommand.sWord, oCommand.sDestination, oCommand.sErrorId);
                }
                break;
            default:
                console.log("[Grammalecte] Event: Unknown command", oCommand.sCommand);
        }
    }
    catch (e) {

Modified gc_lang/fr/webext/content_scripts/panel_gc.js from [5905befb4d] to [61b25ed2ef].

1006
1007
1008
1009
1010
1011
1012
1013

1014
1015
1016
1017
1018
1019
1020
1006
1007
1008
1009
1010
1011
1012

1013
1014
1015
1016
1017
1018
1019
1020







-
+







            this.xNode.removeChild(this.xNode.firstChild);
        }
    }

    write () {
        if (this.xNode !== null) {
            if (this.bResultInEvent) {
                const xEvent = new CustomEvent("GrammalecteResult", { detail: JSON.stringify({ text: this.getText() }) });
                const xEvent = new CustomEvent("GrammalecteResult", { detail: JSON.stringify({ sType: "text", sText: this.getText() }) });
                this.xNode.dispatchEvent(xEvent);
                //console.log("Text sent via an event :", xEvent.detail);
            }
            else if (this.bTextArea) {
                this.xNode.value = this.getText();
            }
            else if (this.bIframe) {