merge mozilla-central to mozilla-inbound. r=merge a=merge

This commit is contained in:
Sebastian Hengst 2017-06-16 09:52:22 +02:00
Родитель c9b55f92a9 265affc002
Коммит d70c8aa98b
423 изменённых файлов: 10301 добавлений и 6945 удалений

Просмотреть файл

@ -1,3 +1,5 @@
MOZ_AUTOMATION_BUILD_SYMBOLS=0
# Developers often build with these options for a better debugging experience.
. "$topsrcdir/browser/config/mozconfigs/linux64/debug"

Просмотреть файл

@ -1,3 +1,5 @@
MOZ_AUTOMATION_BUILD_SYMBOLS=0
# Developers often build with these options for a better debugging experience.
. "$topsrcdir/browser/config/mozconfigs/macosx64/debug"

Просмотреть файл

@ -1,3 +1,5 @@
MOZ_AUTOMATION_BUILD_SYMBOLS=0
# Developers often build with these options for a better debugging experience.
. "$topsrcdir/browser/config/mozconfigs/win32/debug"

Просмотреть файл

@ -1,3 +1,5 @@
MOZ_AUTOMATION_BUILD_SYMBOLS=0
# Developers often build with these options for a better debugging experience.
. "$topsrcdir/browser/config/mozconfigs/win64/debug"

Просмотреть файл

