bug-librejs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Add the capability to import and export settings


From: Mónica Gómez
Subject: [PATCH] Add the capability to import and export settings
Date: Tue, 30 Jan 2024 15:04:22 -0600

Signed-off-by: Mónica Gómez <eunbyeol64@naver.com>
---
 NEWS                                          |  4 +
 html/preferences_panel/pref.js                | 85 ++++++++++++++++++-
 html/preferences_panel/preferences_panel.html | 10 ++-
 html/preferences_panel/prefs.css              | 16 ++++
 manifest.json                                 |  2 +-
 test/spec/LibreJSSpec.js                      | 43 ++++++++++
 6 files changed, 154 insertions(+), 6 deletions(-)

diff --git a/NEWS b/NEWS
index d4b730c..22739af 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,7 @@
+New in 7.21.2
+
+       * Add the capability of importing and exporting LibreJS' settings
+
 New in 7.21.1
 
   * Fix eval loophole with Function constructor
diff --git a/html/preferences_panel/pref.js b/html/preferences_panel/pref.js
index d90e72e..1956902 100644
--- a/html/preferences_panel/pref.js
+++ b/html/preferences_panel/pref.js
@@ -215,6 +215,78 @@
         options.appendChild(option);
       }
       widget.appendChild(options);
+    },
+
+    exportSettings(){
+      Controller.syncAll();
+      browser.storage.local.get(["pref_whitelist", 
"pref_blacklist"]).then((result) =>{
+        const whitelisted = result.pref_whitelist ? 
result.pref_whitelist.split(",") : [];
+        const blacklisted = result.pref_blacklist ? 
result.pref_blacklist.split(",") : [];
+        let backup_data = `# LibreJS settings backup file\n\n[Whitelisted]`;
+        whitelisted.forEach((value) =>{
+          backup_data += `\n${value}`;
+        });
+        backup_data += "\n\n[Blacklisted]";
+        blacklisted.forEach((value) =>{
+          backup_data += `\n${value}`;
+        });
+        const blob = new Blob([backup_data], {type: "text/plain"});
+        const link = document.getElementById("export");
+        link.href = URL.createObjectURL(blob);
+        link.download = "librejs_settings.conf";
+        link.click();
+      });
+    },
+
+    importSettings(){
+      const input = document.getElementById("fileInput");
+      input.click();
+      input.addEventListener("change", Controller.restoreSettings);
+    },
+
+    restoreSettings(event){
+      const file = event.target.files[0];
+      if (!file) return;
+      const reader = new FileReader();
+      reader.onload = (e) =>{
+        const regex = /\[([^\]]+)\]/g;
+        let pref_whitelist = "";
+        let pref_blacklist = "";
+        let read_whitelist = false;
+        let read_blacklist = false;
+        const content = e.target.result;
+        const data = content.split("\n");
+        data.forEach((line) =>{
+          if (line.startsWith("#")) return;
+          if (line === "") return;
+          if (line.match(regex) && line.toLowerCase() === "[whitelisted]"){
+            read_whitelist = true; read_blacklist = false;
+            return;
+          }
+          else if (line.match(regex) && line.toLowerCase() === 
"[blacklisted]"){
+            read_whitelist = false; read_blacklist = true;
+            return;
+          }
+          else if (line.match(regex) && line.toLowerCase() !== "[whitelisted]" 
&&
+                  line.toLowerCase() !== "[blacklisted]"){
+            read_whitelist = false; read_blacklist = false;
+            return;
+          }
+          if (read_whitelist === true){
+            pref_whitelist += `${line},`;
+          }
+          if (read_blacklist === true){
+            pref_blacklist += `${line},`;
+          }
+        });
+        const realData = {
+          pref_whitelist: pref_whitelist.slice(0, -1),
+          pref_blacklist: pref_blacklist.slice(0, -1)
+        };
+        browser.storage.local.set(realData);
+        Controller.syncAll();
+      }
+      reader.readAsText(file);
     }
   };
 
