Merge inbound to mozilla-central a=merge

This commit is contained in:
Coroiu Cristina 2018-06-22 12:55:04 +03:00
commit e72433191e
56 changed files with 600 additions and 539 deletions

View File

@ -5358,12 +5358,6 @@ nsIDocument::InsertAnonymousContent(Element& aElement, ErrorResult& aRv)
return nullptr;
}
// We're about to insert random content here that will be rendered. We're
// going to need more than svg.css here...
if (IsSVGDocument()) {
AsSVGDocument()->EnsureNonSVGUserAgentStyleSheetsLoaded();
}
nsAutoScriptBlocker scriptBlocker;
nsCOMPtr<Element> container = shell->GetCanvasFrame()
->GetCustomContentContainer();

View File

@ -2017,7 +2017,13 @@ public:
}
bool LoadsFullXULStyleSheetUpFront()
{
return IsXULDocument() || AllowXULXBL();
if (IsXULDocument()) {
return true;
}
if (IsSVGDocument()) {
return false;
}
return AllowXULXBL();
}
bool IsScriptEnabled();

View File

@ -292,14 +292,6 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
return Update { };
}
// Check for a ShadowRoot because link elements are inert in a
// ShadowRoot.
ShadowRoot* containingShadow = thisContent->GetContainingShadow();
if (thisContent->IsHTMLElement(nsGkAtoms::link) &&
(aOldShadowRoot || containingShadow)) {
return Update { };
}
if (mStyleSheet && (aOldDocument || aOldShadowRoot)) {
MOZ_ASSERT(!(aOldDocument && aOldShadowRoot),
"ShadowRoot content is never in document, thus "
@ -310,25 +302,30 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
// unload the stylesheet. We want to do this even if updates are
// disabled, since otherwise a sheet with a stale linking element pointer
// will be hanging around -- not good!
//
// TODO(emilio): We can reach this code with aOldShadowRoot ==
// thisContent->GetContainingShadowRoot(), when moving the shadow host
// around. We probably could optimize some of this stuff out, is it worth
// it?
if (aOldShadowRoot) {
aOldShadowRoot->RemoveSheet(mStyleSheet);
} else {
aOldDocument->RemoveStyleSheet(mStyleSheet);
}
nsStyleLinkElement::SetStyleSheet(nullptr);
SetStyleSheet(nullptr);
}
// When static documents are created, stylesheets are cloned manually.
if (mDontLoadStyle || !mUpdatesEnabled ||
thisContent->OwnerDoc()->IsStaticDocument()) {
nsIDocument* doc = thisContent->IsInShadowTree()
? thisContent->OwnerDoc() : thisContent->GetUncomposedDoc();
// Loader could be null during unlink, see bug 1425866.
if (!doc || !doc->CSSLoader() || !doc->CSSLoader()->GetEnabled()) {
return Update { };
}
nsCOMPtr<nsIDocument> doc = thisContent->IsInShadowTree() ?
thisContent->OwnerDoc() : thisContent->GetUncomposedDoc();
// Loader could be null during unlink, see bug 1425866.
if (!doc || !doc->CSSLoader() || !doc->CSSLoader()->GetEnabled()) {
// When static documents are created, stylesheets are cloned manually.
if (mDontLoadStyle || !mUpdatesEnabled || doc->IsStaticDocument()) {
return Update { };
}
@ -394,15 +391,15 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
// Parse the style sheet.
return doc->CSSLoader()->LoadInlineStyle(*info, text, mLineNumber, aObserver);
}
nsAutoString integrity;
if (thisContent->IsElement()) {
nsAutoString integrity;
thisContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::integrity,
integrity);
}
if (!integrity.IsEmpty()) {
MOZ_LOG(SRILogHelper::GetSriLog(), mozilla::LogLevel::Debug,
("nsStyleLinkElement::DoUpdateStyleSheet, integrity=%s",
NS_ConvertUTF16toUTF8(integrity).get()));
if (!integrity.IsEmpty()) {
MOZ_LOG(SRILogHelper::GetSriLog(), mozilla::LogLevel::Debug,
("nsStyleLinkElement::DoUpdateStyleSheet, integrity=%s",
NS_ConvertUTF16toUTF8(integrity).get()));
}
}
auto resultOrError = doc->CSSLoader()->LoadStyleLink(*info, aObserver);
if (resultOrError.isErr()) {

View File

@ -221,10 +221,10 @@ public:
// Static atoms are backed by literals.
SetLiteralInternal(aAtom->GetUTF16String(), aAtom->GetLength());
} else {
// Dynamic atoms always have a string buffer and never have 0 length,
// because nsGkAtoms::_empty is a static atom.
SetKnownLiveStringBuffer(
aAtom->AsDynamic()->GetStringBuffer(), aAtom->GetLength());
// Dynamic atoms own their own chars, and never have 0 length because
// nsGkAtoms::_empty is a static atom.
MOZ_ASSERT(aAtom->GetLength() > 0);
AsAString().Assign(aAtom->AsDynamic()->String(), aAtom->GetLength());
}
} else if (aNullHandling == eTreatNullAsNull) {
SetNull();

View File

@ -125,7 +125,8 @@ HTMLLinkElement::HasDeferredDNSPrefetchRequest()
}
nsresult
HTMLLinkElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
HTMLLinkElement::BindToTree(nsIDocument* aDocument,
nsIContent* aParent,
nsIContent* aBindingParent,
bool aCompileEventHandlers)
{
@ -136,12 +137,8 @@ HTMLLinkElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
aCompileEventHandlers);
NS_ENSURE_SUCCESS(rv, rv);
// Link must be inert in ShadowRoot.
if (aDocument && !GetContainingShadow()) {
aDocument->RegisterPendingLinkUpdate(this);
}
if (IsInComposedDoc()) {
if (nsIDocument* doc = GetComposedDoc()) {
doc->RegisterPendingLinkUpdate(this);
TryDNSPrefetchOrPreconnectOrPrefetchOrPreloadOrPrerender();
}
@ -182,12 +179,8 @@ HTMLLinkElement::UnbindFromTree(bool aDeep, bool aNullParent)
// If this is reinserted back into the document it will not be
// from the parser.
nsCOMPtr<nsIDocument> oldDoc = GetUncomposedDoc();
// Check for a ShadowRoot because link elements are inert in a
// ShadowRoot.
ShadowRoot* oldShadowRoot = GetBindingParent() ?
GetBindingParent()->GetShadowRoot() : nullptr;
nsIDocument* oldDoc = GetUncomposedDoc();
ShadowRoot* oldShadowRoot = GetContainingShadow();
CreateAndDispatchEvent(oldDoc, NS_LITERAL_STRING("DOMLinkRemoved"));
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);

View File

@ -30,26 +30,6 @@ namespace dom {
//----------------------------------------------------------------------
// Implementation
//----------------------------------------------------------------------
// nsISupports methods:
nsresult
SVGDocument::InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
bool aNotify)
{
if (aKid->IsElement() && !aKid->IsSVGElement()) {
// We can get here when well formed XML with a non-SVG root element is
// served with the SVG MIME type, for example. In that case we need to load
// the non-SVG UA sheets or else we can get bugs like bug 1016145. Note
// that we have to do this _before_ the XMLDocument::InsertChildBefore,
// since that can try to construct frames, and we need to have the sheets
// loaded by then.
EnsureNonSVGUserAgentStyleSheetsLoaded();
}
return XMLDocument::InsertChildBefore(aKid, aBeforeThis, aNotify);
}
nsresult
SVGDocument::Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
bool aPreallocateChildren) const
@ -64,97 +44,6 @@ SVGDocument::Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
return CallQueryInterface(clone.get(), aResult);
}
void
SVGDocument::EnsureNonSVGUserAgentStyleSheetsLoaded()
{
if (mHasLoadedNonSVGUserAgentStyleSheets) {
return;
}
if (IsStaticDocument()) {
// If we're a static clone of a document, then
// nsIDocument::CreateStaticClone will handle cloning the original
// document's sheets, including the on-demand non-SVG UA sheets,
// for us.
return;
}
mHasLoadedNonSVGUserAgentStyleSheets = true;
if (IsBeingUsedAsImage()) {
// nsDocumentViewer::CreateStyleSet skipped loading all user-agent/user
// style sheets in this case, but we'll need B2G/Fennec's
// content.css. We could load all the sheets registered with the
// nsIStyleSheetService (and maybe we should) but most likely it isn't
// desirable or necessary for foreignObject in SVG-as-an-image. Instead we
// only load the "agent-style-sheets" that nsStyleSheetService::Init()
// pulls in from the category manager. That keeps memory use of
// SVG-as-an-image down.
//
// We do this before adding the other sheets below because
// EnsureOnDemandBuiltInUASheet prepends, and B2G/Fennec's/GeckoView's
// content.css must come after those UASheet() etc.
//
// FIXME(emilio, bug 1468133): We may already have loaded some of the other
// on-demand built-in UA sheets, including svg.css, so this looks somewhat
// bogus... Also, this should probably just use the stylesheet service which
// also has the right sheets cached and parsed here...
nsCOMPtr<nsICategoryManager> catMan =
do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
if (catMan) {
nsCOMPtr<nsISimpleEnumerator> sheets;
catMan->EnumerateCategory("agent-style-sheets", getter_AddRefs(sheets));
if (sheets) {
bool hasMore;
while (NS_SUCCEEDED(sheets->HasMoreElements(&hasMore)) && hasMore) {
nsCOMPtr<nsISupports> sheet;
if (NS_FAILED(sheets->GetNext(getter_AddRefs(sheet))))
break;
nsCOMPtr<nsISupportsCString> icStr = do_QueryInterface(sheet);
MOZ_ASSERT(icStr,
"category manager entries must be nsISupportsCStrings");
nsAutoCString name;
icStr->GetData(name);
nsCString spec;
catMan->GetCategoryEntry("agent-style-sheets", name.get(),
getter_Copies(spec));
mozilla::css::Loader* cssLoader = CSSLoader();
if (cssLoader->GetEnabled()) {
nsCOMPtr<nsIURI> uri;
NS_NewURI(getter_AddRefs(uri), spec);
if (uri) {
RefPtr<StyleSheet> sheet;
cssLoader->LoadSheetSync(uri,
mozilla::css::eAgentSheetFeatures,
true, &sheet);
if (sheet) {
EnsureOnDemandBuiltInUASheet(sheet);
}
}
}
}
}
}
}
auto cache = nsLayoutStylesheetCache::Singleton();
EnsureOnDemandBuiltInUASheet(cache->FormsSheet());
EnsureOnDemandBuiltInUASheet(cache->CounterStylesSheet());
EnsureOnDemandBuiltInUASheet(cache->HTMLSheet());
if (nsLayoutUtils::ShouldUseNoFramesSheet(this)) {
EnsureOnDemandBuiltInUASheet(cache->NoFramesSheet());
}
if (nsLayoutUtils::ShouldUseNoScriptSheet(this)) {
EnsureOnDemandBuiltInUASheet(cache->NoScriptSheet());
}
EnsureOnDemandBuiltInUASheet(cache->UASheet());
}
} // namespace dom
} // namespace mozilla

