Compare commits

...
Author SHA1 Message Date
Matt A. Tobin 42f895f27f Update old.configure for --enable-phoenix-extensions 2020-09-01 05:44:49 +00:00
Moonchild a6f632714f Merge branch 'redwood' into release 2020-08-31 05:54:39 +00:00
Moonchild b28effe2ea Remove unsupported CE keyword from HTMLLinkElement.webidl 2020-08-30 12:04:46 +00:00
Moonchild afd6edd667 Clobber for NSS update 2020-08-30 11:59:23 +00:00
Moonchild 582a1ce72a [NSS] Version and build bump 2020-08-30 11:59:14 +00:00
J.C. Jones 71ac56ba40 [NSS] Prevent slotLock race in NSC_GetTokenInfo
Basically, NSC_GetTokenInfo doesn't lock slot->slotLock before accessing slot
after obtaining it, even though slotLock is defined as its lock.
2020-08-30 11:59:06 +00:00
Moonchild ae184d09e6 Issue #1587 followup - Improve resilience of AbortSignals. 2020-08-30 11:58:58 +00:00
Moonchild 868f0755ae [misc/mar] Don't use a signed type for a length parameter. 2020-08-30 11:58:49 +00:00
Kris Maglione 5ca8fbd41c [DOM] Only construct JS-implemented objects if inner window is current. 2020-08-30 11:58:40 +00:00
Moonchild 549c8b9283 [media] Only include source error details in debugging scenarios.
Unless a user is debugging media errors, this detail is unnecessary to report
and could include sensitive data which could be abused by third-party
requesters. This aligns it with the standard success/error paradigms in normal
browsing situations.
2020-08-30 11:58:32 +00:00
Moonchild 77e8ba7eaf Issue #618 - Implement async attribute for inline module scripts. (uplift)
This commit does several things:
- Moves the pref check from ScriptLoader to ns[I]Document so it can be called on
the document.
- Changes the atrribute freezing function to a better name that takes the
document as a parameter.
- Sets the proper async/defer attributes on HTML script elements based on
keywords and whether they are module scripts or not.
2020-08-30 09:51:18 +00:00
Moonchild e854d58633 Issue #618 - (async) Keep track of script modes in a single mode state.
This simplifies handling of combinations of async/defer by assigning one and
only one state to scripts.
If async then always async > if defer or module then defer > otherwise blocking.
2020-08-30 09:48:07 +00:00
Moonchild d58cb8e11b Issue #618 - (async, preload) Correctly pass info about async/defer to parser.
This makes sure we don't block body-referred sub-resources by head-referenced
defer and async scripts. This is important for all script loads, not just
modules, but is added here because it was run into while implementing modules.
2020-08-30 09:47:49 +00:00
Moonchild 429a7bdb93 Issue #618 - (async) Split out function to add async request. 2020-08-30 09:40:15 +00:00
Moonchild 3f14e9ec5f Issue #618 - Rename some script load request flags to be more descriptive. 2020-08-30 09:40:03 +00:00
Moonchild aefb293793 Issue #618 - Make document.currentScript null in modules.
Because the spec says so.
2020-08-30 09:39:55 +00:00
Jon Coppeard c583315558 Issue #618 - Fix processing of non-parser-generated module scripts. 2020-08-30 09:39:45 +00:00
Jon Coppeard 834ecdc59a Issue #618 - Handle errors for inline module scripts and ensure we update the
module map after fetch errors.
2020-08-30 09:39:23 +00:00
Moonchild 798c2ed4f8 Issue #618 - Split SRI verification out from OnStreamComplete. 2020-08-30 09:39:13 +00:00
Moonchild 767b637c83 Issue #618 - Split handling of load errors out from OnStreamComplete. 2020-08-30 09:39:03 +00:00
Moonchild 702ad218b0 Issue #618 - Integrity for descendant module scripts should be the empty string
Because the spec says so.
2020-08-30 09:38:54 +00:00
Jon Coppeard b9af9c0c51 Issue #618 - Don't mute errors for module scripts because they always use CORS 2020-08-30 09:38:44 +00:00
Moonchild 9d6e28d3d0 Issue #618: Pass down referrer and referrer policy when fetching modules.
Because the spec says so.
2020-08-30 09:38:29 +00:00
Moonchild c735355ae1 Issue #618: Ignore 'event' and 'for' attributes for module scripts.
Because the spec says so.
2020-08-30 09:38:17 +00:00
Moonchild 10a10fd375 Issue #618 - Simplify module resolve hook to be a function pointer
This is an ahead-of time port to try and address #1624.
This is based on BZ 1461751 and Jon Coppeard's work in it.
2020-08-30 09:37:12 +00:00
Moonchild 1012dbe9e5 [js] Add some utility functions to get the current JS runtime. 2020-08-30 09:37:03 +00:00
Gaming4JC 9982c1f5cb Issue #618 - Keep track of which modules in a graph have been fetched using a visited set
Ref: BZ 1365187
2020-08-30 09:36:51 +00:00
Gaming4JC fe912e94e4 Issue #618 - Simplify module map interface
Ref: BZ 1365187
2020-08-30 09:36:41 +00:00
Gaming4JC 770b1c9071 Issue #618 - Align error handling for module scripts with the spec - Debug follow up
MODULE_STATUS_ERRORED is no more. Replacing with newer API.

Ref: BZ 1420420
2020-08-30 09:35:19 +00:00
Gaming4JC daf56131a7 Issue #618 - Lazily initialise module binding maps - Debug follow up
The added debug assertion does not work due to missing API.
They were added in BZ 1337491, 1395366, and others, but were primarily used for multi-threading.
This uses our existing non-multithreaded syntax instead, resolving a `no member named` build error.
2020-08-30 09:35:07 +00:00
Jon Coppeard d8686de401 Issue #618 - Record module dependency before starting fetch so that error
handling works correctly

Ref BZ 1395896
2020-08-30 09:33:58 +00:00
Moonchild c8a38346c8 Issue #618 - Lazily initialise module binding maps
Make it so they are not allocated on a background thread in a different zone to
the final module.

Ref: BZ 1372258
2020-08-30 09:33:33 +00:00
Moonchild 70bafe4df5 Issue #618 - Use a single slot for the module's environment object.
According to the spec this isn't created until the module is instantiated, but
we create it when we compile the module.
We stored this previously in InitialEnvironmentSlot and copied it to
EnvironmentSlot when it was supposed to be created, but we can just store it in
the latter slot straight away and check the module's status and return null if
it shouldn't exist yet.

This reduces the number of slots needed on a moduleObject to 17.

Re: BZ 1420412 Part 1
We can't implement the second part to further reduce our number of slots,
because it relies on SetProxyReservedSlot which in turn relies on
rearchitecturing JS proxies to make reserved slots dynamic. That's a rabbit hole
we really don't want to fall into.
So, we'll end up being a bit slower because it can't be in-line allocated with
having more than 16 slots, but so be it. I sincerely doubt it will make any
practical difference.
2020-08-30 09:33:21 +00:00
Moonchild 498b1ab0c8 Issue #618 - Align error handling for module scripts with the spec (again)
This updates module implementation to match spec regarding handling of
instantiation errors, after it was changed yet again, this time to not remember
instantiation errors, but instead immediately rethrow applicable ones.

Ref: BZ 1420420
2020-08-30 09:33:06 +00:00
Moonchild 2f145b6eda Issue #618 - Fix error events fired when loading JS module dependencies fail
When module dependencies fail, don't spam with errors for each import; only fire
the error event once.

