Merge mozilla-central to fx-team

This commit is contained in:
Carsten "Tomcat" Book 2014-05-28 15:29:24 +02:00
commit 5b8d5f6fa8
202 changed files with 5547 additions and 2162 deletions

View File

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Bug 994964 apparently requires a clobber, unclear why
Bug 999651 et al. apparently require a clobber, unclear why

View File

@ -429,6 +429,9 @@ HyperTextAccessible::FindOffset(uint32_t aOffset, nsDirection aDirection,
nsSelectionAmount aAmount,
EWordMovementType aWordMovementType)
{
NS_ASSERTION(aDirection == eDirPrevious || aAmount != eSelectBeginLine,
"eSelectBeginLine should only be used with eDirPrevious");
// Find a leaf accessible frame to start with. PeekOffset wants this.
HyperTextAccessible* text = this;
Accessible* child = nullptr;
@ -447,22 +450,32 @@ HyperTextAccessible::FindOffset(uint32_t aOffset, nsDirection aDirection,
if (text->IsHTMLListItem()) {
HTMLLIAccessible* li = text->AsHTMLListItem();
if (child == li->Bullet()) {
// It works only when the bullet is one single char.
if (aDirection == eDirPrevious)
return text != this ? TransformOffset(text, 0, false) : 0;
if (aAmount == eSelectEndLine || aAmount == eSelectLine) {
if (text != this)
return TransformOffset(text, 1, true);
// Ask a text leaf next (if not empty) to the bullet for an offset
// since list item may be multiline.
return aOffset + 1 < CharacterCount() ?
FindOffset(aOffset + 1, aDirection, aAmount, aWordMovementType) : 1;
// XXX: the logic is broken for multichar bullets in moving by
// char/cluster/word cases.
if (text != this) {
return aDirection == eDirPrevious ?
TransformOffset(text, 0, false) :
TransformOffset(text, 1, true);
}
if (aDirection == eDirPrevious)
return 0;
// Case of word and char boundaries.
return text != this ? TransformOffset(text, 1, true) : 1;
uint32_t nextOffset = GetChildOffset(1);
if (nextOffset == 0)
return 0;
switch (aAmount) {
case eSelectLine:
case eSelectEndLine:
// Ask a text leaf next (if not empty) to the bullet for an offset
// since list item may be multiline.
return nextOffset < CharacterCount() ?
FindOffset(nextOffset, aDirection, aAmount, aWordMovementType) :
nextOffset;
default:
return nextOffset;
}
}
}
@ -521,8 +534,12 @@ HyperTextAccessible::FindOffset(uint32_t aOffset, nsDirection aDirection,
return 0;
// PeekOffset stops right before bullet so return 0 to workaround it.
if (IsHTMLListItem() && aAmount == eSelectBeginLine && hyperTextOffset == 1)
return 0;
if (IsHTMLListItem() && aAmount == eSelectBeginLine &&
hyperTextOffset > 0) {
Accessible* prevOffsetChild = GetChildAtOffset(hyperTextOffset - 1);
if (prevOffsetChild == AsHTMLListItem()->Bullet())
return 0;
}
}
return hyperTextOffset;

View File

@ -126,11 +126,34 @@
[ 8, 11, "and ", 8, 12 ] ]);
testTextAtOffset([ "li4" ], BOUNDARY_LINE_START,
[ [ 0, 6, kDiscBulletChar + "a " + kEmbedChar + " c", 0, 6 ] ]);
testTextAtOffset([ "li5" ], BOUNDARY_LINE_START,
[ [ 0, 1, kDiscBulletChar + "\n", 0, 2 ],
[ 2, 6, "hello", 2, 7 ] ]);
testTextAtOffset([ "ul1" ], BOUNDARY_LINE_START,
[ [ 0, 0, kEmbedChar, 0, 1 ],
[ 1, 1, kEmbedChar, 1, 2 ],
[ 2, 2, kEmbedChar, 2, 3 ],
[ 3, 4, kEmbedChar, 3, 4 ] ]);
[ 3, 3, kEmbedChar, 3, 4 ],
[ 4, 5, kEmbedChar, 4, 5 ] ]);
testTextAtOffset([ "li6" ], BOUNDARY_LINE_START,
[ [ 0, 6, "1.Item", 0, 6 ] ]);
testTextAtOffset([ "li7" ], BOUNDARY_LINE_START,
[ [ 0, 2, "2.", 0, 2 ] ]);
testTextAtOffset([ "li8" ], BOUNDARY_LINE_START,
[ [ 0, 8, "3.a long ", 0, 9 ],
[ 9, 12, "and ", 9, 13 ] ]);
testTextAtOffset([ "li9" ], BOUNDARY_LINE_START,
[ [ 0, 7, "4.a " + kEmbedChar + " c", 0, 7 ] ]);
testTextAtOffset([ "li10" ], BOUNDARY_LINE_START,
[ [ 0, 2, "5.\n", 0, 3 ],
[ 3, 7, "hello", 3, 8 ] ]);
testTextAtOffset([ "ol1" ], BOUNDARY_LINE_START,
[ [ 0, 0, kEmbedChar, 0, 1 ],
[ 1, 1, kEmbedChar, 1, 2 ],
[ 2, 2, kEmbedChar, 2, 3 ],
[ 3, 3, kEmbedChar, 3, 4 ],
[ 4, 5, kEmbedChar, 4, 5 ] ]);
//////////////////////////////////////////////////////////////////////////
// Nested hypertexts
@ -210,8 +233,17 @@ two words
<li id="li2"></li>
<li id="li3" style="width:10ex; font-family:monospace; font-size:10pt;">a long and winding road that lead me to your door</li>
<li id="li4">a <a href=''>b</a> c</li>
<li id="li5"><br>hello</li>
</ul>
<ol id="ol1">
<li id="li6">Item</li>
<li id="li7"></li>
<li id="li8" style="width:10ex; font-family:monospace; font-size:10pt;">a long and winding road that lead me to your door</li>
<li id="li9">a <a href=''>b</a> c</li>
<li id="li10"><br>hello</li>
</ol>
<div id="ht_5">
<div>
<p>sectiounus</p>

View File