View File

@ -22,19 +22,13 @@ class SVGForeignObjectElement;
class SVGDocument final : public XMLDocument
{
friend class SVGForeignObjectElement; // To call EnsureNonSVGUserAgentStyleSheetsLoaded
friend class nsIDocument; // Same reason.
public:
SVGDocument()
: XMLDocument("image/svg+xml")
, mHasLoadedNonSVGUserAgentStyleSheets(false)
{
mType = eSVG;
}
virtual nsresult InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
bool aNotify) override;
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
bool aPreallocateChildren) const override;
@ -49,9 +43,6 @@ public:
}
private:
void EnsureNonSVGUserAgentStyleSheetsLoaded();
bool mHasLoadedNonSVGUserAgentStyleSheets;
// This is maintained by AutoSetRestoreSVGContextPaint.
const SVGContextPaint* mCurrentContextPaint = nullptr;

View File

@ -107,32 +107,6 @@ SVGForeignObjectElement::HasValidDimensions() const
//----------------------------------------------------------------------
// nsIContent methods
nsresult
SVGForeignObjectElement::BindToTree(nsIDocument* aDocument,
nsIContent* aParent,
nsIContent* aBindingParent,
bool aCompileEventHandlers)
{
nsresult rv = SVGGraphicsElement::BindToTree(aDocument, aParent,
aBindingParent,
aCompileEventHandlers);
NS_ENSURE_SUCCESS(rv, rv);
nsIDocument* doc = GetComposedDoc();
if (doc && doc->IsSVGDocument()) {
// We assume that we're going to have HTML content, so we ensure that the
// UA style sheets that nsDocumentViewer::CreateStyleSet skipped when
// it saw the document was an SVG document are loaded.
//
// We setup these style sheets during binding, not element construction,
// because elements can be moved from the document that creates them to
// another document.
doc->AsSVGDocument()->EnsureNonSVGUserAgentStyleSheetsLoaded();
}
return rv;
}
NS_IMETHODIMP_(bool)
SVGForeignObjectElement::IsAttributeMapped(const nsAtom* name) const
{

View File

@ -36,9 +36,6 @@ public:
virtual bool HasValidDimensions() const override;
// nsIContent interface
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
nsIContent* aBindingParent,
bool aCompileEventHandlers) override;
NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* name) const override;
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,

View File

