Compare commits
312
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a731633d7b | ||
|
|
cd2ffb4b8f | ||
|
|
df9ab936f2 | ||
|
|
8c7ca10cfe | ||
|
|
0a5ad190c3 | ||
|
|
97b0520d7b | ||
|
|
b33a151836 | ||
|
|
32ca14f34b | ||
|
|
0da8e0b496 | ||
|
|
473e75d5aa | ||
|
|
28613ba836 | ||
|
|
8a5b121489 | ||
|
|
9550c68d7a | ||
|
|
54f44bb628 | ||
|
|
22fc220354 | ||
|
|
6d504711a0 | ||
|
|
60ea1e85f5 | ||
|
|
a20f208834 | ||
|
|
a1f53ada59 | ||
|
|
157a4abbcc | ||
|
|
b3a4b8361e | ||
|
|
41e5925b42 | ||
|
|
8dc520647d | ||
|
|
e8275b9a1e | ||
|
|
ad7526fe70 | ||
|
|
ccee9ea5b7 | ||
|
|
fda8403f56 | ||
|
|
3c8bc3da7c | ||
|
|
be415c44c7 | ||
|
|
a1e6132772 | ||
|
|
9815e4bdf0 | ||
|
|
d0b2595322 | ||
|
|
b14d245a8a | ||
|
|
66ab2fa3da | ||
|
|
4d80ed3d51 | ||
|
|
8baaecd89c | ||
|
|
aaedcc45fb | ||
|
|
88da01c294 | ||
|
|
65b37410ca | ||
|
|
6a3d5769d0 | ||
|
|
1d86d37828 | ||
|
|
9b86872d37 | ||
|
|
f0abf6273c | ||
|
|
76bacde2ae | ||
|
|
9fceb389c1 | ||
|
|
c30898ce33 | ||
|
|
b118bab81f | ||
|
|
ae8eb4d4c4 | ||
|
|
793da7dd62 | ||
|
|
16abf27e65 | ||
|
|
cdc2a22c79 | ||
|
|
de35c43f12 | ||
|
|
11d14ae59f | ||
|
|
d585e25e27 | ||
|
|
4ff7606b6a | ||
|
|
cce2bc9677 | ||
|
|
35c26c6c19 | ||
|
|
8f35c37a9e | ||
|
|
efdc2af8ab | ||
|
|
0ddd00f195 | ||
|
|
20f0905b33 | ||
|
|
8e09aff187 | ||
|
|
44c47c5038 | ||
|
|
ecdeefc4dd | ||
|
|
81089ff094 | ||
|
|
30e4959bd3 | ||
|
|
33ec695ac0 | ||
|
|
e9ee12c988 | ||
|
|
dd57b9273c | ||
|
|
be16123ddc | ||
|
|
e9360fae13 | ||
|
|
2896724eaf | ||
|
|
dada39db23 | ||
|
|
5496e4f391 | ||
|
|
13a8e78881 | ||
|
|
bdad2357a1 | ||
|
|
881c1e5f18 | ||
|
|
ce21c398d7 | ||
|
|
c895d35a7a | ||
|
|
69ed4e4b4e | ||
|
|
7c8262e8c3 | ||
|
|
4e2e9be6ab | ||
|
|
5ee844f710 | ||
|
|
b1cd96989b | ||
|
|
a7888b8cf2 | ||
|
|
944cf0dda9 | ||
|
|
623c44226a | ||
|
|
1e88448ddf | ||
|
|
5e21bf1d54 | ||
|
|
04fb9eaa6a | ||
|
|
b36e606158 | ||
|
|
18e74277b3 | ||
|
|
178382e4ce | ||
|
|
7832dded37 | ||
|
|
d53b11c9dc | ||
|
|
0e9957c412 | ||
|
|
28f67bddcf | ||
|
|
59f7a2cdb4 | ||
|
|
e3d81b698e | ||
|
|
0a8530b916 | ||
|
|
e6b48cb648 | ||
|
|
c220c30bbb | ||
|
|
8dc04fc24b | ||
|
|
461a9e86b2 | ||
|
|
2073a7f1c9 | ||
|
|
66b9ddfd32 | ||
|
|
ac68f8cf6c | ||
|
|
4889e6dbbd | ||
|
|
a4ab3fc59d | ||
|
|
e8417acbff | ||
|
|
d4098037a4 | ||
|
|
f107de8a90 | ||
|
|
d3067ffdda | ||
|
|
4ce361d9ba | ||
|
|
786417cf0f | ||
|
|
16fce4341d | ||
|
|
3bf1b83591 | ||
|
|
2bdbca39b2 | ||
|
|
8ec7618633 | ||
|
|
0a5784d3ce | ||
|
|
7dc9aa0585 | ||
|
|
a399acd57c | ||
|
|
6184ed7555 | ||
|
|
31d8779a22 | ||
|
|
5007e7c498 | ||
|
|
07fe89e26f | ||
|
|
4234b3a36b | ||
|
|
6c82d043a1 | ||
|
|
fa52fa60b7 | ||
|
|
b4ac6a7dcb | ||
|
|
a6ef90b183 | ||
|
|
99aa809cb8 | ||
|
|
6da9e3c6b9 | ||
|
|
5483f807c2 | ||
|
|
e80e4595b9 | ||
|
|
551c418932 | ||
|
|
832d84d2c0 | ||
|
|
cf4ad4e969 | ||
|
|
6376eceaeb | ||
|
|
074f23467b | ||
|
|
741abd440e | ||
|
|
0749a35be9 | ||
|
|
cd87677798 | ||
|
|
0ab5c6474c | ||
|
|
7a0b23aab8 | ||
|
|
c09eca89e4 | ||
|
|
04c770c8c8 | ||
|
|
bf914e9975 | ||
|
|
180543f6c3 | ||
|
|
2e6782afb5 | ||
|
|
758618b605 | ||
|
|
58cfb9acc2 | ||
|
|
4c9689f680 | ||
|
|
43f91872bd | ||
|
|
840ecb5262 | ||
|
|
3a7d5d01cc | ||
|
|
d44c61bf60 | ||
|
|
99118e38e1 | ||
|
|
a595451104 | ||
|
|
597a6996f1 | ||
|
|
c4e1022f57 | ||
|
|
52940bc44c | ||
|
|
9c6a8450b3 | ||
|
|
bbbfd00f95 | ||
|
|
e6c346c36f | ||
|
|
d216db11e7 | ||
|
|
0db3f512ea | ||
|
|
54e3d74002 | ||
|
|
f7b2f0a665 | ||
|
|
dd68cb9b3d | ||
|
|
6a3907dae4 | ||
|
|
7d21d02d53 | ||
|
|
a18c27ddde | ||
|
|
f9ddbe3640 | ||
|
|
406fc463e0 | ||
|
|
28208f1d3e | ||
|
|
6bb671bcdd | ||
|
|
33ad27614a | ||
|
|
229f841295 | ||
|
|
d41ba28f52 | ||
|
|
8f89965f50 | ||
|
|
e0103f3d5b | ||
|
|
64c8c65cf4 | ||
|
|
499b287394 | ||
|
|
00a5321c95 | ||
|
|
fd26b84536 | ||
|
|
e57998f68b | ||
|
|
ed88b99849 | ||
|
|
7a697172f3 | ||
|
|
3c4f414db7 | ||
|
|
c4b0715baa | ||
|
|
54fbb5c75c | ||
|
|
71416f9b79 | ||
|
|
d56573bb9c | ||
|
|
22ed46f7cc | ||
|
|
3c70b297c7 | ||
|
|
0cea94242a | ||
|
|
d84323905b | ||
|
|
e8f95f974f | ||
|
|
53319e5df6 | ||
|
|
a8bf089e8a | ||
|
|
0405d843be | ||
|
|
2077cdb41e | ||
|
|
43a8113072 | ||
|
|
14d115cfe3 | ||
|
|
8db81508a1 | ||
|
|
4083a9abf7 | ||
|
|
f576d8f0fe | ||
|
|
37d09da24e | ||
|
|
7e9efb0f27 | ||
|
|
93313b0ce3 | ||
|
|
fb657f7a1e | ||
|
|
72d4c0b8df | ||
|
|
c199dd22e6 | ||
|
|
e62385604d | ||
|
|
a0014ac6e9 | ||
|
|
dd6749f7dd | ||
|
|
e2fc7a9d49 | ||
|
|
950275abe6 | ||
|
|
ea35625369 | ||
|
|
0f9746b6e5 | ||
|
|
97ed13a9f9 | ||
|
|
d163c367d9 | ||
|
|
9bf83c6a78 | ||
|
|
bec4d0ecdc | ||
|
|
1ef7d17528 | ||
|
|
0b6548613a | ||
|
|
004b231d03 | ||
|
|
4c193edcaf | ||
|
|
b7f890e02e | ||
|
|
fce396323d | ||
|
|
a8511d983c | ||
|
|
e17a17766e | ||
|
|
76a4af3406 | ||
|
|
5d4200f56d | ||
|
|
41e477e2ce | ||
|
|
e5557d43d6 | ||
|
|
650f6b5eb3 | ||
|
|
90d19b0a31 | ||
|
|
f7bb7e81e3 | ||
|
|
016a21c414 | ||
|
|
e387308d9b | ||
|
|
738190dfde | ||
|
|
4503b51a4a | ||
|
|
56925e1f4a | ||
|
|
72a6fd4d2a | ||
|
|
5b862aa38c | ||
|
|
1aa6cdcc1d | ||
|
|
2cbd6d3699 | ||
|
|
4dda3f6039 | ||
|
|
6ec385fbdb | ||
|
|
8e6ce5fae7 | ||
|
|
6bbb9f062b | ||
|
|
01dfbc928f | ||
|
|
3d4c410091 | ||
|
|
186782301c | ||
|
|
42331663e6 | ||
|
|
8573c572fb | ||
|
|
f50503df9c | ||
|
|
5840b63cca | ||
|
|
45a4aaf7e0 | ||
|
|
49f597e7fb | ||
|
|
bf004bb63b | ||
|
|
08fc057471 | ||
|
|
704318ea0a | ||
|
|
bbb717ec12 | ||
|
|
515c46e695 | ||
|
|
d7e5ad445c | ||
|
|
ca596f2823 | ||
|
|
3d44a0b7f0 | ||
|
|
32f1ff0f8d | ||
|
|
53c9b77ed4 | ||
|
|
e6733c9278 | ||
|
|
6ff1c0c52f | ||
|
|
19f08038f0 | ||
|
|
4c9eab4d26 | ||
|
|
7a1cb50405 | ||
|
|
db86d423e5 | ||
|
|
3fd2f61949 | ||
|
|
1674f8f750 | ||
|
|
cc533eaee5 | ||
|
|
59c26110c1 | ||
|
|
a2c7b5f1d9 | ||
|
|
9d51b9d06a | ||
|
|
e86aac28b8 | ||
|
|
88925e150b | ||
|
|
9abc9b2b78 | ||
|
|
859fbc139a | ||
|
|
d8109fa9a0 | ||
|
|
e055747038 | ||
|
|
df23f78ad1 | ||
|
|
20799ce18c | ||
|
|
08d22f03ea | ||
|
|
ba8fb9dc58 | ||
|
|
16cd53bd8d | ||
|
|
25a33c7123 | ||
|
|
5cf46e2f87 | ||
|
|
3a97503b36 | ||
|
|
bac01e30fd | ||
|
|
5b814fffd6 | ||
|
|
6ea0acf750 | ||
|
|
5222f6e9da | ||
|
|
244277a3fa | ||
|
|
2d31ebf6b6 | ||
|
|
bc8543bf79 | ||
|
|
ce285b6f2d | ||
|
|
32f3f8826f | ||
|
|
a2b56b295b | ||
|
|
90773547e7 | ||
|
|
282b791acb | ||
|
|
1f8d508258 | ||
|
|
42e4816771 |
No files matched your search
@@ -22,5 +22,5 @@
|
||||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||
# don't change CLOBBER for WebIDL changes any more.
|
||||
|
||||
Clobber for NSS Update
|
||||
Clobber for incremental customElements v1 landing
|
||||
|
||||
@@ -34,3 +34,6 @@ and other community members.
|
||||
If you fork this repository to perform your own work on it, please consider offering
|
||||
improvement patches upstream to its origin to mutually improve the platform and build
|
||||
a future for XUL.
|
||||
|
||||
## Looking for Pale Moon and Basilisk?
|
||||
As of [`Issue #969`](https://github.com/MoonchildProductions/UXP/issues/969), release versions `29.0.0` and `2020.03.04` respectively, they have been split off into their own dedicated repositories located at [`MoonchildProductions/Pale-Moon`](https://github.com/MoonchildProductions/Pale-Moon) and [`MoonchildProductions/Basilisk`](https://github.com/MoonchildProductions/Basilisk).
|
||||
@@ -175,23 +175,17 @@ HTMLTableCellAccessible::Table() const
|
||||
uint32_t
|
||||
HTMLTableCellAccessible::ColIdx() const
|
||||
{
|
||||
nsITableCellLayout* cellLayout = GetCellLayout();
|
||||
NS_ENSURE_TRUE(cellLayout, 0);
|
||||
|
||||
int32_t colIdx = 0;
|
||||
cellLayout->GetColIndex(colIdx);
|
||||
return colIdx > 0 ? static_cast<uint32_t>(colIdx) : 0;
|
||||
nsTableCellFrame* cellFrame = GetCellFrame();
|
||||
NS_ENSURE_TRUE(cellFrame, 0);
|
||||
return cellFrame->ColIndex();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
HTMLTableCellAccessible::RowIdx() const
|
||||
{
|
||||
nsITableCellLayout* cellLayout = GetCellLayout();
|
||||
NS_ENSURE_TRUE(cellLayout, 0);
|
||||
|
||||
int32_t rowIdx = 0;
|
||||
cellLayout->GetRowIndex(rowIdx);
|
||||
return rowIdx > 0 ? static_cast<uint32_t>(rowIdx) : 0;
|
||||
nsTableCellFrame* cellFrame = GetCellFrame();
|
||||
NS_ENSURE_TRUE(cellFrame, 0);
|
||||
return cellFrame->RowIndex();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
@@ -285,6 +279,12 @@ HTMLTableCellAccessible::GetCellLayout() const
|
||||
return do_QueryFrame(mContent->GetPrimaryFrame());
|
||||
}
|
||||
|
||||
nsTableCellFrame*
|
||||
HTMLTableCellAccessible::GetCellFrame() const
|
||||
{
|
||||
return do_QueryFrame(mContent->GetPrimaryFrame());
|
||||
}
|
||||
|
||||
nsresult
|
||||
HTMLTableCellAccessible::GetCellIndexes(int32_t& aRowIdx, int32_t& aColIdx) const
|
||||
{
|
||||
@@ -520,11 +520,9 @@ HTMLTableAccessible::SelectedCellCount()
|
||||
if (!cellFrame || !cellFrame->IsSelected())
|
||||
continue;
|
||||
|
||||
int32_t startRow = -1, startCol = -1;
|
||||
cellFrame->GetRowIndex(startRow);
|
||||
cellFrame->GetColIndex(startCol);
|
||||
if (startRow >= 0 && (uint32_t)startRow == rowIdx &&
|
||||
startCol >= 0 && (uint32_t)startCol == colIdx)
|
||||
uint32_t startRow = cellFrame->RowIndex();
|
||||
uint32_t startCol = cellFrame->ColIndex();
|
||||
if (startRow == rowIdx && startCol == colIdx)
|
||||
count++;
|
||||
}
|
||||
}
|
||||
@@ -570,11 +568,9 @@ HTMLTableAccessible::SelectedCells(nsTArray<Accessible*>* aCells)
|
||||
if (!cellFrame || !cellFrame->IsSelected())
|
||||
continue;
|
||||
|
||||
int32_t startCol = -1, startRow = -1;
|
||||
cellFrame->GetRowIndex(startRow);
|
||||
cellFrame->GetColIndex(startCol);
|
||||
if ((startRow >= 0 && (uint32_t)startRow != rowIdx) ||
|
||||
(startCol >= 0 && (uint32_t)startCol != colIdx))
|
||||
uint32_t startRow = cellFrame->RowIndex();
|
||||
uint32_t startCol = cellFrame->ColIndex();
|
||||
if (startRow != rowIdx || startCol != colIdx)
|
||||
continue;
|
||||
|
||||
Accessible* cell = mDoc->GetAccessible(cellFrame->GetContent());
|
||||
@@ -597,11 +593,9 @@ HTMLTableAccessible::SelectedCellIndices(nsTArray<uint32_t>* aCells)
|
||||
if (!cellFrame || !cellFrame->IsSelected())
|
||||
continue;
|
||||
|
||||
int32_t startRow = -1, startCol = -1;
|
||||
cellFrame->GetColIndex(startCol);
|
||||
cellFrame->GetRowIndex(startRow);
|
||||
if (startRow >= 0 && (uint32_t)startRow == rowIdx &&
|
||||
startCol >= 0 && (uint32_t)startCol == colIdx)
|
||||
uint32_t startCol = cellFrame->ColIndex();
|
||||
uint32_t startRow = cellFrame->RowIndex();
|
||||
if (startRow == rowIdx && startCol == colIdx)
|
||||
aCells->AppendElement(CellIndexAt(rowIdx, colIdx));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "TableCellAccessible.h"
|
||||
|
||||
class nsITableCellLayout;
|
||||
class nsTableCellFrame;
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
@@ -53,6 +54,11 @@ protected:
|
||||
*/
|
||||
nsITableCellLayout* GetCellLayout() const;
|
||||
|
||||
/**
|
||||
* Return the table cell frame.
|
||||
*/
|
||||
nsTableCellFrame* GetCellFrame() const;
|
||||
|
||||
/**
|
||||
* Return row and column indices of the cell.
|
||||
*/
|
||||
|
||||
+2
-15
@@ -8,19 +8,6 @@ dnl ICU library, as well as a few other things.
|
||||
AC_DEFUN([MOZ_CONFIG_ICU], [
|
||||
|
||||
ICU_LIB_NAMES=
|
||||
MOZ_SYSTEM_ICU=
|
||||
MOZ_ARG_WITH_BOOL(system-icu,
|
||||
[ --with-system-icu
|
||||
Use system ICU (located with pkgconfig)],
|
||||
MOZ_SYSTEM_ICU=1)
|
||||
|
||||
if test -n "$MOZ_SYSTEM_ICU"; then
|
||||
PKG_CHECK_MODULES(MOZ_ICU, icu-i18n >= 58.1)
|
||||
CFLAGS="$CFLAGS $MOZ_ICU_CFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $MOZ_ICU_CFLAGS"
|
||||
fi
|
||||
|
||||
AC_SUBST(MOZ_SYSTEM_ICU)
|
||||
|
||||
dnl We always use ICU.
|
||||
USE_ICU=1
|
||||
@@ -51,7 +38,7 @@ if test -n "$USE_ICU"; then
|
||||
dnl We also don't do it on Windows because sometimes the file goes
|
||||
dnl missing -- possibly due to overzealous antivirus software? --
|
||||
dnl which prevents the browser from starting up :(
|
||||
if test -z "$JS_STANDALONE" -a -z "$MOZ_SYSTEM_ICU" -a "$OS_TARGET" != WINNT -a "$MOZ_WIDGET_TOOLKIT" != "android"; then
|
||||
if test -z "$JS_STANDALONE" -a "$OS_TARGET" != WINNT -a "$MOZ_WIDGET_TOOLKIT" != "android"; then
|
||||
MOZ_ICU_DATA_ARCHIVE=1
|
||||
else
|
||||
MOZ_ICU_DATA_ARCHIVE=
|
||||
@@ -64,7 +51,7 @@ AC_SUBST(USE_ICU)
|
||||
AC_SUBST(ICU_DATA_FILE)
|
||||
AC_SUBST(MOZ_ICU_DATA_ARCHIVE)
|
||||
|
||||
if test -n "$USE_ICU" -a -z "$MOZ_SYSTEM_ICU"; then
|
||||
if test -n "$USE_ICU"; then
|
||||
if test -z "$YASM" -a -z "$GNU_AS" -a "$COMPILE_ENVIRONMENT"; then
|
||||
AC_MSG_ERROR([Building ICU requires either yasm or a GNU assembler. If you do not have either of those available for this platform you must use --without-intl-api])
|
||||
fi
|
||||
|
||||
@@ -42,15 +42,6 @@ if test "$MOZ_BUILD_APP" != js || test -n "$JS_STANDALONE"; then
|
||||
_IS_OUTER_CONFIGURE=1
|
||||
fi
|
||||
|
||||
MOZ_ARG_WITH_BOOL(system-nspr,
|
||||
[ --with-system-nspr Use an NSPR that is already built and installed.
|
||||
Use the 'nspr-config' script in the current path,
|
||||
or look for the script in the directories given with
|
||||
--with-nspr-exec-prefix or --with-nspr-prefix.
|
||||
(Those flags are only checked if you specify
|
||||
--with-system-nspr.)],
|
||||
_USE_SYSTEM_NSPR=1 )
|
||||
|
||||
JS_POSIX_NSPR=unset
|
||||
ifdef([CONFIGURING_JS],[
|
||||
if test -n "$JS_STANDALONE"; then
|
||||
@@ -71,7 +62,6 @@ ifdef([CONFIGURING_JS],[
|
||||
])
|
||||
|
||||
dnl Pass at most one of
|
||||
dnl --with-system-nspr
|
||||
dnl --with-nspr-cflags/libs
|
||||
dnl --enable-nspr-build
|
||||
dnl --enable-posix-nspr-emulation
|
||||
@@ -79,10 +69,6 @@ dnl --enable-posix-nspr-emulation
|
||||
AC_MSG_CHECKING([NSPR selection])
|
||||
nspr_opts=
|
||||
which_nspr=default
|
||||
if test -n "$_USE_SYSTEM_NSPR"; then
|
||||
nspr_opts="x$nspr_opts"
|
||||
which_nspr="system"
|
||||
fi
|
||||
if test -n "$NSPR_CFLAGS" -o -n "$NSPR_LIBS"; then
|
||||
nspr_opts="x$nspr_opts"
|
||||
which_nspr="command-line"
|
||||
@@ -136,11 +122,7 @@ fi
|
||||
# anything itself.
|
||||
if test -n "$_IS_OUTER_CONFIGURE"; then
|
||||
|
||||
if test -n "$_USE_SYSTEM_NSPR"; then
|
||||
AM_PATH_NSPR($NSPR_MINVER, [MOZ_SYSTEM_NSPR=1], [AC_MSG_ERROR([you do not have NSPR installed or your version is older than $NSPR_MINVER.])])
|
||||
fi
|
||||
|
||||
if test -n "$MOZ_SYSTEM_NSPR" -o -n "$NSPR_CFLAGS" -o -n "$NSPR_LIBS"; then
|
||||
if test -n "$NSPR_CFLAGS" -o -n "$NSPR_LIBS"; then
|
||||
_SAVE_CFLAGS=$CFLAGS
|
||||
CFLAGS="$CFLAGS $NSPR_CFLAGS"
|
||||
AC_TRY_COMPILE([#include "prtypes.h"],
|
||||
@@ -178,19 +160,7 @@ AC_SUBST(NSPR_INCLUDE_DIR)
|
||||
AC_SUBST(NSPR_LIB_DIR)
|
||||
|
||||
PKGCONF_REQUIRES_PRIVATE="Requires.private: nspr"
|
||||
if test -n "$MOZ_SYSTEM_NSPR"; then
|
||||
_SAVE_CFLAGS=$CFLAGS
|
||||
CFLAGS="$CFLAGS $NSPR_CFLAGS"
|
||||
AC_TRY_COMPILE([#include "prlog.h"],
|
||||
[#ifndef PR_STATIC_ASSERT
|
||||
#error PR_STATIC_ASSERT not defined
|
||||
#endif],
|
||||
,
|
||||
AC_MSG_ERROR([system NSPR does not support PR_STATIC_ASSERT]))
|
||||
CFLAGS=$_SAVE_CFLAGS
|
||||
# piggy back on $MOZ_SYSTEM_NSPR to set a variable for the nspr check for js.pc
|
||||
PKGCONF_REQUIRES_PRIVATE="Requires.private: nspr >= $NSPR_MINVER"
|
||||
elif test -n "$JS_POSIX_NSPR"; then
|
||||
if test -n "$JS_POSIX_NSPR"; then
|
||||
PKGCONF_REQUIRES_PRIVATE=
|
||||
fi
|
||||
AC_SUBST([PKGCONF_REQUIRES_PRIVATE])
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
# Define indicating that this build is prior to one of the early betas. To be
|
||||
# unset mid-way through the beta cycle.
|
||||
EARLY_BETA_OR_EARLIER=
|
||||
@@ -33,14 +33,9 @@ if ('MOZ_OFFICIAL_BRANDING' in listConfig) or (strBrandingDirectory.endswith("br
|
||||
# Applies to Pale Moon and Basilisk
|
||||
if ('MC_BASILISK' in listConfig) or ('MC_PALEMOON' in listConfig):
|
||||
listViolations += [
|
||||
'MOZ_SYSTEM_NSS',
|
||||
'MOZ_SYSTEM_NSPR',
|
||||
'MOZ_SYSTEM_JPEG',
|
||||
'MOZ_SYSTEM_ZLIB',
|
||||
'MOZ_SYSTEM_BZ2',
|
||||
'MOZ_SYSTEM_PNG',
|
||||
'MOZ_SYSTEM_LIBVPX',
|
||||
'MOZ_SYSTEM_SQLITE',
|
||||
'MOZ_SYSTEM_JEMALLOC'
|
||||
]
|
||||
|
||||
|
||||
@@ -166,6 +166,7 @@ def old_configure_options(*options):
|
||||
'--enable-cookies',
|
||||
'--enable-cpp-rtti',
|
||||
'--enable-crashreporter',
|
||||
'--enable-dbm',
|
||||
'--enable-dbus',
|
||||
'--enable-debug-js-modules',
|
||||
'--enable-jetpack',
|
||||
@@ -233,7 +234,6 @@ def old_configure_options(*options):
|
||||
'--enable-system-cairo',
|
||||
'--enable-system-extension-dirs',
|
||||
'--enable-system-pixman',
|
||||
'--enable-system-sqlite',
|
||||
'--enable-tasktracer',
|
||||
'--enable-tests',
|
||||
'--enable-thread-sanitizer',
|
||||
@@ -287,13 +287,7 @@ def old_configure_options(*options):
|
||||
'--with-sixgill',
|
||||
'--with-soft-float',
|
||||
'--with-system-bz2',
|
||||
'--with-system-icu',
|
||||
'--with-system-jpeg',
|
||||
'--with-system-libevent',
|
||||
'--with-system-libvpx',
|
||||
'--with-system-nspr',
|
||||
'--with-system-nss',
|
||||
'--with-system-png',
|
||||
'--with-system-zlib',
|
||||
'--with-thumb',
|
||||
'--with-thumb-interwork',
|
||||
|
||||
@@ -44,10 +44,7 @@ export:: $(export-preqs)
|
||||
-DMOZ_SYSTEM_HUNSPELL=$(MOZ_SYSTEM_HUNSPELL) \
|
||||
-DMOZ_SYSTEM_BZ2=$(MOZ_SYSTEM_BZ2) \
|
||||
-DMOZ_SYSTEM_ZLIB=$(MOZ_SYSTEM_ZLIB) \
|
||||
-DMOZ_SYSTEM_PNG=$(MOZ_SYSTEM_PNG) \
|
||||
-DMOZ_SYSTEM_JPEG=$(MOZ_SYSTEM_JPEG) \
|
||||
-DMOZ_SYSTEM_LIBVPX=$(MOZ_SYSTEM_LIBVPX) \
|
||||
-DMOZ_SYSTEM_ICU=$(MOZ_SYSTEM_ICU) \
|
||||
$(srcdir)/system-headers $(srcdir)/stl-headers | $(PERL) $(topsrcdir)/nsprpub/config/make-system-wrappers.pl system_wrappers
|
||||
$(INSTALL) system_wrappers $(DIST)
|
||||
|
||||
|
||||
Vendored
+10
-12
@@ -6,16 +6,14 @@
|
||||
|
||||
Library('icu')
|
||||
|
||||
if CONFIG['MOZ_SYSTEM_ICU']:
|
||||
OS_LIBS += CONFIG['MOZ_ICU_LIBS']
|
||||
DIRS += [
|
||||
'common',
|
||||
'data',
|
||||
'i18n',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_ICU_DATA_ARCHIVE']:
|
||||
DIRS += ['stubdata']
|
||||
USE_LIBS += ['icustubdata']
|
||||
else:
|
||||
DIRS += [
|
||||
'common',
|
||||
'data',
|
||||
'i18n',
|
||||
]
|
||||
if CONFIG['MOZ_ICU_DATA_ARCHIVE']:
|
||||
DIRS += ['stubdata']
|
||||
USE_LIBS += ['icustubdata']
|
||||
else:
|
||||
USE_LIBS += ['icudata']
|
||||
USE_LIBS += ['icudata']
|
||||
Vendored
+4
-8
@@ -6,10 +6,8 @@
|
||||
|
||||
external_dirs = []
|
||||
|
||||
DIRS += [
|
||||
'lgpllibs',
|
||||
'sqlite',
|
||||
]
|
||||
DIRS += ['lgpllibs']
|
||||
|
||||
if not CONFIG['MOZ_SYSTEM_JPEG']:
|
||||
external_dirs += ['media/libjpeg']
|
||||
|
||||
@@ -30,14 +28,12 @@ if CONFIG['MOZ_TREMOR']:
|
||||
if CONFIG['MOZ_WEBM_ENCODER']:
|
||||
external_dirs += ['media/libmkv']
|
||||
|
||||
if not CONFIG['MOZ_SYSTEM_LIBVPX']:
|
||||
external_dirs += ['media/libvpx']
|
||||
external_dirs += ['media/libvpx']
|
||||
|
||||
if CONFIG['MOZ_AV1']:
|
||||
external_dirs += ['media/libaom']
|
||||
|
||||
if not CONFIG['MOZ_SYSTEM_PNG']:
|
||||
external_dirs += ['media/libpng']
|
||||
external_dirs += ['media/libpng']
|
||||
|
||||
external_dirs += ['media/libwebp']
|
||||
|
||||
|
||||
Vendored
+1
-10
@@ -3,8 +3,6 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
ifndef MOZ_SYSTEM_NSS
|
||||
|
||||
CC_WRAPPER =
|
||||
CXX_WRAPPER =
|
||||
|
||||
@@ -121,15 +119,9 @@ DEFAULT_GMAKE_FLAGS += NSS_ENABLE_TLS_1_3=1
|
||||
ifeq ($(OS_ARCH)_$(GNU_CC),WINNT_1)
|
||||
DEFAULT_GMAKE_FLAGS += OS_DLLFLAGS='-static-libgcc' NSPR31_LIB_PREFIX=lib
|
||||
endif
|
||||
ifndef MOZ_SYSTEM_SQLITE
|
||||
ifdef MOZ_FOLD_LIBS
|
||||
DEFAULT_GMAKE_FLAGS += SQLITE_LIB_NAME=nss3
|
||||
else
|
||||
DEFAULT_GMAKE_FLAGS += SQLITE_LIB_NAME=mozsqlite3
|
||||
DEFAULT_GMAKE_FLAGS += SQLITE_LIB_DIR=$(ABS_DIST)/../config/external/sqlite
|
||||
endif # MOZ_FOLD_LIBS
|
||||
DEFAULT_GMAKE_FLAGS += SQLITE_LIB_DIR=$(ABS_DIST)/../db/sqlite3/src
|
||||
DEFAULT_GMAKE_FLAGS += SQLITE_INCLUDE_DIR=$(ABS_DIST)/include
|
||||
endif
|
||||
ifdef NSS_DISABLE_DBM
|
||||
DEFAULT_GMAKE_FLAGS += NSS_DISABLE_DBM=1
|
||||
endif
|
||||
@@ -475,4 +467,3 @@ endif # MOZ_FOLD_LIBS
|
||||
# security/nss/lib/ckfw/builtins. See bug #836220.
|
||||
libs-nss/lib$(if $(MOZ_FOLD_LIBS),/ckfw): $(call mkdir_deps,$(DEPTH)/security/nss/lib/ckfw/builtins)
|
||||
|
||||
endif
|
||||
Vendored
+8
-11
@@ -6,14 +6,11 @@
|
||||
|
||||
Library('crmf')
|
||||
|
||||
if CONFIG['MOZ_SYSTEM_NSS']:
|
||||
OS_LIBS += [l for l in CONFIG['NSS_LIBS'] if l.startswith('-L')]
|
||||
else:
|
||||
USE_LIBS += [
|
||||
# The dependency on nss is not real, but is required to force the
|
||||
# parent directory being built before this one. This has no
|
||||
# practical effect on linkage, since the only thing linking crmf
|
||||
# will need nss anyways.
|
||||
'nss',
|
||||
'static:/security/nss/lib/crmf/crmf',
|
||||
]
|
||||
USE_LIBS += [
|
||||
# The dependency on nss is not real, but is required to force the
|
||||
# parent directory being built before this one. This has no
|
||||
# practical effect on linkage, since the only thing linking crmf
|
||||
# will need nss anyways.
|
||||
'nss',
|
||||
'static:/security/nss/lib/crmf/crmf',
|
||||
]
|
||||
Vendored
+3
-5
@@ -6,10 +6,7 @@
|
||||
|
||||
DIRS += ['crmf']
|
||||
|
||||
if CONFIG['MOZ_SYSTEM_NSS']:
|
||||
Library('nss')
|
||||
OS_LIBS += CONFIG['NSS_LIBS']
|
||||
elif CONFIG['MOZ_FOLD_LIBS']:
|
||||
if CONFIG['MOZ_FOLD_LIBS']:
|
||||
GeckoSharedLibrary('nss', linkage=None)
|
||||
# TODO: The library name can be changed when bug 845217 is fixed.
|
||||
SHARED_LIBRARY_NAME = 'nss3'
|
||||
@@ -32,9 +29,10 @@ else:
|
||||
'/security/nss/lib/smime/smime3',
|
||||
'/security/nss/lib/ssl/ssl3',
|
||||
'/security/nss/lib/util/nssutil3',
|
||||
'sqlite',
|
||||
]
|
||||
|
||||
USE_LIBS += ['sqlite']
|
||||
|
||||
# XXX: We should fix these warnings.
|
||||
ALLOW_COMPILER_WARNINGS = True
|
||||
|
||||
|
||||
Vendored
-1
@@ -13,7 +13,6 @@
|
||||
PR_*
|
||||
PL_*
|
||||
#endif
|
||||
#include ../../../db/sqlite3/src/sqlite.symbols
|
||||
ATOB_AsciiToData
|
||||
ATOB_AsciiToData_Util
|
||||
ATOB_ConvertAsciiToItem
|
||||
|
||||
Vendored
-22
@@ -1,22 +0,0 @@
|
||||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
if CONFIG['MOZ_SYSTEM_SQLITE']:
|
||||
Library('sqlite')
|
||||
OS_LIBS += CONFIG['SQLITE_LIBS']
|
||||
else:
|
||||
DIRS += ['../../../db/sqlite3/src']
|
||||
if CONFIG['MOZ_FOLD_LIBS']:
|
||||
Library('sqlite')
|
||||
# When folding libraries, sqlite is actually in the nss library.
|
||||
USE_LIBS += [
|
||||
'nss',
|
||||
]
|
||||
else:
|
||||
SharedLibrary('sqlite')
|
||||
SHARED_LIBRARY_NAME = 'mozsqlite3'
|
||||
|
||||
SYMBOLS_FILE = '/db/sqlite3/src/sqlite.symbols'
|
||||
@@ -10,4 +10,4 @@
|
||||
# hardcoded milestones in the tree from these two files.
|
||||
#--------------------------------------------------------
|
||||
|
||||
4.5.0
|
||||
4.5.9
|
||||
@@ -29,9 +29,6 @@ if CONFIG['HOST_OS_ARCH'] != 'WINNT':
|
||||
# while the program here is in C.
|
||||
HostProgram('nsinstall_real', c_only=True)
|
||||
|
||||
if CONFIG['MOZ_SYSTEM_ICU']:
|
||||
DEFINES['MOZ_SYSTEM_ICU'] = True
|
||||
|
||||
PYTHON_UNIT_TESTS += [
|
||||
'tests/test_mozbuild_reading.py',
|
||||
'tests/unit-expandlibs.py',
|
||||
|
||||
+1
-1
@@ -172,7 +172,7 @@ ifeq ($(MOZ_REPLACE_MALLOC_LINKAGE),dummy library)
|
||||
mozglue/build/target memory/replace/logalloc/replay/target: memory/replace/dummy/target
|
||||
endif
|
||||
endif
|
||||
ifeq (,$(MOZ_SYSTEM_NSPR)$(MOZ_SYSTEM_NSS)$(MOZ_FOLD_LIBS))
|
||||
ifeq (,$(MOZ_FOLD_LIBS))
|
||||
config/external/nss/target: config/external/nspr/pr/target config/external/nspr/ds/target config/external/nspr/libc/target
|
||||
endif
|
||||
# Most things are built during compile (target/host), but some things happen during export
|
||||
|
||||
@@ -1253,9 +1253,6 @@ soundtouch/SoundTouchFactory.h
|
||||
#if MOZ_LIBAV_FFT==1
|
||||
libavcodec/avfft.h
|
||||
#endif
|
||||
#if MOZ_SYSTEM_PNG==1
|
||||
png.h
|
||||
#endif
|
||||
#if MOZ_SYSTEM_ZLIB==1
|
||||
zlib.h
|
||||
#endif
|
||||
@@ -1291,15 +1288,6 @@ QtSparql/qsparqlresult.h
|
||||
#if MOZ_TREE_PIXMAN!=1
|
||||
pixman.h
|
||||
#endif
|
||||
#if MOZ_SYSTEM_LIBVPX==1
|
||||
vpx/svc_context.h
|
||||
vpx/vpx_codec.h
|
||||
vpx/vpx_decoder.h
|
||||
vpx/vpx_encoder.h
|
||||
vpx/vp8cx.h
|
||||
vpx/vp8dx.h
|
||||
vpx_mem/vpx_mem.h
|
||||
#endif
|
||||
gst/gst.h
|
||||
gst/app/gstappsink.h
|
||||
gst/app/gstappsrc.h
|
||||
@@ -1312,22 +1300,6 @@ kvm.h
|
||||
spawn.h
|
||||
err.h
|
||||
xlocale.h
|
||||
#ifdef MOZ_SYSTEM_ICU
|
||||
unicode/locid.h
|
||||
unicode/numsys.h
|
||||
unicode/timezone.h
|
||||
unicode/ucal.h
|
||||
unicode/uchar.h
|
||||
unicode/uclean.h
|
||||
unicode/ucol.h
|
||||
unicode/udat.h
|
||||
unicode/udatpg.h
|
||||
unicode/uenum.h
|
||||
unicode/unorm.h
|
||||
unicode/unum.h
|
||||
unicode/ustring.h
|
||||
unicode/utypes.h
|
||||
#endif
|
||||
libutil.h
|
||||
unwind.h
|
||||
fenv.h
|
||||
@@ -93,7 +93,7 @@ if (!defined($official)) {$official="";}
|
||||
if (!defined($milestone)) {$milestone="";}
|
||||
if (!defined($module)) {$module="";}
|
||||
if (!defined($binary)) {$binary="";}
|
||||
if (!defined($displayname)) {$displayname="Mozilla";}
|
||||
if (!defined($displayname)) {$displayname="UXP";}
|
||||
if (!defined($appversion)) {$appversion=$milestone;}
|
||||
if (!defined($depth)) {$depth=".";}
|
||||
if (!defined($rcinclude)) {$rcinclude="";}
|
||||
@@ -234,10 +234,10 @@ for ($j = 1; $j < 4; $j++)
|
||||
}
|
||||
my $winappversion = "$appver[0],$appver[1],$appver[2],$appver[3]";
|
||||
|
||||
my $copyright = "License: MPL 2";
|
||||
my $company = "Mozilla Foundation";
|
||||
my $trademarks = "Mozilla";
|
||||
my $productname = $displayname;
|
||||
my $copyright = "License: MPL 2.0";
|
||||
my $company = "Moonchild Productions";
|
||||
my $trademarks = "Moonchild";
|
||||
my $productname = "UXP";
|
||||
|
||||
|
||||
if (defined($override_comment)){$override_comment =~ s/\@MOZ_APP_DISPLAYNAME\@/$displayname/g; $comment=$override_comment;}
|
||||
|
||||
+5
-6
@@ -3,9 +3,8 @@
|
||||
# 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/.
|
||||
|
||||
if not CONFIG['NSS_DISABLE_DBM'] and CONFIG['MOZ_MORK']:
|
||||
DIRS += [
|
||||
'public',
|
||||
'src',
|
||||
'build',
|
||||
]
|
||||
DIRS += [
|
||||
'public',
|
||||
'src',
|
||||
'build',
|
||||
]
|
||||
@@ -1,11 +0,0 @@
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
if not CONFIG['NSS_DISABLE_DBM'] and CONFIG['MOZ_MORK']:
|
||||
DIRS += [
|
||||
'mork/public',
|
||||
'mork/src',
|
||||
'mork/build',
|
||||
]
|
||||
+12
-23
@@ -3,25 +3,18 @@
|
||||
# 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/.
|
||||
NO_VISIBILITY_FLAGS = True
|
||||
|
||||
EXPORTS += [
|
||||
'sqlite3.h',
|
||||
]
|
||||
NO_VISIBILITY_FLAGS = True
|
||||
|
||||
# We allow warnings for third-party code that can be updated from upstream.
|
||||
ALLOW_COMPILER_WARNINGS = True
|
||||
|
||||
if CONFIG['MOZ_FOLD_LIBS']:
|
||||
# When folding libraries, sqlite is actually in the nss library.
|
||||
FINAL_LIBRARY = 'nss'
|
||||
else:
|
||||
# The final library is in config/external/sqlite
|
||||
FINAL_LIBRARY = 'sqlite'
|
||||
GeckoSharedLibrary('sqlite', linkage=None, mozglue='library')
|
||||
SHARED_LIBRARY_NAME = 'mozsqlite3'
|
||||
SYMBOLS_FILE = 'sqlite.symbols'
|
||||
|
||||
SOURCES += [
|
||||
'sqlite3.c',
|
||||
]
|
||||
EXPORTS += ['sqlite3.h']
|
||||
SOURCES += ['sqlite3.c']
|
||||
|
||||
# -DSQLITE_SECURE_DELETE=1 will cause SQLITE to 0-fill delete data so we
|
||||
# don't have to vacuum to make sure the data is not visible in the file.
|
||||
@@ -34,8 +27,11 @@ SOURCES += [
|
||||
# hidden preference. If that preference is missing or invalid then this value
|
||||
# will be used.
|
||||
# Note: Be sure to update the configure.in checks when these change!
|
||||
for var in ('SQLITE_SECURE_DELETE', 'SQLITE_THREADSAFE', 'SQLITE_CORE',
|
||||
'SQLITE_ENABLE_FTS3', 'SQLITE_ENABLE_UNLOCK_NOTIFY',
|
||||
for var in ('SQLITE_SECURE_DELETE',
|
||||
'SQLITE_THREADSAFE',
|
||||
'SQLITE_CORE',
|
||||
'SQLITE_ENABLE_FTS3',
|
||||
'SQLITE_ENABLE_UNLOCK_NOTIFY',
|
||||
'SQLITE_ENABLE_DBSTAT_VTAB'):
|
||||
DEFINES[var] = 1
|
||||
|
||||
@@ -67,10 +63,6 @@ if CONFIG['MOZ_DEBUG']:
|
||||
DEFINES['SQLITE_DEBUG'] = 1
|
||||
DEFINES['SQLITE_ENABLE_API_ARMOR'] = True
|
||||
|
||||
if CONFIG['OS_TARGET'] == 'Android':
|
||||
# default to user readable only to fit Android security model
|
||||
DEFINES['SQLITE_DEFAULT_FILE_PERMISSIONS'] = '0600'
|
||||
|
||||
# Force using malloc_usable_size when building with jemalloc because _msize
|
||||
# causes assertions on Win64. See bug 719579.
|
||||
if CONFIG['OS_ARCH'] == 'WINNT' and CONFIG['MOZ_MEMORY']:
|
||||
@@ -86,10 +78,7 @@ DEFINES['SQLITE_OMIT_DECLTYPE'] = True
|
||||
# performance and doesn't suffer from a full separate tmp partition.
|
||||
# Exclude 32bit platforms due to address space fragmentation issues.
|
||||
# System Sqlite is managed through a PRAGMA instead.
|
||||
if CONFIG['OS_TARGET'] == 'Android':
|
||||
# On Android there's no tmp partition, so always use a MEMORY temp store.
|
||||
DEFINES['SQLITE_TEMP_STORE'] = 3
|
||||
elif CONFIG['HAVE_64BIT_BUILD']:
|
||||
if CONFIG['HAVE_64BIT_BUILD']:
|
||||
# On 64bit platforms default to a MEMORY temp store for performance.
|
||||
DEFINES['SQLITE_TEMP_STORE'] = 2
|
||||
|
||||
|
||||
@@ -58,9 +58,21 @@ const Curl = {
|
||||
* A cURL command.
|
||||
*/
|
||||
generateCommand: function (data) {
|
||||
let utils = CurlUtils;
|
||||
const utils = CurlUtils;
|
||||
|
||||
let command = ["curl"];
|
||||
|
||||
// Make sure to use the following helpers to sanitize arguments before execution.
|
||||
const addParam = value => {
|
||||
const safe = /^[a-zA-Z-]+$/.test(value) ? value : escapeString(value);
|
||||
command.push(safe);
|
||||
};
|
||||
|
||||
const addPostData = value => {
|
||||
const safe = /^[a-zA-Z-]+$/.test(value) ? value : escapeString(value);
|
||||
postData.push(safe);
|
||||
};
|
||||
|
||||
let ignoredHeaders = new Set();
|
||||
|
||||
// The cURL command is expected to run on the same platform that Firefox runs
|
||||
@@ -69,7 +81,7 @@ const Curl = {
|
||||
utils.escapeStringWin : utils.escapeStringPosix;
|
||||
|
||||
// Add URL.
|
||||
command.push(escapeString(data.url));
|
||||
addParam(data.url);
|
||||
|
||||
let postDataText = null;
|
||||
let multipartRequest = utils.isMultipartRequest(data);
|
||||
@@ -79,15 +91,15 @@ const Curl = {
|
||||
if (utils.isUrlEncodedRequest(data) ||
|
||||
["PUT", "POST", "PATCH"].includes(data.method)) {
|
||||
postDataText = data.postDataText;
|
||||
postData.push("--data");
|
||||
postData.push(escapeString(utils.writePostDataTextParams(postDataText)));
|
||||
addPostData("--data");
|
||||
addPostData(utils.writePostDataTextParams(postDataText));
|
||||
ignoredHeaders.add("content-length");
|
||||
} else if (multipartRequest) {
|
||||
postDataText = data.postDataText;
|
||||
postData.push("--data-binary");
|
||||
addPostData("--data-binary");
|
||||
let boundary = utils.getMultipartBoundary(data);
|
||||
let text = utils.removeBinaryDataFromMultipartText(postDataText, boundary);
|
||||
postData.push(escapeString(text));
|
||||
addPostData(text);
|
||||
ignoredHeaders.add("content-length");
|
||||
}
|
||||
|
||||
@@ -95,15 +107,15 @@ const Curl = {
|
||||
// For GET and POST requests this is not necessary as GET is the
|
||||
// default. If --data or --binary is added POST is the default.
|
||||
if (!(data.method == "GET" || data.method == "POST")) {
|
||||
command.push("-X");
|
||||
command.push(data.method);
|
||||
addParam("-X");
|
||||
addParam(data.method);
|
||||
}
|
||||
|
||||
// Add -I (HEAD)
|
||||
// For servers that supports HEAD.
|
||||
// This will fetch the header of a document only.
|
||||
if (data.method == "HEAD") {
|
||||
command.push("-I");
|
||||
addParam("-I");
|
||||
}
|
||||
|
||||
// Add http version.
|
||||
@@ -114,7 +126,7 @@ const Curl = {
|
||||
// data.httpVersion are HTTP/1.0, HTTP/1.1 and HTTP/2.0
|
||||
// So in case of HTTP/2.0 (which should ideally be HTTP/2) we are using
|
||||
// only major version, and full version in other cases
|
||||
command.push("--http" + (version == "2.0" ? version.split(".")[0] : version));
|
||||
addParam("--http" + (version == "2.0" ? version.split(".")[0] : version));
|
||||
}
|
||||
|
||||
// Add request headers.
|
||||
@@ -126,14 +138,14 @@ const Curl = {
|
||||
for (let i = 0; i < headers.length; i++) {
|
||||
let header = headers[i];
|
||||
if (header.name.toLowerCase() === "accept-encoding") {
|
||||
command.push("--compressed");
|
||||
addParam("--compressed");
|
||||
continue;
|
||||
}
|
||||
if (ignoredHeaders.has(header.name.toLowerCase())) {
|
||||
continue;
|
||||
}
|
||||
command.push("-H");
|
||||
command.push(escapeString(header.name + ": " + header.value));
|
||||
addParam("-H");
|
||||
addParam(header.name + ": " + header.value);
|
||||
}
|
||||
|
||||
// Add post data.
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
a {
|
||||
-moz-user-focus: normal;
|
||||
-moz-user-input: enabled;
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
+5
-11
@@ -4,20 +4,14 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DIRS += [
|
||||
'server',
|
||||
'shared',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_DEVTOOLS']:
|
||||
DIRS += ['client']
|
||||
|
||||
if CONFIG['MOZ_DEVTOOLS_SERVER']:
|
||||
DIRS += [
|
||||
'server',
|
||||
'shared',
|
||||
]
|
||||
else:
|
||||
DIRS += [
|
||||
'shared/heapsnapshot',
|
||||
'shared/jsinspector',
|
||||
]
|
||||
|
||||
# /browser uses DIST_SUBDIR. We opt-in to this treatment when building
|
||||
# DevTools for the browser to keep the root omni.ja slim for use by external XUL
|
||||
# apps. Mulet also uses this since it includes /browser.
|
||||
|
||||
@@ -1440,8 +1440,6 @@ exports.CSS_PROPERTIES = {
|
||||
"supports": [],
|
||||
"values": [
|
||||
"auto",
|
||||
"disabled",
|
||||
"enabled",
|
||||
"inherit",
|
||||
"initial",
|
||||
"none",
|
||||
|
||||
@@ -4,60 +4,12 @@
|
||||
# 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/.
|
||||
|
||||
with Files('**'):
|
||||
BUG_COMPONENT = ('Firefox', 'Developer Tools: Memory')
|
||||
|
||||
if CONFIG['ENABLE_TESTS']:
|
||||
DIRS += ['tests/gtest']
|
||||
|
||||
XPCSHELL_TESTS_MANIFESTS += [ 'tests/unit/xpcshell.ini' ]
|
||||
MOCHITEST_MANIFESTS += [ 'tests/mochitest/mochitest.ini' ]
|
||||
MOCHITEST_CHROME_MANIFESTS += [ 'tests/mochitest/chrome.ini' ]
|
||||
|
||||
EXPORTS.mozilla.devtools += [
|
||||
'AutoMemMap.h',
|
||||
'CoreDump.pb.h',
|
||||
'DeserializedNode.h',
|
||||
'DominatorTree.h',
|
||||
'FileDescriptorOutputStream.h',
|
||||
'HeapSnapshot.h',
|
||||
'HeapSnapshotTempFileHelperChild.h',
|
||||
'HeapSnapshotTempFileHelperParent.h',
|
||||
'ZeroCopyNSIOutputStream.h',
|
||||
]
|
||||
|
||||
IPDL_SOURCES += [
|
||||
'PHeapSnapshotTempFileHelper.ipdl',
|
||||
]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
SOURCES += [
|
||||
'AutoMemMap.cpp',
|
||||
'CoreDump.pb.cc',
|
||||
'DeserializedNode.cpp',
|
||||
'DominatorTree.cpp',
|
||||
'FileDescriptorOutputStream.cpp',
|
||||
'HeapSnapshot.cpp',
|
||||
'HeapSnapshotTempFileHelperParent.cpp',
|
||||
'ZeroCopyNSIOutputStream.cpp',
|
||||
]
|
||||
|
||||
# Disable RTTI in google protocol buffer
|
||||
DEFINES['GOOGLE_PROTOBUF_NO_RTTI'] = True
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
if CONFIG['MOZ_DEVTOOLS_SERVER']:
|
||||
DevToolsModules(
|
||||
'census-tree-node.js',
|
||||
'CensusUtils.js',
|
||||
'DominatorTreeNode.js',
|
||||
'HeapAnalysesClient.js',
|
||||
'HeapAnalysesWorker.js',
|
||||
'HeapSnapshotFileUtils.js',
|
||||
'shortest-paths.js',
|
||||
)
|
||||
|
||||
if CONFIG['GNU_CXX']:
|
||||
CXXFLAGS += ['-Wno-error=shadow']
|
||||
DevToolsModules(
|
||||
'census-tree-node.js',
|
||||
'CensusUtils.js',
|
||||
'DominatorTreeNode.js',
|
||||
'HeapAnalysesClient.js',
|
||||
'HeapAnalysesWorker.js',
|
||||
'HeapSnapshotFileUtils.js',
|
||||
'shortest-paths.js',
|
||||
)
|
||||
@@ -17,7 +17,6 @@ DIRS += [
|
||||
'heapsnapshot',
|
||||
'inspector',
|
||||
'jsbeautify',
|
||||
'jsinspector',
|
||||
'layout',
|
||||
'locales',
|
||||
'node-properties',
|
||||
|
||||
+253
-11
@@ -1,4 +1,4 @@
|
||||
# UXP Coding Style Guide
|
||||
# UXP Coding Style Guide
|
||||
While our source tree is currently in a number of different Coding Styles and the general rule applies to adhere to style of surrounding code when you are making changes, it is our goal to unify the style of our source tree and making it adhere to a single style.
|
||||
This document describes the preferred style for new source code files and the preferred style to convert existing files to.
|
||||
|
||||
@@ -11,9 +11,9 @@ Our own managed and maintained code should adhere to this guide where possible o
|
||||
## General formatting rules
|
||||
The following formatting rules apply to all code:
|
||||
- Always use spaces for indentation, never use tabs!
|
||||
- Put a space between a keyword and parenthesis, e.g. `if (`.
|
||||
- Put a space between a keyword and parenthesis, e.g. `if (`. Do _not_ put a space between a function/type-assignment name and its parenthesis, e.g. `function(somevar)` or `int32_t(somevar)`.
|
||||
- Put a space between variables and operators, e.g. `a == b`.
|
||||
- Put a space after a comma or semicolon in variable lists, e.g. `function (a, b, c)` or `for (i = 1; i < 10; i++)`.
|
||||
- Put a space after a comma or semicolon in variable lists, e.g. `function(a, b, c)` or `for (i = 1; i < 10; i++)`.
|
||||
- Indentation of scopes is 2 spaces.
|
||||
- Indentation of long lines is variable-aligned or expression-aligned (see "long line wrapping")
|
||||
- Conditional defines are always placed on column 1. This is also true for nested defines.
|
||||
@@ -225,15 +225,257 @@ somelongvariable = somelongexpression ?
|
||||
|
||||
## JavaScript
|
||||
Applies to `*.js` and `*.jsm`.
|
||||
### General formatting guidelines
|
||||
- Place function signatures on the same line as js object identifiers, and do not use named function syntax in that case:
|
||||
```JavaScript
|
||||
var myObject = {
|
||||
myIdentifier: function(var1, var2) {
|
||||
...
|
||||
},
|
||||
myIdentifier2: function() {
|
||||
...
|
||||
}
|
||||
}
|
||||
```
|
||||
- Variable initializers should be placed on the variable declaration line if needed.
|
||||
```JavaScript
|
||||
var fwdCommand = document.getElementById("Browser:Forward");
|
||||
```
|
||||
```JavaScript
|
||||
var myObject = {
|
||||
myVariable: null,
|
||||
myString: "Something"
|
||||
}
|
||||
```
|
||||
- Avoid placing executed code on the expression line. Preferably brace executed code.
|
||||
|
||||
WRONG:
|
||||
```JavaScript
|
||||
if (a == b) do_something();
|
||||
if (a == b) { do_something(); }
|
||||
```
|
||||
DISCOURAGED:
|
||||
```JavaScript
|
||||
if (a == b)
|
||||
do_something();
|
||||
```
|
||||
CORRECT:
|
||||
```JavaScript
|
||||
if (a == b) {
|
||||
do_something();
|
||||
}
|
||||
```
|
||||
- Format in-lined variable functions as if you would format normal functions with the exception of closure: break with the opening brace, followed by code, and closing brace on its own line, followed immediately by any other variables passed in-line.
|
||||
```JavaScript
|
||||
appMenuButton.addEventListener("mousedown", function(event) {
|
||||
if (event.button == 0) {
|
||||
appMenuOpening = new Date();
|
||||
}
|
||||
}, false);
|
||||
```
|
||||
- Use a single space between `{` `}` braces in empty js objects.
|
||||
|
||||
### Flow control
|
||||
Flow control expressions should follow the following guidelines:
|
||||
- Scopes have their opening braces on the expression line
|
||||
- Scopes have their closing braces on a separate line, indent-aligned with the flow control expression
|
||||
- Any alternative flow control paths are generally started with an expression on the closing brace line. The logic behind this is that you should keep the flow control level visually the same for the executed code blocks with no breaks (a closing brace on its own line means "done").
|
||||
- Case statements are indented by 2 on a new line with the case expression on its own line.
|
||||
- Flow control default scopes are always placed at the bottom.
|
||||
|
||||
#### if..else
|
||||
`if..else` statements example:
|
||||
```JavaScript
|
||||
if (something == somethingelse) {
|
||||
true_case_code here;
|
||||
} else {
|
||||
false_case_code here;
|
||||
}
|
||||
|
||||
if (case1) {
|
||||
case1_code here;
|
||||
} else if (case2) {
|
||||
case2_code here;
|
||||
} else {
|
||||
other_case_code here;
|
||||
}
|
||||
|
||||
if (case1) {
|
||||
case1_code here;
|
||||
} else {
|
||||
if (case2) {
|
||||
case2_code here;
|
||||
}
|
||||
case2_and_other_code here;
|
||||
}
|
||||
```
|
||||
#### for
|
||||
`for` loop example:
|
||||
```JavaScript
|
||||
for (let i = 1; i < max; i++) {
|
||||
loop_code here;
|
||||
}
|
||||
|
||||
for (let i = 0;; i++) {
|
||||
do_something_with(i);
|
||||
if (i > max) break;
|
||||
...
|
||||
}
|
||||
```
|
||||
#### while
|
||||
`while` loop example:
|
||||
```JavaScript
|
||||
while (something == true) {
|
||||
loop_code here;
|
||||
}
|
||||
|
||||
do {
|
||||
execute_me_at_least_once();
|
||||
...
|
||||
} while (something == true);
|
||||
```
|
||||
#### switch..case
|
||||
`switch..case` flow control example:
|
||||
```JavaScript
|
||||
switch (variable) {
|
||||
case value1:
|
||||
// Comment describing 1
|
||||
code_for_1;
|
||||
code_for_1;
|
||||
break;
|
||||
case value2:
|
||||
code_for_2;
|
||||
code_for_2;
|
||||
// fallthrough
|
||||
case value3:
|
||||
case value4:
|
||||
code_for_3_and_4;
|
||||
break;
|
||||
default:
|
||||
code_for_default;
|
||||
code_for_default;
|
||||
}
|
||||
```
|
||||
Alternatively (braced):
|
||||
```JavaScript
|
||||
switch (variable) {
|
||||
case value1: {
|
||||
// Comment describing 1
|
||||
code_for_1;
|
||||
code_for_1;
|
||||
break;
|
||||
}
|
||||
case value2: {
|
||||
code_for_2;
|
||||
code_for_2;
|
||||
// fallthrough
|
||||
}
|
||||
case value3:
|
||||
case value4: {
|
||||
code_for_3_and_4;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
code_for_default;
|
||||
code_for_default;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### try..catch
|
||||
- When using `try..catch` blocks, the use of optional catch binding is discouraged. Please always include the error variable.
|
||||
|
||||
`try..catch` flow control examples:
|
||||
```JavaScript
|
||||
try {
|
||||
do_something();
|
||||
} catch(e) {
|
||||
handle_error(e);
|
||||
} finally {
|
||||
always();
|
||||
}
|
||||
|
||||
try {
|
||||
do_something();
|
||||
} catch(e) {
|
||||
}
|
||||
|
||||
try {
|
||||
do_something();
|
||||
} finally {
|
||||
always();
|
||||
}
|
||||
```
|
||||
DISCOURAGED
|
||||
```JavaScript
|
||||
try {
|
||||
do_something();
|
||||
} catch {
|
||||
// No error processing
|
||||
do_something_else();
|
||||
}
|
||||
|
||||
// No closing brace on its own line
|
||||
try {
|
||||
do_something();
|
||||
} catch(ex) { }
|
||||
```
|
||||
|
||||
### Long line wrapping
|
||||
If statements on a single line become overly long, they should be split into multiple lines:
|
||||
- Binary operators (including ternary) must be left on their original lines if the line break happens around the operator. The second line should start in the same column as the start of the expression in the first line.
|
||||
- Lists of variables (e.g. when calling or declaring a function) should be split at the wrapping column.
|
||||
- Long OOP calls should be split at the period with the period on the start of the new line, indented to the column of the first object, filling to the wrapping column where possible, including additional terms.
|
||||
- When breaking assignments/operations/logic, break right after the operator (`=`, `+`, `&&`, `||`, etc.)
|
||||
- **Don't break too rigorously**; short additions should be kept on the same line to keep things legible - use common sense and context for flexibility.
|
||||
|
||||
WRONG:
|
||||
```JavaScript
|
||||
somelongobjectname.somelongfunction(
|
||||
var1, var2, var3, var4, var5);
|
||||
|
||||
if (somelongvariable == somelongothervariable
|
||||
|| somelongvariable2 == somelongothervariable2) {
|
||||
|
||||
somelongvariable = somelongexpression ? somevalue1
|
||||
: somevalue2;
|
||||
|
||||
var iShouldntBeUsingThisLongOfAVarName
|
||||
= someValueToAdd + someValueToAdd + someValueToAdd
|
||||
+ someValueToAdd;
|
||||
|
||||
Cu.import("resource:///modules/DownloadsCommon.jsm", {}).
|
||||
DownloadsCommon.initializeAllDataLinks();
|
||||
```
|
||||
CORRECT:
|
||||
```JavaScript
|
||||
somelongobjectname.somelongfunction(var1, var2, var3,
|
||||
var4, var5);
|
||||
|
||||
if (somelongvariable == somelongothervariable ||
|
||||
somelongvariable2 == somelongothervariable2) {
|
||||
|
||||
somelongvariable = somelongexpression ?
|
||||
somevalue1 :
|
||||
somevalue2;
|
||||
|
||||
var iShouldntBeUsingThisLongOfAVarName =
|
||||
someValueToAdd + someValueToAdd + someValueToAdd +
|
||||
someValueToAdd;
|
||||
|
||||
Cu.import("resource:///modules/DownloadsCommon.jsm", {})
|
||||
.DownloadsCommon.initializeAllDataLinks();
|
||||
|
||||
let sessionStartup = Cc["@mozilla.org/browser/sessionstartup;1"]
|
||||
.getService(Ci.nsISessionStartup);
|
||||
```
|
||||
|
||||
## XUL and other XML-derivatives
|
||||
Applies to `*.xul`, `*.html`, `*.xhtml`.
|
||||
TODO
|
||||
## IDL
|
||||
Applies to `*.idl`, `*.xpidl` and `*.webidl`.
|
||||
|
||||
<!--stackedit_data:
|
||||
eyJoaXN0b3J5IjpbMjUzODYzMzMsMjg5MjUwODIsLTQzMjMzNz
|
||||
ExMSw4MzQ2MjYwNDksLTE5MDMyNzE5OTYsLTEwMTIwMjc3ODMs
|
||||
LTE4MzgzODM5MDIsODA5MjEzNTEyLC01Mzg0MjM4MDAsMzgyNj
|
||||
I3NDYzLDIwODYwMjIwODUsLTE1MjU5MjE2MjIsLTY1OTMzMTA0
|
||||
MCwtNzQwOTE5MDQ1LDE4Njc1NTQxNDJdfQ==
|
||||
-->
|
||||
TODO
|
||||
## Python-esque
|
||||
Applies to `*.py`, `mozbuild` etc.
|
||||
TODO
|
||||
@@ -119,12 +119,10 @@ static RedirEntry kRedirMap[] = {
|
||||
nsIAboutModule::URI_MUST_LOAD_IN_CHILD |
|
||||
nsIAboutModule::ALLOW_SCRIPT
|
||||
},
|
||||
#ifndef ANDROID
|
||||
{
|
||||
"profiles", "chrome://global/content/aboutProfiles.xhtml",
|
||||
nsIAboutModule::ALLOW_SCRIPT
|
||||
},
|
||||
#endif
|
||||
// about:srcdoc is unresolvable by specification. It is included here
|
||||
// because the security manager would disallow srcdoc iframes otherwise.
|
||||
{
|
||||
|
||||
@@ -25,10 +25,6 @@
|
||||
#ifdef MOZ_ENABLE_DBUS
|
||||
#include "nsDBusHandlerApp.h"
|
||||
#endif
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
#include "nsExternalSharingAppService.h"
|
||||
#include "nsExternalURLHandlerService.h"
|
||||
#endif
|
||||
|
||||
// session history
|
||||
#include "nsSHEntry.h"
|
||||
@@ -85,10 +81,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(PlatformLocalHandlerApp_t)
|
||||
#ifdef MOZ_ENABLE_DBUS
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDBusHandlerApp)
|
||||
#endif
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsExternalSharingAppService)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsExternalURLHandlerService)
|
||||
#endif
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(ContentHandlerService, Init)
|
||||
|
||||
// session history
|
||||
@@ -114,10 +106,6 @@ NS_DEFINE_NAMED_CID(NS_LOCALHANDLERAPP_CID);
|
||||
#ifdef MOZ_ENABLE_DBUS
|
||||
NS_DEFINE_NAMED_CID(NS_DBUSHANDLERAPP_CID);
|
||||
#endif
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
NS_DEFINE_NAMED_CID(NS_EXTERNALSHARINGAPPSERVICE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_EXTERNALURLHANDLERSERVICE_CID);
|
||||
#endif
|
||||
NS_DEFINE_NAMED_CID(NS_SHENTRY_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_SHTRANSACTION_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_SHISTORY_CID);
|
||||
@@ -142,10 +130,6 @@ const mozilla::Module::CIDEntry kDocShellCIDs[] = {
|
||||
{ &kNS_LOCALHANDLERAPP_CID, false, nullptr, PlatformLocalHandlerApp_tConstructor },
|
||||
#ifdef MOZ_ENABLE_DBUS
|
||||
{ &kNS_DBUSHANDLERAPP_CID, false, nullptr, nsDBusHandlerAppConstructor },
|
||||
#endif
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
{ &kNS_EXTERNALSHARINGAPPSERVICE_CID, false, nullptr, nsExternalSharingAppServiceConstructor },
|
||||
{ &kNS_EXTERNALURLHANDLERSERVICE_CID, false, nullptr, nsExternalURLHandlerServiceConstructor },
|
||||
#endif
|
||||
{ &kNS_SHENTRY_CID, false, nullptr, nsSHEntryConstructor },
|
||||
{ &kNS_SHTRANSACTION_CID, false, nullptr, nsSHTransactionConstructor },
|
||||
@@ -183,9 +167,7 @@ const mozilla::Module::ContractIDEntry kDocShellContracts[] = {
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "performance", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "plugins", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "serviceworkers", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
|
||||
#ifndef ANDROID
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "profiles", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
|
||||
#endif
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "srcdoc", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "support", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "telemetry", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
|
||||
@@ -205,10 +187,6 @@ const mozilla::Module::ContractIDEntry kDocShellContracts[] = {
|
||||
{ NS_LOCALHANDLERAPP_CONTRACTID, &kNS_LOCALHANDLERAPP_CID },
|
||||
#ifdef MOZ_ENABLE_DBUS
|
||||
{ NS_DBUSHANDLERAPP_CONTRACTID, &kNS_DBUSHANDLERAPP_CID },
|
||||
#endif
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
{ NS_EXTERNALSHARINGAPPSERVICE_CONTRACTID, &kNS_EXTERNALSHARINGAPPSERVICE_CID },
|
||||
{ NS_EXTERNALURLHANDLERSERVICE_CONTRACTID, &kNS_EXTERNALURLHANDLERSERVICE_CID },
|
||||
#endif
|
||||
{ NS_SHENTRY_CONTRACTID, &kNS_SHENTRY_CID },
|
||||
{ NS_SHTRANSACTION_CONTRACTID, &kNS_SHTRANSACTION_CID },
|
||||
|
||||
+674
-336
File diff suppressed because it is too large.
Load diff
@@ -7,13 +7,16 @@
|
||||
#ifndef mozilla_dom_CustomElementRegistry_h
|
||||
#define mozilla_dom_CustomElementRegistry_h
|
||||
|
||||
#include "js/GCHashTable.h"
|
||||
#include "js/TypeDecls.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "mozilla/dom/FunctionBinding.h"
|
||||
#include "mozilla/dom/WebComponentsBinding.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
class nsDocument;
|
||||
|
||||
@@ -22,8 +25,8 @@ namespace dom {
|
||||
|
||||
struct CustomElementData;
|
||||
struct ElementDefinitionOptions;
|
||||
struct LifecycleCallbacks;
|
||||
class CallbackFunction;
|
||||
class CustomElementReaction;
|
||||
class Function;
|
||||
class Promise;
|
||||
|
||||
@@ -32,6 +35,13 @@ struct LifecycleCallbackArgs
|
||||
nsString name;
|
||||
nsString oldValue;
|
||||
nsString newValue;
|
||||
nsString namespaceURI;
|
||||
};
|
||||
|
||||
struct LifecycleAdoptedCallbackArgs
|
||||
{
|
||||
nsCOMPtr<nsIDocument> mOldDocument;
|
||||
nsCOMPtr<nsIDocument> mNewDocument;
|
||||
};
|
||||
|
||||
class CustomElementCallback
|
||||
@@ -39,8 +49,7 @@ class CustomElementCallback
|
||||
public:
|
||||
CustomElementCallback(Element* aThisObject,
|
||||
nsIDocument::ElementCallbackType aCallbackType,
|
||||
CallbackFunction* aCallback,
|
||||
CustomElementData* aOwnerData);
|
||||
CallbackFunction* aCallback);
|
||||
void Traverse(nsCycleCollectionTraversalCallback& aCb) const;
|
||||
void Call();
|
||||
void SetArgs(LifecycleCallbackArgs& aArgs)
|
||||
@@ -50,6 +59,13 @@ public:
|
||||
mArgs = aArgs;
|
||||
}
|
||||
|
||||
void SetAdoptedCallbackArgs(LifecycleAdoptedCallbackArgs& aAdoptedCallbackArgs)
|
||||
{
|
||||
MOZ_ASSERT(mType == nsIDocument::eAdopted,
|
||||
"Arguments are only used by adopted callback.");
|
||||
mAdoptedCallbackArgs = aAdoptedCallbackArgs;
|
||||
}
|
||||
|
||||
private:
|
||||
// The this value to use for invocation of the callback.
|
||||
RefPtr<Element> mThisObject;
|
||||
@@ -59,9 +75,19 @@ private:
|
||||
// Arguments to be passed to the callback,
|
||||
// used by the attribute changed callback.
|
||||
LifecycleCallbackArgs mArgs;
|
||||
// CustomElementData that contains this callback in the
|
||||
// callback queue.
|
||||
CustomElementData* mOwnerData;
|
||||
LifecycleAdoptedCallbackArgs mAdoptedCallbackArgs;
|
||||
};
|
||||
|
||||
class CustomElementConstructor final : public CallbackFunction
|
||||
{
|
||||
public:
|
||||
explicit CustomElementConstructor(CallbackFunction* aOther)
|
||||
: CallbackFunction(aOther)
|
||||
{
|
||||
MOZ_ASSERT(JS::IsConstructor(mCallback));
|
||||
}
|
||||
|
||||
already_AddRefed<Element> Construct(const char* aExecutionReason, ErrorResult& aRv);
|
||||
};
|
||||
|
||||
// Each custom element has an associated callback queue and an element is
|
||||
@@ -70,63 +96,299 @@ struct CustomElementData
|
||||
{
|
||||
NS_INLINE_DECL_REFCOUNTING(CustomElementData)
|
||||
|
||||
explicit CustomElementData(nsIAtom* aType);
|
||||
// Objects in this array are transient and empty after each microtask
|
||||
// checkpoint.
|
||||
nsTArray<nsAutoPtr<CustomElementCallback>> mCallbackQueue;
|
||||
// Custom element type, for <button is="x-button"> or <x-button>
|
||||
// this would be x-button.
|
||||
nsCOMPtr<nsIAtom> mType;
|
||||
// The callback that is next to be processed upon calling RunCallbackQueue.
|
||||
int32_t mCurrentCallback;
|
||||
// Element is being created flag as described in the custom elements spec.
|
||||
bool mElementIsBeingCreated;
|
||||
// Flag to determine if the created callback has been invoked, thus it
|
||||
// determines if other callbacks can be enqueued.
|
||||
bool mCreatedCallbackInvoked;
|
||||
// The microtask level associated with the callbacks in the callback queue,
|
||||
// it is used to determine if a new queue needs to be pushed onto the
|
||||
// processing stack.
|
||||
int32_t mAssociatedMicroTask;
|
||||
// https://dom.spec.whatwg.org/#concept-element-custom-element-state
|
||||
// CustomElementData is only created on the element which is a custom element
|
||||
// or an upgrade candidate, so the state of an element without
|
||||
// CustomElementData is "uncustomized".
|
||||
enum class State {
|
||||
eUndefined,
|
||||
eFailed,
|
||||
eCustom
|
||||
};
|
||||
|
||||
// Empties the callback queue.
|
||||
void RunCallbackQueue();
|
||||
explicit CustomElementData(nsIAtom* aType);
|
||||
CustomElementData(nsIAtom* aType, State aState);
|
||||
|
||||
// Custom element state as described in the custom element spec.
|
||||
State mState;
|
||||
// custom element reaction queue as described in the custom element spec.
|
||||
// There is 1 reaction in reaction queue, when 1) it becomes disconnected,
|
||||
// 2) it’s adopted into a new document, 3) its attributes are changed,
|
||||
// appended, removed, or replaced.
|
||||
// There are 3 reactions in reaction queue when doing upgrade operation,
|
||||
// e.g., create an element, insert a node.
|
||||
AutoTArray<UniquePtr<CustomElementReaction>, 3> mReactionQueue;
|
||||
|
||||
void SetCustomElementDefinition(CustomElementDefinition* aDefinition);
|
||||
CustomElementDefinition* GetCustomElementDefinition();
|
||||
nsIAtom* GetCustomElementType();
|
||||
|
||||
void Traverse(nsCycleCollectionTraversalCallback& aCb) const;
|
||||
void Unlink();
|
||||
|
||||
private:
|
||||
virtual ~CustomElementData() {}
|
||||
|
||||
// Custom element type, for <button is="x-button"> or <x-button>
|
||||
// this would be x-button.
|
||||
RefPtr<nsIAtom> mType;
|
||||
RefPtr<CustomElementDefinition> mCustomElementDefinition;
|
||||
};
|
||||
|
||||
#define ALEADY_CONSTRUCTED_MARKER nullptr
|
||||
|
||||
// The required information for a custom element as defined in:
|
||||
// https://html.spec.whatwg.org/multipage/scripting.html#custom-element-definition
|
||||
struct CustomElementDefinition
|
||||
{
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(CustomElementDefinition)
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(CustomElementDefinition)
|
||||
|
||||
CustomElementDefinition(nsIAtom* aType,
|
||||
nsIAtom* aLocalName,
|
||||
JSObject* aConstructor,
|
||||
Function* aConstructor,
|
||||
nsCOMArray<nsIAtom>&& aObservedAttributes,
|
||||
JSObject* aPrototype,
|
||||
mozilla::dom::LifecycleCallbacks* aCallbacks,
|
||||
uint32_t aDocOrder);
|
||||
|
||||
// The type (name) for this custom element.
|
||||
// The type (name) for this custom element, for <button is="x-foo"> or <x-foo>
|
||||
// this would be x-foo.
|
||||
nsCOMPtr<nsIAtom> mType;
|
||||
|
||||
// The localname to (e.g. <button is=type> -- this would be button).
|
||||
nsCOMPtr<nsIAtom> mLocalName;
|
||||
|
||||
// The custom element constructor.
|
||||
JS::Heap<JSObject *> mConstructor;
|
||||
RefPtr<CustomElementConstructor> mConstructor;
|
||||
|
||||
// The list of attributes that this custom element observes.
|
||||
nsCOMArray<nsIAtom> mObservedAttributes;
|
||||
|
||||
// The prototype to use for new custom elements of this type.
|
||||
JS::Heap<JSObject *> mPrototype;
|
||||
|
||||
// The lifecycle callbacks to call for this custom element.
|
||||
nsAutoPtr<mozilla::dom::LifecycleCallbacks> mCallbacks;
|
||||
UniquePtr<mozilla::dom::LifecycleCallbacks> mCallbacks;
|
||||
|
||||
// A construction stack.
|
||||
// TODO: Bug 1287348 - Implement construction stack for upgrading an element
|
||||
// A construction stack. Use nullptr to represent an "already constructed marker".
|
||||
nsTArray<RefPtr<nsGenericHTMLElement>> mConstructionStack;
|
||||
|
||||
// The document custom element order.
|
||||
uint32_t mDocOrder;
|
||||
|
||||
bool IsCustomBuiltIn()
|
||||
{
|
||||
return mType != mLocalName;
|
||||
}
|
||||
|
||||
bool IsInObservedAttributeList(nsIAtom* aName)
|
||||
{
|
||||
if (mObservedAttributes.IsEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return mObservedAttributes.Contains(aName);
|
||||
}
|
||||
|
||||
private:
|
||||
~CustomElementDefinition() {}
|
||||
};
|
||||
|
||||
class CustomElementReaction
|
||||
{
|
||||
public:
|
||||
virtual ~CustomElementReaction() = default;
|
||||
virtual void Invoke(Element* aElement, ErrorResult& aRv) = 0;
|
||||
virtual void Traverse(nsCycleCollectionTraversalCallback& aCb) const
|
||||
{
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
bool IsUpgradeReaction()
|
||||
{
|
||||
return mIsUpgradeReaction;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool mIsUpgradeReaction = false;
|
||||
#endif
|
||||
};
|
||||
|
||||
class CustomElementUpgradeReaction final : public CustomElementReaction
|
||||
{
|
||||
public:
|
||||
explicit CustomElementUpgradeReaction(CustomElementDefinition* aDefinition)
|
||||
: mDefinition(aDefinition)
|
||||
{
|
||||
#if DEBUG
|
||||
mIsUpgradeReaction = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
virtual void Invoke(Element* aElement, ErrorResult& aRv) override;
|
||||
|
||||
CustomElementDefinition* mDefinition;
|
||||
};
|
||||
|
||||
class CustomElementCallbackReaction final : public CustomElementReaction
|
||||
{
|
||||
public:
|
||||
explicit CustomElementCallbackReaction(UniquePtr<CustomElementCallback> aCustomElementCallback)
|
||||
: mCustomElementCallback(Move(aCustomElementCallback))
|
||||
{
|
||||
}
|
||||
|
||||
virtual void Traverse(nsCycleCollectionTraversalCallback& aCb) const override
|
||||
{
|
||||
mCustomElementCallback->Traverse(aCb);
|
||||
}
|
||||
|
||||
private:
|
||||
virtual void Invoke(Element* aElement, ErrorResult& aRv) override;
|
||||
UniquePtr<CustomElementCallback> mCustomElementCallback;
|
||||
};
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/scripting.html#custom-element-reactions-stack
|
||||
class CustomElementReactionsStack
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(CustomElementReactionsStack)
|
||||
|
||||
CustomElementReactionsStack()
|
||||
: mIsBackupQueueProcessing(false)
|
||||
, mRecursionDepth(0)
|
||||
, mIsElementQueuePushedForCurrentRecursionDepth(false)
|
||||
{
|
||||
}
|
||||
|
||||
// Hold a strong reference of Element so that it does not get cycle collected
|
||||
// before the reactions in its reaction queue are invoked.
|
||||
// The element reaction queues are stored in CustomElementData.
|
||||
// We need to lookup ElementReactionQueueMap again to get relevant reaction queue.
|
||||
// The choice of 1 for the auto size here is based on gut feeling.
|
||||
typedef AutoTArray<RefPtr<Element>, 1> ElementQueue;
|
||||
|
||||
/**
|
||||
* Enqueue a custom element upgrade reaction
|
||||
* https://html.spec.whatwg.org/multipage/scripting.html#enqueue-a-custom-element-upgrade-reaction
|
||||
*/
|
||||
void EnqueueUpgradeReaction(Element* aElement,
|
||||
CustomElementDefinition* aDefinition);
|
||||
|
||||
/**
|
||||
* Enqueue a custom element callback reaction
|
||||
* https://html.spec.whatwg.org/multipage/scripting.html#enqueue-a-custom-element-callback-reaction
|
||||
*/
|
||||
void EnqueueCallbackReaction(Element* aElement,
|
||||
UniquePtr<CustomElementCallback> aCustomElementCallback);
|
||||
|
||||
/**
|
||||
* [CEReactions] Before executing the algorithm's steps.
|
||||
* Increase the current recursion depth, and the element queue is pushed
|
||||
* lazily when we really enqueue reactions.
|
||||
*
|
||||
* @return true if the element queue is pushed for "previous" recursion depth.
|
||||
*/
|
||||
bool EnterCEReactions()
|
||||
{
|
||||
bool temp = mIsElementQueuePushedForCurrentRecursionDepth;
|
||||
mRecursionDepth++;
|
||||
// The is-element-queue-pushed flag is initially false when entering a new
|
||||
// recursion level. The original value will be cached in AutoCEReaction
|
||||
// and restored after leaving this recursion level.
|
||||
mIsElementQueuePushedForCurrentRecursionDepth = false;
|
||||
return temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* [CEReactions] After executing the algorithm's steps.
|
||||
* Pop and invoke the element queue if it is created and pushed for current
|
||||
* recursion depth, then decrease the current recursion depth.
|
||||
*
|
||||
* @param aCx JSContext used for handling exception thrown by algorithm's
|
||||
* steps, this could be a nullptr.
|
||||
* aWasElementQueuePushed used for restoring status after leaving
|
||||
* current recursion.
|
||||
*/
|
||||
void LeaveCEReactions(JSContext* aCx, bool aWasElementQueuePushed)
|
||||
{
|
||||
MOZ_ASSERT(mRecursionDepth);
|
||||
|
||||
if (mIsElementQueuePushedForCurrentRecursionDepth) {
|
||||
Maybe<JS::AutoSaveExceptionState> ases;
|
||||
if (aCx) {
|
||||
ases.emplace(aCx);
|
||||
}
|
||||
PopAndInvokeElementQueue();
|
||||
}
|
||||
mRecursionDepth--;
|
||||
// Restore the is-element-queue-pushed flag cached in AutoCEReaction when
|
||||
// leaving the recursion level.
|
||||
mIsElementQueuePushedForCurrentRecursionDepth = aWasElementQueuePushed;
|
||||
|
||||
MOZ_ASSERT_IF(!mRecursionDepth, mReactionsStack.IsEmpty());
|
||||
}
|
||||
|
||||
private:
|
||||
~CustomElementReactionsStack() {};
|
||||
|
||||
/**
|
||||
* Push a new element queue onto the custom element reactions stack.
|
||||
*/
|
||||
void CreateAndPushElementQueue();
|
||||
|
||||
/**
|
||||
* Pop the element queue from the custom element reactions stack, and invoke
|
||||
* custom element reactions in that queue.
|
||||
*/
|
||||
void PopAndInvokeElementQueue();
|
||||
|
||||
// The choice of 8 for the auto size here is based on gut feeling.
|
||||
AutoTArray<UniquePtr<ElementQueue>, 8> mReactionsStack;
|
||||
ElementQueue mBackupQueue;
|
||||
// https://html.spec.whatwg.org/#enqueue-an-element-on-the-appropriate-element-queue
|
||||
bool mIsBackupQueueProcessing;
|
||||
|
||||
void InvokeBackupQueue();
|
||||
|
||||
/**
|
||||
* Invoke custom element reactions
|
||||
* https://html.spec.whatwg.org/multipage/scripting.html#invoke-custom-element-reactions
|
||||
*/
|
||||
void InvokeReactions(ElementQueue* aElementQueue, nsIGlobalObject* aGlobal);
|
||||
|
||||
void Enqueue(Element* aElement, CustomElementReaction* aReaction);
|
||||
|
||||
// Current [CEReactions] recursion depth.
|
||||
uint32_t mRecursionDepth;
|
||||
// True if the element queue is pushed into reaction stack for current
|
||||
// recursion depth. This will be cached in AutoCEReaction when entering a new
|
||||
// CEReaction recursion and restored after leaving the recursion.
|
||||
bool mIsElementQueuePushedForCurrentRecursionDepth;
|
||||
|
||||
private:
|
||||
class BackupQueueMicroTask final : public mozilla::MicroTaskRunnable {
|
||||
public:
|
||||
explicit BackupQueueMicroTask(CustomElementReactionsStack* aReactionStack)
|
||||
: MicroTaskRunnable()
|
||||
, mReactionStack(aReactionStack)
|
||||
{
|
||||
MOZ_ASSERT(!mReactionStack->mIsBackupQueueProcessing,
|
||||
"mIsBackupQueueProcessing should be initially false");
|
||||
mReactionStack->mIsBackupQueueProcessing = true;
|
||||
}
|
||||
|
||||
virtual void Run(AutoSlowOperation& aAso) override
|
||||
{
|
||||
mReactionStack->InvokeBackupQueue();
|
||||
mReactionStack->mIsBackupQueueProcessing = false;
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<CustomElementReactionsStack> mReactionStack;
|
||||
};
|
||||
};
|
||||
|
||||
class CustomElementRegistry final : public nsISupports,
|
||||
@@ -142,36 +404,33 @@ public:
|
||||
public:
|
||||
static bool IsCustomElementEnabled(JSContext* aCx = nullptr,
|
||||
JSObject* aObject = nullptr);
|
||||
static already_AddRefed<CustomElementRegistry> Create(nsPIDOMWindowInner* aWindow);
|
||||
static void ProcessTopElementQueue();
|
||||
|
||||
static void XPCOMShutdown();
|
||||
explicit CustomElementRegistry(nsPIDOMWindowInner* aWindow);
|
||||
|
||||
/**
|
||||
* Looking up a custom element definition.
|
||||
* https://html.spec.whatwg.org/#look-up-a-custom-element-definition
|
||||
*/
|
||||
CustomElementDefinition* LookupCustomElementDefinition(
|
||||
const nsAString& aLocalName, const nsAString* aIs = nullptr) const;
|
||||
nsIAtom* aNameAtom, nsIAtom* aTypeAtom) const;
|
||||
|
||||
/**
|
||||
* Enqueue created callback or register upgrade candidate for
|
||||
* newly created custom elements, possibly extending an existing type.
|
||||
* ex. <x-button>, <button is="x-button> (type extension)
|
||||
*/
|
||||
void SetupCustomElement(Element* aElement, const nsAString* aTypeExtension);
|
||||
CustomElementDefinition* LookupCustomElementDefinition(
|
||||
JSContext* aCx, JSObject *aConstructor) const;
|
||||
|
||||
void EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType,
|
||||
Element* aCustomElement,
|
||||
LifecycleCallbackArgs* aArgs,
|
||||
CustomElementDefinition* aDefinition);
|
||||
static void EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType,
|
||||
Element* aCustomElement,
|
||||
LifecycleCallbackArgs* aArgs,
|
||||
LifecycleAdoptedCallbackArgs* aAdoptedCallbackArgs,
|
||||
CustomElementDefinition* aDefinition);
|
||||
|
||||
void GetCustomPrototype(nsIAtom* aAtom,
|
||||
JS::MutableHandle<JSObject*> aPrototype);
|
||||
|
||||
private:
|
||||
explicit CustomElementRegistry(nsPIDOMWindowInner* aWindow);
|
||||
~CustomElementRegistry();
|
||||
/**
|
||||
* Upgrade an element.
|
||||
* https://html.spec.whatwg.org/multipage/scripting.html#upgrades
|
||||
*/
|
||||
static void Upgrade(Element* aElement, CustomElementDefinition* aDefinition, ErrorResult& aRv);
|
||||
|
||||
/**
|
||||
* Registers an unresolved custom element that is a candidate for
|
||||
@@ -184,23 +443,48 @@ private:
|
||||
void RegisterUnresolvedElement(Element* aElement,
|
||||
nsIAtom* aTypeName = nullptr);
|
||||
|
||||
void UpgradeCandidates(JSContext* aCx,
|
||||
nsIAtom* aKey,
|
||||
CustomElementDefinition* aDefinition);
|
||||
/**
|
||||
* Unregister an unresolved custom element that is a candidate for
|
||||
* upgrade when a custom element is removed from tree.
|
||||
*/
|
||||
void UnregisterUnresolvedElement(Element* aElement,
|
||||
nsIAtom* aTypeName = nullptr);
|
||||
private:
|
||||
~CustomElementRegistry();
|
||||
|
||||
typedef nsClassHashtable<nsISupportsHashKey, CustomElementDefinition>
|
||||
static UniquePtr<CustomElementCallback> CreateCustomElementCallback(
|
||||
nsIDocument::ElementCallbackType aType, Element* aCustomElement,
|
||||
LifecycleCallbackArgs* aArgs,
|
||||
LifecycleAdoptedCallbackArgs* aAdoptedCallbackArgs,
|
||||
CustomElementDefinition* aDefinition);
|
||||
|
||||
void UpgradeCandidates(nsIAtom* aKey,
|
||||
CustomElementDefinition* aDefinition,
|
||||
ErrorResult& aRv);
|
||||
|
||||
typedef nsRefPtrHashtable<nsISupportsHashKey, CustomElementDefinition>
|
||||
DefinitionMap;
|
||||
typedef nsClassHashtable<nsISupportsHashKey, nsTArray<nsWeakPtr>>
|
||||
CandidateMap;
|
||||
typedef JS::GCHashMap<JS::Heap<JSObject*>,
|
||||
nsCOMPtr<nsIAtom>,
|
||||
js::MovableCellHasher<JS::Heap<JSObject*>>,
|
||||
js::SystemAllocPolicy> ConstructorMap;
|
||||
|
||||
// Hashtable for custom element definitions in web components.
|
||||
// Custom prototypes are stored in the compartment where
|
||||
// registerElement was called.
|
||||
DefinitionMap mCustomDefinitions;
|
||||
|
||||
// Hashtable for looking up definitions by using constructor as key.
|
||||
// Custom elements' name are stored here and we need to lookup
|
||||
// mCustomDefinitions again to get definitions.
|
||||
ConstructorMap mConstructors;
|
||||
|
||||
typedef nsRefPtrHashtable<nsISupportsHashKey, Promise>
|
||||
WhenDefinedPromiseMap;
|
||||
WhenDefinedPromiseMap mWhenDefinedPromiseMap;
|
||||
|
||||
// The "upgrade candidates map" from the web components spec. Maps from a
|
||||
// namespace id and local name to a list of elements to upgrade if that
|
||||
// element is registered as a custom element.
|
||||
@@ -208,14 +492,6 @@ private:
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowInner> mWindow;
|
||||
|
||||
// Array representing the processing stack in the custom elements
|
||||
// specification. The processing stack is conceptually a stack of
|
||||
// element queues. Each queue is represented by a sequence of
|
||||
// CustomElementData in this array, separated by nullptr that
|
||||
// represent the boundaries of the items in the stack. The first
|
||||
// queue in the stack is the base element queue.
|
||||
static mozilla::Maybe<nsTArray<RefPtr<CustomElementData>>> sProcessingStack;
|
||||
|
||||
// It is used to prevent reentrant invocations of element definition.
|
||||
bool mIsCustomDefinitionRunning;
|
||||
|
||||
@@ -252,6 +528,31 @@ public:
|
||||
already_AddRefed<Promise> WhenDefined(const nsAString& aName, ErrorResult& aRv);
|
||||
};
|
||||
|
||||
class MOZ_RAII AutoCEReaction final {
|
||||
public:
|
||||
// JSContext is allowed to be a nullptr if we are guaranteeing that we're
|
||||
// not doing something that might throw but not finish reporting a JS
|
||||
// exception during the lifetime of the AutoCEReaction.
|
||||
AutoCEReaction(CustomElementReactionsStack* aReactionsStack, JSContext* aCx)
|
||||
: mReactionsStack(aReactionsStack)
|
||||
, mCx(aCx)
|
||||
{
|
||||
mIsElementQueuePushedForPreviousRecursionDepth =
|
||||
mReactionsStack->EnterCEReactions();
|
||||
}
|
||||
|
||||
~AutoCEReaction()
|
||||
{
|
||||
mReactionsStack->LeaveCEReactions(
|
||||
mCx, mIsElementQueuePushedForPreviousRecursionDepth);
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<CustomElementReactionsStack> mReactionsStack;
|
||||
JSContext* mCx;
|
||||
bool mIsElementQueuePushedForPreviousRecursionDepth;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
||||
@@ -46,6 +46,9 @@ DocGroup::DocGroup(TabGroup* aTabGroup, const nsACString& aKey)
|
||||
DocGroup::~DocGroup()
|
||||
{
|
||||
MOZ_ASSERT(mDocuments.IsEmpty());
|
||||
if (!NS_IsMainThread()) {
|
||||
NS_ReleaseOnMainThread(mReactionsStack.forget());
|
||||
}
|
||||
mTabGroup->mDocGroups.RemoveEntry(mKey);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "nsString.h"
|
||||
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/dom/CustomElementRegistry.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@@ -52,6 +53,14 @@ public:
|
||||
{
|
||||
return mTabGroup;
|
||||
}
|
||||
mozilla::dom::CustomElementReactionsStack* CustomElementReactionsStack()
|
||||
{
|
||||
if (!mReactionsStack) {
|
||||
mReactionsStack = new mozilla::dom::CustomElementReactionsStack();
|
||||
}
|
||||
|
||||
return mReactionsStack;
|
||||
}
|
||||
void RemoveDocument(nsIDocument* aWindow);
|
||||
|
||||
// Iterators for iterating over every document within the DocGroup
|
||||
@@ -71,6 +80,7 @@ private:
|
||||
nsCString mKey;
|
||||
RefPtr<TabGroup> mTabGroup;
|
||||
nsTArray<nsIDocument*> mDocuments;
|
||||
RefPtr<mozilla::dom::CustomElementReactionsStack> mReactionsStack;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
||||
+114
-44
@@ -479,9 +479,13 @@ Element::WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
if (data) {
|
||||
// If this is a registered custom element then fix the prototype.
|
||||
nsContentUtils::GetCustomPrototype(OwnerDoc(), NodeInfo()->NamespaceID(),
|
||||
data->mType, &customProto);
|
||||
data->GetCustomElementType(), &customProto);
|
||||
if (customProto &&
|
||||
NodePrincipal()->SubsumesConsideringDomain(nsContentUtils::ObjectPrincipal(customProto))) {
|
||||
// The custom element prototype could be in different compartment.
|
||||
if (!JS_WrapObject(aCx, &customProto)) {
|
||||
return nullptr;
|
||||
}
|
||||
// Just go ahead and create with the right proto up front. Set
|
||||
// customProto to null to flag that we don't need to do any post-facto
|
||||
// proto fixups here.
|
||||
@@ -1595,7 +1599,7 @@ Element::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
#endif
|
||||
{
|
||||
if (aBindingParent) {
|
||||
nsDOMSlots *slots = DOMSlots();
|
||||
nsExtendedDOMSlots* slots = ExtendedDOMSlots();
|
||||
|
||||
slots->mBindingParent = aBindingParent; // Weak, so no addref happens.
|
||||
}
|
||||
@@ -1618,7 +1622,7 @@ Element::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
}
|
||||
ShadowRoot* parentContainingShadow = aParent->GetContainingShadow();
|
||||
if (parentContainingShadow) {
|
||||
DOMSlots()->mContainingShadow = parentContainingShadow;
|
||||
ExtendedDOMSlots()->mContainingShadow = parentContainingShadow;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1684,14 +1688,17 @@ Element::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
SetSubtreeRootPointer(aParent->SubtreeRoot());
|
||||
}
|
||||
|
||||
nsIDocument* composedDoc = GetComposedDoc();
|
||||
if (composedDoc) {
|
||||
// Attached callback must be enqueued whenever custom element is inserted into a
|
||||
// document and this document has a browsing context.
|
||||
if (GetCustomElementData() && composedDoc->GetDocShell()) {
|
||||
// Enqueue an attached callback for the custom element.
|
||||
nsContentUtils::EnqueueLifecycleCallback(
|
||||
composedDoc, nsIDocument::eAttached, this);
|
||||
if (CustomElementRegistry::IsCustomElementEnabled() && IsInComposedDoc()) {
|
||||
// Connected callback must be enqueued whenever a custom element becomes
|
||||
// connected.
|
||||
CustomElementData* data = GetCustomElementData();
|
||||
if (data) {
|
||||
if (data->mState == CustomElementData::State::eCustom) {
|
||||
nsContentUtils::EnqueueLifecycleCallback(nsIDocument::eConnected, this);
|
||||
} else {
|
||||
// Step 7.7.2.2 https://dom.spec.whatwg.org/#concept-node-insert
|
||||
nsContentUtils::TryToUpgradeElement(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1986,12 +1993,21 @@ Element::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
|
||||
document->ClearBoxObjectFor(this);
|
||||
|
||||
// Detached must be enqueued whenever custom element is removed from
|
||||
// the document and this document has a browsing context.
|
||||
if (GetCustomElementData() && document->GetDocShell()) {
|
||||
// Enqueue a detached callback for the custom element.
|
||||
nsContentUtils::EnqueueLifecycleCallback(
|
||||
document, nsIDocument::eDetached, this);
|
||||
// Disconnected must be enqueued whenever a connected custom element becomes
|
||||
// disconnected.
|
||||
if (CustomElementRegistry::IsCustomElementEnabled()) {
|
||||
CustomElementData* data = GetCustomElementData();
|
||||
if (data) {
|
||||
if (data->mState == CustomElementData::State::eCustom) {
|
||||
nsContentUtils::EnqueueLifecycleCallback(nsIDocument::eDisconnected,
|
||||
this);
|
||||
} else {
|
||||
// Remove an unresolved custom element that is a candidate for
|
||||
// upgrade when a custom element is disconnected.
|
||||
// We will make sure it's shadow-including tree order in bug 1326028.
|
||||
nsContentUtils::UnregisterUnresolvedElement(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2007,7 +2023,7 @@ Element::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
}
|
||||
#endif
|
||||
|
||||
nsDOMSlots* slots = GetExistingDOMSlots();
|
||||
nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
|
||||
if (slots) {
|
||||
if (clearBindingParent) {
|
||||
slots->mBindingParent = nullptr;
|
||||
@@ -2055,7 +2071,7 @@ Element::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
nsICSSDeclaration*
|
||||
Element::GetSMILOverrideStyle()
|
||||
{
|
||||
Element::nsDOMSlots *slots = DOMSlots();
|
||||
Element::nsExtendedDOMSlots* slots = ExtendedDOMSlots();
|
||||
|
||||
if (!slots->mSMILOverrideStyle) {
|
||||
slots->mSMILOverrideStyle = new nsDOMCSSAttributeDeclaration(this, true);
|
||||
@@ -2067,7 +2083,7 @@ Element::GetSMILOverrideStyle()
|
||||
DeclarationBlock*
|
||||
Element::GetSMILOverrideStyleDeclaration()
|
||||
{
|
||||
Element::nsDOMSlots *slots = GetExistingDOMSlots();
|
||||
Element::nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
|
||||
return slots ? slots->mSMILOverrideStyleDeclaration.get() : nullptr;
|
||||
}
|
||||
|
||||
@@ -2075,7 +2091,7 @@ nsresult
|
||||
Element::SetSMILOverrideStyleDeclaration(DeclarationBlock* aDeclaration,
|
||||
bool aNotify)
|
||||
{
|
||||
Element::nsDOMSlots *slots = DOMSlots();
|
||||
Element::nsExtendedDOMSlots* slots = ExtendedDOMSlots();
|
||||
|
||||
slots->mSMILOverrideStyleDeclaration = aDeclaration;
|
||||
|
||||
@@ -2586,19 +2602,32 @@ Element::SetAttrAndNotify(int32_t aNamespaceID,
|
||||
|
||||
UpdateState(aNotify);
|
||||
|
||||
nsIDocument* ownerDoc = OwnerDoc();
|
||||
if (ownerDoc && GetCustomElementData()) {
|
||||
nsCOMPtr<nsIAtom> oldValueAtom = oldValue->GetAsAtom();
|
||||
nsCOMPtr<nsIAtom> newValueAtom = valueForAfterSetAttr.GetAsAtom();
|
||||
LifecycleCallbackArgs args = {
|
||||
nsDependentAtomString(aName),
|
||||
aModType == nsIDOMMutationEvent::ADDITION ?
|
||||
NullString() : nsDependentAtomString(oldValueAtom),
|
||||
nsDependentAtomString(newValueAtom)
|
||||
};
|
||||
if (CustomElementRegistry::IsCustomElementEnabled()) {
|
||||
if (CustomElementData* data = GetCustomElementData()) {
|
||||
if (CustomElementDefinition* definition =
|
||||
nsContentUtils::GetElementDefinitionIfObservingAttr(this,
|
||||
data->GetCustomElementType(),
|
||||
aName)) {
|
||||
MOZ_ASSERT(data->mState == CustomElementData::State::eCustom,
|
||||
"AttributeChanged callback should fire only if "
|
||||
"custom element state is custom");
|
||||
nsCOMPtr<nsIAtom> oldValueAtom = oldValue->GetAsAtom();
|
||||
nsCOMPtr<nsIAtom> newValueAtom = valueForAfterSetAttr.GetAsAtom();
|
||||
nsAutoString ns;
|
||||
nsContentUtils::NameSpaceManager()->GetNameSpaceURI(aNamespaceID, ns);
|
||||
|
||||
nsContentUtils::EnqueueLifecycleCallback(
|
||||
ownerDoc, nsIDocument::eAttributeChanged, this, &args);
|
||||
LifecycleCallbackArgs args = {
|
||||
nsDependentAtomString(aName),
|
||||
aModType == nsIDOMMutationEvent::ADDITION ?
|
||||
NullString() : nsDependentAtomString(oldValueAtom),
|
||||
nsDependentAtomString(newValueAtom),
|
||||
(ns.IsEmpty() ? NullString() : ns)
|
||||
};
|
||||
|
||||
nsContentUtils::EnqueueLifecycleCallback(nsIDocument::eAttributeChanged,
|
||||
this, &args, nullptr, definition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (aCallAfterSetAttr) {
|
||||
@@ -2843,17 +2872,30 @@ Element::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
|
||||
UpdateState(aNotify);
|
||||
|
||||
nsIDocument* ownerDoc = OwnerDoc();
|
||||
if (ownerDoc && GetCustomElementData()) {
|
||||
nsCOMPtr<nsIAtom> oldValueAtom = oldValue.GetAsAtom();
|
||||
LifecycleCallbackArgs args = {
|
||||
nsDependentAtomString(aName),
|
||||
nsDependentAtomString(oldValueAtom),
|
||||
NullString()
|
||||
};
|
||||
if (CustomElementRegistry::IsCustomElementEnabled()) {
|
||||
if (CustomElementData* data = GetCustomElementData()) {
|
||||
if (CustomElementDefinition* definition =
|
||||
nsContentUtils::GetElementDefinitionIfObservingAttr(this,
|
||||
data->GetCustomElementType(),
|
||||
aName)) {
|
||||
MOZ_ASSERT(data->mState == CustomElementData::State::eCustom,
|
||||
"AttributeChanged callback should fire only if "
|
||||
"custom element state is custom");
|
||||
nsAutoString ns;
|
||||
nsContentUtils::NameSpaceManager()->GetNameSpaceURI(aNameSpaceID, ns);
|
||||
|
||||
nsContentUtils::EnqueueLifecycleCallback(
|
||||
ownerDoc, nsIDocument::eAttributeChanged, this, &args);
|
||||
nsCOMPtr<nsIAtom> oldValueAtom = oldValue.GetAsAtom();
|
||||
LifecycleCallbackArgs args = {
|
||||
nsDependentAtomString(aName),
|
||||
nsDependentAtomString(oldValueAtom),
|
||||
NullString(),
|
||||
(ns.IsEmpty() ? NullString() : ns)
|
||||
};
|
||||
|
||||
nsContentUtils::EnqueueLifecycleCallback(nsIDocument::eAttributeChanged,
|
||||
this, &args, nullptr, definition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (aNotify) {
|
||||
@@ -3988,7 +4030,7 @@ Element::ClearDataset()
|
||||
nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>*
|
||||
Element::RegisteredIntersectionObservers()
|
||||
{
|
||||
nsDOMSlots* slots = DOMSlots();
|
||||
nsExtendedDOMSlots* slots = ExtendedDOMSlots();
|
||||
return &slots->mRegisteredIntersectionObservers;
|
||||
}
|
||||
|
||||
@@ -4037,3 +4079,31 @@ Element::UpdateIntersectionObservation(DOMIntersectionObserver* aObserver, int32
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
Element::SetCustomElementData(CustomElementData* aData)
|
||||
{
|
||||
nsExtendedDOMSlots *slots = ExtendedDOMSlots();
|
||||
MOZ_ASSERT(!slots->mCustomElementData, "Custom element data may not be changed once set.");
|
||||
slots->mCustomElementData = aData;
|
||||
}
|
||||
|
||||
CustomElementDefinition*
|
||||
Element::GetCustomElementDefinition() const
|
||||
{
|
||||
CustomElementData* data = GetCustomElementData();
|
||||
if (!data) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return data->GetCustomElementDefinition();
|
||||
}
|
||||
|
||||
void
|
||||
Element::SetCustomElementDefinition(CustomElementDefinition* aDefinition)
|
||||
{
|
||||
CustomElementData* data = GetCustomElementData();
|
||||
MOZ_ASSERT(data);
|
||||
|
||||
data->SetCustomElementDefinition(aDefinition);
|
||||
}
|
||||
+40
-1
@@ -390,6 +390,45 @@ public:
|
||||
|
||||
Directionality GetComputedDirectionality() const;
|
||||
|
||||
/**
|
||||
* Gets the custom element data used by web components custom element.
|
||||
* Custom element data is created at the first attempt to enqueue a callback.
|
||||
*
|
||||
* @return The custom element data or null if none.
|
||||
*/
|
||||
inline CustomElementData* GetCustomElementData() const
|
||||
{
|
||||
nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
|
||||
if (slots) {
|
||||
return slots->mCustomElementData;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the custom element data, ownership of the
|
||||
* callback data is taken by this element.
|
||||
*
|
||||
* @param aData The custom element data.
|
||||
*/
|
||||
void SetCustomElementData(CustomElementData* aData);
|
||||
|
||||
/**
|
||||
* Gets the custom element definition used by web components custom element.
|
||||
*
|
||||
* @return The custom element definition or null if element is not a custom
|
||||
* element or custom element is not defined yet.
|
||||
*/
|
||||
CustomElementDefinition* GetCustomElementDefinition() const;
|
||||
|
||||
/**
|
||||
* Sets the custom element definition, called when custom element is created
|
||||
* or upgraded.
|
||||
*
|
||||
* @param aDefinition The custom element definition.
|
||||
*/
|
||||
void SetCustomElementDefinition(CustomElementDefinition* aDefinition);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Method to get the _intrinsic_ content state of this element. This is the
|
||||
@@ -814,7 +853,7 @@ public:
|
||||
|
||||
ShadowRoot *FastGetShadowRoot() const
|
||||
{
|
||||
nsDOMSlots* slots = GetExistingDOMSlots();
|
||||
nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
|
||||
return slots ? slots->mShadowRoot.get() : nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -530,8 +530,7 @@ nsNodeSupportsWeakRefTearoff::GetWeakReference(nsIWeakReference** aInstancePtr)
|
||||
//----------------------------------------------------------------------
|
||||
FragmentOrElement::nsDOMSlots::nsDOMSlots()
|
||||
: nsINode::nsSlots(),
|
||||
mDataset(nullptr),
|
||||
mBindingParent(nullptr)
|
||||
mDataset(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -543,84 +542,104 @@ FragmentOrElement::nsDOMSlots::~nsDOMSlots()
|
||||
}
|
||||
|
||||
void
|
||||
FragmentOrElement::nsDOMSlots::Traverse(nsCycleCollectionTraversalCallback &cb, bool aIsXUL)
|
||||
FragmentOrElement::nsDOMSlots::Traverse(nsCycleCollectionTraversalCallback &cb)
|
||||
{
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mStyle");
|
||||
cb.NoteXPCOMChild(mStyle.get());
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mSMILOverrideStyle");
|
||||
cb.NoteXPCOMChild(mSMILOverrideStyle.get());
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mAttributeMap");
|
||||
cb.NoteXPCOMChild(mAttributeMap.get());
|
||||
|
||||
if (aIsXUL) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mControllers");
|
||||
cb.NoteXPCOMChild(mControllers);
|
||||
}
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mXBLBinding");
|
||||
cb.NoteNativeChild(mXBLBinding, NS_CYCLE_COLLECTION_PARTICIPANT(nsXBLBinding));
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mXBLInsertionParent");
|
||||
cb.NoteXPCOMChild(mXBLInsertionParent.get());
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mShadowRoot");
|
||||
cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mShadowRoot));
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mContainingShadow");
|
||||
cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mContainingShadow));
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mChildrenList");
|
||||
cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMNodeList*, mChildrenList));
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mLabelsList");
|
||||
cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMNodeList*, mLabelsList));
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mClassList");
|
||||
cb.NoteXPCOMChild(mClassList.get());
|
||||
|
||||
if (mCustomElementData) {
|
||||
for (uint32_t i = 0; i < mCustomElementData->mCallbackQueue.Length(); i++) {
|
||||
mCustomElementData->mCallbackQueue[i]->Traverse(cb);
|
||||
}
|
||||
if (!mExtendedSlots) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto iter = mRegisteredIntersectionObservers.Iter(); !iter.Done(); iter.Next()) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mSMILOverrideStyle");
|
||||
cb.NoteXPCOMChild(mExtendedSlots->mSMILOverrideStyle.get());
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mControllers");
|
||||
cb.NoteXPCOMChild(mExtendedSlots->mControllers);
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mLabelsList");
|
||||
cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMNodeList*,mExtendedSlots-> mLabelsList));
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mShadowRoot");
|
||||
cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mExtendedSlots->mShadowRoot));
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mContainingShadow");
|
||||
cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mExtendedSlots->mContainingShadow));
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mXBLBinding");
|
||||
cb.NoteNativeChild(mExtendedSlots->mXBLBinding,
|
||||
NS_CYCLE_COLLECTION_PARTICIPANT(nsXBLBinding));
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mXBLInsertionParent");
|
||||
cb.NoteXPCOMChild(mExtendedSlots->mXBLInsertionParent.get());
|
||||
|
||||
if (mExtendedSlots->mCustomElementData) {
|
||||
mExtendedSlots->mCustomElementData->Traverse(cb);
|
||||
}
|
||||
|
||||
for (auto iter = mExtendedSlots->mRegisteredIntersectionObservers.Iter();
|
||||
!iter.Done(); iter.Next()) {
|
||||
DOMIntersectionObserver* observer = iter.Key();
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mRegisteredIntersectionObservers[i]");
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
|
||||
"mExtendedSlots->mRegisteredIntersectionObservers[i]");
|
||||
cb.NoteXPCOMChild(observer);
|
||||
}
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mFrameLoaderOrOpener");
|
||||
cb.NoteXPCOMChild(mExtendedSlots->mFrameLoaderOrOpener);
|
||||
}
|
||||
|
||||
void
|
||||
FragmentOrElement::nsDOMSlots::Unlink(bool aIsXUL)
|
||||
FragmentOrElement::nsDOMSlots::Unlink()
|
||||
{
|
||||
mStyle = nullptr;
|
||||
mSMILOverrideStyle = nullptr;
|
||||
if (mAttributeMap) {
|
||||
mAttributeMap->DropReference();
|
||||
mAttributeMap = nullptr;
|
||||
}
|
||||
if (aIsXUL)
|
||||
NS_IF_RELEASE(mControllers);
|
||||
|
||||
MOZ_ASSERT(!mXBLBinding);
|
||||
|
||||
mXBLInsertionParent = nullptr;
|
||||
mShadowRoot = nullptr;
|
||||
mContainingShadow = nullptr;
|
||||
mChildrenList = nullptr;
|
||||
mLabelsList = nullptr;
|
||||
mCustomElementData = nullptr;
|
||||
mClassList = nullptr;
|
||||
mRegisteredIntersectionObservers.Clear();
|
||||
|
||||
if (!mExtendedSlots) {
|
||||
return;
|
||||
}
|
||||
|
||||
mExtendedSlots->mSMILOverrideStyle = nullptr;
|
||||
mExtendedSlots->mControllers = nullptr;
|
||||
mExtendedSlots->mLabelsList = nullptr;
|
||||
mExtendedSlots->mShadowRoot = nullptr;
|
||||
mExtendedSlots->mContainingShadow = nullptr;
|
||||
MOZ_ASSERT(!(mExtendedSlots->mXBLBinding));
|
||||
mExtendedSlots->mXBLInsertionParent = nullptr;
|
||||
if (mExtendedSlots->mCustomElementData) {
|
||||
mExtendedSlots->mCustomElementData->Unlink();
|
||||
mExtendedSlots->mCustomElementData = nullptr;
|
||||
}
|
||||
mExtendedSlots->mRegisteredIntersectionObservers.Clear();
|
||||
nsCOMPtr<nsIFrameLoader> frameLoader =
|
||||
do_QueryInterface(mExtendedSlots->mFrameLoaderOrOpener);
|
||||
if (frameLoader) {
|
||||
static_cast<nsFrameLoader*>(frameLoader.get())->Destroy();
|
||||
}
|
||||
mExtendedSlots->mFrameLoaderOrOpener = nullptr;
|
||||
}
|
||||
|
||||
size_t
|
||||
FragmentOrElement::nsDOMSlots::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
size_t n = aMallocSizeOf(this);
|
||||
if (mExtendedSlots) {
|
||||
n += aMallocSizeOf(mExtendedSlots.get());
|
||||
}
|
||||
|
||||
if (mAttributeMap) {
|
||||
n += mAttributeMap->SizeOfIncludingThis(aMallocSizeOf);
|
||||
@@ -641,6 +660,19 @@ FragmentOrElement::nsDOMSlots::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) c
|
||||
return n;
|
||||
}
|
||||
|
||||
FragmentOrElement::nsExtendedDOMSlots::nsExtendedDOMSlots()
|
||||
: mBindingParent(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
FragmentOrElement::nsExtendedDOMSlots::~nsExtendedDOMSlots()
|
||||
{
|
||||
nsCOMPtr<nsIFrameLoader> frameLoader = do_QueryInterface(mFrameLoaderOrOpener);
|
||||
if (frameLoader) {
|
||||
static_cast<nsFrameLoader*>(frameLoader.get())->Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
FragmentOrElement::FragmentOrElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
|
||||
: nsIContent(aNodeInfo)
|
||||
{
|
||||
@@ -962,7 +994,7 @@ FragmentOrElement::IsLink(nsIURI** aURI) const
|
||||
nsIContent*
|
||||
FragmentOrElement::GetBindingParent() const
|
||||
{
|
||||
nsDOMSlots *slots = GetExistingDOMSlots();
|
||||
nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
|
||||
|
||||
if (slots) {
|
||||
return slots->mBindingParent;
|
||||
@@ -974,7 +1006,7 @@ nsXBLBinding*
|
||||
FragmentOrElement::GetXBLBinding() const
|
||||
{
|
||||
if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
|
||||
nsDOMSlots *slots = GetExistingDOMSlots();
|
||||
nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
|
||||
if (slots) {
|
||||
return slots->mXBLBinding;
|
||||
}
|
||||
@@ -1009,11 +1041,11 @@ FragmentOrElement::SetXBLBinding(nsXBLBinding* aBinding,
|
||||
|
||||
if (aBinding) {
|
||||
SetFlags(NODE_MAY_BE_IN_BINDING_MNGR);
|
||||
nsDOMSlots *slots = DOMSlots();
|
||||
nsExtendedDOMSlots* slots = ExtendedDOMSlots();
|
||||
slots->mXBLBinding = aBinding;
|
||||
bindingManager->AddBoundContent(this);
|
||||
} else {
|
||||
nsDOMSlots *slots = GetExistingDOMSlots();
|
||||
nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
|
||||
if (slots) {
|
||||
slots->mXBLBinding = nullptr;
|
||||
}
|
||||
@@ -1028,7 +1060,7 @@ nsIContent*
|
||||
FragmentOrElement::GetXBLInsertionParent() const
|
||||
{
|
||||
if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
|
||||
nsDOMSlots *slots = GetExistingDOMSlots();
|
||||
nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
|
||||
if (slots) {
|
||||
return slots->mXBLInsertionParent;
|
||||
}
|
||||
@@ -1040,7 +1072,7 @@ FragmentOrElement::GetXBLInsertionParent() const
|
||||
ShadowRoot*
|
||||
FragmentOrElement::GetContainingShadow() const
|
||||
{
|
||||
nsDOMSlots *slots = GetExistingDOMSlots();
|
||||
nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
|
||||
if (slots) {
|
||||
return slots->mContainingShadow;
|
||||
}
|
||||
@@ -1050,21 +1082,21 @@ FragmentOrElement::GetContainingShadow() const
|
||||
void
|
||||
FragmentOrElement::SetShadowRoot(ShadowRoot* aShadowRoot)
|
||||
{
|
||||
nsDOMSlots *slots = DOMSlots();
|
||||
nsExtendedDOMSlots* slots = ExtendedDOMSlots();
|
||||
slots->mShadowRoot = aShadowRoot;
|
||||
}
|
||||
|
||||
nsTArray<nsIContent*>&
|
||||
FragmentOrElement::DestInsertionPoints()
|
||||
{
|
||||
nsDOMSlots *slots = DOMSlots();
|
||||
nsExtendedDOMSlots* slots = ExtendedDOMSlots();
|
||||
return slots->mDestInsertionPoints;
|
||||
}
|
||||
|
||||
nsTArray<nsIContent*>*
|
||||
FragmentOrElement::GetExistingDestInsertionPoints() const
|
||||
{
|
||||
nsDOMSlots *slots = GetExistingDOMSlots();
|
||||
nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
|
||||
if (slots) {
|
||||
return &slots->mDestInsertionPoints;
|
||||
}
|
||||
@@ -1075,35 +1107,17 @@ void
|
||||
FragmentOrElement::SetXBLInsertionParent(nsIContent* aContent)
|
||||
{
|
||||
if (aContent) {
|
||||
nsDOMSlots *slots = DOMSlots();
|
||||
nsExtendedDOMSlots* slots = ExtendedDOMSlots();
|
||||
SetFlags(NODE_MAY_BE_IN_BINDING_MNGR);
|
||||
slots->mXBLInsertionParent = aContent;
|
||||
} else {
|
||||
nsDOMSlots *slots = GetExistingDOMSlots();
|
||||
nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
|
||||
if (slots) {
|
||||
slots->mXBLInsertionParent = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CustomElementData*
|
||||
FragmentOrElement::GetCustomElementData() const
|
||||
{
|
||||
nsDOMSlots *slots = GetExistingDOMSlots();
|
||||
if (slots) {
|
||||
return slots->mCustomElementData;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
FragmentOrElement::SetCustomElementData(CustomElementData* aData)
|
||||
{
|
||||
nsDOMSlots *slots = DOMSlots();
|
||||
MOZ_ASSERT(!slots->mCustomElementData, "Custom element data may not be changed once set.");
|
||||
slots->mCustomElementData = aData;
|
||||
}
|
||||
|
||||
nsresult
|
||||
FragmentOrElement::InsertChildAt(nsIContent* aKid,
|
||||
uint32_t aIndex,
|
||||
@@ -1366,14 +1380,15 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(FragmentOrElement)
|
||||
{
|
||||
nsDOMSlots *slots = tmp->GetExistingDOMSlots();
|
||||
if (slots) {
|
||||
if (tmp->IsElement()) {
|
||||
if (slots->mExtendedSlots && tmp->IsElement()) {
|
||||
Element* elem = tmp->AsElement();
|
||||
for (auto iter = slots->mRegisteredIntersectionObservers.Iter(); !iter.Done(); iter.Next()) {
|
||||
for (auto iter = slots->mExtendedSlots->mRegisteredIntersectionObservers.Iter();
|
||||
!iter.Done(); iter.Next()) {
|
||||
DOMIntersectionObserver* observer = iter.Key();
|
||||
observer->UnlinkTarget(*elem);
|
||||
}
|
||||
}
|
||||
slots->Unlink(tmp->IsXULElement());
|
||||
slots->Unlink();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1938,7 +1953,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(FragmentOrElement)
|
||||
{
|
||||
nsDOMSlots *slots = tmp->GetExistingDOMSlots();
|
||||
if (slots) {
|
||||
slots->Traverse(cb, tmp->IsXULElement());
|
||||
slots->Traverse(cb);
|
||||
}
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "nsAttrAndChildArray.h" // member
|
||||
#include "nsCycleCollectionParticipant.h" // NS_DECL_CYCLE_*
|
||||
#include "nsIContent.h" // base class
|
||||
@@ -37,6 +38,7 @@ class nsIURI;
|
||||
namespace mozilla {
|
||||
class DeclarationBlock;
|
||||
namespace dom {
|
||||
struct CustomElementData;
|
||||
class DOMIntersectionObserver;
|
||||
class Element;
|
||||
} // namespace dom
|
||||
@@ -159,9 +161,6 @@ public:
|
||||
virtual void SetXBLInsertionParent(nsIContent* aContent) override;
|
||||
virtual bool IsLink(nsIURI** aURI) const override;
|
||||
|
||||
virtual CustomElementData *GetCustomElementData() const override;
|
||||
virtual void SetCustomElementData(CustomElementData* aData) override;
|
||||
|
||||
virtual void DestroyContent() override;
|
||||
virtual void SaveSubtreeState() override;
|
||||
|
||||
@@ -241,8 +240,6 @@ protected:
|
||||
nsresult CopyInnerTo(FragmentOrElement* aDest);
|
||||
|
||||
public:
|
||||
// Because of a bug in MS C++ compiler nsDOMSlots must be declared public,
|
||||
// otherwise nsXULElement::nsXULSlots doesn't compile.
|
||||
/**
|
||||
* There are a set of DOM- and scripting-specific instance variables
|
||||
* that may only be instantiated when a content object is accessed
|
||||
@@ -251,29 +248,13 @@ public:
|
||||
* in a side structure that's only allocated when the content is
|
||||
* accessed through the DOM.
|
||||
*/
|
||||
class nsDOMSlots : public nsINode::nsSlots
|
||||
|
||||
class nsExtendedDOMSlots
|
||||
{
|
||||
public:
|
||||
nsDOMSlots();
|
||||
virtual ~nsDOMSlots();
|
||||
nsExtendedDOMSlots();
|
||||
|
||||
void Traverse(nsCycleCollectionTraversalCallback &cb, bool aIsXUL);
|
||||
void Unlink(bool aIsXUL);
|
||||
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
||||
|
||||
/**
|
||||
* The .style attribute (an interface that forwards to the actual
|
||||
* style rules)
|
||||
* @see nsGenericHTMLElement::GetStyle
|
||||
*/
|
||||
nsCOMPtr<nsICSSDeclaration> mStyle;
|
||||
|
||||
/**
|
||||
* The .dataset attribute.
|
||||
* @see nsGenericHTMLElement::GetDataset
|
||||
*/
|
||||
nsDOMStringMap* mDataset; // [Weak]
|
||||
~nsExtendedDOMSlots();
|
||||
|
||||
/**
|
||||
* SMIL Overridde style rules (for SMIL animation of CSS properties)
|
||||
@@ -287,35 +268,17 @@ public:
|
||||
RefPtr<mozilla::DeclarationBlock> mSMILOverrideStyleDeclaration;
|
||||
|
||||
/**
|
||||
* An object implementing nsIDOMMozNamedAttrMap for this content (attributes)
|
||||
* @see FragmentOrElement::GetAttributes
|
||||
*/
|
||||
RefPtr<nsDOMAttributeMap> mAttributeMap;
|
||||
|
||||
union {
|
||||
/**
|
||||
* The nearest enclosing content node with a binding that created us.
|
||||
* @see FragmentOrElement::GetBindingParent
|
||||
*/
|
||||
nsIContent* mBindingParent; // [Weak]
|
||||
|
||||
/**
|
||||
* The controllers of the XUL Element.
|
||||
*/
|
||||
nsIControllers* mControllers; // [OWNER]
|
||||
};
|
||||
* The nearest enclosing content node with a binding that created us.
|
||||
* @see FragmentOrElement::GetBindingParent
|
||||
*/
|
||||
nsIContent* mBindingParent; // [Weak]
|
||||
|
||||
/**
|
||||
* An object implementing the .children property for this element.
|
||||
*/
|
||||
RefPtr<nsContentList> mChildrenList;
|
||||
* The controllers of the XUL Element.
|
||||
*/
|
||||
nsCOMPtr<nsIControllers> mControllers;
|
||||
|
||||
/**
|
||||
* An object implementing the .classList property for this element.
|
||||
*/
|
||||
RefPtr<nsDOMTokenList> mClassList;
|
||||
|
||||
/*
|
||||
* An object implementing the .labels property for this element.
|
||||
*/
|
||||
RefPtr<nsLabelsNodeList> mLabelsList;
|
||||
@@ -356,6 +319,55 @@ public:
|
||||
*/
|
||||
nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>
|
||||
mRegisteredIntersectionObservers;
|
||||
|
||||
/**
|
||||
* For XUL to hold either frameloader or opener.
|
||||
*/
|
||||
nsCOMPtr<nsISupports> mFrameLoaderOrOpener;
|
||||
|
||||
};
|
||||
|
||||
class nsDOMSlots : public nsINode::nsSlots
|
||||
{
|
||||
public:
|
||||
nsDOMSlots();
|
||||
virtual ~nsDOMSlots();
|
||||
|
||||
void Traverse(nsCycleCollectionTraversalCallback &cb);
|
||||
void Unlink();
|
||||
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
||||
|
||||
/**
|
||||
* The .style attribute (an interface that forwards to the actual
|
||||
* style rules)
|
||||
* @see nsGenericHTMLElement::GetStyle
|
||||
*/
|
||||
nsCOMPtr<nsICSSDeclaration> mStyle;
|
||||
|
||||
/**
|
||||
* The .dataset attribute.
|
||||
* @see nsGenericHTMLElement::GetDataset
|
||||
*/
|
||||
nsDOMStringMap* mDataset; // [Weak]
|
||||
|
||||
/**
|
||||
* An object implementing nsIDOMMozNamedAttrMap for this content (attributes)
|
||||
* @see FragmentOrElement::GetAttributes
|
||||
*/
|
||||
RefPtr<nsDOMAttributeMap> mAttributeMap;
|
||||
|
||||
/**
|
||||
* An object implementing the .children property for this element.
|
||||
*/
|
||||
RefPtr<nsContentList> mChildrenList;
|
||||
|
||||
/**
|
||||
* An object implementing the .classList property for this element.
|
||||
*/
|
||||
RefPtr<nsDOMTokenList> mClassList;
|
||||
|
||||
mozilla::UniquePtr<nsExtendedDOMSlots> mExtendedSlots;
|
||||
};
|
||||
|
||||
protected:
|
||||
@@ -375,6 +387,26 @@ protected:
|
||||
return static_cast<nsDOMSlots*>(GetExistingSlots());
|
||||
}
|
||||
|
||||
nsExtendedDOMSlots* ExtendedDOMSlots()
|
||||
{
|
||||
nsDOMSlots* slots = DOMSlots();
|
||||
if (!slots->mExtendedSlots) {
|
||||
slots->mExtendedSlots = MakeUnique<nsExtendedDOMSlots>();
|
||||
}
|
||||
|
||||
return slots->mExtendedSlots.get();
|
||||
}
|
||||
|
||||
nsExtendedDOMSlots* GetExistingExtendedDOMSlots() const
|
||||
{
|
||||
nsDOMSlots* slots = GetExistingDOMSlots();
|
||||
if (slots) {
|
||||
return slots->mExtendedSlots.get();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls SetIsElementInStyleScopeFlagOnSubtree for each shadow tree attached
|
||||
* to this node, which is assumed to be an Element.
|
||||
|
||||
@@ -37,10 +37,7 @@
|
||||
#include "mozilla/dom/PowerManager.h"
|
||||
#include "mozilla/dom/WakeLock.h"
|
||||
#include "mozilla/dom/power/PowerManagerService.h"
|
||||
#include "mozilla/dom/FlyWebPublishedServer.h"
|
||||
#include "mozilla/dom/FlyWebService.h"
|
||||
#include "mozilla/dom/Permissions.h"
|
||||
#include "mozilla/dom/Presentation.h"
|
||||
#include "mozilla/dom/ServiceWorkerContainer.h"
|
||||
#include "mozilla/dom/StorageManager.h"
|
||||
#include "mozilla/dom/TCPSocket.h"
|
||||
@@ -67,8 +64,6 @@
|
||||
#include "nsIAppsService.h"
|
||||
#include "mozIApplication.h"
|
||||
#include "WidgetUtils.h"
|
||||
#include "nsIPresentationService.h"
|
||||
|
||||
#include "mozilla/dom/MediaDevices.h"
|
||||
#include "MediaManager.h"
|
||||
|
||||
@@ -218,7 +213,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Navigator)
|
||||
#ifdef MOZ_EME
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMediaKeySystemAccessManager)
|
||||
#endif
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPresentation)
|
||||
#ifdef MOZ_GAMEPAD
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGamepadServiceTest)
|
||||
#endif
|
||||
@@ -284,10 +278,6 @@ Navigator::Invalidate()
|
||||
mTimeManager = nullptr;
|
||||
}
|
||||
|
||||
if (mPresentation) {
|
||||
mPresentation = nullptr;
|
||||
}
|
||||
|
||||
mServiceWorkerContainer = nullptr;
|
||||
|
||||
#ifdef MOZ_EME
|
||||
@@ -1364,41 +1354,6 @@ Navigator::GetBattery(ErrorResult& aRv)
|
||||
return mBatteryPromise;
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
Navigator::PublishServer(const nsAString& aName,
|
||||
const FlyWebPublishOptions& aOptions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
RefPtr<FlyWebService> service = FlyWebService::GetOrCreate();
|
||||
if (!service) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<FlyWebPublishPromise> mozPromise =
|
||||
service->PublishServer(aName, aOptions, mWindow);
|
||||
MOZ_ASSERT(mozPromise);
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(mWindow);
|
||||
ErrorResult result;
|
||||
RefPtr<Promise> domPromise = Promise::Create(global, result);
|
||||
if (result.Failed()) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mozPromise->Then(AbstractThread::MainThread(),
|
||||
__func__,
|
||||
[domPromise] (FlyWebPublishedServer* aServer) {
|
||||
domPromise->MaybeResolve(aServer);
|
||||
},
|
||||
[domPromise] (nsresult aStatus) {
|
||||
domPromise->MaybeReject(aStatus);
|
||||
});
|
||||
|
||||
return domPromise.forget();
|
||||
}
|
||||
|
||||
PowerManager*
|
||||
Navigator::GetMozPower(ErrorResult& aRv)
|
||||
{
|
||||
@@ -1931,19 +1886,5 @@ Navigator::RequestMediaKeySystemAccess(const nsAString& aKeySystem,
|
||||
}
|
||||
#endif
|
||||
|
||||
Presentation*
|
||||
Navigator::GetPresentation(ErrorResult& aRv)
|
||||
{
|
||||
if (!mPresentation) {
|
||||
if (!mWindow) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
mPresentation = Presentation::Create(mWindow);
|
||||
}
|
||||
|
||||
return mPresentation;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
@@ -39,8 +39,6 @@ class WakeLock;
|
||||
class ArrayBufferViewOrBlobOrStringOrFormData;
|
||||
class ServiceWorkerContainer;
|
||||
class DOMRequest;
|
||||
struct FlyWebPublishOptions;
|
||||
struct FlyWebFilter;
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -74,7 +72,6 @@ class Connection;
|
||||
} // namespace network
|
||||
|
||||
class PowerManager;
|
||||
class Presentation;
|
||||
class LegacyMozTCPSocket;
|
||||
class StorageManager;
|
||||
|
||||
@@ -141,9 +138,6 @@ public:
|
||||
Geolocation* GetGeolocation(ErrorResult& aRv);
|
||||
Promise* GetBattery(ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<Promise> PublishServer(const nsAString& aName,
|
||||
const FlyWebPublishOptions& aOptions,
|
||||
ErrorResult& aRv);
|
||||
static void AppName(nsAString& aAppName, bool aUsePrefOverriddenValue);
|
||||
|
||||
static nsresult GetPlatform(nsAString& aPlatform,
|
||||
@@ -210,8 +204,6 @@ public:
|
||||
system::AudioChannelManager* GetMozAudioChannelManager(ErrorResult& aRv);
|
||||
#endif // MOZ_AUDIO_CHANNEL_MANAGER
|
||||
|
||||
Presentation* GetPresentation(ErrorResult& aRv);
|
||||
|
||||
bool SendBeacon(const nsAString& aUrl,
|
||||
const Nullable<ArrayBufferViewOrBlobOrStringOrFormData>& aData,
|
||||
ErrorResult& aRv);
|
||||
@@ -288,7 +280,6 @@ private:
|
||||
RefPtr<time::TimeManager> mTimeManager;
|
||||
RefPtr<ServiceWorkerContainer> mServiceWorkerContainer;
|
||||
nsCOMPtr<nsPIDOMWindowInner> mWindow;
|
||||
RefPtr<Presentation> mPresentation;
|
||||
#ifdef MOZ_GAMEPAD
|
||||
RefPtr<GamepadServiceTest> mGamepadServiceTest;
|
||||
#endif
|
||||
|
||||
@@ -75,8 +75,8 @@ ShadowRoot::ShadowRoot(nsIContent* aContent,
|
||||
|
||||
SetFlags(NODE_IS_IN_SHADOW_TREE);
|
||||
|
||||
DOMSlots()->mBindingParent = aContent;
|
||||
DOMSlots()->mContainingShadow = this;
|
||||
ExtendedDOMSlots()->mBindingParent = aContent;
|
||||
ExtendedDOMSlots()->mContainingShadow = this;
|
||||
|
||||
// Add the ShadowRoot as a mutation observer on the host to watch
|
||||
// for mutations because the insertion points in this ShadowRoot
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<script>
|
||||
var o1 = document.documentElement;
|
||||
var o2 = document.createElement("frame");
|
||||
document.documentElement.appendChild(o2);
|
||||
var o3 = o2.contentWindow;
|
||||
o1.parentNode.removeChild(o1);
|
||||
o3.customElements;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -209,3 +209,4 @@ load 1230422.html
|
||||
load 1251361.html
|
||||
load 1304437.html
|
||||
pref(clipboard.autocopy,true) load 1385272-1.html
|
||||
pref(dom.webcomponents.customelements.enabled,true) load 1341693.html
|
||||
@@ -1526,6 +1526,40 @@ nsAttrValue::ParseIntWithFallback(const nsAString& aString, int32_t aDefault,
|
||||
SetIntValueAndType(val, eInteger, nonStrict ? &aString : nullptr);
|
||||
}
|
||||
|
||||
void
|
||||
nsAttrValue::ParseClampedNonNegativeInt(const nsAString& aString,
|
||||
int32_t aDefault, int32_t aMin,
|
||||
int32_t aMax)
|
||||
{
|
||||
ResetIfSet();
|
||||
|
||||
nsContentUtils::ParseHTMLIntegerResultFlags result;
|
||||
int32_t val = nsContentUtils::ParseHTMLInteger(aString, &result);
|
||||
bool nonStrict = (result & nsContentUtils::eParseHTMLInteger_IsPercent) ||
|
||||
(result & nsContentUtils::eParseHTMLInteger_NonStandard) ||
|
||||
(result & nsContentUtils::eParseHTMLInteger_DidNotConsumeAllInput);
|
||||
|
||||
if (result & nsContentUtils::eParseHTMLInteger_ErrorOverflow) {
|
||||
if (result & nsContentUtils::eParseHTMLInteger_Negative) {
|
||||
val = aDefault;
|
||||
} else {
|
||||
val = aMax;
|
||||
}
|
||||
nonStrict = true;
|
||||
} else if ((result & nsContentUtils::eParseHTMLInteger_Error) || val < 0) {
|
||||
val = aDefault;
|
||||
nonStrict = true;
|
||||
} else if (val < aMin) {
|
||||
val = aMin;
|
||||
nonStrict = true;
|
||||
} else if (val > aMax) {
|
||||
val = aMax;
|
||||
nonStrict = true;
|
||||
}
|
||||
|
||||
SetIntValueAndType(val, eInteger, nonStrict ? &aString : nullptr);
|
||||
}
|
||||
|
||||
bool
|
||||
nsAttrValue::ParseNonNegativeIntValue(const nsAString& aString)
|
||||
{
|
||||
|
||||
@@ -362,6 +362,19 @@ public:
|
||||
*/
|
||||
bool ParseNonNegativeIntValue(const nsAString& aString);
|
||||
|
||||
/**
|
||||
* Parse a string value into a clamped non-negative integer.
|
||||
* This method follows the rules for parsing non-negative integer from:
|
||||
* https://html.spec.whatwg.org/multipage/infrastructure.html#clamped-to-the-range
|
||||
*
|
||||
* @param aString the string to parse
|
||||
* @param aDefault value to return for negative or invalid values
|
||||
* @param aMin minimum value
|
||||
* @param aMax maximum value
|
||||
*/
|
||||
void ParseClampedNonNegativeInt(const nsAString& aString, int32_t aDefault,
|
||||
int32_t aMin, int32_t aMax);
|
||||
|
||||
/**
|
||||
* Parse a string value into a positive integer.
|
||||
* This method follows the rules for parsing non-negative integer from:
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace mozilla {
|
||||
namespace dom {
|
||||
class Element;
|
||||
class NodeInfo;
|
||||
struct CustomElementDefinition;
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -41,7 +42,8 @@ nsresult
|
||||
NS_NewHTMLElement(mozilla::dom::Element** aResult,
|
||||
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
|
||||
mozilla::dom::FromParser aFromParser,
|
||||
const nsAString* aIs = nullptr);
|
||||
const nsAString* aIs = nullptr,
|
||||
mozilla::dom::CustomElementDefinition* aDefinition = nullptr);
|
||||
|
||||
// First argument should be nsHTMLTag, but that adds dependency to parser
|
||||
// for a bunch of files.
|
||||
|
||||
+100
-83
@@ -227,6 +227,7 @@ extern "C" int MOZ_XMLCheckQName(const char* ptr, const char* end,
|
||||
int ns_aware, const char** colon);
|
||||
|
||||
class imgLoader;
|
||||
class nsIAtom;
|
||||
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::ipc;
|
||||
@@ -258,7 +259,6 @@ nsIWordBreaker *nsContentUtils::sWordBreaker;
|
||||
nsIBidiKeyboard *nsContentUtils::sBidiKeyboard = nullptr;
|
||||
uint32_t nsContentUtils::sScriptBlockerCount = 0;
|
||||
uint32_t nsContentUtils::sDOMNodeRemovedSuppressCount = 0;
|
||||
uint32_t nsContentUtils::sMicroTaskLevel = 0;
|
||||
AutoTArray<nsCOMPtr<nsIRunnable>, 8>* nsContentUtils::sBlockedScriptRunners = nullptr;
|
||||
uint32_t nsContentUtils::sRunnersCountAtFirstBlocker = 0;
|
||||
nsIInterfaceRequestor* nsContentUtils::sSameOriginChecker = nullptr;
|
||||
@@ -284,6 +284,8 @@ bool nsContentUtils::sIsResourceTimingEnabled = false;
|
||||
bool nsContentUtils::sIsPerformanceNavigationTimingEnabled = false;
|
||||
bool nsContentUtils::sIsUserTimingLoggingEnabled = false;
|
||||
bool nsContentUtils::sIsExperimentalAutocompleteEnabled = false;
|
||||
bool nsContentUtils::sIsWebComponentsEnabled = false;
|
||||
bool nsContentUtils::sIsCustomElementsEnabled = false;
|
||||
bool nsContentUtils::sEncodeDecodeURLHash = false;
|
||||
bool nsContentUtils::sGettersDecodeURLHash = false;
|
||||
bool nsContentUtils::sPrivacyResistFingerprinting = false;
|
||||
@@ -584,6 +586,12 @@ nsContentUtils::Init()
|
||||
Preferences::AddBoolVarCache(&sIsExperimentalAutocompleteEnabled,
|
||||
"dom.forms.autocomplete.experimental", false);
|
||||
|
||||
Preferences::AddBoolVarCache(&sIsWebComponentsEnabled,
|
||||
"dom.webcomponents.enabled", false);
|
||||
|
||||
Preferences::AddBoolVarCache(&sIsCustomElementsEnabled,
|
||||
"dom.webcomponents.customelements.enabled", false);
|
||||
|
||||
Preferences::AddBoolVarCache(&sEncodeDecodeURLHash,
|
||||
"dom.url.encode_decode_hash", false);
|
||||
|
||||
@@ -1080,6 +1088,7 @@ nsContentUtils::ParseHTMLInteger(const nsAString& aValue,
|
||||
int sign = 1;
|
||||
if (*iter == char16_t('-')) {
|
||||
sign = -1;
|
||||
result |= eParseHTMLInteger_Negative;
|
||||
++iter;
|
||||
} else if (*iter == char16_t('+')) {
|
||||
result |= eParseHTMLInteger_NonStandard;
|
||||
@@ -5293,51 +5302,6 @@ nsContentUtils::RunInMetastableState(already_AddRefed<nsIRunnable> aRunnable)
|
||||
CycleCollectedJSContext::Get()->RunInMetastableState(Move(aRunnable));
|
||||
}
|
||||
|
||||
void
|
||||
nsContentUtils::EnterMicroTask()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
++sMicroTaskLevel;
|
||||
}
|
||||
|
||||
void
|
||||
nsContentUtils::LeaveMicroTask()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (--sMicroTaskLevel == 0) {
|
||||
PerformMainThreadMicroTaskCheckpoint();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
nsContentUtils::IsInMicroTask()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
return sMicroTaskLevel != 0;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
nsContentUtils::MicroTaskLevel()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
return sMicroTaskLevel;
|
||||
}
|
||||
|
||||
void
|
||||
nsContentUtils::SetMicroTaskLevel(uint32_t aLevel)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
sMicroTaskLevel = aLevel;
|
||||
}
|
||||
|
||||
void
|
||||
nsContentUtils::PerformMainThreadMicroTaskCheckpoint()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsDOMMutationObserver::HandleMutations();
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function for nsContentUtils::ProcessViewportInfo.
|
||||
*
|
||||
@@ -9567,11 +9531,34 @@ nsContentUtils::HttpsStateIsModern(nsIDocument* aDocument)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsContentUtils::TryToUpgradeElement(Element* aElement)
|
||||
{
|
||||
NodeInfo* nodeInfo = aElement->NodeInfo();
|
||||
RefPtr<nsIAtom> typeAtom =
|
||||
aElement->GetCustomElementData()->GetCustomElementType();
|
||||
|
||||
MOZ_ASSERT(nodeInfo->NameAtom()->Equals(nodeInfo->LocalName()));
|
||||
CustomElementDefinition* definition =
|
||||
nsContentUtils::LookupCustomElementDefinition(nodeInfo->GetDocument(),
|
||||
nodeInfo->NameAtom(),
|
||||
nodeInfo->NamespaceID(),
|
||||
typeAtom);
|
||||
if (definition) {
|
||||
nsContentUtils::EnqueueUpgradeReaction(aElement, definition);
|
||||
} else {
|
||||
// Add an unresolved custom element that is a candidate for
|
||||
// upgrade when a custom element is connected to the document.
|
||||
// We will make sure it's shadow-including tree order in bug 1326028.
|
||||
nsContentUtils::RegisterUnresolvedElement(aElement, typeAtom);
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ CustomElementDefinition*
|
||||
nsContentUtils::LookupCustomElementDefinition(nsIDocument* aDoc,
|
||||
const nsAString& aLocalName,
|
||||
nsIAtom* aNameAtom,
|
||||
uint32_t aNameSpaceID,
|
||||
const nsAString* aIs)
|
||||
nsIAtom* aTypeAtom)
|
||||
{
|
||||
MOZ_ASSERT(aDoc);
|
||||
|
||||
@@ -9593,30 +9580,16 @@ nsContentUtils::LookupCustomElementDefinition(nsIDocument* aDoc,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return registry->LookupCustomElementDefinition(aLocalName, aIs);
|
||||
return registry->LookupCustomElementDefinition(aNameAtom, aTypeAtom);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsContentUtils::SetupCustomElement(Element* aElement,
|
||||
const nsAString* aTypeExtension)
|
||||
nsContentUtils::RegisterUnresolvedElement(Element* aElement, nsIAtom* aTypeName)
|
||||
{
|
||||
MOZ_ASSERT(aElement);
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = aElement->OwnerDoc();
|
||||
|
||||
if (!doc) {
|
||||
return;
|
||||
}
|
||||
|
||||
// To support imported document.
|
||||
doc = doc->MasterDocument();
|
||||
|
||||
if (aElement->GetNameSpaceID() != kNameSpaceID_XHTML ||
|
||||
!doc->GetDocShell()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowInner> window(doc->GetInnerWindow());
|
||||
nsIDocument* doc = aElement->OwnerDoc();
|
||||
nsPIDOMWindowInner* window(doc->GetInnerWindow());
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
@@ -9626,26 +9599,18 @@ nsContentUtils::SetupCustomElement(Element* aElement,
|
||||
return;
|
||||
}
|
||||
|
||||
return registry->SetupCustomElement(aElement, aTypeExtension);
|
||||
registry->RegisterUnresolvedElement(aElement, aTypeName);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsContentUtils::EnqueueLifecycleCallback(nsIDocument* aDoc,
|
||||
nsIDocument::ElementCallbackType aType,
|
||||
Element* aCustomElement,
|
||||
LifecycleCallbackArgs* aArgs,
|
||||
CustomElementDefinition* aDefinition)
|
||||
nsContentUtils::UnregisterUnresolvedElement(Element* aElement)
|
||||
{
|
||||
MOZ_ASSERT(aDoc);
|
||||
MOZ_ASSERT(aElement);
|
||||
|
||||
// To support imported document.
|
||||
nsCOMPtr<nsIDocument> doc = aDoc->MasterDocument();
|
||||
|
||||
if (!doc->GetDocShell()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowInner> window(doc->GetInnerWindow());
|
||||
RefPtr<nsIAtom> typeAtom =
|
||||
aElement->GetCustomElementData()->GetCustomElementType();
|
||||
nsIDocument* doc = aElement->OwnerDoc();
|
||||
nsPIDOMWindowInner* window(doc->GetInnerWindow());
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
@@ -9655,7 +9620,59 @@ nsContentUtils::EnqueueLifecycleCallback(nsIDocument* aDoc,
|
||||
return;
|
||||
}
|
||||
|
||||
registry->EnqueueLifecycleCallback(aType, aCustomElement, aArgs, aDefinition);
|
||||
registry->UnregisterUnresolvedElement(aElement, typeAtom);
|
||||
}
|
||||
|
||||
/* static */ CustomElementDefinition*
|
||||
nsContentUtils::GetElementDefinitionIfObservingAttr(Element* aCustomElement,
|
||||
nsIAtom* aExtensionType,
|
||||
nsIAtom* aAttrName)
|
||||
{
|
||||
CustomElementDefinition* definition =
|
||||
aCustomElement->GetCustomElementDefinition();
|
||||
|
||||
// Custom element not defined yet or attribute is not in the observed
|
||||
// attribute list.
|
||||
if (!definition || !definition->IsInObservedAttributeList(aAttrName)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return definition;
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsContentUtils::EnqueueUpgradeReaction(Element* aElement,
|
||||
CustomElementDefinition* aDefinition)
|
||||
{
|
||||
MOZ_ASSERT(aElement);
|
||||
|
||||
nsIDocument* doc = aElement->OwnerDoc();
|
||||
|
||||
// No DocGroup means no custom element reactions stack.
|
||||
if (!doc->GetDocGroup()) {
|
||||
return;
|
||||
}
|
||||
|
||||
CustomElementReactionsStack* stack =
|
||||
doc->GetDocGroup()->CustomElementReactionsStack();
|
||||
stack->EnqueueUpgradeReaction(aElement, aDefinition);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsContentUtils::EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType,
|
||||
Element* aCustomElement,
|
||||
LifecycleCallbackArgs* aArgs,
|
||||
LifecycleAdoptedCallbackArgs* aAdoptedCallbackArgs,
|
||||
CustomElementDefinition* aDefinition)
|
||||
{
|
||||
// No DocGroup means no custom element reactions stack.
|
||||
if (!aCustomElement->OwnerDoc()->GetDocGroup()) {
|
||||
return;
|
||||
}
|
||||
|
||||
CustomElementRegistry::EnqueueLifecycleCallback(aType, aCustomElement, aArgs,
|
||||
aAdoptedCallbackArgs,
|
||||
aDefinition);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
@@ -9834,4 +9851,4 @@ nsContentUtils::IsLocalRefURL(const nsString& aString)
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+32
-32
@@ -126,6 +126,7 @@ class EventTarget;
|
||||
class IPCDataTransfer;
|
||||
class IPCDataTransferItem;
|
||||
struct LifecycleCallbackArgs;
|
||||
struct LifecycleAdoptedCallbackArgs;
|
||||
class NodeInfo;
|
||||
class nsIContentChild;
|
||||
class nsIContentParent;
|
||||
@@ -444,7 +445,9 @@ public:
|
||||
// Set if one or more error flags were set.
|
||||
eParseHTMLInteger_Error = 1 << 3,
|
||||
eParseHTMLInteger_ErrorNoValue = 1 << 4,
|
||||
eParseHTMLInteger_ErrorOverflow = 1 << 5
|
||||
eParseHTMLInteger_ErrorOverflow = 1 << 5,
|
||||
// Use this flag to detect the difference between overflow and underflow
|
||||
eParseHTMLInteger_Negative = 1 << 6,
|
||||
};
|
||||
static int32_t ParseHTMLInteger(const nsAString& aValue,
|
||||
ParseHTMLIntegerResultFlags *aResult);
|
||||
@@ -1739,17 +1742,6 @@ public:
|
||||
*/
|
||||
static void RunInMetastableState(already_AddRefed<nsIRunnable> aRunnable);
|
||||
|
||||
// Call EnterMicroTask when you're entering JS execution.
|
||||
// Usually the best way to do this is to use nsAutoMicroTask.
|
||||
static void EnterMicroTask();
|
||||
static void LeaveMicroTask();
|
||||
|
||||
static bool IsInMicroTask();
|
||||
static uint32_t MicroTaskLevel();
|
||||
static void SetMicroTaskLevel(uint32_t aLevel);
|
||||
|
||||
static void PerformMainThreadMicroTaskCheckpoint();
|
||||
|
||||
/* Process viewport META data. This gives us information for the scale
|
||||
* and zoom of a page on mobile devices. We stick the information in
|
||||
* the document header and use it later on after rendering.
|
||||
@@ -2710,23 +2702,37 @@ public:
|
||||
*/
|
||||
static bool HttpsStateIsModern(nsIDocument* aDocument);
|
||||
|
||||
/**
|
||||
* Try to upgrade an element.
|
||||
* https://html.spec.whatwg.org/multipage/custom-elements.html#concept-try-upgrade
|
||||
*/
|
||||
static void TryToUpgradeElement(Element* aElement);
|
||||
|
||||
/**
|
||||
* Looking up a custom element definition.
|
||||
* https://html.spec.whatwg.org/#look-up-a-custom-element-definition
|
||||
*/
|
||||
static mozilla::dom::CustomElementDefinition*
|
||||
LookupCustomElementDefinition(nsIDocument* aDoc,
|
||||
const nsAString& aLocalName,
|
||||
nsIAtom* aNameAtom,
|
||||
uint32_t aNameSpaceID,
|
||||
const nsAString* aIs = nullptr);
|
||||
nsIAtom* aTypeAtom);
|
||||
|
||||
static void SetupCustomElement(Element* aElement,
|
||||
const nsAString* aTypeExtension = nullptr);
|
||||
static void RegisterUnresolvedElement(Element* aElement, nsIAtom* aTypeName);
|
||||
static void UnregisterUnresolvedElement(Element* aElement);
|
||||
|
||||
static void EnqueueLifecycleCallback(nsIDocument* aDoc,
|
||||
nsIDocument::ElementCallbackType aType,
|
||||
static mozilla::dom::CustomElementDefinition*
|
||||
GetElementDefinitionIfObservingAttr(Element* aCustomElement,
|
||||
nsIAtom* aExtensionType,
|
||||
nsIAtom* aAttrName);
|
||||
|
||||
static void EnqueueUpgradeReaction(Element* aElement,
|
||||
mozilla::dom::CustomElementDefinition* aDefinition);
|
||||
|
||||
static void EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType,
|
||||
Element* aCustomElement,
|
||||
mozilla::dom::LifecycleCallbackArgs* aArgs = nullptr,
|
||||
mozilla::dom::LifecycleAdoptedCallbackArgs* aAdoptedCallbackArgs = nullptr,
|
||||
mozilla::dom::CustomElementDefinition* aDefinition = nullptr);
|
||||
|
||||
static void GetCustomPrototype(nsIDocument* aDoc,
|
||||
@@ -2743,6 +2749,12 @@ public:
|
||||
static bool
|
||||
IsLocalRefURL(const nsString& aString);
|
||||
|
||||
static bool
|
||||
IsWebComponentsEnabled() { return sIsWebComponentsEnabled; }
|
||||
|
||||
static bool
|
||||
IsCustomElementsEnabled() { return sIsCustomElementsEnabled; }
|
||||
|
||||
private:
|
||||
static bool InitializeEventTable();
|
||||
|
||||
@@ -2829,7 +2841,6 @@ private:
|
||||
static bool sInitialized;
|
||||
static uint32_t sScriptBlockerCount;
|
||||
static uint32_t sDOMNodeRemovedSuppressCount;
|
||||
static uint32_t sMicroTaskLevel;
|
||||
// Not an nsCOMArray because removing elements from those is slower
|
||||
static AutoTArray<nsCOMPtr<nsIRunnable>, 8>* sBlockedScriptRunners;
|
||||
static uint32_t sRunnersCountAtFirstBlocker;
|
||||
@@ -2850,6 +2861,8 @@ private:
|
||||
static bool sIsUserTimingLoggingEnabled;
|
||||
static bool sIsFrameTimingPrefEnabled;
|
||||
static bool sIsExperimentalAutocompleteEnabled;
|
||||
static bool sIsWebComponentsEnabled;
|
||||
static bool sIsCustomElementsEnabled;
|
||||
static bool sEncodeDecodeURLHash;
|
||||
static bool sGettersDecodeURLHash;
|
||||
static bool sPrivacyResistFingerprinting;
|
||||
@@ -2905,19 +2918,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS nsAutoMicroTask
|
||||
{
|
||||
public:
|
||||
nsAutoMicroTask()
|
||||
{
|
||||
nsContentUtils::EnterMicroTask();
|
||||
}
|
||||
~nsAutoMicroTask()
|
||||
{
|
||||
nsContentUtils::LeaveMicroTask();
|
||||
}
|
||||
};
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
|
||||
@@ -32,8 +32,6 @@ using mozilla::dom::Element;
|
||||
AutoTArray<RefPtr<nsDOMMutationObserver>, 4>*
|
||||
nsDOMMutationObserver::sScheduledMutationObservers = nullptr;
|
||||
|
||||
nsDOMMutationObserver* nsDOMMutationObserver::sCurrentObserver = nullptr;
|
||||
|
||||
uint32_t nsDOMMutationObserver::sMutationLevel = 0;
|
||||
uint64_t nsDOMMutationObserver::sCount = 0;
|
||||
|
||||
@@ -597,10 +595,32 @@ nsDOMMutationObserver::ScheduleForRun()
|
||||
RescheduleForRun();
|
||||
}
|
||||
|
||||
class MutationObserverMicroTask final : public MicroTaskRunnable
|
||||
{
|
||||
public:
|
||||
virtual void Run(AutoSlowOperation& aAso) override
|
||||
{
|
||||
nsDOMMutationObserver::HandleMutations(aAso);
|
||||
}
|
||||
|
||||
virtual bool Suppressed() override
|
||||
{
|
||||
return nsDOMMutationObserver::AllScheduledMutationObserversAreSuppressed();
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
nsDOMMutationObserver::RescheduleForRun()
|
||||
{
|
||||
if (!sScheduledMutationObservers) {
|
||||
CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get();
|
||||
if (!ccjs) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<MutationObserverMicroTask> momt =
|
||||
new MutationObserverMicroTask();
|
||||
ccjs->DispatchMicroTaskRunnable(momt.forget());
|
||||
sScheduledMutationObservers = new AutoTArray<RefPtr<nsDOMMutationObserver>, 4>;
|
||||
}
|
||||
|
||||
@@ -862,36 +882,9 @@ nsDOMMutationObserver::HandleMutation()
|
||||
mCallback->Call(this, mutations, *this);
|
||||
}
|
||||
|
||||
class AsyncMutationHandler : public mozilla::Runnable
|
||||
{
|
||||
public:
|
||||
NS_IMETHOD Run() override
|
||||
{
|
||||
nsDOMMutationObserver::HandleMutations();
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
nsDOMMutationObserver::HandleMutationsInternal()
|
||||
nsDOMMutationObserver::HandleMutationsInternal(AutoSlowOperation& aAso)
|
||||
{
|
||||
if (!nsContentUtils::IsSafeToRunScript()) {
|
||||
nsContentUtils::AddScriptRunner(new AsyncMutationHandler());
|
||||
return;
|
||||
}
|
||||
static RefPtr<nsDOMMutationObserver> sCurrentObserver;
|
||||
if (sCurrentObserver && !sCurrentObserver->Suppressed()) {
|
||||
// In normal cases sScheduledMutationObservers will be handled
|
||||
// after previous mutations are handled. But in case some
|
||||
// callback calls a sync API, which spins the eventloop, we need to still
|
||||
// process other mutations happening during that sync call.
|
||||
// This does *not* catch all cases, but should work for stuff running
|
||||
// in separate tabs.
|
||||
return;
|
||||
}
|
||||
|
||||
mozilla::AutoSlowOperation aso;
|
||||
|
||||
nsTArray<RefPtr<nsDOMMutationObserver> >* suppressedObservers = nullptr;
|
||||
|
||||
while (sScheduledMutationObservers) {
|
||||
@@ -899,20 +892,21 @@ nsDOMMutationObserver::HandleMutationsInternal()
|
||||
sScheduledMutationObservers;
|
||||
sScheduledMutationObservers = nullptr;
|
||||
for (uint32_t i = 0; i < observers->Length(); ++i) {
|
||||
sCurrentObserver = static_cast<nsDOMMutationObserver*>((*observers)[i]);
|
||||
if (!sCurrentObserver->Suppressed()) {
|
||||
sCurrentObserver->HandleMutation();
|
||||
RefPtr<nsDOMMutationObserver> currentObserver =
|
||||
static_cast<nsDOMMutationObserver*>((*observers)[i]);
|
||||
if (!currentObserver->Suppressed()) {
|
||||
currentObserver->HandleMutation();
|
||||
} else {
|
||||
if (!suppressedObservers) {
|
||||
suppressedObservers = new nsTArray<RefPtr<nsDOMMutationObserver> >;
|
||||
}
|
||||
if (!suppressedObservers->Contains(sCurrentObserver)) {
|
||||
suppressedObservers->AppendElement(sCurrentObserver);
|
||||
if (!suppressedObservers->Contains(currentObserver)) {
|
||||
suppressedObservers->AppendElement(currentObserver);
|
||||
}
|
||||
}
|
||||
}
|
||||
delete observers;
|
||||
aso.CheckForInterrupt();
|
||||
aAso.CheckForInterrupt();
|
||||
}
|
||||
|
||||
if (suppressedObservers) {
|
||||
@@ -923,7 +917,6 @@ nsDOMMutationObserver::HandleMutationsInternal()
|
||||
delete suppressedObservers;
|
||||
suppressedObservers = nullptr;
|
||||
}
|
||||
sCurrentObserver = nullptr;
|
||||
}
|
||||
|
||||
nsDOMMutationRecord*
|
||||
|
||||
@@ -552,13 +552,29 @@ public:
|
||||
}
|
||||
|
||||
// static methods
|
||||
static void HandleMutations()
|
||||
static void HandleMutations(mozilla::AutoSlowOperation& aAso)
|
||||
{
|
||||
if (sScheduledMutationObservers) {
|
||||
HandleMutationsInternal();
|
||||
HandleMutationsInternal(aAso);
|
||||
}
|
||||
}
|
||||
|
||||
static bool AllScheduledMutationObserversAreSuppressed()
|
||||
{
|
||||
if (sScheduledMutationObservers) {
|
||||
uint32_t len = sScheduledMutationObservers->Length();
|
||||
if (len > 0) {
|
||||
for (uint32_t i = 0; i < len; ++i) {
|
||||
if (!(*sScheduledMutationObservers)[i]->Suppressed()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void EnterMutationHandling();
|
||||
static void LeaveMutationHandling();
|
||||
|
||||
@@ -594,7 +610,7 @@ protected:
|
||||
return false;
|
||||
}
|
||||
|
||||
static void HandleMutationsInternal();
|
||||
static void HandleMutationsInternal(mozilla::AutoSlowOperation& aAso);
|
||||
|
||||
static void AddCurrentlyHandlingObserver(nsDOMMutationObserver* aObserver,
|
||||
uint32_t aMutationLevel);
|
||||
@@ -622,7 +638,6 @@ protected:
|
||||
|
||||
static uint64_t sCount;
|
||||
static AutoTArray<RefPtr<nsDOMMutationObserver>, 4>* sScheduledMutationObservers;
|
||||
static nsDOMMutationObserver* sCurrentObserver;
|
||||
|
||||
static uint32_t sMutationLevel;
|
||||
static AutoTArray<AutoTArray<RefPtr<nsDOMMutationObserver>, 4>, 4>*
|
||||
|
||||
+123
-64
@@ -166,7 +166,6 @@
|
||||
#include "mozilla/dom/HTMLIFrameElement.h"
|
||||
#include "mozilla/dom/HTMLImageElement.h"
|
||||
#include "mozilla/dom/MediaSource.h"
|
||||
#include "mozilla/dom/FlyWebService.h"
|
||||
|
||||
#include "mozAutoDocUpdate.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
@@ -1329,7 +1328,8 @@ nsIDocument::nsIDocument()
|
||||
mFrameRequestCallbacksScheduled(false),
|
||||
mBidiOptions(IBMBIDI_DEFAULT_BIDI_OPTIONS),
|
||||
mPartID(0),
|
||||
mUserHasInteracted(false)
|
||||
mUserHasInteracted(false),
|
||||
mThrowOnDynamicMarkupInsertionCounter(0)
|
||||
{
|
||||
SetIsInDocument();
|
||||
|
||||
@@ -5395,18 +5395,14 @@ nsDocument::CreateElement(const nsAString& aTagName,
|
||||
}
|
||||
|
||||
const nsString* is = nullptr;
|
||||
if (aOptions.IsElementCreationOptions()) {
|
||||
// Throw NotFoundError if 'is' is not-null and definition is null
|
||||
is = CheckCustomElementName(aOptions.GetAsElementCreationOptions(),
|
||||
needsLowercase ? lcTagName : aTagName, mDefaultElementType, rv);
|
||||
if (rv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<Element> elem = CreateElem(
|
||||
needsLowercase ? lcTagName : aTagName, nullptr, mDefaultElementType, is);
|
||||
|
||||
if (is) {
|
||||
elem->SetAttr(kNameSpaceID_None, nsGkAtoms::is, *is, true);
|
||||
}
|
||||
|
||||
return elem.forget();
|
||||
}
|
||||
|
||||
@@ -5443,14 +5439,6 @@ nsDocument::CreateElementNS(const nsAString& aNamespaceURI,
|
||||
}
|
||||
|
||||
const nsString* is = nullptr;
|
||||
if (aOptions.IsElementCreationOptions()) {
|
||||
// Throw NotFoundError if 'is' is not-null and definition is null
|
||||
is = CheckCustomElementName(aOptions.GetAsElementCreationOptions(),
|
||||
aQualifiedName, nodeInfo->NamespaceID(), rv);
|
||||
if (rv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<Element> element;
|
||||
rv = NS_NewElement(getter_AddRefs(element), nodeInfo.forget(),
|
||||
@@ -5459,6 +5447,10 @@ nsDocument::CreateElementNS(const nsAString& aNamespaceURI,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (is) {
|
||||
element->SetAttr(kNameSpaceID_None, nsGkAtoms::is, *is, true);
|
||||
}
|
||||
|
||||
return element.forget();
|
||||
}
|
||||
|
||||
@@ -5681,24 +5673,70 @@ nsDocument::CustomElementConstructor(JSContext* aCx, unsigned aArgc, JS::Value*
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAtom> typeAtom(NS_Atomize(elemName));
|
||||
CustomElementDefinition* definition = registry->mCustomDefinitions.Get(typeAtom);
|
||||
CustomElementDefinition* definition =
|
||||
registry->mCustomDefinitions.GetWeak(typeAtom);
|
||||
if (!definition) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsDependentAtomString localName(definition->mLocalName);
|
||||
RefPtr<Element> element;
|
||||
|
||||
nsCOMPtr<Element> element =
|
||||
document->CreateElem(localName, nullptr, kNameSpaceID_XHTML);
|
||||
NS_ENSURE_TRUE(element, true);
|
||||
// We integrate with construction stack and do prototype swizzling here, so
|
||||
// that old upgrade behavior could also share the new upgrade steps.
|
||||
// And this old upgrade will be remove at some point (when everything is
|
||||
// switched to latest custom element spec).
|
||||
nsTArray<RefPtr<nsGenericHTMLElement>>& constructionStack =
|
||||
definition->mConstructionStack;
|
||||
if (constructionStack.Length()) {
|
||||
element = constructionStack.LastElement();
|
||||
NS_ENSURE_TRUE(element != ALEADY_CONSTRUCTED_MARKER, false);
|
||||
|
||||
if (definition->mLocalName != typeAtom) {
|
||||
// This element is a custom element by extension, thus we need to
|
||||
// do some special setup. For non-extended custom elements, this happens
|
||||
// when the element is created.
|
||||
nsContentUtils::SetupCustomElement(element, &elemName);
|
||||
// Do prototype swizzling if dom reflector exists.
|
||||
JS::Rooted<JSObject*> reflector(aCx, element->GetWrapper());
|
||||
if (reflector) {
|
||||
Maybe<JSAutoCompartment> ac;
|
||||
JS::Rooted<JSObject*> prototype(aCx, definition->mPrototype);
|
||||
if (element->NodePrincipal()->SubsumesConsideringDomain(nsContentUtils::ObjectPrincipal(prototype))) {
|
||||
ac.emplace(aCx, reflector);
|
||||
if (!JS_WrapObject(aCx, &prototype) ||
|
||||
!JS_SetPrototype(aCx, reflector, prototype)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// We want to set the custom prototype in the compartment where it was
|
||||
// registered. We store the prototype from define() without unwrapped,
|
||||
// hence the prototype's compartment is the compartment where it was
|
||||
// registered.
|
||||
// In the case that |reflector| and |prototype| are in different
|
||||
// compartments, this will set the prototype on the |reflector|'s wrapper
|
||||
// and thus only visible in the wrapper's compartment, since we know
|
||||
// reflector's principal does not subsume prototype's in this case.
|
||||
ac.emplace(aCx, prototype);
|
||||
if (!JS_WrapObject(aCx, &reflector) ||
|
||||
!JS_SetPrototype(aCx, reflector, prototype)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Wrap into current context.
|
||||
if (!JS_WrapObject(aCx, &reflector)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
args.rval().setObject(*reflector);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
nsDependentAtomString localName(definition->mLocalName);
|
||||
element =
|
||||
document->CreateElem(localName, nullptr, kNameSpaceID_XHTML,
|
||||
(definition->mLocalName != typeAtom) ? &elemName
|
||||
: nullptr);
|
||||
NS_ENSURE_TRUE(element, false);
|
||||
}
|
||||
|
||||
// The prototype setup happens in Element::WrapObject().
|
||||
|
||||
nsresult rv = nsContentUtils::WrapNative(aCx, element, element, args.rval());
|
||||
NS_ENSURE_SUCCESS(rv, true);
|
||||
|
||||
@@ -5710,7 +5748,7 @@ nsDocument::IsWebComponentsEnabled(JSContext* aCx, JSObject* aObject)
|
||||
{
|
||||
JS::Rooted<JSObject*> obj(aCx, aObject);
|
||||
|
||||
if (Preferences::GetBool("dom.webcomponents.enabled")) {
|
||||
if (nsContentUtils::IsWebComponentsEnabled()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -5726,7 +5764,7 @@ nsDocument::IsWebComponentsEnabled(JSContext* aCx, JSObject* aObject)
|
||||
bool
|
||||
nsDocument::IsWebComponentsEnabled(dom::NodeInfo* aNodeInfo)
|
||||
{
|
||||
if (Preferences::GetBool("dom.webcomponents.enabled")) {
|
||||
if (nsContentUtils::IsWebComponentsEnabled()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -5770,6 +5808,8 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
|
||||
return;
|
||||
}
|
||||
|
||||
AutoCEReaction ceReaction(this->GetDocGroup()->CustomElementReactionsStack(),
|
||||
aCx);
|
||||
// Unconditionally convert TYPE to lowercase.
|
||||
nsAutoString lcType;
|
||||
nsContentUtils::ASCIIToLower(aType, lcType);
|
||||
@@ -6536,6 +6576,49 @@ nsIDocument::GetHtmlChildElement(nsIAtom* aTag)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsGenericHTMLElement*
|
||||
nsIDocument::GetBody()
|
||||
{
|
||||
Element* html = GetHtmlElement();
|
||||
if (!html) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (nsIContent* child = html->GetFirstChild();
|
||||
child;
|
||||
child = child->GetNextSibling()) {
|
||||
if (child->IsHTMLElement(nsGkAtoms::body) ||
|
||||
child->IsHTMLElement(nsGkAtoms::frameset)) {
|
||||
return static_cast<nsGenericHTMLElement*>(child);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
nsIDocument::SetBody(nsGenericHTMLElement* newBody, ErrorResult& rv)
|
||||
{
|
||||
nsCOMPtr<Element> root = GetRootElement();
|
||||
|
||||
// The body element must be either a body tag or a frameset tag. And we must
|
||||
// have a root element to be able to add kids to it.
|
||||
if (!newBody ||
|
||||
!newBody->IsAnyOfHTMLElements(nsGkAtoms::body, nsGkAtoms::frameset) ||
|
||||
!root) {
|
||||
rv.Throw(NS_ERROR_DOM_HIERARCHY_REQUEST_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
// Use DOM methods so that we pass through the appropriate security checks.
|
||||
nsCOMPtr<Element> currentBody = GetBody();
|
||||
if (currentBody) {
|
||||
root->ReplaceChild(*newBody, *currentBody, rv);
|
||||
} else {
|
||||
root->AppendChild(*newBody, rv);
|
||||
}
|
||||
}
|
||||
|
||||
Element*
|
||||
nsDocument::GetTitleElement()
|
||||
{
|
||||
@@ -8369,13 +8452,6 @@ nsDocument::CanSavePresentation(nsIRequest *aNewRequest)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't save presentation if there are active FlyWeb connections or FlyWeb
|
||||
// servers.
|
||||
FlyWebService* flyWebService = FlyWebService::GetExisting();
|
||||
if (flyWebService && flyWebService->HasConnectionOrServer(win->WindowID())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mSubDocuments) {
|
||||
for (auto iter = mSubDocuments->Iter(); !iter.Done(); iter.Next()) {
|
||||
auto entry = static_cast<SubDocMapEntry*>(iter.Get());
|
||||
@@ -12526,8 +12602,12 @@ MarkDocumentTreeToBeInSyncOperation(nsIDocument* aDoc, void* aData)
|
||||
|
||||
nsAutoSyncOperation::nsAutoSyncOperation(nsIDocument* aDoc)
|
||||
{
|
||||
mMicroTaskLevel = nsContentUtils::MicroTaskLevel();
|
||||
nsContentUtils::SetMicroTaskLevel(0);
|
||||
mMicroTaskLevel = 0;
|
||||
CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get();
|
||||
if (ccjs) {
|
||||
mMicroTaskLevel = ccjs->MicroTaskLevel();
|
||||
ccjs->SetMicroTaskLevel(0);
|
||||
}
|
||||
if (aDoc) {
|
||||
if (nsPIDOMWindowOuter* win = aDoc->GetWindow()) {
|
||||
if (nsCOMPtr<nsPIDOMWindowOuter> top = win->GetTop()) {
|
||||
@@ -12543,7 +12623,10 @@ nsAutoSyncOperation::~nsAutoSyncOperation()
|
||||
for (int32_t i = 0; i < mDocuments.Count(); ++i) {
|
||||
mDocuments[i]->SetIsInSyncOperation(false);
|
||||
}
|
||||
nsContentUtils::SetMicroTaskLevel(mMicroTaskLevel);
|
||||
CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get();
|
||||
if (ccjs) {
|
||||
ccjs->SetMicroTaskLevel(mMicroTaskLevel);
|
||||
}
|
||||
}
|
||||
|
||||
gfxUserFontSet*
|
||||
@@ -12713,30 +12796,6 @@ nsIDocument::UpdateStyleBackendType()
|
||||
#endif
|
||||
}
|
||||
|
||||
const nsString*
|
||||
nsDocument::CheckCustomElementName(const ElementCreationOptions& aOptions,
|
||||
const nsAString& aLocalName,
|
||||
uint32_t aNamespaceID,
|
||||
ErrorResult& rv)
|
||||
{
|
||||
// only check aOptions if 'is' is passed and the webcomponents preference
|
||||
// is enabled
|
||||
if (!aOptions.mIs.WasPassed() ||
|
||||
!CustomElementRegistry::IsCustomElementEnabled()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const nsString* is = &aOptions.mIs.Value();
|
||||
|
||||
// Throw NotFoundError if 'is' is not-null and definition is null
|
||||
if (!nsContentUtils::LookupCustomElementDefinition(this, aLocalName,
|
||||
aNamespaceID, is)) {
|
||||
rv.Throw(NS_ERROR_DOM_NOT_FOUND_ERR);
|
||||
}
|
||||
|
||||
return is;
|
||||
}
|
||||
|
||||
Selection*
|
||||
nsIDocument::GetSelection(ErrorResult& aRv)
|
||||
{
|
||||
|
||||
@@ -1388,20 +1388,6 @@ protected:
|
||||
private:
|
||||
static bool CustomElementConstructor(JSContext* aCx, unsigned aArgc, JS::Value* aVp);
|
||||
|
||||
/**
|
||||
* Check if the passed custom element name, aOptions.mIs, is a registered
|
||||
* custom element type or not, then return the custom element name for future
|
||||
* usage.
|
||||
*
|
||||
* If there is no existing custom element definition for this name, throw a
|
||||
* NotFoundError.
|
||||
*/
|
||||
const nsString* CheckCustomElementName(
|
||||
const mozilla::dom::ElementCreationOptions& aOptions,
|
||||
const nsAString& aLocalName,
|
||||
uint32_t aNamespaceID,
|
||||
ErrorResult& rv);
|
||||
|
||||
public:
|
||||
virtual already_AddRefed<mozilla::dom::CustomElementRegistry>
|
||||
GetCustomElementRegistry() override;
|
||||
|
||||
@@ -1261,6 +1261,15 @@ nsFocusManager::SetFocusInner(nsIContent* aNewContent, int32_t aFlags,
|
||||
isElementInActiveWindow = (mActiveWindow && newRootWindow == mActiveWindow);
|
||||
}
|
||||
|
||||
// Exit fullscreen if a website focuses another window
|
||||
if (!isElementInActiveWindow && aFlags & FLAG_RAISE) {
|
||||
if (nsIDocument* doc = mActiveWindow ? mActiveWindow->GetDoc() : nullptr) {
|
||||
if (doc && doc->GetFullscreenElement()) {
|
||||
nsIDocument::AsyncExitFullscreen(doc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Exit fullscreen if we're focusing a windowed plugin on a non-MacOSX
|
||||
// system. We don't control event dispatch to windowed plugins on non-MacOSX,
|
||||
// so we can't display the "Press ESC to leave fullscreen mode" warning on
|
||||
|
||||
@@ -793,17 +793,6 @@ nsGenericDOMDataNode::SetXBLInsertionParent(nsIContent* aContent)
|
||||
}
|
||||
}
|
||||
|
||||
CustomElementData *
|
||||
nsGenericDOMDataNode::GetCustomElementData() const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericDOMDataNode::SetCustomElementData(CustomElementData* aData)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
nsGenericDOMDataNode::IsNodeOfType(uint32_t aFlags) const
|
||||
{
|
||||
|
||||
@@ -162,9 +162,6 @@ public:
|
||||
virtual bool IsNodeOfType(uint32_t aFlags) const override;
|
||||
virtual bool IsLink(nsIURI** aURI) const override;
|
||||
|
||||
virtual mozilla::dom::CustomElementData* GetCustomElementData() const override;
|
||||
virtual void SetCustomElementData(mozilla::dom::CustomElementData* aData) override;
|
||||
|
||||
NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker) override;
|
||||
NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
|
||||
virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
|
||||
|
||||
@@ -4241,8 +4241,9 @@ CustomElementRegistry*
|
||||
nsGlobalWindow::CustomElements()
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(IsInnerWindow());
|
||||
|
||||
if (!mCustomElements) {
|
||||
mCustomElements = CustomElementRegistry::Create(AsInner());
|
||||
mCustomElements = new CustomElementRegistry(AsInner());
|
||||
}
|
||||
|
||||
return mCustomElements;
|
||||
|
||||
@@ -26,7 +26,6 @@ namespace mozilla {
|
||||
class EventChainPreVisitor;
|
||||
namespace dom {
|
||||
class ShadowRoot;
|
||||
struct CustomElementData;
|
||||
} // namespace dom
|
||||
namespace widget {
|
||||
struct IMEState;
|
||||
@@ -729,22 +728,6 @@ public:
|
||||
*/
|
||||
nsINode *GetFlattenedTreeParentNodeInternal() const;
|
||||
|
||||
/**
|
||||
* Gets the custom element data used by web components custom element.
|
||||
* Custom element data is created at the first attempt to enqueue a callback.
|
||||
*
|
||||
* @return The custom element data or null if none.
|
||||
*/
|
||||
virtual mozilla::dom::CustomElementData *GetCustomElementData() const = 0;
|
||||
|
||||
/**
|
||||
* Sets the custom element data, ownership of the
|
||||
* callback data is taken by this content.
|
||||
*
|
||||
* @param aCallbackData The custom element data.
|
||||
*/
|
||||
virtual void SetCustomElementData(mozilla::dom::CustomElementData* aData) = 0;
|
||||
|
||||
/**
|
||||
* API to check if this is a link that's traversed in response to user input
|
||||
* (e.g. a click event). Specializations for HTML/SVG/generic XML allow for
|
||||
|
||||
+47
-3
@@ -61,6 +61,7 @@ class nsFrameLoader;
|
||||
class nsHTMLCSSStyleSheet;
|
||||
class nsHTMLDocument;
|
||||
class nsHTMLStyleSheet;
|
||||
class nsGenericHTMLElement;
|
||||
class nsIAtom;
|
||||
class nsIBFCacheEntry;
|
||||
class nsIChannel;
|
||||
@@ -1036,6 +1037,11 @@ public:
|
||||
Element* GetHeadElement() {
|
||||
return GetHtmlChildElement(nsGkAtoms::head);
|
||||
}
|
||||
// Get the "body" in the sense of document.body: The first <body> or
|
||||
// <frameset> that's a child of a root <html>
|
||||
nsGenericHTMLElement* GetBody();
|
||||
// Set the "body" in the sense of document.body.
|
||||
void SetBody(nsGenericHTMLElement* aBody, mozilla::ErrorResult& rv);
|
||||
|
||||
/**
|
||||
* Accessors to the collection of stylesheets owned by this document.
|
||||
@@ -2573,9 +2579,9 @@ public:
|
||||
}
|
||||
|
||||
enum ElementCallbackType {
|
||||
eCreated,
|
||||
eAttached,
|
||||
eDetached,
|
||||
eConnected,
|
||||
eDisconnected,
|
||||
eAdopted,
|
||||
eAttributeChanged
|
||||
};
|
||||
|
||||
@@ -2872,6 +2878,22 @@ public:
|
||||
virtual void ScheduleIntersectionObserverNotification() = 0;
|
||||
virtual void NotifyIntersectionObservers() = 0;
|
||||
|
||||
bool ShouldThrowOnDynamicMarkupInsertion()
|
||||
{
|
||||
return mThrowOnDynamicMarkupInsertionCounter;
|
||||
}
|
||||
|
||||
void IncrementThrowOnDynamicMarkupInsertionCounter()
|
||||
{
|
||||
++mThrowOnDynamicMarkupInsertionCounter;
|
||||
}
|
||||
|
||||
void DecrementThrowOnDynamicMarkupInsertionCounter()
|
||||
{
|
||||
MOZ_ASSERT(mThrowOnDynamicMarkupInsertionCounter);
|
||||
--mThrowOnDynamicMarkupInsertionCounter;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool GetUseCounter(mozilla::UseCounter aUseCounter)
|
||||
{
|
||||
@@ -3319,6 +3341,11 @@ protected:
|
||||
|
||||
uint32_t mBlockDOMContentLoaded;
|
||||
|
||||
// Used in conjunction with the create-an-element-for-the-token algorithm to
|
||||
// prevent custom element constructors from being able to use document.open(),
|
||||
// document.close(), and document.write() when they are invoked by the parser.
|
||||
uint32_t mThrowOnDynamicMarkupInsertionCounter;
|
||||
|
||||
// Our live MediaQueryLists
|
||||
PRCList mDOMMediaQueryLists;
|
||||
|
||||
@@ -3392,6 +3419,23 @@ private:
|
||||
uint32_t mMicroTaskLevel;
|
||||
};
|
||||
|
||||
class MOZ_RAII AutoSetThrowOnDynamicMarkupInsertionCounter final {
|
||||
public:
|
||||
explicit AutoSetThrowOnDynamicMarkupInsertionCounter(
|
||||
nsIDocument* aDocument)
|
||||
: mDocument(aDocument)
|
||||
{
|
||||
mDocument->IncrementThrowOnDynamicMarkupInsertionCounter();
|
||||
}
|
||||
|
||||
~AutoSetThrowOnDynamicMarkupInsertionCounter() {
|
||||
mDocument->DecrementThrowOnDynamicMarkupInsertionCounter();
|
||||
}
|
||||
|
||||
private:
|
||||
nsIDocument* mDocument;
|
||||
};
|
||||
|
||||
// XXX These belong somewhere else
|
||||
nsresult
|
||||
NS_NewHTMLDocument(nsIDocument** aInstancePtrResult, bool aLoadedAsData = false);
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "xpcpublic.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
|
||||
#include "mozilla/CycleCollectedJSContext.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/Date.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
@@ -159,7 +159,8 @@ nsJSUtils::EvaluateString(JSContext* aCx,
|
||||
aEvaluationGlobal);
|
||||
MOZ_ASSERT_IF(aOffThreadToken, aCompileOptions.noScriptRval);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(nsContentUtils::IsInMicroTask());
|
||||
MOZ_ASSERT(CycleCollectedJSContext::Get() &&
|
||||
CycleCollectedJSContext::Get()->MicroTaskLevel());
|
||||
|
||||
// Unfortunately, the JS engine actually compiles scripts with a return value
|
||||
// in a different, less efficient way. Furthermore, it can't JIT them in many
|
||||
@@ -293,7 +294,8 @@ nsJSUtils::CompileModule(JSContext* aCx,
|
||||
aEvaluationGlobal);
|
||||
MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx) == aEvaluationGlobal);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(nsContentUtils::IsInMicroTask());
|
||||
MOZ_ASSERT(CycleCollectedJSContext::Get() &&
|
||||
CycleCollectedJSContext::Get()->MicroTaskLevel());
|
||||
|
||||
NS_ENSURE_TRUE(xpc::Scriptability::Get(aEvaluationGlobal).Allowed(), NS_OK);
|
||||
|
||||
@@ -330,7 +332,8 @@ nsJSUtils::ModuleEvaluation(JSContext* aCx, JS::Handle<JSObject*> aModule)
|
||||
|
||||
MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(nsContentUtils::IsInMicroTask());
|
||||
MOZ_ASSERT(CycleCollectedJSContext::Get() &&
|
||||
CycleCollectedJSContext::Get()->MicroTaskLevel());
|
||||
|
||||
NS_ENSURE_TRUE(xpc::Scriptability::Get(aModule).Allowed(), NS_OK);
|
||||
|
||||
|
||||
+49
-15
@@ -301,9 +301,12 @@ nsNodeUtils::LastRelease(nsINode* aNode)
|
||||
Element* elem = aNode->AsElement();
|
||||
FragmentOrElement::nsDOMSlots* domSlots =
|
||||
static_cast<FragmentOrElement::nsDOMSlots*>(slots);
|
||||
for (auto iter = domSlots->mRegisteredIntersectionObservers.Iter(); !iter.Done(); iter.Next()) {
|
||||
DOMIntersectionObserver* observer = iter.Key();
|
||||
observer->UnlinkTarget(*elem);
|
||||
if (domSlots->mExtendedSlots) {
|
||||
for (auto iter = domSlots->mExtendedSlots->mRegisteredIntersectionObservers.Iter();
|
||||
!iter.Done(); iter.Next()) {
|
||||
DOMIntersectionObserver* observer = iter.Key();
|
||||
observer->UnlinkTarget(*elem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -476,19 +479,33 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
|
||||
rv = aNode->Clone(nodeInfo, getter_AddRefs(clone));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (clone->IsElement()) {
|
||||
if (CustomElementRegistry::IsCustomElementEnabled() &&
|
||||
clone->IsHTMLElement()) {
|
||||
// The cloned node may be a custom element that may require
|
||||
// enqueing created callback and prototype swizzling.
|
||||
Element* elem = clone->AsElement();
|
||||
if (nsContentUtils::IsCustomElementName(nodeInfo->NameAtom())) {
|
||||
nsContentUtils::SetupCustomElement(elem);
|
||||
} else {
|
||||
// Check if node may be custom element by type extension.
|
||||
// ex. <button is="x-button">
|
||||
nsAutoString extension;
|
||||
if (elem->GetAttr(kNameSpaceID_None, nsGkAtoms::is, extension) &&
|
||||
!extension.IsEmpty()) {
|
||||
nsContentUtils::SetupCustomElement(elem, &extension);
|
||||
// enqueing upgrade reaction.
|
||||
Element* cloneElem = clone->AsElement();
|
||||
RefPtr<nsIAtom> tagAtom = nodeInfo->NameAtom();
|
||||
CustomElementData* data = elem->GetCustomElementData();
|
||||
|
||||
// Check if node may be custom element by type extension.
|
||||
// ex. <button is="x-button">
|
||||
nsAutoString extension;
|
||||
if (!data || data->GetCustomElementType() != tagAtom) {
|
||||
cloneElem->GetAttr(kNameSpaceID_None, nsGkAtoms::is, extension);
|
||||
}
|
||||
|
||||
if (data || !extension.IsEmpty()) {
|
||||
RefPtr<nsIAtom> typeAtom = extension.IsEmpty() ? tagAtom : NS_Atomize(extension);
|
||||
cloneElem->SetCustomElementData(new CustomElementData(typeAtom));
|
||||
|
||||
MOZ_ASSERT(nodeInfo->NameAtom()->Equals(nodeInfo->LocalName()));
|
||||
CustomElementDefinition* definition =
|
||||
nsContentUtils::LookupCustomElementDefinition(nodeInfo->GetDocument(),
|
||||
nodeInfo->NameAtom(),
|
||||
nodeInfo->NamespaceID(),
|
||||
typeAtom);
|
||||
if (definition) {
|
||||
nsContentUtils::EnqueueUpgradeReaction(cloneElem, definition);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -523,6 +540,23 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
|
||||
|
||||
nsIDocument* newDoc = aNode->OwnerDoc();
|
||||
if (newDoc) {
|
||||
if (CustomElementRegistry::IsCustomElementEnabled()) {
|
||||
// Adopted callback must be enqueued whenever a node’s
|
||||
// shadow-including inclusive descendants that is custom.
|
||||
Element* element = aNode->IsElement() ? aNode->AsElement() : nullptr;
|
||||
if (element) {
|
||||
CustomElementData* data = element->GetCustomElementData();
|
||||
if (data && data->mState == CustomElementData::State::eCustom) {
|
||||
LifecycleAdoptedCallbackArgs args = {
|
||||
oldDoc,
|
||||
newDoc
|
||||
};
|
||||
nsContentUtils::EnqueueLifecycleCallback(nsIDocument::eAdopted,
|
||||
element, nullptr, &args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// XXX what if oldDoc is null, we don't know if this should be
|
||||
// registered or not! Can that really happen?
|
||||
if (wasRegistered) {
|
||||
|
||||
@@ -1144,7 +1144,7 @@ nsScriptLoader::InstantiateModuleTree(nsModuleLoadRequest* aRequest)
|
||||
|
||||
nsModuleScript* ms = aRequest->mModuleScript;
|
||||
MOZ_ASSERT(ms);
|
||||
if (!ms->ModuleRecord()) {
|
||||
if (!ms || !ms->ModuleRecord()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
var proto = Object.create(HTMLElement.prototype);
|
||||
proto.magicNumber = 42;
|
||||
proto.createdCallback = function() {
|
||||
proto.connectedCallback = function() {
|
||||
finishTest(this.magicNumber === 42);
|
||||
};
|
||||
document.registerElement("x-foo", { prototype: proto });
|
||||
|
||||
document.createElement("x-foo");
|
||||
document.firstChild.appendChild(document.createElement("x-foo"));
|
||||
@@ -21,19 +21,13 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1130028
|
||||
<script type="application/javascript"><![CDATA[
|
||||
|
||||
/** Test for Bug 1130028 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
var connectedCallbackCount = 0;
|
||||
|
||||
var createdCallbackCount = 0;
|
||||
|
||||
// Callback should be called once by element created in chrome,
|
||||
// and once by element created in content.
|
||||
function createdCallbackCalled() {
|
||||
createdCallbackCount++;
|
||||
ok(true, "Created callback called, should be called twice in test.");
|
||||
// Callback should be called only once by element created in content.
|
||||
function connectedCallbackCalled() {
|
||||
connectedCallbackCount++;
|
||||
is(connectedCallbackCount, 1, "Connected callback called, should be called once in test.");
|
||||
is(this.magicNumber, 42, "Callback should be able to see the custom prototype.");
|
||||
if (createdCallbackCount == 2) {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
function startTests() {
|
||||
@@ -45,10 +39,13 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1130028
|
||||
|
||||
var proto = Object.create(frame.contentWindow.HTMLElement.prototype);
|
||||
proto.magicNumber = 42;
|
||||
proto.createdCallback = createdCallbackCalled;
|
||||
frame.contentDocument.registerElement("x-bar", { prototype: proto });
|
||||
proto.connectedCallback = connectedCallbackCalled;
|
||||
|
||||
frame.contentDocument.createElement("x-bar");
|
||||
frame.contentDocument.registerElement("x-bar", { prototype: proto });
|
||||
is(connectedCallbackCount, 1, "Connected callback should be called by element created in content.");
|
||||
|
||||
var element = frame.contentDocument.createElement("x-bar");
|
||||
is(element.magicNumber, 42, "Should be able to see the custom prototype on created element.");
|
||||
}
|
||||
|
||||
]]></script>
|
||||
|
||||
@@ -26,8 +26,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1130028
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function finishTest(canSeePrototype) {
|
||||
ok(true, "createdCallback called when reigsterElement was called with an extended principal.");
|
||||
ok(canSeePrototype, "createdCallback should be able to see custom prototype.");
|
||||
ok(true, "connectedCallback called when reigsterElement was called with an extended principal.");
|
||||
ok(canSeePrototype, "connectedCallback should be able to see custom prototype.");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
|
||||
@@ -362,7 +362,7 @@ function testChildList5() {
|
||||
is(records[5].previousSibling, c3, "");
|
||||
is(records[5].nextSibling, c5, "");
|
||||
observer.disconnect();
|
||||
then(testAdoptNode);
|
||||
then(testNestedMutations);
|
||||
m = null;
|
||||
});
|
||||
m.observe(div, { childList: true, subtree: true });
|
||||
@@ -375,6 +375,37 @@ function testChildList5() {
|
||||
div.appendChild(emptyDF); // empty document shouldn't cause mutation records
|
||||
}
|
||||
|
||||
function testNestedMutations() {
|
||||
div.textContent = null;
|
||||
div.appendChild(document.createTextNode("foo"));
|
||||
var m2WasCalled = false;
|
||||
m = new M(function(records, observer) {
|
||||
is(records[0].type, "characterData", "Should have got characterData");
|
||||
observer.disconnect();
|
||||
m = null;
|
||||
m3 = new M(function(records, observer) {
|
||||
ok(m2WasCalled, "m2 should have been called before m3!");
|
||||
is(records[0].type, "characterData", "Should have got characterData");
|
||||
observer.disconnect();
|
||||
then(testAdoptNode);
|
||||
m3 = null;
|
||||
});
|
||||
m3.observe(div, { characterData: true, subtree: true});
|
||||
div.firstChild.data = "foo";
|
||||
});
|
||||
m2 = new M(function(records, observer) {
|
||||
m2WasCalled = true;
|
||||
is(records[0].type, "characterData", "Should have got characterData");
|
||||
observer.disconnect();
|
||||
m2 = null;
|
||||
});
|
||||
m2.observe(div, { characterData: true, subtree: true});
|
||||
div.appendChild(document.createTextNode("foo"));
|
||||
m.observe(div, { characterData: true, subtree: true });
|
||||
|
||||
div.firstChild.data = "bar";
|
||||
}
|
||||
|
||||
function testAdoptNode() {
|
||||
var d1 = document.implementation.createHTMLDocument(null);
|
||||
var d2 = document.implementation.createHTMLDocument(null);
|
||||
|
||||
@@ -16,13 +16,16 @@
|
||||
#include "mozilla/SizePrintfMacros.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "mozilla/UseCounter.h"
|
||||
#include "mozilla/dom/DocGroup.h"
|
||||
|
||||
#include "AccessCheck.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDOMGlobalPropertyInitializer.h"
|
||||
#include "nsIParserService.h"
|
||||
#include "nsIPermissionManager.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIXPConnect.h"
|
||||
@@ -37,6 +40,7 @@
|
||||
#include "nsGlobalWindow.h"
|
||||
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/dom/CustomElementRegistry.h"
|
||||
#include "mozilla/dom/DOMError.h"
|
||||
#include "mozilla/dom/DOMErrorBinding.h"
|
||||
#include "mozilla/dom/DOMException.h"
|
||||
@@ -44,6 +48,7 @@
|
||||
#include "mozilla/dom/HTMLObjectElement.h"
|
||||
#include "mozilla/dom/HTMLObjectElementBinding.h"
|
||||
#include "mozilla/dom/HTMLSharedObjectElement.h"
|
||||
#include "mozilla/dom/HTMLElementBinding.h"
|
||||
#include "mozilla/dom/HTMLEmbedElementBinding.h"
|
||||
#include "mozilla/dom/HTMLAppletElementBinding.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
@@ -62,6 +67,30 @@ namespace dom {
|
||||
|
||||
using namespace workers;
|
||||
|
||||
// Forward declare GetConstructorObject methods.
|
||||
#define HTML_TAG(_tag, _classname, _interfacename) \
|
||||
namespace HTML##_interfacename##ElementBinding { \
|
||||
JSObject* GetConstructorObject(JSContext*); \
|
||||
}
|
||||
#define HTML_OTHER(_tag)
|
||||
#include "nsHTMLTagList.h"
|
||||
#undef HTML_TAG
|
||||
#undef HTML_OTHER
|
||||
|
||||
typedef JSObject* (*constructorGetterCallback)(JSContext*);
|
||||
|
||||
// Mapping of html tag and GetConstructorObject methods.
|
||||
#define HTML_TAG(_tag, _classname, _interfacename) HTML##_interfacename##ElementBinding::GetConstructorObject,
|
||||
#define HTML_OTHER(_tag) nullptr,
|
||||
// We use eHTMLTag_foo (where foo is the tag) which is defined in nsHTMLTags.h
|
||||
// to index into this array.
|
||||
static const constructorGetterCallback sConstructorGetterCallback[] = {
|
||||
HTMLUnknownElementBinding::GetConstructorObject,
|
||||
#include "nsHTMLTagList.h"
|
||||
#undef HTML_TAG
|
||||
#undef HTML_OTHER
|
||||
};
|
||||
|
||||
const JSErrorFormatString ErrorFormatString[] = {
|
||||
#define MSG_DEF(_name, _argc, _exn, _str) \
|
||||
{ #_name, _str, _argc, _exn },
|
||||
@@ -3377,6 +3406,189 @@ GetDesiredProto(JSContext* aCx, const JS::CallArgs& aCallArgs,
|
||||
return true;
|
||||
}
|
||||
|
||||
CustomElementReactionsStack*
|
||||
GetCustomElementReactionsStack(JS::Handle<JSObject*> aObj)
|
||||
{
|
||||
// This might not be the right object, if there are wrappers. Unwrap if we can.
|
||||
JSObject* obj = js::CheckedUnwrap(aObj);
|
||||
if (!obj) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsGlobalWindow* window = xpc::WindowGlobalOrNull(obj);
|
||||
if (!window) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DocGroup* docGroup = window->AsInner()->GetDocGroup();
|
||||
if (!docGroup) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return docGroup->CustomElementReactionsStack();
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/dom.html#htmlconstructor
|
||||
already_AddRefed<nsGenericHTMLElement>
|
||||
CreateHTMLElement(const GlobalObject& aGlobal, const JS::CallArgs& aCallArgs,
|
||||
JS::Handle<JSObject*> aGivenProto, ErrorResult& aRv)
|
||||
{
|
||||
// Step 1.
|
||||
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
if (!window) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsIDocument* doc = window->GetExtantDoc();
|
||||
if (!doc) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<mozilla::dom::CustomElementRegistry> registry(window->CustomElements());
|
||||
if (!registry) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Step 2 is in the code output by CGClassConstructor.
|
||||
// Step 3.
|
||||
JSContext* cx = aGlobal.Context();
|
||||
JS::Rooted<JSObject*> newTarget(cx, &aCallArgs.newTarget().toObject());
|
||||
CustomElementDefinition* definition =
|
||||
registry->LookupCustomElementDefinition(cx, newTarget);
|
||||
if (!definition) {
|
||||
aRv.ThrowTypeError<MSG_ILLEGAL_CONSTRUCTOR>();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// The callee might be an Xray. Unwrap it to get actual callee.
|
||||
JS::Rooted<JSObject*> callee(cx, js::CheckedUnwrap(&aCallArgs.callee()));
|
||||
if (!callee) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// And the actual callee might be in different compartment, so enter its
|
||||
// compartment before getting the standard constructor object to compare to,
|
||||
// so we get it from the same global as callee itself.
|
||||
JSAutoCompartment ac(cx, callee);
|
||||
int32_t tag = eHTMLTag_userdefined;
|
||||
if (!definition->IsCustomBuiltIn()) {
|
||||
// Step 4.
|
||||
// If the definition is for an autonomous custom element, the active
|
||||
// function should be HTMLElement.
|
||||
JS::Rooted<JSObject*> constructor(cx, HTMLElementBinding::GetConstructorObject(cx));
|
||||
if (!constructor) {
|
||||
aRv.NoteJSContextException(cx);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (callee != constructor) {
|
||||
aRv.ThrowTypeError<MSG_ILLEGAL_CONSTRUCTOR>();
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
// Step 5.
|
||||
// If the definition is for a customized built-in element, the localName
|
||||
// should be defined in the specification.
|
||||
nsIParserService* parserService = nsContentUtils::GetParserService();
|
||||
if (!parserService) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
tag = parserService->HTMLCaseSensitiveAtomTagToId(definition->mLocalName);
|
||||
if (tag == eHTMLTag_userdefined) {
|
||||
aRv.ThrowTypeError<MSG_ILLEGAL_CONSTRUCTOR>();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(tag <= NS_HTML_TAG_MAX, "tag is out of bounds");
|
||||
|
||||
// If the definition is for a customized built-in element, the active
|
||||
// function should be the localname's element interface.
|
||||
constructorGetterCallback cb = sConstructorGetterCallback[tag];
|
||||
if (!cb) {
|
||||
aRv.ThrowTypeError<MSG_ILLEGAL_CONSTRUCTOR>();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> constructor(cx, cb(cx));
|
||||
if (!constructor) {
|
||||
aRv.NoteJSContextException(cx);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (callee != constructor) {
|
||||
aRv.ThrowTypeError<MSG_ILLEGAL_CONSTRUCTOR>();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<mozilla::dom::NodeInfo> nodeInfo =
|
||||
doc->NodeInfoManager()->GetNodeInfo(definition->mLocalName,
|
||||
nullptr,
|
||||
kNameSpaceID_XHTML,
|
||||
nsIDOMNode::ELEMENT_NODE);
|
||||
if (!nodeInfo) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Step 6 and Step 7 are in the code output by CGClassConstructor.
|
||||
// Step 8.
|
||||
nsTArray<RefPtr<nsGenericHTMLElement>>& constructionStack =
|
||||
definition->mConstructionStack;
|
||||
if (constructionStack.IsEmpty()) {
|
||||
RefPtr<nsGenericHTMLElement> newElement;
|
||||
if (tag == eHTMLTag_userdefined) {
|
||||
// Autonomous custom element.
|
||||
newElement = NS_NewHTMLElement(nodeInfo.forget());
|
||||
} else {
|
||||
// Customized built-in element.
|
||||
newElement = CreateHTMLElement(tag, nodeInfo.forget(), NOT_FROM_PARSER);
|
||||
}
|
||||
|
||||
newElement->SetCustomElementData(
|
||||
new CustomElementData(definition->mType, CustomElementData::State::eCustom));
|
||||
|
||||
newElement->SetCustomElementDefinition(definition);
|
||||
|
||||
return newElement.forget();
|
||||
}
|
||||
|
||||
// Step 9.
|
||||
RefPtr<nsGenericHTMLElement>& element = constructionStack.LastElement();
|
||||
|
||||
// Step 10.
|
||||
if (element == ALEADY_CONSTRUCTED_MARKER) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Step 11.
|
||||
// Do prototype swizzling for upgrading a custom element here, for cases when
|
||||
// we have a reflector already. If we don't have one yet, our caller will
|
||||
// create it with the right proto (by calling DoGetOrCreateDOMReflector with
|
||||
// that proto).
|
||||
JS::Rooted<JSObject*> reflector(cx, element->GetWrapper());
|
||||
if (reflector) {
|
||||
// reflector might be in different compartment.
|
||||
JSAutoCompartment ac(cx, reflector);
|
||||
JS::Rooted<JSObject*> givenProto(cx, aGivenProto);
|
||||
if (!JS_WrapObject(cx, &givenProto) ||
|
||||
!JS_SetPrototype(cx, reflector, givenProto)) {
|
||||
aRv.NoteJSContextException(cx);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Step 12 and Step 13.
|
||||
return element.forget();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
namespace binding_detail {
|
||||
void
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
|
||||
#include "nsWrapperCacheInlines.h"
|
||||
|
||||
class nsGenericHTMLElement;
|
||||
class nsIJSID;
|
||||
|
||||
namespace mozilla {
|
||||
@@ -49,6 +50,7 @@ namespace mozilla {
|
||||
enum UseCounter : int16_t;
|
||||
|
||||
namespace dom {
|
||||
class CustomElementReactionsStack;
|
||||
template<typename KeyType, typename ValueType> class Record;
|
||||
|
||||
nsresult
|
||||
@@ -3420,6 +3422,19 @@ bool
|
||||
GetDesiredProto(JSContext* aCx, const JS::CallArgs& aCallArgs,
|
||||
JS::MutableHandle<JSObject*> aDesiredProto);
|
||||
|
||||
// Get the CustomElementReactionsStack for the docgroup of the global
|
||||
// of the underlying object of aObj. This can be null if aObj can't
|
||||
// be CheckUnwrapped, or if the global of the result has no docgroup
|
||||
// (e.g. because it's not a Window global).
|
||||
CustomElementReactionsStack*
|
||||
GetCustomElementReactionsStack(JS::Handle<JSObject*> aObj);
|
||||
// This function is expected to be called from the constructor function for an
|
||||
// HTML element interface; the global/callargs need to be whatever was passed to
|
||||
// that constructor function.
|
||||
already_AddRefed<nsGenericHTMLElement>
|
||||
CreateHTMLElement(const GlobalObject& aGlobal, const JS::CallArgs& aCallArgs,
|
||||
JS::Handle<JSObject*> aGivenProto, ErrorResult& aRv);
|
||||
|
||||
void
|
||||
SetDocumentAndPageUseCounter(JSContext* aCx, JSObject* aObject,
|
||||
UseCounter aUseCounter);
|
||||
|
||||
@@ -53,11 +53,6 @@ DOMInterfaces = {
|
||||
'concrete': False
|
||||
},
|
||||
|
||||
'AddonManagerPermissions': {
|
||||
'wrapperCache': False,
|
||||
'concrete': False
|
||||
},
|
||||
|
||||
'AnimationEffectReadOnly': {
|
||||
'concrete': False
|
||||
},
|
||||
@@ -340,14 +335,6 @@ DOMInterfaces = {
|
||||
'wrapperCache': False,
|
||||
},
|
||||
|
||||
'FlyWebFetchEvent': {
|
||||
'headerFile': 'FlyWebServerEvents.h',
|
||||
},
|
||||
|
||||
'FlyWebWebSocketEvent': {
|
||||
'headerFile': 'FlyWebServerEvents.h',
|
||||
},
|
||||
|
||||
'FontFaceSet': {
|
||||
'implicitJSContext': [ 'load' ],
|
||||
},
|
||||
@@ -1638,6 +1625,15 @@ DOMInterfaces = {
|
||||
'register': False,
|
||||
},
|
||||
|
||||
'TestHTMLConstructorInterface' : {
|
||||
'headerFile': 'TestBindingHeader.h',
|
||||
'register': False,
|
||||
},
|
||||
|
||||
'TestCEReactionsInterface' : {
|
||||
'headerFile': 'TestBindingHeader.h',
|
||||
'register': False,
|
||||
},
|
||||
}
|
||||
|
||||
# These are temporary, until they've been converted to use new DOM bindings
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/CallbackObject.h"
|
||||
#include "mozilla/CycleCollectedJSContext.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
@@ -79,7 +80,10 @@ CallbackObject::CallSetup::CallSetup(CallbackObject* aCallback,
|
||||
, mIsMainThread(NS_IsMainThread())
|
||||
{
|
||||
if (mIsMainThread) {
|
||||
nsContentUtils::EnterMicroTask();
|
||||
CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get();
|
||||
if (ccjs) {
|
||||
ccjs->EnterMicroTask();
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the caller's subject principal (if necessary) early, before we
|
||||
@@ -288,7 +292,10 @@ CallbackObject::CallSetup::~CallSetup()
|
||||
// It is important that this is the last thing we do, after leaving the
|
||||
// compartment and undoing all our entry/incumbent script changes
|
||||
if (mIsMainThread) {
|
||||
nsContentUtils::LeaveMicroTask();
|
||||
CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get();
|
||||
if (ccjs) {
|
||||
ccjs->LeaveMicroTask();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+133
-25
@@ -1109,6 +1109,12 @@ class CGHeaders(CGWrapper):
|
||||
# Now find all the things we'll need as arguments because we
|
||||
# need to wrap or unwrap them.
|
||||
bindingHeaders = set()
|
||||
|
||||
# KeyframeAnimationOptions.webidl is doing something VERY screwy and
|
||||
# Unified Building really sucks so directly include this
|
||||
if prefix == "KeyframeAnimationOptionsBinding":
|
||||
bindingHeaders.add("mozilla/dom/PrimitiveConversions.h")
|
||||
|
||||
declareIncludes = set(declareIncludes)
|
||||
|
||||
def addHeadersForType((t, dictionary)):
|
||||
@@ -1747,6 +1753,71 @@ class CGClassConstructor(CGAbstractStaticMethod):
|
||||
else:
|
||||
ctorName = self.descriptor.interface.identifier.name
|
||||
|
||||
# [HTMLConstructor] for custom element
|
||||
# This needs to live in bindings code because it directly examines
|
||||
# newtarget and the callee function to do HTMLConstructor specific things.
|
||||
if self._ctor.isHTMLConstructor():
|
||||
htmlConstructorSanityCheck = dedent("""
|
||||
// The newTarget might be a cross-compartment wrapper. Get the underlying object
|
||||
// so we can do the spec's object-identity checks.
|
||||
JS::Rooted<JSObject*> newTarget(cx, js::CheckedUnwrap(&args.newTarget().toObject()));
|
||||
if (!newTarget) {
|
||||
return ThrowErrorMessage(cx, MSG_ILLEGAL_CONSTRUCTOR);
|
||||
}
|
||||
|
||||
// Step 2 of https://html.spec.whatwg.org/multipage/dom.html#htmlconstructor.
|
||||
// Enter the compartment of our underlying newTarget object, so we end
|
||||
// up comparing to the constructor object for our interface from that global.
|
||||
{
|
||||
JSAutoCompartment ac(cx, newTarget);
|
||||
JS::Handle<JSObject*> constructor(GetConstructorObjectHandle(cx));
|
||||
if (!constructor) {
|
||||
return false;
|
||||
}
|
||||
if (newTarget == constructor) {
|
||||
return ThrowErrorMessage(cx, MSG_ILLEGAL_CONSTRUCTOR);
|
||||
}
|
||||
}
|
||||
|
||||
""")
|
||||
|
||||
# If we are unable to get desired prototype from newTarget, then we
|
||||
# fall back to the interface prototype object from newTarget's realm.
|
||||
htmlConstructorFallback = dedent("""
|
||||
if (!desiredProto) {
|
||||
// Step 7 of https://html.spec.whatwg.org/multipage/dom.html#htmlconstructor.
|
||||
// This fallback behavior is designed to match analogous behavior for the
|
||||
// JavaScript built-ins. So we enter the compartment of our underlying
|
||||
// newTarget object and fall back to the prototype object from that global.
|
||||
// XXX The spec says to use GetFunctionRealm(), which is not actually
|
||||
// the same thing as what we have here (e.g. in the case of scripted callable proxies
|
||||
// whose target is not same-compartment with the proxy, or bound functions, etc).
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1317658
|
||||
{
|
||||
JSAutoCompartment ac(cx, newTarget);
|
||||
desiredProto = GetProtoObjectHandle(cx);
|
||||
if (!desiredProto) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// desiredProto is in the compartment of the underlying newTarget object.
|
||||
// Wrap it into the context compartment.
|
||||
if (!JS_WrapObject(cx, &desiredProto)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
""")
|
||||
else:
|
||||
htmlConstructorSanityCheck = ""
|
||||
htmlConstructorFallback = ""
|
||||
|
||||
|
||||
# If we're a constructor, "obj" may not be a function, so calling
|
||||
# XrayAwareCalleeGlobal() on it is not safe. Of course in the
|
||||
# constructor case either "obj" is an Xray or we're already in the
|
||||
# content compartment, not the Xray compartment, so just
|
||||
# constructing the GlobalObject from "obj" is fine.
|
||||
preamble = fill(
|
||||
"""
|
||||
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
|
||||
@@ -1757,19 +1828,41 @@ class CGClassConstructor(CGAbstractStaticMethod):
|
||||
// Adding more relocations
|
||||
return ThrowConstructorWithoutNew(cx, "${ctorName}");
|
||||
}
|
||||
|
||||
GlobalObject global(cx, obj);
|
||||
if (global.Failed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$*{htmlConstructorSanityCheck}
|
||||
JS::Rooted<JSObject*> desiredProto(cx);
|
||||
if (!GetDesiredProto(cx, args, &desiredProto)) {
|
||||
return false;
|
||||
}
|
||||
$*{htmlConstructorFallback}
|
||||
""",
|
||||
chromeOnlyCheck=chromeOnlyCheck,
|
||||
ctorName=ctorName)
|
||||
ctorName=ctorName,
|
||||
htmlConstructorSanityCheck=htmlConstructorSanityCheck,
|
||||
htmlConstructorFallback=htmlConstructorFallback)
|
||||
|
||||
name = self._ctor.identifier.name
|
||||
nativeName = MakeNativeName(self.descriptor.binaryNameFor(name))
|
||||
callGenerator = CGMethodCall(nativeName, True, self.descriptor,
|
||||
self._ctor, isConstructor=True,
|
||||
constructorName=ctorName)
|
||||
if self._ctor.isHTMLConstructor():
|
||||
signatures = self._ctor.signatures()
|
||||
assert len(signatures) == 1
|
||||
# Given that HTMLConstructor takes no args, we can just codegen a
|
||||
# call to CreateHTMLElement() in BindingUtils which reuses the
|
||||
# factory thing in HTMLContentSink. Then we don't have to implement
|
||||
# Constructor on all the HTML elements.
|
||||
callGenerator = CGPerSignatureCall(signatures[0][0], signatures[0][1],
|
||||
"CreateHTMLElement", True,
|
||||
self.descriptor, self._ctor,
|
||||
isConstructor=True)
|
||||
else:
|
||||
name = self._ctor.identifier.name
|
||||
nativeName = MakeNativeName(self.descriptor.binaryNameFor(name))
|
||||
callGenerator = CGMethodCall(nativeName, True, self.descriptor,
|
||||
self._ctor, isConstructor=True,
|
||||
constructorName=ctorName)
|
||||
return preamble + "\n" + callGenerator.define()
|
||||
|
||||
|
||||
@@ -7386,7 +7479,7 @@ class CGPerSignatureCall(CGThing):
|
||||
def __init__(self, returnType, arguments, nativeMethodName, static,
|
||||
descriptor, idlNode, argConversionStartsAt=0, getter=False,
|
||||
setter=False, isConstructor=False, useCounterName=None,
|
||||
resultVar=None):
|
||||
resultVar=None, objectName="obj"):
|
||||
assert idlNode.isMethod() == (not getter and not setter)
|
||||
assert idlNode.isAttr() == (getter or setter)
|
||||
# Constructors are always static
|
||||
@@ -7440,26 +7533,23 @@ class CGPerSignatureCall(CGThing):
|
||||
|
||||
argsPre = []
|
||||
if idlNode.isStatic():
|
||||
# If we're a constructor, "obj" may not be a function, so calling
|
||||
# XrayAwareCalleeGlobal() on it is not safe. Of course in the
|
||||
# constructor case either "obj" is an Xray or we're already in the
|
||||
# content compartment, not the Xray compartment, so just
|
||||
# constructing the GlobalObject from "obj" is fine.
|
||||
if isConstructor:
|
||||
objForGlobalObject = "obj"
|
||||
else:
|
||||
objForGlobalObject = "xpc::XrayAwareCalleeGlobal(obj)"
|
||||
cgThings.append(CGGeneric(fill(
|
||||
"""
|
||||
GlobalObject global(cx, ${obj});
|
||||
if (global.Failed()) {
|
||||
return false;
|
||||
}
|
||||
# If we're a constructor, the GlobalObject struct will be created in
|
||||
# CGClassConstructor.
|
||||
if not isConstructor:
|
||||
cgThings.append(CGGeneric(dedent(
|
||||
"""
|
||||
GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
|
||||
if (global.Failed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
""")))
|
||||
|
||||
""",
|
||||
obj=objForGlobalObject)))
|
||||
argsPre.append("global")
|
||||
|
||||
if isConstructor and idlNode.isHTMLConstructor():
|
||||
argsPre.extend(["args", "desiredProto"])
|
||||
|
||||
# For JS-implemented interfaces we do not want to base the
|
||||
# needsCx decision on the types involved, just on our extended
|
||||
# attributes. Also, JSContext is not needed for the static case
|
||||
@@ -7588,6 +7678,17 @@ class CGPerSignatureCall(CGThing):
|
||||
CGIfWrapper(CGList(xraySteps),
|
||||
"objIsXray"))
|
||||
|
||||
if (idlNode.getExtendedAttribute('CEReactions') is not None and
|
||||
not getter):
|
||||
cgThings.append(CGGeneric(fill(
|
||||
"""
|
||||
CustomElementReactionsStack* reactionsStack = GetCustomElementReactionsStack(${obj});
|
||||
Maybe<AutoCEReaction> ceReaction;
|
||||
if (reactionsStack) {
|
||||
ceReaction.emplace(reactionsStack, cx);
|
||||
}
|
||||
""", obj=objectName)))
|
||||
|
||||
# If this is a method that was generated by a maplike/setlike
|
||||
# interface, use the maplike/setlike generator to fill in the body.
|
||||
# Otherwise, use CGCallGenerator to call the native method.
|
||||
@@ -10985,7 +11086,8 @@ class CGProxySpecialOperation(CGPerSignatureCall):
|
||||
# CGPerSignatureCall won't do any argument conversion of its own.
|
||||
CGPerSignatureCall.__init__(self, returnType, arguments, nativeName,
|
||||
False, descriptor, operation,
|
||||
len(arguments), resultVar=resultVar)
|
||||
len(arguments), resultVar=resultVar,
|
||||
objectName="proxy")
|
||||
|
||||
if operation.isSetter() or operation.isCreator():
|
||||
# arguments[0] is the index or name of the item that we're setting.
|
||||
@@ -13755,12 +13857,18 @@ class CGBindingRoot(CGThing):
|
||||
iface = desc.interface
|
||||
return any(m.getExtendedAttribute("Deprecated") for m in iface.members + [iface])
|
||||
|
||||
def descriptorHasCEReactions(desc):
|
||||
iface = desc.interface
|
||||
return any(m.getExtendedAttribute("CEReactions") for m in iface.members + [iface])
|
||||
|
||||
bindingHeaders["nsIDocument.h"] = any(
|
||||
descriptorDeprecated(d) for d in descriptors)
|
||||
bindingHeaders["mozilla/Preferences.h"] = any(
|
||||
descriptorRequiresPreferences(d) for d in descriptors)
|
||||
bindingHeaders["mozilla/dom/DOMJSProxyHandler.h"] = any(
|
||||
d.concrete and d.proxy for d in descriptors)
|
||||
bindingHeaders["mozilla/dom/CustomElementRegistry.h"] = any(
|
||||
descriptorHasCEReactions(d) for d in descriptors)
|
||||
|
||||
def descriptorHasChromeOnly(desc):
|
||||
ctor = desc.interface.ctor()
|
||||
|
||||
@@ -4,8 +4,12 @@
|
||||
* 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 "jswrapper.h"
|
||||
#include "WebIDLGlobalNameHash.h"
|
||||
#include "js/GCAPI.h"
|
||||
#include "XrayWrapper.h"
|
||||
#include "XPCWrapper.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "mozilla/HashFunctions.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/dom/DOMJSProxyHandler.h"
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#define mozilla_dom_WebIDLGlobalNameHash_h__
|
||||
|
||||
#include "js/RootingAPI.h"
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@@ -89,7 +89,7 @@ LOCAL_INCLUDES += [
|
||||
'/media/webrtc/signaling/src/peerconnection',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
SOURCES += [
|
||||
'BindingUtils.cpp',
|
||||
'CallbackInterface.cpp',
|
||||
'CallbackObject.cpp',
|
||||
|
||||
@@ -14,8 +14,13 @@
|
||||
#include "jsapi.h"
|
||||
#include "js/RootingAPI.h"
|
||||
|
||||
#include "jswrapper.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsString.h"
|
||||
#include "nsStringFwd.h"
|
||||
|
||||
class nsScriptErrorNote final : public nsIScriptErrorNote {
|
||||
public:
|
||||
|
||||
@@ -22,7 +22,7 @@ using namespace mozilla::dom;
|
||||
namespace {
|
||||
|
||||
static nsCString
|
||||
FormatStackString(JSContext* cx, HandleObject aStack) {
|
||||
FormatStackString(JSContext* cx, JS::HandleObject aStack) {
|
||||
JS::RootedString formattedStack(cx);
|
||||
|
||||
if (!JS::BuildStackString(cx, aStack, &formattedStack)) {
|
||||
@@ -111,7 +111,7 @@ nsScriptErrorWithStack::ToString(nsACString& /*UTF8*/ aResult)
|
||||
}
|
||||
|
||||
JSContext* cx = jsapi.cx();
|
||||
RootedObject stack(cx, mStack);
|
||||
JS::RootedObject stack(cx, mStack);
|
||||
nsCString stackString = FormatStackString(cx, stack);
|
||||
nsCString combined = message + NS_LITERAL_CSTRING("\n") + stackString;
|
||||
aResult.Assign(combined);
|
||||
|
||||
@@ -1582,7 +1582,7 @@ class IDLInterface(IDLInterfaceOrNamespace):
|
||||
[self.location])
|
||||
|
||||
self._noInterfaceObject = True
|
||||
elif identifier == "Constructor" or identifier == "NamedConstructor" or identifier == "ChromeConstructor":
|
||||
elif identifier == "Constructor" or identifier == "NamedConstructor" or identifier == "ChromeConstructor" or identifier == "HTMLConstructor":
|
||||
if identifier == "Constructor" and not self.hasInterfaceObject():
|
||||
raise WebIDLError(str(identifier) + " and NoInterfaceObject are incompatible",
|
||||
[self.location])
|
||||
@@ -1595,11 +1595,20 @@ class IDLInterface(IDLInterfaceOrNamespace):
|
||||
raise WebIDLError(str(identifier) + " and NoInterfaceObject are incompatible",
|
||||
[self.location])
|
||||
|
||||
if identifier == "HTMLConstructor":
|
||||
if not self.hasInterfaceObject():
|
||||
raise WebIDLError(str(identifier) + " and NoInterfaceObject are incompatible",
|
||||
[self.location])
|
||||
|
||||
if not attr.noArguments():
|
||||
raise WebIDLError(str(identifier) + " must take no arguments",
|
||||
[attr.location])
|
||||
|
||||
args = attr.args() if attr.hasArgs() else []
|
||||
|
||||
retType = IDLWrapperType(self.location, self)
|
||||
|
||||
if identifier == "Constructor" or identifier == "ChromeConstructor":
|
||||
if identifier == "Constructor" or identifier == "ChromeConstructor" or identifier == "HTMLConstructor":
|
||||
name = "constructor"
|
||||
allowForbidden = True
|
||||
else:
|
||||
@@ -1610,7 +1619,8 @@ class IDLInterface(IDLInterfaceOrNamespace):
|
||||
allowForbidden=allowForbidden)
|
||||
|
||||
method = IDLMethod(self.location, methodIdentifier, retType,
|
||||
args, static=True)
|
||||
args, static=True,
|
||||
htmlConstructor=(identifier == "HTMLConstructor"))
|
||||
# Constructors are always NewObject and are always
|
||||
# assumed to be able to throw (since there's no way to
|
||||
# indicate otherwise) and never have any other
|
||||
@@ -1622,7 +1632,7 @@ class IDLInterface(IDLInterfaceOrNamespace):
|
||||
method.addExtendedAttributes(
|
||||
[IDLExtendedAttribute(self.location, ("ChromeOnly",))])
|
||||
|
||||
if identifier == "Constructor" or identifier == "ChromeConstructor":
|
||||
if identifier == "Constructor" or identifier == "ChromeConstructor" or identifier == "HTMLConstructor":
|
||||
method.resolve(self)
|
||||
else:
|
||||
# We need to detect conflicts for NamedConstructors across
|
||||
@@ -4073,6 +4083,11 @@ class IDLAttribute(IDLInterfaceMember):
|
||||
raise WebIDLError("Attribute returns a type that is not exposed "
|
||||
"everywhere where the attribute is exposed",
|
||||
[self.location])
|
||||
if self.getExtendedAttribute("CEReactions"):
|
||||
if self.readonly:
|
||||
raise WebIDLError("[CEReactions] is not allowed on "
|
||||
"readonly attributes",
|
||||
[self.location])
|
||||
|
||||
def handleExtendedAttribute(self, attr):
|
||||
identifier = attr.identifier()
|
||||
@@ -4243,6 +4258,10 @@ class IDLAttribute(IDLInterfaceMember):
|
||||
raise WebIDLError("[Unscopable] is only allowed on non-static "
|
||||
"attributes and operations",
|
||||
[attr.location, self.location])
|
||||
elif identifier == "CEReactions":
|
||||
if not attr.noArguments():
|
||||
raise WebIDLError("[CEReactions] must take no arguments",
|
||||
[attr.location])
|
||||
elif (identifier == "Pref" or
|
||||
identifier == "Deprecated" or
|
||||
identifier == "SetterThrows" or
|
||||
@@ -4537,7 +4556,7 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
||||
static=False, getter=False, setter=False, creator=False,
|
||||
deleter=False, specialType=NamedOrIndexed.Neither,
|
||||
legacycaller=False, stringifier=False, jsonifier=False,
|
||||
maplikeOrSetlikeOrIterable=None):
|
||||
maplikeOrSetlikeOrIterable=None, htmlConstructor=False):
|
||||
# REVIEW: specialType is NamedOrIndexed -- wow, this is messed up.
|
||||
IDLInterfaceMember.__init__(self, location, identifier,
|
||||
IDLInterfaceMember.Tags.Method)
|
||||
@@ -4567,6 +4586,10 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
||||
self._jsonifier = jsonifier
|
||||
assert maplikeOrSetlikeOrIterable is None or isinstance(maplikeOrSetlikeOrIterable, IDLMaplikeOrSetlikeOrIterableBase)
|
||||
self.maplikeOrSetlikeOrIterable = maplikeOrSetlikeOrIterable
|
||||
assert isinstance(htmlConstructor, bool)
|
||||
# The identifier of a HTMLConstructor must be 'constructor'.
|
||||
assert not htmlConstructor or identifier.name == "constructor"
|
||||
self._htmlConstructor = htmlConstructor
|
||||
self._specialType = specialType
|
||||
self._unforgeable = False
|
||||
self.dependsOn = "Everything"
|
||||
@@ -4667,6 +4690,9 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
||||
self.isStringifier() or
|
||||
self.isJsonifier())
|
||||
|
||||
def isHTMLConstructor(self):
|
||||
return self._htmlConstructor
|
||||
|
||||
def hasOverloads(self):
|
||||
return self._hasOverloads
|
||||
|
||||
@@ -4722,6 +4748,8 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
||||
assert not method.isStringifier()
|
||||
assert not self.isJsonifier()
|
||||
assert not method.isJsonifier()
|
||||
assert not self.isHTMLConstructor()
|
||||
assert not method.isHTMLConstructor()
|
||||
|
||||
return self
|
||||
|
||||
@@ -4964,6 +4992,15 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
||||
raise WebIDLError("[Unscopable] is only allowed on non-static "
|
||||
"attributes and operations",
|
||||
[attr.location, self.location])
|
||||
elif identifier == "CEReactions":
|
||||
if not attr.noArguments():
|
||||
raise WebIDLError("[CEReactions] must take no arguments",
|
||||
[attr.location])
|
||||
|
||||
if self.isSpecial() and not self.isSetter() and not self.isDeleter():
|
||||
raise WebIDLError("[CEReactions] is only allowed on operation, "
|
||||
"attribute, setter, and deleter",
|
||||
[attr.location, self.location])
|
||||
elif (identifier == "Throws" or
|
||||
identifier == "NewObject" or
|
||||
identifier == "ChromeOnly" or
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
def WebIDLTest(parser, harness):
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface Foo {
|
||||
[CEReactions(DOMString a)] void foo(boolean arg2);
|
||||
};
|
||||
""")
|
||||
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Should have thrown for [CEReactions] with an argument")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface Foo {
|
||||
[CEReactions(DOMString b)] readonly attribute boolean bar;
|
||||
};
|
||||
""")
|
||||
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Should have thrown for [CEReactions] with an argument")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface Foo {
|
||||
[CEReactions] attribute boolean bar;
|
||||
};
|
||||
""")
|
||||
|
||||
results = parser.finish()
|
||||
except Exception, e:
|
||||
harness.ok(False, "Shouldn't have thrown for [CEReactions] used on writable attribute. %s" % e)
|
||||
threw = True
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface Foo {
|
||||
[CEReactions] void foo(boolean arg2);
|
||||
};
|
||||
""")
|
||||
|
||||
results = parser.finish()
|
||||
except Exception, e:
|
||||
harness.ok(False, "Shouldn't have thrown for [CEReactions] used on regular operations. %s" % e)
|
||||
threw = True
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface Foo {
|
||||
[CEReactions] readonly attribute boolean A;
|
||||
};
|
||||
""")
|
||||
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Should have thrown for [CEReactions] used on a readonly attribute")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
[CEReactions]
|
||||
interface Foo {
|
||||
}
|
||||
""")
|
||||
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Should have thrown for [CEReactions] used on a interface")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface Foo {
|
||||
[CEReactions] getter any(DOMString name);
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw,
|
||||
"Should have thrown for [CEReactions] used on a named getter")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface Foo {
|
||||
[CEReactions] creator boolean (DOMString name, boolean value);
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw,
|
||||
"Should have thrown for [CEReactions] used on a named creator")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface Foo {
|
||||
[CEReactions] legacycaller double compute(double x);
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw,
|
||||
"Should have thrown for [CEReactions] used on a legacycaller")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface Foo {
|
||||
[CEReactions] stringifier DOMString ();
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw,
|
||||
"Should have thrown for [CEReactions] used on a stringifier")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface Foo {
|
||||
[CEReactions] jsonifier;
|
||||
};
|
||||
""")
|
||||
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Should have thrown for [CEReactions] used on a jsonifier")
|
||||
@@ -13,7 +13,7 @@ def WebIDLTest(parser, harness):
|
||||
def checkMethod(method, QName, name, signatures,
|
||||
static=True, getter=False, setter=False, creator=False,
|
||||
deleter=False, legacycaller=False, stringifier=False,
|
||||
chromeOnly=False):
|
||||
chromeOnly=False, htmlConstructor=False):
|
||||
harness.ok(isinstance(method, WebIDL.IDLMethod),
|
||||
"Should be an IDLMethod")
|
||||
harness.ok(method.isMethod(), "Method is a method")
|
||||
@@ -29,6 +29,7 @@ def WebIDLTest(parser, harness):
|
||||
harness.check(method.isLegacycaller(), legacycaller, "Method has the correct legacycaller value")
|
||||
harness.check(method.isStringifier(), stringifier, "Method has the correct stringifier value")
|
||||
harness.check(method.getExtendedAttribute("ChromeOnly") is not None, chromeOnly, "Method has the correct value for ChromeOnly")
|
||||
harness.check(method.isHTMLConstructor(), htmlConstructor, "Method has the correct htmlConstructor value")
|
||||
harness.check(len(method.signatures()), len(signatures), "Method has the correct number of signatures")
|
||||
|
||||
sigpairs = zip(method.signatures(), signatures)
|
||||
@@ -78,6 +79,21 @@ def WebIDLTest(parser, harness):
|
||||
("TestConstructorOverloads (Wrapper)",
|
||||
[("::TestConstructorOverloads::constructor::bar", "bar", "Boolean", False, False)])])
|
||||
|
||||
parser = parser.reset()
|
||||
parser.parse("""
|
||||
[HTMLConstructor]
|
||||
interface TestHTMLConstructor {
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
harness.check(len(results), 1, "Should be one production")
|
||||
harness.ok(isinstance(results[0], WebIDL.IDLInterface),
|
||||
"Should be an IDLInterface")
|
||||
|
||||
checkMethod(results[0].ctor(), "::TestHTMLConstructor::constructor",
|
||||
"constructor", [("TestHTMLConstructor (Wrapper)", [])],
|
||||
htmlConstructor=True)
|
||||
|
||||
parser = parser.reset()
|
||||
parser.parse("""
|
||||
[ChromeConstructor()]
|
||||
@@ -107,3 +123,151 @@ def WebIDLTest(parser, harness):
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Can't have both a Constructor and a ChromeConstructor")
|
||||
|
||||
# Test HTMLConstructor with argument
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
[HTMLConstructor(DOMString a)]
|
||||
interface TestHTMLConstructorWithArgs {
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "HTMLConstructor should take no argument")
|
||||
|
||||
# Test HTMLConstructor on a callback interface
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
[HTMLConstructor]
|
||||
callback interface TestHTMLConstructorOnCallbackInterface {
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "HTMLConstructor can't be used on a callback interface")
|
||||
|
||||
# Test HTMLConstructor and Constructor
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
[Constructor,
|
||||
HTMLConstructor]
|
||||
interface TestHTMLConstructorAndConstructor {
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Can't have both a Constructor and a HTMLConstructor")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
[HTMLConstructor,
|
||||
Constructor]
|
||||
interface TestHTMLConstructorAndConstructor {
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Can't have both a HTMLConstructor and a Constructor")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
[HTMLConstructor,
|
||||
Constructor(DOMString a)]
|
||||
interface TestHTMLConstructorAndConstructor {
|
||||
};
|
||||
""")
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Can't have both a HTMLConstructor and a Constructor")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
[Constructor(DOMString a),
|
||||
HTMLConstructor]
|
||||
interface TestHTMLConstructorAndConstructor {
|
||||
};
|
||||
""")
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Can't have both a HTMLConstructor and a Constructor")
|
||||
|
||||
# Test HTMLConstructor and ChromeConstructor
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
[ChromeConstructor,
|
||||
HTMLConstructor]
|
||||
interface TestHTMLConstructorAndChromeConstructor {
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Can't have both a HTMLConstructor and a ChromeConstructor")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
[HTMLConstructor,
|
||||
ChromeConstructor]
|
||||
interface TestHTMLConstructorAndChromeConstructor {
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Can't have both a HTMLConstructor and a ChromeConstructor")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
[ChromeConstructor(DOMString a),
|
||||
HTMLConstructor]
|
||||
interface TestHTMLConstructorAndChromeConstructor {
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
[HTMLConstructor,
|
||||
ChromeConstructor(DOMString a)]
|
||||
interface TestHTMLConstructorAndChromeConstructor {
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Can't have both a HTMLConstructor and a ChromeConstructor")
|
||||
@@ -34,3 +34,36 @@ def WebIDLTest(parser, harness):
|
||||
interface TestNamedConstructorNoInterfaceObject {
|
||||
};
|
||||
""")
|
||||
|
||||
# Test HTMLConstructor and NoInterfaceObject
|
||||
parser = parser.reset()
|
||||
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
[NoInterfaceObject, HTMLConstructor]
|
||||
interface TestHTMLConstructorNoInterfaceObject {
|
||||
};
|
||||
""")
|
||||
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Should have thrown.")
|
||||
|
||||
parser = parser.reset()
|
||||
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
[HTMLConstructor, NoInterfaceObject]
|
||||
interface TestHTMLConstructorNoInterfaceObject {
|
||||
};
|
||||
""")
|
||||
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Should have thrown.")
|
||||
@@ -939,6 +939,11 @@ public:
|
||||
void NeedsCallerTypeMethod(CallerType);
|
||||
bool NeedsCallerTypeAttr(CallerType);
|
||||
void SetNeedsCallerTypeAttr(bool, CallerType);
|
||||
void CeReactionsMethod();
|
||||
void CeReactionsMethodOverload();
|
||||
void CeReactionsMethodOverload(const nsAString&);
|
||||
bool CeReactionsAttr() const;
|
||||
void SetCeReactionsAttr(bool);
|
||||
int16_t LegacyCall(const JS::Value&, uint32_t, TestInterface&);
|
||||
void PassArgsWithDefaults(JSContext*, const Optional<int32_t>&,
|
||||
TestInterface*, const Dict&, double,
|
||||
@@ -1425,6 +1430,31 @@ public:
|
||||
void SetNeedsCallerTypeAttr(bool, CallerType);
|
||||
};
|
||||
|
||||
class TestHTMLConstructorInterface : public nsGenericHTMLElement
|
||||
{
|
||||
public:
|
||||
virtual nsISupports* GetParentObject();
|
||||
};
|
||||
|
||||
class TestCEReactionsInterface : public nsISupports,
|
||||
public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// We need a GetParentObject to make binding codegen happy
|
||||
virtual nsISupports* GetParentObject();
|
||||
|
||||
int32_t Item(uint32_t);
|
||||
uint32_t Length() const;
|
||||
int32_t IndexedGetter(uint32_t, bool &);
|
||||
void IndexedSetter(uint32_t, int32_t);
|
||||
void NamedDeleter(const nsAString&, bool &);
|
||||
void NamedGetter(const nsAString&, bool &, nsString&);
|
||||
void NamedSetter(const nsAString&, const nsAString&);
|
||||
void GetSupportedNames(nsTArray<nsString>&);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
||||
@@ -947,6 +947,10 @@ interface TestInterface {
|
||||
[NeedsSubjectPrincipal] attribute boolean needsSubjectPrincipalAttr;
|
||||
[NeedsCallerType] void needsCallerTypeMethod();
|
||||
[NeedsCallerType] attribute boolean needsCallerTypeAttr;
|
||||
[CEReactions] void ceReactionsMethod();
|
||||
[CEReactions] void ceReactionsMethodOverload();
|
||||
[CEReactions] void ceReactionsMethodOverload(DOMString bar);
|
||||
[CEReactions] attribute boolean ceReactionsAttr;
|
||||
legacycaller short(unsigned long arg1, TestInterface arg2);
|
||||
void passArgsWithDefaults(optional long arg1,
|
||||
optional TestInterface? arg2 = null,
|
||||
@@ -1262,3 +1266,16 @@ interface TestWorkerExposedInterface {
|
||||
[NeedsCallerType] void needsCallerTypeMethod();
|
||||
[NeedsCallerType] attribute boolean needsCallerTypeAttr;
|
||||
};
|
||||
|
||||
[HTMLConstructor]
|
||||
interface TestHTMLConstructorInterface {
|
||||
};
|
||||
|
||||
interface TestCEReactionsInterface {
|
||||
[CEReactions] setter creator void (unsigned long index, long item);
|
||||
[CEReactions] setter creator void (DOMString name, DOMString item);
|
||||
[CEReactions] deleter void (DOMString name);
|
||||
getter long item(unsigned long index);
|
||||
getter DOMString (DOMString name);
|
||||
readonly attribute unsigned long length;
|
||||
};
|
||||
@@ -777,6 +777,10 @@ interface TestExampleInterface {
|
||||
[NeedsSubjectPrincipal] attribute boolean needsSubjectPrincipalAttr;
|
||||
[NeedsCallerType] void needsCallerTypeMethod();
|
||||
[NeedsCallerType] attribute boolean needsCallerTypeAttr;
|
||||
[CEReactions] void ceReactionsMethod();
|
||||
[CEReactions] void ceReactionsMethodOverload();
|
||||
[CEReactions] void ceReactionsMethodOverload(DOMString bar);
|
||||
[CEReactions] attribute boolean ceReactionsAttr;
|
||||
legacycaller short(unsigned long arg1, TestInterface arg2);
|
||||
void passArgsWithDefaults(optional long arg1,
|
||||
optional TestInterface? arg2 = null,
|
||||
|
||||
@@ -794,6 +794,10 @@ interface TestJSImplInterface {
|
||||
[Throws] attribute boolean throwingAttr;
|
||||
[GetterThrows] attribute boolean throwingGetterAttr;
|
||||
[SetterThrows] attribute boolean throwingSetterAttr;
|
||||
[CEReactions] void ceReactionsMethod();
|
||||
[CEReactions] void ceReactionsMethodOverload();
|
||||
[CEReactions] void ceReactionsMethodOverload(DOMString bar);
|
||||
[CEReactions] attribute boolean ceReactionsAttr;
|
||||
// NeedsSubjectPrincipal not supported on JS-implemented things for
|
||||
// now, because we always pass in the caller principal anyway.
|
||||
// [NeedsSubjectPrincipal] void needsSubjectPrincipalMethod();
|
||||
|
||||
@@ -20,11 +20,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=560072
|
||||
|
||||
/** Test for Bug 560072 **/
|
||||
is(document.body,
|
||||
Object.getOwnPropertyDescriptor(HTMLDocument.prototype, "body").get.call(document),
|
||||
Object.getOwnPropertyDescriptor(Document.prototype, "body").get.call(document),
|
||||
"Should get body out of property descriptor");
|
||||
|
||||
is(document.body,
|
||||
Object.getOwnPropertyDescriptor(Object.getPrototypeOf(document), "body").get.call(document),
|
||||
Object.getOwnPropertyDescriptor(
|
||||
Object.getPrototypeOf(Object.getPrototypeOf(document)), "body").get.call(document),
|
||||
"Should get body out of property descriptor this way too");
|
||||
|
||||
</script>
|
||||
|
||||
@@ -1087,7 +1087,10 @@ EventListenerManager::HandleEventSubType(Listener* aListener,
|
||||
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
if (mIsMainThreadELM) {
|
||||
nsContentUtils::EnterMicroTask();
|
||||
CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get();
|
||||
if (ccjs) {
|
||||
ccjs->EnterMicroTask();
|
||||
}
|
||||
}
|
||||
// nsIDOMEvent::currentTarget is set in EventDispatcher.
|
||||
if (listenerHolder.HasWebIDLCallback()) {
|
||||
@@ -1099,7 +1102,10 @@ EventListenerManager::HandleEventSubType(Listener* aListener,
|
||||
result = listenerHolder.GetXPCOMCallback()->HandleEvent(aDOMEvent);
|
||||
}
|
||||
if (mIsMainThreadELM) {
|
||||
nsContentUtils::LeaveMicroTask();
|
||||
CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get();
|
||||
if (ccjs) {
|
||||
ccjs->LeaveMicroTask();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -139,10 +139,6 @@ const kEventConstructors = {
|
||||
return new ErrorEvent(aName, aProps);
|
||||
},
|
||||
},
|
||||
FlyWebFetchEvent: { create: null, // Cannot create untrusted event from JS.
|
||||
},
|
||||
FlyWebWebSocketEvent: { create: null, // Cannot create untrusted event from JS.
|
||||
},
|
||||
FocusEvent: { create: function (aName, aProps) {
|
||||
return new FocusEvent(aName, aProps);
|
||||
},
|
||||
|
||||
@@ -1,125 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsTHashtable.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsIUUIDGenerator.h"
|
||||
#include "jsapi.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
|
||||
#include "mozilla/dom/FlyWebDiscoveryManager.h"
|
||||
#include "mozilla/dom/FlyWebDiscoveryManagerBinding.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
static LazyLogModule gFlyWebDiscoveryManagerLog("FlyWebDiscoveryManager");
|
||||
#undef LOG_I
|
||||
#define LOG_I(...) MOZ_LOG(mozilla::dom::gFlyWebDiscoveryManagerLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
|
||||
#undef LOG_E
|
||||
#define LOG_E(...) MOZ_LOG(mozilla::dom::gFlyWebDiscoveryManagerLog, mozilla::LogLevel::Error, (__VA_ARGS__))
|
||||
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(FlyWebDiscoveryManager)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(FlyWebDiscoveryManager)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(FlyWebDiscoveryManager)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(FlyWebDiscoveryManager)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
FlyWebDiscoveryManager::FlyWebDiscoveryManager(nsISupports* aParent,
|
||||
FlyWebService* aService)
|
||||
: mParent(aParent)
|
||||
, mService(aService)
|
||||
, mNextId(0)
|
||||
{
|
||||
}
|
||||
|
||||
FlyWebDiscoveryManager::~FlyWebDiscoveryManager()
|
||||
{
|
||||
mService->UnregisterDiscoveryManager(this);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
FlyWebDiscoveryManager::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return FlyWebDiscoveryManagerBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
nsISupports*
|
||||
FlyWebDiscoveryManager::GetParentObject() const
|
||||
{
|
||||
return mParent;
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<FlyWebDiscoveryManager>
|
||||
FlyWebDiscoveryManager::Constructor(const GlobalObject& aGlobal, ErrorResult& rv)
|
||||
{
|
||||
RefPtr<FlyWebService> service = FlyWebService::GetOrCreate();
|
||||
if (!service) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<FlyWebDiscoveryManager> result = new FlyWebDiscoveryManager(
|
||||
aGlobal.GetAsSupports(), service);
|
||||
return result.forget();
|
||||
}
|
||||
|
||||
void
|
||||
FlyWebDiscoveryManager::ListServices(nsTArray<FlyWebDiscoveredService>& aServices)
|
||||
{
|
||||
return mService->ListDiscoveredServices(aServices);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
FlyWebDiscoveryManager::StartDiscovery(FlyWebDiscoveryCallback& aCallback)
|
||||
{
|
||||
uint32_t id = GenerateId();
|
||||
mCallbackMap.Put(id, &aCallback);
|
||||
mService->RegisterDiscoveryManager(this);
|
||||
return id;
|
||||
}
|
||||
|
||||
void
|
||||
FlyWebDiscoveryManager::StopDiscovery(uint32_t aId)
|
||||
{
|
||||
mCallbackMap.Remove(aId);
|
||||
if (mCallbackMap.Count() == 0) {
|
||||
mService->UnregisterDiscoveryManager(this);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FlyWebDiscoveryManager::PairWithService(const nsAString& aServiceId,
|
||||
FlyWebPairingCallback& aCallback)
|
||||
{
|
||||
mService->PairWithService(aServiceId, aCallback);
|
||||
}
|
||||
|
||||
void
|
||||
FlyWebDiscoveryManager::NotifyDiscoveredServicesChanged()
|
||||
{
|
||||
nsTArray<FlyWebDiscoveredService> services;
|
||||
ListServices(services);
|
||||
Sequence<FlyWebDiscoveredService> servicesSeq;
|
||||
servicesSeq.SwapElements(services);
|
||||
for (auto iter = mCallbackMap.Iter(); !iter.Done(); iter.Next()) {
|
||||
FlyWebDiscoveryCallback *callback = iter.UserData();
|
||||
ErrorResult err;
|
||||
callback->OnDiscoveredServicesChanged(servicesSeq, err);
|
||||
ENSURE_SUCCESS_VOID(err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
@@ -1,61 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_FlyWebDiscoveryManager_h
|
||||
#define mozilla_dom_FlyWebDiscoveryManager_h
|
||||
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "FlyWebDiscoveryManagerBinding.h"
|
||||
#include "FlyWebService.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class FlyWebDiscoveryManager final : public nsISupports
|
||||
, public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(FlyWebDiscoveryManager)
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
nsISupports* GetParentObject() const;
|
||||
|
||||
static already_AddRefed<FlyWebDiscoveryManager> Constructor(const GlobalObject& aGlobal,
|
||||
ErrorResult& rv);
|
||||
|
||||
void ListServices(nsTArray<FlyWebDiscoveredService>& aServices);
|
||||
uint32_t StartDiscovery(FlyWebDiscoveryCallback& aCallback);
|
||||
void StopDiscovery(uint32_t aId);
|
||||
|
||||
void PairWithService(const nsAString& aServiceId,
|
||||
FlyWebPairingCallback& callback);
|
||||
|
||||
void NotifyDiscoveredServicesChanged();
|
||||
|
||||
private:
|
||||
FlyWebDiscoveryManager(nsISupports* mParent, FlyWebService* aService);
|
||||
~FlyWebDiscoveryManager();
|
||||
|
||||
uint32_t GenerateId() {
|
||||
return ++mNextId;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
RefPtr<FlyWebService> mService;
|
||||
|
||||
uint32_t mNextId;
|
||||
|
||||
nsRefPtrHashtable<nsUint32HashKey, FlyWebDiscoveryCallback> mCallbackMap;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_FlyWebDiscoveryManager_h
|
||||
@@ -1,33 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_FlyWebPublishOptionsIPCSerialiser_h
|
||||
#define mozilla_dom_FlyWebPublishOptionsIPCSerialiser_h
|
||||
|
||||
#include "mozilla/dom/FlyWebPublishBinding.h"
|
||||
|
||||
namespace IPC {
|
||||
|
||||
template <>
|
||||
struct ParamTraits<mozilla::dom::FlyWebPublishOptions>
|
||||
{
|
||||
typedef mozilla::dom::FlyWebPublishOptions paramType;
|
||||
|
||||
// Function to serialize a FlyWebPublishOptions
|
||||
static void Write(Message *aMsg, const paramType& aParam)
|
||||
{
|
||||
WriteParam(aMsg, aParam.mUiUrl);
|
||||
}
|
||||
// Function to de-serialize a FlyWebPublishOptions
|
||||
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
|
||||
{
|
||||
return ReadParam(aMsg, aIter, &(aResult->mUiUrl));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // mozilla_dom_FlyWebPublishOptionsIPCSerialiser_h
|
||||
@@ -1,675 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/FlyWebPublishedServerIPC.h"
|
||||
#include "mozilla/dom/FlyWebPublishBinding.h"
|
||||
#include "mozilla/dom/FlyWebService.h"
|
||||
#include "mozilla/dom/Request.h"
|
||||
#include "mozilla/dom/FlyWebServerEvents.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/dom/InternalResponse.h"
|
||||
#include "mozilla/ipc/IPCStreamUtils.h"
|
||||
#include "mozilla/net/NeckoParent.h"
|
||||
#include "mozilla/net/IPCTransportProvider.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "nsCharSeparatedTokenizer.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "WebSocketChannel.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
static LazyLogModule gFlyWebPublishedServerLog("FlyWebPublishedServer");
|
||||
#undef LOG_I
|
||||
#define LOG_I(...) MOZ_LOG(mozilla::dom::gFlyWebPublishedServerLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
|
||||
#undef LOG_E
|
||||
#define LOG_E(...) MOZ_LOG(mozilla::dom::gFlyWebPublishedServerLog, mozilla::LogLevel::Error, (__VA_ARGS__))
|
||||
|
||||
/******** FlyWebPublishedServer ********/
|
||||
|
||||
FlyWebPublishedServer::FlyWebPublishedServer(nsPIDOMWindowInner* aOwner,
|
||||
const nsAString& aName,
|
||||
const FlyWebPublishOptions& aOptions)
|
||||
: mozilla::DOMEventTargetHelper(aOwner)
|
||||
, mOwnerWindowID(aOwner ? aOwner->WindowID() : 0)
|
||||
, mName(aName)
|
||||
, mUiUrl(aOptions.mUiUrl)
|
||||
, mIsRegistered(true) // Registered by the FlyWebService
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
FlyWebPublishedServer::LastRelease()
|
||||
{
|
||||
// Make sure to unregister to avoid dangling pointers. Use the LastRelease
|
||||
// hook rather than dtor since calling virtual functions during dtor
|
||||
// wouldn't do what we want. Also, LastRelease is called earlier than dtor
|
||||
// for CC objects.
|
||||
Close();
|
||||
}
|
||||
|
||||
JSObject*
|
||||
FlyWebPublishedServer::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return FlyWebPublishedServerBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
void
|
||||
FlyWebPublishedServer::Close()
|
||||
{
|
||||
LOG_I("FlyWebPublishedServer::Close(%p)", this);
|
||||
|
||||
// Unregister from server.
|
||||
if (mIsRegistered) {
|
||||
MOZ_ASSERT(FlyWebService::GetExisting());
|
||||
FlyWebService::GetExisting()->UnregisterServer(this);
|
||||
mIsRegistered = false;
|
||||
|
||||
DispatchTrustedEvent(NS_LITERAL_STRING("close"));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FlyWebPublishedServer::FireFetchEvent(InternalRequest* aRequest)
|
||||
{
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
|
||||
RefPtr<FlyWebFetchEvent> e = new FlyWebFetchEvent(this,
|
||||
new Request(global, aRequest),
|
||||
aRequest);
|
||||
e->Init(this);
|
||||
e->InitEvent(NS_LITERAL_STRING("fetch"), false, false);
|
||||
|
||||
DispatchTrustedEvent(e);
|
||||
}
|
||||
|
||||
void
|
||||
FlyWebPublishedServer::FireWebsocketEvent(InternalRequest* aConnectRequest)
|
||||
{
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
|
||||
RefPtr<FlyWebFetchEvent> e = new FlyWebWebSocketEvent(this,
|
||||
new Request(global, aConnectRequest),
|
||||
aConnectRequest);
|
||||
e->Init(this);
|
||||
e->InitEvent(NS_LITERAL_STRING("websocket"), false, false);
|
||||
|
||||
DispatchTrustedEvent(e);
|
||||
}
|
||||
|
||||
void
|
||||
FlyWebPublishedServer::PublishedServerStarted(nsresult aStatus)
|
||||
{
|
||||
LOG_I("FlyWebPublishedServer::PublishedServerStarted(%p)", this);
|
||||
|
||||
RefPtr<FlyWebPublishPromise> promise = mPublishPromise.Ensure(__func__);
|
||||
if (NS_SUCCEEDED(aStatus)) {
|
||||
mPublishPromise.Resolve(this, __func__);
|
||||
} else {
|
||||
Close();
|
||||
mPublishPromise.Reject(aStatus, __func__);
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<WebSocket>
|
||||
FlyWebPublishedServer::OnWebSocketAccept(InternalRequest* aConnectRequest,
|
||||
const Optional<nsAString>& aProtocol,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aConnectRequest);
|
||||
|
||||
LOG_I("FlyWebPublishedServer::OnWebSocketAccept(%p)", this);
|
||||
|
||||
nsCOMPtr<nsITransportProvider> provider =
|
||||
OnWebSocketAcceptInternal(aConnectRequest,
|
||||
aProtocol,
|
||||
aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
MOZ_ASSERT(provider);
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(GetOwner());
|
||||
AutoJSContext cx;
|
||||
GlobalObject global(cx, nsGlobalWindow::Cast(window)->FastGetGlobalJSObject());
|
||||
|
||||
nsAutoCString extensions, negotiatedExtensions;
|
||||
aConnectRequest->Headers()->
|
||||
GetFirst(NS_LITERAL_CSTRING("Sec-WebSocket-Extensions"), extensions, aRv);
|
||||
mozilla::net::ProcessServerWebSocketExtensions(extensions,
|
||||
negotiatedExtensions);
|
||||
|
||||
nsCString url;
|
||||
aConnectRequest->GetURL(url);
|
||||
Sequence<nsString> protocols;
|
||||
if (aProtocol.WasPassed() &&
|
||||
!protocols.AppendElement(aProtocol.Value(), fallible)) {
|
||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return WebSocket::ConstructorCommon(global,
|
||||
NS_ConvertUTF8toUTF16(url),
|
||||
protocols,
|
||||
provider,
|
||||
negotiatedExtensions,
|
||||
aRv);
|
||||
}
|
||||
|
||||
/******** FlyWebPublishedServerImpl ********/
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(FlyWebPublishedServerImpl, mozilla::DOMEventTargetHelper)
|
||||
|
||||
FlyWebPublishedServerImpl::FlyWebPublishedServerImpl(nsPIDOMWindowInner* aOwner,
|
||||
const nsAString& aName,
|
||||
const FlyWebPublishOptions& aOptions)
|
||||
: FlyWebPublishedServer(aOwner, aName, aOptions)
|
||||
, mHttpServer(new HttpServer())
|
||||
{
|
||||
LOG_I("FlyWebPublishedServerImpl::FlyWebPublishedServerImpl(%p)", this);
|
||||
}
|
||||
|
||||
void
|
||||
FlyWebPublishedServerImpl::PermissionGranted(bool aGranted)
|
||||
{
|
||||
LOG_I("FlyWebPublishedServerImpl::PermissionGranted(%b)", aGranted);
|
||||
if (!aGranted) {
|
||||
PublishedServerStarted(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
mHttpServer->Init(-1, Preferences::GetBool("flyweb.use-tls", false), this);
|
||||
}
|
||||
|
||||
void
|
||||
FlyWebPublishedServerImpl::Close()
|
||||
{
|
||||
FlyWebPublishedServer::Close();
|
||||
|
||||
if (mMDNSCancelRegister) {
|
||||
mMDNSCancelRegister->Cancel(NS_BINDING_ABORTED);
|
||||
mMDNSCancelRegister = nullptr;
|
||||
}
|
||||
|
||||
if (mHttpServer) {
|
||||
RefPtr<HttpServer> server = mHttpServer.forget();
|
||||
server->Close();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FlyWebPublishedServerImpl::OnServerStarted(nsresult aStatus)
|
||||
{
|
||||
if (NS_SUCCEEDED(aStatus)) {
|
||||
FlyWebService::GetOrCreate()->StartDiscoveryOf(this);
|
||||
} else {
|
||||
PublishedServerStarted(aStatus);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FlyWebPublishedServerImpl::OnFetchResponse(InternalRequest* aRequest,
|
||||
InternalResponse* aResponse)
|
||||
{
|
||||
MOZ_ASSERT(aRequest);
|
||||
MOZ_ASSERT(aResponse);
|
||||
|
||||
LOG_I("FlyWebPublishedServerImpl::OnFetchResponse(%p)", this);
|
||||
|
||||
if (mHttpServer) {
|
||||
mHttpServer->SendResponse(aRequest, aResponse);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FlyWebPublishedServerImpl::OnWebSocketResponse(InternalRequest* aConnectRequest,
|
||||
InternalResponse* aResponse)
|
||||
{
|
||||
MOZ_ASSERT(aConnectRequest);
|
||||
MOZ_ASSERT(aResponse);
|
||||
|
||||
LOG_I("FlyWebPublishedMDNSServer::OnWebSocketResponse(%p)", this);
|
||||
|
||||
if (mHttpServer) {
|
||||
mHttpServer->SendWebSocketResponse(aConnectRequest, aResponse);
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<nsITransportProvider>
|
||||
FlyWebPublishedServerImpl::OnWebSocketAcceptInternal(InternalRequest* aConnectRequest,
|
||||
const Optional<nsAString>& aProtocol,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
LOG_I("FlyWebPublishedServerImpl::OnWebSocketAcceptInternal(%p)", this);
|
||||
|
||||
if (!mHttpServer) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return mHttpServer->AcceptWebSocket(aConnectRequest,
|
||||
aProtocol,
|
||||
aRv);
|
||||
}
|
||||
|
||||
/******** FlyWebPublishedServerChild ********/
|
||||
|
||||
FlyWebPublishedServerChild::FlyWebPublishedServerChild(nsPIDOMWindowInner* aOwner,
|
||||
const nsAString& aName,
|
||||
const FlyWebPublishOptions& aOptions)
|
||||
: FlyWebPublishedServer(aOwner, aName, aOptions)
|
||||
, mActorExists(false)
|
||||
{
|
||||
LOG_I("FlyWebPublishedServerChild::FlyWebPublishedServerChild(%p)", this);
|
||||
|
||||
// The matching release happens when the actor is destroyed, in
|
||||
// ContentChild::DeallocPFlyWebPublishedServerChild
|
||||
NS_ADDREF_THIS();
|
||||
}
|
||||
|
||||
void
|
||||
FlyWebPublishedServerChild::PermissionGranted(bool aGranted)
|
||||
{
|
||||
if (!aGranted) {
|
||||
PublishedServerStarted(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
mActorExists = true;
|
||||
FlyWebPublishOptions options;
|
||||
options.mUiUrl = mUiUrl;
|
||||
|
||||
// Proceed with initialization.
|
||||
ContentChild::GetSingleton()->
|
||||
SendPFlyWebPublishedServerConstructor(this, mName, options);
|
||||
}
|
||||
|
||||
bool
|
||||
FlyWebPublishedServerChild::RecvServerReady(const nsresult& aStatus)
|
||||
{
|
||||
LOG_I("FlyWebPublishedServerChild::RecvServerReady(%p)", this);
|
||||
MOZ_ASSERT(mActorExists);
|
||||
|
||||
PublishedServerStarted(aStatus);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
FlyWebPublishedServerChild::RecvServerClose()
|
||||
{
|
||||
LOG_I("FlyWebPublishedServerChild::RecvServerClose(%p)", this);
|
||||
MOZ_ASSERT(mActorExists);
|
||||
|
||||
Close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
FlyWebPublishedServerChild::RecvFetchRequest(const IPCInternalRequest& aRequest,
|
||||
const uint64_t& aRequestId)
|
||||
{
|
||||
LOG_I("FlyWebPublishedServerChild::RecvFetchRequest(%p)", this);
|
||||
MOZ_ASSERT(mActorExists);
|
||||
|
||||
RefPtr<InternalRequest> request = new InternalRequest(aRequest);
|
||||
mPendingRequests.Put(request, aRequestId);
|
||||
FireFetchEvent(request);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
FlyWebPublishedServerChild::RecvWebSocketRequest(const IPCInternalRequest& aRequest,
|
||||
const uint64_t& aRequestId,
|
||||
PTransportProviderChild* aProvider)
|
||||
{
|
||||
LOG_I("FlyWebPublishedServerChild::RecvWebSocketRequest(%p)", this);
|
||||
MOZ_ASSERT(mActorExists);
|
||||
|
||||
RefPtr<InternalRequest> request = new InternalRequest(aRequest);
|
||||
mPendingRequests.Put(request, aRequestId);
|
||||
|
||||
// Not addreffing here. The addref was already done when the
|
||||
// PTransportProvider child constructor original ran.
|
||||
mPendingTransportProviders.Put(aRequestId,
|
||||
dont_AddRef(static_cast<TransportProviderChild*>(aProvider)));
|
||||
|
||||
FireWebsocketEvent(request);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
FlyWebPublishedServerChild::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
LOG_I("FlyWebPublishedServerChild::ActorDestroy(%p)", this);
|
||||
|
||||
mActorExists = false;
|
||||
}
|
||||
|
||||
void
|
||||
FlyWebPublishedServerChild::OnFetchResponse(InternalRequest* aRequest,
|
||||
InternalResponse* aResponse)
|
||||
{
|
||||
LOG_I("FlyWebPublishedServerChild::OnFetchResponse(%p)", this);
|
||||
|
||||
if (!mActorExists) {
|
||||
LOG_I("FlyWebPublishedServerChild::OnFetchResponse(%p) - No actor!", this);
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t id = mPendingRequests.Get(aRequest);
|
||||
MOZ_ASSERT(id);
|
||||
mPendingRequests.Remove(aRequest);
|
||||
|
||||
IPCInternalResponse ipcResp;
|
||||
UniquePtr<mozilla::ipc::AutoIPCStream> autoStream;
|
||||
nsIContentChild* cc = static_cast<ContentChild*>(Manager());
|
||||
aResponse->ToIPC(&ipcResp, cc, autoStream);
|
||||
Unused << SendFetchResponse(ipcResp, id);
|
||||
if (autoStream) {
|
||||
autoStream->TakeOptionalValue();
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<nsITransportProvider>
|
||||
FlyWebPublishedServerChild::OnWebSocketAcceptInternal(InternalRequest* aRequest,
|
||||
const Optional<nsAString>& aProtocol,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
LOG_I("FlyWebPublishedServerChild::OnWebSocketAcceptInternal(%p)", this);
|
||||
|
||||
if (!mActorExists) {
|
||||
LOG_I("FlyWebPublishedServerChild::OnWebSocketAcceptInternal(%p) - No actor!", this);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint64_t id = mPendingRequests.Get(aRequest);
|
||||
MOZ_ASSERT(id);
|
||||
mPendingRequests.Remove(aRequest);
|
||||
|
||||
RefPtr<TransportProviderChild> provider;
|
||||
mPendingTransportProviders.Remove(id, getter_AddRefs(provider));
|
||||
|
||||
nsString protocol;
|
||||
if (aProtocol.WasPassed()) {
|
||||
protocol = aProtocol.Value();
|
||||
|
||||
nsAutoCString reqProtocols;
|
||||
aRequest->Headers()->
|
||||
GetFirst(NS_LITERAL_CSTRING("Sec-WebSocket-Protocol"), reqProtocols, aRv);
|
||||
if (!ContainsToken(reqProtocols, NS_ConvertUTF16toUTF8(protocol))) {
|
||||
// Should throw a better error here
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
protocol.SetIsVoid(true);
|
||||
}
|
||||
|
||||
Unused << SendWebSocketAccept(protocol, id);
|
||||
|
||||
return provider.forget();
|
||||
}
|
||||
|
||||
void
|
||||
FlyWebPublishedServerChild::OnWebSocketResponse(InternalRequest* aRequest,
|
||||
InternalResponse* aResponse)
|
||||
{
|
||||
LOG_I("FlyWebPublishedServerChild::OnFetchResponse(%p)", this);
|
||||
|
||||
if (!mActorExists) {
|
||||
LOG_I("FlyWebPublishedServerChild::OnFetchResponse(%p) - No actor!", this);
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t id = mPendingRequests.Get(aRequest);
|
||||
MOZ_ASSERT(id);
|
||||
mPendingRequests.Remove(aRequest);
|
||||
|
||||
mPendingTransportProviders.Remove(id);
|
||||
|
||||
IPCInternalResponse ipcResp;
|
||||
UniquePtr<mozilla::ipc::AutoIPCStream> autoStream;
|
||||
nsIContentChild* cc = static_cast<ContentChild*>(Manager());
|
||||
aResponse->ToIPC(&ipcResp, cc, autoStream);
|
||||
|
||||
Unused << SendWebSocketResponse(ipcResp, id);
|
||||
if (autoStream) {
|
||||
autoStream->TakeOptionalValue();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FlyWebPublishedServerChild::Close()
|
||||
{
|
||||
LOG_I("FlyWebPublishedServerChild::Close(%p)", this);
|
||||
|
||||
FlyWebPublishedServer::Close();
|
||||
|
||||
if (mActorExists) {
|
||||
LOG_I("FlyWebPublishedServerChild::Close - sending __delete__ (%p)", this);
|
||||
|
||||
Send__delete__(this);
|
||||
}
|
||||
}
|
||||
|
||||
/******** FlyWebPublishedServerParent ********/
|
||||
|
||||
NS_IMPL_ISUPPORTS(FlyWebPublishedServerParent, nsIDOMEventListener)
|
||||
|
||||
FlyWebPublishedServerParent::FlyWebPublishedServerParent(const nsAString& aName,
|
||||
const FlyWebPublishOptions& aOptions)
|
||||
: mActorDestroyed(false)
|
||||
, mNextRequestId(1)
|
||||
{
|
||||
LOG_I("FlyWebPublishedServerParent::FlyWebPublishedServerParent(%p)", this);
|
||||
|
||||
RefPtr<FlyWebService> service = FlyWebService::GetOrCreate();
|
||||
if (!service) {
|
||||
Unused << SendServerReady(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<FlyWebPublishPromise> mozPromise =
|
||||
service->PublishServer(aName, aOptions, nullptr);
|
||||
if (!mozPromise) {
|
||||
Unused << SendServerReady(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<FlyWebPublishedServerParent> self = this;
|
||||
|
||||
mozPromise->Then(
|
||||
AbstractThread::MainThread(),
|
||||
__func__,
|
||||
[this, self] (FlyWebPublishedServer* aServer) {
|
||||
mPublishedServer = static_cast<FlyWebPublishedServerImpl*>(aServer);
|
||||
if (mActorDestroyed) {
|
||||
mPublishedServer->Close();
|
||||
return;
|
||||
}
|
||||
|
||||
mPublishedServer->AddEventListener(NS_LITERAL_STRING("fetch"),
|
||||
this, false, false, 2);
|
||||
mPublishedServer->AddEventListener(NS_LITERAL_STRING("websocket"),
|
||||
this, false, false, 2);
|
||||
mPublishedServer->AddEventListener(NS_LITERAL_STRING("close"),
|
||||
this, false, false, 2);
|
||||
Unused << SendServerReady(NS_OK);
|
||||
},
|
||||
[this, self] (nsresult aStatus) {
|
||||
MOZ_ASSERT(NS_FAILED(aStatus));
|
||||
if (!mActorDestroyed) {
|
||||
Unused << SendServerReady(aStatus);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FlyWebPublishedServerParent::HandleEvent(nsIDOMEvent* aEvent)
|
||||
{
|
||||
if (mActorDestroyed) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoString type;
|
||||
aEvent->GetType(type);
|
||||
if (type.EqualsLiteral("close")) {
|
||||
Unused << SendServerClose();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (type.EqualsLiteral("fetch")) {
|
||||
RefPtr<InternalRequest> request =
|
||||
static_cast<FlyWebFetchEvent*>(aEvent)->Request()->GetInternalRequest();
|
||||
uint64_t id = mNextRequestId++;
|
||||
mPendingRequests.Put(id, request);
|
||||
|
||||
IPCInternalRequest ipcReq;
|
||||
request->ToIPC(&ipcReq);
|
||||
Unused << SendFetchRequest(ipcReq, id);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (type.EqualsLiteral("websocket")) {
|
||||
RefPtr<InternalRequest> request =
|
||||
static_cast<FlyWebWebSocketEvent*>(aEvent)->Request()->GetInternalRequest();
|
||||
uint64_t id = mNextRequestId++;
|
||||
mPendingRequests.Put(id, request);
|
||||
|
||||
nsTArray<PNeckoParent*> neckoParents;
|
||||
Manager()->ManagedPNeckoParent(neckoParents);
|
||||
if (neckoParents.Length() != 1) {
|
||||
MOZ_CRASH("Expected exactly 1 PNeckoParent instance per PNeckoChild");
|
||||
}
|
||||
|
||||
RefPtr<TransportProviderParent> provider =
|
||||
static_cast<TransportProviderParent*>(
|
||||
neckoParents[0]->SendPTransportProviderConstructor());
|
||||
|
||||
IPCInternalRequest ipcReq;
|
||||
request->ToIPC(&ipcReq);
|
||||
Unused << SendWebSocketRequest(ipcReq, id, provider);
|
||||
|
||||
mPendingTransportProviders.Put(id, provider.forget());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MOZ_CRASH("Unknown event type");
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
FlyWebPublishedServerParent::RecvFetchResponse(const IPCInternalResponse& aResponse,
|
||||
const uint64_t& aRequestId)
|
||||
{
|
||||
MOZ_ASSERT(!mActorDestroyed);
|
||||
|
||||
RefPtr<InternalRequest> request;
|
||||
mPendingRequests.Remove(aRequestId, getter_AddRefs(request));
|
||||
if (!request) {
|
||||
static_cast<ContentParent*>(Manager())->KillHard("unknown request id");
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<InternalResponse> response = InternalResponse::FromIPC(aResponse);
|
||||
|
||||
mPublishedServer->OnFetchResponse(request, response);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
FlyWebPublishedServerParent::RecvWebSocketResponse(const IPCInternalResponse& aResponse,
|
||||
const uint64_t& aRequestId)
|
||||
{
|
||||
MOZ_ASSERT(!mActorDestroyed);
|
||||
|
||||
mPendingTransportProviders.Remove(aRequestId);
|
||||
|
||||
RefPtr<InternalRequest> request;
|
||||
mPendingRequests.Remove(aRequestId, getter_AddRefs(request));
|
||||
if (!request) {
|
||||
static_cast<ContentParent*>(Manager())->KillHard("unknown websocket request id");
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<InternalResponse> response = InternalResponse::FromIPC(aResponse);
|
||||
|
||||
mPublishedServer->OnWebSocketResponse(request, response);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
FlyWebPublishedServerParent::RecvWebSocketAccept(const nsString& aProtocol,
|
||||
const uint64_t& aRequestId)
|
||||
{
|
||||
MOZ_ASSERT(!mActorDestroyed);
|
||||
|
||||
RefPtr<TransportProviderParent> providerIPC;
|
||||
mPendingTransportProviders.Remove(aRequestId, getter_AddRefs(providerIPC));
|
||||
|
||||
RefPtr<InternalRequest> request;
|
||||
mPendingRequests.Remove(aRequestId, getter_AddRefs(request));
|
||||
|
||||
if (!request || !providerIPC) {
|
||||
static_cast<ContentParent*>(Manager())->KillHard("unknown websocket request id");
|
||||
return false;
|
||||
}
|
||||
|
||||
Optional<nsAString> protocol;
|
||||
if (!aProtocol.IsVoid()) {
|
||||
protocol = &aProtocol;
|
||||
}
|
||||
|
||||
ErrorResult result;
|
||||
nsCOMPtr<nsITransportProvider> providerServer =
|
||||
mPublishedServer->OnWebSocketAcceptInternal(request, protocol, result);
|
||||
if (result.Failed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
providerServer->SetListener(providerIPC);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
FlyWebPublishedServerParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
LOG_I("FlyWebPublishedServerParent::ActorDestroy(%p)", this);
|
||||
|
||||
mActorDestroyed = true;
|
||||
}
|
||||
|
||||
bool
|
||||
FlyWebPublishedServerParent::Recv__delete__()
|
||||
{
|
||||
LOG_I("FlyWebPublishedServerParent::Recv__delete__(%p)", this);
|
||||
MOZ_ASSERT(!mActorDestroyed);
|
||||
|
||||
if (mPublishedServer) {
|
||||
mPublishedServer->RemoveEventListener(NS_LITERAL_STRING("fetch"),
|
||||
this, false);
|
||||
mPublishedServer->RemoveEventListener(NS_LITERAL_STRING("websocket"),
|
||||
this, false);
|
||||
mPublishedServer->RemoveEventListener(NS_LITERAL_STRING("close"),
|
||||
this, false);
|
||||
mPublishedServer->Close();
|
||||
mPublishedServer = nullptr;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_FlyWebPublishedServer_h
|
||||
#define mozilla_dom_FlyWebPublishedServer_h
|
||||
|
||||
#include "mozilla/DOMEventTargetHelper.h"
|
||||
#include "mozilla/MozPromise.h"
|
||||
|
||||
class nsPIDOMWindowInner;
|
||||
class nsITransportProvider;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class ErrorResult;
|
||||
|
||||
namespace dom {
|
||||
|
||||
class InternalResponse;
|
||||
class InternalRequest;
|
||||
class WebSocket;
|
||||
struct FlyWebPublishOptions;
|
||||
class FlyWebPublishedServer;
|
||||
|
||||
typedef MozPromise<RefPtr<FlyWebPublishedServer>, nsresult, false>
|
||||
FlyWebPublishPromise;
|
||||
|
||||
class FlyWebPublishedServer : public mozilla::DOMEventTargetHelper
|
||||
{
|
||||
public:
|
||||
FlyWebPublishedServer(nsPIDOMWindowInner* aOwner,
|
||||
const nsAString& aName,
|
||||
const FlyWebPublishOptions& aOptions);
|
||||
|
||||
virtual void LastRelease() override;
|
||||
|
||||
virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
uint64_t OwnerWindowID() const {
|
||||
return mOwnerWindowID;
|
||||
}
|
||||
|
||||
void GetName(nsAString& aName)
|
||||
{
|
||||
aName = mName;
|
||||
}
|
||||
nsAString& Name()
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
|
||||
void GetUiUrl(nsAString& aUiUrl)
|
||||
{
|
||||
aUiUrl = mUiUrl;
|
||||
}
|
||||
|
||||
virtual void PermissionGranted(bool aGranted) = 0;
|
||||
|
||||
virtual void OnFetchResponse(InternalRequest* aRequest,
|
||||
InternalResponse* aResponse) = 0;
|
||||
already_AddRefed<WebSocket>
|
||||
OnWebSocketAccept(InternalRequest* aConnectRequest,
|
||||
const Optional<nsAString>& aProtocol,
|
||||
ErrorResult& aRv);
|
||||
virtual void OnWebSocketResponse(InternalRequest* aConnectRequest,
|
||||
InternalResponse* aResponse) = 0;
|
||||
virtual already_AddRefed<nsITransportProvider>
|
||||
OnWebSocketAcceptInternal(InternalRequest* aConnectRequest,
|
||||
const Optional<nsAString>& aProtocol,
|
||||
ErrorResult& aRv) = 0;
|
||||
|
||||
virtual void Close();
|
||||
|
||||
void FireFetchEvent(InternalRequest* aRequest);
|
||||
void FireWebsocketEvent(InternalRequest* aConnectRequest);
|
||||
void PublishedServerStarted(nsresult aStatus);
|
||||
|
||||
IMPL_EVENT_HANDLER(fetch)
|
||||
IMPL_EVENT_HANDLER(websocket)
|
||||
IMPL_EVENT_HANDLER(close)
|
||||
|
||||
already_AddRefed<FlyWebPublishPromise>
|
||||
GetPublishPromise()
|
||||
{
|
||||
return mPublishPromise.Ensure(__func__);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~FlyWebPublishedServer()
|
||||
{
|
||||
MOZ_ASSERT(!mIsRegistered, "Subclass dtor forgot to call Close()");
|
||||
}
|
||||
|
||||
uint64_t mOwnerWindowID;
|
||||
MozPromiseHolder<FlyWebPublishPromise> mPublishPromise;
|
||||
|
||||
nsString mName;
|
||||
nsString mUiUrl;
|
||||
|
||||
bool mIsRegistered;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_FlyWebPublishedServer_h
|
||||
@@ -1,172 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_FlyWebPublishedServerIPC_h
|
||||
#define mozilla_dom_FlyWebPublishedServerIPC_h
|
||||
|
||||
#include "HttpServer.h"
|
||||
#include "mozilla/dom/FlyWebPublishedServer.h"
|
||||
#include "mozilla/dom/PFlyWebPublishedServerParent.h"
|
||||
#include "mozilla/dom/PFlyWebPublishedServerChild.h"
|
||||
#include "mozilla/MozPromise.h"
|
||||
#include "nsICancelable.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
|
||||
class nsPIDOMWindowInner;
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
class TransportProviderParent;
|
||||
class TransportProviderChild;
|
||||
}
|
||||
|
||||
namespace dom {
|
||||
|
||||
class FlyWebPublishedServerParent;
|
||||
|
||||
class FlyWebPublishedServerImpl final : public FlyWebPublishedServer
|
||||
, public HttpServerListener
|
||||
{
|
||||
public:
|
||||
FlyWebPublishedServerImpl(nsPIDOMWindowInner* aOwner,
|
||||
const nsAString& aName,
|
||||
const FlyWebPublishOptions& aOptions);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
int32_t Port()
|
||||
{
|
||||
return mHttpServer ? mHttpServer->GetPort() : 0;
|
||||
}
|
||||
void GetCertKey(nsACString& aKey) {
|
||||
if (mHttpServer) {
|
||||
mHttpServer->GetCertKey(aKey);
|
||||
} else {
|
||||
aKey.Truncate();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void PermissionGranted(bool aGranted) override;
|
||||
virtual void OnFetchResponse(InternalRequest* aRequest,
|
||||
InternalResponse* aResponse) override;
|
||||
virtual void OnWebSocketResponse(InternalRequest* aConnectRequest,
|
||||
InternalResponse* aResponse) override;
|
||||
virtual already_AddRefed<nsITransportProvider>
|
||||
OnWebSocketAcceptInternal(InternalRequest* aConnectRequest,
|
||||
const Optional<nsAString>& aProtocol,
|
||||
ErrorResult& aRv) override;
|
||||
|
||||
void SetCancelRegister(nsICancelable* aCancelRegister)
|
||||
{
|
||||
mMDNSCancelRegister = aCancelRegister;
|
||||
}
|
||||
|
||||
virtual void Close() override;
|
||||
|
||||
// HttpServerListener
|
||||
virtual void OnServerStarted(nsresult aStatus) override;
|
||||
virtual void OnRequest(InternalRequest* aRequest) override
|
||||
{
|
||||
FireFetchEvent(aRequest);
|
||||
}
|
||||
virtual void OnWebSocket(InternalRequest* aConnectRequest) override
|
||||
{
|
||||
FireWebsocketEvent(aConnectRequest);
|
||||
}
|
||||
virtual void OnServerClose() override
|
||||
{
|
||||
mHttpServer = nullptr;
|
||||
Close();
|
||||
}
|
||||
|
||||
private:
|
||||
~FlyWebPublishedServerImpl() {}
|
||||
|
||||
RefPtr<HttpServer> mHttpServer;
|
||||
nsCOMPtr<nsICancelable> mMDNSCancelRegister;
|
||||
RefPtr<FlyWebPublishedServerParent> mServerParent;
|
||||
};
|
||||
|
||||
class FlyWebPublishedServerChild final : public FlyWebPublishedServer
|
||||
, public PFlyWebPublishedServerChild
|
||||
{
|
||||
public:
|
||||
FlyWebPublishedServerChild(nsPIDOMWindowInner* aOwner,
|
||||
const nsAString& aName,
|
||||
const FlyWebPublishOptions& aOptions);
|
||||
|
||||
virtual void PermissionGranted(bool aGranted) override;
|
||||
virtual bool RecvServerReady(const nsresult& aStatus) override;
|
||||
virtual bool RecvServerClose() override;
|
||||
virtual bool RecvFetchRequest(const IPCInternalRequest& aRequest,
|
||||
const uint64_t& aRequestId) override;
|
||||
virtual bool RecvWebSocketRequest(const IPCInternalRequest& aRequest,
|
||||
const uint64_t& aRequestId,
|
||||
PTransportProviderChild* aProvider) override;
|
||||
|
||||
virtual void OnFetchResponse(InternalRequest* aRequest,
|
||||
InternalResponse* aResponse) override;
|
||||
virtual void OnWebSocketResponse(InternalRequest* aConnectRequest,
|
||||
InternalResponse* aResponse) override;
|
||||
virtual already_AddRefed<nsITransportProvider>
|
||||
OnWebSocketAcceptInternal(InternalRequest* aConnectRequest,
|
||||
const Optional<nsAString>& aProtocol,
|
||||
ErrorResult& aRv) override;
|
||||
|
||||
virtual void Close() override;
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
private:
|
||||
~FlyWebPublishedServerChild() {}
|
||||
|
||||
nsDataHashtable<nsRefPtrHashKey<InternalRequest>, uint64_t> mPendingRequests;
|
||||
nsRefPtrHashtable<nsUint64HashKey, TransportProviderChild>
|
||||
mPendingTransportProviders;
|
||||
bool mActorExists;
|
||||
};
|
||||
|
||||
class FlyWebPublishedServerParent final : public PFlyWebPublishedServerParent
|
||||
, public nsIDOMEventListener
|
||||
{
|
||||
public:
|
||||
FlyWebPublishedServerParent(const nsAString& aName,
|
||||
const FlyWebPublishOptions& aOptions);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDOMEVENTLISTENER
|
||||
|
||||
private:
|
||||
virtual void
|
||||
ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
virtual bool
|
||||
Recv__delete__() override;
|
||||
virtual bool
|
||||
RecvFetchResponse(const IPCInternalResponse& aResponse,
|
||||
const uint64_t& aRequestId) override;
|
||||
virtual bool
|
||||
RecvWebSocketResponse(const IPCInternalResponse& aResponse,
|
||||
const uint64_t& aRequestId) override;
|
||||
virtual bool
|
||||
RecvWebSocketAccept(const nsString& aProtocol,
|
||||
const uint64_t& aRequestId) override;
|
||||
|
||||
~FlyWebPublishedServerParent() {}
|
||||
|
||||
bool mActorDestroyed;
|
||||
uint64_t mNextRequestId;
|
||||
nsRefPtrHashtable<nsUint64HashKey, InternalRequest> mPendingRequests;
|
||||
nsRefPtrHashtable<nsUint64HashKey, TransportProviderParent>
|
||||
mPendingTransportProviders;
|
||||
RefPtr<FlyWebPublishedServerImpl> mPublishedServer;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_FlyWebPublishedServerIPC_h
|
||||
@@ -1,141 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/EventBinding.h"
|
||||
#include "mozilla/dom/FlyWebFetchEventBinding.h"
|
||||
#include "mozilla/dom/FlyWebPublishedServer.h"
|
||||
#include "mozilla/dom/FlyWebServerEvents.h"
|
||||
#include "mozilla/dom/FlyWebWebSocketEventBinding.h"
|
||||
#include "mozilla/dom/Nullable.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/Response.h"
|
||||
|
||||
#include "js/GCAPI.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(FlyWebFetchEvent)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(FlyWebFetchEvent, Event)
|
||||
NS_IMPL_RELEASE_INHERITED(FlyWebFetchEvent, Event)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(FlyWebFetchEvent, Event)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRequest)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(FlyWebFetchEvent, Event)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(FlyWebFetchEvent, Event)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mRequest)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(FlyWebFetchEvent)
|
||||
NS_INTERFACE_MAP_END_INHERITING(Event)
|
||||
|
||||
FlyWebFetchEvent::FlyWebFetchEvent(FlyWebPublishedServer* aServer,
|
||||
class Request* aRequest,
|
||||
InternalRequest* aInternalRequest)
|
||||
: Event(aServer, nullptr, nullptr)
|
||||
, mRequest(aRequest)
|
||||
, mInternalRequest(aInternalRequest)
|
||||
, mServer(aServer)
|
||||
, mResponded(false)
|
||||
{
|
||||
MOZ_ASSERT(aServer);
|
||||
MOZ_ASSERT(aRequest);
|
||||
MOZ_ASSERT(aInternalRequest);
|
||||
}
|
||||
|
||||
FlyWebFetchEvent::~FlyWebFetchEvent()
|
||||
{
|
||||
}
|
||||
|
||||
JSObject*
|
||||
FlyWebFetchEvent::WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return FlyWebFetchEventBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
void
|
||||
FlyWebFetchEvent::RespondWith(Promise& aArg, ErrorResult& aRv)
|
||||
{
|
||||
if (mResponded) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
mResponded = true;
|
||||
|
||||
aArg.AppendNativeHandler(this);
|
||||
}
|
||||
|
||||
void
|
||||
FlyWebFetchEvent::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
|
||||
{
|
||||
RefPtr<Response> response;
|
||||
if (aValue.isObject()) {
|
||||
UNWRAP_OBJECT(Response, &aValue.toObject(), response);
|
||||
}
|
||||
|
||||
RefPtr<InternalResponse> intResponse;
|
||||
if (response && response->Type() != ResponseType::Opaque) {
|
||||
intResponse = response->GetInternalResponse();
|
||||
}
|
||||
|
||||
if (!intResponse) {
|
||||
intResponse = InternalResponse::NetworkError();
|
||||
}
|
||||
|
||||
NotifyServer(intResponse);
|
||||
}
|
||||
|
||||
void
|
||||
FlyWebFetchEvent::NotifyServer(InternalResponse* aResponse)
|
||||
{
|
||||
mServer->OnFetchResponse(mInternalRequest, aResponse);
|
||||
}
|
||||
|
||||
void
|
||||
FlyWebFetchEvent::RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
|
||||
{
|
||||
RefPtr<InternalResponse> err = InternalResponse::NetworkError();
|
||||
|
||||
NotifyServer(err);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
FlyWebWebSocketEvent::WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return FlyWebWebSocketEventBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
already_AddRefed<WebSocket>
|
||||
FlyWebWebSocketEvent::Accept(const Optional<nsAString>& aProtocol,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (mResponded) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mResponded = true;
|
||||
|
||||
return mServer->OnWebSocketAccept(mInternalRequest, aProtocol, aRv);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FlyWebWebSocketEvent::NotifyServer(InternalResponse* aResponse)
|
||||
{
|
||||
mServer->OnWebSocketResponse(mInternalRequest, aResponse);
|
||||
}
|
||||
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
@@ -1,88 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_FlyWebFetchEvent_h
|
||||
#define mozilla_dom_FlyWebFetchEvent_h
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/Event.h"
|
||||
#include "mozilla/dom/FlyWebFetchEventBinding.h"
|
||||
#include "mozilla/dom/PromiseNativeHandler.h"
|
||||
#include "mozilla/dom/WebSocket.h"
|
||||
|
||||
struct JSContext;
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class Request;
|
||||
class Response;
|
||||
class FlyWebPublishedServer;
|
||||
class InternalRequest;
|
||||
class InternalResponse;
|
||||
|
||||
class FlyWebFetchEvent : public Event
|
||||
, public PromiseNativeHandler
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(FlyWebFetchEvent, Event)
|
||||
|
||||
virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
virtual void
|
||||
ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override;
|
||||
virtual void
|
||||
RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override;
|
||||
|
||||
class Request* Request() const
|
||||
{
|
||||
return mRequest;
|
||||
}
|
||||
|
||||
void RespondWith(Promise& aArg, ErrorResult& aRv);
|
||||
|
||||
FlyWebFetchEvent(FlyWebPublishedServer* aServer,
|
||||
class Request* aRequest,
|
||||
InternalRequest* aInternalRequest);
|
||||
|
||||
protected:
|
||||
virtual ~FlyWebFetchEvent();
|
||||
|
||||
virtual void NotifyServer(InternalResponse* aResponse);
|
||||
|
||||
RefPtr<class Request> mRequest;
|
||||
RefPtr<InternalRequest> mInternalRequest;
|
||||
RefPtr<FlyWebPublishedServer> mServer;
|
||||
|
||||
bool mResponded;
|
||||
};
|
||||
|
||||
class FlyWebWebSocketEvent final : public FlyWebFetchEvent
|
||||
{
|
||||
public:
|
||||
FlyWebWebSocketEvent(FlyWebPublishedServer* aServer,
|
||||
class Request* aRequest,
|
||||
InternalRequest* aInternalRequest)
|
||||
: FlyWebFetchEvent(aServer, aRequest, aInternalRequest)
|
||||
{}
|
||||
|
||||
virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
already_AddRefed<WebSocket> Accept(const Optional<nsAString>& aProtocol,
|
||||
ErrorResult& aRv);
|
||||
|
||||
private:
|
||||
~FlyWebWebSocketEvent() {};
|
||||
|
||||
virtual void NotifyServer(InternalResponse* aResponse) override;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_FlyWebFetchEvent_h
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,113 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_FlyWebService_h
|
||||
#define mozilla_dom_FlyWebService_h
|
||||
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "nsIProtocolHandler.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "mozilla/MozPromise.h"
|
||||
#include "mozilla/ReentrantMonitor.h"
|
||||
#include "mozilla/dom/FlyWebDiscoveryManagerBinding.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsICancelable.h"
|
||||
#include "nsIDNSServiceDiscovery.h"
|
||||
|
||||
class nsPIDOMWindowInner;
|
||||
class nsIProxyInfo;
|
||||
class nsISocketTransport;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
struct FlyWebPublishOptions;
|
||||
struct FlyWebFilter;
|
||||
class FlyWebPublishedServer;
|
||||
class FlyWebPublishedServerImpl;
|
||||
class FlyWebPairingCallback;
|
||||
class FlyWebDiscoveryManager;
|
||||
class FlyWebMDNSService;
|
||||
|
||||
typedef MozPromise<RefPtr<FlyWebPublishedServer>, nsresult, false>
|
||||
FlyWebPublishPromise;
|
||||
|
||||
class FlyWebService final : public nsIObserver
|
||||
{
|
||||
friend class FlyWebMDNSService;
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
static FlyWebService* GetExisting();
|
||||
static FlyWebService* GetOrCreate();
|
||||
static already_AddRefed<FlyWebService> GetOrCreateAddRefed()
|
||||
{
|
||||
return do_AddRef(GetOrCreate());
|
||||
}
|
||||
|
||||
already_AddRefed<FlyWebPublishPromise>
|
||||
PublishServer(const nsAString& aName,
|
||||
const FlyWebPublishOptions& aOptions,
|
||||
nsPIDOMWindowInner* aWindow);
|
||||
|
||||
void UnregisterServer(FlyWebPublishedServer* aServer);
|
||||
|
||||
bool HasConnectionOrServer(uint64_t aWindowID);
|
||||
|
||||
void ListDiscoveredServices(nsTArray<FlyWebDiscoveredService>& aServices);
|
||||
void PairWithService(const nsAString& aServiceId, FlyWebPairingCallback& aCallback);
|
||||
nsresult CreateTransportForHost(const char **types,
|
||||
uint32_t typeCount,
|
||||
const nsACString &host,
|
||||
int32_t port,
|
||||
const nsACString &hostRoute,
|
||||
int32_t portRoute,
|
||||
nsIProxyInfo *proxyInfo,
|
||||
nsISocketTransport **result);
|
||||
|
||||
already_AddRefed<FlyWebPublishedServer> FindPublishedServerByName(
|
||||
const nsAString& aName);
|
||||
|
||||
void RegisterDiscoveryManager(FlyWebDiscoveryManager* aDiscoveryManager);
|
||||
void UnregisterDiscoveryManager(FlyWebDiscoveryManager* aDiscoveryManager);
|
||||
|
||||
// Should only be called by FlyWebPublishedServerImpl
|
||||
void StartDiscoveryOf(FlyWebPublishedServerImpl* aServer);
|
||||
|
||||
private:
|
||||
FlyWebService();
|
||||
~FlyWebService();
|
||||
|
||||
ErrorResult Init();
|
||||
|
||||
void NotifyDiscoveredServicesChanged();
|
||||
|
||||
// Might want to make these hashes for perf
|
||||
nsTArray<FlyWebPublishedServer*> mServers;
|
||||
|
||||
RefPtr<FlyWebMDNSService> mMDNSHttpService;
|
||||
RefPtr<FlyWebMDNSService> mMDNSFlywebService;
|
||||
|
||||
struct PairedInfo
|
||||
{
|
||||
FlyWebPairedService mService;
|
||||
nsCOMPtr<nsIDNSServiceInfo> mDNSServiceInfo;
|
||||
};
|
||||
nsClassHashtable<nsCStringHashKey, PairedInfo>
|
||||
mPairedServiceTable;
|
||||
ReentrantMonitor mMonitor; // Protecting mPairedServiceTable
|
||||
|
||||
nsTHashtable<nsPtrHashKey<FlyWebDiscoveryManager>> mDiscoveryManagerTable;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_FlyWebService_h
|
||||
Loaded 100 of 3689 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user