summaryrefslogtreecommitdiffstats
path: root/WebCore/bindings/js/JSNodeCustom.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/bindings/js/JSNodeCustom.cpp')
-rw-r--r--WebCore/bindings/js/JSNodeCustom.cpp100
1 files changed, 78 insertions, 22 deletions
diff --git a/WebCore/bindings/js/JSNodeCustom.cpp b/WebCore/bindings/js/JSNodeCustom.cpp
index 46a30a4..3a07b29 100644
--- a/WebCore/bindings/js/JSNodeCustom.cpp
+++ b/WebCore/bindings/js/JSNodeCustom.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2009, 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -34,10 +34,12 @@
#include "DocumentType.h"
#include "Entity.h"
#include "EntityReference.h"
+#include "ExceptionCode.h"
#include "HTMLElement.h"
#include "JSAttr.h"
#include "JSCDATASection.h"
#include "JSComment.h"
+#include "JSDOMBinding.h"
#include "JSDocument.h"
#include "JSDocumentFragment.h"
#include "JSDocumentType.h"
@@ -66,12 +68,53 @@ using namespace JSC;
namespace WebCore {
-typedef int ExpectionCode;
+static inline bool isAttrFrameSrc(Element *element, const String& name)
+{
+ return element && (element->hasTagName(HTMLNames::iframeTag) || element->hasTagName(HTMLNames::frameTag)) && equalIgnoringCase(name, "src");
+}
+
+void JSNode::setNodeValue(JSC::ExecState* exec, JSC::JSValue value)
+{
+ Node* imp = static_cast<Node*>(impl());
+ String nodeValue = valueToStringWithNullCheck(exec, value);
+
+ if (imp->nodeType() == Node::ATTRIBUTE_NODE) {
+ Element* ownerElement = static_cast<Attr*>(impl())->ownerElement();
+ if (ownerElement && !allowSettingSrcToJavascriptURL(exec, ownerElement, imp->nodeName(), nodeValue))
+ return;
+ }
+
+ ExceptionCode ec = 0;
+ imp->setNodeValue(nodeValue, ec);
+ setDOMException(exec, ec);
+}
+
+void JSNode::setTextContent(JSC::ExecState* exec, JSC::JSValue value)
+{
+ Node* imp = static_cast<Node*>(impl());
+ String nodeValue = valueToStringWithNullCheck(exec, value);
+
+ if (imp->nodeType() == Node::ATTRIBUTE_NODE) {
+ Element* ownerElement = static_cast<Attr*>(impl())->ownerElement();
+ if (ownerElement && !allowSettingSrcToJavascriptURL(exec, ownerElement, imp->nodeName(), nodeValue))
+ return;
+ }
+
+ ExceptionCode ec = 0;
+ imp->setTextContent(nodeValue, ec);
+ setDOMException(exec, ec);
+}
JSValue JSNode::insertBefore(ExecState* exec, const ArgList& args)
{
+ Node* imp = static_cast<Node*>(impl());
+ if (imp->nodeType() == Node::ATTRIBUTE_NODE && isAttrFrameSrc(static_cast<Attr*>(impl())->ownerElement(), imp->nodeName())) {
+ setDOMException(exec, NOT_SUPPORTED_ERR);
+ return jsNull();
+ }
+
ExceptionCode ec = 0;
- bool ok = impl()->insertBefore(toNode(args.at(0)), toNode(args.at(1)), ec, true);
+ bool ok = imp->insertBefore(toNode(args.at(0)), toNode(args.at(1)), ec, true);
setDOMException(exec, ec);
if (ok)
return args.at(0);
@@ -80,8 +123,14 @@ JSValue JSNode::insertBefore(ExecState* exec, const ArgList& args)
JSValue JSNode::replaceChild(ExecState* exec, const ArgList& args)
{
+ Node* imp = static_cast<Node*>(impl());
+ if (imp->nodeType() == Node::ATTRIBUTE_NODE && isAttrFrameSrc(static_cast<Attr*>(impl())->ownerElement(), imp->nodeName())) {
+ setDOMException(exec, NOT_SUPPORTED_ERR);
+ return jsNull();
+ }
+
ExceptionCode ec = 0;
- bool ok = impl()->replaceChild(toNode(args.at(0)), toNode(args.at(1)), ec, true);
+ bool ok = imp->replaceChild(toNode(args.at(0)), toNode(args.at(1)), ec, true);
setDOMException(exec, ec);
if (ok)
return args.at(1);
@@ -90,8 +139,14 @@ JSValue JSNode::replaceChild(ExecState* exec, const ArgList& args)
JSValue JSNode::removeChild(ExecState* exec, const ArgList& args)
{
+ Node* imp = static_cast<Node*>(impl());
+ if (imp->nodeType() == Node::ATTRIBUTE_NODE && isAttrFrameSrc(static_cast<Attr*>(impl())->ownerElement(), imp->nodeName())) {
+ setDOMException(exec, NOT_SUPPORTED_ERR);
+ return jsNull();
+ }
+
ExceptionCode ec = 0;
- bool ok = impl()->removeChild(toNode(args.at(0)), ec);
+ bool ok = imp->removeChild(toNode(args.at(0)), ec);
setDOMException(exec, ec);
if (ok)
return args.at(0);
@@ -100,8 +155,14 @@ JSValue JSNode::removeChild(ExecState* exec, const ArgList& args)
JSValue JSNode::appendChild(ExecState* exec, const ArgList& args)
{
+ Node* imp = static_cast<Node*>(impl());
+ if (imp->nodeType() == Node::ATTRIBUTE_NODE && isAttrFrameSrc(static_cast<Attr*>(impl())->ownerElement(), imp->nodeName())) {
+ setDOMException(exec, NOT_SUPPORTED_ERR);
+ return jsNull();
+ }
+
ExceptionCode ec = 0;
- bool ok = impl()->appendChild(toNode(args.at(0)), ec, true);
+ bool ok = imp->appendChild(toNode(args.at(0)), ec, true);
setDOMException(exec, ec);
if (ok)
return args.at(0);
@@ -114,7 +175,7 @@ JSValue JSNode::addEventListener(ExecState* exec, const ArgList& args)
if (!listener.isObject())
return jsUndefined();
- impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)), args.at(2).toBoolean(exec));
+ impl()->addEventListener(ustringToAtomicString(args.at(0).toString(exec)), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)), args.at(2).toBoolean(exec));
return jsUndefined();
}
@@ -124,7 +185,7 @@ JSValue JSNode::removeEventListener(ExecState* exec, const ArgList& args)
if (!listener.isObject())
return jsUndefined();
- impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
+ impl()->removeEventListener(ustringToAtomicString(args.at(0).toString(exec)), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
return jsUndefined();
}
@@ -162,6 +223,8 @@ void JSNode::markChildren(MarkStack& markStack)
// case, the root of the detached subtree has a wrapper, so the tree will only
// get marked once. Nodes that aren't outermost need to mark the outermost
// in case it is otherwise unreachable.
+ // FIXME: In the non-common case of root not having a wrapper, this is still an O(n^2) algorithm,
+ // as we will traverse the whole tree as many times as there are nodes with wrappers in it.
if (node != outermostNodeWithWrapper) {
markDOMNodeWrapper(markStack, m_impl->document(), outermostNodeWithWrapper);
return;
@@ -172,7 +235,7 @@ void JSNode::markChildren(MarkStack& markStack)
markDOMNodeWrapper(markStack, m_impl->document(), nodeToMark);
}
-static ALWAYS_INLINE JSValue createWrapper(ExecState* exec, JSDOMGlobalObject* globalObject, Node* node)
+static ALWAYS_INLINE JSValue createWrapperInline(ExecState* exec, JSDOMGlobalObject* globalObject, Node* node)
{
ASSERT(node);
ASSERT(!getCachedDOMNodeWrapper(exec, node->document(), node));
@@ -228,25 +291,18 @@ static ALWAYS_INLINE JSValue createWrapper(ExecState* exec, JSDOMGlobalObject* g
return wrapper;
}
-
-JSValue toJSNewlyCreated(ExecState* exec, JSDOMGlobalObject* globalObject, Node* node)
+
+JSValue createWrapper(ExecState* exec, JSDOMGlobalObject* globalObject, Node* node)
{
- if (!node)
- return jsNull();
-
- return createWrapper(exec, globalObject, node);
+ return createWrapperInline(exec, globalObject, node);
}
-JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, Node* node)
+JSValue toJSNewlyCreated(ExecState* exec, JSDOMGlobalObject* globalObject, Node* node)
{
if (!node)
return jsNull();
-
- JSNode* wrapper = getCachedDOMNodeWrapper(exec, node->document(), node);
- if (wrapper)
- return wrapper;
-
- return createWrapper(exec, globalObject, node);
+
+ return createWrapperInline(exec, globalObject, node);
}
} // namespace WebCore