Compare commits

...
Author SHA1 Message Date
Moonchild dda5aa7a0a Issue #2305 Part 3a: Pass ResultTemplateKind through CreateRegExpMatchResult
This sets up the MatchResult with the proper structure to contain indices
when necessary.
2024-11-09 19:17:11 +01:00
Moonchild 6dc7752f94 Issue #2305 Part 2: Support .indices in match result template objects
Before match indices, all match results had the same shape. (If there are
no named capture groups, `.groups` exists but is undefined.) Match results
with `.indices` have a distinct shape, so we need a distinct template
object. We also need a template object for `.indices` itself.
2024-11-09 18:51:54 +01:00
Moonchild e93ff331a4 Issue #2305 Part 1: Add support for hasIndices to RegExpFlags (/d)
Adds recognition and parsing of the /d RegExp flag.
Drive-by correction: add missing "s" for dotAll to RegExpObject::toString.
Tag #1284 and #2008
2024-11-08 18:22:22 +01:00
Karl Tomlinson 7f93d25967 Bug 1920800 - Remove oldImages from check for flushed old principal handle
The logic should be equivalent when frame IDs on aImages are contiguously
increasing from IDs on previously set frames.

There are currently no callers passing empty aImages, but the logic in this
case would now be as described in the documentation of
UpdatePrincipalHandleForFrameID():

