Grammalecte  Check-in [8dee6996d7]

Overview
Comment:[fx] use persistent connexions between content-scripts and background, better interactions between scripts
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | fx | webext2
Files: files | file ages | folders
SHA3-256: 8dee6996d722e4109fb5302f05301e7867f84428b45d58edfb904966bd6b15d0
User & Date: olr on 2017-08-11 15:48:52
Other Links: branch diff | manifest | tags
Context
2017-08-12
09:51
[fx] panels ui (draft) check-in: e0f8e36d5a user: olr tags: fx, webext2
2017-08-11
15:48
[fx] use persistent connexions between content-scripts and background, better interactions between scripts check-in: 8dee6996d7 user: olr tags: fx, webext2
12:50
[fx] logo-80.png in manifest.json check-in: 62d897eef2 user: olr tags: fx, webext2
Changes

Modified gc_lang/fr/webext/background.js from [fcd118d7b1] to [bc6f49ada9].

17
18
19
20
21
22
23





24


25
26
27




28
29



30
31
32
33
34
35
36
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







+
+
+
+
+
-
+
+



+
+
+
+
-
-
+
+
+







        let {sActionDone, result, dInfo, bError} = e.data;
        switch (sActionDone) {
            case "init":
                console.log("INIT DONE");
                break;
            case "parse":
                console.log("GRAMMAR ERRORS");
                if (typeof(dInfo.iReturnPort) === "number") {
                    let xPort = aConnx[dInfo.iReturnPort];
                    xPort.postMessage(e.data);
                } else {
                    console.log("[background] don’t know where to send results");
                console.log(result);
                    console.log(e.data);
                }
                break;
            case "parseAndSpellcheck":
                console.log("SPELLING AND GRAMMAR ERRORS");
                if (typeof(dInfo.iReturnPort) === "number") {
                    let xPort = aConnx[dInfo.iReturnPort];
                    xPort.postMessage(e.data);
                } else {
                console.log(result.aSpellErr);
                console.log(result.aGrammErr);
                    console.log("[background] don’t know where to send results");
                    console.log(e.data);
                }
                break;
            case "textToTest":
                console.log("TEXT TO TEXT RESULTS");
                browser.runtime.sendMessage({sCommand: "text_to_test_result", sResult: result});
                break;
            case "fullTests":
                console.log("FULL TESTS RESULTS");
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
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







+
+
+
+
+
+
+






+
+
-
+

-
-
-
+
-
-
-
+
-
-
-
+
-
-
-
-
+
+
+
+
+
+







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







        showError(e);
    }
};


xGCEWorker.postMessage({sCommand: "init", dParam: {sExtensionPath: browser.extension.getURL("."), sOptions: "", sContext: "Firefox"}, dInfo: {}});


/*
    Ports from content-scripts
*/

let aConnx = [];


/*
    Messages from the extension (not the Worker)
*/
function handleMessage (oRequest, xSender, sendResponse) {
    //console.log(xSender);
    console.log("[background] received:");
    console.log(oRequest);
    switch(oRequest.sCommand) {
    switch (oRequest.sCommand) {
        case "parse":
            xGCEWorker.postMessage({sCommand: "parse", dParam: {sText: oRequest.sText, sCountry: "FR", bDebug: false, bContext: false}, dInfo: {}});
            break;
        case "parse_and_spellcheck":
        case "parseAndSpellcheck":
            xGCEWorker.postMessage({sCommand: "parseAndSpellcheck", dParam: {sText: oRequest.sText, sCountry: "FR", bDebug: false, bContext: false}, dInfo: {}});
            break;
        case "get_list_of_tokens":
        case "getListOfTokens":
            xGCEWorker.postMessage({sCommand: "getListOfTokens", dParam: {sText: oRequest.sText}, dInfo: {}});
            break;
        case "text_to_test":
        case "textToTest":
            xGCEWorker.postMessage({sCommand: "textToTest", dParam: {sText: oRequest.sText, sCountry: "FR", bDebug: false, bContext: false}, dInfo: {}});
            break;
        case "fulltests":
            xGCEWorker.postMessage({sCommand: "fullTests", dParam: {}, dInfo: {}});
        case "getOptions":
        case "getDefaultOptions":
        case "setOptions":
        case "setOption":
        case "fullTests":
            xGCEWorker.postMessage(oRequest);
            break;
    }
    //sendResponse({response: "response from background script"});
}

browser.runtime.onMessage.addListener(handleMessage);


function handleConnexion (p) {
    var xPort = p;
    let iPortId = aConnx.length; // identifier for the port: each port can be found at aConnx[iPortId]
    aConnx.push(xPort);
    console.log("Port: " + p.name + ", id: " + iPortId);
    xPort.onMessage.addListener(function (oRequest) {
        console.log("[background] message via connexion:");
        console.log(oRequest);
        switch (oRequest.sCommand) {
            case "getCurrentTabId":
                xPort.postMessage({sActionDone: "getCurrentTabId", result: "getCurrentTabId()", dInfo: null, bError: false});
                break;
            case "parse":
            case "parseAndSpellcheck":
            case "getListOfTokens":
                oRequest.dInfo.iReturnPort = iPortId; // we pass the id of the return port to received answer
                console.log(oRequest);
                xGCEWorker.postMessage(oRequest);
                break;
            default:
                console.log("[background] Unknown command: " + oRequest.sCommand);
        }
    });
    xPort.postMessage({sActionDone: "newId", result: iPortId});
}

browser.runtime.onConnect.addListener(handleConnexion);


/*
    Context Menu
*/
browser.contextMenus.create({
    id: "grammar_checking",
    title: "Correction grammaticale",
163
164
165
166
167
168
169








170
171
172
173
174
175
176
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229







+
+
+
+
+
+
+
+







            });
            xConjTab.then(onCreated, onError);
            break;
    }    
});