@ -440,54 +440,42 @@ var FormAutofillContent = {
return formDetails.map(record => record.fieldName);
},
identifyAutofillFields(doc) {
this.log.debug("identifyAutofillFields:", "" + doc.location);
identifyAutofillFields(element) {
this.log.debug("identifyAutofillFields:", "" + element.ownerDocument.location);
if (!this.savedFieldNames) {
this.log.debug("identifyAutofillFields: savedFieldNames are not known yet");
Services.cpmm.sendAsyncMessage("FormAutofill:InitStorage");
}
let forms = [];
// Collects root forms from inputs.
for (let field of FormAutofillUtils.autofillFieldSelector(doc)) {
if (!FormAutofillUtils.isFieldEligibleForAutofill(field)) {
continue;
}
// For now skip consider fields in forms we've already seen before even
// if the specific field wasn't seen before. Ideally whether the field is
// already in the handler's form details would be considered.
if (this.getFormHandler(field)) {
continue;
}
let formLike = FormLikeFactory.createFromField(field);
if (!forms.some(form => form.rootElement === formLike.rootElement)) {
forms.push(formLike);
}
if (!FormAutofillUtils.isFieldEligibleForAutofill(element)) {
this.log.debug("Not an eligible field.");
return;
}
this.log.debug("Found", forms.length, "forms");
let formHandler = this.getFormHandler(element);
if (!formHandler) {
let formLike = FormLikeFactory.createFromField(element);
formHandler = new FormAutofillHandler(formLike);
} else if (!formHandler.isFormChangedSinceLastCollection) {
this.log.debug("No control is removed or inserted since last collection.");
return;
}
// Collects the fields that can be autofilled from each form and marks them
// as autofill fields if the amount is above the threshold.
forms.forEach(form => {
let formHandler = new FormAutofillHandler(form);
formHandler.collectFormFields();
if (formHandler.fieldDetails.length < AUTOFILL_FIELDS_THRESHOLD) {
this.log.debug("Ignoring form since it has only", formHandler.fieldDetails.length,
"field(s)");
return;
}
formHandler.collectFormFields();
this._formsDetails.set(form.rootElement, formHandler);
this.log.debug("Adding form handler to _formsDetails:", formHandler);
formHandler.fieldDetails.forEach(detail =>
this._markAsAutofillField(detail.elementWeakRef.get())
);
});
this._formsDetails.set(formHandler.form.rootElement, formHandler);
this.log.debug("Adding form handler to _formsDetails:", formHandler);
if (formHandler.fieldDetails.length < AUTOFILL_FIELDS_THRESHOLD) {
this.log.debug("Ignoring form since it has only", formHandler.fieldDetails.length,
"field(s)");
return;
}
formHandler.fieldDetails.forEach(detail =>
this._markAsAutofillField(detail.elementWeakRef.get())
);
},
_markAsAutofillField(field) {

Просмотреть файл

@ -39,6 +39,8 @@ FormAutofillHandler.prototype = {
*/
form: null,
_formFieldCount: 0,
/**
* Array of collected data about relevant form fields. Each item is an object
* storing the identifying details of the field and a reference to the
@ -76,10 +78,19 @@ FormAutofillHandler.prototype = {
PREVIEW: "-moz-autofill-preview",
},
get isFormChangedSinceLastCollection() {
// When the number of form controls is the same with last collection, it
// can be recognized as there is no element changed. However, we should
// improve the function to detect the element changes. e.g. a tel field
// is changed from type="hidden" to type="tel".
return this._formFieldCount != this.form.elements.length;
},
/**
* Set fieldDetails from the form about fields that can be autofilled.
*/
collectFormFields() {
this._formFieldCount = this.form.elements.length;
let fieldDetails = FormAutofillHeuristics.getFormInfo(this.form);
this.fieldDetails = fieldDetails ? fieldDetails : [];
log.debug("Collected details on", this.fieldDetails.length, "fields");
@ -174,10 +185,11 @@ FormAutofillHandler.prototype = {
hasFilledFields |= (fieldDetail.state == "AUTO_FILLED");
}
// Unregister listeners once no field is in AUTO_FILLED state.
// Unregister listeners and clear guid once no field is in AUTO_FILLED state.
if (!hasFilledFields) {
this.form.rootElement.removeEventListener("input", onChangeHandler);
this.form.rootElement.removeEventListener("reset", onChangeHandler);
this.filledProfileGUID = null;
}
};

Просмотреть файл

@ -48,7 +48,7 @@ var FormAutofillFrameScript = {
}
let doIdentifyAutofillFields =
() => setTimeout(() => FormAutofillContent.identifyAutofillFields(doc));
() => setTimeout(() => FormAutofillContent.identifyAutofillFields(element));
if (doc.readyState === "loading") {
doc.addEventListener("DOMContentLoaded", doIdentifyAutofillFields, {once: true});

Просмотреть файл

@ -164,6 +164,18 @@ add_task(async function check_fallback_after_form_autofill() {
checkMenuEntries(["1-234-567-890"]);
});
// Resume form autofill once all the autofilled fileds are changed.
add_task(async function check_form_autofill_resume() {
document.querySelector("#tel").blur();
document.querySelector("#form1").reset();
await setInput("#tel", "");
doKey("down");
await expectPopup();
checkMenuEntries(MOCK_STORAGE.map(address =>
JSON.stringify({primary: address.tel, secondary: address["street-address"]})
));
});
registerPopupShownListener(popupShownListener);
</script>

Просмотреть файл

@ -84,10 +84,10 @@ TESTCASES.forEach(testcase => {
let doc = MockDocument.createTestDocument(
"http://localhost:8080/test/", testcase.document);
FormAutofillContent.identifyAutofillFields(doc);
for (let i in testcase.targetInput) {
let input = doc.getElementById(testcase.targetInput[i]);
FormAutofillContent.identifyAutofillFields(input);
// Put the input element reference to `element` to make sure the result of
// `getInputDetails` contains the same input element.

Просмотреть файл

@ -17,6 +17,7 @@ const TESTCASES = [
<input id="without-autocomplete-1">
<input id="without-autocomplete-2">
</form>`,
targetElementId: "given-name",
expectedResult: [
"given-name",
"additional-name",
@ -36,6 +37,7 @@ const TESTCASES = [
<input id="without-autocomplete-1">
<input id="without-autocomplete-2">
</form>`,
targetElementId: "street-addr",
expectedResult: [],
},
{
@ -47,6 +49,7 @@ const TESTCASES = [
<input id="tel" autocomplete="tel">
<input id="without-autocomplete-1">
<input id="without-autocomplete-2">`,
targetElementId: "street-addr",
expectedResult: [
"street-addr",
"city",
@ -70,7 +73,8 @@ TESTCASES.forEach(testcase => {
let doc = MockDocument.createTestDocument(
"http://localhost:8080/test/", testcase.document);
FormAutofillContent.identifyAutofillFields(doc);
let element = doc.getElementById(testcase.targetElementId);
FormAutofillContent.identifyAutofillFields(element);
Assert.deepEqual(markedFieldId, testcase.expectedResult,
"Check the fields were marked correctly.");

Просмотреть файл

@ -11,6 +11,7 @@ const MOCK_DOC = MockDocument.createTestDocument("http://localhost:8080/test/",
<input id="tel" autocomplete="tel">
<input id="submit" type="submit">
</form>`);
const TARGET_ELEMENT_ID = "street-addr";
const TESTCASES = [
{
@ -110,7 +111,8 @@ TESTCASES.forEach(testcase => {
}
sinon.stub(FormAutofillContent, "_onFormSubmit");
FormAutofillContent.identifyAutofillFields(MOCK_DOC);
let element = MOCK_DOC.getElementById(TARGET_ELEMENT_ID);
FormAutofillContent.identifyAutofillFields(element);
FormAutofillContent.notify(form);
do_check_eq(FormAutofillContent._onFormSubmit.called,

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 65 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 71 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 10 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 8.1 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 7.5 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 5.6 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 6.6 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 5.8 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 5.8 KiB

Просмотреть файл

@ -9,6 +9,12 @@
document.getElementById("onboarding-overlay-dialog")
.addEventListener("click", evt => {
switch (evt.target.id) {
case "onboarding-tour-addons-button":
Mozilla.UITour.showHighlight("addons");
break;
case "onboarding-tour-customize-button":
Mozilla.UITour.showHighlight("customize");
break;
case "onboarding-tour-private-browsing-button":
Mozilla.UITour.showHighlight("privateWindow");
break;

Просмотреть файл

@ -225,3 +225,30 @@
#onboarding-tour-private-browsing:hover {
background-image: url("img/icons_private-colored.svg");
}
#onboarding-tour-addons {
background-image: url("img/icons_addons.svg");
}
#onboarding-tour-addons.onboarding-active,
#onboarding-tour-addons:hover {
background-image: url("img/icons_addons-colored.svg");
}
#onboarding-tour-customize {
background-image: url("img/icons_customize.svg");
}
#onboarding-tour-customize.onboarding-active,
#onboarding-tour-customize:hover {
background-image: url("img/icons_customize-colored.svg");
}
#onboarding-tour-default-browser {
background-image: url("img/icons_default.svg");
}
#onboarding-tour-default-browser.onboarding-active,
#onboarding-tour-default-browser:hover {
background-image: url("img/icons_default-colored.svg");
}

Просмотреть файл

@ -33,8 +33,6 @@ const BRAND_SHORT_NAME = Services.strings
* // Add no-button css class in the div if this tour does not need a button.
* // The overlay layout will responsively position and distribute space for these 3 sections based on viewport size
* getPage() {},
* isCompleted() {},
* setCompleted() {},
* },
**/
var onboardingTours = [
@ -57,13 +55,45 @@ var onboardingTours = [
`;
return div;
},
isCompleted() {
// TODO: determine completion by looking up preferences.
return false;
},
{
id: "onboarding-tour-addons",
tourNameId: "onboarding.tour-addons",
getPage(win) {
let div = win.document.createElement("div");
div.innerHTML = `
<section class="onboarding-tour-description">
<h1 data-l10n-id="onboarding.tour-addons.title"></h1>
<p data-l10n-id="onboarding.tour-addons.description"></p>
</section>
<section class="onboarding-tour-content">
<img src="resource://onboarding/img/figure_addons.svg" />
</section>
<aside class="onboarding-tour-button">
<button id="onboarding-tour-addons-button" data-l10n-id="onboarding.tour-addons.button"></button>
</aside>
`;
return div;
},
setCompleted() {
// TODO: set completion to preferences.
return true;
},
{
id: "onboarding-tour-customize",
tourNameId: "onboarding.tour-customize",
getPage(win) {
let div = win.document.createElement("div");
div.innerHTML = `
<section class="onboarding-tour-description">
<h1 data-l10n-id="onboarding.tour-customize.title"></h1>
<p data-l10n-id="onboarding.tour-customize.description"></p>
</section>
<section class="onboarding-tour-content">
<img src="resource://onboarding/img/figure_customize.svg" />
</section>
<aside class="onboarding-tour-button">
<button id="onboarding-tour-customize-button" data-l10n-id="onboarding.tour-customize.button"></button>
</aside>
`;
return div;
},
},
{
@ -85,13 +115,22 @@ var onboardingTours = [
`;
return div;
},
isCompleted() {
// TODO: determine completion by looking up preferences.
return false;
},
setCompleted() {
// TODO: set completion to preferences.
return true;
},
{
id: "onboarding-tour-default-browser",
tourNameId: "onboarding.tour-default-browser",
getPage(win) {
let div = win.document.createElement("div");
div.innerHTML = `
<section class="onboarding-tour-description">
<h1 data-l10n-id="onboarding.tour-default-browser.title"></h1>
<p data-l10n-id="onboarding.tour-default-browser.description"></p>
</section>
<section class="onboarding-tour-content">
<img src="resource://onboarding/img/figure_default.svg" />
</section>
`;
return div;
},
},
];

Просмотреть файл

@ -1,8 +1,7 @@
# 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/.
# LOCALIZATION NOTE(onboarding.overlay-title): This string will be used in the
# overlay title. %S is brandShortName.
# LOCALIZATION NOTE(onboarding.tour-title): This string will be used in the overlay title. %S is brandShortName
onboarding.overlay-title=Getting started with %S
onboarding.tour-search=One-Click Search
onboarding.tour-search.title=Find the needle or the haystack.
@ -17,8 +16,30 @@ onboarding.tour-search.button=Open One-Click Search
onboarding.tour-private-browsing=Private Browsing
onboarding.tour-private-browsing.title=A little privacy goes a long way.
# LOCALIZATION NOTE(onboarding.tour-private-browsing.description): %S is
# brandShortName.
# LOCALIZATION NOTE(onboarding.tour-private-browsing.description): %S is brandShortName.
onboarding.tour-private-browsing.description=Browse the internet without saving your searches or the sites you visited. When your session ends, the cookies disappear from %S like they were never there.
onboarding.tour-private-browsing.button=Show Private Browsing in Menu
onboarding.hidden-checkbox-label=Hide the tour
onboarding.tour-addons=Add-ons
onboarding.tour-addons.title=Add more functionality.
# LOCALIZATION NOTE(onboarding.tour-addons.description): This string will be used in the add-on tour description. %1$S is brandShortName
onboarding.tour-addons.description=Add-ons expand %1$Ss built-in features, so %1$S works the way you do. Compare prices, check the weather or express your personality with a custom theme.
onboarding.tour-addons.button=Show Add-ons in Menu
onboarding.tour-customize=Customize
onboarding.tour-customize.title=Do things your way.
# LOCALIZATION NOTE(onboarding.tour-customize.description): This string will be used in the customize tour description. %S is brandShortName
onboarding.tour-customize.description=Drag, drop, and reorder %Ss toolbar and menu to fit your needs. You can even select a compact theme to give websites more room.
onboarding.tour-customize.button=Show Customize in Menu
onboarding.tour-default-browser=Default Browser
onboarding.tour-default-browser.title=Were there for you.
# LOCALIZATION NOTE(onboarding.tour-default-browser.description): This string will be used in the default browser tour description. %1$S is brandShortName
onboarding.tour-default-browser.description=Love %1$S? Set it as your default browser. Then when you open a link from another application, %1$S has you covered.
# LOCALIZATION NOTE(onboarding.tour-default-browser.button): Label for a button to open the OS default browser settings where it's not possible to set the default browser directly. (OSX, Linux, Windows 8 and higher)
onboarding.tour-default-browser.button=Open Default Browser Settings
# LOCALIZATION NOTE(onboarding.tour-default-browser.win7.button): Label for a button to directly set the default browser (Windows 7). %S is brandShortName
onboarding.tour-default-browser.win7.button=Make %S Your Default Browser

Просмотреть файл

@ -873,6 +873,20 @@ host_cxx_compiler = compiler('C++', host, c_compiler=host_c_compiler,
non_msvc_compiler = depends(c_compiler)(lambda info: info.type != 'msvc')
building_with_gcc = depends(c_compiler)(lambda info: info.type == 'gcc')
@depends(c_compiler)
def msvs_version(info):
# clang-cl emulates the same version scheme as cl. And MSVS_VERSION needs to
# be set for GYP on Windows.
if info.type in ('clang-cl', 'msvc'):
if info.version >= '19.10':
return '2017'
elif info.version >= '19.00':
return '2015'
return ''
set_config('MSVS_VERSION', msvs_version)
include('compile-checks.configure')
@depends(have_64_bit,

Просмотреть файл

@ -6,7 +6,7 @@
#include "AnimValuesStyleRule.h"
#include "nsRuleData.h"
#include "nsStyleContext.h"
#include "mozilla/GeckoStyleContext.h"
namespace mozilla {
@ -15,7 +15,7 @@ NS_IMPL_ISUPPORTS(AnimValuesStyleRule, nsIStyleRule)
void
AnimValuesStyleRule::MapRuleInfoInto(nsRuleData* aRuleData)
{
nsStyleContext *contextParent = aRuleData->mStyleContext->GetParent();
GeckoStyleContext *contextParent = aRuleData->mStyleContext->GetParent();
if (contextParent && contextParent->HasPseudoElementData()) {
// Don't apply transitions or animations to things inside of
// pseudo-elements.

Просмотреть файл

@ -15,6 +15,7 @@
#include "mozilla/AnimationUtils.h"
#include "mozilla/AutoRestore.h"
#include "mozilla/EffectSet.h"
#include "mozilla/GeckoStyleContext.h"
#include "mozilla/LayerAnimationInfo.h"
#include "mozilla/RestyleManager.h"
#include "mozilla/RestyleManagerInlines.h"
@ -33,6 +34,7 @@
#include "nsLayoutUtils.h"
#include "nsRuleNode.h" // For nsRuleNode::ComputePropertiesOverridingAnimation
#include "nsRuleProcessorData.h" // For ElementRuleProcessorData etc.
#include "nsStyleContextInlines.h"
#include "nsTArray.h"
#include <bitset>
#include <initializer_list>
@ -168,7 +170,7 @@ FindAnimationsForCompositor(const nsIFrame* aFrame,
EffectCompositor::GetAnimationElementAndPseudoForFrame(aFrame);
if (pseudoElement) {
StyleBackendType backend =
aFrame->StyleContext()->StyleSource().IsServoComputedValues()
aFrame->StyleContext()->IsServo()
? StyleBackendType::Servo
: StyleBackendType::Gecko;
EffectCompositor::MaybeUpdateCascadeResults(backend,
@ -801,7 +803,7 @@ EffectCompositor::GetOverriddenProperties(StyleBackendType aBackendType,
break;
case StyleBackendType::Gecko:
nsRuleNode::ComputePropertiesOverridingAnimation(propertiesToTrack,
aStyleContext,
aStyleContext->AsGecko(),
result);
break;

Просмотреть файл

@ -15,6 +15,7 @@
#include "mozilla/AnimationUtils.h"
#include "mozilla/AutoRestore.h"
#include "mozilla/EffectSet.h"
#include "mozilla/GeckoStyleContext.h"
#include "mozilla/FloatingPoint.h" // For IsFinite
#include "mozilla/LookAndFeel.h" // For LookAndFeel::GetInt
#include "mozilla/KeyframeUtils.h"
@ -28,6 +29,7 @@
#include "nsCSSPseudoElements.h" // For CSSPseudoElementType
#include "nsIPresShell.h"
#include "nsIScriptError.h"
#include "nsStyleContextInlines.h"
namespace mozilla {
@ -300,7 +302,7 @@ KeyframeEffectReadOnly::UpdateProperties(nsStyleContext* aStyleContext)
}
const ServoComputedValues* currentStyle =
aStyleContext->StyleSource().AsServoComputedValues();
aStyleContext->ComputedValues();
DoUpdateProperties(currentStyle);
}
@ -1643,7 +1645,7 @@ CreateStyleContextForAnimationValue(nsCSSPropertyID aProperty,
// We need to call StyleData to generate cached data for the style context.
// Otherwise CalcStyleDifference returns no meaningful result.
styleContext->StyleData(nsCSSProps::kSIDTable[aProperty]);
styleContext->AsGecko()->StyleData(nsCSSProps::kSIDTable[aProperty]);
return styleContext.forget();
}

Просмотреть файл

@ -6051,32 +6051,53 @@ nsDocument::IsWebComponentsEnabled(JSContext* aCx, JSObject* aObject)
{
JS::Rooted<JSObject*> obj(aCx, aObject);
if (nsContentUtils::IsWebComponentsEnabled()) {
return true;
}
// Check for the webcomponents permission. See Bug 1181555.
JSAutoCompartment ac(aCx, obj);
JS::Rooted<JSObject*> global(aCx, JS_GetGlobalForObject(aCx, obj));
nsCOMPtr<nsPIDOMWindowInner> window =
do_QueryInterface(nsJSUtils::GetStaticScriptGlobal(global));
return IsWebComponentsEnabled(window);
bool enabled =
nsContentUtils::IsWebComponentsEnabled() ||
// Check for the webcomponents permission. See Bug 1181555.
IsWebComponentsEnabled(window);
if (!enabled) {
return false;
}
nsIDocument* doc = window ? window->GetExtantDoc() : nullptr;
if (doc && doc->IsStyledByServo()) {
NS_WARNING("stylo: Web Components not supported yet");
return false;
}
return true;
}
bool
nsDocument::IsWebComponentsEnabled(dom::NodeInfo* aNodeInfo)
{
if (nsContentUtils::IsWebComponentsEnabled()) {
return true;
nsIDocument* doc = aNodeInfo->GetDocument();
bool enabled = nsContentUtils::IsWebComponentsEnabled();
if (!enabled) {
// Use GetScopeObject() here so that data documents work the same way as the
// main document they're associated with.
nsCOMPtr<nsPIDOMWindowInner> window =
do_QueryInterface(doc->GetScopeObject());
enabled = IsWebComponentsEnabled(window);
}
nsIDocument* doc = aNodeInfo->GetDocument();
// Use GetScopeObject() here so that data documents work the same way as the
// main document they're associated with.
nsCOMPtr<nsPIDOMWindowInner> window =
do_QueryInterface(doc->GetScopeObject());
return IsWebComponentsEnabled(window);
if (!enabled) {
return false;
}
if (doc->IsStyledByServo()) {
NS_WARNING("stylo: Web Components not supported yet");
return false;
}
return true;
}
bool

Просмотреть файл

@ -1395,6 +1395,9 @@ private:
void UpdatePossiblyStaleDocumentState();
static bool CustomElementConstructor(JSContext* aCx, unsigned aArgc, JS::Value* aVp);
// Check whether web components are enabled for the given window.
static bool IsWebComponentsEnabled(nsPIDOMWindowInner* aWindow);
public:
virtual already_AddRefed<mozilla::dom::CustomElementRegistry>
GetCustomElementRegistry() override;
@ -1404,8 +1407,6 @@ public:
// Check whether web components are enabled for the global of the document
// this nodeinfo comes from.
static bool IsWebComponentsEnabled(mozilla::dom::NodeInfo* aNodeInfo);
// Check whether web components are enabled for the given window.
static bool IsWebComponentsEnabled(nsPIDOMWindowInner* aWindow);
RefPtr<mozilla::EventListenerManager> mListenerManager;
RefPtr<mozilla::dom::StyleSheetList> mDOMStyleSheets;

Просмотреть файл

@ -33,7 +33,7 @@ CloseFD(PRFileDesc* aFD)
void
FileBlockCache::SetCacheFile(PRFileDesc* aFD)
{
LOG("SetFD(aFD=%p) mIsOpen=%d", aFD, mIsOpen);
LOG("SetFD(aFD=%p) mThread=%p", aFD, mThread.get());
if (!aFD) {
// Failed to get a temporary file. Shutdown.
@ -46,13 +46,17 @@ FileBlockCache::SetCacheFile(PRFileDesc* aFD)
}
{
MutexAutoLock lock(mDataMutex);
if (mIsOpen) {
if (mThread) {
// Still open, complete the initialization.
mInitialized = true;
if (mIsWriteScheduled) {
// A write was scheduled while waiting for FD. We need to run/dispatch a
// task to service the request.
mThread->Dispatch(this, NS_DISPATCH_NORMAL);
nsCOMPtr<nsIRunnable> event = mozilla::NewRunnableMethod(
"FileBlockCache::SetCacheFile -> PerformBlockIOs",
this,
&FileBlockCache::PerformBlockIOs);
mThread->Dispatch(event.forget(), NS_DISPATCH_NORMAL);
}
return;
}
@ -69,9 +73,18 @@ FileBlockCache::SetCacheFile(PRFileDesc* aFD)
nsresult
FileBlockCache::Init()
{
MutexAutoLock mon(mDataMutex);
if (mThread) {
LOG("Init() again");
// Just discard pending changes, assume MediaCache won't read from
// blocks it hasn't written to.
mChangeIndexList.clear();
mBlockChanges.Clear();
return NS_OK;
}
LOG("Init()");
MutexAutoLock mon(mDataMutex);
nsresult rv = NS_NewNamedThread("FileBlockCache",
getter_AddRefs(mThread),
nullptr,
@ -79,7 +92,6 @@ FileBlockCache::Init()
if (NS_FAILED(rv)) {
return rv;
}
mIsOpen = true;
if (XRE_IsParentProcess()) {
RefPtr<FileBlockCache> self = this;
@ -107,32 +119,28 @@ FileBlockCache::Init()
}
FileBlockCache::FileBlockCache()
: mFileMutex("MediaCache.Writer.IO.Mutex"),
mFD(nullptr),
mFDCurrentPos(0),
mDataMutex("MediaCache.Writer.Data.Mutex"),
mIsWriteScheduled(false),
mIsReading(false),
mIsOpen(false)
: mFileMutex("MediaCache.Writer.IO.Mutex")
, mFD(nullptr)
, mFDCurrentPos(0)
, mDataMutex("MediaCache.Writer.Data.Mutex")
, mIsWriteScheduled(false)
, mIsReading(false)
{
}
FileBlockCache::~FileBlockCache()
{
NS_ASSERTION(!mIsOpen, "Should Close() FileBlockCache before destroying");
Close();
}
void FileBlockCache::Close()
void
FileBlockCache::Close()
{
LOG("Close()");
nsCOMPtr<nsIThread> thread;
{
MutexAutoLock mon(mDataMutex);
if (!mIsOpen) {
return;
}
mIsOpen = false;
if (!mThread) {
return;
}
@ -179,8 +187,9 @@ FileBlockCache::WriteBlock(uint32_t aBlockIndex,
{
MutexAutoLock mon(mDataMutex);
if (!mIsOpen)
if (!mThread) {
return NS_ERROR_FAILURE;
}
// Check if we've already got a pending write scheduled for this block.
mBlockChanges.EnsureLengthAtLeast(aBlockIndex + 1);
@ -206,7 +215,7 @@ FileBlockCache::WriteBlock(uint32_t aBlockIndex,
void FileBlockCache::EnsureWriteScheduled()
{
mDataMutex.AssertCurrentThreadOwns();
MOZ_ASSERT(mIsOpen);
MOZ_ASSERT(mThread);
if (mIsWriteScheduled || mIsReading) {
return;
@ -217,7 +226,11 @@ void FileBlockCache::EnsureWriteScheduled()
// the write will be scheduled.
return;
}
mThread->Dispatch(this, NS_DISPATCH_NORMAL);
nsCOMPtr<nsIRunnable> event = mozilla::NewRunnableMethod(
"FileBlockCache::EnsureWriteScheduled -> PerformBlockIOs",
this,
&FileBlockCache::PerformBlockIOs);
mThread->Dispatch(event.forget(), NS_DISPATCH_NORMAL);
}
nsresult FileBlockCache::Seek(int64_t aOffset)
@ -295,26 +308,26 @@ nsresult FileBlockCache::MoveBlockInFile(int32_t aSourceBlockIndex,
return WriteBlockToFile(aDestBlockIndex, buf);
}
nsresult FileBlockCache::Run()
void
FileBlockCache::PerformBlockIOs()
{
NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
MutexAutoLock mon(mDataMutex);
NS_ASSERTION(!mChangeIndexList.empty(), "Only dispatch when there's work to do");
NS_ASSERTION(mIsWriteScheduled, "Should report write running or scheduled.");
LOG("Run() mFD=%p mIsOpen=%d", mFD, mIsOpen);
LOG("Run() mFD=%p mThread=%p", mFD, mThread.get());
while (!mChangeIndexList.empty()) {
if (!mIsOpen) {
if (!mThread) {
// We've been closed, abort, discarding unwritten changes.
mIsWriteScheduled = false;
return NS_ERROR_FAILURE;
return;
}
if (mIsReading) {
// We're trying to read; postpone all writes. (Reader will resume writes.)
mIsWriteScheduled = false;
return NS_OK;
return;
}
// Process each pending change. We pop the index out of the change
@ -339,7 +352,7 @@ nsresult FileBlockCache::Run()
if (!mFD) {
// We may be here if mFD has been reset because we're closing, so we
// don't care anymore about writes.
return NS_OK;
return;
}
if (change->IsWrite()) {
WriteBlockToFile(blockIndex, change->mData.get());
@ -357,8 +370,6 @@ nsresult FileBlockCache::Run()
}
mIsWriteScheduled = false;
return NS_OK;
}
nsresult FileBlockCache::Read(int64_t aOffset,
@ -368,8 +379,9 @@ nsresult FileBlockCache::Read(int64_t aOffset,
{
MutexAutoLock mon(mDataMutex);
if (!mIsOpen || (aOffset / BLOCK_SIZE) > INT32_MAX)
if (!mThread || (aOffset / BLOCK_SIZE) > INT32_MAX) {
return NS_ERROR_FAILURE;
}
mIsReading = true;
auto exitRead = MakeScopeExit([&] {
@ -437,8 +449,9 @@ nsresult FileBlockCache::MoveBlock(int32_t aSourceBlockIndex, int32_t aDestBlock
{
MutexAutoLock mon(mDataMutex);
if (!mIsOpen)
if (!mThread) {
return NS_ERROR_FAILURE;
}
mBlockChanges.EnsureLengthAtLeast(std::max(aSourceBlockIndex, aDestBlockIndex) + 1);

Просмотреть файл

@ -13,7 +13,7 @@
#include "mozilla/UniquePtr.h"
#include "mozilla/AbstractThread.h"
#include "nsTArray.h"
#include "MediaCache.h"
#include "MediaBlockCacheBase.h"
#include "nsDeque.h"
#include "nsThreadUtils.h"
#include <deque>
@ -52,29 +52,23 @@ namespace mozilla {
// changes listed in mBlockChanges to file. Read() checks mBlockChanges and
// determines the current data to return, reading from file or from
// mBlockChanges as necessary.
class FileBlockCache : public Runnable {
class FileBlockCache : public MediaBlockCacheBase
{
public:
enum {
BLOCK_SIZE = MediaCacheStream::BLOCK_SIZE
};
FileBlockCache();
protected:
~FileBlockCache();
virtual ~FileBlockCache();
public:
nsresult Init();
// Closes writer, shuts down thread.
void Close();
// Launch thread and open temporary file.
// If re-initializing, just discard pending writes if any.
nsresult Init() override;
// Can be called on any thread. This defers to a non-main thread.
nsresult WriteBlock(uint32_t aBlockIndex,
Span<const uint8_t> aData1, Span<const uint8_t> aData2);
// Performs block writes and block moves on its own thread.
NS_IMETHOD Run() override;
Span<const uint8_t> aData1,
Span<const uint8_t> aData2) override;
// Synchronously reads data from file. May read from file or memory
// depending on whether written blocks have been flushed to file yet.
@ -82,11 +76,12 @@ public:
nsresult Read(int64_t aOffset,
uint8_t* aData,
int32_t aLength,
int32_t* aBytes);
int32_t* aBytes) override;
// Moves a block asynchronously. Can be called on any thread.
// This defers file I/O to a non-main thread.
nsresult MoveBlock(int32_t aSourceBlockIndex, int32_t aDestBlockIndex);
nsresult MoveBlock(int32_t aSourceBlockIndex,
int32_t aDestBlockIndex) override;
// Represents a change yet to be made to a block in the file. The change
// is either a write (and the data to be written is stored in this struct)
@ -143,6 +138,12 @@ private:
void SetCacheFile(PRFileDesc* aFD);
// Close file in thread and terminate thread.
void Close();
// Performs block writes and block moves on its own thread.
void PerformBlockIOs();
// Mutex which controls access to mFD and mFDCurrentPos. Don't hold
// mDataMutex while holding mFileMutex! mFileMutex must be owned
// while accessing any of the following data fields or methods.
@ -192,8 +193,6 @@ private:
// True when a read is happening. Pending writes may be postponed, to give
// higher priority to reads (which may be blocking the caller).
bool mIsReading;
// True if the writer is ready to enqueue writes.
bool mIsOpen;
// True if we've got a temporary file descriptor. Note: we don't use mFD
// directly as that's synchronized via mFileMutex and we need to make
// decisions about whether we can write while holding mDataMutex.

Просмотреть файл

@ -0,0 +1,76 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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/. */
#ifndef MEDIA_BLOCK_CACHE_BASE_H_
#define MEDIA_BLOCK_CACHE_BASE_H_
#include "MediaCache.h"
#include "mozilla/Span.h"
namespace mozilla {
// Manages block management for the media cache. Data comes in over the network
// via callbacks on the main thread, however we don't want to write the
// incoming data to the media cache on the main thread, as this could block
// causing UI jank.
//
// So MediaBlockCacheBase provides an abstraction for a temporary memory buffer or file accessible
// as an array of blocks, which supports a block move operation, and
// allows synchronous reading and writing from any thread, with writes being
// buffered as needed so as not to block.
//
// Writes and cache block moves (which require reading) may be deferred to
// their own non-main thread. This object also ensures that data which has
// been scheduled to be written, but hasn't actually *been* written, is read
// as if it had, i.e. pending writes are cached in readable memory until
// they're flushed to file.
//
// To improve efficiency, writes can only be done at block granularity,
// whereas reads can be done with byte granularity.
//
// Note it's also recommended not to read from the media cache from the main
// thread to prevent jank.
class MediaBlockCacheBase
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaBlockCacheBase)
static_assert(
MediaCacheStream::BLOCK_SIZE <
static_cast<decltype(MediaCacheStream::BLOCK_SIZE)>(INT32_MAX),
"MediaCacheStream::BLOCK_SIZE should fit in 31 bits");
static const int32_t BLOCK_SIZE = MediaCacheStream::BLOCK_SIZE;
protected:
virtual ~MediaBlockCacheBase() {}
public:
// Initialize this cache.
// If called again, re-initialize cache with minimal chance of failure.
virtual nsresult Init() = 0;
// Can be called on any thread. This defers to a non-main thread.
virtual nsresult WriteBlock(uint32_t aBlockIndex,
Span<const uint8_t> aData1,
Span<const uint8_t> aData2) = 0;
// Synchronously reads data from file. May read from file or memory
// depending on whether written blocks have been flushed to file yet.
// Not recommended to be called from the main thread, as can cause jank.
virtual nsresult Read(int64_t aOffset,
uint8_t* aData,
int32_t aLength,
int32_t* aBytes) = 0;
// Moves a block asynchronously. Can be called on any thread.
// This defers file I/O to a non-main thread.
virtual nsresult MoveBlock(int32_t aSourceBlockIndex,
int32_t aDestBlockIndex) = 0;
};
} // End namespace mozilla.
#endif /* MEDIA_BLOCK_CACHE_BASE_H_ */

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -198,15 +198,16 @@ public:
MediaCacheStream(ChannelMediaResource* aClient, bool aIsPrivateBrowsing);
~MediaCacheStream();
// Set up this stream with the cache. Can fail on OOM. One
// of InitAsClone or Init must be called before any other method on
// this class. Does nothing if already initialized.
nsresult Init();
// Set up this stream with the cache. Can fail on OOM.
// aContentLength is the content length if known, otherwise -1.
// Exactly one of InitAsClone or Init must be called before any other method
// on this class. Does nothing if already initialized.
nsresult Init(int64_t aContentLength);
// Set up this stream with the cache, assuming it's for the same data
// as the aOriginal stream. Can fail on OOM. Exactly one
// of InitAsClone or Init must be called before any other method on
// this class. Does nothing if already initialized.
// as the aOriginal stream. Can fail on OOM.
// Exactly one of InitAsClone or Init must be called before any other method
// on this class. Does nothing if already initialized.
nsresult InitAsClone(MediaCacheStream* aOriginal);
// These are called on the main thread.
@ -438,11 +439,12 @@ private:
// Update mPrincipal given that data has been received from aPrincipal
bool UpdatePrincipal(nsIPrincipal* aPrincipal);
// Instance of MediaCache to use with this MediaCacheStream.
RefPtr<MediaCache> mMediaCache;
// These fields are main-thread-only.
ChannelMediaResource* mClient;
nsCOMPtr<nsIPrincipal> mPrincipal;
// Set to true when Init or InitAsClone has been called
bool mInitialized;
// Set to true when MediaCache::Update() has finished while this stream
// was present.
bool mHasHadUpdate;

Просмотреть файл

@ -87,6 +87,10 @@ private:
// This is where DECL_MEDIA_PREF for each of the preferences should go.
// Cache sizes.
DECL_MEDIA_PREF("media.memory_cache_max_size", MediaMemoryCacheMaxSize, uint32_t, 8192);
DECL_MEDIA_PREF("media.memory_caches_combined_limit_kb", MediaMemoryCachesCombinedLimitKb, uint32_t, 524288);
DECL_MEDIA_PREF("media.memory_caches_combined_limit_pc_sysmem",
MediaMemoryCachesCombinedLimitPcSysmem, uint32_t, 5);
DECL_MEDIA_PREF("media.cache.resource-index", MediaResourceIndexCache, uint32_t, 8192);
// AudioSink

Просмотреть файл

@ -532,7 +532,17 @@ nsresult ChannelMediaResource::Open(nsIStreamListener **aStreamListener)
{
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
nsresult rv = mCacheStream.Init();
int64_t cl = -1;
if (mChannel) {
nsCOMPtr<nsIHttpChannel> hc = do_QueryInterface(mChannel);
if (hc) {
if (NS_FAILED(hc->GetContentLength(&cl))) {
cl = -1;
}
}
}
nsresult rv = mCacheStream.Init(cl);
if (NS_FAILED(rv))
return rv;
NS_ASSERTION(mOffset == 0, "Who set mOffset already?");

Просмотреть файл

@ -0,0 +1,262 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "MemoryBlockCache.h"
#include "MediaPrefs.h"
#include "mozilla/Atomics.h"
#include "mozilla/Logging.h"
#include "prsystem.h"
namespace mozilla {
#undef LOG
LazyLogModule gMemoryBlockCacheLog("MemoryBlockCache");
#define LOG(x, ...) \
MOZ_LOG(gMemoryBlockCacheLog, LogLevel::Debug, ("%p " x, this, ##__VA_ARGS__))
// Combined sizes of all MemoryBlockCache buffers.
// Initialized to 0 by non-local static initialization.
// Increases when a buffer grows (during initialization or unexpected OOB
// writes), decreases when a MemoryBlockCache (with its buffer) is destroyed.
static Atomic<size_t> mCombinedSizes;
enum MemoryBlockCacheTelemetryErrors
{
// Don't change order/numbers! Add new values at the end and update
// MEMORYBLOCKCACHE_ERRORS description in Histograms.json.
InitUnderuse = 0,
InitAllocation = 1,
ReadOverrun = 2,
WriteBlockOverflow = 3,
WriteBlockCannotGrow = 4,
MoveBlockSourceOverrun = 5,
MoveBlockDestOverflow = 6,
MoveBlockCannotGrow = 7,
};
MemoryBlockCache::MemoryBlockCache(int64_t aContentLength)
// Buffer whole blocks.
: mInitialContentLength((aContentLength >= 0) ? size_t(aContentLength) : 0)
, mMutex("MemoryBlockCache")
, mHasGrown(false)
{
if (aContentLength <= 0) {
LOG("@%p MemoryBlockCache() "
"MEMORYBLOCKCACHE_ERRORS='InitUnderuse'",
this);
Telemetry::Accumulate(Telemetry::HistogramID::MEMORYBLOCKCACHE_ERRORS,
InitUnderuse);
}
}
MemoryBlockCache::~MemoryBlockCache()
{
size_t sizes = static_cast<size_t>(mCombinedSizes -= mBuffer.Length());
LOG("~MemoryBlockCache() - destroying buffer of size %zu; combined sizes now "
"%zu",
mBuffer.Length(),
sizes);
}
bool
MemoryBlockCache::EnsureBufferCanContain(size_t aContentLength)
{
mMutex.AssertCurrentThreadOwns();
if (aContentLength == 0) {
return true;
}
const size_t initialLength = mBuffer.Length();
const size_t desiredLength =
((aContentLength - 1) / BLOCK_SIZE + 1) * BLOCK_SIZE;
if (initialLength >= desiredLength) {
// Already large enough.
return true;
}
// Need larger buffer. If we are allowed more memory, attempt to re-allocate.
const size_t extra = desiredLength - initialLength;
// Note: There is a small race between testing `atomic + extra > limit` and
// committing to it with `atomic += extra` below; but this is acceptable, as
// in the worst case it may allow a small number of buffers to go past the
// limit.
// The alternative would have been to reserve the space first with
// `atomic += extra` and then undo it with `atomic -= extra` in case of
// failure; but this would have meant potentially preventing other (small but
// successful) allocations.
static const size_t sysmem =
std::max<size_t>(PR_GetPhysicalMemorySize(), 32 * 1024 * 1024);
const size_t limit = std::min(
size_t(MediaPrefs::MediaMemoryCachesCombinedLimitKb()) * 1024,
sysmem * MediaPrefs::MediaMemoryCachesCombinedLimitPcSysmem() / 100);
const size_t currentSizes = static_cast<size_t>(mCombinedSizes);
if (currentSizes + extra > limit) {
LOG("EnsureBufferCanContain(%zu) - buffer size %zu, wanted + %zu = %zu;"
" combined sizes %zu + %zu > limit %zu",
aContentLength,
initialLength,
extra,
desiredLength,
currentSizes,
extra,
limit);
return false;
}
if (!mBuffer.SetLength(desiredLength, mozilla::fallible)) {
LOG("EnsureBufferCanContain(%zu) - buffer size %zu, wanted + %zu = %zu, "
"allocation failed",
aContentLength,
initialLength,
extra,
desiredLength);
return false;
}
MOZ_ASSERT(mBuffer.Length() == desiredLength);
const size_t capacity = mBuffer.Capacity();
const size_t extraCapacity = capacity - desiredLength;
if (extraCapacity != 0) {
// Our buffer was given a larger capacity than the requested length, we may
// as well claim that extra capacity, both for our accounting, and to
// possibly bypass some future growths that would fit in this new capacity.
mBuffer.SetLength(capacity);
}
size_t newSizes =
static_cast<size_t>(mCombinedSizes += (extra + extraCapacity));
LOG("EnsureBufferCanContain(%zu) - buffer size %zu + requested %zu + bonus "
"%zu = %zu; combined "
"sizes %zu",
aContentLength,
initialLength,
extra,
extraCapacity,
capacity,
newSizes);
mHasGrown = true;
return true;
}
nsresult
MemoryBlockCache::Init()
{
MutexAutoLock lock(mMutex);
if (mBuffer.IsEmpty()) {
LOG("@%p Init()", this);
// Attempt to pre-allocate buffer for expected content length.
if (!EnsureBufferCanContain(mInitialContentLength)) {
LOG("@%p Init() MEMORYBLOCKCACHE_ERRORS='InitAllocation'", this);
Telemetry::Accumulate(Telemetry::HistogramID::MEMORYBLOCKCACHE_ERRORS,
InitAllocation);
return NS_ERROR_FAILURE;
}
} else {
LOG("@%p Init() again", this);
// Re-initialization - Just erase data.
MOZ_ASSERT(mBuffer.Length() >= mInitialContentLength);
memset(mBuffer.Elements(), 0, mBuffer.Length());
}
// Ignore initial growth.
mHasGrown = false;
return NS_OK;
}
nsresult
MemoryBlockCache::WriteBlock(uint32_t aBlockIndex,
Span<const uint8_t> aData1,
Span<const uint8_t> aData2)
{
MutexAutoLock lock(mMutex);
size_t offset = BlockIndexToOffset(aBlockIndex);
if (offset + aData1.Length() + aData2.Length() > mBuffer.Length() &&
!mHasGrown) {
LOG("@%p WriteBlock() "
"MEMORYBLOCKCACHE_ERRORS='WriteBlockOverflow'",
this);
Telemetry::Accumulate(Telemetry::HistogramID::MEMORYBLOCKCACHE_ERRORS,
WriteBlockOverflow);
}
if (!EnsureBufferCanContain(offset + aData1.Length() + aData2.Length())) {
LOG("%p WriteBlock() "
"MEMORYBLOCKCACHE_ERRORS='WriteBlockCannotGrow'",
this);
Telemetry::Accumulate(Telemetry::HistogramID::MEMORYBLOCKCACHE_ERRORS,
WriteBlockCannotGrow);
return NS_ERROR_FAILURE;
}
memcpy(mBuffer.Elements() + offset, aData1.Elements(), aData1.Length());
if (aData2.Length() > 0) {
memcpy(mBuffer.Elements() + offset + aData1.Length(),
aData2.Elements(),
aData2.Length());
}
return NS_OK;
}
nsresult
MemoryBlockCache::Read(int64_t aOffset,
uint8_t* aData,
int32_t aLength,
int32_t* aBytes)
{
MutexAutoLock lock(mMutex);
MOZ_ASSERT(aOffset >= 0);
if (aOffset + aLength > int64_t(mBuffer.Length())) {
LOG("@%p Read() MEMORYBLOCKCACHE_ERRORS='ReadOverrun'", this);
Telemetry::Accumulate(Telemetry::HistogramID::MEMORYBLOCKCACHE_ERRORS,
ReadOverrun);
return NS_ERROR_FAILURE;
}
memcpy(aData, mBuffer.Elements() + aOffset, aLength);
*aBytes = aLength;
return NS_OK;
}
nsresult
MemoryBlockCache::MoveBlock(int32_t aSourceBlockIndex, int32_t aDestBlockIndex)
{
MutexAutoLock lock(mMutex);
size_t sourceOffset = BlockIndexToOffset(aSourceBlockIndex);
size_t destOffset = BlockIndexToOffset(aDestBlockIndex);
if (sourceOffset + BLOCK_SIZE > mBuffer.Length()) {
LOG("@%p MoveBlock() "
"MEMORYBLOCKCACHE_ERRORS='MoveBlockSourceOverrun'",
this);
Telemetry::Accumulate(Telemetry::HistogramID::MEMORYBLOCKCACHE_ERRORS,
MoveBlockSourceOverrun);
return NS_ERROR_FAILURE;
}
if (destOffset + BLOCK_SIZE > mBuffer.Length() && !mHasGrown) {
LOG("@%p MoveBlock() "
"MEMORYBLOCKCACHE_ERRORS='MoveBlockDestOverflow'",
this);
Telemetry::Accumulate(Telemetry::HistogramID::MEMORYBLOCKCACHE_ERRORS,
MoveBlockDestOverflow);
}
if (!EnsureBufferCanContain(destOffset + BLOCK_SIZE)) {
LOG("@%p MoveBlock() "
"MEMORYBLOCKCACHE_ERRORS='MoveBlockCannotGrow'",
this);
Telemetry::Accumulate(Telemetry::HistogramID::MEMORYBLOCKCACHE_ERRORS,
MoveBlockCannotGrow);
return NS_ERROR_FAILURE;
}
memcpy(mBuffer.Elements() + destOffset,
mBuffer.Elements() + sourceOffset,
BLOCK_SIZE);
return NS_OK;
}
} // End namespace mozilla.
// avoid redefined macro in unified build
#undef LOG

Просмотреть файл

@ -0,0 +1,83 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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/. */
#ifndef MEMORY_BLOCK_CACHE_H_
#define MEMORY_BLOCK_CACHE_H_
#include "MediaBlockCacheBase.h"
#include "mozilla/Mutex.h"
namespace mozilla {
// Manages block management for the media cache. Data comes in over the network
// via callbacks on the main thread, however we don't want to write the
// incoming data to the media cache on the main thread, as this could block
// causing UI jank.
//
// So MediaBlockCacheBase provides an abstraction for a temporary memory buffer
// as an array of blocks, which supports a block move operation, and
// allows synchronous reading and writing from any thread.
//
// Writes and cache block moves (which require reading) may be deferred to
// their own non-main thread. This object also ensures that data which has
// been scheduled to be written, but hasn't actually *been* written, is read
// as if it had, i.e. pending writes are cached in readable memory until
// they're flushed to file.
//
// To improve efficiency, writes can only be done at block granularity,
// whereas reads can be done with byte granularity.
class MemoryBlockCache : public MediaBlockCacheBase
{
public:
explicit MemoryBlockCache(int64_t aContentLength);
protected:
virtual ~MemoryBlockCache();
public:
// Allocate initial buffer.
// If re-initializing, clear buffer.
virtual nsresult Init() override;
// Can be called on any thread.
virtual nsresult WriteBlock(uint32_t aBlockIndex,
Span<const uint8_t> aData1,
Span<const uint8_t> aData2) override;
// Synchronously reads data from buffer.
virtual nsresult Read(int64_t aOffset,
uint8_t* aData,
int32_t aLength,
int32_t* aBytes) override;
// Moves a block. Can be called on any thread.
virtual nsresult MoveBlock(int32_t aSourceBlockIndex,
int32_t aDestBlockIndex) override;
private:
static size_t BlockIndexToOffset(uint32_t aBlockIndex)
{
return static_cast<size_t>(aBlockIndex) * BLOCK_SIZE;
}
// Ensure the buffer has at least a multiple of BLOCK_SIZE that can contain
// aContentLength bytes. Buffer size can only grow.
// Returns false if allocation failed.
bool EnsureBufferCanContain(size_t aContentLength);
// Initial content length.
const size_t mInitialContentLength;
// Mutex which controls access to all members below.
Mutex mMutex;
nsTArray<uint8_t> mBuffer;
bool mHasGrown;
};
} // End namespace mozilla.
#endif /* MEMORY_BLOCK_CACHE_H_ */

Просмотреть файл

@ -135,6 +135,7 @@ EXPORTS += [
'MediaTimer.h',
'MediaTrack.h',
'MediaTrackList.h',
'MemoryBlockCache.h',
'MP3Decoder.h',
'MP3Demuxer.h',
'MP3FrameParser.h',
@ -242,6 +243,7 @@ UNIFIED_SOURCES += [
'MediaTimer.cpp',
'MediaTrack.cpp',
'MediaTrackList.cpp',
'MemoryBlockCache.cpp',
'MP3Decoder.cpp',
'MP3Demuxer.cpp',
'MP3FrameParser.cpp',

Просмотреть файл

@ -69,7 +69,7 @@ nsSMILCSSProperty::GetBaseValue() const
AnimationValue computedValue;
if (mElement->IsStyledByServo()) {
const ServoComputedValues* currentStyle =
mBaseStyleContext->StyleSource().AsServoComputedValues();
mBaseStyleContext->ComputedValues();
computedValue.mServo =
Servo_ComputedValues_ExtractAnimationValue(currentStyle, mPropID)
.Consume();

Просмотреть файл

@ -701,7 +701,7 @@ ValueFromStringHelper(nsCSSPropertyID aPropID,
// Get a suitable style context for Servo
const ServoComputedValues* currentStyle =
aStyleContext->StyleSource().AsServoComputedValues();
aStyleContext->ComputedValues();
// Compute value
aPresContext->StyleSet()->AsServo()->GetAnimationValues(servoDeclarationBlock,

Просмотреть файл

@ -31,7 +31,25 @@ ScrollingLayersHelper::ScrollingLayersHelper(WebRenderLayer* aLayer,
Layer* layer = mLayer->GetLayer();
for (uint32_t i = layer->GetScrollMetadataCount(); i > 0; i--) {
const ScrollMetadata& metadata = layer->GetScrollMetadata(i - 1);
// The scroll clip on a given metadata is affected by all async transforms
// from metadatas "above" it, but not the async transform on the metadata
// itself. Therefore we need to push this clip before we push the
// corresponding scroll layer, so that when we set an async scroll position
// on the scroll layer, the clip isn't affected by it.
if (const Maybe<LayerClip>& clip = metadata.GetScrollClip()) {
PushLayerClip(clip.ref(), aStackingContext);
}
const FrameMetrics& fm = layer->GetFrameMetrics(i - 1);
if (layer->GetIsFixedPosition() &&
layer->GetFixedPositionScrollContainerId() == fm.GetScrollId()) {
// If the layer contents are fixed for this metadata onwards, we need
// to insert the layer's local clip at this point in the clip tree,
// as a child of whatever's on the stack.
PushLayerLocalClip(aStackingContext);
}
if (!fm.IsScrollable()) {
continue;
}
@ -59,19 +77,8 @@ ScrollingLayersHelper::ScrollingLayersHelper(WebRenderLayer* aLayer,
// on that layer. That is, the clip scrolls along with the content in
// child layers. So we need to apply this after pushing all the scroll layers,
// which we do above.
if (Maybe<LayerClip> scrolledClip = layer->GetScrolledClip()) {
LayerRect clipRect = IntRectToRect(ViewAs<LayerPixel>(
scrolledClip->GetClipRect(),
PixelCastJustification::MovingDownToChildren));
Maybe<WrImageMask> mask;
if (Maybe<size_t> maskLayerIndex = scrolledClip->GetMaskLayerIndex()) {
Layer* maskLayer = layer->GetAncestorMaskLayerAt(maskLayerIndex.value());
WebRenderLayer* maskWrLayer = WebRenderLayer::ToWebRenderLayer(maskLayer);
// TODO: check this transform is correct in all cases
mask = maskWrLayer->RenderMaskLayer(aStackingContext, maskLayer->GetTransform());
}
mBuilder->PushClip(aStackingContext.ToRelativeWrRect(clipRect),
mask.ptrOr(nullptr));
if (const Maybe<LayerClip>& scrolledClip = layer->GetScrolledClip()) {
PushLayerClip(scrolledClip.ref(), aStackingContext);
}
// If the layer is marked as fixed-position, it is fixed relative to something
@ -79,18 +86,23 @@ ScrollingLayersHelper::ScrollingLayersHelper(WebRenderLayer* aLayer,
// referred to as the "scroll container"). What this really means is that we
// don't want this content to scroll with any scroll layer on the stack up to
// and including the scroll container, but we do want it to scroll with any
// ancestor scroll layers. So we do a PushClipAndScrollInfo that maintains
// ancestor scroll layers.
// Also, the local clip on the layer (defined by layer->GetClipRect() and
// layer->GetMaskLayer()) also need to be fixed relative to the scroll
// container. This is why we inserted it into the clip tree during the
// loop above when we encountered the scroll container.
// At this point we do a PushClipAndScrollInfo that maintains
// the current non-scrolling clip stack, but resets the scrolling clip stack
// to the ancestor of the scroll container.
if (layer->GetIsFixedPosition()) {
FrameMetrics::ViewID fixedFor = layer->GetFixedPositionScrollContainerId();
Maybe<FrameMetrics::ViewID> scrollsWith = mBuilder->ParentScrollIdFor(fixedFor);
Maybe<uint64_t> clipId = mBuilder->TopmostClipId();
Maybe<wr::WrClipId> clipId = mBuilder->TopmostClipId();
// Default to 0 if there is no ancestor, because 0 refers to the root scrollframe.
mBuilder->PushClipAndScrollInfo(scrollsWith.valueOr(0), clipId.ptrOr(nullptr));
} else {
PushLayerLocalClip(aStackingContext);
}
PushLayerLocalClip(aStackingContext);
}
void
@ -114,27 +126,54 @@ ScrollingLayersHelper::PushLayerLocalClip(const StackingContextHelper& aStacking
}
}
void
ScrollingLayersHelper::PushLayerClip(const LayerClip& aClip,
const StackingContextHelper& aSc)
{
LayerRect clipRect = IntRectToRect(ViewAs<LayerPixel>(aClip.GetClipRect(),
PixelCastJustification::MovingDownToChildren));
Maybe<WrImageMask> mask;
if (Maybe<size_t> maskLayerIndex = aClip.GetMaskLayerIndex()) {
Layer* maskLayer = mLayer->GetLayer()->GetAncestorMaskLayerAt(maskLayerIndex.value());
WebRenderLayer* maskWrLayer = WebRenderLayer::ToWebRenderLayer(maskLayer);
// TODO: check this transform is correct in all cases
mask = maskWrLayer->RenderMaskLayer(aSc, maskLayer->GetTransform());
}
mBuilder->PushClip(aSc.ToRelativeWrRect(clipRect), mask.ptrOr(nullptr));
}
ScrollingLayersHelper::~ScrollingLayersHelper()
{
Layer* layer = mLayer->GetLayer();
if (mPushedLayerLocalClip) {
mBuilder->PopClip();
}
if (!mLayer->WrManager()->AsyncPanZoomEnabled()) {
if (mPushedLayerLocalClip) {
mBuilder->PopClip();
}
return;
}
if (layer->GetIsFixedPosition()) {
mBuilder->PopClipAndScrollInfo();
} else if (mPushedLayerLocalClip) {
mBuilder->PopClip();
}
if (layer->GetScrolledClip()) {
mBuilder->PopClip();
}
for (int32_t i = layer->GetScrollMetadataCount(); i > 0; i--) {
const FrameMetrics& fm = layer->GetFrameMetrics(i - 1);
if (!fm.IsScrollable()) {
continue;
for (uint32_t i = 0; i < layer->GetScrollMetadataCount(); i++) {
const FrameMetrics& fm = layer->GetFrameMetrics(i);
if (fm.IsScrollable()) {
mBuilder->PopScrollLayer();
}
if (layer->GetIsFixedPosition() &&
layer->GetFixedPositionScrollContainerId() == fm.GetScrollId() &&
mPushedLayerLocalClip) {
mBuilder->PopClip();
}
const ScrollMetadata& metadata = layer->GetScrollMetadata(i);
if (metadata.GetScrollClip()) {
mBuilder->PopClip();
}
mBuilder->PopScrollLayer();
}
}

Просмотреть файл

@ -16,6 +16,7 @@ class DisplayListBuilder;
namespace layers {
struct LayerClip;
class StackingContextHelper;
class WebRenderLayer;
@ -29,6 +30,8 @@ public:
private:
void PushLayerLocalClip(const StackingContextHelper& aStackingContext);
void PushLayerClip(const LayerClip& aClip,
const StackingContextHelper& aSc);
WebRenderLayer* mLayer;
wr::DisplayListBuilder* mBuilder;

Просмотреть файл

@ -587,13 +587,13 @@ DisplayListBuilder::PushClip(const WrRect& aClipRect,
WRDL_LOG("PushClip id=%" PRIu64 " r=%s m=%p b=%s\n", clip_id,
Stringify(aClipRect).c_str(), aMask,
aMask ? Stringify(aMask->rect).c_str() : "none");
mClipIdStack.push_back(clip_id);
mClipIdStack.push_back(WrClipId { clip_id });
}
void
DisplayListBuilder::PopClip()
{
WRDL_LOG("PopClip id=%" PRIu64 "\n", mClipIdStack.back());
WRDL_LOG("PopClip id=%" PRIu64 "\n", mClipIdStack.back().id);
mClipIdStack.pop_back();
wr_dp_pop_clip(mWrState);
}
@ -627,11 +627,12 @@ DisplayListBuilder::PopScrollLayer()
void
DisplayListBuilder::PushClipAndScrollInfo(const layers::FrameMetrics::ViewID& aScrollId,
const uint64_t* aClipId)
const WrClipId* aClipId)
{
WRDL_LOG("PushClipAndScroll s=%" PRIu64 " c=%s\n", aScrollId,
aClipId ? Stringify(*aClipId).c_str() : "none");
wr_dp_push_clip_and_scroll_info(mWrState, aScrollId, aClipId);
aClipId ? Stringify(aClipId->id).c_str() : "none");
wr_dp_push_clip_and_scroll_info(mWrState, aScrollId,
aClipId ? &(aClipId->id) : nullptr);
}
void
@ -891,7 +892,7 @@ DisplayListBuilder::PushClipRegion(const WrRect& aMain,
aMask);
}
Maybe<uint64_t>
Maybe<WrClipId>
DisplayListBuilder::TopmostClipId()
{
if (mClipIdStack.empty()) {

Просмотреть файл

@ -168,7 +168,7 @@ public:
void PopScrollLayer();
void PushClipAndScrollInfo(const layers::FrameMetrics::ViewID& aScrollId,
const uint64_t* aClipId);
const WrClipId* aClipId);
void PopClipAndScrollInfo();
void PushRect(const WrRect& aBounds,
@ -292,7 +292,7 @@ public:
// Returns the clip id that was most recently pushed with PushClip and that
// has not yet been popped with PopClip. Return Nothing() if the clip stack
// is empty.
Maybe<uint64_t> TopmostClipId();
Maybe<WrClipId> TopmostClipId();
// Returns the scroll id that was pushed just before the given scroll id.
// If the given scroll id is not in the stack of active scrolled layers, or if
// it is the rootmost scroll id (and therefore has no ancestor), this function
@ -308,7 +308,7 @@ protected:
// (by PushClip and PushScrollLayer, respectively) and are still active.
// This is helpful for knowing e.g. what the ancestor scroll id of a particular
// scroll id is, and doing other "queries" of current state.
std::vector<uint64_t> mClipIdStack;
std::vector<WrClipId> mClipIdStack;
std::vector<layers::FrameMetrics::ViewID> mScrollIdStack;
friend class WebRenderAPI;

Просмотреть файл

@ -604,6 +604,14 @@ static inline WrFilterOp ToWrFilterOp(const layers::CSSFilter& filter) {
};
}
// Corresponds to an "internal" webrender clip id. That is, a
// ClipId::Clip(x,pipeline_id) maps to a WrClipId{x}. We use a struct wrapper
// instead of a typedef so that this is a distinct type from FrameMetrics::ViewID
// and the compiler will catch accidental conversions between the two.
struct WrClipId {
uint64_t id;
};
} // namespace wr
} // namespace mozilla

Просмотреть файл

@ -181,7 +181,6 @@ case "$target" in
case "$CC_VERSION" in
19*)
_CC_SUITE=14
MSVS_VERSION=2015
MSVC_C_RUNTIME_DLL=vcruntime140.dll
MSVC_CXX_RUNTIME_DLL=msvcp140.dll
@ -195,7 +194,6 @@ case "$target" in
CXXFLAGS="$CXXFLAGS -Zc:sizedDealloc-"
;;
esac
AC_SUBST(MSVS_VERSION)
AC_SUBST(MSVC_C_RUNTIME_DLL)
AC_SUBST(MSVC_CXX_RUNTIME_DLL)

Просмотреть файл

@ -2503,10 +2503,12 @@ nsXPCComponents_Utils::Import(const nsACString& registryLocation,
if (!moduleloader)
return NS_ERROR_FAILURE;
#ifdef MOZ_GECKO_PROFILER
const nsCString& flatLocation = PromiseFlatCString(registryLocation);
PROFILER_LABEL_DYNAMIC("Components.utils", "import",
js::ProfileEntry::Category::OTHER,
flatLocation.get());
#endif
return moduleloader->Import(registryLocation, targetObj, cx, optionalArgc, retval);
}

Просмотреть файл

@ -13,6 +13,7 @@
#include <algorithm> // For std::max
#include "gfxContext.h"
#include "mozilla/EffectSet.h"
#include "mozilla/GeckoStyleContext.h"
#include "mozilla/EventStates.h"
#include "mozilla/ViewportFrame.h"
#include "mozilla/css/StyleRule.h" // For nsCSSSelector
@ -23,6 +24,7 @@
#include "nsAutoPtr.h"
#include "nsStyleChangeList.h"
#include "nsRuleProcessorData.h"
#include "nsStyleContextInlines.h"
#include "nsStyleSet.h"
#include "nsStyleUtil.h"
#include "nsCSSFrameConstructor.h"
@ -1767,7 +1769,7 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint)
eRestyle_Subtree |
eRestyle_ForceDescendants));
RefPtr<nsStyleContext> oldContext = mFrame->StyleContext();
RefPtr<GeckoStyleContext> oldContext = mFrame->StyleContext()->AsGecko();
nsTArray<SwapInstruction> swaps;
@ -1916,7 +1918,7 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint)
for (SwapInstruction& swap : swaps) {
LOG_RESTYLE("swapping style structs between %p and %p",
swap.mOldContext.get(), swap.mNewContext.get());
swap.mOldContext->SwapStyleData(swap.mNewContext, swap.mStructsToSwap);
swap.mOldContext->AsGecko()->SwapStyleData(swap.mNewContext->AsGecko(), swap.mStructsToSwap);
swappedStructs |= swap.mStructsToSwap;
}
swaps.Clear();
@ -2751,7 +2753,7 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf,
} else {
LOG_RESTYLE("swapping style structs between %p and %p",
oldContext.get(), newContext.get());
oldContext->SwapStyleData(newContext, equalStructs);
oldContext->AsGecko()->SwapStyleData(newContext->AsGecko(), equalStructs);
*aSwappedStructs |= equalStructs;
}
#ifdef RESTYLE_LOGGING
@ -2759,9 +2761,9 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf,
if (structs) {
LOG_RESTYLE_INDENT();
LOG_RESTYLE("old style context now has: %s",
oldContext->GetCachedStyleDataAsString(structs).get());
oldContext->AsGecko()->GetCachedStyleDataAsString(structs).get());
LOG_RESTYLE("new style context now has: %s",
newContext->GetCachedStyleDataAsString(structs).get());
newContext->AsGecko()->GetCachedStyleDataAsString(structs).get());
}
#endif
}
@ -3443,7 +3445,7 @@ ClearCachedInheritedStyleDataOnDescendants(
for (size_t i = 0; i < aContextsToClear.Length(); i++) {
auto& entry = aContextsToClear[i];
if (!entry.mStyleContext->HasSingleReference()) {
entry.mStyleContext->ClearCachedInheritedStyleDataOnDescendants(
entry.mStyleContext->AsGecko()->ClearCachedInheritedStyleDataOnDescendants(
entry.mStructs);
}
entry.mStyleContext = nullptr;

Просмотреть файл

@ -88,7 +88,7 @@ RestyleTracker::ProcessOneRestyle(Element* aElement,
GeckoRestyleManager::StructsToLog() != 0) {
LOG_RESTYLE("style context tree before restyle:");
LOG_RESTYLE_INDENT();
primaryFrame->StyleContext()->LogStyleContextTree(
primaryFrame->StyleContext()->AsGecko()->LogStyleContextTree(
LoggingDepth(), GeckoRestyleManager::StructsToLog());
}
#endif

Просмотреть файл

@ -382,7 +382,7 @@ ServoRestyleManager::ProcessPostTraversal(Element* aElement,
// elements, though that is buggy right now even in non-stylo mode, see
// bug 1251799.
const bool recreateContext = oldStyleContext &&
oldStyleContext->StyleSource().AsServoComputedValues() != computedValues;
oldStyleContext->ComputedValues() != computedValues;
RefPtr<nsStyleContext> newContext = nullptr;
if (recreateContext) {

Просмотреть файл

@ -86,6 +86,7 @@
#include "nsAutoLayoutPhase.h"
#include "nsStyleStructInlines.h"
#include "nsPageContentFrame.h"
#include "mozilla/GeckoStyleContext.h"
#include "mozilla/RestyleManager.h"
#include "mozilla/RestyleManagerInlines.h"
#include "StickyScrollContainer.h"

Просмотреть файл

@ -13,7 +13,7 @@
#include "nsDebug.h"
#include "nsArenaMemoryStats.h"
#include "nsPrintfCString.h"
#include "nsStyleContext.h"
#include "GeckoStyleContext.h"
#include "FrameLayerBuilder.h"
#include "mozilla/ArrayUtils.h"
@ -208,7 +208,7 @@ nsPresArena::AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf,
case eArenaObjectID_nsRuleNode:
p = &aArenaStats->mRuleNodes;
break;
case eArenaObjectID_nsStyleContext:
case eArenaObjectID_GeckoStyleContext:
p = &aArenaStats->mStyleContexts;
break;
#define STYLE_STRUCT(name_, checkdata_cb_) \

Просмотреть файл

@ -47,7 +47,7 @@
PRES_ARENA_OBJECT_WITHOUT_ARENAREFPTR_SUPPORT(nsLineBox)
PRES_ARENA_OBJECT_WITHOUT_ARENAREFPTR_SUPPORT(nsRuleNode)
PRES_ARENA_OBJECT_WITH_ARENAREFPTR_SUPPORT(nsStyleContext)
PRES_ARENA_OBJECT_WITH_ARENAREFPTR_SUPPORT(GeckoStyleContext)
PRES_ARENA_OBJECT_WITHOUT_ARENAREFPTR_SUPPORT(DisplayItemData)
PRES_ARENA_OBJECT_WITHOUT_ARENAREFPTR_SUPPORT(nsInheritedStyleData)
PRES_ARENA_OBJECT_WITHOUT_ARENAREFPTR_SUPPORT(nsResetStyleData)

Просмотреть файл

@ -8,6 +8,7 @@
#include "nsRect.h"
#include "nsStyleContext.h"
#include "nsStyleContextInlines.h"
#include "nsBidiUtils.h"
// It is the caller's responsibility to operate on logical-coordinate objects

Просмотреть файл

@ -42,6 +42,7 @@
#include "nsFrameManager.h"
#include "nsLayoutUtils.h"
#include "LayoutLogging.h"
#include "mozilla/GeckoStyleContext.h"
#include "mozilla/GeckoRestyleManager.h"
#include "mozilla/RestyleManager.h"
#include "mozilla/RestyleManagerInlines.h"
@ -7197,7 +7198,7 @@ nsIFrame::ListGeneric(nsACString& aTo, const char* aPrefix, uint32_t aFlags) con
pseudoTag->ToString(atomString);
aTo += nsPrintfCString("%s", NS_LossyConvertUTF16toASCII(atomString).get());
}
if (mStyleContext->StyleSource().IsGeckoRuleNodeOrNull()) {
if (mStyleContext->IsGecko()) {
if (!mStyleContext->GetParent() ||
(GetParent() && GetParent()->StyleContext() != mStyleContext->GetParent())) {
aTo += nsPrintfCString("^%p", mStyleContext->GetParent());

Просмотреть файл

@ -41,6 +41,7 @@
#include "nsStyleStruct.h"
#include "Visibility.h"
#include "nsChangeHint.h"
#include "nsStyleContextInlines.h"
#ifdef ACCESSIBILITY
#include "mozilla/a11y/AccTypes.h"

Просмотреть файл

@ -243,14 +243,13 @@ inDOMUtils::GetCSSStyleRules(nsIDOMElement *aElement,
return NS_OK;
}
NonOwningStyleContextSource source = styleContext->StyleSource();
if (source.IsNull()) {
return NS_OK;
}
nsCOMPtr<nsIMutableArray> rules = nsArray::Create();
if (source.IsGeckoRuleNodeOrNull()) {
nsRuleNode* ruleNode = source.AsGeckoRuleNode();
if (auto gecko = styleContext->GetAsGecko()) {
nsRuleNode* ruleNode = gecko->RuleNode();
if (!ruleNode) {
return NS_OK;
}
AutoTArray<nsRuleNode*, 16> ruleNodes;
while (!ruleNode->IsRoot()) {

Просмотреть файл

@ -7,15 +7,17 @@
<script>
function insertShadowSVG() {
var x = document.getElementById("x");
x.createShadowRoot();
x.shadowRoot.innerHTML =
'<svg width="50px" height="10px"> \
<switch> \
<foreignObject width="50px" height="50px"> \
<div style="width: 100px; height: 10px; background: red;"></div> \
</foreignObject> \
</switch> \
</svg>';
if (x.createShadowRoot) {
x.createShadowRoot();
x.shadowRoot.innerHTML =
'<svg width="50px" height="10px"> \
<switch> \
<foreignObject width="50px" height="50px"> \
<div style="width: 100px; height: 10px; background: red;"></div> \
</foreignObject> \
</switch> \
</svg>';
}
document.documentElement.removeAttribute("class");
}
window.addEventListener("MozReftestInvalidate", insertShadowSVG);

Просмотреть файл

@ -1856,7 +1856,7 @@ test-pref(layout.css.grid.enabled,true) == 1053035-1-grid.html 1053035-1-ref.htm
== 1062108-1.html 1062108-1-ref.html
== 1062792-1.html 1062792-1-ref.html
== 1062963-floatmanager-reflow.html 1062963-floatmanager-reflow-ref.html
test-pref(dom.webcomponents.enabled,true) == 1066554-1.html 1066554-1-ref.html
test-pref(dom.webcomponents.enabled,true) fails-if(stylo||styloVsGecko) == 1066554-1.html 1066554-1-ref.html
== 1069716-1.html 1069716-1-ref.html
fails-if(webrender) == 1078262-1.html about:blank
test-pref(layout.testing.overlay-scrollbars.always-visible,false) == 1081072-1.html 1081072-1-ref.html

Просмотреть файл

@ -76,38 +76,40 @@ div.after::after {content: " Y";}
return e;
}
document.body.offsetHeight;
function run() {
document.body.offsetHeight;
shadow("host1").innerHTML = '<content></content> c';
shadow("host2").innerHTML = 'a <content style="display:contents"></content> c';
shadow("host3").innerHTML = 'a <content style="display:contents"></content>';
shadow("host4").innerHTML = '<content style="display:contents"></content>';
shadow("host5").innerHTML = 'a <content style="display:contents"></content>';
shadow("host6").innerHTML = '<z style="color:blue; display:contents"><content></content></z> c';
shadow("host7").innerHTML = 'a <content style="display:contents"></content> c';
shadow("host8").innerHTML = 'a <z style="color:blue; display:contents"><content style="display:contents"></z></content>';
shadow("host9").innerHTML = '<content style="display:contents"></content>';
shadow("hostA").innerHTML = 'a <content style="display:contents"></content>';
shadow("hostB").innerHTML = 'a <content select=".c"></content> <content select=".b"></content> B';
shadow("hostC").innerHTML = 'A <content select=".c"></content> <content select=".b"></content> B';
shadow("hostD").innerHTML = 'A <content select=".c"></content> <content select=".b"></content> B <content select=".b"></content>';
shadow("hostE").innerHTML = 'A <content select=".c"></content> <content select=".b"></content> B';
shadow("hostF").innerHTML = '<content select=".c"></content> <content select=".b"></content> B';
shadow("hostG").innerHTML = '<content select=".b"></content>';
shadow("hostH").innerHTML = '<content select=".b"></content>';
shadow("hostI").innerHTML = 'A<content select=".b"></content>';
shadow("hostJ").innerHTML = 'A<content select=".b"></content>';
shadow("hostK").innerHTML = '<content select=".b"></content>';
shadow("hostL").innerHTML = '<content select=".b"></content>';
shadow("hostM").innerHTML = '<content select="b"></content><content select="i"></content>';
shadow("hostN").innerHTML = '<content select="b"></content><content select="i"></content>';
shadow("hostO").innerHTML = '<content select="b"></content><content select="i"></content>';
shadow("hostP").innerHTML = '<content select="b"></content><content select="i"></content>';
shadow("hostQ").innerHTML = '<content select="b"></content><content select="i"></content>';
shadow("hostR").innerHTML = '<content select="span"></content>';
shadow("hostW").innerHTML = '<z style="color:red"><content select="b"></content></z>';
shadow("hostX").innerHTML = '<z style="color:red"><content select="b"></content></z>';
// TODO(bug 1021572?) shadow("hostY").innerHTML = '<content select="b"><style scoped>:scope{color:green}</style></content>';
shadow("host1").innerHTML = '<content></content> c';
shadow("host2").innerHTML = 'a <content style="display:contents"></content> c';
shadow("host3").innerHTML = 'a <content style="display:contents"></content>';
shadow("host4").innerHTML = '<content style="display:contents"></content>';
shadow("host5").innerHTML = 'a <content style="display:contents"></content>';
shadow("host6").innerHTML = '<z style="color:blue; display:contents"><content></content></z> c';
shadow("host7").innerHTML = 'a <content style="display:contents"></content> c';
shadow("host8").innerHTML = 'a <z style="color:blue; display:contents"><content style="display:contents"></z></content>';
shadow("host9").innerHTML = '<content style="display:contents"></content>';
shadow("hostA").innerHTML = 'a <content style="display:contents"></content>';
shadow("hostB").innerHTML = 'a <content select=".c"></content> <content select=".b"></content> B';
shadow("hostC").innerHTML = 'A <content select=".c"></content> <content select=".b"></content> B';
shadow("hostD").innerHTML = 'A <content select=".c"></content> <content select=".b"></content> B <content select=".b"></content>';
shadow("hostE").innerHTML = 'A <content select=".c"></content> <content select=".b"></content> B';
shadow("hostF").innerHTML = '<content select=".c"></content> <content select=".b"></content> B';
shadow("hostG").innerHTML = '<content select=".b"></content>';
shadow("hostH").innerHTML = '<content select=".b"></content>';
shadow("hostI").innerHTML = 'A<content select=".b"></content>';
shadow("hostJ").innerHTML = 'A<content select=".b"></content>';
shadow("hostK").innerHTML = '<content select=".b"></content>';
shadow("hostL").innerHTML = '<content select=".b"></content>';
shadow("hostM").innerHTML = '<content select="b"></content><content select="i"></content>';
shadow("hostN").innerHTML = '<content select="b"></content><content select="i"></content>';
shadow("hostO").innerHTML = '<content select="b"></content><content select="i"></content>';
shadow("hostP").innerHTML = '<content select="b"></content><content select="i"></content>';
shadow("hostQ").innerHTML = '<content select="b"></content><content select="i"></content>';
shadow("hostR").innerHTML = '<content select="span"></content>';
shadow("hostW").innerHTML = '<z style="color:red"><content select="b"></content></z>';
shadow("hostX").innerHTML = '<z style="color:red"><content select="b"></content></z>';
// TODO(bug 1021572?) shadow("hostY").innerHTML = '<content select="b"><style scoped>:scope{color:green}</style></content>';
}
function tweak() {
document.body.offsetHeight;
@ -230,7 +232,12 @@ div.after::after {content: " Y";}
},0);
}
window.addEventListener("MozReftestInvalidate", tweak);
if (document.body.createShadowRoot) {
run();
window.addEventListener("MozReftestInvalidate", tweak);
} else {
document.documentElement.removeAttribute("class");
}
</script>
</body>
</html>

Просмотреть файл

@ -5,8 +5,8 @@ fuzzy-if(Android,8,604) == display-contents-acid.html display-contents-acid-ref.
fuzzy-if(Android,8,604) == display-contents-acid-dyn-1.html display-contents-acid-ref.html
fuzzy-if(Android,8,604) == display-contents-acid-dyn-2.html display-contents-acid-ref.html
fuzzy-if(Android,8,604) == display-contents-acid-dyn-3.html display-contents-acid-ref.html
skip-if(styloVsGecko||stylo) == display-contents-generated-content.html display-contents-generated-content-ref.html
skip-if(styloVsGecko||stylo) == display-contents-generated-content-2.html display-contents-generated-content-ref.html
== display-contents-generated-content.html display-contents-generated-content-ref.html
== display-contents-generated-content-2.html display-contents-generated-content-ref.html
fails-if(styloVsGecko||stylo) == display-contents-style-inheritance-1.html display-contents-style-inheritance-1-ref.html
fails-if(styloVsGecko||stylo) == display-contents-style-inheritance-1-stylechange.html display-contents-style-inheritance-1-ref.html
fuzzy-if(winWidget,12,100) skip-if(styloVsGecko||stylo) == display-contents-style-inheritance-1-dom-mutations.html display-contents-style-inheritance-1-ref.html
@ -17,7 +17,7 @@ fuzzy-if(winWidget,12,100) skip-if(styloVsGecko||stylo) == display-contents-styl
== display-contents-visibility-hidden-2.html display-contents-visibility-hidden-ref.html
== display-contents-495385-2d.html display-contents-495385-2d-ref.html
fuzzy-if(Android,7,3935) == display-contents-xbl.xhtml display-contents-xbl-ref.html
fuzzy-if(Android,7,1186) pref(dom.webcomponents.enabled,true) skip-if(styloVsGecko||stylo) == display-contents-shadow-dom-1.html display-contents-shadow-dom-1-ref.html
fuzzy-if(Android,7,1186) pref(dom.webcomponents.enabled,true) fails-if(stylo||styloVsGecko) == display-contents-shadow-dom-1.html display-contents-shadow-dom-1-ref.html
== display-contents-xbl-2.xul display-contents-xbl-2-ref.xul
asserts(1) asserts-if(styloVsGecko,2) == display-contents-xbl-3.xul display-contents-xbl-3-ref.xul # bug 1089223
skip == display-contents-xbl-4.xul display-contents-xbl-4-ref.xul # fails (not just asserts) due to bug 1089223

Просмотреть файл

@ -1,4 +1,4 @@
== legend.html legend-ref.html
fuzzy-if(skiaContent,1,7) pref(dom.webcomponents.enabled,true) fails-if(styloVsGecko||stylo) == shadow-dom.html shadow-dom-ref.html
fuzzy-if(skiaContent,1,7) pref(dom.webcomponents.enabled,true) fails-if(stylo||styloVsGecko) == shadow-dom.html shadow-dom-ref.html
== 1273433.html 1273433-ref.html
fails-if(styloVsGecko||stylo) == 1339287.html 1339287-ref.html

Просмотреть файл

@ -48,17 +48,19 @@ div.after::after {content: " Y";}
return e;
}
document.body.offsetHeight;
function run() {
document.body.offsetHeight;
shadow("host1").innerHTML = '<content></content> c';
shadow("host2").innerHTML = 'a <content></content> c';
shadow("host3").innerHTML = 'a <content></content>';
shadow("host4").innerHTML = '<content></content>';
shadow("host5").innerHTML = 'a <content></content>';
shadow("host6").innerHTML = '<z style="color:blue; display:contents"><content></content></z> c';
shadow("host7").innerHTML = 'a <content select=".c"></content> <content select=".b"></content> B';
shadow("host8").innerHTML = 'A <content select=".c"></content> <content select=".b"></content> B';
shadow("host9").innerHTML = 'A <content select=".c"></content> <content select=".b"></content> B <content select=".b"></content>';
shadow("host1").innerHTML = '<content></content> c';
shadow("host2").innerHTML = 'a <content></content> c';
shadow("host3").innerHTML = 'a <content></content>';
shadow("host4").innerHTML = '<content></content>';
shadow("host5").innerHTML = 'a <content></content>';
shadow("host6").innerHTML = '<z style="color:blue; display:contents"><content></content></z> c';
shadow("host7").innerHTML = 'a <content select=".c"></content> <content select=".b"></content> B';
shadow("host8").innerHTML = 'A <content select=".c"></content> <content select=".b"></content> B';
shadow("host9").innerHTML = 'A <content select=".c"></content> <content select=".b"></content> B <content select=".b"></content>';
}
function tweak() {
document.body.offsetHeight;
@ -105,7 +107,12 @@ div.after::after {content: " Y";}
},0);
}
window.addEventListener("MozReftestInvalidate", tweak);
if (document.body.createShadowRoot) {
run();
window.addEventListener("MozReftestInvalidate", tweak);
} else {
document.documentElement.removeAttribute("class");
}
</script>
</body>
</html>

Просмотреть файл

@ -367,7 +367,7 @@ fuzzy-if(OSX,1,100) fuzzy-if(skiaContent,1,14) == mfrac-D-1.html mfrac-D-1-ref.h
== mfrac-D-3.html mfrac-D-3-ref.html
== mfrac-D-4.html mfrac-D-4-ref.html
== mfrac-E-1.html mfrac-E-1-ref.html
test-pref(dom.webcomponents.enabled,true) == shadow-dom-1.html shadow-dom-1-ref.html
test-pref(dom.webcomponents.enabled,true) fails-if(stylo||styloVsGecko) == shadow-dom-1.html shadow-dom-1-ref.html
pref(font.size.inflation.emPerLine,25) == font-inflation-1.html font-inflation-1-ref.html
test-pref(font.minimum-size.x-math,40) == default-font.html default-font-ref.html
!= radicalbar-1.html about:blank

Просмотреть файл

@ -7,9 +7,11 @@
<script>
function insertShadowMathML() {
var x = document.getElementById("x");
x.createShadowRoot();
x.shadowRoot.innerHTML =
'<math><msup><mi>X</mi><mi>X</mi></msup></math>';
if (x.createShadowRoot) {
x.createShadowRoot();
x.shadowRoot.innerHTML =
'<math><msup><mi>X</mi><mi>X</mi></msup></math>';
}
document.documentElement.removeAttribute("class");
}
window.addEventListener("MozReftestInvalidate", insertShadowMathML);

Просмотреть файл

@ -3,6 +3,11 @@
<head>
<script>
function tweak() {
if (!document.body.createShadowRoot) {
document.documentElement.className = "";
return;
}
var host = document.getElementById("host");
var shadow = host.createShadowRoot();

Просмотреть файл

@ -5,9 +5,13 @@
<body>
<div id="host"></div>
<script>
var host = document.getElementById("host");
var root = host.createShadowRoot();
root.innerHTML = 'a <content></content> c';
var host, root;
function run() {
host = document.getElementById("host");
root = host.createShadowRoot();
root.innerHTML = 'a <content></content> c';
}
function tweak() {
var span = document.createElement("span");
@ -19,7 +23,12 @@
document.documentElement.removeAttribute("class");
}
window.addEventListener("MozReftestInvalidate", tweak);
if (document.body.createShadowRoot) {
run();
window.addEventListener("MozReftestInvalidate", tweak);
} else {
document.documentElement.className = "";
}
</script>
</body>
</html>

Просмотреть файл

@ -5,9 +5,13 @@
<body>
<div id="host"></div>
<script>
var host = document.getElementById("host");
var root = host.createShadowRoot();
root.innerHTML = "<span>a</span>";
var host, root;
function run() {
host = document.getElementById("host");
root = host.createShadowRoot();
root.innerHTML = "<span>a</span>";
}
function tweak() {
var span = document.createElement("span");
@ -20,7 +24,12 @@
document.documentElement.removeAttribute("class");
}
window.addEventListener("MozReftestInvalidate", tweak);
if (document.body.createShadowRoot) {
run();
window.addEventListener("MozReftestInvalidate", tweak);
} else {
document.documentElement.className = "";
}
</script>
</body>
</html>

Просмотреть файл

@ -5,9 +5,13 @@
<body>
<div id="host"></div>
<script>
var host = document.getElementById("host");
var root = host.createShadowRoot();
root.innerHTML = '<style>input ~ div { background: red; transition: background 100ms; } input:checked ~ div { background: green; }</style><input id="one" type="checkbox"><div style="height: 50px; width: 50px;"></div>';
var host, root;
function run() {
host = document.getElementById("host");
root = host.createShadowRoot();
root.innerHTML = '<style>input ~ div { background: red; transition: background 100ms; } input:checked ~ div { background: green; }</style><input id="one" type="checkbox"><div style="height: 50px; width: 50px;"></div>';
}
function tweak() {
var el = root.getElementById("one");
@ -17,7 +21,12 @@
});
}
window.addEventListener("MozReftestInvalidate", tweak);
if (document.body.createShadowRoot) {
run();
window.addEventListener("MozReftestInvalidate", tweak);
} else {
document.documentElement.className = "";
}
</script>
</body>
</html>

Просмотреть файл

@ -1,19 +1,19 @@
pref(dom.webcomponents.enabled,true) == cross-tree-selection-1.html cross-tree-selection-1-ref.html
pref(dom.webcomponents.enabled,true) == basic-shadow-1.html basic-shadow-1-ref.html
pref(dom.webcomponents.enabled,true) == basic-shadow-2.html basic-shadow-2-ref.html
pref(dom.webcomponents.enabled,true) == basic-shadow-3.html basic-shadow-3-ref.html
pref(dom.webcomponents.enabled,true) == basic-shadow-4.html basic-shadow-4-ref.html
pref(dom.webcomponents.enabled,true) == basic-insertion-point-1.html basic-insertion-point-1-ref.html
pref(dom.webcomponents.enabled,true) skip-if(styloVsGecko||stylo) == basic-insertion-point-2.html basic-insertion-point-2-ref.html
pref(dom.webcomponents.enabled,true) == adjacent-insertion-points-1.html adjacent-insertion-points-1-ref.html
pref(dom.webcomponents.enabled,true) == adjacent-insertion-points-2.html adjacent-insertion-points-2-ref.html
pref(dom.webcomponents.enabled,true) == fallback-content-1.html fallback-content-1-ref.html
pref(dom.webcomponents.enabled,true) == remove-insertion-point-1.html remove-insertion-point-1-ref.html
pref(dom.webcomponents.enabled,true) == nested-insertion-point-1.html nested-insertion-point-1-ref.html
pref(dom.webcomponents.enabled,true) skip-if(styloVsGecko||stylo) == basic-shadow-element-1.html basic-shadow-element-1-ref.html
pref(dom.webcomponents.enabled,true) skip-if(styloVsGecko||stylo) == nested-shadow-element-1.html nested-shadow-element-1-ref.html
pref(dom.webcomponents.enabled,true) skip-if(styloVsGecko||stylo) == update-dist-node-descendants-1.html update-dist-node-descendants-1-ref.html
pref(dom.webcomponents.enabled,true) skip-if(styloVsGecko||stylo) == input-transition-1.html input-transition-1-ref.html
pref(dom.webcomponents.enabled,true) == dynamic-insertion-point-distribution-1.html dynamic-insertion-point-distribution-1-ref.html
pref(dom.webcomponents.enabled,true) == dynamic-insertion-point-distribution-2.html dynamic-insertion-point-distribution-2-ref.html
pref(dom.webcomponents.enabled,true) == remove-append-shadow-host-1.html remove-append-shadow-host-1-ref.html
pref(dom.webcomponents.enabled,true) fails-if(stylo||styloVsGecko) == cross-tree-selection-1.html cross-tree-selection-1-ref.html
pref(dom.webcomponents.enabled,true) fails-if(stylo||styloVsGecko) == basic-shadow-1.html basic-shadow-1-ref.html
pref(dom.webcomponents.enabled,true) fails-if(stylo||styloVsGecko) == basic-shadow-2.html basic-shadow-2-ref.html
pref(dom.webcomponents.enabled,true) fails-if(stylo||styloVsGecko) == basic-shadow-3.html basic-shadow-3-ref.html
pref(dom.webcomponents.enabled,true) fails-if(stylo||styloVsGecko) == basic-shadow-4.html basic-shadow-4-ref.html
pref(dom.webcomponents.enabled,true) fails-if(stylo||styloVsGecko) == basic-insertion-point-1.html basic-insertion-point-1-ref.html
pref(dom.webcomponents.enabled,true) fails-if(stylo||styloVsGecko) == basic-insertion-point-2.html basic-insertion-point-2-ref.html
pref(dom.webcomponents.enabled,true) fails-if(stylo||styloVsGecko) == adjacent-insertion-points-1.html adjacent-insertion-points-1-ref.html
pref(dom.webcomponents.enabled,true) fails-if(stylo||styloVsGecko) == adjacent-insertion-points-2.html adjacent-insertion-points-2-ref.html
pref(dom.webcomponents.enabled,true) fails-if(stylo||styloVsGecko) == fallback-content-1.html fallback-content-1-ref.html
pref(dom.webcomponents.enabled,true) fails-if(stylo||styloVsGecko) == remove-insertion-point-1.html remove-insertion-point-1-ref.html
pref(dom.webcomponents.enabled,true) fails-if(stylo||styloVsGecko) == nested-insertion-point-1.html nested-insertion-point-1-ref.html
pref(dom.webcomponents.enabled,true) fails-if(stylo||styloVsGecko) == basic-shadow-element-1.html basic-shadow-element-1-ref.html
pref(dom.webcomponents.enabled,true) fails-if(stylo||styloVsGecko) == nested-shadow-element-1.html nested-shadow-element-1-ref.html
pref(dom.webcomponents.enabled,true) fails-if(stylo||styloVsGecko) == update-dist-node-descendants-1.html update-dist-node-descendants-1-ref.html
pref(dom.webcomponents.enabled,true) fails-if(stylo||styloVsGecko) == input-transition-1.html input-transition-1-ref.html
pref(dom.webcomponents.enabled,true) fails-if(stylo||styloVsGecko) == dynamic-insertion-point-distribution-1.html dynamic-insertion-point-distribution-1-ref.html
pref(dom.webcomponents.enabled,true) fails-if(stylo||styloVsGecko) == dynamic-insertion-point-distribution-2.html dynamic-insertion-point-distribution-2-ref.html
pref(dom.webcomponents.enabled,true) fails-if(stylo||styloVsGecko) == remove-append-shadow-host-1.html remove-append-shadow-host-1-ref.html

Просмотреть файл

@ -5,8 +5,10 @@
<body>
<div id="outer"><span id="distnode">text</span></div>
<script>
var shadowRoot = document.getElementById('outer').createShadowRoot();
shadowRoot.innerHTML = '<div><content></content></div>';
function run() {
var shadowRoot = document.getElementById('outer').createShadowRoot();
shadowRoot.innerHTML = '<div><content></content></div>';
}
function tweak() {
var distNode = document.getElementById("distnode");
@ -15,7 +17,12 @@ function tweak() {
document.documentElement.removeAttribute("class");
}
window.addEventListener("MozReftestInvalidate", tweak);
if (document.body.createShadowRoot) {
run();
window.addEventListener("MozReftestInvalidate", tweak);
} else {
document.documentElement.className = "";
}
</script>
</body>
</html>

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,192 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef mozilla_GeckoStyleContext_h
#define mozilla_GeckoStyleContext_h
#include "nsStyleContext.h"
namespace mozilla {
class GeckoStyleContext final : public nsStyleContext {
public:
GeckoStyleContext(nsStyleContext* aParent,
nsIAtom* aPseudoTag,
CSSPseudoElementType aPseudoType,
already_AddRefed<nsRuleNode> aRuleNode,
bool aSkipParentDisplayBasedStyleFixup);
void* operator new(size_t sz, nsPresContext* aPresContext);
nsPresContext* PresContext() const {
return RuleNode()->PresContext();
}
void AddChild(GeckoStyleContext* aChild);
void RemoveChild(GeckoStyleContext* aChild);
void* GetUniqueStyleData(const nsStyleStructID& aSID);
void* CreateEmptyStyleData(const nsStyleStructID& aSID);
/**
* Sets the NS_STYLE_INELIGIBLE_FOR_SHARING bit on this style context
* and its descendants. If it finds a descendant that has the bit
* already set, assumes that it can skip that subtree.
*/
void SetIneligibleForSharing();
/**
* On each descendant of this style context, clears out any cached inherited
* structs indicated in aStructs.
*/
void ClearCachedInheritedStyleDataOnDescendants(uint32_t aStructs);
// Find, if it already exists *and is easily findable* (i.e., near the
// start of the child list), a style context whose:
// * GetPseudo() matches aPseudoTag
// * mRuleNode matches aSource
// * !!GetStyleIfVisited() == !!aSourceIfVisited, and, if they're
// non-null, GetStyleIfVisited()->mRuleNode == aSourceIfVisited
// * RelevantLinkVisited() == aRelevantLinkVisited
already_AddRefed<GeckoStyleContext>
FindChildWithRules(const nsIAtom* aPseudoTag,
nsRuleNode* aSource,
nsRuleNode* aSourceIfVisited,
bool aRelevantLinkVisited);
// Tell this style context to cache aStruct as the struct for aSID
void SetStyle(nsStyleStructID aSID, void* aStruct);
/*
* Get the style data for a style struct. This is the most important
* member function of nsStyleContext. It fills in a const pointer
* to a style data struct that is appropriate for the style context's
* frame. This struct may be shared with other contexts (either in
* the rule tree or the style context tree), so it should not be
* modified.
*
* This function will NOT return null (even when out of memory) when
* given a valid style struct ID, so the result does not need to be
* null-checked.
*
* The typesafe functions below are preferred to the use of this
* function, both because they're easier to read and because they're
* faster.
*/
const void* NS_FASTCALL StyleData(nsStyleStructID aSID) MOZ_NONNULL_RETURN;
#ifdef DEBUG
void ListDescendants(FILE* out, int32_t aIndent);
#endif
#ifdef RESTYLE_LOGGING
// This only gets called under call trees where we've already checked
// that PresContext()->RestyleManager()->ShouldLogRestyle() returned true.
// It exists here just to satisfy LOG_RESTYLE's expectations.
bool ShouldLogRestyle() { return true; }
void LogStyleContextTree(int32_t aLoggingDepth, uint32_t aStructs);
void LogStyleContextTree(bool aFirst, uint32_t aStructs);
int32_t& LoggingDepth();
nsCString GetCachedStyleDataAsString(uint32_t aStructs);
#endif
// Only called for Gecko-backed nsStyleContexts.
void ApplyStyleFixups(bool aSkipParentDisplayBasedStyleFixup);
bool HasNoChildren() const;
nsRuleNode* RuleNode() const {
MOZ_ASSERT(mRuleNode);
return mRuleNode;
}
~GeckoStyleContext() {
Destructor();
}
/**
* Swaps owned style struct pointers between this and aNewContext, on
* the assumption that aNewContext is the new style context for a frame
* and this is the old one. aStructs indicates which structs to consider
* swapping; only those which are owned in both this and aNewContext
* will be swapped.
*
* Additionally, if there are identical struct pointers for one of the
* structs indicated by aStructs, and it is not an owned struct on this,
* then the cached struct slot on this will be set to null. If the struct
* has been swapped on an ancestor, this style context (being the old one)
* will be left caching the struct pointer on the new ancestor, despite
* inheriting from the old ancestor. This is not normally a problem, as
* this style context will usually be destroyed by being released at the
* end of ElementRestyler::Restyle; but for style contexts held on to outside
* of the frame, we need to clear out the cached pointer so that if we need
* it again we'll re-fetch it from the new ancestor.
*/
void SwapStyleData(GeckoStyleContext* aNewContext, uint32_t aStructs);
void DestroyCachedStructs(nsPresContext* aPresContext);
/**
* Return style data that is currently cached on the style context.
* Only returns the structs we cache ourselves; never consults the
* rule tree.
*
* For "internal" use only in nsStyleContext and nsRuleNode.
*/
const void* GetCachedStyleData(nsStyleStructID aSID)
{
const void* cachedData;
if (nsCachedStyleData::IsReset(aSID)) {
if (mCachedResetData) {
cachedData = mCachedResetData->mStyleStructs[aSID];
} else {
cachedData = nullptr;
}
} else {
cachedData = mCachedInheritedData.mStyleStructs[aSID];
}
return cachedData;
}
// mCachedInheritedData and mCachedResetData point to both structs that
// are owned by this style context and structs that are owned by one of
// this style context's ancestors (which are indirectly owned since this
// style context owns a reference to its parent). If the bit in |mBits|
// is set for a struct, that means that the pointer for that struct is
// owned by an ancestor or by the rule node rather than by this style context.
// Since style contexts typically have some inherited data but only sometimes
// have reset data, we always allocate the mCachedInheritedData, but only
// sometimes allocate the mCachedResetData.
nsResetStyleData* mCachedResetData; // Cached reset style data.
nsInheritedStyleData mCachedInheritedData; // Cached inherited style data
#ifdef DEBUG
void AssertStructsNotUsedElsewhere(GeckoStyleContext* aDestroyingContext,
int32_t aLevels) const;
#endif
private:
// Helper for ClearCachedInheritedStyleDataOnDescendants.
void DoClearCachedInheritedStyleDataOnDescendants(uint32_t aStructs);
// Children are kept in two circularly-linked lists. The list anchor
// is not part of the list (null for empty), and we point to the first
// child.
// mEmptyChild for children whose rule node is the root rule node, and
// mChild for other children. The order of children is not
// meaningful.
GeckoStyleContext* mChild;
GeckoStyleContext* mEmptyChild;
GeckoStyleContext* mPrevSibling;
GeckoStyleContext* mNextSibling;
RefPtr<nsRuleNode> mRuleNode;
};
}
#endif // mozilla_GeckoStyleContext_h

Просмотреть файл

@ -50,6 +50,7 @@
#include "mozilla/EffectCompositor.h"
#include "mozilla/EffectSet.h"
#include "mozilla/EventStates.h"
#include "mozilla/GeckoStyleContext.h"
#include "mozilla/Keyframe.h"
#include "mozilla/Mutex.h"
#include "mozilla/ServoElementSnapshot.h"

Просмотреть файл

@ -0,0 +1,30 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/ServoStyleContext.h"
#include "nsStyleConsts.h"
#include "nsStyleStruct.h"
#include "nsPresContext.h"
#include "mozilla/ServoBindings.h"
using namespace mozilla;
ServoStyleContext::ServoStyleContext(nsStyleContext* aParent,
nsPresContext* aPresContext,
nsIAtom* aPseudoTag,
CSSPseudoElementType aPseudoType,
already_AddRefed<ServoComputedValues> aComputedValues)
: nsStyleContext(aParent, aPseudoTag, aPseudoType),
mSource(Move(aComputedValues))
{
mPresContext = aPresContext;
FinishConstruction();
// No need to call ApplyStyleFixups here, since fixups are handled by Servo when
// producing the ServoComputedValues.
}

Просмотреть файл

@ -0,0 +1,39 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef mozilla_ServoStyleContext_h
#define mozilla_ServoStyleContext_h
#include "nsStyleContext.h"
namespace mozilla {
class ServoStyleContext final : public nsStyleContext {
public:
ServoStyleContext(nsStyleContext* aParent,
nsPresContext* aPresContext,
nsIAtom* aPseudoTag,
CSSPseudoElementType aPseudoType,
already_AddRefed<ServoComputedValues> aComputedValues);
nsPresContext* PresContext() const {
return mPresContext;
}
ServoComputedValues* ComputedValues() const {
return mSource;
}
~ServoStyleContext() {
Destructor();
}
private:
nsPresContext* mPresContext;
RefPtr<ServoComputedValues> mSource;
};
}
#endif // mozilla_ServoStyleContext_h

Просмотреть файл

@ -13,6 +13,7 @@
#include "mozilla/ServoBindingTypes.h"
#include "nsIDOMCSSStyleRule.h"
#include "nsICSSStyleRuleDOMWrapper.h"
#include "nsDOMCSSDeclaration.h"
namespace mozilla {

Просмотреть файл

@ -441,7 +441,7 @@ ServoStyleSet::ResolveStyleForText(nsIContent* aTextNode,
// enough to do on the main thread, which means that the parallel style system
// can avoid worrying about text nodes.
const ServoComputedValues* parentComputedValues =
aParentContext->StyleSource().AsServoComputedValues();
aParentContext->ComputedValues();
RefPtr<ServoComputedValues> computedValues =
Servo_ComputedValues_Inherit(mRawSet.get(),
parentComputedValues,
@ -457,7 +457,7 @@ already_AddRefed<nsStyleContext>
ServoStyleSet::ResolveStyleForFirstLetterContinuation(nsStyleContext* aParentContext)
{
const ServoComputedValues* parent =
aParentContext->StyleSource().AsServoComputedValues();
aParentContext->ComputedValues();
RefPtr<ServoComputedValues> computedValues =
Servo_ComputedValues_Inherit(mRawSet.get(),
parent,
@ -571,7 +571,7 @@ ServoStyleSet::ResolveInheritingAnonymousBoxStyle(nsIAtom* aPseudoTag,
nsCSSAnonBoxes::AnonBoxSkipsParentDisplayBasedStyleFixup(aPseudoTag);
const ServoComputedValues* parentStyle =
aParentContext ? aParentContext->StyleSource().AsServoComputedValues()
aParentContext ? aParentContext->ComputedValues()
: nullptr;
RefPtr<ServoComputedValues> computedValues =
Servo_ComputedValues_GetForAnonymousBox(parentStyle, aPseudoTag, skipFixup,

Просмотреть файл

@ -28,12 +28,7 @@ void AssertIsMainThreadOrServoFontMetricsLocked();
bool IsServo() const { return false; }
#endif
/**
* Macro used in a base class of |geckotype_| and |servotype_|.
* The class should define |StyleBackendType mType;| itself.
*/
#define MOZ_DECL_STYLO_METHODS(geckotype_, servotype_) \
MOZ_DECL_STYLO_CHECK_METHODS \
#define MOZ_DECL_STYLO_CONVERT_METHODS(geckotype_, servotype_) \
inline geckotype_* AsGecko(); \
inline servotype_* AsServo(); \
inline const geckotype_* AsGecko() const; \
@ -43,6 +38,14 @@ void AssertIsMainThreadOrServoFontMetricsLocked();
inline const geckotype_* GetAsGecko() const; \
inline const servotype_* GetAsServo() const;
/**
* Macro used in a base class of |geckotype_| and |servotype_|.
* The class should define |StyleBackendType mType;| itself.
*/
#define MOZ_DECL_STYLO_METHODS(geckotype_, servotype_) \
MOZ_DECL_STYLO_CHECK_METHODS \
MOZ_DECL_STYLO_CONVERT_METHODS(geckotype_, servotype_)
/**
* Macro used in inline header of class |type_| with its Gecko and Servo
* subclasses named |geckotype_| and |servotype_| correspondingly for

Просмотреть файл

@ -38,6 +38,7 @@
#include "nsIDocument.h"
#include "nsIFrame.h"
#include "gfx2DGlue.h"
#include "nsStyleContextInlines.h"
using namespace mozilla;
using namespace mozilla::css;
@ -3519,7 +3520,7 @@ ComputeValuesFromStyleRule(nsCSSPropertyID aProperty,
// Force walk of rule tree
nsStyleStructID sid = nsCSSProps::kSIDTable[aProperty];
tmpStyleContext->StyleData(sid);
tmpStyleContext->AsGecko()->StyleData(sid);
// The rule node will have unconditional cached style data if the value is
// not context-sensitive. So if there's nothing cached, it's not context
@ -3970,7 +3971,7 @@ SubstitutePixelValues(nsStyleContext* aStyleContext,
if (aInput.IsCalcUnit()) {
RuleNodeCacheConditions conditions;
nsRuleNode::ComputedCalc c =
nsRuleNode::SpecifiedCalcToComputedCalc(aInput, aStyleContext,
nsRuleNode::SpecifiedCalcToComputedCalc(aInput, aStyleContext->AsGecko(),
aStyleContext->PresContext(),
conditions);
nsStyleCoord::CalcValue c2;
@ -3990,7 +3991,7 @@ SubstitutePixelValues(nsStyleContext* aStyleContext,
} else if (aInput.IsLengthUnit() &&
aInput.GetUnit() != eCSSUnit_Pixel) {
RuleNodeCacheConditions conditions;
nscoord len = nsRuleNode::CalcLength(aInput, aStyleContext,
nscoord len = nsRuleNode::CalcLength(aInput, aStyleContext->AsGecko(),
aStyleContext->PresContext(),
conditions);
aOutput.SetFloatValue(nsPresContext::AppUnitsToFloatCSSPixels(len),
@ -4220,7 +4221,7 @@ StyleAnimationValue::ExtractComputedValue(nsCSSPropertyID aProperty,
MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT_no_shorthands,
"bad property");
const void* styleStruct =
aStyleContext->StyleData(nsCSSProps::kSIDTable[aProperty]);
aStyleContext->AsGecko()->StyleData(nsCSSProps::kSIDTable[aProperty]);
ptrdiff_t ssOffset = nsCSSProps::kStyleStructOffsetTable[aProperty];
nsStyleAnimType animType = nsCSSProps::kAnimTypeTable[aProperty];
MOZ_ASSERT(0 <= ssOffset ||
@ -4788,7 +4789,7 @@ StyleAnimationValue::ExtractComputedValue(nsCSSPropertyID aProperty,
eUnit_Visibility);
return true;
}
if (aStyleContext->StyleSource().IsServoComputedValues()) {
if (aStyleContext->IsServo()) {
NS_ERROR("stylo: extracting discretely animated values not supported");
return false;
}
@ -5359,7 +5360,7 @@ AnimationValue::FromString(nsCSSPropertyID aProperty,
RefPtr<nsStyleContext> styleContext =
nsComputedDOMStyle::GetStyleContext(aElement, nullptr, shell);
if (styleContext->StyleSource().IsServoComputedValues()) {
if (auto servoContext = styleContext->GetAsServo()) {
nsPresContext* presContext = shell->GetPresContext();
if (!presContext) {
return result;
@ -5373,7 +5374,7 @@ AnimationValue::FromString(nsCSSPropertyID aProperty,
}
const ServoComputedValues* computedValues =
styleContext->StyleSource().AsServoComputedValues();
servoContext->ComputedValues();
result.mServo = presContext->StyleSet()
->AsServo()
->ComputeAnimationValue(aElement,

Просмотреть файл

@ -1,161 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_StyleContextSource_h
#define mozilla_StyleContextSource_h
#include "mozilla/ServoBindingTypes.h"
#include "nsRuleNode.h"
namespace mozilla {
// Tagged union between Gecko Rule Nodes and Servo Computed Values.
//
// The rule node is the node in the lexicographic tree of rule nodes
// (the "rule tree") that indicates which style rules are used to
// compute the style data, and in what cascading order. The least
// specific rule matched is the one whose rule node is a child of the
// root of the rule tree, and the most specific rule matched is the
// |mRule| member of the rule node.
//
// In the Servo case, we hold an atomically-refcounted handle to a
// Servo ComputedValues struct, which is more or less the Servo equivalent
// of an nsStyleContext.
// Underlying pointer without any strong ownership semantics.
struct NonOwningStyleContextSource
{
MOZ_IMPLICIT NonOwningStyleContextSource(nsRuleNode* aRuleNode)
: mBits(reinterpret_cast<uintptr_t>(aRuleNode)) {}
explicit NonOwningStyleContextSource(const ServoComputedValues* aComputedValues)
: mBits(reinterpret_cast<uintptr_t>(aComputedValues) | 1) {}
bool operator==(const NonOwningStyleContextSource& aOther) const {
MOZ_ASSERT(IsServoComputedValues() == aOther.IsServoComputedValues(),
"Comparing Servo to Gecko - probably a bug");
return mBits == aOther.mBits;
}
bool operator!=(const NonOwningStyleContextSource& aOther) const {
return !(*this == aOther);
}
// We intentionally avoid exposing IsGeckoRuleNode() here, because that would
// encourage callers to do:
//
// if (source.IsGeckoRuleNode()) {
// // Code that we would run unconditionally if it weren't for Servo.
// }
//
// We want these branches to compile away when MOZ_STYLO is disabled, but that
// won't happen if there's an implicit null-check.
bool IsNull() const { return !mBits; }
bool IsGeckoRuleNodeOrNull() const { return !IsServoComputedValues(); }
bool IsServoComputedValues() const {
#ifdef MOZ_STYLO
return mBits & 1;
#else
return false;
#endif
}
nsRuleNode* AsGeckoRuleNode() const {
MOZ_ASSERT(IsGeckoRuleNodeOrNull() && !IsNull());
return reinterpret_cast<nsRuleNode*>(mBits);
}
const ServoComputedValues* AsServoComputedValues() const {
MOZ_ASSERT(IsServoComputedValues());
return reinterpret_cast<ServoComputedValues*>(mBits & ~1);
}
bool MatchesNoRules() const {
if (IsGeckoRuleNodeOrNull()) {
return AsGeckoRuleNode()->IsRoot();
}
// Just assume a Servo-backed StyleContextSource always matches some rules.
//
// MatchesNoRules is used to ensure style contexts that match no rules
// go into a separate mEmptyChild list on their parent. This is only used
// as an optimization so that calling FindChildWithRules for style context
// sharing is faster for text nodes (which match no rules, and are common).
// Since Servo will handle sharing for us, there's no need to split children
// into two lists.
return false;
}
private:
uintptr_t mBits;
};
// Higher-level struct that owns a strong reference to the source. The source
// is never null.
struct OwningStyleContextSource
{
explicit OwningStyleContextSource(already_AddRefed<nsRuleNode> aRuleNode)
: mRaw(aRuleNode.take())
{
MOZ_COUNT_CTOR(OwningStyleContextSource);
MOZ_ASSERT(!mRaw.IsNull());
};
explicit OwningStyleContextSource(already_AddRefed<ServoComputedValues> aComputedValues)
: mRaw(aComputedValues.take())
{
MOZ_COUNT_CTOR(OwningStyleContextSource);
MOZ_ASSERT(!mRaw.IsNull());
}
OwningStyleContextSource(OwningStyleContextSource&& aOther)
: mRaw(aOther.mRaw)
{
MOZ_COUNT_CTOR(OwningStyleContextSource);
aOther.mRaw = nullptr;
}
OwningStyleContextSource& operator=(OwningStyleContextSource&) = delete;
OwningStyleContextSource(OwningStyleContextSource&) = delete;
~OwningStyleContextSource() {
MOZ_COUNT_DTOR(OwningStyleContextSource);
if (mRaw.IsNull()) {
// We must have invoked the move constructor.
} else if (IsGeckoRuleNode()) {
RefPtr<nsRuleNode> releaseme = dont_AddRef(AsGeckoRuleNode());
} else {
MOZ_ASSERT(IsServoComputedValues());
RefPtr<ServoComputedValues> releaseme =
dont_AddRef(AsServoComputedValues());
}
}
bool operator==(const OwningStyleContextSource& aOther) const {
return mRaw == aOther.mRaw;
}
bool operator!=(const OwningStyleContextSource& aOther) const {
return !(*this == aOther);
}
bool IsNull() const { return mRaw.IsNull(); }
bool IsGeckoRuleNode() const {
MOZ_ASSERT(!mRaw.IsNull());
return mRaw.IsGeckoRuleNodeOrNull();
}
bool IsServoComputedValues() const { return mRaw.IsServoComputedValues(); }
NonOwningStyleContextSource AsRaw() const { return mRaw; }
nsRuleNode* AsGeckoRuleNode() const { return mRaw.AsGeckoRuleNode(); }
ServoComputedValues* AsServoComputedValues() const {
return const_cast<ServoComputedValues*>(mRaw.AsServoComputedValues());
}
bool MatchesNoRules() const { return mRaw.MatchesNoRules(); }
private:
NonOwningStyleContextSource mRaw;
};
} // namespace mozilla
#endif // mozilla_StyleContextSource_h

Просмотреть файл

@ -69,6 +69,7 @@ EXPORTS += [
'nsStyleAutoArray.h',
'nsStyleConsts.h',
'nsStyleContext.h',
'nsStyleContextInlines.h',
'nsStyleCoord.h',
'nsStyleSet.h',
'nsStyleStruct.h',
@ -89,6 +90,7 @@ EXPORTS.mozilla += [
'DeclarationBlock.h',
'DeclarationBlockInlines.h',
'DocumentStyleRootIterator.h',
'GeckoStyleContext.h',
'GenericSpecifiedValues.h',
'GenericSpecifiedValuesInlines.h',
'HandleRefPtr.h',
@ -116,6 +118,7 @@ EXPORTS.mozilla += [
'ServoPageRule.h',
'ServoPropPrefList.h',
'ServoSpecifiedValues.h',
'ServoStyleContext.h',
'ServoStyleRule.h',
'ServoStyleSet.h',
'ServoStyleSheet.h',
@ -126,7 +129,6 @@ EXPORTS.mozilla += [
'StyleAnimationValue.h',
'StyleBackendType.h',
'StyleComplexColor.h',
'StyleContextSource.h',
'StyleSetHandle.h',
'StyleSetHandleInlines.h',
'StyleSheet.h',
@ -193,6 +195,7 @@ UNIFIED_SOURCES += [
'FontFace.cpp',
'FontFaceSet.cpp',
'FontFaceSetIterator.cpp',
'GeckoStyleContext.cpp',
'GroupRule.cpp',
'ImageLoader.cpp',
'IncrementalClearCOMRuleArray.cpp',
@ -252,6 +255,7 @@ UNIFIED_SOURCES += [
'ServoNamespaceRule.cpp',
'ServoPageRule.cpp',
'ServoSpecifiedValues.cpp',
'ServoStyleContext.cpp',
'ServoStyleRule.cpp',
'ServoStyleSet.cpp',
'ServoStyleSheet.cpp',

Просмотреть файл

@ -18,6 +18,7 @@
#include "PLDHashTable.h"
#include "nsICSSPseudoComparator.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/css/ImportRule.h"
#include "mozilla/css/StyleRule.h"
#include "mozilla/css/GroupRule.h"
#include "nsIDocument.h"

Просмотреть файл

@ -51,6 +51,7 @@
#include "nsWrapperCacheInlines.h"
#include "mozilla/AppUnits.h"
#include <algorithm>
#include "nsStyleContextInlines.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -563,7 +564,7 @@ MustReresolveStyle(const nsStyleContext* aContext)
if (aContext->HasPseudoElementData()) {
if (!aContext->GetPseudo() ||
aContext->StyleSource().IsServoComputedValues()) {
aContext->IsServo()) {
// TODO(emilio): When ::first-line is supported in Servo, we may want to
// fix this to avoid re-resolving pseudo-element styles.
return true;
@ -870,7 +871,7 @@ nsComputedDOMStyle::UpdateCurrentStyleSources(bool aNeedsLayoutFlush)
if (!mStyleContext || MustReresolveStyle(mStyleContext)) {
#ifdef DEBUG
if (mStyleContext && mStyleContext->StyleSource().IsGeckoRuleNodeOrNull()) {
if (mStyleContext && mStyleContext->IsGecko()) {
// We want to check that going through this path because of
// HasPseudoElementData is rare, because it slows us down a good
// bit. So check that we're really inside something associated

Просмотреть файл

@ -9,12 +9,15 @@
#define nsICSSLoaderObserver_h___
#include "nsISupports.h"
#include "mozilla/StyleSheet.h"
#define NS_ICSSLOADEROBSERVER_IID \
{ 0xf51fbf2c, 0xfe4b, 0x4a15, \
{ 0xaf, 0x7e, 0x5e, 0x20, 0x64, 0x5f, 0xaf, 0x58 } }
namespace mozilla {
class StyleSheet;
}
class nsICSSLoaderObserver : public nsISupports {
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICSSLOADEROBSERVER_IID)

Просмотреть файл

@ -39,7 +39,7 @@
#include "nsCSSPseudoElements.h"
#include "nsThemeConstants.h"
#include "PLDHashTable.h"
#include "nsStyleContext.h"
#include "GeckoStyleContext.h"
#include "nsStyleSet.h"
#include "nsStyleStruct.h"
#include "nsSize.h"
@ -91,7 +91,7 @@ enum UnsetAction
void*
nsConditionalResetStyleData::GetConditionalStyleData(nsStyleStructID aSID,
nsStyleContext* aStyleContext) const
GeckoStyleContext* aStyleContext) const
{
Entry* e = static_cast<Entry*>(mEntries[aSID]);
MOZ_ASSERT(e, "if mConditionalBits bit is set, we must have at least one "
@ -145,14 +145,14 @@ CreateStyleImageRequest(nsPresContext* aPresContext, const nsCSSValue& aValue,
static void
SetStyleShapeSourceToCSSValue(StyleShapeSource* aShapeSource,
const nsCSSValue* aValue,
nsStyleContext* aStyleContext,
GeckoStyleContext* aStyleContext,
nsPresContext* aPresContext,
RuleNodeCacheConditions& aConditions);
/* Helper function to convert a CSS <position> specified value into its
* computed-style form. */
static void
ComputePositionValue(nsStyleContext* aStyleContext,
ComputePositionValue(GeckoStyleContext* aStyleContext,
const nsCSSValue& aValue,
Position& aComputedValue,
RuleNodeCacheConditions& aConditions);
@ -925,7 +925,7 @@ GetFloatFromBoxPosition(int32_t aEnumValue)
// changes aCoord iff it returns true
static bool SetCoord(const nsCSSValue& aValue, nsStyleCoord& aCoord,
const nsStyleCoord& aParentCoord,
int32_t aMask, nsStyleContext* aStyleContext,
int32_t aMask, GeckoStyleContext* aStyleContext,
nsPresContext* aPresContext,
RuleNodeCacheConditions& aConditions)
{
@ -1054,7 +1054,7 @@ static inline bool SetAbsCoord(const nsCSSValue& aValue,
// The values of the following variables will never be used; so it does not
// matter what to set.
const nsStyleCoord dummyParentCoord;
nsStyleContext* dummyStyleContext = nullptr;
GeckoStyleContext* dummyStyleContext = nullptr;
nsPresContext* dummyPresContext = nullptr;
RuleNodeCacheConditions dummyCacheKey;
@ -1074,7 +1074,7 @@ static bool
SetPairCoords(const nsCSSValue& aValue,
nsStyleCoord& aCoordX, nsStyleCoord& aCoordY,
const nsStyleCoord& aParentX, const nsStyleCoord& aParentY,
int32_t aMask, nsStyleContext* aStyleContext,
int32_t aMask, GeckoStyleContext* aStyleContext,
nsPresContext* aPresContext, RuleNodeCacheConditions& aConditions)
{
const nsCSSValue& valX =
@ -1233,7 +1233,7 @@ static Maybe<nscoord>
ComputeLineWidthValue(const nsCSSValue& aValue,
const nscoord aParentCoord,
const nscoord aInitialCoord,
nsStyleContext* aStyleContext,
GeckoStyleContext* aStyleContext,
nsPresContext* aPresContext,
RuleNodeCacheConditions& aConditions)
{
@ -1269,7 +1269,7 @@ ComputeLineWidthValue(const nsCSSValue& aValue,
}
static void SetGradientCoord(const nsCSSValue& aValue, nsPresContext* aPresContext,
nsStyleContext* aContext, nsStyleCoord& aResult,
GeckoStyleContext* aContext, nsStyleCoord& aResult,
RuleNodeCacheConditions& aConditions)
{
// OK to pass bad aParentCoord since we're not passing SETCOORD_INHERIT
@ -1282,7 +1282,7 @@ static void SetGradientCoord(const nsCSSValue& aValue, nsPresContext* aPresConte
}
static void SetGradient(const nsCSSValue& aValue, nsPresContext* aPresContext,
nsStyleContext* aContext, nsStyleGradient& aResult,
GeckoStyleContext* aContext, nsStyleGradient& aResult,
RuleNodeCacheConditions& aConditions)
{
MOZ_ASSERT(aValue.GetUnit() == eCSSUnit_Gradient,
@ -1380,7 +1380,7 @@ static void SetGradient(const nsCSSValue& aValue, nsPresContext* aPresContext,
}
// -moz-image-rect(<uri>, <top>, <right>, <bottom>, <left>)
static void SetStyleImageToImageRect(nsStyleContext* aStyleContext,
static void SetStyleImageToImageRect(GeckoStyleContext* aStyleContext,
const nsCSSValue& aValue,
nsStyleImage& aResult)
{
@ -1415,7 +1415,7 @@ static void SetStyleImageToImageRect(nsStyleContext* aStyleContext,
aResult.SetCropRect(MakeUnique<nsStyleSides>(cropRect));
}
static void SetStyleImage(nsStyleContext* aStyleContext,
static void SetStyleImage(GeckoStyleContext* aStyleContext,
const nsCSSValue& aValue,
nsStyleImage& aResult,
RuleNodeCacheConditions& aConditions)
@ -1986,15 +1986,15 @@ nsRuleNode::PropagateDependentBit(nsStyleStructID aSID, nsRuleNode* aHighestNode
}
/* static */ void
nsRuleNode::PropagateGrandancestorBit(nsStyleContext* aContext,
nsStyleContext* aContextInheritedFrom)
nsRuleNode::PropagateGrandancestorBit(GeckoStyleContext* aContext,
GeckoStyleContext* aContextInheritedFrom)
{
MOZ_ASSERT(aContext);
MOZ_ASSERT(aContextInheritedFrom &&
aContextInheritedFrom != aContext,
"aContextInheritedFrom must be an ancestor of aContext");
for (nsStyleContext* context = aContext->GetParent();
for (GeckoStyleContext* context = aContext->GetParent();
context != aContextInheritedFrom;
context = context->GetParent()) {
if (!context) {
@ -2396,7 +2396,7 @@ nsRuleNode::CheckSpecifiedProperties(const nsStyleStructID aSID,
// return the bit to check in nsCSSProp's flags table. Otherwise,
// return 0.
inline uint32_t
GetPseudoRestriction(nsStyleContext *aContext)
GetPseudoRestriction(GeckoStyleContext *aContext)
{
// This needs to match nsStyleSet::WalkRestrictionRule.
uint32_t pseudoRestriction = 0;
@ -2457,7 +2457,7 @@ AutoCSSValueArray::~AutoCSSValueArray()
/* static */ bool
nsRuleNode::ResolveVariableReferences(const nsStyleStructID aSID,
nsRuleData* aRuleData,
nsStyleContext* aContext)
GeckoStyleContext* aContext)
{
MOZ_ASSERT(aSID != eStyleStruct_Variables);
MOZ_ASSERT(aRuleData->mSIDs & nsCachedStyleData::GetBitForSID(aSID));
@ -2509,7 +2509,7 @@ nsRuleNode::ResolveVariableReferences(const nsStyleStructID aSID,
const void*
nsRuleNode::WalkRuleTree(const nsStyleStructID aSID,
nsStyleContext* aContext)
GeckoStyleContext* aContext)
{
// use placement new[] on the result of alloca() to allocate a
// variable-sized stack array, including execution of constructors,
@ -2689,7 +2689,7 @@ nsRuleNode::WalkRuleTree(const nsStyleStructID aSID,
// All information must necessarily be inherited from our parent style context.
// In the absence of any computed data in the rule tree and with
// no rules specified that didn't have values of 'inherit', we should check our parent.
nsStyleContext* parentContext = aContext->GetParent();
GeckoStyleContext* parentContext = aContext->GetParent();
if (isReset) {
/* Reset structs don't inherit from first-line. */
/* See similar code in COMPUTE_START_RESET */
@ -2721,7 +2721,7 @@ nsRuleNode::WalkRuleTree(const nsStyleStructID aSID,
}
typedef const void* (nsRuleNode::*ComputeFunc)(void*, const nsRuleData*,
nsStyleContext*, nsRuleNode*,
GeckoStyleContext*, nsRuleNode*,
RuleDetail,
const RuleNodeCacheConditions);
static const ComputeFunc sComputeFuncs[] = {
@ -2737,7 +2737,7 @@ nsRuleNode::WalkRuleTree(const nsStyleStructID aSID,
}
const void*
nsRuleNode::SetDefaultOnRoot(const nsStyleStructID aSID, nsStyleContext* aContext)
nsRuleNode::SetDefaultOnRoot(const nsStyleStructID aSID, GeckoStyleContext* aContext)
{
switch (aSID) {
case eStyleStruct_Font:
@ -2916,7 +2916,7 @@ nsRuleNode::SetDefaultOnRoot(const nsStyleStructID aSID, nsStyleContext* aContex
NS_ASSERTION(aRuleDetail != eRuleFullInherited, \
"should not have bothered calling Compute*Data"); \
\
nsStyleContext* parentContext = aContext->GetParent(); \
GeckoStyleContext* parentContext = aContext->GetParent(); \
\
nsStyle##type_* data_ = nullptr; \
mozilla::Maybe<nsStyle##type_> maybeFakeParentData; \
@ -2976,7 +2976,7 @@ nsRuleNode::SetDefaultOnRoot(const nsStyleStructID aSID, nsStyleContext* aContex
NS_ASSERTION(aRuleDetail != eRuleFullInherited, \
"should not have bothered calling Compute*Data"); \
\
nsStyleContext* parentContext = aContext->GetParent(); \
GeckoStyleContext* parentContext = aContext->GetParent(); \
/* Reset structs don't inherit from first-line */ \
/* See similar code in WalkRuleTree */ \
while (parentContext && \
@ -3304,13 +3304,13 @@ struct SetFontSizeCalcOps : public css::BasicCoordCalcOps,
const nscoord mParentSize;
const nsStyleFont* const mParentFont;
nsPresContext* const mPresContext;
nsStyleContext* const mStyleContext;
GeckoStyleContext* const mStyleContext;
const bool mAtRoot;
RuleNodeCacheConditions& mConditions;
SetFontSizeCalcOps(nscoord aParentSize, const nsStyleFont* aParentFont,
nsPresContext* aPresContext,
nsStyleContext* aStyleContext,
GeckoStyleContext* aStyleContext,
bool aAtRoot,
RuleNodeCacheConditions& aConditions)
: mParentSize(aParentSize),
@ -3355,7 +3355,7 @@ struct SetFontSizeCalcOps : public css::BasicCoordCalcOps,
/* static */ void
nsRuleNode::SetFontSize(nsPresContext* aPresContext,
nsStyleContext* aContext,
GeckoStyleContext* aContext,
const nsRuleData* aRuleData,
const nsStyleFont* aFont,
const nsStyleFont* aParentFont,
@ -3534,7 +3534,7 @@ nsRuleNode::ComputeSystemFont(nsFont* aSystemFont, LookAndFeel::FontID aFontID,
}
/* static */ void
nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
nsRuleNode::SetFont(nsPresContext* aPresContext, GeckoStyleContext* aContext,
uint8_t aGenericFontID, const nsRuleData* aRuleData,
const nsStyleFont* aParentFont,
nsStyleFont* aFont, bool aUsedStartStruct,
@ -4161,14 +4161,14 @@ nsRuleNode::ComputeFontVariations(const nsCSSValuePairList* aVariationsList,
// - re-apply cascading rules from there without caching intermediate values
/* static */ void
nsRuleNode::SetGenericFont(nsPresContext* aPresContext,
nsStyleContext* aContext,
GeckoStyleContext* aContext,
uint8_t aGenericFontID,
nsStyleFont* aFont)
{
// walk up the contexts until a context with the desired generic font
AutoTArray<nsStyleContext*, 8> contextPath;
AutoTArray<GeckoStyleContext*, 8> contextPath;
contextPath.AppendElement(aContext);
nsStyleContext* higherContext = aContext->GetParent();
GeckoStyleContext* higherContext = aContext->GetParent();
while (higherContext) {
if (higherContext->StyleFont()->mGenericID == aGenericFontID) {
// done walking up the higher contexts
@ -4201,7 +4201,7 @@ nsRuleNode::SetGenericFont(nsPresContext* aPresContext,
void* dataStorage = alloca(nprops * sizeof(nsCSSValue));
for (int32_t i = contextPath.Length() - 1; i >= 0; --i) {
nsStyleContext* context = contextPath[i];
GeckoStyleContext* context = contextPath[i];
AutoCSSValueArray dataArray(dataStorage, nprops);
nsRuleData ruleData(NS_STYLE_INHERIT_BIT(Font), dataArray.get(),
@ -4254,7 +4254,7 @@ nsRuleNode::SetGenericFont(nsPresContext* aPresContext,
const void*
nsRuleNode::ComputeFontData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext,
GeckoStyleContext* aContext,
nsRuleNode* aHighestNode,
const RuleDetail aRuleDetail,
const RuleNodeCacheConditions aConditions)
@ -4362,7 +4362,7 @@ inline uint32_t ListLength(const T* aList)
static already_AddRefed<nsCSSShadowArray>
GetShadowData(const nsCSSValueList* aList,
nsStyleContext* aContext,
GeckoStyleContext* aContext,
bool aIsBoxShadow,
nsPresContext* aPresContext,
RuleNodeCacheConditions& aConditions)
@ -4503,11 +4503,11 @@ struct LengthNumberCalcObj
struct LengthNumberCalcOps : public css::FloatCoeffsAlreadyNormalizedOps
{
typedef LengthNumberCalcObj result_type;
nsStyleContext* const mStyleContext;
GeckoStyleContext* const mStyleContext;
nsPresContext* const mPresContext;
RuleNodeCacheConditions& mConditions;
LengthNumberCalcOps(nsStyleContext* aStyleContext,
LengthNumberCalcOps(GeckoStyleContext* aStyleContext,
nsPresContext* aPresContext,
RuleNodeCacheConditions& aConditions)
: mStyleContext(aStyleContext),
@ -4585,7 +4585,7 @@ struct LengthNumberCalcOps : public css::FloatCoeffsAlreadyNormalizedOps
struct SetLineHeightCalcOps : public LengthNumberCalcOps
{
SetLineHeightCalcOps(nsStyleContext* aStyleContext,
SetLineHeightCalcOps(GeckoStyleContext* aStyleContext,
nsPresContext* aPresContext,
RuleNodeCacheConditions& aConditions)
: LengthNumberCalcOps(aStyleContext, aPresContext, aConditions)
@ -4622,7 +4622,7 @@ struct SetLineHeightCalcOps : public LengthNumberCalcOps
const void*
nsRuleNode::ComputeTextData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext,
GeckoStyleContext* aContext,
nsRuleNode* aHighestNode,
const RuleDetail aRuleDetail,
const RuleNodeCacheConditions aConditions)
@ -4748,7 +4748,7 @@ nsRuleNode::ComputeTextData(void* aStartStruct,
NS_STYLE_TEXT_ALIGN_MATCH_PARENT ==
textAlignValue->GetIntValue()) {
conditions.SetUncacheable();
nsStyleContext* parent = aContext->GetParent();
GeckoStyleContext* parent = aContext->GetParent();
if (parent) {
uint8_t parentAlign = parentText->mTextAlign;
uint8_t parentDirection = parent->StyleVisibility()->mDirection;
@ -5004,7 +5004,7 @@ nsRuleNode::ComputeTextData(void* aStartStruct,
const void*
nsRuleNode::ComputeTextResetData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext,
GeckoStyleContext* aContext,
nsRuleNode* aHighestNode,
const RuleDetail aRuleDetail,
const RuleNodeCacheConditions aConditions)
@ -5143,7 +5143,7 @@ nsRuleNode::ComputeTextResetData(void* aStartStruct,
const void*
nsRuleNode::ComputeUserInterfaceData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext,
GeckoStyleContext* aContext,
nsRuleNode* aHighestNode,
const RuleDetail aRuleDetail,
const RuleNodeCacheConditions aConditions)
@ -5233,7 +5233,7 @@ nsRuleNode::ComputeUserInterfaceData(void* aStartStruct,
const void*
nsRuleNode::ComputeUIResetData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext,
GeckoStyleContext* aContext,
nsRuleNode* aHighestNode,
const RuleDetail aRuleDetail,
const RuleNodeCacheConditions aConditions)
@ -5487,7 +5487,7 @@ GetWillChangeBitFieldFromPropFlags(const nsCSSPropertyID& aProp)
const void*
nsRuleNode::ComputeDisplayData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext,
GeckoStyleContext* aContext,
nsRuleNode* aHighestNode,
const RuleDetail aRuleDetail,
const RuleNodeCacheConditions aConditions)
@ -6584,7 +6584,7 @@ nsRuleNode::ComputeDisplayData(void* aStartStruct,
const void*
nsRuleNode::ComputeVisibilityData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext,
GeckoStyleContext* aContext,
nsRuleNode* aHighestNode,
const RuleDetail aRuleDetail,
const RuleNodeCacheConditions aConditions)
@ -6682,7 +6682,7 @@ nsRuleNode::ComputeVisibilityData(void* aStartStruct,
const void*
nsRuleNode::ComputeColorData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext,
GeckoStyleContext* aContext,
nsRuleNode* aHighestNode,
const RuleDetail aRuleDetail,
const RuleNodeCacheConditions aConditions)
@ -6718,7 +6718,7 @@ struct BackgroundItemComputer {
template <>
struct BackgroundItemComputer<nsCSSValueList, uint8_t>
{
static void ComputeValue(nsStyleContext* aStyleContext,
static void ComputeValue(GeckoStyleContext* aStyleContext,
const nsCSSValueList* aSpecifiedValue,
uint8_t& aComputedValue,
RuleNodeCacheConditions& aConditions)
@ -6731,7 +6731,7 @@ struct BackgroundItemComputer<nsCSSValueList, uint8_t>
template <>
struct BackgroundItemComputer<nsCSSValuePairList, nsStyleImageLayers::Repeat>
{
static void ComputeValue(nsStyleContext* aStyleContext,
static void ComputeValue(GeckoStyleContext* aStyleContext,
const nsCSSValuePairList* aSpecifiedValue,
nsStyleImageLayers::Repeat& aComputedValue,
RuleNodeCacheConditions& aConditions)
@ -6792,7 +6792,7 @@ struct BackgroundItemComputer<nsCSSValuePairList, nsStyleImageLayers::Repeat>
template <>
struct BackgroundItemComputer<nsCSSValueList, nsStyleImage>
{
static void ComputeValue(nsStyleContext* aStyleContext,
static void ComputeValue(GeckoStyleContext* aStyleContext,
const nsCSSValueList* aSpecifiedValue,
nsStyleImage& aComputedValue,
RuleNodeCacheConditions& aConditions)
@ -6807,7 +6807,7 @@ struct BackgroundItemComputer<nsCSSValueList, T>
{
typedef typename EnableIf<IsEnum<T>::value, T>::Type ComputedType;
static void ComputeValue(nsStyleContext* aStyleContext,
static void ComputeValue(GeckoStyleContext* aStyleContext,
const nsCSSValueList* aSpecifiedValue,
ComputedType& aComputedValue,
RuleNodeCacheConditions& aConditions)
@ -6822,7 +6822,7 @@ struct BackgroundItemComputer<nsCSSValueList, T>
* which represent an edge and an offset from that edge.
*/
static void
ComputePositionCoord(nsStyleContext* aStyleContext,
ComputePositionCoord(GeckoStyleContext* aStyleContext,
const nsCSSValue& aEdge,
const nsCSSValue& aOffset,
Position::Coord* aResult,
@ -6873,7 +6873,7 @@ ComputePositionCoord(nsStyleContext* aStyleContext,
/* Helper function to convert a CSS <position> specified value into its
* computed-style form. */
static void
ComputePositionValue(nsStyleContext* aStyleContext,
ComputePositionValue(GeckoStyleContext* aStyleContext,
const nsCSSValue& aValue,
Position& aComputedValue,
RuleNodeCacheConditions& aConditions)
@ -6910,7 +6910,7 @@ ComputePositionValue(nsStyleContext* aStyleContext,
/* Helper function to convert the -x or -y part of a CSS <position> specified
* value into its computed-style form. */
static void
ComputePositionCoordValue(nsStyleContext* aStyleContext,
ComputePositionCoordValue(GeckoStyleContext* aStyleContext,
const nsCSSValue& aValue,
Position::Coord& aComputedValue,
RuleNodeCacheConditions& aConditions)
@ -6953,7 +6953,7 @@ static const BackgroundSizeAxis gBGSizeAxes[] = {
template <>
struct BackgroundItemComputer<nsCSSValuePairList, nsStyleImageLayers::Size>
{
static void ComputeValue(nsStyleContext* aStyleContext,
static void ComputeValue(GeckoStyleContext* aStyleContext,
const nsCSSValuePairList* aSpecifiedValue,
nsStyleImageLayers::Size& aComputedValue,
RuleNodeCacheConditions& aConditions)
@ -7036,7 +7036,7 @@ struct BackgroundItemComputer<nsCSSValuePairList, nsStyleImageLayers::Size>
template <class ComputedValueItem>
static void
SetImageLayerList(nsStyleContext* aStyleContext,
SetImageLayerList(GeckoStyleContext* aStyleContext,
const nsCSSValue& aValue,
nsStyleAutoArray<nsStyleImageLayers::Layer>& aLayers,
const nsStyleAutoArray<nsStyleImageLayers::Layer>& aParentLayers,
@ -7105,7 +7105,7 @@ SetImageLayerList(nsStyleContext* aStyleContext,
// SetImageLayerList generic enough to handle both cases.
static void
SetImageLayerPositionCoordList(
nsStyleContext* aStyleContext,
GeckoStyleContext* aStyleContext,
const nsCSSValue& aValue,
nsStyleAutoArray<nsStyleImageLayers::Layer>& aLayers,
const nsStyleAutoArray<nsStyleImageLayers::Layer>& aParentLayers,
@ -7171,7 +7171,7 @@ SetImageLayerPositionCoordList(
template <class ComputedValueItem>
static void
SetImageLayerPairList(nsStyleContext* aStyleContext,
SetImageLayerPairList(GeckoStyleContext* aStyleContext,
const nsCSSValue& aValue,
nsStyleAutoArray<nsStyleImageLayers::Layer>& aLayers,
const nsStyleAutoArray<nsStyleImageLayers::Layer>& aParentLayers,
@ -7319,7 +7319,7 @@ nsRuleNode::FillAllBackgroundLists(nsStyleImageLayers& aImage,
const void*
nsRuleNode::ComputeBackgroundData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext,
GeckoStyleContext* aContext,
nsRuleNode* aHighestNode,
const RuleDetail aRuleDetail,
const RuleNodeCacheConditions aConditions)
@ -7440,7 +7440,7 @@ nsRuleNode::ComputeBackgroundData(void* aStartStruct,
const void*
nsRuleNode::ComputeMarginData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext,
GeckoStyleContext* aContext,
nsRuleNode* aHighestNode,
const RuleDetail aRuleDetail,
const RuleNodeCacheConditions aConditions)
@ -7545,7 +7545,7 @@ SetBorderImageSlice(const nsCSSValue& aValue,
const void*
nsRuleNode::ComputeBorderData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext,
GeckoStyleContext* aContext,
nsRuleNode* aHighestNode,
const RuleDetail aRuleDetail,
const RuleNodeCacheConditions aConditions)
@ -7804,7 +7804,7 @@ nsRuleNode::ComputeBorderData(void* aStartStruct,
const void*
nsRuleNode::ComputePaddingData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext,
GeckoStyleContext* aContext,
nsRuleNode* aHighestNode,
const RuleDetail aRuleDetail,
const RuleNodeCacheConditions aConditions)
@ -7832,7 +7832,7 @@ nsRuleNode::ComputePaddingData(void* aStartStruct,
const void*
nsRuleNode::ComputeOutlineData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext,
GeckoStyleContext* aContext,
nsRuleNode* aHighestNode,
const RuleDetail aRuleDetail,
const RuleNodeCacheConditions aConditions)
@ -7916,7 +7916,7 @@ nsRuleNode::ComputeOutlineData(void* aStartStruct,
const void*
nsRuleNode::ComputeListData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext,
GeckoStyleContext* aContext,
nsRuleNode* aHighestNode,
const RuleDetail aRuleDetail,
const RuleNodeCacheConditions aConditions)
@ -8107,7 +8107,7 @@ nsRuleNode::ComputeListData(void* aStartStruct,
static void
SetGridTrackBreadth(const nsCSSValue& aValue,
nsStyleCoord& aResult,
nsStyleContext* aStyleContext,
GeckoStyleContext* aStyleContext,
nsPresContext* aPresContext,
RuleNodeCacheConditions& aConditions)
{
@ -8135,7 +8135,7 @@ static void
SetGridTrackSize(const nsCSSValue& aValue,
nsStyleCoord& aResultMin,
nsStyleCoord& aResultMax,
nsStyleContext* aStyleContext,
GeckoStyleContext* aStyleContext,
nsPresContext* aPresContext,
RuleNodeCacheConditions& aConditions)
{
@ -8171,7 +8171,7 @@ SetGridAutoColumnsRows(const nsCSSValue& aValue,
nsStyleCoord& aResultMax,
const nsStyleCoord& aParentValueMin,
const nsStyleCoord& aParentValueMax,
nsStyleContext* aStyleContext,
GeckoStyleContext* aStyleContext,
nsPresContext* aPresContext,
RuleNodeCacheConditions& aConditions)
@ -8221,7 +8221,7 @@ static void
SetGridTrackList(const nsCSSValue& aValue,
nsStyleGridTemplate& aResult,
const nsStyleGridTemplate& aParentValue,
nsStyleContext* aStyleContext,
GeckoStyleContext* aStyleContext,
nsPresContext* aPresContext,
RuleNodeCacheConditions& aConditions)
@ -8413,7 +8413,7 @@ SetGridLine(const nsCSSValue& aValue,
const void*
nsRuleNode::ComputePositionData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext,
GeckoStyleContext* aContext,
nsRuleNode* aHighestNode,
const RuleDetail aRuleDetail,
const RuleNodeCacheConditions aConditions)
@ -8756,7 +8756,7 @@ nsRuleNode::ComputePositionData(void* aStartStruct,
const void*
nsRuleNode::ComputeTableData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext,
GeckoStyleContext* aContext,
nsRuleNode* aHighestNode,
const RuleDetail aRuleDetail,
const RuleNodeCacheConditions aConditions)
@ -8782,7 +8782,7 @@ nsRuleNode::ComputeTableData(void* aStartStruct,
const void*
nsRuleNode::ComputeTableBorderData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext,
GeckoStyleContext* aContext,
nsRuleNode* aHighestNode,
const RuleDetail aRuleDetail,
const RuleNodeCacheConditions aConditions)
@ -8839,7 +8839,7 @@ nsRuleNode::ComputeTableBorderData(void* aStartStruct,
const void*
nsRuleNode::ComputeContentData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext,
GeckoStyleContext* aContext,
nsRuleNode* aHighestNode,
const RuleDetail aRuleDetail,
const RuleNodeCacheConditions aConditions)
@ -9062,7 +9062,7 @@ nsRuleNode::ComputeContentData(void* aStartStruct,
const void*
nsRuleNode::ComputeXULData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext,
GeckoStyleContext* aContext,
nsRuleNode* aHighestNode,
const RuleDetail aRuleDetail,
const RuleNodeCacheConditions aConditions)
@ -9121,7 +9121,7 @@ nsRuleNode::ComputeXULData(void* aStartStruct,
const void*
nsRuleNode::ComputeColumnData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext,
GeckoStyleContext* aContext,
nsRuleNode* aHighestNode,
const RuleDetail aRuleDetail,
const RuleNodeCacheConditions aConditions)
@ -9217,7 +9217,7 @@ nsRuleNode::ComputeColumnData(void* aStartStruct,
static void
SetSVGPaint(const nsCSSValue& aValue, const nsStyleSVGPaint& parentPaint,
nsPresContext* aPresContext, nsStyleContext *aContext,
nsPresContext* aPresContext, GeckoStyleContext *aContext,
nsStyleSVGPaint& aResult, nsStyleSVGPaintType aInitialPaintType,
RuleNodeCacheConditions& aConditions)
{
@ -9376,7 +9376,7 @@ nsRuleNode::FillAllMaskLists(nsStyleImageLayers& aMask,
const void*
nsRuleNode::ComputeSVGData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext,
GeckoStyleContext* aContext,
nsRuleNode* aHighestNode,
const RuleDetail aRuleDetail,
const RuleNodeCacheConditions aConditions)
@ -9682,7 +9682,7 @@ nsRuleNode::ComputeSVGData(void* aStartStruct,
static already_AddRefed<StyleBasicShape>
GetStyleBasicShapeFromCSSValue(const nsCSSValue& aValue,
nsStyleContext* aStyleContext,
GeckoStyleContext* aStyleContext,
nsPresContext* aPresContext,
RuleNodeCacheConditions& aConditions)
{
@ -9835,7 +9835,7 @@ static void
SetStyleShapeSourceToCSSValue(
StyleShapeSource* aShapeSource,
const nsCSSValue* aValue,
nsStyleContext* aStyleContext,
GeckoStyleContext* aStyleContext,
nsPresContext* aPresContext,
RuleNodeCacheConditions& aConditions)
{
@ -9873,7 +9873,7 @@ SetStyleShapeSourceToCSSValue(
static bool
SetStyleFilterToCSSValue(nsStyleFilter* aStyleFilter,
const nsCSSValue& aValue,
nsStyleContext* aStyleContext,
GeckoStyleContext* aStyleContext,
nsPresContext* aPresContext,
RuleNodeCacheConditions& aConditions)
{
@ -9931,7 +9931,7 @@ SetStyleFilterToCSSValue(nsStyleFilter* aStyleFilter,
const void*
nsRuleNode::ComputeSVGResetData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext,
GeckoStyleContext* aContext,
nsRuleNode* aHighestNode,
const RuleDetail aRuleDetail,
const RuleNodeCacheConditions aConditions)
@ -10156,7 +10156,7 @@ nsRuleNode::ComputeSVGResetData(void* aStartStruct,
const void*
nsRuleNode::ComputeVariablesData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext,
GeckoStyleContext* aContext,
nsRuleNode* aHighestNode,
const RuleDetail aRuleDetail,
const RuleNodeCacheConditions aConditions)
@ -10178,7 +10178,7 @@ nsRuleNode::ComputeVariablesData(void* aStartStruct,
const void*
nsRuleNode::ComputeEffectsData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext,
GeckoStyleContext* aContext,
nsRuleNode* aHighestNode,
const RuleDetail aRuleDetail,
const RuleNodeCacheConditions aConditions)
@ -10338,7 +10338,7 @@ nsRuleNode::ComputeEffectsData(void* aStartStruct,
const void*
nsRuleNode::GetStyleData(nsStyleStructID aSID,
nsStyleContext* aContext,
GeckoStyleContext* aContext,
bool aComputeData)
{
NS_ASSERTION(IsUsedDirectly(),
@ -10401,12 +10401,14 @@ nsRuleNode::HasAuthorSpecifiedRules(nsStyleContext* aStyleContext,
bool aAuthorColorsAllowed)
{
#ifdef MOZ_STYLO
if (aStyleContext->StyleSource().IsServoComputedValues()) {
if (aStyleContext->IsServo()) {
NS_WARNING("stylo: nsRuleNode::HasAuthorSpecifiedRules not implemented");
return true;
}
#endif
RefPtr<GeckoStyleContext> styleContext = aStyleContext->AsGecko();
uint32_t inheritBits = 0;
if (ruleTypeMask & NS_AUTHOR_SPECIFIED_BACKGROUND)
inheritBits |= NS_STYLE_INHERIT_BIT(Background);
@ -10452,9 +10454,9 @@ nsRuleNode::HasAuthorSpecifiedRules(nsStyleContext* aStyleContext,
void* dataStorage = alloca(nprops * sizeof(nsCSSValue));
AutoCSSValueArray dataArray(dataStorage, nprops);
/* We're relying on the use of |aStyleContext| not mutating it! */
/* We're relying on the use of |styleContext| not mutating it! */
nsRuleData ruleData(inheritBits, dataArray.get(),
aStyleContext->PresContext(), aStyleContext);
styleContext->PresContext(), styleContext);
if (ruleTypeMask & NS_AUTHOR_SPECIFIED_BACKGROUND) {
ruleData.mValueOffsets[eStyleStruct_Background] = backgroundOffset;
@ -10552,7 +10554,7 @@ nsRuleNode::HasAuthorSpecifiedRules(nsStyleContext* aStyleContext,
}
}
nsStyleContext* styleContext = aStyleContext;
GeckoStyleContext* styleContextRef = styleContext;
// We need to be careful not to count styles covered up by user-important or
// UA-important declarations. But we do want to catch explicit inherit
@ -10563,7 +10565,7 @@ nsRuleNode::HasAuthorSpecifiedRules(nsStyleContext* aStyleContext,
bool haveExplicitUAInherit;
do {
haveExplicitUAInherit = false;
for (nsRuleNode* ruleNode = styleContext->RuleNode(); ruleNode;
for (nsRuleNode* ruleNode = styleContextRef->RuleNode(); ruleNode;
ruleNode = ruleNode->GetParent()) {
nsIStyleRule *rule = ruleNode->GetRule();
if (rule) {
@ -10630,7 +10632,7 @@ nsRuleNode::HasAuthorSpecifiedRules(nsStyleContext* aStyleContext,
for (uint32_t i = 0; i < nValues; ++i)
if (values[i]->GetUnit() == eCSSUnit_DummyInherit)
values[i]->Reset();
styleContext = styleContext->GetParent();
styleContextRef = styleContextRef->GetParent();
}
} while (haveExplicitUAInherit && styleContext);
@ -10640,7 +10642,7 @@ nsRuleNode::HasAuthorSpecifiedRules(nsStyleContext* aStyleContext,
/* static */ void
nsRuleNode::ComputePropertiesOverridingAnimation(
const nsTArray<nsCSSPropertyID>& aProperties,
nsStyleContext* aStyleContext,
GeckoStyleContext* aStyleContext,
nsCSSPropertyIDSet& aPropertiesOverridden)
{
/*
@ -10740,14 +10742,14 @@ nsRuleNode::ComputeColor(const nsCSSValue& aValue, nsPresContext* aPresContext,
}
/* static */ bool
nsRuleNode::ParentHasPseudoElementData(nsStyleContext* aContext)
nsRuleNode::ParentHasPseudoElementData(GeckoStyleContext* aContext)
{
nsStyleContext* parent = aContext->GetParent();
GeckoStyleContext* parent = aContext->GetParent();
return parent && parent->HasPseudoElementData();
}
/* static */ void
nsRuleNode::StoreStyleOnContext(nsStyleContext* aContext,
nsRuleNode::StoreStyleOnContext(GeckoStyleContext* aContext,
nsStyleStructID aSID,
void* aStruct)
{
@ -10757,7 +10759,7 @@ nsRuleNode::StoreStyleOnContext(nsStyleContext* aContext,
#ifdef DEBUG
bool
nsRuleNode::ContextHasCachedData(nsStyleContext* aContext,
nsRuleNode::ContextHasCachedData(GeckoStyleContext* aContext,
nsStyleStructID aSID)
{
return !!aContext->GetCachedStyleData(aSID);

Просмотреть файл

@ -25,13 +25,16 @@ class nsCSSPropertyIDSet;
class nsCSSValue;
class nsFontMetrics;
class nsIStyleRule;
class nsStyleContext;
class nsStyleCoord;
struct nsCSSRect;
struct nsCSSValueList;
struct nsCSSValuePairList;
struct nsRuleData;
namespace mozilla {
class GeckoStyleContext;
}
struct nsInheritedStyleData
{
mozilla::RangedArray<void*,
@ -163,7 +166,7 @@ struct nsConditionalResetStyleData
}
void* GetStyleData(nsStyleStructID aSID,
nsStyleContext* aStyleContext,
mozilla::GeckoStyleContext* aStyleContext,
bool aCanComputeData) const {
if (!(mConditionalBits & GetBitForSID(aSID))) {
return mEntries[aSID];
@ -183,7 +186,7 @@ struct nsConditionalResetStyleData
private:
// non-inline helper for GetStyleData
void* GetConditionalStyleData(nsStyleStructID aSID,
nsStyleContext* aStyleContext) const;
mozilla::GeckoStyleContext* aStyleContext) const;
public:
void SetStyleData(nsStyleStructID aSID, void* aStyleStruct) {
@ -284,7 +287,7 @@ struct nsCachedStyleData
}
void* NS_FASTCALL GetStyleData(const nsStyleStructID aSID,
nsStyleContext* aStyleContext,
mozilla::GeckoStyleContext* aStyleContext,
bool aCanComputeData) {
if (IsReset(aSID)) {
if (mResetData) {
@ -320,7 +323,7 @@ struct nsCachedStyleData
mInheritedData->mStyleStructs[eStyleStruct_##name_]) : nullptr; \
}
#define STYLE_STRUCT_RESET(name_, checkdata_cb_) \
nsStyle##name_ * NS_FASTCALL GetStyle##name_ (nsStyleContext* aContext, \
nsStyle##name_ * NS_FASTCALL GetStyle##name_ (mozilla::GeckoStyleContext* aContext, \
bool aCanComputeData) { \
return mResetData ? static_cast<nsStyle##name_*>( \
mResetData->GetStyleData(eStyleStruct_##name_, aContext, \
@ -355,9 +358,9 @@ struct nsCachedStyleData
* destroyed when their reference-count drops to zero, but are instead
* destroyed during a GC sweep.
*
* An nsStyleContext, which represents the computed style data for an
* An mozilla::GeckoStyleContext, which represents the computed style data for an
* element, points to an nsRuleNode. The path from the root of the rule
* tree to the nsStyleContext's mRuleNode gives the list of the rules
* tree to the mozilla::GeckoStyleContext's mRuleNode gives the list of the rules
* matched, from least important in the cascading order to most
* important in the cascading order.
*
@ -374,14 +377,14 @@ struct nsCachedStyleData
* 1. [mainly reset structs] When a style data struct will contain the
* same computed value for any elements that match the same set of
* rules (common for reset structs), it can be stored on the
* nsRuleNode instead of on the nsStyleContext.
* nsRuleNode instead of on the mozilla::GeckoStyleContext.
* 2. [only? reset structs] When (1) occurs, and an nsRuleNode doesn't
* have any rules that change the values in the struct, the
* nsRuleNode can share that struct with its parent nsRuleNode.
* 3. [mainly inherited structs] When an element doesn't match any
* rules that change the value of a property (or, in the edge case,
* when all the values specified are 'inherit'), the nsStyleContext
* can use the same nsStyle* struct as its parent nsStyleContext.
* when all the values specified are 'inherit'), the mozilla::GeckoStyleContext
* can use the same nsStyle* struct as its parent mozilla::GeckoStyleContext.
*
* Since the data represented by an nsIStyleRule are immutable, the data
* represented by an nsRuleNode are also immutable.
@ -565,11 +568,11 @@ protected:
void PropagateDependentBit(nsStyleStructID aSID, nsRuleNode* aHighestNode,
void* aStruct);
void PropagateNoneBit(uint32_t aBit, nsRuleNode* aHighestNode);
static void PropagateGrandancestorBit(nsStyleContext* aContext,
nsStyleContext* aContextInheritedFrom);
static void PropagateGrandancestorBit(mozilla::GeckoStyleContext* aContext,
mozilla::GeckoStyleContext* aContextInheritedFrom);
const void* SetDefaultOnRoot(const nsStyleStructID aSID,
nsStyleContext* aContext);
mozilla::GeckoStyleContext* aContext);
/**
* Resolves any property values in aRuleData for a given style struct that
@ -581,127 +584,127 @@ protected:
*/
static bool ResolveVariableReferences(const nsStyleStructID aSID,
nsRuleData* aRuleData,
nsStyleContext* aContext);
mozilla::GeckoStyleContext* aContext);
const void*
WalkRuleTree(const nsStyleStructID aSID, nsStyleContext* aContext);
WalkRuleTree(const nsStyleStructID aSID, mozilla::GeckoStyleContext* aContext);
const void*
ComputeDisplayData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode,
mozilla::GeckoStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail,
const mozilla::RuleNodeCacheConditions aConditions);
const void*
ComputeVisibilityData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode,
mozilla::GeckoStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail,
const mozilla::RuleNodeCacheConditions aConditions);
const void*
ComputeFontData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode,
mozilla::GeckoStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail,
const mozilla::RuleNodeCacheConditions aConditions);
const void*
ComputeColorData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode,
mozilla::GeckoStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail,
const mozilla::RuleNodeCacheConditions aConditions);
const void*
ComputeBackgroundData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode,
mozilla::GeckoStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail,
const mozilla::RuleNodeCacheConditions aConditions);
const void*
ComputeMarginData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode,
mozilla::GeckoStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail,
const mozilla::RuleNodeCacheConditions aConditions);
const void*
ComputeBorderData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode,
mozilla::GeckoStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail,
const mozilla::RuleNodeCacheConditions aConditions);
const void*
ComputePaddingData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode,
mozilla::GeckoStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail,
const mozilla::RuleNodeCacheConditions aConditions);
const void*
ComputeOutlineData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode,
mozilla::GeckoStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail,
const mozilla::RuleNodeCacheConditions aConditions);
const void*
ComputeListData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode,
mozilla::GeckoStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail,
const mozilla::RuleNodeCacheConditions aConditions);
const void*
ComputePositionData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode,
mozilla::GeckoStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail,
const mozilla::RuleNodeCacheConditions aConditions);
const void*
ComputeTableData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode,
mozilla::GeckoStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail,
const mozilla::RuleNodeCacheConditions aConditions);
const void*
ComputeTableBorderData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode,
mozilla::GeckoStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail,
const mozilla::RuleNodeCacheConditions aConditions);
const void*
ComputeContentData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode,
mozilla::GeckoStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail,
const mozilla::RuleNodeCacheConditions aConditions);
const void*
ComputeTextData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode,
mozilla::GeckoStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail,
const mozilla::RuleNodeCacheConditions aConditions);
const void*
ComputeTextResetData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode,
mozilla::GeckoStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail,
const mozilla::RuleNodeCacheConditions aConditions);
const void*
ComputeUserInterfaceData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext,
mozilla::GeckoStyleContext* aContext,
nsRuleNode* aHighestNode,
RuleDetail aRuleDetail,
const mozilla::RuleNodeCacheConditions aConditions);
@ -709,55 +712,55 @@ protected:
const void*
ComputeUIResetData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode,
mozilla::GeckoStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail,
const mozilla::RuleNodeCacheConditions aConditions);
const void*
ComputeXULData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode,
mozilla::GeckoStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail,
const mozilla::RuleNodeCacheConditions aConditions);
const void*
ComputeColumnData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode,
mozilla::GeckoStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail,
const mozilla::RuleNodeCacheConditions aConditions);
const void*
ComputeSVGData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode,
mozilla::GeckoStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail,
const mozilla::RuleNodeCacheConditions aConditions);
const void*
ComputeSVGResetData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode,
mozilla::GeckoStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail,
const mozilla::RuleNodeCacheConditions aConditions);
const void*
ComputeVariablesData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode,
mozilla::GeckoStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail,
const mozilla::RuleNodeCacheConditions aConditions);
const void*
ComputeEffectsData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode,
mozilla::GeckoStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail,
const mozilla::RuleNodeCacheConditions aConditions);
// helpers for |ComputeFontData| that need access to |mNoneBits|:
static void SetFontSize(nsPresContext* aPresContext,
nsStyleContext* aContext,
mozilla::GeckoStyleContext* aContext,
const nsRuleData* aRuleData,
const nsStyleFont* aFont,
const nsStyleFont* aParentFont,
@ -770,7 +773,7 @@ protected:
mozilla::RuleNodeCacheConditions& aConditions);
static void SetFont(nsPresContext* aPresContext,
nsStyleContext* aContext,
mozilla::GeckoStyleContext* aContext,
uint8_t aGenericFontID,
const nsRuleData* aRuleData,
const nsStyleFont* aParentFont,
@ -779,7 +782,7 @@ protected:
mozilla::RuleNodeCacheConditions& aConditions);
static void SetGenericFont(nsPresContext* aPresContext,
nsStyleContext* aContext,
mozilla::GeckoStyleContext* aContext,
uint8_t aGenericFontID,
nsStyleFont* aFont);
@ -890,7 +893,7 @@ public:
nsPresContext* PresContext() const { return mPresContext; }
const void* GetStyleData(nsStyleStructID aSID,
nsStyleContext* aContext,
mozilla::GeckoStyleContext* aContext,
bool aComputeData);
void GetDiscretelyAnimatedCSSValue(nsCSSPropertyID aProperty,
@ -901,7 +904,7 @@ public:
#define STYLE_STRUCT_INHERITED(name_, checkdata_cb_) \
template<bool aComputeData> \
const nsStyle##name_* \
GetStyle##name_(nsStyleContext* aContext, uint64_t& aContextStyleBits) \
GetStyle##name_(mozilla::GeckoStyleContext* aContext, uint64_t& aContextStyleBits) \
{ \
NS_ASSERTION(IsUsedDirectly(), \
"if we ever call this on rule nodes that aren't used " \
@ -940,7 +943,7 @@ public:
#define STYLE_STRUCT_RESET(name_, checkdata_cb_) \
template<bool aComputeData> \
const nsStyle##name_* \
GetStyle##name_(nsStyleContext* aContext) \
GetStyle##name_(mozilla::GeckoStyleContext* aContext) \
{ \
NS_ASSERTION(IsUsedDirectly(), \
"if we ever call this on rule nodes that aren't used " \
@ -996,7 +999,7 @@ public:
static void
ComputePropertiesOverridingAnimation(
const nsTArray<nsCSSPropertyID>& aProperties,
nsStyleContext* aStyleContext,
mozilla::GeckoStyleContext* aStyleContext,
nsCSSPropertyIDSet& aPropertiesOverridden);
// Expose this so media queries can use it
@ -1091,7 +1094,7 @@ public:
nsStyleContext* aStyleContext,
nscolor& aResult);
static bool ParentHasPseudoElementData(nsStyleContext* aContext);
static bool ParentHasPseudoElementData(mozilla::GeckoStyleContext* aContext);
static void ComputeTimingFunction(const nsCSSValue& aValue,
nsTimingFunction& aResult);
@ -1113,12 +1116,12 @@ private:
#ifdef DEBUG
// non-inline helper function to allow assertions without incomplete
// type errors
bool ContextHasCachedData(nsStyleContext* aContext, nsStyleStructID aSID);
bool ContextHasCachedData(mozilla::GeckoStyleContext* aContext, nsStyleStructID aSID);
#endif
// Store style struct on the style context and tell the style context
// that it doesn't own the data
static void StoreStyleOnContext(nsStyleContext* aContext,
static void StoreStyleOnContext(mozilla::GeckoStyleContext* aContext,
nsStyleStructID aSID,
void* aStruct);
};

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -11,7 +11,7 @@
#include "mozilla/Assertions.h"
#include "mozilla/RestyleLogging.h"
#include "mozilla/ServoStyleSet.h"
#include "mozilla/StyleContextSource.h"
#include "mozilla/ServoUtils.h"
#include "mozilla/StyleComplexColor.h"
#include "nsCSSAnonBoxes.h"
#include "nsStyleSet.h"
@ -21,6 +21,8 @@ class nsPresContext;
namespace mozilla {
enum class CSSPseudoElementType : uint8_t;
class GeckoStyleContext;
class ServoStyleContext;
} // namespace mozilla
extern "C" {
@ -52,53 +54,24 @@ extern "C" {
* expectation, but it makes sense in this case)
*/
class nsStyleContext final
class nsStyleContext
{
public:
/**
* Create a new style context.
* @param aParent The parent of a style context is used for CSS
* inheritance. When the element or pseudo-element
* this style context represents the style data of
* inherits a CSS property, the value comes from the
* parent style context. This means style context
* parentage must match the definitions of inheritance
* in the CSS specification.
* @param aPseudoTag The pseudo-element or anonymous box for which
* this style context represents style. Null if
* this style context is for a normal DOM element.
* @param aPseudoType Must match aPseudoTag.
* @param aRuleNode A rule node representing the ordered sequence of
* rules that any element, pseudo-element, or
* anonymous box that this style context is for
* matches. See |nsRuleNode| and |nsIStyleRule|.
* @param aSkipParentDisplayBasedStyleFixup
* If set, this flag indicates that we should skip
* the chunk of ApplyStyleFixups() that applies to
* special cases where a child element's style may
* need to be modified based on its parent's display
* value.
*/
nsStyleContext(nsStyleContext* aParent, nsIAtom* aPseudoTag,
mozilla::CSSPseudoElementType aPseudoType,
already_AddRefed<nsRuleNode> aRuleNode,
bool aSkipParentDisplayBasedStyleFixup);
#ifdef MOZ_STYLO
bool IsGecko() const { return !IsServo(); }
bool IsServo() const { return (mBits & NS_STYLE_CONTEXT_IS_GECKO) == 0; }
#else
bool IsGecko() const { return true; }
bool IsServo() const { return false; }
#endif
MOZ_DECL_STYLO_CONVERT_METHODS(mozilla::GeckoStyleContext, mozilla::ServoStyleContext);
// Version of the above that takes a ServoComputedValues instead of a Gecko
// nsRuleNode.
nsStyleContext(nsStyleContext* aParent,
nsPresContext* aPresContext,
nsIAtom* aPseudoTag,
mozilla::CSSPseudoElementType aPseudoType,
already_AddRefed<ServoComputedValues> aComputedValues);
void* operator new(size_t sz, nsPresContext* aPresContext);
void Destroy();
// These two methods are for use by ArenaRefPtr.
static mozilla::ArenaObjectID ArenaObjectID()
{
return mozilla::eArenaObjectID_nsStyleContext;
return mozilla::eArenaObjectID_GeckoStyleContext;
}
nsIPresShell* Arena();
@ -154,19 +127,9 @@ public:
return mRefCnt == 1;
}
nsPresContext* PresContext() const {
#ifdef MOZ_STYLO
return mPresContext;
#else
return mSource.AsGeckoRuleNode()->PresContext();
#endif
}
inline nsPresContext* PresContext() const;
nsStyleContext* GetParent() const {
MOZ_ASSERT(mSource.IsGeckoRuleNode(),
"This should be used only in Gecko-backed style system!");
return mParent;
}
inline mozilla::GeckoStyleContext* GetParent() const;
nsStyleContext* GetParentAllowServo() const {
return mParent;
@ -186,19 +149,6 @@ public:
bool IsPseudoElement() const { return mPseudoTag && !IsAnonBox(); }
// Find, if it already exists *and is easily findable* (i.e., near the
// start of the child list), a style context whose:
// * GetPseudo() matches aPseudoTag
// * mSource matches aSource
// * !!GetStyleIfVisited() == !!aSourceIfVisited, and, if they're
// non-null, GetStyleIfVisited()->mSource == aSourceIfVisited
// * RelevantLinkVisited() == aRelevantLinkVisited
already_AddRefed<nsStyleContext>
FindChildWithRules(const nsIAtom* aPseudoTag,
mozilla::NonOwningStyleContextSource aSource,
mozilla::NonOwningStyleContextSource aSourceIfVisited,
bool aRelevantLinkVisited);
// Does this style context or any of its ancestors have text
// decoration lines?
// Differs from nsStyleTextReset::HasTextDecorationLines, which tests
@ -242,10 +192,7 @@ public:
{ return !!(mBits & NS_STYLE_RELEVANT_LINK_VISITED); }
// Is this a style context for a link?
bool IsLinkContext() const {
return
GetStyleIfVisited() && GetStyleIfVisited()->GetParent() == GetParent();
}
inline bool IsLinkContext() const;
// Is this style context the GetStyleIfVisited() for some other style
// context?
@ -311,9 +258,6 @@ public:
bool IsShared() const
{ return !!(mBits & NS_STYLE_IS_SHARED); }
// Tell this style context to cache aStruct as the struct for aSID
void SetStyle(nsStyleStructID aSID, void* aStruct);
/**
* Returns whether this style context has cached style data for a
* given style struct and it does NOT own that struct. This can
@ -324,31 +268,11 @@ public:
return mBits & nsCachedStyleData::GetBitForSID(aSID);
}
nsRuleNode* RuleNode() {
MOZ_RELEASE_ASSERT(mSource.IsGeckoRuleNode());
return mSource.AsGeckoRuleNode();
}
inline nsRuleNode* RuleNode();
inline ServoComputedValues* ComputedValues();
void AddStyleBit(const uint64_t& aBit) { mBits |= aBit; }
/*
* Get the style data for a style struct. This is the most important
* member function of nsStyleContext. It fills in a const pointer
* to a style data struct that is appropriate for the style context's
* frame. This struct may be shared with other contexts (either in
* the rule tree or the style context tree), so it should not be
* modified.
*
* This function will NOT return null (even when out of memory) when
* given a valid style struct ID, so the result does not need to be
* null-checked.
*
* The typesafe functions below are preferred to the use of this
* function, both because they're easier to read and because they're
* faster.
*/
const void* NS_FASTCALL StyleData(nsStyleStructID aSID) MOZ_NONNULL_RETURN;
/**
* Define typesafe getter functions for each style struct by
* preprocessing the list of style structs. These functions are the
@ -356,10 +280,8 @@ public:
* const nsStyleBorder* StyleBorder();
* const nsStyleColor* StyleColor();
*/
#define STYLE_STRUCT(name_, checkdata_cb_) \
const nsStyle##name_ * Style##name_() MOZ_NONNULL_RETURN { \
return DoGetStyle##name_<true>(); \
}
#define STYLE_STRUCT(name_, checkdata_cb_) \
inline const nsStyle##name_ * Style##name_() MOZ_NONNULL_RETURN;
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
@ -370,13 +292,8 @@ public:
* this style struct. Use with care.
*/
#define STYLE_STRUCT(name_, checkdata_cb_) \
const nsStyle##name_ * ThreadsafeStyle##name_() { \
if (mozilla::ServoStyleSet::IsInServoTraversal()) { \
return Servo_GetStyle##name_(mSource.AsServoComputedValues()); \
} \
return Style##name_(); \
}
#define STYLE_STRUCT(name_, checkdata_cb_) \
inline const nsStyle##name_ * ThreadsafeStyle##name_();
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
@ -388,10 +305,8 @@ public:
*
* Perhaps this shouldn't be a public nsStyleContext API.
*/
#define STYLE_STRUCT(name_, checkdata_cb_) \
const nsStyle##name_ * PeekStyle##name_() { \
return DoGetStyle##name_<false>(); \
}
#define STYLE_STRUCT(name_, checkdata_cb_) \
inline const nsStyle##name_ * PeekStyle##name_();
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
@ -458,10 +373,7 @@ public:
/**
* Start the background image loads for this style context.
*/
void StartBackgroundImageLoads() {
// Just get our background struct; that should do the trick
StyleBackground();
}
inline void StartBackgroundImageLoads();
/**
* Moves this style context to a new parent.
@ -472,104 +384,39 @@ public:
*/
void MoveTo(nsStyleContext* aNewParent);
/**
* Swaps owned style struct pointers between this and aNewContext, on
* the assumption that aNewContext is the new style context for a frame
* and this is the old one. aStructs indicates which structs to consider
* swapping; only those which are owned in both this and aNewContext
* will be swapped.
*
* Additionally, if there are identical struct pointers for one of the
* structs indicated by aStructs, and it is not an owned struct on this,
* then the cached struct slot on this will be set to null. If the struct
* has been swapped on an ancestor, this style context (being the old one)
* will be left caching the struct pointer on the new ancestor, despite
* inheriting from the old ancestor. This is not normally a problem, as
* this style context will usually be destroyed by being released at the
* end of ElementRestyler::Restyle; but for style contexts held on to outside
* of the frame, we need to clear out the cached pointer so that if we need
* it again we'll re-fetch it from the new ancestor.
*/
void SwapStyleData(nsStyleContext* aNewContext, uint32_t aStructs);
/**
* On each descendant of this style context, clears out any cached inherited
* structs indicated in aStructs.
*/
void ClearCachedInheritedStyleDataOnDescendants(uint32_t aStructs);
/**
* Sets the NS_STYLE_INELIGIBLE_FOR_SHARING bit on this style context
* and its descendants. If it finds a descendant that has the bit
* already set, assumes that it can skip that subtree.
*/
void SetIneligibleForSharing();
#ifdef DEBUG
void List(FILE* out, int32_t aIndent, bool aListDescendants = true);
static const char* StructName(nsStyleStructID aSID);
static bool LookupStruct(const nsACString& aName, nsStyleStructID& aResult);
#endif
#ifdef RESTYLE_LOGGING
nsCString GetCachedStyleDataAsString(uint32_t aStructs);
void LogStyleContextTree(int32_t aLoggingDepth, uint32_t aStructs);
int32_t& LoggingDepth();
#endif
/**
* Return style data that is currently cached on the style context.
* Only returns the structs we cache ourselves; never consults the
* rule tree.
*
* For "internal" use only in nsStyleContext and nsRuleNode.
*/
const void* GetCachedStyleData(nsStyleStructID aSID)
{
const void* cachedData;
if (nsCachedStyleData::IsReset(aSID)) {
if (mCachedResetData) {
cachedData = mCachedResetData->mStyleStructs[aSID];
} else {
cachedData = nullptr;
}
} else {
cachedData = mCachedInheritedData.mStyleStructs[aSID];
}
return cachedData;
}
mozilla::NonOwningStyleContextSource StyleSource() const { return mSource.AsRaw(); }
private:
// Private destructor, to discourage deletion outside of Release():
~nsStyleContext();
protected:
// protected destructor to discourage deletion outside of Release()
~nsStyleContext() {}
// Where the actual destructor lives
// We use this instead of a real destructor because we need
// this to be called *before* the subclass fields are destroyed
// by the subclass destructor
void Destructor();
// Delegated Helper constructor.
nsStyleContext(nsStyleContext* aParent,
mozilla::OwningStyleContextSource&& aSource,
nsIAtom* aPseudoTag,
mozilla::CSSPseudoElementType aPseudoType);
// Helper post-contruct hook.
void FinishConstruction();
// Only does stuff in Gecko mode
void AddChild(nsStyleContext* aChild);
void RemoveChild(nsStyleContext* aChild);
void* GetUniqueStyleData(const nsStyleStructID& aSID);
void* CreateEmptyStyleData(const nsStyleStructID& aSID);
void SetStyleBits();
// Only called for Gecko-backed nsStyleContexts.
void ApplyStyleFixups(bool aSkipParentDisplayBasedStyleFixup);
const void* StyleStructFromServoComputedValues(nsStyleStructID aSID) {
switch (aSID) {
#define STYLE_STRUCT(name_, checkdata_cb_) \
case eStyleStruct_##name_: \
return Servo_GetStyle##name_(mSource.AsServoComputedValues());
return Servo_GetStyle##name_(ComputedValues());
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
default:
@ -610,139 +457,17 @@ private:
// Helper functions for GetStyle* and PeekStyle*
#define STYLE_STRUCT_INHERITED(name_, checkdata_cb_) \
template<bool aComputeData> \
const nsStyle##name_ * DoGetStyle##name_() { \
if (mSource.IsGeckoRuleNode()) { \
const nsStyle##name_ * cachedData = \
static_cast<nsStyle##name_*>( \
mCachedInheritedData.mStyleStructs[eStyleStruct_##name_]); \
if (cachedData) /* Have it cached already, yay */ \
return cachedData; \
if (!aComputeData) { \
/* We always cache inherited structs on the context when we */\
/* compute them. */ \
return nullptr; \
} \
/* Have the rulenode deal */ \
AUTO_CHECK_DEPENDENCY(eStyleStruct_##name_); \
const nsStyle##name_ * newData = \
mSource.AsGeckoRuleNode()-> \
GetStyle##name_<aComputeData>(this, mBits); \
/* always cache inherited data on the style context; the rule */\
/* node set the bit in mBits for us if needed. */ \
mCachedInheritedData.mStyleStructs[eStyleStruct_##name_] = \
const_cast<nsStyle##name_ *>(newData); \
return newData; \
} \
/** \
* Also (conservatively) set the owning bit in the parent style \
* context if we're a text node. \
* \
* This causes the parent element's style context to cache any \
* inherited structs we request for a text node, which means we \
* don't have to compute change hints for the text node, as \
* handling the change on the parent element is sufficient. \
* \
* Note, however, that we still need to request the style struct \
* of the text node itself, since we may run some fixups on it, \
* like for text-combine. \
* \
* This model is sound because for the fixed-up values to change, \
* other properties on the parent need to change too, and we'll \
* handle those change hints correctly. \
* \
* TODO(emilio): Perhaps we should remove those fixups and handle \
* those in layout instead. Those fixups are kind of expensive \
* for style sharing, and computed style of text nodes is not \
* observable. If we do that, we could assert here that the \
* inherited structs of both are the same. \
*/ \
if (mPseudoTag == nsCSSAnonBoxes::mozText && aComputeData) { \
MOZ_ASSERT(mParent); \
mParent->AddStyleBit(NS_STYLE_INHERIT_BIT(name_)); \
} \
\
const bool needToCompute = !(mBits & NS_STYLE_INHERIT_BIT(name_));\
if (!aComputeData && needToCompute) { \
return nullptr; \
} \
\
const nsStyle##name_* data = \
Servo_GetStyle##name_(mSource.AsServoComputedValues()); \
/* perform any remaining main thread work on the struct */ \
if (needToCompute) { \
MOZ_ASSERT(NS_IsMainThread()); \
MOZ_ASSERT(!mozilla::ServoStyleSet::IsInServoTraversal()); \
const_cast<nsStyle##name_*>(data)->FinishStyle(PresContext()); \
/* the Servo-backed StyleContextSource owns the struct */ \
AddStyleBit(NS_STYLE_INHERIT_BIT(name_)); \
} \
return data; \
}
const nsStyle##name_ * DoGetStyle##name_();
#define STYLE_STRUCT_RESET(name_, checkdata_cb_) \
template<bool aComputeData> \
const nsStyle##name_ * DoGetStyle##name_() { \
if (mSource.IsGeckoRuleNode()) { \
if (mCachedResetData) { \
const nsStyle##name_ * cachedData = \
static_cast<nsStyle##name_*>( \
mCachedResetData->mStyleStructs[eStyleStruct_##name_]); \
if (cachedData) /* Have it cached already, yay */ \
return cachedData; \
} \
/* Have the rulenode deal */ \
AUTO_CHECK_DEPENDENCY(eStyleStruct_##name_); \
return mSource.AsGeckoRuleNode()-> \
GetStyle##name_<aComputeData>(this); \
} \
const bool needToCompute = !(mBits & NS_STYLE_INHERIT_BIT(name_));\
if (!aComputeData && needToCompute) { \
return nullptr; \
} \
const nsStyle##name_* data = \
Servo_GetStyle##name_(mSource.AsServoComputedValues()); \
/* perform any remaining main thread work on the struct */ \
if (needToCompute) { \
const_cast<nsStyle##name_*>(data)->FinishStyle(PresContext()); \
/* the Servo-backed StyleContextSource owns the struct */ \
AddStyleBit(NS_STYLE_INHERIT_BIT(name_)); \
} \
return data; \
}
const nsStyle##name_ * DoGetStyle##name_();
#include "nsStyleStructList.h"
#undef STYLE_STRUCT_RESET
#undef STYLE_STRUCT_INHERITED
// Helper for ClearCachedInheritedStyleDataOnDescendants.
void DoClearCachedInheritedStyleDataOnDescendants(uint32_t aStructs);
#ifdef DEBUG
void AssertStructsNotUsedElsewhere(nsStyleContext* aDestroyingContext,
int32_t aLevels) const;
#endif
#ifdef RESTYLE_LOGGING
void LogStyleContextTree(bool aFirst, uint32_t aStructs);
// This only gets called under call trees where we've already checked
// that PresContext()->RestyleManager()->ShouldLogRestyle() returned true.
// It exists here just to satisfy LOG_RESTYLE's expectations.
bool ShouldLogRestyle() { return true; }
#endif
RefPtr<nsStyleContext> mParent;
// Children are kept in two circularly-linked lists. The list anchor
// is not part of the list (null for empty), and we point to the first
// child.
// mEmptyChild for children whose rule node is the root rule node, and
// mChild for other children. The order of children is not
// meaningful.
nsStyleContext* mChild;
nsStyleContext* mEmptyChild;
nsStyleContext* mPrevSibling;
nsStyleContext* mNextSibling;
// Style to be used instead for the R, G, and B components of color,
// background-color, and border-*-color if the nearest ancestor link
// element is visited (see RelevantLinkVisited()).
@ -752,29 +477,6 @@ private:
// the relevant atom.
nsCOMPtr<nsIAtom> mPseudoTag;
// The source for our style data, either a Gecko nsRuleNode or a Servo
// ComputedValues struct. This never changes after construction, except
// when it's released and nulled out during teardown.
const mozilla::OwningStyleContextSource mSource;
#ifdef MOZ_STYLO
// In Gecko, we can get this off the rule node. We make this conditional
// on stylo builds to avoid the memory bloat on release.
nsPresContext* mPresContext;
#endif
// mCachedInheritedData and mCachedResetData point to both structs that
// are owned by this style context and structs that are owned by one of
// this style context's ancestors (which are indirectly owned since this
// style context owns a reference to its parent). If the bit in |mBits|
// is set for a struct, that means that the pointer for that struct is
// owned by an ancestor or by the rule node rather than by this style context.
// Since style contexts typically have some inherited data but only sometimes
// have reset data, we always allocate the mCachedInheritedData, but only
// sometimes allocate the mCachedResetData.
nsResetStyleData* mCachedResetData; // Cached reset style data.
nsInheritedStyleData mCachedInheritedData; // Cached inherited style data
// mBits stores a number of things:
// - It records (using the style struct bits) which structs are
// inherited from the parent context or owned by the rule node (i.e.,

Просмотреть файл

@ -0,0 +1,199 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
/*
* Inlined methods for nsStyleContext. Will just redirect to
* GeckoStyleContext methods when compiled without stylo, but will do
* virtual dispatch (by checking which kind of container it is)
* in stylo mode.
*/
#ifndef nsStyleContextInlines_h
#define nsStyleContextInlines_h
#include "nsStyleContext.h"
#include "mozilla/ServoStyleContext.h"
#include "mozilla/GeckoStyleContext.h"
#include "mozilla/ServoUtils.h"
MOZ_DEFINE_STYLO_METHODS(nsStyleContext,
mozilla::GeckoStyleContext,
mozilla::ServoStyleContext);
nsRuleNode*
nsStyleContext::RuleNode()
{
MOZ_RELEASE_ASSERT(IsGecko());
return AsGecko()->RuleNode();
}
ServoComputedValues*
nsStyleContext::ComputedValues()
{
MOZ_RELEASE_ASSERT(IsServo());
return AsServo()->ComputedValues();
}
#define STYLE_STRUCT(name_, checkdata_cb_) \
const nsStyle##name_ * \
nsStyleContext::Style##name_() { \
return DoGetStyle##name_<true>(); \
} \
const nsStyle##name_ * \
nsStyleContext::ThreadsafeStyle##name_() { \
if (mozilla::ServoStyleSet::IsInServoTraversal()) { \
return Servo_GetStyle##name_(AsServo()->ComputedValues()); \
} \
return Style##name_(); \
} \
const nsStyle##name_ * nsStyleContext::PeekStyle##name_() { \
return DoGetStyle##name_<false>(); \
}
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
// Helper functions for GetStyle* and PeekStyle*
#define STYLE_STRUCT_INHERITED(name_, checkdata_cb_) \
template<bool aComputeData> \
const nsStyle##name_ * nsStyleContext::DoGetStyle##name_() { \
if (auto gecko = GetAsGecko()) { \
const nsStyle##name_ * cachedData = \
static_cast<nsStyle##name_*>( \
gecko->mCachedInheritedData \
.mStyleStructs[eStyleStruct_##name_]); \
if (cachedData) /* Have it cached already, yay */ \
return cachedData; \
if (!aComputeData) { \
/* We always cache inherited structs on the context when we */\
/* compute them. */ \
return nullptr; \
} \
/* Have the rulenode deal */ \
AUTO_CHECK_DEPENDENCY(eStyleStruct_##name_); \
const nsStyle##name_ * newData = \
gecko->RuleNode()-> \
GetStyle##name_<aComputeData>(this->AsGecko(), mBits); \
/* always cache inherited data on the style context; the rule */\
/* node set the bit in mBits for us if needed. */ \
gecko->mCachedInheritedData \
.mStyleStructs[eStyleStruct_##name_] = \
const_cast<nsStyle##name_ *>(newData); \
return newData; \
} \
auto servo = AsServo(); \
/** \
* Also (conservatively) set the owning bit in the parent style \
* context if we're a text node. \
* \
* This causes the parent element's style context to cache any \
* inherited structs we request for a text node, which means we \
* don't have to compute change hints for the text node, as \
* handling the change on the parent element is sufficient. \
* \
* Note, however, that we still need to request the style struct \
* of the text node itself, since we may run some fixups on it, \
* like for text-combine. \
* \
* This model is sound because for the fixed-up values to change, \
* other properties on the parent need to change too, and we'll \
* handle those change hints correctly. \
* \
* TODO(emilio): Perhaps we should remove those fixups and handle \
* those in layout instead. Those fixups are kind of expensive \
* for style sharing, and computed style of text nodes is not \
* observable. If we do that, we could assert here that the \
* inherited structs of both are the same. \
*/ \
if (mPseudoTag == nsCSSAnonBoxes::mozText && aComputeData) { \
MOZ_ASSERT(mParent); \
mParent->AddStyleBit(NS_STYLE_INHERIT_BIT(name_)); \
} \
\
const bool needToCompute = !(mBits & NS_STYLE_INHERIT_BIT(name_));\
if (!aComputeData && needToCompute) { \
return nullptr; \
} \
\
const nsStyle##name_* data = \
Servo_GetStyle##name_(servo->ComputedValues()); \
/* perform any remaining main thread work on the struct */ \
if (needToCompute) { \
MOZ_ASSERT(NS_IsMainThread()); \
MOZ_ASSERT(!mozilla::ServoStyleSet::IsInServoTraversal()); \
const_cast<nsStyle##name_*>(data)->FinishStyle(PresContext()); \
/* the ServoStyleContext owns the struct */ \
AddStyleBit(NS_STYLE_INHERIT_BIT(name_)); \
} \
return data; \
}
#define STYLE_STRUCT_RESET(name_, checkdata_cb_) \
template<bool aComputeData> \
const nsStyle##name_ * nsStyleContext::DoGetStyle##name_() { \
if (auto gecko = GetAsGecko()) { \
if (gecko->mCachedResetData) { \
const nsStyle##name_ * cachedData = \
static_cast<nsStyle##name_*>( \
gecko->mCachedResetData->mStyleStructs[eStyleStruct_##name_]); \
if (cachedData) /* Have it cached already, yay */ \
return cachedData; \
} \
/* Have the rulenode deal */ \
AUTO_CHECK_DEPENDENCY(eStyleStruct_##name_); \
return gecko->RuleNode()->GetStyle##name_<aComputeData>(this->AsGecko()); \
} \
auto servo = AsServo(); \
const bool needToCompute = !(mBits & NS_STYLE_INHERIT_BIT(name_)); \
if (!aComputeData && needToCompute) { \
return nullptr; \
} \
const nsStyle##name_* data = \
Servo_GetStyle##name_(servo->ComputedValues()); \
/* perform any remaining main thread work on the struct */ \
if (needToCompute) { \
const_cast<nsStyle##name_*>(data)->FinishStyle(PresContext()); \
/* the ServoStyleContext owns the struct */ \
AddStyleBit(NS_STYLE_INHERIT_BIT(name_)); \
} \
return data; \
}
#include "nsStyleStructList.h"
#undef STYLE_STRUCT_RESET
#undef STYLE_STRUCT_INHERITED
nsPresContext*
nsStyleContext::PresContext() const
{
MOZ_STYLO_FORWARD(PresContext, ())
}
mozilla::GeckoStyleContext*
nsStyleContext::GetParent() const
{
MOZ_ASSERT(IsGecko(),
"This should be used only in Gecko-backed style system!");
if (mParent) {
return mParent->AsGecko();
} else {
return nullptr;
}
}
bool
nsStyleContext::IsLinkContext() const
{
return GetStyleIfVisited() && GetStyleIfVisited()->GetParent() == GetParent();
}
void
nsStyleContext::StartBackgroundImageLoads()
{
// Just get our background struct; that should do the trick
StyleBackground();
}
#endif // nsStyleContextInlines_h

Просмотреть файл

@ -43,6 +43,7 @@
#include "mozilla/RestyleManager.h"
#include "mozilla/RestyleManagerInlines.h"
#include "nsQueryObject.h"
#include "nsStyleContextInlines.h"
#include <inttypes.h>
@ -308,7 +309,7 @@ nsStyleSet::BeginReconstruct()
// Clear any ArenaRefPtr-managed style contexts, as we don't want them
// held on to after the rule tree has been reconstructed.
PresContext()->PresShell()->ClearArenaRefPtrs(eArenaObjectID_nsStyleContext);
PresContext()->PresShell()->ClearArenaRefPtrs(eArenaObjectID_GeckoStyleContext);
// Clear our cached style contexts for non-inheriting anonymous boxes.
ClearNonInheritingStyleContexts();
@ -926,7 +927,7 @@ nsStyleSet::GetContext(nsStyleContext* aParentContext,
RefPtr<nsStyleContext> result;
if (aParentContext)
result = aParentContext->FindChildWithRules(aPseudoTag, aRuleNode,
result = aParentContext->AsGecko()->FindChildWithRules(aPseudoTag, aRuleNode,
aVisitedRuleNode,
relevantLinkVisited);

Просмотреть файл

@ -93,8 +93,10 @@ class ImageTracker;
#define NS_STYLE_HAS_CHILD_THAT_USES_RESET_STYLE 0x400000000
// See nsStyleContext::IsTextCombined
#define NS_STYLE_IS_TEXT_COMBINED 0x800000000
// Whether a style context is a Gecko or Servo context
#define NS_STYLE_CONTEXT_IS_GECKO 0x1000000000
// See nsStyleContext::GetPseudoEnum
#define NS_STYLE_CONTEXT_TYPE_SHIFT 36
#define NS_STYLE_CONTEXT_TYPE_SHIFT 37
// Additional bits for nsRuleNode's mDependentBits:
#define NS_RULE_NODE_IS_ANIMATION_RULE 0x01000000

Просмотреть файл

@ -514,7 +514,7 @@ ProcessMatrixOperator(Matrix4x4& aMatrix,
Matrix4x4 matrix2 = readTransform(aData->Item(2));
double progress = aData->Item(3).GetPercentValue();
if (aContext && aContext->StyleSource().IsServoComputedValues()) {
if (aContext && aContext->IsServo()) {
aMatrix =
OperateTransformMatrixByServo<Operator>(matrix1, matrix2, progress)
* aMatrix;

Просмотреть файл

@ -13,6 +13,7 @@
#include "nsCOMPtr.h"
#include "nsCSSRendering.h"
#include "nsIPresShell.h"
#include "mozilla/GeckoStyleContext.h"
using namespace mozilla;
@ -296,9 +297,9 @@ nsTableColGroupFrame::RemoveFrame(ChildListID aListID,
#ifdef DEBUG
nsIFrame* providerFrame;
nsStyleContext* psc = colFrame->GetParentStyleContext(&providerFrame);
if (psc->StyleSource().IsGeckoRuleNodeOrNull()) {
if (psc->IsGecko()) {
// This check code is useful only in Gecko-backed style system.
if (colFrame->StyleContext()->GetParent() == psc) {
if (static_cast<nsStyleContext*>(colFrame->StyleContext()->GetParent()) == psc) {
NS_ASSERTION(col->StyleContext() == colFrame->StyleContext() &&
col->GetContent() == colFrame->GetContent(),
"How did that happen??");

Просмотреть файл

@ -57,6 +57,8 @@ except ImportError:
def categoriesToRegex(categoryList):
return "\\(" + ', '.join(["(?P<%s>\\d+) %s" % c for c in categoryList]) + "\\)"
summaryLines = [('Successful', [('pass', 'pass'), ('loadOnly', 'load only')]),
('Unexpected', [('fail', 'unexpected fail'),
('pass', 'unexpected pass'),

Просмотреть файл

@ -118,6 +118,7 @@ nsMenuPopupFrame::nsMenuPopupFrame(nsStyleContext* aContext)
, mInContentShell(true)
, mIsMenuLocked(false)
, mMouseTransparent(false)
, mIsOffset(false)
, mHFlip(false)
, mVFlip(false)
, mAnchorType(MenuPopupAnchorType_Node)
@ -601,7 +602,7 @@ nsMenuPopupFrame::LayoutPopup(nsBoxLayoutState& aState, nsIFrame* aParentMenu,
bool
nsMenuPopupFrame::ReflowFinished()
{
SetPopupPosition(mReflowCallbackData.mAnchor, false, mReflowCallbackData.mSizedToPopup, false);
SetPopupPosition(mReflowCallbackData.mAnchor, false, mReflowCallbackData.mSizedToPopup, true);
mReflowCallbackData.Clear();
@ -1558,10 +1559,14 @@ nsMenuPopupFrame::SetPopupPosition(nsIFrame* aAnchorFrame, bool aIsMove, bool aS
#endif // #ifdef XP_MACOSX
}
// If a panel is being moved or has flip="none", don't constrain or flip it. But always do this for
nscoord oldAlignmentOffset = mAlignmentOffset;
// If a panel is being moved or has flip="none", don't constrain or flip it, in order to avoid
// visual noise when moving windows between screens. However, if a panel is already constrained
// or flipped (mIsOffset), then we want to continue to calculate this. Also, always do this for
// content shells, so that the popup doesn't extend outside the containing frame.
if (mInContentShell || (mFlip != FlipType_None &&
(!aIsMove || mPopupType != ePopupTypePanel))) {
(!aIsMove || mIsOffset || mPopupType != ePopupTypePanel))) {
int32_t appPerDev = presContext->AppUnitsPerDevPixel();
LayoutDeviceIntRect anchorRectDevPix =
LayoutDeviceIntRect::FromAppUnitsToNearest(anchorRect, appPerDev);
@ -1602,6 +1607,7 @@ nsMenuPopupFrame::SetPopupPosition(nsIFrame* aAnchorFrame, bool aIsMove, bool aS
bool endAligned = IsDirectionRTL() ?
mPopupAlignment == POPUPALIGNMENT_TOPLEFT || mPopupAlignment == POPUPALIGNMENT_BOTTOMLEFT :
mPopupAlignment == POPUPALIGNMENT_TOPRIGHT || mPopupAlignment == POPUPALIGNMENT_BOTTOMRIGHT;
nscoord preOffsetScreenPoint = screenPoint.x;
if (slideHorizontal) {
mRect.width = SlideOrResize(screenPoint.x, mRect.width, screenRect.x,
screenRect.XMost(), &mAlignmentOffset);
@ -1611,9 +1617,11 @@ nsMenuPopupFrame::SetPopupPosition(nsIFrame* aAnchorFrame, bool aIsMove, bool aS
margin.left, margin.right, offsetForContextMenu.x, hFlip,
endAligned, &mHFlip);
}
mIsOffset = preOffsetScreenPoint != screenPoint.x;
endAligned = mPopupAlignment == POPUPALIGNMENT_BOTTOMLEFT ||
mPopupAlignment == POPUPALIGNMENT_BOTTOMRIGHT;
preOffsetScreenPoint = screenPoint.y;
if (slideVertical) {
mRect.height = SlideOrResize(screenPoint.y, mRect.height, screenRect.y,
screenRect.YMost(), &mAlignmentOffset);
@ -1623,6 +1631,7 @@ nsMenuPopupFrame::SetPopupPosition(nsIFrame* aAnchorFrame, bool aIsMove, bool aS
margin.top, margin.bottom, offsetForContextMenu.y, vFlip,
endAligned, &mVFlip);
}
mIsOffset = mIsOffset || (preOffsetScreenPoint != screenPoint.y);
NS_ASSERTION(screenPoint.x >= screenRect.x && screenPoint.y >= screenRect.y &&
screenPoint.x + mRect.width <= screenRect.XMost() &&
@ -1669,7 +1678,8 @@ nsMenuPopupFrame::SetPopupPosition(nsIFrame* aAnchorFrame, bool aIsMove, bool aS
// or size changed, dispatch a popuppositioned event if the popup wants it.
nsIntRect newRect(screenPoint.x, screenPoint.y, mRect.width, mRect.height);
if (mPopupState == ePopupPositioning ||
(mPopupState == ePopupShown && !newRect.IsEqualEdges(mUsedScreenRect))) {
(mPopupState == ePopupShown && !newRect.IsEqualEdges(mUsedScreenRect)) ||
(mPopupState == ePopupShown && oldAlignmentOffset != mAlignmentOffset)) {
mUsedScreenRect = newRect;
if (aNotify) {
nsXULPopupPositionedEvent::DispatchIfNeeded(mContent, false, false);

Просмотреть файл

@ -636,6 +636,11 @@ protected:
bool mIsMenuLocked; // Should events inside this menu be ignored?
bool mMouseTransparent; // True if this is a popup is transparent to mouse events
// True if this popup has been offset due to moving off / near the edge of the screen.
// (This is useful for ensuring that a move, which can't offset the popup, doesn't undo
// a previously set offset.)
bool mIsOffset;
// the flip modes that were used when the popup was opened
bool mHFlip;
bool mVFlip;

Просмотреть файл

@ -29,6 +29,7 @@
#include "nsIServiceManager.h"
#include "nsContainerFrame.h"
#include "nsContentCID.h"
#include "mozilla/GeckoStyleContext.h"
#include "mozilla/StyleSetHandle.h"
#include "mozilla/StyleSetHandleInlines.h"
#include "nsLayoutUtils.h"
@ -284,7 +285,7 @@ nsSplitterFrame::Init(nsIContent* aContent,
nsGkAtoms::orient)) {
aContent->SetAttr(kNameSpaceID_None, nsGkAtoms::orient,
NS_LITERAL_STRING("vertical"), false);
nsStyleContext* parentStyleContext = StyleContext()->GetParent();
GeckoStyleContext* parentStyleContext = StyleContext()->GetParent();
RefPtr<nsStyleContext> newContext = PresContext()->StyleSet()->
ResolveStyleFor(aContent->AsElement(), parentStyleContext,
LazyComputeBehavior::Allow);

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше