Merge m-c to fx-team

This commit is contained in:
Carsten "Tomcat" Book 2015-10-16 15:01:23 +02:00
commit f56a925c1e
358 changed files with 8591 additions and 3201 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 1182727 - Update the clang toolchain
No bug - unknown something produced intermittent OS X build failures in libstagefright and jemalloc and malloc

View File

@ -586,9 +586,8 @@ setCaretOffsetCB(AtkText *aText, gint aOffset)
}
if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
if (proxy->SetCaretOffset(aOffset)) {
return TRUE;
}
proxy->SetCaretOffset(aOffset);
return TRUE;
}
return FALSE;

View File

@ -390,13 +390,10 @@ DocAccessibleChild::RecvCaretOffset(const uint64_t& aID, int32_t* aOffset)
bool
DocAccessibleChild::RecvSetCaretOffset(const uint64_t& aID,
const int32_t& aOffset,
bool* aRetVal)
const int32_t& aOffset)
{
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
*aRetVal = false;
if (acc && acc->IsTextRole() && acc->IsValidOffset(aOffset)) {
*aRetVal = true;
acc->SetCaretOffset(aOffset);
}
return true;

View File

@ -103,8 +103,8 @@ public:
override;
virtual bool RecvCaretOffset(const uint64_t& aID, int32_t* aOffset)
override;
virtual bool RecvSetCaretOffset(const uint64_t& aID, const int32_t& aOffset,
bool* aValid) override;
virtual bool RecvSetCaretOffset(const uint64_t& aID, const int32_t& aOffset)
override;
virtual bool RecvCharacterCount(const uint64_t& aID, int32_t* aCount)
override;

View File

@ -92,7 +92,7 @@ child:
// TextSubstring is getText in IDL.
prio(high) sync CaretLineNumber(uint64_t aID) returns(int32_t aLineNumber);
prio(high) sync CaretOffset(uint64_t aID) returns(int32_t aOffset);
prio(high) sync SetCaretOffset(uint64_t aID, int32_t aOffset) returns (bool aValid);
async SetCaretOffset(uint64_t aID, int32_t aOffset);
prio(high) sync CharacterCount(uint64_t aID) returns(int32_t aCount);
prio(high) sync SelectionCount(uint64_t aID) returns(int32_t aCount);
prio(high) sync TextSubstring(uint64_t aID, int32_t aStartOffset, int32_t

View File

@ -216,12 +216,10 @@ ProxyAccessible::CaretOffset()
return offset;
}
bool
void
ProxyAccessible::SetCaretOffset(int32_t aOffset)
{
bool valid = false;
unused << mDoc->SendSetCaretOffset(mID, aOffset, &valid);
return valid;
unused << mDoc->SendSetCaretOffset(mID, aOffset);
}
int32_t

View File

@ -132,7 +132,7 @@ public:
int32_t CaretLineNumber();
int32_t CaretOffset();
bool SetCaretOffset(int32_t aOffset);
void SetCaretOffset(int32_t aOffset);
int32_t CharacterCount();
int32_t SelectionCount();

View File

@ -73,7 +73,20 @@ var OutputGenerator = {
[addOutput(node) for // jshint ignore:line
(node of aContext.subtreeGenerator(false, ignoreSubtree))]; // jshint ignore:line
addOutput(aContext.accessible);
// If there are any documents in new ancestry, find a first one and place
// it in the beginning of the utterance.
let doc, docIndex = contextStart.findIndex(
ancestor => ancestor.role === Roles.DOCUMENT);
if (docIndex > -1) {
doc = contextStart.splice(docIndex, 1)[0];
}
contextStart.reverse().forEach(addOutput);
if (doc) {
output.unshift.apply(output, self.genForObject(doc, aContext));
}
}
return output;

View File

@ -32,13 +32,13 @@
// Simple traversal forward
[ContentMessages.simpleMoveNext,
new ExpectedCursorChange(
['Phone status bar', 'Traversal Rule test document'],
['Traversal Rule test document', 'Phone status bar'],
{ focused: 'body' })],
[ContentMessages.simpleMovePrevious, new ExpectedNoMove()],
[ContentMessages.simpleMoveNext,
new ExpectedCursorChange(["Back", {"string": "pushbutton"}])],
[ContentMessages.simpleMoveNext, new ExpectedCursorChange(
['wow', {'string': 'headingLevel', 'args': [1]} ,'such app'],
['such app', 'wow', {'string': 'headingLevel', 'args': [1]}],
{ focused: 'iframe' })],
[ContentMessages.simpleMoveNext,
new ExpectedCursorChange(['many option', {'string': 'stateNotChecked'},
@ -79,7 +79,7 @@
[ContentMessages.simpleMovePrevious,
new ExpectedCursorChange(['Home', {'string': 'pushbutton'}])],
[ContentMessages.simpleMovePrevious,
new ExpectedCursorChange(['much range', '6', {'string': 'slider'}, 'such app'])],
new ExpectedCursorChange(['such app', 'much range', '6', {'string': 'slider'}])],
[ContentMessages.moveOrAdjustDown(), new ExpectedValueChange('5')],
[ContentMessages.androidScrollForward(), new ExpectedValueChange('6')],
[ContentMessages.androidScrollBackward(), new ExpectedValueChange('5')],
@ -106,7 +106,7 @@
// fails. Bug 972035.
[ContentMessages.simpleMoveNext,
new ExpectedCursorChange(
['wow', {'string': 'headingLevel', 'args': [1]}, 'such app'])],
['such app', 'wow', {'string': 'headingLevel', 'args': [1]}])],
// Move from an inner frame to the last element in the parent doc
[ContentMessages.simpleMoveLast,
new ExpectedCursorChange(
@ -115,13 +115,13 @@
[ContentMessages.clearCursor, 'AccessFu:CursorCleared'],
[ContentMessages.simpleMoveNext,
new ExpectedCursorChange(['Phone status bar', 'Traversal Rule test document'])],
new ExpectedCursorChange(['Traversal Rule test document', 'Phone status bar'])],
[ContentMessages.moveOrAdjustDown('FormElement'),
new ExpectedCursorChange(['Back', {"string": "pushbutton"}])],
[ContentMessages.moveOrAdjustDown('FormElement'),
new ExpectedCursorChange(['many option', {'string': 'stateNotChecked'},
new ExpectedCursorChange(['such app', 'many option', {'string': 'stateNotChecked'},
{'string': 'checkbutton'}, {'string': 'listStart'},
{'string': 'list'}, {'string': 'listItemsCount', 'count': 1}, 'such app'])],
{'string': 'list'}, {'string': 'listItemsCount', 'count': 1}])],
[ContentMessages.moveOrAdjustDown('FormElement'),
new ExpectedCursorChange(['much range', '5', {'string': 'slider'}])],
// Calling AdjustOrMove should adjust the range.
@ -143,11 +143,11 @@
// Moving to the absolute first item from an embedded document
// fails. Bug 972035.
[ContentMessages.simpleMoveNext,
new ExpectedCursorChange(['Phone status bar', 'Traversal Rule test document'])],
new ExpectedCursorChange(['Traversal Rule test document', 'Phone status bar'])],
[ContentMessages.simpleMoveNext,
new ExpectedCursorChange(["Back", {"string": "pushbutton"}])],
[ContentMessages.simpleMoveNext,
new ExpectedCursorChange(['wow', {'string': 'headingLevel', 'args': [1]}, 'such app'])],
new ExpectedCursorChange(['such app', 'wow', {'string': 'headingLevel', 'args': [1]}])],
[ContentMessages.simpleMoveNext, new ExpectedCursorChange(
['many option', {'string': 'stateNotChecked'},
{'string': 'checkbutton'}, {'string': 'listStart'},
@ -160,7 +160,7 @@
// Current virtual cursor's position's name changes
[ContentMessages.simpleMoveNext,
new ExpectedCursorChange(['Phone status bar', 'Traversal Rule test document'])],
new ExpectedCursorChange(['Traversal Rule test document', 'Phone status bar'])],
[ContentMessages.focusSelector('button#fruit', false),
new ExpectedCursorChange(['apple', {'string': 'pushbutton'}])],
[doc.defaultView.renameFruit, new ExpectedNameChange('banana')],
@ -177,7 +177,7 @@
// Move cursor with focus in outside document
[ContentMessages.simpleMoveNext,
new ExpectedCursorChange(['Phone status bar', 'Traversal Rule test document'])],
new ExpectedCursorChange(['Traversal Rule test document', 'Phone status bar'])],
[ContentMessages.focusSelector('button#home', false),
new ExpectedCursorChange(['Home', {'string': 'pushbutton'}])],
@ -188,11 +188,11 @@
// Set focus on element outside of embedded frame while
// cursor is in frame
[ContentMessages.simpleMoveNext,
new ExpectedCursorChange(['Phone status bar', 'Traversal Rule test document'])],
new ExpectedCursorChange(['Traversal Rule test document', 'Phone status bar'])],
[ContentMessages.simpleMoveNext,
new ExpectedCursorChange(["Back", {"string": "pushbutton"}])],
[ContentMessages.simpleMoveNext,
new ExpectedCursorChange(['wow', {'string': 'headingLevel', 'args': [1]}, 'such app'])],
new ExpectedCursorChange(['such app', 'wow', {'string': 'headingLevel', 'args': [1]}])],
[ContentMessages.focusSelector('button#home', false),
new ExpectedCursorChange(['Home', {'string': 'pushbutton'}])],
@ -206,12 +206,12 @@
// aria-hidden element that the virtual cursor is positioned on
[ContentMessages.simpleMoveNext,
new ExpectedCursorChange(['Phone status bar', 'Traversal Rule test document'])],
new ExpectedCursorChange(['Traversal Rule test document', 'Phone status bar'])],
[ContentMessages.simpleMoveNext,
new ExpectedCursorChange(["Back", {"string": "pushbutton"}])],
[doc.defaultView.ariaHideBack,
new ExpectedCursorChange(
["wow", {"string": "headingLevel","args": [1]}, "such app"])],
["such app", "wow", {"string": "headingLevel","args": [1]}])],
// Changing aria-hidden attribute twice and making sure that the event
// is fired only once when the actual change happens.
[doc.defaultView.ariaHideBack],
@ -222,11 +222,11 @@
// aria-hidden on the iframe that has the vc.
[ContentMessages.simpleMoveNext,
new ExpectedCursorChange(['Phone status bar', 'Traversal Rule test document'])],
new ExpectedCursorChange(['Traversal Rule test document', 'Phone status bar'])],
[ContentMessages.simpleMoveNext,
new ExpectedCursorChange(["Back", {"string": "pushbutton"}])],
[ContentMessages.simpleMoveNext,
new ExpectedCursorChange(['wow', {'string': 'headingLevel', 'args': [1]}, 'such app'])],
new ExpectedCursorChange(['such app', 'wow', {'string': 'headingLevel', 'args': [1]}])],
[doc.defaultView.ariaHideIframe,
new ExpectedCursorChange(['Home', {'string': 'pushbutton'}])],
[doc.defaultView.ariaShowIframe],
@ -234,37 +234,39 @@
// aria-hidden element and auto Move
[ContentMessages.simpleMoveNext,
new ExpectedCursorChange(['Phone status bar', 'Traversal Rule test document'])],
new ExpectedCursorChange(['Traversal Rule test document', 'Phone status bar'])],
[doc.defaultView.ariaHideBack],
[ContentMessages.focusSelector('button#back', false),
// Must not speak Back button as it is aria-hidden
new ExpectedCursorChange(
["wow", {"string": "headingLevel","args": [1]}, "such app"])],
["such app", "wow", {"string": "headingLevel","args": [1]}])],
[doc.defaultView.ariaShowBack],
[ContentMessages.focusSelector('button#back', true), null],
[ContentMessages.clearCursor, 'AccessFu:CursorCleared'],
// Open dialog in outer doc, while cursor is also in outer doc
[ContentMessages.simpleMoveLast,
new ExpectedCursorChange(['mover'])],
new ExpectedCursorChange(['Traversal Rule test document', 'mover',
'medium', {'string': 'slider'}])],
[doc.defaultView.showAlert,
new ExpectedCursorChange(['This is an alert!',
{'string': 'headingLevel', 'args': [1]},
{'string': 'dialog'}])],
[doc.defaultView.hideAlert,
new ExpectedCursorChange(['mover'])],
new ExpectedCursorChange(['Traversal Rule test document', 'mover',
'medium', {'string': 'slider'}])],
[ContentMessages.clearCursor, 'AccessFu:CursorCleared'],
// Open dialog in outer doc, while cursor is in inner frame
[ContentMessages.simpleMoveNext,
new ExpectedCursorChange(['Phone status bar', 'Traversal Rule test document'])],
new ExpectedCursorChange(['Traversal Rule test document', 'Phone status bar'])],
[ContentMessages.simpleMoveNext,
new ExpectedCursorChange(["Back", {"string": "pushbutton"}])],
[ContentMessages.simpleMoveNext,
new ExpectedCursorChange(
['wow', {'string': 'headingLevel', 'args': [1]}, 'such app'])],
['such app', 'wow', {'string': 'headingLevel', 'args': [1]}])],
[doc.defaultView.showAlert, new ExpectedCursorChange(['This is an alert!',
{'string': 'headingLevel', 'args': [1]},
{'string': 'dialog'}])],
@ -276,13 +278,13 @@
[ContentMessages.activateCurrent(),
new ExpectedClickAction(),
new ExpectedCursorChange(
['wow', {'string': 'headingLevel', 'args': [1]}, 'such app'])],
['such app', 'wow', {'string': 'headingLevel', 'args': [1]}])],
[ContentMessages.clearCursor, 'AccessFu:CursorCleared'],
// Open dialog, then focus on something when closing
[ContentMessages.simpleMoveNext,
new ExpectedCursorChange(['Phone status bar', 'Traversal Rule test document'])],
new ExpectedCursorChange(['Traversal Rule test document', 'Phone status bar'])],
[doc.defaultView.showAlert,
new ExpectedCursorChange(['This is an alert!',
{'string': 'headingLevel', 'args': [1]}, {'string': 'dialog'}])],
@ -290,8 +292,8 @@
[function hideAlertAndFocusHomeButton() {
doc.defaultView.hideAlert();
doc.querySelector('button#home').focus();
}, new ExpectedCursorChange(['Home', {'string': 'pushbutton'},
'Traversal Rule test document'])],
}, new ExpectedCursorChange(['Traversal Rule test document',
'Home', {'string': 'pushbutton'}])],
[ContentMessages.simpleMoveNext,
new ExpectedCursorChange(['banana', {'string': 'pushbutton'}])]
[ContentMessages.simpleMoveNext, new ExpectedNoMove()]

View File

@ -31,9 +31,9 @@
// Read-only text tests
[ContentMessages.simpleMoveFirst,
new ExpectedCursorChange(
['These are my awards, Mother. From Army. The seal is for ' +
'marksmanship, and the gorilla is for sand racing.',
'Text content test document'])],
['Text content test document', 'These are my awards, Mother. ' +
'From Army. The seal is for marksmanship, and the gorilla is ' +
'for sand racing.'])],
[ContentMessages.moveNextBy('word'),
new ExpectedCursorTextChange('These', 0, 5)],
[ContentMessages.moveNextBy('word'),

View File

@ -434,7 +434,8 @@ ia2AccessibleText::setCaretOffset(long aOffset)
A11Y_TRYBLOCK_BEGIN
if (ProxyAccessible* proxy = HyperTextProxyFor(this)) {
return proxy->SetCaretOffset(aOffset) ? S_OK : E_INVALIDARG;
proxy->SetCaretOffset(aOffset);
return S_OK;
}
HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);

View File

@ -698,6 +698,10 @@ var settingsToObserve = {
prefName: 'dom.sms.maxReadAheadEntries',
defaultValue: 7
},
'services.sync.enabled': {
defaultValue: false,
notifyChange: true
},
'ui.touch.radius.leftmm': {
resetToPref: true
},
@ -717,6 +721,18 @@ var settingsToObserve = {
'wap.UAProf.url': ''
};
function settingObserver(setPref, prefName, setting) {
return value => {
setPref(prefName, value);
if (setting.notifyChange) {
SystemAppProxy._sendCustomEvent('mozPrefChromeEvent', {
prefName: prefName,
value: value
});
}
};
}
for (let key in settingsToObserve) {
let setting = settingsToObserve[key];
@ -766,7 +782,6 @@ for (let key in settingsToObserve) {
break;
}
SettingsListener.observe(key, defaultValue, function(value) {
setPref(prefName, value);
});
SettingsListener.observe(key, defaultValue,
settingObserver(setPref, prefName, setting));
};

View File

