IGNORE IDL
This commit is contained in:
Phil Ringnalda 2015-04-04 11:09:51 -07:00
Родитель 5b396a0fae 3ec9a25f34
Коммит 10292980d7
293 изменённых файлов: 7571 добавлений и 4235 удалений

Просмотреть файл

@ -2982,6 +2982,14 @@
<gfxBlacklistEntry blockID="g511"> <os>WINNT 5.1</os> <vendor>0x8086</vendor> <feature>DIRECT3D_9_LAYERS, WEBGL_ANGLE</feature> <featureStatus>BLOCKED_DRIVER_VERSION</featureStatus> <driverVersion>6.14.10.5218</driverVersion> <driverVersionComparator>LESS_THAN</driverVersionComparator> </gfxBlacklistEntry>
</gfxItems>
<certItems>
<certItem issuerName="MIGQMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01PRE8gQ0EgTGltaXRlZDE2MDQGA1UEAxMtQ09NT0RPIFJTQSBEb21haW4gVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENB">
<serialNumber>D9UltDPl4XVfSSqQOvdiwQ==</serialNumber>
</certItem>
<certItem issuerName="MDIxCzAJBgNVBAYTAkNOMQ4wDAYDVQQKEwVDTk5JQzETMBEGA1UEAxMKQ05OSUMgUk9PVA==">
<serialNumber>STMAjg==</serialNumber>
</certItem>
</certItems>
</blocklist>

Просмотреть файл

@ -258,7 +258,7 @@ const gXPInstallObserver = {
label: gNavigatorBundle.getString("addonInstallRestartButton"),
accessKey: gNavigatorBundle.getString("addonInstallRestartButton.accesskey"),
callback: function() {
Application.restart();
BrowserUtils.restartApplication();
}
};
}
@ -374,7 +374,7 @@ var LightWeightThemeWebInstaller = {
label: gNavigatorBundle.getString("lwthemeNeedsRestart.button"),
accessKey: gNavigatorBundle.getString("lwthemeNeedsRestart.accesskey"),
callback: function () {
Application.restart();
BrowserUtils.restartApplication();
}
};

Просмотреть файл