@@ -256,12 +328,19 @@
 
     click(e) {
       const { target } = e;
-
-      const match = /^cmd-(white|black|delete)(list-site)?/.exec(target.id);
+      const match = /^cmd-(white|black|delete)(list-site)?/.exec(target.id) || 
/^cmd-(export|import)(settings)?/.exec(target.id);
       if (!match) return;
       e.preventDefault();
       const cmd = match[1];
-      if (cmd === "delete") {
+      if (cmd === "export"){
+        Controller.exportSettings();
+        return;
+      }
+      else if (cmd === "import"){
+        Controller.importSettings();
+        return;
+      }
+      else if (cmd === "delete") {
         Controller.deleteSelection();
         return;
       }
diff --git a/html/preferences_panel/preferences_panel.html 
b/html/preferences_panel/preferences_panel.html
index 081ae07..6c80a62 100644
--- a/html/preferences_panel/preferences_panel.html
+++ b/html/preferences_panel/preferences_panel.html
@@ -69,13 +69,19 @@
           </div>
         </div>
       </fieldset>
-
       <fieldset id="section-complaint"><legend>Complaint email 
defaults</legend>
         <label for="pref_subject">Subject</label>
         <input id="pref_subject" type="text"/>
         <label for="pref_body">Body</label>
         <textarea id="pref_body" rows="5"></textarea>
       </fieldset>
+      <fieldset id="backup"><legend>Import or export the settings of your 
allowed and blocked websites</legend>
+        <div id="backup-buttons">
+          <a id="export"><button id="cmd-export-settings" title="Create a 
backup">Export</button></a>
+          <input type="file" id="fileInput" accept=".conf">
+          <button id="cmd-import-settings" title="Restore a 
backup">Import</button>
+        </div>
+      </fieldset>
     </div>
   </body>
-</html>
+</html>
\ No newline at end of file
diff --git a/html/preferences_panel/prefs.css b/html/preferences_panel/prefs.css
index 6e2d206..691cbb5 100644
--- a/html/preferences_panel/prefs.css
+++ b/html/preferences_panel/prefs.css
@@ -75,6 +75,22 @@ input[type="text"] {
   display: flex;
   flex: 2;
 }
+
+#backup-buttons{
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+#backup-buttons button{
+  margin-left: 8px;
+  margin-right: 8px;
+}
+
+#fileInput{
+  display: none;
+}
+
 .error-msg {
   color: red;
 }
diff --git a/manifest.json b/manifest.json
index 73bc918..c522893 100644
--- a/manifest.json
+++ b/manifest.json
@@ -2,7 +2,7 @@
   "manifest_version": 2,
   "name": "GNU LibreJS",
   "short_name": "LibreJS",
-  "version": "7.21.1",
+  "version": "7.21.2",
   "author": "various",
   "description": "Only allows free and/or trivial Javascript to run.",
   "applications": {
diff --git a/test/spec/LibreJSSpec.js b/test/spec/LibreJSSpec.js
index bbd699c..f2e0917 100644
--- a/test/spec/LibreJSSpec.js
+++ b/test/spec/LibreJSSpec.js
@@ -97,6 +97,49 @@ describe('LibreJS\' components', () => {
       expect(lm.getStatus('https://more.evil.gnu.org')).toBe('blacklisted');
       
expect(lm.getStatus('https://more.evil.gnu.org/some/evil/path?too')).toBe('blacklisted');
     });
+    it('Should export and import settings', () =>{
+    const whitelisted = ["https://goodwebsite.com";, 
"https://www.betterwebsite.org";];
+    const blacklisted = ["https://badwebsite.com";, 
"https://www.worsewebsite.org";];
+    let backup_data = `# LibreJS settings backup file\n\n[Test Whitelisted]`;
+    whitelisted.forEach((value) =>{
+      backup_data += `\n${value}`;
+    });
+    backup_data += "\n\n[Test Blacklisted]";
+    blacklisted.forEach((value) =>{
+      backup_data += `\n${value}`;
+    });
+    const regex = /\[([^\]]+)\]/g;
+    let read_whitelist = false;
+    let read_blacklist = false;
+    const data = backup_data.split("\n");
+    data.forEach((line) =>{
+      if (line.startsWith("#")) return;
+      if (line === "") return;
+      if (line.match(regex) && line.toLowerCase() === "[test whitelisted]"){
+        read_whitelist = true; read_blacklist = false;
+        return;
+      }
+      else if (line.match(regex) && line.toLowerCase() === "[test 
blacklisted]"){
+        read_whitelist = false; read_blacklist = true;
+        return;
+      }
+      else if (line.match(regex) && line.toLowerCase() !== "[test 
whitelisted]" &&
+      line.toLowerCase() !== "[test blacklisted]"){
+        read_whitelist = false; read_blacklist = false;
+        return;
+      }
+      if (read_whitelist === true){
+        lm.whitelist(line);
+      }
+      if (read_blacklist === true){
+        lm.blacklist(line);
+      }
+    });
+    expect(lm.getStatus('https://goodwebsite.com')).toBe('whitelisted');
+    expect(lm.getStatus('https://www.betterwebsite.org')).toBe('whitelisted');
+    expect(lm.getStatus('https://badwebsite.com')).toBe('blacklisted');
+    expect(lm.getStatus('https://www.worsewebsite.org')).toBe('blacklisted');
+    });
   })
 
   describe('The external script source processor', () => {
-- 
2.43.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]