зеркало из https://github.com/mozilla/gecko-dev.git
Коммит
10292980d7
|
@ -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=∞
|
|||
# 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>
|
||||
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче