зеркало из https://github.com/mozilla/gecko-dev.git
Bug 776536 part 4. Turn on WebIDL bindings for NodeIterator and TreeWalker. r=peterv
The behavior here is a bit weird because Document is still not a WebIDL object, so calling createNodeIterator or createTreeWalker via an Xray will call the XPCOM versions of those methods. That means that I can't just disable XPCOM-based wrapping for TreeWalker and NodeIterator altogether, unfortunately, which means a web page could try stashing a TreeWalker in something like userdata and then getting it back and end up wrapping it as an XPCOM object the second time. I could "fix" that by adding a wrapper cache and whatnot, I guess, if desired... But the problem will go away once we convert Document in any case.
This commit is contained in:
Родитель
f2eec1914c
Коммит
08d376c598
|
@ -96,7 +96,9 @@ class GlobalObject;
|
|||
class HTMLBodyElement;
|
||||
class Link;
|
||||
class NodeFilter;
|
||||
class NodeIterator;
|
||||
class ProcessingInstruction;
|
||||
class TreeWalker;
|
||||
class UndoManager;
|
||||
template<typename> class Sequence;
|
||||
|
||||
|
@ -1939,18 +1941,18 @@ public:
|
|||
already_AddRefed<nsIDOMEvent> CreateEvent(const nsAString& aEventType,
|
||||
mozilla::ErrorResult& rv) const;
|
||||
already_AddRefed<nsRange> CreateRange(mozilla::ErrorResult& rv);
|
||||
already_AddRefed<nsIDOMNodeIterator>
|
||||
already_AddRefed<mozilla::dom::NodeIterator>
|
||||
CreateNodeIterator(nsINode& aRoot, uint32_t aWhatToShow,
|
||||
mozilla::dom::NodeFilter* aFilter,
|
||||
mozilla::ErrorResult& rv) const;
|
||||
already_AddRefed<nsIDOMNodeIterator>
|
||||
already_AddRefed<mozilla::dom::NodeIterator>
|
||||
CreateNodeIterator(nsINode& aRoot, uint32_t aWhatToShow,
|
||||
const mozilla::dom::NodeFilterHolder& aFilter,
|
||||
mozilla::ErrorResult& rv) const;
|
||||
already_AddRefed<nsIDOMTreeWalker>
|
||||
already_AddRefed<mozilla::dom::TreeWalker>
|
||||
CreateTreeWalker(nsINode& aRoot, uint32_t aWhatToShow,
|
||||
mozilla::dom::NodeFilter* aFilter, mozilla::ErrorResult& rv) const;
|
||||
already_AddRefed<nsIDOMTreeWalker>
|
||||
already_AddRefed<mozilla::dom::TreeWalker>
|
||||
CreateTreeWalker(nsINode& aRoot, uint32_t aWhatToShow,
|
||||
const mozilla::dom::NodeFilterHolder& aFilter,
|
||||
mozilla::ErrorResult& rv) const;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "nsDOMClassInfoID.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "mozilla/dom/NodeIteratorBinding.h"
|
||||
|
||||
DOMCI_DATA(NodeIterator, mozilla::dom::NodeIterator)
|
||||
|
||||
|
@ -300,5 +301,11 @@ void NodeIterator::ContentRemoved(nsIDocument *aDocument,
|
|||
mWorkingPointer.AdjustAfterRemoval(mRoot, container, aChild, aPreviousSibling);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
NodeIterator::WrapObject(JSContext *cx, JSObject *scope)
|
||||
{
|
||||
return NodeIteratorBinding::Wrap(cx, scope, this);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -22,9 +22,9 @@ class nsIDOMNode;
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class NodeIterator : public nsIDOMNodeIterator,
|
||||
public nsTraversal,
|
||||
public nsStubMutationObserver
|
||||
class NodeIterator MOZ_FINAL : public nsIDOMNodeIterator,
|
||||
public nsTraversal,
|
||||
public nsStubMutationObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
|
@ -70,6 +70,8 @@ public:
|
|||
}
|
||||
// The XPCOM Detach() is fine for our purposes
|
||||
|
||||
JSObject* WrapObject(JSContext *cx, JSObject *scope);
|
||||
|
||||
private:
|
||||
struct NodePointer {
|
||||
NodePointer() : mNode(nullptr) {}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "nsINode.h"
|
||||
#include "nsDOMClassInfoID.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "mozilla/dom/TreeWalkerBinding.h"
|
||||
|
||||
DOMCI_DATA(TreeWalker, mozilla::dom::TreeWalker)
|
||||
|
||||
|
@ -449,5 +450,11 @@ TreeWalker::NextSiblingInternal(bool aReversed, ErrorResult& aResult)
|
|||
}
|
||||
}
|
||||
|
||||
JSObject*
|
||||
TreeWalker::WrapObject(JSContext *cx, JSObject *scope)
|
||||
{
|
||||
return TreeWalkerBinding::Wrap(cx, scope, this);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -23,7 +23,7 @@ class nsIDOMNode;
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class TreeWalker : public nsIDOMTreeWalker, public nsTraversal
|
||||
class TreeWalker MOZ_FINAL : public nsIDOMTreeWalker, public nsTraversal
|
||||
{
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
|
@ -64,6 +64,8 @@ public:
|
|||
already_AddRefed<nsINode> PreviousNode(ErrorResult& aResult);
|
||||
already_AddRefed<nsINode> NextNode(ErrorResult& aResult);
|
||||
|
||||
JSObject* WrapObject(JSContext *cx, JSObject *scope);
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsINode> mCurrentNode;
|
||||
|
||||
|
|
|
@ -4746,7 +4746,7 @@ nsDocument::CreateProcessingInstruction(const nsAString& aTarget,
|
|||
already_AddRefed<ProcessingInstruction>
|
||||
nsIDocument::CreateProcessingInstruction(const nsAString& aTarget,
|
||||
const nsAString& aData,
|
||||
mozilla::ErrorResult& rv) const
|
||||
ErrorResult& rv) const
|
||||
{
|
||||
nsresult res = nsContentUtils::CheckQName(aTarget, false);
|
||||
if (NS_FAILED(res)) {
|
||||
|
@ -4823,7 +4823,7 @@ nsDocument::CreateAttributeNS(const nsAString & aNamespaceURI,
|
|||
already_AddRefed<nsIDOMAttr>
|
||||
nsIDocument::CreateAttributeNS(const nsAString& aNamespaceURI,
|
||||
const nsAString& aQualifiedName,
|
||||
mozilla::ErrorResult& rv)
|
||||
ErrorResult& rv)
|
||||
{
|
||||
WarnOnceAbout(eCreateAttributeNS);
|
||||
|
||||
|
@ -5361,23 +5361,19 @@ nsDocument::CreateNodeIterator(nsIDOMNode *aRoot,
|
|||
return rv.ErrorCode();
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDOMNodeIterator>
|
||||
already_AddRefed<NodeIterator>
|
||||
nsIDocument::CreateNodeIterator(nsINode& aRoot, uint32_t aWhatToShow,
|
||||
NodeFilter* aFilter,
|
||||
mozilla::ErrorResult& rv) const
|
||||
ErrorResult& rv) const
|
||||
{
|
||||
NodeFilterHolder holder(aFilter);
|
||||
// We don't really know how to handle WebIDL callbacks yet, in
|
||||
// nsTraversal, so just go ahead and convert to an XPCOM callback.
|
||||
nsCOMPtr<nsIDOMNodeFilter> filter = holder.ToXPCOMCallback();
|
||||
NodeFilterHolder holder2(filter);
|
||||
return CreateNodeIterator(aRoot, aWhatToShow, holder2, rv);
|
||||
return CreateNodeIterator(aRoot, aWhatToShow, holder, rv);
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDOMNodeIterator>
|
||||
already_AddRefed<NodeIterator>
|
||||
nsIDocument::CreateNodeIterator(nsINode& aRoot, uint32_t aWhatToShow,
|
||||
const NodeFilterHolder& aFilter,
|
||||
mozilla::ErrorResult& rv) const
|
||||
ErrorResult& rv) const
|
||||
{
|
||||
nsINode* root = &aRoot;
|
||||
nsresult res = nsContentUtils::CheckSameOrigin(this, root);
|
||||
|
@ -5414,20 +5410,16 @@ nsDocument::CreateTreeWalker(nsIDOMNode *aRoot,
|
|||
return rv.ErrorCode();
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDOMTreeWalker>
|
||||
already_AddRefed<TreeWalker>
|
||||
nsIDocument::CreateTreeWalker(nsINode& aRoot, uint32_t aWhatToShow,
|
||||
NodeFilter* aFilter,
|
||||
ErrorResult& rv) const
|
||||
{
|
||||
NodeFilterHolder holder(aFilter);
|
||||
// We don't really know how to handle WebIDL callbacks yet, in
|
||||
// nsTraversal, so just go ahead and convert to an XPCOM callback.
|
||||
nsCOMPtr<nsIDOMNodeFilter> filter = holder.ToXPCOMCallback();
|
||||
NodeFilterHolder holder2(filter);
|
||||
return CreateTreeWalker(aRoot, aWhatToShow, holder2, rv);
|
||||
return CreateTreeWalker(aRoot, aWhatToShow, holder, rv);
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDOMTreeWalker>
|
||||
already_AddRefed<TreeWalker>
|
||||
nsIDocument::CreateTreeWalker(nsINode& aRoot, uint32_t aWhatToShow,
|
||||
const NodeFilterHolder& aFilter,
|
||||
ErrorResult& rv) const
|
||||
|
|
|
@ -61,7 +61,8 @@ nsTraversal::TestNode(nsINode* aNode, mozilla::ErrorResult& aResult)
|
|||
if (mFilter.HasWebIDLCallback()) {
|
||||
AutoRestore<bool> inAcceptNode(mInAcceptNode);
|
||||
mInAcceptNode = true;
|
||||
return mFilter.GetWebIDLCallback()->AcceptNode(*aNode, aResult);
|
||||
return mFilter.GetWebIDLCallback()->
|
||||
AcceptNode(*aNode, aResult, CallbackObject::eRethrowExceptions);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNode> domNode = do_QueryInterface(aNode);
|
||||
|
|
|
@ -534,9 +534,9 @@ DOMInterfaces = {
|
|||
'attributes' ]
|
||||
},
|
||||
|
||||
'NodeFilter': {
|
||||
'nativeType': 'nsIDOMNodeFilter',
|
||||
'headerFile': 'nsIDOMNodeFilter.h',
|
||||
'NodeIterator': {
|
||||
'wrapperCache': False,
|
||||
'resultNotAddRefed': [ 'root', 'referenceNode' ],
|
||||
},
|
||||
|
||||
'NodeList': {
|
||||
|
@ -848,6 +848,11 @@ DOMInterfaces = {
|
|||
'implicitJSContext': [ 'encode' ],
|
||||
}],
|
||||
|
||||
'TreeWalker': {
|
||||
'wrapperCache': False,
|
||||
'resultNotAddRefed': [ 'root', 'currentNode' ],
|
||||
},
|
||||
|
||||
'URL' : [{
|
||||
'concrete': False,
|
||||
},
|
||||
|
@ -1212,7 +1217,6 @@ addExternalIface('MozRDFCompositeDataSource', nativeType='nsIRDFCompositeDataSou
|
|||
addExternalIface('MozRDFResource', nativeType='nsIRDFResource', notflattened=True)
|
||||
addExternalIface('MozXULTemplateBuilder', nativeType='nsIXULTemplateBuilder')
|
||||
addExternalIface('NamedNodeMap')
|
||||
addExternalIface('NodeIterator')
|
||||
addExternalIface('nsIStreamListener', nativeType='nsIStreamListener', notflattened=True)
|
||||
addExternalIface('nsISupports', nativeType='nsISupports')
|
||||
addExternalIface('nsIEditor', nativeType='nsIEditor', notflattened=True)
|
||||
|
@ -1230,7 +1234,6 @@ addExternalIface('SVGAnimatedString')
|
|||
addExternalIface('SVGLength')
|
||||
addExternalIface('SVGNumber')
|
||||
addExternalIface('TextMetrics', headerFile='nsIDOMCanvasRenderingContext2D.h')
|
||||
addExternalIface('TreeWalker')
|
||||
addExternalIface('Touch', headerFile='nsIDOMTouchEvent.h')
|
||||
addExternalIface('TouchList', headerFile='nsIDOMTouchEvent.h')
|
||||
addExternalIface('URI', nativeType='nsIURI', headerFile='nsIURI.h',
|
||||
|
|
|
@ -131,23 +131,6 @@
|
|||
"Range interface: calling isPointInRange(Node,unsigned long) on detachedRange with too few arguments must throw TypeError": true,
|
||||
"Range interface: calling comparePoint(Node,unsigned long) on detachedRange with too few arguments must throw TypeError": true,
|
||||
"Range interface: calling intersectsNode(Node) on detachedRange with too few arguments must throw TypeError": true,
|
||||
"NodeIterator interface: existence and properties of interface object": true,
|
||||
"NodeIterator interface: existence and properties of interface prototype object": true,
|
||||
"NodeIterator interface: existence and properties of interface prototype object's \"constructor\" property": true,
|
||||
"NodeIterator interface: attribute root": true,
|
||||
"NodeIterator interface: attribute referenceNode": true,
|
||||
"NodeIterator interface: attribute pointerBeforeReferenceNode": true,
|
||||
"NodeIterator interface: attribute whatToShow": true,
|
||||
"NodeIterator interface: attribute filter": true,
|
||||
"Stringification of document.createNodeIterator(document.body, NodeFilter.SHOW_ALL, null)": "debug",
|
||||
"TreeWalker interface: existence and properties of interface object": true,
|
||||
"TreeWalker interface: existence and properties of interface prototype object": true,
|
||||
"TreeWalker interface: existence and properties of interface prototype object's \"constructor\" property": true,
|
||||
"TreeWalker interface: attribute root": true,
|
||||
"TreeWalker interface: attribute whatToShow": true,
|
||||
"TreeWalker interface: attribute filter": true,
|
||||
"TreeWalker interface: attribute currentNode": true,
|
||||
"Stringification of document.createTreeWalker(document.body, NodeFilter.SHOW_ALL, null)": "debug",
|
||||
"NodeFilter interface: existence and properties of interface object": true,
|
||||
"NodeFilter interface: existence and properties of interface prototype object": true,
|
||||
"NodeFilter interface: existence and properties of interface prototype object's \"constructor\" property": true,
|
||||
|
|
|
@ -17,12 +17,10 @@
|
|||
|
||||
interface Attr;
|
||||
interface Comment;
|
||||
interface NodeIterator;
|
||||
interface Range;
|
||||
interface StyleSheetList;
|
||||
interface Touch;
|
||||
interface TouchList;
|
||||
interface TreeWalker;
|
||||
interface WindowProxy;
|
||||
interface nsISupports;
|
||||
|
||||
|
|
|
@ -28,4 +28,4 @@ interface NodeIterator {
|
|||
Node? previousNode();
|
||||
|
||||
void detach();
|
||||
;}
|
||||
};
|
||||
|
|
|
@ -121,6 +121,7 @@ webidl_files = \
|
|||
MutationObserver.webidl \
|
||||
Node.webidl \
|
||||
NodeFilter.webidl \
|
||||
NodeIterator.webidl \
|
||||
NodeList.webidl \
|
||||
PaintRequest.webidl \
|
||||
PaintRequestList.webidl \
|
||||
|
@ -211,6 +212,7 @@ webidl_files = \
|
|||
Text.webidl \
|
||||
TextDecoder.webidl \
|
||||
TextEncoder.webidl \
|
||||
TreeWalker.webidl \
|
||||
URL.webidl \
|
||||
ValidityState.webidl \
|
||||
WebSocket.webidl \
|
||||
|
|
|
@ -37,7 +37,6 @@ MOCHITEST_FILES = chrome_wrappers_helper.html \
|
|||
test_bug478438.html \
|
||||
test_bug500691.html \
|
||||
bug500931_helper.html \
|
||||
test_bug502959.html \
|
||||
test_bug503926.html \
|
||||
test_bug504877.html \
|
||||
bug504877_helper.html \
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=502959
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 502959</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=502959">Mozilla Bug 502959</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 502959 **/
|
||||
// Whatever you do don't use the word "wrapped" in this function.
|
||||
function foo() {
|
||||
ok(true, "Able to call the function");
|
||||
}
|
||||
|
||||
var iter = document.createNodeIterator(document, NodeFilter.SHOW_ELEMENT, foo);
|
||||
var doublewrapped = iter.filter;
|
||||
|
||||
ok(doublewrapped.toString().indexOf("wrapped") > 0, "got a double-wrapped object back");
|
||||
|
||||
(function () {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
Components.utils.forceGC();
|
||||
})();
|
||||
|
||||
doublewrapped.acceptNode(document);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче