Compare commits

..
323 Commits
Author SHA1 Message Date
athenian200 451509e2c0 Issue #1571 - Remove JEMALLOC_USES_MAP_ALIGN and fix 48-bit addressing on SunOS AMD64.
The JEMALLOC_USES_MAP_ALIGN code has turned out to be worse than useless, and in fact it breaks 64-bit SunOS. It's very old and turned out not to be needed anymore because the way the memory allocator works has changed since it was implemented. It prevented a fix I tried for 48-bit addressing from working properly. However, without either this code or the 48-bit addressing fix, the 64-bit version won't even start, which is why I thought the code was still needed.

https://bugzilla.mozilla.org/show_bug.cgi?id=457189

https://hg.mozilla.org/mozilla-central/rev/a26c500b98ab

The 48-bit addressing fix is based on code found here:

https://github.com/OpenIndiana/oi-userland/blob/oi/hipster/components/web/firefox/patches/patch-js_src_gc_Memory.cpp.patch

I already applied these changes to js/src/gc/Memory.cpp, but as I was looking through jemalloc.c I saw that there were very similar ifdefs for Linux on SPARC as the ones I'd had to enaable in Memory.cpp, but for whatever reason the patches I found didn't touch them. So I tried doing for jemalloc.c what was already done for Memory.cpp, and it worked (but only after I removed the map align code).
2020-06-01 11:00:26 +02:00
wolfbeast 7895b8acd9 Issue #1570 - Implement globalThis
This resolves #1570
2020-06-01 10:59:51 +02:00
Fedor ccff4610c5 Issue #1558 - Prevent null deref crash in WebrtcVideoConduit DTOR 2020-06-01 10:59:15 +02:00
athenian200 15a1f78f8b Issue #1557 - Allow event dispatch on disabled form controls. (uplift) 2020-05-21 13:16:17 +00:00
athenian200 8b44473fe6 Revert "Merge pull request #1357 from athenian200/form-disabled-issue"
This reverts commit ed88b99849, reversing
changes made to c4b0715baa.
2020-05-21 13:10:27 +00:00
athenian200 6e0aee959e Issue #1540 - Stop MP3 demuxer from choking on very small files. 2020-05-20 17:18:39 +02:00
Matt A. Tobin ba5930cc8e Issue #1449 - Implement URLSearchParams's sort() 2020-05-10 16:06:19 +02:00
wolfbeast 6376255c0c Issue #1589 - Ensure computed length and data is always available 2020-05-10 14:51:23 +02:00
Moonchild 320682148b [XPFE] Properly anchor XUL windows when tearing down 2020-05-06 19:03:37 +02:00
Moonchild 1ed84ac1f8 [WebRTC] Port some upstream sctp fixes
- add SCTP auth token boundary check.
- turn off SCTP auth and address reconfiguration.
2020-05-06 19:03:23 +02:00
Moonchild 9c9d04e3e0 [dom] Reorder some calls to improve memory safety 2020-05-06 19:03:08 +02:00
Moonchild 19504d5263 [devtools] Port various upstream fixes 2020-05-06 19:02:56 +02:00
Moonchild 533b346f4e [js] Record load in MCreateThis alias set. 2020-05-06 19:02:42 +02:00
Bas Schouten 6afd96c460 Prevent the existance of dangling pointers upon failure of FindDataStart. 2020-05-06 19:02:28 +02:00
Matt A. Tobin 9858dc03cb Hyperbola IceDove should use the toolkit SearchService 2020-05-06 19:00:16 +02:00
wolfbeast d21b46fc9c Revert "Issue #1445 - Clarify the status of extensions in the Add-On manager"
This reverts commit f107de8a90.
2020-04-27 11:58:42 +02:00
wolfbeast 55fa46d059 Revert "Issue #1446 - Only allow extension add-on types for Firefox compat mode."
This reverts commit e8417acbff.
2020-04-27 11:57:28 +02:00
wolfbeast b089b365d6 Revert "Issue #1446 - Only match extension add-on types for target applications."
This reverts commit 4889e6dbbd.
2020-04-27 11:57:14 +02:00
wolfbeast 0c150945dc Revert "Issue #1445 - Use the detailed string also in the list entries."
This reverts commit ac68f8cf6c.
2020-04-27 11:57:01 +02:00
wolfbeast 0fb23389f5 Revert "Issue #1445 - remove redundant nativeIndicator"
This reverts commit 2073a7f1c9.
2020-04-27 11:56:47 +02:00
wolfbeast 7ba07f4a17 Revert "Issue #1445 - Add a link to details on using Firefox extensions in Pale Moon"
This reverts commit c220c30bbb.
2020-04-27 11:56:33 +02:00
wolfbeast 554183b5dd Revert "Issue #1445 - strings cleanup"
This reverts commit 461a9e86b2.
2020-04-27 11:56:19 +02:00
wolfbeast 98fe8b0ccb Merge branch 'redwood' into 28.9-platform 2020-04-26 12:56:46 +02:00
Matt A. Tobin 519030e688 Issue #80 - Resolve issues with compiling on insane gcc configurations with no optimizations in dom/ 2020-04-26 10:27:18 +02:00
adeshkp b9531d8e11 Issue #80 - Add Unused.h to dom/gamepad for Mac build 2020-04-26 10:26:57 +02:00
adeshkp 7605f4b0f8 Issue #80 - Fix include in PlatformDecoderModule.h 2020-04-26 10:26:07 +02:00
wolfbeast ab0e18135f Issue #80 - Fix include in dom/quota
Reported by Luke.
2020-04-26 10:23:13 +02:00
wolfbeast e883ac54e9 Issue #80 - Fix include in dom/media for Pale Moon builds. 2020-04-26 10:22:59 +02:00
New Tobin Paradigm 9cb65e8a77 Add Unused.h to dom/media/webrtc/MediaTrackConstraints.cpp 2020-04-26 10:22:46 +02:00
adeshkp 3a3152d54b Issue #80 - Include D3DMessageUtils.h in dom/plugins/ipc for Mac build
This should ideally not be needed on Mac but compilation fails due to
sizeof `DxgiAdapterDesc` not known.

Didn't face this issue on Linux though, probably due to a different include
chain which already has this file included somewhere along the way.
2020-04-26 10:22:32 +02:00
adeshkp f174801b64 Issue #80 - Fix includes in dom/media/platforms for Mac build 2020-04-26 10:22:20 +02:00
New Tobin Paradigm 3caceeb539 Issue #80 - Include nsIContentInlines.h in dom/svg/SVGTests.cpp to fix linux bustage 2020-04-26 10:21:59 +02:00
Moonchild 216189e6f7 Issue #80 - De-unify dom/xul 2020-04-26 10:21:48 +02:00
Moonchild bbae11cdd9 Issue #80 - De-unify dom/xslt 2020-04-26 10:21:37 +02:00
Moonchild 917447df6e Issue #80 - De-unify dom/xml 2020-04-26 10:21:27 +02:00
Moonchild 244c8ef1f7 Issue #80 - De-unify dom/xhr 2020-04-26 10:21:10 +02:00
Moonchild e1b6493747 Issue #80 - De-unify dom/xbl 2020-04-26 10:20:59 +02:00
Moonchild 4e225fc7d1 Issue #80 - De-unify dom/workers 2020-04-26 10:20:48 +02:00
Moonchild 683b1bedea Issue #80 - De-unify dom/system 2020-04-26 10:20:38 +02:00
Moonchild 11519ee6d2 Issue #80 - De-unify dom/svg 2020-04-26 10:20:27 +02:00
Moonchild 8a343284d9 Issue #80 - De-unify dom/smil 2020-04-26 10:20:16 +02:00
Moonchild 5a34fb5e1d Issue #80 - De-unify dom/security
Exception: CSPUtils relies on something in CSPContext, but on
Windows it throws in an MSVC include which provides no hints.
2020-04-26 10:20:05 +02:00
Moonchild 16c8dff724 Issue #80 - De-unify dom/quota 2020-04-26 10:19:55 +02:00
Moonchild 3595b9eecf Issue #80 - De-unify dom/push 2020-04-26 10:19:44 +02:00
Moonchild 594cbca6d1 Issue #80 - De-unify dom/plugins/ipc 2020-04-26 10:19:33 +02:00
Moonchild a4ba260904 Issue #80 - De-unify dom/plugins/base 2020-04-26 10:19:22 +02:00
Moonchild 4a8c186eea Issue #80 - De-unify dom/performance 2020-04-26 10:19:11 +02:00
Moonchild 8ff6e8c8a2 Issue #80 - De-unify dom/media part 3
Excluding /dom/media/webrtc for bad template use:
MediaTrackConstraints.cpp/h
MediaEngineCameraVideoSource.cpp and
MediaEngineRemoteVideoSource.cpp
2020-04-26 10:18:59 +02:00
Moonchild 3652cd0f99 Issue #80 - De-unify dom/media part 2 2020-04-26 10:18:45 +02:00
Moonchild b738ccc61b Issue #80 - De-unify dom/media part 1 (updated reland)
This de-unifies up to and including dom/media/platforms with the exception of
dom/media/platforms/wmf, because that one throws weird errors in the Win
SDK which don't have a clear cause (yet)
2020-04-26 10:18:28 +02:00
Moonchild 1c3a9a40e5 Issue #80 - De-unify dom/ipc 2020-04-24 10:37:30 +02:00
Moonchild 0a33733505 Issue #80 - De-unify dom/indexedDB 2020-04-24 10:37:19 +02:00
wolfbeast 691878e20f Issue #80 - De-unify dom/html 2020-04-24 10:37:08 +02:00
wolfbeast bf1fa93b91 [AM] Clean up addon-signing build leftovers. 2020-04-24 10:36:55 +02:00
wolfbeast 0ac7481d2e Issue #80 - De-unify dom/network 2020-04-24 10:36:44 +02:00
wolfbeast 168bb31e4f Issue #80 - De-unify dom/grid 2020-04-24 10:36:33 +02:00
wolfbeast ca04b37910 Issue #80 - De-unify dom/geolocation 2020-04-24 10:36:23 +02:00
wolfbeast f3b26f64fc Issue #80 - De-unify dom/gamepad 2020-04-24 10:36:11 +02:00
wolfbeast 99d23484bb Issue #80 - De-unify dom/filesystem 2020-04-24 10:36:01 +02:00
wolfbeast 376bc050a6 Issue #80 - De-unify dom/filehandle 2020-04-24 10:35:49 +02:00
Matt A. Tobin 9258382b0d Issue #576 - Remove IdentityService and ContextualIdentityService 2020-04-24 10:35:38 +02:00
Matt A. Tobin b6a703907e Issue #65 - Remove AppConstants from toolkit/prompts/content/tabprompts.xml
This file not only somehow escaped my pass through here but was also mocking me by using AppConstants in a preprocessed file BUT ALSO right AFTER a preprocessor directive.
2020-04-24 10:35:09 +02:00
Matt A. Tobin da42871b0e Put Request.cpp and Response.cpp back into UNIFIED in dom/fetch due to linux linker errors
Reference:

15:03.06 ../../build/unix/gold/ld: error: /home/mattatobin/development/.obj/trunk-master/navigator-x64-gtk3/toolkit/library/../../dom/fetch/Request.o: requires dynamic R_X86_64_PC32 reloc against '_ZN7mozilla3dom9FetchBodyINS0_7RequestEED2Ev' which may overflow at runtime; recompile with -fPIC
15:03.06 ../../build/unix/gold/ld: error: /home/mattatobin/development/.obj/trunk-master/navigator-x64-gtk3/toolkit/library/../../dom/fetch/Response.o: requires dynamic R_X86_64_PC32 reloc against '_ZN7mozilla3dom9FetchBodyINS0_8ResponseEED2Ev' which may overflow at runtime; recompile with -fPIC
15:03.06 ../../build/unix/gold/ld: error: read-only segment has dynamic relocations
15:03.07 /home/mattatobin/development/.obj/trunk-master/navigator-x64-gtk3/toolkit/library/../../dom/fetch/Request.o:Request.cpp:function mozilla::dom::Request::~Request(): error: undefined reference to 'mozilla::dom::FetchBody<mozilla::dom::Request>::~FetchBody()'
15:03.07 /home/mattatobin/development/.obj/trunk-master/navigator-x64-gtk3/toolkit/library/../../dom/fetch/Response.o:Response.cpp:function mozilla::dom::Response::~Response(): error: undefined reference to 'mozilla::dom::FetchBody<mozilla::dom::Response>::~FetchBody()'
2020-04-24 10:34:46 +02:00
wolfbeast c55433ee03 Issue #80 - De-unify dom/fetch
Running into the same problem as with dom/canvas: derived template
classes not being happy about being non-unified. Kept unified for now
to prevent linking errors.
2020-04-24 10:34:33 +02:00
wolfbeast d0a2389b43 Issue #80 - De-unify dom/events 2020-04-24 10:34:20 +02:00
wolfbeast 796a14e116 Issue #80 - De-unify dom/crypto 2020-04-24 10:34:08 +02:00
Matt A. Tobin ba6e4753b7 Fix typo in dom/animation/CSSPseudoElement.cpp
Linux filesystems tend to be case sensitive
2020-04-24 10:33:56 +02:00
wolfbeast 6d3d69f644 Issue #80 - De-unify dom/canvas 2020-04-24 10:33:20 +02:00
Matt A. Tobin fce3132fe8 Make application moz.configure file optional and set application/xulrunner as the default platform build_app 2020-04-24 10:33:08 +02:00
Matt A. Tobin a7da3cf52b Issue #80 - De-unify layout/mathml 2020-04-24 10:32:48 +02:00
Matt A. Tobin f5316668a3 Issue #80 - De-unify layout/forms 2020-04-24 10:32:36 +02:00
wolfbeast dc687dbc0b Issue #80 - De-unify dom/cache 2020-04-24 10:32:24 +02:00
wolfbeast 216aa2cada Issue #80 - De-unify dom/archivereader 2020-04-24 10:32:14 +02:00
wolfbeast 9d96ad90dd Issue #80 - De-unify dom/animation
KeyFrameEffect and KeyFrameEffectReadOnly are still built unified as
buddies because they have some complex interdependency that couldn't
easily be resolved without linking failures.
2020-04-24 10:32:03 +02:00
Matt A. Tobin b064c95231 Issue #80 - De-unify dom/messagechannel 2020-04-24 10:31:52 +02:00
Matt A. Tobin 11eb1f57f4 Issue #80 - De-unify dom/audiochannel 2020-04-24 10:31:42 +02:00
Matt A. Tobin 052cb18fff Issue #80 - De-unify dom/notification 2020-04-24 10:31:31 +02:00
Matt A. Tobin d306fe61c5 Issue #80 - De-unify dom/url 2020-04-24 10:31:19 +02:00
Matt A. Tobin 7859a0d693 Issue #80 - De-unify dom/encoding 2020-04-24 10:31:08 +02:00
Matt A. Tobin c5d9e1f973 Issue #80 - De-unify dom/json 2020-04-24 10:30:52 +02:00
Matt A. Tobin 2e12bda342 Issue #80 - De-unify dom/u2f 2020-04-24 10:30:40 +02:00
Matt A. Tobin 9755cd617d Issue #80 - De-unify dom/power 2020-04-24 10:30:29 +02:00
Matt A. Tobin abaf4d9fb4 Issue #80 - De-unify dom/mathml 2020-04-24 10:30:18 +02:00
Matt A. Tobin ae6f407177 Issue #80 - De-unify dom/jsurl 2020-04-24 10:30:08 +02:00
Matt A. Tobin 2a44476795 Issue #80 - De-unify dom/worklet 2020-04-24 10:29:56 +02:00
Matt A. Tobin 755cf4c7d0 Issue #80 - De-unify dom/console 2020-04-24 10:29:45 +02:00
Matt A. Tobin 47f26a67f4 Issue #80 - De-unify dom/media/webm 2020-04-24 10:29:34 +02:00
Matt A. Tobin e8aa76713a Issue #80 - De-unify dom/media/flac 2020-04-24 10:29:23 +02:00
Matt A. Tobin e6ffc4bdb7 Issue #80 - De-unify dom/media/mp3 2020-04-24 10:29:13 +02:00
Matt A. Tobin 90bbe7536d Issue #80 - De-unify dom/media/ogg 2020-04-24 10:29:01 +02:00
Matt A. Tobin 140750e4e8 Issue #80 - De-unify dom/media/encoder 2020-04-24 10:28:50 +02:00
Matt A. Tobin f2e089d51b Issue #80 - De-unify dom/media/mediasink 2020-04-24 10:28:38 +02:00
Matt A. Tobin e1d0ac30ac Issue #80 - De-unify dom/media/wave 2020-04-24 10:28:28 +02:00
Matt A. Tobin 9e8adc25a4 Issue #80 - De-unify dom/storage 2020-04-24 10:28:16 +02:00
Matt A. Tobin 7f66e8946a Issue #80 - De-unify dom/time 2020-04-24 10:28:05 +02:00
Matt A. Tobin c75b8ec714 Issue #80 - De-unify dom/permission 2020-04-24 10:27:54 +02:00
Matt A. Tobin 4250d93166 Issue #80 - De-unify dom/broadcastchannel 2020-04-24 10:27:42 +02:00
Matt A. Tobin 37250226d5 Issue #80 - De-unify dom/offline 2020-04-24 10:27:30 +02:00
Matt A. Tobin 802a4cfefe Issue #80 - De-unify /layout/inspector 2020-04-24 10:27:18 +02:00
Matt A. Tobin 5641a6d574 Issue #80 - De-unify /layout/tools/layout-debug/src 2020-04-24 10:27:06 +02:00
Matt A. Tobin 88d2480356 Issue #80 - De-unify /layout/ipc 2020-04-24 10:26:52 +02:00
Matt A. Tobin fcb4b997d0 Issue #80 - De-unify /layout/build 2020-04-24 10:26:40 +02:00
wolfbeast 79964767f5 [docs] Update coding style cf. discussion with Tobin. 2020-04-24 10:26:16 +02:00
wolfbeast a4a8d082a3 Issue #251 - Move MOZ_AV1 back to ac configure for everyone to use. 2020-04-24 10:25:57 +02:00
Matt A. Tobin adce88de95 Issue #1516 - Part 1: Add a global build define to determine if the client can draw in the titlebar and update consumers of the local define 2020-04-24 10:24:52 +02:00
wolfbeast 974d6ca889 Issue #1517 - Enable high-resolution DOM timestamps on trunk
At the very least we should enable these short term, with the potential
removal of it pending.
2020-04-16 13:58:36 +02:00
wolfbeast e08a4ad1c8 Issue #1517 - Enable high-resolution DOM timestamps on release 2020-04-16 04:20:42 +02:00
wolfbeast 39dac57259 Merge branch 'redwood' into 28.9-platform 2020-04-14 21:49:04 +02:00
wolfbeast c2d9ab62f3 Fix additional deprot in dom/base 2020-04-14 21:37:53 +02:00
wolfbeast b9e692af05 Revert 1320408 part 15: Make addDataProperty static 2020-04-14 21:10:50 +02:00
wolfbeast 871e57fdd6 Issue #80 - De-unify dom/base and fix deprot. 2020-04-14 14:19:58 +02:00
wolfbeast 03530de64f Fix deprot in /layout 2020-04-14 14:02:50 +02:00
Moonchild 4730da5b27 Create SECURITY.md
Provide basic instructions how to report security vulnerabilities.
2020-04-14 13:28:43 +02:00
wolfbeast 3cb245b749 Issue #1514 - Perform validity check before trying to use the content.
Resolves #1514
2020-04-14 13:28:28 +02:00
wolfbeast 9f5529d1e7 Issue #1513 - Bail on orphan node
This was refactored by Mozilla into doing effectively the same thing so
it aligns with them re: behavior.
Resolves #1513
2020-04-14 13:28:10 +02:00
wolfbeast 26c888208a Issue #1512 - Improve handling of multiple selections.
IsSelectionEditable should check whether the focus node and anchor node
aren't null before trying to use them.
This also changes the initialization of selections' aOutIndex to the
last range in the selection as a fallback in case we don't add a range
later (in AddItem) which could also end up with a null selection
otherwise if the additional selection nodes are removed.
2020-04-14 13:27:57 +02:00
wolfbeast 9a52b3b852 [layout] Always move descendants of layout frames if moved.
If we move the frame then we always need to move any descendant views,
not just in case the frame itself has a view.
2020-04-14 13:27:34 +02:00
wolfbeast 96afb5250d Issue #1511 - Bail on orphan situation.
This resolves #1511
2020-04-14 13:27:12 +02:00
Jan de Mooij b93afb1ba7 [js] Handle functions with rest parameters in isObservableArgumentSlot. 2020-04-14 13:26:57 +02:00
Matt A. Tobin 277f2116b6 Move aom source to a sub-directory under media/libaom
There is no damned reason to treat this differently than any other media lib given its license and there never was.
2020-04-14 13:26:42 +02:00
Matt A. Tobin d270404436 Silence removing dist/bin 2020-04-14 13:26:26 +02:00
Matt A. Tobin 3bec218684 Take files out of preprocessing that no longer require it 2020-04-14 13:26:13 +02:00
Matt A. Tobin 6daff43b61 Follow up to d0eee8f01 - Run precomplete cmd during package staging 2020-04-14 13:25:58 +02:00
Matt A. Tobin eedf9f5ebf Align mar generation on Windows with other platforms
This makes mar generation dependent on packaging not installer
2020-04-14 13:25:44 +02:00
Matt A. Tobin 049dae86d2 Alter config.guess to properly detect host and target bitness on SunOS 2020-04-14 13:25:29 +02:00
wolfbeast 65ba3cac58 [Docshell] Ensure nsDocShell::mContentViewer is released properly. 2020-04-14 13:25:13 +02:00
wolfbeast 1b8788aecb Issue #1505 - Part 3: Make native mode actually native again. 2020-04-14 13:24:59 +02:00
wolfbeast 747632bd64 Issue #1505 - Part 2: Store application build ID in nsHttpHandler
Since we're needing to reuse this several times, it makes it simpler to
just get it once in init and storing it.
2020-04-14 13:24:46 +02:00
wolfbeast 02327fa745 Issue #1505 - Rebuild application version string
To respond dynamically to the pref change, the mAppVersion string needs
to be rebuilt.
Includes some minor improvements for corner cases and removes leftover
b2g junk.
2020-04-14 13:24:32 +02:00
New Tobin Paradigm b470422d5a Issue #1497 - Re-implement an un-preprocessed file check 2020-04-14 13:24:17 +02:00
wolfbeast 449d530a30 Issue #1508 - Redirect moz://a to http://thereisonlyxul.org/ 2020-04-14 13:24:03 +02:00
wolfbeast 8bd941d4e3 Issue #1507 - Remove nsRefreshDriver's use of high res system timers.
Since we are using vsync for timing anyway in the layout refresh driver,
there is no need to bump the system timer resolution down to 1 ms.

This resolves #1507.
2020-04-14 13:23:48 +02:00
JustOff 7172fc72a3 Issue #65 - Fix unprocessed directives in WebRequest.jsm 2020-04-14 13:23:21 +02:00
Matt A. Tobin b977981df6 Make the reference to Handle unambiguous in ipc/testshell/XPCShellEnvironment.cpp
.. correctly
2020-04-14 13:23:06 +02:00
Matt A. Tobin 9dc65422ba Revert "Make the reference to Handle unambiguous in ipc/testshell/XPCShellEnvironment.cpp"
This reverts commit d4afddfada.
2020-04-14 13:22:51 +02:00
Matt A. Tobin 45e8e98031 Make the reference to Handle unambiguous in ipc/testshell/XPCShellEnvironment.cpp 2020-04-14 13:22:34 +02:00
Matt A. Tobin 965232ab2f Output webidl filenames as they are processed 2020-04-14 13:22:13 +02:00
athenian200 980ca14602 Issue #1501 - Un-bust building of NSS after update to 3.48 on Solaris. 2020-04-14 13:21:54 +02:00
Matt A. Tobin 02519e8575 Explicitly remove dist/bin before mozbuild's install_manifests get a hold of it 2020-04-14 13:21:33 +02:00
Matt A. Tobin e003547dc5 Properly fix crash in nsDownloadManager when repeatedly pausing and resuming a download
This applies only to applications that do not use JSDownloads and is based on Bug 1224326
2020-04-14 13:21:07 +02:00
Matt A. Tobin 56f8375338 Revert "Only state the stop notification for JSDownloads in nsWebBrowserPersist::EndDownload"
This reverts commit aa28523a55.
2020-04-14 13:20:54 +02:00
wolfbeast 2407845ec1 Issue #1280 - Un-bust certerror pages and ForgetAboutSite 2020-04-14 13:20:35 +02:00
wolfbeast 3f09b298b0 Issue #1280 - Stop requesting HPKP state from within devtools. 2020-04-14 13:20:22 +02:00
wolfbeast c27830f35c Issue #1280 - Part 2: Remove HPKP tests. 2020-04-14 13:19:54 +02:00
wolfbeast 99bad1726e Issue #1280 - Part 1: Remove HPKP components.
This also removes leftover plumbing for storing preload information
in SiteSecurityService since no service still uses it.
2020-04-14 13:19:41 +02:00
JustOff d86349716a Issue #1473 - Fix building %OS_SLICE% on non-Windows platforms 2020-04-14 13:19:20 +02:00
JMadgwick 64a7c9e2d2 Issue #1471 - Fix building on sparc64 Linux
Correct various pre-processor defines for sparc64 and in mozjemalloc use the JS arm64 allocator on Linux/sparc64.
This corrects build problems opn Linux sparc64 and is in line with bugzilla bug #1275204.
2020-04-14 13:18:48 +02:00
New Tobin Paradigm 514ff21cba Update README.md 2020-04-14 13:18:16 +02:00
wolfbeast edb5796d58 Issue #1497 Revert "Check if there are any unpreprocessed files"
This reverts PR #429
2020-04-14 13:18:02 +02:00
wolfbeast c23e3b25f8 Issue #1497 Revert "MoonchildProductions#1251 - Part 19"
"Make the unpreprocessed file script work on Solaris."

This reverts commit e51afbcc2f.
2020-04-14 13:17:47 +02:00
Matt A. Tobin e360caa1a2 Teach config.guess to know if we want to build 32 or 64 bit builds on Windows 2020-04-14 13:17:20 +02:00
Matt A. Tobin 9eeaeff77b Issue #1499 - Re-import ExtensionStorage.jsm 2020-04-14 13:16:54 +02:00
wolfbeast a435374873 Issue #1498 - Part 6: Remove STS preloadlist pref. 2020-04-14 13:16:38 +02:00
wolfbeast 04cfc091da Issue #1498 - Part 5: Update SSService CID and correct mismatch. 2020-04-14 13:16:24 +02:00
wolfbeast b23e7b61c6 Issue #1498 - Part 4: Remove clearPreloads.
Also tag #1280
2020-04-14 13:16:11 +02:00
wolfbeast 69b4e77751 Issue #1498 - Part 3: Remove support for storing "knockout" values. 2020-04-14 13:15:58 +02:00
wolfbeast 5657b5c53b Issue #1498 - Part 2: Stop persisting preload states.
Since we don't use preloading anymore for either HPKP or HSTS, we no
longer need persistent storage in the profile for preload states.
Tag #1280 also
2020-04-14 13:14:43 +02:00
wolfbeast 1037746d00 Issue #1498 - Part 1: Stop using HSTS preload lists. 2020-04-14 13:14:03 +02:00
Matt A. Tobin a060401264 Take nsSiteSecurityService out of UNIFIED_SOURCES
It exceeded the obj file sections limit because of the HSTS preload list so it cannot be built in UNIFIED mode.
2020-04-14 13:13:44 +02:00
wolfbeast 4e26fc1844 Issue #447 - Update HSTS preload list 2020-04-14 13:13:06 +02:00
Brian Smith 2645f9b944 Issue #1491 - Part 2: Disable a workaround on macOS 10.14+ for an Apple bug described in Mozilla bug 378645 involving popup windows that was fixed by Apple. 2020-04-14 13:12:48 +02:00
Brian Smith 88ce149033 Issue #1491 - Part 1: Update nsCocoaFeatures for newer versions of MacOS X. 2020-04-14 13:12:25 +02:00
wolfbeast 09655ad6d8 Issue #1467 - Part 4: Rename NSS_SQLSTORE to MOZ_SECURITY_SQLSTORE.
Rename the build config option accordingly.
2020-04-14 13:12:08 +02:00
wolfbeast 4fd0b98c2c Issue #1467 - Part 3: Use UTF-8 file paths for NSS-SQL database. 2020-04-14 13:11:51 +02:00
wolfbeast 894b33e53a Issue #1467 - Part 2: Make the PBKDF rounds adaptive to choice of NSS db 2020-04-14 13:11:37 +02:00
wolfbeast 236d425993 Issue #1467 - Part 1b: Fix type and make moz.configure happy. 2020-04-14 13:11:22 +02:00
wolfbeast 899e14e945 Issue #1467 - Part 1: Set up conditional NSS-SQL builds.
- Adds buildconfig option --enable-nss-sqlstore
- Prefixes NSS dbinit with either sql: or dbm: depending on config
- Pre-initializes mozStorage when NSS-SQL storage is used to prevent
  an sqlite3_config race in NSS Init
2020-04-14 13:11:05 +02:00
wolfbeast 03fda9f0f3 [devtools] Properly escape method arguments for curl. 2020-04-14 13:10:45 +02:00
wolfbeast 3aae828871 [DOM] Make sure to exit fullscreen mode if popups are opened or focused. 2020-04-14 13:10:23 +02:00
wolfbeast e7514afc7c [js] Remove pointless MakeMRegExpHoistable optimization.
It's a lot of code with no measurable effect.
2020-04-14 13:10:09 +02:00
wolfbeast 4adf0d09f7 [network] Cherry-pick various sctp lib upstream fixes. 2020-04-14 13:09:51 +02:00
wolfbeast 22d0b88e37 Issue #1355 - Make addition of cell border display items depend on
whether they should be drawn.

This reduces the size of display lists for tables by only adding display
list items that are actually going to be visibly drawn, which will help
overall performance of table drawing.
2020-04-14 13:06:54 +02:00
JustOff f7388678bd Issue #1482 - Give dynamic SSUAO rules priority over static ones 2020-04-14 13:06:30 +02:00
wolfbeast b45f5c435e Issue #1485 - Fix incorrect grid cell sizing to min/max space.
There were actually two separate logical errors in this method:

The first part is that "origSizes.isSome()" is simply a bogus
requirement for applying min/max-sizes here. I'm still keeping
the optimization of not needlessly copying the mSizes array
(as originally intended) since it's a quite common case.

The second bug is that min/max-sizes were only applied under
the "if (fr != 0.0f)" block. This is bogus since the calculated
'fr' value depends on 'aAvailableSize' which might change by
applying min/max-sizes and thus 'fr' could become non-zero in
the second round.
To fix, this patch just moves "applyMinMax" block out one level.
2020-04-14 13:06:11 +02:00
Matt A. Tobin 3c73c0805c Issue #1477 - Fix finding config.guess on builds not using MOZ_OBJDIR
* So far this seems to only affect Macintosh builds but other unix builds may be affected. Windows doesn't seem to be.
* This maintains consistency with other one-off file invocations and backwards compatibility with older comm setups
2020-04-14 13:05:58 +02:00
wolfbeast db93b005f5 Issue #1480 - Skip abspos, fixed, float and placeholders for outline. 2020-04-14 13:05:43 +02:00
JustOff d2aaa74f31 Issue #1053 - Remove no longer used function and modules from UserAgentUpdates.jsm 2020-04-14 13:05:25 +02:00
JustOff 702cf42544 Issue #1473 - Add %OS_SLICE% macro to SSUAO to refine OS info 2020-04-14 13:05:07 +02:00
wolfbeast 79a9dc2479 Minor update to UXP coding style guideline. 2020-04-14 13:04:46 +02:00
New Tobin Paradigm ddcc3deddd Update README.md 2020-04-14 13:04:19 +02:00
wolfbeast f3b148844a Issue #1474 - Prevent the cp detection from starting if preffed off.
When setting up connectivity, e.g. with new network detection, the pref
wouldn't be checked (or honored), resulting in spurious startup calls
despite being preffed off. This fixes that.

Resolves #1474
2020-04-14 13:04:05 +02:00
wolfbeast 51d5d162b7 Update UXP coding style guide JS guide. 2020-04-14 13:03:47 +02:00
wolfbeast 94494805da Update UXP coding style guide JS guide. 2020-04-14 13:03:34 +02:00
Matt A. Tobin 5c7109182c Issue #1470 - Part 3: Remove now unused update.locale
This requires changes to package-manifest in all applications
2020-04-14 13:03:21 +02:00
Matt A. Tobin 68e873ada7 Issue #1470 - Part 2: Change calls from UpdateUtils.getUpdateChannel() to UpdateUtils.UpdateChannel in telemetry modules 2020-04-14 13:03:07 +02:00
Matt A. Tobin a5b05528fe Issue #1470 - Part 1: Refactor UpdateUtils.jsm 2020-04-14 13:02:53 +02:00
wolfbeast ce88d82f4a Update UXP coding style guide with JS guide. 2020-04-14 13:02:39 +02:00
New Tobin Paradigm 61d3aa9be2 Remove exposed bug from UpdateUtils.jsm 2020-04-14 13:02:22 +02:00
Matt A. Tobin a078d9f976 Issue #1053 - Remove android-only skia-npapi 2020-04-14 13:01:51 +02:00
Matt A. Tobin 3ed2b7a7cc Issue #1053 - Remove android support from nsNSSComponent.cpp 2020-04-14 13:01:34 +02:00
Matt A. Tobin 9816a810e6 Issue #251 - Move --disable-dbm to ac configure
Also Tag #1467
2020-04-14 13:01:21 +02:00
Matt A. Tobin 9a8068ea3f Remove unused mailnews.mozbuild 2020-04-14 13:01:07 +02:00
Matt A. Tobin dcd9bbb717 Mork is not dependent on dbm and never was. 2020-04-14 13:00:55 +02:00
Matt A. Tobin ecc0a40688 Correct typo in mailnews/base/src/moz.build 2020-04-14 13:00:41 +02:00
Matt A. Tobin 8f40737fc7 Issue #1319 - Remove EARLY_BETA_OR_EARLIER condition 2020-04-14 13:00:26 +02:00
wolfbeast e7841ab5d7 Issue #1465 - Implement optional catch binding. 2020-04-14 13:00:11 +02:00
wolfbeast dba09fa5c4 Revert "Issue #1355 - Better way to create display items for column backgrounds"
This reverts commit 44c47c5038.
2020-04-14 12:59:57 +02:00
wolfbeast afe2b7fa5a Revert "Layout\reftests\table-background\reftest.list should have only additions to the end of it."
This reverts commit efdc2af8ab.
2020-04-14 12:59:43 +02:00
wolfbeast acaec3f389 [DOM] Add a null check 2020-04-14 12:59:26 +02:00
Matt A. Tobin d2083edba2 No Issue - Always build marionette until it can be tracked down and killed 2020-04-14 12:58:54 +02:00
win7-7 1ebcc1d7e5 Layout\reftests\table-background\reftest.list should have only additions to the end of it.
Layout\reftests\table-background\reftest.list should have only additions to the end of it. Revert incorrect additions.
2020-04-14 12:58:33 +02:00
win7-7 cbb61ab832 Issue #1355 - Better way to create display items for column backgrounds
Part 1: Remove current table item, as it's never set.

Part 2: Get rid of generic table painting code, and handle each class separately.

Part 4: Hoist outline skipping into col(group) frame code.

Part 5: Skip box-shadow for table column and column groups.

Part 6: Store column and column group backgrounds separately, and then append them before the rest of the table contents.

Part 7: Pass rects in display list coordinates to AppendBackgroundItemsToTop.

Part 8: Create column and column group background display items as part of the cell's BuildDisplayList.

Part 9: Used cached values instead of calling nsDisplayListBuilder::ToReferenceFrame when possible, since it can be expensive when the requested frame isn't the builder's current frame.

Part 10: Make sure we build display items for table parts where only the normal position is visible, since we may need to create background items for ancestors at that position.

Part 11: Create an AutoBuildingDisplayList when we create background items for table columns and column groups, so that we initialize the invalidation state correctly.
2020-04-14 12:58:11 +02:00
Matt A. Tobin cf288a1847 Issue #1053 - Remove android preprocessor directive from toolkit/locales/jar.mn 2020-04-14 12:57:54 +02:00
wolfbeast 0d1eea2ebf Revert #1091 Remove unboxed object code phase 1 + extras.
This should be the last code backout for this. merging this branch
should get us back to the way we were (+ additional code changes for
later changes) as fasr as the unused unboxed code is concerned.
2020-04-14 12:57:32 +02:00
wolfbeast af69cb07db Revert #1137 - Remove unboxed arrays
- accounting for removal of watch()/unwatch()
- updated for intermediate code changes.
2020-04-14 12:57:13 +02:00
wolfbeast dc4695406f Revert "Issue #1382 - Remove invalid assertion."
This reverts commit 9c6a8450b3.
2020-04-14 12:56:56 +02:00
wolfbeast c22a493144 Revert #1142 - Remove unboxed objects
- accounting for removal of watch()/unwatch()
2020-04-14 12:56:40 +02:00
Matt A. Tobin d20ca24a07 Issue #1053 - Remove android support from toolkit
Note: Does not remove support completely from toolkit/mozapps/installer or from telemetry or AppConstants.jsm
2020-04-14 12:56:02 +02:00
Matt A. Tobin b2ca17a298 Bug 1339444 - Remove unused resource://gre/modules/sqlite/sqlite_internal.js 2020-04-14 12:55:48 +02:00
Matt A. Tobin eb70e6e3d0 Issue #439 - Remove tests from toolkit/ 2020-04-14 12:55:19 +02:00
Matt A. Tobin 32ead79529 Issue #1053 - Remove android support from db 2020-04-14 12:55:00 +02:00
Matt A. Tobin 3e59235162 Issue #1053 - Remove android support from docshell 2020-04-14 12:54:47 +02:00
Matt A. Tobin 7494866cb5 Issue #1053 - Remove android support from hal 2020-04-14 12:54:30 +02:00
Matt A. Tobin 19bf63b0ee Issue #1053 - Remove android support from image 2020-04-14 12:54:15 +02:00
Matt A. Tobin 8b539ec9e7 Issue #1053 - Remove android support from intl/locale/nsLocaleService.cpp
This is the only non-icu file with android code in it. Not going to remove android in icu its self because it remains a 3rd party lib.
2020-04-14 12:54:01 +02:00
Matt A. Tobin ba0011606d Follow-up to 4e2e9be6a - Move HeapSnapshot DevTools-only Modules back to DevTools
I am so done with this.

Resolves #316
2020-04-14 12:53:46 +02:00
Matt A. Tobin ec2daa8dc9 Issue #1053 - Remove android support from memory 2020-04-14 12:53:27 +02:00
Matt A. Tobin 44c169c9be Issue #1053 - Remove android support from mfbt 2020-04-14 12:53:13 +02:00
Matt A. Tobin 57383be95d Issue #1053 - Remove android support from ipc except for ipc/chromium
This does not include android in the imported chromium code as specific research needs done on defines and logic.
2020-04-14 12:52:59 +02:00
Matt A. Tobin 6ef03f136b Issue #1053 - Remove android support from mozglue
Yes, I checked for unsaved files this time...
2020-04-14 12:52:45 +02:00
Matt A. Tobin d6bcaa6491 Issue #1053 - Remove android support from netwerk/protocol/http/nsHttpHandler.cpp 2020-04-14 12:52:32 +02:00
Matt A. Tobin 92edec6f58 Issue #1053 - Remove android support from netwerk 2020-04-14 12:52:18 +02:00
Matt A. Tobin 2dea4edfd7 Issue #1053 - Remove android support from storage/mozStorageConnection.cpp 2020-04-14 12:52:05 +02:00
Matt A. Tobin 54cb1b965e Issue #1053 - Remove android support from uriloader 2020-04-14 12:51:52 +02:00
Matt A. Tobin a6d1dd183d Issue #1053 - Remove android support from xpcom/threads/nsThread.cpp
Forgot to save..
2020-04-14 12:51:38 +02:00
Matt A. Tobin da15aa0fdf Issue #1053 - Remove android support from XPCOM 2020-04-14 12:51:25 +02:00
Matt A. Tobin 867737dd4b Remove redundant moz.build from db/ 2020-04-14 12:51:11 +02:00
Matt A. Tobin 36fc5f674e Reclassify heapsnapshot and nsJSInspector as not part of devtools
This resolves Issue #316
2020-04-14 12:50:57 +02:00
wolfbeast 7b30664f59 Set module default identification properly. 2020-04-14 12:50:42 +02:00
wolfbeast ef71f96a8d Remove gtest reference to non-existing path of removed component 2020-04-14 12:50:25 +02:00
wolfbeast 2b99226680 [gfx] Put Skia-specific CTOR init behind Skia-conditional. 2020-04-14 12:50:12 +02:00
wolfbeast 2794f0c48c Issue #316 - Make sure MOZ_DEVTOOLS_SERVER is passed down to js. 2020-04-14 12:49:36 +02:00
Matt A. Tobin 2f23073a3a Issue #1053 - Remove android support from NPAPI 2020-04-14 12:49:22 +02:00
Matt A. Tobin 496fbaf738 Issue #1053 - Remove conditional android code from widget/ 2020-04-14 12:49:08 +02:00
Matt A. Tobin 85621ee9b3 Issue #1053 - Remove Android Widget Toolkit specific files 2020-04-14 12:48:53 +02:00
Matt A. Tobin ee6595e6de Issue #439 - Remove tests from widget/ 2020-04-14 12:48:40 +02:00
wolfbeast 201be4d8fc Issue #316 - Be more gentle with the CC and nursery. 2020-04-14 12:48:23 +02:00
wolfbeast 9e586a1d0e Issue #316 - Pre-process Performance.webidl 2020-04-14 12:48:09 +02:00
wolfbeast 009c9dd2f8 Issue #316 - Make the memory GC performance object conditional (WIP)
This was only added for GCubench and likely interfering with building
without devtools-server.
2020-04-14 12:47:56 +02:00
Matt A. Tobin 6407f1abd4 Issue #1457 - Unfold sqlite3 from nss 2020-04-14 12:47:38 +02:00
wolfbeast 28f0155307 Issue #1383 - Remove "Copy raw data to clipboard" button
This resolves #1383
2020-04-14 12:47:23 +02:00
JustOff 11ede87242 Issue #1445 - Add a link to details on using Firefox extensions in Pale Moon 2020-04-14 12:47:05 +02:00
Matt A. Tobin 3630fec559 Issue #1454 - Add MOZ_PKG_SPECIAL to UpdateUtils 2020-04-14 12:46:46 +02:00
JustOff d062e7311c Issue #1445 - strings cleanup 2020-04-14 12:46:29 +02:00
wolfbeast 0313ac74fd Issue #1445 - remove redundant nativeIndicator
This resolves #1445
2020-04-14 12:46:14 +02:00
Matt A. Tobin 9612c64265 Issue #1320 - Stop appending cpu arch to the end of %BUILD_TARGET% on Windows in UpdateUtils.jsm 2020-04-14 12:45:59 +02:00
wolfbeast c5d570792d Issue #1445 - Use the detailed string also in the list entries. 2020-04-14 12:45:44 +02:00
wolfbeast 10c4e73e56 Issue #1446 - Only match extension add-on types for target applications.
This resolves #1446
2020-04-14 12:45:31 +02:00
win7-7 c9fd86cb78 Issue #1355 - Make nsTableCellFrame::GetColIndex/GetRowIndex faster
We can devirtualize it, remove some branches.
2020-04-14 12:45:15 +02:00
wolfbeast 550d634ff5 Issue #1446 - Only allow extension add-on types for Firefox compat mode. 2020-04-14 12:44:56 +02:00
wolfbeast bbee80fa1c Issue #1445 - Clarify the status of extensions in the Add-On manager
This resolves #1445.
2020-04-14 12:44:41 +02:00
wolfbeast 8ffe533b3d [CSS] Only emit non-GC chrome wrapped XUL box warnings in debug builds. 2020-04-14 12:44:16 +02:00
wolfbeast 9670bdb685 Issue #1441 - Guard appomni/greomni with UXP_CUSTOM_OMNI env var.
This adds an addition to the environment set up for child processes
(plugin container) so that it may still be able to pass the omni
parameters there as-needed.
2020-04-14 12:44:02 +02:00
wolfbeast 8fa80e2c8d Revert "Issue #1441 - Guard appomni/greomni with UXP_CUSTOM_OMNI env var."
This reverts commit 2bdbca39b2.
2020-04-14 12:43:49 +02:00
Simon Giesecke a377d1ecd4 [IndexedDB] Ensure that strong references to newly created cursors are
kept until the DOM Binding is created.

This fixes random crashes on websites that use IndexedDB cursors.
See also BZ bug 1599420
2020-04-14 12:43:34 +02:00
Henri Sivonen 1ebbb0af03 [Parser] Move setting context to null to the correct location. 2020-04-14 12:43:22 +02:00
wolfbeast 29b13d3523 Issue #1441 - Guard appomni/greomni with UXP_CUSTOM_OMNI env var. 2020-04-14 12:43:06 +02:00
sotaro 76476ed75b [Layers] Clear WrappingTextureSourceYCbCrBasic::mTexture correctly 2020-04-14 12:42:53 +02:00
wolfbeast 84fc500ff2 [Network] Bump http channel default Firefox CompatMode init value. 2020-04-14 12:42:38 +02:00
wolfbeast 2560dd2514 Fix a whitespace issue in nsComputedDOMStyle.cpp 2020-04-14 12:42:23 +02:00
wolfbeast 0e2b0db4d7 [CSS] Add stub for font-variation-settings
This stub is added because websites insist on considering this
very hardware-dependent and O.S.-variable low-level font-control
as a "critical feature" which it isn't as there is 0 guarantee
that font variation settings are supported or honored by any
operating system used by the client.

On top this is a WD status feature that sites shouldn't be using, and
the feature itself is strongly discouraged for use in favor of standard
CSS font manipulation keywords like `font-weight`.
2020-04-14 12:42:10 +02:00
wolfbeast c4f65de9b2 [CSP] Allow not having a Port for RessourceURI if the Scheme has no
Default Port
2020-04-14 12:41:57 +02:00
Matt A. Tobin e3148b0a25 Issue #65 - Correct nsHelperAppDlg.js for bad preprocessing conversion 2020-04-14 12:41:44 +02:00
Matt A. Tobin fe6730c219 Issue #80 - Stop building non-generated dom/binding files as UNIFIED_SOURCES
Also fix deprot
2020-04-14 12:41:31 +02:00
Matt A. Tobin 2e44ddb15e Directly assign PrimitiveConversions.h to the generated binding of KeyframeAnimationOptions.
This is a hack to deal UnifiedBindings trying to deal with an incomplete codegen implementation so it was worked around with a hack back in Firefox 30-something. If we have anymore of this non-sense crop up as stuff is added or removed from DOM then extend this conditional.

Least until something better comes along.
2020-04-14 12:41:12 +02:00
win7-7 da74d1f3f3 Issue #1355 - Do less work for columns not in the desired set in PaintRowGroupBackgroundByColIdx
Do less work in PaintRowGroupBackgroundByColIdx for cells that are not in our desired set of columns.

crash fix:

Guard against empty column groups when building a display list for a table.
2020-04-14 12:40:47 +02:00
Matt A. Tobin 91be118376 Issue #65 - Don't split in the middle of assignment statements in createProfileWizard.js 2020-04-14 12:40:06 +02:00
Matt A. Tobin 2258e09d59 Issue #65 - Correct fallthough case in profileSelection.js 2020-04-14 12:39:51 +02:00
Matt A. Tobin 30ec922d7e Issue #65 - Remove AppConstants from toolkit/components/passwordmgr 2020-04-14 12:39:35 +02:00
Matt A. Tobin 1000488a5b Issue #65 - Remove AppConstants from toolkit/components/alerts 2020-04-14 12:39:21 +02:00
Matt A. Tobin ffe75592e3 Issue #65 - Remove AppConstants from toolkit/components/places 2020-04-14 12:39:08 +02:00
Matt A. Tobin 0084e71953 Issue #65 - Remove AppConstants from toolkit/components/apppicker 2020-04-14 12:38:54 +02:00
Matt A. Tobin dbeceecde2 Issue #65 - Remove AppConstants from toolkit/components/thumbnails 2020-04-14 12:38:41 +02:00
Matt A. Tobin 9fc28c55c3 Issue #65 - Remove AppConstants from toolkit/components/printing 2020-04-14 12:38:27 +02:00
Matt A. Tobin 113a825c1f Issue #65 - Remove AppConstants from toolkit/components/satchel 2020-04-14 12:38:14 +02:00
Matt A. Tobin 419abfb09f Issue #65 - Remove AppConstants from toolkit/components/jsdownloads 2020-04-14 12:37:58 +02:00
Matt A. Tobin 4e58dab0a1 Issue #65 - Remove AppConstants from toolkit/mozapps/downloads 2020-04-14 12:37:44 +02:00
Matt A. Tobin 9e42d9ea2f Issue #65 - Remove AppConstants from toolkit/mozapps/extensions 2020-04-14 12:37:29 +02:00
Matt A. Tobin 377f54f3fe Issue #65 - Remove AppConstants from toolkit/mozapps/update 2020-04-14 12:37:16 +02:00
Matt A. Tobin 62f39d829d Issue #65 - Remove AppConstants from toolkit/profile 2020-04-14 12:37:02 +02:00
win7-7 28971524e4 fix whitespace
fix whitespace.
2020-04-14 12:36:29 +02:00
win7-7 be37269123 Issue #1386 - Devirtualize GetRowSpan/GetColSpan
It's at ~1.5% on the perf log for the Netflix use case, which seems a bit too much.
2020-04-14 12:36:12 +02:00
Matt A. Tobin 8acff5cdbe Issue #1395 - Part 2: Remove the rest of FlyWeb 2020-04-14 12:35:06 +02:00
Matt A. Tobin 11a4ab0982 Issue #1395 - Remove FlyWeb Service 2020-04-14 12:31:31 +02:00
Matt A. Tobin 8c41fcd240 Issue #1390 - Get rid of the Presentation API 2020-04-14 12:31:16 +02:00
Matt A. Tobin 27f4e60be8 Issue #1390 - Remove secondscreen modules from toolkit 2020-04-14 12:31:03 +02:00
wolfbeast aae1baabe9 [AM] Remove shared theme leftovers for webextensions 2020-04-14 12:30:49 +02:00
Matt A. Tobin f620afc446 Issue #1392 - Change --enable-eme to MOZ_ARG_ENABLE_BOOL and remove MOZ_EME_MODULES 2020-04-14 12:30:34 +02:00
Moonchild 456f4a5891 Update UXP Coding Style.md
Be more explicit about paranthesis spacing
2020-04-14 12:30:16 +02:00
Moonchild 84d99e2996 Update UXP Coding Style.md
Minor typo
2020-04-14 12:30:03 +02:00
wolfbeast e29301f5d0 Issue #26 - Part 2c: Remove dependence on gmp/widevine-adapter/* 2020-04-14 12:29:44 +02:00
wolfbeast 369ad75fc8 Issue #26 - Part 2b: Stub out GMPDecryptorProxy functions.
If EME isn't built, these functions would have no use and the callback
structures are unavailable. Stubbing these out will still allow the
callers to work unchanged, but in effect simply always return without
dispatching a promised task.
This fixes the dependency issue from part 2a.
2020-04-14 12:29:29 +02:00
wolfbeast 37e3135bc5 Issue #26 Part 2a: make more EME code conditional.
- Exclude missed MediaKey functions and CDMProxy code.
- Exclude EME APIs frm being built (webidl change)
- Fix tests in --disable-eme state
2020-04-14 12:29:16 +02:00
wolfbeast 259bd2e977 [Installer] Updated the 7-zip stub binary to make sure it doesn't hang
on older versions of Windows but instead provides a usable error message
2020-04-14 12:28:34 +02:00
win7-7 0ebdc99757 Issue #1384 - Match standard for colSpan/rowSpan
HTML standardizes proper behavior of colSpan and rowSpan:

The main thing is that getting the .rowSpan and .colSpan IDL properties will now return the actual clamped value that we use.
2020-04-14 12:28:14 +02:00
wolfbeast 68d3bc54fb Issue #1382 - Remove invalid assertion.
There is flexibility in exactly the value the initialized length must
hold, i.e. if an array is completely empty, it is valid for the
initialized length to be any value between zero and the length of the
array, as long as the in-memory values below the initialized length have
been initialized with a hole value.
In the case of 0, the array is packed and the move operation would be a
nop, so simply convert the assert to a condition to save some cycles.
2020-04-14 12:28:00 +02:00
win7-7 2109f36dd4 Issue #1355 - Hit testing in large tables has become extremely slow
Add dirty rect intersection checks so that we don't build unnecessary table part display items.
2020-04-14 12:27:45 +02:00
wolfbeast 58f10adc97 Revert "Issue #1355 - Hit testing in large tables has become extremely slow"
This reverts commit f7b2f0a665.
2020-04-14 12:27:31 +02:00
win7-7 05c68a17a0 Issue #1355 - Hit testing in large tables has become extremely slow
Add dirty rect intersection checks so that we don't build unnecessary table part display items.
2020-04-14 12:27:14 +02:00
New Tobin Paradigm f78958a020 Fix preprocessor directive in UserAgentUpdates.jsm 2020-04-14 12:26:58 +02:00
wolfbeast bcd6c96aec Issue #1378 - Follow-up: make sure background items remain table-aligned. 2020-04-14 12:26:44 +02:00
Matt A. Tobin 73289f5389 Issue #65 - Remove AppConstants from toolkit/modules
Except for secondscreen
2020-04-14 12:26:25 +02:00
Matt A. Tobin 4acc0d58cb Issue #65 - Remove AppConstants from toolkit/content 2020-04-14 12:26:11 +02:00
Matt A. Tobin a1c9dd468d Issue #65 - Remove AppConstants from netwerk/ 2020-04-14 12:25:58 +02:00
Matt A. Tobin 0a5acb852a Issue #65 - Remove AppConstants from mailnews/ 2020-04-14 12:25:45 +02:00
Matt A. Tobin c8bbebe59d Issue #65 - Remove AppConstants from dom/ 2020-04-14 12:25:32 +02:00
wolfbeast fddc35e438 Issue #1378 - Align the drawing of table cell backgrounds with the spec. 2020-04-14 12:22:44 +02:00
Matt A. Tobin 7e4efa4e1f Issue #1377 - Fix porting typo in mailnews/base/search/content/searchWidgets.xml
MailNews Core being historically comm tended to avoid defining shorthand for Components.interfaces
2020-04-14 12:21:51 +02:00
wolfbeast 84b5515a8d Issue #447 - Update HSTS preload list & reduce debug spew
Commented out spewing dump() statements in loops. With the ever growing
HSTS list it takes too much time and is pointless to display.
2020-04-14 12:21:27 +02:00
wolfbeast 6b7fa183dd Issue #1342 - Remove support for system libvpx 2020-04-14 12:21:10 +02:00
wolfbeast a43d59bcbf Issue #1342 - Remove support for system sqlite 2020-04-14 12:20:23 +02:00
wolfbeast ac6896b599 Issue #1342 - Update old.configure for removed build options 2020-04-14 12:20:08 +02:00
wolfbeast 171053d0b2 Issue #1342 - Remove support for system linbpng 2020-04-14 12:19:55 +02:00
win7-7 efd88ee999 Issue #1355 - Speed up the traversal of a table row frame's child cells
Speed up getting the first cellframe in a row and the next cellframe after the given one
2020-04-14 12:19:39 +02:00
wolfbeast 9a74d53315 Issue #1342 - Remove support for system NSPR/NSS 2020-04-14 12:18:35 +02:00
wolfbeast e2a478072a Issue #1342 - Remove support for system ICU 2020-04-14 12:18:21 +02:00
wolfbeast cb06cac81d [WebRequest] Remove AddonManagerPermissions leftovers
This was added as part of the WebExtension sec issue CVE-2017-5389.
Since we no longer have this interface, it needed to be removed to
prevent errors in the WebRequest channel callback.
2020-04-14 12:17:58 +02:00
athenian200 c3d92cd338 Issue #1356 - Add tests.
Forgot to include these before.
2020-04-14 12:17:34 +02:00
athenian200 8ae2267eac Issue #1356 - Restore older syntax.
Some newer Firefox syntax snuck into my last bug. Just to be on the safe side I'm restoring the older syntax here.
2020-04-14 12:16:48 +02:00
athenian200 563dc95cdb Issue #1356 - Remove -moz-user-input disabled to improve event handling. 2020-04-14 12:16:31 +02:00
wolfbeast 7e59ac9036 Issue #1360 - Enable acceleration by default on all known-good platforms. 2020-04-14 12:15:53 +02:00
wolfbeast f1e40aaa5b Issue #1360 - Part 2: Update tests for changed preferences. 2020-04-14 12:14:27 +02:00
wolfbeast 068372c618 Issue #1360 - Part 1: Simplify layers acceleration prefs.
This gets rid of platform-dependent hard-coded defaults, but keeps
build-time blocking if there is no GL provider (in which case layers
acceleration almost certainly won't work because it needs a GL
compositor and would likely crash without)

New prefs are
- layers.acceleration.enabled to enable HWA
- layers.acceleration.force to force it enabled (requires .enabled to be
  set as well)

This is the platform part of this issue. The rest will be front-end work
(Preference UI integration and pref migration)
2020-04-14 12:14:11 +02:00
1842 changed files with 406328 additions and 37817 deletions

No files matched your search

+1 -1
View File
@@ -22,5 +22,5 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Clobber for incremental customElements v1 landing
Clobber for NSS Update
+1 -1
View File
@@ -18,7 +18,7 @@ directory. This will contain relevant documentation regarding contributing,
using and distributing this code and its binaries.
If you are interested in the development and building side of things, some
information will be available on the [Pale Moon developer site](http://developer.palemoon.org).
information will be available on the [Pale Moon developer wiki](http://developer.palemoon.org).
You are also always welcome to get in touch with our community on the [Pale Moon forum](https://forum.palemoon.org/).
### A note about trademarks and branding
+10
View File
@@ -347,6 +347,16 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
eLandmark,
kNoReqStates
},
{ // marquee
&nsGkAtoms::marquee,
roles::ANIMATION,
kUseMapRole,
eNoValue,
eNoAction,
eOffLiveAttr,
kGenericAccType,
kNoReqStates
},
{ // math
&nsGkAtoms::math,
roles::FLAT_EQUATION,
+3
View File
@@ -732,6 +732,8 @@ using namespace mozilla::a11y;
return @"AXDocument";
if (roleAtom == nsGkAtoms::log_)
return @"AXApplicationLog";
if (roleAtom == nsGkAtoms::marquee)
return @"AXApplicationMarquee";
if (roleAtom == nsGkAtoms::math)
return @"AXDocumentMath";
if (roleAtom == nsGkAtoms::note_)
@@ -867,6 +869,7 @@ static const RoleDescrMap sRoleDescrMap[] = {
{ @"AXApplicationAlert", NS_LITERAL_STRING("alert") },
{ @"AXApplicationAlertDialog", NS_LITERAL_STRING("alertDialog") },
{ @"AXApplicationLog", NS_LITERAL_STRING("log") },
{ @"AXApplicationMarquee", NS_LITERAL_STRING("marquee") },
{ @"AXApplicationStatus", NS_LITERAL_STRING("status") },
{ @"AXApplicationTimer", NS_LITERAL_STRING("timer") },
{ @"AXContentSeparator", NS_LITERAL_STRING("separator") },
@@ -62,6 +62,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=558036
testAbsentAttrs("live3", {"live" : ""});
testAttrs("log", {"live" : "polite"}, true);
testAttrs("logAssertive", {"live" : "assertive"}, true);
testAttrs("marquee", {"live" : "off"}, true);
testAttrs("status", {"live" : "polite"}, true);
testAttrs("timer", {"live" : "off"}, true);
testAbsentAttrs("tablist", {"live" : "polite"});
@@ -71,6 +72,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=558036
testAttrs("live2Child", {"container-live" : "polite"}, true);
testAttrs("logChild", {"container-live" : "polite"}, true);
testAttrs("logAssertiveChild", {"container-live" : "assertive"}, true);
testAttrs("marqueeChild", {"container-live" : "off"}, true);
testAttrs("statusChild", {"container-live" : "polite"}, true);
testAttrs("timerChild", {"container-live" : "off"}, true);
testAbsentAttrs("tablistChild", {"container-live" : "polite"});
@@ -78,11 +80,13 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=558036
// container-live-role object attribute
testAttrs("log", {"container-live-role" : "log"}, true);
testAttrs("logAssertive", {"container-live-role" : "log"}, true);
testAttrs("marquee", {"container-live-role" : "marquee"}, true);
testAttrs("status", {"container-live-role" : "status"}, true);
testAttrs("timer", {"container-live-role" : "timer"}, true);
testAttrs("logChild", {"container-live-role" : "log"}, true);
testAttrs("logAssertive", {"container-live-role" : "log"}, true);
testAttrs("logAssertiveChild", {"container-live-role" : "log"}, true);
testAttrs("marqueeChild", {"container-live-role" : "marquee"}, true);
testAttrs("statusChild", {"container-live-role" : "status"}, true);
testAttrs("timerChild", {"container-live-role" : "timer"}, true);
testAbsentAttrs("tablistChild", {"container-live-role" : "tablist"});
@@ -226,9 +230,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=558036
<!-- back to aria -->
<div id="live" aria-live="polite">excuse <div id="liveChild">me</div></div>
<div id="live2" role="marquee" aria-live="polite">excuse <div id="live2Child">me</div></div>
<div id="live3" role="region">excuse</div>
<div id="log" role="log">excuse <div id="logChild">me</div></div>
<div id="logAssertive" role="log" aria-live="assertive">excuse <div id="logAssertiveChild">me</div></div>
<div id="marquee" role="marquee">excuse <div id="marqueeChild">me</div></div>
<div id="status" role="status">excuse <div id="statusChild">me</div></div>
<div id="tablist" role="tablist">tablist <div id="tablistChild">tab</div></div>
<div id="timer" role="timer">excuse <div id="timerChild">me</div></div>
@@ -83,7 +83,7 @@
'listitem-2-3']);
queueTraversalSequence(gQueue, docAcc, TraversalRules.Graphic, null,
['image-1', 'image-2', 'image-3']);
['image-2', 'image-3']);
queueTraversalSequence(gQueue, docAcc, TraversalRules.Link, null,
['link-0', 'link-1', 'link-2', 'link-3']);
@@ -117,7 +117,7 @@
'1. Scheme', '2. Racket', '3. Clojure',
'4. Standard Lisp', 'link-0', ' Lisp',
'checkbox-1-5', ' LeLisp', '• JavaScript',
'heading-5', 'image-1', 'image-2', 'image-3',
'heading-5', 'image-2', 'image-3',
'Not actually an image', 'link-1', 'anchor-1',
'link-2', 'anchor-2', 'link-3', '3', '1', '4',
'1', 'Sunday', 'M', 'Week 1', '3', '4', '7', '2',
@@ -41,6 +41,7 @@
testRole("aria_listbox", ROLE_LISTBOX);
testRole("aria_listitem", ROLE_LISTITEM);
testRole("aria_log", ROLE_TEXT); // weak role
testRole("aria_marquee", ROLE_ANIMATION);
testRole("aria_math", ROLE_FLAT_EQUATION);
testRole("aria_menu", ROLE_MENUPOPUP);
testRole("aria_menubar", ROLE_MENUBAR);
@@ -88,6 +89,9 @@
testRole("log_table", ROLE_TABLE);
testRole("timer_div", ROLE_SECTION);
// other roles that are forms of "live regions"
testRole("marquee_h1", ROLE_ANIMATION);
// strong landmark
testRole("application", ROLE_APPLICATION);
testRole("form", ROLE_FORM);
@@ -215,6 +219,7 @@
<span id="aria_listbox" role="listbox"/>
<span id="aria_listitem" role="listitem"/>
<span id="aria_log" role="log"/>
<span id="aria_marquee" role="marquee"/>
<span id="aria_math" role="math"/>
<span id="aria_menu" role="menu"/>
<span id="aria_menubar" role="menubar"/>
@@ -258,6 +263,7 @@
<table role="log" id="log_table">
<tr><td>Table based log</td></tr>
</table>
<h1 role="marquee" id="marquee_h1">marquee</h1>
<div role="timer" id="timer_div">timer</div>
<!-- landmarks -->
@@ -20,8 +20,8 @@
document.getElementsByTagName("img")[0].firstChild.data = "2";
var accTree = {
role: ROLE_GRAPHIC,
children: []
role: ROLE_TEXT,
children: [ { role: ROLE_TEXT_LEAF } ]
};
testAccessibleTree("the_img", accTree);
SimpleTest.finish();
+1 -1
View File
@@ -38,7 +38,7 @@ if test -n "$USE_ICU"; then
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
if test -z "$JS_STANDALONE" -a "$OS_TARGET" != WINNT -a "$MOZ_WIDGET_TOOLKIT" != "android"; then
MOZ_ICU_DATA_ARCHIVE=1
else
MOZ_ICU_DATA_ARCHIVE=
+5 -4
View File
@@ -436,22 +436,23 @@ nsresult nsChromeRegistry::RefreshWindow(nsPIDOMWindowOuter* aWindow)
NS_ENSURE_SUCCESS(rv, rv);
}
size_t count = document->SheetCount();
int32_t count = document->GetNumberOfStyleSheets();
// Build an array of style sheets we need to reload.
nsTArray<RefPtr<StyleSheet>> oldSheets(count);
nsTArray<RefPtr<StyleSheet>> newSheets(count);
// Iterate over the style sheets.
for (size_t i = 0; i < count; i++) {
for (int32_t i = 0; i < count; i++) {
// Get the style sheet
oldSheets.AppendElement(document->SheetAt(i));
StyleSheet* styleSheet = document->GetStyleSheetAt(i);
oldSheets.AppendElement(styleSheet);
}
// Iterate over our old sheets and kick off a sync load of the new
// sheet if and only if it's a non-inline sheet with a chrome URL.
for (StyleSheet* sheet : oldSheets) {
MOZ_ASSERT(sheet, "SheetAt shouldn't return nullptr for "
MOZ_ASSERT(sheet, "GetStyleSheetAt shouldn't return nullptr for "
"in-range sheet indexes");
nsIURI* uri = sheet->GetSheetURI();
+6
View File
@@ -40,6 +40,12 @@ external_dirs += ['media/libwebp']
if CONFIG['CPU_ARCH'] == 'arm':
external_dirs += ['media/openmax_dl']
if CONFIG['MOZ_WEBSPEECH_POCKETSPHINX']:
external_dirs += [
'media/sphinxbase',
'media/pocketsphinx',
]
if CONFIG['MOZ_FFVPX']:
external_dirs += ['media/ffvpx']
-3
View File
@@ -112,7 +112,6 @@ CERT_GetCertChainFromCert
CERT_GetCertEmailAddress
CERT_GetCertificateDer
CERT_GetCertificateRequestExtensions
CERT_GetCertKeyType
CERT_GetCertTimes
CERT_GetCertTrust
CERT_GetCommonName
@@ -271,7 +270,6 @@ NSS_Init
NSS_Initialize
NSS_InitWithMerge
NSS_IsInitialized
NSS_OptionGet
NSS_OptionSet
NSS_NoDB_Init
NSS_SecureMemcmp
@@ -385,7 +383,6 @@ PK11_GetNextSymKey
PK11_GetPadMechanism
PK11_GetPrivateKeyNickname
PK11_GetPrivateModulusLen
PK11_GetSlotFromPrivateKey
PK11_GetSlotID
PK11_GetSlotInfo
PK11_GetSlotName
+1 -1
View File
@@ -10,4 +10,4 @@
# hardcoded milestones in the tree from these two files.
#--------------------------------------------------------
4.6.0
4.5.0
@@ -33,7 +33,7 @@ function* testTopLeft(inspector, view) {
let afterElement = children.nodes[children.nodes.length - 1];
yield selectNode(afterElement, inspector);
top = getComputedViewPropertyValue(view, "top");
is(top, "96px", "The computed view shows the correct top");
is(top, "50%", "The computed view shows the correct top");
left = getComputedViewPropertyValue(view, "left");
is(left, "96px", "The computed view shows the correct left");
is(left, "50%", "The computed view shows the correct left");
}
-98
View File
@@ -1,98 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "AbortController.h"
#include "AbortSignal.h"
#include "mozilla/dom/AbortControllerBinding.h"
#include "WorkerPrivate.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(AbortController, mGlobal, mSignal)
NS_IMPL_CYCLE_COLLECTING_ADDREF(AbortController)
NS_IMPL_CYCLE_COLLECTING_RELEASE(AbortController)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AbortController)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
/* static */ bool
AbortController::IsEnabled(JSContext* aCx, JSObject* aGlobal)
{
if (NS_IsMainThread()) {
return Preferences::GetBool("dom.abortController.enabled", false);
}
using namespace workers;
// Otherwise, check the pref via the WorkerPrivate
WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(aCx);
if (!workerPrivate) {
return false;
}
return workerPrivate->AbortControllerEnabled();
}
/* static */ already_AddRefed<AbortController>
AbortController::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
if (!global) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
RefPtr<AbortController> abortController = new AbortController(global);
return abortController.forget();
}
AbortController::AbortController(nsIGlobalObject* aGlobal)
: mGlobal(aGlobal)
, mAborted(false)
{}
JSObject*
AbortController::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return AbortControllerBinding::Wrap(aCx, this, aGivenProto);
}
nsIGlobalObject*
AbortController::GetParentObject() const
{
return mGlobal;
}
AbortSignal*
AbortController::Signal()
{
if (!mSignal) {
mSignal = new AbortSignal(this, mAborted);
}
return mSignal;
}
void
AbortController::Abort()
{
if (mAborted) {
return;
}
mAborted = true;
if (mSignal) {
mSignal->Abort();
}
}
} // dom namespace
} // mozilla namespace
-59
View File
@@ -1,59 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_AbortController_h
#define mozilla_dom_AbortController_h
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/AbortSignal.h"
#include "nsCycleCollectionParticipant.h"
#include "nsWrapperCache.h"
#include "mozilla/ErrorResult.h"
#include "nsIGlobalObject.h"
namespace mozilla {
namespace dom {
class AbortController final : public nsISupports
, public nsWrapperCache
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(AbortController)
static bool
IsEnabled(JSContext* aCx, JSObject* aGlobal);
static already_AddRefed<AbortController>
Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
explicit AbortController(nsIGlobalObject* aGlobal);
JSObject*
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
nsIGlobalObject*
GetParentObject() const;
AbortSignal*
Signal();
void
Abort();
private:
~AbortController() = default;
nsCOMPtr<nsIGlobalObject> mGlobal;
RefPtr<AbortSignal> mSignal;
bool mAborted;
};
} // dom namespace
} // mozilla namespace
#endif // mozilla_dom_AbortController_h
-124
View File
@@ -1,124 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "AbortSignal.h"
#include "AbortController.h"
#include "mozilla/dom/Event.h"
#include "mozilla/dom/AbortSignalBinding.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_CLASS(AbortSignal)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(AbortSignal,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mController)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(AbortSignal,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mController)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(AbortSignal)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
NS_IMPL_ADDREF_INHERITED(AbortSignal, DOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(AbortSignal, DOMEventTargetHelper)
AbortSignal::AbortSignal(AbortController* aController,
bool aAborted)
: DOMEventTargetHelper(aController->GetParentObject())
, mController(aController)
, mAborted(aAborted)
{}
AbortSignal::AbortSignal(bool aAborted)
: mAborted(aAborted)
{}
JSObject*
AbortSignal::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return AbortSignalBinding::Wrap(aCx, this, aGivenProto);
}
bool
AbortSignal::Aborted() const
{
return mAborted;
}
void
AbortSignal::Abort()
{
MOZ_ASSERT(!mAborted);
mAborted = true;
// Let's inform the followers.
for (uint32_t i = 0; i < mFollowers.Length(); ++i) {
mFollowers[i]->Aborted();
}
EventInit init;
init.mBubbles = false;
init.mCancelable = false;
RefPtr<Event> event =
Event::Constructor(this, NS_LITERAL_STRING("abort"), init);
event->SetTrusted(true);
bool dummy;
DispatchEvent(event, &dummy);
}
void
AbortSignal::AddFollower(AbortSignal::Follower* aFollower)
{
MOZ_DIAGNOSTIC_ASSERT(aFollower);
if (!mFollowers.Contains(aFollower)) {
mFollowers.AppendElement(aFollower);
}
}
void
AbortSignal::RemoveFollower(AbortSignal::Follower* aFollower)
{
MOZ_DIAGNOSTIC_ASSERT(aFollower);
mFollowers.RemoveElement(aFollower);
}
// AbortSignal::Follower
// ----------------------------------------------------------------------------
AbortSignal::Follower::~Follower()
{
Unfollow();
}
void
AbortSignal::Follower::Follow(AbortSignal* aSignal)
{
MOZ_DIAGNOSTIC_ASSERT(aSignal);
Unfollow();
mFollowingSignal = aSignal;
aSignal->AddFollower(this);
}
void
AbortSignal::Follower::Unfollow()
{
if (mFollowingSignal) {
mFollowingSignal->RemoveFollower(this);
mFollowingSignal = nullptr;
}
}
} // dom namespace
} // mozilla namespace
-76
View File
@@ -1,76 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_AbortSignal_h
#define mozilla_dom_AbortSignal_h
#include "mozilla/DOMEventTargetHelper.h"
namespace mozilla {
namespace dom {
class AbortController;
class AbortSignal;
class AbortSignal final : public DOMEventTargetHelper
{
public:
// This class must be implemented by objects who want to follow a AbortSignal.
class Follower
{
public:
virtual void Aborted() = 0;
protected:
virtual ~Follower();
void
Follow(AbortSignal* aSignal);
void
Unfollow();
RefPtr<AbortSignal> mFollowingSignal;
};
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(AbortSignal, DOMEventTargetHelper)
AbortSignal(AbortController* aController, bool aAborted);
explicit AbortSignal(bool aAborted);
JSObject*
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
bool
Aborted() const;
void
Abort();
IMPL_EVENT_HANDLER(abort);
void
AddFollower(Follower* aFollower);
void
RemoveFollower(Follower* aFollower);
private:
~AbortSignal() = default;
RefPtr<AbortController> mController;
// Raw pointers. Follower unregisters itself in the DTOR.
nsTArray<Follower*> mFollowers;
bool mAborted;
};
} // dom namespace
} // mozilla namespace
#endif // mozilla_dom_AbortSignal_h
-113
View File
@@ -1,113 +0,0 @@
<script>
function ok(a, msg) {
parent.postMessage({ type: "check", status: !!a, message: msg }, "*");
}
function is(a, b, msg) {
ok(a === b, msg);
}
function testWebIDL() {
ok("FetchController" in self, "We have a FetchController prototype");
ok("FetchSignal" in self, "We have a FetchSignal prototype");
var fc = new FetchController();
ok(!!fc, "FetchController can be created");
ok(fc instanceof FetchController, "FetchController is a FetchController");
ok(!!fc.signal, "FetchController has a signal");
ok(fc.signal instanceof FetchSignal, "fetchSignal is a FetchSignal");
is(fc.signal.aborted, false, "By default FetchSignal.aborted is false");
next();
}
function testUpdateData() {
var fc = new FetchController();
is(fc.signal.aborted, false, "By default FetchSignal.aborted is false");
fc.abort();
is(fc.signal.aborted, true, "Signal is aborted");
next();
}
function testAbortEvent() {
var fc = new FetchController();
fc.signal.onabort = function(e) {
is(e.type, "abort", "Abort received");
next();
}
fc.abort();
}
function testAbortedFetch() {
var fc = new FetchController();
fc.abort();
fetch('slow.sjs', { signal: fc.signal }).then(() => {
ok(false, "Fetch should not return a resolved promise");
}, e => {
is(e.name, "AbortError", "We have an abort error");
}).then(next);
}
function testFetchAndAbort() {
var fc = new FetchController();
var p = fetch('slow.sjs', { signal: fc.signal });
fc.abort();
p.then(() => {
ok(false, "Fetch should not return a resolved promise");
}, e => {
is(e.name, "AbortError", "We have an abort error");
}).then(next);
}
function testWorkerAbortedFetch() {
var w = new Worker('worker_fetch_controller.js');
w.onmessage = function(e) {
ok(e.data, "Abort + Fetch works in workers");
next();
}
w.postMessage('testWorkerAbortedFetch');
}
function testWorkerFetchAndAbort() {
var w = new Worker('worker_fetch_controller.js');
w.onmessage = function(e) {
ok(e.data, "Abort + Fetch works in workers");
next();
}
w.postMessage('testWorkerFetchAndAbort');
}
var steps = [
// Simple stuff
testWebIDL,
testUpdateData,
// Event propagation
testAbortEvent,
// fetch + signaling
testAbortedFetch,
testFetchAndAbort,
testWorkerAbortedFetch,
testWorkerFetchAndAbort,
];
function next() {
if (!steps.length) {
parent.postMessage({ type: "finish" }, "*");
return;
}
var step = steps.shift();
step();
}
next();
</script>
-6
View File
@@ -1,6 +0,0 @@
[DEFAULT]
support-files =
file_abort_controller.html
worker_fetch_controller.js
[test_abort_controller.html]
@@ -1,40 +0,0 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE HTML>
<html>
<head>
<title>Test FetchController</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<script class="testbody" type="text/javascript">
SpecialPowers.pushPrefEnv({"set": [["dom.fetchController.enabled", true ]]}, () => {
let ifr = document.createElement('iframe');
ifr.src = "file_fetch_controller.html";
document.body.appendChild(ifr);
onmessage = function(e) {
if (e.data.type == "finish") {
SimpleTest.finish();
return;
}
if (e.data.type == "check") {
ok(e.data.status, e.data.message);
return;
}
ok(false, "Something when wrong.");
}
});
SimpleTest.waitForExplicitFinish();
</script>
</body>
</html>
@@ -1,27 +0,0 @@
function testWorkerAbortedFetch() {
var fc = new AbortController();
fc.abort();
fetch('slow.sjs', { signal: fc.signal }).then(() => {
postMessage(false);
}, e => {
postMessage(e.name == "AbortError");
});
}
function testWorkerFetchAndAbort() {
var fc = new AbortController();
var p = fetch('slow.sjs', { signal: fc.signal });
fc.abort();
p.then(() => {
postMessage(false);
}, e => {
postMessage(e.name == "AbortError");
});
}
onmessage = function(e) {
self[e.data]();
}
+15 -7
View File
@@ -356,16 +356,24 @@ EffectCompositor::GetElementToRestyle(dom::Element* aElement,
return aElement;
}
nsIFrame* primaryFrame = aElement->GetPrimaryFrame();
if (!primaryFrame) {
return nullptr;
}
nsIFrame* pseudoFrame;
if (aPseudoType == CSSPseudoElementType::before) {
return nsLayoutUtils::GetBeforePseudo(aElement);
pseudoFrame = nsLayoutUtils::GetBeforeFrame(primaryFrame);
} else if (aPseudoType == CSSPseudoElementType::after) {
pseudoFrame = nsLayoutUtils::GetAfterFrame(primaryFrame);
} else {
NS_NOTREACHED("Should not try to get the element to restyle for a pseudo "
"other that :before or :after");
return nullptr;
}
if (aPseudoType == CSSPseudoElementType::after) {
return nsLayoutUtils::GetAfterPseudo(aElement);
if (!pseudoFrame) {
return nullptr;
}
NS_NOTREACHED("Should not try to get the element to restyle for a pseudo "
"other that :before or :after");
return nullptr;
return pseudoFrame->GetContent()->AsElement();
}
bool
+7 -5
View File
@@ -1107,17 +1107,19 @@ KeyframeEffectReadOnly::GetAnimationFrame() const
return nullptr;
}
nsIFrame* frame;
nsIFrame* frame = mTarget->mElement->GetPrimaryFrame();
if (!frame) {
return nullptr;
}
if (mTarget->mPseudoType == CSSPseudoElementType::before) {
frame = nsLayoutUtils::GetBeforeFrame(mTarget->mElement);
frame = nsLayoutUtils::GetBeforeFrame(frame);
} else if (mTarget->mPseudoType == CSSPseudoElementType::after) {
frame = nsLayoutUtils::GetAfterFrame(mTarget->mElement);
frame = nsLayoutUtils::GetAfterFrame(frame);
} else {
frame = mTarget->mElement->GetPrimaryFrame();
MOZ_ASSERT(mTarget->mPseudoType == CSSPseudoElementType::NotPseudo,
"unknown mTarget->mPseudoType");
}
if (!frame) {
return nullptr;
}
+2 -2
View File
@@ -71,10 +71,10 @@ ArchiveRequest::~ArchiveRequest()
}
nsresult
ArchiveRequest::GetEventTargetParent(EventChainPreVisitor& aVisitor)
ArchiveRequest::PreHandleEvent(EventChainPreVisitor& aVisitor)
{
aVisitor.mCanHandle = true;
aVisitor.SetParentTarget(nullptr, false);
aVisitor.mParentTarget = nullptr;
return NS_OK;
}
+1 -2
View File
@@ -38,8 +38,7 @@ public:
ArchiveReader* aReader);
// nsIDOMEventTarget
virtual nsresult GetEventTargetParent(
EventChainPreVisitor& aVisitor) override;
virtual nsresult PreHandleEvent(EventChainPreVisitor& aVisitor) override;
public:
// This is called by the DOMArchiveRequestEvent
-27
View File
@@ -7,7 +7,6 @@
#include "AnonymousContent.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/AnonymousContentBinding.h"
#include "nsComputedDOMStyle.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIDocument.h"
#include "nsIDOMHTMLCollection.h"
@@ -209,31 +208,5 @@ AnonymousContent::WrapObject(JSContext* aCx,
return AnonymousContentBinding::Wrap(aCx, this, aGivenProto, aReflector);
}
void
AnonymousContent::GetComputedStylePropertyValue(const nsAString& aElementId,
const nsAString& aPropertyName,
DOMString& aResult,
ErrorResult& aRv)
{
Element* element = GetElementById(aElementId);
if (!element) {
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
return;
}
nsIPresShell* shell = element->OwnerDoc()->GetShell();
if (!shell) {
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
return;
}
RefPtr<nsComputedDOMStyle> cs =
new nsComputedDOMStyle(element,
NS_LITERAL_STRING(""),
element->OwnerDoc(),
nsComputedDOMStyle::eAll);
aRv = cs->GetPropertyValue(aPropertyName, aResult);
}
} // namespace dom
} // namespace mozilla
-5
View File
@@ -68,11 +68,6 @@ public:
const Sequence<OwningNonNull<DOMRect>>& aRects,
ErrorResult& aError);
void GetComputedStylePropertyValue(const nsAString& aElementId,
const nsAString& aPropertyName,
DOMString& aResult,
ErrorResult& aRv);
private:
~AnonymousContent();
nsCOMPtr<Element> mContentNode;
+1 -1
View File
@@ -344,7 +344,7 @@ Attr::RemoveChildAt(uint32_t aIndex, bool aNotify)
}
nsresult
Attr::GetEventTargetParent(EventChainPreVisitor& aVisitor)
Attr::PreHandleEvent(EventChainPreVisitor& aVisitor)
{
aVisitor.mCanHandle = true;
return NS_OK;
+1 -1
View File
@@ -54,7 +54,7 @@ public:
// nsIDOMAttr interface
NS_DECL_NSIDOMATTR
virtual nsresult GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
virtual nsresult PreHandleEvent(EventChainPreVisitor& aVisitor) override;
// nsIAttribute interface
void SetMap(nsDOMAttributeMap *aMap) override;
+2 -2
View File
@@ -4,11 +4,11 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <stdint.h>
#ifndef CORSMode_h_
#define CORSMode_h_
#include <stdint.h>
namespace mozilla {
enum CORSMode : uint8_t {
+179 -122
View File
@@ -6,27 +6,61 @@
#include "ChildIterator.h"
#include "nsContentUtils.h"
#include "mozilla/dom/HTMLSlotElement.h"
#include "mozilla/dom/XBLChildrenElement.h"
#include "mozilla/dom/HTMLContentElement.h"
#include "mozilla/dom/HTMLShadowElement.h"
#include "mozilla/dom/ShadowRoot.h"
#include "nsIAnonymousContentCreator.h"
#include "nsIFrame.h"
#include "nsCSSAnonBoxes.h"
#include "nsDocument.h"
namespace mozilla {
namespace dom {
ExplicitChildIterator::ExplicitChildIterator(const nsIContent* aParent,
bool aStartAtBeginning)
: mParent(aParent),
mChild(nullptr),
mDefaultChild(nullptr),
mIsFirst(aStartAtBeginning),
mIndexInInserted(0)
class MatchedNodes {
public:
explicit MatchedNodes(HTMLContentElement* aInsertionPoint)
: mIsContentElement(true), mContentElement(aInsertionPoint) {}
explicit MatchedNodes(XBLChildrenElement* aInsertionPoint)
: mIsContentElement(false), mChildrenElement(aInsertionPoint) {}
uint32_t Length() const
{
return mIsContentElement ? mContentElement->MatchedNodes().Length()
: mChildrenElement->InsertedChildrenLength();
}
nsIContent* operator[](int32_t aIndex) const
{
return mIsContentElement ? mContentElement->MatchedNodes()[aIndex]
: mChildrenElement->InsertedChild(aIndex);
}
bool IsEmpty() const
{
return mIsContentElement ? mContentElement->MatchedNodes().IsEmpty()
: !mChildrenElement->HasInsertedChildren();
}
protected:
bool mIsContentElement;
union {
HTMLContentElement* mContentElement;
XBLChildrenElement* mChildrenElement;
};
};
static inline MatchedNodes
GetMatchedNodesForPoint(nsIContent* aContent)
{
mParentAsSlot = nsDocument::IsWebComponentsEnabled(mParent) ?
HTMLSlotElement::FromContent(mParent) : nullptr;
if (aContent->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) {
// XBL case
return MatchedNodes(static_cast<XBLChildrenElement*>(aContent));
}
// Web components case
MOZ_ASSERT(aContent->IsHTMLElement(nsGkAtoms::content));
return MatchedNodes(HTMLContentElement::FromContent(aContent));
}
nsIContent*
@@ -35,29 +69,30 @@ ExplicitChildIterator::GetNextChild()
// If we're already in the inserted-children array, look there first
if (mIndexInInserted) {
MOZ_ASSERT(mChild);
MOZ_ASSERT(nsContentUtils::IsContentInsertionPoint(mChild));
MOZ_ASSERT(!mDefaultChild);
if (mParentAsSlot) {
const nsTArray<RefPtr<nsINode>>& assignedNodes =
mParentAsSlot->AssignedNodes();
mChild = (mIndexInInserted < assignedNodes.Length()) ?
assignedNodes[mIndexInInserted++]->AsContent() : nullptr;
return mChild;
}
MOZ_ASSERT(mChild->IsActiveChildrenElement());
auto* childrenElement =
static_cast<XBLChildrenElement*>(mChild);
if (mIndexInInserted < childrenElement->InsertedChildrenLength()) {
return childrenElement->InsertedChild(mIndexInInserted++);
MatchedNodes assignedChildren = GetMatchedNodesForPoint(mChild);
if (mIndexInInserted < assignedChildren.Length()) {
return assignedChildren[mIndexInInserted++];
}
mIndexInInserted = 0;
mChild = mChild->GetNextSibling();
} else if (mShadowIterator) {
// If we're inside of a <shadow> element, look through the
// explicit children of the projected ShadowRoot via
// the mShadowIterator.
nsIContent* nextChild = mShadowIterator->GetNextChild();
if (nextChild) {
return nextChild;
}
mShadowIterator = nullptr;
mChild = mChild->GetNextSibling();
} else if (mDefaultChild) {
// If we're already in default content, check if there are more nodes there
MOZ_ASSERT(mChild);
MOZ_ASSERT(mChild->IsActiveChildrenElement());
MOZ_ASSERT(nsContentUtils::IsContentInsertionPoint(mChild));
mDefaultChild = mDefaultChild->GetNextSibling();
if (mDefaultChild) {
@@ -66,19 +101,6 @@ ExplicitChildIterator::GetNextChild()
mChild = mChild->GetNextSibling();
} else if (mIsFirst) { // at the beginning of the child list
// For slot parent, iterate over assigned nodes if not empty, otherwise
// fall through and iterate over direct children (fallback content).
if (mParentAsSlot) {
const nsTArray<RefPtr<nsINode>>& assignedNodes =
mParentAsSlot->AssignedNodes();
if (!assignedNodes.IsEmpty()) {
mIndexInInserted = 1;
mChild = assignedNodes[0]->AsContent();
mIsFirst = false;
return mChild;
}
}
mChild = mParent->GetFirstChild();
mIsFirst = false;
} else if (mChild) { // in the middle of the child list
@@ -88,16 +110,31 @@ ExplicitChildIterator::GetNextChild()
// Iterate until we find a non-insertion point, or an insertion point with
// content.
while (mChild) {
if (mChild->IsActiveChildrenElement()) {
// If the current child being iterated is a shadow insertion point then
// the iterator needs to go into the projected ShadowRoot.
if (ShadowRoot::IsShadowInsertionPoint(mChild)) {
// Look for the next child in the projected ShadowRoot for the <shadow>
// element.
HTMLShadowElement* shadowElem = HTMLShadowElement::FromContent(mChild);
ShadowRoot* projectedShadow = shadowElem->GetOlderShadowRoot();
if (projectedShadow) {
mShadowIterator = new ExplicitChildIterator(projectedShadow);
nsIContent* nextChild = mShadowIterator->GetNextChild();
if (nextChild) {
return nextChild;
}
mShadowIterator = nullptr;
}
mChild = mChild->GetNextSibling();
} else if (nsContentUtils::IsContentInsertionPoint(mChild)) {
// If the current child being iterated is a content insertion point
// then the iterator needs to return the nodes distributed into
// the content insertion point.
auto* childrenElement =
static_cast<XBLChildrenElement*>(mChild);
if (childrenElement->HasInsertedChildren()) {
MatchedNodes assignedChildren = GetMatchedNodesForPoint(mChild);
if (!assignedChildren.IsEmpty()) {
// Iterate through elements projected on insertion point.
mIndexInInserted = 1;
return childrenElement->InsertedChild(0);
return assignedChildren[0];
}
// Insertion points inside fallback/default content
@@ -155,17 +192,19 @@ FlattenedChildIterator::Init(bool aIgnoreXBL)
}
bool
ExplicitChildIterator::Seek(const nsIContent* aChildToFind)
ExplicitChildIterator::Seek(nsIContent* aChildToFind)
{
if (aChildToFind->GetParent() == mParent &&
!aChildToFind->IsRootOfAnonymousSubtree()) {
// Fast path: just point ourselves to aChildToFind, which is a
// normal DOM child of ours.
mChild = const_cast<nsIContent*>(aChildToFind);
MOZ_ASSERT(!ShadowRoot::IsShadowInsertionPoint(aChildToFind));
MOZ_ASSERT(!nsContentUtils::IsContentInsertionPoint(aChildToFind));
mChild = aChildToFind;
mIndexInInserted = 0;
mShadowIterator = nullptr;
mDefaultChild = nullptr;
mIsFirst = false;
MOZ_ASSERT(!mChild->IsActiveChildrenElement());
return true;
}
@@ -181,18 +220,12 @@ ExplicitChildIterator::Get() const
{
MOZ_ASSERT(!mIsFirst);
// When mParentAsSlot is set, mChild is always set to the current child. It
// does not matter whether mChild is an assigned node or a fallback content.
if (mParentAsSlot) {
return mChild;
}
if (mIndexInInserted) {
MOZ_ASSERT(mChild->IsActiveChildrenElement());
auto* childrenElement = static_cast<XBLChildrenElement*>(mChild);
return childrenElement->InsertedChild(mIndexInInserted - 1);
MatchedNodes assignedChildren = GetMatchedNodesForPoint(mChild);
return assignedChildren[mIndexInInserted - 1];
} else if (mShadowIterator) {
return mShadowIterator->Get();
}
return mDefaultChild ? mDefaultChild : mChild;
}
@@ -201,28 +234,20 @@ ExplicitChildIterator::GetPreviousChild()
{
// If we're already in the inserted-children array, look there first
if (mIndexInInserted) {
if (mParentAsSlot) {
const nsTArray<RefPtr<nsINode>>& assignedNodes =
mParentAsSlot->AssignedNodes();
mChild = (--mIndexInInserted) ?
assignedNodes[mIndexInInserted - 1]->AsContent() : nullptr;
if (!mChild) {
mIsFirst = true;
}
return mChild;
}
// NB: mIndexInInserted points one past the last returned child so we need
// to look *two* indices back in order to return the previous child.
MOZ_ASSERT(mChild->IsActiveChildrenElement());
auto* childrenElement = static_cast<XBLChildrenElement*>(mChild);
MatchedNodes assignedChildren = GetMatchedNodesForPoint(mChild);
if (--mIndexInInserted) {
return childrenElement->InsertedChild(mIndexInInserted - 1);
return assignedChildren[mIndexInInserted - 1];
}
mChild = mChild->GetPreviousSibling();
} else if (mShadowIterator) {
nsIContent* previousChild = mShadowIterator->GetPreviousChild();
if (previousChild) {
return previousChild;
}
mShadowIterator = nullptr;
mChild = mChild->GetPreviousSibling();
} else if (mDefaultChild) {
// If we're already in default content, check if there are more nodes there
mDefaultChild = mDefaultChild->GetPreviousSibling();
@@ -236,32 +261,35 @@ ExplicitChildIterator::GetPreviousChild()
} else if (mChild) { // in the middle of the child list
mChild = mChild->GetPreviousSibling();
} else { // at the end of the child list
// For slot parent, iterate over assigned nodes if not empty, otherwise
// fall through and iterate over direct children (fallback content).
if (mParentAsSlot) {
const nsTArray<RefPtr<nsINode>>& assignedNodes =
mParentAsSlot->AssignedNodes();
if (!assignedNodes.IsEmpty()) {
mIndexInInserted = assignedNodes.Length();
mChild = assignedNodes[mIndexInInserted - 1]->AsContent();
return mChild;
}
}
mChild = mParent->GetLastChild();
}
// Iterate until we find a non-insertion point, or an insertion point with
// content.
while (mChild) {
if (mChild->IsActiveChildrenElement()) {
if (ShadowRoot::IsShadowInsertionPoint(mChild)) {
// If the current child being iterated is a shadow insertion point then
// the iterator needs to go into the projected ShadowRoot.
HTMLShadowElement* shadowElem = HTMLShadowElement::FromContent(mChild);
ShadowRoot* projectedShadow = shadowElem->GetOlderShadowRoot();
if (projectedShadow) {
// Create a ExplicitChildIterator that begins iterating from the end.
mShadowIterator = new ExplicitChildIterator(projectedShadow, false);
nsIContent* previousChild = mShadowIterator->GetPreviousChild();
if (previousChild) {
return previousChild;
}
mShadowIterator = nullptr;
}
mChild = mChild->GetPreviousSibling();
} else if (nsContentUtils::IsContentInsertionPoint(mChild)) {
// If the current child being iterated is a content insertion point
// then the iterator needs to return the nodes distributed into
// the content insertion point.
auto* childrenElement = static_cast<XBLChildrenElement*>(mChild);
if (childrenElement->HasInsertedChildren()) {
mIndexInInserted = childrenElement->InsertedChildrenLength();
return childrenElement->InsertedChild(mIndexInInserted - 1);
MatchedNodes assignedChildren = GetMatchedNodesForPoint(mChild);
if (!assignedChildren.IsEmpty()) {
mIndexInInserted = assignedChildren.Length();
return assignedChildren[mIndexInInserted - 1];
}
mDefaultChild = mChild->GetLastChild();
@@ -289,9 +317,11 @@ AllChildrenIterator::Get() const
{
switch (mPhase) {
case eAtBeforeKid: {
Element* before = nsLayoutUtils::GetBeforePseudo(mOriginalContent);
MOZ_ASSERT(before, "No content before frame at eAtBeforeKid phase");
return before;
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
MOZ_ASSERT(frame, "No frame at eAtBeforeKid phase");
nsIFrame* beforeFrame = nsLayoutUtils::GetBeforeFrame(frame);
MOZ_ASSERT(beforeFrame, "No content before frame at eAtBeforeKid phase");
return beforeFrame->GetContent();
}
case eAtExplicitKids:
@@ -301,9 +331,11 @@ AllChildrenIterator::Get() const
return mAnonKids[mAnonKidsIdx];
case eAtAfterKid: {
Element* after = nsLayoutUtils::GetAfterPseudo(mOriginalContent);
MOZ_ASSERT(after, "No content after frame at eAtAfterKid phase");
return after;
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
MOZ_ASSERT(frame, "No frame at eAtAfterKid phase");
nsIFrame* afterFrame = nsLayoutUtils::GetAfterFrame(frame);
MOZ_ASSERT(afterFrame, "No content before frame at eAtBeforeKid phase");
return afterFrame->GetContent();
}
default:
@@ -313,14 +345,19 @@ AllChildrenIterator::Get() const
bool
AllChildrenIterator::Seek(const nsIContent* aChildToFind)
AllChildrenIterator::Seek(nsIContent* aChildToFind)
{
if (mPhase == eAtBegin || mPhase == eAtBeforeKid) {
mPhase = eAtExplicitKids;
Element* beforePseudo = nsLayoutUtils::GetBeforePseudo(mOriginalContent);
if (beforePseudo && beforePseudo == aChildToFind) {
mPhase = eAtBeforeKid;
return true;
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
if (frame) {
nsIFrame* beforeFrame = nsLayoutUtils::GetBeforeFrame(frame);
if (beforeFrame) {
if (beforeFrame->GetContent() == aChildToFind) {
mPhase = eAtBeforeKid;
return true;
}
}
}
}
@@ -346,10 +383,12 @@ AllChildrenIterator::AppendNativeAnonymousChildren()
// The root scroll frame is not the primary frame of the root element.
// Detect and handle this case.
if (!(mFlags & nsIContent::eSkipDocumentLevelNativeAnonymousContent) &&
mOriginalContent == mOriginalContent->OwnerDoc()->GetRootElement()) {
nsContentUtils::AppendDocumentLevelNativeAnonymousContentTo(
mOriginalContent->OwnerDoc(), mAnonKids);
if (mOriginalContent == mOriginalContent->OwnerDoc()->GetRootElement()) {
nsIPresShell* presShell = mOriginalContent->OwnerDoc()->GetShell();
nsIFrame* scrollFrame = presShell ? presShell->GetRootScrollFrame() : nullptr;
if (scrollFrame) {
AppendNativeAnonymousChildrenFromFrame(scrollFrame);
}
}
}
@@ -367,10 +406,13 @@ AllChildrenIterator::GetNextChild()
{
if (mPhase == eAtBegin) {
mPhase = eAtExplicitKids;
Element* beforeContent = nsLayoutUtils::GetBeforePseudo(mOriginalContent);
if (beforeContent) {
mPhase = eAtBeforeKid;
return beforeContent;
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
if (frame) {
nsIFrame* beforeFrame = nsLayoutUtils::GetBeforeFrame(frame);
if (beforeFrame) {
mPhase = eAtBeforeKid;
return beforeFrame->GetContent();
}
}
}
@@ -406,10 +448,13 @@ AllChildrenIterator::GetNextChild()
return mAnonKids[mAnonKidsIdx];
}
Element* afterContent = nsLayoutUtils::GetAfterPseudo(mOriginalContent);
if (afterContent) {
mPhase = eAtAfterKid;
return afterContent;
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
if (frame) {
nsIFrame* afterFrame = nsLayoutUtils::GetAfterFrame(frame);
if (afterFrame) {
mPhase = eAtAfterKid;
return afterFrame->GetContent();
}
}
}
@@ -423,10 +468,13 @@ AllChildrenIterator::GetPreviousChild()
if (mPhase == eAtEnd) {
MOZ_ASSERT(mAnonKidsIdx == mAnonKids.Length());
mPhase = eAtAnonKids;
Element* afterContent = nsLayoutUtils::GetAfterPseudo(mOriginalContent);
if (afterContent) {
mPhase = eAtAfterKid;
return afterContent;
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
if (frame) {
nsIFrame* afterFrame = nsLayoutUtils::GetAfterFrame(frame);
if (afterFrame) {
mPhase = eAtAfterKid;
return afterFrame->GetContent();
}
}
}
@@ -455,10 +503,13 @@ AllChildrenIterator::GetPreviousChild()
return kid;
}
Element* beforeContent = nsLayoutUtils::GetBeforePseudo(mOriginalContent);
if (beforeContent) {
mPhase = eAtBeforeKid;
return beforeContent;
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
if (frame) {
nsIFrame* beforeFrame = nsLayoutUtils::GetBeforeFrame(frame);
if (beforeFrame) {
mPhase = eAtBeforeKid;
return beforeFrame->GetContent();
}
}
}
@@ -534,6 +585,12 @@ StyleChildrenIterator::IsNeeded(const Element* aElement)
return true;
}
// The root element has a scroll frame that is not the primary frame, so we
// need to do special checking for that case.
if (aElement == aElement->OwnerDoc()->GetRootElement()) {
return true;
}
return false;
}
+36 -41
View File
@@ -36,20 +36,27 @@ class ExplicitChildIterator
{
public:
explicit ExplicitChildIterator(const nsIContent* aParent,
bool aStartAtBeginning = true);
bool aStartAtBeginning = true)
: mParent(aParent),
mChild(nullptr),
mDefaultChild(nullptr),
mIndexInInserted(0),
mIsFirst(aStartAtBeginning)
{
}
ExplicitChildIterator(const ExplicitChildIterator& aOther)
: mParent(aOther.mParent),
mParentAsSlot(aOther.mParentAsSlot),
mChild(aOther.mChild),
: mParent(aOther.mParent), mChild(aOther.mChild),
mDefaultChild(aOther.mDefaultChild),
mShadowIterator(aOther.mShadowIterator ?
new ExplicitChildIterator(*aOther.mShadowIterator) :
nullptr),
mIndexInInserted(aOther.mIndexInInserted), mIsFirst(aOther.mIsFirst) {}
ExplicitChildIterator(ExplicitChildIterator&& aOther)
: mParent(aOther.mParent),
mParentAsSlot(aOther.mParentAsSlot),
mChild(aOther.mChild),
: mParent(aOther.mParent), mChild(aOther.mChild),
mDefaultChild(aOther.mDefaultChild),
mShadowIterator(Move(aOther.mShadowIterator)),
mIndexInInserted(aOther.mIndexInInserted), mIsFirst(aOther.mIsFirst) {}
nsIContent* GetNextChild();
@@ -58,13 +65,13 @@ public:
// found. This version can take shortcuts that the two-argument version
// can't, so can be faster (and in fact can be O(1) instead of O(N) in many
// cases).
bool Seek(const nsIContent* aChildToFind);
bool Seek(nsIContent* aChildToFind);
// Looks for aChildToFind respecting insertion points until aChildToFind is found.
// or aBound is found. If aBound is nullptr then the seek is unbounded. Returns
// whether aChildToFind was found as an explicit child prior to encountering
// aBound.
bool Seek(const nsIContent* aChildToFind, nsIContent* aBound)
bool Seek(nsIContent* aChildToFind, nsIContent* aBound)
{
// It would be nice to assert that we find aChildToFind, but bz thinks that
// we might not find aChildToFind when called from ContentInserted
@@ -95,10 +102,6 @@ protected:
// the <xbl:content> element for the binding.
const nsIContent* mParent;
// If parent is a slot element, this points to the parent as HTMLSlotElement,
// otherwise, it's null.
const HTMLSlotElement* mParentAsSlot;
// The current child. When we encounter an insertion point,
// mChild remains as the insertion point whose content we're iterating (and
// our state is controled by mDefaultChild or mIndexInInserted depending on
@@ -111,6 +114,11 @@ protected:
// to null, we continue iterating at mChild's next sibling.
nsIContent* mDefaultChild;
// If non-null, this points to an iterator of the explicit children of
// the ShadowRoot projected by the current shadow element that we're
// iterating.
nsAutoPtr<ExplicitChildIterator> mShadowIterator;
// If not zero, we're iterating inserted children for an insertion point. This
// is an index into mChild's inserted children array (mChild must be an
// nsXBLChildrenElement). The index is one past the "current" child (as
@@ -131,29 +139,19 @@ class FlattenedChildIterator : public ExplicitChildIterator
public:
explicit FlattenedChildIterator(const nsIContent* aParent,
bool aStartAtBeginning = true)
: ExplicitChildIterator(aParent, aStartAtBeginning)
, mXBLInvolved(false)
, mOriginalContent(aParent)
: ExplicitChildIterator(aParent, aStartAtBeginning), mXBLInvolved(false)
{
Init(false);
}
FlattenedChildIterator(FlattenedChildIterator&& aOther)
: ExplicitChildIterator(Move(aOther))
, mXBLInvolved(aOther.mXBLInvolved)
, mOriginalContent(aOther.mOriginalContent)
{}
: ExplicitChildIterator(Move(aOther)), mXBLInvolved(aOther.mXBLInvolved) {}
FlattenedChildIterator(const FlattenedChildIterator& aOther)
: ExplicitChildIterator(aOther)
, mXBLInvolved(aOther.mXBLInvolved)
, mOriginalContent(aOther.mOriginalContent)
{}
: ExplicitChildIterator(aOther), mXBLInvolved(aOther.mXBLInvolved) {}
bool XBLInvolved() { return mXBLInvolved; }
const nsIContent* Parent() const { return mOriginalContent; }
protected:
/**
* This constructor is a hack to help AllChildrenIterator which sometimes
@@ -161,9 +159,7 @@ protected:
*/
FlattenedChildIterator(const nsIContent* aParent, uint32_t aFlags,
bool aStartAtBeginning = true)
: ExplicitChildIterator(aParent, aStartAtBeginning)
, mXBLInvolved(false)
, mOriginalContent(aParent)
: ExplicitChildIterator(aParent, aStartAtBeginning), mXBLInvolved(false)
{
bool ignoreXBL = aFlags & nsIContent::eAllButXBL;
Init(ignoreXBL);
@@ -174,8 +170,6 @@ protected:
// For certain optimizations, nsCSSFrameConstructor needs to know if the
// child list of the element that we're iterating matches its .childNodes.
bool mXBLInvolved;
const nsIContent* mOriginalContent;
};
/**
@@ -193,11 +187,12 @@ public:
AllChildrenIterator(const nsIContent* aNode, uint32_t aFlags,
bool aStartAtBeginning = true) :
FlattenedChildIterator(aNode, aFlags, aStartAtBeginning),
mAnonKidsIdx(aStartAtBeginning ? UINT32_MAX : 0),
mOriginalContent(aNode), mAnonKidsIdx(aStartAtBeginning ? UINT32_MAX : 0),
mFlags(aFlags), mPhase(aStartAtBeginning ? eAtBegin : eAtEnd) { }
AllChildrenIterator(AllChildrenIterator&& aOther)
: FlattenedChildIterator(Move(aOther)),
mOriginalContent(aOther.mOriginalContent),
mAnonKids(Move(aOther.mAnonKids)), mAnonKidsIdx(aOther.mAnonKidsIdx),
mFlags(aOther.mFlags), mPhase(aOther.mPhase)
#ifdef DEBUG
@@ -216,10 +211,11 @@ public:
// Seeks the given node in children of a parent element, starting from
// the current iterator's position, and sets the iterator at the given child
// node if it was found.
bool Seek(const nsIContent* aChildToFind);
bool Seek(nsIContent* aChildToFind);
nsIContent* GetNextChild();
nsIContent* GetPreviousChild();
const nsIContent* Parent() const { return mOriginalContent; }
enum IteratorPhase
{
@@ -237,6 +233,8 @@ private:
void AppendNativeAnonymousChildren();
void AppendNativeAnonymousChildrenFromFrame(nsIFrame* aFrame);
const nsIContent* mOriginalContent;
// mAnonKids is an array of native anonymous children, mAnonKidsIdx is index
// in the array. If mAnonKidsIdx < mAnonKids.Length() and mPhase is
// eAtAnonKids then the iterator points at a child at mAnonKidsIdx index. If
@@ -258,11 +256,10 @@ private:
/**
* StyleChildrenIterator traverses the children of the element from the
* perspective of the style system, particularly the children we need to traverse
* during restyle. This is identical to AllChildrenIterator with
* (eAllChildren | eSkipDocumentLevelNativeAnonymousContent), _except_ that we
* detect and skip any native anonymous children that are used to implement
* pseudo-elements (since the style system needs to cascade those using
* different algorithms).
* during restyle. This is identical to AllChildrenIterator with eAllChildren,
* _except_ that we detect and skip any native anonymous children that are used
* to implement pseudo-elements (since the style system needs to cascade those
* using different algorithms).
*
* Note: it assumes that no mutation of the DOM or frame tree takes place during
* iteration, and will break horribly if that is not true.
@@ -270,9 +267,7 @@ private:
class StyleChildrenIterator : private AllChildrenIterator {
public:
explicit StyleChildrenIterator(const nsIContent* aContent)
: AllChildrenIterator(aContent,
nsIContent::eAllChildren |
nsIContent::eSkipDocumentLevelNativeAnonymousContent)
: AllChildrenIterator(aContent, nsIContent::eAllChildren)
{
MOZ_COUNT_CTOR(StyleChildrenIterator);
}
-1
View File
@@ -6,7 +6,6 @@
#include "mozilla/dom/ChromeNodeList.h"
#include "mozilla/dom/ChromeNodeListBinding.h"
#include "nsPIDOMWindow.h"
using namespace mozilla;
using namespace mozilla::dom;
-1
View File
@@ -6,7 +6,6 @@
#include "nsCOMArray.h"
#include "nsContentList.h"
#include "nsIDocument.h"
namespace mozilla {
class ErrorResult;
File diff suppressed because it is too large. Load diff
+68 -368
View File
@@ -7,16 +7,13 @@
#ifndef mozilla_dom_CustomElementRegistry_h
#define mozilla_dom_CustomElementRegistry_h
#include "js/GCHashTable.h"
#include "js/TypeDecls.h"
#include "mozilla/Attributes.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/FunctionBinding.h"
#include "mozilla/dom/WebComponentsBinding.h"
#include "nsCycleCollectionParticipant.h"
#include "nsGenericHTMLElement.h"
#include "nsWrapperCache.h"
#include "mozilla/dom/FunctionBinding.h"
class nsDocument;
@@ -25,9 +22,8 @@ namespace dom {
struct CustomElementData;
struct ElementDefinitionOptions;
struct LifecycleCallbacks;
class CallbackFunction;
class CustomElementReaction;
class DocGroup;
class Function;
class Promise;
@@ -36,13 +32,6 @@ struct LifecycleCallbackArgs
nsString name;
nsString oldValue;
nsString newValue;
nsString namespaceURI;
};
struct LifecycleAdoptedCallbackArgs
{
nsCOMPtr<nsIDocument> mOldDocument;
nsCOMPtr<nsIDocument> mNewDocument;
};
class CustomElementCallback
@@ -50,7 +39,8 @@ class CustomElementCallback
public:
CustomElementCallback(Element* aThisObject,
nsIDocument::ElementCallbackType aCallbackType,
CallbackFunction* aCallback);
CallbackFunction* aCallback,
CustomElementData* aOwnerData);
void Traverse(nsCycleCollectionTraversalCallback& aCb) const;
void Call();
void SetArgs(LifecycleCallbackArgs& aArgs)
@@ -60,13 +50,6 @@ public:
mArgs = aArgs;
}
void SetAdoptedCallbackArgs(LifecycleAdoptedCallbackArgs& aAdoptedCallbackArgs)
{
MOZ_ASSERT(mType == nsIDocument::eAdopted,
"Arguments are only used by adopted callback.");
mAdoptedCallbackArgs = aAdoptedCallbackArgs;
}
private:
// The this value to use for invocation of the callback.
RefPtr<Element> mThisObject;
@@ -76,19 +59,9 @@ private:
// Arguments to be passed to the callback,
// used by the attribute changed callback.
LifecycleCallbackArgs mArgs;
LifecycleAdoptedCallbackArgs mAdoptedCallbackArgs;
};
class CustomElementConstructor final : public CallbackFunction
{
public:
explicit CustomElementConstructor(CallbackFunction* aOther)
: CallbackFunction(aOther)
{
MOZ_ASSERT(JS::IsConstructor(mCallback));
}
already_AddRefed<Element> Construct(const char* aExecutionReason, ErrorResult& aRv);
// CustomElementData that contains this callback in the
// callback queue.
CustomElementData* mOwnerData;
};
// Each custom element has an associated callback queue and an element is
@@ -97,299 +70,63 @@ struct CustomElementData
{
NS_INLINE_DECL_REFCOUNTING(CustomElementData)
// https://dom.spec.whatwg.org/#concept-element-custom-element-state
// CustomElementData is only created on the element which is a custom element
// or an upgrade candidate, so the state of an element without
// CustomElementData is "uncustomized".
enum class State {
eUndefined,
eFailed,
eCustom
};
explicit CustomElementData(nsIAtom* aType);
CustomElementData(nsIAtom* aType, State aState);
// Objects in this array are transient and empty after each microtask
// checkpoint.
nsTArray<nsAutoPtr<CustomElementCallback>> mCallbackQueue;
// Custom element type, for <button is="x-button"> or <x-button>
// this would be x-button.
nsCOMPtr<nsIAtom> mType;
// The callback that is next to be processed upon calling RunCallbackQueue.
int32_t mCurrentCallback;
// Element is being created flag as described in the custom elements spec.
bool mElementIsBeingCreated;
// Flag to determine if the created callback has been invoked, thus it
// determines if other callbacks can be enqueued.
bool mCreatedCallbackInvoked;
// The microtask level associated with the callbacks in the callback queue,
// it is used to determine if a new queue needs to be pushed onto the
// processing stack.
int32_t mAssociatedMicroTask;
// Custom element state as described in the custom element spec.
State mState;
// custom element reaction queue as described in the custom element spec.
// There is 1 reaction in reaction queue, when 1) it becomes disconnected,
// 2) it’s adopted into a new document, 3) its attributes are changed,
// appended, removed, or replaced.
// There are 3 reactions in reaction queue when doing upgrade operation,
// e.g., create an element, insert a node.
AutoTArray<UniquePtr<CustomElementReaction>, 3> mReactionQueue;
void SetCustomElementDefinition(CustomElementDefinition* aDefinition);
CustomElementDefinition* GetCustomElementDefinition();
nsIAtom* GetCustomElementType();
void Traverse(nsCycleCollectionTraversalCallback& aCb) const;
void Unlink();
// Empties the callback queue.
void RunCallbackQueue();
private:
virtual ~CustomElementData() {}
// Custom element type, for <button is="x-button"> or <x-button>
// this would be x-button.
RefPtr<nsIAtom> mType;
RefPtr<CustomElementDefinition> mCustomElementDefinition;
};
#define ALEADY_CONSTRUCTED_MARKER nullptr
// The required information for a custom element as defined in:
// https://html.spec.whatwg.org/multipage/scripting.html#custom-element-definition
struct CustomElementDefinition
{
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(CustomElementDefinition)
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(CustomElementDefinition)
CustomElementDefinition(nsIAtom* aType,
nsIAtom* aLocalName,
Function* aConstructor,
nsCOMArray<nsIAtom>&& aObservedAttributes,
JSObject* aConstructor,
JSObject* aPrototype,
mozilla::dom::LifecycleCallbacks* aCallbacks,
uint32_t aDocOrder);
// The type (name) for this custom element, for <button is="x-foo"> or <x-foo>
// this would be x-foo.
// The type (name) for this custom element.
nsCOMPtr<nsIAtom> mType;
// The localname to (e.g. <button is=type> -- this would be button).
nsCOMPtr<nsIAtom> mLocalName;
// The custom element constructor.
RefPtr<CustomElementConstructor> mConstructor;
// The list of attributes that this custom element observes.
nsCOMArray<nsIAtom> mObservedAttributes;
JS::Heap<JSObject *> mConstructor;
// The prototype to use for new custom elements of this type.
JS::Heap<JSObject *> mPrototype;
// The lifecycle callbacks to call for this custom element.
UniquePtr<mozilla::dom::LifecycleCallbacks> mCallbacks;
nsAutoPtr<mozilla::dom::LifecycleCallbacks> mCallbacks;
// A construction stack. Use nullptr to represent an "already constructed marker".
nsTArray<RefPtr<nsGenericHTMLElement>> mConstructionStack;
// A construction stack.
// TODO: Bug 1287348 - Implement construction stack for upgrading an element
// The document custom element order.
uint32_t mDocOrder;
bool IsCustomBuiltIn()
{
return mType != mLocalName;
}
bool IsInObservedAttributeList(nsIAtom* aName)
{
if (mObservedAttributes.IsEmpty()) {
return false;
}
return mObservedAttributes.Contains(aName);
}
private:
~CustomElementDefinition() {}
};
class CustomElementReaction
{
public:
virtual ~CustomElementReaction() = default;
virtual void Invoke(Element* aElement, ErrorResult& aRv) = 0;
virtual void Traverse(nsCycleCollectionTraversalCallback& aCb) const
{
}
#if DEBUG
bool IsUpgradeReaction()
{
return mIsUpgradeReaction;
}
protected:
bool mIsUpgradeReaction = false;
#endif
};
class CustomElementUpgradeReaction final : public CustomElementReaction
{
public:
explicit CustomElementUpgradeReaction(CustomElementDefinition* aDefinition)
: mDefinition(aDefinition)
{
#if DEBUG
mIsUpgradeReaction = true;
#endif
}
private:
virtual void Invoke(Element* aElement, ErrorResult& aRv) override;
CustomElementDefinition* mDefinition;
};
class CustomElementCallbackReaction final : public CustomElementReaction
{
public:
explicit CustomElementCallbackReaction(UniquePtr<CustomElementCallback> aCustomElementCallback)
: mCustomElementCallback(Move(aCustomElementCallback))
{
}
virtual void Traverse(nsCycleCollectionTraversalCallback& aCb) const override
{
mCustomElementCallback->Traverse(aCb);
}
private:
virtual void Invoke(Element* aElement, ErrorResult& aRv) override;
UniquePtr<CustomElementCallback> mCustomElementCallback;
};
// https://html.spec.whatwg.org/multipage/scripting.html#custom-element-reactions-stack
class CustomElementReactionsStack
{
public:
NS_INLINE_DECL_REFCOUNTING(CustomElementReactionsStack)
CustomElementReactionsStack()
: mIsBackupQueueProcessing(false)
, mRecursionDepth(0)
, mIsElementQueuePushedForCurrentRecursionDepth(false)
{
}
// Hold a strong reference of Element so that it does not get cycle collected
// before the reactions in its reaction queue are invoked.
// The element reaction queues are stored in CustomElementData.
// We need to lookup ElementReactionQueueMap again to get relevant reaction queue.
// The choice of 1 for the auto size here is based on gut feeling.
typedef AutoTArray<RefPtr<Element>, 1> ElementQueue;
/**
* Enqueue a custom element upgrade reaction
* https://html.spec.whatwg.org/multipage/scripting.html#enqueue-a-custom-element-upgrade-reaction
*/
void EnqueueUpgradeReaction(Element* aElement,
CustomElementDefinition* aDefinition);
/**
* Enqueue a custom element callback reaction
* https://html.spec.whatwg.org/multipage/scripting.html#enqueue-a-custom-element-callback-reaction
*/
void EnqueueCallbackReaction(Element* aElement,
UniquePtr<CustomElementCallback> aCustomElementCallback);
/**
* [CEReactions] Before executing the algorithm's steps.
* Increase the current recursion depth, and the element queue is pushed
* lazily when we really enqueue reactions.
*
* @return true if the element queue is pushed for "previous" recursion depth.
*/
bool EnterCEReactions()
{
bool temp = mIsElementQueuePushedForCurrentRecursionDepth;
mRecursionDepth++;
// The is-element-queue-pushed flag is initially false when entering a new
// recursion level. The original value will be cached in AutoCEReaction
// and restored after leaving this recursion level.
mIsElementQueuePushedForCurrentRecursionDepth = false;
return temp;
}
/**
* [CEReactions] After executing the algorithm's steps.
* Pop and invoke the element queue if it is created and pushed for current
* recursion depth, then decrease the current recursion depth.
*
* @param aCx JSContext used for handling exception thrown by algorithm's
* steps, this could be a nullptr.
* aWasElementQueuePushed used for restoring status after leaving
* current recursion.
*/
void LeaveCEReactions(JSContext* aCx, bool aWasElementQueuePushed)
{
MOZ_ASSERT(mRecursionDepth);
if (mIsElementQueuePushedForCurrentRecursionDepth) {
Maybe<JS::AutoSaveExceptionState> ases;
if (aCx) {
ases.emplace(aCx);
}
PopAndInvokeElementQueue();
}
mRecursionDepth--;
// Restore the is-element-queue-pushed flag cached in AutoCEReaction when
// leaving the recursion level.
mIsElementQueuePushedForCurrentRecursionDepth = aWasElementQueuePushed;
MOZ_ASSERT_IF(!mRecursionDepth, mReactionsStack.IsEmpty());
}
private:
~CustomElementReactionsStack() {};
/**
* Push a new element queue onto the custom element reactions stack.
*/
void CreateAndPushElementQueue();
/**
* Pop the element queue from the custom element reactions stack, and invoke
* custom element reactions in that queue.
*/
void PopAndInvokeElementQueue();
// The choice of 8 for the auto size here is based on gut feeling.
AutoTArray<UniquePtr<ElementQueue>, 8> mReactionsStack;
ElementQueue mBackupQueue;
// https://html.spec.whatwg.org/#enqueue-an-element-on-the-appropriate-element-queue
bool mIsBackupQueueProcessing;
void InvokeBackupQueue();
/**
* Invoke custom element reactions
* https://html.spec.whatwg.org/multipage/scripting.html#invoke-custom-element-reactions
*/
void InvokeReactions(ElementQueue* aElementQueue, nsIGlobalObject* aGlobal);
void Enqueue(Element* aElement, CustomElementReaction* aReaction);
// Current [CEReactions] recursion depth.
uint32_t mRecursionDepth;
// True if the element queue is pushed into reaction stack for current
// recursion depth. This will be cached in AutoCEReaction when entering a new
// CEReaction recursion and restored after leaving the recursion.
bool mIsElementQueuePushedForCurrentRecursionDepth;
private:
class BackupQueueMicroTask final : public mozilla::MicroTaskRunnable {
public:
explicit BackupQueueMicroTask(CustomElementReactionsStack* aReactionStack)
: MicroTaskRunnable()
, mReactionStack(aReactionStack)
{
MOZ_ASSERT(!mReactionStack->mIsBackupQueueProcessing,
"mIsBackupQueueProcessing should be initially false");
mReactionStack->mIsBackupQueueProcessing = true;
}
virtual void Run(AutoSlowOperation& aAso) override
{
mReactionStack->InvokeBackupQueue();
mReactionStack->mIsBackupQueueProcessing = false;
}
private:
RefPtr<CustomElementReactionsStack> mReactionStack;
};
};
class CustomElementRegistry final : public nsISupports,
@@ -405,34 +142,41 @@ public:
public:
static bool IsCustomElementEnabled(JSContext* aCx = nullptr,
JSObject* aObject = nullptr);
static already_AddRefed<CustomElementRegistry> Create(nsPIDOMWindowInner* aWindow);
static void ProcessTopElementQueue();
explicit CustomElementRegistry(nsPIDOMWindowInner* aWindow);
static void XPCOMShutdown();
/**
* Looking up a custom element definition.
* https://html.spec.whatwg.org/#look-up-a-custom-element-definition
*/
CustomElementDefinition* LookupCustomElementDefinition(
nsIAtom* aNameAtom, nsIAtom* aTypeAtom) const;
CustomElementDefinition* LookupCustomElementDefinition(
JSContext* aCx, JSObject *aConstructor) const;
static void EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType,
Element* aCustomElement,
LifecycleCallbackArgs* aArgs,
LifecycleAdoptedCallbackArgs* aAdoptedCallbackArgs,
CustomElementDefinition* aDefinition);
const nsAString& aLocalName, const nsAString* aIs = nullptr) const;
/**
* Upgrade an element.
* https://html.spec.whatwg.org/multipage/scripting.html#upgrades
* Enqueue created callback or register upgrade candidate for
* newly created custom elements, possibly extending an existing type.
* ex. <x-button>, <button is="x-button> (type extension)
*/
static void Upgrade(Element* aElement, CustomElementDefinition* aDefinition, ErrorResult& aRv);
void SetupCustomElement(Element* aElement, const nsAString* aTypeExtension);
void EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType,
Element* aCustomElement,
LifecycleCallbackArgs* aArgs,
CustomElementDefinition* aDefinition);
void GetCustomPrototype(nsIAtom* aAtom,
JS::MutableHandle<JSObject*> aPrototype);
private:
explicit CustomElementRegistry(nsPIDOMWindowInner* aWindow);
~CustomElementRegistry();
/**
* Registers an unresolved custom element that is a candidate for
* upgrade. |aTypeName| is the name of the custom element type, if it is not
* upgrade when the definition is registered via registerElement.
* |aTypeName| is the name of the custom element type, if it is not
* provided, then element name is used. |aTypeName| should be provided
* when registering a custom element that extends an existing
* element. e.g. <button is="x-button">.
@@ -440,48 +184,23 @@ public:
void RegisterUnresolvedElement(Element* aElement,
nsIAtom* aTypeName = nullptr);
/**
* Unregister an unresolved custom element that is a candidate for
* upgrade when a custom element is removed from tree.
*/
void UnregisterUnresolvedElement(Element* aElement,
nsIAtom* aTypeName = nullptr);
private:
~CustomElementRegistry();
void UpgradeCandidates(JSContext* aCx,
nsIAtom* aKey,
CustomElementDefinition* aDefinition);
static UniquePtr<CustomElementCallback> CreateCustomElementCallback(
nsIDocument::ElementCallbackType aType, Element* aCustomElement,
LifecycleCallbackArgs* aArgs,
LifecycleAdoptedCallbackArgs* aAdoptedCallbackArgs,
CustomElementDefinition* aDefinition);
void UpgradeCandidates(nsIAtom* aKey,
CustomElementDefinition* aDefinition,
ErrorResult& aRv);
typedef nsRefPtrHashtable<nsISupportsHashKey, CustomElementDefinition>
typedef nsClassHashtable<nsISupportsHashKey, CustomElementDefinition>
DefinitionMap;
typedef nsClassHashtable<nsISupportsHashKey, nsTArray<nsWeakPtr>>
CandidateMap;
typedef JS::GCHashMap<JS::Heap<JSObject*>,
nsCOMPtr<nsIAtom>,
js::MovableCellHasher<JS::Heap<JSObject*>>,
js::SystemAllocPolicy> ConstructorMap;
// Hashtable for custom element definitions in web components.
// Custom prototypes are stored in the compartment where definition was
// defined.
// Custom prototypes are stored in the compartment where
// registerElement was called.
DefinitionMap mCustomDefinitions;
// Hashtable for looking up definitions by using constructor as key.
// Custom elements' name are stored here and we need to lookup
// mCustomDefinitions again to get definitions.
ConstructorMap mConstructors;
typedef nsRefPtrHashtable<nsISupportsHashKey, Promise>
WhenDefinedPromiseMap;
WhenDefinedPromiseMap mWhenDefinedPromiseMap;
// The "upgrade candidates map" from the web components spec. Maps from a
// namespace id and local name to a list of elements to upgrade if that
// element is registered as a custom element.
@@ -489,6 +208,14 @@ private:
nsCOMPtr<nsPIDOMWindowInner> mWindow;
// Array representing the processing stack in the custom elements
// specification. The processing stack is conceptually a stack of
// element queues. Each queue is represented by a sequence of
// CustomElementData in this array, separated by nullptr that
// represent the boundaries of the items in the stack. The first
// queue in the stack is the base element queue.
static mozilla::Maybe<nsTArray<RefPtr<CustomElementData>>> sProcessingStack;
// It is used to prevent reentrant invocations of element definition.
bool mIsCustomDefinitionRunning;
@@ -514,8 +241,6 @@ private:
public:
nsISupports* GetParentObject() const;
DocGroup* GetDocGroup() const;
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
void Define(const nsAString& aName, Function& aFunctionConstructor,
@@ -527,31 +252,6 @@ public:
already_AddRefed<Promise> WhenDefined(const nsAString& aName, ErrorResult& aRv);
};
class MOZ_RAII AutoCEReaction final {
public:
// JSContext is allowed to be a nullptr if we are guaranteeing that we're
// not doing something that might throw but not finish reporting a JS
// exception during the lifetime of the AutoCEReaction.
AutoCEReaction(CustomElementReactionsStack* aReactionsStack, JSContext* aCx)
: mReactionsStack(aReactionsStack)
, mCx(aCx)
{
mIsElementQueuePushedForPreviousRecursionDepth =
mReactionsStack->EnterCEReactions();
}
~AutoCEReaction()
{
mReactionsStack->LeaveCEReactions(
mCx, mIsElementQueuePushedForPreviousRecursionDepth);
}
private:
RefPtr<CustomElementReactionsStack> mReactionsStack;
JSContext* mCx;
bool mIsElementQueuePushedForPreviousRecursionDepth;
};
} // namespace dom
} // namespace mozilla
+2 -2
View File
@@ -728,7 +728,7 @@ WalkDescendantsResetAutoDirection(Element* aElement)
{
nsIContent* child = aElement->GetFirstChild();
while (child) {
if (child->IsElement() && child->AsElement()->HasDirAuto()) {
if (child->HasDirAuto()) {
child = child->GetNextNonChildNode(aElement);
continue;
}
@@ -791,7 +791,7 @@ WalkDescendantsClearAncestorDirAuto(Element* aElement)
{
nsIContent* child = aElement->GetFirstChild();
while (child) {
if (child->IsElement() && child->AsElement()->HasDirAuto()) {
if (child->HasDirAuto()) {
child = child->GetNextNonChildNode(aElement);
continue;
}
-28
View File
@@ -1,7 +1,3 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/DocGroup.h"
#include "mozilla/dom/TabGroup.h"
#include "mozilla/Telemetry.h"
@@ -10,14 +6,11 @@
#include "mozilla/StaticPtr.h"
#include "mozilla/ClearOnShutdown.h"
#include "nsIDocShell.h"
#include "nsDOMMutationObserver.h"
#include "nsNetCID.h"
namespace mozilla {
namespace dom {
AutoTArray<RefPtr<DocGroup>, 2>* DocGroup::sPendingDocGroups = nullptr;
/* static */ void
DocGroup::GetKey(nsIPrincipal* aPrincipal, nsACString& aKey)
{
@@ -54,31 +47,10 @@ DocGroup::DocGroup(TabGroup* aTabGroup, const nsACString& aKey)
DocGroup::~DocGroup()
{
MOZ_ASSERT(mDocuments.IsEmpty());
if (!NS_IsMainThread()) {
NS_ReleaseOnMainThread(mReactionsStack.forget());
}
mTabGroup->mDocGroups.RemoveEntry(mKey);
}
NS_IMPL_ISUPPORTS(DocGroup, nsISupports)
void
DocGroup::SignalSlotChange(const HTMLSlotElement* aSlot)
{
if (mSignalSlotList.Contains(aSlot)) {
return;
}
mSignalSlotList.AppendElement(const_cast<HTMLSlotElement*>(aSlot));
if (!sPendingDocGroups) {
// Queue a mutation observer compound microtask.
nsDOMMutationObserver::QueueMutationObserverMicroTask();
sPendingDocGroups = new AutoTArray<RefPtr<DocGroup>, 2>;
}
sPendingDocGroups->AppendElement(this);
}
}
}
+1 -29
View File
@@ -7,6 +7,7 @@
#ifndef DocGroup_h
#define DocGroup_h
#include "nsIDocument.h"
#include "nsISupports.h"
#include "nsISupportsImpl.h"
#include "nsIPrincipal.h"
@@ -14,8 +15,6 @@
#include "nsString.h"
#include "mozilla/RefPtr.h"
#include "mozilla/dom/CustomElementRegistry.h"
#include "mozilla/dom/HTMLSlotElement.h"
namespace mozilla {
namespace dom {
@@ -54,14 +53,6 @@ public:
{
return mTabGroup;
}
mozilla::dom::CustomElementReactionsStack* CustomElementReactionsStack()
{
if (!mReactionsStack) {
mReactionsStack = new mozilla::dom::CustomElementReactionsStack();
}
return mReactionsStack;
}
void RemoveDocument(nsIDocument* aWindow);
// Iterators for iterating over every document within the DocGroup
@@ -74,23 +65,6 @@ public:
return mDocuments.end();
}
// Append aSlot to the list of signal slot list, if it's not in it already
// list, and queue a mutation observer microtask.
void SignalSlotChange(const mozilla::dom::HTMLSlotElement* aSlot);
const nsTArray<RefPtr<HTMLSlotElement>>& SignalSlotList() const
{
return mSignalSlotList;
}
void ClearSignalSlotList()
{
mSignalSlotList.Clear();
}
// List of DocGroups that has non-empty signal slot list.
static AutoTArray<RefPtr<DocGroup>, 2>* sPendingDocGroups;
private:
DocGroup(TabGroup* aTabGroup, const nsACString& aKey);
~DocGroup();
@@ -98,8 +72,6 @@ private:
nsCString mKey;
RefPtr<TabGroup> mTabGroup;
nsTArray<nsIDocument*> mDocuments;
RefPtr<mozilla::dom::CustomElementReactionsStack> mReactionsStack;
nsTArray<RefPtr<HTMLSlotElement>> mSignalSlotList;
};
} // namespace dom
-2
View File
@@ -125,8 +125,6 @@ DocumentFragment::Constructor(const GlobalObject& aGlobal,
return window->GetDoc()->CreateDocumentFragment();
}
NS_IMPL_CYCLE_COLLECTION_INHERITED(DocumentFragment, FragmentOrElement, mHost)
// QueryInterface implementation for DocumentFragment
NS_INTERFACE_MAP_BEGIN(DocumentFragment)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+9 -4
View File
@@ -43,7 +43,6 @@ public:
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DocumentFragment, FragmentOrElement)
// interface nsIDOMNode
NS_FORWARD_NSIDOMNODE_TO_NSINODE
@@ -122,9 +121,15 @@ public:
return nullptr;
}
Element* GetHost() const { return mHost; }
nsIContent* GetHost() const
{
return mHost;
}
void SetHost(Element* aHost) { mHost = aHost; }
void SetHost(nsIContent* aHost)
{
mHost = aHost;
}
static already_AddRefed<DocumentFragment>
Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
@@ -140,7 +145,7 @@ protected:
}
nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const override;
nsCOMPtr<Element> mHost;
nsIContent* mHost; // Weak
};
} // namespace dom
-149
View File
@@ -1,149 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "DocumentOrShadowRoot.h"
#include "mozilla/dom/StyleSheetList.h"
#include "nsDocument.h"
#include "nsFocusManager.h"
#include "ShadowRoot.h"
#include "XULDocument.h"
class nsINode;
class nsIDocument;
class ShadowRoot;
namespace mozilla {
namespace dom {
DocumentOrShadowRoot::DocumentOrShadowRoot(mozilla::dom::ShadowRoot* aShadowRoot)
: mAsNode(aShadowRoot)
, mKind(Kind::ShadowRoot)
{
MOZ_ASSERT(mAsNode);
}
DocumentOrShadowRoot::DocumentOrShadowRoot(nsIDocument* aDoc)
: mAsNode(aDoc)
, mKind(Kind::Document)
{
MOZ_ASSERT(mAsNode);
}
StyleSheetList&
DocumentOrShadowRoot::EnsureDOMStyleSheets()
{
if (!mDOMStyleSheets) {
mDOMStyleSheets = new StyleSheetList(*this);
}
return *mDOMStyleSheets;
}
Element*
DocumentOrShadowRoot::GetElementById(const nsAString& aElementId)
{
if (MOZ_UNLIKELY(aElementId.IsEmpty())) {
nsContentUtils::ReportEmptyGetElementByIdArg(AsNode().OwnerDoc());
return nullptr;
}
if (nsIdentifierMapEntry* entry = mIdentifierMap.GetEntry(aElementId)) {
if (Element* el = entry->GetIdElement()) {
return el;
}
}
if (MOZ_UNLIKELY(mKind == Kind::Document &&
static_cast<nsIDocument&>(AsNode()).IsXULDocument())) {
return static_cast<XULDocument&>(AsNode()).GetRefById(aElementId);
}
return nullptr;
}
already_AddRefed<nsContentList>
DocumentOrShadowRoot::GetElementsByTagNameNS(const nsAString& aNamespaceURI,
const nsAString& aLocalName)
{
ErrorResult rv;
RefPtr<nsContentList> list =
GetElementsByTagNameNS(aNamespaceURI, aLocalName, rv);
if (rv.Failed()) {
return nullptr;
}
return list.forget();
}
already_AddRefed<nsContentList>
DocumentOrShadowRoot::GetElementsByTagNameNS(const nsAString& aNamespaceURI,
const nsAString& aLocalName,
mozilla::ErrorResult& aResult)
{
int32_t nameSpaceId = kNameSpaceID_Wildcard;
if (!aNamespaceURI.EqualsLiteral("*")) {
aResult =
nsContentUtils::NameSpaceManager()->RegisterNameSpace(aNamespaceURI,
nameSpaceId);
if (aResult.Failed()) {
return nullptr;
}
}
NS_ASSERTION(nameSpaceId != kNameSpaceID_Unknown, "Unexpected namespace ID!");
return NS_GetContentList(&AsNode(), nameSpaceId, aLocalName);
}
already_AddRefed<nsContentList>
DocumentOrShadowRoot::GetElementsByClassName(const nsAString& aClasses)
{
return nsContentUtils::GetElementsByClassName(&AsNode(), aClasses);
}
nsIContent*
DocumentOrShadowRoot::Retarget(nsIContent* aContent) const
{
for (nsIContent* cur = aContent;
cur;
cur = cur->GetContainingShadowHost()) {
if (cur->SubtreeRoot() == &AsNode()) {
return cur;
}
}
return nullptr;
}
Element*
DocumentOrShadowRoot::GetRetargetedFocusedElement()
{
if (nsCOMPtr<nsPIDOMWindowOuter> window = AsNode().OwnerDoc()->GetWindow()) {
nsCOMPtr<nsPIDOMWindowOuter> focusedWindow;
nsIContent* focusedContent =
nsFocusManager::GetFocusedDescendant(window,
false,
getter_AddRefs(focusedWindow));
// be safe and make sure the element is from this document
if (focusedContent && focusedContent->OwnerDoc() == AsNode().OwnerDoc()) {
if (focusedContent->ChromeOnlyAccess()) {
focusedContent = focusedContent->FindFirstNonChromeOnlyAccessContent();
}
if (focusedContent) {
if (!nsDocument::IsWebComponentsEnabled(focusedContent)) {
return focusedContent->AsElement();
}
if (nsIContent* retarget = Retarget(focusedContent)) {
return retarget->AsElement();
}
}
}
}
return nullptr;
}
}
}
-160
View File
@@ -1,160 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_DocumentOrShadowRoot_h__
#define mozilla_dom_DocumentOrShadowRoot_h__
#include "nsTArray.h"
#include "nsIdentifierMapEntry.h"
#include "nsContentListDeclarations.h"
#include "nsNameSpaceManager.h"
#include "mozilla/dom/NameSpaceConstants.h"
class nsContentList;
class nsINode;
namespace mozilla {
class StyleSheet;
namespace dom {
class StyleSheetList;
class ShadowRoot;
/**
* A class meant to be shared by ShadowRoot and Document, that holds a list of
* stylesheets.
*
* TODO(emilio, bug 1418159): In the future this should hold most of the
* relevant style state, this should allow us to fix bug 548397.
*/
class DocumentOrShadowRoot
{
enum class Kind {
Document,
ShadowRoot,
};
public:
explicit DocumentOrShadowRoot(nsIDocument*);
explicit DocumentOrShadowRoot(mozilla::dom::ShadowRoot*);
nsINode& AsNode()
{
return *mAsNode;
}
const nsINode& AsNode() const
{
return *mAsNode;
}
StyleSheet* SheetAt(size_t aIndex) const
{
return mStyleSheets.SafeElementAt(aIndex);
}
size_t SheetCount() const
{
return mStyleSheets.Length();
}
int32_t IndexOfSheet(const StyleSheet& aSheet) const
{
return mStyleSheets.IndexOf(&aSheet);
}
void InsertSheetAt(size_t aIndex, StyleSheet& aSheet)
{
mStyleSheets.InsertElementAt(aIndex, &aSheet);
}
void RemoveSheet(StyleSheet& aSheet)
{
mStyleSheets.RemoveElement(&aSheet);
}
void AppendStyleSheet(StyleSheet& aSheet)
{
mStyleSheets.AppendElement(&aSheet);
}
StyleSheetList& EnsureDOMStyleSheets();
Element* GetElementById(const nsAString& aElementId);
/**
* This method returns _all_ the elements in this scope which have id
* aElementId, if there are any. Otherwise it returns null.
*
* This is useful for stuff like QuerySelector optimization and such.
*/
inline const nsTArray<Element*>*
GetAllElementsForId(const nsAString& aElementId) const;
already_AddRefed<nsContentList>
GetElementsByTagName(const nsAString& aTagName)
{
return NS_GetContentList(&AsNode(), kNameSpaceID_Unknown, aTagName);
}
already_AddRefed<nsContentList>
GetElementsByTagNameNS(const nsAString& aNamespaceURI,
const nsAString& aLocalName);
already_AddRefed<nsContentList>
GetElementsByTagNameNS(const nsAString& aNamespaceURI,
const nsAString& aLocalName,
mozilla::ErrorResult&);
already_AddRefed<nsContentList>
GetElementsByClassName(const nsAString& aClasses);
~DocumentOrShadowRoot() = default;
protected:
nsIContent* Retarget(nsIContent* aContent) const;
/**
* If focused element's subtree root is this document or shadow root, return
* focused element, otherwise, get the shadow host recursively until the
* shadow host's subtree root is this document or shadow root.
*/
Element* GetRetargetedFocusedElement();
nsTArray<RefPtr<mozilla::StyleSheet>> mStyleSheets;
RefPtr<mozilla::dom::StyleSheetList> mDOMStyleSheets;
/*
* mIdentifierMap works as follows for IDs:
* 1) Attribute changes affect the table immediately (removing and adding
* entries as needed).
* 2) Removals from the DOM affect the table immediately
* 3) Additions to the DOM always update existing entries for names, and add
* new ones for IDs.
*/
nsTHashtable<nsIdentifierMapEntry> mIdentifierMap;
nsINode* mAsNode;
const Kind mKind;
};
inline const nsTArray<Element*>*
DocumentOrShadowRoot::GetAllElementsForId(const nsAString& aElementId) const
{
if (aElementId.IsEmpty()) {
return nullptr;
}
nsIdentifierMapEntry* entry = mIdentifierMap.GetEntry(aElementId);
return entry ? &entry->GetIdElements() : nullptr;
}
}
}
#endif
+287 -421
View File
File diff suppressed because it is too large. Load diff
+61 -231
View File
@@ -41,7 +41,6 @@
#include "Units.h"
#include "DOMIntersectionObserver.h"
class mozAutoDocUpdate;
class nsIFrame;
class nsIDOMMozNamedAttrMap;
class nsIURI;
@@ -139,12 +138,12 @@ class EventStateManager;
namespace dom {
struct CustomElementDefinition;
class Animation;
class CustomElementRegistry;
class Link;
class DOMRect;
class DOMRectList;
class DestinationInsertionPointList;
class Grid;
// IID for the dom::Element interface
@@ -255,23 +254,6 @@ public:
*/
void ClearStyleStateLocks();
/**
* Accessors for the state of our dir attribute.
*/
bool HasDirAuto() const
{
return State().HasState(NS_EVENT_STATE_DIR_ATTR_LIKE_AUTO);
}
/**
* Elements with dir="rtl" or dir="ltr".
*/
bool HasFixedDir() const
{
return State().HasAtLeastOneOfStates(NS_EVENT_STATE_DIR_ATTR_LTR |
NS_EVENT_STATE_DIR_ATTR_RTL);
}
/**
* Get the inline style declaration, if any, for this element.
*/
@@ -397,48 +379,16 @@ public:
bool GetBindingURL(nsIDocument *aDocument, css::URLValue **aResult);
Directionality GetComputedDirectionality() const;
inline Element* GetFlattenedTreeParentElementForStyle() const;
/**
* Gets the custom element data used by web components custom element.
* Custom element data is created at the first attempt to enqueue a callback.
*
* @return The custom element data or null if none.
*/
inline CustomElementData* GetCustomElementData() const
{
nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
if (slots) {
return slots->mCustomElementData;
}
return nullptr;
// The bdi element defaults to dir=auto if it has no dir attribute set.
// Other elements will only have dir=auto if they have an explicit dir=auto,
// which will mean that HasValidDir() returns true but HasFixedDir() returns
// false
inline bool HasDirAuto() const {
return (!HasFixedDir() &&
(HasValidDir() || IsHTMLElement(nsGkAtoms::bdi)));
}
/**
* Sets the custom element data, ownership of the
* callback data is taken by this element.
*
* @param aData The custom element data.
*/
void SetCustomElementData(CustomElementData* aData);
/**
* Gets the custom element definition used by web components custom element.
*
* @return The custom element definition or null if element is not a custom
* element or custom element is not defined yet.
*/
CustomElementDefinition* GetCustomElementDefinition() const;
/**
* Sets the custom element definition, called when custom element is created
* or upgraded.
*
* @param aDefinition The custom element definition.
*/
void SetCustomElementDefinition(CustomElementDefinition* aDefinition);
Directionality GetComputedDirectionality() const;
protected:
/**
@@ -471,9 +421,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
@@ -512,16 +459,6 @@ protected:
RemoveStatesSilently(aStates);
NotifyStateChange(aStates);
}
virtual void ToggleStates(EventStates aStates, bool aNotify)
{
NS_PRECONDITION(!aStates.HasAtLeastOneOfStates(INTRINSIC_STATES),
"Should only be removing externally-managed states here");
mState ^= aStates;
if (aNotify) {
NotifyStateChange(aStates);
}
}
public:
virtual void UpdateEditableState(bool aNotify) override;
@@ -544,7 +481,6 @@ public:
already_AddRefed<mozilla::dom::NodeInfo>
GetExistingAttrNameFromQName(const nsAString& aStr) const;
MOZ_ALWAYS_INLINE // Avoid a crashy hook from Avast 10 Beta (Bug 1058131)
nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
const nsAString& aValue, bool aNotify)
{
@@ -559,57 +495,25 @@ public:
* values will not actually be compared if we aren't notifying and we don't
* have mutation listeners (in which case it's cheap to just return false
* and let the caller go ahead and set the value).
* @param aOldValue [out] Set to the old value of the attribute, but only if
* there are event listeners. If set, the type of aOldValue will be either
* @param aOldValue Set to the old value of the attribute, but only if there
* are event listeners. If set, the type of aOldValue will be either
* nsAttrValue::eString or nsAttrValue::eAtom.
* @param aModType [out] Set to nsIDOMMutationEvent::MODIFICATION or to
* @param aModType Set to nsIDOMMutationEvent::MODIFICATION or to
* nsIDOMMutationEvent::ADDITION, but only if this helper returns true
* @param aHasListeners [out] Set to true if there are mutation event
* listeners listening for NS_EVENT_BITS_MUTATION_ATTRMODIFIED
* @param aOldValueSet [out] Indicates whether an old attribute value has been
* stored in aOldValue. The bool will be set to true if a value was stored.
* @param aHasListeners Set to true if there are mutation event listeners
* listening for NS_EVENT_BITS_MUTATION_ATTRMODIFIED
*/
bool MaybeCheckSameAttrVal(int32_t aNamespaceID, nsIAtom* aName,
nsIAtom* aPrefix,
const nsAttrValueOrString& aValue,
bool aNotify, nsAttrValue& aOldValue,
uint8_t* aModType, bool* aHasListeners,
bool* aOldValueSet);
/**
* Notifies mutation listeners if aNotify is true, there are mutation
* listeners, and the attribute value is changing.
*
* @param aNamespaceID The namespace of the attribute
* @param aName The local name of the attribute
* @param aPrefix The prefix of the attribute
* @param aValue The value that the attribute is being changed to
* @param aNotify If true, mutation listeners will be notified if they exist
* and the attribute value is changing
* @param aOldValue [out] Set to the old value of the attribute, but only if
* there are event listeners. If set, the type of aOldValue will be either
* nsAttrValue::eString or nsAttrValue::eAtom.
* @param aModType [out] Set to nsIDOMMutationEvent::MODIFICATION or to
* nsIDOMMutationEvent::ADDITION, but only if this helper returns true
* @param aHasListeners [out] Set to true if there are mutation event
* listeners listening for NS_EVENT_BITS_MUTATION_ATTRMODIFIED
* @param aOldValueSet [out] Indicates whether an old attribute value has been
* stored in aOldValue. The bool will be set to true if a value was stored.
*/
uint8_t* aModType, bool* aHasListeners);
bool OnlyNotifySameValueSet(int32_t aNamespaceID, nsIAtom* aName,
nsIAtom* aPrefix,
const nsAttrValueOrString& aValue,
bool aNotify, nsAttrValue& aOldValue,
uint8_t* aModType, bool* aHasListeners,
bool* aOldValueSet);
/**
* Sets the class attribute to a value that contains no whitespace.
* Assumes that we are not notifying and that the attribute hasn't been
* set previously.
*/
nsresult SetSingleClassFromParser(nsIAtom* aSingleClassName);
uint8_t* aModType, bool* aHasListeners);
virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName, nsIAtom* aPrefix,
const nsAString& aValue, bool aNotify) override;
@@ -646,7 +550,7 @@ public:
* guaranteed (e.g. we could have class="").
*/
const nsAttrValue* GetClasses() const {
if (MayHaveClass()) {
if (HasFlag(NODE_MAY_HAVE_CLASS)) {
return DoGetClasses();
}
return nullptr;
@@ -818,25 +722,6 @@ public:
already_AddRefed<nsIHTMLCollection>
GetElementsByClassName(const nsAString& aClassNames);
CSSPseudoElementType GetPseudoElementType() const {
if (!HasProperties()) {
return CSSPseudoElementType::NotPseudo;
}
nsresult rv = NS_OK;
auto raw = GetProperty(nsGkAtoms::pseudoProperty, &rv);
if (rv == NS_PROPTABLE_PROP_NOT_THERE) {
return CSSPseudoElementType::NotPseudo;
}
return CSSPseudoElementType(reinterpret_cast<uintptr_t>(raw));
}
void SetPseudoElementType(CSSPseudoElementType aPseudo) {
static_assert(sizeof(CSSPseudoElementType) <= sizeof(uintptr_t),
"Need to be able to store this in a void*");
MOZ_ASSERT(aPseudo != CSSPseudoElementType::NotPseudo);
SetProperty(nsGkAtoms::pseudoProperty, reinterpret_cast<void*>(aPseudo));
}
private:
/**
* Implement the algorithm specified at
@@ -924,19 +809,12 @@ public:
already_AddRefed<DOMRectList> GetClientRects();
already_AddRefed<DOMRect> GetBoundingClientRect();
// Shadow DOM v1
already_AddRefed<ShadowRoot> AttachShadow(const ShadowRootInit& aInit,
ErrorResult& aError);
ShadowRoot* GetShadowRootByMode() const;
void SetSlot(const nsAString& aName, ErrorResult& aError);
void GetSlot(nsAString& aName);
// [deprecated] Shadow DOM v0
already_AddRefed<ShadowRoot> CreateShadowRoot(ErrorResult& aError);
already_AddRefed<DestinationInsertionPointList> GetDestinationInsertionPoints();
ShadowRoot *FastGetShadowRoot() const
{
nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
nsDOMSlots* slots = GetExistingDOMSlots();
return slots ? slots->mShadowRoot.get() : nullptr;
}
@@ -1322,10 +1200,7 @@ protected:
* its current value) is !StoresOwnData() --- in which
* case the current value is probably already useless.
* If the current value is StoresOwnData() (or absent),
* aOldValue will not be used. aOldValue will only be set
* in certain circumstances (there are mutation
* listeners, element is a custom element, attribute was
* not previously unset). Otherwise it will be null.
* aOldValue will not be used.
* @param aParsedValue parsed new value of attribute. Replaced by the
* old value of the attribute. This old value is only
* useful if either it or the new value is StoresOwnData.
@@ -1334,19 +1209,16 @@ protected:
* @param aFireMutation should mutation-events be fired?
* @param aNotify should we notify document-observers?
* @param aCallAfterSetAttr should we call AfterSetAttr?
* @param aComposedDocument The current composed document of the element.
*/
nsresult SetAttrAndNotify(int32_t aNamespaceID,
nsIAtom* aName,
nsIAtom* aPrefix,
const nsAttrValue* aOldValue,
const nsAttrValue& aOldValue,
nsAttrValue& aParsedValue,
uint8_t aModType,
bool aFireMutation,
bool aNotify,
bool aCallAfterSetAttr,
nsIDocument* aComposedDocument,
const mozAutoDocUpdate& aGuard);
bool aCallAfterSetAttr);
/**
* Scroll to a new position using behavior evaluated from CSS and
@@ -1384,21 +1256,14 @@ protected:
*
* @param aDocument the current document of this node (an optimization)
* @param aName the name of the attribute
* @param aValue the nsAttrValue to set. Will be swapped with the existing
* value of the attribute if the attribute already exists.
* @param [out] aValueWasSet If the attribute was not set previously,
* aValue will be swapped with an empty attribute
* and aValueWasSet will be set to false. Otherwise,
* aValueWasSet will be set to true and aValue will
* contain the previous value set.
* @param aValue the nsAttrValue to set
* @param [out] aRetval the nsresult status of the operation, if any.
* @return true if the setting was attempted, false otherwise.
*/
virtual bool SetAndSwapMappedAttribute(nsIDocument* aDocument,
nsIAtom* aName,
nsAttrValue& aValue,
bool* aValueWasSet,
nsresult* aRetval);
virtual bool SetMappedAttribute(nsIDocument* aDocument,
nsIAtom* aName,
nsAttrValue& aValue,
nsresult* aRetval);
/**
* Hook that is called by Element::SetAttr to allow subclasses to
@@ -1411,92 +1276,33 @@ protected:
* @param aName the localname of the attribute being set
* @param aValue the value it's being set to represented as either a string or
* a parsed nsAttrValue. Alternatively, if the attr is being removed it
* will be null.
* will be null. BeforeSetAttr is allowed to modify aValue by parsing
* the string to an nsAttrValue (to avoid having to reparse it in
* ParseAttribute).
* @param aNotify Whether we plan to notify document observers.
*/
// Note that this is inlined so that when subclasses call it it gets
// inlined. Those calls don't go through a vtable.
virtual nsresult BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
const nsAttrValueOrString* aValue,
nsAttrValueOrString* aValue,
bool aNotify);
/**
* Hook that is called by Element::SetAttr to allow subclasses to
* deal with attribute sets. This will only be called after we have called
* SetAndSwapAttr (that is, after we have actually set the attr). It will
* always be called under a scriptblocker.
* SetAndTakeAttr and AttributeChanged (that is, after we have actually set
* the attr). It will always be called under a scriptblocker.
*
* @param aNamespaceID the namespace of the attr being set
* @param aName the localname of the attribute being set
* @param aValue the value it's being set to. If null, the attr is being
* removed.
* @param aOldValue the value that the attribute had previously. If null,
* the attr was not previously set. This argument may not have the
* correct value for SVG elements, or other cases in which the
* attribute value doesn't store its own data
* @param aNotify Whether we plan to notify document observers.
*/
// Note that this is inlined so that when subclasses call it it gets
// inlined. Those calls don't go through a vtable.
virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
const nsAttrValue* aValue,
const nsAttrValue* aOldValue, bool aNotify)
{
return NS_OK;
}
/**
* This function shall be called just before the id attribute changes. It will
* be called after BeforeSetAttr. If the attribute being changed is not the id
* attribute, this function does nothing. Otherwise, it will remove the old id
* from the document's id cache.
*
* This must happen after BeforeSetAttr (rather than during) because the
* the subclasses' calls to BeforeSetAttr may notify on state changes. If they
* incorrectly determine whether the element had an id, the element may not be
* restyled properly.
*
* @param aNamespaceID the namespace of the attr being set
* @param aName the localname of the attribute being set
* @param aValue the new id value. Will be null if the id is being unset.
*/
void PreIdMaybeChange(int32_t aNamespaceID, nsIAtom* aName,
const nsAttrValueOrString* aValue);
/**
* This function shall be called just after the id attribute changes. It will
* be called before AfterSetAttr. If the attribute being changed is not the id
* attribute, this function does nothing. Otherwise, it will add the new id to
* the document's id cache and properly set the ElementHasID flag.
*
* This must happen before AfterSetAttr (rather than during) because the
* the subclasses' calls to AfterSetAttr may notify on state changes. If they
* incorrectly determine whether the element now has an id, the element may
* not be restyled properly.
*
* @param aNamespaceID the namespace of the attr being set
* @param aName the localname of the attribute being set
* @param aValue the new id value. Will be null if the id is being unset.
*/
void PostIdMaybeChange(int32_t aNamespaceID, nsIAtom* aName,
const nsAttrValue* aValue);
/**
* Usually, setting an attribute to the value that it already has results in
* no action. However, in some cases, setting an attribute to its current
* value should have the effect of, for example, forcing a reload of
* network data. To address that, this function will be called in this
* situation to allow the handling of such a case.
*
* @param aNamespaceID the namespace of the attr being set
* @param aName the localname of the attribute being set
* @param aValue the value it's being set to represented as either a string or
* a parsed nsAttrValue.
* @param aNotify Whether we plan to notify document observers.
*/
// Note that this is inlined so that when subclasses call it it gets
// inlined. Those calls don't go through a vtable.
virtual nsresult OnAttrSetButNotChanged(int32_t aNamespaceID, nsIAtom* aName,
const nsAttrValueOrString& aValue,
bool aNotify)
const nsAttrValue* aValue, bool aNotify)
{
return NS_OK;
}
@@ -1555,7 +1361,7 @@ protected:
/**
* Handle status bar updates before they can be cancelled.
*/
nsresult GetEventTargetParentForLinks(EventChainPreVisitor& aVisitor);
nsresult PreHandleEventForLinks(EventChainPreVisitor& aVisitor);
/**
* Handle default actions for link event if the event isn't consumed yet.
@@ -1615,6 +1421,30 @@ private:
nsCOMPtr<nsIDocument> mDoc;
};
class DestinationInsertionPointList : public nsINodeList
{
public:
explicit DestinationInsertionPointList(Element* aElement);
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DestinationInsertionPointList)
// nsIDOMNodeList
NS_DECL_NSIDOMNODELIST
// nsINodeList
virtual nsIContent* Item(uint32_t aIndex) override;
virtual int32_t IndexOf(nsIContent* aContent) override;
virtual nsINode* GetParentObject() override { return mParent; }
virtual uint32_t Length() const;
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
protected:
virtual ~DestinationInsertionPointList();
RefPtr<Element> mParent;
nsCOMArray<nsIContent> mDestinationPoints;
};
NS_DEFINE_STATIC_IID_ACCESSOR(Element, NS_ELEMENT_IID)
inline bool
-12
View File
@@ -8,7 +8,6 @@
#define mozilla_dom_ElementInlines_h
#include "mozilla/dom/Element.h"
#include "nsIContentInlines.h"
#include "nsIDocument.h"
namespace mozilla {
@@ -26,17 +25,6 @@ Element::UnregisterActivityObserver()
OwnerDoc()->UnregisterActivityObserver(this);
}
inline Element*
Element::GetFlattenedTreeParentElementForStyle() const
{
nsINode* parentNode = GetFlattenedTreeParentNodeForStyle();
if MOZ_LIKELY(parentNode && parentNode->IsElement()) {
return parentNode->AsElement();
}
return nullptr;
}
} // namespace dom
} // namespace mozilla
+157 -222
View File
@@ -123,7 +123,6 @@
#include "mozilla/CORSMode.h"
#include "mozilla/dom/ShadowRoot.h"
#include "mozilla/dom/HTMLSlotElement.h"
#include "mozilla/dom/HTMLTemplateElement.h"
#include "nsStyledElement.h"
@@ -152,56 +151,8 @@ nsIContent::FindFirstNonChromeOnlyAccessContent() const
return nullptr;
}
// https://dom.spec.whatwg.org/#dom-slotable-assignedslot
HTMLSlotElement*
nsIContent::GetAssignedSlotByMode() const
{
/**
* Get slotable's assigned slot for the result of
* find a slot with open flag UNSET [1].
*
* [1] https://dom.spec.whatwg.org/#assign-a-slot
*/
HTMLSlotElement* slot = GetAssignedSlot();
if (!slot) {
return nullptr;
}
MOZ_ASSERT(GetParent());
MOZ_ASSERT(GetParent()->GetShadowRoot());
/**
* Additional check for open flag SET:
* If slotable’s parent’s shadow root's mode is not "open",
* then return null.
*/
if (GetParent()->GetShadowRoot()->IsClosed()) {
return nullptr;
}
return slot;
}
nsINode*
nsIContent::GetFlattenedTreeParentForMaybeAssignedNode() const
{
if (HTMLSlotElement* assignedSlot = GetAssignedSlot()) {
return assignedSlot;
}
HTMLSlotElement* parentSlot = HTMLSlotElement::FromContent(GetParent());
if (!parentSlot) {
return nullptr;
}
// If this is not an unassigned node, then it must be a fallback content.
MOZ_ASSERT(parentSlot->AssignedNodes().IsEmpty());
return parentSlot;
}
nsINode*
nsIContent::GetFlattenedTreeParentNodeInternal(FlattenedParentType aType) const
nsIContent::GetFlattenedTreeParentNodeInternal() const
{
nsINode* parentNode = GetParentNode();
if (!parentNode || !parentNode->IsContent()) {
@@ -210,51 +161,18 @@ nsIContent::GetFlattenedTreeParentNodeInternal(FlattenedParentType aType) const
}
nsIContent* parent = parentNode->AsContent();
if (aType == eForStyle &&
IsRootOfNativeAnonymousSubtree() &&
OwnerDoc()->GetRootElement() == parent) {
// When getting the flattened tree parent for style, we return null
// for any "document level" native anonymous content subtree root.
// This is NAC generated by an ancestor frame of the document element's
// primary frame, and includes scrollbar elements created by the root
// scroll frame, and the "custom content container" and accessible caret
// generated by the nsCanvasFrame. We distinguish document level NAC
// from NAC generated by the root element's primary frame below.
nsIFrame* parentFrame = parent->GetPrimaryFrame();
if (!parentFrame) {
// If the root element has no primary frame, it means it can't have
// generated any NAC itself. Thus any NAC we have here must have
// been generated by an ancestor frame.
//
// If we are in here, then either the root element is display:none, or
// we are in the middle of constructing the root of the frame tree and
// we are trying to eagerly restyle document level NAC in
// nsCSSFrameConstructor::GetAnonymousContent before the root
// element's frame has been constructed.
return nullptr;
}
nsIAnonymousContentCreator* creator = do_QueryFrame(parentFrame);
if (!creator) {
// If the root element does have a frame, but does not implement
// nsIAnonymousContentCreator, then this must be document level NAC.
return nullptr;
}
AutoTArray<nsIContent*, 8> elements;
creator->AppendAnonymousContentTo(elements, 0);
if (!elements.Contains(this)) {
// If the root element does have a frame, and also does implement
// nsIAnonymousContentCreator, but didn't create this node, then
// it must be document level NAC.
return nullptr;
}
}
if (parent && nsContentUtils::HasDistributedChildren(parent) &&
nsContentUtils::IsInSameAnonymousTree(parent, this)) {
return GetFlattenedTreeParentForMaybeAssignedNode();
}
if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
// This node is distributed to insertion points, thus we
// need to consult the destination insertion points list to
// figure out where this node was inserted in the flattened tree.
// It may be the case that |parent| distributes its children
// but the child does not match any insertion points, thus
// the flattened tree parent is nullptr.
nsTArray<nsIContent*>* destInsertionPoints = GetExistingDestInsertionPoints();
parent = destInsertionPoints && !destInsertionPoints->IsEmpty() ?
destInsertionPoints->LastElement()->GetParent() : nullptr;
} else if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
nsIContent* insertionParent = GetXBLInsertionParent();
if (insertionParent) {
parent = insertionParent;
@@ -612,7 +530,8 @@ nsNodeSupportsWeakRefTearoff::GetWeakReference(nsIWeakReference** aInstancePtr)
//----------------------------------------------------------------------
FragmentOrElement::nsDOMSlots::nsDOMSlots()
: nsINode::nsSlots(),
mDataset(nullptr)
mDataset(nullptr),
mBindingParent(nullptr)
{
}
@@ -624,108 +543,84 @@ FragmentOrElement::nsDOMSlots::~nsDOMSlots()
}
void
FragmentOrElement::nsDOMSlots::Traverse(nsCycleCollectionTraversalCallback &cb)
FragmentOrElement::nsDOMSlots::Traverse(nsCycleCollectionTraversalCallback &cb, bool aIsXUL)
{
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mStyle");
cb.NoteXPCOMChild(mStyle.get());
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mSMILOverrideStyle");
cb.NoteXPCOMChild(mSMILOverrideStyle.get());
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mAttributeMap");
cb.NoteXPCOMChild(mAttributeMap.get());
if (aIsXUL) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mControllers");
cb.NoteXPCOMChild(mControllers);
}
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mXBLBinding");
cb.NoteNativeChild(mXBLBinding, NS_CYCLE_COLLECTION_PARTICIPANT(nsXBLBinding));
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mXBLInsertionParent");
cb.NoteXPCOMChild(mXBLInsertionParent.get());
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mShadowRoot");
cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mShadowRoot));
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mContainingShadow");
cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mContainingShadow));
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mChildrenList");
cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMNodeList*, mChildrenList));
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mLabelsList");
cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMNodeList*, mLabelsList));
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mClassList");
cb.NoteXPCOMChild(mClassList.get());
if (!mExtendedSlots) {
return;
if (mCustomElementData) {
for (uint32_t i = 0; i < mCustomElementData->mCallbackQueue.Length(); i++) {
mCustomElementData->mCallbackQueue[i]->Traverse(cb);
}
}
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mSMILOverrideStyle");
cb.NoteXPCOMChild(mExtendedSlots->mSMILOverrideStyle.get());
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mControllers");
cb.NoteXPCOMChild(mExtendedSlots->mControllers);
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mLabelsList");
cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMNodeList*,mExtendedSlots-> mLabelsList));
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mShadowRoot");
cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mExtendedSlots->mShadowRoot));
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mContainingShadow");
cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mExtendedSlots->mContainingShadow));
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mAssignedSlot");
cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mExtendedSlots->mAssignedSlot.get()));
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mXBLBinding");
cb.NoteNativeChild(mExtendedSlots->mXBLBinding,
NS_CYCLE_COLLECTION_PARTICIPANT(nsXBLBinding));
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mXBLInsertionParent");
cb.NoteXPCOMChild(mExtendedSlots->mXBLInsertionParent.get());
if (mExtendedSlots->mCustomElementData) {
mExtendedSlots->mCustomElementData->Traverse(cb);
}
for (auto iter = mExtendedSlots->mRegisteredIntersectionObservers.Iter();
!iter.Done(); iter.Next()) {
for (auto iter = mRegisteredIntersectionObservers.Iter(); !iter.Done(); iter.Next()) {
DOMIntersectionObserver* observer = iter.Key();
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
"mExtendedSlots->mRegisteredIntersectionObservers[i]");
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mRegisteredIntersectionObservers[i]");
cb.NoteXPCOMChild(observer);
}
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mFrameLoaderOrOpener");
cb.NoteXPCOMChild(mExtendedSlots->mFrameLoaderOrOpener);
}
void
FragmentOrElement::nsDOMSlots::Unlink()
FragmentOrElement::nsDOMSlots::Unlink(bool aIsXUL)
{
mStyle = nullptr;
mSMILOverrideStyle = nullptr;
if (mAttributeMap) {
mAttributeMap->DropReference();
mAttributeMap = nullptr;
}
if (aIsXUL)
NS_IF_RELEASE(mControllers);
MOZ_ASSERT(!mXBLBinding);
mXBLInsertionParent = nullptr;
mShadowRoot = nullptr;
mContainingShadow = nullptr;
mChildrenList = nullptr;
mLabelsList = nullptr;
mCustomElementData = nullptr;
mClassList = nullptr;
if (!mExtendedSlots) {
return;
}
mExtendedSlots->mSMILOverrideStyle = nullptr;
mExtendedSlots->mControllers = nullptr;
mExtendedSlots->mLabelsList = nullptr;
mExtendedSlots->mShadowRoot = nullptr;
mExtendedSlots->mContainingShadow = nullptr;
mExtendedSlots->mAssignedSlot = nullptr;
MOZ_ASSERT(!(mExtendedSlots->mXBLBinding));
mExtendedSlots->mXBLInsertionParent = nullptr;
if (mExtendedSlots->mCustomElementData) {
mExtendedSlots->mCustomElementData->Unlink();
mExtendedSlots->mCustomElementData = nullptr;
}
mExtendedSlots->mRegisteredIntersectionObservers.Clear();
nsCOMPtr<nsIFrameLoader> frameLoader =
do_QueryInterface(mExtendedSlots->mFrameLoaderOrOpener);
if (frameLoader) {
static_cast<nsFrameLoader*>(frameLoader.get())->Destroy();
}
mExtendedSlots->mFrameLoaderOrOpener = nullptr;
mRegisteredIntersectionObservers.Clear();
}
size_t
FragmentOrElement::nsDOMSlots::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
{
size_t n = aMallocSizeOf(this);
if (mExtendedSlots) {
n += aMallocSizeOf(mExtendedSlots.get());
}
if (mAttributeMap) {
n += mAttributeMap->SizeOfIncludingThis(aMallocSizeOf);
@@ -746,19 +641,6 @@ FragmentOrElement::nsDOMSlots::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) c
return n;
}
FragmentOrElement::nsExtendedDOMSlots::nsExtendedDOMSlots()
: mBindingParent(nullptr)
{
}
FragmentOrElement::nsExtendedDOMSlots::~nsExtendedDOMSlots()
{
nsCOMPtr<nsIFrameLoader> frameLoader = do_QueryInterface(mFrameLoaderOrOpener);
if (frameLoader) {
static_cast<nsFrameLoader*>(frameLoader.get())->Destroy();
}
}
FragmentOrElement::FragmentOrElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
: nsIContent(aNodeInfo)
{
@@ -804,7 +686,7 @@ FindChromeAccessOnlySubtreeOwner(nsIContent* aContent)
}
nsresult
nsIContent::GetEventTargetParent(EventChainPreVisitor& aVisitor)
nsIContent::PreHandleEvent(EventChainPreVisitor& aVisitor)
{
//FIXME! Document how this event retargeting works, Bug 329124.
aVisitor.mCanHandle = true;
@@ -813,7 +695,6 @@ nsIContent::GetEventTargetParent(EventChainPreVisitor& aVisitor)
// Don't propagate mouseover and mouseout events when mouse is moving
// inside chrome access only content.
bool isAnonForEvents = IsRootOfChromeAccessOnlySubtree();
aVisitor.mRootOfClosedTree = isAnonForEvents;
if ((aVisitor.mEvent->mMessage == eMouseOver ||
aVisitor.mEvent->mMessage == eMouseOut ||
aVisitor.mEvent->mMessage == ePointerOver ||
@@ -825,7 +706,7 @@ nsIContent::GetEventTargetParent(EventChainPreVisitor& aVisitor)
((this == aVisitor.mEvent->mOriginalTarget &&
!ChromeOnlyAccess()) || isAnonForEvents || GetShadowRoot())) {
nsCOMPtr<nsIContent> relatedTarget =
do_QueryInterface(aVisitor.mEvent->AsMouseEvent()->mRelatedTarget);
do_QueryInterface(aVisitor.mEvent->AsMouseEvent()->relatedTarget);
if (relatedTarget &&
relatedTarget->OwnerDoc() == OwnerDoc()) {
@@ -835,7 +716,7 @@ nsIContent::GetEventTargetParent(EventChainPreVisitor& aVisitor)
nsIContent* adjustedTarget =
Event::GetShadowRelatedTarget(this, relatedTarget);
if (this == adjustedTarget) {
aVisitor.SetParentTarget(nullptr, false);
aVisitor.mParentTarget = nullptr;
aVisitor.mCanHandle = false;
return NS_OK;
}
@@ -892,7 +773,7 @@ nsIContent::GetEventTargetParent(EventChainPreVisitor& aVisitor)
originalTarget->FindFirstNonChromeOnlyAccessContent())
? "" : "Wrong event propagation!?!\n");
#endif
aVisitor.SetParentTarget(nullptr, false);
aVisitor.mParentTarget = nullptr;
// Event should not propagate to non-anon content.
aVisitor.mCanHandle = isAnonForEvents;
return NS_OK;
@@ -903,10 +784,58 @@ nsIContent::GetEventTargetParent(EventChainPreVisitor& aVisitor)
}
}
// Event parent is the assigned slot, if node is assigned, or node's parent
// otherwise.
HTMLSlotElement* slot = GetAssignedSlot();
nsIContent* parent = slot ? slot : GetParent();
nsIContent* parent = GetParent();
// Web components have a special event chain that need to account
// for destination insertion points where nodes have been distributed.
nsTArray<nsIContent*>* destPoints = GetExistingDestInsertionPoints();
if (destPoints && !destPoints->IsEmpty()) {
// Push destination insertion points to aVisitor.mDestInsertionPoints
// excluding shadow insertion points.
bool didPushNonShadowInsertionPoint = false;
for (uint32_t i = 0; i < destPoints->Length(); i++) {
nsIContent* point = destPoints->ElementAt(i);
if (!ShadowRoot::IsShadowInsertionPoint(point)) {
aVisitor.mDestInsertionPoints.AppendElement(point);
didPushNonShadowInsertionPoint = true;
}
}
// Next node in the event path is the final destination
// (non-shadow) insertion point that was pushed.
if (didPushNonShadowInsertionPoint) {
parent = aVisitor.mDestInsertionPoints.LastElement();
aVisitor.mDestInsertionPoints.SetLength(
aVisitor.mDestInsertionPoints.Length() - 1);
}
}
ShadowRoot* thisShadowRoot = ShadowRoot::FromNode(this);
if (thisShadowRoot) {
if (!aVisitor.mEvent->mFlags.mComposed) {
// If we do stop propagation, we still want to propagate
// the event to chrome (nsPIDOMWindow::GetParentTarget()).
// The load event is special in that we don't ever propagate it
// to chrome.
nsCOMPtr<nsPIDOMWindowOuter> win = OwnerDoc()->GetWindow();
EventTarget* parentTarget = win && aVisitor.mEvent->mMessage != eLoad
? win->GetParentTarget() : nullptr;
aVisitor.mParentTarget = parentTarget;
return NS_OK;
}
if (!aVisitor.mDestInsertionPoints.IsEmpty()) {
parent = aVisitor.mDestInsertionPoints.LastElement();
aVisitor.mDestInsertionPoints.SetLength(
aVisitor.mDestInsertionPoints.Length() - 1);
} else {
// The pool host for the youngest shadow root is shadow DOM host,
// for older shadow roots, it is the shadow insertion point
// where the shadow root is projected, nullptr if none exists.
parent = thisShadowRoot->GetPoolHost();
}
}
// Event may need to be retargeted if this is the root of a native
// anonymous content subtree or event is dispatched somewhere inside XBL.
@@ -944,17 +873,11 @@ nsIContent::GetEventTargetParent(EventChainPreVisitor& aVisitor)
if (!aVisitor.mEvent->mFlags.mComposedInNativeAnonymousContent &&
IsRootOfNativeAnonymousSubtree() && OwnerDoc() &&
OwnerDoc()->GetWindow()) {
aVisitor.SetParentTarget(OwnerDoc()->GetWindow()->GetParentTarget(), true);
aVisitor.mParentTarget = OwnerDoc()->GetWindow()->GetParentTarget();
} else if (parent) {
aVisitor.SetParentTarget(parent, false);
if (slot) {
ShadowRoot* root = slot->GetContainingShadow();
if (root && root->IsClosed()) {
aVisitor.mParentIsSlotInClosedTree = true;
}
}
aVisitor.mParentTarget = parent;
} else {
aVisitor.SetParentTarget(GetComposedDoc(), false);
aVisitor.mParentTarget = GetComposedDoc();
}
return NS_OK;
}
@@ -1039,7 +962,7 @@ FragmentOrElement::IsLink(nsIURI** aURI) const
nsIContent*
FragmentOrElement::GetBindingParent() const
{
nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
nsDOMSlots *slots = GetExistingDOMSlots();
if (slots) {
return slots->mBindingParent;
@@ -1051,7 +974,7 @@ nsXBLBinding*
FragmentOrElement::GetXBLBinding() const
{
if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
nsDOMSlots *slots = GetExistingDOMSlots();
if (slots) {
return slots->mXBLBinding;
}
@@ -1086,11 +1009,11 @@ FragmentOrElement::SetXBLBinding(nsXBLBinding* aBinding,
if (aBinding) {
SetFlags(NODE_MAY_BE_IN_BINDING_MNGR);
nsExtendedDOMSlots* slots = ExtendedDOMSlots();
nsDOMSlots *slots = DOMSlots();
slots->mXBLBinding = aBinding;
bindingManager->AddBoundContent(this);
} else {
nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
nsDOMSlots *slots = GetExistingDOMSlots();
if (slots) {
slots->mXBLBinding = nullptr;
}
@@ -1105,7 +1028,7 @@ nsIContent*
FragmentOrElement::GetXBLInsertionParent() const
{
if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
nsDOMSlots *slots = GetExistingDOMSlots();
if (slots) {
return slots->mXBLInsertionParent;
}
@@ -1117,7 +1040,7 @@ FragmentOrElement::GetXBLInsertionParent() const
ShadowRoot*
FragmentOrElement::GetContainingShadow() const
{
nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
nsDOMSlots *slots = GetExistingDOMSlots();
if (slots) {
return slots->mContainingShadow;
}
@@ -1127,48 +1050,60 @@ FragmentOrElement::GetContainingShadow() const
void
FragmentOrElement::SetShadowRoot(ShadowRoot* aShadowRoot)
{
nsExtendedDOMSlots* slots = ExtendedDOMSlots();
nsDOMSlots *slots = DOMSlots();
slots->mShadowRoot = aShadowRoot;
}
HTMLSlotElement*
FragmentOrElement::GetAssignedSlot() const
nsTArray<nsIContent*>&
FragmentOrElement::DestInsertionPoints()
{
nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
return slots ? slots->mAssignedSlot.get() : nullptr;
nsDOMSlots *slots = DOMSlots();
return slots->mDestInsertionPoints;
}
nsIContent*
nsIContent::GetContainingShadowHost() const
nsTArray<nsIContent*>*
FragmentOrElement::GetExistingDestInsertionPoints() const
{
if (mozilla::dom::ShadowRoot* shadow = GetContainingShadow()) {
return shadow->GetHost();
nsDOMSlots *slots = GetExistingDOMSlots();
if (slots) {
return &slots->mDestInsertionPoints;
}
return nullptr;
}
void
FragmentOrElement::SetAssignedSlot(HTMLSlotElement* aSlot)
{
nsExtendedDOMSlots* slots = ExtendedDOMSlots();
slots->mAssignedSlot = aSlot;
}
void
FragmentOrElement::SetXBLInsertionParent(nsIContent* aContent)
{
if (aContent) {
nsExtendedDOMSlots* slots = ExtendedDOMSlots();
nsDOMSlots *slots = DOMSlots();
SetFlags(NODE_MAY_BE_IN_BINDING_MNGR);
slots->mXBLInsertionParent = aContent;
} else {
nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
nsDOMSlots *slots = GetExistingDOMSlots();
if (slots) {
slots->mXBLInsertionParent = nullptr;
}
}
}
CustomElementData*
FragmentOrElement::GetCustomElementData() const
{
nsDOMSlots *slots = GetExistingDOMSlots();
if (slots) {
return slots->mCustomElementData;
}
return nullptr;
}
void
FragmentOrElement::SetCustomElementData(CustomElementData* aData)
{
nsDOMSlots *slots = DOMSlots();
MOZ_ASSERT(!slots->mCustomElementData, "Custom element data may not be changed once set.");
slots->mCustomElementData = aData;
}
nsresult
FragmentOrElement::InsertChildAt(nsIContent* aKid,
uint32_t aIndex,
@@ -1431,15 +1366,14 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(FragmentOrElement)
{
nsDOMSlots *slots = tmp->GetExistingDOMSlots();
if (slots) {
if (slots->mExtendedSlots && tmp->IsElement()) {
if (tmp->IsElement()) {
Element* elem = tmp->AsElement();
for (auto iter = slots->mExtendedSlots->mRegisteredIntersectionObservers.Iter();
!iter.Done(); iter.Next()) {
for (auto iter = slots->mRegisteredIntersectionObservers.Iter(); !iter.Done(); iter.Next()) {
DOMIntersectionObserver* observer = iter.Key();
observer->UnlinkTarget(*elem);
}
}
slots->Unlink();
slots->Unlink(tmp->IsXULElement());
}
}
@@ -2004,7 +1938,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(FragmentOrElement)
{
nsDOMSlots *slots = tmp->GetExistingDOMSlots();
if (slots) {
slots->Traverse(cb);
slots->Traverse(cb, tmp->IsXULElement());
}
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
@@ -2419,8 +2353,9 @@ FragmentOrElement::SetIsElementInStyleScopeFlagOnShadowTree(bool aInStyleScope)
NS_ASSERTION(IsElement(), "calling SetIsElementInStyleScopeFlagOnShadowTree "
"on a non-Element is useless");
ShadowRoot* shadowRoot = GetShadowRoot();
if (shadowRoot) {
while (shadowRoot) {
shadowRoot->SetIsElementInStyleScopeFlagOnSubtree(aInStyleScope);
shadowRoot = shadowRoot->GetOlderShadowRoot();
}
}
+55 -87
View File
@@ -15,7 +15,6 @@
#include "mozilla/Attributes.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/UniquePtr.h"
#include "nsAttrAndChildArray.h" // member
#include "nsCycleCollectionParticipant.h" // NS_DECL_CYCLE_*
#include "nsIContent.h" // base class
@@ -38,7 +37,6 @@ class nsIURI;
namespace mozilla {
class DeclarationBlock;
namespace dom {
struct CustomElementData;
class DOMIntersectionObserver;
class Element;
} // namespace dom
@@ -62,7 +60,6 @@ public:
// nsIWeakReference
NS_DECL_NSIWEAKREFERENCE
virtual size_t SizeOfOnlyThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
virtual bool IsAlive() const override { return mNode != nullptr; }
void NoticeNodeDestruction()
{
@@ -155,13 +152,16 @@ public:
virtual void SetXBLBinding(nsXBLBinding* aBinding,
nsBindingManager* aOldBindingManager = nullptr) override;
virtual ShadowRoot *GetContainingShadow() const override;
virtual nsTArray<nsIContent*> &DestInsertionPoints() override;
virtual nsTArray<nsIContent*> *GetExistingDestInsertionPoints() const override;
virtual void SetShadowRoot(ShadowRoot* aBinding) override;
virtual mozilla::dom::HTMLSlotElement* GetAssignedSlot() const override;
virtual void SetAssignedSlot(mozilla::dom::HTMLSlotElement* aSlot) override;
virtual nsIContent *GetXBLInsertionParent() const override;
virtual void SetXBLInsertionParent(nsIContent* aContent) override;
virtual bool IsLink(nsIURI** aURI) const override;
virtual CustomElementData *GetCustomElementData() const override;
virtual void SetCustomElementData(CustomElementData* aData) override;
virtual void DestroyContent() override;
virtual void SaveSubtreeState() override;
@@ -241,6 +241,8 @@ protected:
nsresult CopyInnerTo(FragmentOrElement* aDest);
public:
// Because of a bug in MS C++ compiler nsDOMSlots must be declared public,
// otherwise nsXULElement::nsXULSlots doesn't compile.
/**
* There are a set of DOM- and scripting-specific instance variables
* that may only be instantiated when a content object is accessed
@@ -249,13 +251,29 @@ public:
* in a side structure that's only allocated when the content is
* accessed through the DOM.
*/
class nsExtendedDOMSlots
class nsDOMSlots : public nsINode::nsSlots
{
public:
nsExtendedDOMSlots();
nsDOMSlots();
virtual ~nsDOMSlots();
~nsExtendedDOMSlots();
void Traverse(nsCycleCollectionTraversalCallback &cb, bool aIsXUL);
void Unlink(bool aIsXUL);
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
/**
* The .style attribute (an interface that forwards to the actual
* style rules)
* @see nsGenericHTMLElement::GetStyle
*/
nsCOMPtr<nsICSSDeclaration> mStyle;
/**
* The .dataset attribute.
* @see nsGenericHTMLElement::GetDataset
*/
nsDOMStringMap* mDataset; // [Weak]
/**
* SMIL Overridde style rules (for SMIL animation of CSS properties)
@@ -269,17 +287,35 @@ public:
RefPtr<mozilla::DeclarationBlock> mSMILOverrideStyleDeclaration;
/**
* The nearest enclosing content node with a binding that created us.
* @see FragmentOrElement::GetBindingParent
*/
nsIContent* mBindingParent; // [Weak]
* An object implementing nsIDOMMozNamedAttrMap for this content (attributes)
* @see FragmentOrElement::GetAttributes
*/
RefPtr<nsDOMAttributeMap> mAttributeMap;
union {
/**
* The nearest enclosing content node with a binding that created us.
* @see FragmentOrElement::GetBindingParent
*/
nsIContent* mBindingParent; // [Weak]
/**
* The controllers of the XUL Element.
*/
nsIControllers* mControllers; // [OWNER]
};
/**
* The controllers of the XUL Element.
*/
nsCOMPtr<nsIControllers> mControllers;
* An object implementing the .children property for this element.
*/
RefPtr<nsContentList> mChildrenList;
/**
* An object implementing the .classList property for this element.
*/
RefPtr<nsDOMTokenList> mClassList;
/*
* An object implementing the .labels property for this element.
*/
RefPtr<nsLabelsNodeList> mLabelsList;
@@ -295,9 +331,10 @@ public:
RefPtr<ShadowRoot> mContainingShadow;
/**
* The assigned slot associated with this element.
* An array of web component insertion points to which this element
* is distributed.
*/
RefPtr<mozilla::dom::HTMLSlotElement> mAssignedSlot;
nsTArray<nsIContent*> mDestInsertionPoints;
/**
* XBL binding installed on the element.
@@ -319,55 +356,6 @@ public:
*/
nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>
mRegisteredIntersectionObservers;
/**
* For XUL to hold either frameloader or opener.
*/
nsCOMPtr<nsISupports> mFrameLoaderOrOpener;
};
class nsDOMSlots : public nsINode::nsSlots
{
public:
nsDOMSlots();
virtual ~nsDOMSlots();
void Traverse(nsCycleCollectionTraversalCallback &cb);
void Unlink();
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
/**
* The .style attribute (an interface that forwards to the actual
* style rules)
* @see nsGenericHTMLElement::GetStyle
*/
nsCOMPtr<nsICSSDeclaration> mStyle;
/**
* The .dataset attribute.
* @see nsGenericHTMLElement::GetDataset
*/
nsDOMStringMap* mDataset; // [Weak]
/**
* An object implementing nsIDOMMozNamedAttrMap for this content (attributes)
* @see FragmentOrElement::GetAttributes
*/
RefPtr<nsDOMAttributeMap> mAttributeMap;
/**
* An object implementing the .children property for this element.
*/
RefPtr<nsContentList> mChildrenList;
/**
* An object implementing the .classList property for this element.
*/
RefPtr<nsDOMTokenList> mClassList;
mozilla::UniquePtr<nsExtendedDOMSlots> mExtendedSlots;
};
protected:
@@ -387,26 +375,6 @@ protected:
return static_cast<nsDOMSlots*>(GetExistingSlots());
}
nsExtendedDOMSlots* ExtendedDOMSlots()
{
nsDOMSlots* slots = DOMSlots();
if (!slots->mExtendedSlots) {
slots->mExtendedSlots = MakeUnique<nsExtendedDOMSlots>();
}
return slots->mExtendedSlots.get();
}
nsExtendedDOMSlots* GetExistingExtendedDOMSlots() const
{
nsDOMSlots* slots = GetExistingDOMSlots();
if (slots) {
return slots->mExtendedSlots.get();
}
return nullptr;
}
/**
* Calls SetIsElementInStyleScopeFlagOnSubtree for each shadow tree attached
* to this node, which is assumed to be an Element.
+475 -338
View File
@@ -14,11 +14,9 @@
#include "nsIDOMHTMLElement.h"
#include "nsIStyleSheetLinkingElement.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/HTMLSlotElement.h"
#include "mozilla/dom/StyleSheetList.h"
#include "mozilla/dom/HTMLContentElement.h"
#include "mozilla/dom/HTMLShadowElement.h"
#include "nsXBLPrototypeBinding.h"
#include "mozilla/BasicEvents.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/StyleSheet.h"
#include "mozilla/StyleSheetInlines.h"
@@ -29,7 +27,10 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(ShadowRoot)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ShadowRoot,
DocumentFragment)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDOMStyleSheets)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPoolHost)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStyleSheetList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOlderShadow)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mYoungerShadow)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAssociatedBinding)
for (auto iter = tmp->mIdentifierMap.ConstIter(); !iter.Done();
iter.Next()) {
@@ -37,14 +38,18 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ShadowRoot,
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ShadowRoot)
if (tmp->GetHost()) {
tmp->GetHost()->RemoveMutationObserver(tmp);
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ShadowRoot,
DocumentFragment)
if (tmp->mPoolHost) {
tmp->mPoolHost->RemoveMutationObserver(tmp);
}
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDOMStyleSheets)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPoolHost)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mStyleSheetList)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOlderShadow)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mYoungerShadow)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mAssociatedBinding)
tmp->mIdentifierMap.Clear();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(DocumentFragment)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ShadowRoot)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContent)
@@ -54,17 +59,14 @@ NS_INTERFACE_MAP_END_INHERITING(DocumentFragment)
NS_IMPL_ADDREF_INHERITED(ShadowRoot, DocumentFragment)
NS_IMPL_RELEASE_INHERITED(ShadowRoot, DocumentFragment)
ShadowRoot::ShadowRoot(Element* aElement, bool aClosed,
ShadowRoot::ShadowRoot(nsIContent* aContent,
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
nsXBLPrototypeBinding* aProtoBinding)
: DocumentFragment(aNodeInfo)
, DocumentOrShadowRoot(this)
, mProtoBinding(aProtoBinding)
, mInsertionPointChanged(false)
, mIsComposedDocParticipant(false)
: DocumentFragment(aNodeInfo), mPoolHost(aContent),
mProtoBinding(aProtoBinding), mShadowElement(nullptr),
mInsertionPointChanged(false), mIsComposedDocParticipant(false)
{
SetHost(aElement);
mMode = aClosed ? ShadowRootMode::Closed : ShadowRootMode::Open;
SetHost(aContent);
// Nodes in a shadow tree should never store a value
// in the subtree root pointer, nodes in the shadow tree
@@ -73,27 +75,29 @@ ShadowRoot::ShadowRoot(Element* aElement, bool aClosed,
SetFlags(NODE_IS_IN_SHADOW_TREE);
ExtendedDOMSlots()->mBindingParent = aElement;
ExtendedDOMSlots()->mContainingShadow = this;
DOMSlots()->mBindingParent = aContent;
DOMSlots()->mContainingShadow = this;
// Add the ShadowRoot as a mutation observer on the host to watch
// for mutations because the insertion points in this ShadowRoot
// may need to be updated when the host children are modified.
GetHost()->AddMutationObserver(this);
mPoolHost->AddMutationObserver(this);
}
ShadowRoot::~ShadowRoot()
{
if (auto* host = GetHost()) {
// mHost may have been unlinked or a new ShadowRoot may have been
// created, making this one obsolete.
host->RemoveMutationObserver(this);
if (mPoolHost) {
// mPoolHost may have been unlinked or a new ShadowRoot may have been
// creating, making this one obsolete.
mPoolHost->RemoveMutationObserver(this);
}
UnsetFlags(NODE_IS_IN_SHADOW_TREE);
// nsINode destructor expects mSubtreeRoot == this.
SetSubtreeRootPointer(this);
SetHost(nullptr);
}
JSObject*
@@ -114,116 +118,13 @@ ShadowRoot::FromNode(nsINode* aNode)
return nullptr;
}
void
ShadowRoot::AddSlot(HTMLSlotElement* aSlot)
{
MOZ_ASSERT(aSlot);
// Note that if name attribute missing, the slot is a default slot.
nsAutoString name;
aSlot->GetName(name);
nsTArray<HTMLSlotElement*>* currentSlots = mSlotMap.LookupOrAdd(name);
MOZ_ASSERT(currentSlots);
HTMLSlotElement* oldSlot = currentSlots->IsEmpty() ?
nullptr : currentSlots->ElementAt(0);
TreeOrderComparator comparator;
currentSlots->InsertElementSorted(aSlot, comparator);
HTMLSlotElement* currentSlot = currentSlots->ElementAt(0);
if (currentSlot != aSlot) {
return;
}
bool doEnqueueSlotChange = false;
if (oldSlot && oldSlot != currentSlot) {
// Move assigned nodes from old slot to new slot.
const nsTArray<RefPtr<nsINode>>& assignedNodes = oldSlot->AssignedNodes();
while (assignedNodes.Length() > 0) {
nsINode* assignedNode = assignedNodes[0];
oldSlot->RemoveAssignedNode(assignedNode);
currentSlot->AppendAssignedNode(assignedNode);
doEnqueueSlotChange = true;
}
if (doEnqueueSlotChange) {
oldSlot->EnqueueSlotChangeEvent();
currentSlot->EnqueueSlotChangeEvent();
}
} else {
// Otherwise add appropriate nodes to this slot from the host.
for (nsIContent* child = GetHost()->GetFirstChild();
child;
child = child->GetNextSibling()) {
nsAutoString slotName;
child->GetAttr(kNameSpaceID_None, nsGkAtoms::slot, slotName);
if (child->IsSlotable() && slotName.Equals(name)) {
currentSlot->AppendAssignedNode(child);
doEnqueueSlotChange = true;
}
}
if (doEnqueueSlotChange) {
currentSlot->EnqueueSlotChangeEvent();
}
}
}
void
ShadowRoot::RemoveSlot(HTMLSlotElement* aSlot)
{
MOZ_ASSERT(aSlot);
nsAutoString name;
aSlot->GetName(name);
nsTArray<HTMLSlotElement*>* currentSlots = mSlotMap.Get(name);
if (currentSlots) {
if (currentSlots->Length() == 1) {
MOZ_ASSERT(currentSlots->ElementAt(0) == aSlot);
mSlotMap.Remove(name);
if (aSlot->AssignedNodes().Length() > 0) {
aSlot->ClearAssignedNodes();
aSlot->EnqueueSlotChangeEvent();
}
} else {
bool doEnqueueSlotChange = false;
bool doReplaceSlot = currentSlots->ElementAt(0) == aSlot;
currentSlots->RemoveElement(aSlot);
HTMLSlotElement* replacementSlot = currentSlots->ElementAt(0);
// Move assigned nodes from removed slot to the next slot in
// tree order with the same name.
if (doReplaceSlot) {
const nsTArray<RefPtr<nsINode>>& assignedNodes = aSlot->AssignedNodes();
while (assignedNodes.Length() > 0) {
nsINode* assignedNode = assignedNodes[0];
aSlot->RemoveAssignedNode(assignedNode);
replacementSlot->AppendAssignedNode(assignedNode);
doEnqueueSlotChange = true;
}
if (doEnqueueSlotChange) {
aSlot->EnqueueSlotChangeEvent();
replacementSlot->EnqueueSlotChangeEvent();
}
}
}
}
}
void
ShadowRoot::StyleSheetChanged()
{
mProtoBinding->FlushSkinSheets();
if (nsIPresShell* shell = OwnerDoc()->GetShell()) {
nsIPresShell* shell = OwnerDoc()->GetShell();
if (shell) {
OwnerDoc()->BeginUpdate(UPDATE_STYLE);
shell->RecordShadowStyleChange(this);
OwnerDoc()->EndUpdate(UPDATE_STYLE);
@@ -241,30 +142,16 @@ ShadowRoot::InsertSheet(StyleSheet* aSheet,
linkingElement->SetStyleSheet(aSheet); // This sets the ownerNode on the sheet
MOZ_DIAGNOSTIC_ASSERT(mProtoBinding->SheetCount() == DocumentOrShadowRoot::SheetCount());
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
// FIXME(emilio, bug 1425759): For now we keep them duplicated, the proto
// binding will disappear soon (tm).
{
size_t i = 0;
for (RefPtr<StyleSheet>& sheet : mStyleSheets) {
MOZ_DIAGNOSTIC_ASSERT(sheet.get() == mProtoBinding->StyleSheetAt(i++));
}
}
#endif
// Find the correct position to insert into the style sheet list (must
// be in tree order).
for (size_t i = 0; i <= SheetCount(); i++) {
if (i == SheetCount()) {
AppendStyleSheet(*aSheet);
for (size_t i = 0; i <= mProtoBinding->SheetCount(); i++) {
if (i == mProtoBinding->SheetCount()) {
mProtoBinding->AppendStyleSheet(aSheet);
break;
}
nsINode* sheetOwningNode = SheetAt(i)->GetOwnerNode();
nsINode* sheetOwningNode = mProtoBinding->StyleSheetAt(i)->GetOwnerNode();
if (nsContentUtils::PositionIsBefore(aLinkingContent, sheetOwningNode)) {
InsertSheetAt(i, *aSheet);
mProtoBinding->InsertStyleSheetAt(i, aSheet);
break;
}
@@ -279,17 +166,48 @@ void
ShadowRoot::RemoveSheet(StyleSheet* aSheet)
{
mProtoBinding->RemoveStyleSheet(aSheet);
DocumentOrShadowRoot::RemoveSheet(*aSheet);
if (aSheet->IsApplicable()) {
StyleSheetChanged();
}
}
Element*
ShadowRoot::GetElementById(const nsAString& aElementId)
{
nsIdentifierMapEntry *entry = mIdentifierMap.GetEntry(aElementId);
return entry ? entry->GetIdElement() : nullptr;
}
already_AddRefed<nsContentList>
ShadowRoot::GetElementsByTagName(const nsAString& aTagName)
{
return NS_GetContentList(this, kNameSpaceID_Unknown, aTagName);
}
already_AddRefed<nsContentList>
ShadowRoot::GetElementsByTagNameNS(const nsAString& aNamespaceURI,
const nsAString& aLocalName)
{
int32_t nameSpaceId = kNameSpaceID_Wildcard;
if (!aNamespaceURI.EqualsLiteral("*")) {
nsresult rv =
nsContentUtils::NameSpaceManager()->RegisterNameSpace(aNamespaceURI,
nameSpaceId);
NS_ENSURE_SUCCESS(rv, nullptr);
}
NS_ASSERTION(nameSpaceId != kNameSpaceID_Unknown, "Unexpected namespace ID!");
return NS_GetContentList(this, nameSpaceId, aLocalName);
}
void
ShadowRoot::AddToIdTable(Element* aElement, nsIAtom* aId)
{
nsIdentifierMapEntry* entry = mIdentifierMap.PutEntry(aId);
nsIdentifierMapEntry *entry =
mIdentifierMap.PutEntry(nsDependentAtomString(aId));
if (entry) {
entry->AddIdElement(aElement);
}
@@ -298,7 +216,8 @@ ShadowRoot::AddToIdTable(Element* aElement, nsIAtom* aId)
void
ShadowRoot::RemoveFromIdTable(Element* aElement, nsIAtom* aId)
{
nsIdentifierMapEntry* entry = mIdentifierMap.GetEntry(aId);
nsIdentifierMapEntry *entry =
mIdentifierMap.GetEntry(nsDependentAtomString(aId));
if (entry) {
entry->RemoveIdElement(aElement);
if (entry->IsEmpty()) {
@@ -307,164 +226,244 @@ ShadowRoot::RemoveFromIdTable(Element* aElement, nsIAtom* aId)
}
}
nsresult
ShadowRoot::GetEventTargetParent(EventChainPreVisitor& aVisitor)
already_AddRefed<nsContentList>
ShadowRoot::GetElementsByClassName(const nsAString& aClasses)
{
aVisitor.mCanHandle = true;
aVisitor.mRootOfClosedTree = IsClosed();
// https://dom.spec.whatwg.org/#ref-for-get-the-parent%E2%91%A6
if (!aVisitor.mEvent->mFlags.mComposed) {
nsCOMPtr<nsIContent> originalTarget =
do_QueryInterface(aVisitor.mEvent->mOriginalTarget);
if (originalTarget->GetContainingShadow() == this) {
// If we do stop propagation, we still want to propagate
// the event to chrome (nsPIDOMWindow::GetParentTarget()).
// The load event is special in that we don't ever propagate it
// to chrome.
nsCOMPtr<nsPIDOMWindowOuter> win = OwnerDoc()->GetWindow();
EventTarget* parentTarget = win && aVisitor.mEvent->mMessage != eLoad
? win->GetParentTarget() : nullptr;
aVisitor.SetParentTarget(parentTarget, true);
return NS_OK;
}
}
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;
}
}
return NS_OK;
return nsContentUtils::GetElementsByClassName(this, aClasses);
}
const HTMLSlotElement*
ShadowRoot::AssignSlotFor(nsIContent* aContent)
void
ShadowRoot::AddInsertionPoint(HTMLContentElement* aInsertionPoint)
{
nsAutoString slotName;
// Note that if slot attribute is missing, assign it to the first default
// slot, if exists.
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::slot, slotName);
nsTArray<HTMLSlotElement*>* slots = mSlotMap.Get(slotName);
if (!slots) {
return nullptr;
TreeOrderComparator comparator;
mInsertionPoints.InsertElementSorted(aInsertionPoint, comparator);
}
void
ShadowRoot::RemoveInsertionPoint(HTMLContentElement* aInsertionPoint)
{
mInsertionPoints.RemoveElement(aInsertionPoint);
}
void
ShadowRoot::SetYoungerShadow(ShadowRoot* aYoungerShadow)
{
mYoungerShadow = aYoungerShadow;
mYoungerShadow->mOlderShadow = this;
ChangePoolHost(mYoungerShadow->GetShadowElement());
}
void
ShadowRoot::RemoveDestInsertionPoint(nsIContent* aInsertionPoint,
nsTArray<nsIContent*>& aDestInsertionPoints)
{
// Remove the insertion point from the destination insertion points.
// Also remove all succeeding insertion points because it is no longer
// possible for the content to be distributed into deeper node trees.
int32_t index = aDestInsertionPoints.IndexOf(aInsertionPoint);
// It's possible that we already removed the insertion point while processing
// other insertion point removals.
if (index >= 0) {
aDestInsertionPoints.SetLength(index);
}
}
HTMLSlotElement* slot = slots->ElementAt(0);
MOZ_ASSERT(slot);
// Find the appropriate position in the assigned node list for the
// newly assigned content.
const nsTArray<RefPtr<nsINode>>& assignedNodes = slot->AssignedNodes();
nsIContent* currentContent = GetHost()->GetFirstChild();
bool indexFound = false;
uint32_t insertionIndex;
for (uint32_t i = 0; i < assignedNodes.Length(); i++) {
// Seek through the host's explicit children until the
// assigned content is found.
while (currentContent && currentContent != assignedNodes[i]) {
if (currentContent == aContent) {
indexFound = true;
insertionIndex = i;
void
ShadowRoot::DistributeSingleNode(nsIContent* aContent)
{
// Find the insertion point to which the content belongs.
HTMLContentElement* insertionPoint = nullptr;
for (uint32_t i = 0; i < mInsertionPoints.Length(); i++) {
if (mInsertionPoints[i]->Match(aContent)) {
if (mInsertionPoints[i]->MatchedNodes().Contains(aContent)) {
// Node is already matched into the insertion point. We are done.
return;
}
currentContent = currentContent->GetNextSibling();
}
if (indexFound) {
// Matching may cause the insertion point to drop fallback content.
if (mInsertionPoints[i]->MatchedNodes().IsEmpty() &&
static_cast<nsINode*>(mInsertionPoints[i])->GetFirstChild()) {
// This match will cause the insertion point to drop all fallback
// content and used matched nodes instead. Give up on the optimization
// and just distribute all nodes.
DistributeAllNodes();
return;
}
insertionPoint = mInsertionPoints[i];
break;
}
}
if (indexFound) {
slot->InsertAssignedNode(insertionIndex, aContent);
} else {
slot->AppendAssignedNode(aContent);
}
return slot;
}
const HTMLSlotElement*
ShadowRoot::UnassignSlotFor(nsIContent* aNode, const nsAString& aSlotName)
{
// Find the insertion point to which the content belongs. Note that if slot
// attribute is missing, unassign it from the first default slot, if exists.
nsTArray<HTMLSlotElement*>* slots = mSlotMap.Get(aSlotName);
if (!slots) {
return nullptr;
}
HTMLSlotElement* slot = slots->ElementAt(0);
MOZ_ASSERT(slot);
if (!slot->AssignedNodes().Contains(aNode)) {
return nullptr;
}
slot->RemoveAssignedNode(aNode);
return slot;
}
bool
ShadowRoot::MaybeReassignElement(Element* aElement,
const nsAttrValue* aOldValue)
{
nsIContent* parent = aElement->GetParent();
if (parent && parent == GetHost()) {
const HTMLSlotElement* oldSlot = UnassignSlotFor(aElement,
aOldValue ? aOldValue->GetStringValue() : EmptyString());
const HTMLSlotElement* newSlot = AssignSlotFor(aElement);
if (oldSlot != newSlot) {
if (oldSlot) {
oldSlot->EnqueueSlotChangeEvent();
// Find the index into the insertion point.
if (insertionPoint) {
nsCOMArray<nsIContent>& matchedNodes = insertionPoint->MatchedNodes();
// Find the appropriate position in the matched node list for the
// newly distributed content.
bool isIndexFound = false;
MOZ_ASSERT(mPoolHost, "Where did the content come from if there is no pool host?");
ExplicitChildIterator childIterator(mPoolHost);
for (uint32_t i = 0; i < matchedNodes.Length(); i++) {
// Seek through the host's explicit children until the inserted content
// is found or when the current matched node is reached.
if (childIterator.Seek(aContent, matchedNodes[i])) {
// aContent was found before the current matched node.
insertionPoint->InsertMatchedNode(i, aContent);
isIndexFound = true;
break;
}
if (newSlot) {
newSlot->EnqueueSlotChangeEvent();
}
if (!isIndexFound) {
// We have still not found an index in the insertion point,
// thus it must be at the end.
MOZ_ASSERT(childIterator.Seek(aContent, nullptr),
"Trying to match a node that is not a candidate to be matched");
insertionPoint->AppendMatchedNode(aContent);
}
// Handle the case where the parent of the insertion point is a ShadowRoot
// that is projected into the younger ShadowRoot's shadow insertion point.
// The node distributed into the insertion point must be reprojected
// to the shadow insertion point.
if (insertionPoint->GetParent() == this &&
mYoungerShadow && mYoungerShadow->GetShadowElement()) {
mYoungerShadow->GetShadowElement()->DistributeSingleNode(aContent);
}
// Handle the case where the parent of the insertion point has a ShadowRoot.
// The node distributed into the insertion point must be reprojected to the
// insertion points of the parent's ShadowRoot.
ShadowRoot* parentShadow = insertionPoint->GetParent()->GetShadowRoot();
if (parentShadow) {
parentShadow->DistributeSingleNode(aContent);
}
// Handle the case where the parent of the insertion point is the <shadow>
// element. The node distributed into the insertion point must be reprojected
// into the older ShadowRoot's insertion points.
if (mShadowElement && mShadowElement == insertionPoint->GetParent()) {
ShadowRoot* olderShadow = mShadowElement->GetOlderShadowRoot();
if (olderShadow) {
olderShadow->DistributeSingleNode(aContent);
}
return true;
}
}
return false;
}
void
ShadowRoot::DistributionChanged()
ShadowRoot::RemoveDistributedNode(nsIContent* aContent)
{
// FIXME(emilio): We could be more granular in a bunch of cases.
auto* host = GetHost();
if (!host || !host->IsInComposedDoc()) {
return;
}
// Find insertion point containing the content and remove the node.
for (uint32_t i = 0; i < mInsertionPoints.Length(); i++) {
if (mInsertionPoints[i]->MatchedNodes().Contains(aContent)) {
// Removing the matched node may cause the insertion point to use
// fallback content.
if (mInsertionPoints[i]->MatchedNodes().Length() == 1 &&
static_cast<nsINode*>(mInsertionPoints[i])->GetFirstChild()) {
// Removing the matched node will cause fallback content to be
// used instead. Give up optimization and distribute all nodes.
DistributeAllNodes();
return;
}
auto* shell = OwnerDoc()->GetShell();
if (!shell) {
return;
}
mInsertionPoints[i]->RemoveMatchedNode(aContent);
shell->DestroyFramesForAndRestyle(host);
// Handle the case where the parent of the insertion point is a ShadowRoot
// that is projected into the younger ShadowRoot's shadow insertion point.
// The removed node needs to be removed from the shadow insertion point.
if (mInsertionPoints[i]->GetParent() == this) {
if (mYoungerShadow && mYoungerShadow->GetShadowElement()) {
mYoungerShadow->GetShadowElement()->RemoveDistributedNode(aContent);
}
}
// Handle the case where the parent of the insertion point has a ShadowRoot.
// The removed node needs to be removed from the insertion points of the
// parent's ShadowRoot.
ShadowRoot* parentShadow = mInsertionPoints[i]->GetParent()->GetShadowRoot();
if (parentShadow) {
parentShadow->RemoveDistributedNode(aContent);
}
// Handle the case where the parent of the insertion point is the <shadow>
// element. The removed node must be removed from the older ShadowRoot's
// insertion points.
if (mShadowElement && mShadowElement == mInsertionPoints[i]->GetParent()) {
ShadowRoot* olderShadow = mShadowElement->GetOlderShadowRoot();
if (olderShadow) {
olderShadow->RemoveDistributedNode(aContent);
}
}
break;
}
}
}
void
ShadowRoot::DistributeAllNodes()
{
//XXX Handle <slot>.
// Create node pool.
nsTArray<nsIContent*> nodePool;
DistributionChanged();
}
// Make sure there is a pool host, an older shadow may not have
// one if the younger shadow does not have a <shadow> element.
if (mPoolHost) {
ExplicitChildIterator childIterator(mPoolHost);
for (nsIContent* content = childIterator.GetNextChild();
content;
content = childIterator.GetNextChild()) {
nodePool.AppendElement(content);
}
}
Element*
ShadowRoot::GetActiveElement()
{
return GetRetargetedFocusedElement();
nsTArray<ShadowRoot*> shadowsToUpdate;
for (uint32_t i = 0; i < mInsertionPoints.Length(); i++) {
mInsertionPoints[i]->ClearMatchedNodes();
// Assign matching nodes from node pool.
for (uint32_t j = 0; j < nodePool.Length(); j++) {
if (mInsertionPoints[i]->Match(nodePool[j])) {
mInsertionPoints[i]->AppendMatchedNode(nodePool[j]);
nodePool.RemoveElementAt(j--);
}
}
// Keep track of instances where the content insertion point is distributed
// (parent of insertion point has a ShadowRoot).
nsIContent* insertionParent = mInsertionPoints[i]->GetParent();
MOZ_ASSERT(insertionParent, "The only way for an insertion point to be in the"
"mInsertionPoints array is to be a descendant of a"
"ShadowRoot, in which case, it should have a parent");
// If the parent of the insertion point has a ShadowRoot, the nodes distributed
// to the insertion point must be reprojected to the insertion points of the
// parent's ShadowRoot.
ShadowRoot* parentShadow = insertionParent->GetShadowRoot();
if (parentShadow && !shadowsToUpdate.Contains(parentShadow)) {
shadowsToUpdate.AppendElement(parentShadow);
}
}
// If there is a shadow insertion point in this ShadowRoot, the children
// of the shadow insertion point needs to be distributed into the insertion
// points of the older ShadowRoot.
if (mShadowElement && mOlderShadow) {
mOlderShadow->DistributeAllNodes();
}
// If there is a younger ShadowRoot with a shadow insertion point,
// then the children of this ShadowRoot needs to be distributed to
// the younger ShadowRoot's shadow insertion point.
if (mYoungerShadow && mYoungerShadow->GetShadowElement()) {
mYoungerShadow->GetShadowElement()->DistributeAllNodes();
}
for (uint32_t i = 0; i < shadowsToUpdate.Length(); i++) {
shadowsToUpdate[i]->DistributeAllNodes();
}
}
void
@@ -508,6 +507,105 @@ ShadowRoot::SetApplyAuthorStyles(bool aApplyAuthorStyles)
}
}
StyleSheetList*
ShadowRoot::StyleSheets()
{
if (!mStyleSheetList) {
mStyleSheetList = new ShadowRootStyleSheetList(this);
}
return mStyleSheetList;
}
void
ShadowRoot::SetShadowElement(HTMLShadowElement* aShadowElement)
{
// If there is already a shadow element point, remove
// the projected shadow because it is no longer an insertion
// point.
if (mShadowElement) {
mShadowElement->SetProjectedShadow(nullptr);
}
if (mOlderShadow) {
// Nodes for distribution will come from the new shadow element.
mOlderShadow->ChangePoolHost(aShadowElement);
}
// Set the new shadow element to project the older ShadowRoot because
// it is the current shadow insertion point.
mShadowElement = aShadowElement;
if (mShadowElement) {
mShadowElement->SetProjectedShadow(mOlderShadow);
}
}
void
ShadowRoot::ChangePoolHost(nsIContent* aNewHost)
{
if (mPoolHost) {
mPoolHost->RemoveMutationObserver(this);
}
// Clear the nodes matched to content insertion points
// because it is no longer relevant.
for (uint32_t i = 0; i < mInsertionPoints.Length(); i++) {
mInsertionPoints[i]->ClearMatchedNodes();
}
mPoolHost = aNewHost;
if (mPoolHost) {
mPoolHost->AddMutationObserver(this);
}
}
bool
ShadowRoot::IsShadowInsertionPoint(nsIContent* aContent)
{
if (!aContent) {
return false;
}
HTMLShadowElement* shadowElem = HTMLShadowElement::FromContent(aContent);
return shadowElem && shadowElem->IsInsertionPoint();
}
/**
* Returns whether the web components pool population algorithm
* on the host would contain |aContent|. This function ignores
* insertion points in the pool, thus should only be used to
* test nodes that have not yet been distributed.
*/
bool
ShadowRoot::IsPooledNode(nsIContent* aContent, nsIContent* aContainer,
nsIContent* aHost)
{
if (nsContentUtils::IsContentInsertionPoint(aContent) ||
IsShadowInsertionPoint(aContent)) {
// Insertion points never end up in the pool.
return false;
}
if (aContainer == aHost &&
nsContentUtils::IsInSameAnonymousTree(aContainer, aContent)) {
// Children of the host will end up in the pool. We check to ensure
// that the content is in the same anonymous tree as the container
// because anonymous content may report its container as the host
// but it may not be in the host's child list.
return true;
}
if (aContainer) {
// Fallback content will end up in pool if its parent is a child of the host.
HTMLContentElement* content = HTMLContentElement::FromContent(aContainer);
return content && content->IsInsertionPoint() &&
content->MatchedNodes().IsEmpty() &&
aContainer->GetParentNode() == aHost;
}
return false;
}
void
ShadowRoot::AttributeChanged(nsIDocument* aDocument,
Element* aElement,
@@ -516,26 +614,13 @@ ShadowRoot::AttributeChanged(nsIDocument* aDocument,
int32_t aModType,
const nsAttrValue* aOldValue)
{
if (aNameSpaceID != kNameSpaceID_None || aAttribute != nsGkAtoms::slot) {
if (!IsPooledNode(aElement, aElement->GetParent(), mPoolHost)) {
return;
}
// Attributes may change insertion point matching, find its new distribution.
if (!MaybeReassignElement(aElement, aOldValue)) {
return;
}
if (!aElement->IsInComposedDoc()) {
return;
}
auto* shell = OwnerDoc()->GetShell();
if (!shell) {
return;
}
//XXX optimize this!
shell->DestroyFramesForAndRestyle(aElement);
RemoveDistributedNode(aElement);
DistributeSingleNode(aElement);
}
void
@@ -544,10 +629,29 @@ ShadowRoot::ContentAppended(nsIDocument* aDocument,
nsIContent* aFirstNewContent,
int32_t aNewIndexInContainer)
{
for (nsIContent* content = aFirstNewContent;
content;
content = content->GetNextSibling()) {
ContentInserted(aDocument, aContainer, aFirstNewContent, aNewIndexInContainer);
if (mInsertionPointChanged) {
DistributeAllNodes();
mInsertionPointChanged = false;
return;
}
// Watch for new nodes added to the pool because the node
// may need to be added to an insertion point.
nsIContent* currentChild = aFirstNewContent;
while (currentChild) {
// Add insertion point to destination insertion points of fallback content.
if (nsContentUtils::IsContentInsertionPoint(aContainer)) {
HTMLContentElement* content = HTMLContentElement::FromContent(aContainer);
if (content->MatchedNodes().IsEmpty()) {
currentChild->DestInsertionPoints().AppendElement(aContainer);
}
}
if (IsPooledNode(currentChild, aContainer, mPoolHost)) {
DistributeSingleNode(currentChild);
}
currentChild = currentChild->GetNextSibling();
}
}
@@ -557,30 +661,24 @@ ShadowRoot::ContentInserted(nsIDocument* aDocument,
nsIContent* aChild,
int32_t aIndexInContainer)
{
// Check to ensure that the content is in the same anonymous tree
// as the container because anonymous content may report its container
// as the host but it may not be in the host's child list.
if (!nsContentUtils::IsInSameAnonymousTree(aContainer, aChild)) {
if (mInsertionPointChanged) {
DistributeAllNodes();
mInsertionPointChanged = false;
return;
}
if (!aChild->IsSlotable()) {
return;
}
if (aContainer && aContainer == GetHost()) {
if (const HTMLSlotElement* slot = AssignSlotFor(aChild)) {
slot->EnqueueSlotChangeEvent();
// Watch for new nodes added to the pool because the node
// may need to be added to an insertion point.
if (IsPooledNode(aChild, aContainer, mPoolHost)) {
// Add insertion point to destination insertion points of fallback content.
if (nsContentUtils::IsContentInsertionPoint(aContainer)) {
HTMLContentElement* content = HTMLContentElement::FromContent(aContainer);
if (content->MatchedNodes().IsEmpty()) {
aChild->DestInsertionPoints().AppendElement(aContainer);
}
}
return;
}
// If parent's root is a shadow root, and parent is a slot whose assigned
// nodes is the empty list, then run signal a slot change for parent.
HTMLSlotElement* slot = HTMLSlotElement::FromContentOrNull(aContainer);
if (slot && slot->GetContainingShadow() == this &&
slot->AssignedNodes().IsEmpty()) {
slot->EnqueueSlotChangeEvent();
DistributeSingleNode(aChild);
}
}
@@ -591,32 +689,25 @@ ShadowRoot::ContentRemoved(nsIDocument* aDocument,
int32_t aIndexInContainer,
nsIContent* aPreviousSibling)
{
// Check to ensure that the content is in the same anonymous tree
// as the container because anonymous content may report its container
// as the host but it may not be in the host's child list.
if (!nsContentUtils::IsInSameAnonymousTree(aContainer, aChild)) {
if (mInsertionPointChanged) {
DistributeAllNodes();
mInsertionPointChanged = false;
return;
}
if (!aChild->IsSlotable()) {
return;
}
if (aContainer && aContainer == GetHost()) {
nsAutoString slotName;
aChild->GetAttr(kNameSpaceID_None, nsGkAtoms::slot, slotName);
if (const HTMLSlotElement* slot = UnassignSlotFor(aChild, slotName)) {
slot->EnqueueSlotChangeEvent();
// Clear destination insertion points for removed
// fallback content.
if (nsContentUtils::IsContentInsertionPoint(aContainer)) {
HTMLContentElement* content = HTMLContentElement::FromContent(aContainer);
if (content->MatchedNodes().IsEmpty()) {
aChild->DestInsertionPoints().Clear();
}
return;
}
// If parent's root is a shadow root, and parent is a slot whose assigned
// nodes is the empty list, then run signal a slot change for parent.
HTMLSlotElement* slot = HTMLSlotElement::FromContentOrNull(aContainer);
if (slot && slot->GetContainingShadow() == this &&
slot->AssignedNodes().IsEmpty()) {
slot->EnqueueSlotChangeEvent();
// Watch for node that is removed from the pool because
// it may need to be removed from an insertion point.
if (IsPooledNode(aChild, aContainer, mPoolHost)) {
RemoveDistributedNode(aChild);
}
}
@@ -626,3 +717,49 @@ ShadowRoot::Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const
*aResult = nullptr;
return NS_ERROR_DOM_DATA_CLONE_ERR;
}
void
ShadowRoot::DestroyContent()
{
if (mOlderShadow) {
mOlderShadow->DestroyContent();
}
DocumentFragment::DestroyContent();
}
NS_IMPL_CYCLE_COLLECTION_INHERITED(ShadowRootStyleSheetList, StyleSheetList,
mShadowRoot)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ShadowRootStyleSheetList)
NS_INTERFACE_MAP_END_INHERITING(StyleSheetList)
NS_IMPL_ADDREF_INHERITED(ShadowRootStyleSheetList, StyleSheetList)
NS_IMPL_RELEASE_INHERITED(ShadowRootStyleSheetList, StyleSheetList)
ShadowRootStyleSheetList::ShadowRootStyleSheetList(ShadowRoot* aShadowRoot)
: mShadowRoot(aShadowRoot)
{
MOZ_COUNT_CTOR(ShadowRootStyleSheetList);
}
ShadowRootStyleSheetList::~ShadowRootStyleSheetList()
{
MOZ_COUNT_DTOR(ShadowRootStyleSheetList);
}
StyleSheet*
ShadowRootStyleSheetList::IndexedGetter(uint32_t aIndex, bool& aFound)
{
aFound = aIndex < mShadowRoot->mProtoBinding->SheetCount();
if (!aFound) {
return nullptr;
}
return mShadowRoot->mProtoBinding->StyleSheetAt(aIndex);
}
uint32_t
ShadowRootStyleSheetList::Length()
{
return mShadowRoot->mProtoBinding->SheetCount();
}
+115 -70
View File
@@ -8,30 +8,30 @@
#define mozilla_dom_shadowroot_h__
#include "mozilla/dom/DocumentFragment.h"
#include "mozilla/dom/DocumentOrShadowRoot.h"
#include "mozilla/dom/StyleSheetList.h"
#include "mozilla/StyleSheet.h"
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIContentInlines.h"
#include "nsIdentifierMapEntry.h"
#include "nsTHashtable.h"
#include "nsXBLBinding.h"
#include "nsDocument.h"
class nsIAtom;
class nsIContent;
class nsXBLPrototypeBinding;
namespace mozilla {
class EventChainPreVisitor;
namespace dom {
class Element;
class HTMLContentElement;
class HTMLShadowElement;
class ShadowRootStyleSheetList;
class ShadowRoot final : public DocumentFragment,
public DocumentOrShadowRoot,
public nsStubMutationObserver
{
friend class ShadowRootStyleSheetList;
public:
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ShadowRoot,
DocumentFragment)
@@ -42,30 +42,46 @@ public:
NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
ShadowRoot(Element* aElement, bool aClosed,
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
ShadowRoot(nsIContent* aContent, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
nsXBLPrototypeBinding* aProtoBinding);
// Shadow DOM v1
Element* Host();
ShadowRootMode Mode() const
{
return mMode;
}
bool IsClosed() const
{
return mMode == ShadowRootMode::Closed;
}
// [deprecated] Shadow DOM v0
void AddToIdTable(Element* aElement, nsIAtom* aId);
void RemoveFromIdTable(Element* aElement, nsIAtom* aId);
void InsertSheet(StyleSheet* aSheet, nsIContent* aLinkingContent);
void RemoveSheet(StyleSheet* aSheet);
bool ApplyAuthorStyles();
void SetApplyAuthorStyles(bool aApplyAuthorStyles);
StyleSheetList* StyleSheets()
{
return &DocumentOrShadowRoot::EnsureDOMStyleSheets();
}
StyleSheetList* StyleSheets();
HTMLShadowElement* GetShadowElement() { return mShadowElement; }
/**
* Sets the current shadow insertion point where the older
* ShadowRoot will be projected.
*/
void SetShadowElement(HTMLShadowElement* aShadowElement);
/**
* Change the node that populates the distribution pool with
* its children. This is distinct from the ShadowRoot host described
* in the specifications. The ShadowRoot host is the element
* which created this ShadowRoot and does not change. The pool host
* is the same as the ShadowRoot host if this is the youngest
* ShadowRoot. If this is an older ShadowRoot, the pool host is
* the <shadow> element in the younger ShadowRoot (if it exists).
*/
void ChangePoolHost(nsIContent* aNewHost);
/**
* Distributes a single explicit child of the pool host to the content
* insertion points in this ShadowRoot.
*/
void DistributeSingleNode(nsIContent* aContent);
/**
* Removes a single explicit child of the pool host from the content
* insertion points in this ShadowRoot.
*/
void RemoveDistributedNode(nsIContent* aContent);
/**
* Distributes all the explicit children of the pool host to the content
@@ -73,57 +89,43 @@ public:
*/
void DistributeAllNodes();
private:
/**
* Try to reassign an element to a slot and returns whether the assignment
* changed.
*/
bool MaybeReassignElement(Element* aElement, const nsAttrValue* aOldValue);
/**
* Try to assign aContent to a slot in the shadow tree, returns the assigned
* slot if found.
*/
const HTMLSlotElement* AssignSlotFor(nsIContent* aContent);
/**
* Unassign aContent from the assigned slot in the shadow tree, returns the
* assigned slot if found.
*
* Note: slot attribute of aContent may have changed already, so pass slot
* name explicity here.
*/
const HTMLSlotElement* UnassignSlotFor(nsIContent* aContent,
const nsAString& aSlotName);
/**
* Called when we redistribute content after insertion points have changed.
*/
void DistributionChanged();
bool IsPooledNode(nsIContent* aChild) const;
public:
void AddSlot(HTMLSlotElement* aSlot);
void RemoveSlot(HTMLSlotElement* aSlot);
void AddInsertionPoint(HTMLContentElement* aInsertionPoint);
void RemoveInsertionPoint(HTMLContentElement* aInsertionPoint);
void SetYoungerShadow(ShadowRoot* aYoungerShadow);
ShadowRoot* GetYoungerShadowRoot() { return mYoungerShadow; }
void SetInsertionPointChanged() { mInsertionPointChanged = true; }
void SetAssociatedBinding(nsXBLBinding* aBinding) { mAssociatedBinding = aBinding; }
nsISupports* GetParentObject() const { return mPoolHost; }
nsIContent* GetPoolHost() { return mPoolHost; }
nsTArray<HTMLShadowElement*>& ShadowDescendants() { return mShadowDescendants; }
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
static bool IsPooledNode(nsIContent* aChild, nsIContent* aContainer,
nsIContent* aHost);
static ShadowRoot* FromNode(nsINode* aNode);
static bool IsShadowInsertionPoint(nsIContent* aContent);
void AddToIdTable(Element* aElement, nsIAtom* aId);
void RemoveFromIdTable(Element* aElement, nsIAtom* aId);
static void RemoveDestInsertionPoint(nsIContent* aInsertionPoint,
nsTArray<nsIContent*>& aDestInsertionPoints);
// WebIDL methods.
using mozilla::dom::DocumentOrShadowRoot::GetElementById;
Element* GetActiveElement();
Element* GetElementById(const nsAString& aElementId);
already_AddRefed<nsContentList>
GetElementsByTagName(const nsAString& aNamespaceURI);
already_AddRefed<nsContentList>
GetElementsByTagNameNS(const nsAString& aNamespaceURI,
const nsAString& aLocalName);
already_AddRefed<nsContentList>
GetElementsByClassName(const nsAString& aClasses);
void GetInnerHTML(nsAString& aInnerHTML);
void SetInnerHTML(const nsAString& aInnerHTML, ErrorResult& aError);
Element* Host();
ShadowRoot* GetOlderShadowRoot() { return mOlderShadow; }
void StyleSheetChanged();
bool IsComposedDocParticipant() { return mIsComposedDocParticipant; }
@@ -132,18 +134,26 @@ public:
mIsComposedDocParticipant = aIsComposedDocParticipant;
}
nsresult GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
virtual void DestroyContent() override;
protected:
virtual ~ShadowRoot();
ShadowRootMode mMode;
// The pool host is the parent of the nodes that will be distributed
// into the insertion points in this ShadowRoot. See |ChangeShadowRoot|.
nsCOMPtr<nsIContent> mPoolHost;
// Map from name of slot to an array of all slots in the shadow DOM with with
// the given name. The slots are stored as a weak pointer because the elements
// are in the shadow tree and should be kept alive by its parent.
nsClassHashtable<nsStringHashKey, nsTArray<mozilla::dom::HTMLSlotElement*>> mSlotMap;
// An array of content insertion points that are a descendant of the ShadowRoot
// sorted in tree order. Insertion points are responsible for notifying
// the ShadowRoot when they are removed or added as a descendant. The insertion
// points are kept alive by the parent node, thus weak references are held
// by the array.
nsTArray<HTMLContentElement*> mInsertionPoints;
// An array of the <shadow> elements that are descendant of the ShadowRoot
// sorted in tree order. Only the first may be a shadow insertion point.
nsTArray<HTMLShadowElement*> mShadowDescendants;
nsTHashtable<nsIdentifierMapEntry> mIdentifierMap;
nsXBLPrototypeBinding* mProtoBinding;
// It is necessary to hold a reference to the associated nsXBLBinding
@@ -151,6 +161,19 @@ protected:
// owns |mProtoBinding|.
RefPtr<nsXBLBinding> mAssociatedBinding;
RefPtr<ShadowRootStyleSheetList> mStyleSheetList;
// The current shadow insertion point of this ShadowRoot.
HTMLShadowElement* mShadowElement;
// The ShadowRoot that was created by the host element before
// this ShadowRoot was created.
RefPtr<ShadowRoot> mOlderShadow;
// The ShadowRoot that was created by the host element after
// this ShadowRoot was created.
RefPtr<ShadowRoot> mYoungerShadow;
// A boolean that indicates that an insertion point was added or removed
// from this ShadowRoot and that the nodes need to be redistributed into
// the insertion points. After this flag is set, nodes will be distributed
@@ -166,6 +189,28 @@ protected:
nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const override;
};
class ShadowRootStyleSheetList : public StyleSheetList
{
public:
explicit ShadowRootStyleSheetList(ShadowRoot* aShadowRoot);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ShadowRootStyleSheetList, StyleSheetList)
virtual nsINode* GetParentObject() const override
{
return mShadowRoot;
}
uint32_t Length() override;
StyleSheet* IndexedGetter(uint32_t aIndex, bool& aFound) override;
protected:
virtual ~ShadowRootStyleSheetList();
RefPtr<ShadowRoot> mShadowRoot;
};
} // namespace dom
} // namespace mozilla
+1 -22
View File
@@ -8,7 +8,6 @@
#include "mozilla/CSSStyleSheet.h"
#include "mozilla/dom/StyleSheetListBinding.h"
#include "nsStubDocumentObserver.h"
namespace mozilla {
namespace dom {
@@ -18,8 +17,7 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(StyleSheetList)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(StyleSheetList)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsIDOMStyleSheetList)
NS_INTERFACE_MAP_ENTRY(nsIMutationObserver)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMStyleSheetList)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(StyleSheetList)
@@ -45,24 +43,5 @@ StyleSheetList::SlowItem(uint32_t aIndex, nsIDOMStyleSheet** aItem)
return NS_OK;
}
void
StyleSheetList::NodeWillBeDestroyed(const nsINode* aNode)
{
mDocumentOrShadowRoot = nullptr;
}
StyleSheetList::StyleSheetList(DocumentOrShadowRoot& aScope)
: mDocumentOrShadowRoot(&aScope)
{
mDocumentOrShadowRoot->AsNode().AddMutationObserver(this);
}
StyleSheetList::~StyleSheetList()
{
if (mDocumentOrShadowRoot) {
mDocumentOrShadowRoot->AsNode().RemoveMutationObserver(this);
}
}
} // namespace dom
} // namespace mozilla
+8 -36
View File
@@ -7,10 +7,8 @@
#ifndef mozilla_dom_StyleSheetList_h
#define mozilla_dom_StyleSheetList_h
#include "mozilla/dom/DocumentOrShadowRoot.h"
#include "nsIDOMStyleSheetList.h"
#include "nsWrapperCache.h"
#include "nsStubDocumentObserver.h"
class nsINode;
@@ -19,54 +17,28 @@ class StyleSheet;
namespace dom {
class StyleSheetList final : public nsIDOMStyleSheetList
, public nsWrapperCache
, public nsStubDocumentObserver
class StyleSheetList : public nsIDOMStyleSheetList
, public nsWrapperCache
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(StyleSheetList, nsIDOMStyleSheetList)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(StyleSheetList)
NS_DECL_NSIDOMSTYLESHEETLIST
NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED
explicit StyleSheetList(DocumentOrShadowRoot& aScope);
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override final;
nsINode* GetParentObject() const
{
return mDocumentOrShadowRoot ? &mDocumentOrShadowRoot->AsNode() : nullptr;
}
virtual nsINode* GetParentObject() const = 0;
uint32_t Length() const
{
return mDocumentOrShadowRoot ? mDocumentOrShadowRoot->SheetCount() : 0;
}
StyleSheet* IndexedGetter(uint32_t aIndex, bool& aFound) const
{
if (!mDocumentOrShadowRoot) {
aFound = false;
return nullptr;
}
StyleSheet* sheet = mDocumentOrShadowRoot->SheetAt(aIndex);
aFound = !!sheet;
return sheet;
}
StyleSheet* Item(uint32_t aIndex) const
virtual uint32_t Length() = 0;
virtual StyleSheet* IndexedGetter(uint32_t aIndex, bool& aFound) = 0;
StyleSheet* Item(uint32_t aIndex)
{
bool dummy = false;
return IndexedGetter(aIndex, dummy);
}
protected:
virtual ~StyleSheetList();
DocumentOrShadowRoot* mDocumentOrShadowRoot; // Weak, cleared on "NodeWillBeDestroyed".
virtual ~StyleSheetList() {}
};
} // namespace dom
+33
View File
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script>
var frameRoot;
function boom()
{
var frameWin = f.contentWindow;
frameRoot = frameWin.document.documentElement;
frameWin.location.replace("data:text/html;charset=UTF-8,<body onload='parent.g();'>2");
}
function g()
{
setTimeout(h, 0);
}
function h()
{
var newDoc = document.implementation.createDocument('', '', null);
newDoc.adoptNode(frameRoot);
}
</script>
<body onload="boom();">
<iframe id="f" src="data:text/html;charset=UTF-8,<marquee>1"></iframe>
</body>
</html>
-13
View File
@@ -1,13 +0,0 @@
<!DOCTYPE html>
<html>
<body>
<script>
var o1 = document.documentElement;
var o2 = document.createElement("frame");
document.documentElement.appendChild(o2);
var o3 = o2.contentWindow;
o1.parentNode.removeChild(o1);
o3.customElements;
</script>
</body>
</html>
-17
View File
@@ -1,17 +0,0 @@
<html>
<head>
<script>
try { o1 = document.createElement('textarea') } catch(e) { }
try { o2 = document.createElement('div') } catch(e) { }
try { o3 = document.createElement('map') } catch(e) { }
try { document.documentElement.appendChild(o2) } catch(e) { }
try { o2.appendChild(o1) } catch(e) { }
try { document.documentElement.getClientRects() } catch(e) { }
try { o4 = o2.attachShadow({ mode: "open" }); } catch(e) { }
try { o1.appendChild(o3) } catch(e) { }
try { o5 = o3.parentElement } catch(e) { }
try { o3.outerHTML = "\n" } catch(e) { }
try { o4.prepend("", o5, "") } catch(e) { }
</script>
</head>
</html>
-6
View File
@@ -1,6 +0,0 @@
<!DOCTYPE html>
<html>
<body>
<!-- Testing slot element with "dom.webcomponents.enabled" set to false -->
<slot><div></div></slot>
</html>
+24
View File
@@ -0,0 +1,24 @@
<html xmlns="http://www.w3.org/1999/xhtml" class="reftest-wait">
<head>
<script>
function boom()
{
var marquee = document.getElementById("marquee");
var span = document.getElementById("span");
marquee.appendChild(span);
marquee.removeChild(span);
document.documentElement.removeAttribute("class");
}
</script>
</head>
<body onload="setTimeout(boom, 30);">
<marquee id="marquee" />
<span id="span"><div>Foo</div><textarea/></span>
</body>
</html>
+28
View File
@@ -0,0 +1,28 @@
<html class="reftest-wait">
<head>
<script type="text/javascript">
var i = 0;
function mmf()
{
if (++i == 2) {
document.body.innerHTML = "<marquee>";
document.documentElement.removeAttribute("class");
}
}
function init()
{
document.documentElement.offsetHeight;
for (var j = 0; j < 2; ++j) {
var iframe = document.createElementNS("http://www.w3.org/1999/xhtml", "iframe");
iframe.addEventListener("load", mmf, false);
document.body.appendChild(iframe);
}
}
</script>
</head>
<body onload="setTimeout(init, 0);"></body>
</html>
+1 -4
View File
@@ -193,7 +193,7 @@ load 930250.html
load 942979.html
load 973401.html
load 978646.html
pref(dom.webcomponents.enabled,true) load 1024428-1.html # bug 1340009
pref(dom.webcomponents.enabled,true) load 1024428-1.html
load 1026714.html
pref(dom.webcomponents.enabled,true) load 1027461-1.html
pref(dom.webcomponents.enabled,true) load 1029710.html
@@ -209,6 +209,3 @@ load 1230422.html
load 1251361.html
load 1304437.html
pref(clipboard.autocopy,true) load 1385272-1.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
-3
View File
@@ -86,7 +86,6 @@ EXPORTS += [
'nsIContentInlines.h',
'nsIContentIterator.h',
'nsIContentSerializer.h',
'nsIdentifierMapEntry.h',
'nsIDocument.h',
'nsIDocumentInlines.h',
'nsIDocumentObserver.h',
@@ -164,7 +163,6 @@ EXPORTS.mozilla.dom += [
'DirectionalityUtils.h',
'DocGroup.h',
'DocumentFragment.h',
'DocumentOrShadowRoot.h',
'DocumentType.h',
'DOMCursor.h',
'DOMError.h',
@@ -243,7 +241,6 @@ SOURCES += [
'DirectionalityUtils.cpp',
'DocGroup.cpp',
'DocumentFragment.cpp',
'DocumentOrShadowRoot.cpp',
'DocumentType.cpp',
'DOMCursor.cpp',
'DOMError.cpp',
+10 -24
View File
@@ -382,15 +382,12 @@ nsAttrAndChildArray::AttrAt(uint32_t aPos) const
}
nsresult
nsAttrAndChildArray::SetAndSwapAttr(nsIAtom* aLocalName, nsAttrValue& aValue,
bool* aHadValue)
nsAttrAndChildArray::SetAndSwapAttr(nsIAtom* aLocalName, nsAttrValue& aValue)
{
*aHadValue = false;
uint32_t i, slotCount = AttrSlotCount();
for (i = 0; i < slotCount && AttrSlotIsTaken(i); ++i) {
if (ATTRS(mImpl)[i].mName.Equals(aLocalName)) {
ATTRS(mImpl)[i].mValue.SwapValueWith(aValue);
*aHadValue = true;
return NS_OK;
}
}
@@ -410,22 +407,21 @@ nsAttrAndChildArray::SetAndSwapAttr(nsIAtom* aLocalName, nsAttrValue& aValue,
}
nsresult
nsAttrAndChildArray::SetAndSwapAttr(mozilla::dom::NodeInfo* aName,
nsAttrValue& aValue, bool* aHadValue)
nsAttrAndChildArray::SetAndSwapAttr(mozilla::dom::NodeInfo* aName, nsAttrValue& aValue)
{
int32_t namespaceID = aName->NamespaceID();
nsIAtom* localName = aName->NameAtom();
if (namespaceID == kNameSpaceID_None) {
return SetAndSwapAttr(localName, aValue, aHadValue);
return SetAndSwapAttr(localName, aValue);
}
*aHadValue = false;
uint32_t i, slotCount = AttrSlotCount();
for (i = 0; i < slotCount && AttrSlotIsTaken(i); ++i) {
if (ATTRS(mImpl)[i].mName.Equals(localName, namespaceID)) {
ATTRS(mImpl)[i].mName.SetTo(aName);
ATTRS(mImpl)[i].mValue.Reset();
ATTRS(mImpl)[i].mValue.SwapValueWith(aValue);
*aHadValue = true;
return NS_OK;
}
}
@@ -580,11 +576,10 @@ nsAttrAndChildArray::IndexOfAttr(nsIAtom* aLocalName, int32_t aNamespaceID) cons
}
nsresult
nsAttrAndChildArray::SetAndSwapMappedAttr(nsIAtom* aLocalName,
nsAttrAndChildArray::SetAndTakeMappedAttr(nsIAtom* aLocalName,
nsAttrValue& aValue,
nsMappedAttributeElement* aContent,
nsHTMLStyleSheet* aSheet,
bool* aHadValue)
nsHTMLStyleSheet* aSheet)
{
bool willAdd = true;
if (mImpl && mImpl->mMappedAttrs) {
@@ -594,7 +589,7 @@ nsAttrAndChildArray::SetAndSwapMappedAttr(nsIAtom* aLocalName,
RefPtr<nsMappedAttributes> mapped =
GetModifiableMapped(aContent, aSheet, willAdd);
mapped->SetAndSwapAttr(aLocalName, aValue, aHadValue);
mapped->SetAndTakeAttr(aLocalName, aValue);
return MakeMappedUnique(mapped);
}
@@ -719,19 +714,10 @@ nsAttrAndChildArray::MappedAttrCount() const
return mImpl && mImpl->mMappedAttrs ? (uint32_t)mImpl->mMappedAttrs->Count() : 0;
}
nsresult
nsAttrAndChildArray::ForceMapped(nsMappedAttributeElement* aContent, nsIDocument* aDocument)
{
nsHTMLStyleSheet* sheet = aDocument->GetAttributeStyleSheet();
RefPtr<nsMappedAttributes> mapped = GetModifiableMapped(aContent, sheet, false, 0);
return MakeMappedUnique(mapped);
}
nsMappedAttributes*
nsAttrAndChildArray::GetModifiableMapped(nsMappedAttributeElement* aContent,
nsHTMLStyleSheet* aSheet,
bool aWillAddAttr,
int32_t aAttrCount)
bool aWillAddAttr)
{
if (mImpl && mImpl->mMappedAttrs) {
return mImpl->mMappedAttrs->Clone(aWillAddAttr);
@@ -741,7 +727,7 @@ nsAttrAndChildArray::GetModifiableMapped(nsMappedAttributeElement* aContent,
nsMapRuleToAttributesFunc mapRuleFunc =
aContent->GetAttributeMappingFunction();
return new (aAttrCount) nsMappedAttributes(aSheet, mapRuleFunc);
return new nsMappedAttributes(aSheet, mapRuleFunc);
}
nsresult
+5 -19
View File
@@ -91,13 +91,8 @@ public:
nsCaseTreatment aCaseSensitive) const;
const nsAttrValue* AttrAt(uint32_t aPos) const;
// SetAndSwapAttr swaps the current attribute value with aValue.
// If the attribute was unset, an empty value will be swapped into aValue
// and aHadValue will be set to false. Otherwise, aHadValue will be set to
// true.
nsresult SetAndSwapAttr(nsIAtom* aLocalName, nsAttrValue& aValue,
bool* aHadValue);
nsresult SetAndSwapAttr(mozilla::dom::NodeInfo* aName, nsAttrValue& aValue,
bool* aHadValue);
nsresult SetAndSwapAttr(nsIAtom* aLocalName, nsAttrValue& aValue);
nsresult SetAndSwapAttr(mozilla::dom::NodeInfo* aName, nsAttrValue& aValue);
// Remove the attr at position aPos. The value of the attr is placed in
// aValue; any value that was already in aValue is destroyed.
@@ -115,14 +110,9 @@ public:
const nsAttrName* GetExistingAttrNameFromQName(const nsAString& aName) const;
int32_t IndexOfAttr(nsIAtom* aLocalName, int32_t aNamespaceID = kNameSpaceID_None) const;
// SetAndSwapMappedAttr swaps the current attribute value with aValue.
// If the attribute was unset, an empty value will be swapped into aValue
// and aHadValue will be set to false. Otherwise, aHadValue will be set to
// true.
nsresult SetAndSwapMappedAttr(nsIAtom* aLocalName, nsAttrValue& aValue,
nsresult SetAndTakeMappedAttr(nsIAtom* aLocalName, nsAttrValue& aValue,
nsMappedAttributeElement* aContent,
nsHTMLStyleSheet* aSheet,
bool* aHadValue);
nsHTMLStyleSheet* aSheet);
nsresult SetMappedAttrStyleSheet(nsHTMLStyleSheet* aSheet) {
if (!mImpl || !mImpl->mMappedAttrs) {
return NS_OK;
@@ -145,9 +135,6 @@ public:
return MappedAttrCount();
}
// Force this to have mapped attributes, even if those attributes are empty.
nsresult ForceMapped(nsMappedAttributeElement* aContent, nsIDocument* aDocument);
private:
nsAttrAndChildArray(const nsAttrAndChildArray& aOther) = delete;
nsAttrAndChildArray& operator=(const nsAttrAndChildArray& aOther) = delete;
@@ -161,8 +148,7 @@ private:
nsMappedAttributes*
GetModifiableMapped(nsMappedAttributeElement* aContent,
nsHTMLStyleSheet* aSheet,
bool aWillAddAttr,
int32_t aAttrCount = 1);
bool aWillAddAttr);
nsresult MakeMappedUnique(nsMappedAttributes* aAttributes);
uint32_t AttrSlotsSize() const
+12 -18
View File
@@ -49,13 +49,20 @@ public:
, mCheapString(nullptr)
{ }
void ResetToAttrValue(const nsAttrValue& aValue)
void TakeParsedValue(nsAttrValue& aValue)
{
mAttrValue = &aValue;
mStoredAttrValue.SwapValueWith(aValue);
mAttrValue = &mStoredAttrValue;
mStringPtr = nullptr;
// No need to touch mCheapString here. If we need to use it, we will reset
// it to the rigthe value anyway.
}
/**
* If TakeParsedValue has been called, returns the value that it set.
*/
nsAttrValue* GetStoredAttrValue()
{
return mAttrValue == &mStoredAttrValue ? &mStoredAttrValue : nullptr;
}
const nsAttrValue* GetAttrValue() { return mAttrValue; }
/**
* Returns a reference to the string value of the contents of this object.
@@ -78,24 +85,11 @@ public:
return aOther.EqualsAsStrings(*mAttrValue);
}
/*
* Returns true if the value stored is empty
*/
bool IsEmpty() const
{
if (mStringPtr) {
return mStringPtr->IsEmpty();
}
if (mAttrValue) {
return mAttrValue->IsEmptyString();
}
return true;
}
protected:
const nsAttrValue* mAttrValue;
mutable const nsAString* mStringPtr;
mutable nsCheapString mCheapString;
nsAttrValue mStoredAttrValue;
};
#endif // nsAttrValueOrString_h___
+1 -3
View File
@@ -24,7 +24,6 @@ namespace mozilla {
namespace dom {
class Element;
class NodeInfo;
struct CustomElementDefinition;
} // namespace dom
} // namespace mozilla
@@ -42,8 +41,7 @@ nsresult
NS_NewHTMLElement(mozilla::dom::Element** aResult,
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
mozilla::dom::FromParser aFromParser,
const nsAString* aIs = nullptr,
mozilla::dom::CustomElementDefinition* aDefinition = nullptr);
const nsAString* aIs = nullptr);
// First argument should be nsHTMLTag, but that adds dependency to parser
// for a bunch of files.
+164 -163
View File
@@ -44,8 +44,9 @@
#include "mozilla/dom/Element.h"
#include "mozilla/dom/FileSystemSecurity.h"
#include "mozilla/dom/HTMLMediaElement.h"
#include "mozilla/dom/HTMLSlotElement.h"
#include "mozilla/dom/HTMLTemplateElement.h"
#include "mozilla/dom/HTMLContentElement.h"
#include "mozilla/dom/HTMLShadowElement.h"
#include "mozilla/dom/ipc/BlobChild.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "mozilla/dom/Promise.h"
@@ -101,9 +102,7 @@
#include "nsHostObjectProtocolHandler.h"
#include "nsHtml5Module.h"
#include "nsHtml5StringParser.h"
#include "nsHTMLTags.h"
#include "nsIAddonPolicyService.h"
#include "nsIAnonymousContentCreator.h"
#include "nsIAsyncVerifyRedirectCallback.h"
#include "nsICategoryManager.h"
#include "nsIChannelEventSink.h"
@@ -228,7 +227,6 @@ extern "C" int MOZ_XMLCheckQName(const char* ptr, const char* end,
int ns_aware, const char** colon);
class imgLoader;
class nsIAtom;
using namespace mozilla::dom;
using namespace mozilla::ipc;
@@ -260,6 +258,7 @@ nsIWordBreaker *nsContentUtils::sWordBreaker;
nsIBidiKeyboard *nsContentUtils::sBidiKeyboard = nullptr;
uint32_t nsContentUtils::sScriptBlockerCount = 0;
uint32_t nsContentUtils::sDOMNodeRemovedSuppressCount = 0;
uint32_t nsContentUtils::sMicroTaskLevel = 0;
AutoTArray<nsCOMPtr<nsIRunnable>, 8>* nsContentUtils::sBlockedScriptRunners = nullptr;
uint32_t nsContentUtils::sRunnersCountAtFirstBlocker = 0;
nsIInterfaceRequestor* nsContentUtils::sSameOriginChecker = nullptr;
@@ -285,8 +284,6 @@ bool nsContentUtils::sIsResourceTimingEnabled = false;
bool nsContentUtils::sIsPerformanceNavigationTimingEnabled = false;
bool nsContentUtils::sIsUserTimingLoggingEnabled = false;
bool nsContentUtils::sIsExperimentalAutocompleteEnabled = false;
bool nsContentUtils::sIsWebComponentsEnabled = false;
bool nsContentUtils::sIsCustomElementsEnabled = false;
bool nsContentUtils::sEncodeDecodeURLHash = false;
bool nsContentUtils::sGettersDecodeURLHash = false;
bool nsContentUtils::sPrivacyResistFingerprinting = false;
@@ -501,8 +498,6 @@ nsContentUtils::Init()
return NS_OK;
}
nsHTMLTags::AddRefTable();
sNameSpaceManager = nsNameSpaceManager::GetInstance();
NS_ENSURE_TRUE(sNameSpaceManager, NS_ERROR_OUT_OF_MEMORY);
@@ -589,12 +584,6 @@ nsContentUtils::Init()
Preferences::AddBoolVarCache(&sIsExperimentalAutocompleteEnabled,
"dom.forms.autocomplete.experimental", false);
Preferences::AddBoolVarCache(&sIsWebComponentsEnabled,
"dom.webcomponents.enabled", false);
Preferences::AddBoolVarCache(&sIsCustomElementsEnabled,
"dom.webcomponents.enabled", false);
Preferences::AddBoolVarCache(&sEncodeDecodeURLHash,
"dom.url.encode_decode_hash", false);
@@ -1929,8 +1918,6 @@ nsContentUtils::Shutdown()
{
sInitialized = false;
nsHTMLTags::ReleaseTable();
NS_IF_RELEASE(sContentPolicyService);
sTriedToGetContentPolicy = false;
uint32_t i;
@@ -2395,9 +2382,6 @@ nsContentUtils::ComparePoints(nsINode* aParent1, int32_t aOffset1,
bool* aDisconnected)
{
if (aParent1 == aParent2) {
// XXX This is odd. aOffset1 and/or aOffset2 may be -1, e.g., it's result
// of nsINode::IndexOf(), but this compares such invalid offset with
// valid offset.
return aOffset1 < aOffset2 ? -1 :
aOffset1 > aOffset2 ? 1 :
0;
@@ -2448,14 +2432,10 @@ nsContentUtils::ComparePoints(nsINode* aParent1, int32_t aOffset1,
if (!pos1) {
nsINode* child2 = parents2.ElementAt(--pos2);
// XXX aOffset1 may be -1 as mentioned above. So, why does this return
// it's *before* of the valid DOM point?
return aOffset1 <= parent->IndexOf(child2) ? -1 : 1;
}
nsINode* child1 = parents1.ElementAt(--pos1);
// XXX aOffset2 may be -1 as mentioned above. So, why does this return it's
// *after* of the valid DOM point?
return parent->IndexOf(child1) < aOffset2 ? -1 : 1;
}
@@ -3658,14 +3638,6 @@ nsContentUtils::ReportToConsole(uint32_t aErrorFlags,
aLineNumber, aColumnNumber);
}
/* static */ void
nsContentUtils::ReportEmptyGetElementByIdArg(const nsIDocument* aDoc)
{
ReportToConsole(nsIScriptError::warningFlag,
NS_LITERAL_CSTRING("DOM"), aDoc,
nsContentUtils::eDOM_PROPERTIES,
"EmptyGetElementByIdParam");
}
/* static */ nsresult
nsContentUtils::ReportToConsoleNonLocalized(const nsAString& aErrorText,
@@ -4963,7 +4935,17 @@ nsContentUtils::IsInSameAnonymousTree(const nsINode* aNode,
return aContent->GetBindingParent() == nullptr;
}
return aNode->AsContent()->GetBindingParent() == aContent->GetBindingParent();
const nsIContent* nodeAsContent = static_cast<const nsIContent*>(aNode);
// For nodes in a shadow tree, it is insufficient to simply compare
// the binding parent because a node may host multiple ShadowRoots,
// thus nodes in different shadow tree may have the same binding parent.
if (aNode->IsInShadowTree()) {
return nodeAsContent->GetContainingShadow() ==
aContent->GetContainingShadow();
}
return nodeAsContent->GetBindingParent() == aContent->GetBindingParent();
}
class AnonymousContentDestroyer : public Runnable {
@@ -5312,6 +5294,51 @@ nsContentUtils::RunInMetastableState(already_AddRefed<nsIRunnable> aRunnable)
CycleCollectedJSContext::Get()->RunInMetastableState(Move(aRunnable));
}
void
nsContentUtils::EnterMicroTask()
{
MOZ_ASSERT(NS_IsMainThread());
++sMicroTaskLevel;
}
void
nsContentUtils::LeaveMicroTask()
{
MOZ_ASSERT(NS_IsMainThread());
if (--sMicroTaskLevel == 0) {
PerformMainThreadMicroTaskCheckpoint();
}
}
bool
nsContentUtils::IsInMicroTask()
{
MOZ_ASSERT(NS_IsMainThread());
return sMicroTaskLevel != 0;
}
uint32_t
nsContentUtils::MicroTaskLevel()
{
MOZ_ASSERT(NS_IsMainThread());
return sMicroTaskLevel;
}
void
nsContentUtils::SetMicroTaskLevel(uint32_t aLevel)
{
MOZ_ASSERT(NS_IsMainThread());
sMicroTaskLevel = aLevel;
}
void
nsContentUtils::PerformMainThreadMicroTaskCheckpoint()
{
MOZ_ASSERT(NS_IsMainThread());
nsDOMMutationObserver::HandleMutations();
}
/*
* Helper function for nsContentUtils::ProcessViewportInfo.
*
@@ -7025,11 +7052,25 @@ nsContentUtils::GetHTMLEditor(nsPresContext* aPresContext)
return editor;
}
bool
nsContentUtils::IsContentInsertionPoint(nsIContent* aContent)
{
// Check if the content is a XBL insertion point.
if (aContent->IsActiveChildrenElement()) {
return true;
}
// Check if the content is a web components content insertion point.
HTMLContentElement* contentElement =
HTMLContentElement::FromContent(aContent);
return contentElement && contentElement->IsInsertionPoint();
}
// static
bool
nsContentUtils::HasDistributedChildren(nsIContent* aContent)
{
if (!aContent || !nsDocument::IsWebComponentsEnabled(aContent)) {
if (!aContent) {
return false;
}
@@ -7039,11 +7080,26 @@ nsContentUtils::HasDistributedChildren(nsIContent* aContent)
return true;
}
HTMLSlotElement* slotEl = HTMLSlotElement::FromContent(aContent);
if (slotEl && slotEl->GetContainingShadow()) {
// Children of a slot are rendered if the slot does not have any assigned
// nodes (fallback content).
return slotEl->AssignedNodes().IsEmpty();
ShadowRoot* shadow = ShadowRoot::FromNode(aContent);
if (shadow) {
// Children of a shadow root are distributed to
// the shadow insertion point of the younger shadow root.
return shadow->GetYoungerShadowRoot();
}
HTMLShadowElement* shadowEl = HTMLShadowElement::FromContent(aContent);
if (shadowEl && shadowEl->IsInsertionPoint()) {
// Children of a shadow insertion points are distributed
// to the insertion points in the older shadow root.
return shadowEl->GetOlderShadowRoot();
}
HTMLContentElement* contentEl = HTMLContentElement::FromContent(aContent);
if (contentEl && contentEl->IsInsertionPoint()) {
// Children of a content insertion point are distributed to the
// content insertion point if the content insertion point does
// not match any nodes (fallback content).
return contentEl->MatchedNodes().IsEmpty();
}
return false;
@@ -9512,34 +9568,11 @@ nsContentUtils::HttpsStateIsModern(nsIDocument* aDocument)
return false;
}
/* static */ void
nsContentUtils::TryToUpgradeElement(Element* aElement)
{
NodeInfo* nodeInfo = aElement->NodeInfo();
RefPtr<nsIAtom> typeAtom =
aElement->GetCustomElementData()->GetCustomElementType();
MOZ_ASSERT(nodeInfo->NameAtom()->Equals(nodeInfo->LocalName()));
CustomElementDefinition* definition =
nsContentUtils::LookupCustomElementDefinition(nodeInfo->GetDocument(),
nodeInfo->NameAtom(),
nodeInfo->NamespaceID(),
typeAtom);
if (definition) {
nsContentUtils::EnqueueUpgradeReaction(aElement, definition);
} else {
// Add an unresolved custom element that is a candidate for
// upgrade when a custom element is connected to the document.
// We will make sure it's shadow-including tree order in bug 1326028.
nsContentUtils::RegisterUnresolvedElement(aElement, typeAtom);
}
}
/* static */ CustomElementDefinition*
nsContentUtils::LookupCustomElementDefinition(nsIDocument* aDoc,
nsIAtom* aNameAtom,
const nsAString& aLocalName,
uint32_t aNameSpaceID,
nsIAtom* aTypeAtom)
const nsAString* aIs)
{
MOZ_ASSERT(aDoc);
@@ -9561,16 +9594,30 @@ nsContentUtils::LookupCustomElementDefinition(nsIDocument* aDoc,
return nullptr;
}
return registry->LookupCustomElementDefinition(aNameAtom, aTypeAtom);
return registry->LookupCustomElementDefinition(aLocalName, aIs);
}
/* static */ void
nsContentUtils::RegisterUnresolvedElement(Element* aElement, nsIAtom* aTypeName)
nsContentUtils::SetupCustomElement(Element* aElement,
const nsAString* aTypeExtension)
{
MOZ_ASSERT(aElement);
nsIDocument* doc = aElement->OwnerDoc();
nsPIDOMWindowInner* window(doc->GetInnerWindow());
nsCOMPtr<nsIDocument> doc = aElement->OwnerDoc();
if (!doc) {
return;
}
// To support imported document.
doc = doc->MasterDocument();
if (aElement->GetNameSpaceID() != kNameSpaceID_XHTML ||
!doc->GetDocShell()) {
return;
}
nsCOMPtr<nsPIDOMWindowInner> window(doc->GetInnerWindow());
if (!window) {
return;
}
@@ -9580,80 +9627,65 @@ nsContentUtils::RegisterUnresolvedElement(Element* aElement, nsIAtom* aTypeName)
return;
}
registry->RegisterUnresolvedElement(aElement, aTypeName);
return registry->SetupCustomElement(aElement, aTypeExtension);
}
/* static */ void
nsContentUtils::UnregisterUnresolvedElement(Element* aElement)
{
MOZ_ASSERT(aElement);
RefPtr<nsIAtom> typeAtom =
aElement->GetCustomElementData()->GetCustomElementType();
nsIDocument* doc = aElement->OwnerDoc();
nsPIDOMWindowInner* window(doc->GetInnerWindow());
if (!window) {
return;
}
RefPtr<CustomElementRegistry> registry(window->CustomElements());
if (!registry) {
return;
}
registry->UnregisterUnresolvedElement(aElement, typeAtom);
}
/* static */ CustomElementDefinition*
nsContentUtils::GetElementDefinitionIfObservingAttr(Element* aCustomElement,
nsIAtom* aExtensionType,
nsIAtom* aAttrName)
{
CustomElementDefinition* definition =
aCustomElement->GetCustomElementDefinition();
// Custom element not defined yet or attribute is not in the observed
// attribute list.
if (!definition || !definition->IsInObservedAttributeList(aAttrName)) {
return nullptr;
}
return definition;
}
/* static */ void
nsContentUtils::EnqueueUpgradeReaction(Element* aElement,
CustomElementDefinition* aDefinition)
{
MOZ_ASSERT(aElement);
nsIDocument* doc = aElement->OwnerDoc();
// No DocGroup means no custom element reactions stack.
if (!doc->GetDocGroup()) {
return;
}
CustomElementReactionsStack* stack =
doc->GetDocGroup()->CustomElementReactionsStack();
stack->EnqueueUpgradeReaction(aElement, aDefinition);
}
/* static */ void
nsContentUtils::EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType,
nsContentUtils::EnqueueLifecycleCallback(nsIDocument* aDoc,
nsIDocument::ElementCallbackType aType,
Element* aCustomElement,
LifecycleCallbackArgs* aArgs,
LifecycleAdoptedCallbackArgs* aAdoptedCallbackArgs,
CustomElementDefinition* aDefinition)
{
// No DocGroup means no custom element reactions stack.
if (!aCustomElement->OwnerDoc()->GetDocGroup()) {
MOZ_ASSERT(aDoc);
// To support imported document.
nsCOMPtr<nsIDocument> doc = aDoc->MasterDocument();
if (!doc->GetDocShell()) {
return;
}
CustomElementRegistry::EnqueueLifecycleCallback(aType, aCustomElement, aArgs,
aAdoptedCallbackArgs,
aDefinition);
nsCOMPtr<nsPIDOMWindowInner> window(doc->GetInnerWindow());
if (!window) {
return;
}
RefPtr<CustomElementRegistry> registry(window->CustomElements());
if (!registry) {
return;
}
registry->EnqueueLifecycleCallback(aType, aCustomElement, aArgs, aDefinition);
}
/* static */ void
nsContentUtils::GetCustomPrototype(nsIDocument* aDoc,
int32_t aNamespaceID,
nsIAtom* aAtom,
JS::MutableHandle<JSObject*> aPrototype)
{
MOZ_ASSERT(aDoc);
// To support imported document.
nsCOMPtr<nsIDocument> doc = aDoc->MasterDocument();
if (aNamespaceID != kNameSpaceID_XHTML ||
!doc->GetDocShell()) {
return;
}
nsCOMPtr<nsPIDOMWindowInner> window(doc->GetInnerWindow());
if (!window) {
return;
}
RefPtr<CustomElementRegistry> registry(window->CustomElements());
if (!registry) {
return;
}
return registry->GetCustomPrototype(aAtom, aPrototype);
}
/* static */ bool
@@ -9789,24 +9821,6 @@ nsContentUtils::AttemptLargeAllocationLoad(nsIHttpChannel* aChannel)
return reloadSucceeded;
}
/* static */ void
nsContentUtils::AppendDocumentLevelNativeAnonymousContentTo(
nsIDocument* aDocument,
nsTArray<nsIContent*>& aElements)
{
MOZ_ASSERT(aDocument);
// XXXheycam This probably needs to find the nsCanvasFrame's NAC too.
if (nsIPresShell* presShell = aDocument->GetShell()) {
if (nsIFrame* scrollFrame = presShell->GetRootScrollFrame()) {
nsIAnonymousContentCreator* creator = do_QueryFrame(scrollFrame);
MOZ_ASSERT(creator,
"scroll frame should always implement nsIAnonymousContentCreator");
creator->AppendAnonymousContentTo(aElements, 0);
}
}
}
/* static */ bool
nsContentUtils::IsLocalRefURL(const nsString& aString)
{
@@ -9821,17 +9835,4 @@ nsContentUtils::IsLocalRefURL(const nsString& aString)
}
return false;
}
/* static */ Element*
nsContentUtils::GetClosestNonNativeAnonymousAncestor(Element* aElement)
{
MOZ_ASSERT(aElement);
MOZ_ASSERT(aElement->IsNativeAnonymous());
Element* e = aElement;
while (e && e->IsNativeAnonymous()) {
e = e->GetParentElement();
}
return e;
}
}
+49 -55
View File
@@ -126,7 +126,6 @@ class EventTarget;
class IPCDataTransfer;
class IPCDataTransferItem;
struct LifecycleCallbackArgs;
struct LifecycleAdoptedCallbackArgs;
class NodeInfo;
class nsIContentChild;
class nsIContentParent;
@@ -339,13 +338,6 @@ public:
* NOTE! If the two nodes aren't in the same connected subtree,
* the result is 1, and the optional aDisconnected parameter
* is set to true.
*
* XXX aOffset1 and aOffset2 should be uint32_t since valid offset value is
* between 0 - UINT32_MAX. However, these methods work even with
* negative offset values! E.g., when aOffset1 is -1 and aOffset is 0,
* these methods return -1. Some root callers depend on this behavior.
* On the other hand, nsINode can have ATTRCHILD_ARRAY_MAX_CHILD_COUN
* (0x3FFFFF) at most. Therefore, they can be int32_t for now.
*/
static int32_t ComparePoints(nsINode* aParent1, int32_t aOffset1,
nsINode* aParent2, int32_t aOffset2,
@@ -589,7 +581,7 @@ public:
/**
* Returns true if |aName| is a valid name to be registered via
* customElements.define.
* document.registerElement.
*/
static bool IsCustomElementName(nsIAtom* aName);
@@ -941,8 +933,6 @@ public:
uint32_t aLineNumber = 0,
uint32_t aColumnNumber = 0);
static void ReportEmptyGetElementByIdArg(const nsIDocument* aDoc);
static void LogMessageToConsole(const char* aMsg);
/**
@@ -1751,6 +1741,17 @@ public:
*/
static void RunInMetastableState(already_AddRefed<nsIRunnable> aRunnable);
// Call EnterMicroTask when you're entering JS execution.
// Usually the best way to do this is to use nsAutoMicroTask.
static void EnterMicroTask();
static void LeaveMicroTask();
static bool IsInMicroTask();
static uint32_t MicroTaskLevel();
static void SetMicroTaskLevel(uint32_t aLevel);
static void PerformMainThreadMicroTaskCheckpoint();
/* Process viewport META data. This gives us information for the scale
* and zoom of a page on mobile devices. We stick the information in
* the document header and use it later on after rendering.
@@ -2416,6 +2417,18 @@ public:
*/
static mozilla::LogModule* DOMDumpLog();
/**
* Returns whether a content is an insertion point for XBL
* bindings or web components ShadowRoot. In web components,
* this corresponds to a <content> element that participates
* in node distribution. In XBL this corresponds to an
* <xbl:children> element in anonymous content.
*
* @param aContent The content to test for being an insertion point.
*/
static bool IsContentInsertionPoint(nsIContent* aContent);
/**
* Returns whether the children of the provided content are
* nodes that are distributed to Shadow DOM insertion points.
@@ -2699,50 +2712,31 @@ public:
*/
static bool HttpsStateIsModern(nsIDocument* aDocument);
/**
* Try to upgrade an element.
* https://html.spec.whatwg.org/multipage/custom-elements.html#concept-try-upgrade
*/
static void TryToUpgradeElement(Element* aElement);
/**
* Looking up a custom element definition.
* https://html.spec.whatwg.org/#look-up-a-custom-element-definition
*/
static mozilla::dom::CustomElementDefinition*
LookupCustomElementDefinition(nsIDocument* aDoc,
nsIAtom* aNameAtom,
const nsAString& aLocalName,
uint32_t aNameSpaceID,
nsIAtom* aTypeAtom);
const nsAString* aIs = nullptr);
static void RegisterUnresolvedElement(Element* aElement, nsIAtom* aTypeName);
static void UnregisterUnresolvedElement(Element* aElement);
static void SetupCustomElement(Element* aElement,
const nsAString* aTypeExtension = nullptr);
static mozilla::dom::CustomElementDefinition*
GetElementDefinitionIfObservingAttr(Element* aCustomElement,
nsIAtom* aExtensionType,
nsIAtom* aAttrName);
static void EnqueueUpgradeReaction(Element* aElement,
mozilla::dom::CustomElementDefinition* aDefinition);
static void EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType,
static void EnqueueLifecycleCallback(nsIDocument* aDoc,
nsIDocument::ElementCallbackType aType,
Element* aCustomElement,
mozilla::dom::LifecycleCallbackArgs* aArgs = nullptr,
mozilla::dom::LifecycleAdoptedCallbackArgs* aAdoptedCallbackArgs = nullptr,
mozilla::dom::CustomElementDefinition* aDefinition = nullptr);
static bool AttemptLargeAllocationLoad(nsIHttpChannel* aChannel);
static void GetCustomPrototype(nsIDocument* aDoc,
int32_t aNamespaceID,
nsIAtom* aAtom,
JS::MutableHandle<JSObject*> prototype);
/**
* Appends all "document level" native anonymous content subtree roots for
* aDocument to aElements. Document level NAC subtrees are those created
* by ancestor frames of the document element's primary frame, such as
* the scrollbar elements created by the root scroll frame.
*/
static void AppendDocumentLevelNativeAnonymousContentTo(
nsIDocument* aDocument,
nsTArray<nsIContent*>& aElements);
static bool AttemptLargeAllocationLoad(nsIHttpChannel* aChannel);
/**
* Detect whether a string is a (CSS) local-url.
@@ -2751,18 +2745,6 @@ public:
static bool
IsLocalRefURL(const nsString& aString);
static bool
IsWebComponentsEnabled() { return sIsWebComponentsEnabled; }
/**
* Walks up the tree from aElement until it finds an element that is
* not native anonymous content. aElement must be NAC itself.
*/
static Element* GetClosestNonNativeAnonymousAncestor(Element* aElement);
static bool
IsCustomElementsEnabled() { return sIsCustomElementsEnabled; }
private:
static bool InitializeEventTable();
@@ -2849,6 +2831,7 @@ private:
static bool sInitialized;
static uint32_t sScriptBlockerCount;
static uint32_t sDOMNodeRemovedSuppressCount;
static uint32_t sMicroTaskLevel;
// Not an nsCOMArray because removing elements from those is slower
static AutoTArray<nsCOMPtr<nsIRunnable>, 8>* sBlockedScriptRunners;
static uint32_t sRunnersCountAtFirstBlocker;
@@ -2869,8 +2852,6 @@ private:
static bool sIsUserTimingLoggingEnabled;
static bool sIsFrameTimingPrefEnabled;
static bool sIsExperimentalAutocompleteEnabled;
static bool sIsWebComponentsEnabled;
static bool sIsCustomElementsEnabled;
static bool sEncodeDecodeURLHash;
static bool sGettersDecodeURLHash;
static bool sPrivacyResistFingerprinting;
@@ -2926,6 +2907,19 @@ public:
}
};
class MOZ_STACK_CLASS nsAutoMicroTask
{
public:
nsAutoMicroTask()
{
nsContentUtils::EnterMicroTask();
}
~nsAutoMicroTask()
{
nsContentUtils::LeaveMicroTask();
}
};
namespace mozilla {
namespace dom {
-6
View File
@@ -524,9 +524,3 @@ nsDOMAttributeMap::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return NamedNodeMapBinding::Wrap(aCx, this, aGivenProto);
}
DocGroup*
nsDOMAttributeMap::GetDocGroup() const
{
return mContent ? mContent->OwnerDoc()->GetDocGroup() : nullptr;
}
-7
View File
@@ -22,11 +22,6 @@
class nsIAtom;
class nsIDocument;
namespace mozilla {
namespace dom {
class DocGroup;
} // namespace dom
} // namespace mozilla
/**
* Structure used as a key for caching Attrs in nsDOMAttributeMap's mAttributeCache.
@@ -92,7 +87,6 @@ class nsDOMAttributeMap final : public nsIDOMMozNamedAttrMap
{
public:
typedef mozilla::dom::Attr Attr;
typedef mozilla::dom::DocGroup DocGroup;
typedef mozilla::dom::Element Element;
typedef mozilla::ErrorResult ErrorResult;
@@ -141,7 +135,6 @@ public:
return mContent;
}
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
DocGroup* GetDocGroup() const;
// WebIDL
Attr* GetNamedItem(const nsAString& aAttrName);
+38 -75
View File
@@ -13,7 +13,6 @@
#include "mozilla/dom/Animation.h"
#include "mozilla/dom/KeyframeEffectReadOnly.h"
#include "mozilla/dom/DocGroup.h"
#include "nsContentUtils.h"
#include "nsCSSPseudoElements.h"
@@ -37,6 +36,8 @@ using namespace mozilla::dom;
AutoTArray<RefPtr<nsDOMMutationObserver>, 4>*
nsDOMMutationObserver::sScheduledMutationObservers = nullptr;
nsDOMMutationObserver* nsDOMMutationObserver::sCurrentObserver = nullptr;
uint32_t nsDOMMutationObserver::sMutationLevel = 0;
uint64_t nsDOMMutationObserver::sCount = 0;
@@ -600,54 +601,10 @@ nsDOMMutationObserver::ScheduleForRun()
RescheduleForRun();
}
class MutationObserverMicroTask final : public MicroTaskRunnable
{
public:
virtual void Run(AutoSlowOperation& aAso) override
{
nsDOMMutationObserver::HandleMutations(aAso);
}
virtual bool Suppressed() override
{
return nsDOMMutationObserver::AllScheduledMutationObserversAreSuppressed();
}
};
/* static */ void
nsDOMMutationObserver::QueueMutationObserverMicroTask()
{
CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get();
if (!ccjs) {
return;
}
RefPtr<MutationObserverMicroTask> momt =
new MutationObserverMicroTask();
ccjs->DispatchMicroTaskRunnable(momt.forget());
}
void
nsDOMMutationObserver::HandleMutations(mozilla::AutoSlowOperation& aAso)
{
if (sScheduledMutationObservers ||
mozilla::dom::DocGroup::sPendingDocGroups) {
HandleMutationsInternal(aAso);
}
}
void
nsDOMMutationObserver::RescheduleForRun()
{
if (!sScheduledMutationObservers) {
CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get();
if (!ccjs) {
return;
}
RefPtr<MutationObserverMicroTask> momt =
new MutationObserverMicroTask();
ccjs->DispatchMicroTaskRunnable(momt.forget());
sScheduledMutationObservers = new AutoTArray<RefPtr<nsDOMMutationObserver>, 4>;
}
@@ -909,47 +866,57 @@ nsDOMMutationObserver::HandleMutation()
mCallback->Call(this, mutations, *this);
}
void
nsDOMMutationObserver::HandleMutationsInternal(AutoSlowOperation& aAso)
class AsyncMutationHandler : public mozilla::Runnable
{
nsTArray<RefPtr<nsDOMMutationObserver> >* suppressedObservers = nullptr;
public:
NS_IMETHOD Run() override
{
nsDOMMutationObserver::HandleMutations();
return NS_OK;
}
};
// Let signalList be a copy of unit of related similar-origin browsing
// contexts' signal slot list.
nsTArray<RefPtr<HTMLSlotElement>> signalList;
if (DocGroup::sPendingDocGroups) {
for (uint32_t i = 0; i < DocGroup::sPendingDocGroups->Length(); ++i) {
DocGroup* docGroup = DocGroup::sPendingDocGroups->ElementAt(i);
signalList.AppendElements(docGroup->SignalSlotList());
// Empty unit of related similar-origin browsing contexts' signal slot
// list.
docGroup->ClearSignalSlotList();
}
delete DocGroup::sPendingDocGroups;
DocGroup::sPendingDocGroups = nullptr;
void
nsDOMMutationObserver::HandleMutationsInternal()
{
if (!nsContentUtils::IsSafeToRunScript()) {
nsContentUtils::AddScriptRunner(new AsyncMutationHandler());
return;
}
static RefPtr<nsDOMMutationObserver> sCurrentObserver;
if (sCurrentObserver && !sCurrentObserver->Suppressed()) {
// In normal cases sScheduledMutationObservers will be handled
// after previous mutations are handled. But in case some
// callback calls a sync API, which spins the eventloop, we need to still
// process other mutations happening during that sync call.
// This does *not* catch all cases, but should work for stuff running
// in separate tabs.
return;
}
if (sScheduledMutationObservers) {
mozilla::AutoSlowOperation aso;
nsTArray<RefPtr<nsDOMMutationObserver> >* suppressedObservers = nullptr;
while (sScheduledMutationObservers) {
AutoTArray<RefPtr<nsDOMMutationObserver>, 4>* observers =
sScheduledMutationObservers;
sScheduledMutationObservers = nullptr;
for (uint32_t i = 0; i < observers->Length(); ++i) {
RefPtr<nsDOMMutationObserver> currentObserver =
static_cast<nsDOMMutationObserver*>((*observers)[i]);
if (!currentObserver->Suppressed()) {
currentObserver->HandleMutation();
sCurrentObserver = static_cast<nsDOMMutationObserver*>((*observers)[i]);
if (!sCurrentObserver->Suppressed()) {
sCurrentObserver->HandleMutation();
} else {
if (!suppressedObservers) {
suppressedObservers = new nsTArray<RefPtr<nsDOMMutationObserver> >;
}
if (!suppressedObservers->Contains(currentObserver)) {
suppressedObservers->AppendElement(currentObserver);
if (!suppressedObservers->Contains(sCurrentObserver)) {
suppressedObservers->AppendElement(sCurrentObserver);
}
}
}
delete observers;
aAso.CheckForInterrupt();
aso.CheckForInterrupt();
}
if (suppressedObservers) {
@@ -960,11 +927,7 @@ nsDOMMutationObserver::HandleMutationsInternal(AutoSlowOperation& aAso)
delete suppressedObservers;
suppressedObservers = nullptr;
}
// Fire slotchange event for each slot in signalList.
for (uint32_t i = 0; i < signalList.Length(); ++i) {
signalList[i]->FireSlotChangeEvent();
}
sCurrentObserver = nullptr;
}
nsDOMMutationRecord*
+4 -16
View File
@@ -552,24 +552,11 @@ public:
}
// static methods
static void QueueMutationObserverMicroTask();
static void HandleMutations(mozilla::AutoSlowOperation& aAso);
static bool AllScheduledMutationObserversAreSuppressed()
static void HandleMutations()
{
if (sScheduledMutationObservers) {
uint32_t len = sScheduledMutationObservers->Length();
if (len > 0) {
for (uint32_t i = 0; i < len; ++i) {
if (!(*sScheduledMutationObservers)[i]->Suppressed()) {
return false;
}
}
return true;
}
HandleMutationsInternal();
}
return false;
}
static void EnterMutationHandling();
@@ -607,7 +594,7 @@ protected:
return false;
}
static void HandleMutationsInternal(mozilla::AutoSlowOperation& aAso);
static void HandleMutationsInternal();
static void AddCurrentlyHandlingObserver(nsDOMMutationObserver* aObserver,
uint32_t aMutationLevel);
@@ -635,6 +622,7 @@ protected:
static uint64_t sCount;
static AutoTArray<RefPtr<nsDOMMutationObserver>, 4>* sScheduledMutationObservers;
static nsDOMMutationObserver* sCurrentObserver;
static uint32_t sMutationLevel;
static AutoTArray<AutoTArray<RefPtr<nsDOMMutationObserver>, 4>, 4>*
-6
View File
@@ -366,12 +366,6 @@ nsDOMTokenList::Stringify(nsAString& aResult)
mElement->GetAttr(kNameSpaceID_None, mAttrAtom, aResult);
}
DocGroup*
nsDOMTokenList::GetDocGroup() const
{
return mElement ? mElement->OwnerDoc()->GetDocGroup() : nullptr;
}
JSObject*
nsDOMTokenList::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
{
+1 -6
View File
@@ -22,9 +22,7 @@
namespace mozilla {
class ErrorResult;
namespace dom {
class DocGroup;
} // namespace dom
} // namespace mozilla
class nsAttrValue;
@@ -37,7 +35,6 @@ class nsDOMTokenList : public nsISupports,
{
protected:
typedef mozilla::dom::Element Element;
typedef mozilla::dom::DocGroup DocGroup;
typedef nsWhitespaceTokenizerTemplate<nsContentUtils::IsHTMLWhitespace>
WhitespaceTokenizer;
@@ -55,8 +52,6 @@ public:
return mElement;
}
DocGroup* GetDocGroup() const;
uint32_t Length();
void Item(uint32_t aIndex, nsAString& aResult)
{
+4 -4
View File
@@ -3473,7 +3473,7 @@ nsDOMWindowUtils::AddSheet(nsIDOMStyleSheet *aSheet, uint32_t aSheetType)
nsIDocument::additionalSheetType type = convertSheetType(aSheetType);
RefPtr<CSSStyleSheet> sheet = do_QueryObject(aSheet);
NS_ENSURE_TRUE(sheet, NS_ERROR_FAILURE);
if (sheet->GetAssociatedDocument()) {
if (sheet->GetOwningDocument()) {
return NS_ERROR_INVALID_ARG;
}
return doc->AddAdditionalStyleSheet(type, sheet);
@@ -3658,11 +3658,11 @@ nsDOMWindowUtils::GetOMTAStyle(nsIDOMElement* aElement,
RefPtr<nsROCSSPrimitiveValue> cssValue = nullptr;
nsIFrame* frame = element->GetPrimaryFrame();
if (!aPseudoElement.IsEmpty()) {
if (frame && !aPseudoElement.IsEmpty()) {
if (aPseudoElement.EqualsLiteral("::before")) {
frame = nsLayoutUtils::GetBeforeFrame(element);
frame = nsLayoutUtils::GetBeforeFrame(frame);
} else if (aPseudoElement.EqualsLiteral("::after")) {
frame = nsLayoutUtils::GetAfterFrame(element);
frame = nsLayoutUtils::GetAfterFrame(frame);
} else {
return NS_ERROR_INVALID_ARG;
}
+494 -196
View File
File diff suppressed because it is too large. Load diff
+235 -15
View File
@@ -19,7 +19,6 @@
#include "nsWeakReference.h"
#include "nsWeakPtr.h"
#include "nsTArray.h"
#include "nsIdentifierMapEntry.h"
#include "nsIDOMDocument.h"
#include "nsIDOMDocumentXBL.h"
#include "nsStubDocumentObserver.h"
@@ -131,6 +130,151 @@ public:
} // namespace dom
} // namespace mozilla
/**
* Right now our identifier map entries contain information for 'name'
* and 'id' mappings of a given string. This is so that
* nsHTMLDocument::ResolveName only has to do one hash lookup instead
* of two. It's not clear whether this still matters for performance.
*
* We also store the document.all result list here. This is mainly so that
* when all elements with the given ID are removed and we remove
* the ID's nsIdentifierMapEntry, the document.all result is released too.
* Perhaps the document.all results should have their own hashtable
* in nsHTMLDocument.
*/
class nsIdentifierMapEntry : public nsStringHashKey
{
public:
typedef mozilla::dom::Element Element;
typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
explicit nsIdentifierMapEntry(const nsAString& aKey) :
nsStringHashKey(&aKey), mNameContentList(nullptr)
{
}
explicit nsIdentifierMapEntry(const nsAString* aKey) :
nsStringHashKey(aKey), mNameContentList(nullptr)
{
}
nsIdentifierMapEntry(const nsIdentifierMapEntry& aOther) :
nsStringHashKey(&aOther.GetKey())
{
NS_ERROR("Should never be called");
}
~nsIdentifierMapEntry();
void AddNameElement(nsINode* aDocument, Element* aElement);
void RemoveNameElement(Element* aElement);
bool IsEmpty();
nsBaseContentList* GetNameContentList() {
return mNameContentList;
}
bool HasNameElement() const {
return mNameContentList && mNameContentList->Length() != 0;
}
/**
* Returns the element if we know the element associated with this
* id. Otherwise returns null.
*/
Element* GetIdElement();
/**
* Returns the list of all elements associated with this id.
*/
const nsTArray<Element*>& GetIdElements() const {
return mIdContentList;
}
/**
* If this entry has a non-null image element set (using SetImageElement),
* the image element will be returned, otherwise the same as GetIdElement().
*/
Element* GetImageIdElement();
/**
* Append all the elements with this id to aElements
*/
void AppendAllIdContent(nsCOMArray<nsIContent>* aElements);
/**
* This can fire ID change callbacks.
* @return true if the content could be added, false if we failed due
* to OOM.
*/
bool AddIdElement(Element* aElement);
/**
* This can fire ID change callbacks.
*/
void RemoveIdElement(Element* aElement);
/**
* Set the image element override for this ID. This will be returned by
* GetIdElement(true) if non-null.
*/
void SetImageElement(Element* aElement);
bool HasIdElementExposedAsHTMLDocumentProperty();
bool HasContentChangeCallback() { return mChangeCallbacks != nullptr; }
void AddContentChangeCallback(nsIDocument::IDTargetObserver aCallback,
void* aData, bool aForImage);
void RemoveContentChangeCallback(nsIDocument::IDTargetObserver aCallback,
void* aData, bool aForImage);
/**
* Remove all elements and notify change listeners.
*/
void ClearAndNotify();
void Traverse(nsCycleCollectionTraversalCallback* aCallback);
struct ChangeCallback {
nsIDocument::IDTargetObserver mCallback;
void* mData;
bool mForImage;
};
struct ChangeCallbackEntry : public PLDHashEntryHdr {
typedef const ChangeCallback KeyType;
typedef const ChangeCallback* KeyTypePointer;
explicit ChangeCallbackEntry(const ChangeCallback* aKey) :
mKey(*aKey) { }
ChangeCallbackEntry(const ChangeCallbackEntry& toCopy) :
mKey(toCopy.mKey) { }
KeyType GetKey() const { return mKey; }
bool KeyEquals(KeyTypePointer aKey) const {
return aKey->mCallback == mKey.mCallback &&
aKey->mData == mKey.mData &&
aKey->mForImage == mKey.mForImage;
}
static KeyTypePointer KeyToPointer(KeyType& aKey) { return &aKey; }
static PLDHashNumber HashKey(KeyTypePointer aKey)
{
return mozilla::HashGeneric(aKey->mCallback, aKey->mData);
}
enum { ALLOW_MEMMOVE = true };
ChangeCallback mKey;
};
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
private:
void FireChangeCallbacks(Element* aOldElement, Element* aNewElement,
bool aImageOnly = false);
// empty if there are no elements with this ID.
// The elements are stored as weak pointers.
nsTArray<Element*> mIdContentList;
RefPtr<nsBaseContentList> mNameContentList;
nsAutoPtr<nsTHashtable<ChangeCallbackEntry> > mChangeCallbacks;
RefPtr<Element> mImageElement;
};
namespace mozilla {
namespace dom {
} // namespace dom
} // namespace mozilla
class nsDocHeaderData
{
public:
@@ -149,6 +293,36 @@ public:
nsDocHeaderData* mNext;
};
class nsDOMStyleSheetList : public mozilla::dom::StyleSheetList,
public nsStubDocumentObserver
{
public:
explicit nsDOMStyleSheetList(nsIDocument* aDocument);
NS_DECL_ISUPPORTS_INHERITED
// nsIDocumentObserver
NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETADDED
NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETREMOVED
// nsIMutationObserver
NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED
virtual nsINode* GetParentObject() const override
{
return mDocument;
}
uint32_t Length() override;
mozilla::StyleSheet* IndexedGetter(uint32_t aIndex, bool& aFound) override;
protected:
virtual ~nsDOMStyleSheetList();
int32_t mLength;
nsIDocument* mDocument;
};
class nsOnloadBlocker final : public nsIRequest
{
public:
@@ -333,6 +507,7 @@ class nsDocument : public nsIDocument,
public:
typedef mozilla::dom::Element Element;
using nsIDocument::GetElementsByTagName;
typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
@@ -449,6 +624,14 @@ public:
virtual void EnsureOnDemandBuiltInUASheet(mozilla::StyleSheet* aSheet) override;
/**
* Get the (document) style sheets owned by this document.
* These are ordered, highest priority last
*/
virtual int32_t GetNumberOfStyleSheets() const override;
virtual mozilla::StyleSheet* GetStyleSheetAt(int32_t aIndex) const override;
virtual int32_t GetIndexOfStyleSheet(
const mozilla::StyleSheet* aSheet) const override;
virtual void AddStyleSheet(mozilla::StyleSheet* aSheet) override;
virtual void RemoveStyleSheet(mozilla::StyleSheet* aSheet) override;
@@ -459,7 +642,7 @@ public:
virtual void RemoveStyleSheetFromStyleSets(mozilla::StyleSheet* aSheet);
virtual void InsertStyleSheetAt(mozilla::StyleSheet* aSheet,
size_t aIndex) override;
int32_t aIndex) override;
virtual void SetStyleSheetApplicableState(mozilla::StyleSheet* aSheet,
bool aApplicable) override;
@@ -610,11 +793,7 @@ public:
virtual void NotifyLayerManagerRecreated() override;
// Check whether web components are enabled for the global of aObject.
static bool IsWebComponentsEnabled(JSContext* aCx, JSObject* aObject);
// Check whether web components are enabled for the document this node belongs
// to.
static bool IsWebComponentsEnabled(const nsINode* aNode);
private:
void AddOnDemandBuiltInUASheet(mozilla::StyleSheet* aSheet);
nsRadioGroupStruct* GetRadioGroupInternal(const nsAString& aName) const;
@@ -630,13 +809,8 @@ public:
// nsIDOMDocumentXBL
NS_DECL_NSIDOMDOCUMENTXBL
using mozilla::dom::DocumentOrShadowRoot::GetElementById;
using mozilla::dom::DocumentOrShadowRoot::GetElementsByTagName;
using mozilla::dom::DocumentOrShadowRoot::GetElementsByTagNameNS;
using mozilla::dom::DocumentOrShadowRoot::GetElementsByClassName;
// nsIDOMEventTarget
virtual nsresult GetEventTargetParent(
virtual nsresult PreHandleEvent(
mozilla::EventChainPreVisitor& aVisitor) override;
virtual mozilla::EventListenerManager*
GetOrCreateListenerManager() override;
@@ -823,7 +997,10 @@ public:
virtual void ResetScrolledToRefAlready() override;
virtual void SetChangeScrollPosWhenScrollingToRef(bool aValue) override;
virtual Element* LookupImageElement(const nsAString& aElementId) override;
virtual Element *GetElementById(const nsAString& aElementId) override;
virtual const nsTArray<Element*>* GetAllElementsForId(const nsAString& aElementId) const override;
virtual Element *LookupImageElement(const nsAString& aElementId) override;
virtual void MozSetImageElement(const nsAString& aImageElementId,
Element* aElement) override;
@@ -952,7 +1129,12 @@ public:
// WebIDL bits
virtual mozilla::dom::DOMImplementation*
GetImplementation(mozilla::ErrorResult& rv) override;
virtual void
RegisterElement(JSContext* aCx, const nsAString& aName,
const mozilla::dom::ElementRegistrationOptions& aOptions,
JS::MutableHandle<JSObject*> aRetval,
mozilla::ErrorResult& rv) override;
virtual mozilla::dom::StyleSheetList* StyleSheets() override;
virtual void SetSelectedStyleSheetSet(const nsAString& aSheetSet) override;
virtual void GetLastStyleSheetSet(nsString& aSheetSet) override;
virtual mozilla::dom::DOMStringList* StyleSheetSets() override;
@@ -1174,6 +1356,7 @@ protected:
// EndLoad() has already happened.
nsWeakPtr mWeakSink;
nsTArray<RefPtr<mozilla::StyleSheet>> mStyleSheets;
nsTArray<RefPtr<mozilla::StyleSheet>> mOnDemandBuiltInUASheets;
nsTArray<RefPtr<mozilla::StyleSheet>> mAdditionalSheets[AdditionalSheetTypeCount];
@@ -1202,11 +1385,48 @@ protected:
// non-null when this document is in fullscreen mode.
nsWeakPtr mFullscreenRoot;
private:
static bool CustomElementConstructor(JSContext* aCx, unsigned aArgc, JS::Value* aVp);
/**
* Check if the passed custom element name, aOptions.mIs, is a registered
* custom element type or not, then return the custom element name for future
* usage.
*
* If there is no existing custom element definition for this name, throw a
* NotFoundError.
*/
const nsString* CheckCustomElementName(
const mozilla::dom::ElementCreationOptions& aOptions,
const nsAString& aLocalName,
uint32_t aNamespaceID,
ErrorResult& rv);
public:
virtual already_AddRefed<mozilla::dom::CustomElementRegistry>
GetCustomElementRegistry() override;
// Check whether web components are enabled for the global of aObject.
static bool IsWebComponentsEnabled(JSContext* aCx, JSObject* aObject);
// Check whether web components are enabled for the global of the document
// this nodeinfo comes from.
static bool IsWebComponentsEnabled(mozilla::dom::NodeInfo* aNodeInfo);
// Check whether web components are enabled for the given window.
static bool IsWebComponentsEnabled(nsPIDOMWindowInner* aWindow);
RefPtr<mozilla::EventListenerManager> mListenerManager;
RefPtr<mozilla::dom::StyleSheetList> mDOMStyleSheets;
RefPtr<nsDOMStyleSheetSetList> mStyleSheetSetList;
RefPtr<nsScriptLoader> mScriptLoader;
nsDocHeaderData* mHeaderData;
/* mIdentifierMap works as follows for IDs:
* 1) Attribute changes affect the table immediately (removing and adding
* entries as needed).
* 2) Removals from the DOM affect the table immediately
* 3) Additions to the DOM always update existing entries for names, and add
* new ones for IDs.
*/
nsTHashtable<nsIdentifierMapEntry> mIdentifierMap;
nsClassHashtable<nsStringHashKey, nsRadioGroupStruct> mRadioGroups;
+23 -16
View File
@@ -32,6 +32,7 @@
#include "nsIDOMDocument.h"
#include "nsGkAtoms.h"
#include "nsIContent.h"
#include "nsIParserService.h"
#include "nsIScriptContext.h"
#include "nsIScriptGlobalObject.h"
#include "nsIScriptSecurityManager.h"
@@ -39,7 +40,6 @@
#include "nsISelectionPrivate.h"
#include "nsITransferable.h" // for kUnicodeMime
#include "nsContentUtils.h"
#include "nsElementTable.h"
#include "nsNodeUtils.h"
#include "nsUnicharUtils.h"
#include "nsReadableUtils.h"
@@ -1588,13 +1588,10 @@ nsHTMLCopyEncoder::IncludeInContext(nsINode *aNode)
nsresult
nsHTMLCopyEncoder::PromoteRange(nsIDOMRange *inRange)
{
RefPtr<nsRange> range = static_cast<nsRange*>(inRange);
if (!range) {
return NS_ERROR_NULL_POINTER;
}
if (!inRange) return NS_ERROR_NULL_POINTER;
nsresult rv;
nsCOMPtr<nsIDOMNode> startNode, endNode, common;
uint32_t startOffset, endOffset;
int32_t startOffset, endOffset;
rv = inRange->GetCommonAncestorContainer(getter_AddRefs(common));
NS_ENSURE_SUCCESS(rv, rv);
@@ -1612,11 +1609,9 @@ nsHTMLCopyEncoder::PromoteRange(nsIDOMRange *inRange)
int32_t opStartOffset, opEndOffset;
// examine range endpoints.
rv = GetPromotedPoint(kStart, startNode, static_cast<int32_t>(startOffset),
address_of(opStartNode), &opStartOffset, common);
rv = GetPromotedPoint( kStart, startNode, startOffset, address_of(opStartNode), &opStartOffset, common);
NS_ENSURE_SUCCESS(rv, rv);
rv = GetPromotedPoint(kEnd, endNode, static_cast<int32_t>(endOffset),
address_of(opEndNode), &opEndOffset, common);
rv = GetPromotedPoint( kEnd, endNode, endOffset, address_of(opEndNode), &opEndOffset, common);
NS_ENSURE_SUCCESS(rv, rv);
// if both range endpoints are at the common ancestor, check for possible inclusion of ancestors
@@ -1628,9 +1623,9 @@ nsHTMLCopyEncoder::PromoteRange(nsIDOMRange *inRange)
}
// set the range to the new values
rv = inRange->SetStart(opStartNode, static_cast<uint32_t>(opStartOffset));
rv = inRange->SetStart(opStartNode, opStartOffset);
NS_ENSURE_SUCCESS(rv, rv);
rv = inRange->SetEnd(opEndNode, static_cast<uint32_t>(opEndOffset));
rv = inRange->SetEnd(opEndNode, opEndOffset);
return rv;
}
@@ -1741,6 +1736,9 @@ nsHTMLCopyEncoder::GetPromotedPoint(Endpoint aWhere, nsIDOMNode *aNode, int32_t
rv = GetNodeLocation(node, address_of(parent), &offset);
NS_ENSURE_SUCCESS(rv, rv);
if (offset == -1) return NS_OK; // we hit generated content; STOP
nsIParserService *parserService = nsContentUtils::GetParserService();
if (!parserService)
return NS_ERROR_OUT_OF_MEMORY;
while ((IsFirstNode(node)) && (!IsRoot(parent)) && (parent != common))
{
if (bResetPromotion)
@@ -1748,8 +1746,11 @@ nsHTMLCopyEncoder::GetPromotedPoint(Endpoint aWhere, nsIDOMNode *aNode, int32_t
nsCOMPtr<nsIContent> content = do_QueryInterface(parent);
if (content && content->IsHTMLElement())
{
if (nsHTMLElement::IsBlock(nsHTMLTags::AtomTagToId(
content->NodeInfo()->NameAtom()))) {
bool isBlock = false;
parserService->IsBlock(parserService->HTMLAtomTagToId(
content->NodeInfo()->NameAtom()), isBlock);
if (isBlock)
{
bResetPromotion = false;
}
}
@@ -1818,6 +1819,9 @@ nsHTMLCopyEncoder::GetPromotedPoint(Endpoint aWhere, nsIDOMNode *aNode, int32_t
rv = GetNodeLocation(node, address_of(parent), &offset);
NS_ENSURE_SUCCESS(rv, rv);
if (offset == -1) return NS_OK; // we hit generated content; STOP
nsIParserService *parserService = nsContentUtils::GetParserService();
if (!parserService)
return NS_ERROR_OUT_OF_MEMORY;
while ((IsLastNode(node)) && (!IsRoot(parent)) && (parent != common))
{
if (bResetPromotion)
@@ -1825,8 +1829,11 @@ nsHTMLCopyEncoder::GetPromotedPoint(Endpoint aWhere, nsIDOMNode *aNode, int32_t
nsCOMPtr<nsIContent> content = do_QueryInterface(parent);
if (content && content->IsHTMLElement())
{
if (nsHTMLElement::IsBlock(nsHTMLTags::AtomTagToId(
content->NodeInfo()->NameAtom()))) {
bool isBlock = false;
parserService->IsBlock(parserService->HTMLAtomTagToId(
content->NodeInfo()->NameAtom()), isBlock);
if (isBlock)
{
bResetPromotion = false;
}
}
+8 -7
View File
@@ -813,11 +813,10 @@ nsFocusManager::ContentRemoved(nsIDocument* aDocument, nsIContent* aContent)
if (!window)
return NS_OK;
// if the content is currently focused in the window, or is an
// shadow-including inclusive ancestor of the currently focused element,
// reset the focus within that window.
// if the content is currently focused in the window, or is an ancestor
// of the currently focused element, reset the focus within that window.
nsIContent* content = window->GetFocusedNode();
if (content && nsContentUtils::ContentIsHostIncludingDescendantOf(content, aContent)) {
if (content && nsContentUtils::ContentIsDescendantOf(content, aContent)) {
bool shouldShowFocusRing = window->ShouldShowFocusRing();
window->SetFocusedNode(nullptr);
@@ -2458,7 +2457,7 @@ nsFocusManager::GetSelectionLocation(nsIDocument* aDocument,
nsCOMPtr<nsIDOMNode> startNode, endNode;
bool isCollapsed = false;
nsCOMPtr<nsIContent> startContent, endContent;
uint32_t startOffset = 0;
int32_t startOffset = 0;
if (domSelection) {
domSelection->GetIsCollapsed(&isCollapsed);
nsCOMPtr<nsIDOMRange> domRange;
@@ -2472,6 +2471,7 @@ nsFocusManager::GetSelectionLocation(nsIDocument* aDocument,
startContent = do_QueryInterface(startNode);
if (startContent && startContent->IsElement()) {
NS_ASSERTION(startOffset >= 0, "Start offset cannot be negative");
childContent = startContent->GetChildAt(startOffset);
if (childContent) {
startContent = childContent;
@@ -2480,8 +2480,9 @@ nsFocusManager::GetSelectionLocation(nsIDocument* aDocument,
endContent = do_QueryInterface(endNode);
if (endContent && endContent->IsElement()) {
uint32_t endOffset = 0;
int32_t endOffset = 0;
domRange->GetEndOffset(&endOffset);
NS_ASSERTION(endOffset >= 0, "End offset cannot be negative");
childContent = endContent->GetChildAt(endOffset);
if (childContent) {
endContent = childContent;
@@ -2509,7 +2510,7 @@ nsFocusManager::GetSelectionLocation(nsIDocument* aDocument,
bool isFormControl =
startContent->IsNodeOfType(nsINode::eHTML_FORM_CONTROL);
if (nodeValue.Length() == startOffset && !isFormControl &&
if (nodeValue.Length() == (uint32_t)startOffset && !isFormControl &&
startContent != aDocument->GetRootElement()) {
// Yes, indeed we were at the end of the last node
nsCOMPtr<nsIFrameEnumerator> frameTraversal;
-3
View File
@@ -57,7 +57,6 @@
#include "nsGlobalWindow.h"
#include "nsPIWindowRoot.h"
#include "nsLayoutUtils.h"
#include "nsMappedAttributes.h"
#include "nsView.h"
#include "GroupedSHistory.h"
#include "PartialSHistory.h"
@@ -937,8 +936,6 @@ nsFrameLoader::MarginsChanged(uint32_t aMarginWidth,
RefPtr<nsPresContext> presContext;
mDocShell->GetPresContext(getter_AddRefs(presContext));
if (presContext)
// rebuild, because now the same nsMappedAttributes* will produce
// a different style
presContext->RebuildAllStyleData(nsChangeHint(0), eRestyle_Subtree);
}
+2 -2
View File
@@ -46,7 +46,7 @@ public:
virtual void UnbindFromTree(bool aDeep, bool aNullParent) override;
virtual EventStates IntrinsicState() const override;
virtual nsresult GetEventTargetParent(EventChainPreVisitor& aVisitor) override
virtual nsresult PreHandleEvent(EventChainPreVisitor& aVisitor) override
{
MOZ_ASSERT(IsInNativeAnonymousSubtree());
if (aVisitor.mEvent->mMessage == eLoad ||
@@ -54,7 +54,7 @@ public:
// Don't propagate the events to the parent.
return NS_OK;
}
return nsXMLElement::GetEventTargetParent(aVisitor);
return nsXMLElement::PreHandleEvent(aVisitor);
}
private:
+24 -15
View File
@@ -15,7 +15,6 @@
#include "mozilla/AsyncEventDispatcher.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/HTMLSlotElement.h"
#include "mozilla/dom/ShadowRoot.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
@@ -737,18 +736,21 @@ nsGenericDOMDataNode::SetShadowRoot(ShadowRoot* aShadowRoot)
{
}
HTMLSlotElement*
nsGenericDOMDataNode::GetAssignedSlot() const
{
nsDataSlots *slots = GetExistingDataSlots();
return slots ? slots->mAssignedSlot.get() : nullptr;
}
void
nsGenericDOMDataNode::SetAssignedSlot(HTMLSlotElement* aSlot)
nsTArray<nsIContent*>&
nsGenericDOMDataNode::DestInsertionPoints()
{
nsDataSlots *slots = DataSlots();
slots->mAssignedSlot = aSlot;
return slots->mDestInsertionPoints;
}
nsTArray<nsIContent*>*
nsGenericDOMDataNode::GetExistingDestInsertionPoints() const
{
nsDataSlots *slots = GetExistingDataSlots();
if (slots) {
return &slots->mDestInsertionPoints;
}
return nullptr;
}
nsXBLBinding *
@@ -791,6 +793,17 @@ nsGenericDOMDataNode::SetXBLInsertionParent(nsIContent* aContent)
}
}
CustomElementData *
nsGenericDOMDataNode::GetCustomElementData() const
{
return nullptr;
}
void
nsGenericDOMDataNode::SetCustomElementData(CustomElementData* aData)
{
}
bool
nsGenericDOMDataNode::IsNodeOfType(uint32_t aFlags) const
{
@@ -841,9 +854,6 @@ nsGenericDOMDataNode::nsDataSlots::Traverse(nsCycleCollectionTraversalCallback &
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mContainingShadow");
cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mContainingShadow));
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mAssignedSlot");
cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mAssignedSlot.get()));
}
void
@@ -851,7 +861,6 @@ nsGenericDOMDataNode::nsDataSlots::Unlink()
{
mXBLInsertionParent = nullptr;
mContainingShadow = nullptr;
mAssignedSlot = nullptr;
}
//----------------------------------------------------------------------
+7 -10
View File
@@ -26,12 +26,6 @@
class nsIDocument;
class nsIDOMText;
namespace mozilla {
namespace dom {
class HTMLSlotElement;
} // namespace dom
} // namespace mozilla
#define DATA_NODE_FLAG_BIT(n_) NODE_FLAG_BIT(NODE_TYPE_SPECIFIC_BITS_OFFSET + (n_))
// Data node specific flags
@@ -160,14 +154,17 @@ public:
virtual void SetXBLBinding(nsXBLBinding* aBinding,
nsBindingManager* aOldBindingManager = nullptr) override;
virtual mozilla::dom::ShadowRoot *GetContainingShadow() const override;
virtual nsTArray<nsIContent*> &DestInsertionPoints() override;
virtual nsTArray<nsIContent*> *GetExistingDestInsertionPoints() const override;
virtual void SetShadowRoot(mozilla::dom::ShadowRoot* aShadowRoot) override;
virtual mozilla::dom::HTMLSlotElement* GetAssignedSlot() const override;
virtual void SetAssignedSlot(mozilla::dom::HTMLSlotElement* aSlot) override;
virtual nsIContent *GetXBLInsertionParent() const override;
virtual void SetXBLInsertionParent(nsIContent* aContent) override;
virtual bool IsNodeOfType(uint32_t aFlags) const override;
virtual bool IsLink(nsIURI** aURI) const override;
virtual mozilla::dom::CustomElementData* GetCustomElementData() const override;
virtual void SetCustomElementData(mozilla::dom::CustomElementData* aData) override;
NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker) override;
NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
@@ -267,9 +264,9 @@ protected:
RefPtr<mozilla::dom::ShadowRoot> mContainingShadow;
/**
* @see nsIContent::GetAssignedSlot
* @see nsIContent::GetDestInsertionPoints
*/
RefPtr<mozilla::dom::HTMLSlotElement> mAssignedSlot;
nsTArray<nsIContent*> mDestInsertionPoints;
};
// Override from nsINode
+2 -6
View File
@@ -580,6 +580,7 @@ GK_ATOM(marginTop, "margin-top")
GK_ATOM(marginheight, "marginheight")
GK_ATOM(marginwidth, "marginwidth")
GK_ATOM(mark, "mark")
GK_ATOM(marquee, "marquee")
GK_ATOM(match, "match")
GK_ATOM(max, "max")
GK_ATOM(maxheight, "maxheight")
@@ -909,9 +910,7 @@ GK_ATOM(onreadystatechange, "onreadystatechange")
GK_ATOM(onreceived, "onreceived")
GK_ATOM(onremoteheld, "onremoteheld")
GK_ATOM(onremoteresumed, "onremoteresumed")
GK_ATOM(onrequestprogress, "onrequestprogress")
GK_ATOM(onresourcetimingbufferfull, "onresourcetimingbufferfull")
GK_ATOM(onresponseprogress, "onresponseprogress")
GK_ATOM(onretrieving, "onretrieving")
GK_ATOM(onRequest, "onRequest")
GK_ATOM(onrequestmediaplaystatus, "onrequestmediaplaystatus")
@@ -1561,11 +1560,11 @@ GK_ATOM(saturate, "saturate")
GK_ATOM(saturation, "saturation")
GK_ATOM(set, "set")
GK_ATOM(seed, "seed")
GK_ATOM(shadow, "shadow")
GK_ATOM(shape_rendering, "shape-rendering")
GK_ATOM(skewX, "skewX")
GK_ATOM(skewY, "skewY")
GK_ATOM(slope, "slope")
GK_ATOM(slot, "slot")
GK_ATOM(softLight, "soft-light")
GK_ATOM(spacing, "spacing")
GK_ATOM(spacingAndGlyphs, "spacingAndGlyphs")
@@ -2145,14 +2144,12 @@ GK_ATOM(ongamepaddisconnected, "ongamepaddisconnected")
#endif
// Content property names
GK_ATOM(afterPseudoProperty, "afterPseudoProperty") // nsXMLElement*
GK_ATOM(animationsProperty, "AnimationsProperty") // FrameAnimations*
GK_ATOM(animationsOfBeforeProperty, "AnimationsOfBeforeProperty") // FrameAnimations*
GK_ATOM(animationsOfAfterProperty, "AnimationsOfAfterProperty") // FrameAnimations*
GK_ATOM(animationEffectsProperty, "AnimationEffectsProperty") // EffectSet*
GK_ATOM(animationEffectsForBeforeProperty, "AnimationsEffectsForBeforeProperty") // EffectSet*
GK_ATOM(animationEffectsForAfterProperty, "AnimationsEffectsForAfterProperty") // EffectSet*
GK_ATOM(beforePseudoProperty, "beforePseudoProperty") // nsXMLElement*
GK_ATOM(cssPseudoElementBeforeProperty, "CSSPseudoElementBeforeProperty") // CSSPseudoElement*
GK_ATOM(cssPseudoElementAfterProperty, "CSSPseudoElementAfterProperty") // CSSPseudoElement*
GK_ATOM(transitionsProperty, "TransitionsProperty") // FrameTransitions*
@@ -2165,7 +2162,6 @@ GK_ATOM(lockedStyleStates, "lockedStyleStates")
GK_ATOM(apzCallbackTransform, "apzCallbackTransform")
GK_ATOM(restylableAnonymousNode, "restylableAnonymousNode")
GK_ATOM(paintRequestTime, "PaintRequestTime")
GK_ATOM(pseudoProperty, "PseudoProperty") // CSSPseudoElementType
// Languages for lang-specific transforms
GK_ATOM(Japanese, "ja")
+5 -7
View File
@@ -3577,10 +3577,9 @@ nsGlobalWindow::WillHandleEvent(EventChainPostVisitor& aVisitor)
}
nsresult
nsGlobalWindow::GetEventTargetParent(EventChainPreVisitor& aVisitor)
nsGlobalWindow::PreHandleEvent(EventChainPreVisitor& aVisitor)
{
NS_PRECONDITION(IsInnerWindow(),
"GetEventTargetParent is used on outer window!?");
NS_PRECONDITION(IsInnerWindow(), "PreHandleEvent is used on outer window!?");
EventMessage msg = aVisitor.mEvent->mMessage;
aVisitor.mCanHandle = true;
@@ -3608,7 +3607,7 @@ nsGlobalWindow::GetEventTargetParent(EventChainPreVisitor& aVisitor)
}
}
aVisitor.SetParentTarget(GetParentTarget(), true);
aVisitor.mParentTarget = GetParentTarget();
// Handle 'active' event.
if (!mIdleObservers.IsEmpty() &&
@@ -3813,7 +3812,7 @@ nsGlobalWindow::PostHandleEvent(EventChainPostVisitor& aVisitor)
} else if (aVisitor.mEvent->mMessage == eLoad &&
aVisitor.mEvent->IsTrusted()) {
// This is page load event since load events don't propagate to |window|.
// @see nsDocument::GetEventTargetParent.
// @see nsDocument::PreHandleEvent.
mIsDocumentLoaded = true;
nsCOMPtr<Element> element = GetOuterWindow()->GetFrameElementInternal();
@@ -4242,9 +4241,8 @@ CustomElementRegistry*
nsGlobalWindow::CustomElements()
{
MOZ_RELEASE_ASSERT(IsInnerWindow());
if (!mCustomElements) {
mCustomElements = new CustomElementRegistry(AsInner());
mCustomElements = CustomElementRegistry::Create(AsInner());
}
return mCustomElements;
+14 -8
View File
@@ -15,7 +15,6 @@
#include "nsIDOMElement.h"
#include "nsIContent.h"
#include "nsIDocument.h"
#include "nsElementTable.h"
#include "nsNameSpaceManager.h"
#include "nsString.h"
#include "nsUnicharUtils.h"
@@ -348,13 +347,20 @@ nsHTMLContentSerializer::AppendElementEnd(Element* aElement,
}
if (ns == kNameSpaceID_XHTML) {
bool isContainer =
nsHTMLElement::IsContainer(nsHTMLTags::CaseSensitiveAtomTagToId(name));
if (!isContainer) {
// Keep this in sync with the cleanup at the end of this method.
MOZ_ASSERT(name != nsGkAtoms::body);
MaybeLeaveFromPreContent(content);
return NS_OK;
nsIParserService* parserService = nsContentUtils::GetParserService();
if (parserService) {
bool isContainer;
parserService->
IsContainer(parserService->HTMLCaseSensitiveAtomTagToId(name),
isContainer);
if (!isContainer) {
// Keep this in sync with the cleanup at the end of this method.
MOZ_ASSERT(name != nsGkAtoms::body);
MaybeLeaveFromPreContent(content);
return NS_OK;
}
}
}
+32 -61
View File
@@ -26,7 +26,7 @@ namespace mozilla {
class EventChainPreVisitor;
namespace dom {
class ShadowRoot;
class HTMLSlotElement;
struct CustomElementData;
} // namespace dom
namespace widget {
struct IMEState;
@@ -145,14 +145,7 @@ public:
* Skip native anonymous content created for placeholder of HTML input,
* used in conjunction with eAllChildren or eAllButXBL.
*/
eSkipPlaceholderContent = 2,
/**
* Skip native anonymous content created by ancestor frames of the root
* element's primary frame, such as scrollbar elements created by the root
* scroll frame.
*/
eSkipDocumentLevelNativeAnonymousContent = 4,
eSkipPlaceholderContent = 2
};
/**
@@ -194,7 +187,7 @@ public:
void SetIsNativeAnonymousRoot()
{
SetFlags(NODE_IS_ANONYMOUS_ROOT | NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE |
NODE_IS_NATIVE_ANONYMOUS_ROOT | NODE_IS_NATIVE_ANONYMOUS);
NODE_IS_NATIVE_ANONYMOUS_ROOT);
}
/**
@@ -697,35 +690,18 @@ public:
virtual mozilla::dom::ShadowRoot *GetContainingShadow() const = 0;
/**
* Gets the shadow host if this content is in a shadow tree. That is, the host
* of |GetContainingShadow|, if its not null.
*
* @return The shadow host, if this is in shadow tree, or null.
* Gets an array of destination insertion points where this content
* is distributed by web component distribution algorithms.
* The array is created if it does not already exist.
*/
nsIContent* GetContainingShadowHost() const;
virtual nsTArray<nsIContent*> &DestInsertionPoints() = 0;
/**
* Gets the assigned slot associated with this content.
*
* @return The assigned slot element or null.
* Same as DestInsertionPoints except that this method will return
* null if the array of destination insertion points does not already
* exist.
*/
virtual mozilla::dom::HTMLSlotElement* GetAssignedSlot() const = 0;
/**
* Sets the assigned slot associated with this content.
*
* @param aSlot The assigned slot.
*/
virtual void SetAssignedSlot(mozilla::dom::HTMLSlotElement* aSlot) = 0;
/**
* Gets the assigned slot associated with this content based on parent's
* shadow root mode. Returns null if parent's shadow root is "closed".
* https://dom.spec.whatwg.org/#dom-slotable-assignedslot
*
* @return The assigned slot element or null.
*/
mozilla::dom::HTMLSlotElement* GetAssignedSlotByMode() const;
virtual nsTArray<nsIContent*> *GetExistingDestInsertionPoints() const = 0;
/**
* Gets the insertion parent element of the XBL binding.
@@ -748,9 +724,26 @@ public:
*/
inline nsIContent *GetFlattenedTreeParent() const;
// Helper method, which we leave public so that it's accessible from nsINode.
enum FlattenedParentType { eNotForStyle, eForStyle };
nsINode* GetFlattenedTreeParentNodeInternal(FlattenedParentType aType) const;
/**
* Helper method, which we leave public so that it's accessible from nsINode.
*/
nsINode *GetFlattenedTreeParentNodeInternal() const;
/**
* Gets the custom element data used by web components custom element.
* Custom element data is created at the first attempt to enqueue a callback.
*
* @return The custom element data or null if none.
*/
virtual mozilla::dom::CustomElementData *GetCustomElementData() const = 0;
/**
* Sets the custom element data, ownership of the
* callback data is taken by this content.
*
* @param aCallbackData The custom element data.
*/
virtual void SetCustomElementData(mozilla::dom::CustomElementData* aData) = 0;
/**
* API to check if this is a link that's traversed in response to user input
@@ -968,18 +961,10 @@ public:
return false;
}
// Returns true if this element is native-anonymous scrollbar content.
bool IsNativeScrollbarContent() const {
return IsNativeAnonymous() &&
IsAnyOfXULElements(nsGkAtoms::scrollbar,
nsGkAtoms::resizer,
nsGkAtoms::scrollcorner);
}
// Overloaded from nsINode
virtual already_AddRefed<nsIURI> GetBaseURI(bool aTryUseXHRDocBaseURI = false) const override;
virtual nsresult GetEventTargetParent(
virtual nsresult PreHandleEvent(
mozilla::EventChainPreVisitor& aVisitor) override;
virtual bool IsPurple() = 0;
@@ -993,12 +978,6 @@ protected:
*/
nsIAtom* DoGetID() const;
/**
* Returns the assigned slot, if it exists, or the direct parent, if it's a
* fallback content of a slot.
*/
nsINode* GetFlattenedTreeParentForMaybeAssignedNode() const;
public:
#ifdef DEBUG
/**
@@ -1052,15 +1031,7 @@ inline nsIContent* nsINode::AsContent()
{ \
return aContent->_check ? static_cast<_class*>(aContent) : nullptr; \
} \
static const _class* FromContent(const nsIContent* aContent) \
{ \
return aContent->_check ? static_cast<const _class*>(aContent) : nullptr; \
} \
static _class* FromContentOrNull(nsIContent* aContent) \
{ \
return aContent ? FromContent(aContent) : nullptr; \
} \
static const _class* FromContentOrNull(const nsIContent* aContent) \
{ \
return aContent ? FromContent(aContent) : nullptr; \
}
+11 -36
View File
@@ -33,15 +33,14 @@ inline mozilla::dom::ShadowRoot* nsIContent::GetShadowRoot() const
return AsElement()->FastGetShadowRoot();
}
template<nsIContent::FlattenedParentType Type>
static inline nsINode*
GetFlattenedTreeParentNode(const nsINode* aNode)
inline nsINode* nsINode::GetFlattenedTreeParentNode() const
{
nsINode* parent = aNode->GetParentNode();
nsINode* parent = GetParentNode();
// Try to short-circuit past the complicated and not-exactly-fast logic for
// computing the flattened parent.
//
// There are four cases where we need might something other than parentNode:
// There are three cases where we need might something other than parentNode:
// (1) The node is an explicit child of an XBL-bound element, re-bound
// to an XBL insertion point.
// (2) The node is a top-level element in a shadow tree, whose flattened
@@ -49,29 +48,16 @@ GetFlattenedTreeParentNode(const nsINode* aNode)
// is the shadow root).
// (3) The node is an explicit child of an element with a shadow root,
// re-bound to an insertion point.
// (4) We want the flattened parent for style, and the node is the root
// of a native anonymous content subtree parented to the document's
// root element.
bool needSlowCall = aNode->HasFlag(NODE_MAY_BE_IN_BINDING_MNGR) ||
aNode->IsInShadowTree() ||
(parent &&
parent->IsContent() &&
parent->AsContent()->GetShadowRoot()) ||
(Type == nsIContent::eForStyle &&
aNode->IsContent() &&
aNode->AsContent()->IsRootOfNativeAnonymousSubtree() &&
aNode->OwnerDoc()->GetRootElement() == parent);
bool needSlowCall = HasFlag(NODE_MAY_BE_IN_BINDING_MNGR) ||
IsInShadowTree() ||
(parent && parent->IsContent() &&
parent->AsContent()->GetShadowRoot());
if (MOZ_UNLIKELY(needSlowCall)) {
MOZ_ASSERT(aNode->IsContent());
return aNode->AsContent()->GetFlattenedTreeParentNodeInternal(Type);
MOZ_ASSERT(IsContent());
return AsContent()->GetFlattenedTreeParentNodeInternal();
}
return parent;
}
inline nsINode*
nsINode::GetFlattenedTreeParentNode() const
{
return ::GetFlattenedTreeParentNode<nsIContent::eNotForStyle>(this);
return parent;
}
inline nsIContent*
@@ -81,16 +67,5 @@ nsIContent::GetFlattenedTreeParent() const
return (parent && parent->IsContent()) ? parent->AsContent() : nullptr;
}
inline nsINode*
nsINode::GetFlattenedTreeParentNodeForStyle() const
{
return ::GetFlattenedTreeParentNode<nsIContent::eForStyle>(this);
}
inline bool
nsINode::NodeOrAncestorHasDirAuto() const
{
return AncestorHasDirAuto() || (IsElement() && AsElement()->HasDirAuto());
}
#endif // nsIContentInlines_h
+69 -73
View File
@@ -34,7 +34,6 @@
#include "prclist.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/CORSMode.h"
#include "mozilla/dom/DocumentOrShadowRoot.h"
#include "mozilla/LinkedList.h"
#include "mozilla/StyleBackendType.h"
#include "mozilla/StyleSheet.h"
@@ -62,7 +61,6 @@ class nsFrameLoader;
class nsHTMLCSSStyleSheet;
class nsHTMLDocument;
class nsHTMLStyleSheet;
class nsGenericHTMLElement;
class nsIAtom;
class nsIBFCacheEntry;
class nsIChannel;
@@ -134,6 +132,7 @@ class DOMIntersectionObserver;
class DOMStringList;
class Element;
struct ElementCreationOptions;
struct ElementRegistrationOptions;
class Event;
class EventTarget;
class FontFaceSet;
@@ -197,8 +196,7 @@ class nsContentList;
// Document interface. This is implemented by all document objects in
// Gecko.
class nsIDocument : public nsINode,
public mozilla::dom::DocumentOrShadowRoot
class nsIDocument : public nsINode
{
typedef mozilla::dom::GlobalObject GlobalObject;
@@ -499,7 +497,7 @@ public:
* to remove it.
*/
typedef bool (* IDTargetObserver)(Element* aOldElement,
Element* aNewelement, void* aData);
Element* aNewelement, void* aData);
/**
* Add an IDTargetObserver for a specific ID. The IDTargetObserver
@@ -1038,11 +1036,6 @@ public:
Element* GetHeadElement() {
return GetHtmlChildElement(nsGkAtoms::head);
}
// Get the "body" in the sense of document.body: The first <body> or
// <frameset> that's a child of a root <html>
nsGenericHTMLElement* GetBody();
// Set the "body" in the sense of document.body.
void SetBody(nsGenericHTMLElement* aBody, mozilla::ErrorResult& rv);
/**
* Accessors to the collection of stylesheets owned by this document.
@@ -1071,19 +1064,40 @@ public:
*/
virtual void EnsureOnDemandBuiltInUASheet(mozilla::StyleSheet* aSheet) = 0;
mozilla::dom::StyleSheetList* StyleSheets()
{
return &DocumentOrShadowRoot::EnsureDOMStyleSheets();
}
/**
* Get the number of (document) stylesheets
*
* @return the number of stylesheets
* @throws no exceptions
*/
virtual int32_t GetNumberOfStyleSheets() const = 0;
/**
* Get a particular stylesheet
* @param aIndex the index the stylesheet lives at. This is zero-based
* @return the stylesheet at aIndex. Null if aIndex is out of range.
* @throws no exceptions
*/
virtual mozilla::StyleSheet* GetStyleSheetAt(int32_t aIndex) const = 0;
/**
* Insert a sheet at a particular spot in the stylesheet list (zero-based)
* @param aSheet the sheet to insert
* @param aIndex the index to insert at.
* @param aIndex the index to insert at. This index will be
* adjusted for the "special" sheets.
* @throws no exceptions
*/
virtual void InsertStyleSheetAt(mozilla::StyleSheet* aSheet,
size_t aIndex) = 0;
int32_t aIndex) = 0;
/**
* Get the index of a particular stylesheet. This will _always_
* consider the "special" sheets as part of the sheet list.
* @param aSheet the sheet to get the index of
* @return aIndex the index of the sheet in the full list
*/
virtual int32_t GetIndexOfStyleSheet(
const mozilla::StyleSheet* aSheet) const = 0;
/**
* Replace the stylesheets in aOldSheets with the stylesheets in
@@ -1134,13 +1148,11 @@ public:
* sheets for this document, returns the index that aSheet should
* be inserted at to maintain document ordering.
*
* Type T has to cast to StyleSheet*.
*
* Defined in nsIDocumentInlines.h.
*/
template<typename T>
size_t FindDocStyleSheetInsertionPoint(const nsTArray<T>& aDocSheets,
const mozilla::StyleSheet& aSheet);
size_t FindDocStyleSheetInsertionPoint(const nsTArray<RefPtr<T>>& aDocSheets,
T* aSheet);
/**
* Get this document's CSSLoader. This is guaranteed to not return null.
@@ -2357,10 +2369,19 @@ public:
virtual void ResetScrolledToRefAlready() = 0;
virtual void SetChangeScrollPosWhenScrollingToRef(bool aValue) = 0;
using mozilla::dom::DocumentOrShadowRoot::GetElementById;
using mozilla::dom::DocumentOrShadowRoot::GetElementsByTagName;
using mozilla::dom::DocumentOrShadowRoot::GetElementsByTagNameNS;
using mozilla::dom::DocumentOrShadowRoot::GetElementsByClassName;
/**
* This method is similar to GetElementById() from nsIDOMDocument but it
* returns a mozilla::dom::Element instead of a nsIDOMElement.
* It prevents converting nsIDOMElement to mozilla::dom::Element which is
* already converted from mozilla::dom::Element.
*/
virtual Element* GetElementById(const nsAString& aElementId) = 0;
/**
* This method returns _all_ the elements in this document which
* have id aElementId, if there are any. Otherwise it returns null.
*/
virtual const nsTArray<Element*>* GetAllElementsForId(const nsAString& aElementId) const = 0;
/**
* Lookup an image element using its associated ID, which is usually provided
@@ -2552,14 +2573,34 @@ public:
}
enum ElementCallbackType {
eConnected,
eDisconnected,
eAdopted,
eCreated,
eAttached,
eDetached,
eAttributeChanged
};
nsIDocument* GetTopLevelContentDocument();
virtual void
RegisterElement(JSContext* aCx, const nsAString& aName,
const mozilla::dom::ElementRegistrationOptions& aOptions,
JS::MutableHandle<JSObject*> aRetval,
mozilla::ErrorResult& rv) = 0;
virtual already_AddRefed<mozilla::dom::CustomElementRegistry>
GetCustomElementRegistry() = 0;
already_AddRefed<nsContentList>
GetElementsByTagName(const nsAString& aTagName)
{
return NS_GetContentList(this, kNameSpaceID_Unknown, aTagName);
}
already_AddRefed<nsContentList>
GetElementsByTagNameNS(const nsAString& aNamespaceURI,
const nsAString& aLocalName,
mozilla::ErrorResult& aResult);
already_AddRefed<nsContentList>
GetElementsByClassName(const nsAString& aClasses);
// GetElementById defined above
virtual already_AddRefed<Element>
CreateElement(const nsAString& aTagName,
const mozilla::dom::ElementCreationOptionsOrString& aOptions,
@@ -2659,6 +2700,7 @@ public:
return mVisibilityState;
}
#endif
virtual mozilla::dom::StyleSheetList* StyleSheets() = 0;
void GetSelectedStyleSheetSet(nsAString& aSheetSet);
virtual void SetSelectedStyleSheetSet(const nsAString& aSheetSet) = 0;
virtual void GetLastStyleSheetSet(nsString& aSheetSet) = 0;
@@ -2830,27 +2872,6 @@ public:
virtual void ScheduleIntersectionObserverNotification() = 0;
virtual void NotifyIntersectionObservers() = 0;
bool ShouldThrowOnDynamicMarkupInsertion()
{
return mThrowOnDynamicMarkupInsertionCounter;
}
void IncrementThrowOnDynamicMarkupInsertionCounter()
{
++mThrowOnDynamicMarkupInsertionCounter;
}
void DecrementThrowOnDynamicMarkupInsertionCounter()
{
MOZ_ASSERT(mThrowOnDynamicMarkupInsertionCounter);
--mThrowOnDynamicMarkupInsertionCounter;
}
bool IsWebComponentsEnabled() const
{
return mIsWebComponentsEnabled;
}
protected:
bool GetUseCounter(mozilla::UseCounter aUseCounter)
{
@@ -2994,9 +3015,6 @@ protected:
// container for per-context fonts (downloadable, SVG, etc.)
RefPtr<mozilla::dom::FontFaceSet> mFontFaceSet;
// True if dom.webcomponents.enabled pref is set when document is created.
bool mIsWebComponentsEnabled : 1;
// Compatibility mode
nsCompatibility mCompatMode;
@@ -3301,11 +3319,6 @@ protected:
uint32_t mBlockDOMContentLoaded;
// Used in conjunction with the create-an-element-for-the-token algorithm to
// prevent custom element constructors from being able to use document.open(),
// document.close(), and document.write() when they are invoked by the parser.
uint32_t mThrowOnDynamicMarkupInsertionCounter;
// Our live MediaQueryLists
PRCList mDOMMediaQueryLists;
@@ -3379,23 +3392,6 @@ private:
uint32_t mMicroTaskLevel;
};
class MOZ_RAII AutoSetThrowOnDynamicMarkupInsertionCounter final {
public:
explicit AutoSetThrowOnDynamicMarkupInsertionCounter(
nsIDocument* aDocument)
: mDocument(aDocument)
{
mDocument->IncrementThrowOnDynamicMarkupInsertionCounter();
}
~AutoSetThrowOnDynamicMarkupInsertionCounter() {
mDocument->DecrementThrowOnDynamicMarkupInsertionCounter();
}
private:
nsIDocument* mDocument;
};
// XXX These belong somewhere else
nsresult
NS_NewHTMLDocument(nsIDocument** aInstancePtrResult, bool aLoadedAsData = false);
+12 -11
View File
@@ -19,23 +19,24 @@ nsIDocument::GetBodyElement()
template<typename T>
size_t
nsIDocument::FindDocStyleSheetInsertionPoint(
const nsTArray<T>& aDocSheets,
const mozilla::StyleSheet& aSheet)
const nsTArray<RefPtr<T>>& aDocSheets,
T* aSheet)
{
nsStyleSheetService* sheetService = nsStyleSheetService::GetInstance();
// lowest index first
int32_t newDocIndex = IndexOfSheet(aSheet);
int32_t newDocIndex = GetIndexOfStyleSheet(aSheet);
size_t count = aDocSheets.Length();
size_t index = 0;
for (; index < count; index++) {
auto* sheet = static_cast<mozilla::StyleSheet*>(aDocSheets[index]);
MOZ_ASSERT(sheet);
int32_t sheetDocIndex = IndexOfSheet(*sheet);
int32_t count = aDocSheets.Length();
int32_t index;
for (index = 0; index < count; index++) {
T* sheet = aDocSheets[index];
int32_t sheetDocIndex = GetIndexOfStyleSheet(sheet);
if (sheetDocIndex > newDocIndex)
break;
mozilla::StyleSheet* sheetHandle = sheet;
// If the sheet is not owned by the document it can be an author
// sheet registered at nsStyleSheetService or an additional author
// sheet on the document, which means the new
@@ -43,11 +44,11 @@ nsIDocument::FindDocStyleSheetInsertionPoint(
if (sheetDocIndex < 0) {
if (sheetService) {
auto& authorSheets = *sheetService->AuthorStyleSheets();
if (authorSheets.IndexOf(sheet) != authorSheets.NoIndex) {
if (authorSheets.IndexOf(sheetHandle) != authorSheets.NoIndex) {
break;
}
}
if (sheet == GetFirstAdditionalAuthorSheet()) {
if (sheetHandle == GetFirstAdditionalAuthorSheet()) {
break;
}
}
+1 -1
View File
@@ -68,7 +68,7 @@ interface nsIImageLoadingContent : imgINotificationObserver
* the image was blocked. This status always refers to the
* CURRENT_REQUEST load.
*/
[infallible] readonly attribute short imageBlockingStatus;
readonly attribute short imageBlockingStatus;
/**
* Used to register an image decoder observer. Typically, this will
+2 -32
View File
@@ -107,7 +107,6 @@
#include "GeometryUtils.h"
#include "nsIAnimationObserver.h"
#include "nsChildContentList.h"
#include "mozilla/dom/NodeBinding.h"
#ifdef ACCESSIBILITY
#include "mozilla/dom/AccessibleNode.h"
@@ -251,30 +250,6 @@ nsINode::GetTextEditorRootContent(nsIEditor** aEditor)
return nullptr;
}
nsINode* nsINode::GetRootNode(const GetRootNodeOptions& aOptions)
{
if (aOptions.mComposed) {
if (IsInComposedDoc() && GetComposedDoc()) {
return OwnerDoc();
}
nsINode* node = this;
ShadowRoot* shadowRootParent = nullptr;
while(node) {
node = node->SubtreeRoot();
shadowRootParent = ShadowRoot::FromNode(node);
if (!shadowRootParent) {
break;
}
node = shadowRootParent->GetHost();
}
return node;
}
return SubtreeRoot();
}
nsINode*
nsINode::SubtreeRoot() const
{
@@ -1268,7 +1243,7 @@ nsINode::RemoveEventListener(const nsAString& aType,
NS_IMPL_REMOVE_SYSTEM_EVENT_LISTENER(nsINode)
nsresult
nsINode::GetEventTargetParent(EventChainPreVisitor& aVisitor)
nsINode::PreHandleEvent(EventChainPreVisitor& aVisitor)
{
// This is only here so that we can use the NS_DECL_NSIDOMTARGET macro
NS_ABORT();
@@ -1540,6 +1515,7 @@ nsINode::SetExplicitBaseURI(nsIURI* aURI)
{
nsresult rv = SetProperty(nsGkAtoms::baseURIProperty, aURI, ReleaseURI);
if (NS_SUCCEEDED(rv)) {
SetHasExplicitBaseURI();
NS_ADDREF(aURI);
}
return rv;
@@ -3157,9 +3133,3 @@ nsINode::IsStyledByServo() const
return OwnerDoc()->IsStyledByServo();
}
#endif
DocGroup*
nsINode::GetDocGroup() const
{
return OwnerDoc()->GetDocGroup();
}
+36 -72
View File
@@ -72,7 +72,6 @@ inline bool IsSpaceCharacter(char aChar) {
class AccessibleNode;
struct BoxQuadOptions;
struct ConvertCoordinateOptions;
class DocGroup;
class DOMPoint;
class DOMQuad;
class DOMRectReadOnly;
@@ -84,7 +83,6 @@ template<typename> class Sequence;
class Text;
class TextOrElementOrDocument;
struct DOMPointInit;
struct GetRootNodeOptions;
} // namespace dom
} // namespace mozilla
@@ -128,28 +126,9 @@ enum {
NODE_IS_EDITABLE = NODE_FLAG_BIT(7),
// This node was created by layout as native anonymous content. This
// generally corresponds to things created by nsIAnonymousContentCreator,
// though there are exceptions (svg:use content does not have this flag
// set, and any non-nsIAnonymousContentCreator callers of
// SetIsNativeAnonymousRoot also get this flag).
//
// One very important aspect here is that this node is not transitive over
// the subtree (if you want that, use NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE).
// If Gecko code somewhere attaches children to a node with this bit set,
// the children will not have the bit themselves unless the calling code sets
// it explicitly. This means that XBL content bound to NAC doesn't get this
// bit, nor do nodes inserted by editor.
//
// For now, this bit exists primarily to control style inheritance behavior,
// since the nodes for which we set it are often used to implement pseudo-
// elements, which need to inherit style from a script-visible element.
//
// A more general principle for this bit might be this: If the node is entirely
// a detail of layout, is not script-observable in any way, and other engines
// might accomplish the same task with a nodeless layout frame, then the node
// should have this bit set.
NODE_IS_NATIVE_ANONYMOUS = NODE_FLAG_BIT(8),
// For all Element nodes, NODE_MAY_HAVE_CLASS is guaranteed to be set if the
// node in fact has a class, but may be set even if it doesn't.
NODE_MAY_HAVE_CLASS = NODE_FLAG_BIT(8),
// Whether the node participates in a shadow tree.
NODE_IS_IN_SHADOW_TREE = NODE_FLAG_BIT(9),
@@ -301,7 +280,6 @@ class nsINode : public mozilla::dom::EventTarget
public:
typedef mozilla::dom::BoxQuadOptions BoxQuadOptions;
typedef mozilla::dom::ConvertCoordinateOptions ConvertCoordinateOptions;
typedef mozilla::dom::DocGroup DocGroup;
typedef mozilla::dom::DOMPoint DOMPoint;
typedef mozilla::dom::DOMPointInit DOMPointInit;
typedef mozilla::dom::DOMQuad DOMQuad;
@@ -411,12 +389,6 @@ public:
*/
virtual bool IsNodeOfType(uint32_t aFlags) const = 0;
bool
IsSlotable() const
{
return IsElement() || IsNodeOfType(eTEXT);
}
virtual JSObject* WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
/**
@@ -616,11 +588,6 @@ public:
return mNodeInfo->NamespaceID() == aNamespace;
}
/**
* Returns the DocGroup of the "node document" of this node.
*/
DocGroup* GetDocGroup() const;
/**
* Print a debugger friendly descriptor of this element. This will describe
* the position of this element in the document.
@@ -953,14 +920,6 @@ public:
*/
inline nsINode* GetFlattenedTreeParentNode() const;
/**
* Like GetFlattenedTreeParentNode, but returns null for any native
* anonymous content that was generated for ancestor frames of the
* root element's primary frame, such as scrollbar elements created
* by the root scroll frame.
*/
inline nsINode* GetFlattenedTreeParentNodeForStyle() const;
/**
* Get the parent nsINode for this node if it is an Element.
* @return the parent node
@@ -983,11 +942,10 @@ public:
*/
nsINode* SubtreeRoot() const;
/*
* Get context object's shadow-including root if options's composed is true,
* and context object's root otherwise.
*/
nsINode* GetRootNode(const mozilla::dom::GetRootNodeOptions& aOptions);
nsINode* RootNode() const
{
return SubtreeRoot();
}
/**
* See nsIDOMEventTarget
@@ -1245,15 +1203,6 @@ public:
#endif
}
/**
* Returns true if |this| is native anonymous (i.e. created by
* nsIAnonymousContentCreator);
*/
bool IsNativeAnonymous() const
{
return HasFlag(NODE_IS_NATIVE_ANONYMOUS);
}
/**
* Returns true if |this| or any of its ancestors is native anonymous.
*/
@@ -1386,11 +1335,10 @@ public:
protected:
nsIURI* GetExplicitBaseURI() const {
if (!HasProperties()) {
return nullptr;
if (HasExplicitBaseURI()) {
return static_cast<nsIURI*>(GetProperty(nsGkAtoms::baseURIProperty));
}
return static_cast<nsIURI*>(GetProperty(nsGkAtoms::baseURIProperty));
return nullptr;
}
public:
@@ -1593,8 +1541,6 @@ private:
// cases lie for nsXMLElement, such as when the node has been moved between
// documents with different id mappings.
ElementHasID,
// Set if the element might have a class.
ElementMayHaveClass,
// Set if the element might have inline style.
ElementMayHaveStyle,
// Set if the element has a name attribute set.
@@ -1613,6 +1559,8 @@ private:
// Maybe set if the node is a root of a subtree
// which needs to be kept in the purple buffer.
NodeIsPurpleRoot,
// Set if the node has an explicit base URI stored
NodeHasExplicitBaseURI,
// Set if the element has some style states locked
ElementHasLockedStyleStates,
// Set if element has pointer locked
@@ -1623,11 +1571,10 @@ private:
NodeIsContent,
// Set if the node has animations or transitions
ElementHasAnimations,
// Set if node has a dir attribute with a valid value (ltr, rtl, or auto).
// Note that we cannot compute this from the dir attribute event state
// flags, because we can't use those to distinguish
// <bdi dir="some-invalid-value"> and <bdi dir="auto">.
// Set if node has a dir attribute with a valid value (ltr, rtl, or auto)
NodeHasValidDirAttribute,
// Set if node has a dir attribute with a fixed value (ltr or rtl, NOT auto)
NodeHasFixedDir,
// Set if the node has dir=auto and has a property pointing to the text
// node that determines its direction
NodeHasDirAutoSet,
@@ -1635,6 +1582,8 @@ private:
// and has a TextNodeDirectionalityMap property listing the elements whose
// direction it determines.
NodeHasTextNodeDirectionalityMap,
// Set if the node has dir=auto.
NodeHasDirAuto,
// Set if a node in the node's parent chain has dir=auto.
NodeAncestorHasDirAuto,
// Set if the element is in the scope of a scoped style sheet; this flag is
@@ -1688,8 +1637,6 @@ public:
{ SetBoolFlag(NodeHasRenderingObservers, aValue); }
bool IsContent() const { return GetBoolFlag(NodeIsContent); }
bool HasID() const { return GetBoolFlag(ElementHasID); }
bool MayHaveClass() const { return GetBoolFlag(ElementMayHaveClass); }
void SetMayHaveClass() { SetBoolFlag(ElementMayHaveClass); }
bool MayHaveStyle() const { return GetBoolFlag(ElementMayHaveStyle); }
bool HasName() const { return GetBoolFlag(ElementHasName); }
bool MayHaveContentEditableAttr() const
@@ -1729,6 +1676,17 @@ public:
void SetHasValidDir() { SetBoolFlag(NodeHasValidDirAttribute); }
void ClearHasValidDir() { ClearBoolFlag(NodeHasValidDirAttribute); }
bool HasValidDir() const { return GetBoolFlag(NodeHasValidDirAttribute); }
void SetHasFixedDir() {
MOZ_ASSERT(NodeType() != nsIDOMNode::TEXT_NODE,
"SetHasFixedDir on text node");
SetBoolFlag(NodeHasFixedDir);
}
void ClearHasFixedDir() {
MOZ_ASSERT(NodeType() != nsIDOMNode::TEXT_NODE,
"ClearHasFixedDir on text node");
ClearBoolFlag(NodeHasFixedDir);
}
bool HasFixedDir() const { return GetBoolFlag(NodeHasFixedDir); }
void SetHasDirAutoSet() {
MOZ_ASSERT(NodeType() != nsIDOMNode::TEXT_NODE,
"SetHasDirAutoSet on text node");
@@ -1757,12 +1715,16 @@ public:
return GetBoolFlag(NodeHasTextNodeDirectionalityMap);
}
void SetHasDirAuto() { SetBoolFlag(NodeHasDirAuto); }
void ClearHasDirAuto() { ClearBoolFlag(NodeHasDirAuto); }
bool HasDirAuto() const { return GetBoolFlag(NodeHasDirAuto); }
void SetAncestorHasDirAuto() { SetBoolFlag(NodeAncestorHasDirAuto); }
void ClearAncestorHasDirAuto() { ClearBoolFlag(NodeAncestorHasDirAuto); }
bool AncestorHasDirAuto() const { return GetBoolFlag(NodeAncestorHasDirAuto); }
// Implemented in nsIContentInlines.h.
inline bool NodeOrAncestorHasDirAuto() const;
bool NodeOrAncestorHasDirAuto() const
{ return HasDirAuto() || AncestorHasDirAuto(); }
void SetIsElementInStyleScope(bool aValue) {
MOZ_ASSERT(IsElement(), "SetIsInStyleScope on a non-Element node");
@@ -1804,6 +1766,8 @@ protected:
void ClearHasName() { ClearBoolFlag(ElementHasName); }
void SetMayHaveContentEditableAttr()
{ SetBoolFlag(ElementMayHaveContentEditableAttr); }
bool HasExplicitBaseURI() const { return GetBoolFlag(NodeHasExplicitBaseURI); }
void SetHasExplicitBaseURI() { SetBoolFlag(NodeHasExplicitBaseURI); }
void SetHasLockedStyleStates() { SetBoolFlag(ElementHasLockedStyleStates); }
void ClearHasLockedStyleStates() { ClearBoolFlag(ElementHasLockedStyleStates); }
bool HasLockedStyleStates() const
-236
View File
@@ -1,236 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* Base class for all our document implementations.
*/
#ifndef nsIdentifierMapEntry_h
#define nsIdentifierMapEntry_h
#include "PLDHashTable.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/Move.h"
#include "mozilla/net/ReferrerPolicy.h"
#include "nsCOMArray.h"
#include "nsCOMPtr.h"
#include "nsIAtom.h"
#include "nsTArray.h"
#include "nsTHashtable.h"
#include "nsHashKeys.h"
class nsIContent;
class nsContentList;
class nsBaseContentList;
namespace mozilla {
namespace dom {
class Element;
} // namespace dom
} // namespace mozilla
/**
* Right now our identifier map entries contain information for 'name'
* and 'id' mappings of a given string. This is so that
* nsHTMLDocument::ResolveName only has to do one hash lookup instead
* of two. It's not clear whether this still matters for performance.
*
* We also store the document.all result list here. This is mainly so that
* when all elements with the given ID are removed and we remove
* the ID's nsIdentifierMapEntry, the document.all result is released too.
* Perhaps the document.all results should have their own hashtable
* in nsHTMLDocument.
*/
class nsIdentifierMapEntry : public PLDHashEntryHdr
{
typedef mozilla::dom::Element Element;
typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
/**
* @see nsIDocument::IDTargetObserver, this is just here to avoid include
* hell.
*/
typedef bool (* IDTargetObserver)(Element* aOldElement,
Element* aNewelement, void* aData);
public:
struct AtomOrString
{
MOZ_IMPLICIT AtomOrString(nsIAtom* aAtom) : mAtom(aAtom) {}
MOZ_IMPLICIT AtomOrString(const nsAString& aString) : mString(aString) {}
AtomOrString(const AtomOrString& aOther)
: mAtom(aOther.mAtom)
, mString(aOther.mString)
{
}
AtomOrString(AtomOrString&& aOther)
: mAtom(aOther.mAtom.forget())
, mString(aOther.mString)
{
}
nsCOMPtr<nsIAtom> mAtom;
const nsString mString;
};
typedef const AtomOrString& KeyType;
typedef const AtomOrString* KeyTypePointer;
explicit nsIdentifierMapEntry(const AtomOrString& aKey);
explicit nsIdentifierMapEntry(const AtomOrString* aKey);
nsIdentifierMapEntry(nsIdentifierMapEntry&& aOther);
~nsIdentifierMapEntry();
KeyType GetKey() const { return mKey; }
nsString GetKeyAsString() const
{
if (mKey.mAtom) {
return nsAtomString(mKey.mAtom);
}
return mKey.mString;
}
bool KeyEquals(const KeyTypePointer aOtherKey) const
{
if (mKey.mAtom) {
if (aOtherKey->mAtom) {
return mKey.mAtom == aOtherKey->mAtom;
}
return mKey.mAtom->Equals(aOtherKey->mString);
}
if (aOtherKey->mAtom) {
return aOtherKey->mAtom->Equals(mKey.mString);
}
return mKey.mString.Equals(aOtherKey->mString);
}
static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
static PLDHashNumber HashKey(const KeyTypePointer aKey)
{
return aKey->mAtom ?
aKey->mAtom->hash() : mozilla::HashString(aKey->mString);
}
enum { ALLOW_MEMMOVE = false };
void AddNameElement(nsINode* aDocument, Element* aElement);
void RemoveNameElement(Element* aElement);
bool IsEmpty();
nsBaseContentList* GetNameContentList() {
return mNameContentList;
}
bool HasNameElement() const;
/**
* Returns the element if we know the element associated with this
* id. Otherwise returns null.
*/
Element* GetIdElement();
/**
* Returns the list of all elements associated with this id.
*/
const nsTArray<Element*>& GetIdElements() const {
return mIdContentList;
}
/**
* If this entry has a non-null image element set (using SetImageElement),
* the image element will be returned, otherwise the same as GetIdElement().
*/
Element* GetImageIdElement();
/**
* Append all the elements with this id to aElements
*/
void AppendAllIdContent(nsCOMArray<nsIContent>* aElements);
/**
* This can fire ID change callbacks.
* @return true if the content could be added, false if we failed due
* to OOM.
*/
bool AddIdElement(Element* aElement);
/**
* This can fire ID change callbacks.
*/
void RemoveIdElement(Element* aElement);
/**
* Set the image element override for this ID. This will be returned by
* GetIdElement(true) if non-null.
*/
void SetImageElement(Element* aElement);
bool HasIdElementExposedAsHTMLDocumentProperty();
bool HasContentChangeCallback() { return mChangeCallbacks != nullptr; }
void AddContentChangeCallback(IDTargetObserver aCallback,
void* aData, bool aForImage);
void RemoveContentChangeCallback(IDTargetObserver aCallback,
void* aData, bool aForImage);
/**
* Remove all elements and notify change listeners.
*/
void ClearAndNotify();
void Traverse(nsCycleCollectionTraversalCallback* aCallback);
struct ChangeCallback {
IDTargetObserver mCallback;
void* mData;
bool mForImage;
};
struct ChangeCallbackEntry : public PLDHashEntryHdr {
typedef const ChangeCallback KeyType;
typedef const ChangeCallback* KeyTypePointer;
explicit ChangeCallbackEntry(const ChangeCallback* aKey) :
mKey(*aKey) { }
ChangeCallbackEntry(const ChangeCallbackEntry& toCopy) :
mKey(toCopy.mKey) { }
KeyType GetKey() const { return mKey; }
bool KeyEquals(KeyTypePointer aKey) const {
return aKey->mCallback == mKey.mCallback &&
aKey->mData == mKey.mData &&
aKey->mForImage == mKey.mForImage;
}
static KeyTypePointer KeyToPointer(KeyType& aKey) { return &aKey; }
static PLDHashNumber HashKey(KeyTypePointer aKey)
{
return mozilla::HashGeneric(aKey->mCallback, aKey->mData);
}
enum { ALLOW_MEMMOVE = true };
ChangeCallback mKey;
};
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
private:
nsIdentifierMapEntry(const nsIdentifierMapEntry& aOther) = delete;
nsIdentifierMapEntry& operator=(const nsIdentifierMapEntry& aOther) = delete;
void FireChangeCallbacks(Element* aOldElement, Element* aNewElement,
bool aImageOnly = false);
AtomOrString mKey;
// empty if there are no elements with this ID.
// The elements are stored as weak pointers.
AutoTArray<Element*, 1> mIdContentList;
RefPtr<nsBaseContentList> mNameContentList;
nsAutoPtr<nsTHashtable<ChangeCallbackEntry> > mChangeCallbacks;
RefPtr<Element> mImageElement;
};
#endif // #ifndef nsIdentifierMapEntry_h
+5 -7
View File
@@ -97,7 +97,7 @@ nsInProcessTabChildGlobal::nsInProcessTabChildGlobal(nsIDocShell* aShell,
mozilla::HoldJSObjects(this);
// If owner corresponds to an <iframe mozbrowser> or <iframe mozapp>, we'll
// GetEventTargetParent implementation.
// have to tweak our PreHandleEvent implementation.
nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwner);
if (browserFrame) {
mIsBrowserOrAppFrame = browserFrame->GetReallyIsBrowserOrApp();
@@ -251,7 +251,7 @@ nsInProcessTabChildGlobal::GetOwnerContent()
}
nsresult
nsInProcessTabChildGlobal::GetEventTargetParent(EventChainPreVisitor& aVisitor)
nsInProcessTabChildGlobal::PreHandleEvent(EventChainPreVisitor& aVisitor)
{
aVisitor.mForceContentDispatch = true;
aVisitor.mCanHandle = true;
@@ -270,7 +270,7 @@ nsInProcessTabChildGlobal::GetEventTargetParent(EventChainPreVisitor& aVisitor)
#endif
if (mPreventEventsEscaping) {
aVisitor.SetParentTarget(nullptr, false);
aVisitor.mParentTarget = nullptr;
return NS_OK;
}
@@ -278,13 +278,11 @@ nsInProcessTabChildGlobal::GetEventTargetParent(EventChainPreVisitor& aVisitor)
(!mOwner || !nsContentUtils::IsInChromeDocshell(mOwner->OwnerDoc()))) {
if (mOwner) {
if (nsPIDOMWindowInner* innerWindow = mOwner->OwnerDoc()->GetInnerWindow()) {
// 'this' is already a "chrome handler", so we consider window's
// parent target to be part of that same part of the event path.
aVisitor.SetParentTarget(innerWindow->GetParentTarget(), false);
aVisitor.mParentTarget = innerWindow->GetParentTarget();
}
}
} else {
aVisitor.SetParentTarget(mOwner, false);
aVisitor.mParentTarget = mOwner;
}
return NS_OK;
+2 -2
View File
@@ -96,7 +96,7 @@ public:
JS::Handle<JSObject *> aCpows,
nsIPrincipal* aPrincipal) override;
virtual nsresult GetEventTargetParent(
virtual nsresult PreHandleEvent(
mozilla::EventChainPreVisitor& aVisitor) override;
NS_IMETHOD AddEventListener(const nsAString& aType,
nsIDOMEventListener* aListener,
@@ -168,7 +168,7 @@ protected:
// Is this the message manager for an in-process <iframe mozbrowser> or
// <iframe mozapp>? This affects where events get sent, so it affects
// GetEventTargetParent.
// PreHandleEvent.
bool mIsBrowserOrAppFrame;
bool mPreventEventsEscaping;
+4 -7
View File
@@ -25,7 +25,7 @@
#include "xpcpublic.h"
#include "nsContentUtils.h"
#include "nsGlobalWindow.h"
#include "mozilla/CycleCollectedJSContext.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/Date.h"
#include "mozilla/dom/Element.h"
@@ -160,8 +160,7 @@ nsJSUtils::EvaluateString(JSContext* aCx,
aEvaluationGlobal);
MOZ_ASSERT_IF(aOffThreadToken, aCompileOptions.noScriptRval);
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(CycleCollectedJSContext::Get() &&
CycleCollectedJSContext::Get()->MicroTaskLevel());
MOZ_ASSERT(nsContentUtils::IsInMicroTask());
// Unfortunately, the JS engine actually compiles scripts with a return value
// in a different, less efficient way. Furthermore, it can't JIT them in many
@@ -295,8 +294,7 @@ nsJSUtils::CompileModule(JSContext* aCx,
aEvaluationGlobal);
MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx) == aEvaluationGlobal);
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(CycleCollectedJSContext::Get() &&
CycleCollectedJSContext::Get()->MicroTaskLevel());
MOZ_ASSERT(nsContentUtils::IsInMicroTask());
NS_ENSURE_TRUE(xpc::Scriptability::Get(aEvaluationGlobal).Allowed(), NS_OK);
@@ -333,8 +331,7 @@ nsJSUtils::ModuleEvaluation(JSContext* aCx, JS::Handle<JSObject*> aModule)
MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(CycleCollectedJSContext::Get() &&
CycleCollectedJSContext::Get()->MicroTaskLevel());
MOZ_ASSERT(nsContentUtils::IsInMicroTask());
NS_ENSURE_TRUE(xpc::Scriptability::Get(aModule).Allowed(), NS_OK);
+6 -8
View File
@@ -15,19 +15,17 @@ nsMappedAttributeElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
}
bool
nsMappedAttributeElement::SetAndSwapMappedAttribute(nsIDocument* aDocument,
nsIAtom* aName,
nsAttrValue& aValue,
bool* aValueWasSet,
nsresult* aRetval)
nsMappedAttributeElement::SetMappedAttribute(nsIDocument* aDocument,
nsIAtom* aName,
nsAttrValue& aValue,
nsresult* aRetval)
{
NS_PRECONDITION(aDocument == GetComposedDoc(), "Unexpected document");
nsHTMLStyleSheet* sheet = aDocument ?
aDocument->GetAttributeStyleSheet() : nullptr;
*aRetval = mAttrsAndChildren.SetAndSwapMappedAttr(aName, aValue,
this, sheet, aValueWasSet);
*aRetval = mAttrsAndChildren.SetAndTakeMappedAttr(aName, aValue,
this, sheet);
return true;
}
+4 -5
View File
@@ -39,11 +39,10 @@ public:
nsRuleData* aRuleData);
NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker) override;
virtual bool SetAndSwapMappedAttribute(nsIDocument* aDocument,
nsIAtom* aName,
nsAttrValue& aValue,
bool* aValueWasSet,
nsresult* aRetval) override;
virtual bool SetMappedAttribute(nsIDocument* aDocument,
nsIAtom* aName,
nsAttrValue& aValue,
nsresult* aRetval) override;
};
#endif // NS_MAPPEDATTRIBUTEELEMENT_H_
+6 -13
View File
@@ -62,17 +62,11 @@ nsMappedAttributes::Clone(bool aWillAddAttr)
void* nsMappedAttributes::operator new(size_t aSize, uint32_t aAttrCount) CPP_THROW_NEW
{
size_t size = aSize + aAttrCount * sizeof(InternalAttr);
NS_ASSERTION(aAttrCount > 0, "zero-attribute nsMappedAttributes requested");
// aSize will include the mAttrs buffer so subtract that.
// We don't want to under-allocate, however, so do not subtract
// if we have zero attributes. The zero attribute case only happens
// for <body>'s mapped attributes
if (aAttrCount != 0) {
size -= sizeof(void*[1]);
}
void* newAttrs = ::operator new(size);
void* newAttrs = ::operator new(aSize - sizeof(void*[1]) +
aAttrCount * sizeof(InternalAttr));
#ifdef DEBUG
static_cast<nsMappedAttributes*>(newAttrs)->mBufferSize = aAttrCount;
@@ -85,16 +79,15 @@ NS_IMPL_ISUPPORTS(nsMappedAttributes,
nsIStyleRule)
void
nsMappedAttributes::SetAndSwapAttr(nsIAtom* aAttrName, nsAttrValue& aValue,
bool* aValueWasSet)
nsMappedAttributes::SetAndTakeAttr(nsIAtom* aAttrName, nsAttrValue& aValue)
{
NS_PRECONDITION(aAttrName, "null name");
*aValueWasSet = false;
uint32_t i;
for (i = 0; i < mAttrCount && !Attrs()[i].mName.IsSmaller(aAttrName); ++i) {
if (Attrs()[i].mName.Equals(aAttrName)) {
Attrs()[i].mValue.Reset();
Attrs()[i].mValue.SwapValueWith(aValue);
*aValueWasSet = true;
return;
}
}
+1 -2
View File
@@ -33,8 +33,7 @@ public:
NS_DECL_ISUPPORTS
void SetAndSwapAttr(nsIAtom* aAttrName, nsAttrValue& aValue,
bool* aValueWasSet);
void SetAndTakeAttr(nsIAtom* aAttrName, nsAttrValue& aValue);
const nsAttrValue* GetAttr(nsIAtom* aAttrName) const;
const nsAttrValue* GetAttr(const nsAString& aAttrName) const;
Loaded 100 of 1842 files, more files were not shown because too many files have changed in this diff. Show more