@ -104,6 +104,7 @@ let ReadingListUI = {
}
document.getElementById(READINGLIST_COMMAND_ID).setAttribute("hidden", !enabled);
document.getElementById(READINGLIST_COMMAND_ID).setAttribute("disabled", !enabled);
},
/**

Просмотреть файл

@ -149,7 +149,7 @@
sidebarurl="chrome://browser/content/history/history-panel.xul"
oncommand="SidebarUI.toggle('viewHistorySidebar');"/>
<broadcaster id="readingListSidebar" hidden="true" autoCheck="false"
<broadcaster id="readingListSidebar" hidden="true" autoCheck="false" disabled="true"
sidebartitle="&readingList.label;" type="checkbox" group="sidebar"
sidebarurl="chrome://browser/content/readinglist/sidebar.xhtml"
oncommand="SidebarUI.toggle('readingListSidebar');"/>

Просмотреть файл

@ -2558,11 +2558,7 @@ let gMenuButtonUpdateBadge = {
// If the update is successfully applied, or if the updater has fallen back
// to non-staged updates, add a badge to the hamburger menu to indicate an
// update will be applied once the browser restarts.
let badge = document.getAnonymousElementByAttribute(PanelUI.menuButton,
"class",
"toolbarbutton-badge");
badge.style.backgroundColor = '#74BF43';
PanelUI.menuButton.setAttribute("badge", "\u2B06");
PanelUI.menuButton.setAttribute("update-status", "succeeded");
let brandBundle = document.getElementById("bundle_brand");
let brandShortName = brandBundle.getString("brandShortName");
@ -2580,6 +2576,7 @@ let gMenuButtonUpdateBadge = {
case STATE_FAILED:
// Background update has failed, let's show the UI responsible for
// prompting the user to update manually.
PanelUI.menuButton.setAttribute("update-status", "failed");
PanelUI.menuButton.setAttribute("badge", "!");
stringId = "appmenu.updateFailed.description";

Просмотреть файл

@ -3924,8 +3924,8 @@
<!-- Deprecated stuff, implemented for backwards compatibility. -->
<method name="enterTabbedMode">
<body>
Application.console.log("enterTabbedMode is an obsolete method and " +
"will be removed in a future release.");
Services.console.logStringMessage("enterTabbedMode is an obsolete method and " +
"will be removed in a future release.");
</body>
</method>
<field name="mTabbedMode" readonly="true">true</field>

Просмотреть файл

@ -68,11 +68,6 @@ ServerClient.prototype = {
},
_removeToken(token) {
// XXX - remove this check once tokencaching landsin FxA.
if (!this.fxa.removeCachedOAuthToken) {
dump("XXX - token caching support is yet to land - can't remove token!");
return;
}
return this.fxa.removeCachedOAuthToken({token});
},

Просмотреть файл

@ -106,9 +106,12 @@ let AnimationsController = {
"setCurrentTime");
this.hasMutationEvents = yield target.actorHasMethod("animations",
"stopAnimationPlayerUpdates");
this.hasSetPlaybackRate = yield target.actorHasMethod("animationplayer",
"setPlaybackRate");
this.onPanelVisibilityChange = this.onPanelVisibilityChange.bind(this);
this.onNewNodeFront = this.onNewNodeFront.bind(this);
this.onAnimationMutations = this.onAnimationMutations.bind(this);
this.startListeners();
@ -151,6 +154,9 @@ let AnimationsController = {
gInspector.selection.off("new-node-front", this.onNewNodeFront);
gInspector.sidebar.off("select", this.onPanelVisibilityChange);
gToolbox.off("select", this.onPanelVisibilityChange);
if (this.isListeningToMutations) {
this.animationsFront.off("mutations", this.onAnimationMutations);
}
},
isPanelVisible: function() {
@ -213,6 +219,34 @@ let AnimationsController = {
this.animationPlayers = yield this.animationsFront.getAnimationPlayersForNode(nodeFront);
this.startAllAutoRefresh();
// Start listening for animation mutations only after the first method call
// otherwise events won't be sent.
if (!this.isListeningToMutations && this.hasMutationEvents) {
this.animationsFront.on("mutations", this.onAnimationMutations);
this.isListeningToMutations = true;
}
}),
onAnimationMutations: Task.async(function*(changes) {
// Insert new players into this.animationPlayers when new animations are
// added.
for (let {type, player} of changes) {
if (type === "added") {
this.animationPlayers.push(player);
player.startAutoRefresh();
}
if (type === "removed") {
player.stopAutoRefresh();
yield player.release();
let index = this.animationPlayers.indexOf(player);
this.animationPlayers.splice(index, 1);
}
}
// Let the UI know the list has been updated.
this.emit(this.PLAYERS_UPDATED_EVENT, this.animationPlayers);
}),
startAllAutoRefresh: function() {

Просмотреть файл

@ -19,7 +19,7 @@
<span class="label">&allAnimations;</span>
<button id="toggle-all" standalone="true" class="devtools-button"></button>
</div>
<div id="players" class="theme-toolbar"></div>
<div id="players"></div>
<div id="error-message">
<p>&invalidElement;</p>
<p>&selectElement;</p>

Просмотреть файл

@ -187,8 +187,12 @@ function PlayerWidget(player, containerEl) {
this.onRewindBtnClick = this.onRewindBtnClick.bind(this);
this.onFastForwardBtnClick = this.onFastForwardBtnClick.bind(this);
this.onCurrentTimeChanged = this.onCurrentTimeChanged.bind(this);
this.onPlaybackRateChanged = this.onPlaybackRateChanged.bind(this);
this.metaDataComponent = new PlayerMetaDataHeader();
if (AnimationsController.hasSetPlaybackRate) {
this.rateComponent = new PlaybackRateSelector();
}
}
PlayerWidget.prototype = {
@ -211,6 +215,9 @@ PlayerWidget.prototype = {
this.stopTimelineAnimation();
this.stopListeners();
this.metaDataComponent.destroy();
if (this.rateComponent) {
this.rateComponent.destroy();
}
this.el.remove();
this.playPauseBtnEl = this.rewindBtnEl = this.fastForwardBtnEl = null;
@ -226,6 +233,9 @@ PlayerWidget.prototype = {
this.fastForwardBtnEl.addEventListener("click", this.onFastForwardBtnClick);
this.currentTimeEl.addEventListener("input", this.onCurrentTimeChanged);
}
if (this.rateComponent) {
this.rateComponent.on("rate-changed", this.onPlaybackRateChanged);
}
},
stopListeners: function() {
@ -236,6 +246,9 @@ PlayerWidget.prototype = {
this.fastForwardBtnEl.removeEventListener("click", this.onFastForwardBtnClick);
this.currentTimeEl.removeEventListener("input", this.onCurrentTimeChanged);
}
if (this.rateComponent) {
this.rateComponent.off("rate-changed", this.onPlaybackRateChanged);
}
},
createMarkup: function() {
@ -247,7 +260,7 @@ PlayerWidget.prototype = {
}
});
this.metaDataComponent.createMarkup(this.el);
this.metaDataComponent.init(this.el);
this.metaDataComponent.render(state);
// Timeline widget.
@ -293,6 +306,11 @@ PlayerWidget.prototype = {
});
}
if (this.rateComponent) {
this.rateComponent.init(playbackControlsEl);
this.rateComponent.render(state);
}
// Sliders container.
let slidersContainerEl = createNode({
parent: timelineEl,
@ -378,19 +396,30 @@ PlayerWidget.prototype = {
this.setCurrentTime(parseFloat(time), true);
},
/**
* Executed when the playback rate dropdown value changes in the playbackrate
* component.
*/
onPlaybackRateChanged: function(e, rate) {
this.setPlaybackRate(rate);
},
/**
* Whenever a player state update is received.
*/
onStateChanged: function() {
let state = this.player.state;
this.updateWidgetState(state);
this.metaDataComponent.render(state);
if (this.rateComponent) {
this.rateComponent.render(state);
}
switch (state.playState) {
case "finished":
this.stopTimelineAnimation();
this.displayTime(this.player.state.duration);
this.stopListeners();
this.displayTime(this.player.state.currentTime);
break;
case "running":
this.startTimelineAnimation();
@ -399,6 +428,10 @@ PlayerWidget.prototype = {
this.stopTimelineAnimation();
this.displayTime(this.player.state.currentTime);
break;
case "idle":
this.stopTimelineAnimation();
this.displayTime(0);
break;
}
},
@ -429,16 +462,25 @@ PlayerWidget.prototype = {
yield this.player.setCurrentTime(time);
}),
/**
* Set the playback rate of the animation.
* @param {Number} rate.
* @return {Promise} Resolves when the rate has been set.
*/
setPlaybackRate: function(rate) {
if (!AnimationsController.hasSetPlaybackRate) {
throw new Error("This server version doesn't support setting animations' playbackRate");
}
return this.player.setPlaybackRate(rate);
},
/**
* Pause the animation player via this widget.
* @return {Promise} Resolves when the player is paused, the button is
* switched to the right state, and the timeline animation is stopped.
*/
pause: function() {
if (this.player.state.playState === "finished") {
return;
}
// Switch to the right className on the element right away to avoid waiting
// for the next state update to change the playPause icon.
this.updateWidgetState({playState: "paused"});
@ -452,10 +494,6 @@ PlayerWidget.prototype = {
* switched to the right state, and the timeline animation is started.
*/
play: function() {
if (this.player.state.playState === "finished") {
return;
}
// Switch to the right className on the element right away to avoid waiting
// for the next state update to change the playPause icon.
this.updateWidgetState({playState: "running"});
@ -479,7 +517,8 @@ PlayerWidget.prototype = {
let start = performance.now();
let loop = () => {
this.rafID = requestAnimationFrame(loop);
let now = state.currentTime + performance.now() - start;
let delta = (performance.now() - start) * state.playbackRate;
let now = state.currentTime + delta;
this.displayTime(now);
};
@ -540,7 +579,7 @@ function PlayerMetaDataHeader() {
}
PlayerMetaDataHeader.prototype = {
createMarkup: function(containerEl) {
init: function(containerEl) {
// The main title element.
this.el = createNode({
parent: containerEl,
@ -683,6 +722,87 @@ PlayerMetaDataHeader.prototype = {
}
};
/**
* UI component responsible for displaying the playback rate drop-down in each
* player widget, updating it when the state changes, and emitting events when
* the user selects a new value.
* The parent UI component for this should drive its updates by calling
* render(state) whenever it wants the component to update.
*/
function PlaybackRateSelector() {
this.currentRate = null;
this.onSelectionChanged = this.onSelectionChanged.bind(this);
EventEmitter.decorate(this);
}
PlaybackRateSelector.prototype = {
PRESETS: [.1, .5, 1, 2, 5, 10],
init: function(containerEl) {
// This component is simple enough that we can re-create the markup every
// time it's rendered. So here we only store the parentEl.
this.parentEl = containerEl;
},
destroy: function() {
this.removeSelect();
this.parentEl = this.el = null;
},
removeSelect: function() {
if (this.el) {
this.el.removeEventListener("change", this.onSelectionChanged);
this.el.remove();
}
},
/**
* Get the ordered list of presets, including the current playbackRate if
* different from the existing presets.
*/
getCurrentPresets: function({playbackRate}) {
return [...new Set([...this.PRESETS, playbackRate])].sort((a,b) => a > b);
},
render: function(state) {
if (state.playbackRate === this.currentRate) {
return;
}
this.removeSelect();
this.el = createNode({
parent: this.parentEl,
nodeType: "select",
attributes: {
"class": "rate devtools-button"
}
});
for (let preset of this.getCurrentPresets(state)) {
let option = createNode({
parent: this.el,
nodeType: "option",
attributes: {
value: preset,
}
});
option.textContent = L10N.getFormatStr("player.playbackRateLabel", preset);
if (preset === state.playbackRate) {
option.setAttribute("selected", "");
}
}
this.el.addEventListener("change", this.onSelectionChanged);
this.currentRate = state.playbackRate;
},
onSelectionChanged: function(e) {
this.emit("rate-changed", parseFloat(this.el.value));
}
};
/**
* DOM node creation helper function.
* @param {Object} Options to customize the node to be created.

Просмотреть файл

@ -18,9 +18,13 @@ support-files =
[browser_animation_playerWidgets_have_control_buttons.js]
[browser_animation_playerWidgets_meta_data.js]
[browser_animation_playerWidgets_state_after_pause.js]
[browser_animation_rate_select_shows_presets.js]
[browser_animation_refresh_on_added_animation.js]
[browser_animation_refresh_on_removed_animation.js]
[browser_animation_refresh_when_active.js]
[browser_animation_same_nb_of_playerWidgets_and_playerFronts.js]
[browser_animation_setting_currentTime_works_and_pauses.js]
[browser_animation_setting_playbackRate_works.js]
[browser_animation_shows_player_on_valid_node.js]
[browser_animation_timeline_animates.js]
[browser_animation_timeline_is_enabled.js]
@ -31,4 +35,5 @@ support-files =
[browser_animation_toolbar_exists.js]
[browser_animation_ui_updates_when_animation_changes.js]
[browser_animation_ui_updates_when_animation_data_changes.js]
[browser_animation_ui_updates_when_animation_rate_changes.js]
[browser_animation_ui_updates_when_animation_time_changes.js]

Просмотреть файл

@ -25,15 +25,7 @@ add_task(function*() {
info("Wait for both animations to end");
let promises = controller.animationPlayers.map(front => {
let def = promise.defer();
let onStateChanged = () => {
if (front.state.playState === "finished") {
front.off(front.AUTO_REFRESH_EVENT, onStateChanged);
def.resolve();
}
};
front.on(front.AUTO_REFRESH_EVENT, onStateChanged);
return def.promise;
return waitForPlayState(front, "finished");
});
yield promise.all(promises);

Просмотреть файл

@ -28,15 +28,7 @@ add_task(function*() {
let widget = panel.playerWidgets[0];
let front = widget.player;
let def = promise.defer();
let onStateChanged = () => {
if (front.state.playState === "finished") {
front.off(front.AUTO_REFRESH_EVENT, onStateChanged);
def.resolve();
}
};
front.on(front.AUTO_REFRESH_EVENT, onStateChanged);
yield def.promise;
yield waitForPlayState(front, "finished");
is(widget.currentTimeEl.value, front.state.duration,
"The timeline slider has the right value");

Просмотреть файл

@ -25,6 +25,8 @@ add_task(function*() {
"The second button is the rewind button");
ok(container.children[2].classList.contains("ff"),
"The third button is the fast-forward button");
ok(container.querySelector("select"),
"The container contains the playback rate select");
info("Faking an older server version by setting " +
"AnimationsController.hasSetCurrentTime to false");
@ -46,4 +48,23 @@ add_task(function*() {
yield selectNode("body", inspector);
controller.hasSetCurrentTime = true;
info("Faking an older server version by setting " +
"AnimationsController.hasSetPlaybackRate to false");
yield selectNode("body", inspector);
controller.hasSetPlaybackRate = false;
info("Selecting the animated node again");
yield selectNode(".animated", inspector);
widget = panel.playerWidgets[0];
container = widget.el.querySelector(".playback-controls");
ok(container, "The control buttons container still exists");
ok(!container.querySelector("select"),
"The playback rate select does not exist");
yield selectNode("body", inspector);
controller.hasSetPlaybackRate = true;
});

Просмотреть файл

@ -0,0 +1,49 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that the playbackRate select element contains a list of presets and
// and that if the animation has a current rate that is not part of this list,
// it is added.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector();
info("Selecting the test node");
yield selectNode(".animated", inspector);
info("Get the playback rate UI component");
let widget = panel.playerWidgets[0];
let rateComponent = widget.rateComponent;
let options = rateComponent.el.querySelectorAll("option");
is(options.length, rateComponent.PRESETS.length,
"The playback rate select contains the right number of options");
for (let i = 0; i < rateComponent.PRESETS.length; i ++) {
is(options[i].value, rateComponent.PRESETS[i] + "",
"The playback rate option " + i + " has the right preset value " +
rateComponent.PRESETS[i]);
}
info("Set a custom rate (not part of the presets) via the DOM");
let onRateChanged = waitForStateCondition(widget.player, state => {
return state.playbackRate === 3.6
});
yield executeInContent("Test:SetAnimationPlayerPlaybackRate", {
selector: ".animated",
animationIndex: 0,
playbackRate: 3.6
});
yield onRateChanged;
options = rateComponent.el.querySelectorAll("option");
is(options.length, rateComponent.PRESETS.length + 1,
"The playback rate select contains the right number of options (presets + 1)");
ok([...options].find(option => option.value === "3.6"),
"The custom rate is part of the select");
});

Просмотреть файл

@ -0,0 +1,34 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that the panel content refreshes when new animations are added.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {toolbox, inspector, panel} = yield openAnimationInspector();
info("Select a non animated node");
yield selectNode(".still", inspector);
is(panel.playersEl.querySelectorAll(".player-widget").length, 0,
"There are no player widgets in the panel");
info("Listen to the next UI update event");
let onPanelUpdated = panel.once(panel.UI_UPDATED_EVENT);
info("Start an animation on the node");
yield executeInContent("devtools:test:setAttribute", {
selector: ".still",
attributeName: "class",
attributeValue: "ball animated"
});
yield onPanelUpdated;
ok(true, "The panel update event was fired");
is(panel.playersEl.querySelectorAll(".player-widget").length, 1,
"There is one player widget in the panel");
});

Просмотреть файл

@ -0,0 +1,62 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that the panel content refreshes when animations are removed.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {toolbox, inspector, panel} = yield openAnimationInspector();
info("Select a animated node");
yield selectNode(".animated", inspector);
is(panel.playersEl.querySelectorAll(".player-widget").length, 1,
"There is one player widget in the panel");
info("Listen to the next UI update event");
let onPanelUpdated = panel.once(panel.UI_UPDATED_EVENT);
info("Remove the animation on the node by removing the class");
yield executeInContent("devtools:test:setAttribute", {
selector: ".animated",
attributeName: "class",
attributeValue: "ball still test-node"
});
yield onPanelUpdated;
ok(true, "The panel update event was fired");
is(panel.playersEl.querySelectorAll(".player-widget").length, 0,
"There are no player widgets in the panel anymore");
info("Add an finite animation on the node again, and wait for it to appear");
onPanelUpdated = panel.once(panel.UI_UPDATED_EVENT);
yield executeInContent("devtools:test:setAttribute", {
selector: ".test-node",
attributeName: "class",
attributeValue: "ball short"
});
yield onPanelUpdated;
is(panel.playersEl.querySelectorAll(".player-widget").length, 1,
"There is one player widget in the panel again");
info("Now wait until the animation finishes");
let widget = panel.playerWidgets[0];
yield waitForPlayState(widget.player, "finished")
is(panel.playersEl.querySelectorAll(".player-widget").length, 1,
"There is still a player widget in the panel after the animation finished");
info("Checking that the animation's currentTime can still be set");
info("Click at the center of the slider input");
let onPaused = waitForPlayState(widget.player, "paused");
let input = widget.currentTimeEl;
let win = input.ownerDocument.defaultView;
EventUtils.synthesizeMouseAtCenter(input, {type: "mousedown"}, win);
yield onPaused;
ok(widget.el.classList.contains("paused"), "The widget is in paused mode");
});

Просмотреть файл

@ -41,23 +41,3 @@ add_task(function*() {
yield checkPausedAt(widget, 2000);
});
function* checkPausedAt(widget, time) {
info("Wait for the next auto-update");
let onPaused = promise.defer();
widget.player.on(widget.player.AUTO_REFRESH_EVENT, function onRefresh() {
info("Still waiting for the player to pause");
if (widget.player.state.playState === "paused") {
ok(true, "The player's playState is paused");
widget.player.off(widget.player.AUTO_REFRESH_EVENT, onRefresh);
onPaused.resolve();
}
});
yield onPaused.promise;
ok(widget.el.classList.contains("paused"), "The widget is in paused mode");
is(widget.player.state.currentTime, time,
"The player front's currentTime was set to " + time);
is(widget.currentTimeEl.value, time, "The input's value was set to " + time);
}

Просмотреть файл

@ -0,0 +1,34 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that setting an animation's playback rate by selecting a rate in the
// presets drop-down sets the rate accordingly.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {toolbox, inspector, panel} = yield openAnimationInspector();
info("Select an animated node");
yield selectNode(".animated", inspector);
info("Get the player widget for this node");
let widget = panel.playerWidgets[0];
let select = widget.rateComponent.el;
let win = select.ownerDocument.defaultView;
info("Click on the rate drop-down");
EventUtils.synthesizeMouseAtCenter(select, {type: "mousedown"}, win);
info("Click on a rate option");
let option = select.options[select.options.length - 1];
EventUtils.synthesizeMouseAtCenter(option, {type: "mouseup"}, win);
let selectedRate = parseFloat(option.value);
info("Check that the rate was changed on the player at the next update");
yield waitForStateCondition(widget.player, ({playbackRate}) => playbackRate === selectedRate);
is(widget.player.state.playbackRate, selectedRate,
"The rate was changed successfully");
});

Просмотреть файл

@ -14,22 +14,25 @@ add_task(function*() {
info("Select an animated node");
yield selectNode(".animated", inspector);
let widget = panel.playerWidgets[0];
let player = widget.player;
info("Click the toggle button to pause all animations");
let onRefresh = onceNextPlayerRefresh(widget.player);
info("Listen to animation state changes and click the toggle button to " +
"pause all animations");
let onPaused = waitForPlayState(player, "paused");
yield panel.toggleAll();
yield onRefresh;
yield onPaused;
info("Checking the selected node's animation player widget's state");
is(widget.player.state.playState, "paused", "The player front's state is paused");
is(player.state.playState, "paused", "The player front's state is paused");
ok(widget.el.classList.contains("paused"), "The widget's UI is in paused state");
info("Click the toggle button to play all animations");
onRefresh = onceNextPlayerRefresh(widget.player);
info("Listen to animation state changes and click the toggle button to " +
"play all animations");
let onRunning = waitForPlayState(player, "running");
yield panel.toggleAll();
yield onRefresh;
yield onRunning;
info("Checking the selected node's animation player widget's state again");
is(widget.player.state.playState, "running", "The player front's state is running");
is(player.state.playState, "running", "The player front's state is running");
ok(widget.el.classList.contains("running"), "The widget's UI is in running state");
});

Просмотреть файл

@ -16,6 +16,10 @@ add_task(function*() {
info("Get the player widget");
let widget = panel.playerWidgets[0];
let player = widget.player;
info("Wait for paused playState");
let onPaused = waitForPlayState(player, "paused");
info("Pause the animation via the content DOM");
yield executeInContent("Test:ToggleAnimationPlayer", {
@ -24,13 +28,15 @@ add_task(function*() {
pause: true
});
info("Wait for the next state update");
yield onceNextPlayerRefresh(widget.player);
yield onPaused;
is(widget.player.state.playState, "paused", "The AnimationPlayerFront is paused");
is(player.state.playState, "paused", "The AnimationPlayerFront is paused");
ok(widget.el.classList.contains("paused"), "The button's state has changed");
ok(!widget.rafID, "The smooth timeline animation has been stopped");
info("Wait for running playState");
let onRunning = waitForPlayState(player, "running");
info("Play the animation via the content DOM");
yield executeInContent("Test:ToggleAnimationPlayer", {
selector: ".animated",
@ -38,10 +44,9 @@ add_task(function*() {
pause: false
});
info("Wait for the next state update");
yield onceNextPlayerRefresh(widget.player);
yield onRunning;
is(widget.player.state.playState, "running", "The AnimationPlayerFront is running");
is(player.state.playState, "running", "The AnimationPlayerFront is running");
ok(widget.el.classList.contains("running"), "The button's state has changed");
ok(widget.rafID, "The smooth timeline animation has been started");
});

Просмотреть файл

@ -0,0 +1,47 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that setting an animation's playbackRate via the WebAnimations API (from
// content), actually changes the rate in the corresponding widget too.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector();
info("Selecting the test node");
yield selectNode(".animated", inspector);
info("Get the player widget");
let widget = panel.playerWidgets[0];
info("Change the animation's playbackRate via the content DOM");
let onRateChanged = waitForStateCondition(widget.player, state => {
return state.playbackRate === 2;
}, "playbackRate === 2");
yield executeInContent("Test:SetAnimationPlayerPlaybackRate", {
selector: ".animated",
animationIndex: 0,
playbackRate: 2
});
yield onRateChanged;
is(widget.rateComponent.el.value, "2",
"The playbackRate select value was changed");
info("Change the animation's playbackRate again via the content DOM");
onRateChanged = waitForStateCondition(widget.player, state => {
return state.playbackRate === 0.3;
}, "playbackRate === 0.3");
yield executeInContent("Test:SetAnimationPlayerPlaybackRate", {
selector: ".animated",
animationIndex: 0,
playbackRate: 0.3
});
yield onRateChanged;
is(widget.rateComponent.el.value, "0.3",
"The playbackRate select value was changed again");
});

Просмотреть файл

@ -52,6 +52,27 @@ addMessageListener("Test:SetAnimationPlayerCurrentTime", function(msg) {
sendAsyncMessage("Test:SetAnimationPlayerCurrentTime");
});
/**
* Change the playbackRate of one of the animation players of a given node.
* @param {Object} data
* - {String} selector The CSS selector to get the node (can be a "super"
* selector).
* - {Number} animationIndex The index of the node's animationPlayers to change.
* - {Number} playbackRate The rate to set.
*/
addMessageListener("Test:SetAnimationPlayerPlaybackRate", function(msg) {
let {selector, animationIndex, playbackRate} = msg.data;
let node = superQuerySelector(selector);
if (!node) {
return;
}
let player = node.getAnimations()[animationIndex];
player.playbackRate = playbackRate;
sendAsyncMessage("Test:SetAnimationPlayerPlaybackRate");
});
/**
* Get the current playState of an animation player on a given node.
* @param {Object} data

Просмотреть файл

@ -284,10 +284,8 @@ let togglePlayPauseButton = Task.async(function*(widget) {
yield onClicked;
// Wait for the next sate change event to make sure the state is updated
yield waitForStateCondition(widget.player, state => {
return state.playState === nextState;
}, "after clicking the toggle button");
// Wait until the state changes.
yield waitForPlayState(widget.player, nextState);
});
/**
@ -317,6 +315,37 @@ let waitForStateCondition = Task.async(function*(player, conditionCheck, desc=""
return def.promise;
});
/**
* Wait for a player's auto-refresh events and stop when the playState is the
* provided string.
* @param {AnimationPlayerFront} player
* @param {String} playState The playState to expect.
* @return {Promise} Resolves when the playState has changed to the expected value.
*/
function waitForPlayState(player, playState) {
return waitForStateCondition(player, state => {
return state.playState === playState;
}, "Waiting for animation to be " + playState);
}
/**
* Wait for the player's auto-refresh events until the animation is paused.
* When done, check its currentTime.
* @param {PlayerWidget} widget.
* @param {Numer} time.
* @return {Promise} Resolves when the animation is paused and tests have ran.
*/
let checkPausedAt = Task.async(function*(widget, time) {
info("Wait for the next auto-refresh");
yield waitForPlayState(widget.player, "paused");
ok(widget.el.classList.contains("paused"), "The widget is in paused mode");
is(widget.player.state.currentTime, time,
"The player front's currentTime was set to " + time);
is(widget.currentTimeEl.value, time, "The input's value was set to " + time);
});
/**
* Get the current playState of an animation player on a given node.
*/

Просмотреть файл

@ -83,7 +83,7 @@ function testSetBreakpointBlankLine() {
ok(!aResponse.error,
"Should be able to set a breakpoint in a coffee source file on a blank line.");
ok(aResponse.actualLocation,
"Because 3 is empty, we should have an actualLocation.");
"Because 7 is empty, we should have an actualLocation.");
is(aResponse.actualLocation.source.url, COFFEE_URL,
"actualLocation.actor should be source mapped to the coffee file.");
is(aResponse.actualLocation.line, 8,

Просмотреть файл

@ -8,5 +8,5 @@ support-files =
templates.json
[browser_tabs.js]
skip-if = os == 'win' || e10s # Bug 1149289 - Intermittent on Windows, Bug 1072167 - browser_tabs.js test fails under e10s
skip-if = e10s # Bug 1072167 - browser_tabs.js test fails under e10s
[browser_widget.js]

Просмотреть файл

@ -28,6 +28,9 @@ function test() {
yield selectTabProject(win);
ok(win.UI.toolboxPromise, "Toolbox promise exists");
yield win.UI.toolboxPromise;
let project = win.AppManager.selectedProject;
is(project.location, TEST_URI, "Location is correct");
is(project.name, "example.com: Test Tab", "Name is correct");
@ -61,6 +64,8 @@ function selectTabProject(win) {
yield waitForUpdate(win, "runtime-targets");
let tabsNode = win.document.querySelector("#project-panel-tabs");
let tabNode = tabsNode.querySelectorAll(".panel-item")[1];
let project = waitForUpdate(win, "project");
tabNode.click();
yield project;
});
}

Просмотреть файл

@ -6,6 +6,8 @@ const Ci = Components.interfaces;
const Cc = Components.classes;
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Deprecated",
"resource://gre/modules/Deprecated.jsm");
const APPLICATION_CID = Components.ID("fe74cf80-aa2d-11db-abbd-0800200c9a66");
const APPLICATION_CONTRACTID = "@mozilla.org/fuel/application;1";
@ -734,6 +736,9 @@ var ApplicationFactory = {
//=================================================
// Application constructor
function Application() {
Deprecated.warning("FUEL is deprecated, you should use the add-on SDK instead.",
"https://developer.mozilla.org/Add-ons/SDK/");
this.initToolkitHelpers();
}

Просмотреть файл

@ -46,3 +46,9 @@ player.infiniteIterationCount=&#8734;
# how long (in seconds) the animation lasts, or what is the animation's current
# time (in seconds too);
player.timeLabel=%Ss
# LOCALIZATION NOTE (player.playbackRateLabel):
# This string is displayed in each animation player widget, as the label of
# drop-down list items that can be used to change the rate at which the
# animation runs (1x being the default, 2x being twice as fast).
player.playbackRateLabel=%Sx

Просмотреть файл

@ -1132,26 +1132,7 @@ toolbarbutton[sdk-button="true"][cui-areatype="toolbar"] > .toolbarbutton-icon {
margin-top: 5px;
}
.popup-notification-icon {
width: 64px;
height: 64px;
-moz-margin-end: 10px;
}
.popup-notification-icon[popupid="geolocation"] {
list-style-image: url(chrome://browser/skin/Geolocation-64.png);
}
.popup-notification-icon[popupid="xpinstall-disabled"],
.popup-notification-icon[popupid="addon-progress"],
.popup-notification-icon[popupid="addon-install-blocked"],
.popup-notification-icon[popupid="addon-install-failed"],
.popup-notification-icon[popupid="addon-install-confirmation"],
.popup-notification-icon[popupid="addon-install-complete"] {
list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric.png);
width: 32px;
height: 32px;
}
%include ../shared/notification-icons.inc.css
.popup-notification-description[popupid="addon-progress"],
.popup-notification-description[popupid="addon-install-confirmation"] {
@ -1163,92 +1144,13 @@ toolbarbutton[sdk-button="true"][cui-areatype="toolbar"] > .toolbarbutton-icon {
font-weight: bold;
}
.popup-notification-icon[popupid="click-to-play-plugins"] {
list-style-image: url(chrome://mozapps/skin/plugins/pluginBlocked-64.png);
}
.popup-notification-icon[popupid="web-notifications"] {
list-style-image: url(chrome://browser/skin/notification-64.png);
}
.popup-notification-icon[popupid="indexedDB-permissions-prompt"],
.popup-notification-icon[popupid*="offline-app-requested"],
.popup-notification-icon[popupid="offline-app-usage"] {
list-style-image: url(chrome://global/skin/icons/question-64.png);
}
.popup-notification-icon[popupid="password"] {
list-style-image: url(chrome://mozapps/skin/passwordmgr/key-64.png);
}
.popup-notification-icon[popupid="webapps-install-progress"],
.popup-notification-icon[popupid="webapps-install"] {
list-style-image: url(chrome://global/skin/icons/webapps-64.png);
}
.popup-notification-icon[popupid="bad-content"] {
list-style-image: url(chrome://browser/skin/bad-content-blocked-64.png);
}
.popup-notification-icon[popupid="bad-content"][mixedblockdisabled],
.popup-notification-icon[popupid="bad-content"][trackingblockdisabled] {
list-style-image: url(chrome://browser/skin/bad-content-unblocked-64.png);
}
.popup-notification-icon[popupid="webRTC-sharingDevices"],
.popup-notification-icon[popupid="webRTC-shareDevices"] {
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-64.png);
}
.popup-notification-icon[popupid="webRTC-sharingMicrophone"],
.popup-notification-icon[popupid="webRTC-shareMicrophone"] {
list-style-image: url(chrome://browser/skin/webRTC-shareMicrophone-64.png);
}
.popup-notification-icon[popupid="webRTC-sharingScreen"],
.popup-notification-icon[popupid="webRTC-shareScreen"] {
list-style-image: url(chrome://browser/skin/webRTC-shareScreen-64.png);
}
.popup-notification-icon[popupid="pointerLock"] {
list-style-image: url(chrome://browser/skin/pointerLock-64.png);
}
/* Notification icon box */
#notification-popup-box {
position: relative;
background-color: #fff;
background-clip: padding-box;
padding-left: 3px;
border-radius: 2.5px 0 0 2.5px;
border-width: 0 8px 0 0;
border-style: solid;
border-image: url("chrome://browser/skin/urlbar-arrow.png") 0 8 0 0 fill;
-moz-margin-end: -8px;
margin-top: -1px;
margin-bottom: -1px;
}
@conditionalForwardWithUrlbar@ > #forward-button[disabled] + #urlbar > #notification-popup-box {
padding-left: 7px;
}
#notification-popup-box:not([hidden]) + #identity-box {
-moz-padding-start: 10px;
border-radius: 0;
}
#notification-popup-box:-moz-locale-dir(rtl),
.notification-anchor-icon:-moz-locale-dir(rtl) {
transform: scaleX(-1);
}
.notification-anchor-icon {
width: 16px;
height: 16px;
margin: 0 2px;
}
.notification-anchor-icon:-moz-focusring {
outline: 1px dotted -moz-DialogText;
}
@ -1258,123 +1160,11 @@ toolbarbutton[sdk-button="true"][cui-areatype="toolbar"] > .toolbarbutton-icon {
list-style-image: url(moz-icon://stock/gtk-dialog-info?size=16);
}
.identity-notification-icon,
#identity-notification-icon {
list-style-image: url(chrome://mozapps/skin/profile/profileicon.png);
}
.geo-notification-icon,
#geo-notification-icon {
list-style-image: url(chrome://browser/skin/Geolocation-16.png);
}
#addons-notification-icon {
list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric-16.png);
}
.indexedDB-notification-icon,
#indexedDB-notification-icon {
list-style-image: url(moz-icon://stock/gtk-dialog-question?size=16);
}
#password-notification-icon {
list-style-image: url(chrome://mozapps/skin/passwordmgr/key-16.png);
}
#webapps-notification-icon {
list-style-image: url(chrome://global/skin/icons/webapps-16.png);
}
#plugins-notification-icon {
list-style-image: url(chrome://browser/skin/notification-pluginNormal.png);
}
#plugins-notification-icon.plugin-hidden {
list-style-image: url(chrome://browser/skin/notification-pluginAlert.png);
}
#plugins-notification-icon.plugin-blocked {
list-style-image: url(chrome://browser/skin/notification-pluginBlocked.png);
}
#plugins-notification-icon {
-moz-image-region: rect(0, 16px, 16px, 0);
}
#plugins-notification-icon:hover {
-moz-image-region: rect(0, 32px, 16px, 16px);
}
#plugins-notification-icon:active {
-moz-image-region: rect(0, 48px, 16px, 32px);
}
#notification-popup-box[hidden] {
/* Override display:none to make the pluginBlockedNotification animation work
when showing the notification repeatedly. */
display: -moz-box;
visibility: collapse;
}
#plugins-notification-icon.plugin-blocked[showing] {
animation: pluginBlockedNotification 500ms ease 0s 5 alternate both;
}
@keyframes pluginBlockedNotification {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.bad-content-blocked-notification-icon,
#bad-content-blocked-notification-icon {
list-style-image: url(chrome://browser/skin/bad-content-blocked-16.png);
}
.bad-content-unblocked-notification-icon,
#bad-content-unblocked-notification-icon {
list-style-image: url(chrome://browser/skin/bad-content-unblocked-16.png);
}
.webRTC-shareDevices-notification-icon,
#webRTC-shareDevices-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16.png);
}
.webRTC-sharingDevices-notification-icon,
#webRTC-sharingDevices-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-sharingDevice-16.png);
}
.webRTC-shareMicrophone-notification-icon,
#webRTC-shareMicrophone-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareMicrophone-16.png);
}
.webRTC-sharingMicrophone-notification-icon,
#webRTC-sharingMicrophone-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-sharingMicrophone-16.png);
}
.webRTC-shareScreen-notification-icon,
#webRTC-shareScreen-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareScreen-16.png);
}
.webRTC-sharingScreen-notification-icon,
#webRTC-sharingScreen-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-sharingScreen-16.png);
}
.web-notifications-notification-icon,
#web-notifications-notification-icon {
list-style-image: url(chrome://browser/skin/notification-16.png);
}
#pointerLock-notification-icon {
list-style-image: url(chrome://browser/skin/pointerLock-16.png);
}
#pointerLock-cancel {
margin: 0px;
}
@ -1453,18 +1243,6 @@ notification[value="translation"] menulist > .menulist-dropmarker {
display: block;
}
.translate-notification-icon,
#translate-notification-icon {
list-style-image: url(chrome://browser/skin/translation-16.png);
-moz-image-region: rect(0px, 16px, 16px, 0px);
}
.translated-notification-icon,
#translated-notification-icon {
list-style-image: url(chrome://browser/skin/translation-16.png);
-moz-image-region: rect(0px, 32px, 16px, 16px);
}
/* Loop/ Hello browser styles */
notification[value="loop-sharing-notification"] .button-menubutton-button {
@ -2106,12 +1884,6 @@ toolbarbutton.chevron > .toolbarbutton-icon {
/* Social toolbar item */
.popup-notification-icon[popupid="servicesInstall"] {
list-style-image: url(chrome://browser/skin/social/services-64.png);
}
#servicesInstall-notification-icon {
list-style-image: url(chrome://browser/skin/social/services-16.png);
}
#social-undoactivation-button {
-moz-margin-start: 0; /* override default label margin to match description margin */
}
@ -2188,28 +1960,6 @@ chatbox {
border-top-right-radius: 2.5px;
}
/* EME notifications */
.popup-notification-icon[popupid="drmContentPlaying"],
#eme-notification-icon {
list-style-image: url("chrome://browser/skin/drm-icon.svg#chains");
}
#eme-notification-icon:hover:active {
list-style-image: url("chrome://browser/skin/drm-icon.svg#chains-pressed");
}
#eme-notification-icon[firstplay=true] {
animation: emeTeachingMoment 0.2s linear 0s 5 normal;
}
@keyframes emeTeachingMoment {
0% {transform: translateX(0); }
25% {transform: translateX(3px) }
75% {transform: translateX(-3px) }
100% { transform: translateX(0); }
}
/* Customization mode */
%include ../shared/customizableui/customizeMode.inc.css

Просмотреть файл

@ -86,6 +86,7 @@ browser.jar:
skin/classic/browser/Toolbar-inverted.png
skin/classic/browser/Toolbar-small.png
skin/classic/browser/undoCloseTab.png (../shared/undoCloseTab.png)
skin/classic/browser/update-badge.svg (../shared/update-badge.svg)
skin/classic/browser/urlbar-arrow.png
skin/classic/browser/session-restore.svg (../shared/incontent-icons/session-restore.svg)
skin/classic/browser/tab-crashed.svg (../shared/incontent-icons/tab-crashed.svg)

Просмотреть файл

@ -3657,37 +3657,10 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
margin-top: 5px;
}
%include ../shared/notification-icons.inc.css
#notification-popup-box {
position: relative;
background-color: #fff;
background-clip: padding-box;
padding-left: 3px;
border-radius: 2px 0 0 2px;
border-width: 0 8px 0 0;
border-style: solid;
border-image: url("chrome://browser/skin/urlbar-arrow.png") 0 8 0 0 fill;
-moz-margin-end: -8px;
}
@media (min-resolution: 2dppx) {
#notification-popup-box {
border-image: url("chrome://browser/skin/urlbar-arrow@2x.png") 0 16 0 0 fill;
}
}
@conditionalForwardWithUrlbar@ > #forward-button[disabled] + #urlbar > #notification-popup-box {
padding-left: 7px;
}
#notification-popup-box:-moz-locale-dir(rtl),
.notification-anchor-icon:-moz-locale-dir(rtl) {
transform: scaleX(-1);
}
.notification-anchor-icon {
width: 16px;
height: 16px;
margin: 0 2px;
}
.notification-anchor-icon:-moz-focusring {
@ -3699,278 +3672,8 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
height: 16px;
}
.default-notification-icon,
#default-notification-icon {
list-style-image: url(chrome://global/skin/icons/information-16.png);
}
@media (min-resolution: 2dppx) {
.default-notification-icon,
#default-notification-icon {
list-style-image: url(chrome://global/skin/icons/information-32.png);
}
}
.identity-notification-icon,
#identity-notification-icon {
list-style-image: url(chrome://mozapps/skin/profile/profileicon.png);
}
/* XXX: need HiDPI version */
.geo-notification-icon,
#geo-notification-icon {
list-style-image: url(chrome://browser/skin/Geolocation-16.png);
}
@media (min-resolution: 2dppx) {
.geo-notification-icon,
#geo-notification-icon {
list-style-image: url(chrome://browser/skin/Geolocation-16@2x.png);
}
}
.indexedDB-notification-icon,
#indexedDB-notification-icon {
list-style-image: url(chrome://global/skin/icons/question-16.png);
}
@media (min-resolution: 2dppx) {
.indexedDB-notification-icon,
#indexedDB-notification-icon {
list-style-image: url(chrome://global/skin/icons/question-32.png);
}
}
#addons-notification-icon {
list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric-16.png);
}
@media (min-resolution: 2dppx) {
#addons-notification-icon {
list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric.png);
}
}
#password-notification-icon {
list-style-image: url(chrome://mozapps/skin/passwordmgr/key-16.png);
}
@media (min-resolution: 2dppx) {
#password-notification-icon {
list-style-image: url(chrome://mozapps/skin/passwordmgr/key-16@2x.png);
}
}
.webapps-notification-icon,
#webapps-notification-icon {
list-style-image: url(chrome://global/skin/icons/webapps-16.png);
}
@media (min-resolution: 2dppx) {
.webapps-notification-icon,
#webapps-notification-icon {
list-style-image: url(chrome://global/skin/icons/webapps-16@2x.png);
}
}
#plugins-notification-icon {
list-style-image: url(chrome://browser/skin/notification-pluginNormal.png);
}
#plugins-notification-icon.plugin-hidden {
list-style-image: url(chrome://browser/skin/notification-pluginAlert.png);
}
#plugins-notification-icon.plugin-blocked {
list-style-image: url(chrome://browser/skin/notification-pluginBlocked.png);
}
#plugins-notification-icon {
-moz-image-region: rect(0, 16px, 16px, 0);
}
#plugins-notification-icon:hover {
-moz-image-region: rect(0, 32px, 16px, 16px);
}
#plugins-notification-icon:active {
-moz-image-region: rect(0, 48px, 16px, 32px);
}
@media (min-resolution: 2dppx) {
#plugins-notification-icon {
list-style-image: url(chrome://browser/skin/notification-pluginNormal@2x.png);
}
#plugins-notification-icon.plugin-hidden {
list-style-image: url(chrome://browser/skin/notification-pluginAlert@2x.png);
}
#plugins-notification-icon.plugin-blocked {
list-style-image: url(chrome://browser/skin/notification-pluginBlocked@2x.png);
}
#plugins-notification-icon {
-moz-image-region: rect(0, 32px, 32px, 0);
}
#plugins-notification-icon:hover {
-moz-image-region: rect(0, 64px, 32px, 32px);
}
#plugins-notification-icon:active {
-moz-image-region: rect(0, 96px, 32px, 64px);
}
}
#notification-popup-box[hidden] {
/* Override display:none to make the pluginBlockedNotification animation work
when showing the notification repeatedly. */
display: -moz-box;
visibility: collapse;
}
#plugins-notification-icon.plugin-blocked[showing] {
animation: pluginBlockedNotification 500ms ease 0s 5 alternate both;
}
@keyframes pluginBlockedNotification {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
#bad-content-blocked-notification-icon {
list-style-image: url(chrome://browser/skin/bad-content-blocked-16.png);
}
@media (min-resolution: 2dppx) {
#bad-content-blocked-notification-icon {
list-style-image: url(chrome://browser/skin/bad-content-blocked-16@2x.png);
}
}
#bad-content-unblocked-notification-icon {
list-style-image: url(chrome://browser/skin/bad-content-unblocked-16.png);
}
@media (min-resolution: 2dppx) {
#bad-content-unblocked-notification-icon {
list-style-image: url(chrome://browser/skin/bad-content-unblocked-16@2x.png);
}
}
.webRTC-shareDevices-notification-icon,
#webRTC-shareDevices-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16.png);
}
@media (min-resolution: 2dppx) {
.webRTC-shareDevices-notification-icon,
#webRTC-shareDevices-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16@2x.png);
}
}
.webRTC-sharingDevices-notification-icon,
#webRTC-sharingDevices-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-sharingDevice-16.png);
}
@media (min-resolution: 2dppx) {
.webRTC-sharingDevices-notification-icon,
#webRTC-sharingDevices-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-sharingDevice-16@2x.png);
}
}
.webRTC-shareMicrophone-notification-icon,
#webRTC-shareMicrophone-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareMicrophone-16.png);
}
@media (min-resolution: 2dppx) {
.webRTC-shareMicrophone-notification-icon,
#webRTC-shareMicrophone-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareMicrophone-16@2x.png);
}
}
.webRTC-sharingMicrophone-notification-icon,
#webRTC-sharingMicrophone-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-sharingMicrophone-16.png);
}
@media (min-resolution: 2dppx) {
.webRTC-sharingMicrophone-notification-icon,
#webRTC-sharingMicrophone-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-sharingMicrophone-16@2x.png);
}
}
.webRTC-shareScreen-notification-icon,
#webRTC-shareScreen-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareScreen-16.png);
}
@media (min-resolution: 2dppx) {
.webRTC-shareScreen-notification-icon,
#webRTC-shareScreen-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareScreen-16@2x.png);
}
}
.webRTC-sharingScreen-notification-icon,
#webRTC-sharingScreen-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-sharingScreen-16.png);
}
@media (min-resolution: 2dppx) {
.webRTC-sharingScreen-notification-icon,
#webRTC-sharingScreen-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-sharingScreen-16@2x.png);
}
}
.web-notifications-notification-icon,
#web-notifications-notification-icon {
list-style-image: url(chrome://browser/skin/notification-16.png);
}
@media (min-resolution: 2dppx) {
.web-notifications-notification-icon,
#web-notifications-notification-icon {
list-style-image: url(chrome://browser/skin/notification-16@2x.png);
}
}
.pointerLock-notification-icon,
#pointerLock-notification-icon {
list-style-image: url(chrome://browser/skin/pointerLock-16.png);
}
@media (min-resolution: 2dppx) {
.pointerLock-notification-icon,
#pointerLock-notification-icon {
list-style-image: url(chrome://browser/skin/pointerLock-16@2x.png);
}
}
/* Translation */
.translate-notification-icon,
#translate-notification-icon {
list-style-image: url(chrome://browser/skin/translation-16.png);
-moz-image-region: rect(0px, 16px, 16px, 0px);
}
@media (min-resolution: 2dppx) {
.translate-notification-icon,
#translate-notification-icon {
list-style-image: url(chrome://browser/skin/translation-16@2x.png);
-moz-image-region: rect(0px, 32px, 32px, 0px);
}
}
.translated-notification-icon,
#translated-notification-icon {
list-style-image: url(chrome://browser/skin/translation-16.png);
-moz-image-region: rect(0px, 32px, 16px, 16px);
}
@media (min-resolution: 2dppx) {
.translated-notification-icon,
#translated-notification-icon {
list-style-image: url(chrome://browser/skin/translation-16@2x.png);
-moz-image-region: rect(0px, 64px, 32px, 32px);
}
}
%include ../shared/translation/infobar.inc.css
notification[value="translation"] {
@ -4123,42 +3826,6 @@ notification[value="loop-sharing-notification"] .messageImage {
}
}
.popup-notification-icon {
width: 64px;
height: 64px;
-moz-margin-end: 10px;
}
.popup-notification-icon[popupid="geolocation"] {
list-style-image: url(chrome://browser/skin/Geolocation-64.png);
}
@media (min-resolution: 2dppx) {
.popup-notification-icon[popupid="geolocation"] {
list-style-image: url(chrome://browser/skin/Geolocation-64@2x.png);
}
}
.popup-notification-icon[popupid="web-notifications"] {
list-style-image: url(chrome://browser/skin/notification-64.png);
}
@media (min-resolution: 2dppx) {
.popup-notification-icon[popupid="web-notifications"] {
list-style-image: url(chrome://browser/skin/notification-64@2x.png);
}
}
.popup-notification-icon[popupid="xpinstall-disabled"],
.popup-notification-icon[popupid="addon-progress"],
.popup-notification-icon[popupid="addon-install-blocked"],
.popup-notification-icon[popupid="addon-install-failed"],
.popup-notification-icon[popupid="addon-install-confirmation"],
.popup-notification-icon[popupid="addon-install-complete"] {
list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric.png);
width: 32px;
height: 32px;
}
.popup-notification-description[popupid="addon-progress"],
.popup-notification-description[popupid="addon-install-confirmation"] {
width: 27em;
@ -4177,91 +3844,10 @@ notification[value="loop-sharing-notification"] .messageImage {
-moz-margin-start: 0 !important; /* override default label margin to match description margin */
}
.popup-notification-icon[popupid="click-to-play-plugins"] {
list-style-image: url(chrome://mozapps/skin/plugins/pluginBlocked-64.png);
}
.popup-notification-icon[popupid="indexedDB-permissions-prompt"],
.popup-notification-icon[popupid*="offline-app-requested"],
.popup-notification-icon[popupid="offline-app-usage"] {
list-style-image: url(chrome://global/skin/icons/question-64.png);
}
.popup-notification-icon[popupid="password"] {
list-style-image: url(chrome://mozapps/skin/passwordmgr/key-64.png);
}
.popup-notification-icon[popupid="webapps-install-progress"],
.popup-notification-icon[popupid="webapps-install"] {
list-style-image: url(chrome://global/skin/icons/webapps-64.png);
}
.popup-notification-icon[popupid="bad-content"] {
list-style-image: url(chrome://browser/skin/bad-content-blocked-64.png);
}
@media (min-resolution: 2dppx) {
.popup-notification-icon[popupid="bad-content"] {
list-style-image: url(chrome://browser/skin/bad-content-blocked-64@2x.png);
}
}
.popup-notification-icon[popupid="bad-content"][mixedblockdisabled],
.popup-notification-icon[popupid="bad-content"][trackingblockdisabled] {
list-style-image: url(chrome://browser/skin/bad-content-unblocked-64.png);
}
@media (min-resolution: 2dppx) {
.popup-notification-icon[popupid="bad-content"][mixedblockdisabled],
.popup-notification-icon[popupid="bad-content"][trackingblockdisabled] {
list-style-image: url(chrome://browser/skin/bad-content-unblocked-64@2x.png);
}
}
.popup-notification-icon[popupid="pointerLock"] {
list-style-image: url(chrome://browser/skin/pointerLock-64.png);
}
@media (min-resolution: 2dppx) {
.popup-notification-icon[popupid="pointerLock"] {
list-style-image: url(chrome://browser/skin/pointerLock-64@2x.png);
}
}
#pointerLock-cancel {
margin: 0px;
}
.popup-notification-icon[popupid="webRTC-sharingDevices"],
.popup-notification-icon[popupid="webRTC-shareDevices"] {
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-64.png);
}
@media (min-resolution: 2dppx) {
.popup-notification-icon[popupid="webRTC-sharingDevices"],
.popup-notification-icon[popupid="webRTC-shareDevices"] {
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-64@2x.png);
}
}
.popup-notification-icon[popupid="webRTC-sharingMicrophone"],
.popup-notification-icon[popupid="webRTC-shareMicrophone"] {
list-style-image: url(chrome://browser/skin/webRTC-shareMicrophone-64.png);
}
@media (min-resolution: 2dppx) {
.popup-notification-icon[popupid="webRTC-sharingMicrophone"],
.popup-notification-icon[popupid="webRTC-shareMicrophone"] {
list-style-image: url(chrome://browser/skin/webRTC-shareMicrophone-64@2x.png);
}
}
.popup-notification-icon[popupid="webRTC-sharingScreen"],
.popup-notification-icon[popupid="webRTC-shareScreen"] {
list-style-image: url(chrome://browser/skin/webRTC-shareScreen-64.png);
}
@media (min-resolution: 2dppx) {
.popup-notification-icon[popupid="webRTC-sharingScreen"],
.popup-notification-icon[popupid="webRTC-shareScreen"] {
list-style-image: url(chrome://browser/skin/webRTC-shareScreen-64@2x.png);
}
}
/* Popup Buttons */
#identity-popup-more-info-button {
@hudButton@
@ -4482,22 +4068,6 @@ notification[value="loop-sharing-notification"] .messageImage {
border-radius: 1px;
}
.popup-notification-icon[popupid="servicesInstall"] {
list-style-image: url(chrome://browser/skin/social/services-64.png);
}
#servicesInstall-notification-icon {
list-style-image: url(chrome://browser/skin/social/services-16.png);
}
@media (min-resolution: 2dppx) {
.popup-notification-icon[popupid="servicesInstall"] {
list-style-image: url(chrome://browser/skin/social/services-64@2x.png);
}
#servicesInstall-notification-icon {
list-style-image: url(chrome://browser/skin/social/services-16@2x.png);
}
}
#social-undoactivation-button {
-moz-margin-start: 0; /* override default label margin to match description margin */
}
@ -4619,28 +4189,6 @@ window > chatbox {
border-bottom-right-radius: @toolbarbuttonCornerRadius@;
}
/* EME notifications */
.popup-notification-icon[popupid="drmContentPlaying"],
#eme-notification-icon {
list-style-image: url("chrome://browser/skin/drm-icon.svg#chains");
}
#eme-notification-icon:hover:active {
list-style-image: url("chrome://browser/skin/drm-icon.svg#chains-pressed");
}
#eme-notification-icon[firstplay=true] {
animation: emeTeachingMoment 0.2s linear 0s 5 normal;
}
@keyframes emeTeachingMoment {
0% {transform: translateX(0); }
25% {transform: translateX(3px) }
75% {transform: translateX(-3px) }
100% { transform: translateX(0); }
}
/* Customization mode */
%include ../shared/customizableui/customizeMode.inc.css

Просмотреть файл

@ -131,6 +131,7 @@ browser.jar:
skin/classic/browser/toolbarbutton-dropmarker.png
skin/classic/browser/undoCloseTab.png (../shared/undoCloseTab.png)
skin/classic/browser/undoCloseTab@2x.png (../shared/undoCloseTab@2x.png)
skin/classic/browser/update-badge.svg (../shared/update-badge.svg)
skin/classic/browser/urlbar-history-dropmarker.png
skin/classic/browser/urlbar-history-dropmarker@2x.png
skin/classic/browser/urlbar-arrow.png

Просмотреть файл

@ -106,6 +106,12 @@
background-position: 100% 0, calc(100% - 1px) 0, calc(100% - 2px) 0;
}
#PanelUI-menu-button[update-status="succeeded"] .toolbarbutton-badge::after {
content: url(chrome://browser/skin/update-badge.svg);
background-color: #74BF43;
height: 10px;
}
.panel-subviews {
padding: 4px;
background-clip: padding-box;

Просмотреть файл

@ -28,7 +28,7 @@ body {
}
#toggle-all {
border-width: 0px 1px;
border-width: 0 0 0 1px;
min-height: 20px;
}
@ -99,13 +99,6 @@ body {
}
}
/* Disabled playerWidget when the animation has ended */
.finished {
pointer-events: none;
opacity: .5;
}
/* Animation title gutter, contains the name, duration, iteration */
.animation-title {
@ -182,6 +175,12 @@ body {
}
}
.timeline .rate {
-moz-appearance: none;
text-align: center;
border-right: 1px solid var(--theme-splitter-color);
}
/* Slider (input type range) container */
.timeline .sliders-container {

Просмотреть файл

@ -0,0 +1,439 @@
%if 0
/* 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/. */
%endif
.popup-notification-icon {
width: 64px;
height: 64px;
-moz-margin-end: 10px;
}
.popup-notification-icon[popupid="geolocation"] {
list-style-image: url(chrome://browser/skin/Geolocation-64.png);
}
.popup-notification-icon[popupid="xpinstall-disabled"],
.popup-notification-icon[popupid="addon-progress"],
.popup-notification-icon[popupid="addon-install-blocked"],
.popup-notification-icon[popupid="addon-install-failed"],
.popup-notification-icon[popupid="addon-install-confirmation"],
.popup-notification-icon[popupid="addon-install-complete"] {
list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric.png);
width: 32px;
height: 32px;
}
.popup-notification-icon[popupid="click-to-play-plugins"] {
list-style-image: url(chrome://mozapps/skin/plugins/pluginBlocked-64.png);
}
.popup-notification-icon[popupid="web-notifications"] {
list-style-image: url(chrome://browser/skin/notification-64.png);
}
.popup-notification-icon[popupid="indexedDB-permissions-prompt"],
.popup-notification-icon[popupid*="offline-app-requested"],
.popup-notification-icon[popupid="offline-app-usage"] {
list-style-image: url(chrome://global/skin/icons/question-64.png);
}
.popup-notification-icon[popupid="password"] {
list-style-image: url(chrome://mozapps/skin/passwordmgr/key-64.png);
}
.popup-notification-icon[popupid="webapps-install-progress"],
.popup-notification-icon[popupid="webapps-install"] {
list-style-image: url(chrome://global/skin/icons/webapps-64.png);
}
.popup-notification-icon[popupid="bad-content"] {
list-style-image: url(chrome://browser/skin/bad-content-blocked-64.png);
}
.popup-notification-icon[popupid="bad-content"][mixedblockdisabled],
.popup-notification-icon[popupid="bad-content"][trackingblockdisabled] {
list-style-image: url(chrome://browser/skin/bad-content-unblocked-64.png);
}
.popup-notification-icon[popupid="webRTC-sharingDevices"],
.popup-notification-icon[popupid="webRTC-shareDevices"] {
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-64.png);
}
.popup-notification-icon[popupid="webRTC-sharingMicrophone"],
.popup-notification-icon[popupid="webRTC-shareMicrophone"] {
list-style-image: url(chrome://browser/skin/webRTC-shareMicrophone-64.png);
}
.popup-notification-icon[popupid="webRTC-sharingScreen"],
.popup-notification-icon[popupid="webRTC-shareScreen"] {
list-style-image: url(chrome://browser/skin/webRTC-shareScreen-64.png);
}
.popup-notification-icon[popupid="pointerLock"] {
list-style-image: url(chrome://browser/skin/pointerLock-64.png);
}
/* Notification icon box */
#notification-popup-box {
position: relative;
background-color: #fff;
background-clip: padding-box;
padding-left: 3px;
border-width: 0 8px 0 0;
border-style: solid;
border-image: url("chrome://browser/skin/urlbar-arrow.png") 0 8 0 0 fill;
-moz-margin-end: -8px;
}
@conditionalForwardWithUrlbar@ > #forward-button[disabled] + #urlbar > #notification-popup-box {
padding-left: 7px;
}
#notification-popup-box:-moz-locale-dir(rtl),
.notification-anchor-icon:-moz-locale-dir(rtl) {
transform: scaleX(-1);
}
.notification-anchor-icon {
width: 16px;
height: 16px;
margin: 0 2px;
}
.default-notification-icon,
#default-notification-icon {
list-style-image: url(chrome://global/skin/icons/information-16.png);
}
.identity-notification-icon,
#identity-notification-icon {
list-style-image: url(chrome://mozapps/skin/profile/profileicon.png);
/* XXX: need HiDPI version */
}
.geo-notification-icon,
#geo-notification-icon {
list-style-image: url(chrome://browser/skin/Geolocation-16.png);
}
#addons-notification-icon {
list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric-16.png);
}
.indexedDB-notification-icon,
#indexedDB-notification-icon {
list-style-image: url(chrome://global/skin/icons/question-16.png);
}
#password-notification-icon {
list-style-image: url(chrome://mozapps/skin/passwordmgr/key-16.png);
}
.webapps-notification-icon,
#webapps-notification-icon {
list-style-image: url(chrome://global/skin/icons/webapps-16.png);
}
#plugins-notification-icon {
list-style-image: url(chrome://browser/skin/notification-pluginNormal.png);
}
#plugins-notification-icon.plugin-hidden {
list-style-image: url(chrome://browser/skin/notification-pluginAlert.png);
}
#plugins-notification-icon.plugin-blocked {
list-style-image: url(chrome://browser/skin/notification-pluginBlocked.png);
}
#plugins-notification-icon {
-moz-image-region: rect(0, 16px, 16px, 0);
}
#plugins-notification-icon:hover {
-moz-image-region: rect(0, 32px, 16px, 16px);
}
#plugins-notification-icon:active {
-moz-image-region: rect(0, 48px, 16px, 32px);
}
#notification-popup-box[hidden] {
/* Override display:none to make the pluginBlockedNotification animation work
when showing the notification repeatedly. */
display: -moz-box;
visibility: collapse;
}
#plugins-notification-icon.plugin-blocked[showing] {
animation: pluginBlockedNotification 500ms ease 0s 5 alternate both;
}
@keyframes pluginBlockedNotification {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.bad-content-blocked-notification-icon,
#bad-content-blocked-notification-icon {
list-style-image: url(chrome://browser/skin/bad-content-blocked-16.png);
}
.bad-content-unblocked-notification-icon,
#bad-content-unblocked-notification-icon {
list-style-image: url(chrome://browser/skin/bad-content-unblocked-16.png);
}
.webRTC-shareDevices-notification-icon,
#webRTC-shareDevices-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16.png);
}
.webRTC-sharingDevices-notification-icon,
#webRTC-sharingDevices-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-sharingDevice-16.png);
}
.webRTC-shareMicrophone-notification-icon,
#webRTC-shareMicrophone-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareMicrophone-16.png);
}
.webRTC-sharingMicrophone-notification-icon,
#webRTC-sharingMicrophone-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-sharingMicrophone-16.png);
}
.webRTC-shareScreen-notification-icon,
#webRTC-shareScreen-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareScreen-16.png);
}
.webRTC-sharingScreen-notification-icon,
#webRTC-sharingScreen-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-sharingScreen-16.png);
}
.web-notifications-notification-icon,
#web-notifications-notification-icon {
list-style-image: url(chrome://browser/skin/notification-16.png);
}
.pointerLock-notification-icon,
#pointerLock-notification-icon {
list-style-image: url(chrome://browser/skin/pointerLock-16.png);
}
.translate-notification-icon,
#translate-notification-icon {
list-style-image: url(chrome://browser/skin/translation-16.png);
-moz-image-region: rect(0px, 16px, 16px, 0px);
}
.translated-notification-icon,
#translated-notification-icon {
list-style-image: url(chrome://browser/skin/translation-16.png);
-moz-image-region: rect(0px, 32px, 16px, 16px);
}
.popup-notification-icon[popupid="servicesInstall"] {
list-style-image: url(chrome://browser/skin/social/services-64.png);
}
#servicesInstall-notification-icon {
list-style-image: url(chrome://browser/skin/social/services-16.png);
}
/* EME notifications */
.popup-notification-icon[popupid="drmContentPlaying"],
#eme-notification-icon {
list-style-image: url("chrome://browser/skin/drm-icon.svg#chains");
}
#eme-notification-icon:hover:active {
list-style-image: url("chrome://browser/skin/drm-icon.svg#chains-pressed");
}
#eme-notification-icon[firstplay=true] {
animation: emeTeachingMoment 0.2s linear 0s 5 normal;
}
@keyframes emeTeachingMoment {
0% {transform: translateX(0); }
25% {transform: translateX(3px) }
75% {transform: translateX(-3px) }
100% { transform: translateX(0); }
}
%ifdef XP_MACOSX
/* HiDPI notification icons */
@media (min-resolution: 2dppx) {
#notification-popup-box {
border-image: url("chrome://browser/skin/urlbar-arrow@2x.png") 0 16 0 0 fill;
}
.default-notification-icon,
#default-notification-icon {
list-style-image: url(chrome://global/skin/icons/information-32.png);
}
.geo-notification-icon,
#geo-notification-icon {
list-style-image: url(chrome://browser/skin/Geolocation-16@2x.png);
}
.indexedDB-notification-icon,
#indexedDB-notification-icon {
list-style-image: url(chrome://global/skin/icons/question-32.png);
}
#addons-notification-icon {
list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric.png);
}
#password-notification-icon {
list-style-image: url(chrome://mozapps/skin/passwordmgr/key-16@2x.png);
}
.webapps-notification-icon,
#webapps-notification-icon {
list-style-image: url(chrome://global/skin/icons/webapps-16@2x.png);
}
#plugins-notification-icon {
list-style-image: url(chrome://browser/skin/notification-pluginNormal@2x.png);
}
#plugins-notification-icon.plugin-hidden {
list-style-image: url(chrome://browser/skin/notification-pluginAlert@2x.png);
}
#plugins-notification-icon.plugin-blocked {
list-style-image: url(chrome://browser/skin/notification-pluginBlocked@2x.png);
}
#plugins-notification-icon {
-moz-image-region: rect(0, 32px, 32px, 0);
}
#plugins-notification-icon:hover {
-moz-image-region: rect(0, 64px, 32px, 32px);
}
#plugins-notification-icon:active {
-moz-image-region: rect(0, 96px, 32px, 64px);
}
#bad-content-blocked-notification-icon {
list-style-image: url(chrome://browser/skin/bad-content-blocked-16@2x.png);
}
#bad-content-unblocked-notification-icon {
list-style-image: url(chrome://browser/skin/bad-content-unblocked-16@2x.png);
}
.webRTC-shareDevices-notification-icon,
#webRTC-shareDevices-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16@2x.png);
}
.webRTC-sharingDevices-notification-icon,
#webRTC-sharingDevices-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-sharingDevice-16@2x.png);
}
.webRTC-shareMicrophone-notification-icon,
#webRTC-shareMicrophone-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareMicrophone-16@2x.png);
}
.webRTC-sharingMicrophone-notification-icon,
#webRTC-sharingMicrophone-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-sharingMicrophone-16@2x.png);
}
.webRTC-shareScreen-notification-icon,
#webRTC-shareScreen-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareScreen-16@2x.png);
}
.webRTC-sharingScreen-notification-icon,
#webRTC-sharingScreen-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-sharingScreen-16@2x.png);
}
.web-notifications-notification-icon,
#web-notifications-notification-icon {
list-style-image: url(chrome://browser/skin/notification-16@2x.png);
}
.pointerLock-notification-icon,
#pointerLock-notification-icon {
list-style-image: url(chrome://browser/skin/pointerLock-16@2x.png);
}
.translate-notification-icon,
#translate-notification-icon {
list-style-image: url(chrome://browser/skin/translation-16@2x.png);
-moz-image-region: rect(0px, 32px, 32px, 0px);
}
.translated-notification-icon,
#translated-notification-icon {
list-style-image: url(chrome://browser/skin/translation-16@2x.png);
-moz-image-region: rect(0px, 64px, 32px, 32px);
}
.popup-notification-icon[popupid="geolocation"] {
list-style-image: url(chrome://browser/skin/Geolocation-64@2x.png);
}
.popup-notification-icon[popupid="web-notifications"] {
list-style-image: url(chrome://browser/skin/notification-64@2x.png);
}
.popup-notification-icon[popupid="bad-content"] {
list-style-image: url(chrome://browser/skin/bad-content-blocked-64@2x.png);
}
.popup-notification-icon[popupid="bad-content"][mixedblockdisabled],
.popup-notification-icon[popupid="bad-content"][trackingblockdisabled] {
list-style-image: url(chrome://browser/skin/bad-content-unblocked-64@2x.png);
}
.popup-notification-icon[popupid="pointerLock"] {
list-style-image: url(chrome://browser/skin/pointerLock-64@2x.png);
}
.popup-notification-icon[popupid="webRTC-sharingDevices"],
.popup-notification-icon[popupid="webRTC-shareDevices"] {
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-64@2x.png);
}
.popup-notification-icon[popupid="webRTC-sharingMicrophone"],
.popup-notification-icon[popupid="webRTC-shareMicrophone"] {
list-style-image: url(chrome://browser/skin/webRTC-shareMicrophone-64@2x.png);
}
.popup-notification-icon[popupid="webRTC-sharingScreen"],
.popup-notification-icon[popupid="webRTC-shareScreen"] {
list-style-image: url(chrome://browser/skin/webRTC-shareScreen-64@2x.png);
}
.popup-notification-icon[popupid="servicesInstall"] {
list-style-image: url(chrome://browser/skin/social/services-64@2x.png);
}
#servicesInstall-notification-icon {
list-style-image: url(chrome://browser/skin/social/services-16@2x.png);
}
}
%endif

Просмотреть файл

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="10px" height="10px">
<polygon points="4,9 4,5 2,5 5,1 8,5 6,5 6,9" fill="#fff"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 138 B

Просмотреть файл

@ -2,15 +2,9 @@
* 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/. */
%define WINDOWS_AERO
%include browser.css
%undef WINDOWS_AERO
%define glassActiveBorderColor rgb(37, 44, 51)
%define glassInactiveBorderColor rgb(102, 102, 102)
%include downloads/indicator-aero.css
@media not all and (-moz-windows-classic) {
#main-window[sizemode="normal"] > #tab-view-deck > #browser-panel > #navigator-toolbox > #toolbar-menubar {
margin-top: 1px;

Просмотреть файл

@ -112,10 +112,8 @@
transition: min-height 170ms ease-out, max-height 170ms ease-out, visibility 170ms linear;
}
%ifdef WINDOWS_AERO
@media not all and (-moz-windows-compositor),
not all and (-moz-windows-default-theme) {
%endif
#main-window[tabsintitlebar]:not([inFullscreen]) #toolbar-menubar:not(:-moz-lwtheme),
#main-window[tabsintitlebar]:not([inFullscreen]) #TabsToolbar:not(:-moz-lwtheme) {
color: CaptionText;
@ -129,13 +127,9 @@
#main-window[tabsintitlebar] #main-menubar > menu:not(:-moz-lwtheme) {
color: inherit;
}
%ifdef WINDOWS_AERO
}
%endif
%ifdef WINDOWS_AERO
@media not all and (-moz-windows-compositor) {
%endif
#main-window[tabsintitlebar] #titlebar:-moz-lwtheme {
visibility: hidden;
}
@ -144,9 +138,7 @@
-moz-binding: url("chrome://global/content/bindings/general.xml#windowdragbox");
visibility: visible;
}
%ifdef WINDOWS_AERO
}
%endif
/**
* In the classic themes, the titlebar has a horizontal gradient, which is
@ -313,15 +305,11 @@
box-shadow: 0 1px 0 @toolbarHighlight@ inset;
}
%ifdef WINDOWS_AERO
@media not all and (-moz-windows-compositor) {
%endif
#TabsToolbar[collapsed="true"] + #nav-bar {
border-top-style: none !important;
}
%ifdef WINDOWS_AERO
}
%endif
#personal-bookmarks {
min-height: 24px;
@ -335,13 +323,11 @@
background-color: -moz-dialog;
}
%ifndef WINDOWS_AERO
@media (-moz-windows-default-theme) {
@media (-moz-os-version: windows-xp) and (-moz-windows-default-theme) {
#main-window[tabsintitlebar][sizemode="normal"] #toolbar-menubar {
margin-top: 4px;
}
}
%endif
/* ::::: titlebar ::::: */
@ -370,11 +356,13 @@
}
.titlebar-placeholder[type="caption-buttons"] {
%ifdef WINDOWS_AERO
margin-left: 22px; /* additional space for Aero Snap */
%else
margin-left: 10px;
%endif
margin-left: 22px; /* space needed for Aero Snap */
}
@media (-moz-os-version: windows-xp) {
.titlebar-placeholder[type="caption-buttons"] {
margin-left: 10px; /* less space needed on XP because there's no Aero Snap */
}
}
/* titlebar command buttons */
@ -589,7 +577,6 @@ menuitem.bookmark-item {
%include ../shared/toolbarbuttons.inc.css
%include ../shared/menupanel.inc.css
%ifndef WINDOWS_AERO
@media (-moz-windows-theme: luna-silver) {
:-moz-any(@primaryToolbarButtons@),
#bookmarks-menu-button.toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon {
@ -600,7 +587,6 @@ menuitem.bookmark-item {
list-style-image: url(chrome://browser/skin/loop/toolbar-lunaSilver.png)
}
}
%endif
#main-window:not([customizing]) .toolbarbutton-1[disabled=true] > .toolbarbutton-icon,
#main-window:not([customizing]) .toolbarbutton-1[disabled=true] > .toolbarbutton-menu-dropmarker,
@ -682,10 +668,9 @@ toolbar[brighttext] .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
transition-duration: 150ms;
}
%ifdef WINDOWS_AERO
@media (-moz-os-version: windows-vista),
@media (-moz-os-version: windows-xp),
(-moz-os-version: windows-vista),
(-moz-os-version: windows-win7) {
%endif
/* < Win8 */
:root {
--toolbarbutton-hover-background: linear-gradient(hsla(0,0%,100%,.6), hsla(0,0%,100%,.1));
@ -723,9 +708,7 @@ toolbar[brighttext] .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
transition-property: background-color, border-color, box-shadow;
transition-duration: 150ms;
}
%ifdef WINDOWS_AERO
}
%endif
#nav-bar .toolbarbutton-1:not(:-moz-any(@primaryToolbarButtons@)) > .toolbarbutton-icon,
#nav-bar .toolbarbutton-1:not(:-moz-any(@primaryToolbarButtons@)) > .toolbarbutton-badge-container,
@ -803,10 +786,9 @@ toolbarbutton[sdk-button="true"][cui-areatype="toolbar"] > .toolbarbutton-icon {
box-shadow: var(--toolbarbutton-hover-boxshadow);
}
%ifdef WINDOWS_AERO
@media (-moz-os-version: windows-vista),
@media (-moz-os-version: windows-xp),
(-moz-os-version: windows-vista),
(-moz-os-version: windows-win7) {
%endif
/* < Win8 */
#nav-bar .toolbarbutton-1:not(:hover):not(:active):not([open]) > .toolbarbutton-menubutton-dropmarker::before,
#nav-bar .toolbaritem-combined-buttons > .toolbarbutton-1:-moz-any(:not(:hover):not([open]),[disabled]) + .toolbarbutton-1:-moz-any(:not(:hover):not([open]),[disabled])::before {
@ -834,9 +816,7 @@ toolbarbutton[sdk-button="true"][cui-areatype="toolbar"] > .toolbarbutton-icon {
box-shadow: 0 0 1px hsla(210,54%,20%,.03),
0 0 2px hsla(210,54%,20%,.1);
}
%ifdef WINDOWS_AERO
}
%endif
.findbar-button:not([disabled=true]):-moz-any([checked="true"],:hover:active) > .toolbarbutton-text,
#nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-button:not([disabled=true]):-moz-any(:hover:active, [open]) > .toolbarbutton-icon,
@ -850,10 +830,9 @@ toolbarbutton[sdk-button="true"][cui-areatype="toolbar"] > .toolbarbutton-icon {
transition-duration: 10ms;
}
%ifdef WINDOWS_AERO
@media (-moz-os-version: windows-vista),
@media (-moz-os-version: windows-xp),
(-moz-os-version: windows-vista),
(-moz-os-version: windows-win7) {
%endif
/* < Win8 */
.findbar-button:not([disabled=true]):-moz-any([checked="true"],:hover:active) > .toolbarbutton-text,
#nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-button:not([disabled=true]):-moz-any(:hover:active, [open]) > .toolbarbutton-icon,
@ -873,9 +852,7 @@ toolbarbutton[sdk-button="true"][cui-areatype="toolbar"] > .toolbarbutton-icon {
background-color: var(--toolbarbutton-checkedhover-backgroundcolor);
transition: background-color .4s;
}
%ifdef WINDOWS_AERO
}
%endif
#TabsToolbar .toolbarbutton-1,
#TabsToolbar .toolbarbutton-1 > .toolbarbutton-menubutton-button,
@ -984,10 +961,9 @@ toolbarbutton[sdk-button="true"][cui-areatype="toolbar"] > .toolbarbutton-icon {
0 1px 0 0 hsla(210,80%,20%,.1) inset !important;
}
%ifdef WINDOWS_AERO
@media (-moz-os-version: windows-vista),
@media (-moz-os-version: windows-xp),
(-moz-os-version: windows-vista),
(-moz-os-version: windows-win7) {
%endif
#back-button > .toolbarbutton-icon {
background-image: linear-gradient(hsla(0,0%,100%,.6), hsla(0,0%,100%,.1)) !important;
box-shadow: 0 1px 0 hsla(0,0%,100%,.3) inset,
@ -1020,9 +996,7 @@ toolbarbutton[sdk-button="true"][cui-areatype="toolbar"] > .toolbarbutton-icon {
0 1px 0 hsla(210,54%,20%,.65) !important;
transition: none;
}
%ifdef WINDOWS_AERO
}
%endif
#back-button:-moz-locale-dir(rtl) > .toolbarbutton-icon {
transform: scaleX(-1);
@ -1140,18 +1114,14 @@ toolbarbutton[sdk-button="true"][cui-areatype="toolbar"] > .toolbarbutton-icon {
border: 1px solid ThreeDShadow;
}
%ifdef WINDOWS_AERO
@media (-moz-os-version: windows-vista),
@media (-moz-os-version: windows-xp),
(-moz-os-version: windows-vista),
(-moz-os-version: windows-win7) {
%endif
/* < Win8 */
#urlbar,
.searchbar-textbox {
border-radius: 2px;
}
%ifdef WINDOWS_AERO
}
%endif
#urlbar {
-moz-padding-end: 2px;
@ -1421,17 +1391,14 @@ richlistitem[type~="action"][actiontype="searchengine"] > .ac-title-box > .ac-si
height: 16px;
}
%ifdef WINDOWS_AERO
@media not all and (-moz-windows-default-theme) {
%endif
@media (-moz-os-version: windows-xp),
not all and (-moz-windows-default-theme) {
.ac-result-type-keyword[selected="true"],
.autocomplete-treebody::-moz-tree-image(keyword, treecolAutoCompleteImage, selected),
richlistitem[type~="action"][actiontype="searchengine"][selected="true"] > .ac-title-box > .ac-site-icon {
list-style-image: url(chrome://global/skin/icons/autocomplete-search.svg#search-icon-inverted);
}
%ifdef WINDOWS_AERO
}
%endif
.ac-result-type-tag,
.autocomplete-treebody::-moz-tree-image(tag, treecolAutoCompleteImage) {
@ -1454,14 +1421,12 @@ richlistitem[type~="action"][actiontype="searchengine"] > .ac-title-box > .ac-si
color: -moz-nativehyperlinktext;
}
%ifndef WINDOWS_AERO
@media (-moz-windows-default-theme) {
@media (-moz-os-version: windows-xp) and (-moz-windows-default-theme) {
.ac-url-text:not([selected="true"]),
.ac-action-text:not([selected="true"]) {
color: #008800;
}
}
%endif
richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-icon {
list-style-image: url("chrome://browser/skin/actionicon-tab.png");
@ -1469,9 +1434,8 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
padding: 0 3px;
}
%ifdef WINDOWS_AERO
@media not all and (-moz-windows-default-theme) {
%endif
@media (-moz-os-version: windows-xp),
not all and (-moz-windows-default-theme) {
richlistitem[type~="action"][actiontype="switchtab"][selected="true"] > .ac-url-box > .ac-action-icon {
-moz-image-region: rect(11px, 16px, 22px, 0);
}
@ -1481,9 +1445,7 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
.ac-action-text[selected="true"] {
color: inherit !important;
}
%ifdef WINDOWS_AERO
}
%endif
.autocomplete-treebody::-moz-tree-cell-text(treecolAutoCompleteComment) {
color: GrayText;
@ -1808,14 +1770,12 @@ toolbarbutton[type="socialmark"] > .toolbarbutton-icon {
margin-bottom: calc(-1 * var(--tab-toolbar-navbar-overlap)); /* overlap the nav-bar's top border */
}
%ifndef WINDOWS_AERO
@media (-moz-windows-default-theme) {
@media (-moz-os-version: windows-xp) and (-moz-windows-default-theme) {
#main-window[sizemode=normal] #TabsToolbar {
padding-left: 2px;
padding-right: 2px;
}
}
%endif
%include ../shared/tabs.inc.css
@ -1852,7 +1812,6 @@ toolbarbutton[type="socialmark"] > .toolbarbutton-icon {
}
}
%ifndef WINDOWS_AERO
/* Use lighter colors of buttons and text in the titlebar on luna-blue */
@media (-moz-windows-theme: luna-blue) {
#tabbrowser-tabs[movingtab] > .tabbrowser-tab[beforeselected]:not([last-visible-tab])::after,
@ -1861,7 +1820,6 @@ toolbarbutton[type="socialmark"] > .toolbarbutton-icon {
background-image: url("chrome://browser/skin/tabbrowser/tab-separator-luna-blue.png");
}
}
%endif
#TabsToolbar[brighttext] .tab-close-button:not(:hover):not([visuallyselected="true"]) {
-moz-image-region: rect(0, 64px, 16px, 48px) !important;
@ -2146,26 +2104,7 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
margin-top: 5px;
}
.popup-notification-icon {
width: 64px;
height: 64px;
-moz-margin-end: 10px;
}
.popup-notification-icon[popupid="geolocation"] {
list-style-image: url(chrome://browser/skin/Geolocation-64.png);
}
.popup-notification-icon[popupid="xpinstall-disabled"],
.popup-notification-icon[popupid="addon-progress"],
.popup-notification-icon[popupid="addon-install-blocked"],
.popup-notification-icon[popupid="addon-install-failed"],
.popup-notification-icon[popupid="addon-install-confirmation"],
.popup-notification-icon[popupid="addon-install-complete"] {
list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric.png);
width: 32px;
height: 32px;
}
%include ../shared/notification-icons.inc.css
.popup-notification-description[popupid="addon-progress"],
.popup-notification-description[popupid="addon-install-confirmation"] {
@ -2177,212 +2116,15 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
font-weight: bold;
}
.popup-notification-icon[popupid="click-to-play-plugins"] {
list-style-image: url(chrome://mozapps/skin/plugins/pluginBlocked-64.png);
}
.popup-notification-icon[popupid="web-notifications"] {
list-style-image: url(chrome://browser/skin/notification-64.png);
}
.popup-notification-icon[popupid="indexedDB-permissions-prompt"],
.popup-notification-icon[popupid*="offline-app-requested"],
.popup-notification-icon[popupid="offline-app-usage"] {
list-style-image: url(chrome://global/skin/icons/question-64.png);
}
.popup-notification-icon[popupid="password"] {
list-style-image: url(chrome://mozapps/skin/passwordmgr/key-64.png);
}
.popup-notification-icon[popupid="webapps-install-progress"],
.popup-notification-icon[popupid="webapps-install"] {
list-style-image: url(chrome://global/skin/icons/webapps-64.png);
}
.popup-notification-icon[popupid="bad-content"] {
list-style-image: url(chrome://browser/skin/bad-content-blocked-64.png);
}
.popup-notification-icon[popupid="bad-content"][mixedblockdisabled],
.popup-notification-icon[popupid="bad-content"][trackingblockdisabled] {
list-style-image: url(chrome://browser/skin/bad-content-unblocked-64.png);
}
.popup-notification-icon[popupid="webRTC-sharingDevices"],
.popup-notification-icon[popupid="webRTC-shareDevices"] {
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-64.png);
}
.popup-notification-icon[popupid="webRTC-sharingMicrophone"],
.popup-notification-icon[popupid="webRTC-shareMicrophone"] {
list-style-image: url(chrome://browser/skin/webRTC-shareMicrophone-64.png);
}
.popup-notification-icon[popupid="webRTC-sharingScreen"],
.popup-notification-icon[popupid="webRTC-shareScreen"] {
list-style-image: url(chrome://browser/skin/webRTC-shareScreen-64.png);
}
.popup-notification-icon[popupid="pointerLock"] {
list-style-image: url(chrome://browser/skin/pointerLock-64.png);
}
/* Notification icon box */
#notification-popup-box {
position: relative;
background-color: #fff;
background-clip: padding-box;
padding-left: 3px;
border-radius: 2.5px 0 0 2.5px;
border-width: 0 8px 0 0;
border-style: solid;
border-image: url("chrome://browser/skin/urlbar-arrow.png") 0 8 0 0 fill;
-moz-margin-end: -8px;
}
@conditionalForwardWithUrlbar@ > #forward-button[disabled] + #urlbar > #notification-popup-box {
padding-left: 7px;
}
#notification-popup-box:-moz-locale-dir(rtl),
.notification-anchor-icon:-moz-locale-dir(rtl) {
transform: scaleX(-1);
}
.notification-anchor-icon {
width: 16px;
height: 16px;
margin: 0 2px;
}
.notification-anchor-icon:-moz-focusring {
outline: 1px dotted -moz-DialogText;
}
.default-notification-icon,
#default-notification-icon {
list-style-image: url(chrome://global/skin/icons/information-16.png);
}
.identity-notification-icon,
#identity-notification-icon {
list-style-image: url(chrome://mozapps/skin/profile/profileicon.png);
}
.geo-notification-icon,
#geo-notification-icon {
list-style-image: url(chrome://browser/skin/Geolocation-16.png);
}
#addons-notification-icon {
list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric-16.png);
}
.indexedDB-notification-icon,
#indexedDB-notification-icon {
list-style-image: url(chrome://global/skin/icons/question-16.png);
}
#password-notification-icon {
list-style-image: url(chrome://mozapps/skin/passwordmgr/key-16.png);
}
#webapps-notification-icon {
list-style-image: url(chrome://global/skin/icons/webapps-16.png);
}
#plugins-notification-icon {
list-style-image: url(chrome://browser/skin/notification-pluginNormal.png);
}
#plugins-notification-icon.plugin-hidden {
list-style-image: url(chrome://browser/skin/notification-pluginAlert.png);
}
#plugins-notification-icon.plugin-blocked {
list-style-image: url(chrome://browser/skin/notification-pluginBlocked.png);
}
#plugins-notification-icon {
-moz-image-region: rect(0, 16px, 16px, 0);
}
#plugins-notification-icon:hover {
-moz-image-region: rect(0, 32px, 16px, 16px);
}
#plugins-notification-icon:active {
-moz-image-region: rect(0, 48px, 16px, 32px);
}
#notification-popup-box[hidden] {
/* Override display:none to make the pluginBlockedNotification animation work
when showing the notification repeatedly. */
display: -moz-box;
visibility: collapse;
}
#plugins-notification-icon.plugin-blocked[showing] {
animation: pluginBlockedNotification 500ms ease 0s 5 alternate both;
}
@keyframes pluginBlockedNotification {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.bad-content-blocked-notification-icon,
#bad-content-blocked-notification-icon {
list-style-image: url(chrome://browser/skin/bad-content-blocked-16.png);
}
.bad-content-unblocked-notification-icon,
#bad-content-unblocked-notification-icon {
list-style-image: url(chrome://browser/skin/bad-content-unblocked-16.png);
}
.webRTC-shareDevices-notification-icon,
#webRTC-shareDevices-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16.png);
}
.webRTC-sharingDevices-notification-icon,
#webRTC-sharingDevices-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-sharingDevice-16.png);
}
.webRTC-shareMicrophone-notification-icon,
#webRTC-shareMicrophone-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareMicrophone-16.png);
}
.webRTC-sharingMicrophone-notification-icon,
#webRTC-sharingMicrophone-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-sharingMicrophone-16.png);
}
.webRTC-shareScreen-notification-icon,
#webRTC-shareScreen-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareScreen-16.png);
}
.webRTC-sharingScreen-notification-icon,
#webRTC-sharingScreen-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-sharingScreen-16.png);
}
.web-notifications-notification-icon,
#web-notifications-notification-icon {
list-style-image: url(chrome://browser/skin/notification-16.png);
}
#pointerLock-notification-icon {
list-style-image: url(chrome://browser/skin/pointerLock-16.png);
}
#pointerLock-cancel {
margin: 0px;
}
@ -2464,18 +2206,6 @@ notification[value="translation"] {
}
}
.translate-notification-icon,
#translate-notification-icon {
list-style-image: url(chrome://browser/skin/translation-16.png);
-moz-image-region: rect(0px, 16px, 16px, 0px);
}
.translated-notification-icon,
#translated-notification-icon {
list-style-image: url(chrome://browser/skin/translation-16.png);
-moz-image-region: rect(0px, 32px, 16px, 16px);
}
.translation-menupopup {
-moz-appearance: none;
}
@ -2702,12 +2432,6 @@ toolbarpaletteitem[place="palette"] > #switch-to-metro-button {
list-style-image: url(chrome://browser/skin/Metro_Glyph-menuPanel.png);
}
.popup-notification-icon[popupid="servicesInstall"] {
list-style-image: url(chrome://browser/skin/social/services-64.png);
}
#servicesInstall-notification-icon {
list-style-image: url(chrome://browser/skin/social/services-16.png);
}
#social-undoactivation-button {
-moz-margin-start: 0; /* override default label margin to match description margin */
}
@ -2811,28 +2535,6 @@ chatbox {
border-top-right-radius: 2.5px;
}
/* EME notifications */
.popup-notification-icon[popupid="drmContentPlaying"],
#eme-notification-icon {
list-style-image: url("chrome://browser/skin/drm-icon.svg#chains");
}
#eme-notification-icon:hover:active {
list-style-image: url("chrome://browser/skin/drm-icon.svg#chains-pressed");
}
#eme-notification-icon[firstplay=true] {
animation: emeTeachingMoment 0.2s linear 0s 5 normal;
}
@keyframes emeTeachingMoment {
0% {transform: translateX(0); }
25% {transform: translateX(3px) }
75% {transform: translateX(-3px) }
100% { transform: translateX(0); }
}
/* Customization mode */
%include ../shared/customizableui/customizeMode.inc.css
@ -2936,32 +2638,32 @@ chatbox {
position: relative;
}
%ifndef WINDOWS_AERO
#TabsToolbar > .private-browsing-indicator {
background-image: url("chrome://browser/skin/privatebrowsing-mask-tabstrip-XPVista7.png");
}
@media not all and (-moz-windows-classic) {
#private-browsing-indicator-titlebar > .private-browsing-indicator {
background-image: url("chrome://browser/skin/privatebrowsing-mask-titlebar-XPVista7-tall.png");
height: 28px;
@media (-moz-os-version: windows-xp) {
#TabsToolbar > .private-browsing-indicator {
background-image: url("chrome://browser/skin/privatebrowsing-mask-tabstrip-XPVista7.png");
}
/* We're intentionally using the titlebar asset here for fullscreen mode.
* See bug 1008183.
*/
#main-window[inFullscreen] #TabsToolbar > .private-browsing-indicator {
background-image: url("chrome://browser/skin/privatebrowsing-mask-titlebar-XPVista7.png");
}
@media not all and (-moz-windows-classic) {
#private-browsing-indicator-titlebar > .private-browsing-indicator {
background-image: url("chrome://browser/skin/privatebrowsing-mask-titlebar-XPVista7-tall.png");
height: 28px;
}
#main-window[sizemode="maximized"] > #titlebar > #titlebar-content > #titlebar-buttonbox-container > #private-browsing-indicator-titlebar > .private-browsing-indicator {
top: -5px;
}
#main-window[sizemode="normal"] > #titlebar > #titlebar-content > #titlebar-buttonbox-container > #private-browsing-indicator-titlebar > .private-browsing-indicator {
top: -1px;
/* We're intentionally using the titlebar asset here for fullscreen mode.
* See bug 1008183.
*/
#main-window[inFullscreen] #TabsToolbar > .private-browsing-indicator {
background-image: url("chrome://browser/skin/privatebrowsing-mask-titlebar-XPVista7.png");
}
#main-window[sizemode="maximized"] > #titlebar > #titlebar-content > #titlebar-buttonbox-container > #private-browsing-indicator-titlebar > .private-browsing-indicator {
top: -5px;
}
#main-window[sizemode="normal"] > #titlebar > #titlebar-content > #titlebar-buttonbox-container > #private-browsing-indicator-titlebar > .private-browsing-indicator {
top: -1px;
}
}
}
%endif
@media (-moz-windows-classic) {
/* We're intentionally using the titlebar asset here for fullscreen mode.
@ -3000,3 +2702,8 @@ chatbox {
-moz-margin-start: -28px;
margin-top: -4px;
}
@media not all and (-moz-os-version: windows-xp) {
%include browser-aero.css
}

Просмотреть файл

@ -1,7 +0,0 @@
/* 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/. */
%define WINDOWS_AERO
%include panelUIOverlay.css
%undef WINDOWS_AERO

Просмотреть файл

@ -129,24 +129,24 @@ menu.subviewbutton > .menu-right:-moz-locale-dir(rtl) {
transform: scaleX(-1);
}
%ifdef WINDOWS_AERO
/* Win8 and beyond. */
@media not all and (-moz-os-version: windows-vista) {
@media not all and (-moz-os-version: windows-win7) {
panelview .toolbarbutton-1,
.subviewbutton,
.widget-overflow-list .toolbarbutton-1,
.panelUI-grid .toolbarbutton-1 > .toolbarbutton-menubutton-button,
#BMB_bookmarksPopup menupopup[placespopup=true] > hbox,
#edit-controls@inAnyPanel@,
#zoom-controls@inAnyPanel@,
#edit-controls@inAnyPanel@ > toolbarbutton,
#zoom-controls@inAnyPanel@ > toolbarbutton {
border-radius: 0;
@media not all and (-moz-os-version: windows-xp) {
@media not all and (-moz-os-version: windows-vista) {
@media not all and (-moz-os-version: windows-win7) {
panelview .toolbarbutton-1,
.subviewbutton,
.widget-overflow-list .toolbarbutton-1,
.panelUI-grid .toolbarbutton-1 > .toolbarbutton-menubutton-button,
#BMB_bookmarksPopup menupopup[placespopup=true] > hbox,
#edit-controls@inAnyPanel@,
#zoom-controls@inAnyPanel@,
#edit-controls@inAnyPanel@ > toolbarbutton,
#zoom-controls@inAnyPanel@ > toolbarbutton {
border-radius: 0;
}
}
}
}
%endif
@media not all and (-moz-windows-default-theme) {
#edit-controls@inAnyPanel@ > #copy-button,

Просмотреть файл

@ -1,7 +0,0 @@
% 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/.
%define WINDOWS_AERO
%include devedition.css
%undef WINDOWS_AERO

Просмотреть файл

@ -1,35 +0,0 @@
/* 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/. */
%define WINDOWS_AERO
%include allDownloadsViewOverlay.css
%undef WINDOWS_AERO
@media (-moz-windows-default-theme) {
/*
-moz-appearance: menuitem is almost right, but the hover effect is not
transparent and is lighter than desired.
Copied from the autocomplete richlistbox styling in
toolkit/themes/windows/global/autocomplete.css
This styling should be kept in sync with the style from the above file.
*/
#downloadsRichListBox > richlistitem.download[selected] {
color: inherit;
background-color: transparent;
/* four gradients for the bevel highlights on each edge, one for blue background */
background-image:
linear-gradient(to bottom, rgba(255,255,255,0.9) 3px, transparent 3px),
linear-gradient(to right, rgba(255,255,255,0.5) 3px, transparent 3px),
linear-gradient(to left, rgba(255,255,255,0.5) 3px, transparent 3px),
linear-gradient(to top, rgba(255,255,255,0.4) 3px, transparent 3px),
linear-gradient(to bottom, rgba(163,196,247,0.3), rgba(122,180,246,0.3));
background-clip: content-box;
border-radius: 6px;
outline: 1px solid rgb(124,163,206);
-moz-outline-radius: 3px;
outline-offset: -2px;
}
}

Просмотреть файл

@ -10,21 +10,27 @@
#downloadsRichListBox > richlistitem.download {
height: 6em;
%ifndef WINDOWS_AERO
padding: 5px 8px;
%endif
}
@media (-moz-os-version: windows-xp) {
#downloadsRichListBox > richlistitem.download {
padding: 5px 8px;
}
}
.downloadTypeIcon {
-moz-margin-end: 8px;
%ifdef WINDOWS_AERO
-moz-margin-start: 8px;
%endif
/* explicitly size the icon, so size doesn't vary on hidpi systems */
height: 32px;
width: 32px;
}
@media not all and (-moz-os-version: windows-xp) {
.downloadTypeIcon {
-moz-margin-start: 8px;
}
}
.blockedIcon {
list-style-image: url("chrome://global/skin/icons/Error.png");
}
@ -105,56 +111,86 @@ richlistitem.download:hover > .downloadButton.downloadRetry:active {
-moz-image-region: rect(32px, 64px, 48px, 48px);
}
%ifndef WINDOWS_AERO
richlistitem.download[selected] > .downloadButton.downloadConfirmBlock,
richlistitem.download[selected] > .downloadButton.downloadCancel {
-moz-image-region: rect(0px, 80px, 16px, 64px);
@media (-moz-os-version: windows-xp) {
richlistitem.download[selected] > .downloadButton.downloadConfirmBlock,
richlistitem.download[selected] > .downloadButton.downloadCancel {
-moz-image-region: rect(0px, 80px, 16px, 64px);
}
richlistitem.download[selected]:hover > .downloadButton.downloadConfirmBlock,
richlistitem.download[selected]:hover > .downloadButton.downloadCancel {
-moz-image-region: rect(0px, 96px, 16px, 80px);
}
richlistitem.download[selected]:hover > .downloadButton.downloadConfirmBlock:hover,
richlistitem.download[selected]:hover > .downloadButton.downloadCancel:hover {
-moz-image-region: rect(0px, 112px, 16px, 96px);
}
richlistitem.download[selected]:hover > .downloadButton.downloadConfirmBlock:active,
richlistitem.download[selected]:hover > .downloadButton.downloadCancel:active {
-moz-image-region: rect(0px, 128px, 16px, 112px);
}
richlistitem.download[selected] > .downloadButton.downloadShow {
-moz-image-region: rect(16px, 80px, 32px, 64px);
}
richlistitem.download[selected]:hover > .downloadButton.downloadShow {
-moz-image-region: rect(16px, 96px, 32px, 80px);
}
richlistitem.download[selected]:hover > .downloadButton.downloadShow:hover {
-moz-image-region: rect(16px, 112px, 32px, 96px);
}
richlistitem.download[selected]:hover > .downloadButton.downloadShow:active {
-moz-image-region: rect(16px, 128px, 32px, 112px);
}
richlistitem.download[selected] > .downloadButton.downloadRetry {
-moz-image-region: rect(32px, 80px, 48px, 64px);
}
richlistitem.download[selected]:hover > .downloadButton.downloadRetry {
-moz-image-region: rect(32px, 96px, 48px, 80px);
}
richlistitem.download[selected]:hover > .downloadButton.downloadRetry:hover {
-moz-image-region: rect(32px, 112px, 48px, 96px);
}
richlistitem.download[selected]:hover > .downloadButton.downloadRetry:active {
-moz-image-region: rect(32px, 128px, 48px, 112px);
}
}
richlistitem.download[selected]:hover > .downloadButton.downloadConfirmBlock,
richlistitem.download[selected]:hover > .downloadButton.downloadCancel {
-moz-image-region: rect(0px, 96px, 16px, 80px);
}
@media not all and (-moz-os-version: windows-xp) {
@media (-moz-windows-default-theme) {
/*
-moz-appearance: menuitem is almost right, but the hover effect is not
transparent and is lighter than desired.
richlistitem.download[selected]:hover > .downloadButton.downloadConfirmBlock:hover,
richlistitem.download[selected]:hover > .downloadButton.downloadCancel:hover {
-moz-image-region: rect(0px, 112px, 16px, 96px);
}
Copied from the autocomplete richlistbox styling in
toolkit/themes/windows/global/autocomplete.css
richlistitem.download[selected]:hover > .downloadButton.downloadConfirmBlock:active,
richlistitem.download[selected]:hover > .downloadButton.downloadCancel:active {
-moz-image-region: rect(0px, 128px, 16px, 112px);
This styling should be kept in sync with the style from the above file.
*/
#downloadsRichListBox > richlistitem.download[selected] {
color: inherit;
background-color: transparent;
/* four gradients for the bevel highlights on each edge, one for blue background */
background-image:
linear-gradient(to bottom, rgba(255,255,255,0.9) 3px, transparent 3px),
linear-gradient(to right, rgba(255,255,255,0.5) 3px, transparent 3px),
linear-gradient(to left, rgba(255,255,255,0.5) 3px, transparent 3px),
linear-gradient(to top, rgba(255,255,255,0.4) 3px, transparent 3px),
linear-gradient(to bottom, rgba(163,196,247,0.3), rgba(122,180,246,0.3));
background-clip: content-box;
border-radius: 6px;
outline: 1px solid rgb(124,163,206);
-moz-outline-radius: 3px;
outline-offset: -2px;
}
}
}
richlistitem.download[selected] > .downloadButton.downloadShow {
-moz-image-region: rect(16px, 80px, 32px, 64px);
}
richlistitem.download[selected]:hover > .downloadButton.downloadShow {
-moz-image-region: rect(16px, 96px, 32px, 80px);
}
richlistitem.download[selected]:hover > .downloadButton.downloadShow:hover {
-moz-image-region: rect(16px, 112px, 32px, 96px);
}
richlistitem.download[selected]:hover > .downloadButton.downloadShow:active {
-moz-image-region: rect(16px, 128px, 32px, 112px);
}
richlistitem.download[selected] > .downloadButton.downloadRetry {
-moz-image-region: rect(32px, 80px, 48px, 64px);
}
richlistitem.download[selected]:hover > .downloadButton.downloadRetry {
-moz-image-region: rect(32px, 96px, 48px, 80px);
}
richlistitem.download[selected]:hover > .downloadButton.downloadRetry:hover {
-moz-image-region: rect(32px, 112px, 48px, 96px);
}
richlistitem.download[selected]:hover > .downloadButton.downloadRetry:active {
-moz-image-region: rect(32px, 128px, 48px, 112px);
}
%endif