@ -495,11 +495,10 @@ SVGSVGElement::BindToTree(nsIDocument* aDocument,
aCompileEventHandlers);
NS_ENSURE_SUCCESS(rv,rv);
nsIDocument* doc = GetComposedDoc();
if (doc) {
// Setup the style sheet during binding, not element construction,
// because we could move the root SVG element from the document
// that created it to another document.
if (nsIDocument* doc = GetComposedDoc()) {
// Setup the style sheet during binding, not element construction, because
// we could move the root SVG element from the document that created it to
// another document.
auto cache = nsLayoutStylesheetCache::Singleton();
doc->EnsureOnDemandBuiltInUASheet(cache->SVGSheet());
}

View File

@ -16,34 +16,15 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=806506
SimpleTest.waitForExplicitFinish();
var content = '<div id="grabme"></div>';
setShadowDOMPrefAndCreateIframe(content)
.then((aDocument) => {
function runChecks() {
isnot(aDocument.defaultView.getComputedStyle(shadowSpan, null).getPropertyValue("padding-top"), "10px", "Link element should be inert.");
is(aDocument.styleSheets.length, numStyleBeforeLoad, "Document style count should remain the same because the style should not be in the doucment.");
is(shadow.styleSheets.length, 0, "Inert link should not add style to ShadowRoot.");
// Remove link to make sure we don't get assertions.
shadow.removeChild(shadowStyle);
SimpleTest.finish();
};
setShadowDOMPrefAndCreateIframe(content).then(aDocument => {
var element = aDocument.getElementById("grabme");
var shadow = element.attachShadow({mode: "open"});
var element = aDocument.getElementById("grabme");
var shadow = element.attachShadow({mode: "open"});
// Check that <base> is inert.
shadow.innerHTML = '<base href="http://www.example.org/" />';
isnot(aDocument.baseURI, "http://www.example.org/", "Base element should be inert in ShadowRoot.");
// Check that <link> is inert.
var numStyleBeforeLoad = aDocument.styleSheets.length;
shadow.innerHTML = '<link id="shadowlink" rel="stylesheet" type="text/css" href="inert_style.css" /><span id="shadowspan"></span>';
shadow.applyAuthorStyles = true;
var shadowSpan = shadow.getElementById("shadowspan");
var shadowStyle = shadow.getElementById("shadowlink");
runChecks();
});
// Check that <base> is inert.
shadow.innerHTML = '<base href="http://www.example.org/" />';
isnot(aDocument.baseURI, "http://www.example.org/", "Base element should be inert in ShadowRoot.");
SimpleTest.finish();
});
</script>
</body>
</html>

View File

@ -765,10 +765,7 @@ nsXULElement::BindToTree(nsIDocument* aDocument,
nsIDocument* doc = GetComposedDoc();
#ifdef DEBUG
if (doc &&
!doc->LoadsFullXULStyleSheetUpFront() &&
!doc->IsUnstyledDocument()) {
if (doc && !doc->AllowXULXBL() && !doc->IsUnstyledDocument()) {
// To save CPU cycles and memory, non-XUL documents only load the user
// agent style sheet rules for a minimal set of XUL elements such as
// 'scrollbar' that may be created implicitly for their content (those

View File

@ -1,4 +1,4 @@
52804
52808
0/nm
0th/pt
1/n1
@ -16938,6 +16938,7 @@ blameworthiness/M
blameworthy/P
blammo
blanch/GDS
blanche/S
blancmange/MS
bland/PTRY
blandish/DSLG
@ -18614,6 +18615,7 @@ carsick/P
carsickness/M
cart/SZGMDR
cartage/M
carte/S
cartel/MS
carter/M
carthorse/SM
@ -27760,6 +27762,7 @@ gazer/M
gazette/MGDS
gazetteer/MS
gazillion/S
gazillionth
gazpacho/M
gazump/DGS
gear/MDGS
@ -36405,6 +36408,7 @@ neurosurgical
neurotic/MS
neurotically
neuroticism
neurotoxin/S
neurotransmitter/SM
neut
neuter/MDGS
@ -40457,7 +40461,7 @@ precise/DRSYTGNP
preciseness/M
precision/M
preclude/GDS
preclusion/M
preclusion/MS
precocious/YP
precociousness/M
precocity/M
@ -43963,7 +43967,7 @@ scree/MDS
screech/GMDS
screechy/TR
screed/S
screen/SJMDG
screen/SJMDGRZ
screening/M
screenplay/SM
screensaver/SM
@ -49414,7 +49418,7 @@ trail/ZGSMDR
trailblazer/MS
trailblazing/M
trailer/M
train/ZGSMDRB
train/ZGSMDRBJ
trained/U
trainee/SM
trainer/M

View File

@ -320,7 +320,10 @@ ClientLayerManager::EndTransactionInternal(DrawPaintedLayerCallback aCallback,
// Wait for any previous async paints to complete before starting to paint again.
// Do this outside the profiler and telemetry block so this doesn't count as time
// spent rasterizing.
FlushAsyncPaints();
{
PaintTelemetry::AutoRecord record(PaintTelemetry::Metric::FlushRasterization);
FlushAsyncPaints();
}
PaintTelemetry::AutoRecord record(PaintTelemetry::Metric::Rasterization);
AUTO_PROFILER_TRACING("Paint", "Rasterize");

View File

@ -2440,19 +2440,6 @@ nsDocumentViewer::CreateStyleSet(nsIDocument* aDocument)
UniquePtr<ServoStyleSet> styleSet = MakeUnique<ServoStyleSet>();
// The document will fill in the document sheets when we create the presshell
if (aDocument->IsBeingUsedAsImage()) {
MOZ_ASSERT(aDocument->IsSVGDocument(),
"Do we want to skip most sheets for this new image type?");
// SVG-as-an-image must be kept as light and small as possible. We
// deliberately skip loading everything and leave svg.css (and html.css and
// xul.css) to be loaded on-demand.
// XXXjwatt Nothing else is loaded on-demand, but I don't think that
// should matter for SVG-as-an-image. If it does, I want to know why!
return styleSet;
}
auto cache = nsLayoutStylesheetCache::Singleton();
// Handle the user sheets.
@ -2473,81 +2460,63 @@ nsDocumentViewer::CreateStyleSet(nsIDocument* aDocument)
styleSet->PrependStyleSheet(SheetType::Agent, sheet);
}
if (!aDocument->IsSVGDocument()) {
// !!! IMPORTANT - KEEP THIS BLOCK IN SYNC WITH
// !!! SVGDocument::EnsureNonSVGUserAgentStyleSheetsLoaded.
sheet = cache->FormsSheet();
if (sheet) {
styleSet->PrependStyleSheet(SheetType::Agent, sheet);
}
// SVGForeignObjectElement::BindToTree calls SVGDocument::
// EnsureNonSVGUserAgentStyleSheetsLoaded to loads these UA sheet
// on-demand. (Excluding the quirks sheet, which should never be loaded for
// an SVG document, and excluding xul.css which will be loaded on demand by
// nsXULElement::BindToTree.)
sheet = cache->FormsSheet();
if (aDocument->LoadsFullXULStyleSheetUpFront()) {
// This is the only place components.css gets loaded, unlike xul.css
sheet = cache->XULComponentsSheet();
if (sheet) {
styleSet->PrependStyleSheet(SheetType::Agent, sheet);
}
if (aDocument->LoadsFullXULStyleSheetUpFront()) {
// This is the only place components.css gets loaded, unlike xul.css
sheet = cache->XULComponentsSheet();
if (sheet) {
styleSet->PrependStyleSheet(SheetType::Agent, sheet);
}
// nsXULElement::BindToTree loads xul.css on-demand if we don't load it
// up-front here.
sheet = cache->XULSheet();
if (sheet) {
styleSet->PrependStyleSheet(SheetType::Agent, sheet);
}
}
sheet = cache->MinimalXULSheet();
if (sheet) {
// Load the minimal XUL rules for scrollbars and a few other XUL things
// that non-XUL (typically HTML) documents commonly use.
styleSet->PrependStyleSheet(SheetType::Agent, sheet);
}
sheet = cache->CounterStylesSheet();
if (sheet) {
styleSet->PrependStyleSheet(SheetType::Agent, sheet);
}
if (nsLayoutUtils::ShouldUseNoScriptSheet(aDocument)) {
sheet = cache->NoScriptSheet();
if (sheet) {
styleSet->PrependStyleSheet(SheetType::Agent, sheet);
}
}
if (nsLayoutUtils::ShouldUseNoFramesSheet(aDocument)) {
sheet = cache->NoFramesSheet();
if (sheet) {
styleSet->PrependStyleSheet(SheetType::Agent, sheet);
}
}
// We don't add quirk.css here; nsPresContext::CompatibilityModeChanged will
// append it if needed.
sheet = cache->HTMLSheet();
if (sheet) {
styleSet->PrependStyleSheet(SheetType::Agent, sheet);
}
styleSet->PrependStyleSheet(SheetType::Agent, cache->UASheet());
} else {
// SVG documents may have scrollbars and need the scrollbar styling.
sheet = cache->MinimalXULSheet();
// nsXULElement::BindToTree loads xul.css on-demand if we don't load it
// up-front here.
sheet = cache->XULSheet();
if (sheet) {
styleSet->PrependStyleSheet(SheetType::Agent, sheet);
}
}
nsStyleSheetService* sheetService = nsStyleSheetService::GetInstance();
if (sheetService) {
sheet = cache->MinimalXULSheet();
if (sheet) {
// Load the minimal XUL rules for scrollbars and a few other XUL things
// that non-XUL (typically HTML) documents commonly use.
styleSet->PrependStyleSheet(SheetType::Agent, sheet);
}
sheet = cache->CounterStylesSheet();
if (sheet) {
styleSet->PrependStyleSheet(SheetType::Agent, sheet);
}
if (nsLayoutUtils::ShouldUseNoScriptSheet(aDocument)) {
sheet = cache->NoScriptSheet();
if (sheet) {
styleSet->PrependStyleSheet(SheetType::Agent, sheet);
}
}
if (nsLayoutUtils::ShouldUseNoFramesSheet(aDocument)) {
sheet = cache->NoFramesSheet();
if (sheet) {
styleSet->PrependStyleSheet(SheetType::Agent, sheet);
}
}
// We don't add quirk.css here; nsPresContext::CompatibilityModeChanged will
// append it if needed.
sheet = cache->HTMLSheet();
if (sheet) {
styleSet->PrependStyleSheet(SheetType::Agent, sheet);
}
styleSet->PrependStyleSheet(SheetType::Agent, cache->UASheet());
if (nsStyleSheetService* sheetService = nsStyleSheetService::GetInstance()) {
for (StyleSheet* sheet : *sheetService->AgentStyleSheets()) {
styleSet->AppendStyleSheet(SheetType::Agent, sheet);
}

View File

@ -10026,6 +10026,7 @@ PaintTelemetry::AutoRecordPaint::~AutoRecordPaint()
double dlMs = sMetrics[Metric::DisplayList];
double flbMs = sMetrics[Metric::Layerization];
double frMs = sMetrics[Metric::FlushRasterization];
double rMs = sMetrics[Metric::Rasterization];
// If the total time was >= 16ms, then it's likely we missed a frame due to
@ -10033,10 +10034,12 @@ PaintTelemetry::AutoRecordPaint::~AutoRecordPaint()
if (totalMs >= 16.0) {
recordLarge(NS_LITERAL_CSTRING("dl"), dlMs);
recordLarge(NS_LITERAL_CSTRING("flb"), flbMs);
recordLarge(NS_LITERAL_CSTRING("fr"), frMs);
recordLarge(NS_LITERAL_CSTRING("r"), rMs);
} else {
recordSmall(NS_LITERAL_CSTRING("dl"), dlMs);
recordSmall(NS_LITERAL_CSTRING("flb"), flbMs);
recordSmall(NS_LITERAL_CSTRING("fr"), frMs);
recordSmall(NS_LITERAL_CSTRING("r"), rMs);
}
}

View File

@ -6856,6 +6856,7 @@ class PaintTelemetry
enum class Metric {
DisplayList,
Layerization,
FlushRasterization,
Rasterization,
COUNT,
};

View File

@ -2344,13 +2344,6 @@ nsPrintJob::ReflowPrintObject(const UniquePtr<nsPrintObject>& aPO)
UniquePtr<ServoStyleSet> styleSet =
mDocViewerPrint->CreateStyleSet(aPO->mDocument);
if (aPO->mDocument->IsSVGDocument()) {
// The SVG document only loads minimal-xul.css, so it doesn't apply other
// styles. We should add ua.css for applying style which related to print.
auto cache = nsLayoutStylesheetCache::Singleton();
styleSet->PrependStyleSheet(SheetType::Agent, cache->UASheet());
}
aPO->mPresShell = aPO->mDocument->CreateShell(aPO->mPresContext,
aPO->mViewManager,
std::move(styleSet));

View File

@ -827,9 +827,6 @@ Loader::IsAlternateSheet(const nsAString& aTitle, bool aHasAlternateRel)
// style set, the sheet wasn't marked as an alternate explicitly, and aTitle
// is nonempty, we should select the style set corresponding to aTitle, since
// that's a preferred sheet.
//
// FIXME(emilio): This should return false for Shadow DOM regardless of the
// document.
if (aTitle.IsEmpty()) {
return IsAlternate::No;
}
@ -1921,10 +1918,8 @@ Loader::LoadInlineStyle(const SheetInfo& aInfo,
auto matched =
PrepareSheet(sheet, aInfo.mTitle, aInfo.mMedia, nullptr, isAlternate);
if (aInfo.mContent->HasFlag(NODE_IS_IN_SHADOW_TREE)) {
ShadowRoot* containingShadow = aInfo.mContent->GetContainingShadow();
MOZ_ASSERT(containingShadow);
containingShadow->InsertSheet(sheet, aInfo.mContent);
if (aInfo.mContent->IsInShadowTree()) {
aInfo.mContent->GetContainingShadow()->InsertSheet(sheet, aInfo.mContent);
} else {
rv = InsertSheetInDoc(sheet, aInfo.mContent, mDocument);
if (NS_FAILED(rv)) {
@ -2040,10 +2035,13 @@ Loader::LoadStyleLink(const SheetInfo& aInfo, nsICSSLoaderObserver* aObserver)
auto matched =
PrepareSheet(sheet, aInfo.mTitle, aInfo.mMedia, nullptr, isAlternate);
// FIXME(emilio, bug 1410578): Shadow DOM should be handled here too.
rv = InsertSheetInDoc(sheet, aInfo.mContent, mDocument);
if (NS_FAILED(rv)) {
return Err(rv);
if (aInfo.mContent && aInfo.mContent->IsInShadowTree()) {
aInfo.mContent->GetContainingShadow()->InsertSheet(sheet, aInfo.mContent);
} else {
rv = InsertSheetInDoc(sheet, aInfo.mContent, mDocument);
if (NS_FAILED(rv)) {
return Err(rv);
}
}
nsCOMPtr<nsIStyleSheetLinkingElement> owningElement(

View File

@ -2147,6 +2147,15 @@ Gecko_GetComputedURLSpec(const URLValueData* aURL, nsCString* aOut)
aOut->AssignLiteral("about:invalid");
}
void
Gecko_nsIURI_Debug(nsIURI* aURI, nsCString* aOut)
{
// TODO(emilio): Do we have more useful stuff to put here, maybe?
if (aURI) {
*aOut = aURI->GetSpecOrDefault();
}
}
NS_IMPL_THREADSAFE_FFI_REFCOUNTING(css::URLValue, CSSURLValue);
NS_IMPL_THREADSAFE_FFI_REFCOUNTING(URLExtraData, URLExtraData);

View File

@ -536,6 +536,8 @@ void Gecko_nsStyleSVG_CopyContextProperties(nsStyleSVG* dst, const nsStyleSVG* s
mozilla::css::URLValue* Gecko_NewURLValue(ServoBundledURI uri);
size_t Gecko_URLValue_SizeOfIncludingThis(mozilla::css::URLValue* url);
void Gecko_GetComputedURLSpec(const mozilla::css::URLValueData* url, nsCString* spec);
void Gecko_nsIURI_Debug(nsIURI*, nsCString* spec);
NS_DECL_THREADSAFE_FFI_REFCOUNTING(mozilla::css::URLValue, CSSURLValue);
NS_DECL_THREADSAFE_FFI_REFCOUNTING(RawGeckoURLExtraData, URLExtraData);

View File

@ -2,7 +2,9 @@
* 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/. */
/* This sheet is added to the style set for documents with script disabled */
/* This sheet is added to the style set for documents with script enabled */
@namespace url(http://www.w3.org/1999/xhtml);
noscript {
display: none !important;

View File

@ -84,27 +84,3 @@ foreignObject {
/* Don't specify the outline-color, we should always use initial value. */
outline: 1px dotted;
}
/* nsDocumentViewer::CreateStyleSet doesn't load ua.css.
* A few styles are common to html and SVG though
* so we copy the rules below from that file.
*/
/* Links */
*|*:any-link {
cursor: pointer;
}
*|*:any-link:-moz-focusring {
/* Don't specify the outline-color, we should always use initial value. */
outline: 1px dotted;
}
/*
* SVG-as-an-image needs this rule
*/
*|*::-moz-viewport, *|*::-moz-viewport-scroll, *|*::-moz-canvas, *|*::-moz-scrolled-canvas {
display: block !important;
background-color: inherit;
}

View File

@ -7,7 +7,7 @@
nsHtml5AtomEntry::nsHtml5AtomEntry(KeyTypePointer aStr)
: nsStringHashKey(aStr)
, mAtom(new nsDynamicAtom(*aStr))
, mAtom(nsDynamicAtom::Create(*aStr))
{
}
@ -20,7 +20,7 @@ nsHtml5AtomEntry::nsHtml5AtomEntry(const nsHtml5AtomEntry& aOther)
nsHtml5AtomEntry::~nsHtml5AtomEntry()
{
delete mAtom;
nsDynamicAtom::Destroy(mAtom);
}
nsHtml5AtomTable::nsHtml5AtomTable()

View File

@ -5,8 +5,9 @@
#ifndef nsHtml5String_h
#define nsHtml5String_h
#include "nsString.h"
#include "nsAtom.h"
#include "nsString.h"
#include "nsStringBuffer.h"
class nsHtml5TreeBuilder;

View File

@ -7,7 +7,6 @@
#![deny(missing_docs)]
use cssparser::{BasicParseErrorKind, ParseErrorKind, SourceLocation, Token};
use log;
use std::fmt;
use style_traits::ParseError;
use stylesheets::UrlExtraData;
@ -229,8 +228,10 @@ pub trait ParseErrorReporter {
/// This logging is silent by default, and can be enabled with a `RUST_LOG=style=info`
/// environment variable.
/// (See [`env_logger`](https://rust-lang-nursery.github.io/log/env_logger/).)
#[cfg(feature = "servo")]
pub struct RustLogReporter;
#[cfg(feature = "servo")]
impl ParseErrorReporter for RustLogReporter {
fn report_error(
&self,
@ -238,6 +239,7 @@ impl ParseErrorReporter for RustLogReporter {
location: SourceLocation,
error: ContextualParseError,
) {
use log;
if log_enabled!(log::Level::Info) {
info!(
"Url:\t{}\n{}:{} {}",

View File

@ -17,14 +17,25 @@ use media_queries::{Device, MediaList};
use properties::ComputedValues;
use selector_parser::SnapshotMap;
use servo_arc::Arc;
use std::fmt;
use shared_lock::{Locked, SharedRwLockReadGuard, StylesheetGuards};
use stylesheets::{CssRule, Origin, StylesheetContents, StylesheetInDocument};
use stylist::Stylist;
/// Little wrapper to a Gecko style sheet.
#[derive(Debug, Eq, PartialEq)]
#[derive(Eq, PartialEq)]
pub struct GeckoStyleSheet(*const DomStyleSheet);
impl fmt::Debug for GeckoStyleSheet {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
let contents = self.contents();
formatter.debug_struct("GeckoStyleSheet")
.field("origin", &contents.origin)
.field("url_data", &*contents.url_data.read())
.finish()
}
}
impl ToMediaListKey for ::gecko::data::GeckoStyleSheet {
fn to_media_list_key(&self) -> MediaListKey {
use std::mem;

View File

@ -64,6 +64,27 @@ pub struct Device {
used_viewport_size: AtomicBool,
}
impl fmt::Debug for Device {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use nsstring::nsCString;
let mut doc_uri = nsCString::new();
unsafe {
let doc =
&*self.pres_context().mDocument.raw::<structs::nsIDocument>();
bindings::Gecko_nsIURI_Debug(
doc.mDocumentURI.raw::<structs::nsIURI>(),
&mut doc_uri,
)
};
f.debug_struct("Device")
.field("document_url", &doc_uri)
.finish()
}
}
unsafe impl Sync for Device {}
unsafe impl Send for Device {}

View File

@ -6,7 +6,7 @@
use cssparser::Parser;
use gecko_bindings::bindings;
use gecko_bindings::structs::{ServoBundledURI, URLExtraData};
use gecko_bindings::structs::ServoBundledURI;
use gecko_bindings::structs::mozilla::css::URLValueData;
use gecko_bindings::structs::root::{RustString, nsStyleImageRequest};
use gecko_bindings::structs::root::mozilla::css::{ImageValue, URLValue};
@ -17,6 +17,7 @@ use parser::{Parse, ParserContext};
use servo_arc::{Arc, RawOffsetArc};
use std::fmt::{self, Write};
use std::mem;
use stylesheets::UrlExtraData;
use style_traits::{CssWriter, ParseError, ToCss};
use values::computed::{Context, ToComputedValue};
@ -32,7 +33,7 @@ pub struct CssUrl {
/// The URL extra data.
#[css(skip)]
pub extra_data: RefPtr<URLExtraData>,
pub extra_data: UrlExtraData,
}
impl CssUrl {
@ -58,7 +59,7 @@ impl CssUrl {
&url.mString as *const _ as *const RawOffsetArc<String>;
CssUrl {
serialization: Arc::from_raw_offset((*arc_type).clone()),
extra_data: url.mExtraData.to_safe(),
extra_data: UrlExtraData(url.mExtraData.to_safe()),
}
}
@ -88,7 +89,7 @@ impl CssUrl {
let arc_offset = Arc::into_raw_offset(self.serialization.clone());
ServoBundledURI {
mURLString: unsafe { mem::transmute::<_, RawOffsetArc<RustString>>(arc_offset) },
mExtraData: self.extra_data.get(),
mExtraData: self.extra_data.0.get(),
}
}
}

View File

@ -78,15 +78,6 @@ impl<T: RefCounted> RefPtr<T> {
ret
}
/// Create a reference to RefPtr from a reference to pointer.
///
/// The pointer must be valid and non null.
///
/// This method doesn't touch refcount.
pub unsafe fn from_ptr_ref(ptr: &*mut T) -> &Self {
mem::transmute(ptr)
}
/// Produces an FFI-compatible RefPtr that can be stored in style structs.
///
/// structs::RefPtr does not have a destructor, so this may leak

View File

@ -122,7 +122,8 @@ impl WeakAtom {
unsafe { u8_ptr.offset(string_offset) as *const u16 }
} else {
let atom_ptr = self.as_ptr() as *const nsDynamicAtom;
unsafe { (*(atom_ptr)).mString }
// Dynamic atom chars are stored at the end of the object.
unsafe { atom_ptr.offset(1) as *const u16 }
};
unsafe { slice::from_raw_parts(string, self.len() as usize) }
}

View File

@ -14,8 +14,8 @@ use parser::ParserContext;
use super::{Device, MediaQuery, Qualifier};
/// A type that encapsulates a media query list.
#[css(comma)]
#[derive(Clone, Debug, MallocSizeOf, ToCss)]
#[css(comma, derive_debug)]
#[derive(Clone, MallocSizeOf, ToCss)]
pub struct MediaList {
/// The list of media queries.
#[css(iterable)]

View File

@ -61,22 +61,52 @@ pub type UrlExtraData = ::servo_url::ServoUrl;
/// Extra data that the backend may need to resolve url values.
#[cfg(feature = "gecko")]
pub type UrlExtraData =
::gecko_bindings::sugar::refptr::RefPtr<::gecko_bindings::structs::URLExtraData>;
#[derive(Clone, PartialEq)]
pub struct UrlExtraData(
pub ::gecko_bindings::sugar::refptr::RefPtr<::gecko_bindings::structs::URLExtraData>
);
#[cfg(feature = "gecko")]
impl UrlExtraData {
/// Returns a string for the url.
///
/// Unimplemented currently.
pub fn as_str(&self) -> &str {
// TODO
"(stylo: not supported)"
/// True if this URL scheme is chrome.
#[inline]
pub fn is_chrome(&self) -> bool {
self.0.mIsChrome
}
/// True if this URL scheme is chrome.
pub fn is_chrome(&self) -> bool {
self.mIsChrome
/// Create a reference to this `UrlExtraData` from a reference to pointer.
///
/// The pointer must be valid and non null.
///
/// This method doesn't touch refcount.
#[inline]
pub unsafe fn from_ptr_ref(ptr: &*mut ::gecko_bindings::structs::URLExtraData) -> &Self {
::std::mem::transmute(ptr)
}
}
#[cfg(feature = "gecko")]
impl fmt::Debug for UrlExtraData {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
use gecko_bindings::{structs, bindings};
struct DebugURI(*mut structs::nsIURI);
impl fmt::Debug for DebugURI {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
use nsstring::nsCString;
let mut spec = nsCString::new();
unsafe {
bindings::Gecko_nsIURI_Debug(self.0, &mut spec);
}
spec.fmt(formatter)
}
}
formatter.debug_struct("URLExtraData")
.field("is_chrome", &self.is_chrome())
.field("base", &DebugURI(self.0.mBaseURI.raw::<structs::nsIURI>()))
.field("referrer", &DebugURI(self.0.mReferrer.raw::<structs::nsIURI>()))
.finish()
}
}

View File

@ -176,7 +176,7 @@ macro_rules! rule_filter {
}
/// A trait to represent a given stylesheet in a document.
pub trait StylesheetInDocument {
pub trait StylesheetInDocument : ::std::fmt::Debug {
/// Get the stylesheet origin.
fn origin(&self, guard: &SharedRwLockReadGuard) -> Origin;
@ -263,7 +263,7 @@ impl StylesheetInDocument for Stylesheet {
/// A simple wrapper over an `Arc<Stylesheet>`, with pointer comparison, and
/// suitable for its use in a `StylesheetSet`.
#[derive(Clone)]
#[derive(Clone, Debug)]
#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
pub struct DocumentStyleSheet(
#[cfg_attr(feature = "servo", ignore_malloc_size_of = "Arc")] pub Arc<Stylesheet>,

View File

@ -75,6 +75,10 @@ impl UserAgentCascadeDataCache {
Self { entries: vec![] }
}
fn len(&self) -> usize {
self.entries.len()
}
// FIXME(emilio): This may need to be keyed on quirks-mode too, though there
// aren't class / id selectors on those sheets, usually, so it's probably
// ok...
@ -90,6 +94,7 @@ impl UserAgentCascadeDataCache {
S: StylesheetInDocument + ToMediaListKey + PartialEq + 'static,
{
let mut key = EffectiveMediaQueryResults::new();
debug!("UserAgentCascadeDataCache::lookup({:?})", device);
for sheet in sheets.clone() {
CascadeData::collect_applicable_media_query_results_into(device, sheet, guard, &mut key)
}
@ -105,6 +110,8 @@ impl UserAgentCascadeDataCache {
precomputed_pseudo_element_decls: PrecomputedPseudoElementDeclarations::default(),
};
debug!("> Picking the slow path");
for sheet in sheets {
new_data.cascade_data.add_stylesheet(
device,
@ -117,7 +124,6 @@ impl UserAgentCascadeDataCache {
}
let new_data = Arc::new(new_data);
self.entries.push(new_data.clone());
Ok(new_data)
}
@ -244,8 +250,8 @@ impl DocumentCascadeData {
let origin_sheets = flusher.origin_sheets(Origin::UserAgent);
let ua_cascade_data =
ua_cache.lookup(origin_sheets, device, quirks_mode, guards.ua_or_user)?;
ua_cache.expire_unused();
debug!("User agent data cache size {:?}", ua_cache.len());
self.user_agent = ua_cascade_data;
}
}
@ -1085,7 +1091,7 @@ impl Stylist {
guards: &StylesheetGuards,
device: &Device,
) -> OriginSet {
debug!("Stylist::media_features_change_changed_style");
debug!("Stylist::media_features_change_changed_style {:?}", device);
let mut origins = OriginSet::empty();
let stylesheets = self.stylesheets.iter();
@ -2145,16 +2151,19 @@ impl CascadeData {
return;
}
debug!(" + {:?}", stylesheet);
results.saw_effective(stylesheet);
for rule in stylesheet.effective_rules(device, guard) {
match *rule {
CssRule::Import(ref lock) => {
let import_rule = lock.read_with(guard);
debug!(" + {:?}", import_rule.stylesheet.media(guard));
results.saw_effective(import_rule);
},
CssRule::Media(ref lock) => {
let media_rule = lock.read_with(guard);
debug!(" + {:?}", media_rule.media_queries.read_with(guard));
results.saw_effective(media_rule);
},
_ => {},
@ -2346,8 +2355,10 @@ impl CascadeData {
if effective_now != effective_then {
debug!(
" > Stylesheet changed -> {}, {}",
effective_then, effective_now
" > Stylesheet {:?} changed -> {}, {}",
stylesheet.media(guard),
effective_then,
effective_now
);
return false;
}
@ -2382,8 +2393,10 @@ impl CascadeData {
.was_effective(import_rule);
if effective_now != effective_then {
debug!(
" > @import rule changed {} -> {}",
effective_then, effective_now
" > @import rule {:?} changed {} -> {}",
import_rule.stylesheet.media(guard),
effective_then,
effective_now
);
return false;
}
@ -2401,8 +2414,10 @@ impl CascadeData {
if effective_now != effective_then {
debug!(
" > @media rule changed {} -> {}",
effective_then, effective_now
" > @media rule {:?} changed {} -> {}",
mq,
effective_then,
effective_now
);
return false;
}

View File

@ -231,6 +231,8 @@ pub struct CssInputAttrs {
#[derive(Default, FromVariant)]
pub struct CssVariantAttrs {
pub function: Option<Override<String>>,
// Here because structs variants are also their whole type definition.
pub derive_debug: bool,
pub comma: bool,
pub dimension: bool,
pub keyword: Option<String>,

View File

@ -143,7 +143,7 @@ use style::style_adjuster::StyleAdjuster;
use style::stylesheets::{CssRule, CssRules, CssRuleType, CssRulesHelpers, CounterStyleRule};
use style::stylesheets::{DocumentRule, FontFaceRule, FontFeatureValuesRule, ImportRule};
use style::stylesheets::{KeyframesRule, MediaRule, NamespaceRule, Origin, OriginSet, PageRule};
use style::stylesheets::{StyleRule, StylesheetContents, SupportsRule};
use style::stylesheets::{StyleRule, StylesheetContents, SupportsRule, UrlExtraData};
use style::stylesheets::StylesheetLoader as StyleStylesheetLoader;
use style::stylesheets::import_rule::ImportSheet;
use style::stylesheets::keyframes_rule::{Keyframe, KeyframeSelector, KeyframesStepValue};
@ -189,10 +189,10 @@ impl ClosureHelper for DeclarationBlockMutationClosure {
// A dummy url data for where we don't pass url data in.
// We need to get rid of this sooner than later.
static mut DUMMY_URL_DATA: *mut URLExtraData = 0 as *mut URLExtraData;
static mut DUMMY_URL_DATA: *mut URLExtraData = 0 as *mut _;
#[no_mangle]
pub extern "C" fn Servo_Initialize(dummy_url_data: *mut URLExtraData) {
pub unsafe extern "C" fn Servo_Initialize(dummy_url_data: *mut URLExtraData) {
use style::gecko_bindings::sugar::origin_flags;
// Pretend that we're a Servo Layout thread, to make some assertions happy.
@ -207,8 +207,7 @@ pub extern "C" fn Servo_Initialize(dummy_url_data: *mut URLExtraData) {
specified::font::assert_variant_ligatures_matches();
specified::box_::assert_touch_action_matches();
// Initialize the dummy url data
unsafe { DUMMY_URL_DATA = dummy_url_data; }
DUMMY_URL_DATA = dummy_url_data;
}
#[no_mangle]
@ -218,15 +217,14 @@ pub extern "C" fn Servo_InitializeCooperativeThread() {
}
#[no_mangle]
pub extern "C" fn Servo_Shutdown() {
// The dummy url will be released after shutdown, so clear the
// reference to avoid use-after-free.
unsafe { DUMMY_URL_DATA = ptr::null_mut(); }
pub unsafe extern "C" fn Servo_Shutdown() {
DUMMY_URL_DATA = ptr::null_mut();
Stylist::shutdown();
}
unsafe fn dummy_url_data() -> &'static RefPtr<URLExtraData> {
RefPtr::from_ptr_ref(&DUMMY_URL_DATA)
#[inline(always)]
unsafe fn dummy_url_data() -> &'static UrlExtraData {
UrlExtraData::from_ptr_ref(&DUMMY_URL_DATA)
}
#[allow(dead_code)]
@ -1181,7 +1179,7 @@ pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes(
let input: &str = unsafe { (*bytes).as_str_unchecked() };
let reporter = ErrorReporter::new(stylesheet, loader, extra_data);
let url_data = unsafe { RefPtr::from_ptr_ref(&extra_data) };
let url_data = unsafe { UrlExtraData::from_ptr_ref(&extra_data) };
let loader = if loader.is_null() {
None
} else {
@ -1208,7 +1206,7 @@ pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes(
}
#[no_mangle]
pub extern "C" fn Servo_StyleSheet_FromUTF8BytesAsync(
pub unsafe extern "C" fn Servo_StyleSheet_FromUTF8BytesAsync(
load_data: *mut SheetLoadDataHolder,
extra_data: *mut URLExtraData,
bytes: *const nsACString,
@ -1216,15 +1214,15 @@ pub extern "C" fn Servo_StyleSheet_FromUTF8BytesAsync(
line_number_offset: u32,
quirks_mode: nsCompatibility,
) {
let (load_data, extra_data, bytes) = unsafe {
let mut b = nsCString::new();
b.assign(&*bytes);
(RefPtr::new(load_data), RefPtr::new(extra_data), b)
};
let load_data = RefPtr::new(load_data);
let extra_data = UrlExtraData(RefPtr::new(extra_data));
let mut sheet_bytes = nsCString::new();
sheet_bytes.assign(&*bytes);
let async_parser = AsyncStylesheetParser::new(
load_data,
extra_data,
bytes,
sheet_bytes,
mode_to_origin(mode),
quirks_mode.into(),
line_number_offset
@ -2513,7 +2511,7 @@ pub unsafe extern "C" fn Servo_FontFaceRule_SetDescriptor(
let value = value.as_ref().unwrap().as_str_unchecked();
let mut input = ParserInput::new(&value);
let mut parser = Parser::new(&mut input);
let url_data = RefPtr::from_ptr_ref(&data);
let url_data = UrlExtraData::from_ptr_ref(&data);
let context = ParserContext::new(
Origin::Author,
url_data,
@ -3224,7 +3222,7 @@ fn parse_property_into(
) -> Result<(), ()> {
use style_traits::ParsingMode;
let value = unsafe { value.as_ref().unwrap().as_str_unchecked() };
let url_data = unsafe { RefPtr::from_ptr_ref(&data) };
let url_data = unsafe { UrlExtraData::from_ptr_ref(&data) };
let parsing_mode = ParsingMode::from_bits_truncate(parsing_mode);
parse_one_declaration_into(
@ -3284,7 +3282,7 @@ pub extern "C" fn Servo_ParseEasing(
use style::properties::longhands::transition_timing_function;
// FIXME Dummy URL data would work fine here.
let url_data = unsafe { RefPtr::from_ptr_ref(&data) };
let url_data = unsafe { UrlExtraData::from_ptr_ref(&data) };
let context = ParserContext::new(
Origin::Author,
url_data,
@ -3377,7 +3375,7 @@ pub extern "C" fn Servo_ParseStyleAttribute(
let global_style_data = &*GLOBAL_STYLE_DATA;
let value = unsafe { data.as_ref().unwrap().as_str_unchecked() };
let reporter = ErrorReporter::new(ptr::null_mut(), loader, raw_extra_data);
let url_data = unsafe { RefPtr::from_ptr_ref(&raw_extra_data) };
let url_data = unsafe { UrlExtraData::from_ptr_ref(&raw_extra_data) };
Arc::new(global_style_data.shared_lock.wrap(
parse_style_attribute(
value,
@ -4216,7 +4214,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetBackgroundImage(
use style::values::generics::image::Image;
use style::values::specified::url::SpecifiedImageUrl;
let url_data = unsafe { RefPtr::from_ptr_ref(&raw_extra_data) };
let url_data = unsafe { UrlExtraData::from_ptr_ref(&raw_extra_data) };
let string = unsafe { (*value).to_string() };
let context = ParserContext::new(
Origin::Author,
@ -5539,7 +5537,7 @@ pub extern "C" fn Servo_ParseFontShorthandForMatching(
let string = unsafe { (*value).to_string() };
let mut input = ParserInput::new(&string);
let mut parser = Parser::new(&mut input);
let url_data = unsafe { RefPtr::from_ptr_ref(&data) };
let url_data = unsafe { UrlExtraData::from_ptr_ref(&data) };
let context = ParserContext::new(
Origin::Author,
url_data,

View File

@ -12,14 +12,13 @@ use style::gecko_bindings::bindings;
use style::gecko_bindings::bindings::Gecko_LoadStyleSheet;
use style::gecko_bindings::structs::{Loader, LoaderReusableStyleSheets};
use style::gecko_bindings::structs::{StyleSheet as DomStyleSheet, SheetLoadData, SheetLoadDataHolder};
use style::gecko_bindings::structs::URLExtraData;
use style::gecko_bindings::sugar::ownership::FFIArcHelpers;
use style::gecko_bindings::sugar::refptr::RefPtr;
use style::media_queries::MediaList;
use style::parser::ParserContext;
use style::shared_lock::{Locked, SharedRwLock};
use style::stylesheets::{ImportRule, Origin, StylesheetLoader as StyleStylesheetLoader};
use style::stylesheets::StylesheetContents;
use style::stylesheets::{StylesheetContents, UrlExtraData};
use style::stylesheets::import_rule::ImportSheet;
use style::values::CssUrl;
@ -69,7 +68,7 @@ impl StyleStylesheetLoader for StylesheetLoader {
pub struct AsyncStylesheetParser {
load_data: RefPtr<SheetLoadDataHolder>,
extra_data: RefPtr<URLExtraData>,
extra_data: UrlExtraData,
bytes: nsCString,
origin: Origin,
quirks_mode: QuirksMode,
@ -79,7 +78,7 @@ pub struct AsyncStylesheetParser {
impl AsyncStylesheetParser {
pub fn new(
load_data: RefPtr<SheetLoadDataHolder>,
extra_data: RefPtr<URLExtraData>,
extra_data: UrlExtraData,
bytes: nsCString,
origin: Origin,
quirks_mode: QuirksMode,

View File

@ -0,0 +1,48 @@
# 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/.
loader: taskgraph.loader.transform:loader
transforms:
- taskgraph.transforms.release_deps:transforms
- taskgraph.transforms.release_version_bump:transforms
- taskgraph.transforms.task:transforms
job-defaults:
description: Release Promotion version tag for buildN
run-on-projects: []
shipping-phase: promote
worker-type:
by-project:
mozilla-(beta|release|esr.*): scriptworker-prov-v1/treescript-v1
maple: scriptworker-prov-v1/treescript-v1
birch: scriptworker-prov-v1/treescript-v1
jamun: scriptworker-prov-v1/treescript-v1
default: scriptworker-prov-v1/treescript-dev
worker:
implementation: treescript
tags: ['buildN']
bump: false
push:
by-project:
mozilla-beta: true
mozilla-release: true
mozilla-esr52: true
mozilla-esr60: true
maple: true
birch: true
default: false
jobs:
fennec:
name: fennec-tag-buildN
shipping-product: fennec
firefox:
name: firefox-tag-buildN
shipping-product: firefox
devedition:
name: devedition-tag-buildN
shipping-product: devedition

View File

@ -25,7 +25,7 @@ job-defaults:
default: scriptworker-prov-v1/treescript-dev
worker:
implementation: treescript
tag: true
tags: ['release']
bump: true
bump-files:
by-project:

View File

@ -394,6 +394,10 @@ release-partner-repack-beetmover
------------------------------
Moves the partner repacks to S3 buckets.
release-early-tagging
---------------------
Utilises treescript to perform tagging that should happen near the start of a release.
release-eme-free-repack
----------------------
Generates customized versions of releases for eme-free repacks.

View File

@ -545,7 +545,7 @@ task_description_schema = Schema({
Required('release-name'): basestring,
}, {
Required('implementation'): 'treescript',
Required('tag'): bool,
Required('tags'): [Any('buildN', 'release', None)],
Required('bump'): bool,
Optional('bump-files'): [basestring],
Optional('repo-param-prefix'): basestring,
@ -1139,14 +1139,19 @@ def build_treescript_payload(config, task, task_def):
task_def['payload'] = {}
task_def.setdefault('scopes', [])
if worker['tag']:
if worker['tags']:
tag_names = []
product = task['shipping-product'].upper()
version = release_config['version'].replace('.', '_')
buildnum = release_config['build_number']
tag_names = [
"{}_{}_BUILD{}".format(product, version, buildnum),
"{}_{}_RELEASE".format(product, version)
]
if 'buildN' in worker['tags']:
tag_names.extend([
"{}_{}_BUILD{}".format(product, version, buildnum),
])
if 'release' in worker['tags']:
tag_names.extend([
"{}_{}_RELEASE".format(product, version)
])
tag_info = {
'tags': tag_names,
'revision': config.params['{}head_rev'.format(worker.get('repo-param-prefix', ''))],

View File

@ -129451,6 +129451,30 @@
{}
]
],
"css/css-scoping/shadow-link-rel-stylesheet-no-style-leak.html": [
[
"/css/css-scoping/shadow-link-rel-stylesheet-no-style-leak.html",
[
[
"/css/css-scoping/reference/green-box.html",
"=="
]
],
{}
]
],
"css/css-scoping/shadow-link-rel-stylesheet.html": [
[
"/css/css-scoping/shadow-link-rel-stylesheet.html",
[
[
"/css/css-scoping/reference/green-box.html",
"=="
]
],
{}
]
],
"css/css-scoping/shadow-reassign-dynamic-001.html": [
[
"/css/css-scoping/shadow-reassign-dynamic-001.html",
@ -324151,6 +324175,18 @@
{}
]
],
"css/cssom/getComputedStyle-display-none-001.html": [
[
"/css/cssom/getComputedStyle-display-none-001.html",
{}
]
],
"css/cssom/getComputedStyle-display-none-002.html": [
[
"/css/cssom/getComputedStyle-display-none-002.html",
{}
]
],
"css/cssom/getComputedStyle-dynamic-subdoc.html": [
[
"/css/cssom/getComputedStyle-dynamic-subdoc.html",
@ -340913,6 +340949,12 @@
{}
]
],
"html/scripting/the-noscript-element/non-html-noscript.html": [
[
"/html/scripting/the-noscript-element/non-html-noscript.html",
{}
]
],
"html/semantics/disabled-elements/disabledElement.html": [
[
"/html/semantics/disabled-elements/disabledElement.html",
@ -523066,6 +523108,14 @@
"99af6e29e69b3131b59dbdc2b0eead52931123c2",
"reftest"
],
"css/css-scoping/shadow-link-rel-stylesheet-no-style-leak.html": [
"76a54dabd8bd09f7155ab0331e3d17d1a0cae243",
"reftest"
],
"css/css-scoping/shadow-link-rel-stylesheet.html": [
"07862ce7d2a954988bdbce882869a4c5f097089a",
"reftest"
],
"css/css-scoping/shadow-reassign-dynamic-001.html": [
"11ed4da2e6ce88d8a2b98a8f1c814417ef7770dd",
"reftest"
@ -547462,6 +547512,14 @@
"886f72b4eaa82d3aeb4de5c5b27f71369dbe0186",
"testharness"
],
"css/cssom/getComputedStyle-display-none-001.html": [
"0e1f381bb67d045c9a92461f664c3c4d61de280f",
"testharness"
],
"css/cssom/getComputedStyle-display-none-002.html": [
"23a362d9423cdfe6d8c29809fdadca525054d175",
"testharness"
],
"css/cssom/getComputedStyle-dynamic-subdoc.html": [
"3f379487727d9730de9e3569b26632c35d602d9d",
"testharness"
@ -548543,7 +548601,7 @@
"support"
],
"css/mediaqueries/test_media_queries.html": [
"cff3585932589f611a7101329d3b5b6ca27820aa",
"a7d78b13e119f8cd1ffa8812a9af67e59280084d",
"testharness"
],
"css/mediaqueries/viewport-script-dynamic-ref.html": [
@ -577790,6 +577848,10 @@
"0f18ee2c61b99893cfe2a3d1ff549b170a8d715d",
"support"
],
"html/scripting/the-noscript-element/non-html-noscript.html": [
"c0c5453111f29e5a0206f988f4d127ec8ebc2f13",
"testharness"
],
"html/semantics/.gitkeep": [
"da39a3ee5e6b4b0d3255bfef95601890afd80709",
"support"
@ -619119,7 +619181,7 @@
"support"
],
"webdriver/tests/support/fixtures.py": [
"f1c704ea7b44e08dd63eaac6b5e9a3370e4c0503",
"5ae91067cee6f4cf7e3c63e99aca65104bbc2fab",
"support"
],
"webdriver/tests/support/http_request.py": [

View File

@ -0,0 +1,2 @@
[getComputedStyle-display-none-001.html]
prefs: [dom.webcomponents.shadowdom.enabled:true]

View File

@ -0,0 +1,21 @@
<!doctype html>
<title>CSS Test: &lt;link rel="stylesheet"&gt; in Shadow DOM doesn't affect the normal DOM</title>
<link rel="help" href="https://html.spec.whatwg.org/#link-type-stylesheet">
<link rel="help" href="https://drafts.csswg.org/css-scoping/#selectors-data-model">
<link rel="match" href="reference/green-box.html">
<p>Test passes if you see a single 100px by 100px green box below.</p>
<style>
#light-dom {
width: 100px;
height: 100px;
background: green;
color: green;
}
</style>
<div id="host">FAIL</div>
<div id="light-dom"></div>
<script>
host.attachShadow({ mode: "open" }).innerHTML = `
<link rel="stylesheet" href="data:text/css,div { background: red !important }">
`;
</script>

View File

@ -0,0 +1,11 @@
<!doctype html>
<title>CSS Test: &lt;link rel="stylesheet"&gt; in Shadow DOM</title>
<link rel="help" href="https://html.spec.whatwg.org/#link-type-stylesheet">
<link rel="match" href="reference/green-box.html">
<p>Test passes if you see a single 100px by 100px green box below.</p>
<div id="host">FAIL</div>
<script>
host.attachShadow({ mode: "open" }).innerHTML = `
<link rel="stylesheet" href="resources/host-green-box.css">
`;
</script>

View File

@ -0,0 +1,39 @@
<!doctype html>
<meta charset="utf-8">
<title>CSSOM: getComputedStyle gets invalidated for display: none elements (inheritance)</title>
<link rel="help" href="https://drafts.csswg.org/cssom/#dom-window-getcomputedstyle">
<link rel="help" href="https://bugs.webkit.org/show_bug.cgi?id=186882">
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<style>
#undisplayed, #host {
display: none;
color: red;
}
</style>
<div id="undisplayed"><div id="child"></div></div>
<div id="host"></div>
<script>
test(function() {
let undisplayed_style = getComputedStyle(undisplayed);
let undisplayed_child_style = getComputedStyle(child);
assert_equals(undisplayed_style.color, "rgb(255, 0, 0)");
assert_equals(undisplayed_child_style.color, "rgb(255, 0, 0)");
undisplayed.style.color = "green";
assert_equals(undisplayed_style.color, "rgb(0, 128, 0)");
assert_equals(undisplayed_child_style.color, "rgb(0, 128, 0)");
}, "getComputedStyle gets invalidated in display: none subtrees due to inherited changes to an ancestor");
test(function() {
host.attachShadow({ mode: 'open' }).innerHTML = `
<div></div>
`;
let host_style = getComputedStyle(host);
let shadow_style = getComputedStyle(host.shadowRoot.firstElementChild);
assert_equals(host_style.color, "rgb(255, 0, 0)");
assert_equals(shadow_style.color, "rgb(255, 0, 0)");
host.style.color = "green";
assert_equals(host_style.color, "rgb(0, 128, 0)");
assert_equals(shadow_style.color, "rgb(0, 128, 0)");
}, "getComputedStyle gets invalidated in display: none subtrees due to inherited changes to an ancestor shadow host");
</script>

View File

@ -0,0 +1,34 @@
<!doctype html>
<meta charset="utf-8">
<title>CSSOM: getComputedStyle gets invalidated for display: none elements (rules)</title>
<link rel="help" href="https://drafts.csswg.org/cssom/#dom-window-getcomputedstyle">
<link rel="help" href="https://bugs.webkit.org/show_bug.cgi?id=186882">
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<style>
#undisplayed {
display: none;
color: red;
}
.sibling + #undisplayed {
color: green;
}
.sibling + #undisplayed > div {
color: yellow;
}
</style>
<div id="helper"></div>
<div id="undisplayed"><div id="child"></div></div>
<script>
test(function() {
let undisplayed_style = getComputedStyle(undisplayed);
let undisplayed_child_style = getComputedStyle(child);
assert_equals(undisplayed_style.color, "rgb(255, 0, 0)");
assert_equals(undisplayed_child_style.color, "rgb(255, 0, 0)");
helper.classList.add("sibling");
assert_equals(undisplayed_style.color, "rgb(0, 128, 0)");
assert_equals(undisplayed_child_style.color, "rgb(255, 255, 0)");
}, "getComputedStyle gets invalidated in display: none subtrees due to rule matching changes");
</script>

View File

@ -0,0 +1,16 @@
<!doctype html>
<title>noscript rules don't apply to non-html elements</title>
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-noscript-element">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1470150">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<script>
test(function() {
let non_html_noscript = document.createElementNS("http://www.w3.org/2000/svg", "noscript");
document.body.appendChild(non_html_noscript);
assert_not_equals(getComputedStyle(non_html_noscript).display, "none");
}, "Non-HTML <noscript> element shouldn't be undisplayed by a UA rule");
</script>
</body>

View File

@ -101,8 +101,8 @@
present.places = true;
} else if (aPath.search(/^explicit\/images/) >= 0) {
present.images = true;
} else if (aPath.search(/^explicit\/atoms\/dynamic\/atom-objects$/) >= 0) {
present.dynamicAtomObjects = true;
} else if (aPath.search(/^explicit\/atoms\/dynamic-objects-and-chars$/) >= 0) {
present.dynamicObjectsAndChars = true;
} else if (/\[System Principal\].*this-is-a-sandbox-name/.test(aPath)) {
// A system compartment with a location (such as a sandbox) should
// show that location.
@ -259,7 +259,7 @@
ok(present.windowObjectsJsRealms, "window-objects/.../js realms are present");
ok(present.places, "places is present");
ok(present.images, "images is present");
ok(present.dynamicAtomObjects, "dynamic/atom-objects is present");
ok(present.dynamicObjectsAndChars, "dynamic-objects-and-chars is present");
ok(present.sandboxLocation, "sandbox locations are present");
ok(present.bigString, "large string is present");
ok(present.smallString1, "small string 1 is present");

View File

@ -12817,7 +12817,7 @@
"kind": "exponential",
"high": 1000,
"n_buckets": 50,
"description": "Time spent in the paint pipeline for content."
"description": "Time spent in the paint pipeline for content in milliseconds."
},
"CONTENT_LARGE_PAINT_PHASE_WEIGHT": {
"record_in_processes": ["main", "content"],
@ -12825,10 +12825,11 @@
"bug_numbers": [1309442],
"expires_in_version": "66",
"keyed": true,
"keys": ["dl", "flb", "fr", "r"],
"kind": "linear",
"high": 100,
"n_buckets": 10,
"description": "Percentage of time taken by phases in expensive content paints."
"description": "Percentages of times for phases in an expensive content paint relative to the time spent in the entire expensive paint. (\"dl\" = Display list, \"flb\" = Frame layer builder, \"fr\" = Flush rasterization, \"r\" = Rasterization)"
},
"CONTENT_SMALL_PAINT_PHASE_WEIGHT": {
"record_in_processes": ["main", "content"],
@ -12836,10 +12837,11 @@
"bug_numbers": [1430897],
"expires_in_version": "66",
"keyed": true,
"keys": ["dl", "flb", "fr", "r"],
"kind": "linear",
"high": 100,
"n_buckets": 10,
"description": "Percentage of time taken by phases in normal content paints."
"description": "Percentages of times for phases in a normal content paint relative to the time spent in the entire normal paint. (\"dl\" = Display list, \"flb\" = Frame layer builder, \"fr\" = Flush rasterization, \"r\" = Rasterization)"
},
"NARRATE_CONTENT_BY_LANGUAGE_2": {
"record_in_processes": ["main", "content"],

View File

@ -1421,15 +1421,10 @@ public:
"Memory used by the atom table.");
MOZ_COLLECT_REPORT(
"explicit/atoms/dynamic/atom-objects", KIND_HEAP, UNITS_BYTES,
sizes.mDynamicAtomObjects,
"Memory used by dynamic atom objects.");
MOZ_COLLECT_REPORT(
"explicit/atoms/dynamic/unshared-buffers", KIND_HEAP, UNITS_BYTES,
sizes.mDynamicUnsharedBuffers,
"Memory used by unshared string buffers pointed to by dynamic atom "
"objects.");
"explicit/atoms/dynamic-objects-and-chars", KIND_HEAP, UNITS_BYTES,
sizes.mDynamicAtoms,
"Memory used by dynamic atom objects and chars (which are stored "
"at the end of each atom object).");
return NS_OK;
}

View File

@ -9,8 +9,8 @@
#include "nsISupportsImpl.h"
#include "nsString.h"
#include "nsStringBuffer.h"
#include "mozilla/HashFunctions.h"
#include "mozilla/UniquePtr.h"
namespace mozilla {
struct AtomsSizes;
@ -167,17 +167,9 @@ public:
MozExternalRefCountType AddRef();
MozExternalRefCountType Release();
~nsDynamicAtom();
const char16_t* String() const { return mString; }
// The caller must *not* mutate the string buffer, otherwise all hell will
// break loose.
nsStringBuffer* GetStringBuffer() const
const char16_t* String() const
{
// See the comment on |mString|'s declaration.
MOZ_ASSERT(IsDynamic());
return nsStringBuffer::FromData(const_cast<char16_t*>(mString));
return reinterpret_cast<const char16_t*>(this + 1);
}
private:
@ -186,16 +178,21 @@ private:
// XXX: we'd like to remove nsHtml5AtomEntry. See bug 1392185.
friend class nsHtml5AtomEntry;
// Construction is done by |friend|s.
// The first constructor is for dynamic normal atoms, the second is for
// dynamic HTML5 atoms.
// These shouldn't be used directly, even by friend classes. The
// Create()/Destroy() methods use them.
static nsDynamicAtom* CreateInner(const nsAString& aString, uint32_t aHash);
nsDynamicAtom(const nsAString& aString, uint32_t aHash);
explicit nsDynamicAtom(const nsAString& aString);
~nsDynamicAtom() {}
// Creation/destruction is done by friend classes. The first Create() is for
// dynamic normal atoms, the second is for dynamic HTML5 atoms.
static nsDynamicAtom* Create(const nsAString& aString, uint32_t aHash);
static nsDynamicAtom* Create(const nsAString& aString);
static void Destroy(nsDynamicAtom* aAtom);
mozilla::ThreadSafeAutoRefCnt mRefCnt;
// Note: this points to the chars in an nsStringBuffer, which is obtained
// with nsStringBuffer::FromData(mString).
const char16_t* const mString;
// The atom's chars are stored at the end of the struct.
};
// The four forms of NS_Atomize (for use with |RefPtr<nsAtom>|) return the

View File

@ -30,7 +30,7 @@
// There are two kinds of atoms handled by this module.
//
// - Dynamic: the atom itself is heap allocated, as is the nsStringBuffer it
// - Dynamic: the atom itself is heap allocated, as is the char buffer it
// points to. |gAtomTable| holds weak references to dynamic atoms. When the
// refcount of a dynamic atom drops to zero, we increment a static counter.
// When that counter reaches a certain threshold, we iterate over the atom
@ -63,57 +63,49 @@ enum class GCKind {
// See nsAtom::AddRef() and nsAtom::Release().
static Atomic<int32_t, ReleaseAcquire> gUnusedAtomCount(0);
static char16_t*
FromStringBuffer(const nsAString& aString)
{
char16_t* str;
size_t length = aString.Length();
RefPtr<nsStringBuffer> buf = nsStringBuffer::FromString(aString);
if (buf) {
str = static_cast<char16_t*>(buf->Data());
} else {
const size_t size = (length + 1) * sizeof(char16_t);
buf = nsStringBuffer::Alloc(size);
if (MOZ_UNLIKELY(!buf)) {
NS_ABORT_OOM(size); // OOM because atom allocations should be small.
}
str = static_cast<char16_t*>(buf->Data());
CopyUnicodeTo(aString, 0, str, length);
str[length] = char16_t(0);
}
MOZ_ASSERT(buf && buf->StorageSize() >= (length + 1) * sizeof(char16_t),
"enough storage");
// Take ownership of the string buffer.
mozilla::Unused << buf.forget();
return str;
}
nsDynamicAtom::nsDynamicAtom(const nsAString& aString, uint32_t aHash)
: nsAtom(AtomKind::DynamicNormal, aString, aHash)
, mRefCnt(1)
, mString(FromStringBuffer(aString))
{
MOZ_ASSERT(mHash == HashString(mString, mLength));
MOZ_ASSERT(mString[mLength] == char16_t(0), "null terminated");
MOZ_ASSERT(Equals(aString), "correct data");
}
nsDynamicAtom::nsDynamicAtom(const nsAString& aString)
: nsAtom(AtomKind::DynamicHTML5, aString, 0)
, mRefCnt(1)
, mString(FromStringBuffer(aString))
nsDynamicAtom*
nsDynamicAtom::CreateInner(const nsAString& aString, uint32_t aHash)
{
MOZ_ASSERT(mString[mLength] == char16_t(0), "null terminated");
MOZ_ASSERT(Equals(aString), "correct data");
// We tack the chars onto the end of the nsDynamicAtom object.
size_t numCharBytes = (aString.Length() + 1) * sizeof(char16_t);
size_t numTotalBytes = sizeof(nsDynamicAtom) + numCharBytes;
nsDynamicAtom* atom = (nsDynamicAtom*)moz_xmalloc(numTotalBytes);
new (atom) nsDynamicAtom(aString, aHash);
memcpy(const_cast<char16_t*>(atom->String()),
PromiseFlatString(aString).get(), numCharBytes);
MOZ_ASSERT(atom->String()[atom->GetLength()] == char16_t(0));
MOZ_ASSERT(atom->Equals(aString));
return atom;
}
nsDynamicAtom::~nsDynamicAtom()
nsDynamicAtom*
nsDynamicAtom::Create(const nsAString& aString, uint32_t aHash)
{
GetStringBuffer()->Release();
nsDynamicAtom* atom = CreateInner(aString, aHash);
MOZ_ASSERT(atom->mHash == HashString(atom->String(), atom->GetLength()));
return atom;
}
nsDynamicAtom*
nsDynamicAtom::Create(const nsAString& aString)
{
return CreateInner(aString, /* hash */ 0);
}
void
nsDynamicAtom::Destroy(nsDynamicAtom* aAtom)
{
aAtom->~nsDynamicAtom();
free(aAtom);
}
const nsStaticAtom*
@ -147,7 +139,7 @@ nsAtom::ToString(nsAString& aString) const
// which is what's important.
aString.AssignLiteral(AsStatic()->String(), mLength);
} else {
AsDynamic()->GetStringBuffer()->ToString(mLength, aString);
aString.Assign(AsDynamic()->String(), mLength);
}
}
@ -168,10 +160,7 @@ nsAtom::AddSizeOfIncludingThis(MallocSizeOf aMallocSizeOf, AtomsSizes& aSizes)
// Static atoms are in static memory, and so are not measured here.
if (IsDynamic()) {
aSizes.mDynamicAtomObjects += aMallocSizeOf(this);
aSizes.mDynamicUnsharedBuffers +=
AsDynamic()->GetStringBuffer()->SizeOfIncludingThisIfUnshared(
aMallocSizeOf);
aSizes.mDynamicAtoms += aMallocSizeOf(this);
}
}
@ -501,7 +490,7 @@ nsAtomSubTable::GCLocked(GCKind aKind)
MOZ_ASSERT(!atom->IsDynamicHTML5());
if (atom->IsDynamic() && atom->AsDynamic()->mRefCnt == 0) {
i.Remove();
delete atom->AsDynamic();
nsDynamicAtom::Destroy(atom->AsDynamic());
++removedCount;
}
#ifdef NS_FREE_PERMANENT_DATA
@ -706,12 +695,9 @@ nsAtomTable::Atomize(const nsACString& aUTF8String)
return atom.forget();
}
// This results in an extra addref/release of the nsStringBuffer.
// Unfortunately there doesn't seem to be any APIs to avoid that.
// Actually, now there is, sort of: ForgetSharedBuffer.
nsString str;
CopyUTF8toUTF16(aUTF8String, str);
RefPtr<nsAtom> atom = dont_AddRef(new nsDynamicAtom(str, hash));
RefPtr<nsAtom> atom = dont_AddRef(nsDynamicAtom::Create(str, hash));
he->mAtom = atom;
@ -747,7 +733,7 @@ nsAtomTable::Atomize(const nsAString& aUTF16String)
return atom.forget();
}
RefPtr<nsAtom> atom = dont_AddRef(new nsDynamicAtom(aUTF16String, hash));
RefPtr<nsAtom> atom = dont_AddRef(nsDynamicAtom::Create(aUTF16String, hash));
he->mAtom = atom;
return atom.forget();
@ -786,7 +772,8 @@ nsAtomTable::AtomizeMainThread(const nsAString& aUTF16String)
if (he->mAtom) {
retVal = he->mAtom;
} else {
RefPtr<nsAtom> newAtom = dont_AddRef(new nsDynamicAtom(aUTF16String, hash));
RefPtr<nsAtom> newAtom =
dont_AddRef(nsDynamicAtom::Create(aUTF16String, hash));
he->mAtom = newAtom;
retVal = newAtom.forget();
}

View File

@ -17,13 +17,11 @@ namespace mozilla {
struct AtomsSizes
{
size_t mTable;
size_t mDynamicAtomObjects;
size_t mDynamicUnsharedBuffers;
size_t mDynamicAtoms;
AtomsSizes()
: mTable(0)
, mDynamicAtomObjects(0)
, mDynamicUnsharedBuffers(0)
, mDynamicAtoms(0)
{}
};
} // namespace mozilla

View File

@ -54,16 +54,6 @@ TEST(Atoms, 16vs8)
}
}
TEST(Atoms, BufferSharing)
{
nsString unique;
unique.AssignLiteral("this is a unique string !@#$");
RefPtr<nsAtom> atom = NS_Atomize(unique);
EXPECT_EQ(unique.get(), atom->GetUTF16String());
}
TEST(Atoms, Null)
{
nsAutoString str(NS_LITERAL_STRING("string with a \0 char"));