@ -78,14 +78,12 @@ SettingsListener.observe('language.current', 'en-US', function(value) {
Services.prefs.setCharPref('general.useragent.locale', value);
let prefName = 'intl.accept_languages';
if (Services.prefs.prefHasUserValue(prefName)) {
Services.prefs.clearUserPref(prefName);
}
let defaultBranch = Services.prefs.getDefaultBranch(null);
let intl = '';
try {
intl = Services.prefs.getComplexValue(prefName,
Ci.nsIPrefLocalizedString).data;
intl = defaultBranch.getComplexValue(prefName,
Ci.nsIPrefLocalizedString).data;
} catch(e) {}
// Bug 830782 - Homescreen is in English instead of selected locale after
@ -474,6 +472,13 @@ SettingsListener.observe('debugger.remote-mode', false, function(value) {
#endif
});
// If debug access to certified apps is allowed, we need to preserve system
// sources so that they are visible in the debugger.
let forbidCertified =
Services.prefs.getBoolPref('devtools.debugger.forbid-certified-apps');
Services.prefs.setBoolPref('javascript.options.discardSystemSource',
forbidCertified);
// =================== Device Storage ====================
SettingsListener.observe('device.storage.writable.name', 'sdcard', function(value) {
if (Services.prefs.getPrefType('device.storage.writable.name') != Ci.nsIPrefBranch.PREF_STRING) {

View File

@ -19,13 +19,13 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="bc6f07c149770c6e6dfbea941ac65138dc364a15"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="389dee3293891002f825ea1d5d92283094b7d931"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="87ee480405c4a109c01f68dd64de625f1ff819d9"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="ca283b9db2b151d465cfd2e19346cf58fe89e413"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="5688c04e38ceacb9069b6157db69b37beafab331"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="df6b6315b7217522ae03151449a841f0c382c888"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ef8e1c9128ee14189263382788a7b6b06353a6e8"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
<project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>

View File

@ -17,10 +17,10 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="bc6f07c149770c6e6dfbea941ac65138dc364a15"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="389dee3293891002f825ea1d5d92283094b7d931"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="87ee480405c4a109c01f68dd64de625f1ff819d9"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="df6b6315b7217522ae03151449a841f0c382c888"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ef8e1c9128ee14189263382788a7b6b06353a6e8"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->
@ -128,9 +128,9 @@
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="3a9a17613cc685aa232432566ad6cc607eab4ec1"/>
<project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="c3ee0c875393607430086f942950d1b3f496ab0e"/>
<project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="7d33aaf740bbf6c7c6e9c34a92b371eda311b66b"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="acbdbe5196f06589da05c3bd1f14b27a6cae69c2"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="02f0cc39345c36689ea4bca436b789b38f5751e0"/>
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="dd94b2e17a146cb782d71933d25dcaa9c060e6ce"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="56e7fe044cb6a0ad689b96ad7a3636d65e769b34"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="ea8011252172347bd7711f6fc9c5cc24ab1a109b"/>
<project name="android-sdk" path="sdk" remote="b2g" revision="8b1365af38c9a653df97349ee53a3f5d64fd590a"/>
</manifest>

View File

@ -15,14 +15,14 @@
<project name="platform_build" path="build" remote="b2g" revision="276ce45e78b09c4a4ee643646f691d22804754c1">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="bc6f07c149770c6e6dfbea941ac65138dc364a15"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="389dee3293891002f825ea1d5d92283094b7d931"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="87ee480405c4a109c01f68dd64de625f1ff819d9"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="df6b6315b7217522ae03151449a841f0c382c888"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ef8e1c9128ee14189263382788a7b6b06353a6e8"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/>

View File

@ -19,13 +19,13 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="bc6f07c149770c6e6dfbea941ac65138dc364a15"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="389dee3293891002f825ea1d5d92283094b7d931"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="87ee480405c4a109c01f68dd64de625f1ff819d9"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="ca283b9db2b151d465cfd2e19346cf58fe89e413"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="5688c04e38ceacb9069b6157db69b37beafab331"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="df6b6315b7217522ae03151449a841f0c382c888"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ef8e1c9128ee14189263382788a7b6b06353a6e8"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
<project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>

View File

@ -15,13 +15,12 @@
<project name="platform_build" path="build" remote="b2g" revision="42c224f4304c10166739fd9e25b2db1036410bd8">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="bc6f07c149770c6e6dfbea941ac65138dc364a15"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="389dee3293891002f825ea1d5d92283094b7d931"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="87ee480405c4a109c01f68dd64de625f1ff819d9"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="df6b6315b7217522ae03151449a841f0c382c888"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ef8e1c9128ee14189263382788a7b6b06353a6e8"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->
@ -119,7 +118,7 @@
<!-- Flame specific things -->
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="e8a318f7690092e639ba88891606f4183e846d3f"/>
<project name="device/qcom/common" path="device/qcom/common" revision="34ed8345250bb97262d70a052217a92e83444ede"/>
<project name="device-flame" path="device/t2m/flame" remote="b2g" revision="b99bd353c9a1e292a21e686f2d6b35aafa1d06ca"/>
<project name="device-flame" path="device/t2m/flame" remote="b2g" revision="81eab0894a773fc0274b64432f1f49da95d63b7d"/>
<project name="kernel/msm" path="kernel" revision="228d59147ff524e90774c566eef03260cc6857b8"/>
<project name="platform/bootable/recovery" path="bootable/recovery" revision="f2914eacee9120680a41463708bb6ee8291749fc"/>
<project name="platform/external/bluetooth/bluedroid" path="external/bluetooth/bluedroid" revision="81c4a859d75d413ad688067829d21b7ba9205f81"/>
@ -141,7 +140,7 @@
<project name="platform/hardware/ril" path="hardware/ril" revision="c4e2ac95907a5519a0e09f01a0d8e27fec101af0"/>
<project name="platform/system/bluetooth" path="system/bluetooth" revision="e1eb226fa3ad3874ea7b63c56a9dc7012d7ff3c2"/>
<project name="platform/system/core" path="system/core" revision="bbf7212289fc8311e43f9d11e10788e310d36a08"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="56e7fe044cb6a0ad689b96ad7a3636d65e769b34"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="ea8011252172347bd7711f6fc9c5cc24ab1a109b"/>
<project name="platform/system/qcom" path="system/qcom" revision="1cdab258b15258b7f9657da70e6f06ebd5a2fc25"/>
<project name="platform/vendor/qcom/msm8610" path="device/qcom/msm8610" revision="4ae5df252123591d5b941191790e7abed1bce5a4"/>
</manifest>

View File

@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
"revision": "a9c51a635e985bfa1a1448101e9763dd35426dfa",
"revision": "f2274c0c94a989a204b03b693c73ed1414b0f543",
"repo_path": "/integration/gaia-central"
}

View File

@ -17,12 +17,12 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="bc6f07c149770c6e6dfbea941ac65138dc364a15"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="389dee3293891002f825ea1d5d92283094b7d931"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="87ee480405c4a109c01f68dd64de625f1ff819d9"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="df6b6315b7217522ae03151449a841f0c382c888"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ef8e1c9128ee14189263382788a7b6b06353a6e8"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
<project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>

View File

@ -15,7 +15,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="bc6f07c149770c6e6dfbea941ac65138dc364a15"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="389dee3293891002f825ea1d5d92283094b7d931"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="87ee480405c4a109c01f68dd64de625f1ff819d9"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -19,12 +19,12 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="bc6f07c149770c6e6dfbea941ac65138dc364a15"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="389dee3293891002f825ea1d5d92283094b7d931"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="87ee480405c4a109c01f68dd64de625f1ff819d9"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="df6b6315b7217522ae03151449a841f0c382c888"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ef8e1c9128ee14189263382788a7b6b06353a6e8"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
<project name="platform/bionic" path="bionic" revision="cd5dfce80bc3f0139a56b58aca633202ccaee7f8"/>

View File

@ -17,12 +17,12 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="bc6f07c149770c6e6dfbea941ac65138dc364a15"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="389dee3293891002f825ea1d5d92283094b7d931"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="87ee480405c4a109c01f68dd64de625f1ff819d9"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="df6b6315b7217522ae03151449a841f0c382c888"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ef8e1c9128ee14189263382788a7b6b06353a6e8"/>
<project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>

View File

@ -17,10 +17,10 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="bc6f07c149770c6e6dfbea941ac65138dc364a15"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="389dee3293891002f825ea1d5d92283094b7d931"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="87ee480405c4a109c01f68dd64de625f1ff819d9"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="df6b6315b7217522ae03151449a841f0c382c888"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ef8e1c9128ee14189263382788a7b6b06353a6e8"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->
@ -127,7 +127,7 @@
<project name="device-mako" path="device/lge/mako" remote="b2g" revision="78d17f0c117f0c66dd55ee8d5c5dde8ccc93ecba"/>
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="3a9a17613cc685aa232432566ad6cc607eab4ec1"/>
<project name="device/lge/mako-kernel" path="device/lge/mako-kernel" revision="d1729e53d71d711c8fde25eab8728ff2b9b4df0e"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="56e7fe044cb6a0ad689b96ad7a3636d65e769b34"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="ea8011252172347bd7711f6fc9c5cc24ab1a109b"/>
<project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="7d33aaf740bbf6c7c6e9c34a92b371eda311b66b"/>
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/>
<project name="platform/hardware/broadcom/wlan" path="hardware/broadcom/wlan" revision="0e1929fa3aa38bf9d40e9e953d619fab8164c82e"/>

View File

@ -17,10 +17,10 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="bc6f07c149770c6e6dfbea941ac65138dc364a15"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="389dee3293891002f825ea1d5d92283094b7d931"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="87ee480405c4a109c01f68dd64de625f1ff819d9"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="df6b6315b7217522ae03151449a841f0c382c888"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ef8e1c9128ee14189263382788a7b6b06353a6e8"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->
@ -127,7 +127,7 @@
<project name="device-mako" path="device/lge/mako" remote="b2g" revision="78d17f0c117f0c66dd55ee8d5c5dde8ccc93ecba"/>
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="3a9a17613cc685aa232432566ad6cc607eab4ec1"/>
<project name="device/lge/mako-kernel" path="device/lge/mako-kernel" revision="d1729e53d71d711c8fde25eab8728ff2b9b4df0e"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="56e7fe044cb6a0ad689b96ad7a3636d65e769b34"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="ea8011252172347bd7711f6fc9c5cc24ab1a109b"/>
<project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="7d33aaf740bbf6c7c6e9c34a92b371eda311b66b"/>
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/>
<project name="platform/hardware/broadcom/wlan" path="hardware/broadcom/wlan" revision="0e1929fa3aa38bf9d40e9e953d619fab8164c82e"/>

View File

@ -17,12 +17,12 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="bc6f07c149770c6e6dfbea941ac65138dc364a15"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="389dee3293891002f825ea1d5d92283094b7d931"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="87ee480405c4a109c01f68dd64de625f1ff819d9"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="df6b6315b7217522ae03151449a841f0c382c888"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ef8e1c9128ee14189263382788a7b6b06353a6e8"/>
<project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>

View File

@ -19,6 +19,8 @@ if CONFIG['MOZ_WEBAPP_RUNTIME']:
add_tier_dir('app', 'b2g/chrome')
add_tier_dir('app', 'b2g/components')
add_tier_dir('app', 'b2g/dev/app')
# Never add tier dirs after browser because they apparently won't get
# packaged properly on Mac.
add_tier_dir('app', 'browser')

5
b2g/dev/app/Makefile.in Normal file
View File

@ -0,0 +1,5 @@
# 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/.
PREF_JS_EXPORTS += $(topsrcdir)/b2g/app/b2g.js

View File

@ -627,7 +627,11 @@
; [Default Preferences]
; All the pref files must be part of base to prevent migration bugs
#ifdef MOZ_MULET
@BINPATH@/defaults/pref/b2g.js
#else
@BINPATH@/@PREF_DIR@/b2g.js
#endif
@BINPATH@/@PREF_DIR@/channel-prefs.js
@BINPATH@/greprefs.js
@BINPATH@/defaults/autoconfig/platform.js

View File

@ -7,10 +7,6 @@ dist_dest = $(DIST)/$(MOZ_MACBUNDLE_NAME)
PREF_JS_EXPORTS = $(srcdir)/profile/firefox.js \
$(NULL)
ifdef MOZ_MULET
PREF_JS_EXPORTS += $(topsrcdir)/b2g/app/b2g.js
endif
# hardcode en-US for the moment
AB_CD = en-US

View File

@ -784,7 +784,8 @@ var gBrowserInit = {
gPageStyleMenu.init();
LanguageDetectionListener.init();
messageManager.loadFrameScript("chrome://browser/content/content.js", true);
let mm = window.getGroupMessageManager("browsers");
mm.loadFrameScript("chrome://browser/content/content.js", true);
// initialize observers and listeners
// and give C++ access to gBrowser

View File

@ -34,7 +34,7 @@
<xul:hbox flex="1" class="browserSidebarContainer">
<xul:vbox flex="1" class="browserContainer">
<xul:stack flex="1" class="browserStack" anonid="browserStack">
<xul:browser anonid="initialBrowser" type="content-primary" message="true"
<xul:browser anonid="initialBrowser" type="content-primary" message="true" messagemanagergroup="browsers"
xbl:inherits="tooltip=contenttooltip,contextmenu=contentcontextmenu,autocompletepopup,selectpopup"/>
</xul:stack>
</xul:vbox>
@ -1529,6 +1529,7 @@
"browser");
b.setAttribute("type", "content-targetable");
b.setAttribute("message", "true");
b.setAttribute("messagemanagergroup", "browsers");
b.setAttribute("contextmenu", this.getAttribute("contentcontextmenu"));
b.setAttribute("tooltip", this.getAttribute("contenttooltip"));

View File

@ -764,7 +764,7 @@ let SessionStoreInternal = {
// internal data about the window.
aWindow.__SSi = this._generateWindowID();
let mm = aWindow.messageManager;
let mm = aWindow.getGroupMessageManager("browsers");
MESSAGES.forEach(msg => mm.addMessageListener(msg, this));
// Load the frame script after registering listeners.
@ -1093,7 +1093,7 @@ let SessionStoreInternal = {
// Cache the window state until it is completely gone.
DyingWindowCache.set(aWindow, winData);
let mm = aWindow.messageManager;
let mm = aWindow.getGroupMessageManager("browsers");
MESSAGES.forEach(msg => mm.removeMessageListener(msg, this));
delete aWindow.__SSi;

View File

@ -76,7 +76,8 @@ add_task(function () {
// Create a new window to attach our frame script to.
let win = yield promiseNewWindowLoaded();
win.messageManager.loadFrameScript(FRAME_SCRIPT, true);
let mm = win.getGroupMessageManager("browsers");
mm.loadFrameScript(FRAME_SCRIPT, true);
// Create a new tab in the new window that will load the frame script.
let tab = win.gBrowser.addTab("about:mozilla");

View File

@ -174,7 +174,7 @@ let UI = {
});
// ___ setup DOMWillOpenModalDialog message handler
let mm = gWindow.messageManager;
let mm = gWindow.getGroupMessageManager("browsers");
let callback = this._onDOMWillOpenModalDialog.bind(this);
mm.addMessageListener("Panorama:DOMWillOpenModalDialog", callback);
@ -235,7 +235,7 @@ let UI = {
// ___ load frame script
let frameScript = "chrome://browser/content/tabview-content.js";
gWindow.messageManager.loadFrameScript(frameScript, true);
mm.loadFrameScript(frameScript, true);
// ___ Done
this._frameInitialized = true;

View File

@ -10,10 +10,17 @@ include $(topsrcdir)/config/rules.mk
MOZ_PKG_REMOVALS = $(srcdir)/removed-files.in
MOZ_PKG_MANIFEST_P = $(srcdir)/package-manifest.in
ifdef MOZ_MULET
MOZ_PKG_MANIFEST_P += $(topsrcdir)/b2g/installer/package-manifest.in
endif
# Some files have been already bundled with xulrunner
ifndef SYSTEM_LIBXUL
ifndef MOZ_MULET
MOZ_PKG_FATAL_WARNINGS = 1
endif
endif
DEFINES += -DAB_CD=$(AB_CD) -DMOZ_APP_NAME=$(MOZ_APP_NAME) -DPREF_DIR=$(PREF_DIR)
@ -88,7 +95,7 @@ ifdef MOZ_PKG_MANIFEST_P
MOZ_PKG_MANIFEST = package-manifest
$(MOZ_PKG_MANIFEST): $(MOZ_PKG_MANIFEST_P) $(GLOBAL_DEPS)
$(call py_action,preprocessor,$(DEFINES) $(ACDEFINES) $< -o $@)
$(call py_action,preprocessor,$(DEFINES) $(ACDEFINES) $(MOZ_PKG_MANIFEST_P) -o $@)
GARBAGE += $(MOZ_PKG_MANIFEST)
endif

View File

@ -866,5 +866,7 @@ bin/libfreebl_32int64_3.so
#ifdef MOZ_ASAN
#ifdef CLANG_CXX
@BINPATH@/llvm-symbolizer
#endif
#endif

View File

@ -320,9 +320,9 @@ HiddenBrowser.prototype = {
// Swap docShells.
tabbrowser.swapNewTabWithBrowser(aTab, this._browser);
// Load all default frame scripts attached to the target window.
// Load all delayed frame scripts attached to the "browers" message manager.
let mm = aTab.linkedBrowser.messageManager;
let scripts = win.messageManager.getDelayedFrameScripts();
let scripts = win.getGroupMessageManager("browsers").getDelayedFrameScripts();
Array.forEach(scripts, ([script, runGlobal]) => mm.loadFrameScript(script, true, runGlobal));
// Remove the browser, it will be recreated by a timer.

View File

@ -64,7 +64,7 @@ case "$target" in
kernel_name=`uname -s | tr "[[:upper:]]" "[[:lower:]]"`
for version in $android_gnu_compiler_version 4.7 4.6 4.4.3 ; do
for version in $android_gnu_compiler_version 4.8 4.7 4.6 4.4.3; do
case "$target_cpu" in
arm)
target_name=arm-linux-androideabi-$version

View File

@ -39,6 +39,8 @@ interface nsIPrincipal;
* - "frame message managers" which correspond to frame elements
* - "window message managers" which correspond to top-level chrome
* windows
* - "group message managers" which correspond to named message
* managers with a specific window MM as the parent
* - the "global message manager", on the parent side. See below.
*
* The DOM-realm message managers can communicate in the ways shown by
@ -54,6 +56,16 @@ interface nsIPrincipal;
* | +-->frame MMp1_1<------------>frame MMc1_1
* | |
* | +-->frame MMp1_2<------------>frame MMc1_2
* | |
* | +-->group MMgr1
* | | |
* | | +-->frame MMp2_1<------->frame MMc2_1
* | | |
* | | +-->frame MMp2_2<------->frame MMc2_2
* | |
* | +-->group MMgr2
* | | ...
* | |
* | ...
* |
* +-->window MMw2
@ -64,17 +76,23 @@ interface nsIPrincipal;
* message managers in the hierarchy above MMp1_1, in this diagram
* MMw1 and MMg, will also notify their message listeners when the
* message arrives.
*
* A message sent from MMc2_1 will be sent to MMp2_1 and also notify
* all message managers in the hierarchy above that, including the
* group message manager MMgr1.
* For example: a message broadcast through the global MMg on the
* parent side would be broadcast to MMw1, which would transitively
* broadcast it to MMp1_1, MM1p_2". The message would next be
* broadcast to MMw2, and so on down the hierarchy.
* broadcast it to MMp1_1, MM1p_2. The message would next be
* broadcast to MMgr1, which would broadcast it to MMp2_1 and MMp2_2.
* After that it would broadcast to MMgr2 and then to MMw2, and so
* on down the hierarchy.
*
* ***** PERFORMANCE AND SECURITY WARNING *****
* Messages broadcast through the global MM and window MMs can result
* in messages being dispatched across many OS processes, and to many
* processes with different permissions. Great care should be taken
* when broadcasting.
* Messages broadcast through the global MM and window or group MMs
* can result in messages being dispatched across many OS processes,
* and to many processes with different permissions. Great care
* should be taken when broadcasting.
*
* Interfaces
* ----------

View File

@ -143,6 +143,8 @@ already_AddRefed<nsIDocument>
DOMParser::ParseFromBuffer(const Uint8Array& aBuf, uint32_t aBufLen,
SupportedType aType, ErrorResult& rv)
{
aBuf.ComputeLengthAndData();
if (aBufLen > aBuf.Length()) {
rv.Throw(NS_ERROR_XPC_NOT_ENOUGH_ELEMENTS_IN_ARRAY);
return nullptr;

View File

@ -1212,7 +1212,10 @@ WebSocket::Send(const ArrayBuffer& aData,
{
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
MOZ_ASSERT(sizeof(*aData.Data()) == 1);
aData.ComputeLengthAndData();
static_assert(sizeof(*aData.Data()) == 1, "byte-sized data required");
uint32_t len = aData.Length();
char* data = reinterpret_cast<char*>(aData.Data());
@ -1226,7 +1229,10 @@ WebSocket::Send(const ArrayBufferView& aData,
{
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
MOZ_ASSERT(sizeof(*aData.Data()) == 1);
aData.ComputeLengthAndData();
static_assert(sizeof(*aData.Data()) == 1, "byte-sized data required");
uint32_t len = aData.Length();
char* data = reinterpret_cast<char*>(aData.Data());

View File

@ -303,7 +303,10 @@ nsDOMDataChannel::Send(const ArrayBuffer& aData, ErrorResult& aRv)
{
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
MOZ_ASSERT(sizeof(*aData.Data()) == 1);
aData.ComputeLengthAndData();
static_assert(sizeof(*aData.Data()) == 1, "byte-sized data required");
uint32_t len = aData.Length();
char* data = reinterpret_cast<char*>(aData.Data());
@ -316,7 +319,10 @@ nsDOMDataChannel::Send(const ArrayBufferView& aData, ErrorResult& aRv)
{
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
MOZ_ASSERT(sizeof(*aData.Data()) == 1);
aData.ComputeLengthAndData();
static_assert(sizeof(*aData.Data()) == 1, "byte-sized data required");
uint32_t len = aData.Length();
char* data = reinterpret_cast<char*>(aData.Data());

View File

@ -2529,6 +2529,7 @@ GetRequestBody(nsIVariant* aBody, nsIInputStream** aResult, uint64_t* aContentLe
JS::Rooted<JSObject*> obj(cx, realVal.toObjectOrNull());
if (JS_IsArrayBufferObject(obj)) {
ArrayBuffer buf(obj);
buf.ComputeLengthAndData();
return GetRequestBody(buf.Data(), buf.Length(), aResult,
aContentLength, aContentType, aCharset);
}
@ -2572,14 +2573,16 @@ nsXMLHttpRequest::GetRequestBody(nsIVariant* aVariant,
switch (body.GetType()) {
case nsXMLHttpRequest::RequestBody::ArrayBuffer:
{
return ::GetRequestBody(value.mArrayBuffer->Data(),
value.mArrayBuffer->Length(), aResult,
const ArrayBuffer* buffer = value.mArrayBuffer;
buffer->ComputeLengthAndData();
return ::GetRequestBody(buffer->Data(), buffer->Length(), aResult,
aContentLength, aContentType, aCharset);
}
case nsXMLHttpRequest::RequestBody::ArrayBufferView:
{
return ::GetRequestBody(value.mArrayBufferView->Data(),
value.mArrayBufferView->Length(), aResult,
const ArrayBufferView* view = value.mArrayBufferView;
view->ComputeLengthAndData();
return ::GetRequestBody(view->Data(), view->Length(), aResult,
aContentLength, aContentType, aCharset);
}
case nsXMLHttpRequest::RequestBody::Blob:
@ -3583,15 +3586,11 @@ nsXMLHttpRequest::OnProgress(nsIRequest *aRequest, nsISupports *aContext, uint64
// So, try to remove the headers, if possible.
bool lengthComputable = (aProgressMax != UINT64_MAX);
if (upload) {
uint64_t loaded = aProgress;
uint64_t total = aProgressMax;
mUploadTransferred = aProgress;
if (lengthComputable) {
uint64_t headerSize = aProgressMax - mUploadTotal;
loaded -= headerSize;
total -= headerSize;
mUploadTransferred = aProgressMax - mUploadTotal;
}
mUploadLengthComputable = lengthComputable;
mUploadTransferred = loaded;
mProgressSinceLastProgressEvent = true;
MaybeDispatchProgressEvents(false);

View File

@ -4010,7 +4010,7 @@ CanvasRenderingContext2D::PutImageData(ImageData& imageData, double dx,
error = PutImageData_explicit(JS_DoubleToInt32(dx), JS_DoubleToInt32(dy),
imageData.Width(), imageData.Height(),
arr.Data(), arr.Length(), false, 0, 0, 0, 0);
&arr, false, 0, 0, 0, 0);
}
void
@ -4024,7 +4024,7 @@ CanvasRenderingContext2D::PutImageData(ImageData& imageData, double dx,
error = PutImageData_explicit(JS_DoubleToInt32(dx), JS_DoubleToInt32(dy),
imageData.Width(), imageData.Height(),
arr.Data(), arr.Length(), true,
&arr, true,
JS_DoubleToInt32(dirtyX),
JS_DoubleToInt32(dirtyY),
JS_DoubleToInt32(dirtyWidth),
@ -4036,7 +4036,7 @@ CanvasRenderingContext2D::PutImageData(ImageData& imageData, double dx,
nsresult
CanvasRenderingContext2D::PutImageData_explicit(int32_t x, int32_t y, uint32_t w, uint32_t h,
unsigned char *aData, uint32_t aDataLen,
dom::Uint8ClampedArray* aArray,
bool hasDirtyRect, int32_t dirtyX, int32_t dirtyY,
int32_t dirtyWidth, int32_t dirtyHeight)
{
@ -4089,8 +4089,12 @@ CanvasRenderingContext2D::PutImageData_explicit(int32_t x, int32_t y, uint32_t w
return NS_OK;
}
aArray->ComputeLengthAndData();
uint32_t dataLen = aArray->Length();
uint32_t len = w * h * 4;
if (aDataLen != len) {
if (dataLen != len) {
return NS_ERROR_DOM_SYNTAX_ERR;
}
@ -4101,7 +4105,7 @@ CanvasRenderingContext2D::PutImageData_explicit(int32_t x, int32_t y, uint32_t w
return NS_ERROR_FAILURE;
}
uint8_t *src = aData;
uint8_t *src = aArray->Data();
uint8_t *dst = imgsurf->Data();
for (uint32_t j = 0; j < h; j++) {

View File

@ -551,7 +551,7 @@ protected:
JSObject** aRetval);
nsresult PutImageData_explicit(int32_t x, int32_t y, uint32_t w, uint32_t h,
unsigned char *aData, uint32_t aDataLen,
dom::Uint8ClampedArray* aArray,
bool hasDirtyRect, int32_t dirtyX, int32_t dirtyY,
int32_t dirtyWidth, int32_t dirtyHeight);

View File

@ -70,6 +70,8 @@ ImageData::Constructor(const GlobalObject& aGlobal,
const Optional<uint32_t>& aHeight,
ErrorResult& aRv)
{
aData.ComputeLengthAndData();
uint32_t length = aData.Length();
if (length == 0 || length % 4) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);

View File

@ -83,18 +83,21 @@ WebGLMemoryPressureObserver::Observe(nsISupports* aSubject,
if (!mContext->mCanLoseContextInForeground &&
ProcessPriorityManager::CurrentProcessIsForeground())
{
wantToLoseContext = false;
else if (!nsCRT::strcmp(aSomeData,
MOZ_UTF16("heap-minimize")))
} else if (!nsCRT::strcmp(aSomeData,
MOZ_UTF16("heap-minimize")))
{
wantToLoseContext = mContext->mLoseContextOnHeapMinimize;
}
if (wantToLoseContext)
if (wantToLoseContext) {
mContext->ForceLoseContext();
}
return NS_OK;
}
WebGLContextOptions::WebGLContextOptions()
: alpha(true), depth(true), stencil(false),
premultipliedAlpha(true), antialias(true),
@ -168,12 +171,12 @@ WebGLContext::WebGLContext()
WebGLMemoryTracker::AddWebGLContext(this);
mAllowRestore = true;
mAllowContextRestore = true;
mLastLossWasSimulated = false;
mContextLossTimerRunning = false;
mDrawSinceContextLossTimerSet = false;
mRunContextLossTimerAgain = false;
mContextRestorer = do_CreateInstance("@mozilla.org/timer;1");
mContextStatus = ContextNotLost;
mContextLostErrorSet = false;
mLoseContextOnHeapMinimize = false;
mCanLoseContextInForeground = true;
@ -571,11 +574,8 @@ WebGLContext::SetDimensions(int32_t width, int32_t height)
mResetLayer = true;
mOptionsFrozen = true;
mHasRobustness = gl->HasRobustness();
// increment the generation number
++mGeneration;
#if 0
if (mGeneration > 0) {
// XXX dispatch context lost event
@ -1110,6 +1110,96 @@ WebGLContext::DummyFramebufferOperation(const char *info)
ErrorInvalidFramebufferOperation("%s: incomplete framebuffer", info);
}
static bool
CheckContextLost(GLContext* gl, bool* out_isGuilty)
{
MOZ_ASSERT(gl);
MOZ_ASSERT(out_isGuilty);
bool isEGL = gl->GetContextType() == gl::GLContextType::EGL;
GLenum resetStatus = LOCAL_GL_NO_ERROR;
if (gl->HasRobustness()) {
gl->MakeCurrent();
resetStatus = gl->fGetGraphicsResetStatus();
} else if (isEGL) {
// Simulate a ARB_robustness guilty context loss for when we
// get an EGL_CONTEXT_LOST error. It may not actually be guilty,
// but we can't make any distinction.
if (!gl->MakeCurrent(true) && gl->IsContextLost()) {
resetStatus = LOCAL_GL_UNKNOWN_CONTEXT_RESET_ARB;
}
}
if (resetStatus == LOCAL_GL_NO_ERROR) {
*out_isGuilty = false;
return false;
}
// Assume guilty unless we find otherwise!
bool isGuilty = true;
switch (resetStatus) {
case LOCAL_GL_INNOCENT_CONTEXT_RESET_ARB:
// Either nothing wrong, or not our fault.
isGuilty = false;
break;
case LOCAL_GL_GUILTY_CONTEXT_RESET_ARB:
NS_WARNING("WebGL content on the page definitely caused the graphics"
" card to reset.");
break;
case LOCAL_GL_UNKNOWN_CONTEXT_RESET_ARB:
NS_WARNING("WebGL content on the page might have caused the graphics"
" card to reset");
// If we can't tell, assume guilty.
break;
default:
MOZ_ASSERT(false, "Unreachable.");
// If we do get here, let's pretend to be guilty as an escape plan.
break;
}
if (isGuilty) {
NS_WARNING("WebGL context on this page is considered guilty, and will"
" not be restored.");
}
*out_isGuilty = isGuilty;
return true;
}
bool
WebGLContext::TryToRestoreContext()
{
if (NS_FAILED(SetDimensions(mWidth, mHeight)))
return false;
return true;
}
class UpdateContextLossStatusTask : public nsRunnable
{
WebGLContext* const mContext;
public:
UpdateContextLossStatusTask(WebGLContext* context)
: mContext(context)
{
}
NS_IMETHOD Run() {
mContext->UpdateContextLossStatus();
return NS_OK;
}
};
void
WebGLContext::EnqueueUpdateContextLossStatus()
{
nsCOMPtr<nsIRunnable> task = new UpdateContextLossStatusTask(this);
NS_DispatchToCurrentThread(task);
}
// We use this timer for many things. Here are the things that it is activated for:
// 1) If a script is using the MOZ_WEBGL_lose_context extension.
// 2) If we are using EGL and _NOT ANGLE_, we query periodically to see if the
@ -1125,137 +1215,123 @@ WebGLContext::DummyFramebufferOperation(const char *info)
// At a bare minimum, from context lost to context restores, it would take 3
// full timer iterations: detection, webglcontextlost, webglcontextrestored.
void
WebGLContext::RobustnessTimerCallback(nsITimer* timer)
WebGLContext::UpdateContextLossStatus()
{
TerminateContextLossTimer();
if (!mCanvasElement) {
// the canvas is gone. That happens when the page was closed before we got
// this timer event. In this case, there's nothing to do here, just don't crash.
return;
}
if (mContextStatus == ContextNotLost) {
// We don't know that we're lost, but we might be, so we need to
// check. If we're guilty, don't allow restores, though.
bool isGuilty = true;
bool isContextLost = CheckContextLost(gl, &isGuilty);
if (isContextLost) {
if (isGuilty)
mAllowContextRestore = false;
ForceLoseContext();
}
// Fall through.
}
// If the context has been lost and we're waiting for it to be restored, do
// that now.
if (mContextStatus == ContextLostAwaitingEvent) {
bool defaultAction;
// The context has been lost and we haven't yet triggered the
// callback, so do that now.
bool useDefaultHandler;
nsContentUtils::DispatchTrustedEvent(mCanvasElement->OwnerDoc(),
static_cast<nsIDOMHTMLCanvasElement*>(mCanvasElement),
NS_LITERAL_STRING("webglcontextlost"),
true,
true,
&defaultAction);
&useDefaultHandler);
// We sent the callback, so we're just 'regular lost' now.
mContextStatus = ContextLost;
// If we're told to use the default handler, it means the script
// didn't bother to handle the event. In this case, we shouldn't
// auto-restore the context.
if (useDefaultHandler)
mAllowContextRestore = false;
// If the script didn't handle the event, we don't allow restores.
if (defaultAction)
mAllowRestore = false;
// Fall through.
}
// If the script handled the event and we are allowing restores, then
// mark it to be restored. Otherwise, leave it as context lost
// (unusable).
if (!defaultAction && mAllowRestore) {
ForceRestoreContext();
// Restart the timer so that it will be restored on the next
// callback.
SetupContextLossTimer();
} else {
if (mContextStatus == ContextLost) {
// Context is lost, and we've already sent the callback. We
// should try to restore the context if we're both allowed to,
// and supposed to.
// Are we allowed to restore the context?
if (!mAllowContextRestore)
return;
// If we're only simulated-lost, we shouldn't auto-restore, and
// instead we should wait for restoreContext() to be called.
if (mLastLossWasSimulated)
return;
ForceRestoreContext();
return;
}
if (mContextStatus == ContextLostAwaitingRestore) {
// Context is lost, but we should try to restore it.
if (!mAllowContextRestore) {
// We might decide this after thinking we'd be OK restoring
// the context, so downgrade.
mContextStatus = ContextLost;
}
} else if (mContextStatus == ContextLostAwaitingRestore) {
// Try to restore the context. If it fails, try again later.
if (NS_FAILED(SetDimensions(mWidth, mHeight))) {
SetupContextLossTimer();
return;
}
if (!TryToRestoreContext()) {
// Failed to restore. Try again later.
RunContextLossTimer();
return;
}
// Revival!
mContextStatus = ContextNotLost;
nsContentUtils::DispatchTrustedEvent(mCanvasElement->OwnerDoc(),
static_cast<nsIDOMHTMLCanvasElement*>(mCanvasElement),
NS_LITERAL_STRING("webglcontextrestored"),
true,
true);
// Set all flags back to the state they were in before the context was
// lost.
mEmitContextLostErrorOnce = true;
mAllowRestore = true;
}
MaybeRestoreContext();
return;
}
void
WebGLContext::MaybeRestoreContext()
{
// Don't try to handle it if we already know it's busted.
if (mContextStatus != ContextNotLost || gl == nullptr)
return;
bool isEGL = gl->GetContextType() == gl::GLContextType::EGL,
isANGLE = gl->IsANGLE();
GLContext::ContextResetARB resetStatus = GLContext::CONTEXT_NO_ERROR;
if (mHasRobustness) {
gl->MakeCurrent();
resetStatus = (GLContext::ContextResetARB) gl->fGetGraphicsResetStatus();
} else if (isEGL) {
// Simulate a ARB_robustness guilty context loss for when we
// get an EGL_CONTEXT_LOST error. It may not actually be guilty,
// but we can't make any distinction, so we must assume the worst
// case.
if (!gl->MakeCurrent(true) && gl->IsContextLost()) {
resetStatus = GLContext::CONTEXT_GUILTY_CONTEXT_RESET_ARB;
}
}
if (resetStatus != GLContext::CONTEXT_NO_ERROR) {
// It's already lost, but clean up after it and signal to JS that it is
// lost.
ForceLoseContext();
}
switch (resetStatus) {
case GLContext::CONTEXT_NO_ERROR:
// If there has been activity since the timer was set, it's possible
// that we did or are going to miss something, so clear this flag and
// run it again some time later.
if (mDrawSinceContextLossTimerSet)
SetupContextLossTimer();
break;
case GLContext::CONTEXT_GUILTY_CONTEXT_RESET_ARB:
NS_WARNING("WebGL content on the page caused the graphics card to reset; not restoring the context");
mAllowRestore = false;
break;
case GLContext::CONTEXT_INNOCENT_CONTEXT_RESET_ARB:
break;
case GLContext::CONTEXT_UNKNOWN_CONTEXT_RESET_ARB:
NS_WARNING("WebGL content on the page might have caused the graphics card to reset");
if (isEGL && isANGLE) {
// If we're using ANGLE, we ONLY get back UNKNOWN context resets, including for guilty contexts.
// This means that we can't restore it or risk restoring a guilty context. Should this ever change,
// we can get rid of the whole IsANGLE() junk from GLContext.h since, as of writing, this is the
// only use for it. See ANGLE issue 261.
mAllowRestore = false;
}
break;
}
}
void
WebGLContext::ForceLoseContext()
{
if (mContextStatus == ContextLostAwaitingEvent)
return;
printf_stderr("WebGL(%p)::ForceLoseContext\n", this);
MOZ_ASSERT(!IsContextLost());
mContextStatus = ContextLostAwaitingEvent;
// Queue up a task to restore the event.
SetupContextLossTimer();
mContextLostErrorSet = false;
mLastLossWasSimulated = false;
// Burn it all!
DestroyResourcesAndContext();
// Queue up a task, since we know the status changed.
EnqueueUpdateContextLossStatus();
}
void
WebGLContext::ForceRestoreContext()
{
printf_stderr("WebGL(%p)::ForceRestoreContext\n", this);
mContextStatus = ContextLostAwaitingRestore;
mAllowContextRestore = true; // Hey, you did say 'force'.
// Queue up a task, since we know the status changed.
EnqueueUpdateContextLossStatus();
}
void

View File

@ -202,9 +202,6 @@ public:
int32_t x, int32_t y, int32_t w, int32_t h)
{ return NS_ERROR_NOT_IMPLEMENTED; }
bool LoseContext();
bool RestoreContext();
void SynthesizeGLError(GLenum err);
void SynthesizeGLError(GLenum err, const char *fmt, ...);
@ -261,11 +258,14 @@ public:
bool MinCapabilityMode() const { return mMinCapability; }
void RobustnessTimerCallback(nsITimer* timer);
static void RobustnessTimerCallbackStatic(nsITimer* timer, void *thisPointer);
void SetupContextLossTimer();
void UpdateContextLossStatus();
void EnqueueUpdateContextLossStatus();
static void ContextLossCallbackStatic(nsITimer* timer, void* thisPointer);
void RunContextLossTimer();
void TerminateContextLossTimer();
bool TryToRestoreContext();
void AssertCachedBindings();
void AssertCachedState();
@ -511,6 +511,7 @@ public:
void Uniform1iv(WebGLUniformLocation* location,
const dom::Int32Array& arr) {
arr.ComputeLengthAndData();
Uniform1iv_base(location, arr.Length(), arr.Data());
}
void Uniform1iv(WebGLUniformLocation* location,
@ -522,6 +523,7 @@ public:
void Uniform2iv(WebGLUniformLocation* location,
const dom::Int32Array& arr) {
arr.ComputeLengthAndData();
Uniform2iv_base(location, arr.Length(), arr.Data());
}
void Uniform2iv(WebGLUniformLocation* location,
@ -533,6 +535,7 @@ public:
void Uniform3iv(WebGLUniformLocation* location,
const dom::Int32Array& arr) {
arr.ComputeLengthAndData();
Uniform3iv_base(location, arr.Length(), arr.Data());
}
void Uniform3iv(WebGLUniformLocation* location,
@ -544,6 +547,7 @@ public:
void Uniform4iv(WebGLUniformLocation* location,
const dom::Int32Array& arr) {
arr.ComputeLengthAndData();
Uniform4iv_base(location, arr.Length(), arr.Data());
}
void Uniform4iv(WebGLUniformLocation* location,
@ -555,6 +559,7 @@ public:
void Uniform1fv(WebGLUniformLocation* location,
const dom::Float32Array& arr) {
arr.ComputeLengthAndData();
Uniform1fv_base(location, arr.Length(), arr.Data());
}
void Uniform1fv(WebGLUniformLocation* location,
@ -566,6 +571,7 @@ public:
void Uniform2fv(WebGLUniformLocation* location,
const dom::Float32Array& arr) {
arr.ComputeLengthAndData();
Uniform2fv_base(location, arr.Length(), arr.Data());
}
void Uniform2fv(WebGLUniformLocation* location,
@ -577,6 +583,7 @@ public:
void Uniform3fv(WebGLUniformLocation* location,
const dom::Float32Array& arr) {
arr.ComputeLengthAndData();
Uniform3fv_base(location, arr.Length(), arr.Data());
}
void Uniform3fv(WebGLUniformLocation* location,
@ -588,6 +595,7 @@ public:
void Uniform4fv(WebGLUniformLocation* location,
const dom::Float32Array& arr) {
arr.ComputeLengthAndData();
Uniform4fv_base(location, arr.Length(), arr.Data());
}
void Uniform4fv(WebGLUniformLocation* location,
@ -600,6 +608,7 @@ public:
void UniformMatrix2fv(WebGLUniformLocation* location,
WebGLboolean transpose,
const dom::Float32Array &value) {
value.ComputeLengthAndData();
UniformMatrix2fv_base(location, transpose, value.Length(), value.Data());
}
void UniformMatrix2fv(WebGLUniformLocation* location,
@ -615,6 +624,7 @@ public:
void UniformMatrix3fv(WebGLUniformLocation* location,
WebGLboolean transpose,
const dom::Float32Array &value) {
value.ComputeLengthAndData();
UniformMatrix3fv_base(location, transpose, value.Length(), value.Data());
}
void UniformMatrix3fv(WebGLUniformLocation* location,
@ -630,6 +640,7 @@ public:
void UniformMatrix4fv(WebGLUniformLocation* location,
WebGLboolean transpose,
const dom::Float32Array &value) {
value.ComputeLengthAndData();
UniformMatrix4fv_base(location, transpose, value.Length(), value.Data());
}
void UniformMatrix4fv(WebGLUniformLocation* location,
@ -655,8 +666,12 @@ public:
bool ValidateSamplerUniformSetter(const char* info,
WebGLUniformLocation *location,
GLint value);
void Viewport(GLint x, GLint y, GLsizei width, GLsizei height);
// -----------------------------------------------------------------------------
// WEBGL_lose_context
public:
void LoseContext();
void RestoreContext();
// -----------------------------------------------------------------------------
// Asynchronous Queries (WebGLContextAsyncQueries.cpp)
@ -753,6 +768,7 @@ public:
GLfloat x2, GLfloat x3);
void VertexAttrib1fv(GLuint idx, const dom::Float32Array &arr) {
arr.ComputeLengthAndData();
VertexAttrib1fv_base(idx, arr.Length(), arr.Data());
}
void VertexAttrib1fv(GLuint idx, const dom::Sequence<GLfloat>& arr) {
@ -760,6 +776,7 @@ public:
}
void VertexAttrib2fv(GLuint idx, const dom::Float32Array &arr) {
arr.ComputeLengthAndData();
VertexAttrib2fv_base(idx, arr.Length(), arr.Data());
}
void VertexAttrib2fv(GLuint idx, const dom::Sequence<GLfloat>& arr) {
@ -767,6 +784,7 @@ public:
}
void VertexAttrib3fv(GLuint idx, const dom::Float32Array &arr) {
arr.ComputeLengthAndData();
VertexAttrib3fv_base(idx, arr.Length(), arr.Data());
}
void VertexAttrib3fv(GLuint idx, const dom::Sequence<GLfloat>& arr) {
@ -774,6 +792,7 @@ public:
}
void VertexAttrib4fv(GLuint idx, const dom::Float32Array &arr) {
arr.ComputeLengthAndData();
VertexAttrib4fv_base(idx, arr.Length(), arr.Data());
}
void VertexAttrib4fv(GLuint idx, const dom::Sequence<GLfloat>& arr) {
@ -854,7 +873,6 @@ protected:
bool mOptionsFrozen;
bool mMinCapability;
bool mDisableExtensions;
bool mHasRobustness;
bool mIsMesa;
bool mLoseContextOnHeapMinimize;
bool mCanLoseContextInForeground;
@ -1101,7 +1119,6 @@ protected:
GLenum type,
const GLvoid *data);
void MaybeRestoreContext();
void ForceLoseContext();
void ForceRestoreContext();
@ -1163,7 +1180,7 @@ protected:
GLint mStencilRefFront, mStencilRefBack;
GLuint mStencilValueMaskFront, mStencilValueMaskBack,
mStencilWriteMaskFront, mStencilWriteMaskBack;
mStencilWriteMaskFront, mStencilWriteMaskBack;
realGLboolean mColorWriteMask[4];
realGLboolean mDepthWriteMask;
GLfloat mColorClearValue[4];
@ -1177,9 +1194,10 @@ protected:
bool mAlreadyWarnedAboutViewportLargerThanDest;
nsCOMPtr<nsITimer> mContextRestorer;
bool mAllowRestore;
bool mAllowContextRestore;
bool mLastLossWasSimulated;
bool mContextLossTimerRunning;
bool mDrawSinceContextLossTimerSet;
bool mRunContextLossTimerAgain;
ContextStatus mContextStatus;
bool mContextLostErrorSet;

View File

@ -203,8 +203,10 @@ WebGLContext::BufferData(GLenum target,
}
const ArrayBuffer& data = maybeData.Value();
data.ComputeLengthAndData();
// careful: data.Length() could conceivably be any size_t, but GLsizeiptr is like intptr_t.
// Careful: data.Length() could conceivably be any uint32_t, but GLsizeiptr
// is like intptr_t.
if (!CheckedInt<GLsizeiptr>(data.Length()).isValid())
return ErrorOutOfMemory("bufferData: bad size");
@ -253,7 +255,10 @@ WebGLContext::BufferData(GLenum target, const ArrayBufferView& data,
if (!boundBuffer)
return ErrorInvalidOperation("bufferData: no buffer bound!");
// careful: data.Length() could conceivably be any size_t, but GLsizeiptr is like intptr_t.
data.ComputeLengthAndData();
// Careful: data.Length() could conceivably be any uint32_t, but GLsizeiptr
// is like intptr_t.
if (!CheckedInt<GLsizeiptr>(data.Length()).isValid())
return ErrorOutOfMemory("bufferData: bad size");
@ -290,8 +295,6 @@ WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
return;
}
const ArrayBuffer& data = maybeData.Value();
if (byteOffset < 0)
return ErrorInvalidValue("bufferSubData: negative offset");
@ -300,6 +303,9 @@ WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
if (!boundBuffer)
return ErrorInvalidOperation("bufferData: no buffer bound!");
const ArrayBuffer& data = maybeData.Value();
data.ComputeLengthAndData();
CheckedInt<WebGLsizeiptr> checked_neededByteLength = CheckedInt<WebGLsizeiptr>(byteOffset) + data.Length();
if (!checked_neededByteLength.isValid())
return ErrorInvalidValue("bufferSubData: integer overflow computing the needed byte length");
@ -336,6 +342,8 @@ WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
if (!boundBuffer)
return ErrorInvalidOperation("bufferSubData: no buffer bound!");
data.ComputeLengthAndData();
CheckedInt<WebGLsizeiptr> checked_neededByteLength = CheckedInt<WebGLsizeiptr>(byteOffset) + data.Length();
if (!checked_neededByteLength.isValid())
return ErrorInvalidValue("bufferSubData: integer overflow computing the needed byte length");

View File

@ -128,7 +128,7 @@ WebGLContext::DrawArrays(GLenum mode, GLint first, GLsizei count)
if (!DrawArrays_check(first, count, 1, "drawArrays"))
return;
SetupContextLossTimer();
RunContextLossTimer();
gl->fDrawArrays(mode, first, count);
Draw_cleanup();
@ -149,7 +149,7 @@ WebGLContext::DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsiz
if (!DrawInstanced_check("drawArraysInstanced"))
return;
SetupContextLossTimer();
RunContextLossTimer();
gl->fDrawArraysInstanced(mode, first, count, primcount);
Draw_cleanup();
@ -296,7 +296,7 @@ WebGLContext::DrawElements(GLenum mode, GLsizei count, GLenum type,
return;
}
SetupContextLossTimer();
RunContextLossTimer();
if (gl->IsSupported(gl::GLFeature::draw_range_elements)) {
gl->fDrawRangeElements(mode, 0, upperBound,
@ -324,7 +324,7 @@ WebGLContext::DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
if (!DrawInstanced_check("drawElementsInstanced"))
return;
SetupContextLossTimer();
RunContextLossTimer();
gl->fDrawElementsInstanced(mode, count, type, reinterpret_cast<GLvoid*>(byteOffset), primcount);
Draw_cleanup();

View File

@ -2126,7 +2126,8 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width,
if (!isReadTypeValid)
return ErrorInvalidEnum("readPixels: Bad type", type);
int dataType = JS_GetArrayBufferViewType(pixels.Value().Obj());
const ArrayBufferView& pixbuf = pixels.Value();
int dataType = JS_GetArrayBufferViewType(pixbuf.Obj());
// Check the pixels param type
if (dataType != requiredDataType)
@ -2144,11 +2145,15 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width,
if (!checked_neededByteLength.isValid())
return ErrorInvalidOperation("readPixels: integer overflow computing the needed buffer size");
uint32_t dataByteLen = JS_GetTypedArrayByteLength(pixels.Value().Obj());
// Compute length and data. Don't reenter after this point, lest the
// precomputed go out of sync with the instant length/data.
pixbuf.ComputeLengthAndData();
uint32_t dataByteLen = pixbuf.Length();
if (checked_neededByteLength.value() > dataByteLen)
return ErrorInvalidOperation("readPixels: buffer too small");
void* data = pixels.Value().Data();
void* data = pixbuf.Data();
if (!data) {
ErrorOutOfMemory("readPixels: buffer storage is null. Did we run out of memory?");
return rv.Throw(NS_ERROR_OUT_OF_MEMORY);
@ -3261,6 +3266,8 @@ WebGLContext::CompressedTexImage2D(GLenum target, GLint level, GLenum internalfo
return;
}
view.ComputeLengthAndData();
uint32_t byteLength = view.Length();
if (!ValidateCompTexImageDataSize(target, internalformat, width, height, byteLength, func)) {
return;
@ -3304,6 +3311,8 @@ WebGLContext::CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset,
MOZ_ASSERT(tex);
WebGLTexture::ImageInfo& levelInfo = tex->ImageInfoAt(target, level);
view.ComputeLengthAndData();
uint32_t byteLength = view.Length();
if (!ValidateCompTexImageDataSize(target, format, width, height, byteLength, func))
return;
@ -3670,10 +3679,24 @@ WebGLContext::TexImage2D(GLenum target, GLint level,
if (IsContextLost())
return;
void* data;
uint32_t length;
int jsArrayType;
if (pixels.IsNull()) {
data = nullptr;
length = 0;
jsArrayType = -1;
} else {
const ArrayBufferView& view = pixels.Value();
view.ComputeLengthAndData();
data = view.Data();
length = view.Length();
jsArrayType = int(JS_GetArrayBufferViewType(view.Obj()));
}
return TexImage2D_base(target, level, internalformat, width, height, 0, border, format, type,
pixels.IsNull() ? 0 : pixels.Value().Data(),
pixels.IsNull() ? 0 : pixels.Value().Length(),
pixels.IsNull() ? -1 : (int)JS_GetArrayBufferViewType(pixels.Value().Obj()),
data, length, jsArrayType,
WebGLTexelFormat::Auto, false);
}
@ -3691,6 +3714,8 @@ WebGLContext::TexImage2D(GLenum target, GLint level,
}
Uint8ClampedArray arr(pixels->GetDataObject());
arr.ComputeLengthAndData();
return TexImage2D_base(target, level, internalformat, pixels->Width(),
pixels->Height(), 4*pixels->Width(), 0,
format, type, arr.Data(), arr.Length(), -1,
@ -3799,10 +3824,13 @@ WebGLContext::TexSubImage2D(GLenum target, GLint level,
if (pixels.IsNull())
return ErrorInvalidValue("texSubImage2D: pixels must not be null!");
const ArrayBufferView& view = pixels.Value();
view.ComputeLengthAndData();
return TexSubImage2D_base(target, level, xoffset, yoffset,
width, height, 0, format, type,
pixels.Value().Data(), pixels.Value().Length(),
JS_GetArrayBufferViewType(pixels.Value().Obj()),
view.Data(), view.Length(),
JS_GetArrayBufferViewType(view.Obj()),
WebGLTexelFormat::Auto, false);
}
@ -3819,6 +3847,8 @@ WebGLContext::TexSubImage2D(GLenum target, GLint level,
return ErrorInvalidValue("texSubImage2D: pixels must not be null!");
Uint8ClampedArray arr(pixels->GetDataObject());
arr.ComputeLengthAndData();
return TexSubImage2D_base(target, level, xoffset, yoffset,
pixels->Width(), pixels->Height(),
4*pixels->Width(), format, type,
@ -3827,27 +3857,34 @@ WebGLContext::TexSubImage2D(GLenum target, GLint level,
WebGLTexelFormat::RGBA8, false);
}
bool
void
WebGLContext::LoseContext()
{
if (IsContextLost())
return false;
return ErrorInvalidOperation("loseContext: Context is already lost.");
ForceLoseContext();
return true;
mLastLossWasSimulated = true;
}
bool
void
WebGLContext::RestoreContext()
{
if (!IsContextLost() || !mAllowRestore) {
return false;
if (!IsContextLost())
return ErrorInvalidOperation("restoreContext: Context is not lost.");
if (!mLastLossWasSimulated) {
return ErrorInvalidOperation("restoreContext: Context loss was not simulated."
" Cannot simulate restore.");
}
// If we're currently lost, and the last loss was simulated, then
// we're currently only simulated-lost, allowing us to call
// restoreContext().
if (!mAllowContextRestore)
return ErrorInvalidOperation("restoreContext: Context cannot be restored.");
ForceRestoreContext();
return true;
}
bool

View File

@ -8,33 +8,45 @@
using namespace mozilla;
/* static */ void
WebGLContext::RobustnessTimerCallbackStatic(nsITimer* timer, void *thisPointer) {
static_cast<WebGLContext*>(thisPointer)->RobustnessTimerCallback(timer);
WebGLContext::ContextLossCallbackStatic(nsITimer* timer, void* thisPointer)
{
(void)timer;
WebGLContext* context = static_cast<WebGLContext*>(thisPointer);
context->TerminateContextLossTimer();
context->UpdateContextLossStatus();
}
void
WebGLContext::SetupContextLossTimer() {
WebGLContext::RunContextLossTimer()
{
// If the timer was already running, don't restart it here. Instead,
// wait until the previous call is done, then fire it one more time.
// This is an optimization to prevent unnecessary cross-communication
// between threads.
// This is an optimization to prevent unnecessary
// cross-communication between threads.
if (mContextLossTimerRunning) {
mDrawSinceContextLossTimerSet = true;
mRunContextLossTimerAgain = true;
return;
}
mContextRestorer->InitWithFuncCallback(RobustnessTimerCallbackStatic,
static_cast<void*>(this),
1000,
nsITimer::TYPE_ONE_SHOT);
mContextRestorer->InitWithFuncCallback(ContextLossCallbackStatic,
static_cast<void*>(this),
1000,
nsITimer::TYPE_ONE_SHOT);
mContextLossTimerRunning = true;
mDrawSinceContextLossTimerSet = false;
mRunContextLossTimerAgain = false;
}
void
WebGLContext::TerminateContextLossTimer() {
if (mContextLossTimerRunning) {
mContextRestorer->Cancel();
mContextLossTimerRunning = false;
WebGLContext::TerminateContextLossTimer()
{
if (!mContextLossTimerRunning)
return;
mContextRestorer->Cancel();
mContextLossTimerRunning = false;
if (mRunContextLossTimerAgain) {
RunContextLossTimer();
}
}

View File

@ -21,15 +21,13 @@ WebGLExtensionLoseContext::~WebGLExtensionLoseContext()
void
WebGLExtensionLoseContext::LoseContext()
{
if (!mContext->LoseContext())
mContext->mWebGLError = LOCAL_GL_INVALID_OPERATION;
mContext->LoseContext();
}
void
void
WebGLExtensionLoseContext::RestoreContext()
{
if (!mContext->RestoreContext())
mContext->mWebGLError = LOCAL_GL_INVALID_OPERATION;
mContext->RestoreContext();
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionLoseContext)

View File

@ -99,7 +99,7 @@ function testLosingAndRestoringContext()
// restore the context after this event has exited.
setTimeout(function() {
shouldGenerateGLError(gl, gl.NO_ERROR, "extension.restoreContext()");
// The context should still be lost. It will not get restored until the
// The context should still be lost. It will not get restored until the
// webglrestorecontext event is fired.
shouldBeTrue("gl.isContextLost()");
shouldBe("gl.getError()", "gl.NO_ERROR");

View File

@ -250,12 +250,16 @@ SourceBuffer::SetAppendWindowEnd(double aAppendWindowEnd, ErrorResult& aRv)
void
SourceBuffer::AppendBuffer(const ArrayBuffer& aData, ErrorResult& aRv)
{
aData.ComputeLengthAndData();
AppendData(aData.Data(), aData.Length(), aRv);
}
void
SourceBuffer::AppendBuffer(const ArrayBufferView& aData, ErrorResult& aRv)
{
aData.ComputeLengthAndData();
AppendData(aData.Data(), aData.Length(), aRv);
}

View File

@ -171,6 +171,8 @@ AnalyserNode::GetFloatFrequencyData(const Float32Array& aArray)
return;
}
aArray.ComputeLengthAndData();
float* buffer = aArray.Data();
size_t length = std::min(size_t(aArray.Length()), mOutputBuffer.Length());
@ -189,6 +191,8 @@ AnalyserNode::GetByteFrequencyData(const Uint8Array& aArray)
const double rangeScaleFactor = 1.0 / (mMaxDecibels - mMinDecibels);
aArray.ComputeLengthAndData();
unsigned char* buffer = aArray.Data();
size_t length = std::min(size_t(aArray.Length()), mOutputBuffer.Length());
@ -204,6 +208,8 @@ AnalyserNode::GetByteFrequencyData(const Uint8Array& aArray)
void
AnalyserNode::GetFloatTimeDomainData(const Float32Array& aArray)
{
aArray.ComputeLengthAndData();
float* buffer = aArray.Data();
size_t length = std::min(size_t(aArray.Length()), mBuffer.Length());
@ -215,6 +221,8 @@ AnalyserNode::GetFloatTimeDomainData(const Float32Array& aArray)
void
AnalyserNode::GetByteTimeDomainData(const Uint8Array& aArray)
{
aArray.ComputeLengthAndData();
unsigned char* buffer = aArray.Data();
size_t length = std::min(size_t(aArray.Length()), mBuffer.Length());

View File

@ -130,6 +130,8 @@ void
AudioBuffer::CopyFromChannel(const Float32Array& aDestination, uint32_t aChannelNumber,
uint32_t aStartInChannel, ErrorResult& aRv)
{
aDestination.ComputeLengthAndData();
uint32_t length = aDestination.Length();
CheckedInt<uint32_t> end = aStartInChannel;
end += length;
@ -156,6 +158,8 @@ AudioBuffer::CopyToChannel(JSContext* aJSContext, const Float32Array& aSource,
uint32_t aChannelNumber, uint32_t aStartInChannel,
ErrorResult& aRv)
{
aSource.ComputeLengthAndData();
uint32_t length = aSource.Length();
CheckedInt<uint32_t> end = aStartInChannel;
end += length;

View File

@ -400,6 +400,9 @@ AudioContext::CreatePeriodicWave(const Float32Array& aRealData,
const Float32Array& aImagData,
ErrorResult& aRv)
{
aRealData.ComputeLengthAndData();
aImagData.ComputeLengthAndData();
if (aRealData.Length() != aImagData.Length() ||
aRealData.Length() == 0 ||
aRealData.Length() > 4096) {
@ -434,6 +437,8 @@ AudioContext::DecodeAudioData(const ArrayBuffer& aBuffer,
JSContext* cx = jsapi.cx();
JSAutoCompartment ac(cx, aBuffer.Obj());
aBuffer.ComputeLengthAndData();
// Neuter the array buffer
size_t length = aBuffer.Length();
JS::RootedObject obj(cx, aBuffer.Obj());

View File

@ -55,6 +55,7 @@ public:
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return;
}
aValues.ComputeLengthAndData();
AudioParamTimeline::SetValueCurveAtTime(aValues.Data(), aValues.Length(),
DOMTimeToStreamTime(aStartTime), aDuration, aRv);
mCallback(mNode);

View File

@ -308,6 +308,10 @@ BiquadFilterNode::GetFrequencyResponse(const Float32Array& aFrequencyHz,
const Float32Array& aMagResponse,
const Float32Array& aPhaseResponse)
{
aFrequencyHz.ComputeLengthAndData();
aMagResponse.ComputeLengthAndData();
aPhaseResponse.ComputeLengthAndData();
uint32_t length = std::min(std::min(aFrequencyHz.Length(), aMagResponse.Length()),
aPhaseResponse.Length());
if (!length) {

View File

@ -313,10 +313,14 @@ WaveShaperNode::SetCurve(const Nullable<Float32Array>& aCurve)
{
nsTArray<float> curve;
if (!aCurve.IsNull()) {
mCurve = aCurve.Value().Obj();
const Float32Array& floats = aCurve.Value();
curve.SetLength(aCurve.Value().Length());
PodCopy(curve.Elements(), aCurve.Value().Data(), aCurve.Value().Length());
mCurve = floats.Obj();
floats.ComputeLengthAndData();
curve.SetLength(floats.Length());
PodCopy(curve.Elements(), floats.Data(), floats.Length());
} else {
mCurve = nullptr;
}

View File

@ -27,6 +27,15 @@ GetUserMediaLog()
}
#endif
static PRLogModuleInfo*
GetWebrtcTraceLog()
{
static PRLogModuleInfo *sLog;
if (!sLog)
sLog = PR_NewLogModule("webrtc_trace");
return sLog;
}
#include "MediaEngineWebRTC.h"
#include "ImageContainer.h"
#include "nsIComponentRegistrar.h"
@ -65,6 +74,14 @@ MediaEngineWebRTC::MediaEngineWebRTC(MediaEnginePrefs &aPrefs)
gFarendObserver = new AudioOutputObserver();
}
void
MediaEngineWebRTC::Print(webrtc::TraceLevel level, const char* message, int length)
{
PRLogModuleInfo *log = GetWebrtcTraceLog();
// XXX look at log level?
PR_LOG(log, PR_LOG_DEBUG, ("%s", message));
}
void
MediaEngineWebRTC::EnumerateVideoDevices(nsTArray<nsRefPtr<MediaEngineVideoSource> >* aVSources)
{
@ -130,7 +147,7 @@ MediaEngineWebRTC::EnumerateVideoDevices(nsTArray<nsRefPtr<MediaEngineVideoSourc
}
}
PRLogModuleInfo *logs = GetWebRTCLogInfo();
PRLogModuleInfo *logs = GetWebrtcTraceLog();
if (!gWebrtcTraceLoggingOn && logs && logs->level > 0) {
// no need to a critical section or lock here
gWebrtcTraceLoggingOn = 1;
@ -143,7 +160,11 @@ MediaEngineWebRTC::EnumerateVideoDevices(nsTArray<nsRefPtr<MediaEngineVideoSourc
LOG(("%s Logging webrtc to %s level %d", __FUNCTION__, file, logs->level));
mVideoEngine->SetTraceFilter(logs->level);
mVideoEngine->SetTraceFile(file);
if (strcmp(file, "nspr") == 0) {
mVideoEngine->SetTraceCallback(this);
} else {
mVideoEngine->SetTraceFile(file);
}
}
ptrViEBase = webrtc::ViEBase::GetInterface(mVideoEngine);
@ -263,7 +284,7 @@ MediaEngineWebRTC::EnumerateAudioDevices(nsTArray<nsRefPtr<MediaEngineAudioSourc
}
}
PRLogModuleInfo *logs = GetWebRTCLogInfo();
PRLogModuleInfo *logs = GetWebrtcTraceLog();
if (!gWebrtcTraceLoggingOn && logs && logs->level > 0) {
// no need to a critical section or lock here
gWebrtcTraceLoggingOn = 1;
@ -276,7 +297,11 @@ MediaEngineWebRTC::EnumerateAudioDevices(nsTArray<nsRefPtr<MediaEngineAudioSourc
LOG(("Logging webrtc to %s level %d", __FUNCTION__, file, logs->level));
mVoiceEngine->SetTraceFilter(logs->level);
mVoiceEngine->SetTraceFile(file);
if (strcmp(file, "nspr") == 0) {
mVoiceEngine->SetTraceCallback(this);
} else {
mVoiceEngine->SetTraceFile(file);
}
}
ptrVoEBase = webrtc::VoEBase::GetInterface(mVoiceEngine);
@ -340,13 +365,16 @@ MediaEngineWebRTC::Shutdown()
// This is likely paranoia
MutexAutoLock lock(mMutex);
// Clear callbacks before we go away since the engines may outlive us
if (mVideoEngine) {
mVideoSources.Clear();
mVideoEngine->SetTraceCallback(nullptr);
webrtc::VideoEngine::Delete(mVideoEngine);
}
if (mVoiceEngine) {
mAudioSources.Clear();
mVoiceEngine->SetTraceCallback(nullptr);
webrtc::VoiceEngine::Delete(mVoiceEngine);
}

View File

@ -356,7 +356,8 @@ private:
NullTransport *mNullTransport;
};
class MediaEngineWebRTC : public MediaEngine
class MediaEngineWebRTC : public MediaEngine,
public webrtc::TraceCallback
{
public:
MediaEngineWebRTC(MediaEnginePrefs &aPrefs);
@ -368,6 +369,9 @@ public:
virtual void EnumerateVideoDevices(nsTArray<nsRefPtr<MediaEngineVideoSource> >*);
virtual void EnumerateAudioDevices(nsTArray<nsRefPtr<MediaEngineAudioSource> >*);
// Webrtc trace callbacks for proxying to NSPR
virtual void Print(webrtc::TraceLevel level, const char* message, int length);
private:
~MediaEngineWebRTC() {
Shutdown();

View File

@ -64,12 +64,6 @@ SVGAnimationElement::Init()
//----------------------------------------------------------------------
bool
SVGAnimationElement::PassesConditionalProcessingTests()
{
return SVGTests::PassesConditionalProcessingTests();
}
const nsAttrValue*
SVGAnimationElement::GetAnimAttr(nsIAtom* aName) const
{
@ -313,6 +307,13 @@ SVGAnimationElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
SVGAnimationElementBase::AfterSetAttr(aNamespaceID, aName, aValue,
aNotify);
if (SVGTests::IsConditionalProcessingAttribute(aName)) {
bool isDisabled = !SVGTests::PassesConditionalProcessingTests();
if (mTimedElement.SetIsDisabled(isDisabled)) {
AnimationNeedsResample();
}
}
if (aNamespaceID != kNameSpaceID_XLink || aName != nsGkAtoms::href)
return rv;

View File

@ -58,7 +58,6 @@ public:
virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
const nsAttrValue* aValue, bool aNotify) MOZ_OVERRIDE;
bool PassesConditionalProcessingTests();
const nsAttrValue* GetAnimAttr(nsIAtom* aName) const;
bool GetAnimAttr(nsIAtom* aAttName, nsAString& aResult) const;
bool HasAnimAttr(nsIAtom* aAttName) const;

View File

@ -2716,14 +2716,11 @@ OffThreadScriptReceiverCallback(void *aToken, void *aCallbackData)
nsresult
nsXULPrototypeScript::Compile(JS::SourceBufferHolder& aSrcBuf,
nsIURI* aURI,
uint32_t aLineNo,
nsIURI* aURI, uint32_t aLineNo,
nsIDocument* aDocument,
nsXULPrototypeDocument* aProtoDoc,
nsIOffThreadScriptReceiver *aOffThreadReceiver /* = nullptr */)
{
// We'll compile the script in the compilation scope.
NS_ENSURE_STATE(aProtoDoc);
NS_ENSURE_TRUE(xpc::GetCompilationScope(), NS_ERROR_UNEXPECTED);
AutoSafeJSContext cx;
JSAutoCompartment ac(cx, xpc::GetCompilationScope());
@ -2770,12 +2767,11 @@ nsXULPrototypeScript::Compile(const char16_t* aText,
nsIURI* aURI,
uint32_t aLineNo,
nsIDocument* aDocument,
nsXULPrototypeDocument* aProtoDoc,
nsIOffThreadScriptReceiver *aOffThreadReceiver /* = nullptr */)
{
JS::SourceBufferHolder srcBuf(aText, aTextLength,
JS::SourceBufferHolder::NoOwnership);
return Compile(srcBuf, aURI, aLineNo, aDocument, aProtoDoc, aOffThreadReceiver);
return Compile(srcBuf, aURI, aLineNo, aDocument, aOffThreadReceiver);
}
void

View File

@ -238,13 +238,11 @@ public:
nsresult Compile(JS::SourceBufferHolder& aSrcBuf,
nsIURI* aURI, uint32_t aLineNo,
nsIDocument* aDocument,
nsXULPrototypeDocument* aProtoDoc,
nsIOffThreadScriptReceiver *aOffThreadReceiver = nullptr);
nsresult Compile(const char16_t* aText, int32_t aTextLength,
nsIURI* aURI, uint32_t aLineNo,
nsIDocument* aDocument,
nsXULPrototypeDocument* aProtoDoc,
nsIOffThreadScriptReceiver *aOffThreadReceiver = nullptr);
void UnlinkJSObjects();

View File

@ -3549,10 +3549,7 @@ XULDocument::OnStreamComplete(nsIStreamLoader* aLoader,
mOffThreadCompileStringBuf = nullptr;
mOffThreadCompileStringLength = 0;
rv = mCurrentScriptProto->Compile(srcBuf,
uri, 1, this,
mMasterPrototype,
this);
rv = mCurrentScriptProto->Compile(srcBuf, uri, 1, this, this);
if (NS_SUCCEEDED(rv) && !mCurrentScriptProto->GetScriptObject()) {
// We will be notified via OnOffThreadCompileComplete when the
// compile finishes. Keep the contents of the compiled script

View File

@ -566,7 +566,7 @@ XULContentSinkImpl::HandleEndElement(const char16_t *aName)
script->mOutOfLine = false;
if (doc)
script->Compile(mText, mTextLength, mDocumentURL,
script->mLineNo, doc, mPrototype);
script->mLineNo, doc);
}
FlushText(false);

View File

@ -79,6 +79,7 @@ Crypto::GetRandomValues(JSContext* aCx, const ArrayBufferView& aArray,
return nullptr;
}
aArray.ComputeLengthAndData();
uint32_t dataLen = aArray.Length();
if (dataLen == 0) {
NS_WARNING("ArrayBufferView length is 0, cannot continue");

View File

@ -107,6 +107,7 @@ namespace mozilla {
namespace dom {
static bool sDoNotTrackEnabled = false;
static uint32_t sDoNotTrackValue = 1;
static bool sVibratorEnabled = false;
static uint32_t sMaxVibrateMS = 0;
static uint32_t sMaxVibrateListLen = 0;
@ -118,6 +119,9 @@ Navigator::Init()
Preferences::AddBoolVarCache(&sDoNotTrackEnabled,
"privacy.donottrackheader.enabled",
false);
Preferences::AddUintVarCache(&sDoNotTrackValue,
"privacy.donottrackheader.value",
1);
Preferences::AddBoolVarCache(&sVibratorEnabled,
"dom.vibrator.enabled", true);
Preferences::AddUintVarCache(&sMaxVibrateMS,
@ -621,7 +625,11 @@ NS_IMETHODIMP
Navigator::GetDoNotTrack(nsAString &aResult)
{
if (sDoNotTrackEnabled) {
aResult.AssignLiteral("yes");
if (sDoNotTrackValue == 0) {
aResult.AssignLiteral("0");
} else {
aResult.AssignLiteral("1");
}
} else {
aResult.AssignLiteral("unspecified");
}
@ -784,19 +792,21 @@ Navigator::Vibrate(const nsTArray<uint32_t>& aPattern)
return false;
}
if (aPattern.Length() > sMaxVibrateListLen) {
return false;
nsTArray<uint32_t> pattern(aPattern);
if (pattern.Length() > sMaxVibrateListLen) {
pattern.SetLength(sMaxVibrateMS);
}
for (size_t i = 0; i < aPattern.Length(); ++i) {
if (aPattern[i] > sMaxVibrateMS) {
return false;
for (size_t i = 0; i < pattern.Length(); ++i) {
if (pattern[i] > sMaxVibrateMS) {
pattern[i] = sMaxVibrateMS;
}
}
// The spec says we check sVibratorEnabled after we've done the sanity
// checking on the pattern.
if (aPattern.IsEmpty() || !sVibratorEnabled) {
if (pattern.IsEmpty() || !sVibratorEnabled) {
return true;
}
@ -814,7 +824,7 @@ Navigator::Vibrate(const nsTArray<uint32_t>& aPattern)
}
gVibrateWindowListener = new VibrateWindowListener(mWindow, doc);
hal::Vibrate(aPattern, mWindow);
hal::Vibrate(pattern, mWindow);
return true;
}
@ -1237,8 +1247,10 @@ Navigator::SendBeacon(const nsAString& aUrl,
return false;
}
rv = strStream->SetData(reinterpret_cast<char*>(aData.Value().GetAsArrayBufferView().Data()),
aData.Value().GetAsArrayBufferView().Length());
ArrayBufferView& view = aData.Value().GetAsArrayBufferView();
view.ComputeLengthAndData();
rv = strStream->SetData(reinterpret_cast<char*>(view.Data()),
view.Length());
if (NS_FAILED(rv)) {
aRv.Throw(NS_ERROR_FAILURE);

View File

@ -60,6 +60,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=889335
if (currentTestIdx >= tests.length) {
tearDown();
SimpleTest.finish();
return;
}
tests[currentTestIdx]();

View File

@ -26,7 +26,7 @@ struct TypedArrayObjectStorage : AllTypedArraysBase {
protected:
JSObject* mObj;
TypedArrayObjectStorage()
TypedArrayObjectStorage(JSObject *obj) : mObj(obj)
{
}
@ -55,32 +55,43 @@ private:
* or array buffer object.
*/
template<typename T,
JSObject* UnboxArray(JSObject*, uint32_t*, T**)>
JSObject* UnwrapArray(JSObject*),
void GetLengthAndData(JSObject*, uint32_t*, T**)>
struct TypedArray_base : public TypedArrayObjectStorage {
typedef T element_type;
TypedArray_base(JSObject* obj)
: TypedArrayObjectStorage(obj),
mData(nullptr),
mLength(0),
mComputed(false)
{
DoInit(obj);
MOZ_ASSERT(obj != nullptr);
}
TypedArray_base()
: TypedArrayObjectStorage(nullptr),
mData(nullptr),
mLength(0),
mComputed(false)
{
mObj = nullptr;
}
explicit TypedArray_base(TypedArray_base&& aOther)
: TypedArrayObjectStorage(Move(aOther)),
mData(aOther.mData),
mLength(aOther.mLength)
mLength(aOther.mLength),
mComputed(aOther.mComputed)
{
aOther.mData = nullptr;
aOther.mLength = 0;
aOther.mComputed = false;
}
private:
T* mData;
uint32_t mLength;
mutable T* mData;
mutable uint32_t mLength;
mutable bool mComputed;
public:
inline bool Init(JSObject* obj)
@ -95,12 +106,12 @@ public:
}
inline T *Data() const {
MOZ_ASSERT(inited());
MOZ_ASSERT(mComputed);
return mData;
}
inline uint32_t Length() const {
MOZ_ASSERT(inited());
MOZ_ASSERT(mComputed);
return mLength;
}
@ -115,10 +126,26 @@ public:
JS::MutableHandle<JSObject*>::fromMarkedLocation(&mObj));
}
inline void ComputeLengthAndData() const
{
MOZ_ASSERT(inited());
MOZ_ASSERT(!mComputed);
GetLengthAndData(mObj, &mLength, &mData);
mComputed = true;
}
protected:
inline void DoInit(JSObject* obj)
{
mObj = UnboxArray(obj, &mLength, &mData);
mObj = UnwrapArray(obj);
}
inline void ComputeData() const {
MOZ_ASSERT(inited());
if (!mComputed) {
GetLengthAndData(mObj, &mLength, &mData);
mComputed = true;
}
}
private:
@ -127,20 +154,25 @@ private:
template<typename T,
JSObject* UnwrapArray(JSObject*),
T* GetData(JSObject*),
JSObject* UnboxArray(JSObject*, uint32_t*, T**),
void GetLengthAndData(JSObject*, uint32_t*, T**),
JSObject* CreateNew(JSContext*, uint32_t)>
struct TypedArray : public TypedArray_base<T,UnboxArray> {
TypedArray(JSObject* obj) :
TypedArray_base<T,UnboxArray>(obj)
struct TypedArray : public TypedArray_base<T, UnwrapArray, GetLengthAndData> {
private:
typedef TypedArray_base<T, UnwrapArray, GetLengthAndData> Base;
public:
TypedArray(JSObject* obj)
: Base(obj)
{}
TypedArray() :
TypedArray_base<T,UnboxArray>()
TypedArray()
: Base()
{}
explicit TypedArray(TypedArray&& aOther)
: TypedArray_base<T,UnboxArray>(Move(aOther))
: Base(Move(aOther))
{
}
@ -178,37 +210,37 @@ private:
TypedArray(const TypedArray&) MOZ_DELETE;
};
typedef TypedArray<int8_t, JS_GetInt8ArrayData, JS_GetObjectAsInt8Array,
JS_NewInt8Array>
typedef TypedArray<int8_t, js::UnwrapInt8Array, JS_GetInt8ArrayData,
js::GetInt8ArrayLengthAndData, JS_NewInt8Array>
Int8Array;
typedef TypedArray<uint8_t, JS_GetUint8ArrayData,
JS_GetObjectAsUint8Array, JS_NewUint8Array>
typedef TypedArray<uint8_t, js::UnwrapUint8Array, JS_GetUint8ArrayData,
js::GetUint8ArrayLengthAndData, JS_NewUint8Array>
Uint8Array;
typedef TypedArray<uint8_t, JS_GetUint8ClampedArrayData,
JS_GetObjectAsUint8ClampedArray, JS_NewUint8ClampedArray>
typedef TypedArray<uint8_t, js::UnwrapUint8ClampedArray, JS_GetUint8ClampedArrayData,
js::GetUint8ClampedArrayLengthAndData, JS_NewUint8ClampedArray>
Uint8ClampedArray;
typedef TypedArray<int16_t, JS_GetInt16ArrayData,
JS_GetObjectAsInt16Array, JS_NewInt16Array>
typedef TypedArray<int16_t, js::UnwrapInt16Array, JS_GetInt16ArrayData,
js::GetInt16ArrayLengthAndData, JS_NewInt16Array>
Int16Array;
typedef TypedArray<uint16_t, JS_GetUint16ArrayData,
JS_GetObjectAsUint16Array, JS_NewUint16Array>
typedef TypedArray<uint16_t, js::UnwrapUint16Array, JS_GetUint16ArrayData,
js::GetUint16ArrayLengthAndData, JS_NewUint16Array>
Uint16Array;
typedef TypedArray<int32_t, JS_GetInt32ArrayData,
JS_GetObjectAsInt32Array, JS_NewInt32Array>
typedef TypedArray<int32_t, js::UnwrapInt32Array, JS_GetInt32ArrayData,
js::GetInt32ArrayLengthAndData, JS_NewInt32Array>
Int32Array;
typedef TypedArray<uint32_t, JS_GetUint32ArrayData,
JS_GetObjectAsUint32Array, JS_NewUint32Array>
typedef TypedArray<uint32_t, js::UnwrapUint32Array, JS_GetUint32ArrayData,
js::GetUint32ArrayLengthAndData, JS_NewUint32Array>
Uint32Array;
typedef TypedArray<float, JS_GetFloat32ArrayData,
JS_GetObjectAsFloat32Array, JS_NewFloat32Array>
typedef TypedArray<float, js::UnwrapFloat32Array, JS_GetFloat32ArrayData,
js::GetFloat32ArrayLengthAndData, JS_NewFloat32Array>
Float32Array;
typedef TypedArray<double, JS_GetFloat64ArrayData,
JS_GetObjectAsFloat64Array, JS_NewFloat64Array>
typedef TypedArray<double, js::UnwrapFloat64Array, JS_GetFloat64ArrayData,
js::GetFloat64ArrayLengthAndData, JS_NewFloat64Array>
Float64Array;
typedef TypedArray_base<uint8_t, JS_GetObjectAsArrayBufferView>
typedef TypedArray_base<uint8_t, js::UnwrapArrayBufferView, js::GetArrayBufferViewLengthAndData>
ArrayBufferView;
typedef TypedArray<uint8_t, JS_GetArrayBufferData,
JS_GetObjectAsArrayBuffer, JS_NewArrayBuffer>
typedef TypedArray<uint8_t, js::UnwrapArrayBuffer, JS_GetArrayBufferData,
js::GetArrayBufferLengthAndData, JS_NewArrayBuffer>
ArrayBuffer;
// A class for converting an nsTArray to a TypedArray

View File

@ -233,12 +233,6 @@ RemoveObserversExceptBluetoothManager
return PL_DHASH_NEXT;
}
void
BluetoothService::RemoveObserverFromTable(const nsAString& key)
{
mBluetoothSignalObserverTable.Remove(key);
}
// static
BluetoothService*
BluetoothService::Create()

View File

@ -308,9 +308,6 @@ public:
bool
IsToggling() const;
void
RemoveObserverFromTable(const nsAString& key);
/**
* Below 2 function/variable are used for ensuring event 'AdapterAdded' will
* be fired after event 'Enabled'.

View File

@ -233,12 +233,6 @@ RemoveObserversExceptBluetoothManager
return PL_DHASH_NEXT;
}
void
BluetoothService::RemoveObserverFromTable(const nsAString& key)
{
mBluetoothSignalObserverTable.Remove(key);
}
// static
BluetoothService*
BluetoothService::Create()

View File

@ -308,9 +308,6 @@ public:
bool
IsToggling() const;
void
RemoveObserverFromTable(const nsAString& key);
/**
* Below 2 function/variable are used for ensuring event 'AdapterAdded' will
* be fired after event 'Enabled'.

View File

@ -26,12 +26,14 @@ CryptoBuffer::Assign(const SECItem* aItem)
uint8_t*
CryptoBuffer::Assign(const ArrayBuffer& aData)
{
aData.ComputeLengthAndData();
return Assign(aData.Data(), aData.Length());
}
uint8_t*
CryptoBuffer::Assign(const ArrayBufferView& aData)
{
aData.ComputeLengthAndData();
return Assign(aData.Data(), aData.Length());
}

View File

@ -28,10 +28,12 @@ public:
uint8_t* Assign(const OwningArrayBufferViewOrArrayBuffer& aData);
template<typename T,
JSObject* UnboxArray(JSObject*, uint32_t*, T**)>
uint8_t* Assign(const TypedArray_base<T, UnboxArray>& aData)
JSObject* UnwrapArray(JSObject*),
void GetLengthAndData(JSObject*, uint32_t*, T**)>
uint8_t* Assign(const TypedArray_base<T, UnwrapArray, GetLengthAndData>& aArray)
{
return Assign(aData.Data(), aData.Length());
aArray.ComputeLengthAndData();
return Assign(aArray.Data(), aArray.Length());
}

View File

@ -107,6 +107,7 @@ public:
const TextDecodeOptions& aOptions,
nsAString& aOutDecodedString,
ErrorResult& aRv) {
aView.ComputeLengthAndData();
Decode(reinterpret_cast<char*>(aView.Data()), aView.Length(),
aOptions.mStream, aOutDecodedString, aRv);
}

View File

@ -756,6 +756,7 @@ already_AddRefed<nsIInputStream>
LockedFile::GetInputStream(const ArrayBuffer& aValue, uint64_t* aInputLength,
ErrorResult& aRv)
{
aValue.ComputeLengthAndData();
const char* data = reinterpret_cast<const char*>(aValue.Data());
uint32_t length = aValue.Length();

View File

@ -112,9 +112,11 @@ Directory::CreateFile(const nsAString& aPath, const CreateFileOptions& aOptions)
str.Length());
} else if (data.IsArrayBuffer()) {
ArrayBuffer& buffer = data.GetAsArrayBuffer();
buffer.ComputeLengthAndData();
arrayData.AppendElements(buffer.Data(), buffer.Length());
} else if (data.IsArrayBufferView()){
ArrayBufferView& view = data.GetAsArrayBufferView();
view.ComputeLengthAndData();
arrayData.AppendElements(view.Data(), view.Length());
} else {
blobData = data.GetAsBlob();

View File

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const TIMEUPDATE_TIMEOUT_LENGTH = 10000;
const ENDED_TIMEOUT_LENGTH = 10000;
const ENDED_TIMEOUT_LENGTH = 30000;
/* Time we wait for the canplaythrough event to fire
* Note: this needs to be at least 30s because the

View File

@ -5,7 +5,7 @@
#include "nsISupports.idl"
#include "nsIDOMSmsSegmentInfo.idl"
[scriptable, uuid(41db87b0-b0a1-11e3-a04f-cf487d837ee3)]
[scriptable, uuid(0e6f8ace-cc59-11e3-aad5-e32847abfda1)]
interface nsIMobileMessageCallback : nsISupports
{
/**
@ -30,7 +30,7 @@ interface nsIMobileMessageCallback : nsISupports
* |message| can be nsIDOMMoz{Mms,Sms}Message.
*/
void notifyMessageSent(in nsISupports message);
void notifySendMessageFailed(in long error);
void notifySendMessageFailed(in long error, in nsISupports message);
/**
* |message| can be nsIDOMMoz{Mms,Sms}Message.

View File

@ -0,0 +1,71 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=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 "DOMMobileMessageError.h"
#include "mozilla/dom/DOMMobileMessageErrorBinding.h"
#include "mozilla/dom/UnionTypes.h"
#include "nsIDOMMozMmsMessage.h"
#include "nsIDOMMozSmsMessage.h"
using namespace mozilla::dom;
NS_IMPL_CYCLE_COLLECTION_CLASS(DOMMobileMessageError)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(DOMMobileMessageError, DOMError)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSms)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMms)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(DOMMobileMessageError, DOMError)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSms)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMms)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(DOMMobileMessageError)
NS_INTERFACE_MAP_END_INHERITING(DOMError)
NS_IMPL_ADDREF_INHERITED(DOMMobileMessageError, DOMError)
NS_IMPL_RELEASE_INHERITED(DOMMobileMessageError, DOMError)
DOMMobileMessageError::DOMMobileMessageError(nsPIDOMWindow* aWindow,
const nsAString& aName,
nsIDOMMozSmsMessage* aSms)
: DOMError(aWindow, aName)
, mSms(aSms)
, mMms(nullptr)
{
}
DOMMobileMessageError::DOMMobileMessageError(nsPIDOMWindow* aWindow,
const nsAString& aName,
nsIDOMMozMmsMessage* aMms)
: DOMError(aWindow, aName)
, mSms(nullptr)
, mMms(aMms)
{
}
void
DOMMobileMessageError::GetData(OwningMozSmsMessageOrMozMmsMessage& aRetVal) const
{
if (mSms) {
aRetVal.SetAsMozSmsMessage() = mSms;
return;
}
if (mMms) {
aRetVal.SetAsMozMmsMessage() = mMms;
return;
}
MOZ_ASSUME_UNREACHABLE("Bad object with invalid mSms and mMms.");
}
JSObject*
DOMMobileMessageError::WrapObject(JSContext* aCx)
{
return DOMMobileMessageErrorBinding::Wrap(aCx, this);
}

View File

@ -0,0 +1,45 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=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_MobileMessageError_h
#define mozilla_dom_MobileMessageError_h
#include "mozilla/dom/DOMError.h"
class nsIDOMMozMmsMessage;
class nsIDOMMozSmsMessage;
namespace mozilla {
namespace dom {
class OwningMozSmsMessageOrMozMmsMessage;
class DOMMobileMessageError MOZ_FINAL : public DOMError
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DOMMobileMessageError, DOMError)
DOMMobileMessageError(nsPIDOMWindow* aWindow, const nsAString& aName,
nsIDOMMozSmsMessage* aSms);
DOMMobileMessageError(nsPIDOMWindow* aWindow, const nsAString& aName,
nsIDOMMozMmsMessage* aMms);
virtual JSObject*
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
void GetData(OwningMozSmsMessageOrMozMmsMessage& aRetVal) const;
private:
nsCOMPtr<nsIDOMMozSmsMessage> mSms;
nsCOMPtr<nsIDOMMozMmsMessage> mMms;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_MobileMessageError_h

View File

@ -16,11 +16,57 @@
#include "xpcpublic.h"
#include "nsServiceManagerUtils.h"
#include "nsTArrayHelpers.h"
#include "DOMMobileMessageError.h"
namespace mozilla {
namespace dom {
namespace mobilemessage {
static nsAutoString
ConvertErrorCodeToErrorString(int32_t aError)
{
nsAutoString errorStr;
switch (aError) {
case nsIMobileMessageCallback::NO_SIGNAL_ERROR:
errorStr = NS_LITERAL_STRING("NoSignalError");
break;
case nsIMobileMessageCallback::NOT_FOUND_ERROR:
errorStr = NS_LITERAL_STRING("NotFoundError");
break;
case nsIMobileMessageCallback::UNKNOWN_ERROR:
errorStr = NS_LITERAL_STRING("UnknownError");
break;
case nsIMobileMessageCallback::INTERNAL_ERROR:
errorStr = NS_LITERAL_STRING("InternalError");
break;
case nsIMobileMessageCallback::NO_SIM_CARD_ERROR:
errorStr = NS_LITERAL_STRING("NoSimCardError");
break;
case nsIMobileMessageCallback::RADIO_DISABLED_ERROR:
errorStr = NS_LITERAL_STRING("RadioDisabledError");
break;
case nsIMobileMessageCallback::INVALID_ADDRESS_ERROR:
errorStr = NS_LITERAL_STRING("InvalidAddressError");
break;
case nsIMobileMessageCallback::FDN_CHECK_ERROR:
errorStr = NS_LITERAL_STRING("FdnCheckError");
break;
case nsIMobileMessageCallback::NON_ACTIVE_SIM_CARD_ERROR:
errorStr = NS_LITERAL_STRING("NonActiveSimCardError");
break;
case nsIMobileMessageCallback::STORAGE_FULL_ERROR:
errorStr = NS_LITERAL_STRING("StorageFullError");
break;
case nsIMobileMessageCallback::SIM_NOT_MATCHED_ERROR:
errorStr = NS_LITERAL_STRING("SimNotMatchedError");
break;
default: // SUCCESS_NO_ERROR is handled above.
MOZ_CRASH("Should never get here!");
}
return errorStr;
}
NS_IMPL_ADDREF(MobileMessageCallback)
NS_IMPL_RELEASE(MobileMessageCallback)
@ -78,56 +124,26 @@ MobileMessageCallback::NotifySuccess(nsISupports *aMessage, bool aAsync)
}
nsresult
MobileMessageCallback::NotifyError(int32_t aError, bool aAsync)
MobileMessageCallback::NotifyError(int32_t aError, DOMError *aDetailedError, bool aAsync)
{
nsAutoString errorStr;
switch (aError) {
case nsIMobileMessageCallback::NO_SIGNAL_ERROR:
errorStr = NS_LITERAL_STRING("NoSignalError");
break;
case nsIMobileMessageCallback::NOT_FOUND_ERROR:
errorStr = NS_LITERAL_STRING("NotFoundError");
break;
case nsIMobileMessageCallback::UNKNOWN_ERROR:
errorStr = NS_LITERAL_STRING("UnknownError");
break;
case nsIMobileMessageCallback::INTERNAL_ERROR:
errorStr = NS_LITERAL_STRING("InternalError");
break;
case nsIMobileMessageCallback::NO_SIM_CARD_ERROR:
errorStr = NS_LITERAL_STRING("NoSimCardError");
break;
case nsIMobileMessageCallback::RADIO_DISABLED_ERROR:
errorStr = NS_LITERAL_STRING("RadioDisabledError");
break;
case nsIMobileMessageCallback::INVALID_ADDRESS_ERROR:
errorStr = NS_LITERAL_STRING("InvalidAddressError");
break;
case nsIMobileMessageCallback::FDN_CHECK_ERROR:
errorStr = NS_LITERAL_STRING("FdnCheckError");
break;
case nsIMobileMessageCallback::NON_ACTIVE_SIM_CARD_ERROR:
errorStr = NS_LITERAL_STRING("NonActiveSimCardError");
break;
case nsIMobileMessageCallback::STORAGE_FULL_ERROR:
errorStr = NS_LITERAL_STRING("StorageFullError");
break;
case nsIMobileMessageCallback::SIM_NOT_MATCHED_ERROR:
errorStr = NS_LITERAL_STRING("SimNotMatchedError");
break;
default: // SUCCESS_NO_ERROR is handled above.
MOZ_CRASH("Should never get here!");
}
if (aAsync) {
NS_ASSERTION(!aDetailedError,
"No Support to FireDetailedErrorAsync() in nsIDOMRequestService!");
nsCOMPtr<nsIDOMRequestService> rs =
do_GetService(DOMREQUEST_SERVICE_CONTRACTID);
NS_ENSURE_TRUE(rs, NS_ERROR_FAILURE);
return rs->FireErrorAsync(mDOMRequest, errorStr);
return rs->FireErrorAsync(mDOMRequest,
ConvertErrorCodeToErrorString(aError));
}
if (aDetailedError) {
mDOMRequest->FireDetailedError(aDetailedError);
} else {
mDOMRequest->FireError(ConvertErrorCodeToErrorString(aError));
}
mDOMRequest->FireError(errorStr);
return NS_OK;
}
@ -138,9 +154,25 @@ MobileMessageCallback::NotifyMessageSent(nsISupports *aMessage)
}
NS_IMETHODIMP
MobileMessageCallback::NotifySendMessageFailed(int32_t aError)
MobileMessageCallback::NotifySendMessageFailed(int32_t aError, nsISupports *aMessage)
{
return NotifyError(aError);
nsRefPtr<DOMMobileMessageError> domMobileMessageError;
if (aMessage) {
nsAutoString errorStr = ConvertErrorCodeToErrorString(aError);
nsCOMPtr<nsIDOMMozSmsMessage> smsMsg = do_QueryInterface(aMessage);
if (smsMsg) {
domMobileMessageError =
new DOMMobileMessageError(mDOMRequest->GetOwner(), errorStr, smsMsg);
}
else {
nsCOMPtr<nsIDOMMozMmsMessage> mmsMsg = do_QueryInterface(aMessage);
domMobileMessageError =
new DOMMobileMessageError(mDOMRequest->GetOwner(), errorStr, mmsMsg);
}
NS_ASSERTION(domMobileMessageError, "Invalid DOMMobileMessageError!");
}
return NotifyError(aError, domMobileMessageError);
}
NS_IMETHODIMP
@ -211,7 +243,7 @@ MobileMessageCallback::NotifySegmentInfoForTextGot(nsIDOMMozSmsSegmentInfo *aInf
NS_IMETHODIMP
MobileMessageCallback::NotifyGetSegmentInfoForTextFailed(int32_t aError)
{
return NotifyError(aError, true);
return NotifyError(aError, nullptr, true);
}
NS_IMETHODIMP

View File

@ -31,7 +31,7 @@ private:
nsresult NotifySuccess(JS::Handle<JS::Value> aResult, bool aAsync = false);
nsresult NotifySuccess(nsISupports *aMessage, bool aAsync = false);
nsresult NotifyError(int32_t aError, bool aAsync = false);
nsresult NotifyError(int32_t aError, DOMError *aDetailedError = nullptr, bool aAsync = false);
};
} // namespace mobilemessage

View File

@ -1955,8 +1955,7 @@ MmsService.prototype = {
.setMessageReadStatusByEnvelopeId(envelopeId, address, readStatus,
(function(aRv, aDomMessage) {
if (!Components.isSuccessCode(aRv)) {
// Notifying observers the read status is error.
Services.obs.notifyObservers(aDomMessage, kSmsReadSuccessObserverTopic, null);
if (DEBUG) debug("Failed to update read status: " + aRv);
return;
}
@ -2171,7 +2170,7 @@ MmsService.prototype = {
// If the messsage has been deleted (because the sending process is
// cancelled), we don't need to reset the its delievery state/status.
if (aErrorCode == Ci.nsIMobileMessageCallback.NOT_FOUND_ERROR) {
aRequest.notifySendMessageFailed(aErrorCode);
aRequest.notifySendMessageFailed(aErrorCode, aDomMessage);
Services.obs.notifyObservers(aDomMessage, kSmsFailedObserverTopic, null);
return;
}
@ -2188,7 +2187,7 @@ MmsService.prototype = {
// TODO bug 832140 handle !Components.isSuccessCode(aRv)
if (!isSentSuccess) {
if (DEBUG) debug("Sending MMS failed.");
aRequest.notifySendMessageFailed(aErrorCode);
aRequest.notifySendMessageFailed(aErrorCode, aDomMessage);
Services.obs.notifyObservers(aDomMessage, kSmsFailedObserverTopic, null);
return;
}
@ -2214,7 +2213,8 @@ MmsService.prototype = {
if (!Components.isSuccessCode(aRv)) {
if (DEBUG) debug("Error! Fail to save sending message! rv = " + aRv);
aRequest.notifySendMessageFailed(
gMobileMessageDatabaseService.translateCrErrorToMessageCallbackError(aRv));
gMobileMessageDatabaseService.translateCrErrorToMessageCallbackError(aRv),
aDomMessage);
Services.obs.notifyObservers(aDomMessage, kSmsFailedObserverTopic, null);
return;
}

View File

@ -8,6 +8,8 @@ include protocol PSms;
include protocol PBlob;
include SmsTypes;
using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
namespace mozilla {
namespace dom {
namespace mobilemessage {
@ -28,9 +30,16 @@ struct ReplyMessageSend
MobileMessageData messageData;
};
union OptionalMobileMessageData
{
void_t;
MobileMessageData;
};
struct ReplyMessageSendFail
{
int32_t error;
OptionalMobileMessageData messageData;
};
struct ReplyGetMessage

View File

@ -191,8 +191,18 @@ SmsRequestChild::Recv__delete__(const MessageReply& aReply)
mReplyRequest->NotifyMessageSent(msg);
}
break;
case MessageReply::TReplyMessageSendFail:
mReplyRequest->NotifySendMessageFailed(aReply.get_ReplyMessageSendFail().error());
case MessageReply::TReplyMessageSendFail: {
const ReplyMessageSendFail &replyFail = aReply.get_ReplyMessageSendFail();
nsCOMPtr<nsISupports> msg;
if (replyFail.messageData().type() ==
OptionalMobileMessageData::TMobileMessageData) {
msg = CreateMessageFromMessageData(
replyFail.messageData().get_MobileMessageData());
}
mReplyRequest->NotifySendMessageFailed(replyFail.error(), msg);
}
break;
case MessageReply::TReplyGetMessage: {
const MobileMessageData& data =

View File

@ -126,6 +126,40 @@ GetParamsFromSendMmsMessageRequest(JSContext* aCx,
return true;
}
static bool
GetMobileMessageDataFromMessage(ContentParent* aParent,
nsISupports *aMsg,
MobileMessageData &aData)
{
if (!aMsg) {
NS_WARNING("Invalid message to convert!");
return false;
}
nsCOMPtr<nsIDOMMozMmsMessage> mmsMsg = do_QueryInterface(aMsg);
if (mmsMsg) {
if (!aParent) {
NS_ERROR("Invalid ContentParent to convert MMS Message!");
return false;
}
MmsMessageData data;
if (!static_cast<MmsMessage*>(mmsMsg.get())->GetData(aParent, data)) {
return false;
}
aData = data;
return true;
}
nsCOMPtr<nsIDOMMozSmsMessage> smsMsg = do_QueryInterface(aMsg);
if (smsMsg) {
aData = static_cast<SmsMessage*>(smsMsg.get())->GetData();
return true;
}
NS_WARNING("Cannot get MobileMessageData");
return false;
}
NS_IMPL_ISUPPORTS(SmsParent, nsIObserver)
SmsParent::SmsParent()
@ -172,9 +206,11 @@ NS_IMETHODIMP
SmsParent::Observe(nsISupports* aSubject, const char* aTopic,
const char16_t* aData)
{
ContentParent *parent = static_cast<ContentParent*>(Manager());
if (!strcmp(aTopic, kSmsReceivedObserverTopic)) {
MobileMessageData msgData;
if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
if (!GetMobileMessageDataFromMessage(parent, aSubject, msgData)) {
NS_ERROR("Got a 'sms-received' topic without a valid message!");
return NS_OK;
}
@ -185,7 +221,7 @@ SmsParent::Observe(nsISupports* aSubject, const char* aTopic,
if (!strcmp(aTopic, kSmsRetrievingObserverTopic)) {
MobileMessageData msgData;
if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
if (!GetMobileMessageDataFromMessage(parent, aSubject, msgData)) {
NS_ERROR("Got a 'sms-retrieving' topic without a valid message!");
return NS_OK;
}
@ -196,7 +232,7 @@ SmsParent::Observe(nsISupports* aSubject, const char* aTopic,
if (!strcmp(aTopic, kSmsSendingObserverTopic)) {
MobileMessageData msgData;
if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
if (!GetMobileMessageDataFromMessage(parent, aSubject, msgData)) {
NS_ERROR("Got a 'sms-sending' topic without a valid message!");
return NS_OK;
}
@ -207,7 +243,7 @@ SmsParent::Observe(nsISupports* aSubject, const char* aTopic,
if (!strcmp(aTopic, kSmsSentObserverTopic)) {
MobileMessageData msgData;
if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
if (!GetMobileMessageDataFromMessage(parent, aSubject, msgData)) {
NS_ERROR("Got a 'sms-sent' topic without a valid message!");
return NS_OK;
}
@ -218,7 +254,7 @@ SmsParent::Observe(nsISupports* aSubject, const char* aTopic,
if (!strcmp(aTopic, kSmsFailedObserverTopic)) {
MobileMessageData msgData;
if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
if (!GetMobileMessageDataFromMessage(parent, aSubject, msgData)) {
NS_ERROR("Got a 'sms-failed' topic without a valid message!");
return NS_OK;
}
@ -229,7 +265,7 @@ SmsParent::Observe(nsISupports* aSubject, const char* aTopic,
if (!strcmp(aTopic, kSmsDeliverySuccessObserverTopic)) {
MobileMessageData msgData;
if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
if (!GetMobileMessageDataFromMessage(parent, aSubject, msgData)) {
NS_ERROR("Got a 'sms-sending' topic without a valid message!");
return NS_OK;
}
@ -240,7 +276,7 @@ SmsParent::Observe(nsISupports* aSubject, const char* aTopic,
if (!strcmp(aTopic, kSmsDeliveryErrorObserverTopic)) {
MobileMessageData msgData;
if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
if (!GetMobileMessageDataFromMessage(parent, aSubject, msgData)) {
NS_ERROR("Got a 'sms-delivery-error' topic without a valid message!");
return NS_OK;
}
@ -267,10 +303,9 @@ SmsParent::Observe(nsISupports* aSubject, const char* aTopic,
return NS_OK;
}
if (!strcmp(aTopic, kSmsReadSuccessObserverTopic)) {
MobileMessageData msgData;
if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
if (!GetMobileMessageDataFromMessage(parent, aSubject, msgData)) {
NS_ERROR("Got a 'sms-read-success' topic without a valid message!");
return NS_OK;
}
@ -281,7 +316,7 @@ SmsParent::Observe(nsISupports* aSubject, const char* aTopic,
if (!strcmp(aTopic, kSmsReadErrorObserverTopic)) {
MobileMessageData msgData;
if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
if (!GetMobileMessageDataFromMessage(parent, aSubject, msgData)) {
NS_ERROR("Got a 'sms-read-error' topic without a valid message!");
return NS_OK;
}
@ -294,31 +329,6 @@ SmsParent::Observe(nsISupports* aSubject, const char* aTopic,
return NS_OK;
}
bool
SmsParent::GetMobileMessageDataFromMessage(nsISupports *aMsg,
MobileMessageData &aData)
{
nsCOMPtr<nsIDOMMozMmsMessage> mmsMsg = do_QueryInterface(aMsg);
if (mmsMsg) {
MmsMessageData data;
ContentParent *parent = static_cast<ContentParent*>(Manager());
if (!static_cast<MmsMessage*>(mmsMsg.get())->GetData(parent, data)) {
return false;
}
aData = data;
return true;
}
nsCOMPtr<nsIDOMMozSmsMessage> smsMsg = do_QueryInterface(aMsg);
if (smsMsg) {
aData = static_cast<SmsMessage*>(smsMsg.get())->GetData();
return true;
}
NS_WARNING("Cannot get MobileMessageData");
return false;
}
bool
SmsParent::RecvAddSilentNumber(const nsString& aNumber)
{
@ -619,30 +629,27 @@ SmsRequestParent::NotifyMessageSent(nsISupports *aMessage)
{
NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE);
nsCOMPtr<nsIDOMMozMmsMessage> mms = do_QueryInterface(aMessage);
if (mms) {
MmsMessage *msg = static_cast<MmsMessage*>(mms.get());
ContentParent *parent = static_cast<ContentParent*>(Manager()->Manager());
MmsMessageData data;
if (!msg->GetData(parent, data)) {
return NS_ERROR_FAILURE;
}
return SendReply(ReplyMessageSend(MobileMessageData(data)));
}
nsCOMPtr<nsIDOMMozSmsMessage> sms = do_QueryInterface(aMessage);
if (sms) {
SmsMessage* msg = static_cast<SmsMessage*>(sms.get());
return SendReply(ReplyMessageSend(MobileMessageData(msg->GetData())));
ContentParent *parent = static_cast<ContentParent*>(Manager()->Manager());
MobileMessageData data;
if (GetMobileMessageDataFromMessage(parent, aMessage, data)) {
return SendReply(ReplyMessageSend(data));
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
SmsRequestParent::NotifySendMessageFailed(int32_t aError)
SmsRequestParent::NotifySendMessageFailed(int32_t aError, nsISupports *aMessage)
{
return SendReply(ReplyMessageSendFail(aError));
NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE);
ContentParent *parent = static_cast<ContentParent*>(Manager()->Manager());
MobileMessageData data;
if (!GetMobileMessageDataFromMessage(parent, aMessage, data)) {
return SendReply(ReplyMessageSendFail(aError, OptionalMobileMessageData(void_t())));
}
return SendReply(ReplyMessageSendFail(aError, OptionalMobileMessageData(data)));
}
NS_IMETHODIMP
@ -650,21 +657,10 @@ SmsRequestParent::NotifyMessageGot(nsISupports *aMessage)
{
NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE);
nsCOMPtr<nsIDOMMozMmsMessage> mms = do_QueryInterface(aMessage);
if (mms) {
MmsMessage *msg = static_cast<MmsMessage*>(mms.get());
ContentParent *parent = static_cast<ContentParent*>(Manager()->Manager());
MmsMessageData data;
if (!msg->GetData(parent, data)) {
return NS_ERROR_FAILURE;
}
return SendReply(ReplyGetMessage(MobileMessageData(data)));
}
nsCOMPtr<nsIDOMMozSmsMessage> sms = do_QueryInterface(aMessage);
if (sms) {
SmsMessage* msg = static_cast<SmsMessage*>(sms.get());
return SendReply(ReplyGetMessage(MobileMessageData(msg->GetData())));
ContentParent *parent = static_cast<ContentParent*>(Manager()->Manager());
MobileMessageData data;
if (GetMobileMessageDataFromMessage(parent, aMessage, data)) {
return SendReply(ReplyGetMessage(data));
}
return NS_ERROR_FAILURE;

View File

@ -66,9 +66,6 @@ protected:
virtual bool
DeallocPMobileMessageCursorParent(PMobileMessageCursorParent* aActor) MOZ_OVERRIDE;
bool
GetMobileMessageDataFromMessage(nsISupports* aMsg, MobileMessageData& aData);
private:
nsTArray<nsString> mSilentNumbers;
};

View File

@ -37,6 +37,7 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and CONFIG['MOZ_B2G_RIL']:
]
EXPORTS.mozilla.dom += [
'DOMMobileMessageError.h',
'MmsMessage.h',
'MobileMessageManager.h',
'SmsFilter.h',
@ -46,6 +47,7 @@ EXPORTS.mozilla.dom += [
UNIFIED_SOURCES += [
'Constants.cpp',
'DOMMobileMessageError.cpp',
'ipc/SmsChild.cpp',
'ipc/SmsIPCService.cpp',
'ipc/SmsParent.cpp',

View File

@ -70,6 +70,33 @@ function waitForManagerEvent(aEventName) {
return deferred.promise;
}
/**
* Wrap DOMRequest onsuccess/onerror events to Promise resolve/reject.
*
* Fulfill params: A DOMEvent.
* Reject params: A DOMEvent.
*
* @param aRequest
* A DOMRequest instance.
*
* @return A deferred promise.
*/
function wrapDomRequestAsPromise(aRequest) {
let deferred = Promise.defer();
ok(aRequest instanceof DOMRequest,
"aRequest is instanceof " + aRequest.constructor);
aRequest.addEventListener("success", function(aEvent) {
deferred.resolve(aEvent);
});
aRequest.addEventListener("error", function(aEvent) {
deferred.reject(aEvent);
});
return deferred.promise;
}
/**
* Send a SMS message to a single receiver. Resolve if it succeeds, reject
* otherwise.
@ -86,17 +113,42 @@ function waitForManagerEvent(aEventName) {
* @return A deferred promise.
*/
function sendSmsWithSuccess(aReceiver, aText) {
let deferred = Promise.defer();
let request = manager.send(aReceiver, aText);
return wrapDomRequestAsPromise(request)
.then((aEvent) => { return aEvent.target.result; },
(aEvent) => { throw aEvent.target.error; });
}
/**
* Send a SMS message to a single receiver.
* Resolve if it fails, reject otherwise.
*
* Fulfill params:
* {
* message, -- the failed MmsMessage
* error, -- error of the send request
* }
*
* Reject params: (none)
*
* @param aReceiver the address of the receiver.
* @param aText the text body of the message.
*
* @return A deferred promise.
*/
function sendSmsWithFailure(aReceiver, aText) {
let promises = [];
promises.push(waitForManagerEvent("failed")
.then((aEvent) => { return aEvent.message; }));
let request = manager.send(aReceiver, aText);
request.onsuccess = function(event) {
deferred.resolve(event.target.result);
};
request.onerror = function(event) {
deferred.reject(event.target.error);
};
promises.push(wrapDomRequestAsPromise(request)
.then((aEvent) => { throw aEvent; },
(aEvent) => { return aEvent.target.error; }));
return deferred.promise;
return Promise.all(promises)
.then((aResults) => { return { message: aResults[0],
error: aResults[1] }; });
}
/**
@ -118,30 +170,18 @@ function sendSmsWithSuccess(aReceiver, aText) {
* @return A deferred promise.
*/
function sendMmsWithFailure(aMmsParameters, aSendParameters) {
let deferred = Promise.defer();
let result = { message: null, error: null };
function got(which, value) {
result[which] = value;
if (result.message != null && result.error != null) {
deferred.resolve(result);
}
}
manager.addEventListener("failed", function onfailed(event) {
manager.removeEventListener("failed", onfailed);
got("message", event.message);
});
let promises = [];
promises.push(waitForManagerEvent("failed")
.then((aEvent) => { return aEvent.message; }));
let request = manager.sendMMS(aMmsParameters, aSendParameters);
request.onsuccess = function(event) {
deferred.reject();
};
request.onerror = function(event) {
got("error", event.target.error);
}
promises.push(wrapDomRequestAsPromise(request)
.then((aEvent) => { throw aEvent; },
(aEvent) => { return aEvent.target.error; }));
return deferred.promise;
return Promise.all(promises)
.then((aResults) => { return { message: aResults[0],
error: aResults[1] }; });
}
/**
@ -272,15 +312,9 @@ function deleteMessagesById(aMessageIds) {
return [];
}
let deferred = Promise.defer();
let request = manager.delete(aMessageIds);
request.onsuccess = function(event) {
deferred.resolve(event.target.result);
};
request.onerror = deferred.reject.bind(deferred);
return deferred.promise;
return wrapDomRequestAsPromise(request)
.then((aEvent) => { return aEvent.target.result; });
}
/**

View File

@ -49,3 +49,4 @@ qemu = true
[test_mt_sms_concatenation.js]
[test_error_of_mms_manual_retrieval.js]
[test_error_of_mms_send.js]
[test_error_of_sms_send.js]

View File

@ -14,13 +14,31 @@ function testSendFailed(aCause, aServiceId) {
sendParameters = { serviceId: aServiceId };
}
let mmsParameters = { subject: "Test",
receivers: ["+0987654321"],
let testSubject = "Test";
let testReceivers = ["+0987654321"];
let mmsParameters = { subject: testSubject,
receivers: testReceivers,
attachments: [] };
return sendMmsWithFailure(mmsParameters, sendParameters)
.then((result) => {
is(result.error.name, aCause, "Checking failure cause.");
let domMessage = result.error.data;
is(domMessage.id, result.message.id, "Checking message id.");
is(domMessage.subject, testSubject, "Checking subject.");
is(domMessage.receivers.length, testReceivers.length, "Checking no. of receivers.");
for (let i = 0; i < testReceivers.length; i++) {
is(domMessage.receivers[i], testReceivers[i], "Checking receiver address.");
}
let deliveryInfo = domMessage.deliveryInfo;
is(deliveryInfo.length, testReceivers.length, "Checking no. of deliveryInfo.");
for (let i = 0; i < deliveryInfo.length; i++) {
is(deliveryInfo[i].receiver, testReceivers[i], "Checking receiver address.");
is(deliveryInfo[i].deliveryStatus, "error", "Checking deliveryStatus.");
}
});
}

View File

@ -0,0 +1,105 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = 'head.js';
const kPrefRilRadioDisabled = "ril.radio.disabled";
let connection;
function ensureMobileConnection() {
let deferred = Promise.defer();
let permissions = [{
"type": "mobileconnection",
"allow": true,
"context": document,
}];
SpecialPowers.pushPermissions(permissions, function() {
ok(true, "permissions pushed: " + JSON.stringify(permissions));
connection = window.navigator.mozMobileConnections[0];
if (connection) {
log("navigator.mozMobileConnections[0] is instance of " + connection.constructor);
} else {
log("navigator.mozMobileConnections[0] is undefined.");
}
if (connection instanceof MozMobileConnection) {
deferred.resolve(connection);
} else {
deferred.reject();
}
});
return deferred.promise;
}
function waitRadioState(state) {
let deferred = Promise.defer();
waitFor(function() {
deferred.resolve();
}, function() {
return connection.radioState == state;
});
return deferred.promise;
}
function setRadioEnabled(enabled) {
log("setRadioEnabled to " + enabled);
let deferred = Promise.defer();
let finalState = (enabled) ? "enabled" : "disabled";
connection.onradiostatechange = function() {
let state = connection.radioState;
log("Received 'radiostatechange' event, radioState: " + state);
if (state == finalState) {
deferred.resolve();
connection.onradiostatechange = null;
}
};
let req = connection.setRadioEnabled(enabled);
req.onsuccess = function() {
log("setRadioEnabled success");
};
req.onerror = function() {
ok(false, "setRadioEnabled should not fail");
deferred.reject();
};
return deferred.promise;
}
function testSendFailed(aCause) {
log("testSendFailed, aCause: " + aCause);
let testReceiver = "+0987654321";
let testMessage = "quick fox jump over the lazy dog";
return sendSmsWithFailure(testReceiver, testMessage)
.then((result) => {
is(result.error.name, aCause, "Checking failure cause.");
let domMessage = result.error.data;
is(domMessage.id, result.message.id, "Checking message id.");
is(domMessage.receiver, testReceiver, "Checking receiver address.");
is(domMessage.body, testMessage, "Checking message body.");
is(domMessage.delivery, "error", "Checking delivery.");
is(domMessage.deliveryStatus, "error", "Checking deliveryStatus.");
});
}
startTestCommon(function testCaseMain() {
return ensureMobileConnection()
.then(() => waitRadioState("enabled"))
.then(() => setRadioEnabled(false))
.then(() => testSendFailed("RadioDisabledError"))
.then(() => setRadioEnabled(true));
});

View File

@ -159,5 +159,15 @@ var NfcUtils = {
buf[i] = str.charCodeAt(i);
}
return buf;
},
toUTF8: function(array) {
if (!array) {
return null;
}
let str = "";
for (var i = 0; i < array.length; i++) {
str += String.fromCharCode(array[i]);
}
return str;
}
};

View File

@ -8,5 +8,4 @@ qemu=true
[test_nfc_manager_tech_discovered.js]
[test_nfc_peer.js]
[test_nfc_peer_sendndef.js]
[test_nfc_checkP2PRegistration.js]
[test_nfc_error_messages.js]
[test_nfc_tag.js]

View File

@ -0,0 +1,73 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 30000;
MARIONETTE_HEAD_JS = "head.js";
let url = "http://www.mozilla.org";
// TODO : Get this from emulator console command.
const T2T_RE_INDEX = 2;
function activateRE(re) {
let deferred = Promise.defer();
let cmd = "nfc nci rf_intf_activated_ntf " + re;
emulator.run(cmd, function(result) {
is(result.pop(), "OK", "check activation of RE" + re);
deferred.resolve();
});
return deferred.promise;
}
function setTagData(re, flag, tnf, type, payload) {
let deferred = Promise.defer();
let cmd = "nfc tag set " + re +
" [" + flag + "," + tnf + "," + type + "," + payload + ",]";
log("Executing \'" + cmd + "\'");
emulator.run(cmd, function(result) {
is(result.pop(), "OK", "set NDEF data of tag" + re);
deferred.resolve();
});
return deferred.promise;
}
function testUrlTagDiscover() {
log("Running \'testUrlTagDiscover\'");
// TODO : Make flag value readable.
let flag = 0xd0;
let tnf = NDEF.TNF_WELL_KNOWN;
let type = "U";
let payload = url;
window.navigator.mozSetMessageHandler("nfc-manager-tech-discovered", function(msg) {
log("Received \'nfc-manager-tech-ndiscovered\'");
is(msg.type, "techDiscovered", "check for correct message type");
let index = msg.techList.indexOf("NDEF");
isnot(index, -1, "check for \'NDEF\' in tech list");
let records = msg.records;
ok(records.length > 0);
is(tnf, records[0].tnf, "check for TNF field in NDEF");
is(type, NfcUtils.toUTF8(records[0].type), "check for type field in NDEF");
is(payload, NfcUtils.toUTF8(records[0].payload), "check for payload field in NDEF");
toggleNFC(false, runNextTest);
});
toggleNFC(true, function() {
setTagData(T2T_RE_INDEX, flag, tnf, btoa(type), btoa(payload))
.then(() => activateRE(T2T_RE_INDEX));
});
}
let tests = [
testUrlTagDiscover
];
SpecialPowers.pushPermissions(
[{'type': 'nfc-manager', 'allow': true, context: document}], runTests);

View File

@ -8,7 +8,7 @@ this.PHONE_NUMBER_META_DATA = {
"299": '["GL","00",,,,,"\\d{6}","[1-689]\\d{5}",[["(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3",,,]]]',
"385": '["HR","00","0",,,"$NP$FG","\\d{6,12}","[1-7]\\d{5,8}|[89]\\d{6,11}",[["(1)(\\d{4})(\\d{3})","$1 $2 $3","1",,],["(6[09])(\\d{4})(\\d{3})","$1 $2 $3","6[09]",,],["(62)(\\d{3})(\\d{3,4})","$1 $2 $3","62",,],["([2-5]\\d)(\\d{3})(\\d{3})","$1 $2 $3","[2-5]",,],["(9\\d)(\\d{3})(\\d{3,4})","$1 $2 $3","9",,],["(9\\d)(\\d{4})(\\d{4})","$1 $2 $3","9",,],["(9\\d)(\\d{3,4})(\\d{3})(\\d{3})","$1 $2 $3 $4","9",,],["(\\d{2})(\\d{2})(\\d{2,3})","$1 $2 $3","6[145]|7",,],["(\\d{2})(\\d{3,4})(\\d{3})","$1 $2 $3","6[145]|7",,],["(80[01])(\\d{2})(\\d{2,3})","$1 $2 $3","8",,],["(80[01])(\\d{3,4})(\\d{3})","$1 $2 $3","8",,]]]',
"670": '["TL","00",,,,,"\\d{7,8}","[2-489]\\d{6}|7\\d{6,7}",[["(\\d{3})(\\d{4})","$1 $2","[2-489]",,],["(\\d{4})(\\d{4})","$1 $2","7",,]]]',
"258": '["MZ","00",,,,,"\\d{8,9}","[28]\\d{7,8}",[["([28]\\d)(\\d{3})(\\d{3,4})","$1 $2 $3","2|8[246]",,],["(80\\d)(\\d{3})(\\d{3})","$1 $2 $3","80",,]]]',
"258": '["MZ","00",,,,,"\\d{8,9}","[28]\\d{7,8}",[["([28]\\d)(\\d{3})(\\d{3,4})","$1 $2 $3","2|8[2-7]",,],["(80\\d)(\\d{3})(\\d{3})","$1 $2 $3","80",,]]]',
"359": '["BG","00","0",,,"$NP$FG","\\d{5,9}","[23567]\\d{5,7}|[489]\\d{6,8}",[["(2)(\\d{5})","$1 $2","29",,],["(2)(\\d{3})(\\d{3,4})","$1 $2 $3","2",,],["(\\d{3})(\\d{4})","$1 $2","43[124-7]|70[1-9]",,],["(\\d{3})(\\d{3})(\\d{2})","$1 $2 $3","43[124-7]|70[1-9]",,],["(\\d{3})(\\d{2})(\\d{3})","$1 $2 $3","[78]00",,],["(\\d{2})(\\d{3})(\\d{2,3})","$1 $2 $3","[356]|4[124-7]|7[1-9]|8[1-6]|9[1-7]",,],["(\\d{2})(\\d{3})(\\d{3,4})","$1 $2 $3","48|8[7-9]|9[08]",,]]]',
"682": '["CK","00",,,,,"\\d{5}","[2-57]\\d{4}",[["(\\d{2})(\\d{3})","$1 $2",,,]]]',
"852": '["HK","00",,,,,"\\d{5,11}","[235-7]\\d{7}|8\\d{7,8}|9\\d{4,10}",[["(\\d{4})(\\d{4})","$1 $2","[235-7]|[89](?:0[1-9]|[1-9])",,],["(800)(\\d{3})(\\d{3})","$1 $2 $3","800",,],["(900)(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3 $4","900",,],["(900)(\\d{2,5})","$1 $2","900",,]]]',
@ -31,7 +31,7 @@ this.PHONE_NUMBER_META_DATA = {
"974": '["QA","00",,,,,"\\d{7,8}","[2-8]\\d{6,7}",[["([28]\\d{2})(\\d{4})","$1 $2","[28]",,],["([3-7]\\d{3})(\\d{4})","$1 $2","[3-7]",,]]]',
"218": '["LY","00","0",,,"$NP$FG","\\d{7,9}","[25679]\\d{8}",[["([25679]\\d)(\\d{7})","$1-$2",,,]]]',
"51": '["PE","19(?:1[124]|77|90)00","0",,,"($NP$FG)","\\d{6,9}","[14-9]\\d{7,8}",[["(1)(\\d{7})","$1 $2","1",,],["([4-8]\\d)(\\d{6})","$1 $2","[4-7]|8[2-4]",,],["(\\d{3})(\\d{5})","$1 $2","80",,],["(9\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","9","$FG",]]]',
"62": '["ID","0(?:0[1789]|10(?:00|1[67]))","0",,,"$NP$FG","\\d{5,11}","[1-9]\\d{6,10}",[["(\\d{2})(\\d{7,8})","$1 $2","2[124]|[36]1","($NP$FG)",],["(\\d{3})(\\d{5,7})","$1 $2","[4579]|2[035-9]|[36][02-9]","($NP$FG)",],["(8\\d{2})(\\d{3,4})(\\d{3,4})","$1-$2-$3","8[1-35-9]",,],["(177)(\\d{6,8})","$1 $2","1",,],["(800)(\\d{5,7})","$1 $2","800",,],["(809)(\\d)(\\d{3})(\\d{3})","$1 $2 $3 $4","809",,]]]',
"62": '["ID","0(?:0[1789]|10(?:00|1[67]))","0",,,"$NP$FG","\\d{5,11}","[1-9]\\d{6,10}",[["(\\d{2})(\\d{5,8})","$1 $2","2[124]|[36]1","($NP$FG)",],["(\\d{3})(\\d{5,7})","$1 $2","[4579]|2[035-9]|[36][02-9]","($NP$FG)",],["(8\\d{2})(\\d{3,4})(\\d{3,4})","$1-$2-$3","8[1-35-9]",,],["(177)(\\d{6,8})","$1 $2","1",,],["(800)(\\d{5,7})","$1 $2","800",,],["(80\\d)(\\d)(\\d{3})(\\d{3})","$1 $2 $3 $4","80[79]",,]]]',
"298": '["FO","00",,"(10(?:01|[12]0|88))",,,"\\d{6}","[2-9]\\d{5}",[["(\\d{6})","$1",,,]]]',
"381": '["RS","00","0",,,"$NP$FG","\\d{5,12}","[126-9]\\d{4,11}|3(?:[0-79]\\d{3,10}|8[2-9]\\d{2,9})",[["([23]\\d{2})(\\d{4,9})","$1 $2","(?:2[389]|39)0",,],["([1-3]\\d)(\\d{5,10})","$1 $2","1|2(?:[0-24-7]|[389][1-9])|3(?:[0-8]|9[1-9])",,],["(6\\d)(\\d{6,8})","$1 $2","6",,],["([89]\\d{2})(\\d{3,9})","$1 $2","[89]",,],["(7[26])(\\d{4,9})","$1 $2","7[26]",,],["(7[08]\\d)(\\d{4,9})","$1 $2","7[08]",,]]]',
"975": '["BT","00",,,,,"\\d{6,8}","[1-8]\\d{6,7}",[["([17]7)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","1|77",,],["([2-8])(\\d{3})(\\d{3})","$1 $2 $3","[2-68]|7[246]",,]]]',
@ -73,7 +73,7 @@ this.PHONE_NUMBER_META_DATA = {
"357": '["CY","00",,,,,"\\d{8}","[257-9]\\d{7}",[["(\\d{2})(\\d{6})","$1 $2",,,]]]',
"240": '["GQ","00",,,,,"\\d{9}","[23589]\\d{8}",[["(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3","[235]",,],["(\\d{3})(\\d{6})","$1 $2","[89]",,]]]',
"506": '["CR","00",,"(19(?:0[01468]|19|20|66|77))",,,"\\d{8,10}","[24-9]\\d{7,9}",[["(\\d{4})(\\d{4})","$1 $2","[24-7]|8[3-9]",,],["(\\d{3})(\\d{3})(\\d{4})","$1-$2-$3","[89]0",,]]]',
"86": '["CN","(1[1279]\\d{3})?00","0","(1[1279]\\d{3})|0",,,"\\d{4,12}","[1-7]\\d{6,11}|8[0-357-9]\\d{6,9}|9\\d{9}",[["(80\\d{2})(\\d{4})","$1 $2","80[2678]","$NP$FG",],["([48]00)(\\d{3})(\\d{4})","$1 $2 $3","[48]00",,],["(\\d{5,6})","$1","100|95",,"NA"],["(\\d{2})(\\d{5,6})","$1 $2","(?:10|2\\d)[19]","$NP$FG",],["(\\d{3})(\\d{5,6})","$1 $2","[3-9]","$NP$FG",],["(\\d{3,4})(\\d{4})","$1 $2","[2-9]",,"NA"],["(21)(\\d{4})(\\d{4,6})","$1 $2 $3","21","$NP$FG",],["([12]\\d)(\\d{4})(\\d{4})","$1 $2 $3","10[1-9]|2[02-9]","$NP$FG",],["(\\d{3})(\\d{4})(\\d{4})","$1 $2 $3","3(?:11|7[179])|4(?:[15]1|3[12])|5(?:1|2[37]|3[12]|51|7[13-79]|9[15])|7(?:31|5[457]|6[09]|91)|8(?:71|98)","$NP$FG",],["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","3(?:1[02-9]|35|49|5|7[02-68]|9[1-68])|4(?:1[02-9]|2[179]|[35][2-9]|6[4789]|7\\d|8[23])|5(?:3[03-9]|4[36]|5[02-9]|6[1-46]|7[028]|80|9[2-46-9])|6(?:3[1-5]|6[0238]|9[12])|7(?:01|[1579]|2[248]|3[04-9]|4[3-6]|6[2368])|8(?:1[236-8]|2[5-7]|3|5[1-9]|7[02-9]|8[3678]|9[1-7])|9(?:0[1-3689]|1[1-79]|[379]|4[13]|5[1-5])","$NP$FG",],["(1[3-58]\\d)(\\d{4})(\\d{4})","$1 $2 $3","1[3-58]",,],["(10800)(\\d{3})(\\d{4})","$1 $2 $3","108",,]]]',
"86": '["CN","(1[1279]\\d{3})?00","0","(1[1279]\\d{3})|0",,,"\\d{4,12}","[1-7]\\d{6,11}|8[0-357-9]\\d{6,9}|9\\d{9}",[["(80\\d{2})(\\d{4})","$1 $2","80[2678]","$NP$FG",],["([48]00)(\\d{3})(\\d{4})","$1 $2 $3","[48]00",,],["(\\d{5,6})","$1","100|95",,"NA"],["(\\d{2})(\\d{5,6})","$1 $2","(?:10|2\\d)[19]","$NP$FG",],["(\\d{3})(\\d{5,6})","$1 $2","[3-9]","$NP$FG",],["(\\d{3,4})(\\d{4})","$1 $2","[2-9]",,"NA"],["(21)(\\d{4})(\\d{4,6})","$1 $2 $3","21","$NP$FG",],["([12]\\d)(\\d{4})(\\d{4})","$1 $2 $3","10[1-9]|2[02-9]","$NP$FG",],["(\\d{3})(\\d{4})(\\d{4})","$1 $2 $3","3(?:11|7[179])|4(?:[15]1|3[12])|5(?:1|2[37]|3[12]|51|7[13-79]|9[15])|7(?:31|5[457]|6[09]|91)|8(?:71|98)","$NP$FG",],["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","3(?:1[02-9]|35|49|5|7[02-68]|9[1-68])|4(?:1[02-9]|2[179]|[35][2-9]|6[4789]|7\\d|8[23])|5(?:3[03-9]|4[36]|5[02-9]|6[1-46]|7[028]|80|9[2-46-9])|6(?:3[1-5]|6[0238]|9[12])|7(?:01|[1579]|2[248]|3[04-9]|4[3-6]|6[2368])|8(?:1[236-8]|2[5-7]|3|5[1-9]|7[02-9]|8[3678]|9[1-7])|9(?:0[1-3689]|1[1-79]|[379]|4[13]|5[1-5])","$NP$FG",],["(\\d{3})(\\d{4})(\\d{4})","$1 $2 $3","1[3-578]",,],["(10800)(\\d{3})(\\d{4})","$1 $2 $3","108",,]]]',
"257": '["BI","00",,,,,"\\d{8}","[27]\\d{7}",[["([27]\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,,]]]',
"683": '["NU","00",,,,,"\\d{4}","[1-5]\\d{3}",]',
"43": '["AT","00","0",,,"$NP$FG","\\d{3,13}","[1-9]\\d{3,12}",[["(1)(\\d{3,12})","$1 $2","1",,],["(5\\d)(\\d{3,5})","$1 $2","5[079]",,],["(5\\d)(\\d{3})(\\d{3,4})","$1 $2 $3","5[079]",,],["(5\\d)(\\d{4})(\\d{4,7})","$1 $2 $3","5[079]",,],["(\\d{3})(\\d{3,10})","$1 $2","316|46|51|732|6(?:44|5[0-3579]|[6-9])|7(?:1|[28]0)|[89]",,],["(\\d{4})(\\d{3,9})","$1 $2","2|3(?:1[1-578]|[3-8])|4[2378]|5[2-6]|6(?:[12]|4[1-35-9]|5[468])|7(?:2[1-8]|35|4[1-8]|[5-79])",,]]]',
@ -100,26 +100,26 @@ this.PHONE_NUMBER_META_DATA = {
"238": '["CV","0",,,,,"\\d{7}","[259]\\d{6}",[["(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3",,,]]]',
"691": '["FM","00",,,,,"\\d{7}","[39]\\d{6}",[["(\\d{3})(\\d{4})","$1 $2",,,]]]',
"262": ['["RE","00","0",,,"$NP$FG","\\d{9}","[268]\\d{8}",[["([268]\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,,]]]','["YT","00","0",,,"$NP$FG","\\d{9}","[268]\\d{8}",]'],
"241": '["GA","00",,,,,"\\d{8}","0\\d{7}",[["(0\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,,]]]',
"241": '["GA","00",,,,,"\\d{7,8}","0?\\d{7}",[["(\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","[2-7]","0$FG",],["(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","0",,]]]',
"370": '["LT","00","8","[08]",,"($NP-$FG)","\\d{8}","[3-9]\\d{7}",[["([34]\\d)(\\d{6})","$1 $2","37|4(?:1|5[45]|6[2-4])",,],["([3-6]\\d{2})(\\d{5})","$1 $2","3[148]|4(?:[24]|6[09])|528|6",,],["([7-9]\\d{2})(\\d{2})(\\d{3})","$1 $2 $3","[7-9]","$NP $FG",],["(5)(2\\d{2})(\\d{4})","$1 $2 $3","52[0-79]",,]]]',
"256": '["UG","00[057]","0",,,"$NP$FG","\\d{5,9}","\\d{9}",[["(\\d{3})(\\d{6})","$1 $2","[7-9]|20(?:[013-8]|2[5-9])|4(?:6[45]|[7-9])",,],["(\\d{2})(\\d{7})","$1 $2","3|4(?:[1-5]|6[0-36-9])",,],["(2024)(\\d{5})","$1 $2","2024",,]]]',
"677": '["SB","0[01]",,,,,"\\d{5,7}","[1-9]\\d{4,6}",[["(\\d{3})(\\d{4})","$1 $2","[7-9]",,]]]',
"377": '["MC","00","0",,,"$NP$FG","\\d{8,9}","[4689]\\d{7,8}",[["(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","[89]","$FG",],["(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","4",,],["(6)(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4 $5","6",,]]]',
"382": '["ME","00","0",,,"$NP$FG","\\d{6,9}","[2-9]\\d{7,8}",[["(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","[2-57-9]|6[3789]",,],["(67)(9)(\\d{3})(\\d{3})","$1 $2 $3 $4","679",,]]]',
"231": '["LR","00","0",,,"$NP$FG","\\d{7,9}","(?:[29]\\d|[4-6]|7\\d{1,2}|[38]\\d{2})\\d{6}",[["([279]\\d)(\\d{3})(\\d{3})","$1 $2 $3","[279]",,],["(7\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","7",,],["([4-6])(\\d{3})(\\d{3})","$1 $2 $3","[4-6]",,],["(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3","[38]",,]]]',
"231": '["LR","00","0",,,"$NP$FG","\\d{7,9}","2\\d{7}|[37-9]\\d{8}|[45]\\d{6}",[["(2\\d)(\\d{3})(\\d{3})","$1 $2 $3","2",,],["([79]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","[79]",,],["([4-6])(\\d{3})(\\d{3})","$1 $2 $3","[4-6]",,],["(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3","[38]",,]]]',
"591": '["BO","00(1\\d)?","0","0(1\\d)?",,,"\\d{7,8}","[23467]\\d{7}",[["([234])(\\d{7})","$1 $2","[234]",,],["([67]\\d{7})","$1","[67]",,]]]',
"808": '["001",,,,,,"\\d{8}","\\d{8}",[["(\\d{4})(\\d{4})","$1 $2",,,]]]',
"964": '["IQ","00","0",,,"$NP$FG","\\d{6,10}","[1-7]\\d{7,9}",[["(1)(\\d{3})(\\d{4})","$1 $2 $3","1",,],["([2-6]\\d)(\\d{3})(\\d{3,4})","$1 $2 $3","[2-6]",,],["(7\\d{2})(\\d{3})(\\d{4})","$1 $2 $3","7",,]]]',
"225": '["CI","00",,,,,"\\d{8}","[02-7]\\d{7}",[["(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,,]]]',
"992": '["TJ","810","8",,,"($NP) $FG","\\d{3,9}","[3-59]\\d{8}",[["([349]\\d{2})(\\d{2})(\\d{4})","$1 $2 $3","[34]7|91[78]",,],["([459]\\d)(\\d{3})(\\d{4})","$1 $2 $3","4[48]|5|9(?:1[59]|[0235-9])",,],["(331700)(\\d)(\\d{2})","$1 $2 $3","331",,],["(\\d{4})(\\d)(\\d{4})","$1 $2 $3","3[1-5]",,]]]',
"55": '["BR","00(?:1[45]|2[135]|[34]1|43)","0","(?:0|90)(?:(1[245]|2[135]|[34]1)(\\d{10,11}))?","$2",,"\\d{8,11}","[1-46-9]\\d{7,10}|5\\d{8,9}",[["(\\d{4})(\\d{4})","$1-$2","[2-9](?:[1-9]|0[1-9])","$FG","NA"],["(\\d{5})(\\d{4})","$1-$2","9(?:[1-9]|0[1-9])","$FG","NA"],["(\\d{3,5})","$1","1[125689]","$FG","NA"],["(\\d{2})(\\d{5})(\\d{4})","$1 $2-$3","(?:1[1-9]|2[12478])9","($FG)",],["(\\d{2})(\\d{4})(\\d{4})","$1 $2-$3","[1-9][1-9]","($FG)",],["([34]00\\d)(\\d{4})","$1-$2","[34]00",,],["([3589]00)(\\d{2,3})(\\d{4})","$1 $2 $3","[3589]00","$NP$FG",]]]',
"55": '["BR","00(?:1[45]|2[135]|31|4[13])","0","(?:0|90)(?:(1[245]|2[135]|[34]1)(\\d{10,11}))?","$2",,"\\d{8,11}","[1-46-9]\\d{7,10}|5\\d{8,9}",[["(\\d{4})(\\d{4})","$1-$2","[2-9](?:[1-9]|0[1-9])","$FG","NA"],["(\\d{5})(\\d{4})","$1-$2","9(?:[1-9]|0[1-9])","$FG","NA"],["(\\d{3,5})","$1","1[125689]","$FG","NA"],["(\\d{2})(\\d{5})(\\d{4})","$1 $2-$3","(?:1[1-9]|2[12478])9","($FG)",],["(\\d{2})(\\d{4})(\\d{4})","$1 $2-$3","[1-9][1-9]","($FG)",],["([34]00\\d)(\\d{4})","$1-$2","[34]00",,],["([3589]00)(\\d{2,3})(\\d{4})","$1 $2 $3","[3589]00","$NP$FG",]]]',
"674": '["NR","00",,,,,"\\d{7}","[458]\\d{6}",[["(\\d{3})(\\d{4})","$1 $2",,,]]]',
"967": '["YE","00","0",,,"$NP$FG","\\d{6,9}","[1-7]\\d{6,8}",[["([1-7])(\\d{3})(\\d{3,4})","$1 $2 $3","[1-6]|7[24-68]",,],["(7\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","7[0137]",,]]]',
"49": '["DE","00","0",,,"$NP$FG","\\d{2,15}","[1-35-9]\\d{3,14}|4(?:[0-8]\\d{4,12}|9(?:[0-37]\\d|4(?:[1-35-8]|4\\d?)|5\\d{1,2}|6[1-8]\\d?)\\d{2,7})",[["(1\\d{2})(\\d{7,8})","$1 $2","1[67]",,],["(1\\d{3})(\\d{7})","$1 $2","15",,],["(\\d{2})(\\d{3,11})","$1 $2","3[02]|40|[68]9",,],["(\\d{3})(\\d{3,11})","$1 $2","2(?:\\d1|0[2389]|1[24]|28|34)|3(?:[3-9][15]|40)|[4-8][1-9]1|9(?:06|[1-9]1)",,],["(\\d{4})(\\d{2,11})","$1 $2","[24-6]|[7-9](?:\\d[1-9]|[1-9]\\d)|3(?:[3569][02-46-9]|4[2-4679]|7[2-467]|8[2-46-8])",,],["(3\\d{4})(\\d{1,10})","$1 $2","3",,],["(800)(\\d{7,12})","$1 $2","800",,],["(177)(99)(\\d{7,8})","$1 $2 $3","177",,],["(\\d{3})(\\d)(\\d{4,10})","$1 $2 $3","(?:18|90)0",,],["(1\\d{2})(\\d{5,11})","$1 $2","181",,],["(18\\d{3})(\\d{6})","$1 $2","185",,],["(18\\d{2})(\\d{7})","$1 $2","18[68]",,],["(18\\d)(\\d{8})","$1 $2","18[2-579]",,],["(700)(\\d{4})(\\d{4})","$1 $2 $3","700",,]]]',
"49": '["DE","00","0",,,"$NP$FG","\\d{2,15}","[1-35-9]\\d{3,14}|4(?:[0-8]\\d{4,12}|9(?:[0-37]\\d|4(?:[1-35-8]|4\\d?)|5\\d{1,2}|6[1-8]\\d?)\\d{2,7})",[["(1\\d{2})(\\d{7,8})","$1 $2","1[67]",,],["(1\\d{3})(\\d{7})","$1 $2","15",,],["(\\d{2})(\\d{3,11})","$1 $2","3[02]|40|[68]9",,],["(\\d{3})(\\d{3,11})","$1 $2","2(?:\\d1|0[2389]|1[24]|28|34)|3(?:[3-9][15]|40)|[4-8][1-9]1|9(?:06|[1-9]1)",,],["(\\d{4})(\\d{2,11})","$1 $2","[24-6]|[7-9](?:\\d[1-9]|[1-9]\\d)|3(?:[3569][02-46-9]|4[2-4679]|7[2-467]|8[2-46-8])",,],["(3\\d{4})(\\d{1,10})","$1 $2","3",,],["(800)(\\d{7,12})","$1 $2","800",,],["(177)(99)(\\d{7,8})","$1 $2 $3","177",,],["(\\d{3})(\\d)(\\d{4,10})","$1 $2 $3","(?:18|90)0|137",,],["(1\\d{2})(\\d{5,11})","$1 $2","181",,],["(18\\d{3})(\\d{6})","$1 $2","185",,],["(18\\d{2})(\\d{7})","$1 $2","18[68]",,],["(18\\d)(\\d{8})","$1 $2","18[2-579]",,],["(700)(\\d{4})(\\d{4})","$1 $2 $3","700",,],["(138)(\\d{4})","$1 $2","138",,]]]',
"31": '["NL","00","0",,,"$NP$FG","\\d{5,10}","1\\d{4,8}|[2-7]\\d{8}|[89]\\d{6,9}",[["([1-578]\\d)(\\d{3})(\\d{4})","$1 $2 $3","1[035]|2[0346]|3[03568]|4[0356]|5[0358]|7|8[4578]",,],["([1-5]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","1[16-8]|2[259]|3[124]|4[17-9]|5[124679]",,],["(6)(\\d{8})","$1 $2","6[0-57-9]",,],["(66)(\\d{7})","$1 $2","66",,],["(14)(\\d{3,4})","$1 $2","14","$FG",],["([89]0\\d)(\\d{4,7})","$1 $2","80|9",,]]]',
"970": '["PS","00","0",,,"$NP$FG","\\d{4,10}","[24589]\\d{7,8}|1(?:[78]\\d{8}|[49]\\d{2,3})",[["([2489])(2\\d{2})(\\d{4})","$1 $2 $3","[2489]",,],["(5[69]\\d)(\\d{3})(\\d{3})","$1 $2 $3","5",,],["(1[78]00)(\\d{3})(\\d{3})","$1 $2 $3","1[78]","$FG",]]]',
"58": '["VE","00","0",,,"$NP$FG","\\d{7,10}","[24589]\\d{9}",[["(\\d{3})(\\d{7})","$1-$2",,,]]]',
"856": '["LA","00","0",,,"$NP$FG","\\d{6,10}","[2-8]\\d{7,9}",[["(20)(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3 $4","20",,],["([2-8]\\d)(\\d{3})(\\d{3})","$1 $2 $3","2[13]|[3-8]",,]]]',
"856": '["LA","00","0",,,"$NP$FG","\\d{6,10}","[2-8]\\d{7,9}",[["(20)(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3 $4","20",,],["([2-8]\\d)(\\d{3})(\\d{3})","$1 $2 $3","2[13]|3[14]|[4-8]",,],["(30)(\\d{2})(\\d{2})(\\d{3})","$1 $2 $3 $4","30",,]]]',
"354": '["IS","00",,,,,"\\d{7,9}","[4-9]\\d{6}|38\\d{7}",[["(\\d{3})(\\d{4})","$1 $2","[4-9]",,],["(3\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","3",,]]]',
"242": '["CG","00",,,,,"\\d{9}","[028]\\d{8}",[["(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3","[02]",,],["(\\d)(\\d{4})(\\d{4})","$1 $2 $3","8",,]]]',
"423": '["LI","00","0",,,,"\\d{7,9}","6\\d{8}|[23789]\\d{6}",[["(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3","[23]|7[3-57-9]|87",,],["(6\\d)(\\d{3})(\\d{3})","$1 $2 $3","6",,],["(6[567]\\d)(\\d{3})(\\d{3})","$1 $2 $3","6[567]",,],["(69)(7\\d{2})(\\d{4})","$1 $2 $3","697",,],["([7-9]0\\d)(\\d{2})(\\d{2})","$1 $2 $3","[7-9]0",,],["([89]0\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","[89]0","$NP$FG",]]]',
@ -148,22 +148,22 @@ this.PHONE_NUMBER_META_DATA = {
"971": '["AE","00","0",,,"$NP$FG","\\d{5,12}","[2-79]\\d{7,8}|800\\d{2,9}",[["([2-4679])(\\d{3})(\\d{4})","$1 $2 $3","[2-4679][2-8]",,],["(5[0256])(\\d{3})(\\d{4})","$1 $2 $3","5",,],["([479]00)(\\d)(\\d{5})","$1 $2 $3","[479]0","$FG",],["([68]00)(\\d{2,9})","$1 $2","60|8","$FG",]]]',
"30": '["GR","00",,,,,"\\d{10}","[26-9]\\d{9}",[["([27]\\d)(\\d{4})(\\d{4})","$1 $2 $3","21|7",,],["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","2[2-9]1|[689]",,],["(2\\d{3})(\\d{6})","$1 $2","2[2-9][02-9]",,]]]',
"228": '["TG","00",,,,,"\\d{8}","[29]\\d{7}",[["(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,,]]]',
"48": '["PL","00",,,,,"\\d{6,9}","[1-58]\\d{6,8}|9\\d{8}|[67]\\d{5,8}",[["(\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4","[124]|3[2-4]|5[24-689]|6[1-3578]|7[14-7]|8[1-79]|9[145]",,],["(\\d{2})(\\d{4,6})","$1 $2","[124]|3[2-4]|5[24-689]|6[1-3578]|7[14-7]|8[1-7]",,],["(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3","39|5[0137]|6[0469]|7[02389]|8[08]",,],["(\\d{3})(\\d{2})(\\d{2,3})","$1 $2 $3","64",,],["(\\d{3})(\\d{3})","$1 $2","64",,]]]',
"886": '["TW","0(?:0[25679]|19)","0",,,"$NP$FG","\\d{8,9}","[2-9]\\d{7,8}",[["([2-8])(\\d{3,4})(\\d{4})","$1 $2 $3","[2-7]|8[1-9]",,],["([89]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","80|9",,]]]',
"48": '["PL","00",,,,,"\\d{6,9}","[12]\\d{6,8}|[3-57-9]\\d{8}|6\\d{5,8}",[["(\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4","[124]|3[2-4]|5[24-689]|6[1-3578]|7[14-7]|8[1-79]|9[145]",,],["(\\d{2})(\\d{1})(\\d{4})","$1 $2 $3","[12]2",,],["(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3","39|5[0137]|6[0469]|7[02389]|8[08]",,],["(\\d{3})(\\d{2})(\\d{2,3})","$1 $2 $3","64",,],["(\\d{3})(\\d{3})","$1 $2","64",,]]]',
"886": '["TW","0(?:0[25679]|19)","0",,,"$NP$FG","\\d{8,10}","[2-689]\\d{7,8}|7\\d{7,9}",[["([2-8])(\\d{3,4})(\\d{4})","$1 $2 $3","[2-6]|[78][1-9]",,],["([89]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","80|9",,],["(70)(\\d{4})(\\d{4})","$1 $2 $3","70",,]]]',
"212": ['["MA","00","0",,,"$NP$FG","\\d{9}","[5689]\\d{8}",[["([56]\\d{2})(\\d{6})","$1-$2","5(?:2[015-7]|3[0-4])|6",,],["([58]\\d{3})(\\d{5})","$1-$2","5(?:2[2-489]|3[5-9])|892",,],["(5\\d{4})(\\d{4})","$1-$2","5(?:29|38)",,],["(8[09])(\\d{7})","$1-$2","8(?:0|9[013-9])",,]]]','["EH","00","0",,,"$NP$FG","\\d{9}","[5689]\\d{8}",]'],
"372": '["EE","00",,,,,"\\d{4,10}","1\\d{3,4}|[3-9]\\d{6,7}|800\\d{6,7}",[["([3-79]\\d{2})(\\d{4})","$1 $2","[369]|4[3-8]|5(?:[0-2]|5[0-478]|6[45])|7[1-9]",,],["(70)(\\d{2})(\\d{4})","$1 $2 $3","70",,],["(8000)(\\d{3})(\\d{3})","$1 $2 $3","800",,],["([458]\\d{3})(\\d{3,4})","$1 $2","40|5|8(?:00|[1-5])",,]]]',
"598": '["UY","0(?:1[3-9]\\d|0)","0",,,,"\\d{7,8}","[2489]\\d{6,7}",[["(\\d{4})(\\d{4})","$1 $2","[24]",,],["(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","9[1-9]","$NP$FG",],["(\\d{3})(\\d{4})","$1 $2","[89]0","$NP$FG",]]]',
"502": '["GT","00",,,,,"\\d{8}(?:\\d{3})?","[2-7]\\d{7}|1[89]\\d{9}",[["(\\d{4})(\\d{4})","$1 $2","[2-7]",,],["(\\d{4})(\\d{3})(\\d{4})","$1 $2 $3","1",,]]]',
"82": '["KR","00(?:[124-68]|[37]\\d{2})","0","0(8[1-46-8]|85\\d{2})?",,"$NP$FG","\\d{4,10}","[1-7]\\d{3,9}|8\\d{8}",[["(\\d{2})(\\d{4})(\\d{4})","$1-$2-$3","1(?:0|1[19]|[69]9|5[458])|[57]0",,],["(\\d{2})(\\d{3,4})(\\d{4})","$1-$2-$3","1(?:[169][2-8]|[78]|5[1-4])|[68]0|[3-6][1-9][1-9]",,],["(\\d{3})(\\d)(\\d{4})","$1-$2-$3","131",,],["(\\d{3})(\\d{2})(\\d{4})","$1-$2-$3","131",,],["(\\d{3})(\\d{3})(\\d{4})","$1-$2-$3","13[2-9]",,],["(\\d{2})(\\d{2})(\\d{3})(\\d{4})","$1-$2-$3-$4","30",,],["(\\d)(\\d{3,4})(\\d{4})","$1-$2-$3","2[1-9]",,],["(\\d)(\\d{3,4})","$1-$2","21[0-46-9]",,],["(\\d{2})(\\d{3,4})","$1-$2","[3-6][1-9]1",,],["(\\d{4})(\\d{4})","$1-$2","1(?:5[46-9]|6[04678])","$FG",]]]',
"253": '["DJ","00",,,,,"\\d{8}","[27]\\d{7}",[["(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,,]]]',
"91": '["IN","00","0",,,"$NP$FG","\\d{6,13}","1\\d{7,12}|[2-9]\\d{9,10}",[["(\\d{2})(\\d{2})(\\d{6})","$1 $2 $3","7(?:2[0579]|3[057-9]|4[0-389]|6[0-35-9]|[57]|8[0-79])|8(?:0[015689]|1[0-57-9]|2[2356-9]|3[0-57-9]|[45]|6[02457-9]|7[1-69]|8[0124-9]|9[02-9])|9",,],["(\\d{2})(\\d{4})(\\d{4})","$1 $2 $3","11|2[02]|33|4[04]|79|80[2-46]",,],["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","1(?:2[0-249]|3[0-25]|4[145]|[569][14]|7[1257]|8[1346]|[68][1-9])|2(?:1[257]|3[013]|4[01]|5[0137]|6[0158]|78|8[1568]|9[14])|3(?:26|4[1-3]|5[34]|6[01489]|7[02-46]|8[159])|4(?:1[36]|2[1-47]|3[15]|5[12]|6[126-9]|7[0-24-9]|8[013-57]|9[014-7])|5(?:[136][25]|22|4[28]|5[12]|[78]1|9[15])|6(?:12|[2345]1|57|6[13]|7[14]|80)",,],["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","7(?:12|2[14]|3[134]|4[47]|5[15]|[67]1|88)",,],["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","8(?:16|2[014]|3[126]|6[136]|7[078]|8[34]|91)",,],["(\\d{4})(\\d{3})(\\d{3})","$1 $2 $3","1(?:[23579]|[468][1-9])|[2-8]",,],["(1600)(\\d{2})(\\d{4})","$1 $2 $3","160","$FG",],["(1800)(\\d{4,5})","$1 $2","180","$FG",],["(18[06]0)(\\d{2,4})(\\d{4})","$1 $2 $3","18[06]","$FG",],["(140)(\\d{3})(\\d{4})","$1 $2 $3","140","$FG",],["(\\d{4})(\\d{3})(\\d{4})(\\d{2})","$1 $2 $3 $4","18[06]","$FG",]]]',
"91": '["IN","00","0",,,"$NP$FG","\\d{6,13}","1\\d{7,12}|[2-9]\\d{9,10}",[["(\\d{2})(\\d{2})(\\d{6})","$1 $2 $3","7(?:0[2-4]|2[0579]|3[057-9]|4[0-389]|6[0-35-9]|[57]|8[0-79])|8(?:0[015689]|1[0-57-9]|2[2356-9]|3[0-57-9]|[45]|6[02457-9]|7[1-69]|8[0124-9]|9[02-9])|9",,],["(\\d{2})(\\d{4})(\\d{4})","$1 $2 $3","11|2[02]|33|4[04]|79|80[2-46]",,],["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","1(?:2[0-249]|3[0-25]|4[145]|[569][14]|7[1257]|8[1346]|[68][1-9])|2(?:1[257]|3[013]|4[01]|5[0137]|6[0158]|78|8[1568]|9[14])|3(?:26|4[1-3]|5[34]|6[01489]|7[02-46]|8[159])|4(?:1[36]|2[1-47]|3[15]|5[12]|6[126-9]|7[0-24-9]|8[013-57]|9[014-7])|5(?:[136][25]|22|4[28]|5[12]|[78]1|9[15])|6(?:12|[2345]1|57|6[13]|7[14]|80)",,],["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","7(?:12|2[14]|3[134]|4[47]|5[15]|[67]1|88)",,],["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","8(?:16|2[014]|3[126]|6[136]|7[078]|8[34]|91)",,],["(\\d{4})(\\d{3})(\\d{3})","$1 $2 $3","1(?:[23579]|[468][1-9])|[2-8]",,],["(1600)(\\d{2})(\\d{4})","$1 $2 $3","160","$FG",],["(1800)(\\d{4,5})","$1 $2","180","$FG",],["(18[06]0)(\\d{2,4})(\\d{4})","$1 $2 $3","18[06]","$FG",],["(140)(\\d{3})(\\d{4})","$1 $2 $3","140","$FG",],["(\\d{4})(\\d{3})(\\d{4})(\\d{2})","$1 $2 $3 $4","18[06]","$FG",]]]',
"389": '["MK","00","0",,,"$NP$FG","\\d{8}","[2-578]\\d{7}",[["(2)(\\d{3})(\\d{4})","$1 $2 $3","2",,],["([347]\\d)(\\d{3})(\\d{3})","$1 $2 $3","[347]",,],["([58]\\d{2})(\\d)(\\d{2})(\\d{2})","$1 $2 $3 $4","[58]",,]]]',
"1": ['["US","011","1",,,,"\\d{7}(?:\\d{3})?","[2-9]\\d{9}",[["(\\d{3})(\\d{4})","$1-$2",,,"NA"],["(\\d{3})(\\d{3})(\\d{4})","($1) $2-$3",,,"$1-$2-$3"]]]','["AI","011","1",,,,"\\d{7}(?:\\d{3})?","[2589]\\d{9}",]','["AS","011","1",,,,"\\d{7}(?:\\d{3})?","[5689]\\d{9}",]','["BB","011","1",,,,"\\d{7}(?:\\d{3})?","[2589]\\d{9}",]','["BM","011","1",,,,"\\d{7}(?:\\d{3})?","[4589]\\d{9}",]','["BS","011","1",,,,"\\d{7}(?:\\d{3})?","[2589]\\d{9}",]','["CA","011","1",,,,"\\d{7}(?:\\d{3})?","[2-9]\\d{9}|3\\d{6}",]','["DM","011","1",,,,"\\d{7}(?:\\d{3})?","[57-9]\\d{9}",]','["DO","011","1",,,,"\\d{7}(?:\\d{3})?","[589]\\d{9}",]','["GD","011","1",,,,"\\d{7}(?:\\d{3})?","[4589]\\d{9}",]','["GU","011","1",,,,"\\d{7}(?:\\d{3})?","[5689]\\d{9}",]','["JM","011","1",,,,"\\d{7}(?:\\d{3})?","[589]\\d{9}",]','["KN","011","1",,,,"\\d{7}(?:\\d{3})?","[589]\\d{9}",]','["KY","011","1",,,,"\\d{7}(?:\\d{3})?","[3589]\\d{9}",]','["LC","011","1",,,,"\\d{7}(?:\\d{3})?","[5789]\\d{9}",]','["MP","011","1",,,,"\\d{7}(?:\\d{3})?","[5689]\\d{9}",]','["MS","011","1",,,,"\\d{7}(?:\\d{3})?","[5689]\\d{9}",]','["PR","011","1",,,,"\\d{7}(?:\\d{3})?","[5789]\\d{9}",]','["SX","011","1",,,,"\\d{7}(?:\\d{3})?","[5789]\\d{9}",]','["TC","011","1",,,,"\\d{7}(?:\\d{3})?","[5689]\\d{9}",]','["TT","011","1",,,,"\\d{7}(?:\\d{3})?","[589]\\d{9}",]','["AG","011","1",,,,"\\d{7}(?:\\d{3})?","[2589]\\d{9}",]','["VC","011","1",,,,"\\d{7}(?:\\d{3})?","[5789]\\d{9}",]','["VG","011","1",,,,"\\d{7}(?:\\d{3})?","[2589]\\d{9}",]','["VI","011","1",,,,"\\d{7}(?:\\d{3})?","[3589]\\d{9}",]'],
"60": '["MY","00","0",,,,"\\d{6,10}","[13-9]\\d{7,9}",[["([4-79])(\\d{3})(\\d{4})","$1-$2 $3","[4-79]","$NP$FG",],["(3)(\\d{4})(\\d{4})","$1-$2 $3","3","$NP$FG",],["([18]\\d)(\\d{3})(\\d{3,4})","$1-$2 $3","1[02-46-9][1-9]|8","$NP$FG",],["(1)([36-8]00)(\\d{2})(\\d{4})","$1-$2-$3-$4","1[36-8]0",,],["(11)(\\d{4})(\\d{4})","$1-$2 $3","11","$NP$FG",],["(15[49])(\\d{3})(\\d{4})","$1-$2 $3","15","$NP$FG",]]]',
"355": '["AL","00","0",,,"$NP$FG","\\d{5,9}","[2-57]\\d{7}|6\\d{8}|8\\d{5,7}|9\\d{5}",[["(4)(\\d{3})(\\d{4})","$1 $2 $3","4[0-6]",,],["(6[6-9])(\\d{3})(\\d{4})","$1 $2 $3","6",,],["(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","[2358][2-5]|4[7-9]",,],["(\\d{3})(\\d{3,5})","$1 $2","[235][16-9]|8[016-9]|[79]",,]]]',
"254": '["KE","000","0",,,"$NP$FG","\\d{5,10}","20\\d{6,7}|[4-9]\\d{6,9}",[["(\\d{2})(\\d{4,7})","$1 $2","[24-6]",,],["(\\d{3})(\\d{6,7})","$1 $2","7",,],["(\\d{3})(\\d{3})(\\d{3,4})","$1 $2 $3","[89]",,]]]',
"223": '["ML","00",,,,,"\\d{8}","[246-9]\\d{7}",[["(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","[246-9]",,],["(\\d{4})","$1","67|74",,"NA"]]]',
"686": '["KI","00",,"0",,,"\\d{5,8}","[2-58]\\d{4}|7\\d{7}",]',
"686": '["KI","00",,"0",,,"\\d{5,8}","[2458]\\d{4}|3\\d{4,7}|7\\d{7}",]',
"994": '["AZ","00","0",,,"($NP$FG)","\\d{7,9}","[1-9]\\d{8}",[["(\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4","(?:1[28]|2(?:[45]2|[0-36])|365)",,],["(\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4","[4-8]","$NP$FG",],["(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","9","$NP$FG",]]]',
"979": '["001",,,,,,"\\d{9}","\\d{9}",[["(\\d)(\\d{4})(\\d{4})","$1 $2 $3",,,]]]',
"66": '["TH","00","0",,,"$NP$FG","\\d{4}|\\d{8,10}","[2-9]\\d{7,8}|1\\d{3}(?:\\d{6})?",[["(2)(\\d{3})(\\d{4})","$1 $2 $3","2",,],["([3-9]\\d)(\\d{3})(\\d{3,4})","$1 $2 $3","[3-9]",,],["(1[89]00)(\\d{3})(\\d{3})","$1 $2 $3","1","$FG",]]]',
@ -197,7 +197,7 @@ this.PHONE_NUMBER_META_DATA = {
"976": '["MN","001","0",,,"$NP$FG","\\d{6,10}","[12]\\d{7,9}|[57-9]\\d{7}",[["([12]\\d)(\\d{2})(\\d{4})","$1 $2 $3","[12]1",,],["([12]2\\d)(\\d{5,6})","$1 $2","[12]2[1-3]",,],["([12]\\d{3})(\\d{5})","$1 $2","[12](?:27|[3-5])",,],["(\\d{4})(\\d{4})","$1 $2","[57-9]","$FG",],["([12]\\d{4})(\\d{4,5})","$1 $2","[12](?:27|[3-5])",,]]]',
"20": '["EG","00","0",,,"$NP$FG","\\d{5,10}","1\\d{4,9}|[2456]\\d{8}|3\\d{7}|[89]\\d{8,9}",[["(\\d)(\\d{7,8})","$1 $2","[23]",,],["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","1[012]|[89]00",,],["(\\d{2})(\\d{6,7})","$1 $2","1[35]|[4-6]|[89][2-9]",,]]]',
"689": '["PF","00",,,,,"\\d{6}(?:\\d{2})?","[2-79]\\d{5}|8\\d{5,7}",[["(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","89",,],["(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3",,,]]]',
"56": '["CL","(?:0|1(?:1[0-69]|2[0-57]|5[13-58]|69|7[0167]|8[018]))0","0","0|(1(?:1[0-69]|2[0-57]|5[13-58]|69|7[0167]|8[018]))",,"$NP$FG","\\d{6,11}","(?:[2-9]|600|123)\\d{7,8}",[["(\\d)(\\d{4})(\\d{4})","$1 $2 $3","2","($FG)",],["(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3","[357]|4[1-35]|6[13-57]","($FG)",],["(\\d{2})(\\d{2})(\\d{4})","$1 $2 $3","65","($FG)",],["(9)([5-9]\\d{3})(\\d{4})","$1 $2 $3","9",,],["(44)(\\d{3})(\\d{4})","$1 $2 $3","44",,],["([68]00)(\\d{3})(\\d{3,4})","$1 $2 $3","60|8","$FG",],["(600)(\\d{3})(\\d{2})(\\d{3})","$1 $2 $3 $4","60","$FG",],["(1230)(\\d{3})(\\d{4})","$1 $2 $3","1","$FG",],["(\\d{4,5})","$1","[1-9]","$FG","NA"]]]',
"56": '["CL","(?:0|1(?:1[0-69]|2[0-57]|5[13-58]|69|7[0167]|8[018]))0","0","0|(1(?:1[0-69]|2[0-57]|5[13-58]|69|7[0167]|8[018]))",,"$NP$FG","\\d{6,11}","(?:[2-9]|600|123)\\d{7,8}",[["(\\d)(\\d{4})(\\d{4})","$1 $2 $3","22","($FG)",],["(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3","[357]|4[1-35]|6[13-57]","($FG)",],["(\\d{2})(\\d{2})(\\d{4})","$1 $2 $3","65","($FG)",],["(9)([5-9]\\d{3})(\\d{4})","$1 $2 $3","9",,],["(44)(\\d{3})(\\d{4})","$1 $2 $3","44",,],["([68]00)(\\d{3})(\\d{3,4})","$1 $2 $3","60|8","$FG",],["(600)(\\d{3})(\\d{2})(\\d{3})","$1 $2 $3 $4","60","$FG",],["(1230)(\\d{3})(\\d{4})","$1 $2 $3","1","$FG",],["(\\d{5})(\\d{4})","$1 $2","219","($FG)",],["(\\d{4,5})","$1","[1-9]","$FG","NA"]]]',
"596": '["MQ","00","0",,,"$NP$FG","\\d{9}","[56]\\d{8}",[["(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,,]]]',
"508": '["PM","00","0",,,"$NP$FG","\\d{6}","[45]\\d{5}",[["([45]\\d)(\\d{2})(\\d{2})","$1 $2 $3",,,]]]',
"269": '["KM","00",,,,,"\\d{7}","[379]\\d{6}",[["(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3",,,]]]',

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
class="reftest-wait">
<script>
<![CDATA[
function boom()
{
var animate =
document.createElementNS("http://www.w3.org/2000/svg", "animate");
animate.setAttribute("dur", "2s");
document.documentElement.appendChild(animate);
animate.targetElement;
animate.requiredFeatures.insertItemBefore(0, 0);
document.documentElement.setCurrentTime(4);
document.documentElement.setCurrentTime(0);
document.documentElement.removeAttribute("class");
}
window.addEventListener("load", boom, false);
]]>
</script></svg>

After

Width:  |  Height:  |  Size: 608 B

View File

@ -51,3 +51,4 @@ load 697640-1.svg
load 699325-1.svg
load 709907-1.svg
load 720103-1.svg
load 1010681-1.svg

View File

@ -672,12 +672,10 @@ nsSMILAnimationController::SampleAnimation(AnimationElementPtrKey* aKey,
NS_ENSURE_TRUE(aData, PL_DHASH_NEXT);
SVGAnimationElement* animElem = aKey->GetKey();
if (animElem->PassesConditionalProcessingTests()) {
SampleAnimationParams* params = static_cast<SampleAnimationParams*>(aData);
SampleAnimationParams* params = static_cast<SampleAnimationParams*>(aData);
SampleTimedElement(animElem, params->mActiveContainers);
AddAnimationToCompositorTable(animElem, params->mCompositorTable);
}
SampleTimedElement(animElem, params->mActiveContainers);
AddAnimationToCompositorTable(animElem, params->mCompositorTable);
return PL_DHASH_NEXT;
}

View File

@ -253,6 +253,7 @@ nsSMILTimedElement::nsSMILTimedElement()
mSeekState(SEEK_NOT_SEEKING),
mDeferIntervalUpdates(false),
mDoDeferredUpdate(false),
mIsDisabled(false),
mDeleteCount(0),
mUpdateIntervalRecursionDepth(0)
{
@ -521,6 +522,9 @@ nsSMILTimedElement::SetTimeClient(nsSMILAnimationFunction* aClient)
void
nsSMILTimedElement::SampleAt(nsSMILTime aContainerTime)
{
if (mIsDisabled)
return;
// Milestones are cleared before a sample
mPrevRegisteredMilestone = sMaxMilestone;
@ -530,6 +534,9 @@ nsSMILTimedElement::SampleAt(nsSMILTime aContainerTime)
void
nsSMILTimedElement::SampleEndAt(nsSMILTime aContainerTime)
{
if (mIsDisabled)
return;
// Milestones are cleared before a sample
mPrevRegisteredMilestone = sMaxMilestone;
@ -797,36 +804,38 @@ nsSMILTimedElement::Rewind()
mSeekState == SEEK_BACKWARD_FROM_ACTIVE,
"Rewind in the middle of a forwards seek?");
// Putting us in the startup state will ensure we skip doing any interval
// updates
mElementState = STATE_STARTUP;
ClearIntervals();
ClearTimingState(RemoveNonDynamic);
RebuildTimingState(RemoveNonDynamic);
UnsetBeginSpec(RemoveNonDynamic);
UnsetEndSpec(RemoveNonDynamic);
if (mClient) {
mClient->Inactivate(false);
}
if (mAnimationElement->HasAnimAttr(nsGkAtoms::begin)) {
nsAutoString attValue;
mAnimationElement->GetAnimAttr(nsGkAtoms::begin, attValue);
SetBeginSpec(attValue, mAnimationElement, RemoveNonDynamic);
}
if (mAnimationElement->HasAnimAttr(nsGkAtoms::end)) {
nsAutoString attValue;
mAnimationElement->GetAnimAttr(nsGkAtoms::end, attValue);
SetEndSpec(attValue, mAnimationElement, RemoveNonDynamic);
}
mPrevRegisteredMilestone = sMaxMilestone;
RegisterMilestone();
NS_ABORT_IF_FALSE(!mCurrentInterval,
"Current interval is set at end of rewind");
}
namespace
{
bool
RemoveAll(nsSMILInstanceTime* aInstanceTime)
{
return true;
}
}
bool
nsSMILTimedElement::SetIsDisabled(bool aIsDisabled)
{
if (mIsDisabled == aIsDisabled)
return false;
if (aIsDisabled) {
mIsDisabled = true;
ClearTimingState(RemoveAll);
} else {
RebuildTimingState(RemoveAll);
mIsDisabled = false;
}
return true;
}
namespace
{
bool
@ -1438,6 +1447,45 @@ nsSMILTimedElement::Reset()
RemoveInstanceTimes(mEndInstances, resetEnd);
}
void
nsSMILTimedElement::ClearTimingState(RemovalTestFunction aRemove)
{
mElementState = STATE_STARTUP;
ClearIntervals();
UnsetBeginSpec(aRemove);
UnsetEndSpec(aRemove);
if (mClient) {
mClient->Inactivate(false);
}
}
void
nsSMILTimedElement::RebuildTimingState(RemovalTestFunction aRemove)
{
MOZ_ASSERT(mAnimationElement,
"Attempting to enable a timed element not attached to an "
"animation element");
MOZ_ASSERT(mElementState == STATE_STARTUP,
"Rebuilding timing state from non-startup state");
if (mAnimationElement->HasAnimAttr(nsGkAtoms::begin)) {
nsAutoString attValue;
mAnimationElement->GetAnimAttr(nsGkAtoms::begin, attValue);
SetBeginSpec(attValue, mAnimationElement, aRemove);
}
if (mAnimationElement->HasAnimAttr(nsGkAtoms::end)) {
nsAutoString attValue;
mAnimationElement->GetAnimAttr(nsGkAtoms::end, attValue);
SetEndSpec(attValue, mAnimationElement, aRemove);
}
mPrevRegisteredMilestone = sMaxMilestone;
RegisterMilestone();
}
void
nsSMILTimedElement::DoPostSeek()
{

View File

@ -239,6 +239,18 @@ public:
*/
void Rewind();
/**
* Marks this element as disabled or not. If the element is disabled, it
* will ignore any future samples and discard any accumulated timing state.
*
* This is used by SVG to "turn off" timed elements when the associated
* animation element has failing conditional processing tests.
*
* Returns true if the disabled state of the timed element was changed
* as a result of this call (i.e. it was not a redundant call).
*/
bool SetIsDisabled(bool aIsDisabled);
/**
* Attempts to set an attribute on this timed element.
*
@ -423,6 +435,28 @@ protected:
*/
void Reset();
/**
* Clears all accumulated timing state except for those instance times for
* which aRemove does not return true.
*
* Unlike the Reset method which only clears instance times, this clears the
* element's state, intervals (including current interval), and tells the
* client animation function to stop applying a result. In effect, it returns
* the element to its initial state but preserves any instance times excluded
* by the passed-in function.
*/
void ClearTimingState(RemovalTestFunction aRemove);
/**
* Recreates timing state by re-applying begin/end attributes specified on
* the associated animation element.
*
* Note that this does not completely restore the information cleared by
* ClearTimingState since it leaves the element in the startup state.
* The element state will be updated on the next sample.
*/
void RebuildTimingState(RemovalTestFunction aRemove);
/**
* Completes a seek operation by sending appropriate events and, in the case
* of a backwards seek, updating the state of timing information that was
@ -616,6 +650,7 @@ protected:
bool mDeferIntervalUpdates;
bool mDoDeferredUpdate; // Set if an update to the current interval was
// requested while mDeferIntervalUpdates was set
bool mIsDisabled;
// Stack-based helper class to call UpdateCurrentInterval when it is destroyed
class AutoIntervalUpdater;

View File

@ -24,6 +24,7 @@ support-files =
[test_smilCSSInvalidValues.xhtml]
[test_smilCSSPaced.xhtml]
[test_smilChangeAfterFrozen.xhtml]
[test_smilConditionalProcessing.html]
[test_smilContainerBinding.xhtml]
[test_smilCrossContainer.xhtml]
[test_smilDynamicDelayedBeginElement.xhtml]

Some files were not shown because too many files have changed in this diff Show More