Просмотреть файл

@ -1,23 +0,0 @@
/* 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/. */
%define WINDOWS_AERO
%include downloads.css
%undef WINDOWS_AERO
@media (-moz-windows-default-theme) and (-moz-os-version: windows-vista),
(-moz-windows-default-theme) and (-moz-os-version: windows-win7) {
richlistitem[type="download"] {
border: 1px solid transparent;
border-bottom: 1px solid hsl(213,40%,90%);
}
#downloadsPanel:not([keyfocus]) > #downloadsListBox > richlistitem[type="download"][state="1"][exists]:hover {
border: 1px solid hsl(213,45%,65%);
box-shadow: 0 0 0 1px hsla(0,0%,100%,.5) inset,
0 1px 0 hsla(0,0%,100%,.3) inset;
background-image: linear-gradient(hsl(212,86%,92%), hsl(212,91%,86%));
color: black;
}
}

Просмотреть файл

@ -32,16 +32,13 @@
cursor: pointer;
}
%ifdef WINDOWS_AERO
@media (-moz-os-version: windows-vista),
@media (-moz-os-version: windows-xp),
(-moz-os-version: windows-vista),
(-moz-os-version: windows-win7) {
%endif
#downloadsHistory {
color: -moz-nativehyperlinktext;
#downloadsHistory {
color: -moz-nativehyperlinktext;
}
}
%ifdef WINDOWS_AERO
}
%endif
#downloadsPanel[keyfocus] > #downloadsFooter > #downloadsHistory:focus {
outline: 1px -moz-dialogtext dotted;
@ -69,31 +66,32 @@
box-shadow: 0 2px 0 0 hsla(210,4%,10%,.1) inset;
}
%ifdef WINDOWS_AERO
@media (-moz-os-version: windows-vista),
@media (-moz-os-version: windows-xp),
(-moz-os-version: windows-vista),
(-moz-os-version: windows-win7) {
%endif
@media (-moz-windows-default-theme) {
#downloadsFooter {
border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
transition-duration: 0s;
}
@media (-moz-windows-default-theme) {
#downloadsFooter {
border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
transition-duration: 0s;
}
#downloadsFooter,
#downloadsFooter:hover,
#downloadsFooter:hover:active {
%ifdef WINDOWS_AERO
background-color: #f1f5fb;
%else
background-color: hsla(216,45%,88%,.98);
%endif
box-shadow: 0px 1px 2px rgb(204,214,234) inset;
#downloadsFooter,
#downloadsFooter:hover,
#downloadsFooter:hover:active {
background-color: #f1f5fb;
box-shadow: 0px 1px 2px rgb(204,214,234) inset;
}
@media (-moz-os-version: windows-xp) {
#downloadsFooter,
#downloadsFooter:hover,
#downloadsFooter:hover:active {
background-color: hsla(216,45%,88%,.98);
}
}
}
}
%ifdef WINDOWS_AERO
}
%endif
/*** Downloads Summary and List items ***/
@ -131,6 +129,14 @@ richlistitem[type="download"] {
padding: 8px;
}
@media (-moz-windows-default-theme) and (-moz-os-version: windows-vista),
(-moz-windows-default-theme) and (-moz-os-version: windows-win7) {
richlistitem[type="download"] {
border: 1px solid transparent;
border-bottom: 1px solid hsl(213,40%,90%);
}
}
richlistitem[type="download"]:first-child {
border-top: 1px solid transparent;
}
@ -227,27 +233,35 @@ richlistitem[type="download"]:first-child {
box-shadow: 0 1px 0 0 hsla(210,4%,10%,.05) inset;
}
%ifdef WINDOWS_AERO
@media (-moz-os-version: windows-vista),
@media (-moz-os-version: windows-xp),
(-moz-os-version: windows-vista),
(-moz-os-version: windows-win7) {
%endif
#downloadsPanel:not([keyfocus]) > #downloadsListBox > richlistitem[type="download"][state="1"][exists]:hover {
border-radius: 3px;
outline: 0;
border-top: 1px solid hsla(0,0%,100%,.2);
border-bottom: 1px solid hsla(0,0%,0%,.2);
background-color: Highlight;
color: HighlightText;
#downloadsPanel:not([keyfocus]) > #downloadsListBox > richlistitem[type="download"][state="1"][exists]:hover {
border-radius: 3px;
outline: 0;
border-top: 1px solid hsla(0,0%,100%,.2);
border-bottom: 1px solid hsla(0,0%,0%,.2);
background-color: Highlight;
color: HighlightText;
}
#downloadsPanel:not([keyfocus]) > #downloadsListBox > richlistitem[type="download"][state="1"][exists]:hover:active {
background-color: Highlight;
outline: 0;
box-shadow: none;
}
}
#downloadsPanel:not([keyfocus]) > #downloadsListBox > richlistitem[type="download"][state="1"][exists]:hover:active {
background-color: Highlight;
outline: 0;
box-shadow: none;
@media (-moz-windows-default-theme) and (-moz-os-version: windows-vista),
(-moz-windows-default-theme) and (-moz-os-version: windows-win7) {
#downloadsPanel:not([keyfocus]) > #downloadsListBox > richlistitem[type="download"][state="1"][exists]:hover {
border: 1px solid hsl(213,45%,65%);
box-shadow: 0 0 0 1px hsla(0,0%,100%,.5) inset,
0 1px 0 hsla(0,0%,100%,.3) inset;
background-image: linear-gradient(hsl(212,86%,92%), hsl(212,91%,86%));
color: black;
}
}
%ifdef WINDOWS_AERO
}
%endif
/*** Button icons ***/
@ -280,26 +294,26 @@ richlistitem[type="download"]:hover > stack > .downloadButton.downloadShow:hover
richlistitem[type="download"]:hover > stack > .downloadButton.downloadShow:active {
-moz-image-region: rect(16px, 64px, 32px, 48px);
}
%ifndef WINDOWS_AERO
#downloadsPanel[keyfocus] > #downloadsListBox > richlistitem[type="download"][state="1"]:hover > stack > .downloadButton.downloadShow {
-moz-image-region: rect(16px, 32px, 32px, 16px);
@media (-moz-os-version: windows-xp) {
#downloadsPanel[keyfocus] > #downloadsListBox > richlistitem[type="download"][state="1"]:hover > stack > .downloadButton.downloadShow {
-moz-image-region: rect(16px, 32px, 32px, 16px);
}
#downloadsPanel[keyfocus] > #downloadsListBox > richlistitem[type="download"][state="1"]:hover > stack > .downloadButton.downloadShow:hover {
-moz-image-region: rect(16px, 48px, 32px, 32px);
}
#downloadsPanel[keyfocus] > #downloadsListBox > richlistitem[type="download"][state="1"]:hover > stack > .downloadButton.downloadShow:active {
-moz-image-region: rect(16px, 64px, 32px, 48px);
}
#downloadsPanel:not([keyfocus]) > #downloadsListBox > richlistitem[type="download"][state="1"]:hover > stack > .downloadButton.downloadShow {
-moz-image-region: rect(16px, 96px, 32px, 80px);
}
#downloadsPanel:not([keyfocus]) > #downloadsListBox > richlistitem[type="download"][state="1"]:hover > stack > .downloadButton.downloadShow:hover {
-moz-image-region: rect(16px, 112px, 32px, 96px);
}
#downloadsPanel:not([keyfocus]) > #downloadsListBox > richlistitem[type="download"][state="1"]:hover > stack > .downloadButton.downloadShow:active {
-moz-image-region: rect(16px, 128px, 32px, 112px);
}
}
#downloadsPanel[keyfocus] > #downloadsListBox > richlistitem[type="download"][state="1"]:hover > stack > .downloadButton.downloadShow:hover {
-moz-image-region: rect(16px, 48px, 32px, 32px);
}
#downloadsPanel[keyfocus] > #downloadsListBox > richlistitem[type="download"][state="1"]:hover > stack > .downloadButton.downloadShow:active {
-moz-image-region: rect(16px, 64px, 32px, 48px);
}
#downloadsPanel:not([keyfocus]) > #downloadsListBox > richlistitem[type="download"][state="1"]:hover > stack > .downloadButton.downloadShow {
-moz-image-region: rect(16px, 96px, 32px, 80px);
}
#downloadsPanel:not([keyfocus]) > #downloadsListBox > richlistitem[type="download"][state="1"]:hover > stack > .downloadButton.downloadShow:hover {
-moz-image-region: rect(16px, 112px, 32px, 96px);
}
#downloadsPanel:not([keyfocus]) > #downloadsListBox > richlistitem[type="download"][state="1"]:hover > stack > .downloadButton.downloadShow:active {
-moz-image-region: rect(16px, 128px, 32px, 112px);
}
%endif
.downloadButton.downloadRetry {
-moz-image-region: rect(32px, 16px, 48px, 0px);

Просмотреть файл

@ -1,8 +0,0 @@
/* 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/. */
#downloads-indicator-counter {
/* Bug 812345 added this... */
margin-bottom: -1px;
}