async function getCurrentTabId () {
    let xTab = await browser.tabs.getCurrent();
    return xTab.id;
}

/*
    TESTS ONLY
*/
async function newwin () {
    // test for popup window-like, which doesn’t close when losing the focus
    console.log("Async on");
    const getActive = browser.tabs.query({ currentWindow: true, active: true, });
    const xWindowInfo = await browser.windows.getLastFocused();
    const width = 710, height = 980; // the maximum size for panels is somewhere around 700x800. Firefox needs some additional pixels: 14x42 for FF54 on Win 10 with dpi 1.25
    const left = Math.round(xWindowInfo.left + xWindowInfo.width - width - 25);

Modified gc_lang/fr/webext/content_scripts/modify_page.js from [15a0d2d897] to [8366675e79].

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

13
14

15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
19
20
21
22











-
+


+







// Modify page

/*
    JS sucks (again and again and again and again…)
    Not possible to load content from within the extension:
    https://bugzilla.mozilla.org/show_bug.cgi?id=1267027
    No SharedWorker, no images allowed for now…
*/

"use strict";

console.log("Content script [start]");
console.log("[Content script] Start");


let nTadId = null;
let nWrapper = 0;

let xConjPanel = null;
let xTFPanel = null;
let xLxgPanel = null;
let xGCPanel = null;

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







+





-










+
+
+
+
+












-
+






-
+






-
+








-

















-
-
-
+



-
+



-
+

+
+
+
+
+
+
+
+
+
+
+
+













+
+
+
+
+
+
+
+
+
+
+
-
+
+
+

-
+

-
-
+
+
-
-
+





-
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

        xWrapper.style = "padding: 5px; color: hsl(210, 10%, 90%); background-color: hsl(210, 50%, 50%); border-radius: 3px;";
        xWrapper.id = nWrapper + 1;
        nWrapper += 1;
        xParentElement.insertBefore(xWrapper, xTextArea);
        xWrapper.appendChild(xTextArea); // move textarea in wrapper
        let xToolbar = createWrapperToolbar(xTextArea);
        xWrapper.appendChild(xToolbar);
        loadImage("GrammalecteTitle", "img/logo-16.png");
    }
    catch (e) {
        showError(e);
    }
}


let sButtonStyle = "display: inline-block; padding: 0 5px; margin-left: 5px; background-color: hsl(210, 50%, 60%); border-radius: 2px; cursor: pointer;";

