diff options
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | html/display_panel/content/README | 21 | ||||
-rw-r--r-- | html/display_panel/content/background-panel.png | bin | 0 -> 14814 bytes | |||
-rw-r--r-- | html/display_panel/content/display-panel.html | 73 | ||||
-rw-r--r-- | html/display_panel/content/librejs-title-old.png | bin | 0 -> 2673 bytes | |||
-rw-r--r-- | html/display_panel/content/librejs-title.png | bin | 0 -> 14123 bytes | |||
-rw-r--r-- | html/display_panel/content/main_panel.js | 96 | ||||
-rw-r--r-- | html/display_panel/content/panel-styles.css | 190 | ||||
-rw-r--r-- | html/preferences_panel/pref.js | 56 | ||||
-rw-r--r-- | html/preferences_panel/preferences_panel.html | 63 | ||||
-rw-r--r-- | html/report_page/report.html | 0 | ||||
-rw-r--r-- | html/report_page/report.js | 0 | ||||
-rw-r--r-- | icons/librejs.png | bin | 0 -> 1604 bytes | |||
-rw-r--r-- | main_background.js | 161 | ||||
-rw-r--r-- | manifest.json | 44 |
15 files changed, 708 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b7da9fb --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*~ +old/ +*.zip +SDK LibreJS source/
\ No newline at end of file diff --git a/html/display_panel/content/README b/html/display_panel/content/README new file mode 100644 index 0000000..a56ea46 --- /dev/null +++ b/html/display_panel/content/README @@ -0,0 +1,21 @@ +/** + * GNU LibreJS - A browser add-on to block nonfree nontrivial JavaScript. + * * + * Copyright (C) 2011, 2012, 2014 Loic J. Duros + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +All images in this directory are free, released under the GPLv3 or later.
\ No newline at end of file diff --git a/html/display_panel/content/background-panel.png b/html/display_panel/content/background-panel.png Binary files differnew file mode 100644 index 0000000..022ffb3 --- /dev/null +++ b/html/display_panel/content/background-panel.png diff --git a/html/display_panel/content/display-panel.html b/html/display_panel/content/display-panel.html new file mode 100644 index 0000000..9ef3eef --- /dev/null +++ b/html/display_panel/content/display-panel.html @@ -0,0 +1,73 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"/> +<title>Display JS Monitoring Panel</title> +<link rel="stylesheet" type="text/css" href="./panel-styles.css"/> + +<!-- /** + * GNU LibreJS - A browser add-on to block nonfree nontrivial JavaScript. + * * + * Copyright (C) 2011, 2012, 2014 Loic J. Duros + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +--> +</head> + +<body> + <script src="main_panel.js"></script> + <div class="title-area"> + <div> + <a class="libre" + id="ljs-settings" + href="javascript:void" + title="LibreJS Whitelist Settings"> + <h1 class="libre">LibreJS</h1> + </a> + </div> + <div> + <a target="_blank" href="https://www.gnu.org/software/librejs/" + id="librejs-web-link" + >gnu.org/software/librejs</a> + </div> + <div> + <strong>LibreJS 6.0.13</strong> + </div> + </div> + + <div id="info"> + <div id="dryrun"> + <h2 class="dryrun-js"></h2> + <ul class="dryrun-js"></ul> + </div> + + <div id="accepted"> + <h2 class="accepted-js"></h2> + <ul class="accepted-js"></ul> + </div> + + <div id="blocked"> + <h2 class="blocked-js"></h2> + <ul class="blocked-js"> + </div> + + <div id="librejs-web-labels-pages"> + <h2></h2> + <ul></ul> + </div> + </div> +</body> +</html> diff --git a/html/display_panel/content/librejs-title-old.png b/html/display_panel/content/librejs-title-old.png Binary files differnew file mode 100644 index 0000000..8a11527 --- /dev/null +++ b/html/display_panel/content/librejs-title-old.png diff --git a/html/display_panel/content/librejs-title.png b/html/display_panel/content/librejs-title.png Binary files differnew file mode 100644 index 0000000..c1a911c --- /dev/null +++ b/html/display_panel/content/librejs-title.png diff --git a/html/display_panel/content/main_panel.js b/html/display_panel/content/main_panel.js new file mode 100644 index 0000000..3bcb164 --- /dev/null +++ b/html/display_panel/content/main_panel.js @@ -0,0 +1,96 @@ +/** +* +* Sets global variable "webex" to either "chrome" or "browser" for +* use on Chrome or a Firefox variant. +* +* Change this to support a new browser that isn't Chrome or Firefox, +* given that it supports webExtensions. +* +* (Use the variable "webex" for all API calls after calling this) +*/ +var webex; +function set_webex(){ + if(typeof(browser) == "undefined"){ + webex = chrome; + } else{ + webex = browser; + } +} +set_webex(); + +/** +* update the HTML of the pop-up window. +* If return_HTML is true, it returns the HTML of the popup window without updating it. +* example input: +* +* var example_input = { +* "accepted": [["REASON 1","SOURCE 1"],["REASON 2","SOURCE 2"]], +* "blocked": [["REASON 1","SOURCE 1"],["REASON 2","SOURCE 2"]], +* "url": "example.com" +* } +* +*/ +function generate_HTML(blocked_data){ + var a = blocked_data; + var button_complain = '<a id="complain-contact" class="button white" href="#"><span>Complain to site owner</span></a>'; + var button_allow_all = '<a id="allow-button" class="button white" href="#"><span>Allow all scripts in this page</span></a>'; + var button_block_nonfree = '<a id="disallow-button" class="button white" href="#"><span>Block all nonfree/nontrivial scripts from this page</span></a>'; + var button_new_tab = '<a id="open-in-tab" class="button white" href="#"><span>Open this report in a new tab</span></a>'; + var htmlDoc = document;// Not neccessary + var accept = htmlDoc.getElementById("accepted"); + var blocked = htmlDoc.getElementById("blocked"); + // HTML taken directly from the current LibreJS, display-panel.html + if(a["accepted"].length == 0){ + accept.innerHTML = '<li>LibreJS did not allow the execution of any scripts on this page: \n\n<ul><li>There may be no scripts on this page (check source, C-u)</li><li>The inline and on-page JavaScript code may not be free and/or may not have proper license information and external scripts (if present) may have been removed by default.</li><li>External scripts may not be free and/or may not have proper licensing and are not part of the whitelist of free JavaScript libraries.</li></ul></li>'; + } else{ + accept.innerHTML = ""; + accept.innerHTML = '<h2 class="accepted-js">List of <div style="color: green;">ACCEPTED</div> javascript in '+a["url"]+':</h2>'; + accept.innerHTML += '<ul class="accepted-js">'; + } + // Iterate over a["accepted"] and generate bulleted list + for(var i = 0; i < a["accepted"].length; i++){ + accept.innerHTML += "<li>"; + accept.innerHTML += a["accepted"][i][0] + "<br>" + a["accepted"][i][1]; + accept.innerHTML += "</li>"; + } + if(a["accepted"].length != 0){ + accept.innerHTML += "</ul>"; + } + // HTML taken directly from the current LibreJS, display-panel.html + if(a["blocked"].length == 0){ + blocked.innerHTML += '<li>LibreJS did not block any scripts on this page: \n\n<ul><li>There may be no scripts on this page (check source, C-u).</li><li>All the scripts on this page may be trivial and/or free.</li><li>You may have whitelisted this domain name or url from the preferences (Type about:addons in your location bar to check)</li><li>You may have clicked the "allow all scripts" button, which causes LibreJS to load all JavaScript on a page regardless of whether it is free, trivial, nontrivial or nonfree. This policy is effective for the entire duration of a Firefox session.</li><li>If for any reason you think LibreJS should have blocked JavaScript code on this page, please report this issue to: <a id="report" href="mailto:bug-librejs@gnu.org" target="_blank">bug-librejs@gnu.org</a></li></ul></li>'; + } else{ + blocked.innerHTML = ""; + blocked.innerHTML = "<h2 class='blocked-js'>List of <div style='color: red;'>BLOCKED</div> javascript in" + a["url"]+":</h2>"; + blocked.innerHTML += '<ul class="blocked-js">'; + } + // Iterate over a["blocked"] and generate bulleted list + for(var i = 0; i < a["blocked"].length; i++){ + blocked.innerHTML += "<li>"; + blocked.innerHTML += a["blocked"][i][0]+ "<br>" + a["blocked"][i][1]; + blocked.innerHTML += "</li>"; + } + if(a["blocked"].length != 0){ + blocked.innerHTML += "</ul>"; + } + // At this point, it has the HTML that the popup needs and the only problem is + // getting it into the popup. (browserAction() needs a (local) URL to work). + +} + + +// content-script.js + +var myPort = webex.runtime.connect({name:"port-from-cs"}); + +myPort.onMessage.addListener(function(m) { + if(m["show_info"] !== undefined){ + generate_HTML(m["show_info"]); + } +}); +function onGot(tabInfo) { + myPort.postMessage({"tab_info": tabInfo}); +} +var gettingCurrent = webex.tabs.getCurrent(onGot); + + diff --git a/html/display_panel/content/panel-styles.css b/html/display_panel/content/panel-styles.css new file mode 100644 index 0000000..2e5223b --- /dev/null +++ b/html/display_panel/content/panel-styles.css @@ -0,0 +1,190 @@ +/** + * GNU LibreJS - A browser add-on to block nonfree nontrivial JavaScript. + * * + * Copyright (C) 2011, 2012, 2014 Loic J. Duros + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +html { + padding:10px; + color:#000 !important; + background:url('background-panel.png') !important; +} +document { + padding:10px; +} +body { + padding:10px; + font-size:67.5%; + overflow-x:hidden; + overflow-y:visible; + color:#000; +} + +.libre { + width:230px; + height:104px; + display:block; + margin-bottom: 4px; +} +h1.libre { + font-size:1.5em; + font-weight:normal; + font-family:Arial; + margin:-20px 0 0 0; + padding:0; + font-weight:bold; + background:url('librejs-title.png') no-repeat top left; + text-indent:-1000px; + overflow:hidden; +} +h2 { + font-size:1.5em; + font-weight:bold; + font-family:arial; + border-bottom:4px solid #444; + padding-bottom:0; + margin:30px 0 0 0; + width:710px; + line-height:140%; +} +code { + font-size:1.2em; + margin:0; + padding:0; +} +ul { + margin:0; + padding:0; + list-style:none; +} +ul.blocked-js li, ul.accepted-js li, ul.dryrun-js li { + padding:5px; + border-bottom:2px solid #CCC; + margin:0; + width:700px; +} + +ul ul { + margin:10px; + list-style:disc; +} +ul.blocked-js ul li, ul.accepted-js ul li, ul.dryrun-js ul li { + padding:5px; + border-bottom:0; + width:auto; +} +#info { + clear:both; +} +.button { + float:right; + padding:10px; + display:none; + clear:both; + margin:10px; +} + +/* + Pure JS button styles below taken from: + http://webdesignerwall.com/tutorials/css3-gradient-buttons + */ +.button { + display: inline-block; + outline: none; + cursor: pointer; + text-align: center; + text-decoration: none; + font: 14px/100% Arial, Helvetica, sans-serif; + padding: .5em 2em .55em; + text-shadow: 0 1px 1px rgba(0,0,0,.3); + -webkit-border-radius: .5em; + -moz-border-radius: .5em; + border-radius: .5em; + -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.2); + -moz-box-shadow: 0 1px 2px rgba(0,0,0,.2); + box-shadow: 0 1px 2px rgba(0,0,0,.2); +} +.small.button { + font-size:11px; + padding:.5em .5em; + margin-top:10px; +} +.button:hover { + text-decoration: none; +} +.button:active { + position: relative; + top: 1px; +} +.orange { + color: #fef4e9; + border: solid 1px #da7c0c; + background: #f78d1d; + background: -webkit-gradient(linear, left top, left bottom, from(#faa51a), to(#f47a20)); + background: -moz-linear-gradient(top, #faa51a, #f47a20); +} +.orange:hover { + background: #f47c20; + background: -webkit-gradient(linear, left top, left bottom, from(#f88e11), to(#f06015)); + background: -moz-linear-gradient(top, #f88e11, #f06015); +} +.orange:active { + color: #fcd3a5; + background: -webkit-gradient(linear, left top, left bottom, from(#f47a20), to(#faa51a)); + background: -moz-linear-gradient(top, #f47a20, #faa51a); +} +.white { + background: -moz-linear-gradient(center top , #FFFFFF, #EDEDED) repeat scroll 0 0 transparent; + border: 1px solid #B7B7B7; + /* color: #606060;*/ + color:#9d0d0d; +} +.white:hover { + background: -moz-linear-gradient(center top , #FFFFFF, #DCDCDC) repeat scroll 0 0 transparent; +} +.white:active { + background: -moz-linear-gradient(center top , #EDEDED, #FFFFFF) repeat scroll 0 0 transparent; +/*color: #999999;*/ + +} + +span.accepted, span.blocked { + color:#008e00; + font-size:145%; + font-variant:small-caps; + font-weight:bold; +} +ul.blocked-js li { + overflow:hidden; +} +span.blocked { + color:#8e0000; +} + +.title-area { + width: 230px; + text-align: center; +} + +.title-area #librejs-web-link { + font-size: 18px; +} + +#librejs-web-labels-pages>ul { + margin-top: 8px; + font-size: 14px; + list-style-type: disc; +}
\ No newline at end of file diff --git a/html/preferences_panel/pref.js b/html/preferences_panel/pref.js new file mode 100644 index 0000000..aa88f5d --- /dev/null +++ b/html/preferences_panel/pref.js @@ -0,0 +1,56 @@ +/** +* +* Sets global variable "webex" to either "chrome" or "browser" for +* use on Chrome or a Firefox variant. +* +* Change this to support a new browser that isn't Chrome or Firefox, +* given that it supports webExtensions. +* +* (Use the variable "webex" for all API calls after calling this) +*/ +var store; +function set_webex(){ + if(typeof(browser) == "undefined"){ + webex = chrome; + } else{ + webex = browser; + } +} +set_webex(); + +function storage_got(items){ + var inputs = document.getElementsByTagName("input"); + for(var i = 0; i < inputs.length; i++){ + if(inputs[i].id.indexOf("pref_") != -1){ + if(inputs[i].type == "checkbox" && items[inputs[i].id]){ + inputs[i].checked = true; + } + if(inputs[i].type == "text"){ + inputs[i].value = items[inputs[i].id]; + } + } + } +} +webex.storage.local.get(storage_got); + +document.getElementById("save_changes").addEventListener("click", function(){ + var inputs = document.getElementsByTagName("input"); + // TODO: validate/sanitize the user inputs + var data = {}; + for(var i = 0; i < inputs.length; i++){ + if(inputs[i].id.indexOf("pref_") != -1){ + var input_val = ""; + if(inputs[i].type == "checkbox"){ + input_val = inputs[i].checked; + } else{ + input_val = inputs[i].value; + } + var input_id = inputs[i].id; + data[input_id] = input_val; + } + } + console.log(data); + webex.storage.local.set(data); +}); + + diff --git a/html/preferences_panel/preferences_panel.html b/html/preferences_panel/preferences_panel.html new file mode 100644 index 0000000..5c5a217 --- /dev/null +++ b/html/preferences_panel/preferences_panel.html @@ -0,0 +1,63 @@ +<html> + <head> +<!-- /** + * GNU LibreJS - A browser add-on to block nonfree nontrivial JavaScript. + * * + * Copyright (C) 2011, 2012, 2014 Loic J. Duros + * Copyright (C) 2014, 2015 Nik Nyby + * + * This file is part of GNU LibreJS. + * + * GNU LibreJS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNU LibreJS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU LibreJS. If not, see <http://www.gnu.org/licenses/>. + */ +--> + <title> + LibreJS preferences + </title> + </head> + + <body> + <h3> + LibreJS Preferences + </h3> + + <table> + <tr> + <td><p>Whitelist domains, seperated by comma (wildcard is *)</p></td> + <td><input id="pref_whitelist" type="text"></input></td> + </tr> + <tr> + <td><p>Display complaint tab on sites where nonfree nontrivial Javascript detected</p></td> + <td><input id="pref_complaint_tab" type="checkbox"></input></td> + </tr> + <tr> + <td><p>Display notifications of the JavaScript code being analyzed by LibreJS</p></td> + <td><input id="pref_notify_analyze" type="checkbox"></input></td> + </tr> + <tr> + <td><p>Default complaint email subject</p></td> + <td><input id="pref_subject" type="text"></input></td> + </tr> + <tr> + <td><p>Default complaint email body</p></td> + <td><input id="pref_body" type="text"></input></td> + </tr> + <tr> + <td><input type="button" value="Save changes" id="save_changes"></input></td> + <td></td> + </tr> + </table> + <script type="text/javascript" src="pref.js"></script> + </body> +</html> diff --git a/html/report_page/report.html b/html/report_page/report.html new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/html/report_page/report.html diff --git a/html/report_page/report.js b/html/report_page/report.js new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/html/report_page/report.js diff --git a/icons/librejs.png b/icons/librejs.png Binary files differnew file mode 100644 index 0000000..82ac632 --- /dev/null +++ b/icons/librejs.png diff --git a/main_background.js b/main_background.js new file mode 100644 index 0000000..300cfb7 --- /dev/null +++ b/main_background.js @@ -0,0 +1,161 @@ +console.debug("main_background.js"); + +/** +* +* Sets global variable "webex" to either "chrome" or "browser" for +* use on Chrome or a Firefox variant. +* +* Change this to support a new browser that isn't Chrome or Firefox, +* given that it supports webExtensions. +* +* (Use the variable "webex" for all API calls after calling this) +*/ +var webex; +function set_webex(){ + if(typeof(browser) == "undefined"){ + webex = chrome; + } else{ + webex = browser; + } +} + +/* +* +* Called when something changes the persistent data of the add-on. +* +* The only things that should need to change this data are: +* a) The "Whitelist this page" button +* b) The options screen +* +* When the actual blocking is implemented, this will need to comminicate +* with its code to update accordingly +* +*/ +function options_listener(changes, area){ + console.log("Items updated in area" + area +": "); + + var changedItems = Object.keys(changes); + var changed_items = ""; + for (var item of changedItems) { + changed_items += item + ","; + } + console.log(changed_items); + +} +/** +* Executes the "Display this report in new tab" function +* by opening a new tab with whatever HTML is in the popup +* at the moment. +*/ +function open_popup_tab(){ + function gotPopup(popupURL){ + var creating = webex.tabs.create({"url":popupURL}); + } + + var gettingPopup = webex.browserAction.getPopup({},gotPopup); +} + +/** +* +* This is what you call when a page gets changed to update the info box. +* +* Sends a message to the content script that updates the popup for a page. +* +* +* var example_blocked_info = { +* "accepted": [["REASON 1","SOURCE 1"],["REASON 2","SOURCE 2"]], +* "blocked": [["REASON 1","SOURCE 1"],["REASON 2","SOURCE 2"]], +* "url": "example.com" +* } +* +*/ + +var active_connections = {}; +var unused_data = {}; +function update_popup(tab_id,blocked_info){ + // this will happen almost every time (browser action not opened before javascript has been filtered) + // store the blocked info until it is opened and needed + if(active_connections[tab_id] === undefined){ + console.log("[TABID:"+tab_id+"]"+"Storing blocked_info for when the browser action is opened."); + unused_data[tab_id] = blocked_info; + } else{ + console.log("[TABID:"+tab_id+"]"+"Sending blocked_info directly to browser action"); + active_connections[tab_id].postMessage({"show_info":blocked_info}); + delete active_connections[tab_id]; + } +} +/** +* +* This is the callback where the content scripts of the browser action will contact the background script. +* +*/ +var portFromCS; +function connected(p) { + console.log(p); + p.onMessage.addListener(function(m) { + function logTabs(tabs) { + for(let tab of tabs) { + var tab_id = tab["id"] + console.log(tab_id) + if(unused_data[tab_id] !== undefined){ + // If we have some data stored here for this tabID, send it and then delete our copy + console.log("[TABID:"+tab_id+"]"+"Sending stored data associated with browser action"); + p.postMessage({"show_info":unused_data[tab_id]}); + } else{ + // create a new entry + unused_data[tab_id] = {"url":tab["url"],"blocked":"","accepted":""}; + p.postMessage({"show_info":unused_data[tab_id]}); + console.log("[TABID:"+tab_id+"]"+"No data found, creating a new entry for this window."); + } + } + } + var querying = webex.tabs.query({active: true,currentWindow: true},logTabs); + + }); +} + +/** +* The callback for tab closings. +* +* Delete the info we are storing about this tab if there is any. +* +*/ +function delete_removed_tab_info(tab_id, remove_info){ + console.log("[TABID:"+tab_id+"]"+"Deleting stored info about closed tab"); + if(unused_data[tab_id] !== undefined){ + delete unused_data[tab_id]; + } + if(active_connections[tab_id] !== undefined){ + delete active_connections[tab_id]; + } +} + + +/** +* Initializes various add-on functions +* only meant to be called once when the script starts +*/ +function init_addon(){ + set_webex(); + webex.runtime.onConnect.addListener(connected); + webex.storage.onChanged.addListener(options_listener); + webex.tabs.onRemoved.addListener(delete_removed_tab_info); +} + + +init_addon(); + +// some misc. debugging: +var example_input = { + "accepted": [["FILENAME 1","REASON 1"],["FILENAME 2","REASON 2"]], + "blocked": [["FILENAME 1","REASON 1"],["FILENAME 2","REASON 2"]], + "url":"example.com" +} +example_input["accepted"] = []; +example_input["blocked"] = []; + +//open_popup_tab(); + + + + diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..4d6825a --- /dev/null +++ b/manifest.json @@ -0,0 +1,44 @@ +{ + "manifest_version": 2, + "name": "GNU LibreJS [webExtensions]", + "short_name": "LibreJS [experimental]", + "version": "1.0", + "author": "See file 'authors'", + "description": "Only allows free and/or trivial Javascript to run.", + "applications": { + "gecko": { + "id": "bug-librejs@gnu.org", + "strict_min_version": "42.0" + } + }, + "icons":{ + "64": "icons/librejs.png" + }, + "permissions": [ + "contextMenus", + "webRequest", + "webRequestBlocking", + "activeTab", + "notifications", + "storage", + "tabs" + ], + "browser_action": { + "browser_style": true, + "default_icon": { + "64": "icons/librejs.png" + }, + "default_title": "LibreJS", + "default_popup": "html/display_panel/content/display-panel.html" + }, + "options_ui": { + "page": "html/preferences_panel/preferences_panel.html" + }, + "web_accessible_resources": [ + "html/report_page/report.html" + ], + "background": { + "scripts": ["main_background.js"] + } + +} |