Compare commits

...
527 Commits
Author SHA1 Message Date
Moonchild 8e2e19d639 Commit hourCycle test. 2023-04-06 22:56:08 +02:00
Moonchild 0379f29f80 Issue #2195 - Implement hourCycle (WIP)
For some reason this is non-functional...
2023-04-06 21:29:39 +02:00
Moonchild 186d4b7132 Merge pull request 'Fix FreeBSD build failure with WebRTC enabled.' (#2193) from dbsoft/UXP:freebsdwebrtc into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2193
2023-04-05 10:15:13 +00:00
Moonchild a85b4739e4 Merge pull request 'Fix build bustage with GCC 9 related to checkExportedNamesForDeclaration' (#2192) from jobbautista9/UXP:2189-followup into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2192
2023-04-05 10:14:24 +00:00
Brian Smith dad82a67d6 No Issue - Fix FreeBSD build failure with WebRTC enabled. 2023-04-05 00:54:29 -05:00
Job Bautista 1359f67e56 PR #2189 - Follow-up: Fix build bustage with GCC 9 related to checkExportedNamesForDeclaration 2023-04-05 13:11:44 +08:00
Moonchild a68e524a90 Merge pull request 'JS: Parser Frontend Refactor' (#2189) from martok/UXP-contrib:mr/frontend-2 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2189
2023-04-04 18:54:15 +00:00
Moonchild e354a428b7 Merge pull request 'Update freetype2 to 2.13.0.' (#2190) from jobbautista9/UXP:freetype2-2.13.0 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2190
2023-04-04 10:38:11 +00:00
Job Bautista 031f4f5504 Issue #1863 - Update freetype2 to 2.13.0. 2023-04-04 14:09:09 +08:00
Martok 98a18afe5b Issue #2173 - Introduce FunctionNode::syntaxKind instead of JSOPs
This moves some "implementation details" to later in the emitter,
and also keeps syntax information available for later use.

Based-on: 1518391/{3+4}
2023-04-03 16:50:25 +02:00
Martok 0c7e7591b7 Issue #2173 - Separate CodeNode into FunctionNode and ModuleNode
ModuleNode only has a body and FunctionNode has many more attributes,
and will get more in the following commit.

Based-on: 1518391/2
2023-04-03 16:50:24 +02:00
Martok c3617331a1 Issue #2173 - Remove unused case/code from function node ops
CodeNodes only ever use 3 JSOPs at this point in time.

Based-on: 1518391/1
2023-04-03 16:50:24 +02:00
Martok 3415e1d32d Issue #2173 - Allow constant folding to see inside functions when using the module pattern
(function() { ... })() IIFE pattern should get its body const-folded. This won't make much
runtime difference on JIT, but can be significant in interpreted code (and saves time for
JIT codegen).

Based-on: m-c 632020
2023-04-03 16:50:24 +02:00
Martok f687581b7f Issue #2173 - Fix remaining ParseNode* in FullParseHandler methods signature
The handlers should use the alias types exclusively in their interface.

Based-on: m-c 1479659/11
2023-04-03 16:50:24 +02:00
Martok 6d9f234c60 Issue #2173 - Add TryNode
This is adjusted from upstream to follow our data structure with PNK_CATCHLIST

Based-on: m-c 1479659/8
2023-04-03 16:50:23 +02:00
Martok 2067485b27 Issue #2173 - Add accessors to LexicalScopeNode
Based-on: m-c 1479659/7
2023-04-03 16:50:23 +02:00
Martok 9cd981b485 Issue #2173 - Add accessors to NullaryNode and change LoopControlStatement arity to PN_LOOP
Based-on: m-c 1479659/6
2023-04-03 16:50:23 +02:00
Martok 88f7cba9c9 Issue #2173 - Add accessors to NameNode, CodeNode, RegExpLiteral, and add NumericLiteral
Based-on: m-c 1479659/{5,9,10}, m-c 1491147
2023-04-03 16:50:23 +02:00
Martok 6cea01f811 Issue #2173 - Add accessors to UnaryNode and subclasses
Based-on: m-c 1479659/4
2023-04-03 16:50:22 +02:00
Martok 0fdd23e0b4 Issue #2173 - Add accessors to BinaryNode and subclasses
Based-on: m-c 1479659/3
2023-04-03 16:50:22 +02:00
Martok ad4b2ecefa Issue #2173 - Add accessors to TernaryNode
Based-on: m-c 1479659/2
2023-04-03 16:50:22 +02:00
Martok cc14ee0148 Issue #2173 - Add accessors to ListNode
Based-on: m-c 1479659/{1,12}
2023-04-03 16:50:22 +02:00
Martok 483420f253 Issue #2173 - Fix return value of MUST_MATCH_TOKEN* macros in Parser methods which returns bool
Based-on: m-c 1479659/0
2023-04-03 16:50:21 +02:00
Martok 4d76651ff2 Issue #2173 - Store the info about the existence of the default case into the switch ParseNode
Based-on: m-c 1477157
2023-04-03 16:50:21 +02:00
Martok 33d29efe43 Issue #2173 - Add a new PNK_PROPERTYNAME to hold location information about property access name
Based-on: m-c 1378808/2
2023-04-03 16:50:21 +02:00
Martok 416d9683fe Issue #2173 - Add a new PNK_ARGUMENTS node type for call argument lists
Also change PNK_GENEXP (not supported by upstream) to a PN_BINARY node

Based-on: m-c 1378808/1
2023-04-03 16:50:06 +02:00
Martok 3481496454 Issue #2173 - Fix exporting array and object binding patterns
Examples:
  export const [name1, name2] = [1, 2];
  export var {...name} = get;

Based-on: m-c 1446811, m-c 1462286
2023-04-03 15:33:21 +02:00
Martok 299090f227 Issue #2155 - Follow-up: Reorder super-property evaluation order per latest spec change
Fix regression from difference between Interpreter (old) and ElemOpEmitter (new). We don't have
any Ion/IC support for these ops.

Based-on: m-c 1472211
2023-04-03 14:52:45 +02:00
Moonchild 9d03184aa2 Merge pull request 'Also use xz compression for packaging FreeBSD builds.' (#2188) from jobbautista9/UXP:freebsd-xz into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2188
2023-04-03 09:40:47 +00:00
Job Bautista 7598e16eaa No issue - FreeBSD builds should also use xz compression for packaging.
Currently it defaults to bzip2, which has been obsolete for us.
2023-04-03 15:46:55 +08:00
Moonchild 85f0301dd8 Merge pull request 'Fix debug build bustage with shared Spidermonkey.' (#2187) from jobbautista9/UXP:62-jsprincipals-debug-fix into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2187
2023-04-02 13:36:39 +00:00
Job Bautista d3ed316788 Issue #62 - Follow-up: Fix debug build bustage with shared Spidermonkey.
A method marked with dllimport shouldn't be defined.
2023-04-02 12:47:04 +08:00
Moonchild 131409a24b Merge pull request 'Increase mozjemalloc page cache size from 1 MiB to 16 MiB.' (#2185) from jobbautista9/UXP:2184-mozjemalloc-12 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2185
2023-04-01 07:37:59 +00:00
Job Bautista 4a052de454 Issue #2184 - Increase mozjemalloc page cache size from 1 MiB to 16 MiB.
We don't need the reduced memory overhead as we are not using e10s. This
should speed up JS by a point according to Speedometer 2.1.
2023-04-01 10:42:03 +08:00
Moonchild c36eae9bf5 Merge pull request 'Add sys/auxv.h to system-headers' (#2183) from jobbautista9/UXP:2181-auxv into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2183
2023-03-30 09:40:57 +00:00
Job Bautista da09b1d972 Issue #2181 - Add sys/auxv.h to system-headers
This should fix getauxval being undefined when building highway on Linux ARM64.
2023-03-30 14:39:44 +08:00
Moonchild 93addf962f Merge pull request 'Fix drawing in titlebar on Mac when building with the Big Sur 11.0 SDK.' (#2182) from dbsoft/UXP:drawintitlebar into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2182
2023-03-29 20:32:48 +00:00
Brian Smith c09fb2cd97 No Issue - Fix drawing in titlebar on Mac when building with the Big Sur 11.0 SDK.
On Intel we build with the 10.12 SDK so this problem is avoided.
Also Pale Moon no longer supports drawing in the titlebar in the front end.
However Basilisk does and built for ARM the tabs were cut off by the native titlebar.
This uses the new APIs introduced in SDK 10.10 and 11.0 to draw in the titlebar.
2023-03-29 02:46:32 -05:00
Moonchild ad7ffc0525 Issue #2180 - Follow-up: Move sentinel check up a bit. 2023-03-28 17:59:19 +02:00
Moonchild 500ece900a Issue #2180 - Add pref to control NSS TLS 1.3 protocol downgrade sentinel 2023-03-28 15:13:09 +02:00
Moonchild f90106bd7e Merge pull request 'Refactor more BytecodeEmitters' (#2179) from martok/UXP-contrib:mr/bce-split2 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2179
2023-03-27 14:10:07 +00:00
Moonchild 5a0b5b05da Merge pull request 'Issue #2175 - Fix build bustage in WebRTC.' (#2177) from tvall43/UXP:master into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2177
2023-03-27 14:08:41 +00:00
Moonchild 77692ac0bf Merge pull request 'Fix JS_SHARED_LIBRARY and always build Spidermonkey and ICU as shared lib in Windows.' (#2164) from jobbautista9/UXP:62-shared-mozjs into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2164
2023-03-27 14:07:14 +00:00
Martok 1a24ac966e Issue #2155 - Add SwitchEmitter
Based-on: m-c 1456006/{0,1}
2023-03-26 20:20:16 +02:00
Martok c26df1a48a Issue #2155 - Move TryEmitter and ForOfLoopControl to TryEmitter.{cpp.h} and ForOfLoopControl.{cpp.h}
Based-on: m-c 1460489/5
2023-03-26 20:20:16 +02:00
Martok 0a2eb24435 Issue #2155 - Move NestableControl classes except ForOfLoopControl to BytecodeControlStructures.{cpp.h}
Based-on: m-c 1460489/3
2023-03-26 20:20:15 +02:00
Martok 2e2855cf04 Issue #2155 - Split Nestable to ds/ and EmitterScope to EmitterScope.{cpp.h}
Based-on: m-c 1351107/17, m-c 1460489/2
2023-03-26 20:20:15 +02:00
Moonchild 73d78767c8 Merge pull request 'Don't reconstruct the parent when tearing down display:contents nodes' (#2178) from 2176 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2178
2023-03-26 18:06:09 +00:00
Timothy Valldeperas 5b6c6b98d2 Issue #2175 - Fix build bustage in WebRTC. 2023-03-26 01:16:13 -05:00
Job Bautista f23839412e Issue #62 - Always build Spidermonkey as shared lib in Windows.
Shared JS is confirmed working fine in Windows after a week of testing.
Non-Windows will have to wait unfortunately. The JS_SHARED_LIBRARY option is
kept for easy testing on those unsupported platforms.
2023-03-26 13:14:59 +08:00
Job Bautista 86b77f1284 Issue #2165 - Disable LNK4217 and LNK4286 warnings when linking ICU as they're too spammy. 2023-03-26 13:14:10 +08:00
Moonchild ecda3426e6 Issue #2176 - Don't reconstruct the parent when tearing down
display:contents nodes with pseudo-elements.

We need to use StyleChildrenIterator which iterates over them, instead.
This is a bit of a hack but we can't always have our cake.

We need to be a bit careful though, since ::before and ::after are owned
by their own frame, and thus could be unbound from the tree or even dead
after removing the frame.

This basically ports bugs 1435566 and 1438467
2023-03-26 00:15:45 +01:00
Moonchild eae71465d0 Merge pull request 'Don't discard event state mask when matching ::slotted() or :host arguments' (#2174) from FranklinDM/UXP-contrib:work_css-host-slotted-retain-event-states into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2174
2023-03-24 12:18:15 +00:00
Job Bautista 19b76a68ac Issue #324 - Follow-up: Remove more traces of *INTL_API.
The trace in Spidermonkey's old-configure is causing the MOZ_CONFIG_ICU function
to be called twice, which is not desirable as it can cause the MOZ_SHARED_ICU
check in build/autoconf/icu.m4 to fail and build an ICU data file even if we're
building ICU as a shared library.
2023-03-24 20:12:47 +08:00
FranklinDM 9365fbd8ad Issue #2135 - Don't discard event state mask when matching ::slotted() or :host arguments
This should fix issues with selectors like :host(:hover) that continue to be matched although the cursor is no longer hovering over those elements.
2023-03-24 19:39:30 +08:00
Job Bautista 431f782f17 Issue #2165 - Follow-up: Always build ICU as shared lib in Windows. 2023-03-24 17:51:39 +08:00
Job Bautista ee870812ff Revert "Issue #2165 - Follow-up: No longer support bundling the ICU data file into packaging, fold it into the ICU shared library, and always build ICU shared."
This reverts commit 0c63f5a273.
Building shared ICU is currently broken in non-Windows, so we need the option for now.
2023-03-24 17:45:16 +08:00
Moonchild 434379eb34 Issue #2161 - Ctrl + Enter should cause keypress event even though the
key combination doesn't input any character

Currently, we dispatch keypress event when Enter is pressed without
modifiers or only with the Shift key (line break).
However, other browsers dispatch keypress events for Ctrl + Enter also
even if it doesn't cause any text input.

So, we should fire keypress events for Ctrl + Enter, even in strict
keypress dispatching mode. Note that with other modifiers, it depends on
the browser and/or platform and we can't dispatch the event for
consistent behavior.

This means web developers shouldn't rely one keypress events to catch
Alt + Enter, Meta + Enter and two or more modifiers + Enter.

Based on BZ 1438133
Resolves #2161
2023-03-23 22:35:03 +01:00
Moonchild 2f3f8e13eb Merge branch 'css-slotted-pseudo-rebased' 2023-03-23 12:46:34 +01:00
FranklinDM ef7ff8da4b Issue #1592 - Follow-up: Don't post a restyle event if restyleElement is null
This fixes a potential crash caused if restyleElement is null.
2023-03-23 12:18:04 +01:00
FranklinDM 2733585a3f Issue #1592 - Part 10: Slot elements should restyle their parent on attribute changes 2023-03-23 12:18:04 +01:00
FranklinDM 039b67f6c6 Issue #1592 - Part 9: Post a restyle event after changing the slot of a slottable 2023-03-23 12:18:03 +01:00
FranklinDM c0e6ba933e Issue #1592 - Part 8: Test the assigned slot for type/class/ID/attribute instead of the slottable when matching ::slotted() 2023-03-23 12:18:02 +01:00
FranklinDM 4665c79582 Issue #1592 - Part 7: Slottables cannot be matched from the outer tree. 2023-03-23 12:18:02 +01:00
FranklinDM 7c82808510 Issue #1592 - Part 6: Allow pseudo-classes with a forgiving selector list argument to follow pseudo-elements
Pseudo-classes with a forgiving selector list argument are allowed to follow a pseudo-element, but must treat any selector that is not of the same type as invalid. It doesn't make any sense, but that's the behavior of other tainted browsers.
2023-03-23 12:18:01 +01:00
FranklinDM c5cb2983e6 Issue #1592 - Part 5: Use flattened element tree when looking for a parent while matching ::slotted() 2023-03-23 12:18:01 +01:00
FranklinDM 9c5999c8bc Issue #1592 - Part 4: Walk ::slotted()-containing rules for slottables
- Check against all selector parts and not the leftmost selector only for ::slotted()
- Walk rules for ::slotted() regardless if the shadow root is opened/closed
- Ensure that ::slotted() rules are walked in the right order
- Fix ::slotted inheritance from topmost shadow root
2023-03-23 12:18:00 +01:00
FranklinDM 8313fea7c5 Issue #1592 - Part 3: Ensure only tree-abiding pseudo-elements will follow ::slotted() 2023-03-23 12:17:59 +01:00
FranklinDM 5fc444a0b6 Issue #1592 - Part 2: Parse ::slotted() pseudo-element as if it were a pseudo-class
- Block slot elements from being matched by ::slotted
- Ensure ::slotted() is serialized as a pseudo-element
- Add pref to control whether the pseudo-class is enabled
2023-03-23 12:17:59 +01:00
FranklinDM d2be38e92b Issue #1592 - Part 1c: Pass SelectorParsingFlags as a reference 2023-03-23 12:17:58 +01:00
FranklinDM fc5d7a94b7 Issue #1592 - Part 1b: Move <slot> UA rule to html.css
Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1468127
2023-03-23 12:17:58 +01:00
FranklinDM 8206716e8d Issue #1592 - Part 1a: Prevent crashing if a slot element was selected via DOM Inspector 2023-03-23 12:17:57 +01:00
Moonchild 376bae925b Merge branch 'master' of https://repo.palemoon.org/MoonchildProductions/UXP 2023-03-23 01:57:44 +01:00
Moonchild 494ec06817 Merge pull request 'Follow-up: Fix :host matching from inside the shadow tree' (#2169) from FranklinDM/UXP-contrib:work_css-host-in-shadow-tree-followup into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2169
2023-03-23 00:33:59 +00:00
FranklinDM ef8565458e Issue #2061 - Follow-up: Silence compiler warnings for libjxl 2023-03-23 01:12:42 +01:00
Moonchild 537a5d447e Issue #2171 - Skip over shadow nodes that don't have an owning node.
Resolves #2171
2023-03-23 00:29:13 +01:00
Moonchild da24537414 Merge pull request 'Port ByteCodeEmitter helper classes' (#2159) from martok/UXP-contrib:mr/bce-emitters into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2159
2023-03-22 16:20:08 +00:00
FranklinDM 9700f5557b Issue #1593 - Follow-up: Fix :host matching from inside the shadow tree
Previously, we'd match :host despite the element having a different shadow root from the one that we currently have. Also, there's a test where :host should be blocked from matching if it is a descendant of an explicit universal selector.
2023-03-20 20:15:13 +08:00
Job Bautista 0c63f5a273 Issue #2165 - Follow-up: No longer support bundling the ICU data file into packaging, fold it into the ICU shared library, and always build ICU shared.
This removes two variables in the build system: MOZ_ICU_DATA_ARCHIVE and
MOZ_SHARED_ICU.
Per discussion in PR #2164, it's now preferred to fold the ICU data into the new
shared library.
This effectively means --enable-shared-icu is no longer a thing. UXP apps must
update their packaging manifest to avoid breakage.
2023-03-19 10:55:00 +08:00
Moonchild 16baa04533 Revert "[widget] Linux GTK3: Detach accessible from moz_container before it's deleted"
This reverts commit 465a18f342.
Resolves #2168
2023-03-18 19:57:19 +01:00
Job Bautista eac3436960 Issue #2165 - Build ICU as a shared library if we're building Spidermonkey shared.
It seems that if we're going to enable JS_SHARED_LIBRARY, we need ICU to be a
shared library too in order to prevent code duplication in mozjs.dll bloating
it to a whopping 21 MB.
This unfortunately means we have to fold icudata back to icu itself. But since
icudata is still separated from libxul (which is what really matters for #1451),
I think this is a fair compromise.
Building ICU as shared is offered as an option via --enable-shared-icu. But
technically you really need --enable-shared-icu if you're going to use
--enable-shared-js. Unfortunately I can't make configure exit with an error if
MOZ_SHARED_ICU is not defined when JS_SHARED_LIBRARY is enabled, because options
are controlled by different configure scripts (icu is based on bash, while js is
based on python), and I have no idea how to pass MOZ_SHARED_ICU to js's
moz.configure.

Tag #62
2023-03-19 00:16:46 +08:00
Moonchild 09513970d8 Issue #2166 - Follow-up: Fix style nits. 2023-03-18 15:35:38 +01:00
Moonchild 1a19248860 Merge pull request 'Remove mozilla::AlignedStorage' (#2167) from FranklinDM/UXP-contrib:work_remove-aligned-storage into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2167
2023-03-18 14:24:31 +00:00
Moonchild df5696425e Issue #2117 - Follow-up: Run precomplete cmd during package staging
We rely on this for all OSes except Mac where precomplete should not
be in the root (it uses Mozilla's fallback packaging that places it in
$RESPATH)
2023-03-17 22:10:59 +01:00
FranklinDM d8a518b4db Issue #2166 - Part 6: Remove mozilla::AlignedStorage
Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1341951
2023-03-17 20:29:23 +08:00
FranklinDM a343d564a6 Issue #2166 - Part 5c: Use override keyword for all virtual methods of Recover Instructions
Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1341951
2023-03-17 20:29:22 +08:00
FranklinDM 5d6aca7e55 Issue #2166 - Part 5b: Replace RInstructionStorage copy by a cloneInto function on every RInstruction
Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1341951
2023-03-17 20:29:22 +08:00
FranklinDM 705e2e17be Issue #2166 - Part 5a: Use alignas/alignof inside RInstructionStorage
Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1341951
2023-03-17 20:29:21 +08:00
FranklinDM 53adec5e96 Issue #2166 - Part 4: Use alignas/alignof to define Variant's internal raw storage
Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1338374
2023-03-17 20:29:20 +08:00
FranklinDM 88d2d5eef6 Issue #2166 - Part 3: Make tl::Min/Max variadic
Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1338374
2023-03-17 20:29:19 +08:00
FranklinDM 5e6a0efb65 Issue #2166 - Part 2: Use alignas/alignof in MaybeOneOf
Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1338374
2023-03-17 20:29:19 +08:00
FranklinDM 0c35e43441 Issue #2166 - Part 1: Use alignas/alignof for public JS::ProfilingFrameIterator's internal storage
... of a private wasm or JIT profiling frame iterator.

Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1338374
2023-03-17 20:29:18 +08:00
Moonchild 9477683481 Issue #1911 - Follow-up: Filter out illegal file extensions also.
We already did this for file names, just not extensions.
2023-03-16 17:14:07 +01:00
Moonchild 465a18f342 [widget] Linux GTK3: Detach accessible from moz_container before it's deleted 2023-03-16 16:49:56 +01:00
Moonchild 4435cfeeae [GFX] Add some sanity checks and clamps to SurfaceData calculations. 2023-03-16 14:39:31 +01:00
Moonchild 8577fab815 No Issue - Ensure more OsiSpace
ensureOsiSpace(); was very much under-used. This adds more instances
where it makes sense to ensure Osi space before placing masm calls.
2023-03-16 13:38:26 +01:00
Job Bautista 972e0410ca Issue #62 - Fix xul.dll link bustage related to JS::ubi::DominatorTree.
This is the one I don't understand how it fixed the bustage. Why is it needed
to remove JS_PUBLIC_API..? It would seem counter-intuitive, but it wasn't...
2023-03-16 14:02:16 +08:00
Job Bautista b805d9da66 Issue #62 - Fix xul.dll link bustage relating to JSErrorNotes. 2023-03-16 14:02:16 +08:00
Job Bautista 948268ffde Issue #62 - Fix xul.dll link bustage related to MovableCellHasher.
The unsafeSet method is based on Jon Coppeard's part 2 patch for Mozilla bug
1306008. This is needed because of the use of unsafeSet in rekey() of
MovableCellHasher<JS::Heap<T>>
2023-03-16 14:02:16 +08:00
Job Bautista bddc8b630c Issue #62 - Get --enable-shared-js and --enable-export-js working again, and fix link bustage related to ICU when doing shared lib 2023-03-16 14:02:16 +08:00
FranklinDM 68f456b5fd Issue #2148 - Shrink Vector from (usually) four pointers in size to three
when no inline storage is used.

See Bug 1338374
2023-03-15 13:02:23 +01:00
FranklinDM 9475b959d7 Issue #2148 - Make Vector not use AlignedStorage for its inline element storage
See Bug 1338374 1/2
2023-03-15 13:01:21 +01:00
Job Bautista 17e261ae9b Issue #2148 - Discard RegExpShared data tables when discarding regexp JIT code.
Based on Mozilla bug 1378736's part 2.
Should fix the double-free.
Follow-up for #2083
2023-03-15 13:00:37 +01:00
Job Bautista 1122d6cba6 Issue #2148 - Don't null out RegExpObject -> RegExpShared pointer on GC.
Follow-up for issue #2083.
Taken from Mozilla bug 1378736.
2023-03-15 12:59:35 +01:00
Moonchild 79201ad741 Merge pull request 'Support for notarizing during DMG package.' (#2163) from dbsoft/UXP:macnotarize into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2163
2023-03-15 11:50:34 +00:00
Martok c3a35f75a2 Issue #2155 - Fix wrong assertion
(x) = function() {..} is an extremely sparsely documented way to prevent function name inference.
Modeled after how BytecodeEmitter::emitInitializer does it.
2023-03-15 10:29:12 +01:00
Martok 6bb4747ff3 Issue #2155 - Fix debug build 2023-03-14 23:28:13 +01:00
Brian Smith 26b3d4c151 Issue #2160 - Initial support for notarizing during DMG package.
Added --with-macbundle-idenity configure option to set a codesign identity.
If no identity is set or cross-compiling from Linux no codesigning will be
done. Currently doing a full deep bundle v2 sign, instead of limited v1.
2023-03-14 15:28:51 -05:00
Moonchild 31e7e7e66c Merge pull request 'Fix all deprot in builtin/intl' (#2162) from jobbautista9/UXP:deprot-hunt3 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2162
2023-03-14 16:30:59 +00:00
Job Bautista 396549c5ac Issue #2046 - Follow-up: Fix deprot in builtin/intl
Missing a couple of includes.
Tag #80
2023-03-14 22:39:27 +08:00
Martok 0f87c37c5d Issue #2155 - Remove now-unused functions 2023-03-13 00:37:54 +01:00
Martok 482ef6ac19 Issue #2155 - Fix BytecodeEmitter::emitArguments for our ParseNode tree
This resolves the differences in storage of call arguments between Mozilla's and our ParseNode tree.
2023-03-13 00:37:54 +01:00
Martok b26511f287 Issue #2155 - Add PropOpEmitter, ElemOpEmitter, NameOpEmitter, CallOrNewEmitter
Attn: this plain patch port still contains issues caused by differences in the
ParseNode tree that will be fixed in the following commits.

Based-on: m-c 1466000/{7-10}
2023-03-13 00:37:54 +01:00
Martok da908629c1 Issue #2155 - Refactor BytecodeEmitter in preparation for *Emitter work
This removed a bit of reduncancy and makes stack building easier to follow.

- Move call context handling from BytecodeEmitter::emitGetNameAtLocation to BytecodeEmitter::emitCalleeAndThis
- Add stack comments for prop and elem related methods in BytecodeEmitter
- Remove emitAtopOp with NameNode*
- Pass JSOp to BytecodeEmitter::emitAssignment (modified)
- Add BytecodeEmitter::emitGetFunctionThis variant with offset

Based-on: m-c 1466000/{2-6}
2023-03-13 00:37:53 +01:00
Martok 6a6777e73e Issue #2155 - Simplify BytecodeEmitter::isRestParameter 2023-03-13 00:37:53 +01:00
Martok c7dff3002f Issue #2155 - Split TDZCheckCache, IfEmitter/InternalIfEmitter, JumpList from BytecodeEmitter 2023-03-13 00:37:53 +01:00
FranklinDM 9f009467d8 No issue - Make content-type on JAR channels behave the same as HTTP channels
This ensures that the content type is also determined when opening JAR channels both synchronously and asynchronously. Current m-c modifies only the async portion, while the mentioned commit below modifies only the sync portion. This commit does it for both.

Partially based on 425677ada7 and bug 1757604.
2023-03-12 20:19:03 +01:00
Moonchild d3d61f478c Merge pull request 'Fix some deprots in js' (#2156) from jobbautista9/UXP:deprot-hunt2 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2156
2023-03-12 16:49:59 +00:00
Moonchild 5ed6e2e676 Merge pull request 'Use pre-C++17 static_assert() by adding reason for assert.' (#2157) from dbsoft/UXP:fix_static_assert into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2157
2023-03-12 16:47:59 +00:00
Brian Smith 3089da7aeb No issue - Use pre-C++17 static_assert() by adding reason for assert.
This fixes warnings with clang and build failures with Visual C versions prior to 2022.
2023-03-12 09:20:15 -05:00
Job Bautista 26201f3795 Issue #80 - Move implementation of CPOWTimer::CPOWTimer to header.
Fixes link bustage in xul.dll
Inline functions must be implemented in the header.
2023-03-12 22:04:36 +08:00
Job Bautista 4ca103d1b8 Issue #80 - Fix deprot in js/xpconnect.
I think we never deunified js/xpconnect before. But if we're going to ever build
this tree deunified in the future, there's nothing stopping us now!
2023-03-12 20:26:26 +08:00
Job Bautista 1d594e9b3e Issue #80 - Fix deprot in js/ipc.
I think we never deunified js/ipc before. But if we're going to build this tree
deunified ever in the future, there's nothing stopping us now!
2023-03-12 20:26:26 +08:00
Job Bautista b29ef13cd6 Issue #2046 - Follow-up: Fix deprot in RelativeTimeFormat.
Found while building js/src deunified, with the exception of builtin/intl.
Tag #80.
2023-03-12 20:26:25 +08:00
Moonchild 16c5b95b91 Bump Goanna milestone to 6.1 2023-03-12 10:54:48 +01:00
Moonchild e848bea43f Merge pull request 'Modify :not() selector to accept a complex selector list' (#2151) from FranklinDM/UXP-contrib:work_css-not-selector-list-support into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2151
2023-03-11 17:57:09 +00:00
Moonchild 4c4bc3ca0f Merge pull request 'Destroy the host frame and restyle when there are content changes' (#2152) from FranklinDM/UXP-contrib:work_wc-content-change-fix into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2152
2023-03-11 07:08:38 +00:00
Moonchild 014e4b6e7f Merge pull request 'Follow-up: Ensure empty selector lists aren't iterated when serialized' (#2154) from FranklinDM/UXP-contrib:work_css-empty-selector-list-serialization-fix into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2154
2023-03-11 07:02:24 +00:00
FranklinDM ac589d72a2 Issue #2078 - Follow-up: Ensure empty selector lists aren't iterated when serialized
Really odd that this wasn't caught/doesn't cause any issues on MSVC/unoptimized GCC. Must've been luck, I guess.
2023-03-11 12:09:53 +08:00
FranklinDM 14746314c4 Issue #2135 - Destroy the host frame and restyle when there are content changes
This is likely inefficient, but I haven't found a way other than this to ensure that the host frame is updated if the inserted/removed content isn't slotted. I'm assuming that Firefox is handling this somewhere else (and may have been even moved to Stylo), but was mentioned in an m-c bug we haven't seen yet. In fact, this is actually similar to how we handled elements passed to ContentInserted before landing e31ed5b074.
2023-03-11 00:04:53 +08:00
FranklinDM 18c6aa0252 Issue #2137 - Part 4: Fix namespace regression 2023-03-10 19:14:26 +08:00
FranklinDM 40c9c92116 Issue #2137 - Part 3: Don't always use the internal pseudo-class for handling negations 2023-03-10 19:14:25 +08:00
FranklinDM e9a1859915 Issue #2137 - Part 2: Implement SelectorParsingFlags and use it to pass info around 2023-03-10 19:14:25 +08:00
FranklinDM de225cca0d Issue #2137 - Part 1: Modify :not() selector to accept a complex selector list 2023-03-10 19:14:24 +08:00
Moonchild 476dec2351 Issue #2135 - Follow-up: Check for aElement not being null
This was introduced to Make <link rel="stylesheet"> work in shadow trees.
eElement can, however, be `null` here and if so, it would crash.
2023-03-10 11:44:28 +01:00
Moonchild 1affd523ec Merge pull request 'Root the RegExpShared in RegExpMacroAssembler.' (#2150) from jobbautista9/UXP:2148-rootregexpshared into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2150
2023-03-09 09:02:10 +00:00
Job Bautista 21668cd7d3 Issue #2148 - Root the RegExpShared in RegExpMacroAssembler.
Based on Mozilla bug 1355050.
2023-03-09 14:52:14 +08:00
Moonchild 713ada0ccf Merge pull request 'Follow-up: Ensure document is not null in nsImageLoadingContent::BindToTree' (#2147) from FranklinDM/UXP-contrib:work_wc-image-followup into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2147
2023-03-08 08:28:08 +00:00
FranklinDM a4e18703e9 Issue #2135 - Follow-up: Ensure document is not null in nsImageLoadingContent::BindToTree 2023-03-08 12:14:27 +08:00
Moonchild 9fafaedafb Issue #2146 - Remove nsChannelClassifier/nsIURIClassifier
Resolves #2146
2023-03-08 01:19:47 +01:00
Moonchild e923f5aacd Merge branch 'trackingprotection-cleanup' 2023-03-07 17:38:18 +01:00
Moonchild 3f7b0b7164 Issue #1693 - Follow-up: restore exported NSS symbols for mailnews.
This restores the erroneously-removed CMS* symbol exports, as well as a
few NSS functions that are likely to be used or have utility value in
applications.
2023-03-07 17:36:12 +01:00
Moonchild dd32c96ac6 Issue #2133 - Part 4: Remove TrackingProtection var in classifier. 2023-03-07 11:35:36 +01:00
Moonchild 71a3487554 Issue #2133 - Part 3: Remove TrackingProtection plumbing 2023-03-07 01:37:28 +01:00
Moonchild 517ab728ac Issue #2133 - Part 2: Remove nsIPrivateBrowsingTrackingProtectionWhitelist
This removes the in-memory whitelist for PB mode.
2023-03-07 00:01:58 +01:00
Moonchild 4d38cb76c2 Issue #2133 - Part 1: Remove private browsing TP pref.
This removes selectively enabling TP mode in PB windows.
2023-03-06 22:37:16 +01:00
Moonchild 98e96503e6 Issue #1693 - Follow-up: restore exported NSS symbol for debug builds.
Tag #1382
2023-03-06 15:18:25 +01:00
Moonchild a75c4164e1 Merge pull request 'Implement CSS env() Environment Variables' (#2144) from martok/UXP-contrib:mr/css-env2 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2144
2023-03-06 10:56:05 +00:00
Martok 958b02c358 Issue #2143 - Implement CSS env() Environment Variables 2023-03-05 23:06:55 +01:00
Moonchild 5b9f0fd796 Merge pull request 'Implement CSS inset property' (#2140) from FranklinDM/UXP-contrib:work_css-inset-property into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2140
2023-03-05 21:55:21 +00:00
Moonchild 6cdb875cc5 Merge pull request 'Incremental WebComponents merge' (#2139) from FranklinDM/UXP-contrib:work_wc-incremental-1 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2139
2023-03-05 20:53:16 +00:00
FranklinDM f7e1c71930 Issue #2136 - Part 2: Regenerate devtools CSS database 2023-03-05 07:54:18 +08:00
FranklinDM 3e37869990 Issue #2136 - Part 1: Implement CSS inset property 2023-03-05 07:54:11 +08:00
FranklinDM ce47a81c57 Issue #2135 - Follow-up: Fix potential crash if shadow root is null 2023-03-05 07:41:07 +08:00
Moonchild e7cffa5316 Issue #2046 - correct debug assert for intl_FormatRelativeTime()
Probably fallout from the refactoring in #2109
Tag #1382
2023-03-04 20:42:22 +01:00
FranklinDM 50124e9ea6 Issue #2135 - Follow-up: Fix typo 2023-03-04 23:48:07 +08:00
FranklinDM d8befb4395 Issue #2135 - Follow-up: Fix crash for passing nullptr as an argument to the aNodesWithProperties parameter 2023-03-04 23:45:46 +08:00
Moonchild d38d687150 Merge pull request 'Update NSPR to 4.35 and NSS to 3.79.4' (#2138) from jobbautista9/UXP:1693-nss-nspr-3_79_4-update into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2138
2023-03-04 13:59:11 +00:00
FranklinDM cd76bf5aa1 Issue #2135 - Bug 1433669/Part 2: Flush the document instead of the shell in ContentEventHandler
* Unlike the original patch, I went with just getting a reference to the document rather than replacing mPresShell with mDocument.
2023-03-04 21:32:19 +08:00
FranklinDM 851e691089 Issue #2135 - Bug 1433669/Part 1: Remove dead function 2023-03-04 21:32:18 +08:00
FranklinDM 055ccba3c3 Issue #2135 - Bug 1419803: Use GetComposedDoc instead of GetUncomposedDoc in ContentEventHandler 2023-03-04 21:32:18 +08:00
FranklinDM 6cc4505e14 Issue #2135 - Bug 1425864: Ensure printing documents which have shadow DOM works 2023-03-04 21:32:17 +08:00
FranklinDM 8caa472402 Issue #2135 - Bug 1393806/Part 3: Change dom::ReparentWrapper to take an ErrorResult
* Bug 1393806 (Part 4) landed as part of Issue #1118.
* Account for ReparentWrappersInSubtree, introduced in 1466991
2023-03-04 21:32:17 +08:00
FranklinDM f9ee95f207 Issue #2135 - Bug 1393806/Part 2: Modify AdoptNodeIntoOwnerDoc to use the non-XPCOM version of document.AdoptNode
* Unlike the original patch, this does not remove the XPCOM version of Document.adoptNode/importNode to avoid breaking other applications that might be using those functions.
2023-03-04 21:32:16 +08:00
FranklinDM 88b54a8b67 Issue #2135 - Bug 1393806/Part 1: Change nsNodeUtils cloning/adopting stuff to use an ErrorResult for errors
This will allow us to propagate out more informative errors in some cases.
2023-03-04 21:32:16 +08:00
FranklinDM 744da8ddb3 Issue #2135 - Bug 1414692: Adopt shadow roots when adopting a shadow host across documents 2023-03-04 21:32:15 +08:00
FranklinDM 6a1b4a9e3a Issue #2135 - Bug 1329877: Optimize AncestorFilter usage in lazy frame construction 2023-03-04 21:32:15 +08:00
FranklinDM 7669ddb4b7 Issue #2135 - Bug 1518795: Properly track responsive content in a connected ShadowRoot 2023-03-04 21:32:14 +08:00
FranklinDM 8edbed3761 Issue #2135 - Implement sequential focus navigation for shadow DOM
This covers the following:
Bug 1413834	Implement sequential focus navigation regarding shadow DOM
> Bug 1430020	Let sequential focus navigation in shadow DOM enter iframes
> Bug 1430701	Handle focus navigation on frameless shadow hosts in light DOM
> Bug 1430692	Handle focus navigation on NAC in shadow DOM
> Bug 1453693	Ensure sequential focus navigation works in Shadow DOM and add some tests
> Bug 1466581	Handle sequential focus also in nested shadow DOM
> Bug 1481079	Shadow DOM hosts should be focusable
> Bug 1507101	Use StyleChildrenIterator instead of custom frame tree walking code to handle NAC inside shadow dom
> Bug 1512043	Ensure traverse all nodes owned by the top level shadow host
> Bug 1512457	Fix various cases that focus navigation doesn't work well with frameless shadow host
> Bug 1513141	Really minor nsFocusManager cleanup
> Bug 1519090	Keyboard focus is trapped inside <slot>
> Bug 1528034	Make IsHostOrSlot null-safe
> Bug 1544826	Wrong focus navigation behavior when the root element is a shadow root
>> Bug 1500273	Ensure backward focus navigation works in Shadow DOM
2023-03-04 21:32:14 +08:00
FranklinDM 125b8ae43c Issue #2135 - Bug 1455891/Part 1: Improve StyleChildrenIterator 2023-03-04 21:32:13 +08:00
FranklinDM 59dbe81c92 Issue #2135 - Bug 1410578: Make <link rel="stylesheet"> work in shadow trees 2023-03-04 21:32:13 +08:00
FranklinDM 00c570d27b Issue #2135 - Bug 1453789: Remove Element.createShadowRoot 2023-03-04 21:32:12 +08:00
FranklinDM 2fbefbbc58 Issue #2135 - Bug 1066965: Make contentEditable and spellchecking to work in Shadow DOM 2023-03-04 21:32:12 +08:00
FranklinDM 59b4e5ceb2 Issue #2135 - Bug 1356496: Don't use nsIDOM* in ConfirmSelectionInBody 2023-03-04 21:32:11 +08:00
FranklinDM 6ffdfa793e Issue #2135 - Bug 1430301: Implement ShadowRoot.elementFromPoint/elementsFromPoint 2023-03-04 21:32:11 +08:00
FranklinDM fb9484caa3 Issue #2135 - Bug 1438129: Remove ShadowRoot.applyAuthorStyles. 2023-03-04 21:32:10 +08:00
FranklinDM 4390724666 Issue #2135 - Bug 1323815: FocusEvent.relatedTarget should work consistently with MouseEvent.relatedTarget
* This incorporates changes from Bug 1413102.
2023-03-04 21:32:10 +08:00
FranklinDM a69e82b0d7 Issue #2135 - Bug 1413102 (Follow-up): Ignore current target because of shadow DOM retargeting
Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1466581
2023-03-04 21:32:10 +08:00
FranklinDM 3d82baddf3 Issue #2135 - Bug 1413102: Ensure Shadow DOM boundaries are dealt properly in event handling
* RE: BasicEvents.h - our WidgetEvent is not movable (yet), so the change that requires that wasn't included.
* Parts of this use code that was introduced in bug 1427511. For now, they were replaced with their equivalents.
2023-03-04 21:32:09 +08:00
FranklinDM 60d420fe71 Issue #2135 - Bug 1430305: Implement ShadowRoot.fullscreenElement 2023-03-04 21:32:09 +08:00
FranklinDM 9e2c43705b Issue #2135 - Bug 1430303: Implement ShadowRoot.pointerLockElement 2023-03-04 21:32:08 +08:00
Job Bautista f0e4bf4035 Issue #1693 - Update old-configure and force clobber
NSS 3.79.4 and NSPR 4.35 upgrades require a clobber.
2023-03-04 13:58:00 +08:00
Job Bautista 1c811a1476 Issue #1693 - Update NSS symbols file for 3.79.4 upgrade
Based on latest SeaMonkey's security/nss.symbols, as well as some
unresolved external symbols I found myself.
2023-03-04 13:57:07 +08:00
Job Bautista 43c816cd19 Issue #1693 - Update NSS to 3.79.4 2023-03-04 13:13:49 +08:00
Job Bautista 409d3e66de Issue #1693 - Update NSPR to 4.35 2023-03-04 13:04:26 +08:00
Job Bautista c7aa6e40f6 Issue #1693 - Use scoped enums for IDBTransaction.
Based on a patch from Mozilla bug 1598164.
Needed due to identifier collision between NSS and IDBTransaction.

Co-authored by: Simon Giesecke <simon.giesecke@gmail.com>
Co-authored by: Matt A. Tobin <email@mattatobin.com>
2023-03-04 13:02:13 +08:00
Moonchild 8744033a34 Issue #1361 - Enable WebComponents' getRootNode by default.
Since we're enabling WebComponents, we should enable this too.
TODO: merge the two relevant prefs.
2023-03-01 23:49:34 +01:00
Moonchild 4b7f6babe3 Merge pull request 'CE define must upgrade elements in the shadow-including tree order' (#2134) from FranklinDM/UXP-contrib:work_wc-define-upgrade-in-shadow-including-tree-order into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2134
2023-02-28 08:32:23 +00:00
FranklinDM 059af6d121 Issue #1375 - Part 2: customElements.define must upgrade custom element in shadow-including tree order
Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1326028
2023-02-28 07:48:27 +08:00
FranklinDM 9e2751484a Issue #1375 - Part 1: Allow moving a reference into nsInterfaceHashtable 2023-02-28 07:47:27 +08:00
Moonchild cd86d9ce3f No Issue - Remove speech recognition pref and enable TTS API by default.
Speech recognition was removed a while back. The pref is just leftover.
Having the TTS API available will provide some accessibility benefits
for users, so flip that on while we're here.
2023-02-28 00:42:11 +01:00
Moonchild 6da7d30e76 No Issue - Enable MSE for WebM on all platforms.
WebM is certainly mature enough to have hooked into MSE (default on
Linux and other for years now).
2023-02-28 00:40:26 +01:00
Moonchild 953a2eab75 Issue #1361 - Enable WebComponents by default in the platform. 2023-02-28 00:38:44 +01:00
Moonchild f3c063a868 Issue #2131 - Remove image.webp.enabled preference 2023-02-27 19:27:19 +01:00
Moonchild 41448d401d Merge pull request 'Remove shadow tree hacks in the frame constructor and use correct insertion point during reconstruction' (#2130) from FranklinDM/UXP-contrib:work_sdom-1404789 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2130
2023-02-27 09:20:32 +00:00
FranklinDM 679e53697c Issue #1375 - Follow-up: Get the insertion point right when reconstructing direct children of a shadow root
This should've been changed alongside bug 1404789 when it landed.
2023-02-27 13:15:43 +08:00
FranklinDM 047e44d5c7 Issue #1375 - Follow-up: Remove shadow tree hacks in the frame constructor
This should've been removed alongside bug 1404789 when it landed.
2023-02-27 13:15:37 +08:00
Moonchild eff173129a Merge branch 'full-range-video' 2023-02-26 21:15:12 +01:00
Moonchild a578a28dd8 Merge pull request 'RGB video playback' (#2125) from u3shit/UXP:gbrp-video into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2125
2023-02-26 20:14:03 +00:00
u3shit c64fe52b28 Issue #2101 - Part 7: Add color range support on GPUs 2023-02-26 19:42:14 +01:00
u3shit 338cbff242 Issue #2101 - Part 6: Plumbing of ColorRange between video decoders and YUV convert 2023-02-26 19:42:04 +01:00
u3shit c03bb68372 Issue #2101 - Part 5: Add ColorRange support to video decoders 2023-02-26 19:41:56 +01:00
u3shit e736dc2d34 Issue #2101 - Part 4: Add color range support to gfx/ycbcr
Loosely based on current mozilla code
https://hg.mozilla.org/mozilla-central/file/25a8668d92431d469b443f0f2030328bab754aea/gfx/ycbcr/yuv_convert.cpp
2023-02-26 19:41:47 +01:00
u3shit 8ed007c4e8 Issue #2101 - Part 3: Update libyuv
Updated to version 1861, git revision 88b050f337cc0ca2a51800fe7bf4737222c87344 from
https://chromium.googlesource.com/libyuv/libyuv/
2023-02-26 19:41:38 +01:00
u3shit 466b773179 Issue #2101 - Part 2: Use stdint.h types instead of uint8 and friends
Required for upcoming libyuv update
2023-02-26 19:41:30 +01:00
u3shit 092ff20c60 Issue #2101 - Part 1: Add mColorRange info to YCbCrBuffer
https://hg.mozilla.org/integration/autoland/rev/6f4c7904cda8
2023-02-26 19:41:20 +01:00
u3shit f6e1f851d0 Issue #2118 - Part 2: Add support for Identity YUVColorSpace
https://hg.mozilla.org/mozilla-central/rev/be342c90755d11551623362f2058c0326f63bbb3
2023-02-26 13:04:53 +01:00
u3shit 98fef024cd Issue #2118 - Part 1: Update gfxUtils YuvColorMatrix functions to match upstream mozilla code more closely.
https://hg.mozilla.org/mozilla-central/file/4fba5295dc19f9d2f5d065ba502a44d8f2dc9e85/gfx/thebes/gfxUtils.cpp#l1246
2023-02-26 13:04:53 +01:00
Moonchild c47d20f3f3 Merge pull request 'Fix HTML5 parser behavior when looking for custom elements' (#2129) from FranklinDM/UXP-contrib:work_wc-fix-parser-for-custom-elements into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2129
2023-02-26 10:20:48 +00:00
Moonchild 3e108a2c4e Merge pull request 'Fix :host selector matching' (#2128) from FranklinDM/UXP-contrib:work_css-fix-host-selector-matching into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2128
2023-02-26 10:16:24 +00:00
Moonchild e3275643e2 Merge pull request 'Remove assertion that GetPreEffectsVisualOverflowRect is called only by frames whose parent is an anonymous block' (#2127) from FranklinDM/UXP-contrib:work_css-remove-svg-frame-assertion into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2127
2023-02-26 10:14:07 +00:00
FranklinDM 6c2fef44cf Issue #1344 - (Parser: C++) Don't reset containsHyphen value after finding one 2023-02-26 16:19:09 +08:00
FranklinDM acbce95aa3 Issue #1344 - (Parser: Java) Don't reset containsHyphen value after finding one 2023-02-26 16:19:02 +08:00
FranklinDM 468a37eab8 Issue #1593 - Follow-up: Fix :host selector matching
Previously, we would match `:host` if:
(a) we don't have any arguments and our parent is the shadow root, or;
(b) if any of the arguments match, then reject if we don't have a containing shadow

Revised, we would match `:host` if:
(Preconditions) The element must have a shadow root, the selector must not have any feature selectors, and it is not blocked from matching `:host` (e.g. .matches outside of the shadow root context)
(a) The selector does not have any arguments, or;
(b) It matches any of its arguments in the functional part of the pseudo-class

With this, we now pass these tests that were previously failing:
http://wpt.live/css/css-scoping/css-scoping-shadow-host-rule.html
http://wpt.live/css/css-scoping/host-descendant-002.html
http://wpt.live/css/css-scoping/host-multiple-001.html
Improved (1 less red box):
http://wpt.live/css/css-scoping/css-scoping-shadow-host-namespace.html
2023-02-26 01:32:13 +08:00
FranklinDM 9d7d704523 Issue #1382 - Part 2: Add crash test
Based on https://bugzilla.mozilla.org/show_bug.cgi?id=842114
2023-02-25 11:27:54 +08:00
FranklinDM a28ce48a16 Issue #1382 - Part 1: Remove assertion that GetPreEffectsVisualOverflowRect is called only by frames whose parent is an anonymous block
This is always hit if an SVG effect is applied on other frame types.

Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1340257
2023-02-25 11:27:53 +08:00
Moonchild 630e34a966 Merge pull request 'Cleanup Mac DMG packaging, better naming and remove extra precomplete file.' (#2123) from dbsoft/UXP:Mac2117 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2123
2023-02-24 13:33:54 +00:00
Moonchild fc408bf1e2 Merge pull request 'Propagate combinator restriction to :is()/:where()' (#2122) from FranklinDM/UXP-contrib:work_css-propagate-combinator-restriction into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2122
2023-02-23 09:40:56 +00:00
Moonchild 3a2adcff71 Merge pull request 'Move Has* function definition out of the header file for consistency' (#2121) from FranklinDM/UXP-contrib:work_css-pseudoclass-funcdef-move into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2121
2023-02-23 09:19:20 +00:00
Moonchild dabadd700c Issue #2046 - Follow-up: Fix debug assert using old chars definition. 2023-02-22 22:31:24 +01:00
FranklinDM 826464c80b Issue #2078 - Follow-up: Propagate combinator restriction to :is()/:where()
Based on spec discussion: https://github.com/w3c/csswg-drafts/issues/5093
2023-02-22 14:00:49 +08:00
FranklinDM f17feba05f Issue #2078 - Follow-up: aPreventComplexSelectors should be passed 2023-02-22 14:00:49 +08:00
FranklinDM 4493017fd8 Issue #2078 - Follow-up: Move isForgiving check to ParsePseudoClassWithSelectorListArg 2023-02-22 14:00:43 +08:00
FranklinDM bae06ce171 No issue - Move Has* function definition out of the header file for consistency 2023-02-22 13:51:53 +08:00
Moonchild f2ef28d09c Merge pull request 'Improve :host and :host-context matching' (#2120) from FranklinDM/UXP-contrib:work_css-host-matching-fixes into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2120
2023-02-21 22:56:39 +00:00
Moonchild b9f3a03a5f Merge pull request 'Ensure :host() and :host-context() are given proper weights' (#2119) from FranklinDM/UXP-contrib:work_css-host-and-host-context-specificity into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2119
2023-02-21 22:55:35 +00:00
Moonchild 5b21c547de [DOM] WebCrypto: Check decoded key type before using it.
Just in case someone forces the wrong key type and misuses WebCrypto.
It won't be usable anyway so better to throw.
2023-02-21 21:07:04 +01:00
Moonchild ee7201bbb4 Merge branch 'master' of https://repo.palemoon.org/MoonchildProductions/UXP 2023-02-21 20:29:51 +01:00
Moonchild b2af611dc1 No issue - Refactor FindErrorInstanceOrPrototype
The logic here wasn't very transparent or easy to follow.
Doing a positive check to set the result instead of defaulting to it
also potentially prevents issues.
2023-02-21 20:29:35 +01:00
FranklinDM e0226ccae6 Issue #1593 - Follow-up: Accept only a single selector in the argument of :host/:host-context
Current spec says these two pseudo-classes accept only a single compound selector:
:host( <compound-selector> )
:host-context( <compound-selector> )
2023-02-21 22:50:18 +08:00
FranklinDM 9c1d44f5f6 Issue #1593 - Follow-up: Copy mIsRelevantLink value over rather than calling IsLink
Calling IsLink ignores whatever state we have for aTreeMatchContext and will trigger an assertion if aTreeMatchContext.mForStyling is false. This also adds a comment about what that line effectively does.
2023-02-21 22:50:18 +08:00
FranklinDM ab5a651d55 Issue #1593 - Follow-up: :host() should not automatically match if we have a non-empty selector list 2023-02-21 22:50:17 +08:00
FranklinDM ae59eb00e5 Issue #1823 - Ensure :host() and :host-context() are given proper weights 2023-02-21 22:46:04 +08:00
Moonchild 9d9d93381e Merge pull request 'Implement :is() and :where() CSS pseudo-classes' (#2110) from FranklinDM/UXP-contrib:work_css-is-where into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2110
2023-02-21 12:31:17 +00:00
athenian200 d022966201 Merge pull request 'MailNews: Re-check availability of OAuth2 when hostname fields modified.' (#2052) from blu.256/UXP:fix/mailnews/oauth-custom-domain into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2052
2023-02-21 06:12:19 +00:00
Brian Smith c2ed566b06 Issue #2117 - Part 2 - Revert "Follow up to d0eee8f01 - Run precomplete cmd during package staging"
This reverts commit c622e988fe.
2023-02-20 10:17:49 -06:00
Brian Smith 2f5798b5db Issue #2117 - Part 1 - Update Mac DMG platform names to intel64 for Intel and arm64 for Apple Silicon. 2023-02-20 10:12:47 -06:00
FranklinDM 31c074ce15 Issue #2078 - Part 6: Replace empty list head with the next non-empty list for forgiving selector lists
What happens here if aListHead is an empty selector list:
(1) next selector group is parsed and continues to the next iteration if it's empty or invalid
(2) if we're a forgiving selector list and aListHead is empty, replace it with the selector group that we've just parsed
(3) step 1 ignores invalid/empty, so we assert that step 2 should never have an empty selector list
2023-02-20 23:36:28 +08:00
FranklinDM f19504608e Issue #2078 - Part 5: Ensure :is() and :where() are given proper weights 2023-02-20 23:36:27 +08:00
FranklinDM adc21f14fa Issue #2078 - Part 4: Unify selector list matching
This should allow pseudo-classes that accept selector lists to properly handle complex selectors. `:visited` is also matched inside selector lists.
A previous iteration of this commit had incorrect matching behavior when called from `RestrictedSelectorListMatches`.
2023-02-20 23:36:26 +08:00
FranklinDM 828c8cc46f Issue #2078 - Part 3: Rename nsCSSRuleProcessor::SelectorListMatches to RestrictedSelectorListMatches
This is in preparation for merging the logic of RestrictedSelectorListMatches and AnySelectorInArgListMatches.
2023-02-20 23:35:55 +08:00
FranklinDM bc399f7871 Issue #2078 - Part 2: Rename nsPseudoClassList->u.mSelectors to mSelectorList
This makes it clear that we're accessing a selector list (nsCSSSelectorList), which is different from the selectors (nsCSSSelector) contained inside a selector list. Previously, both were confusingly referred to as mSelectors.
2023-02-20 23:35:54 +08:00
FranklinDM 024b7500d1 Issue #2078 - Part 1: Update CSS rule processor to handle :is() and :where() CSS pseudo-classes
This modifies selector list parsing to accommodate being "forgiving". Aliases for the :is selector's former names were also included. Note that the older and prefixed variant `-moz-any` remains unforgiving.
2023-02-20 23:35:47 +08:00
Moonchild 9b1b294e29 Merge pull request 'Improve fallback handling with mach clobber python command' (#2116) from FranklinDM/UXP-contrib:work_python-clobber-fallback into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2116
2023-02-20 12:24:04 +00:00
Moonchild 33bc5535f2 Merge pull request 'Annotate crash with database name when storage connection not closed' (#2115) from FranklinDM/UXP-contrib:work_js-annotate-crash-with-db-name into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2115
2023-02-20 12:09:47 +00:00
Moonchild 3076df399c Merge pull request 'Fix invalid assert for decoder type if JXL is not built on debug builds' (#2114) from FranklinDM/UXP-contrib:work_jxl-assert-fix-1 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2114
2023-02-20 11:12:10 +00:00
Moonchild aa43190b9a Merge pull request 'Split monolithic Intl.* into separate files' (#2109) from martok/UXP-contrib:mr/intl-split into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2109
2023-02-20 11:07:49 +00:00
FranklinDM ae476cc42c No issue - Improve fallback handling and resolve PATH issues with python clobber command 2023-02-20 17:32:40 +08:00
FranklinDM a434994229 Issue #1382 - Annotate crash with database name when storage connection not closed
Reported on https://bugzilla.mozilla.org/show_bug.cgi?id=1384036
This was fixed with an unrelated issue: https://bugzilla.mozilla.org/show_bug.cgi?id=1372823
2023-02-20 17:25:09 +08:00
FranklinDM 8d980914af Issue #1382 - Fix invalid assert for decoder type if JXL is not built on debug builds 2023-02-20 17:22:16 +08:00
Moonchild 97f69387f4 Merge pull request 'Implement CSSStyleRule.selectorText setter' (#2113) from FranklinDM/UXP-contrib:work_css-stylerule-selectortext-setter into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2113
2023-02-20 08:31:46 +00:00
FranklinDM 8d6c043b89 Issue #2111 - Implement CSSStyleRule.selectorText setter
Unlike the original patch, this copies Chrome behavior: ignores invalid values of selectorText without any console log.

Partially based on https://bugzilla.mozilla.org/show_bug.cgi?id=37468
2023-02-20 12:56:39 +08:00
Moonchild 41bab244fc Force clobber 2023-02-19 17:53:21 +01:00
Moonchild fb73c3aa3b [NSS] Update NSS to 3.52.9 to pick up fixes. 2023-02-19 15:26:44 +01:00
Moonchild 078a424cf3 [DOM] Check whether module load request was already cancelled when a load fails 2023-02-19 13:10:29 +01:00
Moonchild 576ac835f0 [widget] Properly test for and handle errors in target-surface creation
and mapping.
2023-02-19 12:08:17 +01:00
Martok ac4240f055 Issue #2046 - Move a bunch of functions in builtin/intl/CommonFunctions.js into more-specific files, where those functions are only used in a single more-specific file 2023-02-17 00:21:40 +01:00
Martok 233feee823 Issue #2046 - Move builtin/Intl.js (which now contains only shared functionality) to builtin/intl/CommonFunctions.js 2023-02-17 00:07:06 +01:00
Martok df8d3c4b0a Issue #2046 - Move Intl.Collator self-hosted code to a new builtin/intl/Collator.js file 2023-02-17 00:01:59 +01:00
Martok d3abfaff82 Issue #2046 - Move Intl.NumberFormat self-hosted code to a new builtin/intl/NumberFormat.js file 2023-02-17 00:00:36 +01:00
Martok 5cf6aa9065 Issue #2046 - Move Intl.DateTimeFormat self-hosted code to a new builtin/intl/DateTimeFormat.js file 2023-02-17 00:00:21 +01:00
Martok 1491d55375 Issue #2046 - Move Intl.PluralRules self-hosted code to a new builtin/intl/PluralRules.js file 2023-02-16 23:56:35 +01:00
Martok f53901c567 Issue #2046 - Move Intl.RelativeTimeFormat self-hosted code to a new builtin/intl/RelativeTimeFormat.js file 2023-02-16 23:55:05 +01:00
Martok a63ea3fdfb Issue #2046 - Move the self-hosting of non-constructor properties of Intl to a new builtin/intl/IntlObject.js file 2023-02-16 23:53:01 +01:00
Martok fe7e00d47f Issue #2046 - Move various generated files from builtin/Intl* to builtin/intl/*, and add "Generated" to their names for clarity 2023-02-16 23:42:45 +01:00
Martok face1e6e9b Issue #2046 - Move builtin/Intl.* to builtin/intl/IntlObject.* 2023-02-16 22:41:00 +01:00
Martok 22b189727f Issue #2046 - Trim builtin/Intl.*'s #include set down to what is required for Intl itself 2023-02-16 22:24:52 +01:00
Martok 9ad97da85b Issue #2046 - Move Intl.RelativeTimeFormat functionality into builtin/intl/RelativeTimeFormat.* 2023-02-16 21:26:50 +01:00
Martok 5f9d4f115e Issue #2046 - Move Intl.PluralRules functionality into builtin/intl/PluralRules.* 2023-02-16 01:33:43 +01:00
Martok 29e2547f26 Issue #2046 - Move Intl.DateTimeFormat functionality into builtin/intl/DateTimeFormat.* 2023-02-16 00:14:24 +01:00
Martok 24f8c4f052 Issue #2046 - Move SharedIntlData into its own builtin/intl/SharedIntlData.* files so the world doesn't have to import all shared Intl functionality. 2023-02-15 22:58:28 +01:00
Martok 52821c2e85 Issue #2046 - Move Intl.Collator functionality into builtin/intl/Collator.* 2023-02-15 22:32:08 +01:00
Martok 2b0f6aea16 Issue #2046 - Move NewUNumberFormatForPluralRules next to its only use 2023-02-15 22:32:07 +01:00
Martok 31adccdffc Issue #2046 - Move Intl.NumberFormat functionality into builtin/intl/NumberFormat.* 2023-02-15 22:32:07 +01:00
Martok b13cd385a4 Issue #2046 - Create helper method to call ICU string conversion methods
Based-on: m-c 1333844
2023-02-13 01:29:00 +01:00
Martok 3091ff4e57 Issue #2046 - Move functionality used in the implementation of multiple Intl.* constructors into builtin/intl/CommonFunctions.* 2023-02-12 23:27:21 +01:00
Martok 8ca01873c0 Issue #2046 - Move ScopedICUObject into builtin/intl/ScopedICUObject.h 2023-02-12 22:32:41 +01:00
Moonchild 013e19eed6 Merge branch 'master' of https://repo.palemoon.org/MoonchildProductions/UXP 2023-02-11 22:52:55 +01:00
Moonchild 6a353ef32d Issue #1851 - Update TwemojiMozilla to 0.7.0 (Twemoji 14) 2023-02-11 22:52:29 +01:00
Moonchild 05ad5bcb5b Merge pull request 'Clean up caret when destroying editor.' (#2108) from jobbautista9/UXP:2107-caret into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2108
2023-02-11 09:16:39 +00:00
Job BautistaandMakoto Kato 42742eceae Issue #2107 - Clean up caret when destroying editor.
Editor changes caret visibility during drag and drop. But when destroying
editor, we don't restore caret state. So we should restore it when destroying
editor.

Co-authored-by: Makoto Kato <m_kato@ga2.so-net.ne.jp>
2023-02-09 20:51:34 +08:00
Moonchild ffdba3d91e No issue - Accept also video/vp8 as MIME type (bis) 2023-02-08 01:01:25 +01:00
Moonchild 1f32c17fcf No issue - Accept also video/vp8 as MIME type 2023-02-07 19:58:04 +01:00
Moonchild 8b26fcd0de Merge pull request 'Implement XUL crop:clip property value for string cropping' (#2105) from FranklinDM/UXP-contrib:work_xul-crop-clip into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2105
2023-02-04 17:00:04 +00:00
FranklinDM 1a2a779aaf Issue #2104 - Part 2: Indicate if a label was cropped via the "_is_cropped" attribute 2023-02-03 22:44:04 +08:00
FranklinDM dc14e5a906 Issue #2104 - Part 1: Implement "clip" attribute value for XUL string cropping
This implements the "clip" attribute value for the "crop" attribute found in XUL label elements. It functions similarly to having the text-overflow property set to an empty string or "". This shouldn't break previously established behavior as it only adds a new value to be checked.

The behavior of the "none" attribute value in the documentation (https://udn.realityripple.com/docs/Archive/Mozilla/XUL/Attribute/crop) is incorrect. The "none" attribute value literally means "don't crop anything" if you'd check the code and is also equivalent to not setting the "crop" attribute at all. This has always been the case since Firefox 2 (earliest version I checked) and apparently, this section of the documentation was copied verbatim from XULPlanet without even checking if it's correct.
2023-02-03 22:44:04 +08:00
Moonchild fb8347c7d2 Issue #2103 - Fix typo in RegExp Parser
This corrects the typo where the left-hand character would determine if
the right-hand character would be added or not.

Resolves #2103
2023-02-02 10:50:02 +01:00
Moonchild aa0d7fc060 Merge pull request 'Promises pt. 3: Implement Promise.any' (#2102) from martok/UXP-contrib:mr/prom-async-pt3 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2102
2023-02-01 22:52:14 +00:00
Martok 04e13794b2 Issue #2089 - Implement the Promise.any combinator
Based-on: m-c 1568903/9,1560300
2023-02-01 00:02:45 +01:00
Martok 2421d31e02 Issue #2089 - Rename shared Promise combinator functions, with helpers for element functions
Based-on: m-c 1568903/{5-8}
2023-02-01 00:02:45 +01:00
Martok 0148ae5a60 Issue #2089 - Implement AggregateError
Based-on: m-c 1568903/4,1641355(partial),1652148,1643397
2023-02-01 00:02:44 +01:00
Martok ec38c883c6 Issue #2089 - Move ErrorObject parts from jsexn.cpp to ErrorObject.cpp
Based-on: m-c 1568903/2
2023-02-01 00:02:44 +01:00
Martok e3c44ebafa Issue #2089 - Add cache for Promise property lookups
Based-on: m-c 1475678/11
2023-02-01 00:02:44 +01:00
Moonchild c9764f76ec Merge pull request 'Remove unnecessary cast in GeneratorObject::suspend's do loop.' (#2100) from jobbautista9/UXP:2099-generatorobject-cast into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2100
2023-01-31 16:22:02 +00:00
Job Bautista a1d573eb13 Issue #2099 - Remove unnecessary cast in GeneratorObject::suspend's do loop.
This resolves build bustage with --enable-debug.
2023-01-31 20:03:09 +08:00
Moonchild 94e2874370 Merge pull request 'Promises pt. 2: Optimization and Unification' (#2096) from martok/UXP-contrib:mr/prom-async-pt2 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2096
2023-01-31 11:10:03 +00:00
Moonchild a13035b1de Merge pull request 'Make RegExpShared into a proper GC thing' (#2095) from jobbautista9/UXP:2083-regexpshared-gc-final into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2095
2023-01-31 09:46:14 +00:00
Moonchild d7c90a831a [xpcom] remove incorrect assertion.
See https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2095#issuecomment-33796
2023-01-29 19:19:48 +01:00
Moonchild 243c2bd498 No issue - bump default platform UA compatibility mode to 102.0 2023-01-29 19:17:00 +01:00
Moonchild e57d4347cd Issue #1382 - Remove incorrect assertion.
Tag #2090 #2095
2023-01-29 19:16:16 +01:00
Job Bautista 5732cf1f17 Issue #2083 - Follow-up: RegExpShared::source should be a GCPtr.
A hangover from before RegExpShared was a GC thing, as noted by m-c 1399928.
2023-01-28 19:32:24 +08:00
Martok ae4149e7ee Issue #2089 - Report unhandled rejection for optimized away promise
Based-on: m-c 1498775
2023-01-27 19:31:17 +01:00
Job Bautista 40ef2a5756 PR #2090 - Follow-up: Remove invalid MOZ_ASSERT in js::NativeDefineDataProperty
We don't have isHelperThreadContext, and this is breaking debug builds.
2023-01-27 16:47:12 +08:00
Martok 15a0dd6e4c Issue #2089 - Further runtime perf improvements for PromiseState
- Reduce slot size of PromiseReactionRecord to fit into OBJECT8 alloc kind
- Use the Call() helper from Interpreter.h to reduce code duplication
- Clear the incumbent global slot when it's no longer used

Based-on: m-c 1475678/{12-14}
2023-01-27 00:09:15 +01:00
Martok c1b1638522 Issue #2089 - Create a shared helper for PerformPromiseRace, PerformPromiseAll and PerformPromiseAllSettled
Replace the previous non-CommonPerformPromiseAllRace port with the unified one

Based-on: m-c 1475678/10,1539694
2023-01-26 22:33:28 +01:00
Martok c805a6a526 Issue #2089 - Add a PromiseCapability struct, directly initialize dense elements in PerformPromiseAll using NewbornArrayPush
Based-on: m-c 1475678/{8,9}
2023-01-26 22:25:07 +01:00
Martok 82222eb7b4 Issue #2089 - Improve Runtime perf of Promises
- reduce typecasting
- reduce rooting already rooted values
- directly handle unwrapped promises

Based-on: m-c 1475678/{1-7}
2023-01-26 20:54:33 +01:00
Martok 0dc2b249dc Issue #2089 - Don't use BlockOnPromise fast path with non-default resolving functions, combine default resolving functions flags
Based-on: m-c 1474348
2023-01-26 20:54:32 +01:00
Martok f2eeb76969 Issue #2089 - Optimize Promise.then and Promise.all/race with default resolving functions
Based-on: m-c 1401508,1412200,1473970/{1-4}
2023-01-26 20:54:32 +01:00
Martok 6445a1bdb4 Issue #2089 - Turn AsyncGeneratorResumeNext recursion into iteration to avoid stack overflow
Based-on: m-c 1416809
2023-01-26 20:54:32 +01:00
Martok 94df491338 Issue #2089 - Only create result Promises in Promise#then and Promise#catch if it's used or the creation is otherwise observable
Based-on: m-c 1342070
2023-01-26 20:54:31 +01:00
Martok a6ceedf7b2 Issue #2089 - Shrink Promise instances from 8 to 4 slots by moving debug information to an external object
Based-on: m-c 1342050
2023-01-26 20:54:31 +01:00
Job Bautista 47c6fe9cee Revert "Issue #1382 - RegExpShared::groupsTemplate_ cannot be a GCPtr since RegExpShared is managed by C++"
This workaround has been obsoleted by the work on Issue #2083.
This reverts commit bbd7436086.
2023-01-26 15:26:32 +08:00
Job Bautista 64370b64d2 Issue #2083 - Part 5: Fix memory leak in RegExpObject.
Based on Mozilla bug 1345177.
2023-01-26 15:26:32 +08:00
Job Bautista 523201f3e4 Issue #2083 - Part 4: Give RegExpShared a finalizer.
Based on Mozilla bug 1345177.
2023-01-26 15:26:32 +08:00
Job Bautista 997616e308 Issue #2083 - Part 3: Fix RegExpShared rooting hazards now it's a GC thing.
Based on Mozilla bug 1345177.
Changes from the original bug's patch:

- The original patch didn't have a dotAll for a call to irregexp::ParsePattern,
  so let's make our dotAll a member of the MutableHandleRegExpShared re.
- Make RegExpShared::initializeNamedCaptures, introduced in Issue #1285, static.
  This resolves a build bustage where static RegExpShared::compile was trying to
  use a member function.
2023-01-26 15:26:32 +08:00
Job Bautista f5761df1c7 Issue #2083 - Part 2: Remove use of RegExpGuard.
Based on Mozilla bug 1345177.
There were more uses of RegExpGuard in js/src/builtin/RegExp.cpp not found in
 the original bug's patch.
2023-01-26 15:26:31 +08:00
Job Bautista c566c36791 Issue #2083 - Part 1: Make RegExpShared a GC thing.
Based on Mozilla bug 1345177.
Changes from the original bug's patch:

- We don't have JS::CurrentThreadIsHeapCollecting, so let's use
  trc->runtime()->isHeapCollecting() instead.
- Mozilla bug 1337117 renamed runtimeFromMainThread to
  runtimeFromActiveCooperatingThread for Firefox 54, so let's use the former
2023-01-26 15:26:31 +08:00
Moonchild 5a4478b409 Merge pull request 'Fix crash in js::CreateRegExpMatchResult' (#2094) from martok/UXP-contrib:mr/2093-regexp into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2094
2023-01-25 23:02:39 +00:00
Martok cce4862b70 Issue #2093 - Trace HeapPtr<RegExpShared::groupsTemplate_> for GC move/compact events, regression from #2072 2023-01-25 23:22:07 +01:00
Moonchild c06a9ae523 Merge pull request 'Parse \p{Extended_Pictographic} too.' (#2092) from jobbautista9/UXP:2091-extended-pictographic into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2092
2023-01-25 21:46:18 +00:00
Job Bautista aa108a39d6 Issue #2091 - Parse \p{Extended_Pictographic} too.
This is essentially a follow up to Issue #1286. We already have
 UCHAR_EXTENDED_PICTOGRAPHIC in our in-tree ICU, so there's no reason to comment
 this case out.
2023-01-25 16:33:44 +08:00
Moonchild b87775f75a Merge pull request 'Promises pt. 1: Basics' (#2090) from martok/UXP-contrib:mr/prom-async-pt1 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2090
Reviewed-by: Moonchild <moonchild@palemoon.org>
2023-01-23 16:55:39 +00:00
Martok d72c98277b Issue #2089 - Avoid copying/recreating iterator result, AsyncGeneratorRequest and GeneratorObject expression stacks
Based-on: m-c 1394682,1410283,1396499
2023-01-22 00:11:28 +01:00
Martok 9f07ad27f5 Issue #2089 - In Promises, use a C++ version of SpeciesConstructor when calling from C++
Based-on: m-c 1344656,1386534
2023-01-22 00:11:28 +01:00
Martok b1440d285b Issue #2089 - Use JS engine stack if necessary when reporting errors
Based-on: m-c 996060
2023-01-22 00:11:27 +01:00
Martok d78912ec17 No issue - Throw error when resolving or rejecting promise returned by async function with testing function
Based-on: m-c 1418106
2023-01-22 00:11:27 +01:00
Martok d454045363 No issue - add API to tell Profile Timeline Recording state to JS engine
Based-on: m-c 1342070/5
2023-01-21 22:49:10 +01:00
Martok 44adc9e25c No issue - Cleanup unused function exports to self-hosted global
Based-on: m-c 1325696
2023-01-21 22:49:10 +01:00
Martok 7cde54d976 No issue - Remove "code" from jsprototype.h macros
Based-on: m-c 1394084
2023-01-21 00:55:40 +01:00
Martok 13eac0ae3f No issue - reformat GlobalObject::skipDeselectedConstructor 2023-01-21 00:51:34 +01:00
Martok 0d1d366685 No issue - implement js::NativeDefineDataProperty helper 2023-01-21 00:50:37 +01:00
Moonchild 9536cf49ce [DOM] Make nsHTMLContentSerializer handle noscript depending on the
scripting enabled state of the document.
2023-01-18 21:23:40 +01:00
Moonchild bd9042426a [devtools] Improve Copy as cURL
Windows commonly fails to work because of --compressed, and its string
escaping needed improvement because of the complexities of argument
parsing in command windows.
2023-01-18 19:21:26 +01:00
Moonchild 76f10666f4 [DOM] Add some null checks for PerformanceWorkers 2023-01-18 17:54:34 +01:00
Moonchild c8b74d4cbd No issue - factor out some frame iterator helper functions. 2023-01-18 14:08:50 +01:00
Moonchild 25ed473471 [gtk widget] Use text/uri-list for file drag&drop. 2023-01-18 12:32:12 +01:00
Moonchild 304dfb8da2 [network] Avoid queue manipulation inside a loop 2023-01-18 02:26:23 +01:00
Moonchild 2c4410681f Merge pull request 'Re-unify some more missed sources in js/src' (#2088) from jobbautista9/UXP:js-src-80 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2088
Reviewed-by: Moonchild <moonchild@palemoon.org>
2023-01-10 11:22:52 +00:00
Job Bautista 5b3edcd412 Issue #80 - Re-unify some more missed sources in js/src 2023-01-10 15:50:56 +08:00
Moonchild 8dadf744e3 Issue #2087 - Don't throw on lacking PresShell in SetFontInternal
In CanvasRenderingContext2D::SetFontInternal, we should not throw if
there is no PresShell due to (sandboxed/hidden) iframe use that has not
initialized its presentation yet at the time of property manipulation.
This removes the throwing of the error and just silently fails.

Resolves #2087
2023-01-09 10:52:49 +01:00
Moonchild e7268f447a Merge pull request 'Remove CSS unprefixing service' (#2085) from FranklinDM/UXP-contrib:work_css-remove-unprefixing-service into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2085
Reviewed-by: Moonchild <moonchild@palemoon.org>
2023-01-06 15:49:41 +00:00
Moonchild d3830bea8d Merge pull request 'Fix invalid inequality check on assert in RegExpParser' (#2086) from FranklinDM/UXP-contrib:work_regexp-assert-fix into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2086
2023-01-06 15:04:30 +00:00
Moonchild 4ebfc47dff Merge pull request 'Performance Enhancements for Animated Images' (#2081) from martok/UXP-contrib:gfx-gifmem into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2081
2023-01-06 15:02:51 +00:00
FranklinDM 9694f5c216 No issue - Fix invalid neq check on assert in RegExpParser 2023-01-06 22:16:32 +08:00
FranklinDM 1264824127 Issue #2084 - Part 2: Simplify logic in CSSParserImpl::LookupKeywordPrefixAware
Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1259348
2023-01-06 22:13:16 +08:00
FranklinDM b5f8fa6479 Issue #2084 - Part 1: Remove CSSUnprefixingService.js and associated code
It's effectively dead code since it's been supplanted by built-in webkit-prefixed-CSS support (landed before fork point in Firefox 49).

Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1259348
2023-01-06 22:13:08 +08:00
Moonchild af3a27e838 Merge pull request 'Follow-up fixes to #2060' (#2072) from martok/UXP-contrib:irregexp-fix1 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2072
2023-01-06 09:06:56 +00:00
Moonchild 1d4532ac5e Merge pull request 'Fix linking libxul on *nix when using gold, lld, and mold as linker.' (#2082) from jobbautista9/UXP:staticxul-ldmagic into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2082
2023-01-05 17:53:04 +00:00
Job Bautista 2e8442e6ec Issue #2079 - Fix linking libxul on *nix when using a linker other than bfd.
Don't mark the .kPStaticModules section as relro for bfd, as the linkers on
 Windows and Mac don't do this anyway.
Add a section insert of .kPStaticModules to config/expandlibs_exec.py, which
 seems to be the primary cause of linking bustage on gold, lld, and mold.
2023-01-05 13:12:29 +08:00
Martok bbd7436086 Issue #1382 - RegExpShared::groupsTemplate_ cannot be a GCPtr since RegExpShared is managed by C++ 2023-01-04 20:48:25 +01:00
Martok 61dccf9933 Issue #2073 - m-c 1454149: Do not advance animated images which are not displayed 2023-01-04 00:50:26 +01:00
Martok cbcf9b9d8e Issue #2073 - m-c 1546500: Avoid dispatching synchronous thread shutdown runnables 2023-01-04 00:50:17 +01:00
Martok d28497f2cf Issue #2073 - m-c 1651587: Make image::Image release efficient on main thread 2023-01-04 00:50:03 +01:00
Martok 919a966dc2 Issue #2073 - m-c 1383404: make SourceBuffer::Compact more efficient (squashed)
The first part also means that Compact no longer needs the SurfaceCache lock (used to be via CreateChunk->CanHold),
which avoids potential deadlocks during shutdown that m-c 523950 would otherwise cause
2023-01-04 00:49:05 +01:00
Martok b618b3fb76 Issue #2073 - m-c 523950: Discard decoded frames of very large GIF animations (squashed)
Controlled by image.animated.decode-on-demand.threshold-kb, default 256MB

Includes squashed bugfixes/regressions:
 - m-c 1444537: Shutting down the decode pool should make animated decoders bail early
 - m-c 1628606: Make sure to mark the surface cache entry available before sending the frame complete notification
 - m-c 1502275: Skip recreating the decoder after redecode errors if an animated image is reset
 - m-c 1443232: Don't insert frames into our AnimationFrameBuffer that we consider in error and unusable
2023-01-04 00:49:04 +01:00
Martok e7fd4ba61b Issue #2073 - m-c 1343341: Infrastructure necessary to allow discarding of animated images (squashed)
Includes squashed changes of:
 - m-c 1317907: Refactor FrameAnimator::GetCompositedFrame to be a bit simpler
 - m-c 1351434: bugfix
 - m-c 686905: Enable the pref image.mem.animated.discardable to allow discarding of animated images
2023-01-03 02:01:10 +01:00
Martok 608ecc9549 Issue #2073 - m-c 1382683: Accelerate GIF decoding to SurfacePipe
1. Implement SurfacePipe::WritePixelBlocks for faster writing of pixels
2. Switch nsGIFDecoder2 to write pixels in blocks instead of individually
2023-01-03 02:01:10 +01:00
Moonchild 61b688198a Merge pull request 'Implement inset-(block|inline)-(start|end)' (#2076) from css-offset-inset-work into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2076
Reviewed-by: Travis W. <travawine@palemoon.org>
2023-01-01 23:33:27 +00:00
Moonchild 7bcc49489a Issue #2075 - Part 5: Allow logical aliases in the property database. 2022-12-31 10:19:45 +00:00
Moonchild 45193b1a82 Issue #2075 - Part 4: Update tests
* Update reftests to use inset-*
* Update property database
* Update logical properties test
2022-12-31 01:32:15 +00:00
Moonchild f404243371 Issue #2075 - Part 3: Regenerate devtools CSS database
Using `mach devtools-css-db`
2022-12-31 01:30:30 +00:00
Moonchild a943408c35 Issue #2075 - Part 2: Update devtools for inset-* 2022-12-31 01:29:03 +00:00
Moonchild 34ccfbcc0e Issue #2075 - Part 1: Rename offset-* logical properties to inset-*
This adds aliases behind a pref with the old offset-* names
2022-12-30 22:37:02 +00:00
Martok 4731658b7e Follow-up #2060 - Correctly handle \k in non-unicode expressions 2022-12-30 15:27:03 +01:00
Moonchild 4a3caaf522 Merge pull request 'Fix deprot in dom/base and js/src when building them de-unified.' (#2074) from jobbautista9/UXP:deprot-hunt1 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2074
2022-12-29 21:12:51 +00:00
Job Bautista edaddb1e5d Issue #80 - Fix deprot in js/src/irregexp.
Regression seems to have been introduced by PR #2060? This tree didn't fail
 building before we've reinstated unified building for js/src.
Found while building js/src de-unified.
2022-12-29 22:00:18 +08:00
Job Bautista 028e97d11e Issue #80 - Fix deprot in dom/base.
This regression was introduced by my PR #2015.
Found while building dom/base de-unified.
2022-12-29 22:00:07 +08:00
Moonchild a6d113f87b Issue #2053 - Disable DOM Performance API navigation timing.
We may eventually want to make this permanent in the front-end of
Pale Moon for privacy reasons.
Disabling this to avoid usage expecting changed spec results.
2022-12-26 11:21:32 +00:00
Moonchild 413cb600cc Update README 2022-12-25 16:59:18 +00:00
Moonchild 4ed26484ee Issue #2070 - When multiple HSTS headers are received, only consider the first.
This implements a plain interpretations of RFC 6797, which says to only consider
the first HSTS header.
This slightly conflicts with RFC 7230, which says that sending multiple headers
which can't be merged is illegal (except for a specific whitelist which HSTS isn't in),
so this situation should never occur in the first place (and would therefore not need
the explicit entry in RFC 6797).

It improves HSTS robustness dealing with non-compliant servers.

Resolves #2070
2022-12-25 11:42:42 +00:00
Moonchild 2a77e5662d Merge pull request 'Terminate some fallthrough attributes with a semicolon.' (#2071) from jobbautista9/UXP:fallthrough-sc into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2071
2022-12-25 08:27:44 +00:00
Moonchild 1555b1d89c Merge pull request 'Update libjxl to 0.7.0 and highway to 1.0.2.' (#2062) from jobbautista9/UXP:jxl-0.7 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2062
2022-12-25 08:26:16 +00:00
Job Bautista 080877ccec No issue - Fallthrough attributes must be terminated with semicolon.
This also fixes building with Clang 15 on Linux.
2022-12-25 14:50:24 +08:00
Job BautistaandMoonchild dcf9837607 Issue #2061 Follow-up: Fix moz.build to compile on all platforms.
Remove stuff from /extra/ and the JPEG transcoding file from compilation, as
 we don't need them.
A disable define for box decoding is also added, but currently commented out as
 there's no need to disable the function right now.

Co-authored-by: Moonchild <moonchild@palemoon.org>
2022-12-25 11:33:10 +08:00
Moonchild 5de28553a1 Current changes to the platform warrant a new milestone version for Goanna. 2022-12-24 23:36:07 +00:00
Moonchild 6249e60f41 Merge pull request 'Only wrap the last line of inline elements when positively padding to the right.' (#2069) from jobbautista9/UXP:paddingright-linewrap-fix into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2069
2022-12-24 23:22:11 +00:00
Moonchild fb305d451f Merge pull request 'Restore and fix support for FasterMake' (#2066) from FranklinDM/UXP-contrib:work_restore-faster-make into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2066
2022-12-24 20:56:23 +00:00
Moonchild 154b94d350 Merge pull request 'Ensure a floated ::first-letter inherits from ::first-line.' (#2064) from jobbautista9/UXP:first-letter-floatinherit into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2064
2022-12-24 19:29:20 +00:00
Moonchild ea2d754647 Merge pull request 'Replace use of deprecated GetPreventDefault in GTK menu bar' (#2067) from FranklinDM/UXP-contrib:work_gtkmb-defaultprevented into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2067
2022-12-24 19:28:28 +00:00
Job BautistaandJonathan Kew 0063a28576 Issue #2068 - Only wrap the last line of inline elements when positively padding to the right.
This fixes the 21 year old Mozilla bug 122795.

Co-authored-by: Jonathan Kew <jfkthame@gmail.com>
2022-12-24 17:41:31 +08:00
FranklinDM 4e9a2f783e No issue - Replace use of deprecated GetPreventDefault in GTK menu bar 2022-12-24 13:16:03 +08:00
FranklinDM 84acd8c0ef Issue #2065 - Part 5: Fix incorrect inclusion of base file name in destination path for generated FasterMake track files
I'm not sure about what they had in mind when they first wrote this, but this is completely unnecessary. The base name is the file name. This part will break building with `mach faster` once partial filenames with wildcards are included in the package manifest, which became the case when we began supporting the newer MSVC runtime.

This also aligns FasterMake with how RecursiveMake treats wildcard copy directives.

They fixed this in bug 1416465, but it included a conditional that will almost always be true and kept this incorrect joining of the path and base name in the destination path. Since the value for the base name is either empty or contains a partial file name, that conditional effectively does nothing.
2022-12-24 12:57:59 +08:00
FranklinDM fba59dfc4b Issue #2065 - Part 4: Revise comments and remove parts dependent on hybrid FasterMake/RecursiveMake backend 2022-12-24 12:57:55 +08:00
FranklinDM 7ff4b0d120 Issue #2065 - Part 3: Process install manifests with --track in the recursive make backend
This excludes parts that remove support for building the Mozilla SDK.
Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1390916
2022-12-24 12:57:52 +08:00
FranklinDM 13e658a200 Issue #2065 - Part 2: Expand pattern when track file is created rather than read
This fixes build bustage on Windows when using `mach build faster`.

Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1416465
2022-12-24 12:57:48 +08:00
FranklinDM abf74404c5 Issue #2065 - Part 1: Restore FasterMake build backend
I use this for quickly rebuilding and preprocessing the JS/XUL/CSS assets them without the need to recompile the IDL interfaces and other unnecessary items.
2022-12-24 12:57:44 +08:00
Job Bautista cfc61b4c5d Issue #2061 Follow-up: Export jxl/version.h.
Fixes building on Windows.
I also decided to move the preprocessed jxl/version.h to our include/jxl
 instead of relying on moz.build in preprocessing the file. Future me
 should note to not forget to update the version number at that new file
2022-12-24 10:42:27 +08:00
Moonchild 012669ee58 Merge pull request 'RegExp: upgrades to the irregexp regex engine' (#2060) from martok/UXP-contrib:irregexp-upgrades into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2060
2022-12-23 19:55:27 +00:00
Job BautistaandRyo Onodera 6f635acadc Issue #2063 - Ensure a floated ::first-letter inherits from ::first-line.
This fixes the 24 year old Mozilla bug 13610.

Co-authored-by: Ryo Onodera <ryoqun@gmail.com>
2022-12-23 19:21:40 +08:00
Job Bautista fc4d64665f Issue #2061 - Part 4: Update build system for highway library update. 2022-12-22 12:55:56 +08:00
Job Bautista ada110f579 Issue #2061 - Part 3: Update highway source to 1.0.2. 2022-12-22 12:55:25 +08:00
Job Bautista 1356ecde96 Issue #2061 - Part 2: Update build system for libjxl update. 2022-12-22 12:54:52 +08:00
Job Bautista 3d07029232 Issue #2061 - Part 1: Update libjxl source to 0.7.0. 2022-12-22 12:53:52 +08:00
Martok 3f2b011ee6 Issue #1286 - Parse unicode property escapes and property sequences
In addition to upstream, we also allow RGI-named sequences since they're used in the wild.
2022-12-21 19:35:56 +01:00
Martok 9a9e4e0c9a No issue - Refactor CharacterRange + Unicode handling into module for maintainability
Collects code from RegExpParser and RegExpEngine (regexp-compiler-tonode.cc)
Simplify parsing AtomEscape/CharacterClassEscape
2022-12-21 18:53:27 +01:00
Martok 58f3b2c581 Issue #1285 - Implement named capturing groups for replacing 2022-12-21 18:53:27 +01:00
Martok b356d64f4e Issue #1285 - implement named capturing groups and named backrefs
- RegExpParser collects seen groups in named_captures_.
- After irregexp::ParsePattern has finished, RegExpParser::StoreNamedCaptureMap translates
  the parser data to RegExpCompileData.capture_name/index
- RegExpShared::initializeNamedCaptures takes these and builds a PlainObject map which
  is kept with the compiled expression
This is done because irregexp doesn't have access to the JS context and so can't allocate
any JSValues itself.
- for each match result, this map is used to build PlainObjects of name->match/undefined
  (extremely simplified from upstream at the expense of some perf)

IonMonkey switches to non-masm code path for expressions with named groups.
2022-12-21 18:53:27 +01:00
Martok 9a0807a62c No issue - Refactor parsing of unicode escapes to be more general 2022-12-21 18:53:26 +01:00
Martok ffab95c3a3 No issue - Fix VectorMatchPairs allocating more memory than required 2022-12-21 18:53:26 +01:00
Martok 4a290b16b0 No issue - Flag to parse 'v' flag as 'u' for automated tests, disabled by default 2022-12-21 18:53:26 +01:00
Martok 4e252574e0 No issue - refactor base classes for easier access
- move InfallibleVector into its own header, together with common typedefs
- refactor CapturesVector
2022-12-21 18:53:25 +01:00
Martok 94f456f834 Issue #2056 - Fix handling of captures in lookbehinds
- Port unification of CheckNotBackReference*
- Port LoadCurrentCharacter
- Make RegExpMacroAssembler::CheckAtStart understand cp_offset
- Replace magic numbers in ChoiceNode::Emit, Trace::PerformDeferredActions
- CheckBacktrackStackLimit
- Allow backrefs to resist recursion
2022-12-21 18:53:25 +01:00
Moonchild 37bbb4152d Issue #1279 - Implement regular expressions lookbehind (v3)
Based on d10e8a5b with the addition of chromium issue 570241.
2022-12-21 18:53:25 +01:00
Moonchild fc62ce0076 Merge pull request 'Use gfxPackedPixel + WritePixels instead of WriteBuffer in JPEG-XL decoding' (#2059) from jobbautista9/UXP:jxl-writepixels into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2059
2022-12-19 08:00:40 +00:00
Job Bautista b9d00e8c27 Issue #2057 - Use gfxPackedPixel + WritePixels instead of WriteBuffer.
This means we no longer need the workarounds intended for #2033 and #2040!
2022-12-19 13:58:32 +08:00
Moonchild (Away until 22-12-14) a2a0dec11d Merge pull request '[no issue] fix macro condition' (#2055) from lexx9999/UXP:lx_fix_macro into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2055
2022-12-16 12:25:37 +00:00
Moonchild 3e9621aa59 Issue #1818 - Remove obsolete path hack in widget code. 2022-12-15 13:14:03 +00:00
Moonchild 03875cd609 [network] Align cookie checks with RFC 6265 (bis) 2022-12-15 12:30:21 +00:00
Moonchild d9fb68d21b [libjar] Add some extra sanity checks to our Zip reader. 2022-12-15 11:49:39 +00:00
Moonchild df2b82e2cb [network] move some generic websocket code to the baseclass 2022-12-15 10:59:40 +00:00
Moonchild c34cceb678 Revert "Issue #1279 - Implement regular expressions lookbehind (v2)"
This reverts commit d10e8a5b06.
2022-12-15 09:01:05 +00:00
lexx9999 6343937b2c Issue #2041 follow-up - fix macro condition 2022-12-11 05:26:37 +01:00
Moonchild b9894f1e93 Merge pull request 'Include the Emoji font on all GTK platforms, not just Linux.' (#2054) from dbsoft/UXP:GTKFont into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2054
2022-12-09 15:32:51 +00:00
Mavridis Philippe c8bafb9faa MailNews: Re-check availability of OAuth2 when hostname fields modified.
This is for those cases where the hostnme of the email address is not
the actual hostname of the e-mail service (e.g. GMail with a custom
domain).

This should resolve issue athenian200/epyrus#53.

Signed-off-by: Mavridis Philippe <mavridisf@gmail.com>
2022-12-07 13:22:55 +02:00
Brian Smith ecd5436c58 No issue - Fix packaging Epyrus on FreeBSD and Solaris.
The TwemojiMozilla.ttf font should be bundled on Windows and any GTK platforms.
We should not limit the GTK platform to Linux only.
2022-12-04 08:07:44 -06:00
Moonchild b019e959d4 Merge pull request 'Add animation support and progressive decoding for JPEG-XL.' (#2050) from jobbautista9/UXP:jxl-anim-progdec into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2050
2022-12-03 14:09:30 +00:00
Moonchild ab4cc6ebae PR #2050 follow-up: add symbols to build shared on Windows. 2022-12-03 10:45:25 +00:00
Job Bautista 925b33158b Issue #2041 Follow-up - Remove opacity check from original patch.
Per Issue #2033 we don't support expanding RGB to RGBA yet, so this opacity
 check will always return RGBX, which makes images with transparent backgrounds
 show up with a black background instead. Feel free to readd once we backport
 Mozilla bug 1551088.
2022-12-02 14:17:10 +08:00
Job Bautista daf859d84c Issue #2048 - Add progressive decoding for JPEG-XL.
Based on Mozilla phab D122159, intended for bug 1709815.
Also moved the temporary RGBA and premultiplication fixes to a macro, since
 progressive decoding also needs these fixes.
2022-12-02 13:28:34 +08:00
Job Bautista b66e0ffdc4 Issue #2041 - Add animation support for JPEG-XL.
Based on Mozilla phab D122158, intended for bug 1709818.
2022-12-02 11:15:05 +08:00
Moonchild 8f266bb6e7 Merge pull request 'Allow <button> children to receive pointer events' (#2043) from martok/UXP-contrib:2030-button into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2043
2022-11-30 22:04:23 +00:00
Moonchild 2e888727e0 Issue #2040 - Pre-multiply the alpha values in our JXL decode buffer.
Using selective calculation (only if not opaque) and fast integer
math here should optimize well in compilers.
2022-11-30 14:28:09 +00:00
Moonchild bc165aebf8 Merge pull request 'Prevent GTK color picker from being frozen when launched from a modal XUL window' (#2037) from FranklinDM/UXP-contrib:work_gtk-color-picker-frozen into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2037
2022-11-27 22:32:30 +00:00
Moonchild 9d0a8340d7 Merge pull request 'Follow-up to the Ventura fixes and fix building LDAP on Mac for Epyrus' (#2044) from dbsoft/UXP:Mac into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2044
2022-11-27 22:31:53 +00:00
Brian Smith abc044bc61 No Issue - Fix building ldap on MacOS.
Discovered this problem building Epyrus on MacOS, based on this Mozilla Bug:
https://bugzilla.mozilla.org/show_bug.cgi?id=1652906
2022-11-27 13:59:27 -06:00
Brian Smith a061db91dd Issue #2022 Follow-Up - Add autorelease to our manual NSView to prevent potential leaks.
Also move titlebar overrides from BaseWindow to ToolbarWindow...
This caused problems in Waterfox Classic on Ventura, while this didn't seem to be necessary in UXP...
There is no need for those overrides in BaseWindow, so why risk potential problems.
https://bugzilla.mozilla.org/show_bug.cgi?id=1576387
https://github.com/WaterfoxCo/Waterfox-Classic/commit/d7f5814dc089f615385a00db4dfe187c6aefa1af
2022-11-27 13:57:13 -06:00
Martok 0494d561c5 Issue #2030 - Dispatch click on common interactive ancestor if mousdown/up are not on the same element
For example, if the mouse is dragged from one element to another while
staying inside the same button, dispatch from their common ancestor
2022-11-27 16:35:56 +01:00
Martok 41fed1ebf8 Issue #2030 - Pref-gate default button event dispatch logic 2022-11-27 16:35:47 +01:00
Martok a585aeacf0 Issue #2030 - Allow child nodes of button to participate in mouse hit tests
This is needed for web compatibility, even if standards compliance is debatable.
2022-11-27 16:35:38 +01:00
Martok 814fa6e3ba Issue #2030 - (chore) refactor event dispatch functions
Based on selected bits of M-C 1461708:
- EventStateManager::CheckForAndDispatchClick() to early-return style
- split EventStateManager::CheckForAndDispatchClick() into:
  EventCausesClickEvents, PostHandleMouseUp, DispatchClickEvents
- Move implementation of UIEvent::GetRangeParent() and UIEvent::RangeOffset() to nsLayoutUtils
2022-11-27 16:35:25 +01:00
Moonchild 541508cd83 Merge pull request '[No issue] Add executable bit to shell scripts in tree' (#2038) from trav90/UXP-contrib:add-executable-bit into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2038
2022-11-25 19:17:40 +00:00
trav90 2770a0588c [No issue] Add executable bit to shell scripts in tree 2022-11-25 09:37:30 -06:00
Moonchild 88f392397b Issue #2019 - Follow-up: Make nsPluginInstanceOwner also listen to keypress events in the system event group.
nsPluginInstanceOwner only listens to keypress events in the default event group.
However, in our changed operating mode, keypress events are not fired in the
default event group if the key does not result in something printable.
This means that nsPluginInstanceOwner should also listen to keypress events
in the system event group and should handle each keypress that way, but
only once. I.e., if a printable keypress event is received in the system event
group, it should be ignored, since it would've already been handled in the
default event group in that case.
2022-11-24 21:41:28 +00:00
Moonchild 6efb151520 [no issue] fix whitespace. 2022-11-24 15:06:28 +00:00
FranklinDM 058474229d Issue #2036 - Prevent GTK color picker from being frozen when launched from a modal XUL window
Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1496836
2022-11-24 21:54:22 +08:00
Moonchild eb87672d4c Merge pull request 'Improve the protocol handling dialog' (#2032) from FranklinDM/UXP-contrib:work_protocol-handling-dialog-opener into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2032
2022-11-24 12:42:24 +00:00
Moonchild 4b9789888f Issue #2033 - Temporary fix of R<->B channel swap.
We have a BGR/RGB channel ordering mismatch here. to at least
provide proper display, a quick&dirty byte swap on the output
buffer will fix this for now, but we should look into seeing where
the surface mismatch is caused.
std::swap() should optimize pretty well in any of the used
compilers, but if necessary, a full buffer ASM routine can be
slotted in (although on current hardware I doubt this will be
even noticeable as it is)
2022-11-24 12:37:28 +00:00
FranklinDM cc98224267 Issue #2029 - Part 2: Protocol handling dialog should be dependent if not modal
Following the behavior of the download dialog, the content handling dialog should be `dependent` as well. This means that this dialog should close when the parent window is closed, is not visible on the taskbar, and stays in front of the parent window.
2022-11-23 17:57:11 +08:00
FranklinDM 7001a57aef Issue #2029 - Part 1: Add preference for opening the protocol handling dialog as window modal
This adds the preference, `prompts.content_handling_dialog_modal.enabled`, to control whether the dialog is window modal or not.
2022-11-23 17:56:50 +08:00
Moonchild 173320cf7d Merge pull request 'Use reserved stack space instead of heap allocation in nsLocalFileUnix' (#2028) from FranklinDM/UXP-contrib:work_issue-2027 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2028
2022-11-22 00:10:09 +00:00
Moonchild 5f243826b4 Revert "Revert "[XPCOM] Deal with lstat potentially lying in nsLocalFileUnix.""
This reverts commit 3d4474a977.
2022-11-22 00:09:27 +00:00
Moonchild 3d4474a977 Revert "[XPCOM] Deal with lstat potentially lying in nsLocalFileUnix."
This reverts commit c127f58ef3.
2022-11-20 14:15:22 +00:00
FranklinDM 06bc499a0d Issue #2027 - Use reserved stack space instead of heap allocation in nsLocalFile
This should resolve the build bustage associated with c127f58ef3.

Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1371279
2022-11-20 18:42:34 +08:00
Moonchild c127f58ef3 [XPCOM] Deal with lstat potentially lying in nsLocalFileUnix. 2022-11-19 20:11:34 +00:00
Moonchild 5e6006a2bd [network] Fix Mac buffer overflow. 2022-11-19 14:23:40 +00:00
Moonchild ac9253e987 WebSocketChannel::CleanupConnection should run on the socket thread 2022-11-19 14:06:18 +00:00
Moonchild 8778d48290 [Network, DOM] Align our implementation with the current CORS/Fetch spec. 2022-11-18 20:00:59 +00:00
Moonchild fb0c204f2b Issue #1769 - Follow-up: Default-enable JPEG-XL images if built
Sets the pref default to true and also add conneg entry for images
if jxl support is built.
Additionally, ifdefs the GfxPref to only observe when jxl is built.
2022-11-11 12:25:17 +00:00
Moonchild e6888aa2bd Merge branch '1769-take2' 2022-11-10 20:15:54 +00:00
Moonchild d14c78b29d Issue #1769: Ensure MIME type is known in URIloader for jxl 2022-11-08 18:16:29 +00:00
Moonchild 76e7290c1a Issue #1769: Update symbols for libxul linkage 2022-11-07 15:03:03 +00:00
Moonchild d19fb35c6a Merge branch 'master' into 1769-take2 2022-11-07 13:49:11 +00:00
Moonchild 94554142e9 [intl] Update timezone data to 2022e 2022-11-06 21:35:01 +01:00
Moonchild 1c04b522d3 Issue #2024 - Part 2: Add wildcard to Access-Control-Allow-{Method|Headers}
For requests without credentials, add wildcard to Access-Control-Allow-Headers
and Access-Control-Allow-Method.

Resolves #2024
2022-11-06 13:22:44 +00:00
Moonchild 84d3226fb1 Issue #2024 - Part 1: Add wildcard to Access-Control-Expose-Headers
For requests without credentials, add wildcard to Access-Control-Expose-Headers.
2022-11-06 12:31:17 +00:00
Moonchild 42d1d20efd [WebGL] Implement webgl.max-size-per-texture-mib 2022-10-26 13:52:42 +00:00
Moonchild 3505c2050a [XPCOM] Fix Base64 off-by-one issue and safeguard against this mistake in the future. 2022-10-26 09:24:27 +00:00
Moonchild 1139e11f3a [No issue] Hold some strong references on nsRefreshDriver 2022-10-26 08:05:04 +00:00
athenian200 b19541f1d4 Issue #1824 - Remove dependency on libdemangle.
This may be removed from illumos soon, and it is apparently unused anyway, so leaving it in doesn't make sense.
2022-10-26 01:18:43 +00:00
Moonchild 30653de864 Merge pull request 'Support MacOS 13 Ventura' (#2023) from dbsoft/UXP:MacVentura into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2023
2022-10-25 10:02:48 +00:00
Brian Smith 7a82ec5764 Issue #2022 - Part 2 - Add Ventura version detection.
Also add Monterey and Ventura to the graphics driver blocklist.
2022-10-24 23:47:42 -05:00
Brian Smith e73a2fb0fc Issue #2022 - Part 1 - Fix transparent windows on MacOS 13 Ventura.
During the BaseWindow creation contenView is nil on Ventura...
So create a NSView with the requested dimensions and set is as the contenView.
2022-10-24 23:45:38 -05:00
Moonchild b14db5e91e Merge branch 'master' of https://repo.palemoon.org/MoonchildProductions/UXP 2022-10-23 21:46:30 +00:00
Moonchild 2d752c9259 Merge pull request 'Align keypress events in content with the web' (#2020) from keypress-event-work into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2020
2022-10-23 21:45:26 +00:00
Moonchild 362a84565c Issue #21 - Remove panning/tab animation performance measurements
Based on FranklinDM's follow-up for the issue.

This would require browser FE changes, particularly removing the associated
code in `tabbrowser.xml`, however, that was already done in Pale Moon previously.
Other front-end applications may need to take note, though.

Based on changes from the following bugs:
* Bug 696398 - Need an api to analyze panning performance
* Bug 800031 - Include paint time in tab switch telemetry
* Bug 820167 - Enable performance measurement of tab animation
* Bug 826383 - Improve Start/Stop FrameTimeRecording for telemetry usage
2022-10-23 21:43:46 +00:00
FranklinDM d8ef6bf7af Issue #1956 - Look for Visual Studio's path directly in the mozdebug module
This change modifies the mozdebug module to include a special case for Visual Studio when looking for its path.

This also removes the workaround implemented in dcb027a718 which can break debugging in certain installations of Visual Studio 2015.
2022-10-23 21:30:17 +00:00
FranklinDM 825fb3a207 Issue #1793 - Follow-up: Fix incorrect media query 2022-10-23 21:29:24 +00:00
FranklinDM d1345b1da6 Issue #58 - Remove leftover rust build files from /js 2022-10-23 21:29:06 +00:00
FranklinDM 4f95caf7fb Issue #1829 - Follow-up: Mac-specific shortcut key for closing the developer tools toolbox window should not be excluded from other platforms 2022-10-23 21:28:47 +00:00
Moonchild 528ae6aeb0 Merge pull request 'Issue #1375 - Don't mark nodes in the shadow tree as orphan nodes' (#2021) from Basilisk-Dev/UXP:master into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2021
2022-10-22 14:17:59 +00:00
Basilisk-Dev ea0a08fcab Issue #1375 - Don't mark nodes in the shadow tree as orphan nodes
Port of Bug 1026714
2022-10-20 18:22:30 -04:00
Moonchild 7ac438f6ad Issue #2019 - Follow-up: Make autocomplete and satchel listen to keypress events in the system event group
The autocomplete module listens to keypress events for both printable keys
and non-printable keys a lot. However, we're stopping dispatching keypress
events for non-printable keys in the default event group of web content.

This means that autocomplete should listen to keypress events in the
system event group.

Note that it's difficult to globally change keypress event listeners to
keydown event listeners because if we stop keypress events at preceding
keydown event in autocomplete or satchel modules, some other modules
fail to handle keydown or keypress events before autocomplete, and it's
not easy to investigate which keypress event listener in which modules
should be changed to a keydown event listener.

Therefore, this patch doesn't do that, and uses the event group approach.
2022-10-18 12:48:23 +00:00
Moonchild 3142f95469 Issue #2019 - Follow-up: Adjust content spellchecker to use keydown
Since keypress is no longer triggered on all keypresses in content,
the spellchecker would potentially not be triggered when it should be.
This changes the trigger to keydown, instead.
No behavioral changes otherwise.
2022-10-17 15:22:03 +00:00
Moonchild 74b3ce90d7 Issue #2019 - Do not dispatch keypress event for non-printable keys.
This will prevent the keypress DOM event from firing on keypresses
that do not produce printable keys (e.g. editing nav keys) in content.
This should not affect any chrome events that are in use.
Event dispatch can be re-enabled if necessary with the added pref.
2022-10-17 12:28:26 +00:00
Moonchild ebd7672d6b [No issue] Ensure LockImpl::Try() returns the correct bool value. 2022-10-16 23:24:19 +00:00
Moonchild 1f78e93f1d Merge pull request 'Implement regular expressions lookbehind (v2)' (#2017) from regex-lookbehind-v2 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2017
2022-10-12 16:44:09 +00:00
Moonchild 69502301fa Merge pull request 'Implement customElements.upgrade.' (#2015) from jobbautista9/UXP:1375-ceupgrade into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2015
2022-10-12 08:58:55 +00:00
Moonchild d10e8a5b06 Issue #1279 - Implement regular expressions lookbehind (v2)
Because of some additional changes in the JS engine in the meantime,
this implementation should work and not crash due to slot allocation.
2022-10-11 10:59:43 +00:00
Moonchild fb173db64b Issue #2016 - Remove non-functional V8 regex import 2022-10-10 19:36:24 +00:00
Job Bautista 5bc4892122 Issue #1375 - Use nsIAtom* instead of nsAtom* for CE Upgrade function.
We haven't refactored nsIAtom* as Mozilla did yet.
2022-10-09 12:59:21 +08:00
Job Bautista 58670d66e5 Issue #1375 - Implement customElements.upgrade.
Backported from Mozilla bug 1443722.
2022-10-09 10:33:50 +08:00
Jeremy Andrews 4ba7e05b96 Issue #2012 - Follow-up: Make sure Services.jsm is imported earlier.
I didn't catch this because I am used to the .jsm files being imported near the
top of the file, not later on. This is the case in the other two files I
worked on. Only AddonUpdateChecker.jsm seems to have this problem.
2022-10-06 03:27:46 -05:00
Moonchild 2dc264047e Fix some debug assertions.
refactored code porting in assertions causing debug build failures.
2022-10-04 16:32:25 +00:00
Moonchild 6d5b934dc0 Merge pull request 'Allow other UXP applications to use dual-GUID system.' (#2013) from athenian200/UXP:generic-dual-guid-system into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2013
Reviewed-by: Moonchild <moonchild@palemoon.org>
2022-10-04 11:45:50 +00:00
Jeremy Andrews 87ef3606e2 Issue #2012 - Change name of feature to AppCompat GUID.
It's not just for supporting "Phoenix" extensions anymore.
2022-10-03 17:13:57 -05:00
Jeremy Andrews 4ced37546e Issue #2012 - Have fallback value and use better term than "fake ID."
I also use the pref as a constant rather than calling the pref service
repeatedly to make code look much neater. APPCOMPATID matches
APPCOMPATVERSION, and doesn't give the vibe of a sneaky young lad trying to
enter into a tavern whilst underage.
2022-10-03 08:13:17 -05:00
Jeremy Andrews cb61e1a354 Issue #2012 - Allow other UXP applications to use dual-GUID system. 2022-10-02 22:17:27 -05:00
Moonchild b83dd4e5e8 Issue #2010 - Ensure raw tagnames are safe exiting internalEntityParser
This resolves #2010
2022-09-28 13:49:41 +00:00
Moonchild 95907ddf88 Revert "Issue #1986 - Use logical coordinates in flex containers."
This reverts commit 2a57b39dbc.
2022-09-27 20:04:13 +00:00
Moonchild 5f8d70dacd Revert "Issue #1986 - Part 2: Add IsItemInlineAxisMainAxis() and rework some nsFrame code."
This reverts commit ef4eb3f926.
2022-09-27 20:04:02 +00:00
Moonchild 4bf2bf74b1 Revert "Issue #1986 - Add in reftests for new behavior."
This reverts commit 2fc5e3ad7d.
2022-09-27 20:03:42 +00:00
Moonchild b575f4a516 Platform version bump 2022-09-24 12:16:43 +00:00
Moonchild 47a7de8aa4 Issue #1977 - Follow-up: Correct pref check to be selective on wave formats only. 2022-09-22 13:14:17 +00:00
Moonchild 1a5e2e32e1 Merge pull request 'Un-prefix -moz-[min|max}-content keyword' (#2009) from 1992 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2009
2022-09-22 11:47:37 +00:00
Moonchild d06666cd12 [network] Reject cookies with no name and a __Secure- or __Host- prefix 2022-09-21 21:11:53 +00:00
Moonchild 24ee0680b1 [DOM security] Be more explicit about CSP checks and reports. 2022-09-21 14:08:22 +00:00
Moonchild 66a4e02856 Issue #1992 - Part 2: Regenerate devtools CSS database.
Using `mach devtools-css-db`
Note: this also picked up a break-spaces entry that was missed previously.
2022-09-20 20:44:57 +00:00
Moonchild 9fea63c9d4 Issue #1992 - Part 1: Un-prefix -moz-{min|max}-content keywords. 2022-09-20 20:41:33 +00:00
Moonchild fc5b767f5d Issue #2008 - Implement missing s parameter parsing and align case with spec.
This does 2 things.
First, it adds parsing of the 's' parameter parsing to DOM object construction of regexes
Second, it corrects the DOM property to be `dotAll` instead of `dotall`

For consistency's sake, all function names and calls were renamed with the finalized casing.

This resolves #2008
2022-09-18 11:01:27 +00:00
Moonchild 302d46a0f9 Merge pull request 'Media fixes to play nice with MSVC WPO/GL' (#2006) from twivi/UXP:optimize into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2006
Reviewed-by: Moonchild <moonchild@palemoon.org>
2022-09-14 09:42:09 +00:00
twivi d2683b0ff7 revert 82ac99acb5
revert Allow explicit inlines in libaom code, but still prevent automatic inlines due to compiler issues
2022-09-14 02:33:01 +00:00
twivi 92d5680b85 Updated libav/ffvpx patch files to help with upstream library 2022-09-13 14:33:32 +00:00
Moonchild f9a1ebf886 No issue - Stop pre-processing some files that don't have preprocessor statements in them. 2022-09-12 08:05:25 +00:00
twivi a68021d41e Fix ffvpx/libav architecture checks to use preprocessor instead, prevents breakage with LTCG 2022-09-11 21:51:08 +00:00
twivi 82ac99acb5 Allow explicit inlines in libaom code, but still prevent automatic inlines due to compiler issues 2022-09-11 21:49:56 +00:00
Moonchild c623c47157 Merge pull request 'Update IPC locking code.' (#2004) from athenian200/UXP:ipc-locking-update into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2004
2022-09-09 08:10:36 +00:00
Moonchild da835adb48 Merge pull request 'Fix build bustage with spell checker in GCC 12' (#2002) from jobbautista9/UXP:spellcheck-gcc12 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2002
2022-09-08 17:38:29 +00:00
Moonchild a9c9be4d21 Issue #80 - Re-unify most of gfx 2022-09-08 16:54:07 +00:00
Moonchild 0682d4ac0e No Issue - prevent build issue in MSVC due to libaom SIMD inlining. 2022-09-08 16:52:26 +00:00
Jeremy Andrews 77bca114d1 Issue #2003 - Update IPC locking code. 2022-09-08 08:10:11 -05:00
Job Bautista 59f6ae3d74 Issue #1995 - Fix build bustage in GCC 12
For some reason, GCC 12 is treating this include as a circular dependency.
See athenian200's analysis for more details.
2022-09-08 17:57:06 +08:00
Moonchild 1fba5c3cc7 Issue #80 - Re-unify most of the layout engine 2022-09-08 06:49:40 +00:00
Moonchild 3d99e06afe Issue #80 - Re-unify most of DOM 2022-09-08 06:49:09 +00:00
Moonchild ed2a457b0a Merge branch 're-unify' 2022-09-06 23:42:27 +00:00
Moonchild b1b57cefa3 Merge pull request 'Stop using deprecated ext/hash_map and FreeBSD/clang fixes.' (#2001) from dbsoft/UXP:freebsdfix into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2001
2022-09-05 11:13:36 +00:00
Brian Smith 6619e475ab No issue - Fix OutputVariable visibility issue, when building with clang. 2022-09-05 04:47:15 -05:00
Brian Smith f369fbd6f7 Issue #2000 - Stop using deprecated ext/hash_map.
This has been long deprecated in favor of std::unsorted_map. Since all platforms
are using modern compilers now it should not be a problem to switch over to
std::unsorted_map in the single place hash_map is used. This allows us to build
on platforms which have removed hash_map such as FreeBSD.
2022-09-04 23:05:10 -05:00
Brian Smith 2db2e0fe58 No issue - Fix FreeBSD NSS build by adding FreeBSD to the list. 2022-09-04 16:57:20 -05:00
Job Bautista 10a37f462e Issue #1769 - Follow-up: Put JXL_DEPRECATED in front of types
This fixes building with Clang on Mac.
I also separated our changes to JXL_DEPRECATED into a patch file.
2022-06-30 13:55:14 +08:00
Job Bautista 922edb1d93 Issue #1769 - Follow-up: Fix typo in MOZ_ARG_ENABLE_BOOL
Silly copy-paste mistake from AV1
2022-06-29 13:53:11 +08:00
Job Bautista cba46e5628 Issue #1769 - Part 1 Follow-up: Use standard [[deprecated]] for JXL_DEPRECATED.
This fixes building with MSVC for Windows.
2022-06-29 13:53:11 +08:00
Job Bautista 3173108a3f Issue #1769 - Part 2 Follow-up: Do not use namespace parent::child {} for defining nested namespaces.
It doesn't build for MSVC on Windows. Also other decoders are using the old
 way for defining nested namespaces, so better be consistent here.
2022-06-29 13:53:10 +08:00
Job Bautista 5f4d519194 Issue #1769 - Part 1 Follow-up: Tidy up moz.build for highway and libjxl
highway upstream added a new header file to be included in highway.h after
 0.15.0 it seems, so we have to account for that in moz.build.
Also brought back allowing compiler warnings for libjxl and highway.
 Apparently the equivalent of AllowCompilerWarnings() is a bool whose name
 is UPPERCASE and uses under_scores instead of CamelCase.
2022-06-29 13:53:10 +08:00
Job Bautista 2ad17268ed Issue #1769 - Part 3: Cleanup nsJXLDecoder.
The mp4parse Rust component has been removed in Issue #58. It doesn't seem
 like the decoder uses any mp4parse function, so seems like it's safe to
 remove it.
Removed const DecoderType named GetType() because we don't have it in our
 Decoder.h.
I've decided to abandon the OS_RGBA backporting effort and instead went for
 using OS_RGBA's value which is R8G8B8A8. Turns out that there is much more
 going on in Mozilla's version of CreateSurfacePipe than I've expected, like
 the aInFormat and aOutFormat thing which I really don't want to delve into
 right now. Looking at the code it looks like all JPEG-XL images are expected
 to have an alpha channel anyway, so I think my workaround should be safe.
I also removed the dependency in OrientedIntSize and used Size() from gfx/2d/
 Point.h like our PNG and GIF decoders currently do. Migrating our decoders
 to OrientedInt types should be done in another PR instead.
Also also changed the coding style to be closer to UXP's.
Also also also, I made a mistake in Part 1's commit message; the commit used
for libjxl is 192ddd90fdf0c69cd1db1c8d7850db036dd87f4b.
2022-06-29 13:53:10 +08:00
Job Bautista 888c35be89 Issue #1769 - Part 2: Implement JPEG-XL decoder and about:config and MIME plumbing.
Backported from Mozilla bug 1707590 whereever possible.
2022-06-29 13:53:09 +08:00
Job Bautista 73e06b6df9 Issue #1769 - Part 1: Add vendored libjxl and highway sources.
Used old-configure to add the build option for enabling JPEG-XL support.
Highway version: 0.17.0
libjxl version: tree of commit 318c592d98b97d103941b90d47107f06a10c71da
2022-06-29 13:53:09 +08:00
4640 changed files with 861817 additions and 258490 deletions

No files matched your search

+1 -1
View File
@@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Issue #1971 - Update to ICU 63 requires clobber
Touching ICU's build system requires a CLOBBER. (Issue #2165)
+8 -15
View File
@@ -160,18 +160,12 @@ endif
.PHONY: install-manifests
install-manifests: $(addprefix install-,$(install_manifests))
# process_install_manifest needs to be invoked with --no-remove when building
# js as standalone because automated builds are building nspr separately and
# that would remove the resulting files.
# Eventually, a standalone js build would just be able to build nspr itself,
# removing the need for the former.
ifdef JS_STANDALONE
NO_REMOVE=1
endif
.PHONY: $(addprefix install-,$(subst /,_,$(install_manifests)))
.PHONY: $(addprefix install-,$(install_manifests))
$(addprefix install-,$(install_manifests)): install-%: $(install_manifest_depends)
$(addprefix $(call py_action,process_install_manifest,$(if $(NO_REMOVE),--no-remove )$*) ,$(wildcard _build_manifests/install/$(subst /,_,$*)))
$(addprefix $(call py_action,process_install_manifest,--track install_$(subst /,_,$*).track $*) ,$(wildcard _build_manifests/install/$(subst /,_,$*)))
# Dummy wrapper rule to allow the faster backend to piggy back
$(addprefix install-,$(subst /,_,$(filter dist/%,$(install_manifests)))): install-dist_%: install-dist/% ;
.PHONY: install-tests
install-tests: install-test-files
@@ -181,10 +175,9 @@ install-tests: install-test-files
.PHONY: run-tests-deps
run-tests-deps: $(install_manifest_depends)
# Force --no-remove, because $objdir/_tests is handled by multiple manifests.
.PHONY: install-test-files
install-test-files:
$(call py_action,process_install_manifest,--no-remove _tests _build_manifests/install/_test_files)
$(call py_action,process_install_manifest,--track install__test_files.track _tests _build_manifests/install/_test_files)
include $(topsrcdir)/build/moz-automation.mk
@@ -204,13 +197,13 @@ ifndef NO_PROFILE_GUIDED_OPTIMIZE
ifneq ($(OS_ARCH)_$(GNU_CC), WINNT_)
recurse_pre-export:: install-manifests
binaries::
@$(MAKE) install-manifests NO_REMOVE=1 install_manifests=dist/include
@$(MAKE) install-manifests install_manifests=dist/include
endif
endif
else # !MOZ_PROFILE_USE (normal build)
recurse_pre-export:: install-manifests
binaries::
@$(MAKE) install-manifests NO_REMOVE=1 install_manifests=dist/include
@$(MAKE) install-manifests install_manifests=dist/include
endif
# For historical reasons that are unknown, $(DIST)/sdk is always blown away
+4 -2
View File
@@ -33,5 +33,7 @@ If you fork this repository to perform your own work on it, please consider offe
improvement patches upstream to its origin to mutually improve the platform and build
a future for XUL.
## Looking for Pale Moon and Basilisk?
As of [`Issue #969`](https://repo.palemoon.org/MoonchildProductions/UXP/issues/969), release versions `28.9.0` and `2020.03.04` respectively, they have been split off into their own dedicated repositories located at [`MoonchildProductions/Pale-Moon`](https://repo.palemoon.org/MoonchildProductions/Pale-Moon) and [`MoonchildProductions/Basilisk`](https://repo.palemoon.org/MoonchildProductions/Basilisk).
## Looking for Pale Moon?
As of [`Issue #969`](https://repo.palemoon.org/MoonchildProductions/UXP/issues/969), release version `28.9.0`,
applications have been split off into their own dedicated (front-end) repositories, with Pale Moon located at
[`MoonchildProductions/Pale-Moon`](https://repo.palemoon.org/MoonchildProductions/Pale-Moon).
+8 -8
View File
@@ -34,11 +34,10 @@ if test -n "$USE_ICU"; then
ICU_DATA_FILE="icudt${version}l.dat"
dnl We won't build ICU data as a separate file when building
dnl JS standalone so that embedders don't have to deal with it.
dnl We also don't do it on Windows because sometimes the file goes
dnl missing -- possibly due to overzealous antivirus software? --
dnl which prevents the browser from starting up :(
if test -z "$JS_STANDALONE"; then
dnl ICU as a shared library, as we need to fold the data into
dnl the shared library in order for consumers like Spidermonkey
dnl to use it without code duplication.
if test -z "$MOZ_SHARED_ICU"; then
MOZ_ICU_DATA_ARCHIVE=1
else
MOZ_ICU_DATA_ARCHIVE=
@@ -46,17 +45,18 @@ if test -n "$USE_ICU"; then
fi
AC_SUBST(MOZ_ICU_VERSION)
AC_SUBST(ENABLE_INTL_API)
AC_SUBST(USE_ICU)
AC_SUBST(ICU_DATA_FILE)
AC_SUBST(MOZ_ICU_DATA_ARCHIVE)
AC_SUBST(MOZ_SHARED_ICU)
if test -n "$USE_ICU"; then
if test -z "$YASM" -a -z "$GNU_AS" -a "$COMPILE_ENVIRONMENT"; then
AC_MSG_ERROR([Building ICU requires either yasm or a GNU assembler. If you do not have either of those available for this platform you must use --without-intl-api])
fi
dnl We build ICU as a static library.
AC_DEFINE(U_STATIC_IMPLEMENTATION)
if test -z "$MOZ_SHARED_ICU"; then
AC_DEFINE(U_STATIC_IMPLEMENTATION)
fi
dnl Source files that use ICU should have control over which parts of the ICU
dnl namespace they want to use.
AC_DEFINE(U_USING_ICU_NAMESPACE,0)
+4 -1
View File
@@ -156,7 +156,9 @@ def old_configure_options(*options):
'--enable-accessibility',
'--enable-address-sanitizer',
'--enable-alsa',
'--enable-appcompat-guid',
'--enable-av1',
'--enable-jxl',
'--enable-b2g-bt',
'--enable-b2g-camera',
'--enable-b2g-ril',
@@ -225,6 +227,7 @@ def old_configure_options(*options):
'--enable-safe-browsing',
'--enable-sandbox',
'--enable-security-sqlstore',
'--enable-shared-icu',
'--enable-shared-media',
'--enable-signmar',
'--enable-simulator',
@@ -272,6 +275,7 @@ def old_configure_options(*options):
'--with-ios-sdk',
'--with-jitreport-granularity',
'--with-macbundlename-prefix',
'--with-macbundle-identity',
'--with-macos-private-frameworks',
'--with-macos-sdk',
'--with-nspr-cflags',
@@ -306,7 +310,6 @@ def old_configure_options(*options):
'--disable-browser-statusbar',
'--disable-sync',
'--disable-personas',
'--enable-phoenix-extensions',
# Below are configure flags used by Basilisk
'--disable-webextensions',
View File
File mode changed.
Regular → Executable
View File
File mode changed.
Regular → Executable
View File
File mode changed.
Regular → Executable
View File
File mode changed.
-2
View File
@@ -287,8 +287,6 @@ public:
virtual bool AddonHasPermission(const nsAString& aPerm);
virtual bool IsOnCSSUnprefixingWhitelist() override { return false; }
virtual bool IsCodebasePrincipal() const { return false; };
static BasePrincipal* Cast(nsIPrincipal* aPrin) { return static_cast<BasePrincipal*>(aPrin); }
+1 -10
View File
@@ -21,7 +21,7 @@ interface nsIDOMDocument;
[ptr] native JSPrincipals(JSPrincipals);
[ptr] native PrincipalArray(nsTArray<nsCOMPtr<nsIPrincipal> >);
[scriptable, builtinclass, uuid(3da7b133-f1a0-4de9-a2bc-5c49014c1077)]
[scriptable, builtinclass, uuid(f75f502d-79fd-48be-a079-e5a7b8f80c8b)]
interface nsIPrincipal : nsISerializable
{
/**
@@ -333,15 +333,6 @@ interface nsIPrincipal : nsISerializable
* Returns true iff this is the system principal.
*/
[infallible] readonly attribute boolean isSystemPrincipal;
/**
* Returns true if this principal's origin is recognized as being on the
* whitelist of sites that can use the CSS Unprefixing Service.
*
* (This interface provides a trivial implementation, just returning false;
* subclasses can implement something more complex as-needed.)
*/
[noscript,notxpcom,nostdcall] bool IsOnCSSUnprefixingWhitelist();
};
/**
+1 -1
View File
@@ -85,7 +85,7 @@ nsJSPrincipals::Destroy(JSPrincipals *jsprin)
#ifdef DEBUG
// Defined here so one can do principals->dump() in the debugger
JS_PUBLIC_API(void)
void
JSPrincipals::dump()
{
if (debugToken == nsJSPrincipals::DEBUG_TOKEN) {
-204
View File
@@ -35,7 +35,6 @@
using namespace mozilla;
static bool gIsWhitelistingTestDomains = false;
static bool gCodeBasePrincipalSupport = false;
static bool URIIsImmutable(nsIURI* aURI)
@@ -61,10 +60,6 @@ NS_IMPL_CI_INTERFACE_GETTER(nsPrincipal,
/* static */ void
nsPrincipal::InitializeStatics()
{
Preferences::AddBoolVarCache(
&gIsWhitelistingTestDomains,
"layout.css.unprefixing-service.include-test-domains");
Preferences::AddBoolVarCache(&gCodeBasePrincipalSupport,
"signed.applets.codebase_principal_support",
false);
@@ -483,196 +478,6 @@ nsPrincipal::Write(nsIObjectOutputStream* aStream)
return NS_OK;
}
// Helper-function to indicate whether the CSS Unprefixing Service
// whitelist should include dummy domains that are only intended for
// use in testing. (Controlled by a pref.)
static inline bool
IsWhitelistingTestDomains()
{
return gIsWhitelistingTestDomains;
}
// Checks if the given URI's host is on our "full domain" whitelist
// (i.e. if it's an exact match against a domain that needs unprefixing)
static bool
IsOnFullDomainWhitelist(nsIURI* aURI)
{
nsAutoCString hostStr;
nsresult rv = aURI->GetHost(hostStr);
NS_ENSURE_SUCCESS(rv, false);
// NOTE: This static whitelist is expected to be short. If that changes,
// we should consider a different representation; e.g. hash-set, prefix tree.
static const nsLiteralCString sFullDomainsOnWhitelist[] = {
// 0th entry only active when testing:
NS_LITERAL_CSTRING("test1.example.org"),
NS_LITERAL_CSTRING("map.baidu.com"),
NS_LITERAL_CSTRING("3g.163.com"),
NS_LITERAL_CSTRING("3glogo.gtimg.com"), // for 3g.163.com
NS_LITERAL_CSTRING("info.3g.qq.com"), // for 3g.qq.com
NS_LITERAL_CSTRING("3gimg.qq.com"), // for 3g.qq.com
NS_LITERAL_CSTRING("img.m.baidu.com"), // for [shucheng|ks].baidu.com
NS_LITERAL_CSTRING("m.mogujie.com"),
NS_LITERAL_CSTRING("touch.qunar.com"),
NS_LITERAL_CSTRING("mjs.sinaimg.cn"), // for sina.cn
NS_LITERAL_CSTRING("static.qiyi.com"), // for m.iqiyi.com
NS_LITERAL_CSTRING("cdn.kuaidi100.com"), // for m.kuaidi100.com
NS_LITERAL_CSTRING("m.pc6.com"),
NS_LITERAL_CSTRING("m.haosou.com"),
NS_LITERAL_CSTRING("m.mi.com"),
NS_LITERAL_CSTRING("wappass.baidu.com"),
NS_LITERAL_CSTRING("m.video.baidu.com"),
NS_LITERAL_CSTRING("m.video.baidu.com"),
NS_LITERAL_CSTRING("imgcache.gtimg.cn"), // for m.v.qq.com
NS_LITERAL_CSTRING("s.tabelog.jp"),
NS_LITERAL_CSTRING("s.yimg.jp"), // for s.tabelog.jp
NS_LITERAL_CSTRING("i.yimg.jp"), // for *.yahoo.co.jp
NS_LITERAL_CSTRING("ai.yimg.jp"), // for *.yahoo.co.jp
NS_LITERAL_CSTRING("m.finance.yahoo.co.jp"),
NS_LITERAL_CSTRING("daily.c.yimg.jp"), // for sp.daily.co.jp
NS_LITERAL_CSTRING("stat100.ameba.jp"), // for ameblo.jp
NS_LITERAL_CSTRING("user.ameba.jp"), // for ameblo.jp
NS_LITERAL_CSTRING("www.goo.ne.jp"),
NS_LITERAL_CSTRING("x.gnst.jp"), // for mobile.gnavi.co.jp
NS_LITERAL_CSTRING("c.x.gnst.jp"), // for mobile.gnavi.co.jp
NS_LITERAL_CSTRING("www.smbc-card.com"),
NS_LITERAL_CSTRING("static.card.jp.rakuten-static.com"), // for rakuten-card.co.jp
NS_LITERAL_CSTRING("img.travel.rakuten.co.jp"), // for travel.rakuten.co.jp
NS_LITERAL_CSTRING("img.mixi.net"), // for mixi.jp
NS_LITERAL_CSTRING("girlschannel.net"),
NS_LITERAL_CSTRING("www.fancl.co.jp"),
NS_LITERAL_CSTRING("s.cosme.net"),
NS_LITERAL_CSTRING("www.sapporobeer.jp"),
NS_LITERAL_CSTRING("www.mapion.co.jp"),
NS_LITERAL_CSTRING("touch.navitime.co.jp"),
NS_LITERAL_CSTRING("sp.mbga.jp"),
NS_LITERAL_CSTRING("ava-a.sp.mbga.jp"), // for sp.mbga.jp
NS_LITERAL_CSTRING("www.ntv.co.jp"),
NS_LITERAL_CSTRING("mobile.suntory.co.jp"), // for suntory.jp
NS_LITERAL_CSTRING("www.aeonsquare.net"),
NS_LITERAL_CSTRING("mw.nikkei.com"),
NS_LITERAL_CSTRING("www.nhk.or.jp"),
NS_LITERAL_CSTRING("www.tokyo-sports.co.jp"),
NS_LITERAL_CSTRING("www.bellemaison.jp"),
NS_LITERAL_CSTRING("www.kuronekoyamato.co.jp"),
NS_LITERAL_CSTRING("formassist.jp"), // for orico.jp
NS_LITERAL_CSTRING("sp.m.reuters.co.jp"),
NS_LITERAL_CSTRING("www.atre.co.jp"),
NS_LITERAL_CSTRING("www.jtb.co.jp"),
NS_LITERAL_CSTRING("www.sharp.co.jp"),
NS_LITERAL_CSTRING("www.biccamera.com"),
NS_LITERAL_CSTRING("weathernews.jp"),
NS_LITERAL_CSTRING("cache.ymail.jp"), // for www.yamada-denkiweb.com
};
static const size_t sNumFullDomainsOnWhitelist =
MOZ_ARRAY_LENGTH(sFullDomainsOnWhitelist);
// Skip 0th (dummy) entry in whitelist, unless a pref is enabled.
const size_t firstWhitelistIdx = IsWhitelistingTestDomains() ? 0 : 1;
for (size_t i = firstWhitelistIdx; i < sNumFullDomainsOnWhitelist; ++i) {
if (hostStr == sFullDomainsOnWhitelist[i]) {
return true;
}
}
return false;
}
// Checks if the given URI's host is on our "base domain" whitelist
// (i.e. if it's a subdomain of some host that we've whitelisted as needing
// unprefixing for all its subdomains)
static bool
IsOnBaseDomainWhitelist(nsIURI* aURI)
{
static const nsLiteralCString sBaseDomainsOnWhitelist[] = {
// 0th entry only active when testing:
NS_LITERAL_CSTRING("test2.example.org"),
NS_LITERAL_CSTRING("tbcdn.cn"), // for m.taobao.com
NS_LITERAL_CSTRING("alicdn.com"), // for m.taobao.com
NS_LITERAL_CSTRING("dpfile.com"), // for m.dianping.com
NS_LITERAL_CSTRING("hao123img.com"), // for hao123.com
NS_LITERAL_CSTRING("tabelog.k-img.com"), // for s.tabelog.com
NS_LITERAL_CSTRING("tsite.jp"), // for *.tsite.jp
};
static const size_t sNumBaseDomainsOnWhitelist =
MOZ_ARRAY_LENGTH(sBaseDomainsOnWhitelist);
nsCOMPtr<nsIEffectiveTLDService> tldService =
do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
if (tldService) {
// Skip 0th test-entry in whitelist, unless the testing pref is enabled.
const size_t firstWhitelistIdx = IsWhitelistingTestDomains() ? 0 : 1;
// Right now, the test base-domain "test2.example.org" is the only entry in
// its whitelist with a nonzero "depth". So we'll only bother going beyond
// 0 depth (to 1) if that entry is enabled. (No point in slowing down the
// normal codepath, for the benefit of a disabled test domain.) If we add a
// "real" base-domain with a depth of >= 1 to our whitelist, we can get rid
// of this conditional & just make this a static variable.
const uint32_t maxSubdomainDepth = IsWhitelistingTestDomains() ? 1 : 0;
for (uint32_t subdomainDepth = 0;
subdomainDepth <= maxSubdomainDepth; ++subdomainDepth) {
// Get the base domain (to depth |subdomainDepth|) from passed-in URI:
nsAutoCString baseDomainStr;
nsresult rv = tldService->GetBaseDomain(aURI, subdomainDepth,
baseDomainStr);
if (NS_FAILED(rv)) {
// aURI doesn't have |subdomainDepth| levels of subdomains. If we got
// here without a match yet, then aURI is not on our whitelist.
return false;
}
// Compare the base domain against each entry in our whitelist:
for (size_t i = firstWhitelistIdx; i < sNumBaseDomainsOnWhitelist; ++i) {
if (baseDomainStr == sBaseDomainsOnWhitelist[i]) {
return true;
}
}
}
}
return false;
}
// The actual (non-cached) implementation of IsOnCSSUnprefixingWhitelist():
static bool
IsOnCSSUnprefixingWhitelistImpl(nsIURI* aURI)
{
// Check scheme, so we can drop any non-HTTP/HTTPS URIs right away
nsAutoCString schemeStr;
nsresult rv = aURI->GetScheme(schemeStr);
NS_ENSURE_SUCCESS(rv, false);
// Only proceed if scheme is "http" or "https"
if (!(StringBeginsWith(schemeStr, NS_LITERAL_CSTRING("http")) &&
(schemeStr.Length() == 4 ||
(schemeStr.Length() == 5 && schemeStr[4] == 's')))) {
return false;
}
return (IsOnFullDomainWhitelist(aURI) ||
IsOnBaseDomainWhitelist(aURI));
}
bool
nsPrincipal::IsOnCSSUnprefixingWhitelist()
{
if (mIsOnCSSUnprefixingWhitelist.isNothing()) {
// Value not cached -- perform our lazy whitelist-check.
// (NOTE: If our URI is mutable, we just assume it's not on the whitelist,
// since our caching strategy won't work. This isn't expected to be common.)
mIsOnCSSUnprefixingWhitelist.emplace(
mCodebaseImmutable &&
IsOnCSSUnprefixingWhitelistImpl(mCodebase));
}
return *mIsOnCSSUnprefixingWhitelist;
}
/************************************************************************************************************************/
NS_IMPL_CLASSINFO(nsExpandedPrincipal, nullptr, nsIClassInfo::MAIN_THREAD_ONLY,
@@ -837,15 +642,6 @@ nsExpandedPrincipal::AddonHasPermission(const nsAString& aPerm)
return false;
}
bool
nsExpandedPrincipal::IsOnCSSUnprefixingWhitelist()
{
// CSS Unprefixing Whitelist is a per-origin thing; doesn't really make sense
// for an expanded principal. (And probably shouldn't be needed.)
return false;
}
nsresult
nsExpandedPrincipal::GetScriptLocation(nsACString& aStr)
{
-3
View File
@@ -25,7 +25,6 @@ public:
NS_IMETHOD GetDomain(nsIURI** aDomain) override;
NS_IMETHOD SetDomain(nsIURI* aDomain) override;
NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) override;
virtual bool IsOnCSSUnprefixingWhitelist() override;
bool IsCodebasePrincipal() const override { return true; }
nsresult GetOriginInternal(nsACString& aOrigin) override;
@@ -55,7 +54,6 @@ public:
bool mCodebaseImmutable;
bool mDomainImmutable;
bool mInitialized;
mozilla::Maybe<bool> mIsOnCSSUnprefixingWhitelist; // Lazily-computed
protected:
virtual ~nsPrincipal();
@@ -81,7 +79,6 @@ public:
NS_IMETHOD SetDomain(nsIURI* aDomain) override;
NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) override;
virtual bool AddonHasPermission(const nsAString& aPerm) override;
virtual bool IsOnCSSUnprefixingWhitelist() override;
virtual nsresult GetScriptLocation(nsACString &aStr) override;
nsresult GetOriginInternal(nsACString& aOrigin) override;
+1
View File
@@ -45,6 +45,7 @@ SECTION_INSERT_BEFORE = [
('.text', '.fini'),
('.rodata', '.rodata1'),
('.data.rel.ro', '.dynamic'),
('.kPStaticModules', '.data.rel.ro'),
('.data', '.data1'),
]
Binary file not shown.
+9 -2
View File
@@ -3,8 +3,6 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
Library('icu')
DIRS += [
'common',
'data',
@@ -14,5 +12,14 @@ DIRS += [
if CONFIG['MOZ_ICU_DATA_ARCHIVE']:
DIRS += ['stubdata']
USE_LIBS += ['icustubdata']
Library('icu')
else:
USE_LIBS += ['icudata']
SharedLibrary('icu')
SHARED_LIBRARY_NAME = 'icu' + CONFIG['MOZ_ICU_VERSION']
# Linking ICU gets too spammy in warnings with MSVC
if CONFIG['_MSC_VER'] and not CONFIG['CLANG_CL']:
LDFLAGS += [
'/IGNORE:4217', # symbol defined in $1.obj is defined in $2.obj
'/IGNORE:4286', # similar with LNK4217
]
+3
View File
@@ -41,6 +41,9 @@ if CONFIG['CPU_ARCH'] == 'arm':
if CONFIG['MOZ_FFVPX']:
external_dirs += ['media/ffvpx']
if CONFIG["MOZ_JXL"]:
external_dirs += ["media/libjxl", "media/highway"]
external_dirs += [
'media/kiss_fft',
'media/libcubeb',
+98
View File
@@ -0,0 +1,98 @@
# 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/.
# /!\ Please make sure to update the following comment when you touch this
# file. Thank you /!\
# The traditional Mozilla build system relied on going through the entire
# build tree a number of times with different targets, and many of the
# things happening at each step required other things happening in previous
# steps without any documentation of those dependencies.
#
# This build system establishes what files or operations are needed for the
# build, and applying the necessary rules to have those in place, relying on
# make dependencies to get them going.
#
# Only non-compiled parts of the application and platform are built and
# supported here (a few other things are also left out).
#
# This file contains rules and dependencies to get things working. The intent
# is for a Makefile to define some dependencies and variables, and include
# this file. What needs to be defined there, and ends up being generated by
# python/mozbuild/mozbuild/backend/fastermake.py is the following:
# - TOPSRCDIR/TOPOBJDIR, respectively the top source directory and the top
# object directory
# - PYTHON, the path to the python executable
# - ACDEFINES, which contains a set of -Dvar=name to be used during
# preprocessing
# - INSTALL_MANIFESTS, which defines the list of base directories handled
# by install manifests, see further below
#
# A convention used between this file and the Makefile including it is that
# global Make variables names are uppercase, while "local" Make variables
# applied to specific targets are lowercase.
# Targets to be triggered for a default build
default: $(addprefix install-,$(INSTALL_MANIFESTS))
ifndef NO_XPIDL
# Targets from the recursive make backend to be built for a default build
default: $(TOPOBJDIR)/config/makefiles/xpidl/xpidl
endif
# Mac builds require copying files in dist/bin/*.app
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
default:
$(MAKE) -C $(TOPOBJDIR)/$(MOZ_BUILD_APP)/app repackage
endif
.PHONY: FORCE
# Extra define to trigger some workarounds. We should strive to limit the
# use of those. As of writing the only ones are in
# toolkit/content/buildconfig.html and browser/locales/jar.mn.
ACDEFINES += -DBUILD_FASTER
# Files under the faster/ sub-directory, however, are not meant to use the
# fallback
$(TOPOBJDIR)/faster/%: ;
# Generic rule to fall back to the recursive make backend.
# This needs to stay after other $(TOPOBJDIR)/* rules because GNU Make
# <3.82 apply pattern rules in definition order, not stem length like
# modern GNU Make.
$(TOPOBJDIR)/%: FORCE
$(MAKE) -C $(dir $@) $(notdir $@)
# Install files using install manifests
#
# The list of base directories is given in INSTALL_MANIFESTS. The
# corresponding install manifests are named correspondingly, with forward
# slashes replaced with underscores, and prefixed with `install_`. That is,
# the install manifest for `dist/bin` would be `install_dist_bin`.
$(addprefix install-,$(INSTALL_MANIFESTS)): install-%: $(addprefix $(TOPOBJDIR)/,buildid.h source-repo.h)
@# For now, force preprocessed files to be reprocessed every time.
@# The overhead is not that big, and this avoids waiting for proper
@# support for defines tracking in process_install_manifest.
@touch install_$(subst /,_,$*)
@# BOOKMARKS_INCLUDE_DIR is for bookmarks.html only.
$(PYTHON) -m mozbuild.action.process_install_manifest \
--track install_$(subst /,_,$*).track \
$(TOPOBJDIR)/$* \
-DAB_CD=en-US \
-DBOOKMARKS_INCLUDE_DIR=$(TOPSRCDIR)/browser/locales/en-US/profile \
$(ACDEFINES) \
install_$(subst /,_,$*)
# ============================================================================
# Below is a set of additional dependencies and variables used to build things
# that are not supported by data in moz.build.
# The xpidl target in config/makefiles/xpidl requires the install manifest for
# dist/idl to have been processed.
$(TOPOBJDIR)/config/makefiles/xpidl/xpidl: $(TOPOBJDIR)/install-dist_idl
# It also requires all the install manifests for dist/bin to have been processed
# because it adds interfaces.manifest references with buildlist.py.
$(TOPOBJDIR)/config/makefiles/xpidl/xpidl: $(addprefix install-,$(filter dist/bin%,$(INSTALL_MANIFESTS)))
+1 -1
View File
@@ -8,4 +8,4 @@
# Referenced by milestone.py.
#--------------------------------------------------------
5.2.0
6.1.0
+1
View File
@@ -810,6 +810,7 @@ sym.h
synch.h
syncmgr.h
sys/atomic_op.h
sys/auxv.h
sys/bitypes.h
sys/byteorder.h
syscall.h
+8 -5
View File
@@ -26,16 +26,19 @@
key="&closeCmd.key;"
command="toolbox-cmd-close"
modifiers="accel"/>
<key id="toolbox-key-toggle"
key="&toggleToolbox.key;"
command="toolbox-cmd-close"
modifiers="accel,shift"
disabled="true"/>
#ifdef XP_MACOSX
<key id="toolbox-key-toggle-osx"
key="&toggleToolbox.key;"
command="toolbox-cmd-close"
modifiers="accel,alt"
disabled="true"/>
#else
<key id="toolbox-key-toggle"
key="&toggleToolbox.key;"
command="toolbox-cmd-close"
modifiers="accel,shift"
disabled="true"/>
#endif
<key id="toolbox-key-toggle-F12"
keycode="&toggleToolboxF12.keycode;"
keytext="&toggleToolboxF12.keytext;"
@@ -25,10 +25,8 @@
<script>
"use strict";
var host = document.querySelector("#shadow");
if (host.createShadowRoot) {
var root = host.createShadowRoot();
root.innerHTML = "<h3>Shadow DOM</h3><select multiple></select>";
}
var root = host.attachShadow({ mode: "open" });
root.innerHTML = "<h3>Shadow DOM</h3><select multiple></select>";
</script>
</body>
</html>
+1 -1
View File
@@ -104,7 +104,7 @@ devtools.jar:
content/commandline/commandline.css (commandline/commandline.css)
content/commandline/commandlineoutput.xhtml (commandline/commandlineoutput.xhtml)
content/commandline/commandlinetooltip.xhtml (commandline/commandlinetooltip.xhtml)
content/framework/toolbox-window.xul (framework/toolbox-window.xul)
* content/framework/toolbox-window.xul (framework/toolbox-window.xul)
content/framework/toolbox-options.xhtml (framework/toolbox-options.xhtml)
content/framework/toolbox.xul (framework/toolbox.xul)
content/framework/toolbox-init.js (framework/toolbox-init.js)
@@ -46,7 +46,7 @@
.tabs .all-tabs-menu {
position: absolute;
top: 0;
offset-inline-end: 0;
inset-inline-end: 0;
width: 15px;
height: 100%;
border-inline-start: 1px solid var(--theme-splitter-color);
+43 -28
View File
@@ -8,7 +8,7 @@
* Copyright (C) 2008, 2009 Anthony Ricaud <rik@webkit.org>
* Copyright (C) 2011 Google Inc. All rights reserved.
* Copyright (C) 2009 Mozilla Foundation. All rights reserved.
* Copyright (C) 2022 Moonchild Productions. All rights reserved.
* Copyright (C) 2022, 2023 Moonchild Productions. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -138,7 +138,8 @@ const Curl = {
for (let i = 0; i < headers.length; i++) {
let header = headers[i];
if (header.name.toLowerCase() === "accept-encoding") {
addParam("--compressed");
// Ignore transfer encoding (compression) as not all commonly installed
// versions of curl support this.
continue;
}
if (ignoredHeaders.has(header.name.toLowerCase())) {
@@ -397,41 +398,55 @@ const CurlUtils = {
/**
* Escape util function for Windows systems.
* Credit: Google DevTools
*/
escapeStringWin: function (str) {
/*
Replace the backtick character ` with `` in order to escape it.
The backtick character is an escape character in PowerShell and
can, among other things, be used to disable the effect of some
of the other escapes created below.
Because the cmd.exe parser and the MS Crt arguments parsers use some
of the same escape characters, they can interact with each other in
terrible ways, meaning the order of operations is critical here.
Replace dollar sign because of commands in powershell when using
double quotes. e.g $(calc.exe).
1. Replace \ with \\ first, because it is an escape character for
certain conditions in both parsers.
2. Replace double quote chars with two double quotes (not by escaping
with \") because it is recognized by both the cmd.exe and MS Crt
arguments parsers.
Also see http://www.rlmueller.net/PowerShellEscape.htm for details.
3. Escape ` and $ so commands do not get executed, e.g $(calc.exe) or
`\$(calc.exe)
4. Escape all characters we are not sure about with ^, to ensure it
gets to the MS Crt arguments parser safely.
Replace quote by double quote (but not by \") because it is
recognized by both cmd.exe and MS Crt arguments parser.
5. The % character is special because the MS Crt arguments parser will
try and look for environment variables and fill them in, in-place. We
cannot escape them with % and cannot escape them with ^ (because it's
cmd.exe's escape, not the MS Crt arguments parser). So, we can get the
cmd.exe parser to escape the character after it, if it is followed by
a valid starting character of an environment variable.
This ensures we do not try and double-escape another ^ if it was placed
by the previous replace.
Replace % by "%" because it could be expanded to an environment
variable value. So %% becomes "%""%". Even if an env variable ""
(2 doublequotes) is declared, the cmd.exe will not
substitute it with its value.
6. We replace \r and \r\n with \n; this allows us to consistently
escape all new lines in the next replace.
Replace each backslash with double backslash to make sure
MS Crt arguments parser won't collapse them.
Replace new line outside of quotes since cmd.exe doesn't let
us do it inside.
7. Lastly, we replace new lines with ^ and TWO new lines, because the
first new line is there to enact the escape command, and the second is
the character to escape (in this case new line).
The extra " enables escaping new lines with ^ within quotes in cmd.exe.
*/
return "\"" +
str.replaceAll("`", "``")
.replaceAll("$", "`$")
.replaceAll('"', '""')
.replaceAll("%", '"%"')
.replace(/\\/g, "\\\\")
.replace(/[\r\n]+/g, "\"^$&\"") + "\"";
const encapsChars = '"';
return (
encapsChars +
str
.replace(/\\/g, "\\\\")
.replace(/"/g, '""')
.replace(/[`$]/g, "\\$&")
.replace(/[^a-zA-Z0-9\s_\-:=+~\/.',?;()*\$&\\{}\"`]/g, "^$&")
.replace(/%(?=[a-zA-Z0-9_])/g, "%^")
.replace(/\r\n?/g, "\n")
.replace(/\n/g, '"^\r\n\r\n"')
+ encapsChars);
}
};
+1 -1
View File
@@ -1032,7 +1032,7 @@ OutputPanel.prototype._resize = function () {
break;
}
this.document.body.style.width = "-moz-max-content";
this.document.body.style.width = "max-content";
let style = this._frame.contentWindow.getComputedStyle(this.document.body);
let frameWidth = parseInt(style.width, 10);
let width = Math.min(maxWidth, frameWidth);
+1 -1
View File
@@ -652,7 +652,7 @@ checkbox:-moz-focusring {
.devtools-searchinput-clear {
position: absolute;
top: 3.5px;
offset-inline-end: 7px;
inset-inline-end: 7px;
padding: 0;
border: 0;
width: 16px;
+1 -1
View File
@@ -216,7 +216,7 @@
content: "";
position: absolute;
top: 1px;
offset-inline-start: 0;
inset-inline-start: 0;
width: 12px;
height: 22px;
background-repeat: no-repeat;
+2 -2
View File
@@ -521,8 +521,8 @@
width: 16px;
height: 16px;
position: absolute;
offset-inline-start: 3px;
offset-block-start: 3px;
inset-inline-start: 3px;
inset-block-start: 3px;
box-shadow: 0px 0px 0px black;
border: solid 1px #fff;
}
@@ -21,8 +21,8 @@
// Set up a basic shadow DOM
var host = document.querySelector('#shadow');
if (host.createShadowRoot) {
var root = host.createShadowRoot();
if (host.attachShadow) {
let root = host.attachShadow({ mode: "open" });
root.innerHTML = '<h3>Shadow <em>DOM</em></h3><select multiple></select>';
}
+130 -36
View File
@@ -2209,13 +2209,13 @@ exports.CSS_PROPERTIES = {
"-moz-available",
"-moz-calc",
"-moz-fit-content",
"-moz-max-content",
"-moz-min-content",
"auto",
"calc",
"content",
"inherit",
"initial",
"max-content",
"min-content",
"unset"
]
},
@@ -2232,13 +2232,13 @@ exports.CSS_PROPERTIES = {
"-moz-available",
"-moz-calc",
"-moz-fit-content",
"-moz-max-content",
"-moz-min-content",
"auto",
"calc",
"content",
"inherit",
"initial",
"max-content",
"min-content",
"unset"
]
},
@@ -3144,10 +3144,10 @@ exports.CSS_PROPERTIES = {
"mix-blend-mode",
"object-fit",
"object-position",
"offset-block-end",
"offset-block-start",
"offset-inline-end",
"offset-inline-start",
"inset-block-end",
"inset-block-start",
"inset-inline-end",
"inset-inline-start",
"opacity",
"order",
"-moz-orient",
@@ -3304,9 +3304,7 @@ exports.CSS_PROPERTIES = {
"-moz-mac-source-list-selection",
"-moz-mac-vibrancy-dark",
"-moz-mac-vibrancy-light",
"-moz-max-content",
"-moz-middle-with-baseline",
"-moz-min-content",
"-moz-none",
"-moz-popup",
"-moz-pre-space",
@@ -3362,6 +3360,7 @@ exports.CSS_PROPERTIES = {
"bottom",
"bottom-outside",
"break-all",
"break-spaces",
"break-word",
"butt",
"button",
@@ -3493,6 +3492,7 @@ exports.CSS_PROPERTIES = {
"margin-box",
"match-source",
"mathematical",
"max-content",
"medium",
"menuarrow",
"menubar",
@@ -3510,6 +3510,7 @@ exports.CSS_PROPERTIES = {
"meterbar",
"meterchunk",
"middle",
"min-content",
"miter",
"mixed",
"multiply",
@@ -6000,13 +6001,13 @@ exports.CSS_PROPERTIES = {
"-moz-available",
"-moz-calc",
"-moz-fit-content",
"-moz-max-content",
"-moz-min-content",
"auto",
"calc",
"content",
"inherit",
"initial",
"max-content",
"min-content",
"unset"
]
},
@@ -6023,13 +6024,13 @@ exports.CSS_PROPERTIES = {
"-moz-available",
"-moz-calc",
"-moz-fit-content",
"-moz-max-content",
"-moz-min-content",
"auto",
"calc",
"content",
"inherit",
"initial",
"max-content",
"min-content",
"unset"
]
},
@@ -6816,12 +6817,12 @@ exports.CSS_PROPERTIES = {
"-moz-available",
"-moz-calc",
"-moz-fit-content",
"-moz-max-content",
"-moz-min-content",
"auto",
"calc",
"inherit",
"initial",
"max-content",
"min-content",
"unset"
]
},
@@ -6903,8 +6904,101 @@ exports.CSS_PROPERTIES = {
"-moz-available",
"-moz-calc",
"-moz-fit-content",
"-moz-max-content",
"-moz-min-content",
"auto",
"calc",
"inherit",
"initial",
"max-content",
"min-content",
"unset"
]
},
"inset": {
"isInherited": false,
"subproperties": [
"top",
"right",
"bottom",
"left"
],
"supports": [
6,
8
],
"values": [
"-moz-calc",
"auto",
"calc",
"inherit",
"initial",
"unset"
]
},
"inset-block-end": {
"isInherited": false,
"subproperties": [
"inset-block-end"
],
"supports": [
6,
8
],
"values": [
"-moz-calc",
"auto",
"calc",
"inherit",
"initial",
"unset"
]
},
"inset-block-start": {
"isInherited": false,
"subproperties": [
"inset-block-start"
],
"supports": [
6,
8
],
"values": [
"-moz-calc",
"auto",
"calc",
"inherit",
"initial",
"unset"
]
},
"inset-inline-end": {
"isInherited": false,
"subproperties": [
"inset-inline-end"
],
"supports": [
6,
8
],
"values": [
"-moz-calc",
"auto",
"calc",
"inherit",
"initial",
"unset"
]
},
"inset-inline-start": {
"isInherited": false,
"subproperties": [
"inset-inline-start"
],
"supports": [
6,
8
],
"values": [
"-moz-calc",
"auto",
"calc",
"inherit",
@@ -7651,11 +7745,11 @@ exports.CSS_PROPERTIES = {
"-moz-available",
"-moz-calc",
"-moz-fit-content",
"-moz-max-content",
"-moz-min-content",
"calc",
"inherit",
"initial",
"max-content",
"min-content",
"none",
"unset"
]
@@ -7673,11 +7767,11 @@ exports.CSS_PROPERTIES = {
"-moz-available",
"-moz-calc",
"-moz-fit-content",
"-moz-max-content",
"-moz-min-content",
"calc",
"inherit",
"initial",
"max-content",
"min-content",
"none",
"unset"
]
@@ -7695,11 +7789,11 @@ exports.CSS_PROPERTIES = {
"-moz-available",
"-moz-calc",
"-moz-fit-content",
"-moz-max-content",
"-moz-min-content",
"calc",
"inherit",
"initial",
"max-content",
"min-content",
"none",
"unset"
]
@@ -7735,12 +7829,12 @@ exports.CSS_PROPERTIES = {
"-moz-available",
"-moz-calc",
"-moz-fit-content",
"-moz-max-content",
"-moz-min-content",
"auto",
"calc",
"inherit",
"initial",
"max-content",
"min-content",
"unset"
]
},
@@ -7757,12 +7851,12 @@ exports.CSS_PROPERTIES = {
"-moz-available",
"-moz-calc",
"-moz-fit-content",
"-moz-max-content",
"-moz-min-content",
"auto",
"calc",
"inherit",
"initial",
"max-content",
"min-content",
"unset"
]
},
@@ -7779,12 +7873,12 @@ exports.CSS_PROPERTIES = {
"-moz-available",
"-moz-calc",
"-moz-fit-content",
"-moz-max-content",
"-moz-min-content",
"auto",
"calc",
"inherit",
"initial",
"max-content",
"min-content",
"unset"
]
},
@@ -7851,7 +7945,7 @@ exports.CSS_PROPERTIES = {
"offset-block-end": {
"isInherited": false,
"subproperties": [
"offset-block-end"
"inset-block-end"
],
"supports": [
6,
@@ -7869,7 +7963,7 @@ exports.CSS_PROPERTIES = {
"offset-block-start": {
"isInherited": false,
"subproperties": [
"offset-block-start"
"inset-block-start"
],
"supports": [
6,
@@ -7887,7 +7981,7 @@ exports.CSS_PROPERTIES = {
"offset-inline-end": {
"isInherited": false,
"subproperties": [
"offset-inline-end"
"inset-inline-end"
],
"supports": [
6,
@@ -7905,7 +7999,7 @@ exports.CSS_PROPERTIES = {
"offset-inline-start": {
"isInherited": false,
"subproperties": [
"offset-inline-start"
"inset-inline-start"
],
"supports": [
6,
@@ -9543,12 +9637,12 @@ exports.CSS_PROPERTIES = {
"-moz-available",
"-moz-calc",
"-moz-fit-content",
"-moz-max-content",
"-moz-min-content",
"auto",
"calc",
"inherit",
"initial",
"max-content",
"min-content",
"unset"
]
},
-17
View File
@@ -190,23 +190,6 @@ LoadContext::GetOriginAttributes(JS::MutableHandleValue aAttrs)
return NS_OK;
}
NS_IMETHODIMP
LoadContext::IsTrackingProtectionOn(bool* aIsTrackingProtectionOn)
{
MOZ_ASSERT(mIsNotNull);
if (Preferences::GetBool("privacy.trackingprotection.enabled", false)) {
*aIsTrackingProtectionOn = true;
} else if ((mOriginAttributes.mPrivateBrowsingId > 0) &&
Preferences::GetBool("privacy.trackingprotection.pbmode.enabled", false)) {
*aIsTrackingProtectionOn = true;
} else {
*aIsTrackingProtectionOn = false;
}
return NS_OK;
}
//-----------------------------------------------------------------------------
// LoadContext::nsIInterfaceRequestor
//-----------------------------------------------------------------------------
-15
View File
@@ -13651,21 +13651,6 @@ nsDocShell::GetNestedFrameId(uint64_t* aId)
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::IsTrackingProtectionOn(bool* aIsTrackingProtectionOn)
{
if (Preferences::GetBool("privacy.trackingprotection.enabled", false)) {
*aIsTrackingProtectionOn = true;
} else if (UsePrivateBrowsing() &&
Preferences::GetBool("privacy.trackingprotection.pbmode.enabled", false)) {
*aIsTrackingProtectionOn = true;
} else {
*aIsTrackingProtectionOn = false;
}
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetIsContent(bool* aIsContent)
{
-1
View File
@@ -233,7 +233,6 @@ public:
NS_IMETHOD GetUseRemoteTabs(bool*) override;
NS_IMETHOD SetRemoteTabs(bool) override;
NS_IMETHOD GetOriginAttributes(JS::MutableHandle<JS::Value>) override;
NS_IMETHOD IsTrackingProtectionOn(bool*) override;
// Restores a cached presentation from history (mLSHE).
// This method swaps out the content viewer and simulates loads for
-15
View File
@@ -137,19 +137,4 @@ interface nsILoadContext : nsISupports
#endif
%}
/**
* Returns true if tracking protection is enabled for the load context.
*/
boolean IsTrackingProtectionOn();
%{C++
/**
* De-XPCOMed getter to make call-sites cleaner.
*/
bool UseTrackingProtection() {
bool usingTP;
IsTrackingProtectionOn(&usingTP);
return usingTP;
}
%}
};
@@ -6,6 +6,7 @@
#include "TimelineConsumers.h"
#include "mozilla/ClearOnShutdown.h"
#include "jsapi.h"
#include "nsAppRunner.h" // for XRE_IsContentProcess, XRE_IsParentProcess
#include "nsDocShell.h"
@@ -125,6 +126,9 @@ TimelineConsumers::AddConsumer(nsDocShell* aDocShell)
UniquePtr<ObservedDocShell>& observed = aDocShell->mObserved;
MOZ_ASSERT(!observed);
if (mActiveConsumers == 0) {
JS::SetProfileTimelineRecordingEnabled(true);
}
mActiveConsumers++;
ObservedDocShell* obsDocShell = new ObservedDocShell(aDocShell);
@@ -144,6 +148,9 @@ TimelineConsumers::RemoveConsumer(nsDocShell* aDocShell)
MOZ_ASSERT(observed);
mActiveConsumers--;
if (mActiveConsumers == 0) {
JS::SetProfileTimelineRecordingEnabled(false);
}
// Clear all markers from the `mTimelineMarkers` store.
observed.get()->ClearMarkers();
-18
View File
@@ -536,23 +536,5 @@ StyleChildrenIterator::IsNeeded(const Element* aElement)
return false;
}
nsIContent*
StyleChildrenIterator::GetNextChild()
{
while (nsIContent* child = AllChildrenIterator::GetNextChild()) {
if (IsNativeAnonymousImplementationOfPseudoElement(child)) {
// Skip any native-anonymous children that are used to implement pseudo-
// elements. These match pseudo-element selectors instead of being
// considered a child of their host, and thus the style system needs to
// handle them separately.
} else {
return child;
}
}
return nullptr;
}
} // namespace dom
} // namespace mozilla
+51 -16
View File
@@ -7,6 +7,8 @@
#define ChildIterator_h
#include "nsIContent.h"
#include "nsIContentInlines.h"
#include <stdint.h>
/**
* Iterates over the children on a node. If a child is an insertion point,
@@ -17,9 +19,6 @@
* binding's <xbl:content> element.
*/
#include <stdint.h>
#include "nsAutoPtr.h"
class nsIContent;
namespace mozilla {
@@ -189,20 +188,33 @@ protected:
class AllChildrenIterator : private FlattenedChildIterator
{
public:
AllChildrenIterator(const nsIContent* aNode, uint32_t aFlags,
bool aStartAtBeginning = true) :
FlattenedChildIterator(aNode, aFlags, aStartAtBeginning),
mAnonKidsIdx(aStartAtBeginning ? UINT32_MAX : 0),
mFlags(aFlags), mPhase(aStartAtBeginning ? eAtBegin : eAtEnd) { }
AllChildrenIterator(const nsIContent* aNode,
uint32_t aFlags,
bool aStartAtBeginning = true)
: FlattenedChildIterator(aNode, aFlags, aStartAtBeginning)
, mAnonKidsIdx(aStartAtBeginning ? UINT32_MAX : 0)
, mFlags(aFlags), mPhase(aStartAtBeginning ? eAtBegin : eAtEnd)
{
}
AllChildrenIterator(AllChildrenIterator&& aOther)
: FlattenedChildIterator(Move(aOther)),
mAnonKids(Move(aOther.mAnonKids)), mAnonKidsIdx(aOther.mAnonKidsIdx),
mFlags(aOther.mFlags), mPhase(aOther.mPhase)
: FlattenedChildIterator(Move(aOther))
, mAnonKids(Move(aOther.mAnonKids))
, mAnonKidsIdx(aOther.mAnonKidsIdx)
, mFlags(aOther.mFlags)
, mPhase(aOther.mPhase)
#ifdef DEBUG
, mMutationGuard(aOther.mMutationGuard)
, mMutationGuard(aOther.mMutationGuard)
#endif
{}
{
}
AllChildrenIterator& operator=(AllChildrenIterator&& aOther)
{
this->~AllChildrenIterator();
new (this)AllChildrenIterator(Move(aOther));
return *this;
}
#ifdef DEBUG
~AllChildrenIterator() { MOZ_ASSERT(!mMutationGuard.Mutated(0)); }
@@ -268,20 +280,43 @@ private:
*/
class StyleChildrenIterator : private AllChildrenIterator {
public:
explicit StyleChildrenIterator(const nsIContent* aContent)
StyleChildrenIterator(const nsIContent* aContent,
bool aStartAtBeginning = true)
: AllChildrenIterator(aContent,
nsIContent::eAllChildren |
nsIContent::eSkipDocumentLevelNativeAnonymousContent)
nsIContent::eSkipDocumentLevelNativeAnonymousContent,
aStartAtBeginning)
{
MOZ_COUNT_CTOR(StyleChildrenIterator);
}
StyleChildrenIterator(StyleChildrenIterator&& aOther)
: AllChildrenIterator(Move(aOther))
{
MOZ_COUNT_CTOR(StyleChildrenIterator);
}
StyleChildrenIterator& operator=(StyleChildrenIterator&& aOther)
{
AllChildrenIterator::operator=(Move(aOther));
return *this;
}
~StyleChildrenIterator() { MOZ_COUNT_DTOR(StyleChildrenIterator); }
nsIContent* GetNextChild();
static nsIContent* GetParent(const nsIContent& aContent)
{
nsINode* node = aContent.GetFlattenedTreeParentNodeForStyle();
return node && node->IsContent() ? node->AsContent() : nullptr;
}
// Returns true if we cannot find all the children we need to style by
// traversing the siblings of the first child.
static bool IsNeeded(const Element* aParent);
using AllChildrenIterator::GetNextChild;
using AllChildrenIterator::GetPreviousChild;
using AllChildrenIterator::Seek;
};
} // namespace dom
+131 -7
View File
@@ -15,6 +15,7 @@
#include "nsContentUtils.h"
#include "nsHTMLTags.h"
#include "jsapi.h"
#include "ShadowRoot.h"
namespace mozilla {
namespace dom {
@@ -415,6 +416,95 @@ CustomElementRegistry::EnqueueLifecycleCallback(nsIDocument::ElementCallbackType
reactionsStack->EnqueueCallbackReaction(aCustomElement, Move(callback));
}
namespace {
class CandidateFinder
{
public:
CandidateFinder(nsTArray<nsWeakPtr>&& aCandidates, nsIDocument* aDoc);
nsTArray<nsCOMPtr<Element>> OrderedCandidates();
private:
bool Traverse(Element* aRoot, nsTArray<nsCOMPtr<Element>>& aOrderedElements);
nsCOMPtr<nsIDocument> mDoc;
nsInterfaceHashtable<nsPtrHashKey<Element>, Element> mCandidates;
};
CandidateFinder::CandidateFinder(nsTArray<nsWeakPtr>&& aCandidates,
nsIDocument* aDoc)
: mDoc(aDoc)
, mCandidates(aCandidates.Length())
{
MOZ_ASSERT(mDoc);
for (auto& candidate : aCandidates) {
nsCOMPtr<Element> elem = do_QueryReferent(candidate);
if (!elem) {
continue;
}
Element* key = elem.get();
mCandidates.Put(key, elem.forget());
}
}
nsTArray<nsCOMPtr<Element>>
CandidateFinder::OrderedCandidates()
{
if (mCandidates.Count() == 1) {
// Fast path for one candidate.
for (auto iter = mCandidates.Iter(); !iter.Done(); iter.Next()) {
nsTArray<nsCOMPtr<Element>> rval({ Move(iter.Data()) });
iter.Remove();
return rval;
}
}
nsTArray<nsCOMPtr<Element>> orderedElements(mCandidates.Count());
for (Element* child = mDoc->GetFirstElementChild(); child; child = child->GetNextElementSibling()) {
if (!Traverse(child->AsElement(), orderedElements)) {
break;
}
}
return orderedElements;
}
bool
CandidateFinder::Traverse(Element* aRoot, nsTArray<nsCOMPtr<Element>>& aOrderedElements)
{
nsCOMPtr<Element> elem = mCandidates.Get(aRoot);
if (elem) {
mCandidates.Remove(aRoot);
aOrderedElements.AppendElement(Move(elem));
if (mCandidates.Count() == 0) {
return false;
}
}
if (ShadowRoot* root = aRoot->GetShadowRoot()) {
// First iterate the children of the shadow root if aRoot is a shadow host.
for (Element* child = root->GetFirstElementChild(); child;
child = child->GetNextElementSibling()) {
if (!Traverse(child, aOrderedElements)) {
return false;
}
}
}
// Iterate the explicit children of aRoot.
for (Element* child = aRoot->GetFirstElementChild(); child;
child = child->GetNextElementSibling()) {
if (!Traverse(child, aOrderedElements)) {
return false;
}
}
return true;
}
}
void
CustomElementRegistry::UpgradeCandidates(nsIAtom* aKey,
CustomElementDefinition* aDefinition,
@@ -426,18 +516,13 @@ CustomElementRegistry::UpgradeCandidates(nsIAtom* aKey,
return;
}
// TODO: Bug 1326028 - Upgrade custom element in shadow-including tree order
nsAutoPtr<nsTArray<nsWeakPtr>> candidates;
mCandidatesMap.RemoveAndForget(aKey, candidates);
if (candidates) {
CustomElementReactionsStack* reactionsStack =
docGroup->CustomElementReactionsStack();
for (size_t i = 0; i < candidates->Length(); ++i) {
nsCOMPtr<Element> elem = do_QueryReferent(candidates->ElementAt(i));
if (!elem) {
continue;
}
CandidateFinder finder(Move(*candidates), mWindow->GetExtantDoc());
for (auto& elem : finder.OrderedCandidates()) {
reactionsStack->EnqueueUpgradeReaction(elem, aDefinition);
}
}
@@ -791,6 +876,45 @@ CustomElementRegistry::Define(const nsAString& aName,
}
static void
TryUpgrade(nsINode& aNode)
{
Element* element = aNode.IsElement() ? aNode.AsElement() : nullptr;
if (element) {
CustomElementData* ceData = element->GetCustomElementData();
if (ceData) {
NodeInfo* nodeInfo = element->NodeInfo();
nsIAtom* typeAtom = ceData->GetCustomElementType();
CustomElementDefinition* definition =
nsContentUtils::LookupCustomElementDefinition(nodeInfo->GetDocument(),
nodeInfo->NameAtom(),
nodeInfo->NamespaceID(),
typeAtom);
if (definition) {
nsContentUtils::EnqueueUpgradeReaction(element, definition);
}
}
if (ShadowRoot* root = element->GetShadowRoot()) {
for (Element* child = root->GetFirstElementChild(); child;
child = child->GetNextElementSibling()) {
TryUpgrade(*child);
}
}
}
for (Element* child = aNode.GetFirstElementChild(); child;
child = child->GetNextElementSibling()) {
TryUpgrade(*child);
}
}
void
CustomElementRegistry::Upgrade(nsINode& aRoot)
{
TryUpgrade(aRoot);
}
void
CustomElementRegistry::Get(JSContext* aCx, const nsAString& aName,
JS::MutableHandle<JS::Value> aRetVal)
+2
View File
@@ -525,6 +525,8 @@ public:
JS::MutableHandle<JS::Value> aRetVal);
already_AddRefed<Promise> WhenDefined(const nsAString& aName, ErrorResult& aRv);
void Upgrade(nsINode& aRoot);
};
class MOZ_RAII AutoCEReaction final {
+156
View File
@@ -4,11 +4,14 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "DocumentOrShadowRoot.h"
#include "mozilla/EventStateManager.h"
#include "mozilla/dom/StyleSheetList.h"
#include "nsDocument.h"
#include "nsFocusManager.h"
#include "ShadowRoot.h"
#include "XULDocument.h"
#include "nsLayoutUtils.h"
#include "nsSVGUtils.h"
class nsINode;
class nsIDocument;
@@ -144,5 +147,158 @@ DocumentOrShadowRoot::GetRetargetedFocusedElement()
return nullptr;
}
Element*
DocumentOrShadowRoot::GetPointerLockElement()
{
nsCOMPtr<Element> pointerLockedElement =
do_QueryReferent(EventStateManager::sPointerLockedElement);
if (!pointerLockedElement) {
return nullptr;
}
nsIContent* retargetedPointerLockedElement = Retarget(pointerLockedElement);
return
retargetedPointerLockedElement && retargetedPointerLockedElement->IsElement() ?
retargetedPointerLockedElement->AsElement() : nullptr;
}
Element*
DocumentOrShadowRoot::GetFullscreenElement()
{
if (!AsNode().IsInComposedDoc()) {
return nullptr;
}
Element* element = AsNode().OwnerDoc()->FullScreenStackTop();
NS_ASSERTION(!element ||
element->State().HasState(NS_EVENT_STATE_FULL_SCREEN),
"Fullscreen element should have fullscreen styles applied");
nsIContent* retargeted = Retarget(element);
if (retargeted && retargeted->IsElement()) {
return retargeted->AsElement();
}
return nullptr;
}
Element*
DocumentOrShadowRoot::ElementFromPoint(float aX, float aY)
{
return ElementFromPointHelper(aX, aY, false, true);
}
void
DocumentOrShadowRoot::ElementsFromPoint(float aX, float aY,
nsTArray<RefPtr<Element>>& aElements)
{
ElementsFromPointHelper(aX, aY, nsIDocument::FLUSH_LAYOUT, aElements);
}
Element*
DocumentOrShadowRoot::ElementFromPointHelper(float aX, float aY,
bool aIgnoreRootScrollFrame,
bool aFlushLayout)
{
AutoTArray<RefPtr<Element>, 1> elementArray;
ElementsFromPointHelper(aX, aY,
((aIgnoreRootScrollFrame ? nsIDocument::IGNORE_ROOT_SCROLL_FRAME : 0) |
(aFlushLayout ? nsIDocument::FLUSH_LAYOUT : 0) |
nsIDocument::IS_ELEMENT_FROM_POINT),
elementArray);
if (elementArray.IsEmpty()) {
return nullptr;
}
return elementArray[0];
}
void
DocumentOrShadowRoot::ElementsFromPointHelper(float aX, float aY,
uint32_t aFlags,
nsTArray<RefPtr<mozilla::dom::Element>>& aElements)
{
// As per the the spec, we return null if either coord is negative
if (!(aFlags & nsIDocument::IGNORE_ROOT_SCROLL_FRAME) && (aX < 0 || aY < 0)) {
return;
}
nscoord x = nsPresContext::CSSPixelsToAppUnits(aX);
nscoord y = nsPresContext::CSSPixelsToAppUnits(aY);
nsPoint pt(x, y);
nsCOMPtr<nsIDocument> doc = AsNode().OwnerDoc();
// Make sure the layout information we get is up-to-date, and
// ensure we get a root frame (for everything but XUL)
if (aFlags & nsIDocument::FLUSH_LAYOUT) {
doc->FlushPendingNotifications(Flush_Layout);
}
nsIPresShell* ps = doc->GetShell();
if (!ps) {
return;
}
nsIFrame* rootFrame = ps->GetRootFrame();
// XUL docs, unlike HTML, have no frame tree until everything's done loading
if (!rootFrame) {
return; // return null to premature XUL callers as a reminder to wait
}
nsTArray<nsIFrame*> outFrames;
// Emulate what GetFrameAtPoint does, since we want all the frames under our
// point.
nsLayoutUtils::GetFramesForArea(rootFrame, nsRect(pt, nsSize(1, 1)), outFrames,
nsLayoutUtils::IGNORE_PAINT_SUPPRESSION | nsLayoutUtils::IGNORE_CROSS_DOC |
((aFlags & nsIDocument::IGNORE_ROOT_SCROLL_FRAME) ? nsLayoutUtils::IGNORE_ROOT_SCROLL_FRAME : 0));
// Dunno when this would ever happen, as we should at least have a root frame under us?
if (outFrames.IsEmpty()) {
return;
}
// Used to filter out repeated elements in sequence.
nsIContent* lastAdded = nullptr;
for (uint32_t i = 0; i < outFrames.Length(); i++) {
nsIContent* node = doc->GetContentInThisDocument(outFrames[i]);
if (!node || !node->IsElement()) {
// If this helper is called via ElementsFromPoint, we need to make sure
// our frame is an element. Otherwise return whatever the top frame is
// even if it isn't the top-painted element.
// SVG 'text' element's SVGTextFrame doesn't respond to hit-testing, so
// if 'node' is a child of such an element then we need to manually defer
// to the parent here.
if (!(aFlags & nsIDocument::IS_ELEMENT_FROM_POINT) &&
!outFrames[i]->IsSVGText()) {
continue;
}
node = node->GetParent();
if (node) {
ShadowRoot* shadow = ShadowRoot::FromNode(node);
if (shadow) {
node = shadow->Host();
}
}
}
//XXXsmaug There is plenty of unspec'ed behavior here
// https://github.com/w3c/webcomponents/issues/735
// https://github.com/w3c/webcomponents/issues/736
node = Retarget(node);
if (node && node != lastAdded) {
aElements.AppendElement(node->AsElement());
lastAdded = node;
// If this helper is called via ElementFromPoint, just return the first
// element we find.
if (aFlags & nsIDocument::IS_ELEMENT_FROM_POINT) {
return;
}
}
}
}
}
}
+26
View File
@@ -114,6 +114,32 @@ public:
~DocumentOrShadowRoot() = default;
Element* GetPointerLockElement();
Element* GetFullscreenElement();
Element* ElementFromPoint(float aX, float aY);
void ElementsFromPoint(float aX, float aY,
nsTArray<RefPtr<mozilla::dom::Element>>& aElements);
/**
* Helper for nsIDOMDocument::elementFromPoint implementation that allows
* ignoring the scroll frame and/or avoiding layout flushes.
*
* @see nsIDOMWindowUtils::elementFromPoint
*/
Element* ElementFromPointHelper(float aX, float aY,
bool aIgnoreRootScrollFrame,
bool aFlushLayout);
enum ElementsFromPointFlags
{
IGNORE_ROOT_SCROLL_FRAME = 1,
FLUSH_LAYOUT = 2,
IS_ELEMENT_FROM_POINT = 4
};
void ElementsFromPointHelper(float aX, float aY, uint32_t aFlags,
nsTArray<RefPtr<mozilla::dom::Element>>& aElements);
protected:
nsIContent* Retarget(nsIContent* aContent) const;
+12 -21
View File
@@ -1122,18 +1122,6 @@ Element::AttachShadow(const ShadowRootInit& aInit, ErrorResult& aError)
return nullptr;
}
return AttachShadowInternal(aInit.mMode == ShadowRootMode::Closed, aError);
}
already_AddRefed<ShadowRoot>
Element::CreateShadowRoot(ErrorResult& aError)
{
return AttachShadowInternal(false, aError);
}
already_AddRefed<ShadowRoot>
Element::AttachShadowInternal(bool aClosed, ErrorResult& aError)
{
/**
* 3. If context object is a shadow host, then throw
* an "InvalidStateError" DOMException.
@@ -1179,8 +1167,9 @@ Element::AttachShadowInternal(bool aClosed, ErrorResult& aError)
* context object???s node document, host is context object,
* and mode is init???s mode.
*/
bool isClosed = (aInit.mMode == ShadowRootMode::Closed);
RefPtr<ShadowRoot> shadowRoot =
new ShadowRoot(this, aClosed, nodeInfo.forget(), protoBinding);
new ShadowRoot(this, isClosed, nodeInfo.forget(), protoBinding);
shadowRoot->SetIsComposedDocParticipant(IsInComposedDoc());
@@ -1717,10 +1706,11 @@ Element::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
if (!hadParent) {
uint32_t editableDescendantChange = EditableInclusiveDescendantCount(this);
if (editableDescendantChange != 0) {
// If we are binding a subtree root to the document, we need to update
// the editable descendant count of all the ancestors.
// If we are binding a subtree root to the document, we need to update
// the editable descendant count of all the ancestors. However, we don't
// cross the Shadow DOM boundary (expected behavior is unclear).
nsIContent* parent = GetParent();
while (parent) {
while (parent && parent->IsElement()) {
parent->ChangeEditableDescendantCount(editableDescendantChange);
parent = parent->GetParent();
}
@@ -3428,9 +3418,9 @@ Element::Closest(const nsAString& aSelector, ErrorResult& aResult)
matchingContext.AddScopeElement(this);
for (nsINode* node = this; node; node = node->GetParentNode()) {
if (node->IsElement() &&
nsCSSRuleProcessor::SelectorListMatches(node->AsElement(),
matchingContext,
selectorList)) {
nsCSSRuleProcessor::RestrictedSelectorListMatches(node->AsElement(),
matchingContext,
selectorList)) {
return node->AsElement();
}
}
@@ -3454,8 +3444,9 @@ Element::Matches(const nsAString& aSelector, ErrorResult& aError)
TreeMatchContext::eNeverMatchVisited);
matchingContext.SetHasSpecifiedScope();
matchingContext.AddScopeElement(this);
return nsCSSRuleProcessor::SelectorListMatches(this, matchingContext,
selectorList);
return nsCSSRuleProcessor::RestrictedSelectorListMatches(this,
matchingContext,
selectorList);
}
static const nsAttrValue::EnumTable kCORSAttributeTable[] = {
-6
View File
@@ -470,9 +470,6 @@ protected:
mState &= ~aStates;
}
already_AddRefed<ShadowRoot> AttachShadowInternal(bool aClosed,
ErrorResult& aError);
private:
// Need to allow the ESM, nsGlobalWindow, and the focus manager to
// set our state
@@ -930,9 +927,6 @@ public:
void SetSlot(const nsAString& aName, ErrorResult& aError);
void GetSlot(nsAString& aName);
// [deprecated] Shadow DOM v0
already_AddRefed<ShadowRoot> CreateShadowRoot(ErrorResult& aError);
ShadowRoot *FastGetShadowRoot() const
{
nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
+116 -15
View File
@@ -797,6 +797,22 @@ FindChromeAccessOnlySubtreeOwner(nsIContent* aContent)
return aContent;
}
already_AddRefed<nsINode>
FindChromeAccessOnlySubtreeOwner(EventTarget* aTarget)
{
nsCOMPtr<nsINode> node = do_QueryInterface(aTarget);
if (!node || !node->ChromeOnlyAccess()) {
return node.forget();
}
if (!node->IsContent()) {
return nullptr;
}
node = FindChromeAccessOnlySubtreeOwner(node->AsContent());
return node.forget();
}
nsresult
nsIContent::GetEventTargetParent(EventChainPreVisitor& aVisitor)
{
@@ -817,24 +833,11 @@ nsIContent::GetEventTargetParent(EventChainPreVisitor& aVisitor)
// chrome access only subtree or if we are about to propagate out of
// a shadow root to a shadow root host.
((this == aVisitor.mEvent->mOriginalTarget &&
!ChromeOnlyAccess()) || isAnonForEvents || GetShadowRoot())) {
!ChromeOnlyAccess()) || isAnonForEvents)) {
nsCOMPtr<nsIContent> relatedTarget =
do_QueryInterface(aVisitor.mEvent->AsMouseEvent()->mRelatedTarget);
if (relatedTarget &&
relatedTarget->OwnerDoc() == OwnerDoc()) {
// In the web components case, we may need to stop propagation of events
// at shadow root host.
if (GetShadowRoot()) {
nsIContent* adjustedTarget =
Event::GetShadowRelatedTarget(this, relatedTarget);
if (this == adjustedTarget) {
aVisitor.SetParentTarget(nullptr, false);
aVisitor.mCanHandle = false;
return NS_OK;
}
}
// If current target is anonymous for events or we know that related
// target is descendant of an element which is anonymous for events,
// we may want to stop event propagation.
@@ -950,6 +953,104 @@ nsIContent::GetEventTargetParent(EventChainPreVisitor& aVisitor)
} else {
aVisitor.SetParentTarget(GetComposedDoc(), false);
}
if (!ChromeOnlyAccess() && !aVisitor.mRelatedTargetRetargetedInCurrentScope) {
// We don't support Shadow DOM in native anonymous content yet.
aVisitor.mRelatedTargetRetargetedInCurrentScope = true;
if (aVisitor.mEvent->mOriginalRelatedTarget) {
// https://dom.spec.whatwg.org/#concept-event-dispatch
// Step 3.
// "Let relatedTarget be the result of retargeting event's relatedTarget
// against target if event's relatedTarget is non-null, and null
// otherwise."
//
// This is a bit complicated because the event might be from native
// anonymous content, but we need to deal with non-native anonymous
// content there.
bool initialTarget = this == aVisitor.mEvent->mOriginalTarget;
nsCOMPtr<nsINode> originalTargetAsNode;
// Use of mOriginalTargetIsInAnon is an optimization here.
if (!initialTarget && aVisitor.mOriginalTargetIsInAnon) {
originalTargetAsNode =
FindChromeAccessOnlySubtreeOwner(aVisitor.mEvent->mOriginalTarget);
initialTarget = originalTargetAsNode == this;
}
if (initialTarget) {
nsCOMPtr<nsINode> relatedTargetAsNode =
FindChromeAccessOnlySubtreeOwner(aVisitor.mEvent->mOriginalRelatedTarget);
if (!originalTargetAsNode) {
originalTargetAsNode =
do_QueryInterface(aVisitor.mEvent->mOriginalTarget);
}
if (relatedTargetAsNode && originalTargetAsNode) {
nsINode* retargetedRelatedTarget =
nsContentUtils::Retarget(relatedTargetAsNode, originalTargetAsNode);
if (originalTargetAsNode == retargetedRelatedTarget &&
retargetedRelatedTarget != relatedTargetAsNode) {
// Step 4.
// "If target is relatedTarget and target is not event's
// relatedTarget, then return true."
aVisitor.IgnoreCurrentTargetBecauseOfShadowDOMRetargeting();
// Old code relies on mTarget to point to the first element which
// was not added to the event target chain because of mCanHandle
// being false, but in Shadow DOM case mTarget really should
// point to a node in Shadow DOM.
aVisitor.mEvent->mTarget = aVisitor.mTargetInKnownToBeHandledScope;
return NS_OK;
}
// Part of step 5. Retargeting target has happened already higher
// up in this method.
// "Append to an event path with event, target, targetOverride,
// relatedTarget, and false."
aVisitor.mRetargetedRelatedTarget = retargetedRelatedTarget;
}
} else {
nsCOMPtr<nsINode> relatedTargetAsNode =
FindChromeAccessOnlySubtreeOwner(aVisitor.mEvent->mOriginalRelatedTarget);
if (relatedTargetAsNode) {
// Step 11.3.
// "Let relatedTarget be the result of retargeting event's
// relatedTarget against parent if event's relatedTarget is non-null,
// and null otherwise.".
nsINode* retargetedRelatedTarget =
nsContentUtils::Retarget(relatedTargetAsNode, this);
nsCOMPtr<nsINode> targetInKnownToBeHandledScope =
FindChromeAccessOnlySubtreeOwner(aVisitor.mTargetInKnownToBeHandledScope);
if (nsContentUtils::ContentIsShadowIncludingDescendantOf(
this, targetInKnownToBeHandledScope->SubtreeRoot())) {
// Part of step 11.4.
// "If target's root is a shadow-including inclusive ancestor of
// parent, then"
// "...Append to an event path with event, parent, null, relatedTarget,
// " and slot-in-closed-tree."
aVisitor.mRetargetedRelatedTarget = retargetedRelatedTarget;
} else if (this == retargetedRelatedTarget) {
// Step 11.5
// "Otherwise, if parent and relatedTarget are identical, then set
// parent to null."
aVisitor.IgnoreCurrentTargetBecauseOfShadowDOMRetargeting();
// Old code relies on mTarget to point to the first element which
// was not added to the event target chain because of mCanHandle
// being false, but in Shadow DOM case mTarget really should
// point to a node in Shadow DOM.
aVisitor.mEvent->mTarget = aVisitor.mTargetInKnownToBeHandledScope;
return NS_OK;
} else {
// Step 11.6
aVisitor.mRetargetedRelatedTarget = retargetedRelatedTarget;
}
}
}
}
}
if (slot) {
// Inform that we're about to exit the current scope.
aVisitor.mRelatedTargetRetargetedInCurrentScope = false;
}
return NS_OK;
}
@@ -1917,7 +2018,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(FragmentOrElement)
}
nsAutoCString orphan;
if (!tmp->IsInUncomposedDoc() &&
if (!tmp->IsInComposedDoc() &&
// Ignore xbl:content, which is never in the document and hence always
// appears to be orphaned.
!tmp->NodeInfo()->Equals(nsGkAtoms::content, kNameSpaceID_XBL)) {
+58 -25
View File
@@ -9,6 +9,7 @@
#include "mozilla/dom/DocumentFragment.h"
#include "ChildIterator.h"
#include "nsContentUtils.h"
#include "nsLayoutUtils.h"
#include "nsDOMClassInfoID.h"
#include "nsIDOMHTMLElement.h"
#include "nsIStyleSheetLinkingElement.h"
@@ -101,6 +102,23 @@ ShadowRoot::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
return mozilla::dom::ShadowRootBinding::Wrap(aCx, this, aGivenProto);
}
void
ShadowRoot::CloneInternalDataFrom(ShadowRoot* aOther)
{
size_t sheetCount = aOther->SheetCount();
for (size_t i = 0; i < sheetCount; ++i) {
StyleSheet* sheet = aOther->SheetAt(i);
if (sheet && sheet->IsApplicable()) {
// TODO: Remove AsGecko() call once Stylo is removed.
RefPtr<CSSStyleSheet> clonedSheet =
sheet->AsGecko()->Clone(nullptr, nullptr, nullptr, nullptr);
if (clonedSheet) {
AppendStyleSheet(*clonedSheet);
}
}
}
}
ShadowRoot*
ShadowRoot::FromNode(nsINode* aNode)
{
@@ -145,6 +163,19 @@ ShadowRoot::AddSlot(HTMLSlotElement* aSlot)
oldSlot->RemoveAssignedNode(assignedNode);
currentSlot->AppendAssignedNode(assignedNode);
Element* restyleElement;
if (assignedNode->IsElement()) {
restyleElement = assignedNode->AsElement();
} else {
// This is likely a text node. Use the host instead.
restyleElement = GetHost();
}
if (restyleElement) {
nsLayoutUtils::PostRestyleEvent(
restyleElement, eRestyle_Subtree, nsChangeHint(0));
}
doEnqueueSlotChange = true;
}
@@ -262,6 +293,13 @@ ShadowRoot::InsertSheet(StyleSheet* aSheet,
}
nsINode* sheetOwningNode = SheetAt(i)->GetOwnerNode();
if (!sheetOwningNode) {
// Keep moving; all sheets with a sheetOwner come after all
// sheets without an owning Node
continue;
}
if (nsContentUtils::PositionIsBefore(aLinkingContent, sheetOwningNode)) {
InsertSheetAt(i, *aSheet);
mProtoBinding->InsertStyleSheetAt(i, aSheet);
@@ -311,6 +349,8 @@ ShadowRoot::GetEventTargetParent(EventChainPreVisitor& aVisitor)
{
aVisitor.mCanHandle = true;
aVisitor.mRootOfClosedTree = IsClosed();
// Inform that we're about to exit the current scope.
aVisitor.mRelatedTargetRetargetedInCurrentScope = false;
// https://dom.spec.whatwg.org/#ref-for-get-the-parent%E2%91%A6
if (!aVisitor.mEvent->mFlags.mComposed) {
@@ -333,12 +373,10 @@ ShadowRoot::GetEventTargetParent(EventChainPreVisitor& aVisitor)
nsIContent* shadowHost = GetHost();
aVisitor.SetParentTarget(shadowHost, false);
if (aVisitor.mOriginalTargetIsInAnon) {
nsCOMPtr<nsIContent> content(do_QueryInterface(aVisitor.mEvent->mTarget));
if (content && content->GetBindingParent() == shadowHost) {
aVisitor.mEventTargetAtParent = shadowHost;
}
}
nsCOMPtr<nsIContent> content(do_QueryInterface(aVisitor.mEvent->mTarget));
if (content && content->GetBindingParent() == shadowHost) {
aVisitor.mEventTargetAtParent = shadowHost;
}
return NS_OK;
}
@@ -488,25 +526,6 @@ ShadowRoot::Host()
return host->AsElement();
}
bool
ShadowRoot::ApplyAuthorStyles()
{
return mProtoBinding->InheritsStyle();
}
void
ShadowRoot::SetApplyAuthorStyles(bool aApplyAuthorStyles)
{
mProtoBinding->SetInheritsStyle(aApplyAuthorStyles);
nsIPresShell* shell = OwnerDoc()->GetShell();
if (shell) {
OwnerDoc()->BeginUpdate(UPDATE_STYLE);
shell->RecordShadowStyleChange(this);
OwnerDoc()->EndUpdate(UPDATE_STYLE);
}
}
void
ShadowRoot::AttributeChanged(nsIDocument* aDocument,
Element* aElement,
@@ -580,6 +599,13 @@ ShadowRoot::ContentInserted(nsIDocument* aDocument,
if (slot && slot->GetContainingShadow() == this &&
slot->AssignedNodes().IsEmpty()) {
slot->EnqueueSlotChangeEvent();
return;
}
// XXX: The following makes the host destroy its frames and force a
// restyle for cases where the content isn't slotted.
if (aContainer == this) {
DistributionChanged();
}
}
@@ -616,6 +642,13 @@ ShadowRoot::ContentRemoved(nsIDocument* aDocument,
if (slot && slot->GetContainingShadow() == this &&
slot->AssignedNodes().IsEmpty()) {
slot->EnqueueSlotChangeEvent();
return;
}
// XXX: The following makes the host destroy its frames and force a
// restyle for cases where the content isn't slotted.
if (aContainer == this) {
DistributionChanged();
}
}
+5 -2
View File
@@ -59,13 +59,16 @@ public:
// [deprecated] Shadow DOM v0
void InsertSheet(StyleSheet* aSheet, nsIContent* aLinkingContent);
void RemoveSheet(StyleSheet* aSheet);
bool ApplyAuthorStyles();
void SetApplyAuthorStyles(bool aApplyAuthorStyles);
StyleSheetList* StyleSheets()
{
return &DocumentOrShadowRoot::EnsureDOMStyleSheets();
}
/**
* Clones internal state, for example stylesheets, of aOther to 'this'.
*/
void CloneInternalDataFrom(ShadowRoot* aOther);
/**
* Distributes all the explicit children of the pool host to the content
* insertion points in this ShadowRoot.
+1 -2
View File
@@ -5,8 +5,7 @@
<body>
<div id="host"></div>
<script>
var s = host.createShadowRoot();
s.innerHTML = '<input type="range" />';
host.attachShadow({ mode: "open" }).innerHTML = '<input type="range" />';
</script>
</body>
</html>
+1 -1
View File
@@ -3,7 +3,7 @@
<body>
<script>
var x = document.createElement('span');
x.createShadowRoot();
x.attachShadow({ mode: "open" });
x.id = 'a';
</script>
</body>
-33
View File
@@ -1,33 +0,0 @@
<!DOCTYPE html>
<html>
<body>
<style>
#foo {
overflow: scroll;
height: 100px;
}
</style>
<div id="foo">
Mozilla Firefox<br>
Mozilla Firefox<br>
Mozilla Firefox<br>
Mozilla Firefox<br>
Mozilla Firefox<br>
Mozilla Firefox<br>
Mozilla Firefox<br>
Mozilla Firefox<br>
Mozilla Firefox<br>
Mozilla Firefox<br>
Mozilla Firefox<br>
Mozilla Firefox<br>
Mozilla Firefox<br>
Mozilla Firefox<br>
Mozilla Firefox<br>
Mozilla Firefox<br>
Mozilla Firefox<br>
Mozilla Firefox<br>
<script>
foo.createShadowRoot().innerHTML = "<content></content>";
</script>
</body>
</html>
+17
View File
@@ -0,0 +1,17 @@
<html>
<head>
<script>
function fun_0() {
document.implementation.createDocument('', '', null).adoptNode(o2);
}
o1 = document.createElement('map');
o2 = document.createElement('iframe');
document.documentElement.appendChild(o1);
document.documentElement.appendChild(o2);
o1.textContent = 'x';
document.addEventListener('DOMNodeRemoved', fun_0, false);
o1.innerText = 'x';
</script>
</head>
</html>
+1
View File
@@ -209,6 +209,7 @@ load 1230422.html
load 1251361.html
load 1304437.html
pref(clipboard.autocopy,true) load 1385272-1.html
load 1393806.html
pref(dom.webcomponents.enabled,true) load 1341693.html
pref(dom.webcomponents.enabled,true) load 1419799.html
pref(dom.webcomponents.enabled,false) load 1422931.html
+4 -3
View File
@@ -222,7 +222,7 @@ EXPORTS.mozilla.dom += [
'WindowOrientationObserver.h',
]
SOURCES += [
UNIFIED_SOURCES += [
'AnonymousContent.cpp',
'Attr.cpp',
'BarProps.cpp',
@@ -238,7 +238,6 @@ SOURCES += [
'DirectionalityUtils.cpp',
'DocGroup.cpp',
'DocumentFragment.cpp',
'DocumentOrShadowRoot.cpp',
'DocumentType.cpp',
'DOMCursor.cpp',
'DOMError.cpp',
@@ -373,12 +372,14 @@ SOURCES += [
]
if CONFIG['MOZ_WEBRTC']:
SOURCES += [
UNIFIED_SOURCES += [
'nsDOMDataChannel.cpp',
]
# these files couldn't be in UNIFIED_SOURCES for now for reasons given below:
SOURCES += [
# DocumentOrShadowRoot conflicts with mozilla::dom::ShadowRoot
'DocumentOrShadowRoot.cpp',
# Several conflicts with other bindings.
'DOMIntersectionObserver.cpp',
# Because of OS X headers.
+215 -8
View File
@@ -2248,6 +2248,34 @@ nsContentUtils::ContentIsHostIncludingDescendantOf(
return false;
}
bool
nsContentUtils::ContentIsShadowIncludingDescendantOf(
const nsINode* aPossibleDescendant, const nsINode* aPossibleAncestor)
{
MOZ_ASSERT(aPossibleDescendant, "The possible descendant is null!");
MOZ_ASSERT(aPossibleAncestor, "The possible ancestor is null!");
if (aPossibleAncestor == aPossibleDescendant->GetComposedDoc()) {
return true;
}
do {
if (aPossibleDescendant == aPossibleAncestor) {
return true;
}
if (aPossibleDescendant->NodeType() == nsIDOMNode::DOCUMENT_FRAGMENT_NODE) {
ShadowRoot* shadowRoot =
ShadowRoot::FromNode(const_cast<nsINode*>(aPossibleDescendant));
aPossibleDescendant = shadowRoot ? shadowRoot->GetHost() : nullptr;
} else {
aPossibleDescendant = aPossibleDescendant->GetParentNode();
}
} while (aPossibleDescendant);
return false;
}
// static
bool
nsContentUtils::ContentIsCrossDocDescendantOf(nsINode* aPossibleDescendant,
@@ -2266,6 +2294,30 @@ nsContentUtils::ContentIsCrossDocDescendantOf(nsINode* aPossibleDescendant,
return false;
}
// static
nsINode*
nsContentUtils::Retarget(nsINode* aTargetA, nsINode* aTargetB)
{
while (true && aTargetA) {
// If A's root is not a shadow root...
nsINode* root = aTargetA->SubtreeRoot();
// TODO: replace with IsShadowRoot() check once bug 1427511 lands.
if (!ShadowRoot::FromNode(root)) {
// ...then return A.
return aTargetA;
}
// or A's root is a shadow-including inclusive ancestor of B...
if (nsContentUtils::ContentIsShadowIncludingDescendantOf(aTargetB, root)) {
// ...then return A.
return aTargetA;
}
aTargetA = ShadowRoot::FromNode(root)->GetHost();
}
return nullptr;
}
// static
nsresult
@@ -2377,6 +2429,56 @@ nsContentUtils::GetCommonAncestor(nsINode* aNode1,
return parent;
}
// static
nsINode*
nsContentUtils::GetCommonAncestorUnderInteractiveContent(nsINode* aNode1,
nsINode* aNode2)
{
if (!aNode1 || !aNode2) {
return nullptr;
}
if (aNode1 == aNode2) {
return aNode1;
}
// Build the chain of parents
AutoTArray<nsINode*, 30> parents1;
do {
parents1.AppendElement(aNode1);
if (aNode1->IsElement() &&
aNode1->AsElement()->IsInteractiveHTMLContent(true)) {
break;
}
aNode1 = aNode1->GetFlattenedTreeParentNode();
} while (aNode1);
AutoTArray<nsINode*, 30> parents2;
do {
parents2.AppendElement(aNode2);
if (aNode2->IsElement() &&
aNode2->AsElement()->IsInteractiveHTMLContent(true)) {
break;
}
aNode2 = aNode2->GetFlattenedTreeParentNode();
} while (aNode2);
// Find where the parent chain differs
uint32_t pos1 = parents1.Length();
uint32_t pos2 = parents2.Length();
nsINode* parent = nullptr;
for (uint32_t len = std::min(pos1, pos2); len > 0; --len) {
nsINode* child1 = parents1.ElementAt(--pos1);
nsINode* child2 = parents2.ElementAt(--pos2);
if (child1 != child2) {
break;
}
parent = child1;
}
return parent;
}
/* static */
bool
nsContentUtils::PositionIsBefore(nsINode* aNode1, nsINode* aNode2)
@@ -6332,9 +6434,7 @@ nsContentUtils::IsFocusedContent(const nsIContent* aContent)
bool
nsContentUtils::IsSubDocumentTabbable(nsIContent* aContent)
{
//XXXsmaug Shadow DOM spec issue!
// We may need to change this to GetComposedDoc().
nsIDocument* doc = aContent->GetUncomposedDoc();
nsIDocument* doc = aContent->GetComposedDoc();
if (!doc) {
return false;
}
@@ -7056,16 +7156,26 @@ nsContentUtils::HasDistributedChildren(nsIContent* aContent)
// static
bool
nsContentUtils::IsForbiddenRequestHeader(const nsACString& aHeader)
nsContentUtils::IsForbiddenRequestHeader(const nsACString& aHeader,
const nsACString& aValue)
{
if (IsForbiddenSystemRequestHeader(aHeader)) {
return true;
}
if ((nsContentUtils::IsOverrideMethodHeader(aHeader) &&
nsContentUtils::ContainsForbiddenMethod(aValue))) {
return true;
}
return StringBeginsWith(aHeader, NS_LITERAL_CSTRING("proxy-"),
nsCaseInsensitiveCStringComparator()) ||
StringBeginsWith(aHeader, NS_LITERAL_CSTRING("sec-"),
nsCaseInsensitiveCStringComparator());
if (StringBeginsWith(aHeader, NS_LITERAL_CSTRING("proxy-"),
nsCaseInsensitiveCStringComparator()) ||
StringBeginsWith(aHeader, NS_LITERAL_CSTRING("sec-"),
nsCaseInsensitiveCStringComparator())) {
return true;
}
return false;
}
// static
@@ -7094,6 +7204,64 @@ nsContentUtils::IsForbiddenResponseHeader(const nsACString& aHeader)
aHeader.LowerCaseEqualsASCII("set-cookie2"));
}
// static
bool
nsContentUtils::IsOverrideMethodHeader(const nsACString& headerName) {
return headerName.LowerCaseEqualsASCII("x-http-method-override") ||
headerName.LowerCaseEqualsASCII("x-http-method") ||
headerName.LowerCaseEqualsASCII("x-method-override");
}
// static
bool
nsContentUtils::ContainsForbiddenMethod(const nsACString& headerValue) {
bool hasInsecureMethod = false;
nsCCharSeparatedTokenizer tokenizer(headerValue, ',');
while (tokenizer.hasMoreTokens()) {
const nsDependentCSubstring& value = tokenizer.nextToken();
if (value.LowerCaseEqualsASCII("connect") ||
value.LowerCaseEqualsASCII("trace") ||
value.LowerCaseEqualsASCII("track")) {
hasInsecureMethod = true;
break;
}
}
return hasInsecureMethod;
}
// static
bool nsContentUtils::IsCorsUnsafeRequestHeaderValue(
const nsACString& aHeaderValue) {
const char* cur = aHeaderValue.BeginReading();
const char* end = aHeaderValue.EndReading();
while (cur != end) {
// Implementation of
// https://fetch.spec.whatwg.org/#cors-unsafe-request-header-byte Is less
// than a space but not a horizontal tab
if ((*cur < ' ' && *cur != '\t') || *cur == '"' || *cur == '(' ||
*cur == ')' || *cur == ':' || *cur == '<' || *cur == '>' ||
*cur == '?' || *cur == '@' || *cur == '[' || *cur == '\\' ||
*cur == ']' || *cur == '{' || *cur == '}' ||
*cur == 0x7F) { // 0x75 is DEL
return true;
}
cur++;
}
return false;
}
// static
bool nsContentUtils::IsAllowedNonCorsAccept(const nsACString& aHeaderValue) {
if (IsCorsUnsafeRequestHeaderValue(aHeaderValue)) {
return false;
}
return true;
}
// static
bool
nsContentUtils::IsAllowedNonCorsContentType(const nsACString& aHeaderValue)
@@ -7101,6 +7269,10 @@ nsContentUtils::IsAllowedNonCorsContentType(const nsACString& aHeaderValue)
nsAutoCString contentType;
nsAutoCString unused;
if (IsCorsUnsafeRequestHeaderValue(aHeaderValue)) {
return false;
}
nsresult rv = NS_ParseRequestContentType(aHeaderValue, contentType, unused);
if (NS_FAILED(rv)) {
return false;
@@ -7111,6 +7283,41 @@ nsContentUtils::IsAllowedNonCorsContentType(const nsACString& aHeaderValue)
contentType.LowerCaseEqualsLiteral("multipart/form-data");
}
// static
bool nsContentUtils::IsAllowedNonCorsLanguage(const nsACString& aHeaderValue) {
const char* cur = aHeaderValue.BeginReading();
const char* end = aHeaderValue.EndReading();
while (cur != end) {
if ((*cur >= '0' && *cur <= '9') || (*cur >= 'A' && *cur <= 'Z') ||
(*cur >= 'a' && *cur <= 'z') || *cur == ' ' || *cur == '*' ||
*cur == ',' || *cur == '-' || *cur == '.' || *cur == ';' ||
*cur == '=') {
cur++;
continue;
}
return false;
}
return true;
}
// static
bool nsContentUtils::IsCORSSafelistedRequestHeader(const nsACString& aName,
const nsACString& aValue) {
// See https://fetch.spec.whatwg.org/#cors-safelisted-request-header
if (aValue.Length() > 128) {
return false;
}
return (aName.LowerCaseEqualsLiteral("accept") &&
nsContentUtils::IsAllowedNonCorsAccept(aValue)) ||
(aName.LowerCaseEqualsLiteral("accept-language") &&
nsContentUtils::IsAllowedNonCorsLanguage(aValue)) ||
(aName.LowerCaseEqualsLiteral("content-language") &&
nsContentUtils::IsAllowedNonCorsLanguage(aValue)) ||
(aName.LowerCaseEqualsLiteral("content-type") &&
nsContentUtils::IsAllowedNonCorsContentType(aValue));
}
bool
nsContentUtils::DOMWindowDumpEnabled()
{
+57 -1
View File
@@ -279,6 +279,13 @@ public:
static bool ContentIsHostIncludingDescendantOf(
const nsINode* aPossibleDescendant, const nsINode* aPossibleAncestor);
/**
* Similar to above, but does special case only ShadowRoot,
* not HTMLTemplateElement.
*/
static bool ContentIsShadowIncludingDescendantOf(
const nsINode* aPossibleDescendant, const nsINode* aPossibleAncestor);
/**
* Similar to ContentIsDescendantOf except it crosses document boundaries,
* this function uses ancestor/descendant relations in the composed document
@@ -287,6 +294,13 @@ public:
static bool ContentIsCrossDocDescendantOf(nsINode* aPossibleDescendant,
nsINode* aPossibleAncestor);
/**
* Retarget an object A against an object B
* @see https://dom.spec.whatwg.org/#retarget
*/
static nsINode*
Retarget(nsINode* aTargetA, nsINode* aTargetB);
/*
* This method fills the |aArray| with all ancestor nodes of |aNode|
* including |aNode| at the zero index.
@@ -324,6 +338,15 @@ public:
static nsINode* GetCommonAncestor(nsINode* aNode1,
nsINode* aNode2);
/**
* Returns the common ancestor under interactive content, if any.
* If neither one has interactive content as ancestor, common ancestor will be
* returned. If only one has interactive content as ancestor, null will be
* returned. If the nodes are the same, that node is returned.
*/
static nsINode* GetCommonAncestorUnderInteractiveContent(nsINode* aNode1,
nsINode* aNode2);
/**
* Returns true if aNode1 is before aNode2 in the same connected
* tree.
@@ -2425,7 +2448,8 @@ public:
* Returns whether a given header is forbidden for an XHR or fetch
* request.
*/
static bool IsForbiddenRequestHeader(const nsACString& aHeader);
static bool IsForbiddenRequestHeader(const nsACString& aHeader,
const nsACString& aValue);
/**
* Returns whether a given header is forbidden for a system XHR
@@ -2433,18 +2457,50 @@ public:
*/
static bool IsForbiddenSystemRequestHeader(const nsACString& aHeader);
/**
* Returns whether a given header has characters that aren't permitted
*/
static bool IsCorsUnsafeRequestHeaderValue(const nsACString& aHeaderValue);
/**
* Returns whether a given Accept header value is allowed
* for a non-CORS XHR or fetch request.
*/
static bool IsAllowedNonCorsAccept(const nsACString& aHeaderValue);
/**
* Returns whether a given Content-Type header value is allowed
* for a non-CORS XHR or fetch request.
*/
static bool IsAllowedNonCorsContentType(const nsACString& aHeaderValue);
/**
* Returns whether a given Content-Language or accept-language header value is
* allowed for a non-CORS XHR or fetch request.
*/
static bool IsAllowedNonCorsLanguage(const nsACString& aHeaderValue);
/**
* Returns whether a given header and value is a CORS-safelisted request
* header per https://fetch.spec.whatwg.org/#cors-safelisted-request-header
*/
static bool IsCORSSafelistedRequestHeader(const nsACString& aName,
const nsACString& aValue);
/**
* Returns whether a given header is forbidden for an XHR or fetch
* response.
*/
static bool IsForbiddenResponseHeader(const nsACString& aHeader);
/**
* Checks whether the header overrides any http methods
*/
static bool IsOverrideMethodHeader(const nsACString& headerName);
/**
* Checks whether the header value contains any forbidden method
*/
static bool ContainsForbiddenMethod(const nsACString& headerValue);
/**
* Returns the inner window ID for the window associated with a request,
*/
+1 -70
View File
@@ -2367,75 +2367,6 @@ nsDOMWindowUtils::GetCurrentAudioBackend(nsAString& aBackend)
return NS_OK;
}
NS_IMETHODIMP
nsDOMWindowUtils::StartFrameTimeRecording(uint32_t *startIndex)
{
NS_ENSURE_ARG_POINTER(startIndex);
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget)
return NS_ERROR_FAILURE;
LayerManager *mgr = widget->GetLayerManager();
if (!mgr)
return NS_ERROR_FAILURE;
const uint32_t kRecordingMinSize = 60 * 10; // 10 seconds @60 fps.
const uint32_t kRecordingMaxSize = 60 * 60 * 60; // One hour
uint32_t bufferSize = Preferences::GetUint("toolkit.framesRecording.bufferSize", uint32_t(0));
bufferSize = std::min(bufferSize, kRecordingMaxSize);
bufferSize = std::max(bufferSize, kRecordingMinSize);
*startIndex = mgr->StartFrameTimeRecording(bufferSize);
return NS_OK;
}
NS_IMETHODIMP
nsDOMWindowUtils::StopFrameTimeRecording(uint32_t startIndex,
uint32_t *frameCount,
float **frameIntervals)
{
NS_ENSURE_ARG_POINTER(frameCount);
NS_ENSURE_ARG_POINTER(frameIntervals);
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget)
return NS_ERROR_FAILURE;
LayerManager *mgr = widget->GetLayerManager();
if (!mgr)
return NS_ERROR_FAILURE;
nsTArray<float> tmpFrameIntervals;
mgr->StopFrameTimeRecording(startIndex, tmpFrameIntervals);
*frameCount = tmpFrameIntervals.Length();
*frameIntervals = (float*)moz_xmalloc(*frameCount * sizeof(float));
/* copy over the frame intervals and paint times into the arrays we just allocated */
for (uint32_t i = 0; i < *frameCount; i++) {
(*frameIntervals)[i] = tmpFrameIntervals[i];
}
return NS_OK;
}
NS_IMETHODIMP
nsDOMWindowUtils::BeginTabSwitch()
{
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget)
return NS_ERROR_FAILURE;
LayerManager *mgr = widget->GetLayerManager();
if (!mgr)
return NS_ERROR_FAILURE;
mgr->BeginTabSwitch();
return NS_OK;
}
static bool
ComputeAnimationValue(nsCSSPropertyID aProperty,
Element* aElement,
@@ -2478,7 +2409,7 @@ nsDOMWindowUtils::AdvanceTimeAndRefresh(int64_t aMilliseconds)
nsPresContext* presContext = GetPresContext();
if (presContext) {
nsRefreshDriver* driver = presContext->RefreshDriver();
RefPtr<nsRefreshDriver> driver = presContext->RefreshDriver();
driver->AdvanceTimeAndRefresh(aMilliseconds);
RefPtr<LayerTransactionChild> transaction = GetLayerTransaction();
+31 -162
View File
@@ -3120,106 +3120,6 @@ nsDocument::ElementFromPoint(float aX, float aY, nsIDOMElement** aReturn)
return NS_OK;
}
Element*
nsIDocument::ElementFromPoint(float aX, float aY)
{
return ElementFromPointHelper(aX, aY, false, true);
}
void
nsIDocument::ElementsFromPoint(float aX, float aY,
nsTArray<RefPtr<Element>>& aElements)
{
ElementsFromPointHelper(aX, aY, nsIDocument::FLUSH_LAYOUT, aElements);
}
Element*
nsDocument::ElementFromPointHelper(float aX, float aY,
bool aIgnoreRootScrollFrame,
bool aFlushLayout)
{
AutoTArray<RefPtr<Element>, 1> elementArray;
ElementsFromPointHelper(aX, aY,
((aIgnoreRootScrollFrame ? nsIDocument::IGNORE_ROOT_SCROLL_FRAME : 0) |
(aFlushLayout ? nsIDocument::FLUSH_LAYOUT : 0) |
nsIDocument::IS_ELEMENT_FROM_POINT),
elementArray);
if (elementArray.IsEmpty()) {
return nullptr;
}
return elementArray[0];
}
void
nsDocument::ElementsFromPointHelper(float aX, float aY,
uint32_t aFlags,
nsTArray<RefPtr<mozilla::dom::Element>>& aElements)
{
// As per the the spec, we return null if either coord is negative
if (!(aFlags & nsIDocument::IGNORE_ROOT_SCROLL_FRAME) && (aX < 0 || aY < 0)) {
return;
}
nscoord x = nsPresContext::CSSPixelsToAppUnits(aX);
nscoord y = nsPresContext::CSSPixelsToAppUnits(aY);
nsPoint pt(x, y);
// Make sure the layout information we get is up-to-date, and
// ensure we get a root frame (for everything but XUL)
if (aFlags & nsIDocument::FLUSH_LAYOUT) {
FlushPendingNotifications(Flush_Layout);
}
nsIPresShell *ps = GetShell();
if (!ps) {
return;
}
nsIFrame *rootFrame = ps->GetRootFrame();
// XUL docs, unlike HTML, have no frame tree until everything's done loading
if (!rootFrame) {
return; // return null to premature XUL callers as a reminder to wait
}
nsTArray<nsIFrame*> outFrames;
// Emulate what GetFrameAtPoint does, since we want all the frames under our
// point.
nsLayoutUtils::GetFramesForArea(rootFrame, nsRect(pt, nsSize(1, 1)), outFrames,
nsLayoutUtils::IGNORE_PAINT_SUPPRESSION | nsLayoutUtils::IGNORE_CROSS_DOC |
((aFlags & nsIDocument::IGNORE_ROOT_SCROLL_FRAME) ? nsLayoutUtils::IGNORE_ROOT_SCROLL_FRAME : 0));
// Dunno when this would ever happen, as we should at least have a root frame under us?
if (outFrames.IsEmpty()) {
return;
}
// Used to filter out repeated elements in sequence.
nsIContent* lastAdded = nullptr;
for (uint32_t i = 0; i < outFrames.Length(); i++) {
nsIContent* node = GetContentInThisDocument(outFrames[i]);
if (!node || !node->IsElement()) {
// If this helper is called via ElementsFromPoint, we need to make sure
// our frame is an element. Otherwise return whatever the top frame is
// even if it isn't the top-painted element.
if (!(aFlags & nsIDocument::IS_ELEMENT_FROM_POINT)) {
continue;
}
node = node->GetParent();
}
if (node && node != lastAdded) {
aElements.AppendElement(node->AsElement());
lastAdded = node;
// If this helper is called via ElementFromPoint, just return the first
// element we find.
if (aFlags & nsIDocument::IS_ELEMENT_FROM_POINT) {
return;
}
}
}
}
nsresult
nsDocument::NodesFromRectHelper(float aX, float aY,
float aTopSize, float aRightSize,
@@ -5923,14 +5823,9 @@ nsIDocument::ImportNode(nsINode& aNode, bool aDeep, ErrorResult& rv) const
case nsIDOMNode::COMMENT_NODE:
case nsIDOMNode::DOCUMENT_TYPE_NODE:
{
nsCOMPtr<nsINode> newNode;
nsCOMArray<nsINode> nodesWithProperties;
rv = nsNodeUtils::Clone(imported, aDeep, mNodeInfoManager,
nodesWithProperties, getter_AddRefs(newNode));
if (rv.Failed()) {
return nullptr;
}
return newNode.forget();
return nsNodeUtils::Clone(imported, aDeep, mNodeInfoManager,
&nodesWithProperties, rv);
}
default:
{
@@ -7091,8 +6986,8 @@ nsIDocument::AdoptNode(nsINode& aAdoptedNode, ErrorResult& rv)
}
nsCOMArray<nsINode> nodesWithProperties;
rv = nsNodeUtils::Adopt(adoptedNode, sameDocument ? nullptr : mNodeInfoManager,
newScope, nodesWithProperties);
nsNodeUtils::Adopt(adoptedNode, sameDocument ? nullptr : mNodeInfoManager,
newScope, nodesWithProperties, rv);
if (rv.Failed()) {
// Disconnect all nodes from their parents, since some have the old document
// as their ownerDocument and some have this as their ownerDocument.
@@ -8387,7 +8282,7 @@ nsDocument::DoUnblockOnload()
}
nsIContent*
nsDocument::GetContentInThisDocument(nsIFrame* aFrame) const
nsIDocument::GetContentInThisDocument(nsIFrame* aFrame) const
{
for (nsIFrame* f = aFrame; f;
f = nsLayoutUtils::GetParentOrPlaceholderForCrossDoc(f)) {
@@ -8598,7 +8493,7 @@ nsDocument::OnPageHide(bool aPersisted,
EnumerateActivityObservers(NotifyActivityChanged, nullptr);
ClearPendingFullscreenRequests(this);
if (GetFullscreenElement()) {
if (FullScreenStackTop()) {
// If this document was fullscreen, we should exit fullscreen in this
// doctree branch. This ensures that if the user navigates while in
// fullscreen mode we don't leave its still visible ancestor documents
@@ -10302,7 +10197,7 @@ nsIDocument::AsyncExitFullscreen(nsIDocument* aDoc)
static bool
CountFullscreenSubDocuments(nsIDocument* aDoc, void* aData)
{
if (aDoc->GetFullscreenElement()) {
if (aDoc->FullScreenStackTop()) {
uint32_t* count = static_cast<uint32_t*>(aData);
(*count)++;
}
@@ -10322,7 +10217,7 @@ nsDocument::IsFullscreenLeaf()
{
// A fullscreen leaf document is fullscreen, and has no fullscreen
// subdocuments.
if (!GetFullscreenElement()) {
if (!FullScreenStackTop()) {
return false;
}
return CountFullscreenSubDocuments(this) == 0;
@@ -10331,11 +10226,11 @@ nsDocument::IsFullscreenLeaf()
static bool
ResetFullScreen(nsIDocument* aDocument, void* aData)
{
if (aDocument->GetFullscreenElement()) {
if (aDocument->FullScreenStackTop()) {
NS_ASSERTION(CountFullscreenSubDocuments(aDocument) <= 1,
"Should have at most 1 fullscreen subdocument.");
static_cast<nsDocument*>(aDocument)->CleanupFullscreenState();
NS_ASSERTION(!aDocument->GetFullscreenElement(),
NS_ASSERTION(!aDocument->FullScreenStackTop(),
"Should reset full-screen");
auto changed = reinterpret_cast<nsCOMArray<nsIDocument>*>(aData);
changed->AppendElement(aDocument);
@@ -10383,7 +10278,7 @@ nsIDocument::ExitFullscreenInDocTree(nsIDocument* aMaybeNotARootDoc)
UnlockPointer();
nsCOMPtr<nsIDocument> root = aMaybeNotARootDoc->GetFullscreenRoot();
if (!root || !root->GetFullscreenElement()) {
if (!root || !root->FullScreenStackTop()) {
// If a document was detached before exiting from fullscreen, it is
// possible that the root had left fullscreen state. In this case,
// we would not get anything from the ResetFullScreen() call. Root's
@@ -10412,7 +10307,7 @@ nsIDocument::ExitFullscreenInDocTree(nsIDocument* aMaybeNotARootDoc)
DispatchFullScreenChange(changed[changed.Length() - i - 1]);
}
NS_ASSERTION(!root->GetFullscreenElement(),
NS_ASSERTION(!root->FullScreenStackTop(),
"Fullscreen root should no longer be a fullscreen doc...");
// Move the top-level window out of fullscreen mode.
@@ -10429,7 +10324,7 @@ GetFullscreenLeaf(nsIDocument* aDoc, void* aData)
nsIDocument** result = static_cast<nsIDocument**>(aData);
*result = aDoc;
return false;
} else if (aDoc->GetFullscreenElement()) {
} else if (aDoc->FullScreenStackTop()) {
aDoc->EnumerateSubDocuments(GetFullscreenLeaf, aData);
}
return true;
@@ -10448,7 +10343,7 @@ GetFullscreenLeaf(nsIDocument* aDoc)
nsIDocument* root = nsContentUtils::GetRootDocument(aDoc);
// Check that the root is actually fullscreen so we don't waste time walking
// around its descendants.
if (!root->GetFullscreenElement()) {
if (!root->FullScreenStackTop()) {
return nullptr;
}
GetFullscreenLeaf(root, &leaf);
@@ -10458,10 +10353,10 @@ GetFullscreenLeaf(nsIDocument* aDoc)
void
nsDocument::RestorePreviousFullScreenState()
{
NS_ASSERTION(!GetFullscreenElement() || !FullscreenRoots::IsEmpty(),
NS_ASSERTION(!FullScreenStackTop() || !FullscreenRoots::IsEmpty(),
"Should have at least 1 fullscreen root when fullscreen!");
if (!GetFullscreenElement() || !GetWindow() || FullscreenRoots::IsEmpty()) {
if (!FullScreenStackTop() || !GetWindow() || FullscreenRoots::IsEmpty()) {
return;
}
@@ -10636,7 +10531,7 @@ nsDocument::FullScreenStackPush(Element* aElement)
}
EventStateManager::SetFullScreenState(aElement, true);
mFullScreenStack.AppendElement(do_GetWeakReference(aElement));
NS_ASSERTION(GetFullscreenElement() == aElement, "Should match");
NS_ASSERTION(FullScreenStackTop() == aElement, "Should match");
UpdateViewportScrollbarOverrideForFullscreen(this);
return true;
}
@@ -10684,7 +10579,7 @@ nsDocument::FullScreenStackTop()
uint32_t last = mFullScreenStack.Length() - 1;
nsCOMPtr<Element> element(do_QueryReferent(mFullScreenStack[last]));
NS_ASSERTION(element, "Should have full-screen element!");
NS_ASSERTION(element->IsInUncomposedDoc(), "Full-screen element should be in doc");
NS_ASSERTION(element->IsInComposedDoc(), "Full-screen element should be in doc");
NS_ASSERTION(element->OwnerDoc() == this, "Full-screen element should be in this doc");
return element;
}
@@ -10762,7 +10657,7 @@ nsresult nsDocument::RemoteFrameFullscreenReverted()
}
/* static */ bool
nsDocument::IsUnprefixedFullscreenEnabled(JSContext* aCx, JSObject* aObject)
nsIDocument::IsUnprefixedFullscreenEnabled(JSContext* aCx, JSObject* aObject)
{
MOZ_ASSERT(NS_IsMainThread());
return nsContentUtils::IsCallerChrome() ||
@@ -10810,10 +10705,10 @@ nsDocument::FullscreenElementReadyCheck(Element* aElement,
{
NS_ASSERTION(aElement,
"Must pass non-null element to nsDocument::RequestFullScreen");
if (!aElement || aElement == GetFullscreenElement()) {
if (!aElement || aElement == FullScreenStackTop()) {
return false;
}
if (!aElement->IsInUncomposedDoc()) {
if (!aElement->IsInComposedDoc()) {
DispatchFullscreenError("FullscreenDeniedNotInDocument");
return false;
}
@@ -10837,8 +10732,11 @@ nsDocument::FullscreenElementReadyCheck(Element* aElement,
DispatchFullscreenError("FullscreenDeniedSubDocFullScreen");
return false;
}
if (GetFullscreenElement() &&
!nsContentUtils::ContentIsDescendantOf(aElement, GetFullscreenElement())) {
//XXXsmaug Note, we don't follow the latest fullscreen spec here.
// This whole check could be probably removed.
if (FullScreenStackTop() &&
!nsContentUtils::ContentIsHostIncludingDescendantOf(aElement,
FullScreenStackTop())) {
// If this document is full-screen, only grant full-screen requests from
// a descendant of the current full-screen element.
DispatchFullscreenError("FullscreenDeniedNotDescendant");
@@ -11198,16 +11096,6 @@ nsDocument::GetMozFullScreenElement(nsIDOMElement **aFullScreenElement)
return NS_OK;
}
Element*
nsDocument::GetFullscreenElement()
{
Element* element = FullScreenStackTop();
NS_ASSERTION(!element ||
element->State().HasState(NS_EVENT_STATE_FULL_SCREEN),
"Fullscreen element should have fullscreen styles applied");
return element;
}
NS_IMETHODIMP
nsDocument::GetMozFullScreen(bool *aFullScreen)
{
@@ -11326,7 +11214,7 @@ GetPointerLockError(Element* aElement, Element* aCurrentLock,
return "PointerLockDeniedInUse";
}
if (!aElement->IsInUncomposedDoc()) {
if (!aElement->IsInComposedDoc()) {
return "PointerLockDeniedNotInDocument";
}
@@ -11377,11 +11265,11 @@ ChangePointerLockedElement(Element* aElement, nsIDocument* aDocument,
MOZ_ASSERT(aDocument);
MOZ_ASSERT(aElement != aPointerLockedElement);
if (aPointerLockedElement) {
MOZ_ASSERT(aPointerLockedElement->GetUncomposedDoc() == aDocument);
MOZ_ASSERT(aPointerLockedElement->GetComposedDoc() == aDocument);
aPointerLockedElement->ClearPointerLock();
}
if (aElement) {
MOZ_ASSERT(aElement->GetUncomposedDoc() == aDocument);
MOZ_ASSERT(aElement->GetComposedDoc() == aDocument);
aElement->SetPointerLock();
EventStateManager::sPointerLockedElement = do_GetWeakReference(aElement);
EventStateManager::sPointerLockedDoc = do_GetWeakReference(aDocument);
@@ -11405,9 +11293,9 @@ PointerLockRequest::Run()
nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocument);
nsDocument* d = static_cast<nsDocument*>(doc.get());
const char* error = nullptr;
if (!e || !d || !e->GetUncomposedDoc()) {
if (!e || !d || !e->GetComposedDoc()) {
error = "PointerLockDeniedNotInDocument";
} else if (e->GetUncomposedDoc() != d) {
} else if (e->GetComposedDoc() != d) {
error = "PointerLockDeniedMovedDocument";
}
if (!error) {
@@ -11573,25 +11461,6 @@ nsDocument::GetMozPointerLockElement(nsIDOMElement** aPointerLockedElement)
return NS_OK;
}
Element*
nsIDocument::GetPointerLockElement()
{
nsCOMPtr<Element> pointerLockedElement =
do_QueryReferent(EventStateManager::sPointerLockedElement);
if (!pointerLockedElement) {
return nullptr;
}
// Make sure pointer locked element is in the same document.
nsCOMPtr<nsIDocument> pointerLockedDoc =
do_QueryReferent(EventStateManager::sPointerLockedDoc);
if (pointerLockedDoc != this) {
return nullptr;
}
return pointerLockedElement;
}
nsresult
nsDocument::Observe(nsISupports *aSubject,
const char *aTopic,
+1 -22
View File
@@ -692,14 +692,6 @@ public:
nsIAtom* aAttrName,
const nsAString& aAttrValue) const override;
virtual Element* ElementFromPointHelper(float aX, float aY,
bool aIgnoreRootScrollFrame,
bool aFlushLayout) override;
virtual void ElementsFromPointHelper(float aX, float aY,
uint32_t aFlags,
nsTArray<RefPtr<mozilla::dom::Element>>& aElements) override;
virtual nsresult NodesFromRectHelper(float aX, float aY,
float aTopSize, float aRightSize,
float aBottomSize, float aLeftSize,
@@ -896,8 +888,6 @@ public:
//
already_AddRefed<nsSimpleContentList> BlockedTrackingNodes() const;
static bool IsUnprefixedFullscreenEnabled(JSContext* aCx, JSObject* aObject);
// Do the "fullscreen element ready check" from the fullscreen spec.
// It returns true if the given element is allowed to go into fullscreen.
bool FullscreenElementReadyCheck(Element* aElement, bool aWasCallerChrome);
@@ -921,11 +911,10 @@ public:
void FullScreenStackPop();
// Returns the top element from the full-screen stack.
Element* FullScreenStackTop();
Element* FullScreenStackTop() override;
// DOM-exposed fullscreen API
bool FullscreenEnabled() override;
Element* GetFullscreenElement() override;
void RequestPointerLock(Element* aElement) override;
bool SetPointerLock(Element* aElement, int aCursorStyle);
@@ -1315,16 +1304,6 @@ private:
nsresult InitCSP(nsIChannel* aChannel);
/**
* Find the (non-anonymous) content in this document for aFrame. It will
* be aFrame's content node if that content is in this document and not
* anonymous. Otherwise, when aFrame is in a subdocument, we use the frame
* element containing the subdocument containing aFrame, and/or find the
* nearest non-anonymous ancestor in this document.
* Returns null if there is no such element.
*/
nsIContent* GetContentInThisDocument(nsIFrame* aFrame) const;
// Just like EnableStyleSheetsForSet, but doesn't check whether
// aSheetSet is null and allows the caller to control whether to set
// aSheetSet as the preferred set in the CSSLoader.
+639 -94
View File
@@ -8,10 +8,12 @@
#include "nsFocusManager.h"
#include "AccessibleCaretEventHub.h"
#include "ChildIterator.h"
#include "nsAttrValueInlines.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsGkAtoms.h"
#include "nsContentUtils.h"
#include "nsIDocument.h"
#include "nsDocument.h"
#include "nsIEditor.h"
#include "nsPIDOMWindow.h"
#include "nsIDOMChromeWindow.h"
@@ -46,7 +48,9 @@
#include "mozilla/ContentEvents.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/ShadowRoot.h"
#include "mozilla/dom/HTMLInputElement.h"
#include "mozilla/dom/HTMLSlotElement.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/EventStateManager.h"
#include "mozilla/EventStates.h"
@@ -2972,6 +2976,378 @@ nsFocusManager::DetermineElementToMoveFocus(nsPIDOMWindowOuter* aWindow,
return NS_OK;
}
static bool
IsHostOrSlot(nsIContent* aContent)
{
return aContent && (aContent->GetShadowRoot() ||
aContent->IsHTMLElement(nsGkAtoms::slot));
}
// Helper class to iterate contents in scope by traversing flattened tree
// in tree order
class MOZ_STACK_CLASS ScopedContentTraversal
{
public:
ScopedContentTraversal(nsIContent* aStartContent, nsIContent* aOwner)
: mCurrent(aStartContent)
, mOwner(aOwner)
{
MOZ_ASSERT(aStartContent);
}
void Next();
void Prev();
void Reset()
{
SetCurrent(mOwner);
}
nsIContent* GetCurrent()
{
return mCurrent;
}
private:
void SetCurrent(nsIContent* aContent)
{
mCurrent = aContent;
}
nsIContent* mCurrent;
nsIContent* mOwner;
};
void
ScopedContentTraversal::Next()
{
MOZ_ASSERT(mCurrent);
// Get mCurrent's first child if it's in the same scope.
if (!IsHostOrSlot(mCurrent) || mCurrent == mOwner) {
StyleChildrenIterator iter(mCurrent);
nsIContent* child = iter.GetNextChild();
if (child) {
SetCurrent(child);
return;
}
}
// If mOwner has no children, END traversal
if (mCurrent == mOwner) {
SetCurrent(nullptr);
return;
}
nsIContent* current = mCurrent;
while (1) {
// Create parent's iterator and move to current
nsIContent* parent = current->GetFlattenedTreeParent();
StyleChildrenIterator parentIter(parent);
parentIter.Seek(current);
// Get next sibling of current
if (nsIContent* next = parentIter.GetNextChild()) {
SetCurrent(next);
return;
}
// If no next sibling and parent is mOwner, END traversal
if (parent == mOwner) {
SetCurrent(nullptr);
return;
}
current = parent;
}
}
void
ScopedContentTraversal::Prev()
{
MOZ_ASSERT(mCurrent);
nsIContent* parent;
nsIContent* last;
if (mCurrent == mOwner) {
// Get last child of mOwner
StyleChildrenIterator ownerIter(mOwner, false /* aStartAtBeginning */);
last = ownerIter.GetPreviousChild();
parent = last;
} else {
// Create parent's iterator and move to mCurrent
parent = mCurrent->GetFlattenedTreeParent();
StyleChildrenIterator parentIter(parent);
parentIter.Seek(mCurrent);
// Get previous sibling
last = parentIter.GetPreviousChild();
}
while (last) {
parent = last;
if (parent->GetShadowRoot() ||
parent->IsHTMLElement(nsGkAtoms::slot)) {
// Skip contents in other scopes
break;
}
// Find last child
StyleChildrenIterator iter(parent, false /* aStartAtBeginning */);
last = iter.GetPreviousChild();
}
// If parent is mOwner and no previous sibling remains, END traversal
SetCurrent(parent == mOwner ? nullptr : parent);
}
nsIContent*
nsFocusManager::FindOwner(nsIContent* aContent)
{
nsIContent* currentContent = aContent;
while (currentContent) {
nsIContent* parent = currentContent->GetFlattenedTreeParent();
// Shadow host / Slot
if (IsHostOrSlot(parent)) {
return parent;
}
currentContent = parent;
}
return nullptr;
}
/**
* Host and Slot elements need to be handled as if they had tabindex 0 even
* when they don't have the attribute. This is a helper method to get the
* right value for focus navigation. If aIsFocusable is passed, it is set to
* true if the element itself is focusable.
*/
static int32_t
HostOrSlotTabIndexValue(nsIContent* aContent,
bool* aIsFocusable = nullptr)
{
MOZ_ASSERT(IsHostOrSlot(aContent));
if (aIsFocusable) {
*aIsFocusable = false;
nsIFrame* frame = aContent->GetPrimaryFrame();
if (frame) {
int32_t tabIndex;
frame->IsFocusable(&tabIndex, 0);
*aIsFocusable = tabIndex >= 0;
}
}
const nsAttrValue* attrVal =
aContent->AsElement()->GetParsedAttr(nsGkAtoms::tabindex);
if (!attrVal) {
return 0;
}
if (attrVal->Type() == nsAttrValue::eInteger) {
return attrVal->GetIntegerValue();
}
return -1;
}
nsIContent*
nsFocusManager::GetNextTabbableContentInScope(nsIContent* aOwner,
nsIContent* aStartContent,
nsIContent* aOriginalStartContent,
bool aForward,
int32_t aCurrentTabIndex,
bool aIgnoreTabIndex,
bool aForDocumentNavigation,
bool aSkipOwner)
{
MOZ_ASSERT(IsHostOrSlot(aOwner), "Scope owner should be host or slot");
if (!aSkipOwner && (aForward && aOwner == aStartContent)) {
int32_t tabIndex = -1;
nsIFrame* frame = aOwner->GetPrimaryFrame();
if (frame && frame->IsFocusable(&tabIndex, false) && tabIndex >= 0) {
return aOwner;
}
}
//
// Iterate contents in scope
//
ScopedContentTraversal contentTraversal(aStartContent, aOwner);
nsCOMPtr<nsIContent> iterContent;
nsIContent* firstNonChromeOnly = aStartContent->IsInNativeAnonymousSubtree() ?
aStartContent->FindFirstNonChromeOnlyAccessContent() : nullptr;
while (1) {
// Iterate tab index to find corresponding contents in scope
while (1) {
// Iterate remaining contents in scope to find next content to focus
// Get next content
aForward ? contentTraversal.Next() : contentTraversal.Prev();
iterContent = contentTraversal.GetCurrent();
if (firstNonChromeOnly && firstNonChromeOnly == iterContent) {
// We just broke out from the native anonymous content, so move
// to the previous/next node of the native anonymous owner.
if (aForward) {
contentTraversal.Next();
} else {
contentTraversal.Prev();
}
iterContent = contentTraversal.GetCurrent();
}
if (!iterContent) {
// Reach the end
break;
}
// Get the tab index of the next element. For NAC we rely on frames.
//XXXsmaug we should probably use frames also for Shadow DOM and special
// case only display:contents elements.
int32_t tabIndex = 0;
if (iterContent->IsInNativeAnonymousSubtree() &&
iterContent->GetPrimaryFrame()) {
iterContent->GetPrimaryFrame()->IsFocusable(&tabIndex);
} else if (IsHostOrSlot(iterContent)) {
tabIndex = HostOrSlotTabIndexValue(iterContent);
} else {
iterContent->IsFocusable(&tabIndex);
}
if (tabIndex < 0 || !(aIgnoreTabIndex || tabIndex == aCurrentTabIndex)) {
continue;
}
if (!IsHostOrSlot(iterContent)) {
nsCOMPtr<nsIContent> elementInFrame;
bool checkSubDocument = true;
if (aForDocumentNavigation &&
TryDocumentNavigation(iterContent, &checkSubDocument,
getter_AddRefs(elementInFrame))) {
return elementInFrame;
}
if (!checkSubDocument) {
continue;
}
if (TryToMoveFocusToSubDocument(iterContent, aOriginalStartContent,
aForward, aForDocumentNavigation,
getter_AddRefs(elementInFrame))) {
return elementInFrame;
}
// Found content to focus
return iterContent;
}
// Search in scope owned by iterContent
nsIContent* contentToFocus =
GetNextTabbableContentInScope(iterContent, iterContent,
aOriginalStartContent, aForward,
aForward ? 1 : 0, aIgnoreTabIndex,
aForDocumentNavigation,
false /* aSkipOwner */);
if (contentToFocus) {
return contentToFocus;
}
};
// If already at lowest priority tab (0), end search completely.
// A bit counterintuitive but true, tabindex order goes 1, 2, ... 32767, 0
if (aCurrentTabIndex == (aForward ? 0 : 1)) {
break;
}
// Continue looking for next highest priority tabindex
aCurrentTabIndex = GetNextTabIndex(aOwner, aCurrentTabIndex, aForward);
contentTraversal.Reset();
}
// Return scope owner at last for backward navigation if its tabindex
// is non-negative
if (!aSkipOwner && !aForward) {
int32_t tabIndex = -1;
nsIFrame* frame = aOwner->GetPrimaryFrame();
if (frame && frame->IsFocusable(&tabIndex, false) && tabIndex >= 0) {
return aOwner;
}
}
return nullptr;
}
nsIContent*
nsFocusManager::GetNextTabbableContentInAncestorScopes(
nsIContent* aStartOwner,
nsIContent** aStartContent,
nsIContent* aOriginalStartContent,
bool aForward,
int32_t* aCurrentTabIndex,
bool aIgnoreTabIndex,
bool aForDocumentNavigation)
{
MOZ_ASSERT(aStartOwner == FindOwner(*aStartContent),
"aStartOwner should be the scope owner of aStartContent");
MOZ_ASSERT(IsHostOrSlot(aStartOwner), "scope owner should be host or slot");
nsIContent* owner = aStartOwner;
nsIContent* startContent = *aStartContent;
while (IsHostOrSlot(owner)) {
int32_t tabIndex = 0;
if (IsHostOrSlot(startContent)) {
tabIndex = HostOrSlotTabIndexValue(startContent);
} else {
startContent->IsFocusable(&tabIndex);
}
nsIContent* contentToFocus =
GetNextTabbableContentInScope(owner, startContent, aOriginalStartContent,
aForward, tabIndex, aIgnoreTabIndex,
aForDocumentNavigation,
false /* aSkipOwner */);
if (contentToFocus) {
return contentToFocus;
}
startContent = owner;
owner = FindOwner(startContent);
}
// If not found in shadow DOM, search from the top level shadow host in light DOM
*aStartContent = startContent;
*aCurrentTabIndex = HostOrSlotTabIndexValue(startContent);
return nullptr;
}
static nsIContent*
GetTopLevelScopeOwner(nsIContent* aContent)
{
nsIContent* topLevelScopeOwner = nullptr;
while (aContent) {
if (HTMLSlotElement* slot = aContent->GetAssignedSlot()) {
aContent = slot;
} else if (ShadowRoot* shadowRoot = aContent->GetContainingShadow()) {
aContent = shadowRoot->Host();
topLevelScopeOwner = aContent;
} else {
// TODO: replaced with FromNode.
if (HTMLSlotElement::FromContentOrNull(aContent)) {
topLevelScopeOwner = aContent;
}
aContent = aContent->GetParent();
}
}
return topLevelScopeOwner;
}
nsresult
nsFocusManager::GetNextTabbableContent(nsIPresShell* aPresShell,
nsIContent* aRootContent,
@@ -2989,70 +3365,163 @@ nsFocusManager::GetNextTabbableContent(nsIPresShell* aPresShell,
if (!startContent)
return NS_OK;
nsIContent* currentTopLevelScopeOwner = GetTopLevelScopeOwner(aStartContent);
LOGCONTENTNAVIGATION("GetNextTabbable: %s", aStartContent);
LOGFOCUSNAVIGATION((" tabindex: %d", aCurrentTabIndex));
if (nsDocument::IsWebComponentsEnabled(aRootContent)) {
// If aStartContent is a shadow host or slot in forward navigation,
// search in scope owned by aStartContent.
if (aForward && IsHostOrSlot(aStartContent)) {
nsIContent* contentToFocus =
GetNextTabbableContentInScope(aStartContent, aStartContent,
aOriginalStartContent, aForward,
aForward ? 1 : 0, aIgnoreTabIndex,
aForDocumentNavigation,
true /* aSkipOwner */);
if (contentToFocus) {
NS_ADDREF(*aResultContent = contentToFocus);
return NS_OK;
}
}
// If aStartContent is in a scope owned by Shadow DOM search from scope
// including aStartContent.
if (nsIContent* owner = FindOwner(aStartContent)) {
nsIContent* contentToFocus =
GetNextTabbableContentInAncestorScopes(owner,
&aStartContent,
aOriginalStartContent,
aForward,
&aCurrentTabIndex,
aIgnoreTabIndex,
aForDocumentNavigation);
if (contentToFocus) {
NS_ADDREF(*aResultContent = contentToFocus);
return NS_OK;
}
}
// If we reach here, it means no next tabbable content in shadow DOM.
// We need to continue searching in light DOM, starting at the top level
// shadow host in light DOM (updated aStartContent) and its tabindex
// (updated aCurrentTabIndex).
MOZ_ASSERT(!FindOwner(aStartContent),
"aStartContent should not be owned by Shadow DOM at this point");
}
nsPresContext* presContext = aPresShell->GetPresContext();
bool getNextFrame = true;
nsCOMPtr<nsIContent> iterStartContent = aStartContent;
// Iterate tab index to find corresponding contents
while (1) {
nsIFrame* startFrame = iterStartContent->GetPrimaryFrame();
nsIFrame* frame = iterStartContent->GetPrimaryFrame();
// if there is no frame, look for another content node that has a frame
if (!startFrame) {
while (!frame) {
// if the root content doesn't have a frame, just return
if (iterStartContent == aRootContent)
if (iterStartContent == aRootContent) {
return NS_OK;
}
// look for the next or previous content node in tree order
iterStartContent = aForward ? iterStartContent->GetNextNode() : iterStartContent->GetPreviousContent();
iterStartContent = aForward ? iterStartContent->GetNextNode()
: iterStartContent->GetPreviousContent();
if (!iterStartContent) {
break;
}
frame = iterStartContent->GetPrimaryFrame();
// Host without frame, enter its scope.
if (nsDocument::IsWebComponentsEnabled(aRootContent) &&
(!frame && iterStartContent->GetShadowRoot())) {
int32_t tabIndex = HostOrSlotTabIndexValue(iterStartContent);
if (tabIndex >= 0 &&
(aIgnoreTabIndex || aCurrentTabIndex == tabIndex)) {
nsIContent* contentToFocus = GetNextTabbableContentInScope(
iterStartContent, iterStartContent, aOriginalStartContent,
aForward, aForward ? 1 : 0, aIgnoreTabIndex,
aForDocumentNavigation, true /* aSkipOwner */);
if (contentToFocus) {
NS_ADDREF(*aResultContent = contentToFocus);
return NS_OK;
}
}
}
// we've already skipped over the initial focused content, so we
// don't want to traverse frames.
getNextFrame = false;
if (iterStartContent)
continue;
// otherwise, as a last attempt, just look at the root content
iterStartContent = aRootContent;
continue;
}
// For tab navigation, pass false for aSkipPopupChecks so that we don't
// iterate into or out of a popup. For document naviation pass true to
// ignore these boundaries.
nsCOMPtr<nsIFrameEnumerator> frameTraversal;
nsresult rv = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),
presContext, startFrame,
ePreOrder,
false, // aVisual
false, // aLockInScrollView
true, // aFollowOOFs
aForDocumentNavigation // aSkipPopupChecks
);
NS_ENSURE_SUCCESS(rv, rv);
if (frame) {
// For tab navigation, pass false for aSkipPopupChecks so that we don't
// iterate into or out of a popup. For document navigation, pass true to
// ignore these boundaries.
nsresult rv = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),
presContext,
frame,
ePreOrder,
false, // aVisual
false, // aLockInScrollView
true, // aFollowOOFs
aForDocumentNavigation // aSkipPopupChecks
);
NS_ENSURE_SUCCESS(rv, rv);
if (iterStartContent == aRootContent) {
if (!aForward) {
frameTraversal->Last();
} else if (aRootContent->IsFocusable()) {
frameTraversal->Next();
if (iterStartContent == aRootContent) {
if (!aForward) {
frameTraversal->Last();
} else if (aRootContent->IsFocusable()) {
frameTraversal->Next();
}
frame = static_cast<nsIFrame*>(frameTraversal->CurrentItem());
} else if (getNextFrame &&
(!iterStartContent ||
!iterStartContent->IsHTMLElement(nsGkAtoms::area))) {
// Need to do special check in case we're in an imagemap which has multiple
// content nodes per frame, so don't skip over the starting frame.
if (aForward) {
frameTraversal->Next();
} else {
frameTraversal->Prev();
}
frame = static_cast<nsIFrame*>(frameTraversal->CurrentItem());
}
}
else if (getNextFrame &&
(!iterStartContent ||
!iterStartContent->IsHTMLElement(nsGkAtoms::area))) {
// Need to do special check in case we're in an imagemap which has multiple
// content nodes per frame, so don't skip over the starting frame.
if (aForward)
frameTraversal->Next();
else
frameTraversal->Prev();
}
// Walk frames to find something tabbable matching mCurrentTabIndex
nsIFrame* frame = static_cast<nsIFrame*>(frameTraversal->CurrentItem());
while (frame) {
nsIContent* currentContent = frame->GetContent();
if (nsDocument::IsWebComponentsEnabled(currentContent)) {
// Try to find the topmost scope owner, since we want to skip the node
// that is not owned by document in frame traversal.
nsIContent* oldTopLevelScopeOwner = currentTopLevelScopeOwner;
if (!aForward || oldTopLevelScopeOwner != currentContent) {
currentTopLevelScopeOwner = GetTopLevelScopeOwner(currentContent);
} else {
currentTopLevelScopeOwner = currentContent;
}
if (currentTopLevelScopeOwner) {
if (currentTopLevelScopeOwner == oldTopLevelScopeOwner) {
// We're within non-document scope, continue.
do {
if (aForward) {
frameTraversal->Next();
} else {
frameTraversal->Prev();
}
frame = static_cast<nsIFrame*>(frameTraversal->CurrentItem());
// For the usage of GetPrevContinuation, see the comment
// at the end of while (frame) loop.
} while (frame && frame->GetPrevContinuation());
continue;
}
currentContent = currentTopLevelScopeOwner;
}
}
// For document navigation, check if this element is an open panel. Since
// panels aren't focusable (tabIndex would be -1), we'll just assume that
@@ -3086,7 +3555,7 @@ nsFocusManager::GetNextTabbableContent(nsIPresShell* aPresShell,
// and root content, so that we only find content within the panel.
// Note also that we pass false for aForDocumentNavigation since we
// want to locate the first content, not the first document.
rv = GetNextTabbableContent(aPresShell, currentContent,
nsresult rv = GetNextTabbableContent(aPresShell, currentContent,
nullptr, currentContent,
true, 1, false, false,
aResultContent);
@@ -3097,6 +3566,34 @@ nsFocusManager::GetNextTabbableContent(nsIPresShell* aPresShell,
}
}
// As of now, 2018/04/12, sequential focus navigation is still
// in the obsolete Shadow DOM specification.
// http://w3c.github.io/webcomponents/spec/shadow/#sequential-focus-navigation
// "if ELEMENT is focusable, a shadow host, or a slot element,
// append ELEMENT to NAVIGATION-ORDER."
// and later in "For each element ELEMENT in NAVIGATION-ORDER: "
// hosts and slots are handled before other elements.
if (nsDocument::IsWebComponentsEnabled(currentContent) &&
IsHostOrSlot(currentContent)) {
bool focusableHostSlot;
int32_t tabIndex =
HostOrSlotTabIndexValue(currentContent, &focusableHostSlot);
// Host or slot itself isn't focusable or going backwards, enter its scope.
if ((!aForward || !focusableHostSlot) && tabIndex >= 0 &&
(aIgnoreTabIndex || aCurrentTabIndex == tabIndex)) {
nsIContent* contentToFocus =
GetNextTabbableContentInScope(currentContent, currentContent,
aOriginalStartContent, aForward,
aForward ? 1 : 0, aIgnoreTabIndex,
aForDocumentNavigation,
true /* aSkipOwner */);
if (contentToFocus) {
NS_ADDREF(*aResultContent = contentToFocus);
return NS_OK;
}
}
}
// TabIndex not set defaults to 0 for form elements, anchors and other
// elements that are normally focusable. Tabindex defaults to -1
// for elements that are not normally focusable.
@@ -3145,54 +3642,22 @@ nsFocusManager::GetNextTabbableContent(nsIPresShell* aPresShell,
// Next, for document navigation, check if this a non-remote child document.
bool checkSubDocument = true;
if (aForDocumentNavigation) {
nsIContent* docRoot = GetRootForChildDocument(currentContent);
if (docRoot) {
// If GetRootForChildDocument returned something then call
// FocusFirst to find the root or first element to focus within
// the child document. If this is a frameset though, skip this and
// fall through to the checkSubDocument block below to iterate into
// the frameset's frames and locate the first focusable frame.
if (!docRoot->IsHTMLElement(nsGkAtoms::frameset)) {
return FocusFirst(docRoot, aResultContent);
}
} else {
// Set checkSubDocument to false, as this was neither a frame
// type element or a child document that was focusable.
checkSubDocument = false;
}
if (aForDocumentNavigation &&
TryDocumentNavigation(currentContent, &checkSubDocument,
aResultContent)) {
return NS_OK;
}
if (checkSubDocument) {
// found a node with a matching tab index. Check if it is a child
// frame. If so, navigate into the child frame instead.
nsIDocument* doc = currentContent->GetComposedDoc();
NS_ASSERTION(doc, "content not in document");
nsIDocument* subdoc = doc->GetSubDocumentFor(currentContent);
if (subdoc && !subdoc->EventHandlingSuppressed()) {
if (aForward) {
// when tabbing forward into a frame, return the root
// frame so that the canvas becomes focused.
nsCOMPtr<nsPIDOMWindowOuter> subframe = subdoc->GetWindow();
if (subframe) {
*aResultContent = GetRootForFocus(subframe, subdoc, false, true);
if (*aResultContent) {
NS_ADDREF(*aResultContent);
return NS_OK;
}
}
}
Element* rootElement = subdoc->GetRootElement();
nsIPresShell* subShell = subdoc->GetShell();
if (rootElement && subShell) {
rv = GetNextTabbableContent(subShell, rootElement,
aOriginalStartContent, rootElement,
aForward, (aForward ? 1 : 0),
false, aForDocumentNavigation, aResultContent);
NS_ENSURE_SUCCESS(rv, rv);
if (*aResultContent)
return NS_OK;
}
if (TryToMoveFocusToSubDocument(currentContent,
aOriginalStartContent,
aForward,
aForDocumentNavigation,
aResultContent)) {
MOZ_ASSERT(*aResultContent);
return NS_OK;
}
// otherwise, use this as the next content node to tab to, unless
// this was the element we started on. This would happen for
@@ -3263,6 +3728,77 @@ nsFocusManager::GetNextTabbableContent(nsIPresShell* aPresShell,
return NS_OK;
}
bool
nsFocusManager::TryDocumentNavigation(nsIContent* aCurrentContent,
bool* aCheckSubDocument,
nsIContent** aResultContent)
{
*aCheckSubDocument = true;
nsIContent* docRoot = GetRootForChildDocument(aCurrentContent);
if (docRoot) {
// If GetRootForChildDocument returned something then call
// FocusFirst to find the root or first element to focus within
// the child document. If this is a frameset though, skip this and
// fall through to normal tab navigation to iterate into
// the frameset's frames and locate the first focusable frame.
if (!docRoot->IsHTMLElement(nsGkAtoms::frameset)) {
*aCheckSubDocument = false;
Unused << FocusFirst(docRoot, aResultContent);
return *aResultContent != nullptr;
}
} else {
// Set aCheckSubDocument to false, as this was neither a frame
// type element or a child document that was focusable.
*aCheckSubDocument = false;
}
return false;
}
bool
nsFocusManager::TryToMoveFocusToSubDocument(nsIContent* aCurrentContent,
nsIContent* aOriginalStartContent,
bool aForward,
bool aForDocumentNavigation,
nsIContent** aResultContent)
{
nsIDocument* doc = aCurrentContent->GetComposedDoc();
NS_ASSERTION(doc, "content not in document");
nsIDocument* subdoc = doc->GetSubDocumentFor(aCurrentContent);
if (subdoc && !subdoc->EventHandlingSuppressed()) {
if (aForward) {
// when tabbing forward into a frame, return the root
// frame so that the canvas becomes focused.
nsCOMPtr<nsPIDOMWindowOuter> subframe = subdoc->GetWindow();
if (subframe) {
*aResultContent = GetRootForFocus(subframe, subdoc, false, true);
if (*aResultContent) {
NS_ADDREF(*aResultContent);
return true;
}
}
}
Element* rootElement = subdoc->GetRootElement();
nsIPresShell* subShell = subdoc->GetShell();
if (rootElement && subShell) {
nsresult rv = GetNextTabbableContent(subShell,
rootElement,
aOriginalStartContent,
rootElement,
aForward,
(aForward ? 1 : 0),
false,
aForDocumentNavigation,
aResultContent);
NS_ENSURE_SUCCESS(rv, false);
if (*aResultContent) {
return true;
}
}
}
return false;
}
nsIContent*
nsFocusManager::GetNextTabbableMapArea(bool aForward,
int32_t aCurrentTabIndex,
@@ -3309,15 +3845,20 @@ nsFocusManager::GetNextTabIndex(nsIContent* aParent,
bool aForward)
{
int32_t tabIndex, childTabIndex;
StyleChildrenIterator iter(aParent);
if (aForward) {
tabIndex = 0;
for (nsIContent* child = aParent->GetFirstChild();
for (nsIContent* child = iter.GetNextChild();
child;
child = child->GetNextSibling()) {
childTabIndex = GetNextTabIndex(child, aCurrentTabIndex, aForward);
if (childTabIndex > aCurrentTabIndex && childTabIndex != tabIndex) {
tabIndex = (tabIndex == 0 || childTabIndex < tabIndex) ? childTabIndex : tabIndex;
child = iter.GetNextChild()) {
// Skip child's descendants if child is a shadow host, as they are
// in the focus navigation scope owned by child's shadow root
if (!(nsDocument::IsWebComponentsEnabled(aParent) && IsHostOrSlot(child))) {
childTabIndex = GetNextTabIndex(child, aCurrentTabIndex, aForward);
if (childTabIndex > aCurrentTabIndex && childTabIndex != tabIndex) {
tabIndex = (tabIndex == 0 || childTabIndex < tabIndex) ? childTabIndex : tabIndex;
}
}
nsAutoString tabIndexStr;
@@ -3331,13 +3872,17 @@ nsFocusManager::GetNextTabIndex(nsIContent* aParent,
}
else { /* !aForward */
tabIndex = 1;
for (nsIContent* child = aParent->GetFirstChild();
for (nsIContent* child = iter.GetNextChild();
child;
child = child->GetNextSibling()) {
childTabIndex = GetNextTabIndex(child, aCurrentTabIndex, aForward);
if ((aCurrentTabIndex == 0 && childTabIndex > tabIndex) ||
(childTabIndex < aCurrentTabIndex && childTabIndex > tabIndex)) {
tabIndex = childTabIndex;
child = iter.GetNextChild()) {
// Skip child's descendants if child is a shadow host, as they are
// in the focus navigation scope owned by child's shadow root
if (!(nsDocument::IsWebComponentsEnabled(aParent) && IsHostOrSlot(child))) {
childTabIndex = GetNextTabIndex(child, aCurrentTabIndex, aForward);
if ((aCurrentTabIndex == 0 && childTabIndex > tabIndex) ||
(childTabIndex < aCurrentTabIndex && childTabIndex > tabIndex)) {
tabIndex = childTabIndex;
}
}
nsAutoString tabIndexStr;
+95
View File
@@ -384,6 +384,91 @@ protected:
int32_t aType, bool aNoParentTraversal,
nsIContent** aNextContent);
/**
* Returns scope owner of aContent.
* A scope owner is either a document root, shadow host, or slot.
*/
nsIContent* FindOwner(nsIContent* aContent);
/**
* Retrieve the next tabbable element in scope owned by aOwner, using
* focusability and tabindex to determine the tab order.
*
* aOwner is the owner of scope to search in.
*
* aStartContent is the starting point for this call of this method.
*
* aOriginalStartContent is the initial starting point for sequential
* navigation.
*
* aForward should be true for forward navigation or false for backward
* navigation.
*
* aCurrentTabIndex is the current tabindex.
*
* aIgnoreTabIndex to ignore the current tabindex and find the element
* irrespective or the tab index.
*
* aForDocumentNavigation informs whether we're navigating only through
* documents.
*
* aSkipOwner to skip owner while searching. The flag is set when caller is
* |GetNextTabbableContent| in order to let caller handle owner.
*
* NOTE:
* Consider the method searches downwards in flattened subtree
* rooted at aOwner.
*/
nsIContent* GetNextTabbableContentInScope(nsIContent* aOwner,
nsIContent* aStartContent,
nsIContent* aOriginalStartContent,
bool aForward,
int32_t aCurrentTabIndex,
bool aIgnoreTabIndex,
bool aForDocumentNavigation,
bool aSkipOwner);
/**
* Retrieve the next tabbable element in scope including aStartContent
* and the scope's ancestor scopes, using focusability and tabindex to
* determine the tab order.
*
* aStartOwner is the scope owner of the aStartContent.
*
* aStartContent an in/out paremeter. It as input is the starting point
* for this call of this method; as output it is the shadow host in
* light DOM if the next tabbable element is not found in shadow DOM,
* in order to continue searching in light DOM.
*
* aOriginalStartContent is the initial starting point for sequential
* navigation.
*
* aForward should be true for forward navigation or false for backward
* navigation.
*
* aCurrentTabIndex returns tab index of shadow host in light DOM if the
* next tabbable element is not found in shadow DOM, in order to continue
* searching in light DOM.
*
* aIgnoreTabIndex to ignore the current tabindex and find the element
* irrespective or the tab index.
*
* aForDocumentNavigation informs whether we're navigating only through
* documents.
*
* NOTE:
* Consider the method searches upwards in all shadow host- or slot-rooted
* flattened subtrees that contains aStartContent as non-root, except
* the flattened subtree rooted at shadow host in light DOM.
*/
nsIContent* GetNextTabbableContentInAncestorScopes(nsIContent* aStartOwner,
nsIContent** aStartContent,
nsIContent* aOriginalStartContent,
bool aForward,
int32_t* aCurrentTabIndex,
bool aIgnoreTabIndex,
bool aForDocumentNavigation);
/**
* Retrieve the next tabbable element within a document, using focusability
* and tabindex to determine the tab order. The element is returned in
@@ -503,6 +588,16 @@ private:
void SetFocusedWindowInternal(nsPIDOMWindowOuter* aWindow);
bool TryDocumentNavigation(nsIContent* aCurrentContent,
bool* aCheckSubDocument,
nsIContent** aResultContent);
bool TryToMoveFocusToSubDocument(nsIContent* aCurrentContent,
nsIContent* aOriginalStartContent,
bool aForward,
bool aForDocumentNavigation,
nsIContent** aResultContent);
// the currently active and front-most top-most window
nsCOMPtr<nsPIDOMWindowOuter> mActiveWindow;
+1
View File
@@ -39,6 +39,7 @@ GK_ATOM(_moz_resizing, "_moz_resizing")
GK_ATOM(mozallowfullscreen, "mozallowfullscreen")
GK_ATOM(moztype, "_moz-type")
GK_ATOM(mozdirty, "_moz_dirty")
GK_ATOM(_is_cropped, "_is_cropped")
GK_ATOM(mozdisallowselectionprint, "mozdisallowselectionprint")
GK_ATOM(mozdonotsend, "moz-do-not-send")
GK_ATOM(mozeditorbogusnode, "_moz_editor_bogus_node")
+2 -2
View File
@@ -284,7 +284,7 @@ nsHTMLContentSerializer::AppendElementStart(Element* aElement,
if (ns == kNameSpaceID_XHTML &&
(name == nsGkAtoms::script ||
name == nsGkAtoms::style ||
name == nsGkAtoms::noscript ||
(name == nsGkAtoms::noscript && aElement->OwnerDoc()->IsScriptEnabled()) ||
name == nsGkAtoms::noframes)) {
++mDisableEntityEncoding;
}
@@ -314,7 +314,7 @@ nsHTMLContentSerializer::AppendElementEnd(Element* aElement,
if (ns == kNameSpaceID_XHTML &&
(name == nsGkAtoms::script ||
name == nsGkAtoms::style ||
name == nsGkAtoms::noscript ||
(name == nsGkAtoms::noscript && aElement->OwnerDoc()->IsScriptEnabled()) ||
name == nsGkAtoms::noframes)) {
--mDisableEntityEncoding;
}
+12 -26
View File
@@ -1811,26 +1811,6 @@ public:
nsIAtom* aAttrName,
const nsAString& aAttrValue) const = 0;
/**
* Helper for nsIDOMDocument::elementFromPoint implementation that allows
* ignoring the scroll frame and/or avoiding layout flushes.
*
* @see nsIDOMWindowUtils::elementFromPoint
*/
virtual Element* ElementFromPointHelper(float aX, float aY,
bool aIgnoreRootScrollFrame,
bool aFlushLayout) = 0;
enum ElementsFromPointFlags {
IGNORE_ROOT_SCROLL_FRAME = 1,
FLUSH_LAYOUT = 2,
IS_ELEMENT_FROM_POINT = 4
};
virtual void ElementsFromPointHelper(float aX, float aY,
uint32_t aFlags,
nsTArray<RefPtr<mozilla::dom::Element>>& aElements) = 0;
virtual nsresult NodesFromRectHelper(float aX, float aY,
float aTopSize, float aRightSize,
float aBottomSize, float aLeftSize,
@@ -2637,17 +2617,17 @@ public:
nsIURI* GetDocumentURIObject() const;
// Not const because all the full-screen goop is not const
virtual bool FullscreenEnabled() = 0;
virtual Element* GetFullscreenElement() = 0;
virtual Element* FullScreenStackTop() = 0;
bool Fullscreen()
{
return !!GetFullscreenElement();
}
void ExitFullscreen();
Element* GetPointerLockElement();
void ExitPointerLock()
{
UnlockPointer(this);
}
static bool IsUnprefixedFullscreenEnabled(JSContext* aCx, JSObject* aObject);
#ifdef MOZILLA_INTERNAL_API
bool Hidden() const
{
@@ -2664,10 +2644,6 @@ public:
void GetPreferredStyleSheetSet(nsAString& aSheetSet);
virtual mozilla::dom::DOMStringList* StyleSheetSets() = 0;
virtual void EnableStyleSheetsForSet(const nsAString& aSheetSet) = 0;
Element* ElementFromPoint(float aX, float aY);
void ElementsFromPoint(float aX,
float aY,
nsTArray<RefPtr<mozilla::dom::Element>>& aElements);
/**
* Retrieve the location of the caret position (DOM node and character
@@ -2835,6 +2811,16 @@ public:
bool ModuleScriptsEnabled();
/**
* Find the (non-anonymous) content in this document for aFrame. It will
* be aFrame's content node if that content is in this document and not
* anonymous. Otherwise, when aFrame is in a subdocument, we use the frame
* element containing the subdocument containing aFrame, and/or find the
* nearest non-anonymous ancestor in this document.
* Returns null if there is no such element.
*/
nsIContent* GetContentInThisDocument(nsIFrame* aFrame) const;
virtual void AddResizeObserver(mozilla::dom::ResizeObserver* aResizeObserver) = 0;
virtual void ScheduleResizeObserversNotification() const = 0;
+47 -36
View File
@@ -273,6 +273,18 @@ nsINode* nsINode::GetRootNode(const GetRootNodeOptions& aOptions)
return SubtreeRoot();
}
// TODO: was marked as constant.
nsINode*
nsINode::GetParentOrHostNode()
{
if (mParent) {
return mParent;
}
ShadowRoot* shadowRoot = ShadowRoot::FromNode(this);
return shadowRoot ? shadowRoot->GetHost() : nullptr;
}
nsINode*
nsINode::SubtreeRoot() const
{
@@ -1543,32 +1555,25 @@ nsINode::SetExplicitBaseURI(nsIURI* aURI)
return rv;
}
static nsresult
AdoptNodeIntoOwnerDoc(nsINode *aParent, nsINode *aNode)
static void
AdoptNodeIntoOwnerDoc(nsINode *aParent, nsINode *aNode, ErrorResult& aError)
{
NS_ASSERTION(!aNode->GetParentNode(),
"Should have removed from parent already");
nsIDocument *doc = aParent->OwnerDoc();
nsresult rv;
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(doc, &rv);
NS_ENSURE_SUCCESS(rv, rv);
DebugOnly<nsINode*> adoptedNode = doc->AdoptNode(*aNode, aError);
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aNode, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMNode> adoptedNode;
rv = domDoc->AdoptNode(node, getter_AddRefs(adoptedNode));
NS_ENSURE_SUCCESS(rv, rv);
NS_ASSERTION(aParent->OwnerDoc() == doc,
"ownerDoc chainged while adopting");
NS_ASSERTION(adoptedNode == node, "Uh, adopt node changed nodes?");
NS_ASSERTION(aParent->OwnerDoc() == aNode->OwnerDoc(),
#ifdef DEBUG
if (!aError.Failed()) {
MOZ_ASSERT(aParent->OwnerDoc() == doc,
"ownerDoc changed while adopting");
MOZ_ASSERT(adoptedNode == aNode, "Uh, adopt node changed nodes?");
MOZ_ASSERT(aParent->OwnerDoc() == aNode->OwnerDoc(),
"ownerDocument changed again after adopting!");
return NS_OK;
}
#endif // DEBUG
}
static nsresult
@@ -1593,19 +1598,20 @@ ReparentWrappersInSubtree(nsIContent* aRoot)
rootedGlobal = xpc::GetXBLScope(cx, rootedGlobal);
nsresult rv;
ErrorResult rv;
JS::Rooted<JSObject*> reflector(cx);
for (nsIContent* cur = aRoot; cur; cur = cur->GetNextNode(aRoot)) {
if ((reflector = cur->GetWrapper())) {
JSAutoCompartment ac(cx, reflector);
rv = ReparentWrapper(cx, reflector);
if NS_FAILED(rv) {
ReparentWrapper(cx, reflector, rv);
rv.WouldReportJSException();
if (rv.Failed()) {
// We _could_ consider BlastSubtreeToPieces here, but it's not really
// needed. Having some nodes in here accessible to content while others
// are not is probably OK. We just need to fail out of the actual
// insertion, so they're not in the DOM. Returning a failure here will
// do that.
return rv;
return rv.StealNSResult();
}
}
}
@@ -1619,7 +1625,6 @@ nsINode::doInsertChildAt(nsIContent* aKid, uint32_t aIndex,
{
NS_PRECONDITION(!aKid->GetParentNode(),
"Inserting node that already has parent");
nsresult rv;
// The id-handling code, and in the future possibly other code, need to
// react to unexpected attribute changes.
@@ -1630,15 +1635,23 @@ nsINode::doInsertChildAt(nsIContent* aKid, uint32_t aIndex,
mozAutoDocUpdate updateBatch(GetComposedDoc(), UPDATE_CONTENT_MODEL, aNotify);
if (OwnerDoc() != aKid->OwnerDoc()) {
rv = AdoptNodeIntoOwnerDoc(this, aKid);
NS_ENSURE_SUCCESS(rv, rv);
ErrorResult error;
AdoptNodeIntoOwnerDoc(this, aKid, error);
// Need to WouldReportJSException() if our callee can throw a JS
// exception (which it can) and we're neither propagating the
// error out nor unconditionally suppressing it.
error.WouldReportJSException();
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
}
uint32_t childCount = aChildArray.ChildCount();
NS_ENSURE_TRUE(aIndex <= childCount, NS_ERROR_ILLEGAL_VALUE);
bool isAppend = (aIndex == childCount);
rv = aChildArray.InsertChildAt(aKid, aIndex);
nsresult rv = aChildArray.InsertChildAt(aKid, aIndex);
NS_ENSURE_SUCCESS(rv, rv);
if (aIndex == 0) {
mFirstChild = aKid;
@@ -2475,7 +2488,7 @@ nsINode::ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
// inserting them w/o calling AdoptNode().
nsIDocument* doc = OwnerDoc();
if (doc != newContent->OwnerDoc()) {
aError = AdoptNodeIntoOwnerDoc(this, aNewChild);
AdoptNodeIntoOwnerDoc(this, aNewChild, aError);
if (aError.Failed()) {
return nullptr;
}
@@ -2879,9 +2892,9 @@ FindMatchingElementsWithId(const nsAString& aId, nsINode* aRoot,
// We have an element with the right id and it's a strict descendant
// of aRoot. Make sure it really matches the selector.
if (!aMatchInfo ||
nsCSSRuleProcessor::SelectorListMatches(element,
aMatchInfo->mMatchContext,
aMatchInfo->mSelectorList)) {
nsCSSRuleProcessor::RestrictedSelectorListMatches(element,
aMatchInfo->mMatchContext,
aMatchInfo->mSelectorList)) {
aList.AppendElement(element);
if (onlyFirstMatch) {
return;
@@ -2932,9 +2945,9 @@ FindMatchingElements(nsINode* aRoot, nsCSSSelectorList* aSelectorList, T &aList,
cur;
cur = cur->GetNextNode(aRoot)) {
if (cur->IsElement() &&
nsCSSRuleProcessor::SelectorListMatches(cur->AsElement(),
matchingContext,
aSelectorList)) {
nsCSSRuleProcessor::RestrictedSelectorListMatches(cur->AsElement(),
matchingContext,
aSelectorList)) {
if (onlyFirstMatch) {
aList.AppendElement(cur->AsElement());
return;
@@ -3072,9 +3085,7 @@ nsINode::WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
already_AddRefed<nsINode>
nsINode::CloneNode(bool aDeep, ErrorResult& aError)
{
nsCOMPtr<nsINode> result;
aError = nsNodeUtils::CloneNodeImpl(this, aDeep, getter_AddRefs(result));
return result.forget();
return nsNodeUtils::CloneNodeImpl(this, aDeep, aError);
}
nsDOMAttributeMap*
+6
View File
@@ -942,6 +942,12 @@ public:
return mParent;
}
/**
* This is similar to above, but in case 'this' is ShadowRoot, we return its
* host element.
*/
nsINode* GetParentOrHostNode();
/**
* Returns the node that is the parent of this node in the flattened
* tree. This differs from the normal parent if the node is filtered
+4 -4
View File
@@ -1412,16 +1412,16 @@ nsImageLoadingContent::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
nsIContent* aBindingParent,
bool aCompileEventHandlers)
{
// We may be entering the document, so if our image should be tracked,
// track it.
if (!aDocument)
// We may be getting connected and our image should be tracked.
nsCOMPtr<nsIDocument> doc = GetOurCurrentDoc();
if (!doc)
return;
TrackImage(mCurrentRequest);
TrackImage(mPendingRequest);
if (mCurrentRequestFlags & REQUEST_BLOCKS_ONLOAD)
aDocument->BlockOnload();
doc->BlockOnload();
}
void
+23 -8
View File
@@ -224,16 +224,23 @@ ProcessNameForCollectorLog()
namespace xpc {
// This handles JS Exceptions (via ExceptionStackOrNull), as well as DOM and XPC
// Exceptions.
// This handles JS Exceptions (via ExceptionStackOrNull), DOM and XPC
// Exceptions, and arbitrary values that were associated with a stack by the
// JS engine when they were thrown, as specified by exceptionStack.
//
// Note that the returned object is _not_ wrapped into the compartment of
// exceptionValue.
JSObject*
FindExceptionStackForConsoleReport(nsPIDOMWindowInner* win,
JS::HandleValue exceptionValue)
JS::HandleValue exceptionValue,
JS::HandleObject exceptionStack)
{
if (!exceptionValue.isObject()) {
// Use the stack provided by the JS engine, if available. This will not be
// a wrapper.
if (exceptionStack) {
return exceptionStack;
}
return nullptr;
}
@@ -257,6 +264,10 @@ FindExceptionStackForConsoleReport(nsPIDOMWindowInner* win,
// Not a DOM Exception, try XPC Exception.
UNWRAP_OBJECT(Exception, exceptionObject, exception);
if (!exception) {
// As above, use the stack provided by the JS engine, if available.
if (exceptionStack) {
return exceptionStack;
}
return nullptr;
}
}
@@ -421,10 +432,12 @@ public:
ScriptErrorEvent(nsPIDOMWindowInner* aWindow,
JS::RootingContext* aRootingCx,
xpc::ErrorReport* aReport,
JS::Handle<JS::Value> aError)
JS::Handle<JS::Value> aError,
JS::Handle<JSObject*> aErrorStack)
: mWindow(aWindow)
, mReport(aReport)
, mError(aRootingCx, aError)
, mErrorStack(aRootingCx, aErrorStack)
{}
NS_IMETHOD Run() override
@@ -471,7 +484,7 @@ public:
if (status != nsEventStatus_eConsumeNoDefault) {
JS::Rooted<JSObject*> stack(rootingCx,
xpc::FindExceptionStackForConsoleReport(win, mError));
xpc::FindExceptionStackForConsoleReport(win, mError, mErrorStack));
mReport->LogToConsoleWithStack(stack);
}
@@ -481,7 +494,8 @@ public:
private:
nsCOMPtr<nsPIDOMWindowInner> mWindow;
RefPtr<xpc::ErrorReport> mReport;
JS::PersistentRootedValue mError;
JS::PersistentRootedValue mError;
JS::PersistentRootedObject mErrorStack;
static bool sHandlingScriptError;
};
@@ -494,9 +508,10 @@ namespace xpc {
void
DispatchScriptErrorEvent(nsPIDOMWindowInner *win, JS::RootingContext* rootingCx,
xpc::ErrorReport *xpcReport, JS::Handle<JS::Value> exception)
xpc::ErrorReport *xpcReport, JS::Handle<JS::Value> exception,
JS::Handle<JSObject*> exceptionStack)
{
nsContentUtils::AddScriptRunner(new ScriptErrorEvent(win, rootingCx, xpcReport, exception));
nsContentUtils::AddScriptRunner(new ScriptErrorEvent(win, rootingCx, xpcReport, exception, exceptionStack));
}
} /* namespace xpc */
+79 -42
View File
@@ -402,28 +402,20 @@ nsNodeUtils::TraverseUserData(nsINode* aNode,
}
/* static */
nsresult
nsNodeUtils::CloneNodeImpl(nsINode *aNode, bool aDeep, nsINode **aResult)
already_AddRefed<nsINode>
nsNodeUtils::CloneNodeImpl(nsINode *aNode, bool aDeep, ErrorResult& aError)
{
*aResult = nullptr;
nsCOMPtr<nsINode> newNode;
nsCOMArray<nsINode> nodesWithProperties;
nsresult rv = Clone(aNode, aDeep, nullptr, nodesWithProperties,
getter_AddRefs(newNode));
NS_ENSURE_SUCCESS(rv, rv);
newNode.forget(aResult);
return NS_OK;
return Clone(aNode, aDeep, nullptr, &nodesWithProperties, aError);
}
/* static */
nsresult
already_AddRefed<nsINode>
nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
nsNodeInfoManager *aNewNodeInfoManager,
JS::Handle<JSObject*> aReparentScope,
nsCOMArray<nsINode> &aNodesWithProperties,
nsINode *aParent, nsINode **aResult)
nsCOMArray<nsINode> *aNodesWithProperties,
nsINode *aParent, ErrorResult& aError)
{
NS_PRECONDITION((!aClone && aNewNodeInfoManager) || !aReparentScope,
"If cloning or not getting a new nodeinfo we shouldn't "
@@ -431,14 +423,11 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
NS_PRECONDITION(!aParent || aNode->IsNodeOfType(nsINode::eCONTENT),
"Can't insert document or attribute nodes into a parent");
*aResult = nullptr;
// First deal with aNode and walk its attributes (and their children). Then,
// if aDeep is true, deal with aNode's children (and recurse into their
// attributes and children).
nsAutoScriptBlocker scriptBlocker;
nsresult rv;
nsNodeInfoManager *nodeInfoManager = aNewNodeInfoManager;
@@ -450,14 +439,20 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
// Don't allow importing/adopting nodes from non-privileged "scriptable"
// documents to "non-scriptable" documents.
nsIDocument* newDoc = nodeInfoManager->GetDocument();
NS_ENSURE_STATE(newDoc);
if (NS_WARN_IF(!newDoc)) {
aError.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
bool hasHadScriptHandlingObject = false;
if (!newDoc->GetScriptHandlingObject(hasHadScriptHandlingObject) &&
!hasHadScriptHandlingObject) {
nsIDocument* currentDoc = aNode->OwnerDoc();
NS_ENSURE_STATE((nsContentUtils::IsChromeDoc(currentDoc) ||
(!currentDoc->GetScriptHandlingObject(hasHadScriptHandlingObject) &&
!hasHadScriptHandlingObject)));
if (NS_WARN_IF(!nsContentUtils::IsChromeDoc(currentDoc) &&
(currentDoc->GetScriptHandlingObject(hasHadScriptHandlingObject) ||
hasHadScriptHandlingObject))) {
aError.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
}
newNodeInfo = nodeInfoManager->GetNodeInfo(nodeInfo->NameAtom(),
@@ -473,8 +468,11 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
nsCOMPtr<nsINode> clone;
if (aClone) {
rv = aNode->Clone(nodeInfo, getter_AddRefs(clone));
NS_ENSURE_SUCCESS(rv, rv);
nsresult rv = aNode->Clone(nodeInfo, getter_AddRefs(clone));
if (NS_WARN_IF(NS_FAILED(rv))) {
aError.Throw(rv);
return nullptr;
}
if (CustomElementRegistry::IsCustomElementEnabled() &&
clone->IsHTMLElement()) {
@@ -512,7 +510,10 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
// parent.
rv = aParent->AppendChildTo(static_cast<nsIContent*>(clone.get()),
false);
NS_ENSURE_SUCCESS(rv, rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
aError.Throw(rv);
return nullptr;
}
}
else if (aDeep && clone->IsNodeOfType(nsINode::eDOCUMENT)) {
// After cloning the document itself, we want to clone the children into
@@ -611,8 +612,8 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
if ((wrapper = aNode->GetWrapper())) {
MOZ_ASSERT(IsDOMObject(wrapper));
JSAutoCompartment ac(cx, wrapper);
rv = ReparentWrapper(cx, wrapper);
if (NS_FAILED(rv)) {
ReparentWrapper(cx, wrapper, aError);
if (aError.Failed()) {
if (wasRegistered) {
aNode->OwnerDoc()->UnregisterActivityObserver(aNode->AsElement());
}
@@ -620,17 +621,17 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
if (wasRegistered) {
aNode->OwnerDoc()->RegisterActivityObserver(aNode->AsElement());
}
return rv;
return nullptr;
}
}
}
}
if (aNode->HasProperties()) {
bool ok = aNodesWithProperties.AppendObject(aNode);
bool ok = aNodesWithProperties->AppendObject(aNode);
MOZ_RELEASE_ASSERT(ok, "Out of memory");
if (aClone) {
ok = aNodesWithProperties.AppendObject(clone);
ok = aNodesWithProperties->AppendObject(clone);
MOZ_RELEASE_ASSERT(ok, "Out of memory");
}
}
@@ -640,11 +641,47 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
for (nsIContent* cloneChild = aNode->GetFirstChild();
cloneChild;
cloneChild = cloneChild->GetNextSibling()) {
nsCOMPtr<nsINode> child;
rv = CloneAndAdopt(cloneChild, aClone, true, nodeInfoManager,
aReparentScope, aNodesWithProperties, clone,
getter_AddRefs(child));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsINode> child =
CloneAndAdopt(cloneChild, aClone, true, nodeInfoManager,
aReparentScope, aNodesWithProperties, clone,
aError);
if (NS_WARN_IF(aError.Failed())) {
return nullptr;
}
}
}
if (aDeep && aNode->IsElement()) {
ShadowRoot* shadowRoot = aNode->AsElement()->GetShadowRoot();
if (!shadowRoot) {
// Nothing to do here.
} else if (aClone && clone->OwnerDoc()->IsStaticDocument()) {
ShadowRootInit init;
init.mMode = shadowRoot->Mode();
RefPtr<ShadowRoot> newShadowRoot =
clone->AsElement()->AttachShadow(init, aError);
if (NS_WARN_IF(aError.Failed())) {
return nullptr;
}
newShadowRoot->CloneInternalDataFrom(shadowRoot);
for (nsIContent* originalChild = shadowRoot->GetFirstChild();
originalChild;
originalChild = originalChild->GetNextSibling()) {
nsCOMPtr<nsINode> child = CloneAndAdopt(originalChild, aClone, aDeep, nodeInfoManager,
aReparentScope, aNodesWithProperties, newShadowRoot,
aError);
if (NS_WARN_IF(aError.Failed())) {
return nullptr;
}
}
} else if (!aClone) {
nsCOMPtr<nsINode> child = CloneAndAdopt(shadowRoot, aClone, aDeep, nodeInfoManager,
aReparentScope, aNodesWithProperties, clone,
aError);
if (NS_WARN_IF(aError.Failed())) {
return nullptr;
}
}
}
@@ -663,11 +700,13 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
for (nsIContent* cloneChild = origContent->GetFirstChild();
cloneChild;
cloneChild = cloneChild->GetNextSibling()) {
nsCOMPtr<nsINode> child;
rv = CloneAndAdopt(cloneChild, aClone, aDeep, ownerNodeInfoManager,
aReparentScope, aNodesWithProperties, cloneContent,
getter_AddRefs(child));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsINode> child =
CloneAndAdopt(cloneChild, aClone, aDeep, ownerNodeInfoManager,
aReparentScope, aNodesWithProperties, cloneContent,
aError);
if (NS_WARN_IF(aError.Failed())) {
return nullptr;
}
}
}
@@ -688,9 +727,7 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
}
}
clone.forget(aResult);
return NS_OK;
return clone.forget();
}
+36 -35
View File
@@ -17,6 +17,7 @@ template<class E> class nsCOMArray;
class nsCycleCollectionTraversalCallback;
namespace mozilla {
struct NonOwningAnimationTarget;
class ErrorResult;
namespace dom {
class Animation;
} // namespace dom
@@ -181,25 +182,17 @@ public:
* @param aNodesWithProperties All nodes (from amongst aNode and its
* descendants) with properties. Every node will
* be followed by its clone.
* @param aResult *aResult will contain the cloned node.
* @param aError The error, if any.
*
* @return The newly created node. Null in error conditions.
*/
static nsresult Clone(nsINode *aNode, bool aDeep,
nsNodeInfoManager *aNewNodeInfoManager,
nsCOMArray<nsINode> &aNodesWithProperties,
nsINode **aResult)
static already_AddRefed<nsINode> Clone(nsINode *aNode, bool aDeep,
nsNodeInfoManager *aNewNodeInfoManager,
nsCOMArray<nsINode> *aNodesWithProperties,
mozilla::ErrorResult& aError)
{
return CloneAndAdopt(aNode, true, aDeep, aNewNodeInfoManager,
nullptr, aNodesWithProperties, nullptr, aResult);
}
/**
* Clones aNode, its attributes and, if aDeep is true, its descendant nodes
*/
static nsresult Clone(nsINode *aNode, bool aDeep, nsINode **aResult)
{
nsCOMArray<nsINode> dummyNodeWithProperties;
return CloneAndAdopt(aNode, true, aDeep, nullptr, nullptr,
dummyNodeWithProperties, aNode->GetParent(), aResult);
nullptr, aNodesWithProperties, nullptr, aError);
}
/**
@@ -218,19 +211,20 @@ public:
* should be done.
* @param aNodesWithProperties All nodes (from amongst aNode and its
* descendants) with properties.
* @param aError The error, if any.
*/
static nsresult Adopt(nsINode *aNode, nsNodeInfoManager *aNewNodeInfoManager,
JS::Handle<JSObject*> aReparentScope,
nsCOMArray<nsINode> &aNodesWithProperties)
static void Adopt(nsINode *aNode, nsNodeInfoManager *aNewNodeInfoManager,
JS::Handle<JSObject*> aReparentScope,
nsCOMArray<nsINode>& aNodesWithProperties,
mozilla::ErrorResult& aError)
{
nsCOMPtr<nsINode> node;
nsresult rv = CloneAndAdopt(aNode, false, true, aNewNodeInfoManager,
aReparentScope, aNodesWithProperties,
nullptr, getter_AddRefs(node));
// Just need to store the return value of CloneAndAdopt in a
// temporary nsCOMPtr to make sure we release it.
nsCOMPtr<nsINode> node = CloneAndAdopt(aNode, false, true, aNewNodeInfoManager,
aReparentScope, &aNodesWithProperties,
nullptr, aError);
nsMutationGuard::DidMutate();
return rv;
}
/**
@@ -248,9 +242,12 @@ public:
*
* @param aNode the node to clone
* @param aDeep if true all descendants will be cloned too
* @param aResult the clone
* @param aError the error, if any.
*
* @return the clone, or null if an error occurs.
*/
static nsresult CloneNodeImpl(nsINode *aNode, bool aDeep, nsINode **aResult);
static already_AddRefed<nsINode> CloneNodeImpl(nsINode *aNode, bool aDeep,
mozilla::ErrorResult& aError);
/**
* Release the UserData for aNode.
@@ -286,7 +283,7 @@ private:
*
* @param aNode Node to adopt/clone.
* @param aClone If true the node will be cloned and the cloned node will
* be in aResult.
* be returned.
* @param aDeep If true the function will be called recursively on
* descendants of the node
* @param aNewNodeInfoManager The nodeinfo manager to use to create new
@@ -302,14 +299,18 @@ private:
* @param aParent If aClone is true the cloned node will be appended to
* aParent's children. May be null. If not null then aNode
* must be an nsIContent.
* @param aResult If aClone is true then *aResult will contain the cloned
* node.
* @param aError The error, if any.
*
* @return If aClone is true then the cloned node will be returned,
* unless an error occurred. In error conditions, null
* will be returned.
*/
static nsresult CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
nsNodeInfoManager *aNewNodeInfoManager,
JS::Handle<JSObject*> aReparentScope,
nsCOMArray<nsINode> &aNodesWithProperties,
nsINode *aParent, nsINode **aResult);
static already_AddRefed<nsINode>
CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
nsNodeInfoManager* aNewNodeInfoManager,
JS::Handle<JSObject*> aReparentScope,
nsCOMArray<nsINode> *aNodesWithProperties,
nsINode *aParent, mozilla::ErrorResult& aError);
enum class AnimationMutationType
{
-1
View File
@@ -86,7 +86,6 @@
#include "mozilla/EventStates.h"
#include "mozilla/dom/HTMLObjectElementBinding.h"
#include "mozilla/dom/HTMLSharedObjectElement.h"
#include "nsChannelClassifier.h"
#ifdef XP_WIN
// Thanks so much, Microsoft! :(
+8 -16
View File
@@ -304,14 +304,6 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
return NS_OK;
}
// Check for a ShadowRoot because link elements are inert in a
// ShadowRoot.
ShadowRoot* containingShadow = thisContent->GetContainingShadow();
if (thisContent->IsHTMLElement(nsGkAtoms::link) &&
(aOldShadowRoot || containingShadow)) {
return NS_OK;
}
// XXXheycam ServoStyleSheets do not support <style scoped>.
Element* oldScopeElement = nullptr;
if (mStyleSheet) {
@@ -346,15 +338,16 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
}
}
// When static documents are created, stylesheets are cloned manually.
if (mDontLoadStyle || !mUpdatesEnabled ||
thisContent->OwnerDoc()->IsStaticDocument()) {
nsCOMPtr<nsIDocument> doc = thisContent->IsInShadowTree() ?
thisContent->OwnerDoc() : thisContent->GetUncomposedDoc();
// Loader could be null during unlink, see bug 1425866.
if (!doc || !doc->CSSLoader() || !doc->CSSLoader()->GetEnabled()) {
return NS_OK;
}
nsCOMPtr<nsIDocument> doc = thisContent->IsInShadowTree() ?
thisContent->OwnerDoc() : thisContent->GetUncomposedDoc();
if (!doc || !doc->CSSLoader()->GetEnabled()) {
// When static documents are created, stylesheets are cloned manually.
if (mDontLoadStyle || !mUpdatesEnabled || doc->IsStaticDocument()) {
return NS_OK;
}
@@ -426,8 +419,7 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
rv = doc->CSSLoader()->
LoadInlineStyle(thisContent, text, mLineNumber, title, media,
scopeElement, aObserver, &doneLoading, &isAlternate, &isExplicitlyEnabled);
}
else {
} else {
nsAutoString integrity;
thisContent->GetAttr(kNameSpaceID_None, nsGkAtoms::integrity, integrity);
if (!integrity.IsEmpty()) {
+903
View File
@@ -0,0 +1,903 @@
<html>
<head>
<title>Test for Bug 1453693</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script>
class TestNode extends HTMLElement {
constructor() {
super();
const styles = "<style>:focus{background-color:yellow;}</style>";
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML =
`${styles}<div tabindex='-1'>test node</div> <slot></slot>`;
}}
window.customElements.define('test-node', TestNode);
var lastFocusTarget;
function focusLogger(event) {
lastFocusTarget = event.target;
console.log(event.target + " under " + event.target.parentNode);
event.stopPropagation();
}
function testTabbingThroughShadowDOMWithTabIndexes() {
var anchor = document.createElement("a");
anchor.onfocus = focusLogger;
anchor.href = "#";
anchor.textContent = "in light DOM";
document.body.appendChild(anchor);
var host = document.createElement("div");
document.body.appendChild(host);
var sr = host.attachShadow({mode: "open"});
var shadowAnchor = anchor.cloneNode(false);
shadowAnchor.onfocus = focusLogger;
shadowAnchor.textContent = "in shadow DOM";
sr.appendChild(shadowAnchor);
var shadowInput = document.createElement("input");
shadowInput.onfocus = focusLogger;
shadowInput.tabIndex = 1;
sr.appendChild(shadowInput);
var shadowDate = document.createElement("input");
shadowDate.type = "date";
shadowDate.onfocus = focusLogger;
shadowDate.tabIndex = 1;
sr.appendChild(shadowDate);
var shadowIframe = document.createElement("iframe");
shadowIframe.tabIndex = 1;
sr.appendChild(shadowIframe);
shadowIframe.contentDocument.body.innerHTML = "<input>";
var input = document.createElement("input");
input.onfocus = focusLogger;
input.tabIndex = 1;
document.body.appendChild(input);
var input2 = document.createElement("input");
input2.onfocus = focusLogger;
document.body.appendChild(input2);
document.body.offsetLeft;
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input, "Should have focused input element. (3)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, anchor, "Should have focused anchor element. (3)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, shadowInput, "Should have focused input element in shadow DOM. (3)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, shadowDate, "Should have focused date element in shadow DOM. (3)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, shadowDate, "Should have focused date element in shadow DOM. (3)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, shadowDate, "Should have focused date element in shadow DOM. (3)");
synthesizeKey("KEY_Tab");
opener.is(shadowIframe.contentDocument.activeElement,
shadowIframe.contentDocument.documentElement,
"Should have focused document element in shadow iframe. (3)");
synthesizeKey("KEY_Tab");
opener.is(shadowIframe.contentDocument.activeElement,
shadowIframe.contentDocument.body.firstChild,
"Should have focused input element in shadow iframe. (3)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, shadowAnchor, "Should have focused anchor element in shadow DOM. (3)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input2, "Should have focused input[2] element. (3)");
// Backwards
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, shadowAnchor, "Should have focused anchor element in shadow DOM. (4)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(shadowIframe.contentDocument.activeElement,
shadowIframe.contentDocument.body.firstChild,
"Should have focused input element in shadow iframe. (4)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(shadowIframe.contentDocument.activeElement,
shadowIframe.contentDocument.documentElement,
"Should have focused document element in shadow iframe. (4)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, shadowDate, "Should have focused date element in shadow DOM. (4)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, shadowDate, "Should have focused date element in shadow DOM. (4)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, shadowDate, "Should have focused date element in shadow DOM. (4)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, shadowInput, "Should have focused input element in shadow DOM. (4)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, anchor, "Should have focused anchor element. (4)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, input, "Should have focused input element. (4)");
document.body.innerHTML = null;
}
function testTabbingThroughSimpleShadowDOM() {
var anchor = document.createElement("a");
anchor.onfocus = focusLogger;
anchor.href = "#";
anchor.textContent = "in light DOM";
document.body.appendChild(anchor);
anchor.focus();
var host = document.createElement("div");
document.body.appendChild(host);
var sr = host.attachShadow({mode: "open"});
var shadowAnchor = anchor.cloneNode(false);
shadowAnchor.onfocus = focusLogger;
shadowAnchor.textContent = "in shadow DOM";
sr.appendChild(shadowAnchor);
var shadowInput = document.createElement("input");
shadowInput.onfocus = focusLogger;
sr.appendChild(shadowInput);
var hiddenShadowButton = document.createElement("button");
hiddenShadowButton.setAttribute("style", "display: none;");
sr.appendChild(hiddenShadowButton);
var input = document.createElement("input");
input.onfocus = focusLogger;
document.body.appendChild(input);
var input2 = document.createElement("input");
input2.onfocus = focusLogger;
document.body.appendChild(input2);
document.body.offsetLeft;
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, shadowAnchor, "Should have focused anchor element in shadow DOM.");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, shadowInput, "Should have focused input element in shadow DOM.");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input, "Should have focused input element.");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input2, "Should have focused input[2] element.");
// Backwards
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, input, "Should have focused input element. (2)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, shadowInput, "Should have focused input element in shadow DOM. (2)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, shadowAnchor, "Should have focused anchor element in shadow DOM. (2)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, anchor, "Should have focused anchor element. (2)");
host.remove();
input.remove();
input2.remove();
}
function testTabbingThroughNestedShadowDOM() {
opener.is(document.activeElement, document.body.firstChild, "body's first child should have focus. (1)");
var host = document.createElement("div");
host.id = "host";
document.body.appendChild(host);
var sr0 = host.attachShadow({mode: "open"});
sr0.innerHTML = "<button id='button'>X</button><br id='br'><div id='h1'></div><div id='h2'></div>";
var button = sr0.getElementById("button");
button.onfocus = focusLogger;
var h1 = sr0.getElementById("h1");
var sr1 = h1.attachShadow({mode: "open"});
sr1.innerHTML = "h1 <input id='h11' placeholder='click me and press tab'><input id='h12' placeholder='and then tab again'>";
var input11 = sr1.getElementById("h11");
input11.onfocus = focusLogger;
var input12 = sr1.getElementById("h12");
input12.onfocus = focusLogger;
var h2 = sr0.getElementById("h2");
var sr2 = h2.attachShadow({mode: "open"});
sr2.innerHTML = "h2 <input id='h21'><input id='h22'>";
var input21 = sr2.getElementById("h21");
input21.onfocus = focusLogger;
var input22 = sr2.getElementById("h22");
input22.onfocus = focusLogger;
document.body.offsetLeft;
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, button, "[nested shadow] Should have focused button element. (1)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input11, "[nested shadow] Should have focused input element. (1)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input12, "[nested shadow] Should have focused input element. (2)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input21, "[nested shadow] Should have focused input element. (3)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input22, "[nested shadow] Should have focused input element. (4)");
// Backwards
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, input21, "[nested shadow] Should have focused input element. (5)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, input12, "[nested shadow] Should have focused input element. (6)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, input11, "[nested shadow] Should have focused input element. (7)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, button, "[nested shadow] Should have focused button element. (8)");
// Back to beginning, outside of Shadow DOM.
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(document.activeElement, document.body.firstChild, "body's first child should have focus. (2)");
host.remove();
}
function testTabbingThroughDisplayContentsHost() {
opener.is(document.activeElement, document.body.firstChild, "body's first child should have focus. (1)");
var host = document.createElement("div");
host.id = "host";
host.setAttribute("style", "display: contents; border: 1px solid black;");
document.body.appendChild(host);
var sr0 = host.attachShadow({mode: "open"});
sr0.innerHTML = "<input id='shadowInput1'><input id='shadowInput2'>";
var shadowInput1 = sr0.getElementById("shadowInput1");
shadowInput1.onfocus = focusLogger;
var shadowInput2 = sr0.getElementById("shadowInput2");
shadowInput2.onfocus = focusLogger;
var host1 = document.createElement("div");
host1.id = "host";
host1.tabIndex = 0;
host1.setAttribute("style", "display: contents; border: 1px solid black;");
document.body.appendChild(host1);
var sr1 = host1.attachShadow({mode: "open"});
sr1.innerHTML = "<input id='shadowInput1'><input id='shadowInput2'>";
var shadowInput3 = sr1.getElementById("shadowInput1");
shadowInput3.onfocus = focusLogger;
var shadowInput4 = sr1.getElementById("shadowInput2");
shadowInput4.onfocus = focusLogger;
document.body.offsetLeft;
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, shadowInput1, "Should have focused input element. (1)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, shadowInput2, "Should have focused input element. (2)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, shadowInput3, "Should have focused input element. (3)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, shadowInput4, "Should have focused input element. (4)");
// Backwards
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, shadowInput3, "Should have focused input element. (5)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, shadowInput2, "Should have focused input element. (6)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, shadowInput1, "Should have focused input element. (7)");
// Back to beginning, outside of Shadow DOM.
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(document.activeElement, document.body.firstChild, "body's first child should have focus. (2)");
host.remove();
host1.remove();
}
function testTabbingThroughLightDOMShadowDOMLightDOM() {
opener.is(document.activeElement, document.body.firstChild,
"body's first child should have focus.");
var host = document.createElement("span");
host.innerHTML = "\n";
host.id = "host";
document.body.appendChild(host);
var sr0 = host.attachShadow({mode: "open"});
sr0.innerHTML = document.getElementById("template").innerHTML;
var p1 = sr0.getElementById("p1");
p1.onfocus = focusLogger;
var p2 = sr0.getElementById("p2");
p2.onfocus = focusLogger;
var p = document.createElement("p");
p.innerHTML = " <a href='#p'>link 1</a> ";
var a = p.firstElementChild;
a.onfocus = focusLogger;
document.body.appendChild(p);
document.body.offsetLeft;
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, p1, "Should have focused p1.");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, p2, "Should have focused p2.");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, a, "Should have focused a.");
// Backwards
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, p2, "Should have focused p2.");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, p1, "Should have focused p1.");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(document.activeElement, document.body.firstChild,
"body's first child should have focus.");
host.remove();
p.remove();
}
function testFocusableHost() {
opener.is(document.activeElement, document.body.firstChild,
"body's first child should have focus.");
var host = document.createElement("div");
host.id = "host";
host.tabIndex = 0;
host.onfocus = focusLogger;
document.body.appendChild(host);
var slotted = document.createElement("div");
slotted.tabIndex = 0;
slotted.onfocus = focusLogger;
host.appendChild(slotted);
var sr0 = host.attachShadow({mode: "open"});
sr0.appendChild(document.createElement("slot"));
var p = document.createElement("p");
p.innerHTML = " <a href='#p'>link 1</a> ";
var a = p.firstElementChild;
a.onfocus = focusLogger;
document.body.appendChild(p);
document.body.offsetLeft;
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, host, "Should have focused host.");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, slotted, "Should have focused slotted.");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, a, "Should have focused a.");
// Backwards
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, slotted, "Should have focused slotted.");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, host, "Should have focused host.");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(document.activeElement, document.body.firstChild,
"body's first child should have focus.");
host.remove();
p.remove();
}
function testShiftTabbingThroughFocusableHost() {
opener.is(document.activeElement, document.body.firstChild,
"body's first child should have focus.");
var host = document.createElement("div");
host.id = "host";
host.tabIndex = 0;
host.onfocus = focusLogger;
document.body.appendChild(host);
var sr = host.attachShadow({mode: "open"});
var shadowButton = document.createElement("button");
shadowButton.innerText = "X";
shadowButton.onfocus = focusLogger;
sr.appendChild(shadowButton);
var shadowInput = document.createElement("input");
shadowInput.onfocus = focusLogger;
sr.appendChild(shadowInput);
sr.appendChild(document.createElement("br"));
var input = document.createElement("input");
input.onfocus = focusLogger;
document.body.appendChild(input);
document.body.offsetLeft;
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, host, "Should have focused host element. (1)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, shadowButton, "Should have focused button element in shadow DOM. (2)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, shadowInput, "Should have focused input element in shadow DOM. (3)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input, "Should have focused input element. (4)");
// Backwards
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, shadowInput, "Should have focused input element in shadow DOM. (5)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, shadowButton, "Should have focused button element in shadow DOM. (6)");
synthesizeKey("KEY_Tab", {shiftKey: true});
// focus is already on host
opener.is(sr.activeElement, null,
"Focus should have left button element in shadow DOM. (7)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(document.activeElement, document.body.firstChild,
"body's first child should have focus.");
host.remove();
input.remove();
}
function testTabbingThroughNestedSlot() {
opener.is(document.activeElement, document.body.firstChild, "body's first child should have focus.");
var host0 = document.createElement("div");
var sr0 = host0.attachShadow({mode: "open"});
sr0.innerHTML = "<slot></slot>";
document.body.appendChild(host0);
// focusable
var host00 = document.createElement("div");
var sr00 = host00.attachShadow({mode: "open"});
var div00 = document.createElement("div");
div00.tabIndex = 0;
div00.onfocus = focusLogger;
sr00.appendChild(div00);
host0.appendChild(host00);
// not focusable
var host01 = document.createElement("div");
var sr01 = host01.attachShadow({mode: "open"});
sr01.innerHTML = "<div></div>";
host0.appendChild(host01);
// focusable
var host02 = document.createElement("div");
var sr02 = host02.attachShadow({mode: "open"});
var div02 = document.createElement("div");
div02.tabIndex = 0;
div02.onfocus = focusLogger;
sr02.appendChild(div02);
host0.appendChild(host02);
var host1 = document.createElement("div");
var sr1 = host1.attachShadow({mode: "open"});
sr1.innerHTML = "<slot></slot>";
document.body.appendChild(host1);
var host10 = document.createElement("div");
var sr10 = host10.attachShadow({mode: "open"});
sr10.innerHTML = "<slot></slot>";
host1.appendChild(host10);
var input10 = document.createElement("input");
input10.onfocus = focusLogger;
host10.appendChild(input10);
var host11 = document.createElement("div");
var sr11 = host11.attachShadow({mode: "open"});
sr11.innerHTML = "<slot></slot>";
host1.appendChild(host11);
var input11 = document.createElement("input");
input11.onfocus = focusLogger;
host11.appendChild(input11);
document.body.offsetLeft;
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, div00, "Should have focused div element in shadow DOM. (1)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, div02, "Should have focused div element in shadow DOM. (2)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input10, "Should have focused input element in shadow DOM. (3)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input11, "Should have focused button element in shadow DOM. (4)");
// Backwards
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, input10, "Should have focused input element in shadow DOM. (5)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, div02, "Should have focused input element in shadow DOM. (6)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, div00, "Should have focused input element in shadow DOM. (7)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(document.activeElement, document.body.firstChild,
"body's first child should have focus.");
host0.remove();
host1.remove();
}
function testTabbingThroughSlotInLightDOM() {
opener.is(document.activeElement, document.body.firstChild, "body's first child should have focus.");
var input0 = document.createElement("input");
input0.onfocus = focusLogger;
document.body.appendChild(input0);
var slot1 = document.createElement("slot");
document.body.appendChild(slot1);
var input10 = document.createElement("input");
input10.onfocus = focusLogger;
slot1.appendChild(input10);
var input11 = document.createElement("input");
input11.onfocus = focusLogger;
slot1.appendChild(input11);
var input2 = document.createElement("input");
input2.onfocus = focusLogger;
document.body.appendChild(input2);
document.body.offsetLeft;
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input0, "Should have focused input element. (1)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input10, "Should have focused input element in slot. (2)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input11, "Should have focused input element in slot. (3)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input2, "Should have focused input element. (4)");
// Backwards
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, input11, "Should have focused input element in slot. (5)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, input10, "Should have focused input element in slot. (6)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, input0, "Should have focused input element. (7)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(document.activeElement, document.body.firstChild,
"body's first child should have focus.");
input0.remove();
slot1.remove();
input2.remove();
}
function testTabbingThroughFocusableSlotInLightDOM() {
opener.is(document.activeElement, document.body.firstChild, "body's first child should have focus.");
var slot0 = document.createElement("slot");
slot0.tabIndex = 0;
slot0.setAttribute("style", "display: inline;");
slot0.onfocus = focusLogger;
document.body.appendChild(slot0);
var slot00 = document.createElement("slot");
slot00.tabIndex = 0;
slot00.setAttribute("style", "display: inline;");
slot00.onfocus = focusLogger;
slot0.appendChild(slot00);
var input000 = document.createElement("input");
input000.onfocus = focusLogger;
slot00.appendChild(input000);
var input01 = document.createElement("input");
input01.onfocus = focusLogger;
slot0.appendChild(input01);
var input1 = document.createElement("input");
input1.onfocus = focusLogger;
document.body.appendChild(input1);
document.body.offsetLeft;
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, slot0, "Should have focused slot element. (1)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, slot00, "Should have focused slot element. (2)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input000, "Should have focused input element in slot. (3)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input01, "Should have focused input element in slot. (4)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input1, "Should have focused input element. (5)");
// Backwards
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, input01, "Should have focused input element in slot. (6)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, input000, "Should have focused input element in slot. (7)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, slot00, "Should have focused slot element. (8)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, slot0, "Should have focused slot element. (9)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(document.activeElement, document.body.firstChild,
"body's first child should have focus.");
slot0.remove();
input1.remove();
}
function testTabbingThroughScrollableShadowDOM() {
opener.is(document.activeElement, document.body.firstChild, "body's first child should have focus.");
var host0 = document.createElement("div");
host0.setAttribute("style", "height: 50px; overflow: auto;");
host0.onfocus = focusLogger;
document.body.appendChild(host0);
var sr0 = host0.attachShadow({mode: "open"});
sr0.innerHTML = `
<style>
div,slot {
height: 30px;
display: block;
overflow: auto;
}
input {
display: block;
}
</style>
`;
var input00 = document.createElement("input");
input00.setAttribute("style", "background-color: red;");
input00.onfocus = focusLogger;
sr0.appendChild(input00);
var container01 = document.createElement("div");
container01.onfocus = focusLogger;
sr0.appendChild(container01);
var input010 = document.createElement("input");
input010.onfocus = focusLogger;
container01.appendChild(input010);
var input011 = document.createElement("input");
input011.onfocus = focusLogger;
container01.appendChild(input011);
var slot02 = document.createElement("slot");
slot02.onfocus = focusLogger;
sr0.appendChild(slot02);
var input020 = document.createElement("input");
input020.setAttribute("style", "display: block;");
input020.onfocus = focusLogger;
host0.appendChild(input020);
var input021 = document.createElement("input");
input021.setAttribute("style", "display: block;");
input021.onfocus = focusLogger;
host0.appendChild(input021);
var input1 = document.createElement("input");
input1.onfocus = focusLogger;
document.body.appendChild(input1);
document.body.offsetLeft;
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, host0, "Should have focused shadow host element. (1)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input00, "Should have focused input element in shadow dom. (2)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, container01, "Should have focused scrollable element in shadow dom. (3)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input010, "Should have focused input element in shadow dom. (4)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input011, "Should have focused input element in shadow dom. (5)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, slot02, "Should have focused slot element in shadow dom. (6)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input020, "Should have focused input element in slot. (7)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input021, "Should have focused input element in slot. (8)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input1, "Should have focused input element in light dom. (9)");
// Backwards
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, input021, "Should have focused input element in slot. (10)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, input020, "Should have focused input element in slot. (11)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, slot02, "Should have focused slot element in shadow dom. (12)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, input011, "Should have focused input element in shadow dom. (13)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, input010, "Should have focused input element in shadow dom. (14)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, container01, "Should have focused scrollable element in shadow dom. (15)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, input00, "Should have focused input element in shadow dom. (16)");
synthesizeKey("KEY_Tab", {shiftKey: true});
// focus is already on host
opener.is(sr0.activeElement, null,
"Focus should have left input element in shadow DOM. (7)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(document.activeElement, document.body.firstChild,
"body's first child should have focus.");
host0.remove();
input1.remove();
}
function testDeeplyNestedShadowTree() {
opener.is(document.activeElement, document.body.firstChild, "body's first child should have focus.");
var host1 = document.createElement("test-node");
var lastHost = host1;
for (var i = 0; i < 20; ++i) {
lastHost.appendChild(document.createElement("test-node"));
lastHost = lastHost.firstChild;
}
var input = document.createElement("input");
document.body.appendChild(host1);
document.body.appendChild(input);
document.body.offsetLeft;
// Test shadow tree which doesn't have anything tab-focusable.
host1.shadowRoot.querySelector("div").focus();
synthesizeKey("KEY_Tab");
is(document.activeElement, input, "Should have focused input element.");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(document.activeElement, document.body.firstChild, "body's first child should have focus.");
// Same test but with focusable elements in the tree...
var input2 = document.createElement("input");
var host2 = host1.firstChild;
var host3 = host2.firstChild;
host2.insertBefore(input2, host3);
var input3 = document.createElement("input");
lastHost.appendChild(input3);
document.body.offsetLeft;
host3.shadowRoot.querySelector("div").focus();
synthesizeKey("KEY_Tab");
is(document.activeElement, input3, "Should have focused input3 element.");
// ...and backwards
host3.shadowRoot.querySelector("div").focus();
synthesizeKey("KEY_Tab", {shiftKey: true});
is(document.activeElement, input2, "Should have focused input2 element.");
// Remove elements added to body element.
host1.remove();
input.remove();
// Tests expect body.firstChild to have focus.
document.body.firstChild.focus();
}
// Bug 1558393
function testBackwardsTabbingWithSlotsWithoutFocusableContent() {
let first = document.createElement("div");
first.tabIndex = 0;
let host = document.createElement("div");
host.tabIndex = 0;
let second = document.createElement("div");
second.tabIndex = 0;
host.appendChild(document.createTextNode("foo"));
host.attachShadow({ mode: "open" }).innerHTML = `<slot></slot>`;
document.body.appendChild(first);
document.body.appendChild(host);
document.body.appendChild(second);
document.body.offsetLeft;
first.focus();
opener.is(document.activeElement, first, "First light div should have focus");
synthesizeKey("KEY_Tab");
opener.is(document.activeElement, host, "Host should be focused");
synthesizeKey("KEY_Tab");
opener.is(document.activeElement, second, "Second light div should be focused");
// Now backwards
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(document.activeElement, host, "Focus should return to host");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(document.activeElement, first, "Focus should return to first light div");
second.remove();
host.remove();
first.remove();
}
function runTest() {
testTabbingThroughShadowDOMWithTabIndexes();
testTabbingThroughSimpleShadowDOM();
testTabbingThroughNestedShadowDOM();
testTabbingThroughDisplayContentsHost();
testTabbingThroughLightDOMShadowDOMLightDOM();
testFocusableHost();
testShiftTabbingThroughFocusableHost();
testTabbingThroughNestedSlot();
testTabbingThroughSlotInLightDOM();
testTabbingThroughFocusableSlotInLightDOM();
testTabbingThroughScrollableShadowDOM();
testDeeplyNestedShadowTree();
testBackwardsTabbingWithSlotsWithoutFocusableContent();
opener.didRunTests();
window.close();
}
function init() {
SimpleTest.waitForFocus(runTest);
}
</script>
<style>
</style>
<template id="template">
<div style="overflow: hidden">
<p tabindex="0" id="p1">component</p>
<p tabindex="0" id="p2">/component</p>
</div>
</template>
</head>
<body onload="init()">
</body>
</html>
+5
View File
@@ -129,6 +129,7 @@ support-files =
file_bug1263696_frame_pass.html
file_bug1263696_frame_fail.html
file_bug1274806.html
file_bug1453693.html
file_general_document.html
file_htmlserializer_1.html
file_htmlserializer_1_bodyonly.html
@@ -609,6 +610,8 @@ skip-if = toolkit == 'android'
[test_bug1308069.html]
[test_bug1314032.html]
[test_bug1375050.html]
[test_bug1453693.html]
skip-if = os == "mac" # Different tab focus behavior on mac
[test_caretPositionFromPoint.html]
[test_change_policy.html]
[test_classList.html]
@@ -648,6 +651,8 @@ skip-if = toolkit == 'android' #bug 904183
[test_fileapi.html]
[test_fileapi_slice.html]
skip-if = (toolkit == 'android') # Android: Bug 775227
[test_focus_shadow_dom_root.html]
skip-if = os == "mac" # Different tab focus behavior on mac
[test_getAttribute_after_createAttribute.html]
[test_getElementById.html]
[test_getTranslationNodes.html]
+32
View File
@@ -0,0 +1,32 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1453693
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1453693</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
/** Test for Bug 1453693 **/
SimpleTest.waitForExplicitFinish();
function runTests() {
win = window.open("file_bug1453693.html", "", "width=300, height=300");
}
function didRunTests() {
setTimeout("SimpleTest.finish()");
}
;
</script>
</head>
<body onload="SimpleTest.waitForFocus(runTests);">
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1453693">Mozilla Bug 1453693</a>
</body>
</html>
@@ -0,0 +1,36 @@
<!doctype html>
<title>Test for bug 1544826</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<div id="host"><a href="#" id="slotted">This is focusable too</a></div>
<script>
const host = document.getElementById("host");
const shadow = host.attachShadow({ mode: "open" });
shadow.innerHTML = `
<a id="shadow-1" href="#">This is focusable</a>
<slot></slot>
<a id="shadow-2" href="#">So is this</a>
`;
document.documentElement.remove();
document.appendChild(host);
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(function() {
is(document.documentElement, host, "Host is the document element");
host.offsetTop;
synthesizeKey("KEY_Tab");
is(shadow.activeElement.id, "shadow-1", "First link in Shadow DOM is focused");
synthesizeKey("KEY_Tab");
is(document.activeElement.id, "slotted", "Slotted link is focused");
synthesizeKey("KEY_Tab");
is(shadow.activeElement.id, "shadow-2", "Second link in Shadow DOM is focused");
// Now backwards.
synthesizeKey("KEY_Tab", {shiftKey: true});
is(document.activeElement.id, "slotted", "Backwards: Slotted link is focused");
synthesizeKey("KEY_Tab", {shiftKey: true});
is(shadow.activeElement.id, "shadow-1", "Backwards: First slotted link is focused");
SimpleTest.finish();
});
</script>
+18 -13
View File
@@ -2106,16 +2106,19 @@ DictionaryBase::AppendJSONToString(const char16_t* aJSONData,
return true;
}
nsresult
ReparentWrapper(JSContext* aCx, JS::Handle<JSObject*> aObjArg)
void
ReparentWrapper(JSContext* aCx, JS::Handle<JSObject*> aObjArg, ErrorResult& aError)
{
js::AssertSameCompartment(aCx, aObjArg);
aError.MightThrowJSException();
// Check if we're anywhere near the stack limit before we reach the
// transplanting code, since it has no good way to handle errors. This uses
// the untrusted script limit, which is not strictly necessary since no
// actual script should run.
JS_CHECK_RECURSION_CONSERVATIVE(aCx, return NS_ERROR_FAILURE);
// TODO: Make sure to retain 'onerror' if bug 1342439 lands.
JS_CHECK_RECURSION_CONSERVATIVE(aCx, aError.StealExceptionFromJSContext(aCx); return);
JS::Rooted<JSObject*> aObj(aCx, aObjArg);
const DOMJSClass* domClass = GetDOMClass(aObj);
@@ -2135,12 +2138,12 @@ ReparentWrapper(JSContext* aCx, JS::Handle<JSObject*> aObjArg)
JSCompartment* newCompartment = js::GetObjectCompartment(newParent);
if (oldCompartment == newCompartment) {
MOZ_ASSERT(oldParent == newParent);
return NS_OK;
return;
}
nsISupports* native = UnwrapDOMObjectToISupports(aObj);
if (!native) {
return NS_OK;
return;
}
bool isProxy = js::IsProxy(aObj);
@@ -2156,12 +2159,14 @@ ReparentWrapper(JSContext* aCx, JS::Handle<JSObject*> aObjArg)
JS::Handle<JSObject*> proto = (domClass->mGetProto)(aCx);
if (!proto) {
return NS_ERROR_FAILURE;
aError.StealExceptionFromJSContext(aCx);
return;
}
JS::Rooted<JSObject*> newobj(aCx, JS_CloneObject(aCx, aObj, proto));
if (!newobj) {
return NS_ERROR_FAILURE;
aError.StealExceptionFromJSContext(aCx);
return;
}
JS::Rooted<JSObject*> propertyHolder(aCx);
@@ -2169,11 +2174,13 @@ ReparentWrapper(JSContext* aCx, JS::Handle<JSObject*> aObjArg)
if (copyFrom) {
propertyHolder = JS_NewObjectWithGivenProto(aCx, nullptr, nullptr);
if (!propertyHolder) {
return NS_ERROR_OUT_OF_MEMORY;
aError.StealExceptionFromJSContext(aCx);
return;
}
if (!JS_CopyPropertiesFrom(aCx, propertyHolder, copyFrom)) {
return NS_ERROR_FAILURE;
aError.StealExceptionFromJSContext(aCx);
return;
}
} else {
propertyHolder = nullptr;
@@ -2189,7 +2196,8 @@ ReparentWrapper(JSContext* aCx, JS::Handle<JSObject*> aObjArg)
// if expandos are present then the wrapper will already have been preserved
// for this native.
if (!xpc::XrayUtils::CloneExpandoChain(aCx, newobj, aObj)) {
return NS_ERROR_FAILURE;
aError.StealExceptionFromJSContext(aCx);
return;
}
// We've set up |newobj|, so we make it own the native by setting its reserved
@@ -2244,9 +2252,6 @@ ReparentWrapper(JSContext* aCx, JS::Handle<JSObject*> aObjArg)
if (htmlobject) {
htmlobject->SetupProtoChain(aCx, aObj);
}
// Now we can just return the wrapper
return NS_OK;
}
GlobalObject::GlobalObject(JSContext* aCx, JSObject* aObject)
+2 -2
View File
@@ -2758,8 +2758,8 @@ const nsAString& NonNullHelper(const binding_detail::FakeString& aArg)
// Reparent the wrapper of aObj to whatever its native now thinks its
// parent should be.
nsresult
ReparentWrapper(JSContext* aCx, JS::Handle<JSObject*> aObj);
void
ReparentWrapper(JSContext* aCx, JS::Handle<JSObject*> aObj, ErrorResult& aError);
/**
* Used to implement the Symbol.hasInstance property of an interface object.
+1 -1
View File
@@ -1770,7 +1770,7 @@ Manager::~Manager()
// Don't spin the event loop in the destructor waiting for the thread to
// shutdown. Defer this to the main thread, instead.
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(NewRunnableMethod(ioThread, &nsIThread::Shutdown)));
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(NewRunnableMethod(ioThread, &nsIThread::AsyncShutdown)));
}
void
+5 -1
View File
@@ -3758,7 +3758,11 @@ CanvasRenderingContext2D::SetFontInternal(const nsAString& aFont,
nsCOMPtr<nsIPresShell> presShell = GetPresShell();
if (!presShell) {
aError.Throw(NS_ERROR_FAILURE);
// Do not throw here. We may be in a situation where we're loading in an iframe
// that is sandboxed, and/or initially hidden with display:none, in which case
// we don't want to throw an error but silently fail.
// If we don't do this, JS trying to set context.font to something will abort,
// breaking e.g. third party serviced graphs.
return false;
}
+17 -20
View File
@@ -6,37 +6,34 @@
#include "ImageBitmapColorUtils.h"
#include "js/LegacyIntTypes.h"
#include <cmath>
namespace mozilla {
namespace dom {
/*
* Utility function form libyuv source files.
*/
static __inline int32 clamp0(int32 v) {
static __inline int32_t clamp0(int32_t v) {
return ((-(v) >> 31) & (v));
}
static __inline int32 clamp255(int32 v) {
static __inline int32_t clamp255(int32_t v) {
return (((255 - (v)) >> 31) | (v)) & 255;
}
static __inline uint32 Clamp(int32 val) {
static __inline uint32_t Clamp(int32_t val) {
int v = clamp0(val);
return (uint32)(clamp255(v));
return (uint32_t)(clamp255(v));
}
#define YG 74 /* (int8)(1.164 * 64 + 0.5) */
#define YG 74 /* (int8_t)(1.164 * 64 + 0.5) */
#define UB 127 /* min(63,(int8)(2.018 * 64)) */
#define UG -25 /* (int8)(-0.391 * 64 - 0.5) */
#define UB 127 /* min(63,(int8_t)(2.018 * 64)) */
#define UG -25 /* (int8_t)(-0.391 * 64 - 0.5) */
#define UR 0
#define VB 0
#define VG -52 /* (int8)(-0.813 * 64 - 0.5) */
#define VR 102 /* (int8)(1.596 * 64 + 0.5) */
#define VG -52 /* (int8_t)(-0.813 * 64 - 0.5) */
#define VR 102 /* (int8_t)(1.596 * 64 + 0.5) */
// Bias
#define BB UB * 128 + VB * 128
@@ -44,28 +41,28 @@ static __inline uint32 Clamp(int32 val) {
#define BR UR * 128 + VR * 128
static __inline void
YuvPixel(uint8 y, uint8 u, uint8 v, uint8* b, uint8* g, uint8* r)
YuvPixel(uint8_t y, uint8_t u, uint8_t v, uint8_t* b, uint8_t* g, uint8_t* r)
{
int32 y1 = ((int32)(y) - 16) * YG;
*b = Clamp((int32)((u * UB + v * VB) - (BB) + y1) >> 6);
*g = Clamp((int32)((u * UG + v * VG) - (BG) + y1) >> 6);
*r = Clamp((int32)((u * UR + v * VR) - (BR) + y1) >> 6);
int32_t y1 = ((int32_t)(y) - 16) * YG;
*b = Clamp((int32_t)((u * UB + v * VB) - (BB) + y1) >> 6);
*g = Clamp((int32_t)((u * UG + v * VG) - (BG) + y1) >> 6);
*r = Clamp((int32_t)((u * UR + v * VR) - (BR) + y1) >> 6);
}
static __inline int
RGBToY(uint8 r, uint8 g, uint8 b)
RGBToY(uint8_t r, uint8_t g, uint8_t b)
{
return (66 * r + 129 * g + 25 * b + 0x1080) >> 8;
}
static __inline int
RGBToU(uint8 r, uint8 g, uint8 b)
RGBToU(uint8_t r, uint8_t g, uint8_t b)
{
return (112 * b - 74 * g - 38 * r + 0x8080) >> 8;
}
static __inline int
RGBToV(uint8 r, uint8 g, uint8 b)
RGBToV(uint8_t r, uint8_t g, uint8_t b)
{
return (112 * r - 94 * g - 18 * b + 0x8080) >> 8;
}
+36 -14
View File
@@ -303,13 +303,13 @@ WebGLContext::FromDomElem(const char* funcName, TexImageTarget target, uint32_t
uint32_t height, uint32_t depth, const dom::Element& elem,
ErrorResult* const out_error)
{
if (elem.IsHTMLElement(nsGkAtoms::canvas)) {
const dom::HTMLCanvasElement* canvas = static_cast<const dom::HTMLCanvasElement*>(&elem);
if (canvas->IsWriteOnly()) {
out_error->Throw(NS_ERROR_DOM_SECURITY_ERR);
return nullptr;
}
}
if (elem.IsHTMLElement(nsGkAtoms::canvas)) {
const dom::HTMLCanvasElement* canvas = static_cast<const dom::HTMLCanvasElement*>(&elem);
if (canvas->IsWriteOnly()) {
out_error->Throw(NS_ERROR_DOM_SECURITY_ERR);
return nullptr;
}
}
uint32_t flags = nsLayoutUtils::SFE_WANT_IMAGE_SURFACE |
nsLayoutUtils::SFE_USE_ELEMENT_SIZE_IF_VECTOR;
@@ -1032,9 +1032,27 @@ ValidateCompressedTexImageRestrictions(const char* funcName, WebGLContext* webgl
}
static bool
ValidateTargetForFormat(const char* funcName, WebGLContext* webgl, TexImageTarget target,
const webgl::FormatInfo* format)
{
ValidateFormatAndSize(const char* funcName,
WebGLContext* webgl,
TexImageTarget target,
const webgl::FormatInfo* format,
const uint32_t width,
const uint32_t height,
const uint32_t depth) {
// Check if texture size will likely be rejected by the driver and give a more
// meaningful error message.
auto baseImageSize = CheckedInt<uint64_t>(format->estimatedBytesPerPixel) *
width * height * depth;
if (target == LOCAL_GL_TEXTURE_CUBE_MAP) {
baseImageSize *= 6;
}
if (!baseImageSize.isValid() ||
baseImageSize.value() > (uint64_t)gfxPrefs::WebGLMaxSizePerTextureMB * (1024 * 1024)) {
webgl->ErrorOutOfMemory("Texture size too large; base image MB > webgl.max-size-per-texture-mb");
return false;
}
// GLES 3.0.4 p127:
// "Textures with a base internal format of DEPTH_COMPONENT or DEPTH_STENCIL are
// supported by texture image specification commands only if `target` is TEXTURE_2D,
@@ -1137,7 +1155,8 @@ WebGLTexture::TexStorage(const char* funcName, TexTarget target, GLsizei levels,
}
auto dstFormat = dstUsage->format;
if (!ValidateTargetForFormat(funcName, mContext, testTarget, dstFormat))
if (!ValidateFormatAndSize(funcName, mContext, testTarget, dstFormat,
width, height, depth))
return;
if (dstFormat->compression) {
@@ -1264,7 +1283,8 @@ WebGLTexture::TexImage(const char* funcName, TexImageTarget target, GLint level,
// Check that source and dest info are compatible
auto dstFormat = dstUsage->format;
if (!ValidateTargetForFormat(funcName, mContext, target, dstFormat))
if (!ValidateFormatAndSize(funcName, mContext, target, dstFormat,
blob->mWidth, blob->mHeight, blob->mDepth))
return;
if (!mContext->IsWebGL2() && dstFormat->d) {
@@ -1484,7 +1504,8 @@ WebGLTexture::CompressedTexImage(const char* funcName, TexImageTarget target, GL
return;
}
if (!ValidateTargetForFormat(funcName, mContext, target, format))
if (!ValidateFormatAndSize(funcName, mContext, target, format,
blob->mWidth, blob->mHeight, blob->mDepth))
return;
////////////////////////////////////
@@ -2143,7 +2164,8 @@ WebGLTexture::CopyTexImage2D(TexImageTarget target, GLint level, GLenum internal
return;
const auto& dstFormat = dstUsage->format;
if (!ValidateTargetForFormat(funcName, mContext, target, dstFormat))
if (!ValidateFormatAndSize(funcName, mContext, target, dstFormat,
width, height, depth))
return;
if (!mContext->IsWebGL2() && dstFormat->d) {
+2 -2
View File
@@ -41,7 +41,7 @@ EXPORTS.mozilla.dom += [
]
# Canvas 2D and common sources
SOURCES += [
UNIFIED_SOURCES += [
'CanvasImageCache.cpp',
'CanvasRenderingContext2D.cpp',
'CanvasRenderingContextHelper.cpp',
@@ -59,7 +59,7 @@ SOURCES += [
]
# WebGL Sources
SOURCES += [
UNIFIED_SOURCES += [
'TexUnpackBlob.cpp',
'WebGL1Context.cpp',
'WebGL1ContextUniforms.cpp',
View File
File mode changed.
View File
File mode changed.
+8
View File
@@ -1741,6 +1741,10 @@ private:
return NS_ERROR_DOM_SYNTAX_ERR;
}
if (pubKey->keyType != rsaKey) {
return NS_ERROR_DOM_DATA_ERR;
}
// Extract relevant information from the public key
mModulusLength = 8 * pubKey->u.rsa.modulus.len;
if (!mPublicExponent.Assign(&pubKey->u.rsa.publicExponent)) {
@@ -1874,6 +1878,10 @@ private:
}
if (mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_SPKI)) {
if (pubKey->keyType != ecKey) {
return NS_ERROR_DOM_DATA_ERR;
}
if (!CheckEncodedECParameters(&pubKey->u.ec.DEREncodedParams)) {
return NS_ERROR_DOM_OPERATION_ERR;
}
+5 -31
View File
@@ -116,10 +116,9 @@ ContentEventHandler::InitBasic()
// If text frame which has overflowing selection underline is dirty,
// we need to flush the pending reflow here.
mPresShell->FlushPendingNotifications(Flush_Layout);
// Flushing notifications can cause mPresShell to be destroyed (bug 577963).
NS_ENSURE_TRUE(!mPresShell->IsDestroying(), NS_ERROR_FAILURE);
if (nsIDocument* doc = mPresShell->GetDocument()) {
doc->FlushPendingNotifications(Flush_Layout);
}
return NS_OK;
}
@@ -170,11 +169,11 @@ ContentEventHandler::InitRootContent(Selection* aNormalSelection)
}
// See bug 537041 comment 5, the range could have removed node.
if (NS_WARN_IF(startNode->GetUncomposedDoc() != mPresShell->GetDocument())) {
if (NS_WARN_IF(startNode->GetComposedDoc() != mPresShell->GetDocument())) {
return NS_ERROR_FAILURE;
}
NS_ASSERTION(startNode->GetUncomposedDoc() == endNode->GetUncomposedDoc(),
NS_ASSERTION(startNode->GetComposedDoc() == endNode->GetComposedDoc(),
"firstNormalSelectionRange crosses the document boundary");
mRootContent = startNode->GetSelectionRootContent(mPresShell);
@@ -2882,31 +2881,6 @@ ContentEventHandler::AdjustCollapsedRangeMaybeIntoTextNode(nsRange* aRange)
return NS_OK;
}
nsresult
ContentEventHandler::GetStartFrameAndOffset(const nsRange* aRange,
nsIFrame*& aFrame,
int32_t& aOffsetInFrame)
{
MOZ_ASSERT(aRange);
aFrame = nullptr;
aOffsetInFrame = -1;
nsINode* node = aRange->GetStartParent();
if (NS_WARN_IF(!node) ||
NS_WARN_IF(!node->IsNodeOfType(nsINode::eCONTENT))) {
return NS_ERROR_FAILURE;
}
nsIContent* content = static_cast<nsIContent*>(node);
RefPtr<nsFrameSelection> fs = mPresShell->FrameSelection();
aFrame = fs->GetFrameForNodeOffset(content, aRange->StartOffset(),
fs->GetHint(), &aOffsetInFrame);
if (NS_WARN_IF(!aFrame)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult
ContentEventHandler::ConvertToRootRelativeOffset(nsIFrame* aFrame,
nsRect& aRect)
-4
View File
@@ -287,10 +287,6 @@ protected:
// If the aRange isn't in text node but next to a text node, this method
// modifies it in the text node. Otherwise, not modified.
nsresult AdjustCollapsedRangeMaybeIntoTextNode(nsRange* aCollapsedRange);
// Find the first frame for the range and get the start offset in it.
nsresult GetStartFrameAndOffset(const nsRange* aRange,
nsIFrame*& aFrame,
int32_t& aOffsetInFrame);
// Convert the frame relative offset to be relative to the root frame of the
// root presContext (but still measured in appUnits of aFrame's presContext).
nsresult ConvertToRootRelativeOffset(nsIFrame* aFrame,
+27 -38
View File
@@ -148,6 +148,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Event)
tmp->mEvent->mCurrentTarget = nullptr;
tmp->mEvent->mOriginalTarget = nullptr;
tmp->mEvent->mRelatedTarget = nullptr;
tmp->mEvent->mOriginalRelatedTarget = nullptr;
switch (tmp->mEvent->mClass) {
case eDragEventClass: {
WidgetDragEvent* dragEvent = tmp->mEvent->AsDragEvent();
@@ -176,6 +177,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Event)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEvent->mCurrentTarget)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEvent->mOriginalTarget)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEvent->mRelatedTarget)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEvent->mOriginalRelatedTarget)
switch (tmp->mEvent->mClass) {
case eDragEventClass: {
WidgetDragEvent* dragEvent = tmp->mEvent->AsDragEvent();
@@ -194,6 +196,11 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Event)
default:
break;
}
if (WidgetMouseEvent* mouseEvent = tmp->mEvent->AsMouseEvent()) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mEvent->mClickTarget");
cb.NoteXPCOMChild(mouseEvent->mClickTarget);
}
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPresContext)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mExplicitOriginalTarget)
@@ -550,6 +557,26 @@ Event::SetEventType(const nsAString& aEventTypeArg)
mEvent->SetDefaultComposedInNativeAnonymousContent();
}
already_AddRefed<EventTarget>
Event::EnsureWebAccessibleRelatedTarget(EventTarget* aRelatedTarget)
{
nsCOMPtr<EventTarget> relatedTarget = aRelatedTarget;
if (relatedTarget) {
nsCOMPtr<nsIContent> content = do_QueryInterface(relatedTarget);
if (content && content->ChromeOnlyAccess() &&
!nsContentUtils::CanAccessNativeAnon()) {
content = content->FindFirstNonChromeOnlyAccessContent();
relatedTarget = do_QueryInterface(content);
}
if (relatedTarget) {
relatedTarget = relatedTarget->GetTargetForDOMEvent();
}
}
return relatedTarget.forget();
}
void
Event::InitEvent(const nsAString& aEventTypeArg,
bool aCanBubbleArg,
@@ -1222,44 +1249,6 @@ Event::SetOwner(EventTarget* aOwner)
#endif
}
// static
nsIContent*
Event::GetShadowRelatedTarget(nsIContent* aCurrentTarget,
nsIContent* aRelatedTarget)
{
if (!aCurrentTarget || !aRelatedTarget) {
return nullptr;
}
// Walk up the ancestor node trees of the related target until
// we encounter the node tree of the current target in order
// to find the adjusted related target. Walking up the tree may
// not find a common ancestor node tree if the related target is in
// an ancestor tree, but in that case it does not need to be adjusted.
ShadowRoot* currentTargetShadow = aCurrentTarget->GetContainingShadow();
if (!currentTargetShadow) {
return nullptr;
}
nsIContent* relatedTarget = aCurrentTarget;
while (relatedTarget) {
ShadowRoot* ancestorShadow = relatedTarget->GetContainingShadow();
if (currentTargetShadow == ancestorShadow) {
return relatedTarget;
}
// Didn't find the ancestor tree, thus related target does not have to
// adjusted.
if (!ancestorShadow) {
return nullptr;
}
relatedTarget = ancestorShadow->GetHost();
}
return nullptr;
}
NS_IMETHODIMP
Event::GetCancelBubble(bool* aCancelBubble)
{
+3 -8
View File
@@ -251,14 +251,6 @@ public:
return mIsMainThreadEvent;
}
/**
* For a given current target, returns the related target adjusted with
* shadow DOM retargeting rules. Returns nullptr if related target
* is not adjusted.
*/
static nsIContent* GetShadowRelatedTarget(nsIContent* aCurrentTarget,
nsIContent* aRelatedTarget);
void MarkUninitialized()
{
mEvent->mMessage = eVoidEvent;
@@ -295,6 +287,9 @@ protected:
mEvent->SetComposed(aComposed);
}
already_AddRefed<EventTarget>
EnsureWebAccessibleRelatedTarget(EventTarget* aRelatedTarget);
mozilla::WidgetEvent* mEvent;
RefPtr<nsPresContext> mPresContext;
nsCOMPtr<EventTarget> mExplicitOriginalTarget;
+77 -4
View File
@@ -204,6 +204,16 @@ public:
mNewTarget = aNewTarget;
}
EventTarget* GetRetargetedRelatedTarget()
{
return mRetargetedRelatedTarget;
}
void SetRetargetedRelatedTarget(EventTarget* aTarget)
{
mRetargetedRelatedTarget = aTarget;
}
void SetForceContentDispatch(bool aForce)
{
mFlags.mForceContentDispatch = aForce;
@@ -354,6 +364,7 @@ public:
private:
nsCOMPtr<EventTarget> mTarget;
nsCOMPtr<EventTarget> mRetargetedRelatedTarget;
class EventTargetChainFlags
{
@@ -422,6 +433,7 @@ EventTargetChainItem::GetEventTargetParent(EventChainPreVisitor& aVisitor)
SetWantsPreHandleEvent(aVisitor.mWantsPreHandleEvent);
SetPreHandleEventOnly(aVisitor.mWantsPreHandleEvent && !aVisitor.mCanHandle);
SetRootOfClosedTree(aVisitor.mRootOfClosedTree);
SetRetargetedRelatedTarget(aVisitor.mRetargetedRelatedTarget);
mItemFlags = aVisitor.mItemFlags;
mItemData = aVisitor.mItemData;
}
@@ -454,6 +466,7 @@ EventTargetChainItem::HandleEventTargetChain(
{
// Save the target so that it can be restored later.
nsCOMPtr<EventTarget> firstTarget = aVisitor.mEvent->mTarget;
nsCOMPtr<EventTarget> firstRelatedTarget = aVisitor.mEvent->mRelatedTarget;
uint32_t chainLength = aChain.Length();
uint32_t firstCanHandleEventTargetIdx =
EventTargetChainItem::GetFirstCanHandleEventTargetIdx(aChain);
@@ -483,6 +496,30 @@ EventTargetChainItem::HandleEventTargetChain(
}
}
}
// https://dom.spec.whatwg.org/#dispatching-events
// Step 14.2
// "Set event's relatedTarget to tuple's relatedTarget."
// Note, the initial retargeting was done already when creating
// event target chain, so we need to do this only after calling
// HandleEvent, not before, like in the specification.
if (item.GetRetargetedRelatedTarget()) {
bool found = false;
for (uint32_t j = i; j > 0; --j) {
uint32_t childIndex = j - 1;
EventTarget* relatedTarget =
aChain[childIndex].GetRetargetedRelatedTarget();
if (relatedTarget) {
found = true;
aVisitor.mEvent->mRelatedTarget = relatedTarget;
break;
}
}
if (!found) {
aVisitor.mEvent->mRelatedTarget =
aVisitor.mEvent->mOriginalRelatedTarget;
}
}
}
// Target
@@ -511,6 +548,14 @@ EventTargetChainItem::HandleEventTargetChain(
aVisitor.mEvent->mTarget = newTarget;
}
// https://dom.spec.whatwg.org/#dispatching-events
// Step 15.2
// "Set event's relatedTarget to tuple's relatedTarget."
EventTarget* relatedTarget = item.GetRetargetedRelatedTarget();
if (relatedTarget) {
aVisitor.mEvent->mRelatedTarget = relatedTarget;
}
if (aVisitor.mEvent->mFlags.mBubbles || newTarget) {
if ((!aVisitor.mEvent->mFlags.mNoContentDispatch ||
item.ForceContentDispatch()) &&
@@ -542,6 +587,7 @@ EventTargetChainItem::HandleEventTargetChain(
// Retarget for system event group (which does the default handling too).
// Setting back the target which was used also for default event group.
aVisitor.mEvent->mTarget = firstTarget;
aVisitor.mEvent->mRelatedTarget = aVisitor.mEvent->mOriginalRelatedTarget;
aVisitor.mEvent->mFlags.mInSystemGroup = true;
HandleEventTargetChain(aChain,
aVisitor,
@@ -599,6 +645,7 @@ MayRetargetToChromeIfCanNotHandleEvent(
EventTargetChainItem::DestroyLast(aChain, aTargetEtci);
}
if (aPreVisitor.mAutomaticChromeDispatch && aContent) {
aPreVisitor.mRelatedTargetRetargetedInCurrentScope = false;
// Event target couldn't handle the event. Try to propagate to chrome.
EventTargetChainItem* chromeTargetEtci =
EventTargetChainItemForChromeTarget(aChain, aContent, aChildEtci);
@@ -762,9 +809,10 @@ EventDispatcher::Dispatch(nsISupports* aTarget,
aEvent->mOriginalTarget = aEvent->mTarget;
}
aEvent->mOriginalRelatedTarget = aEvent->mRelatedTarget;
nsCOMPtr<nsIContent> content = do_QueryInterface(aEvent->mOriginalTarget);
bool isInAnon = (content && (content->IsInAnonymousSubtree() ||
content->IsInShadowTree()));
bool isInAnon = (content && content->IsInAnonymousSubtree());
aEvent->mFlags.mIsBeingDispatched = true;
@@ -772,7 +820,7 @@ EventDispatcher::Dispatch(nsISupports* aTarget,
// GetEventTargetParent for the original target.
nsEventStatus status = aEventStatus ? *aEventStatus : nsEventStatus_eIgnore;
EventChainPreVisitor preVisitor(aPresContext, aEvent, aDOMEvent, status,
isInAnon);
isInAnon, aEvent->mTarget);
targetEtci->GetEventTargetParent(preVisitor);
if (!preVisitor.mCanHandle) {
@@ -810,14 +858,21 @@ EventDispatcher::Dispatch(nsISupports* aTarget,
if (preVisitor.mEventTargetAtParent) {
// Need to set the target of the event
// so that also the next retargeting works.
preVisitor.mTargetInKnownToBeHandledScope = preVisitor.mEvent->mTarget;
preVisitor.mEvent->mTarget = preVisitor.mEventTargetAtParent;
parentEtci->SetNewTarget(preVisitor.mEventTargetAtParent);
}
if (preVisitor.mRetargetedRelatedTarget) {
preVisitor.mEvent->mRelatedTarget = preVisitor.mRetargetedRelatedTarget;
}
parentEtci->GetEventTargetParent(preVisitor);
if (preVisitor.mCanHandle) {
preVisitor.mTargetInKnownToBeHandledScope = preVisitor.mEvent->mTarget;
topEtci = parentEtci;
} else {
bool ignoreBecauseOfShadowDOM = preVisitor.mIgnoreBecauseOfShadowDOM;
nsCOMPtr<nsINode> disabledTarget = do_QueryInterface(parentTarget);
parentEtci = MayRetargetToChromeIfCanNotHandleEvent(chain,
preVisitor,
@@ -825,9 +880,14 @@ EventDispatcher::Dispatch(nsISupports* aTarget,
topEtci,
disabledTarget);
if (parentEtci && preVisitor.mCanHandle) {
preVisitor.mTargetInKnownToBeHandledScope = preVisitor.mEvent->mTarget;
EventTargetChainItem* item =
EventTargetChainItem::GetFirstCanHandleEventTarget(chain);
item->SetNewTarget(parentTarget);
if (!ignoreBecauseOfShadowDOM) {
// If we ignored the target because of Shadow DOM retargeting, we
// shouldn't treat the target to be in the event path at all.
item->SetNewTarget(parentTarget);
}
topEtci = parentEtci;
continue;
}
@@ -871,6 +931,19 @@ EventDispatcher::Dispatch(nsISupports* aTarget,
aEvent->mFlags.mIsBeingDispatched = false;
aEvent->mFlags.mDispatchedAtLeastOnce = true;
// https://dom.spec.whatwg.org/#concept-event-dispatch
// Step 18
// "If target's root is a shadow root, then set event's target attribute and
// event's relatedTarget to null."
nsCOMPtr<nsIContent> finalTarget = do_QueryInterface(aEvent->mTarget);
// TODO: replace with IsShadowRoot() check once bug 1427511 lands.
if (finalTarget && ShadowRoot::FromNode(finalTarget->SubtreeRoot())) {
aEvent->mTarget = nullptr;
aEvent->mOriginalTarget = nullptr;
aEvent->mRelatedTarget = nullptr;
aEvent->mOriginalRelatedTarget = nullptr;
}
if (!externalDOMEvent && preVisitor.mDOMEvent) {
// An dom::Event was created while dispatching the event.
// Duplicate private data if someone holds a pointer to it.
+45 -1
View File
@@ -113,7 +113,8 @@ public:
WidgetEvent* aEvent,
nsIDOMEvent* aDOMEvent,
nsEventStatus aEventStatus,
bool aIsInAnon)
bool aIsInAnon,
dom::EventTarget* aTargetInKnownToBeHandledScope)
: EventChainVisitor(aPresContext, aEvent, aDOMEvent, aEventStatus)
, mCanHandle(true)
, mAutomaticChromeDispatch(true)
@@ -126,8 +127,12 @@ public:
, mRootOfClosedTree(false)
, mParentIsSlotInClosedTree(false)
, mParentIsChromeHandler(false)
, mRelatedTargetRetargetedInCurrentScope(false)
, mIgnoreBecauseOfShadowDOM(false)
, mParentTarget(nullptr)
, mEventTargetAtParent(nullptr)
, mRetargetedRelatedTarget(nullptr)
, mTargetInKnownToBeHandledScope(aTargetInKnownToBeHandledScope)
{
}
@@ -144,8 +149,13 @@ public:
mRootOfClosedTree = false;
mParentIsSlotInClosedTree = false;
mParentIsChromeHandler = false;
// Note, we don't clear mRelatedTargetRetargetedInCurrentScope explicitly,
// since it is used during event path creation to indicate whether
// relatedTarget may need to be retargeted.
mIgnoreBecauseOfShadowDOM = false;
mParentTarget = nullptr;
mEventTargetAtParent = nullptr;
mRetargetedRelatedTarget = nullptr;
}
dom::EventTarget* GetParentTarget()
@@ -161,6 +171,14 @@ public:
}
}
void IgnoreCurrentTargetBecauseOfShadowDOMRetargeting()
{
mCanHandle = false;
mIgnoreBecauseOfShadowDOM = true;
SetParentTarget(nullptr, false);
mEventTargetAtParent = nullptr;
}
/**
* Member that must be set in GetEventTargetParent by event targets. If set to
* false, indicates that this event target will not be handling the event and
@@ -229,6 +247,19 @@ public:
*/
bool mParentIsChromeHandler;
/**
* True if event's related target has been already retargeted in the
* current 'scope'. This should be set to false initially and whenever
* event path creation crosses shadow boundary.
*/
bool mRelatedTargetRetargetedInCurrentScope;
/**
* True if Shadow DOM relatedTarget retargeting causes the current item
* to not show up in the event path.
*/
bool mIgnoreBecauseOfShadowDOM;
private:
/**
* Parent item in the event target chain.
@@ -241,6 +272,19 @@ public:
* which should be used when the event is handled at mParentTarget.
*/
dom::EventTarget* mEventTargetAtParent;
/**
* If the related target of the event needs to be retargeted, set this
* to a new EventTarget.
*/
dom::EventTarget* mRetargetedRelatedTarget;
/**
* Set to the value of mEvent->mTarget of the previous scope in case of
* Shadow DOM or such, and if there is no anonymous content this just points
* to the initial target.
*/
dom::EventTarget* mTargetInKnownToBeHandledScope;
};
class EventChainPostVisitor : public mozilla::EventChainVisitor
+155 -105
View File
@@ -432,11 +432,8 @@ NS_IMPL_CYCLE_COLLECTION(EventStateManager,
mGestureDownContent,
mGestureDownFrameOwner,
mLastLeftMouseDownContent,
mLastLeftMouseDownContentParent,
mLastMiddleMouseDownContent,
mLastMiddleMouseDownContentParent,
mLastRightMouseDownContent,
mLastRightMouseDownContentParent,
mActiveContent,
mHoverContent,
mURLTargetContent,
@@ -3171,14 +3168,11 @@ EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
case eMouseUp:
{
ClearGlobalActiveContent(this);
WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
if (mouseEvent && mouseEvent->IsReal()) {
if (!mCurrentTarget) {
GetEventTarget();
}
WidgetMouseEvent* mouseUpEvent = aEvent->AsMouseEvent();
if (mouseUpEvent && EventCausesClickEvents(*mouseUpEvent)) {
// Make sure to dispatch the click even if there is no frame for
// the current target element. This is required for Web compatibility.
ret = CheckForAndDispatchClick(mouseEvent, aStatus);
ret = PostHandleMouseUp(mouseUpEvent, aStatus);
}
nsIPresShell *shell = presContext->GetPresShell();
@@ -4573,16 +4567,13 @@ EventStateManager::SetClickCount(WidgetMouseEvent* aEvent,
nsEventStatus* aStatus)
{
nsCOMPtr<nsIContent> mouseContent;
nsIContent* mouseContentParent = nullptr;
if (mCurrentTarget) {
mCurrentTarget->GetContentForEvent(aEvent, getter_AddRefs(mouseContent));
}
if (mouseContent) {
if (mouseContent->IsNodeOfType(nsINode::eTEXT)) {
mouseContent = mouseContent->GetParent();
}
if (mouseContent && mouseContent->IsRootOfNativeAnonymousSubtree()) {
mouseContentParent = mouseContent->GetParent();
if (mouseContent && mouseContent->IsNodeOfType(nsINode::eTEXT)) {
nsINode* parent = mouseContent->GetFlattenedTreeParentNode();
if (parent && parent->IsContent()) {
mouseContent = parent->AsContent();
}
}
@@ -4590,54 +4581,51 @@ EventStateManager::SetClickCount(WidgetMouseEvent* aEvent,
case WidgetMouseEvent::eLeftButton:
if (aEvent->mMessage == eMouseDown) {
mLastLeftMouseDownContent = mouseContent;
mLastLeftMouseDownContentParent = mouseContentParent;
} else if (aEvent->mMessage == eMouseUp) {
if (mLastLeftMouseDownContent == mouseContent ||
mLastLeftMouseDownContentParent == mouseContent ||
mLastLeftMouseDownContent == mouseContentParent) {
aEvent->mClickTarget =
nsContentUtils::GetCommonAncestorUnderInteractiveContent(
mouseContent, mLastLeftMouseDownContent);
if (aEvent->mClickTarget) {
aEvent->mClickCount = mLClickCount;
mLClickCount = 0;
} else {
aEvent->mClickCount = 0;
}
mLastLeftMouseDownContent = nullptr;
mLastLeftMouseDownContentParent = nullptr;
}
break;
case WidgetMouseEvent::eMiddleButton:
if (aEvent->mMessage == eMouseDown) {
mLastMiddleMouseDownContent = mouseContent;
mLastMiddleMouseDownContentParent = mouseContentParent;
} else if (aEvent->mMessage == eMouseUp) {
if (mLastMiddleMouseDownContent == mouseContent ||
mLastMiddleMouseDownContentParent == mouseContent ||
mLastMiddleMouseDownContent == mouseContentParent) {
aEvent->mClickTarget =
nsContentUtils::GetCommonAncestorUnderInteractiveContent(
mouseContent, mLastMiddleMouseDownContent);
if (aEvent->mClickTarget) {
aEvent->mClickCount = mMClickCount;
mMClickCount = 0;
} else {
aEvent->mClickCount = 0;
}
mLastMiddleMouseDownContent = nullptr;
mLastMiddleMouseDownContentParent = nullptr;
}
break;
case WidgetMouseEvent::eRightButton:
if (aEvent->mMessage == eMouseDown) {
mLastRightMouseDownContent = mouseContent;
mLastRightMouseDownContentParent = mouseContentParent;
} else if (aEvent->mMessage == eMouseUp) {
if (mLastRightMouseDownContent == mouseContent ||
mLastRightMouseDownContentParent == mouseContent ||
mLastRightMouseDownContent == mouseContentParent) {
aEvent->mClickTarget =
nsContentUtils::GetCommonAncestorUnderInteractiveContent(
mouseContent, mLastRightMouseDownContent);
if (aEvent->mClickTarget) {
aEvent->mClickCount = mRClickCount;
mRClickCount = 0;
} else {
aEvent->mClickCount = 0;
}
mLastRightMouseDownContent = nullptr;
mLastRightMouseDownContentParent = nullptr;
}
break;
}
@@ -4645,89 +4633,151 @@ EventStateManager::SetClickCount(WidgetMouseEvent* aEvent,
return NS_OK;
}
nsresult
EventStateManager::InitAndDispatchClickEvent(WidgetMouseEvent* aEvent,
nsEventStatus* aStatus,
EventMessage aMessage,
nsIPresShell* aPresShell,
nsIContent* aMouseTarget,
nsWeakFrame aCurrentTarget,
bool aNoContentDispatch)
// static
bool
EventStateManager::EventCausesClickEvents(const WidgetMouseEvent& aMouseEvent)
{
WidgetMouseEvent event(aEvent->IsTrusted(), aMessage,
aEvent->mWidget, WidgetMouseEvent::eReal);
event.mRefPoint = aEvent->mRefPoint;
event.mClickCount = aEvent->mClickCount;
event.mModifiers = aEvent->mModifiers;
event.buttons = aEvent->buttons;
event.mTime = aEvent->mTime;
event.mTimeStamp = aEvent->mTimeStamp;
event.mFlags.mNoContentDispatch = aNoContentDispatch;
event.button = aEvent->button;
event.inputSource = aEvent->inputSource;
return aPresShell->HandleEventWithTarget(&event, aCurrentTarget,
aMouseTarget, aStatus);
if (NS_WARN_IF(aMouseEvent.mMessage != eMouseUp)) {
return false;
}
// If the mouseup event is synthesized event, we don't need to dispatch
// click events.
if (!aMouseEvent.IsReal()) {
return false;
}
// If mouse is still over same element, clickcount will be > 1.
// If it has moved it will be zero, so no click.
if (!aMouseEvent.mClickCount || !aMouseEvent.mClickTarget) {
return false;
}
// Check that the window isn't disabled before firing a click
// (see bug 366544).
return !(aMouseEvent.mWidget && !aMouseEvent.mWidget->IsEnabled());
}
nsresult
EventStateManager::CheckForAndDispatchClick(WidgetMouseEvent* aEvent,
nsEventStatus* aStatus)
EventStateManager::InitAndDispatchClickEvent(WidgetMouseEvent* aMouseUpEvent,
nsEventStatus* aStatus,
EventMessage aMessage,
nsIPresShell* aPresShell,
nsIContent* aMouseUpContent,
nsWeakFrame aCurrentTarget,
bool aNoContentDispatch)
{
nsresult ret = NS_OK;
MOZ_ASSERT(aMouseUpEvent);
MOZ_ASSERT(EventCausesClickEvents(*aMouseUpEvent));
MOZ_ASSERT(aMouseUpContent || aCurrentTarget);
//If mouse is still over same element, clickcount will be > 1.
//If it has moved it will be zero, so no click.
if (aEvent->mClickCount) {
//Check that the window isn't disabled before firing a click
//(see bug 366544).
if (aEvent->mWidget && !aEvent->mWidget->IsEnabled()) {
WidgetMouseEvent event(aMouseUpEvent->IsTrusted(), aMessage,
aMouseUpEvent->mWidget, WidgetMouseEvent::eReal);
event.mRefPoint = aMouseUpEvent->mRefPoint;
event.mClickCount = aMouseUpEvent->mClickCount;
event.mModifiers = aMouseUpEvent->mModifiers;
event.buttons = aMouseUpEvent->buttons;
event.mTime = aMouseUpEvent->mTime;
event.mTimeStamp = aMouseUpEvent->mTimeStamp;
event.mFlags.mNoContentDispatch = aNoContentDispatch;
event.button = aMouseUpEvent->button;
event.inputSource = aMouseUpEvent->inputSource;
if (!aMouseUpContent->IsInComposedDoc()) {
return NS_OK;
}
// Use local event status for each click event dispatching since it'll be
// cleared by EventStateManager::PreHandleEvent(). Therefore, dispatching
// an event means that previous event status will be ignored.
nsEventStatus status = nsEventStatus_eIgnore;
nsresult rv = aPresShell->HandleEventWithTarget(&event, aCurrentTarget,
aMouseUpContent, &status);
// If current status is nsEventStatus_eConsumeNoDefault, we don't need to
// overwrite it.
if (*aStatus == nsEventStatus_eConsumeNoDefault) {
return rv;
}
// If new status is nsEventStatus_eConsumeNoDefault or
// nsEventStatus_eConsumeDoDefault, use it.
if (status == nsEventStatus_eConsumeNoDefault ||
status == nsEventStatus_eConsumeDoDefault) {
*aStatus = status;
return rv;
}
// Otherwise, keep the original status.
return rv;
}
nsresult
EventStateManager::PostHandleMouseUp(WidgetMouseEvent* aMouseUpEvent,
nsEventStatus* aStatus)
{
MOZ_ASSERT(aMouseUpEvent);
MOZ_ASSERT(EventCausesClickEvents(*aMouseUpEvent));
MOZ_ASSERT(aStatus);
nsCOMPtr<nsIPresShell> presShell = mPresContext->GetPresShell();
if (!presShell) {
return NS_OK;
}
nsCOMPtr<nsIContent> clickTarget = do_QueryInterface(aMouseUpEvent->mClickTarget);
NS_ENSURE_STATE(clickTarget);
// Fire click events if the event target is still available.
nsresult rv = DispatchClickEvents(presShell, aMouseUpEvent, aStatus,
clickTarget);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
nsresult
EventStateManager::DispatchClickEvents(nsIPresShell* aPresShell,
WidgetMouseEvent* aMouseUpEvent,
nsEventStatus* aStatus,
nsIContent* aClickTarget)
{
MOZ_ASSERT(aPresShell);
MOZ_ASSERT(aMouseUpEvent);
MOZ_ASSERT(EventCausesClickEvents(*aMouseUpEvent));
MOZ_ASSERT(aStatus);
MOZ_ASSERT(aClickTarget);
bool notDispatchToContents =
(aMouseUpEvent->button == WidgetMouseEvent::eMiddleButton ||
aMouseUpEvent->button == WidgetMouseEvent::eRightButton);
bool fireAuxClick = notDispatchToContents;
nsWeakFrame currentTarget = aClickTarget->GetPrimaryFrame();
nsresult ret =
InitAndDispatchClickEvent(aMouseUpEvent, aStatus, eMouseClick,
aPresShell, aClickTarget, currentTarget,
notDispatchToContents);
if (NS_WARN_IF(NS_FAILED(ret))) {
return ret;
}
// Fire double click event if click count is 2.
if (aMouseUpEvent->mClickCount == 2 &&
aClickTarget && aClickTarget->IsInComposedDoc()) {
ret = InitAndDispatchClickEvent(aMouseUpEvent, aStatus, eMouseDoubleClick,
aPresShell, aClickTarget, currentTarget,
notDispatchToContents);
if (NS_WARN_IF(NS_FAILED(ret))) {
return ret;
}
//fire click
bool notDispatchToContents =
(aEvent->button == WidgetMouseEvent::eMiddleButton ||
aEvent->button == WidgetMouseEvent::eRightButton);
bool fireAuxClick = notDispatchToContents;
nsCOMPtr<nsIPresShell> presShell = mPresContext->GetPresShell();
if (presShell) {
nsCOMPtr<nsIContent> mouseContent = GetEventTargetContent(aEvent);
// Click events apply to *elements* not nodes. At this point the target
// content may have been reset to some non-element content, and so we need
// to walk up the closest ancestor element, just like we do in
// nsPresShell::HandlePositionedEvent.
while (mouseContent && !mouseContent->IsElement()) {
mouseContent = mouseContent->GetParent();
}
if (!mouseContent && !mCurrentTarget) {
return NS_OK;
}
// HandleEvent clears out mCurrentTarget which we might need again
nsWeakFrame currentTarget = mCurrentTarget;
ret = InitAndDispatchClickEvent(aEvent, aStatus, eMouseClick,
presShell, mouseContent, currentTarget,
notDispatchToContents);
if (NS_SUCCEEDED(ret) && aEvent->mClickCount == 2 &&
mouseContent && mouseContent->IsInComposedDoc()) {
//fire double click
ret = InitAndDispatchClickEvent(aEvent, aStatus, eMouseDoubleClick,
presShell, mouseContent, currentTarget,
notDispatchToContents);
}
if (NS_SUCCEEDED(ret) && mouseContent && fireAuxClick &&
mouseContent->IsInComposedDoc()) {
ret = InitAndDispatchClickEvent(aEvent, aStatus, eMouseAuxClick,
presShell, mouseContent, currentTarget,
false);
}
}
}
// Fire auxclick even if necessary.
if (fireAuxClick &&
aClickTarget && aClickTarget->IsInComposedDoc()) {
ret = InitAndDispatchClickEvent(aMouseUpEvent, aStatus, eMouseAuxClick,
aPresShell, aClickTarget, currentTarget,
false);
NS_WARNING_ASSERTION(NS_SUCCEEDED(ret), "Failed to dispatch eMouseAuxClick");
}
return ret;
}
+67 -7
View File
@@ -414,16 +414,79 @@ protected:
*/
void UpdateDragDataTransfer(WidgetDragEvent* dragEvent);
static nsresult InitAndDispatchClickEvent(WidgetMouseEvent* aEvent,
/**
* InitAndDispatchClickEvent() dispatches a click event.
*
* @param aMouseUpEvent eMouseUp event which causes the click event.
* EventCausesClickEvents() must return true
* if this event is set to it.
* @param aStatus Returns the result of click event.
* If the status indicates consumed, the
* value won't be overwritten with
* nsEventStatus_eIgnore.
* @param aMessage Should be eMouseClick, eMouseDoubleClick or
* eMouseAuxClick.
* @param aPresShell The PresShell.
* @param aMouseUpContent The event target of aMouseUpEvent.
* @param aCurrentTarget Current target of the caller.
* @param aNoContentDispatch true if the event shouldn't be exposed to
* web contents (although will be fired on
* document and window).
* @param aOverrideClickTarget Preferred click event target. If this is
* not nullptr, aMouseUpContent and
* aCurrentTarget are ignored.
*/
static nsresult InitAndDispatchClickEvent(WidgetMouseEvent* aMouseUpEvent,
nsEventStatus* aStatus,
EventMessage aMessage,
nsIPresShell* aPresShell,
nsIContent* aMouseTarget,
nsIContent* aMouseUpContent,
nsWeakFrame aCurrentTarget,
bool aNoContentDispatch);
nsresult SetClickCount(WidgetMouseEvent* aEvent, nsEventStatus* aStatus);
nsresult CheckForAndDispatchClick(WidgetMouseEvent* aEvent,
nsEventStatus* aStatus);
/**
* EventCausesClickEvents() returns true when aMouseEvent is an eMouseUp
* event and it should cause eMouseClick, eMouseDoubleClick and/or
* eMouseAuxClick events. Note that this method assumes that
* aMouseEvent.mClickCount has already been initialized with SetClickCount().
*/
static bool EventCausesClickEvents(const WidgetMouseEvent& aMouseEvent);
/**
* PostHandleMouseUp() handles default actions of eMouseUp event.
*
* @param aMouseUpEvent eMouseUp event which causes the click event.
* EventCausesClickEvents() must return true
* if this event is set to it.
* @param aStatus Returns the result of event status.
* If one of dispatching event is consumed or
* this does something as default action,
* returns nsEventStatus_eConsumeNoDefault.
*/
nsresult PostHandleMouseUp(WidgetMouseEvent* aMouseUpEvent,
nsEventStatus* aStatus);
/**
* DispatchClickEvents() dispatches eMouseClick, eMouseDoubleClick and
* eMouseAuxClick events for aMouseUpEvent. aMouseUpEvent should cause
* click event.
*
* @param aPresShell The PresShell.
* @param aMouseUpEvent eMouseUp event which causes the click event.
* EventCausesClickEvents() must return true
* if this event is set to it.
* @param aStatus Returns the result of event status.
* If one of dispatching click event is
* consumed, returns
* nsEventStatus_eConsumeNoDefault.
* @param aMouseUpContent The event target of aMouseUpEvent.
*/
nsresult DispatchClickEvents(nsIPresShell* aPresShell,
WidgetMouseEvent* aMouseUpEvent,
nsEventStatus* aStatus,
nsIContent* aMouseUpContent);
void EnsureDocument(nsPresContext* aPresContext);
void FlushPendingEvents(nsPresContext* aPresContext);
@@ -951,11 +1014,8 @@ private:
uint16_t mGestureDownButtons;
nsCOMPtr<nsIContent> mLastLeftMouseDownContent;
nsCOMPtr<nsIContent> mLastLeftMouseDownContentParent;
nsCOMPtr<nsIContent> mLastMiddleMouseDownContent;
nsCOMPtr<nsIContent> mLastMiddleMouseDownContentParent;
nsCOMPtr<nsIContent> mLastRightMouseDownContent;
nsCOMPtr<nsIContent> mLastRightMouseDownContentParent;
nsCOMPtr<nsIContent> mActiveContent;
nsCOMPtr<nsIContent> mHoverContent;
+3 -3
View File
@@ -30,14 +30,14 @@ NS_IMETHODIMP
FocusEvent::GetRelatedTarget(nsIDOMEventTarget** aRelatedTarget)
{
NS_ENSURE_ARG_POINTER(aRelatedTarget);
NS_IF_ADDREF(*aRelatedTarget = GetRelatedTarget());
*aRelatedTarget = GetRelatedTarget().take();
return NS_OK;
}
EventTarget*
already_AddRefed<EventTarget>
FocusEvent::GetRelatedTarget()
{
return mEvent->AsFocusEvent()->mRelatedTarget;
return EnsureWebAccessibleRelatedTarget(mEvent->AsFocusEvent()->mRelatedTarget);
}
void
+1 -1
View File
@@ -32,7 +32,7 @@ public:
nsPresContext* aPresContext,
InternalFocusEvent* aEvent);
EventTarget* GetRelatedTarget();
already_AddRefed<EventTarget> GetRelatedTarget();
static already_AddRefed<FocusEvent> Constructor(const GlobalObject& aGlobal,
const nsAString& aType,
+1 -21
View File
@@ -300,27 +300,7 @@ MouseEvent::GetRelatedTarget()
break;
}
if (relatedTarget) {
nsCOMPtr<nsIContent> content = do_QueryInterface(relatedTarget);
nsCOMPtr<nsIContent> currentTarget =
do_QueryInterface(mEvent->mCurrentTarget);
nsIContent* shadowRelatedTarget = GetShadowRelatedTarget(currentTarget, content);
if (shadowRelatedTarget) {
relatedTarget = shadowRelatedTarget;
}
if (content && content->ChromeOnlyAccess() &&
!nsContentUtils::CanAccessNativeAnon()) {
relatedTarget = do_QueryInterface(content->FindFirstNonChromeOnlyAccessContent());
}
if (relatedTarget) {
relatedTarget = relatedTarget->GetTargetForDOMEvent();
}
return relatedTarget.forget();
}
return nullptr;
return EnsureWebAccessibleRelatedTarget(relatedTarget);
}
void
+17 -22
View File
@@ -228,26 +228,20 @@ UIEvent::GetWhich(uint32_t* aWhich)
already_AddRefed<nsINode>
UIEvent::GetRangeParent()
{
nsIFrame* targetFrame = nullptr;
if (mPresContext) {
targetFrame = mPresContext->EventStateManager()->GetEventTarget();
if (NS_WARN_IF(!mPresContext)) {
return nullptr;
}
if (targetFrame) {
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(mEvent,
targetFrame);
nsCOMPtr<nsIContent> parent = targetFrame->GetContentOffsetsFromPoint(pt).content;
if (parent) {
if (parent->ChromeOnlyAccess() &&
!nsContentUtils::CanAccessNativeAnon()) {
return nullptr;
}
return parent.forget();
}
nsCOMPtr<nsIPresShell> presShell = mPresContext->GetPresShell();
if (NS_WARN_IF(!presShell)) {
return nullptr;
}
return nullptr;
nsCOMPtr<nsIContent> container;
nsLayoutUtils::GetContainerAndOffsetAtEvent(presShell, mEvent,
getter_AddRefs(container),
nullptr);
return container.forget();
}
NS_IMETHODIMP
@@ -273,18 +267,19 @@ UIEvent::GetRangeOffset(int32_t* aRangeOffset)
int32_t
UIEvent::RangeOffset() const
{
if (!mPresContext) {
if (NS_WARN_IF(!mPresContext)) {
return 0;
}
nsIFrame* targetFrame = mPresContext->EventStateManager()->GetEventTarget();
if (!targetFrame) {
nsCOMPtr<nsIPresShell> presShell = mPresContext->GetPresShell();
if (NS_WARN_IF(!presShell)) {
return 0;
}
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(mEvent,
targetFrame);
return targetFrame->GetContentOffsetsFromPoint(pt).offset;
int32_t offset = 0;
nsLayoutUtils::GetContainerAndOffsetAtEvent(presShell, mEvent,
nullptr, &offset);
return offset;
}
nsIntPoint
@@ -8,6 +8,9 @@
</head>
<body>
<p id="display"></p>
<p><input type="text" id="input"></p>
<p><input type="text" id="input_readonly" readonly></p>
<p><textarea id="textarea"></textarea></p>
<div id="content" style="display: none">
</div>
@@ -293,10 +296,163 @@ function testSynthesizedKeyLocation()
window.removeEventListener("keyup", handler, true);
}
// We're using TextEventDispatcher to decide if we should keypress event
// on content in the default event group. So, we can test if keypress
// event is NOT fired unexpectedly with synthesizeKey().
function testEnterKeyPressEvent()
{
let keydownFired, keypressFired, beforeinputFired;
function onEvent(aEvent) {
switch (aEvent.type) {
case "keydown":
keydownFired = true;
return;
case "keypress":
keypressFired = true;
return;
case "beforeinput":
beforeinputFired = true;
return;
}
}
for (let targetId of ["input", "textarea", "input_readonly"]) {
let target = document.getElementById(targetId);
function reset() {
keydownFired = keypressFired = beforeinputFired = false;
target.value = "";
}
target.addEventListener("keydown", onEvent);
target.addEventListener("keypress", onEvent);
target.addEventListener("beforeinput", onEvent);
const kDescription = "<" + targetId.replace("_", " ") + ">: ";
let isEditable = kDescription.includes("readonly");
let isTextarea = kDescription.includes("textarea");
target.focus();
reset();
synthesizeKey("KEY_Enter", {});
is(keydownFired, true,
kDescription + "keydown event should be fired when Enter key is pressed");
is(keypressFired, true,
kDescription + "keypress event should be fired when Enter key is pressed");
if (isEditable) {
todo_is(beforeinputFired, true,
kDescription + "beforeinput event should be fired when Enter key is pressed");
} else {
is(beforeinputFired, false,
kDescription + "beforeinput event shouldn't be fired when Enter key is pressed");
}
if (isTextarea) {
is(target.value, "\n",
kDescription + "Enter key should cause inputting a line break in <textarea>");
} else {
is(target.value, "",
kDescription + "Enter key should not cause inputting a line break");
}
reset();
synthesizeKey("KEY_Enter", {shiftKey: true});
is(keydownFired, true,
kDescription + "keydown event should be fired when Shift + Enter key is pressed");
is(keypressFired, true,
kDescription + "keypress event should be fired when Shift + Enter key is pressed");
if (isEditable) {
todo_is(beforeinputFired, true,
kDescription + "beforeinput event should be fired when Shift + Enter key is pressed");
} else {
is(beforeinputFired, false,
kDescription + "beforeinput event shouldn't be fired when Shift + Enter key is pressed");
}
if (isTextarea) {
is(target.value, "\n",
kDescription + "Shift + Enter key should cause inputting a line break in <textarea>");
} else {
is(target.value, "",
kDescription + "Shift + Enter key should not cause inputting a line break");
}
reset();
synthesizeKey("KEY_Enter", {ctrlKey: true});
is(keydownFired, true,
kDescription + "keydown event should be fired when Ctrl + Enter key is pressed");
is(keypressFired, true,
kDescription + "keypress event should be fired when Ctrl + Enter key is pressed");
is(beforeinputFired, false,
kDescription + "beforeinput event shouldn't be fired when Ctrl + Enter key is pressed");
is(target.value, "",
kDescription + "Ctrl + Enter key should not cause inputting a line break");
reset();
synthesizeKey("KEY_Enter", {altKey: true});
is(keydownFired, true,
kDescription + "keydown event should be fired when Alt + Enter key is pressed");
is(keypressFired, !kStrictKeyPressEvents,
kDescription + "keypress event shouldn't be fired when Alt + Enter key is pressed in strict keypress dispatching mode");
is(beforeinputFired, false,
kDescription + "beforeinput event shouldn't be fired when Alt + Enter key is pressed");
is(target.value, "",
kDescription + "Alt + Enter key should not cause inputting a line break");
reset();
synthesizeKey("KEY_Enter", {metaKey: true});
is(keydownFired, true,
kDescription + "keydown event should be fired when Meta + Enter key is pressed");
is(keypressFired, !kStrictKeyPressEvents,
kDescription + "keypress event shouldn't be fired when Meta + Enter key is pressed in strict keypress dispatching mode");
is(beforeinputFired, false,
kDescription + "beforeinput event shouldn't be fired when Meta + Enter key is pressed");
is(target.value, "",
kDescription + "Meta + Enter key should not cause inputting a line break");
reset();
synthesizeKey("KEY_Enter", {shiftKey: true, ctrlKey: true});
is(keydownFired, true,
kDescription + "keydown event should be fired when Ctrl + Shift + Enter key is pressed");
is(keypressFired, !kStrictKeyPressEvents,
kDescription + "keypress event shouldn't be fired when Ctrl + Shift + Enter key is pressed in strict keypress dispatching mode");
is(beforeinputFired, false,
kDescription + "beforeinput event shouldn't be fired when Ctrl + Shift + Enter key is pressed");
is(target.value, "",
kDescription + "Ctrl + Shift + Enter key should not cause inputting a line break");
reset();
synthesizeKey("KEY_Enter", {shiftKey: true, altKey: true});
is(keydownFired, true,
kDescription + "keydown event should be fired when Alt + Shift + Enter key is pressed");
is(keypressFired, !kStrictKeyPressEvents,
kDescription + "keypress event shouldn't be fired when Alt + Shift + Enter key is pressed in strict keypress dispatching mode");
is(beforeinputFired, false,
kDescription + "beforeinput event shouldn't be fired when Alt + Shift + Enter key is pressed");
is(target.value, "",
kDescription + "Alt + Shift + Enter key should not cause inputting a line break");
reset();
synthesizeKey("KEY_Enter", {shiftKey: true, metaKey: true});
is(keydownFired, true,
kDescription + "keydown event should be fired when Meta + Shift + Enter key is pressed");
is(keypressFired, !kStrictKeyPressEvents,
kDescription + "keypress event shouldn't be fired when Meta + Shift + Enter key is pressed in strict keypress dispatching mode");
is(beforeinputFired, false,
kDescription + "beforeinput event shouldn't be fired when Meta + Shift + Enter key is pressed");
is(target.value, "",
kDescription + "Meta + Shift + Enter key should not cause inputting a line break");
target.removeEventListener("keydown", onEvent);
target.removeEventListener("keypress", onEvent);
target.removeEventListener("beforeinput", onEvent);
}
}
function runTests()
{
testInitializingUntrustedEvent();
testSynthesizedKeyLocation();
testEnterKeyPressEvent();
SimpleTest.finish();
}
+4 -2
View File
@@ -536,7 +536,8 @@ FetchDriver::OnStartRequest(nsIRequest* aRequest,
nsAutoCString statusText;
httpChannel->GetResponseStatusText(statusText);
response = new InternalResponse(responseStatus, statusText);
response = new InternalResponse(responseStatus, statusText,
mRequest->GetCredentialsMode());
RefPtr<FillResponseHeaders> visitor = new FillResponseHeaders(response);
rv = httpChannel->VisitResponseHeaders(visitor);
@@ -555,7 +556,8 @@ FetchDriver::OnStartRequest(nsIRequest* aRequest,
}
MOZ_ASSERT(!result.Failed());
} else {
response = new InternalResponse(200, NS_LITERAL_CSTRING("OK"));
response = new InternalResponse(200, NS_LITERAL_CSTRING("OK"),
mRequest->GetCredentialsMode());
ErrorResult result;
nsAutoCString contentType;
Loaded 100 of 4640 files, more files were not shown because too many files have changed in this diff. Show more