mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Merge m-c to m-i
This commit is contained in:
commit
69f7ad4a4b
@ -629,7 +629,7 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
||||
|
||||
// Destroy toolboxes for closed window
|
||||
for (let [target, toolbox] of gDevTools._toolboxes) {
|
||||
if (toolbox.frame && toolbox.frame.ownerDocument.defaultView == win) {
|
||||
if (toolbox.win == win) {
|
||||
toolbox.destroy();
|
||||
}
|
||||
}
|
||||
|
@ -201,7 +201,7 @@ function destroyToolbox(toolbox) {
|
||||
toolbox.destroy().then(function () {
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
ok(gDevTools._toolboxes.get(target) == null, "gDevTools doesn't know about target");
|
||||
ok(toolbox._target == null, "toolbox doesn't know about target.");
|
||||
ok(toolbox.target == null, "toolbox doesn't know about target.");
|
||||
finishUp();
|
||||
});
|
||||
}
|
||||
|
@ -39,10 +39,8 @@ function checkToolLoading() {
|
||||
}
|
||||
|
||||
function selectAndCheckById(id) {
|
||||
let doc = toolbox.frame.contentDocument;
|
||||
|
||||
return toolbox.selectTool(id).then(function () {
|
||||
let tab = doc.getElementById("toolbox-tab-" + id);
|
||||
let tab = toolbox.doc.getElementById("toolbox-tab-" + id);
|
||||
is(tab.hasAttribute("selected"), true, "The " + id + " tab is selected");
|
||||
});
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ function toolRegistered(event, toolId)
|
||||
ok(gDevTools.getToolDefinitionMap().has(toolId), "tool added to map");
|
||||
|
||||
// test that it appeared in the UI
|
||||
let doc = toolbox.frame.contentDocument;
|
||||
let doc = toolbox.doc;
|
||||
let tab = doc.getElementById("toolbox-tab-" + toolId);
|
||||
ok(tab, "new tool's tab exists in toolbox UI");
|
||||
|
||||
@ -82,7 +82,7 @@ function toolUnregistered(event, toolDefinition)
|
||||
ok(!gDevTools.getToolDefinitionMap().has(toolId), "tool removed from map");
|
||||
|
||||
// test that it disappeared from the UI
|
||||
let doc = toolbox.frame.contentDocument;
|
||||
let doc = toolbox.doc;
|
||||
let tab = doc.getElementById("toolbox-tab-" + toolId);
|
||||
ok(!tab, "tool's tab was removed from the toolbox UI");
|
||||
|
||||
|
@ -52,8 +52,9 @@ function sendZoomKey(shortcut, times) {
|
||||
}
|
||||
|
||||
function getCurrentZoom() {
|
||||
var contViewer = toolbox.frame.docShell.contentViewer;
|
||||
return contViewer.fullZoom;
|
||||
let windowUtils = toolbox.win.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
return windowUtils.fullZoom;
|
||||
}
|
||||
|
||||
function tidyUp() {
|
||||
|
@ -191,7 +191,7 @@ exports.getHighlighterUtils = function (toolbox) {
|
||||
*/
|
||||
function onPickerNodeCanceled() {
|
||||
stopPicker();
|
||||
toolbox.frame.focus();
|
||||
toolbox.win.focus();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -12,8 +12,8 @@ let url = new window.URL(href);
|
||||
if (url.search.length > 1) {
|
||||
const Cu = Components.utils;
|
||||
const Ci = Components.interfaces;
|
||||
const { gDevTools } = Cu.import("resource://devtools/client/framework/gDevTools.jsm", {});
|
||||
const { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
const { gDevTools } = require("devtools/client/framework/devtools");
|
||||
const { targetFromURL } = require("devtools/client/framework/target-from-url");
|
||||
const { Toolbox } = require("devtools/client/framework/toolbox");
|
||||
const { TargetFactory } = require("devtools/client/framework/target");
|
||||
@ -66,18 +66,7 @@ if (url.search.length > 1) {
|
||||
target = yield targetFromURL(url);
|
||||
}
|
||||
let options = { customIframe: host };
|
||||
let toolbox = yield gDevTools.showToolbox(target, tool, Toolbox.HostType.CUSTOM, options);
|
||||
|
||||
// Watch for toolbox.xul unload in order to cleanup things when we close
|
||||
// about:devtools-toolbox tabs
|
||||
function onUnload() {
|
||||
window.removeEventListener("unload", onUnload);
|
||||
toolbox.destroy();
|
||||
}
|
||||
window.addEventListener("unload", onUnload);
|
||||
toolbox.on("destroy", function () {
|
||||
window.removeEventListener("unload", onUnload);
|
||||
});
|
||||
yield gDevTools.showToolbox(target, tool, Toolbox.HostType.CUSTOM, options);
|
||||
}).catch(error => {
|
||||
console.error("Exception while loading the toolbox", error);
|
||||
});
|
||||
|
@ -108,6 +108,7 @@ const ToolboxButtons = exports.ToolboxButtons = [
|
||||
*/
|
||||
function Toolbox(target, selectedTool, hostType, hostOptions) {
|
||||
this._target = target;
|
||||
this._win = null;
|
||||
this._toolPanels = new Map();
|
||||
this._telemetry = new Telemetry();
|
||||
if (Services.prefs.getBoolPref("devtools.sourcemap.locations.enabled")) {
|
||||
@ -272,25 +273,18 @@ Toolbox.prototype = {
|
||||
return this._host.type;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the iframe containing the toolbox UI.
|
||||
*/
|
||||
get frame() {
|
||||
return this._host.frame;
|
||||
},
|
||||
|
||||
/**
|
||||
* Shortcut to the window containing the toolbox UI
|
||||
*/
|
||||
get win() {
|
||||
return this.frame.contentWindow;
|
||||
return this._win;
|
||||
},
|
||||
|
||||
/**
|
||||
* Shortcut to the document containing the toolbox UI
|
||||
*/
|
||||
get doc() {
|
||||
return this.frame.contentDocument;
|
||||
return this.win.document;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -359,6 +353,8 @@ Toolbox.prototype = {
|
||||
open: function () {
|
||||
return Task.spawn(function* () {
|
||||
let iframe = yield this._host.create();
|
||||
this._win = iframe.contentWindow;
|
||||
|
||||
let domReady = defer();
|
||||
|
||||
// Prevent reloading the document when the toolbox is opened in a tab
|
||||
@ -625,8 +621,17 @@ Toolbox.prototype = {
|
||||
});
|
||||
|
||||
this.doc.addEventListener("keypress", this._splitConsoleOnKeypress, false);
|
||||
|
||||
this.doc.addEventListener("focus", this._onFocus, true);
|
||||
this.win.addEventListener("unload", this.destroy);
|
||||
},
|
||||
|
||||
_removeHostListeners: function () {
|
||||
// The host iframe's contentDocument may already be gone.
|
||||
if (this.doc) {
|
||||
this.doc.removeEventListener("keypress", this._splitConsoleOnKeypress, false);
|
||||
this.doc.removeEventListener("focus", this._onFocus, true);
|
||||
this.win.removeEventListener("unload", this.destroy);
|
||||
}
|
||||
},
|
||||
|
||||
_registerOverlays: function () {
|
||||
@ -1803,7 +1808,7 @@ Toolbox.prototype = {
|
||||
|
||||
// Handle the case where the previous host happens to match the current
|
||||
// host. If so, switch to bottom if it's not already used, and side if not.
|
||||
if (hostType === this._host.type) {
|
||||
if (hostType === this.hostType) {
|
||||
if (hostType === Toolbox.HostType.BOTTOM) {
|
||||
hostType = Toolbox.HostType.SIDE;
|
||||
} else {
|
||||
@ -1822,7 +1827,7 @@ Toolbox.prototype = {
|
||||
* The host type of the new host object
|
||||
*/
|
||||
switchHost: function (hostType) {
|
||||
if (hostType == this._host.type || !this._target.isLocalTab) {
|
||||
if (hostType == this.hostType || !this._target.isLocalTab) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -1838,7 +1843,7 @@ Toolbox.prototype = {
|
||||
return newHost.create().then(iframe => {
|
||||
// change toolbox document's parent to the new host
|
||||
iframe.QueryInterface(Ci.nsIFrameLoaderOwner);
|
||||
iframe.swapFrameLoaders(this.frame);
|
||||
iframe.swapFrameLoaders(this._host.frame);
|
||||
|
||||
this._host.off("window-closed", this.destroy);
|
||||
this.destroyHost();
|
||||
@ -2035,12 +2040,7 @@ Toolbox.prototype = {
|
||||
* @return {promise} to be resolved when the host is destroyed.
|
||||
*/
|
||||
destroyHost: function () {
|
||||
// The host iframe's contentDocument may already be gone.
|
||||
if (this.doc) {
|
||||
this.doc.removeEventListener("keypress",
|
||||
this._splitConsoleOnKeypress, false);
|
||||
this.doc.removeEventListener("focus", this._onFocus, true);
|
||||
}
|
||||
this._removeHostListeners();
|
||||
return this._host.destroy();
|
||||
},
|
||||
|
||||
@ -2127,7 +2127,7 @@ Toolbox.prototype = {
|
||||
this._threadClient = null;
|
||||
|
||||
// We need to grab a reference to win before this._host is destroyed.
|
||||
let win = this.frame.ownerDocument.defaultView;
|
||||
let win = this.win;
|
||||
|
||||
if (this._requisition) {
|
||||
CommandUtils.destroyRequisition(this._requisition, this.target);
|
||||
@ -2143,6 +2143,8 @@ Toolbox.prototype = {
|
||||
.then(() => this.destroyHost())
|
||||
.catch(console.error)
|
||||
.then(() => {
|
||||
this._win = null;
|
||||
|
||||
// Targets need to be notified that the toolbox is being torn down.
|
||||
// This is done after other destruction tasks since it may tear down
|
||||
// fronts and the debugger transport which earlier destroy methods may
|
||||
|
@ -75,7 +75,7 @@ const TOOLBOX_L10N = new LocalizationHelper("devtools/locale/toolbox.properties"
|
||||
*/
|
||||
function InspectorPanel(iframeWindow, toolbox) {
|
||||
this._toolbox = toolbox;
|
||||
this._target = toolbox._target;
|
||||
this._target = toolbox.target;
|
||||
this.panelDoc = iframeWindow.document;
|
||||
this.panelWin = iframeWindow;
|
||||
this.panelWin.inspector = this;
|
||||
|
@ -512,7 +512,7 @@ CssRuleView.prototype = {
|
||||
_onAddRule: function () {
|
||||
let elementStyle = this._elementStyle;
|
||||
let element = elementStyle.element;
|
||||
let client = this.inspector.toolbox._target.client;
|
||||
let client = this.inspector.toolbox.target.client;
|
||||
let pseudoClasses = element.pseudoClassLocks;
|
||||
|
||||
if (!client.traits.addNewRule) {
|
||||
|
@ -54,10 +54,6 @@
|
||||
- tooltip for the button that toggles the promise debugger. -->
|
||||
<!ENTITY debuggerUI.sources.togglePromiseDebugger "Toggle Promise Debugger">
|
||||
|
||||
<!-- LOCALIZATION NOTE (debuggerUI.startTracing): This is the text displayed in
|
||||
- the button to start execution tracing. -->
|
||||
<!ENTITY debuggerUI.startTracing "Start Tracing">
|
||||
|
||||
<!-- LOCALIZATION NOTE (debuggerUI.clearButton): This is the label for
|
||||
- the button that clears the collected tracing data in the tracing tab. -->
|
||||
<!ENTITY debuggerUI.clearButton "Clear">
|
||||
|
@ -30,14 +30,6 @@ pausePendingButtonTooltip=Waiting for next execution
|
||||
# button when the debugger is in a paused state.
|
||||
resumeButtonTooltip=Click to resume (%S)
|
||||
|
||||
# LOCALIZATION NOTE (startTracingTooltip): The label that is displayed on the trace
|
||||
# button when execution tracing is stopped.
|
||||
startTracingTooltip=Click to start tracing
|
||||
|
||||
# LOCALIZATION NOTE (stopTracingTooltip): The label that is displayed on the trace
|
||||
# button when execution tracing is started.
|
||||
stopTracingTooltip=Click to stop tracing
|
||||
|
||||
# LOCALIZATION NOTE (stepOverTooltip): The label that is displayed on the
|
||||
# button that steps over a function call.
|
||||
stepOverTooltip=Step Over (%S)
|
||||
@ -50,10 +42,6 @@ stepInTooltip=Step In (%S)
|
||||
# button that steps out of a function call.
|
||||
stepOutTooltip=Step Out (%S)
|
||||
|
||||
# LOCALIZATION NOTE (emptyGlobalsText): The text to display in the menulist
|
||||
# when there are no chrome globals available.
|
||||
noGlobalsText=No globals
|
||||
|
||||
# LOCALIZATION NOTE (noWorkersText): The text to display in the workers list
|
||||
# when there are no workers.
|
||||
noWorkersText=This page has no workers.
|
||||
@ -62,10 +50,6 @@ noWorkersText=This page has no workers.
|
||||
# when there are no sources.
|
||||
noSourcesText=This page has no sources.
|
||||
|
||||
# LOCALIZATION NOTE (loadingSourcesText): The text to display in the sources menu
|
||||
# when waiting for scripts to load.
|
||||
loadingSourcesText=Waiting for sources…
|
||||
|
||||
# LOCALIZATION NOTE (noEventListenersText): The text to display in the events tab
|
||||
# when there are no events.
|
||||
noEventListenersText=No event listeners to display
|
||||
@ -74,14 +58,6 @@ noEventListenersText=No event listeners to display
|
||||
# when there are no stack frames.
|
||||
noStackFramesText=No stack frames to display
|
||||
|
||||
# LOCALIZATION NOTE (noStackFramesText): The text to display in the traces tab
|
||||
# when there are no function calls.
|
||||
noFunctionCallsText=No function calls to display
|
||||
|
||||
# LOCALIZATION NOTE (tracingNotStartedText): The text to display in the traces tab
|
||||
# when when tracing hasn't started yet.
|
||||
tracingNotStartedText=Tracing has not started
|
||||
|
||||
# LOCALIZATION NOTE (eventCheckboxTooltip): The tooltip text to display when
|
||||
# the user hovers over the checkbox used to toggle an event breakpoint.
|
||||
eventCheckboxTooltip=Toggle breaking on this event
|
||||
@ -140,11 +116,6 @@ noMatchingStringsText=No matches found
|
||||
# filter text box when it is empty and the scripts container is selected.
|
||||
emptySearchText=Search scripts (%S)
|
||||
|
||||
# LOCALIZATION NOTE (emptyChromeGlobalsFilterText): This is the text that
|
||||
# appears in the filter text box when it is empty and the chrome globals
|
||||
# container is selected.
|
||||
emptyChromeGlobalsFilterText=Filter chrome globals (%S)
|
||||
|
||||
# LOCALIZATION NOTE (emptyVariablesFilterText): This is the text that
|
||||
# appears in the filter text box for the variables view container.
|
||||
emptyVariablesFilterText=Filter variables
|
||||
|
@ -9,12 +9,6 @@
|
||||
# A good criteria is the language in which you'd find the best documentation
|
||||
# on web development on the web.
|
||||
|
||||
# LOCALIZATION NOTE (storage.tooltip3):
|
||||
# This string is displayed in the tooltip of the tab when the storage editor is
|
||||
# displayed inside the developer tools window.
|
||||
# A keyboard shortcut for Storage Inspector will be shown inside the brackets.
|
||||
storage.tooltip3=Storage Inspector (Cookies, Local Storage, …) (%S)
|
||||
|
||||
# LOCALIZATION NOTE (storage.filter.key):
|
||||
# Key shortcut used to focus the filter box on top of the data view
|
||||
storage.filter.key=CmdOrCtrl+F
|
||||
|
@ -7,7 +7,7 @@ var toolbox;
|
||||
add_task(function* () {
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
let toolbox = yield gDevTools.showToolbox(target);
|
||||
let doc = toolbox.frame.contentDocument;
|
||||
let doc = toolbox.doc;
|
||||
let root = doc.documentElement;
|
||||
|
||||
let platform = root.getAttribute("platform");
|
||||
|
@ -31,7 +31,7 @@ function CssDocsTooltip(toolbox) {
|
||||
this.widget.on("visitlink", this._onVisitLink);
|
||||
|
||||
// Initialize keyboard shortcuts
|
||||
this.shortcuts = new KeyShortcuts({ window: toolbox.doc.defaultView });
|
||||
this.shortcuts = new KeyShortcuts({ window: toolbox.win });
|
||||
this._onShortcut = this._onShortcut.bind(this);
|
||||
|
||||
this.shortcuts.on("Escape", this._onShortcut);
|
||||
|
@ -65,7 +65,7 @@ add_task(function* () {
|
||||
is(toolbox.getCurrentPanel(), scratchpadPanel,
|
||||
"Clicking link switches to Scratchpad panel");
|
||||
|
||||
is(Services.ww.activeWindow, toolbox.frame.ownerGlobal,
|
||||
is(Services.ww.activeWindow, toolbox.win.parent,
|
||||
"Scratchpad's toolbox is focused");
|
||||
|
||||
Tools.scratchpad.isTargetSupported = isTargetSupported;
|
||||
|
@ -40,14 +40,17 @@ window.onload = function() {
|
||||
hasActor: () => useActor,
|
||||
client: attachmentA.client,
|
||||
form: attachmentA.tab
|
||||
}
|
||||
},
|
||||
// Fake the window for css-properties.js's getClientBrowserVersion to work
|
||||
win: window
|
||||
};
|
||||
const toolboxMockB = {
|
||||
target: {
|
||||
hasActor: () => useActor,
|
||||
client: attachmentB.client,
|
||||
form: attachmentB.tab
|
||||
}
|
||||
},
|
||||
win: window
|
||||
};
|
||||
|
||||
yield initCssProperties(toolboxMockA);
|
||||
|
@ -40,15 +40,7 @@ window.onload = function() {
|
||||
client: attachmentA.client,
|
||||
form: attachmentA.tab,
|
||||
},
|
||||
_host: { frame: { contentWindow: window } }
|
||||
};
|
||||
const toolboxUnknownVersions = {
|
||||
target: {
|
||||
hasActor: () => true,
|
||||
client: attachmentB.client,
|
||||
form: attachmentB.tab
|
||||
}
|
||||
// Don't add a host here.
|
||||
win: window
|
||||
};
|
||||
const toolboxDifferentVersions = {
|
||||
target: {
|
||||
@ -56,9 +48,9 @@ window.onload = function() {
|
||||
client: attachmentB.client,
|
||||
form: attachmentB.tab
|
||||
},
|
||||
_host: { frame: { contentWindow: { navigator: { userAgent:
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:49.0) Gecko/20100101 " +
|
||||
"Firefox/30.0" }}}}
|
||||
win: { navigator: { userAgent:
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:49.0) Gecko/20100101 " +
|
||||
"Firefox/30.0" }}
|
||||
};
|
||||
|
||||
// Modify a property on the static database, to differentiate between a generated
|
||||
@ -66,17 +58,13 @@ window.onload = function() {
|
||||
CSS_PROPERTIES_DB.properties.color.isStatic = true;
|
||||
|
||||
yield initCssProperties(toolboxMatchingVersions);
|
||||
yield initCssProperties(toolboxUnknownVersions);
|
||||
yield initCssProperties(toolboxDifferentVersions);
|
||||
|
||||
const cssPropertiesMatching = getCssProperties(toolboxMatchingVersions);
|
||||
const cssPropertiesUnknown = getCssProperties(toolboxUnknownVersions);
|
||||
const cssPropertiesDifferent = getCssProperties(toolboxDifferentVersions);
|
||||
|
||||
is(cssPropertiesMatching.properties.color.isStatic, true,
|
||||
"The static CSS database is used when the client and platform versions match.");
|
||||
is(cssPropertiesUnknown.properties.color.isStatic, true,
|
||||
"The static CSS database is used when the client is not a known Firefox.");
|
||||
isnot(cssPropertiesDifferent.properties.color.isStatic, undefined,
|
||||
"The generated CSS database is used when the client and platform versions do " +
|
||||
"not match, but the client is a Firefox.");
|
||||
|
@ -192,10 +192,7 @@ function getClientCssProperties() {
|
||||
* @returns {string} The browser version.
|
||||
*/
|
||||
function getClientBrowserVersion(toolbox) {
|
||||
if (!toolbox._host) {
|
||||
return "0";
|
||||
}
|
||||
const regexResult = toolbox._host.frame.contentWindow.navigator
|
||||
const regexResult = toolbox.win.navigator
|
||||
.userAgent.match(/Firefox\/(\d+)\.\d/);
|
||||
return Array.isArray(regexResult) ? regexResult[1] : "0";
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "mozilla/dom/KeyframeEffectBinding.h"
|
||||
#include "mozilla/KeyframeUtils.h"
|
||||
#include "nsDOMMutationObserver.h" // For nsAutoAnimationMutationBatch
|
||||
#include "nsIScriptError.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -125,5 +126,59 @@ KeyframeEffect::SetTarget(const Nullable<ElementOrCSSPseudoElement>& aTarget)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
KeyframeEffect::SetSpacing(JSContext* aCx,
|
||||
const nsAString& aSpacing,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
SpacingMode spacingMode = SpacingMode::distribute;
|
||||
nsCSSPropertyID pacedProperty = eCSSProperty_UNKNOWN;
|
||||
nsAutoString invalidPacedProperty;
|
||||
KeyframeEffectParams::ParseSpacing(aSpacing,
|
||||
spacingMode,
|
||||
pacedProperty,
|
||||
invalidPacedProperty,
|
||||
aRv);
|
||||
if (aRv.Failed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!invalidPacedProperty.IsEmpty()) {
|
||||
const char16_t* params[] = { invalidPacedProperty.get() };
|
||||
nsIDocument* doc = AnimationUtils::GetCurrentRealmDocument(aCx);
|
||||
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
|
||||
NS_LITERAL_CSTRING("Animation"),
|
||||
doc,
|
||||
nsContentUtils::eDOM_PROPERTIES,
|
||||
"UnanimatablePacedProperty",
|
||||
params, ArrayLength(params));
|
||||
}
|
||||
|
||||
if (mEffectOptions.mSpacingMode == spacingMode &&
|
||||
mEffectOptions.mPacedProperty == pacedProperty) {
|
||||
return;
|
||||
}
|
||||
|
||||
mEffectOptions.mSpacingMode = spacingMode;
|
||||
mEffectOptions.mPacedProperty = pacedProperty;
|
||||
|
||||
// Apply spacing. We apply distribute here. If the new spacing is paced,
|
||||
// UpdateProperties() will apply it.
|
||||
if (mEffectOptions.mSpacingMode == SpacingMode::distribute) {
|
||||
KeyframeUtils::ApplyDistributeSpacing(mKeyframes);
|
||||
}
|
||||
|
||||
if (mAnimation && mAnimation->IsRelevant()) {
|
||||
nsNodeUtils::AnimationChanged(mAnimation);
|
||||
}
|
||||
|
||||
if (mTarget) {
|
||||
RefPtr<nsStyleContext> styleContext = GetTargetStyleContext();
|
||||
if (styleContext) {
|
||||
UpdateProperties(styleContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -65,6 +65,8 @@ public:
|
||||
// that to update the properties rather than calling
|
||||
// GetStyleContextForElement.
|
||||
void SetTarget(const Nullable<ElementOrCSSPseudoElement>& aTarget);
|
||||
|
||||
void SetSpacing(JSContext* aCx, const nsAString& aSpacing, ErrorResult& aRv);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -1896,6 +1896,73 @@ addAsyncAnimTest("set_effect_with_previous_animation",
|
||||
yield await_frame();
|
||||
});
|
||||
|
||||
addAsyncAnimTest("set_spacing",
|
||||
{ observe: div, subtree: true }, function*() {
|
||||
var anim = div.animate([ { marginLeft: "0px" },
|
||||
{ marginLeft: "-20px" },
|
||||
{ marginLeft: "100px" },
|
||||
{ marginLeft: "50px" } ],
|
||||
{ duration: 100 * MS_PER_SEC });
|
||||
yield await_frame();
|
||||
assert_records([{ added: [anim], changed: [], removed: [] }],
|
||||
"records after animation is added");
|
||||
|
||||
anim.effect.spacing = "paced(margin-left)";
|
||||
yield await_frame();
|
||||
assert_records([{ added: [], changed: [anim], removed: [] }],
|
||||
"records after animation is changed");
|
||||
|
||||
anim.cancel();
|
||||
yield await_frame();
|
||||
assert_records([{ added: [], changed: [], removed: [anim] }],
|
||||
"records after animation end");
|
||||
});
|
||||
|
||||
addAsyncAnimTest("set_spacing_on_a_non-animatable_property",
|
||||
{ observe: div, subtree: true }, function*() {
|
||||
var anim = div.animate([ { marginLeft: "0px" },
|
||||
{ marginLeft: "-20px" },
|
||||
{ marginLeft: "100px" },
|
||||
{ marginLeft: "50px" } ],
|
||||
{ duration: 100 * MS_PER_SEC,
|
||||
spacing: "paced(margin-left)" });
|
||||
yield await_frame();
|
||||
assert_records([{ added: [anim], changed: [], removed: [] }],
|
||||
"records after animation is added");
|
||||
|
||||
anim.effect.spacing = "paced(animation-duration)";
|
||||
yield await_frame();
|
||||
assert_records([{ added: [], changed: [anim], removed: [] }],
|
||||
"records after setting a non-animatable paced property");
|
||||
|
||||
anim.cancel();
|
||||
yield await_frame();
|
||||
assert_records([{ added: [], changed: [], removed: [anim] }],
|
||||
"records after animation end");
|
||||
});
|
||||
|
||||
addAsyncAnimTest("set_the_same_spacing",
|
||||
{ observe: div, subtree: true }, function*() {
|
||||
var anim = div.animate([ { marginLeft: "0px" },
|
||||
{ marginLeft: "-20px" },
|
||||
{ marginLeft: "100px" },
|
||||
{ marginLeft: "50px" } ],
|
||||
{ duration: 100 * MS_PER_SEC,
|
||||
spacing: "paced(margin-left)" });
|
||||
yield await_frame();
|
||||
assert_records([{ added: [anim], changed: [], removed: [] }],
|
||||
"records after animation is added");
|
||||
|
||||
anim.effect.spacing = "paced(margin-left)";
|
||||
yield await_frame();
|
||||
assert_records([], "no record after setting the same spacing");
|
||||
|
||||
anim.cancel();
|
||||
yield await_frame();
|
||||
assert_records([{ added: [], changed: [], removed: [anim] }],
|
||||
"records after animation end");
|
||||
});
|
||||
|
||||
// Run the tests.
|
||||
SimpleTest.requestLongerTimeout(2);
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
@ -48,6 +48,7 @@ support-files =
|
||||
style/file_animation-seeking-with-current-time.html
|
||||
style/file_animation-seeking-with-start-time.html
|
||||
style/file_animation-setting-effect.html
|
||||
style/file_animation-setting-spacing.html
|
||||
testcommon.js
|
||||
|
||||
[css-animations/test_animations-dynamic-changes.html]
|
||||
@ -101,3 +102,4 @@ skip-if = (toolkit == 'gonk' && debug)
|
||||
[style/test_animation-seeking-with-current-time.html]
|
||||
[style/test_animation-seeking-with-start-time.html]
|
||||
[style/test_animation-setting-effect.html]
|
||||
[style/test_animation-setting-spacing.html]
|
||||
|
111
dom/animation/test/style/file_animation-setting-spacing.html
Normal file
111
dom/animation/test/style/file_animation-setting-spacing.html
Normal file
@ -0,0 +1,111 @@
|
||||
<!doctype html>
|
||||
<head>
|
||||
<meta charset=utf-8>
|
||||
<title>Tests for setting spacing by using KeyframeEffect.spacing</title>
|
||||
<script src='../testcommon.js'></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
function calculateInterpolation(pacedDistances, values, progress) {
|
||||
if (progress == 0.0) {
|
||||
return values[0];
|
||||
} else if (progress == 1.0) {
|
||||
return values[valus.length - 1];
|
||||
}
|
||||
|
||||
const cumDist = pacedDistances.reduce( (prev, curr) => {
|
||||
prev.push(prev.length == 0 ? curr : curr + prev[prev.length - 1]);
|
||||
return prev;
|
||||
}, []);
|
||||
|
||||
const last = cumDist[cumDist.length - 1];
|
||||
const offsets = cumDist.map( (curr) => { return curr / last; } );
|
||||
|
||||
let idx = 0;
|
||||
for (let i = 0; i < offsets.length - 1; ++i) {
|
||||
if (progress >= offsets[i] && progress < offsets[i + 1]) {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const ratio = (progress - offsets[idx]) / (offsets[idx + 1] - offsets[idx]);
|
||||
return values[idx] + ratio * (values[idx + 1] - values[idx]) + 'px';
|
||||
}
|
||||
|
||||
promise_test(function(t) {
|
||||
var target = addDiv(t);
|
||||
var anim = target.animate([ { marginLeft: '0px' },
|
||||
{ marginLeft: '-20px' },
|
||||
{ marginLeft: '100px' },
|
||||
{ marginLeft: '50px' } ],
|
||||
100 * MS_PER_SEC);
|
||||
|
||||
return anim.ready.then(function() {
|
||||
anim.currentTime = 50 * MS_PER_SEC;
|
||||
assert_equals(getComputedStyle(target).marginLeft, '40px',
|
||||
'computed value before setting a new spacing');
|
||||
|
||||
var dist = [0, 20, 120, 50];
|
||||
var marginLeftValues = [0, -20, 100, 50];
|
||||
anim.effect.spacing = 'paced(margin-left)';
|
||||
assert_equals(getComputedStyle(target).marginLeft,
|
||||
calculateInterpolation(dist, marginLeftValues, 0.5),
|
||||
'computed value after setting a new spacing');
|
||||
});
|
||||
}, 'Test for setting spacing from distribute to paced');
|
||||
|
||||
promise_test(function(t) {
|
||||
var target = addDiv(t);
|
||||
var anim = target.animate([ { marginLeft: '0px' },
|
||||
{ marginLeft: '-20px' },
|
||||
{ marginLeft: '100px' },
|
||||
{ marginLeft: '50px' } ],
|
||||
{ duration: 100 * MS_PER_SEC,
|
||||
spacing: 'paced(margin-left)' });
|
||||
|
||||
return anim.ready.then(function() {
|
||||
var dist = [0, 20, 120, 50];
|
||||
var marginLeftValues = [0, -20, 100, 50];
|
||||
anim.currentTime = 50 * MS_PER_SEC;
|
||||
assert_equals(getComputedStyle(target).marginLeft,
|
||||
calculateInterpolation(dist, marginLeftValues, 0.5),
|
||||
'computed value before setting a new spacing');
|
||||
|
||||
anim.effect.spacing = 'distribute';
|
||||
assert_equals(getComputedStyle(target).marginLeft, '40px',
|
||||
'computed value after setting a new spacing');
|
||||
});
|
||||
}, 'Test for setting spacing from paced to distribute');
|
||||
|
||||
promise_test(function(t) {
|
||||
var target = addDiv(t);
|
||||
var anim =
|
||||
target.animate([ { marginLeft: '0px', borderRadius: '0%' },
|
||||
{ marginLeft: '-20px', borderRadius: '50%' },
|
||||
{ marginLeft: '100px', borderRadius: '25%' },
|
||||
{ marginLeft: '50px', borderRadius: '100%' } ],
|
||||
{ duration: 100 * MS_PER_SEC,
|
||||
spacing: 'paced(margin-left)' });
|
||||
|
||||
return anim.ready.then(function() {
|
||||
var dist = [0, 20, 120, 50];
|
||||
var marginLeftValues = [0, -20, 100, 50];
|
||||
anim.currentTime = 50 * MS_PER_SEC;
|
||||
assert_equals(getComputedStyle(target).marginLeft,
|
||||
calculateInterpolation(dist, marginLeftValues, 0.5),
|
||||
'computed value before setting a new spacing');
|
||||
|
||||
dist = [0, 50, 25, 75];
|
||||
anim.effect.spacing = 'paced(border-radius)';
|
||||
assert_equals(getComputedStyle(target).marginLeft,
|
||||
calculateInterpolation(dist, marginLeftValues, 0.5),
|
||||
'computed value after setting a new spacing');
|
||||
});
|
||||
}, 'Test for setting spacing from paced to a different paced');
|
||||
|
||||
done();
|
||||
</script>
|
||||
</body>
|
14
dom/animation/test/style/test_animation-setting-spacing.html
Normal file
14
dom/animation/test/style/test_animation-setting-spacing.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<script src='/resources/testharness.js'></script>
|
||||
<script src='/resources/testharnessreport.js'></script>
|
||||
<div id='log'></div>
|
||||
<script>
|
||||
'use strict';
|
||||
setup({explicit_done: true});
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{ 'set': [['dom.animations-api.core.enabled', true]]},
|
||||
function() {
|
||||
window.open('file_animation-setting-spacing.html');
|
||||
});
|
||||
</script>
|
@ -624,6 +624,10 @@ DOMInterfaces = {
|
||||
'concrete': False
|
||||
},
|
||||
|
||||
'KeyframeEffect': {
|
||||
'implicitJSContext': { 'setterOnly': [ 'spacing' ] }
|
||||
},
|
||||
|
||||
'LegacyMozTCPSocket': {
|
||||
'headerFile': 'TCPSocket.h',
|
||||
'wrapperCache': False,
|
||||
|
@ -73,8 +73,8 @@ interface KeyframeEffect : KeyframeEffectReadOnly {
|
||||
// inherit attribute IterationCompositeOperation iterationComposite;
|
||||
// Bug 1216844 - implement additive animation
|
||||
// inherit attribute CompositeOperation composite;
|
||||
// Bug 1244590 - implement spacing modes
|
||||
// inherit attribute DOMString spacing;
|
||||
[SetterThrows]
|
||||
inherit attribute DOMString spacing;
|
||||
[Throws]
|
||||
void setKeyframes (object? keyframes);
|
||||
};
|
||||
|
@ -6513,10 +6513,7 @@ nsCSSFrameConstructor::IsValidSibling(nsIFrame* aSibling,
|
||||
StyleDisplay& aDisplay)
|
||||
{
|
||||
nsIFrame* parentFrame = aSibling->GetParent();
|
||||
nsIAtom* parentType = nullptr;
|
||||
if (parentFrame) {
|
||||
parentType = parentFrame->GetType();
|
||||
}
|
||||
nsIAtom* parentType = parentFrame->GetType();
|
||||
|
||||
StyleDisplay siblingDisplay = aSibling->GetDisplay();
|
||||
if (StyleDisplay::TableColumnGroup == siblingDisplay ||
|
||||
|
@ -3036,6 +3036,30 @@ nsCSSRendering::PaintGradient(nsPresContext* aPresContext,
|
||||
}
|
||||
}
|
||||
|
||||
static CompositionOp
|
||||
DetermineCompositionOp(const nsCSSRendering::PaintBGParams& aParams,
|
||||
const nsStyleImageLayers& aLayers,
|
||||
uint32_t aLayerIndex)
|
||||
{
|
||||
if (aParams.layer >= 0) {
|
||||
// When drawing a single layer, use the specified composition op.
|
||||
return aParams.compositionOp;
|
||||
}
|
||||
|
||||
const nsStyleImageLayers::Layer& layer = aLayers.mLayers[aLayerIndex];
|
||||
// When drawing all layers, get the compositon op from each image layer.
|
||||
if (aParams.paintFlags & nsCSSRendering::PAINTBG_MASK_IMAGE) {
|
||||
// Always using OP_OVER mode while drawing the bottom mask layer.
|
||||
if (aLayerIndex == (aLayers.mImageCount - 1)) {
|
||||
return CompositionOp::OP_OVER;
|
||||
}
|
||||
|
||||
return nsCSSRendering::GetGFXCompositeMode(layer.mComposite);
|
||||
}
|
||||
|
||||
return nsCSSRendering::GetGFXBlendMode(layer.mBlendMode);
|
||||
}
|
||||
|
||||
DrawResult
|
||||
nsCSSRendering::PaintBackgroundWithSC(const PaintBGParams& aParams,
|
||||
nsStyleContext *aBackgroundSC,
|
||||
@ -3226,21 +3250,14 @@ nsCSSRendering::PaintBackgroundWithSC(const PaintBGParams& aParams,
|
||||
}
|
||||
if ((aParams.layer < 0 || i == (uint32_t)startLayer) &&
|
||||
!clipState.mDirtyRectGfx.IsEmpty()) {
|
||||
// When we're drawing a single layer, use the specified composition op,
|
||||
// otherwise get the compositon op from the image layer.
|
||||
CompositionOp co = (aParams.layer >= 0) ? aParams.compositionOp :
|
||||
(paintMask ? GetGFXCompositeMode(layer.mComposite) :
|
||||
GetGFXBlendMode(layer.mBlendMode));
|
||||
CompositionOp co = DetermineCompositionOp(aParams, layers, i);
|
||||
nsBackgroundLayerState state =
|
||||
PrepareImageLayer(&aParams.presCtx, aParams.frame,
|
||||
aParams.paintFlags, paintBorderArea, clipState.mBGClipArea,
|
||||
layer, nullptr, co);
|
||||
layer, nullptr);
|
||||
result &= state.mImageRenderer.PrepareResult();
|
||||
if (!state.mFillArea.IsEmpty()) {
|
||||
// Always using OP_OVER mode while drawing the bottom mask layer.
|
||||
bool isBottomMaskLayer = paintMask ?
|
||||
(i == (layers.mImageCount - 1)) : false;
|
||||
if (co != CompositionOp::OP_OVER && !isBottomMaskLayer) {
|
||||
if (co != CompositionOp::OP_OVER) {
|
||||
NS_ASSERTION(ctx->CurrentOp() == CompositionOp::OP_OVER,
|
||||
"It is assumed the initial op is OP_OVER, when it is restored later");
|
||||
ctx->SetOp(co);
|
||||
@ -3512,8 +3529,7 @@ nsCSSRendering::PrepareImageLayer(nsPresContext* aPresContext,
|
||||
const nsRect& aBorderArea,
|
||||
const nsRect& aBGClipRect,
|
||||
const nsStyleImageLayers::Layer& aLayer,
|
||||
bool* aOutIsTransformedFixed,
|
||||
CompositionOp aCompositonOp)
|
||||
bool* aOutIsTransformedFixed)
|
||||
{
|
||||
/*
|
||||
* The properties we need to keep in mind when drawing style image
|
||||
|
@ -551,8 +551,7 @@ struct nsCSSRendering {
|
||||
const nsRect& aBorderArea,
|
||||
const nsRect& aBGClipRect,
|
||||
const nsStyleImageLayers::Layer& aLayer,
|
||||
bool* aOutIsTransformedFixed = nullptr,
|
||||
CompositionOp aCompositionOp = CompositionOp::OP_OVER);
|
||||
bool* aOutIsTransformedFixed = nullptr);
|
||||
|
||||
struct ImageLayerClipState {
|
||||
nsRect mBGClipArea; // Affected by mClippedRadii
|
||||
|
@ -3356,10 +3356,7 @@ public class BrowserApp extends GeckoApp
|
||||
|
||||
String url = tab.getURL();
|
||||
if (AboutPages.isAboutReader(url)) {
|
||||
String urlFromReader = ReaderModeUtils.getUrlFromAboutReader(url);
|
||||
if (urlFromReader != null) {
|
||||
url = urlFromReader;
|
||||
}
|
||||
url = ReaderModeUtils.stripAboutReaderUrl(url);
|
||||
}
|
||||
|
||||
// Disable share menuitem for about:, chrome:, file:, and resource: URIs
|
||||
@ -3538,9 +3535,7 @@ public class BrowserApp extends GeckoApp
|
||||
if (tab != null) {
|
||||
String url = tab.getURL();
|
||||
if (url != null) {
|
||||
if (AboutPages.isAboutReader(url)) {
|
||||
url = ReaderModeUtils.getUrlFromAboutReader(url);
|
||||
}
|
||||
url = ReaderModeUtils.stripAboutReaderUrl(url);
|
||||
|
||||
// Context: Sharing via chrome list (no explicit session is active)
|
||||
Telemetry.sendUIEvent(TelemetryContract.Event.SHARE, TelemetryContract.Method.LIST, "menu");
|
||||
|
@ -745,16 +745,15 @@ public class Tabs implements GeckoEventListener {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (AboutPages.isAboutReader(url)) {
|
||||
url = ReaderModeUtils.getUrlFromAboutReader(url);
|
||||
}
|
||||
url = ReaderModeUtils.stripAboutReaderUrl(url);
|
||||
|
||||
for (Tab tab : mOrder) {
|
||||
if (isPrivate != tab.isPrivate()) {
|
||||
continue;
|
||||
}
|
||||
String tabUrl = tab.getURL();
|
||||
if (AboutPages.isAboutReader(tabUrl)) {
|
||||
tabUrl = ReaderModeUtils.getUrlFromAboutReader(tabUrl);
|
||||
tabUrl = ReaderModeUtils.stripAboutReaderUrl(tabUrl);
|
||||
if (url.equals(tabUrl)) {
|
||||
return tab;
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ public class ReaderModeUtils {
|
||||
* URLs.
|
||||
* @return <code>null</code> if the URL is malformed or doesn't contain a URL parameter.
|
||||
*/
|
||||
public static String getUrlFromAboutReader(String aboutReaderUrl) {
|
||||
private static String getUrlFromAboutReader(String aboutReaderUrl) {
|
||||
return StringUtils.getQueryParameter(aboutReaderUrl, "url");
|
||||
}
|
||||
|
||||
@ -45,6 +45,12 @@ public class ReaderModeUtils {
|
||||
return getAboutReaderForUrl(url, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the underlying URL from an about:reader URL.
|
||||
* This will return the input URL if either of the following is true:
|
||||
* 1. the input URL is a non about:reader URL
|
||||
* 2. the input URL is an invalid/unparseable about:reader URL
|
||||
*/
|
||||
public static String stripAboutReaderUrl(String url) {
|
||||
if (!AboutPages.isAboutReader(url)) {
|
||||
return url;
|
||||
|
@ -37856,6 +37856,12 @@
|
||||
"url": "/web-animations/interfaces/Animation/effect.html"
|
||||
}
|
||||
],
|
||||
"web-animations/interfaces/KeyframeEffect/spacing.html": [
|
||||
{
|
||||
"path": "web-animations/interfaces/KeyframeEffect/spacing.html",
|
||||
"url": "/web-animations/interfaces/KeyframeEffect/spacing.html"
|
||||
}
|
||||
],
|
||||
"web-animations/timing-model/animation-effects/phases-and-states.html": [
|
||||
{
|
||||
"path": "web-animations/timing-model/animation-effects/phases-and-states.html",
|
||||
|
@ -322,7 +322,70 @@ test(function(t) {
|
||||
'and falling back to distribute spacing for the reset with some specific ' +
|
||||
'offsets');
|
||||
|
||||
// Bug 1276193: Test for mixing percent and pixel values.
|
||||
// Tests for setting spacing by KeyframeEffect.spacing.
|
||||
|
||||
test(function(t) {
|
||||
var anim = createDiv(t).animate([ { marginLeft: '0px' },
|
||||
{ marginLeft: '-20px' },
|
||||
{ marginLeft: '100px' },
|
||||
{ marginLeft: '50px' } ],
|
||||
{ duration: 100 * MS_PER_SEC });
|
||||
|
||||
anim.effect.spacing = 'paced(margin-left)';
|
||||
|
||||
var frames = anim.effect.getKeyframes();
|
||||
var cumDist = [0, 20, 140, 190];
|
||||
assert_equals(frames[0].computedOffset, 0.0,
|
||||
'1st frame offset');
|
||||
assert_equals(frames[1].computedOffset, cumDist[1] / cumDist[3],
|
||||
'2nd frame offset');
|
||||
assert_equals(frames[2].computedOffset, cumDist[2] / cumDist[3],
|
||||
'3rd frame offset');
|
||||
assert_equals(frames[3].computedOffset, 1.0,
|
||||
'last frame offset');
|
||||
}, 'Test paced spacing by setter');
|
||||
|
||||
test(function(t) {
|
||||
var anim = createDiv(t).animate([ { marginLeft: '0px' },
|
||||
{ marginLeft: '-20px' },
|
||||
{ marginLeft: '100px' },
|
||||
{ marginLeft: '50px' } ],
|
||||
{ duration: 100 * MS_PER_SEC,
|
||||
spacing: 'paced(margin-left)' });
|
||||
|
||||
anim.effect.spacing = 'distribute';
|
||||
|
||||
var frames = anim.effect.getKeyframes();
|
||||
var slots = frames.length - 1;
|
||||
assert_equals(frames[0].computedOffset, 0.0, '1st frame offset');
|
||||
assert_equals(frames[1].computedOffset, 1.0 / slots, '2nd frame offset');
|
||||
assert_equals(frames[2].computedOffset, 2.0 / slots, '3rd frame offset');
|
||||
assert_equals(frames[3].computedOffset, 1.0, 'last frame offset');
|
||||
}, 'Test distribute spacing by setter');
|
||||
|
||||
test(function(t) {
|
||||
var anim =
|
||||
createDiv(t).animate([ { marginLeft: '0px', borderRadius: '0%' },
|
||||
{ marginLeft: '-20px', borderRadius: '50%' },
|
||||
{ marginLeft: '100px', borderRadius: '25%' },
|
||||
{ marginLeft: '50px', borderRadius: '100%' } ],
|
||||
{ duration: 100 * MS_PER_SEC,
|
||||
spacing: 'paced(margin-left)' });
|
||||
|
||||
anim.effect.spacing = 'paced(border-radius)';
|
||||
|
||||
var frames = anim.effect.getKeyframes();
|
||||
var cumDist = [0, 50, 50 + 25, 50 + 25 + 75];
|
||||
|
||||
assert_equals(frames[0].computedOffset, 0.0,
|
||||
'1st frame offset');
|
||||
assert_equals(frames[1].computedOffset, cumDist[1] / cumDist[3],
|
||||
'2nd frame offset');
|
||||
assert_equals(frames[2].computedOffset, cumDist[2] / cumDist[3],
|
||||
'3rd frame offset');
|
||||
assert_equals(frames[3].computedOffset, 1.0,
|
||||
'last frame offset');
|
||||
}, 'Test paced spacing by changing the paced property');
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
@ -0,0 +1,60 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>KeyframeEffect spacing attribute tests</title>
|
||||
<link rel="help"
|
||||
href="https://w3c.github.io/web-animations/#dom-keyframeeffect-spacing">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../../testcommon.js"></script>
|
||||
<body>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
test(function(t) {
|
||||
var anim = createDiv(t).animate(null);
|
||||
assert_throws(new TypeError, function() {
|
||||
anim.effect.spacing = '';
|
||||
});
|
||||
}, 'Test throwing TypeError if using empty string');
|
||||
|
||||
test(function(t) {
|
||||
var anim = createDiv(t).animate(null);
|
||||
assert_throws(new TypeError, function() {
|
||||
anim.effect.spacing = 'dist';
|
||||
});
|
||||
}, 'Test throwing TypeError if not using the correct keyword');
|
||||
|
||||
test(function(t) {
|
||||
var anim = createDiv(t).animate(null);
|
||||
anim.effect.spacing = 'paced(A)';
|
||||
assert_equals(anim.effect.spacing, 'distribute', 'spacing mode');
|
||||
}, 'Test falling back to distribute spacing if using a unrecognized property');
|
||||
|
||||
test(function(t) {
|
||||
var anim = createDiv(t).animate(null);
|
||||
anim.effect.spacing = 'paced(--bg-color)';
|
||||
assert_equals(anim.effect.spacing, 'distribute', 'spacing mode');
|
||||
}, 'Test falling back to distribute spacing if using CSS variables');
|
||||
|
||||
test(function(t) {
|
||||
var anim = createDiv(t).animate(null);
|
||||
anim.effect.spacing = 'paced(animation-duration)';
|
||||
assert_equals(anim.effect.spacing, 'distribute', 'spacing mode');
|
||||
}, 'Test falling back to distribute spacing if using a non-animatable ' +
|
||||
'property');
|
||||
|
||||
test(function(t) {
|
||||
var anim = createDiv(t).animate(null);
|
||||
anim.effect.spacing = 'distribute';
|
||||
assert_equals(anim.effect.spacing, 'distribute', 'spacing mode');
|
||||
}, 'Test spacing value if setting distribute');
|
||||
|
||||
test(function(t) {
|
||||
var anim = createDiv(t).animate(null);
|
||||
anim.effect.spacing = 'paced(transform)';
|
||||
assert_equals(anim.effect.spacing, 'paced(transform)', 'spacing mode');
|
||||
}, 'Test spacing value if setting paced');
|
||||
|
||||
</script>
|
||||
</body>
|
@ -50,7 +50,7 @@ SpecialPowers.pushPrefEnv(
|
||||
["urlclassifier.phishTable", "test-phish-simple"]]},
|
||||
function() {
|
||||
classifierHelper.waitForInit()
|
||||
.then(() => { classifierHelper.addUrlToDB(testData); })
|
||||
.then(() => classifierHelper.addUrlToDB(testData))
|
||||
.then(updateSuccess)
|
||||
.catch(err => {
|
||||
updateError(err);
|
||||
|
@ -57,7 +57,7 @@ SpecialPowers.pushPrefEnv(
|
||||
["urlclassifier.phishTable", "test-phish-simple"]]},
|
||||
function() {
|
||||
classifierHelper.waitForInit()
|
||||
.then(() => { classifierHelper.addUrlToDB(testData); })
|
||||
.then(() => classifierHelper.addUrlToDB(testData))
|
||||
.then(updateSuccess)
|
||||
.catch(err => {
|
||||
updateError(err);
|
||||
|
Loading…
Reference in New Issue
Block a user