Просмотреть файл

@ -133,6 +133,13 @@ toolbar[brighttext] #downloads-button:not([counter])[attention] > #downloads-ind
text-align: center;
}
@media not all and (-moz-os-version: windows-xp) {
#downloads-indicator-counter {
/* Bug 812345 added this... */
margin-bottom: -1px;
}
}
toolbar[brighttext] #downloads-indicator-counter {
color: white;
text-shadow: 0 0 1px rgba(0,0,0,.7),

Просмотреть файл

@ -23,9 +23,7 @@ browser.jar:
skin/classic/browser/aboutTabCrashed.css (../shared/aboutTabCrashed.css)
skin/classic/browser/actionicon-tab.png
* skin/classic/browser/browser.css
* skin/classic/browser/browser-aero.css
* skin/classic/browser/devedition.css
* skin/classic/browser/devedition-aero.css
* skin/classic/browser/browser-lightweightTheme.css
skin/classic/browser/click-to-play-warning-stripes.png
skin/classic/browser/content-contextmenu.svg
@ -119,6 +117,7 @@ browser.jar:
skin/classic/browser/toolbarbutton-dropdown-arrow-inverted.png
skin/classic/browser/undoCloseTab.png (../shared/undoCloseTab.png)
skin/classic/browser/undoCloseTab@2x.png (../shared/undoCloseTab@2x.png)
skin/classic/browser/update-badge.svg (../shared/update-badge.svg)
skin/classic/browser/urlbar-arrow.png
skin/classic/browser/urlbar-popup-blocked.png
skin/classic/browser/urlbar-history-dropmarker.png
@ -165,15 +164,13 @@ browser.jar:
skin/classic/browser/customizableui/menuPanel-customizeFinish.png (../shared/customizableui/menuPanel-customizeFinish.png)
skin/classic/browser/customizableui/panelarrow-customizeTip.png (../shared/customizableui/panelarrow-customizeTip.png)
* skin/classic/browser/customizableui/panelUIOverlay.css (customizableui/panelUIOverlay.css)
* skin/classic/browser/customizableui/panelUIOverlay-aero.css (customizableui/panelUIOverlay-aero.css)
skin/classic/browser/customizableui/subView-arrow-back-inverted.png (../shared/customizableui/subView-arrow-back-inverted.png)
skin/classic/browser/customizableui/subView-arrow-back-inverted-rtl.png (../shared/customizableui/subView-arrow-back-inverted-rtl.png)
skin/classic/browser/customizableui/whimsy.png (../shared/customizableui/whimsy.png)
skin/classic/browser/customizableui/whimsy@2x.png (../shared/customizableui/whimsy@2x.png)
skin/classic/browser/customizableui/whimsy-bw.png (../shared/customizableui/whimsy-bw.png)
skin/classic/browser/customizableui/whimsy-bw@2x.png (../shared/customizableui/whimsy-bw@2x.png)
* skin/classic/browser/downloads/allDownloadsViewOverlay.css (downloads/allDownloadsViewOverlay.css)
* skin/classic/browser/downloads/allDownloadsViewOverlay-aero.css (downloads/allDownloadsViewOverlay-aero.css)
skin/classic/browser/downloads/allDownloadsViewOverlay.css (downloads/allDownloadsViewOverlay.css)
skin/classic/browser/downloads/buttons.png (downloads/buttons.png)
skin/classic/browser/downloads/buttons-aero.png (downloads/buttons-aero.png)
skin/classic/browser/downloads/contentAreaDownloadsView.css (downloads/contentAreaDownloadsView.css)
@ -181,8 +178,7 @@ browser.jar:
skin/classic/browser/downloads/download-notification-finish.png (downloads/download-notification-finish.png)
skin/classic/browser/downloads/download-notification-start.png (downloads/download-notification-start.png)
skin/classic/browser/downloads/download-summary.png (downloads/download-summary.png)
* skin/classic/browser/downloads/downloads.css (downloads/downloads.css)
* skin/classic/browser/downloads/downloads-aero.css (downloads/downloads-aero.css)
skin/classic/browser/downloads/downloads.css (downloads/downloads.css)
skin/classic/browser/feeds/feedIcon.png (feeds/feedIcon.png)
skin/classic/browser/feeds/feedIcon16.png (feeds/feedIcon16.png)
skin/classic/browser/feeds/feedIcon-aero.png (feeds/feedIcon-aero.png)
@ -195,9 +191,7 @@ browser.jar:
skin/classic/browser/panic-panel/header-small.png (../shared/panic-panel/header-small.png)
skin/classic/browser/panic-panel/icons.png (../shared/panic-panel/icons.png)
skin/classic/browser/places/places.css (places/places.css)
* skin/classic/browser/places/places-aero.css (places/places-aero.css)
* skin/classic/browser/places/organizer.css (places/organizer.css)
* skin/classic/browser/places/organizer-aero.css (places/organizer-aero.css)
skin/classic/browser/places/bookmark.png (places/bookmark.png)
skin/classic/browser/places/bookmark-aero.png (places/bookmark-aero.png)
skin/classic/browser/places/query.png (places/query.png)
@ -529,8 +523,6 @@ browser.jar:
% override chrome://browser/skin/aboutSessionRestore-window-icon.png chrome://browser/skin/preferences/application.png os=WINNT osversion<6
% override chrome://browser/skin/aboutSessionRestore-window-icon.png chrome://browser/skin/aboutSessionRestore-window-icon-aero.png os=WINNT osversion>=6
% override chrome://browser/skin/browser.css chrome://browser/skin/browser-aero.css os=WINNT osversion>=6
% override chrome://browser/skin/devedition.css chrome://browser/skin/devedition-aero.css os=WINNT osversion>=6
% override chrome://browser/skin/Info.png chrome://browser/skin/Info-aero.png os=WINNT osversion>=6
% override chrome://browser/skin/identity.png chrome://browser/skin/identity-aero.png os=WINNT osversion>=6
% override chrome://browser/skin/livemark-folder.png chrome://browser/skin/livemark-folder-aero.png os=WINNT osversion>=6
@ -541,14 +533,9 @@ browser.jar:
% override chrome://browser/skin/Privacy-32.png chrome://browser/skin/Privacy-32-aero.png os=WINNT osversion>=6
% override chrome://browser/skin/searchbar-dropdown-arrow.png chrome://browser/skin/searchbar-dropdown-arrow-aero.png os=WINNT osversion>=6
% override chrome://browser/skin/Secure24.png chrome://browser/skin/Secure24-aero.png os=WINNT osversion>=6
% override chrome://browser/skin/customizableui/panelUIOverlay.css chrome://browser/skin/customizableui/panelUIOverlay-aero.css os=WINNT osversion>=6
% override chrome://browser/skin/downloads/allDownloadsViewOverlay.css chrome://browser/skin/downloads/allDownloadsViewOverlay-aero.css os=WINNT osversion>=6
% override chrome://browser/skin/downloads/buttons.png chrome://browser/skin/downloads/buttons-aero.png os=WINNT osversion>=6
% override chrome://browser/skin/downloads/downloads.css chrome://browser/skin/downloads/downloads-aero.css os=WINNT osversion>=6
% override chrome://browser/skin/feeds/feedIcon.png chrome://browser/skin/feeds/feedIcon-aero.png os=WINNT osversion>=6
% override chrome://browser/skin/feeds/feedIcon16.png chrome://browser/skin/feeds/feedIcon16-aero.png os=WINNT osversion>=6
% override chrome://browser/skin/places/places.css chrome://browser/skin/places/places-aero.css os=WINNT osversion>=6
% override chrome://browser/skin/places/organizer.css chrome://browser/skin/places/organizer-aero.css os=WINNT osversion>=6
% override chrome://browser/skin/places/bookmark.png chrome://browser/skin/places/bookmark-aero.png os=WINNT osversion>=6
% override chrome://browser/skin/places/query.png chrome://browser/skin/places/query-aero.png os=WINNT osversion>=6
% override chrome://browser/skin/places/bookmarksMenu.png chrome://browser/skin/places/bookmarksMenu-aero.png os=WINNT osversion>=6

