summaryrefslogtreecommitdiffstats
path: root/webkit/port/bindings
diff options
context:
space:
mode:
authortc@google.com <tc@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-10-01 22:31:35 +0000
committertc@google.com <tc@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-10-01 22:31:35 +0000
commitde56f378336660dcc848763c80267a5e063ae47d (patch)
tree7f551b88923b35bc4022ce6ab3a3f602fb60d91c /webkit/port/bindings
parentdc4f63c80cb90efe594131030aad6776e5945fcc (diff)
downloadchromium_src-de56f378336660dcc848763c80267a5e063ae47d.zip
chromium_src-de56f378336660dcc848763c80267a5e063ae47d.tar.gz
chromium_src-de56f378336660dcc848763c80267a5e063ae47d.tar.bz2
Merge the chrome_webkit_merge_branch back on to trunk. This brings us
up to webkit@36102. git-svn-id: svn://svn.chromium.org/chrome/trunk/src@2778 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/port/bindings')
-rw-r--r--webkit/port/bindings/scripts/CodeGenerator.pm1
-rw-r--r--webkit/port/bindings/scripts/CodeGeneratorV8.pm57
-rw-r--r--webkit/port/bindings/v8/JSNSResolver.cpp99
-rw-r--r--webkit/port/bindings/v8/JSNSResolver.h58
-rw-r--r--webkit/port/bindings/v8/V8SVGPODTypeWrapper.h29
-rw-r--r--webkit/port/bindings/v8/V8XMLHttpRequestCustom.cpp792
-rw-r--r--webkit/port/bindings/v8/np_v8object.cpp4
-rw-r--r--webkit/port/bindings/v8/npruntime_internal.h2
-rw-r--r--webkit/port/bindings/v8/v8_binding.h9
-rw-r--r--webkit/port/bindings/v8/v8_custom.cpp1096
-rw-r--r--webkit/port/bindings/v8/v8_custom.h60
-rw-r--r--webkit/port/bindings/v8/v8_events.cpp5
-rw-r--r--webkit/port/bindings/v8/v8_index.cpp7
-rw-r--r--webkit/port/bindings/v8/v8_index.h7
-rw-r--r--webkit/port/bindings/v8/v8_nodefilter.cpp13
-rw-r--r--webkit/port/bindings/v8/v8_nodefilter.h3
-rw-r--r--webkit/port/bindings/v8/v8_proxy.cpp1091
-rw-r--r--webkit/port/bindings/v8/v8_proxy.h18
18 files changed, 2271 insertions, 1080 deletions
diff --git a/webkit/port/bindings/scripts/CodeGenerator.pm b/webkit/port/bindings/scripts/CodeGenerator.pm
index 7d7fe50..d6900ee 100644
--- a/webkit/port/bindings/scripts/CodeGenerator.pm
+++ b/webkit/port/bindings/scripts/CodeGenerator.pm
@@ -38,6 +38,7 @@ my $verbose = 0;
my %primitiveTypeHash = ("int" => 1, "short" => 1, "long" => 1,
"unsigned int" => 1, "unsigned short" => 1,
"unsigned long" => 1, "float" => 1,
+ "unsigned long long" => 1,
"double" => 1, "boolean" => 1, "void" => 1);
my %podTypeHash = ("SVGLength" => 1, "SVGPoint" => 1, "SVGRect" => 1, "SVGNumber" => 1, "SVGMatrix" => 1, "SVGTransform" => 1);
diff --git a/webkit/port/bindings/scripts/CodeGeneratorV8.pm b/webkit/port/bindings/scripts/CodeGeneratorV8.pm
index f1c235f..7186575 100644
--- a/webkit/port/bindings/scripts/CodeGeneratorV8.pm
+++ b/webkit/port/bindings/scripts/CodeGeneratorV8.pm
@@ -268,7 +268,7 @@ sub GenerateHeader
my $podType = $dataNode->extendedAttributes->{"PODType"};
my $passType = $podType ? "JSSVGPODTypeWrapper<$podType>*" : "$implClassName*";
- push(@headerContent, "#include \"$podType.h\"\n") if $podType and $podType ne "double";
+ push(@headerContent, "#include \"$podType.h\"\n") if $podType and ($podType ne "double" and $podType ne "float" and $podType ne "RGBA32");
push(@headerContent, "#include <v8.h>\n");
push(@headerContent, "#include <wtf/HashMap.h>\n");
@@ -304,7 +304,7 @@ sub GenerateSetDOMException
my $indent = shift;
my $result = "";
- $result .= $indent . "if (ec != 0) {\n";
+ $result .= $indent . "if (ec) {\n";
$result .= $indent . " V8Proxy::SetDOMException(ec);\n";
$result .= $indent . " return v8::Handle<v8::Value>();\n";
$result .= $indent . "}\n";
@@ -530,6 +530,9 @@ END
} else {
$getterString = "imp_instance";
}
+ if ($nativeType eq "String") {
+ $getterString = "ToString($getterString)";
+ }
my $result;
my $wrapper;
@@ -584,7 +587,7 @@ sub GenerateReplaceableAttrSetter
push(@implContentDecls,
" static void ${attrName}AttrSetter(v8::Local<v8::String> name," .
- " v8::Local<v8::Value> value, const v8::AccessorInfo& info) {\n");
+ " v8::Local<v8::Value> value, const v8::AccessorInfo& info)\n{\n");
push(@implContentDecls, " INC_STATS(L\"DOM.$implClassName.$attrName._set\");\n");
@@ -608,7 +611,7 @@ sub GenerateNormalAttrSetter
push(@implContentDecls,
" static void ${attrName}AttrSetter(v8::Local<v8::String> name," .
- " v8::Local<v8::Value> value, const v8::AccessorInfo& info) {\n");
+ " v8::Local<v8::Value> value, const v8::AccessorInfo& info)\n{\n");
push(@implContentDecls, " INC_STATS(L\"DOM.$implClassName.$attrName._set\");\n");
@@ -722,7 +725,7 @@ sub GenerateFunctionCallback
my $name = $function->signature->name;
push(@implContentDecls,
-" static v8::Handle<v8::Value> ${name}Callback(const v8::Arguments& args) {\n" .
+" static v8::Handle<v8::Value> ${name}Callback(const v8::Arguments& args)\n{\n" .
" INC_STATS(L\"DOM.$implClassName.$name\");\n");
my $numParameters = @{$function->parameters};
@@ -871,7 +874,11 @@ sub GenerateImplementation
}
# Generate the accessor.
- GenerateNormalAttrGetter($attribute, $dataNode, $classIndex, $implClassName);
+ if ($attribute->signature->extendedAttributes->{"CustomGetter"}) {
+ $implIncludes{"v8_custom.h"} = 1;
+ } else {
+ GenerateNormalAttrGetter($attribute, $dataNode, $classIndex, $implClassName);
+ }
if ($attribute->signature->extendedAttributes->{"CustomSetter"}) {
$implIncludes{"v8_custom.h"} = 1;
} elsif ($attribute->signature->extendedAttributes->{"Replaceable"}) {
@@ -930,7 +937,7 @@ sub GenerateImplementation
}
}
- my $customAccessor = $attrExt->{"Custom"} || $attrExt->{"CustomSetter"} || "";
+ my $customAccessor = $attrExt->{"Custom"} || $attrExt->{"CustomSetter"} || $attrExt->{"CustomGetter"} || "";
if ($customAccessor eq 1) {
# use the naming convension, interface + (capitalize) attr name
$customAccessor = $interfaceName . WK_ucfirst($attrName);
@@ -967,7 +974,12 @@ sub GenerateImplementation
} elsif ($attrExt->{"CustomSetter"}) {
$getter = "${interfaceName}Internal::${attrName}AttrGetter";
$setter = "V8Custom::v8${customAccessor}AccessorSetter";
-
+
+ # Custom Getter
+ } elsif ($attrExt->{"CustomGetter"}) {
+ $getter = "V8Custom::v8${customAccessor}AccessorGetter";
+ $setter = "${interfaceName}Internal::${attrName}AttrSetter";
+
# Replaceable
} elsif ($attrExt->{"Replaceable"}) {
# Replaceable accessor is put on instance template with ReadOnly attribute.
@@ -1233,9 +1245,15 @@ sub GenerateFunctionCallString()
# This is a bit of a hack... we need to convert parameters to methods on SVG lists
# of POD types which are items in the list to appropriate SVGList<> instances
if ($returnsListItemPodType && $paramType . "List" eq $implClassName) {
- $paramName = "new SVGPODListItem<" . GetNativeType($paramType, 1) . ">($paramName)";
+ $paramName = "SVGPODListItem<" . GetNativeType($paramType, 1) . ">::copy($paramName)";
+ }
+
+ if ($parameter->type eq "NodeFilter") {
+ $functionString .= "$paramName.get()";
+ } else {
+ $functionString .= $paramName;
}
- $functionString .= $paramName;
+
if ($parameter->extendedAttributes->{"Return"}) {
$nodeToReturn = $parameter->name;
}
@@ -1383,6 +1401,7 @@ sub IsRefPtrType
return 1 if $type eq "CSSMediaRule";
return 1 if $type eq "CSSFontFaceRule";
return 1 if $type eq "CSSPageRule";
+ return 1 if $type eq "CSSPrimitiveValue";
return 1 if $type eq "CSSStyleSheet";
return 1 if $type eq "CSSStyleDeclaration";
return 1 if $type eq "CSSValue";
@@ -1397,21 +1416,25 @@ sub IsRefPtrType
return 1 if $type eq "HTMLDocument";
return 1 if $type eq "HTMLElement";
return 1 if $type eq "HTMLOptionsCollection";
+ return 1 if $type eq "ImageData";
return 1 if $type eq "Node";
return 1 if $type eq "NodeList";
return 1 if $type eq "NodeFilter";
return 1 if $type eq "NodeIterator";
+ return 1 if $type eq "NSResolver";
return 1 if $type eq "ProcessingInstruction";
return 1 if $type eq "Range";
return 1 if $type eq "Text";
+ return 1 if $type eq "TextMetrics";
return 1 if $type eq "TreeWalker";
return 1 if $type eq "XPathExpression";
return 1 if $type eq "XPathNSResolver";
return 1 if $type eq "XPathResult";
+ return 1 if $type eq "SVGAngle";
return 1 if $type eq "SVGElementInstance";
return 1 if $type eq "SVGElementInstanceList";
- return 1 if $type eq "SVGPathSeg";
+ return 1 if $type =~ /^SVGPathSeg/;
return 1 if $type =~ /^SVGAnimated/;
@@ -1429,6 +1452,7 @@ sub GetNativeType
return "int" if $type eq "short" or $type eq "unsigned short";
return "int" if $type eq "long" or $type eq "unsigned long";
+ return "unsigned long long" if $type eq "unsigned long long";
return "bool" if $type eq "boolean";
return "String" if $type eq "DOMString";
return "Range::CompareHow" if $type eq "CompareHow";
@@ -1441,12 +1465,16 @@ sub GetNativeType
return "SVGPaint::SVGPaintType" if $type eq "SVGPaintType";
return "DOMTimeStamp" if $type eq "DOMTimeStamp";
return "RGBColor" if $type eq "RGBColor";
+ return "EventTargetNode*" if $type eq "EventTarget" and $isParameter;
return "String" if $type eq "DOMUserData"; # temporary hack, TODO
# temporary hack
$type = GetImplementationClassName($type);
+ # temporary hack
+ return "RefPtr<NodeFilter>" if $type eq "NodeFilter";
+
return "RefPtr<${type}>" if IsRefPtrType($type) and not $isParameter;
# Default, assume native type is a pointer with same type name as idl type
@@ -1469,6 +1497,7 @@ my %typeCanFailConversion = (
"HTMLOptionElement" => 0,
"Node" => 0,
"NodeFilter" => 0,
+ "NSResolver" => 0,
"Range" => 0,
"SQLResultSet" => 0,
"SVGAngle" => 0,
@@ -1740,6 +1769,10 @@ sub NativeToJSValue
AddIncludesForType($type);
# $implIncludes{GetImplementationFileName($type)} = 1 unless AvoidInclusionOfType($type);
+ if ($type eq "CSSStyleDeclaration") {
+ $implIncludes{"CSSMutableStyleDeclaration.h"} = 1;
+ }
+
# special case for non-DOM node interfaces
if (IsDOMNodeType($type)) {
return "V8Proxy::NodeToV8Object($value)";
@@ -1770,7 +1803,7 @@ sub NativeToJSValue
$value = GenerateReadOnlyPodTypeWrapper($type, $value);
}
- return "V8Proxy::ToV8Object(V8ClassIndex::$classIndex, static_cast<Peerable*>($value))";
+ return "V8Proxy::ToV8Object(V8ClassIndex::$classIndex, $value)";
}
}
diff --git a/webkit/port/bindings/v8/JSNSResolver.cpp b/webkit/port/bindings/v8/JSNSResolver.cpp
new file mode 100644
index 0000000..5251a35
--- /dev/null
+++ b/webkit/port/bindings/v8/JSNSResolver.cpp
@@ -0,0 +1,99 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "config.h"
+#include "JSNSResolver.h"
+
+#include "v8_proxy.h"
+#include "v8_binding.h"
+#include "ExceptionContext.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+JSNSResolver::JSNSResolver(v8::Handle<v8::Object> resolver)
+ : m_resolver(resolver)
+{
+}
+
+JSNSResolver::~JSNSResolver()
+{
+}
+
+String JSNSResolver::lookupNamespaceURI(ExceptionContext* exceptionContext,
+ const String& prefix)
+{
+ v8::Handle<v8::Function> lookupNamespaceURIFunc;
+ v8::Handle<v8::String> lookupNamespaceURIName =
+ v8::String::New("lookupNamespaceURI");
+
+ // Check if the resolver has a function property named lookupNamespaceURI.
+ if (m_resolver->Has(lookupNamespaceURIName)) {
+ // In case the property is a getter that throws an error,
+ // see LayoutTests/fast/dom/SelectorAPI/NSResolver-exceptions.xhtml
+ ExceptionCatcher exceptionCatcher(exceptionContext);
+ v8::Handle<v8::Value> lookupNamespaceURI = m_resolver->Get(
+ lookupNamespaceURIName);
+ if (exceptionContext->hadException())
+ return String();
+ if (lookupNamespaceURI->IsFunction()) {
+ lookupNamespaceURIFunc = v8::Handle<v8::Function>::Cast(
+ lookupNamespaceURI);
+ }
+ }
+
+ if (lookupNamespaceURIFunc.IsEmpty() && !m_resolver->IsFunction()) {
+ Frame* frame = ScriptController::retrieveActiveFrame();
+ log_info(frame, "NSResolver does not have a lookupNamespaceURI method.",
+ String());
+ return String();
+ }
+
+ // Catch exceptions from calling the namespace resolver.
+ ExceptionCatcher exceptionCatcher(exceptionContext);
+
+ const int argc = 1;
+ v8::Handle<v8::Value> argv[argc] = { v8String(prefix) };
+ v8::Handle<v8::Function> function = lookupNamespaceURIFunc.IsEmpty()
+ ? v8::Handle<v8::Function>::Cast(m_resolver)
+ : lookupNamespaceURIFunc;
+
+ V8Proxy* proxy = V8Proxy::retrieve();
+ v8::Handle<v8::Value> retval = proxy->CallFunction(function, m_resolver,
+ argc, argv);
+
+ // Eat exceptions from namespace resolver and return an empty string. This
+ // will cause NAMESPACE_ERR.
+ if (exceptionContext->hadException())
+ return String();
+
+ return valueToStringWithNullOrUndefinedCheck(retval);
+}
+
+}
diff --git a/webkit/port/bindings/v8/JSNSResolver.h b/webkit/port/bindings/v8/JSNSResolver.h
new file mode 100644
index 0000000..84bd072
--- /dev/null
+++ b/webkit/port/bindings/v8/JSNSResolver.h
@@ -0,0 +1,58 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+// The wrapper for a JS object that implements NSResolver interface.
+
+#ifndef JSNSResolver_h
+#define JSNSResolver_h
+
+#include <v8.h>
+#include <wtf/RefCounted.h>
+#include "NSResolver.h"
+
+namespace WebCore {
+
+class ExceptionContext;
+class String;
+
+class JSNSResolver : public NSResolver {
+public:
+ JSNSResolver(v8::Handle<v8::Object>);
+ virtual ~JSNSResolver();
+
+ virtual String lookupNamespaceURI(ExceptionContext*, const String&);
+
+private:
+ v8::Handle<v8::Object> m_resolver; // Handle to resolver object.
+};
+
+}
+
+#endif // !defined(JSNSResolver_h)
diff --git a/webkit/port/bindings/v8/V8SVGPODTypeWrapper.h b/webkit/port/bindings/v8/V8SVGPODTypeWrapper.h
index 488ab2b..94ddf5d 100644
--- a/webkit/port/bindings/v8/V8SVGPODTypeWrapper.h
+++ b/webkit/port/bindings/v8/V8SVGPODTypeWrapper.h
@@ -160,11 +160,14 @@ struct PODTypeReadWriteHashInfo {
{ }
// Deleted value
- explicit PODTypeReadWriteHashInfo(bool)
+ explicit PODTypeReadWriteHashInfo(WTF::HashTableDeletedValueType)
: creator(reinterpret_cast<PODTypeCreator*>(-1))
- , getter(0)
- , setter(0)
- { }
+ {
+ }
+ bool isHashTableDeletedValue() const
+ {
+ return creator == reinterpret_cast<PODTypeCreator*>(-1);
+ }
PODTypeReadWriteHashInfo(PODTypeCreator* _creator, GetterMethod _getter, SetterMethod _setter)
: creator(_creator)
@@ -202,19 +205,25 @@ struct PODTypeReadWriteHashInfoHash {
template<typename PODType, typename PODTypeCreator>
struct PODTypeReadWriteHashInfoTraits : WTF::GenericHashTraits<PODTypeReadWriteHashInfo<PODType, PODTypeCreator> > {
+ typedef PODTypeReadWriteHashInfo<PODType, PODTypeCreator> CacheInfo;
+
static const bool emptyValueIsZero = true;
static const bool needsDestruction = false;
- static const PODTypeReadWriteHashInfo<PODType, PODTypeCreator>& deletedValue()
+ static const CacheInfo& emptyValue()
{
- static PODTypeReadWriteHashInfo<PODType, PODTypeCreator> key(true);
+ static CacheInfo key;
return key;
}
- static const PODTypeReadWriteHashInfo<PODType, PODTypeCreator>& emptyValue()
+ static void constructDeletedValue(CacheInfo& slot)
{
- static PODTypeReadWriteHashInfo<PODType, PODTypeCreator> key;
- return key;
+ new (&slot) CacheInfo(WTF::HashTableDeletedValue);
+ }
+
+ static bool isDeletedValue(const CacheInfo& value)
+ {
+ return value.isHashTableDeletedValue();
}
};
@@ -260,7 +269,7 @@ public:
if (it->second != wrapper)
continue;
- // It's guaruanteed that there's just one object we need to take care of.
+ // It's guaranteed that there's just one object we need to take care of.
map.remove(it->first);
break;
}
diff --git a/webkit/port/bindings/v8/V8XMLHttpRequestCustom.cpp b/webkit/port/bindings/v8/V8XMLHttpRequestCustom.cpp
new file mode 100644
index 0000000..0c2cda0
--- /dev/null
+++ b/webkit/port/bindings/v8/V8XMLHttpRequestCustom.cpp
@@ -0,0 +1,792 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "config.h"
+
+#include "v8_binding.h"
+#include "v8_custom.h"
+#include "v8_events.h"
+#include "v8_proxy.h"
+
+#include "V8Document.h"
+#include "V8HTMLDocument.h"
+
+#include "ExceptionCode.h"
+#include "Frame.h"
+#include "XMLHttpRequest.h"
+#include "XMLHttpRequestUpload.h"
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(XMLHttpRequestConstructor) {
+ INC_STATS(L"DOM.XMLHttpRequest.Constructor");
+
+ if (!args.IsConstructCall()) {
+ V8Proxy::ThrowError(V8Proxy::TYPE_ERROR,
+ "DOM object constructor cannot be called as a function.");
+ return v8::Undefined();
+ }
+ // Expect no parameters.
+ // Allocate a XMLHttpRequest object as its internal field.
+ Document* doc = V8Proxy::retrieveFrame()->document();
+ RefPtr<XMLHttpRequest> xhr = XMLHttpRequest::create(doc);
+ V8Proxy::SetDOMWrapper(args.Holder(),
+ V8ClassIndex::ToInt(V8ClassIndex::XMLHTTPREQUEST), xhr.get());
+ // Set object as the peer.
+ V8Proxy::SetJSWrapperForDOMObject(xhr.get(),
+ v8::Persistent<v8::Object>::New(args.Holder()));
+ return args.Holder();
+}
+
+// XMLHttpRequest --------------------------------------------------------------
+
+// Use an array to hold dependents. It works like a ref-counted scheme.
+// A value can be added more than once to the xhr object.
+static void CreateHiddenXHRDependency(v8::Local<v8::Object> xhr,
+ v8::Local<v8::Value> value) {
+ ASSERT(V8Proxy::GetDOMWrapperType(xhr) == V8ClassIndex::XMLHTTPREQUEST ||
+ V8Proxy::GetDOMWrapperType(xhr) == V8ClassIndex::XMLHTTPREQUESTUPLOAD);
+ v8::Local<v8::Value> cache =
+ xhr->GetInternalField(V8Custom::kXMLHttpRequestCacheIndex);
+ if (cache->IsNull() || cache->IsUndefined()) {
+ cache = v8::Array::New();
+ xhr->SetInternalField(V8Custom::kXMLHttpRequestCacheIndex, cache);
+ }
+
+ v8::Local<v8::Array> cache_array = v8::Local<v8::Array>::Cast(cache);
+ cache_array->Set(v8::Integer::New(cache_array->Length()), value);
+}
+
+static void RemoveHiddenXHRDependency(v8::Local<v8::Object> xhr,
+ v8::Local<v8::Value> value) {
+ ASSERT(V8Proxy::GetDOMWrapperType(xhr) == V8ClassIndex::XMLHTTPREQUEST ||
+ V8Proxy::GetDOMWrapperType(xhr) == V8ClassIndex::XMLHTTPREQUESTUPLOAD);
+ v8::Local<v8::Value> cache =
+ xhr->GetInternalField(V8Custom::kXMLHttpRequestCacheIndex);
+ ASSERT(cache->IsArray());
+ v8::Local<v8::Array> cache_array = v8::Local<v8::Array>::Cast(cache);
+ for (int i = cache_array->Length() - 1; i >= 0; i--) {
+ v8::Local<v8::Value> cached = cache_array->Get(v8::Integer::New(i));
+ if (cached->StrictEquals(value)) {
+ cache_array->Delete(i);
+ return;
+ }
+ }
+
+ // We should only get here if we try to remove an event listener that was
+ // never added.
+}
+
+ACCESSOR_GETTER(XMLHttpRequestOnabort) {
+ INC_STATS(L"DOM.XMLHttpRequest.onabort._get");
+ XMLHttpRequest* imp = V8Proxy::ToNativeObject<XMLHttpRequest>(
+ V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ if (imp->onAbortListener()) {
+ V8XHREventListener* listener =
+ static_cast<V8XHREventListener*>(imp->onAbortListener());
+ v8::Local<v8::Object> v8_listener = listener->GetListenerObject();
+ return v8_listener;
+ }
+ return v8::Undefined();
+}
+
+ACCESSOR_SETTER(XMLHttpRequestOnabort) {
+ INC_STATS(L"DOM.XMLHttpRequest.onabort._set");
+ XMLHttpRequest* imp = V8Proxy::ToNativeObject<XMLHttpRequest>(
+ V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ if (value->IsNull()) {
+ if (imp->onAbortListener()) {
+ V8XHREventListener* listener =
+ static_cast<V8XHREventListener*>(imp->onAbortListener());
+ v8::Local<v8::Object> v8_listener = listener->GetListenerObject();
+ RemoveHiddenXHRDependency(info.Holder(), v8_listener);
+ }
+
+ // Clear the listener
+ imp->setOnAbortListener(0);
+ } else {
+ V8Proxy* proxy = V8Proxy::retrieve(imp->document()->frame());
+ if (!proxy)
+ return;
+
+ EventListener* listener = proxy->FindOrCreateXHREventListener(value, false);
+ if (listener) {
+ imp->setOnAbortListener(listener);
+ CreateHiddenXHRDependency(info.Holder(), value);
+ }
+ }
+}
+
+ACCESSOR_GETTER(XMLHttpRequestOnerror) {
+ INC_STATS(L"DOM.XMLHttpRequest.onerror._get");
+ XMLHttpRequest* imp = V8Proxy::ToNativeObject<XMLHttpRequest>(
+ V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ if (imp->onErrorListener()) {
+ V8XHREventListener* listener =
+ static_cast<V8XHREventListener*>(imp->onErrorListener());
+ v8::Local<v8::Object> v8_listener = listener->GetListenerObject();
+ return v8_listener;
+ }
+ return v8::Undefined();
+}
+
+ACCESSOR_SETTER(XMLHttpRequestOnerror) {
+ INC_STATS(L"DOM.XMLHttpRequest.onerror._set");
+ XMLHttpRequest* imp = V8Proxy::ToNativeObject<XMLHttpRequest>(
+ V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ if (value->IsNull()) {
+ if (imp->onErrorListener()) {
+ V8XHREventListener* listener =
+ static_cast<V8XHREventListener*>(imp->onErrorListener());
+ v8::Local<v8::Object> v8_listener = listener->GetListenerObject();
+ RemoveHiddenXHRDependency(info.Holder(), v8_listener);
+ }
+
+ // Clear the listener
+ imp->setOnErrorListener(0);
+ } else {
+ V8Proxy* proxy = V8Proxy::retrieve(imp->document()->frame());
+ if (!proxy)
+ return;
+
+ EventListener* listener = proxy->FindOrCreateXHREventListener(value, false);
+ if (listener) {
+ imp->setOnErrorListener(listener);
+ CreateHiddenXHRDependency(info.Holder(), value);
+ }
+ }
+}
+
+ACCESSOR_GETTER(XMLHttpRequestOnload) {
+ INC_STATS(L"DOM.XMLHttpRequest.onload._get");
+ XMLHttpRequest* imp = V8Proxy::ToNativeObject<XMLHttpRequest>(
+ V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ if (imp->onLoadListener()) {
+ V8XHREventListener* listener =
+ static_cast<V8XHREventListener*>(imp->onLoadListener());
+ v8::Local<v8::Object> v8_listener = listener->GetListenerObject();
+ return v8_listener;
+ }
+ return v8::Undefined();
+}
+
+ACCESSOR_SETTER(XMLHttpRequestOnload)
+{
+ INC_STATS(L"DOM.XMLHttpRequest.onload._set");
+ XMLHttpRequest* imp = V8Proxy::ToNativeObject<XMLHttpRequest>(
+ V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ if (value->IsNull()) {
+ if (imp->onload()) {
+ V8XHREventListener* listener = static_cast<V8XHREventListener*>(imp->onload());
+ v8::Local<v8::Object> v8_listener = listener->GetListenerObject();
+ RemoveHiddenXHRDependency(info.Holder(), v8_listener);
+ }
+
+ imp->setOnload(0);
+
+ } else {
+ V8Proxy* proxy = V8Proxy::retrieve(imp->document()->frame());
+ if (!proxy)
+ return;
+
+ EventListener* listener = proxy->FindOrCreateXHREventListener(value, false);
+ if (listener) {
+ imp->setOnload(listener);
+ CreateHiddenXHRDependency(info.Holder(), value);
+ }
+ }
+}
+
+ACCESSOR_GETTER(XMLHttpRequestOnloadstart) {
+ INC_STATS(L"DOM.XMLHttpRequest.onloadstart._get");
+ XMLHttpRequest* imp = V8Proxy::ToNativeObject<XMLHttpRequest>(
+ V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ if (imp->onLoadStartListener()) {
+ V8XHREventListener* listener =
+ static_cast<V8XHREventListener*>(imp->onLoadStartListener());
+ v8::Local<v8::Object> v8_listener = listener->GetListenerObject();
+ return v8_listener;
+ }
+ return v8::Undefined();
+}
+
+ACCESSOR_SETTER(XMLHttpRequestOnloadstart) {
+ INC_STATS(L"DOM.XMLHttpRequest.onloadstart._set");
+ XMLHttpRequest* imp = V8Proxy::ToNativeObject<XMLHttpRequest>(
+ V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ if (value->IsNull()) {
+ if (imp->onLoadStartListener()) {
+ V8XHREventListener* listener =
+ static_cast<V8XHREventListener*>(imp->onLoadStartListener());
+ v8::Local<v8::Object> v8_listener = listener->GetListenerObject();
+ RemoveHiddenXHRDependency(info.Holder(), v8_listener);
+ }
+
+ // Clear the listener
+ imp->setOnLoadStartListener(0);
+ } else {
+ V8Proxy* proxy = V8Proxy::retrieve(imp->document()->frame());
+ if (!proxy)
+ return;
+
+ EventListener* listener = proxy->FindOrCreateXHREventListener(value, false);
+ if (listener) {
+ imp->setOnLoadStartListener(listener);
+ CreateHiddenXHRDependency(info.Holder(), value);
+ }
+ }
+}
+
+ACCESSOR_GETTER(XMLHttpRequestOnprogress) {
+ INC_STATS(L"DOM.XMLHttpRequest.onprogress._get");
+ XMLHttpRequest* imp = V8Proxy::ToNativeObject<XMLHttpRequest>(
+ V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ if (imp->onProgressListener()) {
+ V8XHREventListener* listener =
+ static_cast<V8XHREventListener*>(imp->onProgressListener());
+ v8::Local<v8::Object> v8_listener = listener->GetListenerObject();
+ return v8_listener;
+ }
+ return v8::Undefined();
+}
+
+ACCESSOR_SETTER(XMLHttpRequestOnprogress) {
+ INC_STATS(L"DOM.XMLHttpRequest.onprogress._set");
+ XMLHttpRequest* imp = V8Proxy::ToNativeObject<XMLHttpRequest>(
+ V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ if (value->IsNull()) {
+ if (imp->onProgressListener()) {
+ V8XHREventListener* listener =
+ static_cast<V8XHREventListener*>(imp->onProgressListener());
+ v8::Local<v8::Object> v8_listener = listener->GetListenerObject();
+ RemoveHiddenXHRDependency(info.Holder(), v8_listener);
+ }
+
+ // Clear the listener
+ imp->setOnProgressListener(0);
+ } else {
+ V8Proxy* proxy = V8Proxy::retrieve(imp->document()->frame());
+ if (!proxy)
+ return;
+
+ EventListener* listener = proxy->FindOrCreateXHREventListener(value, false);
+ if (listener) {
+ imp->setOnProgressListener(listener);
+ CreateHiddenXHRDependency(info.Holder(), value);
+ }
+ }
+}
+
+ACCESSOR_GETTER(XMLHttpRequestOnreadystatechange) {
+ INC_STATS(L"DOM.XMLHttpRequest.onreadystatechange._get");
+ XMLHttpRequest* imp = V8Proxy::ToNativeObject<XMLHttpRequest>(
+ V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ if (imp->onReadyStateChangeListener()) {
+ V8XHREventListener* listener =
+ static_cast<V8XHREventListener*>(imp->onReadyStateChangeListener());
+ v8::Local<v8::Object> v8_listener = listener->GetListenerObject();
+ return v8_listener;
+ }
+ return v8::Undefined();
+}
+
+ACCESSOR_SETTER(XMLHttpRequestOnreadystatechange)
+{
+ INC_STATS(L"DOM.XMLHttpRequest.onreadystatechange._set");
+ XMLHttpRequest* imp = V8Proxy::ToNativeObject<XMLHttpRequest>(
+ V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ if (value->IsNull()) {
+ if (imp->onreadystatechange()) {
+ V8XHREventListener* listener =
+ static_cast<V8XHREventListener*>(imp->onreadystatechange());
+ v8::Local<v8::Object> v8_listener = listener->GetListenerObject();
+ RemoveHiddenXHRDependency(info.Holder(), v8_listener);
+ }
+
+ // Clear the listener
+ imp->setOnreadystatechange(0);
+ } else {
+ V8Proxy* proxy = V8Proxy::retrieve(imp->document()->frame());
+ if (!proxy)
+ return;
+
+ EventListener* listener = proxy->FindOrCreateXHREventListener(value, false);
+ if (listener) {
+ imp->setOnreadystatechange(listener);
+ CreateHiddenXHRDependency(info.Holder(), value);
+ }
+ }
+}
+
+CALLBACK_FUNC_DECL(XMLHttpRequestAddEventListener)
+{
+ INC_STATS(L"DOM.XMLHttpRequest.addEventListener()");
+ XMLHttpRequest* imp = V8Proxy::ToNativeObject<XMLHttpRequest>(
+ V8ClassIndex::XMLHTTPREQUEST, args.Holder());
+
+ V8Proxy* proxy = V8Proxy::retrieve(imp->document()->frame());
+ if (!proxy)
+ return v8::Undefined();
+
+ EventListener* listener = proxy->FindOrCreateXHREventListener(args[1], false);
+ if (listener) {
+ String type = ToWebCoreString(args[0]);
+ bool useCapture = args[2]->BooleanValue();
+ imp->addEventListener(type, listener, useCapture);
+
+ CreateHiddenXHRDependency(args.Holder(), args[1]);
+ }
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(XMLHttpRequestRemoveEventListener) {
+ INC_STATS(L"DOM.XMLHttpRequest.removeEventListener()");
+ XMLHttpRequest* imp = V8Proxy::ToNativeObject<XMLHttpRequest>(
+ V8ClassIndex::XMLHTTPREQUEST, args.Holder());
+
+ V8Proxy* proxy = V8Proxy::retrieve(imp->document()->frame());
+ if (!proxy)
+ return v8::Undefined(); // probably leaked
+
+ EventListener* listener =
+ proxy->FindXHREventListener(args[1], false);
+
+ if (listener) {
+ String type = ToWebCoreString(args[0]);
+ bool useCapture = args[2]->BooleanValue();
+ imp->removeEventListener(type, listener, useCapture);
+
+ RemoveHiddenXHRDependency(args.Holder(), args[1]);
+ }
+
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(XMLHttpRequestOpen)
+{
+ INC_STATS(L"DOM.XMLHttpRequest.open()");
+ // Four cases:
+ // open(method, url)
+ // open(method, url, async)
+ // open(method, url, async, user)
+ // open(method, url, async, user, passwd)
+
+ if (args.Length() < 2) {
+ V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "Not enough arguments");
+ return v8::Undefined();
+ }
+
+ // get the implementation
+ XMLHttpRequest* xhr = V8Proxy::ToNativeObject<XMLHttpRequest>(
+ V8ClassIndex::XMLHTTPREQUEST, args.Holder());
+
+ // retrieve parameters
+ String method = ToWebCoreString(args[0]);
+ String urlstring = ToWebCoreString(args[1]);
+ V8Proxy* proxy = V8Proxy::retrieve();
+ KURL url = proxy->frame()->document()->completeURL(urlstring);
+
+ bool async = (args.Length() < 3) ? true : args[2]->BooleanValue();
+
+ ExceptionCode ec = 0;
+ String user, passwd;
+ if (args.Length() >= 4 && !args[3]->IsUndefined()) {
+ user = valueToStringWithNullCheck(args[3]);
+
+ if (args.Length() >= 5 && !args[4]->IsUndefined()) {
+ passwd = valueToStringWithNullCheck(args[4]);
+ xhr->open(method, url, async, user, passwd, ec);
+ } else
+ xhr->open(method, url, async, user, ec);
+ } else
+ xhr->open(method, url, async, ec);
+
+ if (ec != 0) {
+ V8Proxy::SetDOMException(ec);
+ return v8::Handle<v8::Value>();
+ }
+
+ return v8::Undefined();
+}
+
+static bool IsDocumentType(v8::Handle<v8::Value> value)
+{
+ // TODO(fqian): add other document types.
+ return V8Document::HasInstance(value) || V8HTMLDocument::HasInstance(value);
+}
+
+CALLBACK_FUNC_DECL(XMLHttpRequestSend)
+{
+ INC_STATS(L"DOM.XMLHttpRequest.send()");
+ XMLHttpRequest* xhr = V8Proxy::ToNativeObject<XMLHttpRequest>(
+ V8ClassIndex::XMLHTTPREQUEST, args.Holder());
+
+ ExceptionCode ec = 0;
+ if (args.Length() < 1)
+ xhr->send(ec);
+ else {
+ v8::Handle<v8::Value> arg = args[0];
+ // TODO(eseidel): upstream handles "File" objects too
+ if (IsDocumentType(arg)) {
+ v8::Handle<v8::Object> obj = v8::Handle<v8::Object>::Cast(arg);
+ Document* doc = V8Proxy::DOMWrapperToNode<Document>(obj);
+ ASSERT(doc);
+ xhr->send(doc, ec);
+ } else
+ xhr->send(valueToStringWithNullCheck(arg), ec);
+ }
+
+ if (ec) {
+ V8Proxy::SetDOMException(ec);
+ return v8::Handle<v8::Value>();
+ }
+
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(XMLHttpRequestSetRequestHeader) {
+ INC_STATS(L"DOM.XMLHttpRequest.setRequestHeader()");
+ if (args.Length() < 2) {
+ V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "Not enough arguments");
+ return v8::Undefined();
+ }
+
+ XMLHttpRequest* imp = V8Proxy::ToNativeObject<XMLHttpRequest>(
+ V8ClassIndex::XMLHTTPREQUEST, args.Holder());
+ ExceptionCode ec = 0;
+ String header = ToWebCoreString(args[0]);
+ String value = ToWebCoreString(args[1]);
+ imp->setRequestHeader(header, value, ec);
+ if (ec != 0) {
+ V8Proxy::SetDOMException(ec);
+ return v8::Handle<v8::Value>();
+ }
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(XMLHttpRequestGetResponseHeader) {
+ INC_STATS(L"DOM.XMLHttpRequest.getResponseHeader()");
+ if (args.Length() < 1) {
+ V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "Not enough arguments");
+ return v8::Undefined();
+ }
+
+ XMLHttpRequest* imp = V8Proxy::ToNativeObject<XMLHttpRequest>(
+ V8ClassIndex::XMLHTTPREQUEST, args.Holder());
+ ExceptionCode ec = 0;
+ String header = ToWebCoreString(args[0]);
+ String result = imp->getResponseHeader(header, ec);
+ if (ec != 0) {
+ V8Proxy::SetDOMException(ec);
+ return v8::Handle<v8::Value>();
+ }
+ return v8StringOrNull(result);
+}
+
+CALLBACK_FUNC_DECL(XMLHttpRequestOverrideMimeType)
+{
+ INC_STATS(L"DOM.XMLHttpRequest.overrideMimeType()");
+ if (args.Length() < 1) {
+ V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "Not enough arguments");
+ return v8::Undefined();
+ }
+
+ XMLHttpRequest* imp = V8Proxy::ToNativeObject<XMLHttpRequest>(
+ V8ClassIndex::XMLHTTPREQUEST, args.Holder());
+ String value = ToWebCoreString(args[0]);
+ imp->overrideMimeType(value);
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(XMLHttpRequestDispatchEvent)
+{
+ INC_STATS(L"DOM.XMLHttpRequest.dispatchEvent()");
+ return v8::Undefined();
+}
+
+
+// XMLHttpRequestUpload --------------------------------------------------------
+
+ACCESSOR_GETTER(XMLHttpRequestUploadOnabort) {
+ INC_STATS(L"DOM.XMLHttpRequestUpload.onabort._get");
+ XMLHttpRequestUpload* imp = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(
+ V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
+ if (imp->onAbortListener()) {
+ V8XHREventListener* listener =
+ static_cast<V8XHREventListener*>(imp->onAbortListener());
+ v8::Local<v8::Object> v8_listener = listener->GetListenerObject();
+ return v8_listener;
+ }
+ return v8::Undefined();
+}
+
+ACCESSOR_SETTER(XMLHttpRequestUploadOnabort) {
+ INC_STATS(L"DOM.XMLHttpRequestUpload.onabort._set");
+ XMLHttpRequestUpload* imp = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(
+ V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
+ if (value->IsNull()) {
+ if (imp->onAbortListener()) {
+ V8XHREventListener* listener =
+ static_cast<V8XHREventListener*>(imp->onAbortListener());
+ v8::Local<v8::Object> v8_listener = listener->GetListenerObject();
+ RemoveHiddenXHRDependency(info.Holder(), v8_listener);
+ }
+
+ // Clear the listener
+ imp->setOnAbortListener(0);
+ } else {
+ XMLHttpRequest* xmlhttprequest = imp->associatedXMLHttpRequest();
+ V8Proxy* proxy = V8Proxy::retrieve(xmlhttprequest->document()->frame());
+ if (!proxy)
+ return;
+
+ EventListener* listener = proxy->FindOrCreateXHREventListener(value, false);
+ if (listener) {
+ imp->setOnAbortListener(listener);
+ CreateHiddenXHRDependency(info.Holder(), value);
+ }
+ }
+}
+
+ACCESSOR_GETTER(XMLHttpRequestUploadOnerror) {
+ INC_STATS(L"DOM.XMLHttpRequestUpload.onerror._get");
+ XMLHttpRequestUpload* imp = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(
+ V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
+ if (imp->onErrorListener()) {
+ V8XHREventListener* listener =
+ static_cast<V8XHREventListener*>(imp->onErrorListener());
+ v8::Local<v8::Object> v8_listener = listener->GetListenerObject();
+ return v8_listener;
+ }
+ return v8::Undefined();
+}
+
+ACCESSOR_SETTER(XMLHttpRequestUploadOnerror) {
+ INC_STATS(L"DOM.XMLHttpRequestUpload.onerror._set");
+ XMLHttpRequestUpload* imp = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(
+ V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
+ if (value->IsNull()) {
+ if (imp->onErrorListener()) {
+ V8XHREventListener* listener =
+ static_cast<V8XHREventListener*>(imp->onErrorListener());
+ v8::Local<v8::Object> v8_listener = listener->GetListenerObject();
+ RemoveHiddenXHRDependency(info.Holder(), v8_listener);
+ }
+
+ // Clear the listener
+ imp->setOnErrorListener(0);
+ } else {
+ XMLHttpRequest* xmlhttprequest = imp->associatedXMLHttpRequest();
+ V8Proxy* proxy = V8Proxy::retrieve(xmlhttprequest->document()->frame());
+ if (!proxy)
+ return;
+
+ EventListener* listener = proxy->FindOrCreateXHREventListener(value, false);
+ if (listener) {
+ imp->setOnErrorListener(listener);
+ CreateHiddenXHRDependency(info.Holder(), value);
+ }
+ }
+}
+
+ACCESSOR_GETTER(XMLHttpRequestUploadOnload) {
+ INC_STATS(L"DOM.XMLHttpRequestUpload.onload._get");
+ XMLHttpRequestUpload* imp = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(
+ V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
+ if (imp->onLoadListener()) {
+ V8XHREventListener* listener =
+ static_cast<V8XHREventListener*>(imp->onLoadListener());
+ v8::Local<v8::Object> v8_listener = listener->GetListenerObject();
+ return v8_listener;
+ }
+ return v8::Undefined();
+}
+
+ACCESSOR_SETTER(XMLHttpRequestUploadOnload) {
+ INC_STATS(L"DOM.XMLHttpRequestUpload.onload._set");
+ XMLHttpRequestUpload* imp = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(
+ V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
+ if (value->IsNull()) {
+ if (imp->onLoadListener()) {
+ V8XHREventListener* listener =
+ static_cast<V8XHREventListener*>(imp->onLoadListener());
+ v8::Local<v8::Object> v8_listener = listener->GetListenerObject();
+ RemoveHiddenXHRDependency(info.Holder(), v8_listener);
+ }
+
+ // Clear the listener
+ imp->setOnLoadListener(0);
+ } else {
+ XMLHttpRequest* xmlhttprequest = imp->associatedXMLHttpRequest();
+ V8Proxy* proxy = V8Proxy::retrieve(xmlhttprequest->document()->frame());
+ if (!proxy)
+ return;
+
+ EventListener* listener = proxy->FindOrCreateXHREventListener(value, false);
+ if (listener) {
+ imp->setOnLoadListener(listener);
+ CreateHiddenXHRDependency(info.Holder(), value);
+ }
+ }
+}
+
+ACCESSOR_GETTER(XMLHttpRequestUploadOnloadstart) {
+ INC_STATS(L"DOM.XMLHttpRequestUpload.onloadstart._get");
+ XMLHttpRequestUpload* imp = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(
+ V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
+ if (imp->onLoadStartListener()) {
+ V8XHREventListener* listener =
+ static_cast<V8XHREventListener*>(imp->onLoadStartListener());
+ v8::Local<v8::Object> v8_listener = listener->GetListenerObject();
+ return v8_listener;
+ }
+ return v8::Undefined();
+}
+
+ACCESSOR_SETTER(XMLHttpRequestUploadOnloadstart) {
+ INC_STATS(L"DOM.XMLHttpRequestUpload.onloadstart._set");
+ XMLHttpRequestUpload* imp = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(
+ V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
+ if (value->IsNull()) {
+ if (imp->onLoadStartListener()) {
+ V8XHREventListener* listener =
+ static_cast<V8XHREventListener*>(imp->onLoadStartListener());
+ v8::Local<v8::Object> v8_listener = listener->GetListenerObject();
+ RemoveHiddenXHRDependency(info.Holder(), v8_listener);
+ }
+
+ // Clear the listener
+ imp->setOnLoadStartListener(0);
+ } else {
+ XMLHttpRequest* xmlhttprequest = imp->associatedXMLHttpRequest();
+ V8Proxy* proxy = V8Proxy::retrieve(xmlhttprequest->document()->frame());
+ if (!proxy)
+ return;
+
+ EventListener* listener = proxy->FindOrCreateXHREventListener(value, false);
+ if (listener) {
+ imp->setOnLoadStartListener(listener);
+ CreateHiddenXHRDependency(info.Holder(), value);
+ }
+ }
+}
+
+ACCESSOR_GETTER(XMLHttpRequestUploadOnprogress) {
+ INC_STATS(L"DOM.XMLHttpRequestUpload.onprogress._get");
+ XMLHttpRequestUpload* imp = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(
+ V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
+ if (imp->onProgressListener()) {
+ V8XHREventListener* listener =
+ static_cast<V8XHREventListener*>(imp->onProgressListener());
+ v8::Local<v8::Object> v8_listener = listener->GetListenerObject();
+ return v8_listener;
+ }
+ return v8::Undefined();
+}
+
+ACCESSOR_SETTER(XMLHttpRequestUploadOnprogress) {
+ INC_STATS(L"DOM.XMLHttpRequestUpload.onprogress._set");
+ XMLHttpRequestUpload* imp = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(
+ V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
+ if (value->IsNull()) {
+ if (imp->onProgressListener()) {
+ V8XHREventListener* listener =
+ static_cast<V8XHREventListener*>(imp->onProgressListener());
+ v8::Local<v8::Object> v8_listener = listener->GetListenerObject();
+ RemoveHiddenXHRDependency(info.Holder(), v8_listener);
+ }
+
+ // Clear the listener
+ imp->setOnProgressListener(0);
+ } else {
+ XMLHttpRequest* xmlhttprequest = imp->associatedXMLHttpRequest();
+ V8Proxy* proxy = V8Proxy::retrieve(xmlhttprequest->document()->frame());
+ if (!proxy)
+ return;
+
+ EventListener* listener = proxy->FindOrCreateXHREventListener(value, false);
+ if (listener) {
+ imp->setOnProgressListener(listener);
+ CreateHiddenXHRDependency(info.Holder(), value);
+ }
+ }
+}
+
+CALLBACK_FUNC_DECL(XMLHttpRequestUploadAddEventListener) {
+ INC_STATS(L"DOM.XMLHttpRequestUpload.addEventListener()");
+ XMLHttpRequestUpload* imp = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(
+ V8ClassIndex::XMLHTTPREQUESTUPLOAD, args.Holder());
+
+ XMLHttpRequest* xmlhttprequest = imp->associatedXMLHttpRequest();
+ V8Proxy* proxy = V8Proxy::retrieve(xmlhttprequest->document()->frame());
+ if (!proxy)
+ return v8::Undefined();
+
+ EventListener* listener = proxy->FindOrCreateXHREventListener(args[1], false);
+ if (listener) {
+ String type = ToWebCoreString(args[0]);
+ bool useCapture = args[2]->BooleanValue();
+ imp->addEventListener(type, listener, useCapture);
+
+ CreateHiddenXHRDependency(args.Holder(), args[1]);
+ }
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(XMLHttpRequestUploadRemoveEventListener) {
+ INC_STATS(L"DOM.XMLHttpRequestUpload.removeEventListener()");
+ XMLHttpRequestUpload* imp = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(
+ V8ClassIndex::XMLHTTPREQUESTUPLOAD, args.Holder());
+
+ XMLHttpRequest* xmlhttprequest = imp->associatedXMLHttpRequest();
+ V8Proxy* proxy = V8Proxy::retrieve(xmlhttprequest->document()->frame());
+ if (!proxy)
+ return v8::Undefined(); // probably leaked
+
+ EventListener* listener =
+ proxy->FindXHREventListener(args[1], false);
+
+ if (listener) {
+ String type = ToWebCoreString(args[0]);
+ bool useCapture = args[2]->BooleanValue();
+ imp->removeEventListener(type, listener, useCapture);
+
+ RemoveHiddenXHRDependency(args.Holder(), args[1]);
+ }
+
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(XMLHttpRequestUploadDispatchEvent) {
+ INC_STATS(L"DOM.XMLHttpRequestUpload.dispatchEvent()");
+ V8Proxy::SetDOMException(NOT_SUPPORTED_ERR);
+ return v8::Undefined();
+}
+
+} // namespace WebCore
diff --git a/webkit/port/bindings/v8/np_v8object.cpp b/webkit/port/bindings/v8/np_v8object.cpp
index 3b3be3a..4387180 100644
--- a/webkit/port/bindings/v8/np_v8object.cpp
+++ b/webkit/port/bindings/v8/np_v8object.cpp
@@ -36,10 +36,10 @@
#include "bindings/npruntime.h"
#include "npruntime_priv.h"
#include "PlatformString.h"
+#include "ScriptController.h"
#include "v8_helpers.h"
#include "v8_np_utils.h"
#include "v8_proxy.h"
-#include "V8Bridge.h"
#include "DOMWindow.h"
using WebCore::V8ClassIndex;
@@ -326,7 +326,7 @@ bool NPN_SetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName,
NPIdentifierToV8Identifier(propertyName, identifier);
obj->Set(v8::String::New(identifier.c_str()),
ConvertNPVariantToV8Object(value,
- object->root_object->frame()->windowScriptNPObject()));
+ object->root_object->frame()->script()->windowScriptNPObject()));
return true;
}
diff --git a/webkit/port/bindings/v8/npruntime_internal.h b/webkit/port/bindings/v8/npruntime_internal.h
index f5357cd..75bf2b0 100644
--- a/webkit/port/bindings/v8/npruntime_internal.h
+++ b/webkit/port/bindings/v8/npruntime_internal.h
@@ -25,7 +25,9 @@
* include this file instead of the actual npapi.h or npruntime.h
*/
+#include "npapi.h"
#include "npruntime.h"
+#include "npfunctions.h"
#ifdef XP_UNIX
#include <X11/Xresource.h>
diff --git a/webkit/port/bindings/v8/v8_binding.h b/webkit/port/bindings/v8/v8_binding.h
index 81d7dde..1239791 100644
--- a/webkit/port/bindings/v8/v8_binding.h
+++ b/webkit/port/bindings/v8/v8_binding.h
@@ -9,6 +9,7 @@
#include "build/build_config.h"
#include <v8.h>
+#include "KURL.h"
#include "PlatformString.h"
#include "MathExtras.h"
#include "StringBuffer.h"
@@ -131,6 +132,14 @@ inline int ToInt32(v8::Handle<v8::Value> value) {
return ToInt32(value, ok);
}
+inline String ToString(const String& string) {
+ return string;
+}
+
+inline String ToString(const KURL& url) {
+ return url.string();
+}
+
// If a WebCore string length is greater than the threshold,
// v8String creates an external string to avoid allocating
// the string in the large object space (which has a high memory overhead).
diff --git a/webkit/port/bindings/v8/v8_custom.cpp b/webkit/port/bindings/v8/v8_custom.cpp
index 604ab14..78a0160 100644
--- a/webkit/port/bindings/v8/v8_custom.cpp
+++ b/webkit/port/bindings/v8/v8_custom.cpp
@@ -1,11 +1,10 @@
/*
- * This file is part of the KDE libraries
* Copyright (C) 2000 Harri Porten (porten@kde.org)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
* Copyright (C) 2004-2006 Apple Computer, Inc.
* Copyright (C) 2006 James G. Speth (speth@end.com)
* Copyright (C) 2006 Samuel Weinig (sam@webkit.org)
- * Copyright 2007 Google Inc. All Rights Reserved.
+ * Copyright 2007, 2008 Google Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -25,6 +24,7 @@
#include "config.h"
#include <Assertions.h>
+#include <wtf/ASCIICType.h>
#include "v8_proxy.h"
#include "v8_events.h"
@@ -43,6 +43,7 @@
#include "V8HTMLImageElement.h"
#include "V8HTMLOptionElement.h"
#include "V8Node.h"
+#include "V8NSResolver.h"
#include "V8XPathNSResolver.h"
#include "V8XPathResult.h"
@@ -50,11 +51,12 @@
#include "CanvasPattern.h"
#include "CanvasStyle.h"
#include "CanvasRenderingContext2D.h"
-
#include "Clipboard.h"
#include "ClipboardEvent.h"
+// TODO(tc): Sort these after the merge lands on trunk.
#include "Base64.h"
+#include "Console.h"
#include "FloatRect.h"
#include "Frame.h"
#include "FrameTree.h"
@@ -72,10 +74,8 @@
#include "EventTargetNode.h"
#include "EventTarget.h"
#include "ExceptionCode.h"
-#include "XMLHttpRequest.h"
#include "XMLSerializer.h"
#include "KURL.h"
-#include "DeprecatedString.h"
#include "HTMLDocument.h"
#include "HTMLNames.h"
#include "HTMLBodyElement.h"
@@ -101,12 +101,12 @@
#include "Settings.h"
#include "StyleSheetList.h"
#include "TreeWalker.h"
+#include "JSNSResolver.h"
#include "WindowFeatures.h"
#include "XPathEvaluator.h"
#include "JSXPathNSResolver.h"
#include "XPathResult.h"
#include "XSLTProcessor.h"
-#include "V8Bridge.h"
#if ENABLE(SVG)
#include "V8SVGPODTypeWrapper.h"
@@ -124,18 +124,6 @@ static const int kPopupTilePixels = 10;
namespace WebCore {
-#define CALLBACK_FUNC_DECL(NAME) \
-v8::Handle<v8::Value> V8Custom::v8##NAME##Callback(const v8::Arguments& args)
-
-#define ACCESSOR_GETTER(NAME) \
-v8::Handle<v8::Value> V8Custom::v8##NAME##AccessorGetter(\
- v8::Local<v8::String> name, const v8::AccessorInfo& info)
-
-#define ACCESSOR_SETTER(NAME) \
-void V8Custom::v8##NAME##AccessorSetter(v8::Local<v8::String> name, \
- v8::Local<v8::Value> value, \
- const v8::AccessorInfo& info)
-
#define NAMED_PROPERTY_GETTER(NAME) \
v8::Handle<v8::Value> V8Custom::v8##NAME##NamedPropertyGetter(\
v8::Local<v8::String> name, const v8::AccessorInfo& info)
@@ -264,27 +252,6 @@ void V8ScheduledAction::execute(DOMWindow* window) {
}
-CALLBACK_FUNC_DECL(XMLHttpRequestConstructor) {
- INC_STATS(L"DOM.XMLHttpRequest.Constructor");
-
- if (!args.IsConstructCall()) {
- V8Proxy::ThrowError(V8Proxy::TYPE_ERROR,
- "DOM object constructor cannot be called as a function.");
- return v8::Undefined();
- }
- // Expect no parameters.
- // Allocate a XMLHttpRequest object as its internal field.
- Document* doc = V8Proxy::retrieveFrame()->document();
- XMLHttpRequest* xhr = new XMLHttpRequest(doc);
- V8Proxy::SetDOMWrapper(args.Holder(),
- V8ClassIndex::ToInt(V8ClassIndex::XMLHTTPREQUEST), xhr);
- // Set object as the peer.
- V8Proxy::SetJSWrapperForDOMObject(xhr,
- v8::Persistent<v8::Object>::New(args.Holder()));
- return args.Holder();
-}
-
-
CALLBACK_FUNC_DECL(DOMParserConstructor) {
INC_STATS(L"DOM.DOMParser.Contructor");
return V8Proxy::ConstructDOMObject<V8ClassIndex::DOMPARSER,
@@ -355,10 +322,12 @@ CALLBACK_FUNC_DECL(XSLTProcessorTransformToDocument) {
V8ClassIndex::XSLTPROCESSOR, args.Holder());
Node* source = V8Proxy::DOMWrapperToNode<Node>(args[0]);
- if (!source) return v8::Undefined();
+ if (!source)
+ return v8::Undefined();
RefPtr<Document> result = imp->transformToDocument(source);
// Return undefined if no result was found.
- if (!result) return v8::Undefined();
+ if (!result)
+ return v8::Undefined();
return V8Proxy::NodeToV8Object(result.get());
}
@@ -404,9 +373,8 @@ CALLBACK_FUNC_DECL(XSLTProcessorGetParameter) {
CALLBACK_FUNC_DECL(XSLTProcessorRemoveParameter) {
INC_STATS(L"DOM.XSLTProcessor.removeParameter");
// Bail out if localName is null or undefined.
- if (args[1]->IsNull() || args[1]->IsUndefined()) {
+ if (args[1]->IsNull() || args[1]->IsUndefined())
return v8::Undefined();
- }
XSLTProcessor* imp = V8Proxy::ToNativeObject<XSLTProcessor>(
V8ClassIndex::XSLTPROCESSOR, args.Holder());
@@ -419,33 +387,30 @@ CALLBACK_FUNC_DECL(XSLTProcessorRemoveParameter) {
// ---- Canvas support ----
-static v8::Handle<v8::Value> CanvasStyleToV8Object(CanvasStyle* style) {
- if (style->gradient()) {
- return V8Proxy::ToV8Object(V8ClassIndex::CANVASGRADIENT,
- static_cast<Peerable*>(style->gradient()));
- }
- if (style->pattern()) {
- return V8Proxy::ToV8Object(V8ClassIndex::CANVASPATTERN,
- static_cast<Peerable*>(style->pattern()));
- }
- return v8String(style->color());
+static v8::Handle<v8::Value> CanvasStyleToV8Object(CanvasStyle* style)
+{
+ if (style->canvasGradient())
+ return V8Proxy::ToV8Object(V8ClassIndex::CANVASGRADIENT, static_cast<Peerable*>(style->canvasGradient()));
+ if (style->canvasPattern())
+ return V8Proxy::ToV8Object(V8ClassIndex::CANVASPATTERN, static_cast<Peerable*>(style->canvasPattern()));
+ return v8String(style->color());
}
-
-static PassRefPtr<CanvasStyle> V8ObjectToCanvasStyle(
- v8::Handle<v8::Value> value) {
- if (value->IsString()) return new CanvasStyle(ToWebCoreString(value));
+static PassRefPtr<CanvasStyle> V8ObjectToCanvasStyle(v8::Handle<v8::Value> value)
+{
+ if (value->IsString())
+ return CanvasStyle::create(ToWebCoreString(value));
if (V8CanvasGradient::HasInstance(value)) {
CanvasGradient* gradient =
V8Proxy::DOMWrapperToNative<CanvasGradient>(value);
- return new CanvasStyle(gradient);
+ return CanvasStyle::create(gradient);
}
if (V8CanvasPattern::HasInstance(value)) {
CanvasPattern* pattern =
V8Proxy::DOMWrapperToNative<CanvasPattern>(value);
- return new CanvasStyle(pattern);
+ return CanvasStyle::create(pattern);
}
return 0;
@@ -866,16 +831,19 @@ CALLBACK_FUNC_DECL(DOMWindowPostMessage) {
DOMWindow* source = V8Proxy::retrieveActiveFrame()->domWindow();
ASSERT(source->frame());
- String domain = source->frame()->loader()->url().host();
String uri = source->frame()->loader()->url().string();
v8::TryCatch try_catch;
String message = ToWebCoreString(args[0]);
+ String domain = ToWebCoreString(args[1]);
if (try_catch.HasCaught()) return v8::Undefined();
- window->postMessage(message, domain, uri, source);
+ ExceptionCode ec;
+ window->postMessage(message, domain, source, ec);
+ if (ec)
+ V8Proxy::SetDOMException(ec);
return v8::Undefined();
}
@@ -892,7 +860,7 @@ static bool allowPopUp() {
Frame* frame = V8Proxy::retrieveActiveFrame();
ASSERT(frame);
- if (frame->scriptBridge()->wasRunByUserGesture()) return true;
+ if (frame->script()->processingUserGesture()) return true;
Settings* settings = frame->settings();
return settings && settings->JavaScriptCanOpenWindowsAutomatically();
}
@@ -901,7 +869,8 @@ static HashMap<String, String> parseModalDialogFeatures(
const String& features_arg) {
HashMap<String, String> map;
- Vector<String> features = features_arg.split(';');
+ Vector<String> features;
+ features_arg.split(';', features);
Vector<String>::const_iterator end = features.end();
for (Vector<String>::const_iterator it = features.begin(); it != end; ++it) {
String s = *it;
@@ -956,9 +925,8 @@ static Frame* createWindow(Frame* opener_frame,
// "_self" or "_parent".
Frame* new_frame = active_frame->loader()->createWindow(
opener_frame->loader(), frame_request, window_features, created);
- if (!new_frame) {
+ if (!new_frame)
return 0;
- }
new_frame->loader()->setOpener(opener_frame);
new_frame->loader()->setOpenedByDOM();
@@ -973,23 +941,20 @@ static Frame* createWindow(Frame* opener_frame,
}
if (!parseURL(url).startsWith("javascript:", false) ||
- JSBridge::isSafeScript(new_frame)) {
- String completed_url =
- url.isEmpty() ? url : active_frame->document()->completeURL(url);
- bool user_gesture = active_frame->scriptBridge()->wasRunByUserGesture();
+ ScriptController::isSafeScript(new_frame)) {
+ KURL completed_url =
+ url.isEmpty() ? KURL("") : active_frame->document()->completeURL(url);
+ bool user_gesture = active_frame->script()->processingUserGesture();
if (created) {
new_frame->loader()->changeLocation(
- KURL(completed_url.deprecatedString()),
+ completed_url,
active_frame->loader()->outgoingReferrer(),
false,
user_gesture);
- if (Document* old_doc = opener_frame->document()) {
- new_frame->document()->setBaseURL(old_doc->baseURL());
- }
} else if (!url.isEmpty()) {
new_frame->loader()->scheduleLocationChange(
- completed_url,
+ completed_url.string(),
active_frame->loader()->outgoingReferrer(),
false,
user_gesture);
@@ -1149,8 +1114,8 @@ CALLBACK_FUNC_DECL(DOMWindowOpen) {
if (!completed_url.isEmpty() &&
(!parseURL(url_string).startsWith("javascript:", false) ||
- JSBridge::isSafeScript(frame))) {
- bool user_gesture = active_frame->scriptBridge()->wasRunByUserGesture();
+ ScriptController::isSafeScript(frame))) {
+ bool user_gesture = active_frame->script()->processingUserGesture();
frame->loader()->scheduleLocationChange(
completed_url,
active_frame->loader()->outgoingReferrer(),
@@ -1373,7 +1338,8 @@ NAMED_PROPERTY_DELETER(HTMLDocument) {
}
-NAMED_PROPERTY_SETTER(HTMLDocument) {
+NAMED_PROPERTY_SETTER(HTMLDocument)
+{
INC_STATS(L"DOM.HTMLDocument.NamedPropertySetter");
// Only handle document.all. We insert the value into the shadow
// internal field from which the getter will retrieve it.
@@ -1387,50 +1353,45 @@ NAMED_PROPERTY_SETTER(HTMLDocument) {
}
-NAMED_PROPERTY_GETTER(HTMLDocument) {
- INC_STATS(L"DOM.HTMLDocument.NamedPropertyGetter");
- String key = ToWebCoreString(name);
+NAMED_PROPERTY_GETTER(HTMLDocument)
+{
+ INC_STATS(L"DOM.HTMLDocument.NamedPropertyGetter");
+ AtomicString key = ToWebCoreString(name);
- // Special case for document.all. If the value in the shadow
- // internal field is not the marker object, then document.all has
- // been temporarily shadowed and we return the value.
- if (key == "all") {
- ASSERT(info.Holder()->InternalFieldCount() ==
- kHTMLDocumentInternalFieldCount);
- v8::Local<v8::Value> marker =
- info.Holder()->GetInternalField(kHTMLDocumentMarkerIndex);
- v8::Local<v8::Value> value =
- info.Holder()->GetInternalField(kHTMLDocumentShadowIndex);
- if (marker != value) {
- return value;
+ // Special case for document.all. If the value in the shadow
+ // internal field is not the marker object, then document.all has
+ // been temporarily shadowed and we return the value.
+ if (key == "all") {
+ ASSERT(info.Holder()->InternalFieldCount() == kHTMLDocumentInternalFieldCount);
+ v8::Local<v8::Value> marker = info.Holder()->GetInternalField(kHTMLDocumentMarkerIndex);
+ v8::Local<v8::Value> value = info.Holder()->GetInternalField(kHTMLDocumentShadowIndex);
+ if (marker != value)
+ return value;
}
- }
HTMLDocument* imp = V8Proxy::DOMWrapperToNode<HTMLDocument>(info.Holder());
- // Fast case for named elements that are not there.
- if (!imp->hasNamedItem(key) && !imp->hasDocExtraNamedItem(key)) {
- return v8::Handle<v8::Value>();
- }
-
+ // Fast case for named elements that are not there.
+ if (!imp->hasNamedItem(key.impl()) && !imp->hasExtraNamedItem(key.impl()))
+ return v8::Handle<v8::Value>();
- RefPtr<HTMLCollection> items = imp->documentNamedItems(key);
- if (items->length() == 0) return v8::Handle<v8::Value>();
- if (items->length() == 1) {
- Node* node = items->firstItem();
- Frame* frame = 0;
- if (node->hasTagName(HTMLNames::iframeTag) &&
- (frame = static_cast<HTMLIFrameElement*>(node)->contentFrame())) {
- return V8Proxy::ToV8Object(V8ClassIndex::DOMWINDOW, frame->domWindow());
- }
+ RefPtr<HTMLCollection> items = imp->documentNamedItems(key);
+ if (items->length() == 0)
+ return v8::Handle<v8::Value>();
+ if (items->length() == 1) {
+ Node* node = items->firstItem();
+ Frame* frame = 0;
+ if (node->hasTagName(HTMLNames::iframeTag) && (frame = static_cast<HTMLIFrameElement*>(node)->contentFrame()))
+ return V8Proxy::ToV8Object(V8ClassIndex::DOMWINDOW, frame->domWindow());
return V8Proxy::NodeToV8Object(node);
- }
- return V8Proxy::ToV8Object(V8ClassIndex::HTMLCOLLECTION,
+ }
+ return V8Proxy::ToV8Object(V8ClassIndex::HTMLCOLLECTION,
static_cast<Peerable*>(items.get()));
}
-NAMED_PROPERTY_GETTER(HTMLFrameSetElement) {
+NAMED_PROPERTY_GETTER(HTMLFrameSetElement)
+{
INC_STATS(L"DOM.HTMLFrameSetElement.NamedPropertyGetter");
HTMLFrameSetElement* imp =
V8Proxy::DOMWrapperToNode<HTMLFrameSetElement>(info.Holder());
@@ -1440,10 +1401,8 @@ NAMED_PROPERTY_GETTER(HTMLFrameSetElement) {
Document* doc = static_cast<HTMLFrameElement*>(frame)->contentDocument();
if (doc) {
Frame* content_frame = doc->frame();
- if (content_frame) {
- return V8Proxy::ToV8Object(V8ClassIndex::DOMWINDOW,
- content_frame->domWindow());
- }
+ if (content_frame)
+ return V8Proxy::ToV8Object(V8ClassIndex::DOMWINDOW, content_frame->domWindow());
}
return v8::Undefined();
}
@@ -1598,6 +1557,32 @@ INDEXED_PROPERTY_SETTER(HTMLSelectElementCollection) {
return OptionsCollectionSetter(index, value, select);
}
+// Check for a CSS prefix.
+// Passed prefix is all lowercase.
+// First character of the prefix within the property name may be upper or lowercase.
+// Other characters in the prefix within the property name must be lowercase.
+// The prefix within the property name must be followed by a capital letter.
+static bool hasCSSPropertyNamePrefix(const String& propertyName, const char* prefix)
+{
+#ifndef NDEBUG
+ ASSERT(*prefix);
+ for (const char* p = prefix; *p; ++p)
+ ASSERT(WTF::isASCIILower(*p));
+ ASSERT(propertyName.length());
+#endif
+
+ if (WTF::toASCIILower(propertyName[0]) != prefix[0])
+ return false;
+
+ unsigned length = propertyName.length();
+ for (unsigned i = 1; i < length; ++i) {
+ if (!prefix[i])
+ return WTF::isASCIIUpper(propertyName[i]);
+ if (propertyName[i] != prefix[i])
+ return false;
+ }
+ return false;
+}
// When getting properties on CSSStyleDeclarations, the name used from
// Javascript and the actual name of the property are not the same, so
@@ -1610,48 +1595,60 @@ INDEXED_PROPERTY_SETTER(HTMLSelectElementCollection) {
// Also, certain prefixes such as 'pos', 'css-' and 'pixel-' are stripped
// and the pixel_or_pos_prefix out parameter is used to indicate whether or
// not the property name was prefixed with 'pos-' or 'pixel-'.
-static String CSSPropertyName(const String &p, bool *pixel_or_pos_prefix = 0) {
- DeprecatedString prop = p.deprecatedString();
-
- int i = prop.length();
- while (--i > 0) {
- ::UChar c = prop[i].unicode();
- if (c >= 'A' && c <= 'Z')
- prop.insert(i, '-');
- }
-
- prop = prop.lower();
+static String cssPropertyName(const String& propertyName, bool* hadPixelOrPosPrefix = 0)
+{
+ if (hadPixelOrPosPrefix)
+ *hadPixelOrPosPrefix = false;
+
+ unsigned length = propertyName.length();
+ if (!length)
+ return String();
+
+ Vector<UChar> name;
+ name.reserveCapacity(length);
+
+ unsigned i = 0;
+
+ if (hasCSSPropertyNamePrefix(propertyName, "css"))
+ i += 3;
+ else if (hasCSSPropertyNamePrefix(propertyName, "pixel")) {
+ i += 5;
+ if (hadPixelOrPosPrefix)
+ *hadPixelOrPosPrefix = true;
+ } else if (hasCSSPropertyNamePrefix(propertyName, "pos")) {
+ i += 3;
+ if (hadPixelOrPosPrefix)
+ *hadPixelOrPosPrefix = true;
+ } else if (hasCSSPropertyNamePrefix(propertyName, "webkit")
+ || hasCSSPropertyNamePrefix(propertyName, "khtml")
+ || hasCSSPropertyNamePrefix(propertyName, "apple"))
+ name.append('-');
+ else {
+ if (WTF::isASCIIUpper(propertyName[0]))
+ return String();
+ }
- if (pixel_or_pos_prefix)
- *pixel_or_pos_prefix = false;
+ name.append(WTF::toASCIILower(propertyName[i++]));
- if (prop.startsWith("css-")) {
- prop = prop.mid(4);
- } else if (prop.startsWith("pixel-")) {
- prop = prop.mid(6);
- if (pixel_or_pos_prefix)
- *pixel_or_pos_prefix = true;
- } else if (prop.startsWith("pos-")) {
- prop = prop.mid(4);
- if (pixel_or_pos_prefix)
- *pixel_or_pos_prefix = true;
- } else if (prop.startsWith("khtml-") ||
- prop.startsWith("apple-") ||
- prop.startsWith("webkit-")) {
- prop.insert(0, '-');
- }
+ for (; i < length; ++i) {
+ UChar c = propertyName[i];
+ if (!WTF::isASCIIUpper(c))
+ name.append(c);
+ else {
+ name.append('-');
+ name.append(WTF::toASCIILower(c));
+ }
+ }
- return prop;
+ return String::adopt(name);
}
-
NAMED_PROPERTY_GETTER(CSSStyleDeclaration) {
INC_STATS(L"DOM.CSSStyleDeclaration.NamedPropertyGetter");
// First look for API defined attributes on the style declaration
// object.
- if (info.Holder()->HasRealNamedCallbackProperty(name)) {
+ if (info.Holder()->HasRealNamedCallbackProperty(name))
return v8::Handle<v8::Value>();
- }
// Search the style declaration.
CSSStyleDeclaration* imp = V8Proxy::ToNativeObject<CSSStyleDeclaration>(
@@ -1659,7 +1656,7 @@ NAMED_PROPERTY_GETTER(CSSStyleDeclaration) {
bool pixel_or_pos;
String p = ToWebCoreString(name);
- String prop = CSSPropertyName(p, &pixel_or_pos);
+ String prop = cssPropertyName(p, &pixel_or_pos);
// Do not handle non-property names.
if (!CSSStyleDeclaration::isPropertyName(prop)) {
@@ -1698,7 +1695,7 @@ NAMED_PROPERTY_SETTER(CSSStyleDeclaration) {
int ec = 0;
bool pixel_or_pos;
- String prop = CSSPropertyName(property_name, &pixel_or_pos);
+ String prop = cssPropertyName(property_name, &pixel_or_pos);
if (!CSSStyleDeclaration::isPropertyName(prop)) {
return v8::Handle<v8::Value>(); // do not block the call
}
@@ -1800,6 +1797,9 @@ CALLBACK_FUNC_DECL(CSSPrimitiveValueGetRGBColorValue) {
static_cast<Peerable*>(new RGBColor(rgbcolor)));
}
+
+// CanvasRenderingContext2D ----------------------------------------------------
+
// Helper macro for converting v8 values into floats (expected by many of the
// canvas functions).
#define TO_FLOAT(a) static_cast<float>((a)->NumberValue())
@@ -1849,7 +1849,6 @@ CALLBACK_FUNC_DECL(CanvasRenderingContext2DSetStrokeColor) {
return v8::Undefined();
}
-
CALLBACK_FUNC_DECL(CanvasRenderingContext2DSetFillColor) {
INC_STATS(L"DOM.CanvasRenderingContext2D.steFillColor()");
CanvasRenderingContext2D* context =
@@ -1891,39 +1890,31 @@ CALLBACK_FUNC_DECL(CanvasRenderingContext2DSetFillColor) {
return v8::Undefined();
}
-
CALLBACK_FUNC_DECL(CanvasRenderingContext2DStrokeRect) {
INC_STATS(L"DOM.CanvasRenderingContext2D.strokeRect()");
CanvasRenderingContext2D* context =
V8Proxy::ToNativeObject<CanvasRenderingContext2D>(
V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder());
- ExceptionCode ec = 0;
double x = 0, y = 0, width = 0, height = 0, line_width = 0;
if (args.Length() == 5) {
context->strokeRect(TO_FLOAT(args[0]),
TO_FLOAT(args[1]),
TO_FLOAT(args[2]),
TO_FLOAT(args[3]),
- TO_FLOAT(args[4]),
- ec);
+ TO_FLOAT(args[4]));
} else if (args.Length() == 4) {
context->strokeRect(TO_FLOAT(args[0]),
TO_FLOAT(args[1]),
TO_FLOAT(args[2]),
- TO_FLOAT(args[3]),
- ec);
+ TO_FLOAT(args[3]));
} else {
- // Should throw index error
- ec = INDEX_SIZE_ERR;
- }
- if (ec != 0) {
- V8Proxy::SetDOMException(ec);
+ V8Proxy::SetDOMException(INDEX_SIZE_ERR);
return v8::Handle<v8::Value>();
}
+
return v8::Undefined();
}
-
CALLBACK_FUNC_DECL(CanvasRenderingContext2DSetShadow) {
INC_STATS(L"DOM.CanvasRenderingContext2D.setShadow()");
CanvasRenderingContext2D* context =
@@ -1974,7 +1965,6 @@ CALLBACK_FUNC_DECL(CanvasRenderingContext2DSetShadow) {
return v8::Undefined();
}
-
CALLBACK_FUNC_DECL(CanvasRenderingContext2DDrawImage) {
INC_STATS(L"DOM.CanvasRenderingContext2D.drawImage()");
CanvasRenderingContext2D* context =
@@ -2060,7 +2050,6 @@ CALLBACK_FUNC_DECL(CanvasRenderingContext2DDrawImage) {
return v8::Handle<v8::Value>();
}
-
CALLBACK_FUNC_DECL(CanvasRenderingContext2DDrawImageFromRect) {
INC_STATS(L"DOM.CanvasRenderingContext2D.drawImageFromRect()");
CanvasRenderingContext2D* context =
@@ -2129,6 +2118,113 @@ CALLBACK_FUNC_DECL(CanvasRenderingContext2DCreatePattern) {
return v8::Handle<v8::Value>();
}
+CALLBACK_FUNC_DECL(CanvasRenderingContext2DFillText) {
+ INC_STATS(L"DOM.CanvasRenderingContext2D.fillText()");
+ V8Proxy::SetDOMException(NOT_SUPPORTED_ERR);
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(CanvasRenderingContext2DStrokeText) {
+ INC_STATS(L"DOM.CanvasRenderingContext2D.strokeText()");
+ V8Proxy::SetDOMException(NOT_SUPPORTED_ERR);
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(CanvasRenderingContext2DPutImageData) {
+ INC_STATS(L"DOM.CanvasRenderingContext2D.putImageData()");
+ V8Proxy::SetDOMException(NOT_SUPPORTED_ERR);
+ return v8::Undefined();
+}
+
+
+// Console ---------------------------------------------------------------------
+
+CALLBACK_FUNC_DECL(ConsoleAssert) {
+ INC_STATS(L"DOM.Console.assert()");
+ V8Proxy::SetDOMException(NOT_SUPPORTED_ERR);
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(ConsoleCount) {
+ INC_STATS(L"DOM.Console.count()");
+ V8Proxy::SetDOMException(NOT_SUPPORTED_ERR);
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(ConsoleDebug) {
+ INC_STATS(L"DOM.Console.debug()");
+ V8Proxy::SetDOMException(NOT_SUPPORTED_ERR);
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(ConsoleDir) {
+ INC_STATS(L"DOM.Console.dir()");
+ V8Proxy::SetDOMException(NOT_SUPPORTED_ERR);
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(ConsoleError) {
+ INC_STATS(L"DOM.Console.error()");
+ v8::Handle<v8::Value> holder = args.Holder();
+ Console* imp = V8Proxy::ToNativeObject<Console>(V8ClassIndex::CONSOLE, holder);
+ String message = ToWebCoreString(args[0]);
+ imp->error(message);
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(ConsoleGroup) {
+ INC_STATS(L"DOM.Console.group()");
+ V8Proxy::SetDOMException(NOT_SUPPORTED_ERR);
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(ConsoleInfo) {
+ INC_STATS(L"DOM.Console.info()");
+ v8::Handle<v8::Value> holder = args.Holder();
+ Console* imp = V8Proxy::ToNativeObject<Console>(V8ClassIndex::CONSOLE, holder);
+ String message = ToWebCoreString(args[0]);
+ imp->info(message);
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(ConsoleLog) {
+ INC_STATS(L"DOM.Console.log()");
+ v8::Handle<v8::Value> holder = args.Holder();
+ Console* imp = V8Proxy::ToNativeObject<Console>(V8ClassIndex::CONSOLE, holder);
+ String message = ToWebCoreString(args[0]);
+ imp->log(message);
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(ConsoleProfile) {
+ INC_STATS(L"DOM.Console.profile()");
+ V8Proxy::SetDOMException(NOT_SUPPORTED_ERR);
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(ConsoleProfileEnd) {
+ INC_STATS(L"DOM.Console.profileEnd()");
+ V8Proxy::SetDOMException(NOT_SUPPORTED_ERR);
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(ConsoleTimeEnd) {
+ INC_STATS(L"DOM.Console.timeEnd()");
+ V8Proxy::SetDOMException(NOT_SUPPORTED_ERR);
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(ConsoleWarn) {
+ INC_STATS(L"DOM.Console.warn()");
+ v8::Handle<v8::Value> holder = args.Holder();
+ Console* imp = V8Proxy::ToNativeObject<Console>(V8ClassIndex::CONSOLE, holder);
+ String message = ToWebCoreString(args[0]);
+ imp->warn(message);
+ return v8::Undefined();
+}
+
+
+// Clipboard -------------------------------------------------------------------
CALLBACK_FUNC_DECL(ClipboardClearData) {
INC_STATS(L"DOM.Clipboard.clearData()");
@@ -2215,6 +2311,71 @@ static bool AllowSettingFrameSrcToJavascriptUrl(HTMLFrameElementBase* frame,
}
+// Element ---------------------------------------------------------------------
+
+CALLBACK_FUNC_DECL(ElementQuerySelector) {
+ INC_STATS(L"DOM.Element.querySelector()");
+ Element* element = V8Proxy::DOMWrapperToNode<Element>(args.Holder());
+
+ ExceptionCode ec = 0;
+
+ String selectors = valueToStringWithNullOrUndefinedCheck(args[0]);
+
+ NSResolver* resolver = 0;
+ if (V8NSResolver::HasInstance(args[1])) {
+ resolver = V8Proxy::ToNativeObject<NSResolver>(
+ V8ClassIndex::NSRESOLVER, args[1]);
+ } else if (args[1]->IsObject()) {
+ resolver = new JSNSResolver(args[1]->ToObject());
+ } else if (!args[1]->IsNull() && !args[1]->IsUndefined()) {
+ V8Proxy::SetDOMException(TYPE_MISMATCH_ERR);
+ return v8::Handle<v8::Value>();
+ }
+ OwnPtr<ExceptionContext> context(new ExceptionContext());
+ RefPtr<Element> result = WTF::getPtr(
+ element->querySelector(selectors, resolver, ec, context.get()));
+ if (ec != 0) {
+ V8Proxy::SetDOMException(ec);
+ return v8::Handle<v8::Value>();
+ }
+ if (context->hadException()) {
+ v8::ThrowException(context->exception());
+ return v8::Undefined();
+ }
+ return V8Proxy::ToV8Object(V8ClassIndex::NODE, WTF::getPtr(result));
+}
+
+CALLBACK_FUNC_DECL(ElementQuerySelectorAll) {
+ INC_STATS(L"DOM.Element.querySelectorAll()");
+ Element* element = V8Proxy::DOMWrapperToNode<Element>(args.Holder());
+ ExceptionCode ec = 0;
+
+ String selectors = valueToStringWithNullOrUndefinedCheck(args[0]);
+
+ NSResolver* resolver = 0;
+ if (V8NSResolver::HasInstance(args[1])) {
+ resolver = V8Proxy::ToNativeObject<NSResolver>(
+ V8ClassIndex::NSRESOLVER, args[1]);
+ } else if (args[1]->IsObject()) {
+ resolver = new JSNSResolver(args[1]->ToObject());
+ } else if (!args[1]->IsNull() && !args[1]->IsUndefined()) {
+ V8Proxy::SetDOMException(TYPE_MISMATCH_ERR);
+ return v8::Handle<v8::Value>();
+ }
+ OwnPtr<ExceptionContext> context(new ExceptionContext());
+ RefPtr<NodeList> result = WTF::getPtr(
+ element->querySelectorAll(selectors, resolver, ec, context.get()));
+ if (ec != 0) {
+ V8Proxy::SetDOMException(ec);
+ return v8::Handle<v8::Value>();
+ }
+ if (context->hadException()) {
+ v8::ThrowException(context->exception());
+ return v8::Undefined();
+ }
+ return V8Proxy::ToV8Object(V8ClassIndex::NODELIST, WTF::getPtr(result));
+}
+
CALLBACK_FUNC_DECL(ElementSetAttribute) {
INC_STATS(L"DOM.Element.setAttribute()");
Element* imp = V8Proxy::DOMWrapperToNode<Element>(args.Holder());
@@ -2234,7 +2395,6 @@ CALLBACK_FUNC_DECL(ElementSetAttribute) {
return v8::Undefined();
}
-
CALLBACK_FUNC_DECL(ElementSetAttributeNode) {
INC_STATS(L"DOM.Element.setAttributeNode()");
if (!V8Attr::HasInstance(args[0])) {
@@ -2258,7 +2418,6 @@ CALLBACK_FUNC_DECL(ElementSetAttributeNode) {
return V8Proxy::NodeToV8Object(result.get());
}
-
CALLBACK_FUNC_DECL(ElementSetAttributeNS) {
INC_STATS(L"DOM.Element.setAttributeNS()");
Element* imp = V8Proxy::DOMWrapperToNode<Element>(args.Holder());
@@ -2279,7 +2438,6 @@ CALLBACK_FUNC_DECL(ElementSetAttributeNS) {
return v8::Undefined();
}
-
CALLBACK_FUNC_DECL(ElementSetAttributeNodeNS) {
INC_STATS(L"DOM.Element.setAttributeNodeNS()");
if (!V8Attr::HasInstance(args[0])) {
@@ -2304,6 +2462,8 @@ CALLBACK_FUNC_DECL(ElementSetAttributeNodeNS) {
}
+// Attr ------------------------------------------------------------------------
+
ACCESSOR_SETTER(AttrValue) {
Attr* imp =
V8Proxy::DOMWrapperToNode<Attr>(info.Holder());
@@ -2320,6 +2480,8 @@ ACCESSOR_SETTER(AttrValue) {
}
+// HTMLFrameElement ------------------------------------------------------------
+
ACCESSOR_SETTER(HTMLFrameElementSrc) {
HTMLFrameElement* imp =
V8Proxy::DOMWrapperToNode<HTMLFrameElement>(info.Holder());
@@ -2330,7 +2492,6 @@ ACCESSOR_SETTER(HTMLFrameElementSrc) {
imp->setSrc(v);
}
-
ACCESSOR_SETTER(HTMLFrameElementLocation) {
HTMLFrameElement* imp =
V8Proxy::DOMWrapperToNode<HTMLFrameElement>(info.Holder());
@@ -2342,6 +2503,8 @@ ACCESSOR_SETTER(HTMLFrameElementLocation) {
}
+// HTMLIFrameElement -----------------------------------------------------------
+
ACCESSOR_SETTER(HTMLIFrameElementSrc) {
HTMLIFrameElement* imp =
V8Proxy::DOMWrapperToNode<HTMLIFrameElement>(info.Holder());
@@ -2419,6 +2582,9 @@ CALLBACK_FUNC_DECL(DOMWindowSetInterval) {
return WindowSetTimeoutImpl(args, false);
}
+
+// HTMLDocument ----------------------------------------------------------------
+
// Concatenates "args" to a string. If args is empty, returns empty string.
// Firefox/Safari/IE support non-standard arguments to document.write, ex:
// document.write("a", "b", "c") --> document.write("abc")
@@ -2431,23 +2597,22 @@ static String WriteHelper_GetString(const v8::Arguments& args) {
return str;
}
-
CALLBACK_FUNC_DECL(HTMLDocumentWrite) {
INC_STATS(L"DOM.HTMLDocument.write()");
HTMLDocument* imp = V8Proxy::DOMWrapperToNode<HTMLDocument>(args.Holder());
- imp->write(WriteHelper_GetString(args));
+ imp->write(WriteHelper_GetString(args),
+ V8Proxy::retrieveWindow()->document());
return v8::Undefined();
}
-
CALLBACK_FUNC_DECL(HTMLDocumentWriteln) {
INC_STATS(L"DOM.HTMLDocument.writeln()");
HTMLDocument* imp = V8Proxy::DOMWrapperToNode<HTMLDocument>(args.Holder());
- imp->writeln(WriteHelper_GetString(args));
+ imp->writeln(WriteHelper_GetString(args),
+ V8Proxy::retrieveWindow()->document());
return v8::Undefined();
}
-
CALLBACK_FUNC_DECL(HTMLDocumentOpen) {
INC_STATS(L"DOM.HTMLDocument.open()");
HTMLDocument* imp = V8Proxy::DOMWrapperToNode<HTMLDocument>(args.Holder());
@@ -2487,7 +2652,6 @@ CALLBACK_FUNC_DECL(HTMLDocumentOpen) {
return v8::Undefined();
}
-
CALLBACK_FUNC_DECL(HTMLDocumentClear) {
INC_STATS(L"DOM.HTMLDocument.clear()");
// Do nothing (unimplemented)
@@ -2500,6 +2664,8 @@ CALLBACK_FUNC_DECL(HTMLDocumentClear) {
}
+// Document --------------------------------------------------------------------
+
CALLBACK_FUNC_DECL(DocumentEvaluate) {
INC_STATS(L"DOM.Document.evaluate()");
@@ -2538,6 +2704,133 @@ CALLBACK_FUNC_DECL(DocumentEvaluate) {
static_cast<Peerable*>(result.get()));
}
+CALLBACK_FUNC_DECL(DocumentQuerySelector) {
+ INC_STATS(L"DOM.Document.querySelector()");
+ Document* document = V8Proxy::DOMWrapperToNode<Document>(args.Holder());
+ ExceptionCode ec = 0;
+
+ String selectors = valueToStringWithNullOrUndefinedCheck(args[0]);
+
+ NSResolver* resolver = 0;
+ if (V8NSResolver::HasInstance(args[1])) {
+ resolver = V8Proxy::ToNativeObject<NSResolver>(
+ V8ClassIndex::NSRESOLVER, args[1]);
+ } else if (args[1]->IsObject()) {
+ resolver = new JSNSResolver(args[1]->ToObject());
+ } else if (!args[1]->IsNull() && !args[1]->IsUndefined()) {
+ V8Proxy::SetDOMException(TYPE_MISMATCH_ERR);
+ return v8::Handle<v8::Value>();
+ }
+ OwnPtr<ExceptionContext> context(new ExceptionContext());
+ RefPtr<Element> result = WTF::getPtr(
+ document->querySelector(selectors, resolver, ec, context.get()));
+ if (ec != 0) {
+ V8Proxy::SetDOMException(ec);
+ return v8::Handle<v8::Value>();
+ }
+ if (context->hadException()) {
+ v8::ThrowException(context->exception());
+ return v8::Undefined();
+ }
+ return V8Proxy::ToV8Object(V8ClassIndex::NODE, WTF::getPtr(result));
+}
+
+CALLBACK_FUNC_DECL(DocumentQuerySelectorAll) {
+ INC_STATS(L"DOM.Document.querySelectorAll()");
+ Document* document = V8Proxy::DOMWrapperToNode<Document>(args.Holder());
+ ExceptionCode ec = 0;
+
+ String selectors = valueToStringWithNullOrUndefinedCheck(args[0]);
+
+ NSResolver* resolver = 0;
+ if (V8NSResolver::HasInstance(args[1])) {
+ resolver = V8Proxy::ToNativeObject<NSResolver>(
+ V8ClassIndex::NSRESOLVER, args[1]);
+ } else if (args[1]->IsObject()) {
+ resolver = new JSNSResolver(args[1]->ToObject());
+ } else if (!args[1]->IsNull() && !args[1]->IsUndefined()) {
+ V8Proxy::SetDOMException(TYPE_MISMATCH_ERR);
+ return v8::Handle<v8::Value>();
+ }
+ OwnPtr<ExceptionContext> context(new ExceptionContext());
+ RefPtr<NodeList> result = WTF::getPtr(
+ document->querySelectorAll(selectors, resolver, ec, context.get()));
+ if (ec != 0) {
+ V8Proxy::SetDOMException(ec);
+ return v8::Handle<v8::Value>();
+ }
+ if (context->hadException()) {
+ v8::ThrowException(context->exception());
+ return v8::Undefined();
+ }
+ return V8Proxy::ToV8Object(V8ClassIndex::NODELIST, WTF::getPtr(result));
+}
+
+CALLBACK_FUNC_DECL(DocumentFragmentQuerySelector) {
+ INC_STATS(L"DOM.DocumentFragment.querySelector()");
+ DocumentFragment* fragment =
+ V8Proxy::DOMWrapperToNode<DocumentFragment>(args.Holder());
+ ExceptionCode ec = 0;
+
+ String selectors = valueToStringWithNullOrUndefinedCheck(args[0]);
+
+ NSResolver* resolver = 0;
+ if (V8NSResolver::HasInstance(args[1])) {
+ resolver = V8Proxy::ToNativeObject<NSResolver>(
+ V8ClassIndex::NSRESOLVER, args[1]);
+ } else if (args[1]->IsObject()) {
+ resolver = new JSNSResolver(args[1]->ToObject());
+ } else if (!args[1]->IsNull() && !args[1]->IsUndefined()) {
+ V8Proxy::SetDOMException(TYPE_MISMATCH_ERR);
+ return v8::Handle<v8::Value>();
+ }
+ OwnPtr<ExceptionContext> context(new ExceptionContext());
+ RefPtr<Element> result = WTF::getPtr(
+ fragment->querySelector(selectors, resolver, ec, context.get()));
+ if (ec != 0) {
+ V8Proxy::SetDOMException(ec);
+ return v8::Handle<v8::Value>();
+ }
+ if (context->hadException()) {
+ v8::ThrowException(context->exception());
+ return v8::Undefined();
+ }
+ return V8Proxy::ToV8Object(V8ClassIndex::NODE, WTF::getPtr(result));
+}
+
+CALLBACK_FUNC_DECL(DocumentFragmentQuerySelectorAll) {
+ INC_STATS(L"DOM.DocumentFragment.querySelectorAll()");
+ DocumentFragment* fragment =
+ V8Proxy::DOMWrapperToNode<DocumentFragment>(args.Holder());
+ ExceptionCode ec = 0;
+
+ String selectors = valueToStringWithNullOrUndefinedCheck(args[0]);
+
+ NSResolver* resolver = 0;
+ if (V8NSResolver::HasInstance(args[1])) {
+ resolver = V8Proxy::ToNativeObject<NSResolver>(
+ V8ClassIndex::NSRESOLVER, args[1]);
+ } else if (args[1]->IsObject()) {
+ resolver = new JSNSResolver(args[1]->ToObject());
+ } else if (!args[1]->IsNull() && !args[1]->IsUndefined()) {
+ V8Proxy::SetDOMException(TYPE_MISMATCH_ERR);
+ return v8::Handle<v8::Value>();
+ }
+ OwnPtr<ExceptionContext> context(new ExceptionContext());
+ RefPtr<NodeList> result = WTF::getPtr(
+ fragment->querySelectorAll(selectors, resolver, ec, context.get()));
+ if (ec != 0) {
+ V8Proxy::SetDOMException(ec);
+ return v8::Handle<v8::Value>();
+ }
+ if (context->hadException()) {
+ v8::ThrowException(context->exception());
+ return v8::Undefined();
+ }
+ return V8Proxy::ToV8Object(V8ClassIndex::NODELIST, WTF::getPtr(result));
+}
+
+// DOMWindow -------------------------------------------------------------------
static bool IsAscii(const String& str) {
for (size_t i = 0; i < str.length(); i++) {
@@ -2547,7 +2840,6 @@ static bool IsAscii(const String& str) {
return true;
}
-
static v8::Handle<v8::Value> Base64Convert(const String& str, bool encode) {
if (!IsAscii(str)) {
V8Proxy::SetDOMException(INVALID_CHARACTER_ERR);
@@ -2572,7 +2864,6 @@ static v8::Handle<v8::Value> Base64Convert(const String& str, bool encode) {
return v8String(String(out.data(), out.size()));
}
-
CALLBACK_FUNC_DECL(DOMWindowAtob) {
INC_STATS(L"DOM.DOMWindow.atob()");
DOMWindow* imp = V8Proxy::ToNativeObject<DOMWindow>(
@@ -2595,7 +2886,6 @@ CALLBACK_FUNC_DECL(DOMWindowAtob) {
return Base64Convert(str, false);
}
-
CALLBACK_FUNC_DECL(DOMWindowBtoa) {
INC_STATS(L"DOM.DOMWindow.btoa()");
DOMWindow* imp = V8Proxy::ToNativeObject<DOMWindow>(
@@ -2618,23 +2908,25 @@ CALLBACK_FUNC_DECL(DOMWindowBtoa) {
return Base64Convert(str, true);
}
-
// TODO(fqian): returning string is cheating, and we should
// fix this by calling toString function on the receiver.
// However, V8 implements toString in JavaScript, which requires
// switching context of receiver. I consider it is dangerous.
-CALLBACK_FUNC_DECL(DOMWindowToString) {
- INC_STATS(L"DOM.DOMWindow.toString()");
- return args.This()->ObjectProtoToString();
+CALLBACK_FUNC_DECL(DOMWindowToString)
+{
+ INC_STATS(L"DOM.DOMWindow.toString()");
+ return args.This()->ObjectProtoToString();
}
-
-CALLBACK_FUNC_DECL(DOMWindowNOP) {
- INC_STATS(L"DOM.DOMWindow.nop()");
- return v8::Undefined();
+CALLBACK_FUNC_DECL(DOMWindowNOP)
+{
+ INC_STATS(L"DOM.DOMWindow.nop()");
+ return v8::Undefined();
}
+// EventTargetNode -------------------------------------------------------------
+
CALLBACK_FUNC_DECL(EventTargetNodeAddEventListener) {
INC_STATS(L"DOM.EventTargetNode.addEventListener()");
EventTargetNode* node =
@@ -2654,7 +2946,6 @@ CALLBACK_FUNC_DECL(EventTargetNodeAddEventListener) {
return v8::Undefined();
}
-
CALLBACK_FUNC_DECL(EventTargetNodeRemoveEventListener) {
INC_STATS(L"DOM.EventTargetNode.removeEventListener()");
EventTargetNode* node =
@@ -2679,365 +2970,164 @@ CALLBACK_FUNC_DECL(EventTargetNodeRemoveEventListener) {
}
-// ------------------------------------------------------------------
-// Customized XMLHttpRequest binding implementation
-
-// Use an array to hold dependents. It works like a ref-counted scheme.
-// A value can be added more than once to the xhr object.
-static void CreateHiddenXHRDependency(v8::Local<v8::Object> xhr,
- v8::Local<v8::Value> value) {
- ASSERT(V8Proxy::GetDOMWrapperType(xhr) == V8ClassIndex::XMLHTTPREQUEST);
- v8::Local<v8::Value> cache =
- xhr->GetInternalField(V8Custom::kXMLHttpRequestCacheIndex);
- if (cache->IsNull() || cache->IsUndefined()) {
- cache = v8::Array::New();
- xhr->SetInternalField(V8Custom::kXMLHttpRequestCacheIndex, cache);
- }
-
- v8::Local<v8::Array> cache_array = v8::Local<v8::Array>::Cast(cache);
- cache_array->Set(v8::Integer::New(cache_array->Length()), value);
-}
-
-
-static void RemoveHiddenXHRDependency(v8::Local<v8::Object> xhr,
- v8::Local<v8::Value> value) {
- ASSERT(V8Proxy::GetDOMWrapperType(xhr) == V8ClassIndex::XMLHTTPREQUEST);
- v8::Local<v8::Value> cache =
- xhr->GetInternalField(V8Custom::kXMLHttpRequestCacheIndex);
- ASSERT(cache->IsArray());
- v8::Local<v8::Array> cache_array = v8::Local<v8::Array>::Cast(cache);
- for (int i = cache_array->Length() - 1; i >= 0; i--) {
- v8::Local<v8::Value> cached = cache_array->Get(v8::Integer::New(i));
- if (cached->StrictEquals(value)) {
- cache_array->Delete(i);
- return;
- }
- }
-
- // Should not reach here.
- ASSERT(false);
-}
-
-
-ACCESSOR_SETTER(XMLHttpRequestOnreadystatechange) {
- XMLHttpRequest* imp = V8Proxy::ToNativeObject<XMLHttpRequest>(
- V8ClassIndex::XMLHTTPREQUEST, info.Holder());
- if (value->IsNull()) {
- if (imp->onreadystatechange()) {
- V8XHREventListener* listener =
- static_cast<V8XHREventListener*>(imp->onreadystatechange());
- v8::Local<v8::Object> v8_listener = listener->GetListenerObject();
- RemoveHiddenXHRDependency(info.Holder(), v8_listener);
- }
-
- // Clear the listener
- imp->setOnreadystatechange(0);
-
- } else {
- V8Proxy* proxy = V8Proxy::retrieve(imp->document()->frame());
- if (!proxy)
- return;
-
- EventListener* listener =
- proxy->FindOrCreateXHREventListener(value, false);
- if (listener) {
- imp->setOnreadystatechange(listener);
- CreateHiddenXHRDependency(info.Holder(), value);
- }
- }
-}
-
-
-ACCESSOR_SETTER(XMLHttpRequestOnload) {
- XMLHttpRequest* imp = V8Proxy::ToNativeObject<XMLHttpRequest>(
- V8ClassIndex::XMLHTTPREQUEST, info.Holder());
- if (value->IsNull()) {
- if (imp->onload()) {
- V8XHREventListener* listener =
- static_cast<V8XHREventListener*>(imp->onload());
- v8::Local<v8::Object> v8_listener = listener->GetListenerObject();
- RemoveHiddenXHRDependency(info.Holder(), v8_listener);
- }
-
- imp->setOnload(0);
-
- } else {
- V8Proxy* proxy = V8Proxy::retrieve(imp->document()->frame());
- if (!proxy)
- return;
-
- EventListener* listener =
- proxy->FindOrCreateXHREventListener(value, false);
- if (listener) {
- imp->setOnload(listener);
- CreateHiddenXHRDependency(info.Holder(), value);
- }
- }
-}
-
-
-CALLBACK_FUNC_DECL(XMLHttpRequestAddEventListener) {
- INC_STATS(L"DOM.XMLHttpRequest.addEventListener()");
- XMLHttpRequest* imp = V8Proxy::ToNativeObject<XMLHttpRequest>(
- V8ClassIndex::XMLHTTPREQUEST, args.Holder());
-
- V8Proxy* proxy = V8Proxy::retrieve(imp->document()->frame());
- if (!proxy)
- return v8::Undefined();
-
- EventListener* listener =
- proxy->FindOrCreateXHREventListener(args[1], false);
- if (listener) {
- String type = ToWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- imp->addEventListener(type, listener, useCapture);
-
- CreateHiddenXHRDependency(args.Holder(), args[1]);
- }
- return v8::Undefined();
-}
-
-
-CALLBACK_FUNC_DECL(XMLHttpRequestRemoveEventListener) {
- INC_STATS(L"DOM.XMLHttpRequest.removeEventListener()");
- XMLHttpRequest* imp = V8Proxy::ToNativeObject<XMLHttpRequest>(
- V8ClassIndex::XMLHTTPREQUEST, args.Holder());
-
- V8Proxy* proxy = V8Proxy::retrieve(imp->document()->frame());
- if (!proxy)
- return v8::Undefined(); // probably leaked
-
- EventListener* listener =
- proxy->FindXHREventListener(args[1], false);
-
- if (listener) {
- String type = ToWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- imp->removeEventListener(type, listener, useCapture);
-
- RemoveHiddenXHRDependency(args.Holder(), args[1]);
- }
-
- return v8::Undefined();
-}
-
-
-CALLBACK_FUNC_DECL(XMLHttpRequestOpen) {
- INC_STATS(L"DOM.XMLHttpRequest.open()");
- // Four cases:
- // open(method, url)
- // open(method, url, async)
- // open(method, url, async, user)
- // open(method, url, async, user, passwd)
-
- if (args.Length() < 2) {
- V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "Not enough arguments");
- return v8::Undefined();
- }
-
- // get the implementation
- XMLHttpRequest* xhr = V8Proxy::ToNativeObject<XMLHttpRequest>(
- V8ClassIndex::XMLHTTPREQUEST, args.Holder());
-
- // retrieve parameters
- String method = ToWebCoreString(args[0]);
- String urlstring = ToWebCoreString(args[1]);
- V8Proxy* proxy = V8Proxy::retrieve();
- KURL url =
- proxy->frame()->document()->completeURL(urlstring).deprecatedString();
-
- bool async = (args.Length() < 3) ? true : args[2]->BooleanValue();
-
- ExceptionCode ec = 0;
- String user, passwd;
- if (args.Length() >= 4 && !args[3]->IsUndefined()) {
- user = valueToStringWithNullCheck(args[3]);
-
- if (args.Length() >= 5 && !args[4]->IsUndefined()) {
- passwd = valueToStringWithNullCheck(args[4]);
- xhr->open(method, url, async, user, passwd, ec);
- } else {
- xhr->open(method, url, async, user, ec);
- }
- } else {
- xhr->open(method, url, async, ec);
- }
-
- if (ec != 0) {
- V8Proxy::SetDOMException(ec);
- return v8::Handle<v8::Value>();
- }
-
- return v8::Undefined();
-}
-
-
-static bool IsDocumentType(v8::Handle<v8::Value> value) {
- // TODO(fqian): add other document types.
- return V8Document::HasInstance(value) || V8HTMLDocument::HasInstance(value);
-}
-
-
-CALLBACK_FUNC_DECL(XMLHttpRequestSend) {
- INC_STATS(L"DOM.XMLHttpRequest.send()");
- // Two cases:
- // send(document)
- // send(string)
-
- // get implementation
- XMLHttpRequest* xhr = V8Proxy::ToNativeObject<XMLHttpRequest>(
- V8ClassIndex::XMLHTTPREQUEST, args.Holder());
-
- String body;
- if (args.Length() >= 1) {
- v8::Handle<v8::Value> arg = args[0];
- if (IsDocumentType(arg)) {
- v8::Handle<v8::Object> obj = v8::Handle<v8::Object>::Cast(arg);
- Document* doc = V8Proxy::DOMWrapperToNode<Document>(obj);
- ASSERT(doc);
- body = doc->toString();
- } else {
- body = valueToStringWithNullCheck(arg);
- }
- }
-
- ExceptionCode ec = 0;
- xhr->send(body, ec);
- if (ec != 0) {
- V8Proxy::SetDOMException(ec);
- return v8::Handle<v8::Value>();
- }
-
- return v8::Undefined();
-}
-
-
-CALLBACK_FUNC_DECL(XMLHttpRequestSetRequestHeader) {
- INC_STATS(L"DOM.XMLHttpRequest.setRequestHeader()");
- if (args.Length() < 2) {
- V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "Not enough arguments");
- return v8::Undefined();
- }
-
- XMLHttpRequest* imp = V8Proxy::ToNativeObject<XMLHttpRequest>(
- V8ClassIndex::XMLHTTPREQUEST, args.Holder());
- ExceptionCode ec = 0;
- String header = ToWebCoreString(args[0]);
- String value = ToWebCoreString(args[1]);
- imp->setRequestHeader(header, value, ec);
- if (ec != 0) {
- V8Proxy::SetDOMException(ec);
- return v8::Handle<v8::Value>();
- }
- return v8::Undefined();
-}
-
-
-CALLBACK_FUNC_DECL(XMLHttpRequestGetResponseHeader) {
- INC_STATS(L"DOM.XMLHttpRequest.getResponseHeader()");
- if (args.Length() < 1) {
- V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "Not enough arguments");
- return v8::Undefined();
- }
-
- XMLHttpRequest* imp = V8Proxy::ToNativeObject<XMLHttpRequest>(
- V8ClassIndex::XMLHTTPREQUEST, args.Holder());
- ExceptionCode ec = 0;
- String header = ToWebCoreString(args[0]);
- String result = imp->getResponseHeader(header, ec);
- if (ec != 0) {
- V8Proxy::SetDOMException(ec);
- return v8::Handle<v8::Value>();
- }
- return v8StringOrNull(result);
-}
-
-
-CALLBACK_FUNC_DECL(XMLHttpRequestOverrideMimeType) {
- INC_STATS(L"DOM.XMLHttpRequest.overrideMimeType()");
- if (args.Length() < 1) {
- V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "Not enough arguments");
- return v8::Undefined();
- }
-
- XMLHttpRequest* imp = V8Proxy::ToNativeObject<XMLHttpRequest>(
- V8ClassIndex::XMLHTTPREQUEST, args.Holder());
- String value = ToWebCoreString(args[0]);
- imp->overrideMIMEType(value);
- return v8::Undefined();
-}
+// TreeWalker ------------------------------------------------------------------
CALLBACK_FUNC_DECL(TreeWalkerParentNode) {
INC_STATS(L"DOM.TreeWalker.parentNode()");
- TreeWalker* imp = V8Proxy::ToNativeObject<TreeWalker>(
+ TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>(
V8ClassIndex::TREEWALKER, args.Holder());
- return V8Proxy::NodeToV8Object(imp->parentNode());
+
+ OwnPtr<ExceptionContext> context(new ExceptionContext());
+ RefPtr<Node> result = treeWalker->parentNode(context.get());
+ if (context->hadException()) {
+ v8::ThrowException(context->exception());
+ return v8::Undefined();
+ }
+ if (!result) return v8::Null();
+ return V8Proxy::NodeToV8Object(result.get());
}
CALLBACK_FUNC_DECL(TreeWalkerFirstChild) {
INC_STATS(L"DOM.TreeWalker.firstChild()");
- TreeWalker* imp = V8Proxy::ToNativeObject<TreeWalker>(
+ TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>(
V8ClassIndex::TREEWALKER, args.Holder());
- return V8Proxy::NodeToV8Object(imp->firstChild());
+
+ OwnPtr<ExceptionContext> context(new ExceptionContext());
+ RefPtr<Node> result = treeWalker->firstChild(context.get());
+ if (context->hadException()) {
+ v8::ThrowException(context->exception());
+ return v8::Undefined();
+ }
+ if (!result) return v8::Null();
+ return V8Proxy::NodeToV8Object(result.get());
}
CALLBACK_FUNC_DECL(TreeWalkerLastChild) {
INC_STATS(L"DOM.TreeWalker.lastChild()");
- TreeWalker* imp = V8Proxy::ToNativeObject<TreeWalker>(
+ TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>(
V8ClassIndex::TREEWALKER, args.Holder());
- return V8Proxy::NodeToV8Object(imp->lastChild());
+
+ OwnPtr<ExceptionContext> context(new ExceptionContext());
+ RefPtr<Node> result = treeWalker->lastChild(context.get());
+ if (context->hadException()) {
+ v8::ThrowException(context->exception());
+ return v8::Undefined();
+ }
+ if (!result) return v8::Null();
+ return V8Proxy::NodeToV8Object(result.get());
}
CALLBACK_FUNC_DECL(TreeWalkerNextNode) {
INC_STATS(L"DOM.TreeWalker.nextNode()");
- TreeWalker* imp = V8Proxy::ToNativeObject<TreeWalker>(
+ TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>(
V8ClassIndex::TREEWALKER, args.Holder());
- return V8Proxy::NodeToV8Object(imp->nextNode());
+
+ OwnPtr<ExceptionContext> context(new ExceptionContext());
+ RefPtr<Node> result = treeWalker->nextNode(context.get());
+ if (context->hadException()) {
+ v8::ThrowException(context->exception());
+ return v8::Undefined();
+ }
+ if (!result) return v8::Null();
+ return V8Proxy::NodeToV8Object(result.get());
}
CALLBACK_FUNC_DECL(TreeWalkerPreviousNode) {
INC_STATS(L"DOM.TreeWalker.previousNode()");
- TreeWalker* imp = V8Proxy::ToNativeObject<TreeWalker>(
+ TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>(
V8ClassIndex::TREEWALKER, args.Holder());
- return V8Proxy::NodeToV8Object(imp->previousNode());
+
+ OwnPtr<ExceptionContext> context(new ExceptionContext());
+ RefPtr<Node> result = treeWalker->previousNode(context.get());
+ if (context->hadException()) {
+ v8::ThrowException(context->exception());
+ return v8::Undefined();
+ }
+ if (!result) return v8::Null();
+ return V8Proxy::NodeToV8Object(result.get());
}
CALLBACK_FUNC_DECL(TreeWalkerNextSibling) {
INC_STATS(L"DOM.TreeWalker.nextSibling()");
- TreeWalker* imp = V8Proxy::ToNativeObject<TreeWalker>(
+ TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>(
V8ClassIndex::TREEWALKER, args.Holder());
- return V8Proxy::NodeToV8Object(imp->nextSibling());
+
+ OwnPtr<ExceptionContext> context(new ExceptionContext());
+ RefPtr<Node> result = treeWalker->nextSibling(context.get());
+ if (context->hadException()) {
+ v8::ThrowException(context->exception());
+ return v8::Undefined();
+ }
+ if (!result) return v8::Null();
+ return V8Proxy::NodeToV8Object(result.get());
}
CALLBACK_FUNC_DECL(TreeWalkerPreviousSibling) {
INC_STATS(L"DOM.TreeWalker.previousSibling()");
- TreeWalker* imp = V8Proxy::ToNativeObject<TreeWalker>(
+ TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>(
V8ClassIndex::TREEWALKER, args.Holder());
- return V8Proxy::NodeToV8Object(imp->previousSibling());
+
+ OwnPtr<ExceptionContext> context(new ExceptionContext());
+ RefPtr<Node> result = treeWalker->previousSibling(context.get());
+ if (context->hadException()) {
+ v8::ThrowException(context->exception());
+ return v8::Undefined();
+ }
+ if (!result) return v8::Null();
+ return V8Proxy::NodeToV8Object(result.get());
}
CALLBACK_FUNC_DECL(NodeIteratorNextNode) {
INC_STATS(L"DOM.NodeIterator.nextNode()");
- NodeIterator* imp = V8Proxy::ToNativeObject<NodeIterator>(
+ NodeIterator* nodeIterator = V8Proxy::ToNativeObject<NodeIterator>(
V8ClassIndex::NODEITERATOR, args.Holder());
+
ExceptionCode ec = 0;
- return V8Proxy::NodeToV8Object(imp->nextNode(ec));
+ OwnPtr<ExceptionContext> context(new ExceptionContext());
+ RefPtr<Node> result = nodeIterator->nextNode(context.get(), ec);
+ if (ec != 0) {
+ V8Proxy::SetDOMException(ec);
+ return v8::Null();
+ }
+ if (context->hadException()) {
+ v8::ThrowException(context->exception());
+ return v8::Undefined();
+ }
+ if (!result) return v8::Null();
+ return V8Proxy::NodeToV8Object(result.get());
}
CALLBACK_FUNC_DECL(NodeIteratorPreviousNode) {
INC_STATS(L"DOM.NodeIterator.previousNode()");
- NodeIterator* imp = V8Proxy::ToNativeObject<NodeIterator>(
+ NodeIterator* nodeIterator = V8Proxy::ToNativeObject<NodeIterator>(
V8ClassIndex::NODEITERATOR, args.Holder());
+
ExceptionCode ec = 0;
- return V8Proxy::NodeToV8Object(imp->previousNode(ec));
+ OwnPtr<ExceptionContext> context(new ExceptionContext());
+ RefPtr<Node> result = nodeIterator->previousNode(context.get(), ec);
+ if (ec != 0) {
+ V8Proxy::SetDOMException(ec);
+ return v8::Null();
+ }
+ if (context->hadException()) {
+ v8::ThrowException(context->exception());
+ return v8::Undefined();
+ }
+ if (!result) return v8::Null();
+ return V8Proxy::NodeToV8Object(result.get());
}
CALLBACK_FUNC_DECL(NodeFilterAcceptNode) {
INC_STATS(L"DOM.NodeFilter.acceptNode()");
- NodeFilter* imp = V8Proxy::ToNativeObject<NodeFilter>(
- V8ClassIndex::NODEFILTER, args.Holder());
- Node* node = V8Proxy::DOMWrapperToNode<Node>(args[0]);
- return v8::Local<v8::Integer>(v8::Integer::New(imp->acceptNode(node)));
+ V8Proxy::SetDOMException(NOT_SUPPORTED_ERR);
+ return v8::Undefined();
+}
+
+// NSResolver
+CALLBACK_FUNC_DECL(NSResolverLookupNamespaceURI) {
+ INC_STATS(L"DOM.NSResolver.lookupNamespaceURI()");
+ V8Proxy::SetDOMException(NOT_SUPPORTED_ERR);
+ return v8::Undefined();
}
ACCESSOR_SETTER(DOMWindowEventHandler) {
@@ -3168,6 +3258,21 @@ ACCESSOR_SETTER(HTMLOptionsCollectionLength) {
}
#if ENABLE(SVG)
+
+ACCESSOR_GETTER(SVGLengthValue) {
+ INC_STATS(L"DOM.SVGLength.value");
+ V8SVGPODTypeWrapper<SVGLength>* wrapper = V8Proxy::ToNativeObject<V8SVGPODTypeWrapper<SVGLength> >(V8ClassIndex::SVGLENGTH, info.Holder());
+ SVGLength imp_instance = *wrapper;
+ SVGLength* imp = &imp_instance;
+ return v8::Number::New(imp->value(V8Proxy::GetSVGContext(wrapper)));
+}
+
+CALLBACK_FUNC_DECL(SVGLengthConvertToSpecifiedUnits) {
+ INC_STATS(L"DOM.SVGLength.convertToSpecifiedUnits");
+ V8Proxy::SetDOMException(NOT_SUPPORTED_ERR);
+ return v8::Undefined();
+}
+
CALLBACK_FUNC_DECL(SVGMatrixInverse) {
INC_STATS(L"DOM.SVGMatrix.inverse()");
AffineTransform imp =
@@ -3300,9 +3405,6 @@ NAMED_ACCESS_CHECK(Location) {
#undef INDEXED_ACCESS_CHECK
#undef NAMED_ACCESS_CHECK
-#undef ACCESSOR_GETTER
-#undef ACCESSOR_SETTER
-#undef CALLBACK_FUNC_DECL
#undef NAMED_PROPERTY_GETTER
#undef NAMED_PROPERTY_SETTER
#undef INDEXED_PROPERTY_GETTER
diff --git a/webkit/port/bindings/v8/v8_custom.h b/webkit/port/bindings/v8/v8_custom.h
index dae13ab..6c60e33 100644
--- a/webkit/port/bindings/v8/v8_custom.h
+++ b/webkit/port/bindings/v8/v8_custom.h
@@ -6,9 +6,22 @@
#define V8_CUSTOM_H__
#include <v8.h>
+#include "v8_index.h"
struct NPObject;
+#define CALLBACK_FUNC_DECL(NAME) \
+v8::Handle<v8::Value> V8Custom::v8##NAME##Callback(const v8::Arguments& args)
+
+#define ACCESSOR_GETTER(NAME) \
+v8::Handle<v8::Value> V8Custom::v8##NAME##AccessorGetter(\
+ v8::Local<v8::String> name, const v8::AccessorInfo& info)
+
+#define ACCESSOR_SETTER(NAME) \
+void V8Custom::v8##NAME##AccessorSetter(v8::Local<v8::String> name, \
+ v8::Local<v8::Value> value, \
+ const v8::AccessorInfo& info)
+
namespace WebCore {
class Frame;
@@ -186,6 +199,10 @@ DECLARE_CALLBACK(HTMLDocumentClear)
// Document customized functions
DECLARE_CALLBACK(DocumentEvaluate)
+DECLARE_CALLBACK(DocumentQuerySelector)
+DECLARE_CALLBACK(DocumentQuerySelectorAll)
+DECLARE_CALLBACK(DocumentFragmentQuerySelector)
+DECLARE_CALLBACK(DocumentFragmentQuerySelectorAll)
// Window customized functions
DECLARE_CALLBACK(DOMWindowAddEventListener)
@@ -225,6 +242,23 @@ DECLARE_CALLBACK(CanvasRenderingContext2DSetShadow)
DECLARE_CALLBACK(CanvasRenderingContext2DDrawImage)
DECLARE_CALLBACK(CanvasRenderingContext2DDrawImageFromRect)
DECLARE_CALLBACK(CanvasRenderingContext2DCreatePattern)
+DECLARE_CALLBACK(CanvasRenderingContext2DFillText)
+DECLARE_CALLBACK(CanvasRenderingContext2DStrokeText)
+DECLARE_CALLBACK(CanvasRenderingContext2DPutImageData)
+
+// Console customized functions
+DECLARE_CALLBACK(ConsoleAssert)
+DECLARE_CALLBACK(ConsoleCount)
+DECLARE_CALLBACK(ConsoleDebug)
+DECLARE_CALLBACK(ConsoleDir)
+DECLARE_CALLBACK(ConsoleError)
+DECLARE_CALLBACK(ConsoleGroup)
+DECLARE_CALLBACK(ConsoleInfo)
+DECLARE_CALLBACK(ConsoleLog)
+DECLARE_CALLBACK(ConsoleProfile)
+DECLARE_CALLBACK(ConsoleProfileEnd)
+DECLARE_CALLBACK(ConsoleTimeEnd)
+DECLARE_CALLBACK(ConsoleWarn)
// Implementation of Clipboard methods.
DECLARE_CALLBACK(ClipboardClearData)
@@ -232,6 +266,8 @@ DECLARE_CALLBACK(ClipboardGetData)
DECLARE_CALLBACK(ClipboardSetData)
// Implementation of Element methods.
+DECLARE_CALLBACK(ElementQuerySelector)
+DECLARE_CALLBACK(ElementQuerySelectorAll)
DECLARE_CALLBACK(ElementSetAttribute)
DECLARE_CALLBACK(ElementSetAttributeNode)
DECLARE_CALLBACK(ElementSetAttributeNS)
@@ -243,8 +279,12 @@ DECLARE_CALLBACK(EventTargetNodeAddEventListener)
DECLARE_CALLBACK(EventTargetNodeRemoveEventListener)
// Custom implementation of XMLHttpRequest properties
-DECLARE_PROPERTY_ACCESSOR_SETTER(XMLHttpRequestOnreadystatechange)
-DECLARE_PROPERTY_ACCESSOR_SETTER(XMLHttpRequestOnload)
+DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestOnabort)
+DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestOnerror)
+DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestOnload)
+DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestOnloadstart)
+DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestOnprogress)
+DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestOnreadystatechange)
DECLARE_CALLBACK(XMLHttpRequestAddEventListener)
DECLARE_CALLBACK(XMLHttpRequestRemoveEventListener)
DECLARE_CALLBACK(XMLHttpRequestOpen)
@@ -252,6 +292,17 @@ DECLARE_CALLBACK(XMLHttpRequestSend)
DECLARE_CALLBACK(XMLHttpRequestSetRequestHeader)
DECLARE_CALLBACK(XMLHttpRequestGetResponseHeader)
DECLARE_CALLBACK(XMLHttpRequestOverrideMimeType)
+DECLARE_CALLBACK(XMLHttpRequestDispatchEvent)
+
+// Custom implementation of XMLHttpRequestUpload properties
+DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestUploadOnabort)
+DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestUploadOnerror)
+DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestUploadOnload)
+DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestUploadOnloadstart)
+DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestUploadOnprogress)
+DECLARE_CALLBACK(XMLHttpRequestUploadAddEventListener)
+DECLARE_CALLBACK(XMLHttpRequestUploadRemoveEventListener)
+DECLARE_CALLBACK(XMLHttpRequestUploadDispatchEvent)
// Custom implementation of TreeWalker functions
DECLARE_CALLBACK(TreeWalkerParentNode)
@@ -299,8 +350,13 @@ DECLARE_INDEXED_PROPERTY_SETTER(HTMLOptionsCollection)
DECLARE_INDEXED_PROPERTY_SETTER(HTMLSelectElementCollection)
DECLARE_NAMED_PROPERTY_GETTER(HTMLCollection)
+// NSResolver
+DECLARE_CALLBACK(NSResolverLookupNamespaceURI)
+
// SVG custom properties and callbacks
#if ENABLE(SVG)
+DECLARE_PROPERTY_ACCESSOR_GETTER(SVGLengthValue)
+DECLARE_CALLBACK(SVGLengthConvertToSpecifiedUnits)
DECLARE_CALLBACK(SVGMatrixInverse)
DECLARE_CALLBACK(SVGMatrixRotateFromVector)
#endif
diff --git a/webkit/port/bindings/v8/v8_events.cpp b/webkit/port/bindings/v8/v8_events.cpp
index feb13f53..33bb48f 100644
--- a/webkit/port/bindings/v8/v8_events.cpp
+++ b/webkit/port/bindings/v8/v8_events.cpp
@@ -223,6 +223,11 @@ v8::Local<v8::Object> V8EventListener::GetThisObject(Event* event,
V8ClassIndex::XMLHTTPREQUEST, target->toXMLHttpRequest());
return v8::Local<v8::Object>::New(v8::Handle<v8::Object>::Cast(value));
+ } else if (target->toXMLHttpRequestUpload()) {
+ v8::Handle<v8::Value> value = V8Proxy::ToV8Object(
+ V8ClassIndex::XMLHTTPREQUESTUPLOAD, target->toXMLHttpRequestUpload());
+ return v8::Local<v8::Object>::New(v8::Handle<v8::Object>::Cast(value));
+
} else {
ASSERT(false);
return v8::Local<v8::Object>();
diff --git a/webkit/port/bindings/v8/v8_index.cpp b/webkit/port/bindings/v8/v8_index.cpp
index 4cbe7d9..e731b05 100644
--- a/webkit/port/bindings/v8/v8_index.cpp
+++ b/webkit/port/bindings/v8/v8_index.cpp
@@ -38,6 +38,7 @@
#include "V8CanvasRenderingContext2D.h"
#include "V8CanvasGradient.h"
#include "V8CanvasPattern.h"
+#include "V8CanvasPixelArray.h"
#include "V8CDATASection.h"
#include "V8CharacterData.h"
#include "V8Clipboard.h"
@@ -63,6 +64,8 @@
#include "V8Element.h"
#include "V8Entity.h"
#include "V8EntityReference.h"
+#include "V8File.h"
+#include "V8FileList.h"
#include "V8History.h"
#include "V8HTMLCanvasElement.h"
#include "V8UndetectableHTMLCollection.h"
@@ -127,6 +130,7 @@
#include "V8HTMLTextAreaElement.h"
#include "V8HTMLTitleElement.h"
#include "V8HTMLUListElement.h"
+#include "V8ImageData.h"
#include "V8InspectorController.h"
#include "V8MediaList.h"
#include "V8MessageEvent.h"
@@ -135,6 +139,7 @@
#include "V8NodeList.h"
#include "V8NodeFilter.h"
#include "V8Notation.h"
+#include "V8NSResolver.h"
#include "V8ProcessingInstruction.h"
#include "V8ProgressEvent.h"
#include "V8StyleSheet.h"
@@ -164,6 +169,7 @@
#include "V8RangeException.h"
#include "V8Rect.h"
#include "V8NodeIterator.h"
+#include "V8TextMetrics.h"
#include "V8TreeWalker.h"
#include "V8StyleSheetList.h"
#include "V8DOMImplementation.h"
@@ -172,6 +178,7 @@
#include "V8XPathExpression.h"
#include "V8XPathNSResolver.h"
#include "V8XMLHttpRequest.h"
+#include "V8XMLHttpRequestUpload.h"
#include "V8XMLHttpRequestException.h"
#include "V8XMLSerializer.h"
#include "V8XPathEvaluator.h"
diff --git a/webkit/port/bindings/v8/v8_index.h b/webkit/port/bindings/v8/v8_index.h
index 8ff9d35..0df22e9 100644
--- a/webkit/port/bindings/v8/v8_index.h
+++ b/webkit/port/bindings/v8/v8_index.h
@@ -211,6 +211,7 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)();
V(BARINFO, BarInfo) \
V(CANVASGRADIENT, CanvasGradient) \
V(CANVASPATTERN, CanvasPattern) \
+ V(CANVASPIXELARRAY, CanvasPixelArray) \
V(CANVASRENDERINGCONTEXT2D, CanvasRenderingContext2D) \
V(CLIPBOARD, Clipboard) \
V(CONSOLE, Console) \
@@ -235,10 +236,13 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)();
V(DOMWINDOW, DOMWindow) \
V(EVENT, Event) \
V(EVENTEXCEPTION, EventException) \
+ V(FILE, File) \
+ V(FILELIST, FileList) \
V(HISTORY, History) \
V(UNDETECTABLEHTMLCOLLECTION, UndetectableHTMLCollection) \
V(HTMLCOLLECTION, HTMLCollection) \
V(HTMLOPTIONSCOLLECTION, HTMLOptionsCollection) \
+ V(IMAGEDATA, ImageData) \
V(INSPECTORCONTROLLER, InspectorController) \
V(KEYBOARDEVENT, KeyboardEvent) \
V(LOCATION, Location) \
@@ -253,6 +257,7 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)();
V(NODEFILTER, NodeFilter) \
V(NODEITERATOR, NodeIterator) \
V(NODELIST, NodeList) \
+ V(NSRESOLVER, NSResolver) \
V(OVERFLOWEVENT, OverflowEvent) \
V(PLUGIN, Plugin) \
V(PLUGINARRAY, PluginArray) \
@@ -265,10 +270,12 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)();
V(STYLESHEET, StyleSheet) \
V(STYLESHEETLIST, StyleSheetList) \
V(TEXTEVENT, TextEvent) \
+ V(TEXTMETRICS, TextMetrics) \
V(TREEWALKER, TreeWalker) \
V(UIEVENT, UIEvent) \
V(WHEELEVENT, WheelEvent) \
V(XMLHTTPREQUEST, XMLHttpRequest) \
+ V(XMLHTTPREQUESTUPLOAD, XMLHttpRequestUpload) \
V(XMLHTTPREQUESTEXCEPTION, XMLHttpRequestException) \
V(XMLSERIALIZER, XMLSerializer) \
V(XPATHEVALUATOR, XPathEvaluator) \
diff --git a/webkit/port/bindings/v8/v8_nodefilter.cpp b/webkit/port/bindings/v8/v8_nodefilter.cpp
index c8846ab..3f958e5 100644
--- a/webkit/port/bindings/v8/v8_nodefilter.cpp
+++ b/webkit/port/bindings/v8/v8_nodefilter.cpp
@@ -31,6 +31,7 @@
#include "v8_nodefilter.h"
#include "v8_proxy.h"
+#include "ExceptionContext.h"
#include "NodeFilter.h"
#include "Node.h"
@@ -51,15 +52,17 @@ V8NodeFilterCondition::~V8NodeFilterCondition() {
m_filter.Clear();
}
-short V8NodeFilterCondition::acceptNode(Node* node) const {
+short V8NodeFilterCondition::acceptNode(ExceptionContext* exception_context,
+ Node* node) const {
ASSERT(v8::Context::InContext());
if (!m_filter->IsFunction()) return NodeFilter::FILTER_ACCEPT;
- v8::TryCatch exception_catcher;
+ ExceptionCatcher exception_catcher(exception_context);
v8::Handle<v8::Object> this_obj = v8::Context::GetCurrent()->Global();
- v8::Handle<v8::Function> callback = v8::Handle<v8::Function>::Cast(m_filter);
+ v8::Handle<v8::Function> callback =
+ v8::Handle<v8::Function>::Cast(m_filter);
v8::Handle<v8::Value>* args = new v8::Handle<v8::Value>[1];
args[0] = V8Proxy::ToV8Object(V8ClassIndex::NODE, node);
@@ -70,9 +73,7 @@ short V8NodeFilterCondition::acceptNode(Node* node) const {
proxy->CallFunction(callback, this_obj, 1, args);
delete[] args;
- // TODO(fqian): this code can be removed when issue 1042294 is fixed.
- // See also 1068243.
- if (exception_catcher.HasCaught()) {
+ if (exception_context->hadException()) {
return NodeFilter::FILTER_REJECT;
}
diff --git a/webkit/port/bindings/v8/v8_nodefilter.h b/webkit/port/bindings/v8/v8_nodefilter.h
index cf203eff..ef7906d 100644
--- a/webkit/port/bindings/v8/v8_nodefilter.h
+++ b/webkit/port/bindings/v8/v8_nodefilter.h
@@ -19,7 +19,8 @@ class V8NodeFilterCondition : public NodeFilterCondition {
explicit V8NodeFilterCondition(v8::Handle<v8::Value> filter);
virtual ~V8NodeFilterCondition();
- virtual short acceptNode(Node* node) const;
+ virtual short acceptNode(ExceptionContext* exception_context,
+ Node* node) const;
private:
mutable v8::Persistent<v8::Value> m_filter;
diff --git a/webkit/port/bindings/v8/v8_proxy.cpp b/webkit/port/bindings/v8/v8_proxy.cpp
index 60f0488..ae96b63 100644
--- a/webkit/port/bindings/v8/v8_proxy.cpp
+++ b/webkit/port/bindings/v8/v8_proxy.cpp
@@ -39,7 +39,6 @@
#include "v8_custom.h"
#include "v8_collection.h"
#include "v8_nodefilter.h"
-#include "V8Bridge.h"
#include "RefCounted.h" // for Peerable
@@ -65,6 +64,7 @@
#include "Notation.h"
#include "Text.h"
#include "ProcessingInstruction.h"
+#include "Console.h"
#include "CharacterData.h"
#include "DocumentType.h"
#include "DocumentFragment.h"
@@ -82,6 +82,7 @@
#include "FrameLoader.h"
#include "FrameTree.h"
#include "RangeException.h"
+#include "ScriptController.h"
#include "NodeFilter.h"
#include "SecurityOrigin.h"
#include "XMLHttpRequestException.h"
@@ -97,8 +98,10 @@
#include "XPathEvaluator.h"
#endif
+#undef LOG
#include "base/stats_table.h"
#include "base/trace_event.h"
+#include "webkit/glue/webkit_glue.h"
#include "webkit/glue/glue_util.h"
#include "webkit/glue/webkit_glue.h"
@@ -154,9 +157,10 @@ namespace WebCore {
//
typedef HashMap<v8::Value*, GlobalHandleInfo*> GlobalHandleMap;
-static GlobalHandleMap& global_handle_map() {
- static GlobalHandleMap static_global_handle_map;
- return static_global_handle_map;
+static GlobalHandleMap& global_handle_map()
+{
+ static GlobalHandleMap static_global_handle_map;
+ return static_global_handle_map;
}
@@ -178,12 +182,12 @@ void V8Proxy::RegisterGlobalHandle(GlobalHandleType type, void* host,
}
-void V8Proxy::UnregisterGlobalHandle(void* host,
- v8::Persistent<v8::Value> handle) {
- ASSERT(global_handle_map().contains(*handle));
- GlobalHandleInfo* info = global_handle_map().take(*handle);
- ASSERT(info->host_ == host);
- delete info;
+void V8Proxy::UnregisterGlobalHandle(void* host, v8::Persistent<v8::Value> handle)
+{
+ ASSERT(global_handle_map().contains(*handle));
+ GlobalHandleInfo* info = global_handle_map().take(*handle);
+ ASSERT(info->host_ == host);
+ delete info;
}
#endif // ifndef NDEBUG
@@ -293,13 +297,12 @@ static void WeakSVGElementInstanceCallback(v8::Persistent<v8::Object> obj,
v8::Handle<v8::Value> V8Proxy::SVGElementInstanceToV8Object(
SVGElementInstance* instance) {
- if (!instance) return v8::Null();
+ if (!instance)
+ return v8::Null();
- v8::Handle<v8::Object> existing_instance =
- dom_svg_element_instance_map().get(instance);
- if (!existing_instance.IsEmpty()) {
+ v8::Handle<v8::Object> existing_instance = dom_svg_element_instance_map().get(instance);
+ if (!existing_instance.IsEmpty())
return existing_instance;
- }
instance->ref();
@@ -317,31 +320,34 @@ v8::Handle<v8::Value> V8Proxy::SVGElementInstanceToV8Object(
}
// SVG non-node elements may have a reference to a context node which
-// should be notified when the element is changed
+// should be notified when the element is change
static void WeakSVGObjectWithContext(v8::Persistent<v8::Object> obj,
void* param);
// Map of SVG objects with contexts to V8 objects
-static DOMWrapperMap<Peerable>& dom_svg_object_with_context_map() {
- static DOMPeerableWrapperMap<Peerable>
- static_dom_svg_object_with_context_map(&WeakSVGObjectWithContext);
- return static_dom_svg_object_with_context_map;
+static DOMWrapperMap<Peerable>& dom_svg_object_with_context_map()
+{
+ static DOMPeerableWrapperMap<Peerable>
+ static_dom_svg_object_with_context_map(&WeakSVGObjectWithContext);
+ return static_dom_svg_object_with_context_map;
}
// Map of SVG objects with contexts to their contexts
-static HashMap<void*, SVGElement*>& svg_object_to_context_map() {
- static HashMap<void*, SVGElement*> static_svg_object_to_context_map;
- return static_svg_object_to_context_map;
+static HashMap<void*, SVGElement*>& svg_object_to_context_map()
+{
+ static HashMap<void*, SVGElement*> static_svg_object_to_context_map;
+ return static_svg_object_to_context_map;
}
v8::Handle<v8::Value> V8Proxy::SVGObjectWithContextToV8Object(
- Peerable* object, V8ClassIndex::V8WrapperType type) {
- if (!object) return v8::Null();
+ Peerable* object, V8ClassIndex::V8WrapperType type)
+{
+ if (!object)
+ return v8::Null();
// Special case: SVGPathSegs need to be downcast to their real type
- if (type == V8ClassIndex::SVGPATHSEG) {
+ if (type == V8ClassIndex::SVGPATHSEG)
type = V8Custom::DowncastSVGPathSeg(object);
- }
v8::Persistent<v8::Object> result =
dom_svg_object_with_context_map().get(object);
@@ -372,26 +378,25 @@ static void WeakSVGObjectWithContext(v8::Persistent<v8::Object> obj,
dom_svg_object_with_context_map().forget(dom_obj);
}
-void V8Proxy::SetSVGContext(void* obj, SVGElement* context) {
+void V8Proxy::SetSVGContext(void* obj, SVGElement* context)
+{
SVGElement* old_context = svg_object_to_context_map().get(obj);
- if (old_context == context) {
+ if (old_context == context)
return;
- }
- if (old_context) {
+ if (old_context)
old_context->deref();
- }
- if (context) {
+ if (context)
context->ref();
- }
svg_object_to_context_map().set(obj, context);
}
-SVGElement* V8Proxy::GetSVGContext(void* obj) {
- return svg_object_to_context_map().get(obj);
+SVGElement* V8Proxy::GetSVGContext(void* obj)
+{
+ return svg_object_to_context_map().get(obj);
}
#endif
@@ -409,17 +414,17 @@ static void WeakPeerableCallback(v8::Persistent<v8::Object> obj, void* para) {
dom_object_map().forget(dom_obj);
}
-
-static void WeakNodeCallback(v8::Persistent<v8::Object> obj, void* param) {
+static void WeakNodeCallback(v8::Persistent<v8::Object> obj, void* param)
+{
Node* node = static_cast<Node*>(param);
ASSERT(dom_node_map().contains(node));
dom_node_map().forget(node);
}
-
// Create object groups for DOM tree nodes.
-static void GCPrologue() {
+static void GCPrologue()
+{
#ifndef NDEBUG
// Check that all references in the map are weak.
PeerableMap peer_map = dom_object_map().impl();
@@ -448,9 +453,8 @@ static void GCPrologue() {
!static_cast<HTMLImageElement*>(node)->haveFiredLoadEvent()) ) {
Document* doc = node->document();
v8::Persistent<v8::Object> wrapper = dom_node_map().get(node);
- if (!wrapper.IsEmpty()) {
+ if (!wrapper.IsEmpty())
v8::V8::AddObjectToGroup(doc, wrapper);
- }
}
}
}
@@ -477,20 +481,23 @@ static void GCEpilogue() {
#endif
}
-
// A map from a peerable node to its JS wrapper, the wrapper
// is kept as a strong reference to survive GCs.
-static PeerableMap& gc_protected_map() {
- static PeerableMap static_gc_protected_map;
- return static_gc_protected_map;
+static PeerableMap& gc_protected_map()
+{
+ static PeerableMap static_gc_protected_map;
+ return static_gc_protected_map;
}
-
// static
-void V8Proxy::GCProtect(Peerable* dom_object) {
- if (!dom_object) return;
- if (gc_protected_map().contains(dom_object)) return;
- if (!dom_object->peer()) return;
+void V8Proxy::GCProtect(Peerable* dom_object)
+{
+ if (!dom_object)
+ return;
+ if (gc_protected_map().contains(dom_object))
+ return;
+ if (!dom_object->peer())
+ return;
// Create a new (strong) persistent handle for the peer.
v8::Persistent<v8::Object>
@@ -502,8 +509,10 @@ void V8Proxy::GCProtect(Peerable* dom_object) {
// static
void V8Proxy::GCUnprotect(Peerable* dom_object) {
- if (!dom_object) return;
- if (!gc_protected_map().contains(dom_object)) return;
+ if (!dom_object)
+ return;
+ if (!gc_protected_map().contains(dom_object))
+ return;
// Dispose the strong reference.
v8::Persistent<v8::Object> wrapper(gc_protected_map().take(dom_object));
@@ -535,17 +544,13 @@ class JavaScriptConsoleMessage {
const unsigned m_lineNumber;
};
-
-void JavaScriptConsoleMessage::AddToPage(Page* page) const {
- ASSERT(page);
- Chrome* chrome = page->chrome();
- // Only messages with ErrorMessageLevel are logged when
- // calling Chrome::addMessageToConsole().
- chrome->addMessageToConsole(JSMessageSource, ErrorMessageLevel,
- m_string, m_lineNumber, m_sourceID);
+void JavaScriptConsoleMessage::AddToPage(Page* page) const
+{
+ ASSERT(page);
+ Console* console = page->mainFrame()->domWindow()->console();
+ console->addMessage(JSMessageSource, ErrorMessageLevel, m_string, m_lineNumber, m_sourceID);
}
-
// The ConsoleMessageManager handles all console messages that stem
// from JavaScript. It keeps a list of messages that have been delayed but
// it makes sure to add all messages to the console in the right order.
@@ -590,21 +595,22 @@ void ConsoleMessageManager::AddMessage(
}
-void ConsoleMessageManager::AddDelayedMessage(
- const JavaScriptConsoleMessage& message) {
- if (!m_delayed) {
- // Allocate a vector for the delayed messages. Will be
- // deallocated when the delayed messages are processed
- // in ProcessDelayedMessages().
- m_delayed = new Vector<JavaScriptConsoleMessage>();
- }
- m_delayed->append(message);
+void ConsoleMessageManager::AddDelayedMessage(const JavaScriptConsoleMessage& message)
+{
+ if (!m_delayed)
+ // Allocate a vector for the delayed messages. Will be
+ // deallocated when the delayed messages are processed
+ // in ProcessDelayedMessages().
+ m_delayed = new Vector<JavaScriptConsoleMessage>();
+ m_delayed->append(message);
}
-void ConsoleMessageManager::ProcessDelayedMessages() {
+void ConsoleMessageManager::ProcessDelayedMessages()
+{
// If we have a delayed vector it cannot be empty.
- if (!m_delayed) return;
+ if (!m_delayed)
+ return;
ASSERT(!m_delayed->isEmpty());
// Add the delayed messages to the page of the active
@@ -613,8 +619,10 @@ void ConsoleMessageManager::ProcessDelayedMessages() {
// posting messages. We still deallocate the vector.
Frame* frame = V8Proxy::retrieveActiveFrame();
Page* page = NULL;
- if (frame) page = frame->page();
- if (!page) m_delayed->clear();
+ if (frame)
+ page = frame->page();
+ if (!page)
+ m_delayed->clear();
// Iterate through all the delayed messages and add them
// to the console.
@@ -637,23 +645,25 @@ class ConsoleMessageScope {
~ConsoleMessageScope() { ConsoleMessageManager::ProcessDelayedMessages(); }
};
-
-void log_info(Frame* frame, const String& msg, const String& url) {
- Page* page = frame->page();
- if (!page) return;
- JavaScriptConsoleMessage message(msg, url, 0);
- ConsoleMessageManager::AddMessage(page, message);
+void log_info(Frame* frame, const String& msg, const String& url)
+{
+ Page* page = frame->page();
+ if (!page)
+ return;
+ JavaScriptConsoleMessage message(msg, url, 0);
+ ConsoleMessageManager::AddMessage(page, message);
}
-
static void HandleConsoleMessage(v8::Handle<v8::Message> message,
v8::Handle<v8::Value> data) {
// Use the frame where JavaScript is called from.
Frame* frame = V8Proxy::retrieveActiveFrame();
- if (!frame) return;
+ if (!frame)
+ return;
Page* page = frame->page();
- if (!page) return;
+ if (!page)
+ return;
v8::Handle<v8::String> errorMessageString = message->Get();
ASSERT(!errorMessageString.IsEmpty());
@@ -679,7 +689,8 @@ enum DelayReporting {
static void ReportUnsafeAccessTo(Frame* target, DelayReporting delay) {
ASSERT(target);
Document* targetDocument = target->document();
- if (!targetDocument) return;
+ if (!targetDocument)
+ return;
Frame* source = V8Proxy::retrieveActiveFrame();
Document* sourceDocument = source->document();
@@ -690,8 +701,8 @@ static void ReportUnsafeAccessTo(Frame* target, DelayReporting delay) {
String str = String::format("Unsafe JavaScript attempt to access frame "
"with URL %s from frame with URL %s. Domains, protocols and ports must "
"match.\n",
- targetDocument->url().utf8().data(),
- sourceDocument->url().utf8().data());
+ targetDocument->url().string().utf8().data(),
+ sourceDocument->url().string().utf8().data());
// Build a console message with fake source ID and line number.
const String kSourceID = "";
@@ -713,72 +724,72 @@ static void ReportUnsafeAccessTo(Frame* target, DelayReporting delay) {
}
}
-
static void ReportUnsafeJavaScriptAccess(v8::Local<v8::Object> host,
v8::AccessType type,
v8::Local<v8::Value> data) {
- // Do not report error if the access type is HAS.
- if (type == v8::ACCESS_HAS) return;
+ // Do not report error if the access type is HAS.
+ if (type == v8::ACCESS_HAS)
+ return;
- Frame* target = V8Custom::GetTargetFrame(host, data);
- if (target)
- ReportUnsafeAccessTo(target, REPORT_LATER);
+ Frame* target = V8Custom::GetTargetFrame(host, data);
+ if (target)
+ ReportUnsafeAccessTo(target, REPORT_LATER);
}
-
-static void ReportFatalErrorInV8(const char* location, const char* message) {
- // V8 is shutdown, we cannot use V8 api.
- // The only thing we can do is to disable JavaScript.
- // TODO: clean up V8Proxy and disable JavaScript.
- printf("V8 error: %s (%s)\n", message, location);
+static void ReportFatalErrorInV8(const char* location, const char* message)
+{
+ // V8 is shutdown, we cannot use V8 api.
+ // The only thing we can do is to disable JavaScript.
+ // TODO: clean up V8Proxy and disable JavaScript.
+ printf("V8 error: %s (%s)\n", message, location);
}
-
-static void HandleFatalErrorInV8() {
- // TODO: We temporarily deal with V8 internal error situations
- // such as out-of-memory by crashing the renderer.
- CRASH();
+static void HandleFatalErrorInV8()
+{
+ // TODO: We temporarily deal with V8 internal error situations
+ // such as out-of-memory by crashing the renderer.
+ CRASH();
}
-V8Proxy::~V8Proxy() {
- clear();
- DestroyGlobal();
+V8Proxy::~V8Proxy()
+{
+ clear();
+ DestroyGlobal();
}
-
-void V8Proxy::DestroyGlobal() {
- if (!m_global.IsEmpty()) {
+void V8Proxy::DestroyGlobal()
+{
+ if (!m_global.IsEmpty()) {
#ifndef NDEBUG
- UnregisterGlobalHandle(this, m_global);
+ UnregisterGlobalHandle(this, m_global);
#endif
- m_global.Dispose();
- m_global.Clear();
- }
+ m_global.Dispose();
+ m_global.Clear();
+ }
}
-
-void V8Proxy::SetJSWrapperForDOMObject(Peerable* obj,
- v8::Persistent<v8::Object> wrapper) {
- dom_object_map().set(obj, wrapper);
+void V8Proxy::SetJSWrapperForDOMObject(Peerable* obj, v8::Persistent<v8::Object> wrapper)
+{
+ dom_object_map().set(obj, wrapper);
}
-
-void V8Proxy::SetJSWrapperForDOMNode(Node* node,
- v8::Persistent<v8::Object> wrapper) {
- dom_node_map().set(node, wrapper);
+void V8Proxy::SetJSWrapperForDOMNode(Node* node, v8::Persistent<v8::Object> wrapper)
+{
+ dom_node_map().set(node, wrapper);
}
-
EventListener* V8Proxy::createHTMLEventHandler(const String& functionName,
- const String& code, Node* node) {
- return new V8LazyEventListener(m_frame, code, functionName);
+ const String& code, Node* node)
+{
+ return new V8LazyEventListener(m_frame, code, functionName);
}
#if ENABLE(SVG)
EventListener* V8Proxy::createSVGEventHandler(const String& functionName,
- const String& code, Node* node) {
- return new V8LazyEventListener(m_frame, code, functionName);
+ const String& code, Node* node)
+{
+ return new V8LazyEventListener(m_frame, code, functionName);
}
#endif
@@ -790,7 +801,8 @@ static V8EventListener* FindEventListenerInList(V8EventListenerList& list,
bool html) {
ASSERT(v8::Context::InContext());
- if (!listener->IsObject()) return 0;
+ if (!listener->IsObject())
+ return 0;
V8EventListenerList::iterator p = list.begin();
while (p != list.end()) {
@@ -802,31 +814,31 @@ static V8EventListener* FindEventListenerInList(V8EventListenerList& list,
// check using the == operator on the handles. This is much,
// much faster than calling StrictEquals through the API in
// the negative case.
- if (el->isHTMLEventListener() == html && listener == wrapper) {
- return el;
- }
+ if (el->isHTMLEventListener() == html && listener == wrapper)
+ return el;
++p;
}
return 0;
}
-
// Find an existing wrapper for a JS event listener in the map.
V8EventListener* V8Proxy::FindV8EventListener(v8::Local<v8::Value> listener,
- bool html) {
- return FindEventListenerInList(m_event_listeners, listener, html);
+ bool html)
+{
+ return FindEventListenerInList(m_event_listeners, listener, html);
}
-
-V8EventListener* V8Proxy::FindOrCreateV8EventListener(v8::Local<v8::Value> obj,
- bool html) {
+V8EventListener* V8Proxy::FindOrCreateV8EventListener(v8::Local<v8::Value> obj, bool html)
+{
ASSERT(v8::Context::InContext());
- if (!obj->IsObject()) return 0;
+ if (!obj->IsObject())
+ return 0;
V8EventListener* wrapper =
FindEventListenerInList(m_event_listeners, obj, html);
- if (wrapper) return wrapper;
+ if (wrapper)
+ return wrapper;
// Create a new one, and add to cache.
V8EventListener* new_listener =
@@ -921,63 +933,63 @@ void V8Proxy::DisconnectEventListeners() {
v8::Handle<v8::Script> V8Proxy::CompileScript(v8::Handle<v8::String> code,
const String& fileName,
- int baseLine) {
- const uint16_t* fileNameString = FromWebCoreString(fileName);
- v8::Handle<v8::String> name =
+ int baseLine)
+{
+ const uint16_t* fileNameString = FromWebCoreString(fileName);
+ v8::Handle<v8::String> name =
v8::String::New(fileNameString, fileName.length());
- v8::Handle<v8::Integer> line = v8::Integer::New(baseLine);
- v8::ScriptOrigin origin(name, line);
- v8::Handle<v8::Script> script = v8::Script::Compile(code, &origin);
- return script;
+ v8::Handle<v8::Integer> line = v8::Integer::New(baseLine);
+ v8::ScriptOrigin origin(name, line);
+ v8::Handle<v8::Script> script = v8::Script::Compile(code, &origin);
+ return script;
}
+bool V8Proxy::HandleOutOfMemory()
+{
+ v8::Local<v8::Context> context = v8::Context::GetCurrent();
-bool V8Proxy::HandleOutOfMemory() {
- v8::Local<v8::Context> context = v8::Context::GetCurrent();
-
- if (!context->HasOutOfMemoryException())
- return false;
+ if (!context->HasOutOfMemoryException())
+ return false;
- // Warning, error, disable JS for this frame?
- Frame* frame = V8Proxy::retrieveFrame(context);
+ // Warning, error, disable JS for this frame?
+ Frame* frame = V8Proxy::retrieveFrame(context);
- V8Proxy* proxy = V8Proxy::retrieve(frame);
- // Clean m_context, m_document, and event handlers.
- proxy->clear();
- // Destroy the global object.
- proxy->DestroyGlobal();
+ V8Proxy* proxy = V8Proxy::retrieve(frame);
+ // Clean m_context, m_document, and event handlers.
+ proxy->clear();
+ // Destroy the global object.
+ proxy->DestroyGlobal();
- webkit_glue::NotifyJSOutOfMemory(frame);
+ webkit_glue::NotifyJSOutOfMemory(frame);
- // Disable JS.
- Settings* settings = frame->settings();
- ASSERT(settings);
- settings->setJavaScriptEnabled(false);
+ // Disable JS.
+ Settings* settings = frame->settings();
+ ASSERT(settings);
+ settings->setJavaScriptEnabled(false);
- return true;
+ return true;
}
-
v8::Local<v8::Value> V8Proxy::Evaluate(const String& fileName, int baseLine,
- const String& str, Node* n) {
- ASSERT(v8::Context::InContext());
-
- // Compile the script.
- v8::Local<v8::String> code = v8ExternalString(str);
- TRACE_EVENT_BEGIN("v8.compile", n, "");
- v8::Handle<v8::Script> script = CompileScript(code, fileName, baseLine);
- TRACE_EVENT_END("v8.compile", n, "");
-
- // Set inlineCode to true for <a href="javascript:doSomething()">
- // and false for <script>doSomething</script>. For some reason, fileName
- // gives us this information.
- TRACE_EVENT_BEGIN("v8.run", n, "");
- v8::Local<v8::Value> result = RunScript(script, fileName.isNull());
- TRACE_EVENT_END("v8.run", n, "");
- return result;
+ const String& str, Node* n)
+{
+ ASSERT(v8::Context::InContext());
+
+ // Compile the script.
+ v8::Local<v8::String> code = v8ExternalString(str);
+ TRACE_EVENT_BEGIN("v8.compile", n, "");
+ v8::Handle<v8::Script> script = CompileScript(code, fileName, baseLine);
+ TRACE_EVENT_END("v8.compile", n, "");
+
+ // Set inlineCode to true for <a href="javascript:doSomething()">
+ // and false for <script>doSomething</script>. For some reason, fileName
+ // gives us this information.
+ TRACE_EVENT_BEGIN("v8.run", n, "");
+ v8::Local<v8::Value> result = RunScript(script, fileName.isNull());
+ TRACE_EVENT_END("v8.run", n, "");
+ return result;
}
-
v8::Local<v8::Value> V8Proxy::RunScript(v8::Handle<v8::Script> script,
bool inline_code) {
if (script.IsEmpty())
@@ -1293,6 +1305,14 @@ v8::Persistent<v8::FunctionTemplate> V8Proxy::GetTemplate(
desc->SetCallHandler(USE_CALLBACK(XMLHttpRequestConstructor));
break;
}
+ case V8ClassIndex::XMLHTTPREQUESTUPLOAD: {
+ // Reserve one more internal field for keeping event listeners.
+ v8::Local<v8::ObjectTemplate> instance_template =
+ desc->InstanceTemplate();
+ instance_template->SetInternalFieldCount(
+ V8Custom::kXMLHttpRequestInternalFieldCount);
+ break;
+ }
case V8ClassIndex::XPATHEVALUATOR:
desc->SetCallHandler(USE_CALLBACK(XPathEvaluatorConstructor));
break;
@@ -1307,141 +1327,144 @@ v8::Persistent<v8::FunctionTemplate> V8Proxy::GetTemplate(
return desc;
}
-
-bool V8Proxy::ContextInitialized() {
- return !m_context.IsEmpty();
+bool V8Proxy::ContextInitialized()
+{
+ return !m_context.IsEmpty();
}
-
-DOMWindow* V8Proxy::retrieveWindow() {
- // TODO: This seems very fragile. How do we know that the global object
- // from the current context is something sensible? Do we need to use the
- // last entered here? Who calls this?
- v8::Handle<v8::Object> global = v8::Context::GetCurrent()->Global();
- if (global.IsEmpty()) return 0;
- v8::Handle<v8::Value> window = global->GetPrototype();
- return ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, window);
+DOMWindow* V8Proxy::retrieveWindow()
+{
+ // TODO: This seems very fragile. How do we know that the global object
+ // from the current context is something sensible? Do we need to use the
+ // last entered here? Who calls this?
+ v8::Handle<v8::Object> global = v8::Context::GetCurrent()->Global();
+ if (global.IsEmpty())
+ return 0;
+ v8::Handle<v8::Value> window = global->GetPrototype();
+ return ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, window);
}
-
-Frame* V8Proxy::retrieveFrame(v8::Handle<v8::Context> context) {
- v8::Handle<v8::Object> global = context->Global();
- v8::Handle<v8::Value> window_peer = global->GetPrototype();
- DOMWindow* window =
- ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, window_peer);
- return window->frame();
+Frame* V8Proxy::retrieveFrame(v8::Handle<v8::Context> context)
+{
+ v8::Handle<v8::Object> global = context->Global();
+ v8::Handle<v8::Value> window_peer = global->GetPrototype();
+ DOMWindow* window = ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, window_peer);
+ return window->frame();
}
-
-Frame* V8Proxy::retrieveActiveFrame() {
- v8::Handle<v8::Context> context = v8::Context::GetEntered();
- if (context.IsEmpty())
- return 0;
- return retrieveFrame(context);
+Frame* V8Proxy::retrieveActiveFrame()
+{
+ v8::Handle<v8::Context> context = v8::Context::GetEntered();
+ if (context.IsEmpty())
+ return 0;
+ return retrieveFrame(context);
}
-
-Frame* V8Proxy::retrieveFrame() {
- DOMWindow* window = retrieveWindow();
- return window ? window->frame() : 0;
+Frame* V8Proxy::retrieveFrame()
+{
+ DOMWindow* window = retrieveWindow();
+ return window ? window->frame() : 0;
}
-
-V8Proxy* V8Proxy::retrieve() {
- DOMWindow* window = retrieveWindow();
- ASSERT(window);
- return retrieve(window->frame());
+V8Proxy* V8Proxy::retrieve()
+{
+ DOMWindow* window = retrieveWindow();
+ ASSERT(window);
+ return retrieve(window->frame());
}
-
-V8Proxy* V8Proxy::retrieve(Frame* frame) {
- if (!frame) return 0;
- V8Bridge* bridge = static_cast<V8Bridge*>(frame->scriptBridge());
- return bridge->isEnabled() ? bridge->proxy() : 0;
+V8Proxy* V8Proxy::retrieve(Frame* frame)
+{
+ if (!frame)
+ return 0;
+ return frame->script()->isEnabled() ? frame->script()->proxy() : 0;
}
+void V8Proxy::disconnectFrame()
+{
+ // disconnect all event listeners
+ DisconnectEventListeners();
-void V8Proxy::disconnectFrame() {
- // disconnect all event listeners
- DisconnectEventListeners();
-
- // clear all timeouts.
- if (m_frame->domWindow())
- m_frame->domWindow()->clearAllTimeouts();
-}
-
-bool V8Proxy::isEnabled() {
- Settings* settings = m_frame->settings();
- if (!settings)
- return false;
-
- // In the common case, JavaScript is enabled and we're done.
- if (settings->isJavaScriptEnabled())
- return true;
-
- // If JavaScript has been disabled, we need to look at the frame to tell
- // whether this script came from the web or the embedder. Scripts from the
- // embedder are safe to run, but scripts from the other sources are
- // disallowed.
- Document* document = m_frame->document();
- if (!document)
- return false;
-
- SecurityOrigin* origin = document->securityOrigin();
- if (origin->protocol().isEmpty())
- return false; // Uninitialized document
-
- if (origin->protocol() == "http" || origin->protocol() == "https")
- return false; // Web site
-
- if (origin->protocol() ==
- webkit_glue::StdStringToString(webkit_glue::GetUIResourceProtocol()))
- return true; // Embedder's scripts are ok to run
-
- // If the scheme is ftp: or file:, an empty file name indicates a directory
- // listing, which requires JavaScript to function properly.
- const char* kDirProtocols[] = { "ftp", "file" };
- GURL url(document->url().utf8().data());
- for (size_t i = 0; i < arraysize(kDirProtocols); ++i) {
- if (origin->protocol() == kDirProtocols[i]) {
- ASSERT(url.SchemeIs(kDirProtocols[i]));
- return url.ExtractFileName().empty();
+ // clear all timeouts.
+ if (m_frame->domWindow())
+ m_frame->domWindow()->clearAllTimeouts();
+}
+
+bool V8Proxy::isEnabled()
+{
+ Settings* settings = m_frame->settings();
+ if (!settings)
+ return false;
+
+ // In the common case, JavaScript is enabled and we're done.
+ if (settings->isJavaScriptEnabled())
+ return true;
+
+ // If JavaScript has been disabled, we need to look at the frame to tell
+ // whether this script came from the web or the embedder. Scripts from the
+ // embedder are safe to run, but scripts from the other sources are
+ // disallowed.
+ Document* document = m_frame->document();
+ if (!document)
+ return false;
+
+ SecurityOrigin* origin = document->securityOrigin();
+ if (origin->protocol().isEmpty())
+ return false; // Uninitialized document
+
+ if (origin->protocol() == "http" || origin->protocol() == "https")
+ return false; // Web site
+
+ if (origin->protocol() == webkit_glue::StdStringToString(webkit_glue::GetUIResourceProtocol()))
+ return true; // Embedder's scripts are ok to run
+
+ // If the scheme is ftp: or file:, an empty file name indicates a directory
+ // listing, which requires JavaScript to function properly.
+ const char* kDirProtocols[] = { "ftp", "file" };
+ GURL url = webkit_glue::KURLToGURL(document->url());
+ for (size_t i = 0; i < arraysize(kDirProtocols); ++i) {
+ if (origin->protocol() == kDirProtocols[i]) {
+ ASSERT(url.SchemeIs(kDirProtocols[i]));
+ return url.ExtractFileName().empty();
+ }
}
- }
- return false; // Other protocols fall through to here
+ return false; // Other protocols fall through to here
}
+void V8Proxy::clearDocumentWrapper()
+{
+ v8::HandleScope handle_scope;
+ v8::Local<v8::Context> context = GetContext();
+ if (context.IsEmpty())
+ return; // not initialize yet
-void V8Proxy::clearDocumentWrapper() {
- v8::HandleScope handle_scope;
- v8::Local<v8::Context> context = GetContext();
- if (context.IsEmpty()) return; // not initialize yet
-
- if (!m_document.IsEmpty()) {
+ if (!m_document.IsEmpty()) {
#ifndef NDEBUG
- UnregisterGlobalHandle(this, m_document);
+ UnregisterGlobalHandle(this, m_document);
#endif
- m_document.Dispose();
- m_document.Clear();
- }
+ m_document.Dispose();
+ m_document.Clear();
+ }
}
-
// static
-void V8Proxy::DomainChanged(Frame* frame) {
- V8Proxy* proxy = retrieve(frame);
- proxy->ClearSecurityToken();
+void V8Proxy::DomainChanged(Frame* frame)
+{
+ V8Proxy* proxy = retrieve(frame);
+ proxy->ClearSecurityToken();
}
-
-void V8Proxy::ClearSecurityToken() {
- m_context->SetSecurityToken(m_global);
+void V8Proxy::ClearSecurityToken()
+{
+ m_context->SetSecurityToken(m_global);
}
+void V8Proxy::clear()
+{
+ if (m_context.IsEmpty())
+ return;
-void V8Proxy::clear() {
- if (!m_context.IsEmpty()) {
ClearSecurityToken();
if (m_frame->domWindow())
@@ -1452,68 +1475,55 @@ void V8Proxy::clear() {
// Corresponds to the context creation in initContextIfNeeded().
m_context.Dispose();
m_context.Clear();
- }
}
-
// Check if two frames are from the same origin.
// This function is equivalent to
// KJS::Window::allowsAccessFrom(const JSGlobalObject*,
// SecurityOrigin::Reason&, String& message) const.
-static bool SameOrigin(Frame* source, Frame* target,
- SecurityOrigin::Reason& reason, String& message) {
- if (!source) {
- reason = SecurityOrigin::GenericMismatch;
- return false;
- }
+static bool SameOrigin(Frame* source, Frame* target, String& message)
+{
+ if (!source || !target)
+ return false;
- if (!target) {
- reason = SecurityOrigin::GenericMismatch;
- return false;
- }
-
- // Allow access if the frames the windows represent are the same.
- if (source == target)
- return true;
+ // Allow access if the frames the windows represent are the same.
+ if (source == target)
+ return true;
- Document* target_document = target->document();
+ Document* target_document = target->document();
- // JS may be attempting to access the "window" object, which should be valid,
- // even if the document hasn't been constructed yet. If the document doesn't
- // exist yet allow JS to access the window object.
- if (!target_document)
- return true;
+ // JS may be attempting to access the "window" object, which should be valid,
+ // even if the document hasn't been constructed yet. If the document doesn't
+ // exist yet allow JS to access the window object.
+ if (!target_document)
+ return true;
- Document* act_document = source->document();
+ Document* act_document = source->document();
- const SecurityOrigin* active_security_origin = act_document->securityOrigin();
- const SecurityOrigin* target_security_origin =
- target_document->securityOrigin();
+ const SecurityOrigin* active_security_origin = act_document->securityOrigin();
+ const SecurityOrigin* target_security_origin = target_document->securityOrigin();
- String ui_resource_protocol =
- webkit_glue::StdStringToString(webkit_glue::GetUIResourceProtocol());
- if (active_security_origin->protocol() == ui_resource_protocol) {
- KURL inspector_url =
- webkit_glue::GURLToKURL(webkit_glue::GetInspectorURL());
- ASSERT(inspector_url.protocol() == ui_resource_protocol);
- ASSERT(inspector_url.protocol().endsWith("-resource"));
+ String ui_resource_protocol = webkit_glue::StdStringToString(webkit_glue::GetUIResourceProtocol());
+ if (active_security_origin->protocol() == ui_resource_protocol) {
+ KURL inspector_url = webkit_glue::GURLToKURL(webkit_glue::GetInspectorURL());
+ ASSERT(inspector_url.protocol() == ui_resource_protocol);
+ ASSERT(inspector_url.protocol().endsWith("-resource"));
- // The Inspector can access anything.
- if (active_security_origin->host() == inspector_url.host())
- return true;
+ // The Inspector can access anything.
+ if (active_security_origin->host() == inspector_url.host())
+ return true;
- // To mitigate XSS vulnerabilities on the browser itself, UI resources
- // besides the Inspector can't access other documents.
- return false;
- }
+ // To mitigate XSS vulnerabilities on the browser itself, UI resources
+ // besides the Inspector can't access other documents.
+ return false;
+ }
- if (active_security_origin->canAccess(target_security_origin, reason))
- return true;
+ if (active_security_origin->canAccess(target_security_origin))
+ return true;
- return false;
+ return false;
}
-
// Check if the current execution context can access a target frame.
// First it checks same domain policy using the security context
// (where the script is invoked), if domain check failed due to
@@ -1521,54 +1531,49 @@ static bool SameOrigin(Frame* source, Frame* target,
// to check domain policy.
//
// This is equivalent to KJS::Window::allowsAccessFrom(ExecState*, String&).
-bool V8Proxy::CanAccess(Frame* target) {
- SecurityOrigin::Reason reason;
- String message;
-
- // Check dynamic (security) context first.
- Frame* source =
- V8Proxy::retrieveFrame(v8::Context::GetCurrentSecurityContext());
- if (SameOrigin(source, target, reason, message)) {
- return true;
- }
+bool V8Proxy::CanAccess(Frame* target)
+{
+ String message;
+
+ // Check dynamic (security) context first.
+ Frame* source = V8Proxy::retrieveFrame(v8::Context::GetCurrentSecurityContext());
+ if (SameOrigin(source, target, message))
+ return true;
- // Check lexical orgin if the reason is DomainSetInDOM mismatch.
- if (reason == SecurityOrigin::DomainSetInDOMMismatch) {
source = V8Proxy::retrieveFrame(v8::Context::GetCurrent());
- if (SameOrigin(source, target, reason, message)) {
- return true;
- }
- }
+ if (SameOrigin(source, target, message))
+ return true;
- return false;
+ return false;
}
+bool V8Proxy::IsFromSameOrigin(Frame* target, bool report_error)
+{
+ // The subject is detached from a frame, deny accesses.
+ if (!target)
+ return false;
-bool V8Proxy::IsFromSameOrigin(Frame* target, bool report_error) {
- // The subject is detached from a frame, deny accesses.
- if (!target) return false;
-
- if (!CanAccess(target)) {
- if (report_error) ReportUnsafeAccessTo(target, REPORT_NOW);
- return false;
- }
- return true;
+ if (!CanAccess(target)) {
+ if (report_error)
+ ReportUnsafeAccessTo(target, REPORT_NOW);
+ return false;
+ }
+ return true;
}
+bool V8Proxy::CheckNodeSecurity(Node* node)
+{
+ if (!node)
+ return false;
-bool V8Proxy::CheckNodeSecurity(Node* node) {
- if (!node)
- return false;
+ Frame* target = node->document()->frame();
- Frame* target = node->document()->frame();
+ if (!target)
+ return false;
- if (!target)
- return false;
-
- return IsFromSameOrigin(target, true);
+ return IsFromSameOrigin(target, true);
}
-
// Create a new environment and setup the global object.
//
// The global object corresponds to a DOMWindow instance. However, to
@@ -1582,9 +1587,11 @@ bool V8Proxy::CheckNodeSecurity(Node* node) {
// from javascript. The javascript object that corresponds to a
// DOMWindow instance is the shadow object. When mapping a DOMWindow
// instance to a V8 object, we return the shadow object.
-void V8Proxy::initContextIfNeeded() {
+void V8Proxy::initContextIfNeeded()
+{
// Bail out if the context has already been initialized.
- if (!m_context.IsEmpty()) return;
+ if (!m_context.IsEmpty())
+ return;
// Install counters handler with V8.
static bool v8_counters_initialized = false;
@@ -1619,7 +1626,8 @@ void V8Proxy::initContextIfNeeded() {
return;
// Install a security handler with V8.
- { v8::Local<v8::External> external =
+ {
+ v8::Local<v8::External> external =
v8::External::New(reinterpret_cast<void*>(V8ClassIndex::DOMWINDOW));
if (external.IsEmpty())
return;
@@ -1674,7 +1682,7 @@ void V8Proxy::initContextIfNeeded() {
V8Proxy::retrieveFrame(context)->loader()->dispatchWindowObjectAvailable();
- if (JSBridge::RecordPlaybackMode()) {
+ if (ScriptController::RecordPlaybackMode()) {
// Inject code which overrides a few common JS functions for implementing
// randomness. In order to implement effective record & playback of
// websites, it is important that the URLs not change. Many popular web
@@ -1721,13 +1729,10 @@ v8::Handle<v8::Value> V8Proxy::GenerateSecurityToken(
}
-void V8Proxy::SetDOMException(int exception_code) {
- if (exception_code <= 0) return;
-
- if (exception_code == XMLHttpRequestException::PERMISSION_DENIED) {
- ThrowError(GENERAL_ERROR, "Permission denied");
- return;
- }
+void V8Proxy::SetDOMException(int exception_code)
+{
+ if (exception_code <= 0)
+ return;
ExceptionCodeDescription description;
getExceptionCodeDescription(exception_code, description);
@@ -1736,30 +1741,30 @@ void V8Proxy::SetDOMException(int exception_code) {
switch (description.type) {
case DOMExceptionType:
exception = ToV8Object(V8ClassIndex::DOMCOREEXCEPTION,
- new DOMCoreException(description));
+ DOMCoreException::create(description));
break;
case RangeExceptionType:
exception = ToV8Object(V8ClassIndex::RANGEEXCEPTION,
- new RangeException(description));
+ RangeException::create(description));
break;
case EventExceptionType:
exception = ToV8Object(V8ClassIndex::EVENTEXCEPTION,
- new EventException(description));
+ EventException::create(description));
break;
case XMLHttpRequestExceptionType:
exception = ToV8Object(V8ClassIndex::XMLHTTPREQUESTEXCEPTION,
- new XMLHttpRequestException(description));
+ XMLHttpRequestException::create(description));
break;
#if ENABLE(SVG)
case SVGExceptionType:
exception = ToV8Object(V8ClassIndex::SVGEXCEPTION,
- new SVGException(description));
+ SVGException::create(description));
break;
#endif
#if ENABLE(XPATH)
case XPathExceptionType:
exception = ToV8Object(V8ClassIndex::XPATHEXCEPTION,
- new XPathException(description));
+ XPathException::create(description));
break;
#endif
}
@@ -1768,8 +1773,8 @@ void V8Proxy::SetDOMException(int exception_code) {
v8::ThrowException(exception);
}
-
-v8::Handle<v8::Value> V8Proxy::ThrowError(ErrorType type, const char* message) {
+v8::Handle<v8::Value> V8Proxy::ThrowError(ErrorType type, const char* message)
+{
switch (type) {
case RANGE_ERROR:
return v8::ThrowException(v8::Exception::RangeError(v8String(message)));
@@ -1788,24 +1793,23 @@ v8::Handle<v8::Value> V8Proxy::ThrowError(ErrorType type, const char* message) {
}
}
+v8::Local<v8::Context> V8Proxy::GetContext(Frame* frame)
+{
+ V8Proxy* proxy = retrieve(frame);
+ if (!proxy)
+ return v8::Local<v8::Context>();
-v8::Local<v8::Context> V8Proxy::GetContext(Frame* frame) {
- V8Proxy* proxy = retrieve(frame);
- if (!proxy)
- return v8::Local<v8::Context>();
-
- proxy->initContextIfNeeded();
- return proxy->GetContext();
+ proxy->initContextIfNeeded();
+ return proxy->GetContext();
}
-
-v8::Local<v8::Context> V8Proxy::GetCurrentContext() {
- return v8::Context::GetCurrent();
+v8::Local<v8::Context> V8Proxy::GetCurrentContext()
+{
+ return v8::Context::GetCurrent();
}
-
-v8::Handle<v8::Value> V8Proxy::ToV8Object(V8ClassIndex::V8WrapperType type,
- void* imp) {
+v8::Handle<v8::Value> V8Proxy::ToV8Object(V8ClassIndex::V8WrapperType type, void* imp)
+{
ASSERT(type != V8ClassIndex::EVENTLISTENER);
ASSERT(type != V8ClassIndex::EVENTTARGET);
ASSERT(type != V8ClassIndex::EVENT);
@@ -1830,13 +1834,9 @@ v8::Handle<v8::Value> V8Proxy::ToV8Object(V8ClassIndex::V8WrapperType type,
return WindowToV8Object(static_cast<DOMWindow*>(imp));
#if ENABLE(SVG)
SVGNONNODE_WRAPPER_TYPES(MAKE_CASE)
- if (type == V8ClassIndex::SVGELEMENTINSTANCE) {
- return SVGElementInstanceToV8Object(
- static_cast<SVGElementInstance*>(imp));
- } else {
- return SVGObjectWithContextToV8Object(static_cast<Peerable*>(imp),
- type);
- }
+ if (type == V8ClassIndex::SVGELEMENTINSTANCE)
+ return SVGElementInstanceToV8Object(static_cast<SVGElementInstance*>(imp));
+ return SVGObjectWithContextToV8Object(static_cast<Peerable*>(imp), type);
#endif
default:
break;
@@ -1876,29 +1876,28 @@ v8::Handle<v8::Value> V8Proxy::ToV8Object(V8ClassIndex::V8WrapperType type,
void V8Proxy::SetHiddenWindowReference(Frame* frame,
const int internal_index,
v8::Handle<v8::Object> jsobj) {
- // Get DOMWindow
- if (!frame) return; // Object might be detached from window
- v8::Handle<v8::Context> context = GetContext(frame);
- if (context.IsEmpty()) return;
+ // Get DOMWindow
+ if (!frame) return; // Object might be detached from window
+ v8::Handle<v8::Context> context = GetContext(frame);
+ if (context.IsEmpty()) return;
- ASSERT(internal_index < V8Custom::kDOMWindowInternalFieldCount);
+ ASSERT(internal_index < V8Custom::kDOMWindowInternalFieldCount);
- v8::Handle<v8::Object> global = context->Global();
- ASSERT(!global.IsEmpty());
- // Look for real DOM wrapper.
- global = LookupDOMWrapper(V8ClassIndex::DOMWINDOW, global);
- ASSERT(global->GetInternalField(internal_index)->IsUndefined());
- global->SetInternalField(internal_index, jsobj);
+ v8::Handle<v8::Object> global = context->Global();
+ ASSERT(!global.IsEmpty());
+ // Look for real DOM wrapper.
+ global = LookupDOMWrapper(V8ClassIndex::DOMWINDOW, global);
+ ASSERT(global->GetInternalField(internal_index)->IsUndefined());
+ global->SetInternalField(internal_index, jsobj);
}
-V8ClassIndex::V8WrapperType V8Proxy::GetDOMWrapperType(
- v8::Handle<v8::Object> object) {
+V8ClassIndex::V8WrapperType V8Proxy::GetDOMWrapperType(v8::Handle<v8::Object> object)
+{
ASSERT(MaybeDOMWrapper(object));
-
v8::Handle<v8::Value> type =
object->GetInternalField(V8Custom::kDOMWrapperTypeIndex);
- return V8ClassIndex::FromInt(type->Int32Value());
+ return V8ClassIndex::FromInt(type->Int32Value());
}
@@ -1935,36 +1934,39 @@ void* V8Proxy::ToNativeObjectImpl(V8ClassIndex::V8WrapperType type,
return DOMWrapperToNative<Peerable>(object);
}
-
v8::Handle<v8::Object> V8Proxy::LookupDOMWrapper(
- V8ClassIndex::V8WrapperType type, v8::Handle<v8::Value> value) {
- if (value.IsEmpty()) return v8::Handle<v8::Object>();
-
- v8::Handle<v8::FunctionTemplate> desc = V8Proxy::GetTemplate(type);
- while (value->IsObject()) {
- v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value);
- if (desc->HasInstance(object))
- return object;
-
- value = object->GetPrototype();
- }
- return v8::Handle<v8::Object>();
+ V8ClassIndex::V8WrapperType type, v8::Handle<v8::Value> value)
+{
+ if (value.IsEmpty())
+ return v8::Handle<v8::Object>();
+
+ v8::Handle<v8::FunctionTemplate> desc = V8Proxy::GetTemplate(type);
+ while (value->IsObject()) {
+ v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value);
+ if (desc->HasInstance(object))
+ return object;
+
+ value = object->GetPrototype();
+ }
+ return v8::Handle<v8::Object>();
}
-NodeFilter* V8Proxy::ToNativeNodeFilter(v8::Handle<v8::Value> filter) {
- // A NodeFilter is used when walking through a DOM tree or iterating tree
- // nodes.
- // TODO: we may want to cache NodeFilterCondition and NodeFilter
- // object, but it is minor.
- // NodeFilter is passed to NodeIterator that has a ref counted pointer
- // to NodeFilter. NodeFilter has a ref counted pointer to NodeFilterCondition.
- // In NodeFilterCondition, filter object is persisted in its constructor,
- // and disposed in its destructor. No need to use peer field in this case.
- if (!filter->IsFunction()) return 0;
+PassRefPtr<NodeFilter> V8Proxy::ToNativeNodeFilter(v8::Handle<v8::Value> filter)
+{
+ // A NodeFilter is used when walking through a DOM tree or iterating tree
+ // nodes.
+ // TODO: we may want to cache NodeFilterCondition and NodeFilter
+ // object, but it is minor.
+ // NodeFilter is passed to NodeIterator that has a ref counted pointer
+ // to NodeFilter. NodeFilter has a ref counted pointer to NodeFilterCondition.
+ // In NodeFilterCondition, filter object is persisted in its constructor,
+ // and disposed in its destructor. No need to use peer field in this case.
+ if (!filter->IsFunction())
+ return 0;
- NodeFilterCondition* cond = new V8NodeFilterCondition(filter);
- return new NodeFilter(cond);
+ NodeFilterCondition* cond = new V8NodeFilterCondition(filter);
+ return NodeFilter::create(cond);
}
@@ -1981,9 +1983,8 @@ v8::Local<v8::Object> V8Proxy::InstantiateV8Object(
// Special case for HTMLInputElements that support selection.
if (desc_type == V8ClassIndex::HTMLINPUTELEMENT) {
HTMLInputElement* element = static_cast<HTMLInputElement*>(imp);
- if (element->canHaveSelection()) {
+ if (element->canHaveSelection())
desc_type = V8ClassIndex::HTMLSELECTIONINPUTELEMENT;
- }
}
v8::Persistent<v8::FunctionTemplate> desc = GetTemplate(desc_type);
@@ -1996,15 +1997,14 @@ v8::Local<v8::Object> V8Proxy::InstantiateV8Object(
return instance;
}
-v8::Handle<v8::Value> V8Proxy::CheckNewLegal(const v8::Arguments& args) {
- if (!AllowAllocation::m_current) {
- return ThrowError(TYPE_ERROR, "Illegal constructor");
- } else {
+v8::Handle<v8::Value> V8Proxy::CheckNewLegal(const v8::Arguments& args)
+{
+ if (!AllowAllocation::m_current)
+ return ThrowError(TYPE_ERROR, "Illegal constructor");
+
return args.This();
- }
}
-
void V8Proxy::SetDOMWrapper(v8::Handle<v8::Object> obj, int type, void* cptr) {
ASSERT(obj->InternalFieldCount() >= 2);
obj->SetInternalField(V8Custom::kDOMWrapperObjectIndex, WrapCPointer(cptr));
@@ -2144,7 +2144,8 @@ FOR_EACH_TAG(ADD_TO_HASH_MAP)
}
V8ClassIndex::V8WrapperType t = map.get(element->localName().impl());
- if (t == 0) return V8ClassIndex::HTMLELEMENT;
+ if (t == 0)
+ return V8ClassIndex::HTMLELEMENT;
return t;
}
#undef FOR_EACH_TAG
@@ -2274,13 +2275,14 @@ FOR_EACH_TAG(ADD_TO_HASH_MAP)
#endif // ENABLE(SVG)
-v8::Handle<v8::Value> V8Proxy::EventToV8Object(Event* event) {
- if (!event) return v8::Null();
+v8::Handle<v8::Value> V8Proxy::EventToV8Object(Event* event)
+{
+ if (!event)
+ return v8::Null();
v8::Handle<v8::Object> peer = dom_object_map().get(event);
- if (!peer.IsEmpty()) {
+ if (!peer.IsEmpty())
return peer;
- }
V8ClassIndex::V8WrapperType type = V8ClassIndex::EVENT;
@@ -2324,24 +2326,22 @@ v8::Handle<v8::Value> V8Proxy::NodeToV8Object(Node* node) {
if (!node) return v8::Null();
v8::Handle<v8::Object> peer = dom_node_map().get(node);
- if (!peer.IsEmpty()) {
+ if (!peer.IsEmpty())
return peer;
- }
bool is_document = false; // document type node has special handling
V8ClassIndex::V8WrapperType type;
switch (node->nodeType()) {
case Node::ELEMENT_NODE:
- if (node->isHTMLElement()) {
+ if (node->isHTMLElement())
type = GetHTMLElementType(static_cast<HTMLElement*>(node));
#if ENABLE(SVG)
- } else if (node->isSVGElement()) {
+ else if (node->isSVGElement())
type = GetSVGElementType(static_cast<SVGElement*>(node));
#endif
- } else {
+ else
type = V8ClassIndex::ELEMENT;
- }
break;
case Node::ATTRIBUTE_NODE:
type = V8ClassIndex::ATTR;
@@ -2364,15 +2364,14 @@ v8::Handle<v8::Value> V8Proxy::NodeToV8Object(Node* node) {
case Node::DOCUMENT_NODE: {
is_document = true;
Document* doc = static_cast<Document*>(node);
- if (doc->isHTMLDocument()) {
+ if (doc->isHTMLDocument())
type = V8ClassIndex::HTMLDOCUMENT;
#if ENABLE(SVG)
- } else if (doc->isSVGDocument()) {
+ else if (doc->isSVGDocument())
type = V8ClassIndex::SVGDOCUMENT;
#endif
- } else {
+ else
type = V8ClassIndex::DOCUMENT;
- }
break;
}
case Node::DOCUMENT_TYPE_NODE:
@@ -2408,9 +2407,8 @@ v8::Handle<v8::Value> V8Proxy::NodeToV8Object(Node* node) {
if (is_document) {
Document* doc = static_cast<Document*>(node);
V8Proxy* proxy = V8Proxy::retrieve(doc->frame());
- if (proxy) {
+ if (proxy)
proxy->UpdateDocumentHandle(result);
- }
if (type == V8ClassIndex::HTMLDOCUMENT) {
// Create marker object and insert it in two internal fields.
@@ -2447,16 +2445,20 @@ void V8Proxy::UpdateDocumentHandle(v8::Local<v8::Object> handle) {
// A JS object of type EventTarget can only be two possible types:
// 1) EventTargetNode; 2) XMLHttpRequest;
-v8::Handle<v8::Value> V8Proxy::EventTargetToV8Object(EventTarget* target) {
- if (!target) return v8::Null();
+v8::Handle<v8::Value> V8Proxy::EventTargetToV8Object(EventTarget* target)
+{
+ if (!target)
+ return v8::Null();
#if ENABLE(SVG)
SVGElementInstance* instance = target->toSVGElementInstance();
- if (instance) return ToV8Object(V8ClassIndex::SVGELEMENTINSTANCE, instance);
+ if (instance)
+ return ToV8Object(V8ClassIndex::SVGELEMENTINSTANCE, instance);
#endif
Node* node = target->toNode();
- if (node) return NodeToV8Object(node);
+ if (node)
+ return NodeToV8Object(node);
// XMLHttpRequest is created within its JS counterpart.
XMLHttpRequest* xhr = target->toXMLHttpRequest();
@@ -2501,12 +2503,12 @@ v8::Handle<v8::Value> V8Proxy::StyleSheetToV8Object(StyleSheet* sheet) {
if (!sheet) return v8::Null();
v8::Handle<v8::Object> peer = dom_object_map().get(sheet);
- if (!peer.IsEmpty()) {
+ if (!peer.IsEmpty())
return peer;
- }
V8ClassIndex::V8WrapperType type = V8ClassIndex::STYLESHEET;
- if (sheet->isCSSStyleSheet()) type = V8ClassIndex::CSSSTYLESHEET;
+ if (sheet->isCSSStyleSheet())
+ type = V8ClassIndex::CSSSTYLESHEET;
v8::Handle<v8::Object> result =
InstantiateV8Object(type, V8ClassIndex::STYLESHEET, sheet);
@@ -2519,7 +2521,7 @@ v8::Handle<v8::Value> V8Proxy::StyleSheetToV8Object(StyleSheet* sheet) {
Node* owner_node = sheet->ownerNode();
if (owner_node) {
v8::Handle<v8::Object> owner =
- v8::Handle<v8::Object>::Cast(NodeToV8Object(owner_node));
+ v8::Handle<v8::Object>::Cast(NodeToV8Object(owner_node));
result->SetInternalField(V8Custom::kStyleSheetOwnerNodeIndex, owner);
}
@@ -2531,9 +2533,8 @@ v8::Handle<v8::Value> V8Proxy::CSSValueToV8Object(CSSValue* value) {
if (!value) return v8::Null();
v8::Handle<v8::Object> peer = dom_object_map().get(value);
- if (!peer.IsEmpty()) {
+ if (!peer.IsEmpty())
return peer;
- }
V8ClassIndex::V8WrapperType type;
@@ -2552,95 +2553,93 @@ v8::Handle<v8::Value> V8Proxy::CSSValueToV8Object(CSSValue* value) {
v8::Handle<v8::Object> result =
InstantiateV8Object(type, V8ClassIndex::CSSVALUE, value);
- if (!result.IsEmpty()) {
+ if (!result.IsEmpty())
// Only update the DOM object map if the result is non-empty.
dom_object_map().set(value, v8::Persistent<v8::Object>::New(result));
- }
return result;
}
v8::Handle<v8::Value> V8Proxy::CSSRuleToV8Object(CSSRule* rule) {
- if (!rule) return v8::Null();
-
- v8::Handle<v8::Object> peer = dom_object_map().get(rule);
- if (!peer.IsEmpty()) {
- return peer;
- }
-
- V8ClassIndex::V8WrapperType type;
-
- switch (rule->type()) {
- case CSSRule::STYLE_RULE:
- type = V8ClassIndex::CSSSTYLERULE;
- break;
- case CSSRule::CHARSET_RULE:
- type = V8ClassIndex::CSSCHARSETRULE;
- break;
- case CSSRule::IMPORT_RULE:
- type = V8ClassIndex::CSSIMPORTRULE;
- break;
- case CSSRule::MEDIA_RULE:
- type = V8ClassIndex::CSSMEDIARULE;
- break;
- case CSSRule::FONT_FACE_RULE:
- type = V8ClassIndex::CSSFONTFACERULE;
- break;
- case CSSRule::PAGE_RULE:
- type = V8ClassIndex::CSSPAGERULE;
- break;
- default: // CSSRule::UNKNOWN_RULE
- type = V8ClassIndex::CSSRULE;
- }
+ if (!rule) return v8::Null();
+
+ v8::Handle<v8::Object> peer = dom_object_map().get(rule);
+ if (!peer.IsEmpty())
+ return peer;
+
+ V8ClassIndex::V8WrapperType type;
+
+ switch (rule->type()) {
+ case CSSRule::STYLE_RULE:
+ type = V8ClassIndex::CSSSTYLERULE;
+ break;
+ case CSSRule::CHARSET_RULE:
+ type = V8ClassIndex::CSSCHARSETRULE;
+ break;
+ case CSSRule::IMPORT_RULE:
+ type = V8ClassIndex::CSSIMPORTRULE;
+ break;
+ case CSSRule::MEDIA_RULE:
+ type = V8ClassIndex::CSSMEDIARULE;
+ break;
+ case CSSRule::FONT_FACE_RULE:
+ type = V8ClassIndex::CSSFONTFACERULE;
+ break;
+ case CSSRule::PAGE_RULE:
+ type = V8ClassIndex::CSSPAGERULE;
+ break;
+ default: // CSSRule::UNKNOWN_RULE
+ type = V8ClassIndex::CSSRULE;
+ }
- // Set the peer object for future access.
- v8::Handle<v8::Object> result =
- InstantiateV8Object(type, V8ClassIndex::CSSRULE, rule);
- if (!result.IsEmpty()) {
- // Only update the DOM object map if the result is non-empty.
- dom_object_map().set(rule, v8::Persistent<v8::Object>::New(result));
- }
- return result;
+ // Set the peer object for future access.
+ v8::Handle<v8::Object> result =
+ InstantiateV8Object(type, V8ClassIndex::CSSRULE, rule);
+ if (!result.IsEmpty())
+ // Only update the DOM object map if the result is non-empty.
+ dom_object_map().set(rule, v8::Persistent<v8::Object>::New(result));
+ return result;
}
v8::Handle<v8::Value> V8Proxy::WindowToV8Object(DOMWindow* window) {
- if (!window) return v8::Null();
+ if (!window) return v8::Null();
+ // Initializes environment of a frame, and return the global object
+ // of the frame.
+ Frame* frame = window->frame();
+ if (!frame)
+ return v8::Handle<v8::Object>();
- // Initializes environment of a frame, and return the global object
- // of the frame.
- Frame* frame = window->frame();
- if (!frame) return v8::Handle<v8::Object>();
+ v8::Handle<v8::Context> context = GetContext(frame);
+ if (context.IsEmpty())
+ return v8::Handle<v8::Object>();
- v8::Handle<v8::Context> context = GetContext(frame);
- if (context.IsEmpty()) return v8::Handle<v8::Object>();
-
- v8::Handle<v8::Object> global = context->Global();
- ASSERT(!global.IsEmpty());
- return global;
+ v8::Handle<v8::Object> global = context->Global();
+ ASSERT(!global.IsEmpty());
+ return global;
}
-
void V8Proxy::BindJSObjectToWindow(Frame* frame,
const char* name,
int type,
v8::Handle<v8::FunctionTemplate> desc,
- void* imp) {
- // Get environment.
- v8::Handle<v8::Context> context = V8Proxy::GetContext(frame);
- if (context.IsEmpty()) return; // JS not enabled.
+ void* imp)
+{
+ // Get environment.
+ v8::Handle<v8::Context> context = V8Proxy::GetContext(frame);
+ if (context.IsEmpty())
+ return; // JS not enabled.
- v8::Context::Scope scope(context);
- v8::Handle<v8::Object> instance = desc->GetFunction();
- SetDOMWrapper(instance, type, imp);
+ v8::Context::Scope scope(context);
+ v8::Handle<v8::Object> instance = desc->GetFunction();
+ SetDOMWrapper(instance, type, imp);
- v8::Handle<v8::Object> global = context->Global();
- global->Set(v8::String::New(name), instance);
+ v8::Handle<v8::Object> global = context->Global();
+ global->Set(v8::String::New(name), instance);
}
-
-void V8Proxy::ProcessConsoleMessages() {
- ConsoleMessageManager::ProcessDelayedMessages();
+void V8Proxy::ProcessConsoleMessages()
+{
+ ConsoleMessageManager::ProcessDelayedMessages();
}
-
} // namespace WebCore
diff --git a/webkit/port/bindings/v8/v8_proxy.h b/webkit/port/bindings/v8/v8_proxy.h
index 94f0450..784d763 100644
--- a/webkit/port/bindings/v8/v8_proxy.h
+++ b/webkit/port/bindings/v8/v8_proxy.h
@@ -13,6 +13,7 @@
#include "NodeFilter.h"
#include "PlatformString.h" // for WebCore::String
#include <wtf/HashMap.h> // for HashMap
+#include <wtf/PassRefPtr.h> // so generated bindings don't have to
#include <wtf/Assertions.h>
#include <iterator>
@@ -331,6 +332,11 @@ class V8Proxy {
return static_cast<C*>(ExtractCPointer<Node>(wrapper));
}
+ template<typename T>
+ static v8::Handle<v8::Value> ToV8Object(V8ClassIndex::V8WrapperType type, PassRefPtr<T> imp)
+ {
+ return ToV8Object(type, imp.get());
+ }
static v8::Handle<v8::Value> ToV8Object(V8ClassIndex::V8WrapperType type,
void* imp);
// Fast-path for Node objects.
@@ -378,7 +384,7 @@ class V8Proxy {
DOMImplementation* impl);
// Wrap JS node filter in C++
- static NodeFilter* ToNativeNodeFilter(v8::Handle<v8::Value> filter);
+ static PassRefPtr<NodeFilter> ToNativeNodeFilter(v8::Handle<v8::Value> filter);
static v8::Persistent<v8::FunctionTemplate> GetTemplate(
V8ClassIndex::V8WrapperType type);
@@ -518,10 +524,14 @@ v8::Handle<v8::Value> V8Proxy::ConstructDOMObject(const v8::Arguments& args) {
"DOM object constructor cannot be called as a function.");
return v8::Undefined();
}
- T* obj = new T();
- V8Proxy::SetDOMWrapper(args.Holder(), tag, obj);
+
+
+ // Note: it's OK to let this RefPtr go out of scope because we also call
+ // SetDOMWrapper(), which effectively holds a reference to obj.
+ RefPtr<T> obj = T::create();
+ V8Proxy::SetDOMWrapper(args.Holder(), tag, obj.get());
V8Proxy::SetJSWrapperForDOMObject(
- obj, v8::Persistent<v8::Object>::New(args.Holder()));
+ obj.get(), v8::Persistent<v8::Object>::New(args.Holder()));
return args.Holder();
}