merge mozilla-central to mozilla-inbound. r=merge a=merge
|
@ -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$S’s 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 %S’s 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=We’re 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);
|
||||
|
|