Просмотреть файл

@ -1,77 +0,0 @@
/* 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/. */
%define WINDOWS_AERO
%include ../windowsShared.inc
%include organizer.css
%undef WINDOWS_AERO
%filter substitution
#placesView {
border-top: none;
}
@media not all and (-moz-windows-classic) {
#placesToolbox {
-moz-appearance: none;
background-color: transparent;
}
#placesToolbar {
-moz-appearance: none;
background-color: -moz-Dialog;
color: -moz-dialogText;
}
}
@media (-moz-windows-compositor) {
#placesToolbox {
border-top: none;
}
#placesToolbar {
background-image: linear-gradient(@toolbarHighlight@, transparent);
}
}
@media (-moz-windows-default-theme) {
#placesView > splitter {
border: 0;
-moz-border-end: 1px solid #A9B7C9;
min-width: 0;
width: 3px;
background-color: transparent;
-moz-margin-start: -3px;
position: relative;
}
}
@media (-moz-windows-default-theme) and (-moz-os-version: windows-vista),
(-moz-windows-default-theme) and (-moz-os-version: windows-win7) {
#placesView,
#infoPane,
#placesList,
#placeContent {
background-color: #EEF3FA;
}
#placesToolbar {
background-color: @customToolbarColor@;
color: black;
}
#detailsDeck {
border-top-color: #A9B7C9;
}
#searchFilter {
-moz-appearance: none;
padding: 2px;
-moz-padding-start: 4px;
background-clip: padding-box;
border: 1px solid rgba(0,0,0,.32);
border-radius: 2px;
}
}