@ -156,7 +156,8 @@ this.FxAccountsMgmtService = {
case "signIn":
case "signUp":
case "refreshAuthentication":
FxAccountsManager[data.method](data.email, data.password).then(
FxAccountsManager[data.method](data.email, data.password,
data.fetchKeys).then(
user => {
self._onFulfill(msg.id, user);
},

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8ea9029190af2ffeb04dcd97b323738125e31a0e"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8999f0ba6326d815c8366e3c1155b7e4e9763b40"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8ea9029190af2ffeb04dcd97b323738125e31a0e"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8999f0ba6326d815c8366e3c1155b7e4e9763b40"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>

View File

@ -19,7 +19,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="8ea9029190af2ffeb04dcd97b323738125e31a0e"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="8999f0ba6326d815c8366e3c1155b7e4e9763b40"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="4ace9aaee0e048dfda11bb787646c59982a3dc80"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8ea9029190af2ffeb04dcd97b323738125e31a0e"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8999f0ba6326d815c8366e3c1155b7e4e9763b40"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="31a7849fe9a8b743d6f5e5facc212f0ef9d57499"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0c28789b9957913be975eb002a22323f93585d4c"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8ea9029190af2ffeb04dcd97b323738125e31a0e"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8999f0ba6326d815c8366e3c1155b7e4e9763b40"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8ea9029190af2ffeb04dcd97b323738125e31a0e"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8999f0ba6326d815c8366e3c1155b7e4e9763b40"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -19,7 +19,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="8ea9029190af2ffeb04dcd97b323738125e31a0e"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="8999f0ba6326d815c8366e3c1155b7e4e9763b40"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="4ace9aaee0e048dfda11bb787646c59982a3dc80"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8ea9029190af2ffeb04dcd97b323738125e31a0e"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8999f0ba6326d815c8366e3c1155b7e4e9763b40"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>

View File

@ -1,9 +1,9 @@
{
"git": {
"git_revision": "8ea9029190af2ffeb04dcd97b323738125e31a0e",
"git_revision": "8999f0ba6326d815c8366e3c1155b7e4e9763b40",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
"revision": "25790d1036e01366a957eed0ade6c259f5442cbf",
"revision": "983b7ecb17c67b9fb511f400bb5b28b9069eea00",
"repo_path": "integration/gaia-central"
}

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8ea9029190af2ffeb04dcd97b323738125e31a0e"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8999f0ba6326d815c8366e3c1155b7e4e9763b40"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>

View File

@ -18,7 +18,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8ea9029190af2ffeb04dcd97b323738125e31a0e"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8999f0ba6326d815c8366e3c1155b7e4e9763b40"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="31a7849fe9a8b743d6f5e5facc212f0ef9d57499"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0c28789b9957913be975eb002a22323f93585d4c"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8ea9029190af2ffeb04dcd97b323738125e31a0e"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8999f0ba6326d815c8366e3c1155b7e4e9763b40"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>

View File

@ -3,8 +3,8 @@
"clang_version": "r247539"
},
{
"size": 105219872,
"digest": "aa8de2fa535d0667e079019c475c631ea008f1bb5228505510867255b4d9c30663e2c97e579220a575a5887aa3bcf250021b50f76b90c2fa8c65a7aa19270066",
"size": 106877168,
"digest": "1c50c6348eaf429ed59bb603cff63bcc1f870f59216dd3c234db5b1156cfd351d5ee7b820ec31be4d2661eb4213b2e0030e2ba2782b42905d1ec19c7f8bd322a",
"algorithm": "sha512",
"filename": "clang.tar.xz",
"unpack": true,

View File

@ -3,8 +3,8 @@
"clang_version": "r247539"
},
{
"size": 105219872,
"digest": "aa8de2fa535d0667e079019c475c631ea008f1bb5228505510867255b4d9c30663e2c97e579220a575a5887aa3bcf250021b50f76b90c2fa8c65a7aa19270066",
"size": 106877168,
"digest": "1c50c6348eaf429ed59bb603cff63bcc1f870f59216dd3c234db5b1156cfd351d5ee7b820ec31be4d2661eb4213b2e0030e2ba2782b42905d1ec19c7f8bd322a",
"algorithm": "sha512",
"filename": "clang.tar.xz",
"unpack": true

View File

@ -3,8 +3,8 @@
"clang_version": "r247539"
},
{
"size": 105219872,
"digest": "aa8de2fa535d0667e079019c475c631ea008f1bb5228505510867255b4d9c30663e2c97e579220a575a5887aa3bcf250021b50f76b90c2fa8c65a7aa19270066",
"size": 106877168,
"digest": "1c50c6348eaf429ed59bb603cff63bcc1f870f59216dd3c234db5b1156cfd351d5ee7b820ec31be4d2661eb4213b2e0030e2ba2782b42905d1ec19c7f8bd322a",
"algorithm": "sha512",
"filename": "clang.tar.xz",
"unpack": true

View File

@ -3,8 +3,8 @@
"clang_version": "r247539"
},
{
"size": 121393888,
"digest": "6ae4e651e545538e6de326a7fb8b44b6e6d0b3acdb6a969ecb2b6f63b9995bbad2111cabf044ba575464f17f1f948d78ec92ad3a6922a7bfdf3ad6b6b2cad050",
"size": 121389802,
"digest": "2be6b42cfa1e92de4b49a57123f54043fec2d3cf8385276516dc6aaed99c88768ac4aebd7ce2e007ab074163523da29223436a4d1aef82f0f750f08f1b14cd71",
"algorithm": "sha512",
"filename": "clang.tar.bz2",
"unpack": true

View File

@ -3,8 +3,8 @@
"clang_version": "r247539"
},
{
"size": 105219872,
"digest": "aa8de2fa535d0667e079019c475c631ea008f1bb5228505510867255b4d9c30663e2c97e579220a575a5887aa3bcf250021b50f76b90c2fa8c65a7aa19270066",
"size": 106877168,
"digest": "1c50c6348eaf429ed59bb603cff63bcc1f870f59216dd3c234db5b1156cfd351d5ee7b820ec31be4d2661eb4213b2e0030e2ba2782b42905d1ec19c7f8bd322a",
"algorithm": "sha512",
"filename": "clang.tar.xz",
"unpack": true

View File

@ -1,12 +1,12 @@
[
{
"clang_version": "r183744"
"clang_version": "r247539"
},
{
"size": 59602619,
"digest": "86662ebc0ef650490559005948c4f0cb015dad72c7cac43732c2bf2995247081e30c139cf8008d19670a0009fc302c4eee2676981ee3f9ff4a15c01af22b783b",
"algorithm": "sha512",
"filename": "clang.tar.bz2",
"size": 97314461,
"digest": "9a74670fa917f760a4767923485d5166bbd258a8023c8aeb899b8c4d22f2847be76508ac5f26d7d2193318a2bb368a71bc62888d1bfe9d81eb45329a60451aa4",
"algorithm": "sha512",
"filename": "clang.tar.xz",
"unpack": true
},
{

View File

@ -13,8 +13,20 @@
"cc": "/home/worker/workspace/build/src/gcc/bin/gcc",
"cxx": "/home/worker/workspace/build/src/gcc/bin/g++",
"patches": {
"macosx64": ["llvm-debug-frame.patch"],
"linux64": ["llvm-debug-frame.patch"],
"linux32": ["llvm-debug-frame.patch"]
"macosx64": [
"llvm-debug-frame.patch",
"query-selector-visibility.patch",
"return-empty-string-non-mangled.patch"
],
"linux64": [
"llvm-debug-frame.patch",
"query-selector-visibility.patch",
"return-empty-string-non-mangled.patch"
],
"linux32": [
"llvm-debug-frame.patch",
"query-selector-visibility.patch",
"return-empty-string-non-mangled.patch"
]
}
}

View File

@ -13,8 +13,20 @@
"cc": "/home/worker/workspace/build/src/gcc/bin/gcc",
"cxx": "/home/worker/workspace/build/src/gcc/bin/g++",
"patches": {
"macosx64": ["llvm-debug-frame.patch"],
"linux64": ["llvm-debug-frame.patch"],
"linux32": ["llvm-debug-frame.patch"]
"macosx64": [
"llvm-debug-frame.patch",
"query-selector-visibility.patch",
"return-empty-string-non-mangled.patch"
],
"linux64": [
"llvm-debug-frame.patch",
"query-selector-visibility.patch",
"return-empty-string-non-mangled.patch"
],
"linux32": [
"llvm-debug-frame.patch",
"query-selector-visibility.patch",
"return-empty-string-non-mangled.patch"
]
}
}

View File

@ -12,8 +12,20 @@
"cc": "/usr/bin/clang",
"cxx": "/usr/bin/clang++",
"patches": {
"macosx64": ["llvm-debug-frame.patch"],
"linux64": ["llvm-debug-frame.patch"],
"linux32": ["llvm-debug-frame.patch"]
"macosx64": [
"llvm-debug-frame.patch",
"query-selector-visibility.patch",
"return-empty-string-non-mangled.patch"
],
"linux64": [
"llvm-debug-frame.patch",
"query-selector-visibility.patch",
"return-empty-string-non-mangled.patch"
],
"linux32": [
"llvm-debug-frame.patch",
"query-selector-visibility.patch",
"return-empty-string-non-mangled.patch"
]
}
}

View File

@ -0,0 +1,79 @@
commit 865b9340996f9f9d04b73b187248737dc6fd845e
Author: Michael Wu <mwu@mozilla.com>
Date: Mon Sep 14 17:47:21 2015 -0400
Add support for querying the visibility of a cursor
diff --git a/llvm/tools/clang/include/clang-c/Index.h b/llvm/tools/clang/include/clang-c/Index.h
index fad9cfa..311bfcb 100644
--- a/llvm/tools/clang/include/clang-c/Index.h
+++ b/llvm/tools/clang/include/clang-c/Index.h
@@ -2440,6 +2440,24 @@ enum CXLinkageKind {
CINDEX_LINKAGE enum CXLinkageKind clang_getCursorLinkage(CXCursor cursor);
/**
+ * \brief Describe the visibility of the entity referred to by a cursor.
+ */
+enum CXVisibilityKind {
+ /** \brief This value indicates that no visibility information is available
+ * for a provided CXCursor. */
+ CXVisibility_Invalid,
+
+ /** \brief Symbol not seen by the linker. */
+ CXVisibility_Hidden,
+ /** \brief Symbol seen by the linker but resolves to a symbol inside this object. */
+ CXVisibility_Protected,
+ /** \brief Symbol seen by the linker and acts like a normal symbol. */
+ CXVisibility_Default,
+};
+
+CINDEX_LINKAGE enum CXVisibilityKind clang_getCursorVisibility(CXCursor cursor);
+
+/**
* \brief Determine the availability of the entity that this cursor refers to,
* taking the current target platform into account.
*
diff --git a/llvm/tools/clang/tools/libclang/CIndex.cpp b/llvm/tools/clang/tools/libclang/CIndex.cpp
index 8225a6c..9fa18d3 100644
--- a/llvm/tools/clang/tools/libclang/CIndex.cpp
+++ b/llvm/tools/clang/tools/libclang/CIndex.cpp
@@ -6361,6 +6361,27 @@ CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
} // end: extern "C"
//===----------------------------------------------------------------------===//
+// Operations for querying visibility of a cursor.
+//===----------------------------------------------------------------------===//
+
+extern "C" {
+CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
+ if (!clang_isDeclaration(cursor.kind))
+ return CXVisibility_Invalid;
+
+ const Decl *D = cxcursor::getCursorDecl(cursor);
+ if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
+ switch (ND->getVisibility()) {
+ case HiddenVisibility: return CXVisibility_Hidden;
+ case ProtectedVisibility: return CXVisibility_Protected;
+ case DefaultVisibility: return CXVisibility_Default;
+ };
+
+ return CXVisibility_Invalid;
+}
+} // end: extern "C"
+
+//===----------------------------------------------------------------------===//
// Operations for querying language of a cursor.
//===----------------------------------------------------------------------===//
diff --git a/llvm/tools/clang/tools/libclang/libclang.exports b/llvm/tools/clang/tools/libclang/libclang.exports
index f6a7175..a919a8e 100644
--- a/llvm/tools/clang/tools/libclang/libclang.exports
+++ b/llvm/tools/clang/tools/libclang/libclang.exports
@@ -173,6 +173,7 @@ clang_getCursorSemanticParent
clang_getCursorSpelling
clang_getCursorType
clang_getCursorUSR
+clang_getCursorVisibility
clang_getDeclObjCTypeEncoding
clang_getDefinitionSpellingAndExtent
clang_getDiagnostic

View File

@ -0,0 +1,21 @@
commit 009de5ea7a1913f0b4619cf514787bd52af38c28
Author: Michael Wu <mwu@mozilla.com>
Date: Thu Sep 24 11:36:08 2015 -0400
Return an empty string when a symbol isn't mangled
diff --git a/llvm/tools/clang/tools/libclang/CIndex.cpp b/llvm/tools/clang/tools/libclang/CIndex.cpp
index 9fa18d3..1253832 100644
--- a/llvm/tools/clang/tools/libclang/CIndex.cpp
+++ b/llvm/tools/clang/tools/libclang/CIndex.cpp
@@ -3891,6 +3891,10 @@ CXString clang_Cursor_getMangling(CXCursor C) {
ASTContext &Ctx = ND->getASTContext();
std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
+ // Don't mangle if we don't need to.
+ if (!MC->shouldMangleCXXName(ND))
+ return cxstring::createEmpty();
+
std::string FrontendBuf;
llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
MC->mangleName(ND, FrontendBufOS);

View File

@ -7,13 +7,14 @@ import subprocess
def get_all_toplevel_filenames():
'''Get a list of all the files in the (Mercurial or Git) repository.'''
failed_cmds = []
try:
cmd = ['hg', 'manifest', '-q']
all_filenames = subprocess.check_output(cmd, universal_newlines=True,
stderr=subprocess.PIPE).split('\n')
return all_filenames
except:
pass
failed_cmds.append(cmd)
try:
# Get the relative path to the top-level directory.
@ -25,6 +26,6 @@ def get_all_toplevel_filenames():
stderr=subprocess.PIPE).split('\n')
return all_filenames
except:
pass
failed_cmds.append(cmd)
raise Exception('failed to run any of the repo manifest commands', cmds)
raise Exception('failed to run any of the repo manifest commands', failed_cmds)

View File

@ -37,6 +37,7 @@
#include "mozilla/dom/WindowBinding.h"
#include "mozilla/dom/ElementBinding.h"
#include "Units.h"
#include "nsContentListDeclarations.h"
class nsIFrame;
class nsIDOMMozNamedAttrMap;
@ -61,11 +62,6 @@ namespace dom {
} // namespace mozilla
already_AddRefed<nsContentList>
NS_GetContentList(nsINode* aRootNode,
int32_t aMatchNameSpaceId,
const nsAString& aTagname);
#define ELEMENT_FLAG_BIT(n_) NODE_FLAG_BIT(NODE_TYPE_SPECIFIC_BITS_OFFSET + (n_))
// Element-specific flags

View File

@ -198,7 +198,8 @@ NS_GetContentList(nsINode* aRootNode,
NS_ASSERTION(aRootNode, "content list has to have a root");
nsRefPtr<nsContentList> list;
nsContentListKey hashKey(aRootNode, aMatchNameSpaceId, aTagname);
nsContentListKey hashKey(aRootNode, aMatchNameSpaceId, aTagname,
aRootNode->OwnerDoc()->IsHTMLDocument());
uint32_t recentlyUsedCacheIndex = RecentlyUsedCacheIndex(hashKey);
nsContentList* cachedList = sRecentlyUsedContentLists[recentlyUsedCacheIndex];
if (cachedList && cachedList->MatchesKey(hashKey)) {
@ -398,7 +399,8 @@ nsContentList::nsContentList(nsINode* aRootNode,
mData(nullptr),
mState(LIST_DIRTY),
mDeep(aDeep),
mFuncMayDependOnAttr(false)
mFuncMayDependOnAttr(false),
mIsHTMLDocument(aRootNode->OwnerDoc()->IsHTMLDocument())
{
NS_ASSERTION(mRootNode, "Must have root");
if (nsGkAtoms::_asterisk == mHTMLMatchAtom) {
@ -438,7 +440,8 @@ nsContentList::nsContentList(nsINode* aRootNode,
mState(LIST_DIRTY),
mMatchAll(false),
mDeep(aDeep),
mFuncMayDependOnAttr(aFuncMayDependOnAttr)
mFuncMayDependOnAttr(aFuncMayDependOnAttr),
mIsHTMLDocument(false)
{
NS_ASSERTION(mRootNode, "Must have root");
mRootNode->AddMutationObserver(this);
@ -839,25 +842,20 @@ nsContentList::Match(Element *aElement)
if (!mXMLMatchAtom)
return false;
mozilla::dom::NodeInfo *ni = aElement->NodeInfo();
bool unknown = mMatchNameSpaceId == kNameSpaceID_Unknown;
bool wildcard = mMatchNameSpaceId == kNameSpaceID_Wildcard;
NodeInfo *ni = aElement->NodeInfo();
bool wildcard = mMatchNameSpaceId == kNameSpaceID_Wildcard ||
mMatchNameSpaceId == kNameSpaceID_Unknown;
bool toReturn = mMatchAll;
if (!unknown && !wildcard)
if (!wildcard)
toReturn &= ni->NamespaceEquals(mMatchNameSpaceId);
if (toReturn)
return toReturn;
bool matchHTML = aElement->GetNameSpaceID() == kNameSpaceID_XHTML &&
aElement->OwnerDoc()->IsHTMLDocument();
if (unknown) {
return matchHTML ? ni->QualifiedNameEquals(mHTMLMatchAtom) :
ni->QualifiedNameEquals(mXMLMatchAtom);
}
bool matchHTML =
mIsHTMLDocument && aElement->GetNameSpaceID() == kNameSpaceID_XHTML;
if (wildcard) {
return matchHTML ? ni->Equals(mHTMLMatchAtom) :
ni->Equals(mXMLMatchAtom);
@ -962,7 +960,7 @@ nsContentList::RemoveFromHashtable()
}
nsDependentAtomString str(mXMLMatchAtom);
nsContentListKey key(mRootNode, mMatchNameSpaceId, str);
nsContentListKey key(mRootNode, mMatchNameSpaceId, str, mIsHTMLDocument);
uint32_t recentlyUsedCacheIndex = RecentlyUsedCacheIndex(key);
if (sRecentlyUsedContentLists[recentlyUsedCacheIndex] == this) {
sRecentlyUsedContentLists[recentlyUsedCacheIndex] = nullptr;

View File

@ -142,14 +142,21 @@ private:
*/
struct nsContentListKey
{
// We have to take an aIsHTMLDocument arg for two reasons:
// 1) We don't want to include nsIDocument.h in this header.
// 2) We need to do that to make nsContentList::RemoveFromHashtable
// work, because by the time it's called the document of the
// list's root node might have changed.
nsContentListKey(nsINode* aRootNode,
int32_t aMatchNameSpaceId,
const nsAString& aTagname)
const nsAString& aTagname,
bool aIsHTMLDocument)
: mRootNode(aRootNode),
mMatchNameSpaceId(aMatchNameSpaceId),
mTagname(aTagname),
mIsHTMLDocument(aIsHTMLDocument),
mHash(mozilla::AddToHash(mozilla::HashString(aTagname), mRootNode,
mMatchNameSpaceId))
mMatchNameSpaceId, mIsHTMLDocument))
{
}
@ -157,6 +164,7 @@ struct nsContentListKey
: mRootNode(aContentListKey.mRootNode),
mMatchNameSpaceId(aContentListKey.mMatchNameSpaceId),
mTagname(aContentListKey.mTagname),
mIsHTMLDocument(aContentListKey.mIsHTMLDocument),
mHash(aContentListKey.mHash)
{
}
@ -169,6 +177,7 @@ struct nsContentListKey
nsINode* const mRootNode; // Weak ref
const int32_t mMatchNameSpaceId;
const nsAString& mTagname;
bool mIsHTMLDocument;
const uint32_t mHash;
};
@ -209,7 +218,7 @@ public:
* The special value "*" always matches whatever aMatchAtom
* is matched against.
* @param aMatchNameSpaceId If kNameSpaceID_Unknown, then aMatchAtom is the
* tagName to match.
* localName to match.
* If kNameSpaceID_Wildcard, then aMatchAtom is the
* localName to match.
* Otherwise we match nodes whose namespace is
@ -237,7 +246,8 @@ public:
* deeper. If true, then look at the whole subtree rooted at
* our root.
* @param aMatchAtom an atom to be passed back to aFunc
* @param aMatchNameSpaceId a namespace id to be passed back to aFunc
* @param aMatchNameSpaceId a namespace id to be passed back to aFunc. Is
allowed to be kNameSpaceID_Unknown.
* @param aFuncMayDependOnAttr a boolean that indicates whether this list is
* sensitive to attribute changes.
*/
@ -318,13 +328,15 @@ public:
{
// The root node is most commonly the same: the document. And the
// most common namespace id is kNameSpaceID_Unknown. So check the
// string first.
// string first. Cases in which whether our root's ownerDocument
// is HTML changes are extremely rare, so check those last.
NS_PRECONDITION(mXMLMatchAtom,
"How did we get here with a null match atom on our list?");
return
mXMLMatchAtom->Equals(aKey.mTagname) &&
mRootNode == aKey.mRootNode &&
mMatchNameSpaceId == aKey.mMatchNameSpaceId;
mMatchNameSpaceId == aKey.mMatchNameSpaceId &&
mIsHTMLDocument == aKey.mIsHTMLDocument;
}
/**
@ -445,6 +457,12 @@ protected:
* Whether we actually need to flush to get our state correct.
*/
uint8_t mFlushesNeeded : 1;
/**
* Whether the ownerDocument of our root node at list creation time was an
* HTML document. Only needed when we're doing a namespace/atom match, not
* when doing function matching, always false otherwise.
*/
uint8_t mIsHTMLDocument : 1;
#ifdef DEBUG_CONTENT_LIST
void AssertInSync();

View File

@ -9,12 +9,14 @@
#include <stdint.h>
#include "nsCOMPtr.h"
#include "nsStringFwd.h"
class nsContentList;
class nsIAtom;
class nsIContent;
class nsINode;
// Can't use nsStringFwd.h because that's internal-API-only.
class nsString;
class nsAString;
// Magic namespace id that means "match all namespaces". This is
// negative so it won't collide with actual namespace constants.
@ -42,8 +44,9 @@ typedef void* (*nsFuncStringContentListDataAllocator)(nsINode* aRootNode,
// If aMatchNameSpaceId is kNameSpaceID_Unknown, this will return a
// content list which matches ASCIIToLower(aTagname) against HTML
// elements in HTML documents and aTagname against everything else.
// For any other value of aMatchNameSpaceId, the list will match
// aTagname against all elements.
// The comparison is done to the element's localName. For any
// other value of aMatchNameSpaceId, the list will match aTagname
// against all elements, again comparing to the localName.
already_AddRefed<nsContentList>
NS_GetContentList(nsINode* aRootNode,
int32_t aMatchNameSpaceId,

View File

@ -28,6 +28,7 @@
#include "mozilla/UseCounter.h"
#include "mozilla/WeakPtr.h"
#include "Units.h"
#include "nsContentListDeclarations.h"
#include "nsExpirationTracker.h"
#include "nsClassHashtable.h"
#include "prclist.h"
@ -176,11 +177,6 @@ enum DocumentFlavor {
// Some function forward-declarations
class nsContentList;
already_AddRefed<nsContentList>
NS_GetContentList(nsINode* aRootNode,
int32_t aMatchNameSpaceId,
const nsAString& aTagname);
//----------------------------------------------------------------------
// Document interface. This is implemented by all document objects in

View File

@ -32,7 +32,7 @@ function test_getElementsByTagName()
do_check_eq(doc.getElementById("test2").getElementsByTagName("*").length,
8);
do_check_eq(doc.getElementById("test2").getElementsByTagName("test").length,
3);
7);
// Check that the first element of getElementsByTagName on the document is
// the right thing.
@ -40,7 +40,7 @@ function test_getElementsByTagName()
// Check that we get the right things in the right order
var numTests = doc.getElementsByTagName("test").length;
do_check_eq(numTests, 5);
do_check_eq(numTests, 14);
for (var i = 1; i <= numTests; ++i) {
do_check_true(doc.getElementById("test" + i) instanceof nsIDOMElement);
@ -51,15 +51,15 @@ function test_getElementsByTagName()
// Check that we handle tagnames containing ':' correctly
do_check_true(doc.getElementsByTagName("foo:test")
instanceof nsIDOMNodeList);
do_check_eq(doc.getElementsByTagName("foo:test").length, 2);
do_check_eq(doc.getElementsByTagName("foo:test").length, 0);
do_check_true(doc.getElementsByTagName("foo2:test")
instanceof nsIDOMNodeList);
do_check_eq(doc.getElementsByTagName("foo2:test").length, 3);
do_check_eq(doc.getElementsByTagName("foo2:test").length, 0);
do_check_true(doc.getElementsByTagName("bar:test")
instanceof nsIDOMNodeList);
do_check_eq(doc.getElementsByTagName("bar:test").length, 4);
do_check_eq(doc.getElementsByTagName("bar:test").length, 0);
}
function test_getElementsByTagNameNS()

View File

@ -700,6 +700,10 @@ DOMInterfaces = {
'notflattened': True
},
'IterableIterator': {
'skipGen': True
},
'KeyEvent': {
'concrete': False
},

View File

@ -1121,7 +1121,10 @@ class CGHeaders(CGWrapper):
# Now for non-callback descriptors make sure we include any
# headers needed by Func declarations.
for desc in descriptors:
if desc.interface.isExternal():
# If this is an iterator interface generated for a seperate
# iterable interface, skip generating type includes, as we have
# what we need in IterableIterator.h
if desc.interface.isExternal() or desc.interface.isIteratorInterface():
continue
def addHeaderForFunc(func):
@ -1148,16 +1151,15 @@ class CGHeaders(CGWrapper):
if funcList is not None:
addHeaderForFunc(funcList[0])
for desc in descriptors:
if desc.interface.maplikeOrSetlike:
if desc.interface.maplikeOrSetlikeOrIterable:
# We need ToJSValue.h for maplike/setlike type conversions
bindingHeaders.add("mozilla/dom/ToJSValue.h")
# Add headers for the key and value types of the maplike, since
# they'll be needed for convenience functions
addHeadersForType((desc.interface.maplikeOrSetlike.keyType,
addHeadersForType((desc.interface.maplikeOrSetlikeOrIterable.keyType,
desc, None))
if desc.interface.maplikeOrSetlike.valueType:
addHeadersForType((desc.interface.maplikeOrSetlike.valueType,
if desc.interface.maplikeOrSetlikeOrIterable.valueType:
addHeadersForType((desc.interface.maplikeOrSetlikeOrIterable.valueType,
desc, None))
for d in dictionaries:
@ -2197,13 +2199,18 @@ class MethodDefiner(PropertyDefiner):
})
continue
# Iterable methods should be enumerable, maplike/setlike methods
# should not.
isMaplikeOrSetlikeMethod = (m.isMaplikeOrSetlikeOrIterableMethod() and
(m.maplikeOrSetlikeOrIterable.isMaplike() or
m.maplikeOrSetlikeOrIterable.isSetlike()))
method = {
"name": m.identifier.name,
"methodInfo": not m.isStatic(),
"length": methodLength(m),
# Methods generated for a maplike/setlike declaration are not
# enumerable.
"flags": "JSPROP_ENUMERATE" if not m.isMaplikeOrSetlikeMethod() else "0",
"flags": "JSPROP_ENUMERATE" if not isMaplikeOrSetlikeMethod else "0",
"condition": PropertyDefiner.getControllingCondition(m, descriptor),
"allowCrossOriginThis": m.getExtendedAttribute("CrossOriginCallable"),
"returnsPromise": m.returnsPromise(),
@ -2247,19 +2254,23 @@ class MethodDefiner(PropertyDefiner):
# Generate the maplike/setlike iterator, if one wasn't already
# generated by a method. If we already have an @@iterator symbol, fail.
if descriptor.interface.maplikeOrSetlike:
if descriptor.interface.maplikeOrSetlikeOrIterable:
if hasIterator(methods, self.regular):
raise TypeError("Cannot have maplike/setlike interface with "
raise TypeError("Cannot have maplike/setlike/iterable interface with "
"other members that generate @@iterator "
"on interface %s, such as indexed getters "
"or aliased functions." %
self.descriptor.interface.identifier.name)
for m in methods:
if (m.isMaplikeOrSetlikeMethod() and
((m.maplikeOrSetlike.isMaplike() and
m.identifier.name == "entries") or
(m.maplikeOrSetlike.isSetlike() and
m.identifier.name == "values"))):
if (m.isMaplikeOrSetlikeOrIterableMethod() and
(((m.maplikeOrSetlikeOrIterable.isMaplike() or
(m.maplikeOrSetlikeOrIterable.isIterable() and
m.maplikeOrSetlikeOrIterable.hasValueType())) and
m.identifier.name == "entries") or
(((m.maplikeOrSetlikeOrIterable.isSetlike() or
(m.maplikeOrSetlikeOrIterable.isIterable() and
not m.maplikeOrSetlikeOrIterable.hasValueType()))) and
m.identifier.name == "values"))):
self.regular.append({
"name": "@@iterator",
"methodName": m.identifier.name,
@ -5810,8 +5821,10 @@ class CGArgumentConverter(CGThing):
# If we have a method generated by the maplike/setlike portion of an
# interface, arguments can possibly be undefined, but will need to be
# converted to the key/value type of the backing object. In this case,
# use .get() instead of direct access to the argument.
if member.isMethod() and member.isMaplikeOrSetlikeMethod():
# use .get() instead of direct access to the argument. This won't
# matter for iterable since generated functions for those interface
# don't take arguments.
if member.isMethod() and member.isMaplikeOrSetlikeOrIterableMethod():
self.replacementVariables["val"] = string.Template(
"args.get(${index})").substitute(replacer)
else:
@ -7111,10 +7124,16 @@ class CGPerSignatureCall(CGThing):
# If this is a method that was generated by a maplike/setlike
# interface, use the maplike/setlike generator to fill in the body.
# Otherwise, use CGCallGenerator to call the native method.
if idlNode.isMethod() and idlNode.isMaplikeOrSetlikeMethod():
cgThings.append(CGMaplikeOrSetlikeMethodGenerator(descriptor,
idlNode.maplikeOrSetlike,
idlNode.identifier.name))
if idlNode.isMethod() and idlNode.isMaplikeOrSetlikeOrIterableMethod():
if (idlNode.maplikeOrSetlikeOrIterable.isMaplike() or
idlNode.maplikeOrSetlikeOrIterable.isSetlike()):
cgThings.append(CGMaplikeOrSetlikeMethodGenerator(descriptor,
idlNode.maplikeOrSetlikeOrIterable,
idlNode.identifier.name))
else:
cgThings.append(CGIterableMethodGenerator(descriptor,
idlNode.maplikeOrSetlikeOrIterable,
idlNode.identifier.name))
else:
cgThings.append(CGCallGenerator(
self.getErrorReport() if self.isFallible() else None,
@ -7349,7 +7368,7 @@ class CGMethodCall(CGThing):
# Skip required arguments check for maplike/setlike interfaces, as
# they can have arguments which are not passed, and are treated as
# if undefined had been explicitly passed.
if requiredArgs > 0 and not method.isMaplikeOrSetlikeMethod():
if requiredArgs > 0 and not method.isMaplikeOrSetlikeOrIterableMethod():
code = fill(
"""
if (MOZ_UNLIKELY(args.length() < ${requiredArgs})) {
@ -12779,6 +12798,10 @@ class CGForwardDeclarations(CGWrapper):
# Needed for at least Wrap.
for d in descriptors:
# If this is a generated iterator interface, we only create these
# in the generated bindings, and don't need to forward declare.
if d.interface.isIteratorInterface():
continue
builder.add(d.nativeType)
# If we're an interface and we have a maplike/setlike declaration,
# we'll have helper functions exposed to the native side of our
@ -12786,17 +12809,23 @@ class CGForwardDeclarations(CGWrapper):
# our key/value types are interfaces, they'll be passed as
# arguments to helper functions, and they'll need to be forward
# declared in the header.
if d.interface.maplikeOrSetlike:
builder.forwardDeclareForType(d.interface.maplikeOrSetlike.keyType,
config)
builder.forwardDeclareForType(d.interface.maplikeOrSetlike.valueType,
if d.interface.maplikeOrSetlikeOrIterable:
builder.forwardDeclareForType(d.interface.maplikeOrSetlikeOrIterable.keyType,
config)
if d.interface.maplikeOrSetlikeOrIterable.hasValueType():
builder.forwardDeclareForType(d.interface.maplikeOrSetlikeOrIterable.valueType,
config)
# We just about always need NativePropertyHooks
builder.addInMozillaDom("NativePropertyHooks", isStruct=True)
builder.addInMozillaDom("ProtoAndIfaceCache")
# Add the atoms cache type, even if we don't need it.
for d in descriptors:
# Iterators have native types that are template classes, so
# creating an 'Atoms' cache type doesn't work for them, and is one
# of the cases where we don't need it anyways.
if d.interface.isIteratorInterface():
continue
builder.add(d.nativeType + "Atoms", isStruct=True)
for callback in mainCallbacks:
@ -12859,6 +12888,8 @@ class CGBindingRoot(CGThing):
bindingDeclareHeaders["mozilla/dom/UnionMember.h"] = len(unionStructs) > 0
bindingDeclareHeaders["mozilla/dom/BindingUtils.h"] = len(unionStructs) > 0
bindingDeclareHeaders["mozilla/dom/IterableIterator.h"] = any(d.interface.isIteratorInterface() or
d.interface.isIterable() for d in descriptors)
def descriptorHasCrossOriginProperties(desc):
def hasCrossOriginProperty(m):
@ -12922,14 +12953,6 @@ class CGBindingRoot(CGThing):
bindingHeaders["nsIGlobalObject.h"] = jsImplemented
bindingHeaders["AtomList.h"] = hasNonEmptyDictionaries or jsImplemented or callbackDescriptors
def addHeaderBasedOnTypes(header, typeChecker):
bindingHeaders[header] = (
bindingHeaders.get(header, False) or
any(map(typeChecker,
getAllTypes(descriptors + callbackDescriptors,
dictionaries,
mainCallbacks + workerCallbacks))))
# Only mainthread things can have hasXPConnectImpls
provider = config.getDescriptorProvider(False)
@ -14966,7 +14989,7 @@ def getMaplikeOrSetlikeBackingObject(descriptor, maplikeOrSetlike, helperImpl=No
Generate code to get/create a JS backing object for a maplike/setlike
declaration from the declaration slot.
"""
func_prefix = maplikeOrSetlike.maplikeOrSetlikeType.title()
func_prefix = maplikeOrSetlike.maplikeOrSetlikeOrIterableType.title()
ret = fill(
"""
JS::Rooted<JSObject*> backingObj(cx);
@ -15403,8 +15426,11 @@ class CGMaplikeOrSetlikeHelperGenerator(CGNamespace):
"""
def __init__(self, descriptor, maplikeOrSetlike):
self.descriptor = descriptor
# Since iterables are folded in with maplike/setlike, make sure we've
# got the right type here.
assert maplikeOrSetlike.isMaplike() or maplikeOrSetlike.isSetlike()
self.maplikeOrSetlike = maplikeOrSetlike
self.namespace = "%sHelpers" % (self.maplikeOrSetlike.maplikeOrSetlikeType.title())
self.namespace = "%sHelpers" % (self.maplikeOrSetlike.maplikeOrSetlikeOrIterableType.title())
self.helpers = [
CGMaplikeOrSetlikeHelperFunctionGenerator(descriptor,
maplikeOrSetlike,
@ -15436,6 +15462,26 @@ class CGMaplikeOrSetlikeHelperGenerator(CGNamespace):
CGNamespace.__init__(self, self.namespace, CGList(self.helpers))
class CGIterableMethodGenerator(CGGeneric):
"""
Creates methods for iterable interfaces. Unwrapping/wrapping
will be taken care of by the usual method generation machinery in
CGMethodCall/CGPerSignatureCall. Functionality is filled in here instead of
using CGCallGenerator.
"""
def __init__(self, descriptor, iterable, methodName):
CGGeneric.__init__(self, fill(
"""
typedef IterableIterator<${nativeType}> itrType;
nsRefPtr<itrType> result(new itrType(self,
itrType::IterableIteratorType::${itrMethod},
&${ifaceName}IteratorBinding::Wrap));
""",
nativeType=descriptor.nativeType,
ifaceName=descriptor.interface.identifier.name,
itrMethod=methodName.title()))
class GlobalGenRoots():
"""
Roots for global codegen.

View File

@ -26,6 +26,7 @@ class Configuration:
# |parseData|.
self.descriptors = []
self.interfaces = {}
self.descriptorsByName = {}
self.optimizedOutDescriptorNames = set()
self.generatedEvents = generatedEvents
self.maxProtoChainLength = 0
@ -86,15 +87,18 @@ class Configuration:
else:
raise TypeError("Interface " + iface.identifier.name +
" should have no more than two entries in Bindings.conf")
self.descriptors.extend([Descriptor(self, iface, x) for x in entry])
descs = [Descriptor(self, iface, x) for x in entry]
self.descriptors.extend(descs)
# Setting up descriptorsByName while iterating through interfaces
# means we can get the nativeType of iterable interfaces without
# having to do multiple loops.
for d in descs:
self.descriptorsByName.setdefault(d.interface.identifier.name,
[]).append(d)
# Keep the descriptor list sorted for determinism.
self.descriptors.sort(lambda x, y: cmp(x.name, y.name))
self.descriptorsByName = {}
for d in self.descriptors:
self.descriptorsByName.setdefault(d.interface.identifier.name,
[]).append(d)
self.descriptorsByFile = {}
for d in self.descriptors:
@ -348,7 +352,18 @@ class Descriptor(DescriptorProvider):
# Read the desc, and fill in the relevant defaults.
ifaceName = self.interface.identifier.name
if self.interface.isExternal():
# For generated iterator interfaces for other iterable interfaces, we
# just use IterableIterator as the native type, templated on the
# nativeType of the iterable interface. That way we can have a
# templated implementation for all the duplicated iterator
# functionality.
if self.interface.isIteratorInterface():
itrName = self.interface.iterableInterface.identifier.name
itrDesc = self.getDescriptor(itrName)
nativeTypeDefault = ("mozilla::dom::IterableIterator<%s>"
% itrDesc.nativeType)
elif self.interface.isExternal():
assert not self.workers
nativeTypeDefault = "nsIDOM" + ifaceName
elif self.interface.isCallback():
@ -386,6 +401,8 @@ class Descriptor(DescriptorProvider):
headerDefault = "mozilla/dom/workers/bindings/%s.h" % ifaceName
elif not self.interface.isExternal() and self.interface.getExtendedAttribute("HeaderFile"):
headerDefault = self.interface.getExtendedAttribute("HeaderFile")[0]
elif self.interface.isIteratorInterface():
headerDefault = "mozilla/dom/IterableIterator.h"
else:
headerDefault = self.nativeType
headerDefault = headerDefault.replace("::", "/") + ".h"
@ -514,6 +531,7 @@ class Descriptor(DescriptorProvider):
if desc.get('wantsQI', None) is not None:
self._wantsQI = desc.get('wantsQI', None)
self.wrapperCache = (not self.interface.isCallback() and
not self.interface.isIteratorInterface() and
desc.get('wrapperCache', True))
def make_name(name):

View File

@ -0,0 +1,35 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/IterableIterator.h"
namespace mozilla {
namespace dom {
// Due to IterableIterator being a templated class, we implement the necessary
// CC bits in a superclass that IterableIterator then inherits from. This allows
// us to put the macros outside of the header. The base class has pure virtual
// functions for Traverse/Unlink that the templated subclasses will override.
NS_IMPL_CYCLE_COLLECTION_CLASS(IterableIteratorBase)
NS_IMPL_CYCLE_COLLECTING_ADDREF(IterableIteratorBase)
NS_IMPL_CYCLE_COLLECTING_RELEASE(IterableIteratorBase)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(IterableIteratorBase)
tmp->TraverseHelper(cb);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(IterableIteratorBase)
tmp->UnlinkHelper();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(IterableIteratorBase)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
}
}

View File

@ -0,0 +1,192 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* The IterableIterator class is used for WebIDL interfaces that have a
* iterable<> member defined. It handles the ES6 Iterator-like functions that
* are generated for the iterable interface.
*
* For iterable interfaces, the implementation class will need to contain three
* functions:
*
* - size_t GetIterableLength()
* - Returns the number of elements available to iterate over
* - [type] GetKeyAtIndex(size_t index)
* - Returns the key at the requested index
* - [type] GetValueAtIndex(size_t index)
* - Returns the value at the requested index, or the key again if this is
* a single type iterator.
*
* Examples of iterable interface implementations can be found in the bindings
* test directory.
*/
#ifndef mozilla_dom_IterableIterator_h
#define mozilla_dom_IterableIterator_h
#include "nsISupports.h"
#include "nsWrapperCache.h"
#include "nsPIDOMWindow.h"
#include "nsCOMPtr.h"
#include "mozilla/dom/ToJSValue.h"
#include "jswrapper.h"
#include "mozilla/dom/IterableIteratorBinding.h"
namespace mozilla {
namespace dom {
class IterableIteratorBase : public nsISupports
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(IterableIteratorBase)
typedef enum {
Keys = 0,
Values,
Entries
} IterableIteratorType;
IterableIteratorBase() {}
protected:
virtual ~IterableIteratorBase() {}
virtual void UnlinkHelper() = 0;
virtual void TraverseHelper(nsCycleCollectionTraversalCallback& cb) = 0;
};
template <typename T>
class IterableIterator final : public IterableIteratorBase
{
public:
typedef bool (*WrapFunc)(JSContext* aCx,
mozilla::dom::IterableIterator<T>* aObject,
JS::Handle<JSObject*> aGivenProto,
JS::MutableHandle<JSObject*> aReflector);
IterableIterator(T* aIterableObj, IterableIteratorType aIteratorType, WrapFunc aWrapFunc)
: mIteratorType(aIteratorType)
, mIterableObj(aIterableObj)
, mIndex(0)
, mWrapFunc(aWrapFunc)
{
MOZ_ASSERT(mIterableObj);
MOZ_ASSERT(mWrapFunc);
}
void
DictReturn(JSContext* aCx, JS::MutableHandle<JSObject*> aResult,
bool aDone, JS::Handle<JS::Value> aValue, ErrorResult& aRv)
{
RootedDictionary<IterableKeyOrValueResult> dict(aCx);
dict.mDone = aDone;
dict.mValue = aValue;
JS::Rooted<JS::Value> dictValue(aCx);
if (!ToJSValue(aCx, dict, &dictValue)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
aResult.set(&dictValue.toObject());
}
void
Next(JSContext* aCx, JS::MutableHandle<JSObject*> aResult, ErrorResult& aRv)
{
JS::Rooted<JS::Value> value(aCx, JS::UndefinedValue());
if (mIndex >= mIterableObj->GetIterableLength()) {
DictReturn(aCx, aResult, true, value, aRv);
return;
}
switch (mIteratorType) {
case IterableIteratorType::Keys:
{
if (!ToJSValue(aCx, mIterableObj->GetKeyAtIndex(mIndex), &value)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
DictReturn(aCx, aResult, false, value, aRv);
break;
}
case IterableIteratorType::Values:
{
if (!ToJSValue(aCx, mIterableObj->GetValueAtIndex(mIndex), &value)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
DictReturn(aCx, aResult, false, value, aRv);
break;
}
case IterableIteratorType::Entries:
{
JS::Rooted<JS::Value> key(aCx);
if (!ToJSValue(aCx, mIterableObj->GetKeyAtIndex(mIndex), &key)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
if (!ToJSValue(aCx, mIterableObj->GetValueAtIndex(mIndex), &value)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
RootedDictionary<IterableKeyAndValueResult> dict(aCx);
dict.mDone = false;
// Dictionary values are a Sequence, which is a FallibleTArray, so we need
// to check returns when appending.
if (!dict.mValue.AppendElement(key, mozilla::fallible)) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return;
}
if (!dict.mValue.AppendElement(value, mozilla::fallible)) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return;
}
JS::Rooted<JS::Value> dictValue(aCx);
if (!ToJSValue(aCx, dict, &dictValue)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
aResult.set(&dictValue.toObject());
break;
}
default:
MOZ_CRASH("Invalid iterator type!");
}
++mIndex;
}
virtual ~IterableIterator() {}
bool
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aObj)
{
return (*mWrapFunc)(aCx, this, aGivenProto, aObj);
}
protected:
// Tells whether this is a key, value, or entries iterator.
IterableIteratorType mIteratorType;
// Binding Implementation Object that we're iterating over.
nsRefPtr<T> mIterableObj;
// Current index of iteration.
uint32_t mIndex;
// Function pointer to binding-type-specific Wrap() call for this iterator.
WrapFunc mWrapFunc;
// Since we're templated on a binding, we need to possibly CC it, but can't do
// that through macros. So it happens here.
virtual void UnlinkHelper() final
{
mIterableObj = nullptr;
}
virtual void TraverseHelper(nsCycleCollectionTraversalCallback& cb) override
{
IterableIterator<T>* tmp = this;
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIterableObj);
}
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_IterableIterator_h

View File

@ -27,6 +27,7 @@ EXPORTS.mozilla.dom += [
'DOMString.h',
'Errors.msg',
'Exceptions.h',
'IterableIterator.h',
'JSSlots.h',
'MozMap.h',
'NonRefcountedDOMObject.h',
@ -74,6 +75,7 @@ UNIFIED_SOURCES += [
'Date.cpp',
'DOMJSProxyHandler.cpp',
'Exceptions.cpp',
'IterableIterator.cpp',
'ToJSValue.cpp',
]
@ -88,12 +90,16 @@ SOURCES += [
# them are only run in debug mode.
if CONFIG['MOZ_DEBUG']:
EXPORTS.mozilla.dom += [
"test/TestInterfaceIterableDouble.h",
"test/TestInterfaceIterableSingle.h",
"test/TestInterfaceMaplike.h",
"test/TestInterfaceMaplikeObject.h",
"test/TestInterfaceSetlike.h",
"test/TestInterfaceSetlikeNode.h"
]
UNIFIED_SOURCES += [
"test/TestInterfaceIterableDouble.cpp",
"test/TestInterfaceIterableSingle.cpp",
"test/TestInterfaceMaplike.cpp",
"test/TestInterfaceMaplikeObject.cpp",
"test/TestInterfaceSetlike.cpp",

View File

@ -540,6 +540,9 @@ class IDLExternalInterface(IDLObjectWithIdentifier, IDLExposureMixins):
def validate(self):
pass
def isIteratorInterface(self):
return False
def isExternal(self):
return True
@ -640,7 +643,7 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
self._callback = False
self._finished = False
self.members = []
self.maplikeOrSetlike = None
self.maplikeOrSetlikeOrIterable = None
self._partialInterfaces = []
self._extendedAttrDict = {}
# namedConstructors needs deterministic ordering because bindings code
@ -664,6 +667,9 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
self.totalMembersInSlots = 0
# Tracking of the number of own own members we have in slots
self._ownMembersInSlots = 0
# If this is an iterator interface, we need to know what iterable
# interface we're iterating for in order to get its nativeType.
self.iterableInterface = None
IDLObjectWithScope.__init__(self, location, parentScope, name)
IDLExposureMixins.__init__(self, location)
@ -682,6 +688,13 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
except:
return None
def isIterable(self):
return (self.maplikeOrSetlikeOrIterable and
self.maplikeOrSetlikeOrIterable.isIterable())
def isIteratorInterface(self):
return self.iterableInterface is not None
def resolveIdentifierConflict(self, scope, identifier, originalObject, newObject):
assert isinstance(scope, IDLScope)
assert isinstance(originalObject, IDLInterfaceMember)
@ -718,22 +731,22 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
# need to be treated like regular interface members, do this before
# things like exposure setting.
for member in self.members:
if member.isMaplikeOrSetlike():
if member.isMaplikeOrSetlikeOrIterable():
# Check that we only have one interface declaration (currently
# there can only be one maplike/setlike declaration per
# interface)
if self.maplikeOrSetlike:
if self.maplikeOrSetlikeOrIterable:
raise WebIDLError("%s declaration used on "
"interface that already has %s "
"declaration" %
(member.maplikeOrSetlikeType,
self.maplikeOrSetlike.maplikeOrSetlikeType),
[self.maplikeOrSetlike.location,
(member.maplikeOrSetlikeOrIterableType,
self.maplikeOrSetlike.maplikeOrSetlikeOrIterableType),
[self.maplikeOrSetlikeOrIterable.location,
member.location])
self.maplikeOrSetlike = member
self.maplikeOrSetlikeOrIterable = member
# If we've got a maplike or setlike declaration, we'll be building all of
# our required methods in Codegen. Generate members now.
self.maplikeOrSetlike.expand(self.members, self.isJSImplemented())
self.maplikeOrSetlikeOrIterable.expand(self.members, self.isJSImplemented())
# Now that we've merged in our partial interfaces, set the
# _exposureGlobalNames on any members that don't have it set yet. Note
@ -884,14 +897,14 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
# If we have a maplike or setlike, and the consequential interface
# also does, throw an error.
if iface.maplikeOrSetlike and self.maplikeOrSetlike:
raise WebIDLError("Maplike/setlike interface %s cannot have "
"maplike/setlike interface %s as a "
if iface.maplikeOrSetlikeOrIterable and self.maplikeOrSetlikeOrIterable:
raise WebIDLError("Maplike/setlike/iterable interface %s cannot have "
"maplike/setlike/iterable interface %s as a "
"consequential interface" %
(self.identifier.name,
iface.identifier.name),
[self.maplikeOrSetlike.location,
iface.maplikeOrSetlike.location])
[self.maplikeOrSetlikeOrIterable.location,
iface.maplikeOrSetlikeOrIterable.location])
additionalMembers = iface.originalMembers
for additionalMember in additionalMembers:
for member in self.members:
@ -905,15 +918,15 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
for ancestor in self.getInheritedInterfaces():
ancestor.interfacesBasedOnSelf.add(self)
if (ancestor.maplikeOrSetlike is not None and
self.maplikeOrSetlike is not None):
if (ancestor.maplikeOrSetlikeOrIterable is not None and
self.maplikeOrSetlikeOrIterable is not None):
raise WebIDLError("Cannot have maplike/setlike on %s that "
"inherits %s, which is already "
"maplike/setlike" %
(self.identifier.name,
ancestor.identifier.name),
[self.maplikeOrSetlike.location,
ancestor.maplikeOrSetlike.location])
[self.maplikeOrSetlikeOrIterable.location,
ancestor.maplikeOrSetlikeOrIterable.location])
for ancestorConsequential in ancestor.getConsequentialInterfaces():
ancestorConsequential.interfacesBasedOnSelf.add(self)
@ -997,12 +1010,12 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
# At this point, we have all of our members. If the current interface
# uses maplike/setlike, check for collisions anywhere in the current
# interface or higher in the inheritance chain.
if self.maplikeOrSetlike:
if self.maplikeOrSetlikeOrIterable:
testInterface = self
isAncestor = False
while testInterface:
self.maplikeOrSetlike.checkCollisions(testInterface.members,
isAncestor)
self.maplikeOrSetlikeOrIterable.checkCollisions(testInterface.members,
isAncestor)
isAncestor = True
testInterface = testInterface.parent
@ -3367,7 +3380,8 @@ class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins):
'Const',
'Attr',
'Method',
'MaplikeOrSetlike'
'MaplikeOrSetlike',
'Iterable'
)
Special = enum(
@ -3393,6 +3407,10 @@ class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins):
def isConst(self):
return self.tag == IDLInterfaceMember.Tags.Const
def isMaplikeOrSetlikeOrIterable(self):
return (self.tag == IDLInterfaceMember.Tags.MaplikeOrSetlike or
self.tag == IDLInterfaceMember.Tags.Iterable)
def isMaplikeOrSetlike(self):
return self.tag == IDLInterfaceMember.Tags.MaplikeOrSetlike
@ -3470,58 +3488,42 @@ class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins):
self.aliases.append(alias)
# MaplikeOrSetlike adds a trait to an interface, like map or iteration
# functions. To handle them while still getting all of the generated binding
# code taken care of, we treat them as macros that are expanded into members
# based on parsed values.
class IDLMaplikeOrSetlike(IDLInterfaceMember):
MaplikeOrSetlikeTypes = enum(
'maplike',
'setlike'
)
def __init__(self, location, identifier, maplikeOrSetlikeType,
readonly, keyType, valueType):
IDLInterfaceMember.__init__(self, location, identifier,
IDLInterfaceMember.Tags.MaplikeOrSetlike)
class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember):
def __init__(self, location, identifier, ifaceType, keyType, valueType, ifaceKind):
IDLInterfaceMember.__init__(self, location, identifier, ifaceKind)
assert isinstance(keyType, IDLType)
assert isinstance(valueType, IDLType)
self.maplikeOrSetlikeType = maplikeOrSetlikeType
self.readonly = readonly
assert ifaceType in ['maplike', 'setlike', 'iterable']
if valueType is not None:
assert isinstance(valueType, IDLType)
self.keyType = keyType
self.valueType = valueType
self.slotIndex = None
self.maplikeOrSetlikeOrIterableType = ifaceType
self.disallowedMemberNames = []
self.disallowedNonMethodNames = []
# When generating JSAPI access code, we need to know the backing object
# type prefix to create the correct function. Generate here for reuse.
if self.isMaplike():
self.prefix = 'Map'
elif self.isSetlike():
self.prefix = 'Set'
def __str__(self):
return "declared '%s' with key '%s'" % (self.maplikeOrSetlikeType, self.keyType)
def isMaplike(self):
return self.maplikeOrSetlikeType == "maplike"
return self.maplikeOrSetlikeOrIterableType == "maplike"
def isSetlike(self):
return self.maplikeOrSetlikeType == "setlike"
return self.maplikeOrSetlikeOrIterableType == "setlike"
def isIterable(self):
return self.maplikeOrSetlikeOrIterableType == "iterable"
def hasValueType(self):
return self.valueType is not None
def checkCollisions(self, members, isAncestor):
for member in members:
# Check that there are no disallowed members
if (member.identifier.name in self.disallowedMemberNames and
not ((member.isMethod() and member.isMaplikeOrSetlikeMethod()) or
not ((member.isMethod() and member.isMaplikeOrSetlikeOrIterableMethod()) or
(member.isAttr() and member.isMaplikeOrSetlikeAttr()))):
raise WebIDLError("Member '%s' conflicts "
"with reserved %s name." %
(member.identifier.name,
self.maplikeOrSetlikeType),
self.maplikeOrSetlikeOrIterableType),
[self.location, member.location])
# Check that there are no disallowed non-method members
if (isAncestor or (member.isAttr() or member.isConst()) and
@ -3529,168 +3531,76 @@ class IDLMaplikeOrSetlike(IDLInterfaceMember):
raise WebIDLError("Member '%s' conflicts "
"with reserved %s method." %
(member.identifier.name,
self.maplikeOrSetlikeType),
self.maplikeOrSetlikeOrIterableType),
[self.location, member.location])
def expand(self, members, isJSImplemented):
def addMethod(self, name, members, allowExistingOperations, returnType, args=[],
chromeOnly=False, isPure=False, affectsNothing=False, newObject=False):
"""
In order to take advantage of all of the method machinery in Codegen,
we generate our functions as if they were part of the interface
specification during parsing.
Create an IDLMethod based on the parameters passed in.
- members is the member list to add this function to, since this is
called during the member expansion portion of interface object
building.
- chromeOnly is only True for read-only js implemented classes, to
implement underscore prefixed convenience functions which would
otherwise not be available, unlike the case of C++ bindings.
- isPure is only True for idempotent functions, so it is not valid for
things like keys, values, etc. that return a new object every time.
- affectsNothing means that nothing changes due to this method, which
affects JIT optimization behavior
- newObject means the method creates and returns a new object.
"""
def addMethod(name, allowExistingOperations, returnType, args=[],
chromeOnly=False, isPure=False, affectsNothing=False):
"""
Create an IDLMethod based on the parameters passed in. chromeOnly is only
True for read-only js implemented classes, to implement underscore
prefixed convenience functions would otherwise not be available,
unlike the case of C++ bindings. isPure is only True for
idempotent functions, so it is not valid for things like keys,
values, etc. that return a new object every time.
"""
# Only add name to lists for collision checks if it's not chrome
# only.
if chromeOnly:
name = "__" + name
# Only add name to lists for collision checks if it's not chrome
# only.
if chromeOnly:
name = "__" + name
else:
if not allowExistingOperations:
self.disallowedMemberNames.append(name)
else:
if not allowExistingOperations:
self.disallowedMemberNames.append(name)
else:
self.disallowedNonMethodNames.append(name)
# If allowExistingOperations is True, and another operation exists
# with the same name as the one we're trying to add, don't add the
# maplike/setlike operation. However, if the operation is static,
# then fail by way of creating the function, which will cause a
# naming conflict, per the spec.
if allowExistingOperations:
for m in members:
if m.identifier.name == name and m.isMethod() and not m.isStatic():
return
method = IDLMethod(self.location,
IDLUnresolvedIdentifier(self.location, name, allowDoubleUnderscore=chromeOnly),
returnType, args, maplikeOrSetlike=self)
# We need to be able to throw from declaration methods
self.disallowedNonMethodNames.append(name)
# If allowExistingOperations is True, and another operation exists
# with the same name as the one we're trying to add, don't add the
# maplike/setlike operation. However, if the operation is static,
# then fail by way of creating the function, which will cause a
# naming conflict, per the spec.
if allowExistingOperations:
for m in members:
if m.identifier.name == name and m.isMethod() and not m.isStatic():
return
method = IDLMethod(self.location,
IDLUnresolvedIdentifier(self.location, name, allowDoubleUnderscore=chromeOnly),
returnType, args, maplikeOrSetlikeOrIterable=self)
# We need to be able to throw from declaration methods
method.addExtendedAttributes(
[IDLExtendedAttribute(self.location, ("Throws",))])
if chromeOnly:
method.addExtendedAttributes(
[IDLExtendedAttribute(self.location, ("Throws",))])
if chromeOnly:
method.addExtendedAttributes(
[IDLExtendedAttribute(self.location, ("ChromeOnly",))])
if isPure:
method.addExtendedAttributes(
[IDLExtendedAttribute(self.location, ("Pure",))])
# Following attributes are used for keys/values/entries. Can't mark
# them pure, since they return a new object each time they are run.
if affectsNothing:
method.addExtendedAttributes(
[IDLExtendedAttribute(self.location, ("DependsOn", "Everything")),
IDLExtendedAttribute(self.location, ("Affects", "Nothing"))])
members.append(method)
# Both maplike and setlike have a size attribute
members.append(IDLAttribute(self.location,
IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"), "size"),
BuiltinTypes[IDLBuiltinType.Types.unsigned_long],
True,
maplikeOrSetlike=self))
self.reserved_ro_names = ["size"]
# object entries()
addMethod("entries", False, BuiltinTypes[IDLBuiltinType.Types.object],
affectsNothing=True)
# object keys()
addMethod("keys", False, BuiltinTypes[IDLBuiltinType.Types.object],
affectsNothing=True)
# object values()
addMethod("values", False, BuiltinTypes[IDLBuiltinType.Types.object],
affectsNothing=True)
# void forEach(callback(valueType, keyType), thisVal)
foreachArguments = [IDLArgument(self.location,
IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"),
"callback"),
BuiltinTypes[IDLBuiltinType.Types.object]),
IDLArgument(self.location,
IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"),
"thisArg"),
BuiltinTypes[IDLBuiltinType.Types.any],
optional=True)]
addMethod("forEach", False, BuiltinTypes[IDLBuiltinType.Types.void],
foreachArguments)
def getKeyArg():
return IDLArgument(self.location,
IDLUnresolvedIdentifier(self.location, "key"),
self.keyType)
# boolean has(keyType key)
addMethod("has", False, BuiltinTypes[IDLBuiltinType.Types.boolean],
[getKeyArg()], isPure=True)
if not self.readonly:
# void clear()
addMethod("clear", True, BuiltinTypes[IDLBuiltinType.Types.void],
[])
# boolean delete(keyType key)
addMethod("delete", True,
BuiltinTypes[IDLBuiltinType.Types.boolean], [getKeyArg()])
# Always generate underscored functions (e.g. __add, __clear) for js
# implemented interfaces as convenience functions.
if isJSImplemented:
# void clear()
addMethod("clear", True, BuiltinTypes[IDLBuiltinType.Types.void],
[], chromeOnly=True)
# boolean delete(keyType key)
addMethod("delete", True,
BuiltinTypes[IDLBuiltinType.Types.boolean], [getKeyArg()],
chromeOnly=True)
if self.isSetlike():
if not self.readonly:
# Add returns the set object it just added to.
# object add(keyType key)
addMethod("add", True,
BuiltinTypes[IDLBuiltinType.Types.object], [getKeyArg()])
if isJSImplemented:
addMethod("add", True,
BuiltinTypes[IDLBuiltinType.Types.object], [getKeyArg()],
chromeOnly=True)
return
# If we get this far, we're a maplike declaration.
# valueType get(keyType key)
#
# Note that instead of the value type, we're using any here. The
# validity checks should happen as things are inserted into the map,
# and using any as the return type makes code generation much simpler.
#
# TODO: Bug 1155340 may change this to use specific type to provide
# more info to JIT.
addMethod("get", False, BuiltinTypes[IDLBuiltinType.Types.any],
[getKeyArg()], isPure=True)
def getValueArg():
return IDLArgument(self.location,
IDLUnresolvedIdentifier(self.location, "value"),
self.valueType)
if not self.readonly:
addMethod("set", True, BuiltinTypes[IDLBuiltinType.Types.object],
[getKeyArg(), getValueArg()])
if isJSImplemented:
addMethod("set", True, BuiltinTypes[IDLBuiltinType.Types.object],
[getKeyArg(), getValueArg()], chromeOnly=True)
[IDLExtendedAttribute(self.location, ("ChromeOnly",))])
if isPure:
method.addExtendedAttributes(
[IDLExtendedAttribute(self.location, ("Pure",))])
# Following attributes are used for keys/values/entries. Can't mark
# them pure, since they return a new object each time they are run.
if affectsNothing:
method.addExtendedAttributes(
[IDLExtendedAttribute(self.location, ("DependsOn", "Everything")),
IDLExtendedAttribute(self.location, ("Affects", "Nothing"))])
if newObject:
method.addExtendedAttributes(
[IDLExtendedAttribute(self.location, ("NewObject",))])
members.append(method)
def resolve(self, parentScope):
self.keyType.resolveType(parentScope)
self.valueType.resolveType(parentScope)
if self.valueType:
self.valueType.resolveType(parentScope)
def finish(self, scope):
IDLInterfaceMember.finish(self, scope)
@ -3701,7 +3611,7 @@ class IDLMaplikeOrSetlike(IDLInterfaceMember):
assert not isinstance(t, IDLTypedefType)
assert not isinstance(t.name, IDLUnresolvedIdentifier)
self.keyType = t
if not self.valueType.isComplete():
if self.valueType and not self.valueType.isComplete():
t = self.valueType.complete(scope)
assert not isinstance(t, IDLUnresolvedType)
@ -3716,8 +3626,161 @@ class IDLMaplikeOrSetlike(IDLInterfaceMember):
IDLInterfaceMember.handleExtendedAttribute(self, attr)
def _getDependentObjects(self):
return set([self.keyType, self.valueType])
if self.valueType:
return set([self.keyType, self.valueType])
return set([self.keyType])
# Iterable adds ES6 iterator style functions and traits
# (keys/values/entries/@@iterator) to an interface.
class IDLIterable(IDLMaplikeOrSetlikeOrIterableBase):
def __init__(self, location, identifier, keyType, valueType=None, scope=None):
IDLMaplikeOrSetlikeOrIterableBase.__init__(self, location, identifier,
"iterable", keyType, valueType,
IDLInterfaceMember.Tags.Iterable)
self.iteratorType = None
def __str__(self):
return "declared iterable with key '%s' and value '%s'" % (self.keyType, self.valueType)
def expand(self, members, isJSImplemented):
"""
In order to take advantage of all of the method machinery in Codegen,
we generate our functions as if they were part of the interface
specification during parsing.
"""
# object entries()
self.addMethod("entries", members, False, self.iteratorType,
affectsNothing=True, newObject=True)
# object keys()
self.addMethod("keys", members, False, self.iteratorType,
affectsNothing=True, newObject=True)
# object values()
self.addMethod("values", members, False, self.iteratorType,
affectsNothing=True, newObject=True)
# MaplikeOrSetlike adds ES6 map-or-set-like traits to an interface.
class IDLMaplikeOrSetlike(IDLMaplikeOrSetlikeOrIterableBase):
def __init__(self, location, identifier, maplikeOrSetlikeType,
readonly, keyType, valueType):
IDLMaplikeOrSetlikeOrIterableBase.__init__(self, location, identifier, maplikeOrSetlikeType,
keyType, valueType, IDLInterfaceMember.Tags.MaplikeOrSetlike)
self.readonly = readonly
self.slotIndex = None
# When generating JSAPI access code, we need to know the backing object
# type prefix to create the correct function. Generate here for reuse.
if self.isMaplike():
self.prefix = 'Map'
elif self.isSetlike():
self.prefix = 'Set'
def __str__(self):
return "declared '%s' with key '%s'" % (self.maplikeOrSetlikeOrIterableType, self.keyType)
def expand(self, members, isJSImplemented):
"""
In order to take advantage of all of the method machinery in Codegen,
we generate our functions as if they were part of the interface
specification during parsing.
"""
# Both maplike and setlike have a size attribute
members.append(IDLAttribute(self.location,
IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"), "size"),
BuiltinTypes[IDLBuiltinType.Types.unsigned_long],
True,
maplikeOrSetlike=self))
self.reserved_ro_names = ["size"]
# object entries()
self.addMethod("entries", members, False, BuiltinTypes[IDLBuiltinType.Types.object],
affectsNothing=True)
# object keys()
self.addMethod("keys", members, False, BuiltinTypes[IDLBuiltinType.Types.object],
affectsNothing=True)
# object values()
self.addMethod("values", members, False, BuiltinTypes[IDLBuiltinType.Types.object],
affectsNothing=True)
# void forEach(callback(valueType, keyType), thisVal)
foreachArguments = [IDLArgument(self.location,
IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"),
"callback"),
BuiltinTypes[IDLBuiltinType.Types.object]),
IDLArgument(self.location,
IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"),
"thisArg"),
BuiltinTypes[IDLBuiltinType.Types.any],
optional=True)]
self.addMethod("forEach", members, False, BuiltinTypes[IDLBuiltinType.Types.void],
foreachArguments)
def getKeyArg():
return IDLArgument(self.location,
IDLUnresolvedIdentifier(self.location, "key"),
self.keyType)
# boolean has(keyType key)
self.addMethod("has", members, False, BuiltinTypes[IDLBuiltinType.Types.boolean],
[getKeyArg()], isPure=True)
if not self.readonly:
# void clear()
self.addMethod("clear", members, True, BuiltinTypes[IDLBuiltinType.Types.void],
[])
# boolean delete(keyType key)
self.addMethod("delete", members, True,
BuiltinTypes[IDLBuiltinType.Types.boolean], [getKeyArg()])
# Always generate underscored functions (e.g. __add, __clear) for js
# implemented interfaces as convenience functions.
if isJSImplemented:
# void clear()
self.addMethod("clear", members, True, BuiltinTypes[IDLBuiltinType.Types.void],
[], chromeOnly=True)
# boolean delete(keyType key)
self.addMethod("delete", members, True,
BuiltinTypes[IDLBuiltinType.Types.boolean], [getKeyArg()],
chromeOnly=True)
if self.isSetlike():
if not self.readonly:
# Add returns the set object it just added to.
# object add(keyType key)
self.addMethod("add", members, True,
BuiltinTypes[IDLBuiltinType.Types.object], [getKeyArg()])
if isJSImplemented:
self.addMethod("add", members, True,
BuiltinTypes[IDLBuiltinType.Types.object], [getKeyArg()],
chromeOnly=True)
return
# If we get this far, we're a maplike declaration.
# valueType get(keyType key)
#
# Note that instead of the value type, we're using any here. The
# validity checks should happen as things are inserted into the map,
# and using any as the return type makes code generation much simpler.
#
# TODO: Bug 1155340 may change this to use specific type to provide
# more info to JIT.
self.addMethod("get", members, False, BuiltinTypes[IDLBuiltinType.Types.any],
[getKeyArg()], isPure=True)
def getValueArg():
return IDLArgument(self.location,
IDLUnresolvedIdentifier(self.location, "value"),
self.valueType)
if not self.readonly:
self.addMethod("set", members, True, BuiltinTypes[IDLBuiltinType.Types.object],
[getKeyArg(), getValueArg()])
if isJSImplemented:
self.addMethod("set", members, True, BuiltinTypes[IDLBuiltinType.Types.object],
[getKeyArg(), getValueArg()], chromeOnly=True)
class IDLConst(IDLInterfaceMember):
def __init__(self, location, identifier, type, value):
@ -4319,7 +4382,7 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
static=False, getter=False, setter=False, creator=False,
deleter=False, specialType=NamedOrIndexed.Neither,
legacycaller=False, stringifier=False, jsonifier=False,
maplikeOrSetlike=None):
maplikeOrSetlikeOrIterable=None):
# REVIEW: specialType is NamedOrIndexed -- wow, this is messed up.
IDLInterfaceMember.__init__(self, location, identifier,
IDLInterfaceMember.Tags.Method)
@ -4347,8 +4410,8 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
self._stringifier = stringifier
assert isinstance(jsonifier, bool)
self._jsonifier = jsonifier
assert maplikeOrSetlike is None or isinstance(maplikeOrSetlike, IDLMaplikeOrSetlike)
self.maplikeOrSetlike = maplikeOrSetlike
assert maplikeOrSetlikeOrIterable is None or isinstance(maplikeOrSetlikeOrIterable, IDLMaplikeOrSetlikeOrIterableBase)
self.maplikeOrSetlikeOrIterable = maplikeOrSetlikeOrIterable
self._specialType = specialType
self._unforgeable = False
self.dependsOn = "Everything"
@ -4430,12 +4493,12 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
def isJsonifier(self):
return self._jsonifier
def isMaplikeOrSetlikeMethod(self):
def isMaplikeOrSetlikeOrIterableMethod(self):
"""
True if this method was generated as part of a
maplike/setlike/etc interface (e.g. has/get methods)
"""
return self.maplikeOrSetlike is not None
return self.maplikeOrSetlikeOrIterable is not None
def isSpecial(self):
return (self.isGetter() or
@ -4458,7 +4521,7 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
an non-identifier name, they actually DO have an identifier.
"""
return (self.identifier.name[:2] == "__" and
not self.isMaplikeOrSetlikeMethod())
not self.isMaplikeOrSetlikeOrIterableMethod())
def resolve(self, parentScope):
assert isinstance(parentScope, IDLScope)
@ -4966,7 +5029,8 @@ class Tokenizer(object):
"SharedArrayBuffer": "SHAREDARRAYBUFFER",
"or": "OR",
"maplike": "MAPLIKE",
"setlike": "SETLIKE"
"setlike": "SETLIKE",
"iterable": "ITERABLE"
}
tokens.extend(keywords.values())
@ -5120,8 +5184,9 @@ class Parser(Tokenizer):
raise ex
pass
p[0] = IDLInterface(location, self.globalScope(), identifier, parent,
iface = IDLInterface(location, self.globalScope(), identifier, parent,
members, isKnownNonPartial=True)
p[0] = iface
def p_InterfaceForwardDecl(self, p):
"""
@ -5207,7 +5272,7 @@ class Parser(Tokenizer):
def p_InterfaceMember(self, p):
"""
InterfaceMember : Const
| AttributeOrOperationOrMaplikeOrSetlike
| AttributeOrOperationOrMaplikeOrSetlikeOrIterable
"""
p[0] = p[1]
@ -5422,15 +5487,30 @@ class Parser(Tokenizer):
"""
p[0] = False
def p_AttributeOrOperationOrMaplikeOrSetlike(self, p):
def p_AttributeOrOperationOrMaplikeOrSetlikeOrIterable(self, p):
"""
AttributeOrOperationOrMaplikeOrSetlike : Attribute
| Maplike
| Setlike
| Operation
AttributeOrOperationOrMaplikeOrSetlikeOrIterable : Attribute
| Maplike
| Setlike
| Iterable
| Operation
"""
p[0] = p[1]
def p_Iterable(self, p):
"""
Iterable : ITERABLE LT Type GT SEMICOLON
| ITERABLE LT Type COMMA Type GT SEMICOLON
"""
location = self.getLocation(p, 2)
identifier = IDLUnresolvedIdentifier(location, "__iterable",
allowDoubleUnderscore=True)
keyType = p[3]
valueType = None
if (len(p) > 6):
valueType = p[5]
p[0] = IDLIterable(location, identifier, keyType, valueType, self.globalScope())
def p_Setlike(self, p):
"""
Setlike : ReadOnly SETLIKE LT Type GT SEMICOLON
@ -5803,6 +5883,7 @@ class Parser(Tokenizer):
| IMPLEMENTS
| INHERIT
| INTERFACE
| ITERABLE
| LEGACYCALLER
| MAPLIKE
| PARTIAL
@ -6481,7 +6562,46 @@ class Parser(Tokenizer):
self._filename = None
def finish(self):
# First, finish all the IDLImplementsStatements. In particular, we
# If we have interfaces that are iterable, create their
# iterator interfaces and add them to the productions array.
interfaceStatements = [p for p in self._productions if
isinstance(p, IDLInterface)]
for iface in interfaceStatements:
iterable = None
# We haven't run finish() on the interface yet, so we don't know
# whether our interface is maplike/setlike/iterable or not. This
# means we have to loop through the members to see if we have an
# iterable member.
for m in iface.members:
if isinstance(m, IDLIterable):
iterable = m
break
if iterable:
itr_ident = IDLUnresolvedIdentifier(iface.location,
iface.identifier.name + "Iterator")
itr_iface = IDLInterface(iface.location, self.globalScope(),
itr_ident, None, [],
isKnownNonPartial=True)
itr_iface.addExtendedAttributes([IDLExtendedAttribute(iface.location,
("NoInterfaceObject", ))])
# Always append generated iterable interfaces and their
# matching implements statements after the interface they're a
# member of, otherwise nativeType generation won't work
# correctly.
itr_iface.iterableInterface = iface
self._productions.append(itr_iface)
iterable.iteratorType = IDLWrapperType(iface.location, itr_iface)
itrPlaceholder = IDLIdentifierPlaceholder(iface.location,
IDLUnresolvedIdentifier(iface.location,
"IterableIterator"))
implements = IDLImplementsStatement(iface.location,
IDLIdentifierPlaceholder(iface.location,
itr_ident),
itrPlaceholder)
self._productions.append(implements)
# Then, finish all the IDLImplementsStatements. In particular, we
# have to make sure we do those before we do the IDLInterfaces.
# XXX khuey hates this bit and wants to nuke it from orbit.
implementsStatements = [p for p in self._productions if

View File

@ -41,11 +41,11 @@ def WebIDLTest(parser, harness):
prefix + " - Interface failed but not as a WebIDLError exception")
iterableMembers = [(x, WebIDL.IDLMethod) for x in ["entries", "keys",
"values", "forEach"]]
iterableMembers.extend([("size", WebIDL.IDLAttribute)])
setROMembers = ([(x, WebIDL.IDLMethod) for x in ["has"]] +
"values"]]
setROMembers = ([(x, WebIDL.IDLMethod) for x in ["has", "foreach"]] +
[("__setlike", WebIDL.IDLMaplikeOrSetlike)] +
iterableMembers)
setROMembers.extend([("size", WebIDL.IDLAttribute)])
setRWMembers = ([(x, WebIDL.IDLMethod) for x in ["add",
"clear",
"delete"]] +
@ -58,9 +58,10 @@ def WebIDLTest(parser, harness):
"__clear",
"__delete"]] +
setRWMembers)
mapROMembers = ([(x, WebIDL.IDLMethod) for x in ["get", "has"]] +
mapROMembers = ([(x, WebIDL.IDLMethod) for x in ["get", "has", "foreach"]] +
[("__maplike", WebIDL.IDLMaplikeOrSetlike)] +
iterableMembers)
mapROMembers.extend([("size", WebIDL.IDLAttribute)])
mapRWMembers = ([(x, WebIDL.IDLMethod) for x in ["set",
"clear",
"delete"]] + mapROMembers)
@ -69,8 +70,8 @@ def WebIDLTest(parser, harness):
"__delete"]] +
mapRWMembers)
disallowedMemberNames = ["keys", "entries", "values", "forEach", "has",
"size"]
disallowedIterableNames = ["keys", "entries", "values"]
disallowedMemberNames = ["forEach", "has", "size"] + disallowedIterableNames
mapDisallowedMemberNames = ["get"] + disallowedMemberNames
disallowedNonMethodNames = ["clear", "delete"]
mapDisallowedNonMethodNames = ["set"] + disallowedNonMethodNames
@ -80,6 +81,27 @@ def WebIDLTest(parser, harness):
# Simple Usage Tests
#
shouldPass("Iterable (key only)",
"""
interface Foo1 {
iterable<long>;
};
""", iterableMembers)
shouldPass("Iterable (key and value)",
"""
interface Foo1 {
iterable<long, long>;
};
""", iterableMembers)
shouldPass("Maplike (readwrite)",
"""
interface Foo1 {
maplike<long, long>;
};
""", mapRWMembers)
shouldPass("Maplike (readwrite)",
"""
interface Foo1 {
@ -157,6 +179,22 @@ def WebIDLTest(parser, harness):
};
""")
shouldFail("Two iterable/setlikes on same interface",
"""
interface Foo1 {
iterable<long>;
maplike<long, long>;
};
""")
shouldFail("Two iterables on same interface",
"""
interface Foo1 {
iterable<long>;
iterable<long, long>;
};
""")
shouldFail("Two maplike/setlikes in partials",
"""
interface Foo1 {
@ -177,6 +215,16 @@ def WebIDLTest(parser, harness):
};
""")
shouldFail("Conflicting maplike/iterable across inheritance",
"""
interface Foo1 {
maplike<long, long>;
};
interface Foo2 : Foo1 {
iterable<long>;
};
""")
shouldFail("Conflicting maplike/setlikes across multistep inheritance",
"""
interface Foo1 {
@ -283,6 +331,8 @@ def WebIDLTest(parser, harness):
};
""" % (likeMember, conflictName))
for member in disallowedIterableNames:
testConflictingMembers("iterable<long, long>", member, iterableMembers, False)
for member in mapDisallowedMemberNames:
testConflictingMembers("maplike<long, long>", member, mapRWMembers, False)
for member in disallowedMemberNames:

View File

@ -0,0 +1,82 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/TestInterfaceIterableDouble.h"
#include "mozilla/dom/TestInterfaceJSMaplikeSetlikeIterableBinding.h"
#include "nsPIDOMWindow.h"
#include "mozilla/dom/BindingUtils.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(TestInterfaceIterableDouble, mParent)
NS_IMPL_CYCLE_COLLECTING_ADDREF(TestInterfaceIterableDouble)
NS_IMPL_CYCLE_COLLECTING_RELEASE(TestInterfaceIterableDouble)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TestInterfaceIterableDouble)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
TestInterfaceIterableDouble::TestInterfaceIterableDouble(nsPIDOMWindow* aParent)
: mParent(aParent)
{
mValues.AppendElement(std::pair<nsString, nsString>(NS_LITERAL_STRING("a"),
NS_LITERAL_STRING("b")));
mValues.AppendElement(std::pair<nsString, nsString>(NS_LITERAL_STRING("c"),
NS_LITERAL_STRING("d")));
mValues.AppendElement(std::pair<nsString, nsString>(NS_LITERAL_STRING("e"),
NS_LITERAL_STRING("f")));
}
//static
already_AddRefed<TestInterfaceIterableDouble>
TestInterfaceIterableDouble::Constructor(const GlobalObject& aGlobal,
ErrorResult& aRv)
{
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.GetAsSupports());
if (!window) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsRefPtr<TestInterfaceIterableDouble> r = new TestInterfaceIterableDouble(window);
return r.forget();
}
JSObject*
TestInterfaceIterableDouble::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return TestInterfaceIterableDoubleBinding::Wrap(aCx, this, aGivenProto);
}
nsPIDOMWindow*
TestInterfaceIterableDouble::GetParentObject() const
{
return mParent;
}
size_t
TestInterfaceIterableDouble::GetIterableLength()
{
return mValues.Length();
}
nsAString&
TestInterfaceIterableDouble::GetKeyAtIndex(uint32_t aIndex)
{
MOZ_ASSERT(aIndex < mValues.Length());
return mValues.ElementAt(aIndex).first;
}
nsAString&
TestInterfaceIterableDouble::GetValueAtIndex(uint32_t aIndex)
{
MOZ_ASSERT(aIndex < mValues.Length());
return mValues.ElementAt(aIndex).second;
}
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,51 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_TestInterfaceIterableDouble_h
#define mozilla_dom_TestInterfaceIterableDouble_h
#include "nsWrapperCache.h"
#include "nsCOMPtr.h"
class nsPIDOMWindow;
namespace mozilla {
class ErrorResult;
namespace dom {
class GlobalObject;
// Implementation of test binding for webidl iterable interfaces, using
// primitives for value type
class TestInterfaceIterableDouble final : public nsISupports,
public nsWrapperCache
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TestInterfaceIterableDouble)
explicit TestInterfaceIterableDouble(nsPIDOMWindow* aParent);
nsPIDOMWindow* GetParentObject() const;
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
static already_AddRefed<TestInterfaceIterableDouble>
Constructor(const GlobalObject& aGlobal, ErrorResult& rv);
size_t GetIterableLength();
nsAString& GetKeyAtIndex(uint32_t aIndex);
nsAString& GetValueAtIndex(uint32_t aIndex);
private:
virtual ~TestInterfaceIterableDouble() {}
nsCOMPtr<nsPIDOMWindow> mParent;
nsTArray<std::pair<nsString, nsString>> mValues;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_TestInterfaceIterableDouble_h

View File

@ -0,0 +1,78 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/TestInterfaceIterableSingle.h"
#include "mozilla/dom/TestInterfaceJSMaplikeSetlikeIterableBinding.h"
#include "nsPIDOMWindow.h"
#include "mozilla/dom/BindingUtils.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(TestInterfaceIterableSingle, mParent)
NS_IMPL_CYCLE_COLLECTING_ADDREF(TestInterfaceIterableSingle)
NS_IMPL_CYCLE_COLLECTING_RELEASE(TestInterfaceIterableSingle)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TestInterfaceIterableSingle)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
TestInterfaceIterableSingle::TestInterfaceIterableSingle(nsPIDOMWindow* aParent)
: mParent(aParent)
{
for(int i = 0; i < 3; ++i) {
mValues.AppendElement(i);
}
}
//static
already_AddRefed<TestInterfaceIterableSingle>
TestInterfaceIterableSingle::Constructor(const GlobalObject& aGlobal,
ErrorResult& aRv)
{
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.GetAsSupports());
if (!window) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsRefPtr<TestInterfaceIterableSingle> r = new TestInterfaceIterableSingle(window);
return r.forget();
}
JSObject*
TestInterfaceIterableSingle::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return TestInterfaceIterableSingleBinding::Wrap(aCx, this, aGivenProto);
}
nsPIDOMWindow*
TestInterfaceIterableSingle::GetParentObject() const
{
return mParent;
}
size_t
TestInterfaceIterableSingle::GetIterableLength() const
{
return mValues.Length();
}
uint32_t
TestInterfaceIterableSingle::GetKeyAtIndex(uint32_t index) const
{
MOZ_ASSERT(index < mValues.Length());
return mValues.ElementAt(index);
}
uint32_t
TestInterfaceIterableSingle::GetValueAtIndex(uint32_t index) const
{
return GetKeyAtIndex(index);
}
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,51 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_TestInterfaceIterableSingle_h
#define mozilla_dom_TestInterfaceIterableSingle_h
#include "nsWrapperCache.h"
#include "nsCOMPtr.h"
class nsPIDOMWindow;
namespace mozilla {
class ErrorResult;
namespace dom {
class GlobalObject;
// Implementation of test binding for webidl iterable interfaces, using
// primitives for value type
class TestInterfaceIterableSingle final : public nsISupports,
public nsWrapperCache
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TestInterfaceIterableSingle)
explicit TestInterfaceIterableSingle(nsPIDOMWindow* aParent);
nsPIDOMWindow* GetParentObject() const;
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
static already_AddRefed<TestInterfaceIterableSingle>
Constructor(const GlobalObject& aGlobal, ErrorResult& rv);
size_t GetIterableLength() const;
uint32_t GetKeyAtIndex(uint32_t aIndex) const;
uint32_t GetValueAtIndex(uint32_t aIndex) const;
private:
virtual ~TestInterfaceIterableSingle() {}
nsCOMPtr<nsPIDOMWindow> mParent;
nsTArray<uint32_t> mValues;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_TestInterfaceIterableSingle_h

View File

@ -3,7 +3,7 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/TestInterfaceMaplike.h"
#include "mozilla/dom/TestInterfaceJSMaplikeSetlikeBinding.h"
#include "mozilla/dom/TestInterfaceJSMaplikeSetlikeIterableBinding.h"
#include "nsPIDOMWindow.h"
#include "mozilla/dom/BindingUtils.h"

View File

@ -4,7 +4,7 @@
#include "mozilla/dom/TestInterfaceMaplikeObject.h"
#include "mozilla/dom/TestInterfaceMaplike.h"
#include "mozilla/dom/TestInterfaceJSMaplikeSetlikeBinding.h"
#include "mozilla/dom/TestInterfaceJSMaplikeSetlikeIterableBinding.h"
#include "nsPIDOMWindow.h"
#include "mozilla/dom/BindingUtils.h"

View File

@ -3,7 +3,7 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/TestInterfaceSetlike.h"
#include "mozilla/dom/TestInterfaceJSMaplikeSetlikeBinding.h"
#include "mozilla/dom/TestInterfaceJSMaplikeSetlikeIterableBinding.h"
#include "nsPIDOMWindow.h"
#include "mozilla/dom/BindingUtils.h"

View File

@ -3,7 +3,7 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/TestInterfaceSetlikeNode.h"
#include "mozilla/dom/TestInterfaceJSMaplikeSetlikeBinding.h"
#include "mozilla/dom/TestInterfaceJSMaplikeSetlikeIterableBinding.h"
#include "nsPIDOMWindow.h"
#include "mozilla/dom/BindingUtils.h"

View File

@ -68,3 +68,5 @@ skip-if = debug == false
skip-if = debug == false
[test_jsimplemented_eventhandler.html]
skip-if = debug == false
[test_iterable.html]
skip-if = debug == false

View File

@ -57,7 +57,6 @@
var m;
var testSet;
var testIndex;
var iterable;
// Simple map creation and functionality test
info("SimpleMap: Testing simple map creation and functionality");
m = new TestInterfaceMaplike();

View File

@ -0,0 +1,112 @@
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<!DOCTYPE HTML>
<html>
<head>
<title>Test Iterable Interface</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<script class="testbody" type="application/javascript">
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({set: [['dom.expose_test_interfaces', true]]}, function() {
base_properties = [["entries", "function", 0],
["keys", "function", 0],
["values", "function", 0]]
var testExistence = function testExistence(prefix, obj, properties) {
for (var [name, type, args] of properties) {
// Properties are somewhere up the proto chain, hasOwnProperty won't work
isnot(obj[name], undefined,
`${prefix} object has property ${name}`);
is(typeof obj[name], type,
`${prefix} object property ${name} is a ${type}`);
// Check function length
if (type == "function") {
is(obj[name].length, args,
`${prefix} object property ${name} is length ${args}`);
is(obj[name].name, name,
`${prefix} object method name is ${name}`);
}
// Find where property is on proto chain, check for enumerablility there.
var owner = obj;
while (owner) {
var propDesc = Object.getOwnPropertyDescriptor(owner, name);
if (propDesc) {
ok(propDesc.enumerable,
`${prefix} object property ${name} is enumerable`);
break;
}
owner = Object.getPrototypeOf(owner);
}
}
}
var itr;
// Simple single type iterable creation and functionality test
info("IterableSingle: Testing simple iterable creation and functionality");
itr = new TestInterfaceIterableSingle();
testExistence("IterableSingle: ", itr, base_properties);
var key_itr = itr.keys();
var value_itr = itr.values();
var entries_itr = itr.entries();
for (var i = 0; i < 3; ++i) {
var key = key_itr.next();
var value = value_itr.next();
var entry = entries_itr.next();
is(key.value, i, "IterableSingle: Key iterator value should be " + i);
is(value.value, key.value, "IterableSingle: Value iterator value should be " + key.value);
is(entry.value[0], i, "IterableSingle: Entry iterator value 0 should be " + i);
is(entry.value[1], i, "IterableSingle: Entry iterator value 1 should be " + i);
}
var key = key_itr.next();
var value = value_itr.next();
var entry = entries_itr.next();
is(key.value, undefined, "IterableSingle: Key iterator value should be undefined");
is(key.done, true, "IterableSingle: Key iterator done should be true");
is(value.value, undefined, "IterableSingle: Value iterator value should be undefined");
is(value.done, true, "IterableSingle: Value iterator done should be true");
is(entry.value, undefined, "IterableDouble: Entry iterator value should be undefined");
is(entry.done, true, "IterableSingle: Entry iterator done should be true");
is(Object.prototype.toString.call(Object.getPrototypeOf(key_itr)),
"[object TestInterfaceIterableSingleIteratorPrototype]",
"iterator prototype should have the right brand");
// Simple dual type iterable creation and functionality test
info("IterableDouble: Testing simple iterable creation and functionality");
itr = new TestInterfaceIterableDouble();
testExistence("IterableDouble: ", itr, base_properties);
var elements = [["a", "b"], ["c", "d"], ["e", "f"]]
var key_itr = itr.keys();
var value_itr = itr.values();
var entries_itr = itr.entries();
for (var i = 0; i < 3; ++i) {
var key = key_itr.next();
var value = value_itr.next();
var entry = entries_itr.next();
is(key.value, elements[i][0], "IterableDouble: Key iterator value should be " + elements[i][0]);
is(value.value, elements[i][1], "IterableDouble: Value iterator value should be " + elements[i][1]);
is(entry.value[0], elements[i][0], "IterableDouble: Entry iterator value 0 should be " + elements[i][0]);
is(entry.value[1], elements[i][1], "IterableDouble: Entry iterator value 1 should be " + elements[i][1]);
}
var key = key_itr.next();
var value = value_itr.next();
var entry = entries_itr.next()
is(key.value, undefined, "IterableDouble: Key iterator value should be undefined");
is(key.done, true, "IterableDouble: Key iterator done should be true");
is(value.value, undefined, "IterableDouble: Value iterator value should be undefined");
is(value.done, true, "IterableDouble: Value iterator done should be true");
is(entry.value, undefined, "IterableDouble: Entry iterator value should be undefined");
is(entry.done, true, "IterableDouble: Entry iterator done should be true");
is(Object.prototype.toString.call(Object.getPrototypeOf(key_itr)),
"[object TestInterfaceIterableDoubleIteratorPrototype]",
"iterator prototype should have the right brand");
SimpleTest.finish();
});
</script>
</body>
</html>

10
dom/cache/Context.cpp vendored
View File

@ -1001,7 +1001,15 @@ Context::OnQuotaInit(nsresult aRv, const QuotaInfo& aQuotaInfo,
MOZ_ASSERT(!mDirectoryLock);
mDirectoryLock = aDirectoryLock;
if (mState == STATE_CONTEXT_CANCELED || NS_FAILED(aRv)) {
// If we opening the context failed, but we were not explicitly canceled,
// still treat the entire context as canceled. We don't want to allow
// new actions to be dispatched. We also cannot leave the context in
// the INIT state after failing to open.
if (NS_FAILED(aRv)) {
mState = STATE_CONTEXT_CANCELED;
}
if (mState == STATE_CONTEXT_CANCELED) {
for (uint32_t i = 0; i < mPendingActions.Length(); ++i) {
mPendingActions[i].mAction->CompleteOnInitiatingThread(aRv);
}

View File

@ -202,7 +202,7 @@ TypeUtils::ToCacheResponseWithoutBody(CacheResponse& aOut,
{
aOut.type() = aIn.Type();
aIn.GetUrl(aOut.url());
aIn.GetUnfilteredUrl(aOut.url());
if (aOut.url() != EmptyCString()) {
// Pass all Response URL schemes through... The spec only requires we take

View File

@ -400,7 +400,9 @@ HTMLCanvasElement::CreateContext(CanvasContextType aContextType)
// Add Observer for webgl canvas.
if (aContextType == CanvasContextType::WebGL1 ||
aContextType == CanvasContextType::WebGL2) {
mContextObserver = new HTMLCanvasElementObserver(this);
if (!mContextObserver) {
mContextObserver = new HTMLCanvasElementObserver(this);
}
}
ret->SetCanvasElement(this);
@ -779,7 +781,9 @@ HTMLCanvasElement::TransferControlToOffscreen(ErrorResult& aRv)
sz.height,
GetCompositorBackendType(),
renderer);
mContextObserver = new HTMLCanvasElementObserver(this);
if (!mContextObserver) {
mContextObserver = new HTMLCanvasElementObserver(this);
}
} else {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
}

View File

@ -151,6 +151,7 @@ public:
return nsRefPtr<ImportLoader>(mImportLoader).forget();
}
virtual CORSMode GetCORSMode() const override;
protected:
virtual ~HTMLLinkElement();
@ -161,7 +162,6 @@ protected:
nsAString& aMedia,
bool* aIsScoped,
bool* aIsAlternate) override;
virtual CORSMode GetCORSMode() const override;
protected:
// nsGenericHTMLElement
virtual void GetItemValueText(DOMString& text) override;

View File

@ -5,9 +5,7 @@ support-files =
[test_Document-createElement-namespace.html.json]
[test_Document-createElementNS.html.json]
[test_Document-getElementsByTagName.html.json]
[test_Node-properties.html.json]
[test_attributes.html.json]
[test_case.html.json]
[test_getElementsByClassName-10.xml.json]
[test_getElementsByClassName-11.xml.json]

View File

@ -1,4 +0,0 @@
{
"Document.getElementsByTagName 1": true,
"Document.getElementsByTagName 2": true
}

View File

@ -1,7 +1,5 @@
{
"getElementsByTagName abc": true,
"getElementsByTagName Abc": true,
"getElementsByTagName ABC": true,
"getElementsByTagName \u00e4": true,
"getElementsByTagName \u00c4": true
"getElementsByTagName ABC": true
}

View File

@ -1,3 +0,0 @@
{
"document.getElementsByClassName(): compound": true
}

View File

@ -36,7 +36,7 @@ public:
nsresult Flush();
// Shutdown decoder and rejects the init promise.
nsresult Shutdown();
virtual nsresult Shutdown();
// True if sample is queued.
bool HasQueuedSample();

View File

@ -59,16 +59,22 @@ GonkVideoDecoderManager::GonkVideoDecoderManager(
nsIntSize frameSize(mVideoWidth, mVideoHeight);
mPicture = pictureRect;
mInitialFrame = frameSize;
mVideoListener = new VideoResourceListener(this);
mVideoListener = new VideoResourceListener();
}
GonkVideoDecoderManager::~GonkVideoDecoderManager()
{
mVideoListener->NotifyManagerRelease();
MOZ_COUNT_DTOR(GonkVideoDecoderManager);
}
nsresult
GonkVideoDecoderManager::Shutdown()
{
mVideoCodecRequest.DisconnectIfExists();
return GonkDecoderManager::Shutdown();
}
nsRefPtr<MediaDataDecoder::InitPromise>
GonkVideoDecoderManager::Init()
{
@ -107,6 +113,16 @@ GonkVideoDecoderManager::Init()
}
nsRefPtr<InitPromise> p = mInitPromise.Ensure(__func__);
android::sp<GonkVideoDecoderManager> self = this;
mVideoCodecRequest.Begin(mVideoListener->Init()
->Then(mReaderTaskQueue, __func__,
[self] (bool) -> void {
self->mVideoCodecRequest.Complete();
self->codecReserved();
}, [self] (bool) -> void {
self->mVideoCodecRequest.Complete();
self->codecCanceled();
}));
mDecoder = MediaCodecProxy::CreateByType(mDecodeLooper, mMimeType.get(), false, mVideoListener);
mDecoder->AsyncAskMediaCodec();
@ -399,6 +415,9 @@ void GonkVideoDecoderManager::ReleaseVideoBuffer() {
void
GonkVideoDecoderManager::codecReserved()
{
if (mInitPromise.IsEmpty()) {
return;
}
GVDM_LOG("codecReserved");
sp<AMessage> format = new AMessage;
sp<Surface> surface;
@ -427,7 +446,7 @@ GonkVideoDecoderManager::codecReserved()
return;
}
mInitPromise.ResolveIfExists(TrackType::kVideoTrack, __func__);
mInitPromise.Resolve(TrackType::kVideoTrack, __func__);
}
void
@ -456,66 +475,24 @@ GonkVideoDecoderManager::onMessageReceived(const sp<AMessage> &aMessage)
}
}
GonkVideoDecoderManager::VideoResourceListener::VideoResourceListener(GonkVideoDecoderManager *aManager)
: mManager(aManager)
GonkVideoDecoderManager::VideoResourceListener::VideoResourceListener()
{
}
GonkVideoDecoderManager::VideoResourceListener::~VideoResourceListener()
{
mManager = nullptr;
}
void
GonkVideoDecoderManager::VideoResourceListener::codecReserved()
{
// This class holds VideoResourceListener reference to prevent it's destroyed.
class CodecListenerHolder : public nsRunnable {
public:
CodecListenerHolder(VideoResourceListener* aListener)
: mVideoListener(aListener) {}
NS_IMETHOD Run()
{
mVideoListener->NotifyCodecReserved();
mVideoListener = nullptr;
return NS_OK;
}
android::sp<VideoResourceListener> mVideoListener;
};
if (mManager) {
nsRefPtr<CodecListenerHolder> runner = new CodecListenerHolder(this);
mManager->mReaderTaskQueue->Dispatch(runner.forget());
}
mVideoCodecPromise.Resolve(true, __func__);
}
void
GonkVideoDecoderManager::VideoResourceListener::codecCanceled()
{
if (mManager) {
MOZ_ASSERT(mManager->mReaderTaskQueue->IsCurrentThreadIn());
nsCOMPtr<nsIRunnable> r =
NS_NewNonOwningRunnableMethod(mManager, &GonkVideoDecoderManager::codecCanceled);
mManager->mReaderTaskQueue->Dispatch(r.forget());
}
}
void
GonkVideoDecoderManager::VideoResourceListener::NotifyManagerRelease()
{
MOZ_ASSERT_IF(mManager, mManager->mReaderTaskQueue->IsCurrentThreadIn());
mManager = nullptr;
}
void
GonkVideoDecoderManager::VideoResourceListener::NotifyCodecReserved()
{
if (mManager) {
MOZ_ASSERT(mManager->mReaderTaskQueue->IsCurrentThreadIn());
mManager->codecReserved();
}
mVideoCodecPromise.Reject(true, __func__);
}
uint8_t *

View File

@ -36,6 +36,8 @@ typedef android::MediaCodecProxy MediaCodecProxy;
typedef mozilla::layers::TextureClient TextureClient;
public:
typedef MozPromise<bool /* aIgnored */, bool /* aIgnored */, /* IsExclusive = */ true> MediaResourcePromise;
GonkVideoDecoderManager(mozilla::layers::ImageContainer* aImageContainer,
const VideoInfo& aConfig);
@ -46,6 +48,8 @@ public:
nsresult Output(int64_t aStreamOffset,
nsRefPtr<MediaData>& aOutput) override;
nsresult Shutdown() override;
static void RecycleCallback(TextureClient* aClient, void* aClosure);
private:
@ -67,24 +71,25 @@ private:
class VideoResourceListener : public android::MediaCodecProxy::CodecResourceListener
{
public:
VideoResourceListener(GonkVideoDecoderManager *aManager);
VideoResourceListener();
~VideoResourceListener();
nsRefPtr<MediaResourcePromise> Init()
{
nsRefPtr<MediaResourcePromise> p = mVideoCodecPromise.Ensure(__func__);
return p.forget();
}
void codecReserved() override;
void codecCanceled() override;
void NotifyManagerRelease();
void NotifyCodecReserved();
private:
// Forbidden
VideoResourceListener() = delete;
VideoResourceListener(const VideoResourceListener &rhs) = delete;
const VideoResourceListener &operator=(const VideoResourceListener &rhs) = delete;
GonkVideoDecoderManager *mManager;
MozPromiseHolder<MediaResourcePromise> mVideoCodecPromise;
};
friend class VideoResourceListener;
bool SetVideoFormat();
@ -113,6 +118,7 @@ private:
MediaInfo mInfo;
android::sp<VideoResourceListener> mVideoListener;
MozPromiseRequestHolder<MediaResourcePromise> mVideoCodecRequest;
FrameInfo mFrameInfo;
// color converter

View File

@ -1847,6 +1847,10 @@ nsPluginHost::SiteHasData(nsIPluginTag* plugin, const nsACString& domain,
nsPluginHost::SpecialType
nsPluginHost::GetSpecialType(const nsACString & aMIMEType)
{
if (aMIMEType.LowerCaseEqualsASCII("application/x-test")) {
return eSpecialType_Test;
}
if (aMIMEType.LowerCaseEqualsASCII("application/x-shockwave-flash") ||
aMIMEType.LowerCaseEqualsASCII("application/futuresplash")) {
return eSpecialType_Flash;
@ -2446,6 +2450,7 @@ nsPluginHost::FindPluginsInContent(bool aCreatePluginList, bool* aPluginsChanged
nsTArray<nsCString>(tag.extensions()),
tag.isJavaPlugin(),
tag.isFlashPlugin(),
tag.supportsAsyncInit(),
tag.lastModifiedTime(),
tag.isFromExtension());
AddPluginTag(pluginTag);
@ -2682,6 +2687,7 @@ nsPluginHost::FindPluginsForContent(uint32_t aPluginEpoch,
tag->Extensions(),
tag->mIsJavaPlugin,
tag->mIsFlashPlugin,
tag->mSupportsAsyncInit,
tag->FileName(),
tag->Version(),
tag->mLastModifiedTime,

View File

@ -191,6 +191,8 @@ public:
// checks whether aType is a type we recognize for potential special handling
enum SpecialType { eSpecialType_None,
// Needed to whitelist for async init support
eSpecialType_Test,
// Informs some decisions about OOP and quirks
eSpecialType_Flash,
// Binds to the <applet> tag, has various special

View File

@ -293,6 +293,7 @@ nsPluginTag::nsPluginTag(uint32_t aId,
nsTArray<nsCString> aExtensions,
bool aIsJavaPlugin,
bool aIsFlashPlugin,
bool aSupportsAsyncInit,
int64_t aLastModifiedTime,
bool aFromExtension)
: nsIInternalPluginTag(aName, aDescription, aFileName, aVersion, aMimeTypes,
@ -302,7 +303,7 @@ nsPluginTag::nsPluginTag(uint32_t aId,
mLibrary(nullptr),
mIsJavaPlugin(aIsJavaPlugin),
mIsFlashPlugin(aIsFlashPlugin),
mSupportsAsyncInit(false),
mSupportsAsyncInit(aSupportsAsyncInit),
mLastModifiedTime(aLastModifiedTime),
mNiceFileName(),
mCachedBlocklistState(nsIBlocklistService::STATE_NOT_BLOCKED),
@ -354,6 +355,7 @@ void nsPluginTag::InitMime(const char* const* aMimeTypes,
break;
case nsPluginHost::eSpecialType_Silverlight:
case nsPluginHost::eSpecialType_Unity:
case nsPluginHost::eSpecialType_Test:
mSupportsAsyncInit = true;
break;
case nsPluginHost::eSpecialType_None:

View File

@ -128,6 +128,7 @@ public:
nsTArray<nsCString> aExtensions,
bool aIsJavaPlugin,
bool aIsFlashPlugin,
bool aSupportsAsyncInit,
int64_t aLastModifiedTime,
bool aFromExtension);

View File

@ -16,6 +16,7 @@ struct PluginTag
nsCString[] extensions;
bool isJavaPlugin;
bool isFlashPlugin;
bool supportsAsyncInit;
nsCString filename;
nsCString version;
int64_t lastModifiedTime;

View File

@ -112,11 +112,33 @@ Volume::Dump(const char* aLabel) const
: (IsUnmounting() ? "y" : "n"));
}
void
Volume::ResolveAndSetMountPoint(const nsCSubstring& aMountPoint)
{
nsCString mountPoint(aMountPoint);
char realPathBuf[PATH_MAX];
// Call realpath so that we wind up with a path which is compatible with
// functions like nsVolumeService::GetVolumeByPath.
if (realpath(mountPoint.get(), realPathBuf) < 0) {
// The path we were handed doesn't exist. Warn about it, but use it
// anyways assuming that the user knows what they're doing.
ERR("ResolveAndSetMountPoint: realpath on '%s' failed: %d",
mountPoint.get(), errno);
mMountPoint = mountPoint;
} else {
mMountPoint = realPathBuf;
}
DBG("Volume %s: Setting mountpoint to '%s'", NameStr(), mMountPoint.get());
}
void Volume::SetFakeVolume(const nsACString& aMountPoint)
{
this->mMountLocked = false;
this->mCanBeShared = false;
this->mMountPoint = aMountPoint;
ResolveAndSetMountPoint(aMountPoint);
SetState(nsIVolume::STATE_MOUNTED);
}
@ -386,8 +408,7 @@ Volume::SetMountPoint(const nsCSubstring& aMountPoint)
if (mMountPoint.Equals(aMountPoint)) {
return;
}
mMountPoint = aMountPoint;
DBG("Volume %s: Setting mountpoint to '%s'", NameStr(), mMountPoint.get());
ResolveAndSetMountPoint(aMountPoint);
}
void

View File

@ -119,6 +119,8 @@ private:
void SetMountPoint(const nsCSubstring& aMountPoint);
void StartCommand(VolumeCommand* aCommand);
void ResolveAndSetMountPoint(const nsCSubstring& aMountPoint);
bool BoolConfigValue(const nsCString& aConfigValue, bool& aBoolValue);
void SetConfig(const nsCString& aConfigName, const nsCString& aConfigValue);

View File

@ -305,7 +305,7 @@ add_test(function test_is_cphs_service_available() {
let context = worker.ContextPool._contexts[0];
let ICCUtilsHelper = context.ICCUtilsHelper;
let RIL = context.RIL;
RIL.iccInfoPrivate.cphsSt = Uint8Array(2);
RIL.iccInfoPrivate.cphsSt = new Uint8Array(2);
function test_table(cphsSt, geckoService) {
RIL.iccInfoPrivate.cphsSt.set(cphsSt);

View File

@ -1312,7 +1312,7 @@ add_test(function test_read_cphs_info() {
let recordHelper = context.SimRecordHelper;
let buf = context.Buf;
let io = context.ICCIOHelper;
let cphsPDU = Uint8Array(3);
let cphsPDU = new Uint8Array(3);
io.loadTransparentEF = function(options) {
if (cphsPDU) {

View File

@ -100,7 +100,8 @@ function elementsetattributens03() {
docRef = this.doc;
}
doc = load(docRef, "doc", "staffNS");
elementList = doc.getElementsByTagName("emp:employee");
// Changed for bug 492933.
elementList = doc.getElementsByTagName("employee");
element = elementList.item(0);
assertNotNull("empEmployeeNotNull",element);
element.setAttributeNS("http://www.w3.org/DOM/Test/1","defaultAttr","default1");

View File

@ -105,11 +105,13 @@ function getAttributeNS02() {
}
doc = load(docRef, "doc", "staffNS");
newAttribute = doc.createAttributeNS(namespaceURI,qualifiedName);
elementList = doc.getElementsByTagName("emp:address");
// Changed for bug 492933.
elementList = doc.getElementsByTagName("address");
testAddr = elementList.item(0);
assertNotNull("empAddrNotNull",testAddr);
districtAttr = testAddr.setAttributeNodeNS(newAttribute);
elementList = doc.getElementsByTagName("emp:address");
// Changed for bug 492933.
elementList = doc.getElementsByTagName("address");
testAddr = elementList.item(0);
attrValue = testAddr.getAttributeNS(namespaceURI,localName);
assertEquals("throw_Equals","",attrValue);

View File

@ -100,7 +100,8 @@ function getAttributeNS03() {
docRef = this.doc;
}
doc = load(docRef, "doc", "staffNS");
elementList = doc.getElementsByTagName("emp:address");
// Changed for bug 492933.
elementList = doc.getElementsByTagName("address");
testAddr = elementList.item(0);
assertNotNull("empAddrNotNull",testAddr);
testAddr.removeAttributeNS(namespaceURI,localName);

View File

@ -105,7 +105,8 @@ function getAttributeNS04() {
}
doc = load(docRef, "doc", "staffNS");
newAttribute = doc.createAttributeNS(namespaceURI,qualifiedName);
elementList = doc.getElementsByTagName("emp:address");
// Changed for bug 492933.
elementList = doc.getElementsByTagName("address");
testAddr = elementList.item(0);
assertNotNull("empAddrNotNull",testAddr);
testAddr.setAttributeNS(namespaceURI,qualifiedName,"NewValue");

View File

@ -99,8 +99,9 @@ function getAttributeNS05() {
docRef = this.doc;
}
doc = load(docRef, "doc", "staffNS");
elementList = doc.getElementsByTagName("emp:address");
testAddr = elementList.item(0);
// Changed for bug 492933.
elementList = doc.getElementsByTagName("address");
testAddr = elementList.item(3);
assertNotNull("empAddrNotNull",testAddr);
attrValue = testAddr.getAttributeNS("http://www.nist.gov","domestic");
assertEquals("attrValue","Yes",attrValue);

View File

@ -101,7 +101,8 @@ function getAttributeNodeNS01() {
docRef = this.doc;
}
doc = load(docRef, "doc", "staffNS");
elementList = doc.getElementsByTagName("emp:address");
// Changed for bug 492933.
elementList = doc.getElementsByTagName("address");
testAddr = elementList.item(0);
assertNotNull("empAddrNotNull",testAddr);
attribute = testAddr.getAttributeNodeNS(namespaceURI,localName);

View File

@ -100,8 +100,9 @@ function getAttributeNodeNS02() {
docRef = this.doc;
}
doc = load(docRef, "doc", "staffNS");
elementList = doc.getElementsByTagName("emp:address");
testAddr = elementList.item(0);
// Changed for bug 492933.
elementList = doc.getElementsByTagName("address");
testAddr = elementList.item(3);
assertNotNull("empAddrNotNull",testAddr);
attribute = testAddr.getAttributeNodeNS("http://www.nist.gov","domestic");
attrName = attribute.nodeName;

View File

@ -100,7 +100,8 @@ function hasAttributeNS03() {
docRef = this.doc;
}
doc = load(docRef, "doc", "staffNS");
elementList = doc.getElementsByTagName("emp:address");
// Changed for bug 492933.
elementList = doc.getElementsByTagName("address");
testNode = elementList.item(0);
assertNotNull("empAddrNotNull",testNode);
state = testNode.hasAttributeNS(namespaceURI,localName);

View File

@ -102,7 +102,8 @@ function hasAttributeNS04() {
docRef = this.doc;
}
doc = load(docRef, "doc", "staffNS");
elementList = doc.getElementsByTagName("emp:address");
// Changed for bug 492933.
elementList = doc.getElementsByTagName("address");
testNode = elementList.item(0);
assertNotNull("empAddressNotNull",testNode);
state = testNode.hasAttributeNS(namespaceURI,localName);

View File

@ -119,8 +119,9 @@ function importNode05() {
aNewDocRef = this.aNewDoc;
}
aNewDoc = load(aNewDocRef, "aNewDoc", "staffNS");
addresses = aNewDoc.getElementsByTagName("emp:address");
element = addresses.item(0);
// Changed for bug 492933.
addresses = aNewDoc.getElementsByTagName("address");
element = addresses.item(3);
assertNotNull("empAddressNotNull",element);
aNode = doc.importNode(element,false);
hasChild = aNode.hasChildNodes();

View File

@ -117,8 +117,9 @@ function importNode06() {
aNewDocRef = this.aNewDoc;
}
aNewDoc = load(aNewDocRef, "aNewDoc", "staffNS");
addresses = aNewDoc.getElementsByTagName("emp:address");
element = addresses.item(0);
// Changed for bug 492933.
addresses = aNewDoc.getElementsByTagName("address");
element = addresses.item(3);
assertNotNull("empAddressNotNull",element);
aNode = doc.importNode(element,true);
hasChild = aNode.hasChildNodes();

View File

@ -101,8 +101,9 @@ function localName01() {
docRef = this.doc;
}
doc = load(docRef, "doc", "staffNS");
elementList = doc.getElementsByTagName("emp:address");
testAddr = elementList.item(0);
// Changed for bug 492933.
elementList = doc.getElementsByTagName("address");
testAddr = elementList.item(3);
assertNotNull("empAddrNotNull",testAddr);
addrAttr = testAddr.getAttributeNode("emp:domestic");
localName = addrAttr.localName;

View File

@ -99,8 +99,9 @@ function namespaceURI02() {
docRef = this.doc;
}
doc = load(docRef, "doc", "staffNS");
elementList = doc.getElementsByTagName("emp:address");
testAddr = elementList.item(0);
// Changed for bug 492933.
elementList = doc.getElementsByTagName("address");
testAddr = elementList.item(3);
assertNotNull("empAddressNotNull",testAddr);
addrAttr = testAddr.getAttributeNodeNS("http://www.nist.gov","domestic");
attrNamespaceURI = addrAttr.namespaceURI;

View File

@ -94,7 +94,8 @@ function nodehasattributes03() {
docRef = this.doc;
}
doc = load(docRef, "doc", "staffNS");
elementList = doc.getElementsByTagName("emp:employee");
// Changed for bug 492933.
elementList = doc.getElementsByTagName("employee");
element = elementList.item(0);
assertNotNull("empEmployeeNotNull",element);
hasAttributes = element.hasAttributes();

View File

@ -100,7 +100,8 @@ function prefix02() {
docRef = this.doc;
}
doc = load(docRef, "doc", "staffNS");
elementList = doc.getElementsByTagName("emp:employeeId");
// Changed for bug 492933.
elementList = doc.getElementsByTagName("employeeId");
testEmployee = elementList.item(0);
assertNotNull("empEmployeeNotNull",testEmployee);
textNode = testEmployee.firstChild;

View File

@ -97,8 +97,9 @@ function prefix03() {
docRef = this.doc;
}
doc = load(docRef, "doc", "staffNS");
elementList = doc.getElementsByTagName("emp:employee");
testEmployee = elementList.item(0);
// Changed for bug 492933.
elementList = doc.getElementsByTagName("employee");
testEmployee = elementList.item(3);
assertNotNull("empEmployeeNotNull",testEmployee);
prefix = testEmployee.prefix;

View File

@ -100,7 +100,8 @@ function setAttributeNS02() {
docRef = this.doc;
}
doc = load(docRef, "doc", "staffNS");
elementList = doc.getElementsByTagName("emp:employee");
// Changed for bug 492933.
elementList = doc.getElementsByTagName("employee");
testAddr = elementList.item(0);
{

View File

@ -108,7 +108,8 @@ function setAttributeNS04() {
docRef = this.doc;
}
doc = load(docRef, "doc", "staffNS");
elementList = doc.getElementsByTagName("emp:address");
// Changed for bug 492933.
elementList = doc.getElementsByTagName("address");
testAddr = elementList.item(0);
assertNotNull("empAddrNotNull",testAddr);
testAddr.setAttributeNS("http://www.nist.gov","newprefix:zone","newValue");

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