mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-17 07:15:46 +00:00
Bug 1621415 - Ensure adopted styles are applied when printing r=emilio
- Add functionality to clone adopted style sheets for printing. - Add reftest to ensure that the document's adopted styles show in print. - Add reftest to ensure that a shadow root's adopted styles show in print. Differential Revision: https://phabricator.services.mozilla.com/D66517 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
e13b4495b3
commit
ca4fa23626
@ -12076,6 +12076,7 @@ already_AddRefed<Document> Document::CreateStaticClone(
|
||||
}
|
||||
}
|
||||
}
|
||||
clonedDoc->CloneAdoptedSheetsFrom(*this);
|
||||
|
||||
for (int t = 0; t < AdditionalSheetTypeCount; ++t) {
|
||||
auto& sheets = mAdditionalSheets[additionalSheetType(t)];
|
||||
|
@ -198,6 +198,27 @@ void DocumentOrShadowRoot::ClearAdoptedStyleSheets() {
|
||||
mAdoptedStyleSheets.Clear();
|
||||
}
|
||||
|
||||
void DocumentOrShadowRoot::CloneAdoptedSheetsFrom(
|
||||
DocumentOrShadowRoot& aSource) {
|
||||
Document& ownerDoc = *AsNode().OwnerDoc();
|
||||
Sequence<OwningNonNull<StyleSheet>> list;
|
||||
if (!list.SetCapacity(mAdoptedStyleSheets.Length(), fallible)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(nordzilla, bug 1621415) We can improve the performance here.
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1622322
|
||||
for (auto& sheet : aSource.mAdoptedStyleSheets) {
|
||||
DebugOnly<bool> succeeded =
|
||||
list.AppendElement(sheet->CloneAdoptedSheet(ownerDoc), fallible);
|
||||
MOZ_ASSERT(succeeded);
|
||||
}
|
||||
|
||||
ErrorResult rv;
|
||||
SetAdoptedStyleSheets(list, rv);
|
||||
MOZ_ASSERT(!rv.Failed());
|
||||
}
|
||||
|
||||
Element* DocumentOrShadowRoot::GetElementById(const nsAString& aElementId) {
|
||||
if (MOZ_UNLIKELY(aElementId.IsEmpty())) {
|
||||
nsContentUtils::ReportEmptyGetElementByIdArg(AsNode().OwnerDoc());
|
||||
|
@ -245,6 +245,12 @@ class DocumentOrShadowRoot {
|
||||
void RemoveSheetFromStylesIfApplicable(StyleSheet&);
|
||||
void ClearAdoptedStyleSheets();
|
||||
|
||||
/**
|
||||
* Clone's the argument's adopted style sheets into this.
|
||||
* This should only be used when cloning a static document for printing.
|
||||
*/
|
||||
void CloneAdoptedSheetsFrom(DocumentOrShadowRoot&);
|
||||
|
||||
// Returns the reference to the sheet, if found in mStyleSheets.
|
||||
already_AddRefed<StyleSheet> RemoveSheet(StyleSheet& aSheet);
|
||||
void InsertSheetAt(size_t aIndex, StyleSheet& aSheet);
|
||||
|
@ -107,6 +107,7 @@ void ShadowRoot::CloneInternalDataFrom(ShadowRoot* aOther) {
|
||||
}
|
||||
}
|
||||
}
|
||||
CloneAdoptedSheetsFrom(*aOther);
|
||||
}
|
||||
|
||||
nsresult ShadowRoot::Bind() {
|
||||
|
@ -1,5 +1,6 @@
|
||||
[DEFAULT]
|
||||
prefs =
|
||||
layout.css.constructable-stylesheets.enabled=true
|
||||
layout.css.individual-transform.enabled=true
|
||||
layout.css.motion-path.enabled=true
|
||||
plugin.load_flash_only=false
|
||||
@ -21,6 +22,10 @@ support-files =
|
||||
printpreview_font_mozprintcallback_ref.html
|
||||
printpreview_quirks.html
|
||||
printpreview_quirks_ref.html
|
||||
test_document_adopted_styles.html
|
||||
test_document_adopted_styles_ref.html
|
||||
test_shadow_root_adopted_styles.html
|
||||
test_shadow_root_adopted_styles_ref.html
|
||||
file_bug1018265.xhtml
|
||||
|
||||
[test_bug396367-1.html]
|
||||
|
@ -31,7 +31,7 @@ function printpreview(hasMozPrintCallback) {
|
||||
gWbp = frameElts[1].docShell.initOrReusePrintPreviewViewer();
|
||||
var listener = {
|
||||
onLocationChange: function(webProgress, request, location, flags) { },
|
||||
onProgressChange: function(webProgress, request, curSelfProgress,
|
||||
onProgressChange: function(webProgress, request, curSelfProgress,
|
||||
maxSelfProgress, curTotalProgress,
|
||||
maxTotalProgress) { },
|
||||
onSecurityChange: function(webProgress, request, state) { },
|
||||
@ -100,10 +100,14 @@ function runTests()
|
||||
}
|
||||
|
||||
function compareCanvases() {
|
||||
return window.windowUtils
|
||||
.compareCanvases(document.getElementsByTagName("canvas")[0],
|
||||
document.getElementsByTagName("canvas")[1],
|
||||
{}) == 0;
|
||||
const canvas1 = document.getElementsByTagName("canvas")[0];
|
||||
const canvas2 = document.getElementsByTagName("canvas")[1];
|
||||
const result = window.windowUtils.compareCanvases(canvas1, canvas2, {}) == 0;
|
||||
if (!result) {
|
||||
todo(false, "TEST CASE: " + canvas1.toDataURL());
|
||||
todo(false, "REFERENCE: " + canvas2.toDataURL());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function addHTMLContent(parent) {
|
||||
@ -422,8 +426,20 @@ async function runTest11() {
|
||||
requestAnimationFrame(function() { setTimeout(runTest12); } );
|
||||
}
|
||||
|
||||
// Crash test for bug 1615261
|
||||
// bug 1621415
|
||||
async function runTest12() {
|
||||
await compareFiles("test_document_adopted_styles.html", "test_document_adopted_styles_ref.html");
|
||||
requestAnimationFrame(function() { setTimeout(runTest13); } );
|
||||
}
|
||||
|
||||
// bug 1621415
|
||||
async function runTest13() {
|
||||
await compareFiles("test_shadow_root_adopted_styles.html", "test_shadow_root_adopted_styles_ref.html");
|
||||
requestAnimationFrame(function() { setTimeout(runTest14); } );
|
||||
}
|
||||
|
||||
// Crash test for bug 1615261
|
||||
async function runTest14() {
|
||||
frameElts[0].contentDocument.body.innerHTML =
|
||||
'<style> div { width: 100px; height: 100px; background-image: url("animated.gif"); } </style>' +
|
||||
'<div>Firefox will crash if you try and print this page</div>';
|
||||
|
@ -0,0 +1,8 @@
|
||||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<div class="target"></div>
|
||||
<script>
|
||||
const sheet = new CSSStyleSheet();
|
||||
document.adoptedStyleSheets = [sheet];
|
||||
sheet.replaceSync(".target { width: 100px; height: 100px; border-style: solid; border-color: blue; }");
|
||||
</script>
|
@ -0,0 +1,6 @@
|
||||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<body>
|
||||
<div class="target"></div>
|
||||
<style> .target { width: 100px; height: 100px; border-style: solid; border-color: blue; } </style>
|
||||
</body>
|
@ -0,0 +1,11 @@
|
||||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<body>
|
||||
<script>
|
||||
document.body.attachShadow({mode: "open"}).innerHTML = `
|
||||
<div class="target"></div>
|
||||
`;
|
||||
const sheet = new CSSStyleSheet();
|
||||
document.body.shadowRoot.adoptedStyleSheets = [sheet];
|
||||
sheet.replaceSync(".target { width: 100px; height: 100px; border-style: solid; border-color: blue; }");
|
||||
</script>
|
@ -0,0 +1,11 @@
|
||||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<body>
|
||||
<script>
|
||||
document.body.attachShadow({mode: "open"}).innerHTML = `
|
||||
<div class="target"></div>
|
||||
<style>
|
||||
.target { width: 100px; height: 100px; border-style: solid; border-color: blue; }
|
||||
</style>
|
||||
`;
|
||||
</script>
|
@ -1321,12 +1321,29 @@ already_AddRefed<StyleSheet> StyleSheet::Clone(
|
||||
StyleSheet* aCloneParent, dom::CSSImportRule* aCloneOwnerRule,
|
||||
dom::DocumentOrShadowRoot* aCloneDocumentOrShadowRoot,
|
||||
nsINode* aCloneOwningNode) const {
|
||||
MOZ_ASSERT(!IsConstructed(),
|
||||
"Cannot create a non-constructed sheet from a constructed sheet");
|
||||
RefPtr<StyleSheet> clone =
|
||||
new StyleSheet(*this, aCloneParent, aCloneOwnerRule,
|
||||
aCloneDocumentOrShadowRoot, aCloneOwningNode);
|
||||
return clone.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<StyleSheet> StyleSheet::CloneAdoptedSheet(
|
||||
Document& aConstructorDocument) const {
|
||||
MOZ_ASSERT(IsConstructed(),
|
||||
"Cannot create a constructed sheet from a non-constructed sheet");
|
||||
MOZ_ASSERT(aConstructorDocument.IsStaticDocument(),
|
||||
"Should never clone adopted sheets for a non-static document");
|
||||
RefPtr<StyleSheet> clone = new StyleSheet(*this,
|
||||
/* aParentToUse */ nullptr,
|
||||
/* aOwnerRuleToUse */ nullptr,
|
||||
/* aDocumentOrShadowRoot */ nullptr,
|
||||
/* aOwningNodeToUse */ nullptr);
|
||||
clone->mConstructorDocument = &aConstructorDocument;
|
||||
return clone.forget();
|
||||
}
|
||||
|
||||
ServoCSSRuleList* StyleSheet::GetCssRulesInternal() {
|
||||
if (!mRuleList) {
|
||||
EnsureUniqueInner();
|
||||
|
@ -221,6 +221,13 @@ class StyleSheet final : public nsICSSLoaderObserver, public nsWrapperCache {
|
||||
dom::DocumentOrShadowRoot* aCloneDocumentOrShadowRoot,
|
||||
nsINode* aCloneOwningNode) const;
|
||||
|
||||
/**
|
||||
* Creates a clone of the adopted style sheet as though it were constructed
|
||||
* by aConstructorDocument. This should only be used for printing.
|
||||
*/
|
||||
already_AddRefed<StyleSheet> CloneAdoptedSheet(
|
||||
dom::Document& aConstructorDocument) const;
|
||||
|
||||
bool HasForcedUniqueInner() const {
|
||||
return bool(mState & State::ForcedUniqueInner);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user