Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
65d7d93760 | ||
|
|
dfd0ea4e8a | ||
|
|
12a49709cb | ||
|
|
2a70c8a6f0 | ||
|
|
1f639d78ca | ||
|
|
65e8245153 | ||
|
|
bce5dbad0b | ||
|
|
0b25b5f8db | ||
|
|
7345874098 | ||
|
|
edb82fd1c9 | ||
|
|
35ebdcac66 | ||
|
|
a095661e86 | ||
|
|
205a0d66bb | ||
|
|
54945a0808 | ||
|
|
84c1eedac6 | ||
|
|
ddf5d6256e | ||
|
|
0eae777fd0 | ||
|
|
b2594a4ace | ||
|
|
30e29845c4 | ||
|
|
d8662c5dd9 | ||
|
|
0a5e50a9fe | ||
|
|
3f5b7ed020 |
No files matched your search
@@ -18,10 +18,6 @@
|
||||
#endif
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#if (MOZ_WIDGET_GTK == 3)
|
||||
extern "C" __attribute__((weak,visibility("default"))) int atk_bridge_adaptor_init(int*, char **[]);
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
@@ -33,12 +29,20 @@ extern "C" {
|
||||
typedef GType (* AtkGetTypeType) (void);
|
||||
typedef void (*GnomeAccessibilityInit) (void);
|
||||
typedef void (*GnomeAccessibilityShutdown) (void);
|
||||
#if (MOZ_WIDGET_GTK == 3)
|
||||
typedef int (*AtkBridgeAdaptorInit) (int*, char***);
|
||||
#endif
|
||||
}
|
||||
|
||||
static PRLibrary* sATKLib = nullptr;
|
||||
static const char sATKLibName[] = "libatk-1.0.so.0";
|
||||
static const char sATKHyperlinkImplGetTypeSymbol[] =
|
||||
"atk_hyperlink_impl_get_type";
|
||||
#if (MOZ_WIDGET_GTK == 3)
|
||||
static PRLibrary* sAtkBridgeAdaptorLib = nullptr;
|
||||
static const char sAtkBridgeAdaptorLibName[] = "libatk-bridge-2.0.so.0";
|
||||
static const char sAtkBridgeAdaptorInitSymbol[] = "atk_bridge_adaptor_init";
|
||||
#endif
|
||||
|
||||
gboolean toplevel_event_watcher(GSignalInvocationHint*, guint, const GValue*,
|
||||
gpointer);
|
||||
@@ -127,6 +131,38 @@ LoadGtkModule(GnomeAccessibilityModule& aModule)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#if (MOZ_WIDGET_GTK == 3)
|
||||
static bool
|
||||
InitAtkBridgeAdaptor()
|
||||
{
|
||||
AtkBridgeAdaptorInit initBridge =
|
||||
reinterpret_cast<AtkBridgeAdaptorInit>(
|
||||
PR_FindFunctionSymbolAndLibrary(sAtkBridgeAdaptorInitSymbol,
|
||||
&sAtkBridgeAdaptorLib));
|
||||
|
||||
if (!initBridge) {
|
||||
sAtkBridgeAdaptorLib = PR_LoadLibrary(sAtkBridgeAdaptorLibName);
|
||||
if (sAtkBridgeAdaptorLib) {
|
||||
initBridge =
|
||||
reinterpret_cast<AtkBridgeAdaptorInit>(
|
||||
PR_FindFunctionSymbol(sAtkBridgeAdaptorLib,
|
||||
sAtkBridgeAdaptorInitSymbol));
|
||||
if (!initBridge) {
|
||||
PR_UnloadLibrary(sAtkBridgeAdaptorLib);
|
||||
sAtkBridgeAdaptorLib = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!initBridge) {
|
||||
return false;
|
||||
}
|
||||
|
||||
initBridge(nullptr, nullptr);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
a11y::PlatformInit()
|
||||
{
|
||||
@@ -181,9 +217,7 @@ a11y::PlatformInit()
|
||||
// Init atk-bridge now
|
||||
PR_SetEnv("NO_AT_BRIDGE=0");
|
||||
#if (MOZ_WIDGET_GTK == 3)
|
||||
if (atk_bridge_adaptor_init) {
|
||||
atk_bridge_adaptor_init(nullptr, nullptr);
|
||||
} else
|
||||
if (!InitAtkBridgeAdaptor())
|
||||
#endif
|
||||
{
|
||||
nsresult rv = LoadGtkModule(sAtkBridge);
|
||||
@@ -228,6 +262,13 @@ a11y::PlatformShutdown()
|
||||
sAtkBridge.init = nullptr;
|
||||
sAtkBridge.shutdown = nullptr;
|
||||
}
|
||||
#if (MOZ_WIDGET_GTK == 3)
|
||||
if (sAtkBridgeAdaptorLib) {
|
||||
// Do not shutdown/unload atk-bridge; an exit function registered by
|
||||
// the bridge will take care of it.
|
||||
sAtkBridgeAdaptorLib = nullptr;
|
||||
}
|
||||
#endif
|
||||
#if (MOZ_WIDGET_GTK == 2)
|
||||
if (sGail.lib) {
|
||||
// Do not shutdown gail because
|
||||
|
||||
@@ -164,6 +164,7 @@ def old_configure_options(*options):
|
||||
'--enable-negotiateauth',
|
||||
'--enable-nfc',
|
||||
'--enable-npapi',
|
||||
'--enable-npapi-gtk2',
|
||||
'--enable-nspr-build',
|
||||
'--enable-official-branding',
|
||||
'--enable-official-vendor',
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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))
|
||||
|
||||
@@ -55,7 +55,12 @@ using namespace std;
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
#include <gdk/gdk.h>
|
||||
#if (GTK_MAJOR_VERSION == 3)
|
||||
#include <gtk/gtkx.h>
|
||||
#endif
|
||||
#ifdef MOZ_ENABLE_NPAPI_GTK2
|
||||
#include "gtk2xtbin.h"
|
||||
#endif
|
||||
|
||||
#elif defined(OS_WIN)
|
||||
|
||||
@@ -208,7 +213,9 @@ PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface,
|
||||
memset(&mWsInfo, 0, sizeof(mWsInfo));
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
mWsInfo.display = nullptr;
|
||||
#ifdef MOZ_ENABLE_NPAPI_GTK2
|
||||
mXtClient.top_widget = nullptr;
|
||||
#endif
|
||||
#else
|
||||
mWsInfo.display = DefaultXDisplay();
|
||||
#endif
|
||||
@@ -620,15 +627,17 @@ PluginInstanceChild::NPN_SetValue(NPPVariable aVar, void* aValue)
|
||||
NPWindowType newWindowType = windowed ? NPWindowTypeWindow : NPWindowTypeDrawable;
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
if (mWindow.type != newWindowType && mWsInfo.display) {
|
||||
// plugin type has been changed but we already have a valid display
|
||||
// so update it for the recent plugin mode
|
||||
if (mXEmbed || !windowed) {
|
||||
// Use default GTK display for XEmbed and windowless plugins
|
||||
mWsInfo.display = DefaultXDisplay();
|
||||
}
|
||||
else {
|
||||
mWsInfo.display = xt_client_get_display();
|
||||
}
|
||||
// plugin type has been changed but we already have a valid display
|
||||
// so update it for the recent plugin mode
|
||||
#ifdef MOZ_ENABLE_NPAPI_GTK2
|
||||
if (!mXEmbed && windowed) {
|
||||
mWsInfo.display = xt_client_get_display();
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
// Use default GTK display for XEmbed and windowless plugins.
|
||||
mWsInfo.display = DefaultXDisplay();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
mWindow.type = newWindowType;
|
||||
@@ -1214,12 +1223,18 @@ bool PluginInstanceChild::CreateWindow(const NPRemoteWindow& aWindow)
|
||||
if (mXEmbed) {
|
||||
mWindow.window = reinterpret_cast<void*>(aWindow.window);
|
||||
}
|
||||
#ifdef MOZ_ENABLE_NPAPI_GTK2
|
||||
else {
|
||||
Window browserSocket = (Window)(aWindow.window);
|
||||
xt_client_init(&mXtClient, mWsInfo.visual, mWsInfo.colormap, mWsInfo.depth);
|
||||
xt_client_create(&mXtClient, browserSocket, mWindow.width, mWindow.height);
|
||||
mWindow.window = (void *)XtWindow(mXtClient.child_widget);
|
||||
}
|
||||
}
|
||||
#else
|
||||
else {
|
||||
mWindow.window = reinterpret_cast<void*>(aWindow.window);
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
mWindow.window = reinterpret_cast<void*>(aWindow.window);
|
||||
#endif
|
||||
@@ -1239,7 +1254,7 @@ void PluginInstanceChild::DeleteWindow()
|
||||
if (!mWindow.window)
|
||||
return;
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
#ifdef MOZ_ENABLE_NPAPI_GTK2
|
||||
if (mXtClient.top_widget) {
|
||||
xt_client_unrealize(&mXtClient);
|
||||
xt_client_destroy(&mXtClient);
|
||||
@@ -1321,7 +1336,7 @@ PluginInstanceChild::AnswerNPP_SetWindow(const NPRemoteWindow& aWindow)
|
||||
CreateWindow(aWindow);
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
#ifdef MOZ_ENABLE_NPAPI_GTK2
|
||||
if (mXEmbed && gtk_check_version(2,18,7) != nullptr) { // older
|
||||
if (aWindow.type == NPWindowTypeWindow) {
|
||||
GdkWindow* socket_window = gdk_window_lookup(static_cast<GdkNativeWindow>(aWindow.window));
|
||||
@@ -1456,19 +1471,27 @@ PluginInstanceChild::Initialize()
|
||||
if (mWindow.type == NPWindowTypeWindow) {
|
||||
AnswerNPP_GetValue_NPPVpluginNeedsXEmbed(&mXEmbed, &rv);
|
||||
|
||||
#ifdef MOZ_ENABLE_NPAPI_GTK2
|
||||
// Set up Xt loop for windowed plugins without XEmbed support
|
||||
if (!mXEmbed) {
|
||||
xt_client_xloop_create();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Use default GTK display for XEmbed and windowless plugins
|
||||
// Use default GTK display for XEmbed and windowless plugins.
|
||||
if (mXEmbed || mWindow.type != NPWindowTypeWindow) {
|
||||
mWsInfo.display = DefaultXDisplay();
|
||||
}
|
||||
#ifdef MOZ_ENABLE_NPAPI_GTK2
|
||||
else {
|
||||
mWsInfo.display = xt_client_get_display();
|
||||
}
|
||||
#else
|
||||
else {
|
||||
mWsInfo.display = DefaultXDisplay();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return true;
|
||||
@@ -4656,7 +4679,7 @@ PluginInstanceChild::Destroy()
|
||||
|
||||
mPendingAsyncCalls.Clear();
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
#if defined(MOZ_WIDGET_GTK) && defined(MOZ_ENABLE_NPAPI_GTK2)
|
||||
if (mWindow.type == NPWindowTypeWindow && !mXEmbed) {
|
||||
xt_client_xloop_destroy();
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
#include <map>
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
#if defined(MOZ_WIDGET_GTK) && defined(MOZ_ENABLE_NPAPI_GTK2)
|
||||
#include "gtk2xtbin.h"
|
||||
#endif
|
||||
|
||||
@@ -462,6 +462,8 @@ private:
|
||||
NPSetWindowCallbackStruct mWsInfo;
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
bool mXEmbed;
|
||||
#endif
|
||||
#ifdef MOZ_ENABLE_NPAPI_GTK2
|
||||
XtClient mXtClient;
|
||||
#endif
|
||||
#elif defined(OS_WIN)
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
#include <gtk/gtk.h>
|
||||
#if (GTK_MAJOR_VERSION == 3)
|
||||
#include <gtk/gtkx.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "nsIFile.h"
|
||||
@@ -1101,7 +1104,11 @@ _getvalue(NPP aNPP,
|
||||
return InstCast(aNPP)->NPN_GetValue(aVariable, aValue);
|
||||
}
|
||||
else {
|
||||
#ifdef MOZ_ENABLE_NPAPI_GTK2
|
||||
*(void **)aValue = xt_client_get_display();
|
||||
#else
|
||||
*(void **)aValue = DefaultXDisplay();
|
||||
#endif
|
||||
}
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
@@ -143,11 +143,13 @@ LOCAL_INCLUDES += [
|
||||
|
||||
DEFINES['FORCE_PR_LOG'] = True
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gtk3':
|
||||
CXXFLAGS += CONFIG['TK_CFLAGS']
|
||||
else:
|
||||
if (CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk3' and
|
||||
CONFIG['MOZ_ENABLE_NPAPI'] and
|
||||
CONFIG['MOZ_ENABLE_NPAPI_GTK2']):
|
||||
# Force build against gtk+2 for struct offsets and such.
|
||||
CXXFLAGS += CONFIG['MOZ_GTK2_CFLAGS']
|
||||
else:
|
||||
CXXFLAGS += CONFIG['TK_CFLAGS']
|
||||
|
||||
CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
|
||||
|
||||
|
||||
+14
-5
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
+4
-4
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -13642,6 +13658,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 +13922,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 +14280,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 +15113,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 +15880,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 +15950,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 +16010,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 +16057,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 +16681,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 +16718,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 +18368,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 +18593,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 +19514,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 +19525,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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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[])
|
||||
{
|
||||
|
||||
@@ -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 ||
|
||||
@@ -3007,6 +3071,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 +3508,8 @@ nsCSSValueTokenStream::nsCSSValueTokenStream()
|
||||
: mPropertyID(eCSSProperty_UNKNOWN)
|
||||
, mShorthandPropertyID(eCSSProperty_UNKNOWN)
|
||||
, mLevel(SheetType::Count)
|
||||
, mIsImportant(false)
|
||||
, mLayerIndex(0)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsCSSValueTokenStream);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -31,6 +31,7 @@ struct nsRuleData
|
||||
mozilla::RuleNodeCacheConditions mConditions;
|
||||
bool mIsImportantRule;
|
||||
mozilla::SheetType mLevel;
|
||||
int32_t mLayerIndex;
|
||||
nsPresContext* const mPresContext;
|
||||
nsStyleContext* const mStyleContext;
|
||||
|
||||
|
||||
+147
-12
@@ -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,
|
||||
@@ -11081,6 +11209,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 +11603,7 @@ nsRuleNode::HasAuthorSpecifiedRules(nsStyleContext* aStyleContext,
|
||||
if (rule) {
|
||||
ruleData.mLevel = ruleNode->GetLevel();
|
||||
ruleData.mIsImportantRule = ruleNode->IsImportantRule();
|
||||
ruleData.mLayerIndex = ruleNode->GetLayerIndex();
|
||||
|
||||
rule->MapRuleInfoInto(&ruleData);
|
||||
|
||||
@@ -11485,11 +11616,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 +11637,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 +11730,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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -847,14 +847,14 @@ ReplaceAnimationRule(nsRuleNode *aOldRuleNode,
|
||||
"wrong level");
|
||||
|
||||
if (aNewAnimRule) {
|
||||
n = n->Transition(aNewAnimRule, SheetType::Animation, false);
|
||||
n = n->Transition(aNewAnimRule, SheetType::Animation, false, 0);
|
||||
n->SetIsAnimationRule();
|
||||
}
|
||||
|
||||
for (uint32_t i = moreSpecificNodes.Length(); i-- != 0; ) {
|
||||
nsRuleNode *oldNode = moreSpecificNodes[i];
|
||||
n = n->Transition(oldNode->GetRule(), oldNode->GetLevel(),
|
||||
oldNode->IsImportantRule());
|
||||
oldNode->IsImportantRule(), oldNode->GetLayerIndex());
|
||||
}
|
||||
|
||||
return n;
|
||||
@@ -1124,6 +1124,7 @@ FileRulesFromAllChildProcessors(
|
||||
if (i > 0) {
|
||||
aRuleWalker->SetLevel(aLevel, false, true);
|
||||
}
|
||||
aRuleWalker->SetLayerIndex(i);
|
||||
nsCOMPtr<nsIStyleRuleProcessor> processor = (*processors)[i];
|
||||
(*aCollectorFunc)(processor, aData);
|
||||
TrackRuleNodeForCurrentOrigin(aRuleWalker,
|
||||
@@ -1307,6 +1308,7 @@ nsStyleSet::FileRules(nsIStyleRuleProcessor::EnumFunc aCollectorFunc,
|
||||
if (haveAnyImportantDocRules) {
|
||||
for (uint32_t i = lastDocRNs.Length(); i-- != 0; ) {
|
||||
aRuleWalker->SetLevel(SheetType::Doc, true, false);
|
||||
aRuleWalker->SetLayerIndex(i);
|
||||
nsRuleNode* startRN = lastDocRNs[i];
|
||||
nsRuleNode* endRN = i == 0 ? lastSVGAttrAnimationRN : lastDocRNs[i - 1];
|
||||
if (haveImportantDocRules[i]) {
|
||||
@@ -1352,6 +1354,7 @@ nsStyleSet::FileRules(nsIStyleRuleProcessor::EnumFunc aCollectorFunc,
|
||||
if (haveAnyImportantUserRules) {
|
||||
for (uint32_t i = lastUserRNs.Length(); i-- != 0;) {
|
||||
aRuleWalker->SetLevel(SheetType::User, true, false);
|
||||
aRuleWalker->SetLayerIndex(i);
|
||||
nsRuleNode* startRN = lastUserRNs[i];
|
||||
nsRuleNode* endRN = i == 0 ? lastAgentRN : lastUserRNs[i - 1];
|
||||
if (haveImportantUserRules[i]) {
|
||||
@@ -1373,6 +1376,7 @@ nsStyleSet::FileRules(nsIStyleRuleProcessor::EnumFunc aCollectorFunc,
|
||||
if (haveAnyImportantAgentRules) {
|
||||
for (uint32_t i = lastAgentRNs.Length(); i-- != 0;) {
|
||||
aRuleWalker->SetLevel(SheetType::Agent, true, false);
|
||||
aRuleWalker->SetLayerIndex(i);
|
||||
nsRuleNode* startRN = lastAgentRNs[i];
|
||||
nsRuleNode* endRN = i == 0 ? lastRestrictionRN : lastAgentRNs[i - 1];
|
||||
if (haveImportantAgentRules[i]) {
|
||||
@@ -1585,6 +1589,7 @@ nsStyleSet::ResolveStyleByAddingRules(nsStyleContext* aBaseContext,
|
||||
struct RuleNodeInfo {
|
||||
nsIStyleRule* mRule;
|
||||
SheetType mLevel;
|
||||
int32_t mLayerIndex;
|
||||
bool mIsImportant;
|
||||
bool mIsAnimationRule;
|
||||
};
|
||||
@@ -1657,6 +1662,7 @@ nsStyleSet::RuleNodeWithReplacement(Element* aElement,
|
||||
RuleNodeInfo* curRule = rules.AppendElement();
|
||||
curRule->mRule = ruleNode->GetRule();
|
||||
curRule->mLevel = ruleNode->GetLevel();
|
||||
curRule->mLayerIndex = ruleNode->GetLayerIndex();
|
||||
curRule->mIsImportant = ruleNode->IsImportantRule();
|
||||
curRule->mIsAnimationRule = ruleNode->IsAnimationRule();
|
||||
}
|
||||
@@ -1771,6 +1777,7 @@ nsStyleSet::RuleNodeWithReplacement(Element* aElement,
|
||||
}
|
||||
|
||||
if (!doReplace) {
|
||||
ruleWalker.SetLayerIndex(ruleInfo.mLayerIndex);
|
||||
ruleWalker.ForwardOnPossiblyCSSRule(ruleInfo.mRule);
|
||||
if (ruleInfo.mIsAnimationRule) {
|
||||
ruleWalker.CurrentNode()->SetIsAnimationRule();
|
||||
|
||||
@@ -245,6 +245,7 @@ support-files =
|
||||
support-files = redundant_font_download.sjs
|
||||
[test_rem_unit.html]
|
||||
[test_restyles_in_smil_animation.html]
|
||||
[test_revert_layer.html]
|
||||
[test_root_node_display.html]
|
||||
[test_rule_insertion.html]
|
||||
[test_rule_serialization.html]
|
||||
|
||||
@@ -37,6 +37,7 @@ function runTest()
|
||||
"(unknown:) or (color: green)",
|
||||
"(unknown) or (color: green)",
|
||||
"(font: 16px serif)",
|
||||
"(all: revert-layer)",
|
||||
"(color:) or (color: green)",
|
||||
"not (@page)",
|
||||
"not ({ something @with [ balanced ] brackets })",
|
||||
@@ -69,6 +70,7 @@ function runTest()
|
||||
"not ({ something @with (unbalanced brackets })",
|
||||
"(color: green) or an-extension(that is [unbalanced)",
|
||||
"not(unknown: unknown)",
|
||||
"not (all: revert-layer)",
|
||||
"(color: green) or(color: blue)",
|
||||
"(color: green;)",
|
||||
"(font-family: 'Helvetica\n",
|
||||
@@ -87,7 +89,9 @@ function runTest()
|
||||
["font", "16px serif"],
|
||||
["font", "16px /* comment */ serif"],
|
||||
["font", "16px\nserif"],
|
||||
["color", "\\0067reen"]
|
||||
["color", "\\0067reen"],
|
||||
["all", "revert-layer"],
|
||||
["color", "revert-layer"]
|
||||
];
|
||||
|
||||
var failingDeclarations = [
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test CSS revert-layer cascade behavior</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="display"></div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
let fixtureCount = 0;
|
||||
|
||||
function runFixture(css, callback) {
|
||||
const id = "revert-layer-fixture-" + (++fixtureCount);
|
||||
const style = document.createElement("style");
|
||||
style.textContent = css.replace(/__ID__/g, id);
|
||||
document.head.appendChild(style);
|
||||
|
||||
const element = document.createElement("div");
|
||||
element.id = id;
|
||||
document.getElementById("display").appendChild(element);
|
||||
|
||||
try {
|
||||
callback(element, getComputedStyle(element));
|
||||
} finally {
|
||||
element.remove();
|
||||
style.remove();
|
||||
}
|
||||
}
|
||||
|
||||
ok(CSS.supports("color", "revert-layer"), "revert-layer parses as a CSS-wide keyword");
|
||||
ok(CSS.supports("all", "revert-layer"), "all accepts revert-layer");
|
||||
ok(!CSS.supports("not (all: revert-layer)"), "supports negation sees revert-layer support");
|
||||
|
||||
runFixture(`
|
||||
@layer { #__ID__ { color: rgb(0, 128, 0); } }
|
||||
@layer { #__ID__ { color: red; color: revert-layer; } }
|
||||
`, function(element, cs) {
|
||||
is(cs.color, "rgb(0, 128, 0)", "revert-layer rolls back to a previous explicit layer");
|
||||
});
|
||||
|
||||
runFixture(`
|
||||
@layer { #__ID__ { color: rgb(0, 128, 0); } }
|
||||
#__ID__ { color: red; color: revert-layer; }
|
||||
`, function(element, cs) {
|
||||
is(cs.color, "rgb(0, 128, 0)", "revert-layer rolls back from the implicit outer layer");
|
||||
});
|
||||
|
||||
runFixture(`
|
||||
@layer {
|
||||
#__ID__ { color: rgb(0, 128, 0); width: 5px; height: 6px; }
|
||||
}
|
||||
@layer {
|
||||
#__ID__ { color: red; width: 50px; height: 60px; }
|
||||
#__ID__ { all: revert-layer; }
|
||||
}
|
||||
`, function(element, cs) {
|
||||
is(cs.color, "rgb(0, 128, 0)", "all: revert-layer rolls color back");
|
||||
is(cs.width, "5px", "all: revert-layer rolls width back");
|
||||
is(cs.height, "6px", "all: revert-layer rolls height back");
|
||||
});
|
||||
|
||||
runFixture(`
|
||||
@layer { #__ID__ { height: 7px; } }
|
||||
@layer { #__ID__ { block-size: revert-layer; } }
|
||||
`, function(element, cs) {
|
||||
is(cs.height, "7px", "revert-layer on a logical alias rolls back the physical property");
|
||||
});
|
||||
|
||||
runFixture(`
|
||||
@layer { #__ID__ { color: rgb(0, 128, 0) !important; } }
|
||||
@layer { #__ID__ { color: red !important; color: revert-layer !important; } }
|
||||
`, function(element, cs) {
|
||||
is(cs.color, "rgb(0, 128, 0)", "important revert-layer uses reversed layer order");
|
||||
});
|
||||
|
||||
runFixture(`
|
||||
@layer { #__ID__ { color: rgb(0, 128, 0); } }
|
||||
`, function(element, cs) {
|
||||
element.style.color = "revert-layer";
|
||||
is(cs.color, "rgb(0, 128, 0)", "normal style attribute revert-layer rolls back to author rules");
|
||||
});
|
||||
|
||||
runFixture(`
|
||||
@layer { #__ID__ { color: rgb(0, 128, 0) !important; } }
|
||||
`, function(element, cs) {
|
||||
element.style.setProperty("color", "revert-layer", "important");
|
||||
is(cs.color, "rgb(0, 128, 0)",
|
||||
"important style attribute revert-layer does not skip author important rules");
|
||||
});
|
||||
|
||||
runFixture(`
|
||||
@layer {
|
||||
#__ID__ { --x:PASS; margin: 1px; padding-left: 1px; }
|
||||
}
|
||||
@layer {
|
||||
#__ID__ {
|
||||
--x: var(--unknown, revert-layer);
|
||||
margin: var(--unknown, revert-layer);
|
||||
padding-left: var(--unknown, revert-layer);
|
||||
}
|
||||
}
|
||||
`, function(element, cs) {
|
||||
is(cs.getPropertyValue("--x"), "PASS", "custom property var() fallback can resolve to revert-layer");
|
||||
is(cs.marginLeft, "1px", "shorthand var() fallback can resolve to revert-layer");
|
||||
is(cs.paddingLeft, "1px", "longhand var() fallback can resolve to revert-layer");
|
||||
});
|
||||
|
||||
runFixture(`
|
||||
@layer { #__ID__ { --x:PASS; } }
|
||||
@layer { #__ID__ { --x: var(--unknown-a, revert-layer); } }
|
||||
@layer { #__ID__ { --x: var(--unknown-b, revert-layer); } }
|
||||
`, function(element, cs) {
|
||||
is(cs.getPropertyValue("--x"), "PASS",
|
||||
"custom property fallback continues past lower declarations that also resolve to revert-layer");
|
||||
});
|
||||
|
||||
SimpleTest.finish();
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
@@ -56,13 +56,13 @@ template<typename T, typename Storage>
|
||||
struct EnumTypeFitsWithin
|
||||
: public detail::EnumFitsWithinHelper<
|
||||
sizeof(T),
|
||||
std::is_signed<typename std::underlying_type<T>::type>::value,
|
||||
std::is_signed_v<typename std::underlying_type_t<T>>,
|
||||
sizeof(Storage),
|
||||
std::is_signed<Storage>::value
|
||||
std::is_signed_v<Storage>
|
||||
>
|
||||
{
|
||||
static_assert(std::is_enum<T>::value, "must provide an enum type");
|
||||
static_assert(std::is_integral<Storage>::value, "must provide an integral type");
|
||||
static_assert(std::is_enum_v<T>, "must provide an enum type");
|
||||
static_assert(std::is_integral_v<Storage>, "must provide an integral type");
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -31,7 +31,7 @@ template<typename EnumTypeT>
|
||||
class EnumeratedIterator
|
||||
{
|
||||
public:
|
||||
typedef typename std::underlying_type<EnumTypeT>::type IntTypeT;
|
||||
typedef typename std::underlying_type_t<EnumTypeT> IntTypeT;
|
||||
|
||||
template<typename EnumType>
|
||||
explicit EnumeratedIterator(EnumType aCurrent)
|
||||
|
||||
+7
-7
@@ -115,7 +115,7 @@ public:
|
||||
*/
|
||||
template<typename U,
|
||||
typename =
|
||||
typename std::enable_if<std::is_convertible<U, T>::value>::type>
|
||||
typename std::enable_if_t<std::is_convertible_v<U, T>>>
|
||||
MOZ_IMPLICIT
|
||||
Maybe(const Maybe<U>& aOther)
|
||||
: mIsSome(false)
|
||||
@@ -139,7 +139,7 @@ public:
|
||||
*/
|
||||
template<typename U,
|
||||
typename =
|
||||
typename std::enable_if<std::is_convertible<U, T>::value>::type>
|
||||
typename std::enable_if_t<std::is_convertible_v<U, T>>>
|
||||
MOZ_IMPLICIT
|
||||
Maybe(Maybe<U>&& aOther)
|
||||
: mIsSome(false)
|
||||
@@ -168,7 +168,7 @@ public:
|
||||
|
||||
template<typename U,
|
||||
typename =
|
||||
typename std::enable_if<std::is_convertible<U, T>::value>::type>
|
||||
typename std::enable_if_t<std::is_convertible_v<U, T>>>
|
||||
Maybe& operator=(const Maybe<U>& aOther)
|
||||
{
|
||||
if (aOther.isSome()) {
|
||||
@@ -203,7 +203,7 @@ public:
|
||||
|
||||
template<typename U,
|
||||
typename =
|
||||
typename std::enable_if<std::is_convertible<U, T>::value>::type>
|
||||
typename std::enable_if_t<std::is_convertible_v<U, T>>>
|
||||
Maybe& operator=(Maybe<U>&& aOther)
|
||||
{
|
||||
if (aOther.isSome()) {
|
||||
@@ -539,8 +539,8 @@ class Maybe<T&> {
|
||||
* reference value, you need to use emplace() instead.
|
||||
*/
|
||||
template<typename T,
|
||||
typename U = typename std::remove_cv<
|
||||
typename std::remove_reference<T>::type>::type>
|
||||
typename U = typename std::remove_cv_t<
|
||||
typename std::remove_reference_t<T>>>
|
||||
Maybe<U>
|
||||
Some(T&& aValue)
|
||||
{
|
||||
@@ -574,7 +574,7 @@ ToMaybe(T* aPtr)
|
||||
template<typename T> bool
|
||||
operator==(const Maybe<T>& aLHS, const Maybe<T>& aRHS)
|
||||
{
|
||||
static_assert(!std::is_reference<T>::value,
|
||||
static_assert(!std::is_reference_v<T>,
|
||||
"operator== is not defined for Maybe<T&>, compare values or "
|
||||
"addresses explicitly instead");
|
||||
if (aLHS.isNothing() != aRHS.isNothing()) {
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ public:
|
||||
explicit SaturateOp(T& aValue)
|
||||
: mValue(aValue)
|
||||
{
|
||||
// We should actually check for |std::is_scalar<T>::value| to be
|
||||
// We should actually check for |std::is_scalar_v<T>| to be
|
||||
// true, but this type trait is not available everywhere. Relax
|
||||
// this assertion if you want to use floating point values as well.
|
||||
static_assert(IsIntegral<T>::value,
|
||||
|
||||
+33
-10
@@ -2135,6 +2135,16 @@ if test -z "$XULRUNNER_STUB_NAME"; then
|
||||
fi
|
||||
AC_SUBST(XULRUNNER_STUB_NAME)
|
||||
|
||||
dnl ========================================================
|
||||
|
||||
dnl there are a lot of tests on MOZ_ENABLE_GTK below, that are more convenient
|
||||
dnl to keep that way than testing against MOZ_WIDGET_TOOLKIT
|
||||
case "$MOZ_WIDGET_TOOLKIT" in
|
||||
gtk*)
|
||||
MOZ_ENABLE_GTK=1
|
||||
;;
|
||||
esac
|
||||
|
||||
dnl ========================================================
|
||||
dnl = NPAPI support
|
||||
dnl ========================================================
|
||||
@@ -2153,6 +2163,22 @@ fi
|
||||
|
||||
AC_SUBST(MOZ_ENABLE_NPAPI)
|
||||
|
||||
if test -n "$MOZ_ENABLE_GTK" ; then
|
||||
MOZ_ENABLE_NPAPI_GTK2=1
|
||||
|
||||
MOZ_ARG_DISABLE_BOOL(npapi-gtk2,
|
||||
[ --disable-npapi-gtk2 Disable GTK2 support for NPAPI plugins ],
|
||||
MOZ_ENABLE_NPAPI_GTK2=,
|
||||
MOZ_ENABLE_NPAPI_GTK2=1)
|
||||
|
||||
if test "$MOZ_ENABLE_NPAPI" -a "$MOZ_ENABLE_NPAPI_GTK2"
|
||||
then
|
||||
AC_DEFINE(MOZ_ENABLE_NPAPI_GTK2)
|
||||
fi
|
||||
|
||||
AC_SUBST(MOZ_ENABLE_NPAPI_GTK2)
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl =
|
||||
dnl = Toolkit Options
|
||||
@@ -2192,13 +2218,9 @@ cocoa)
|
||||
|
||||
esac
|
||||
|
||||
dnl there are a lot of tests on MOZ_ENABLE_GTK below, that are more convenient
|
||||
dnl to keep that way than testing against MOZ_WIDGET_TOOLKIT
|
||||
case "$MOZ_WIDGET_TOOLKIT" in
|
||||
gtk*)
|
||||
MOZ_ENABLE_GTK=1
|
||||
;;
|
||||
esac
|
||||
if test "$MOZ_WIDGET_TOOLKIT" = gtk2 -a -z "$MOZ_ENABLE_NPAPI_GTK2"; then
|
||||
AC_MSG_ERROR([--disable-npapi-gtk2 cannot be used with GTK2 browser builds.])
|
||||
fi
|
||||
|
||||
if test "$COMPILE_ENVIRONMENT"; then
|
||||
if test "$MOZ_WIDGET_TOOLKIT" = gtk3; then
|
||||
@@ -2210,8 +2232,9 @@ if test "$COMPILE_ENVIRONMENT"; then
|
||||
dnl are suppressed by widget/gtk/compat-gtk3/gdk/gdkversionmacros.h.
|
||||
AC_DEFINE_UNQUOTED(GDK_VERSION_MAX_ALLOWED,$GDK_VERSION_MAX_ALLOWED)
|
||||
GLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_32
|
||||
dnl We want to check GTK2 packages if NPAPI is enabled, even if building with GTK3.
|
||||
if test "$MOZ_ENABLE_NPAPI"; then
|
||||
dnl GTK2 NPAPI plugin support needs GTK2 packages, even when the browser
|
||||
dnl itself is built against GTK3.
|
||||
if test "$MOZ_ENABLE_NPAPI" -a "$MOZ_ENABLE_NPAPI_GTK2"; then
|
||||
MOZ_CHECK_GTK2=1
|
||||
fi
|
||||
fi
|
||||
@@ -2229,7 +2252,7 @@ if test "$COMPILE_ENVIRONMENT"; then
|
||||
|
||||
if test "$MOZ_CHECK_GTK2"; then
|
||||
PKG_CHECK_MODULES(MOZ_GTK2, gtk+-2.0 >= $GTK2_VERSION gtk+-unix-print-2.0 glib-2.0 >= $GLIB_VERSION gobject-2.0 $GDK_PACKAGES, ,
|
||||
[AC_MSG_ERROR([ * * * Could not find gtk+-2.0. Required for NPAPI plugins. To build without NPAPI, add --disable-npapi to your .mozconfig and clobber.])])
|
||||
[AC_MSG_ERROR([ * * * Could not find gtk+-2.0. Required for GTK2 browser builds and GTK2 NPAPI plugin support. To build a GTK3 browser with NPAPI but without GTK2 NPAPI plugin support, add --disable-npapi-gtk2 to your .mozconfig and clobber.])])
|
||||
MOZ_GTK2_CFLAGS="-I${_topsrcdir}/widget/gtk/compat $MOZ_GTK2_CFLAGS"
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -445,8 +445,6 @@ option('--disable-skia', help='Disable use of Skia')
|
||||
|
||||
@depends('--disable-skia', target)
|
||||
def skia(value, target):
|
||||
if value.origin == 'default' and target.endianness == 'big':
|
||||
return None
|
||||
if value:
|
||||
return True
|
||||
|
||||
|
||||
@@ -3727,7 +3727,7 @@ NSEvent* gLastDragMouseDownEvent = nil;
|
||||
|
||||
NSSize viewSize = [self bounds].size;
|
||||
gfx::IntSize backingSize = gfx::IntSize::Truncate(viewSize.width * scale, viewSize.height * scale);
|
||||
#if defined(MAC_OS_X_VERSION_10_7) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7)
|
||||
#ifdef USE_SKIA
|
||||
LayoutDeviceIntRegion region = [self nativeDirtyRegionWithBoundingRect:aRect];
|
||||
|
||||
bool painted = mGeckoChild->PaintWindowInContext(cgContext, region, backingSize);
|
||||
|
||||
@@ -3,4 +3,7 @@
|
||||
# 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/.
|
||||
|
||||
DIRS += ['stub', 'gtk2', 'gtk3']
|
||||
DIRS += ['stub', 'gtk3']
|
||||
|
||||
if CONFIG['MOZ_ENABLE_NPAPI_GTK2']:
|
||||
DIRS += ['gtk2']
|
||||
@@ -7,9 +7,12 @@ SOURCES += [
|
||||
'../mozgtk.c',
|
||||
]
|
||||
|
||||
for var in ('COMMON_SYMBOLS', 'GTK2_SYMBOLS', 'GTK3_SYMBOLS'):
|
||||
for var in ('COMMON_SYMBOLS', 'GTK3_SYMBOLS'):
|
||||
DEFINES[var] = True
|
||||
|
||||
if CONFIG['MOZ_ENABLE_NPAPI_GTK2']:
|
||||
DEFINES['GTK2_SYMBOLS'] = True
|
||||
|
||||
SharedLibrary('mozgtk_stub')
|
||||
|
||||
SONAME = 'mozgtk'
|
||||
+2
-1
@@ -52,7 +52,8 @@ if toolkit in ('cocoa', 'gtk2', 'gtk3'):
|
||||
if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
|
||||
DIRS += ['gtk']
|
||||
|
||||
if CONFIG['MOZ_X11'] and CONFIG['MOZ_ENABLE_NPAPI']:
|
||||
if (CONFIG['MOZ_X11'] and CONFIG['MOZ_ENABLE_NPAPI'] and
|
||||
CONFIG['MOZ_ENABLE_NPAPI_GTK2']):
|
||||
DIRS += ['gtkxtbin']
|
||||
|
||||
XPIDL_SOURCES += [
|
||||
|
||||
Reference in new issue
Block a user