aboutsummaryrefslogtreecommitdiffstats
path: root/meta
diff options
context:
space:
mode:
authorDeathamns <deathamns@gmail.com>2014-12-01 16:23:19 +0100
committerDeathamns <deathamns@gmail.com>2014-12-01 20:47:23 +0100
commitc0e11d81825e3a51faddad06076b5fcb3b1baf5c (patch)
tree3a4d4bdde1b437074c36cccdc0583d1c5f98d3e0 /meta
parent98464a56fe4fa2a28372018640d648a1f772ea36 (diff)
downloaduBlock-c0e11d81825e3a51faddad06076b5fcb3b1baf5c.zip
uBlock-c0e11d81825e3a51faddad06076b5fcb3b1baf5c.tar.gz
uBlock-c0e11d81825e3a51faddad06076b5fcb3b1baf5c.tar.bz2
Safari: fix vAPI.tabs.close() + cleanup
Diffstat (limited to 'meta')
-rw-r--r--meta/safariextz/Info.plist91
-rw-r--r--meta/safariextz/Settings.plist22
-rw-r--r--meta/safariextz/sitepatch-safari.js81
-rw-r--r--meta/safariextz/update_safariextz.plist21
-rw-r--r--meta/safariextz/vapi-background.js753
-rw-r--r--meta/safariextz/vapi-client.js405
-rw-r--r--meta/safariextz/vapi-common.js156
7 files changed, 0 insertions, 1529 deletions
diff --git a/meta/safariextz/Info.plist b/meta/safariextz/Info.plist
deleted file mode 100644
index 50134bc..0000000
--- a/meta/safariextz/Info.plist
+++ /dev/null
@@ -1,91 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>Author</key>
- <string>Raymond Hill</string>
- <key>Builder Version</key>
- <string>534.57.2</string>
- <key>CFBundleDisplayName</key>
- <string>µBlock</string>
- <key>CFBundleIdentifier</key>
- <string>net.gorhill.uBlock</string>
- <key>CFBundleInfoDictionaryVersion</key>
- <string>6.0</string>
- <key>CFBundleShortVersionString</key>
- <string>0.7.0.10</string>
- <key>CFBundleVersion</key>
- <string>1456132</string>
- <key>Chrome</key>
- <dict>
- <key>Database Quota</key>
- <real>52428800</real>
- <key>Global Page</key>
- <string>background.html</string>
- <key>Popovers</key>
- <array>
- <dict>
- <key>Filename</key>
- <string>popup.html</string>
- <key>Height</key>
- <real>310</real>
- <key>Identifier</key>
- <string>popover</string>
- <key>Width</key>
- <real>180</real>
- </dict>
- </array>
- <key>Toolbar Items</key>
- <array>
- <dict>
- <key>Identifier</key>
- <string>toolbarItem</string>
- <key>Image</key>
- <string>img/icon16.png</string>
- <key>Label</key>
- <string>µBlock</string>
- <key>Popover</key>
- <string>popover</string>
- </dict>
- </array>
- </dict>
- <key>Content</key>
- <dict>
- <key>Scripts</key>
- <dict>
- <key>End</key>
- <array>
- <string>js/contentscript-end.js</string>
- </array>
- <key>Start</key>
- <array>
- <string>js/vapi-client.js</string>
- <string>js/contentscript-start.js</string>
- </array>
- </dict>
- <key>Whitelist</key>
- <array>
- <string>http://*/*</string>
- <string>https://*/*</string>
- </array>
- </dict>
- <key>Description</key>
- <string>Finally, an efficient blocker. Easy on CPU and memory.</string>
- <key>ExtensionInfoDictionaryVersion</key>
- <string>1.0</string>
- <key>Permissions</key>
- <dict>
- <key>Website Access</key>
- <dict>
- <key>Include Secure Pages</key>
- <true/>
- <key>Level</key>
- <string>All</string>
- </dict>
- </dict>
- <!-- <key>Update Manifest URL</key>
- <string>https://github.com/gorhill/uBlockupdate_safariextz.plist</string> -->
- <key>Website</key>
- <string>https://github.com/gorhill/uBlock</string>
-</dict>
-</plist>
diff --git a/meta/safariextz/Settings.plist b/meta/safariextz/Settings.plist
deleted file mode 100644
index 40cc1ff..0000000
--- a/meta/safariextz/Settings.plist
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<array>
- <dict>
- <key>DefaultValue</key>
- <false/>
- <key>FalseValue</key>
- <false/>
- <key>Key</key>
- <string>open_prefs</string>
- <key>Secure</key>
- <false/>
- <key>Title</key>
- <string>Click to see the Preferences</string>
- <key>TrueValue</key>
- <true/>
- <key>Type</key>
- <string>CheckBox</string>
- </dict>
-</array>
-</plist>
diff --git a/meta/safariextz/sitepatch-safari.js b/meta/safariextz/sitepatch-safari.js
deleted file mode 100644
index b99a28e..0000000
--- a/meta/safariextz/sitepatch-safari.js
+++ /dev/null
@@ -1,81 +0,0 @@
-// Adding new URL requires to whitelist it in the background script too (addContentScriptFromURL)
-// Note that the sitePach function will be converted to a string, and injected
-// into the web-page in order to run in that scope. Because of this, variables
-// from the extension scope won't be accessible in the sitePatch function.
-'use strict';
-
-self.vAPI = self.vAPI || {};
-
-if (/^www\.youtube(-nocookie)?\.com/.test(location.host)) {
- vAPI.sitePatch = function() {
- // disable spf
- window.ytspf = {};
- Object.defineProperty(ytspf, 'enabled', {'value': false});
-
- // based on ExtendTube's ad removing solution
- var p, yt = {}, config_ = {}, ytplayer = {}, playerConfig = { args: {} };
-
- Object.defineProperties(yt, {
- 'playerConfig': {
- get: function() { return playerConfig; },
- set: function(data) {
- if (data && typeof data === 'object'
- && data.args && typeof data.args === 'object') {
- var nope = /ad\d?_|afv|watermark|adsense|xfp/;
-
- for (var prop in data.args) {
- if (nope.test(prop) && !/policy/.test(prop)) {
- delete data.args[prop];
- }
- }
- }
-
- playerConfig = data;
-
- var playerRoot = document.querySelector('[data-swf-config]');
- if (playerRoot)
- playerRoot.dataset.swfConfig = JSON.stringify(yt.playerConfig);
- }
- },
- 'config_': {
- get: function() { return config_; },
- set: function(value) { config_ = value; }
- }
- });
-
- Object.defineProperty(config_, 'PLAYER_CONFIG', {
- get: function() { return yt.playerConfig; },
- set: function(value) { yt.playerConfig = value; }
- });
-
- Object.defineProperty(ytplayer, 'config', {
- get: function() { return playerConfig; },
- set: function(value) { yt.playerConfig = value; }
- });
-
- if (window.yt) {
- for (p in window.yt) { yt[p] = window.yt[p]; }
- window.yt = yt;
- }
- else {
- Object.defineProperty(window, 'yt', {
- get: function() { return yt; },
- set: function() {}
- });
- }
-
- if (window.ytplayer) {
- for (p in window.ytplayer) { ytplayer[p] = window.ytplayer[p]; }
- window.ytplayer = ytplayer;
- }
- else {
- Object.defineProperty(window, 'ytplayer', {
- get: function() { return ytplayer; },
- set: function() {}
- });
- }
- };
-}
-/*else if (check url) {
- vAPI.sitePatch do something
-}*/
diff --git a/meta/safariextz/update_safariextz.plist b/meta/safariextz/update_safariextz.plist
deleted file mode 100644
index 0681b05..0000000
--- a/meta/safariextz/update_safariextz.plist
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
- <dict>
- <key>Extension Updates</key>
- <array>
- <dict>
- <key>CFBundleIdentifier</key>
- <string>net.gorhill.uBlock</string>
- <key>Developer Identifier</key>
- <string></string>
- <key>CFBundleShortVersionString</key>
- <string>0.7.0.10</string>
- <key>CFBundleVersion</key>
- <string>1456132</string>
- <key>URL</key>
- <string>https://.../uBlock.safariextz</string>
- </dict>
- </array>
- </dict>
-</plist>
diff --git a/meta/safariextz/vapi-background.js b/meta/safariextz/vapi-background.js
deleted file mode 100644
index d4a78d6..0000000
--- a/meta/safariextz/vapi-background.js
+++ /dev/null
@@ -1,753 +0,0 @@
-/*******************************************************************************
-
- µBlock - a Chromium browser extension to block requests.
- Copyright (C) 2014 The µBlock authors
-
- 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/}.
-
- Home: https://github.com/gorhill/uBlock
-*/
-
-/* global µBlock, SafariBrowserTab */
-// For background page
-
-/******************************************************************************/
-
-(function() {
-
-'use strict';
-
-/******************************************************************************/
-
-self.vAPI = self.vAPI || {};
-
-vAPI.safari = true;
-
-/******************************************************************************/
-
-// addContentScriptFromURL allows whitelisting,
-// so load sitepaching this way, instead of adding it to the Info.plist
-
-safari.extension.addContentScriptFromURL(
- safari.extension.baseURI + 'js/sitepatch-safari.js',
- [
- 'http://www.youtube.com/*',
- 'https://www.youtube.com/*',
- 'http://www.youtube-nocookie.com/*',
- 'https://www.youtube-nocookie.com/*'
- ]
-);
-
-/******************************************************************************/
-
-safari.extension.settings.addEventListener('change', function(e) {
- if (e.key === 'open_prefs') {
- vAPI.tabs.open({url: 'dashboard.html', active: true});
- }
-}, false);
-
-/******************************************************************************/
-
-vAPI.storage = {
- _storage: safari.extension.settings,
- QUOTA_BYTES: 52428800, // copied from Info.plist
- get: function(keys, callback) {
- if (typeof callback !== 'function') {
- return;
- }
-
- var i, value, result = {};
-
- if (keys === null) {
- for (i in this._storage) {
- value = this._storage[i];
-
- if (typeof value === 'string') {
- result[i] = JSON.parse(value);
- }
- }
- }
- else if (typeof keys === 'string') {
- value = this._storage[keys];
-
- if (typeof value === 'string') {
- result[keys] = JSON.parse(value);
- }
- }
- else if (Array.isArray(keys)) {
- for ( i = 0; i < keys.length; ++i) {
- value = this._storage[i];
-
- if (typeof value === 'string') {
- result[keys[i]] = JSON.parse(value);
- }
- }
- }
- else if (typeof keys === 'object') {
- for (i in keys) {
- value = this._storage[i];
-
- if (typeof value === 'string') {
- result[i] = JSON.parse(value);
- }
- else {
- result[i] = keys[i];
- }
- }
- }
-
- callback(result);
- },
- set: function(details, callback) {
- for (var key in details) {
- this._storage.setItem(key, JSON.stringify(details[key]));
- }
-
- if (typeof callback === 'function') {
- callback();
- }
- },
- remove: function(keys) {
- if (typeof keys === 'string') {
- keys = [keys];
- }
-
- for (var i = 0; i < keys.length; ++i) {
- this._storage.removeItem(keys[i]);
- }
- },
- clear: function(callback) {
- this._storage.clear();
- callback();
- },
- getBytesInUse: function(keys, callback) {
- var key, size = 0;
-
- if (keys === null) {
- for (key in this._storage) {
- size += (this._storage[key] || '').length;
- }
- }
- else {
- if (typeof keys === 'string') {
- keys = [keys];
- }
-
- for (key = 0; key < keys.length; ++key) {
- size += (this._storage[keys[key]] || '').length;
- }
- }
-
- callback(size);
- }
-};
-
-/******************************************************************************/
-
-vAPI.tabs = {
- stack: {},
- stackID: 1
-};
-
-/******************************************************************************/
-
-vAPI.tabs.registerListeners = function() {
- var onNavigation = this.onNavigation;
-
- if (typeof onNavigation === 'function') {
- this.onNavigation = function(e) {
- // e.url is not present for local files or data URIs,
- // or probably for those URLs which we don't have access to
- if (!e.target || !e.target.url) {
- return;
- }
-
- onNavigation({
- frameId: 0,
- tabId: vAPI.tabs.getTabId(e.target),
- url: e.target.url
- });
- };
-
- safari.application.addEventListener('navigate', this.onNavigation, true);
- }
-
- // ??
- /* if (typeof this.onUpdated === 'function') { } */
-
- // onClosed handled in the main tab-close event
- // onPopup is handled in window.open on web-pages?
- /* if (typeof onPopup === 'function') { } */
-};
-
-/******************************************************************************/
-
-vAPI.tabs.getTabId = function(tab) {
- for (var i in vAPI.tabs.stack) {
- if (vAPI.tabs.stack[i] === tab) {
- return +i;
- }
- }
-
- return -1;
-};
-
-/******************************************************************************/
-
-vAPI.tabs.get = function(tabId, callback) {
- var tab;
-
- if (tabId === null) {
- tab = safari.application.activeBrowserWindow.activeTab;
- tabId = this.getTabId(tab);
- }
- else {
- tab = this.stack[tabId];
- }
-
- if (!tab) {
- callback();
- return;
- }
-
- callback({
- id: tabId,
- index: tab.browserWindow.tabs.indexOf(tab),
- windowId: safari.application.browserWindows.indexOf(tab.browserWindow),
- active: tab === tab.browserWindow.activeTab,
- url: tab.url,
- title: tab.title
- });
-};
-// properties of the details object:
-// url: 'URL', // the address that will be opened
-// tabId: 1, // the tab is used if set, instead of creating a new one
-// index: -1, // undefined: end of the list, -1: following tab, or after index
-// active: false, // opens the tab in background - true and undefined: foreground
-// select: true // if a tab is already opened with that url, then select it instead of opening a new one
-
-/******************************************************************************/
-
-vAPI.tabs.open = function(details) {
- if (!details.url) {
- return null;
- }
- // extension pages
- if (!/^[\w-]{2,}:/.test(details.url)) {
- details.url = vAPI.getURL(details.url);
- }
-
- var curWin, tab;
-
- if (details.select) {
- tab = safari.application.browserWindows.some(function(win) {
- var rgxHash = /#.*/;
- // this is questionable
- var url = details.url.replace(rgxHash, '');
-
- for (var i = 0; i < win.tabs.length; ++i) {
- if (win.tabs[i].url.replace(rgxHash, '') === url) {
- win.tabs[i].activate();
- return true;
- }
- }
- });
-
- if (tab) {
- return;
- }
- }
-
- if (details.active === undefined) {
- details.active = true;
- }
-
- curWin = safari.application.activeBrowserWindow;
-
- // it must be calculated before opening a new tab,
- // otherwise the new tab will be the active tab here
- if (details.index === -1) {
- details.index = curWin.tabs.indexOf(curWin.activeTab) + 1;
- }
-
- tab = details.tabId && this.stack[details.tabId]
- || curWin.openTab(details.active ? 'foreground' : 'background');
-
- if (details.index !== undefined) {
- curWin.insertTab(tab, details.index);
- }
-
- tab.url = details.url;
-};
-
-/******************************************************************************/
-
-vAPI.tabs.close = function(tab) {
- if (!(tab instanceof SafariBrowserTab)) {
- tab = this.stack[tab];
- }
-
- if (tab) {
- tab.close();
- }
-};
-
-/******************************************************************************/
-
-vAPI.tabs.injectScript = function(tabId, details, callback) {
- var tab;
-
- if (tabId) {
- tab = this.stack[tabId];
- }
- else {
- tab = safari.application.activeBrowserWindow.activeTab;
- }
-
- if (details.file) {
- var xhr = new XMLHttpRequest;
- xhr.overrideMimeType('application/x-javascript;charset=utf-8');
- xhr.open('GET', details.file, false);
- xhr.send();
- details.code = xhr.responseText;
- }
-
- tab.page.dispatchMessage('broadcast', {
- portName: 'vAPI',
- msg: {
- cmd: 'runScript',
- details: details
- }
- });
-
- if (typeof callback === 'function') {
- setTimeout(callback, 13);
- }
-};
-
-/******************************************************************************/
-
-// bind tabs to unique IDs
-
-(function() {
- var wins = safari.application.browserWindows, i = wins.length, j;
- var tabs = [];
-
- while (i--) {
- j = wins[i].tabs.length;
-
- while (j--) {
- tabs.push(wins[i].tabs[j]);
- }
- }
-
- return tabs;
-})().forEach(function(tab) {
- vAPI.tabs.stack[vAPI.tabs.stackID++] = tab;
-});
-
-/******************************************************************************/
-
-safari.application.addEventListener('open', function(e) {
- // ignore windows
- if (e.target instanceof SafariBrowserTab) {
- vAPI.tabs.stack[vAPI.tabs.stackID++] = e.target;
- }
-}, true);
-
-/******************************************************************************/
-
-safari.application.addEventListener('close', function(e) {
- // ignore windows
- if (!(e.target instanceof SafariBrowserTab)) {
- return;
- }
-
- var tabId = vAPI.tabs.getTabId(e.target);
-
- if (tabId > -1) {
- // to not add another listener, put this here
- // instead of vAPI.tabs.registerListeners
- if (typeof vAPI.tabs.onClosed === 'function') {
- vAPI.tabs.onClosed(tabId);
- }
-
- delete vAPI.tabIcons[tabId];
- delete vAPI.tabs.stack[tabId];
- }
-}, true);
-
-/******************************************************************************/
-
-// update badge when tab is activated
-safari.application.addEventListener('activate', function(e) {
- // hide popover, since in some cases won't close by itself
- var items = safari.extension.toolbarItems;
-
- for (var i = 0; i < items.length; ++i) {
- if (items[i].browserWindow === safari.application.activeBrowserWindow) {
- if (items[i].popover) {
- items[i].popover.hide();
- }
-
- break;
- }
- }
-
- // ignore windows
- if (!(e.target instanceof SafariBrowserTab)) {
- return;
- }
-
- // update the badge, when tab is selected
- vAPI.setIcon();
-}, true);
-
-/******************************************************************************/
-
-// reload the popup when that is opened
-safari.application.addEventListener('popover', function(e) {
- e.target.contentWindow.document.body.textContent = '';
- e.target.contentWindow.location.reload();
-}, true);
-
-/******************************************************************************/
-
-vAPI.tabIcons = { /*tabId: {badge: 0, img: dict}*/ };
-vAPI.setIcon = function(tabId, img, badge) {
- var curTabId = vAPI.tabs.getTabId(
- safari.application.activeBrowserWindow.activeTab
- );
-
- // from 'activate' event
- if (tabId === undefined) {
- tabId = curTabId;
- }
- else {
- vAPI.tabIcons[tabId] = {
- badge: badge || 0/*,
- img: img*/
- };
- }
-
- if (tabId !== curTabId) {
- return;
- }
-
- // if the selected tab has the same ID, then update the badge too,
- // or always update it when changing tabs ('activate' event)
- var items = safari.extension.toolbarItems, i = items.length;
-
- while (i--) {
- if (items[i].browserWindow === safari.application.activeBrowserWindow) {
- if (vAPI.tabIcons[tabId]) {
- items[i].badge = vAPI.tabIcons[tabId].badge;
- // items[i].img = vAPI.tabIcons[tabId].img;
- }
- else {
- items[i].badge = 0;
- }
-
- return;
- }
- }
-};
-
-/******************************************************************************/
-
-vAPI.messaging = {
- listeners: {},
- defaultHandler: null,
- NOOPFUNC: function(){},
- UNHANDLED: 'vAPI.messaging.notHandled'
-};
-
-/******************************************************************************/
-
-vAPI.messaging.listen = function(listenerName, callback) {
- this.listeners[listenerName] = callback;
-};
-
-/******************************************************************************/
-
-vAPI.messaging.onMessage = function(request) {
- var callback = vAPI.messaging.NOOPFUNC;
- if ( request.message.requestId !== undefined ) {
- callback = function(response) {
- request.target.page.dispatchMessage(
- request.name,
- {
- requestId: request.message.requestId,
- portName: request.message.portName,
- msg: response !== undefined ? response : null
- }
- );
- };
- }
-
- var sender = {
- tab: {
- id: vAPI.tabs.getTabId(request.target)
- }
- };
-
- // Specific handler
- var r = vAPI.messaging.UNHANDLED;
- var listener = vAPI.messaging.listeners[request.message.portName];
- if ( typeof listener === 'function' ) {
- r = listener(request.message.msg, sender, callback);
- }
- if ( r !== vAPI.messaging.UNHANDLED ) {
- return;
- }
-
- // Default handler
- r = vAPI.messaging.defaultHandler(request.message.msg, sender, callback);
- if ( r !== vAPI.messaging.UNHANDLED ) {
- return;
- }
-
- console.error('µBlock> messaging > unknown request: %o', request.message);
-
- // Unhandled:
- // Need to callback anyways in case caller expected an answer, or
- // else there is a memory leak on caller's side
- callback();
-};
-
-/******************************************************************************/
-
-vAPI.messaging.setup = function(defaultHandler) {
- // Already setup?
- if ( this.defaultHandler !== null ) {
- return;
- }
-
- if ( typeof defaultHandler !== 'function' ) {
- defaultHandler = function(){ return vAPI.messaging.UNHANDLED; };
- }
- this.defaultHandler = defaultHandler;
-
- // the third parameter must stay false (bubbling), so later
- // onBeforeRequest will use true (capturing), where we can invoke
- // stopPropagation() (this way this.onMessage won't be fired)
- safari.application.addEventListener('message', this.onMessage, false);
-};
-
-/******************************************************************************/
-
-vAPI.messaging.broadcast = function(message) {
- message = {
- broadcast: true,
- msg: message
- };
-
- for (var tabId in vAPI.tabs.stack) {
- vAPI.tabs.stack[tabId].page.dispatchMessage('broadcast', message);
- }
-};
-
-/******************************************************************************/
-
-vAPI.net = {}
-
-/******************************************************************************/
-
-vAPI.net.registerListeners = function() {
- var onBeforeRequest = this.onBeforeRequest;
-
- if (typeof onBeforeRequest.callback === 'function') {
- if (!Array.isArray(onBeforeRequest.types)) {
- onBeforeRequest.types = [];
- }
-
- onBeforeRequest = onBeforeRequest.callback;
- this.onBeforeRequest.callback = function(e) {
- var block;
-
- if (e.name !== 'canLoad') {
- return;
- }
-
- // no stopPropagation if it was called from beforeNavigate event
- if (e.stopPropagation) {
- e.stopPropagation();
- }
-
- if (e.message.isWhiteListed) {
- block = µBlock.URI.hostnameFromURI(e.message.isWhiteListed);
- block = µBlock.URI.domainFromHostname(block) || block;
- e.message = !!µBlock.netWhitelist[block];
- return e.message;
- }
-
- // blocking unwanted pop-ups
- if (e.message.type === 'popup') {
- if (typeof vAPI.tabs.onPopup === 'function') {
- e.message.type = 'main_frame';
- e.message.sourceTabId = vAPI.tabs.getTabId(e.target);
-
- if (vAPI.tabs.onPopup(e.message)) {
- e.message = false;
- return;
- }
- }
-
- e.message = true;
- return;
- }
-
- block = vAPI.net.onBeforeRequest;
-
- if (block.types.indexOf(e.message.type) < 0) {
- return true;
- }
-
- e.message.tabId = vAPI.tabs.getTabId(e.target);
- block = onBeforeRequest(e.message);
-
- // truthy return value will allow the request,
- // except when redirectUrl is present
- if (block && typeof block === 'object') {
- if (block.cancel) {
- e.message = false;
- }
- else if (e.message.type === 'script'
- && typeof block.redirectUrl === "string") {
- e.message = block.redirectUrl;
- }
- else {
- e.message = true;
- }
- }
- else {
- e.message = true;
- }
-
- return e.message;
- };
-
- safari.application.addEventListener('message', this.onBeforeRequest.callback, true);
- }
-};
-
-/******************************************************************************/
-
-vAPI.contextMenu = {};
-
-/******************************************************************************/
-
-vAPI.contextMenu.create = function(details, callback) {
- var contexts = details.contexts;
- var menuItemId = details.id;
- var menuTitle = details.title;
-
- if (Array.isArray(contexts) && contexts.length) {
- contexts = contexts.indexOf('all') === -1 ? contexts : null;
- }
- else {
- // default in Chrome
- contexts = ['page'];
- }
-
- this.onContextMenu = function(e) {
- var uI = e.userInfo;
-
- if (uI && /^https?:\/\//i.test(uI.pageUrl)) {
- if (contexts) {
- var invalidContext = true;
-
- for (var i = 0; i < contexts.length; ++i) {
- if (contexts[i] === 'frame') {
- if (uI.insideFrame) {
- invalidContext = false;
- break;
- }
- }
- else if (contexts[i] === 'link') {
- if (uI.linkHref) {
- invalidContext = false;
- break;
- }
- }
- else if (contexts[i] === 'image') {
- if (uI.srcUrl) {
- invalidContext = false;
- break;
- }
- }
- else if (contexts[i] === 'audio'
- || contexts[i] === 'video') {
- if (uI.srcUrl && uI.tagName === contexts[i]) {
- invalidContext = false;
- break;
- }
- }
- else if (contexts[i] === 'editable') {
- if (uI.editable) {
- invalidContext = false;
- break;
- }
- }
- else if (contexts[i] === 'page') {
- if (!(uI.insideFrame || uI.linkHref
- || uI.mediaType || uI.editable)) {
- invalidContext = false;
- break;
- }
- }
- }
-
- if (invalidContext) {
- return;
- }
- }
-
- e.contextMenu.appendContextMenuItem(menuItemId, menuTitle);
- }
- };
-
- this.onContextMenuCmd = function(e) {
- if (e.command === menuItemId) {
- var tab = e.currentTarget.activeBrowserWindow.activeTab;
- e.userInfo.menuItemId = menuItemId;
- callback(e.userInfo, tab ? {
- id: vAPI.tabs.getTabId(tab),
- url: tab.url
- } : undefined);
- }
- };
-
- safari.application.addEventListener('contextmenu', this.onContextMenu);
- safari.application.addEventListener("command", this.onContextMenuCmd);
-};
-
-/******************************************************************************/
-
-vAPI.contextMenu.remove = function() {
- safari.application.removeEventListener('contextmenu', this.onContextMenu);
- safari.application.removeEventListener("command", this.onContextMenuCmd);
- this.onContextMenu = null;
- this.onContextMenuCmd = null;
-};
-
-/******************************************************************************/
-
-vAPI.lastError = function() {
- return null;
-};
-
-/******************************************************************************/
-
-})();
diff --git a/meta/safariextz/vapi-client.js b/meta/safariextz/vapi-client.js
deleted file mode 100644
index 65e4002..0000000
--- a/meta/safariextz/vapi-client.js
+++ /dev/null
@@ -1,405 +0,0 @@
-/*******************************************************************************
-
- µBlock - a Chromium browser extension to block requests.
- Copyright (C) 2014 The µBlock authors
-
- 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/}.
-
- Home: https://github.com/gorhill/uBlock
-*/
-
-// For non background pages
-
-/******************************************************************************/
-
-(function() {
-
-'use strict';
-
-/******************************************************************************/
-
-self.vAPI = self.vAPI || {};
-self.vAPI.safari = true;
-
-/******************************************************************************/
-
-var messagingConnector = function(response) {
- if ( !response ) {
- return;
- }
-
- var channel, listener;
-
- if ( response.broadcast === true ) {
- for ( channel in vAPI.messaging.channels ) {
- listener = vAPI.messaging.channels[channel].listener;
- if ( typeof listener === 'function' ) {
- listener(response.msg);
- }
- }
- return;
- }
-
- if ( response.requestId ) {
- listener = vAPI.messaging.listeners[response.requestId];
- delete vAPI.messaging.listeners[response.requestId];
- delete response.requestId;
- }
-
- if ( !listener ) {
- channel = vAPI.messaging.channels[response.portName];
- listener = channel && channel.listener;
- }
-
- if ( typeof listener === 'function' ) {
- listener(response.msg);
- }
-};
-
-/******************************************************************************/
-
-var uniqueId = function() {
- return parseInt(Math.random() * 1e10, 10).toString(36);
-};
-
-/******************************************************************************/
-
-// relevant?
-// https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/MessagesandProxies/MessagesandProxies.html#//apple_ref/doc/uid/TP40009977-CH14-SW12
-vAPI.messaging = {
- channels: {},
- listeners: {},
- requestId: 1,
- connectorId: uniqueId(),
-
- setup: function() {
- this.connector = function(msg) {
- // messages from the background script are sent to every frame,
- // so we need to check the connectorId to accept only
- // what is meant for the current context
- if (msg.name === vAPI.messaging.connectorId
- || msg.name === 'broadcast') {
- messagingConnector(msg.message);
- }
- };
- safari.self.addEventListener('message', this.connector, false);
-
- this.channels['vAPI'] = {
- listener: function(msg) {
- if (msg.cmd === 'runScript' && msg.details.code) {
- Function(msg.details.code).call(self);
- }
- }
- };
- },
- close: function() {
- if (this.connector) {
- safari.self.removeEventListener('message', this.connector, false);
- this.connector = null;
- this.channels = {};
- this.listeners = {};
- }
- },
- channel: function(channelName, callback) {
- if ( !channelName ) {
- return;
- }
-
- this.channels[channelName] = {
- portName: channelName,
- listener: typeof callback === 'function' ? callback : null,
- send: function(message, callback) {
- if (!vAPI.messaging.connector) {
- vAPI.messaging.setup();
- }
-
- message = {
- portName: this.portName,
- msg: message
- };
-
- if ( callback ) {
- message.requestId = vAPI.messaging.requestId++;
- vAPI.messaging.listeners[message.requestId] = callback;
- }
-
- // popover content doesn't know messaging...
- if (safari.extension.globalPage) {
- if (!safari.self.visible) {
- return;
- }
-
- safari.extension.globalPage.contentWindow
- .vAPI.messaging.onMessage({
- name: vAPI.messaging.connectorId,
- message: message,
- target: {
- page: {
- dispatchMessage: function(name, msg) {
- messagingConnector(msg);
- }
- }
- }
- });
- }
- else {
- safari.self.tab.dispatchMessage(
- vAPI.messaging.connectorId,
- message
- );
- }
- },
- close: function() {
- delete vAPI.messaging.channels[this.portName];
- }
- };
-
- return this.channels[channelName];
- }
-};
-
-/******************************************************************************/
-
-// content scripts are loaded into extension pages by default, but they shouldn't
-
-if (location.protocol === "safari-extension:") {
- return;
-}
-
-/******************************************************************************/
-
-window.MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
-
-if (!window.MutationObserver) {
- // dummy, minimalistic shim for older versions (<6)
- // only supports node insertions, but currently we don't use it for anything else
- window.MutationObserver = function(handler) {
- this.observe = function(target) {
- target.addEventListener('DOMNodeInserted', function(e) {
- handler([{addedNodes: [e.target]}]);
- }, true);
- };
- };
-}
-
-/******************************************************************************/
-
-var beforeLoadEvent = document.createEvent('Event');
-beforeLoadEvent.initEvent('beforeload');
-
-/******************************************************************************/
-
-var frameId = window === window.top ? 0 : Date.now() % 1E5;
-var linkHelper = document.createElement('a');
-var onBeforeLoad = function(e, details) {
- if (e.url && e.url.slice(0, 5) === 'data:') {
- return;
- }
-
- linkHelper.href = details ? details.url : e.url;
-
- if (!/^https?:/.test(linkHelper.protocol)) {
- return;
- }
-
- if (details) {
- details.url = linkHelper.href;
- }
- else {
- details = {
- url: linkHelper.href
- };
-
- switch (e.target.nodeName.toLowerCase()) {
- case 'frame':
- case 'iframe':
- details.type = 'sub_frame';
- break;
- case 'script':
- details.type = 'script';
- break;
- case 'img':
- case 'input': // type=image
- details.type = 'image';
- break;
- case 'object':
- case 'embed':
- details.type = 'object';
- break;
- case 'link':
- var rel = e.target.rel.trim().toLowerCase();
-
- if (rel.indexOf('icon') > -1) {
- details.type = 'image';
- break;
- }
- else if (rel === 'stylesheet') {
- details.type = 'stylesheet';
- break;
- }
- default:
- details.type = 'other';
- }
-
- // This can run even before the first DOMSubtreeModified event fired
- if (firstMutation) {
- firstMutation();
- }
- }
-
- // tabId is determined in the background script
- // details.tabId = null;
- details.frameId = frameId;
- details.parentFrameId = frameId ? 0 : -1;
- details.timeStamp = Date.now();
-
- var response = safari.self.tab.canLoad(e, details);
-
- if (!response) {
- if (details.type === 'main_frame') {
- window.stop();
- }
- else {
- e.preventDefault();
- }
-
- return false;
- }
- // local mirroring, response is a data: URL here
- else if (typeof response === 'string' && details.type === 'script') {
- // Content Security Policy with disallowed inline scripts may break things
- e.preventDefault();
- details = document.createElement('script');
- details.textContent = atob(response.slice(response.indexOf(',', 20) + 1));
-
- if (e.target.hasAttribute('defer') && document.readyState === 'loading') {
- var jsOnLoad = function(ev) {
- this.removeEventListener(ev.type, jsOnLoad, true);
- this.body.removeChild(this.body.appendChild(details));
- };
-
- document.addEventListener('DOMContentLoaded', jsOnLoad, true);
- }
- else {
- e.target.parentNode.insertBefore(details, e.target);
- details.parentNode.removeChild(details);
- }
- }
-};
-
-document.addEventListener('beforeload', onBeforeLoad, true);
-
-/******************************************************************************/
-
-// block pop-ups, intercept xhr requests, and apply site patches
-var firstMutation = function() {
- document.removeEventListener('DOMSubtreeModified', firstMutation, true);
- firstMutation = null;
- var randEventName = parseInt(Math.random() * 1e15, 10).toString(36);
-
- window.addEventListener(randEventName, function(e) {
- var result = onBeforeLoad(beforeLoadEvent, e.detail);
-
- if (result === false) {
- e.detail.url = false;
- }
- }, true);
-
- // the extension context is unable to reach the page context,
- // also this only works when Content Security Policy allows inline scripts
- var tmpJS = document.createElement('script');
- var tmpScript = ["(function() {",
- "var block = function(u, t) {",
- "var e = document.createEvent('CustomEvent'),",
- "d = {url: u, type: t};",
- "e.initCustomEvent('" + randEventName + "', !1, !1, d);",
- "dispatchEvent(e);",
- "return d.url === !1;",
- "}, wo = open, xo = XMLHttpRequest.prototype.open;",
- "open = function(u) {",
- "return block(u, 'popup') ? null : wo.apply(this, [].slice.call(arguments));",
- "};",
- "XMLHttpRequest.prototype.open = function(m, u, s) {",
- "return xo.apply(this, block(u, 'xmlhttprequest') ? ['HEAD', u, s] : [].slice.call(arguments));",
- "};"
- ];
-
- if (vAPI.sitePatch
- && !safari.self.tab.canLoad(beforeLoadEvent, {isWhiteListed: location.href})) {
- tmpScript.push('(' + vAPI.sitePatch + ')();');
- }
-
- tmpScript.push("})();");
- tmpJS.textContent = tmpScript.join('');
- document.documentElement.removeChild(document.documentElement.appendChild(tmpJS));
-};
-
-document.addEventListener('DOMSubtreeModified', firstMutation, true);
-
-/******************************************************************************/
-
-var onContextMenu = function(e) {
- var details = {
- tagName: e.target.tagName.toLowerCase(),
- pageUrl: location.href,
- insideFrame: window !== window.top
- };
-
- details.editable = details.tagName === 'textarea' || details.tagName === 'input';
-
- if ('checked' in e.target) {
- details.checked = e.target.checked;
- }
-
- if (details.tagName === 'a') {
- details.linkUrl = e.target.href;
- }
-
- if ('src' in e.target) {
- details.srcUrl = e.target.src;
-
- if (details.tagName === 'img') {
- details.mediaType = 'image';
- }
- else if (details.tagName === 'video' || details.tagName === 'audio') {
- details.mediaType = details.tagName;
- }
- }
-
- safari.self.tab.setContextMenuEventUserInfo(e, details);
-};
-
-self.addEventListener('contextmenu', onContextMenu, true);
-
-/******************************************************************************/
-
-// 'main_frame' simulation
-if (frameId === 0) {
- onBeforeLoad(beforeLoadEvent, {
- url: location.href,
- type: 'main_frame'
- });
-}
-
-/******************************************************************************/
-
-self.vAPI.canExecuteContentScript = function() {
- return /^https?:/.test(location.protocol);
-};
-
-/******************************************************************************/
-
-})();
-
-/******************************************************************************/
diff --git a/meta/safariextz/vapi-common.js b/meta/safariextz/vapi-common.js
deleted file mode 100644
index 2021d77..0000000
--- a/meta/safariextz/vapi-common.js
+++ /dev/null
@@ -1,156 +0,0 @@
-/*******************************************************************************
-
- µBlock - a Chromium browser extension to block requests.
- Copyright (C) 2014 The µBlock authors
-
- 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/}.
-
- Home: https://github.com/gorhill/uBlock
-*/
-
-// For background page or non-background pages
-
-/******************************************************************************/
-
-(function() {
-
-'use strict';
-
-self.vAPI = self.vAPI || {};
-
-/******************************************************************************/
-
-// http://www.w3.org/International/questions/qa-scripts#directions
-
-var setScriptDirection = function(language) {
- document.body.setAttribute(
- 'dir',
- ~['ar', 'he', 'fa', 'ps', 'ur'].indexOf(language) ? 'rtl' : 'ltr'
- );
-};
-
-/******************************************************************************/
-
-vAPI.download = function(details) {
- if ( !details.url ) {
- return;
- }
-
- var a = document.createElement('a');
-
- if ( 'download' in a ) {
- a.href = details.url;
- a.setAttribute('download', details.filename || '');
- a.dispatchEvent(new MouseEvent('click'));
- return;
- }
-
- var messager = vAPI.messaging.channel('_download');
- messager.send({
- what: 'gotoURL',
- details: {
- url: details.url,
- index: -1
- }
- });
- messager.close();
-};
-
-/******************************************************************************/
-
-vAPI.getURL = function(path) {
- return safari.extension.baseURI + path;
-};
-
-/******************************************************************************/
-
-// supported languages
-// first language is the default
-vAPI.i18nData = [
- "en", "ar", "cs", "da", "de", "el", "es", "et", "fi", "fr", "he", "hi",
- "hr", "hu", "id", "it", "ja", "mr", "nb", "nl", "pl", "pt_BR", "pt_PT",
- "ro", "ru", "sv", "tr", "uk", "vi", "zh_CN"
-];
-
-vAPI.i18n = navigator.language.replace('-', '_');
-
-if (vAPI.i18nData.indexOf(vAPI.i18n) === -1) {
- vAPI.i18n = vAPI.i18n.slice(0, 2);
-
- if (vAPI.i18nData.indexOf(vAPI.i18n) === -1) {
- vAPI.i18n = vAPI.i18nData[0];
- }
-}
-
-setScriptDirection(vAPI.i18n);
-
-var xhr = new XMLHttpRequest;
-xhr.overrideMimeType('application/json;charset=utf-8');
-xhr.open('GET', './_locales/' + vAPI.i18n + '/messages.json', false);
-xhr.send();
-vAPI.i18nData = JSON.parse(xhr.responseText);
-
-for (var i18nKey in vAPI.i18nData) {
- vAPI.i18nData[i18nKey] = vAPI.i18nData[i18nKey].message;
-}
-
-vAPI.i18n = function(s) {
- return this.i18nData[s] || s;
-};
-
-/******************************************************************************/
-
-// update popover size to its content
-if (safari.self.identifier === 'popover') {
- var onLoaded = function() {
- // Initial dimensions are set in Info.plist
- var pWidth = safari.self.width;
- var pHeight = safari.self.height;
- var upadteTimer = null;
- var resizePopover = function() {
- if (upadteTimer) {
- return;
- }
-
- upadteTimer = setTimeout(function() {
- safari.self.width = Math.max(pWidth, document.body.clientWidth);
- safari.self.height = Math.max(pHeight, document.body.clientHeight);
- upadteTimer = null;
- }, 20);
- };
-
- var mutObs = window.MutationObserver || window.WebkitMutationObserver;
-
- if (mutObs) {
- (new mutObs(resizePopover)).observe(document, {
- childList: true,
- attributes: true,
- characterData: true,
- subtree: true
- });
- }
- else {
- // Safari doesn't support DOMAttrModified
- document.addEventListener('DOMSubtreeModified', resizePopover);
- }
- };
-
- window.addEventListener('load', onLoaded);
-}
-
-/******************************************************************************/
-
-})();
-
-/******************************************************************************/