> We will notify mElement that aPrincipalHandle has been applied when all
> FrameIDs prior to aFrameID have been flushed out.
2024-10-30 13:21:33 +01:00
Moonchild 0f007a16d5 Issue #2648 - Inherit the content disposition of the multipart response 2024-10-30 09:50:08 +01:00
Moonchild eacd48cccb Issue #2648 - Apply CSP to documents sent through multipart/x-mixed-replace 2024-10-30 09:48:28 +01:00
Moonchild fc1fe7d0c5 Issue #2646 - Parse "variations" keywords.
Resolves #2646
2024-10-29 15:27:44 +01:00
Moonchild 92873ead3e Revert "Issue #2645 - Fix type confusion for ResumeKind"
This reverts commit 12e9db2481.
2024-10-28 14:51:10 +01:00
Moonchild 9fede4a3ba Merge branch '2645-resumekind' 2024-10-23 10:52:32 +02:00
Moonchild dbd5dc9554 Issue #2645 - Return null if getName() PC is invalid. 2024-10-21 22:50:57 +02:00
Moonchild 3f538909ab Merge branch 'master' into 2645-resumekind 2024-10-21 13:56:59 +02:00
Moonchild 8e4ce9b800 Issue #2641 - Update Fetch to adhere to the updated spec (pass refpolicy)
Resolves #2641
2024-10-21 12:37:01 +02:00
Moonchild edf4210e12 Issue #2641 - Speculative load changes for referrerpolicy 2024-10-21 12:36:11 +02:00
Moonchild 5a64fd9657 Merge pull request 'Apply border-radius to Outlines as fallback to -moz-outline-radius' (#2643) from RealityRipple/UXP:outline-radius-fallback into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2643
2024-10-11 21:55:29 +00:00
Moonchild 12e9db2481 Issue #2645 - Fix type confusion for ResumeKind
It used a mix of uint8_t and uint16_t. Set it to uint16_t.
Also don't allow non-typeset to simplify stubs used in compound opcodes.
2024-10-11 22:02:44 +02:00
Andy 0af6123536 The border-radius Directive Should Apply to Outlines
However, `-moz-outline-radius` should still override any `border-radius`.
This is primarily done for backward compatibility with some themes.
Additionally, it also allows for more advanced outline control than the CSS spec provides, without breaking spec.
Finally, if the spec is ever updated to include `outline-radius`, we'll be ready to drop the `-moz-` prefix!

Note: BZ 315209 has an inadvertent double-negative in nsDisplayList.cpp:
HasRadius() essentially returns the opposite value it should.
2024-10-09 12:08:46 -07:00
Moonchild e2c94125cc [GMP] Factor out more detailed CheckDimensions function for CreateFrame. 2024-10-02 10:34:38 +02:00
Steve Fink 723ca48613 [js] Disallow deserializing structured clone buffers with transferables more than once. 2024-10-01 22:22:04 +02:00
Boris Zbarsky 15514da406 Bug 1493449 - Change the default credentials mode for module scripts from 'omit' to 'same-origin'
Resolves #2642
2024-10-01 00:03:06 +02:00
Moonchild 04d1e3e53a Revert "Issue #2523 - Part 1 - Import headers from FFmpeg 7.0"
This reverts commit 27bb48deaf.
2024-09-30 23:49:05 +02:00
Moonchild c654c1820f Revert "Issue #2523 - Part 2 - Update audio & video decoders to work with FFmpeg 7.0"
This reverts commit 7dbc24a739.
2024-09-30 23:48:55 +02:00
Moonchild 39dd9d560a Revert "Issue #2527 - Part 1 - Remove old FFmpeg and LibAV headers"
This reverts commit b970fc412a.
2024-09-30 23:48:43 +02:00
Moonchild 032357c053 Revert "Issue #2527 - Part 2 - Remove support for libavcodec < 58"
This reverts commit 738c6a740a.
2024-09-30 23:48:33 +02:00
Moonchild ecacd4a4d9 Revert "Issue #2527 - Part 3 - Remove additional checks for LibAV"
This reverts commit b0f872c919.
2024-09-30 23:48:25 +02:00
Moonchild a6bc5962c4 Bug 1900191 - Use nestegg advertised default duration if it exists. 2024-09-30 22:34:37 +02:00
Moonchild 12e93be21a Bug 1878510 - Follow-up: Explicitly pass values through variadic functions
While MSVC has no issue with this and understands values should be passed,
clang doesn't like it and aborts.
2024-09-27 13:15:06 +02:00
Moonchild 0aeac02b89 Bug 1878510 - When recreating WebM demuxer when encountering a new segment, propagate media time 2024-09-25 22:22:49 +02:00
Moonchild 1402d8eee6 Merge pull request 'libjpeg: NetBSD/powerpc ALTIVEC simd support' (#2591) from discoM/UXP:powerpc_altivec into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2591
2024-09-23 13:02:25 +00:00
Martin Husemann 42b3e18a4a libjpeg: add NetBSD/powerpc spcific Altivec cpu feature detection 2024-09-23 12:51:33 +02:00
Moonchild cabe9ea2d5 Update README to point to the xref site.
Gitea's bleve indexer is too slow and resource-intensive to use.
2024-09-22 15:14:37 +02:00
Moonchild c57a1eee66 Merge pull request 'Make NetBSD use the same xptcall support as others.' (#2588) from discoM/UXP:xptcall_netbsd_powerpc into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2588
2024-09-22 10:50:03 +00:00
Moonchild a8fbc1dfbe Merge pull request 'Make NetBSD/powerpc use the powerpc atomic ops.' (#2589) from discoM/UXP:netbsd_ppc_atomicops into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2589
2024-09-22 10:49:44 +00:00
Martin Husemann 1f457514b0 Hardcode '-maltivec' as compiler flag for powerpc/altivec support 2024-09-22 12:39:23 +02:00
Martin Husemann acd339fcf7 Make NetBSD/powerpc use the powerpc atomic ops.
NetBSD/powerpc gcc does not predefine __ppc__, but only __powerpc__,
so add that to the preprocessor ifdef cascade to select atomic
ops.
2024-09-22 12:10:32 +02:00
Martin Husemann 07bb7f379b Make NetBSD use the same xptcall support as others.
These functions are only ELF ABI specific, not really OS specific.
Add powerpc, powerpc64 and sparc64 support for NetBSD
by using the same code as other ELF systems do.
2024-09-22 11:56:04 +02:00
Moonchild 8cabf0bf72 [Debug] Make inaccurate GC stats reporting non-fatal in debug builds.
Not sure why this was fatal as it only hinders being able to report memory
issues to a debugging dev :P
2024-09-21 15:38:34 +02:00
Moonchild 178f72365d Merge branch '2251-ghostbuster-work' 2024-09-20 16:47:02 +02:00
FranklinDM f819937a31 Issue #2251 - Expose unlink ghost windows to about:memory 2024-09-19 19:08:04 +02:00
FranklinDM 114b5265d6 Issue #2251 - Expose ghost window unlinking to release builds. 2024-09-19 19:07:33 +02:00
Moonchild 8595dc550f No issue - Fix asserts in debug.
Hashbang parser changes allow more than one EOL which screws up these
assertions' premise. Just remove them as the preconditions are no longer
valid.
2024-09-19 19:04:22 +02:00
Moonchild 5b8d28ba4d Merge pull request 'Fix building for Apple Silicon Mac with Xcode 16.' (#2587) from dbsoft/UXP:clangarm64fix into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2587
2024-09-19 12:47:55 +00:00
Brian Smith 8146ba5a07 No Issue - Fix building for Apple Silicon Mac with Xcode 16.
Due to the following LLVM change labels need to be outside .cfi_start/endprocs:
https://reviews.llvm.org/D155245
Solution pointed out here is to move the label above .cfi_startproc:
https://github.com/libffi/libffi/issues/807
2024-09-18 13:47:23 -05:00
Moonchild 727b9c9adf Merge pull request 'media/libcubeb: Use Sun audio backend also on NetBSD' (#2583) from nia/UXP:sunaudio-netbsd into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2583
2024-09-13 10:33:35 +00:00
Moonchild 7056301965 Merge pull request 'Fix bashism in old-configure.in' (#2582) from nia/UXP:shellport into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2582
2024-09-13 10:29:01 +00:00
Nia Alarie dc3c2f3da8 media/libcubeb: Use Sun audio backend also on NetBSD 2024-09-13 12:15:20 +02:00
Nia Alarie baf4c5b6bb Fix bashism in old-configure.in 2024-09-13 12:13:13 +02:00
Moonchild 3575bc580f Merge pull request 'Implement and expose config preferences for SOP and CORS' (#2580) from FranklinDM/UXP-contrib:work_content-disable-cors-sop into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2580
2024-09-12 16:19:47 +00:00
FranklinDM 21e49b0a92 Issue #2578 - Part 3: Expose CORS and CORS bypass preflight requests preferences. 2024-09-13 00:00:11 +08:00
FranklinDM 9d9534cc71 Issue #2578 - Part 2: Implement preference for disabling CORS preflight requests if CORS is disabled 2024-09-13 00:00:11 +08:00
FranklinDM 993681b010 Issue #2578 - Part 1: Implement preference for controlling same-origin policy 2024-09-13 00:00:10 +08:00
Moonchild 3d29257050 Merge pull request 'js: Support for the MPROTECT security feature (PaX and NetBSD)' (#2579) from nia/UXP:mprotect into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2579
2024-09-12 13:04:23 +00:00
Nia Alarie 7dd9438137 js: Support for the MPROTECT security feature (PaX and NetBSD)
On such platforms, remapping memory that was once writable
to executable is forbidden unless the initial mmap() is declared
to change in such a way using the PROT_MPROTECT macro.
2024-09-12 09:42:44 +02:00
Moonchild 44c611aeaf [js xpconnect] Fix error handling in xpc::CreateSandboxObject 2024-09-04 15:21:42 +02:00
Moonchild 7c4cbfd49e [js] Simplify with-env handling in FetchName 2024-09-04 15:21:08 +02:00
Moonchild 64bc57fa85 [DOM] Stop exposing NotifyPaintEvent to web content.
There's no reason this should be available to the web, as it's an
indicator of browser internals.
2024-09-04 13:31:23 +02:00
Moonchild c6a82aa32c Merge pull request 'Implement hashbang grammar (ES2023)' (#2560) from hashbang-work into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2560
2024-09-01 09:22:33 +00:00
Moonchild 334fe4be6c Issue #2559 - Implement hashbang grammar
This adds special-case #! comment handling at the top level, treating
any hashbang line as a single-line comment in the parser.
This only applies to Eval(), module script or global context.
2024-08-29 11:40:42 +02:00
Moonchild d76e865563 Merge pull request 'Add DOMMatrix versions of getTransform/setTransform' (#2558) from dommatrix-transforms-work into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2558
2024-08-17 09:06:31 +00:00
Moonchild ed862e5777 Issue #1810 - Add DOMMatrix {get|set}Transform WebIDL interfaces 2024-08-16 14:33:06 +02:00
Moonchild 719bed3ead Issue #1810 - Allow superfluous [LenientFloat] extended attributes.
This changes the way the extended attribute [LenientFloat] behaves, so
that overloading functions can match extended attributes while not
having restricted float type arguments themselves.
2024-08-16 14:31:51 +02:00
Moonchild e1c28ba852 Issue #1810 - Implement {get|set}Transform with DOMMatrix arguments.
We already had part of the plumbing for other canvas manipulations, so
this is somewhat simplified.

This excludes the interface as that is breaking the build at this stage.
Some more research is required.
2024-08-16 11:02:07 +02:00
Moonchild ba54621f01 Issue #1925 - Follow-up: Fix debug builds (namespace) 2024-08-12 11:23:35 +02:00
Moonchild 9babba6c44 No issue - Update TwemojiMozilla to 15.1.2
Fixes out-of-bounds watermelon emoji size.
2024-08-09 19:35:21 +02:00
Moonchild 5ff9b81126 Issue #2554 - Follow-up: Also block [::] and [::0.0.0.0] IPv6 addresses. 2024-08-09 19:17:49 +02:00
Moonchild 70c32d67f9 Issue #2554 - Follow-up: Correct code comment (no functional changes) 2024-08-09 16:18:37 +02:00
Moonchild 09a4832168 Issue #2554 - Block access to 0.0.0.0 on non-Windows OSes.
Resolves #2554.
2024-08-09 15:56:21 +02:00
Moonchild 1fd02db477 Update NSS to 3.90.4
Note: manually updated the version indicators due to BZ Bug 1912012
(https://bugzilla.mozilla.org/show_bug.cgi?id=1912012)
2024-08-07 13:03:17 +02:00
Moonchild 810a054eb5 [DOM] Pass error up the chain in SetColorValue. 2024-08-07 11:58:14 +02:00
Moonchild 3104055d42 Merge pull request '[gfx] Fix loading libGL on NetBSD' (#2553) from nia/UXP:webgl-netbsd into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2553
2024-08-04 19:01:49 +00:00
Nia Alarie 0d3d33623f [gfx] Fix loading libGL on NetBSD
The unversioned libGL is preferred on OpenBSD and NetBSD because
both (a) always install it (b) have forks of X11 with different
ABI versions.  However, many Linux distributions do not ship
unversioned .so symlinks unless you install -dev packages.

Unfortunately also needs to be fixed in ANGLE which has the same
problem.
2024-08-04 13:39:17 +02:00
Moonchild 3c46251443 Merge pull request 'Clean up CSS Macro use' (#2552) from 1925-macro-cleanup-work into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2552
2024-08-03 06:32:26 +00:00
Moonchild 186c58897b Issue #1925 - Replace RectCorner with Corner. 2024-08-02 12:10:27 +02:00
Moonchild bb3405c8b6 Issue #1925 - Convert NS_SIDE_TO_HALF_CORNER to a constexpr function. 2024-08-02 11:15:28 +02:00
Moonchild b82596eb98 Issue #1925 - Convert NS_SIDE_TO_FULL_CORNER to a constexpr function. 2024-08-02 10:36:07 +02:00
Moonchild cf7b3e3a09 Issue #1925 - Convert NS_SIDE_IS_VERTICAL to a constexpr function. 2024-08-02 10:31:21 +02:00
Moonchild c9cd25abc5 Issue #1925 - Convert NS_FULL_TO_HALF_CORNER to a constexpr function.
Note: Because the new function checks types, we need to change the
fullCorner type in `nsComputedDOMStyle::GetEllipseRadii()` and
`StyleAnimationValue::ExtractComputedValue()` to `Corner` instead of the
underlying base type.
2024-08-02 10:15:50 +02:00
Moonchild 73e0e8bbbe Issue #1925 - Convert NS_HALF_TO_FULL_CORNER to a constexpr function. 2024-08-02 09:25:03 +02:00
Moonchild 0bdb90ab40 Issue #1925 - Convert NS_HALF_CORNER_IS_X to a constexpr function. 2024-08-02 08:30:23 +02:00
Moonchild c0d87ea595 Issue #1925 - Move NS_FOR_CSS_HALF_CORNER to gfx/2d/Types.h and rewrite it. 2024-08-02 08:10:52 +02:00
Moonchild 11c9b60eba Issue #1925 - Convert half-corner index macros to an enum. 2024-08-02 08:01:01 +02:00
Moonchild f9d1e87756 Issue #1925 - Remove use of NS_CORNER_{TOP|BOTTOM}_{LEFT|RIGHT} macros. 2024-08-02 06:08:29 +02:00
Moonchild 15ad259ac7 Issue #1925 - Rewrite NS_FOR_CSS_CORNERS to be similar to *_SIDES
- Renames it to NS_CSS_FULL_CORNERS and uses the one macro for all full
  corners. In preparation for giving half corners the same treatment.
- Swaps to prefix operator++
2024-08-02 04:50:01 +02:00
Moonchild 819c3c990b Issue #1925 - Move Corner enum from mozilla::css to mozilla namespace. 2024-08-01 20:28:28 +02:00
Moonchild c4d4c9d6de Issue #1925 - Rename Corner to LogicalCorner and move it to nsStyleCoord.h.
To avoid confusion with mozilla::css::corner, rename ::Corner to
mozilla::LogicalCorner, and move it to nsStyleCoord.h from the illogical
nsCellMap.h location.
Also, append the LogicalCorner prefix to all the enum values, to match
the surrounding coding style.
2024-08-01 20:09:22 +02:00
Moonchild 903dea4285 Issue #1925 - Move NS_FOR_CSS_CORNERS and enum to gfx/2d/Types.h. 2024-08-01 19:55:20 +02:00
Moonchild 620a3336eb Issue #1925 - Change Side's operator++ from postfix to prefix.
The postfix operator++ was actually incorrectly implemented (the
implementation is a prefix version). Since it's only used in the adjacent
macro, there's no risk with this change to correct that.
2024-08-01 18:58:14 +02:00
Moonchild 6d20a50b09 Issue #1925 - Remove use of SIDE_BIT{S}_* macros.
This already has an enum in gfx/Types.h
2024-08-01 18:23:03 +02:00
Moonchild dc4316132b Issue #1925 - Remove use of NS_SIDE_* macros. 2024-08-01 17:28:01 +02:00
Moonchild 9b375ff678 Issue #1925 - Remove mozilla::css::Side typedef. 2024-08-01 16:46:27 +02:00
Moonchild 7a0c651c5d Issue #1925 - Move NS_FOR_CSS_SIDES and operator++ to gfx/2d/Types.h 2024-08-01 16:11:48 +02:00
Moonchild a653cb9b83 No issue - Update Twemoji Mozilla to 15.1.1
This updates Lime and Watermelon emoji to slightly larger versions.
2024-07-29 23:17:42 +02:00
Moonchild 4875759e78 Merge branch '2515-remove-content-dispatch-flags' 2024-07-25 22:44:15 +02:00
Moonchild 126b981629 Issue #2515 - Guard devtools click handlers against non-primary clicks.
We only want clicks on HTML elements to respond to the primary button.
2024-07-25 15:50:31 +02:00
Moonchild 103cf524ec Issue #2515 - Clarify only dispatching in chrome. 2024-07-25 15:42:08 +02:00
Moonchild ea96fed795 Issue #2515 - Remove mForceContentDispatch and mNoContentDispatch 2024-07-25 15:33:07 +02:00
Moonchild 8c46320564 Merge pull request 'constants.py: fix powerpc arch detection' (#2550) from barracuda156/UXP:arch_fix into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2550
2024-07-20 21:36:14 +00:00
Sergey Fedorov 23b2a53d4c constants.py: fix powerpc arch detection 2024-07-16 21:14:14 +08:00
Moonchild 4616af0c7c Bump platform version 2024-07-16 11:40:03 +02:00
Moonchild a873824668 Merge pull request 'Implement parser and CSSOM support for layer at-rules' (#2549) from FranklinDM/UXP-contrib:work_css-cascade-layers-parser-only into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2549
Reviewed-by: Moonchild <moonchild@palemoon.org>
2024-07-16 09:12:34 +00:00
FranklinDM e5cec10a4e Issue #2486 - Part 5: Fix parsing of nested layer names
This does not handle the merging of same-named layers, however.
2024-07-15 09:00:53 +08:00
FranklinDM 917cac9674 Issue #2486 - Part 4: Ensure layer statement rule is appended and invalid tokens are restored 2024-07-15 08:33:34 +08:00
FranklinDM be4699e54c Issue #2486 - Part 3: Fix serialization of layer statement rule 2024-07-15 08:33:26 +08:00
FranklinDM caaf54a046 Issue #2486 - Part 2: Implement parser support for layer block and layer statements
This does not deal with layer specificity.
2024-07-14 22:58:25 +08:00
FranklinDM d3812c1a0e Issue #2486 - Part 1: Initial plumbing and CSSOM support for cascade layers 2024-07-14 22:58:24 +08:00
Moonchild 729b32a2f0 Issue #2547 - Remove hidden network.dns.disablePrefetchFromHTTPS pref.
Resolves #2547
2024-07-10 23:25:49 +02:00
Moonchild 79c8e2e86c [DOM/network] Disable DNS prefetching if document nodePrincipal is systemPrincipal 2024-07-10 09:14:47 +02:00
Moonchild 93b4e6566d [IPC] Clean up control flow in WaitableEvent. 2024-07-10 07:43:38 +02:00
Moonchild 42a3dffe69 [network] Add additional cookie setting checks.
Added checks for sub-document navigations from cross-site to same-site in
third-party checks when setting a cookie.
2024-07-10 00:22:49 +02:00
Moonchild b21dd824a2 Merge branch 'master' of https://repo.palemoon.org/MoonchildProductions/UXP 2024-07-09 22:38:36 +02:00
Moonchild ccd9e8e106 Merge pull request 'Implement Sec-Fetch headers and improve mixed content blocker' (#2544) from sec-fetch-work into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2544
2024-07-09 20:37:45 +00:00
Moonchild eebb25dda0 No issue - Update SQLite to 3.46.0 2024-07-09 21:29:41 +02:00
Moonchild 27ce4ea0fa No issue - Update NSS to 3.90.3 2024-07-09 21:18:25 +02:00
Moonchild fb4ede7d2e Merge branch 'remove-foxeye' 2024-07-09 13:30:27 +02:00
Moonchild a09c6b6ce0 Issue #2546 - Part 6: Remove canvas.imagebitmap_extensions.enabled preference. 2024-07-09 12:16:18 +02:00
Moonchild a8f376aa3b Issue #2546 - Part 5: Remove tests 2024-07-09 12:00:35 +02:00
Moonchild e9868fcb47 Issue #2546 - Part 4: Remove mappedDataLength and findOptimalFormat 2024-07-09 11:56:51 +02:00
Moonchild 7e49aebcc8 Issue #2546 - Part 3: Remove mapDataInto 2024-07-09 00:33:06 +02:00
Moonchild 1c04829dca Issue #2546 - Part 2: Remove special FoxEye CreateImageBitmap method. 2024-07-08 23:45:49 +02:00
Moonchild 2379bb29be Issue #2546 - Part 1: Remove BufferSource support in CreateImageBitmap. 2024-07-08 23:36:40 +02:00
Moonchild 2b2475905e Issue #2542 - Part 9: Remove TODO comment.
From our understanding of the spec, our current implementation is
feature-complete.
2024-07-07 03:07:29 +02:00
Moonchild f25c809ff0 Issue #2045 - Temporarily force hidden elements to be actually hidden.
For the time being, because we don't have `revert` yet, we should force
normally hidden elements to be hidden, so they aren't revealed by sites
using the bad practice of `*{ }` style blanking rules but then using
`revert` to re-hide them.
2024-07-06 17:47:06 +02:00
Moonchild ff9f024589 Issue #2542 - Part 8: Enable Sec-Fetch-* headers by default. 2024-07-05 15:26:49 +02:00
Moonchild add1037bb8 Issue #2542 - Part 7: Move SecFetch.* to /netwerk where it belongs. 2024-07-05 14:05:45 +02:00
Moonchild 962ca150bd Issue #2542 - Part 6: Add Sec-Fetch-User header for all requests that
are the direct result of a system principal request.

This means navigation resulting from interaction with the browser UI
should result in a -user header (address bar navigation, bookmarks, etc.)
2024-07-04 22:40:06 +02:00
Moonchild b693f60fc7 Issue #2542 - Part 5: Assume browser-initiated requests for unspecified
content types to always be user-triggered.
2024-07-04 22:34:00 +02:00
Moonchild a4cd652b6f Issue #2542 - Part 4b: Fix pointer mess-up. 2024-07-04 19:00:29 +02:00
Moonchild 689cbd7509 Issue #2542 - Part 4: Use BasePrincipal's IsSameOrigin() in SecFetch. 2024-07-03 17:03:36 +02:00
Moonchild a3f4272093 Issue #2542 - Part 3: Expand BasePrincipal with an IsSameOrigin check
Manual checking of the origins in SecFetch fails, so we add this
capability to the base principal interface for sake of ease.
We could use ScriptSecurityManager directly but it's more convenient
this way and can be re-used elsewhere in the future.
2024-07-03 17:02:32 +02:00
Moonchild 927173b648 Issue #2542 - Part 2b: Fix typo in pref check 2024-07-03 16:59:39 +02:00
Moonchild c62cc61613 Issue #2542 - Part 2: Base implementation of Sec-Fetch-* header code.
Currently following Mozilla putting stuff in /dom for additional porting,
but it's actually the wrong location since it belongs in /netwerk with
the other code that deals with http headers.
2024-07-03 11:00:53 +02:00
Moonchild b4a50f830c Issue #2542 - Part 1b: Fix dom.securecontext.whitelist code issues
Some minor bugfixes (wrong condition and string type)
2024-07-02 22:07:39 +02:00
Moonchild 5cadc0eee2 Issue #2542 - Part 1: Factor out Potentially Trustworthy URI checks.
For sake of ease of use, converted to boolean functions that just assume "false"
in case of errors.

Note: Mozilla makes special arrangements for .onion addresses as well but
we explicitly do not adopt that. TOR browser can do that all day if it wants.
2024-07-02 21:23:30 +02:00
Moonchild 59431e104c Issue #2531 - Adjust rounding in toExponential (and kin) to round up at midpoint.
Resolves #2531
2024-07-02 00:14:28 +02:00
Moonchild 47de3819f6 Issue #2543 - adjust toFixed precision range according to spec update.
As pointed out in the ecma-262 spec change discussion, the behavior is
inconsistent for negative numbers because the exponential fallback assumes
all the digits will be displayed. The negative support was motivated just
by consistency, without any particular concrete use cases, and it's not
supported in other browsers, so this patch removes negatives.

Resolves #2543
2024-07-01 23:43:24 +02:00
Moonchild 037f0ac647 Issue #2541 - Deal with empty LineNameList in CSS grid templates.
Resolves #2541
2024-06-30 22:33:59 +02:00
Moonchild b97f03f0c6 Issue #2537 - Don't assume username fields appear before password fields in forms. 2024-06-28 14:55:06 +02:00
Moonchild e3443de36e Merge pull request 'Separate Emoji Cluster Extenders' (#2539) from RealityRipple/UXP:Component2538 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2539
2024-06-28 12:43:10 +00:00
Andy 4b1bf3620d Issue #2538 - Part 3: Bring ZWJ Awareness to ClusterReverseIterator
Additional patch to resolve a bug exposed while working on the Cluster issue.
2024-06-27 18:29:23 -07:00
Andy 5d221d0cb2 Issue #2538 - Part 2: Add IsEmojiClusterExtender
Check specifically for Emoji-specific clusters only in Emoji-specific contexts.
2024-06-26 11:11:19 -07:00
Andy 9cca2f22c5 Issue #2538 - Part 1: Undo IsClusterExtender Change
This partially reverts commit 49b7816286.
So much for getting rid of the stupid constants...
2024-06-26 11:10:15 -07:00
Moonchild 8a9955f181 Issue #2534 - Part 2: Update tests 2024-06-23 18:11:22 +02:00
Moonchild 90a67a4825 Issue #2534 - Part 1: window.postMessage should provide a trusted MessageEvent 2024-06-23 17:55:13 +02:00
Moonchild 4381067d04 Issue #2536 - Re-implement plugin enumeration shuffle.
Resolves #2536
2024-06-23 17:31:02 +02:00
Moonchild 5457c3711b Merge pull request 'Remove support for libavcodec 57 and below' (#2535) from trav90/UXP-contrib:2527 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2535
2024-06-23 14:43:40 +00:00
trav90 b0f872c919 Issue #2527 - Part 3 - Remove additional checks for LibAV
Also removes the "media.libavcodec.allow-obsolete" pref.
2024-06-21 07:14:53 -05:00
trav90 738c6a740a Issue #2527 - Part 2 - Remove support for libavcodec < 58
This removes all support for LibAV and FFmpeg 3.x and below. Only FFmpeg 4.x or higher is supported now.
2024-06-19 15:39:31 -05:00
trav90 b970fc412a Issue #2527 - Part 1 - Remove old FFmpeg and LibAV headers 2024-06-19 14:51:14 -05:00
Moonchild 0886ccfa95 No Issue - Add navigator.webdriver attribute.
This patch adds an enumerable, configurable, readonly attribute "webdriver" to
the Navigator object. The attribute is always false because we do not support
WebDriver or scripted automation.

The navigator.webdriver attribute is meant as an indication to web authors that
a document is visited by WebDriver. It is important to stress that it is not
meant as a way to detect that a website is being visited by a browser automation
tool or bot, but as a tool for web documents to take alternate code paths.

On the off-chance exposing navigator.webdriver turns out to be catastrophic,
we put it behind a new preference dom.webdriver.enabled that controls its
exposure.
2024-06-17 09:44:52 +02:00
Moonchild f3786e036c Merge pull request 'Add support for libavcodec61' (#2528) from trav90/UXP-contrib:2523 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2528
2024-06-17 06:50:26 +00:00
Moonchild d8091d3958 Issue #2532 - Align dialog submission triggered by form.submit() with the spec.
Submission in click handler of submit button should not be deferred
per https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#submit-dialog

See Bug 1719872
2024-06-15 17:04:24 +02:00
Moonchild 726452fc88 Issue #2532 - Prevent unwanted text selection when backdrop is clicked. 2024-06-15 17:03:43 +02:00
Moonchild 361b76beb2 Issue #2532 - Don't do PreventDefault for escape key if <select> dropdown is not shown
We always use PreventDefault for <select> element, which is problematic if modal
dialog is on as it prevents cancelling the dialog. We fix it by not blocking the
default action if <select> is not shown.

See Bug 1649278
2024-06-15 17:03:16 +02:00
Moonchild 6ca3eb7c98 Issue #2532 - Fix a null pointer crash while doing dialog form submission
See Bug 1652699
2024-06-15 17:02:31 +02:00
Moonchild 42a208e60c Issue #2532 - Default pref check to true 2024-06-15 17:01:57 +02:00
Moonchild c2de359372 Issue #2532 - Implement form[method=dialog]
See bug 1557303
2024-06-15 17:01:27 +02:00
Moonchild 40016a1bf9 Merge pull request 'Fix altivec code, fix building for PPC' (#2530) from o_o/UXP:master into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2530
2024-06-15 07:19:12 +00:00
Richard-Rogalski e593872f19 Fix altivec code, fix building for PPC
Altivec code was previously uncompilable, and the altivec accelerations
also could not be disabled with a build flag or env variable, leading
to pale moon not being buildable on any altivec supported CPU ( all
PPC CPUs ever almost ). Why? I don't know, 'inline' in C is cursed
and making it static makes it significantly less so.

Closes: https://forum.palemoon.org/viewtopic.php?f=5&t=31108&p=252462#p252462
Signed-off-by: Richard Rogalski <rrogalski@firemail.cc>
2024-06-14 19:45:13 -05:00
trav90 7dbc24a739 Issue #2523 - Part 2 - Update audio & video decoders to work with FFmpeg 7.0 2024-06-10 07:55:58 -05:00
trav90 27bb48deaf Issue #2523 - Part 1 - Import headers from FFmpeg 7.0 2024-06-08 15:54:35 -05:00
291 changed files with 23415 additions and 13691 deletions

No files matched your search

+1 -1
View File
@@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Switching to C++17 requires CLOBBER to pick up compiler conf. (Issue #2281)
Clobber for NSS update
+7
View File
@@ -19,6 +19,13 @@ 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).
You are also always welcome to get in touch with our community on the [Pale Moon forum](https://forum.palemoon.org/).
### Code search
While our repo has basic code searching capabilities (via `git grep`), you are strongly
encouraged to instead use the dedicated code search and cross-referencing site:
[https://xref.palemoon.org/](https://xref.palemoon.org/)
This repo and a copy of the front-end are amalgamated in the `goanna-central` index.
### A note about trademarks and branding
Although this repository is primarily licensed under Mozilla Public License v2.0, the
+1 -1
View File
@@ -80,7 +80,7 @@ StyleInfo::TextIndent(nsAString& aValue)
}
void
StyleInfo::Margin(css::Side aSide, nsAString& aValue)
StyleInfo::Margin(Side aSide, nsAString& aValue)
{
MOZ_ASSERT(mElement->GetPrimaryFrame(), " mElement->GetPrimaryFrame() needs to be valid pointer");
aValue.Truncate();
+17
View File
@@ -560,6 +560,23 @@ BasePrincipal::GetCspJSON(nsAString& outCSPinJSON)
return mCSP->ToJSON(outCSPinJSON);
}
NS_IMETHODIMP
BasePrincipal::IsSameOrigin(nsIURI* aURI, bool aIsPrivateWin, bool* aRes) {
*aRes = false;
nsCOMPtr<nsIURI> prinURI;
nsresult rv = GetURI(getter_AddRefs(prinURI));
if (NS_FAILED(rv) || !prinURI) {
return NS_OK;
}
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
if (!ssm) {
return NS_ERROR_UNEXPECTED;
;
}
*aRes = NS_SUCCEEDED(ssm->CheckSameOriginURI(prinURI, aURI, aIsPrivateWin));
return NS_OK;
}
NS_IMETHODIMP
BasePrincipal::GetIsNullPrincipal(bool* aResult)
{
+1
View File
@@ -282,6 +282,7 @@ public:
NS_IMETHOD GetUnknownAppId(bool* aUnknownAppId) final;
NS_IMETHOD GetUserContextId(uint32_t* aUserContextId) final;
NS_IMETHOD GetPrivateBrowsingId(uint32_t* aPrivateBrowsingId) final;
NS_IMETHOD IsSameOrigin(nsIURI* aURI, bool aIsPrivateWin, bool* aRes) override;
bool EqualsIgnoringAddonId(nsIPrincipal *aOther);
+6
View File
@@ -223,6 +223,12 @@ interface nsIPrincipal : nsISerializable
*/
readonly attribute AUTF8String originSuffix;
/**
* Uses NS_Security Compare to determine if the
* other URI is same-origin as the uri of the Principal
*/
bool IsSameOrigin(in nsIURI otherURI, in bool aIsPrivateWin);
/**
* The base domain of the codebase URI to which this principal pertains
* (generally the document URI), handling null principals and
+7 -1
View File
@@ -76,6 +76,7 @@ nsIIOService *nsScriptSecurityManager::sIOService = nullptr;
nsIStringBundle *nsScriptSecurityManager::sStrBundle = nullptr;
JSContext *nsScriptSecurityManager::sContext = nullptr;
bool nsScriptSecurityManager::sStrictFileOriginPolicy = true;
bool nsScriptSecurityManager::sSameOriginPolicy = true;
///////////////////////////
// Convenience Functions //
@@ -607,7 +608,7 @@ nsScriptSecurityManager::CheckSameOriginURI(nsIURI* aSourceURI,
nsIURI* aTargetURI,
bool reportError)
{
if (!SecurityCompareURIs(aSourceURI, aTargetURI))
if (sSameOriginPolicy && !SecurityCompareURIs(aSourceURI, aTargetURI))
{
if (reportError) {
ReportError(nullptr, NS_LITERAL_STRING("CheckSameOriginError"),
@@ -1434,10 +1435,13 @@ nsScriptSecurityManager::CanGetService(JSContext *cx,
const char sJSEnabledPrefName[] = "javascript.enabled";
const char sFileOriginPolicyPrefName[] =
"security.fileuri.strict_origin_policy";
const char sSameOriginPolicyPrefName[] =
"security.same_origin_policy.enabled";
static const char* kObservedPrefs[] = {
sJSEnabledPrefName,
sFileOriginPolicyPrefName,
sSameOriginPolicyPrefName,
"capability.policy.",
nullptr
};
@@ -1593,6 +1597,8 @@ nsScriptSecurityManager::ScriptSecurityPrefChanged()
Preferences::GetBool(sJSEnabledPrefName, mIsJavaScriptEnabled);
sStrictFileOriginPolicy =
Preferences::GetBool(sFileOriginPolicyPrefName, false);
sSameOriginPolicy =
Preferences::GetBool(sSameOriginPolicyPrefName, true);
mFileURIWhitelist.reset();
}
+1
View File
@@ -152,6 +152,7 @@ private:
}
static bool sStrictFileOriginPolicy;
static bool sSameOriginPolicy;
static nsIIOService *sIOService;
static nsIStringBundle *sStrBundle;
+1 -1
View File
@@ -8,4 +8,4 @@
# Referenced by milestone.py.
#--------------------------------------------------------
6.6.0
6.7.0
+9 -34
View File
@@ -1,39 +1,14 @@
This directory contains source code to
This is the SQLite amalgamation.
Check sqlite3.h for the version number and source id.
SQLite: An Embeddable SQL Database Engine
See http://www.sqlite.org/ for more info.
To compile the project, first create a directory in which to place
the build products. It is recommended, but not required, that the
build directory be separate from the source directory. Cd into the
build directory and then from the build directory run the configure
script found at the root of the source tree. Then run "make".
We have a UXP-specific moz.build in src/ (normally not there) that we
use to build. Adfditionally, src/ contains sqlite.symbols which lists
all explicitly exported symbols from the library to expose.
For example:
To move to a new version:
tar xzf sqlite.tar.gz ;# Unpack the source tree into "sqlite"
mkdir bld ;# Build will occur in a sibling directory
cd bld ;# Change to the build directory
../sqlite/configure ;# Run the configure script
make ;# Run the makefile.
make install ;# (Optional) Install the build products
Copy the sqlite3.h and sqlite3.c files from the amalgamation of sqlite.
The configure script uses autoconf 2.61 and libtool. If the configure
script does not work out for you, there is a generic makefile named
"Makefile.linux-gcc" in the top directory of the source tree that you
can copy and edit to suit your needs. Comments on the generic makefile
show what changes are needed.
The linux binaries on the website are created using the generic makefile,
not the configure script. The windows binaries on the website are created
using MinGW32 configured as a cross-compiler running under Linux. For
details, see the ./publish.sh script at the top-level of the source tree.
The developers do not use teh configure script.
SQLite does not require TCL to run, but a TCL installation is required
by the makefiles. SQLite contains a lot of generated code and TCL is
used to do much of that code generation. The makefile also requires
AWK.
Contacts:
http://www.sqlite.org/
Be sure to update SQLITE_VERSION accordingly in $(topsrcdir)/old-configure.in.
-13
View File
@@ -1,13 +0,0 @@
This is the SQLite amalgamation.
Check sqlite3.h for the version number and source id.
See http://www.sqlite.org/ for more info.
We have a mozilla-specific Makefile.in in src/ (normally no
Makefile.in there) that we use to build.
To move to a new version:
Copy the sqlite3.h and sqlite3.c files from the amalgamation of sqlite.
Be sure to update SQLITE_VERSION accordingly in $(topsrcdir)/configure.in.
+18003 -7959
View File
File diff suppressed because it is too large. Load diff
+450 -93
View File
@@ -146,9 +146,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION "3.42.0"
#define SQLITE_VERSION_NUMBER 3042000
#define SQLITE_SOURCE_ID "2023-05-16 12:36:15 831d0fb2836b71c9bc51067c49fee4b8f18047814f2ff22d817d25195cf350b0"
#define SQLITE_VERSION "3.46.0"
#define SQLITE_VERSION_NUMBER 3046000
#define SQLITE_SOURCE_ID "2024-05-23 13:25:27 96c92aba00c8375bc32fafcdf12429c58bd8aabfcadab6683e35bbb9cdebf19e"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -420,6 +420,8 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running.
** <li> The application must not modify the SQL statement text passed into
** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running.
** <li> The application must not dereference the arrays or string pointers
** passed as the 3rd and 4th callback parameters after it returns.
** </ul>
*/
SQLITE_API int sqlite3_exec(
@@ -528,6 +530,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8))
#define SQLITE_IOERR_DATA (SQLITE_IOERR | (32<<8))
#define SQLITE_IOERR_CORRUPTFS (SQLITE_IOERR | (33<<8))
#define SQLITE_IOERR_IN_PAGE (SQLITE_IOERR | (34<<8))
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
#define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8))
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
@@ -761,11 +764,11 @@ struct sqlite3_file {
** </ul>
** xLock() upgrades the database file lock. In other words, xLock() moves the
** database file lock in the direction NONE toward EXCLUSIVE. The argument to
** xLock() is always on of SHARED, RESERVED, PENDING, or EXCLUSIVE, never
** xLock() is always one of SHARED, RESERVED, PENDING, or EXCLUSIVE, never
** SQLITE_LOCK_NONE. If the database file lock is already at or above the
** requested lock, then the call to xLock() is a no-op.
** xUnlock() downgrades the database file lock to either SHARED or NONE.
* If the lock is already at or below the requested lock state, then the call
** If the lock is already at or below the requested lock state, then the call
** to xUnlock() is a no-op.
** The xCheckReservedLock() method checks whether any database connection,
** either in this process or in some other process, is holding a RESERVED,
@@ -1190,7 +1193,7 @@ struct sqlite3_io_methods {
** by clients within the current process, only within other processes.
**
** <li>[[SQLITE_FCNTL_CKSM_FILE]]
** The [SQLITE_FCNTL_CKSM_FILE] opcode is for use interally by the
** The [SQLITE_FCNTL_CKSM_FILE] opcode is for use internally by the
** [checksum VFS shim] only.
**
** <li>[[SQLITE_FCNTL_RESET_CACHE]]
@@ -2126,7 +2129,7 @@ struct sqlite3_mem_methods {
** is stored in each sorted record and the required column values loaded
** from the database as records are returned in sorted order. The default
** value for this option is to never use this optimization. Specifying a
** negative value for this option restores the default behaviour.
** negative value for this option restores the default behavior.
** This option is only available if SQLite is compiled with the
** [SQLITE_ENABLE_SORTER_REFERENCES] compile-time option.
**
@@ -2140,6 +2143,22 @@ struct sqlite3_mem_methods {
** configuration setting is never used, then the default maximum is determined
** by the [SQLITE_MEMDB_DEFAULT_MAXSIZE] compile-time option. If that
** compile-time option is not set, then the default maximum is 1073741824.
**
** [[SQLITE_CONFIG_ROWID_IN_VIEW]]
** <dt>SQLITE_CONFIG_ROWID_IN_VIEW
** <dd>The SQLITE_CONFIG_ROWID_IN_VIEW option enables or disables the ability
** for VIEWs to have a ROWID. The capability can only be enabled if SQLite is
** compiled with -DSQLITE_ALLOW_ROWID_IN_VIEW, in which case the capability
** defaults to on. This configuration option queries the current setting or
** changes the setting to off or on. The argument is a pointer to an integer.
** If that integer initially holds a value of 1, then the ability for VIEWs to
** have ROWIDs is activated. If the integer initially holds zero, then the
** ability is deactivated. Any other initial value for the integer leaves the
** setting unchanged. After changes, if any, the integer is written with
** a 1 or 0, if the ability for VIEWs to have ROWIDs is on or off. If SQLite
** is compiled without -DSQLITE_ALLOW_ROWID_IN_VIEW (which is the usual and
** recommended case) then the integer is always filled with zero, regardless
** if its initial value.
** </dl>
*/
#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
@@ -2171,6 +2190,7 @@ struct sqlite3_mem_methods {
#define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */
#define SQLITE_CONFIG_SORTERREF_SIZE 28 /* int nByte */
#define SQLITE_CONFIG_MEMDB_MAXSIZE 29 /* sqlite3_int64 */
#define SQLITE_CONFIG_ROWID_IN_VIEW 30 /* int* */
/*
** CAPI3REF: Database Connection Configuration Options
@@ -2301,7 +2321,7 @@ struct sqlite3_mem_methods {
** database handle, SQLite checks if this will mean that there are now no
** connections at all to the database. If so, it performs a checkpoint
** operation before closing the connection. This option may be used to
** override this behaviour. The first parameter passed to this operation
** override this behavior. The first parameter passed to this operation
** is an integer - positive to disable checkpoints-on-close, or zero (the
** default) to enable them, and negative to leave the setting unchanged.
** The second parameter is a pointer to an integer
@@ -2454,7 +2474,7 @@ struct sqlite3_mem_methods {
** the [VACUUM] command will fail with an obscure error when attempting to
** process a table with generated columns and a descending index. This is
** not considered a bug since SQLite versions 3.3.0 and earlier do not support
** either generated columns or decending indexes.
** either generated columns or descending indexes.
** </dd>
**
** [[SQLITE_DBCONFIG_STMT_SCANSTATUS]]
@@ -2735,6 +2755,7 @@ SQLITE_API sqlite3_int64 sqlite3_total_changes64(sqlite3*);
**
** ^The [sqlite3_is_interrupted(D)] interface can be used to determine whether
** or not an interrupt is currently in effect for [database connection] D.
** It returns 1 if an interrupt is currently in effect, or 0 otherwise.
*/
SQLITE_API void sqlite3_interrupt(sqlite3*);
SQLITE_API int sqlite3_is_interrupted(sqlite3*);
@@ -3284,8 +3305,8 @@ SQLITE_API int sqlite3_set_authorizer(
#define SQLITE_RECURSIVE 33 /* NULL NULL */
/*
** CAPI3REF: Tracing And Profiling Functions
** METHOD: sqlite3
** CAPI3REF: Deprecated Tracing And Profiling Functions
** DEPRECATED
**
** These routines are deprecated. Use the [sqlite3_trace_v2()] interface
** instead of the routines described here.
@@ -3388,8 +3409,10 @@ SQLITE_API SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*,
** M argument should be the bitwise OR-ed combination of
** zero or more [SQLITE_TRACE] constants.
**
** ^Each call to either sqlite3_trace() or sqlite3_trace_v2() overrides
** (cancels) any prior calls to sqlite3_trace() or sqlite3_trace_v2().
** ^Each call to either sqlite3_trace(D,X,P) or sqlite3_trace_v2(D,M,X,P)
** overrides (cancels) all prior calls to sqlite3_trace(D,X,P) or
** sqlite3_trace_v2(D,M,X,P) for the [database connection] D. Each
** database connection may have at most one trace callback.
**
** ^The X callback is invoked whenever any of the events identified by
** mask M occur. ^The integer return value from the callback is currently
@@ -3758,7 +3781,7 @@ SQLITE_API int sqlite3_open_v2(
** as F) must be one of:
** <ul>
** <li> A database filename pointer created by the SQLite core and
** passed into the xOpen() method of a VFS implemention, or
** passed into the xOpen() method of a VFS implementation, or
** <li> A filename obtained from [sqlite3_db_filename()], or
** <li> A new filename constructed using [sqlite3_create_filename()].
** </ul>
@@ -3871,7 +3894,7 @@ SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*);
/*
** CAPI3REF: Create and Destroy VFS Filenames
**
** These interfces are provided for use by [VFS shim] implementations and
** These interfaces are provided for use by [VFS shim] implementations and
** are not useful outside of that context.
**
** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of
@@ -3950,14 +3973,17 @@ SQLITE_API void sqlite3_free_filename(sqlite3_filename);
** </ul>
**
** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
** text that describes the error, as either UTF-8 or UTF-16 respectively.
** text that describes the error, as either UTF-8 or UTF-16 respectively,
** or NULL if no error message is available.
** (See how SQLite handles [invalid UTF] for exceptions to this rule.)
** ^(Memory to hold the error message string is managed internally.
** The application does not need to worry about freeing the result.
** However, the error string might be overwritten or deallocated by
** subsequent calls to other SQLite interface functions.)^
**
** ^The sqlite3_errstr() interface returns the English-language text
** that describes the [result code], as UTF-8.
** ^The sqlite3_errstr(E) interface returns the English-language text
** that describes the [result code] E, as UTF-8, or NULL if E is not an
** result code for which a text error message is available.
** ^(Memory to hold the error message string is managed internally
** and must not be freed by the application)^.
**
@@ -4418,6 +4444,41 @@ SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
*/
SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Change The EXPLAIN Setting For A Prepared Statement
** METHOD: sqlite3_stmt
**
** The sqlite3_stmt_explain(S,E) interface changes the EXPLAIN
** setting for [prepared statement] S. If E is zero, then S becomes
** a normal prepared statement. If E is 1, then S behaves as if
** its SQL text began with "[EXPLAIN]". If E is 2, then S behaves as if
** its SQL text began with "[EXPLAIN QUERY PLAN]".
**
** Calling sqlite3_stmt_explain(S,E) might cause S to be reprepared.
** SQLite tries to avoid a reprepare, but a reprepare might be necessary
** on the first transition into EXPLAIN or EXPLAIN QUERY PLAN mode.
**
** Because of the potential need to reprepare, a call to
** sqlite3_stmt_explain(S,E) will fail with SQLITE_ERROR if S cannot be
** reprepared because it was created using [sqlite3_prepare()] instead of
** the newer [sqlite3_prepare_v2()] or [sqlite3_prepare_v3()] interfaces and
** hence has no saved SQL text with which to reprepare.
**
** Changing the explain setting for a prepared statement does not change
** the original SQL text for the statement. Hence, if the SQL text originally
** began with EXPLAIN or EXPLAIN QUERY PLAN, but sqlite3_stmt_explain(S,0)
** is called to convert the statement into an ordinary statement, the EXPLAIN
** or EXPLAIN QUERY PLAN keywords will still appear in the sqlite3_sql(S)
** output, even though the statement now acts like a normal SQL statement.
**
** This routine returns SQLITE_OK if the explain mode is successfully
** changed, or an error code if the explain mode could not be changed.
** The explain mode cannot be changed while a statement is active.
** Hence, it is good practice to call [sqlite3_reset(S)]
** immediately prior to calling sqlite3_stmt_explain(S,E).
*/
SQLITE_API int sqlite3_stmt_explain(sqlite3_stmt *pStmt, int eMode);
/*
** CAPI3REF: Determine If A Prepared Statement Has Been Reset
** METHOD: sqlite3_stmt
@@ -4581,7 +4642,7 @@ typedef struct sqlite3_context sqlite3_context;
** with it may be passed. ^It is called to dispose of the BLOB or string even
** if the call to the bind API fails, except the destructor is not called if
** the third parameter is a NULL pointer or the fourth parameter is negative.
** ^ (2) The special constant, [SQLITE_STATIC], may be passsed to indicate that
** ^ (2) The special constant, [SQLITE_STATIC], may be passed to indicate that
** the application remains responsible for disposing of the object. ^In this
** case, the object and the provided pointer to it must remain valid until
** either the prepared statement is finalized or the same SQL parameter is
@@ -5260,20 +5321,33 @@ SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);
** ^The [sqlite3_reset(S)] interface resets the [prepared statement] S
** back to the beginning of its program.
**
** ^If the most recent call to [sqlite3_step(S)] for the
** [prepared statement] S returned [SQLITE_ROW] or [SQLITE_DONE],
** or if [sqlite3_step(S)] has never before been called on S,
** then [sqlite3_reset(S)] returns [SQLITE_OK].
** ^The return code from [sqlite3_reset(S)] indicates whether or not
** the previous evaluation of prepared statement S completed successfully.
** ^If [sqlite3_step(S)] has never before been called on S or if
** [sqlite3_step(S)] has not been called since the previous call
** to [sqlite3_reset(S)], then [sqlite3_reset(S)] will return
** [SQLITE_OK].
**
** ^If the most recent call to [sqlite3_step(S)] for the
** [prepared statement] S indicated an error, then
** [sqlite3_reset(S)] returns an appropriate [error code].
** ^The [sqlite3_reset(S)] interface might also return an [error code]
** if there were no prior errors but the process of resetting
** the prepared statement caused a new error. ^For example, if an
** [INSERT] statement with a [RETURNING] clause is only stepped one time,
** that one call to [sqlite3_step(S)] might return SQLITE_ROW but
** the overall statement might still fail and the [sqlite3_reset(S)] call
** might return SQLITE_BUSY if locking constraints prevent the
** database change from committing. Therefore, it is important that
** applications check the return code from [sqlite3_reset(S)] even if
** no prior call to [sqlite3_step(S)] indicated a problem.
**
** ^The [sqlite3_reset(S)] interface does not change the values
** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S.
*/
SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Create Or Redefine SQL Functions
** KEYWORDS: {function creation routines}
@@ -5484,7 +5558,7 @@ SQLITE_API int sqlite3_create_window_function(
** [application-defined SQL function]
** that has side-effects or that could potentially leak sensitive information.
** This will prevent attacks in which an application is tricked
** into using a database file that has had its schema surreptiously
** into using a database file that has had its schema surreptitiously
** modified to invoke the application-defined function in ways that are
** harmful.
** <p>
@@ -5520,13 +5594,27 @@ SQLITE_API int sqlite3_create_window_function(
** </dd>
**
** [[SQLITE_SUBTYPE]] <dt>SQLITE_SUBTYPE</dt><dd>
** The SQLITE_SUBTYPE flag indicates to SQLite that a function may call
** The SQLITE_SUBTYPE flag indicates to SQLite that a function might call
** [sqlite3_value_subtype()] to inspect the sub-types of its arguments.
** Specifying this flag makes no difference for scalar or aggregate user
** functions. However, if it is not specified for a user-defined window
** function, then any sub-types belonging to arguments passed to the window
** function may be discarded before the window function is called (i.e.
** sqlite3_value_subtype() will always return 0).
** This flag instructs SQLite to omit some corner-case optimizations that
** might disrupt the operation of the [sqlite3_value_subtype()] function,
** causing it to return zero rather than the correct subtype().
** SQL functions that invokes [sqlite3_value_subtype()] should have this
** property. If the SQLITE_SUBTYPE property is omitted, then the return
** value from [sqlite3_value_subtype()] might sometimes be zero even though
** a non-zero subtype was specified by the function argument expression.
**
** [[SQLITE_RESULT_SUBTYPE]] <dt>SQLITE_RESULT_SUBTYPE</dt><dd>
** The SQLITE_RESULT_SUBTYPE flag indicates to SQLite that a function might call
** [sqlite3_result_subtype()] to cause a sub-type to be associated with its
** result.
** Every function that invokes [sqlite3_result_subtype()] should have this
** property. If it does not, then the call to [sqlite3_result_subtype()]
** might become a no-op if the function is used as term in an
** [expression index]. On the other hand, SQL functions that never invoke
** [sqlite3_result_subtype()] should avoid setting this property, as the
** purpose of this property is to disable certain optimizations that are
** incompatible with subtypes.
** </dd>
** </dl>
*/
@@ -5534,6 +5622,7 @@ SQLITE_API int sqlite3_create_window_function(
#define SQLITE_DIRECTONLY 0x000080000
#define SQLITE_SUBTYPE 0x000100000
#define SQLITE_INNOCUOUS 0x000200000
#define SQLITE_RESULT_SUBTYPE 0x001000000
/*
** CAPI3REF: Deprecated Functions
@@ -5730,6 +5819,12 @@ SQLITE_API int sqlite3_value_encoding(sqlite3_value*);
** information can be used to pass a limited amount of context from
** one SQL function to another. Use the [sqlite3_result_subtype()]
** routine to set the subtype for the return value of an SQL function.
**
** Every [application-defined SQL function] that invoke this interface
** should include the [SQLITE_SUBTYPE] property in the text
** encoding argument when the function is [sqlite3_create_function|registered].
** If the [SQLITE_SUBTYPE] property is omitted, then sqlite3_value_subtype()
** might return zero instead of the upstream subtype in some corner cases.
*/
SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*);
@@ -5828,48 +5923,56 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
** METHOD: sqlite3_context
**
** These functions may be used by (non-aggregate) SQL functions to
** associate metadata with argument values. If the same value is passed to
** multiple invocations of the same SQL function during query execution, under
** some circumstances the associated metadata may be preserved. An example
** of where this might be useful is in a regular-expression matching
** function. The compiled version of the regular expression can be stored as
** metadata associated with the pattern string.
** associate auxiliary data with argument values. If the same argument
** value is passed to multiple invocations of the same SQL function during
** query execution, under some circumstances the associated auxiliary data
** might be preserved. An example of where this might be useful is in a
** regular-expression matching function. The compiled version of the regular
** expression can be stored as auxiliary data associated with the pattern string.
** Then as long as the pattern string remains the same,
** the compiled regular expression can be reused on multiple
** invocations of the same function.
**
** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the metadata
** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the auxiliary data
** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument
** value to the application-defined function. ^N is zero for the left-most
** function argument. ^If there is no metadata
** function argument. ^If there is no auxiliary data
** associated with the function argument, the sqlite3_get_auxdata(C,N) interface
** returns a NULL pointer.
**
** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
** argument of the application-defined function. ^Subsequent
** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as auxiliary data for the
** N-th argument of the application-defined function. ^Subsequent
** calls to sqlite3_get_auxdata(C,N) return P from the most recent
** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or
** NULL if the metadata has been discarded.
** sqlite3_set_auxdata(C,N,P,X) call if the auxiliary data is still valid or
** NULL if the auxiliary data has been discarded.
** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL,
** SQLite will invoke the destructor function X with parameter P exactly
** once, when the metadata is discarded.
** SQLite is free to discard the metadata at any time, including: <ul>
** once, when the auxiliary data is discarded.
** SQLite is free to discard the auxiliary data at any time, including: <ul>
** <li> ^(when the corresponding function parameter changes)^, or
** <li> ^(when [sqlite3_reset()] or [sqlite3_finalize()] is called for the
** SQL statement)^, or
** <li> ^(when sqlite3_set_auxdata() is invoked again on the same
** parameter)^, or
** <li> ^(during the original sqlite3_set_auxdata() call when a memory
** allocation error occurs.)^ </ul>
** allocation error occurs.)^
** <li> ^(during the original sqlite3_set_auxdata() call if the function
** is evaluated during query planning instead of during query execution,
** as sometimes happens with [SQLITE_ENABLE_STAT4].)^ </ul>
**
** Note the last bullet in particular. The destructor X in
** Note the last two bullets in particular. The destructor X in
** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the
** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata()
** should be called near the end of the function implementation and the
** function implementation should not make any use of P after
** sqlite3_set_auxdata() has been called.
** sqlite3_set_auxdata() has been called. Furthermore, a call to
** sqlite3_get_auxdata() that occurs immediately after a corresponding call
** to sqlite3_set_auxdata() might still return NULL if an out-of-memory
** condition occurred during the sqlite3_set_auxdata() call or if the
** function is being evaluated during query planning rather than during
** query execution.
**
** ^(In practice, metadata is preserved between function calls for
** ^(In practice, auxiliary data is preserved between function calls for
** function parameters that are compile-time constants, including literal
** values and [parameters] and expressions composed from the same.)^
**
@@ -5879,10 +5982,67 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
**
** These routines must be called from the same thread in which
** the SQL function is running.
**
** See also: [sqlite3_get_clientdata()] and [sqlite3_set_clientdata()].
*/
SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N);
SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));
/*
** CAPI3REF: Database Connection Client Data
** METHOD: sqlite3
**
** These functions are used to associate one or more named pointers
** with a [database connection].
** A call to sqlite3_set_clientdata(D,N,P,X) causes the pointer P
** to be attached to [database connection] D using name N. Subsequent
** calls to sqlite3_get_clientdata(D,N) will return a copy of pointer P
** or a NULL pointer if there were no prior calls to
** sqlite3_set_clientdata() with the same values of D and N.
** Names are compared using strcmp() and are thus case sensitive.
**
** If P and X are both non-NULL, then the destructor X is invoked with
** argument P on the first of the following occurrences:
** <ul>
** <li> An out-of-memory error occurs during the call to
** sqlite3_set_clientdata() which attempts to register pointer P.
** <li> A subsequent call to sqlite3_set_clientdata(D,N,P,X) is made
** with the same D and N parameters.
** <li> The database connection closes. SQLite does not make any guarantees
** about the order in which destructors are called, only that all
** destructors will be called exactly once at some point during the
** database connection closing process.
** </ul>
**
** SQLite does not do anything with client data other than invoke
** destructors on the client data at the appropriate time. The intended
** use for client data is to provide a mechanism for wrapper libraries
** to store additional information about an SQLite database connection.
**
** There is no limit (other than available memory) on the number of different
** client data pointers (with different names) that can be attached to a
** single database connection. However, the implementation is optimized
** for the case of having only one or two different client data names.
** Applications and wrapper libraries are discouraged from using more than
** one client data name each.
**
** There is no way to enumerate the client data pointers
** associated with a database connection. The N parameter can be thought
** of as a secret key such that only code that knows the secret key is able
** to access the associated data.
**
** Security Warning: These interfaces should not be exposed in scripting
** languages or in other circumstances where it might be possible for an
** an attacker to invoke them. Any agent that can invoke these interfaces
** can probably also take control of the process.
**
** Database connection client data is only available for SQLite
** version 3.44.0 ([dateof:3.44.0]) and later.
**
** See also: [sqlite3_set_auxdata()] and [sqlite3_get_auxdata()].
*/
SQLITE_API void *sqlite3_get_clientdata(sqlite3*,const char*);
SQLITE_API int sqlite3_set_clientdata(sqlite3*, const char*, void*, void(*)(void*));
/*
** CAPI3REF: Constants Defining Special Destructor Behavior
@@ -6084,6 +6244,20 @@ SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n);
** higher order bits are discarded.
** The number of subtype bytes preserved by SQLite might increase
** in future releases of SQLite.
**
** Every [application-defined SQL function] that invokes this interface
** should include the [SQLITE_RESULT_SUBTYPE] property in its
** text encoding argument when the SQL function is
** [sqlite3_create_function|registered]. If the [SQLITE_RESULT_SUBTYPE]
** property is omitted from the function that invokes sqlite3_result_subtype(),
** then in some cases the sqlite3_result_subtype() might fail to set
** the result subtype.
**
** If SQLite is compiled with -DSQLITE_STRICT_SUBTYPE=1, then any
** SQL function that invokes the sqlite3_result_subtype() interface
** and that does not have the SQLITE_RESULT_SUBTYPE property will raise
** an error. Future versions of SQLite might enable -DSQLITE_STRICT_SUBTYPE=1
** by default.
*/
SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int);
@@ -6515,7 +6689,7 @@ SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema);
/*
** CAPI3REF: Allowed return values from [sqlite3_txn_state()]
** CAPI3REF: Allowed return values from sqlite3_txn_state()
** KEYWORDS: {transaction state}
**
** These constants define the current transaction state of a database file.
@@ -6647,7 +6821,7 @@ SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
** ^Each call to the sqlite3_autovacuum_pages() interface overrides all
** previous invocations for that database connection. ^If the callback
** argument (C) to sqlite3_autovacuum_pages(D,C,P,X) is a NULL pointer,
** then the autovacuum steps callback is cancelled. The return value
** then the autovacuum steps callback is canceled. The return value
** from sqlite3_autovacuum_pages() is normally SQLITE_OK, but might
** be some other error code if something goes wrong. The current
** implementation will only return SQLITE_OK or SQLITE_MISUSE, but other
@@ -6713,6 +6887,12 @@ SQLITE_API int sqlite3_autovacuum_pages(
** The exceptions defined in this paragraph might change in a future
** release of SQLite.
**
** Whether the update hook is invoked before or after the
** corresponding change is currently unspecified and may differ
** depending on the type of change. Do not rely on the order of the
** hook call with regards to the final result of the operation which
** triggers the hook.
**
** The update hook implementation must not do anything that will modify
** the database connection that invoked the update hook. Any actions
** to modify the database connection must be deferred until after the
@@ -7166,6 +7346,10 @@ struct sqlite3_module {
/* The methods above are in versions 1 and 2 of the sqlite_module object.
** Those below are for version 3 and greater. */
int (*xShadowName)(const char*);
/* The methods above are in versions 1 through 3 of the sqlite_module object.
** Those below are for version 4 and greater. */
int (*xIntegrity)(sqlite3_vtab *pVTab, const char *zSchema,
const char *zTabName, int mFlags, char **pzErr);
};
/*
@@ -7653,7 +7837,7 @@ SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
** code is returned and the transaction rolled back.
**
** Calling this function with an argument that is not a NULL pointer or an
** open blob handle results in undefined behaviour. ^Calling this routine
** open blob handle results in undefined behavior. ^Calling this routine
** with a null pointer (such as would be returned by a failed call to
** [sqlite3_blob_open()]) is a harmless no-op. ^Otherwise, if this function
** is passed a valid open blob handle, the values returned by the
@@ -7880,9 +8064,11 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
**
** ^(Some systems (for example, Windows 95) do not support the operation
** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try()
** will always return SQLITE_BUSY. The SQLite core only ever uses
** sqlite3_mutex_try() as an optimization so this is acceptable
** behavior.)^
** will always return SQLITE_BUSY. In most cases the SQLite core only uses
** sqlite3_mutex_try() as an optimization, so this is acceptable
** behavior. The exceptions are unix builds that set the
** SQLITE_ENABLE_SETLK_TIMEOUT build option. In that case a working
** sqlite3_mutex_try() is required.)^
**
** ^The sqlite3_mutex_leave() routine exits a mutex that was
** previously entered by the same thread. The behavior
@@ -8133,6 +8319,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_PRNG_SAVE 5
#define SQLITE_TESTCTRL_PRNG_RESTORE 6
#define SQLITE_TESTCTRL_PRNG_RESET 7 /* NOT USED */
#define SQLITE_TESTCTRL_FK_NO_ACTION 7
#define SQLITE_TESTCTRL_BITVEC_TEST 8
#define SQLITE_TESTCTRL_FAULT_INSTALL 9
#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10
@@ -8140,6 +8327,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_ASSERT 12
#define SQLITE_TESTCTRL_ALWAYS 13
#define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */
#define SQLITE_TESTCTRL_JSON_SELFCHECK 14
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
@@ -8161,7 +8349,8 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_TRACEFLAGS 31
#define SQLITE_TESTCTRL_TUNE 32
#define SQLITE_TESTCTRL_LOGEST 33
#define SQLITE_TESTCTRL_LAST 33 /* Largest TESTCTRL */
#define SQLITE_TESTCTRL_USELONGDOUBLE 34
#define SQLITE_TESTCTRL_LAST 34 /* Largest TESTCTRL */
/*
** CAPI3REF: SQL Keyword Checking
@@ -8174,7 +8363,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
** The sqlite3_keyword_count() interface returns the number of distinct
** keywords understood by SQLite.
**
** The sqlite3_keyword_name(N,Z,L) interface finds the N-th keyword and
** The sqlite3_keyword_name(N,Z,L) interface finds the 0-based N-th keyword and
** makes *Z point to that keyword expressed as UTF8 and writes the number
** of bytes in the keyword into *L. The string that *Z points to is not
** zero-terminated. The sqlite3_keyword_name(N,Z,L) routine returns
@@ -9617,7 +9806,7 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
** [[SQLITE_VTAB_DIRECTONLY]]<dt>SQLITE_VTAB_DIRECTONLY</dt>
** <dd>Calls of the form
** [sqlite3_vtab_config](db,SQLITE_VTAB_DIRECTONLY) from within the
** the [xConnect] or [xCreate] methods of a [virtual table] implmentation
** the [xConnect] or [xCreate] methods of a [virtual table] implementation
** prohibits that virtual table from being used from within triggers and
** views.
** </dd>
@@ -9753,24 +9942,45 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
** <li value="2"><p>
** ^(If the sqlite3_vtab_distinct() interface returns 2, that means
** that the query planner does not need the rows returned in any particular
** order, as long as rows with the same values in all "aOrderBy" columns
** are adjacent.)^ ^(Furthermore, only a single row for each particular
** combination of values in the columns identified by the "aOrderBy" field
** needs to be returned.)^ ^It is always ok for two or more rows with the same
** values in all "aOrderBy" columns to be returned, as long as all such rows
** are adjacent. ^The virtual table may, if it chooses, omit extra rows
** that have the same value for all columns identified by "aOrderBy".
** ^However omitting the extra rows is optional.
** order, as long as rows with the same values in all columns identified
** by "aOrderBy" are adjacent.)^ ^(Furthermore, when two or more rows
** contain the same values for all columns identified by "colUsed", all but
** one such row may optionally be omitted from the result.)^
** The virtual table is not required to omit rows that are duplicates
** over the "colUsed" columns, but if the virtual table can do that without
** too much extra effort, it could potentially help the query to run faster.
** This mode is used for a DISTINCT query.
** <li value="3"><p>
** ^(If the sqlite3_vtab_distinct() interface returns 3, that means
** that the query planner needs only distinct rows but it does need the
** rows to be sorted.)^ ^The virtual table implementation is free to omit
** rows that are identical in all aOrderBy columns, if it wants to, but
** it is not required to omit any rows. This mode is used for queries
** ^(If the sqlite3_vtab_distinct() interface returns 3, that means the
** virtual table must return rows in the order defined by "aOrderBy" as
** if the sqlite3_vtab_distinct() interface had returned 0. However if
** two or more rows in the result have the same values for all columns
** identified by "colUsed", then all but one such row may optionally be
** omitted.)^ Like when the return value is 2, the virtual table
** is not required to omit rows that are duplicates over the "colUsed"
** columns, but if the virtual table can do that without
** too much extra effort, it could potentially help the query to run faster.
** This mode is used for queries
** that have both DISTINCT and ORDER BY clauses.
** </ol>
**
** <p>The following table summarizes the conditions under which the
** virtual table is allowed to set the "orderByConsumed" flag based on
** the value returned by sqlite3_vtab_distinct(). This table is a
** restatement of the previous four paragraphs:
**
** <table border=1 cellspacing=0 cellpadding=10 width="90%">
** <tr>
** <td valign="top">sqlite3_vtab_distinct() return value
** <td valign="top">Rows are returned in aOrderBy order
** <td valign="top">Rows with the same value in all aOrderBy columns are adjacent
** <td valign="top">Duplicates over all colUsed columns may be omitted
** <tr><td>0<td>yes<td>yes<td>no
** <tr><td>1<td>no<td>yes<td>no
** <tr><td>2<td>no<td>yes<td>yes
** <tr><td>3<td>yes<td>yes<td>yes
** </table>
**
** ^For the purposes of comparing virtual table output values to see if the
** values are same value for sorting purposes, two NULL values are considered
** to be the same. In other words, the comparison operator is "IS"
@@ -9807,7 +10017,7 @@ SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info*);
** communicated to the xBestIndex method as a
** [SQLITE_INDEX_CONSTRAINT_EQ] constraint.)^ If xBestIndex wants to use
** this constraint, it must set the corresponding
** aConstraintUsage[].argvIndex to a postive integer. ^(Then, under
** aConstraintUsage[].argvIndex to a positive integer. ^(Then, under
** the usual mode of handling IN operators, SQLite generates [bytecode]
** that invokes the [xFilter|xFilter() method] once for each value
** on the right-hand side of the IN operator.)^ Thus the virtual table
@@ -10236,7 +10446,7 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*);
** When the [sqlite3_blob_write()] API is used to update a blob column,
** the pre-update hook is invoked with SQLITE_DELETE. This is because the
** in this case the new values are not available. In this case, when a
** callback made with op==SQLITE_DELETE is actuall a write using the
** callback made with op==SQLITE_DELETE is actually a write using the
** sqlite3_blob_write() API, the [sqlite3_preupdate_blobwrite()] returns
** the index of the column being written. In other cases, where the
** pre-update hook is being invoked for some other reason, including a
@@ -10497,6 +10707,13 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const c
** SQLITE_SERIALIZE_NOCOPY bit is set but no contiguous copy
** of the database exists.
**
** After the call, if the SQLITE_SERIALIZE_NOCOPY bit had been set,
** the returned buffer content will remain accessible and unchanged
** until either the next write operation on the connection or when
** the connection is closed, and applications must not modify the
** buffer. If the bit had been clear, the returned buffer will not
** be accessed by SQLite after the call.
**
** A call to sqlite3_serialize(D,S,P,F) might return NULL even if the
** SQLITE_SERIALIZE_NOCOPY bit is omitted from argument F if a memory
** allocation error occurs.
@@ -10545,6 +10762,9 @@ SQLITE_API unsigned char *sqlite3_serialize(
** SQLite will try to increase the buffer size using sqlite3_realloc64()
** if writes on the database cause it to grow larger than M bytes.
**
** Applications must not modify the buffer P or invalidate it before
** the database connection D is closed.
**
** The sqlite3_deserialize() interface will fail with SQLITE_BUSY if the
** database is currently in a read transaction or is involved in a backup
** operation.
@@ -10553,6 +10773,13 @@ SQLITE_API unsigned char *sqlite3_serialize(
** S argument to sqlite3_deserialize(D,S,P,N,M,F) is "temp" then the
** function returns SQLITE_ERROR.
**
** The deserialized database should not be in [WAL mode]. If the database
** is in WAL mode, then any attempt to use the database file will result
** in an [SQLITE_CANTOPEN] error. The application can set the
** [file format version numbers] (bytes 18 and 19) of the input database P
** to 0x01 prior to invoking sqlite3_deserialize(D,S,P,N,M,F) to force the
** database file into rollback mode and work around this limitation.
**
** If sqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the
** SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then
** [sqlite3_free()] is invoked on argument P prior to returning.
@@ -11625,6 +11852,18 @@ SQLITE_API int sqlite3changeset_concat(
);
/*
** CAPI3REF: Upgrade the Schema of a Changeset/Patchset
*/
SQLITE_API int sqlite3changeset_upgrade(
sqlite3 *db,
const char *zDb,
int nIn, const void *pIn, /* Input changeset */
int *pnOut, void **ppOut /* OUT: Inverse of input */
);
/*
** CAPI3REF: Changegroup Handle
**
@@ -11671,6 +11910,38 @@ typedef struct sqlite3_changegroup sqlite3_changegroup;
*/
SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp);
/*
** CAPI3REF: Add a Schema to a Changegroup
** METHOD: sqlite3_changegroup_schema
**
** This method may be used to optionally enforce the rule that the changesets
** added to the changegroup handle must match the schema of database zDb
** ("main", "temp", or the name of an attached database). If
** sqlite3changegroup_add() is called to add a changeset that is not compatible
** with the configured schema, SQLITE_SCHEMA is returned and the changegroup
** object is left in an undefined state.
**
** A changeset schema is considered compatible with the database schema in
** the same way as for sqlite3changeset_apply(). Specifically, for each
** table in the changeset, there exists a database table with:
**
** <ul>
** <li> The name identified by the changeset, and
** <li> at least as many columns as recorded in the changeset, and
** <li> the primary key columns in the same position as recorded in
** the changeset.
** </ul>
**
** The output of the changegroup object always has the same schema as the
** database nominated using this function. In cases where changesets passed
** to sqlite3changegroup_add() have fewer columns than the corresponding table
** in the database schema, these are filled in using the default column
** values from the database schema. This makes it possible to combined
** changesets that have different numbers of columns for a single table
** within a changegroup, provided that they are otherwise compatible.
*/
SQLITE_API int sqlite3changegroup_schema(sqlite3_changegroup*, sqlite3*, const char *zDb);
/*
** CAPI3REF: Add A Changeset To A Changegroup
** METHOD: sqlite3_changegroup
@@ -11739,16 +12010,45 @@ SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp);
** If the new changeset contains changes to a table that is already present
** in the changegroup, then the number of columns and the position of the
** primary key columns for the table must be consistent. If this is not the
** case, this function fails with SQLITE_SCHEMA. If the input changeset
** appears to be corrupt and the corruption is detected, SQLITE_CORRUPT is
** returned. Or, if an out-of-memory condition occurs during processing, this
** function returns SQLITE_NOMEM. In all cases, if an error occurs the state
** of the final contents of the changegroup is undefined.
** case, this function fails with SQLITE_SCHEMA. Except, if the changegroup
** object has been configured with a database schema using the
** sqlite3changegroup_schema() API, then it is possible to combine changesets
** with different numbers of columns for a single table, provided that
** they are otherwise compatible.
**
** If no error occurs, SQLITE_OK is returned.
** If the input changeset appears to be corrupt and the corruption is
** detected, SQLITE_CORRUPT is returned. Or, if an out-of-memory condition
** occurs during processing, this function returns SQLITE_NOMEM.
**
** In all cases, if an error occurs the state of the final contents of the
** changegroup is undefined. If no error occurs, SQLITE_OK is returned.
*/
SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
/*
** CAPI3REF: Add A Single Change To A Changegroup
** METHOD: sqlite3_changegroup
**
** This function adds the single change currently indicated by the iterator
** passed as the second argument to the changegroup object. The rules for
** adding the change are just as described for [sqlite3changegroup_add()].
**
** If the change is successfully added to the changegroup, SQLITE_OK is
** returned. Otherwise, an SQLite error code is returned.
**
** The iterator must point to a valid entry when this function is called.
** If it does not, SQLITE_ERROR is returned and no change is added to the
** changegroup. Additionally, the iterator must not have been opened with
** the SQLITE_CHANGESETAPPLY_INVERT flag. In this case SQLITE_ERROR is also
** returned.
*/
SQLITE_API int sqlite3changegroup_add_change(
sqlite3_changegroup*,
sqlite3_changeset_iter*
);
/*
** CAPI3REF: Obtain A Composite Changeset From A Changegroup
** METHOD: sqlite3_changegroup
@@ -12010,10 +12310,17 @@ SQLITE_API int sqlite3changeset_apply_v2(
** <li>an insert change if all fields of the conflicting row match
** the row being inserted.
** </ul>
**
** <dt>SQLITE_CHANGESETAPPLY_FKNOACTION <dd>
** If this flag it set, then all foreign key constraints in the target
** database behave as if they were declared with "ON UPDATE NO ACTION ON
** DELETE NO ACTION", even if they are actually CASCADE, RESTRICT, SET NULL
** or SET DEFAULT.
*/
#define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001
#define SQLITE_CHANGESETAPPLY_INVERT 0x0002
#define SQLITE_CHANGESETAPPLY_IGNORENOOP 0x0004
#define SQLITE_CHANGESETAPPLY_FKNOACTION 0x0008
/*
** CAPI3REF: Constants Passed To The Conflict Handler
@@ -12546,8 +12853,8 @@ struct Fts5PhraseIter {
** EXTENSION API FUNCTIONS
**
** xUserData(pFts):
** Return a copy of the context pointer the extension function was
** registered with.
** Return a copy of the pUserData pointer passed to the xCreateFunction()
** API when the extension function was registered.
**
** xColumnTotalSize(pFts, iCol, pnToken):
** If parameter iCol is less than zero, set output variable *pnToken
@@ -12579,8 +12886,11 @@ struct Fts5PhraseIter {
** created with the "columnsize=0" option.
**
** xColumnText:
** This function attempts to retrieve the text of column iCol of the
** current document. If successful, (*pz) is set to point to a buffer
** If parameter iCol is less than zero, or greater than or equal to the
** number of columns in the table, SQLITE_RANGE is returned.
**
** Otherwise, this function attempts to retrieve the text of column iCol of
** the current document. If successful, (*pz) is set to point to a buffer
** containing the text in utf-8 encoding, (*pn) is set to the size in bytes
** (not characters) of the buffer and SQLITE_OK is returned. Otherwise,
** if an error occurs, an SQLite error code is returned and the final values
@@ -12590,8 +12900,10 @@ struct Fts5PhraseIter {
** Returns the number of phrases in the current query expression.
**
** xPhraseSize:
** Returns the number of tokens in phrase iPhrase of the query. Phrases
** are numbered starting from zero.
** If parameter iCol is less than zero, or greater than or equal to the
** number of phrases in the current query, as returned by xPhraseCount,
** 0 is returned. Otherwise, this function returns the number of tokens in
** phrase iPhrase of the query. Phrases are numbered starting from zero.
**
** xInstCount:
** Set *pnInst to the total number of occurrences of all phrases within
@@ -12607,12 +12919,13 @@ struct Fts5PhraseIter {
** Query for the details of phrase match iIdx within the current row.
** Phrase matches are numbered starting from zero, so the iIdx argument
** should be greater than or equal to zero and smaller than the value
** output by xInstCount().
** output by xInstCount(). If iIdx is less than zero or greater than
** or equal to the value returned by xInstCount(), SQLITE_RANGE is returned.
**
** Usually, output parameter *piPhrase is set to the phrase number, *piCol
** Otherwise, output parameter *piPhrase is set to the phrase number, *piCol
** to the column in which it occurs and *piOff the token offset of the
** first token of the phrase. Returns SQLITE_OK if successful, or an error
** code (i.e. SQLITE_NOMEM) if an error occurs.
** first token of the phrase. SQLITE_OK is returned if successful, or an
** error code (i.e. SQLITE_NOMEM) if an error occurs.
**
** This API can be quite slow if used with an FTS5 table created with the
** "detail=none" or "detail=column" option.
@@ -12638,6 +12951,10 @@ struct Fts5PhraseIter {
** Invoking Api.xUserData() returns a copy of the pointer passed as
** the third argument to pUserData.
**
** If parameter iPhrase is less than zero, or greater than or equal to
** the number of phrases in the query, as returned by xPhraseCount(),
** this function returns SQLITE_RANGE.
**
** If the callback function returns any value other than SQLITE_OK, the
** query is abandoned and the xQueryPhrase function returns immediately.
** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK.
@@ -12752,6 +13069,39 @@ struct Fts5PhraseIter {
**
** xPhraseNextColumn()
** See xPhraseFirstColumn above.
**
** xQueryToken(pFts5, iPhrase, iToken, ppToken, pnToken)
** This is used to access token iToken of phrase iPhrase of the current
** query. Before returning, output parameter *ppToken is set to point
** to a buffer containing the requested token, and *pnToken to the
** size of this buffer in bytes.
**
** If iPhrase or iToken are less than zero, or if iPhrase is greater than
** or equal to the number of phrases in the query as reported by
** xPhraseCount(), or if iToken is equal to or greater than the number of
** tokens in the phrase, SQLITE_RANGE is returned and *ppToken and *pnToken
are both zeroed.
**
** The output text is not a copy of the query text that specified the
** token. It is the output of the tokenizer module. For tokendata=1
** tables, this includes any embedded 0x00 and trailing data.
**
** xInstToken(pFts5, iIdx, iToken, ppToken, pnToken)
** This is used to access token iToken of phrase hit iIdx within the
** current row. If iIdx is less than zero or greater than or equal to the
** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise,
** output variable (*ppToken) is set to point to a buffer containing the
** matching document token, and (*pnToken) to the size of that buffer in
** bytes. This API is not available if the specified token matches a
** prefix query term. In that case both output variables are always set
** to 0.
**
** The output text is not a copy of the document text that was tokenized.
** It is the output of the tokenizer module. For tokendata=1 tables, this
** includes any embedded 0x00 and trailing data.
**
** This API can be quite slow if used with an FTS5 table created with the
** "detail=none" or "detail=column" option.
*/
struct Fts5ExtensionApi {
int iVersion; /* Currently always set to 3 */
@@ -12789,6 +13139,13 @@ struct Fts5ExtensionApi {
int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*);
void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol);
/* Below this point are iVersion>=3 only */
int (*xQueryToken)(Fts5Context*,
int iPhrase, int iToken,
const char **ppToken, int *pnToken
);
int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*);
};
/*
@@ -12983,8 +13340,8 @@ struct Fts5ExtensionApi {
** as separate queries of the FTS index are required for each synonym.
**
** When using methods (2) or (3), it is important that the tokenizer only
** provide synonyms when tokenizing document text (method (2)) or query
** text (method (3)), not both. Doing so will not cause any errors, but is
** provide synonyms when tokenizing document text (method (3)) or query
** text (method (2)), not both. Doing so will not cause any errors, but is
** inefficient.
*/
typedef struct Fts5Tokenizer Fts5Tokenizer;
@@ -13032,7 +13389,7 @@ struct fts5_api {
int (*xCreateTokenizer)(
fts5_api *pApi,
const char *zName,
void *pContext,
void *pUserData,
fts5_tokenizer *pTokenizer,
void (*xDestroy)(void*)
);
@@ -13041,7 +13398,7 @@ struct fts5_api {
int (*xFindTokenizer)(
fts5_api *pApi,
const char *zName,
void **ppContext,
void **ppUserData,
fts5_tokenizer *pTokenizer
);
@@ -13049,7 +13406,7 @@ struct fts5_api {
int (*xCreateFunction)(
fts5_api *pApi,
const char *zName,
void *pContext,
void *pUserData,
fts5_extension_function xFunction,
void (*xDestroy)(void*)
);
+3
View File
@@ -209,6 +209,9 @@ SplitView.prototype = {
this._nav.appendChild(aSummary);
aSummary.addEventListener("click", (aEvent) => {
if (aEvent.button != 0) {
return;
}
aEvent.stopPropagation();
this.activeSummary = aSummary;
}, false);
@@ -97,6 +97,9 @@ AutocompletePopup.prototype = {
},
onClick: function (e) {
if (e.button != 0) {
return;
}
let item = e.target.closest(".autocomplete-item");
if (item && typeof item.dataset.index !== "undefined") {
this.selectedIndex = parseInt(item.dataset.index, 10);
@@ -240,6 +240,9 @@ Spectrum.prototype = {
},
onElementClick: function (e) {
if (e.button != 0) {
return;
}
e.stopPropagation();
},
@@ -1480,6 +1480,9 @@ Column.prototype = {
* for sorting.
*/
onClick: function (event) {
if (event.button != 0) {
return;
}
let target = event.originalTarget;
if (target.nodeType !== target.ELEMENT_NODE || target == this.column) {
@@ -174,7 +174,10 @@ StyleEditorUI.prototype = {
this._view = new SplitView(viewRoot);
wire(this._view.rootElement, ".style-editor-newButton", () =>{
wire(this._view.rootElement, ".style-editor-newButton", (e) =>{
if (e.button != 0) {
return;
}
this._debuggee.addStyleSheet(null);
});
+1 -1
View File
@@ -340,7 +340,7 @@ DOMIntersectionObserver::Update(nsIDocument* aDocument, DOMHighResTimeStamp time
nsMargin rootMargin;
NS_FOR_CSS_SIDES(side) {
nscoord basis = side == NS_SIDE_TOP || side == NS_SIDE_BOTTOM ?
nscoord basis = side == eSideTop || side == eSideBottom ?
rootRect.height : rootRect.width;
nsCSSValue value = mRootMargin.*nsCSSRect::sides[side];
nsStyleCoord coord;
+2 -7
View File
@@ -129,17 +129,12 @@ DOMMatrixReadOnly::SetDataFromMatrix2DInit(const DOMMatrix2DInit& aMatrixInit) {
}
void
DOMMatrixReadOnly::SetDataFromMatrixInit(DOMMatrixInit& aMatrixInit)
DOMMatrixReadOnly::SetDataFromMatrixInit(const DOMMatrixInit& aMatrixInit)
{
const bool is2D = aMatrixInit.mIs2D.Value();
MOZ_ASSERT(is2D == Is2D());
if (is2D) {
mMatrix2D->_11 = aMatrixInit.mM11.Value();
mMatrix2D->_12 = aMatrixInit.mM12.Value();
mMatrix2D->_21 = aMatrixInit.mM21.Value();
mMatrix2D->_22 = aMatrixInit.mM22.Value();
mMatrix2D->_31 = aMatrixInit.mM41.Value();
mMatrix2D->_32 = aMatrixInit.mM42.Value();
SetDataFromMatrix2DInit(aMatrixInit);
} else {
mMatrix3D->_11 = aMatrixInit.mM11.Value();
mMatrix3D->_12 = aMatrixInit.mM12.Value();
+10 -1
View File
@@ -52,6 +52,11 @@ public:
mMatrix3D = new gfx::Matrix4x4(aMatrix);
}
DOMMatrixReadOnly(nsISupports* aParent, const gfx::Matrix& aMatrix)
: mParent(aParent) {
mMatrix2D = new gfx::Matrix(aMatrix);
}
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(DOMMatrixReadOnly)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(DOMMatrixReadOnly)
@@ -234,7 +239,7 @@ protected:
* The init dictionary's dimension must match the matrix one.
*/
void SetDataFromMatrix2DInit(const DOMMatrix2DInit& aMatrixInit);
void SetDataFromMatrixInit(DOMMatrixInit& aMatrixInit);
void SetDataFromMatrixInit(const DOMMatrixInit& aMatrixInit);
DOMMatrixReadOnly* SetMatrixValue(const nsAString& aTransformList, ErrorResult& aRv);
void Ensure3DMatrix();
@@ -268,6 +273,10 @@ public:
: DOMMatrixReadOnly(aParent, aMatrix)
{}
DOMMatrix(nsISupports* aParent, const gfx::Matrix& aMatrix)
: DOMMatrixReadOnly(aParent, aMatrix)
{}
static already_AddRefed<DOMMatrix>
FromMatrix(nsISupports* aParent, const DOMMatrixInit& aMatrixInit, ErrorResult& aRv);
static already_AddRefed<DOMMatrix>
+8
View File
@@ -1519,5 +1519,13 @@ Navigator::Clipboard()
return mClipboard;
}
/* static */
bool
Navigator::Webdriver()
{
// We don't support Selenium or marionette, so this is always false.
return false;
}
} // namespace dom
} // namespace mozilla
+2
View File
@@ -220,6 +220,8 @@ public:
dom::Clipboard* Clipboard();
static bool Webdriver();
void GetLanguages(nsTArray<nsString>& aLanguages);
StorageManager* Storage();
+9 -11
View File
@@ -32,16 +32,14 @@ PostMessageEvent::PostMessageEvent(nsGlobalWindow* aSource,
const nsAString& aCallerOrigin,
nsGlobalWindow* aTargetWindow,
nsIPrincipal* aProvidedPrincipal,
nsIDocument* aSourceDocument,
bool aTrustedCaller)
: StructuredCloneHolder(CloningSupported, TransferringSupported,
StructuredCloneScope::SameProcessSameThread),
mSource(aSource),
mCallerOrigin(aCallerOrigin),
mTargetWindow(aTargetWindow),
mProvidedPrincipal(aProvidedPrincipal),
mSourceDocument(aSourceDocument),
mTrustedCaller(aTrustedCaller)
nsIDocument* aSourceDocument)
: StructuredCloneHolder(CloningSupported, TransferringSupported,
StructuredCloneScope::SameProcessSameThread)
, mSource(aSource)
, mCallerOrigin(aCallerOrigin)
, mTargetWindow(aTargetWindow)
, mProvidedPrincipal(aProvidedPrincipal)
, mSourceDocument(aSourceDocument)
{
MOZ_COUNT_CTOR(PostMessageEvent);
}
@@ -169,7 +167,7 @@ PostMessageEvent::Run()
if (shell)
presContext = shell->GetPresContext();
event->SetTrusted(mTrustedCaller);
event->SetTrusted(true);
WidgetEvent* internalEvent = event->WidgetEventPtr();
nsEventStatus status = nsEventStatus_eIgnore;
+1 -3
View File
@@ -33,8 +33,7 @@ public:
const nsAString& aCallerOrigin,
nsGlobalWindow* aTargetWindow,
nsIPrincipal* aProvidedPrincipal,
nsIDocument* aSourceDocument,
bool aTrustedCaller);
nsIDocument* aSourceDocument);
private:
~PostMessageEvent();
@@ -44,7 +43,6 @@ private:
RefPtr<nsGlobalWindow> mTargetWindow;
nsCOMPtr<nsIPrincipal> mProvidedPrincipal;
nsCOMPtr<nsIDocument> mSourceDocument;
bool mTrustedCaller;
};
} // namespace dom
+6 -8
View File
@@ -1598,12 +1598,12 @@ nsAttrValue::ParsePositiveIntValue(const nsAString& aString)
return true;
}
void
bool
nsAttrValue::SetColorValue(nscolor aColor, const nsAString& aString)
{
nsStringBuffer* buf = GetStringBuffer(aString).take();
if (!buf) {
return;
return false;
}
MiscContainer* cont = EnsureEmptyMiscContainer();
@@ -1612,6 +1612,7 @@ nsAttrValue::SetColorValue(nscolor aColor, const nsAString& aString)
// Save the literal string we were passed for round-tripping.
cont->mStringBits = reinterpret_cast<uintptr_t>(buf) | eStringBase;
return true;
}
bool
@@ -1635,13 +1636,11 @@ nsAttrValue::ParseColor(const nsAString& aString)
if (colorStr.First() == '#') {
nsDependentString withoutHash(colorStr.get() + 1, colorStr.Length() - 1);
if (NS_HexToRGBA(withoutHash, nsHexColorType::NoAlpha, &color)) {
SetColorValue(color, aString);
return true;
return SetColorValue(color, aString);
}
} else {
if (NS_ColorNameToRGB(colorStr, &color)) {
SetColorValue(color, aString);
return true;
return SetColorValue(color, aString);
}
}
@@ -1652,8 +1651,7 @@ nsAttrValue::ParseColor(const nsAString& aString)
// Use NS_LooseHexToRGB as a fallback if nothing above worked.
if (NS_LooseHexToRGB(colorStr, &color)) {
SetColorValue(color, aString);
return true;
return SetColorValue(color, aString);
}
return false;
+1 -1
View File
@@ -463,7 +463,7 @@ private:
inline void SetPtrValueAndType(void* aValue, ValueBaseType aType);
void SetIntValueAndType(int32_t aValue, ValueType aType,
const nsAString* aStringValue);
void SetColorValue(nscolor aColor, const nsAString& aString);
bool SetColorValue(nscolor aColor, const nsAString& aString);
void SetMiscAtomOrString(const nsAString* aValue);
void ResetMiscAtomOrString();
void SetSVGType(ValueType aType, const void* aValue,
+23 -5
View File
@@ -472,6 +472,7 @@ nsContentSink::ProcessLinkHeader(const nsAString& aLinkData)
nsAutoString media;
nsAutoString anchor;
nsAutoString crossOrigin;
nsAutoString referrerPolicy;
nsAutoString destination;
crossOrigin.SetIsVoid(true);
@@ -660,6 +661,15 @@ nsContentSink::ProcessLinkHeader(const nsAString& aLinkData)
destination = value;
destination.StripWhitespace();
}
} else if (attr.LowerCaseEqualsLiteral("referrerpolicy")) {
// https://html.spec.whatwg.org/multipage/urls-and-fetching.html#referrer-policy-attribute
// The spec says that the referrer policy attribute is an enumerated attribute,
// case insensitive and includes the empty string.
// We will parse the value with AttributeReferrerPolicyFromString
// later, which will handle parsing it as an enumerated attribute.
if (referrerPolicy.IsEmpty()) {
referrerPolicy = value;
}
}
}
}
@@ -673,7 +683,7 @@ nsContentSink::ProcessLinkHeader(const nsAString& aLinkData)
rv = ProcessLink(anchor, href, rel,
// prefer RFC 5987 variant over non-I18zed version
titleStar.IsEmpty() ? title : titleStar,
type, media, crossOrigin, destination);
type, media, crossOrigin, referrerPolicy, destination);
}
href.Truncate();
@@ -682,6 +692,7 @@ nsContentSink::ProcessLinkHeader(const nsAString& aLinkData)
type.Truncate();
media.Truncate();
anchor.Truncate();
referrerPolicy.Truncate();
crossOrigin.SetIsVoid(true);
destination.Truncate();
@@ -696,7 +707,7 @@ nsContentSink::ProcessLinkHeader(const nsAString& aLinkData)
rv = ProcessLink(anchor, href, rel,
// prefer RFC 5987 variant over non-I18zed version
titleStar.IsEmpty() ? title : titleStar,
type, media, crossOrigin, destination);
type, media, crossOrigin, referrerPolicy, destination);
}
return rv;
@@ -708,6 +719,7 @@ nsContentSink::ProcessLink(const nsSubstring& aAnchor, const nsSubstring& aHref,
const nsSubstring& aRel, const nsSubstring& aTitle,
const nsSubstring& aType, const nsSubstring& aMedia,
const nsSubstring& aCrossOrigin,
const nsAString& aReferrerPolicy,
const nsSubstring& aDestination)
{
uint32_t linkTypes =
@@ -749,7 +761,7 @@ nsContentSink::ProcessLink(const nsSubstring& aAnchor, const nsSubstring& aHref,
bool isAlternate = linkTypes & nsStyleLinkElement::eALTERNATE;
return ProcessStyleLink(nullptr, aHref, isAlternate, aTitle, aType,
aMedia);
aMedia, aReferrerPolicy);
}
nsresult
@@ -758,7 +770,8 @@ nsContentSink::ProcessStyleLink(nsIContent* aElement,
bool aAlternate,
const nsSubstring& aTitle,
const nsSubstring& aType,
const nsSubstring& aMedia)
const nsSubstring& aMedia,
const nsSubstring& aReferrerPolicy)
{
if (aAlternate && aTitle.IsEmpty()) {
// alternates must have title return without error, for now
@@ -797,13 +810,18 @@ nsContentSink::ProcessStyleLink(nsIContent* aElement,
("nsContentSink::ProcessStyleLink, integrity=%s",
NS_ConvertUTF16toUTF8(integrity).get()));
}
mozilla::net::ReferrerPolicy referrerPolicy =
mozilla::net::AttributeReferrerPolicyFromString(aReferrerPolicy);
if (referrerPolicy == net::RP_Unset) {
referrerPolicy = mDocument->GetReferrerPolicy();
}
// If this is a fragment parser, we don't want to observe.
// We don't support CORS for processing instructions
bool isAlternate;
bool isExplicitlyEnabled;
rv = mCSSLoader->LoadStyleLink(aElement, url, aTitle, aMedia, aAlternate,
CORS_NONE, mDocument->GetReferrerPolicy(),
CORS_NONE, referrerPolicy,
integrity, mRunsToCompletion ? nullptr : this,
&isAlternate, &isExplicitlyEnabled);
NS_ENSURE_SUCCESS(rv, rv);
+3 -1
View File
@@ -154,6 +154,7 @@ protected:
const nsSubstring& aHref, const nsSubstring& aRel,
const nsSubstring& aTitle, const nsSubstring& aType,
const nsSubstring& aMedia, const nsSubstring& aCrossOrigin,
const nsSubstring& aReferrerPolicy,
const nsSubstring& aDestination);
virtual nsresult ProcessStyleLink(nsIContent* aElement,
@@ -161,7 +162,8 @@ protected:
bool aAlternate,
const nsSubstring& aTitle,
const nsSubstring& aType,
const nsSubstring& aMedia);
const nsSubstring& aMedia,
const nsSubstring& aReferrerPolicy);
void PrefetchOrPreloadHref(const nsAString &aHref,
nsINode *aSource,
+2 -4
View File
@@ -8868,10 +8868,8 @@ nsContentUtils::SetFetchReferrerURIWithPolicy(nsIPrincipal* aPrincipal,
referrerURI = principalURI;
}
net::ReferrerPolicy referrerPolicy = aReferrerPolicy;
if (referrerPolicy == net::RP_Default) {
referrerPolicy = aDoc->GetReferrerPolicy();
}
net::ReferrerPolicy referrerPolicy = (aReferrerPolicy != net::RP_Unset) ?
aReferrerPolicy : net::RP_Default;
return aChannel->SetReferrerWithPolicy(referrerURI, referrerPolicy);
}
-16
View File
@@ -2802,20 +2802,9 @@ nsDocument::GetPrincipal()
return NodePrincipal();
}
extern bool sDisablePrefetchHTTPSPref;
void
nsDocument::SetPrincipal(nsIPrincipal *aNewPrincipal)
{
if (aNewPrincipal && mAllowDNSPrefetch && sDisablePrefetchHTTPSPref) {
nsCOMPtr<nsIURI> uri;
aNewPrincipal->GetURI(getter_AddRefs(uri));
bool isHTTPS;
if (!uri || NS_FAILED(uri->SchemeIs("https", &isHTTPS)) ||
isHTTPS) {
mAllowDNSPrefetch = false;
}
}
mNodeInfoManager->SetDocumentPrincipal(aNewPrincipal);
#ifdef DEBUG
@@ -7250,11 +7239,6 @@ nsDocument::GetEventTargetParent(EventChainPreVisitor& aVisitor)
aVisitor.mCanHandle = true;
// Middle/right click shouldn't dispatch click event, use auxclick to instead.
Element* docElement = GetRootElement();
if (docElement && docElement->IsXULElement()) {
// FIXME! This is a hack to make middle mouse paste working also in Editor.
// Bug 329119
aVisitor.mForceContentDispatch = true;
}
// Load events must not propagate to |window| object, see bug 335251.
if (aVisitor.mEvent->mMessage != eLoad) {
+1 -40
View File
@@ -2300,13 +2300,11 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindow)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
#ifdef DEBUG
void
nsGlobalWindow::RiskyUnlink()
{
NS_CYCLE_COLLECTION_INNERNAME.Unlink(this);
}
#endif
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsGlobalWindow)
if (tmp->mCachedXBLPrototypeHandlers) {
@@ -3542,12 +3540,6 @@ nsGlobalWindow::GetEventTargetParent(EventChainPreVisitor& aVisitor)
EventMessage msg = aVisitor.mEvent->mMessage;
aVisitor.mCanHandle = true;
// Middle/right click shouldn't dispatch click event, use auxclick to instead.
// Note: mDoc should always exist here, but check just in case someone yanked
// it out from under us.
if (mDoc && mDoc->IsXULDocument()) {
aVisitor.mForceContentDispatch = true; //FIXME! Bug 329119
}
if (msg == eResize && aVisitor.mEvent->IsTrusted()) {
// QIing to window so that we can keep the old behavior also in case
// a child window is handling resize.
@@ -8879,8 +8871,7 @@ nsGlobalWindow::PostMessageMozOuter(JSContext* aCx, JS::Handle<JS::Value> aMessa
providedPrincipal,
callerInnerWin
? callerInnerWin->GetDoc()
: nullptr,
nsContentUtils::IsCallerChrome());
: nullptr);
JS::Rooted<JS::Value> message(aCx, aMessage);
JS::Rooted<JS::Value> transfer(aCx, aTransfer);
@@ -14601,11 +14592,6 @@ already_AddRefed<Promise>
nsGlobalWindow::CreateImageBitmap(const ImageBitmapSource& aImage,
ErrorResult& aRv)
{
if (aImage.IsArrayBuffer() || aImage.IsArrayBufferView()) {
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
return nullptr;
}
return ImageBitmap::Create(this, aImage, Nothing(), aRv);
}
@@ -14614,34 +14600,9 @@ nsGlobalWindow::CreateImageBitmap(const ImageBitmapSource& aImage,
int32_t aSx, int32_t aSy, int32_t aSw, int32_t aSh,
ErrorResult& aRv)
{
if (aImage.IsArrayBuffer() || aImage.IsArrayBufferView()) {
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
return nullptr;
}
return ImageBitmap::Create(this, aImage, Some(gfx::IntRect(aSx, aSy, aSw, aSh)), aRv);
}
already_AddRefed<mozilla::dom::Promise>
nsGlobalWindow::CreateImageBitmap(const ImageBitmapSource& aImage,
int32_t aOffset, int32_t aLength,
ImageBitmapFormat aFormat,
const Sequence<ChannelPixelLayout>& aLayout,
ErrorResult& aRv)
{
if (!ImageBitmap::ExtensionsEnabled(nullptr, nullptr)) {
aRv.Throw(NS_ERROR_TYPE_ERR);
return nullptr;
}
if (aImage.IsArrayBuffer() || aImage.IsArrayBufferView()) {
return ImageBitmap::Create(this, aImage, aOffset, aLength, aFormat, aLayout,
aRv);
} else {
aRv.Throw(NS_ERROR_TYPE_ERR);
return nullptr;
}
}
// https://html.spec.whatwg.org/#structured-cloning
void
nsGlobalWindow::StructuredClone(JSContext* aCx,
-2
View File
@@ -597,11 +597,9 @@ public:
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsGlobalWindow,
nsIDOMEventTarget)
#ifdef DEBUG
// Call Unlink on this window. This may cause bad things to happen, so use
// with caution.
void RiskyUnlink();
#endif
virtual JSObject*
GetCachedXBLPrototypeHandler(nsXBLPrototypeHandler* aKey) override;
-1
View File
@@ -252,7 +252,6 @@ nsInProcessTabChildGlobal::GetOwnerContent()
nsresult
nsInProcessTabChildGlobal::GetEventTargetParent(EventChainPreVisitor& aVisitor)
{
aVisitor.mForceContentDispatch = true;
aVisitor.mCanHandle = true;
#ifdef DEBUG
+11 -10
View File
@@ -411,6 +411,16 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
bool doneLoading = false;
nsresult rv = NS_OK;
// Load the link's referrerpolicy attribute. If the link does not provide a
// referrerpolicy attribute, ignore this and use the document's referrer
// policy
net::ReferrerPolicy referrerPolicy = GetLinkReferrerPolicy();
if (referrerPolicy == net::RP_Unset) {
referrerPolicy = doc->GetReferrerPolicy();
}
if (isInline) {
nsAutoString text;
if (!nsContentUtils::GetNodeTextContent(thisContent, false, text, fallible)) {
@@ -429,7 +439,7 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
// Parse the style sheet.
rv = doc->CSSLoader()->
LoadInlineStyle(thisContent, text, mLineNumber, title, media,
LoadInlineStyle(thisContent, text, mLineNumber, title, media, referrerPolicy,
scopeElement, aObserver, &doneLoading, &isAlternate, &isExplicitlyEnabled);
} else {
nsAutoString integrity;
@@ -440,15 +450,6 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
NS_ConvertUTF16toUTF8(integrity).get()));
}
// if referrer attributes are enabled in preferences, load the link's referrer
// attribute. If the link does not provide a referrer attribute, ignore this
// and use the document's referrer policy
net::ReferrerPolicy referrerPolicy = GetLinkReferrerPolicy();
if (referrerPolicy == net::RP_Unset) {
referrerPolicy = doc->GetReferrerPolicy();
}
// XXXbz clone the URI here to work around content policies modifying URIs.
nsCOMPtr<nsIURI> clonedURI;
uri->Clone(getter_AddRefs(clonedURI));
-2
View File
@@ -829,7 +829,6 @@ nsWindowMemoryReporter::KillCheckTimer()
}
}
#ifdef DEBUG
/* static */ void
nsWindowMemoryReporter::UnlinkGhostWindows()
{
@@ -866,4 +865,3 @@ nsWindowMemoryReporter::UnlinkGhostWindows()
}
}
}
#endif
-2
View File
@@ -150,13 +150,11 @@ public:
static void Init();
#ifdef DEBUG
/**
* Unlink all known ghost windows, to enable investigating what caused them
* to become ghost windows in the first place.
*/
static void UnlinkGhostWindows();
#endif
static nsWindowMemoryReporter* Get();
void ObserveDOMWindowDetached(nsGlobalWindow* aWindow);
-1
View File
@@ -179,7 +179,6 @@ nsresult
nsWindowRoot::GetEventTargetParent(EventChainPreVisitor& aVisitor)
{
aVisitor.mCanHandle = true;
aVisitor.mForceContentDispatch = true; //FIXME! Bug 329119
// To keep mWindow alive
aVisitor.mItemData = static_cast<nsISupports *>(mWindow);
aVisitor.SetParentTarget(mParent, false);
+10 -4
View File
@@ -220,6 +220,16 @@ DOMInterfaces = {
'headerFile': 'nsCSSRules.h',
},
'CSSLayerBlockRule': {
'nativeType': 'mozilla::CSSLayerBlockRule',
'headerFile': 'nsCSSRules.h',
},
'CSSLayerStatementRule': {
'nativeType': 'mozilla::CSSLayerStatementRule',
'headerFile': 'nsCSSRules.h',
},
'CSSLexer': {
'wrapperCache': False
},
@@ -545,10 +555,6 @@ DOMInterfaces = {
'headerFile': 'xpcjsid.h',
},
'ImageBitmap': {
'implicitJSContext': [ 'mapDataInto' ],
},
'ImageCapture': {
'binaryNames': { 'videoStreamTrack': 'GetVideoStreamTrack' }
},
+10 -4
View File
@@ -4888,6 +4888,16 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
raise WebIDLError("StaticClassOverride can be applied to static"
" methods on JS-implemented classes only.",
[self.location])
if self.getExtendedAttribute("LenientFloat"):
assert len(self.signatures()) >= 1
found = False
for sig in self.signatures():
if any(arg.type.includesRestrictedFloat() for arg in sig[1]):
found = True
if not found:
raise WebIDLError("[LenientFloat] used on an operation with no "
"restricted float type arguments",
[self.location])
def overloadsForArgCount(self, argc):
return [overload for overload in self._overloads if
@@ -4966,10 +4976,6 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
if not sig[0].isVoid():
raise WebIDLError("[LenientFloat] used on a non-void method",
[attr.location, self.location])
if not any(arg.type.includesRestrictedFloat() for arg in sig[1]):
raise WebIDLError("[LenientFloat] used on an operation with no "
"restricted float type arguments",
[attr.location, self.location])
elif identifier == "Exposed":
convertExposedAttrToGlobalNameSet(attr, self._exposureGlobalNames)
elif (identifier == "CrossOriginCallable" or
+4 -1
View File
@@ -196,7 +196,10 @@ static_assert(int(ReferrerPolicy::_empty) == 0 &&
int(ReferrerPolicy::Origin) == 3 &&
int(ReferrerPolicy::Origin_when_cross_origin) == 4 &&
int(ReferrerPolicy::Unsafe_url) == 5 &&
int(ReferrerPolicy::EndGuard_) == 6,
int(ReferrerPolicy::Same_origin) == 6 &&
int(ReferrerPolicy::Strict_origin) == 7 &&
int(ReferrerPolicy::Strict_origin_when_cross_origin) == 8 &&
int(ReferrerPolicy::EndGuard_) == 9,
"ReferrerPolicy values are as expected");
static_assert(int(RequestMode::Same_origin) == 0 &&
int(RequestMode::No_cors) == 1 &&
+28
View File
@@ -2229,6 +2229,18 @@ CanvasRenderingContext2D::Transform(double aM11, double aM12, double aM21,
SetTransformInternal(newMatrix);
}
already_AddRefed<DOMMatrix>
CanvasRenderingContext2D::GetTransform(ErrorResult& aError) {
EnsureTarget();
if (!IsTargetValid()) {
aError.Throw(NS_ERROR_FAILURE);
return nullptr;
}
RefPtr<DOMMatrix> matrix =
new DOMMatrix(GetParentObject(), mTarget->GetTransform());
return matrix.forget();
}
void
CanvasRenderingContext2D::SetTransform(double aM11, double aM12,
double aM21, double aM22,
@@ -2244,6 +2256,22 @@ CanvasRenderingContext2D::SetTransform(double aM11, double aM12,
SetTransformInternal(Matrix(aM11, aM12, aM21, aM22, aDx, aDy));
}
void
CanvasRenderingContext2D::SetTransform(const DOMMatrix2DInit& aInit,
ErrorResult& aError) {
TransformWillUpdate();
if (!IsTargetValid()) {
aError.Throw(NS_ERROR_FAILURE);
return;
}
RefPtr<DOMMatrixReadOnly> matrix =
DOMMatrixReadOnly::FromMatrix(GetParentObject(), aInit, aError);
if (!aError.Failed()) {
SetTransformInternal(Matrix(*(matrix->GetInternal2D())));
}
}
void
CanvasRenderingContext2D::SetTransformInternal(const Matrix& aTransform)
{
+6
View File
@@ -57,6 +57,10 @@ class CanvasRenderingContext2DUserData;
class CanvasDrawObserver;
class CanvasShutdownObserver;
class DOMMatrix;
class DOMMatrixReadOnly;
struct DOMMatrix2DInit;
/**
** CanvasRenderingContext2D
**/
@@ -88,8 +92,10 @@ public:
void Translate(double aX, double aY, mozilla::ErrorResult& aError);
void Transform(double aM11, double aM12, double aM21, double aM22, double aDx,
double aDy, mozilla::ErrorResult& aError);
already_AddRefed<DOMMatrix> GetTransform(mozilla::ErrorResult& aError);
void SetTransform(double aM11, double aM12, double aM21, double aM22, double aDx,
double aDy, mozilla::ErrorResult& aError);
void SetTransform(const DOMMatrix2DInit& aInit, mozilla::ErrorResult& aError);
void ResetTransform(mozilla::ErrorResult& aError);
double GlobalAlpha()
+2 -613
View File
@@ -412,7 +412,6 @@ ImageBitmap::ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData,
, mDataWrapper(new ImageUtils(mData))
, mPictureRect(0, 0, aData->GetSize().width, aData->GetSize().height)
, mIsPremultipliedAlpha(aIsPremultipliedAlpha)
, mIsCroppingAreaOutSideOfSourceImage(false)
, mWriteOnly(aWriteOnly)
{
MOZ_ASSERT(aData, "aData is null in ImageBitmap constructor.");
@@ -442,23 +441,6 @@ ImageBitmap::SetPictureRect(const IntRect& aRect, ErrorResult& aRv)
mPictureRect = FixUpNegativeDimension(aRect, aRv);
}
void
ImageBitmap::SetIsCroppingAreaOutSideOfSourceImage(const IntSize& aSourceSize,
const Maybe<IntRect>& aCroppingRect)
{
// No cropping at all.
if (aCroppingRect.isNothing()) {
mIsCroppingAreaOutSideOfSourceImage = false;
return;
}
if (aCroppingRect->X() < 0 || aCroppingRect->Y() < 0 ||
aCroppingRect->Width() > aSourceSize.width ||
aCroppingRect->Height() > aSourceSize.height) {
mIsCroppingAreaOutSideOfSourceImage = true;
}
}
static already_AddRefed<SourceSurface>
ConvertColorFormatIfNeeded(RefPtr<SourceSurface> aSurface)
{
@@ -702,7 +684,6 @@ ImageBitmap::ToCloneData() const
UniquePtr<ImageBitmapCloneData> result(new ImageBitmapCloneData());
result->mPictureRect = mPictureRect;
result->mIsPremultipliedAlpha = mIsPremultipliedAlpha;
result->mIsCroppingAreaOutSideOfSourceImage = mIsCroppingAreaOutSideOfSourceImage;
RefPtr<SourceSurface> surface = mData->GetAsSourceSurface();
result->mSurface = surface->GetDataSurface();
MOZ_ASSERT(result->mSurface);
@@ -720,9 +701,6 @@ ImageBitmap::CreateFromCloneData(nsIGlobalObject* aGlobal,
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, aData->mWriteOnly,
aData->mIsPremultipliedAlpha);
ret->mIsCroppingAreaOutSideOfSourceImage =
aData->mIsCroppingAreaOutSideOfSourceImage;
ErrorResult rv;
ret->SetPictureRect(aData->mPictureRect, rv);
return ret.forget();
@@ -796,9 +774,6 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLImageElement& aImageEl
ret->SetPictureRect(aCropRect.ref(), aRv);
}
// Set mIsCroppingAreaOutSideOfSourceImage.
ret->SetIsCroppingAreaOutSideOfSourceImage(surface->GetSize(), aCropRect);
return ret.forget();
}
@@ -850,9 +825,6 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLVideoElement& aVideoEl
ret->SetPictureRect(aCropRect.ref(), aRv);
}
// Set mIsCroppingAreaOutSideOfSourceImage.
ret->SetIsCroppingAreaOutSideOfSourceImage(data->GetSize(), aCropRect);
return ret.forget();
}
@@ -918,9 +890,6 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLCanvasElement& aCanvas
ret->SetPictureRect(cropRect, aRv);
}
// Set mIsCroppingAreaOutSideOfSourceImage.
ret->SetIsCroppingAreaOutSideOfSourceImage(surface->GetSize(), aCropRect);
return ret.forget();
}
@@ -986,9 +955,6 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, ImageData& aImageData,
// The cropping information has been handled in the CreateImageFromRawData()
// function.
// Set mIsCroppingAreaOutSideOfSourceImage.
ret->SetIsCroppingAreaOutSideOfSourceImage(imageSize, aCropRect);
return ret.forget();
}
@@ -1026,9 +992,6 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, CanvasRenderingContext2D&
ret->SetPictureRect(aCropRect.ref(), aRv);
}
// Set mIsCroppingAreaOutSideOfSourceImage.
ret->SetIsCroppingAreaOutSideOfSourceImage(surface->GetSize(), aCropRect);
return ret.forget();
}
@@ -1052,14 +1015,6 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, ImageBitmap& aImageBitmap,
ret->SetPictureRect(aCropRect.ref(), aRv);
}
// Set mIsCroppingAreaOutSideOfSourceImage.
if (aImageBitmap.mIsCroppingAreaOutSideOfSourceImage == true) {
ret->mIsCroppingAreaOutSideOfSourceImage = true;
} else {
ret->SetIsCroppingAreaOutSideOfSourceImage(aImageBitmap.mPictureRect.Size(),
aCropRect);
}
return ret.forget();
}
@@ -1318,9 +1273,6 @@ private:
// Create ImageBitmap object.
RefPtr<ImageBitmap> imageBitmap = new ImageBitmap(mGlobalObject, data, false /* write-only */);
// Set mIsCroppingAreaOutSideOfSourceImage.
imageBitmap->SetIsCroppingAreaOutSideOfSourceImage(sourceSize, originalCropRect);
return imageBitmap.forget();
}
};
@@ -1414,9 +1366,6 @@ private:
// Create ImageBitmap object.
RefPtr<ImageBitmap> imageBitmap = new ImageBitmap(mGlobalObject, data, false /* write-only */);
// Set mIsCroppingAreaOutSideOfSourceImage.
imageBitmap->SetIsCroppingAreaOutSideOfSourceImage(sourceSize, originalCropRect);
return imageBitmap.forget();
}
@@ -1506,20 +1455,17 @@ ImageBitmap::ReadStructuredClone(JSContext* aCx,
uint32_t picRectWidth_;
uint32_t picRectHeight_;
uint32_t isPremultipliedAlpha_;
uint32_t isCroppingAreaOutSideOfSourceImage_;
uint32_t writeOnly;
uint32_t dummy;
if (!JS_ReadUint32Pair(aReader, &picRectX_, &picRectY_) ||
!JS_ReadUint32Pair(aReader, &picRectWidth_, &picRectHeight_) ||
!JS_ReadUint32Pair(aReader, &isPremultipliedAlpha_,
&isCroppingAreaOutSideOfSourceImage_) ||
&dummy) ||
!JS_ReadUint32Pair(aReader, &writeOnly, &dummy)) {
return nullptr;
}
MOZ_ASSERT(dummy == 0);
int32_t picRectX = BitwiseCast<int32_t>(picRectX_);
int32_t picRectY = BitwiseCast<int32_t>(picRectY_);
int32_t picRectWidth = BitwiseCast<int32_t>(picRectWidth_);
@@ -1540,9 +1486,6 @@ ImageBitmap::ReadStructuredClone(JSContext* aCx,
RefPtr<ImageBitmap> imageBitmap =
new ImageBitmap(aParent, img, !!writeOnly, isPremultipliedAlpha_);
imageBitmap->mIsCroppingAreaOutSideOfSourceImage =
isCroppingAreaOutSideOfSourceImage_;
ErrorResult error;
imageBitmap->SetPictureRect(IntRect(picRectX, picRectY,
picRectWidth, picRectHeight), error);
@@ -1572,7 +1515,6 @@ ImageBitmap::WriteStructuredClone(JSStructuredCloneWriter* aWriter,
const uint32_t picRectWidth = BitwiseCast<uint32_t>(aImageBitmap->mPictureRect.width);
const uint32_t picRectHeight = BitwiseCast<uint32_t>(aImageBitmap->mPictureRect.height);
const uint32_t isPremultipliedAlpha = aImageBitmap->mIsPremultipliedAlpha ? 1 : 0;
const uint32_t isCroppingAreaOutSideOfSourceImage = aImageBitmap->mIsCroppingAreaOutSideOfSourceImage ? 1 : 0;
const uint32_t isWriteOnly = aImageBitmap->mWriteOnly ? 1 : 0;
// Indexing the cloned surfaces and send the index to the receiver.
@@ -1581,8 +1523,7 @@ ImageBitmap::WriteStructuredClone(JSStructuredCloneWriter* aWriter,
if (NS_WARN_IF(!JS_WriteUint32Pair(aWriter, SCTAG_DOM_IMAGEBITMAP, index)) ||
NS_WARN_IF(!JS_WriteUint32Pair(aWriter, picRectX, picRectY)) ||
NS_WARN_IF(!JS_WriteUint32Pair(aWriter, picRectWidth, picRectHeight)) ||
NS_WARN_IF(!JS_WriteUint32Pair(aWriter, isPremultipliedAlpha,
isCroppingAreaOutSideOfSourceImage)) ||
NS_WARN_IF(!JS_WriteUint32Pair(aWriter, isPremultipliedAlpha, 0)) ||
NS_WARN_IF(!JS_WriteUint32Pair(aWriter, isWriteOnly, 0))) {
return false;
}
@@ -1608,557 +1549,5 @@ ImageBitmap::WriteStructuredClone(JSStructuredCloneWriter* aWriter,
return true;
}
/*static*/ bool
ImageBitmap::ExtensionsEnabled(JSContext* aCx, JSObject*)
{
if (NS_IsMainThread()) {
return Preferences::GetBool("canvas.imagebitmap_extensions.enabled");
} else {
WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(aCx);
MOZ_ASSERT(workerPrivate);
return workerPrivate->ImageBitmapExtensionsEnabled();
}
}
// ImageBitmap extensions.
ImageBitmapFormat
ImageBitmap::FindOptimalFormat(const Optional<Sequence<ImageBitmapFormat>>& aPossibleFormats,
ErrorResult& aRv)
{
MOZ_ASSERT(mDataWrapper, "No ImageBitmapFormatUtils functionalities.");
ImageBitmapFormat platformFormat = mDataWrapper->GetFormat();
if (!aPossibleFormats.WasPassed() ||
aPossibleFormats.Value().Contains(platformFormat)) {
return platformFormat;
} else {
// If no matching is found, FindBestMatchingFromat() returns
// ImageBitmapFormat::EndGuard_ and we throw an exception.
ImageBitmapFormat optimalFormat =
FindBestMatchingFromat(platformFormat, aPossibleFormats.Value());
if (optimalFormat == ImageBitmapFormat::EndGuard_) {
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
}
return optimalFormat;
}
}
int32_t
ImageBitmap::MappedDataLength(ImageBitmapFormat aFormat, ErrorResult& aRv)
{
MOZ_ASSERT(mDataWrapper, "No ImageBitmapFormatUtils functionalities.");
if (aFormat == mDataWrapper->GetFormat()) {
return mDataWrapper->GetBufferLength();
} else {
return CalculateImageBufferSize(aFormat, Width(), Height());
}
}
template<typename T>
class MapDataIntoBufferSource
{
protected:
MapDataIntoBufferSource(JSContext* aCx,
Promise *aPromise,
ImageBitmap *aImageBitmap,
const T& aBuffer,
int32_t aOffset,
ImageBitmapFormat aFormat)
: mPromise(aPromise)
, mImageBitmap(aImageBitmap)
, mBuffer(aCx, aBuffer.Obj())
, mOffset(aOffset)
, mFormat(aFormat)
{
MOZ_ASSERT(mPromise);
MOZ_ASSERT(JS_IsArrayBufferObject(mBuffer) ||
JS_IsArrayBufferViewObject(mBuffer));
}
virtual ~MapDataIntoBufferSource() = default;
void DoMapDataIntoBufferSource()
{
ErrorResult error;
// Prepare destination buffer.
uint8_t* bufferData = nullptr;
uint32_t bufferLength = 0;
bool isSharedMemory = false;
if (JS_IsArrayBufferObject(mBuffer)) {
js::GetArrayBufferLengthAndData(mBuffer, &bufferLength, &isSharedMemory, &bufferData);
} else if (JS_IsArrayBufferViewObject(mBuffer)) {
js::GetArrayBufferViewLengthAndData(mBuffer, &bufferLength, &isSharedMemory, &bufferData);
} else {
error.Throw(NS_ERROR_NOT_IMPLEMENTED);
mPromise->MaybeReject(error);
return;
}
if (NS_WARN_IF(!bufferData) || NS_WARN_IF(!bufferLength)) {
error.Throw(NS_ERROR_NOT_AVAILABLE);
mPromise->MaybeReject(error);
return;
}
// Check length.
const int32_t neededBufferLength =
mImageBitmap->MappedDataLength(mFormat, error);
if (((int32_t)bufferLength - mOffset) < neededBufferLength) {
error.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
mPromise->MaybeReject(error);
return;
}
// Call ImageBitmapFormatUtils.
UniquePtr<ImagePixelLayout> layout =
mImageBitmap->mDataWrapper->MapDataInto(bufferData,
mOffset,
bufferLength,
mFormat,
error);
if (NS_WARN_IF(!layout)) {
mPromise->MaybeReject(error);
return;
}
mPromise->MaybeResolve(*layout);
}
RefPtr<Promise> mPromise;
RefPtr<ImageBitmap> mImageBitmap;
JS::PersistentRooted<JSObject*> mBuffer;
int32_t mOffset;
ImageBitmapFormat mFormat;
};
template<typename T>
class MapDataIntoBufferSourceTask final : public Runnable,
public MapDataIntoBufferSource<T>
{
public:
MapDataIntoBufferSourceTask(JSContext* aCx,
Promise *aPromise,
ImageBitmap *aImageBitmap,
const T& aBuffer,
int32_t aOffset,
ImageBitmapFormat aFormat)
: MapDataIntoBufferSource<T>(aCx, aPromise, aImageBitmap, aBuffer, aOffset, aFormat)
{
}
virtual ~MapDataIntoBufferSourceTask() = default;
NS_IMETHOD Run() override
{
MapDataIntoBufferSource<T>::DoMapDataIntoBufferSource();
return NS_OK;
}
};
template<typename T>
class MapDataIntoBufferSourceWorkerTask final : public WorkerSameThreadRunnable,
public MapDataIntoBufferSource<T>
{
public:
MapDataIntoBufferSourceWorkerTask(JSContext* aCx,
Promise *aPromise,
ImageBitmap *aImageBitmap,
const T& aBuffer,
int32_t aOffset,
ImageBitmapFormat aFormat)
: WorkerSameThreadRunnable(GetCurrentThreadWorkerPrivate()),
MapDataIntoBufferSource<T>(aCx, aPromise, aImageBitmap, aBuffer, aOffset, aFormat)
{
}
virtual ~MapDataIntoBufferSourceWorkerTask() = default;
bool WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
{
MapDataIntoBufferSource<T>::DoMapDataIntoBufferSource();
return true;
}
};
void AsyncMapDataIntoBufferSource(JSContext* aCx,
Promise *aPromise,
ImageBitmap *aImageBitmap,
const ArrayBufferViewOrArrayBuffer& aBuffer,
int32_t aOffset,
ImageBitmapFormat aFormat)
{
MOZ_ASSERT(aCx);
MOZ_ASSERT(aPromise);
MOZ_ASSERT(aImageBitmap);
if (NS_IsMainThread()) {
nsCOMPtr<nsIRunnable> task;
if (aBuffer.IsArrayBuffer()) {
const ArrayBuffer& buffer = aBuffer.GetAsArrayBuffer();
task = new MapDataIntoBufferSourceTask<ArrayBuffer>(aCx, aPromise, aImageBitmap, buffer, aOffset, aFormat);
} else if (aBuffer.IsArrayBufferView()) {
const ArrayBufferView& bufferView = aBuffer.GetAsArrayBufferView();
task = new MapDataIntoBufferSourceTask<ArrayBufferView>(aCx, aPromise, aImageBitmap, bufferView, aOffset, aFormat);
}
NS_DispatchToCurrentThread(task); // Actually, to the main-thread.
} else {
RefPtr<WorkerSameThreadRunnable> task;
if (aBuffer.IsArrayBuffer()) {
const ArrayBuffer& buffer = aBuffer.GetAsArrayBuffer();
task = new MapDataIntoBufferSourceWorkerTask<ArrayBuffer>(aCx, aPromise, aImageBitmap, buffer, aOffset, aFormat);
} else if (aBuffer.IsArrayBufferView()) {
const ArrayBufferView& bufferView = aBuffer.GetAsArrayBufferView();
task = new MapDataIntoBufferSourceWorkerTask<ArrayBufferView>(aCx, aPromise, aImageBitmap, bufferView, aOffset, aFormat);
}
task->Dispatch(); // Actually, to the current worker-thread.
}
}
already_AddRefed<Promise>
ImageBitmap::MapDataInto(JSContext* aCx,
ImageBitmapFormat aFormat,
const ArrayBufferViewOrArrayBuffer& aBuffer,
int32_t aOffset, ErrorResult& aRv)
{
MOZ_ASSERT(mDataWrapper, "No ImageBitmapFormatUtils functionalities.");
MOZ_ASSERT(aCx, "No JSContext while calling ImageBitmap::MapDataInto().");
RefPtr<Promise> promise = Promise::Create(mParent, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
// Check for cases that should throws.
// Case 1:
// If image bitmap was cropped to the source rectangle so that it contains any
// transparent black pixels (cropping area is outside of the source image),
// then reject promise with IndexSizeError and abort these steps.
if (mIsCroppingAreaOutSideOfSourceImage) {
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return promise.forget();
}
// Case 2:
// If the image bitmap is going to be accessed in YUV422/YUV422 series with a
// cropping area starts at an odd x or y coordinate.
if (aFormat == ImageBitmapFormat::YUV422P ||
aFormat == ImageBitmapFormat::YUV420P ||
aFormat == ImageBitmapFormat::YUV420SP_NV12 ||
aFormat == ImageBitmapFormat::YUV420SP_NV21) {
if ((mPictureRect.x & 1) || (mPictureRect.y & 1)) {
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return promise.forget();
}
}
AsyncMapDataIntoBufferSource(aCx, promise, this, aBuffer, aOffset, aFormat);
return promise.forget();
}
// ImageBitmapFactories extensions.
static SurfaceFormat
ImageFormatToSurfaceFromat(mozilla::dom::ImageBitmapFormat aFormat)
{
switch(aFormat) {
case ImageBitmapFormat::RGBA32:
return SurfaceFormat::R8G8B8A8;
case ImageBitmapFormat::BGRA32:
return SurfaceFormat::B8G8R8A8;
case ImageBitmapFormat::RGB24:
return SurfaceFormat::R8G8B8;
case ImageBitmapFormat::BGR24:
return SurfaceFormat::B8G8R8;
case ImageBitmapFormat::GRAY8:
return SurfaceFormat::A8;
case ImageBitmapFormat::HSV:
return SurfaceFormat::HSV;
case ImageBitmapFormat::Lab:
return SurfaceFormat::Lab;
case ImageBitmapFormat::DEPTH:
return SurfaceFormat::Depth;
default:
return SurfaceFormat::UNKNOWN;
}
}
static already_AddRefed<layers::Image>
CreateImageFromBufferSourceRawData(const uint8_t*aBufferData,
uint32_t aBufferLength,
mozilla::dom::ImageBitmapFormat aFormat,
const Sequence<ChannelPixelLayout>& aLayout)
{
MOZ_ASSERT(aBufferData);
MOZ_ASSERT(aBufferLength > 0);
switch(aFormat) {
case ImageBitmapFormat::RGBA32:
case ImageBitmapFormat::BGRA32:
case ImageBitmapFormat::RGB24:
case ImageBitmapFormat::BGR24:
case ImageBitmapFormat::GRAY8:
case ImageBitmapFormat::HSV:
case ImageBitmapFormat::Lab:
case ImageBitmapFormat::DEPTH:
{
const nsTArray<ChannelPixelLayout>& channels = aLayout;
MOZ_ASSERT(channels.Length() != 0, "Empty Channels.");
const SurfaceFormat srcFormat = ImageFormatToSurfaceFromat(aFormat);
const uint32_t srcStride = channels[0].mStride;
const IntSize srcSize(channels[0].mWidth, channels[0].mHeight);
RefPtr<DataSourceSurface> dstDataSurface =
Factory::CreateDataSourceSurfaceWithStride(srcSize, srcFormat, srcStride);
if (NS_WARN_IF(!dstDataSurface)) {
return nullptr;
}
// Copy the raw data into the newly created DataSourceSurface.
DataSourceSurface::ScopedMap dstMap(dstDataSurface, DataSourceSurface::WRITE);
if (NS_WARN_IF(!dstMap.IsMapped())) {
return nullptr;
}
const uint8_t* srcBufferPtr = aBufferData;
uint8_t* dstBufferPtr = dstMap.GetData();
for (int i = 0; i < srcSize.height; ++i) {
memcpy(dstBufferPtr, srcBufferPtr, srcStride);
srcBufferPtr += srcStride;
dstBufferPtr += dstMap.GetStride();
}
// Create an Image from the BGRA SourceSurface.
RefPtr<SourceSurface> surface = dstDataSurface;
RefPtr<layers::Image> image = CreateImageFromSurface(surface);
if (NS_WARN_IF(!image)) {
return nullptr;
}
return image.forget();
}
case ImageBitmapFormat::YUV444P:
case ImageBitmapFormat::YUV422P:
case ImageBitmapFormat::YUV420P:
case ImageBitmapFormat::YUV420SP_NV12:
case ImageBitmapFormat::YUV420SP_NV21:
{
// Prepare the PlanarYCbCrData.
const ChannelPixelLayout& yLayout = aLayout[0];
const ChannelPixelLayout& uLayout = aFormat != ImageBitmapFormat::YUV420SP_NV21 ? aLayout[1] : aLayout[2];
const ChannelPixelLayout& vLayout = aFormat != ImageBitmapFormat::YUV420SP_NV21 ? aLayout[2] : aLayout[1];
layers::PlanarYCbCrData data;
// Luminance buffer
data.mYChannel = const_cast<uint8_t*>(aBufferData + yLayout.mOffset);
data.mYStride = yLayout.mStride;
data.mYSize = gfx::IntSize(yLayout.mWidth, yLayout.mHeight);
data.mYSkip = yLayout.mSkip;
// Chroma buffers
data.mCbChannel = const_cast<uint8_t*>(aBufferData + uLayout.mOffset);
data.mCrChannel = const_cast<uint8_t*>(aBufferData + vLayout.mOffset);
data.mCbCrStride = uLayout.mStride;
data.mCbCrSize = gfx::IntSize(uLayout.mWidth, uLayout.mHeight);
data.mCbSkip = uLayout.mSkip;
data.mCrSkip = vLayout.mSkip;
// Picture rectangle.
// We set the picture rectangle to exactly the size of the source image to
// keep the full original data.
data.mPicX = 0;
data.mPicY = 0;
data.mPicSize = data.mYSize;
// Create a layers::Image and set data.
if (aFormat == ImageBitmapFormat::YUV444P ||
aFormat == ImageBitmapFormat::YUV422P ||
aFormat == ImageBitmapFormat::YUV420P) {
RefPtr<layers::PlanarYCbCrImage> image =
new layers::RecyclingPlanarYCbCrImage(new layers::BufferRecycleBin());
if (NS_WARN_IF(!image)) {
return nullptr;
}
// Set Data.
if (NS_WARN_IF(!image->CopyData(data))) {
return nullptr;
}
return image.forget();
} else {
RefPtr<layers::NVImage>image = new layers::NVImage();
if (NS_WARN_IF(!image)) {
return nullptr;
}
// Set Data.
if (NS_WARN_IF(!image->SetData(data))) {
return nullptr;
}
return image.forget();
}
}
default:
return nullptr;
}
}
/*
* This is a synchronous task.
* This class is used to create a layers::CairoImage from raw data in the main
* thread. While creating an ImageBitmap from an BufferSource, we need to create
* a SouceSurface from the BufferSource raw data and then set the SourceSurface
* into a layers::CairoImage. However, the layers::CairoImage asserts the
* setting operation in the main thread, so if we are going to create an
* ImageBitmap from an BufferSource off the main thread, we post an event to the
* main thread to create a layers::CairoImage from an BufferSource raw data.
*
* TODO: Once the layers::CairoImage is constructible off the main thread, which
* means the SouceSurface could be released anywhere, we do not need this
* task anymore.
*/
class CreateImageFromBufferSourceRawDataInMainThreadSyncTask final :
public WorkerMainThreadRunnable
{
public:
CreateImageFromBufferSourceRawDataInMainThreadSyncTask(const uint8_t* aBuffer,
uint32_t aBufferLength,
mozilla::dom::ImageBitmapFormat aFormat,
const Sequence<ChannelPixelLayout>& aLayout,
/*output*/ layers::Image** aImage)
: WorkerMainThreadRunnable(GetCurrentThreadWorkerPrivate(),
NS_LITERAL_CSTRING("ImageBitmap-extensions :: Create Image from BufferSource Raw Data"))
, mImage(aImage)
, mBuffer(aBuffer)
, mBufferLength(aBufferLength)
, mFormat(aFormat)
, mLayout(aLayout)
{
MOZ_ASSERT(!(*aImage), "Don't pass an existing Image into CreateImageFromBufferSourceRawDataInMainThreadSyncTask.");
}
bool MainThreadRun() override
{
RefPtr<layers::Image> image =
CreateImageFromBufferSourceRawData(mBuffer, mBufferLength, mFormat, mLayout);
if (NS_WARN_IF(!image)) {
return true;
}
image.forget(mImage);
return true;
}
private:
layers::Image** mImage;
const uint8_t* mBuffer;
uint32_t mBufferLength;
mozilla::dom::ImageBitmapFormat mFormat;
const Sequence<ChannelPixelLayout>& mLayout;
};
/*static*/ already_AddRefed<Promise>
ImageBitmap::Create(nsIGlobalObject* aGlobal,
const ImageBitmapSource& aBuffer,
int32_t aOffset, int32_t aLength,
mozilla::dom::ImageBitmapFormat aFormat,
const Sequence<ChannelPixelLayout>& aLayout,
ErrorResult& aRv)
{
MOZ_ASSERT(aGlobal);
RefPtr<Promise> promise = Promise::Create(aGlobal, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
uint8_t* bufferData = nullptr;
uint32_t bufferLength = 0;
if (aBuffer.IsArrayBuffer()) {
const ArrayBuffer& buffer = aBuffer.GetAsArrayBuffer();
buffer.ComputeLengthAndData();
bufferData = buffer.Data();
bufferLength = buffer.Length();
} else if (aBuffer.IsArrayBufferView()) {
const ArrayBufferView& bufferView = aBuffer.GetAsArrayBufferView();
bufferView.ComputeLengthAndData();
bufferData = bufferView.Data();
bufferLength = bufferView.Length();
} else {
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
return promise.forget();
}
MOZ_ASSERT(bufferData && bufferLength > 0, "Cannot read data from BufferSource.");
// Check the buffer.
if (((uint32_t)(aOffset + aLength) > bufferLength)) {
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return promise.forget();
}
// Create and Crop the raw data into a layers::Image
RefPtr<layers::Image> data;
if (NS_IsMainThread()) {
data = CreateImageFromBufferSourceRawData(bufferData + aOffset, bufferLength,
aFormat, aLayout);
} else {
RefPtr<CreateImageFromBufferSourceRawDataInMainThreadSyncTask> task =
new CreateImageFromBufferSourceRawDataInMainThreadSyncTask(bufferData + aOffset,
bufferLength,
aFormat,
aLayout,
getter_AddRefs(data));
task->Dispatch(Terminating, aRv);
if (aRv.Failed()) {
return promise.forget();
}
}
if (NS_WARN_IF(!data)) {
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
return promise.forget();
}
// Create an ImageBimtap.
// Assume the data from an external buffer is not alpha-premultiplied.
RefPtr<ImageBitmap> imageBitmap = new ImageBitmap(aGlobal, data, false);
// We don't need to call SetPictureRect() here because there is no cropping
// supported and the ImageBitmap's mPictureRect is the size of the source
// image in default
// We don't need to set mIsCroppingAreaOutSideOfSourceImage here because there
// is no cropping supported and the mIsCroppingAreaOutSideOfSourceImage is
// false in default.
AsyncFulfillImageBitmapPromise(promise, imageBitmap);
return promise.forget();
}
} // namespace dom
} // namespace mozilla
-43
View File
@@ -45,7 +45,6 @@ class WorkerStructuredCloneClosure;
class ArrayBufferViewOrArrayBuffer;
class CanvasRenderingContext2D;
struct ChannelPixelLayout;
class CreateImageBitmapFromBlob;
class CreateImageBitmapFromBlobTask;
class CreateImageBitmapFromBlobWorkerTask;
@@ -56,7 +55,6 @@ class HTMLVideoElement;
enum class ImageBitmapFormat : uint32_t;
class ImageData;
class ImageUtils;
template<typename T> class MapDataIntoBufferSource;
class Promise;
class PostMessageEvent; // For StructuredClone between windows.
@@ -65,7 +63,6 @@ struct ImageBitmapCloneData final
RefPtr<gfx::DataSourceSurface> mSurface;
gfx::IntRect mPictureRect;
bool mIsPremultipliedAlpha;
bool mIsCroppingAreaOutSideOfSourceImage;
bool mWriteOnly;
};
@@ -133,14 +130,6 @@ public:
Create(nsIGlobalObject* aGlobal, const ImageBitmapSource& aSrc,
const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv);
static already_AddRefed<Promise>
Create(nsIGlobalObject* aGlobal,
const ImageBitmapSource& aBuffer,
int32_t aOffset, int32_t aLength,
mozilla::dom::ImageBitmapFormat aFormat,
const Sequence<mozilla::dom::ChannelPixelLayout>& aLayout,
ErrorResult& aRv);
static JSObject*
ReadStructuredClone(JSContext* aCx,
JSStructuredCloneReader* aReader,
@@ -153,34 +142,14 @@ public:
nsTArray<RefPtr<gfx::DataSourceSurface>>& aClonedSurfaces,
ImageBitmap* aImageBitmap);
// Mozilla Extensions
static bool ExtensionsEnabled(JSContext* aCx, JSObject* aObj);
friend CreateImageBitmapFromBlob;
friend CreateImageBitmapFromBlobTask;
friend CreateImageBitmapFromBlobWorkerTask;
template<typename T>
friend class MapDataIntoBufferSource;
bool IsWriteOnly() const {
return mWriteOnly;
}
// Mozilla Extensions
ImageBitmapFormat
FindOptimalFormat(const Optional<Sequence<ImageBitmapFormat>>& aPossibleFormats,
ErrorResult& aRv);
int32_t
MappedDataLength(ImageBitmapFormat aFormat, ErrorResult& aRv);
already_AddRefed<Promise>
MapDataInto(JSContext* aCx,
ImageBitmapFormat aFormat,
const ArrayBufferViewOrArrayBuffer& aBuffer,
int32_t aOffset, ErrorResult& aRv);
protected:
/*
@@ -210,9 +179,6 @@ protected:
void SetPictureRect(const gfx::IntRect& aRect, ErrorResult& aRv);
void SetIsCroppingAreaOutSideOfSourceImage(const gfx::IntSize& aSourceSize,
const Maybe<gfx::IntRect>& aCroppingRect);
static already_AddRefed<ImageBitmap>
CreateInternal(nsIGlobalObject* aGlobal, HTMLImageElement& aImageEl,
const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv);
@@ -278,15 +244,6 @@ protected:
const bool mIsPremultipliedAlpha;
/*
* Set mIsCroppingAreaOutSideOfSourceImage if image bitmap was cropped to the
* source rectangle so that it contains any transparent black pixels (cropping
* area is outside of the source image).
* This is used in mapDataInto() to check if we should reject promise with
* IndexSizeError.
*/
bool mIsCroppingAreaOutSideOfSourceImage;
/*
* Write-Only flag is set to true if this image has been generated from a
* cross-origin source. This is the opposite of what is called 'origin-clean'
+2 -3
View File
@@ -10,9 +10,8 @@ namespace mozilla {
namespace dom {
// So we don't have to forward declare this elsewhere.
class HTMLImageElementOrHTMLVideoElementOrHTMLCanvasElementOrBlobOrImageDataOrCanvasRenderingContext2DOrImageBitmapOrArrayBufferViewOrArrayBuffer;
typedef HTMLImageElementOrHTMLVideoElementOrHTMLCanvasElementOrBlobOrImageDataOrCanvasRenderingContext2DOrImageBitmapOrArrayBufferViewOrArrayBuffer
ImageBitmapSource;
class HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElementOrImageBitmapOrBlobOrCanvasRenderingContext2DOrImageData;
typedef HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElementOrImageBitmapOrBlobOrCanvasRenderingContext2DOrImageData ImageBitmapSource;
}
}
-10
View File
@@ -2728,16 +2728,6 @@ GetChannelCountOfImageFormat(ImageBitmapFormat aFormat)
return format->GetChannelCount();
}
uint32_t
CalculateImageBufferSize(ImageBitmapFormat aFormat,
uint32_t aWidth, uint32_t aHeight)
{
UtilsUniquePtr format = Utils::GetUtils(aFormat);
MOZ_ASSERT(format, "Cannot get a valid ImageBitmapFormatUtils instance.");
return format->NeededBufferSize(aWidth, aHeight);
}
UniquePtr<ImagePixelLayout>
CopyAndConvertImageData(ImageBitmapFormat aSrcFormat,
const uint8_t* aSrcBuffer,
-8
View File
@@ -48,14 +48,6 @@ CreatePixelLayoutFromPlanarYCbCrData(const layers::PlanarYCbCrData* aData);
uint8_t
GetChannelCountOfImageFormat(ImageBitmapFormat aFormat);
/*
* Get the needed buffer size to store the image data in the given
* ImageBitmapFormat with the given width and height.
*/
uint32_t
CalculateImageBufferSize(ImageBitmapFormat aFormat,
uint32_t aWidth, uint32_t aHeight);
/*
* This function always copies the image data in _aSrcBuffer_ into _aDstBuffer_
* and it also performs color conversion if the _aSrcFormat_ and the
-70
View File
@@ -118,38 +118,6 @@ public:
return (uint32_t)(size.height * stride);
}
virtual UniquePtr<ImagePixelLayout>
MapDataInto(uint8_t* aBuffer,
uint32_t aOffset,
uint32_t aBufferLength,
ImageBitmapFormat aFormat,
ErrorResult& aRv) const
{
DataSourceSurface::ScopedMap map(Surface(), DataSourceSurface::READ);
if (!map.IsMapped()) {
aRv.Throw(NS_ERROR_ILLEGAL_VALUE);
return nullptr;
}
// Copy or convert data.
UniquePtr<ImagePixelLayout> srcLayout =
CreateDefaultPixelLayout(GetFormat(), Surface()->GetSize().width,
Surface()->GetSize().height, map.GetStride());
// Prepare destination buffer.
uint8_t* dstBuffer = aBuffer + aOffset;
UniquePtr<ImagePixelLayout> dstLayout =
CopyAndConvertImageData(GetFormat(), map.GetData(), srcLayout.get(),
aFormat, dstBuffer);
if (!dstLayout) {
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
return nullptr;
}
return dstLayout;
}
protected:
Impl() {}
@@ -197,32 +165,6 @@ public:
}
}
UniquePtr<ImagePixelLayout>
MapDataInto(uint8_t* aBuffer,
uint32_t aOffset,
uint32_t aBufferLength,
ImageBitmapFormat aFormat,
ErrorResult& aRv) const override
{
// Prepare source buffer and pixel layout.
const PlanarYCbCrData* data = GetPlanarYCbCrData();
UniquePtr<ImagePixelLayout> srcLayout =
CreatePixelLayoutFromPlanarYCbCrData(data);
// Do conversion.
UniquePtr<ImagePixelLayout> dstLayout =
CopyAndConvertImageData(GetFormat(), data->mYChannel, srcLayout.get(),
aFormat, aBuffer+aOffset);
if (!dstLayout) {
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
return nullptr;
}
return dstLayout;
}
private:
const PlanarYCbCrData* GetPlanarYCbCrData() const
{
@@ -274,17 +216,5 @@ ImageUtils::GetBufferLength() const
return mImpl->GetBufferLength();
}
UniquePtr<ImagePixelLayout>
ImageUtils::MapDataInto(uint8_t* aBuffer,
uint32_t aOffset,
uint32_t aBufferLength,
ImageBitmapFormat aFormat,
ErrorResult& aRv) const
{
MOZ_ASSERT(mImpl);
MOZ_ASSERT(aBuffer, "Map data into a null buffer.");
return mImpl->MapDataInto(aBuffer, aOffset, aBufferLength, aFormat, aRv);
}
} // namespace dom
} // namespace mozilla
-8
View File
@@ -31,10 +31,6 @@ typedef nsTArray<ChannelPixelLayout> ImagePixelLayout;
* (1) GetFormat() converts the image's format into ImageBitmapFormat enum.
* (2) GetBufferLength() returns the number of bytes that are used to store
* the image's underlying raw data.
* (3) MapDataInto() writes the image's underlying raw data into a given
* ArrayBuffer in the given format. (If the given format is different from
* the existing format, the ImageUtils uses the ImageBitmapFormatUtils to
* performa color conversion.)
*
* In theory, the functionalities of this class could be merged into the
* interface of layers::Image. However, this is designed as a isolated wrapper
@@ -58,10 +54,6 @@ public:
uint32_t GetBufferLength() const;
UniquePtr<ImagePixelLayout>
MapDataInto(uint8_t* aBuffer, uint32_t aOffset, uint32_t aBufferLength,
ImageBitmapFormat aFormat, ErrorResult& aRv) const;
protected:
Impl* mImpl;
};
@@ -1,49 +0,0 @@
<!DOCTYPE HTML>
<head>
<title>Test ImageBitmap Extensions (Bug 1141979)</title>
<meta charset="utf-8">
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
</head>
<body>
<script src="imagebitmap_extensions_prepareSources.js"></script>
<script src="imagebitmap_extensions_data.js"></script>
<script src="imagebitmap_extensions.js"></script>
<script type="text/javascript">
runTests();
function ok(expect, msg) {
window.parent.postMessage({"type": "status", status: !!expect, msg: msg}, "*");
}
function runTests() {
prepareSources().
then( function() { return Promise.all([testAccessing_randomTest("Video", gVideo, 20), // video might use slightly different frames
testAccessing_randomTest("Image", gImage, 0),
testAccessing_randomTest("Canvas", gCanvas, 0),
testAccessing_randomTest("Ctx", gCtx, 0),
testAccessing_randomTest("ImageData", gImageData, 0),
testAccessing_randomTest("ImageBitmap", gImageBitmap, 0),
testAccessing_randomTest("PNG", gPNGBlob, 0),
testAccessing_randomTest("JPEG", gJPEGBlob, 10) // JPEG loses information
]); }).
then( function() { return Promise.all([testCreateFromArrayBffer_randomTest("Video", gVideo, 20), // video might use slightly different frames
testCreateFromArrayBffer_randomTest("Image", gImage, 0),
testCreateFromArrayBffer_randomTest("Canvas", gCanvas, 0),
testCreateFromArrayBffer_randomTest("Ctx", gCtx, 0),
testCreateFromArrayBffer_randomTest("ImageData", gImageData, 0),
testCreateFromArrayBffer_randomTest("ImageBitmap", gImageBitmap, 0),
testCreateFromArrayBffer_randomTest("PNG", gPNGBlob, 0),
testCreateFromArrayBffer_randomTest("JPEG", gJPEGBlob, 10) // JPEG loses information
]); }).
then(testDraw()).
then(testExceptions).
then(testColorConversions()).
then(function() { return testInvalidAccess([gVideo, gImage, gCanvas, gCtx, gImageData, gImageBitmap, gPNGBlob, gJPEGBlob]); } ).
then(function() {window.parent.postMessage({"type": "finish"}, "*");}, function(ev) { failed(ev); window.parent.postMessage({"type": "finish"}, "*"); });
}
</script>
</body>
-526
View File
@@ -1,526 +0,0 @@
function failed(ex) {
ok(false, "Promise failure: " + ex);
}
function isPixel(sourceType, bitmapFormat, imageData, bitmapImageData, x, y, tolerance) {
if (imageData.width != bitmapImageData.width ||
imageData.height != bitmapImageData.height) {
ok(false, "Wrong dimension");
}
var index = 4 * (y * imageData.width + x);
var pr = imageData.data[index+0],
pg = imageData.data[index+1],
pb = imageData.data[index+2],
pa = imageData.data[index+3];
if (bitmapFormat == "RGBA32" || bitmapFormat == "RGBX32") {
var bpr = bitmapImageData.data[index+0],
bpg = bitmapImageData.data[index+1],
bpb = bitmapImageData.data[index+2],
bpa = bitmapImageData.data[index+3];
}
else if (bitmapFormat == "BGRA32" || bitmapFormat == "BGRX32") {
var bpb = bitmapImageData.data[index+0],
bpg = bitmapImageData.data[index+1],
bpr = bitmapImageData.data[index+2],
bpa = bitmapImageData.data[index+3];
}
else {
// format might be one of the followings: "R5G6B5", "A8", "YUV", ""
ok(false, "Not supported ImageFormat: " + bitmapFormat);
}
ok(pr - tolerance <= bpr && bpr <= pr + tolerance &&
pg - tolerance <= bpg && bpg <= pg + tolerance &&
pb - tolerance <= bpb && bpb <= pb + tolerance &&
pa - tolerance <= bpa && bpa <= pa + tolerance,
"pixel[" + x + "][" + y + "]: " + sourceType + " is "+pr+","+pg+","+pb+","+pa+"; ImageBitmap is "+ bpr + "," + bpg + "," + bpb + "," + bpa);
}
function promiseThrows(p, name) {
var didThrow;
return p.then(function() { didThrow = false; },
function() { didThrow = true; })
.then(function() { ok(didThrow, name); });
}
function testExceptions() {
return Promise.all([
promiseThrows(testColorConversion("GRAY8", "RGBA32", undefined, true), "[Exception] Cannot convert from GRAY8 to RGBA32"),
promiseThrows(testColorConversion("GRAY8", "BGRA32", undefined, true), "[Exception] Cannot convert from GRAY8 to BGRA32"),
promiseThrows(testColorConversion("GRAY8", "RGB24", undefined, true), "[Exception] Cannot convert from GRAY8 to RGB24"),
promiseThrows(testColorConversion("GRAY8", "BGR24", undefined, true), "[Exception] Cannot convert from GRAY8 to BGR24"),
promiseThrows(testColorConversion("GRAY8", "YUV444P", undefined, true), "[Exception] Cannot convert from GRAY8 to YUV444P"),
promiseThrows(testColorConversion("GRAY8", "YUV422P", undefined, true), "[Exception] Cannot convert from GRAY8 to YUV422P"),
promiseThrows(testColorConversion("GRAY8", "YUV420P", undefined, true), "[Exception] Cannot convert from GRAY8 to YUV420P"),
promiseThrows(testColorConversion("GRAY8", "YUV420SP_NV12", undefined, true), "[Exception] Cannot convert from GRAY8 to YUV420SP_NV12"),
promiseThrows(testColorConversion("GRAY8", "YUV420SP_NV21", undefined, true), "[Exception] Cannot convert from GRAY8 to YUV420SP_NV21"),
promiseThrows(testColorConversion("GRAY8", "HSV", undefined, true), "[Exception] Cannot convert from GRAY8 to HSV"),
promiseThrows(testColorConversion("GRAY8", "Lab", undefined, true), "[Exception] Cannot convert from GRAY8 to Lab"),
promiseThrows(testColorConversion("GRAY8", "DEPTH", undefined, true), "[Exception] Cannot convert from GRAY8 to DEPTH"),
promiseThrows(testColorConversion("DEPTH", "RGBA32", undefined, true), "[Exception] Cannot convert from DEPTH to RGBA32"),
promiseThrows(testColorConversion("DEPTH", "BGRA32", undefined, true), "[Exception] Cannot convert from DEPTH to BGRA32"),
promiseThrows(testColorConversion("DEPTH", "RGB24", undefined, true), "[Exception] Cannot convert from DEPTH to RGB24"),
promiseThrows(testColorConversion("DEPTH", "BGR24", undefined, true), "[Exception] Cannot convert from DEPTH to BGR24"),
promiseThrows(testColorConversion("DEPTH", "GRAY8", undefined, true), "[Exception] Cannot convert from DEPTH to GRAY8"),
promiseThrows(testColorConversion("DEPTH", "YUV444P", undefined, true), "[Exception] Cannot convert from DEPTH to YUV444P"),
promiseThrows(testColorConversion("DEPTH", "YUV422P", undefined, true), "[Exception] Cannot convert from DEPTH to YUV422P"),
promiseThrows(testColorConversion("DEPTH", "YUV420P", undefined, true), "[Exception] Cannot convert from DEPTH to YUV420P"),
promiseThrows(testColorConversion("DEPTH", "YUV420SP_NV12", undefined, true), "[Exception] Cannot convert from DEPTH to YUV420SP_NV12"),
promiseThrows(testColorConversion("DEPTH", "YUV420SP_NV21", undefined, true), "[Exception] Cannot convert from DEPTH to YUV420SP_NV21"),
promiseThrows(testColorConversion("DEPTH", "HSV", undefined, true), "[Exception] Cannot convert from DEPTH to HSV"),
promiseThrows(testColorConversion("DEPTH", "Lab", undefined, true), "[Exception] Cannot convert from DEPTH to Lab"),
promiseThrows(testColorConversion("RGBA32", "DEPTH", undefined, true), "[Exception] Cannot convert from RGBA32 to DEPTH"),
promiseThrows(testColorConversion("BGRA32", "DEPTH", undefined, true), "[Exception] Cannot convert from BGRA32 to DEPTH"),
promiseThrows(testColorConversion("RGB24", "DEPTH", undefined, true), "[Exception] Cannot convert from RGB24 to DEPTH"),
promiseThrows(testColorConversion("BGR24", "DEPTH", undefined, true), "[Exception] Cannot convert from BGR24 to DEPTH"),
promiseThrows(testColorConversion("YUV444P", "DEPTH", undefined, true), "[Exception] Cannot convert from YUV444P to DEPTH"),
promiseThrows(testColorConversion("YUV422P", "DEPTH", undefined, true), "[Exception] Cannot convert from YUV422P to DEPTH"),
promiseThrows(testColorConversion("YUV420P", "DEPTH", undefined, true), "[Exception] Cannot convert from YUV420P to DEPTH"),
promiseThrows(testColorConversion("YUV420SP_NV12", "DEPTH", undefined, true), "[Exception] Cannot convert from YUV420SP_NV12 to DEPTH"),
promiseThrows(testColorConversion("YUV420SP_NV21", "DEPTH", undefined, true), "[Exception] Cannot convert from YUV420SP_NV21 to DEPTH"),
promiseThrows(testColorConversion("HSV", "DEPTH", undefined, true), "[Exception] Cannot convert from HSV to DEPTH"),
promiseThrows(testColorConversion("Lab", "DEPTH", undefined, true), "[Exception] Cannot convert from Lab to DEPTH"),
]);
}
function testInvalidAccess(sources) {
function callMapDataIntoWithImageBitmapCroppedOutSideOfTheSourceImage(source) {
return new Promise(function(resolve, reject) {
var p = createImageBitmap(source, -1, -1, 2, 2);
p.then(
function(bitmap) {
var format = bitmap.findOptimalFormat();
var length = bitmap.mappedDataLength(format);
var buffer = new ArrayBuffer(length);
bitmap.mapDataInto(format, buffer, 0).then(
function(layout) { resolve(); },
function(error) { reject(error); }
);
},
function() { resolve(); });
});
};
var testCases = sources.map( function(source) {
return promiseThrows(callMapDataIntoWithImageBitmapCroppedOutSideOfTheSourceImage(source),
"[Exception] mapDataInto() should throw with transparent black."); });
return Promise.all(testCases);
}
function testColorConversions() {
return Promise.all([// From RGBA32
testColorConversion("RGBA32", "RGBA32"),
testColorConversion("RGBA32", "BGRA32"),
testColorConversion("RGBA32", "RGB24"),
testColorConversion("RGBA32", "BGR24"),
testColorConversion("RGBA32", "GRAY8"),
testColorConversion("RGBA32", "YUV444P"),
testColorConversion("RGBA32", "YUV422P"),
testColorConversion("RGBA32", "YUV420P", 2),
testColorConversion("RGBA32", "YUV420SP_NV12"),
testColorConversion("RGBA32", "YUV420SP_NV21"),
testColorConversion("RGBA32", "HSV", 0.01),
testColorConversion("RGBA32", "Lab", 0.5),
// From BGRA32
testColorConversion("BGRA32", "RGBA32"),
testColorConversion("BGRA32", "BGRA32"),
testColorConversion("BGRA32", "RGB24"),
testColorConversion("BGRA32", "BGR24"),
testColorConversion("BGRA32", "GRAY8"),
testColorConversion("BGRA32", "YUV444P", 3),
testColorConversion("BGRA32", "YUV422P", 2),
testColorConversion("BGRA32", "YUV420P", 2),
testColorConversion("BGRA32", "YUV420SP_NV12", 2),
testColorConversion("BGRA32", "YUV420SP_NV21", 2),
testColorConversion("BGRA32", "HSV", 0.01),
testColorConversion("BGRA32", "Lab", 0.5),
// From RGB24
testColorConversion("RGB24", "RGBA32"),
testColorConversion("RGB24", "BGRA32"),
testColorConversion("RGB24", "RGB24"),
testColorConversion("RGB24", "BGR24"),
testColorConversion("RGB24", "GRAY8"),
testColorConversion("RGB24", "YUV444P"),
testColorConversion("RGB24", "YUV422P"),
testColorConversion("RGB24", "YUV420P"),
testColorConversion("RGB24", "YUV420SP_NV12"),
testColorConversion("RGB24", "YUV420SP_NV21"),
testColorConversion("RGB24", "HSV", 0.01),
testColorConversion("RGB24", "Lab", 0.5),
// From BGR24
testColorConversion("BGR24", "RGBA32"),
testColorConversion("BGR24", "BGRA32"),
testColorConversion("BGR24", "RGB24"),
testColorConversion("BGR24", "BGR24"),
testColorConversion("BGR24", "GRAY8"),
testColorConversion("BGR24", "YUV444P"),
testColorConversion("BGR24", "YUV422P"),
testColorConversion("BGR24", "YUV420P"),
testColorConversion("BGR24", "YUV420SP_NV12"),
testColorConversion("BGR24", "YUV420SP_NV21"),
testColorConversion("BGR24", "HSV", 0.01),
testColorConversion("BGR24", "Lab", 0.5),
// From YUV444P
testColorConversion("YUV444P", "RGBA32"),
testColorConversion("YUV444P", "BGRA32"),
testColorConversion("YUV444P", "RGB24"),
testColorConversion("YUV444P", "BGR24"),
testColorConversion("YUV444P", "GRAY8"),
testColorConversion("YUV444P", "YUV444P"),
testColorConversion("YUV444P", "YUV422P", 4),
testColorConversion("YUV444P", "YUV420P", 3),
testColorConversion("YUV444P", "YUV420SP_NV12", 3),
testColorConversion("YUV444P", "YUV420SP_NV21", 3),
testColorConversion("YUV444P", "HSV", 0.01),
testColorConversion("YUV444P", "Lab", 0.01),
// From YUV422P
testColorConversion("YUV422P", "RGBA32"),
testColorConversion("YUV422P", "BGRA32", 2),
testColorConversion("YUV422P", "RGB24"),
testColorConversion("YUV422P", "BGR24"),
testColorConversion("YUV422P", "GRAY8"),
testColorConversion("YUV422P", "YUV444P", 3),
testColorConversion("YUV422P", "YUV422P"),
testColorConversion("YUV422P", "YUV420P"),
testColorConversion("YUV422P", "YUV420SP_NV12"),
testColorConversion("YUV422P", "YUV420SP_NV21"),
testColorConversion("YUV422P", "HSV", 0.01),
testColorConversion("YUV422P", "Lab", 0.01),
// From YUV420P
testColorConversion("YUV420P", "RGBA32", 2),
testColorConversion("YUV420P", "BGRA32", 2),
testColorConversion("YUV420P", "RGB24"),
testColorConversion("YUV420P", "BGR24"),
testColorConversion("YUV420P", "GRAY8"),
testColorConversion("YUV420P", "YUV444P", 3),
testColorConversion("YUV420P", "YUV422P", 1),
testColorConversion("YUV420P", "YUV420P"),
testColorConversion("YUV420P", "YUV420SP_NV12"),
testColorConversion("YUV420P", "YUV420SP_NV21"),
testColorConversion("YUV420P", "HSV", 0.01),
testColorConversion("YUV420P", "Lab", 0.01),
// From NV12
testColorConversion("YUV420SP_NV12", "RGBA32"),
testColorConversion("YUV420SP_NV12", "BGRA32", 2),
testColorConversion("YUV420SP_NV12", "RGB24"),
testColorConversion("YUV420SP_NV12", "BGR24"),
testColorConversion("YUV420SP_NV12", "GRAY8"),
testColorConversion("YUV420SP_NV12", "YUV444P", 3),
testColorConversion("YUV420SP_NV12", "YUV422P", 1),
testColorConversion("YUV420SP_NV12", "YUV420P"),
testColorConversion("YUV420SP_NV12", "YUV420SP_NV12"),
testColorConversion("YUV420SP_NV12", "YUV420SP_NV21"),
testColorConversion("YUV420SP_NV12", "HSV", 0.01),
testColorConversion("YUV420SP_NV12", "Lab", 0.01),
// From NV21
testColorConversion("YUV420SP_NV21", "RGBA32"),
testColorConversion("YUV420SP_NV21", "BGRA32", 2),
testColorConversion("YUV420SP_NV21", "RGB24"),
testColorConversion("YUV420SP_NV21", "BGR24"),
testColorConversion("YUV420SP_NV21", "GRAY8"),
testColorConversion("YUV420SP_NV21", "YUV444P", 3),
testColorConversion("YUV420SP_NV21", "YUV422P", 1),
testColorConversion("YUV420SP_NV21", "YUV420P"),
testColorConversion("YUV420SP_NV21", "YUV420SP_NV12"),
testColorConversion("YUV420SP_NV21", "YUV420SP_NV21"),
testColorConversion("YUV420SP_NV21", "HSV", 0.01),
testColorConversion("YUV420SP_NV21", "Lab", 0.01),
// From HSV
testColorConversion("HSV", "RGBA32"),
testColorConversion("HSV", "BGRA32"),
testColorConversion("HSV", "RGB24"),
testColorConversion("HSV", "BGR24"),
testColorConversion("HSV", "GRAY8"),
testColorConversion("HSV", "YUV444P"),
testColorConversion("HSV", "YUV422P"),
testColorConversion("HSV", "YUV420P"),
testColorConversion("HSV", "YUV420SP_NV12"),
testColorConversion("HSV", "YUV420SP_NV21"),
testColorConversion("HSV", "HSV", 0),
testColorConversion("HSV", "Lab", 0.5),
// From Lab
testColorConversion("Lab", "RGBA32", 1),
testColorConversion("Lab", "BGRA32", 1),
testColorConversion("Lab", "RGB24", 1),
testColorConversion("Lab", "BGR24", 1),
testColorConversion("Lab", "GRAY8", 1),
testColorConversion("Lab", "YUV444P", 1),
testColorConversion("Lab", "YUV422P", 1),
testColorConversion("Lab", "YUV420P", 1),
testColorConversion("Lab", "YUV420SP_NV12", 1),
testColorConversion("Lab", "YUV420SP_NV21", 1),
testColorConversion("Lab", "HSV", 0.5),
testColorConversion("Lab", "Lab", 0),
// From GRAY8
testColorConversion("GRAY8", "GRAY8"),
// From DEPTH
testColorConversion("DEPTH", "DEPTH", 0, Uint16Array),
]);
}
function testDraw() {
return Promise.all([doOneDrawTest("RGB24"),
doOneDrawTest("BGR24"),
doOneDrawTest("YUV444P", 5),
doOneDrawTest("YUV422P", 2),
doOneDrawTest("YUV420P", 2),
doOneDrawTest("YUV420SP_NV12", 2),
doOneDrawTest("YUV420SP_NV21", 2),
doOneDrawTest("HSV", 2),
doOneDrawTest("Lab", 2)]);
}
// Create an ImageBitmap, _bitmap_, from the _source_.
// Read the underlying data of _bitmap_ into _bitmapBuffer_.
// Compare the _bitmapBuffer_ with gGroundTruthImageData.
function testAccessing_randomTest(sourceType, source, duration) {
return new Promise(function(resolve, reject) {
var p = createImageBitmap(source);
p.then(
function(bitmap) {
bitmapFormat = "RGBA32";
var bitmapBufferLength = bitmap.mappedDataLength(bitmapFormat);
var bitmapBuffer = new ArrayBuffer(bitmapBufferLength);
var bitmapBufferView = new Uint8ClampedArray(bitmapBuffer, 0, bitmapBufferLength);
var promise = bitmap.mapDataInto(bitmapFormat, bitmapBuffer, 0);
promise.then(
function(bitmapPixelLayout) {
// Prepare.
bitmapImageData = new ImageData(bitmapBufferView, bitmap.width, bitmap.height);
// Test.
for (var t = 0; t < 50; ++t) {
var randomX = Math.floor(Math.random() * 240);
var randomY = Math.floor(Math.random() * 175);
isPixel(sourceType, "RGBA32", gGroundTruthImageData, bitmapImageData, randomX, randomY, duration);
}
resolve();
},
function(ev) { failed(ev); reject(); });
},
function(ev) { failed(ev); reject(); });
});
}
// Create an ImageBitmap, _bitmap_, from the _source_.
// Read the underlying data of _bitmap_ into _bitmapBuffer_.
// Create another ImageBitmap, _bitmap2_, from _bitmapBuffer_.
// Read the underlying data of _bitmap2_ into _bitmapBuffer2_.
// Compare the _bitmapBuffer2_ with gGroundTruthImageData.
function testCreateFromArrayBffer_randomTest(sourceType, source, duration) {
return new Promise(function(resolve, reject) {
var p = createImageBitmap(source);
p.then(
function(bitmap) {
bitmapFormat = "RGBA32";
var bitmapBufferLength = bitmap.mappedDataLength(bitmapFormat);
var bitmapBuffer = new ArrayBuffer(bitmapBufferLength);
var bitmapBufferView = new Uint8ClampedArray(bitmapBuffer, 0, bitmapBufferLength);
var promiseMapDataInto = bitmap.mapDataInto(bitmapFormat, bitmapBuffer, 0);
promiseMapDataInto.then(
function(bitmapPixelLayout) {
// Create a new ImageBitmap from an ArrayBuffer.
var p2 = createImageBitmap(bitmapBufferView,
0,
bitmapBufferLength,
bitmapFormat,
bitmapPixelLayout);
p2.then(
function(bitmap2) {
bitmapFormat2 = "RGBA32";
var bitmapBufferLength2 = bitmap2.mappedDataLength(bitmapFormat2);
var bitmapBuffer2 = new ArrayBuffer(bitmapBufferLength2);
var bitmapBufferView2 = new Uint8ClampedArray(bitmapBuffer2, 0, bitmapBufferLength2);
var promise2 = bitmap2.mapDataInto(bitmapFormat2, bitmapBuffer2, 0);
promise2.then(
function(bitmapPixelLayout2) {
// Prepare.
var bitmapImageData2 = new ImageData(bitmapBufferView2, bitmap2.width, bitmap2.height);
// Test.
for (var t = 0; t < 50; ++t) {
var randomX = Math.floor(Math.random() * 240);
var randomY = Math.floor(Math.random() * 175);
isPixel(sourceType, "RGBA32", gGroundTruthImageData, bitmapImageData2, randomX, randomY, duration);
}
resolve();
},
function(ev) { failed(ev); reject(); });
},
function(ev) { console.log("p2 rejected!"); failed(ev); reject(); });
},
function(ev) { console.log("promiseMapDataInto rejected!"); failed(ev); reject(); });
},
function(ev) { failed(ev); reject(); });
});
}
function testColorConversion(sourceFromat, destinationFormat, tolerance, shouldThrow) {
tolerance = tolerance || 0;
shouldThrow = shouldThrow || false;
return new Promise(function(resolve, reject) {
var [srcData, dstData] = getTestData(sourceFromat, destinationFormat);
ok(!!srcData, "Get valid srcData of type:" + sourceFromat);
ok(!!dstData, "Get valid dstData of type:" + destinationFormat);
// printInfo(sourceFromat, srcData);
// printInfo(destinationFormat, dstData);
// Create a new ImageBitmap from an ArrayBuffer.
var p = createImageBitmap(srcData.buffer,
0,
srcData.bufferLength,
srcData.format,
srcData.pixelLayout);
p.then(
function(srcBitmap) {
ok(!!srcBitmap, "Should get a valid srcBitmap.");
ok(srcBitmap.findOptimalFormat() == sourceFromat, "srcBitmap.findOptimalFormat():" + srcBitmap.findOptimalFormat() +
" should equal to sourceFromat:" + sourceFromat);
var dstBufferLength = srcBitmap.mappedDataLength(destinationFormat);
var dstBuffer = new ArrayBuffer(dstBufferLength);
var dstBufferView = new dstData.ArrayType(dstBuffer, 0, dstBufferLength / dstData.ArrayType.BYTES_PER_ELEMENT);
// Do color conversion here.
var p2 = srcBitmap.mapDataInto(destinationFormat, dstBuffer, 0);
p2.then(
function(dstPixelLayout) {
var dataPixalLayout = dstData.pixelLayout;
// Check pixel layout.
ok(dstPixelLayout.length == dstData.channelCount, "dstPixelLayout.length:" + dstPixelLayout.length +
" should equal to dstData.channelCount:" + dstData.channelCount);
for (var c = 0; c < dstData.channelCount; ++c) {
var dstChannelLayout = dstPixelLayout[c];
var dataChannelLayout = dataPixalLayout[c];
ok(dstChannelLayout.width == dataChannelLayout.width, "channel[" + c + "] dstChannelLayout.width:" + dstChannelLayout.width + " should equal to dataChannelLayout.width:" + dataChannelLayout.width);
ok(dstChannelLayout.height == dataChannelLayout.height, "channel[" + c + "] dstChannelLayout.height:" + dstChannelLayout.height + " should equal to dataChannelLayout.height:" + dataChannelLayout.height);
ok(dstChannelLayout.skip == dataChannelLayout.skip, "channel[" + c + "] dstChannelLayout.skip:" + dstChannelLayout.skip + " should equal to dataChannelLayout.skip:" + dataChannelLayout.skip);
for (var i = 0; i < dstChannelLayout.height; ++i) {
for (var j = 0; j < dstChannelLayout.width; ++j) {
var byteOffset = dstChannelLayout.offset + i * dstChannelLayout.stride + j * (dstChannelLayout.skip + 1) * dstData.ArrayType.BYTES_PER_ELEMENT;
var view = new dstData.ArrayType(dstBuffer, byteOffset, 1);
var dstBufferViewValue = view[0];
var dstDataValue = dstData.getPixelValue(i, j, c);
ok(Math.abs(dstBufferViewValue - dstDataValue) <= tolerance,
"[" + sourceFromat + " -> " + destinationFormat + "] pixel(" + i + "," + j + ") channnel(" + c +
"): dstBufferViewValue:" + dstBufferViewValue +
" should equal to dstDataValue:" + dstDataValue);
}
}
}
resolve();
},
function(ev) {
// If the "mapDataInto" throws, the flow goes here.
if (!shouldThrow) { failed(ev); }
reject();
}
);
},
function(ev) {
reject(ev);
}
);
});
}
function doOneDrawTest(sourceFromat, tolerance) {
tolerance = tolerance || 0;
var destinationFormat = "RGBA32";
return new Promise(function(resolve, reject) {
var [srcData, dstData] = getTestData(sourceFromat, destinationFormat);
ok(!!srcData, "Get valid srcData of type:" + sourceFromat);
ok(!!dstData, "Get valid dstData of type:" + destinationFormat);
var p = createImageBitmap(srcData.buffer,
0,
srcData.bufferLength,
srcData.format,
srcData.pixelLayout);
p.then(
function(srcBitmap) {
ok(!!srcBitmap, "Should get a valid srcBitmap.");
ok(srcBitmap.findOptimalFormat() == sourceFromat, "srcBitmap.findOptimalFormat():" + srcBitmap.findOptimalFormat() +
" should equal to sourceFromat:" + sourceFromat);
var canvas = document.createElement("canvas");
canvas.width = srcBitmap.width;
canvas.height = srcBitmap.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(srcBitmap, 0, 0, srcBitmap.width, srcBitmap.height);
// Get an ImageData from the canvas.
var imageData = ctx.getImageData(0, 0, srcBitmap.width, srcBitmap.height);
for (var i = 0; i < srcBitmap.height; ++i) {
for (var j = 0; j < srcBitmap.width; ++j) {
var pixelOffset = i * srcBitmap.width * dstData.channelCount + j * dstData.channelCount;
var dstImageDataValue_R = imageData.data[pixelOffset + 0];
var dstImageDataValue_G = imageData.data[pixelOffset + 1];
var dstImageDataValue_B = imageData.data[pixelOffset + 2];
var dstImageDataValue_A = imageData.data[pixelOffset + 3];
var logPrefix = "[" + sourceFromat + " -> " + destinationFormat + "] pixel(" + i + "," + j + ")";
var dstDataValue_R = dstData.getPixelValue(i, j, 0);
var dstDataValue_G = dstData.getPixelValue(i, j, 1);
var dstDataValue_B = dstData.getPixelValue(i, j, 2);
var dstDataValue_A = dstData.getPixelValue(i, j, 3);
ok(Math.abs(dstImageDataValue_R - dstDataValue_R) <= tolerance,
logPrefix + "channnel(R): dstImageDataValue:" + dstImageDataValue_R + " should equal to dstDataValue_R: " + dstDataValue_R);
ok(Math.abs(dstImageDataValue_G - dstDataValue_G) <= tolerance,
logPrefix + "channnel(G): dstImageDataValue:" + dstImageDataValue_G + " should equal to dstDataValue_G: " + dstDataValue_G);
ok(Math.abs(dstImageDataValue_B - dstDataValue_B) <= tolerance,
logPrefix + "channnel(B): dstImageDataValue:" + dstImageDataValue_B + " should equal to dstDataValue_B: " + dstDataValue_B);
ok(Math.abs(dstImageDataValue_A - dstDataValue_A) <= tolerance,
logPrefix + "channnel(A): dstImageDataValue:" + dstImageDataValue_A + " should equal to dstDataValue_A: " + dstDataValue_A);
}
}
resolve();
},
function(ev) {
failed(ev);
reject(ev);
}
);
});
}
File diff suppressed because it is too large. Load diff
@@ -1,47 +0,0 @@
importScripts("imagebitmap_extensions_data.js");
importScripts("imagebitmap_extensions.js");
var gGroundTruthImageData;
var gImageData;
var gImageBitmap;
var gPNGBlob;
var gJPEGBlob;
onmessage = function(event) {
if (event.data.type == "setSources") {
gGroundTruthImageData = event.data.groundTruthImageData;
gImageData = event.data.imageData;
gImageBitmap = event.data.imageBitmap;
gPNGBlob = event.data.pngBlob;
gJPEGBlob = event.data.jpegBlob;
ok(!!gGroundTruthImageData, "Get gGroundTruthImageData!");
ok(!!gImageData, "Get gImageData!");
ok(!!gImageBitmap, "Get gImageBitmap!");
ok(!!gPNGBlob, "Get gPNGBlob!");
ok(!!gJPEGBlob, "Get gJPEGBlob!");
runTests();
}
};
function ok(expect, msg) {
postMessage({"type": "status", status: !!expect, msg: msg});
}
function runTests() {
testExceptions().
then(testColorConversions()).
then( function() { return Promise.all([testAccessing_randomTest("ImageData", gImageData, 0),
testAccessing_randomTest("ImageBitmap", gImageBitmap, 0),
testAccessing_randomTest("PNG", gPNGBlob, 0),
testAccessing_randomTest("JPEG", gJPEGBlob, 10) // JPEG loses information
]); }).
then( function() { return Promise.all([testCreateFromArrayBffer_randomTest("ImageData", gImageData, 0),
testCreateFromArrayBffer_randomTest("ImageBitmap", gImageBitmap, 0),
testCreateFromArrayBffer_randomTest("PNG", gPNGBlob, 0),
testCreateFromArrayBffer_randomTest("JPEG", gJPEGBlob, 10) // JPEG loses information
]); }).
then(function() { return testInvalidAccess([gImageData, gImageBitmap, gPNGBlob, gJPEGBlob]); } ).
then(function() {postMessage({"type": "finish"});}, function(ev) { failed(ev); postMessage({"type": "finish"}); });
}
@@ -1,94 +0,0 @@
var gImage;
var gVideo;
var gCanvas;
var gCtx;
var gImageData;
var gImageBitmap;
var gPNGBlob;
var gJPEGBlob;
var gGroundTruthImageData;
function prepareSources() {
gVideo = document.createElement("video");
gVideo.src = "http://example.com/tests/dom/canvas/test/crossorigin/video.sjs?name=tests/dom/media/test/320x240.ogv&type=video/ogg&cors=anonymous";
gVideo.crossOrigin = "anonymous";
gVideo.autoplay = "true"
gCanvas = document.createElement("canvas");
gCtx = gCanvas.getContext("2d");
var resolver;
var promise = new Promise(function(resolve, reject) {
resolver = resolve;
});
// Prepare video.
gVideo.onloadeddata = function() {
ok(gVideo, "[Prepare Sources] gVideo is ok.");
// Prepare canvas.
gCanvas.width = gVideo.videoWidth;
gCanvas.height = gVideo.videoHeight;
gCtx.drawImage(gVideo, 0, 0);
ok(gCanvas, "[Prepare Sources] gCanvas is ok.");
ok(gCtx, "[Prepare Sources] gCtx is ok.");
// Prepare gGroundTruthImageData.
gGroundTruthImageData = gCtx.getImageData(0, 0, gCanvas.width, gCanvas.height);
ok(gGroundTruthImageData, "[Prepare Sources] gGroundTruthImageData is ok.");
// Prepare image.
gImage = document.createElement("img");
gImage.src = gCanvas.toDataURL();
var resolverImage;
var promiseImage = new Promise(function(resolve, reject) {
resolverImage = resolve;
});
gImage.onload = function() {
resolverImage(true);
}
// Prepare ImageData.
gImageData = gCtx.getImageData(0, 0, gCanvas.width, gCanvas.height);
ok(gImageData, "[Prepare Sources] gImageData is ok.");
// Prepapre PNG Blob.
var promisePNGBlob = new Promise(function(resolve, reject) {
gCanvas.toBlob(function(blob) {
gPNGBlob = blob;
ok(gPNGBlob, "[Prepare Sources] gPNGBlob is ok.");
resolve(true);
});
});
// Prepare JPEG Blob.
var promiseJPEGBlob = new Promise(function(resolve, reject) {
gCanvas.toBlob(function(blob) {
gJPEGBlob = blob;
ok(gJPEGBlob, "[Prepare Sources] gJPEGBlob is ok.");
resolve(true);
}, "image/jpeg", 1.00);
});
// Prepare ImageBitmap.
var promiseImageBitmap = new Promise(function(resolve, reject) {
var p = createImageBitmap(gCanvas);
p.then(function(bitmap) {
gImageBitmap = bitmap;
ok(gImageBitmap, "[Prepare Sources] gImageBitmap is ok.");
resolve(true);
});
});
resolver(Promise.all([
promiseImage,
promisePNGBlob,
promiseJPEGBlob,
promiseImageBitmap
]))
}
return promise;
}
-8
View File
@@ -27,10 +27,6 @@ support-files =
imagebitmap_bug1239300.js
imagebitmap_bug1239752.js
imagebitmap_extensions.html
imagebitmap_extensions.js
imagebitmap_extensions_data.js
imagebitmap_extensions_on_worker.js
imagebitmap_extensions_prepareSources.js
imagebitmap_on_worker.js
imagebitmap_structuredclone.js
imagebitmap_structuredclone_iframe.html
@@ -232,10 +228,6 @@ tags = imagebitmap
tags = imagebitmap
[test_imagebitmap_cropping.html]
tags = imagebitmap
[test_imagebitmap_extensions.html]
tags = imagebitmap
[test_imagebitmap_extensions_on_worker.html]
tags = imagebitmap
[test_imagebitmap_on_worker.html]
tags = imagebitmap
[test_imagebitmap_structuredclone.html]
@@ -1,37 +0,0 @@
<!DOCTYPE HTML>
<heand>
<title>Test ImageBitmap Extensions (Bug 1141979)</title>
<meta charset="utf-8">
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
</head>
<body>
<div id="content"><div>
<script type="text/javascript">
SimpleTest.waitForExplicitFinish();
// The createImageBitmap() method is part of Window whose
// prototype was created before the preference is set. So I create another
// iframe with the right preference setting so that the
// createImageBitmap() will be visible.
SpecialPowers.pushPrefEnv({'set': [
['canvas.imagebitmap_extensions.enabled', true],
['gfx.ycbcr.accurate-conversion', true]
]}, function() {
var div = document.getElementById("content");
ok(div, "Parent exists");
var ifr = document.createElement("iframe");
ifr.setAttribute('src', "imagebitmap_extensions.html");
div.appendChild(ifr);
});
window.onmessage = function(event) {
if (event.data.type == "status") {
ok(event.data.status, event.data.msg);
} else if (event.data.type == "finish") {
SimpleTest.finish();
}
}
</script>
</body>
@@ -1,39 +0,0 @@
<!DOCTYPE HTML>
<heand>
<title>Test ImageBitmap Extensions On Worker (Bug 1141979)</title>
<meta charset="utf-8">
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
</head>
<body>
<div id="content"><div>
<script src="imagebitmap_extensions_prepareSources.js"></script>
<script type="text/javascript">
var worker;
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({'set': [
['canvas.imagebitmap_extensions.enabled', true]
]}, function() {
worker = new Worker("imagebitmap_extensions_on_worker.js");
worker.onmessage = function(event) {
if (event.data.type == "status") {
ok(event.data.status, event.data.msg);
} else if (event.data.type == "finish") {
SimpleTest.finish();
}
};
ok(!!worker, "Worker created successfully.");
prepareSources().then(function() {
worker.postMessage({"type": "setSources",
"groundTruthImageData": gGroundTruthImageData,
"imageData": gImageData,
"imageBitmap": gImageBitmap,
"pngBlob": gPNGBlob,
"jpegBlob": gJPEGBlob});
});
});
</script>
</body>
+3 -21
View File
@@ -214,16 +214,6 @@ public:
mRetargetedRelatedTarget = aTarget;
}
void SetForceContentDispatch(bool aForce)
{
mFlags.mForceContentDispatch = aForce;
}
bool ForceContentDispatch()
{
return mFlags.mForceContentDispatch;
}
void SetWantsWillHandleEvent(bool aWants)
{
mFlags.mWantsWillHandleEvent = aWants;
@@ -387,7 +377,6 @@ private:
// Cached flags for each EventTargetChainItem which are set when calling
// GetEventTargetParent to create event target chain. They are used to
// manage or speedup event dispatching.
bool mForceContentDispatch : 1;
bool mWantsWillHandleEvent : 1;
bool mMayHaveManager : 1;
bool mChechedIfChrome : 1;
@@ -439,7 +428,6 @@ EventTargetChainItem::GetEventTargetParent(EventChainPreVisitor& aVisitor)
{
aVisitor.Reset();
Unused << mTarget->GetEventTargetParent(aVisitor);
SetForceContentDispatch(aVisitor.mForceContentDispatch);
SetWantsWillHandleEvent(aVisitor.mWantsWillHandleEvent);
SetMayHaveListenerManager(aVisitor.mMayHaveListenerManager);
SetWantsPreHandleEvent(aVisitor.mWantsPreHandleEvent);
@@ -492,9 +480,7 @@ EventTargetChainItem::HandleEventTargetChain(
if (item.PreHandleEventOnly()) {
continue;
}
if ((!aVisitor.mEvent->mFlags.mNoContentDispatch ||
item.ForceContentDispatch()) &&
!aVisitor.mEvent->PropagationStopped()) {
if (!aVisitor.mEvent->PropagationStopped()) {
item.HandleEvent(aVisitor, aCd);
}
@@ -538,9 +524,7 @@ EventTargetChainItem::HandleEventTargetChain(
// Target
aVisitor.mEvent->mFlags.mInBubblingPhase = true;
EventTargetChainItem& targetItem = aChain[firstCanHandleEventTargetIdx];
if (!aVisitor.mEvent->PropagationStopped() &&
(!aVisitor.mEvent->mFlags.mNoContentDispatch ||
targetItem.ForceContentDispatch())) {
if (!aVisitor.mEvent->PropagationStopped()) {
targetItem.HandleEvent(aVisitor, aCd);
}
if (aVisitor.mEvent->mFlags.mInSystemGroup) {
@@ -570,9 +554,7 @@ EventTargetChainItem::HandleEventTargetChain(
}
if (aVisitor.mEvent->mFlags.mBubbles || newTarget) {
if ((!aVisitor.mEvent->mFlags.mNoContentDispatch ||
item.ForceContentDispatch()) &&
!aVisitor.mEvent->PropagationStopped()) {
if (!aVisitor.mEvent->PropagationStopped()) {
item.HandleEvent(aVisitor, aCd);
}
if (aVisitor.mEvent->mFlags.mInSystemGroup) {
-9
View File
@@ -118,7 +118,6 @@ public:
: EventChainVisitor(aPresContext, aEvent, aDOMEvent, aEventStatus)
, mCanHandle(true)
, mAutomaticChromeDispatch(true)
, mForceContentDispatch(false)
, mRelatedTargetIsInAnon(false)
, mOriginalTargetIsInAnon(aIsInAnon)
, mWantsWillHandleEvent(false)
@@ -143,7 +142,6 @@ public:
mItemData = nullptr;
mCanHandle = true;
mAutomaticChromeDispatch = true;
mForceContentDispatch = false;
mWantsWillHandleEvent = false;
mMayHaveListenerManager = true;
mWantsPreHandleEvent = false;
@@ -195,13 +193,6 @@ public:
*/
bool mAutomaticChromeDispatch;
/**
* If mForceContentDispatch is set to true,
* content dispatching is not disabled for this event target.
* FIXME! This is here for backward compatibility. Bug 329119
*/
bool mForceContentDispatch;
/**
* true if it is known that related target is or is a descendant of an
* element which is anonymous for events.
+15 -16
View File
@@ -4677,7 +4677,7 @@ EventStateManager::InitAndDispatchClickEvent(WidgetMouseEvent* aMouseUpEvent,
nsIPresShell* aPresShell,
nsIContent* aMouseUpContent,
nsWeakFrame aCurrentTarget,
bool aNoContentDispatch)
bool aOnlyChromeDispatch)
{
MOZ_ASSERT(aMouseUpEvent);
MOZ_ASSERT(EventCausesClickEvents(*aMouseUpEvent));
@@ -4691,8 +4691,7 @@ EventStateManager::InitAndDispatchClickEvent(WidgetMouseEvent* aMouseUpEvent,
event.buttons = aMouseUpEvent->buttons;
event.mTime = aMouseUpEvent->mTime;
event.mTimeStamp = aMouseUpEvent->mTimeStamp;
event.mFlags.mOnlyChromeDispatch = aNoContentDispatch;
event.mFlags.mNoContentDispatch = aNoContentDispatch;
event.mFlags.mOnlyChromeDispatch = aOnlyChromeDispatch;
event.button = aMouseUpEvent->button;
event.inputSource = aMouseUpEvent->inputSource;
@@ -4759,41 +4758,41 @@ EventStateManager::DispatchClickEvents(nsIPresShell* aPresShell,
MOZ_ASSERT(aStatus);
MOZ_ASSERT(aClickTarget);
bool notDispatchToContents =
bool onlyDispatchInChrome =
(aMouseUpEvent->button == WidgetMouseEvent::eMiddleButton ||
aMouseUpEvent->button == WidgetMouseEvent::eRightButton);
bool fireAuxClick = notDispatchToContents;
bool fireAuxClick = onlyDispatchInChrome;
nsWeakFrame currentTarget = aClickTarget->GetPrimaryFrame();
nsresult ret =
nsresult rv =
InitAndDispatchClickEvent(aMouseUpEvent, aStatus, eMouseClick,
aPresShell, aClickTarget, currentTarget,
notDispatchToContents);
if (NS_WARN_IF(NS_FAILED(ret))) {
return ret;
onlyDispatchInChrome);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// Fire auxclick even if necessary.
if (fireAuxClick && aClickTarget && aClickTarget->IsInComposedDoc()) {
ret = InitAndDispatchClickEvent(aMouseUpEvent, aStatus, eMouseAuxClick,
rv = InitAndDispatchClickEvent(aMouseUpEvent, aStatus, eMouseAuxClick,
aPresShell, aClickTarget, currentTarget,
false);
NS_WARNING_ASSERTION(NS_SUCCEEDED(ret), "Failed to dispatch eMouseAuxClick");
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to dispatch eMouseAuxClick");
}
// Fire double click event if click count is 2.
if (aMouseUpEvent->mClickCount == 2 && !fireAuxClick &&
aClickTarget && aClickTarget->IsInComposedDoc()) {
ret = InitAndDispatchClickEvent(aMouseUpEvent, aStatus, eMouseDoubleClick,
rv = InitAndDispatchClickEvent(aMouseUpEvent, aStatus, eMouseDoubleClick,
aPresShell, aClickTarget, currentTarget,
notDispatchToContents);
if (NS_WARN_IF(NS_FAILED(ret))) {
return ret;
onlyDispatchInChrome);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
return ret;
return rv;
}
nsIFrame*
+30 -75
View File
@@ -33,6 +33,7 @@
#include "mozilla/Unused.h"
#include "Fetch.h"
#include "FetchUtil.h"
#include "InternalRequest.h"
#include "InternalResponse.h"
@@ -262,62 +263,30 @@ FetchDriver::HttpFetch()
// Set the same headers.
SetRequestHeaders(httpChan);
// Step 2. Set the referrer.
nsAutoString referrer;
mRequest->GetReferrer(referrer);
// The Referrer Policy in Request can be used to override a referrer policy
// associated with an environment settings object.
// If there's no Referrer Policy in the request, it should be inherited
// from environment.
ReferrerPolicy referrerPolicy = mRequest->ReferrerPolicy_();
net::ReferrerPolicy net_referrerPolicy = mRequest->GetEnvironmentReferrerPolicy();
switch (referrerPolicy) {
case ReferrerPolicy::_empty:
break;
case ReferrerPolicy::No_referrer:
net_referrerPolicy = net::RP_No_Referrer;
break;
case ReferrerPolicy::No_referrer_when_downgrade:
net_referrerPolicy = net::RP_No_Referrer_When_Downgrade;
break;
case ReferrerPolicy::Origin:
net_referrerPolicy = net::RP_Origin;
break;
case ReferrerPolicy::Origin_when_cross_origin:
net_referrerPolicy = net::RP_Origin_When_Crossorigin;
break;
case ReferrerPolicy::Unsafe_url:
net_referrerPolicy = net::RP_Unsafe_URL;
break;
default:
MOZ_ASSERT_UNREACHABLE("Invalid ReferrerPolicy enum value?");
break;
// Step 6 of
// https://fetch.spec.whatwg.org/#main-fetch
// If request's referrer policy is the empty string and request's client is
// non-null, then set request's referrer policy to request's client's
// associated referrer policy.
// Basically, "client" is not in our implementation, we use
// EnvironmentReferrerPolicy of the worker or document context
if (mRequest->ReferrerPolicy_() == ReferrerPolicy::_empty) {
mRequest->SetReferrerPolicy(net_referrerPolicy);
}
// Step 7 of
// https://fetch.spec.whatwg.org/#main-fetch
// If request’s referrer policy is the empty string,
// then set request’s referrer policy to "no-referrer-when-downgrade".
if (mRequest->ReferrerPolicy_() == ReferrerPolicy::_empty) {
mRequest->SetReferrerPolicy(net::RP_No_Referrer_When_Downgrade);
}
if (referrer.EqualsLiteral(kFETCH_CLIENT_REFERRER_STR)) {
rv = nsContentUtils::SetFetchReferrerURIWithPolicy(mPrincipal,
mDocument,
httpChan,
net_referrerPolicy);
NS_ENSURE_SUCCESS(rv, rv);
} else if (referrer.IsEmpty()) {
rv = httpChan->SetReferrerWithPolicy(nullptr, net::RP_No_Referrer);
NS_ENSURE_SUCCESS(rv, rv);
} else {
// From "Determine request's Referrer" step 3
// "If request's referrer is a URL, let referrerSource be request's
// referrer."
nsCOMPtr<nsIURI> referrerURI;
rv = NS_NewURI(getter_AddRefs(referrerURI), referrer, nullptr, nullptr);
NS_ENSURE_SUCCESS(rv, rv);
rv =
httpChan->SetReferrerWithPolicy(referrerURI,
referrerPolicy == ReferrerPolicy::_empty ?
mRequest->GetEnvironmentReferrerPolicy() :
net_referrerPolicy);
NS_ENSURE_SUCCESS(rv, rv);
}
rv = FetchUtil::SetRequestReferrer(mPrincipal,
mDocument,
httpChan,
mRequest);
NS_ENSURE_SUCCESS(rv, rv);
// Bug 1120722 - Authorization will be handled later.
// Auth may require prompting, we don't support it yet.
@@ -864,29 +833,15 @@ FetchDriver::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
net::ReferrerPolicy net_referrerPolicy =
nsContentUtils::GetReferrerPolicyFromHeader(tRPHeaderValue);
if (net_referrerPolicy != net::RP_Unset) {
ReferrerPolicy referrerPolicy = mRequest->ReferrerPolicy_();
switch (net_referrerPolicy) {
case net::RP_No_Referrer:
referrerPolicy = ReferrerPolicy::No_referrer;
break;
case net::RP_No_Referrer_When_Downgrade:
referrerPolicy = ReferrerPolicy::No_referrer_when_downgrade;
break;
case net::RP_Origin:
referrerPolicy = ReferrerPolicy::Origin;
break;
case net::RP_Origin_When_Crossorigin:
referrerPolicy = ReferrerPolicy::Origin_when_cross_origin;
break;
case net::RP_Unsafe_URL:
referrerPolicy = ReferrerPolicy::Unsafe_url;
break;
default:
MOZ_ASSERT_UNREACHABLE("Invalid ReferrerPolicy value");
break;
mRequest->SetReferrerPolicy(net_referrerPolicy);
// Should update channel's referrer policy
if (httpChannel) {
rv = FetchUtil::SetRequestReferrer(mPrincipal,
mDocument,
httpChannel,
mRequest);
NS_ENSURE_SUCCESS(rv, rv);
}
mRequest->SetReferrerPolicy(referrerPolicy);
}
}
+56
View File
@@ -4,8 +4,10 @@
#include "nsIUnicodeDecoder.h"
#include "nsNetUtil.h"
#include "nsString.h"
#include "nsIDocument.h"
#include "mozilla/dom/EncodingUtils.h"
#include "mozilla/dom/InternalRequest.h"
namespace mozilla {
namespace dom {
@@ -111,5 +113,59 @@ FetchUtil::ExtractHeader(nsACString::const_iterator& aStart,
return PushOverLine(aStart, aEnd);
}
// static
nsresult
FetchUtil::SetRequestReferrer(nsIPrincipal* aPrincipal,
nsIDocument* aDoc,
nsIHttpChannel* aChannel,
InternalRequest* aRequest) {
MOZ_ASSERT(NS_IsMainThread());
nsAutoString referrer;
aRequest->GetReferrer(referrer);
net::ReferrerPolicy policy = aRequest->GetReferrerPolicy();
nsresult rv = NS_OK;
if (referrer.IsEmpty()) {
// This is the case request’s referrer is "no-referrer"
rv = aChannel->SetReferrerWithPolicy(nullptr, net::RP_No_Referrer);
NS_ENSURE_SUCCESS(rv, rv);
} else if (referrer.EqualsLiteral(kFETCH_CLIENT_REFERRER_STR)) {
rv = nsContentUtils::SetFetchReferrerURIWithPolicy(aPrincipal,
aDoc,
aChannel,
policy);
NS_ENSURE_SUCCESS(rv, rv);
} else {
// From "Determine request's Referrer" step 3
// "If request's referrer is a URL, let referrerSource be request's
// referrer."
nsCOMPtr<nsIURI> referrerURI;
rv = NS_NewURI(getter_AddRefs(referrerURI), referrer, nullptr, nullptr);
NS_ENSURE_SUCCESS(rv, rv);
rv = aChannel->SetReferrerWithPolicy(referrerURI, policy);
NS_ENSURE_SUCCESS(rv, rv);
}
nsCOMPtr<nsIURI> referrerURI;
aChannel->GetReferrer(getter_AddRefs(referrerURI));
// Step 8 https://fetch.spec.whatwg.org/#main-fetch
// If request’s referrer is not "no-referrer", set request’s referrer to
// the result of invoking determine request’s referrer.
if (referrerURI) {
nsAutoCString spec;
rv = referrerURI->GetSpec(spec);
NS_ENSURE_SUCCESS(rv, rv);
aRequest->SetReferrer(NS_ConvertUTF8toUTF16(spec));
} else {
aRequest->SetReferrer(EmptyString());
}
return NS_OK;
}
} // namespace dom
} // namespace mozilla
+13
View File
@@ -8,9 +8,15 @@
#include "mozilla/dom/File.h"
#include "mozilla/dom/FormData.h"
class nsIPrincipal;
class nsIDocument;
class nsIHttpChannel;
namespace mozilla {
namespace dom {
class InternalRequest;
class FetchUtil final
{
private:
@@ -35,6 +41,13 @@ public:
nsCString& aHeaderName,
nsCString& aHeaderValue,
bool* aWasEmptyHeader);
static nsresult
SetRequestReferrer(nsIPrincipal* aPrincipal,
nsIDocument* aDoc,
nsIHttpChannel* aChannel,
InternalRequest* aRequest);
};
} // namespace dom
+66
View File
@@ -232,6 +232,72 @@ public:
mReferrerPolicy = aReferrerPolicy;
}
void
SetReferrerPolicy(net::ReferrerPolicy aReferrerPolicy)
{
switch (aReferrerPolicy) {
case net::RP_Unset:
mReferrerPolicy = ReferrerPolicy::_empty;
break;
case net::RP_No_Referrer:
mReferrerPolicy = ReferrerPolicy::No_referrer;
break;
case net::RP_No_Referrer_When_Downgrade:
mReferrerPolicy = ReferrerPolicy::No_referrer_when_downgrade;
break;
case net::RP_Origin:
mReferrerPolicy = ReferrerPolicy::Origin;
break;
case net::RP_Origin_When_Crossorigin:
mReferrerPolicy = ReferrerPolicy::Origin_when_cross_origin;
break;
case net::RP_Unsafe_URL:
mReferrerPolicy = ReferrerPolicy::Unsafe_url;
break;
case net::RP_Same_Origin:
mReferrerPolicy = ReferrerPolicy::Same_origin;
break;
case net::RP_Strict_Origin:
mReferrerPolicy = ReferrerPolicy::Strict_origin;
break;
case net::RP_Strict_Origin_When_Cross_Origin:
mReferrerPolicy = ReferrerPolicy::Strict_origin_when_cross_origin;
break;
default:
MOZ_ASSERT_UNREACHABLE("Invalid ReferrerPolicy value");
break;
}
}
net::ReferrerPolicy
GetReferrerPolicy()
{
switch (mReferrerPolicy) {
case ReferrerPolicy::_empty:
return net::RP_Unset;
case ReferrerPolicy::No_referrer:
return net::RP_No_Referrer;
case ReferrerPolicy::No_referrer_when_downgrade:
return net::RP_No_Referrer_When_Downgrade;
case ReferrerPolicy::Origin:
return net::RP_Origin;
case ReferrerPolicy::Origin_when_cross_origin:
return net::RP_Origin_When_Crossorigin;
case ReferrerPolicy::Unsafe_url:
return net::RP_Unsafe_URL;
case ReferrerPolicy::Strict_origin:
return net::RP_Strict_Origin;
case ReferrerPolicy::Same_origin:
return net::RP_Same_Origin;
case ReferrerPolicy::Strict_origin_when_cross_origin:
return net::RP_Strict_Origin_When_Cross_Origin;
default:
MOZ_ASSERT_UNREACHABLE("Invalid ReferrerPolicy enum value?");
break;
}
return net::RP_Unset;
}
net::ReferrerPolicy
GetEnvironmentReferrerPolicy() const
{
+4
View File
@@ -33,6 +33,7 @@
#include "nsFocusManager.h"
#include "mozilla/dom/HTMLFormElement.h"
#include "mozAutoDocUpdate.h"
#include "mozilla/Preferences.h"
#define NS_IN_SUBMIT_CLICK (1 << 0)
#define NS_OUTER_ACTIVATE_EVENT (1 << 1)
@@ -186,6 +187,9 @@ HTMLButtonElement::ParseAttribute(int32_t aNamespaceID,
}
if (aAttribute == nsGkAtoms::formmethod) {
if (Preferences::GetBool("dom.dialog_element.enabled", true)) {
return aResult.ParseEnumValue(aValue, kFormMethodTableDialogEnabled, false);
}
return aResult.ParseEnumValue(aValue, kFormMethodTable, false);
}
if (aAttribute == nsGkAtoms::formenctype) {
+47 -5
View File
@@ -321,6 +321,9 @@ HTMLFormElement::ParseAttribute(int32_t aNamespaceID,
{
if (aNamespaceID == kNameSpaceID_None) {
if (aAttribute == nsGkAtoms::method) {
if (Preferences::GetBool("dom.dialog_element.enabled", true)) {
return aResult.ParseEnumValue(aValue, kFormMethodTableDialogEnabled, false);
}
return aResult.ParseEnumValue(aValue, kFormMethodTable, false);
}
if (aAttribute == nsGkAtoms::enctype) {
@@ -673,6 +676,30 @@ HTMLFormElement::DoSubmit(WidgetEvent* aEvent)
mSubmitInitiatedFromUserInput = EventStateManager::IsHandlingUserInput();
//
// perform the submission
//
if (!submission) {
mIsSubmitting = false;
#ifdef DEBUG
HTMLDialogElement* dialog = nullptr;
for (nsIContent* parent = GetParent(); parent;
parent = parent->GetParent()) {
dialog = HTMLDialogElement::FromContentOrNull(parent);
if (dialog) {
break;
}
}
MOZ_ASSERT(!dialog || !dialog->Open());
#endif
return NS_OK;
}
if (DialogFormSubmission* dialogSubmission =
submission->GetAsDialogSubmission()) {
return SubmitDialog(dialogSubmission);
}
if(mDeferSubmission) {
// we are in an event handler, JS submitted so we have to
// defer this submission. let's remember it and return
@@ -683,9 +710,6 @@ HTMLFormElement::DoSubmit(WidgetEvent* aEvent)
return NS_OK;
}
//
// perform the submission
//
return SubmitSubmission(submission);
}
@@ -722,8 +746,10 @@ HTMLFormElement::BuildSubmission(HTMLFormSubmission** aFormSubmission,
//
// Dump the data into the submission object
//
rv = WalkFormElements(*aFormSubmission);
NS_ENSURE_SUBMIT_SUCCESS(rv);
if (!(*aFormSubmission)->GetAsDialogSubmission()) {
rv = WalkFormElements(*aFormSubmission);
NS_ENSURE_SUBMIT_SUCCESS(rv);
}
return NS_OK;
}
@@ -862,6 +888,22 @@ HTMLFormElement::SubmitSubmission(HTMLFormSubmission* aFormSubmission)
return rv;
}
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#submit-dialog
nsresult HTMLFormElement::SubmitDialog(DialogFormSubmission* aFormSubmission) {
mIsSubmitting = false;
// Close the dialog subject. If there is a result, let that be the return
// value.
HTMLDialogElement* dialog = aFormSubmission->DialogElement();
MOZ_ASSERT(dialog);
Optional<nsAString> retValue;
retValue = &aFormSubmission->ReturnValue();
dialog->Close(retValue);
return NS_OK;
}
nsresult
HTMLFormElement::DoSecureToInsecureSubmitCheck(nsIURI* aActionURL,
bool* aCancelSubmit)
+6
View File
@@ -483,6 +483,12 @@ protected:
*/
nsresult SubmitSubmission(HTMLFormSubmission* aFormSubmission);
/**
* Submit a form[method=dialog]
* @param aFormSubmission the submission object
*/
nsresult SubmitDialog(DialogFormSubmission* aFormSubmission);
/**
* Notify any submit observers of the submit.
*
+24
View File
@@ -944,6 +944,30 @@ HTMLFormSubmission::GetFromForm(nsGenericHTMLElement* aForm,
charset.AssignLiteral("UTF-8");
}
if (method == NS_FORM_METHOD_DIALOG) {
HTMLDialogElement* dialog = nullptr;
for (nsIContent* parent = aForm->GetParent(); parent;
parent = parent->GetParent()) {
dialog = HTMLDialogElement::FromContentOrNull(parent);
if (dialog) {
break;
}
}
// If there isn't one, or if it does not have an open attribute, do
// nothing.
if (!dialog || !dialog->Open()) {
return NS_ERROR_FAILURE;
}
nsAutoString result;
if (aOriginatingElement) {
aOriginatingElement->ResultForDialogSubmit(result);
}
*aFormSubmission = new DialogFormSubmission(result, charset, aOriginatingElement, dialog);
return NS_OK;
}
// Choose encoder
if (method == NS_FORM_METHOD_POST &&
enctype == NS_FORM_ENCTYPE_MULTIPART) {
+47
View File
@@ -7,6 +7,7 @@
#define mozilla_dom_HTMLFormSubmission_h
#include "mozilla/Attributes.h"
#include "mozilla/dom/HTMLDialogElement.h"
#include "nsCOMPtr.h"
#include "nsIContent.h"
#include "nsNCRFallbackEncoderWrapper.h"
@@ -121,6 +122,8 @@ public:
return mOriginatingElement.get();
}
virtual DialogFormSubmission* GetAsDialogSubmission() { return nullptr; }
protected:
/**
* Can only be constructed by subclasses.
@@ -168,6 +171,50 @@ private:
nsNCRFallbackEncoderWrapper mEncoder;
};
class DialogFormSubmission final : public HTMLFormSubmission {
public:
DialogFormSubmission(nsAString& aResult,
const nsACString& aCharset, Element* aSubmitter,
HTMLDialogElement* aDialogElement)
: HTMLFormSubmission(aCharset, aSubmitter)
, mDialogElement(aDialogElement)
, mReturnValue(aResult) {
}
nsresult AddNameValuePair(const nsAString& aName,
const nsAString& aValue) override {
MOZ_CRASH("This method should not be called");
return NS_OK;
}
nsresult AddNameBlobOrNullPair(const nsAString& aName, Blob* aBlob) override {
MOZ_CRASH("This method should not be called");
return NS_OK;
}
nsresult AddNameDirectoryPair(const nsAString& aName,
Directory* aDirectory) override {
MOZ_CRASH("This method should not be called");
return NS_OK;
}
nsresult GetEncodedSubmission(nsIURI* aURI, nsIInputStream** aPostDataStream) override {
MOZ_CRASH("This method should not be called");
return NS_OK;
}
DialogFormSubmission* GetAsDialogSubmission() override { return this; }
HTMLDialogElement* DialogElement() { return mDialogElement; }
nsString& ReturnValue() { return mReturnValue; }
private:
const RefPtr<HTMLDialogElement> mDialogElement;
nsString mReturnValue;
};
/**
* Handle multipart/form-data encoding, which does files as well as normal
* inputs. This always does POST.
+7
View File
@@ -14,6 +14,13 @@ static const nsAttrValue::EnumTable kFormMethodTable[] = {
{ nullptr, 0 }
};
static const nsAttrValue::EnumTable kFormMethodTableDialogEnabled[] = {
{"get", NS_FORM_METHOD_GET},
{"post", NS_FORM_METHOD_POST},
{"dialog", NS_FORM_METHOD_DIALOG},
{nullptr, 0}
};
// Default method is 'get'.
static const nsAttrValue::EnumTable* kFormDefaultMethod = &kFormMethodTable[0];
+23
View File
@@ -1482,6 +1482,26 @@ NS_IMPL_STRING_ATTR(HTMLInputElement, Placeholder, placeholder)
NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(HTMLInputElement, Type, type,
kInputDefaultType->tag)
void HTMLInputElement::ResultForDialogSubmit(nsAString& aResult) {
if (mType == NS_FORM_INPUT_IMAGE) {
// Get a property set by the frame to find out where it was clicked.
nsIntPoint* lastClickedPoint =
static_cast<nsIntPoint*>(GetProperty(nsGkAtoms::imageClickedPoint));
int32_t x, y;
if (lastClickedPoint) {
x = lastClickedPoint->x;
y = lastClickedPoint->y;
} else {
x = y = 0;
}
aResult.AppendInt(x);
aResult.AppendLiteral(",");
aResult.AppendInt(y);
} else {
GetAttr(kNameSpaceID_None, nsGkAtoms::value, aResult);
}
}
NS_IMETHODIMP
HTMLInputElement::GetAutocomplete(nsAString& aValue)
{
@@ -5916,6 +5936,9 @@ HTMLInputElement::ParseAttribute(int32_t aNamespaceID,
return aResult.ParseEnumValue(aValue, kFormMethodTable, false);
}
if (aAttribute == nsGkAtoms::formenctype) {
if (Preferences::GetBool("dom.dialog_element.enabled", true)) {
return aResult.ParseEnumValue(aValue, kFormMethodTableDialogEnabled, false);
}
return aResult.ParseEnumValue(aValue, kFormEnctypeTable, false);
}
if (aAttribute == nsGkAtoms::autocomplete) {
+2
View File
@@ -968,6 +968,8 @@ protected:
const nsAttrValue* aOldValue,
bool aNotify) override;
virtual void ResultForDialogSubmit(nsAString& aResult) override;
/**
* Dispatch a select event. Returns true if the event was not cancelled.
*/
+6
View File
@@ -324,6 +324,12 @@ HTMLScriptElement::GetCORSMode() const
return AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
}
mozilla::net::ReferrerPolicy
HTMLScriptElement::GetReferrerPolicy()
{
return GetReferrerPolicyAsEnum();
}
bool
HTMLScriptElement::HasScriptContent()
{
+9
View File
@@ -42,6 +42,7 @@ public:
virtual void GetScriptCharset(nsAString& charset) override;
virtual void FreezeExecutionAttrs(nsIDocument* aOwnerDoc) override;
virtual CORSMode GetCORSMode() const override;
virtual mozilla::net::ReferrerPolicy GetReferrerPolicy() override;
// nsIContent
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
@@ -96,6 +97,14 @@ public:
{
SetHTMLAttr(nsGkAtoms::integrity, aIntegrity, rv);
}
void SetReferrerPolicy(const nsAString& aReferrerPolicy, ErrorResult& aError)
{
SetHTMLAttr(nsGkAtoms::referrerpolicy, aReferrerPolicy, aError);
}
void GetReferrerPolicy(nsAString& aReferrerPolicy)
{
GetEnumAttr(nsGkAtoms::referrerpolicy, EmptyCString().get(), aReferrerPolicy);
}
bool Async();
void SetAsync(bool aValue, ErrorResult& rv);
bool NoModule();
+2 -2
View File
@@ -340,8 +340,8 @@ nsGenericHTMLElement::GetOffsetRect(CSSIntRect& aRect)
if (parent &&
parent->StylePosition()->mBoxSizing != StyleBoxSizing::Border) {
const nsStyleBorder* border = parent->StyleBorder();
origin.x -= border->GetComputedBorderWidth(NS_SIDE_LEFT);
origin.y -= border->GetComputedBorderWidth(NS_SIDE_TOP);
origin.x -= border->GetComputedBorderWidth(eSideLeft);
origin.y -= border->GetComputedBorderWidth(eSideTop);
}
// XXX We should really consider subtracting out padding for
+4
View File
@@ -861,6 +861,10 @@ public:
static bool
IsScrollGrabAllowed(JSContext*, JSObject*);
virtual inline void ResultForDialogSubmit(nsAString& aResult) {
GetAttr(kNameSpaceID_None, nsGkAtoms::value, aResult);
}
protected:
/**
* Add/remove this element to the documents name cache
+8 -9
View File
@@ -37,7 +37,6 @@ using namespace mozilla::dom;
using namespace mozilla::net;
static NS_DEFINE_CID(kDNSServiceCID, NS_DNSSERVICE_CID);
bool sDisablePrefetchHTTPSPref;
static bool sInitialized = false;
static nsIDNSService *sDNSService = nullptr;
static nsHTMLDNSPrefetch::nsDeferrals *sPrefetches = nullptr;
@@ -59,13 +58,6 @@ nsHTMLDNSPrefetch::Initialize()
sPrefetches->Activate();
Preferences::AddBoolVarCache(&sDisablePrefetchHTTPSPref,
"network.dns.disablePrefetchFromHTTPS");
// Default is false, so we need an explicit call to prime the cache.
sDisablePrefetchHTTPSPref =
Preferences::GetBool("network.dns.disablePrefetchFromHTTPS", true);
NS_IF_RELEASE(sDNSService);
nsresult rv;
rv = CallGetService(kDNSServiceCID, &sDNSService);
@@ -94,8 +86,15 @@ nsHTMLDNSPrefetch::Shutdown()
}
bool
nsHTMLDNSPrefetch::IsAllowed (nsIDocument *aDocument)
nsHTMLDNSPrefetch::IsAllowed(nsIDocument *aDocument)
{
// Do not use prefetch if the document's node principal is the system
// principal.
nsCOMPtr<nsIPrincipal> principal = aDocument->NodePrincipal();
if (nsContentUtils::IsSystemPrincipal(principal)) {
return false;
}
// There is no need to do prefetch on non UI scenarios such as XMLHttpRequest.
return aDocument->IsDNSPrefetchAllowed() && aDocument->GetWindow();
}
+1
View File
@@ -12,6 +12,7 @@ class nsIFormControl;
#define NS_FORM_METHOD_GET 0
#define NS_FORM_METHOD_POST 1
#define NS_FORM_METHOD_DIALOG 2
#define NS_FORM_ENCTYPE_URLENCODED 0
#define NS_FORM_ENCTYPE_MULTIPART 1
#define NS_FORM_ENCTYPE_TEXTPLAIN 2
+1
View File
@@ -16,6 +16,7 @@ namespace dom {
class Element;
class HTMLFieldSetElement;
class HTMLFormSubmission;
class DialogFormSubmission;
} // namespace dom
} // namespace mozilla
+1 -1
View File
@@ -24,7 +24,7 @@ SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(runTests);
function runTests() {
var elements = [ "iframe", "img", "a", "area", "link" ];
var elements = [ "iframe", "img", "a", "area", "link", "script"];
for (var i = 0; i < elements.length; ++i) {
reflectLimitedEnumerated({
+2
View File
@@ -13,6 +13,8 @@ XPIDL_SOURCES += [
'nsIDOMCSSImportRule.idl',
'nsIDOMCSSKeyframeRule.idl',
'nsIDOMCSSKeyframesRule.idl',
'nsIDOMCSSLayerBlockRule.idl',
'nsIDOMCSSLayerStatementRule.idl',
'nsIDOMCSSMediaRule.idl',
'nsIDOMCSSMozDocumentRule.idl',
'nsIDOMCSSPageRule.idl',
@@ -14,4 +14,5 @@ interface nsIDOMCSSImportRule : nsISupports
readonly attribute DOMString href;
readonly attribute nsIDOMMediaList media;
readonly attribute nsIDOMCSSStyleSheet styleSheet;
readonly attribute DOMString layerName;
};
@@ -0,0 +1,12 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsIDOMCSSGroupingRule.idl"
[scriptable, uuid(2865c2ba-ae78-4282-8eff-9b7a2d71f9eb)]
interface nsIDOMCSSLayerBlockRule : nsIDOMCSSGroupingRule
{
readonly attribute DOMString name;
};
@@ -0,0 +1,11 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
[scriptable, uuid(ec215b70-417e-41fa-8d48-8edd6d30aac3)]
interface nsIDOMCSSLayerStatementRule : nsISupports
{
};
+3
View File
@@ -44,6 +44,9 @@ interface nsIDOMCSSRule : nsISupports
const unsigned short COUNTER_STYLE_RULE = 11;
const unsigned short SUPPORTS_RULE = 12;
const unsigned short FONT_FEATURE_VALUES_RULE = 14;
const unsigned short RESERVED1_RULE = 15;
const unsigned short LAYER_BLOCK_RULE = 16;
const unsigned short LAYER_STATEMENT_RULE = 17;
readonly attribute unsigned short type;
attribute DOMString cssText;
-1
View File
@@ -136,7 +136,6 @@ public:
nsresult
GetEventTargetParent(EventChainPreVisitor& aVisitor) override
{
aVisitor.mForceContentDispatch = true;
return NS_OK;
}
+6 -12
View File
@@ -225,19 +225,13 @@ void VideoFrameContainer::SetCurrentFramesLocked(const gfx::IntSize& aIntrinsicS
nsTArray<ImageContainer::OwningImage> oldImages;
mImageContainer->GetCurrentImages(&oldImages);
ImageContainer::FrameID lastFrameIDForOldPrincipalHandle =
mFrameIDForPendingPrincipalHandle - 1;
if (mPendingPrincipalHandle != PRINCIPAL_HANDLE_NONE &&
((!oldImages.IsEmpty() &&
oldImages.LastElement().mFrameID >= lastFrameIDForOldPrincipalHandle) ||
(!aImages.IsEmpty() &&
aImages[0].mFrameID > lastFrameIDForOldPrincipalHandle))) {
// We are releasing the last FrameID prior to `lastFrameIDForOldPrincipalHandle`
// OR
// there are no FrameIDs prior to `lastFrameIDForOldPrincipalHandle` in the new
// set of images.
// This means that the old principal handle has been flushed out and we can
// notify our video element about this change.
(aImages.IsEmpty() ||
aImages[0].mFrameID >= mFrameIDForPendingPrincipalHandle)) {
// There are no FrameIDs prior to `mFrameIDForPendingPrincipalHandle`
// in the new set of images.
// This means that the old principal handle has been flushed out and we
// can notify our video element about this change.
RefPtr<VideoFrameContainer> self = this;
PrincipalHandle principalHandle = mPendingPrincipalHandle;
mLastPrincipalHandle = mPendingPrincipalHandle;
+30 -5
View File
@@ -89,6 +89,34 @@ GMPVideoi420FrameImpl::CheckFrameData(const GMPVideoi420FrameData& aFrameData)
return true;
}
bool
GMPVideoi420FrameImpl::CheckDimensions(int32_t aWidth, int32_t aHeight,
int32_t aStride_y,
int32_t aStride_u,
int32_t aStride_v, int32_t aSize_y,
int32_t aSize_u, int32_t aSize_v) {
if (aWidth < 1 || aHeight < 1 || aStride_y < aWidth || aSize_y < 1 ||
aSize_u < 1 || aSize_v < 1) {
return false;
}
auto halfWidth = (CheckedInt<int32_t>(aWidth) + 1) / 2;
if (!halfWidth.isValid() || aStride_u < halfWidth.value() ||
aStride_v < halfWidth.value()) {
return false;
}
auto height = CheckedInt<int32_t>(aHeight);
auto halfHeight = (height + 1) / 2;
auto minSizeY = height * aStride_y;
auto minSizeU = halfHeight * aStride_u;
auto minSizeV = halfHeight * aStride_v;
if (!minSizeY.isValid() || !minSizeU.isValid() || !minSizeV.isValid() ||
minSizeY.value() > aSize_y || minSizeU.value() > aSize_u ||
minSizeV.value() > aSize_v) {
return false;
}
return true;
}
bool
GMPVideoi420FrameImpl::CheckDimensions(int32_t aWidth, int32_t aHeight,
int32_t aStride_y, int32_t aStride_u, int32_t aStride_v)
@@ -179,11 +207,8 @@ GMPVideoi420FrameImpl::CreateFrame(int32_t aSize_y, const uint8_t* aBuffer_y,
MOZ_ASSERT(aBuffer_u);
MOZ_ASSERT(aBuffer_v);
if (aSize_y < 1 || aSize_u < 1 || aSize_v < 1) {
return GMPGenericErr;
}
if (!CheckDimensions(aWidth, aHeight, aStride_y, aStride_u, aStride_v)) {
if (!CheckDimensions(aWidth, aHeight, aStride_y, aStride_u, aStride_v,
aSize_y, aSize_u, aSize_v)) {
return GMPGenericErr;
}
+3
View File
@@ -65,6 +65,9 @@ public:
void ResetSize() override;
private:
bool CheckDimensions(int32_t aWidth, int32_t aHeight, int32_t aStride_y,
int32_t aStride_u, int32_t aStride_v, int32_t aSize_y,
int32_t aSize_u, int32_t aSize_v);
bool CheckDimensions(int32_t aWidth, int32_t aHeight,
int32_t aStride_y, int32_t aStride_u, int32_t aStride_v);
+25 -3
View File
@@ -31,6 +31,7 @@ mozilla::LogModule* GetMediaSourceSamplesLog()
return sLogModule;
}
#define SAMPLE_DEBUG(arg, ...) MOZ_LOG(GetMediaSourceSamplesLog(), mozilla::LogLevel::Debug, ("TrackBuffersManager(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
#define SAMPLE_DEBUGV(arg, ...) MOZ_LOG(GetMediaSourceSamplesLog(), mozilla::LogLevel::Verbose, ("TrackBuffersManager(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
namespace mozilla {
@@ -680,7 +681,11 @@ TrackBuffersManager::SegmentParserLoop()
if (mNewMediaSegmentStarted) {
if (NS_SUCCEEDED(newData) && mLastParsedEndTime.isSome() &&
start < mLastParsedEndTime.ref().ToMicroseconds()) {
MSE_DEBUG("Re-creating demuxer");
MSE_DEBUG("Re-creating demuxer, new start (%" PRId64
") is smaller than last parsed end time (%" PRId64 ")",
start,
mLastParsedEndTime.value());
mFrameEndTimeBeforeRecreateDemuxer = Some(end);
ResetDemuxingState();
return;
}
@@ -789,7 +794,15 @@ TrackBuffersManager::CreateDemuxerforMIMEType()
mType.LowerCaseEqualsLiteral("video/x-matroska") ||
mType.LowerCaseEqualsLiteral("audio/x-matroska") ||
mType.LowerCaseEqualsLiteral("audio/webm")) {
mInputDemuxer = new WebMDemuxer(mCurrentInputBuffer, true /* IsMediaSource*/ );
if (mFrameEndTimeBeforeRecreateDemuxer) {
MSE_DEBUG(
"CreateDemuxerFromMimeType: "
"mFrameEndTimeBeforeRecreateDemuxer=%" PRId64,
mFrameEndTimeBeforeRecreateDemuxer.value());
}
mInputDemuxer = new WebMDemuxer(mCurrentInputBuffer, true /* IsMediaSource*/,
mFrameEndTimeBeforeRecreateDemuxer);
mFrameEndTimeBeforeRecreateDemuxer.reset();
return;
}
@@ -797,6 +810,7 @@ TrackBuffersManager::CreateDemuxerforMIMEType()
if (mType.LowerCaseEqualsLiteral("video/mp4") ||
mType.LowerCaseEqualsLiteral("audio/mp4")) {
mInputDemuxer = new MP4Demuxer(mCurrentInputBuffer);
mFrameEndTimeBeforeRecreateDemuxer.reset();
return;
}
#endif
@@ -1193,9 +1207,11 @@ void
TrackBuffersManager::OnVideoDemuxCompleted(RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples)
{
MOZ_ASSERT(OnTaskQueue());
MSE_DEBUG("%d video samples demuxed", aSamples->mSamples.Length());
mVideoTracks.mDemuxRequest.Complete();
mVideoTracks.mQueuedSamples.AppendElements(aSamples->mSamples);
MSE_DEBUG("%zu video samples demuxed, queued-sz=%zu",
aSamples->mSamples.Length(),
mVideoTracks.mQueuedSamples.Length());
DoDemuxAudio();
}
@@ -1436,6 +1452,9 @@ TrackBuffersManager::ProcessFrames(TrackBuffer& aSamples, TrackData& aTrackData)
if (trackBuffer.mNeedRandomAccessPoint) {
// 1. If the coded frame is not a random access point, then drop the coded frame and jump to the top of the loop to start processing the next coded frame.
if (!sample->mKeyframe) {
SAMPLE_DEBUGV("skipping sample [%" PRId64 ",%" PRId64 "]",
sample->mTime,
sample->GetEndTime());
continue;
}
// 2. Set the need random access point flag on track buffer to false.
@@ -1496,6 +1515,7 @@ TrackBuffersManager::ProcessFrames(TrackBuffer& aSamples, TrackData& aTrackData)
// 3. Unset the last frame duration on all track buffers.
// 4. Unset the highest end timestamp on all track buffers.
// 5. Set the need random access point flag on all track buffers to true.
MSE_DEBUG("Resetting append state");
track->ResetAppendState();
}
// 6. Jump to the Loop Top step above to restart processing of the current coded frame.
@@ -1894,10 +1914,12 @@ TrackBuffersManager::RecreateParser(bool aReuseInitData)
// we can optimize this part. TODO
mParser = ContainerParser::CreateForMIMEType(mType);
if (aReuseInitData && mInitData) {
MSE_DEBUG("Using existing init data to reset parser");
int64_t start, end;
mParser->ParseStartAndEndTimestamps(mInitData, start, end);
mProcessedInput = mInitData->Length();
} else {
MSE_DEBUG("Resetting parser, not reusing init data");
mProcessedInput = 0;
}
}
@@ -492,6 +492,8 @@ private:
media::TimeIntervals mAudioBufferedRanges;
// MediaInfo of the first init segment read.
MediaInfo mInfo;
Maybe<int64_t> mFrameEndTimeBeforeRecreateDemuxer;
};
} // namespace mozilla
+12 -2
View File
@@ -22,10 +22,11 @@ public:
: mPacket(nullptr)
, mOffset(-1)
, mTimestamp(-1)
, mDefaultDuration(-1)
, mDuration(-1)
, mIsKeyframe(false) {}
bool Init(nestegg_packet* aPacket, int64_t aOffset, unsigned aTrack, bool aIsKeyframe)
bool Init(nestegg_packet* aPacket, nestegg* aContext, int64_t aOffset, unsigned aTrack, bool aIsKeyframe)
{
uint64_t timestamp_ns;
if (nestegg_packet_tstamp(aPacket, &timestamp_ns) == -1) {
@@ -44,6 +45,9 @@ public:
if (!nestegg_packet_duration(aPacket, &duration_ns)) {
mDuration = duration_ns / 1000;
}
if (!nestegg_track_default_duration(aContext, mTrack, &duration_ns)) {
mDefaultDuration = duration_ns / 1000;
}
return true;
}
@@ -51,6 +55,7 @@ public:
int64_t Offset() { MOZ_ASSERT(IsInitialized()); return mOffset; }
int64_t Timestamp() { MOZ_ASSERT(IsInitialized()); return mTimestamp; }
int64_t Duration() { MOZ_ASSERT(IsInitialized()); return mDuration; }
int64_t DefaultDuration() const { MOZ_ASSERT(IsInitialized()); return mDefaultDuration; }
unsigned Track() { MOZ_ASSERT(IsInitialized()); return mTrack; }
bool IsKeyframe() { MOZ_ASSERT(IsInitialized()); return mIsKeyframe; }
@@ -60,7 +65,7 @@ private:
nestegg_free_packet(mPacket);
}
bool IsInitialized() { return mOffset >= 0; }
bool IsInitialized() const { return mOffset >= 0; }
nestegg_packet* mPacket;
@@ -72,8 +77,13 @@ private:
int64_t mTimestamp;
// Packet duration in microseconds; -1 if unknown or retrieval failed.
// https://www.webmproject.org/docs/container/#BlockDuration
int64_t mDuration;
// Default duration in microseconds; -1 if unknown or retrieval failed.
// https://www.webmproject.org/docs/container/#Duration
int64_t mDefaultDuration;
// Track ID.
unsigned mTrack;
File diff suppressed because it is too large. Load diff
+5 -1
View File
@@ -92,7 +92,9 @@ public:
explicit WebMDemuxer(MediaResource* aResource);
// Indicate if the WebMDemuxer is to be used with MediaSource. In which
// case the demuxer will stop reads to the last known complete block.
WebMDemuxer(MediaResource* aResource, bool aIsMediaSource);
WebMDemuxer(MediaResource* aResource,
bool aIsMediaSource,
Maybe<int64_t> aFrameEndTimeBeforeRecreateDemuxer = Nothing());
RefPtr<InitPromise> Init() override;
@@ -227,6 +229,8 @@ private:
Maybe<int64_t> mLastAudioFrameTime;
Maybe<int64_t> mLastVideoFrameTime;
Maybe<int64_t> mVideoFrameEndTimeBeforeReset;
// Codec ID of audio track
int mAudioCodec;
// Codec ID of video track
+9
View File
@@ -1161,6 +1161,15 @@ nsPluginHost::GetPlugins(nsTArray<nsCOMPtr<nsIInternalPluginTag>>& aPluginArray,
}
plugin = plugin->mNext;
}
// Durstenfeld shuffle
size_t pluginCount = aPluginArray.Length();
if (pluginCount >= 2) {
for (size_t i = pluginCount - 1; i > 0; i--) {
size_t j = rand() % (i + 1);
std::swap(aPluginArray[i],aPluginArray[j]);
}
}
}
// FIXME-jsplugins Check users for order of fake v non-fake
+17 -7
View File
@@ -1307,9 +1307,8 @@ ScriptLoader::StartLoad(ScriptLoadRequest *aRequest, const nsAString &aType,
// According to the spec, module scripts have different behaviour to classic
// scripts and always use CORS.
securityFlags = nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS;
if (aRequest->CORSMode() == CORS_NONE) {
securityFlags |= nsILoadInfo::SEC_COOKIES_OMIT;
} else if (aRequest->CORSMode() == CORS_ANONYMOUS) {
if (aRequest->CORSMode() == CORS_NONE ||
aRequest->CORSMode() == CORS_ANONYMOUS) {
securityFlags |= nsILoadInfo::SEC_COOKIES_SAME_ORIGIN;
} else {
MOZ_ASSERT(aRequest->CORSMode() == CORS_USE_CREDENTIALS);
@@ -1563,7 +1562,7 @@ ScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
// Step 15. and later in the HTML5 spec
nsresult rv = NS_OK;
RefPtr<ScriptLoadRequest> request;
mozilla::net::ReferrerPolicy ourRefPolicy = mDocument->GetReferrerPolicy();
mozilla::net::ReferrerPolicy referrerPolicy = GetReferrerPolicy(aElement);
if (aElement->GetScriptExternal()) {
// external script
nsCOMPtr<nsIURI> scriptURI = aElement->GetScriptURI();
@@ -1593,7 +1592,7 @@ ScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
aElement->GetScriptCharset(elementCharset);
if (elementCharset.Equals(preloadCharset) &&
ourCORSMode == request->CORSMode() &&
ourRefPolicy == request->ReferrerPolicy() &&
referrerPolicy == request->ReferrerPolicy() &&
scriptKind == request->mKind) {
rv = CheckContentPolicy(mDocument, aElement, request->mURI, type, false);
if (NS_FAILED(rv)) {
@@ -1639,7 +1638,7 @@ ScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
nsCOMPtr<nsIPrincipal> principal = scriptContent->NodePrincipal();
request = CreateLoadRequest(scriptKind, scriptURI, aElement, principal,
ourCORSMode, sriMetadata, ourRefPolicy);
ourCORSMode, sriMetadata, referrerPolicy);
request->mIsInline = false;
request->SetScriptMode(aElement->GetScriptDeferred(),
aElement->GetScriptAsync());
@@ -1760,7 +1759,7 @@ ScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
mDocument->NodePrincipal(),
CORS_NONE,
SRIMetadata(), // SRI doesn't apply
ourRefPolicy);
referrerPolicy);
request->mIsInline = true;
request->mLineNo = aElement->GetScriptLineNumber();
@@ -1826,6 +1825,17 @@ ScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
return ProcessRequest(request) == NS_ERROR_HTMLPARSER_BLOCK;
}
mozilla::net::ReferrerPolicy
ScriptLoader::GetReferrerPolicy(nsIScriptElement* aElement)
{
mozilla::net::ReferrerPolicy scriptReferrerPolicy =
aElement->GetReferrerPolicy();
if (scriptReferrerPolicy != mozilla::net::RP_Unset) {
return scriptReferrerPolicy;
}
return mDocument->GetReferrerPolicy();
}
namespace {
class NotifyOffThreadScriptLoadCompletedRunnable : public Runnable
+6
View File
@@ -619,6 +619,12 @@ private:
void ContinueParserAsync(ScriptLoadRequest* aParserBlockingRequest);
/**
* Given a script element, get the referrer policy that should be applied to
* load requests.
*/
mozilla::net::ReferrerPolicy GetReferrerPolicy(nsIScriptElement* aElement);
/**
* Helper function to check the content policy for a given request.
*/
+9
View File
@@ -16,6 +16,7 @@
#include "nsContentCreatorFunctions.h"
#include "nsIDOMHTMLScriptElement.h"
#include "mozilla/CORSMode.h"
#include "mozilla/net/ReferrerPolicy.h"
#define NS_ISCRIPTELEMENT_IID \
{ 0xe60fca9b, 0x1b96, 0x4e4e, \
@@ -263,6 +264,14 @@ public:
return mozilla::CORS_NONE;
}
/**
* Get referrer policy of the script element
*/
virtual mozilla::net::ReferrerPolicy GetReferrerPolicy()
{
return mozilla::net::RP_Unset;
}
/**
* Fire an error event
*/
+82 -3
View File
@@ -333,6 +333,78 @@ nsMixedContentBlocker::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
return NS_OK;
}
bool nsMixedContentBlocker::IsPotentiallyTrustworthyLoopbackURL(nsIURI* aURL) {
nsAutoCString host;
nsresult rv = aURL->GetHost(host);
NS_ENSURE_SUCCESS(rv, false);
return host.EqualsLiteral("127.0.0.1") || host.EqualsLiteral("::1") ||
host.EqualsLiteral("localhost");
}
bool nsMixedContentBlocker::IsPotentiallyTrustworthyOrigin(nsIURI* aURI) {
// The following implements:
// https://w3c.github.io/webappsec-secure-contexts/#is-origin-trustworthy
nsAutoCString scheme;
nsresult rv = aURI->GetScheme(scheme);
if (NS_FAILED(rv)) {
return false;
}
// Blobs are expected to inherit their principal so we don't expect to have
// a codebase principal with scheme 'blob' here. We can't assert that though
// since someone could mess with a non-blob URI to give it that scheme.
NS_WARNING_ASSERTION(!scheme.EqualsLiteral("blob"),
"IsPotentiallyTrustworthyOrigin ignoring blob scheme");
// According to the specification, the user agent may choose to extend the
// trust to other, vendor-specific URL schemes. We use this for "resource:",
// which is technically a substituting protocol handler that is not limited to
// local resource mapping, but in practice is never mapped remotely as this
// would violate assumptions a lot of code makes.
if (scheme.EqualsLiteral("https") ||
scheme.EqualsLiteral("file") ||
scheme.EqualsLiteral("resource") ||
scheme.EqualsLiteral("app") ||
scheme.EqualsLiteral("moz-extension") ||
scheme.EqualsLiteral("wss")) {
return true;
}
nsAutoCString host;
rv = aURI->GetHost(host);
if (NS_FAILED(rv)) {
return false;
}
if (IsPotentiallyTrustworthyLoopbackURL(aURI)) {
return true;
}
// If a host is not considered secure according to the default algorithm, then
// check to see if it has been whitelisted by the user. We only apply this
// whitelist for network resources, i.e., those with scheme "http" or "ws".
// The pref should contain a comma-separated list of hostnames.
if (!scheme.EqualsLiteral("http") && !scheme.EqualsLiteral("ws")) {
return false;
}
nsAdoptingCString whitelist = Preferences::GetCString("dom.securecontext.whitelist");
if (whitelist) {
nsCCharSeparatedTokenizer tokenizer(whitelist, ',');
while (tokenizer.hasMoreTokens()) {
const nsCSubstring& allowedHost = tokenizer.nextToken();
if (host.Equals(allowedHost)) {
return true;
}
}
}
return false;
}
/* This version of ShouldLoad() is non-static and called by the Content Policy
* API and AsyncOnChannelRedirect(). See nsIContentPolicy::ShouldLoad()
@@ -666,6 +738,16 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
*aDecision = REJECT_REQUEST;
return NS_OK;
}
bool isHttpScheme = false;
rv = innerContentLocation->SchemeIs("http", &isHttpScheme);
NS_ENSURE_SUCCESS(rv, rv);
// Allow http requests for trusted origins (e.g. localhost or explicitly trusted contexts)
if (isHttpScheme && IsPotentiallyTrustworthyOrigin(innerContentLocation)) {
*aDecision = ACCEPT;
return NS_OK;
}
// The page might have set the CSP directive 'upgrade-insecure-requests'. In such
// a case allow the http: load to succeed with the promise that the channel will
@@ -678,9 +760,6 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
// we only have to check against http: here. Skip mixed content blocking if the
// subresource load uses http: and the CSP directive 'upgrade-insecure-requests'
// is present on the page.
bool isHttpScheme = false;
rv = innerContentLocation->SchemeIs("http", &isHttpScheme);
NS_ENSURE_SUCCESS(rv, rv);
nsIDocument* document = docShell->GetDocument();
MOZ_ASSERT(document, "Expected a document");
if (isHttpScheme && document->GetUpgradeInsecureRequests(isPreload)) {
Loaded 100 of 291 files, more files were not shown because too many files have changed in this diff. Show more