Просмотреть файл

@ -2,6 +2,9 @@
* 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 ../windowsShared.inc
%filter substitution
/* Toolbar */
#placesToolbar {
padding: 3px;
@ -17,14 +20,12 @@
list-style-image: url("chrome://browser/skin/Toolbar.png");
}
%ifndef WINDOWS_AERO
@media (-moz-windows-theme: luna-silver) {
#back-button,
#forward-button {
list-style-image: url("chrome://browser/skin/Toolbar-lunaSilver.png");
}
}
%endif
#back-button {
-moz-image-region: rect(0, 54px, 18px, 36px);
@ -149,3 +150,73 @@
-moz-padding-start: 9px;
-moz-padding-end: 9px;
}
@media not all and (-moz-os-version: windows-xp) {
#placesView {
border-top: none;
}
@media not all and (-moz-windows-classic) {
#placesToolbox {
-moz-appearance: none;
background-color: transparent;
}
#placesToolbar {
-moz-appearance: none;
background-color: -moz-Dialog;
color: -moz-dialogText;
}
}
@media (-moz-windows-default-theme) {
#placesView > splitter {
border: 0;
-moz-border-end: 1px solid #A9B7C9;
min-width: 0;
width: 3px;
background-color: transparent;
-moz-margin-start: -3px;
position: relative;
}
}
}
@media (-moz-windows-compositor) {
#placesToolbox {
border-top: none;
}
#placesToolbar {
background-image: linear-gradient(@toolbarHighlight@, transparent);
}
}
@media (-moz-windows-default-theme) and (-moz-os-version: windows-vista),
(-moz-windows-default-theme) and (-moz-os-version: windows-win7) {
#placesView,
#infoPane,
#placesList,
#placeContent {
background-color: #EEF3FA;
}
#placesToolbar {
background-color: @customToolbarColor@;
color: black;
}
#detailsDeck {
border-top-color: #A9B7C9;
}
#searchFilter {
-moz-appearance: none;
padding: 2px;
-moz-padding-start: 4px;
background-clip: padding-box;
border: 1px solid rgba(0,0,0,.32);
border-radius: 2px;
}
}

Просмотреть файл

@ -1,22 +0,0 @@
/* 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 places.css
/* Style Places sidebars as Vista media collection */
@media (-moz-windows-default-theme) {
#bookmarksPanel,
#history-panel {
background-color: #EEF3FA;
}
.sidebar-placesTree {
background-color: transparent;
border-top: none;
}
.sidebar-placesTreechildren::-moz-tree-cell-text(leaf, hover) {
text-decoration: none;
}
}

Просмотреть файл

@ -24,6 +24,25 @@
cursor: default;
}
/* Style Places sidebars as Vista media collection */
@media not all and (-moz-os-version: windows-xp) {
@media (-moz-windows-default-theme) {
#bookmarksPanel,
#history-panel {
background-color: #EEF3FA;
}
.sidebar-placesTree {
background-color: transparent;
border-top: none;
}
.sidebar-placesTreechildren::-moz-tree-cell-text(leaf, hover) {
text-decoration: none;
}
}
}
/* Trees */
treechildren::-moz-tree-image(title) {
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");

Просмотреть файл

@ -23,6 +23,7 @@
#include "xpcprivate.h"
#include "nsContentUtils.h"
#include "nsDocShell.h"
#include "nsProxyRelease.h"
#include "nsIConsoleAPIStorage.h"
#include "nsIDOMWindowUtils.h"
@ -152,6 +153,8 @@ static const JSStructuredCloneCallbacks gConsoleCallbacks = {
class ConsoleCallData final
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ConsoleCallData)
ConsoleCallData()
: mMethodName(Console::MethodLog)
, mPrivate(false)
@ -238,6 +241,10 @@ public:
Maybe<ConsoleStackEntry> mTopStackFrame;
Maybe<nsTArray<ConsoleStackEntry>> mReifiedStack;
nsCOMPtr<nsIStackFrame> mStack;
private:
~ConsoleCallData()
{ }
};
// This class is used to clear any exception at the end of this method.
@ -284,16 +291,13 @@ public:
return false;
}
AutoSyncLoopHolder syncLoop(mWorkerPrivate);
mSyncLoopTarget = syncLoop.EventTarget();
if (NS_FAILED(NS_DispatchToMainThread(this))) {
JS_ReportError(cx,
"Failed to dispatch to main thread for the Console API!");
return false;
}
return syncLoop.Run();
return true;
}
private:
@ -314,14 +318,6 @@ private:
RunWithWindow(window);
}
nsRefPtr<MainThreadStopSyncLoopRunnable> response =
new MainThreadStopSyncLoopRunnable(mWorkerPrivate,
mSyncLoopTarget.forget(),
true);
if (!response->Dispatch(nullptr)) {
NS_WARNING("Failed to dispatch response!");
}
return NS_OK;
}
@ -388,9 +384,6 @@ protected:
// Raw pointer because this method is async and this object is kept alive by
// the caller.
Console* mConsole;
private:
nsCOMPtr<nsIEventTarget> mSyncLoopTarget;
};
// This runnable appends a CallData object into the Console queue running on
@ -406,7 +399,30 @@ public:
private:
~ConsoleCallDataRunnable()
{ }
{
class ReleaseCallData final : public nsRunnable
{
public:
explicit ReleaseCallData(nsRefPtr<ConsoleCallData>& aCallData)
{
mCallData.swap(aCallData);
}
NS_IMETHOD Run() override
{
mCallData = nullptr;
return NS_OK;
}
private:
nsRefPtr<ConsoleCallData> mCallData;
};
nsRefPtr<ReleaseCallData> runnable = new ReleaseCallData(mCallData);
if(NS_FAILED(NS_DispatchToMainThread(runnable))) {
NS_WARNING("Failed to dispatch a ReleaseCallData runnable. Leaking.");
}
}
bool
PreDispatch(JSContext* aCx) override
@ -514,7 +530,7 @@ private:
mConsole->ProcessCallData(mCallData);
}
ConsoleCallData* mCallData;
nsRefPtr<ConsoleCallData> mCallData;
JSAutoStructuredCloneBuffer mArguments;
ConsoleStructuredCloneData mData;
@ -566,6 +582,7 @@ private:
return false;
}
mArguments.Clear();
return true;
}
@ -959,7 +976,7 @@ Console::Method(JSContext* aCx, MethodName aMethodName,
const nsAString& aMethodString,
const Sequence<JS::Value>& aData)
{
nsAutoPtr<ConsoleCallData> callData(new ConsoleCallData());
nsRefPtr<ConsoleCallData> callData(new ConsoleCallData());
ClearException ce(aCx);
@ -1078,8 +1095,6 @@ Console::Method(JSContext* aCx, MethodName aMethodName,
return;
}
// Note: we can pass the reference of callData because this runnable calls
// ProcessCallData() synchronously.
nsRefPtr<ConsoleCallDataRunnable> runnable =
new ConsoleCallDataRunnable(this, callData);
runnable->Dispatch();

Просмотреть файл

@ -80,6 +80,17 @@ public:
Serialize(aRetval);
}
typedef void (*ParamFunc)(const nsString& aName, const nsString& aValue,
void* aClosure);
void
ForEach(ParamFunc aFunc, void* aClosure)
{
for (uint32_t i = 0; i < mSearchParams.Length(); ++i) {
aFunc(mSearchParams[i].mKey, mSearchParams[i].mValue, aClosure);
}
}
private:
void AppendInternal(const nsAString& aName, const nsAString& aValue);

Просмотреть файл