Ref: BZ 1421259
2020-08-30 09:32:52 +00:00
Matt A. Tobin 06a092d08e Follow up to eb28b1f32 - Correct inputmethod build file by putting Keyboard.jsm back in EXTRA_JS_MODULES
JSMs are NOT Components.
2020-08-30 09:31:24 +00:00
Moonchild d107016d37 [js] Reinstate precise floating point model for all js sources. 2020-08-30 09:31:10 +00:00
Moonchild 63371593c0 Issue #457 - Silence SQLite compiler warning
Our use of SQLite explicitly avoids using MSVC's _msize which the lib would
notrmally use. This was set up this way in BZ bug 719579 for legitimate reasons
(because _msize would end up using the system symbol, which would crash trying
to get the size information from jemalloc allocations). Since we build the
SQLite lib separately there is no easy way to avoid this warning as it's not
directly linked against mozglue.dll which has the jemalloc functions it wants
for _msize when not using the system allocator. It is implicitly assuming the
function is an extern returning an int (with the call specifically  casting to
int) which is correct (well, correct _enough_, anyway) so the warning can
safely be ignored for our specific use as it all lines up at link time.
2020-08-30 09:30:50 +00:00
Moonchild ce1dc7e6c6 [db] Update SQLite lib to 3.33.0 2020-08-30 09:30:28 +00:00
Moonchild a4780ebaeb Issue #1629 - Uplift implementation of <link disabled> behavior for stylesheets. 2020-08-30 09:29:45 +00:00
Gaming4JC c384fa6e25 Issue #1620 - Intrinsic Aspect Ratio: Debug Follow up.
Newly introduced aspect-ratio property did not have CSS_PROP_LIST_EXCLUDE_INTERNAL defines, resulting in the following assertion:
\!nsCSSProps::PropHasFlags(p, (1<<28)) (properties defined outside of #ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL sections must not have the CSS_PROPERTY_INTERNAL flag), at ...layout/style/nsCSSProps.cpp:289

This patch resolves the assertion by adding #ifndef around the aspect-ratio property.
2020-08-30 09:24:25 +00:00
Moonchild 5e8e0d05a6 [CSS] Alias -webkit-appearance for compatibility reasons
Since this is supported as an alias by Firefox and Edge for the same
reasons and we have websites using this to (attempt to) override the
system-provided styling with their own, leaving out the only supported
keyword we'd otherwise have (with -moz- prefix) but still stating
-webkit-.

TODO: unprefix this completely and make the vendor prefixes aliases.
2020-08-30 09:24:02 +00:00
Andy bf95a03189 Issue #1620 - Enable Intrinsic Ratio by Default
A simpler name feels so much cleaner.
2020-08-30 09:23:46 +00:00
Andy c75e412f17 Issue #1620 - Remove Development Comments 2020-08-30 09:23:37 +00:00
Andy 0bbe6ec105 Issue #1620 - Use Intrinsic Aspect Ratio for Images (uplift) 2020-08-30 09:23:18 +00:00
Moonchild 48d31ea5eb Pref and disable getRootNode()
This is apparently used for fallback selection and if available it is "assumed"
Shadow DOM is also available, while this is a utility function.

Webcompat is a nightmare sometimes.
2020-08-07 21:30:12 +00:00
Matt A. Tobin 3cf0843679 Issue #1628 - Remove redundant PREF_EM_UPDATE_BACKGROUND_URL 2020-08-07 21:30:03 +00:00
Gaming4JC ff21776616 Issue #1621 - Part 4: Check whether node can be splited.
At first, HTMLEditor::GetActiveEditingHost might return null in this situation, we should check whether nullptr is returned. At second, SplitNodeDeep returns error since curent is design mode and selection node has no parent. So we should check error.

Ref: Bug 1350772
2020-08-07 21:29:45 +00:00
Gaming4JC 2f022ab1fa Issue #1621 - Part 3: Use nsIAtom to change attirbute if possible.
We can replace old nsIEditor API with nsIAtom version.

Ref: Bug 1324996
2020-08-07 21:29:36 +00:00
Gaming4JC 14e7f881be Issue #1621 - Part 2: Implement nsIAtom version of SetAttribute/RemoveAttribute/CloneAttirubte.
Add nsIAtom version of the following.
 - CloneAttribute
 - RemoveAttribute
 - RemoveAttributeOrEquivalent
 - SetAttribute
 - SetAttributeOrEquivalent

Ref: Bug 1324996
2020-08-07 21:29:27 +00:00
Gaming4JC 4f03fb2798 Issue #1621 - Part 1: CSSEditUtils should use atom for CSS property if possible.
There is a lot of string compare when using CSS property name. We should use nsGkAtoms instead.

Ref: Bug 1323138
2020-08-07 21:29:16 +00:00
Matt A. Tobin 3dd316f739 Issue #1625 - Allow MailNews Oauth2 support to be configured in confvars.sh
Baby has his bottle, you ok now?
2020-08-07 21:28:54 +00:00
Moonchild 972ab6d437 [js] Try to catch bad pointers for GC and bail if not valid. 2020-08-07 21:28:14 +00:00
Andy 83ae5bd019 Issue #1619 - Nits Picked 2020-08-07 21:28:03 +00:00
Andy c237a54f23 Issue #1619 - Add Vertical Writing Testcase
Ensures aspect ratio numerator and denominator aren't swapped in vertical writing modes.
https://bugzilla.mozilla.org/show_bug.cgi?id=1548768
2020-08-07 21:27:54 +00:00
Andy 8f72a673ca Issue #1619 - Missing Dimension Computation
This existed in Firefox before this bug.
I don't know if it came from a previous bug or was removed post-fork.
2020-08-07 21:27:40 +00:00
Andy 3266e0976f Issue #1619 - Convert Intrinsic Ratio to Float
https://bugzilla.mozilla.org/show_bug.cgi?id=1547792

Aspect Ratio handling simplified by using floating point integers:
- Multiplication of value (or inverse value) to a known side for Scaling
- No unequal equal values such as "4/3" vs "8/6" vs "20/15"
- Truly "Empty" aspect ratios, even if one dimension is not 0
2020-08-07 21:27:29 +00:00
Matt A. Tobin 4433519ae8 Add license header to media/webrtc/trunk/build/mac/find_sdk_uxp.py 2020-08-07 21:27:17 +00:00
Matt A. Tobin d419fe2d52 Use an alt script to properly determine the OSX SDK version 2020-08-07 21:27:03 +00:00
Gaming4JC c77c6de9ce Bug 1318570 - Clean up GetTextNode into TextEditRules.
EditorBase parameter of GetTextNode is unnecessary because it uses static method only. Also, we should return nsINode to reduce QI.

Resolves #1617
2020-08-07 21:26:33 +00:00
Moonchild 2ed0607c74 Merge branch 'redwood' into release 2020-07-30 09:37:13 +00:00
athenian200 922a72766c Issue #1615 - SunOS LDAP cleanup.
I meant to do this a long time ago, but basically it accounts for the new XP_SOLARIS build flag that never made it into the MailNews code. Additionally, it enables a compatibility flag for Solaris 11.4 that allows us to use the three-argument implementation of ctime_r still used by Solaris 11.3 and illumos (which also appears equivalent to the NSLDAPI_CTIME implementation used by libldap internally). Also, the ctime_r function has been added to the time.h header library for a while now, not sure why Mozilla thought we didn't have a ctime_r implementation.
2020-07-30 09:36:55 +00:00
Moonchild 16d1313104 Merge branch 'redwood' into release 2020-07-29 19:32:26 +00:00
Matt A. Tobin 0387f52bd3 Issue #1614 - Update en-US Dictionary 2020-07-29 19:32:08 +00:00
Moonchild a1ca8ca9bd Merge branch 'redwood' into release 2020-07-29 14:30:24 +00:00
Moonchild 2ee2ca7dfb Improve dll loading on Windows. 2020-07-29 14:29:33 +00:00
Michael Tuexen 0d7b7b74c6 [WebRTC] Stop putting addresses in the cookie chunk.
When using AF_CONN addresses, don't put these in the COOKIE
chunk. For these addresses it is possible to reconstruct them
locally. Conceptually, addresses are something to be shared
with the peer, but in the case of AF_CONN this might not be
the case. Therefore, zero then out.

Thanks to Natalie Silvanovich of Google Project Zero for
finding and reporting the issue.
2020-07-29 14:29:23 +00:00
Moonchild 45db2388fe [dom] Fix a spec compliance issue with the HTML LS regarding script loading.
This fixes a spec compliance issue with section 8.1.4.2 Fetching scripts.
2020-07-29 14:29:10 +00:00
Moonchild 323288bc72 [js] Don't improve TypeSets containing the magic-args type.
JIT optimizations involving the Javascript 'arguments' object could
potentially confuse later optimizations, so we simply disable these
optimizations as a DiD measure.
2020-07-29 14:28:55 +00:00
Andrea Marchesini 3323a8eda3 [xpcom] Make Base64 compatible with ReadSegments() with small buffers. 2020-07-29 14:28:45 +00:00
Jan de Mooij 71293f0fe4 [js] Fix Sink to check for non-recoverable operands. 2020-07-29 14:28:36 +00:00
Moonchild a91722be27 [network/dom] Improve sanitization of download filenames. 2020-07-29 14:28:24 +00:00
Matt A. Tobin 1ef64f9ea3 Follow up to 39be34c06 - The check sound be if not ordered
FINE! I'll go to bed already...
2020-07-28 15:51:37 +00:00
Matt A. Tobin 4a960879c8 [MailNews] Allow setting "Local Folders" as always the first displayed account 2020-07-28 15:50:20 +00:00
Matt A. Tobin 4329ae3337 [MailNews] Allow ordering of accounts to respect mail.accountmanager.accounts 2020-07-28 15:50:09 +00:00
Moonchild ad453f0b28 Issue #1391 - Remove the DOM battery API 2020-07-28 15:46:41 +00:00
Moonchild d332d4a60d Fix line endings. 2020-07-28 10:38:28 +00:00
Moonchild ad5e9449d2 Issue #1587 Part 12 (followup 2): Allow clearing of signal by setting to null. 2020-07-28 10:38:16 +00:00
Moonchild 71848c23a4 Issue #1587 Part 11 (followup 1): Implement multithreaded signals for workers. 2020-07-28 10:38:04 +00:00
Moonchild 1d321e689e [css] Enable various arbitrarily-disabled CSS features in the platform.
These should all be spec-compliant and were (for release-trickling of features)
arbitrarily disabled by Mozilla at our fork point. There's no real reason to
keep them disabled since they are used in the wild.
2020-07-23 23:17:18 +00:00
Matt A. Tobin b9b9d5bfb9 Issue #1612 - Add-ons targeting Toolkit's ID (and not Firefox's) should be considered "native" by the Add-ons Manager when using the Dual-GUID system
A version bump triggering add-on compatibility check will re-evaluate the "native" status (among other things) so no extra or special work is required to fix erroneous warnings.

tl;dr instafix!
2020-07-23 23:17:09 +00:00
Matt A. Tobin b92abc83c2 Issue #1611 - Enable WASM by default but only enable jit when 64bit 2020-07-23 23:16:56 +00:00
Gaming4JC 4950c982e0 Issue #618 - Remove eager instantiation - Debug follow up
The added debug assertion did not take into account microtask refactoring done in BZ 1405821.
Resulting in error: no member named 'IsInMicroTask' in 'nsContentUtils'.

This resolves the error.
2020-07-12 19:40:18 +00:00
209 changed files with 27356 additions and 20020 deletions

No files matched your search

-1
View File
@@ -23,4 +23,3 @@
# don't change CLOBBER for WebIDL changes any more.
Clobber for NSS update
+1
View File
@@ -310,6 +310,7 @@ def old_configure_options(*options):
'--disable-browser-statusbar',
'--disable-sync',
'--disable-personas',
'--enable-phoenix-extensions',
# Below are configure flags used by Basilisk
'--disable-webextensions',
+4
View File
@@ -65,9 +65,13 @@ if CONFIG['MOZ_DEBUG']:
# Force using malloc_usable_size when building with jemalloc because _msize
# causes assertions on Win64. See bug 719579.
# This causes a known warning due to the way mozjemalloc is linked and the
# malloc_usable_size function not being available at compile time on MSVC
# so we suppress that particular warning (C4013)
if CONFIG['OS_ARCH'] == 'WINNT' and CONFIG['MOZ_MEMORY']:
DEFINES['HAVE_MALLOC_USABLE_SIZE'] = True
DEFINES['SQLITE_WITHOUT_MSIZE'] = True
CFLAGS += ['-wd4013']
# Omit unused functions to save some library footprint.
DEFINES['SQLITE_OMIT_DEPRECATED'] = True
+20958 -15503
View File
File diff suppressed because it is too large. Load diff
+1205 -888
View File
File diff suppressed because it is too large. Load diff
+8 -1
View File
@@ -56,9 +56,16 @@ AbortSignal::Aborted() const
void
AbortSignal::Abort()
{
MOZ_ASSERT(!mAborted);
// Re-entrancy guard
if (mAborted) {
return;
}
mAborted = true;
// We might be deleted as a result of aborting a follower, so ensure we
// stay alive until all followers have been aborted.
RefPtr<AbortSignal> pinThis = this;
// Let's inform the followers.
for (uint32_t i = 0; i < mFollowers.Length(); ++i) {
mFollowers[i]->Aborted();
+1 -1
View File
@@ -14,7 +14,7 @@ EXPORTS.mozilla.dom += [
'AbortSignal.h',
]
UNIFIED_SOURCES += [
SOURCES += [
'AbortController.cpp',
'AbortSignal.cpp',
]
-43
View File
@@ -30,7 +30,6 @@
#include "nsUnicharUtils.h"
#include "mozilla/Preferences.h"
#include "mozilla/Telemetry.h"
#include "BatteryManager.h"
#ifdef MOZ_GAMEPAD
#include "mozilla/dom/GamepadServiceTest.h"
#endif
@@ -197,8 +196,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Navigator)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPermissions)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGeolocation)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNotification)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBatteryManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBatteryPromise)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPowerManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConnection)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStorageManager)
@@ -249,13 +246,6 @@ Navigator::Invalidate()
mNotification = nullptr;
}
if (mBatteryManager) {
mBatteryManager->Shutdown();
mBatteryManager = nullptr;
}
mBatteryPromise = nullptr;
if (mPowerManager) {
mPowerManager->Shutdown();
mPowerManager = nullptr;
@@ -1321,39 +1311,6 @@ Navigator::GetMozNotification(ErrorResult& aRv)
return mNotification;
}
//*****************************************************************************
// Navigator::nsINavigatorBattery
//*****************************************************************************
Promise*
Navigator::GetBattery(ErrorResult& aRv)
{
if (mBatteryPromise) {
return mBatteryPromise;
}
if (!mWindow || !mWindow->GetDocShell()) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mWindow);
RefPtr<Promise> batteryPromise = Promise::Create(go, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
mBatteryPromise = batteryPromise;
if (!mBatteryManager) {
mBatteryManager = new battery::BatteryManager(mWindow);
mBatteryManager->Init();
}
mBatteryPromise->MaybeResolve(mBatteryManager);
return mBatteryPromise;
}
PowerManager*
Navigator::GetMozPower(ErrorResult& aRv)
{
-7
View File
@@ -51,10 +51,6 @@ namespace dom {
class Permissions;
namespace battery {
class BatteryManager;
} // namespace battery
class Promise;
class DesktopNotificationCenter;
@@ -136,7 +132,6 @@ public:
Permissions* GetPermissions(ErrorResult& aRv);
// The XPCOM GetDoNotTrack is ok
Geolocation* GetGeolocation(ErrorResult& aRv);
Promise* GetBattery(ErrorResult& aRv);
static void AppName(nsAString& aAppName, bool aUsePrefOverriddenValue);
@@ -269,8 +264,6 @@ private:
RefPtr<Permissions> mPermissions;
RefPtr<Geolocation> mGeolocation;
RefPtr<DesktopNotificationCenter> mNotification;
RefPtr<battery::BatteryManager> mBatteryManager;
RefPtr<Promise> mBatteryPromise;
RefPtr<PowerManager> mPowerManager;
RefPtr<network::Connection> mConnection;
#ifdef MOZ_AUDIO_CHANNEL_MANAGER
-1
View File
@@ -416,7 +416,6 @@ EXTRA_JS_MODULES += [
]
LOCAL_INCLUDES += [
'../battery',
'../events',
'../media',
'../network',
+3 -2
View File
@@ -789,13 +789,14 @@ nsContentSink::ProcessStyleLink(nsIContent* aElement,
// If this is a fragment parser, we don't want to observe.
// We don't support CORS for processing instructions
bool isAlternate;
bool isExplicitlyEnabled;
rv = mCSSLoader->LoadStyleLink(aElement, url, aTitle, aMedia, aAlternate,
CORS_NONE, mDocument->GetReferrerPolicy(),
integrity, mRunsToCompletion ? nullptr : this,
&isAlternate);
&isAlternate, &isExplicitlyEnabled);
NS_ENSURE_SUCCESS(rv, rv);
if (!isAlternate && !mRunsToCompletion) {
if ((!isAlternate || isExplicitlyEnabled) && !mRunsToCompletion) {
++mPendingSheetCount;
mScriptLoader->AddParserBlockingScriptExecutionBlocker();
}
+8
View File
@@ -5105,6 +5105,14 @@ nsContentUtils::TriggerLink(nsIContent *aContent, nsPresContext *aPresContext,
fileName.SetIsVoid(true); // No actionable download attribute was found.
}
// Sanitize fileNames containing control characters by replacing them with
// underscores.
if (!fileName.IsVoid()) {
for (int i = 0; i < 32; i++) {
fileName.ReplaceChar(char16_t(i), '_');
}
}
handler->OnLinkClick(aContent, aLinkURI,
fileName.IsVoid() ? aTargetSpec.get() : EmptyString().get(),
fileName, nullptr, nullptr, aIsTrusted, aContent->NodePrincipal());
+13
View File
@@ -12745,3 +12745,16 @@ nsIDocument::GetSelection(ErrorResult& aRv)
return nsGlobalWindow::Cast(window)->GetSelection(aRv);
}
bool
nsIDocument::ModuleScriptsEnabled()
{
static bool sEnabledForContent = false;
static bool sCachedPref = false;
if (!sCachedPref) {
sCachedPref = true;
Preferences::AddBoolVarCache(&sEnabledForContent, "dom.moduleScripts.enabled", false);
}
return nsContentUtils::IsChromeDoc(this) || sEnabledForContent;
}
+2
View File
@@ -2872,6 +2872,8 @@ public:
virtual void ScheduleIntersectionObserverNotification() = 0;
virtual void NotifyIntersectionObservers() = 0;
bool ModuleScriptsEnabled();
protected:
bool GetUseCounter(mozilla::UseCounter aUseCounter)
{
+2 -1
View File
@@ -313,7 +313,8 @@ nsJSUtils::ModuleInstantiate(JSContext* aCx, JS::Handle<JSObject*> aModule)
MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(nsContentUtils::IsInMicroTask());
MOZ_ASSERT(CycleCollectedJSContext::Get() &&
CycleCollectedJSContext::Get()->MicroTaskLevel());
NS_ENSURE_TRUE(xpc::Scriptability::Get(aModule).Allowed(), NS_OK);
+5 -3
View File
@@ -393,8 +393,9 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
nsAutoString title, type, media;
bool isScoped;
bool isAlternate;
bool isExplicitlyEnabled;
GetStyleSheetInfo(title, type, media, &isScoped, &isAlternate);
GetStyleSheetInfo(title, type, media, &isScoped, &isAlternate, &isExplicitlyEnabled);
if (!type.LowerCaseEqualsLiteral("text/css")) {
return NS_OK;
@@ -425,7 +426,7 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
// Parse the style sheet.
rv = doc->CSSLoader()->
LoadInlineStyle(thisContent, text, mLineNumber, title, media,
scopeElement, aObserver, &doneLoading, &isAlternate);
scopeElement, aObserver, &doneLoading, &isAlternate, &isExplicitlyEnabled);
}
else {
nsAutoString integrity;
@@ -452,13 +453,14 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
rv = doc->CSSLoader()->
LoadStyleLink(thisContent, clonedURI, title, media, isAlternate,
GetCORSMode(), referrerPolicy, integrity,
aObserver, &isAlternate);
aObserver, &isAlternate, &isExplicitlyEnabled);
if (NS_FAILED(rv)) {
// Don't propagate LoadStyleLink() errors further than this, since some
// consumers (e.g. nsXMLContentSink) will completely abort on innocuous
// things like a stylesheet load being blocked by the security system.
doneLoading = true;
isAlternate = false;
isExplicitlyEnabled = false;
rv = NS_OK;
}
}
+2 -1
View File
@@ -98,7 +98,8 @@ protected:
nsAString& aType,
nsAString& aMedia,
bool* aIsScoped,
bool* aIsAlternate) = 0;
bool* aIsAlternate,
bool* aIsExplicitlyEnabled) = 0;
virtual mozilla::CORSMode GetCORSMode() const
{
-212
View File
@@ -1,212 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <cmath>
#include <limits>
#include "BatteryManager.h"
#include "Constants.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/Hal.h"
#include "mozilla/dom/BatteryManagerBinding.h"
#include "mozilla/Preferences.h"
#include "nsContentUtils.h"
#include "nsIDOMClassInfo.h"
#include "nsIDocument.h"
/**
* We have to use macros here because our leak analysis tool things we are
* leaking strings when we have |static const nsString|. Sad :(
*/
#define LEVELCHANGE_EVENT_NAME NS_LITERAL_STRING("levelchange")
#define CHARGINGCHANGE_EVENT_NAME NS_LITERAL_STRING("chargingchange")
#define DISCHARGINGTIMECHANGE_EVENT_NAME NS_LITERAL_STRING("dischargingtimechange")
#define CHARGINGTIMECHANGE_EVENT_NAME NS_LITERAL_STRING("chargingtimechange")
namespace mozilla {
namespace dom {
namespace battery {
BatteryManager::BatteryManager(nsPIDOMWindowInner* aWindow)
: DOMEventTargetHelper(aWindow)
, mLevel(kDefaultLevel)
, mCharging(kDefaultCharging)
, mRemainingTime(kDefaultRemainingTime)
{
}
void
BatteryManager::Init()
{
hal::RegisterBatteryObserver(this);
hal::BatteryInformation batteryInfo;
hal::GetCurrentBatteryInformation(&batteryInfo);
UpdateFromBatteryInfo(batteryInfo);
}
void
BatteryManager::Shutdown()
{
hal::UnregisterBatteryObserver(this);
}
JSObject*
BatteryManager::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return BatteryManagerBinding::Wrap(aCx, this, aGivenProto);
}
bool
BatteryManager::Charging() const
{
MOZ_ASSERT(NS_IsMainThread());
// For testing, unable to report the battery status information
if (Preferences::GetBool("dom.battery.test.default", false)) {
return true;
}
if (Preferences::GetBool("dom.battery.test.charging", false)) {
return true;
}
if (Preferences::GetBool("dom.battery.test.discharging", false)) {
return false;
}
return mCharging;
}
double
BatteryManager::DischargingTime() const
{
MOZ_ASSERT(NS_IsMainThread());
// For testing, unable to report the battery status information
if (Preferences::GetBool("dom.battery.test.default", false)) {
return std::numeric_limits<double>::infinity();
}
if (Preferences::GetBool("dom.battery.test.discharging", false)) {
return 42.0;
}
if (Charging() || mRemainingTime == kUnknownRemainingTime) {
return std::numeric_limits<double>::infinity();
}
return mRemainingTime;
}
double
BatteryManager::ChargingTime() const
{
MOZ_ASSERT(NS_IsMainThread());
// For testing, unable to report the battery status information
if (Preferences::GetBool("dom.battery.test.default", false)) {
return 0.0;
}
if (Preferences::GetBool("dom.battery.test.charging", false)) {
return 42.0;
}
if (!Charging() || mRemainingTime == kUnknownRemainingTime) {
return std::numeric_limits<double>::infinity();
}
return mRemainingTime;
}
double
BatteryManager::Level() const
{
MOZ_ASSERT(NS_IsMainThread());
// For testing, unable to report the battery status information
if (Preferences::GetBool("dom.battery.test.default")) {
return 1.0;
}
return mLevel;
}
void
BatteryManager::UpdateFromBatteryInfo(const hal::BatteryInformation& aBatteryInfo)
{
mLevel = aBatteryInfo.level();
// Round to the nearest ten percent for non-chrome and non-certified apps
nsIDocument* doc = GetOwner() ? GetOwner()->GetDoc() : nullptr;
uint16_t status = nsIPrincipal::APP_STATUS_NOT_INSTALLED;
if (doc) {
status = doc->NodePrincipal()->GetAppStatus();
}
mCharging = aBatteryInfo.charging();
mRemainingTime = aBatteryInfo.remainingTime();
if (!nsContentUtils::IsChromeDoc(doc) &&
status != nsIPrincipal::APP_STATUS_CERTIFIED)
{
mLevel = lround(mLevel * 10.0) / 10.0;
if (mLevel == 1.0) {
mRemainingTime = mCharging ? kDefaultRemainingTime : kUnknownRemainingTime;
} else if (mRemainingTime != kUnknownRemainingTime) {
// Round the remaining time to a multiple of 15 minutes and never zero
const double MINUTES_15 = 15.0 * 60.0;
mRemainingTime = fmax(lround(mRemainingTime / MINUTES_15) * MINUTES_15,
MINUTES_15);
}
}
// Add some guards to make sure the values are coherent.
if (mLevel == 1.0 && mCharging == true &&
mRemainingTime != kDefaultRemainingTime) {
mRemainingTime = kDefaultRemainingTime;
NS_ERROR("Battery API: When charging and level at 1.0, remaining time "
"should be 0. Please fix your backend!");
}
}
void
BatteryManager::Notify(const hal::BatteryInformation& aBatteryInfo)
{
double previousLevel = mLevel;
bool previousCharging = mCharging;
double previousRemainingTime = mRemainingTime;
UpdateFromBatteryInfo(aBatteryInfo);
if (previousCharging != mCharging) {
DispatchTrustedEvent(CHARGINGCHANGE_EVENT_NAME);
}
if (previousLevel != mLevel) {
DispatchTrustedEvent(LEVELCHANGE_EVENT_NAME);
}
/*
* There are a few situations that could happen here:
* 1. Charging state changed:
* a. Previous remaining time wasn't unkwonw, we have to fire an event for
* the change.
* b. New remaining time isn't unkwonw, we have to fire an event for it.
* 2. Charging state didn't change but remainingTime did, we have to fire
* the event that correspond to the current charging state.
*/
if (mCharging != previousCharging) {
if (previousRemainingTime != kUnknownRemainingTime) {
DispatchTrustedEvent(previousCharging ? CHARGINGTIMECHANGE_EVENT_NAME
: DISCHARGINGTIMECHANGE_EVENT_NAME);
}
if (mRemainingTime != kUnknownRemainingTime) {
DispatchTrustedEvent(mCharging ? CHARGINGTIMECHANGE_EVENT_NAME
: DISCHARGINGTIMECHANGE_EVENT_NAME);
}
} else if (previousRemainingTime != mRemainingTime) {
DispatchTrustedEvent(mCharging ? CHARGINGTIMECHANGE_EVENT_NAME
: DISCHARGINGTIMECHANGE_EVENT_NAME);
}
}
} // namespace battery
} // namespace dom
} // namespace mozilla
-84
View File
@@ -1,84 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_battery_BatteryManager_h
#define mozilla_dom_battery_BatteryManager_h
#include "Types.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/Observer.h"
#include "nsCycleCollectionParticipant.h"
namespace mozilla {
namespace hal {
class BatteryInformation;
} // namespace hal
namespace dom {
namespace battery {
class BatteryManager : public DOMEventTargetHelper
, public BatteryObserver
{
public:
explicit BatteryManager(nsPIDOMWindowInner* aWindow);
void Init();
void Shutdown();
// For IObserver.
void Notify(const hal::BatteryInformation& aBatteryInfo) override;
/**
* WebIDL Interface
*/
nsPIDOMWindowInner* GetParentObject() const
{
return GetOwner();
}
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
bool Charging() const;
double ChargingTime() const;
double DischargingTime() const;
double Level() const;
IMPL_EVENT_HANDLER(chargingchange)
IMPL_EVENT_HANDLER(chargingtimechange)
IMPL_EVENT_HANDLER(dischargingtimechange)
IMPL_EVENT_HANDLER(levelchange)
private:
/**
* Update the battery information stored in the battery manager object using
* a battery information object.
*/
void UpdateFromBatteryInfo(const hal::BatteryInformation& aBatteryInfo);
/**
* Represents the battery level, ranging from 0.0 (dead or removed?)
* to 1.0 (fully charged)
*/
double mLevel;
bool mCharging;
/**
* Represents the discharging time or the charging time, depending on the
* current battery status (charging or not).
*/
double mRemainingTime;
};
} // namespace battery
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_battery_BatteryManager_h
-27
View File
@@ -1,27 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_battery_Constants_h__
#define mozilla_dom_battery_Constants_h__
/**
* A set of constants that might need to be used by battery backends.
* It's not part of BatteryManager.h to prevent those backends to include it.
*/
namespace mozilla {
namespace dom {
namespace battery {
static const double kDefaultLevel = 1.0;
static const bool kDefaultCharging = true;
static const double kDefaultRemainingTime = 0;
static const double kUnknownRemainingTime = -1;
} // namespace battery
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_battery_Constants_h__
-23
View File
@@ -1,23 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_battery_Types_h
#define mozilla_dom_battery_Types_h
namespace mozilla {
namespace hal {
class BatteryInformation;
} // namespace hal
template <class T>
class Observer;
typedef Observer<hal::BatteryInformation> BatteryObserver;
} // namespace mozilla
#endif // mozilla_dom_battery_Types_h
-21
View File
@@ -1,21 +0,0 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXPORTS.mozilla.dom.battery += [
'Constants.h',
'Types.h',
]
SOURCES += [
'BatteryManager.cpp',
]
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'
MOCHITEST_CHROME_MANIFESTS += ['test/chrome.ini']
MOCHITEST_MANIFESTS += ['test/mochitest.ini']
-3
View File
@@ -1,3 +0,0 @@
[test_battery_basics.html]
[test_battery_charging.html]
[test_battery_discharging.html]
-1
View File
@@ -1 +0,0 @@
[test_battery_unprivileged.html]
-39
View File
@@ -1,39 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for Battery API</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
"use strict";
SimpleTest.waitForExplicitFinish();
/** Test for Battery API **/
ok("getBattery" in navigator, "navigator.getBattery should exist");
ok(!("battery" in navigator), "navigator.battery should not exist");
navigator.getBattery().then(function (battery) {
ok(battery.level >= 0.0 && battery.level <= 1.0, "Battery level " + battery.level + " should be in the range [0.0, 1.0]");
SpecialPowers.pushPrefEnv({"set": [["dom.battery.test.default", true]]}, function () {
ok(battery.charging, "Battery should be charging by default");
is(battery.chargingTime, 0, "Battery chargingTime " + battery.chargingTime + " should be zero by default");
is(battery.dischargingTime, Infinity, "Battery dischargingTime should be Infinity by default");
is(battery.level, 1.0, "Battery level " + battery.level + " should be 1.0 by default");
SimpleTest.finish();
});
});
</script>
</pre>
</body>
</html>
@@ -1,35 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for Battery API</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
"use strict";
SimpleTest.waitForExplicitFinish();
/** Test for Battery API **/
navigator.getBattery().then(function (battery) {
ok(battery.level >= 0.0 && battery.level <= 1.0, "Battery level " + battery.level + " should be in the range [0.0, 1.0]");
SpecialPowers.pushPrefEnv({"set": [["dom.battery.test.charging", true]]}, function () {
is(battery.charging, true, "Battery should be charging");
ok(battery.chargingTime >= 0, "Battery chargingTime " + battery.chargingTime + " should be nonnegative when charging");
is(battery.dischargingTime, Infinity, "Battery dischargingTime should be Infinity when charging");
SimpleTest.finish();
});
});
</script>
</pre>
</body>
</html>
@@ -1,35 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for Battery API</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
"use strict";
SimpleTest.waitForExplicitFinish();
/** Test for Battery API **/
navigator.getBattery().then(function (battery) {
ok(battery.level >= 0.0 && battery.level <= 1.0, "Battery level " + battery.level + " should be in the range [0.0, 1.0]");
SpecialPowers.pushPrefEnv({"set": [["dom.battery.test.discharging", true]]}, function () {
is(battery.charging, false, "Battery should be discharging");
is(battery.chargingTime, Infinity, "Battery chargingTime should be Infinity when discharging");
ok(battery.dischargingTime > 0, "Battery dischargingTime " + battery.dischargingTime + " should be positive when discharging");
SimpleTest.finish();
});
});
</script>
</pre>
</body>
</html>
@@ -1,24 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for Battery API</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
"use strict";
/** Test for Battery API **/
ok(!("getBattery" in navigator), "navigator.getBattery should not exist for unprivileged web content");
ok(!("battery" in navigator), "navigator.battery should not exist");
</script>
</pre>
</body>
</html>
+6 -1
View File
@@ -2487,6 +2487,12 @@ ConstructJSImplementation(const char* aContractId,
{
AutoNoJSAPI nojsapi;
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobal);
if (!window->IsCurrentInnerWindow()) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
// Get the XPCOM component containing the JS implementation.
nsresult rv;
nsCOMPtr<nsISupports> implISupports = do_CreateInstance(aContractId, &rv);
@@ -2501,7 +2507,6 @@ ConstructJSImplementation(const char* aContractId,
// and our global is a window.
nsCOMPtr<nsIDOMGlobalPropertyInitializer> gpi =
do_QueryInterface(implISupports);
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobal);
if (gpi) {
JS::Rooted<JS::Value> initReturn(RootingCx());
rv = gpi->Init(window, &initReturn);
-1
View File
@@ -64,7 +64,6 @@ LOCAL_INCLUDES += [
LOCAL_INCLUDES += [
'/dom/base',
'/dom/battery',
'/dom/canvas',
'/dom/geolocation',
'/dom/html',
+3 -3
View File
@@ -253,7 +253,7 @@ TypeUtils::ToResponse(const CacheResponse& aIn)
{
if (aIn.type() == ResponseType::Error) {
RefPtr<InternalResponse> error = InternalResponse::NetworkError();
RefPtr<Response> r = new Response(GetGlobalObject(), error);
RefPtr<Response> r = new Response(GetGlobalObject(), error, nullptr);
return r.forget();
}
@@ -302,7 +302,7 @@ TypeUtils::ToResponse(const CacheResponse& aIn)
}
MOZ_DIAGNOSTIC_ASSERT(ir);
RefPtr<Response> ref = new Response(GetGlobalObject(), ir);
RefPtr<Response> ref = new Response(GetGlobalObject(), ir, nullptr);
return ref.forget();
}
already_AddRefed<InternalRequest>
@@ -345,7 +345,7 @@ already_AddRefed<Request>
TypeUtils::ToRequest(const CacheRequest& aIn)
{
RefPtr<InternalRequest> internalRequest = ToInternalRequest(aIn);
RefPtr<Request> request = new Request(GetGlobalObject(), internalRequest);
RefPtr<Request> request = new Request(GetGlobalObject(), internalRequest, nullptr);
return request.forget();
}
+34 -11
View File
@@ -111,6 +111,12 @@ public:
return mSignalMainThread;
}
AbortSignal*
GetSignalForTargetThread()
{
return mFollowingSignal;
}
void
Shutdown()
{
@@ -161,7 +167,7 @@ public:
}
AbortSignal*
GetAbortSignal()
GetAbortSignalForMainThread()
{
MOZ_ASSERT(NS_IsMainThread());
@@ -172,6 +178,18 @@ public:
return mSignalProxy->GetOrCreateSignalForMainThread();
}
AbortSignal*
GetAbortSignalForTargetThread()
{
mPromiseProxy->GetWorkerPrivate()->AssertIsOnWorkerThread();
if (!mSignalProxy) {
return nullptr;
}
return mSignalProxy->GetSignalForTargetThread();
}
void
OnResponseAvailableInternal(InternalResponse* aResponse) override;
@@ -205,14 +223,16 @@ class MainThreadFetchResolver final : public FetchDriverObserver
RefPtr<Promise> mPromise;
RefPtr<Response> mResponse;
RefPtr<FetchObserver> mFetchObserver;
RefPtr<AbortSignal> mSignal;
nsCOMPtr<nsIDocument> mDocument;
NS_DECL_OWNINGTHREAD
public:
MainThreadFetchResolver(Promise* aPromise, FetchObserver* aObserver)
MainThreadFetchResolver(Promise* aPromise, FetchObserver* aObserver, AbortSignal* aSignal)
: mPromise(aPromise)
, mFetchObserver(aObserver)
, mSignal(aSignal)
{}
void
@@ -287,7 +307,7 @@ public:
fetch->SetWorkerScript(spec);
}
RefPtr<AbortSignal> signal = mResolver->GetAbortSignal();
RefPtr<AbortSignal> signal = mResolver->GetAbortSignalForMainThread();
// ...but release it before calling Fetch, because mResolver's callback can
// be called synchronously and they want the mutex, too.
@@ -329,10 +349,7 @@ FetchRequest(nsIGlobalObject* aGlobal, const RequestOrUSVString& aInput,
RefPtr<InternalRequest> r = request->GetInternalRequest();
RefPtr<AbortSignal> signal;
if (aInit.mSignal.WasPassed()) {
signal = &aInit.mSignal.Value();
}
RefPtr<AbortSignal> signal = request->GetSignal();
if (signal && signal->Aborted()) {
// An already aborted signal should reject immediately.
@@ -373,7 +390,7 @@ FetchRequest(nsIGlobalObject* aGlobal, const RequestOrUSVString& aInput,
}
RefPtr<MainThreadFetchResolver> resolver =
new MainThreadFetchResolver(p, observer);
new MainThreadFetchResolver(p, observer, signal);
RefPtr<FetchDriver> fetch = new FetchDriver(r, principal, loadGroup);
fetch->SetDocument(doc);
resolver->SetDocument(doc);
@@ -416,7 +433,7 @@ MainThreadFetchResolver::OnResponseAvailableInternal(InternalResponse* aResponse
}
nsCOMPtr<nsIGlobalObject> go = mPromise->GetParentObject();
mResponse = new Response(go, aResponse);
mResponse = new Response(go, aResponse, mSignal);
mPromise->MaybeResolve(mResponse);
} else {
if (mFetchObserver) {
@@ -479,7 +496,7 @@ public:
}
RefPtr<nsIGlobalObject> global = aWorkerPrivate->GlobalScope();
RefPtr<Response> response = new Response(global, mInternalResponse);
RefPtr<Response> response = new Response(global, mInternalResponse, mResolver->GetAbortSignalForTargetThread());
promise->MaybeResolve(response);
} else {
if (mResolver->mFetchObserver) {
@@ -926,6 +943,12 @@ template <class Derived>
already_AddRefed<Promise>
FetchBody<Derived>::ConsumeBody(FetchConsumeType aType, ErrorResult& aRv)
{
RefPtr<AbortSignal> signal = DerivedClass()->GetSignal();
if (signal && signal->Aborted()) {
aRv.Throw(NS_ERROR_DOM_ABORT_ERR);
return nullptr;
}
if (BodyUsed()) {
aRv.ThrowTypeError<MSG_FETCH_BODY_CONSUMED_ERROR>();
return nullptr;
@@ -935,7 +958,7 @@ FetchBody<Derived>::ConsumeBody(FetchConsumeType aType, ErrorResult& aRv)
RefPtr<Promise> promise =
FetchBodyConsumer<Derived>::Create(DerivedClass()->GetParentObject(),
this, aType, aRv);
this, signal, aType, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
+3
View File
@@ -162,6 +162,9 @@ public:
return mMimeType;
}
virtual AbortSignal*
GetSignal() const = 0;
protected:
FetchBody();
+15
View File
@@ -284,6 +284,7 @@ template <class Derived>
/* static */ already_AddRefed<Promise>
FetchBodyConsumer<Derived>::Create(nsIGlobalObject* aGlobal,
FetchBody<Derived>* aBody,
AbortSignal* aSignal,
FetchConsumeType aType,
ErrorResult& aRv)
{
@@ -345,6 +346,10 @@ FetchBodyConsumer<Derived>::Create(nsIGlobalObject* aGlobal,
return nullptr;
}
if (aSignal) {
consumer->Follow(aSignal);
}
return promise.forget();
}
@@ -368,6 +373,8 @@ FetchBodyConsumer<Derived>::ReleaseObject()
#ifdef DEBUG
mBody = nullptr;
#endif
Unfollow();
}
template <class Derived>
@@ -684,6 +691,14 @@ FetchBodyConsumer<Derived>::Observe(nsISupports* aSubject,
return NS_OK;
}
template <class Derived>
void
FetchBodyConsumer<Derived>::Aborted()
{
AssertIsOnTargetThread();
ContinueConsumeBody(NS_ERROR_DOM_ABORT_ERR, 0, nullptr);
}
template <class Derived>
NS_IMPL_ADDREF(FetchBodyConsumer<Derived>)
+6
View File
@@ -11,6 +11,7 @@
#include "nsIInputStream.h"
#include "nsIObserver.h"
#include "nsWeakReference.h"
#include "mozilla/dom/AbortSignal.h"
#include "mozilla/dom/MutableBlobStorage.h"
class nsIThread;
@@ -34,6 +35,7 @@ template <class Derived> class FetchBody;
template <class Derived>
class FetchBodyConsumer final : public nsIObserver
, public nsSupportsWeakReference
, public AbortSignal::Follower
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
@@ -42,6 +44,7 @@ public:
static already_AddRefed<Promise>
Create(nsIGlobalObject* aGlobal,
FetchBody<Derived>* aBody,
AbortSignal* aSignal,
FetchConsumeType aType,
ErrorResult& aRv);
@@ -73,6 +76,9 @@ public:
mConsumeBodyPump = nullptr;
}
// Override AbortSignal::Follower::Aborted
void Aborted() override;
private:
FetchBodyConsumer(nsIGlobalObject* aGlobalObject,
workers::WorkerPrivate* aWorkerPrivate,
+5
View File
@@ -499,6 +499,11 @@ FetchDriver::OnStartRequest(nsIRequest* aRequest,
return rv;
}
if (!mChannel) {
MOZ_ASSERT(!mObserver);
return NS_BINDING_ABORTED;
}
// We should only get to the following code once.
MOZ_ASSERT(!mPipeOutputStream);
MOZ_ASSERT(mObserver);
+30 -4
View File
@@ -37,15 +37,18 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Request)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
Request::Request(nsIGlobalObject* aOwner, InternalRequest* aRequest)
Request::Request(nsIGlobalObject* aOwner, InternalRequest* aRequest, AbortSignal* aSignal)
: FetchBody<Request>()
, mOwner(aOwner)
, mRequest(aRequest)
, mSignal(aSignal)
{
MOZ_ASSERT(aRequest->Headers()->Guard() == HeadersGuardEnum::Immutable ||
aRequest->Headers()->Guard() == HeadersGuardEnum::Request ||
aRequest->Headers()->Guard() == HeadersGuardEnum::Request_no_cors);
SetMimeType();
// aSignal can be null.
}
Request::~Request()
@@ -286,6 +289,8 @@ Request::Constructor(const GlobalObject& aGlobal,
RefPtr<InternalRequest> request;
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
RefPtr<AbortSignal> signal;
if (aInput.IsRequest()) {
RefPtr<Request> inputReq = &aInput.GetAsRequest();
@@ -300,6 +305,7 @@ Request::Constructor(const GlobalObject& aGlobal,
}
request = inputReq->GetInternalRequest();
signal = inputReq->GetOrCreateSignal();
} else {
// aInput is USVString.
// We need to get url before we create a InternalRequest.
@@ -418,6 +424,10 @@ Request::Constructor(const GlobalObject& aGlobal,
request->SetReferrerPolicy(aInit.mReferrerPolicy.Value());
}
if (aInit.mSignal.WasPassed()) {
signal = aInit.mSignal.Value();
}
if (NS_IsMainThread()) {
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(global);
if (window) {
@@ -579,7 +589,7 @@ Request::Constructor(const GlobalObject& aGlobal,
}
}
RefPtr<Request> domRequest = new Request(global, request);
RefPtr<Request> domRequest = new Request(global, request, signal);
domRequest->SetMimeType();
if (aInput.IsRequest()) {
@@ -595,7 +605,7 @@ Request::Constructor(const GlobalObject& aGlobal,
}
already_AddRefed<Request>
Request::Clone(ErrorResult& aRv) const
Request::Clone(ErrorResult& aRv)
{
if (BodyUsed()) {
aRv.ThrowTypeError<MSG_FETCH_BODY_CONSUMED_ERROR>();
@@ -608,7 +618,7 @@ Request::Clone(ErrorResult& aRv) const
return nullptr;
}
RefPtr<Request> request = new Request(mOwner, ir);
RefPtr<Request> request = new Request(mOwner, ir, GetOrCreateSignal());
return request.forget();
}
@@ -622,5 +632,21 @@ Request::Headers_()
return mHeaders;
}
AbortSignal*
Request::GetOrCreateSignal()
{
if (!mSignal) {
mSignal = new AbortSignal(false);
}
return mSignal;
}
AbortSignal*
Request::GetSignal() const
{
return mSignal;
}
} // namespace dom
} // namespace mozilla
+11 -2
View File
@@ -33,7 +33,7 @@ class Request final : public nsISupports
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Request)
public:
Request(nsIGlobalObject* aOwner, InternalRequest* aRequest);
Request(nsIGlobalObject* aOwner, InternalRequest* aRequest, AbortSignal* aSignal);
static bool
RequestContextEnabled(JSContext* aCx, JSObject* aObj);
@@ -142,7 +142,7 @@ public:
}
already_AddRefed<Request>
Clone(ErrorResult& aRv) const;
Clone(ErrorResult& aRv);
already_AddRefed<InternalRequest>
GetInternalRequest();
@@ -153,13 +153,22 @@ public:
return mRequest->GetPrincipalInfo();
}
AbortSignal*
GetOrCreateSignal();
// This can return a null AbortSignal.
AbortSignal*
GetSignal() const override;
private:
~Request();
nsCOMPtr<nsIGlobalObject> mOwner;
RefPtr<InternalRequest> mRequest;
// Lazily created.
RefPtr<Headers> mHeaders;
RefPtr<AbortSignal> mSignal;
};
} // namespace dom
+6 -5
View File
@@ -34,10 +34,11 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Response)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
Response::Response(nsIGlobalObject* aGlobal, InternalResponse* aInternalResponse)
Response::Response(nsIGlobalObject* aGlobal, InternalResponse* aInternalResponse, AbortSignal* aSignal)
: FetchBody<Response>()
, mOwner(aGlobal)
, mInternalResponse(aInternalResponse)
, mSignal(aSignal)
{
MOZ_ASSERT(aInternalResponse->Headers()->Guard() == HeadersGuardEnum::Immutable ||
aInternalResponse->Headers()->Guard() == HeadersGuardEnum::Response);
@@ -53,7 +54,7 @@ Response::Error(const GlobalObject& aGlobal)
{
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
RefPtr<InternalResponse> error = InternalResponse::NetworkError();
RefPtr<Response> r = new Response(global, error);
RefPtr<Response> r = new Response(global, error, nullptr);
return r.forget();
}
@@ -173,7 +174,7 @@ Response::Constructor(const GlobalObject& aGlobal,
internalResponse->InitChannelInfo(worker->GetChannelInfo());
}
RefPtr<Response> r = new Response(global, internalResponse);
RefPtr<Response> r = new Response(global, internalResponse, nullptr);
if (aInit.mHeaders.WasPassed()) {
internalResponse->Headers()->Clear();
@@ -236,7 +237,7 @@ Response::Clone(ErrorResult& aRv) const
}
RefPtr<InternalResponse> ir = mInternalResponse->Clone();
RefPtr<Response> response = new Response(mOwner, ir);
RefPtr<Response> response = new Response(mOwner, ir, mSignal);
return response.forget();
}
@@ -250,7 +251,7 @@ Response::CloneUnfiltered(ErrorResult& aRv) const
RefPtr<InternalResponse> clone = mInternalResponse->Clone();
RefPtr<InternalResponse> ir = clone->Unfiltered();
RefPtr<Response> ref = new Response(mOwner, ir);
RefPtr<Response> ref = new Response(mOwner, ir, mSignal);
return ref.forget();
}
+9 -1
View File
@@ -33,7 +33,7 @@ class Response final : public nsISupports
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Response)
public:
Response(nsIGlobalObject* aGlobal, InternalResponse* aInternalResponse);
Response(nsIGlobalObject* aGlobal, InternalResponse* aInternalResponse, AbortSignal* aSignal);
Response(const Response& aOther) = delete;
@@ -134,13 +134,21 @@ public:
already_AddRefed<InternalResponse>
GetInternalResponse() const;
AbortSignal*
GetSignal() const override
{
return mSignal;
}
private:
~Response();
nsCOMPtr<nsIGlobalObject> mOwner;
RefPtr<InternalResponse> mInternalResponse;
// Lazily created
RefPtr<Headers> mHeaders;
RefPtr<AbortSignal> mSignal;
};
} // namespace dom
+1 -1
View File
@@ -324,7 +324,7 @@ HTMLImageElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
nsGenericHTMLElement::MapImageAlignAttributeInto(aAttributes, aData);
nsGenericHTMLElement::MapImageBorderAttributeInto(aAttributes, aData);
nsGenericHTMLElement::MapImageMarginAttributeInto(aAttributes, aData);
nsGenericHTMLElement::MapImageSizeAttributesInto(aAttributes, aData);
nsGenericHTMLElement::MapImageSizeAttributesInto(aAttributes, aData, true);
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aData);
}
+5
View File
@@ -206,6 +206,11 @@ public:
return GetReferrerPolicyAsEnum();
}
bool IsAwaitingLoad() const
{
return !!mPendingImageLoadTask;
}
int32_t X();
int32_t Y();
// Uses XPCOM GetLowsrc.
+47 -12
View File
@@ -33,6 +33,8 @@
#define LINK_ELEMENT_FLAG_BIT(n_) \
NODE_FLAG_BIT(ELEMENT_TYPE_SPECIFIC_BITS_OFFSET + (n_))
#define LINK_DISABLED Preferences::GetBool("dom.link.disabled_attribute.enabled", true)
// Link element specific bits
enum {
// Indicates that a DNS Prefetch has been requested from this Link element.
@@ -92,9 +94,14 @@ NS_INTERFACE_TABLE_TAIL_INHERITING(nsGenericHTMLElement)
NS_IMPL_ELEMENT_CLONE(HTMLLinkElement)
bool
HTMLLinkElement::Disabled()
HTMLLinkElement::Disabled() const
{
if (LINK_DISABLED) {
return GetBoolAttr(nsGkAtoms::disabled);
}
StyleSheet* ss = GetSheet();
return ss && ss->Disabled();
}
@@ -107,8 +114,12 @@ HTMLLinkElement::GetMozDisabled(bool* aDisabled)
}
void
HTMLLinkElement::SetDisabled(bool aDisabled)
{
HTMLLinkElement::SetDisabled(bool aDisabled, ErrorResult& aRv)
{
if (LINK_DISABLED) {
return SetHTMLBoolAttr(nsGkAtoms::disabled, aDisabled, aRv);
}
if (StyleSheet* ss = GetSheet()) {
ss->SetDisabled(aDisabled);
}
@@ -117,11 +128,11 @@ HTMLLinkElement::SetDisabled(bool aDisabled)
NS_IMETHODIMP
HTMLLinkElement::SetMozDisabled(bool aDisabled)
{
SetDisabled(aDisabled);
return NS_OK;
ErrorResult rv;
SetDisabled(aDisabled, rv);
return rv.StealNSResult();
}
NS_IMPL_STRING_ATTR(HTMLLinkElement, Charset, charset)
NS_IMPL_URI_ATTR(HTMLLinkElement, Href, href)
NS_IMPL_STRING_ATTR(HTMLLinkElement, Hreflang, hreflang)
@@ -369,7 +380,8 @@ HTMLLinkElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
aName == nsGkAtoms::rel ||
aName == nsGkAtoms::title ||
aName == nsGkAtoms::media ||
aName == nsGkAtoms::type)) {
aName == nsGkAtoms::type ||
(LINK_DISABLED && aName == nsGkAtoms::disabled))) {
bool dropSheet = false;
if (aName == nsGkAtoms::rel) {
nsAutoString value;
@@ -396,17 +408,24 @@ HTMLLinkElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
dropSheet ||
(aName == nsGkAtoms::title ||
aName == nsGkAtoms::media ||
aName == nsGkAtoms::type));
aName == nsGkAtoms::type ||
(LINK_DISABLED && aName == nsGkAtoms::disabled)));
}
} else {
// Since removing href or rel makes us no longer link to a
// stylesheet, force updates for those too.
// If the disabled attribute is removed from a link element, the
// stylesheet may be explicitly enabled.
if (aNameSpaceID == kNameSpaceID_None) {
if (aName == nsGkAtoms::disabled && LINK_DISABLED) {
mExplicitlyEnabled = true;
}
// Since removing href or rel makes us no longer link to a
// stylesheet, force updates for those too.
if (aName == nsGkAtoms::href ||
aName == nsGkAtoms::rel ||
aName == nsGkAtoms::title ||
aName == nsGkAtoms::media ||
aName == nsGkAtoms::type) {
aName == nsGkAtoms::type ||
(LINK_DISABLED && aName == nsGkAtoms::disabled)) {
UpdateStyleSheetInternal(nullptr, nullptr, true);
}
if (aName == nsGkAtoms::href ||
@@ -499,13 +518,15 @@ HTMLLinkElement::GetStyleSheetInfo(nsAString& aTitle,
nsAString& aType,
nsAString& aMedia,
bool* aIsScoped,
bool* aIsAlternate)
bool* aIsAlternate,
bool* aIsExplicitlyEnabled)
{
aTitle.Truncate();
aType.Truncate();
aMedia.Truncate();
*aIsScoped = false;
*aIsAlternate = false;
*aIsExplicitlyEnabled = false;
nsAutoString rel;
GetAttr(kNameSpaceID_None, nsGkAtoms::rel, rel);
@@ -515,6 +536,20 @@ HTMLLinkElement::GetStyleSheetInfo(nsAString& aTitle,
return;
}
if (LINK_DISABLED) {
// Is the link disabled?
if (Disabled()) {
return;
}
// Is it explicitly enabled?
if (mExplicitlyEnabled) {
*aIsExplicitlyEnabled = true;
}
}
nsAutoString title;
GetAttr(kNameSpaceID_None, nsGkAtoms::title, title);
title.CompressWhitespace();
+12 -4
View File
@@ -84,8 +84,8 @@ public:
virtual bool HasDeferredDNSPrefetchRequest() override;
// WebIDL
bool Disabled();
void SetDisabled(bool aDisabled);
bool Disabled() const;
void SetDisabled(bool aDisabled, ErrorResult& aRv);
// XPCOM GetHref is fine.
void SetHref(const nsAString& aHref, ErrorResult& aRv)
{
@@ -179,10 +179,18 @@ protected:
nsAString& aType,
nsAString& aMedia,
bool* aIsScoped,
bool* aIsAlternate) override;
protected:
bool* aIsAlternate,
bool* aIsExplicitlyEnabled) override;
RefPtr<nsDOMTokenList> mRelList;
// The "explicitly enabled" flag. This flag is set whenever the 'disabled'
// attribute is explicitly unset, and makes alternate stylesheets not be
// disabled by default anymore.
//
// See https://github.com/whatwg/html/issues/3840#issuecomment-481034206.
bool mExplicitlyEnabled = false;
private:
RefPtr<ImportLoader> mImportLoader;
};
+13 -1
View File
@@ -9,6 +9,7 @@
#include "mozilla/dom/HTMLSourceElement.h"
#include "mozilla/dom/ElementInlines.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/Preferences.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/MathAlgorithms.h"
#include "mozilla/AsyncEventDispatcher.h"
@@ -1245,7 +1246,18 @@ void HTMLMediaElement::NoSupportedMediaSourceError(const nsACString& aErrorDetai
if (mDecoder) {
ShutdownDecoder();
}
mErrorSink->SetError(MEDIA_ERR_SRC_NOT_SUPPORTED, aErrorDetails);
// aErrorDetails can include sensitive details like MimeType or HTTP Status
// Code. We should not leak this and pass a Generic Error Message unless the
// user has explicitly enabled error reporting for debugging purposes.
bool reportDetails = Preferences::GetBool("media.sourceErrorDetails.enabled", false);
if (reportDetails) {
mErrorSink->SetError(MEDIA_ERR_SRC_NOT_SUPPORTED, aErrorDetails);
} else {
mErrorSink->SetError(MEDIA_ERR_SRC_NOT_SUPPORTED,
NS_LITERAL_CSTRING("Failed to open media"));
}
ChangeDelayLoadStatus(false);
UpdateAudioChannelPlayingState();
RejectPromises(TakePendingPlayPromises(), NS_ERROR_DOM_MEDIA_NOT_SUPPORTED_ERR);
+15 -8
View File
@@ -279,12 +279,20 @@ HTMLScriptElement::GetScriptCharset(nsAString& charset)
}
void
HTMLScriptElement::FreezeUriAsyncDefer()
HTMLScriptElement::FreezeExecutionAttrs(nsIDocument* aOwnerDoc)
{
if (mFrozen) {
return;
}
MOZ_ASSERT(!mIsModule && !mAsync && !mDefer && !mExternal);
// Determine whether this is a classic script or a module script.
nsAutoString type;
GetScriptType(type);
mIsModule = aOwnerDoc->ModuleScriptsEnabled() &&
!type.IsEmpty() && type.LowerCaseEqualsASCII("module");
// variation of this code in nsSVGScriptElement - check if changes
// need to be transfered when modifying. Note that we don't use GetSrc here
// because it will return the base URL when the attr value is "".
@@ -299,14 +307,13 @@ HTMLScriptElement::FreezeUriAsyncDefer()
// At this point mUri will be null for invalid URLs.
mExternal = true;
bool defer, async;
GetAsync(&async);
GetDefer(&defer);
mDefer = !async && defer;
mAsync = async;
}
bool defer, async;
GetAsync(&async);
mAsync = (mExternal || mIsModule) && async;
GetDefer(&defer);
mDefer = mExternal && !async && defer;
mFrozen = true;
}
+1 -1
View File
@@ -41,7 +41,7 @@ public:
virtual bool GetScriptType(nsAString& type) override;
virtual void GetScriptText(nsAString& text) override;
virtual void GetScriptCharset(nsAString& charset) override;
virtual void FreezeUriAsyncDefer() override;
virtual void FreezeExecutionAttrs(nsIDocument* aOwnerDoc) override;
virtual CORSMode GetCORSMode() const override;
// nsIContent
+4 -2
View File
@@ -66,7 +66,7 @@ HTMLStyleElement::GetMozDisabled(bool* aDisabled)
}
bool
HTMLStyleElement::Disabled()
HTMLStyleElement::Disabled() const
{
StyleSheet* ss = GetSheet();
return ss && ss->Disabled();
@@ -222,12 +222,14 @@ HTMLStyleElement::GetStyleSheetInfo(nsAString& aTitle,
nsAString& aType,
nsAString& aMedia,
bool* aIsScoped,
bool* aIsAlternate)
bool* aIsAlternate,
bool* aIsExplicitlyEnabled)
{
aTitle.Truncate();
aType.Truncate();
aMedia.Truncate();
*aIsAlternate = false;
*aIsExplicitlyEnabled = false;
nsAutoString title;
GetAttr(kNameSpaceID_None, nsGkAtoms::title, title);
+3 -2
View File
@@ -58,7 +58,7 @@ public:
NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
bool Disabled();
bool Disabled() const;
void SetDisabled(bool aDisabled);
void SetMedia(const nsAString& aMedia, ErrorResult& aError)
{
@@ -87,7 +87,8 @@ protected:
nsAString& aType,
nsAString& aMedia,
bool* aIsScoped,
bool* aIsAlternate) override;
bool* aIsAlternate,
bool* aIsExplicitlyEnabled) override;
/**
* Common method to call from the various mutation observer methods.
* aContent is a content node that's either the one that changed or its
+43 -15
View File
@@ -1449,29 +1449,57 @@ nsGenericHTMLElement::MapImageMarginAttributeInto(const nsMappedAttributes* aAtt
void
nsGenericHTMLElement::MapImageSizeAttributesInto(const nsMappedAttributes* aAttributes,
nsRuleData* aData)
nsRuleData* aData,
bool aMapAspectRatio)
{
if (!(aData->mSIDs & NS_STYLE_INHERIT_BIT(Position)))
return;
auto* aWidth = aAttributes->GetAttr(nsGkAtoms::width);
auto* aHeight = aAttributes->GetAttr(nsGkAtoms::height);
// width: value
nsCSSValue* width = aData->ValueForWidth();
if (width->GetUnit() == eCSSUnit_Null) {
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::width);
if (value && value->Type() == nsAttrValue::eInteger)
width->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
else if (value && value->Type() == nsAttrValue::ePercent)
width->SetPercentValue(value->GetPercentValue());
if (aWidth) {
nsCSSValue* cWidth = aData->ValueForWidth();
if (cWidth->GetUnit() == eCSSUnit_Null) {
if (aWidth->Type() == nsAttrValue::eInteger)
cWidth->SetFloatValue((float)aWidth->GetIntegerValue(), eCSSUnit_Pixel);
else if (aWidth->Type() == nsAttrValue::ePercent)
cWidth->SetPercentValue(aWidth->GetPercentValue());
}
}
// height: value
nsCSSValue* height = aData->ValueForHeight();
if (height->GetUnit() == eCSSUnit_Null) {
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::height);
if (value && value->Type() == nsAttrValue::eInteger)
height->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
else if (value && value->Type() == nsAttrValue::ePercent)
height->SetPercentValue(value->GetPercentValue());
if (aHeight) {
nsCSSValue* cHeight = aData->ValueForHeight();
if (cHeight->GetUnit() == eCSSUnit_Null) {
if (aHeight->Type() == nsAttrValue::eInteger)
cHeight->SetFloatValue((float)aHeight->GetIntegerValue(), eCSSUnit_Pixel);
else if (aHeight->Type() == nsAttrValue::ePercent)
cHeight->SetPercentValue(aHeight->GetPercentValue());
}
}
if (Preferences::GetBool("layout.css.intrinsic-aspect-ratio.enabled") &&
aMapAspectRatio && aWidth && aHeight) {
Maybe<double> w;
if (aWidth->Type() == nsAttrValue::eInteger) {
w.emplace(aWidth->GetIntegerValue());
} else if (aWidth->Type() == nsAttrValue::eDoubleValue) {
w.emplace(aWidth->GetDoubleValue());
}
Maybe<double> h;
if (aHeight->Type() == nsAttrValue::eInteger) {
h.emplace(aHeight->GetIntegerValue());
} else if (aHeight->Type() == nsAttrValue::eDoubleValue) {
h.emplace(aHeight->GetDoubleValue());
}
if (w && h && *w != 0 && *h != 0) {
nsCSSValue* aspect_ratio = aData->ValueForAspectRatio();
aspect_ratio->SetFloatValue((float(*w) / float(*h)), eCSSUnit_Number);
}
}
}
+3 -1
View File
@@ -712,10 +712,12 @@ public:
*
* @param aAttributes the list of attributes to map
* @param aData the returned rule data [INOUT]
* @param aMapAspectRatio map width and height attributes on aspect-ratio
* @see GetAttributeMappingFunction
*/
static void MapImageSizeAttributesInto(const nsMappedAttributes* aAttributes,
nsRuleData* aData);
nsRuleData* aData,
bool = false);
/**
* Helper to map the background attribute
* into a style struct.
+2 -1
View File
@@ -6,10 +6,11 @@
EXTRA_COMPONENTS += [
'InputMethod.manifest',
'Keyboard.jsm',
'MozKeyboard.js',
]
EXTRA_JS_MODULES += ['Keyboard.jsm']
JAR_MANIFESTS += ['jar.mn']
MOCHITEST_CHROME_MANIFESTS += ['mochitest/chrome.ini']
-1
View File
@@ -43,7 +43,6 @@ DIRS += [
'base',
'archivereader',
'bindings',
'battery',
'browser-element',
'cache',
'canvas',
-24
View File
@@ -432,30 +432,6 @@ QuotaManagerService::PerformIdleMaintenance()
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(NS_IsMainThread());
// If we're running on battery power then skip all idle maintenance since we
// would otherwise be doing lots of disk I/O.
BatteryInformation batteryInfo;
#ifdef MOZ_WIDGET_ANDROID
// Android XPCShell doesn't load the AndroidBridge that is needed to make
// GetCurrentBatteryInformation work...
if (!QuotaManager::IsRunningXPCShellTests())
#endif
{
GetCurrentBatteryInformation(&batteryInfo);
}
// If we're running XPCShell because we always want to be able to test this
// code so pretend that we're always charging.
if (QuotaManager::IsRunningXPCShellTests()) {
batteryInfo.level() = 100;
batteryInfo.charging() = true;
}
if (NS_WARN_IF(!batteryInfo.charging())) {
return;
}
if (QuotaManager::IsRunningXPCShellTests()) {
// We don't want user activity to impact this code if we're running tests.
Unused << Observe(nullptr, OBSERVER_TOPIC_IDLE, nullptr);
+36 -9
View File
@@ -17,26 +17,54 @@ NS_INTERFACE_MAP_END_INHERITING(ScriptLoadRequest)
NS_IMPL_CYCLE_COLLECTION_INHERITED(ModuleLoadRequest, ScriptLoadRequest,
mBaseURL,
mLoader,
mParent,
mModuleScript,
mImports)
NS_IMPL_ADDREF_INHERITED(ModuleLoadRequest, ScriptLoadRequest)
NS_IMPL_RELEASE_INHERITED(ModuleLoadRequest, ScriptLoadRequest)
ModuleLoadRequest::ModuleLoadRequest(nsIScriptElement* aElement,
ModuleLoadRequest::ModuleLoadRequest(nsIURI* aURI,
nsIScriptElement* aElement,
uint32_t aVersion,
CORSMode aCORSMode,
const SRIMetadata &aIntegrity,
nsIURI* aReferrer,
mozilla::net::ReferrerPolicy aReferrerPolicy,
ScriptLoader* aLoader)
: ScriptLoadRequest(ScriptKind::Module,
aURI,
aElement,
aVersion,
aCORSMode,
aIntegrity),
aIntegrity,
aReferrer,
aReferrerPolicy),
mIsTopLevel(true),
mLoader(aLoader)
{}
mLoader(aLoader),
mVisitedSet(new VisitedURLSet())
{
mVisitedSet->PutEntry(aURI);
}
ModuleLoadRequest::ModuleLoadRequest(nsIURI* aURI,
ModuleLoadRequest* aParent)
: ScriptLoadRequest(ScriptKind::Module,
aURI,
aParent->mElement,
aParent->mJSVersion,
aParent->mCORSMode,
SRIMetadata(),
aParent->mURI,
aParent->mReferrerPolicy),
mIsTopLevel(false),
mLoader(aParent->mLoader),
mVisitedSet(aParent->mVisitedSet)
{
MOZ_ASSERT(mVisitedSet->Contains(aURI));
mIsInline = false;
mScriptMode = aParent->mScriptMode;
}
void ModuleLoadRequest::Cancel()
{
@@ -83,7 +111,7 @@ ModuleLoadRequest::ModuleLoaded()
// been loaded.
mModuleScript = mLoader->GetFetchedModule(mURI);
if (!mModuleScript || mModuleScript->IsErrored()) {
if (!mModuleScript || mModuleScript->HasParseError()) {
ModuleErrored();
return;
}
@@ -95,7 +123,7 @@ void
ModuleLoadRequest::ModuleErrored()
{
mLoader->CheckModuleDependenciesLoaded(this);
MOZ_ASSERT(!mModuleScript || mModuleScript->IsErrored());
MOZ_ASSERT(!mModuleScript || mModuleScript->HasParseError());
CancelImports();
SetReady();
@@ -132,8 +160,7 @@ ModuleLoadRequest::LoadFinished()
{
mLoader->ProcessLoadedModuleTree(this);
mLoader = nullptr;
mParent = nullptr;
}
} // dom namespace
} // mozilla namespace
} // mozilla namespace
+26 -7
View File
@@ -8,6 +8,7 @@
#define mozilla_dom_ModuleLoadRequest_h
#include "mozilla/dom/ScriptLoader.h"
#include "nsURIHashKey.h"
#include "mozilla/MozPromise.h"
namespace mozilla {
@@ -16,6 +17,16 @@ namespace dom {
class ModuleScript;
class ScriptLoader;
// A reference counted set of URLs we have visited in the process of loading a
// module graph.
class VisitedURLSet : public nsTHashtable<nsURIHashKey>
{
NS_INLINE_DECL_REFCOUNTING(VisitedURLSet)
private:
~VisitedURLSet() = default;
};
// A load request for a module, created for every top level module script and
// every module import. Load request can share a ModuleScript if there are
// multiple imports of the same module.
@@ -31,12 +42,20 @@ public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ModuleLoadRequest, ScriptLoadRequest)
ModuleLoadRequest(nsIScriptElement* aElement,
// Create a top-level module load request.
ModuleLoadRequest(nsIURI* aURI,
nsIScriptElement* aElement,
uint32_t aVersion,
CORSMode aCORSMode,
const SRIMetadata& aIntegrity,
nsIURI* aReferrer,
mozilla::net::ReferrerPolicy,
ScriptLoader* aLoader);
// Create a module load request for an imported module.
ModuleLoadRequest(nsIURI* aURI,
ModuleLoadRequest* aParent);
bool IsTopLevel() const {
return mIsTopLevel;
}
@@ -55,7 +74,7 @@ private:
public:
// Is this a request for a top level module script or an import?
bool mIsTopLevel;
const bool mIsTopLevel;
// The base URL used for resolving relative module imports.
nsCOMPtr<nsIURI> mBaseURL;
@@ -64,10 +83,6 @@ public:
// finishes.
RefPtr<ScriptLoader> mLoader;
// The importing module, or nullptr for top level module scripts. Used to
// implement the ancestor list checked when fetching module dependencies.
RefPtr<ModuleLoadRequest> mParent;
// Set to a module script object after a successful load or nullptr on
// failure.
RefPtr<ModuleScript> mModuleScript;
@@ -79,9 +94,13 @@ public:
// Array of imported modules.
nsTArray<RefPtr<ModuleLoadRequest>> mImports;
// Set of module URLs visited while fetching the module graph this request is
// part of.
RefPtr<VisitedURLSet> mVisitedSet;
};
} // dom namespace
} // mozilla namespace
#endif // mozilla_dom_ModuleLoadRequest_h
#endif // mozilla_dom_ModuleLoadRequest_h
+17 -26
View File
@@ -26,7 +26,8 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ModuleScript)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mLoader)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mBaseURL)
tmp->UnlinkModuleRecord();
tmp->mError.setUndefined();
tmp->mParseError.setUndefined();
tmp->mErrorToRethrow.setUndefined();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ModuleScript)
@@ -35,7 +36,8 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ModuleScript)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mModuleRecord)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mError)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mParseError)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mErrorToRethrow)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(ModuleScript)
@@ -48,7 +50,8 @@ ModuleScript::ModuleScript(ScriptLoader *aLoader, nsIURI* aBaseURL)
MOZ_ASSERT(mLoader);
MOZ_ASSERT(mBaseURL);
MOZ_ASSERT(!mModuleRecord);
MOZ_ASSERT(mError.isUndefined());
MOZ_ASSERT(!HasParseError());
MOZ_ASSERT(!HasErrorToRethrow());
}
void
@@ -74,7 +77,8 @@ void
ModuleScript::SetModuleRecord(JS::Handle<JSObject*> aModuleRecord)
{
MOZ_ASSERT(!mModuleRecord);
MOZ_ASSERT(mError.isUndefined());
MOZ_ASSERT(!HasParseError());
MOZ_ASSERT(!HasErrorToRethrow());
mModuleRecord = aModuleRecord;
@@ -85,37 +89,24 @@ ModuleScript::SetModuleRecord(JS::Handle<JSObject*> aModuleRecord)
}
void
ModuleScript::SetPreInstantiationError(const JS::Value& aError)
ModuleScript::SetParseError(const JS::Value& aError)
{
MOZ_ASSERT(!aError.isUndefined());
MOZ_ASSERT(!HasParseError());
MOZ_ASSERT(!HasErrorToRethrow());
UnlinkModuleRecord();
mError = aError;
mParseError = aError;
HoldJSObjects(this);
}
bool
ModuleScript::IsErrored() const
void
ModuleScript::SetErrorToRethrow(const JS::Value& aError)
{
if (!mModuleRecord) {
MOZ_ASSERT(!mError.isUndefined());
return true;
}
MOZ_ASSERT(!aError.isUndefined());
MOZ_ASSERT(!HasErrorToRethrow());
return JS::IsModuleErrored(mModuleRecord);
}
JS::Value
ModuleScript::Error() const
{
MOZ_ASSERT(IsErrored());
if (!mModuleRecord) {
return mError;
}
return JS::GetModuleError(mModuleRecord);
mErrorToRethrow = aError;
}
} // dom namespace
+8 -4
View File
@@ -23,7 +23,8 @@ class ModuleScript final : public nsISupports
RefPtr<ScriptLoader> mLoader;
nsCOMPtr<nsIURI> mBaseURL;
JS::Heap<JSObject*> mModuleRecord;
JS::Heap<JS::Value> mError;
JS::Heap<JS::Value> mParseError;
JS::Heap<JS::Value> mErrorToRethrow;
~ModuleScript();
@@ -35,14 +36,17 @@ public:
nsIURI* aBaseURL);
void SetModuleRecord(JS::Handle<JSObject*> aModuleRecord);
void SetPreInstantiationError(const JS::Value& aError);
void SetParseError(const JS::Value& aError);
void SetErrorToRethrow(const JS::Value& aError);
ScriptLoader* Loader() const { return mLoader; }
JSObject* ModuleRecord() const { return mModuleRecord; }
nsIURI* BaseURL() const { return mBaseURL; }
bool IsErrored() const;
JS::Value Error() const;
JS::Value ParseError() const { return mParseError; }
JS::Value ErrorToRethrow() const { return mErrorToRethrow; }
bool HasParseError() const { return !mParseError.isUndefined(); }
bool HasErrorToRethrow() const { return !mErrorToRethrow.isUndefined(); }
void UnlinkModuleRecord();
};
+4 -4
View File
@@ -21,11 +21,11 @@ using namespace mozilla::dom;
NS_IMETHODIMP
ScriptElement::ScriptAvailable(nsresult aResult,
nsIScriptElement *aElement,
bool aIsInline,
bool aIsInlineClassicScript,
nsIURI *aURI,
int32_t aLineNo)
{
if (!aIsInline && NS_FAILED(aResult)) {
if (!aIsInlineClassicScript && NS_FAILED(aResult)) {
nsCOMPtr<nsIParser> parser = do_QueryReferent(mCreatorParser);
if (parser) {
parser->PushDefinedInsertionPoint();
@@ -128,11 +128,11 @@ ScriptElement::MaybeProcessScript()
return false;
}
FreezeUriAsyncDefer();
nsIDocument* ownerDoc = cont->OwnerDoc();
FreezeExecutionAttrs(ownerDoc);
mAlreadyStarted = true;
nsIDocument* ownerDoc = cont->OwnerDoc();
nsCOMPtr<nsIParser> parser = ((nsIScriptElement*) this)->GetCreatorParser();
if (parser) {
nsCOMPtr<nsIContentSink> sink = parser->GetContentSink();
File diff suppressed because it is too large. Load diff
+66 -23
View File
@@ -62,17 +62,21 @@ protected:
public:
ScriptLoadRequest(ScriptKind aKind,
nsIURI* aURI,
nsIScriptElement* aElement,
uint32_t aVersion,
mozilla::CORSMode aCORSMode,
const mozilla::dom::SRIMetadata &aIntegrity)
const SRIMetadata& aIntegrity,
nsIURI* aReferrer,
mozilla::net::ReferrerPolicy aReferrerPolicy)
: mKind(aKind),
mElement(aElement),
mProgress(Progress::Loading),
mScriptMode(ScriptMode::eBlocking),
mIsInline(true),
mHasSourceMapURL(false),
mIsDefer(false),
mIsAsync(false),
mInDeferList(false),
mInAsyncList(false),
mIsNonAsyncScriptInserted(false),
mIsXSLT(false),
mIsCanceled(false),
@@ -81,10 +85,12 @@ public:
mScriptTextBuf(nullptr),
mScriptTextLength(0),
mJSVersion(aVersion),
mURI(aURI),
mLineNo(1),
mCORSMode(aCORSMode),
mIntegrity(aIntegrity),
mReferrerPolicy(mozilla::net::RP_Default)
mReferrer(aReferrer),
mReferrerPolicy(aReferrerPolicy)
{
}
@@ -100,7 +106,8 @@ public:
void FireScriptAvailable(nsresult aResult)
{
mElement->ScriptAvailable(aResult, mElement, mIsInline, mURI, mLineNo);
bool isInlineClassicScript = mIsInline && !IsModuleRequest();
mElement->ScriptAvailable(aResult, mElement, isInlineClassicScript, mURI, mLineNo);
}
void FireScriptEvaluated(nsresult aResult)
{
@@ -143,6 +150,29 @@ public:
(IsReadyToRun() && mWasCompiledOMT);
}
enum class ScriptMode : uint8_t {
eBlocking,
eDeferred,
eAsync
};
void SetScriptMode(bool aDeferAttr, bool aAsyncAttr);
bool IsBlockingScript() const
{
return mScriptMode == ScriptMode::eBlocking;
}
bool IsDeferredScript() const
{
return mScriptMode == ScriptMode::eDeferred;
}
bool IsAsyncScript() const
{
return mScriptMode == ScriptMode::eAsync;
}
void MaybeCancelOffThreadScript();
using super::getNext;
@@ -151,10 +181,11 @@ public:
const ScriptKind mKind;
nsCOMPtr<nsIScriptElement> mElement;
Progress mProgress; // Are we still waiting for a load to complete?
ScriptMode mScriptMode; // Whether this script is blocking, deferred or async.
bool mIsInline; // Is the script inline or loaded?
bool mHasSourceMapURL; // Does the HTTP header have a source map url?
bool mIsDefer; // True if we live in mDeferRequests.
bool mIsAsync; // True if we live in mLoadingAsyncRequests or mLoadedAsyncRequests.
bool mInDeferList; // True if we live in mDeferRequests.
bool mInAsyncList; // True if we live in mLoadingAsyncRequests or mLoadedAsyncRequests.
bool mIsNonAsyncScriptInserted; // True if we live in mNonAsyncExternalScriptInsertedRequests
bool mIsXSLT; // True if we live in mXSLTRequests.
bool mIsCanceled; // True if we have been explicitly canceled.
@@ -164,13 +195,14 @@ public:
char16_t* mScriptTextBuf; // Holds script text for non-inline scripts. Don't
size_t mScriptTextLength; // use nsString so we can give ownership to jsapi.
uint32_t mJSVersion;
nsCOMPtr<nsIURI> mURI;
const nsCOMPtr<nsIURI> mURI;
nsCOMPtr<nsIPrincipal> mOriginPrincipal;
nsAutoCString mURL; // Keep the URI's filename alive during off thread parsing.
int32_t mLineNo;
const mozilla::CORSMode mCORSMode;
const mozilla::dom::SRIMetadata mIntegrity;
mozilla::net::ReferrerPolicy mReferrerPolicy;
const SRIMetadata mIntegrity;
const nsCOMPtr<nsIURI> mReferrer;
const mozilla::net::ReferrerPolicy mReferrerPolicy;
};
class ScriptLoadRequestList : private mozilla::LinkedList<ScriptLoadRequest>
@@ -452,6 +484,8 @@ public:
const nsAString &aCrossOrigin,
const nsAString& aIntegrity,
bool aScriptFromHead,
bool aAsync,
bool aDefer,
const mozilla::net::ReferrerPolicy aReferrerPolicy);
/**
@@ -467,12 +501,13 @@ public:
private:
virtual ~ScriptLoader();
ScriptLoadRequest* CreateLoadRequest(
ScriptKind aKind,
nsIScriptElement* aElement,
uint32_t aVersion,
mozilla::CORSMode aCORSMode,
const mozilla::dom::SRIMetadata &aIntegrity);
ScriptLoadRequest* CreateLoadRequest(ScriptKind aKind,
nsIURI* aURI,
nsIScriptElement* aElement,
uint32_t aVersion,
mozilla::CORSMode aCORSMode,
const SRIMetadata& aIntegrity,
mozilla::net::ReferrerPolicy aReferrerPolicy);
/**
* Unblocks the creator parser of the parser-blocking scripts.
@@ -500,6 +535,8 @@ private:
nsresult StartLoad(ScriptLoadRequest *aRequest, const nsAString &aType,
bool aScriptFromHead);
void HandleLoadError(ScriptLoadRequest *aRequest, nsresult aResult);
/**
* Process any pending requests asynchronously (i.e. off an event) if there
* are any. Note that this is a no-op if there aren't any currently pending
@@ -534,6 +571,11 @@ private:
return mEnabled && !mBlockerCount;
}
nsresult VerifySRI(ScriptLoadRequest *aRequest,
nsIIncrementalStreamLoader* aLoader,
nsresult aSRIStatus,
SRICheckDataVerifier* aSRIDataVerifier) const;
nsresult AttemptAsyncScriptCompile(ScriptLoadRequest* aRequest);
nsresult ProcessRequest(ScriptLoadRequest* aRequest);
nsresult CompileOffThreadOrProcessRequest(ScriptLoadRequest* aRequest);
@@ -556,6 +598,7 @@ private:
mozilla::Vector<char16_t> &aString);
void AddDeferRequest(ScriptLoadRequest* aRequest);
void AddAsyncRequest(ScriptLoadRequest* aRequest);
bool MaybeRemovedDeferRequests();
void MaybeMoveToLoadedList(ScriptLoadRequest* aRequest);
@@ -563,30 +606,30 @@ private:
JS::SourceBufferHolder GetScriptSource(ScriptLoadRequest* aRequest,
nsAutoString& inlineData);
bool ModuleScriptsEnabled();
void SetModuleFetchStarted(ModuleLoadRequest *aRequest);
void SetModuleFetchFinishedAndResumeWaitingRequests(ModuleLoadRequest *aRequest,
nsresult aResult);
bool IsFetchingModule(ModuleLoadRequest *aRequest) const;
bool ModuleMapContainsModule(ModuleLoadRequest *aRequest) const;
RefPtr<mozilla::GenericPromise> WaitForModuleFetch(ModuleLoadRequest *aRequest);
bool ModuleMapContainsURL(nsIURI* aURL) const;
RefPtr<mozilla::GenericPromise> WaitForModuleFetch(nsIURI* aURL);
ModuleScript* GetFetchedModule(nsIURI* aURL) const;
friend bool
HostResolveImportedModule(JSContext* aCx, unsigned argc, JS::Value* vp);
friend JSObject*
HostResolveImportedModule(JSContext* aCx, JS::Handle<JSObject*> aModule,
JS::Handle<JSString*> aSpecifier);
nsresult CreateModuleScript(ModuleLoadRequest* aRequest);
nsresult ProcessFetchedModuleSource(ModuleLoadRequest* aRequest);
void CheckModuleDependenciesLoaded(ModuleLoadRequest* aRequest);
void ProcessLoadedModuleTree(ModuleLoadRequest* aRequest);
JS::Value FindFirstParseError(ModuleLoadRequest* aRequest);
bool InstantiateModuleTree(ModuleLoadRequest* aRequest);
void StartFetchingModuleDependencies(ModuleLoadRequest* aRequest);
RefPtr<mozilla::GenericPromise>
StartFetchingModuleAndDependencies(ModuleLoadRequest* aRequest, nsIURI* aURI);
StartFetchingModuleAndDependencies(ModuleLoadRequest* aParent, nsIURI* aURI);
nsIDocument* mDocument; // [WEAK]
nsCOMArray<nsIScriptLoaderObserver> mObservers;
+25 -4
View File
@@ -13,6 +13,7 @@
#include "nsIScriptLoaderObserver.h"
#include "nsWeakPtr.h"
#include "nsIParser.h"
#include "nsIDocument.h"
#include "nsContentCreatorFunctions.h"
#include "nsIDOMHTMLScriptElement.h"
#include "mozilla/CORSMode.h"
@@ -37,6 +38,7 @@ public:
mForceAsync(aFromParser == mozilla::dom::NOT_FROM_PARSER ||
aFromParser == mozilla::dom::FROM_PARSER_FRAGMENT),
mFrozen(false),
mIsModule(false),
mDefer(false),
mAsync(false),
mExternal(false),
@@ -73,11 +75,25 @@ public:
virtual void GetScriptCharset(nsAString& charset) = 0;
/**
* Freezes the return values of GetScriptDeferred(), GetScriptAsync() and
* GetScriptURI() so that subsequent modifications to the attributes don't
* change execution behavior.
* Freezes the return values of the following methods so that subsequent
* modifications to the attributes don't change execution behavior:
* - GetScriptIsModule()
* - GetScriptDeferred()
* - GetScriptAsync()
* - GetScriptURI()
* - GetScriptExternal()
*/
virtual void FreezeUriAsyncDefer() = 0;
virtual void FreezeExecutionAttrs(nsIDocument* aOwnerDoc) = 0;
/**
* Is the script a module script?
* Currently only supported by HTML scripts.
*/
bool GetScriptIsModule()
{
NS_PRECONDITION(mFrozen, "Execution attributes not yet frozen: Not ready for this call!");
return mIsModule;
}
/**
* Is the script deferred. Currently only supported by HTML scripts.
@@ -292,6 +308,11 @@ protected:
*/
bool mFrozen;
/**
* The effective moduleness.
*/
bool mIsModule;
/**
* The effective deferredness.
*/
+5 -4
View File
@@ -20,15 +20,16 @@ interface nsIScriptLoaderObserver : nsISupports {
* a script. If this is a failure code, script evaluation
* will not occur.
* @param aElement The element being processed.
* @param aIsInline Is this an inline script or externally loaded?
* @param aIsInline Is this an inline classic script (as opposed to an
* externally loaded classic script or module script)?
* @param aURI What is the URI of the script (the document URI if
* it is inline).
* @param aLineNo At what line does the script appear (generally 1
* if it is a loaded script).
*/
void scriptAvailable(in nsresult aResult,
void scriptAvailable(in nsresult aResult,
in nsIScriptElement aElement,
in boolean aIsInline,
in boolean aIsInlineClassicScript,
in nsIURI aURI,
in int32_t aLineNo);
@@ -40,7 +41,7 @@ interface nsIScriptLoaderObserver : nsISupports {
* @param aElement The element being processed.
* @param aIsInline Is this an inline script or externally loaded?
*/
void scriptEvaluated(in nsresult aResult,
void scriptEvaluated(in nsresult aResult,
in nsIScriptElement aElement,
in boolean aIsInline);
+1 -1
View File
@@ -137,7 +137,7 @@ SVGScriptElement::GetScriptCharset(nsAString& charset)
}
void
SVGScriptElement::FreezeUriAsyncDefer()
SVGScriptElement::FreezeExecutionAttrs(nsIDocument* aOwnerDoc)
{
if (mFrozen) {
return;
+1 -1
View File
@@ -44,7 +44,7 @@ public:
virtual bool GetScriptType(nsAString& type) override;
virtual void GetScriptText(nsAString& text) override;
virtual void GetScriptCharset(nsAString& charset) override;
virtual void FreezeUriAsyncDefer() override;
virtual void FreezeExecutionAttrs(nsIDocument* aOwnerDoc) override;
virtual CORSMode GetCORSMode() const override;
// ScriptElement
+3 -1
View File
@@ -271,9 +271,11 @@ SVGStyleElement::GetStyleSheetInfo(nsAString& aTitle,
nsAString& aType,
nsAString& aMedia,
bool* aIsScoped,
bool* aIsAlternate)
bool* aIsAlternate,
bool* aIsExplicitlyEnabled)
{
*aIsAlternate = false;
*aIsExplicitlyEnabled = false;
nsAutoString title;
GetAttr(kNameSpaceID_None, nsGkAtoms::title, title);
+2 -1
View File
@@ -95,7 +95,8 @@ protected:
nsAString& aType,
nsAString& aMedia,
bool* aIsScoped,
bool* aIsAlternate) override;
bool* aIsAlternate,
bool* aIsExplicitlyEnabled) override;
virtual CORSMode GetCORSMode() const override;
/**
-23
View File
@@ -1,23 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* http://www.w3.org/TR/battery-status/
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
interface BatteryManager : EventTarget {
readonly attribute boolean charging;
readonly attribute unrestricted double chargingTime;
readonly attribute unrestricted double dischargingTime;
readonly attribute double level;
attribute EventHandler onchargingchange;
attribute EventHandler onchargingtimechange;
attribute EventHandler ondischargingtimechange;
attribute EventHandler onlevelchange;
};
+1 -1
View File
@@ -13,7 +13,7 @@
// http://www.whatwg.org/specs/web-apps/current-work/#the-link-element
interface HTMLLinkElement : HTMLElement {
[Pure]
[SetterThrows, Pure]
attribute boolean disabled;
[SetterThrows, Pure]
attribute DOMString href;
-8
View File
@@ -7,7 +7,6 @@
* http://www.whatwg.org/specs/web-apps/current-work/#the-navigator-object
* http://www.w3.org/TR/tracking-dnt/
* http://www.w3.org/TR/geolocation-API/#geolocation_interface
* http://www.w3.org/TR/battery-status/#navigatorbattery-interface
* http://www.w3.org/TR/vibration/#vibration-interface
* http://www.w3.org/2012/sysapps/runtime/#extension-to-the-navigator-interface-1
* https://dvcs.w3.org/hg/gamepad/raw-file/default/gamepad.html#navigator-interface-extension
@@ -125,13 +124,6 @@ interface NavigatorGeolocation {
};
Navigator implements NavigatorGeolocation;
// http://www.w3.org/TR/battery-status/#navigatorbattery-interface
partial interface Navigator {
// ChromeOnly to prevent web content from fingerprinting users' batteries.
[Throws, ChromeOnly, Pref="dom.battery.enabled"]
Promise<BatteryManager> getBattery();
};
// http://www.w3.org/TR/vibration/#vibration-interface
partial interface Navigator {
// We don't support sequences in unions yet
+1 -1
View File
@@ -38,7 +38,7 @@ interface Node : EventTarget {
readonly attribute boolean isConnected;
[Pure]
readonly attribute Document? ownerDocument;
[Pure]
[Pure, Pref="dom.getRootNode.enabled"]
Node getRootNode(optional GetRootNodeOptions options);
[Pure]
readonly attribute Node? parentNode;
+5 -1
View File
@@ -27,6 +27,10 @@ interface Request {
readonly attribute RequestRedirect redirect;
readonly attribute DOMString integrity;
[Func="AbortController::IsEnabled",
BinaryName="getOrCreateSignal"]
readonly attribute AbortSignal signal;
[Throws,
NewObject] Request clone();
@@ -49,7 +53,7 @@ dictionary RequestInit {
DOMString integrity;
[Func="AbortController::IsEnabled"]
AbortSignal signal;
AbortSignal? signal;
[Func="FetchObserver::IsEnabled"]
ObserverCallback observe;
-1
View File
@@ -50,7 +50,6 @@ WEBIDL_FILES = [
'AutocompleteInfo.webidl',
'BarProp.webidl',
'BaseKeyframeTypes.webidl',
'BatteryManager.webidl',
'BeforeAfterKeyboardEvent.webidl',
'BeforeUnloadEvent.webidl',
'BiquadFilterNode.webidl',
+10 -8
View File
@@ -694,7 +694,7 @@ private:
ir->SetPrincipalInfo(Move(principalInfo));
RefPtr<mozilla::dom::Response> response =
new mozilla::dom::Response(mCacheCreator->Global(), ir);
new mozilla::dom::Response(mCacheCreator->Global(), ir, nullptr);
mozilla::dom::RequestOrUSVString request;
@@ -1101,14 +1101,16 @@ private:
rv = NS_GetFinalChannelURI(channel, getter_AddRefs(finalURI));
NS_ENSURE_SUCCESS(rv, rv);
nsCString filename;
rv = finalURI->GetSpec(filename);
NS_ENSURE_SUCCESS(rv, rv);
if (principal->Subsumes(channelPrincipal)) {
nsCString filename;
rv = finalURI->GetSpec(filename);
NS_ENSURE_SUCCESS(rv, rv);
if (!filename.IsEmpty()) {
// This will help callers figure out what their script url resolved to in
// case of errors.
aLoadInfo.mURL.Assign(NS_ConvertUTF8toUTF16(filename));
if (!filename.IsEmpty()) {
// This will help callers figure out what their script url resolved to in
// case of errors.
aLoadInfo.mURL.Assign(NS_ConvertUTF8toUTF16(filename));
}
}
nsCOMPtr<nsILoadInfo> chanLoadInfo = channel->GetLoadInfo();
+1 -1
View File
@@ -1510,7 +1510,7 @@ private:
if (NS_WARN_IF(!global)) {
return false;
}
RefPtr<Request> request = new Request(global, internalReq);
RefPtr<Request> request = new Request(global, internalReq, nullptr);
MOZ_ASSERT_IF(internalReq->IsNavigationRequest(),
request->Redirect() == RequestRedirect::Manual);
+1 -1
View File
@@ -554,7 +554,7 @@ private:
ir->SetPrincipalInfo(Move(mPrincipalInfo));
}
RefPtr<Response> response = new Response(aCache->GetGlobalObject(), ir);
RefPtr<Response> response = new Response(aCache->GetGlobalObject(), ir, nullptr);
RequestOrUSVString request;
request.SetAsUSVString().Rebind(URL().Data(), URL().Length());
@@ -131,13 +131,15 @@ XMLStylesheetProcessingInstruction::GetStyleSheetInfo(nsAString& aTitle,
nsAString& aType,
nsAString& aMedia,
bool* aIsScoped,
bool* aIsAlternate)
bool* aIsAlternate,
bool* aIsExplicitlyEnabled)
{
aTitle.Truncate();
aType.Truncate();
aMedia.Truncate();
*aIsScoped = false;
*aIsAlternate = false;
*aIsExplicitlyEnabled = false;
// xml-stylesheet PI is special only in prolog
if (!nsContentUtils::InProlog(this)) {
+2 -1
View File
@@ -82,7 +82,8 @@ protected:
nsAString& aType,
nsAString& aMedia,
bool* aIsScoped,
bool* aIsAlternate) override;
bool* aIsAlternate,
bool* aIsExplicitlyEnabled) override;
virtual nsGenericDOMDataNode* CloneDataNode(mozilla::dom::NodeInfo *aNodeInfo,
bool aCloneText) const override;
};
+1 -1
View File
@@ -955,7 +955,7 @@ NS_IMPL_ISUPPORTS(txTransformNotifier,
NS_IMETHODIMP
txTransformNotifier::ScriptAvailable(nsresult aResult,
nsIScriptElement *aElement,
bool aIsInline,
bool aIsInlineClassicScript,
nsIURI *aURI,
int32_t aLineNo)
{
+139 -120
View File
@@ -319,6 +319,15 @@ bool
CSSEditUtils::IsCSSEditableProperty(nsINode* aNode,
nsIAtom* aProperty,
const nsAString* aAttribute)
{
nsCOMPtr<nsIAtom> attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
return IsCSSEditableProperty(aNode, aProperty, attribute);
}
bool
CSSEditUtils::IsCSSEditableProperty(nsINode* aNode,
nsIAtom* aProperty,
nsIAtom* aAttribute)
{
MOZ_ASSERT(aNode);
@@ -336,13 +345,12 @@ CSSEditUtils::IsCSSEditableProperty(nsINode* aNode,
nsGkAtoms::u == aProperty ||
nsGkAtoms::strike == aProperty ||
(nsGkAtoms::font == aProperty && aAttribute &&
(aAttribute->EqualsLiteral("color") ||
aAttribute->EqualsLiteral("face")))) {
(aAttribute == nsGkAtoms::color || aAttribute == nsGkAtoms::face))) {
return true;
}
// ALIGN attribute on elements supporting it
if (aAttribute && (aAttribute->EqualsLiteral("align")) &&
if (aAttribute == nsGkAtoms::align &&
node->IsAnyOfHTMLElements(nsGkAtoms::div,
nsGkAtoms::p,
nsGkAtoms::h1,
@@ -365,7 +373,7 @@ CSSEditUtils::IsCSSEditableProperty(nsINode* aNode,
return true;
}
if (aAttribute && (aAttribute->EqualsLiteral("valign")) &&
if (aAttribute == nsGkAtoms::valign &&
node->IsAnyOfHTMLElements(nsGkAtoms::col,
nsGkAtoms::colgroup,
nsGkAtoms::tbody,
@@ -378,59 +386,52 @@ CSSEditUtils::IsCSSEditableProperty(nsINode* aNode,
}
// attributes TEXT, BACKGROUND and BGCOLOR on BODY
if (aAttribute && node->IsHTMLElement(nsGkAtoms::body) &&
(aAttribute->EqualsLiteral("text")
|| aAttribute->EqualsLiteral("background")
|| aAttribute->EqualsLiteral("bgcolor"))) {
if (node->IsHTMLElement(nsGkAtoms::body) &&
(aAttribute == nsGkAtoms::text || aAttribute == nsGkAtoms::background ||
aAttribute == nsGkAtoms::bgcolor)) {
return true;
}
// attribute BGCOLOR on other elements
if (aAttribute && aAttribute->EqualsLiteral("bgcolor")) {
if (aAttribute == nsGkAtoms::bgcolor) {
return true;
}
// attributes HEIGHT, WIDTH and NOWRAP on TD and TH
if (aAttribute &&
node->IsAnyOfHTMLElements(nsGkAtoms::td, nsGkAtoms::th) &&
(aAttribute->EqualsLiteral("height")
|| aAttribute->EqualsLiteral("width")
|| aAttribute->EqualsLiteral("nowrap"))) {
if (node->IsAnyOfHTMLElements(nsGkAtoms::td, nsGkAtoms::th) &&
(aAttribute == nsGkAtoms::height || aAttribute == nsGkAtoms::width ||
aAttribute == nsGkAtoms::nowrap)) {
return true;
}
// attributes HEIGHT and WIDTH on TABLE
if (aAttribute && node->IsHTMLElement(nsGkAtoms::table) &&
(aAttribute->EqualsLiteral("height")
|| aAttribute->EqualsLiteral("width"))) {
if (node->IsHTMLElement(nsGkAtoms::table) &&
(aAttribute == nsGkAtoms::height || aAttribute == nsGkAtoms::width)) {
return true;
}
// attributes SIZE and WIDTH on HR
if (aAttribute && node->IsHTMLElement(nsGkAtoms::hr) &&
(aAttribute->EqualsLiteral("size")
|| aAttribute->EqualsLiteral("width"))) {
if (node->IsHTMLElement(nsGkAtoms::hr) &&
(aAttribute == nsGkAtoms::size || aAttribute == nsGkAtoms::width)) {
return true;
}
// attribute TYPE on OL UL LI
if (aAttribute &&
node->IsAnyOfHTMLElements(nsGkAtoms::ol, nsGkAtoms::ul,
if (node->IsAnyOfHTMLElements(nsGkAtoms::ol, nsGkAtoms::ul,
nsGkAtoms::li) &&
aAttribute->EqualsLiteral("type")) {
aAttribute == nsGkAtoms::type) {
return true;
}
if (aAttribute && node->IsHTMLElement(nsGkAtoms::img) &&
(aAttribute->EqualsLiteral("border")
|| aAttribute->EqualsLiteral("width")
|| aAttribute->EqualsLiteral("height"))) {
if (node->IsHTMLElement(nsGkAtoms::img) &&
(aAttribute == nsGkAtoms::border || aAttribute == nsGkAtoms::width ||
aAttribute == nsGkAtoms::height)) {
return true;
}
// other elements that we can align using CSS even if they
// can't carry the html ALIGN attribute
if (aAttribute && aAttribute->EqualsLiteral("align") &&
if (aAttribute == nsGkAtoms::align &&
node->IsAnyOfHTMLElements(nsGkAtoms::ul,
nsGkAtoms::ol,
nsGkAtoms::dl,
@@ -815,7 +816,7 @@ void
CSSEditUtils::GenerateCSSDeclarationsFromHTMLStyle(
Element* aElement,
nsIAtom* aHTMLProperty,
const nsAString* aAttribute,
nsIAtom* aAttribute,
const nsAString* aValue,
nsTArray<nsIAtom*>& cssPropertyArray,
nsTArray<nsString>& cssValueArray,
@@ -835,21 +836,20 @@ CSSEditUtils::GenerateCSSDeclarationsFromHTMLStyle(
} else if (nsGkAtoms::tt == aHTMLProperty) {
equivTable = ttEquivTable;
} else if (aAttribute) {
if (nsGkAtoms::font == aHTMLProperty &&
aAttribute->EqualsLiteral("color")) {
if (nsGkAtoms::font == aHTMLProperty && aAttribute == nsGkAtoms::color) {
equivTable = fontColorEquivTable;
} else if (nsGkAtoms::font == aHTMLProperty &&
aAttribute->EqualsLiteral("face")) {
aAttribute == nsGkAtoms::face) {
equivTable = fontFaceEquivTable;
} else if (aAttribute->EqualsLiteral("bgcolor")) {
} else if (aAttribute == nsGkAtoms::bgcolor) {
equivTable = bgcolorEquivTable;
} else if (aAttribute->EqualsLiteral("background")) {
} else if (aAttribute == nsGkAtoms::background) {
equivTable = backgroundImageEquivTable;
} else if (aAttribute->EqualsLiteral("text")) {
} else if (aAttribute == nsGkAtoms::text) {
equivTable = textColorEquivTable;
} else if (aAttribute->EqualsLiteral("border")) {
} else if (aAttribute == nsGkAtoms::border) {
equivTable = borderEquivTable;
} else if (aAttribute->EqualsLiteral("align")) {
} else if (aAttribute == nsGkAtoms::align) {
if (aElement->IsHTMLElement(nsGkAtoms::table)) {
equivTable = tableAlignEquivTable;
} else if (aElement->IsHTMLElement(nsGkAtoms::hr)) {
@@ -860,17 +860,17 @@ CSSEditUtils::GenerateCSSDeclarationsFromHTMLStyle(
} else {
equivTable = textAlignEquivTable;
}
} else if (aAttribute->EqualsLiteral("valign")) {
} else if (aAttribute == nsGkAtoms::valign) {
equivTable = verticalAlignEquivTable;
} else if (aAttribute->EqualsLiteral("nowrap")) {
} else if (aAttribute == nsGkAtoms::nowrap) {
equivTable = nowrapEquivTable;
} else if (aAttribute->EqualsLiteral("width")) {
} else if (aAttribute == nsGkAtoms::width) {
equivTable = widthEquivTable;
} else if (aAttribute->EqualsLiteral("height") ||
} else if (aAttribute == nsGkAtoms::height ||
(aElement->IsHTMLElement(nsGkAtoms::hr) &&
aAttribute->EqualsLiteral("size"))) {
aAttribute == nsGkAtoms::size)) {
equivTable = heightEquivTable;
} else if (aAttribute->EqualsLiteral("type") &&
} else if (aAttribute == nsGkAtoms::type &&
aElement->IsAnyOfHTMLElements(nsGkAtoms::ol,
nsGkAtoms::ul,
nsGkAtoms::li)) {
@@ -887,40 +887,46 @@ CSSEditUtils::GenerateCSSDeclarationsFromHTMLStyle(
// aValue for the node, and return in aCount the number of CSS properties set
// by the call. The Element version returns aCount instead.
int32_t
CSSEditUtils::SetCSSEquivalentToHTMLStyle(Element* aElement,
CSSEditUtils::SetCSSEquivalentToHTMLStyle(nsIDOMNode* aNode,
nsIAtom* aProperty,
const nsAString* aAttribute,
const nsAString* aValue,
bool aSuppressTransaction)
{
MOZ_ASSERT(aElement && aProperty);
MOZ_ASSERT_IF(aAttribute, aValue);
int32_t count;
// This can only fail if SetCSSProperty fails, which should only happen if
// something is pretty badly wrong. In this case we assert so that hopefully
// someone will notice, but there's nothing more sensible to do than just
// return the count and carry on.
nsresult rv = SetCSSEquivalentToHTMLStyle(aElement->AsDOMNode(),
aProperty, aAttribute,
aValue, &count,
aSuppressTransaction);
NS_ASSERTION(NS_SUCCEEDED(rv), "SetCSSEquivalentToHTMLStyle failed");
NS_ENSURE_SUCCESS(rv, count);
return count;
nsCOMPtr<Element> element = do_QueryInterface(aNode);
return SetCSSEquivalentToHTMLStyle(element,
aProperty, aAttribute,
aValue, aSuppressTransaction);
}
nsresult
CSSEditUtils::SetCSSEquivalentToHTMLStyle(nsIDOMNode* aNode,
int32_t
CSSEditUtils::SetCSSEquivalentToHTMLStyle(Element* aElement,
nsIAtom* aHTMLProperty,
const nsAString* aAttribute,
const nsAString* aValue,
int32_t* aCount,
bool aSuppressTransaction)
{
nsCOMPtr<Element> element = do_QueryInterface(aNode);
*aCount = 0;
if (!element || !IsCSSEditableProperty(element, aHTMLProperty, aAttribute)) {
return NS_OK;
nsCOMPtr<nsIAtom> attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
return SetCSSEquivalentToHTMLStyle(aElement, aHTMLProperty, attribute,
aValue, aSuppressTransaction);
}
int32_t
CSSEditUtils::SetCSSEquivalentToHTMLStyle(Element* aElement,
nsIAtom* aHTMLProperty,
nsIAtom* aAttribute,
const nsAString* aValue,
bool aSuppressTransaction)
{
MOZ_ASSERT(aElement);
if (!IsCSSEditableProperty(aElement, aHTMLProperty, aAttribute)) {
return 0;
}
// we can apply the styles only if the node is an element and if we have
@@ -929,18 +935,20 @@ CSSEditUtils::SetCSSEquivalentToHTMLStyle(nsIDOMNode* aNode,
// Find the CSS equivalence to the HTML style
nsTArray<nsIAtom*> cssPropertyArray;
nsTArray<nsString> cssValueArray;
GenerateCSSDeclarationsFromHTMLStyle(element, aHTMLProperty, aAttribute,
GenerateCSSDeclarationsFromHTMLStyle(aElement, aHTMLProperty, aAttribute,
aValue, cssPropertyArray, cssValueArray,
false);
// set the individual CSS inline styles
*aCount = cssPropertyArray.Length();
for (int32_t index = 0; index < *aCount; index++) {
nsresult rv = SetCSSProperty(*element, *cssPropertyArray[index],
size_t count = cssPropertyArray.Length();
for (size_t index = 0; index < count; index++) {
nsresult rv = SetCSSProperty(*aElement, *cssPropertyArray[index],
cssValueArray[index], aSuppressTransaction);
NS_ENSURE_SUCCESS(rv, rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
return 0;
}
}
return NS_OK;
return count;
}
// Remove from aNode the CSS inline style equivalent to HTMLProperty/aAttribute/aValue for the node
@@ -952,20 +960,22 @@ CSSEditUtils::RemoveCSSEquivalentToHTMLStyle(nsIDOMNode* aNode,
bool aSuppressTransaction)
{
nsCOMPtr<Element> element = do_QueryInterface(aNode);
NS_ENSURE_TRUE(element, NS_OK);
nsCOMPtr<nsIAtom> attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
return RemoveCSSEquivalentToHTMLStyle(element, aHTMLProperty, aAttribute,
return RemoveCSSEquivalentToHTMLStyle(element, aHTMLProperty, attribute,
aValue, aSuppressTransaction);
}
nsresult
CSSEditUtils::RemoveCSSEquivalentToHTMLStyle(Element* aElement,
nsIAtom* aHTMLProperty,
const nsAString* aAttribute,
nsIAtom* aAttribute,
const nsAString* aValue,
bool aSuppressTransaction)
{
MOZ_ASSERT(aElement);
if (NS_WARN_IF(!aElement)) {
return NS_OK;
}
if (!IsCSSEditableProperty(aElement, aHTMLProperty, aAttribute)) {
return NS_OK;
@@ -1000,7 +1010,7 @@ CSSEditUtils::RemoveCSSEquivalentToHTMLStyle(Element* aElement,
nsresult
CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode,
nsIAtom* aHTMLProperty,
const nsAString* aAttribute,
nsIAtom* aAttribute,
nsAString& aValueString,
StyleType aStyleType)
{
@@ -1017,7 +1027,8 @@ CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode,
nsTArray<nsString> cssValueArray;
// get the CSS equivalence with last param true indicating we want only the
// "gettable" properties
GenerateCSSDeclarationsFromHTMLStyle(theElement, aHTMLProperty, aAttribute, nullptr,
GenerateCSSDeclarationsFromHTMLStyle(theElement, aHTMLProperty, aAttribute,
nullptr,
cssPropertyArray, cssValueArray, true);
int32_t count = cssPropertyArray.Length();
for (int32_t index = 0; index < count; index++) {
@@ -1063,48 +1074,58 @@ CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode,
StyleType aStyleType)
{
MOZ_ASSERT(aNode && aProperty);
bool isSet;
nsresult rv = IsCSSEquivalentToHTMLInlineStyleSet(aNode->AsDOMNode(),
aProperty, aAttribute,
isSet, aValue, aStyleType);
NS_ENSURE_SUCCESS(rv, false);
return isSet;
nsCOMPtr<nsIAtom> attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
return IsCSSEquivalentToHTMLInlineStyleSet(aNode,
aProperty, attribute,
aValue, aStyleType);
}
nsresult
bool
CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(nsIDOMNode* aNode,
nsIAtom* aProperty,
const nsAString* aAttribute,
nsAString& aValue,
StyleType aStyleType)
{
MOZ_ASSERT(aNode && aProperty);
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
nsCOMPtr<nsIAtom> attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
return IsCSSEquivalentToHTMLInlineStyleSet(node, aProperty, attribute,
aValue, aStyleType);
}
bool
CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
nsIDOMNode* aNode,
nsINode* aNode,
nsIAtom* aHTMLProperty,
const nsAString* aHTMLAttribute,
bool& aIsSet,
nsIAtom* aHTMLAttribute,
nsAString& valueString,
StyleType aStyleType)
{
NS_ENSURE_TRUE(aNode, NS_ERROR_NULL_POINTER);
NS_ENSURE_TRUE(aNode, false);
nsAutoString htmlValueString(valueString);
aIsSet = false;
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
bool isSet = false;
do {
valueString.Assign(htmlValueString);
// get the value of the CSS equivalent styles
nsresult rv =
GetCSSEquivalentToHTMLInlineStyleSet(node, aHTMLProperty, aHTMLAttribute,
GetCSSEquivalentToHTMLInlineStyleSet(aNode, aHTMLProperty, aHTMLAttribute,
valueString, aStyleType);
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_SUCCESS(rv, false);
// early way out if we can
if (valueString.IsEmpty()) {
return NS_OK;
return isSet;
}
if (nsGkAtoms::b == aHTMLProperty) {
if (valueString.EqualsLiteral("bold")) {
aIsSet = true;
isSet = true;
} else if (valueString.EqualsLiteral("normal")) {
aIsSet = false;
isSet = false;
} else if (valueString.EqualsLiteral("bolder")) {
aIsSet = true;
isSet = true;
valueString.AssignLiteral("bold");
} else {
int32_t weight = 0;
@@ -1112,32 +1133,31 @@ CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
nsAutoString value(valueString);
weight = value.ToInteger(&errorCode);
if (400 < weight) {
aIsSet = true;
isSet = true;
valueString.AssignLiteral("bold");
} else {
aIsSet = false;
isSet = false;
valueString.AssignLiteral("normal");
}
}
} else if (nsGkAtoms::i == aHTMLProperty) {
if (valueString.EqualsLiteral("italic") ||
valueString.EqualsLiteral("oblique")) {
aIsSet = true;
isSet = true;
}
} else if (nsGkAtoms::u == aHTMLProperty) {
nsAutoString val;
val.AssignLiteral("underline");
aIsSet = ChangeStyleTransaction::ValueIncludes(valueString, val);
isSet = ChangeStyleTransaction::ValueIncludes(valueString, val);
} else if (nsGkAtoms::strike == aHTMLProperty) {
nsAutoString val;
val.AssignLiteral("line-through");
aIsSet = ChangeStyleTransaction::ValueIncludes(valueString, val);
} else if (aHTMLAttribute &&
((nsGkAtoms::font == aHTMLProperty &&
aHTMLAttribute->EqualsLiteral("color")) ||
aHTMLAttribute->EqualsLiteral("bgcolor"))) {
isSet = ChangeStyleTransaction::ValueIncludes(valueString, val);
} else if ((nsGkAtoms::font == aHTMLProperty &&
aHTMLAttribute == nsGkAtoms::color) ||
aHTMLAttribute == nsGkAtoms::bgcolor) {
if (htmlValueString.IsEmpty()) {
aIsSet = true;
isSet = true;
} else {
nscolor rgba;
nsAutoString subStr;
@@ -1171,54 +1191,53 @@ CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
htmlColor.Append(char16_t(')'));
}
aIsSet = htmlColor.Equals(valueString,
nsCaseInsensitiveStringComparator());
isSet = htmlColor.Equals(valueString,
nsCaseInsensitiveStringComparator());
} else {
aIsSet = htmlValueString.Equals(valueString,
nsCaseInsensitiveStringComparator());
isSet = htmlValueString.Equals(valueString,
nsCaseInsensitiveStringComparator());
}
}
} else if (nsGkAtoms::tt == aHTMLProperty) {
aIsSet = StringBeginsWith(valueString, NS_LITERAL_STRING("monospace"));
isSet = StringBeginsWith(valueString, NS_LITERAL_STRING("monospace"));
} else if (nsGkAtoms::font == aHTMLProperty && aHTMLAttribute &&
aHTMLAttribute->EqualsLiteral("face")) {
aHTMLAttribute == nsGkAtoms::face) {
if (!htmlValueString.IsEmpty()) {
const char16_t commaSpace[] = { char16_t(','), char16_t(' '), 0 };
const char16_t comma[] = { char16_t(','), 0 };
htmlValueString.ReplaceSubstring(commaSpace, comma);
nsAutoString valueStringNorm(valueString);
valueStringNorm.ReplaceSubstring(commaSpace, comma);
aIsSet = htmlValueString.Equals(valueStringNorm,
nsCaseInsensitiveStringComparator());
isSet = htmlValueString.Equals(valueStringNorm,
nsCaseInsensitiveStringComparator());
} else {
aIsSet = true;
isSet = true;
}
return NS_OK;
} else if (aHTMLAttribute && aHTMLAttribute->EqualsLiteral("align")) {
aIsSet = true;
return isSet;
} else if (aHTMLAttribute == nsGkAtoms::align) {
isSet = true;
} else {
aIsSet = false;
return NS_OK;
return false;
}
if (!htmlValueString.IsEmpty() &&
htmlValueString.Equals(valueString,
nsCaseInsensitiveStringComparator())) {
aIsSet = true;
isSet = true;
}
if (htmlValueString.EqualsLiteral("-moz-editor-invert-value")) {
aIsSet = !aIsSet;
isSet = !isSet;
}
if (nsGkAtoms::u == aHTMLProperty || nsGkAtoms::strike == aHTMLProperty) {
// unfortunately, the value of the text-decoration property is not inherited.
// that means that we have to look at ancestors of node to see if they are underlined
node = node->GetParentElement(); // set to null if it's not a dom element
aNode = aNode->GetParentElement(); // set to null if it's not a dom element
}
} while ((nsGkAtoms::u == aHTMLProperty ||
nsGkAtoms::strike == aHTMLProperty) && !aIsSet && node);
return NS_OK;
nsGkAtoms::strike == aHTMLProperty) && !isSet && aNode);
return isSet;
}
void
+36 -29
View File
@@ -90,6 +90,8 @@ public:
*/
bool IsCSSEditableProperty(nsINode* aNode, nsIAtom* aProperty,
const nsAString* aAttribute);
bool IsCSSEditableProperty(nsINode* aNode, nsIAtom* aProperty,
nsIAtom* aAttribute);
/**
* Adds/remove a CSS declaration to the STYLE atrribute carried by a given
@@ -188,14 +190,14 @@ public:
*
* @param aNode [IN] A DOM node.
* @param aHTMLProperty [IN] An atom containing an HTML property.
* @param aAttribute [IN] A pointer to an attribute name or nullptr if
* @param aAttribute [IN] An atom of attribute name or nullptr if
* irrelevant.
* @param aValueString [OUT] The list of CSS values.
* @param aStyleType [IN] eSpecified or eComputed.
*/
nsresult GetCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode,
nsIAtom* aHTMLProperty,
const nsAString* aAttribute,
nsIAtom* aAttribute,
nsAString& aValueString,
StyleType aStyleType);
@@ -205,16 +207,20 @@ public:
*
* @param aNode [IN] A DOM node.
* @param aHTMLProperty [IN] An atom containing an HTML property.
* @param aAttribute [IN] A pointer to an attribute name or nullptr if
* irrelevant.
* @param aIsSet [OUT] A boolean being true if the css properties are
* set.
* @param aAttribute [IN] A pointer/atom to an attribute name or nullptr
* if irrelevant.
* @param aValueString [IN/OUT] The attribute value (in) the list of CSS
* values (out).
* @param aStyleType [IN] eSpecified or eComputed.
*
* The nsIContent variant returns aIsSet instead of using an out parameter.
* @return A boolean being true if the css properties are
* set.
*/
bool IsCSSEquivalentToHTMLInlineStyleSet(nsINode* aContent,
nsIAtom* aProperty,
nsIAtom* aAttribute,
nsAString& aValue,
StyleType aStyleType);
bool IsCSSEquivalentToHTMLInlineStyleSet(nsINode* aContent,
nsIAtom* aProperty,
const nsAString* aAttribute,
@@ -227,12 +233,11 @@ public:
nsAString& aValue,
StyleType aStyleType);
nsresult IsCSSEquivalentToHTMLInlineStyleSet(nsIDOMNode* aNode,
nsIAtom* aHTMLProperty,
const nsAString* aAttribute,
bool& aIsSet,
nsAString& aValueString,
StyleType aStyleType);
bool IsCSSEquivalentToHTMLInlineStyleSet(nsIDOMNode* aNode,
nsIAtom* aProperty,
const nsAString* aAttribute,
nsAString& aValue,
StyleType aStyleType);
/**
* Adds to the node the CSS inline styles equivalent to the HTML style
@@ -240,27 +245,29 @@ public:
*
* @param aNode [IN] A DOM node.
* @param aHTMLProperty [IN] An atom containing an HTML property.
* @param aAttribute [IN] A pointer to an attribute name or nullptr if
* irrelevant.
* @param aAttribute [IN] A pointer/atom to an attribute name or nullptr
* if irrelevant.
* @param aValue [IN] The attribute value.
* @param aCount [OUT] The number of CSS properties set by the call.
* @param aSuppressTransaction [IN] A boolean indicating, when true,
* that no transaction should be recorded.
*
* aCount is returned by the dom::Element variant instead of being an out
* parameter.
* @return The number of CSS properties set by the call.
*/
int32_t SetCSSEquivalentToHTMLStyle(dom::Element* aElement,
nsIAtom* aProperty,
nsIAtom* aAttribute,
const nsAString* aValue,
bool aSuppressTransaction);
int32_t SetCSSEquivalentToHTMLStyle(dom::Element* aElement,
nsIAtom* aProperty,
const nsAString* aAttribute,
const nsAString* aValue,
bool aSuppressTransaction);
nsresult SetCSSEquivalentToHTMLStyle(nsIDOMNode* aNode,
nsIAtom* aHTMLProperty,
const nsAString* aAttribute,
const nsAString* aValue,
int32_t* aCount,
bool aSuppressTransaction);
int32_t SetCSSEquivalentToHTMLStyle(nsIDOMNode* aNode,
nsIAtom* aHTMLProperty,
const nsAString* aAttribute,
const nsAString* aValue,
bool aSuppressTransaction);
/**
* Removes from the node the CSS inline styles equivalent to the HTML style.
@@ -284,7 +291,7 @@ public:
*
* @param aElement [IN] A DOM Element (must not be null).
* @param aHTMLProperty [IN] An atom containing an HTML property.
* @param aAttribute [IN] A pointer to an attribute name or nullptr if
* @param aAttribute [IN] An atom to an attribute name or nullptr if
* irrelevant.
* @param aValue [IN] The attribute value.
* @param aSuppressTransaction [IN] A boolean indicating, when true,
@@ -292,7 +299,7 @@ public:
*/
nsresult RemoveCSSEquivalentToHTMLStyle(dom::Element* aElement,
nsIAtom* aHTMLProperty,
const nsAString* aAttribute,
nsIAtom* aAttribute,
const nsAString* aValue,
bool aSuppressTransaction);
@@ -409,7 +416,7 @@ private:
*
* @param aNode [IN] The DOM node.
* @param aHTMLProperty [IN] An atom containing an HTML property.
* @param aAttribute [IN] A pointer to an attribute name or nullptr
* @param aAttribute [IN] An atom to an attribute name or nullptr
* if irrelevant
* @param aValue [IN] The attribute value.
* @param aPropertyArray [OUT] The array of CSS properties.
@@ -422,7 +429,7 @@ private:
*/
void GenerateCSSDeclarationsFromHTMLStyle(dom::Element* aNode,
nsIAtom* aHTMLProperty,
const nsAString* aAttribute,
nsIAtom* aAttribute,
const nsAString* aValue,
nsTArray<nsIAtom*>& aPropertyArray,
nsTArray<nsString>& aValueArray,
+64 -31
View File
@@ -1229,12 +1229,23 @@ EditorBase::SetAttribute(nsIDOMElement* aElement,
const nsAString& aAttribute,
const nsAString& aValue)
{
if (NS_WARN_IF(aAttribute.IsEmpty())) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<Element> element = do_QueryInterface(aElement);
NS_ENSURE_TRUE(element, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIAtom> attribute = NS_Atomize(aAttribute);
return SetAttribute(element, attribute, aValue);
}
nsresult
EditorBase::SetAttribute(Element* aElement,
nsIAtom* aAttribute,
const nsAString& aValue)
{
RefPtr<ChangeAttributeTransaction> transaction =
CreateTxnForSetAttribute(*element, *attribute, aValue);
CreateTxnForSetAttribute(*aElement, *aAttribute, aValue);
return DoTransaction(transaction);
}
@@ -1263,12 +1274,22 @@ NS_IMETHODIMP
EditorBase::RemoveAttribute(nsIDOMElement* aElement,
const nsAString& aAttribute)
{
if (NS_WARN_IF(aAttribute.IsEmpty())) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<Element> element = do_QueryInterface(aElement);
NS_ENSURE_TRUE(element, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIAtom> attribute = NS_Atomize(aAttribute);
return RemoveAttribute(element, attribute);
}
nsresult
EditorBase::RemoveAttribute(Element* aElement,
nsIAtom* aAttribute)
{
RefPtr<ChangeAttributeTransaction> transaction =
CreateTxnForRemoveAttribute(*element, *attribute);
CreateTxnForRemoveAttribute(*aElement, *aAttribute);
return DoTransaction(transaction);
}
@@ -2208,25 +2229,28 @@ EditorBase::CloneAttribute(const nsAString& aAttribute,
nsIDOMNode* aSourceNode)
{
NS_ENSURE_TRUE(aDestNode && aSourceNode, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIDOMElement> destElement = do_QueryInterface(aDestNode);
nsCOMPtr<nsIDOMElement> sourceElement = do_QueryInterface(aSourceNode);
NS_ENSURE_TRUE(destElement && sourceElement, NS_ERROR_NO_INTERFACE);
nsAutoString attrValue;
bool isAttrSet;
nsresult rv = GetAttributeValue(sourceElement,
aAttribute,
attrValue,
&isAttrSet);
NS_ENSURE_SUCCESS(rv, rv);
if (isAttrSet) {
rv = SetAttribute(destElement, aAttribute, attrValue);
} else {
rv = RemoveAttribute(destElement, aAttribute);
if (NS_WARN_IF(aAttribute.IsEmpty())) {
return NS_ERROR_FAILURE;
}
return rv;
nsCOMPtr<Element> destElement = do_QueryInterface(aDestNode);
nsCOMPtr<Element> sourceElement = do_QueryInterface(aSourceNode);
NS_ENSURE_TRUE(destElement && sourceElement, NS_ERROR_NO_INTERFACE);
nsCOMPtr<nsIAtom> attribute = NS_Atomize(aAttribute);
return CloneAttribute(attribute, destElement, sourceElement);
}
nsresult
EditorBase::CloneAttribute(nsIAtom* aAttribute,
Element* aDestElement,
Element* aSourceElement)
{
nsAutoString attrValue;
if (aSourceElement->GetAttr(kNameSpaceID_None, aAttribute, attrValue)) {
return SetAttribute(aDestElement, aAttribute, attrValue);
}
return RemoveAttribute(aDestElement, aAttribute);
}
/**
@@ -2265,11 +2289,9 @@ EditorBase::CloneAttributes(Element* aDest,
RefPtr<nsDOMAttributeMap> destAttributes = aDest->Attributes();
while (RefPtr<Attr> attr = destAttributes->Item(0)) {
if (destInBody) {
RemoveAttribute(static_cast<nsIDOMElement*>(GetAsDOMNode(aDest)),
attr->NodeName());
RemoveAttribute(aDest, attr->NodeInfo()->NameAtom());
} else {
ErrorResult ignored;
aDest->RemoveAttribute(attr->NodeName(), ignored);
aDest->UnsetAttr(kNameSpaceID_None, attr->NodeInfo()->NameAtom(), true);
}
}
@@ -2281,13 +2303,13 @@ EditorBase::CloneAttributes(Element* aDest,
nsAutoString value;
attr->GetValue(value);
if (destInBody) {
SetAttributeOrEquivalent(static_cast<nsIDOMElement*>(GetAsDOMNode(aDest)),
attr->NodeName(), value, false);
SetAttributeOrEquivalent(aDest, attr->NodeInfo()->NameAtom(), value,
false);
} else {
// The element is not inserted in the document yet, we don't want to put
// a transaction on the UndoStack
SetAttributeOrEquivalent(static_cast<nsIDOMElement*>(GetAsDOMNode(aDest)),
attr->NodeName(), value, true);
SetAttributeOrEquivalent(aDest, attr->NodeInfo()->NameAtom(), value,
true);
}
}
}
@@ -4618,21 +4640,32 @@ EditorBase::CreateHTMLContent(nsIAtom* aTag)
kNameSpaceID_XHTML);
}
nsresult
NS_IMETHODIMP
EditorBase::SetAttributeOrEquivalent(nsIDOMElement* aElement,
const nsAString& aAttribute,
const nsAString& aValue,
bool aSuppressTransaction)
{
return SetAttribute(aElement, aAttribute, aValue);
nsCOMPtr<Element> element = do_QueryInterface(aElement);
if (NS_WARN_IF(!element)) {
return NS_ERROR_NULL_POINTER;
}
nsCOMPtr<nsIAtom> attribute = NS_Atomize(aAttribute);
return SetAttributeOrEquivalent(element, attribute, aValue,
aSuppressTransaction);
}
nsresult
NS_IMETHODIMP
EditorBase::RemoveAttributeOrEquivalent(nsIDOMElement* aElement,
const nsAString& aAttribute,
bool aSuppressTransaction)
{
return RemoveAttribute(aElement, aAttribute);
nsCOMPtr<Element> element = do_QueryInterface(aElement);
if (NS_WARN_IF(!element)) {
return NS_ERROR_NULL_POINTER;
}
nsCOMPtr<nsIAtom> attribute = NS_Atomize(aAttribute);
return RemoveAttributeOrEquivalent(element, attribute, aSuppressTransaction);
}
nsresult
+13
View File
@@ -236,6 +236,19 @@ public:
nsresult JoinNodes(nsINode& aLeftNode, nsINode& aRightNode);
nsresult MoveNode(nsIContent* aNode, nsINode* aParent, int32_t aOffset);
nsresult CloneAttribute(nsIAtom* aAttribute, Element* aDestElement,
Element* aSourceElement);
nsresult RemoveAttribute(Element* aElement, nsIAtom* aAttribute);
virtual nsresult RemoveAttributeOrEquivalent(Element* aElement,
nsIAtom* aAttribute,
bool aSuppressTransaction) = 0;
nsresult SetAttribute(Element* aElement, nsIAtom* aAttribute,
const nsAString& aValue);
virtual nsresult SetAttributeOrEquivalent(Element* aElement,
nsIAtom* aAttribute,
const nsAString& aValue,
bool aSuppressTransaction) = 0;
/**
* Method to replace certain CreateElementNS() calls.
*
+42 -41
View File
@@ -839,19 +839,18 @@ HTMLEditRules::GetAlignment(bool* aMixed,
NS_ENSURE_TRUE(nodeToExamine, NS_ERROR_NULL_POINTER);
NS_NAMED_LITERAL_STRING(typeAttrName, "align");
nsCOMPtr<Element> blockParent = htmlEditor->GetBlock(*nodeToExamine);
NS_ENSURE_TRUE(blockParent, NS_ERROR_FAILURE);
if (htmlEditor->IsCSSEnabled() &&
htmlEditor->mCSSEditUtils->IsCSSEditableProperty(blockParent, nullptr,
&typeAttrName)) {
nsGkAtoms::align)) {
// We are in CSS mode and we know how to align this element with CSS
nsAutoString value;
// Let's get the value(s) of text-align or margin-left/margin-right
htmlEditor->mCSSEditUtils->GetCSSEquivalentToHTMLInlineStyleSet(
blockParent, nullptr, &typeAttrName, value, CSSEditUtils::eComputed);
blockParent, nullptr, nsGkAtoms::align, value, CSSEditUtils::eComputed);
if (value.EqualsLiteral("center") ||
value.EqualsLiteral("-moz-center") ||
value.EqualsLiteral("auto auto")) {
@@ -1510,10 +1509,11 @@ HTMLEditRules::WillInsertBreak(Selection& aSelection,
nsCOMPtr<Element> blockParent = htmlEditor->GetBlock(node);
NS_ENSURE_TRUE(blockParent, NS_ERROR_FAILURE);
// If the active editing host is an inline element, or if the active editing
// host is the block parent itself, just append a br.
// When there is an active editing host (the <body> if it's in designMode)
// and a block which becomes the parent of line breaker is in it, do the
// standard thing.
nsCOMPtr<Element> host = htmlEditor->GetActiveEditingHost();
if (!EditorUtils::IsDescendantOf(blockParent, host)) {
if (host && !EditorUtils::IsDescendantOf(blockParent, host)) {
nsresult rv = StandardBreakImpl(node, offset, aSelection);
NS_ENSURE_SUCCESS(rv, rv);
*aHandled = true;
@@ -3303,15 +3303,15 @@ HTMLEditRules::WillMakeList(Selection* aSelection,
}
}
NS_ENSURE_STATE(mHTMLEditor);
nsCOMPtr<nsIDOMElement> curElement = do_QueryInterface(curNode);
NS_NAMED_LITERAL_STRING(typestr, "type");
nsCOMPtr<Element> curElement = do_QueryInterface(curNode);
if (aBulletType && !aBulletType->IsEmpty()) {
rv = mHTMLEditor->SetAttribute(curElement, typestr, *aBulletType);
rv = mHTMLEditor->SetAttribute(curElement, nsGkAtoms::type,
*aBulletType);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
} else {
rv = mHTMLEditor->RemoveAttribute(curElement, typestr);
rv = mHTMLEditor->RemoveAttribute(curElement, nsGkAtoms::type);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@@ -4755,7 +4755,7 @@ HTMLEditRules::WillAlign(Selection& aSelection,
NS_ENSURE_SUCCESS(rv, rv);
if (useCSS) {
htmlEditor->mCSSEditUtils->SetCSSEquivalentToHTMLStyle(
curNode->AsElement(), nullptr, &NS_LITERAL_STRING("align"),
curNode->AsElement(), nullptr, nsGkAtoms::align,
&aAlignType, false);
curDiv = nullptr;
continue;
@@ -4836,7 +4836,6 @@ HTMLEditRules::AlignBlockContents(nsIDOMNode* aNode,
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
NS_ENSURE_TRUE(node && alignType, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIContent> firstChild, lastChild;
nsCOMPtr<Element> divNode;
bool useCSS = mHTMLEditor->IsCSSEnabled();
@@ -4844,24 +4843,25 @@ HTMLEditRules::AlignBlockContents(nsIDOMNode* aNode,
firstChild = mHTMLEditor->GetFirstEditableChild(*node);
NS_ENSURE_STATE(mHTMLEditor);
lastChild = mHTMLEditor->GetLastEditableChild(*node);
NS_NAMED_LITERAL_STRING(attr, "align");
if (!firstChild) {
// this cell has no content, nothing to align
} else if (firstChild == lastChild &&
firstChild->IsHTMLElement(nsGkAtoms::div)) {
// the cell already has a div containing all of its content: just
// act on this div.
nsCOMPtr<nsIDOMElement> divElem = do_QueryInterface(firstChild);
RefPtr<Element> divElem = firstChild->AsElement();
if (useCSS) {
NS_ENSURE_STATE(mHTMLEditor);
nsresult rv = mHTMLEditor->SetAttributeOrEquivalent(divElem, attr,
nsresult rv = mHTMLEditor->SetAttributeOrEquivalent(divElem,
nsGkAtoms::align,
*alignType, false);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
} else {
NS_ENSURE_STATE(mHTMLEditor);
nsresult rv = mHTMLEditor->SetAttribute(divElem, attr, *alignType);
nsresult rv = mHTMLEditor->SetAttribute(divElem, nsGkAtoms::align,
*alignType);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@@ -4869,28 +4869,29 @@ HTMLEditRules::AlignBlockContents(nsIDOMNode* aNode,
} else {
// else we need to put in a div, set the alignment, and toss in all the children
NS_ENSURE_STATE(mHTMLEditor);
divNode = mHTMLEditor->CreateNode(nsGkAtoms::div, node, 0);
NS_ENSURE_STATE(divNode);
RefPtr<Element> divElem = mHTMLEditor->CreateNode(nsGkAtoms::div, node, 0);
NS_ENSURE_STATE(divElem);
// set up the alignment on the div
nsCOMPtr<nsIDOMElement> divElem = do_QueryInterface(divNode);
if (useCSS) {
NS_ENSURE_STATE(mHTMLEditor);
nsresult rv =
mHTMLEditor->SetAttributeOrEquivalent(divElem, attr, *alignType, false);
mHTMLEditor->SetAttributeOrEquivalent(divElem, nsGkAtoms::align,
*alignType, false);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
} else {
NS_ENSURE_STATE(mHTMLEditor);
nsresult rv = mHTMLEditor->SetAttribute(divElem, attr, *alignType);
nsresult rv =
mHTMLEditor->SetAttribute(divElem, nsGkAtoms::align, *alignType);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
// tuck the children into the end of the active div
while (lastChild && (lastChild != divNode)) {
while (lastChild && (lastChild != divElem)) {
NS_ENSURE_STATE(mHTMLEditor);
nsresult rv = mHTMLEditor->MoveNode(lastChild, divNode, 0);
nsresult rv = mHTMLEditor->MoveNode(lastChild, divElem, 0);
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_STATE(mHTMLEditor);
lastChild = mHTMLEditor->GetLastEditableChild(*node);
@@ -6480,10 +6481,14 @@ HTMLEditRules::SplitParagraph(nsIDOMNode *aPara,
// split the paragraph
NS_ENSURE_STATE(mHTMLEditor);
NS_ENSURE_STATE(selNode->IsContent());
mHTMLEditor->SplitNodeDeep(*para, *selNode->AsContent(), *aOffset,
HTMLEditor::EmptyContainers::yes,
getter_AddRefs(leftPara),
getter_AddRefs(rightPara));
int32_t offset =
mHTMLEditor->SplitNodeDeep(*para, *selNode->AsContent(), *aOffset,
HTMLEditor::EmptyContainers::yes,
getter_AddRefs(leftPara),
getter_AddRefs(rightPara));
if (NS_WARN_IF(offset == -1)) {
return NS_ERROR_FAILURE;
}
// get rid of the break, if it is visible (otherwise it may be needed to prevent an empty p)
NS_ENSURE_STATE(mHTMLEditor);
if (mHTMLEditor->IsVisBreak(aBRNode)) {
@@ -6493,9 +6498,9 @@ HTMLEditRules::SplitParagraph(nsIDOMNode *aPara,
}
// remove ID attribute on the paragraph we just created
nsCOMPtr<nsIDOMElement> rightElt = do_QueryInterface(rightPara);
RefPtr<Element> rightElt = rightPara->AsElement();
NS_ENSURE_STATE(mHTMLEditor);
rv = mHTMLEditor->RemoveAttribute(rightElt, NS_LITERAL_STRING("id"));
rv = mHTMLEditor->RemoveAttribute(rightElt, nsGkAtoms::id);
NS_ENSURE_SUCCESS(rv, rv);
// check both halves of para to see if we need mozBR
@@ -7125,9 +7130,9 @@ HTMLEditRules::CacheInlineStyles(nsIDOMNode* aNode)
isSet, &outValue);
} else {
NS_ENSURE_STATE(mHTMLEditor);
mHTMLEditor->mCSSEditUtils->IsCSSEquivalentToHTMLInlineStyleSet(aNode,
mCachedStyles[j].tag, &(mCachedStyles[j].attr), isSet, outValue,
CSSEditUtils::eComputed);
isSet = mHTMLEditor->mCSSEditUtils->IsCSSEquivalentToHTMLInlineStyleSet(
aNode, mCachedStyles[j].tag, &(mCachedStyles[j].attr), outValue,
CSSEditUtils::eComputed);
}
if (isSet) {
mCachedStyles[j].mPresent = true;
@@ -8356,18 +8361,18 @@ HTMLEditRules::RemoveAlignment(nsIDOMNode* aNode,
NS_ENSURE_SUCCESS(rv, rv);
} else if (isBlock || HTMLEditUtils::IsHR(child)) {
// the current node is a block element
nsCOMPtr<nsIDOMElement> curElem = do_QueryInterface(child);
nsCOMPtr<Element> curElem = do_QueryInterface(child);
if (HTMLEditUtils::SupportsAlignAttr(child)) {
// remove the ALIGN attribute if this element can have it
NS_ENSURE_STATE(mHTMLEditor);
rv = mHTMLEditor->RemoveAttribute(curElem, NS_LITERAL_STRING("align"));
rv = mHTMLEditor->RemoveAttribute(curElem, nsGkAtoms::align);
NS_ENSURE_SUCCESS(rv, rv);
}
if (useCSS) {
if (HTMLEditUtils::IsTable(child) || HTMLEditUtils::IsHR(child)) {
NS_ENSURE_STATE(mHTMLEditor);
rv = mHTMLEditor->SetAttributeOrEquivalent(curElem,
NS_LITERAL_STRING("align"),
nsGkAtoms::align,
aAlignType, false);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
@@ -8487,21 +8492,17 @@ HTMLEditRules::AlignBlock(Element& aElement,
nsresult rv = RemoveAlignment(aElement.AsDOMNode(), aAlignType,
aContentsOnly == ContentsOnly::yes);
NS_ENSURE_SUCCESS(rv, rv);
NS_NAMED_LITERAL_STRING(attr, "align");
if (htmlEditor->IsCSSEnabled()) {
// Let's use CSS alignment; we use margin-left and margin-right for tables
// and text-align for other block-level elements
rv = htmlEditor->SetAttributeOrEquivalent(
static_cast<nsIDOMElement*>(aElement.AsDOMNode()),
attr, aAlignType, false);
&aElement, nsGkAtoms::align, aAlignType, false);
NS_ENSURE_SUCCESS(rv, rv);
} else {
// HTML case; this code is supposed to be called ONLY if the element
// supports the align attribute but we'll never know...
if (HTMLEditUtils::SupportsAlignAttr(aElement.AsDOMNode())) {
rv = htmlEditor->SetAttribute(
static_cast<nsIDOMElement*>(aElement.AsDOMNode()),
attr, aAlignType);
rv = htmlEditor->SetAttribute(&aElement, nsGkAtoms::align, aAlignType);
NS_ENSURE_SUCCESS(rv, rv);
}
}
+68 -68
View File
@@ -2584,7 +2584,7 @@ HTMLEditor::CreateElementWithDefaults(const nsAString& aTagName)
// New call to use instead to get proper HTML element, bug 39919
nsCOMPtr<nsIAtom> realTagAtom = NS_Atomize(realTagName);
nsCOMPtr<Element> newElement = CreateHTMLContent(realTagAtom);
RefPtr<Element> newElement = CreateHTMLContent(realTagAtom);
if (!newElement) {
return nullptr;
}
@@ -2616,8 +2616,7 @@ HTMLEditor::CreateElementWithDefaults(const nsAString& aTagName)
} else if (tagName.EqualsLiteral("td")) {
nsresult rv =
SetAttributeOrEquivalent(
static_cast<nsIDOMElement*>(newElement->AsDOMNode()),
NS_LITERAL_STRING("valign"), NS_LITERAL_STRING("top"), true);
newElement, nsGkAtoms::valign, NS_LITERAL_STRING("top"), true);
NS_ENSURE_SUCCESS(rv, nullptr);
}
// ADD OTHER TAGS HERE
@@ -4443,87 +4442,83 @@ HTMLEditor::IsEmptyNodeImpl(nsINode* aNode,
// add to aElement the CSS inline styles corresponding to the HTML attribute
// aAttribute with its value aValue
nsresult
HTMLEditor::SetAttributeOrEquivalent(nsIDOMElement* aElement,
const nsAString& aAttribute,
HTMLEditor::SetAttributeOrEquivalent(Element* aElement,
nsIAtom* aAttribute,
const nsAString& aValue,
bool aSuppressTransaction)
{
MOZ_ASSERT(aElement);
MOZ_ASSERT(aAttribute);
nsAutoScriptBlocker scriptBlocker;
if (IsCSSEnabled() && mCSSEditUtils) {
int32_t count;
nsresult rv =
mCSSEditUtils->SetCSSEquivalentToHTMLStyle(aElement, nullptr,
&aAttribute, &aValue,
&count,
aSuppressTransaction);
NS_ENSURE_SUCCESS(rv, rv);
if (count) {
// we found an equivalence ; let's remove the HTML attribute itself if it is set
nsAutoString existingValue;
bool wasSet = false;
rv = GetAttributeValue(aElement, aAttribute, existingValue, &wasSet);
NS_ENSURE_SUCCESS(rv, rv);
if (!wasSet) {
return NS_OK;
}
return aSuppressTransaction ? aElement->RemoveAttribute(aAttribute) :
RemoveAttribute(aElement, aAttribute);
}
// count is an integer that represents the number of CSS declarations applied to the
// element. If it is zero, we found no equivalence in this implementation for the
// attribute
if (aAttribute.EqualsLiteral("style")) {
// if it is the style attribute, just add the new value to the existing style
// attribute's value
nsAutoString existingValue;
bool wasSet = false;
nsresult rv = GetAttributeValue(aElement, NS_LITERAL_STRING("style"),
existingValue, &wasSet);
NS_ENSURE_SUCCESS(rv, rv);
existingValue.Append(' ');
existingValue.Append(aValue);
return aSuppressTransaction ?
aElement->SetAttribute(aAttribute, existingValue) :
SetAttribute(aElement, aAttribute, existingValue);
}
// we have no CSS equivalence for this attribute and it is not the style
// attribute; let's set it the good'n'old HTML way
return aSuppressTransaction ? aElement->SetAttribute(aAttribute, aValue) :
SetAttribute(aElement, aAttribute, aValue);
if (!IsCSSEnabled() || !mCSSEditUtils) {
// we are not in an HTML+CSS editor; let's set the attribute the HTML way
return aSuppressTransaction ?
aElement->SetAttr(kNameSpaceID_None, aAttribute, aValue, true) :
SetAttribute(aElement, aAttribute, aValue);
}
// we are not in an HTML+CSS editor; let's set the attribute the HTML way
return aSuppressTransaction ? aElement->SetAttribute(aAttribute, aValue) :
SetAttribute(aElement, aAttribute, aValue);
int32_t count =
mCSSEditUtils->SetCSSEquivalentToHTMLStyle(aElement, nullptr,
aAttribute, &aValue,
aSuppressTransaction);
if (count) {
// we found an equivalence ; let's remove the HTML attribute itself if it
// is set
nsAutoString existingValue;
if (!aElement->GetAttr(kNameSpaceID_None, aAttribute, existingValue)) {
return NS_OK;
}
return aSuppressTransaction ?
aElement->UnsetAttr(kNameSpaceID_None, aAttribute, true) :
RemoveAttribute(aElement, aAttribute);
}
// count is an integer that represents the number of CSS declarations applied
// to the element. If it is zero, we found no equivalence in this
// implementation for the attribute
if (aAttribute == nsGkAtoms::style) {
// if it is the style attribute, just add the new value to the existing
// style attribute's value
nsAutoString existingValue;
aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::style, existingValue);
existingValue.Append(' ');
existingValue.Append(aValue);
return aSuppressTransaction ?
aElement->SetAttr(kNameSpaceID_None, aAttribute, existingValue, true) :
SetAttribute(aElement, aAttribute, existingValue);
}
// we have no CSS equivalence for this attribute and it is not the style
// attribute; let's set it the good'n'old HTML way
return aSuppressTransaction ?
aElement->SetAttr(kNameSpaceID_None, aAttribute, aValue, true) :
SetAttribute(aElement, aAttribute, aValue);
}
nsresult
HTMLEditor::RemoveAttributeOrEquivalent(nsIDOMElement* aElement,
const nsAString& aAttribute,
HTMLEditor::RemoveAttributeOrEquivalent(Element* aElement,
nsIAtom* aAttribute,
bool aSuppressTransaction)
{
nsCOMPtr<dom::Element> element = do_QueryInterface(aElement);
NS_ENSURE_TRUE(element, NS_OK);
nsCOMPtr<nsIAtom> attribute = NS_Atomize(aAttribute);
MOZ_ASSERT(attribute);
MOZ_ASSERT(aElement);
MOZ_ASSERT(aAttribute);
if (IsCSSEnabled() && mCSSEditUtils) {
nsresult rv =
mCSSEditUtils->RemoveCSSEquivalentToHTMLStyle(
element, nullptr, &aAttribute, nullptr, aSuppressTransaction);
aElement, nullptr, aAttribute, nullptr, aSuppressTransaction);
NS_ENSURE_SUCCESS(rv, rv);
}
if (!element->HasAttr(kNameSpaceID_None, attribute)) {
if (!aElement->HasAttr(kNameSpaceID_None, aAttribute)) {
return NS_OK;
}
return aSuppressTransaction ?
element->UnsetAttr(kNameSpaceID_None, attribute, /* aNotify = */ true) :
aElement->UnsetAttr(kNameSpaceID_None, aAttribute, /* aNotify = */ true) :
RemoveAttribute(aElement, aAttribute);
}
@@ -4576,7 +4571,6 @@ HTMLEditor::SetCSSBackgroundColor(const nsAString& aColor)
NS_ENSURE_SUCCESS(rv, rv);
if (!cancel && !handled) {
// Loop through the ranges in the selection
NS_NAMED_LITERAL_STRING(bgcolor, "bgcolor");
for (uint32_t i = 0; i < selection->RangeCount(); i++) {
RefPtr<nsRange> range = selection->GetRangeAt(i);
NS_ENSURE_TRUE(range, NS_ERROR_FAILURE);
@@ -4595,13 +4589,15 @@ HTMLEditor::SetCSSBackgroundColor(const nsAString& aColor)
if (blockParent && cachedBlockParent != blockParent) {
cachedBlockParent = blockParent;
mCSSEditUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr,
&bgcolor, &aColor, false);
nsGkAtoms::bgcolor,
&aColor, false);
}
} else if (startNode == endNode &&
startNode->IsHTMLElement(nsGkAtoms::body) && isCollapsed) {
// No block in the document, let's apply the background to the body
mCSSEditUtils->SetCSSEquivalentToHTMLStyle(startNode->AsElement(),
nullptr, &bgcolor, &aColor,
nullptr, nsGkAtoms::bgcolor,
&aColor,
false);
} else if (startNode == endNode && (endOffset - startOffset == 1 ||
(!startOffset && !endOffset))) {
@@ -4612,7 +4608,8 @@ HTMLEditor::SetCSSBackgroundColor(const nsAString& aColor)
if (blockParent && cachedBlockParent != blockParent) {
cachedBlockParent = blockParent;
mCSSEditUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr,
&bgcolor, &aColor, false);
nsGkAtoms::bgcolor,
&aColor, false);
}
} else {
// Not the easy case. Range not contained in single text node. There
@@ -4655,7 +4652,8 @@ HTMLEditor::SetCSSBackgroundColor(const nsAString& aColor)
if (blockParent && cachedBlockParent != blockParent) {
cachedBlockParent = blockParent;
mCSSEditUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr,
&bgcolor, &aColor,
nsGkAtoms::bgcolor,
&aColor,
false);
}
}
@@ -4666,7 +4664,8 @@ HTMLEditor::SetCSSBackgroundColor(const nsAString& aColor)
if (blockParent && cachedBlockParent != blockParent) {
cachedBlockParent = blockParent;
mCSSEditUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr,
&bgcolor, &aColor,
nsGkAtoms::bgcolor,
&aColor,
false);
}
}
@@ -4680,7 +4679,8 @@ HTMLEditor::SetCSSBackgroundColor(const nsAString& aColor)
if (blockParent && cachedBlockParent != blockParent) {
cachedBlockParent = blockParent;
mCSSEditUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr,
&bgcolor, &aColor,
nsGkAtoms::bgcolor,
&aColor,
false);
}
}
+10 -8
View File
@@ -118,6 +118,16 @@ public:
virtual already_AddRefed<nsIContent> GetInputEventTargetContent() override;
virtual bool IsEditable(nsINode* aNode) override;
using EditorBase::IsEditable;
virtual nsresult RemoveAttributeOrEquivalent(
Element* aElement,
nsIAtom* aAttribute,
bool aSuppressTransaction) override;
virtual nsresult SetAttributeOrEquivalent(Element* aElement,
nsIAtom* aAttribute,
const nsAString& aValue,
bool aSuppressTransaction) override;
using EditorBase::RemoveAttributeOrEquivalent;
using EditorBase::SetAttributeOrEquivalent;
// nsStubMutationObserver overrides
NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
@@ -329,14 +339,6 @@ public:
*/
virtual nsresult SelectEntireDocument(Selection* aSelection) override;
NS_IMETHOD SetAttributeOrEquivalent(nsIDOMElement* aElement,
const nsAString& aAttribute,
const nsAString& aValue,
bool aSuppressTransaction) override;
NS_IMETHOD RemoveAttributeOrEquivalent(nsIDOMElement* aElement,
const nsAString& aAttribute,
bool aSuppressTransaction) override;
/**
* Join together any adjacent editable text nodes in the range.
*/
+12 -17
View File
@@ -926,35 +926,30 @@ HTMLEditor::SetFinalSize(int32_t aX,
// we want one transaction only from a user's point of view
AutoEditBatch batchIt(this);
NS_NAMED_LITERAL_STRING(widthStr, "width");
NS_NAMED_LITERAL_STRING(heightStr, "height");
nsCOMPtr<Element> resizedObject = do_QueryInterface(mResizedObject);
NS_ENSURE_TRUE(resizedObject, );
if (mResizedObjectIsAbsolutelyPositioned) {
if (setHeight) {
mCSSEditUtils->SetCSSPropertyPixels(*resizedObject, *nsGkAtoms::top, y);
mCSSEditUtils->SetCSSPropertyPixels(*mResizedObject, *nsGkAtoms::top, y);
}
if (setWidth) {
mCSSEditUtils->SetCSSPropertyPixels(*resizedObject, *nsGkAtoms::left, x);
mCSSEditUtils->SetCSSPropertyPixels(*mResizedObject, *nsGkAtoms::left, x);
}
}
if (IsCSSEnabled() || mResizedObjectIsAbsolutelyPositioned) {
if (setWidth && mResizedObject->HasAttr(kNameSpaceID_None, nsGkAtoms::width)) {
RemoveAttribute(static_cast<nsIDOMElement*>(GetAsDOMNode(mResizedObject)), widthStr);
RemoveAttribute(mResizedObject, nsGkAtoms::width);
}
if (setHeight && mResizedObject->HasAttr(kNameSpaceID_None,
nsGkAtoms::height)) {
RemoveAttribute(static_cast<nsIDOMElement*>(GetAsDOMNode(mResizedObject)), heightStr);
RemoveAttribute(mResizedObject, nsGkAtoms::height);
}
if (setWidth) {
mCSSEditUtils->SetCSSPropertyPixels(*resizedObject, *nsGkAtoms::width,
mCSSEditUtils->SetCSSPropertyPixels(*mResizedObject, *nsGkAtoms::width,
width);
}
if (setHeight) {
mCSSEditUtils->SetCSSPropertyPixels(*resizedObject, *nsGkAtoms::height,
mCSSEditUtils->SetCSSPropertyPixels(*mResizedObject, *nsGkAtoms::height,
height);
}
} else {
@@ -964,30 +959,30 @@ HTMLEditor::SetFinalSize(int32_t aX,
// triggering an immediate reflow; otherwise, we have problems
// with asynchronous reflow
if (setWidth) {
mCSSEditUtils->SetCSSPropertyPixels(*resizedObject, *nsGkAtoms::width,
mCSSEditUtils->SetCSSPropertyPixels(*mResizedObject, *nsGkAtoms::width,
width);
}
if (setHeight) {
mCSSEditUtils->SetCSSPropertyPixels(*resizedObject, *nsGkAtoms::height,
mCSSEditUtils->SetCSSPropertyPixels(*mResizedObject, *nsGkAtoms::height,
height);
}
if (setWidth) {
nsAutoString w;
w.AppendInt(width);
SetAttribute(static_cast<nsIDOMElement*>(GetAsDOMNode(mResizedObject)), widthStr, w);
SetAttribute(mResizedObject, nsGkAtoms::width, w);
}
if (setHeight) {
nsAutoString h;
h.AppendInt(height);
SetAttribute(static_cast<nsIDOMElement*>(GetAsDOMNode(mResizedObject)), heightStr, h);
SetAttribute(mResizedObject, nsGkAtoms::height, h);
}
if (setWidth) {
mCSSEditUtils->RemoveCSSProperty(*resizedObject, *nsGkAtoms::width,
mCSSEditUtils->RemoveCSSProperty(*mResizedObject, *nsGkAtoms::width,
EmptyString());
}
if (setHeight) {
mCSSEditUtils->RemoveCSSProperty(*resizedObject, *nsGkAtoms::height,
mCSSEditUtils->RemoveCSSProperty(*mResizedObject, *nsGkAtoms::height,
EmptyString());
}
}
+14 -16
View File
@@ -429,7 +429,7 @@ HTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent& aNode,
mCSSEditUtils->IsCSSEditableProperty(&aNode, &aProperty,
aAttribute)) ||
// bgcolor is always done using CSS
aAttribute->EqualsLiteral("bgcolor");
attrAtom == nsGkAtoms::bgcolor;
if (useCSS) {
nsCOMPtr<dom::Element> tmp;
@@ -444,12 +444,9 @@ HTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent& aNode,
}
// Add the CSS styles corresponding to the HTML style request
int32_t count;
nsresult rv =
mCSSEditUtils->SetCSSEquivalentToHTMLStyle(tmp->AsDOMNode(),
&aProperty, aAttribute,
&aValue, &count, false);
NS_ENSURE_SUCCESS(rv, rv);
mCSSEditUtils->SetCSSEquivalentToHTMLStyle(tmp,
&aProperty, attrAtom,
&aValue, false);
return NS_OK;
}
@@ -574,8 +571,9 @@ HTMLEditor::SplitStyleAbovePoint(nsCOMPtr<nsINode>* aNode,
// in this implementation for the node; let's check if it carries those
// CSS styles
nsAutoString firstValue;
mCSSEditUtils->IsCSSEquivalentToHTMLInlineStyleSet(GetAsDOMNode(node),
aProperty, aAttribute, isSet, firstValue, CSSEditUtils::eSpecified);
isSet = mCSSEditUtils->IsCSSEquivalentToHTMLInlineStyleSet(
node, aProperty, aAttribute, firstValue,
CSSEditUtils::eSpecified);
}
if (// node is the correct inline prop
(aProperty && node->IsHTMLElement(aProperty)) ||
@@ -744,8 +742,6 @@ HTMLEditor::RemoveStyleInside(nsIContent& aNode,
// if we weren't passed an attribute, then we want to
// remove any matching inlinestyles entirely
if (!aAttribute || aAttribute->IsEmpty()) {
NS_NAMED_LITERAL_STRING(styleAttr, "style");
NS_NAMED_LITERAL_STRING(classAttr, "class");
bool hasStyleAttr = aNode.HasAttr(kNameSpaceID_None, nsGkAtoms::style);
bool hasClassAttr = aNode.HasAttr(kNameSpaceID_None, nsGkAtoms::_class);
@@ -754,14 +750,14 @@ HTMLEditor::RemoveStyleInside(nsIContent& aNode,
// just remove the element... We need to create above the element
// a span that will carry those styles or class, then we can delete
// the node.
nsCOMPtr<Element> spanNode =
RefPtr<Element> spanNode =
InsertContainerAbove(&aNode, nsGkAtoms::span);
NS_ENSURE_STATE(spanNode);
nsresult rv =
CloneAttribute(styleAttr, spanNode->AsDOMNode(), aNode.AsDOMNode());
CloneAttribute(nsGkAtoms::style, spanNode, aNode.AsElement());
NS_ENSURE_SUCCESS(rv, rv);
rv =
CloneAttribute(classAttr, spanNode->AsDOMNode(), aNode.AsDOMNode());
CloneAttribute(nsGkAtoms::_class, spanNode, aNode.AsElement());
NS_ENSURE_SUCCESS(rv, rv);
}
nsresult rv = RemoveContainer(&aNode);
@@ -794,15 +790,17 @@ HTMLEditor::RemoveStyleInside(nsIContent& aNode,
// the HTML style defined by aProperty/aAttribute has a CSS equivalence in
// this implementation for the node aNode; let's check if it carries those
// css styles
nsCOMPtr<nsIAtom> attribute =
aAttribute ? NS_Atomize(*aAttribute) : nullptr;
nsAutoString propertyValue;
bool isSet = mCSSEditUtils->IsCSSEquivalentToHTMLInlineStyleSet(&aNode,
aProperty, aAttribute, propertyValue, CSSEditUtils::eSpecified);
aProperty, attribute, propertyValue, CSSEditUtils::eSpecified);
if (isSet && aNode.IsElement()) {
// yes, tmp has the corresponding css declarations in its style attribute
// let's remove them
mCSSEditUtils->RemoveCSSEquivalentToHTMLStyle(aNode.AsElement(),
aProperty,
aAttribute,
attribute,
&propertyValue,
false);
// remove the node if it is a span or font, if its style attribute is
+16 -22
View File
@@ -25,7 +25,6 @@
#include "nsError.h"
#include "nsGkAtoms.h"
#include "nsIContent.h"
#include "nsIDOMCharacterData.h"
#include "nsIDOMDocument.h"
#include "nsIDOMElement.h"
#include "nsIDOMNode.h"
@@ -482,26 +481,24 @@ TextEditRules::CollapseSelectionToTrailingBRIfNeeded(Selection* aSelection)
return NS_OK;
}
static inline already_AddRefed<nsIDOMNode>
GetTextNode(Selection* selection,
EditorBase* editor)
static inline already_AddRefed<nsINode>
GetTextNode(Selection* selection)
{
int32_t selOffset;
nsCOMPtr<nsIDOMNode> selNode;
nsCOMPtr<nsINode> selNode;
nsresult rv =
editor->GetStartNodeAndOffset(selection,
getter_AddRefs(selNode), &selOffset);
EditorBase::GetStartNodeAndOffset(selection,
getter_AddRefs(selNode), &selOffset);
NS_ENSURE_SUCCESS(rv, nullptr);
if (!editor->IsTextNode(selNode)) {
// Get an nsINode from the nsIDOMNode
nsCOMPtr<nsINode> node = do_QueryInterface(selNode);
// if node is null, return it to indicate there's no text
NS_ENSURE_TRUE(node, nullptr);
if (!EditorBase::IsTextNode(selNode)) {
// This should be the root node, walk the tree looking for text nodes
RefPtr<NodeIterator> iter =
new NodeIterator(node, nsIDOMNodeFilter::SHOW_TEXT, NodeFilterHolder());
while (!editor->IsTextNode(selNode)) {
if (NS_FAILED(iter->NextNode(getter_AddRefs(selNode))) || !selNode) {
new NodeIterator(selNode, nsIDOMNodeFilter::SHOW_TEXT,
NodeFilterHolder());
while (!EditorBase::IsTextNode(selNode)) {
IgnoredErrorResult rv;
selNode = iter->NextNode(rv);
if (!selNode) {
return nullptr;
}
}
@@ -1385,13 +1382,10 @@ TextEditRules::HideLastPWInput()
nsContentUtils::GetSelectionInTextControl(selection, mTextEditor->GetRoot(),
start, end);
nsCOMPtr<nsIDOMNode> selNode = GetTextNode(selection, mTextEditor);
nsCOMPtr<nsINode> selNode = GetTextNode(selection);
NS_ENSURE_TRUE(selNode, NS_OK);
nsCOMPtr<nsIDOMCharacterData> nodeAsText(do_QueryInterface(selNode));
NS_ENSURE_TRUE(nodeAsText, NS_OK);
nodeAsText->ReplaceData(mLastStart, mLastLength, hiddenText);
selNode->GetAsText()->ReplaceData(mLastStart, mLastLength, hiddenText);
selection->Collapse(selNode, start);
if (start != end) {
selection->Extend(selNode, end);
@@ -1431,9 +1425,9 @@ TextEditRules::CreateMozBR(nsIDOMNode* inParent,
NS_ENSURE_SUCCESS(rv, rv);
// give it special moz attr
nsCOMPtr<nsIDOMElement> brElem = do_QueryInterface(brNode);
nsCOMPtr<Element> brElem = do_QueryInterface(brNode);
if (brElem) {
rv = mTextEditor->SetAttribute(brElem, NS_LITERAL_STRING("type"),
rv = mTextEditor->SetAttribute(brElem, nsGkAtoms::type,
NS_LITERAL_STRING("_moz"));
NS_ENSURE_SUCCESS(rv, rv);
}
+6 -6
View File
@@ -310,9 +310,9 @@ TextEditor::UpdateMetaCharset(nsIDOMDocument* aDocument,
}
// set attribute to <original prefix> charset=text/html
nsCOMPtr<nsIDOMElement> metaElement = do_QueryInterface(metaNode);
RefPtr<Element> metaElement = metaNode->AsElement();
MOZ_ASSERT(metaElement);
rv = EditorBase::SetAttribute(metaElement, NS_LITERAL_STRING("content"),
rv = EditorBase::SetAttribute(metaElement, nsGkAtoms::content,
Substring(originalStart, start) +
charsetEquals +
NS_ConvertASCIItoUTF16(aCharacterSet));
@@ -1621,8 +1621,8 @@ TextEditor::GetDOMEventTarget()
nsresult
TextEditor::SetAttributeOrEquivalent(nsIDOMElement* aElement,
const nsAString& aAttribute,
TextEditor::SetAttributeOrEquivalent(Element* aElement,
nsIAtom* aAttribute,
const nsAString& aValue,
bool aSuppressTransaction)
{
@@ -1630,8 +1630,8 @@ TextEditor::SetAttributeOrEquivalent(nsIDOMElement* aElement,
}
nsresult
TextEditor::RemoveAttributeOrEquivalent(nsIDOMElement* aElement,
const nsAString& aAttribute,
TextEditor::RemoveAttributeOrEquivalent(Element* aElement,
nsIAtom* aAttribute,
bool aSuppressTransaction)
{
return EditorBase::RemoveAttribute(aElement, aAttribute);
+11 -8
View File
@@ -63,14 +63,17 @@ public:
// nsIEditorMailSupport overrides
NS_DECL_NSIEDITORMAILSUPPORT
// Overrides of EditorBase interface methods
NS_IMETHOD SetAttributeOrEquivalent(nsIDOMElement* aElement,
const nsAString& aAttribute,
const nsAString& aValue,
bool aSuppressTransaction) override;
NS_IMETHOD RemoveAttributeOrEquivalent(nsIDOMElement* aElement,
const nsAString& aAttribute,
bool aSuppressTransaction) override;
// Overrides of EditorBase
virtual nsresult RemoveAttributeOrEquivalent(
Element* aElement,
nsIAtom* aAttribute,
bool aSuppressTransaction) override;
virtual nsresult SetAttributeOrEquivalent(Element* aElement,
nsIAtom* aAttribute,
const nsAString& aValue,
bool aSuppressTransaction) override;
using EditorBase::RemoveAttributeOrEquivalent;
using EditorBase::SetAttributeOrEquivalent;
NS_IMETHOD Init(nsIDOMDocument* aDoc, nsIContent* aRoot,
nsISelectionController* aSelCon, uint32_t aFlags,
@@ -1,6 +1,6 @@
en_US-mozilla Hunspell Dictionary
Generated from SCOWL Version 2017.01.22
Tue Jan 24 22:59:28 EST 2017
Generated from SCOWL Version 2019.10.06
Fri Feb 7 12:44:15 EST 2020
http://wordlist.sourceforge.net
@@ -95,10 +95,10 @@ released as part of Geoff Kuenning's Ispell and as such is covered by
his BSD license. Part of SCOWL is also based on Ispell thus the
Ispell copyright is included with the SCOWL copyright.
The collective work is Copyright 2000-2016 by Kevin Atkinson as well
The collective work is Copyright 2000-2018 by Kevin Atkinson as well
as any of the copyrights mentioned below:
Copyright 2000-2016 by Kevin Atkinson
Copyright 2000-2018 by Kevin Atkinson
Permission to use, copy, modify, distribute and sell these word
lists, the associated scripts, the output created from the scripts,
@@ -344,4 +344,4 @@ and Australian word list. It is under the following copyright:
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
Build Date: Tue Jan 24 22:59:28 EST 2017
Build Date: Fri Feb 7 12:44:15 EST 2020
File diff suppressed because it is too large. Load diff
@@ -1,6 +1,6 @@
en_US-custom Hunspell Dictionary
Generated from SCOWL Version 2017.01.22
Tue Jan 24 22:59:27 EST 2017
Generated from SCOWL Version 2019.10.06
Fri Feb 7 12:44:14 EST 2020
http://wordlist.sourceforge.net
@@ -95,10 +95,10 @@ released as part of Geoff Kuenning's Ispell and as such is covered by
his BSD license. Part of SCOWL is also based on Ispell thus the
Ispell copyright is included with the SCOWL copyright.
The collective work is Copyright 2000-2016 by Kevin Atkinson as well
The collective work is Copyright 2000-2018 by Kevin Atkinson as well
as any of the copyrights mentioned below:
Copyright 2000-2016 by Kevin Atkinson
Copyright 2000-2018 by Kevin Atkinson
Permission to use, copy, modify, distribute and sell these word
lists, the associated scripts, the output created from the scripts,
@@ -344,5 +344,5 @@ and Australian word list. It is under the following copyright:
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
Build Date: Tue Jan 24 22:59:27 EST 2017
Build Date: Fri Feb 7 12:44:14 EST 2020
With Input Command: ../mk-list -v1 --accents=both en_US 60
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+2 -1
View File
@@ -14,6 +14,7 @@
#include "FilterNodeD2D1.h"
#include "ExtendInputEffectD2D1.h"
#include "Tools.h"
#include "nsWindowsHelpers.h"
using namespace std;
@@ -1177,7 +1178,7 @@ DrawTargetD2D1::GetDWriteFactory()
}
decltype(DWriteCreateFactory)* createDWriteFactory;
HMODULE dwriteModule = LoadLibraryW(L"dwrite.dll");
HMODULE dwriteModule = LoadLibrarySystem32(L"dwrite.dll");
createDWriteFactory = (decltype(DWriteCreateFactory)*)
GetProcAddress(dwriteModule, "DWriteCreateFactory");
-53
View File
@@ -264,30 +264,6 @@ private:
bool mHasValidCache;
};
class BatteryObserversManager : public CachingObserversManager<BatteryInformation>
{
protected:
void EnableNotifications() {
PROXY_IF_SANDBOXED(EnableBatteryNotifications());
}
void DisableNotifications() {
PROXY_IF_SANDBOXED(DisableBatteryNotifications());
}
void GetCurrentInformationInternal(BatteryInformation* aInfo) {
PROXY_IF_SANDBOXED(GetCurrentBatteryInformation(aInfo));
}
};
static BatteryObserversManager&
BatteryObservers()
{
static BatteryObserversManager sBatteryObservers;
AssertMainThread();
return sBatteryObservers;
}
class NetworkObserversManager : public CachingObserversManager<NetworkInformation>
{
protected:
@@ -356,35 +332,6 @@ ScreenConfigurationObservers()
return sScreenConfigurationObservers;
}
void
RegisterBatteryObserver(BatteryObserver* aObserver)
{
AssertMainThread();
BatteryObservers().AddObserver(aObserver);
}
void
UnregisterBatteryObserver(BatteryObserver* aObserver)
{
AssertMainThread();
BatteryObservers().RemoveObserver(aObserver);
}
void
GetCurrentBatteryInformation(BatteryInformation* aInfo)
{
AssertMainThread();
*aInfo = BatteryObservers().GetCurrentInformation();
}
void
NotifyBatteryChange(const BatteryInformation& aInfo)
{
AssertMainThread();
BatteryObservers().CacheInformation(aInfo);
BatteryObservers().BroadcastCachedInformation();
}
bool GetScreenEnabled()
{
AssertMainThread();
-24
View File
@@ -10,7 +10,6 @@
#include "base/basictypes.h"
#include "base/platform_thread.h"
#include "nsTArray.h"
#include "mozilla/dom/battery/Types.h"
#include "mozilla/dom/MozPowerManagerBinding.h"
#include "mozilla/dom/network/Types.h"
#include "mozilla/dom/power/Types.h"
@@ -87,29 +86,6 @@ void Vibrate(const nsTArray<uint32_t>& pattern,
void CancelVibrate(nsPIDOMWindowInner* aWindow);
void CancelVibrate(const hal::WindowIdentifier &id);
/**
* Inform the battery backend there is a new battery observer.
* @param aBatteryObserver The observer that should be added.
*/
void RegisterBatteryObserver(BatteryObserver* aBatteryObserver);
/**
* Inform the battery backend a battery observer unregistered.
* @param aBatteryObserver The observer that should be removed.
*/
void UnregisterBatteryObserver(BatteryObserver* aBatteryObserver);
/**
* Returns the current battery information.
*/
void GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInfo);
/**
* Notify of a change in the battery state.
* @param aBatteryInfo The new battery information.
*/
void NotifyBatteryChange(const hal::BatteryInformation& aBatteryInfo);
/**
* Determine whether the device's screen is currently enabled.
*/
-325
View File
@@ -1,325 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim set: sw=2 ts=2 et lcs=trail\:.,tab\:>~ : */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#import <CoreFoundation/CoreFoundation.h>
#import <IOKit/ps/IOPowerSources.h>
#import <IOKit/ps/IOPSKeys.h>
#include <mozilla/Hal.h>
#include <mozilla/dom/battery/Constants.h>
#include <mozilla/Services.h>
#include <nsIObserverService.h>
#include <nsIObserver.h>
#include <dlfcn.h>
#define IOKIT_FRAMEWORK_PATH "/System/Library/Frameworks/IOKit.framework/IOKit"
#ifndef kIOPSTimeRemainingUnknown
#define kIOPSTimeRemainingUnknown ((CFTimeInterval)-1.0)
#endif
#ifndef kIOPSTimeRemainingUnlimited
#define kIOPSTimeRemainingUnlimited ((CFTimeInterval)-2.0)
#endif
using namespace mozilla::dom::battery;
namespace mozilla {
namespace hal_impl {
typedef CFTimeInterval (*IOPSGetTimeRemainingEstimateFunc)(void);
class MacPowerInformationService
{
public:
static MacPowerInformationService* GetInstance();
static void Shutdown();
static bool IsShuttingDown();
void BeginListening();
void StopListening();
static void HandleChange(void *aContext);
~MacPowerInformationService();
private:
MacPowerInformationService();
// The reference to the runloop that is notified of power changes.
CFRunLoopSourceRef mRunLoopSource;
double mLevel;
bool mCharging;
double mRemainingTime;
bool mShouldNotify;
friend void GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInfo);
static MacPowerInformationService* sInstance;
static bool sShuttingDown;
static void* sIOKitFramework;
static IOPSGetTimeRemainingEstimateFunc sIOPSGetTimeRemainingEstimate;
};
void* MacPowerInformationService::sIOKitFramework;
IOPSGetTimeRemainingEstimateFunc MacPowerInformationService::sIOPSGetTimeRemainingEstimate;
/*
* Implementation of mozilla::hal_impl::EnableBatteryNotifications,
* mozilla::hal_impl::DisableBatteryNotifications,
* and mozilla::hal_impl::GetCurrentBatteryInformation.
*/
void
EnableBatteryNotifications()
{
if (!MacPowerInformationService::IsShuttingDown()) {
MacPowerInformationService::GetInstance()->BeginListening();
}
}
void
DisableBatteryNotifications()
{
if (!MacPowerInformationService::IsShuttingDown()) {
MacPowerInformationService::GetInstance()->StopListening();
}
}
void
GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInfo)
{
MacPowerInformationService* powerService = MacPowerInformationService::GetInstance();
aBatteryInfo->level() = powerService->mLevel;
aBatteryInfo->charging() = powerService->mCharging;
aBatteryInfo->remainingTime() = powerService->mRemainingTime;
}
bool MacPowerInformationService::sShuttingDown = false;
/*
* Following is the implementation of MacPowerInformationService.
*/
MacPowerInformationService* MacPowerInformationService::sInstance = nullptr;
namespace {
struct SingletonDestroyer final : public nsIObserver
{
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
private:
~SingletonDestroyer() {}
};
NS_IMPL_ISUPPORTS(SingletonDestroyer, nsIObserver)
NS_IMETHODIMP
SingletonDestroyer::Observe(nsISupports*, const char* aTopic, const char16_t*)
{
MOZ_ASSERT(!strcmp(aTopic, "xpcom-shutdown"));
MacPowerInformationService::Shutdown();
return NS_OK;
}
} // namespace
/* static */ MacPowerInformationService*
MacPowerInformationService::GetInstance()
{
if (sInstance) {
return sInstance;
}
sInstance = new MacPowerInformationService();
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs) {
obs->AddObserver(new SingletonDestroyer(), "xpcom-shutdown", false);
}
return sInstance;
}
bool
MacPowerInformationService::IsShuttingDown()
{
return sShuttingDown;
}
void
MacPowerInformationService::Shutdown()
{
sShuttingDown = true;
delete sInstance;
sInstance = nullptr;
}
MacPowerInformationService::MacPowerInformationService()
: mRunLoopSource(nullptr)
, mLevel(kDefaultLevel)
, mCharging(kDefaultCharging)
, mRemainingTime(kDefaultRemainingTime)
, mShouldNotify(false)
{
// IOPSGetTimeRemainingEstimate (and the related constants) are only available
// on 10.7, so we test for their presence at runtime.
sIOKitFramework = dlopen(IOKIT_FRAMEWORK_PATH, RTLD_LAZY | RTLD_LOCAL);
if (sIOKitFramework) {
sIOPSGetTimeRemainingEstimate =
(IOPSGetTimeRemainingEstimateFunc)dlsym(sIOKitFramework, "IOPSGetTimeRemainingEstimate");
} else {
sIOPSGetTimeRemainingEstimate = nullptr;
}
}
MacPowerInformationService::~MacPowerInformationService()
{
MOZ_ASSERT(!mRunLoopSource,
"The observers have not been correctly removed! "
"(StopListening should have been called)");
if (sIOKitFramework) {
dlclose(sIOKitFramework);
}
}
void
MacPowerInformationService::BeginListening()
{
// Set ourselves up to be notified about changes.
MOZ_ASSERT(!mRunLoopSource, "IOPS Notification Loop Source already set up. "
"(StopListening should have been called)");
mRunLoopSource = ::IOPSNotificationCreateRunLoopSource(HandleChange, this);
if (mRunLoopSource) {
::CFRunLoopAddSource(::CFRunLoopGetCurrent(), mRunLoopSource,
kCFRunLoopDefaultMode);
// Invoke our callback now so we have data if GetCurrentBatteryInformation is
// called before a change happens.
HandleChange(this);
mShouldNotify = true;
}
}
void
MacPowerInformationService::StopListening()
{
MOZ_ASSERT(mRunLoopSource, "IOPS Notification Loop Source not set up. "
"(StopListening without BeginListening)");
::CFRunLoopRemoveSource(::CFRunLoopGetCurrent(), mRunLoopSource,
kCFRunLoopDefaultMode);
mRunLoopSource = nullptr;
}
void
MacPowerInformationService::HandleChange(void* aContext) {
MacPowerInformationService* power =
static_cast<MacPowerInformationService*>(aContext);
CFTypeRef data = ::IOPSCopyPowerSourcesInfo();
if (!data) {
::CFRelease(data);
return;
}
// Get the list of power sources.
CFArrayRef list = ::IOPSCopyPowerSourcesList(data);
if (!list) {
::CFRelease(list);
return;
}
// Default values. These will be used if there are 0 sources or we can't find
// better information.
double level = kDefaultLevel;
double charging = kDefaultCharging;
double remainingTime = kDefaultRemainingTime;
// Look for the first battery power source to give us the information we need.
// Usually there's only 1 available, depending on current power source.
for (CFIndex i = 0; i < ::CFArrayGetCount(list); ++i) {
CFTypeRef source = ::CFArrayGetValueAtIndex(list, i);
CFDictionaryRef currPowerSourceDesc = ::IOPSGetPowerSourceDescription(data, source);
if (!currPowerSourceDesc) {
continue;
}
// Get a battery level estimate. This key is required.
int currentCapacity = 0;
const void* cfRef = ::CFDictionaryGetValue(currPowerSourceDesc, CFSTR(kIOPSCurrentCapacityKey));
::CFNumberGetValue((CFNumberRef)cfRef, kCFNumberSInt32Type, &currentCapacity);
// This key is also required.
int maxCapacity = 0;
cfRef = ::CFDictionaryGetValue(currPowerSourceDesc, CFSTR(kIOPSMaxCapacityKey));
::CFNumberGetValue((CFNumberRef)cfRef, kCFNumberSInt32Type, &maxCapacity);
if (maxCapacity > 0) {
level = static_cast<double>(currentCapacity)/static_cast<double>(maxCapacity);
}
// Find out if we're charging.
// This key is optional, we fallback to kDefaultCharging if the current power
// source doesn't have that info.
if(::CFDictionaryGetValueIfPresent(currPowerSourceDesc, CFSTR(kIOPSIsChargingKey), &cfRef)) {
charging = ::CFBooleanGetValue((CFBooleanRef)cfRef);
// Get an estimate of how long it's going to take until we're fully charged.
// This key is optional.
if (charging) {
// Default value that will be changed if we happen to find the actual
// remaining time.
remainingTime = level == 1.0 ? kDefaultRemainingTime : kUnknownRemainingTime;
if (::CFDictionaryGetValueIfPresent(currPowerSourceDesc,
CFSTR(kIOPSTimeToFullChargeKey), &cfRef)) {
int timeToCharge;
::CFNumberGetValue((CFNumberRef)cfRef, kCFNumberIntType, &timeToCharge);
if (timeToCharge != kIOPSTimeRemainingUnknown) {
remainingTime = timeToCharge*60;
}
}
} else if (sIOPSGetTimeRemainingEstimate) { // not charging
// See if we can get a time estimate.
CFTimeInterval estimate = sIOPSGetTimeRemainingEstimate();
if (estimate == kIOPSTimeRemainingUnlimited || estimate == kIOPSTimeRemainingUnknown) {
remainingTime = kUnknownRemainingTime;
} else {
remainingTime = estimate;
}
}
}
break;
}
bool isNewData = level != power->mLevel || charging != power->mCharging ||
remainingTime != power->mRemainingTime;
power->mRemainingTime = remainingTime;
power->mCharging = charging;
power->mLevel = level;
// Notify the observers if stuff changed.
if (power->mShouldNotify && isNewData) {
hal::NotifyBatteryChange(hal::BatteryInformation(power->mLevel,
power->mCharging,
power->mRemainingTime));
}
::CFRelease(data);
::CFRelease(list);
}
} // namespace hal_impl
} // namespace mozilla
Loaded 100 of 209 files, more files were not shown because too many files have changed in this diff. Show more