Compare commits

...
Author SHA1 Message Date
Moonchild 4d5b1cc5d8 Merge branch 'nss-3.125-port' 2026-07-28 10:50:50 +02:00
Moonchild 0e521f6302 Bump NSS (UXP) patch level. 2026-07-28 10:10:27 +02:00
Moonchild 9cacfcff57 Merge remote-tracking branch 'dbsoft/flex-button-fix2' 2026-07-28 10:08:00 +02:00
John Schanck 21ad7adc90 Bug 2043887 - guard against integer overflow in CERT_Hexify. 2026-07-28 10:03:44 +02:00
Benjamin Beurdouche 9a29430751 Bug 2027353 - clamp input.len to testString size in pk11_mergeSecretKey. 2026-07-28 09:59:51 +02:00
Benjamin Beurdouche 481d4868b0 Bug 2029433 - Bounds-check wrap index in PK11_GetWrapKey to match PK11_SetWrapKey. 2026-07-28 09:57:10 +02:00
Anna Weine d148c11717 Bug 2028954 - CERT_DecodeAVAValue — Integer Overflow in Output Buffer Sizing. 2026-07-28 09:53:26 +02:00
Moonchild bc322e58f8 Bug 2027364 - Set tail pointer to null in static slot lists when deallocating. 2026-07-28 09:22:56 +02:00
John Schanck e48a6f26a5 Bug 2032110 - fix two integer overflows on LLP64 systems. 2026-07-27 23:58:14 +02:00
John Schanck d85edd01df Bug 2030102 - avoid leaving a dangling ss->sec.ci.sid on allocation failure. 2026-07-27 23:49:55 +02:00
Maurice Dauer 296379d751 Bug 2027325 - Reject empty nickname in PK11_TraverseCertsForNicknameInSlot. 2026-07-27 23:46:32 +02:00
Moonchild 7ba9fc2801 Bug 2030563 - Validate CKA_CERTIFICATE_TYPE ulValueLen in nss_cert_type_from_ck_attrib. 2026-07-27 23:22:58 +02:00
Brian Smith a9ac8b390f Issue #3153 - Make sure buttons report a definite size for flex containers.
Second try, this time ONLY do it for flex container or grids.
This should prevent layout problems in non-flex scenarios.
2026-07-27 12:36:24 -05:00
Benjamin Beurdouche 71c0f8246c Bug 2029807 - Guard padding read against empty output in SEC_PKCS7DecryptContents. 2026-07-27 19:12:42 +02:00
Benjamin Beurdouche 6cda35442f Bug 2027346 - validate encoded EC params length and tag in SECKEY_ECParamsToKeySize/BasePointOrderLen. 2026-07-27 19:05:33 +02:00
Benjamin Beurdouche 1dba423327 Bug 2027371 - rewrite labelLen bound in tls13_HkdfExpandLabelGeneral to avoid unsigned overflow. 2026-07-27 18:56:08 +02:00
Benjamin Beurdouche e2af0b28bf Bug 2027373 - guard space subtraction in ssl_CallCustomExtensionSenders. 2026-07-27 18:51:32 +02:00
Benjamin Beurdouche 5ea9b7b80a Bug 2029901 - Guard against keySize overflow in IKE PRF/PRF+ output sizing. 2026-07-27 18:44:55 +02:00
Benjamin Beurdouche b799e100ad Bug 2027362 - bound usageCount in PK11_UnwrapPrivKey to keyTemplate capacity. 2026-07-27 18:39:10 +02:00
Benjamin Beurdouche 1c500a6abb Bug 2027349 - reject empty nickname in PK11_TraverseCertsForNicknameInSlot. 2026-07-27 18:27:47 +02:00
Moonchild b909fccc92 Revert "Issue #3153 - Make sure buttons report a definite size for flex containers."
This reverts commit 3e223cbfb4.
2026-07-27 17:59:43 +02:00
Moonchild abddee43b4 Merge remote-tracking branch 'dbsoft/flex-button-fix' 2026-07-27 14:41:27 +02:00
Moonchild 49d184e550 [network] Fix CacheEntry::mDoomCallback data race. 2026-07-27 14:32:51 +02:00
Brian Smith 3e223cbfb4 Issue #3153 - Make sure buttons report a definite size for flex containers. 2026-07-27 05:38:09 -05:00
Moonchild dd9099a7d3 [layout] Fix nsFrameSetFrame primary frame handling of replicated children. 2026-07-26 19:55:49 +02:00
Moonchild 31558a1521 Merge pull request 'Issue #3061 Follow-up: Remove network tickler prefs' (#3151) from Shadow/UXP-contrib:contrib into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3151
2026-07-26 15:45:08 +00:00
Shadow 0e683bf699 Issue #3061 Follow-up: Remove network tickler prefs 2026-07-26 15:39:39 +00:00
Moonchild 6459dec5bb [DOM media] Perform more thorough checks on video regions. 2026-07-26 15:04:18 +02:00
az 0e930fba3f Bug 2045742 2026-07-26 10:08:13 +02:00
Moonchild 3b683bbe59 Merge pull request 'Align aspect-ratio to spec' (#3150) from Basilisk-Dev/UXP-contrib:css-aspect-ratio into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3150
2026-07-26 07:06:00 +00:00
Basilisk-Dev 0042e54c38 Issue #2404 - Split aspect ratio enum types into a separate header to fix compilation issues 2026-07-25 12:24:15 -04:00
Andrew McCreight e75201f7d1 Bug 2049523 - Make ToJSValue for float consistent with double. 2026-07-25 17:04:14 +02:00
Moonchild 28c47723b2 Fix comment (nit) 2026-07-25 16:12:08 +02:00
Randell Jesup 3d872ff7b0 Bug 2029734: Flush before calling sctp_process_init() 2026-07-25 14:52:29 +02:00
Moonchild beb684c29e No issue - Use strnlen instead of strnlen_s.
Apparently, GCC doesn't like the _s variants.
2026-07-25 13:08:15 +02:00
Moonchild 775588b75d [image] Make sure the image was fully and cleanly decoded before finalizing its animation state as complete. 2026-07-25 10:01:55 +02:00
Basilisk-Dev 8a2a5d837c Issue #2404 - Fix aspect ratio sizing for grid items 2026-07-25 00:58:20 -04:00
Basilisk-Dev 8add755c81 Issue #2404 - Improvements to CSS aspect-ratio spec compliance 2026-07-25 00:57:58 -04:00
Moonchild 257c64567e [parser] Associate image elements with form only if the form and the intended parent are in the same tree. 2026-07-24 21:12:04 +02:00
Moonchild d0b61d4a68 No issue - CallUpdateWindow is [[nodiscard]], but we don't need to use
the result here.
2026-07-24 19:29:00 +02:00
Moonchild 3b5f50cc35 Merge pull request 'No Issue - Remove the half-life experiment in HTTP cache' (#3149) from Shadow/UXP-contrib:master into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3149
2026-07-24 14:32:21 +00:00
Moonchild 27c6a7f477 [DOM media] Stop accepting audio samples with too low sample rates.
This sets the floor to 8kHz audio, which is generally considered to be
the lowest acceptable "phone quality"/"walkie-talkie" audio rate.
Audio outside the range will refuse to decode after this commit and give
a console error.
This avoids a whole class of potential bugs.
2026-07-24 14:52:40 +02:00
Moonchild c65f84214e [layout] Add corner-case correctness check in DottedCornerFinder::FindBestOverlap. 2026-07-24 13:17:54 +02:00
Moonchild a317c65fd7 [network] Add usrsctp TSN gap check. 2026-07-24 12:58:20 +02:00
Shadow 0ec35ce534 No Issue - Remove the half-life experiment in HTTP cache
Reviewed-on: https://repo.palemoon.org/Shadow/UXP-contrib/pulls/1
2026-07-24 09:49:48 +00:00
Moonchild bf0c040722 [js] Clamp length of regexp captures array for dollar substitution. 2026-07-22 22:37:50 +02:00
Moonchild ebadd51401 [js] Initialize BaselineFrame return value slot in OnLeaveBaselineFrame. 2026-07-22 20:26:07 +02:00
Moonchild 5ed0bf8b44 [DOM] Make parser update form owner properly 2026-07-22 17:12:32 +02:00
Moonchild f877c1dba5 [gfx] Hold a strong ref during GetFontAt lookup. 2026-07-22 10:27:53 +02:00
Moonchild 4c14f8f89b [gfx] Add bounds checks and limit reverse scanning of ligature data. 2026-07-22 09:43:54 +02:00
Moonchild c119728965 Merge pull request 'Implement CSSStyleSheet replaceSync' (#3145) from Basilisk-Dev/UXP-contrib:replacesync into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3145
2026-07-22 06:02:21 +00:00
Moonchild fa55b9c2e8 [js] Guard against OOB string sizes in internal Printf 2026-07-22 01:39:03 +02:00
Basilisk-Dev 16aba76fc5 Issue #3144 - Implement CSSStyleSheet replaceSync 2026-07-21 04:23:19 -04:00
Moonchild 995def99cd No issue - Exclude some files from the preprocessor that don't have directives in them. 2026-07-19 15:57:10 +02:00
Moonchild 923e52789c Merge pull request 'Convert std::*<T>::value/::type to _v and _t suffixes.' (#3143) from 1803 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3143
2026-07-19 07:40:35 +00:00
Moonchild 22d945430b Issue #3061 - Remove network tickler.
Resolves #3061
2026-07-19 08:17:05 +02:00
Moonchild 65d7d93760 Issue #1803 - Convert std::*<T>::value/::type to _v and _t suffixes.
This excludes uses in third-party libs in our tree.
2026-07-15 11:20:06 +02:00
Moonchild dfd0ea4e8a Merge pull request 'implement URL.parse()' (#3141) from Basilisk-Dev/UXP-contrib:urlparse into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3141
2026-07-14 21:05:40 +00:00
Basilisk-Dev 12a49709cb Issue #3140 - implement URL.parse() 2026-07-14 16:07:45 -04:00
Moonchild 2a70c8a6f0 Merge pull request 'Implement CSS4 revert-layer keyword' (#3139) from Basilisk-Dev/UXP-contrib:revert-layer into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3139
2026-07-13 12:44:06 +00:00
Moonchild 1f639d78ca Merge pull request 'Allow Skia on Mac OS X 10.5 Leopard / big endian PPC' (#3138) from Jazzzny/UXP:skia-leopard-ppc into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3138
2026-07-13 12:43:15 +00:00
Basilisk-Dev 65e8245153 Issue #2829 - Regenerate devtools CSS database for revert-layer 2026-07-11 10:41:52 -04:00
Basilisk-Dev bce5dbad0b Issue #2829 - Use layer index naming for revert-layer metadata 2026-07-11 10:41:46 -04:00
Basilisk-Dev 0b25b5f8db Issue #2829 - Handle revert-layer variable fallbacks 2026-07-10 09:59:20 -04:00
Basilisk-Dev 7345874098 Issue #2829 - Implement CSS revert-layer cascade rollback 2026-07-10 09:59:14 -04:00
Basilisk-Dev edb82fd1c9 Issue #2829 - Support revert-layer in CSS-wide parsing 2026-07-10 09:59:03 -04:00
Jazzzny 35ebdcac66 Fix build issues in Skia code 2026-07-09 12:32:44 -04:00
Jazzzny a095661e86 Use Skia macros where appropriate 2026-07-08 13:43:07 -04:00
Jazzzny 205a0d66bb Add support for big endian in Skia 2026-07-08 04:38:00 -04:00
Jazzzny 54945a0808 Unblock Skia for big endian 2026-07-08 04:38:00 -04:00
Jazzzny 84c1eedac6 Fixes for Skia on 10.5 2026-07-08 04:38:00 -04:00
Moonchild ddf5d6256e Whitespace fix 2026-07-03 09:24:24 +02:00
Moonchild 0eae777fd0 Issue #3132 Follow-up: only include gtk2xtbin.h on GTK targets.
PR #3133 caused build breakage on non-gtk platforms by unconditionally
including the header (because the def defaults to true in configure)

This also reorganizes the configure script to add a check for
MOZ_WIDGET_GTK (hoisted up a little) so the new configure entry is
simply ignored on non-GTK targets.
2026-07-03 09:19:54 +02:00
149 changed files with 3300 additions and 900 deletions

No files matched your search

+1 -1
View File
@@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Clobber for Idle GC backout
Clobber for removal of network tickler
@@ -143,7 +143,8 @@ TooltipsOverlay.prototype = {
// Font preview tooltip
if (type === VIEW_NODE_VALUE_TYPE && prop.property === "font-family") {
let value = prop.value.toLowerCase();
if (value !== "inherit" && value !== "unset" && value !== "initial" && value !== "revert") {
if (value !== "inherit" && value !== "unset" && value !== "initial" &&
value !== "revert" && value !== "revert-layer") {
tooltipType = TOOLTIP_FONTFAMILY_TYPE;
}
}
+1 -1
View File
@@ -3,6 +3,6 @@
# 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/.
JS_PREFERENCE_PP_FILES += [
JS_PREFERENCE_FILES += [
'devtools.js',
]
+2 -1
View File
@@ -10,7 +10,8 @@ const SPECIALVALUES = new Set([
"initial",
"inherit",
"unset",
"revert"
"revert",
"revert-layer"
]);
const {getCSSLexer} = require("devtools/shared/css/lexer");
@@ -99,7 +99,14 @@ const filterList = [
];
// Valid values that shouldn't be parsed for filters.
const SPECIAL_VALUES = new Set(["none", "unset", "initial", "inherit", "revert"]);
const SPECIAL_VALUES = new Set([
"none",
"unset",
"initial",
"inherit",
"revert",
"revert-layer"
]);
/**
* A CSS Filter editor widget used to add/remove/modify
+2 -1
View File
@@ -20,7 +20,8 @@ const SPECIALVALUES = new Set([
"inherit",
"transparent",
"unset",
"revert"
"revert",
"revert-layer"
]);
/**
@@ -43,7 +43,7 @@ class MachCommands(MachCommandBase):
if not os.path.exists(generated_dir):
generated_dir = mozpath.join(self.topsrcdir, 'platform',
'devtools/shared/css/generated')
else:
if not os.path.exists(generated_dir):
raise Exception('Directory expected at %s does not exist.' % generated_dir)
self.generated_dir = generated_dir
@@ -75,6 +75,9 @@ class MachCommands(MachCommandBase):
contents = subprocess.check_output([xpcshell_path, '-g', gre_path,
'-a', browser_path, script_path],
env = sub_env)
if not isinstance(contents, str):
contents = contents.decode('utf-8')
# Extract just the output between the delimiters as the xpcshell output can
# have extra output that we don't want.
contents = contents.split('DEVTOOLS_CSS_DB_DELIMITER')[1]
@@ -88,13 +91,13 @@ class MachCommands(MachCommandBase):
destination_path = mozpath.join(self.generated_dir,
'properties-db.js')
with open(js_template_path, 'rb') as handle:
with open(js_template_path, 'r') as handle:
js_template = handle.read()
preamble = '/* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT */\n\n'
contents = string.Template(js_template).substitute(substitutions)
with open(destination_path, 'wb') as destination:
with open(destination_path, 'w') as destination:
destination.write(preamble + contents)
print(('The database was successfully generated at ' + destination_path))
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -274,7 +274,7 @@ public:
}
template<typename T,
typename = typename std::enable_if<std::is_enum<T>::value>::type>
typename = typename std::enable_if_t<std::is_enum_v<T>>>
EnumTable(const char* aTag, T aValue)
: tag(aTag)
, value(static_cast<int16_t>(aValue))
+2 -2
View File
@@ -97,7 +97,7 @@ ToJSValue(JSContext* aCx,
return true;
}
// accept floating point types
// Accept floating point types
inline bool
ToJSValue(JSContext* aCx,
float aArgument,
@@ -106,7 +106,7 @@ ToJSValue(JSContext* aCx,
// Make sure we're called in a compartment
MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
aValue.setNumber(aArgument);
aValue.set(JS_NumberValue(double(aArgument)));
return true;
}
+2 -10
View File
@@ -876,20 +876,12 @@ HTMLImageElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
return HTMLImageElementBinding::Wrap(aCx, this, aGivenProto);
}
#ifdef DEBUG
nsIDOMHTMLFormElement*
HTMLImageElement::GetForm() const
{
return mForm;
}
#endif
void
HTMLImageElement::SetForm(nsIDOMHTMLFormElement* aForm)
{
NS_PRECONDITION(aForm, "Don't pass null here");
NS_ASSERTION(!mForm,
"We don't support switching from one non-null form to another.");
MOZ_ASSERT(!mForm && !HasFlag(ADDED_TO_FORM),
"We don't support switching from one non-null form to another.");
mForm = static_cast<HTMLFormElement*>(aForm);
}
+2 -3
View File
@@ -216,9 +216,8 @@ public:
SetHTMLAttr(nsGkAtoms::lowsrc, aLowsrc, aError);
}
#ifdef DEBUG
nsIDOMHTMLFormElement* GetForm() const;
#endif
HTMLFormElement* GetForm() const { return mForm; };
void SetForm(nsIDOMHTMLFormElement* aForm);
void ClearForm(bool aRemoveFromForm);
+11 -4
View File
@@ -1487,8 +1487,15 @@ nsGenericHTMLElement::MapImageSizeAttributesInto(const nsMappedAttributes* aAttr
}
if (w && h && *w != 0 && *h != 0) {
nsCSSValue* aspect_ratio = aData->ValueForAspectRatio();
aspect_ratio->SetFloatValue((float(*w) / float(*h)), eCSSUnit_Number);
nsCSSValue width;
width.SetFloatValue(float(*w), eCSSUnit_Number);
nsCSSValue height;
height.SetFloatValue(float(*h), eCSSUnit_Number);
nsCSSValue ratio;
ratio.SetPairValue(width, height);
nsCSSValue autoValue;
autoValue.SetAutoValue();
aData->ValueForAspectRatio()->SetPairValue(autoValue, ratio);
}
}
}
@@ -1824,8 +1831,8 @@ void
nsGenericHTMLFormElement::SetForm(nsIDOMHTMLFormElement* aForm)
{
NS_PRECONDITION(aForm, "Don't pass null here");
NS_ASSERTION(!mForm,
"We don't support switching from one non-null form to another.");
MOZ_ASSERT(!mForm && !HasFlag(ADDED_TO_FORM),
"We don't support switching from one non-null form to another.");
// keep a *weak* ref to the form here
mForm = static_cast<HTMLFormElement*>(aForm);
+1 -1
View File
@@ -2455,7 +2455,7 @@ ContentChild::RecvUpdateWindow(const uintptr_t& aChildId)
if (parentInstance) {
// sync! update call to the plugin instance that forces the
// plugin to paint its child window.
parentInstance->CallUpdateWindow();
Unused << parentInstance->CallUpdateWindow();
}
return true;
#else
+2 -1
View File
@@ -367,12 +367,13 @@ public:
{
}
static const uint32_t MIN_RATE = 8000;
static const uint32_t MAX_RATE = 640000;
bool IsValid() const override
{
return mChannels > 0 && mChannels <= MAX_AUDIO_CHANNELS
&& mRate > 0 && mRate <= MAX_RATE;
&& mRate >= MIN_RATE && mRate <= MAX_RATE;
}
AudioInfo* GetAsAudioInfo() override
+6
View File
@@ -179,12 +179,18 @@ IsValidVideoRegion(const nsIntSize& aFrame, const nsIntRect& aPicture,
aFrame.height <= PlanarYCbCrImage::MAX_DIMENSION &&
aFrame.width * aFrame.height <= MAX_VIDEO_WIDTH * MAX_VIDEO_HEIGHT &&
aFrame.width * aFrame.height != 0 &&
aPicture.width > 0 &&
aPicture.width <= PlanarYCbCrImage::MAX_DIMENSION &&
aPicture.x >= 0 &&
aPicture.x < PlanarYCbCrImage::MAX_DIMENSION &&
aPicture.x + aPicture.width < PlanarYCbCrImage::MAX_DIMENSION &&
aPicture.XMost() <= aFrame.width &&
aPicture.height > 0 &&
aPicture.height <= PlanarYCbCrImage::MAX_DIMENSION &&
aPicture.y >= 0 &&
aPicture.y < PlanarYCbCrImage::MAX_DIMENSION &&
aPicture.y + aPicture.height < PlanarYCbCrImage::MAX_DIMENSION &&
aPicture.YMost() <= aFrame.height &&
aPicture.width * aPicture.height <= MAX_VIDEO_WIDTH * MAX_VIDEO_HEIGHT &&
aPicture.width * aPicture.height != 0 &&
aDisplay.width <= PlanarYCbCrImage::MAX_DIMENSION &&
+1 -1
View File
@@ -439,7 +439,7 @@ private:
Maybe<size_t> mInitOffset;
Maybe<size_t> mMediaOffset;
bool mValid = true;
char mLastInvalidBox[5];
char mLastInvalidBox[5]{};
};
public:
+14 -5
View File
@@ -20,6 +20,7 @@
#include "WebMBufferedParser.h"
#include "gfx2DGlue.h"
#include "mozilla/Atomics.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/EndianUtils.h"
#include "mozilla/Maybe.h"
#include "mozilla/SharedThreadPool.h"
@@ -352,19 +353,27 @@ WebMDemuxer::ReadMetadata()
mInfo.mVideo.mExtraData = new MediaByteBuffer(length);
mInfo.mVideo.mExtraData->AppendElements(data, length);
break;
}
}
default:
NS_WARNING("Unknown WebM video codec");
return NS_ERROR_FAILURE;
}
// Picture region, taking into account cropping, before scaling
// to the display size.
unsigned int cropH = params.crop_right + params.crop_left;
unsigned int cropV = params.crop_bottom + params.crop_top;
CheckedInt<uint32_t> cropH = CheckedInt<uint32_t>(params.crop_left) + params.crop_right;
CheckedInt<uint32_t> cropV = CheckedInt<uint32_t>(params.crop_top) + params.crop_bottom;
if (!cropH.isValid() || !cropV.isValid() ||
cropH.value() >= params.width || cropV.value() >= params.height) {
WEBM_DEBUG("Invalid crop values left: {} right: {} top: {} bottom: {}",
params.crop_left, params.crop_right, params.crop_top,
params.crop_bottom);
// Ignore invalid crop parameters.
continue;
}
nsIntRect pictureRect(params.crop_left,
params.crop_top,
params.width - cropH,
params.height - cropV);
params.width - cropH.value(),
params.height - cropV.value());
// If the cropping data appears invalid then use the frame data
if (pictureRect.width <= 0 ||
+1 -1
View File
@@ -4679,7 +4679,7 @@ PluginInstanceChild::Destroy()
mPendingAsyncCalls.Clear();
#ifdef MOZ_ENABLE_NPAPI_GTK2
#if defined(MOZ_WIDGET_GTK) && defined(MOZ_ENABLE_NPAPI_GTK2)
if (mWindow.type == NPWindowTypeWindow && !mXEmbed) {
xt_client_xloop_destroy();
}
+1 -1
View File
@@ -36,7 +36,7 @@
#include <map>
#ifdef MOZ_ENABLE_NPAPI_GTK2
#if defined(MOZ_WIDGET_GTK) && defined(MOZ_ENABLE_NPAPI_GTK2)
#include "gtk2xtbin.h"
#endif
+14 -5
View File
@@ -1789,17 +1789,26 @@ URL::IsValidURL(const GlobalObject& aGlobal, const nsAString& aURL,
return URLWorker::IsValidURL(aGlobal, aURL, aRv);
}
bool
URL::CanParse(const GlobalObject& aGlobal, const nsAString& aURL,
const Optional<nsAString>& aBase) {
already_AddRefed<URL>
URL::Parse(const GlobalObject& aGlobal, const nsAString& aURL,
const Optional<nsAString>& aBase)
{
ErrorResult rv;
RefPtr<URL> parsed = URL::Constructor(aGlobal, aURL, aBase, rv);
if (rv.Failed() || !parsed) {
rv.SuppressException();
return false;
return nullptr;
}
return true;
return parsed.forget();
}
bool
URL::CanParse(const GlobalObject& aGlobal, const nsAString& aURL,
const Optional<nsAString>& aBase)
{
RefPtr<URL> parsed = URL::Parse(aGlobal, aURL, aBase);
return !!parsed;
}
already_AddRefed<URLSearchParams>
+4
View File
@@ -88,6 +88,10 @@ public:
IsValidURL(const GlobalObject& aGlobal, const nsAString& aURL,
ErrorResult& aRv);
static already_AddRefed<URL>
Parse(const GlobalObject& aGlobal, const nsAString& aURL,
const Optional<nsAString>& aBase);
static bool
CanParse(const GlobalObject& aGlobal, const nsAString& aURL,
const Optional<nsAString>& aBase);
+28
View File
@@ -448,6 +448,34 @@
!URL.canParse("/static/client/runtime.js", "mailto:test@example.com"),
"URL.canParse rejects root-relative input against opaque mailto: base",
);
ok("parse" in URL, "URL.parse exists");
is(URL.parse.length, 1, "URL.parse has one required argument");
var parsed = URL.parse("/static/client/runtime.js", "x:/");
ok(parsed instanceof URL, "URL.parse returns a URL object on success");
is(parsed.href, "x:/static/client/runtime.js", "URL.parse resolves against a base");
is(URL.parse("/static/client/runtime.js"), null, "URL.parse returns null for invalid input");
is(
URL.parse("/static/client/runtime.js", "mailto:test@example.com"),
null,
"URL.parse returns null for an invalid base/input combination",
);
var conversionOrder = [];
parsed = URL.parse(
{ toString: function() { conversionOrder.push("url"); return "child"; } },
{ toString: function() { conversionOrder.push("base"); return "https://example.com/root/"; } },
);
is(conversionOrder.join(","), "url,base", "URL.parse converts its arguments in order");
is(parsed.href, "https://example.com/root/child", "URL.parse uses converted arguments");
var sentinel = {};
var thrown;
try {
URL.parse({ toString: function() { throw sentinel; } });
} catch (e) {
thrown = e;
}
is(thrown, sentinel, "URL.parse propagates argument conversion exceptions");
SimpleTest.doesThrow(() => {
new URL("/static/client/runtime.js", "mailto:test@example.com");
}, "constructor rejects root-relative input against opaque mailto: base");
+58
View File
@@ -301,6 +301,64 @@ onmessage = function () {
!URL.canParse("/static/client/runtime.js", "mailto:test@example.com"),
"URL.canParse rejects root-relative input against opaque mailto: base",
);
ok("parse" in URL, "URL.parse exists");
is(URL.parse.length, 1, "URL.parse has one required argument");
let parsed = URL.parse("/static/client/runtime.js", "x:/");
ok(parsed instanceof URL, "URL.parse returns a URL object on success");
is(
parsed.href,
"x:/static/client/runtime.js",
"URL.parse resolves against a base",
);
is(
URL.parse("/static/client/runtime.js"),
null,
"URL.parse returns null for invalid input",
);
is(
URL.parse("/static/client/runtime.js", "mailto:test@example.com"),
null,
"URL.parse returns null for an invalid base/input combination",
);
const conversionOrder = [];
parsed = URL.parse(
{
toString() {
conversionOrder.push("url");
return "child";
},
},
{
toString() {
conversionOrder.push("base");
return "https://example.com/root/";
},
},
);
is(
conversionOrder.join(","),
"url,base",
"URL.parse converts its arguments in order",
);
is(
parsed.href,
"https://example.com/root/child",
"URL.parse uses converted arguments",
);
const sentinel = {};
let thrown;
try {
URL.parse({
toString() {
throw sentinel;
},
});
} catch (e) {
thrown = e;
}
is(thrown, sentinel, "URL.parse propagates argument conversion exceptions");
let mailtoRelativeFailed = false;
try {
new URL("/static/client/runtime.js", "mailto:test@example.com");
+2
View File
@@ -25,6 +25,8 @@ interface CSSStyleSheet : StyleSheet {
unsigned long insertRule(DOMString rule, optional unsigned long index = 0);
[Throws, NeedsSubjectPrincipal]
void deleteRule(unsigned long index);
[Throws]
void replaceSync(DOMString text);
// Non-standard WebKit things, see https://github.com/w3c/csswg-drafts/pull/3900.
[Throws, NeedsSubjectPrincipal, BinaryName="cssRules"]
+1
View File
@@ -23,6 +23,7 @@ interface URL {
[Throws]
stringifier;
static URL? parse(USVString url, optional USVString base);
static boolean canParse(USVString url, optional USVString base);
[Throws]
+10
View File
@@ -1117,6 +1117,7 @@ DrawTargetSkia::BorrowCGContext(const DrawOptions &aOptions)
kCGImageAlphaOnly :
kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;
#if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
mCG = CGBitmapContextCreateWithData(mCanvasData,
mCGSize.width,
mCGSize.height,
@@ -1126,6 +1127,15 @@ DrawTargetSkia::BorrowCGContext(const DrawOptions &aOptions)
bitmapInfo,
NULL, /* Callback when released */
NULL);
#else
mCG = CGBitmapContextCreate(mCanvasData,
mCGSize.width,
mCGSize.height,
8, /* bits per component */
stride,
mColorSpace,
bitmapInfo);
#endif
if (!mCG) {
ReleaseBits(mCanvasData);
NS_WARNING("Could not create bitmap around skia data\n");
+1 -1
View File
@@ -115,7 +115,7 @@ ScaledFontMac::GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aT
return ScaledFontBase::GetPathForGlyphs(aBuffer, aTarget);
}
#if !defined(MAC_OS_X_VERSION_10_7) || (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7)
#ifndef USE_SKIA
void
ScaledFontMac::CopyGlyphsToBuilder(const GlyphBuffer &aBuffer, PathBuilder *aBuilder, const Matrix *aTransformHint)
{
+1 -1
View File
@@ -32,7 +32,7 @@ public:
virtual SkTypeface* GetSkTypeface();
#endif
virtual already_AddRefed<Path> GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget);
#if !defined(MAC_OS_X_VERSION_10_7) || (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7)
#ifndef USE_SKIA
virtual void CopyGlyphsToBuilder(const GlyphBuffer &aBuffer, PathBuilder *aBuilder, const Matrix *aTransformHint);
#endif
virtual bool GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton);
+58 -15
View File
@@ -24,15 +24,21 @@
* Skia's 32bit backend only supports 1 sizzle order at a time (compile-time).
* This is specified by 4 defines SK_A32_SHIFT, SK_R32_SHIFT, ... for G and B.
*
* For easier compatibility with Skia's GPU backend, we further restrict these
* to either (in memory-byte-order) RGBA or BGRA. Note that this "order" does
* not directly correspond to the same shift-order, since we have to take endianess
* into account.
* For easier compatibility with Skia's GPU backend, Skia normally restricts
* these to either (in memory-byte-order) RGBA or BGRA. Mozilla's big-endian
* PowerPC port uses CoreGraphics' native ARGB pixels, so we also accept ARGB.
* Note that this "order" does not directly correspond to the same shift-order,
* since we have to take endianess into account.
*
* Here we enforce this constraint.
*/
#ifdef SK_CPU_BENDIAN
#define SK_ARGB_A32_SHIFT 24
#define SK_ARGB_R32_SHIFT 16
#define SK_ARGB_G32_SHIFT 8
#define SK_ARGB_B32_SHIFT 0
#define SK_RGBA_R32_SHIFT 24
#define SK_RGBA_G32_SHIFT 16
#define SK_RGBA_B32_SHIFT 8
@@ -43,6 +49,11 @@
#define SK_BGRA_R32_SHIFT 8
#define SK_BGRA_A32_SHIFT 0
#else
#define SK_ARGB_A32_SHIFT 0
#define SK_ARGB_R32_SHIFT 8
#define SK_ARGB_G32_SHIFT 16
#define SK_ARGB_B32_SHIFT 24
#define SK_RGBA_R32_SHIFT 0
#define SK_RGBA_G32_SHIFT 8
#define SK_RGBA_B32_SHIFT 16
@@ -54,10 +65,18 @@
#define SK_BGRA_A32_SHIFT 24
#endif
#if defined(SK_PMCOLOR_IS_RGBA) && defined(SK_PMCOLOR_IS_BGRA)
#error "can't define PMCOLOR to be RGBA and BGRA"
#if (defined(SK_PMCOLOR_IS_RGBA) && defined(SK_PMCOLOR_IS_BGRA)) || \
(defined(SK_PMCOLOR_IS_RGBA) && defined(SK_PMCOLOR_IS_ARGB)) || \
(defined(SK_PMCOLOR_IS_BGRA) && defined(SK_PMCOLOR_IS_ARGB))
#error "can't define PMCOLOR to more than one byte order"
#endif
#define LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_ARGB \
(SK_A32_SHIFT == SK_ARGB_A32_SHIFT && \
SK_R32_SHIFT == SK_ARGB_R32_SHIFT && \
SK_G32_SHIFT == SK_ARGB_G32_SHIFT && \
SK_B32_SHIFT == SK_ARGB_B32_SHIFT)
#define LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA \
(SK_A32_SHIFT == SK_RGBA_A32_SHIFT && \
SK_R32_SHIFT == SK_RGBA_R32_SHIFT && \
@@ -76,6 +95,10 @@
#define SK_G_INDEX (SK_G32_SHIFT/8)
#define SK_B_INDEX (SK_B32_SHIFT/8)
#if defined(SK_PMCOLOR_IS_ARGB) && !LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_ARGB
#error "SK_PMCOLOR_IS_ARGB does not match SK_*32_SHIFT values"
#endif
#if defined(SK_PMCOLOR_IS_RGBA) && !LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA
#error "SK_PMCOLOR_IS_RGBA does not match SK_*32_SHIFT values"
#endif
@@ -84,19 +107,22 @@
#error "SK_PMCOLOR_IS_BGRA does not match SK_*32_SHIFT values"
#endif
#if !defined(SK_PMCOLOR_IS_RGBA) && !defined(SK_PMCOLOR_IS_BGRA)
#if !defined(SK_PMCOLOR_IS_ARGB) && !defined(SK_PMCOLOR_IS_RGBA) && !defined(SK_PMCOLOR_IS_BGRA)
// deduce which to define from the _SHIFT defines
#if LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA
#if LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_ARGB
#define SK_PMCOLOR_IS_ARGB
#elif LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA
#define SK_PMCOLOR_IS_RGBA
#elif LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_BGRA
#define SK_PMCOLOR_IS_BGRA
#else
#error "need 32bit packing to be either RGBA or BGRA"
#error "need 32bit packing to be either ARGB, RGBA, or BGRA"
#endif
#endif
// hide these now that we're done
#undef LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_ARGB
#undef LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA
#undef LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_BGRA
@@ -131,19 +157,38 @@ static inline uint32_t SkPackARGB_as_BGRA(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
(g << SK_BGRA_G32_SHIFT) | (b << SK_BGRA_B32_SHIFT);
}
static inline SkPMColor SkPackARGB_as_PMColor(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
SkASSERT_IS_BYTE(a);
SkASSERT_IS_BYTE(r);
SkASSERT_IS_BYTE(g);
SkASSERT_IS_BYTE(b);
return (a << SK_A32_SHIFT) | (r << SK_R32_SHIFT) |
(g << SK_G32_SHIFT) | (b << SK_B32_SHIFT);
}
static inline SkPMColor SkSwizzle_RGBA_to_PMColor(uint32_t c) {
#ifdef SK_PMCOLOR_IS_RGBA
return c;
#else
#elif defined(SK_PMCOLOR_IS_BGRA)
return SkSwizzle_RB(c);
#else
return SkPackARGB_as_PMColor((c >> SK_RGBA_A32_SHIFT) & 0xFF,
(c >> SK_RGBA_R32_SHIFT) & 0xFF,
(c >> SK_RGBA_G32_SHIFT) & 0xFF,
(c >> SK_RGBA_B32_SHIFT) & 0xFF);
#endif
}
static inline SkPMColor SkSwizzle_BGRA_to_PMColor(uint32_t c) {
#ifdef SK_PMCOLOR_IS_BGRA
return c;
#else
#elif defined(SK_PMCOLOR_IS_RGBA)
return SkSwizzle_RB(c);
#else
return SkPackARGB_as_PMColor((c >> SK_BGRA_A32_SHIFT) & 0xFF,
(c >> SK_BGRA_R32_SHIFT) & 0xFF,
(c >> SK_BGRA_G32_SHIFT) & 0xFF,
(c >> SK_BGRA_B32_SHIFT) & 0xFF);
#endif
}
@@ -412,8 +457,7 @@ static inline SkPMColor SkPackARGB32(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
SkASSERT(g <= a);
SkASSERT(b <= a);
return (a << SK_A32_SHIFT) | (r << SK_R32_SHIFT) |
(g << SK_G32_SHIFT) | (b << SK_B32_SHIFT);
return SkPackARGB_as_PMColor(a, r, g, b);
}
static inline uint32_t SkPackPMColor_as_RGBA(SkPMColor c) {
@@ -547,8 +591,7 @@ static inline SkPMColor SkFastFourByteInterp(SkPMColor src,
* values are premultiplied in the debug version.
*/
static inline SkPMColor SkPackARGB32NoCheck(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
return (a << SK_A32_SHIFT) | (r << SK_R32_SHIFT) |
(g << SK_G32_SHIFT) | (b << SK_B32_SHIFT);
return SkPackARGB_as_PMColor(a, r, g, b);
}
static inline
+6 -1
View File
@@ -82,8 +82,13 @@ enum SkColorType {
kN32_SkColorType = kBGRA_8888_SkColorType,
#elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
kN32_SkColorType = kRGBA_8888_SkColorType,
#elif defined(MOZ_SKIA) && SK_PMCOLOR_BYTE_ORDER(A,R,G,B)
// Big-endian PowerPC Mozilla surfaces use native uint32 ARGB memory.
// Moz2D's legacy A8R8G8B8_UINT32 format aliases to B8G8R8A8, so keep
// kN32 on Skia's BGRA path while the channel shifts above describe ARGB.
kN32_SkColorType = kBGRA_8888_SkColorType,
#else
#error "SK_*32_SHFIT values must correspond to BGRA or RGBA byte order"
#error "SK_*32_SHIFT values must correspond to BGRA, RGBA, or Mozilla ARGB byte order"
#endif
};
+6 -4
View File
@@ -275,17 +275,19 @@ enum GrPixelConfig {
static const int kGrPixelConfigCnt = kLast_GrPixelConfig + 1;
// Aliases for pixel configs that match skia's byte order.
#ifndef SK_CPU_LENDIAN
#error "Skia gpu currently assumes little endian"
#endif
#if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
static const GrPixelConfig kSkia8888_GrPixelConfig = kBGRA_8888_GrPixelConfig;
static const GrPixelConfig kSkiaGamma8888_GrPixelConfig = kSBGRA_8888_GrPixelConfig;
#elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
static const GrPixelConfig kSkia8888_GrPixelConfig = kRGBA_8888_GrPixelConfig;
static const GrPixelConfig kSkiaGamma8888_GrPixelConfig = kSRGBA_8888_GrPixelConfig;
#elif defined(MOZ_SKIA) && SK_PMCOLOR_BYTE_ORDER(A,R,G,B)
// Mozilla's big-endian PowerPC path stores native 32-bit pixels as ARGB,
// while Moz2D routes those surfaces through Skia's BGRA color type.
static const GrPixelConfig kSkia8888_GrPixelConfig = kBGRA_8888_GrPixelConfig;
static const GrPixelConfig kSkiaGamma8888_GrPixelConfig = kSBGRA_8888_GrPixelConfig;
#else
#error "SK_*32_SHIFT values must correspond to GL_BGRA or GL_RGBA format."
#error "SK_*32_SHIFT values must correspond to GL_BGRA, GL_RGBA, or Mozilla ARGB format."
#endif
// Returns true if the pixel config is a GPU-specific compressed format
+4
View File
@@ -306,7 +306,11 @@ static inline SkPMColor premultiply_argb_as_bgra(U8CPU a, U8CPU r, U8CPU g, U8CP
b = SkMulDiv255Round(b, a);
}
#ifdef SK_PMCOLOR_IS_ARGB
return SkPackARGB_as_PMColor(a, r, g, b);
#else
return SkPackARGB_as_BGRA(a, r, g, b);
#endif
}
static inline bool is_rgba(SkColorType colorType) {
+6
View File
@@ -51,10 +51,16 @@ struct SkPM4f {
Sk4f to4f_pmorder() const { return swizzle_rb_if_bgra(this->to4f()); }
SkPMColor toPMColor() const {
#ifdef SK_PMCOLOR_IS_ARGB
Sk4f value = this->to4f();
Sk4b bytes = SkNx_cast<uint8_t>(value * Sk4f(255) + Sk4f(0.5f));
return SkPackARGB_as_PMColor(bytes[3], bytes[0], bytes[1], bytes[2]);
#else
Sk4f value = swizzle_rb_if_bgra(this->to4f());
SkPMColor result;
SkNx_cast<uint8_t>(value * Sk4f(255) + Sk4f(0.5f)).store(&result);
return result;
#endif
}
void toF16(uint16_t[4]) const;
+21
View File
@@ -22,29 +22,50 @@ static inline float get_alpha(const Sk4f& px) {
static inline Sk4f Sk4f_fromL32(uint32_t px) {
#ifdef SK_PMCOLOR_IS_ARGB
return Sk4f(SkGetPackedR32(px), SkGetPackedG32(px),
SkGetPackedB32(px), SkGetPackedA32(px)) * (1/255.0f);
#else
return SkNx_cast<float>(Sk4b::Load(&px)) * (1/255.0f);
#endif
}
static inline Sk4f Sk4f_fromS32(uint32_t px) {
#ifdef SK_PMCOLOR_IS_ARGB
return { sk_linear_from_srgb[SkGetPackedR32(px)],
sk_linear_from_srgb[SkGetPackedG32(px)],
sk_linear_from_srgb[SkGetPackedB32(px)],
(1/255.0f) * SkGetPackedA32(px) };
#else
return { sk_linear_from_srgb[(px >> 0) & 0xff],
sk_linear_from_srgb[(px >> 8) & 0xff],
sk_linear_from_srgb[(px >> 16) & 0xff],
(1/255.0f) * (px >> 24) };
#endif
}
static inline uint32_t Sk4f_toL32(const Sk4f& px) {
#ifdef SK_PMCOLOR_IS_ARGB
Sk4b bytes = SkNx_cast<uint8_t>(Sk4f_round(px * 255.0f));
return SkPackARGB_as_PMColor(bytes[3], bytes[0], bytes[1], bytes[2]);
#else
uint32_t l32;
SkNx_cast<uint8_t>(Sk4f_round(px * 255.0f)).store(&l32);
return l32;
#endif
}
static inline uint32_t Sk4f_toS32(const Sk4f& px) {
Sk4i rgb = sk_linear_to_srgb(px),
srgb = { rgb[0], rgb[1], rgb[2], (int)(255.0f * px[3] + 0.5f) };
#ifdef SK_PMCOLOR_IS_ARGB
return SkPackARGB_as_PMColor(srgb[3], srgb[0], srgb[1], srgb[2]);
#else
uint32_t s32;
SkNx_cast<uint8_t>(srgb).store(&s32);
return s32;
#endif
}
+3 -2
View File
@@ -121,9 +121,10 @@ SkDEBUGCODE(static const unsigned kRunRecordMagic = 0xb10bcafe;)
namespace {
struct RunRecordStorageEquivalent {
RunFont fFont;
SkPoint fOffset;
uint32_t fCount;
uint32_t fFlags;
SkPoint fOffset;
SkTextBlob::GlyphPositioning fPositioning;
bool fExtended;
SkDEBUGCODE(unsigned fMagic;)
};
}
+33 -1
View File
@@ -44,6 +44,25 @@ static Sk4x4f load_4_srgb(const void* vptr) {
Sk4x4f rgba;
#ifdef SK_PMCOLOR_IS_ARGB
rgba.r = { sk_linear_from_srgb[SkGetPackedR32(ptr[0])],
sk_linear_from_srgb[SkGetPackedR32(ptr[1])],
sk_linear_from_srgb[SkGetPackedR32(ptr[2])],
sk_linear_from_srgb[SkGetPackedR32(ptr[3])] };
rgba.g = { sk_linear_from_srgb[SkGetPackedG32(ptr[0])],
sk_linear_from_srgb[SkGetPackedG32(ptr[1])],
sk_linear_from_srgb[SkGetPackedG32(ptr[2])],
sk_linear_from_srgb[SkGetPackedG32(ptr[3])] };
rgba.b = { sk_linear_from_srgb[SkGetPackedB32(ptr[0])],
sk_linear_from_srgb[SkGetPackedB32(ptr[1])],
sk_linear_from_srgb[SkGetPackedB32(ptr[2])],
sk_linear_from_srgb[SkGetPackedB32(ptr[3])] };
rgba.a = SkNx_cast<float>(Sk4i(SkGetPackedA32(ptr[0]), SkGetPackedA32(ptr[1]),
SkGetPackedA32(ptr[2]), SkGetPackedA32(ptr[3]))) * (1/255.0f);
#else
rgba.r = { sk_linear_from_srgb[(ptr[0] >> 0) & 0xff],
sk_linear_from_srgb[(ptr[1] >> 0) & 0xff],
sk_linear_from_srgb[(ptr[2] >> 0) & 0xff],
@@ -60,15 +79,28 @@ static Sk4x4f load_4_srgb(const void* vptr) {
sk_linear_from_srgb[(ptr[3] >> 16) & 0xff] };
rgba.a = SkNx_cast<float>((Sk4i::Load(ptr) >> 24) & 0xff) * (1/255.0f);
#endif
return rgba;
}
static void store_4_srgb(void* ptr, const Sk4x4f& p) {
#ifdef SK_PMCOLOR_IS_ARGB
uint32_t* dst = (uint32_t*)ptr;
Sk4i r = sk_linear_to_srgb(p.r);
Sk4i g = sk_linear_to_srgb(p.g);
Sk4i b = sk_linear_to_srgb(p.b);
Sk4i a = Sk4f_round(255.0f*p.a);
dst[0] = SkPackARGB_as_PMColor(a[0], r[0], g[0], b[0]);
dst[1] = SkPackARGB_as_PMColor(a[1], r[1], g[1], b[1]);
dst[2] = SkPackARGB_as_PMColor(a[2], r[2], g[2], b[2]);
dst[3] = SkPackARGB_as_PMColor(a[3], r[3], g[3], b[3]);
#else
( sk_linear_to_srgb(p.r) << 0
| sk_linear_to_srgb(p.g) << 8
| sk_linear_to_srgb(p.b) << 16
| Sk4f_round(255.0f*p.a) << 24).store(ptr);
#endif
}
///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -391,7 +423,7 @@ SkXfermode::D32Proc SkXfermode::GetD32Proc(SkXfermode* xfer, uint32_t flags) {
#include "SkColorPriv.h"
static Sk4f lcd16_to_unit_4f(uint16_t rgb) {
#ifdef SK_PMCOLOR_IS_RGBA
#if defined(SK_PMCOLOR_IS_RGBA) || defined(SK_PMCOLOR_IS_ARGB)
Sk4i rgbi = Sk4i(SkGetPackedR16(rgb), SkGetPackedG16(rgb), SkGetPackedB16(rgb), 0);
#else
Sk4i rgbi = Sk4i(SkGetPackedB16(rgb), SkGetPackedG16(rgb), SkGetPackedR16(rgb), 0);
+1 -1
View File
@@ -251,7 +251,7 @@ bool GrDrawTarget::drawBatches(GrBatchFlushState* flushState) {
if (currentRT) {
static const GrGpuCommandBuffer::LoadAndStoreInfo kBasicLoadStoreInfo
{ GrGpuCommandBuffer::LoadOp::kLoad,GrGpuCommandBuffer::StoreOp::kStore,
GrColor_ILLEGAL };
static_cast<GrColor>(GrColor_ILLEGAL) };
commandBuffer.reset(fGpu->createCommandBuffer(currentRT,
kBasicLoadStoreInfo, // Color
kBasicLoadStoreInfo)); // Stencil
+21
View File
@@ -69,11 +69,18 @@ inline Sk4px Sk4px::Wide::div255() const {
}
inline Sk4px Sk4px::alphas() const {
#ifdef SK_PMCOLOR_IS_ARGB
return Sk16b((*this)[ 0], (*this)[ 0], (*this)[ 0], (*this)[ 0],
(*this)[ 4], (*this)[ 4], (*this)[ 4], (*this)[ 4],
(*this)[ 8], (*this)[ 8], (*this)[ 8], (*this)[ 8],
(*this)[12], (*this)[12], (*this)[12], (*this)[12]);
#else
static_assert(SK_A32_SHIFT == 24, "This method assumes little-endian.");
return Sk16b((*this)[ 3], (*this)[ 3], (*this)[ 3], (*this)[ 3],
(*this)[ 7], (*this)[ 7], (*this)[ 7], (*this)[ 7],
(*this)[11], (*this)[11], (*this)[11], (*this)[11],
(*this)[15], (*this)[15], (*this)[15], (*this)[15]);
#endif
}
inline Sk4px Sk4px::Load4Alphas(const SkAlpha a[4]) {
@@ -91,19 +98,33 @@ inline Sk4px Sk4px::Load2Alphas(const SkAlpha a[2]) {
}
inline Sk4px Sk4px::zeroAlphas() const {
#ifdef SK_PMCOLOR_IS_ARGB
return Sk16b(0, (*this)[ 1], (*this)[ 2], (*this)[ 3],
0, (*this)[ 5], (*this)[ 6], (*this)[ 7],
0, (*this)[ 9], (*this)[10], (*this)[11],
0, (*this)[13], (*this)[14], (*this)[15]);
#else
static_assert(SK_A32_SHIFT == 24, "This method assumes little-endian.");
return Sk16b((*this)[ 0], (*this)[ 1], (*this)[ 2], 0,
(*this)[ 4], (*this)[ 5], (*this)[ 6], 0,
(*this)[ 8], (*this)[ 9], (*this)[10], 0,
(*this)[12], (*this)[13], (*this)[14], 0);
#endif
}
inline Sk4px Sk4px::zeroColors() const {
#ifdef SK_PMCOLOR_IS_ARGB
return Sk16b((*this)[ 0], 0,0,0,
(*this)[ 4], 0,0,0,
(*this)[ 8], 0,0,0,
(*this)[12], 0,0,0);
#else
static_assert(SK_A32_SHIFT == 24, "This method assumes little-endian.");
return Sk16b(0,0,0, (*this)[ 3],
0,0,0, (*this)[ 7],
0,0,0, (*this)[11],
0,0,0, (*this)[15]);
#endif
}
} // namespace
@@ -72,6 +72,10 @@ static void color_cube_filter_span(const SkPMColor src[],
// color is BGRA (SkColor order), dst is SkPMColor order, so may need to swap R+B.
#if defined(SK_PMCOLOR_IS_RGBA)
color = SkNx_shuffle<2,1,0,3>(color);
#elif defined(SK_PMCOLOR_IS_ARGB)
Sk4b bytes = SkNx_cast<uint8_t>(color);
dst[i] = SkPackARGB32NoCheck(a, bytes[2], bytes[1], bytes[0]);
continue;
#endif
uint8_t* dstBytes = (uint8_t*)(dst+i);
SkNx_cast<uint8_t>(color).store(dstBytes);
@@ -73,7 +73,39 @@ static CFArrayRef SkCTFontManagerCopyAvailableFontFamilyNames() {
#ifdef SK_BUILD_FOR_IOS
return CFArrayCreate(nullptr, nullptr, 0, nullptr);
#else
#if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
return CTFontManagerCopyAvailableFontFamilyNames();
#else
CFMutableArrayRef familyNames =
CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
if (!familyNames) {
return nullptr;
}
ATSFontFamilyIterator iterator;
OSStatus status = ATSFontFamilyIteratorCreate(kATSFontContextGlobal,
nullptr,
nullptr,
kATSOptionFlagsDefaultScope,
&iterator);
if (status != noErr) {
CFRelease(familyNames);
return nullptr;
}
ATSFontFamilyRef family;
while (ATSFontFamilyIteratorNext(iterator, &family) == noErr) {
CFStringRef familyName = nullptr;
if (ATSFontFamilyGetName(family, kATSOptionFlagsDefault, &familyName) == noErr &&
familyName) {
CFArrayAppendValue(familyNames, familyName);
CFRelease(familyName);
}
}
ATSFontFamilyIteratorRelease(&iterator);
return familyNames;
#endif
#endif
}
@@ -908,6 +940,7 @@ CGRGBPixel* Offscreen::getCG(const SkScalerContext_Mac& context, const SkGlyph&
// Skia handles quantization and subpixel positioning,
// so disable quantization and enabe subpixel positioning in CG.
#if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
CGContextSetAllowsFontSubpixelQuantization(fCG, false);
CGContextSetShouldSubpixelQuantizeFonts(fCG, false);
@@ -916,6 +949,7 @@ CGRGBPixel* Offscreen::getCG(const SkScalerContext_Mac& context, const SkGlyph&
// then CG cannot draw the glyph in the correct location without subpixel positioning.
CGContextSetAllowsFontSubpixelPositioning(fCG, true);
CGContextSetShouldSubpixelPositionFonts(fCG, true);
#endif
CGContextSetTextDrawingMode(fCG, kCGTextFill);
@@ -971,7 +1005,13 @@ CGRGBPixel* Offscreen::getCG(const SkScalerContext_Mac& context, const SkGlyph&
// So always make the font transform identity and place the transform on the context.
point = CGPointApplyAffineTransform(point, context.fInvTransform);
#if defined(MAC_OS_X_VERSION_10_7) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7)
CTFontDrawGlyphs(context.fCTFont, &glyphID, &point, 1, fCG);
#else
CGContextSetFont(fCG, CTFontCopyGraphicsFont(context.fCTFont, NULL));
CGContextSetFontSize(fCG, CTFontGetSize(context.fCTFont));
CGContextShowGlyphsAtPositions(fCG, &glyphID, &point, 1);
#endif
SkASSERT(rowBytesPtr);
*rowBytesPtr = rowBytes;
@@ -1682,6 +1722,7 @@ SkAdvancedTypefaceMetrics* SkTypeface_Mac::onGetAdvancedTypefaceMetrics(
static SK_SFNT_ULONG get_font_type_tag(const SkTypeface_Mac* typeface) {
CTFontRef ctFont = typeface->fFontRef.get();
#if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
AutoCFRelease<CFNumberRef> fontFormatRef(
static_cast<CFNumberRef>(CTFontCopyAttribute(ctFont, kCTFontFormatAttribute)));
if (!fontFormatRef) {
@@ -1711,6 +1752,35 @@ static SK_SFNT_ULONG get_font_type_tag(const SkTypeface_Mac* typeface) {
//Just the presence of the FontForge 'FFTM' table seems to throw it off.
return SkSFNTHeader::fontType_WindowsTrueType::TAG;
}
#else
AutoCFRelease<CFStringRef> postScriptName(CTFontCopyPostScriptName(ctFont));
if (!postScriptName) {
return 0;
}
ATSFontRef atsFont =
ATSFontFindFromPostScriptName(postScriptName, kATSOptionFlagsDefault);
if (atsFont == kInvalidFont) {
return 0;
}
SkSFNTHeader header;
ByteCount headerSize = sizeof(header);
if (ATSFontGetTableDirectory(atsFont, headerSize, &header, &headerSize) != noErr ||
headerSize < sizeof(header.fontType)) {
return 0;
}
switch (header.fontType) {
case SkSFNTHeader::fontType_OpenTypeCFF::TAG:
case SkSFNTHeader::fontType_WindowsTrueType::TAG:
case SkSFNTHeader::fontType_MacTrueType::TAG:
case SkSFNTHeader::fontType_PostScript::TAG:
return header.fontType;
default:
return SkSFNTHeader::fontType_WindowsTrueType::TAG;
}
#endif
}
SkStreamAsset* SkTypeface_Mac::onOpenStream(int* ttcIndex) const {
+14 -1
View File
@@ -336,7 +336,20 @@ gfxGraphiteShaper::SetGlyphsFromSegment(DrawTarget *aDrawTarget,
// not a one-to-one mapping with simple metrics: use DetailedGlyph
AutoTArray<gfxShapedText::DetailedGlyph,8> details;
float clusterLoc;
for (uint32_t j = c.baseGlyph; j < c.baseGlyph + c.nGlyphs; ++j) {
uint32_t glyph_start = c.baseGlyph;
uint32_t glyph_end = glyph_start + c.nGlyphs;
if (glyph_end < glyph_start) {
return NS_ERROR_ILLEGAL_VALUE;
}
if (glyph_end - glyph_start > 0xFFFF) {
return NS_ERROR_ILLEGAL_VALUE;
}
if (!details.SetCapacity(glyph_end - glyph_start, fallible)) {
return NS_ERROR_OUT_OF_MEMORY;
}
for (uint32_t j = glyph_start; j < glyph_end; ++j) {
gfxShapedText::DetailedGlyph* d = details.AppendElement();
d->mGlyphID = gids[j];
d->mYOffset = roundY ? NSToIntRound(-yLocs[j]) * dev2appUnits :
+15 -7
View File
@@ -231,11 +231,13 @@ gfxTextRun::ComputeLigatureData(Range aPartRange,
LigatureData result;
const CompressedGlyph *charGlyphs = mCharacterGlyphs;
uint32_t i;
for (i = aPartRange.start; !charGlyphs[i].IsLigatureGroupStart(); --i) {
NS_ASSERTION(i > 0, "Ligature at the start of the run??");
uint32_t i = aPartRange.start;
while (i && !charGlyphs[i].IsLigatureGroupStart()) {
--i;
}
NS_ASSERTION(charGlyphs[i].IsLigatureGroupStart(), "Ligature at run start?");
result.mRange.start = i;
for (i = aPartRange.start + 1;
i < GetLength() && !charGlyphs[i].IsLigatureGroupStart(); ++i) {
}
@@ -1704,21 +1706,27 @@ gfxFontGroup::GetFontAt(int32_t i, uint32_t aCh)
RefPtr<gfxFont> font = ff.Font();
if (!font) {
gfxFontEntry* fe = mFonts[i].FontEntry();
gfxCharacterMap* unicodeRangeMap = nullptr;
RefPtr<gfxFontEntry> fe = ff.FontEntry();
if (!fe) {
return nullptr;
}
RefPtr<gfxCharacterMap> unicodeRangeMap;
if (fe->mIsUserFontContainer) {
gfxUserFontEntry* ufe = static_cast<gfxUserFontEntry*>(fe);
// This raw pointer is OK because fe holds a strong ref to the object.
gfxUserFontEntry* ufe = static_cast<gfxUserFontEntry*>(fe.get());
if (ufe->LoadState() == gfxUserFontEntry::STATUS_NOT_LOADED &&
ufe->CharacterInUnicodeRange(aCh) &&
!FontLoadingForFamily(ff.Family(), aCh)) {
ufe->Load();
ff.CheckState(mSkipDrawing);
}
unicodeRangeMap = ufe->GetUnicodeRangeMap();
// Update fe to refer to the actual platform font entry, rather than the
// webfont wrapper. After this, we no longer have a strong ref to ufe.
fe = ufe->GetPlatformFontEntry();
if (!fe) {
return nullptr;
}
unicodeRangeMap = ufe->GetUnicodeRangeMap();
}
font = fe->FindOrMakeFont(&mStyle, mFonts[i].NeedsBold(),
unicodeRangeMap);
+7 -4
View File
@@ -1637,10 +1637,13 @@ RasterImage::NotifyDecodeComplete(const DecoderFinalStatus& aStatus,
if (!(aDecoderFlags & DecoderFlags::FIRST_FRAME_ONLY) &&
mHasBeenDecoded && mAnimationState) {
// We've finished a full decode of all animation frames and our AnimationState
// has been notified about them all, so let it know not to expect anymore.
mAnimationState->NotifyDecodeComplete();
mAnimationState->UpdateState(mAnimationFinished, this, mSize);
// If we've successfully finished a full decode of all animation frames
// then let our animation state know it's complete and to not to expect
// any more frames.
if (aStatus.mFinished && !aStatus.mHadError) {
mAnimationState->NotifyDecodeComplete();
mAnimationState->UpdateState(mAnimationFinished, this, mSize);
}
}
// Only act on errors if we have no usable frames from the decoder.
+6 -1
View File
@@ -8,8 +8,11 @@
#include "mozilla/CheckedInt.h"
#include "mozilla/TypeTraits.h"
#include <algorithm>
#include "jscntxt.h"
#include "builtin/SelfHostingDefines.h"
#include "irregexp/RegExpParser.h"
#include "jit/InlinableNatives.h"
#include "vm/RegExpStatics.h"
@@ -1754,7 +1757,9 @@ js::RegExpGetSubstitution(JSContext* cx, HandleArrayObject matchResult, HandleLi
// Step 6.
MOZ_ASSERT(position <= string->length());
uint32_t nCaptures = matchResultLength - 1;
// String substitutions can only reference $1 through $99.
uint32_t nCaptures = std::min<uint32_t>(matchResultLength - 1,
REGEXP_MAX_SUBSTITUTION_CAPTURES);
Rooted<CapturesVector> captures(cx, CapturesVector(cx));
if (!captures.reserve(nCaptures))
return false;
+9 -1
View File
@@ -463,6 +463,12 @@ function RegExpGetComplexReplacement(result, matched, S, position,
// Step 14.k.i (reordered).
_DefineDataProperty(captures, capturesLength++, matched);
// String substitutions can only reference $1 through $99. Keep getting and
// stringifying all captures because those operations are observable.
var storedCaptures = functionalReplace ?
nCaptures :
std_Math_min(nCaptures, REGEXP_MAX_SUBSTITUTION_CAPTURES);
// Step 14.g, 14.i, 14.i.iv.
for (var n = 1; n <= nCaptures; n++) {
// Step 14.i.i.
@@ -473,7 +479,9 @@ function RegExpGetComplexReplacement(result, matched, S, position,
capN = ToString(capN);
// Step 14.i.iii.
_DefineDataProperty(captures, capturesLength++, capN);
if (n <= storedCaptures) {
_DefineDataProperty(captures, capturesLength++, capN);
}
}
// Step 14.j.
+2
View File
@@ -79,6 +79,8 @@
#define REGEXP_FLAGS_SLOT 2
#define REGEXP_MAX_SUBSTITUTION_CAPTURES 99
#define REGEXP_IGNORECASE_FLAG 0x01
#define REGEXP_GLOBAL_FLAG 0x02
#define REGEXP_MULTILINE_FLAG 0x04
+2 -2
View File
@@ -8185,7 +8185,7 @@ CodeGenerator::visitStoreElementV(LStoreElementV* lir)
template <typename T> void
CodeGenerator::emitStoreElementHoleT(T* lir)
{
static_assert(std::is_same<T, LStoreElementHoleT>::value || std::is_same<T, LFallibleStoreElementT>::value,
static_assert(std::is_same_v<T, LStoreElementHoleT> || std::is_same_v<T, LFallibleStoreElementT>,
"emitStoreElementHoleT called with unexpected argument type");
OutOfLineStoreElementHole* ool = new(alloc()) OutOfLineStoreElementHole(lir);
@@ -8244,7 +8244,7 @@ CodeGenerator::visitStoreElementHoleT(LStoreElementHoleT* lir)
template <typename T> void
CodeGenerator::emitStoreElementHoleV(T* lir)
{
static_assert(std::is_same<T, LStoreElementHoleV>::value || std::is_same<T, LFallibleStoreElementV>::value,
static_assert(std::is_same_v<T, LStoreElementHoleV> || std::is_same_v<T, LFallibleStoreElementV>,
"emitStoreElementHoleV called with unexpected parameter type");
OutOfLineStoreElementHole* ool = new(alloc()) OutOfLineStoreElementHole(lir);
+3
View File
@@ -494,6 +494,9 @@ OnLeaveBaselineFrame(JSContext* cx, const JitFrameIterator& frame, jsbytecode* p
{
BaselineFrame* baselineFrame = frame.baselineFrame();
if (jit::DebugEpilogue(cx, baselineFrame, pc, frameOk)) {
if (!baselineFrame->hasReturnValue()) {
baselineFrame->setReturnValue(UndefinedValue());
}
rfe->kind = ResumeFromException::RESUME_FORCED_RETURN;
rfe->framePointer = frame.fp() - BaselineFrame::FramePointerOffset;
rfe->stackPointer = reinterpret_cast<uint8_t*>(baselineFrame);
+5 -4
View File
@@ -312,12 +312,13 @@ cvt_s(SprintfState* ss, const char* s, int width, int prec, int flags)
s = generic_null_str(s);
// Limit string length by precision value
int slen = int(generic_strlen(s));
if (0 < prec && prec < slen)
slen = prec;
size_t slen = strnlen(s, size_t(prec));
if (slen > INT_MAX) {
return false;
}
// and away we go
return fill2(ss, s, slen, width, flags);
return fill2(ss, s, int(slen), width, flags);
}
/*
+4 -4
View File
@@ -2871,8 +2871,8 @@ static JSString* ReplaceAll(JSContext* cx, JSLinearString* str,
// Step 13.
StringBuffer result(cx);
if (std::is_same<StrChar, char16_t>::value ||
std::is_same<RepChar, char16_t>::value) {
if (std::is_same_v<StrChar, char16_t> ||
std::is_same_v<RepChar, char16_t>) {
if (!result.ensureTwoByteChars()) {
return nullptr;
}
@@ -2954,8 +2954,8 @@ static JSString* ReplaceAllInterleave(JSContext* cx, JSLinearString* str,
// Step 13.
StringBuffer result(cx);
if (std::is_same<StrChar, char16_t>::value ||
std::is_same<RepChar, char16_t>::value) {
if (std::is_same_v<StrChar, char16_t> ||
std::is_same_v<RepChar, char16_t>) {
if (!result.ensureTwoByteChars()) {
return nullptr;
}
+20 -20
View File
@@ -309,26 +309,26 @@ InflateUTF8StringToBuffer(ContextT* cx, const UTF8Chars src, CharT* dst, size_t*
while (v & (0x80 >> n))
n++;
#define INVALID(report, arg, n2) \
do { \
if (Action == CountAndReportInvalids) { \
report(cx, arg); \
return false; \
} else if (Action == AssertNoInvalids) { \
MOZ_CRASH("invalid UTF-8 string: " # report); \
} else { \
if (Action == Copy) { \
if (std::is_same<decltype(dst[0]), Latin1Char>::value) \
dst[j] = CharT(REPLACE_UTF8_LATIN1); \
else \
dst[j] = CharT(REPLACE_UTF8); \
} else { \
MOZ_ASSERT(Action == CountAndIgnoreInvalids || \
Action == FindEncoding); \
} \
n = n2; \
goto invalidMultiByteCodeUnit; \
} \
#define INVALID(report, arg, n2) \
do { \
if (Action == CountAndReportInvalids) { \
report(cx, arg); \
return false; \
} else if (Action == AssertNoInvalids) { \
MOZ_CRASH("invalid UTF-8 string: " # report); \
} else { \
if (Action == Copy) { \
if (std::is_same_v<decltype(dst[0]), Latin1Char>) \
dst[j] = CharT(REPLACE_UTF8_LATIN1); \
else \
dst[j] = CharT(REPLACE_UTF8); \
} else { \
MOZ_ASSERT(Action == CountAndIgnoreInvalids || \
Action == FindEncoding); \
} \
n = n2; \
goto invalidMultiByteCodeUnit; \
} \
} while (0)
// Check the leading byte.
+1 -1
View File
@@ -1138,7 +1138,7 @@ class StaticStrings
}
template <typename CharT,
typename = typename std::enable_if<!std::is_const<CharT>::value>::type>
typename = typename std::enable_if_t<!std::is_const_v<CharT>>>
MOZ_ALWAYS_INLINE JSAtom* lookup(CharT* chars, size_t length) {
// Collapse the remaining |CharT*| to |const CharT*| to avoid excess
// instantiations.
+2 -2
View File
@@ -677,12 +677,12 @@ class ElementSpecific
return true;
}
if (std::is_same<T, int64_t>::value) {
if (std::is_same_v<T, int64_t>) {
JS_TRY_VAR_OR_RETURN_FALSE(cx, *result, ToBigInt64(cx, v));
return true;
}
if (std::is_same<T, uint64_t>::value) {
if (std::is_same_v<T, uint64_t>) {
JS_TRY_VAR_OR_RETURN_FALSE(cx, *result, ToBigUint64(cx, v));
return true;
}
+7
View File
@@ -411,6 +411,13 @@ DottedCornerFinder::FindBestOverlap(Float aMinR, Float aMinBorderRadius,
mCount = mMaxCount;
break;
}
// GetCountAndLastOverlap() failed without writing |count| and
// |actualOverlap|: the walk needed more than mMaxCount circles, i.e.
// this overlap produces too many circles. Narrow the search toward
// smaller overlaps.
upper = overlap;
overlap = (upper + lower) / 2.0f;
continue;
}
if (j == 0) {
+17 -8
View File
@@ -5107,19 +5107,28 @@ nsLayoutUtils::IntrinsicForAxis(PhysicalAxis aAxis,
styleMinBSize.GetCoordValue() == 0)) ||
styleMaxBSize.GetUnit() != eStyleUnit_None) {
AspectRatio ratio = aFrame->GetIntrinsicRatio();
AspectRatio ratio = aFrame->GetAspectRatio();
if (ratio) {
// Convert 'ratio' if necessary, so that it's storing ISize/BSize:
if (!horizontalAxis) {
ratio = ratio.Inverted();
}
AddStateBitToAncestors(aFrame,
NS_FRAME_DESCENDANT_INTRINSIC_ISIZE_DEPENDS_ON_BSIZE);
const WritingMode wm = aFrame->GetWritingMode();
LogicalSize boxSizingAdjust(wm);
boxSizingAdjust.ISize(wm) =
GetDefiniteSizeTakenByBoxSizing(boxSizing, aFrame, isInlineAxis,
aFlags & IGNORE_PADDING,
aPercentageBasis);
nscoord bSizeTakenByBoxSizing =
GetDefiniteSizeTakenByBoxSizing(boxSizing, aFrame, !isInlineAxis,
aFlags & IGNORE_PADDING,
aPercentageBasis);
boxSizingAdjust.BSize(wm) = bSizeTakenByBoxSizing;
auto iSizeFromBSize = [&](nscoord aBSize) {
LogicalAxis dependentAxis =
isInlineAxis ? eLogicalAxisInline : eLogicalAxisBlock;
return ratio.ComputeRatioDependentSize(
dependentAxis, wm, aBSize, boxSizingAdjust);
};
// NOTE: This is only the minContentSize if we've been passed MIN_INTRINSIC_ISIZE
// (which is fine, because this should only be used inside a check for that flag).
nscoord minContentSize = result;
@@ -5128,14 +5137,14 @@ nsLayoutUtils::IntrinsicForAxis(PhysicalAxis aAxis,
(aPercentageBasis.isNothing() &&
GetPercentBSize(styleBSize, aFrame, horizontalAxis, h))) {
h = std::max(0, h - bSizeTakenByBoxSizing);
result = ratio.ApplyTo(h);
result = iSizeFromBSize(h);
}
if (GetDefiniteSize(styleMaxBSize, aFrame, !isInlineAxis, aPercentageBasis, &h) ||
(aPercentageBasis.isNothing() &&
GetPercentBSize(styleMaxBSize, aFrame, horizontalAxis, h))) {
h = std::max(0, h - bSizeTakenByBoxSizing);
nscoord maxISize = ratio.ApplyTo(h);
nscoord maxISize = iSizeFromBSize(h);
if (maxISize < result) {
result = maxISize;
}
@@ -5148,7 +5157,7 @@ nsLayoutUtils::IntrinsicForAxis(PhysicalAxis aAxis,
(aPercentageBasis.isNothing() &&
GetPercentBSize(styleMinBSize, aFrame, horizontalAxis, h))) {
h = std::max(0, h - bSizeTakenByBoxSizing);
nscoord minISize = ratio.ApplyTo(h);
nscoord minISize = iSizeFromBSize(h);
if (minISize > result) {
result = minISize;
}
+18 -1
View File
@@ -234,7 +234,18 @@ nsHTMLButtonControlFrame::ReflowButtonContents(nsPresContext* aPresContext,
{
WritingMode wm = GetWritingMode();
LogicalSize availSize = aButtonReflowInput.ComputedSize(wm);
availSize.BSize(wm) = NS_INTRINSICSIZE;
// Identify if the inner anonymous block is actually functioning as a flex or grid container.
nsIAtom* kidType = aFirstKid->GetType();
bool isFlexOrGrid = (kidType == nsGkAtoms::flexContainerFrame ||
kidType == nsGkAtoms::gridContainerFrame);
// Preserve the button's definite BSize ONLY for flex/grid children so they
// see a definite containing block main size. For standard buttons, clobber
// to intrinsic so standard vertical centering (extraSpace) calculations work.
if (!isFlexOrGrid || aButtonReflowInput.ComputedBSize() == NS_INTRINSICSIZE) {
availSize.BSize(wm) = NS_INTRINSICSIZE;
}
// shorthand for a value we need to use in a bunch of places
const LogicalMargin& clbp = aButtonReflowInput.ComputedLogicalBorderPadding();
@@ -248,6 +259,12 @@ nsHTMLButtonControlFrame::ReflowButtonContents(nsPresContext* aPresContext,
aFirstKid,
availSize);
// Apply the definite BSize directly on the inner reflow input ONLY if it's
// a flex or grid container, allowing it to be used as-is.
if (isFlexOrGrid && aButtonReflowInput.ComputedBSize() != NS_INTRINSICSIZE) {
contentsReflowInput.SetComputedBSize(aButtonReflowInput.ComputedBSize());
}
nsReflowStatus contentsReflowStatus;
ReflowOutput contentsDesiredSize(aButtonReflowInput);
childPos.B(wm) = 0; // This will be set properly later, after reflowing the
+39
View File
@@ -0,0 +1,39 @@
/* 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/AspectRatio.h"
#include "mozilla/WritingModes.h"
namespace mozilla {
nscoord
AspectRatio::ComputeRatioDependentSize(
LogicalAxis aRatioDependentAxis,
const WritingMode& aWM,
nscoord aRatioDeterminingSize,
const LogicalSize& aContentBoxToBoxSizingAdjust) const
{
MOZ_DIAGNOSTIC_ASSERT(*this);
LogicalSize adjust(aWM);
if (mUseBoxSizing == UseBoxSizing::Yes) {
adjust = aContentBoxToBoxSizingAdjust;
}
AspectRatio logicalRatio = aWM.IsVertical() ? Inverted() : *this;
nscoord result;
if (aRatioDependentAxis == eLogicalAxisInline) {
result = logicalRatio.ApplyTo(aRatioDeterminingSize +
adjust.BSize(aWM)) -
adjust.ISize(aWM);
} else {
result = logicalRatio.Inverted().ApplyTo(aRatioDeterminingSize +
adjust.ISize(aWM)) -
adjust.BSize(aWM);
}
return std::max(nscoord(0), result);
}
} // namespace mozilla
+45 -7
View File
@@ -9,21 +9,46 @@
/* The aspect ratio of a box, in a "width / height" format. */
#include "mozilla/Attributes.h"
#include "mozilla/LogicalTypes.h"
#include "nsCoord.h"
#include "nsSize.h"
#include <algorithm>
#include <limits>
namespace mozilla {
struct AspectRatio {
AspectRatio() : mRatio(0.0f) {}
explicit AspectRatio(float aRatio) : mRatio(std::max(aRatio, 0.0f)) {}
class LogicalSize;
class WritingMode;
static AspectRatio FromSize(float aWidth, float aHeight) {
enum class UseBoxSizing : uint8_t {
// Natural ratios and "auto <ratio>" always use content-box dimensions.
No,
// A specified <ratio> uses the dimensions selected by box-sizing.
Yes,
};
struct AspectRatio {
AspectRatio()
: mRatio(0.0f)
, mUseBoxSizing(UseBoxSizing::No)
{}
explicit AspectRatio(float aRatio,
UseBoxSizing aUseBoxSizing = UseBoxSizing::No)
: mRatio(std::max(aRatio, 0.0f))
, mUseBoxSizing(aUseBoxSizing)
{}
static AspectRatio FromSize(float aWidth, float aHeight,
UseBoxSizing aUseBoxSizing = UseBoxSizing::No) {
if (aWidth == 0.0f || aHeight == 0.0f) {
return AspectRatio();
}
return AspectRatio(aWidth / aHeight);
float ratio = aWidth / aHeight;
if (!std::isfinite(ratio)) {
return AspectRatio();
}
return AspectRatio(ratio, aUseBoxSizing);
}
static AspectRatio FromSize(nsSize aSize) {
@@ -55,11 +80,23 @@ struct AspectRatio {
// 0.0f in the division here (so that valid ratios always generate other
// valid ratios when inverted).
return AspectRatio(
std::max(std::numeric_limits<float>::epsilon(), 1.0f / mRatio));
std::max(std::numeric_limits<float>::epsilon(), 1.0f / mRatio),
mUseBoxSizing);
}
/**
* Computes a content-box size in the ratio-dependent axis from a
* content-box size in the ratio-determining axis.
*/
nscoord ComputeRatioDependentSize(
LogicalAxis aRatioDependentAxis,
const WritingMode& aWM,
nscoord aRatioDeterminingSize,
const LogicalSize& aContentBoxToBoxSizingAdjust) const;
bool operator==(const AspectRatio& aOther) const {
return mRatio == aOther.mRatio;
return mRatio == aOther.mRatio &&
mUseBoxSizing == aOther.mUseBoxSizing;
}
bool operator!=(const AspectRatio& aOther) const {
@@ -73,6 +110,7 @@ struct AspectRatio {
private:
// 0.0f represents no aspect ratio.
float mRatio;
UseBoxSizing mUseBoxSizing;
};
} // namespace mozilla
+37
View File
@@ -0,0 +1,37 @@
/* -*- 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_LogicalTypes_h
#define mozilla_LogicalTypes_h
namespace mozilla {
// Logical axis, edge, side and corner constants for use in various places.
enum LogicalAxis {
eLogicalAxisBlock = 0x0,
eLogicalAxisInline = 0x1
};
enum LogicalEdge {
eLogicalEdgeStart = 0x0,
eLogicalEdgeEnd = 0x1
};
enum LogicalSide {
eLogicalSideBStart = (eLogicalAxisBlock << 1) | eLogicalEdgeStart, // 0x0
eLogicalSideBEnd = (eLogicalAxisBlock << 1) | eLogicalEdgeEnd, // 0x1
eLogicalSideIStart = (eLogicalAxisInline << 1) | eLogicalEdgeStart, // 0x2
eLogicalSideIEnd = (eLogicalAxisInline << 1) | eLogicalEdgeEnd // 0x3
};
enum LogicalCorner
{
eLogicalCornerBStartIStart = 0,
eLogicalCornerBStartIEnd = 1,
eLogicalCornerBEndIEnd = 2,
eLogicalCornerBEndIStart = 3
};
} // namespace mozilla
#endif // mozilla_LogicalTypes_h
+1
View File
@@ -6,6 +6,7 @@
#ifndef WritingModes_h_
#define WritingModes_h_
#include "mozilla/LogicalTypes.h"
#include "nsRect.h"
#include "nsStyleContext.h"
#include "nsBidiUtils.h"
+2
View File
@@ -110,6 +110,7 @@ EXPORTS += [
EXPORTS.mozilla += [
'AspectRatio.h',
'CSSAlignUtils.h',
'LogicalTypes.h',
'ReflowInput.h',
'ReflowOutput.h',
'WritingModes.h',
@@ -124,6 +125,7 @@ EXPORTS.mozilla.layout += [
]
UNIFIED_SOURCES += [
'AspectRatio.cpp',
'AsyncScrollBase.cpp',
'BlockReflowInput.cpp',
'CSSAlignUtils.cpp',
+1 -1
View File
@@ -1945,7 +1945,7 @@ FlexItem::FlexItem(ReflowInput& aFlexItemReflowInput,
: mFrame(aFlexItemReflowInput.mFrame),
mFlexGrow(aFlexGrow),
mFlexShrink(aFlexShrink),
mIntrinsicRatio(mFrame->GetIntrinsicRatio()),
mIntrinsicRatio(mFrame->GetAspectRatio()),
mBorderPadding(aFlexItemReflowInput.ComputedPhysicalBorderPadding()),
mMargin(aFlexItemReflowInput.ComputedPhysicalMargin()),
mMainMinSize(aMainMinSize),
+67 -26
View File
@@ -4655,10 +4655,44 @@ nsFrame::GetIntrinsicSize()
/* virtual */ AspectRatio
nsFrame::GetIntrinsicRatio()
{
const nsStylePosition* stylePos = StylePosition();
return stylePos->mAspectRatio == 0.0f
? AspectRatio()
: AspectRatio(stylePos->mAspectRatio);
return AspectRatio();
}
AspectRatio
nsIFrame::GetAspectRatio()
{
// The property does not apply to inline boxes or internal ruby/table boxes.
nsIAtom* type = GetType();
if (type == nsGkAtoms::inlineFrame ||
RubyUtils::IsRubyBox(type) ||
type == nsGkAtoms::tableCellFrame ||
type == nsGkAtoms::tableColFrame ||
type == nsGkAtoms::tableColGroupFrame ||
type == nsGkAtoms::tableRowFrame ||
type == nsGkAtoms::tableRowGroupFrame) {
return AspectRatio();
}
const StyleAspectRatio& styleRatio = StylePosition()->mAspectRatio;
// A non-auto, non-degenerate ratio overrides the natural ratio and uses the
// box selected by box-sizing.
if (!styleRatio.mAuto && styleRatio.HasUsableRatio()) {
return AspectRatio::FromSize(styleRatio.mWidth, styleRatio.mHeight,
UseBoxSizing::Yes);
}
if (AspectRatio intrinsicRatio = GetIntrinsicRatio()) {
return intrinsicRatio;
}
// The fallback in "auto <ratio>" always operates on the content box.
if (styleRatio.HasUsableRatio()) {
return AspectRatio::FromSize(styleRatio.mWidth, styleRatio.mHeight,
UseBoxSizing::No);
}
return AspectRatio();
}
void
@@ -4727,11 +4761,11 @@ nsFrame::ComputeSize(nsRenderingContext* aRenderingContext,
const LogicalSize& aPadding,
ComputeSizeFlags aFlags)
{
AspectRatio intrinsicRatio = GetIntrinsicRatio();
if (intrinsicRatio) {
AspectRatio aspectRatio = GetAspectRatio();
if (aspectRatio) {
return ComputeSizeWithIntrinsicDimensions(aRenderingContext, aWM,
GetIntrinsicSize(),
intrinsicRatio,
aspectRatio,
aCBSize, aMargin,
aBorder, aPadding,
aFlags);
@@ -4976,8 +5010,6 @@ nsFrame::ComputeSizeWithIntrinsicDimensions(nsRenderingContext* aRenderingConte
const LogicalSize& aPadding,
ComputeSizeFlags aFlags)
{
auto logicalRatio =
aWM.IsVertical() ? aIntrinsicRatio.Inverted() : aIntrinsicRatio;
const nsStylePosition* stylePos = StylePosition();
const nsStyleCoord* inlineStyleCoord = &stylePos->ISize(aWM);
const nsStyleCoord* blockStyleCoord = &stylePos->BSize(aWM);
@@ -5039,6 +5071,14 @@ nsFrame::ComputeSizeWithIntrinsicDimensions(nsRenderingContext* aRenderingConte
if (stylePos->mBoxSizing == StyleBoxSizing::Border) {
boxSizingAdjust = aBorder + aPadding;
}
auto iSizeFromBSize = [&](nscoord aBSize) {
return aIntrinsicRatio.ComputeRatioDependentSize(
eLogicalAxisInline, aWM, aBSize, boxSizingAdjust);
};
auto bSizeFromISize = [&](nscoord aISize) {
return aIntrinsicRatio.ComputeRatioDependentSize(
eLogicalAxisBlock, aWM, aISize, boxSizingAdjust);
};
nscoord boxSizingToMarginEdgeISize =
aMargin.ISize(aWM) + aBorder.ISize(aWM) + aPadding.ISize(aWM) -
boxSizingAdjust.ISize(aWM);
@@ -5129,7 +5169,8 @@ nsFrame::ComputeSizeWithIntrinsicDimensions(nsRenderingContext* aRenderingConte
bSize = nsLayoutUtils::ComputeBSizeValue(aCBSize.BSize(aWM),
boxSizingAdjust.BSize(aWM),
*blockStyleCoord);
} else if (MOZ_UNLIKELY(isGridItem)) {
} else if (MOZ_UNLIKELY(isGridItem) &&
!(aFlags & nsIFrame::eUseAutoBSize)) {
MOZ_ASSERT(!IS_TRUE_OVERFLOW_CONTAINER(this));
// 'auto' block-size for grid-level box - apply 'stretch' as needed:
auto cbSize = aCBSize.BSize(aWM);
@@ -5230,9 +5271,9 @@ nsFrame::ComputeSizeWithIntrinsicDimensions(nsRenderingContext* aRenderingConte
if (hasIntrinsicISize) {
tentISize = intrinsicISize;
} else if (hasIntrinsicBSize && logicalRatio) {
tentISize = logicalRatio.ApplyTo(intrinsicBSize);
} else if (logicalRatio) {
} else if (hasIntrinsicBSize && aIntrinsicRatio) {
tentISize = iSizeFromBSize(intrinsicBSize);
} else if (aIntrinsicRatio) {
tentISize = aCBSize.ISize(aWM) - boxSizingToMarginEdgeISize; // XXX scrollbar?
if (tentISize < 0) tentISize = 0;
} else {
@@ -5249,8 +5290,8 @@ nsFrame::ComputeSizeWithIntrinsicDimensions(nsRenderingContext* aRenderingConte
if (hasIntrinsicBSize) {
tentBSize = intrinsicBSize;
} else if (logicalRatio) {
tentBSize = logicalRatio.Inverted().ApplyTo(tentISize);
} else if (aIntrinsicRatio) {
tentBSize = bSizeFromISize(tentISize);
} else {
tentBSize = nsPresContext::CSSPixelsToAppUnits(150);
}
@@ -5261,39 +5302,39 @@ nsFrame::ComputeSizeWithIntrinsicDimensions(nsRenderingContext* aRenderingConte
stretchB = (stretchI == eStretch ? eStretch : eStretchPreservingRatio);
}
if (logicalRatio) {
if (aIntrinsicRatio) {
if (stretchI == eStretch) {
tentISize = iSize; // * / 'stretch'
if (stretchB == eStretch) {
tentBSize = bSize; // 'stretch' / 'stretch'
} else if (stretchB == eStretchPreservingRatio) {
// 'normal' / 'stretch'
tentBSize = logicalRatio.Inverted().ApplyTo(iSize);
tentBSize = bSizeFromISize(iSize);
}
} else if (stretchB == eStretch) {
tentBSize = bSize; // 'stretch' / * (except 'stretch')
if (stretchI == eStretchPreservingRatio) {
// 'stretch' / 'normal'
tentISize = logicalRatio.ApplyTo(bSize);
tentISize = iSizeFromBSize(bSize);
}
} else if (stretchI == eStretchPreservingRatio) {
tentISize = iSize; // * (except 'stretch') / 'normal'
tentBSize = logicalRatio.Inverted().ApplyTo(iSize);
tentBSize = bSizeFromISize(iSize);
if (stretchB == eStretchPreservingRatio && tentBSize > bSize) {
// Stretch within the CB size with preserved intrinsic ratio.
tentBSize = bSize; // 'normal' / 'normal'
tentISize = logicalRatio.ApplyTo(bSize);
tentISize = iSizeFromBSize(bSize);
}
} else if (stretchB == eStretchPreservingRatio) {
tentBSize = bSize; // 'normal' / * (except 'normal' and 'stretch')
tentISize = logicalRatio.ApplyTo(bSize);
tentISize = iSizeFromBSize(bSize);
}
}
// ComputeAutoSizeWithIntrinsicDimensions preserves the ratio when applying
// the min/max-size. We don't want that when we have 'stretch' in either
// axis because tentISize/tentBSize is likely not according to ratio now.
if (logicalRatio && stretchI != eStretch && stretchB != eStretch) {
if (aIntrinsicRatio && stretchI != eStretch && stretchB != eStretch) {
nsSize autoSize = nsLayoutUtils::
ComputeAutoSizeWithIntrinsicDimensions(minISize, minBSize,
maxISize, maxBSize,
@@ -5314,8 +5355,8 @@ nsFrame::ComputeSizeWithIntrinsicDimensions(nsRenderingContext* aRenderingConte
// 'auto' iSize, non-'auto' bSize
bSize = NS_CSS_MINMAX(bSize, minBSize, maxBSize);
if (stretchI != eStretch) {
if (logicalRatio) {
iSize = logicalRatio.ApplyTo(bSize);
if (aIntrinsicRatio) {
iSize = iSizeFromBSize(bSize);
} else if (hasIntrinsicISize) {
if (!((aFlags & ComputeSizeFlags::eIClampMarginBoxMinSize) &&
intrinsicISize > iSize)) {
@@ -5334,8 +5375,8 @@ nsFrame::ComputeSizeWithIntrinsicDimensions(nsRenderingContext* aRenderingConte
// non-'auto' iSize, 'auto' bSize
iSize = NS_CSS_MINMAX(iSize, minISize, maxISize);
if (stretchB != eStretch) {
if (logicalRatio) {
bSize = logicalRatio.Inverted().ApplyTo(iSize);
if (aIntrinsicRatio) {
bSize = bSizeFromISize(iSize);
} else if (hasIntrinsicBSize) {
if (!((aFlags & ComputeSizeFlags::eBClampMarginBoxMinSize) &&
intrinsicBSize > bSize)) {
+5 -1
View File
@@ -318,7 +318,11 @@ nsHTMLFramesetFrame::Init(nsIContent* aContent,
mChildFrameborder[mChildCount] = GetFrameBorder(child);
mChildBorderColors[mChildCount].Set(GetBorderColor(child));
}
child->SetPrimaryFrame(frame);
if (MOZ_LIKELY(!child->GetPrimaryFrame())) {
// Child might have a pre-existing primary frame if we're doing fixed-pos
// replication... So, only set it if there is no primary frame yet.
child->SetPrimaryFrame(frame);
}
mFrames.AppendFrame(nullptr, frame);
+1 -2
View File
@@ -225,7 +225,7 @@ nsHTMLCanvasFrame::ComputeSize(nsRenderingContext *aRenderingContext,
intrinsicSize.width.SetCoordValue(nsPresContext::CSSPixelsToAppUnits(size.width));
intrinsicSize.height.SetCoordValue(nsPresContext::CSSPixelsToAppUnits(size.height));
AspectRatio intrinsicRatio = GetIntrinsicRatio();
AspectRatio intrinsicRatio = GetAspectRatio();
return ComputeSizeWithIntrinsicDimensions(aRenderingContext, aWM,
intrinsicSize, intrinsicRatio,
@@ -424,4 +424,3 @@ nsHTMLCanvasFrame::GetFrameName(nsAString& aResult) const
return MakeFrameName(NS_LITERAL_STRING("HTMLCanvas"), aResult);
}
#endif
+6
View File
@@ -2078,6 +2078,12 @@ public:
virtual mozilla::IntrinsicSize GetIntrinsicSize() = 0;
/**
* Get the preferred aspect ratio after applying the aspect-ratio property
* to this frame's natural ratio.
*/
mozilla::AspectRatio GetAspectRatio();
/**
* Get the intrinsic ratio of this element, or a default-constructed
* AspectRatio if it has no intrinsic ratio.
+6 -4
View File
@@ -320,7 +320,7 @@ ComputeIntrinsicSize(imgIContainer* aImage,
}
*/
if (aUseMappedRatio && aFrame.StylePosition()->mAspectRatio != 0.0f) {
if (aUseMappedRatio && aFrame.StylePosition()->mAspectRatio.HasRatio()) {
return IntrinsicSize();
}
@@ -375,8 +375,10 @@ ComputeAspectRatio(imgIContainer* aImage,
return fromImage;
}
}
if (aUseMappedRatio && aFrame.StylePosition()->mAspectRatio != 0.0f) {
return AspectRatio(aFrame.StylePosition()->mAspectRatio);
if (aUseMappedRatio &&
aFrame.StylePosition()->mAspectRatio.HasUsableRatio()) {
const StyleAspectRatio& ratio = aFrame.StylePosition()->mAspectRatio;
return AspectRatio::FromSize(ratio.mWidth, ratio.mHeight);
}
if (aFrame.ShouldShowBrokenImageIcon()) {
return AspectRatio(1.0f);
@@ -891,7 +893,7 @@ nsImageFrame::ComputeSize(nsRenderingContext *aRenderingContext,
}
return ComputeSizeWithIntrinsicDimensions(aRenderingContext, aWM,
intrinsicSize, mIntrinsicRatio,
intrinsicSize, GetAspectRatio(),
aCBSize, aMargin, aBorder, aPadding,
aFlags);
}
+1 -1
View File
@@ -786,7 +786,7 @@ IsPercentageAware(const nsIFrame* aFrame)
// is calculated from the constraint equation used for
// block-level, non-replaced elements in normal flow.
nsIFrame *f = const_cast<nsIFrame*>(aFrame);
if (f->GetIntrinsicRatio() &&
if (f->GetAspectRatio() &&
// Some percents are treated like 'auto', so check != coord
pos->mHeight.GetUnit() != eStyleUnit_Coord) {
const IntrinsicSize &intrinsicSize = f->GetIntrinsicSize();
+1 -1
View File
@@ -721,7 +721,7 @@ nsSubDocumentFrame::ComputeSize(nsRenderingContext* aRenderingContext,
if (subDocRoot) {
return ComputeSizeWithIntrinsicDimensions(aRenderingContext, aWM,
subDocRoot->GetIntrinsicSize(),
subDocRoot->GetIntrinsicRatio(),
GetAspectRatio(),
aCBSize, aMargin, aBorder,
aPadding, aFlags);
}
+1 -6
View File
@@ -543,13 +543,8 @@ nsVideoFrame::ComputeSize(nsRenderingContext *aRenderingContext,
intrinsicSize.width.SetCoordValue(size.width);
intrinsicSize.height.SetCoordValue(size.height);
// Only video elements have an intrinsic ratio.
auto intrinsicRatio = HasVideoElement() ?
AspectRatio::FromSize(size) :
AspectRatio();
return ComputeSizeWithIntrinsicDimensions(aRenderingContext, aWM,
intrinsicSize, intrinsicRatio,
intrinsicSize, GetAspectRatio(),
aCBSize, aMargin, aBorder, aPadding,
aFlags);
}
+2 -1
View File
@@ -953,11 +953,12 @@ inDOMUtils::GetCSSValuesForProperty(const nsAString& aProperty,
GetOtherValuesForProperty(propertyParserVariant, array);
}
}
// All CSS properties take initial, inherit, unset, and revert.
// All CSS properties take initial, inherit, unset, revert, and revert-layer.
InsertNoDuplicates(array, NS_LITERAL_STRING("initial"));
InsertNoDuplicates(array, NS_LITERAL_STRING("inherit"));
InsertNoDuplicates(array, NS_LITERAL_STRING("unset"));
InsertNoDuplicates(array, NS_LITERAL_STRING("revert"));
InsertNoDuplicates(array, NS_LITERAL_STRING("revert-layer"));
*aLength = array.Length();
char16_t** ret =
@@ -0,0 +1,37 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Grid: aspect-ratio contributes to an auto row reference</title>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.gallery {
display: grid;
width: 640px;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 20px;
padding: 30px;
}
.item {
position: relative;
height: 280px;
overflow: hidden;
}
.item > div {
width: 100%;
height: 100%;
background: green;
}
</style>
</head>
<body>
<div class="gallery">
<div class="item"><div></div></div>
<div class="item"><div></div></div>
</div>
</body>
</html>
@@ -0,0 +1,39 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Grid: aspect-ratio contributes to an auto row</title>
<link rel="match" href="grid-item-aspect-ratio-001-ref.html">
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.gallery {
display: grid;
width: 640px;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 20px;
padding: 30px;
}
.item {
position: relative;
aspect-ratio: 1;
overflow: hidden;
background: red;
}
.item > div {
width: 100%;
height: 100%;
background: green;
}
</style>
</head>
<body>
<div class="gallery">
<div class="item"><div></div></div>
<div class="item"><div></div></div>
</div>
</body>
</html>
+1
View File
@@ -280,5 +280,6 @@ asserts(0-10) == grid-fragmentation-015.html grid-fragmentation-015-ref.html # b
== grid-fragmentation-dyn2-031.html grid-fragmentation-031-ref.html
== bug1306106.html bug1306106-ref.html
== grid-percent-intrinsic-sizing-001.html grid-percent-intrinsic-sizing-001-ref.html
== grid-item-aspect-ratio-001.html grid-item-aspect-ratio-001-ref.html
== bug1349571.html bug1349571-ref.html
== bug1356820.html bug1356820-ref.html
+80
View File
@@ -1987,6 +1987,86 @@ CSSStyleSheet::DeleteRuleInternal(uint32_t aIndex, ErrorResult& aRv)
}
}
void
CSSStyleSheet::ReplaceSyncInternal(const nsAString& aText, ErrorResult& aRv)
{
MOZ_ASSERT(mInner->mComplete);
RefPtr<CSSStyleSheet> parsedSheet =
new CSSStyleSheet(mParsingMode, GetCORSMode(), GetReferrerPolicy());
parsedSheet->SetURIs(mInner->mSheetURI, mInner->mOriginalSheetURI,
mInner->mBaseURI);
parsedSheet->SetPrincipal(mInner->mPrincipal);
parsedSheet->SetComplete();
nsCSSParser parser(nullptr, parsedSheet);
nsresult rv = parser.ParseSheet(aText, parsedSheet->GetSheetURI(),
parsedSheet->GetBaseURI(),
parsedSheet->Principal(), 1);
if (NS_FAILED(rv)) {
parsedSheet->mInner->mOrderedRules.EnumerateForwards(SetStyleSheetReference,
nullptr);
parsedSheet->mInner->mOrderedRules.Clear();
}
for (int32_t index = parsedSheet->mInner->mOrderedRules.Count() - 1;
index >= 0; --index) {
RefPtr<css::Rule> rule = parsedSheet->mInner->mOrderedRules.ObjectAt(index);
if (rule->GetType() == css::Rule::IMPORT_RULE) {
parsedSheet->mInner->mOrderedRules.RemoveObjectAt(index);
rule->SetStyleSheet(nullptr);
}
}
mozAutoDocUpdate updateBatch(mDocument, UPDATE_STYLE, true);
WillDirty();
while (mInner->mOrderedRules.Count() != 0) {
RefPtr<css::Rule> rule =
mInner->mOrderedRules.ObjectAt(mInner->mOrderedRules.Count() - 1);
mInner->mOrderedRules.RemoveObjectAt(mInner->mOrderedRules.Count() - 1);
rule->SetStyleSheet(nullptr);
if (mDocument) {
mDocument->StyleRuleRemoved(this, rule);
}
}
for (CSSStyleSheet* child = mInner->mFirstChild; child; ) {
NS_ASSERTION(child->mParent == this, "Child sheet is not parented to this!");
CSSStyleSheet* next = child->mNext;
child->mParent = nullptr;
child->mDocument = nullptr;
child->mNext = nullptr;
child = next;
}
mInner->mFirstChild = nullptr;
mInner->mNameSpaceMap = nullptr;
for (int32_t index = 0; index < parsedSheet->mInner->mOrderedRules.Count();
++index) {
RefPtr<css::Rule> rule = parsedSheet->mInner->mOrderedRules.ObjectAt(index);
if (!mInner->mOrderedRules.AppendObject(rule)) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return;
}
rule->SetStyleSheet(this);
}
parsedSheet->mInner->mOrderedRules.Clear();
parsedSheet->mInner->mNameSpaceMap = nullptr;
mInner->RebuildNameSpaces();
DidDirty();
if (mDocument) {
for (int32_t index = 0; index < mInner->mOrderedRules.Count(); ++index) {
RefPtr<css::Rule> rule = mInner->mOrderedRules.ObjectAt(index);
mDocument->StyleRuleAdded(this, rule);
}
}
}
nsresult
CSSStyleSheet::DeleteRuleFromGroup(css::GroupRule* aGroup, uint32_t aIndex)
{
+1
View File
@@ -253,6 +253,7 @@ protected:
uint32_t InsertRuleInternal(const nsAString& aRule,
uint32_t aIndex, ErrorResult& aRv);
void DeleteRuleInternal(uint32_t aIndex, ErrorResult& aRv);
void ReplaceSyncInternal(const nsAString& aText, ErrorResult& aRv);
RefPtr<nsMediaList> mMedia;
RefPtr<CSSStyleSheet> mNext;
+370 -14
View File
@@ -8,19 +8,227 @@
#include "CSSVariableDeclarations.h"
#include "CSSVariableResolver.h"
#include "CSSVariableValues.h"
#include "nsCSSScanner.h"
#include "nsRuleData.h"
// These four special string values are used to represent specified values of
// 'initial', 'inherit', 'unset', and 'revert'. (Note that none of these are
// valid variable values.)
// These special string values are used to represent specified values of
// CSS-wide keywords. (Note that none of these are valid variable values.)
#define INITIAL_VALUE "!"
#define INHERIT_VALUE ";"
#define UNSET_VALUE ")"
#define REVERT_VALUE ">"
#define REVERT_LAYER_VALUE "]"
static const int32_t kRevertLayerMask = 0x000fffff;
static const int32_t kRevertLayerImportant = 0x00100000;
static const int32_t kRevertLayerOriginShift = 21;
static const int32_t kLayerIndexMax = 0x000fffff;
static const int32_t kCascadeRankStride = kLayerIndexMax + 1;
namespace mozilla {
static bool
IsRevertLayerValue(const nsString& aValue)
{
return StringBeginsWith(aValue, NS_LITERAL_STRING(REVERT_LAYER_VALUE));
}
static bool
ValueMightResolveToRevertLayer(const nsString& aValue)
{
return IsRevertLayerValue(aValue) ||
aValue.Find(NS_LITERAL_STRING("revert-layer")) != kNotFound;
}
static int32_t
PackRevertLayerData(SheetType aLevel, bool aIsImportant,
int32_t aLayerIndex)
{
MOZ_ASSERT(aLayerIndex >= 0 && aLayerIndex <= kRevertLayerMask);
return (uint32_t(aLevel) << kRevertLayerOriginShift) |
(aIsImportant ? kRevertLayerImportant : 0) |
(aLayerIndex & kRevertLayerMask);
}
static void
SetRevertLayerData(nsString& aValue, const nsRuleData* aRuleData)
{
aValue.AssignLiteral(REVERT_LAYER_VALUE);
aValue.AppendInt(PackRevertLayerData(aRuleData->mLevel,
aRuleData->mIsImportantRule,
aRuleData->mLayerIndex));
}
static bool
UnpackRevertLayerData(const nsString& aValue, SheetType& aLevel,
bool& aIsImportant, int32_t& aLayerIndex)
{
if (!IsRevertLayerValue(aValue) ||
aValue.Length() == NS_LITERAL_STRING(REVERT_LAYER_VALUE).Length()) {
return false;
}
nsresult rv;
nsAutoString metadata;
metadata.Assign(Substring(aValue,
NS_LITERAL_STRING(REVERT_LAYER_VALUE).Length()));
int32_t packed = metadata.ToInteger(&rv);
if (NS_FAILED(rv)) {
return false;
}
aLevel = SheetType(uint32_t(packed) >> kRevertLayerOriginShift);
aIsImportant = (packed & kRevertLayerImportant) != 0;
aLayerIndex = packed & kRevertLayerMask;
return true;
}
static int32_t
LayerIndexRank(bool aIsImportant, int32_t aLayerIndex)
{
MOZ_ASSERT(aLayerIndex >= 0);
MOZ_ASSERT(aLayerIndex <= kLayerIndexMax);
return aIsImportant ? kLayerIndexMax - aLayerIndex : aLayerIndex;
}
static int32_t
CascadePrecedenceRank(SheetType aLevel, bool aIsImportant,
int32_t aLayerIndex)
{
int32_t bucket = 0;
bool isLayeredOrigin = false;
switch (aLevel) {
case SheetType::Agent:
bucket = aIsImportant ? 14 : 0;
isLayeredOrigin = true;
break;
case SheetType::User:
bucket = aIsImportant ? 13 : 1;
isLayeredOrigin = true;
break;
case SheetType::PresHint:
bucket = 2;
break;
case SheetType::SVGAttrAnimation:
bucket = 3;
break;
case SheetType::Doc:
bucket = aIsImportant ? 10 : 4;
isLayeredOrigin = true;
break;
case SheetType::ScopedDoc:
bucket = aIsImportant ? 9 : 5;
isLayeredOrigin = true;
break;
case SheetType::StyleAttr:
bucket = aIsImportant ? 11 : 6;
break;
case SheetType::Override:
bucket = aIsImportant ? 12 : 7;
break;
case SheetType::Animation:
bucket = 8;
break;
case SheetType::Transition:
bucket = 15;
break;
default:
MOZ_ASSERT_UNREACHABLE("unexpected cascade level");
break;
}
return bucket * kCascadeRankStride +
(isLayeredOrigin ? LayerIndexRank(aIsImportant, aLayerIndex) : 0);
}
static bool
ShouldIgnoreForRevertLayerData(SheetType aSourceLevel,
bool aSourceImportant,
int32_t aSourceLayerIndex,
SheetType aCandidateLevel,
bool aCandidateImportant,
int32_t aCandidateLayerIndex)
{
int32_t candidateRank =
CascadePrecedenceRank(aCandidateLevel, aCandidateImportant,
aCandidateLayerIndex);
int32_t sourceRank =
CascadePrecedenceRank(aSourceLevel, aSourceImportant, aSourceLayerIndex);
if (candidateRank >= sourceRank) {
return true;
}
if (!aSourceImportant) {
return false;
}
if (aSourceLevel == SheetType::StyleAttr) {
return aCandidateLevel == SheetType::StyleAttr ||
aCandidateLevel == SheetType::Animation;
}
int32_t normalBoundary =
CascadePrecedenceRank(aSourceLevel, false, aSourceLayerIndex);
return candidateRank >= normalBoundary;
}
static bool
ShouldIgnoreForRevertLayerValue(const nsString& aTargetValue,
SheetType aCandidateLevel,
bool aCandidateImportant,
int32_t aCandidateLayerIndex)
{
SheetType sourceLevel;
bool sourceImportant;
int32_t sourceLayerIndex;
if (!UnpackRevertLayerData(aTargetValue, sourceLevel, sourceImportant,
sourceLayerIndex)) {
return false;
}
return ShouldIgnoreForRevertLayerData(sourceLevel, sourceImportant,
sourceLayerIndex, aCandidateLevel,
aCandidateImportant,
aCandidateLayerIndex);
}
static bool
ShouldIgnoreForRevertLayerValue(const nsString& aTargetValue,
const nsRuleData* aRuleData)
{
return ShouldIgnoreForRevertLayerValue(aTargetValue, aRuleData->mLevel,
aRuleData->mIsImportantRule,
aRuleData->mLayerIndex);
}
static bool
ShouldIgnoreForRevertLayerSourceValue(const nsString& aTargetValue,
const nsString& aCandidateValue)
{
SheetType candidateLevel;
bool candidateImportant;
int32_t candidateLayerIndex;
if (!UnpackRevertLayerData(aCandidateValue, candidateLevel,
candidateImportant, candidateLayerIndex)) {
return false;
}
return ShouldIgnoreForRevertLayerValue(aTargetValue, candidateLevel,
candidateImportant,
candidateLayerIndex);
}
static bool
IsComputedRevertLayerValue(const nsString& aValue)
{
nsAutoString trimmed(aValue);
trimmed.CompressWhitespace(true, true);
return trimmed.EqualsLiteral("revert-layer");
}
CSSVariableDeclarations::CSSVariableDeclarations()
{
MOZ_COUNT_CTOR(CSSVariableDeclarations);
@@ -47,6 +255,8 @@ CSSVariableDeclarations::operator=(const CSSVariableDeclarations& aOther)
}
mVariables.Clear();
mRevertLayerSources.Clear();
mRevertLayerFallbacks.Clear();
CopyVariablesFrom(aOther);
return *this;
}
@@ -57,6 +267,15 @@ CSSVariableDeclarations::CopyVariablesFrom(const CSSVariableDeclarations& aOther
for (auto iter = aOther.mVariables.ConstIter(); !iter.Done(); iter.Next()) {
mVariables.Put(iter.Key(), iter.UserData());
}
for (auto iter = aOther.mRevertLayerSources.ConstIter();
!iter.Done(); iter.Next()) {
mRevertLayerSources.Put(iter.Key(), iter.UserData());
}
for (auto iter = aOther.mRevertLayerFallbacks.ConstIter();
!iter.Done(); iter.Next()) {
RevertLayerFallbackList* list = mRevertLayerFallbacks.LookupOrAdd(iter.Key());
list->mItems = iter.UserData()->mItems;
}
}
bool
@@ -87,6 +306,9 @@ CSSVariableDeclarations::Get(const nsAString& aName,
} else if (value.EqualsLiteral(REVERT_VALUE)) {
aType = eRevert;
aTokenStream.Truncate();
} else if (IsRevertLayerValue(value)) {
aType = eRevertLayer;
aTokenStream.Truncate();
} else {
aType = eTokenStream;
aTokenStream = value;
@@ -101,7 +323,8 @@ CSSVariableDeclarations::PutTokenStream(const nsAString& aName,
MOZ_ASSERT(!aTokenStream.EqualsLiteral(INITIAL_VALUE) &&
!aTokenStream.EqualsLiteral(INHERIT_VALUE) &&
!aTokenStream.EqualsLiteral(UNSET_VALUE) &&
!aTokenStream.EqualsLiteral(REVERT_VALUE));
!aTokenStream.EqualsLiteral(REVERT_VALUE) &&
!aTokenStream.EqualsLiteral(REVERT_LAYER_VALUE));
mVariables.Put(aName, aTokenStream);
}
@@ -129,6 +352,12 @@ CSSVariableDeclarations::PutRevert(const nsAString& aName)
mVariables.Put(aName, NS_LITERAL_STRING(REVERT_VALUE));
}
void
CSSVariableDeclarations::PutRevertLayer(const nsAString& aName)
{
mVariables.Put(aName, NS_LITERAL_STRING(REVERT_LAYER_VALUE));
}
void
CSSVariableDeclarations::Remove(const nsAString& aName)
{
@@ -143,16 +372,49 @@ CSSVariableDeclarations::MapRuleInfoInto(nsRuleData* aRuleData)
}
if (!aRuleData->mVariables) {
aRuleData->mVariables = new CSSVariableDeclarations(*this);
} else {
for (auto iter = mVariables.Iter(); !iter.Done(); iter.Next()) {
nsDataHashtable<nsStringHashKey, nsString>& variables =
aRuleData->mVariables->mVariables;
const nsAString& aName = iter.Key();
if (!variables.Contains(aName)) {
variables.Put(aName, iter.UserData());
aRuleData->mVariables = new CSSVariableDeclarations;
}
for (auto iter = mVariables.Iter(); !iter.Done(); iter.Next()) {
nsDataHashtable<nsStringHashKey, nsString>& variables =
aRuleData->mVariables->mVariables;
const nsAString& name = iter.Key();
nsString value = iter.UserData();
nsString valueSource;
SetRevertLayerData(valueSource, aRuleData);
if (value.EqualsLiteral(REVERT_LAYER_VALUE)) {
value = valueSource;
aRuleData->mConditions.SetUncacheable();
}
nsString existingValue;
if (variables.Get(name, &existingValue)) {
if (IsRevertLayerValue(existingValue)) {
if (ShouldIgnoreForRevertLayerValue(existingValue, aRuleData)) {
continue;
}
} else {
nsString sourceValue;
if (aRuleData->mVariables->mRevertLayerSources.Get(name,
&sourceValue) &&
!ShouldIgnoreForRevertLayerValue(sourceValue, aRuleData)) {
RevertLayerFallbackList* fallbacks =
aRuleData->mVariables->mRevertLayerFallbacks.LookupOrAdd(name);
RevertLayerFallback* fallback = fallbacks->mItems.AppendElement();
fallback->mValue = value;
fallback->mSource = valueSource;
}
continue;
}
}
variables.Put(name, value);
if (ValueMightResolveToRevertLayer(value)) {
aRuleData->mVariables->mRevertLayerSources.Put(name, valueSource);
} else {
aRuleData->mVariables->mRevertLayerSources.Remove(name);
aRuleData->mVariables->mRevertLayerFallbacks.Remove(name);
}
}
}
@@ -172,8 +434,9 @@ CSSVariableDeclarations::AddVariablesToResolver(
false);
} else if (value.EqualsLiteral(INHERIT_VALUE) ||
value.EqualsLiteral(UNSET_VALUE) ||
value.EqualsLiteral(REVERT_VALUE)) {
// Values of 'inherit', 'unset', and 'revert' don't need any handling,
value.EqualsLiteral(REVERT_VALUE) ||
IsRevertLayerValue(value)) {
// Values of 'inherit', 'unset', 'revert', and 'revert-layer' don't need any handling,
// since it means we just need to keep whatever value is currently in
// the resolver. This is because the specified variable declarations
// already have only the winning declaration for the variable and no
@@ -190,6 +453,83 @@ CSSVariableDeclarations::AddVariablesToResolver(
}
}
void
CSSVariableDeclarations::ResolveRevertLayerFallbacks(
const CSSVariableValues* aInherited,
CSSVariableValues* aOutput) const
{
for (auto iter = mRevertLayerSources.ConstIter();
!iter.Done(); iter.Next()) {
const nsAString& name = iter.Key();
nsString value;
nsCSSTokenSerializationType firstToken, lastToken;
if (!aOutput->Get(name, value, firstToken, lastToken)) {
continue;
}
if (!IsComputedRevertLayerValue(value)) {
continue;
}
const RevertLayerFallbackList* fallbacks = mRevertLayerFallbacks.Get(name);
if (fallbacks) {
nsString sourceValue = iter.UserData();
bool foundFallback = false;
for (uint32_t i = 0, n = fallbacks->mItems.Length(); i < n; i++) {
const RevertLayerFallback& fallback = fallbacks->mItems[i];
if (ShouldIgnoreForRevertLayerSourceValue(sourceValue,
fallback.mSource)) {
continue;
}
if (IsRevertLayerValue(fallback.mValue)) {
sourceValue = fallback.mSource;
continue;
}
CSSVariableValues inheritedValues(*aOutput);
if (aInherited->Get(name, value, firstToken, lastToken)) {
inheritedValues.Put(name, value, firstToken, lastToken);
} else {
inheritedValues.Remove(name);
}
CSSVariableDeclarations fallbackDeclarations;
fallbackDeclarations.mVariables.Put(name, fallback.mValue);
CSSVariableValues fallbackValues;
CSSVariableResolver resolver(&fallbackValues);
resolver.Resolve(&inheritedValues, &fallbackDeclarations);
if (!fallbackValues.Get(name, value, firstToken, lastToken)) {
aOutput->Remove(name);
foundFallback = true;
break;
}
if (IsComputedRevertLayerValue(value)) {
sourceValue = fallback.mSource;
continue;
}
aOutput->Put(name, value, firstToken, lastToken);
foundFallback = true;
break;
}
if (foundFallback) {
continue;
}
}
if (aInherited->Get(name, value, firstToken, lastToken)) {
aOutput->Put(name, value, firstToken, lastToken);
} else {
aOutput->Remove(name);
}
}
}
size_t
CSSVariableDeclarations::SizeOfIncludingThis(
mozilla::MallocSizeOf aMallocSizeOf) const
@@ -200,6 +540,22 @@ CSSVariableDeclarations::SizeOfIncludingThis(
n += iter.Key().SizeOfExcludingThisIfUnshared(aMallocSizeOf);
n += iter.Data().SizeOfExcludingThisIfUnshared(aMallocSizeOf);
}
n += mRevertLayerSources.ShallowSizeOfExcludingThis(aMallocSizeOf);
for (auto iter = mRevertLayerSources.ConstIter(); !iter.Done(); iter.Next()) {
n += iter.Key().SizeOfExcludingThisIfUnshared(aMallocSizeOf);
n += iter.Data().SizeOfExcludingThisIfUnshared(aMallocSizeOf);
}
n += mRevertLayerFallbacks.ShallowSizeOfExcludingThis(aMallocSizeOf);
for (auto iter = mRevertLayerFallbacks.ConstIter(); !iter.Done(); iter.Next()) {
n += iter.Key().SizeOfExcludingThisIfUnshared(aMallocSizeOf);
const RevertLayerFallbackList* list = iter.UserData();
n += aMallocSizeOf(list);
n += list->mItems.ShallowSizeOfExcludingThis(aMallocSizeOf);
for (uint32_t i = 0, len = list->mItems.Length(); i < len; i++) {
n += list->mItems[i].mValue.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
n += list->mItems[i].mSource.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
}
}
return n;
}
+35 -1
View File
@@ -7,10 +7,13 @@
#ifndef mozilla_CSSVariableDeclarations_h
#define mozilla_CSSVariableDeclarations_h
#include "nsClassHashtable.h"
#include "nsDataHashtable.h"
#include "nsTArray.h"
namespace mozilla {
class CSSVariableResolver;
class CSSVariableValues;
} // namespace mozilla
struct nsRuleData;
@@ -43,7 +46,8 @@ public:
eInitial, // 'initial'
eInherit, // 'inherit'
eUnset, // 'unset'
eRevert // 'revert'
eRevert, // 'revert'
eRevertLayer // 'revert-layer'
};
/**
@@ -97,6 +101,15 @@ public:
*/
void PutRevert(const nsAString& aName);
/**
* Adds or modifies an existing entry in this set of variable declarations
* to have the value 'revert-layer'.
*
* @param aName The variable name (not including any "--" prefix that would
* be part of the custom property name) whose value is to be set.
*/
void PutRevertLayer(const nsAString& aName);
/**
* Adds or modifies an existing entry in this set of variable declarations
* to have a token stream value.
@@ -132,15 +145,36 @@ public:
*/
void AddVariablesToResolver(CSSVariableResolver* aResolver) const;
/**
* Applies stored lower-priority declarations for custom property values that
* resolved to 'revert-layer'.
*/
void ResolveRevertLayerFallbacks(const CSSVariableValues* aInherited,
CSSVariableValues* aOutput) const;
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
private:
struct RevertLayerFallback
{
nsString mValue;
nsString mSource;
};
struct RevertLayerFallbackList
{
nsTArray<RevertLayerFallback> mItems;
};
/**
* Adds all the variable declarations from aOther into this object.
*/
void CopyVariablesFrom(const CSSVariableDeclarations& aOther);
nsDataHashtable<nsStringHashKey, nsString> mVariables;
nsDataHashtable<nsStringHashKey, nsString> mRevertLayerSources;
nsClassHashtable<nsStringHashKey, RevertLayerFallbackList>
mRevertLayerFallbacks;
};
} // namespace mozilla
+15
View File
@@ -121,6 +121,21 @@ CSSVariableValues::Put(const nsAString& aName,
}
}
void
CSSVariableValues::Remove(const nsAString& aName)
{
size_t id;
if (!mVariableIDs.Get(aName, &id)) {
return;
}
mVariables.RemoveElementAt(id);
mVariableIDs.Clear();
for (size_t i = 0, n = mVariables.Length(); i < n; i++) {
mVariableIDs.Put(mVariables[i].mVariableName, i);
}
}
void
CSSVariableValues::CopyVariablesFrom(const CSSVariableValues& aOther)
{
+5
View File
@@ -94,6 +94,11 @@ public:
nsCSSTokenSerializationType aFirstToken,
nsCSSTokenSerializationType aLastToken);
/**
* Removes an entry in this set of variable values.
*/
void Remove(const nsAString& aName);
/**
* Copies the variables from this object into aResolver, marking them as
* computed, inherited values.
+29 -2
View File
@@ -576,6 +576,7 @@ Declaration::GetPropertyValueInternal(
const nsCSSValue* tokenStream = nullptr;
uint32_t totalCount = 0, importantCount = 0,
initialCount = 0, inheritCount = 0, unsetCount = 0, revertCount = 0,
revertLayerCount = 0,
matchingTokenStreamCount = 0, nonMatchingTokenStreamCount = 0;
CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(p, aProperty,
CSSEnabledState::eForAllContent) {
@@ -603,6 +604,8 @@ Declaration::GetPropertyValueInternal(
++unsetCount;
} else if (val->GetUnit() == eCSSUnit_Revert) {
++revertCount;
} else if (val->GetUnit() == eCSSUnit_RevertLayer) {
++revertLayerCount;
} else if (val->GetUnit() == eCSSUnit_TokenStream) {
if (val->GetTokenStreamValue()->mShorthandPropertyID == aProperty) {
tokenStream = val;
@@ -640,9 +643,19 @@ Declaration::GetPropertyValueInternal(
nsCSSValue::eNormalized);
return;
}
if (revertLayerCount == totalCount) {
// Simplify serialization below by serializing revert-layer up-front.
nsCSSValue revertLayer;
revertLayer.SetRevertLayerValue();
revertLayer.AppendToString(eCSSProperty_UNKNOWN, aValue,
nsCSSValue::eNormalized);
return;
}
if (initialCount != 0 || inheritCount != 0 || unsetCount != 0 ||
revertCount != 0 || nonMatchingTokenStreamCount != 0) {
// Case (2): partially initial, inherit, unset, revert, or token stream.
revertCount != 0 || revertLayerCount != 0 ||
nonMatchingTokenStreamCount != 0) {
// Case (2): partially initial, inherit, unset, revert, revert-layer,
// or token stream.
return;
}
if (tokenStream) {
@@ -1535,6 +1548,7 @@ Declaration::GetPropertyValueInternal(
case eCSSUnit_Initial:
case eCSSUnit_Unset:
case eCSSUnit_Revert:
case eCSSUnit_RevertLayer:
return true;
case eCSSUnit_Enumerated:
// return false if there is a fallback value or <overflow-position>
@@ -1749,6 +1763,10 @@ Declaration::AppendVariableAndValueToString(const nsAString& aName,
aResult.AppendLiteral("revert");
break;
case CSSVariableDeclarations::eRevertLayer:
aResult.AppendLiteral("revert-layer");
break;
default:
MOZ_ASSERT(false, "unexpected variable value type");
}
@@ -1989,6 +2007,10 @@ Declaration::GetVariableValue(const nsAString& aName, nsAString& aValue) const
aValue.AppendLiteral("revert");
break;
case CSSVariableDeclarations::eRevertLayer:
aValue.AppendLiteral("revert-layer");
break;
default:
MOZ_ASSERT(false, "unexpected variable value type");
}
@@ -2059,6 +2081,11 @@ Declaration::AddVariable(const nsAString& aName,
variables->PutRevert(aName);
break;
case CSSVariableDeclarations::eRevertLayer:
MOZ_ASSERT(aValue.IsEmpty());
variables->PutRevertLayer(aName);
break;
default:
MOZ_ASSERT(false, "unexpected aType value");
}
+109
View File
@@ -32,6 +32,8 @@
#include "nsIFrame.h"
#include "gfx2DGlue.h"
#include <cmath>
using namespace mozilla;
using namespace mozilla::css;
using namespace mozilla::gfx;
@@ -39,6 +41,35 @@ using nsStyleTransformMatrix::Decompose2DMatrix;
using nsStyleTransformMatrix::Decompose3DMatrix;
using nsStyleTransformMatrix::ShearType;
static bool
GetAspectRatioAnimationValue(const nsCSSValuePair* aPair,
bool& aAuto,
float& aRatio)
{
aAuto = aPair->mXValue.GetUnit() == eCSSUnit_Auto;
if (aAuto) {
if (aPair->mYValue.GetUnit() != eCSSUnit_Pair) {
return false;
}
aPair = &aPair->mYValue.GetPairValue();
}
if (aPair->mXValue.GetUnit() != eCSSUnit_Number ||
aPair->mYValue.GetUnit() != eCSSUnit_Number) {
return false;
}
float width = aPair->mXValue.GetFloatValue();
float height = aPair->mYValue.GetFloatValue();
if (width <= 0.0f || height <= 0.0f ||
!std::isfinite(width) || !std::isfinite(height)) {
return false;
}
aRatio = width / height;
return std::isfinite(aRatio) && aRatio > 0.0f;
}
// HELPER METHODS
// --------------
/*
@@ -1243,6 +1274,21 @@ StyleAnimationValue::ComputeDistance(nsCSSPropertyID aProperty,
case eUnit_CSSValuePair: {
const nsCSSValuePair *pair1 = aStartValue.GetCSSValuePairValue();
const nsCSSValuePair *pair2 = aEndValue.GetCSSValuePairValue();
if (aProperty == eCSSProperty_aspect_ratio) {
bool auto1;
bool auto2;
float ratio1;
float ratio2;
if (!GetAspectRatioAnimationValue(pair1, auto1, ratio1) ||
!GetAspectRatioAnimationValue(pair2, auto2, ratio2) ||
auto1 != auto2) {
return false;
}
aDistance = Abs(std::log(double(ratio2)) -
std::log(double(ratio1)));
return true;
}
nsCSSUnit unit[2];
unit[0] = GetCommonUnit(aProperty, pair1->mXValue.GetUnit(),
pair2->mXValue.GetUnit());
@@ -2821,6 +2867,42 @@ StyleAnimationValue::AddWeighted(nsCSSPropertyID aProperty,
return true;
}
case eUnit_CSSValuePair: {
if (aProperty == eCSSProperty_aspect_ratio) {
bool auto1;
bool auto2;
float ratio1;
float ratio2;
if (!GetAspectRatioAnimationValue(aValue1.GetCSSValuePairValue(),
auto1, ratio1) ||
!GetAspectRatioAnimationValue(aValue2.GetCSSValuePairValue(),
auto2, ratio2) ||
auto1 != auto2 ||
std::abs((aCoeff1 + aCoeff2) - 1.0) > 0.000001) {
return false;
}
float resultRatio =
std::exp(aCoeff1 * std::log(double(ratio1)) +
aCoeff2 * std::log(double(ratio2)));
nsCSSValue width;
width.SetFloatValue(resultRatio, eCSSUnit_Number);
nsCSSValue height;
height.SetFloatValue(1.0f, eCSSUnit_Number);
nsCSSValue ratio;
ratio.SetPairValue(width, height);
auto result = MakeUnique<nsCSSValuePair>();
if (auto1) {
result->mXValue.SetAutoValue();
result->mYValue = ratio;
} else {
*result = ratio.GetPairValue();
}
aResultValue.SetAndAdoptCSSValuePairValue(result.release(),
eUnit_CSSValuePair);
return true;
}
uint32_t restrictions = nsCSSProps::ValueRestrictions(aProperty);
Maybe<nsCSSValuePair> result =
AddCSSValuePair(aProperty, restrictions,
@@ -4031,6 +4113,33 @@ StyleAnimationValue::ExtractComputedValue(nsCSSPropertyID aProperty,
break;
}
case eCSSProperty_aspect_ratio: {
const StyleAspectRatio& ratio =
static_cast<const nsStylePosition*>(styleStruct)->mAspectRatio;
if (!ratio.HasRatio()) {
aComputedValue.SetAutoValue();
break;
}
nsCSSValue width;
width.SetFloatValue(ratio.mWidth, eCSSUnit_Number);
nsCSSValue height;
height.SetFloatValue(ratio.mHeight, eCSSUnit_Number);
nsCSSValue ratioValue;
ratioValue.SetPairValue(width, height);
auto pair = MakeUnique<nsCSSValuePair>();
if (ratio.mAuto) {
pair->mXValue.SetAutoValue();
pair->mYValue = ratioValue;
} else {
*pair = ratioValue.GetPairValue();
}
aComputedValue.SetAndAdoptCSSValuePairValue(pair.release(),
eUnit_CSSValuePair);
break;
}
case eCSSProperty_border_spacing: {
const nsStyleTableBorder *styleTableBorder =
static_cast<const nsStyleTableBorder*>(styleStruct);
+1 -1
View File
@@ -489,7 +489,7 @@ public:
void SetNoneValue();
void SetIntValue(int32_t aInt, Unit aUnit);
template<typename T,
typename = typename std::enable_if<std::is_enum<T>::value>::type>
typename = typename std::enable_if_t<std::is_enum_v<T>>>
void SetIntValue(T aInt, Unit aUnit)
{
static_assert(mozilla::EnumTypeFitsWithin<T, int32_t>::value,
+16
View File
@@ -26,6 +26,8 @@ StyleSheet::StyleSheet(css::SheetParsingMode aParsingMode)
, mOwningNode(nullptr)
, mParsingMode(aParsingMode)
, mDisabled(false)
, mConstructed(false)
, mDisallowModification(false)
, mDocumentAssociationMode(NotOwnedByDocument)
{
}
@@ -38,6 +40,8 @@ StyleSheet::StyleSheet(const StyleSheet& aCopy,
, mOwningNode(aOwningNodeToUse)
, mParsingMode(aCopy.mParsingMode)
, mDisabled(aCopy.mDisabled)
, mConstructed(aCopy.mConstructed)
, mDisallowModification(false)
// We only use this constructor during cloning. It's the cloner's
// responsibility to notify us if we end up being owned by a document.
, mDocumentAssociationMode(NotOwnedByDocument)
@@ -254,6 +258,7 @@ StyleSheet::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
sheet->SetURIs(documentURI, nullptr, baseURI);
sheet->SetPrincipal(principal);
sheet->SetComplete();
sheet->SetConstructed();
return sheet.forget();
}
@@ -290,6 +295,17 @@ StyleSheet::DeleteRule(uint32_t aIndex,
AsConcrete()->DeleteRuleInternal(aIndex, aRv);
}
void
StyleSheet::ReplaceSync(const nsAString& aText, ErrorResult& aRv)
{
if (!IsConstructed() || IsModificationDisallowed()) {
aRv.Throw(NS_ERROR_DOM_NOT_ALLOWED_ERR);
return;
}
AsConcrete()->ReplaceSyncInternal(aText, aRv);
}
int32_t
StyleSheet::AddRule(const nsAString& aSelector, const nsAString& aBlock,
const Optional<uint32_t>& aIndex,
+7
View File
@@ -160,6 +160,7 @@ public:
void DeleteRule(uint32_t aIndex,
nsIPrincipal& aSubjectPrincipal,
ErrorResult& aRv);
void ReplaceSync(const nsAString& aText, ErrorResult& aRv);
int32_t AddRule(const nsAString& aSelector, const nsAString& aBlock,
const dom::Optional<uint32_t>& aIndex,
nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv);
@@ -205,6 +206,10 @@ private:
bool AreRulesAvailable(nsIPrincipal& aSubjectPrincipal,
ErrorResult& aRv);
bool IsConstructed() const { return mConstructed; }
void SetConstructed() { mConstructed = true; }
bool IsModificationDisallowed() const { return mDisallowModification; }
protected:
// Return success if the subject principal subsumes the principal of our
// inner, error otherwise. This will also succeed if the subject has
@@ -223,6 +228,8 @@ protected:
css::SheetParsingMode mParsingMode;
bool mDisabled;
bool mConstructed;
bool mDisallowModification;
// mDocumentAssociationMode determines whether mDocument directly owns us (in
// the sense that if it's known-live then we're known-live). Always
+123 -1
View File
@@ -48,6 +48,102 @@ ShouldIgnoreColors(nsRuleData *aRuleData)
!aRuleData->mPresContext->UseDocumentColors();
}
static const int32_t kLayerIndexMax = 0x000fffff;
static const int32_t kCascadeRankStride = kLayerIndexMax + 1;
static int32_t
LayerIndexRank(bool aIsImportant, int32_t aLayerIndex)
{
MOZ_ASSERT(aLayerIndex >= 0);
MOZ_ASSERT(aLayerIndex <= kLayerIndexMax);
return aIsImportant ? kLayerIndexMax - aLayerIndex : aLayerIndex;
}
static int32_t
CascadePrecedenceRank(SheetType aLevel, bool aIsImportant,
int32_t aLayerIndex)
{
int32_t bucket = 0;
bool isLayeredOrigin = false;
switch (aLevel) {
case SheetType::Agent:
bucket = aIsImportant ? 14 : 0;
isLayeredOrigin = true;
break;
case SheetType::User:
bucket = aIsImportant ? 13 : 1;
isLayeredOrigin = true;
break;
case SheetType::PresHint:
bucket = 2;
break;
case SheetType::SVGAttrAnimation:
bucket = 3;
break;
case SheetType::Doc:
bucket = aIsImportant ? 10 : 4;
isLayeredOrigin = true;
break;
case SheetType::ScopedDoc:
bucket = aIsImportant ? 9 : 5;
isLayeredOrigin = true;
break;
case SheetType::StyleAttr:
bucket = aIsImportant ? 11 : 6;
break;
case SheetType::Override:
bucket = aIsImportant ? 12 : 7;
break;
case SheetType::Animation:
bucket = 8;
break;
case SheetType::Transition:
bucket = 15;
break;
default:
MOZ_ASSERT_UNREACHABLE("unexpected cascade level");
break;
}
return bucket * kCascadeRankStride +
(isLayeredOrigin ? LayerIndexRank(aIsImportant, aLayerIndex) : 0);
}
static bool
ShouldIgnoreForRevertLayer(const nsCSSValue& aTargetValue,
const nsRuleData* aRuleData)
{
SheetType sourceLevel = aTargetValue.GetRevertLayerOriginValue();
bool sourceImportant = aTargetValue.GetRevertLayerImportanceValue();
int32_t sourceLayerIndex = aTargetValue.GetRevertLayerLayerIndexValue();
MOZ_ASSERT(sourceLevel != SheetType::Unknown,
"revert-layer should have cascade metadata before mapping");
int32_t candidateRank =
CascadePrecedenceRank(aRuleData->mLevel, aRuleData->mIsImportantRule,
aRuleData->mLayerIndex);
int32_t sourceRank =
CascadePrecedenceRank(sourceLevel, sourceImportant, sourceLayerIndex);
if (candidateRank >= sourceRank) {
return true;
}
if (!sourceImportant) {
return false;
}
if (sourceLevel == SheetType::StyleAttr) {
return aRuleData->mLevel == SheetType::StyleAttr ||
aRuleData->mLevel == SheetType::Animation;
}
int32_t normalBoundary =
CascadePrecedenceRank(sourceLevel, false, sourceLayerIndex);
return candidateRank >= normalBoundary;
}
/**
* Tries to call |nsCSSValue::StartImageLoad()| on an image source.
* Image sources are specified by |url()| or |-moz-image-rect()| function.
@@ -175,7 +271,8 @@ MapSinglePropertyInto(nsCSSPropertyID aTargetProp,
// CSSVariableImageTable, to give them the appropriate lifetime.
MOZ_ASSERT(aTargetValue->GetUnit() == eCSSUnit_TokenStream ||
aTargetValue->GetUnit() == eCSSUnit_Null ||
aTargetValue->GetUnit() == eCSSUnit_Revert,
aTargetValue->GetUnit() == eCSSUnit_Revert ||
aTargetValue->GetUnit() == eCSSUnit_RevertLayer,
"aTargetValue must only be a token stream (when re-parsing "
"properties with variable references) or null");
@@ -365,6 +462,10 @@ nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const
if (aRuleData->mLevel >= target->GetCascadeOriginValue()) {
continue;
}
} else if (target->GetUnit() == eCSSUnit_RevertLayer) {
if (ShouldIgnoreForRevertLayer(*target, aRuleData)) {
continue;
}
} else if (target->GetUnit() != eCSSUnit_Null) {
continue;
}
@@ -377,8 +478,18 @@ nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const
// the rule walking will have just updated aRuleData.
if (val->GetUnit() == eCSSUnit_TokenStream) {
val->GetTokenStreamValue()->mLevel = aRuleData->mLevel;
val->GetTokenStreamValue()->mIsImportant = aRuleData->mIsImportantRule;
val->GetTokenStreamValue()->mLayerIndex = aRuleData->mLayerIndex;
} else if (val->GetUnit() == eCSSUnit_Revert) {
aRuleData->mConditions.SetUncacheable();
} else if (val->GetUnit() == eCSSUnit_RevertLayer) {
nsCSSValue revertLayer;
revertLayer.SetRevertLayerValue(aRuleData->mLevel,
aRuleData->mIsImportantRule,
aRuleData->mLayerIndex);
aRuleData->mConditions.SetUncacheable();
MapSinglePropertyInto(iProp, &revertLayer, target, aRuleData);
continue;
}
MapSinglePropertyInto(iProp, val, target, aRuleData);
}
@@ -819,6 +930,17 @@ nsCSSExpandedDataBlock::MapRuleInfoInto(nsCSSPropertyID aPropID,
MOZ_ASSERT(dest->GetUnit() == eCSSUnit_TokenStream &&
dest->GetTokenStreamValue()->mPropertyID == aPropID);
if (src->GetUnit() == eCSSUnit_RevertLayer) {
nsCSSValueTokenStream* tokenStream = dest->GetTokenStreamValue();
nsCSSValue revertLayer;
revertLayer.SetRevertLayerValue(tokenStream->mLevel,
tokenStream->mIsImportant,
tokenStream->mLayerIndex);
aRuleData->mConditions.SetUncacheable();
MapSinglePropertyInto(physicalProp, &revertLayer, dest, aRuleData);
return;
}
CSSVariableImageTable::ReplaceAll(aRuleData->mStyleContext, aPropID, [=] {
MapSinglePropertyInto(physicalProp, src, dest, aRuleData);
});
+1 -1
View File
@@ -481,6 +481,7 @@ CSS_KEY(repeat-x, repeat_x)
CSS_KEY(repeat-y, repeat_y)
CSS_KEY(reverse, reverse)
CSS_KEY(revert, revert)
CSS_KEY(revert-layer, revert_layer)
CSS_KEY(ridge, ridge)
CSS_KEY(right, right)
CSS_KEY(rl, rl)
@@ -814,4 +815,3 @@ CSS_KEY(text-before-edge, text_before_edge)
CSS_KEY(use-script, use_script)
CSS_KEY(-moz-crisp-edges, _moz_crisp_edges)
CSS_KEY(space, space)
+68 -28
View File
@@ -9126,6 +9126,10 @@ CSSParserImpl::ParseVariant(nsCSSValue& aValue,
aValue.SetRevertValue(mLevel);
return CSSParseResult::Ok;
}
else if (eCSSKeyword_revert_layer == keyword) {
aValue.SetRevertLayerValue();
return CSSParseResult::Ok;
}
}
if ((aVariantMask & VARIANT_NONE) != 0) {
if (eCSSKeyword_none == keyword) {
@@ -9330,7 +9334,8 @@ CSSParserImpl::ParseVariant(nsCSSValue& aValue,
tk->mIdent.LowerCaseEqualsLiteral("initial") ||
(tk->mIdent.LowerCaseEqualsLiteral("unset") &&
nsLayoutUtils::UnsetValueEnabled()) ||
tk->mIdent.LowerCaseEqualsLiteral("revert")))) {
tk->mIdent.LowerCaseEqualsLiteral("revert") ||
tk->mIdent.LowerCaseEqualsLiteral("revert-layer")))) {
aValue.SetStringValue(tk->mIdent, eCSSUnit_Ident);
return CSSParseResult::Ok;
}
@@ -9406,6 +9411,7 @@ CSSParserImpl::ParseCustomIdent(nsCSSValue& aValue,
keyword == eCSSKeyword_initial ||
keyword == eCSSKeyword_unset ||
keyword == eCSSKeyword_revert ||
keyword == eCSSKeyword_revert_layer ||
keyword == eCSSKeyword_default ||
(aPropertyKTable &&
nsCSSProps::FindIndexOfKeyword(keyword, aPropertyKTable) >= 0)) {
@@ -12595,6 +12601,12 @@ CSSParserImpl::ParseChoice(nsCSSValue aValues[],
}
found = ((1 << aNumIDs) - 1);
}
else if (eCSSUnit_RevertLayer == aValues[0].GetUnit()) { // one revert-layer, all revert-layer
for (loop = 1; loop < aNumIDs; loop++) {
aValues[loop].SetRevertLayerValue();
}
found = ((1 << aNumIDs) - 1);
}
}
else { // more than one value, verify no inherits, initials, unsets, or reverts
for (loop = 0; loop < aNumIDs; loop++) {
@@ -12610,7 +12622,8 @@ CSSParserImpl::ParseChoice(nsCSSValue aValues[],
found = -1;
break;
}
else if (eCSSUnit_Revert == aValues[loop].GetUnit()) {
else if (eCSSUnit_Revert == aValues[loop].GetUnit() ||
eCSSUnit_RevertLayer == aValues[loop].GetUnit()) {
found = -1;
break;
}
@@ -12658,7 +12671,8 @@ CSSParserImpl::ParseBoxProperties(const nsCSSPropertyID aPropIDs[])
if (eCSSUnit_Inherit == unit ||
eCSSUnit_Initial == unit ||
eCSSUnit_Unset == unit ||
eCSSUnit_Revert == unit) {
eCSSUnit_Revert == unit ||
eCSSUnit_RevertLayer == unit) {
return false;
}
}
@@ -12766,7 +12780,8 @@ CSSParserImpl::ParseBoxCornerRadius(nsCSSPropertyID aPropID)
if (dimenX.GetUnit() != eCSSUnit_Inherit &&
dimenX.GetUnit() != eCSSUnit_Initial &&
dimenX.GetUnit() != eCSSUnit_Unset &&
dimenX.GetUnit() != eCSSUnit_Revert) {
dimenX.GetUnit() != eCSSUnit_Revert &&
dimenX.GetUnit() != eCSSUnit_RevertLayer) {
if (ParseNonNegativeVariant(dimenY, VARIANT_LP | VARIANT_CALC, nullptr) ==
CSSParseResult::Error) {
return false;
@@ -12831,7 +12846,8 @@ CSSParserImpl::ParseBoxCornerRadiiInternals(nsCSSValue array[])
if (eCSSUnit_Inherit == unit ||
eCSSUnit_Initial == unit ||
eCSSUnit_Unset == unit ||
eCSSUnit_Revert == unit)
eCSSUnit_Revert == unit ||
eCSSUnit_RevertLayer == unit)
return false;
}
@@ -13403,23 +13419,26 @@ bool
CSSParserImpl::ParseAspectRatioRatio(nsCSSValue& aValue)
{
nsCSSValue width;
if (!ParseNonNegativeNumber(width)) {
if (!ParseSingleTokenNonNegativeVariant(width,
VARIANT_NUMBER | VARIANT_CALC,
nullptr)) {
return false;
}
float w = width.GetFloatValue();
float h = 1.0f;
nsCSSValue height;
height.SetFloatValue(1.0f, eCSSUnit_Number);
if (ExpectSymbol('/', true)) {
nsCSSValue height;
if (!ParseNonNegativeNumber(height)) {
if (!ParseSingleTokenNonNegativeVariant(height,
VARIANT_NUMBER | VARIANT_CALC,
nullptr)) {
return false;
}
h = height.GetFloatValue();
}
// Degenerate ratios behave as auto in layout.
aValue.SetFloatValue(w == 0.0f || h == 0.0f ? 0.0f : w / h,
eCSSUnit_Number);
// Keep both components: the computed value is a pair of numbers, and
// degenerate ratios still serialize as ratios even though they behave as
// auto during layout.
aValue.SetPairValue(width, height);
return true;
}
@@ -13442,9 +13461,15 @@ CSSParserImpl::ParseAspectRatio(nsCSSValue& aValue)
if (hasRatio) {
if (!hasAuto) {
// The grammar is "auto || <ratio>", so auto may appear after the ratio.
ParseSingleTokenVariant(autoValue, VARIANT_AUTO, nullptr);
hasAuto = ParseSingleTokenVariant(autoValue, VARIANT_AUTO, nullptr);
}
if (hasAuto) {
nsCSSValue combined;
combined.SetPairValue(autoValue, ratioValue);
aValue = combined;
} else {
aValue = ratioValue;
}
aValue = ratioValue;
return true;
}
@@ -13642,6 +13667,7 @@ CSSParserImpl::ParseFontDescriptorValue(nsCSSFontDesc aDescID,
aValue.GetUnit() != eCSSUnit_Initial &&
aValue.GetUnit() != eCSSUnit_Unset &&
aValue.GetUnit() != eCSSUnit_Revert &&
aValue.GetUnit() != eCSSUnit_RevertLayer &&
(aValue.GetUnit() != eCSSUnit_Enumerated ||
(aValue.GetIntValue() != NS_STYLE_FONT_WEIGHT_BOLDER &&
aValue.GetIntValue() != NS_STYLE_FONT_WEIGHT_LIGHTER)));
@@ -13905,7 +13931,8 @@ CSSParserImpl::ParseImageLayersItem(
if (keyword == eCSSKeyword_inherit ||
keyword == eCSSKeyword_initial ||
keyword == eCSSKeyword_unset ||
keyword == eCSSKeyword_revert) {
keyword == eCSSKeyword_revert ||
keyword == eCSSKeyword_revert_layer) {
return false;
} else if (keyword == eCSSKeyword_none) {
if (haveImage)
@@ -14262,7 +14289,8 @@ bool CSSParserImpl::ParseBoxPositionValues(nsCSSValuePair &aOut,
if (eCSSUnit_Inherit == xValue.GetUnit() ||
eCSSUnit_Initial == xValue.GetUnit() ||
eCSSUnit_Unset == xValue.GetUnit() ||
eCSSUnit_Revert == xValue.GetUnit()) { // both are inherit, initial, unset, or revert
eCSSUnit_Revert == xValue.GetUnit() ||
eCSSUnit_RevertLayer == xValue.GetUnit()) {
yValue = xValue;
return true;
}
@@ -15094,6 +15122,7 @@ CSSParserImpl::ParseBorderSide(const nsCSSPropertyID aPropIDs[],
case eCSSUnit_Initial:
case eCSSUnit_Unset:
case eCSSUnit_Revert:
case eCSSUnit_RevertLayer:
extraValue = values[0];
// Set value of border-image properties to initial/inherit/unset/revert
AppendValue(eCSSProperty_border_image_source, extraValue);
@@ -15860,7 +15889,8 @@ CSSParserImpl::ParseFont()
if (eCSSUnit_Inherit == family.GetUnit() ||
eCSSUnit_Initial == family.GetUnit() ||
eCSSUnit_Unset == family.GetUnit() ||
eCSSUnit_Revert == family.GetUnit()) {
eCSSUnit_Revert == family.GetUnit() ||
eCSSUnit_RevertLayer == family.GetUnit()) {
AppendValue(eCSSProperty__x_system_font, nsCSSValue(eCSSUnit_None));
AppendValue(eCSSProperty_font_family, family);
AppendValue(eCSSProperty_font_style, family);
@@ -15929,7 +15959,8 @@ CSSParserImpl::ParseFont()
eCSSUnit_Inherit == values[kFontStyleIndex].GetUnit() ||
eCSSUnit_Initial == values[kFontStyleIndex].GetUnit() ||
eCSSUnit_Unset == values[kFontStyleIndex].GetUnit() ||
eCSSUnit_Revert == values[kFontStyleIndex].GetUnit() ) { // illegal data
eCSSUnit_Revert == values[kFontStyleIndex].GetUnit() ||
eCSSUnit_RevertLayer == values[kFontStyleIndex].GetUnit() ) { // illegal data
return false;
}
if ((found & (1 << kFontStyleIndex)) == 0) {
@@ -15988,7 +16019,8 @@ CSSParserImpl::ParseFont()
if (eCSSUnit_Inherit != family.GetUnit() &&
eCSSUnit_Initial != family.GetUnit() &&
eCSSUnit_Unset != family.GetUnit() &&
eCSSUnit_Revert != family.GetUnit()) {
eCSSUnit_Revert != family.GetUnit() &&
eCSSUnit_RevertLayer != family.GetUnit()) {
AppendValue(eCSSProperty__x_system_font, nsCSSValue(eCSSUnit_None));
AppendValue(eCSSProperty_font_family, family);
AppendValue(eCSSProperty_font_style, values[kFontStyleIndex]);
@@ -16034,7 +16066,8 @@ CSSParserImpl::ParseFontSynthesis(nsCSSValue& aValue)
eCSSUnit_Initial == aValue.GetUnit() ||
eCSSUnit_Inherit == aValue.GetUnit() ||
eCSSUnit_Unset == aValue.GetUnit() ||
eCSSUnit_Revert == aValue.GetUnit() )
eCSSUnit_Revert == aValue.GetUnit() ||
eCSSUnit_RevertLayer == aValue.GetUnit() )
{
return true;
}
@@ -16657,6 +16690,9 @@ CSSParserImpl::ParseFamily(nsCSSValue& aValue)
case eCSSKeyword_revert:
aValue.SetRevertValue(mLevel);
return true;
case eCSSKeyword_revert_layer:
aValue.SetRevertLayerValue();
return true;
case eCSSKeyword__moz_use_system_font:
if (!IsParsingCompoundProperty()) {
aValue.SetSystemFontValue();
@@ -16691,6 +16727,7 @@ CSSParserImpl::ParseFamily(nsCSSValue& aValue)
case eCSSKeyword_initial:
case eCSSKeyword_default:
case eCSSKeyword_revert:
case eCSSKeyword_revert_layer:
case eCSSKeyword__moz_use_system_font:
return false;
case eCSSKeyword_unset:
@@ -18340,7 +18377,8 @@ bool CSSParserImpl::ParseTransformOrigin(bool aPerspective)
if (position.mXValue.GetUnit() == eCSSUnit_Inherit ||
position.mXValue.GetUnit() == eCSSUnit_Initial ||
position.mXValue.GetUnit() == eCSSUnit_Unset ||
position.mXValue.GetUnit() == eCSSUnit_Revert) {
position.mXValue.GetUnit() == eCSSUnit_Revert ||
position.mXValue.GetUnit() == eCSSUnit_RevertLayer) {
MOZ_ASSERT(position.mXValue == position.mYValue,
"inherit/initial/unset/revert only half?");
AppendValue(prop, position.mXValue);
@@ -18564,14 +18602,15 @@ CSSParserImpl::ParseTransitionProperty()
}
if (cur->mValue.GetUnit() == eCSSUnit_Ident) {
nsDependentString str(cur->mValue.GetStringBufferValue());
// Exclude 'none', 'inherit', 'initial', 'unset', and 'revert'
// according to the same rules as for 'counter-reset' in CSS 2.1.
// Exclude CSS-wide keywords and 'none' according to the same rules
// as for 'counter-reset' in CSS 2.1.
if (str.LowerCaseEqualsLiteral("none") ||
str.LowerCaseEqualsLiteral("inherit") ||
str.LowerCaseEqualsLiteral("initial") ||
(str.LowerCaseEqualsLiteral("unset") &&
nsLayoutUtils::UnsetValueEnabled()) ||
str.LowerCaseEqualsLiteral("revert")) {
str.LowerCaseEqualsLiteral("revert") ||
str.LowerCaseEqualsLiteral("revert-layer")) {
return false;
}
}
@@ -19484,8 +19523,7 @@ CSSParserImpl::ParseValueWithVariables(CSSVariableDeclarations::Type* aType,
}
}
// Look for 'initial', 'inherit', 'unset', or 'revert' as the first
// non-white space token.
// Look for CSS-wide keywords as the first non-white space token.
CSSVariableDeclarations::Type type = CSSVariableDeclarations::eTokenStream;
if (mToken.mType == eCSSToken_Ident) {
if (mToken.mIdent.LowerCaseEqualsLiteral("initial")) {
@@ -19496,6 +19534,8 @@ CSSParserImpl::ParseValueWithVariables(CSSVariableDeclarations::Type* aType,
type = CSSVariableDeclarations::eUnset;
} else if (mToken.mIdent.LowerCaseEqualsLiteral("revert")) {
type = CSSVariableDeclarations::eRevert;
} else if (mToken.mIdent.LowerCaseEqualsLiteral("revert-layer")) {
type = CSSVariableDeclarations::eRevertLayer;
}
}
+2 -2
View File
@@ -479,8 +479,8 @@ CSS_PROP_POSITION(
"",
0,
nullptr,
offsetof(nsStylePosition, mAspectRatio),
eStyleAnimType_None)
CSS_PROP_NO_OFFSET,
eStyleAnimType_Custom)
CSS_PROP_DISPLAY(
backface-visibility,
backface_visibility,
+4 -4
View File
@@ -44,7 +44,7 @@
// 'inherit' and 'initial'
#define VARIANT_OPACITY 0x008000 // Take floats and percents as input, output float.
#define VARIANT_AUTO 0x010000 // A
#define VARIANT_INHERIT 0x020000 // H eCSSUnit_Initial, eCSSUnit_Inherit, eCSSUnit_Unset, eCSSUnit_Revert
#define VARIANT_INHERIT 0x020000 // H eCSSUnit_Initial, eCSSUnit_Inherit, eCSSUnit_Unset, eCSSUnit_Revert, eCSSUnit_RevertLayer
#define VARIANT_NONE 0x040000 // O
#define VARIANT_NORMAL 0x080000 // M
#define VARIANT_SYSFONT 0x100000 // eCSSUnit_System_Font
@@ -364,7 +364,7 @@ public:
}
template<typename T,
typename = typename std::enable_if<std::is_enum<T>::value>::type>
typename = typename std::enable_if_t<std::is_enum_v<T>>>
KTableEntry(nsCSSKeyword aKeyword, T aValue)
: mKeyword(aKeyword)
, mValue(static_cast<int16_t>(aValue))
@@ -451,7 +451,7 @@ public:
static nsCSSKeyword ValueToKeywordEnum(int32_t aValue,
const KTableEntry aTable[]);
template<typename T,
typename = typename std::enable_if<std::is_enum<T>::value>::type>
typename = typename std::enable_if_t<std::is_enum_v<T>>>
static nsCSSKeyword ValueToKeywordEnum(T aValue,
const KTableEntry aTable[])
{
@@ -463,7 +463,7 @@ public:
static const nsAFlatCString& ValueToKeyword(int32_t aValue,
const KTableEntry aTable[]);
template<typename T,
typename = typename std::enable_if<std::is_enum<T>::value>::type>
typename = typename std::enable_if_t<std::is_enum_v<T>>>
static const nsAFlatCString& ValueToKeyword(T aValue,
const KTableEntry aTable[])
{
+86 -5
View File
@@ -192,6 +192,9 @@ nsCSSValue::nsCSSValue(const nsCSSValue& aCopy)
else if (eCSSUnit_Revert == mUnit) {
mValue.mCascadeOrigin = aCopy.mValue.mCascadeOrigin;
}
else if (eCSSUnit_RevertLayer == mUnit) {
mValue.mInt = aCopy.mValue.mInt;
}
else if (UnitHasArrayValue()) {
mValue.mArray = aCopy.mValue.mArray;
mValue.mArray->AddRef();
@@ -316,6 +319,9 @@ bool nsCSSValue::operator==(const nsCSSValue& aOther) const
else if (eCSSUnit_Revert == mUnit) {
return mValue.mCascadeOrigin == aOther.mValue.mCascadeOrigin;
}
else if (eCSSUnit_RevertLayer == mUnit) {
return mValue.mInt == aOther.mValue.mInt;
}
else if (UnitHasArrayValue()) {
return *mValue.mArray == *aOther.mValue.mArray;
}
@@ -593,6 +599,31 @@ nsCSSValue::SetCascadeOriginValue(mozilla::SheetType aValue, nsCSSUnit aUnit)
mValue.mCascadeOrigin = aValue;
}
static const int32_t kRevertLayerMask = 0x000fffff;
static const int32_t kRevertLayerImportant = 0x00100000;
static const int32_t kRevertLayerOriginShift = 21;
mozilla::SheetType
nsCSSValue::GetRevertLayerOriginValue() const
{
MOZ_ASSERT(mUnit == eCSSUnit_RevertLayer, "not a revert-layer value");
return mozilla::SheetType(uint32_t(mValue.mInt) >> kRevertLayerOriginShift);
}
bool
nsCSSValue::GetRevertLayerImportanceValue() const
{
MOZ_ASSERT(mUnit == eCSSUnit_RevertLayer, "not a revert-layer value");
return (mValue.mInt & kRevertLayerImportant) != 0;
}
int32_t
nsCSSValue::GetRevertLayerLayerIndexValue() const
{
MOZ_ASSERT(mUnit == eCSSUnit_RevertLayer, "not a revert-layer value");
return mValue.mInt & kRevertLayerMask;
}
void nsCSSValue::SetArrayValue(nsCSSValue::Array* aValue, nsCSSUnit aUnit)
{
Reset();
@@ -663,7 +694,9 @@ void nsCSSValue::SetPairValue(const nsCSSValuePair* aValue)
aValue->mXValue.GetUnit() != eCSSUnit_Unset &&
aValue->mYValue.GetUnit() != eCSSUnit_Unset &&
aValue->mXValue.GetUnit() != eCSSUnit_Revert &&
aValue->mYValue.GetUnit() != eCSSUnit_Revert,
aValue->mYValue.GetUnit() != eCSSUnit_Revert &&
aValue->mXValue.GetUnit() != eCSSUnit_RevertLayer &&
aValue->mYValue.GetUnit() != eCSSUnit_RevertLayer,
"missing or inappropriate pair value");
Reset();
mUnit = eCSSUnit_Pair;
@@ -683,7 +716,9 @@ void nsCSSValue::SetPairValue(const nsCSSValue& xValue,
xValue.GetUnit() != eCSSUnit_Unset &&
yValue.GetUnit() != eCSSUnit_Unset &&
xValue.GetUnit() != eCSSUnit_Revert &&
yValue.GetUnit() != eCSSUnit_Revert,
yValue.GetUnit() != eCSSUnit_Revert &&
xValue.GetUnit() != eCSSUnit_RevertLayer &&
yValue.GetUnit() != eCSSUnit_RevertLayer,
"inappropriate pair value");
Reset();
mUnit = eCSSUnit_Pair;
@@ -709,7 +744,10 @@ void nsCSSValue::SetTripletValue(const nsCSSValueTriplet* aValue)
aValue->mZValue.GetUnit() != eCSSUnit_Unset &&
aValue->mXValue.GetUnit() != eCSSUnit_Revert &&
aValue->mYValue.GetUnit() != eCSSUnit_Revert &&
aValue->mZValue.GetUnit() != eCSSUnit_Revert,
aValue->mZValue.GetUnit() != eCSSUnit_Revert &&
aValue->mXValue.GetUnit() != eCSSUnit_RevertLayer &&
aValue->mYValue.GetUnit() != eCSSUnit_RevertLayer &&
aValue->mZValue.GetUnit() != eCSSUnit_RevertLayer,
"missing or inappropriate triplet value");
Reset();
mUnit = eCSSUnit_Triplet;
@@ -735,7 +773,10 @@ void nsCSSValue::SetTripletValue(const nsCSSValue& xValue,
zValue.GetUnit() != eCSSUnit_Unset &&
xValue.GetUnit() != eCSSUnit_Revert &&
yValue.GetUnit() != eCSSUnit_Revert &&
zValue.GetUnit() != eCSSUnit_Revert,
zValue.GetUnit() != eCSSUnit_Revert &&
xValue.GetUnit() != eCSSUnit_RevertLayer &&
yValue.GetUnit() != eCSSUnit_RevertLayer &&
zValue.GetUnit() != eCSSUnit_RevertLayer,
"inappropriate triplet value");
Reset();
mUnit = eCSSUnit_Triplet;
@@ -851,6 +892,26 @@ nsCSSValue::SetRevertValue(mozilla::SheetType aValue)
SetCascadeOriginValue(aValue, eCSSUnit_Revert);
}
void
nsCSSValue::SetRevertLayerValue()
{
SetRevertLayerValue(mozilla::SheetType::Unknown, false, 0);
}
void
nsCSSValue::SetRevertLayerValue(mozilla::SheetType aLevel,
bool aIsImportant,
int32_t aLayerIndex)
{
MOZ_ASSERT(aLayerIndex >= 0 && aLayerIndex <= kRevertLayerMask,
"cascade layer index is out of range");
Reset();
mUnit = eCSSUnit_RevertLayer;
mValue.mInt = (uint32_t(aLevel) << kRevertLayerOriginShift) |
(aIsImportant ? kRevertLayerImportant : 0) |
(aLayerIndex & kRevertLayerMask);
}
void nsCSSValue::SetNoneValue()
{
Reset();
@@ -2234,6 +2295,7 @@ nsCSSValue::AppendToString(nsCSSPropertyID aProperty, nsAString& aResult,
case eCSSUnit_Initial: aResult.AppendLiteral("initial"); break;
case eCSSUnit_Unset: aResult.AppendLiteral("unset"); break;
case eCSSUnit_Revert: aResult.AppendLiteral("revert"); break;
case eCSSUnit_RevertLayer: aResult.AppendLiteral("revert-layer"); break;
case eCSSUnit_None: aResult.AppendLiteral("none"); break;
case eCSSUnit_Normal: aResult.AppendLiteral("normal"); break;
case eCSSUnit_System_Font: aResult.AppendLiteral("-moz-use-system-font"); break;
@@ -2511,6 +2573,7 @@ nsCSSValue::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
// Cascade Origin: nothing extra to measure.
case eCSSUnit_Revert:
case eCSSUnit_RevertLayer:
break;
// Float: nothing extra to measure.
@@ -2836,7 +2899,8 @@ nsCSSRect::AppendToString(nsCSSPropertyID aProperty, nsAString& aResult,
mTop.GetUnit() != eCSSUnit_Inherit &&
mTop.GetUnit() != eCSSUnit_Initial &&
mTop.GetUnit() != eCSSUnit_Unset &&
mTop.GetUnit() != eCSSUnit_Revert,
mTop.GetUnit() != eCSSUnit_Revert &&
mTop.GetUnit() != eCSSUnit_RevertLayer,
"parser should have used a bare value");
if (eCSSProperty_border_image_slice == aProperty ||
@@ -2908,6 +2972,20 @@ nsCSSValuePair::AppendToString(nsCSSPropertyID aProperty,
nsAString& aResult,
nsCSSValue::Serialization aSerialization) const
{
if (aProperty == eCSSProperty_aspect_ratio) {
if (mXValue.GetUnit() == eCSSUnit_Auto) {
mXValue.AppendToString(aProperty, aResult, aSerialization);
aResult.Append(char16_t(' '));
mYValue.AppendToString(aProperty, aResult, aSerialization);
return;
}
mXValue.AppendToString(aProperty, aResult, aSerialization);
aResult.AppendLiteral(" / ");
mYValue.AppendToString(aProperty, aResult, aSerialization);
return;
}
mXValue.AppendToString(aProperty, aResult, aSerialization);
if (mYValue.GetUnit() != eCSSUnit_Null) {
aResult.Append(char16_t(' '));
@@ -3007,6 +3085,7 @@ nsCSSValuePairList::AppendToString(nsCSSPropertyID aProperty,
item->mXValue.GetUnit() != eCSSUnit_Initial &&
item->mXValue.GetUnit() != eCSSUnit_Unset &&
item->mXValue.GetUnit() != eCSSUnit_Revert &&
item->mXValue.GetUnit() != eCSSUnit_RevertLayer &&
item->mYValue.GetUnit() != eCSSUnit_Null) {
aResult.Append(char16_t(' '));
item->mYValue.AppendToString(aProperty, aResult, aSerialization);
@@ -3443,6 +3522,8 @@ nsCSSValueTokenStream::nsCSSValueTokenStream()
: mPropertyID(eCSSProperty_UNKNOWN)
, mShorthandPropertyID(eCSSProperty_UNKNOWN)
, mLevel(SheetType::Count)
, mIsImportant(false)
, mLayerIndex(0)
{
MOZ_COUNT_CTOR(nsCSSValueTokenStream);
}
+13 -1
View File
@@ -490,6 +490,7 @@ enum nsCSSUnit {
eCSSUnit_GridTemplateAreas = 44, // (GridTemplateAreasValue*)
// for grid-template-areas
eCSSUnit_Revert = 45, // (SheetType) value is the current cascade origin
eCSSUnit_RevertLayer = 46, // (int32_t) packed cascade layer rollback data
eCSSUnit_Pair = 50, // (nsCSSValuePair*) pair of values
eCSSUnit_Triplet = 51, // (nsCSSValueTriplet*) triplet of values
@@ -939,6 +940,9 @@ public:
MOZ_ASSERT(mUnit == eCSSUnit_Revert, "not a cascade origin value");
return mValue.mCascadeOrigin;
}
mozilla::SheetType GetRevertLayerOriginValue() const;
bool GetRevertLayerImportanceValue() const;
int32_t GetRevertLayerLayerIndexValue() const;
void Reset() // sets to null
{
@@ -951,7 +955,7 @@ private:
public:
void SetIntValue(int32_t aValue, nsCSSUnit aUnit);
template<typename T,
typename = typename std::enable_if<std::is_enum<T>::value>::type>
typename = typename std::enable_if_t<std::is_enum_v<T>>>
void SetIntValue(T aValue, nsCSSUnit aUnit)
{
static_assert(mozilla::EnumTypeFitsWithin<T, int32_t>::value,
@@ -994,6 +998,10 @@ public:
void SetInitialValue();
void SetUnsetValue();
void SetRevertValue(mozilla::SheetType aValue);
void SetRevertLayerValue();
void SetRevertLayerValue(mozilla::SheetType aLevel,
bool aIsImportant,
int32_t aLayerIndex);
void SetNoneValue();
void SetAllValue();
void SetNormalValue();
@@ -1837,6 +1845,8 @@ public:
mShorthandPropertyID == aOther.mShorthandPropertyID &&
mTokenStream.Equals(aOther.mTokenStream) &&
mLevel == aOther.mLevel &&
mIsImportant == aOther.mIsImportant &&
mLayerIndex == aOther.mLayerIndex &&
(mBaseURI == aOther.mBaseURI ||
(mBaseURI && aOther.mBaseURI &&
NS_SUCCEEDED(mBaseURI->Equals(aOther.mBaseURI, &eq)) &&
@@ -1886,6 +1896,8 @@ public:
uint32_t mLineNumber;
uint32_t mLineOffset;
mozilla::SheetType mLevel;
bool mIsImportant;
int32_t mLayerIndex;
private:
nsCSSValueTokenStream(const nsCSSValueTokenStream& aOther) = delete;
+8 -4
View File
@@ -968,13 +968,17 @@ already_AddRefed<CSSValue>
nsComputedDOMStyle::DoGetAspectRatio()
{
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
float ratio = StylePosition()->mAspectRatio;
if (ratio == 0.0f) {
const StyleAspectRatio& ratio = StylePosition()->mAspectRatio;
if (!ratio.HasRatio()) {
val->SetIdent(eCSSKeyword_auto);
} else {
nsAutoString ratioString;
nsStyleUtil::AppendCSSNumber(ratio, ratioString);
ratioString.AppendLiteral(" / 1");
if (ratio.mAuto) {
ratioString.AppendLiteral("auto ");
}
nsStyleUtil::AppendCSSNumber(ratio.mWidth, ratioString);
ratioString.AppendLiteral(" / ");
nsStyleUtil::AppendCSSNumber(ratio.mHeight, ratioString);
val->SetString(ratioString);
}
return val.forget();
+3
View File
@@ -28,6 +28,9 @@ nsRuleData::GetPoisonOffset()
nsRuleData::nsRuleData(uint32_t aSIDs, nsCSSValue* aValueStorage,
nsPresContext* aContext, nsStyleContext* aStyleContext)
: mSIDs(aSIDs),
mIsImportantRule(false),
mLevel(mozilla::SheetType::Unknown),
mLayerIndex(0),
mPresContext(aContext),
mStyleContext(aStyleContext),
mValueStorage(aValueStorage)
+1
View File
@@ -31,6 +31,7 @@ struct nsRuleData
mozilla::RuleNodeCacheConditions mConditions;
bool mIsImportantRule;
mozilla::SheetType mLevel;
int32_t mLayerIndex;
nsPresContext* const mPresContext;
nsStyleContext* const mStyleContext;
+194 -20
View File
@@ -188,9 +188,10 @@ nsRuleNode::ChildrenHashHashKey(const void *aKey)
{
const nsRuleNode::Key *key =
static_cast<const nsRuleNode::Key*>(aKey);
// Disagreement on importance and level for the same rule is extremely
// rare, so hash just on the rule.
return PLDHashTable::HashVoidPtrKeyStub(key->mRule);
return PLDHashTable::HashVoidPtrKeyStub(key->mRule) ^
(uint32_t(key->mLayerIndex) << 4) ^
(uint32_t(key->mLevel) << 1) ^
(key->mIsImportantRule ? 1 : 0);
}
/* static */ bool
@@ -2270,18 +2271,19 @@ already_AddRefed<nsRuleNode>
nsRuleNode::CreateRootNode(nsPresContext* aPresContext)
{
return do_AddRef(new (aPresContext)
nsRuleNode(aPresContext, nullptr, nullptr, SheetType::Unknown, false));
nsRuleNode(aPresContext, nullptr, nullptr, SheetType::Unknown, false, 0));
}
nsRuleNode::nsRuleNode(nsPresContext* aContext, nsRuleNode* aParent,
nsIStyleRule* aRule, SheetType aLevel,
bool aIsImportant)
bool aIsImportant, int32_t aLayerIndex)
: mPresContext(aContext),
mParent(aParent),
mRule(aRule),
mNextSibling(nullptr),
mDependentBits((uint32_t(aLevel) << NS_RULE_NODE_LEVEL_SHIFT) |
(aIsImportant ? NS_RULE_NODE_IS_IMPORTANT : 0)),
mLayerIndex(aLayerIndex),
mNoneBits(aParent ? aParent->mNoneBits & NS_RULE_NODE_HAS_ANIMATION_DATA :
0),
mRefCnt(0)
@@ -2295,6 +2297,8 @@ nsRuleNode::nsRuleNode(nsPresContext* aContext, nsRuleNode* aParent,
NS_ASSERTION(IsRoot() || GetLevel() == aLevel, "not enough bits");
NS_ASSERTION(IsRoot() || IsImportantRule() == aIsImportant, "yikes");
NS_ASSERTION(IsRoot() || GetLayerIndex() == aLayerIndex,
"bad layer index");
aContext->StyleSet()->RuleNodeUnused(this, /* aMayGC = */ false);
// nsStyleSet::GetContext depends on there being only one animation
@@ -2319,7 +2323,7 @@ nsRuleNode::~nsRuleNode()
nsRuleNode*
nsRuleNode::Transition(nsIStyleRule* aRule, SheetType aLevel,
bool aIsImportantRule)
bool aIsImportantRule, int32_t aLayerIndex)
{
#ifdef DEBUG
{
@@ -2330,7 +2334,7 @@ nsRuleNode::Transition(nsIStyleRule* aRule, SheetType aLevel,
#endif
nsRuleNode* next = nullptr;
nsRuleNode::Key key(aRule, aLevel, aIsImportantRule);
nsRuleNode::Key key(aRule, aLevel, aIsImportantRule, aLayerIndex);
if (HaveChildren() && !ChildrenAreHashed()) {
int32_t numKids = 0;
@@ -2357,12 +2361,14 @@ nsRuleNode::Transition(nsIStyleRule* aRule, SheetType aLevel,
next = entry->mRuleNode;
} else {
next = entry->mRuleNode = new (mPresContext)
nsRuleNode(mPresContext, this, aRule, aLevel, aIsImportantRule);
nsRuleNode(mPresContext, this, aRule, aLevel, aIsImportantRule,
aLayerIndex);
}
} else if (!next) {
// Create the new entry in our list.
next = new (mPresContext)
nsRuleNode(mPresContext, this, aRule, aLevel, aIsImportantRule);
nsRuleNode(mPresContext, this, aRule, aLevel, aIsImportantRule,
aLayerIndex);
next->mNextSibling = ChildrenList();
SetChildrenList(next);
}
@@ -2545,7 +2551,8 @@ ExamineCSSValue(const nsCSSValue& aValue,
++aInheritedCount;
} else if (aValue.GetUnit() == eCSSUnit_Unset) {
++aUnsetCount;
} else if (aValue.GetUnit() == eCSSUnit_Revert) {
} else if (aValue.GetUnit() == eCSSUnit_Revert ||
aValue.GetUnit() == eCSSUnit_RevertLayer) {
++aRevertCount;
}
}
@@ -3021,7 +3028,11 @@ nsRuleNode::ResolveVariableReferences(const nsStyleStructID aSID,
"Token stream should have a defined level");
AutoRestore<SheetType> saveLevel(aRuleData->mLevel);
AutoRestore<bool> saveImportant(aRuleData->mIsImportantRule);
AutoRestore<int32_t> saveLayerIndex(aRuleData->mLayerIndex);
aRuleData->mLevel = tokenStream->mLevel;
aRuleData->mIsImportantRule = tokenStream->mIsImportant;
aRuleData->mLayerIndex = tokenStream->mLayerIndex;
// Note that ParsePropertyWithVariableReferences relies on the fact
// that the nsCSSValue in aRuleData for the property we are re-parsing
@@ -3045,6 +3056,114 @@ nsRuleNode::ResolveVariableReferences(const nsStyleStructID aSID,
return anyTokenStreams;
}
static nsCSSPropertyID
PropertyAtIndexInStruct(nsStyleStructID aSID, size_t aIndex)
{
for (int32_t prop = 0; prop < eCSSProperty_COUNT_no_shorthands; prop++) {
nsCSSPropertyID property = nsCSSPropertyID(prop);
if (nsCSSProps::kSIDTable[property] == aSID &&
nsCSSProps::PropertyIndexInStruct(property) == aIndex) {
return property;
}
}
MOZ_ASSERT_UNREACHABLE("no property for style struct index");
return eCSSProperty_UNKNOWN;
}
/* static */ bool
nsRuleNode::ResolveRevertLayerValues(const nsStyleStructID aSID,
nsRuleData* aRuleData,
nsStyleContext* aContext,
nsRuleNode* aStartRuleNode)
{
MOZ_ASSERT(aSID != eStyleStruct_Variables);
size_t nprops = nsCSSProps::PropertyCountInStruct(aSID);
bool resolvedAny = false;
for (size_t pass = 0; pass <= nprops; pass++) {
bool resolvedThisPass = false;
bool needsVariableResolution = false;
for (size_t index = 0; index < nprops; index++) {
nsCSSValue* target = aRuleData->mValueStorage + index;
if (target->GetUnit() != eCSSUnit_RevertLayer) {
continue;
}
nsCSSPropertyID property = PropertyAtIndexInStruct(aSID, index);
if (property == eCSSProperty_UNKNOWN) {
continue;
}
AutoTArray<nsCSSValue, 64> tempValues;
tempValues.SetLength(nprops);
for (size_t i = 0; i < nprops; i++) {
tempValues[i].SetDummyValue();
}
tempValues[index] = *target;
nsRuleData tempRuleData(nsCachedStyleData::GetBitForSID(aSID),
tempValues.Elements(),
aStartRuleNode->mPresContext, aContext);
tempRuleData.mValueOffsets[aSID] = 0;
uint32_t bit = nsCachedStyleData::GetBitForSID(aSID);
for (nsRuleNode* ruleNode = aStartRuleNode; ruleNode;
ruleNode = ruleNode->GetParent()) {
if (ruleNode->mNoneBits & bit) {
break;
}
nsIStyleRule* rule = ruleNode->mRule;
if (rule) {
tempRuleData.mLevel = ruleNode->GetLevel();
tempRuleData.mIsImportantRule = ruleNode->IsImportantRule();
tempRuleData.mLayerIndex = ruleNode->GetLayerIndex();
rule->MapRuleInfoInto(&tempRuleData);
}
if (tempValues[index].GetUnit() != eCSSUnit_RevertLayer) {
break;
}
}
if (tempValues[index].GetUnit() == eCSSUnit_RevertLayer) {
tempValues[index].SetRevertValue(
target->GetRevertLayerOriginValue());
} else if (tempValues[index].GetUnit() == eCSSUnit_TokenStream) {
needsVariableResolution = true;
}
*target = tempValues[index];
aRuleData->mConditions.SetUncacheable();
resolvedThisPass = true;
resolvedAny = true;
}
if (!resolvedThisPass) {
break;
}
if (needsVariableResolution &&
ResolveVariableReferences(aSID, aRuleData, aContext)) {
resolvedAny = true;
continue;
}
}
for (size_t index = 0; index < nprops; index++) {
nsCSSValue* target = aRuleData->mValueStorage + index;
if (target->GetUnit() == eCSSUnit_RevertLayer) {
target->SetRevertValue(target->GetRevertLayerOriginValue());
aRuleData->mConditions.SetUncacheable();
resolvedAny = true;
}
}
return resolvedAny;
}
const void*
nsRuleNode::WalkRuleTree(const nsStyleStructID aSID,
nsStyleContext* aContext)
@@ -3118,6 +3237,7 @@ nsRuleNode::WalkRuleTree(const nsStyleStructID aSID,
if (rule) {
ruleData.mLevel = ruleNode->GetLevel();
ruleData.mIsImportantRule = ruleNode->IsImportantRule();
ruleData.mLayerIndex = ruleNode->GetLayerIndex();
rule->MapRuleInfoInto(&ruleData);
}
@@ -3154,6 +3274,11 @@ nsRuleNode::WalkRuleTree(const nsStyleStructID aSID,
recomputeDetail = ResolveVariableReferences(aSID, &ruleData, aContext);
}
if (aSID != eStyleStruct_Variables &&
ResolveRevertLayerValues(aSID, &ruleData, aContext, this)) {
recomputeDetail = true;
}
// If needed, unset the properties that don't have a flag that allows
// them to be set for this style context. (For example, only some
// properties apply to :first-line and :first-letter.)
@@ -4889,6 +5014,7 @@ nsRuleNode::SetGenericFont(nsPresContext* aPresContext,
if (rule) {
ruleData.mLevel = ruleNode->GetLevel();
ruleData.mIsImportantRule = ruleNode->IsImportantRule();
ruleData.mLayerIndex = ruleNode->GetLayerIndex();
rule->MapRuleInfoInto(&ruleData);
}
}
@@ -4902,6 +5028,8 @@ nsRuleNode::SetGenericFont(nsPresContext* aPresContext,
}
ResolveVariableReferences(eStyleStruct_Font, &ruleData, aContext);
ResolveRevertLayerValues(eStyleStruct_Font, &ruleData, aContext,
context->RuleNode());
RuleNodeCacheConditions dummy;
nsRuleNode::SetFont(aPresContext, context,
@@ -9479,15 +9607,54 @@ nsRuleNode::ComputePositionData(void* aStartStruct,
SETCOORD_UNSET_INITIAL,
aContext, mPresContext, conditions);
// aspect-ratio: auto | <ratio>
// aspect-ratio: auto || <ratio>
const nsCSSValue* aspectRatio = aRuleData->ValueForAspectRatio();
if (aspectRatio->GetUnit() == eCSSUnit_Auto) {
pos->mAspectRatio = 0.0f;
} else {
SetFactor(*aspectRatio,
pos->mAspectRatio, conditions,
parentPos->mAspectRatio, 0.0f,
SETFCT_UNSET_INITIAL | SETFCT_POSITIVE | SETFCT_NONE);
switch (aspectRatio->GetUnit()) {
case eCSSUnit_Null:
break;
case eCSSUnit_Inherit:
conditions.SetUncacheable();
pos->mAspectRatio = parentPos->mAspectRatio;
break;
case eCSSUnit_Auto:
case eCSSUnit_Initial:
case eCSSUnit_Unset:
case eCSSUnit_Revert:
case eCSSUnit_RevertLayer:
pos->mAspectRatio = StyleAspectRatio();
break;
case eCSSUnit_Number:
// Animation normalizes a ratio to <number> / 1 when both components
// would otherwise compare equal and the pair is collapsed.
pos->mAspectRatio =
StyleAspectRatio(aspectRatio->GetFloatValue(), 1.0f, false);
break;
case eCSSUnit_Pair: {
const nsCSSValuePair* ratio = &aspectRatio->GetPairValue();
bool hasAuto = ratio->mXValue.GetUnit() == eCSSUnit_Auto;
if (hasAuto) {
MOZ_ASSERT(ratio->mYValue.GetUnit() == eCSSUnit_Pair,
"auto must be followed by a ratio");
ratio = &ratio->mYValue.GetPairValue();
}
float width = 0.0f;
float height = 0.0f;
SetFactor(ratio->mXValue, width, conditions, 0.0f, 0.0f,
SETFCT_POSITIVE);
SetFactor(ratio->mYValue, height, conditions, 0.0f, 0.0f,
SETFCT_POSITIVE);
pos->mAspectRatio = StyleAspectRatio(width, height, hasAuto);
break;
}
default:
MOZ_ASSERT_UNREACHABLE("unexpected aspect-ratio unit");
break;
}
// box-sizing: enum, inherit, initial
@@ -11081,6 +11248,8 @@ nsRuleNode::ComputeVariablesData(void* aStartStruct,
CSSVariableResolver resolver(&variables->mVariables);
resolver.Resolve(&parentVariables->mVariables,
aRuleData->mVariables);
aRuleData->mVariables->ResolveRevertLayerFallbacks(&parentVariables->mVariables,
&variables->mVariables);
conditions.SetUncacheable();
COMPUTE_END_INHERITED(Variables, variables)
@@ -11473,6 +11642,7 @@ nsRuleNode::HasAuthorSpecifiedRules(nsStyleContext* aStyleContext,
if (rule) {
ruleData.mLevel = ruleNode->GetLevel();
ruleData.mIsImportantRule = ruleNode->IsImportantRule();
ruleData.mLayerIndex = ruleNode->GetLayerIndex();
rule->MapRuleInfoInto(&ruleData);
@@ -11485,11 +11655,13 @@ nsRuleNode::HasAuthorSpecifiedRules(nsStyleContext* aStyleContext,
nsCSSUnit unit = values[i]->GetUnit();
if (unit != eCSSUnit_Null &&
unit != eCSSUnit_Revert &&
unit != eCSSUnit_RevertLayer &&
unit != eCSSUnit_Dummy &&
unit != eCSSUnit_DummyInherit) {
if (unit == eCSSUnit_Inherit ||
(i >= inheritedOffset && unit == eCSSUnit_Unset) ||
(i >= inheritedOffset && unit == eCSSUnit_Revert)) {
(i >= inheritedOffset && unit == eCSSUnit_Revert) ||
(i >= inheritedOffset && unit == eCSSUnit_RevertLayer)) {
haveExplicitUAInherit = true;
values[i]->SetDummyInheritValue();
} else {
@@ -11504,7 +11676,8 @@ nsRuleNode::HasAuthorSpecifiedRules(nsStyleContext* aStyleContext,
if (values[i]->GetUnit() != eCSSUnit_Null &&
values[i]->GetUnit() != eCSSUnit_Dummy && // see above
values[i]->GetUnit() != eCSSUnit_DummyInherit &&
values[i]->GetUnit() != eCSSUnit_Revert) {
values[i]->GetUnit() != eCSSUnit_Revert &&
values[i]->GetUnit() != eCSSUnit_RevertLayer) {
// If author colors are not allowed, only claim to have
// author-specified rules if we're looking at a non-color
// property or if we're looking at the background color and it's
@@ -11596,6 +11769,7 @@ nsRuleNode::ComputePropertiesOverridingAnimation(
if (rule) {
ruleData.mLevel = ruleNode->GetLevel();
ruleData.mIsImportantRule = ruleNode->IsImportantRule();
ruleData.mLayerIndex = ruleNode->GetLayerIndex();
// Transitions are the only non-!important level overriding
// animations in the cascade ordering. They also don't actually
+20 -5
View File
@@ -441,16 +441,20 @@ private:
struct Key {
nsIStyleRule* mRule;
mozilla::SheetType mLevel;
int32_t mLayerIndex;
bool mIsImportantRule;
Key(nsIStyleRule* aRule, mozilla::SheetType aLevel, bool aIsImportantRule)
: mRule(aRule), mLevel(aLevel), mIsImportantRule(aIsImportantRule)
Key(nsIStyleRule* aRule, mozilla::SheetType aLevel,
bool aIsImportantRule, int32_t aLayerIndex)
: mRule(aRule), mLevel(aLevel), mLayerIndex(aLayerIndex),
mIsImportantRule(aIsImportantRule)
{}
bool operator==(const Key& aOther) const
{
return mRule == aOther.mRule &&
mLevel == aOther.mLevel &&
mLayerIndex == aOther.mLayerIndex &&
mIsImportantRule == aOther.mIsImportantRule;
}
@@ -469,7 +473,7 @@ private:
static const PLDHashTableOps ChildrenHashOps;
Key GetKey() const {
return Key(mRule, GetLevel(), IsImportantRule());
return Key(mRule, GetLevel(), IsImportantRule(), GetLayerIndex());
}
// The children of this node are stored in either a hashtable or list
@@ -528,6 +532,8 @@ private:
uint32_t mDependentBits; // Used to cache the fact that we can look up
// cached data under a parent rule.
int32_t mLayerIndex;
uint32_t mNoneBits; // Used to cache the fact that the branch to this
// node specifies no non-inherited data for a
// given struct type. (This usually implies that
@@ -585,6 +591,10 @@ protected:
static bool ResolveVariableReferences(const nsStyleStructID aSID,
nsRuleData* aRuleData,
nsStyleContext* aContext);
static bool ResolveRevertLayerValues(const nsStyleStructID aSID,
nsRuleData* aRuleData,
nsStyleContext* aContext,
nsRuleNode* aStartRuleNode);
const void*
WalkRuleTree(const nsStyleStructID aSID, nsStyleContext* aContext);
@@ -792,7 +802,8 @@ protected:
private:
nsRuleNode(nsPresContext* aPresContext, nsRuleNode* aParent,
nsIStyleRule* aRule, mozilla::SheetType aLevel, bool aIsImportant);
nsIStyleRule* aRule, mozilla::SheetType aLevel,
bool aIsImportant, int32_t aLayerIndex);
~nsRuleNode();
public:
@@ -805,7 +816,7 @@ public:
// Transition never returns null; on out of memory it'll just return |this|.
nsRuleNode* Transition(nsIStyleRule* aRule, mozilla::SheetType aLevel,
bool aIsImportantRule);
bool aIsImportantRule, int32_t aLayerIndex);
nsRuleNode* GetParent() const { return mParent; }
bool IsRoot() const { return mParent == nullptr; }
@@ -825,6 +836,10 @@ public:
NS_ASSERTION(!IsRoot(), "can't call on root");
return (mDependentBits & NS_RULE_NODE_IS_IMPORTANT) != 0;
}
int32_t GetLayerIndex() const {
NS_ASSERTION(!IsRoot(), "can't call on root");
return mLayerIndex;
}
/**
* Has this rule node at some time in its lifetime been the mRuleNode
+13 -1
View File
@@ -28,7 +28,8 @@ public:
protected:
void DoForward(nsIStyleRule* aRule) {
mCurrent = mCurrent->Transition(aRule, mLevel, mImportance);
mCurrent = mCurrent->Transition(aRule, mLevel, mImportance,
mLayerIndex);
NS_POSTCONDITION(mCurrent, "Transition messed up");
}
@@ -61,10 +62,16 @@ public:
"important rules");
mLevel = aLevel;
mImportance = aImportance;
mLayerIndex = 0;
mCheckForImportantRules = aCheckForImportantRules;
}
mozilla::SheetType GetLevel() const { return mLevel; }
bool GetImportance() const { return mImportance; }
void SetLayerIndex(int32_t aLayerIndex) {
MOZ_ASSERT(aLayerIndex >= 0, "negative cascade layer index");
mLayerIndex = aLayerIndex;
}
int32_t GetLayerIndex() const { return mLayerIndex; }
bool GetCheckForImportantRules() const { return mCheckForImportantRules; }
bool AuthorStyleDisabled() const { return mAuthorStyleDisabled; }
@@ -87,6 +94,7 @@ private:
nsRuleNode* mCurrent; // Our current position. Never null.
nsRuleNode* mRoot; // The root of the tree we're walking.
mozilla::SheetType mLevel;
int32_t mLayerIndex;
bool mImportance;
bool mCheckForImportantRules; // If true, check for important rules as
// we walk and set to false if we find
@@ -97,6 +105,10 @@ public:
nsRuleWalker(nsRuleNode* aRoot, bool aAuthorStyleDisabled)
: mCurrent(aRoot)
, mRoot(aRoot)
, mLevel(mozilla::SheetType::Unknown)
, mLayerIndex(0)
, mImportance(false)
, mCheckForImportantRules(false)
, mAuthorStyleDisabled(aAuthorStyleDisabled)
{
NS_ASSERTION(mCurrent, "Caller screwed up and gave us null node");
+1 -24
View File
@@ -8,6 +8,7 @@
#ifndef nsStyleCoord_h___
#define nsStyleCoord_h___
#include "mozilla/LogicalTypes.h"
#include "nsCoord.h"
#include "nsStyleConsts.h"
#include "nsTArray.h"
@@ -17,30 +18,6 @@ namespace mozilla {
class WritingMode;
// Logical axis, edge, side and corner constants for use in various places.
enum LogicalAxis {
eLogicalAxisBlock = 0x0,
eLogicalAxisInline = 0x1
};
enum LogicalEdge {
eLogicalEdgeStart = 0x0,
eLogicalEdgeEnd = 0x1
};
enum LogicalSide {
eLogicalSideBStart = (eLogicalAxisBlock << 1) | eLogicalEdgeStart, // 0x0
eLogicalSideBEnd = (eLogicalAxisBlock << 1) | eLogicalEdgeEnd, // 0x1
eLogicalSideIStart = (eLogicalAxisInline << 1) | eLogicalEdgeStart, // 0x2
eLogicalSideIEnd = (eLogicalAxisInline << 1) | eLogicalEdgeEnd // 0x3
};
enum LogicalCorner
{
eLogicalCornerBStartIStart = 0,
eLogicalCornerBStartIEnd = 1,
eLogicalCornerBEndIEnd = 2,
eLogicalCornerBEndIStart = 3
};
} // namespace mozilla
enum nsStyleUnit : uint8_t {
Loaded 100 of 149 files, more files were not shown because too many files have changed in this diff. Show more