2015-05-03 22:32:37 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* 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/. */
|
2001-11-11 04:15:22 +03:00
|
|
|
|
|
|
|
#include "nsIDocument.h"
|
|
|
|
#include "nsIContent.h"
|
|
|
|
#include "nsIServiceManager.h"
|
|
|
|
#include "nsXBLResourceLoader.h"
|
|
|
|
#include "nsXBLPrototypeResources.h"
|
2010-03-03 00:00:53 +03:00
|
|
|
#include "nsXBLPrototypeBinding.h"
|
2001-11-11 04:15:22 +03:00
|
|
|
#include "nsIDocumentObserver.h"
|
2010-06-29 02:49:35 +04:00
|
|
|
#include "mozilla/css/Loader.h"
|
2001-12-18 01:51:39 +03:00
|
|
|
#include "nsIURI.h"
|
|
|
|
#include "nsLayoutCID.h"
|
2013-11-20 20:29:03 +04:00
|
|
|
#include "mozilla/dom/URL.h"
|
2014-06-19 11:28:47 +04:00
|
|
|
#include "mozilla/DebugOnly.h"
|
2016-09-26 15:03:25 +03:00
|
|
|
#include "mozilla/StyleSheet.h"
|
|
|
|
#include "mozilla/StyleSheetInlines.h"
|
2013-11-20 20:29:03 +04:00
|
|
|
|
2014-06-19 12:02:14 +04:00
|
|
|
using namespace mozilla;
|
2013-11-20 20:29:03 +04:00
|
|
|
using mozilla::dom::IsChromeURI;
|
2001-12-18 01:51:39 +03:00
|
|
|
|
2003-03-07 02:59:18 +03:00
|
|
|
nsXBLPrototypeResources::nsXBLPrototypeResources(nsXBLPrototypeBinding* aBinding)
|
2001-11-11 04:15:22 +03:00
|
|
|
{
|
|
|
|
MOZ_COUNT_CTOR(nsXBLPrototypeResources);
|
|
|
|
|
|
|
|
mLoader = new nsXBLResourceLoader(aBinding, this);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsXBLPrototypeResources::~nsXBLPrototypeResources()
|
|
|
|
{
|
|
|
|
MOZ_COUNT_DTOR(nsXBLPrototypeResources);
|
2004-01-06 02:46:00 +03:00
|
|
|
if (mLoader) {
|
2012-07-30 18:20:58 +04:00
|
|
|
mLoader->mResources = nullptr;
|
2004-01-06 02:46:00 +03:00
|
|
|
}
|
2001-11-11 04:15:22 +03:00
|
|
|
}
|
|
|
|
|
2014-04-10 18:05:21 +04:00
|
|
|
void
|
2017-10-03 01:05:19 +03:00
|
|
|
nsXBLPrototypeResources::AddResource(nsAtom* aResourceType, const nsAString& aSrc)
|
2001-11-11 04:15:22 +03:00
|
|
|
{
|
|
|
|
if (mLoader)
|
|
|
|
mLoader->AddResource(aResourceType, aSrc);
|
|
|
|
}
|
2014-04-10 18:05:21 +04:00
|
|
|
|
2017-06-05 09:29:31 +03:00
|
|
|
bool
|
2017-06-05 09:30:52 +03:00
|
|
|
nsXBLPrototypeResources::LoadResources(nsIContent* aBoundElement)
|
2001-11-11 04:15:22 +03:00
|
|
|
{
|
2017-06-05 09:29:31 +03:00
|
|
|
if (mLoader) {
|
2017-06-05 09:30:52 +03:00
|
|
|
return mLoader->LoadResources(aBoundElement);
|
2017-06-05 09:29:31 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return true; // All resources loaded.
|
2001-11-11 04:15:22 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2014-04-10 18:05:21 +04:00
|
|
|
nsXBLPrototypeResources::AddResourceListener(nsIContent* aBoundElement)
|
2001-11-11 04:15:22 +03:00
|
|
|
{
|
|
|
|
if (mLoader)
|
|
|
|
mLoader->AddResourceListener(aBoundElement);
|
|
|
|
}
|
2001-12-18 01:51:39 +03:00
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsXBLPrototypeResources::FlushSkinSheets()
|
|
|
|
{
|
2010-05-12 00:41:47 +04:00
|
|
|
if (mStyleSheetList.Length() == 0)
|
2001-12-18 01:51:39 +03:00
|
|
|
return NS_OK;
|
|
|
|
|
2010-07-15 05:55:54 +04:00
|
|
|
nsCOMPtr<nsIDocument> doc =
|
|
|
|
mLoader->mBinding->XBLDocumentInfo()->GetDocument();
|
2014-04-24 01:20:09 +04:00
|
|
|
|
|
|
|
// If doc is null, we're in the process of tearing things down, so just
|
|
|
|
// return without rebuilding anything.
|
|
|
|
if (!doc) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2010-03-03 00:00:53 +03:00
|
|
|
|
2001-12-18 01:51:39 +03:00
|
|
|
// We have scoped stylesheets. Reload any chrome stylesheets we
|
|
|
|
// encounter. (If they aren't skin sheets, it doesn't matter, since
|
2016-03-26 09:02:30 +03:00
|
|
|
// they'll still be in the chrome cache. Skip inline sheets, which
|
|
|
|
// skin sheets can't be, and which in any case don't have a usable
|
|
|
|
// URL to reload.)
|
2001-12-18 01:51:39 +03:00
|
|
|
|
2016-09-26 15:03:25 +03:00
|
|
|
nsTArray<RefPtr<StyleSheet>> oldSheets;
|
2014-06-19 11:02:56 +04:00
|
|
|
|
|
|
|
oldSheets.SwapElements(mStyleSheetList);
|
2010-03-03 00:00:53 +03:00
|
|
|
|
2014-04-24 01:20:09 +04:00
|
|
|
mozilla::css::Loader* cssLoader = doc->CSSLoader();
|
|
|
|
|
2014-06-19 11:02:56 +04:00
|
|
|
for (size_t i = 0, count = oldSheets.Length(); i < count; ++i) {
|
2016-09-26 15:03:25 +03:00
|
|
|
StyleSheet* oldSheet = oldSheets[i];
|
2010-03-03 00:00:53 +03:00
|
|
|
|
2010-05-18 08:00:40 +04:00
|
|
|
nsIURI* uri = oldSheet->GetSheetURI();
|
2001-12-18 01:51:39 +03:00
|
|
|
|
2016-09-26 15:03:25 +03:00
|
|
|
RefPtr<StyleSheet> newSheet;
|
2016-03-26 09:02:30 +03:00
|
|
|
if (!oldSheet->IsInline() && IsChromeURI(uri)) {
|
2016-02-24 10:01:12 +03:00
|
|
|
if (NS_FAILED(cssLoader->LoadSheetSync(uri, &newSheet)))
|
2002-01-16 09:40:47 +03:00
|
|
|
continue;
|
2001-12-18 01:51:39 +03:00
|
|
|
}
|
2004-01-13 02:43:59 +03:00
|
|
|
else {
|
2001-12-18 01:51:39 +03:00
|
|
|
newSheet = oldSheet;
|
2004-01-13 02:43:59 +03:00
|
|
|
}
|
2010-03-03 00:00:53 +03:00
|
|
|
|
2010-05-12 00:41:47 +04:00
|
|
|
mStyleSheetList.AppendElement(newSheet);
|
2001-12-18 01:51:39 +03:00
|
|
|
}
|
2014-06-19 11:02:56 +04:00
|
|
|
|
2018-03-25 20:42:10 +03:00
|
|
|
// There may be no shell during unlink.
|
|
|
|
if (auto* shell = doc->GetShell()) {
|
|
|
|
MOZ_ASSERT(shell->GetPresContext());
|
2018-03-29 14:15:46 +03:00
|
|
|
ComputeServoStyles(*shell->StyleSet());
|
2017-10-16 19:42:04 +03:00
|
|
|
}
|
2010-03-03 00:00:53 +03:00
|
|
|
|
2001-12-18 01:51:39 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2011-11-04 00:39:08 +04:00
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsXBLPrototypeResources::Write(nsIObjectOutputStream* aStream)
|
|
|
|
{
|
|
|
|
if (mLoader)
|
|
|
|
return mLoader->Write(aStream);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2014-04-10 18:05:21 +04:00
|
|
|
|
|
|
|
void
|
2014-06-24 06:09:36 +04:00
|
|
|
nsXBLPrototypeResources::Traverse(nsCycleCollectionTraversalCallback &cb)
|
2014-04-10 18:05:21 +04:00
|
|
|
{
|
|
|
|
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "proto mResources mLoader");
|
|
|
|
cb.NoteXPCOMChild(mLoader);
|
2014-06-24 06:09:36 +04:00
|
|
|
|
|
|
|
ImplCycleCollectionTraverse(cb, mStyleSheetList, "mStyleSheetList");
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsXBLPrototypeResources::Unlink()
|
|
|
|
{
|
|
|
|
mStyleSheetList.Clear();
|
2014-04-10 18:05:21 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsXBLPrototypeResources::ClearLoader()
|
|
|
|
{
|
2014-04-10 18:05:21 +04:00
|
|
|
mLoader = nullptr;
|
2014-04-10 18:05:21 +04:00
|
|
|
}
|
2014-06-19 11:02:56 +04:00
|
|
|
|
2014-06-19 11:02:56 +04:00
|
|
|
|
2017-06-05 08:06:52 +03:00
|
|
|
void
|
2018-02-18 16:35:57 +03:00
|
|
|
nsXBLPrototypeResources::SyncServoStyles()
|
2017-06-05 08:06:52 +03:00
|
|
|
{
|
2018-02-12 15:57:26 +03:00
|
|
|
mStyleRuleMap.reset(nullptr);
|
|
|
|
mServoStyles.reset(Servo_AuthorStyles_Create());
|
|
|
|
for (auto& sheet : mStyleSheetList) {
|
|
|
|
Servo_AuthorStyles_AppendStyleSheet(mServoStyles.get(), sheet->AsServo());
|
2017-06-05 08:06:52 +03:00
|
|
|
}
|
2018-02-18 16:35:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsXBLPrototypeResources::ComputeServoStyles(const ServoStyleSet& aMasterStyleSet)
|
|
|
|
{
|
|
|
|
SyncServoStyles();
|
2018-02-12 15:57:26 +03:00
|
|
|
Servo_AuthorStyles_Flush(mServoStyles.get(), aMasterStyleSet.RawSet());
|
|
|
|
}
|
2017-08-22 09:46:25 +03:00
|
|
|
|
2018-02-12 15:57:26 +03:00
|
|
|
ServoStyleRuleMap*
|
|
|
|
nsXBLPrototypeResources::GetServoStyleRuleMap()
|
|
|
|
{
|
|
|
|
if (!HasStyleSheets() || !mServoStyles) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!mStyleRuleMap) {
|
|
|
|
mStyleRuleMap = MakeUnique<ServoStyleRuleMap>();
|
|
|
|
}
|
|
|
|
|
|
|
|
mStyleRuleMap->EnsureTable(*this);
|
|
|
|
return mStyleRuleMap.get();
|
2017-06-05 08:06:52 +03:00
|
|
|
}
|
|
|
|
|
2014-06-19 11:02:56 +04:00
|
|
|
void
|
2016-09-26 15:03:25 +03:00
|
|
|
nsXBLPrototypeResources::AppendStyleSheet(StyleSheet* aSheet)
|
2014-06-19 11:02:56 +04:00
|
|
|
{
|
|
|
|
mStyleSheetList.AppendElement(aSheet);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-09-26 15:03:25 +03:00
|
|
|
nsXBLPrototypeResources::RemoveStyleSheet(StyleSheet* aSheet)
|
2014-06-19 11:02:56 +04:00
|
|
|
{
|
2014-06-24 06:09:36 +04:00
|
|
|
mStyleSheetList.RemoveElement(aSheet);
|
2014-06-19 11:02:56 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-09-26 15:03:25 +03:00
|
|
|
nsXBLPrototypeResources::InsertStyleSheetAt(size_t aIndex, StyleSheet* aSheet)
|
2014-06-19 11:02:56 +04:00
|
|
|
{
|
|
|
|
mStyleSheetList.InsertElementAt(aIndex, aSheet);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsXBLPrototypeResources::AppendStyleSheetsTo(
|
2016-09-26 15:03:25 +03:00
|
|
|
nsTArray<StyleSheet*>& aResult) const
|
2014-06-19 11:02:56 +04:00
|
|
|
{
|
|
|
|
aResult.AppendElements(mStyleSheetList);
|
|
|
|
}
|
2018-02-16 15:02:28 +03:00
|
|
|
|
|
|
|
MOZ_DEFINE_MALLOC_SIZE_OF(ServoAuthorStylesMallocSizeOf)
|
|
|
|
MOZ_DEFINE_MALLOC_ENCLOSING_SIZE_OF(ServoAuthorStylesMallocEnclosingSizeOf)
|
|
|
|
|
|
|
|
size_t
|
|
|
|
nsXBLPrototypeResources::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
|
|
|
|
{
|
|
|
|
size_t n = aMallocSizeOf(this);
|
|
|
|
n += mStyleSheetList.ShallowSizeOfExcludingThis(aMallocSizeOf);
|
2018-02-20 11:58:50 +03:00
|
|
|
for (const auto& sheet : mStyleSheetList) {
|
|
|
|
n += sheet->SizeOfIncludingThis(aMallocSizeOf);
|
|
|
|
}
|
2018-02-16 15:02:28 +03:00
|
|
|
n += mServoStyles ? Servo_AuthorStyles_SizeOfIncludingThis(
|
|
|
|
ServoAuthorStylesMallocSizeOf,
|
|
|
|
ServoAuthorStylesMallocEnclosingSizeOf,
|
|
|
|
mServoStyles.get()) : 0;
|
|
|
|
n += mStyleRuleMap ? mStyleRuleMap->SizeOfIncludingThis(aMallocSizeOf) : 0;
|
|
|
|
|
|
|
|
// Measurement of the following members may be added later if DMD finds it
|
|
|
|
// is worthwhile:
|
|
|
|
// - mLoader
|
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|