зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to b2g-inbound.
This commit is contained in:
Коммит
3a898fba7a
|
@ -3,7 +3,6 @@
|
|||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
|
||||
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
<Description about="urn:mozilla:install-manifest">
|
||||
|
@ -17,7 +16,7 @@
|
|||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>21.0</em:minVersion>
|
||||
<em:minVersion>26.0</em:minVersion>
|
||||
<em:maxVersion>29.0a1</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
|
|
@ -34,8 +34,15 @@ const { events: stateEvents } = require('../state/events');
|
|||
const { events: viewEvents } = require('./view/events');
|
||||
const events = require('../../event/utils');
|
||||
|
||||
const { id: addonID } = require('../../self');
|
||||
const { identify } = require('../id');
|
||||
|
||||
const buttons = new Map();
|
||||
|
||||
const toWidgetId = id =>
|
||||
('action-button--' + addonID.toLowerCase()+ '-' + id).
|
||||
replace(/[^a-z0-9_-]/g, '');
|
||||
|
||||
const ActionButton = Class({
|
||||
extends: EventTarget,
|
||||
implements: [
|
||||
|
@ -48,32 +55,37 @@ const ActionButton = Class({
|
|||
disabled: false
|
||||
}, buttonContract(options));
|
||||
|
||||
let id = toWidgetId(options.id);
|
||||
|
||||
register(this, state);
|
||||
|
||||
// Setup listeners.
|
||||
setListeners(this, options);
|
||||
|
||||
buttons.set(options.id, this);
|
||||
buttons.set(id, this);
|
||||
|
||||
view.create(state);
|
||||
view.create(merge({}, state, { id: id }));
|
||||
},
|
||||
|
||||
dispose: function dispose() {
|
||||
buttons.delete(this.id);
|
||||
let id = toWidgetId(this.id);
|
||||
buttons.delete(id);
|
||||
|
||||
off(this);
|
||||
|
||||
view.dispose(this.id);
|
||||
view.dispose(id);
|
||||
|
||||
unregister(this);
|
||||
},
|
||||
|
||||
get id() this.state().id,
|
||||
|
||||
click: function click() { view.click(this.id) }
|
||||
click: function click() { view.click(toWidgetId(this.id)) }
|
||||
});
|
||||
exports.ActionButton = ActionButton;
|
||||
|
||||
identify.define(ActionButton, ({id}) => toWidgetId(id));
|
||||
|
||||
let actionButtonStateEvents = events.filter(stateEvents,
|
||||
e => e.target instanceof ActionButton);
|
||||
|
||||
|
@ -95,7 +107,7 @@ on(updateEvents, 'data', ({target: id, window}) => {
|
|||
});
|
||||
|
||||
on(actionButtonStateEvents, 'data', ({target, window, state}) => {
|
||||
let { id } = target;
|
||||
let id = toWidgetId(target.id);
|
||||
view.setIcon(id, window, state.icon);
|
||||
view.setLabel(id, window, state.label);
|
||||
view.setDisabled(id, window, state.disabled);
|
||||
|
|
|
@ -34,8 +34,15 @@ const { events: stateEvents } = require('../state/events');
|
|||
const { events: viewEvents } = require('./view/events');
|
||||
const events = require('../../event/utils');
|
||||
|
||||
const { id: addonID } = require('../../self');
|
||||
const { identify } = require('../id');
|
||||
|
||||
const buttons = new Map();
|
||||
|
||||
const toWidgetId = id =>
|
||||
('toggle-button--' + addonID.toLowerCase()+ '-' + id).
|
||||
replace(/[^a-z0-9_-]/g, '');
|
||||
|
||||
const ToggleButton = Class({
|
||||
extends: EventTarget,
|
||||
implements: [
|
||||
|
@ -49,32 +56,37 @@ const ToggleButton = Class({
|
|||
checked: false
|
||||
}, toggleButtonContract(options));
|
||||
|
||||
let id = toWidgetId(options.id);
|
||||
|
||||
register(this, state);
|
||||
|
||||
// Setup listeners.
|
||||
setListeners(this, options);
|
||||
|
||||
buttons.set(options.id, this);
|
||||
buttons.set(id, this);
|
||||
|
||||
view.create(merge({ type: 'checkbox' }, state));
|
||||
view.create(merge({ type: 'checkbox' }, state, { id: id }));
|
||||
},
|
||||
|
||||
dispose: function dispose() {
|
||||
buttons.delete(this.id);
|
||||
let id = toWidgetId(this.id);
|
||||
buttons.delete(id);
|
||||
|
||||
off(this);
|
||||
|
||||
view.dispose(this.id);
|
||||
view.dispose(id);
|
||||
|
||||
unregister(this);
|
||||
},
|
||||
|
||||
get id() this.state().id,
|
||||
|
||||
click: function click() view.click(this.id)
|
||||
click: function click() view.click(toWidgetId(this.id))
|
||||
});
|
||||
exports.ToggleButton = ToggleButton;
|
||||
|
||||
identify.define(ToggleButton, ({id}) => toWidgetId(id));
|
||||
|
||||
let toggleButtonStateEvents = events.filter(stateEvents,
|
||||
e => e.target instanceof ToggleButton);
|
||||
|
||||
|
@ -85,7 +97,8 @@ let clickEvents = events.filter(toggleButtonViewEvents, e => e.type === 'click')
|
|||
let updateEvents = events.filter(toggleButtonViewEvents, e => e.type === 'update');
|
||||
|
||||
on(toggleButtonStateEvents, 'data', ({target, window, state}) => {
|
||||
let { id } = target;
|
||||
let id = toWidgetId(target.id);
|
||||
|
||||
view.setIcon(id, window, state.icon);
|
||||
view.setLabel(id, window, state.label);
|
||||
view.setDisabled(id, window, state.disabled);
|
||||
|
|
|
@ -13,9 +13,7 @@ module.metadata = {
|
|||
const { Cu } = require('chrome');
|
||||
const { on, off, emit } = require('../../event/core');
|
||||
|
||||
const { id: addonID, data } = require('sdk/self');
|
||||
const buttonPrefix =
|
||||
'button--' + addonID.toLowerCase().replace(/[^a-z0-9-_]/g, '');
|
||||
const { data } = require('sdk/self');
|
||||
|
||||
const { isObject } = require('../../lang/type');
|
||||
|
||||
|
@ -28,9 +26,6 @@ const { events: viewEvents } = require('./view/events');
|
|||
|
||||
const XUL_NS = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul';
|
||||
|
||||
const toWidgetID = id => buttonPrefix + '-' + id;
|
||||
const toButtonID = id => id.substr(buttonPrefix.length + 1);
|
||||
|
||||
const views = new Map();
|
||||
const customizedWindows = new WeakMap();
|
||||
|
||||
|
@ -47,14 +42,14 @@ const buttonListener = {
|
|||
customizedWindows.delete(window);
|
||||
|
||||
for (let [id, ] of views) {
|
||||
let placement = CustomizableUI.getPlacementOfWidget(toWidgetID(id));
|
||||
let placement = CustomizableUI.getPlacementOfWidget(id);
|
||||
|
||||
if (placement)
|
||||
emit(viewEvents, 'data', { type: 'update', target: id, window: window });
|
||||
}
|
||||
},
|
||||
onWidgetAfterDOMChange: (node, nextNode, container) => {
|
||||
let id = toButtonID(node.id);
|
||||
let { id } = node;
|
||||
let view = views.get(id);
|
||||
let window = node.ownerDocument.defaultView;
|
||||
|
||||
|
@ -73,11 +68,11 @@ require('../../system/unload').when( _ =>
|
|||
function getNode(id, window) {
|
||||
return !views.has(id) || ignoreWindow(window)
|
||||
? null
|
||||
: CustomizableUI.getWidget(toWidgetID(id)).forWindow(window).node
|
||||
: CustomizableUI.getWidget(id).forWindow(window).node
|
||||
};
|
||||
|
||||
function isInToolbar(id) {
|
||||
let placement = CustomizableUI.getPlacementOfWidget(toWidgetID(id));
|
||||
let placement = CustomizableUI.getPlacementOfWidget(id);
|
||||
|
||||
return placement && CustomizableUI.getAreaType(placement.area) === 'toolbar';
|
||||
}
|
||||
|
@ -120,7 +115,7 @@ function create(options) {
|
|||
throw new Error('The ID "' + id + '" seems already used.');
|
||||
|
||||
CustomizableUI.createWidget({
|
||||
id: toWidgetID(id),
|
||||
id: id,
|
||||
type: 'custom',
|
||||
removable: true,
|
||||
defaultArea: AREA_NAVBAR,
|
||||
|
@ -131,7 +126,7 @@ function create(options) {
|
|||
|
||||
let node = document.createElementNS(XUL_NS, 'toolbarbutton');
|
||||
|
||||
let image = getImage(icon, false, window.devicePixelRatio);
|
||||
let image = getImage(icon, true, window.devicePixelRatio);
|
||||
|
||||
if (ignoreWindow(window))
|
||||
node.style.display = 'none';
|
||||
|
@ -170,7 +165,7 @@ function dispose(id) {
|
|||
if (!views.has(id)) return;
|
||||
|
||||
views.delete(id);
|
||||
CustomizableUI.destroyWidget(toWidgetID(id));
|
||||
CustomizableUI.destroyWidget(id);
|
||||
}
|
||||
exports.dispose = dispose;
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ DEFAULT_COMMON_PREFS = {
|
|||
# sets this preference)
|
||||
'browser.dom.window.dump.enabled': True,
|
||||
# warn about possibly incorrect code
|
||||
'javascript.options.strict': True,
|
||||
'javascript.options.showInConsole': True,
|
||||
|
||||
# Allow remote connections to the debugger
|
||||
|
|
|
@ -106,12 +106,24 @@ if not mswindows:
|
|||
class Popen(subprocess.Popen):
|
||||
kill_called = False
|
||||
if mswindows:
|
||||
def _execute_child(self, args, executable, preexec_fn, close_fds,
|
||||
cwd, env, universal_newlines, startupinfo,
|
||||
creationflags, shell,
|
||||
p2cread, p2cwrite,
|
||||
c2pread, c2pwrite,
|
||||
errread, errwrite):
|
||||
def _execute_child(self, *args_tuple):
|
||||
# workaround for bug 958609
|
||||
if sys.hexversion < 0x02070600: # prior to 2.7.6
|
||||
(args, executable, preexec_fn, close_fds,
|
||||
cwd, env, universal_newlines, startupinfo,
|
||||
creationflags, shell,
|
||||
p2cread, p2cwrite,
|
||||
c2pread, c2pwrite,
|
||||
errread, errwrite) = args_tuple
|
||||
to_close = set()
|
||||
else: # 2.7.6 and later
|
||||
(args, executable, preexec_fn, close_fds,
|
||||
cwd, env, universal_newlines, startupinfo,
|
||||
creationflags, shell, to_close,
|
||||
p2cread, p2cwrite,
|
||||
c2pread, c2pwrite,
|
||||
errread, errwrite) = args_tuple
|
||||
|
||||
if not isinstance(args, types.StringTypes):
|
||||
args = subprocess.list2cmdline(args)
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
'use strict';
|
||||
|
||||
module.metadata = {
|
||||
|
@ -11,7 +10,7 @@ module.metadata = {
|
|||
};
|
||||
|
||||
const { isTabOpen, activateTab, openTab,
|
||||
closeTab, getURI } = require('sdk/tabs/utils');
|
||||
closeTab, getTabURL, getWindowHoldingTab } = require('sdk/tabs/utils');
|
||||
const windows = require('sdk/deprecated/window-utils');
|
||||
const { LoaderWithHookedConsole } = require('sdk/test/loader');
|
||||
const { setTimeout } = require('sdk/timers');
|
||||
|
@ -19,10 +18,27 @@ const { is } = require('sdk/system/xul-app');
|
|||
const tabs = require('sdk/tabs');
|
||||
const isAustralis = "gCustomizeMode" in windows.activeBrowserWindow;
|
||||
const { set: setPref } = require("sdk/preferences/service");
|
||||
const { defer } = require('sdk/core/promise');
|
||||
|
||||
const DEPRECATE_PREF = "devtools.errorconsole.deprecation_warnings";
|
||||
|
||||
let uri = require('sdk/self').data.url('index.html');
|
||||
|
||||
function closeTabPromise(tab) {
|
||||
let { promise, resolve } = defer();
|
||||
let url = getTabURL(tab);
|
||||
|
||||
tabs.on('close', function onCloseTab(t) {
|
||||
if (t.url == url) {
|
||||
tabs.removeListener('close', onCloseTab);
|
||||
setTimeout(_ => resolve(tab))
|
||||
}
|
||||
});
|
||||
closeTab(tab);
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
function isChromeVisible(window) {
|
||||
let x = window.document.documentElement.getAttribute('disablechrome')
|
||||
return x !== 'true';
|
||||
|
@ -61,11 +77,12 @@ exports['test that add-on page has no chrome'] = function(assert, done) {
|
|||
assert.equal(isChromeVisible(window), is('Fennec') || isAustralis,
|
||||
'chrome is not visible for addon page');
|
||||
|
||||
closeTab(tab);
|
||||
assert.ok(isChromeVisible(window), 'chrome is visible again');
|
||||
loader.unload();
|
||||
assert.ok(!isTabOpen(tab), 'add-on page tab is closed on unload');
|
||||
done();
|
||||
closeTabPromise(tab).then(function() {
|
||||
assert.ok(isChromeVisible(window), 'chrome is visible again');
|
||||
loader.unload();
|
||||
assert.ok(!isTabOpen(tab), 'add-on page tab is closed on unload');
|
||||
done();
|
||||
}).then(null, assert.fail);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -86,11 +103,12 @@ exports['test that add-on page with hash has no chrome'] = function(assert, done
|
|||
assert.equal(isChromeVisible(window), is('Fennec') || isAustralis,
|
||||
'chrome is not visible for addon page');
|
||||
|
||||
closeTab(tab);
|
||||
assert.ok(isChromeVisible(window), 'chrome is visible again');
|
||||
loader.unload();
|
||||
assert.ok(!isTabOpen(tab), 'add-on page tab is closed on unload');
|
||||
done();
|
||||
closeTabPromise(tab).then(function() {
|
||||
assert.ok(isChromeVisible(window), 'chrome is visible again');
|
||||
loader.unload();
|
||||
assert.ok(!isTabOpen(tab), 'add-on page tab is closed on unload');
|
||||
done();
|
||||
}).then(null, assert.fail);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -111,11 +129,12 @@ exports['test that add-on page with querystring has no chrome'] = function(asser
|
|||
assert.equal(isChromeVisible(window), is('Fennec') || isAustralis,
|
||||
'chrome is not visible for addon page');
|
||||
|
||||
closeTab(tab);
|
||||
assert.ok(isChromeVisible(window), 'chrome is visible again');
|
||||
loader.unload();
|
||||
assert.ok(!isTabOpen(tab), 'add-on page tab is closed on unload');
|
||||
done();
|
||||
closeTabPromise(tab).then(function() {
|
||||
assert.ok(isChromeVisible(window), 'chrome is visible again');
|
||||
loader.unload();
|
||||
assert.ok(!isTabOpen(tab), 'add-on page tab is closed on unload');
|
||||
done();
|
||||
}).then(null, assert.fail);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -136,11 +155,12 @@ exports['test that add-on page with hash and querystring has no chrome'] = funct
|
|||
assert.equal(isChromeVisible(window), is('Fennec') || isAustralis,
|
||||
'chrome is not visible for addon page');
|
||||
|
||||
closeTab(tab);
|
||||
assert.ok(isChromeVisible(window), 'chrome is visible again');
|
||||
loader.unload();
|
||||
assert.ok(!isTabOpen(tab), 'add-on page tab is closed on unload');
|
||||
done();
|
||||
closeTabPromise(tab).then(function() {
|
||||
assert.ok(isChromeVisible(window), 'chrome is visible again');
|
||||
loader.unload();
|
||||
assert.ok(!isTabOpen(tab), 'add-on page tab is closed on unload');
|
||||
done();
|
||||
}).then(null, assert.fail);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -158,9 +178,10 @@ exports['test that malformed uri is not an addon-page'] = function(assert, done)
|
|||
|
||||
assert.ok(isChromeVisible(window), 'chrome is visible for malformed uri');
|
||||
|
||||
closeTab(tab);
|
||||
loader.unload();
|
||||
done();
|
||||
closeTabPromise(tab).then(function() {
|
||||
loader.unload();
|
||||
done();
|
||||
}).then(null, assert.fail);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -25,6 +25,40 @@ exports.testOptionsType = function(assert, done) {
|
|||
});
|
||||
}
|
||||
|
||||
exports.testButton = function(assert, done) {
|
||||
tabs.open({
|
||||
url: 'about:addons',
|
||||
onReady: function(tab) {
|
||||
sp.once('sayHello', function() {
|
||||
assert.pass('The button was pressed!');
|
||||
tab.close(done)
|
||||
});
|
||||
|
||||
tab.attach({
|
||||
contentScriptWhen: 'end',
|
||||
contentScript: 'function onLoad() {\n' +
|
||||
'unsafeWindow.removeEventListener("load", onLoad, false);\n' +
|
||||
'AddonManager.getAddonByID("' + self.id + '", function(aAddon) {\n' +
|
||||
'unsafeWindow.gViewController.viewObjects.detail.node.addEventListener("ViewChanged", function whenViewChanges() {\n' +
|
||||
'unsafeWindow.gViewController.viewObjects.detail.node.removeEventListener("ViewChanged", whenViewChanges, false);\n' +
|
||||
'setTimeout(function() {\n' + // TODO: figure out why this is necessary..
|
||||
'unsafeWindow.document.querySelector("button[label=\'Click me!\']").click()\n' +
|
||||
'}, 250);\n' +
|
||||
'}, false);\n' +
|
||||
'unsafeWindow.gViewController.commands.cmd_showItemDetails.doCommand(aAddon, true);\n' +
|
||||
'});\n' +
|
||||
'}\n' +
|
||||
// Wait for the load event ?
|
||||
'if (document.readyState == "complete") {\n' +
|
||||
'onLoad()\n' +
|
||||
'} else {\n' +
|
||||
'unsafeWindow.addEventListener("load", onLoad, false);\n' +
|
||||
'}\n',
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (app.is('Firefox')) {
|
||||
exports.testAOM = function(assert, done) {
|
||||
tabs.open({
|
||||
|
@ -41,7 +75,8 @@ if (app.is('Firefox')) {
|
|||
'self.postMessage({\n' +
|
||||
'somePreference: getAttributes(unsafeWindow.document.querySelector("setting[title=\'some-title\']")),\n' +
|
||||
'myInteger: getAttributes(unsafeWindow.document.querySelector("setting[title=\'my-int\']")),\n' +
|
||||
'myHiddenInt: getAttributes(unsafeWindow.document.querySelector("setting[title=\'hidden-int\']"))\n' +
|
||||
'myHiddenInt: getAttributes(unsafeWindow.document.querySelector("setting[title=\'hidden-int\']")),\n' +
|
||||
'sayHello: getAttributes(unsafeWindow.document.querySelector("button[label=\'Click me!\']"))\n' +
|
||||
'});\n' +
|
||||
'}, 250);\n' +
|
||||
'}, false);\n' +
|
||||
|
@ -53,7 +88,8 @@ if (app.is('Firefox')) {
|
|||
'pref: ele.getAttribute("pref"),\n' +
|
||||
'type: ele.getAttribute("type"),\n' +
|
||||
'title: ele.getAttribute("title"),\n' +
|
||||
'desc: ele.getAttribute("desc")\n' +
|
||||
'desc: ele.getAttribute("desc"),\n' +
|
||||
'"data-jetpack-id": ele.getAttribute(\'data-jetpack-id\')\n' +
|
||||
'}\n' +
|
||||
'}\n' +
|
||||
'}\n' +
|
||||
|
@ -69,12 +105,14 @@ if (app.is('Firefox')) {
|
|||
assert.equal(msg.somePreference.pref, 'extensions.'+self.id+'.somePreference', 'somePreference path is correct');
|
||||
assert.equal(msg.somePreference.title, 'some-title', 'somePreference title is correct');
|
||||
assert.equal(msg.somePreference.desc, 'Some short description for the preference', 'somePreference description is correct');
|
||||
assert.equal(msg.somePreference['data-jetpack-id'], self.id, 'data-jetpack-id attribute value is correct');
|
||||
|
||||
// test myInteger
|
||||
assert.equal(msg.myInteger.type, 'integer', 'myInteger is a int');
|
||||
assert.equal(msg.myInteger.pref, 'extensions.'+self.id+'.myInteger', 'extensions.test-simple-prefs.myInteger');
|
||||
assert.equal(msg.myInteger.title, 'my-int', 'myInteger title is correct');
|
||||
assert.equal(msg.myInteger.desc, 'How many of them we have.', 'myInteger desc is correct');
|
||||
assert.equal(msg.myInteger['data-jetpack-id'], self.id, 'data-jetpack-id attribute value is correct');
|
||||
|
||||
// test myHiddenInt
|
||||
assert.equal(msg.myHiddenInt.type, undefined, 'myHiddenInt was not displayed');
|
||||
|
@ -82,6 +120,9 @@ if (app.is('Firefox')) {
|
|||
assert.equal(msg.myHiddenInt.title, undefined, 'myHiddenInt was not displayed');
|
||||
assert.equal(msg.myHiddenInt.desc, undefined, 'myHiddenInt was not displayed');
|
||||
|
||||
// test sayHello
|
||||
assert.equal(msg.sayHello['data-jetpack-id'], self.id, 'data-jetpack-id attribute value is correct');
|
||||
|
||||
tab.close(done);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -19,5 +19,10 @@
|
|||
"hidden": true,
|
||||
"value": 5,
|
||||
"title": "hidden-int"
|
||||
}]
|
||||
}, {
|
||||
"name": "sayHello",
|
||||
"type": "control",
|
||||
"label": "Click me!",
|
||||
"title": "hello"
|
||||
}]
|
||||
}
|
||||
|
|
|
@ -260,20 +260,22 @@ exports.testTabLocation = function(assert, done) {
|
|||
|
||||
// TEST: tab.close()
|
||||
exports.testTabClose = function(assert, done) {
|
||||
let url = "data:text/html;charset=utf-8,foo";
|
||||
let testName = "testTabClose";
|
||||
let url = "data:text/html;charset=utf-8," + testName;
|
||||
|
||||
assert.notEqual(tabs.activeTab.url, url, "tab is not the active tab");
|
||||
tabs.on('ready', function onReady(tab) {
|
||||
tabs.removeListener('ready', onReady);
|
||||
tabs.once('ready', function onReady(tab) {
|
||||
assert.equal(tabs.activeTab.url, tab.url, "tab is now the active tab");
|
||||
assert.equal(url, tab.url, "tab url is the test url");
|
||||
let secondOnCloseCalled = false;
|
||||
|
||||
// Bug 699450: Multiple calls to tab.close should not throw
|
||||
tab.close(function() secondOnCloseCalled = true);
|
||||
try {
|
||||
tab.close(function () {
|
||||
assert.notEqual(tabs.activeTab.url, url, "tab is no longer the active tab");
|
||||
assert.ok(secondOnCloseCalled,
|
||||
"The immediate second call to tab.close gots its callback fired");
|
||||
"The immediate second call to tab.close happened");
|
||||
assert.notEqual(tabs.activeTab.url, url, "tab is no longer the active tab");
|
||||
|
||||
done();
|
||||
|
@ -282,7 +284,6 @@ exports.testTabClose = function(assert, done) {
|
|||
catch(e) {
|
||||
assert.fail("second call to tab.close() thrown an exception: " + e);
|
||||
}
|
||||
assert.notEqual(tabs.activeTab.url, url, "tab is no longer the active tab");
|
||||
});
|
||||
|
||||
tabs.open(url);
|
||||
|
|
|
@ -21,7 +21,7 @@ function getWidget(buttonId, window = getMostRecentBrowserWindow()) {
|
|||
const { AREA_NAVBAR } = CustomizableUI;
|
||||
|
||||
let widgets = CustomizableUI.getWidgetIdsInArea(AREA_NAVBAR).
|
||||
filter((id) => id.startsWith('button--') && id.endsWith(buttonId));
|
||||
filter((id) => id.startsWith('action-button--') && id.endsWith(buttonId));
|
||||
|
||||
if (widgets.length === 0)
|
||||
throw new Error('Widget with id `' + id +'` not found.');
|
||||
|
@ -594,6 +594,7 @@ exports['test button click'] = function(assert, done) {
|
|||
then(done, assert.fail);
|
||||
});
|
||||
}).then(null, assert.fail);
|
||||
|
||||
}
|
||||
|
||||
exports['test button icon set'] = function(assert) {
|
||||
|
|
|
@ -21,7 +21,7 @@ function getWidget(buttonId, window = getMostRecentBrowserWindow()) {
|
|||
const { AREA_NAVBAR } = CustomizableUI;
|
||||
|
||||
let widgets = CustomizableUI.getWidgetIdsInArea(AREA_NAVBAR).
|
||||
filter((id) => id.startsWith('button--') && id.endsWith(buttonId));
|
||||
filter((id) => id.startsWith('toggle-button--') && id.endsWith(buttonId));
|
||||
|
||||
if (widgets.length === 0)
|
||||
throw new Error('Widget with id `' + id +'` not found.');
|
||||
|
|
|
@ -62,6 +62,13 @@ let devtoolsWidgetPanel = {
|
|||
Services.obs.addObserver(this, 'remote-browser-frame-pending', false);
|
||||
Services.obs.addObserver(this, 'in-process-browser-or-app-frame-shown', false);
|
||||
Services.obs.addObserver(this, 'message-manager-disconnect', false);
|
||||
|
||||
let systemapp = document.querySelector('#systemapp').contentWindow;
|
||||
let frames = systemapp.document.querySelectorAll('iframe[mozapp]');
|
||||
for (let frame of frames) {
|
||||
let manifestURL = frame.getAttribute("mozapp");
|
||||
this.trackApp(manifestURL);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
|
|
@ -740,6 +740,7 @@ var PlacesMenuDNDHandler = {
|
|||
_closeDelayMs: 500,
|
||||
_loadTimer: null,
|
||||
_closeTimer: null,
|
||||
_closingTimerNode: null,
|
||||
|
||||
/**
|
||||
* Called when the user enters the <menu> element during a drag.
|
||||
|
@ -751,6 +752,15 @@ var PlacesMenuDNDHandler = {
|
|||
if (!this._isStaticContainer(event.target))
|
||||
return;
|
||||
|
||||
// If we re-enter the same menu or anchor before the close timer runs out,
|
||||
// we should ensure that we do not close:
|
||||
if (this._closeTimer && this._closingTimerNode === event.currentTarget) {
|
||||
this._closeTimer.cancel();
|
||||
this._closingTimerNode = null;
|
||||
this._closeTimer = null;
|
||||
}
|
||||
|
||||
PlacesControllerDragHelper.currentDropTarget = event.target;
|
||||
let popup = event.target.lastChild;
|
||||
if (this._loadTimer || popup.state === "showing" || popup.state === "open")
|
||||
return;
|
||||
|
@ -767,8 +777,6 @@ var PlacesMenuDNDHandler = {
|
|||
|
||||
/**
|
||||
* Handles dragleave on the <menu> element.
|
||||
* @returns true if the element is a container element (menu or
|
||||
* menu-toolbarbutton), false otherwise.
|
||||
*/
|
||||
onDragLeave: function PMDH_onDragLeave(event) {
|
||||
// Handle menu-button separate targets.
|
||||
|
@ -781,6 +789,7 @@ var PlacesMenuDNDHandler = {
|
|||
if (!this._isStaticContainer(event.target))
|
||||
return;
|
||||
|
||||
PlacesControllerDragHelper.currentDropTarget = null;
|
||||
let popup = event.target.lastChild;
|
||||
|
||||
if (this._loadTimer) {
|
||||
|
@ -788,8 +797,10 @@ var PlacesMenuDNDHandler = {
|
|||
this._loadTimer = null;
|
||||
}
|
||||
this._closeTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
this._closingTimerNode = event.currentTarget;
|
||||
this._closeTimer.initWithCallback(function() {
|
||||
this._closeTimer = null;
|
||||
this._closingTimerNode = null;
|
||||
let node = PlacesControllerDragHelper.currentDropTarget;
|
||||
let inHierarchy = false;
|
||||
while (node && !inHierarchy) {
|
||||
|
@ -845,6 +856,7 @@ var PlacesMenuDNDHandler = {
|
|||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
Ci.nsITreeView.DROP_ON);
|
||||
PlacesControllerDragHelper.onDrop(ip, event.dataTransfer);
|
||||
PlacesControllerDragHelper.currentDropTarget = null;
|
||||
event.stopPropagation();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1032,6 +1032,9 @@ let SocialStatusWidgetListener = {
|
|||
SocialStatus = {
|
||||
populateToolbarPalette: function() {
|
||||
this._toolbarHelper.populatePalette();
|
||||
|
||||
for (let provider of Social.providers)
|
||||
this.updateButton(provider.origin);
|
||||
},
|
||||
|
||||
removeProvider: function(origin) {
|
||||
|
|
|
@ -1049,7 +1049,7 @@
|
|||
|
||||
if (!this._previewMode) {
|
||||
this.mCurrentTab.removeAttribute("unread");
|
||||
this.selectedTab.lastAccessed = Date.now();
|
||||
oldTab.lastAccessed = Date.now();
|
||||
|
||||
let oldFindBar = oldTab._findBar;
|
||||
if (oldFindBar &&
|
||||
|
@ -4719,10 +4719,19 @@
|
|||
</getter>
|
||||
</property>
|
||||
|
||||
<property name="lastAccessed">
|
||||
<getter>
|
||||
return this.selected ? Date.now() : this._lastAccessed;
|
||||
</getter>
|
||||
<setter>
|
||||
this._lastAccessed = val;
|
||||
</setter>
|
||||
</property>
|
||||
<field name="_lastAccessed">0</field>
|
||||
|
||||
<field name="mOverCloseButton">false</field>
|
||||
<field name="mCorrespondingMenuitem">null</field>
|
||||
<field name="closing">false</field>
|
||||
<field name="lastAccessed">0</field>
|
||||
|
||||
<method name="_mouseenter">
|
||||
<body><![CDATA[
|
||||
|
|
|
@ -1,26 +1,24 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test for bug 739866.
|
||||
*
|
||||
* 1. Adds a new tab (but doesn't select it)
|
||||
* 2. Checks if timestamp on the new tab is 0
|
||||
* 3. Selects the new tab, checks that the timestamp is updated (>0)
|
||||
* 4. Selects the original tab & checks if new tab's timestamp has remained changed
|
||||
*/
|
||||
|
||||
function test() {
|
||||
let originalTab = gBrowser.selectedTab;
|
||||
isnot(originalTab.lastAccessed, 0, "selectedTab has been selected");
|
||||
ok(originalTab.lastAccessed <= Date.now(), "selectedTab has a valid timestamp");
|
||||
|
||||
let newTab = gBrowser.addTab("about:blank", {skipAnimation: true});
|
||||
is(newTab.lastAccessed, 0, "Timestamp on the new tab is 0.");
|
||||
is(newTab.lastAccessed, 0, "newTab hasn't been selected so far");
|
||||
|
||||
gBrowser.selectedTab = newTab;
|
||||
let newTabAccessedDate = newTab.lastAccessed;
|
||||
ok(newTabAccessedDate > 0, "Timestamp on the selected tab is more than 0.");
|
||||
// Date.now is not guaranteed to be monotonic, so include one second of fudge.
|
||||
let now = Date.now() + 1000;
|
||||
ok(newTabAccessedDate <= now, "Timestamp less than or equal current Date: " + newTabAccessedDate + " <= " + now);
|
||||
gBrowser.selectedTab = originalTab;
|
||||
is(newTab.lastAccessed, newTabAccessedDate, "New tab's timestamp remains the same.");
|
||||
|
||||
isnot(newTab.lastAccessed, 0, "newTab has been selected");
|
||||
ok(newTab.lastAccessed <= Date.now(), "newTab has a valid timestamp");
|
||||
|
||||
isnot(originalTab.lastAccessed, 0, "originalTab has been selected");
|
||||
ok(originalTab.lastAccessed <= Date.now(), "originalTab has a valid timestamp");
|
||||
|
||||
ok(originalTab.lastAccessed <= newTab.lastAccessed,
|
||||
"originalTab's timestamp must be lower than newTab's");
|
||||
|
||||
gBrowser.removeTab(newTab);
|
||||
}
|
||||
|
|
|
@ -1188,6 +1188,12 @@ SourceScripts.prototype = {
|
|||
return;
|
||||
}
|
||||
|
||||
if (aResponse.sources.length === 0) {
|
||||
DebuggerView.Sources.emptyText = L10N.getStr("noSourcesText");
|
||||
window.emit(EVENTS.SOURCES_ADDED);
|
||||
return;
|
||||
}
|
||||
|
||||
// Add all the sources in the debugger view sources container.
|
||||
for (let source of aResponse.sources) {
|
||||
// Ignore bogus scripts, e.g. generated from 'clientEvaluate' packets.
|
||||
|
@ -1690,11 +1696,10 @@ EventListeners.prototype = {
|
|||
if (aResponse.error) {
|
||||
const msg = "Error getting function definition site: " + aResponse.message;
|
||||
DevToolsUtils.reportException("scheduleEventListenersFetch", msg);
|
||||
deferred.reject(msg);
|
||||
return;
|
||||
} else {
|
||||
aListener.function.url = aResponse.url;
|
||||
}
|
||||
|
||||
aListener.function.url = aResponse.url;
|
||||
deferred.resolve(aListener);
|
||||
});
|
||||
|
||||
|
|
|
@ -637,6 +637,8 @@ let DebuggerView = {
|
|||
this.editor.clearHistory();
|
||||
this._editorSource = {};
|
||||
}
|
||||
|
||||
this.Sources.emptyText = L10N.getStr("loadingSourcesText");
|
||||
},
|
||||
|
||||
_startup: null,
|
||||
|
|
|
@ -52,6 +52,7 @@ support-files =
|
|||
doc_large-array-buffer.html
|
||||
doc_minified.html
|
||||
doc_minified_bogus_map.html
|
||||
doc_no-page-sources.html
|
||||
doc_pause-exceptions.html
|
||||
doc_pretty-print.html
|
||||
doc_pretty-print-2.html
|
||||
|
@ -131,6 +132,7 @@ support-files =
|
|||
[browser_dbg_location-changes-04-breakpoint.js]
|
||||
[browser_dbg_multiple-windows.js]
|
||||
[browser_dbg_navigation.js]
|
||||
[browser_dbg_no-page-sources.js]
|
||||
[browser_dbg_on-pause-highlight.js]
|
||||
[browser_dbg_panel-size.js]
|
||||
[browser_dbg_parser-01.js]
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Make sure the right text shows when the page has no sources.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_no-page-sources.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gEditor, gSources;
|
||||
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
|
||||
reloadActiveTab(gPanel, gDebugger.EVENTS.SOURCES_ADDED)
|
||||
.then(testSourcesEmptyText)
|
||||
.then(() => closeDebuggerAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testSourcesEmptyText() {
|
||||
is(gSources.itemCount, 0,
|
||||
"Found no entries in the sources widget.");
|
||||
|
||||
is(gEditor.getText().length, 0,
|
||||
"The source editor should not have any text displayed.");
|
||||
|
||||
is(gDebugger.document.querySelector("#sources .side-menu-widget-empty-text").getAttribute("value"),
|
||||
gDebugger.L10N.getStr("noSourcesText"),
|
||||
"The sources widget should now display 'This page has no sources'.");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gEditor = null;
|
||||
gSources = null;
|
||||
});
|
|
@ -0,0 +1,11 @@
|
|||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>This page has no sources</title>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
|
@ -1103,9 +1103,7 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
|
|||
// Skipping "blocked" because it doesn't work yet.
|
||||
|
||||
let timingsNode = $(".requests-menu-timings", target);
|
||||
let startCapNode = $(".requests-menu-timings-cap.start", timingsNode);
|
||||
let endCapNode = $(".requests-menu-timings-cap.end", timingsNode);
|
||||
let firstBox;
|
||||
let timingsTotal = $(".requests-menu-timings-total", timingsNode);
|
||||
|
||||
// Add a set of boxes representing timing information.
|
||||
for (let key of sections) {
|
||||
|
@ -1117,23 +1115,10 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
|
|||
let timingBox = document.createElement("hbox");
|
||||
timingBox.className = "requests-menu-timings-box " + key;
|
||||
timingBox.setAttribute("width", width);
|
||||
timingsNode.insertBefore(timingBox, endCapNode);
|
||||
|
||||
// Make the start cap inherit the aspect of the first timing box.
|
||||
if (!firstBox) {
|
||||
firstBox = timingBox;
|
||||
startCapNode.classList.add(key);
|
||||
}
|
||||
// Same goes for the end cap, inherit the aspect of the last timing box.
|
||||
endCapNode.classList.add(key);
|
||||
timingsNode.insertBefore(timingBox, timingsTotal);
|
||||
}
|
||||
}
|
||||
|
||||
// Since at least one timing box should've been rendered, unhide the
|
||||
// start and end timing cap nodes.
|
||||
startCapNode.hidden = false;
|
||||
endCapNode.hidden = false;
|
||||
|
||||
// Don't paint things while the waterfall view isn't even visible.
|
||||
if (NetMonitorView.currentFrontendMode != "network-inspector-view") {
|
||||
return;
|
||||
|
@ -1174,8 +1159,6 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
|
|||
// accurately translate and resize as needed.
|
||||
for (let { target, attachment } of this) {
|
||||
let timingsNode = $(".requests-menu-timings", target);
|
||||
let startCapNode = $(".requests-menu-timings-cap.start", target);
|
||||
let endCapNode = $(".requests-menu-timings-cap.end", target);
|
||||
let totalNode = $(".requests-menu-timings-total", target);
|
||||
let direction = window.isRTL ? -1 : 1;
|
||||
|
||||
|
@ -1192,8 +1175,6 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
|
|||
let revScaleX = "scaleX(" + (1 / scale) + ")";
|
||||
|
||||
timingsNode.style.transform = scaleX + " " + translateX;
|
||||
startCapNode.style.transform = revScaleX + " translateX(" + (direction * 0.5) + "px)";
|
||||
endCapNode.style.transform = revScaleX + " translateX(" + (direction * -0.5) + "px)";
|
||||
totalNode.style.transform = revScaleX;
|
||||
}
|
||||
},
|
||||
|
|
|
@ -161,8 +161,6 @@
|
|||
flex="1">
|
||||
<hbox class="requests-menu-timings"
|
||||
align="center">
|
||||
<hbox class="start requests-menu-timings-cap" hidden="true"/>
|
||||
<hbox class="end requests-menu-timings-cap" hidden="true"/>
|
||||
<label class="plain requests-menu-timings-total"/>
|
||||
</hbox>
|
||||
</hbox>
|
||||
|
|
|
@ -55,6 +55,7 @@ function StyleEditorUI(debuggee, target, panelDoc) {
|
|||
|
||||
this.editors = [];
|
||||
this.selectedEditor = null;
|
||||
this.savedLocations = {};
|
||||
|
||||
this._updateSourcesLabel = this._updateSourcesLabel.bind(this);
|
||||
this._onStyleSheetCreated = this._onStyleSheetCreated.bind(this);
|
||||
|
@ -104,13 +105,14 @@ StyleEditorUI.prototype = {
|
|||
let toolbox = gDevTools.getToolbox(this._target);
|
||||
return toolbox.initInspector().then(() => {
|
||||
this._walker = toolbox.walker;
|
||||
}).then(() => this.createUI())
|
||||
.then(() => this._debuggee.getStyleSheets())
|
||||
.then((styleSheets) => {
|
||||
this._resetStyleSheetList(styleSheets);
|
||||
}).then(() => {
|
||||
this.createUI();
|
||||
this._debuggee.getStyleSheets().then((styleSheets) => {
|
||||
this._resetStyleSheetList(styleSheets);
|
||||
|
||||
this._target.on("will-navigate", this._clear);
|
||||
this._target.on("navigate", this._onNewDocument);
|
||||
this._target.on("will-navigate", this._clear);
|
||||
this._target.on("navigate", this._onNewDocument);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -166,30 +168,6 @@ StyleEditorUI.prototype = {
|
|||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove all editors and add loading indicator.
|
||||
*/
|
||||
_clear: function() {
|
||||
// remember selected sheet and line number for next load
|
||||
if (this.selectedEditor && this.selectedEditor.sourceEditor) {
|
||||
let href = this.selectedEditor.styleSheet.href;
|
||||
let {line, ch} = this.selectedEditor.sourceEditor.getCursor();
|
||||
|
||||
this._styleSheetToSelect = {
|
||||
href: href,
|
||||
line: line,
|
||||
col: ch
|
||||
};
|
||||
}
|
||||
|
||||
this._clearStyleSheetEditors();
|
||||
this._view.removeAll();
|
||||
|
||||
this.selectedEditor = null;
|
||||
|
||||
this._root.classList.add("loading");
|
||||
},
|
||||
|
||||
/**
|
||||
* Add editors for all the given stylesheets to the UI.
|
||||
*
|
||||
|
@ -208,6 +186,37 @@ StyleEditorUI.prototype = {
|
|||
this.emit("stylesheets-reset");
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove all editors and add loading indicator.
|
||||
*/
|
||||
_clear: function() {
|
||||
// remember selected sheet and line number for next load
|
||||
if (this.selectedEditor && this.selectedEditor.sourceEditor) {
|
||||
let href = this.selectedEditor.styleSheet.href;
|
||||
let {line, ch} = this.selectedEditor.sourceEditor.getCursor();
|
||||
|
||||
this._styleSheetToSelect = {
|
||||
href: href,
|
||||
line: line,
|
||||
col: ch
|
||||
};
|
||||
}
|
||||
|
||||
// remember saved file locations
|
||||
for (let editor of this.editors) {
|
||||
if (editor.savedFile) {
|
||||
this.savedLocations[editor.styleSheet.href] = editor.savedFile;
|
||||
}
|
||||
}
|
||||
|
||||
this._clearStyleSheetEditors();
|
||||
this._view.removeAll();
|
||||
|
||||
this.selectedEditor = null;
|
||||
|
||||
this._root.classList.add("loading");
|
||||
},
|
||||
|
||||
/**
|
||||
* Add an editor for this stylesheet. Add editors for its original sources
|
||||
* instead (e.g. Sass sources), if applicable.
|
||||
|
@ -247,6 +256,12 @@ StyleEditorUI.prototype = {
|
|||
* Optional if stylesheet is a new sheet created by user
|
||||
*/
|
||||
_addStyleSheetEditor: function(styleSheet, file, isNew) {
|
||||
// recall location of saved file for this sheet after page reload
|
||||
let savedFile = this.savedLocations[styleSheet.href];
|
||||
if (savedFile && !file) {
|
||||
file = savedFile;
|
||||
}
|
||||
|
||||
let editor =
|
||||
new StyleSheetEditor(styleSheet, this._window, file, isNew, this._walker);
|
||||
|
||||
|
|
|
@ -77,6 +77,10 @@ noGlobalsText=No globals
|
|||
# when there are no scripts.
|
||||
noSourcesText=This page has no sources.
|
||||
|
||||
# LOCALIZATION NOTE (loadingSourcesText): The text to display in the sources menu
|
||||
# when waiting for scripts to load.
|
||||
loadingSourcesText=Waiting for sources...
|
||||
|
||||
# LOCALIZATION NOTE (noEventListenersText): The text to display in the events tab
|
||||
# when there are no events.
|
||||
noEventListenersText=No event listeners to display
|
||||
|
|
|
@ -185,7 +185,7 @@ browser.jar:
|
|||
skin/classic/browser/devtools/breadcrumbs-divider@2x.png (../shared/devtools/images/breadcrumbs-divider@2x.png)
|
||||
skin/classic/browser/devtools/breadcrumbs-scrollbutton.png (../shared/devtools/images/breadcrumbs-scrollbutton.png)
|
||||
skin/classic/browser/devtools/breadcrumbs-scrollbutton@2x.png (../shared/devtools/images/breadcrumbs-scrollbutton@2x.png)
|
||||
skin/classic/browser/devtools/splitview.css (../shared/devtools/splitview.css)
|
||||
* skin/classic/browser/devtools/splitview.css (../shared/devtools/splitview.css)
|
||||
skin/classic/browser/devtools/styleeditor.css (../shared/devtools/styleeditor.css)
|
||||
* skin/classic/browser/devtools/shadereditor.css (devtools/shadereditor.css)
|
||||
* skin/classic/browser/devtools/debugger.css (devtools/debugger.css)
|
||||
|
|
|
@ -295,7 +295,7 @@ browser.jar:
|
|||
skin/classic/browser/devtools/breadcrumbs-divider@2x.png (../shared/devtools/images/breadcrumbs-divider@2x.png)
|
||||
skin/classic/browser/devtools/breadcrumbs-scrollbutton.png (../shared/devtools/images/breadcrumbs-scrollbutton.png)
|
||||
skin/classic/browser/devtools/breadcrumbs-scrollbutton@2x.png (../shared/devtools/images/breadcrumbs-scrollbutton@2x.png)
|
||||
skin/classic/browser/devtools/splitview.css (../shared/devtools/splitview.css)
|
||||
* skin/classic/browser/devtools/splitview.css (../shared/devtools/splitview.css)
|
||||
skin/classic/browser/devtools/styleeditor.css (../shared/devtools/styleeditor.css)
|
||||
* skin/classic/browser/devtools/shadereditor.css (devtools/shadereditor.css)
|
||||
* skin/classic/browser/devtools/debugger.css (devtools/debugger.css)
|
||||
|
|
|
@ -5,6 +5,12 @@
|
|||
%filter substitution
|
||||
|
||||
%define menuPanelWidth 22.35em
|
||||
% XXXgijs This is the ugliest bit of code I think I've ever written for Mozilla.
|
||||
% Basically, the 0.1px is there to avoid CSS rounding errors causing buttons to wrap.
|
||||
% For gory details, refer to https://bugzilla.mozilla.org/show_bug.cgi?id=963365#c11
|
||||
% There's no calc() here (and therefore lots of calc() where this is used) because
|
||||
% we don't support nested calc(): https://bugzilla.mozilla.org/show_bug.cgi?id=968761
|
||||
%define menuPanelButtonWidth (@menuPanelWidth@ / 3 - 0.1px)
|
||||
%define exitSubviewGutterWidth 38px
|
||||
%define buttonStateHover :not(:-moz-any([disabled],[open],[checked="true"],:active)):-moz-any(:hover,[_moz-menuactive])
|
||||
%define buttonStateActive :not([disabled]):-moz-any([open],[checked="true"],:hover:active,[_moz-menuactive]:active)
|
||||
|
@ -177,7 +183,7 @@ toolbaritem[cui-areatype="menu-panel"][sdkstylewidget="true"]:not(.panel-wide-it
|
|||
.panel-customization-placeholder-child {
|
||||
-moz-appearance: none;
|
||||
-moz-box-orient: vertical;
|
||||
width: calc(@menuPanelWidth@ / 3);
|
||||
width: calc(@menuPanelButtonWidth@);
|
||||
height: calc(40px + 4em);
|
||||
}
|
||||
|
||||
|
@ -189,7 +195,7 @@ toolbaritem[cui-areatype="menu-panel"][sdkstylewidget="true"]:not(.panel-wide-it
|
|||
.panelUI-grid .toolbarbutton-1 > .toolbarbutton-menubutton-button {
|
||||
-moz-appearance: none;
|
||||
-moz-box-orient: vertical;
|
||||
width: calc(@menuPanelWidth@ / 3 - 2px);
|
||||
width: calc(@menuPanelButtonWidth@ - 2px);
|
||||
height: calc(38px + 4em);
|
||||
margin-top: 3px; /* Hack needed to get type=menu-button to properly align vertically. */
|
||||
border: 0;
|
||||
|
@ -232,7 +238,7 @@ toolbaritem[cui-areatype="menu-panel"][sdkstylewidget="true"]:not(.panel-wide-it
|
|||
}
|
||||
|
||||
toolbaritem[cui-areatype="menu-panel"][sdkstylewidget="true"] {
|
||||
width: calc(@menuPanelWidth@ / 3);
|
||||
width: calc(@menuPanelButtonWidth@);
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
|
@ -258,18 +264,19 @@ toolbaritem[cui-areatype="menu-panel"][sdkstylewidget="true"]:not(.panel-wide-it
|
|||
.panel-customization-placeholder-child > .toolbarbutton-icon {
|
||||
min-width: 32px;
|
||||
min-height: 32px;
|
||||
/* Explanation for calc((A / B - C) / D), simplified to calc(X / Y - Z):
|
||||
A / B (@menuPanelWidth@ / 3)
|
||||
Each button is @menuPanelWidth@ / 3 wide.
|
||||
C (46px)
|
||||
/* Explanation for the below formula (A / B - C)
|
||||
A
|
||||
Each button is @menuPanelButtonWidth@ wide
|
||||
B
|
||||
Each button has two margins.
|
||||
C (46px / 2 = 23px)
|
||||
The button icon is 32 pixels wide.
|
||||
The button has 12px of horizontal padding (6 on each side).
|
||||
The button has 2px of horizontal border (1 on each side).
|
||||
Total width of button should therefore be 46px.
|
||||
D (2)
|
||||
Divide by 2 since each button has two horizontal margins.
|
||||
Total width of button's icon + button padding should therefore be 46px,
|
||||
which means each horizontal margin should be the half the button's width - (46/2) px.
|
||||
*/
|
||||
margin: 4px calc(@menuPanelWidth@ / 6 - 23px);
|
||||
margin: 4px calc(@menuPanelButtonWidth@ / 2 - 23px);
|
||||
}
|
||||
|
||||
toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton {
|
||||
|
@ -642,8 +649,8 @@ toolbarpaletteitem[place="palette"] > #search-container {
|
|||
-moz-box-flex: 1;
|
||||
/* reduce the width with 2px for each button to compensate for two separators
|
||||
of 3px. */
|
||||
min-width: calc(@menuPanelWidth@ / 3 - 2px);
|
||||
max-width: calc(@menuPanelWidth@ / 3 - 2px);
|
||||
min-width: calc(@menuPanelButtonWidth@ - 2px);
|
||||
max-width: calc(@menuPanelButtonWidth@ - 2px);
|
||||
/* We'd prefer to use height: auto here but it leads to layout bugs in the panel. Cope:
|
||||
1.2em for line height + 2 * .5em padding + margin on the label (2 * 2px) */
|
||||
height: calc(2.2em + 4px);
|
||||
|
|
|
@ -158,81 +158,51 @@ box.requests-menu-status {
|
|||
}
|
||||
|
||||
.theme-dark box.requests-menu-status:not([code]) {
|
||||
box-shadow:
|
||||
0 0 0 1px rgba(255,255,255,0.4) inset,
|
||||
0 -6px 4px 0 rgba(32,32,32,1.0) inset,
|
||||
0 0 8px 0 rgba(32,0,0,0.4);
|
||||
background-color: rgba(95, 115, 135, 1); /* dark grey */
|
||||
}
|
||||
|
||||
.theme-light box.requests-menu-status:not([code]) {
|
||||
box-shadow:
|
||||
0 0 0 1px rgba(255,255,255,0.4) inset,
|
||||
0 -6px 4px 0 rgba(32,32,32, 0.5) inset;
|
||||
background-color: rgba(143, 161, 178, 1); /* grey */
|
||||
}
|
||||
|
||||
.theme-dark box.requests-menu-status[code^="1"] {
|
||||
box-shadow:
|
||||
0 0 2px 1px rgba(255,255,255,0.8) inset,
|
||||
0 -6px 4px 0 rgba(0,0,64,1.0) inset,
|
||||
0 0 8px 0 rgba(0,0,128,1.0);
|
||||
background-color: rgba(70, 175, 227, 1); /* light blue */
|
||||
}
|
||||
|
||||
.theme-light box.requests-menu-status[code^="1"] {
|
||||
box-shadow:
|
||||
0 0 2px 1px rgba(255,255,255,0.8) inset,
|
||||
0 -6px 4px 0 rgba(0,0,128,1) inset;
|
||||
background-color: rgba(0, 136, 204, 1); /* light blue */
|
||||
}
|
||||
|
||||
.theme-dark box.requests-menu-status[code^="2"] {
|
||||
box-shadow:
|
||||
0 0 2px 1px rgba(255,255,255,0.8) inset,
|
||||
0 -6px 4px 0 rgba(0,64,0,1.0) inset,
|
||||
0 0 8px 0 rgba(0,128,0,1.0);
|
||||
background-color: rgba(112, 191, 83, 1); /* green */
|
||||
}
|
||||
|
||||
.theme-light box.requests-menu-status[code^="2"] {
|
||||
box-shadow:
|
||||
0 0 2px 1px rgba(255,255,255,0.8) inset,
|
||||
0 -6px 4px 0 rgba(0,128,0,1) inset;
|
||||
background-color: rgba(44, 187, 15, 1); /* green */
|
||||
}
|
||||
|
||||
.theme-dark box.requests-menu-status[code^="3"] {
|
||||
box-shadow:
|
||||
0 0 2px 1px rgba(255,255,255,0.8) inset,
|
||||
0 -6px 4px 0 rgba(64,32,0,1.0) inset,
|
||||
0 0 8px 0 rgba(128,128,0,1.0);
|
||||
background-color: rgba(94, 136, 176, 1); /* grey */
|
||||
}
|
||||
|
||||
.theme-light box.requests-menu-status[code^="3"] {
|
||||
box-shadow:
|
||||
0 0 2px 1px rgba(255,255,255,0.8) inset,
|
||||
0 -6px 4px 0 rgba(128,64,0,1) inset;
|
||||
background-color: rgba(95, 136, 176, 1); /* blue grey */
|
||||
}
|
||||
|
||||
.theme-dark box.requests-menu-status[code^="4"] {
|
||||
box-shadow:
|
||||
0 0 2px 1px rgba(255,255,255,0.8) inset,
|
||||
0 -6px 4px 0 rgba(64,0,0,1.0) inset,
|
||||
0 0 8px 0 rgba(128,0,0,1.0);
|
||||
background-color: rgba(235, 83, 104, 1); /* red */
|
||||
}
|
||||
|
||||
.theme-light box.requests-menu-status[code^="4"] {
|
||||
box-shadow:
|
||||
0 0 2px 1px rgba(255,255,255,0.8) inset,
|
||||
0 -6px 4px 0 rgba(128,0,0,1) inset;
|
||||
background-color: rgba(237, 38, 85, 1); /* red */
|
||||
}
|
||||
|
||||
.theme-dark box.requests-menu-status[code^="5"] {
|
||||
box-shadow:
|
||||
0 0 2px 1px rgba(255,255,255,0.8) inset,
|
||||
0 -6px 4px 0 rgba(64,0,64,1.0) inset,
|
||||
0 0 8px 0 rgba(128,0,128,1.0);
|
||||
background-color: rgba(223, 128, 255, 1); /* pink? */
|
||||
}
|
||||
|
||||
.theme-light box.requests-menu-status[code^="5"] {
|
||||
box-shadow:
|
||||
0 0 2px 1px rgba(255,255,255,0.8) inset,
|
||||
0 -6px 4px 0 rgba(128,0,128,1.0) inset;
|
||||
background-color: rgba(184, 46, 229, 1); /* pink! */
|
||||
}
|
||||
|
||||
/* Network requests table: waterfall header */
|
||||
|
@ -294,7 +264,7 @@ box.requests-menu-status {
|
|||
/* Network requests table: waterfall items */
|
||||
|
||||
.requests-menu-subitem.requests-menu-waterfall {
|
||||
-moz-padding-start: 4px;
|
||||
-moz-padding-start: 0px;
|
||||
-moz-padding-end: 4px;
|
||||
background-repeat: repeat-y; /* Background created on a <canvas> in js. */
|
||||
background-position: -1px center;
|
||||
|
@ -323,129 +293,50 @@ box.requests-menu-status {
|
|||
}
|
||||
|
||||
.requests-menu-timings-total {
|
||||
-moz-padding-start: 8px;
|
||||
-moz-padding-start: 4px;
|
||||
font-size: 85%;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.requests-menu-timings-cap {
|
||||
width: 4px;
|
||||
height: 8px;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.theme-dark .requests-menu-timings-cap {
|
||||
border: 1px solid #b8c8d9; /* Light content text */
|
||||
}
|
||||
|
||||
.theme-light .requests-menu-timings-cap {
|
||||
border: 1px solid #292e33; /* Dark content text */
|
||||
}
|
||||
|
||||
.requests-menu-timings-cap.start {
|
||||
-moz-border-end: none;
|
||||
}
|
||||
|
||||
.requests-menu-timings-cap.end {
|
||||
-moz-border-start: none;
|
||||
}
|
||||
|
||||
.requests-menu-timings-cap.start:-moz-locale-dir(ltr) {
|
||||
border-radius: 4px 0 0 4px;
|
||||
transform-origin: right center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-cap.start:-moz-locale-dir(rtl) {
|
||||
border-radius: 0 4px 4px 0;
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-cap.end:-moz-locale-dir(ltr) {
|
||||
border-radius: 0 4px 4px 0;
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-cap.end:-moz-locale-dir(rtl) {
|
||||
border-radius: 4px 0 0 4px;
|
||||
transform-origin: right center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-box {
|
||||
height: 8px;
|
||||
height: 9px;
|
||||
}
|
||||
|
||||
.theme-dark .requests-menu-timings-box {
|
||||
border-top: 1px solid #b8c8d9; /* Light content text */
|
||||
border-bottom: 1px solid #b8c8d9;
|
||||
.requests-menu-timings-box.blocked {
|
||||
background-color: rgba(235, 83, 104, 0.8); /* red */
|
||||
}
|
||||
|
||||
.theme-light .requests-menu-timings-box {
|
||||
border-top: 1px solid #292e33; /* Dark content text */
|
||||
border-bottom: 1px solid #292e33;
|
||||
.requests-menu-timings-box.dns {
|
||||
background-color: rgba(223, 128, 255, 0.8); /* pink */
|
||||
}
|
||||
|
||||
.requests-menu-timings-box.blocked,
|
||||
.requests-menu-timings-cap.blocked {
|
||||
background-color: rgba(255,32,32,0.8);
|
||||
box-shadow: 0 0 2px 0 rgba(128,32,32,0.8),
|
||||
0 0 1px 0 rgba(255,255,255,1.0) inset;
|
||||
}
|
||||
|
||||
.requests-menu-timings-box.dns,
|
||||
.requests-menu-timings-cap.dns {
|
||||
background-color: rgba(255,128,255,0.6);
|
||||
box-shadow: 0 0 2px 0 rgba(128,128,255,1.0),
|
||||
0 0 1px 0 rgba(255,255,255,1.0) inset;
|
||||
}
|
||||
|
||||
.requests-menu-timings-box.connect,
|
||||
.requests-menu-timings-cap.connect {
|
||||
background-color: rgba(255,128,16,0.4);
|
||||
box-shadow: 0 0 2px 0 rgba(128,128,16,0.8),
|
||||
0 0 1px 0 rgba(255,255,255,1.0) inset;
|
||||
.requests-menu-timings-box.connect {
|
||||
background-color: rgba(217, 102, 41, 0.8); /* orange */
|
||||
}
|
||||
|
||||
/* Use custom colors for dark and light theme on remaining timing types. */
|
||||
.theme-dark .requests-menu-timings-box.send,
|
||||
.theme-dark .requests-menu-timings-cap.send {
|
||||
background-color: rgba(255,255,128,0.4);
|
||||
box-shadow: 0 0 2px 0 rgba(128,255,128,0.8),
|
||||
0 0 1px 0 rgba(255,255,255,1.0) inset;
|
||||
.theme-dark .requests-menu-timings-box.send {
|
||||
background-color: rgba(70, 175, 227, 0.8); /* light blue */
|
||||
}
|
||||
|
||||
.theme-light .requests-menu-timings-box.send,
|
||||
.theme-light .requests-menu-timings-cap.send {
|
||||
background-color: rgba(255,255,128,0.4);
|
||||
box-shadow: 0 0 2px 0 rgba(128,255,128,0.8),
|
||||
0 0 1px 0 rgba(255,255,255,1.0) inset;
|
||||
.theme-light .requests-menu-timings-box.send {
|
||||
background-color: rgba(0, 136, 204, 0.8); /* blue */
|
||||
}
|
||||
|
||||
.theme-dark .requests-menu-timings-box.wait,
|
||||
.theme-dark .requests-menu-timings-cap.wait {
|
||||
background-color: rgba(255,255,255,0.2);
|
||||
box-shadow: 0 0 2px 0 rgba(128,255,255,0.4),
|
||||
0 0 1px 0 rgba(255,255,255,1.0) inset;
|
||||
.theme-dark .requests-menu-timings-box.wait {
|
||||
background-color: rgba(94, 136, 176, 0.8); /* blue grey */
|
||||
}
|
||||
|
||||
.theme-light .requests-menu-timings-box.wait,
|
||||
.theme-light .requests-menu-timings-cap.wait {
|
||||
background-color: rgba(200, 200, 200, 0.8);
|
||||
box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.4),
|
||||
0 0 1px 0 rgba(255,255,255,1.0) inset;
|
||||
.theme-light .requests-menu-timings-box.wait {
|
||||
background-color: rgba(95, 136, 176, 0.8); /* blue grey */
|
||||
}
|
||||
|
||||
.theme-dark .requests-menu-timings-box.receive,
|
||||
.theme-dark .requests-menu-timings-cap.receive {
|
||||
background-color: rgba(255,255,255,1.0);
|
||||
box-shadow: 0 0 2px 0 rgba(128,255,255,1.0),
|
||||
0 0 1px 0 rgba(255,255,255,1.0) inset;
|
||||
.theme-dark .requests-menu-timings-box.receive {
|
||||
background-color: rgba(112, 191, 83, 0.8); /* green */
|
||||
}
|
||||
|
||||
.theme-light .requests-menu-timings-box.receive,
|
||||
.theme-light .requests-menu-timings-cap.receive {
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.8),
|
||||
0 0 1px 0 rgba(0,0,0,1.0) inset;
|
||||
.theme-light .requests-menu-timings-box.receive {
|
||||
background-color: rgba(44, 187, 15, 0.8); /* green */
|
||||
}
|
||||
|
||||
/* SideMenuWidget */
|
||||
|
|
|
@ -3,6 +3,14 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
%filter substitution
|
||||
%define smw_marginDark #000
|
||||
%define smw_marginLight #aaa
|
||||
%define smw_itemDarkTopBorder rgba(0,0,0,0.2)
|
||||
%define smw_itemDarkBottomBorder rgba(128,128,128,0.15)
|
||||
%define smw_itemLightTopBorder rgba(128,128,128,0.15)
|
||||
%define smw_itemLightBottomBorder transparent
|
||||
|
||||
.loading .splitview-nav-container {
|
||||
background-image: url(chrome://global/skin/icons/loading_16.png);
|
||||
background-repeat: no-repeat;
|
||||
|
@ -15,67 +23,93 @@
|
|||
|
||||
.splitview-nav {
|
||||
-moz-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.theme-dark .splitview-nav {
|
||||
box-shadow: inset -1px 0 0 black; /* Match the splitter. */
|
||||
}
|
||||
|
||||
.theme-light .splitview-nav {
|
||||
box-shadow: inset -1px 0 0 #aaa; /* Match the splitter color. */
|
||||
}
|
||||
|
||||
.splitview-nav > li {
|
||||
background-clip: padding-box;
|
||||
border-bottom: 1px solid hsla(210,16%,76%,.1);
|
||||
box-shadow: inset 0 -1px 0 hsla(210,8%,5%,.25);
|
||||
-moz-padding-end: 8px;
|
||||
-moz-box-align: center;
|
||||
}
|
||||
|
||||
.splitview-nav {
|
||||
list-style-image: none;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.theme-dark .splitview-nav {
|
||||
box-shadow: inset -1px 0 0 @smw_marginDark@;
|
||||
}
|
||||
|
||||
.theme-dark .splitview-nav:-moz-locale-dir(rtl) {
|
||||
box-shadow: inset 1px 0 0 @smw_marginDark@;
|
||||
}
|
||||
|
||||
.theme-light .splitview-nav {
|
||||
box-shadow: inset -1px 0 0 @smw_marginLight@;
|
||||
}
|
||||
|
||||
.theme-light .splitview-nav:-moz-locale-dir(rtl) {
|
||||
box-shadow: inset 1px 0 0 @smw_marginLight@;
|
||||
}
|
||||
|
||||
.splitview-nav > li {
|
||||
/* To compensate for the top and bottom borders */
|
||||
margin-top: -1px;
|
||||
margin-bottom: -1px;
|
||||
-moz-padding-end: 8px;
|
||||
-moz-box-align: center;
|
||||
outline: 0;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
.theme-dark .splitview-nav > li {
|
||||
border-top: 1px solid @smw_itemDarkTopBorder@;
|
||||
border-bottom: 1px solid @smw_itemDarkBottomBorder@;
|
||||
}
|
||||
|
||||
.theme-dark .splitview-nav > li:last-of-type {
|
||||
box-shadow: inset 0 -1px 0 @smw_itemDarkTopBorder@;
|
||||
}
|
||||
|
||||
.theme-light .splitview-nav > li {
|
||||
border-top: 1px solid @smw_itemLightTopBorder@;
|
||||
border-bottom: 1px solid @smw_itemLightBottomBorder@;
|
||||
}
|
||||
|
||||
.theme-light .splitview-nav > li:last-of-type {
|
||||
box-shadow: inset 0 -1px 0 @smw_itemLightTopBorder@;
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
-moz-box-flex: 1;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.splitview-nav > li.splitview-active {
|
||||
background-image: url(itemArrow-dark-ltr.png),
|
||||
linear-gradient(#1d4f73, #1d4f73);
|
||||
background-repeat: no-repeat, repeat-x;
|
||||
background-position: center right, top left;
|
||||
background-size: auto, auto;
|
||||
border-bottom: 1px solid hsla(210,8%,5%,.25);
|
||||
box-shadow: inset 0 1px 0 hsla(210,40%,83%,.15),
|
||||
inset 0 -1px 0 hsla(210,40%,83%,.05);
|
||||
background-repeat: no-repeat, no-repeat, repeat-x;
|
||||
background-position: center right, center right, top left;
|
||||
background-size: auto, 1px, auto;
|
||||
}
|
||||
|
||||
.splitview-nav > li.splitview-active:-moz-locale-dir(rtl) {
|
||||
background-image: url(itemArrow-dark-rtl.png),
|
||||
background-repeat: no-repeat, no-repeat, repeat-x;
|
||||
background-position: center left, center left, top right;
|
||||
}
|
||||
|
||||
.theme-dark .splitview-nav > li.splitview-active {
|
||||
background-image: url(itemArrow-dark-ltr.png),
|
||||
linear-gradient(@smw_marginDark@, @smw_marginDark@),
|
||||
linear-gradient(#1d4f73, #1d4f73);
|
||||
}
|
||||
|
||||
.theme-dark .splitview-nav > li.splitview-active:-moz-locale-dir(rtl) {
|
||||
background-image: url(itemArrow-dark-rtl.png),
|
||||
linear-gradient(@smw_marginDark@, @smw_marginDark@),
|
||||
linear-gradient(#1d4f73, #1d4f73);
|
||||
background-repeat: no-repeat, repeat-x;
|
||||
background-position: center left, top right;
|
||||
}
|
||||
|
||||
.theme-light .splitview-nav > li.splitview-active {
|
||||
background-image: url(itemArrow-ltr.svg),
|
||||
linear-gradient(@smw_marginLight@, @smw_marginLight@),
|
||||
linear-gradient(#4c9ed9, #4c9ed9);
|
||||
}
|
||||
|
||||
.theme-light .splitview-nav > li.splitview-active:-moz-locale-dir(rtl) {
|
||||
background-image: url(itemArrow-rtl.png),
|
||||
background-image: url(itemArrow-rtl.svg),
|
||||
linear-gradient(@smw_marginLight@, @smw_marginLight@),
|
||||
linear-gradient(#4c9ed9, #4c9ed9);
|
||||
}
|
||||
|
||||
|
@ -88,12 +122,12 @@
|
|||
|
||||
.theme-dark .splitview-main > toolbar,
|
||||
.theme-dark .loading .splitview-nav-container {
|
||||
-moz-border-end: 1px solid black; /* Match the splitter. */
|
||||
-moz-border-end: 1px solid @smw_marginDark@;
|
||||
}
|
||||
|
||||
.theme-light .splitview-main > toolbar,
|
||||
.theme-light .loading .splitview-nav-container {
|
||||
-moz-border-end: 1px solid #aaa; /* Match the splitter. */
|
||||
-moz-border-end: 1px solid @smw_marginLight@;
|
||||
}
|
||||
|
||||
.splitview-main > .devtools-toolbarbutton {
|
||||
|
|
|
@ -67,8 +67,7 @@
|
|||
.theme-light .devtools-toolbarbutton[open=true]:hover,
|
||||
.theme-light .devtools-toolbarbutton[open=true]:hover:active,
|
||||
.theme-light .devtools-toolbarbutton[checked=true],
|
||||
.theme-light .devtools-toolbarbutton[checked=true]:hover,
|
||||
.theme-light .devtools-toolbarbutton[checked=true]:hover:active {
|
||||
.theme-light .devtools-toolbarbutton[checked=true]:hover {
|
||||
background: #ddd;
|
||||
}
|
||||
|
||||
|
@ -76,6 +75,11 @@
|
|||
background: #eee;
|
||||
}
|
||||
|
||||
.theme-light .devtools-toolbarbutton:hover:active,
|
||||
.theme-light .devtools-toolbarbutton[checked=true]:hover:active {
|
||||
background: #e8e8e8;
|
||||
}
|
||||
|
||||
.theme-light .devtools-toolbarbutton[type=menu-button] > .toolbarbutton-menubutton-button {
|
||||
color: #667380;
|
||||
}
|
||||
|
@ -203,7 +207,7 @@
|
|||
.devtools-searchinput {
|
||||
-moz-appearance: none;
|
||||
margin: 0 3px;
|
||||
border: 1px solid rgb(88, 94, 101);
|
||||
border: 1px solid;
|
||||
%ifdef XP_MACOSX
|
||||
border-radius: 20px;
|
||||
%else
|
||||
|
@ -212,6 +216,16 @@
|
|||
padding: 4px 6px;
|
||||
}
|
||||
|
||||
.theme-dark .devtools-textinput,
|
||||
.theme-dark .devtools-searchinput {
|
||||
border-color: rgb(88, 94, 101);
|
||||
}
|
||||
|
||||
.theme-light .devtools-textinput,
|
||||
.theme-light .devtools-searchinput {
|
||||
border-color: #aaa; /* Match the splitter color */
|
||||
}
|
||||
|
||||
.devtools-searchinput {
|
||||
padding-top: 3px;
|
||||
padding-bottom: 3px;
|
||||
|
@ -587,64 +601,87 @@
|
|||
|
||||
.devtools-tabbar {
|
||||
-moz-appearance: none;
|
||||
background: #252c33;
|
||||
min-height: 28px;
|
||||
border: 0px solid #000;
|
||||
border: 0px solid;
|
||||
border-bottom-width: 1px;
|
||||
box-shadow: 0 -2px 0 rgba(0,0,0,.1) inset;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.theme-light .devtools-tabbar {
|
||||
box-shadow: 0 -2px 0 rgba(170,170,170,.1) inset;
|
||||
background: #ebeced;
|
||||
border-bottom-color: #aaa;
|
||||
}
|
||||
|
||||
.theme-dark .devtools-tabbar {
|
||||
box-shadow: 0 -2px 0 rgba(0,0,0,.1) inset;
|
||||
background: #252c33;
|
||||
border-bottom-color: #000;
|
||||
}
|
||||
|
||||
#toolbox-tabs {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.devtools-tab {
|
||||
-moz-appearance: none;
|
||||
-moz-binding: url("chrome://global/content/bindings/general.xml#control-item");
|
||||
-moz-box-align: center;
|
||||
}
|
||||
|
||||
.devtools-tab {
|
||||
-moz-appearance: none;
|
||||
min-width: 32px;
|
||||
min-height: 28px;
|
||||
max-width: 127px;
|
||||
color: #b6babf;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
-moz-border-start: 1px solid #42484f;
|
||||
-moz-border-start: 1px solid;
|
||||
-moz-box-align: center;
|
||||
}
|
||||
|
||||
.theme-light .devtools-tabbar {
|
||||
background: #ebeced;
|
||||
border-bottom-color: #aaa;
|
||||
.theme-dark .devtools-tab {
|
||||
color: #b6babf;
|
||||
border-color: #42484f;
|
||||
}
|
||||
|
||||
.theme-light .devtools-tab,
|
||||
.theme-light .devtools-tab:hover {
|
||||
.theme-light .devtools-tab {
|
||||
color: #18191a;
|
||||
border-color: #aaa;
|
||||
}
|
||||
|
||||
.theme-dark .devtools-tab:hover {
|
||||
background-color: hsla(206,37%,4%,.2);
|
||||
color: #ced3d9;
|
||||
}
|
||||
|
||||
.theme-light .devtools-tab:hover {
|
||||
background-color: #ddd;
|
||||
box-shadow: 0 -2px 0 rgba(0,0,0,.1) inset;
|
||||
background-color: rgba(170,170,170,.2);
|
||||
}
|
||||
|
||||
.theme-dark .devtools-tab:hover:active {
|
||||
background-color: hsla(206,37%,4%,.4);
|
||||
color: #f5f7fa;
|
||||
}
|
||||
|
||||
.theme-light .devtools-tab:hover:active {
|
||||
background-color: rgba(170,170,170,.4);
|
||||
}
|
||||
|
||||
.theme-dark .devtools-tab:not([selected])[highlighted] {
|
||||
background-color: hsla(99,100%,14%,.2);
|
||||
box-shadow: 0 2px 0 #7bc107 inset;
|
||||
}
|
||||
|
||||
.theme-light .devtools-tab:not([selected])[highlighted] {
|
||||
background-color: rgba(44, 187, 15, .2);
|
||||
}
|
||||
|
||||
.theme-light .devtools-tab:last-child {
|
||||
-moz-border-end: 1px solid #aaa;
|
||||
}
|
||||
|
||||
.devtools-tab:first-child {
|
||||
-moz-border-start-width: 0;
|
||||
}
|
||||
|
||||
.devtools-tab:last-child {
|
||||
.theme-light .devtools-tab:last-child {
|
||||
-moz-border-end: 1px solid #aaa;
|
||||
}
|
||||
|
||||
.theme-dark .devtools-tab:last-child {
|
||||
-moz-border-end: 1px solid #42484f;
|
||||
}
|
||||
|
||||
|
@ -674,17 +711,7 @@
|
|||
opacity: 1;
|
||||
}
|
||||
|
||||
.devtools-tab:hover {
|
||||
background-color: hsla(206,37%,4%,.2);
|
||||
color: #ced3d9;
|
||||
}
|
||||
|
||||
.devtools-tab:hover:active {
|
||||
background-color: hsla(206,37%,4%,.4);
|
||||
color: #f5f7fa;
|
||||
}
|
||||
|
||||
#toolbox-tabs .devtools-tab[selected] {
|
||||
.theme-dark #toolbox-tabs .devtools-tab[selected] {
|
||||
color: #f5f7fa;
|
||||
background-color: #1a4666;
|
||||
box-shadow: 0 2px 0 #d7f1ff inset,
|
||||
|
@ -693,7 +720,11 @@
|
|||
}
|
||||
|
||||
.theme-light #toolbox-tabs .devtools-tab[selected] {
|
||||
color: #f5f7fa;
|
||||
background-color: #4c9ed9;
|
||||
box-shadow: 0 2px 0 #d7f1ff inset,
|
||||
0 8px 3px -5px #2b82bf inset,
|
||||
0 -2px 0 rgba(0,0,0,.06) inset;
|
||||
}
|
||||
|
||||
.devtools-tab[selected]:not(:first-child),
|
||||
|
@ -713,15 +744,6 @@
|
|||
-moz-padding-start: 1px;
|
||||
}
|
||||
|
||||
.theme-dark .devtools-tab:not([selected])[highlighted] {
|
||||
background-color: hsla(99,100%,14%,.2);
|
||||
box-shadow: 0 2px 0 #7bc107 inset;
|
||||
}
|
||||
|
||||
.theme-dark #toolbox-tabs .devtools-tab[selected] {
|
||||
color: #f5f7fa;
|
||||
}
|
||||
|
||||
.devtools-tab:not([highlighted]) > .highlighted-icon,
|
||||
.devtools-tab[selected] > .highlighted-icon,
|
||||
.devtools-tab:not([selected])[highlighted] > .default-icon {
|
||||
|
|
|
@ -214,7 +214,7 @@ browser.jar:
|
|||
skin/classic/browser/devtools/breadcrumbs-divider@2x.png (../shared/devtools/images/breadcrumbs-divider@2x.png)
|
||||
skin/classic/browser/devtools/breadcrumbs-scrollbutton.png (../shared/devtools/images/breadcrumbs-scrollbutton.png)
|
||||
skin/classic/browser/devtools/breadcrumbs-scrollbutton@2x.png (../shared/devtools/images/breadcrumbs-scrollbutton@2x.png)
|
||||
skin/classic/browser/devtools/splitview.css (../shared/devtools/splitview.css)
|
||||
* skin/classic/browser/devtools/splitview.css (../shared/devtools/splitview.css)
|
||||
skin/classic/browser/devtools/styleeditor.css (../shared/devtools/styleeditor.css)
|
||||
* skin/classic/browser/devtools/shadereditor.css (devtools/shadereditor.css)
|
||||
* skin/classic/browser/devtools/debugger.css (devtools/debugger.css)
|
||||
|
@ -527,7 +527,7 @@ browser.jar:
|
|||
skin/classic/aero/browser/devtools/breadcrumbs-divider@2x.png (../shared/devtools/images/breadcrumbs-divider@2x.png)
|
||||
skin/classic/aero/browser/devtools/breadcrumbs-scrollbutton.png (../shared/devtools/images/breadcrumbs-scrollbutton.png)
|
||||
skin/classic/aero/browser/devtools/breadcrumbs-scrollbutton@2x.png (../shared/devtools/images/breadcrumbs-scrollbutton@2x.png)
|
||||
skin/classic/aero/browser/devtools/splitview.css (../shared/devtools/splitview.css)
|
||||
* skin/classic/aero/browser/devtools/splitview.css (../shared/devtools/splitview.css)
|
||||
skin/classic/aero/browser/devtools/styleeditor.css (../shared/devtools/styleeditor.css)
|
||||
* skin/classic/aero/browser/devtools/shadereditor.css (devtools/shadereditor.css)
|
||||
* skin/classic/aero/browser/devtools/debugger.css (devtools/debugger.css)
|
||||
|
|
|
@ -205,3 +205,10 @@ https://www2.w3c-test.org:443
|
|||
https://xn--n8j6ds53lwwkrqhv28a.w3c-test.org:443
|
||||
https://xn--lve-6lad.w3c-test.org:443
|
||||
http://test.w3.org:80
|
||||
|
||||
# Hosts for testing TLD-based fallback encoding
|
||||
http://example.tw:80 privileged
|
||||
http://example.cn:80 privileged
|
||||
http://example.co.jp:80 privileged
|
||||
http://example.fi:80 privileged
|
||||
|
||||
|
|
|
@ -435,6 +435,66 @@ nsHTMLDocument::TryParentCharset(nsIDocShell* aDocShell,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLDocument::TryTLD(int32_t& aCharsetSource, nsACString& aCharset)
|
||||
{
|
||||
if (aCharsetSource >= kCharsetFromTopLevelDomain) {
|
||||
return;
|
||||
}
|
||||
if (!FallbackEncoding::sGuessFallbackFromTopLevelDomain) {
|
||||
return;
|
||||
}
|
||||
if (!mDocumentURI) {
|
||||
return;
|
||||
}
|
||||
nsAutoCString host;
|
||||
mDocumentURI->GetAsciiHost(host);
|
||||
if (host.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
// First let's see if the host is DNS-absolute and ends with a dot and
|
||||
// get rid of that one.
|
||||
if (host.Last() == '.') {
|
||||
host.SetLength(host.Length() - 1);
|
||||
if (host.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// If we still have a dot, the host is weird, so let's continue only
|
||||
// if we have something other than a dot now.
|
||||
if (host.Last() == '.') {
|
||||
return;
|
||||
}
|
||||
int32_t index = host.RFindChar('.');
|
||||
if (index == kNotFound) {
|
||||
// We have an intranet host, Gecko-internal URL or an IPv6 address.
|
||||
return;
|
||||
}
|
||||
// Since the string didn't end with a dot and we found a dot,
|
||||
// there is at least one character between the dot and the end of
|
||||
// the string, so taking the substring below is safe.
|
||||
nsAutoCString tld;
|
||||
ToLowerCase(Substring(host, index + 1, host.Length() - (index + 1)), tld);
|
||||
// Reject generic TLDs and country TLDs that need more research
|
||||
if (!FallbackEncoding::IsParticipatingTopLevelDomain(tld)) {
|
||||
return;
|
||||
}
|
||||
// Check if we have an IPv4 address
|
||||
bool seenNonDigit = false;
|
||||
for (size_t i = 0; i < tld.Length(); ++i) {
|
||||
char c = tld.CharAt(i);
|
||||
if (c < '0' || c > '9') {
|
||||
seenNonDigit = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!seenNonDigit) {
|
||||
return;
|
||||
}
|
||||
aCharsetSource = kCharsetFromTopLevelDomain;
|
||||
FallbackEncoding::FromTopLevelDomain(tld, aCharset);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLDocument::TryFallback(int32_t& aCharsetSource, nsACString& aCharset)
|
||||
{
|
||||
|
@ -661,6 +721,7 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
|
|||
TryCacheCharset(cachingChan, charsetSource, charset);
|
||||
}
|
||||
|
||||
TryTLD(charsetSource, charset);
|
||||
TryFallback(charsetSource, charset);
|
||||
|
||||
if (wyciwygChannel) {
|
||||
|
|
|
@ -313,6 +313,7 @@ protected:
|
|||
nsACString& aCharset);
|
||||
void TryParentCharset(nsIDocShell* aDocShell,
|
||||
int32_t& charsetSource, nsACString& aCharset);
|
||||
void TryTLD(int32_t& aCharsetSource, nsACString& aCharset);
|
||||
static void TryFallback(int32_t& aCharsetSource, nsACString& aCharset);
|
||||
|
||||
// Override so we can munge the charset on our wyciwyg channel as needed.
|
||||
|
|
|
@ -39,7 +39,7 @@ load 878407.html
|
|||
load 878478.html
|
||||
load 877527.html
|
||||
load 880129.html
|
||||
skip-if(B2G) test-pref(media.webaudio.enabled,true) load 880202.html # load failed, bug 908306 for B2G
|
||||
skip-if(B2G) load 880202.html # load failed, bug 908306 for B2G
|
||||
load 880342-1.html
|
||||
load 880342-2.html
|
||||
load 880384.html
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include "nsWrapperCache.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "EnableWebAudioCheck.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsTArray.h"
|
||||
#include "AudioContext.h"
|
||||
|
@ -31,8 +30,7 @@ class AudioContext;
|
|||
* are Float32Arrays, or in mSharedChannels if the mJSChannels objects have
|
||||
* been neutered.
|
||||
*/
|
||||
class AudioBuffer MOZ_FINAL : public nsWrapperCache,
|
||||
public EnableWebAudioCheck
|
||||
class AudioBuffer MOZ_FINAL : public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
AudioBuffer(AudioContext* aContext, uint32_t aLength,
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#define AudioContext_h_
|
||||
|
||||
#include "mozilla/dom/AudioChannelBinding.h"
|
||||
#include "EnableWebAudioCheck.h"
|
||||
#include "MediaBufferDecoder.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/dom/TypedArray.h"
|
||||
|
@ -64,8 +63,7 @@ class WaveShaperNode;
|
|||
class PeriodicWave;
|
||||
|
||||
class AudioContext MOZ_FINAL : public nsDOMEventTargetHelper,
|
||||
public nsIMemoryReporter,
|
||||
public EnableWebAudioCheck
|
||||
public nsIMemoryReporter
|
||||
{
|
||||
AudioContext(nsPIDOMWindow* aParentWindow,
|
||||
bool aIsOffline,
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include "nsWrapperCache.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "EnableWebAudioCheck.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "ThreeDPoint.h"
|
||||
#include "AudioContext.h"
|
||||
|
@ -23,8 +22,7 @@ namespace mozilla {
|
|||
|
||||
namespace dom {
|
||||
|
||||
class AudioListener MOZ_FINAL : public nsWrapperCache,
|
||||
public EnableWebAudioCheck
|
||||
class AudioListener MOZ_FINAL : public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
explicit AudioListener(AudioContext* aContext);
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include "nsDOMEventTargetHelper.h"
|
||||
#include "mozilla/dom/AudioNodeBinding.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "EnableWebAudioCheck.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsTArray.h"
|
||||
#include "AudioContext.h"
|
||||
|
@ -82,8 +81,7 @@ private:
|
|||
* still alive, and will still be alive when it receives a message from the
|
||||
* engine.
|
||||
*/
|
||||
class AudioNode : public nsDOMEventTargetHelper,
|
||||
public EnableWebAudioCheck
|
||||
class AudioNode : public nsDOMEventTargetHelper
|
||||
{
|
||||
protected:
|
||||
// You can only use refcounting to delete this object
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include "AudioParamTimeline.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "EnableWebAudioCheck.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "AudioNode.h"
|
||||
#include "mozilla/dom/TypedArray.h"
|
||||
|
@ -22,7 +21,6 @@ namespace mozilla {
|
|||
namespace dom {
|
||||
|
||||
class AudioParam MOZ_FINAL : public nsWrapperCache,
|
||||
public EnableWebAudioCheck,
|
||||
public AudioParamTimeline
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -14,8 +14,7 @@
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class AudioProcessingEvent : public nsDOMEvent,
|
||||
public EnableWebAudioCheck
|
||||
class AudioProcessingEvent : public nsDOMEvent
|
||||
{
|
||||
public:
|
||||
AudioProcessingEvent(ScriptProcessorNode* aOwner,
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "EnableWebAudioCheck.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
namespace {
|
||||
|
||||
bool gPrefInitialized = false;
|
||||
bool gWebAudioEnabled = false;
|
||||
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
/* static */ bool
|
||||
EnableWebAudioCheck::PrefEnabled()
|
||||
{
|
||||
if (!gPrefInitialized) {
|
||||
Preferences::AddBoolVarCache(&gWebAudioEnabled, "media.webaudio.enabled");
|
||||
gPrefInitialized = true;
|
||||
}
|
||||
return gWebAudioEnabled;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef EnableWebAudioCheck_h_
|
||||
#define EnableWebAudioCheck_h_
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
// This is a helper class which enables Web Audio to be enabled or disabled
|
||||
// as whole. Individual Web Audio object classes should inherit from this.
|
||||
class EnableWebAudioCheck {
|
||||
public:
|
||||
static bool PrefEnabled();
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -15,8 +15,7 @@ namespace dom {
|
|||
|
||||
class AudioContext;
|
||||
|
||||
class OfflineAudioCompletionEvent : public nsDOMEvent,
|
||||
public EnableWebAudioCheck
|
||||
class OfflineAudioCompletionEvent : public nsDOMEvent
|
||||
{
|
||||
public:
|
||||
OfflineAudioCompletionEvent(AudioContext* aOwner,
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include "nsWrapperCache.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "EnableWebAudioCheck.h"
|
||||
#include "AudioContext.h"
|
||||
#include "AudioNodeEngine.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
@ -19,8 +18,7 @@ namespace mozilla {
|
|||
|
||||
namespace dom {
|
||||
|
||||
class PeriodicWave MOZ_FINAL : public nsWrapperCache,
|
||||
public EnableWebAudioCheck
|
||||
class PeriodicWave MOZ_FINAL : public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
PeriodicWave(AudioContext* aContext,
|
||||
|
|
|
@ -36,7 +36,6 @@ EXPORTS.mozilla.dom += [
|
|||
'ConvolverNode.h',
|
||||
'DelayNode.h',
|
||||
'DynamicsCompressorNode.h',
|
||||
'EnableWebAudioCheck.h',
|
||||
'GainNode.h',
|
||||
'MediaElementAudioSourceNode.h',
|
||||
'MediaStreamAudioDestinationNode.h',
|
||||
|
@ -66,7 +65,6 @@ UNIFIED_SOURCES += [
|
|||
'DelayNode.cpp',
|
||||
'DelayProcessor.cpp',
|
||||
'DynamicsCompressorNode.cpp',
|
||||
'EnableWebAudioCheck.cpp',
|
||||
'FFTBlock.cpp',
|
||||
'GainNode.cpp',
|
||||
'MediaBufferDecoder.cpp',
|
||||
|
|
|
@ -1994,6 +1994,10 @@ nsDocShell::GatherCharsetMenuTelemetry()
|
|||
|
||||
int32_t charsetSource = doc->GetDocumentCharacterSetSource();
|
||||
switch (charsetSource) {
|
||||
case kCharsetFromTopLevelDomain:
|
||||
// Unlabeled doc on a domain that we map to a fallback encoding
|
||||
Telemetry::Accumulate(Telemetry::CHARSET_OVERRIDE_SITUATION, 7);
|
||||
break;
|
||||
case kCharsetFromFallback:
|
||||
case kCharsetFromDocTypeDefault:
|
||||
case kCharsetFromCache:
|
||||
|
|
|
@ -17,7 +17,16 @@ static const char* localesFallbacks[][3] = {
|
|||
#include "localesfallbacks.properties.h"
|
||||
};
|
||||
|
||||
static const char* domainsFallbacks[][3] = {
|
||||
#include "domainsfallbacks.properties.h"
|
||||
};
|
||||
|
||||
static const char* nonParticipatingDomains[][3] = {
|
||||
#include "nonparticipatingdomains.properties.h"
|
||||
};
|
||||
|
||||
FallbackEncoding* FallbackEncoding::sInstance = nullptr;
|
||||
bool FallbackEncoding::sGuessFallbackFromTopLevelDomain = true;
|
||||
|
||||
FallbackEncoding::FallbackEncoding()
|
||||
{
|
||||
|
@ -121,6 +130,8 @@ FallbackEncoding::Initialize()
|
|||
Preferences::RegisterCallback(FallbackEncoding::PrefChanged,
|
||||
"general.useragent.locale",
|
||||
nullptr);
|
||||
Preferences::AddBoolVarCache(&sGuessFallbackFromTopLevelDomain,
|
||||
"intl.charset.fallback.tld");
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -132,5 +143,26 @@ FallbackEncoding::Shutdown()
|
|||
FallbackEncoding::sInstance = nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
FallbackEncoding::IsParticipatingTopLevelDomain(const nsACString& aTLD)
|
||||
{
|
||||
nsAutoCString dummy;
|
||||
return NS_FAILED(nsUConvPropertySearch::SearchPropertyValue(
|
||||
nonParticipatingDomains,
|
||||
ArrayLength(nonParticipatingDomains),
|
||||
aTLD,
|
||||
dummy));
|
||||
}
|
||||
|
||||
void
|
||||
FallbackEncoding::FromTopLevelDomain(const nsACString& aTLD,
|
||||
nsACString& aFallback)
|
||||
{
|
||||
if (NS_FAILED(nsUConvPropertySearch::SearchPropertyValue(
|
||||
domainsFallbacks, ArrayLength(domainsFallbacks), aTLD, aFallback))) {
|
||||
aFallback.AssignLiteral("windows-1252");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -14,6 +14,11 @@ class FallbackEncoding
|
|||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Whether FromTopLevelDomain() should be used.
|
||||
*/
|
||||
static bool sGuessFallbackFromTopLevelDomain;
|
||||
|
||||
/**
|
||||
* Gets the locale-dependent fallback encoding for legacy HTML and plain
|
||||
* text content.
|
||||
|
@ -22,6 +27,23 @@ public:
|
|||
*/
|
||||
static void FromLocale(nsACString& aFallback);
|
||||
|
||||
/**
|
||||
* Checks if it is appropriate to call FromTopLevelDomain() for a given TLD.
|
||||
*
|
||||
* @param aTLD the top-level domain (in Punycode)
|
||||
* @return true if OK to call FromTopLevelDomain()
|
||||
*/
|
||||
static bool IsParticipatingTopLevelDomain(const nsACString& aTLD);
|
||||
|
||||
/**
|
||||
* Gets a top-level domain-depedendent fallback encoding for legacy HTML
|
||||
* and plain text content
|
||||
*
|
||||
* @param aTLD the top-level domain (in Punycode)
|
||||
* @param aFallback the outparam for the fallback encoding
|
||||
*/
|
||||
static void FromTopLevelDomain(const nsACString& aTLD, nsACString& aFallback);
|
||||
|
||||
// public API ends here!
|
||||
|
||||
/**
|
||||
|
|
|
@ -9,3 +9,7 @@ labelsencodings.properties.h: $(PROPS2ARRAYS) labelsencodings.properties
|
|||
$(PYTHON) $^ $@
|
||||
localesfallbacks.properties.h: $(PROPS2ARRAYS) localesfallbacks.properties
|
||||
$(PYTHON) $^ $@
|
||||
domainsfallbacks.properties.h: $(PROPS2ARRAYS) domainsfallbacks.properties
|
||||
$(PYTHON) $^ $@
|
||||
nonparticipatingdomains.properties.h: $(PROPS2ARRAYS) nonparticipatingdomains.properties
|
||||
$(PYTHON) $^ $@
|
||||
|
|
|
@ -0,0 +1,167 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
# This file contains educated guesses about which top-level domains are
|
||||
# likely to host legacy content that assumes a non-windows-1252 encoding.
|
||||
# Punycode TLDs are included on the theory that legacy content might appear
|
||||
# behind those relatively new TLDs if DNS just points to a legacy server.
|
||||
#
|
||||
# Encodings for which a confident-enough educated guess is missing are
|
||||
# listed in nonparticipatingdomains.properties. Domains that are listed
|
||||
# neither there nor here get windows-1252 as the associated fallback.
|
||||
#
|
||||
# The list below includes Arabic-script TLDs not on IANA list but on the
|
||||
# ICANN list:
|
||||
# http://www.icann.org/en/resources/idn/fast-track/string-evaluation-completion
|
||||
# Otherwise, the list includes non-windows-1252-affilited country TLDs from
|
||||
# https://data.iana.org/TLD/tlds-alpha-by-domain.txt
|
||||
#
|
||||
# The guesses are assigned as follows:
|
||||
# * If the country has a dominant country-affiliated language and that language
|
||||
# is part of the languages to fallbacks mapping, use the encoding for that
|
||||
# language from that mapping.
|
||||
# * Use windows-1256 for countries that have a dominant Arabic-script
|
||||
# language or whose all languages are Arabic-script languages.
|
||||
# * Use windows-1251 likewise but for Cyrillic script.
|
||||
|
||||
ae=windows-1256
|
||||
xn--mgbaam7a8h=windows-1256
|
||||
|
||||
af=windows-1256
|
||||
|
||||
bg=windows-1251
|
||||
|
||||
bh=windows-1256
|
||||
|
||||
by=windows-1251
|
||||
|
||||
cn=gbk
|
||||
xn--fiqs8s=gbk
|
||||
# Assume that Traditional Chinese TLD is meant to work if URL input happens to
|
||||
# be in the traditional mode. Expect content to be simplified anyway.
|
||||
xn--fiqz9s=gbk
|
||||
|
||||
cz=windows-1250
|
||||
|
||||
dz=windows-1256
|
||||
xn--lgbbat1ad8j=windows-1256
|
||||
|
||||
ee=windows-1257
|
||||
|
||||
eg=windows-1256
|
||||
xn--wgbh1c=windows-1256
|
||||
|
||||
gr=ISO-8859-7
|
||||
|
||||
hk=Big5-HKSCS
|
||||
xn--j6w193g=Big5-HKSCS
|
||||
|
||||
hr=windows-1250
|
||||
|
||||
hu=ISO-8859-2
|
||||
|
||||
iq=windows-1256
|
||||
|
||||
ir=windows-1256
|
||||
xn--mgba3a4f16a=windows-1256
|
||||
|
||||
jo=windows-1256
|
||||
xn--mgbayh7gpa=windows-1256
|
||||
|
||||
jp=Shift_JIS
|
||||
|
||||
kg=windows-1251
|
||||
|
||||
kp=EUC-KR
|
||||
|
||||
kr=EUC-KR
|
||||
xn--3e0b707e=EUC-KR
|
||||
|
||||
kw=windows-1256
|
||||
|
||||
kz=windows-1251
|
||||
xn--80ao21a=windows-1251
|
||||
|
||||
lb=windows-1256
|
||||
|
||||
lt=windows-1257
|
||||
|
||||
lv=windows-1257
|
||||
|
||||
ma=windows-1256
|
||||
xn--mgbc0a9azcg=windows-1256
|
||||
|
||||
mk=windows-1251
|
||||
|
||||
mn=windows-1251
|
||||
xn--l1acc=windows-1251
|
||||
|
||||
mo=Big5
|
||||
|
||||
# my
|
||||
xn--mgbx4cd0ab=windows-1256
|
||||
|
||||
om=windows-1256
|
||||
xn--mgb9awbf=windows-1256
|
||||
|
||||
#pk
|
||||
xn--mgbai9azgqp6j=windows-1256
|
||||
|
||||
pl=ISO-8859-2
|
||||
|
||||
ps=windows-1256
|
||||
xn--ygbi2ammx=windows-1256
|
||||
|
||||
qa=windows-1256
|
||||
xn--wgbl6a=windows-1256
|
||||
|
||||
rs=windows-1251
|
||||
xn--90a3ac=windows-1251
|
||||
|
||||
ru=windows-1251
|
||||
xn--p1ai=windows-1251
|
||||
|
||||
sa=windows-1256
|
||||
xn--mgberp4a5d4ar=windows-1256
|
||||
|
||||
sd=windows-1256
|
||||
xn--mgbpl2fh=windows-1256
|
||||
|
||||
sg=gbk
|
||||
xn--yfro4i67o=gbk
|
||||
|
||||
si=ISO-8859-2
|
||||
|
||||
sk=windows-1250
|
||||
|
||||
su=windows-1251
|
||||
|
||||
sy=windows-1256
|
||||
xn--mgbtf8fl=windows-1256
|
||||
|
||||
th=windows-874
|
||||
xn--o3cw4h=windows-874
|
||||
|
||||
tj=windows-1251
|
||||
|
||||
tn=windows-1256
|
||||
xn--pgbs0dh=windows-1256
|
||||
|
||||
tr=windows-1254
|
||||
|
||||
tw=Big5
|
||||
# Assume that the Simplified Chinese TLD is meant to work when URL input
|
||||
# happens in the simplified mode. Assume content is tradition anyway.
|
||||
xn--kprw13d=Big5
|
||||
xn--kpry57d=Big5
|
||||
|
||||
ua=windows-1251
|
||||
xn--j1amh=windows-1251
|
||||
|
||||
uz=windows-1251
|
||||
|
||||
vn=windows-1258
|
||||
|
||||
ye=windows-1256
|
||||
xn--mgb2ddes=windows-1256
|
|
@ -28,6 +28,8 @@ LOCAL_INCLUDES += [
|
|||
]
|
||||
|
||||
GENERATED_FILES += [
|
||||
'domainsfallbacks.properties.h',
|
||||
'labelsencodings.properties.h',
|
||||
'localesfallbacks.properties.h',
|
||||
'nonparticipatingdomains.properties.h',
|
||||
]
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
# Top-level domains listed here do not participate in TLD-based guessing.
|
||||
#
|
||||
# We should do Web crawls to see if domains listed here can migrate to
|
||||
# domainsfallbacks.properties.
|
||||
#
|
||||
# The value to the right of the = sign is ignored and serves as a placeholder.
|
||||
|
||||
# Generic
|
||||
com=windows-1252
|
||||
net=windows-1252
|
||||
org=windows-1252
|
||||
|
||||
# No Firefox localization for Azeri
|
||||
az=windows-1254
|
||||
|
||||
# windows-1251 or windows-1250?
|
||||
ba=???
|
||||
|
||||
# ISO-8859-7 or windows-1254?
|
||||
cy=???
|
||||
|
||||
# Is there enough unlabeled windows-1256 content for a windows-1255 to break
|
||||
# too much?
|
||||
il=windows-1255
|
||||
|
||||
# Out-of-country English use
|
||||
ly=windows-1256
|
||||
|
||||
# Out-of-country English use
|
||||
# md=windows-1250
|
||||
|
||||
# Out-of-country English use
|
||||
# me=windows-1251
|
||||
|
||||
# Malaysia has an Arabic-script TLD, official script is latin, possibly Chinese-script publications
|
||||
my=???
|
||||
|
||||
# No Firefox localization for Urdu; potential for minority-language sites
|
||||
# relying on windows-1252 hacks.
|
||||
pk=windows-1256
|
||||
|
||||
# The Romanian localization says windows-1252, even though the Windows legacy
|
||||
# differs.
|
||||
ro=windows-1250
|
||||
|
||||
tm=windows-1250
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<script>
|
||||
function report() {
|
||||
window.parent.postMessage(document.characterSet, "*");
|
||||
}
|
||||
</script>
|
||||
<body onload="report();">
|
|
@ -7,6 +7,7 @@ support-files =
|
|||
file_utf16_le_bom.js
|
||||
file_utf16_le_bom.xhtml
|
||||
file_utf16_le_nobom.xhtml
|
||||
file_TLD.html
|
||||
worker_helper.js
|
||||
|
||||
[test_BOMEncoding.js]
|
||||
|
@ -16,4 +17,5 @@ support-files =
|
|||
[test_TextEncoder.js]
|
||||
[test_stringencoding.html]
|
||||
[test_submit_euckr.html]
|
||||
[test_TLD.html]
|
||||
[test_utf16_files.html]
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=910211
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 910211</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 910211 **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var tlds = [
|
||||
{'tld': 'tw', 'encoding': 'Big5'},
|
||||
{'tld': 'cn', 'encoding': 'gbk'},
|
||||
{'tld': 'co.jp', 'encoding': 'Shift_JIS'},
|
||||
{'tld': 'fi', 'encoding': 'windows-1252'},
|
||||
];
|
||||
|
||||
var iframe = null;
|
||||
|
||||
var current = null;
|
||||
|
||||
function runTest() {
|
||||
iframe = document.getElementsByTagName("iframe")[0];
|
||||
window.addEventListener("message", next);
|
||||
next(null);
|
||||
}
|
||||
|
||||
function next(event) {
|
||||
if (event) {
|
||||
is(event.data, current['encoding'], "Got bad encoding for " + current["tld"]);
|
||||
}
|
||||
current = tlds.shift();
|
||||
if (!current) {
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
iframe.src = "http://example." + current["tld"] + "/tests/dom/encoding/test/file_TLD.html";
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="runTest();">
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=910211">Mozilla Bug 910211</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<iframe></iframe>
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -10,7 +10,6 @@
|
|||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[PrefControlled]
|
||||
interface AnalyserNode : AudioNode {
|
||||
|
||||
// Real-time frequency-domain data
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[PrefControlled]
|
||||
interface AudioBuffer {
|
||||
|
||||
readonly attribute float sampleRate;
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[PrefControlled]
|
||||
interface AudioBufferSourceNode : AudioNode {
|
||||
|
||||
attribute AudioBuffer? buffer;
|
||||
|
@ -34,7 +33,6 @@ interface AudioBufferSourceNode : AudioNode {
|
|||
* The origin of this IDL file is
|
||||
* https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#AlternateNames
|
||||
*/
|
||||
[PrefControlled]
|
||||
partial interface AudioBufferSourceNode {
|
||||
// Same as start()
|
||||
[Throws,Pref="media.webaudio.legacy.AudioBufferSourceNode"]
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
callback DecodeSuccessCallback = void (AudioBuffer decodedData);
|
||||
callback DecodeErrorCallback = void ();
|
||||
|
||||
[Constructor, PrefControlled]
|
||||
[Constructor]
|
||||
interface AudioContext : EventTarget {
|
||||
|
||||
readonly attribute AudioDestinationNode destination;
|
||||
|
@ -78,7 +78,6 @@ interface AudioContext : EventTarget {
|
|||
* The origin of this IDL file is
|
||||
* https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#AlternateNames
|
||||
*/
|
||||
[PrefControlled]
|
||||
partial interface AudioContext {
|
||||
[NewObject, Throws]
|
||||
AudioBuffer? createBuffer(ArrayBuffer buffer, boolean mixToMono);
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[PrefControlled]
|
||||
interface AudioDestinationNode : AudioNode {
|
||||
|
||||
readonly attribute unsigned long maxChannelCount;
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[PrefControlled]
|
||||
interface AudioListener {
|
||||
|
||||
// same as OpenAL (default 1)
|
||||
|
|
|
@ -21,7 +21,6 @@ enum ChannelInterpretation {
|
|||
"discrete"
|
||||
};
|
||||
|
||||
[PrefControlled]
|
||||
interface AudioNode : EventTarget {
|
||||
|
||||
[Throws]
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[PrefControlled]
|
||||
interface AudioParam {
|
||||
|
||||
attribute float value;
|
||||
|
@ -43,7 +42,6 @@ interface AudioParam {
|
|||
* The origin of this IDL file is
|
||||
* https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#AlternateNames
|
||||
*/
|
||||
[PrefControlled]
|
||||
partial interface AudioParam {
|
||||
// Same as setTargetAtTime()
|
||||
[Throws,Pref="media.webaudio.legacy.AudioParam"]
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[PrefControlled]
|
||||
interface AudioProcessingEvent : Event {
|
||||
|
||||
readonly attribute double playbackTime;
|
||||
|
|
|
@ -24,7 +24,6 @@ enum BiquadFilterType {
|
|||
"allpass"
|
||||
};
|
||||
|
||||
[PrefControlled]
|
||||
interface BiquadFilterNode : AudioNode {
|
||||
|
||||
attribute BiquadFilterType type;
|
||||
|
@ -43,7 +42,6 @@ interface BiquadFilterNode : AudioNode {
|
|||
* The origin of this IDL file is
|
||||
* https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#AlternateNames
|
||||
*/
|
||||
[PrefControlled]
|
||||
partial interface BiquadFilterNode {
|
||||
[Pref="media.webaudio.legacy.BiquadFilterNode"]
|
||||
const unsigned short LOWPASS = 0;
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[PrefControlled]
|
||||
interface ChannelMergerNode : AudioNode {
|
||||
|
||||
};
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[PrefControlled]
|
||||
interface ChannelSplitterNode : AudioNode {
|
||||
|
||||
};
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[PrefControlled]
|
||||
interface ConvolverNode : AudioNode {
|
||||
|
||||
[SetterThrows]
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[PrefControlled]
|
||||
interface DelayNode : AudioNode {
|
||||
|
||||
readonly attribute AudioParam delayTime;
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[PrefControlled]
|
||||
interface DynamicsCompressorNode : AudioNode {
|
||||
|
||||
readonly attribute AudioParam threshold; // in Decibels
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[PrefControlled]
|
||||
interface GainNode : AudioNode {
|
||||
|
||||
readonly attribute AudioParam gain;
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[PrefControlled]
|
||||
interface MediaElementAudioSourceNode : AudioNode {
|
||||
|
||||
};
|
||||
|
|
|
@ -10,9 +10,8 @@
|
|||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[PrefControlled]
|
||||
interface MediaStreamAudioDestinationNode : AudioNode {
|
||||
|
||||
readonly attribute MediaStream stream;
|
||||
|
||||
};
|
||||
};
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[PrefControlled]
|
||||
interface OfflineAudioCompletionEvent : Event {
|
||||
|
||||
readonly attribute AudioBuffer renderedBuffer;
|
||||
|
|
|
@ -12,8 +12,7 @@
|
|||
|
||||
callback OfflineRenderSuccessCallback = void (AudioBuffer renderedData);
|
||||
|
||||
[Constructor(unsigned long numberOfChannels, unsigned long length, float sampleRate),
|
||||
PrefControlled]
|
||||
[Constructor(unsigned long numberOfChannels, unsigned long length, float sampleRate)]
|
||||
interface OfflineAudioContext : AudioContext {
|
||||
|
||||
[Throws]
|
||||
|
|
|
@ -21,7 +21,6 @@ enum OscillatorType {
|
|||
"custom"
|
||||
};
|
||||
|
||||
[PrefControlled]
|
||||
interface OscillatorNode : AudioNode {
|
||||
|
||||
[SetterThrows]
|
||||
|
|
|
@ -27,7 +27,6 @@ enum DistanceModelType {
|
|||
"exponential"
|
||||
};
|
||||
|
||||
[PrefControlled]
|
||||
interface PannerNode : AudioNode {
|
||||
|
||||
// Default for stereo is HRTF
|
||||
|
@ -55,7 +54,6 @@ interface PannerNode : AudioNode {
|
|||
* The origin of this IDL file is
|
||||
* https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#AlternateNames
|
||||
*/
|
||||
[PrefControlled]
|
||||
partial interface PannerNode {
|
||||
[Pref="media.webaudio.legacy.PannerNode"]
|
||||
const unsigned short EQUALPOWER = 0;
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[PrefControlled]
|
||||
interface PeriodicWave {
|
||||
|
||||
};
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[PrefControlled]
|
||||
interface ScriptProcessorNode : AudioNode {
|
||||
|
||||
attribute EventHandler onaudioprocess;
|
||||
|
|
|
@ -16,7 +16,6 @@ enum OverSampleType {
|
|||
"4x"
|
||||
};
|
||||
|
||||
[PrefControlled]
|
||||
interface WaveShaperNode : AudioNode {
|
||||
|
||||
attribute Float32Array? curve;
|
||||
|
|
|
@ -275,6 +275,30 @@ GetWorkerPref(const nsACString& aPref,
|
|||
return result;
|
||||
}
|
||||
|
||||
// This function creates a key for a SharedWorker composed by "name|scriptSpec".
|
||||
// If the name contains a '|', this will be replaced by '||'.
|
||||
void
|
||||
GenerateSharedWorkerKey(const nsACString& aScriptSpec, const nsACString& aName,
|
||||
nsCString& aKey)
|
||||
{
|
||||
aKey.Truncate();
|
||||
aKey.SetCapacity(aScriptSpec.Length() + aName.Length() + 1);
|
||||
|
||||
nsACString::const_iterator start, end;
|
||||
aName.BeginReading(start);
|
||||
aName.EndReading(end);
|
||||
for (; start != end; ++start) {
|
||||
if (*start == '|') {
|
||||
aKey.AppendASCII("||");
|
||||
} else {
|
||||
aKey.Append(*start);
|
||||
}
|
||||
}
|
||||
|
||||
aKey.Append('|');
|
||||
aKey.Append(aScriptSpec);
|
||||
}
|
||||
|
||||
void
|
||||
LoadJSContextOptions(const char* aPrefName, void* /* aClosure */)
|
||||
{
|
||||
|
@ -1257,7 +1281,7 @@ RuntimeService::RegisterWorker(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
|||
|
||||
bool isSharedWorker = aWorkerPrivate->IsSharedWorker();
|
||||
|
||||
const nsString& sharedWorkerName = aWorkerPrivate->SharedWorkerName();
|
||||
const nsCString& sharedWorkerName = aWorkerPrivate->SharedWorkerName();
|
||||
nsCString sharedWorkerScriptSpec;
|
||||
|
||||
if (isSharedWorker) {
|
||||
|
@ -1306,13 +1330,14 @@ RuntimeService::RegisterWorker(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
|||
}
|
||||
|
||||
if (isSharedWorker) {
|
||||
MOZ_ASSERT(!domainInfo->mSharedWorkerInfos.Get(sharedWorkerScriptSpec));
|
||||
nsAutoCString key;
|
||||
GenerateSharedWorkerKey(sharedWorkerScriptSpec, sharedWorkerName, key);
|
||||
MOZ_ASSERT(!domainInfo->mSharedWorkerInfos.Get(key));
|
||||
|
||||
SharedWorkerInfo* sharedWorkerInfo =
|
||||
new SharedWorkerInfo(aWorkerPrivate, sharedWorkerScriptSpec,
|
||||
sharedWorkerName);
|
||||
domainInfo->mSharedWorkerInfos.Put(sharedWorkerScriptSpec,
|
||||
sharedWorkerInfo);
|
||||
domainInfo->mSharedWorkerInfos.Put(key, sharedWorkerInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1402,8 +1427,10 @@ RuntimeService::UnregisterWorker(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
|||
&match);
|
||||
|
||||
if (match.mSharedWorkerInfo) {
|
||||
domainInfo->mSharedWorkerInfos.Remove(
|
||||
match.mSharedWorkerInfo->mScriptSpec);
|
||||
nsAutoCString key;
|
||||
GenerateSharedWorkerKey(match.mSharedWorkerInfo->mScriptSpec,
|
||||
match.mSharedWorkerInfo->mName, key);
|
||||
domainInfo->mSharedWorkerInfos.Remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2051,7 +2078,7 @@ RuntimeService::ResumeWorkersForWindow(nsPIDOMWindow* aWindow)
|
|||
nsresult
|
||||
RuntimeService::CreateSharedWorker(const GlobalObject& aGlobal,
|
||||
const nsAString& aScriptURL,
|
||||
const nsAString& aName,
|
||||
const nsACString& aName,
|
||||
SharedWorker** aSharedWorker)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
@ -2079,9 +2106,11 @@ RuntimeService::CreateSharedWorker(const GlobalObject& aGlobal,
|
|||
WorkerDomainInfo* domainInfo;
|
||||
SharedWorkerInfo* sharedWorkerInfo;
|
||||
|
||||
nsAutoCString key;
|
||||
GenerateSharedWorkerKey(scriptSpec, aName, key);
|
||||
|
||||
if (mDomainMap.Get(loadInfo.mDomain, &domainInfo) &&
|
||||
domainInfo->mSharedWorkerInfos.Get(scriptSpec, &sharedWorkerInfo) &&
|
||||
sharedWorkerInfo->mName == aName) {
|
||||
domainInfo->mSharedWorkerInfos.Get(key, &sharedWorkerInfo)) {
|
||||
workerPrivate = sharedWorkerInfo->mWorkerPrivate;
|
||||
}
|
||||
}
|
||||
|
@ -2144,8 +2173,10 @@ RuntimeService::ForgetSharedWorker(WorkerPrivate* aWorkerPrivate)
|
|||
&match);
|
||||
|
||||
if (match.mSharedWorkerInfo) {
|
||||
domainInfo->mSharedWorkerInfos.Remove(
|
||||
match.mSharedWorkerInfo->mScriptSpec);
|
||||
nsAutoCString key;
|
||||
GenerateSharedWorkerKey(match.mSharedWorkerInfo->mScriptSpec,
|
||||
match.mSharedWorkerInfo->mName, key);
|
||||
domainInfo->mSharedWorkerInfos.Remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,11 +37,11 @@ private:
|
|||
{
|
||||
WorkerPrivate* mWorkerPrivate;
|
||||
nsCString mScriptSpec;
|
||||
nsString mName;
|
||||
nsCString mName;
|
||||
|
||||
SharedWorkerInfo(WorkerPrivate* aWorkerPrivate,
|
||||
const nsACString& aScriptSpec,
|
||||
const nsAString& aName)
|
||||
const nsACString& aName)
|
||||
: mWorkerPrivate(aWorkerPrivate), mScriptSpec(aScriptSpec), mName(aName)
|
||||
{ }
|
||||
};
|
||||
|
@ -144,7 +144,7 @@ public:
|
|||
nsresult
|
||||
CreateSharedWorker(const GlobalObject& aGlobal,
|
||||
const nsAString& aScriptURL,
|
||||
const nsAString& aName,
|
||||
const nsACString& aName,
|
||||
SharedWorker** aSharedWorker);
|
||||
|
||||
void
|
||||
|
|
|
@ -72,9 +72,9 @@ SharedWorker::Constructor(const GlobalObject& aGlobal, JSContext* aCx,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
nsString name;
|
||||
nsCString name;
|
||||
if (aName.WasPassed()) {
|
||||
name = aName.Value();
|
||||
name = NS_ConvertUTF16toUTF8(aName.Value());
|
||||
}
|
||||
|
||||
nsRefPtr<SharedWorker> sharedWorker;
|
||||
|
|
|
@ -2092,13 +2092,13 @@ typename WorkerPrivateParent<Derived>::cycleCollection
|
|||
|
||||
template <class Derived>
|
||||
WorkerPrivateParent<Derived>::WorkerPrivateParent(
|
||||
JSContext* aCx,
|
||||
WorkerPrivate* aParent,
|
||||
const nsAString& aScriptURL,
|
||||
bool aIsChromeWorker,
|
||||
WorkerType aWorkerType,
|
||||
const nsAString& aSharedWorkerName,
|
||||
LoadInfo& aLoadInfo)
|
||||
JSContext* aCx,
|
||||
WorkerPrivate* aParent,
|
||||
const nsAString& aScriptURL,
|
||||
bool aIsChromeWorker,
|
||||
WorkerType aWorkerType,
|
||||
const nsACString& aSharedWorkerName,
|
||||
LoadInfo& aLoadInfo)
|
||||
: mMutex("WorkerPrivateParent Mutex"),
|
||||
mCondVar(mMutex, "WorkerPrivateParent CondVar"),
|
||||
mMemoryReportCondVar(mMutex, "WorkerPrivateParent Memory Report CondVar"),
|
||||
|
@ -3523,7 +3523,7 @@ WorkerPrivate::WorkerPrivate(JSContext* aCx,
|
|||
WorkerPrivate* aParent,
|
||||
const nsAString& aScriptURL,
|
||||
bool aIsChromeWorker, WorkerType aWorkerType,
|
||||
const nsAString& aSharedWorkerName,
|
||||
const nsACString& aSharedWorkerName,
|
||||
LoadInfo& aLoadInfo)
|
||||
: WorkerPrivateParent<WorkerPrivate>(aCx, aParent, aScriptURL,
|
||||
aIsChromeWorker, aWorkerType,
|
||||
|
@ -3563,8 +3563,9 @@ WorkerPrivate::Constructor(const GlobalObject& aGlobal,
|
|||
const nsAString& aScriptURL,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
return WorkerPrivate::Constructor(aGlobal, aScriptURL, false, WorkerTypeDedicated,
|
||||
EmptyString(), nullptr, aRv);
|
||||
return WorkerPrivate::Constructor(aGlobal, aScriptURL, false,
|
||||
WorkerTypeDedicated, EmptyCString(),
|
||||
nullptr, aRv);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -3591,8 +3592,10 @@ ChromeWorkerPrivate::Constructor(const GlobalObject& aGlobal,
|
|||
const nsAString& aScriptURL,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
return WorkerPrivate::Constructor(aGlobal, aScriptURL, true, WorkerTypeDedicated,
|
||||
EmptyString(), nullptr, aRv).downcast<ChromeWorkerPrivate>();
|
||||
return WorkerPrivate::Constructor(aGlobal, aScriptURL, true,
|
||||
WorkerTypeDedicated, EmptyCString(),
|
||||
nullptr, aRv)
|
||||
.downcast<ChromeWorkerPrivate>();
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -3609,7 +3612,7 @@ already_AddRefed<WorkerPrivate>
|
|||
WorkerPrivate::Constructor(const GlobalObject& aGlobal,
|
||||
const nsAString& aScriptURL,
|
||||
bool aIsChromeWorker, WorkerType aWorkerType,
|
||||
const nsAString& aSharedWorkerName,
|
||||
const nsACString& aSharedWorkerName,
|
||||
LoadInfo* aLoadInfo, ErrorResult& aRv)
|
||||
{
|
||||
WorkerPrivate* parent = NS_IsMainThread() ?
|
||||
|
|
|
@ -214,7 +214,7 @@ protected:
|
|||
private:
|
||||
WorkerPrivate* mParent;
|
||||
nsString mScriptURL;
|
||||
nsString mSharedWorkerName;
|
||||
nsCString mSharedWorkerName;
|
||||
LocationInfo mLocationInfo;
|
||||
// The lifetime of these objects within LoadInfo is managed explicitly;
|
||||
// they do not need to be cycle collected.
|
||||
|
@ -251,7 +251,8 @@ protected:
|
|||
WorkerPrivateParent(JSContext* aCx, WorkerPrivate* aParent,
|
||||
const nsAString& aScriptURL, bool aIsChromeWorker,
|
||||
WorkerType aWorkerType,
|
||||
const nsAString& aSharedWorkerName, LoadInfo& aLoadInfo);
|
||||
const nsACString& aSharedWorkerName,
|
||||
LoadInfo& aLoadInfo);
|
||||
|
||||
~WorkerPrivateParent();
|
||||
|
||||
|
@ -648,7 +649,7 @@ public:
|
|||
return mWorkerType == WorkerTypeShared;
|
||||
}
|
||||
|
||||
const nsString&
|
||||
const nsCString&
|
||||
SharedWorkerName() const
|
||||
{
|
||||
return mSharedWorkerName;
|
||||
|
@ -788,7 +789,7 @@ public:
|
|||
static already_AddRefed<WorkerPrivate>
|
||||
Constructor(const GlobalObject& aGlobal, const nsAString& aScriptURL,
|
||||
bool aIsChromeWorker, WorkerType aWorkerType,
|
||||
const nsAString& aSharedWorkerName,
|
||||
const nsACString& aSharedWorkerName,
|
||||
LoadInfo* aLoadInfo, ErrorResult& aRv);
|
||||
|
||||
static bool
|
||||
|
@ -1042,7 +1043,7 @@ public:
|
|||
private:
|
||||
WorkerPrivate(JSContext* aCx, WorkerPrivate* aParent,
|
||||
const nsAString& aScriptURL, bool aIsChromeWorker,
|
||||
WorkerType aWorkerType, const nsAString& aSharedWorkerName,
|
||||
WorkerType aWorkerType, const nsACString& aSharedWorkerName,
|
||||
LoadInfo& aLoadInfo);
|
||||
|
||||
void
|
||||
|
|
|
@ -311,7 +311,7 @@ DedicatedWorkerGlobalScope::PostMessage(JSContext* aCx,
|
|||
}
|
||||
|
||||
SharedWorkerGlobalScope::SharedWorkerGlobalScope(WorkerPrivate* aWorkerPrivate,
|
||||
const nsString& aName)
|
||||
const nsCString& aName)
|
||||
: WorkerGlobalScope(aWorkerPrivate), mName(aName)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -138,12 +138,13 @@ public:
|
|||
|
||||
class SharedWorkerGlobalScope MOZ_FINAL : public WorkerGlobalScope
|
||||
{
|
||||
const nsString mName;
|
||||
const nsCString mName;
|
||||
|
||||
~SharedWorkerGlobalScope() { }
|
||||
|
||||
public:
|
||||
SharedWorkerGlobalScope(WorkerPrivate* aWorkerPrivate, const nsString& aName);
|
||||
SharedWorkerGlobalScope(WorkerPrivate* aWorkerPrivate,
|
||||
const nsCString& aName);
|
||||
|
||||
static bool
|
||||
Visible(JSContext* aCx, JSObject* aObj);
|
||||
|
@ -152,7 +153,7 @@ public:
|
|||
WrapGlobalObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||
|
||||
void GetName(DOMString& aName) const {
|
||||
aName.AsAString() = mName;
|
||||
aName.AsAString() = NS_ConvertUTF8toUTF16(mName);
|
||||
}
|
||||
|
||||
IMPL_EVENT_HANDLER(connect)
|
||||
|
|
|
@ -71,6 +71,7 @@ support-files =
|
|||
[test_atob.html]
|
||||
[test_blobConstructor.html]
|
||||
[test_blobWorkers.html]
|
||||
[test_bug949946.html]
|
||||
[test_chromeWorker.html]
|
||||
[test_clearTimeouts.html]
|
||||
[test_close.html]
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for bug 949946</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
SpecialPowers.pushPrefEnv({ set: [["dom.workers.sharedWorkers.enabled", true]] }, function() {
|
||||
new SharedWorker('sharedWorker_sharedWorker.js');
|
||||
new SharedWorker('sharedWorker_sharedWorker.js', ':');
|
||||
new SharedWorker('sharedWorker_sharedWorker.js', '|||');
|
||||
ok(true, "3 SharedWorkers created!");
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -293,9 +293,11 @@ ContentClientRemoteBuffer::Updated(const nsIntRegion& aRegionToDraw,
|
|||
aDidSelfCopy);
|
||||
|
||||
MOZ_ASSERT(mTextureClient);
|
||||
mForwarder->UseTexture(this, mTextureClient);
|
||||
if (mTextureClientOnWhite) {
|
||||
mForwarder->UseTexture(this, mTextureClientOnWhite);
|
||||
mForwarder->UseComponentAlphaTextures(this, mTextureClient,
|
||||
mTextureClientOnWhite);
|
||||
} else {
|
||||
mForwarder->UseTexture(this, mTextureClient);
|
||||
}
|
||||
mForwarder->UpdateTextureRegion(this,
|
||||
ThebesBufferData(BufferRect(),
|
||||
|
|
|
@ -109,6 +109,7 @@ public:
|
|||
// call before and after painting into this content client
|
||||
virtual void BeginPaint() {}
|
||||
virtual void EndPaint() {}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -48,6 +48,17 @@ CompositableHost::UseTextureHost(TextureHost* aTexture)
|
|||
aTexture->SetCompositableBackendSpecificData(GetCompositableBackendSpecificData());
|
||||
}
|
||||
|
||||
void
|
||||
CompositableHost::UseComponentAlphaTextures(TextureHost* aTextureOnBlack,
|
||||
TextureHost* aTextureOnWhite)
|
||||
{
|
||||
MOZ_ASSERT(aTextureOnBlack && aTextureOnWhite);
|
||||
aTextureOnBlack->SetCompositor(GetCompositor());
|
||||
aTextureOnBlack->SetCompositableBackendSpecificData(GetCompositableBackendSpecificData());
|
||||
aTextureOnWhite->SetCompositor(GetCompositor());
|
||||
aTextureOnWhite->SetCompositableBackendSpecificData(GetCompositableBackendSpecificData());
|
||||
}
|
||||
|
||||
void
|
||||
CompositableHost::SetCompositor(Compositor* aCompositor)
|
||||
{
|
||||
|
|
|
@ -288,6 +288,8 @@ public:
|
|||
virtual void PrintInfo(nsACString& aTo, const char* aPrefix) { }
|
||||
|
||||
virtual void UseTextureHost(TextureHost* aTexture);
|
||||
virtual void UseComponentAlphaTextures(TextureHost* aTextureOnBlack,
|
||||
TextureHost* aTextureOnWhite);
|
||||
|
||||
protected:
|
||||
TextureInfo mTextureInfo;
|
||||
|
|
|
@ -220,13 +220,18 @@ ContentHostBase::Composite(EffectChain& aEffectChain,
|
|||
void
|
||||
ContentHostBase::UseTextureHost(TextureHost* aTexture)
|
||||
{
|
||||
if (aTexture->GetFlags() & TEXTURE_ON_WHITE) {
|
||||
mTextureHostOnWhite = aTexture;
|
||||
mTextureHostOnWhite->SetCompositor(GetCompositor());
|
||||
} else {
|
||||
mTextureHost = aTexture;
|
||||
mTextureHost->SetCompositor(GetCompositor());
|
||||
}
|
||||
mTextureHost = aTexture;
|
||||
mTextureHostOnWhite = nullptr;
|
||||
mTextureHost->SetCompositor(GetCompositor());
|
||||
}
|
||||
|
||||
void
|
||||
ContentHostBase::UseComponentAlphaTextures(TextureHost* aTextureOnBlack,
|
||||
TextureHost* aTextureOnWhite)
|
||||
{
|
||||
CompositableHost::UseComponentAlphaTextures(aTextureOnBlack, aTextureOnWhite);
|
||||
mTextureHost = aTextureOnBlack;
|
||||
mTextureHostOnWhite = aTextureOnWhite;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -116,6 +116,8 @@ public:
|
|||
virtual TextureHost* GetAsTextureHost() MOZ_OVERRIDE;
|
||||
|
||||
virtual void UseTextureHost(TextureHost* aTexture) MOZ_OVERRIDE;
|
||||
virtual void UseComponentAlphaTextures(TextureHost* aTextureOnBlack,
|
||||
TextureHost* aTextureOnWhite) MOZ_OVERRIDE;
|
||||
|
||||
virtual void SetPaintWillResample(bool aResample) { mPaintWillResample = aResample; }
|
||||
|
||||
|
|
|
@ -190,6 +190,9 @@ public:
|
|||
*/
|
||||
virtual void UseTexture(CompositableClient* aCompositable,
|
||||
TextureClient* aClient) = 0;
|
||||
virtual void UseComponentAlphaTextures(CompositableClient* aCompositable,
|
||||
TextureClient* aClientOnBlack,
|
||||
TextureClient* aClientOnWhite) = 0;
|
||||
|
||||
/**
|
||||
* Tell the compositor side that the shared data has been modified so that
|
||||
|
|
|
@ -233,6 +233,20 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
|
|||
}
|
||||
break;
|
||||
}
|
||||
case CompositableOperation::TOpUseComponentAlphaTextures: {
|
||||
const OpUseComponentAlphaTextures& op = aEdit.get_OpUseComponentAlphaTextures();
|
||||
CompositableHost* compositable = AsCompositable(op);
|
||||
RefPtr<TextureHost> texOnBlack = TextureHost::AsTextureHost(op.textureOnBlackParent());
|
||||
RefPtr<TextureHost> texOnWhite = TextureHost::AsTextureHost(op.textureOnWhiteParent());
|
||||
|
||||
MOZ_ASSERT(texOnBlack && texOnWhite);
|
||||
compositable->UseComponentAlphaTextures(texOnBlack, texOnWhite);
|
||||
|
||||
if (IsAsync()) {
|
||||
ScheduleComposition(op);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CompositableOperation::TOpUpdateTexture: {
|
||||
const OpUpdateTexture& op = aEdit.get_OpUpdateTexture();
|
||||
RefPtr<TextureHost> texture = TextureHost::AsTextureHost(op.textureParent());
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче