Bug 591737 - Add pref for details and summary elements
--- a/dom/html/HTMLDetailsElement.cpp
+++ b/dom/html/HTMLDetailsElement.cpp
@@ -1,22 +1,49 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/HTMLDetailsElement.h"
#include "mozilla/dom/HTMLDetailsElementBinding.h"
+#include "mozilla/dom/HTMLUnknownElement.h"
+#include "mozilla/Preferences.h"
-NS_IMPL_NS_NEW_HTML_ELEMENT(Details)
+// Expand NS_IMPL_NS_NEW_HTML_ELEMENT(Details) to add pref check.
+nsGenericHTMLElement*
+NS_NewHTMLDetailsElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
+ mozilla::dom::FromParser aFromParser)
+{
+ if (!mozilla::dom::HTMLDetailsElement::IsDetailsEnabled()) {
+ return new mozilla::dom::HTMLUnknownElement(aNodeInfo);
+ }
+
+ return new mozilla::dom::HTMLDetailsElement(aNodeInfo);
+}
namespace mozilla {
namespace dom {
+bool
+HTMLDetailsElement::IsDetailsEnabled()
+{
+ static bool isDetailsEnabled = false;
+ static bool added = false;
+
+ if (!added) {
+ Preferences::AddBoolVarCache(&isDetailsEnabled,
+ "dom.details_element.enabled");
+ added = true;
+ }
+
+ return isDetailsEnabled;
+}
+
HTMLDetailsElement::~HTMLDetailsElement()
{
}
NS_IMPL_ELEMENT_CLONE(HTMLDetailsElement)
nsIContent*
HTMLDetailsElement::GetFirstSummary() const
--- a/dom/html/HTMLDetailsElement.h
+++ b/dom/html/HTMLDetailsElement.h
@@ -17,16 +17,18 @@ namespace dom {
// controls. Please see the spec for more information.
// https://html.spec.whatwg.org/multipage/forms.html#the-details-element
//
class HTMLDetailsElement final : public nsGenericHTMLElement
{
public:
using NodeInfo = mozilla::dom::NodeInfo;
+ static bool IsDetailsEnabled();
+
explicit HTMLDetailsElement(already_AddRefed<NodeInfo>& aNodeInfo)
: nsGenericHTMLElement(aNodeInfo)
{
}
NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLDetailsElement, details)
nsIContent* GetFirstSummary() const;
--- a/dom/html/HTMLSummaryElement.cpp
+++ b/dom/html/HTMLSummaryElement.cpp
@@ -2,19 +2,31 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/HTMLSummaryElement.h"
#include "mozilla/dom/HTMLDetailsElement.h"
#include "mozilla/dom/HTMLElementBinding.h"
+#include "mozilla/dom/HTMLUnknownElement.h"
#include "mozilla/MouseEvents.h"
+#include "mozilla/Preferences.h"
-NS_IMPL_NS_NEW_HTML_ELEMENT(Summary)
+// Expand NS_IMPL_NS_NEW_HTML_ELEMENT(Summary) to add pref check.
+nsGenericHTMLElement*
+NS_NewHTMLSummaryElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
+ mozilla::dom::FromParser aFromParser)
+{
+ if (!mozilla::dom::HTMLDetailsElement::IsDetailsEnabled()) {
+ return new mozilla::dom::HTMLUnknownElement(aNodeInfo);
+ }
+
+ return new mozilla::dom::HTMLSummaryElement(aNodeInfo);
+}
namespace mozilla {
namespace dom {
HTMLSummaryElement::~HTMLSummaryElement()
{
}
--- a/dom/tests/mochitest/general/test_interfaces.html
+++ b/dom/tests/mochitest/general/test_interfaces.html
@@ -539,17 +539,17 @@ var interfaceNamesInGlobalScope =
"HTMLCollection",
// IMPORTANT: Do not change this list without review from a DOM peer!
"HTMLContentElement",
// IMPORTANT: Do not change this list without review from a DOM peer!
"HTMLDataElement",
// IMPORTANT: Do not change this list without review from a DOM peer!
"HTMLDataListElement",
// IMPORTANT: Do not change this list without review from a DOM peer!
- "HTMLDetailsElement",
+ {name: "HTMLDetailsElement", disabled: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
"HTMLDirectoryElement",
// IMPORTANT: Do not change this list without review from a DOM peer!
"HTMLDivElement",
// IMPORTANT: Do not change this list without review from a DOM peer!
"HTMLDListElement",
// IMPORTANT: Do not change this list without review from a DOM peer!
"HTMLDocument",
--- a/dom/webidl/HTMLDetailsElement.webidl
+++ b/dom/webidl/HTMLDetailsElement.webidl
@@ -6,12 +6,13 @@
* The origin of this IDL file is
* https://html.spec.whatwg.org/multipage/forms.html#the-details-element
*
* © Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and
* Opera Software ASA. You are granted a license to use, reproduce
* and create derivative works of this document.
*/
+[Pref="dom.details_element.enabled"]
interface HTMLDetailsElement : HTMLElement {
[SetterThrows]
attribute boolean open;
};
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -3532,16 +3532,22 @@ nsCSSFrameConstructor::FindHTMLData(Elem
// <legend> is only special inside fieldset, we only check the frame tree
// parent because the content tree parent may not be a <fieldset> due to
// display:contents, Shadow DOM, or XBL. For floated or absolutely
// positioned legends we want to construct by display type and
// not do special legend stuff.
return nullptr;
}
+ if (aTag == nsGkAtoms::details || aTag == nsGkAtoms::summary) {
+ if (!HTMLDetailsElement::IsDetailsEnabled()) {
+ return nullptr;
+ }
+ }
+
if (aTag == nsGkAtoms::summary &&
(!aParentFrame || aParentFrame->GetType() != nsGkAtoms::detailsFrame)) {
// <summary> is special only if it is a direct child of <details>. If it
// isn't, construct it as a normal block frame instead of a summary frame.
return nullptr;
}
static const FrameConstructionDataByTag sHTMLData[] = {
--- a/layout/generic/crashtests/crashtests.list
+++ b/layout/generic/crashtests/crashtests.list
@@ -597,24 +597,24 @@ load 1222783.xhtml
load 1223568-1.html
load 1223568-2.html
load 1224230-1.html
pref(layout.css.grid.enabled,true) load 1225118.html
pref(layout.css.grid.enabled,true) load 1225376.html
pref(layout.css.grid.enabled,true) load 1225592.html
load 1229437-1.html
load 1229437-2.html
-load details-containing-only-text.html
-load details-open-overflow-auto.html
-load details-open-overflow-hidden.html
-load details-three-columns.html
+pref(dom.details_element.enabled,true) load details-containing-only-text.html
+pref(dom.details_element.enabled,true) load details-open-overflow-auto.html
+pref(dom.details_element.enabled,true) load details-open-overflow-hidden.html
+pref(dom.details_element.enabled,true) load details-three-columns.html
load first-letter-638937-1.html
load first-letter-638937-2.html
pref(dom.meta-viewport.enabled,true) test-pref(font.size.inflation.emPerLine,15) asserts(0-100) load font-inflation-762332.html # bug 762332
load outline-on-frameset.xhtml
-load summary-position-out-of-flow.html
+pref(dom.details_element.enabled,true) load summary-position-out-of-flow.html
load text-overflow-bug666751-1.html
load text-overflow-bug666751-2.html
load text-overflow-bug670564.xhtml
load text-overflow-bug671796.xhtml
load text-overflow-bug713610.html
load text-overflow-form-elements.html
load text-overflow-iframe.html
--- a/layout/reftests/details-summary/reftest.list
+++ b/layout/reftests/details-summary/reftest.list
@@ -1,69 +1,69 @@
# Basic <summary> handling
-== multiple-summary.html single-summary.html
-== open-multiple-summary.html open-multiple-summary-ref.html
-== summary-not-first-child.html single-summary.html
-== open-summary-not-first-child.html open-single-summary.html
-== open-summary-block-style.html open-single-summary.html
-== no-summary.html no-summary-ref.html
-== open-no-summary.html open-no-summary-ref.html
-== summary-not-in-details.html summary-not-in-details-ref.html
-== summary-not-direct-child.html summary-not-direct-child-ref.html
-== float-in-summary.html float-in-summary-ref.html
+pref(dom.details_element.enabled,true) == multiple-summary.html single-summary.html
+pref(dom.details_element.enabled,true) == open-multiple-summary.html open-multiple-summary-ref.html
+pref(dom.details_element.enabled,true) == summary-not-first-child.html single-summary.html
+pref(dom.details_element.enabled,true) == open-summary-not-first-child.html open-single-summary.html
+pref(dom.details_element.enabled,true) == open-summary-block-style.html open-single-summary.html
+pref(dom.details_element.enabled,true) == no-summary.html no-summary-ref.html
+pref(dom.details_element.enabled,true) == open-no-summary.html open-no-summary-ref.html
+pref(dom.details_element.enabled,true) == summary-not-in-details.html summary-not-in-details-ref.html
+pref(dom.details_element.enabled,true) == summary-not-direct-child.html summary-not-direct-child-ref.html
+pref(dom.details_element.enabled,true) == float-in-summary.html float-in-summary-ref.html
# Add elements dynamically
-== dynamic-add-single-summary.html open-single-summary.html
-== dynamic-add-summary-not-first-child.html open-single-summary.html
-== dynamic-add-summary-and-paragraph.html open-single-summary.html
-== dynamic-add-paragraph-before-summary.html open-single-summary.html
-== dynamic-add-paragraph-before-summary-close.html single-summary.html
-== dynamic-add-paragraph-after-summary.html open-single-summary.html
-== dynamic-add-paragraph-after-summary-close.html single-summary.html
-== dynamic-add-details.html open-single-summary.html
-== dynamic-add-first-summary.html open-multiple-summary.html
-== dynamic-add-second-summary.html open-multiple-summary.html
+pref(dom.details_element.enabled,true) == dynamic-add-single-summary.html open-single-summary.html
+pref(dom.details_element.enabled,true) == dynamic-add-summary-not-first-child.html open-single-summary.html
+pref(dom.details_element.enabled,true) == dynamic-add-summary-and-paragraph.html open-single-summary.html
+pref(dom.details_element.enabled,true) == dynamic-add-paragraph-before-summary.html open-single-summary.html
+pref(dom.details_element.enabled,true) == dynamic-add-paragraph-before-summary-close.html single-summary.html
+pref(dom.details_element.enabled,true) == dynamic-add-paragraph-after-summary.html open-single-summary.html
+pref(dom.details_element.enabled,true) == dynamic-add-paragraph-after-summary-close.html single-summary.html
+pref(dom.details_element.enabled,true) == dynamic-add-details.html open-single-summary.html
+pref(dom.details_element.enabled,true) == dynamic-add-first-summary.html open-multiple-summary.html
+pref(dom.details_element.enabled,true) == dynamic-add-second-summary.html open-multiple-summary.html
# Remove elements dynamically
-== dynamic-remove-single-summary.html open-no-summary.html
-== dynamic-remove-summary-not-first-child.html open-no-summary.html
-== dynamic-remove-first-summary.html open-single-summary.html
-== dynamic-remove-second-summary.html open-single-summary.html
+pref(dom.details_element.enabled,true) == dynamic-remove-single-summary.html open-no-summary.html
+pref(dom.details_element.enabled,true) == dynamic-remove-summary-not-first-child.html open-no-summary.html
+pref(dom.details_element.enabled,true) == dynamic-remove-first-summary.html open-single-summary.html
+pref(dom.details_element.enabled,true) == dynamic-remove-second-summary.html open-single-summary.html
# Toggle details by open attribute
-== close-nested-details.html close-nested-details-ref.html
-== open-nested-details.html open-nested-details-ref.html
+pref(dom.details_element.enabled,true) == close-nested-details.html close-nested-details-ref.html
+pref(dom.details_element.enabled,true) == open-nested-details.html open-nested-details-ref.html
# With 'overflow' property
-== overflow-hidden-open-details.html overflow-hidden-open-details-ref.html
-== overflow-auto-open-details.html overflow-auto-open-details-ref.html
+pref(dom.details_element.enabled,true) == overflow-hidden-open-details.html overflow-hidden-open-details-ref.html
+pref(dom.details_element.enabled,true) == overflow-auto-open-details.html overflow-auto-open-details-ref.html
# With pagination property
-== details-page-break-after-1.html details-two-pages.html
-== details-page-break-after-2.html details-two-pages.html
-== details-page-break-before-1.html details-two-pages.html
-== details-page-break-before-2.html details-two-pages.html
+pref(dom.details_element.enabled,true) == details-page-break-after-1.html details-two-pages.html
+pref(dom.details_element.enabled,true) == details-page-break-after-2.html details-two-pages.html
+pref(dom.details_element.enabled,true) == details-page-break-before-1.html details-two-pages.html
+pref(dom.details_element.enabled,true) == details-page-break-before-2.html details-two-pages.html
# Various properties on details or summary
-== details-display-inline.html details-display-inline-ref.html
-== details-percentage-height-children.html details-percentage-height-children-ref.html
-== details-absolute-children.html details-absolute-children-ref.html
-== details-three-columns.html details-three-columns-ref.html
-== details-writing-mode.html details-writing-mode-ref.html
-== details-in-ol.html details-in-ol-ref.html
+pref(dom.details_element.enabled,true) == details-display-inline.html details-display-inline-ref.html
+pref(dom.details_element.enabled,true) == details-percentage-height-children.html details-percentage-height-children-ref.html
+pref(dom.details_element.enabled,true) == details-absolute-children.html details-absolute-children-ref.html
+pref(dom.details_element.enabled,true) == details-three-columns.html details-three-columns-ref.html
+pref(dom.details_element.enabled,true) == details-writing-mode.html details-writing-mode-ref.html
+pref(dom.details_element.enabled,true) == details-in-ol.html details-in-ol-ref.html
# Dispatch mouse click to summary
-== mouse-click-single-summary.html open-single-summary.html
-== mouse-click-twice-single-summary.html single-summary.html
-== mouse-click-open-single-summary.html single-summary.html
-== mouse-click-twice-open-single-summary.html open-single-summary.html
-== mouse-click-open-second-summary.html open-multiple-summary.html
-== mouse-click-overflow-hidden-details.html overflow-hidden-open-details.html
-== mouse-click-twice-overflow-hidden-details.html overflow-hidden-details.html
-== mouse-click-overflow-auto-details.html overflow-auto-open-details.html
-== mouse-click-twice-overflow-auto-details.html overflow-auto-details.html
-== mouse-click-display-none-details.html single-summary.html
+pref(dom.details_element.enabled,true) == mouse-click-single-summary.html open-single-summary.html
+pref(dom.details_element.enabled,true) == mouse-click-twice-single-summary.html single-summary.html
+pref(dom.details_element.enabled,true) == mouse-click-open-single-summary.html single-summary.html
+pref(dom.details_element.enabled,true) == mouse-click-twice-open-single-summary.html open-single-summary.html
+pref(dom.details_element.enabled,true) == mouse-click-open-second-summary.html open-multiple-summary.html
+pref(dom.details_element.enabled,true) == mouse-click-overflow-hidden-details.html overflow-hidden-open-details.html
+pref(dom.details_element.enabled,true) == mouse-click-twice-overflow-hidden-details.html overflow-hidden-details.html
+pref(dom.details_element.enabled,true) == mouse-click-overflow-auto-details.html overflow-auto-open-details.html
+pref(dom.details_element.enabled,true) == mouse-click-twice-overflow-auto-details.html overflow-auto-details.html
+pref(dom.details_element.enabled,true) == mouse-click-display-none-details.html single-summary.html
# Dispatch mouse click to out-of-flow details or summary
-== mouse-click-fixed-summary.html open-fixed-summary.html
-== mouse-click-twice-fixed-summary.html fixed-summary.html
-== mouse-click-float-details.html open-float-details.html
-== mouse-click-twice-float-details.html float-details.html
+pref(dom.details_element.enabled,true) == mouse-click-fixed-summary.html open-fixed-summary.html
+pref(dom.details_element.enabled,true) == mouse-click-twice-fixed-summary.html fixed-summary.html
+pref(dom.details_element.enabled,true) == mouse-click-float-details.html open-float-details.html
+pref(dom.details_element.enabled,true) == mouse-click-twice-float-details.html float-details.html
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -5150,16 +5150,19 @@ pref("reader.toolbar.vertical", true);
// Whether to allow, on a Linux system that doesn't support the necessary sandboxing
// features, loading Gecko Media Plugins unsandboxed. However, EME CDMs will not be
// loaded without sandboxing even if this pref is changed.
pref("media.gmp.insecure.allow", false);
#endif
pref("dom.audiochannel.mutedByDefault", false);
+// Enable <details> and <summary> tags.
+pref("dom.details_element.enabled", false);
+
// Secure Element API
#ifdef MOZ_SECUREELEMENT
pref("dom.secureelement.enabled", false);
#endif
// Allow control characters appear in composition string.
// When this is false, control characters except
// CHARACTER TABULATION (horizontal tab) are removed from
--- a/testing/web-platform/meta/html/dom/interfaces.html.ini
+++ b/testing/web-platform/meta/html/dom/interfaces.html.ini
@@ -1,11 +1,13 @@
[interfaces.html]
type: testharness
- prefs: [dom.forms.inputmode:true]
+ prefs: [dom.forms.inputmode:true,
+ dom.details_element.enabled:true]
+
[Document interface: attribute domain]
expected: FAIL
[Document interface: attribute cookie]
expected: FAIL
[Document interface: attribute body]
expected: FAIL
--- a/testing/web-platform/meta/html/dom/reflection-misc.html.ini
+++ b/testing/web-platform/meta/html/dom/reflection-misc.html.ini
@@ -1,10 +1,12 @@
[reflection-misc.html]
type: testharness
+ prefs: [dom.details_element.enabled:true]
+
[html.tabIndex: setAttribute() to -2147483648 followed by IDL get]
expected: FAIL
[html.tabIndex: setAttribute() to object "3" followed by getAttribute()]
expected: FAIL
[html.tabIndex: setAttribute() to object "3" followed by IDL get]
expected: FAIL
--- a/testing/web-platform/meta/html/semantics/interactive-elements/the-details-element/details.html.ini
+++ b/testing/web-platform/meta/html/semantics/interactive-elements/the-details-element/details.html.ini
@@ -1,2 +1,3 @@
[details.html]
type: testharness
+ prefs: [dom.details_element.enabled:true]
--- a/testing/web-platform/meta/html/semantics/interfaces.html.ini
+++ b/testing/web-platform/meta/html/semantics/interfaces.html.ini
@@ -1,10 +1,12 @@
[interfaces.html]
type: testharness
+ prefs: [dom.details_element.enabled:true]
+
[Interfaces for basefont]
expected: FAIL
[Interfaces for image]
expected: FAIL
[Interfaces for keygen]
expected: FAIL