function createWrapperToolbar (xTextArea) {
    try {
        let xToolbar = document.createElement("div");
        xToolbar.style = "display: flex; justify-content: flex-end; margin-top: 5px; padding: 5px 10px;";
        /*let xLogo = document.createElement("img");
        xLogo.src = browser.extension.getURL("img/logo-16.png");
        xTitle.appendChild(xLogo);*/

        let xImagePlace = document.createElement("span");
        xImagePlace.className = "GrammalecteTitle";
        xToolbar.appendChild(xImagePlace);

        xToolbar.appendChild(document.createTextNode("Grammalecte"));
        let xConjButton = document.createElement("div");
        xConjButton.textContent = "Conjuguer";
        xConjButton.style = sButtonStyle;
        xConjButton.onclick = function() {
            createConjPanel();
        };
        xToolbar.appendChild(xConjButton);
        let xTFButton = document.createElement("div");
        xTFButton.textContent = "Formater";
        xTFButton.style = sButtonStyle;
        xTFButton.onclick = function() {
            createTFPanel();
            createTFPanel(xTextArea);
        };
        xToolbar.appendChild(xTFButton);
        let xLxgButton = document.createElement("div");
        xLxgButton.textContent = "Analyser";
        xLxgButton.style = sButtonStyle;
        xLxgButton.onclick = function() {
            createLxgPanel();
            console.log("Analyser");
        };
        xToolbar.appendChild(xLxgButton);
        let xGCButton = document.createElement("div");
        xGCButton.textContent = "Corriger";
        xGCButton.style = sButtonStyle;
        xGCButton.onclick = function() {
            createGCPanel();
            xPort.postMessage({sCommand: "parseAndSpellcheck", dParam: {sText: xTextArea.value, sCountry: "FR", bDebug: false, bContext: false}, dInfo: {sTextAreaId: xTextArea.id}});
        };
        xToolbar.appendChild(xGCButton);
        return xToolbar;
    }
    catch (e) {
        showError(e);
    }
}


function createConjPanel () {
    console.log("Conjugueur");
    if (xConjPanel !== null) {
        xConjPanel.style.display = "block";
    } else {
        // create the panel
        xConjPanel = document.createElement("div");
        xConjPanel.style = "position: fixed; left: 50%; top: 50%; z-index: 100; height: 400px; margin-top: -200px; width: 600px; margin-left: -300px; border-radius: 10px;"
                         + " color: hsl(210, 10%, 4%); background-color: hsl(210, 20%, 90%); border: 10px solid hsla(210, 20%, 70%, .5);";
        xConjPanel.textContent = "Conjugueur";
        xConjPanel.setAttribute("draggable", true);
        xConjPanel.appendChild(createCloseButton(xConjPanel));
        document.body.appendChild(xConjPanel);
    }
}



