diff --git a/platform/chromium/vapi-client.js b/platform/chromium/vapi-client.js
index 4b0f56256..d1d096605 100644
--- a/platform/chromium/vapi-client.js
+++ b/platform/chromium/vapi-client.js
@@ -25,14 +25,13 @@
/******************************************************************************/
-(function() {
+(function(self) {
'use strict';
/******************************************************************************/
var vAPI = self.vAPI = self.vAPI || {};
-
var chrome = self.chrome;
// https://github.com/gorhill/uBlock/issues/456
@@ -40,8 +39,10 @@ var chrome = self.chrome;
if ( vAPI.vapiClientInjected ) {
return;
}
-vAPI.vapiClientInjected = true;
+vAPI.vapiClientInjected = true;
+vAPI.sessionId = String.fromCharCode(Date.now() % 25 + 97) +
+ Math.random().toString(36).slice(2);
vAPI.chrome = true;
/******************************************************************************/
@@ -85,21 +86,14 @@ var messagingConnector = function(response) {
/******************************************************************************/
-var uniqueId = function() {
- return Math.random().toString(36).slice(2);
-};
-
-/******************************************************************************/
-
vAPI.messaging = {
port: null,
channels: {},
listeners: {},
requestId: 1,
- connectorId: uniqueId(),
setup: function() {
- this.port = chrome.runtime.connect({name: this.connectorId});
+ this.port = chrome.runtime.connect({name: vAPI.sessionId});
this.port.onMessage.addListener(messagingConnector);
},
@@ -150,6 +144,6 @@ vAPI.messaging = {
/******************************************************************************/
-})();
+})(this);
/******************************************************************************/
diff --git a/platform/firefox/vapi-client.js b/platform/firefox/vapi-client.js
index c9caa85d4..2d35b2e12 100644
--- a/platform/firefox/vapi-client.js
+++ b/platform/firefox/vapi-client.js
@@ -31,8 +31,10 @@
/******************************************************************************/
-self.vAPI = self.vAPI || {};
+var vAPI = self.vAPI = self.vAPI || {};
vAPI.firefox = true;
+vAPI.sessionId = String.fromCharCode(Date.now() % 25 + 97) +
+ Math.random().toString(36).slice(2);
/******************************************************************************/
diff --git a/platform/safari/vapi-client.js b/platform/safari/vapi-client.js
index 2e6285f5f..3eb57e954 100644
--- a/platform/safari/vapi-client.js
+++ b/platform/safari/vapi-client.js
@@ -21,7 +21,7 @@
/******************************************************************************/
// For non background pages
-(function() {
+(function(self) {
'use strict';
var vAPI = self.vAPI = self.vAPI || {};
if(vAPI.vapiClientInjected) {
@@ -29,7 +29,8 @@
}
vAPI.vapiClientInjected = true;
vAPI.safari = true;
-
+ vAPI.sessionId = String.fromCharCode(Date.now() % 25 + 97) +
+ Math.random().toString(36).slice(2);
/******************************************************************************/
var messagingConnector = function(response) {
if(!response) {
@@ -63,26 +64,21 @@
}
};
/******************************************************************************/
- var uniqueId = function() {
- return Math.random().toString(36).slice(2);
- };
- /******************************************************************************/
// 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() {
if(typeof safari === "undefined") {
return;
}
this.connector = function(msg) {
// messages from the background script are sent to every frame,
- // so we need to check the connectorId to accept only
+ // so we need to check the vAPI.sessionId to accept only
// what is meant for the current context
- if(msg.name === vAPI.messaging.connectorId || msg.name === 'broadcast') {
+ if(msg.name === vAPI.sessionId || msg.name === 'broadcast') {
messagingConnector(msg.message);
}
};
@@ -131,7 +127,7 @@
return;
}
safari.extension.globalPage.contentWindow.vAPI.messaging.onMessage({
- name: vAPI.messaging.connectorId,
+ name: vAPI.sessionId,
message: message,
target: {
page: {
@@ -142,7 +138,7 @@
}
});
} else {
- safari.self.tab.dispatchMessage(vAPI.messaging.connectorId, message);
+ safari.self.tab.dispatchMessage(vAPI.sessionId, message);
}
},
close: function() {
@@ -215,8 +211,7 @@
var firstMutation = function() {
document.removeEventListener("DOMContentLoaded", firstMutation, true);
firstMutation = false;
- var randEventName = uniqueId();
- document.addEventListener(randEventName, function(e) {
+ document.addEventListener(vAPI.sessionId, function(e) {
if(shouldBlockDetailedRequest(e.detail)) {
e.detail.url = false;
}
@@ -225,7 +220,7 @@
var tmpScript = "\
(function() {\
var block = function(u, t) {\
-var e = new CustomEvent('" + randEventName + "', {\
+var e = new CustomEvent('" + vAPI.sessionId + "', {\
detail: {\
url: u,\
type: t\
@@ -298,5 +293,5 @@ return r;\
safari.self.tab.setContextMenuEventUserInfo(e, details);
};
self.addEventListener("contextmenu", onContextMenu, true);
-})();
+})(this);
/******************************************************************************/
diff --git a/src/epicker.html b/src/epicker.html
new file mode 100644
index 000000000..7b0d081ca
--- /dev/null
+++ b/src/epicker.html
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+ {{netFilters}}
+
+ -
+ {{cosmeticFilters}} {{cosmeticFiltersHint}}
+
+
+
+
diff --git a/src/js/element-picker.js b/src/js/element-picker.js
index 7915aea4f..e521dd4c9 100644
--- a/src/js/element-picker.js
+++ b/src/js/element-picker.js
@@ -125,12 +125,7 @@ if ( window.top !== window ) {
return;
}
-// https://github.com/gorhill/uBlock/issues/314#issuecomment-58878112
-// Using an id makes uBlock's CSS rules more specific, thus prevents
-// surrounding external rules from winning over own rules.
-var µBlockId = CSS.escape('µBlock');
-
-var pickerRoot = document.getElementById(µBlockId);
+var pickerRoot = document.getElementById(vAPI.sessionId);
if ( pickerRoot ) {
return;
@@ -138,22 +133,22 @@ if ( pickerRoot ) {
var localMessager = vAPI.messaging.channel('element-picker.js');
-var svgns = 'http://www.w3.org/2000/svg';
-
var svgRoot = null;
var svgOcean = null;
var svgIslands = null;
-var divDialog = null;
+var frameDialog = null;
+var dialogBody = null;
var taCandidate = null;
var urlNormalizer = null;
+var lastDetails = null;
+
var netFilterCandidates = [];
var cosmeticFilterCandidates = [];
var targetElements = [];
var svgWidth = 0;
var svgHeight = 0;
-var elementFromPointCSSProperty = 'pointerEvents';
var onSvgHoveredTimer = null;
/******************************************************************************/
@@ -189,20 +184,6 @@ var unpausePicker = function() {
/******************************************************************************/
-var pickerRootDistance = function(elem) {
- var distance = 0;
- while ( elem ) {
- if ( elem === pickerRoot ) {
- return distance;
- }
- elem = elem.parentNode;
- distance += 1;
- }
- return -1;
-};
-
-/******************************************************************************/
-
var highlightElements = function(elems, force) {
// To make mouse move handler more efficient
if ( !force && elems.length === targetElements.length ) {
@@ -479,7 +460,7 @@ var userFilterFromCandidate = function() {
var onCandidateChanged = function() {
var elems = elementsFromFilter(taCandidate.value);
- divDialog.querySelector('#create').disabled = elems.length === 0;
+ dialogBody.querySelector('#create').disabled = elems.length === 0;
highlightElements(elems);
};
@@ -554,7 +535,7 @@ var onDialogClicked = function(ev) {
stopPicker();
}
- else if ( ev.target.tagName.toLowerCase() === 'li' && pickerRootDistance(ev.target) === 5 ) {
+ else if ( ev.target.parentNode.classList.contains('changeFilter') ) {
taCandidate.value = candidateFromFilterChoice(filterChoiceFromEvent(ev));
onCandidateChanged();
}
@@ -583,7 +564,7 @@ var showDialog = function(options) {
// Create lists of candidate filters
var populate = function(src, des) {
- var root = divDialog.querySelector(des);
+ var root = dialogBody.querySelector(des);
var ul = root.querySelector('ul');
removeAllChildren(ul);
var li;
@@ -598,8 +579,8 @@ var showDialog = function(options) {
populate(netFilterCandidates, '#netFilters');
populate(cosmeticFilterCandidates, '#cosmeticFilters');
- divDialog.querySelector('ul').style.display = netFilterCandidates.length || cosmeticFilterCandidates.length ? '' : 'none';
- divDialog.querySelector('#create').disabled = true;
+ dialogBody.querySelector('ul').style.display = netFilterCandidates.length || cosmeticFilterCandidates.length ? '' : 'none';
+ dialogBody.querySelector('#create').disabled = true;
// Auto-select a candidate filter
var filterChoice = {
@@ -621,17 +602,19 @@ var showDialog = function(options) {
taCandidate.value = candidateFromFilterChoice(filterChoice);
onCandidateChanged();
}
+
+ frameDialog.style.height = dialogBody.offsetHeight + 'px';
};
/******************************************************************************/
var elementFromPoint = function(x, y) {
- svgRoot.style[elementFromPointCSSProperty] = 'none';
+ svgRoot.style.pointerEvents = 'none';
var elem = document.elementFromPoint(x, y);
if ( elem === document.body || elem === document.documentElement ) {
elem = null;
}
- svgRoot.style[elementFromPointCSSProperty] = '';
+ svgRoot.style.pointerEvents = '';
return elem;
};
@@ -699,12 +682,13 @@ var stopPicker = function() {
window.removeEventListener('keydown', onKeyPressed, true);
window.removeEventListener('scroll', onScrolled, true);
taCandidate.removeEventListener('input', onCandidateChanged);
- divDialog.removeEventListener('click', onDialogClicked);
+ dialogBody.removeEventListener('click', onDialogClicked);
svgRoot.removeEventListener('mousemove', onSvgHovered);
svgRoot.removeEventListener('click', onSvgClicked);
pickerRoot.parentNode.removeChild(pickerRoot);
pickerRoot =
- divDialog =
+ frameDialog =
+ dialogBody =
svgRoot = svgOcean = svgIslands =
taCandidate =
urlNormalizer = null;
@@ -715,267 +699,29 @@ var stopPicker = function() {
/******************************************************************************/
-var startPicker = function(details) {
- pickerRoot = document.createElement('div');
- pickerRoot.id = µBlockId;
- pickerRoot.setAttribute('lang', navigator.language);
+var onFrameReady = function() {
+ var elem;
+ var details = lastDetails;
+ this.onload = lastDetails = null;
- var pickerStyle = document.createElement('style');
- pickerStyle.setAttribute('scoped', '');
- pickerStyle.textContent = [
- '#µBlock, #µBlock * {',
- 'background: transparent;',
- 'background-image: none;',
- 'border: 0;',
- 'border-radius: 0;',
- 'box-shadow: none;',
- 'color: #000;',
- 'display: inline;',
- 'float: none;',
- 'font: 12px sans-serif;',
- 'height: auto;',
- 'letter-spacing: normal;',
- 'margin: 0;',
- 'max-width: none;',
- 'min-height: 0;',
- 'min-width: 0;',
- 'outline: 0;',
- 'overflow: visible;',
- 'padding: 0;',
- 'text-transform: none;',
- 'vertical-align: baseline;',
- 'width: auto;',
- 'z-index: auto;',
- '}',
- '#µBlock {',
- 'position: absolute;',
- 'top: 0;',
- 'left: 0;',
- '}',
- '#µBlock style, #µBlock script {',
- 'display: none;',
- '}',
- '#µBlock ul, #µBlock li, #µBlock div {',
- 'display: block;',
- '}',
- '#µBlock *::selection {',
- 'background-color: Highlight;',
- 'color: HighlightText;',
- '}',
- '#µBlock button {',
- 'border: 1px solid #aaa !important;',
- 'padding: 6px 8px 4px 8px;',
- 'box-sizing: border-box;',
- 'box-shadow: none;',
- 'border-radius: 3px;',
- 'display: inline;',
- 'line-height: 1;',
- 'color: #444;',
- 'background-color: #ccc;',
- 'cursor: pointer;',
- '}',
- '#µBlock button:hover {',
- 'background: none;',
- 'background-color: #eee;',
- 'background-image: none;',
- '}',
- '#µBlock button:disabled {',
- 'color: #999;',
- 'background-color: #ccc;',
- '}',
- '#µBlock button#create:not(:disabled) {',
- 'background-color: #ffdca8;',
- '}',
- '#µBlock > svg {',
- 'position: absolute;',
- 'top: 0;',
- 'left: 0;',
- 'pointer-events: auto;',
- 'cursor: crosshair;',
- 'z-index: 4999999999;',
- '}',
- '#µBlock.paused > svg {',
- 'cursor: wait;',
- '}',
- '#µBlock > svg > path:first-child {',
- 'fill: rgba(0,0,0,0.75);',
- 'fill-rule: evenodd;',
- '}',
- '#µBlock > svg > path + path {',
- 'stroke: #F00;',
- 'stroke-width: 0.5px;',
- 'fill: rgba(255,0,0,0.25);',
- '}',
- '#µBlock > div {',
- 'background-color: rgba(255,255,255,0.9);',
- 'bottom: 4px;',
- 'display: none;',
- 'font: 12px sans-serif;',
- 'padding: 4px;',
- 'position: fixed;',
- 'right: 4px;',
- 'width: 30em;',
- 'z-index: 5999999999;',
- '}',
- '#µBlock.paused > div {',
- 'opacity: 0.2;',
- 'display: block;',
- '}',
- '#µBlock.paused > div:hover {',
- 'opacity: 1;',
- '}',
- '#µBlock > div > div {',
- 'box-sizing: border-box;',
- 'display: inline-block;',
- 'height: 8em;',
- 'padding: 0;',
- 'position: relative;',
- 'width: 100%;',
- '}',
- '#µBlock > div > div > textarea {',
- 'background-color: white;',
- 'border: 1px solid #ccc;',
- 'box-sizing: border-box;',
- 'font: 11px monospace;',
- 'height: 100% !important;',
- 'max-height: 100% !important;',
- 'min-height: 100% !important;',
- 'overflow: hidden !important;',
- 'padding: 2px;',
- 'resize: none;',
- 'width: 100% !important;',
- '}',
- '#µBlock > div > div > div {',
- 'bottom: 2px;',
- 'direction: ltr;',
- 'opacity: 0.2;',
- 'position: absolute;',
- 'right: 2px;',
- '}',
- '#µBlock > div > div > div:hover {',
- 'opacity: 1;',
- '}',
- '#µBlock > div > div > div > button {',
- 'margin-left: 3px !important;',
- '}',
- '#µBlock > div > ul {',
- 'margin: 0;',
- 'list-style-type: none;',
- 'text-align: left;',
- 'overflow: hidden;',
- '}',
- '#µBlock > div > ul > li {',
- 'padding-top: 3px;',
- '}',
- '#µBlock > div > ul > li > span:nth-of-type(1) {',
- 'font-weight: bold;',
- '}',
- '#µBlock > div > ul > li > span:nth-of-type(2) {',
- 'font-size: smaller;',
- 'color: gray;',
- '}',
- '#µBlock > div > ul > li > ul {',
- 'background-color: #eee;',
- 'list-style-type: none;',
- 'margin: 0 0 0 1em;',
- 'overflow: hidden;',
- 'text-align: left;',
- '}',
- '#µBlock > div > ul > li > ul > li {',
- 'font: 11px monospace;',
- 'white-space: nowrap;',
- 'cursor: pointer;',
- 'direction: ltr;',
- '}',
- '#µBlock > div > ul > li > ul > li:hover {',
- 'background-color: rgba(255,255,255,1.0);',
- '}',
- ''
- ].join('\n');
- pickerRoot.appendChild(pickerStyle);
-
- svgRoot = document.createElementNS(svgns, 'svg');
- svgRoot.appendChild(document.createElementNS(svgns, 'path'));
- svgRoot.appendChild(document.createElementNS(svgns, 'path'));
- svgWidth = document.documentElement.scrollWidth;
- svgHeight = Math.max(
- document.documentElement.scrollHeight,
- window.scrollY + window.innerHeight
+ var parsedDom = (new DOMParser()).parseFromString(
+ details.frameContent,
+ 'text/html'
+ );
+ var frameDoc = this.contentDocument;
+ frameDoc.documentElement.replaceChild(
+ frameDoc.adoptNode(parsedDom.head),
+ frameDoc.head
+ );
+ frameDoc.documentElement.replaceChild(
+ frameDoc.adoptNode(parsedDom.body),
+ frameDoc.body
);
- svgRoot.setAttribute('x', 0);
- svgRoot.setAttribute('y', 0);
- svgRoot.style.width = svgWidth + 'px';
- svgRoot.style.height = svgHeight + 'px';
- svgRoot.setAttribute('viewBox', '0 0 ' + svgWidth + ' ' + svgHeight);
- svgOcean = svgRoot.firstChild;
- svgIslands = svgRoot.lastChild;
- pickerRoot.appendChild(svgRoot);
- // TODO: do not rely on element ids, they could collide with whatever
- // is used in the page. Just use built-in hierarchy of elements as
- // selectors.
-
- divDialog = document.createElement('div');
- divDialog.innerHTML = [
- '',
- '
',
- '
',
- '',
- '',
- '',
- '
',
- '
',
- ''
- ].join('');
- pickerRoot.appendChild(divDialog);
-
- // https://github.com/gorhill/uBlock/issues/344#issuecomment-60775958
- // Insert in `html` tag, not `body` tag.
- document.documentElement.appendChild(pickerRoot);
- svgRoot.addEventListener('click', onSvgClicked);
- svgRoot.addEventListener('mousemove', onSvgHovered);
- divDialog.addEventListener('click', onDialogClicked);
- taCandidate = divDialog.querySelector('textarea');
+ dialogBody = frameDoc.body;
+ dialogBody.addEventListener('click', onDialogClicked);
+ taCandidate = dialogBody.querySelector('textarea');
taCandidate.addEventListener('input', onCandidateChanged);
- urlNormalizer = document.createElement('a');
- window.addEventListener('scroll', onScrolled, true);
- window.addEventListener('keydown', onKeyPressed, true);
-
- highlightElements([], true);
-
- var i18nMap = {
- '#µBlock > div': '@@bidi_dir',
- '#create': 'create',
- '#pick': 'pick',
- '#quit': 'quit',
- 'ul > li#netFilters > span:nth-of-type(1)': 'netFilters',
- 'ul > li#cosmeticFilters > span:nth-of-type(1)': 'cosmeticFilters',
- 'ul > li#cosmeticFilters > span:nth-of-type(2)': 'cosmeticFiltersHint'
- };
-
- if ( details.i18n['@@bidi_dir'] ) {
- divDialog.style.direction = details.i18n['@@bidi_dir'];
- delete i18nMap['#µBlock > div'];
- }
-
- for ( var k in i18nMap ) {
- if ( i18nMap.hasOwnProperty(k) === false ) {
- continue;
- }
- divDialog.querySelector(k).firstChild.nodeValue = details.i18n[i18nMap[k]];
- }
-
- // First we test if pointer-events are hadnled in Node.elementFromPoint().
- // If the browser ignores pointer-events in Node.elementFromPoint(),
- // then use the display property instead (e.g., for older Safari).
- var elem = elementFromPoint(0, 0);
-
- if ( elem === svgRoot ) {
- elementFromPointCSSProperty = 'display';
- }
// Auto-select a specific target, if any, and if possible
@@ -1028,6 +774,124 @@ var startPicker = function(details) {
/******************************************************************************/
+var startPicker = function(details) {
+ pickerRoot = document.createElement('div');
+ var pid = vAPI.sessionId;
+ pickerRoot.id = pid;
+ pickerRoot.setAttribute('lang', navigator.language);
+
+ var pickerStyle = document.createElement('style');
+ pickerStyle.setAttribute('scoped', '');
+ pid = '#' + pid;
+ pickerStyle.textContent = [
+ pid + ' {',
+ 'position: absolute;',
+ 'top: 0;',
+ 'left: 0;',
+ '}',
+ pid + ', ' + pid + ' > iframe, ' + pid + ' > svg {',
+ 'background: transparent;',
+ 'border: 0;',
+ 'border-radius: 0;',
+ 'box-shadow: none;',
+ 'display: inline;',
+ 'float: none;',
+ 'height: auto;',
+ 'margin: 0;',
+ 'max-width: none;',
+ 'min-height: 0;',
+ 'min-width: 0;',
+ 'outline: 0;',
+ 'overflow: visible;',
+ 'padding: 0;',
+ 'width: auto;',
+ 'z-index: auto;',
+ '}',
+ pid + ' > svg {',
+ 'position: absolute;',
+ 'top: 0;',
+ 'left: 0;',
+ 'pointer-events: auto;',
+ 'cursor: crosshair;',
+ 'z-index: 4999999999;',
+ '}',
+ pid + '.paused > svg {',
+ 'cursor: wait;',
+ '}',
+ pid + ' > svg > path:first-child {',
+ 'fill: rgba(0,0,0,0.75);',
+ 'fill-rule: evenodd;',
+ '}',
+ pid + ' > svg > path + path {',
+ 'stroke: #F00;',
+ 'stroke-width: 0.5px;',
+ 'fill: rgba(255,0,0,0.25);',
+ '}',
+ pid + ' > iframe {',
+ 'background-color: rgba(255,255,255,0.9);',
+ 'bottom: 4px;',
+ 'display: none;',
+ 'padding: 4px;',
+ 'position: fixed;',
+ 'right: 4px;',
+ 'width: 30em;',
+ 'z-index: 5999999999;',
+ '}',
+ pid + '.paused > iframe {',
+ 'opacity: 0.2;',
+ 'display: block;',
+ '}',
+ pid + '.paused > iframe:hover {',
+ 'opacity: 1;',
+ '}',
+ ''
+ ].join('\n');
+ pickerRoot.appendChild(pickerStyle);
+
+ var svgns = 'http://www.w3.org/2000/svg';
+ svgRoot = document.createElementNS(svgns, 'svg');
+ svgRoot.appendChild(document.createElementNS(svgns, 'path'));
+ svgRoot.appendChild(document.createElementNS(svgns, 'path'));
+ svgWidth = document.documentElement.scrollWidth;
+ svgHeight = Math.max(
+ document.documentElement.scrollHeight,
+ window.scrollY + window.innerHeight
+ );
+ svgRoot.setAttribute('x', 0);
+ svgRoot.setAttribute('y', 0);
+ svgRoot.style.width = svgWidth + 'px';
+ svgRoot.style.height = svgHeight + 'px';
+ svgRoot.setAttribute('viewBox', '0 0 ' + svgWidth + ' ' + svgHeight);
+ svgOcean = svgRoot.firstChild;
+ svgIslands = svgRoot.lastChild;
+ pickerRoot.appendChild(svgRoot);
+
+ // https://github.com/gorhill/uBlock/issues/344#issuecomment-60775958
+ // Insert in `html` tag, not `body` tag.
+ document.documentElement.appendChild(pickerRoot);
+ svgRoot.addEventListener('click', onSvgClicked);
+ svgRoot.addEventListener('mousemove', onSvgHovered);
+ urlNormalizer = document.createElement('a');
+ window.addEventListener('scroll', onScrolled, true);
+ window.addEventListener('keydown', onKeyPressed, true);
+
+ highlightElements([], true);
+
+ lastDetails = {
+ frameContent: details.frameContent,
+ clientX: details.clientX,
+ clientY: details.clientY,
+ target: details.target
+ };
+
+ frameDialog = document.createElement('iframe');
+ frameDialog.setAttribute('seamless', '');
+ frameDialog.onload = onFrameReady;
+ pickerRoot.appendChild(frameDialog);
+};
+
+/******************************************************************************/
+
localMessager.send({ what: 'elementPickerArguments' }, startPicker);
// So the shortcuts will be usable in Firefox
diff --git a/src/js/messaging.js b/src/js/messaging.js
index 22894d903..6d7176ce7 100644
--- a/src/js/messaging.js
+++ b/src/js/messaging.js
@@ -527,6 +527,40 @@ var µb = µBlock;
var onMessage = function(request, sender, callback) {
// Async
switch ( request.what ) {
+ case 'elementPickerArguments':
+ var xhr = new XMLHttpRequest();
+ xhr.open('GET', 'epicker.html', true);
+ xhr.overrideMimeType('text/html;charset=utf-8');
+ xhr.responseType = 'text';
+ xhr.onload = function() {
+ this.onload = null;
+ var i18n = {
+ bidi_dir: document.body.getAttribute('dir'),
+ create: vAPI.i18n('pickerCreate'),
+ pick: vAPI.i18n('pickerPick'),
+ quit: vAPI.i18n('pickerQuit'),
+ netFilters: vAPI.i18n('pickerNetFilters'),
+ cosmeticFilters: vAPI.i18n('pickerCosmeticFilters'),
+ cosmeticFiltersHint: vAPI.i18n('pickerCosmeticFiltersHint')
+ };
+ var reStrings = /\{\{(\w+)\}\}/g;
+ var replacer = function(a0, string) {
+ return i18n[string];
+ };
+
+ callback({
+ frameContent: this.responseText.replace(reStrings, replacer),
+ target: µb.contextMenuTarget,
+ clientX: µb.contextMenuClientX,
+ clientY: µb.contextMenuClientY
+ });
+
+ µb.contextMenuTarget = '';
+ µb.contextMenuClientX = -1;
+ µb.contextMenuClientY = -1;
+ };
+ xhr.send();
+ return;
default:
break;
}
@@ -535,26 +569,6 @@ var onMessage = function(request, sender, callback) {
var response;
switch ( request.what ) {
- case 'elementPickerArguments':
- response = {
- i18n: {
- '@@bidi_dir': document.body.getAttribute('dir'),
- create: vAPI.i18n('pickerCreate'),
- pick: vAPI.i18n('pickerPick'),
- quit: vAPI.i18n('pickerQuit'),
- netFilters: vAPI.i18n('pickerNetFilters'),
- cosmeticFilters: vAPI.i18n('pickerCosmeticFilters'),
- cosmeticFiltersHint: vAPI.i18n('pickerCosmeticFiltersHint')
- },
- target: µb.contextMenuTarget,
- clientX: µb.contextMenuClientX,
- clientY: µb.contextMenuClientY
- };
- µb.contextMenuTarget = '';
- µb.contextMenuClientX = -1;
- µb.contextMenuClientY = -1;
- break;
-
case 'createUserFilter':
µb.appendUserFilters(request.filters);
break;