diff --git a/accessible/jsat/AccessFu.jsm b/accessible/jsat/AccessFu.jsm index d87962ac3d85..30704eccc358 100644 --- a/accessible/jsat/AccessFu.jsm +++ b/accessible/jsat/AccessFu.jsm @@ -569,25 +569,12 @@ var Output = { } }, - get androidBridge() { - delete this.androidBridge; - if (Utils.MozBuildApp === 'mobile/android') { - this.androidBridge = Services.androidBridge; - } else { - this.androidBridge = null; - } - return this.androidBridge; - }, - Android: function Android(aDetails, aBrowser) { const ANDROID_VIEW_TEXT_CHANGED = 0x10; const ANDROID_VIEW_TEXT_SELECTION_CHANGED = 0x2000; - if (!this.androidBridge) { - return; - } - for (let androidEvent of aDetails) { + androidEvent.type = 'Accessibility:Event'; if (androidEvent.bounds) { androidEvent.bounds = AccessFu.adjustContentBounds( androidEvent.bounds, aBrowser); @@ -607,9 +594,8 @@ var Output = { androidEvent.brailleOutput); break; } - let win = Utils.win; - let view = win && win.QueryInterface(Ci.nsIAndroidView); - view.dispatch('Accessibility:Event', androidEvent); + + Utils.win.WindowEventDispatcher.sendRequest(androidEvent); } }, @@ -805,9 +791,7 @@ var Input = { if (Utils.MozBuildApp == 'mobile/android') { // Return focus to native Android browser chrome. - let win = Utils.win; - let view = win && win.QueryInterface(Ci.nsIAndroidView); - view.dispatch('ToggleChrome:Focus'); + Utils.win.WindowEventDispatcher.dispatch('ToggleChrome:Focus'); } break; case aEvent.DOM_VK_RETURN: diff --git a/accessible/jsat/Presentation.jsm b/accessible/jsat/Presentation.jsm index 6912d0ea58d6..c7d4162b7149 100644 --- a/accessible/jsat/Presentation.jsm +++ b/accessible/jsat/Presentation.jsm @@ -315,7 +315,7 @@ AndroidPresenter.prototype.actionInvoked = // Checkable objects use TalkBack's text derived from the event state, // so we don't populate the text here. - let text = ''; + let text = null; if (!state.contains(States.CHECKABLE)) { text = Utils.localize(UtteranceGenerator.genForAction(aObject, aActionName)); diff --git a/b2g/installer/package-manifest.in b/b2g/installer/package-manifest.in index 55e1b2caa577..a5b8d5ba9a47 100644 --- a/b2g/installer/package-manifest.in +++ b/b2g/installer/package-manifest.in @@ -492,7 +492,6 @@ @RESPATH@/components/nsWebHandlerApp.js @RESPATH@/components/satchel.manifest @RESPATH@/components/nsFormAutoComplete.js -@RESPATH@/components/nsFormHistory.js @RESPATH@/components/FormHistoryStartup.js @RESPATH@/components/nsInputListAutoComplete.js @RESPATH@/components/formautofill.manifest diff --git a/browser/app/blocklist.xml b/browser/app/blocklist.xml index b0e0d71c11af..3bd28d0b6ff9 100644 --- a/browser/app/blocklist.xml +++ b/browser/app/blocklist.xml @@ -2143,12 +2143,16 @@ + + https://get.adobe.com/flashplayer/ - + + + https://get.adobe.com/flashplayer/ @@ -2202,7 +2206,9 @@ + + https://get.adobe.com/flashplayer/ @@ -2459,8 +2465,10 @@ https://get.adobe.com/flashplayer/ - + + + https://get.adobe.com/flashplayer/ @@ -2571,8 +2579,10 @@ - + + + https://get.adobe.com/flashplayer/ @@ -2640,8 +2650,10 @@ https://get.adobe.com/flashplayer/ - + + + https://get.adobe.com/flashplayer/ @@ -2810,7 +2822,9 @@ + + https://get.adobe.com/flashplayer/ @@ -3006,8 +3020,10 @@ https://get.adobe.com/reader - + + + https://get.adobe.com/flashplayer/ diff --git a/browser/base/content/test/general/browser_selectpopup.js b/browser/base/content/test/general/browser_selectpopup.js index 07acd36b2ee5..547c5871f938 100644 --- a/browser/base/content/test/general/browser_selectpopup.js +++ b/browser/base/content/test/general/browser_selectpopup.js @@ -1,9 +1,8 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ -// This test checks that a in a child process. This is different than +// single-process as a is used to implement the dropdown list. requestLongerTimeout(2); @@ -851,3 +850,35 @@ add_task(function* test_colors_applied_to_popup() { yield hideSelectPopup(selectPopup, "escape"); yield BrowserTestUtils.removeTab(tab); }); + +// This test checks that the popup is closed when the select element is blurred. +add_task(function* test_blur_hides_popup() { + const pageUrl = "data:text/html," + escape(PAGECONTENT_SMALL); + let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, pageUrl); + + yield ContentTask.spawn(tab.linkedBrowser, null, function*() { + content.addEventListener("blur", function(event) { + event.preventDefault(); + event.stopPropagation(); + }, true); + + content.document.getElementById("one").focus(); + }); + + let menulist = document.getElementById("ContentSelectDropdown"); + let selectPopup = menulist.menupopup; + + yield openSelectPopup(selectPopup); + + let popupHiddenPromise = BrowserTestUtils.waitForEvent(selectPopup, "popuphidden"); + + yield ContentTask.spawn(tab.linkedBrowser, null, function*() { + content.document.getElementById("one").blur(); + }); + + yield popupHiddenPromise; + + ok(true, "Blur closed popup"); + + yield BrowserTestUtils.removeTab(tab); +}); diff --git a/browser/config/tooltool-manifests/macosx64/cross-releng.manifest b/browser/config/tooltool-manifests/macosx64/cross-releng.manifest index c5e22f2d0f84..5002bb6410f1 100644 --- a/browser/config/tooltool-manifests/macosx64/cross-releng.manifest +++ b/browser/config/tooltool-manifests/macosx64/cross-releng.manifest @@ -33,9 +33,10 @@ "size": 1020700 }, { -"size": 57060, +"version": "https://github.com/andreas56/libdmg-hfsplus rev 81dd75fd1549b24bf8af9736ac25518b367e6b63", +"size": 62032, "visibility": "public", -"digest": "9649ca595f4cf088d118da26201f92cc94cda7af49c7c48112ee31cd13c83b2935b3e145de9dd78060cff2480b4c2e7ff5fb24235876956fed13c87852071998", +"digest": "9073c41034784eb8823ec817aed42bbc65c8da63ad3fac572726fa48b36320ee302ca8f51b23576e7fdbeec6ab300610d0c58bbd9c52024577dfdb13d95aa2ec", "algorithm": "sha512", "unpack": true, "filename": "dmg.tar.xz" diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in index 8550f7222966..f481d9a0266c 100644 --- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -465,7 +465,6 @@ @RESPATH@/components/nsWebHandlerApp.js @RESPATH@/components/satchel.manifest @RESPATH@/components/nsFormAutoComplete.js -@RESPATH@/components/nsFormHistory.js @RESPATH@/components/FormHistoryStartup.js @RESPATH@/components/nsInputListAutoComplete.js @RESPATH@/components/formautofill.manifest diff --git a/devtools/client/shared/widgets/ColorWidget.js b/devtools/client/shared/widgets/ColorWidget.js index ba705e6e1680..7031c73f5eba 100644 --- a/devtools/client/shared/widgets/ColorWidget.js +++ b/devtools/client/shared/widgets/ColorWidget.js @@ -10,6 +10,8 @@ "use strict"; const EventEmitter = require("devtools/shared/event-emitter"); +const {colorUtils} = require("devtools/shared/css/color"); + const XHTML_NS = "http://www.w3.org/1999/xhtml"; /** @@ -63,8 +65,35 @@ function ColorWidget(parentEl, rgb) {
+
+ +
+ +
+
+ + + + +
+
+ + + + +
+
`; + this.onSelectValueChange = this.onSelectValueChange.bind(this); + this.onHexInputChange = this.onHexInputChange.bind(this); + this.onRgbaInputChange = this.onRgbaInputChange.bind(this); + this.onHslaInputChange = this.onHslaInputChange.bind(this); + this.onElementClick = this.onElementClick.bind(this); this.element.addEventListener("click", this.onElementClick); @@ -83,6 +112,31 @@ function ColorWidget(parentEl, rgb) { this.alphaSliderHelper = this.element.querySelector(".colorwidget-alpha-handle"); ColorWidget.draggable(this.alphaSliderInner, this.onAlphaSliderMove.bind(this)); + this.colorSelect = this.element.querySelector(".colorwidget-select"); + this.colorSelect.addEventListener("change", this.onSelectValueChange); + + this.hexValue = this.element.querySelector(".colorwidget-hex"); + this.hexValueInput = this.element.querySelector(".colorwidget-hex-input"); + this.hexValueInput.addEventListener("input", this.onHexInputChange); + + this.rgbaValue = this.element.querySelector(".colorwidget-rgba"); + this.rgbaValueInputs = { + r: this.element.querySelector(".colorwidget-rgba-r"), + g: this.element.querySelector(".colorwidget-rgba-g"), + b: this.element.querySelector(".colorwidget-rgba-b"), + a: this.element.querySelector(".colorwidget-rgba-a"), + }; + this.rgbaValue.addEventListener("input", this.onRgbaInputChange); + + this.hslaValue = this.element.querySelector(".colorwidget-hsla"); + this.hslaValueInputs = { + h: this.element.querySelector(".colorwidget-hsla-h"), + s: this.element.querySelector(".colorwidget-hsla-s"), + l: this.element.querySelector(".colorwidget-hsla-l"), + a: this.element.querySelector(".colorwidget-hsla-a"), + }; + this.hslaValue.addEventListener("input", this.onHslaInputChange); + if (rgb) { this.rgb = rgb; this.updateUI(); @@ -137,6 +191,10 @@ ColorWidget.rgbToHsv = function (r, g, b, a) { return [h, s, v, a]; }; +ColorWidget.hslToCssString = function (h, s, l, a) { + return `hsla(${h}, ${s}%, ${l}%, ${a})`; +}; + ColorWidget.draggable = function (element, onmove, onstart, onstop) { onmove = onmove || function () {}; onstart = onstart || function () {}; @@ -210,6 +268,9 @@ ColorWidget.draggable = function (element, onmove, onstart, onstop) { ColorWidget.prototype = { set rgb(color) { this.hsv = ColorWidget.rgbToHsv(color[0], color[1], color[2], color[3]); + + let { h, s, l } = new colorUtils.CssColor(this.rgbCssString)._getHSLATuple(); + this.hsl = [h, s, l, color[3]]; }, get rgb() { @@ -250,6 +311,7 @@ ColorWidget.prototype = { onSliderMove: function (dragX, dragY) { this.hsv[0] = (dragY / this.slideHeight); + this.hsl[0] = (dragY / this.slideHeight) * 360; this.updateUI(); this.onChange(); }, @@ -257,12 +319,130 @@ ColorWidget.prototype = { onDraggerMove: function (dragX, dragY) { this.hsv[1] = dragX / this.dragWidth; this.hsv[2] = (this.dragHeight - dragY) / this.dragHeight; + + this.hsl[2] = ((2 - this.hsv[1]) * this.hsv[2] / 2); + if (this.hsl[2] && this.hsl[2] < 1) { + this.hsl[1] = this.hsv[1] * this.hsv[2] / + (this.hsl[2] < 0.5 ? this.hsl[2] * 2 : 2 - this.hsl[2] * 2); + this.hsl[1] = this.hsl[1] * 100; + } + this.hsl[2] = this.hsl[2] * 100; + this.updateUI(); this.onChange(); }, onAlphaSliderMove: function (dragX, dragY) { this.hsv[3] = dragX / this.alphaSliderWidth; + this.hsl[3] = dragX / this.alphaSliderWidth; + this.updateUI(); + this.onChange(); + }, + + onSelectValueChange: function (event) { + const selection = event.target.value; + this.colorSelect.classList.remove("colorwidget-select-spacing"); + this.hexValue.classList.add("colorwidget-hidden"); + this.rgbaValue.classList.add("colorwidget-hidden"); + this.hslaValue.classList.add("colorwidget-hidden"); + + switch (selection) { + case "hex": + this.hexValue.classList.remove("colorwidget-hidden"); + break; + case "rgba": + this.colorSelect.classList.add("colorwidget-select-spacing"); + this.rgbaValue.classList.remove("colorwidget-hidden"); + break; + case "hsla": + this.colorSelect.classList.add("colorwidget-select-spacing"); + this.hslaValue.classList.remove("colorwidget-hidden"); + break; + } + }, + + onHexInputChange: function (event) { + const hex = event.target.value; + const color = new colorUtils.CssColor(hex, true); + if (!color.rgba) { + return; + } + + const { r, g, b, a } = color._getRGBATuple(); + this.rgb = [r, g, b, a]; + this.updateUI(); + this.onChange(); + }, + + onRgbaInputChange: function (event) { + const field = event.target.dataset.id; + const value = event.target.value.toString(); + if (!value || isNaN(value) || value.endsWith(".")) { + return; + } + + let rgb = this.rgb; + + switch (field) { + case "r": + rgb[0] = value; + break; + case "g": + rgb[1] = value; + break; + case "b": + rgb[2] = value; + break; + case "a": + rgb[3] = Math.min(value, 1); + break; + } + + this.rgb = rgb; + + this.updateUI(); + this.onChange(); + }, + + onHslaInputChange: function (event) { + const field = event.target.dataset.id; + let value = event.target.value.toString(); + if ((field === "s" || field === "l") && !value.endsWith("%")) { + return; + } + + if (value.endsWith("%")) { + value = value.substring(0, value.length - 1); + } + + if (!value || isNaN(value) || value.endsWith(".")) { + return; + } + + const hsl = this.hsl; + + switch (field) { + case "h": + hsl[0] = value; + break; + case "s": + hsl[1] = value; + break; + case "l": + hsl[2] = value; + break; + case "a": + hsl[3] = Math.min(value, 1); + break; + } + + const cssString = ColorWidget.hslToCssString(hsl[0], hsl[1], hsl[2], hsl[3]); + const { r, g, b, a } = new colorUtils.CssColor(cssString)._getRGBATuple(); + + this.rgb = [r, g, b, a]; + + this.hsl = hsl; + this.updateUI(); this.onChange(); }, @@ -307,6 +487,24 @@ ColorWidget.prototype = { let alphaSliderX = (this.hsv[3] * this.alphaSliderWidth) - (this.alphaSliderHelperWidth / 2); this.alphaSliderHelper.style.left = alphaSliderX + "px"; + + const color = new colorUtils.CssColor(this.rgbCssString); + + // Updating the hex field + this.hexValueInput.value = color.hex; + + // Updating the RGBA fields + const rgb = this.rgb; + this.rgbaValueInputs.r.value = rgb[0]; + this.rgbaValueInputs.g.value = rgb[1]; + this.rgbaValueInputs.b.value = rgb[2]; + this.rgbaValueInputs.a.value = parseFloat(rgb[3].toFixed(1)); + + // Updating the HSLA fields + this.hslaValueInputs.h.value = this.hsl[0]; + this.hslaValueInputs.s.value = this.hsl[1] + "%"; + this.hslaValueInputs.l.value = this.hsl[2] + "%"; + this.hslaValueInputs.a.value = parseFloat(this.hsl[3].toFixed(1)); }, updateUI: function () { diff --git a/devtools/client/shared/widgets/color-widget.css b/devtools/client/shared/widgets/color-widget.css index 2306c875db37..1e2fbcc45c5e 100644 --- a/devtools/client/shared/widgets/color-widget.css +++ b/devtools/client/shared/widgets/color-widget.css @@ -153,3 +153,59 @@ http://www.briangrinstead.com/blog/keep-aspect-ratio-with-html-and-css */ left: -3px; right: -3px; } + +/** + * Color Widget Editor + */ + +.colorwidget-value { + position: relative; + margin-top: 8px; +} + +/** + * Color Widget Select + */ + +.colorwidget-select { + width: 100%; +} + +.colorwidget-select-spacing { + letter-spacing: 40px; +} + +.colorwidget-select-spacing option { + letter-spacing: initial; +} + +/** + * Color Widget Inputs + */ + +.colorwidget-hidden { + display: none; +} + +.colorwidget-hex, +.colorwidget-rgba, +.colorwidget-hsla { + width: 200px; + font-size: 0; +} + +.colorwidget-hex-input { + width: 192px; +} + +.colorwidget-rgba-r, +.colorwidget-rgba-g, +.colorwidget-rgba-b, +.colorwidget-rgba-a, +.colorwidget-hsla-h, +.colorwidget-hsla-s, +.colorwidget-hsla-l, +.colorwidget-hsla-a { + width: 42px; + margin: 0; +} \ No newline at end of file diff --git a/devtools/client/shared/widgets/tooltip/SwatchColorPickerTooltip.js b/devtools/client/shared/widgets/tooltip/SwatchColorPickerTooltip.js index 8c61235074d1..9207784d59ea 100644 --- a/devtools/client/shared/widgets/tooltip/SwatchColorPickerTooltip.js +++ b/devtools/client/shared/widgets/tooltip/SwatchColorPickerTooltip.js @@ -74,13 +74,13 @@ SwatchColorPickerTooltip.prototype = Heritage.extend(SwatchBasedEditorTooltip.pr eyedropper.style.pointerEvents = "auto"; container.appendChild(eyedropper); - this.tooltip.setContent(container, { width: 218, height: 224 }); - let spectrum; if (NEW_COLOR_WIDGET) { + this.tooltip.setContent(container, { width: 218, height: 271 }); const {ColorWidget} = require("devtools/client/shared/widgets/ColorWidget"); spectrum = new ColorWidget(spectrumNode, color); } else { + this.tooltip.setContent(container, { width: 218, height: 224 }); spectrum = new Spectrum(spectrumNode, color); } diff --git a/devtools/shared/css/color.js b/devtools/shared/css/color.js index 98ddeff1953f..5c9518b2b708 100644 --- a/devtools/shared/css/color.js +++ b/devtools/shared/css/color.js @@ -408,6 +408,23 @@ CssColor.prototype = { return tuple; }, + /** + * Returns a HSLA 4-Tuple representation of a color or transparent as + * appropriate. + */ + _getHSLATuple: function () { + let {r, g, b, a} = colorToRGBA(this.authored, this.cssColor4); + + let [h, s, l] = rgbToHsl([r, g, b]); + + return { + h, + s, + l, + a: parseFloat(a.toFixed(1)) + }; + }, + _hsl: function (maybeAlpha) { if (this.lowerCased.startsWith("hsl(") && maybeAlpha === undefined) { // We can use it as-is. diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 846c1c53f709..4daa91072872 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -12607,7 +12607,7 @@ nsDocShell::LoadHistoryEntry(nsISHEntry* aEntry, uint32_t aLoadType) MOZ_ASSERT(triggeringPrincipal, "need a valid triggeringPrincipal to load from history"); if (!triggeringPrincipal) { - return NS_ERROR_FAILURE; + triggeringPrincipal = nsContentUtils::GetSystemPrincipal(); } // Passing nullptr as aSourceDocShell gives the same behaviour as before diff --git a/dom/animation/AnimationUtils.cpp b/dom/animation/AnimationUtils.cpp index ce945ce1ab56..98cbccd21148 100644 --- a/dom/animation/AnimationUtils.cpp +++ b/dom/animation/AnimationUtils.cpp @@ -13,6 +13,8 @@ #include "nsGlobalWindow.h" #include "nsString.h" #include "xpcpublic.h" // For xpc::NativeGlobal +#include "mozilla/EffectSet.h" +#include "mozilla/dom/KeyframeEffectReadOnly.h" #include "mozilla/Preferences.h" namespace mozilla { @@ -83,4 +85,17 @@ AnimationUtils::IsCoreAPIEnabledForCaller(dom::CallerType aCallerType) return IsCoreAPIEnabled() || aCallerType == dom::CallerType::System; } +/* static */ bool +AnimationUtils::EffectSetContainsAnimatedScale(EffectSet& aEffects, + const nsIFrame* aFrame) +{ + for (const dom::KeyframeEffectReadOnly* effect : aEffects) { + if (effect->ContainsAnimatedScale(aFrame)) { + return true; + } + } + + return false; +} + } // namespace mozilla diff --git a/dom/animation/AnimationUtils.h b/dom/animation/AnimationUtils.h index 2ba249c9f178..d3b11047484f 100644 --- a/dom/animation/AnimationUtils.h +++ b/dom/animation/AnimationUtils.h @@ -14,11 +14,13 @@ class nsIContent; class nsIDocument; +class nsIFrame; struct JSContext; namespace mozilla { class ComputedTimingFunction; +class EffectSet; class AnimationUtils { @@ -73,6 +75,13 @@ public: * true or the caller is chrome. */ static bool IsCoreAPIEnabledForCaller(dom::CallerType aCallerType); + + /** + * Returns true if the given EffectSet contains a current effect that animates + * scale. |aFrame| is used for calculation of scale values. + */ + static bool EffectSetContainsAnimatedScale(EffectSet& aEffects, + const nsIFrame* aFrame); }; } // namespace mozilla diff --git a/dom/animation/KeyframeEffectReadOnly.cpp b/dom/animation/KeyframeEffectReadOnly.cpp index 32be4e6a6b43..6caf7bb19a5b 100644 --- a/dom/animation/KeyframeEffectReadOnly.cpp +++ b/dom/animation/KeyframeEffectReadOnly.cpp @@ -1763,5 +1763,54 @@ KeyframeEffectReadOnly::NeedsBaseStyle(nsCSSPropertyID aProperty) const return false; } +bool +KeyframeEffectReadOnly::ContainsAnimatedScale(const nsIFrame* aFrame) const +{ + if (!IsCurrent()) { + return false; + } + + for (const AnimationProperty& prop : mProperties) { + if (prop.mProperty != eCSSProperty_transform) { + continue; + } + + if (NeedsBaseStyle(prop.mProperty)) { + StyleAnimationValue baseStyle = + EffectCompositor::GetBaseStyle(prop.mProperty, aFrame); + MOZ_ASSERT(!baseStyle.IsNull(), "The base value should be set"); + if (baseStyle.IsNull()) { + // If we failed to get the base style, we consider it has scale value + // here for the safety. + return true; + } + gfxSize size = baseStyle.GetScaleValue(aFrame); + if (size != gfxSize(1.0f, 1.0f)) { + return true; + } + } + + // This is actually overestimate because there are some cases that combining + // the base value and from/to value produces 1:1 scale. But it doesn't + // really matter. + for (const AnimationPropertySegment& segment : prop.mSegments) { + if (!segment.mFromValue.IsNull()) { + gfxSize from = segment.mFromValue.GetScaleValue(aFrame); + if (from != gfxSize(1.0f, 1.0f)) { + return true; + } + } + if (!segment.mToValue.IsNull()) { + gfxSize to = segment.mToValue.GetScaleValue(aFrame); + if (to != gfxSize(1.0f, 1.0f)) { + return true; + } + } + } + } + + return false; +} + } // namespace dom } // namespace mozilla diff --git a/dom/animation/KeyframeEffectReadOnly.h b/dom/animation/KeyframeEffectReadOnly.h index d9d6b9701bef..e1b071bd73d1 100644 --- a/dom/animation/KeyframeEffectReadOnly.h +++ b/dom/animation/KeyframeEffectReadOnly.h @@ -288,6 +288,10 @@ public: // needs a base style to composite with. bool NeedsBaseStyle(nsCSSPropertyID aProperty) const; + // Returns true if the effect is current state and has scale animation. + // |aFrame| is used for calculation of scale values. + bool ContainsAnimatedScale(const nsIFrame* aFrame) const; + protected: KeyframeEffectReadOnly(nsIDocument* aDocument, const Maybe& aTarget, diff --git a/dom/base/Element.h b/dom/base/Element.h index 85146e8b6724..d29a8b34369a 100644 --- a/dom/base/Element.h +++ b/dom/base/Element.h @@ -44,6 +44,7 @@ class nsIFrame; class nsIDOMMozNamedAttrMap; +class nsIMozBrowserFrame; class nsIURI; class nsIScrollableFrame; class nsAttrValueOrString; @@ -339,6 +340,16 @@ public: */ virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const; + /** + * Returns |this| as an nsIMozBrowserFrame* if the element is a frame or + * iframe element. + * + * We have this method, rather than using QI, so that we can use it during + * the servo traversal, where we can't QI DOM nodes because of non-thread-safe + * refcounts. + */ + virtual nsIMozBrowserFrame* GetAsMozBrowserFrame() { return nullptr; } + /** * Is the attribute named stored in the mapped attributes? * diff --git a/dom/base/Location.cpp b/dom/base/Location.cpp index cb8acd85d8a8..eab9db9341da 100644 --- a/dom/base/Location.cpp +++ b/dom/base/Location.cpp @@ -33,6 +33,7 @@ #include "nsCycleCollectionParticipant.h" #include "nsNullPrincipal.h" #include "ScriptSettings.h" +#include "mozilla/Unused.h" #include "mozilla/dom/LocationBinding.h" namespace mozilla { @@ -699,9 +700,17 @@ Location::SetProtocol(const nsAString& aProtocol) return rv; } - rv = uri->SetScheme(NS_ConvertUTF16toUTF8(aProtocol)); + nsAString::const_iterator start, end; + aProtocol.BeginReading(start); + aProtocol.EndReading(end); + nsAString::const_iterator iter(start); + Unused << FindCharInReadable(':', iter, end); + + rv = uri->SetScheme(NS_ConvertUTF16toUTF8(Substring(start, iter))); if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; + // Oh, I wish nsStandardURL returned NS_ERROR_MALFORMED_URI for _all_ the + // malformed cases, not just some of them! + return NS_ERROR_DOM_SYNTAX_ERR; } nsAutoCString newSpec; rv = uri->GetSpec(newSpec); @@ -711,9 +720,29 @@ Location::SetProtocol(const nsAString& aProtocol) // We may want a new URI class for the new URI, so recreate it: rv = NS_NewURI(getter_AddRefs(uri), newSpec); if (NS_FAILED(rv)) { + if (rv == NS_ERROR_MALFORMED_URI) { + rv = NS_ERROR_DOM_SYNTAX_ERR; + } return rv; } + bool isHttp; + rv = uri->SchemeIs("http", &isHttp); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + bool isHttps; + rv = uri->SchemeIs("https", &isHttps); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + if (!isHttp && !isHttps) { + // No-op, per spec. + return NS_OK; + } + return SetURI(uri); } diff --git a/dom/base/Navigator.cpp b/dom/base/Navigator.cpp index 0c5e6d1eff77..2f3dd6e24853 100644 --- a/dom/base/Navigator.cpp +++ b/dom/base/Navigator.cpp @@ -1229,7 +1229,7 @@ BeaconStreamListener::OnDataAvailable(nsIRequest *aRequest, bool Navigator::SendBeacon(const nsAString& aUrl, - const Nullable& aData, + const Nullable& aData, ErrorResult& aRv) { if (aData.IsNull()) { diff --git a/dom/base/Navigator.h b/dom/base/Navigator.h index df6b59841fed..8e97c4661518 100644 --- a/dom/base/Navigator.h +++ b/dom/base/Navigator.h @@ -9,6 +9,7 @@ #include "mozilla/MemoryReporting.h" #include "mozilla/dom/BindingDeclarations.h" +#include "mozilla/dom/Fetch.h" #include "mozilla/dom/Nullable.h" #include "mozilla/ErrorResult.h" #include "nsIDOMNavigator.h" @@ -226,7 +227,7 @@ public: Presentation* GetPresentation(ErrorResult& aRv); bool SendBeacon(const nsAString& aUrl, - const Nullable& aData, + const Nullable& aData, ErrorResult& aRv); void MozGetUserMedia(const MediaStreamConstraints& aConstraints, diff --git a/dom/base/nsAttrValue.cpp b/dom/base/nsAttrValue.cpp index 8eb1aaf974e5..1a893cd3bfa7 100644 --- a/dom/base/nsAttrValue.cpp +++ b/dom/base/nsAttrValue.cpp @@ -18,6 +18,7 @@ #include "nsUnicharUtils.h" #include "mozilla/MemoryReporting.h" #include "mozilla/ServoBindingTypes.h" +#include "mozilla/ServoStyleSet.h" #include "mozilla/DeclarationBlockInlines.h" #include "nsContentUtils.h" #include "nsReadableUtils.h" @@ -647,7 +648,15 @@ nsAttrValue::ToString(nsAString& aResult) const if (DeclarationBlock* decl = container->mValue.mCSSDeclaration) { decl->ToString(aResult); } - const_cast(this)->SetMiscAtomOrString(&aResult); + + // We can reach this during parallel style traversal. If that happens, + // don't cache the string. The TLS overhead should't hurt us here, since + // main thread consumers will subsequently use the cache, and + // off-main-thread consumers only reach this in the rare case of selector + // matching on the "style" attribute. + if (!ServoStyleSet::IsInServoTraversal()) { + const_cast(this)->SetMiscAtomOrString(&aResult); + } break; } diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 00bbd4089a81..ebf9f2390976 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -4037,6 +4037,10 @@ nsIDocument::GetRootElement() const Element* nsDocument::GetRootElementInternal() const { + // We invoke GetRootElement() immediately before the servo traversal, so we + // should always have a cache hit from Servo. + MOZ_ASSERT(NS_IsMainThread()); + // Loop backwards because any non-elements, such as doctypes and PIs // are likely to appear before the root element. uint32_t i; diff --git a/dom/base/nsObjectLoadingContent.cpp b/dom/base/nsObjectLoadingContent.cpp index 59752ffbf2e0..51697b9b0e21 100644 --- a/dom/base/nsObjectLoadingContent.cpp +++ b/dom/base/nsObjectLoadingContent.cpp @@ -88,6 +88,7 @@ #include "mozilla/Telemetry.h" #include "mozilla/dom/HTMLObjectElementBinding.h" #include "mozilla/dom/HTMLSharedObjectElement.h" +#include "mozilla/dom/HTMLObjectElement.h" #include "nsChannelClassifier.h" #ifdef XP_WIN @@ -97,13 +98,6 @@ #endif #endif // XP_WIN -#ifdef XP_MACOSX -// HandlePluginCrashed() and HandlePluginInstantiated() needed from here to -// fix bug 1147521. Should later be replaced by proper interface methods, -// maybe on nsIObjectLoadingContext. -#include "mozilla/dom/HTMLObjectElement.h" -#endif - static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID); static const char *kPrefJavaMIME = "plugin.java.mime"; @@ -3018,7 +3012,7 @@ nsObjectLoadingContent::LoadFallback(FallbackType aType, bool aNotify) { // Fixup mFallbackType // nsCOMPtr thisContent = - do_QueryInterface(static_cast(this)); + do_QueryInterface(static_cast(this)); NS_ASSERTION(thisContent, "must be a content"); if (!thisContent->IsHTMLElement() || mContentType.IsEmpty()) { @@ -3031,8 +3025,10 @@ nsObjectLoadingContent::LoadFallback(FallbackType aType, bool aNotify) { // child embeds as we find them in the upcoming loop. mType = eType_Null; - // Do a breadth-first traverse of node tree with the current element as root, - // looking for the first embed we can find. + bool thisIsObject = thisContent->IsHTMLElement(nsGkAtoms::object); + + // Do a depth-first traverse of node tree with the current element as root, + // looking for or elements that might now need to load. nsTArray childNodes; if ((thisContent->IsHTMLElement(nsGkAtoms::object) || thisContent->IsHTMLElement(nsGkAtoms::applet)) && @@ -3048,10 +3044,11 @@ nsObjectLoadingContent::LoadFallback(FallbackType aType, bool aNotify) { nsStyleUtil::IsSignificantChild(child, true, false)) { aType = eFallbackAlternate; } - if (child->IsHTMLElement(nsGkAtoms::embed) && - thisContent->IsHTMLElement(nsGkAtoms::object)) { - HTMLSharedObjectElement* object = static_cast(child); - if (object) { + if (thisIsObject) { + if (child->IsHTMLElement(nsGkAtoms::embed)) { + HTMLSharedObjectElement* embed = static_cast(child); + embed->StartObjectLoad(true, true); + } else if (auto object = HTMLObjectElement::FromContent(child)) { object->StartObjectLoad(true, true); } } @@ -3817,6 +3814,38 @@ nsObjectLoadingContent::MaybeFireErrorEvent() } } +bool +nsObjectLoadingContent::BlockEmbedOrObjectContentLoading() +{ + nsCOMPtr thisContent = + do_QueryInterface(static_cast(this)); + if (!thisContent->IsHTMLElement(nsGkAtoms::embed) && + !thisContent->IsHTMLElement(nsGkAtoms::object)) { + // Doesn't apply to other elements (i.e. ) + return false; + } + + // Traverse up the node tree to see if we have any ancestors that may block us + // from loading + for (nsIContent* parent = thisContent->GetParent(); + parent; + parent = parent->GetParent()) { + if (parent->IsAnyOfHTMLElements(nsGkAtoms::video, nsGkAtoms::audio)) { + return true; + } + // If we have an ancestor that is an object with a source, it'll have an + // associated displayed type. If that type is not null, don't load content + // for the embed. + if (HTMLObjectElement* object = HTMLObjectElement::FromContent(parent)) { + uint32_t type = object->DisplayedType(); + if (type != eType_Null) { + return true; + } + } + } + return false; +} + // SetupProtoChainRunner implementation nsObjectLoadingContent::SetupProtoChainRunner::SetupProtoChainRunner( nsObjectLoadingContent* aContent) diff --git a/dom/base/nsObjectLoadingContent.h b/dom/base/nsObjectLoadingContent.h index 13b7cc3f893f..92d880d99b75 100644 --- a/dom/base/nsObjectLoadingContent.h +++ b/dom/base/nsObjectLoadingContent.h @@ -334,6 +334,21 @@ class nsObjectLoadingContent : public nsImageLoadingContent */ virtual nsContentPolicyType GetContentPolicyType() const = 0; + /** + * Decides whether we should load / node content. + * + * If this is an or node there are cases in which we should + * not try to load the content: + * + * - If the node is the child of a media element + * - If the node is the child of an node that already has + * content being loaded. + * + * In these cases, this function will return false, which will cause + * us to skip calling LoadObject. + */ + bool BlockEmbedOrObjectContentLoading(); + private: // Object parameter changes returned by UpdateObjectParameters diff --git a/dom/base/test/file_bug1263696_frame_fail.html b/dom/base/test/file_bug1263696_frame_fail.html deleted file mode 100644 index b45561aa6f72..000000000000 --- a/dom/base/test/file_bug1263696_frame_fail.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - Bug 1263696 - iframe that should not be loaded - - - - - diff --git a/dom/base/test/file_bug1263696_frame_pass.html b/dom/base/test/file_bug1263696_frame_pass.html deleted file mode 100644 index 7f49d6541c44..000000000000 --- a/dom/base/test/file_bug1263696_frame_pass.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - Bug 1263696 - iframe that should be loaded - - - - - diff --git a/dom/base/test/mochitest.ini b/dom/base/test/mochitest.ini index f6f548a8a6c3..368b0ae0b295 100644 --- a/dom/base/test/mochitest.ini +++ b/dom/base/test/mochitest.ini @@ -125,8 +125,6 @@ support-files = file_bug902350_frame.html file_bug907892.html file_bug945152.jar - file_bug1263696_frame_pass.html - file_bug1263696_frame_fail.html file_bug1274806.html file_general_document.html file_htmlserializer_1.html @@ -587,7 +585,6 @@ skip-if = toolkit == 'android' [test_bug1238440.html] [test_bug1250148.html] [test_bug1259588.html] -[test_bug1263696.html] [test_bug1268962.html] [test_bug1274806.html] [test_bug1281963.html] diff --git a/dom/base/test/test_bug1263696.html b/dom/base/test/test_bug1263696.html deleted file mode 100644 index 289a26ba4ff1..000000000000 --- a/dom/base/test/test_bug1263696.html +++ /dev/null @@ -1,53 +0,0 @@ - - - - - Test Embed/Object Node Conflicts - - - - - - - - - - - - - -
- -
- -
- -
-
- - - - - - - - - - -
- - -
-
- - -
- - diff --git a/dom/fetch/Fetch.cpp b/dom/fetch/Fetch.cpp index fe06f4c074c8..5f164643f09b 100644 --- a/dom/fetch/Fetch.cpp +++ b/dom/fetch/Fetch.cpp @@ -480,7 +480,7 @@ WorkerFetchResolver::FlushConsoleReport() } nsresult -ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams& aBodyInit, +ExtractByteStreamFromBody(const fetch::OwningBodyInit& aBodyInit, nsIInputStream** aStream, nsCString& aContentTypeWithCharset, uint64_t& aContentLength) @@ -533,7 +533,7 @@ ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrBlobOrFormDa } nsresult -ExtractByteStreamFromBody(const ArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams& aBodyInit, +ExtractByteStreamFromBody(const fetch::BodyInit& aBodyInit, nsIInputStream** aStream, nsCString& aContentTypeWithCharset, uint64_t& aContentLength) diff --git a/dom/fetch/Fetch.h b/dom/fetch/Fetch.h index baacf38c3b0f..d69f92d98a55 100644 --- a/dom/fetch/Fetch.h +++ b/dom/fetch/Fetch.h @@ -27,10 +27,10 @@ class nsIGlobalObject; namespace mozilla { namespace dom { -class ArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams; +class BlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString; class BlobImpl; class InternalRequest; -class OwningArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams; +class OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString; class RequestOrUSVString; enum class CallerType : uint32_t; @@ -46,13 +46,18 @@ FetchRequest(nsIGlobalObject* aGlobal, const RequestOrUSVString& aInput, nsresult UpdateRequestReferrer(nsIGlobalObject* aGlobal, InternalRequest* aRequest); +namespace fetch { +typedef BlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString BodyInit; +typedef OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString OwningBodyInit; +}; + /* * Creates an nsIInputStream based on the fetch specifications 'extract a byte * stream algorithm' - http://fetch.spec.whatwg.org/#concept-bodyinit-extract. * Stores content type in out param aContentType. */ nsresult -ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams& aBodyInit, +ExtractByteStreamFromBody(const fetch::OwningBodyInit& aBodyInit, nsIInputStream** aStream, nsCString& aContentType, uint64_t& aContentLength); @@ -61,7 +66,7 @@ ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrBlobOrFormDa * Non-owning version. */ nsresult -ExtractByteStreamFromBody(const ArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams& aBodyInit, +ExtractByteStreamFromBody(const fetch::BodyInit& aBodyInit, nsIInputStream** aStream, nsCString& aContentType, uint64_t& aContentLength); diff --git a/dom/fetch/Request.cpp b/dom/fetch/Request.cpp index 97863a40d5b4..0847ed088ae2 100644 --- a/dom/fetch/Request.cpp +++ b/dom/fetch/Request.cpp @@ -547,11 +547,9 @@ Request::Constructor(const GlobalObject& aGlobal, } if (aInit.mBody.WasPassed()) { - const Nullable& bodyInitNullable = - aInit.mBody.Value(); + const Nullable& bodyInitNullable = aInit.mBody.Value(); if (!bodyInitNullable.IsNull()) { - const OwningArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams& bodyInit = - bodyInitNullable.Value(); + const fetch::OwningBodyInit& bodyInit = bodyInitNullable.Value(); nsCOMPtr stream; nsAutoCString contentTypeWithCharset; uint64_t contentLengthUnused; diff --git a/dom/fetch/Response.cpp b/dom/fetch/Response.cpp index c69bffba53b5..628d9d0c0b8a 100644 --- a/dom/fetch/Response.cpp +++ b/dom/fetch/Response.cpp @@ -104,7 +104,7 @@ Response::Redirect(const GlobalObject& aGlobal, const nsAString& aUrl, return nullptr; } - Optional body; + Optional body; ResponseInit init; init.mStatus = aStatus; RefPtr r = Response::Constructor(aGlobal, body, init, aRv); @@ -125,7 +125,7 @@ Response::Redirect(const GlobalObject& aGlobal, const nsAString& aUrl, /*static*/ already_AddRefed Response::Constructor(const GlobalObject& aGlobal, - const Optional& aBody, + const Optional& aBody, const ResponseInit& aInit, ErrorResult& aRv) { nsCOMPtr global = do_QueryInterface(aGlobal.GetAsSupports()); diff --git a/dom/fetch/Response.h b/dom/fetch/Response.h index 64b3c5f45194..67e03d65b7cc 100644 --- a/dom/fetch/Response.h +++ b/dom/fetch/Response.h @@ -114,7 +114,7 @@ public: static already_AddRefed Constructor(const GlobalObject& aGlobal, - const Optional& aBody, + const Optional& aBody, const ResponseInit& aInit, ErrorResult& rv); nsIGlobalObject* GetParentObject() const diff --git a/dom/file/File.h b/dom/file/File.h index 4343023a164d..4dc448eb75ae 100644 --- a/dom/file/File.h +++ b/dom/file/File.h @@ -42,7 +42,7 @@ struct ChromeFilePropertyBag; struct FilePropertyBag; class BlobImpl; class File; -class OwningArrayBufferOrArrayBufferViewOrBlobOrUSVString; +class OwningArrayBufferViewOrArrayBufferOrBlobOrUSVString; class Promise; class Blob : public nsIDOMBlob @@ -59,7 +59,7 @@ public: NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(Blob, nsIDOMBlob) - typedef OwningArrayBufferOrArrayBufferViewOrBlobOrUSVString BlobPart; + typedef OwningArrayBufferViewOrArrayBufferOrBlobOrUSVString BlobPart; // This creates a Blob or a File based on the type of BlobImpl. static Blob* diff --git a/dom/file/FileCreatorHelper.cpp b/dom/file/FileCreatorHelper.cpp index 918fdf72d709..00094c892d5d 100644 --- a/dom/file/FileCreatorHelper.cpp +++ b/dom/file/FileCreatorHelper.cpp @@ -99,6 +99,10 @@ FileCreatorHelper::FileCreatorHelper(Promise* aPromise, MOZ_ASSERT(aPromise); } +FileCreatorHelper::~FileCreatorHelper() +{ +} + void FileCreatorHelper::SendRequest(nsIFile* aFile, const ChromeFilePropertyBag& aBag, diff --git a/dom/file/FileCreatorHelper.h b/dom/file/FileCreatorHelper.h index 4c64ce83ecc3..12cd7e72800a 100644 --- a/dom/file/FileCreatorHelper.h +++ b/dom/file/FileCreatorHelper.h @@ -72,7 +72,7 @@ private: BlobImpl** aBlobImpl); FileCreatorHelper(Promise* aPromise, nsPIDOMWindowInner* aWindow); - ~FileCreatorHelper() = default; + ~FileCreatorHelper(); void SendRequest(nsIFile* aFile, const ChromeFilePropertyBag& aBag, diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp index f763175ab89a..9dcc5277ab34 100644 --- a/dom/html/HTMLInputElement.cpp +++ b/dom/html/HTMLInputElement.cpp @@ -2433,11 +2433,8 @@ HTMLInputElement::GetMaximum() const Decimal HTMLInputElement::GetStepBase() const { - MOZ_ASSERT(mType == NS_FORM_INPUT_NUMBER || - mType == NS_FORM_INPUT_DATE || - mType == NS_FORM_INPUT_TIME || - mType == NS_FORM_INPUT_MONTH || - mType == NS_FORM_INPUT_WEEK || + MOZ_ASSERT(IsDateTimeInputType(mType) || + mType == NS_FORM_INPUT_NUMBER || mType == NS_FORM_INPUT_RANGE, "Check that kDefaultStepBase is correct for this new type"); @@ -8671,6 +8668,7 @@ HTMLInputElement::GetStepScaleFactor() const case NS_FORM_INPUT_RANGE: return kStepScaleFactorNumberRange; case NS_FORM_INPUT_TIME: + case NS_FORM_INPUT_DATETIME_LOCAL: return kStepScaleFactorTime; case NS_FORM_INPUT_MONTH: return kStepScaleFactorMonth; @@ -8695,6 +8693,7 @@ HTMLInputElement::GetDefaultStep() const case NS_FORM_INPUT_RANGE: return kDefaultStep; case NS_FORM_INPUT_TIME: + case NS_FORM_INPUT_DATETIME_LOCAL: return kDefaultStepTime; default: MOZ_ASSERT(false, "Unrecognized input type"); diff --git a/dom/html/HTMLInputElement.h b/dom/html/HTMLInputElement.h index fe97471c0a55..7fa84726330f 100644 --- a/dom/html/HTMLInputElement.h +++ b/dom/html/HTMLInputElement.h @@ -1070,11 +1070,7 @@ protected: /** * Returns if the step attribute apply for the current type. */ - bool DoesStepApply() const - { - // TODO: this is temporary until bug 888331 is fixed. - return DoesMinMaxApply() && mType != NS_FORM_INPUT_DATETIME_LOCAL; - } + bool DoesStepApply() const { return DoesMinMaxApply(); } /** * Returns if stepDown and stepUp methods apply for the current type. diff --git a/dom/html/HTMLObjectElement.cpp b/dom/html/HTMLObjectElement.cpp index c509ac1af3ed..b80c684d5d6d 100644 --- a/dom/html/HTMLObjectElement.cpp +++ b/dom/html/HTMLObjectElement.cpp @@ -79,7 +79,7 @@ HTMLObjectElement::DoneAddingChildren(bool aHaveNotified) // If we're already in a document, we need to trigger the load // Otherwise, BindToTree takes care of that. if (IsInComposedDoc()) { - StartObjectLoad(aHaveNotified); + StartObjectLoad(aHaveNotified, false); } } @@ -310,7 +310,8 @@ HTMLObjectElement::SetAttr(int32_t aNameSpaceID, nsIAtom *aName, // a document, just in case that the caller wants to set additional // attributes before inserting the node into the document. if (aNotify && IsInComposedDoc() && mIsDoneAddingChildren && - aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::data) { + aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::data && + !BlockEmbedOrObjectContentLoading()) { return LoadObject(aNotify, true); } @@ -327,7 +328,8 @@ HTMLObjectElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute, // See comment in SetAttr if (aNotify && IsInComposedDoc() && mIsDoneAddingChildren && - aNameSpaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::data) { + aNameSpaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::data && + !BlockEmbedOrObjectContentLoading()) { return LoadObject(aNotify, true); } @@ -535,15 +537,16 @@ HTMLObjectElement::GetAttributeMappingFunction() const } void -HTMLObjectElement::StartObjectLoad(bool aNotify) +HTMLObjectElement::StartObjectLoad(bool aNotify, bool aForce) { // BindToTree can call us asynchronously, and we may be removed from the tree // in the interim - if (!IsInComposedDoc() || !OwnerDoc()->IsActive()) { + if (!IsInComposedDoc() || !OwnerDoc()->IsActive() || + BlockEmbedOrObjectContentLoading()) { return; } - LoadObject(aNotify); + LoadObject(aNotify, aForce); SetIsNetworkCreated(false); } diff --git a/dom/html/HTMLObjectElement.h b/dom/html/HTMLObjectElement.h index 7cb98249beb9..f439108fee14 100644 --- a/dom/html/HTMLObjectElement.h +++ b/dom/html/HTMLObjectElement.h @@ -98,7 +98,7 @@ public: nsresult CopyInnerTo(Element* aDest); - void StartObjectLoad() { StartObjectLoad(true); } + void StartObjectLoad() { StartObjectLoad(true, false); } NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLObjectElement, nsGenericHTMLFormElement) @@ -247,12 +247,12 @@ public: return GetContentDocument(aSubjectPrincipal); } -private: /** * Calls LoadObject with the correct arguments to start the plugin load. */ - void StartObjectLoad(bool aNotify); + void StartObjectLoad(bool aNotify, bool aForceLoad); +private: /** * Returns if the element is currently focusable regardless of it's tabindex * value. This is used to know the default tabindex value. diff --git a/dom/html/HTMLSharedObjectElement.cpp b/dom/html/HTMLSharedObjectElement.cpp index 1f7b9cc6ae46..9c78b03a360c 100644 --- a/dom/html/HTMLSharedObjectElement.cpp +++ b/dom/html/HTMLSharedObjectElement.cpp @@ -180,7 +180,7 @@ HTMLSharedObjectElement::SetAttr(int32_t aNameSpaceID, nsIAtom *aName, // attributes before inserting the node into the document. if (aNotify && IsInComposedDoc() && mIsDoneAddingChildren && aNameSpaceID == kNameSpaceID_None && aName == URIAttrName() - && !BlockEmbedContentLoading()) { + && !BlockEmbedOrObjectContentLoading()) { return LoadObject(aNotify, true); } @@ -313,7 +313,7 @@ HTMLSharedObjectElement::StartObjectLoad(bool aNotify, bool aForceLoad) // BindToTree can call us asynchronously, and we may be removed from the tree // in the interim if (!IsInComposedDoc() || !OwnerDoc()->IsActive() || - BlockEmbedContentLoading()) { + BlockEmbedOrObjectContentLoading()) { return; } @@ -389,31 +389,5 @@ HTMLSharedObjectElement::GetContentPolicyType() const } } -bool -HTMLSharedObjectElement::BlockEmbedContentLoading() -{ - // Only check on embed elements - if (!IsHTMLElement(nsGkAtoms::embed)) { - return false; - } - // Traverse up the node tree to see if we have any ancestors that may block us - // from loading - for (nsIContent* parent = GetParent(); parent; parent = parent->GetParent()) { - if (parent->IsAnyOfHTMLElements(nsGkAtoms::video, nsGkAtoms::audio)) { - return true; - } - // If we have an ancestor that is an object with a source, it'll have an - // associated displayed type. If that type is not null, don't load content - // for the embed. - if (HTMLObjectElement* object = HTMLObjectElement::FromContent(parent)) { - uint32_t type = object->DisplayedType(); - if (type != eType_Null) { - return true; - } - } - } - return false; -} - } // namespace dom } // namespace mozilla diff --git a/dom/html/HTMLSharedObjectElement.h b/dom/html/HTMLSharedObjectElement.h index 3d51d0a996b6..a6e7fe65d250 100644 --- a/dom/html/HTMLSharedObjectElement.h +++ b/dom/html/HTMLSharedObjectElement.h @@ -220,21 +220,6 @@ private: static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes, GenericSpecifiedValues* aGenericData); - - /** - * Decides whether we should load embed node content. - * - * If this is an embed node there are cases in which we should not try to load - * the content: - * - * - If the embed node is the child of a media element - * - If the embed node is the child of an object node that already has - * content being loaded. - * - * In these cases, this function will return false, which will cause - * us to skip calling LoadObject. - */ - bool BlockEmbedContentLoading(); }; } // namespace dom diff --git a/dom/html/nsGenericHTMLFrameElement.cpp b/dom/html/nsGenericHTMLFrameElement.cpp index 76056536af4d..4b5b71a5965f 100644 --- a/dom/html/nsGenericHTMLFrameElement.cpp +++ b/dom/html/nsGenericHTMLFrameElement.cpp @@ -453,18 +453,28 @@ nsGenericHTMLFrameElement::IsHTMLFocusable(bool aWithMouse, return false; } +static bool sMozBrowserFramesEnabled = false; +#ifdef DEBUG +static bool sBoolVarCacheInitialized = false; +#endif + +void +nsGenericHTMLFrameElement::InitStatics() +{ + MOZ_ASSERT(!sBoolVarCacheInitialized); + MOZ_ASSERT(NS_IsMainThread()); + Preferences::AddBoolVarCache(&sMozBrowserFramesEnabled, + "dom.mozBrowserFramesEnabled"); +#ifdef DEBUG + sBoolVarCacheInitialized = true; +#endif +} + + bool nsGenericHTMLFrameElement::BrowserFramesEnabled() { - static bool sMozBrowserFramesEnabled = false; - static bool sBoolVarCacheInitialized = false; - - if (!sBoolVarCacheInitialized) { - sBoolVarCacheInitialized = true; - Preferences::AddBoolVarCache(&sMozBrowserFramesEnabled, - "dom.mozBrowserFramesEnabled"); - } - + MOZ_ASSERT(sBoolVarCacheInitialized); return sMozBrowserFramesEnabled; } diff --git a/dom/html/nsGenericHTMLFrameElement.h b/dom/html/nsGenericHTMLFrameElement.h index d9c2df9d5714..fd565e8bb5e8 100644 --- a/dom/html/nsGenericHTMLFrameElement.h +++ b/dom/html/nsGenericHTMLFrameElement.h @@ -71,6 +71,8 @@ public: virtual int32_t TabIndexDefault() override; + virtual nsIMozBrowserFrame* GetAsMozBrowserFrame() override { return this; } + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsGenericHTMLFrameElement, nsGenericHTMLElement) @@ -86,6 +88,7 @@ public: void PresetOpenerWindow(mozIDOMWindowProxy* aOpenerWindow, mozilla::ErrorResult& aRv); + static void InitStatics(); static bool BrowserFramesEnabled(); /** diff --git a/dom/html/test/forms/test_step_attribute.html b/dom/html/test/forms/test_step_attribute.html index 31277860c9d9..a14afa46125d 100644 --- a/dom/html/test/forms/test_step_attribute.html +++ b/dom/html/test/forms/test_step_attribute.html @@ -31,8 +31,7 @@ var data = [ { type: 'month', apply: true }, { type: 'week', apply: true }, { type: 'time', apply: true }, - // TODO: temporary set to false until bug 888331 is fixed. - { type: 'datetime-local', apply: false }, + { type: 'datetime-local', apply: true }, { type: 'number', apply: true }, { type: 'range', apply: true }, { type: 'color', apply: false }, @@ -950,7 +949,104 @@ for (var test of data) { break; case 'datetime-local': - // TODO: this is temporary until bug 888331 is fixed. + // When step is invalid, every datetime is valid + input.step = 0; + input.value = '2017-02-06T12:00'; + checkValidity(input, true, apply); + + input.step = 'foo'; + input.value = '1970-01-01T00:00'; + checkValidity(input, true, apply); + + input.step = '-1'; + input.value = '1969-12-12 00:10'; + checkValidity(input, true, apply); + + input.removeAttribute('step'); + input.value = '1500-01-01T12:00'; + checkValidity(input, true, apply); + + input.step = 'any'; + input.value = '1966-12-12T12:00'; + checkValidity(input, true, apply); + + input.step = 'ANY'; + input.value = '2017-01-01 12:00'; + checkValidity(input, true, apply); + + // When min is set to a valid datetime, there is a step base. + input.min = '2017-01-01T00:00:00'; + input.step = '2'; + input.value = '2017-01-01T00:00:02'; + checkValidity(input, true, apply); + + input.value = '2017-01-01T00:00:03'; + checkValidity(input, false, apply, + { low: "2017-01-01T00:00:02", high: "2017-01-01T00:00:04" }); + + input.min = '2017-01-01T00:00:05'; + input.value = '2017-01-01T00:00:08'; + checkValidity(input, false, apply, + { low: "2017-01-01T00:00:07", high: "2017-01-01T00:00:09" }); + + input.min = '2000-01-01T00:00'; + input.step = '120'; + input.value = '2000-01-01T00:02'; + checkValidity(input, true, apply); + + // Without any step attribute the datetime is valid + input.removeAttribute('step'); + checkValidity(input, true, apply); + + input.min = '1950-01-01T00:00'; + input.step = '129600'; // 1.5 day + input.value = '1950-01-02T00:00'; + checkValidity(input, false, apply, + { low: "1950-01-01T00:00", high: "1950-01-02T12:00" }); + + input.step = '259200'; // 3 days + input.value = '1950-01-04T12:00'; + checkValidity(input, false, apply, + { low: "1950-01-04T00:00", high: "1950-01-07T00:00" }); + + input.value = '1950-01-10T00:00'; + checkValidity(input, true, apply); + + input.step = '0.5'; // half a second + input.value = '1950-01-01T00:00:00.123'; + checkValidity(input, false, apply, + { low: "1950-01-01T00:00", high: "1950-01-01T00:00:00.500" }); + + input.value = '2000-01-01T12:30:30.600'; + checkValidity(input, false, apply, + { low: "2000-01-01T12:30:30.500", high: "2000-01-01T12:30:31" }); + + input.value = '1950-01-05T00:00:00.500'; + checkValidity(input, true, apply); + + input.step = '2.1'; + input.min = '1991-01-01T12:00'; + input.value = '1991-01-01T12:00'; + checkValidity(input, true, apply); + + input.value = '1991-01-01T12:00:03'; + checkValidity(input, false, apply, + { low: "1991-01-01T12:00:02.100", high: "1991-01-01T12:00:04.200" }); + + input.value = '1991-01-01T12:00:06.3'; + checkValidity(input, true, apply); + + input.step = '2.1'; + input.min = '1969-12-20T10:00:05'; + input.value = '1969-12-20T10:00:05'; + checkValidity(input, true, apply); + + input.value = '1969-12-20T10:00:08'; + checkValidity(input, false, apply, + { low: "1969-12-20T10:00:07.100", high: "1969-12-20T10:00:09.200" }); + + input.value = '1969-12-20T10:00:09.200'; + checkValidity(input, true, apply); break; default: diff --git a/dom/html/test/forms/test_stepup_stepdown.html b/dom/html/test/forms/test_stepup_stepdown.html index d968951801e0..21cde58aa567 100644 --- a/dom/html/test/forms/test_stepup_stepdown.html +++ b/dom/html/test/forms/test_stepup_stepdown.html @@ -52,13 +52,8 @@ function checkAvailability() ["time", true], ["month", true], ["week", true], - ["color", false], - ]; - - var todoList = - [ - ["datetime", true], ["datetime-local", true], + ["color", false], ]; var element = document.createElement("input"); @@ -82,27 +77,6 @@ function checkAvailability() } is(exceptionCaught, !data[1], "stepUp() availability is not correct"); } - - for (data of todoList) { - var exceptionCaught = false; - element.type = data[0]; - try { - element.stepDown(); - } catch (e) { - exceptionCaught = true; - } - todo_is(exceptionCaught, !data[1], - "stepDown() availability is not correct"); - - exceptionCaught = false; - try { - element.stepUp(); - } catch (e) { - exceptionCaught = true; - } - todo_is(exceptionCaught, !data[1], - "stepUp() availability is not correct"); - } } function checkStepDown() @@ -509,6 +483,80 @@ function checkStepDown() [ '2016-W01', 'AnY', null, null, 1, null, true ], [ '2016-W01', 'aNy', null, null, 1, null, true ], ]}, + { type: 'datetime-local', data: [ + // Regular case. + [ '2017-02-07T09:30', null, null, null, null, '2017-02-07T09:29', false ], + // Argument testing. + [ '2017-02-07T09:30', null, null, null, 1, '2017-02-07T09:29', false ], + [ '2017-02-07T09:30', null, null, null, 5, '2017-02-07T09:25', false ], + [ '2017-02-07T09:30', null, null, null, -1, '2017-02-07T09:31', false ], + [ '2017-02-07T09:30', null, null, null, 0, '2017-02-07T09:30', false ], + // hour/minutes/seconds wrapping. + [ '2000-01-01T05:00', null, null, null, null, '2000-01-01T04:59', false ], + [ '2000-01-01T05:00:00', 1, null, null, null, '2000-01-01T04:59:59', false ], + [ '2000-01-01T05:00:00', 0.1, null, null, null, '2000-01-01T04:59:59.900', false ], + [ '2000-01-01T05:00:00', 0.01, null, null, null, '2000-01-01T04:59:59.990', false ], + [ '2000-01-01T05:00:00', 0.001, null, null, null, '2000-01-01T04:59:59.999', false ], + // month/year wrapping. + [ '2012-08-01T12:00', null, null, null, 1440, '2012-07-31T12:00', false ], + [ '1969-01-02T12:00', null, null, null, 5760, '1968-12-29T12:00', false ], + [ '1969-12-31T00:00', null, null, null, -1440, '1970-01-01T00:00', false ], + [ '2012-02-29T00:00', null, null, null, -1440, '2012-03-01T00:00', false ], + // stepDown() on '00:00' gives '23:59'. + [ '2017-02-07T00:00', null, null, null, 1, '2017-02-06T23:59', false ], + [ '2017-02-07T00:00', null, null, null, 3, '2017-02-06T23:57', false ], + // Some random step values.. + [ '2017-02-07T16:07', '0.5', null, null, null, '2017-02-07T16:06:59.500', false ], + [ '2017-02-07T16:07', '2', null, null, null, '2017-02-07T16:06:58', false ], + [ '2017-02-07T16:07', '0.25', null, null, 4, '2017-02-07T16:06:59', false ], + [ '2017-02-07T16:07', '1.1', '2017-02-07T16:00', null, 1, '2017-02-07T16:06:59.100', false ], + [ '2017-02-07T16:07', '1.1', '2017-02-07T16:00', null, 2, '2017-02-07T16:06:58', false ], + [ '2017-02-07T16:07', '1.1', '2017-02-07T16:00', null, 10, '2017-02-07T16:06:49.200', false ], + [ '2017-02-07T16:07', '129600', '2017-02-01T00:00', null, 2, '2017-02-05T12:00', false ], + // step = 0 isn't allowed (-> step = 1). + [ '2017-02-07T10:15', '0', null, null, null, '2017-02-07T10:14', false ], + // step < 0 isn't allowed (-> step = 1). + [ '2017-02-07T10:15', '-1', null, null, null, '2017-02-07T10:14', false ], + // step = NaN isn't allowed (-> step = 1). + [ '2017-02-07T10:15', 'foo', null, null, null, '2017-02-07T10:14', false ], + // Min values testing. + [ '2012-02-02T17:02', '60', 'foo', null, 2, '2012-02-02T17:00', false ], + [ '2012-02-02T17:10', '60', '2012-02-02T17:09', null, null, '2012-02-02T17:09', false ], + [ '2012-02-02T17:10', '60', '2012-02-02T17:10', null, null, '2012-02-02T17:10', false ], + [ '2012-02-02T17:10', '60', '2012-02-02T17:30', null, 1, '2012-02-02T17:10', false ], + [ '2012-02-02T17:10', '180', '2012-02-02T17:05', null, null, '2012-02-02T17:08', false ], + [ '2012-02-03T20:05', '86400', '2012-02-02T17:05', null, null, '2012-02-03T17:05', false ], + [ '2012-02-03T18:00', '129600', '2012-02-01T00:00', null, null, '2012-02-02T12:00', false ], + // Max values testing. + [ '2012-02-02T17:15', '60', null, 'foo', null, '2012-02-02T17:14', false ], + [ '2012-02-02T17:15', null, null, '2012-02-02T17:20', null, '2012-02-02T17:14', false ], + [ '2012-02-02T17:15', null, null, '2012-02-02T17:15', null, '2012-02-02T17:14', false ], + [ '2012-02-02T17:15', null, null, '2012-02-02T17:13', 4, '2012-02-02T17:11', false ], + [ '2012-02-02T17:15', '120', null, '2012-02-02T17:13', 3, '2012-02-02T17:09', false ], + [ '2012-02-03T20:05', '86400', null, '2012-02-03T20:05', null, '2012-02-02T20:05', false ], + [ '2012-02-03T18:00', '129600', null, '2012-02-03T20:00', null, '2012-02-02T06:00', false ], + // Step mismatch. + [ '2017-02-07T17:19', '120', '2017-02-07T17:10', null, null, '2017-02-07T17:18', false ], + [ '2017-02-07T17:19', '120', '2017-02-07T17:10', null, 2, '2017-02-07T17:16', false ], + [ '2017-02-07T17:19', '120', '2017-02-07T17:18', '2017-02-07T17:25', null, '2017-02-07T17:18', false ], + [ '2017-02-07T17:19', '120', null, null, null, '2017-02-07T17:17', false ], + [ '2017-02-07T17:19', '180', null, null, null, '2017-02-07T17:16', false ], + [ '2017-02-07T17:19', '172800', '2017-02-02T17:19', '2017-02-10T17:19', null, '2017-02-06T17:19', false ], + // Clamping. + [ '2017-02-07T17:22', null, null, '2017-02-07T17:11', null, '2017-02-07T17:11', false ], + [ '2017-02-07T17:22', '120', '2017-02-07T17:20', '2017-02-07T17:22', null, '2017-02-07T17:20', false ], + [ '2017-02-07T17:22', '300', '2017-02-07T17:12', '2017-02-07T17:20', 10, '2017-02-07T17:12', false ], + [ '2017-02-07T17:22', '300', '2017-02-07T17:18', '2017-02-07T17:20', 2, '2017-02-07T17:18', false ], + [ '2017-02-07T17:22', '600', '2017-02-02T17:00', '2017-02-07T17:00', 15, '2017-02-07T15:00', false ], + [ '2017-02-07T17:22', '600', '2017-02-02T17:00', '2017-02-07T17:00', 2, '2017-02-07T17:00', false ], + // value = "" (NaN). + [ '', null, null, null, null, '1969-12-31T23:59', false ], + // With step = 'any'. + [ '2017-02-07T15:20', 'any', null, null, 1, null, true ], + [ '2017-02-07T15:20', 'ANY', null, null, 1, null, true ], + [ '2017-02-07T15:20', 'AnY', null, null, 1, null, true ], + [ '2017-02-07T15:20', 'aNy', null, null, 1, null, true ], + ]}, ]; for (var test of testData) { @@ -958,6 +1006,78 @@ function checkStepUp() [ '2016-W01', 'AnY', null, null, 1, null, true ], [ '2016-W01', 'aNy', null, null, 1, null, true ], ]}, + { type: 'datetime-local', data: [ + // Regular case. + [ '2017-02-07T17:09', null, null, null, null, '2017-02-07T17:10', false ], + // Argument testing. + [ '2017-02-07T17:10', null, null, null, 1, '2017-02-07T17:11', false ], + [ '2017-02-07T17:10', null, null, null, 5, '2017-02-07T17:15', false ], + [ '2017-02-07T17:10', null, null, null, -1, '2017-02-07T17:09', false ], + [ '2017-02-07T17:10', null, null, null, 0, '2017-02-07T17:10', false ], + // hour/minutes/seconds wrapping. + [ '2000-01-01T04:59', null, null, null, null, '2000-01-01T05:00', false ], + [ '2000-01-01T04:59:59', 1, null, null, null, '2000-01-01T05:00', false ], + [ '2000-01-01T04:59:59.900', 0.1, null, null, null, '2000-01-01T05:00', false ], + [ '2000-01-01T04:59:59.990', 0.01, null, null, null, '2000-01-01T05:00', false ], + [ '2000-01-01T04:59:59.999', 0.001, null, null, null, '2000-01-01T05:00', false ], + // month/year wrapping. + [ '2012-07-31T12:00', null, null, null, 1440, '2012-08-01T12:00', false ], + [ '1968-12-29T12:00', null, null, null, 5760, '1969-01-02T12:00', false ], + [ '1970-01-01T00:00', null, null, null, -1440, '1969-12-31T00:00', false ], + [ '2012-03-01T00:00', null, null, null, -1440, '2012-02-29T00:00', false ], + // stepUp() on '23:59' gives '00:00'. + [ '2017-02-07T23:59', null, null, null, 1, '2017-02-08T00:00', false ], + [ '2017-02-07T23:59', null, null, null, 3, '2017-02-08T00:02', false ], + // Some random step values.. + [ '2017-02-07T17:40', '0.5', null, null, null, '2017-02-07T17:40:00.500', false ], + [ '2017-02-07T17:40', '2', null, null, null, '2017-02-07T17:40:02', false ], + [ '2017-02-07T17:40', '0.25', null, null, 4, '2017-02-07T17:40:01', false ], + [ '2017-02-07T17:40', '1.1', '2017-02-07T17:00', null, 1, '2017-02-07T17:40:00.200', false ], + [ '2017-02-07T17:40', '1.1', '2017-02-07T17:00', null, 2, '2017-02-07T17:40:01.300', false ], + [ '2017-02-07T17:40', '1.1', '2017-02-07T17:00', null, 10, '2017-02-07T17:40:10.100', false ], + [ '2017-02-07T17:40', '129600', '2017-02-01T00:00', null, 2, '2017-02-10T00:00', false ], + // step = 0 isn't allowed (-> step = 1). + [ '2017-02-07T17:39', '0', null, null, null, '2017-02-07T17:40', false ], + // step < 0 isn't allowed (-> step = 1). + [ '2017-02-07T17:39', '-1', null, null, null, '2017-02-07T17:40', false ], + // step = NaN isn't allowed (-> step = 1). + [ '2017-02-07T17:39', 'foo', null, null, null, '2017-02-07T17:40', false ], + // Min values testing. + [ '2012-02-02T17:00', '60', 'foo', null, 2, '2012-02-02T17:02', false ], + [ '2012-02-02T17:10', '60', '2012-02-02T17:10', null, null, '2012-02-02T17:11', false ], + [ '2012-02-02T17:10', '60', '2012-02-02T17:30', null, 1, '2012-02-02T17:30', false ], + [ '2012-02-02T17:10', '180', '2012-02-02T17:05', null, null, '2012-02-02T17:11', false ], + [ '2012-02-02T17:10', '86400', '2012-02-02T17:05', null, null, '2012-02-03T17:05', false ], + [ '2012-02-02T17:10', '129600', '2012-02-01T00:00', null, null, '2012-02-04T00:00', false ], + // Max values testing. + [ '2012-02-02T17:15', '60', null, 'foo', null, '2012-02-02T17:16', false ], + [ '2012-02-02T17:15', null, null, '2012-02-02T17:20', null, '2012-02-02T17:16', false ], + [ '2012-02-02T17:15', null, null, '2012-02-02T17:15', null, '2012-02-02T17:15', false ], + [ '2012-02-02T17:15', null, null, '2012-02-02T17:13', 4, '2012-02-02T17:15', false ], + [ '2012-02-02T20:05', '86400', null, '2012-02-03T20:05', null, '2012-02-03T20:05', false ], + [ '2012-02-02T18:00', '129600', null, '2012-02-04T20:00', null, '2012-02-04T06:00', false ], + // Step mismatch. + [ '2017-02-07T17:19', '120', '2017-02-07T17:10', null, null, '2017-02-07T17:20', false ], + [ '2017-02-07T17:19', '120', '2017-02-07T17:10', null, 2, '2017-02-07T17:22', false ], + [ '2017-02-07T17:19', '120', '2017-02-07T17:18', '2017-02-07T17:25', null, '2017-02-07T17:20', false ], + [ '2017-02-07T17:19', '120', null, null, null, '2017-02-07T17:21', false ], + [ '2017-02-07T17:19', '180', null, null, null, '2017-02-07T17:22', false ], + [ '2017-02-03T17:19', '172800', '2017-02-02T17:19', '2017-02-10T17:19', null, '2017-02-04T17:19', false ], + // Clamping. + [ '2017-02-07T17:22', null, null, '2017-02-07T17:11', null, '2017-02-07T17:22', false ], + [ '2017-02-07T17:22', '120', '2017-02-07T17:20', '2017-02-07T17:22', null, '2017-02-07T17:22', false ], + [ '2017-02-07T17:22', '300', '2017-02-07T17:12', '2017-02-07T17:20', 10, '2017-02-07T17:22', false ], + [ '2017-02-07T17:22', '300', '2017-02-07T17:18', '2017-02-07T17:20', 2, '2017-02-07T17:22', false ], + [ '2017-02-06T17:22', '600', '2017-02-02T17:00', '2017-02-07T17:20', 15, '2017-02-06T19:50', false ], + [ '2017-02-06T17:22', '600', '2017-02-02T17:10', '2017-02-07T17:20', 2, '2017-02-06T17:40', false ], + // value = "" (NaN). + [ '', null, null, null, null, '1970-01-01T00:01', false ], + // With step = 'any'. + [ '2017-02-07T17:30', 'any', null, null, 1, null, true ], + [ '2017-02-07T17:30', 'ANY', null, null, 1, null, true ], + [ '2017-02-07T17:30', 'AnY', null, null, 1, null, true ], + [ '2017-02-07T17:30', 'aNy', null, null, 1, null, true ], + ]}, ]; for (var test of testData) { diff --git a/dom/ipc/ContentPrefs.cpp b/dom/ipc/ContentPrefs.cpp index 714c18f76202..6d65b4914cfc 100644 --- a/dom/ipc/ContentPrefs.cpp +++ b/dom/ipc/ContentPrefs.cpp @@ -42,6 +42,7 @@ const char* mozilla::dom::ContentPrefs::gInitPrefs[] = { "dom.ipc.processPriorityManager.backgroundPerceivableGracePeriodMS", "dom.max_chrome_script_run_time", "dom.max_script_run_time", + "dom.mozBrowserFramesEnabled", "dom.performance.enable_notify_performance_timing", "dom.performance.enable_user_timing_logging", "dom.storage.testing", diff --git a/dom/plugins/ipc/PPluginModule.ipdl b/dom/plugins/ipc/PPluginModule.ipdl index 29de2048545c..369f3ecf7182 100644 --- a/dom/plugins/ipc/PPluginModule.ipdl +++ b/dom/plugins/ipc/PPluginModule.ipdl @@ -160,7 +160,7 @@ parent: async ReturnSitesWithData(nsCString[] aSites, uint64_t aCallbackId); - sync GetKeyState(int32_t aVirtKey) + intr GetKeyState(int32_t aVirtKey) returns (int16_t aState); intr NPN_SetValue_NPPVpluginRequiresAudioDeviceChanges(bool shouldRegister) diff --git a/dom/plugins/ipc/PluginModuleChild.cpp b/dom/plugins/ipc/PluginModuleChild.cpp index 87e8598a502d..ba3cf9f7c311 100644 --- a/dom/plugins/ipc/PluginModuleChild.cpp +++ b/dom/plugins/ipc/PluginModuleChild.cpp @@ -2118,7 +2118,7 @@ PMCGetKeyState(int aVirtKey) PluginModuleChild* chromeInstance = PluginModuleChild::GetChrome(); if (chromeInstance) { int16_t ret = 0; - if (chromeInstance->SendGetKeyState(aVirtKey, &ret)) { + if (chromeInstance->CallGetKeyState(aVirtKey, &ret)) { return ret; } } diff --git a/dom/plugins/ipc/PluginModuleParent.cpp b/dom/plugins/ipc/PluginModuleParent.cpp index dbf11cc1b4b1..84c1925dae0a 100644 --- a/dom/plugins/ipc/PluginModuleParent.cpp +++ b/dom/plugins/ipc/PluginModuleParent.cpp @@ -3403,19 +3403,19 @@ PluginModuleChromeParent::RecvProfile(const nsCString& aProfile) } mozilla::ipc::IPCResult -PluginModuleParent::RecvGetKeyState(const int32_t& aVirtKey, int16_t* aRet) +PluginModuleParent::AnswerGetKeyState(const int32_t& aVirtKey, int16_t* aRet) { return IPC_FAIL_NO_REASON(this); } mozilla::ipc::IPCResult -PluginModuleChromeParent::RecvGetKeyState(const int32_t& aVirtKey, +PluginModuleChromeParent::AnswerGetKeyState(const int32_t& aVirtKey, int16_t* aRet) { #if defined(XP_WIN) *aRet = ::GetKeyState(aVirtKey); return IPC_OK(); #else - return PluginModuleParent::RecvGetKeyState(aVirtKey, aRet); + return PluginModuleParent::AnswerGetKeyState(aVirtKey, aRet); #endif } diff --git a/dom/plugins/ipc/PluginModuleParent.h b/dom/plugins/ipc/PluginModuleParent.h index dc56749701c8..25e251c7452a 100644 --- a/dom/plugins/ipc/PluginModuleParent.h +++ b/dom/plugins/ipc/PluginModuleParent.h @@ -213,7 +213,7 @@ protected: virtual mozilla::ipc::IPCResult RecvProfile(const nsCString& aProfile) override { return IPC_OK(); } - virtual mozilla::ipc::IPCResult RecvGetKeyState(const int32_t& aVirtKey, int16_t* aRet) override; + virtual mozilla::ipc::IPCResult AnswerGetKeyState(const int32_t& aVirtKey, int16_t* aRet) override; virtual mozilla::ipc::IPCResult RecvReturnClearSiteData(const NPError& aRv, const uint64_t& aCallbackId) override; @@ -507,7 +507,7 @@ class PluginModuleChromeParent RecvProfile(const nsCString& aProfile) override; virtual mozilla::ipc::IPCResult - RecvGetKeyState(const int32_t& aVirtKey, int16_t* aRet) override; + AnswerGetKeyState(const int32_t& aVirtKey, int16_t* aRet) override; private: virtual void diff --git a/dom/plugins/test/mochitest/mochitest.ini b/dom/plugins/test/mochitest/mochitest.ini index 9f882bf6b38a..f70137dfeaba 100644 --- a/dom/plugins/test/mochitest/mochitest.ini +++ b/dom/plugins/test/mochitest/mochitest.ini @@ -124,7 +124,9 @@ skip-if = true # Bug 596491 [test_pluginstream_asfileonly.html] [test_pluginstream_err.html] [test_pluginstream_geturl.html] +skip-if = true # Bug 1267432 [test_pluginstream_geturlnotify.html] +skip-if = true # Bug 1267432 [test_pluginstream_newstream.html] [test_pluginstream_post.html] [test_pluginstream_poststream.html] diff --git a/dom/tests/mochitest/general/resource_timing_cross_origin.html b/dom/tests/mochitest/general/resource_timing_cross_origin.html index c5b906280744..6a82885a74c4 100644 --- a/dom/tests/mochitest/general/resource_timing_cross_origin.html +++ b/dom/tests/mochitest/general/resource_timing_cross_origin.html @@ -170,16 +170,16 @@ function finishTests() {

- - - - - - - - - - + + + + + + + + + + diff --git a/dom/tests/mochitest/general/test_focusrings.xul b/dom/tests/mochitest/general/test_focusrings.xul index 1e3896b8baed..1833b9393eb7 100644 --- a/dom/tests/mochitest/general/test_focusrings.xul +++ b/dom/tests/mochitest/general/test_focusrings.xul @@ -168,7 +168,7 @@ SimpleTest.waitForFocus(runTest);