diff options
author | Matt A. Tobin <email@mattatobin.com> | 2020-04-16 20:19:06 -0400 |
---|---|---|
committer | Matt A. Tobin <email@mattatobin.com> | 2020-04-16 20:19:06 -0400 |
commit | de45820b64ab03768336c7242622ef9f499347cf (patch) | |
tree | 718a67a64a29f2440850e693f8ba707f3b91c179 | |
parent | ab05e6f9ad185a1f7c405fd29876edca9e0567ba (diff) | |
download | UXP-de45820b64ab03768336c7242622ef9f499347cf.tar UXP-de45820b64ab03768336c7242622ef9f499347cf.tar.gz UXP-de45820b64ab03768336c7242622ef9f499347cf.tar.lz UXP-de45820b64ab03768336c7242622ef9f499347cf.tar.xz UXP-de45820b64ab03768336c7242622ef9f499347cf.zip |
Bug 1346623 - Allow anonymous content created with nsIDocument::InsertAnonymousContent can change from non-native to native AC
* Prevent canvas custom content from becoming NAC when reframing the root element
* Add an API to get computed style values through an AnonymousContent object
Tag #1375
-rw-r--r-- | dom/base/AnonymousContent.cpp | 27 | ||||
-rw-r--r-- | dom/base/AnonymousContent.h | 5 | ||||
-rw-r--r-- | dom/webidl/AnonymousContent.webidl | 8 | ||||
-rw-r--r-- | layout/base/nsCSSFrameConstructor.cpp | 23 | ||||
-rw-r--r-- | layout/style/test/chrome/chrome.ini | 1 | ||||
-rw-r--r-- | layout/style/test/chrome/test_bug1346623.html | 60 |
6 files changed, 120 insertions, 4 deletions
diff --git a/dom/base/AnonymousContent.cpp b/dom/base/AnonymousContent.cpp index 1df36b048..aea923f2b 100644 --- a/dom/base/AnonymousContent.cpp +++ b/dom/base/AnonymousContent.cpp @@ -7,6 +7,7 @@ #include "AnonymousContent.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/AnonymousContentBinding.h" +#include "nsComputedDOMStyle.h" #include "nsCycleCollectionParticipant.h" #include "nsIDocument.h" #include "nsIDOMHTMLCollection.h" @@ -208,5 +209,31 @@ AnonymousContent::WrapObject(JSContext* aCx, return AnonymousContentBinding::Wrap(aCx, this, aGivenProto, aReflector); } +void +AnonymousContent::GetComputedStylePropertyValue(const nsAString& aElementId, + const nsAString& aPropertyName, + DOMString& aResult, + ErrorResult& aRv) +{ + Element* element = GetElementById(aElementId); + if (!element) { + aRv.Throw(NS_ERROR_NOT_AVAILABLE); + return; + } + + nsIPresShell* shell = element->OwnerDoc()->GetShell(); + if (!shell) { + aRv.Throw(NS_ERROR_NOT_AVAILABLE); + return; + } + + RefPtr<nsComputedDOMStyle> cs = + new nsComputedDOMStyle(element, + NS_LITERAL_STRING(""), + element->OwnerDoc(), + nsComputedDOMStyle::eAll); + aRv = cs->GetPropertyValue(aPropertyName, aResult); +} + } // namespace dom } // namespace mozilla diff --git a/dom/base/AnonymousContent.h b/dom/base/AnonymousContent.h index fd3b59c44..b56c14595 100644 --- a/dom/base/AnonymousContent.h +++ b/dom/base/AnonymousContent.h @@ -68,6 +68,11 @@ public: const Sequence<OwningNonNull<DOMRect>>& aRects, ErrorResult& aError); + void GetComputedStylePropertyValue(const nsAString& aElementId, + const nsAString& aPropertyName, + DOMString& aResult, + ErrorResult& aRv); + private: ~AnonymousContent(); nsCOMPtr<Element> mContentNode; diff --git a/dom/webidl/AnonymousContent.webidl b/dom/webidl/AnonymousContent.webidl index 6755fe598..8be69cd26 100644 --- a/dom/webidl/AnonymousContent.webidl +++ b/dom/webidl/AnonymousContent.webidl @@ -77,4 +77,12 @@ interface AnonymousContent { [Throws] void setCutoutRectsForElement(DOMString elementId, sequence<DOMRect> rects); + + /** + * Get the computed value of a property on an element inside this custom + * anonymous content. + */ + [Throws] + DOMString? getComputedStylePropertyValue(DOMString elementId, + DOMString propertyName); }; diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 374764203..3be7c2a0b 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -4192,13 +4192,28 @@ nsCSSFrameConstructor::GetAnonymousContent(nsIContent* aParent, ConnectAnonymousTreeDescendants(content, aContent[i].mChildren); - // least-surprise CSS binding until we do the SVG specified - // cascading rules for <svg:use> - bug 265894 - if (aParentFrame->GetType() == nsGkAtoms::svgUseFrame) { + nsIAtom* parentFrameType = aParentFrame->GetType(); + if (parentFrameType == nsGkAtoms::svgUseFrame) { + // least-surprise CSS binding until we do the SVG specified + // cascading rules for <svg:use> - bug 265894 content->SetFlags(NODE_IS_ANONYMOUS_ROOT); } else { content->SetIsNativeAnonymousRoot(); - SetNativeAnonymousBitOnDescendants(content); + // Don't mark descendants of the custom content container + // as native anonymous. When canvas custom content is initially + // created and appended to the custom content container, in + // nsIDocument::InsertAnonymousContent, it is not considered native + // anonymous content. But if we end up reframing the root element, + // we will re-create the nsCanvasFrame, and we would end up in here, + // marking it as NAC. Existing uses of canvas custom content would + // break if it becomes NAC (since each element starts inheriting + // styles from its closest non-NAC ancestor, rather than from its + // parent). + if (!(parentFrameType == nsGkAtoms::canvasFrame && + content == static_cast<nsCanvasFrame*>(aParentFrame) + ->GetCustomContentContainer())) { + SetNativeAnonymousBitOnDescendants(content); + } } bool anonContentIsEditable = content->HasFlag(NODE_IS_EDITABLE); diff --git a/layout/style/test/chrome/chrome.ini b/layout/style/test/chrome/chrome.ini index e34fce671..dd3bdf8f5 100644 --- a/layout/style/test/chrome/chrome.ini +++ b/layout/style/test/chrome/chrome.ini @@ -10,6 +10,7 @@ support-files = mismatch.png [test_author_specified_style.html] +[test_bug1346623.html] [test_bug418986-2.xul] [test_bug1157097.html] [test_bug1160724.xul] diff --git a/layout/style/test/chrome/test_bug1346623.html b/layout/style/test/chrome/test_bug1346623.html new file mode 100644 index 000000000..d24d66646 --- /dev/null +++ b/layout/style/test/chrome/test_bug1346623.html @@ -0,0 +1,60 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for bug 1346623</title> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> +</head> +<body onload="startTest();"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1346623">Mozilla Bug 1346623</a> +<div id="display"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +var Ci = Components.interfaces; +var winUtils = window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils); + +function startTest() { + // load some styles at the agent level + var css = ` + #ac-parent { color: green; } + #ac-child.abc { } + `; + var sheetURL = "data:text/css," + encodeURIComponent(css); + winUtils.loadSheetUsingURIString(sheetURL, winUtils.AGENT_SHEET); + + // add canvas anonymous content + var bq = document.createElement("blockquote"); + bq.id = "ac-parent"; + bq.textContent = "This blockquote text should be green."; + var div = document.createElement("div"); + div.id = "ac-child"; + div.textContent = " This div text should be green."; + bq.appendChild(div); + var ac = document.insertAnonymousContent(bq); + document.body.offsetWidth; + + is(ac.getComputedStylePropertyValue("ac-child", "color"), "rgb(0, 128, 0)", + "color before reframing"); + + // reframe the root + document.documentElement.style.display = "flex"; + document.body.offsetWidth; + + // restyle the div + ac.setAttributeForElement("ac-child", "class", "abc"); + document.body.offsetWidth; + + is(ac.getComputedStylePropertyValue("ac-child", "color"), "rgb(0, 128, 0)", + "color after reframing"); + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); +</script> +</pre> +</body> +</html> |