@ -17,11 +17,14 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=345339
src="http://mochi.test:8888/tests/dom/base/test/345339_iframe.html">
</iframe>
<pre id="test">
<script class="testbody" type="text/javascript">
<script class="testbody" type="text/javascript;version=1.7">
/** Test for Bug 345339 **/
SimpleTest.waitForExplicitFinish();
var filePath;
const testData = "Test data\n";
let file = new File([testData],
"345339_test.file",
{ type: "text/plain" });
function afterLoad() {
var iframeDoc = $("testframe").contentDocument;
@ -32,15 +35,7 @@ function afterLoad() {
iframeDoc.getElementById("password").value = "123456";
iframeDoc.getElementById("hidden").value = "gecko";
var file = SpecialPowers.Cc["@mozilla.org/file/directory_service;1"]
.getService(SpecialPowers.Ci.nsIProperties)
.get("TmpD", SpecialPowers.Ci.nsILocalFile);
file.append("345339_test.file");
// Only the file's path is used, so it doesn't need to be created.
// See also bug 1058977.
filePath = file.path;
SpecialPowers.wrap(iframeDoc).getElementById("file").value = filePath;
SpecialPowers.wrap(iframeDoc).getElementById("file").mozSetFileArray([file]);
/* Reload the page */
$("testframe").setAttribute("onload", "afterReload()");
@ -62,10 +57,26 @@ function afterReload() {
"password field value forgotten");
is(iframeDoc.getElementById("hidden").value, "gecko",
"hidden field value preserved");
is(SpecialPowers.wrap(iframeDoc).getElementById("file").value, filePath,
"file field value preserved");
SimpleTest.finish();
// The new file object isn't ===, but it's extensionally equal:
let newFile = iframeDoc.getElementById("file").files[0];
for (let prop of ["name", "lastModified", "size", "type"]) {
is(newFile[prop], file[prop],
"file field " + prop + " property preserved");
}
let reader = new FileReader();
reader.onloadend = function() {
SimpleTest.finish();
};
reader.onload = function() {
is(reader.result, testData,
"file field contents preserved")
};
reader.onerror = function() {
is(reader.error, null,
"FileReader error");
};
reader.readAsText(newFile);
}
</script>
</pre>

Просмотреть файл

@ -73,3 +73,4 @@ MSG_DEF(MSG_INVALID_RESPONSE_STATUSCODE_ERROR, 0, JSEXN_RANGEERR, "Invalid respo
MSG_DEF(MSG_INVALID_REDIRECT_STATUSCODE_ERROR, 0, JSEXN_RANGEERR, "Invalid redirect status code.")
MSG_DEF(MSG_INVALID_URL_SCHEME, 2, JSEXN_TYPEERR, "{0} URL {1} must be either http:// or https://.")
MSG_DEF(MSG_RESPONSE_URL_IS_NULL, 0, JSEXN_TYPEERR, "Cannot set Response.finalURL when Response.url is null.")
MSG_DEF(MSG_BAD_FORMDATA, 0, JSEXN_TYPEERR, "Could not parse content as FormData.")

Просмотреть файл

@ -56,53 +56,68 @@ GetOrigin(nsIPrincipal* aPrincipal, nsAString& aOrigin, ErrorResult& aRv)
{
MOZ_ASSERT(aPrincipal);
uint16_t appStatus = aPrincipal->GetAppStatus();
bool unknownAppId;
aRv = aPrincipal->GetUnknownAppId(&unknownAppId);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
if (appStatus == nsIPrincipal::APP_STATUS_NOT_INSTALLED) {
nsAutoString tmp;
aRv = nsContentUtils::GetUTFOrigin(aPrincipal, tmp);
if (!unknownAppId) {
uint32_t appId;
aRv = aPrincipal->GetAppId(&appId);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
aOrigin = tmp;
if (aOrigin.EqualsASCII("null")) {
nsCOMPtr<nsIURI> uri;
aRv = aPrincipal->GetURI(getter_AddRefs(uri));
if (NS_WARN_IF(aRv.Failed())) {
if (appId != nsIScriptSecurityManager::NO_APP_ID) {
// If we are in "app code", use manifest URL as unique origin since
// multiple apps can share the same origin but not same broadcast
// messages.
nsresult rv;
nsCOMPtr<nsIAppsService> appsService =
do_GetService("@mozilla.org/AppsService;1", &rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
aRv.Throw(rv);
return;
}
if (NS_WARN_IF(!uri)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
nsAutoCString spec;
aRv = uri->GetSpec(spec);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
aOrigin = NS_ConvertUTF8toUTF16(spec);
appsService->GetManifestURLByLocalId(appId, aOrigin);
return;
}
}
nsAutoString tmp;
aRv = nsContentUtils::GetUTFOrigin(aPrincipal, tmp);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
uint32_t appId = aPrincipal->GetAppId();
// 'null' means an unknown origin (it can be chrome code or it can be some
// about: page).
// If we are in "app code", use manifest URL as unique origin since
// multiple apps can share the same origin but not same broadcast messages.
nsresult rv;
nsCOMPtr<nsIAppsService> appsService =
do_GetService("@mozilla.org/AppsService;1", &rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
aRv.Throw(rv);
aOrigin = tmp;
if (!aOrigin.EqualsASCII("null")) {
return;
}
appsService->GetManifestURLByLocalId(appId, aOrigin);
nsCOMPtr<nsIURI> uri;
aRv = aPrincipal->GetURI(getter_AddRefs(uri));
if (NS_WARN_IF(aRv.Failed())) {
return;
}
if (NS_WARN_IF(!uri)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
nsAutoCString spec;
aRv = uri->GetSpec(spec);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
aOrigin = NS_ConvertUTF8toUTF16(spec);
}
nsIPrincipal*

Просмотреть файл

@ -1,5 +1,5 @@
[DEFAULT]
skip-if = buildapp == 'b2g'
skip-if = e10s || buildapp == 'b2g'
support-files =
blank.html

Просмотреть файл

@ -0,0 +1,20 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>MozBrowser iframe</title>
</head>
<body>
<div id="container"></div>
<script type="application/javascript;version=1.7">
var ifr = document.createElement('iframe');
ifr.src = 'http://mochi.test:8888/tests/dom/broadcastchannel/tests/iframe_mozbrowser.html';
ifr.onload = function() { alert('DONE'); }
var domParent = document.getElementById('container');
domParent.appendChild(ifr);
</script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,21 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>MozBrowser iframe</title>
</head>
<body>
<div id="container"></div>
<script type="application/javascript;version=1.7">
var ifr = document.createElement('iframe');
ifr.setAttribute('mozbrowser', true);
ifr.src = 'http://mochi.test:8888/tests/dom/broadcastchannel/tests/iframe_mozbrowser2.html';
ifr.onload = function() { alert('DONE'); }
var domParent = document.getElementById('container');
domParent.appendChild(ifr);
</script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,15 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>MozBrowser iframe</title>
</head>
<body>
<script type="application/javascript;version=1.7">
var bc = new BroadcastChannel('foobar');
bc.postMessage('This is wrong!');
</script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,15 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>MozBrowser iframe</title>
</head>
<body>
<script type="application/javascript;version=1.7">
var bc = new BroadcastChannel('foobar');
bc.postMessage('This is wrong!');
</script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,6 @@
{
"name": "BroadcastChannel",
"description": "BroadcastChannel app",
"launch_path": "/tests/dom/broadcastchannel/tests/TESTTOKEN",
"icons": { "128": "default_icon" }
}

Просмотреть файл

@ -6,6 +6,12 @@ support-files =
broadcastchannel_worker.js
broadcastchannel_worker_alive.js
broadcastchannel_worker_any.js
file_mozbrowser.html
file_mozbrowser2.html
iframe_mozbrowser.html
iframe_mozbrowser2.html
server.sjs
manifest.webapp
[test_broadcastchannel_any.html]
[test_broadcastchannel_basic.html]
@ -15,3 +21,7 @@ support-files =
[test_broadcastchannel_sharedWorker.html]
[test_broadcastchannel_worker.html]
[test_broadcastchannel_worker_alive.html]
[test_broadcastchannel_mozbrowser.html]
skip-if = e10s || buildapp == 'b2g'
[test_broadcastchannel_mozbrowser2.html]
skip-if = e10s || buildapp == 'b2g'

Просмотреть файл

@ -0,0 +1,56 @@
var gBasePath = "tests/dom/broadcastchannel/tests/";
function handleRequest(request, response) {
var query = getQuery(request);
var testToken = '';
if ('testToken' in query) {
testToken = query.testToken;
}
var template = 'manifest.webapp';
if ('template' in query) {
template = query.template;
}
var template = gBasePath + template;
response.setHeader("Content-Type", "application/x-web-app-manifest+json", false);
response.write(readTemplate(template).replace(/TESTTOKEN/g, testToken));
}
// Copy-pasted incantations. There ought to be a better way to synchronously read
// a file into a string, but I guess we're trying to discourage that.
function readTemplate(path) {
var file = Components.classes["@mozilla.org/file/directory_service;1"].
getService(Components.interfaces.nsIProperties).
get("CurWorkD", Components.interfaces.nsILocalFile);
var fis = Components.classes['@mozilla.org/network/file-input-stream;1'].
createInstance(Components.interfaces.nsIFileInputStream);
var cis = Components.classes["@mozilla.org/intl/converter-input-stream;1"].
createInstance(Components.interfaces.nsIConverterInputStream);
var split = path.split("/");
for(var i = 0; i < split.length; ++i) {
file.append(split[i]);
}
fis.init(file, -1, -1, false);
cis.init(fis, "UTF-8", 0, 0);
var data = "";
let str = {};
let read = 0;
do {
read = cis.readString(0xffffffff, str); // read as much as we can and put it in str.value
data += str.value;
} while (read != 0);
cis.close();
return data;
}
function getQuery(request) {
var query = {};
request.queryString.split('&').forEach(function (val) {
var [name, value] = val.split('=');
query[name] = unescape(value);
});
return query;
}

Просмотреть файл

@ -0,0 +1,137 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for BroadcastChannel - iframe mozbrowser</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<div id="container"></div>
<script type="application/javascript">
var gHostedManifestURL = 'http://test/tests/dom/broadcastchannel/tests/server.sjs?testToken=file_mozbrowser.html';
var gApp;
function cbError() {
ok(false, "Error callback invoked");
finish();
}
function createBC() {
var bc = new BroadcastChannel('foobar');
bc.onmessage = function(e) {
is(e.data, "Done!", "A message has been received!");
nextStep();
}
nextStep();
}
function completeOperation() {
var bc = new BroadcastChannel('foobar');
bc.postMessage("Done!");
}
function installApp() {
var request = navigator.mozApps.install(gHostedManifestURL);
request.onerror = cbError;
request.onsuccess = function() {
gApp = request.result;
nextStep();
}
}
function uninstallApp() {
// Uninstall the app.
var request = navigator.mozApps.mgmt.uninstall(gApp);
request.onerror = cbError;
request.onsuccess = function() {
// All done.
info("All done");
nextStep();
}
}
function testApp() {
var ifr = document.createElement('iframe');
ifr.setAttribute('mozbrowser', 'true');
ifr.setAttribute('mozapp', gApp.manifestURL);
ifr.setAttribute('src', gApp.manifest.launch_path);
var domParent = document.getElementById('container');
// Set us up to listen for messages from the app.
var listener = function(e) {
ok(true, "Messaging from app complete");
ifr.removeEventListener('mozbrowsershowmodalprompt', listener);
domParent.removeChild(ifr);
nextStep();
}
// This event is triggered when the app calls "alert".
ifr.addEventListener('mozbrowsershowmodalprompt', listener, false);
domParent.appendChild(ifr);
}
var steps = [
// Permissions
function() {
SpecialPowers.pushPermissions(
[{ "type": "browser", "allow": 1, "context": document },
{ "type": "embed-apps", "allow": 1, "context": document },
{ "type": "webapps-manage", "allow": 1, "context": document }], nextStep);
},
function() {
SpecialPowers.pushPrefEnv({"set": [["dom.broadcastChannel.enabled", true],
["network.disable.ipc.security", true],
["browser.pagethumbnails.capturing_disabled", true],
["dom.mozBrowserFramesEnabled", true],
["dom.ipc.browser_frames.oop_by_default", false],
["dom.ipc.tabs.disabled", false],
["dom.testing.ignore_ipc_principal", true],
["security.mixed_content.block_active_content", false]]},
nextStep);
},
// No confirmation needed when an app is installed
function() {
SpecialPowers.autoConfirmAppInstall(() =>
SpecialPowers.autoConfirmAppUninstall(nextStep));
},
createBC,
// Installing the app
installApp,
// Run tests in app
testApp,
// Uninstall the app
uninstallApp,
// finish
completeOperation
];
function finish() {
SimpleTest.finish();
}
function nextStep() {
if (!steps.length) {
SimpleTest.finish();
return;
}
var step = steps.shift();
step();
}
SimpleTest.waitForExplicitFinish();
nextStep();
</script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,137 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for BroadcastChannel - iframe mozbrowser</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<div id="container"></div>
<script type="application/javascript">
var gHostedManifestURL = 'http://test/tests/dom/broadcastchannel/tests/server.sjs?testToken=file_mozbrowser2.html';
var gApp;
function cbError() {
ok(false, "Error callback invoked");
finish();
}
function createBC() {
var bc = new BroadcastChannel('foobar');
bc.onmessage = function(e) {
is(e.data, "Done!", "A message has been received!");
nextStep();
}
nextStep();
}
function completeOperation() {
var bc = new BroadcastChannel('foobar');
bc.postMessage("Done!");
}
function installApp() {
var request = navigator.mozApps.install(gHostedManifestURL);
request.onerror = cbError;
request.onsuccess = function() {
gApp = request.result;
nextStep();
}
}
function uninstallApp() {
// Uninstall the app.
var request = navigator.mozApps.mgmt.uninstall(gApp);
request.onerror = cbError;
request.onsuccess = function() {
// All done.
info("All done");
nextStep();
}
}
function testApp() {
var ifr = document.createElement('iframe');
ifr.setAttribute('mozbrowser', 'true');
ifr.setAttribute('mozapp', gApp.manifestURL);
ifr.setAttribute('src', gApp.manifest.launch_path);
var domParent = document.getElementById('container');
// Set us up to listen for messages from the app.
var listener = function(e) {
ok(true, "Messaging from app complete");
ifr.removeEventListener('mozbrowsershowmodalprompt', listener);
domParent.removeChild(ifr);
nextStep();
}
// This event is triggered when the app calls "alert".
ifr.addEventListener('mozbrowsershowmodalprompt', listener, false);
domParent.appendChild(ifr);
}
var steps = [
// Permissions
function() {
SpecialPowers.pushPermissions(
[{ "type": "browser", "allow": 1, "context": document },
{ "type": "embed-apps", "allow": 1, "context": document },
{ "type": "webapps-manage", "allow": 1, "context": document }], nextStep);
},
function() {
SpecialPowers.pushPrefEnv({"set": [["dom.broadcastChannel.enabled", true],
["network.disable.ipc.security", true],
["browser.pagethumbnails.capturing_disabled", true],
["dom.mozBrowserFramesEnabled", true],
["dom.ipc.browser_frames.oop_by_default", false],
["dom.ipc.tabs.disabled", false],
["dom.testing.ignore_ipc_principal", true],
["security.mixed_content.block_active_content", false]]},
nextStep);
},
// No confirmation needed when an app is installed
function() {
SpecialPowers.autoConfirmAppInstall(() =>
SpecialPowers.autoConfirmAppUninstall(nextStep));
},
createBC,
// Installing the app
installApp,
// Run tests in app
testApp,
// Uninstall the app
uninstallApp,
// finish
completeOperation
];
function finish() {
SimpleTest.finish();
}
function nextStep() {
if (!steps.length) {
SimpleTest.finish();
return;
}
var step = steps.shift();
step();
}
SimpleTest.waitForExplicitFinish();
nextStep();
</script>
</body>
</html>

Просмотреть файл

@ -113,6 +113,7 @@
#include "nsSVGLength2.h"
#include "nsDeviceContext.h"
#include "nsFontMetrics.h"
#include "Units.h"
#undef free // apparently defined by some windows header, clashing with a free()
// method in SkTypes.h
@ -1349,7 +1350,9 @@ CanvasRenderingContext2D::EnsureTarget(RenderingMode aRenderingMode)
}
if (layerManager) {
if (mode == RenderingMode::OpenGLBackendMode && CheckSizeForSkiaGL(size)) {
if (mode == RenderingMode::OpenGLBackendMode &&
gfxPlatform::GetPlatform()->UseAcceleratedSkiaCanvas() &&
CheckSizeForSkiaGL(size)) {
DemoteOldestContextIfNecessary();
#if USE_SKIA_GPU
@ -4461,7 +4464,8 @@ CanvasRenderingContext2D::DrawDirectlyToCanvas(
// FLAG_CLAMP is added for increased performance, since we never tile here.
uint32_t modifiedFlags = image.mDrawingFlags | imgIContainer::FLAG_CLAMP;
SVGImageContext svgContext(scaledImageSize, Nothing(), CurrentState().globalAlpha);
CSSIntSize sz(scaledImageSize.width, scaledImageSize.height); // XXX hmm is scaledImageSize really in CSS pixels?
SVGImageContext svgContext(sz, Nothing(), CurrentState().globalAlpha);
auto result = image.mImgContainer->
Draw(context, scaledImageSize,

Просмотреть файл

@ -12,8 +12,10 @@
#include "nsIUnicodeDecoder.h"
#include "nsIUnicodeEncoder.h"
#include "nsCharSeparatedTokenizer.h"
#include "nsDOMString.h"
#include "nsNetUtil.h"
#include "nsReadableUtils.h"
#include "nsStreamUtils.h"
#include "nsStringStream.h"
@ -515,6 +517,382 @@ ExtractFromURLSearchParams(const URLSearchParams& aParams,
aContentType = NS_LITERAL_CSTRING("application/x-www-form-urlencoded;charset=UTF-8");
return NS_NewStringInputStream(aStream, serialized);
}
void
FillFormData(const nsString& aName, const nsString& aValue, void* aFormData)
{
MOZ_ASSERT(aFormData);
nsFormData* fd = static_cast<nsFormData*>(aFormData);
fd->Append(aName, aValue);
}
/**
* A simple multipart/form-data parser as defined in RFC 2388 and RFC 2046.
* This does not respect any encoding specified per entry, using UTF-8
* throughout. This is as the Fetch spec states in the consume body algorithm.
* Borrows some things from Necko's nsMultiMixedConv, but is simpler since
* unlike Necko we do not have to deal with receiving incomplete chunks of data.
*
* This parser will fail the entire parse on any invalid entry, so it will
* never return a partially filled FormData.
* The content-disposition header is used to figure out the name and filename
* entries. The inclusion of the filename parameter decides if the entry is
* inserted into the nsFormData as a string or a File.
*
* File blobs are copies of the underlying data string since we cannot adopt
* char* chunks embedded within the larger body without significant effort.
* FIXME(nsm): Bug 1127552 - We should add telemetry to calls to formData() and
* friends to figure out if Fetch ends up copying big blobs to see if this is
* worth optimizing.
*/
class MOZ_STACK_CLASS FormDataParser
{
private:
nsRefPtr<nsFormData> mFormData;
nsCString mMimeType;
nsCString mData;
// Entry state, reset in START_PART.
nsCString mName;
nsCString mFilename;
nsCString mContentType;
enum
{
START_PART,
PARSE_HEADER,
PARSE_BODY,
} mState;
nsIGlobalObject* mParentObject;
// Reads over a boundary and sets start to the position after the end of the
// boundary. Returns false if no boundary is found immediately.
bool
PushOverBoundary(const nsACString& aBoundaryString,
nsACString::const_iterator& aStart,
nsACString::const_iterator& aEnd)
{
// We copy the end iterator to keep the original pointing to the real end
// of the string.
nsACString::const_iterator end(aEnd);
const char* beginning = aStart.get();
if (FindInReadable(aBoundaryString, aStart, end)) {
// We either should find the body immediately, or after 2 chars with the
// 2 chars being '-', everything else is failure.
if ((aStart.get() - beginning) == 0) {
aStart.advance(aBoundaryString.Length());
return true;
}
if ((aStart.get() - beginning) == 2) {
if (*(--aStart) == '-' && *(--aStart) == '-') {
aStart.advance(aBoundaryString.Length() + 2);
return true;
}
}
}
return false;
}
// Reads over a CRLF and positions start after it.
bool
PushOverLine(nsACString::const_iterator& aStart)
{
if (*aStart == nsCRT::CR && (aStart.size_forward() > 1) && *(++aStart) == nsCRT::LF) {
++aStart; // advance to after CRLF
return true;
}
return false;
}
bool
FindCRLF(nsACString::const_iterator& aStart,
nsACString::const_iterator& aEnd)
{
nsACString::const_iterator end(aEnd);
return FindInReadable(NS_LITERAL_CSTRING("\r\n"), aStart, end);
}
bool
ParseHeader(nsACString::const_iterator& aStart,
nsACString::const_iterator& aEnd,
bool* aWasEmptyHeader)
{
MOZ_ASSERT(aWasEmptyHeader);
// Set it to a valid value here so we don't forget later.
*aWasEmptyHeader = false;
const char* beginning = aStart.get();
nsACString::const_iterator end(aEnd);
if (!FindCRLF(aStart, end)) {
return false;
}
if (aStart.get() == beginning) {
*aWasEmptyHeader = true;
return true;
}
nsAutoCString header(beginning, aStart.get() - beginning);
nsACString::const_iterator headerStart, headerEnd;
header.BeginReading(headerStart);
header.EndReading(headerEnd);
if (!FindCharInReadable(':', headerStart, headerEnd)) {
return false;
}
nsAutoCString headerName(StringHead(header, headerStart.size_backward()));
headerName.CompressWhitespace();
if (!NS_IsValidHTTPToken(headerName)) {
return false;
}
nsAutoCString headerValue(Substring(++headerStart, headerEnd));
if (!NS_IsReasonableHTTPHeaderValue(headerValue)) {
return false;
}
headerValue.CompressWhitespace();
if (headerName.LowerCaseEqualsLiteral("content-disposition")) {
nsCCharSeparatedTokenizer tokenizer(headerValue, ';');
bool seenFormData = false;
while (tokenizer.hasMoreTokens()) {
const nsDependentCSubstring& token = tokenizer.nextToken();
if (token.IsEmpty()) {
continue;
}
if (token.EqualsLiteral("form-data")) {
seenFormData = true;
continue;
}
if (seenFormData &&
StringBeginsWith(token, NS_LITERAL_CSTRING("name="))) {
mName = StringTail(token, token.Length() - 5);
mName.Trim(" \"");
continue;
}
if (seenFormData &&
StringBeginsWith(token, NS_LITERAL_CSTRING("filename="))) {
mFilename = StringTail(token, token.Length() - 9);
mFilename.Trim(" \"");
continue;
}
}
if (mName.IsVoid()) {
// Could not parse a valid entry name.
return false;
}
} else if (headerName.LowerCaseEqualsLiteral("content-type")) {
mContentType = headerValue;
}
return true;
}
// The end of a body is marked by a CRLF followed by the boundary. So the
// CRLF is part of the boundary and not the body, but any prior CRLFs are
// part of the body. This will position the iterator at the beginning of the
// boundary (after the CRLF).
bool
ParseBody(const nsACString& aBoundaryString,
nsACString::const_iterator& aStart,
nsACString::const_iterator& aEnd)
{
const char* beginning = aStart.get();
// Find the boundary marking the end of the body.
nsACString::const_iterator end(aEnd);
if (!FindInReadable(aBoundaryString, aStart, end)) {
return false;
}
// We found a boundary, strip the just prior CRLF, and consider
// everything else the body section.
if (aStart.get() - beginning < 2) {
// Only the first entry can have a boundary right at the beginning. Even
// an empty body will have a CRLF before the boundary. So this is
// a failure.
return false;
}
// Check that there is a CRLF right before the boundary.
aStart.advance(-2);
// Skip optional hyphens.
if (*aStart == '-' && *(aStart.get()+1) == '-') {
if (aStart.get() - beginning < 2) {
return false;
}
aStart.advance(-2);
}
if (*aStart != nsCRT::CR || *(aStart.get()+1) != nsCRT::LF) {
return false;
}
nsAutoCString body(beginning, aStart.get() - beginning);
// Restore iterator to after the \r\n as we promised.
// We do not need to handle the extra hyphens case since our boundary
// parser in PushOverBoundary()
aStart.advance(2);
if (!mFormData) {
mFormData = new nsFormData();
}
NS_ConvertUTF8toUTF16 name(mName);
if (mFilename.IsVoid()) {
mFormData->Append(name, NS_ConvertUTF8toUTF16(body));
} else {
// Unfortunately we've to copy the data first since all our strings are
// going to free it. We also need fallible alloc, so we can't just use
// ToNewCString().
char* copy = static_cast<char*>(NS_Alloc(body.Length()));
if (!copy) {
NS_WARNING("Failed to copy File entry body.");
return false;
}
nsCString::const_iterator bodyIter, bodyEnd;
body.BeginReading(bodyIter);
body.EndReading(bodyEnd);
char *p = copy;
while (bodyIter != bodyEnd) {
*p++ = *bodyIter++;
}
p = nullptr;
nsRefPtr<File> file =
File::CreateMemoryFile(mParentObject,
reinterpret_cast<void *>(copy), body.Length(),
NS_ConvertUTF8toUTF16(mFilename),
NS_ConvertUTF8toUTF16(mContentType), /* aLastModifiedDate */ 0);
Optional<nsAString> dummy;
mFormData->Append(name, *file, dummy);
}
return true;
}
public:
FormDataParser(const nsACString& aMimeType, const nsACString& aData, nsIGlobalObject* aParent)
: mMimeType(aMimeType), mData(aData), mState(START_PART), mParentObject(aParent)
{
}
bool
Parse()
{
// Determine boundary from mimetype.
const char* boundaryId = nullptr;
boundaryId = strstr(mMimeType.BeginWriting(), "boundary");
if (!boundaryId) {
return false;
}
boundaryId = strchr(boundaryId, '=');
if (!boundaryId) {
return false;
}
// Skip over '='.
boundaryId++;
char *attrib = (char *) strchr(boundaryId, ';');
if (attrib) *attrib = '\0';
nsAutoCString boundaryString(boundaryId);
if (attrib) *attrib = ';';
boundaryString.Trim(" \"");
if (boundaryString.Length() == 0) {
return false;
}
nsACString::const_iterator start, end;
mData.BeginReading(start);
// This should ALWAYS point to the end of data.
// Helpers make copies.
mData.EndReading(end);
while (start != end) {
switch(mState) {
case START_PART:
mName.SetIsVoid(true);
mFilename.SetIsVoid(true);
mContentType = NS_LITERAL_CSTRING("text/plain");
// MUST start with boundary.
if (!PushOverBoundary(boundaryString, start, end)) {
return false;
}
if (start != end && *start == '-') {
// End of data.
if (!mFormData) {
mFormData = new nsFormData();
}
return true;
}
if (!PushOverLine(start)) {
return false;
}
mState = PARSE_HEADER;
break;
case PARSE_HEADER:
bool emptyHeader;
if (!ParseHeader(start, end, &emptyHeader)) {
return false;
}
if (!PushOverLine(start)) {
return false;
}
mState = emptyHeader ? PARSE_BODY : PARSE_HEADER;
break;
case PARSE_BODY:
if (mName.IsVoid()) {
NS_WARNING("No content-disposition header with a valid name was "
"found. Failing at body parse.");
return false;
}
if (!ParseBody(boundaryString, start, end)) {
return false;
}
mState = START_PART;
break;
default:
MOZ_CRASH("Invalid case");
}
}
NS_NOTREACHED("Should never reach here.");
return false;
}
already_AddRefed<nsFormData> FormData()
{
return mFormData.forget();
}
};
} // anonymous namespace
nsresult
@ -1142,6 +1520,56 @@ FetchBody<Derived>::ContinueConsumeBody(nsresult aStatus, uint32_t aResultLength
autoFree.Reset();
return;
}
case CONSUME_FORMDATA: {
nsCString data;
data.Adopt(reinterpret_cast<char*>(aResult), aResultLength);
autoFree.Reset();
NS_NAMED_LITERAL_CSTRING(formDataMimeType, NS_LITERAL_CSTRING("multipart/form-data"));
// Allow semicolon separated boundary/encoding suffix like multipart/form-data; boundary=
// but disallow multipart/form-datafoobar.
bool isValidFormDataMimeType = StringBeginsWith(mMimeType, formDataMimeType);
if (isValidFormDataMimeType && mMimeType.Length() > formDataMimeType.Length()) {
isValidFormDataMimeType = mMimeType[formDataMimeType.Length()] == ';';
}
if (isValidFormDataMimeType) {
FormDataParser parser(mMimeType, data, DerivedClass()->GetParentObject());
if (!parser.Parse()) {
ErrorResult result;
result.ThrowTypeError(MSG_BAD_FORMDATA);
localPromise->MaybeReject(result);
return;
}
nsRefPtr<nsFormData> fd = parser.FormData();
MOZ_ASSERT(fd);
localPromise->MaybeResolve(fd);
} else {
NS_NAMED_LITERAL_CSTRING(urlDataMimeType, NS_LITERAL_CSTRING("application/x-www-form-urlencoded"));
bool isValidUrlEncodedMimeType = StringBeginsWith(mMimeType, urlDataMimeType);
if (isValidUrlEncodedMimeType && mMimeType.Length() > urlDataMimeType.Length()) {
isValidUrlEncodedMimeType = mMimeType[urlDataMimeType.Length()] == ';';
}
if (isValidUrlEncodedMimeType) {
nsRefPtr<URLSearchParams> params = new URLSearchParams();
params->ParseInput(data, /* aObserver */ nullptr);
nsRefPtr<nsFormData> fd = new nsFormData(DerivedClass()->GetParentObject());
params->ForEach(FillFormData, static_cast<void*>(fd));
localPromise->MaybeResolve(fd);
} else {
ErrorResult result;
result.ThrowTypeError(MSG_BAD_FORMDATA);
localPromise->MaybeReject(result);
}
}
return;
}
case CONSUME_TEXT:
// fall through handles early exit.
case CONSUME_JSON: {
@ -1216,15 +1644,15 @@ FetchBody<Response>::ConsumeBody(ConsumeType aType, ErrorResult& aRv);
template <class Derived>
void
FetchBody<Derived>::SetMimeType(ErrorResult& aRv)
FetchBody<Derived>::SetMimeType()
{
// Extract mime type.
ErrorResult result;
nsTArray<nsCString> contentTypeValues;
MOZ_ASSERT(DerivedClass()->GetInternalHeaders());
DerivedClass()->GetInternalHeaders()->GetAll(NS_LITERAL_CSTRING("Content-Type"), contentTypeValues, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
DerivedClass()->GetInternalHeaders()->GetAll(NS_LITERAL_CSTRING("Content-Type"),
contentTypeValues, result);
MOZ_ALWAYS_TRUE(!result.Failed());
// HTTP ABNF states Content-Type may have only one value.
// This is from the "parse a header value" of the fetch spec.
@ -1236,10 +1664,10 @@ FetchBody<Derived>::SetMimeType(ErrorResult& aRv)
template
void
FetchBody<Request>::SetMimeType(ErrorResult& aRv);
FetchBody<Request>::SetMimeType();
template
void
FetchBody<Response>::SetMimeType(ErrorResult& aRv);
FetchBody<Response>::SetMimeType();
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -113,6 +113,12 @@ public:
return ConsumeBody(CONSUME_BLOB, aRv);
}
already_AddRefed<Promise>
FormData(ErrorResult& aRv)
{
return ConsumeBody(CONSUME_FORMDATA, aRv);
}
already_AddRefed<Promise>
Json(ErrorResult& aRv)
{
@ -154,13 +160,13 @@ protected:
virtual ~FetchBody();
void
SetMimeType(ErrorResult& aRv);
SetMimeType();
private:
enum ConsumeType
{
CONSUME_ARRAYBUFFER,
CONSUME_BLOB,
// FormData not supported right now,
CONSUME_FORMDATA,
CONSUME_JSON,
CONSUME_TEXT,
};

Просмотреть файл

@ -34,6 +34,7 @@ Request::Request(nsIGlobalObject* aOwner, InternalRequest* aRequest)
, mOwner(aOwner)
, mRequest(aRequest)
{
SetMimeType();
}
Request::~Request()
@ -264,7 +265,7 @@ Request::Constructor(const GlobalObject& aGlobal,
}
nsRefPtr<Request> domRequest = new Request(global, request);
domRequest->SetMimeType(aRv);
domRequest->SetMimeType();
return domRequest.forget();
}

Просмотреть файл

@ -38,6 +38,7 @@ Response::Response(nsIGlobalObject* aGlobal, InternalResponse* aInternalResponse
, mOwner(aGlobal)
, mInternalResponse(aInternalResponse)
{
SetMimeType();
}
Response::~Response()
@ -188,7 +189,7 @@ Response::Constructor(const GlobalObject& aGlobal,
}
}
r->SetMimeType(aRv);
r->SetMimeType();
return r.forget();
}

Просмотреть файл

@ -1831,7 +1831,7 @@ HTMLInputElement::SetValue(const nsAString& aValue, ErrorResult& aRv)
}
Sequence<nsString> list;
list.AppendElement(aValue);
MozSetFileNameArray(list);
MozSetFileNameArray(list, aRv);
return;
}
else {
@ -2352,8 +2352,13 @@ HTMLInputElement::MozSetFileArray(const Sequence<OwningNonNull<File>>& aFiles)
}
void
HTMLInputElement::MozSetFileNameArray(const Sequence< nsString >& aFileNames)
HTMLInputElement::MozSetFileNameArray(const Sequence< nsString >& aFileNames, ErrorResult& aRv)
{
if (XRE_GetProcessType() == GeckoProcessType_Content) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return;
}
nsTArray<nsRefPtr<File>> files;
for (uint32_t i = 0; i < aFileNames.Length(); ++i) {
nsCOMPtr<nsIFile> file;
@ -2397,8 +2402,9 @@ HTMLInputElement::MozSetFileNameArray(const char16_t** aFileNames, uint32_t aLen
list.AppendElement(nsDependentString(aFileNames[i]));
}
MozSetFileNameArray(list);
return NS_OK;
ErrorResult rv;
MozSetFileNameArray(list, rv);
return rv.ErrorCode();
}
bool
@ -2445,8 +2451,9 @@ HTMLInputElement::SetUserInput(const nsAString& aValue)
{
Sequence<nsString> list;
list.AppendElement(aValue);
MozSetFileNameArray(list);
return NS_OK;
ErrorResult rv;
MozSetFileNameArray(list, rv);
return rv.ErrorCode();
} else {
nsresult rv = SetValueInternal(aValue, true, true);
NS_ENSURE_SUCCESS(rv, rv);

Просмотреть файл

@ -715,7 +715,7 @@ public:
void MozGetFileNameArray(nsTArray< nsString >& aFileNames);
void MozSetFileNameArray(const Sequence< nsString >& aFileNames);
void MozSetFileNameArray(const Sequence< nsString >& aFileNames, ErrorResult& aRv);
void MozSetFileArray(const Sequence<OwningNonNull<File>>& aFiles);
HTMLInputElement* GetOwnerNumberControl();

Просмотреть файл

@ -39,7 +39,7 @@ skip-if(Android||B2G) == 649134-2.html 649134-2-ref.html
# (Fuzzy necessary due to pixel-wise comparison of different JPEGs.
# The vast majority of the fuzziness comes from Linux and WinXP.)
fuzzy(1,149) == bug917595-iframe-1.html bug917595-1-ref.html
skip-if(B2G) fuzzy-if(!B2G,3,640) == bug917595-exif-rotated.jpg bug917595-pixel-rotated.jpg # bug 1060869
skip-if(B2G||Mulet) fuzzy-if((!B2G&&!Mulet),3,640) == bug917595-exif-rotated.jpg bug917595-pixel-rotated.jpg # bug 1060869 # Bug 1150490 disabling on Mulet as on B2G
# Test support for SVG-as-image in <picture> elements.
pref(dom.image.picture.enabled,true) pref(dom.image.srcset.enabled,true) == bug1106522-1.html bug1106522-ref.html

Просмотреть файл

@ -0,0 +1,6 @@
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.importGlobalProperties(["File"]);
addMessageListener("files.open", function (message) {
sendAsyncMessage("files.opened", message.map(path => new File(path)));
});

Просмотреть файл

@ -68,12 +68,10 @@ skip-if = buildapp == 'mulet'
[test_label_control_attribute.html]
[test_label_input_controls.html]
[test_max_attribute.html]
skip-if = e10s
[test_maxlength_attribute.html]
[test_meter_element.html]
[test_meter_pseudo-classes.html]
[test_min_attribute.html]
skip-if = e10s
[test_mozistextfield.html]
[test_novalidate_attribute.html]
[test_option_disabled.html]
@ -85,14 +83,12 @@ skip-if = e10s
[test_radio_in_label.html]
[test_radio_radionodelist.html]
[test_required_attribute.html]
skip-if = e10s
[test_restore_form_elements.html]
[test_save_restore_radio_groups.html]
[test_select_selectedOptions.html]
[test_select_validation.html]
[test_set_range_text.html]
[test_step_attribute.html]
skip-if = e10s
[test_stepup_stepdown.html]
[test_textarea_attributes_reflection.html]
[test_validation.html]

Просмотреть файл

@ -175,14 +175,9 @@ for (var test of data) {
checkValidity(input, true, apply, apply);
break;
case 'file':
var dirSvc = SpecialPowers.Cc["@mozilla.org/file/directory_service;1"]
.getService(SpecialPowers.Ci.nsIProperties);
var file = dirSvc.get("ProfD", SpecialPowers.Ci.nsIFile);
file.append('635499_file');
// Only the file's path is used, so it doesn't need to be created.
// See also bug 1058977.
var file = new File([''], '635499_file');
SpecialPowers.wrap(input).value = file.path;
SpecialPowers.wrap(input).mozSetFileArray([file]);
checkValidity(input, true, apply, apply);
break;

Просмотреть файл

@ -173,14 +173,9 @@ for (var test of data) {
checkValidity(input, true, apply, apply);
break;
case 'file':
var dirSvc = SpecialPowers.Cc["@mozilla.org/file/directory_service;1"]
.getService(SpecialPowers.Ci.nsIProperties);
var file = dirSvc.get("ProfD", SpecialPowers.Ci.nsIFile);
file.append('635499_file');
// Only the file's path is used, so it doesn't need to be created.
// See also bug 1058977.
var file = new File([''], '635499_file');
SpecialPowers.wrap(input).value = file.path;
SpecialPowers.wrap(input).mozSetFileArray([file]);
checkValidity(input, true, apply, apply);
break;

Просмотреть файл

@ -41,9 +41,12 @@ function completeValidityCheck(element, alwaysValid, isBarred)
} else if (element.type == 'url') {
element.pattern = "http://.*\\.com$";
element.value = "http://mozilla.com";
} else if (element.type == 'file') {
element.pattern = "foo";
SpecialPowers.wrap(element).mozSetFileArray([new File(["foo"], "foo")]);
} else {
element.pattern = "foo";
SpecialPowers.wrap(element).value = "foo";
element.value = "foo";
}
checkValidPattern(element, true, isBarred);
@ -56,9 +59,12 @@ function completeValidityCheck(element, alwaysValid, isBarred)
} else if (element.type == 'url') {
element.pattern = "http://.*\\.com$";
element.value = "http://mozilla.org";
} else if (element.type == 'file') {
element.pattern = "foo";
SpecialPowers.wrap(element).mozSetFileArray([new File(["bar"], "bar")]);
} else {
element.pattern = "foo";
SpecialPowers.wrap(element).value = "bar";
element.value = "bar";
}
if (!alwaysValid) {

Просмотреть файл

@ -314,18 +314,7 @@ function checkInputRequiredValidityForFile()
element.type = 'file'
document.forms[0].appendChild(element);
function createFile(fileName) {
var dirSvc = SpecialPowers.Cc["@mozilla.org/file/directory_service;1"]
.getService(SpecialPowers.Ci.nsIProperties);
var testFile = dirSvc.get("ProfD", SpecialPowers.Ci.nsIFile);
testFile.append(fileName);
// Only the file's path is used, so it doesn't need to be created.
// See also bug 1058977.
return testFile;
}
var file = createFile("345822_file");
var file = new File([""], "345822_file");
SpecialPowers.wrap(element).value = "";
element.required = false;
@ -334,7 +323,7 @@ function checkInputRequiredValidityForFile()
element.required = true;
checkSufferingFromBeingMissing(element, true);
SpecialPowers.wrap(element).value = file.path;
SpecialPowers.wrap(element).mozSetFileArray([file]);
checkNotSufferingFromBeingMissing(element);
SpecialPowers.wrap(element).value = "";
@ -344,7 +333,7 @@ function checkInputRequiredValidityForFile()
checkNotSufferingFromBeingMissing(element);
element.focus();
SpecialPowers.wrap(element).value = file.path;
SpecialPowers.wrap(element).mozSetFileArray([file]);
element.required = true;
element.blur();
element.form.reset();

Просмотреть файл

@ -128,14 +128,9 @@ for (var test of data) {
checkValidity(input, true, apply);
break;
case 'file':
var dirSvc = SpecialPowers.Cc["@mozilla.org/file/directory_service;1"]
.getService(SpecialPowers.Ci.nsIProperties);
var file = dirSvc.get("ProfD", SpecialPowers.Ci.nsIFile);
file.append('635499_file');
// Only the file's path is used, so it doesn't need to be created.
// See also bug 1058977.
var file = new File([''], '635499_file');
SpecialPowers.wrap(input).value = file.path;
SpecialPowers.wrap(input).mozSetFileArray([file]);
checkValidity(input, true, apply);
break;

Просмотреть файл

@ -178,6 +178,7 @@ support-files =
file_srcdoc.html
file_window_open_close_outer.html
file_window_open_close_inner.html
formSubmission_chrome.js
form_submit_server.sjs
formData_worker.js
formData_test.js
@ -459,7 +460,7 @@ skip-if = (toolkit == 'gonk' && debug) || e10s #debug-only failure
[test_embed_attributes_reflection.html]
[test_formData.html]
[test_formSubmission.html]
skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s #TIMED_OUT # b2g(NS_ERROR_FILE_TARGET_DOES_NOT_EXIST) b2g-debug(NS_ERROR_FILE_TARGET_DOES_NOT_EXIST) b2g-desktop(NS_ERROR_FILE_TARGET_DOES_NOT_EXIST)
skip-if = buildapp == 'b2g' || toolkit == 'android' #TIMED_OUT # b2g(NS_ERROR_FILE_TARGET_DOES_NOT_EXIST) b2g-debug(NS_ERROR_FILE_TARGET_DOES_NOT_EXIST) b2g-desktop(NS_ERROR_FILE_TARGET_DOES_NOT_EXIST)
[test_formSubmission2.html]
skip-if = toolkit == 'android'
[test_formelements.html]

Просмотреть файл

@ -18,49 +18,53 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=143220
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
<script class="testbody" type="text/javascript;version=1.7">
/** Test for Bug 143220 **/
var leafName;
var fullPath;
SimpleTest.waitForExplicitFinish();
const helperURL = SimpleTest.getTestFileURL("simpleFileOpener.js");
const helper = SpecialPowers.loadChromeScript(helperURL);
helper.addMessageListener("fail", function onFail(message) {
is(message, null, "chrome script failed");
SimpleTest.finish();
});
helper.addMessageListener("file.opened", onFileOpened);
helper.sendAsyncMessage("file.open", "test_bug143220.txt");
function onFileOpened(message) {
const { leafName, fullPath, domFile } = message;
function initVals() {
var dirSvc = SpecialPowers.Cc["@mozilla.org/file/directory_service;1"]
.getService(SpecialPowers.Ci.nsIProperties);
var file = dirSvc.get("XpcomLib", SpecialPowers.Ci.nsILocalFile);
isnot(file, null, "Must have file here");
function initControl1() {
SpecialPowers.wrap($("i1")).mozSetFileArray([domFile]);
}
leafName = file.leafName;
fullPath = file.path;
function initControl2() {
SpecialPowers.wrap($("i2")).mozSetFileArray([domFile]);
}
// Check that we can't just set the value
try {
$("i1").value = fullPath;
is(0, 1, "Should have thrown exception on set!");
} catch(e) {
is($("i1").value, "", "Shouldn't have value here");
}
initControl1();
initControl2();
is($("i1").value, leafName, "Leaking full value?");
is($("i2").value, leafName, "Leaking full value?");
helper.addMessageListener("file.removed", onFileRemoved);
helper.sendAsyncMessage("file.remove", null);
}
function initControl1() {
SpecialPowers.wrap($("i1")).value = fullPath;
is(SpecialPowers.wrap($("i1")).value, fullPath, "Should have set full path 1");
function onFileRemoved() {
helper.destroy();
SimpleTest.finish();
}
function initControl2() {
SpecialPowers.wrap($("i2")).value = fullPath;
is(SpecialPowers.wrap($("i2")).value, fullPath, "Should have set full path 2");
}
initVals();
// Check that we can't just set the value
try {
$("i1").value = fullPath;
is(0, 1, "Should have thrown exception on set!");
} catch(e) {
is($("i1").value, "", "Shouldn't have value here");
}
initControl1();
initControl2();
is($("i1").value, leafName, "Leaking full value?");
is($("i2").value, leafName, "Leaking full value?");
</script>
</pre>
</body>

Просмотреть файл

@ -399,41 +399,59 @@ t_6_v</textarea>
SimpleTest.waitForExplicitFinish();
var myFile1, myFile2, emptyFile;
const placeholder_myFile1 = {};
const placeholder_myFile2 = {};
const placeholder_emptyFile = {};
(function setFileNames() {
var myFile1, myFile2, emptyFile;
let openerURL = SimpleTest.getTestFileURL("formSubmission_chrome.js");
let opener = SpecialPowers.loadChromeScript(openerURL);
{
let xhr = new XMLHttpRequest;
xhr.open("GET", "/dynamic/getMyDirectory.sjs", false);
xhr.send();
var basePath = xhr.responseText;
let basePath = xhr.responseText;
singleFile = basePath + "file_formSubmission_text.txt";
multiFile = [basePath + "file_formSubmission_text.txt",
basePath + "file_formSubmission_img.jpg"];
opener.addMessageListener("files.opened", onFilesOpened);
opener.sendAsyncMessage("files.open", [
basePath + "file_formSubmission_text.txt",
basePath + "file_formSubmission_img.jpg",
]);
}
function onFilesOpened(files) {
let [textFile, imageFile] = files;
opener.destroy();
let singleFile = textFile;
let multiFile = [textFile, imageFile];
var addList = document.getElementsByClassName("setfile");
let i = 0;
var input;
while (input = addList[i++]) {
if (input.classList.contains("multi")) {
SpecialPowers.wrap(input).mozSetFileNameArray(multiFile, multiFile.length);
SpecialPowers.wrap(input).mozSetFileArray(multiFile);
}
else {
SpecialPowers.wrap(input).value = singleFile;
SpecialPowers.wrap(input).mozSetFileArray([singleFile]);
}
}
input = document.createElement("input");
input.type = "file";
input.multiple = true;
SpecialPowers.wrap(input).mozSetFileNameArray(multiFile, multiFile.length);
SpecialPowers.wrap(input).mozSetFileArray(multiFile);
myFile1 = input.files[0];
myFile2 = input.files[1];
is(myFile1.size, 20, "File1 size");
is(myFile2.size, 2711, "File2 size");
emptyFile = { name: "", type: "application/octet-stream" };
})();
// Now, actually run the tests; see below.
onFilesSet();
};
var expectedSub = [
// Default input
@ -495,13 +513,13 @@ var expectedSub = [
// Reset button
// Unknown button
// File
{ name: "file_1", value: myFile1 },
{ name: "file_2", value: emptyFile },
{ name: "file_1", value: placeholder_myFile1 },
{ name: "file_2", value: placeholder_emptyFile },
// Multiple file
{ name: "file_3", value: myFile1 },
{ name: "file_4", value: myFile1 },
{ name: "file_4", value: myFile2 },
{ name: "file_5", value: emptyFile },
{ name: "file_3", value: placeholder_myFile1 },
{ name: "file_4", value: placeholder_myFile1 },
{ name: "file_4", value: placeholder_myFile2 },
{ name: "file_5", value: placeholder_emptyFile },
// Textarea
{ name: "t1", value: "t_1_v" },
{ name: "t2", value: "" },
@ -562,12 +580,12 @@ var expectedSub = [
{ name: "msel_31", value: "msel_31_v1" },
];
expectedAugment = [
var expectedAugment = [
{ name: "aName", value: "aValue" },
//{ name: "aNameBool", value: "false" },
{ name: "aNameNum", value: "9.2" },
{ name: "aNameFile1", value: myFile1 },
{ name: "aNameFile2", value: myFile2 },
{ name: "aNameFile1", value: placeholder_myFile1 },
{ name: "aNameFile2", value: placeholder_myFile2 },
//{ name: "aNameObj", value: "[object XMLHttpRequest]" },
//{ name: "aNameNull", value: "null" },
//{ name: "aNameUndef", value: "undefined" },
@ -661,10 +679,13 @@ function setDisabled(list, state) {
});
}
var gen = runTest();
addLoadEvent(function() {
gen.next();
});
var gen;
function onFilesSet() {
gen = runTest();
addLoadEvent(function() {
gen.next();
});
}
function runTest() {
// Set up the expectedSub array
@ -676,17 +697,17 @@ function runTest() {
yield undefined; // Wait for both FileReaders. We don't care which order they finish.
yield undefined;
function fileFixup(o) {
if (o.value == myFile1) {
if (o.value === placeholder_myFile1) {
o.value = fileReader1.result;
o.fileName = myFile1.name;
o.contentType = myFile1.type;
}
else if (o.value == myFile2) {
else if (o.value === placeholder_myFile2) {
o.value = fileReader2.result;
o.fileName = myFile2.name;
o.contentType = myFile2.type;
}
else if (o.value == emptyFile) {
else if (o.value === placeholder_emptyFile) {
o.value = "";
o.fileName = emptyFile.name;
o.contentType = emptyFile.type;

Просмотреть файл

@ -1235,13 +1235,14 @@ StartMacOSContentSandbox()
MacSandboxInfo info;
info.type = MacSandboxType_Content;
info.appPath.Assign(appPath);
info.appBinaryPath.Assign(appBinaryPath);
info.appDir.Assign(appDir);
info.level = Preferences::GetInt("security.sandbox.content.level");
info.appPath.assign(appPath.get());
info.appBinaryPath.assign(appBinaryPath.get());
info.appDir.assign(appDir.get());
nsAutoCString err;
std::string err;
if (!mozilla::StartMacSandbox(info, err)) {
NS_WARNING(err.get());
NS_WARNING(err.c_str());
MOZ_CRASH("sandbox_init() failed");
}
}

Просмотреть файл

@ -1579,13 +1579,14 @@ TabParent::RecvNotifyIMEFocus(const bool& aFocus,
nsIMEUpdatePreference* aPreference,
uint32_t* aSeqno)
{
*aSeqno = mIMESeqno;
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) {
*aPreference = nsIMEUpdatePreference();
return true;
}
*aSeqno = mIMESeqno;
mIMETabParent = aFocus ? this : nullptr;
mIMESelectionAnchor = 0;
mIMESelectionFocus = 0;

Просмотреть файл

@ -111,6 +111,12 @@ FAIL_ON_WARNINGS = True
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'
if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_TARGET'] == 'Darwin':
USE_LIBS += [
'mozsandbox',
]
LOCAL_INCLUDES += [
'/caps',
'/chrome',

Просмотреть файл

@ -228,32 +228,31 @@ GetAppPaths(nsCString &aAppPath, nsCString &aAppBinaryPath)
return true;
}
void
GMPChild::StartMacSandbox()
bool
GMPChild::SetMacSandboxInfo()
{
if (!mGMPLoader) {
return false;
}
nsAutoCString pluginDirectoryPath, pluginFilePath;
if (!GetPluginPaths(mPluginPath, pluginDirectoryPath, pluginFilePath)) {
MOZ_CRASH("Error scanning plugin path");
return false;
}
nsAutoCString appPath, appBinaryPath;
if (!GetAppPaths(appPath, appBinaryPath)) {
MOZ_CRASH("Error resolving child process path");
return false;
}
MacSandboxInfo info;
info.type = MacSandboxType_Plugin;
info.pluginInfo.type = MacSandboxPluginType_GMPlugin_Default;
info.pluginInfo.pluginPath.Assign(pluginDirectoryPath);
mPluginBinaryPath.Assign(pluginFilePath);
info.pluginInfo.pluginBinaryPath.Assign(pluginFilePath);
info.appPath.Assign(appPath);
info.appBinaryPath.Assign(appBinaryPath);
info.pluginInfo.pluginPath.assign(pluginDirectoryPath.get());
info.pluginInfo.pluginBinaryPath.assign(pluginFilePath.get());
info.appPath.assign(appPath.get());
info.appBinaryPath.assign(appBinaryPath.get());
nsAutoCString err;
if (!mozilla::StartMacSandbox(info, err)) {
NS_WARNING(err.get());
MOZ_CRASH("sandbox_init() failed");
}
mGMPLoader->SetSandboxInfo(&info);
return true;
}
#endif // XP_MACOSX && MOZ_GMP_SANDBOX
@ -364,24 +363,6 @@ GMPChild::PreLoadLibraries(const std::string& aPluginPath)
}
#endif
#if defined(MOZ_GMP_SANDBOX)
#if defined(XP_MACOSX)
class MacOSXSandboxStarter : public SandboxStarter {
public:
explicit MacOSXSandboxStarter(GMPChild* aGMPChild)
: mGMPChild(aGMPChild)
{}
virtual void Start(const char* aLibPath) override {
mGMPChild->StartMacSandbox();
}
private:
GMPChild* mGMPChild;
};
#endif
#endif // MOZ_GMP_SANDBOX
bool
GMPChild::GetLibPath(nsACString& aOutLibPath)
{
@ -427,8 +408,10 @@ GMPChild::RecvStartPlugin()
}
#if defined(MOZ_GMP_SANDBOX) && defined(XP_MACOSX)
nsAutoPtr<SandboxStarter> starter(new MacOSXSandboxStarter(this));
mGMPLoader->SetStartSandboxStarter(starter);
if (!SetMacSandboxInfo()) {
NS_WARNING("Failed to set Mac GMP sandbox info");
return false;
}
#endif
if (!mGMPLoader->Load(libPath.get(),

Просмотреть файл

@ -44,7 +44,7 @@ public:
void ShutdownComplete() override;
#if defined(XP_MACOSX) && defined(MOZ_GMP_SANDBOX)
void StartMacSandbox();
bool SetMacSandboxInfo();
#endif
private:
@ -89,9 +89,6 @@ private:
MessageLoop* mGMPMessageLoop;
std::string mPluginPath;
std::string mVoucherPath;
#if defined(XP_MACOSX) && defined(MOZ_GMP_SANDBOX)
nsCString mPluginBinaryPath;
#endif
std::string mNodeId;
GMPLoader* mGMPLoader;
nsTArray<uint8_t> mPluginVoucher;

Просмотреть файл

@ -80,10 +80,8 @@ public:
virtual void Shutdown() override;
#ifdef SANDBOX_NOT_STATICALLY_LINKED_INTO_PLUGIN_CONTAINER
virtual void SetStartSandboxStarter(SandboxStarter* aStarter) override {
mSandboxStarter = aStarter;
}
#if defined(XP_MACOSX)
virtual void SetSandboxInfo(MacSandboxInfo* aSandboxInfo) override;
#endif
private:
@ -220,8 +218,8 @@ GMPLoaderImpl::Load(const char* aLibPath,
// Start the sandbox now that we've generated the device bound node id.
// This must happen after the node id is bound to the device id, as
// generating the device id requires privileges.
if (mSandboxStarter) {
mSandboxStarter->Start(aLibPath);
if (mSandboxStarter && !mSandboxStarter->Start(aLibPath)) {
return false;
}
// Load the GMP.
@ -277,6 +275,15 @@ GMPLoaderImpl::Shutdown()
}
}
#if defined(XP_MACOSX)
void
GMPLoaderImpl::SetSandboxInfo(MacSandboxInfo* aSandboxInfo)
{
if (mSandboxStarter) {
mSandboxStarter->SetSandboxInfo(aSandboxInfo);
}
}
#endif
} // namespace gmp
} // namespace mozilla

Просмотреть файл

@ -10,18 +10,24 @@
#include <stdint.h>
#include "gmp-entrypoints.h"
#if defined(XP_MACOSX)
#include "mozilla/Sandbox.h"
#endif
namespace mozilla {
namespace gmp {
class SandboxStarter {
public:
virtual ~SandboxStarter() {}
virtual void Start(const char* aLibPath) = 0;
};
virtual bool Start(const char* aLibPath) = 0;
#if defined(XP_MACOSX)
#define SANDBOX_NOT_STATICALLY_LINKED_INTO_PLUGIN_CONTAINER 1
// On OS X we need to set Mac-specific sandbox info just before we start the
// sandbox, which we don't yet know when the GMPLoader and SandboxStarter
// objects are created.
virtual void SetSandboxInfo(MacSandboxInfo* aSandboxInfo) = 0;
#endif
};
// Encapsulates generating the device-bound node id, activating the sandbox,
// loading the GMP, and passing the node id to the GMP (in that order).
@ -59,10 +65,11 @@ public:
// plugin library.
virtual void Shutdown() = 0;
#ifdef SANDBOX_NOT_STATICALLY_LINKED_INTO_PLUGIN_CONTAINER
// Encapsulates starting the sandbox on Linux and MacOSX.
// TODO: Remove this, and put sandbox in plugin-container on all platforms.
virtual void SetStartSandboxStarter(SandboxStarter* aStarter) = 0;
#if defined(XP_MACOSX)
// On OS X we need to set Mac-specific sandbox info just before we start the
// sandbox, which we don't yet know when the GMPLoader and SandboxStarter
// objects are created.
virtual void SetSandboxInfo(MacSandboxInfo* aSandboxInfo) = 0;
#endif
};

Просмотреть файл

@ -144,9 +144,6 @@ GetStrokeDashData(SVGContentUtils::AutoStrokeOptions* aStrokeOptions,
// stroke to essentially be continuous or to be nonexistent in which case
// we can avoid expensive stroking operations (the underlying platform
// graphics libraries don't seem to optimize for this).
if (totalLengthOfDashes <= 0 && totalLengthOfGaps <= 0) {
return eNoStroke;
}
if (totalLengthOfGaps <= 0) {
return eContinuousStroke;
}

Просмотреть файл

@ -47,40 +47,3 @@ function testScript(script) {
});
}
// Utilities
// =========
// Helper that uses FileReader or FileReaderSync based on context and returns
// a Promise that resolves with the text or rejects with error.
function readAsText(blob) {
if (typeof FileReader !== "undefined") {
return new Promise(function(resolve, reject) {
var fs = new FileReader();
fs.onload = function() {
resolve(fs.result);
}
fs.onerror = reject;
fs.readAsText(blob);
});
} else {
var fs = new FileReaderSync();
return Promise.resolve(fs.readAsText(blob));
}
}
function readAsArrayBuffer(blob) {
if (typeof FileReader !== "undefined") {
return new Promise(function(resolve, reject) {
var fs = new FileReader();
fs.onload = function() {
resolve(fs.result);
}
fs.onerror = reject;
fs.readAsArrayBuffer(blob);
});
} else {
var fs = new FileReaderSync();
return Promise.resolve(fs.readAsArrayBuffer(blob));
}
}

Просмотреть файл

@ -4,9 +4,11 @@ support-files =
test_fetch_basic.js
test_fetch_basic_http.js
test_fetch_cors.js
test_formdataparsing.js
test_headers_common.js
test_request.js
test_response.js
utils.js
worker_wrapper.js
[test_headers.html]
@ -14,5 +16,6 @@ support-files =
[test_fetch_basic.html]
[test_fetch_basic_http.html]
[test_fetch_cors.html]
[test_formdataparsing.html]
[test_request.html]
[test_response.html]

Просмотреть файл

@ -13,6 +13,7 @@
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test"></pre>
<script type="text/javascript" src="utils.js"> </script>
<script type="text/javascript" src="fetch_test_framework.js"> </script>
<script class="testbody" type="text/javascript">
testScript("test_fetch_basic.js");

Просмотреть файл

@ -13,6 +13,7 @@
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test"></pre>
<script type="text/javascript" src="utils.js"> </script>
<script type="text/javascript" src="fetch_test_framework.js"> </script>
<script class="testbody" type="text/javascript">
testScript("test_fetch_basic_http.js");

Просмотреть файл

@ -13,6 +13,7 @@
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test"></pre>
<script type="text/javascript" src="utils.js"> </script>
<script type="text/javascript" src="fetch_test_framework.js"> </script>
<script class="testbody" type="text/javascript">
testScript("test_fetch_cors.js");

Просмотреть файл

@ -0,0 +1,23 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE HTML>
<html>
<head>
<title>Bug 1109751 - Test FormData parsing</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 type="text/javascript" src="utils.js"> </script>
<script type="text/javascript" src="fetch_test_framework.js"> </script>
<script class="testbody" type="text/javascript">
testScript("test_formdataparsing.js");
</script>
</body>
</html>

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше