├── .gitignore
├── README.md
├── makexpi.sh
├── version.py
└── xpi
├── GPL.txt
├── NoScript_License.txt
├── bootstrap.js
├── chrome.manifest
├── chrome
├── content
│ └── noscript
│ │ ├── ABE.g
│ │ ├── ABE.js
│ │ ├── ABELexer.js
│ │ ├── ABEParser.js
│ │ ├── ASPIdiocy.js
│ │ ├── AddressMatcher.js
│ │ ├── Bug.js
│ │ ├── ChannelReplacement.js
│ │ ├── ClearClickHandler.js
│ │ ├── Cookie.js
│ │ ├── DNS.js
│ │ ├── DOM.js
│ │ ├── DoNotTrack.js
│ │ ├── Entities.js
│ │ ├── ExternalFilters.js
│ │ ├── FlashIdiocy.js
│ │ ├── ForcedRedirectionCallback.js
│ │ ├── FrameScript.jsm
│ │ ├── HTTPS.js
│ │ ├── IO.js
│ │ ├── IOUtil.js
│ │ ├── InjectionChecker.js
│ │ ├── JSURL.js
│ │ ├── Lang.js
│ │ ├── MSEInterception.js
│ │ ├── Main.js
│ │ ├── MainChild.js
│ │ ├── MainParent.js
│ │ ├── Membrane.js
│ │ ├── MimeService.js
│ │ ├── MimeServiceParent.js
│ │ ├── NoScript_License.txt
│ │ ├── PasteHandler.jsm
│ │ ├── Plugins.js
│ │ ├── Policy.js
│ │ ├── Profiler.js
│ │ ├── RequestWatchdog.js
│ │ ├── Restartless.jsm
│ │ ├── ScriptSurrogate.js
│ │ ├── ScriptlessBGThumbs.js
│ │ ├── SiteUtils.js
│ │ ├── Strings.js
│ │ ├── SyntaxChecker.js
│ │ ├── Thread.js
│ │ ├── UISync.jsm
│ │ ├── URIValidator.js
│ │ ├── WebExt.js
│ │ ├── WebGLInterception.js
│ │ ├── WinScript.js
│ │ ├── about.xul
│ │ ├── antlr.js
│ │ ├── clearClick.js
│ │ ├── clearClick.xul
│ │ ├── defer.jsm
│ │ ├── e10sChild.js
│ │ ├── e10sIPC.js
│ │ ├── e10sParent.js
│ │ ├── e10sProcessScript.js
│ │ ├── frameScript.js
│ │ ├── iaUI.js
│ │ ├── importer.jsm
│ │ ├── loader.js
│ │ ├── noscript.js
│ │ ├── noscript.xbl
│ │ ├── noscriptBM.js
│ │ ├── noscriptBMOverlay.xul
│ │ ├── noscriptOptions.js
│ │ ├── noscriptOptions.xul
│ │ ├── noscriptOverlay-noStatusBar.xul
│ │ ├── noscriptOverlay.js
│ │ ├── noscriptOverlay.xul
│ │ └── tree-copy.js
├── locale
│ ├── ar
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── be-BY
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── bg-BG
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── bn-IN
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── ca-AD
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── cs-CZ
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── cy-GB
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── da
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── de
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── el
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── en-GB
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── en-US
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── eo
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── es-AR
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── es-CL
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── es-ES
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── et-EE
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── eu
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── fa-IR
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── fi
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── fr
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── gl-ES
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── he-IL
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── hr-HR
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── hsb
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── hu-HU
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── id-ID
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── it
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── ja-JP
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── kk-KZ
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── km-KH
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── ko-KR
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── lt
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── mk-MK
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── ms-MY
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── nb-NO
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── nl
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── pl
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── pt-BR
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── pt-PT
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── ro
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── ru-RU
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── sk-SK
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── sl-SI
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── sr-RS
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── sr
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── sv-SE
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── te-IN
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── th
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── tr
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── uk
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── vi
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ ├── zh-CN
│ │ └── noscript
│ │ │ ├── about.properties
│ │ │ ├── noscript.dtd
│ │ │ └── noscript.properties
│ └── zh-TW
│ │ └── noscript
│ │ ├── about.properties
│ │ ├── noscript.dtd
│ │ └── noscript.properties
└── skin
│ └── classic
│ └── noscript
│ ├── abe16.png
│ ├── about.css
│ ├── block.wav
│ ├── browser.css
│ ├── clearclick16.png
│ ├── close.png
│ ├── console16.png
│ ├── content.css
│ ├── ef-no16.png
│ ├── ef16.png
│ ├── emb16.png
│ ├── embed-no16.png
│ ├── embed16.png
│ ├── faq16.png
│ ├── flash16.png
│ ├── flash32.png
│ ├── folder_closed.png
│ ├── folder_open.png
│ ├── font.png
│ ├── glb-emb16.png
│ ├── glb-no16.png
│ ├── glb16.png
│ ├── https16.png
│ ├── ia.png
│ ├── icon24.png
│ ├── icon32.png
│ ├── icon64.png
│ ├── icon80.png
│ ├── inactive-emb16.png
│ ├── inactive-glb16.png
│ ├── inactive-no-emb16.png
│ ├── inactive-no16.png
│ ├── inactive-prt16.png
│ ├── inactive-yes16.png
│ ├── inactive-yu16.png
│ ├── java16.png
│ ├── java32.png
│ ├── mobile.css
│ ├── no-emb16.png
│ ├── no16.png
│ ├── options.css
│ ├── prt16.png
│ ├── redirect16.png
│ ├── revtemp16.png
│ ├── somelight16.png
│ ├── somelight32.png
│ ├── subprt16.png
│ ├── temp16.png
│ ├── unsafe-reload16.png
│ ├── untrusted-glb16.png
│ ├── untrusted16.png
│ ├── webgl16.png
│ ├── webgl32.png
│ ├── xss16.png
│ ├── yes16.png
│ ├── yu-emb16.png
│ ├── yu-glb16.png
│ └── yu16.png
├── components
└── noscriptService.js
├── defaults
└── preferences
│ └── noscript.js
├── install.rdf
├── mozilla.cfg
└── webextension
├── legacy.js
└── manifest.json
/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Unofficial NoScript version history
2 |
3 | This repository contains version history for the NoScript Firefox add-on **up
4 | to around March 2018**. **This repository is no longer being updated. It
5 | predates the official noscript repository on GitHub.**
6 |
7 | **As of July 2018, official noscript repository is [here](https://github.com/hackademix/noscript).**
8 |
9 | Files in the xpi/ subdirectory were automatically extracted from XPI files
10 | downloaded from https://addons.mozilla.org/en-US/firefox/addon/noscript.
11 |
12 | **This repository is not affiliated in any way with the developers of the
13 | NoScript add-on. Please do not report issues with NoScript itself here.
14 | Developers of the add-on can be reached at [noscript.net](https://noscript.net).**
15 |
16 | For some background on why this repository was created, see [this blog
17 | post](https://www.tablix.org/~avian/blog/archives/2012/02/too_much_noscript/).
18 |
19 | ## Building
20 |
21 | To build an XPI file, use `makexpi.sh` script:
22 |
23 | $ ./makexpi.sh [commit]
24 |
25 | ## License
26 |
27 | Following copyright notice appears in the latest version at the time of
28 | writing. Please refer to the files in the xpi/ subdirectory for details.
29 |
30 | NoScript - a Firefox extension for whitelist driven safe JavaScript execution
31 | Copyright (C) 2004-2014 Giorgio Maone - g.maone@informaction.com
32 |
33 | This program is free software; you can redistribute it and/or modify
34 | it under the terms of the GNU General Public License as published by
35 | the Free Software Foundation; either version 2 of the License, or
36 | (at your option) any later version.
37 |
38 | This program is distributed in the hope that it will be useful,
39 | but WITHOUT ANY WARRANTY; without even the implied warranty of
40 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
41 | GNU General Public License for more details.
42 |
43 | You should have received a copy of the GNU General Public License
44 | along with this program; if not, write to the
45 | Free Software Foundation, Inc.,
46 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
47 |
--------------------------------------------------------------------------------
/makexpi.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # builds a .xpi from the git repository, placing the .xpi in the root
3 | # of the repository.
4 | #
5 | # invoke with no arguments to build from the current src directory.
6 | #
7 | # ./makexpi.sh
8 | #
9 | # OR, invoke with a tag name to build a specific branch or tag.
10 | #
11 | # e.g.:
12 | #
13 | # ./makexpi.sh 0.2.3.development.2
14 | #
15 | # Script adapted from
16 | # https://gitweb.torproject.org/https-everywhere.git/blob/HEAD:/makexpi.sh
17 |
18 | set -e
19 |
20 | APP_NAME=noscript
21 |
22 | BUILDDIR=build
23 |
24 | cd "`dirname $0`"
25 |
26 | rm -rf "$BUILDDIR"
27 | mkdir "$BUILDDIR"
28 |
29 | # If the command line argument is a tag name, check that out and build it
30 | if [ -n "$1" ]; then
31 | cp -a .git "$BUILDDIR"
32 | cd "$BUILDDIR"
33 | git reset --hard "$1"
34 | else
35 | cp -a xpi "$BUILDDIR"
36 | cd "$BUILDDIR"
37 | fi
38 |
39 | # The name/version of the XPI we're building comes from manifest.json
40 | VERSION=`sed -ne '/"version":/{s/^.*: *"\(.*\)" *,.*$/\1/;p}' xpi/manifest.json`
41 | XPI_NAME="$APP_NAME-$VERSION"
42 | if [ "$1" ]; then
43 | XPI_NAME="$XPI_NAME.xpi"
44 | else
45 | XPI_NAME="$XPI_NAME~pre.xpi"
46 | fi
47 |
48 | ../version.py --add "$VERSION" xpi
49 |
50 | # Build the XPI!
51 | rm -f "../$XPI_NAME"
52 | (cd xpi && zip -q -r "../../$XPI_NAME" .)
53 |
--------------------------------------------------------------------------------
/version.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | import argparse
3 | import os
4 | import re
5 | from functools import partial
6 |
7 | def escape(match):
8 | g = match.group(1)
9 | if g is None:
10 | return b'@VERSION@'
11 | else:
12 | return b'@X' + g + b'VERSION@'
13 |
14 | def unescape(version, match):
15 | g = match.group(1)
16 | if g == b'':
17 | return version
18 | else:
19 | return b'@' + g[1:] + b'VERSION@'
20 |
21 | def main():
22 | parser = argparse.ArgumentParser(description='version placeholder tool for noscript')
23 | parser.add_argument('--add', action='store_true', help='add version string')
24 | parser.add_argument('--strip', action='store_true', help='strip version string')
25 | parser.add_argument('version', nargs=1, help='version string to add or strip')
26 | parser.add_argument('path', nargs=1, help='path to xpi source')
27 |
28 | args = parser.parse_args()
29 |
30 | version = args.version[0].encode('ascii')
31 | path = args.path[0]
32 |
33 | if args.add and (not args.strip):
34 | patt = re.compile(b'@(X*)VERSION@')
35 | func = partial(unescape, version)
36 | elif args.strip and (not args.add):
37 | patt = re.compile(re.escape(version) + b'|@(X*)VERSION@')
38 | func = escape
39 | else:
40 | print('Either --add or --strip must be specified')
41 | return
42 |
43 | path_patt = re.compile(r'\.(?:dtd|xul|js)$')
44 |
45 | for root, dirs, files in os.walk(path):
46 | for name in files:
47 | if not path_patt.search(name):
48 | continue
49 |
50 | filepath = os.path.join(root, name)
51 |
52 | with open(filepath, 'rb') as f:
53 | data = f.read()
54 |
55 | ndata = patt.sub(func, data)
56 | if ndata != data:
57 | with open(filepath, 'wb') as f:
58 | f.write(ndata)
59 |
60 | if __name__ == '__main__':
61 | main()
62 |
--------------------------------------------------------------------------------
/xpi/NoScript_License.txt:
--------------------------------------------------------------------------------
1 | NoScript - a Firefox extension for whitelist driven safe JavaScript execution
2 | Copyright (C) 2004-2014 Giorgio Maone - g.maone@informaction.com
3 |
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the
16 | Free Software Foundation, Inc.,
17 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 |
--------------------------------------------------------------------------------
/xpi/bootstrap.js:
--------------------------------------------------------------------------------
1 | var { utils: Cu, interfaces: Ci } = Components;
2 |
3 | Cu.import("resource://gre/modules/Services.jsm");
4 |
5 | let moduleURL = `chrome://noscript/content/Restartless.jsm?${Math.random() }.${Date.now()}`;
6 | let customizeStyle = "chrome://noscript/skin/browser.css";
7 | let module = {};
8 |
9 | function startup(data, reason) {
10 | Cu.import(moduleURL, module);
11 | module.startup(data, reason === APP_STARTUP); // Do whatever initial startup stuff you need to do
12 |
13 | if (module.loadIntoWindow) {
14 | forEachOpenWindow(module.loadIntoWindow);
15 | }
16 | Services.wm.addListener(WindowListener);
17 | }
18 |
19 | function shutdown(data, reason) {
20 | if (reason === APP_SHUTDOWN)
21 | return;
22 |
23 | Services.wm.removeListener(WindowListener);
24 |
25 | if (module.unloadFromWindow) forEachOpenWindow(module.unloadFromWindow);
26 |
27 |
28 | module.shutdown(data);
29 |
30 | Cu.unload(moduleURL);
31 | Services.obs.notifyObservers(null, "chrome-flush-caches", null);
32 | }
33 | function install(data, reason) { }
34 | function uninstall(data, reason) { }
35 |
36 | function forEachOpenWindow(todo) // Apply a function to all open browser windows
37 | {
38 | var windows = Services.wm.getEnumerator("navigator:browser");
39 | while (windows.hasMoreElements())
40 | todo(windows.getNext().QueryInterface(Ci.nsIDOMWindow));
41 | }
42 | var WindowListener =
43 | {
44 | onOpenWindow: function(xulWindow)
45 | {
46 | var window = xulWindow.QueryInterface(Ci.nsIInterfaceRequestor)
47 | .getInterface(Ci.nsIDOMWindow);
48 | function onWindowLoad()
49 | {
50 | window.removeEventListener("DOMContentLoad",onWindowLoad);
51 | let doc = window.document;
52 | if (doc.documentElement.getAttribute("windowtype") == "navigator:browser") {
53 | module.loadIntoWindow(window, true);
54 | } else if(window.location.href === "chrome://global/content/customizeToolbar.xul") {
55 | let root = doc.documentElement;
56 | let styleNode = doc.createProcessingInstruction("xml-stylesheet",`href="${customizeStyle}" type="text/css"`);
57 | doc.insertBefore(styleNode, root);
58 | }
59 | }
60 | window.addEventListener("DOMContentLoaded", onWindowLoad);
61 | },
62 | onCloseWindow: function(xulWindow) { },
63 | onWindowTitleChange: function(xulWindow, newTitle) { }
64 | };
65 |
--------------------------------------------------------------------------------
/xpi/chrome.manifest:
--------------------------------------------------------------------------------
1 | content noscript chrome/content/noscript/
2 |
3 | skin noscript classic/1.0 chrome/skin/classic/noscript/
4 |
5 | # Work around for breakages caused by the .NET Framework Assistant
6 | override chrome://dotnetassistant/content/bootstrap.xul data:text/xml,
7 |
8 | # Localization
9 | locale noscript ar chrome/locale/ar/noscript/
10 | locale noscript be-BY chrome/locale/be-BY/noscript/
11 | locale noscript bg-BG chrome/locale/bg-BG/noscript/
12 | locale noscript bn-IN chrome/locale/bn-IN/noscript/
13 | locale noscript ca-AD chrome/locale/ca-AD/noscript/
14 | locale noscript cs-CZ chrome/locale/cs-CZ/noscript/
15 | locale noscript cy-GB chrome/locale/cy-GB/noscript/
16 | locale noscript da chrome/locale/da/noscript/
17 | locale noscript de chrome/locale/de/noscript/
18 | locale noscript el chrome/locale/el/noscript/
19 | locale noscript en-GB chrome/locale/en-GB/noscript/
20 | locale noscript en-US chrome/locale/en-US/noscript/
21 | locale noscript eo chrome/locale/eo/noscript/
22 | locale noscript es-AR chrome/locale/es-AR/noscript/
23 | locale noscript es-CL chrome/locale/es-CL/noscript/
24 | locale noscript es-ES chrome/locale/es-ES/noscript/
25 | locale noscript et-EE chrome/locale/et-EE/noscript/
26 | locale noscript eu chrome/locale/eu/noscript/
27 | locale noscript fa-IR chrome/locale/fa-IR/noscript/
28 | locale noscript fi chrome/locale/fi/noscript/
29 | locale noscript fr chrome/locale/fr/noscript/
30 | locale noscript gl-ES chrome/locale/gl-ES/noscript/
31 | locale noscript he-IL chrome/locale/he-IL/noscript/
32 | locale noscript hr-HR chrome/locale/hr-HR/noscript/
33 | locale noscript hsb chrome/locale/hsb/noscript/
34 | locale noscript hu-HU chrome/locale/hu-HU/noscript/
35 | locale noscript id-ID chrome/locale/id-ID/noscript/
36 | locale noscript it chrome/locale/it/noscript/
37 | locale noscript ja-JP chrome/locale/ja-JP/noscript/
38 | locale noscript kk-KZ chrome/locale/kk-KZ/noscript/
39 | locale noscript km-KH chrome/locale/km-KH/noscript/
40 | locale noscript ko-KR chrome/locale/ko-KR/noscript/
41 | locale noscript lt chrome/locale/lt/noscript/
42 | locale noscript mk-MK chrome/locale/mk-MK/noscript/
43 | locale noscript ms-MY chrome/locale/ms-MY/noscript/
44 | locale noscript nb-NO chrome/locale/nb-NO/noscript/
45 | locale noscript nl chrome/locale/nl/noscript/
46 | locale noscript pl chrome/locale/pl/noscript/
47 | locale noscript pt-BR chrome/locale/pt-BR/noscript/
48 | locale noscript pt-PT chrome/locale/pt-PT/noscript/
49 | locale noscript ro chrome/locale/ro/noscript/
50 | locale noscript ru-RU chrome/locale/ru-RU/noscript/
51 | locale noscript sk-SK chrome/locale/sk-SK/noscript/
52 | locale noscript sl-SI chrome/locale/sl-SI/noscript/
53 | locale noscript sr chrome/locale/sr/noscript/
54 | locale noscript sr-RS chrome/locale/sr-RS/noscript/
55 | locale noscript sv-SE chrome/locale/sv-SE/noscript/
56 | locale noscript te-IN chrome/locale/te-IN/noscript/
57 | locale noscript th chrome/locale/th/noscript/
58 | locale noscript tr chrome/locale/tr/noscript/
59 | locale noscript uk chrome/locale/uk/noscript/
60 | locale noscript vi chrome/locale/vi/noscript/
61 | locale noscript zh-CN chrome/locale/zh-CN/noscript/
62 | locale noscript zh-TW chrome/locale/zh-TW/noscript/
63 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/ABE.g:
--------------------------------------------------------------------------------
1 | grammar ABE;
2 |
3 | options {
4 | language=JavaScript;
5 | output=AST;
6 | }
7 |
8 | tokens {
9 | T_ACTION;
10 | T_METHODS;
11 | }
12 |
13 | ruleset : rule* EOF ;
14 | rule : subject predicate+ -> subject predicate+ ;
15 | predicate : action methods? origin? -> T_ACTION action T_METHODS methods? origin? ;
16 | methods : (method+ | ALL) ;
17 | method : (HTTPVERB | SUB | inclusion) ;
18 | inclusion : INC (LPAR (INC_TYPE COMMA)* INC_TYPE? RPAR)? ;
19 | origin : T_FROM oresources ;
20 | subject : T_SITE resources ;
21 | oresources: (oresource+ | ALL) ;
22 | resources : (resource+ | ALL) ;
23 | oresource: resource | 'SELF' | 'SELF+' | 'SELF++' ;
24 | resource : REGEXP | GLOB | URI | LOCATION ;
25 | action : A_DENY | A_LOGOUT | A_SANDBOX | A_ACCEPT ;
26 |
27 | T_SITE : ('Site' | 'Request') ;
28 | T_FROM : ('f' | 'F') 'rom' ;
29 | A_DENY : 'Deny' ;
30 | A_LOGOUT : 'Logout' | 'Anon' 'ymize'? ;
31 | A_SANDBOX : 'Sandbox' ;
32 | A_ACCEPT : 'Accept' ;
33 |
34 | fragment URI_START : 'a'..'z' | '0'..'9' ;
35 | fragment URI_PART : 'a'..'z' | 'A'..'Z' | '0'..'9' | '_' | '-' | '.' |
36 | '[' | ']' | ':' | '/' | '@' | '~' | ';' | ',' |
37 | '?' | '&' | '=' | '%' | '#' ;
38 | LOCATION : 'LOCAL' ;
39 | URI : URI_START URI_PART+ ;
40 | GLOB : (URI_START | '*' | '.') (URI_PART | '*')* ;
41 | REGEXP : '^' ~'\n'+ ;
42 |
43 | ALL : 'ALL' ;
44 | SUB : 'SUB' ;
45 | INC : 'INC' 'LUSION'? ;
46 | HTTPVERB : 'GET' | 'POST' | 'PUT' | 'HEAD' | 'PATCH' | 'DELETE' | 'TRACE' | 'OPTIONS';nsI
47 | INC_TYPE : 'A'..'Z' ('A'..'Z' | 'A'..'Z' '_' 'A'..'Z')+ ;
48 |
49 |
50 | COMMA : ',' ;
51 | LPAR : '(' ;
52 | RPAR : ')' ;
53 |
54 | WS : (' '|'\r'|'\t'|'\u000C'|'\n') {$channel=HIDDEN;} ;
55 | COMMENT : '#' ~'\n'* {$channel=HIDDEN;} ;
56 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/Bug.js:
--------------------------------------------------------------------------------
1 | var Bug = {
2 |
3 | };
4 |
5 | {
6 | let lazy = {
7 | $677643: "8.0",
8 | $677050: ["6.0", "18.0"],
9 | $771655: "20",
10 | $789773: "19",
11 | }
12 | for (let b in lazy) {
13 | let v = lazy[b];
14 | Bug.__defineGetter__(b, function() {
15 | delete this[b];
16 | return this[b] = (typeof v[0] === "object")
17 | ? ns.geckoVersionCheck(v[0]) >= 0 && ns.geckoVersionCheck(v[1]) < 0
18 | : ns.geckoVersionCheck(v) < 0;
19 | });
20 | }
21 | }
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/ChannelReplacement.js:
--------------------------------------------------------------------------------
1 | function ChannelReplacement(chan, newURI, newMethod) {
2 | return this._init(chan, newURI, newMethod);
3 | }
4 |
5 | ChannelReplacement.runWhenPending = function(channel, callback) {
6 | callback();
7 | };
8 |
9 | ChannelReplacement.prototype = {
10 | _init: function(chan, newURI, newMethod) {
11 | this.oldChannel = this.channel = chan;
12 | this.newURI = newURI || chan.URI;
13 | this.newMethod = newMethod;
14 | return this;
15 | },
16 | replace: function(realRedirect, callback) {
17 | let chan = this.channel;
18 | if (!this.newURI.equals(chan.URI)) {
19 | realRedirect = true;
20 | }
21 | if (this.newMethod && this.newMethod !== chan.requestMethod) {
22 | chan.requestMethod = this.newMethod;
23 | realRedirect = true;
24 | }
25 |
26 | let forceRedirect = !realRedirect;
27 | if (forceRedirect) {
28 | chan.redirectionLimit += 1;
29 | } else {
30 | let loadInfo = chan.loadInfo;
31 | if (loadInfo) {
32 | let type = loadInfo.externalContentPolicyType || loadInfo.contentPolicyType;
33 | forceRedirect = type === 11 || type === 12;
34 | }
35 | }
36 |
37 | if (forceRedirect) {
38 | let ncb = chan.notificationCallbacks;
39 | if (ncb) {
40 | try {
41 | let ces = ncb.getInterface(Ci.nsIChannelEventSink);
42 | if (ces) {
43 | INCLUDE("ForcedRedirectionCallback");
44 | chan.notificationCallbacks = new NCBWrapper(ncb, new CESDelegate(ces));
45 | }
46 | } catch (e) {
47 | // notificationCallbacks might not implement nsIChannelEventSink, e.g. in live bookmarks
48 | }
49 | }
50 | }
51 |
52 |
53 | chan.redirectTo(this.newURI);
54 | chan.suspend();
55 | if (typeof callback === "function") callback(this);
56 | else this.open();
57 | },
58 | open: function() {
59 | this.channel.resume();
60 | }
61 | };
62 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/DoNotTrack.js:
--------------------------------------------------------------------------------
1 | var DoNotTrack = {
2 | enabled: true,
3 | exceptions: null,
4 | forced: null,
5 |
6 | init: function(prefs) {
7 | this.prefs = prefs;
8 | for (let k of prefs.getChildList("", {})) {
9 | this.observe(prefs, null, k);
10 | }
11 | prefs.addObserver("", this, true);
12 | },
13 | QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
14 | observe: function(prefs, topic, name) {
15 | switch(name) {
16 | case "enabled":
17 | this.enabled = prefs.getBoolPref(name);
18 | break;
19 | case "exceptions":
20 | case "forced":
21 | this[name] = AddressMatcher.create(COMPAT.getStringPref(prefs, name));
22 | break;
23 | }
24 | },
25 |
26 | apply: function(/* ABEReq */ req) {
27 | let url = req.destination;
28 |
29 | try {
30 | if (
31 | (this.exceptions && this.exceptions.test(url) ||
32 | req.localDestination ||
33 | req.isDoc && req.method === "POST" && req.originURI.host === req.destinationURI.host
34 | ) &&
35 | !(this.forced && this.forced.test(url))
36 | // TODO: find a way to check whether this request is gonna be WWW-authenticated
37 | )
38 | return;
39 |
40 | let channel = req.channel;
41 | channel.setRequestHeader("DNT", "1", false);
42 |
43 | // reorder headers to mirror Firefox 4's behavior
44 | let conn = channel.getRequestHeader("Connection");
45 | channel.setRequestHeader("Connection", "", false);
46 | channel.setRequestHeader("Connection", conn, false);
47 | } catch(e) {}
48 | },
49 |
50 | getDOMPatch: function(docShell) {
51 | try {
52 | if (docShell.document.defaultView.navigator.doNotTrack !== "1" &&
53 | docShell.currentDocumentChannel.getRequestHeader("DNT") === "1") {
54 | return 'Object.defineProperty(window.navigator, "doNotTrack", { configurable: true, enumerable: true, value: "1" });';
55 | }
56 | } catch (e) {}
57 | return "";
58 | },
59 | }
60 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/Entities.js:
--------------------------------------------------------------------------------
1 | var Entities = {
2 |
3 | get htmlNode() {
4 | delete this.htmlNode;
5 | var impl = Cc["@mozilla.org/xul/xul-document;1"].createInstance(Ci.nsIDOMDocument).implementation;
6 | return this.htmlNode = (("createHTMLDocument" in impl)
7 | ? impl.createHTMLDocument("")
8 | : impl.createDocument(
9 | HTML_NS, "html", impl.createDocumentType(
10 | "html", "-//W3C//DTD HTML 4.01 Transitional//EN", "http://www.w3.org/TR/html4/loose.dtd"
11 | ))
12 | ).createElementNS(HTML_NS, "body");
13 | },
14 | convert: function(e) {
15 | try {
16 | this.htmlNode.innerHTML = e;
17 | var child = this.htmlNode.firstChild || null;
18 | return child && child.nodeValue || e;
19 | } catch(ex) {
20 | return e;
21 | }
22 | },
23 | convertAll: function(s) {
24 | return s.replace(/[\\&][^<>]+/g, function(e) { return Entities.convert(e) });
25 | },
26 | convertDeep: function(s) {
27 | for (var prev = null; (s = this.convertAll(s)) !== prev || (s = unescape(s)) !== prev; prev = s);
28 | return s;
29 | },
30 | neutralize: function(e, whitelist) {
31 | var c = this.convert(e);
32 | return (c == e) ? c : (whitelist && whitelist.test(c) ? e : e.replace(";", ","));
33 | },
34 | neutralizeAll: function(s, whitelist) {
35 | return s.replace(/&[\w#-]*?;/g, function(e) { return Entities.neutralize(e, whitelist || null); });
36 | }
37 | };
38 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/FlashIdiocy.js:
--------------------------------------------------------------------------------
1 | FlashIdiocy.purgeBadEncodings = s => s.replace(/%(?:[0-9a-f]?(?:[^0-9a-f]|$))/ig, "");
2 | FlashIdiocy.platformDecode = s => s.replace(/%[8-9a-f][0-9a-f]/ig, s => FlashIdiocy.map[s.substring(1).toLowerCase()]);
3 |
4 | FlashIdiocy.map = {
5 | "80": "?",
6 | "81": "",
7 | "82": "?",
8 | "83": "?",
9 | "84": "?",
10 | "85": "?",
11 | "86": "?",
12 | "87": "?",
13 | "88": "?",
14 | "89": "?",
15 | "8a": "?",
16 | "8b": "?",
17 | "8c": "?",
18 | "8d": "",
19 | "8e": "?",
20 | "8f": "",
21 | "90": "",
22 | "91": "?",
23 | "92": "?",
24 | "93": "?",
25 | "94": "?",
26 | "95": "?",
27 | "96": "?",
28 | "97": "?",
29 | "98": "?",
30 | "99": "?",
31 | "9a": "?",
32 | "9b": "?",
33 | "9c": "?",
34 | "9d": "",
35 | "9e": "?",
36 | "9f": "?",
37 | "a0": " ",
38 | "a1": "¡",
39 | "a2": "¢",
40 | "a3": "£",
41 | "a4": "¤",
42 | "a5": "¥",
43 | "a6": "¦",
44 | "a7": "§",
45 | "a8": "¨",
46 | "a9": "©",
47 | "aa": "ª",
48 | "ab": "«",
49 | "ac": "¬",
50 | "ad": "",
51 | "ae": "®",
52 | "af": "¯",
53 | "b0": "°",
54 | "b1": "±",
55 | "b2": "²",
56 | "b3": "³",
57 | "b4": "´",
58 | "b5": "µ",
59 | "b6": "¶",
60 | "b7": "·",
61 | "b8": "¸",
62 | "b9": "¹",
63 | "ba": "º",
64 | "bb": "»",
65 | "bc": "¼",
66 | "bd": "½",
67 | "be": "¾",
68 | "bf": "¿",
69 | "c0": "À",
70 | "c1": "Á",
71 | "c2": "Â",
72 | "c3": "Ã",
73 | "c4": "Ä",
74 | "c5": "Å",
75 | "c6": "Æ",
76 | "c7": "Ç",
77 | "c8": "È",
78 | "c9": "É",
79 | "ca": "Ê",
80 | "cb": "Ë",
81 | "cc": "Ì",
82 | "cd": "Í",
83 | "ce": "Î",
84 | "cf": "Ï",
85 | "d0": "Ð",
86 | "d1": "Ñ",
87 | "d2": "Ò",
88 | "d3": "Ó",
89 | "d4": "Ô",
90 | "d5": "Õ",
91 | "d6": "Ö",
92 | "d7": "×",
93 | "d8": "Ø",
94 | "d9": "Ù",
95 | "da": "Ú",
96 | "db": "Û",
97 | "dc": "Ü",
98 | "dd": "Ý",
99 | "de": "Þ",
100 | "df": "ß",
101 | "e0": "à",
102 | "e1": "á",
103 | "e2": "â",
104 | "e3": "ã",
105 | "e4": "ä",
106 | "e5": "å",
107 | "e6": "æ",
108 | "e7": "ç",
109 | "e8": "è",
110 | "e9": "é",
111 | "ea": "ê",
112 | "eb": "ë",
113 | "ec": "ì",
114 | "ed": "í",
115 | "ee": "î",
116 | "ef": "ï",
117 | "f0": "ð",
118 | "f1": "ñ",
119 | "f2": "ò",
120 | "f3": "ó",
121 | "f4": "ô",
122 | "f5": "õ",
123 | "f6": "ö",
124 | "f7": "÷",
125 | "f8": "ø",
126 | "f9": "ù",
127 | "fa": "ú",
128 | "fb": "û",
129 | "fc": "ü",
130 | "fd": "ý",
131 | "fe": "þ",
132 | "ff": "ÿ",
133 | }
134 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/ForcedRedirectionCallback.js:
--------------------------------------------------------------------------------
1 |
2 | function NCBWrapper(delegator, delegate) {
3 | this.delegator = delegator;
4 | this.delegate = delegate;
5 | }
6 | NCBWrapper.prototype = {
7 | QueryInterface: function(iid) {
8 | if (Ci.nsIInterfaceRequestor.equals(iid)) {
9 | return this;
10 | }
11 | return this.delegator.QueryInterface(iid);
12 | },
13 | getInterface: function(iid) {
14 | try {
15 | return this.delegate.QueryInterface(iid);
16 | } catch (e) {}
17 | return this.delegator.getInterface(iid);
18 | }
19 | }
20 |
21 | function RCBDelegate(redirectCallback, label) {
22 | this.delegator = redirectCallback;
23 | this.label = label;
24 | }
25 | RCBDelegate.prototype = {
26 | QueryInterface: XPCOMUtils.generateQI([Ci.sIAsyncVerifyRedirectCallback]),
27 | onRedirectVerifyCallback: function(result) {
28 | try {
29 | if (result !== 0) ns.log("Overriding failed (" + result + ") redirect callback for " + this.label); // plugin failure is 2147500037
30 | this.delegator.onRedirectVerifyCallback(0);
31 | } catch (e) {
32 | ns.log(e);
33 | }
34 | }
35 | }
36 |
37 | function CESDelegate(ces) {
38 | this.delegator = ces;
39 | }
40 | CESDelegate.prototype = {
41 | QueryInterface: XPCOMUtils.generateQI([Ci.nsIChannelEventSink]),
42 | asyncOnChannelRedirect: function(oldChan, newChan, flags, callback) {
43 | let label = "plugin forced redirection";
44 | try {
45 | label = (oldChan.loadInfo.externalContentPolicyType || oldChan.loadInfo.contentPolicyType)+ ": " + oldChan.name + " -> " + newChan.name + " - " + flags;
46 | } catch (e) {
47 | ns.log(e);
48 | }
49 | let cb = new RCBDelegate(callback, label);
50 | try {
51 | this.delegator.asyncOnChannelRedirect(oldChan, newChan, Ci.nsIChannelEventSink.REDIRECT_INTERNAL, cb);
52 | } catch (e) {
53 | ns.log(e);
54 | throw e;
55 | } finally {
56 | oldChan.notificationCallbacks = newChan.notificationCallbacks = this.delegator;
57 | }
58 | }
59 | };
60 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/FrameScript.jsm:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var EXPORTED_SYMBOLS = ["FrameScript"];
4 |
5 | const { utils: Cu, interfaces: Ci, classes: Cc } = Components;
6 |
7 | Cu.import("resource://gre/modules/Services.jsm");
8 | Cu.import("resource://gre/modules/XPCOMUtils.jsm");
9 |
10 | const SERVICE_READY = "NoScript.ServiceReady";
11 | const SERVICE_DISPOSE = "NoScript.Dispose";
12 |
13 | Cu.import("chrome://noscript/content/importer.jsm");
14 | let IMPORT = IMPORT_FOR(this);
15 | IMPORT("PasteHandler");
16 | IMPORT("UISync");
17 |
18 | function FrameScript(ctx) {
19 | Object.defineProperty(ctx, "ns", {
20 | get: function() {
21 | try {
22 | const CTRID = "@maone.net/noscript-service;1";
23 | if (CTRID in Cc) {
24 | let ns = Cc[CTRID].getService().wrappedJSObject;
25 | delete this.ns;
26 | return (this.ns = ns);
27 | }
28 | } catch(e) {
29 | Cu.reportError(e);
30 | }
31 | return null;
32 | },
33 | configurable: true,
34 | enumerable: true
35 | });
36 |
37 | this.ctx = ctx;
38 |
39 | if (ctx.ns) {
40 | this.init();
41 | } else {
42 | Services.obs.addObserver(this, SERVICE_READY, true);
43 | }
44 |
45 | }
46 |
47 | FrameScript.prototype = {
48 | QueryInterface: XPCOMUtils.generateQI(
49 | [Ci.nsIObserver, Ci.nsISupportsWeakReference]),
50 | init() {
51 | if (this.uiSync) return;
52 |
53 | let ctx = this.ctx;
54 | this.pasteHandler = new PasteHandler(ctx);
55 | this.uiSync = new UISync(ctx);
56 | ctx.addMessageListener("NoScript:unload", this);
57 | Services.obs.addObserver(this, SERVICE_DISPOSE, true);
58 | let ns = ctx.ns;
59 | if (ns.consoleDump && ctx.content && ctx.content.location)
60 | ns.dump(`Framescript initialized in ${ctx.content.location.href}`);
61 | },
62 | observe(subj, topic, data) {
63 | switch(topic) {
64 | case SERVICE_READY:
65 | this.init();
66 | break;
67 | case SERVICE_DISPOSE:
68 | this.dispose();
69 | break;
70 | }
71 | },
72 | receiveMessage(m) {
73 | if (m.name === "NoScript:unload") {
74 | this.dispose();
75 | }
76 | },
77 | dispose() {
78 | if (!this.uiSync) return;
79 | this.pasteHandler.dispose();
80 | this.uiSync.unwire();
81 | this.uiSync = this.pasteHandler = null;
82 | let ctx = this.ctx;
83 | let ns = ctx.ns;
84 | if (ns.consoleDump && ctx.content && ctx.content.location)
85 | this.ctx.ns.dump(`Framescript disposed in ${this.ctx.content.location.href}`);
86 | }
87 | };
88 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/IO.js:
--------------------------------------------------------------------------------
1 | var IO = {
2 | readFile: function(file, charset) {
3 | var res;
4 |
5 | const is = Cc["@mozilla.org/network/file-input-stream;1"]
6 | .createInstance(Ci.nsIFileInputStream );
7 | is.init(file ,0x01, 256 /*0400*/, null);
8 | const sis = Cc["@mozilla.org/scriptableinputstream;1"]
9 | .createInstance(Ci.nsIScriptableInputStream);
10 | sis.init(is);
11 |
12 | res = sis.read(sis.available());
13 | is.close();
14 |
15 | if (charset !== null) { // use "null" if you want uncoverted data...
16 | const unicodeConverter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
17 | .createInstance(Ci.nsIScriptableUnicodeConverter);
18 | try {
19 | unicodeConverter.charset = charset || "UTF-8";
20 | } catch(ex) {
21 | unicodeConverter.charset = "UTF-8";
22 | }
23 | res = unicodeConverter.ConvertToUnicode(res);
24 | }
25 |
26 | return res;
27 | },
28 | writeFile: function(file, content, charset) {
29 | const unicodeConverter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
30 | .createInstance(Ci.nsIScriptableUnicodeConverter);
31 | try {
32 | unicodeConverter.charset = charset || "UTF-8";
33 | } catch(ex) {
34 | unicodeConverter.charset = "UTF-8";
35 | }
36 |
37 | content = unicodeConverter.ConvertFromUnicode(content);
38 | const os = Cc["@mozilla.org/network/file-output-stream;1"]
39 | .createInstance(Ci.nsIFileOutputStream);
40 | os.init(file, 0x02 | 0x08 | 0x20, 448 /*0700*/, 0);
41 | os.write(content, content.length);
42 | os.close();
43 | },
44 |
45 | safeWriteFile: function(file, content, charset) {
46 | var tmp = file.clone();
47 | var name = file.leafName;
48 | tmp.leafName = name + ".tmp";
49 | tmp.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, file.exists() ? file.permissions : 384 /*0600*/);
50 | this.writeFile(tmp, content, charset);
51 | tmp.moveTo(file.parent, name);
52 | }
53 | };
54 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/JSURL.js:
--------------------------------------------------------------------------------
1 | var JSURL = {
2 | JS_VERSION: "1.8",
3 | load: function(url, document) {
4 | this._run(document, url.substring("javascript:".length)
5 | .replace(/(?:%[0-9a-f]{2})+/gi, function(m) {
6 | try {
7 | return decodeURIComponent(m);
8 | } catch (e) {}
9 | return unescape(m);
10 | }));
11 | },
12 |
13 | _patch: (function() {
14 | (function patchAll(w) {
15 | if (!w || w.open && w.open._bypass)
16 | return w;
17 |
18 | var d = w.document;
19 |
20 | function op(data) {
21 | var code = "Object.getPrototypeOf(document)." +
22 | (typeof(data) === "string"
23 | ? 'write.call(document, ' + JSON.stringify(data) + ')'
24 | : 'open.call(document)'
25 | );
26 | var s = d.createElement("script");
27 | s.appendChild(d.createTextNode(code));
28 | var p = d.documentElement;
29 | p.appendChild(s);
30 | p.removeChild(s);
31 | if (d.write === Object.getPrototypeOf(d).write) {
32 | patchAll(w);
33 | }
34 | }
35 | function patch(o, m, f) {
36 | var saved = o[m];
37 | f._restore = function() { o[m] = saved };
38 | f._bypass = saved;
39 | o[m] = f;
40 | }
41 |
42 | patch(d, "open", function() { op(null) });
43 | patch(d, "write", function(s) {
44 | op(typeof(s) === "string" ? s : "" + s);
45 | });
46 | patch(d, "writeln", function(s) { this.write(s + "\n") });
47 |
48 | patch(w, "open", function() {
49 | return patchAll(w.open._bypass.apply(w, arguments));
50 | });
51 |
52 | return w;
53 | })(window);
54 | }).toSource() + "()",
55 | _restore: (function() {
56 | var d = window.document;
57 | d.writeln._restore();
58 | d.write._restore();
59 | d.open._restore();
60 | }).toSource() + "()",
61 |
62 | _run: function(document, code) {
63 | var w = document.defaultView;
64 | var p = document.nodePrincipal;
65 | var s = ScriptSurrogate.createSandboxForWindow(w, p, {
66 | sandboxName: "NoScript::JSURL@" + document.documentURI,
67 | sandboxPrototype: w,
68 | wantXrays: false,
69 | });
70 | var e = (script) => Cu.evalInSandbox("with(window) {" + script + "}", s);
71 | try {
72 | e(this._patch);
73 | let ret = e(code);
74 | if (typeof ret !== "undefined" &&
75 | !DOM.getDocShellForWindow(w).isLoadingDocument) {
76 | s._ret_ = ret;
77 | e("window.location.href = 'javascript:' + JSON.stringify('' + this._ret_)");
78 | delete s._ret_;
79 | Thread.yieldAll();
80 | }
81 | } catch (e) {
82 | try { w.console.error("" + e) } catch(consoleError) { Cu.reportError(e) }
83 | } finally {
84 | try { e(this._restore) } catch(e) {}
85 | }
86 | },
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/Lang.js:
--------------------------------------------------------------------------------
1 | // language utilities
2 |
3 | const Lang = {
4 | memoize: function(obj, funcs) {
5 | for (var p in funcs) {
6 | this._memoizeMember(obj, p, funcs[p]);
7 | }
8 | return obj;
9 | },
10 | _memoizeMember: function(obj, prop, func) {
11 | obj.__defineGetter__(prop, function() {
12 | var r = func.apply(this);
13 | this.__defineGetter__(prop, function() { return r; });
14 | return r;
15 | });
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/MSEInterception.js:
--------------------------------------------------------------------------------
1 | var MSEInterception = {
2 | sites: {},
3 | handler(ev) {
4 | if (typeof ns === "undefined") {
5 | ev.currentTarget.removeEventListener(ev.type, argument.callee, true);
6 | return;
7 | }
8 | let target = ev.target;
9 | let mime = ev.detail.mime;
10 | let doc = target.ownerDocument || target;
11 | let url = doc.documentURI;
12 | let site = ns.getSite(url);
13 | if (ns.forbidMedia && ns.contentBlocker && !(ns.isAllowedObject(url, mime, site, site) || ns.isAllowedMime(mime, site))) {
14 | ev.preventDefault();
15 | ev.stopPropagation();
16 | ev.detail.blocked = true;
17 | MSEInterception.record(target, url, site, mime, true);
18 | }
19 | },
20 | record(ctx, url, site, mime, fromDOM) {
21 | let data = {
22 | url,
23 | site,
24 | originSite: site,
25 | mime
26 | };
27 | ns.tagForReplacement(ctx, data);
28 | ns.countObject(ctx, url);
29 | let doc = ctx.ownerDocument || ctx;
30 | if (fromDOM) {
31 | let ds = DOM.getDocShellForWindow(doc.defaultView);
32 | if (ds.isLoadingDocument) { // prevent fallback redirection from hiding us
33 | let sites = this.sites;
34 | sites[site] = data;
35 | doc.defaultView.addEventListener("load", () => delete sites[site], false);
36 | }
37 | }
38 | ns.recordBlocked(url, site);
39 | },
40 |
41 | get interceptionDef() {
42 | delete this.interceptionDef;
43 | return (this.interceptionDef = function() {
44 | let urlMap = new WeakMap();
45 | let createObjectURL = URL.createObjectURL;
46 | URL.createObjectURL = function(o, ...args) {
47 | let url = createObjectURL.call(this, o, ...args);
48 | if (o instanceof MediaSource) {
49 | let urls = urlMap.get(o);
50 | if (!urls) urlMap.set(o, urls = new Set());
51 | urls.add(url);
52 | }
53 | return url;
54 | };
55 | let proto = MediaSource.prototype;
56 | let addSourceBuffer = proto.addSourceBuffer;
57 | proto.addSourceBuffer = function(mime, ...args) {
58 | let ms = this;
59 | let urls = urlMap.get(ms);
60 | let me = Array.from(document.querySelectorAll("video,audio")).find(e => e.srcObject === ms || urls && urls.has(e.src));
61 | let exposedMime = `${mime} (MSE)`;
62 | let ev = new CustomEvent("NoScript:MSE", {cancelable: true, detail: { mime: exposedMime, blocked: false }});
63 |
64 | (me || document).dispatchEvent(ev);
65 |
66 | if (ev.detail.blocked) {
67 | throw new Error(`${exposedMime} blocked by NoScript`);
68 | }
69 | return addSourceBuffer.call(ms, mime, ...args);
70 | };
71 | }.toSource() + "()");
72 | },
73 | reloadAllowed(docShell) {
74 | let curURL = docShell.currentURI.spec;
75 | let site = ns.getSite(curURL);
76 | if (site in this.sites) {
77 | let {url} = this.sites[site];
78 | delete this.sites[site];
79 | if (url !== curURL) {
80 | docShell.loadURI(url, Ci.nsIWebNavigation.LOAD_FLAGS_NONE, null, null, null);
81 | return true;
82 | }
83 | }
84 | return false;
85 | },
86 | hook(doc, site) {
87 | let url = doc.documentURI;
88 | if (!(ns.isAllowedObject(url, "MSE", site, site) || ns.isAllowedMime("MSE", url))) {
89 | DOM.getFrameMM(doc.defaultView).addEventListener("NoScript:MSE", this.handler, true, true);
90 | if (site in this.sites) {
91 | let data = this.sites[site];
92 | this.record(doc, data.url, data.site, data.mime);
93 | }
94 | return this.interceptionDef;
95 | }
96 | return null;
97 | }
98 | };
99 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/Membrane.js:
--------------------------------------------------------------------------------
1 | var Membrane = {
2 | create(real, wrap) {
3 | let shadow = {};
4 | return new Proxy(shadow, {
5 | get: function(target, propKey, receiver) {
6 | var pd = Object.getOwnPropertyDescriptor(real, propKey);
7 | if (pd !== undefined && !pd.configurable && !pd.writable) {
8 | Object.defineProperty(target, propKey, {
9 | value: wrap(real, propKey, receiver),
10 | writable: false,
11 | configurable: false,
12 | enumerable: pd.enumerable
13 | });
14 | return target[propKey];
15 | }
16 | return wrap(real, propKey, receiver);
17 | }
18 | });
19 | }
20 | };
21 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/MimeService.js:
--------------------------------------------------------------------------------
1 | var MimeService = {
2 | _cache: new Map(),
3 | getTypeFromExtension(ext) {
4 | if (ext) {
5 | if (typeof ext !== "string") {
6 | Cu.reportError(`getTypeFromExtension ${ext}`);
7 | }
8 | let cache = this._cache;
9 | if (cache.has(ext)) {
10 | return cache.get(ext);
11 | }
12 | let res = Services.cpmm.sendSyncMessage("NoScript:getMime", {ext})[0];
13 | cache.set(ext, res);
14 | return res;
15 | }
16 | }
17 | };
18 |
19 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/MimeServiceParent.js:
--------------------------------------------------------------------------------
1 | var MimeService = {
2 | QueryInterface: XPCOMUtils.generateQI([Ci.nsIMessageListener, Ci.nsISupportsWeakReference]),
3 | service: Cc['@mozilla.org/uriloader/external-helper-app-service;1']
4 | .getService(Ci.nsIMIMEService),
5 | getTypeFromExtension(ext) {
6 | return this.service.getTypeFromExtension(ext);
7 | },
8 | receiveMessage(m) {
9 | if (m.name === "NoScript:getMime") {
10 | try {
11 | return this.getTypeFromExtension(m.data.ext);
12 | } catch (e) {
13 | ns.dump(`Could not guess mime type for ${m.data.ext}`);
14 | }
15 | }
16 | return '';
17 | }
18 | };
19 | Services.ppmm.addWeakMessageListener("NoScript:getMime", MimeService);
20 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/NoScript_License.txt:
--------------------------------------------------------------------------------
1 | NoScript - a Firefox extension for whitelist driven safe JavaScript execution
2 | Copyright (C) 2004-2014 Giorgio Maone - g.maone@informaction.com
3 |
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the
16 | Free Software Foundation, Inc.,
17 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/PasteHandler.jsm:
--------------------------------------------------------------------------------
1 | var EXPORTED_SYMBOLS = ["PasteHandler"];
2 |
3 | const Cu = Components.utils;
4 |
5 | Cu.import("chrome://noscript/content/importer.jsm");
6 | let IMPORT = IMPORT_FOR(this);
7 |
8 | function PasteHandler(ctx) {
9 | this.ctx = ctx;
10 | ctx.addEventListener("paste", pasteEventHandler, true);
11 | }
12 |
13 | PasteHandler.prototype = {
14 | dispose() {
15 | this.ctx.removeEventListener("paste", pasteEventHandler, true);
16 | }
17 | }
18 |
19 |
20 |
21 | function pasteEventHandler(e) {
22 | if (typeof Cu === "undefined") { // uninstalled
23 | e.currentTarget.removeEventListener(e.type, arguments.callee, true);
24 | return;
25 | }
26 | Cu.import("resource://gre/modules/Services.jsm");
27 | if (!Services.prefs.getBoolPref("noscript.sanitizePaste")) {
28 | return;
29 | }
30 | let data = e.clipboardData;
31 | let html = data.getData("text/html");
32 | let t = e.target;
33 | if (t.nodeType !== 1) t = t.parentElement;
34 |
35 | let console = t.ownerDocument.defaultView.console;
36 |
37 | try {
38 | let node = t.cloneNode();
39 |
40 | node.innerHTML = html;
41 |
42 | if (sanitizeExtras(node)) {
43 | let sanitized = node.innerHTML;
44 | IMPORT("defer");
45 | defer(function() { try {
46 | sanitizeExtras(t);
47 | console.log("[NoScript] Sanitized\n\n" + html + "\nto\n\n" + sanitized + "");
48 | } catch(ex) {
49 | console.log(ex);
50 | }}, 0);
51 | }
52 | } catch(ex) {
53 | console.log(ex);
54 | }
55 | }
56 |
57 | function sanitizeExtras(el) {
58 | let ret = false;
59 |
60 | // remove attributes from forms
61 | for (let f of el.getElementsByTagName("form")) {
62 | for (let a of f.attributes) {
63 | f.removeAttribute(a.name);
64 | ret = true;
65 | }
66 | }
67 |
68 | let doc = el.ownerDocument;
69 |
70 | // remove dangerous URLs (e.g. javascript: or data: URLs)
71 | for (let a of ['href', 'to', 'from', 'by', 'values']) {
72 | let res = doc.evaluate('//@' + a, el, null, /* DOMXPathResult.UNORDERED_NODE_SNAPSHOT_TYPE */ 6, null);
73 | for (let j = res.snapshotLength; j-- > 0;) {
74 | let attr = res.snapshotItem(j);
75 | if (/^\W*(?:(?:javascript|data):|https?:[\s\S]+[[(<])/i.test(unescape(attr.value))) {
76 | attr.value = "javascript:void(0)";
77 | ret = true;
78 | }
79 | }
80 | }
81 | return ret;
82 | }
83 |
84 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/Plugins.js:
--------------------------------------------------------------------------------
1 | var Plugins = {
2 | _disabled: false,
3 | get disabled() { return this._disabled; },
4 |
5 | _registrar: Components.manager.nsIComponentRegistrar,
6 | _CTRID: "@mozilla.org/plugin/host;1",
7 | get _CID() {
8 | delete this._CID;
9 | return this._CID = this._registrar.contractIDToCID(this._CTRID);
10 | },
11 | get _factory() {
12 | delete this._factory;
13 |
14 | return this._factory = Components.manager.getClassObject(Cc[this._CTRID], Ci.nsIFactory);
15 | },
16 |
17 | set disabled(b) {
18 | if (b == this._disabled) return b;
19 | if (b) {
20 | this._registrar.unregisterFactory(this._CID, this._factory);
21 | } else {
22 | this._registrar.registerFactory(this._CID, "PluginHost", this._CTRID, this._factory);
23 | }
24 | return this._disabled = !!b;
25 | }
26 |
27 | };
28 | // Gecko >= 2.0 seems to need the following to gets things rolling reliably
29 | Plugins.disabled = true;
30 | Plugins.disabled = false;
31 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/Profiler.js:
--------------------------------------------------------------------------------
1 | Profiler = {
2 | watchlist: { NoScript: ns, requestWatchdog: RequestWatchdog.prototype,
3 | InjectionChecker: InjectionChecker, ABE: ABE, IOUtil: IOUtil, DNS: DNS},
4 | data: {},
5 | reset: function() { return this.data = {} },
6 |
7 | instrument: function(b) {
8 | const oo = this.watchlist;
9 | const pf = "profiler.function";
10 | for (let v in oo) {
11 | let o = oo[v]
12 | for (let n in o) {
13 | let f = o[n];
14 | if (typeof f == "function") {
15 | if (b) {
16 | if (pf in f) continue;
17 | let key = v + "." + n;
18 | let patched = function() {
19 | let t = Date.now();
20 | let r = f.apply(this, arguments);
21 | let pdata = Profiler.data;
22 | let data = pdata[key] || (pdata[key] = {count: 0, time: 0, min: 120000, max: 0});
23 | data.count++;
24 | data.time += t = (Date.now() - t);
25 | if (t > data.max) data.max = t;
26 | if (t < data.min) data.min = t;
27 | return r;
28 | }
29 | patched[pf] = f;
30 | o[n] = patched;
31 | dump(key + "\n");
32 | } else {
33 | if (pf in f) o[n] = f[pf];
34 | }
35 | }
36 | }
37 | }
38 | },
39 |
40 | report: function(count) {
41 | if (arguments.length === 0) count = 20;
42 | dump("\n\n\nProfiler Report");
43 | let ar = [];
44 | for (let [call, data] in Iterator(this.data)) {
45 | data.avg = Math.round(data.time / data.count * 1000) / 1000;
46 | ar.push({call: call, data: data});
47 | }
48 | let cmp = (a,b) => a > b ? - 1: a < b ? 1 : 0;
49 | ar.sort((a, b) => cmp(a.data.time, b.data.time));
50 | for (let l of ar) {
51 | dump(l.call + ": " + l.data.toSource() + "\n");
52 | if (count-- <= 0) break;
53 | }
54 | },
55 |
56 | gc: function() {
57 | DOM.mostRecentBrowserWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
58 | .getInterface(Components.interfaces.nsIDOMWindowUtils)
59 | .garbageCollect();
60 | }
61 | }
62 |
63 |
64 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/ScriptlessBGThumbs.js:
--------------------------------------------------------------------------------
1 | {
2 | let scope = {};
3 | Cu.import("resource://gre/modules/BackgroundPageThumbs.jsm", scope);
4 |
5 | let bpt = scope.BackgroundPageThumbs;
6 |
7 | if (!bpt._NoScript_) {
8 | let patched = bpt._NoScript_ = {};
9 | let patch = (name, f) => {
10 | patched[name] = bpt[name];
11 | bpt[name] = f;
12 | };
13 | patch("capture", function() {
14 | Cu.import("resource://gre/modules/PageThumbs.jsm", scope);
15 | let PageThumbs = scope.PageThumbs;
16 | let e = PageThumbs._prefEnabled;
17 | if (!ns.getPref("bgThumbs.allowed")) {
18 | PageThumbs._prefEnabled = () => false;
19 | }
20 | try {
21 | bpt._NoScript_.capture.apply(bpt, arguments);
22 | } finally {
23 | PageThumbs._prefEnabled = e;
24 | }
25 | });
26 |
27 | bpt._destroyBrowser();
28 |
29 | patch("_ensureBrowser", function() {
30 | if (!this._thumbBrowser) {
31 | this._NoScript_._ensureBrowser.apply(this, arguments);
32 | if (this._thumbBrowser && ns.getPref("bgThumbs.disableJS"))
33 | this._thumbBrowser.messageManager.loadFrameScript(
34 | "data:text/javascript,docShell.allowJavascript = false", false);
35 | }
36 | });
37 |
38 | ns.onDisposal(() => {
39 | let patched = bpt._NoScript_;
40 | if (!patched) return;
41 | for(let name of Object.keys(patched)) {
42 | bpt[name] = patched[name];
43 | }
44 | delete bpt._NoScript_;
45 | });
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/Strings.js:
--------------------------------------------------------------------------------
1 | function Strings(chromeName) {
2 | this.chromeName = chromeName;
3 | }
4 |
5 | Strings.wrap = (s, count) => s.replace(new RegExp("\\w{" + (parseInt(count) || 20) + "}", 'g'), "$&\u200B");
6 |
7 | Strings.prototype = {
8 | _rnd: `${Math.random()}-${Date.now()}`,
9 | bundles: {},
10 | getBundle: function(path) {
11 | if (path in this.bundles) return this.bundles[path];
12 | try {
13 | return this.bundles[path] =
14 | Cc["@mozilla.org/intl/stringbundle;1"]
15 | .getService(Ci.nsIStringBundleService)
16 | .createBundle(
17 | `chrome://${this.chromeName}/${path}/${this.chromeName}.properties?${this._rnd}`
18 | );
19 | } catch(ex) {
20 | return this.bundles[path] = null;
21 | }
22 | },
23 |
24 |
25 | _stringFrom: function(bundle, name, parms) {
26 | try {
27 | return parms ? bundle.formatStringFromName(name, parms, parms.length) : bundle.GetStringFromName(name);
28 | } catch(ex) {
29 | return null;
30 | }
31 | }
32 | ,
33 | getString: function(name, parms) {
34 | var s = this._stringFrom(this.getBundle("locale"), name, parms);
35 | return s || name;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/SyntaxChecker.js:
--------------------------------------------------------------------------------
1 | function SyntaxChecker(version) {
2 | this.version = version || "1.5";
3 | this.sandbox = new Cu.Sandbox("about:");
4 | }
5 |
6 | SyntaxChecker.prototype = {
7 | lastError: null,
8 | lastFunction: null,
9 | check: function(script) {
10 | this.sandbox.script = script;
11 | try {
12 | return !!(this.lastFunction = this.ev("new Function(script)"));
13 | } catch(e) {
14 | this.lastError = e;
15 | this.lastFunction = null;
16 | }
17 | return false;
18 | },
19 | unquote: function(s, q) {
20 | if (!(s[0] == q && s[s.length - 1] == q &&
21 | !s.replace(/\\./g, '').replace(/^(['"])[^\n\r]*?\1/, "")
22 | )) return null;
23 | try {
24 | return this.ev(s);
25 | } catch(e) {}
26 | return null;
27 | },
28 | ev: function(s) {
29 | return Cu.evalInSandbox(s, this.sandbox);
30 | }
31 | };
32 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/Thread.js:
--------------------------------------------------------------------------------
1 | var Thread = {
2 |
3 | hostRunning: true,
4 | activeLoops: 0,
5 |
6 | spin: function(ctrl) {
7 | ctrl.startTime = ctrl.startTime || Date.now();
8 | ctrl.timeout = false;
9 | this.activeLoops++;
10 | this._spinInternal(ctrl);
11 | this.activeLoops--;
12 | ctrl.elapsed = Date.now() - ctrl.startTime;
13 | return ctrl.timeout;
14 | },
15 |
16 | _spinInternal: function(ctrl) {
17 | var t = ctrl.startTime;
18 | var maxTime = parseInt(ctrl.maxTime);
19 | if (maxTime) {
20 | while(ctrl.running && this.hostRunning) {
21 | this.yield();
22 | if (Date.now() - t > maxTime) {
23 | ctrl.timeout = true;
24 | ctrl.running = false;
25 | break;
26 | }
27 | }
28 | } else while(ctrl.running && this.hostRunning) this.yield();
29 | },
30 |
31 | yield: function() {
32 | this.current.processNextEvent(true);
33 | },
34 |
35 | yieldAll: function() {
36 | var t = this.current;
37 | while(t.hasPendingEvents()) t.processNextEvent(false);
38 | },
39 |
40 | get current() {
41 | delete this.current;
42 | var obj = "@mozilla.org/thread-manager;1" in Cc
43 | ? Cc["@mozilla.org/thread-manager;1"].getService()
44 | : Cc["@mozilla.org/thread;1"].createInstance(Ci.nsIThread);
45 | this.__defineGetter__("current", function() { return obj.currentThread; });
46 | return this.current;
47 | },
48 |
49 | get currentQueue() {
50 | delete this.currentQueue;
51 | var eqs = null;
52 | const CTRID = "@mozilla.org/event-queue-service;1";
53 | if (CTRID in Cc) {
54 | const IFace = Ci.nsIEventQueueService;
55 | eqs = Cc[CTRID].getService(IFace);
56 | }
57 | this.__defineGetter__("currentQueue", eqs
58 | ? function() { return eqs.getSpecialEventQueue(IFace.CURRENT_THREAD_EVENT_QUEUE); }
59 | : this.__lookupGetter__("current")
60 | );
61 | return this.currentQueue;
62 | },
63 |
64 | delay: function(callback, time = 0, self = null, args = DUMMY_ARRAY) {
65 | var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
66 | timer.initWithCallback({
67 | notify: this._delayRunner,
68 | context: { callback, args, self }
69 | }, time, 0);
70 | },
71 |
72 | dispatch: function(runnable) {
73 | this.current.dispatch(runnable, Ci.nsIEventTarget.DISPATCH_NORMAL);
74 | },
75 |
76 | asap: function(callback, self, args = DUMMY_ARRAY) {
77 | this.current.dispatch({
78 | run: function() {
79 | callback.apply(self, args);
80 | }
81 | }, Ci.nsIEventTarget.DISPATCH_NORMAL);
82 | },
83 |
84 | _delayRunner: function(timer) {
85 | var ctx = this.context;
86 | try {
87 | if (typeof Thread === "undefined") return;
88 | ctx.callback.apply(ctx.self, ctx.args);
89 | } finally {
90 | this.context = null;
91 | timer.cancel();
92 | }
93 | }
94 |
95 | };
96 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/URIValidator.js:
--------------------------------------------------------------------------------
1 | var URIValidator = {
2 |
3 | QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
4 |
5 | // returns false if absolute URI is not valid, undefined if it cannot be validated (i.e. no validator is found for this scheme)
6 | validate: function(uriSpec) {
7 | if (!uriSpec) return false;
8 | var parts = uriSpec.split(":");
9 | if (parts.length < 2) return false;
10 | var scheme = parts.shift().toLowerCase();
11 | if (!scheme) return false;
12 | var validator = this.validators[scheme];
13 | try {
14 | // using unescape rather than decodeURI for a reason:
15 | // many external URL (e.g. mailto) default to ISO8859, and we would fail,
16 | // but on the other hand rules marking as invalid non-null high unicode chars are unlikely (let's hope it)
17 | return validator && validator.test(unescape(parts.join(":")));
18 | } catch(e) {
19 | return false;
20 | }
21 | },
22 |
23 | get validators() {
24 | delete this.validators;
25 | this._init();
26 | return this.validators;
27 | },
28 |
29 | prefs: null,
30 | _init: function() {
31 | this.validators = {};
32 | this.prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService)
33 | .getBranch("noscript.urivalid.");
34 | for (var key of this.prefs.getChildList("", {})) {
35 | this.parseValidator(key);
36 | }
37 | this.prefs.addObserver("", this, true);
38 | },
39 | parseValidator: function(key) {
40 | try {
41 | this.validators[key] = new RegExp("^" + this.prefs.getCharPref(key) + "$");
42 | } catch(e) {
43 | delete this.validators[key];
44 | }
45 | },
46 | observe: function(prefs, topic, key) {
47 | this.parseValidator(key);
48 | }
49 | };
50 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/WebExt.js:
--------------------------------------------------------------------------------
1 | var WebExt = {
2 | enabled: false,
3 | started: false,
4 | running: false,
5 | port: null,
6 | saveData(json = ns.conf2JSON(true)) {
7 | this.tell("saveData", json);
8 | },
9 | dumpData() {
10 | this.tell("dumpData");
11 | },
12 | tell(type, data) {
13 | if (this.port) try {
14 | this.port.postMessage({ type, data });
15 | } catch (e) {
16 | if (!/\bdead object\b/.test(e.message)) { // normal on uninstall
17 | Cu.reportError(e);
18 | }
19 | }
20 | },
21 |
22 | init(embeddedWebExtension) {
23 | WebExt.enabled = true;
24 | embeddedWebExtension.startup().then(({browser}) => {
25 | WebExt.started = true;
26 | ns.dump(`Embedded webext started`);
27 | browser.runtime.onMessage.addListener(msg => {
28 | switch(msg) {
29 | case "STARTED":
30 | WebExt.running = true;
31 | break;
32 | case "STOPPED":
33 | WebExt.running = false;
34 | break;
35 | }
36 | ns.dump(`Received message from embedded webext ${msg}`);
37 | });
38 | browser.runtime.onConnect.addListener(port => {
39 | ns.dump(`Webext connected`);
40 | WebExt.port = port;
41 | WebExt.saveData();
42 | });
43 | }).catch(err => {
44 | Components.utils.reportError(
45 | `Embedded webext startup failed: ${err.message} ${err.stack}\n`
46 | );
47 | });
48 | },
49 | };
50 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/WebGLInterception.js:
--------------------------------------------------------------------------------
1 | var WebGLInterception = {
2 | sites: {},
3 | handler(ev) {
4 | WebGLInterception.record(ev.target, ns.getSite(ev.target.documentURI || ev.target.ownerDocument.documentURI), true);
5 | },
6 | record(ctx, site, fromDOM) {
7 | ns.tagForReplacement(ctx, {
8 | url: site,
9 | site: site,
10 | originSite: site,
11 | mime: "WebGL"
12 | });
13 | let doc = ctx.ownerDocument || ctx;
14 | if (fromDOM) {
15 | let ds = DOM.getDocShellForWindow(doc.defaultView);
16 | if (ds.isLoadingDocument) { // prevent fallback redirection from hiding us
17 | let sites = this.sites;
18 | sites[site] = doc.documentURI;
19 | doc.defaultView.addEventListener("load", () => delete sites[site], false);
20 | }
21 | }
22 | ns.recordBlocked(site, site);
23 | },
24 | get interceptionDef() {
25 | delete this.interceptionDef;
26 | return (this.interceptionDef = function() {
27 | var proto = HTMLCanvasElement.prototype;
28 | var getContext = proto.getContext;
29 | proto.getContext = function(type) {
30 | if (type && type.toString().indexOf("webgl") !== -1) {
31 | var ev = this.ownerDocument.createEvent("Events");
32 | ev.initEvent("NoScript:WebGL", true, false);
33 | (this.parentNode ? this : this.ownerDocument)
34 | .dispatchEvent(ev);
35 | return null;
36 | }
37 | return getContext.call(this, "2d");
38 | };
39 | }.toSource() + "()");
40 | },
41 | reloadAllowed(docShell) {
42 | let curURL = docShell.currentURI.spec;
43 | let site = ns.getSite(curURL);
44 | if (site in this.sites) {
45 | let url = this.sites[site];
46 | delete this.sites[site];
47 | if (url !== curURL) {
48 | docShell.loadURI(url, Ci.nsIWebNavigation.LOAD_FLAGS_NONE, null, null, null);
49 | return true;
50 | }
51 | }
52 | return false;
53 | },
54 | hook(doc, site) {
55 | if (!(ns.isAllowedObject(site, "WebGL", site, site) || ns.isAllowedMime("WebGL", site))) {
56 | doc.addEventListener("NoScript:WebGL", this.handler, false, true);
57 | if (site in this.sites) {
58 | this.record(doc, site);
59 | }
60 | return this.interceptionDef;
61 | }
62 | return null;
63 | }
64 | };
65 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/WinScript.js:
--------------------------------------------------------------------------------
1 | var WinScript = {
2 | supported: true,
3 | block: function(window) {
4 | if (window._blockScriptForGlobal) return;
5 | try {
6 | Cu.blockScriptForGlobal(window);
7 | if (!("_blockScriptForGlobal" in window)) {
8 | this.patchStyle(window.document);
9 | }
10 | } catch (e) {
11 | if (e.message === "Script may not be disabled for system globals") {
12 | try {
13 | window.console.log("NoScript could not disable scripts for system global " + window.document.nodePrincipal.origin);
14 | } catch(e) {}
15 | return;
16 | }
17 | if (!this._childDo("block", window)) throw e;
18 | }
19 | window._blockScriptForGlobal = true;
20 | },
21 | unblock: function(window) {
22 | if (!window._blockScriptForGlobal) return;
23 | try {
24 | Cu.unblockScriptForGlobal(window);
25 | } catch (e) {
26 | if (this._childDo("unblock", window)) throw e;
27 | }
28 | window._blockScriptForGlobal = false;
29 | },
30 | isBlocked: function(window) {
31 | return window._blockScriptForGlobal;
32 | },
33 | isDecided: function(window) {
34 | return "_blockScriptForGlobal" in window;
35 | },
36 | get _childDo() {
37 | return (this._childDo = IPC.parent && IPC.parent.mm && ("isCrossProcessWrapper" in Cu) ?
38 | function(verb, window) {
39 | if (Cu.isCrossProcessWrapper(window)) {
40 | IPC.parent.mm.broadcastAsyncMessage("NoScript:WinScript", verb, { window: window });
41 | return true;
42 | }
43 | return false;
44 | }
45 | : function() { return false; }
46 | );
47 | },
48 | _domUtils: Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils),
49 | patchStyle: function(doc) {
50 | let ss = this._domUtils.getAllStyleSheets(doc);
51 | // reverse loop because the preference stylesheet is almost always the last one
52 | for (let j = ss.length; j-- > 0;) {
53 | let s = ss[j];
54 | switch(s.href) {
55 |
56 | case "about:PreferenceStyleSheet":
57 | {
58 | let rules = s.cssRules;
59 | // skip 1st & 2nd, as they are HTML & SVG namespaces
60 | for (let j = 2, len = rules.length; j < len; j++) {
61 | let r = rules[j];
62 | if (r.cssText === "noscript { display: none ! important; }") {
63 | s.deleteRule(j);
64 | return;
65 | }
66 | }
67 | }
68 | break;
69 | case "data:text/css,noscript%20{%20display%3A%20none%20!important%3B%20}":
70 | case "resource://gre-resources/noscript.css":
71 | doc.defaultView.QueryInterface(Ci.nsIInterfaceRequestor)
72 | .getInterface(Ci.nsIDOMWindowUtils)
73 | .loadSheetUsingURIString("data:text/css,noscript { display: initial !important }", 0);
74 | return;
75 | }
76 | }
77 | }
78 | };
79 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/clearClick.xul:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/defer.jsm:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var EXPORTED_SYMBOLS = ["defer"];
4 |
5 | let { interfaces: Ci, classes: Cc } = Components;
6 |
7 | let currentThread = null;
8 |
9 | function defer(callback, milliseconds = 0) {
10 | if (milliseconds > 0) {
11 | let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
12 | timer.initWithCallback(callback, milliseconds, timer.TYPE_ONE_SHOT);
13 | } else {
14 | (currentThread || (currentThread = Cc["@mozilla.org/thread-manager;1"].getService().currentThread))
15 | .dispatch({ run: callback }, Ci.nsIEventTarget.DISPATCH_NORMAL);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/e10sChild.js:
--------------------------------------------------------------------------------
1 | var EXPORTED_SYMBOLS = [];
2 | Components.utils.import("resource://gre/modules/Services.jsm");
3 | Components.utils.import(`chrome://noscript/content/importer.jsm`);
4 |
5 | Services.scriptloader.loadSubScript(NO_CACHE(`loader.js`), this);
6 |
7 | Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
8 |
9 |
10 |
11 | (function () {
12 | try {
13 | INCLUDE("Main");
14 | } catch (e) {
15 | Cu.reportError(e);
16 | }
17 |
18 | IPC.child = {
19 | QueryInterface: XPCOMUtils.generateQI([Ci.nsIMessageListener, Ci.nsISupportsWeakReference]),
20 | init: function() {
21 | Services.cpmm.addWeakMessageListener(IPC_P_MSG.CALL, this);
22 | Main.init();
23 | },
24 | dispose: function() {
25 | Services.cpmm.removeWeakMessageListener(IPC_P_MSG.CALL, this);
26 | Main.shutdown();
27 | UNLOAD_ALL();
28 | },
29 |
30 | receiveMessage: function(m) {
31 | if (IPC.receiveMessage(m)) {
32 | return;
33 | }
34 | if (m.name === "NoScript:unload") {
35 | this.dispose();
36 | }
37 | },
38 |
39 | remote(objName, method, args) {
40 | Services.cpmm.sendAsyncMessage(IPC_P_MSG.CALL, {objName, method, args});
41 | },
42 |
43 | callback(id, autoRemote = true) {
44 | let cb = () => {
45 | cb._executed = true;
46 | };
47 | cb._executed = false;
48 | cb.remote = () => {
49 | Services.cpmm.sendAsyncMessage(IPC_P_MSG.CALLBACK, {id, execute: cb._executed });
50 | };
51 | if (autoRemote) Thread.asap(cb.remote);
52 | },
53 |
54 | };
55 |
56 | try {
57 | Main.bootstrap();
58 | IPC.child.init();
59 | Services.cpmm.sendAsyncMessage(IPC_P_MSG.SERVICE_READY);
60 | } catch (e) {
61 | Components.utils.reportError(e);
62 | }
63 | })();
64 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/e10sIPC.js:
--------------------------------------------------------------------------------
1 | var IPC_MSG = {
2 | SYNC: "NoScript:syncUI",
3 | NOTIFY_META: "NoScript:notifyMetaRefresh",
4 | CLEARCLICK_WARNING: "NoScript:clearClickWarning",
5 | },
6 | IPC_P_MSG = {
7 | SERVICE_READY: "NoScript:ServiceReady",
8 | LOAD_SURROGATE: "NoScript:loadSurrogate",
9 | CALL: "NoScript:remoteCall",
10 | RESUME: "NoScript:resume",
11 | GET_PREF: "NoScript:getPref",
12 | GET_SNAPSHOT: "NoScript:getSnapshot",
13 | CALLBACK: "NoScript:callback",
14 | }
15 |
16 | var IPC = {
17 | logger: null,
18 | log(...args) {
19 | if (this.logger) {
20 | args[0] = `[${this.parent ? 'P' : 'C'}] ${args[0]}`;
21 | this.logger(...args);
22 | }
23 | },
24 | registry: null,
25 | autoSync(obj, objName, methods) {
26 | if (!this.registry) this.registry = new Map();
27 | this.registry.set(objName, {
28 | reference: obj,
29 | methods: new Set(methods),
30 | });
31 |
32 | for (let m of methods) {
33 | let method = m; // hack needed in Fx < 50
34 | if (!(method in obj)) {
35 | ns.log(`method ${method} not found in ${objName}\n`);
36 | }
37 | let func = obj[method];
38 | if (func._autoSynced) continue;
39 | (obj[method] = (...args) => {
40 | let stack = Components.stack;
41 | let caller = stack.caller;
42 | if (caller.name !== "call" || stack.filename !== caller.filename) {
43 | let process = IPC.parent || IPC.child;
44 | process.remote(objName, method, args);
45 | }
46 | return func.apply(obj, args);
47 | })._autoSynced = true;
48 | }
49 | return true;
50 | },
51 | call(objName, method, args) {
52 | let {reference, methods} = this.registry.get(objName);
53 | if (methods.has(method)) {
54 | reference[method].apply(reference, args);
55 | }
56 | },
57 |
58 | receiveMessage(m) {
59 | if (this.logger) this.log(`Received message ${m.name} - ${JSON.stringify(m.data)}`);
60 | switch(m.name) {
61 | case IPC_P_MSG.CALL:
62 | let { objName, method, args } = m.data;
63 | IPC.call(objName, method, args);
64 | return true;
65 | }
66 | return false;
67 | },
68 | };
69 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/e10sParent.js:
--------------------------------------------------------------------------------
1 | IPC.parent = {
2 | FRAME_SCRIPT: NO_CACHE("frameScript.js"),
3 | PROCESS_SCRIPT: NO_CACHE("e10sProcessScript.js"),
4 | QueryInterface: XPCOMUtils.generateQI([Ci.nsIMessageListener, Ci.nsISupportsWeakReference]),
5 | init() {
6 | let globalMM = Services.mm;
7 | for (let m of Object.keys(IPC_MSG)) {
8 | globalMM.addWeakMessageListener(IPC_MSG[m], this);
9 | }
10 | let processMM = Services.ppmm;
11 | for (let m of Object.keys(IPC_P_MSG)) {
12 | processMM.addWeakMessageListener(IPC_P_MSG[m], this);
13 | }
14 | processMM.loadProcessScript(this.PROCESS_SCRIPT, true);
15 | globalMM.loadFrameScript(this.FRAME_SCRIPT, true);
16 | },
17 | dispose() {
18 | let globalMM = Services.mm;
19 | for (let m of Object.keys(IPC_MSG)) {
20 | globalMM.removeWeakMessageListener(IPC_MSG[m], this);
21 | }
22 | let processMM = Services.ppmm;
23 | for (let m of Object.keys(IPC_P_MSG)) {
24 | processMM.removeWeakMessageListener(IPC_P_MSG[m], this);
25 | }
26 | globalMM.removeDelayedFrameScript(this.FRAME_SCRIPT);
27 | globalMM.broadcastAsyncMessage("NoScript:unload");
28 | processMM.removeDelayedProcessScript(this.PROCESS_SCRIPT);
29 | processMM.broadcastAsyncMessage("NoScript:unload");
30 | },
31 |
32 |
33 | receiveMessage(m) {
34 | ns.onContentInit();
35 | this.receiveMessage = this._receiveMessageReal;
36 | return this.receiveMessage(m);
37 | },
38 | _receiveMessageReal(m) {
39 | if (IPC.receiveMessage(m)) {
40 | return;
41 | }
42 | switch(m.name) {
43 | case IPC_MSG.SYNC:
44 | ns.setExpando(m.target, "sites", m.data);
45 | ns.syncUI(m.target);
46 | return;
47 | case IPC_MSG.NOTIFY_META:
48 | let browser = m.target;
49 | info.browser = browser;
50 | browser.defaultView.noscriptOverlay.notifyMetaRefresh(info);
51 | return;
52 | case IPC_MSG.CLEARCLICK_WARNING:
53 | return ClearClickHandler.prototype.showWarningParent(m.target.ownerDocument.defaultView, m.data).locked;
54 | case IPC_P_MSG.CALLBACK:
55 | let {id, execute} = m.data;
56 | this._handleCallback(id, execute);
57 | return;
58 | case IPC_P_MSG.LOAD_SURROGATE:
59 | return ScriptSurrogate.loadReplacementFile(ScriptSurrogate.getReplacement(m.data));
60 | case IPC_P_MSG.RESUME:
61 | return IOUtil.resumeParentChannel(m.data.id, m.data.abort);
62 | case IPC_P_MSG.GET_PREF:
63 | let {method, name} = m.data;
64 | if (method in Services.prefs && method.startsWith("get")) {
65 | try {
66 | return Services.prefs[method](name);
67 | } catch (e) {
68 | Cu.reportError(e);
69 | }
70 | }
71 | return null;
72 | case IPC_P_MSG.GET_SNAPSHOT:
73 | return ns.getSnapshot();
74 | }
75 | },
76 |
77 | remote(objName, method, args) {
78 | Services.ppmm.broadcastAsyncMessage(IPC_P_MSG.CALL, {objName, method, args});
79 | },
80 |
81 | _callbacks: new Map(),
82 | _callbackId: 0,
83 | callback(f) {
84 | this._callbacks.set(++this._callbackId, f);
85 | return this._callbackId;
86 | },
87 | _handleCallback(id, execute) {
88 | let callback = this._callbacks.get(id);
89 | if (callback) this._callbacks.delete(id);
90 | if (execute) {
91 | try {
92 | callback();
93 | } catch (e) {
94 | Cu.reportError(e);
95 | }
96 | }
97 | },
98 | };
99 |
100 | IPC.parent.init();
101 |
102 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/e10sProcessScript.js:
--------------------------------------------------------------------------------
1 | Components.utils.import("resource://gre/modules/Services.jsm");
2 |
3 | if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) {
4 | Components.utils.import(`chrome://noscript/content/importer.jsm`);
5 | Services.scriptloader.loadSubScript(NO_CACHE(`e10sChild.js`), {});
6 | } else {
7 | // nothing to do exclusively in the parent process yet...
8 | }
9 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/frameScript.js:
--------------------------------------------------------------------------------
1 | Components.utils.import("chrome://noscript/content/importer.jsm");
2 | IMPORT_FOR(this)("FrameScript");
3 | new FrameScript(this);
4 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/importer.jsm:
--------------------------------------------------------------------------------
1 | var EXPORTED_SYMBOLS = ["NO_CACHE", "IMPORT_FOR", "UNLOAD", "UNLOAD_ALL", "BASE_URL"];
2 |
3 | let { utils: Cu } = Components;
4 |
5 | let BASE_URL = "chrome://noscript/content/";
6 | let toURL = name => `${name}.jsm`;
7 |
8 | let _NO_CACHE_KEY = Date.now().toString(32).concat(Math.random().toString(32).substring(2));
9 |
10 | function NO_CACHE(url) {
11 | return `${BASE_URL}${url}?${_NO_CACHE_KEY}`;
12 | }
13 |
14 | let _MODULES = new Set();
15 |
16 | function IMPORT_FOR(scope) {
17 | return name => {
18 | let url = NO_CACHE(toURL(name));
19 | _MODULES.add(url);
20 | return Cu.import(url, scope);
21 | };
22 | }
23 |
24 | function UNLOAD(name) {
25 | Cu.unload(NO_CACHE(toURL(name)));
26 | }
27 | function UNLOAD_ALL() {
28 | for (let m of _MODULES) Cu.unload(m);
29 | UNLOAD("importer");
30 | }
31 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/loader.js:
--------------------------------------------------------------------------------
1 | // const TIME0 = Date.now();
2 |
3 | var { interfaces: Ci, classes: Cc, utils: Cu, results: Cr } = Components;
4 |
5 | Cu.import("resource://gre/modules/Services.jsm");
6 | Cu.import("resource://gre/modules/XPCOMUtils.jsm");
7 | Cu.import(`chrome://noscript/content/importer.jsm`);
8 | var IMPORT = IMPORT_FOR(this);
9 |
10 | var IOS = Services.io;
11 | var OS = Services.obs;
12 | var LOADER = Services.scriptloader;
13 |
14 |
15 | var _INCLUDED = new Set();
16 |
17 | var INCLUDE = function (...objectNames) {
18 | for (let objectName of objectNames) {
19 | if (!(_INCLUDED.has(objectName))) {
20 | _INCLUDED.add(objectName);
21 | // let t = Date.now();
22 | LOADER.loadSubScript(NO_CACHE(`${objectName}.js`), this);
23 | // dump((t - TIME0) + " - loaded " + objectName + " in " + (Date.now() - t) + "\n")
24 | }
25 | }
26 | };
27 |
28 | function LAZY_INCLUDE(...objectNames) {
29 | for (let objectName of objectNames) {
30 | if (!(_INCLUDED.has(objectName))) {
31 | let key = objectName; // hack needed in Fx < 50
32 | this.__defineGetter__(key, function() {
33 | delete this[key];
34 | // dump(objectName + " kickstarted at " + (new Error().stack));
35 | INCLUDE(key);
36 | return this[key];
37 | });
38 | }
39 | }
40 | }
41 |
42 | function INCLUDE_MIXIN(target, ...objectNames) {
43 | INCLUDE(...objectNames);
44 | return MIXIN(target, ...objectNames.map(objectName => this[objectName]));
45 | }
46 |
47 | function MIXIN(target, ...objects) {
48 | for (let o of objects) {
49 | let object = o; // hack needed in Fx < 50
50 | Object.defineProperties(target, Object.keys(object).reduce((descriptors, key) => {
51 | descriptors[key] = Object.getOwnPropertyDescriptor(object, key);
52 | return descriptors;
53 | }, {}));
54 | }
55 | return target;
56 | }
57 |
58 | var COMPAT = {
59 | setStringPref(branch, name, value) {
60 | if (branch.setStringPref) {
61 | branch.setStringPref(name, value);
62 | } else {
63 | let str = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
64 | str.data = value;
65 | branch.setComplexValue(name, Ci.nsISupportsString, str);
66 | }
67 | },
68 |
69 | getStringPref(branch, name, defValue) {
70 | return branch.getStringPref ? branch.getStringPref(name, defValue)
71 | : branch.getComplexValue(name, Ci.nsISupportsString).data || defValue;
72 | }
73 | };
74 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/noscript.xbl:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
18 |
19 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/noscriptBMOverlay.xul:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/xpi/chrome/content/noscript/tree-copy.js:
--------------------------------------------------------------------------------
1 | // Tree clipboard utils
2 |
3 | const Cc = Components.classes, Ci = Components.interfaces, Cu = Components.utils;
4 |
5 | var noscriptTreeCc = {
6 | cb: Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper),
7 |
8 | getSelectionString: function(tree, csc, rsc) {
9 | if (!rsc) rsc = "\n";
10 | let start = new Object(), end = new Object(), v = tree.view, out = "";
11 | let numRanges = v.selection.getRangeCount();
12 | let b = tree.boxObject;
13 | b.QueryInterface(Ci.nsITreeBoxObject);
14 | let cols = b.columns, l = cols.length - 1;
15 |
16 | for (let i = 0; i < numRanges; i++) {
17 | v.selection.getRangeAt(i,start,end);
18 | for (let r = start.value; r <= end.value; r++) {
19 | for (let c = 0; c <= l; c++) {
20 | let f = c != l ? csc : ""
21 | out += v.getCellText(r, cols.getColumnAt(c)) + f;
22 | }
23 | out += rsc;
24 | }
25 | }
26 | return out.trim();
27 | },
28 |
29 | getSelectedItems: function(tree, sourceData) {
30 | let start = new Object(), end = new Object(), v = tree.view, out = [];
31 | let numRanges = v.selection.getRangeCount();
32 | let b = tree.boxObject;
33 | b.QueryInterface(Ci.nsITreeBoxObject);
34 | let cols = b.columns, l = cols.length - 1;
35 |
36 | for (let i = 0; i < numRanges; i++) {
37 | v.selection.getRangeAt(i,start,end);
38 | for (let r = start.value; r <= end.value; r++) {
39 | out.push(sourceData[r]);
40 | }
41 | }
42 | return out;
43 | },
44 |
45 | selectAll: function(t) {
46 | t.view.selection.selectAll();
47 | },
48 |
49 | doCopy: function(t, csc, rsc) {
50 | this.cb.copyString(this.getSelectionString(t, csc, rsc));
51 | }
52 |
53 | };
54 |
--------------------------------------------------------------------------------
/xpi/chrome/locale/ar/noscript/about.properties:
--------------------------------------------------------------------------------
1 | extensions.{73a6fe31-595d-460b-a920-fcc0f8843232}.description=حمايةاضافية لفيرفوكس : نوسكربت يسمح لجافاسكربت و جافا وتقنيات اخرى فقظ للمجالات التي تثق بها.
2 | aboutTitle=عن %S
3 | extensionContributors=المساهمون:
4 | extensionContributors.tip=أشخاص يستحقون الشكر لهذا الامتداد
5 | extensionCreatorLabel=المؤلف:
6 | changelog=سجل التغييرات
7 | changelog.tip=استعرض سجلل التغييرات
8 | license=الترخيص
9 | license.tip=اقرأ رخصة المستخدم
10 | logo.tip=زيارة موقع الامتدادة
11 | sponsor.tip=زيارة موقع الراعي
12 | informaction.tip=زيارة موقع إنفورماكشن
13 | extensionHomepage.tip=زيارة موقع الامتدادة
14 | extensionCreator.tip=زيارة موقع المؤلف
15 | version=
16 |
--------------------------------------------------------------------------------
/xpi/chrome/locale/ar/noscript/noscript.properties:
--------------------------------------------------------------------------------
1 | allowGlobal=السماح للسكربتات بشكل شامل (غير آمن)
2 | forbidGlobal=منع السكربتات نهائيا (محبذ)
3 | allowLocal=السماح من %S
4 | allowTemp=السماح من %S مؤقتا
5 | forbidLocal=المنع من %S
6 | allowed.glb=خطر! السكربتات مسموحة كلياً
7 | allowed.yes=السكربتات مسموحة حاليًا
8 | allowed.prt=السكربتات مسموحة جزئيًا
9 | allowed.no=السكربتات ممنوعة حاليًا
10 | global.warning.title=تحذير!
11 | global.warning.text=سيسمح للسكربتات كلياً (لكل المواقع).\nيمكن أن يكون هذا خطيرا.\nأمتأكد أنك تريد المواصلة؟
12 | audio.samples=عينات صوتية
13 | confirm=هل أنت متأكد؟
14 | alwaysAsk=إسأل دائما للتوكيد
15 | notifyHide=أخفِ بعد %S ثانية
16 | trust=ثق في %S
17 | distrust=ألتأشير %S كغير موثوق
18 | untrustedOrigin=مصدر غير موثوق
19 | xss.notify.generic=منع نوسكربت محاولة لتشغيل سركيبتات عبر المواقع من %S. تم تسجيل التفاصيل التقنية في المرقاب-الكونسول.
20 | xss.notify.showConsole=أظهار المرقاب-الكونسول…
21 | xss.notify.showConsole.accessKey=ر
22 | xss.reason.filterXGet=تم تطهير طلب مشبوه. المسار الأصلي [%1$S] طُلب من [%2$S]. المسار المطهر هو: [%3$S]
23 | xss.reason.filterXGetRef=تم تطهير محيل طلب مشبوه. المسار الأصلي [%1$S] طُلب من [%2$S]. المسار المطهر هو: [%3$S]
24 | xss.reason.filterXPost=تم تطهير تحميل مشبوه إلى [%1$S] من [%2$S]: تم تحويله إلى تنزيل فقط بالفعل GET.
25 | unsafeReload.warning=تجري إعادة تحميل غير آمنة\n\n[%1$S] [%2$S]\n\nمن[%3$S]\n\nلن يحمي نوسكربت هذا الطلب\n
26 | metaRefresh.notify=نوسكربت اعترض تحويلا باستخدام داخل عنصر