summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrei Popescu <andreip@google.com>2009-06-08 17:39:30 +0100
committerAndrei Popescu <andreip@google.com>2009-06-08 17:40:48 +0100
commit595f429f16d56891f697a15c3ec2fd2ec9647c5f (patch)
tree0567454fd15ccfac8f82047ce0203a0878c186f6
parent91637c8ca6b8baa16edf528ee009b228d6e6c053 (diff)
downloadexternal_webkit-595f429f16d56891f697a15c3ec2fd2ec9647c5f.zip
external_webkit-595f429f16d56891f697a15c3ec2fd2ec9647c5f.tar.gz
external_webkit-595f429f16d56891f697a15c3ec2fd2ec9647c5f.tar.bz2
Make AppCache work with v8:
-- Most changes follow Chrome's changes in the same area -- I needed to update the CodeGeneratorV8.pm to the latest version -- I needed to deprecate v8_utility.h and replace it with V8Utilities.h/cpp
-rw-r--r--V8Binding/V8Binding.derived.mk15
-rw-r--r--V8Binding/scripts/CodeGeneratorV8.pm76
-rw-r--r--V8Binding/v8/DOMObjectsInclude.h1
-rw-r--r--V8Binding/v8/V8Utilities.cpp110
-rw-r--r--V8Binding/v8/V8Utilities.h131
-rw-r--r--V8Binding/v8/v8_custom.h14
-rw-r--r--V8Binding/v8/v8_index.cpp4
-rw-r--r--V8Binding/v8/v8_index.h8
-rw-r--r--V8Binding/v8/v8_proxy.cpp16
-rw-r--r--V8Binding/v8/v8_proxy.h2
-rw-r--r--V8Binding/v8/v8_utility.h58
-rw-r--r--WebCore/bindings/v8/custom/V8DOMApplicationCacheCustom.cpp142
-rw-r--r--WebCore/loader/appcache/DOMApplicationCache.cpp45
-rw-r--r--WebCore/loader/appcache/DOMApplicationCache.h10
14 files changed, 552 insertions, 80 deletions
diff --git a/V8Binding/V8Binding.derived.mk b/V8Binding/V8Binding.derived.mk
index ce32839..67f5d06 100644
--- a/V8Binding/V8Binding.derived.mk
+++ b/V8Binding/V8Binding.derived.mk
@@ -56,6 +56,7 @@ WEBCORE_SRC_FILES := \
bindings/v8/custom/V8DOMStringListCustom.cpp \
bindings/v8/custom/V8DOMWindowCustom.cpp \
bindings/v8/custom/V8DocumentCustom.cpp \
+ bindings/v8/custom/V8DOMApplicationCacheCustom.cpp \
bindings/v8/custom/V8ElementCustom.cpp \
bindings/v8/custom/V8EventCustom.cpp \
bindings/v8/custom/V8HTMLCanvasElementCustom.cpp \
@@ -113,6 +114,7 @@ LOCAL_SRC_FILES := \
v8/V8MessagePortCustom.cpp \
v8/V8NPObject.cpp \
v8/V8NPUtils.cpp \
+ v8/V8Utilities.cpp \
v8/V8WorkerContextCustom.cpp \
v8/V8WorkerCustom.cpp \
v8/npruntime.cpp \
@@ -137,7 +139,7 @@ js_binding_scripts := \
$(WEBCORE_PATH)/bindings/scripts/IDLStructure.pm \
$(LOCAL_PATH)/scripts/generate-bindings.pl
-FEATURE_DEFINES := ANDROID_ORIENTATION_SUPPORT ENABLE_TOUCH_EVENTS=1 V8_BINDING ENABLE_DATABASE=1
+FEATURE_DEFINES := ANDROID_ORIENTATION_SUPPORT ENABLE_TOUCH_EVENTS=1 V8_BINDING ENABLE_DATABASE=1 ENABLE_OFFLINE_WEB_APPLICATIONS=1
GEN := \
$(intermediates)/css/V8CSSCharsetRule.h \
@@ -316,6 +318,17 @@ LOCAL_GENERATED_SOURCES += $(GEN) $(GEN:%.h=%.cpp)
# above rules. Specifying this explicitly makes -j2 work.
$(patsubst %.h,%.cpp,$(GEN)): $(intermediates)/html/%.cpp : $(intermediates)/html/%.h
+GEN := \
+ $(intermediates)/loader/appcache/V8DOMApplicationCache.h
+
+$(GEN): PRIVATE_CUSTOM_TOOL = SOURCE_ROOT=$(WEBCORE_PATH) perl -I$(v8binding_dir)/scripts -I$(WEBCORE_PATH)/bindings/scripts $(v8binding_dir)/scripts/generate-bindings.pl --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT" --generator V8 --include dom --include html --outputdir $(dir $@) $<
+$(GEN): $(intermediates)/loader/appcache/V8%.h : $(WEBCORE_PATH)/loader/appcache/%.idl $(js_binding_scripts)
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN) $(GEN:%.h=%.cpp)
+
+# We also need the .cpp files, which are generated as side effects of the
+# above rules. Specifying this explicitly makes -j2 work.
+$(patsubst %.h,%.cpp,$(GEN)): $(intermediates)/loader/appcache/%.cpp : $(intermediates)/loader/appcache/%.h
GEN := \
$(intermediates)/page/V8BarInfo.h \
diff --git a/V8Binding/scripts/CodeGeneratorV8.pm b/V8Binding/scripts/CodeGeneratorV8.pm
index 541d17b..37a9f74 100644
--- a/V8Binding/scripts/CodeGeneratorV8.pm
+++ b/V8Binding/scripts/CodeGeneratorV8.pm
@@ -4,7 +4,7 @@
# Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
# Copyright (C) 2006 Alexey Proskuryakov <ap@webkit.org>
# Copyright (C) 2006 Apple Computer, Inc.
-# Copyright (C) 2007 Google Inc.
+# Copyright (C) 2007, 2008, 2009 Google Inc.
#
# This file is part of the KDE project
#
@@ -314,6 +314,8 @@ END
push(@headerContent, "}\n\n");
push(@headerContent, "#endif // $className" . "_H\n");
+ push(@headerContent, "#endif // ${conditionalString}\n\n") if $conditional;
+
if ($className =~ /^V8SVG/) {
push(@headerContent, "\n#endif // ENABLE(SVG)\n");
} elsif (IsVideoClassName($className)) {
@@ -321,8 +323,6 @@ END
} elsif (IsWorkerClassName($className)) {
push(@headerContent, "\n#endif // ENABLE(WORKERS)\n");
}
-
- push(@headerContent, "#endif // ${conditionalString}\n\n") if $conditional;
}
@@ -450,10 +450,11 @@ END
return WorkerContextExecutionProxy::retrieve()->GetConstructor(type);
END
} else {
- push(@implContentDecls, " return V8Proxy::retrieve()->GetConstructor(type);");
+ push(@implContentDecls, " return v8::Undefined();");
}
push(@implContentDecls, <<END);
+
}
END
@@ -931,6 +932,7 @@ sub GenerateBatchedAttributeData
my $getter;
my $setter;
my $propAttr = "v8::None";
+ my $hasCustomSetter = 0;
# Check attributes.
if ($attrExt->{"DontEnum"}) {
@@ -954,13 +956,24 @@ sub GenerateBatchedAttributeData
$propAttr = "v8::ReadOnly";
# EventListeners
- } elsif ($attrExt->{"ProtectedListener"}) {
+ } elsif ($attribute->signature->type eq "EventListener") {
if ($interfaceName eq "DOMWindow") {
$getter = "V8Custom::v8DOMWindowEventHandlerAccessorGetter";
$setter = "V8Custom::v8DOMWindowEventHandlerAccessorSetter";
- } else {
+ } elsif ($interfaceName eq "DOMApplicationCache") {
+ $getter = "V8Custom::v8DOMApplicationCacheEventHandlerAccessorGetter";
+ $setter = "V8Custom::v8DOMApplicationCacheEventHandlerAccessorSetter";
+ } elsif ($interfaceName eq "Node" || $interfaceName eq "SVGElementInstance") {
$getter = "V8Custom::v8ElementEventHandlerAccessorGetter";
$setter = "V8Custom::v8ElementEventHandlerAccessorSetter";
+ } else {
+ $getter = "V8Custom::v8${customAccessor}AccessorGetter";
+ if ($interfaceName eq "WorkerContext" and $attrName eq "self") {
+ $setter = "0";
+ $propAttr = "v8::ReadOnly";
+ } else {
+ $setter = "V8Custom::v8${customAccessor}AccessorSetter";
+ }
}
# Custom Getter and Setter
@@ -970,11 +983,13 @@ sub GenerateBatchedAttributeData
$setter = "0";
$propAttr = "v8::ReadOnly";
} else {
+ $hasCustomSetter = 1;
$setter = "V8Custom::v8${customAccessor}AccessorSetter";
}
# Custom Setter
} elsif ($attrExt->{"CustomSetter"} || $attrExt->{"V8CustomSetter"}) {
+ $hasCustomSetter = 1;
$getter = "${interfaceName}Internal::${attrName}AttrGetter";
$setter = "V8Custom::v8${customAccessor}AccessorSetter";
@@ -988,14 +1003,28 @@ sub GenerateBatchedAttributeData
# Replaceable accessor is put on instance template with ReadOnly attribute.
$getter = "${interfaceName}Internal::${attrName}AttrGetter";
$setter = "0";
- $propAttr .= "|v8::ReadOnly";
-
+
+ # Mark to avoid duplicate v8::ReadOnly flags in output.
+ $hasCustomSetter = 1;
+
+ # Handle the special case of window.top being marked upstream as Replaceable.
+ # TODO(dglazkov): Investigate why [Replaceable] is not marked as ReadOnly
+ # upstream and reach parity.
+ if (!($interfaceName eq "DOMWindow" and $attrName eq "top")) {
+ $propAttr .= "|v8::ReadOnly";
+ }
+
# Normal
} else {
$getter = "${interfaceName}Internal::${attrName}AttrGetter";
$setter = "${interfaceName}Internal::${attrName}AttrSetter";
}
+ if ($attrExt->{"Replaceable"} && !$hasCustomSetter) {
+ $setter = "0";
+ $propAttr .= "|v8::ReadOnly";
+ }
+
# Read only attributes
if ($attribute->type =~ /^readonly/ || $attrExt->{"V8ReadOnly"}) {
$setter = "0";
@@ -1052,7 +1081,7 @@ sub GenerateImplementation
} elsif (IsWorkerClassName($className)) {
push(@implFixedHeader, "#if ENABLE(WORKERS)\n\n");
}
-
+
my $conditionalString;
if ($conditional) {
$conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
@@ -1388,6 +1417,7 @@ END
} elsif (IsWorkerClassName($className)) {
push(@implContent, "\n#endif // ENABLE(WORKERS)\n");
}
+
push(@implContent, "\n#endif // ${conditionalString}\n") if $conditional;
}
@@ -1684,6 +1714,7 @@ sub GetNativeType
return $type
}
+ return "int" if $type eq "int";
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";
@@ -1698,6 +1729,7 @@ sub GetNativeType
return "double" if $type eq "SVGNumber";
return "SVGPaint::SVGPaintType" if $type eq "SVGPaintType";
return "DOMTimeStamp" if $type eq "DOMTimeStamp";
+ return "unsigned" if $type eq "unsigned int";
return "unsigned" if $type eq "RGBColor";
return "Node*" if $type eq "EventTarget" and $isParameter;
@@ -1724,7 +1756,6 @@ my %typeCanFailConversion = (
"Event" => 0,
"EventListener" => 0,
"EventTarget" => 0,
- "Geoposition" => 0,
"HTMLElement" => 0,
"HTMLOptionElement" => 0,
"Node" => 0,
@@ -1736,14 +1767,14 @@ my %typeCanFailConversion = (
"SQLResultSet" => 0,
"SVGAngle" => 0,
"SVGElement" => 0,
- "SVGLength" => 0,
- "SVGMatrix" => 0,
+ "SVGLength" => 1,
+ "SVGMatrix" => 1,
"SVGNumber" => 0,
"SVGPaintType" => 0,
"SVGPathSeg" => 0,
- "SVGPoint" => 0,
- "SVGRect" => 0,
- "SVGTransform" => 0,
+ "SVGPoint" => 1,
+ "SVGRect" => 1,
+ "SVGTransform" => 1,
"TouchList" => 0,
"VoidCallback" => 1,
"WebKitCSSMatrix" => 0,
@@ -1759,7 +1790,6 @@ my %typeCanFailConversion = (
"unsigned short" => 0,
);
-
sub TranslateParameter
{
my $signature = shift;
@@ -1772,7 +1802,14 @@ sub TranslateParameter
sub BasicTypeCanFailConversion
{
- # As can been seen from the above, no basic types can fail conversion.
+ my $signature = shift;
+ my $type = $codeGenerator->StripModule($signature->type);
+
+ return 1 if $type eq "SVGLength";
+ return 1 if $type eq "SVGMatrix";
+ return 1 if $type eq "SVGPoint";
+ return 1 if $type eq "SVGRect";
+ return 1 if $type eq "SVGTransform";
return 0;
}
@@ -1856,8 +1893,7 @@ sub JSValueToNative
my $nativeType = GetNativeType($type);
$implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
- # TODO(jhass): perform type checking like others???
- return "*V8Proxy::ToNativeObject<V8SVGPODTypeWrapper<${nativeType}> >(V8ClassIndex::${classIndex}, $value)"
+ return "V8SVGPODTypeUtil::ToSVGPODType<${nativeType}>(V8ClassIndex::${classIndex}, $value${maybeOkParam})"
}
$implIncludes{"V8${type}.h"} = 1;
@@ -2037,7 +2073,7 @@ sub NativeToJSValue
return "V8Proxy::ToV8Object(V8ClassIndex::RGBCOLOR, new RGBColor($value))";
}
- if ($type eq "WorkerLocation" or $type eq "WorkerNavigator") {
+ if ($type eq "WorkerContext" or $type eq "WorkerLocation" or $type eq "WorkerNavigator") {
$implIncludes{"WorkerContextExecutionProxy.h"} = 1;
my $classIndex = uc($type);
diff --git a/V8Binding/v8/DOMObjectsInclude.h b/V8Binding/v8/DOMObjectsInclude.h
index b7b941e..0268bca 100644
--- a/V8Binding/v8/DOMObjectsInclude.h
+++ b/V8Binding/v8/DOMObjectsInclude.h
@@ -32,6 +32,7 @@
#include "Database.h"
#include "DocumentType.h"
#include "DocumentFragment.h"
+#include "DOMApplicationCache.h"
#include "DOMCoreException.h"
#include "DOMImplementation.h"
#include "DOMParser.h"
diff --git a/V8Binding/v8/V8Utilities.cpp b/V8Binding/v8/V8Utilities.cpp
new file mode 100644
index 0000000..8853506
--- /dev/null
+++ b/V8Binding/v8/V8Utilities.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2008, 2009 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 "V8Utilities.h"
+
+#include <v8.h>
+
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+#include <wtf/Assertions.h>
+#include "Frame.h"
+
+namespace WebCore {
+
+// Use an array to hold dependents. It works like a ref-counted scheme.
+// A value can be added more than once to the DOM object.
+void createHiddenDependency(v8::Local<v8::Object> object, v8::Local<v8::Value> value, int cacheIndex)
+{
+ v8::Local<v8::Value> cache = object->GetInternalField(cacheIndex);
+ if (cache->IsNull() || cache->IsUndefined()) {
+ cache = v8::Array::New();
+ object->SetInternalField(cacheIndex, cache);
+ }
+
+ v8::Local<v8::Array> cacheArray = v8::Local<v8::Array>::Cast(cache);
+ cacheArray->Set(v8::Integer::New(cacheArray->Length()), value);
+}
+
+void removeHiddenDependency(v8::Local<v8::Object> object, v8::Local<v8::Value> value, int cacheIndex)
+{
+ v8::Local<v8::Value> cache = object->GetInternalField(cacheIndex);
+ ASSERT(cache->IsArray());
+ v8::Local<v8::Array> cacheArray = v8::Local<v8::Array>::Cast(cache);
+ for (int i = cacheArray->Length() - 1; i >= 0; --i) {
+ v8::Local<v8::Value> cached = cacheArray->Get(v8::Integer::New(i));
+ if (cached->StrictEquals(value)) {
+ cacheArray->Delete(i);
+ return;
+ }
+ }
+
+ // We should only get here if we try to remove an event listener that was never added.
+ ASSERT_NOT_REACHED();
+}
+
+#if PLATFORM(ANDROID)
+ // The functions below are not needed on Android.
+#else
+bool processingUserGesture()
+{
+ Frame* frame = V8Proxy::retrieveFrameForEnteredContext();
+ return frame && frame->script()->processingUserGesture();
+}
+
+bool shouldAllowNavigation(Frame* frame)
+{
+ Frame* callingFrame = V8Proxy::retrieveFrameForCallingContext();
+ return callingFrame && callingFrame->loader()->shouldAllowNavigation(frame);
+}
+
+KURL completeURL(const String& relativeURL)
+{
+ // For histoical reasons, we need to complete the URL using the dynamic frame.
+ Frame* frame = V8Proxy::retrieveFrameForEnteredContext();
+ if (!frame)
+ return KURL();
+ return frame->loader()->completeURL(relativeURL);
+}
+
+void navigateIfAllowed(Frame* frame, const KURL& url, bool lockHistory, bool lockBackForwardList)
+{
+ Frame* callingFrame = V8Proxy::retrieveFrameForCallingContext();
+ if (!callingFrame)
+ return;
+
+ if (!protocolIsJavaScript(url) || ScriptController::isSafeScript(frame))
+ frame->loader()->scheduleLocationChange(url.string(), callingFrame->loader()->outgoingReferrer(), lockHistory, lockBackForwardList, processingUserGesture());
+}
+#endif // PLATFORM(ANDROID)
+
+} // namespace WebCore
diff --git a/V8Binding/v8/V8Utilities.h b/V8Binding/v8/V8Utilities.h
new file mode 100644
index 0000000..f4346f6
--- /dev/null
+++ b/V8Binding/v8/V8Utilities.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2006, 2007, 2008, 2009 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.
+ */
+
+#ifndef V8Utilities_h
+#define V8Utilities_h
+
+// FIXME: Remove once chromium dependencies on v8_utility.h are removed.
+#define V8UTILITIES_DEFINED 1
+
+#include <v8.h>
+
+namespace WebCore {
+
+ class Frame;
+ class KURL;
+ class String;
+
+ // Use an array to hold dependents. It works like a ref-counted scheme. A value can be added more than once to the DOM object.
+ void createHiddenDependency(v8::Local<v8::Object>, v8::Local<v8::Value>, int cacheIndex);
+ void removeHiddenDependency(v8::Local<v8::Object>, v8::Local<v8::Value>, int cacheIndex);
+
+#if PLATFORM(ANDROID)
+ // The functions below are not needed (yet) on Android.
+#else
+ bool processingUserGesture();
+ bool shouldAllowNavigation(Frame*);
+ KURL completeURL(const String& relativeURL);
+ void navigateIfAllowed(Frame*, const KURL&, bool lockHistory, bool lockBackForwardList);
+#endif // PLATFORM(ANDROID)
+
+ class AllowAllocation {
+ public:
+ inline AllowAllocation()
+ {
+ m_previous = m_current;
+ m_current = true;
+ }
+
+ inline ~AllowAllocation()
+ {
+ m_current = m_previous;
+ }
+
+ static bool m_current;
+
+ private:
+ bool m_previous;
+ };
+
+ class SafeAllocation {
+ public:
+ static inline v8::Local<v8::Object> newInstance(v8::Handle<v8::Function>);
+ static inline v8::Local<v8::Object> newInstance(v8::Handle<v8::ObjectTemplate>);
+ static inline v8::Local<v8::Object> newInstance(v8::Handle<v8::Function>, int argc, v8::Handle<v8::Value> argv[]);
+
+ // FIXME: These NewInstance functions are here to ease upstreaming. Remove along with V8UTILITIES_DEFINED once chromium dependencies on v8_utility.h are removed.
+ static inline v8::Local<v8::Object> NewInstance(v8::Handle<v8::Function>);
+ static inline v8::Local<v8::Object> NewInstance(v8::Handle<v8::ObjectTemplate>);
+ static inline v8::Local<v8::Object> NewInstance(v8::Handle<v8::Function>, int argc, v8::Handle<v8::Value> argv[]);
+ };
+
+ v8::Local<v8::Object> SafeAllocation::newInstance(v8::Handle<v8::Function> function)
+ {
+ if (function.IsEmpty())
+ return v8::Local<v8::Object>();
+ AllowAllocation allow;
+ return function->NewInstance();
+ }
+
+ v8::Local<v8::Object> SafeAllocation::newInstance(v8::Handle<v8::ObjectTemplate> objectTemplate)
+ {
+ if (objectTemplate.IsEmpty())
+ return v8::Local<v8::Object>();
+ AllowAllocation allow;
+ return objectTemplate->NewInstance();
+ }
+
+ v8::Local<v8::Object> SafeAllocation::newInstance(v8::Handle<v8::Function> function, int argc, v8::Handle<v8::Value> argv[])
+ {
+ if (function.IsEmpty())
+ return v8::Local<v8::Object>();
+ AllowAllocation allow;
+ return function->NewInstance(argc, argv);
+ }
+
+ // FIXME: These NewInstance functions are here to ease upstreaming. Remove along with V8UTILITIES_DEFINED once chromium dependencies on v8_utility.h are removed.
+ v8::Local<v8::Object> SafeAllocation::NewInstance(v8::Handle<v8::Function> function)
+ {
+ return newInstance(function);
+ }
+
+ v8::Local<v8::Object> SafeAllocation::NewInstance(v8::Handle<v8::ObjectTemplate> objectTemplate)
+ {
+ return newInstance(objectTemplate);
+ }
+
+ v8::Local<v8::Object> SafeAllocation::NewInstance(v8::Handle<v8::Function> function, int argc, v8::Handle<v8::Value> argv[])
+ {
+ return newInstance(function, argc, argv);
+ }
+
+} // namespace WebCore
+
+#endif // V8Utilities_h
diff --git a/V8Binding/v8/v8_custom.h b/V8Binding/v8/v8_custom.h
index a891e2e..caeac41 100644
--- a/V8Binding/v8/v8_custom.h
+++ b/V8Binding/v8/v8_custom.h
@@ -135,6 +135,13 @@ class V8Custom {
static const int kStyleSheetInternalFieldCount =
kDefaultWrapperInternalFieldCount + 1;
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ static const int kDOMApplicationCacheCacheIndex =
+ kDefaultWrapperInternalFieldCount + 0;
+ static const int kDOMApplicationCacheFieldCount =
+ kDefaultWrapperInternalFieldCount + 1;
+#endif
+
#define DECLARE_PROPERTY_ACCESSOR_GETTER(NAME) \
static v8::Handle<v8::Value> v8##NAME##AccessorGetter(\
v8::Local<v8::String> name, const v8::AccessorInfo& info);
@@ -503,6 +510,13 @@ DECLARE_CALLBACK(WorkerContextAddEventListener)
DECLARE_CALLBACK(WorkerContextRemoveEventListener)
#endif
+// AppCache
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+DECLARE_PROPERTY_ACCESSOR(DOMApplicationCacheEventHandler)
+DECLARE_CALLBACK(DOMApplicationCacheAddEventListener)
+DECLARE_CALLBACK(DOMApplicationCacheRemoveEventListener)
+#endif
+
#undef DECLARE_INDEXED_ACCESS_CHECK
#undef DECLARE_NAMED_ACCESS_CHECK
diff --git a/V8Binding/v8/v8_index.cpp b/V8Binding/v8/v8_index.cpp
index fcc75e9..df138dc 100644
--- a/V8Binding/v8/v8_index.cpp
+++ b/V8Binding/v8/v8_index.cpp
@@ -392,6 +392,10 @@
#include "V8VoidCallback.h"
#endif
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+#include "V8DOMApplicationCache.h"
+#endif
+
namespace WebCore {
FunctionTemplateFactory V8ClassIndex::GetFactory(V8WrapperType type) {
diff --git a/V8Binding/v8/v8_index.h b/V8Binding/v8/v8_index.h
index b8d76ed..71453c3 100644
--- a/V8Binding/v8/v8_index.h
+++ b/V8Binding/v8/v8_index.h
@@ -39,6 +39,13 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)();
#define WORKER_NONNODE_WRAPPER_TYPES(V)
#endif
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+#define APPLICATIONCACHE_NONNODE_WRAPPER_TYPES(V) \
+ V(DOMAPPLICATIONCACHE, DOMApplicationCache)
+#else
+#define APPLICATIONCACHE_NONNODE_WRAPPER_TYPES(V)
+#endif
+
#define DOM_NODE_TYPES(V) \
V(ATTR, Attr) \
V(CHARACTERDATA, CharacterData) \
@@ -328,6 +335,7 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)();
V(XMLHTTPREQUESTPROGRESSEVENT, XMLHttpRequestProgressEvent) \
V(XMLSERIALIZER, XMLSerializer) \
ACTIVE_DOM_OBJECT_TYPES(V) \
+ APPLICATIONCACHE_NONNODE_WRAPPER_TYPES(V) \
VIDEO_NONNODE_TYPES(V) \
WORKER_NONNODE_WRAPPER_TYPES(V)
diff --git a/V8Binding/v8/v8_proxy.cpp b/V8Binding/v8/v8_proxy.cpp
index 204b2bc..45b56d7 100644
--- a/V8Binding/v8/v8_proxy.cpp
+++ b/V8Binding/v8/v8_proxy.cpp
@@ -1658,6 +1658,16 @@ v8::Persistent<v8::FunctionTemplate> V8Proxy::GetTemplate(
}
#endif // WORKERS
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ case V8ClassIndex::DOMAPPLICATIONCACHE: {
+ // Reserve one more internal field for keeping event listeners.
+ v8::Local<v8::ObjectTemplate> instance_template =
+ desc->InstanceTemplate();
+ instance_template->SetInternalFieldCount(
+ V8Custom::kDOMApplicationCacheFieldCount);
+ break;
+ }
+#endif
// The following objects are created from JavaScript.
case V8ClassIndex::DOMPARSER:
@@ -3065,6 +3075,12 @@ v8::Handle<v8::Value> V8Proxy::EventTargetToV8Object(EventTarget* target)
return ToV8Object(V8ClassIndex::WORKER, worker);
#endif // WORKERS
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ DOMApplicationCache* app_cache = target->toDOMApplicationCache();
+ if (app_cache)
+ return ToV8Object(V8ClassIndex::DOMAPPLICATIONCACHE, app_cache);
+#endif
+
Node* node = target->toNode();
if (node)
return NodeToV8Object(node);
diff --git a/V8Binding/v8/v8_proxy.h b/V8Binding/v8/v8_proxy.h
index 45f9f39..17a2d1b 100644
--- a/V8Binding/v8/v8_proxy.h
+++ b/V8Binding/v8/v8_proxy.h
@@ -8,7 +8,7 @@
#include <v8.h>
#include "v8_index.h"
#include "v8_custom.h"
-#include "v8_utility.h"
+#include "V8Utilities.h"
#include "Node.h"
#include "NodeFilter.h"
#include "PlatformString.h" // for WebCore::String
diff --git a/V8Binding/v8/v8_utility.h b/V8Binding/v8/v8_utility.h
deleted file mode 100644
index 620c04c..0000000
--- a/V8Binding/v8/v8_utility.h
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_UTILITY_H__
-#define V8_UTILITY_H__
-
-namespace WebCore {
-
-class AllowAllocation {
- public:
- inline AllowAllocation() {
- m_prev = m_current;
- m_current = true;
- }
- inline ~AllowAllocation() {
- m_current = m_prev;
- }
- static bool m_current;
- private:
- bool m_prev;
-};
-
-class SafeAllocation {
- public:
- static inline v8::Local<v8::Object> NewInstance(
- v8::Handle<v8::Function> fun);
- static inline v8::Local<v8::Object> NewInstance(
- v8::Handle<v8::ObjectTemplate> templ);
- static inline v8::Local<v8::Object> NewInstance(
- v8::Handle<v8::Function> fun, int argc, v8::Handle<v8::Value> argv[]);
-};
-
-v8::Local<v8::Object> SafeAllocation::NewInstance(
- v8::Handle<v8::Function> fun) {
- if (fun.IsEmpty())
- return v8::Local<v8::Object>();
- AllowAllocation allow;
- return fun->NewInstance();
-}
-
-v8::Local<v8::Object> SafeAllocation::NewInstance(
- v8::Handle<v8::ObjectTemplate> templ) {
- if (templ.IsEmpty()) return v8::Local<v8::Object>();
- AllowAllocation allow;
- return templ->NewInstance();
-}
-
-v8::Local<v8::Object> SafeAllocation::NewInstance(
- v8::Handle<v8::Function> fun, int argc, v8::Handle<v8::Value> argv[]) {
- if (fun.IsEmpty()) return v8::Local<v8::Object>();
- AllowAllocation allow;
- return fun->NewInstance(argc, argv);
-}
-
-} // namespace WebCore
-
-#endif // V8_UTILITY_H__
diff --git a/WebCore/bindings/v8/custom/V8DOMApplicationCacheCustom.cpp b/WebCore/bindings/v8/custom/V8DOMApplicationCacheCustom.cpp
new file mode 100644
index 0000000..b0789e5
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8DOMApplicationCacheCustom.cpp
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2008, 2009 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 "DOMApplicationCache.h"
+
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+
+#include "V8Binding.h"
+#include "V8Document.h"
+#include "V8CustomBinding.h"
+#include "V8ObjectEventListener.h"
+#include "V8Proxy.h"
+#include "V8Utilities.h"
+#include "WorkerContextExecutionProxy.h"
+
+namespace WebCore {
+
+static const bool kFindOnly = true;
+static const bool kFindOrCreate = false;
+
+static PassRefPtr<EventListener> argumentToEventListener(DOMApplicationCache* appcache, v8::Local<v8::Value> value, bool findOnly)
+{
+#if 0 && ENABLE(WORKERS)
+ // FIXME: this is not tested yet
+ WorkerContextExecutionProxy* workerContextProxy = WorkerContextExecutionProxy::retrieve();
+ if (workerContextProxy)
+ return workerContextProxy->findOrCreateObjectEventListener(value, false, findOnly);
+#endif
+
+ V8Proxy* proxy = V8Proxy::retrieve(appcache->scriptExecutionContext());
+ if (proxy)
+ return findOnly ? proxy->FindObjectEventListener(value, false)
+ : proxy->FindOrCreateObjectEventListener(value, false);
+ return 0;
+}
+
+static v8::Local<v8::Object> eventListenerToV8Object(EventListener* listener)
+{
+ return (static_cast<V8ObjectEventListener*>(listener))->getListenerObject();
+}
+
+static inline String toEventType(v8::Local<v8::String> value)
+{
+ String key = toWebCoreString(value);
+ ASSERT(key.startsWith("on"));
+ return key.substring(2);
+}
+
+// Handles appcache.onfooevent attribute getting
+ACCESSOR_GETTER(DOMApplicationCacheEventHandler)
+{
+ INC_STATS("DOMApplicationCache.onevent_getter");
+ DOMApplicationCache* appcache = V8Proxy::ToNativeObject<DOMApplicationCache>(V8ClassIndex::DOMAPPLICATIONCACHE, info.Holder());
+ EventListener* listener = appcache->getAttributeEventListener(toEventType(name));
+ return eventListenerToV8Object(listener);
+}
+
+// Handles appcache.onfooevent attribute setting
+ACCESSOR_SETTER(DOMApplicationCacheEventHandler)
+{
+ INC_STATS("DOMApplicationCache.onevent_setter");
+ DOMApplicationCache* appcache = V8Proxy::ToNativeObject<DOMApplicationCache>(V8ClassIndex::DOMAPPLICATIONCACHE, info.Holder());
+ String eventType = toEventType(name);
+
+ if (EventListener* oldListener = appcache->getAttributeEventListener(eventType)) {
+ v8::Local<v8::Object> object = eventListenerToV8Object(oldListener);
+ removeHiddenDependency(info.Holder(), object, V8Custom::kDOMApplicationCacheCacheIndex);
+ appcache->clearAttributeEventListener(eventType);
+ }
+
+ if (value->IsFunction()) {
+ RefPtr<EventListener> newListener = argumentToEventListener(appcache, value, kFindOrCreate);
+ if (newListener) {
+ createHiddenDependency(info.Holder(), value, V8Custom::kDOMApplicationCacheCacheIndex);
+ appcache->setAttributeEventListener(eventType, newListener);
+ }
+ }
+}
+
+// Handles appcache.addEventListner(name, func, capture) method calls
+CALLBACK_FUNC_DECL(DOMApplicationCacheAddEventListener)
+{
+ INC_STATS("DOMApplicationCache.addEventListener()");
+ DOMApplicationCache* appcache = V8Proxy::ToNativeObject<DOMApplicationCache>(V8ClassIndex::DOMAPPLICATIONCACHE, args.Holder());
+
+ RefPtr<EventListener> listener = argumentToEventListener(appcache, args[1], kFindOrCreate);
+ if (listener) {
+ createHiddenDependency(args.Holder(), args[1], V8Custom::kDOMApplicationCacheCacheIndex);
+ String eventType = toWebCoreString(args[0]);
+ bool useCapture = args[2]->BooleanValue();
+ appcache->addEventListener(eventType, listener, useCapture);
+ }
+ return v8::Undefined();
+}
+
+// Handles appcache.removeEventListner(name, func, capture) method calls
+CALLBACK_FUNC_DECL(DOMApplicationCacheRemoveEventListener)
+{
+ INC_STATS("DOMApplicationCache.removeEventListener()");
+ DOMApplicationCache* appcache = V8Proxy::ToNativeObject<DOMApplicationCache>(V8ClassIndex::DOMAPPLICATIONCACHE, args.Holder());
+
+ RefPtr<EventListener> listener = argumentToEventListener(appcache, args[1], kFindOnly);
+ if (listener) {
+ removeHiddenDependency(args.Holder(), args[1], V8Custom::kDOMApplicationCacheCacheIndex);
+ String eventType = toWebCoreString(args[0]);
+ bool useCapture = args[2]->BooleanValue();
+ appcache->removeEventListener(eventType, listener.get(), useCapture);
+ }
+ return v8::Undefined();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(OFFLINE_WEB_APPLICATIONS)
diff --git a/WebCore/loader/appcache/DOMApplicationCache.cpp b/WebCore/loader/appcache/DOMApplicationCache.cpp
index 90d2930..12d86a7 100644
--- a/WebCore/loader/appcache/DOMApplicationCache.cpp
+++ b/WebCore/loader/appcache/DOMApplicationCache.cpp
@@ -298,6 +298,51 @@ void DOMApplicationCache::callObsoleteListener()
callListener(eventNames().obsoleteEvent, m_onObsoleteListener.get());
}
+#if USE(V8)
+RefPtr<EventListener>* DOMApplicationCache::getAttributeEventListenerStorage(const AtomicString& eventType)
+{
+ if (eventType == eventNames().checkingEvent)
+ return &m_onCheckingListener;
+ else if (eventType == eventNames().errorEvent)
+ return &m_onErrorListener;
+ else if (eventType == eventNames().noupdateEvent)
+ return &m_onNoUpdateListener;
+ else if (eventType == eventNames().downloadingEvent)
+ return &m_onDownloadingListener;
+ else if (eventType == eventNames().progressEvent)
+ return &m_onProgressListener;
+ else if (eventType == eventNames().updatereadyEvent)
+ return &m_onUpdateReadyListener;
+ else if (eventType == eventNames().cachedEvent)
+ return &m_onCachedListener;
+ else if (eventType == eventNames().obsoleteEvent)
+ return &m_onObsoleteListener;
+ else
+ return 0;
+}
+
+EventListener* DOMApplicationCache::getAttributeEventListener(const AtomicString& eventType)
+{
+ RefPtr<EventListener>* storage = getAttributeEventListenerStorage(eventType);
+ ASSERT(storage);
+ return (*storage).get();
+}
+
+void DOMApplicationCache::setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener)
+{
+ RefPtr<EventListener>* storage = getAttributeEventListenerStorage(eventType);
+ ASSERT(storage);
+ (*storage) = listener;
+}
+
+void DOMApplicationCache::clearAttributeEventListener(const AtomicString& eventType)
+{
+ RefPtr<EventListener>* storage = getAttributeEventListenerStorage(eventType);
+ ASSERT(storage);
+ (*storage) = 0;
+}
+#endif
+
} // namespace WebCore
#endif // ENABLE(OFFLINE_WEB_APPLICATIONS)
diff --git a/WebCore/loader/appcache/DOMApplicationCache.h b/WebCore/loader/appcache/DOMApplicationCache.h
index b76542d..57b37bc 100644
--- a/WebCore/loader/appcache/DOMApplicationCache.h
+++ b/WebCore/loader/appcache/DOMApplicationCache.h
@@ -115,6 +115,12 @@ public:
void callUpdateReadyListener();
void callCachedListener();
void callObsoleteListener();
+
+#if USE(V8)
+ EventListener* getAttributeEventListener(const AtomicString& eventType);
+ void setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener);
+ void clearAttributeEventListener(const AtomicString& eventType);
+#endif
private:
DOMApplicationCache(Frame*);
@@ -125,6 +131,10 @@ private:
ApplicationCache* associatedCache() const;
bool swapCache();
+
+#if USE(V8)
+ RefPtr<EventListener>* getAttributeEventListenerStorage(const AtomicString& eventType);
+#endif
RefPtr<EventListener> m_onCheckingListener;
RefPtr<EventListener> m_onErrorListener;