function createTFPanel () {
function createTFPanel (xTextArea) {
    console.log("Formateur de texte");
}

function createLxgPanel () {
function createLxgPanel (xTextArea) {
    console.log("Analyse");
}

function createGCPanel () {
function createGCPanel (oErrors) {
    console.log("Correction grammaticale");
    if (xGCPanel !== null) {
        xGCPanel.style.display = "block";
    } else {
        // create the panel
        xGCPanel = document.createElement("div");
        xGCPanel.style = "position: fixed; left: 50%; top: 50%; z-index: 100; height: 400px; margin-top: -200px; width: 600px; margin-left: -300px; border-radius: 10px;"
                         + " color: hsl(210, 10%, 4%); background-color: hsl(210, 20%, 90%); border: 10px solid hsla(210, 20%, 70%, .5);";
        xGCPanel.textContent = JSON.stringify(oErrors);
        xGCPanel.setAttribute("draggable", true);
        xGCPanel.appendChild(createCloseButton(xGCPanel));
        document.body.appendChild(xGCPanel);
    }
}

function createCloseButton (xParentNode) {
    let xButton = document.createElement("div");
    xButton.style = "float: right; width: 20px; padding: 5px 10px; color: hsl(210, 0%, 100%); text-align: center;"
                  + "font-size: 20px; font-weight: bold; background-color: hsl(0, 80%, 50%); border-radius: 0 0 0 3px; cursor: pointer;";
    xButton.textContent = "×";
    xButton.onclick = function () {
        xParentNode.style.display = "none";
    }
    return xButton;
}

function loadImage (sContainerClass, sImagePath) {
    let xRequest = new XMLHttpRequest();
    xRequest.open('GET', browser.extension.getURL("")+sImagePath, false);
    xRequest.responseType = "arraybuffer";
    xRequest.send();
    let blobTxt = new Blob([xRequest.response], {type: 'image/png'});
    let img = document.createElement('img');
    img.src = (URL || webkitURL).createObjectURL(blobTxt);
    Array.filter(document.getElementsByClassName(sContainerClass), function (oElem) {
        oElem.appendChild(img);
    });

}


/*
    Assign do_something() as a listener for messages from the extension.
    Simple message
*/


function handleMessage (oMessage, xSender, sendResponse) {
    console.log("[Content script] received:");
function handleMessage2 (oRequest, xSender, sendResponse) {
    console.log(`[Content script] received: ${oRequest.content}`);
    console.log(oMessage);
    //change(request.myparam);
    //browser.runtime.onMessage.removeListener(handleMessage);
    sendResponse({response: "response from content script"});
}

browser.runtime.onMessage.addListener(handleMessage2);
browser.runtime.onMessage.addListener(handleMessage);


/*
    Connexion
*/
let xPort = browser.runtime.connect({name: "content-script port"});
xPort.onMessage.addListener(function (oMessage) {
    console.log("[Content script] received…");
    let {sActionDone, result, dInfo, bError} = oMessage;
    switch (sActionDone) {
        case "getCurrentTabId":
            console.log("[Content script] tab id: " + result);
            nTadId = result;
            break;
        case "parseAndSpellcheck":
            console.log(result);
            createGCPanel(result);
            break;
        case "getListOfTokens":
            console.log(result);
            break;
        default:
            console.log("[Content script] Unknown command: " + sActionDone);
    }
});
xPort.postMessage({sCommand: "getCurrentTabId", dParam: {}, dInfo: {}});

/*document.body.addEventListener("click", function () {
    xPort.postMessage({greeting: "they clicked the page!"});
});*/

wrapTextareas();

Modified gc_lang/fr/webext/manifest.json from [988b2f9443] to [d1899487f8].

41
42
43
44
45
46
47
48


49
50
51
52
53
54
55
41
42
43
44
45
46
47

48
49
50
51
52
53
54
55
56







-
+
+







    }
  ],
  "web_accessible_resources": [
    "grammalecte/_dictionaries/French.json",
    "grammalecte/fr/conj_data.json",
    "grammalecte/fr/mfsp_data.json",
    "grammalecte/fr/phonet_data.json",
    "grammalecte/fr/tests_data.json"
    "grammalecte/fr/tests_data.json",
    "img/logo-16.png"
  ],
  "permissions": [
    "activeTab",
    "contextMenus"
  ],
  "chrome_settings_overrides": {
    "search_provider": {

Modified gc_lang/fr/webext/panel/main.html from [d1a2ec127f] to [f22bea17bb].

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
20
21
22
23
24
25
26









27
28
29
30
31
32
33
34
35
36
37
38







-
-
-
-
-
-
-
-
-




+







            <li class="select" data-page="gc_options_page"><i class="fa fa-coffee icon"></i> OP1</li>
            <li class="select" data-page="sc_options_page"><i class="fa fa-keyboard-o icon"></i> OP2</li>
            <li class="select" data-page="test_page"><i class="fa fa-keyboard-o icon"></i> TST</li>
          </ul>
        </nav>
      </header> <!-- #left -->

      <!--
      <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="page">

        <section id="home_page" class="page">
          <h1>GRAMMALECTE</h1>
          <div><a href="https://www.dicollecte.org/test.html" target="_blank">TEST</a></div>
        </section>

        <section id="gc_options_page" class="page">
          <h1>OPTIONS GRAMMATICALES</h1>
        </section>

        <section id="sc_options_page" class="page">

Modified gc_lang/fr/webext/panel/main.js from [2915144b90] to [41da6fb310].

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







-
+



-
+




-
+

-
+







window.addEventListener(
    "click",
    function (xEvent) {
        let xElem = xEvent.target;
        if (xElem.id) {
            switch (xElem.id) {
                case "text_to_test":
                    browser.runtime.sendMessage({sCommand: "text_to_test", sText: document.getElementById("text_to_test").value});
                    browser.runtime.sendMessage({sCommand: "textToTest", dParam: {sText: document.getElementById("text_to_test").value, sCountry: "FR", bDebug: false, bContext: false}, dInfo: {}});
                    break;
                case "fulltests":
                    document.getElementById("tests_result").textContent = "Veuillez patienter…";
                    browser.runtime.sendMessage({sCommand: "fulltests"});
                    browser.runtime.sendMessage({sCommand: "fullTests", dParam: {}, dInfo: {}});
                    break;
            }
        } else if (xElem.className === "select") {
            showPage(xElem.dataset.page);
        } else if (xElem.tagName === "A") {
        }/* else if (xElem.tagName === "A") {
            openURL(xElem.getAttribute("href"));
        }
        }*/
    },
    false
);


/* 
    Message sender