diff options
author | dglazkov@google.com <dglazkov@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-30 18:48:28 +0000 |
---|---|---|
committer | dglazkov@google.com <dglazkov@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-30 18:48:28 +0000 |
commit | 074ff16d3029256a9585529cad5487c1ae6eb409 (patch) | |
tree | e4d57cd79c533507a632ebf70c8ea8850113a9fc /webkit/port | |
parent | 332ff119039b7dd3ba3d1994dde0b077f015bc03 (diff) | |
download | chromium_src-074ff16d3029256a9585529cad5487c1ae6eb409.zip chromium_src-074ff16d3029256a9585529cad5487c1ae6eb409.tar.gz chromium_src-074ff16d3029256a9585529cad5487c1ae6eb409.tar.bz2 |
Landing 36102:37604 merge on trunk
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@4222 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/port')
49 files changed, 1497 insertions, 3260 deletions
diff --git a/webkit/port/DerivedSources.make b/webkit/port/DerivedSources.make index f0a0dad..e832dec 100644 --- a/webkit/port/DerivedSources.make +++ b/webkit/port/DerivedSources.make @@ -32,6 +32,7 @@ VPATH = \ $(PORTROOT)/html \ $(PORTROOT)/page \ $(PORTROOT)/page/inspector \ + $(PORTROOT)/svg \ $(PORTROOT)/xml \ $(PORTROOT)/ksvg2/svg \ $(PORTROOT)/ksvg2/events \ @@ -733,7 +734,9 @@ all : \ V8ImageData.h \ V8KeyboardEvent.h \ V8MediaList.h \ + V8MessageChannel.h \ V8MessageEvent.h \ + V8MessagePort.h \ V8MouseEvent.h \ V8MutationEvent.h \ V8NamedNodeMap.h \ @@ -742,7 +745,6 @@ all : \ V8NodeIterator.h \ V8NodeList.h \ V8Notation.h \ - V8NSResolver.h \ V8OverflowEvent.h \ V8ProcessingInstruction.h \ V8ProgressEvent.h \ @@ -918,7 +920,6 @@ all : \ XPathGrammar.cpp \ tokenizer.cpp \ V8Clipboard.h \ - V8HTMLSelectionInputElement.h \ V8InspectorController.h \ V8Location.h \ V8Navigator.h \ diff --git a/webkit/port/bindings/scripts/CodeGeneratorV8.pm b/webkit/port/bindings/scripts/CodeGeneratorV8.pm index 99e447c..87353ca 100644 --- a/webkit/port/bindings/scripts/CodeGeneratorV8.pm +++ b/webkit/port/bindings/scripts/CodeGeneratorV8.pm @@ -224,7 +224,6 @@ sub GetImplementationFileName { my $iface = shift; return "HTMLCollection.h" if $iface eq "UndetectableHTMLCollection"; - return "HTMLInputElement.h" if $iface eq "HTMLSelectionInputElement"; return "Event.h" if $iface eq "DOMTimeStamp"; return "NamedAttrMap.h" if $iface eq "NamedNodeMap"; return "NameNodeList.h" if $iface eq "NodeList"; @@ -240,7 +239,7 @@ sub GenerateHeader my $interfaceName = $dataNode->name; my $className = "V8$interfaceName"; - my $implClassName = GetImplementationClassName($interfaceName); + my $implClassName = $interfaceName; # Copy contents of parent classes except the first parent or if it is # EventTarget. @@ -426,11 +425,12 @@ sub GenerateNormalAttrGetter my $isPodType = $codeGenerator->IsPodType($implClassName); my $skipContext = 0; + if ($isPodType) { $implClassName = GetNativeType($implClassName); $implIncludes{"V8SVGPODTypeWrapper.h"} = 1; } - + # Special case: SVGZoomEvent's attributes are all read-only if ($implClassName eq "SVGZoomEvent") { $attrIsPodType = 0; @@ -830,7 +830,7 @@ sub GenerateImplementation my $dataNode = shift; my $interfaceName = $dataNode->name; my $className = "V8$interfaceName"; - my $implClassName = GetImplementationClassName($interfaceName); + my $implClassName = $interfaceName; my $classIndex = uc($codeGenerator->StripModule($interfaceName)); my $hasLegacyParent = $dataNode->extendedAttributes->{"LegacyParent"}; @@ -867,7 +867,8 @@ sub GenerateImplementation my $hasConstructors = 0; # Generate property accessors for attributes. - foreach my $attribute (@{$dataNode->attributes}) { + for ($index = 0; $index < @{$dataNode->attributes}; $index++) { + $attribute = @{$dataNode->attributes}[$index]; $attrName = $attribute->signature->name; $attrType = $attribute->signature->type; @@ -876,6 +877,18 @@ sub GenerateImplementation $hasConstructors = 1; next; } + + # Make EventListeners always custom. + # TODO(mbelshe): make the perl code capable of generating the + # event setters/getters. For now, WebKit has started removing the + # [Custom] attribute, so just automatically insert it to avoid forking + # other files. This should be okay because we can't generate stubs + # for any event getter/setters anyway. + if ($attrType eq "EventListener") { + $attribute->signature->extendedAttributes->{"Custom"} = 1; + $implIncludes{"v8_custom.h"} = 1; + next; + } # Do not generate accessor if this is a custom attribute. The # call will be forwarded to a hand-written accessor @@ -884,7 +897,7 @@ sub GenerateImplementation $implIncludes{"v8_custom.h"} = 1; next; } - + # Generate the accessor. if ($attribute->signature->extendedAttributes->{"CustomGetter"}) { $implIncludes{"v8_custom.h"} = 1; @@ -1374,21 +1387,10 @@ sub GetClassName { my $type = shift; return "HTMLCollection" if $type eq "UndetectableHTMLCollection"; - return "HTMLInputElement" if $type eq "HTMLSelectionInputElement"; return $type; } -sub GetImplementationClassName -{ - my $type = shift; - - return "HTMLInputElement" if $type eq "HTMLSelectionInputElement"; - - return $type; -} - - sub GetNativeTypeFromSignature { my $signature = shift; @@ -1484,9 +1486,6 @@ sub GetNativeType 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; @@ -1511,6 +1510,7 @@ my %typeCanFailConversion = ( "HTMLOptionElement" => 0, "Node" => 0, "NodeFilter" => 0, + "MessagePort" => 0, "NSResolver" => 0, "Range" => 0, "SQLResultSet" => 0, @@ -1615,7 +1615,7 @@ sub JSValueToNative } else { # TODO: Temporary to avoid Window name conflict. my $classIndex = uc($type); - my $implClassName = GetImplementationClassName(${type}); + my $implClassName = ${type}; $implIncludes{"V8$type.h"} = 1; @@ -1777,7 +1777,7 @@ sub NativeToJSValue } # V8 specific. - my $implClassName = GetImplementationClassName($type); + my $implClassName = $type; AddIncludesForType($type); # $implIncludes{GetImplementationFileName($type)} = 1 unless AvoidInclusionOfType($type); diff --git a/webkit/port/bindings/v8/JSNSResolver.cpp b/webkit/port/bindings/v8/JSNSResolver.cpp deleted file mode 100644 index 5251a35..0000000 --- a/webkit/port/bindings/v8/JSNSResolver.cpp +++ /dev/null @@ -1,99 +0,0 @@ -// 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/ScriptController.h b/webkit/port/bindings/v8/ScriptController.h index aa4a46b..d23ca65 100644 --- a/webkit/port/bindings/v8/ScriptController.h +++ b/webkit/port/bindings/v8/ScriptController.h @@ -34,6 +34,7 @@ #define ScriptController_h #include "HashMap.h" +#include "SecurityOrigin.h" #include "bindings/npruntime.h" diff --git a/webkit/port/bindings/v8/V8MessagePortCustom.cpp b/webkit/port/bindings/v8/V8MessagePortCustom.cpp new file mode 100644 index 0000000..8e4c3a9 --- /dev/null +++ b/webkit/port/bindings/v8/V8MessagePortCustom.cpp @@ -0,0 +1,232 @@ +// 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 "MessagePort.h" + +namespace WebCore { + +// TODO(mbelshe) - merge these with XHR's CreateHiddenXHRDependency + +// 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 CreateHiddenDependency(v8::Local<v8::Object> object, + v8::Local<v8::Value> value) { + ASSERT(V8Proxy::GetDOMWrapperType(object) == + V8ClassIndex::MESSAGEPORT); + v8::Local<v8::Value> cache = + object->GetInternalField(V8Custom::kMessagePortRequestCacheIndex); + if (cache->IsNull() || cache->IsUndefined()) { + cache = v8::Array::New(); + object->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 RemoveHiddenDependency(v8::Local<v8::Object> object, + v8::Local<v8::Value> value) { + ASSERT(V8Proxy::GetDOMWrapperType(object) == V8ClassIndex::MESSAGEPORT); + v8::Local<v8::Value> cache = + object->GetInternalField(V8Custom::kMessagePortRequestCacheIndex); + 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(MessagePortOnmessage) { + INC_STATS(L"DOM.MessagePort.onmessage._get"); + MessagePort* imp = V8Proxy::ToNativeObject<MessagePort>( + V8ClassIndex::MESSAGEPORT, info.Holder()); + if (imp->onmessage()) { + V8ObjectEventListener* listener = + static_cast<V8ObjectEventListener*>(imp->onmessage()); + v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); + return v8_listener; + } + return v8::Undefined(); +} + +ACCESSOR_SETTER(MessagePortOnmessage) { + INC_STATS(L"DOM.MessagePort.onmessage._set"); + MessagePort* imp = V8Proxy::ToNativeObject<MessagePort>( + V8ClassIndex::MESSAGEPORT, info.Holder()); + if (value->IsNull()) { + if (imp->onmessage()) { + V8ObjectEventListener* listener = + static_cast<V8ObjectEventListener*>(imp->onmessage()); + v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); + RemoveHiddenDependency(info.Holder(), v8_listener); + } + + // Clear the listener + imp->setOnmessage(0); + + } else { + V8Proxy* proxy = V8Proxy::retrieve(imp->document()->frame()); + if (!proxy) + return; + + RefPtr<EventListener> listener = + proxy->FindOrCreateObjectEventListener(value, false); + if (listener) { + imp->setOnmessage(listener); + CreateHiddenDependency(info.Holder(), value); + } + } +} + +ACCESSOR_GETTER(MessagePortOnclose) { + INC_STATS(L"DOM.MessagePort.onclose._get"); + MessagePort* imp = V8Proxy::ToNativeObject<MessagePort>( + V8ClassIndex::MESSAGEPORT, info.Holder()); + if (imp->onclose()) { + V8ObjectEventListener* listener = + static_cast<V8ObjectEventListener*>(imp->onclose()); + v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); + return v8_listener; + } + return v8::Undefined(); +} + +ACCESSOR_SETTER(MessagePortOnclose) { + INC_STATS(L"DOM.MessagePort.onclose._set"); + MessagePort* imp = V8Proxy::ToNativeObject<MessagePort>( + V8ClassIndex::MESSAGEPORT, info.Holder()); + if (value->IsNull()) { + if (imp->onclose()) { + V8ObjectEventListener* listener = + static_cast<V8ObjectEventListener*>(imp->onclose()); + v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); + RemoveHiddenDependency(info.Holder(), v8_listener); + } + + // Clear the listener + imp->setOnclose(0); + } else { + V8Proxy* proxy = V8Proxy::retrieve(imp->document()->frame()); + if (!proxy) + return; + + RefPtr<EventListener> listener = + proxy->FindOrCreateObjectEventListener(value, false); + if (listener) { + imp->setOnclose(listener); + CreateHiddenDependency(info.Holder(), value); + } + } +} + +CALLBACK_FUNC_DECL(MessagePortStartConversation) { + INC_STATS(L"DOM.MessagePort.StartConversation()"); + if (args.Length() < 1) { + V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "Not enough arguments"); + return v8::Undefined(); + } + + MessagePort* imp = V8Proxy::ToNativeObject<MessagePort>( + V8ClassIndex::MESSAGEPORT, args.Holder()); + + V8Proxy* proxy = V8Proxy::retrieve(imp->document()->frame()); + if (!proxy) + return v8::Undefined(); + + RefPtr<MessagePort> port = imp->startConversation(imp->document(), + ToWebCoreString(args[0])); + v8::Handle<v8::Value> wrapper = + V8Proxy::ToV8Object(V8ClassIndex::MESSAGEPORT, port.get()); + return wrapper; +} + +CALLBACK_FUNC_DECL(MessagePortAddEventListener) { + INC_STATS(L"DOM.MessagePort.AddEventListener()"); + MessagePort* imp = V8Proxy::ToNativeObject<MessagePort>( + V8ClassIndex::MESSAGEPORT, args.Holder()); + + V8Proxy* proxy = V8Proxy::retrieve(imp->document()->frame()); + if (!proxy) + return v8::Undefined(); + + RefPtr<EventListener> listener = + proxy->FindOrCreateObjectEventListener(args[1], false); + if (listener) { + String type = ToWebCoreString(args[0]); + bool useCapture = args[2]->BooleanValue(); + imp->addEventListener(type, listener, useCapture); + + CreateHiddenDependency(args.Holder(), args[1]); + } + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(MessagePortRemoveEventListener) { + INC_STATS(L"DOM.MessagePort.RemoveEventListener()"); + MessagePort* imp = V8Proxy::ToNativeObject<MessagePort>( + V8ClassIndex::MESSAGEPORT, args.Holder()); + + V8Proxy* proxy = V8Proxy::retrieve(imp->document()->frame()); + if (!proxy) + return v8::Undefined(); // probably leaked + + RefPtr<EventListener> listener = + proxy->FindObjectEventListener(args[1], false); + + if (listener) { + String type = ToWebCoreString(args[0]); + bool useCapture = args[2]->BooleanValue(); + imp->removeEventListener(type, listener.get(), useCapture); + + RemoveHiddenDependency(args.Holder(), args[1]); + } + + return v8::Undefined(); +} + + +} // namespace WebCore diff --git a/webkit/port/bindings/v8/V8XMLHttpRequestCustom.cpp b/webkit/port/bindings/v8/V8XMLHttpRequestCustom.cpp index ce4c84d..d61a8c32 100644 --- a/webkit/port/bindings/v8/V8XMLHttpRequestCustom.cpp +++ b/webkit/port/bindings/v8/V8XMLHttpRequestCustom.cpp @@ -107,9 +107,9 @@ 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()); + if (imp->onabort()) { + V8ObjectEventListener* listener = + static_cast<V8ObjectEventListener*>(imp->onabort()); v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); return v8_listener; } @@ -121,24 +121,24 @@ ACCESSOR_SETTER(XMLHttpRequestOnabort) { XMLHttpRequest* imp = V8Proxy::ToNativeObject<XMLHttpRequest>( V8ClassIndex::XMLHTTPREQUEST, info.Holder()); if (value->IsNull()) { - if (imp->onAbortListener()) { - V8XHREventListener* listener = - static_cast<V8XHREventListener*>(imp->onAbortListener()); + if (imp->onabort()) { + V8ObjectEventListener* listener = + static_cast<V8ObjectEventListener*>(imp->onabort()); v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); RemoveHiddenXHRDependency(info.Holder(), v8_listener); } // Clear the listener - imp->setOnAbortListener(0); + imp->setOnabort(0); } else { V8Proxy* proxy = V8Proxy::retrieve(imp->document()->frame()); if (!proxy) return; RefPtr<EventListener> listener = - proxy->FindOrCreateXHREventListener(value, false); + proxy->FindOrCreateObjectEventListener(value, false); if (listener) { - imp->setOnAbortListener(listener); + imp->setOnabort(listener); CreateHiddenXHRDependency(info.Holder(), value); } } @@ -148,9 +148,9 @@ ACCESSOR_GETTER(XMLHttpRequestOnerror) { INC_STATS(L"DOM.XMLHttpRequest.onerror._get"); XMLHttpRequest* imp = V8Proxy::ToNativeObject<XMLHttpRequest>( V8ClassIndex::XMLHTTPREQUEST, info.Holder()); - if (imp->onErrorListener()) { - RefPtr<V8XHREventListener> listener = - static_cast<V8XHREventListener*>(imp->onErrorListener()); + if (imp->onerror()) { + RefPtr<V8ObjectEventListener> listener = + static_cast<V8ObjectEventListener*>(imp->onerror()); v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); return v8_listener; } @@ -162,24 +162,24 @@ ACCESSOR_SETTER(XMLHttpRequestOnerror) { XMLHttpRequest* imp = V8Proxy::ToNativeObject<XMLHttpRequest>( V8ClassIndex::XMLHTTPREQUEST, info.Holder()); if (value->IsNull()) { - if (imp->onErrorListener()) { - V8XHREventListener* listener = - static_cast<V8XHREventListener*>(imp->onErrorListener()); + if (imp->onerror()) { + V8ObjectEventListener* listener = + static_cast<V8ObjectEventListener*>(imp->onerror()); v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); RemoveHiddenXHRDependency(info.Holder(), v8_listener); } // Clear the listener - imp->setOnErrorListener(0); + imp->setOnerror(0); } else { V8Proxy* proxy = V8Proxy::retrieve(imp->document()->frame()); if (!proxy) return; RefPtr<EventListener> listener = - proxy->FindOrCreateXHREventListener(value, false); + proxy->FindOrCreateObjectEventListener(value, false); if (listener) { - imp->setOnErrorListener(listener); + imp->setOnerror(listener); CreateHiddenXHRDependency(info.Holder(), value); } } @@ -189,9 +189,9 @@ 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()); + if (imp->onload()) { + V8ObjectEventListener* listener = + static_cast<V8ObjectEventListener*>(imp->onload()); v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); return v8_listener; } @@ -205,7 +205,7 @@ ACCESSOR_SETTER(XMLHttpRequestOnload) V8ClassIndex::XMLHTTPREQUEST, info.Holder()); if (value->IsNull()) { if (imp->onload()) { - V8XHREventListener* listener = static_cast<V8XHREventListener*>(imp->onload()); + V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(imp->onload()); v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); RemoveHiddenXHRDependency(info.Holder(), v8_listener); } @@ -218,7 +218,7 @@ ACCESSOR_SETTER(XMLHttpRequestOnload) return; RefPtr<EventListener> listener = - proxy->FindOrCreateXHREventListener(value, false); + proxy->FindOrCreateObjectEventListener(value, false); if (listener) { imp->setOnload(listener.get()); CreateHiddenXHRDependency(info.Holder(), value); @@ -230,9 +230,9 @@ 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()); + if (imp->onloadstart()) { + V8ObjectEventListener* listener = + static_cast<V8ObjectEventListener*>(imp->onloadstart()); v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); return v8_listener; } @@ -244,24 +244,24 @@ ACCESSOR_SETTER(XMLHttpRequestOnloadstart) { XMLHttpRequest* imp = V8Proxy::ToNativeObject<XMLHttpRequest>( V8ClassIndex::XMLHTTPREQUEST, info.Holder()); if (value->IsNull()) { - if (imp->onLoadStartListener()) { - V8XHREventListener* listener = - static_cast<V8XHREventListener*>(imp->onLoadStartListener()); + if (imp->onloadstart()) { + V8ObjectEventListener* listener = + static_cast<V8ObjectEventListener*>(imp->onloadstart()); v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); RemoveHiddenXHRDependency(info.Holder(), v8_listener); } // Clear the listener - imp->setOnLoadStartListener(0); + imp->setOnloadstart(0); } else { V8Proxy* proxy = V8Proxy::retrieve(imp->document()->frame()); if (!proxy) return; RefPtr<EventListener> listener = - proxy->FindOrCreateXHREventListener(value, false); + proxy->FindOrCreateObjectEventListener(value, false); if (listener) { - imp->setOnLoadStartListener(listener); + imp->setOnloadstart(listener); CreateHiddenXHRDependency(info.Holder(), value); } } @@ -271,9 +271,9 @@ 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()); + if (imp->onprogress()) { + V8ObjectEventListener* listener = + static_cast<V8ObjectEventListener*>(imp->onprogress()); v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); return v8_listener; } @@ -285,24 +285,24 @@ ACCESSOR_SETTER(XMLHttpRequestOnprogress) { XMLHttpRequest* imp = V8Proxy::ToNativeObject<XMLHttpRequest>( V8ClassIndex::XMLHTTPREQUEST, info.Holder()); if (value->IsNull()) { - if (imp->onProgressListener()) { - V8XHREventListener* listener = - static_cast<V8XHREventListener*>(imp->onProgressListener()); + if (imp->onprogress()) { + V8ObjectEventListener* listener = + static_cast<V8ObjectEventListener*>(imp->onprogress()); v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); RemoveHiddenXHRDependency(info.Holder(), v8_listener); } // Clear the listener - imp->setOnProgressListener(0); + imp->setOnprogress(0); } else { V8Proxy* proxy = V8Proxy::retrieve(imp->document()->frame()); if (!proxy) return; RefPtr<EventListener> listener = - proxy->FindOrCreateXHREventListener(value, false); + proxy->FindOrCreateObjectEventListener(value, false); if (listener) { - imp->setOnProgressListener(listener); + imp->setOnprogress(listener); CreateHiddenXHRDependency(info.Holder(), value); } } @@ -312,9 +312,9 @@ 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()); + if (imp->onreadystatechange()) { + V8ObjectEventListener* listener = + static_cast<V8ObjectEventListener*>(imp->onreadystatechange()); v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); return v8_listener; } @@ -328,8 +328,8 @@ ACCESSOR_SETTER(XMLHttpRequestOnreadystatechange) V8ClassIndex::XMLHTTPREQUEST, info.Holder()); if (value->IsNull()) { if (imp->onreadystatechange()) { - V8XHREventListener* listener = - static_cast<V8XHREventListener*>(imp->onreadystatechange()); + V8ObjectEventListener* listener = + static_cast<V8ObjectEventListener*>(imp->onreadystatechange()); v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); RemoveHiddenXHRDependency(info.Holder(), v8_listener); } @@ -342,7 +342,7 @@ ACCESSOR_SETTER(XMLHttpRequestOnreadystatechange) return; RefPtr<EventListener> listener = - proxy->FindOrCreateXHREventListener(value, false); + proxy->FindOrCreateObjectEventListener(value, false); if (listener) { imp->setOnreadystatechange(listener.get()); CreateHiddenXHRDependency(info.Holder(), value); @@ -361,7 +361,7 @@ CALLBACK_FUNC_DECL(XMLHttpRequestAddEventListener) return v8::Undefined(); RefPtr<EventListener> listener = - proxy->FindOrCreateXHREventListener(args[1], false); + proxy->FindOrCreateObjectEventListener(args[1], false); if (listener) { String type = ToWebCoreString(args[0]); bool useCapture = args[2]->BooleanValue(); @@ -382,7 +382,7 @@ CALLBACK_FUNC_DECL(XMLHttpRequestRemoveEventListener) { return v8::Undefined(); // probably leaked RefPtr<EventListener> listener = - proxy->FindXHREventListener(args[1], false); + proxy->FindObjectEventListener(args[1], false); if (listener) { String type = ToWebCoreString(args[0]); @@ -544,9 +544,9 @@ 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()); + if (imp->onabort()) { + V8ObjectEventListener* listener = + static_cast<V8ObjectEventListener*>(imp->onabort()); v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); return v8_listener; } @@ -558,15 +558,15 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnabort) { XMLHttpRequestUpload* imp = V8Proxy::ToNativeObject<XMLHttpRequestUpload>( V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder()); if (value->IsNull()) { - if (imp->onAbortListener()) { - V8XHREventListener* listener = - static_cast<V8XHREventListener*>(imp->onAbortListener()); + if (imp->onabort()) { + V8ObjectEventListener* listener = + static_cast<V8ObjectEventListener*>(imp->onabort()); v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); RemoveHiddenXHRDependency(info.Holder(), v8_listener); } // Clear the listener - imp->setOnAbortListener(0); + imp->setOnabort(0); } else { XMLHttpRequest* xmlhttprequest = imp->associatedXMLHttpRequest(); V8Proxy* proxy = V8Proxy::retrieve(xmlhttprequest->document()->frame()); @@ -574,9 +574,9 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnabort) { return; RefPtr<EventListener> listener = - proxy->FindOrCreateXHREventListener(value, false); + proxy->FindOrCreateObjectEventListener(value, false); if (listener) { - imp->setOnAbortListener(listener); + imp->setOnabort(listener); CreateHiddenXHRDependency(info.Holder(), value); } } @@ -586,9 +586,9 @@ 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()); + if (imp->onerror()) { + V8ObjectEventListener* listener = + static_cast<V8ObjectEventListener*>(imp->onerror()); v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); return v8_listener; } @@ -600,15 +600,15 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnerror) { XMLHttpRequestUpload* imp = V8Proxy::ToNativeObject<XMLHttpRequestUpload>( V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder()); if (value->IsNull()) { - if (imp->onErrorListener()) { - V8XHREventListener* listener = - static_cast<V8XHREventListener*>(imp->onErrorListener()); + if (imp->onerror()) { + V8ObjectEventListener* listener = + static_cast<V8ObjectEventListener*>(imp->onerror()); v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); RemoveHiddenXHRDependency(info.Holder(), v8_listener); } // Clear the listener - imp->setOnErrorListener(0); + imp->setOnerror(0); } else { XMLHttpRequest* xmlhttprequest = imp->associatedXMLHttpRequest(); V8Proxy* proxy = V8Proxy::retrieve(xmlhttprequest->document()->frame()); @@ -616,9 +616,9 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnerror) { return; RefPtr<EventListener> listener = - proxy->FindOrCreateXHREventListener(value, false); + proxy->FindOrCreateObjectEventListener(value, false); if (listener) { - imp->setOnErrorListener(listener); + imp->setOnerror(listener); CreateHiddenXHRDependency(info.Holder(), value); } } @@ -628,9 +628,9 @@ 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()); + if (imp->onload()) { + V8ObjectEventListener* listener = + static_cast<V8ObjectEventListener*>(imp->onload()); v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); return v8_listener; } @@ -642,15 +642,15 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnload) { XMLHttpRequestUpload* imp = V8Proxy::ToNativeObject<XMLHttpRequestUpload>( V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder()); if (value->IsNull()) { - if (imp->onLoadListener()) { - V8XHREventListener* listener = - static_cast<V8XHREventListener*>(imp->onLoadListener()); + if (imp->onload()) { + V8ObjectEventListener* listener = + static_cast<V8ObjectEventListener*>(imp->onload()); v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); RemoveHiddenXHRDependency(info.Holder(), v8_listener); } // Clear the listener - imp->setOnLoadListener(0); + imp->setOnload(0); } else { XMLHttpRequest* xmlhttprequest = imp->associatedXMLHttpRequest(); V8Proxy* proxy = V8Proxy::retrieve(xmlhttprequest->document()->frame()); @@ -658,9 +658,9 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnload) { return; RefPtr<EventListener> listener = - proxy->FindOrCreateXHREventListener(value, false); + proxy->FindOrCreateObjectEventListener(value, false); if (listener) { - imp->setOnLoadListener(listener); + imp->setOnload(listener); CreateHiddenXHRDependency(info.Holder(), value); } } @@ -670,9 +670,9 @@ 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()); + if (imp->onloadstart()) { + V8ObjectEventListener* listener = + static_cast<V8ObjectEventListener*>(imp->onloadstart()); v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); return v8_listener; } @@ -684,15 +684,15 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnloadstart) { XMLHttpRequestUpload* imp = V8Proxy::ToNativeObject<XMLHttpRequestUpload>( V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder()); if (value->IsNull()) { - if (imp->onLoadStartListener()) { - V8XHREventListener* listener = - static_cast<V8XHREventListener*>(imp->onLoadStartListener()); + if (imp->onloadstart()) { + V8ObjectEventListener* listener = + static_cast<V8ObjectEventListener*>(imp->onloadstart()); v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); RemoveHiddenXHRDependency(info.Holder(), v8_listener); } // Clear the listener - imp->setOnLoadStartListener(0); + imp->setOnloadstart(0); } else { XMLHttpRequest* xmlhttprequest = imp->associatedXMLHttpRequest(); V8Proxy* proxy = V8Proxy::retrieve(xmlhttprequest->document()->frame()); @@ -700,9 +700,9 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnloadstart) { return; RefPtr<EventListener> listener = - proxy->FindOrCreateXHREventListener(value, false); + proxy->FindOrCreateObjectEventListener(value, false); if (listener) { - imp->setOnLoadStartListener(listener); + imp->setOnloadstart(listener); CreateHiddenXHRDependency(info.Holder(), value); } } @@ -712,9 +712,9 @@ 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()); + if (imp->onprogress()) { + V8ObjectEventListener* listener = + static_cast<V8ObjectEventListener*>(imp->onprogress()); v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); return v8_listener; } @@ -726,15 +726,15 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnprogress) { XMLHttpRequestUpload* imp = V8Proxy::ToNativeObject<XMLHttpRequestUpload>( V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder()); if (value->IsNull()) { - if (imp->onProgressListener()) { - V8XHREventListener* listener = - static_cast<V8XHREventListener*>(imp->onProgressListener()); + if (imp->onprogress()) { + V8ObjectEventListener* listener = + static_cast<V8ObjectEventListener*>(imp->onprogress()); v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); RemoveHiddenXHRDependency(info.Holder(), v8_listener); } // Clear the listener - imp->setOnProgressListener(0); + imp->setOnprogress(0); } else { XMLHttpRequest* xmlhttprequest = imp->associatedXMLHttpRequest(); V8Proxy* proxy = V8Proxy::retrieve(xmlhttprequest->document()->frame()); @@ -742,9 +742,9 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnprogress) { return; RefPtr<EventListener> listener = - proxy->FindOrCreateXHREventListener(value, false); + proxy->FindOrCreateObjectEventListener(value, false); if (listener) { - imp->setOnProgressListener(listener); + imp->setOnprogress(listener); CreateHiddenXHRDependency(info.Holder(), value); } } @@ -761,7 +761,7 @@ CALLBACK_FUNC_DECL(XMLHttpRequestUploadAddEventListener) { return v8::Undefined(); RefPtr<EventListener> listener = - proxy->FindOrCreateXHREventListener(args[1], false); + proxy->FindOrCreateObjectEventListener(args[1], false); if (listener) { String type = ToWebCoreString(args[0]); bool useCapture = args[2]->BooleanValue(); @@ -783,7 +783,7 @@ CALLBACK_FUNC_DECL(XMLHttpRequestUploadRemoveEventListener) { return v8::Undefined(); // probably leaked RefPtr<EventListener> listener = - proxy->FindXHREventListener(args[1], false); + proxy->FindObjectEventListener(args[1], false); if (listener) { String type = ToWebCoreString(args[0]); diff --git a/webkit/port/bindings/v8/v8_custom.cpp b/webkit/port/bindings/v8/v8_custom.cpp index 827323a..9bb904d 100644 --- a/webkit/port/bindings/v8/v8_custom.cpp +++ b/webkit/port/bindings/v8/v8_custom.cpp @@ -43,7 +43,6 @@ #include "V8HTMLImageElement.h" #include "V8HTMLOptionElement.h" #include "V8Node.h" -#include "V8NSResolver.h" #include "V8XPathNSResolver.h" #include "V8XPathResult.h" @@ -80,15 +79,17 @@ #include "HTMLFrameSetElement.h" #include "HTMLIFrameElement.h" #include "HTMLImageElement.h" +#include "HTMLInputElement.h" #include "HTMLNames.h" #include "HTMLOptionElement.h" #include "HTMLOptionsCollection.h" #include "HTMLSelectElement.h" #include "History.h" -#include "JSNSResolver.h" #include "JSXPathNSResolver.h" #include "KURL.h" #include "Location.h" +#include "MessageChannel.h" +#include "MessagePort.h" #include "MouseEvent.h" #include "NodeIterator.h" #include "Page.h" @@ -110,6 +111,7 @@ #if ENABLE(SVG) #include "V8SVGPODTypeWrapper.h" +#include "SVGElementInstance.h" #include "SVGException.h" #include "SVGPathSeg.h" #endif @@ -260,6 +262,33 @@ CALLBACK_FUNC_DECL(DOMParserConstructor) { DOMParser>(args); } +// TODO(mbelshe): merge this with the XHR Constructor. +// The only difference is that this one takes an argument to its +// create call, the XHR does not. +CALLBACK_FUNC_DECL(MessageChannelConstructor) { + INC_STATS(L"DOM.MessageChannel.Constructor"); + if (!args.IsConstructCall()) { + V8Proxy::ThrowError(V8Proxy::TYPE_ERROR, + "DOM object constructor cannot be called as a function."); + return v8::Undefined(); + } + + // Get the document. + Frame* frame = V8Proxy::retrieveFrame(); + if (!frame) + return v8::Undefined(); + Document* document = frame->document(); + + // 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<MessageChannel> obj = MessageChannel::create(document); + V8Proxy::SetDOMWrapper(args.Holder(), V8ClassIndex::MESSAGECHANNEL, + obj.get()); + V8Proxy::SetJSWrapperForDOMObject( + obj.get(), v8::Persistent<v8::Object>::New(args.Holder())); + return args.Holder(); +} + CALLBACK_FUNC_DECL(XMLSerializerConstructor) { INC_STATS(L"DOM.XMLSerializer.Constructor"); @@ -859,19 +888,31 @@ CALLBACK_FUNC_DECL(DOMWindowPostMessage) { v8::TryCatch try_catch; String message = ToWebCoreString(args[0]); - String domain = ToWebCoreString(args[1]); + MessagePort* port = NULL; + String domain; + + // This function has variable arguments and can either be: + // postMessage(message, port, domain); + // or + // postMessage(message, domain); + if (args.Length() > 2) { + port = V8Proxy::ToNativeObject<MessagePort>( + V8ClassIndex::MESSAGEPORT, args[1]); + domain = valueToStringWithNullOrUndefinedCheck(args[2]); + } else { + domain = valueToStringWithNullOrUndefinedCheck(args[1]); + } if (try_catch.HasCaught()) return v8::Undefined(); - ExceptionCode ec; - window->postMessage(message, domain, source, ec); + ExceptionCode ec = 0; + window->postMessage(message, port, domain, source, ec); if (ec) V8Proxy::SetDOMException(ec); return v8::Undefined(); } - static bool canShowModalDialogNow(const Frame* frame) { // A frame can out live its page. See bug 1219613. if (!frame || !frame->page()) @@ -2324,6 +2365,18 @@ CALLBACK_FUNC_DECL(ConsoleWarn) { return v8::Undefined(); } +CALLBACK_FUNC_DECL(ConsoleDirxml) { + INC_STATS(L"DOM.Console.dirxml()"); + V8Proxy::SetDOMException(NOT_SUPPORTED_ERR); + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(ConsoleTrace) { + INC_STATS(L"DOM.Console.trace()"); + V8Proxy::SetDOMException(NOT_SUPPORTED_ERR); + return v8::Undefined(); +} + // Clipboard ------------------------------------------------------------------- @@ -2488,69 +2541,6 @@ 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()); @@ -2857,142 +2847,19 @@ CALLBACK_FUNC_DECL(DocumentEvaluate) { inResult = V8Proxy::ToNativeObject<XPathResult>( V8ClassIndex::XPATHRESULT, args[4]); } + + v8::TryCatch try_catch; RefPtr<XPathResult> result = imp->evaluate(expression, contextNode, resolver, type, inResult, ec); - if (ec != 0) { - V8Proxy::SetDOMException(ec); + if (try_catch.HasCaught() || ec != 0) { + if (!try_catch.HasCaught()) + V8Proxy::SetDOMException(ec); return v8::Handle<v8::Value>(); } return V8Proxy::ToV8Object(V8ClassIndex::XPATHRESULT, 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) { @@ -3291,14 +3158,6 @@ CALLBACK_FUNC_DECL(NodeFilterAcceptNode) { return v8::Undefined(); } -// NSResolver -CALLBACK_FUNC_DECL(NSResolverLookupNamespaceURI) { - INC_STATS(L"DOM.NSResolver.lookupNamespaceURI()"); - V8Proxy::SetDOMException(NOT_SUPPORTED_ERR); - return v8::Undefined(); -} - - static String EventNameFromAttributeName(const String& name) { ASSERT(name.startsWith("on")); String event_type = name.substring(2); @@ -3345,7 +3204,7 @@ ACCESSOR_SETTER(DOMWindowEventHandler) { if (value->IsNull()) { // Clear the event listener - doc->removeHTMLWindowEventListener(event_type); + doc->removeWindowEventListenerForType(event_type); } else { V8Proxy* proxy = V8Proxy::retrieve(imp->frame()); if (!proxy) @@ -3354,7 +3213,7 @@ ACCESSOR_SETTER(DOMWindowEventHandler) { RefPtr<EventListener> listener = proxy->FindOrCreateV8EventListener(value, true); if (listener) { - doc->setHTMLWindowEventListener(event_type, listener); + doc->setWindowEventListenerForType(event_type, listener); } } } @@ -3378,7 +3237,7 @@ ACCESSOR_GETTER(DOMWindowEventHandler) { String key = ToWebCoreString(name); String event_type = EventNameFromAttributeName(key); - EventListener* listener = doc->getHTMLWindowEventListener(event_type); + EventListener* listener = doc->windowEventListenerForType(event_type); return V8Proxy::EventListenerToV8Object(listener); } @@ -3406,10 +3265,10 @@ ACCESSOR_SETTER(ElementEventHandler) { RefPtr<EventListener> listener = proxy->FindOrCreateV8EventListener(value, true); if (listener) { - node->setHTMLEventListener(event_type, listener); + node->setEventListenerForType(event_type, listener); } } else { - node->removeHTMLEventListener(event_type); + node->removeEventListenerForType(event_type); } } @@ -3423,7 +3282,7 @@ ACCESSOR_GETTER(ElementEventHandler) { ASSERT(key.startsWith("on")); String event_type = key.substring(2); - EventListener* listener = node->getHTMLEventListener(event_type); + EventListener* listener = node->eventListenerForType(event_type); return V8Proxy::EventListenerToV8Object(listener); } @@ -3448,6 +3307,30 @@ ACCESSOR_SETTER(HTMLOptionsCollectionLength) { V8Proxy::SetDOMException(ec); } +ACCESSOR_GETTER(HTMLInputElementSelectionStart) { + INC_STATS(L"DOM.HTMLInputElement.selectionStart._get"); + v8::Handle<v8::Object> holder = info.Holder(); + HTMLInputElement* imp = V8Proxy::DOMWrapperToNode<HTMLInputElement>(holder); + + if (!imp->canHaveSelection()) + return v8::Undefined(); + + int v = imp->selectionStart(); + return v8::Integer::New(v); +} + +ACCESSOR_GETTER(HTMLInputElementSelectionEnd) { + INC_STATS(L"DOM.HTMLInputElement.selectionEnd._get"); + v8::Handle<v8::Object> holder = info.Holder(); + HTMLInputElement* imp = V8Proxy::DOMWrapperToNode<HTMLInputElement>(holder); + + if (!imp->canHaveSelection()) + return v8::Undefined(); + + int v = imp->selectionEnd(); + return v8::Integer::New(v); +} + #if ENABLE(SVG) ACCESSOR_GETTER(SVGLengthValue) { @@ -3510,6 +3393,48 @@ CALLBACK_FUNC_DECL(SVGMatrixRotateFromVector) { return V8Proxy::ToV8Object(V8ClassIndex::SVGMATRIX, peer); } +CALLBACK_FUNC_DECL(SVGElementInstanceAddEventListener) { + INC_STATS(L"DOM.SVGElementInstance.AddEventListener()"); + SVGElementInstance* instance = + V8Proxy::DOMWrapperToNative<SVGElementInstance>(args.Holder()); + + V8Proxy* proxy = V8Proxy::retrieve(instance->associatedFrame()); + if (!proxy) + return v8::Undefined(); + + RefPtr<EventListener> listener = + proxy->FindOrCreateV8EventListener(args[1], false); + if (listener) { + String type = ToWebCoreString(args[0]); + bool useCapture = args[2]->BooleanValue(); + instance->addEventListener(type, listener, useCapture); + } + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(SVGElementInstanceRemoveEventListener) { + INC_STATS(L"DOM.SVGElementInstance.RemoveEventListener()"); + SVGElementInstance* instance = + V8Proxy::DOMWrapperToNative<SVGElementInstance>(args.Holder()); + + V8Proxy* proxy = V8Proxy::retrieve(instance->associatedFrame()); + // It is possbile that the owner document of the node is detached + // from the frame, return immediately in this case. + // See issue 878909 + if (!proxy) + return v8::Undefined(); + + RefPtr<EventListener> listener = + proxy->FindV8EventListener(args[1], false); + if (listener) { + String type = ToWebCoreString(args[0]); + bool useCapture = args[2]->BooleanValue(); + instance->removeEventListener(type, listener.get(), useCapture); + } + + return v8::Undefined(); +} + #endif // ENABLE(SVG) // --------------- Security Checks ------------------------- diff --git a/webkit/port/bindings/v8/v8_custom.h b/webkit/port/bindings/v8/v8_custom.h index 302b80a..ef2fb4d 100644 --- a/webkit/port/bindings/v8/v8_custom.h +++ b/webkit/port/bindings/v8/v8_custom.h @@ -54,6 +54,11 @@ class V8Custom { static const int kXMLHttpRequestInternalFieldCount = kDefaultWrapperInternalFieldCount + 1; + static const int kMessagePortRequestCacheIndex = + kDefaultWrapperInternalFieldCount + 0; + static const int kMessagePortInternalFieldCount = + kDefaultWrapperInternalFieldCount + 1; + static const int kDOMWindowLocationIndex = kDefaultWrapperInternalFieldCount + 0; static const int kDOMWindowNavigatorIndex = @@ -172,6 +177,10 @@ DECLARE_PROPERTY_ACCESSOR_SETTER(AttrValue) // Customized setter of HTMLOptionsCollection length DECLARE_PROPERTY_ACCESSOR_SETTER(HTMLOptionsCollectionLength) +// Customized accessors for HTMLInputElement +DECLARE_PROPERTY_ACCESSOR_GETTER(HTMLInputElementSelectionStart) +DECLARE_PROPERTY_ACCESSOR_GETTER(HTMLInputElementSelectionEnd) + DECLARE_NAMED_ACCESS_CHECK(Location) DECLARE_INDEXED_ACCESS_CHECK(History) @@ -217,6 +226,7 @@ DECLARE_CALLBACK(DOMWindowShowModalDialog) DECLARE_CALLBACK(DOMWindowOpen) DECLARE_CALLBACK(DOMParserConstructor) +DECLARE_CALLBACK(MessageChannelConstructor) DECLARE_CALLBACK(XMLHttpRequestConstructor) DECLARE_CALLBACK(XMLSerializerConstructor) DECLARE_CALLBACK(XPathEvaluatorConstructor) @@ -258,6 +268,8 @@ DECLARE_CALLBACK(ConsoleProfile) DECLARE_CALLBACK(ConsoleProfileEnd) DECLARE_CALLBACK(ConsoleTimeEnd) DECLARE_CALLBACK(ConsoleWarn) +DECLARE_CALLBACK(ConsoleDirxml) +DECLARE_CALLBACK(ConsoleTrace) // Implementation of Clipboard attributes and methods. DECLARE_PROPERTY_ACCESSOR_GETTER(ClipboardTypes) @@ -360,8 +372,12 @@ DECLARE_NAMED_PROPERTY_GETTER(HTMLCollection) DECLARE_INDEXED_PROPERTY_GETTER(CanvasPixelArray) DECLARE_INDEXED_PROPERTY_SETTER(CanvasPixelArray) -// NSResolver -DECLARE_CALLBACK(NSResolverLookupNamespaceURI) +// MessagePort +DECLARE_PROPERTY_ACCESSOR(MessagePortOnmessage) +DECLARE_PROPERTY_ACCESSOR(MessagePortOnclose) +DECLARE_CALLBACK(MessagePortStartConversation) +DECLARE_CALLBACK(MessagePortAddEventListener) +DECLARE_CALLBACK(MessagePortRemoveEventListener) // SVG custom properties and callbacks #if ENABLE(SVG) @@ -369,6 +385,8 @@ DECLARE_PROPERTY_ACCESSOR_GETTER(SVGLengthValue) DECLARE_CALLBACK(SVGLengthConvertToSpecifiedUnits) DECLARE_CALLBACK(SVGMatrixInverse) DECLARE_CALLBACK(SVGMatrixRotateFromVector) +DECLARE_CALLBACK(SVGElementInstanceAddEventListener) +DECLARE_CALLBACK(SVGElementInstanceRemoveEventListener) #endif #undef DECLARE_INDEXED_ACCESS_CHECK diff --git a/webkit/port/bindings/v8/v8_events.cpp b/webkit/port/bindings/v8/v8_events.cpp index dd11bb2..bdd7e8a 100644 --- a/webkit/port/bindings/v8/v8_events.cpp +++ b/webkit/port/bindings/v8/v8_events.cpp @@ -61,8 +61,8 @@ V8AbstractEventListener::V8AbstractEventListener(Frame* frame, bool html) void V8AbstractEventListener::handleEvent(Event* event, bool isWindowEvent) { // EventListener could be disconnected from the frame. - ASSERT(m_frame); - if (!m_frame) return; + if (!m_frame) + return; // The callback function on XMLHttpRequest can clear the event listener // and destroys 'this' object. Keep a local reference of it. @@ -72,7 +72,8 @@ void V8AbstractEventListener::handleEvent(Event* event, bool isWindowEvent) { v8::HandleScope handle_scope; v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame); - if (context.IsEmpty()) return; + if (context.IsEmpty()) + return; v8::Context::Scope scope(context); // m_frame can removed by the callback function, @@ -227,6 +228,11 @@ v8::Local<v8::Object> V8EventListener::GetThisObject(Event* event, v8::Handle<v8::Value> value = V8Proxy::ToV8Object( V8ClassIndex::XMLHTTPREQUESTUPLOAD, target->toXMLHttpRequestUpload()); return v8::Local<v8::Object>::New(v8::Handle<v8::Object>::Cast(value)); + + } else if (target->toMessagePort()) { + v8::Handle<v8::Value> value = V8Proxy::ToV8Object( + V8ClassIndex::MESSAGEPORT, target->toMessagePort()); + return v8::Local<v8::Object>::New(v8::Handle<v8::Object>::Cast(value)); } else { ASSERT(false); @@ -237,16 +243,16 @@ v8::Local<v8::Object> V8EventListener::GetThisObject(Event* event, // ------- V 8 X H R E v e n t L i s t e n e r ----------------- -static void WeakXHRListenerCallback(v8::Persistent<v8::Value> obj, +static void WeakObjectEventListenerCallback(v8::Persistent<v8::Value> obj, void* para) { - V8XHREventListener* listener = static_cast<V8XHREventListener*>(para); + V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(para); // Remove the wrapper Frame* frame = listener->frame(); if (frame) { V8Proxy* proxy = V8Proxy::retrieve(frame); if (proxy) - proxy->RemoveXHREventListener(listener); + proxy->RemoveObjectEventListener(listener); // Because the listener is no longer in the list, it must // be disconnected from the frame to avoid dangling frame pointer @@ -259,21 +265,21 @@ static void WeakXHRListenerCallback(v8::Persistent<v8::Value> obj, } -V8XHREventListener::V8XHREventListener(Frame* frame, +V8ObjectEventListener::V8ObjectEventListener(Frame* frame, v8::Local<v8::Object> listener, bool html) : V8EventListener(frame, listener, html) { // make m_listener weak. - m_listener.MakeWeak(this, WeakXHRListenerCallback); + m_listener.MakeWeak(this, WeakObjectEventListenerCallback); } -V8XHREventListener::~V8XHREventListener() { +V8ObjectEventListener::~V8ObjectEventListener() { if (m_frame) { ASSERT(!m_listener.IsEmpty()); V8Proxy* proxy = V8Proxy::retrieve(m_frame); if (proxy) - proxy->RemoveXHREventListener(this); + proxy->RemoveObjectEventListener(this); } DisposeListenerObject(); diff --git a/webkit/port/bindings/v8/v8_events.h b/webkit/port/bindings/v8/v8_events.h index 72e077a..5ff5e96 100644 --- a/webkit/port/bindings/v8/v8_events.h +++ b/webkit/port/bindings/v8/v8_events.h @@ -72,7 +72,7 @@ class V8AbstractEventListener : public EventListener { int m_columnNumber; friend class V8EventListener; - friend class V8XHREventListener; + friend class V8ObjectEventListener; friend class V8LazyEventListener; }; @@ -102,16 +102,16 @@ class V8EventListener : public V8AbstractEventListener { }; -// V8XHREventListener is a special listener wrapper for XMLHttpRequest object. -// It keeps JS listener week. -class V8XHREventListener : public V8EventListener { +// V8ObjectEventListener is a special listener wrapper for objects not +// in the DOM. It keeps the JS listener as a weak pointer. +class V8ObjectEventListener : public V8EventListener { public: - static PassRefPtr<V8XHREventListener> create(Frame* frame, + static PassRefPtr<V8ObjectEventListener> create(Frame* frame, v8::Local<v8::Object> listener, bool html) { - return adoptRef(new V8XHREventListener(frame, listener, html)); + return adoptRef(new V8ObjectEventListener(frame, listener, html)); } - V8XHREventListener(Frame* frame, v8::Local<v8::Object> listener, bool html); - virtual ~V8XHREventListener(); + V8ObjectEventListener(Frame* frame, v8::Local<v8::Object> listener, bool html); + virtual ~V8ObjectEventListener(); }; diff --git a/webkit/port/bindings/v8/v8_index.cpp b/webkit/port/bindings/v8/v8_index.cpp index 902ebfb..d785d73 100644 --- a/webkit/port/bindings/v8/v8_index.cpp +++ b/webkit/port/bindings/v8/v8_index.cpp @@ -102,7 +102,6 @@ #include "V8HTMLIFrameElement.h" #include "V8HTMLImageElement.h" #include "V8HTMLInputElement.h" -#include "V8HTMLSelectionInputElement.h" #include "V8HTMLIsIndexElement.h" #include "V8HTMLLabelElement.h" #include "V8HTMLLegendElement.h" @@ -135,13 +134,14 @@ #include "V8ImageData.h" #include "V8InspectorController.h" #include "V8MediaList.h" +#include "V8MessageChannel.h" #include "V8MessageEvent.h" +#include "V8MessagePort.h" #include "V8NamedNodeMap.h" #include "V8Node.h" #include "V8NodeList.h" #include "V8NodeFilter.h" #include "V8Notation.h" -#include "V8NSResolver.h" #include "V8ProcessingInstruction.h" #include "V8ProgressEvent.h" #include "V8StyleSheet.h" diff --git a/webkit/port/bindings/v8/v8_index.h b/webkit/port/bindings/v8/v8_index.h index 109f702..5ba923d 100644 --- a/webkit/port/bindings/v8/v8_index.h +++ b/webkit/port/bindings/v8/v8_index.h @@ -61,7 +61,6 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)(); V(HTMLIFRAMEELEMENT, HTMLIFrameElement) \ V(HTMLIMAGEELEMENT, HTMLImageElement) \ V(HTMLINPUTELEMENT, HTMLInputElement) \ - V(HTMLSELECTIONINPUTELEMENT, HTMLSelectionInputElement) \ V(HTMLISINDEXELEMENT, HTMLIsIndexElement) \ V(HTMLLABELELEMENT, HTMLLabelElement) \ V(HTMLLEGENDELEMENT, HTMLLegendElement) \ @@ -251,7 +250,9 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)(); V(KEYBOARDEVENT, KeyboardEvent) \ V(LOCATION, Location) \ V(MEDIALIST, MediaList) \ + V(MESSAGECHANNEL, MessageChannel) \ V(MESSAGEEVENT, MessageEvent) \ + V(MESSAGEPORT, MessagePort) \ V(MIMETYPE, MimeType) \ V(MIMETYPEARRAY, MimeTypeArray) \ V(MOUSEEVENT, MouseEvent) \ @@ -261,7 +262,6 @@ 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) \ diff --git a/webkit/port/bindings/v8/v8_proxy.cpp b/webkit/port/bindings/v8/v8_proxy.cpp index f21197b..4e84ae1 100644 --- a/webkit/port/bindings/v8/v8_proxy.cpp +++ b/webkit/port/bindings/v8/v8_proxy.cpp @@ -903,44 +903,48 @@ PassRefPtr<V8EventListener> V8Proxy::FindOrCreateV8EventListener(v8::Local<v8::V } -// XMLHttpRequest(XHR) event listeners are different from listeners -// on DOM nodes. A XHR event listener wrapper only hold a weak reference -// to the JS function. A strong reference can create a cycle. +// Object event listeners (such as XmlHttpRequest and MessagePort) are +// different from listeners on DOM nodes. An object event listener wrapper +// only holds a weak reference to the JS function. A strong reference can +// create a cycle. // -// The lifetime of a XHR object is bounded by the life time of its JS_XHR -// object. So we can create a hidden reference from JS_XHR to JS function. +// The lifetime of these objects is bounded by the life time of its JS +// wrapper. So we can create a hidden reference from the JS wrapper to +// to its JS function. // // (peer) -// XHR <---------- JS_XHR +// XHR <---------- JS_wrapper // | (hidden) : ^ // V V : (may reachable by closure) // V8_listener --------> JS_function // (weak) <-- may create a cycle if it is strong // // The persistent reference is made weak in the constructor -// of V8XHREventListener. +// of V8ObjectEventListener. -PassRefPtr<V8EventListener> V8Proxy::FindXHREventListener( +PassRefPtr<V8EventListener> V8Proxy::FindObjectEventListener( v8::Local<v8::Value> listener, bool html) { return FindEventListenerInList(m_xhr_listeners, listener, html); } -PassRefPtr<V8EventListener> V8Proxy::FindOrCreateXHREventListener( +PassRefPtr<V8EventListener> V8Proxy::FindOrCreateObjectEventListener( 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_xhr_listeners, obj, html); - if (wrapper) return wrapper; + if (wrapper) + return wrapper; // Create a new one, and add to cache. RefPtr<V8EventListener> new_listener = - V8XHREventListener::create(m_frame, v8::Local<v8::Object>::Cast(obj), html); + V8ObjectEventListener::create(m_frame, v8::Local<v8::Object>::Cast(obj), html); m_xhr_listeners.push_back(new_listener.get()); return new_listener.release(); @@ -967,7 +971,7 @@ void V8Proxy::RemoveV8EventListener(V8EventListener* listener) } -void V8Proxy::RemoveXHREventListener(V8XHREventListener* listener) +void V8Proxy::RemoveObjectEventListener(V8ObjectEventListener* listener) { RemoveEventListenerFromList(m_xhr_listeners, listener); } @@ -1120,7 +1124,8 @@ v8::Local<v8::Value> V8Proxy::CallFunction(v8::Handle<v8::Function> function, // of recursion that stems from calling functions. This is in // contrast to the script evaluations. v8::Local<v8::Value> result; - { ConsoleMessageScope scope; + { + ConsoleMessageScope scope; // Evaluating the JavaScript could cause the frame to be deallocated, // so we start the keep alive timer here. @@ -1145,7 +1150,8 @@ v8::Persistent<v8::FunctionTemplate> V8Proxy::GetTemplate( { v8::Persistent<v8::FunctionTemplate>* cache_cell = V8ClassIndex::GetCache(type); - if (!(*cache_cell).IsEmpty()) return *cache_cell; + if (!(*cache_cell).IsEmpty()) + return *cache_cell; // not found FunctionTemplateFactory factory = V8ClassIndex::GetFactory(type); @@ -1377,6 +1383,18 @@ v8::Persistent<v8::FunctionTemplate> V8Proxy::GetTemplate( break; } + case V8ClassIndex::MESSAGECHANNEL: + desc->SetCallHandler(USE_CALLBACK(MessageChannelConstructor)); + break; + case V8ClassIndex::MESSAGEPORT: { + // Reserve one more internal field for keeping event listeners. + v8::Local<v8::ObjectTemplate> instance_template = + desc->InstanceTemplate(); + instance_template->SetInternalFieldCount( + V8Custom::kMessagePortInternalFieldCount); + break; + } + // DOMParser, XMLSerializer, and XMLHttpRequest objects are created from // JS world, but we setup the constructor function lazily in // WindowNamedPropertyHandler::get. @@ -1388,12 +1406,12 @@ v8::Persistent<v8::FunctionTemplate> V8Proxy::GetTemplate( break; case V8ClassIndex::XMLHTTPREQUEST: { // Reserve one more internal field for keeping event listeners. - v8::Local<v8::ObjectTemplate> instance_template = - desc->InstanceTemplate(); - instance_template->SetInternalFieldCount( - V8Custom::kXMLHttpRequestInternalFieldCount); - desc->SetCallHandler(USE_CALLBACK(XMLHttpRequestConstructor)); - break; + v8::Local<v8::ObjectTemplate> instance_template = + desc->InstanceTemplate(); + instance_template->SetInternalFieldCount( + V8Custom::kXMLHttpRequestInternalFieldCount); + desc->SetCallHandler(USE_CALLBACK(XMLHttpRequestConstructor)); + break; } case V8ClassIndex::XMLHTTPREQUESTUPLOAD: { // Reserve one more internal field for keeping event listeners. @@ -1702,7 +1720,11 @@ static void GenerateSecurityToken(v8::Local<v8::Context> context) // Ask the document's SecurityOrigin to generate a security token. // If two tokens are equal, then the SecurityOrigins canAccess each other. // If two tokens are not equal, then we have to call canAccess. - String token = document->securityOrigin()->securityToken(); + // Note: we can't use the HTTPOrigin if it was set from the DOM. + SecurityOrigin* origin = document->securityOrigin(); + String token; + if (!origin->domainWasSetInDOM()) + token = document->securityOrigin()->toString(); // An empty token means we always have to call canAccess. In this case, we // use the global object as the security token to avoid calling canAccess @@ -2120,13 +2142,6 @@ v8::Local<v8::Object> V8Proxy::InstantiateV8Object( desc_type = V8ClassIndex::UNDETECTABLEHTMLCOLLECTION; } - // Special case for HTMLInputElements that support selection. - if (desc_type == V8ClassIndex::HTMLINPUTELEMENT) { - HTMLInputElement* element = static_cast<HTMLInputElement*>(imp); - if (element->canHaveSelection()) - desc_type = V8ClassIndex::HTMLSELECTIONINPUTELEMENT; - } - v8::Persistent<v8::FunctionTemplate> desc = GetTemplate(desc_type); v8::Local<v8::Function> function = desc->GetFunction(); v8::Local<v8::Object> instance = SafeAllocation::NewInstance(function); diff --git a/webkit/port/bindings/v8/v8_proxy.h b/webkit/port/bindings/v8/v8_proxy.h index f1b558f..5c2c246 100644 --- a/webkit/port/bindings/v8/v8_proxy.h +++ b/webkit/port/bindings/v8/v8_proxy.h @@ -70,7 +70,7 @@ class SVGElementInstance; #endif class V8EventListener; -class V8XHREventListener; +class V8ObjectEventListener; typedef std::list<V8EventListener*> V8EventListenerList; // TODO(fqian): use standard logging facilities in WebCore. @@ -197,13 +197,13 @@ class V8Proxy { PassRefPtr<V8EventListener> FindOrCreateV8EventListener(v8::Local<v8::Value> listener, bool html); - PassRefPtr<V8EventListener> FindXHREventListener(v8::Local<v8::Value> listener, + PassRefPtr<V8EventListener> FindObjectEventListener(v8::Local<v8::Value> listener, bool html); - PassRefPtr<V8EventListener> FindOrCreateXHREventListener(v8::Local<v8::Value> listener, + PassRefPtr<V8EventListener> FindOrCreateObjectEventListener(v8::Local<v8::Value> listener, bool html); void RemoveV8EventListener(V8EventListener* listener); - void RemoveXHREventListener(V8XHREventListener* listener); + void RemoveObjectEventListener(V8ObjectEventListener* listener); // Protect/Unprotect JS wrappers of a DOM object. static void GCProtect(Peerable* dom_object); diff --git a/webkit/port/bindings/v8/v8_utility.h b/webkit/port/bindings/v8/v8_utility.h index 5e7df97..2dd52bf 100644 --- a/webkit/port/bindings/v8/v8_utility.h +++ b/webkit/port/bindings/v8/v8_utility.h @@ -33,7 +33,8 @@ class SafeAllocation { v8::Local<v8::Object> SafeAllocation::NewInstance( v8::Handle<v8::Function> fun) { - if (fun.IsEmpty()) return v8::Local<v8::Object>(); + if (fun.IsEmpty()) + return v8::Local<v8::Object>(); AllowAllocation allow; return fun->NewInstance(); } diff --git a/webkit/port/bindings/v8/v8_vectornodelist.cpp b/webkit/port/bindings/v8/v8_vectornodelist.cpp index 7e19cf8..f9341aa 100644 --- a/webkit/port/bindings/v8/v8_vectornodelist.cpp +++ b/webkit/port/bindings/v8/v8_vectornodelist.cpp @@ -30,6 +30,7 @@ #include "config.h" #include "v8_vectornodelist.h" +#include "Element.h" #include "NamedAttrMap.h" // Node::attributes namespace WebCore { diff --git a/webkit/port/dom/Document.idl b/webkit/port/dom/Document.idl index fb8ba94..83c80b8 100644 --- a/webkit/port/dom/Document.idl +++ b/webkit/port/dom/Document.idl @@ -237,18 +237,10 @@ module core { NodeList getElementsByClassName(in DOMString tagname); // NodeSelector - Selector API -#if defined(LANGUAGE_JAVASCRIPT) - [Custom] Element querySelector(in [ConvertUndefinedOrNullToNullString] DOMString selectors, in NSResolver resolver) - raises(DOMException); - [Custom] NodeList querySelectorAll(in [ConvertUndefinedOrNullToNullString] DOMString selectors, in NSResolver resolver) - raises(DOMException); -#else - // FIXME: add support for NSResolver in languages other than JS Element querySelector(in [ConvertUndefinedOrNullToNullString] DOMString selectors) raises(DOMException); NodeList querySelectorAll(in [ConvertUndefinedOrNullToNullString] DOMString selectors) raises(DOMException); -#endif }; diff --git a/webkit/port/html/HTMLSelectionInputElement.idl b/webkit/port/html/HTMLSelectionInputElement.idl deleted file mode 100644 index ba6e611..0000000 --- a/webkit/port/html/HTMLSelectionInputElement.idl +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) 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. - -module html { - - // HTMLSelectionInputElements are the HTMLInputElements that support selection. - interface HTMLSelectionInputElement : HTMLInputElement { - attribute long selectionStart; - attribute long selectionEnd; - void setSelectionRange(in long start, in long end); - }; - -} diff --git a/webkit/port/page/DOMWindow.idl b/webkit/port/page/DOMWindow.idl index e6e0c31..c6f51f3 100644 --- a/webkit/port/page/DOMWindow.idl +++ b/webkit/port/page/DOMWindow.idl @@ -314,6 +314,7 @@ module window { // KJS adds these to the window object in kjs_window.cpp. attribute XMLHttpRequestConstructor XMLHttpRequest; attribute XSLTProcessorConstructor XSLTProcessor; + attribute MessageChannelConstructor MessageChannel; #endif #if ENABLE_DOM_STORAGE diff --git a/webkit/port/page/chromium/ChromeClientChromium.h b/webkit/port/page/chromium/ChromeClientChromium.h index 2e04c39..66e08b0 100644 --- a/webkit/port/page/chromium/ChromeClientChromium.h +++ b/webkit/port/page/chromium/ChromeClientChromium.h @@ -10,10 +10,13 @@ #include "ChromeClient.h" namespace WebCore { - + class Cursor; class FileChooser; class Frame; + class FramelessScrollView; + class IntRect; class String; + class Widget; class ChromeClientChromium : public ChromeClient { public: @@ -21,9 +24,12 @@ namespace WebCore { virtual void runFileChooser(const String& defaultFileName, PassRefPtr<FileChooser> file_chooser) = 0; - // Given a rect in main frame coordinates, returns a new rect relative - // to the screen. - virtual IntRect windowToScreen(const IntRect& rect) = 0; + // Notifies the client of a new popup widget. The client should place + // and size the widget with the given bounds, relative to the screen. + virtual void popupOpened(FramelessScrollView* popupView, const IntRect& bounds) = 0; + + // Set the current cursor. + virtual void setCursor(const Cursor& cursor) = 0; }; } diff --git a/webkit/port/page/chromium/EventHandlerChromium.cpp b/webkit/port/page/chromium/EventHandlerChromium.cpp index ef4d732..d7082e5 100644 --- a/webkit/port/page/chromium/EventHandlerChromium.cpp +++ b/webkit/port/page/chromium/EventHandlerChromium.cpp @@ -37,7 +37,6 @@ #include "MouseEventWithHitTestResults.h" #include "Page.h" #include "PlatformKeyboardEvent.h" -#include "PlatformScrollBar.h" #include "PlatformWheelEvent.h" #include "RenderWidget.h" #include "SelectionController.h" @@ -104,13 +103,6 @@ bool EventHandler::passWheelEventToWidget(PlatformWheelEvent& wheelEvent, Widget return static_cast<FrameView*>(widget)->frame()->eventHandler()->handleWheelEvent(wheelEvent); } -bool EventHandler::passMousePressEventToScrollbar(MouseEventWithHitTestResults& mev, PlatformScrollbar* scrollbar) -{ - if (!scrollbar || !scrollbar->isEnabled()) - return false; - return scrollbar->handleMousePressEvent(mev.event()); -} - bool EventHandler::passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults& event) { // Figure out which view to send the event to. diff --git a/webkit/port/page/inspector/InspectorController.cpp b/webkit/port/page/inspector/InspectorController.cpp index 901a97d..f18a6bb 100644 --- a/webkit/port/page/inspector/InspectorController.cpp +++ b/webkit/port/page/inspector/InspectorController.cpp @@ -54,6 +54,7 @@ #include "FrameTree.h" #include "FrameView.h" #include "GraphicsContext.h" +#include "HitTestResult.h" #include "HTMLFrameOwnerElement.h" #include "InspectorClient.h" #include "v8_proxy.h" @@ -622,6 +623,10 @@ InspectorController::InspectorController(Page* page, InspectorClient* client) , m_showAfterVisible(ElementsPanel) , m_nextIdentifier(-2) , m_groupLevel(0) + , m_searchingForNode(false) + , m_currentUserInitiatedProfileNumber(-1) + , m_nextUserInitiatedProfileNumber(1) + , m_previousMessage(0) { ASSERT_ARG(page, page); ASSERT_ARG(client, client); @@ -893,6 +898,41 @@ void InspectorController::setAttachedWindowHeight(unsigned height) notImplemented(); } +void InspectorController::toggleSearchForNodeInPage() +{ + if (!enabled()) + return; + + m_searchingForNode = !m_searchingForNode; + if (!m_searchingForNode) + hideHighlight(); +} + +void InspectorController::mouseDidMoveOverElement(const HitTestResult& result, unsigned modifierFlags) +{ + if (!enabled() || !m_searchingForNode) + return; + + Node* node = result.innerNode(); + if (node) + highlight(node); +} + +void InspectorController::handleMousePressOnNode(Node* node) +{ + if (!enabled()) + return; + + ASSERT(m_searchingForNode); + ASSERT(node); + if (!node) + return; + + // inspect() will implicitly call ElementsPanel's focusedNodeChanged() and the hover feedback will be stopped there. + inspect(node); +} + + void InspectorController::windowScriptObjectAvailable() { if (!m_page || !enabled()) diff --git a/webkit/port/platform/GKURL_unittest.cpp b/webkit/port/platform/GKURL_unittest.cpp index 4286d0a..4da8c94 100644 --- a/webkit/port/platform/GKURL_unittest.cpp +++ b/webkit/port/platform/GKURL_unittest.cpp @@ -587,4 +587,4 @@ TEST(GKURL, Offsets) { EXPECT_TRUE(kurl3.pathStart() == gurl3.pathStart()); EXPECT_TRUE(kurl3.pathEnd() == gurl3.pathEnd()); EXPECT_TRUE(kurl3.pathAfterLastSlash() == gurl3.pathAfterLastSlash()); -} +}
\ No newline at end of file diff --git a/webkit/port/platform/chromium/FileChooserChromium.cpp b/webkit/port/platform/chromium/FileChooserChromium.cpp index 6d38b2db..c70ff69 100644 --- a/webkit/port/platform/chromium/FileChooserChromium.cpp +++ b/webkit/port/platform/chromium/FileChooserChromium.cpp @@ -24,18 +24,13 @@ */ #include "config.h" -#if PLATFORM(WIN_OS) -#include <shlwapi.h> -#endif #pragma warning(push, 0) #include "ChromeClientChromium.h" #include "Document.h" #include "Frame.h" #include "FileChooser.h" -#if PLATFORM(DARWIN) -#include "FileChooserChromiumMac.h" -#endif +#include "FileSystem.h" #include "LocalizedStrings.h" #include "NotImplemented.h" #include "Page.h" @@ -65,19 +60,8 @@ String FileChooser::basenameForWidth(const Font& font, int width) const String string; if (m_filename.isEmpty()) string = fileButtonNoFileSelectedLabel(); - else { -#if PLATFORM(WIN_OS) - String tmpFilename = m_filename; - // Apple's code has a LPTSTR here, which will compile and run, but is wrong. - wchar_t* basename = PathFindFileName(tmpFilename.charactersWithNullTermination()); - string = String(basename); -#elif PLATFORM(DARWIN) - string = FileChooserGetBaseNameFromPath(m_filename); -#else - notImplemented(); - string = "fixme"; -#endif - } + else + string = pathGetFileName(m_filename); return StringTruncator::centerTruncate(string, static_cast<float>(width), font, false); } diff --git a/webkit/port/platform/chromium/FileChooserChromiumMac.mm b/webkit/port/platform/chromium/FileChooserChromiumMac.mm deleted file mode 100644 index 389bb8d..0000000 --- a/webkit/port/platform/chromium/FileChooserChromiumMac.mm +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. 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 "FileChooserChromiumMac.h" - -#import <Foundation/NSFileManager.h> -#include "PlatformString.h" - -namespace WebCore { - -String FileChooserGetBaseNameFromPath(const String &path) { - // TODO(playmobil): Perhaps in the future we can unify this with the other - // platforms by using the FilePath class in base. - return [[NSFileManager defaultManager] displayNameAtPath:path]; -} - -} diff --git a/webkit/port/dom/NSResolver.idl b/webkit/port/platform/chromium/FileSystemChromium.cpp index 5927331..102fde9 100644 --- a/webkit/port/dom/NSResolver.idl +++ b/webkit/port/platform/chromium/FileSystemChromium.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,10 +10,10 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. 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 @@ -23,10 +23,42 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -module core { +#include "config.h" - interface NSResolver { - [Custom] DOMString lookupNamespaceURI(in DOMString prefix); - }; +#include "NotImplemented.h" +#include "PlatformString.h" + +namespace WebCore { + +bool deleteFile(const String&) +{ + notImplemented(); + return false; +} + +bool deleteEmptyDirectory(const String&) +{ + notImplemented(); + return false; +} + +bool getFileSize(const String&, long long& result) +{ + notImplemented(); + return false; } + +bool getFileModificationTime(const String&, time_t& result) +{ + notImplemented(); + return false; +} + +String directoryName(const String&) +{ + notImplemented(); + return String(); +} + +} // namespace WebCore diff --git a/webkit/port/bindings/v8/JSNSResolver.h b/webkit/port/platform/chromium/FileSystemChromiumMac.mm index 84bd072..152bee2 100644 --- a/webkit/port/bindings/v8/JSNSResolver.h +++ b/webkit/port/platform/chromium/FileSystemChromiumMac.mm @@ -27,32 +27,17 @@ // (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 "FileSystem.h" -// 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" +#import <Foundation/NSFileManager.h> +#include "PlatformString.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. -}; - +String pathGetFileName(const String& path) +{ + return [[NSFileManager defaultManager] displayNameAtPath:path]; } -#endif // !defined(JSNSResolver_h) +} diff --git a/webkit/port/platform/chromium/FileChooserChromiumMac.h b/webkit/port/platform/chromium/FileSystemChromiumWin.cpp index 5b546fc..0c91231 100644 --- a/webkit/port/platform/chromium/FileChooserChromiumMac.h +++ b/webkit/port/platform/chromium/FileSystemChromiumWin.cpp @@ -1,19 +1,20 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// +// 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 +// +// * 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 +// * 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 +// * 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 @@ -26,16 +27,17 @@ // (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 FileChooserChromiumMac_h__ -#define FileChooserChromiumMac_h__ +#include "config.h" +#include "FileSystem.h" + +#include <windows.h> +#include <shlwapi.h> namespace WebCore { - -class String; -// Returns the basename of a path. -String FileChooserGetBaseNameFromPath(const String &path); - +String pathGetFileName(const String& path) +{ + return String(PathFindFileName(String(path).charactersWithNullTermination())); } -#endif +}
\ No newline at end of file diff --git a/webkit/port/platform/chromium/FramelessScrollView.cpp b/webkit/port/platform/chromium/FramelessScrollView.cpp index 51c9d52..60d4375 100644 --- a/webkit/port/platform/chromium/FramelessScrollView.cpp +++ b/webkit/port/platform/chromium/FramelessScrollView.cpp @@ -28,14 +28,59 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "config.h" - #include "FramelessScrollView.h" +#include "FramelessScrollViewClient.h" + namespace WebCore { -IntRect FramelessScrollView::windowClipRect() const +FramelessScrollView::~FramelessScrollView() +{ + // Remove native scrollbars now before we lose the connection to the HostWindow. + setHasHorizontalScrollbar(false); + setHasVerticalScrollbar(false); +} + +void FramelessScrollView::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect) +{ + // Add in our offset within the ScrollView. + IntRect dirtyRect = rect; + dirtyRect.move(scrollbar->x(), scrollbar->y()); + invalidateRect(dirtyRect); +} + +bool FramelessScrollView::isActive() const +{ + // FIXME + return true; +} + +void FramelessScrollView::invalidateRect(const IntRect& rect) +{ + if (HostWindow* h = hostWindow()) + h->repaint(contentsToWindow(rect), true); +} + +HostWindow* FramelessScrollView::hostWindow() const +{ + return const_cast<FramelessScrollViewClient*>(m_client); +} + +IntRect FramelessScrollView::windowClipRect(bool clipToContents) const +{ + return contentsToWindow(visibleContentRect(!clipToContents)); +} + +void FramelessScrollView::paintContents(GraphicsContext*, const IntRect& damageRect) +{ +} + +void FramelessScrollView::contentsResized() +{ +} + +void FramelessScrollView::visibleContentsResized() { - return convertToContainingWindow(IntRect(0, 0, width(), height())); } } diff --git a/webkit/port/platform/chromium/FramelessScrollView.h b/webkit/port/platform/chromium/FramelessScrollView.h index a71fcfb..dd940a0 100644 --- a/webkit/port/platform/chromium/FramelessScrollView.h +++ b/webkit/port/platform/chromium/FramelessScrollView.h @@ -5,34 +5,55 @@ #ifndef FramelessScrollView_h #define FramelessScrollView_h -#include "FrameView.h" +#include "ScrollView.h" namespace WebCore { - + class FramelessScrollViewClient; class PlatformKeyboardEvent; + class PlatformMouseEvent; + class PlatformWheelEvent; // A FramelessScrollView is a ScrollView that can be used to render custom - // content, which does not have an associated Frame. This extends from - // FrameView because much of WebCore unfortunately assumes that a - // ScrollView is a FrameView. + // content, which does not have an associated Frame. // // TODO: It may be better to just develop a custom subclass of Widget that // can have scroll bars for this instead of trying to reuse ScrollView. // - class FramelessScrollView : public FrameView { + class FramelessScrollView : public ScrollView { public: - FramelessScrollView() : FrameView(0) {} + FramelessScrollView() : m_client(0) {} + ~FramelessScrollView(); - virtual IntRect windowClipRect() const; + FramelessScrollViewClient* client() const { return m_client; } + void setClient(FramelessScrollViewClient* client) { m_client = client; } - // Event handlers + // Event handlers that subclasses must implement. virtual bool handleMouseDownEvent(const PlatformMouseEvent&) = 0; virtual bool handleMouseMoveEvent(const PlatformMouseEvent&) = 0; virtual bool handleMouseReleaseEvent(const PlatformMouseEvent&) = 0; virtual bool handleWheelEvent(const PlatformWheelEvent&) = 0; virtual bool handleKeyEvent(const PlatformKeyboardEvent&) = 0; + + // ScrollbarClient public methods: + virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&); + virtual bool isActive() const; + + // Widget public methods: + virtual void invalidateRect(const IntRect&); + + // ScrollView public methods: + virtual HostWindow* hostWindow() const; + virtual IntRect windowClipRect(bool clipToContents = true) const; + + protected: + // ScrollView protected methods: + virtual void paintContents(GraphicsContext*, const IntRect& damageRect); + virtual void contentsResized(); + virtual void visibleContentsResized(); + + private: + FramelessScrollViewClient* m_client; }; } #endif // FramelessScrollView_h - diff --git a/webkit/port/platform/chromium/FramelessScrollViewClient.h b/webkit/port/platform/chromium/FramelessScrollViewClient.h new file mode 100644 index 0000000..a237bce --- /dev/null +++ b/webkit/port/platform/chromium/FramelessScrollViewClient.h @@ -0,0 +1,17 @@ +// Copyright (c) 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 FramelessScrollViewClient_h +#define FramelessScrollViewClient_h + +#include "HostWindow.h" + +namespace WebCore { + class FramelessScrollViewClient : public HostWindow { + public: + virtual void popupClosed(FramelessScrollView* popup_view) = 0; + }; +} + +#endif // FramelessScrollViewClient_h diff --git a/webkit/port/platform/chromium/PlatformScrollBar.h b/webkit/port/platform/chromium/PlatformScrollBar.h deleted file mode 100644 index bf865c5..0000000 --- a/webkit/port/platform/chromium/PlatformScrollBar.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (C) 2004, 2005, 2006, 2007 Apple 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: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 PlatformScrollbar_h -#define PlatformScrollbar_h - -#include "Widget.h" -#include "ScrollBar.h" -#include "Timer.h" - -namespace WebCore { - -// IMPORTANT NOTES ABOUT SCROLLBARS -// -// WebKit uses scrollbars in two ways. The first way is as a scroll control -// for a ScrollView. This scrollbar sits inside the ScrollView's rect and -// modifies its scrollOffset. Because it is inside the ScrollView's rect, it -// is a child of the ScrollView, but because it is not really part of the -// scrollView's content, it doesn't move as the scrollOffset changes. -// -// The second use is as a scroll control for things other than a ScrollView, -// e.g. a <select>. A <select> is not a ScrollView, so the scrollbar is not a -// child of it -- instead, it is a child of the ScrollView representing the -// frame in which the <select> (and the scrollbar) are located. In this case, -// the scrollbar IS part of the ScrollView's content, and it moves when the -// scrollOffset changes. -// -// ScrollViewWin distinguishes these two cases in its convertChildToSelf and -// convertSelfToChild methods, which are used when converting coordinates -// between the ScrollBar's coordinate system and that of the native window. - -class PlatformScrollbar : public Widget, public Scrollbar { -public: - static PassRefPtr<PlatformScrollbar> create(ScrollbarClient* client, ScrollbarOrientation orientation, ScrollbarControlSize size) - { - return adoptRef(new PlatformScrollbar(client, orientation, size)); - } - virtual ~PlatformScrollbar(); - - virtual bool isWidget() const { return true; } - - virtual int width() const; - virtual int height() const; - virtual void setRect(const IntRect&); - virtual void setEnabled(bool); - virtual bool isEnabled() const { return m_enabled; } - virtual void paint(GraphicsContext*, const IntRect& damageRect); - - virtual void setFrameGeometry(const IntRect& rect); - - // All mouse handler functions below receive mouse events in window - // coordinates. - - // NOTE: These may be called after we've been removed from the widget/ - // window hierarchy, for example because the EventHandler keeps a reference - // around and tries to feed us MouseOut events. In this case, doing - // something would be not only pointless but dangerous, as without a - // parent() we will end up failing an ASSERT(). So bail early if we get to - // any of these with no parent(). - virtual bool handleMouseMoveEvent(const PlatformMouseEvent&); - virtual bool handleMouseOutEvent(const PlatformMouseEvent&); - virtual bool handleMousePressEvent(const PlatformMouseEvent&); - virtual bool handleMouseReleaseEvent(const PlatformMouseEvent&); - - virtual IntRect windowClipRect() const; - - static void themeChanged(); - static int horizontalScrollbarHeight(ScrollbarControlSize size = RegularScrollbar); - static int verticalScrollbarWidth(ScrollbarControlSize size = RegularScrollbar); - - // Scrolls the page when auto-repeat scrolling. - void autoscrollTimerFired(Timer<PlatformScrollbar>*); - - // This function receives events in window coordinates. - void handleMouseMoveEventWhenCapturing(const PlatformMouseEvent& e); - -protected: - virtual void updateThumbPosition(); - virtual void updateThumbProportion(); - -private: - PlatformScrollbar(ScrollbarClient*, ScrollbarOrientation, ScrollbarControlSize); - - // Scroll bar segment identifiers - enum Segment { - Arrow1 = 0, - Track, // Only used when scrollbar does not contain a thumb - BeforeThumb, // -| - Thumb, // -+ Only used when scrollbar contains a thumb - AfterThumb, // -| - Arrow2, - None, - NumSegments = None - }; - - // Turns on/off whether we have mouse capture. This is only for tracking, - // as the EventHandler is what controls the actual capture. - void setCapturingMouse(bool capturing); - - // Returns the girth of the scrollbar arrow button for layout, given the - // system metrics code for the desired direction's button and a limiting - // height (for vertical scroll bars) or width (for horizontal scrollbars). - // Also computes the background span (available remaining space). - int scrollButtonGirth(int systemMetricsCode, int limit, - int* backgroundSpan); - - // Returns the girth of the scrollbar thumb for layout, given the system - // metrics code for the desired direction's thumb and the background span - // (space remaining after the buttons are drawn). - int scrollThumbGirth(int systemMetricsCode, int backgroundSpan); - - // Computes the layout of the scroll bar given its current configuration. - void layout(); - - // Sets the current mouse position to the coordinates in |event|. - void updateMousePosition(int x, int y); - - // Helper routine for updateMousePosition(), used to bypass layout(). - void updateMousePositionInternal(); - - // Returns the correct state for the theme engine to draw a segment. - int getThemeState(Segment target) const; - int getThemeArrowState(Segment target) const; - int getClassicThemeState(Segment target) const; - - // Draws the tick-marks on the scrollbar. The tick-marks are visual - // indicators showing the results from a find-in-page operation. - void DrawTickmarks(GraphicsContext* context) const; - - IntPoint m_lastNativePos; // The last (native) mouse coordinate received. - struct { - int thumbPos; // Relevant (window) mouse coordinate, and... - int scrollVal; // ...current scrollvalue, when... - } m_dragOrigin; // ...user begins dragging the thumb. - IntRect m_segmentRects[NumSegments]; - // The native coordinates of the scrollbar - // segments. - Segment m_mouseOver; // The scrollbar segment the mouse is over. - Segment m_captureStart; // The segment on which we started capture. - Timer<PlatformScrollbar> m_autorepeatTimer; - // Timer to start and continue auto-repeat - // scrolling when the button is held down. - bool m_enabled; // True when the scrollbar is enabled. - bool m_needsLayout; // True when cached geometry may have changed - - // Multipliers against scrollbar thickness that determine how far away from - // the scrollbar track the cursor can go before the thumb "snaps back" - static const int kOffSideMultiplier; - static const int kOffEndMultiplier; - - // Auto-repeat delays, in seconds - static const double kAutorepeatInitialDelay; - static const double kAutorepeatRepeatInterval; -}; - -} - -#endif // PlatformScrollbar_h diff --git a/webkit/port/platform/chromium/PlatformScrollBarChromium.cpp b/webkit/port/platform/chromium/PlatformScrollBarChromium.cpp deleted file mode 100644 index 6cd0033..0000000 --- a/webkit/port/platform/chromium/PlatformScrollBarChromium.cpp +++ /dev/null @@ -1,848 +0,0 @@ -// 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. - -// TODO(pinkerton): clearly this needs a lot of work for mac and linux. -// Right now it has just been stubbed out to get things to compile with fixed -// geometries. - -#include "config.h" -#include <algorithm> -#if PLATFORM(WIN_OS) -#include <windows.h> -#include <vsstyle.h> -#endif -#include "FrameView.h" -#include "GraphicsContext.h" -#include "IntRect.h" -#include "NativeImageSkia.h" -#include "PlatformMouseEvent.h" -#include "PlatformScrollBar.h" -#include "Range.h" -#include "ScrollView.h" -#include "WidgetClientChromium.h" - -#include "graphics/SkiaUtils.h" - -#undef LOG -#if PLATFORM(WIN_OS) -#include "base/gfx/native_theme.h" -#endif -#include "base/gfx/platform_canvas.h" -#include "base/gfx/skia_utils.h" -#if PLATFORM(WIN_OS) -#include "base/win_util.h" -#endif -#include "webkit/glue/webframe_impl.h" -#include "webkit/glue/webkit_glue.h" - -namespace WebCore { - -const int PlatformScrollbar::kOffSideMultiplier = 8; -const int PlatformScrollbar::kOffEndMultiplier = 3; -const double PlatformScrollbar::kAutorepeatInitialDelay = 0.4; -const double PlatformScrollbar::kAutorepeatRepeatInterval = 1. / 15.; - -// The scrollbar size in DumpRenderTree on the Mac - so we can match their -// layout results. Entries are for regular, small, and mini scrollbars. -// Metrics obtained using [NSScroller scrollerWidthForControlSize:] -static const int kMacScrollbarSize[3] = {15, 11, 15}; - -// Scrollbar button and thumb sizes, for consistent layout results. The Mac -// value is not readily available, but it's not really needed, since these -// metrics only affect drawing within the scrollbar itself. These are the -// standard Windows values without Large Fonts. -static const int kLayoutTestScrollbarButtonGirth = 17; -static const int kLayoutTestScrollbarThumbGirth = 17; - - -/*static*/ void PlatformScrollbar::themeChanged() -{ - // TODO(darin): implement this -} - -/*static*/ int PlatformScrollbar::horizontalScrollbarHeight( - ScrollbarControlSize controlSize) -{ -#if PLATFORM(WIN_OS) - return webkit_glue::IsLayoutTestMode() ? kMacScrollbarSize[controlSize] : - GetSystemMetrics(SM_CYHSCROLL); -#elif PLATFORM(UNIX) - return kMacScrollbarSize[controlSize]; -#endif -} - -/*static*/ int PlatformScrollbar::verticalScrollbarWidth( - ScrollbarControlSize controlSize) -{ -#if PLATFORM(WIN_OS) - return webkit_glue::IsLayoutTestMode() ? kMacScrollbarSize[controlSize] : - GetSystemMetrics(SM_CXVSCROLL); -#elif PLATFORM(UNIX) - return kMacScrollbarSize[controlSize]; -#endif -} - -PlatformScrollbar::PlatformScrollbar(ScrollbarClient* client, - ScrollbarOrientation orientation, - ScrollbarControlSize controlSize) - : Scrollbar(client, orientation, controlSize) - , m_lastNativePos(-1, -1) // initialize to bogus values - , m_mouseOver(None) - , m_captureStart(None) -#pragma warning(suppress: 4355) // it's okay to pass |this| here! - , m_autorepeatTimer(this, &PlatformScrollbar::autoscrollTimerFired) - , m_enabled(true) - , m_needsLayout(true) -{ -} - -PlatformScrollbar::~PlatformScrollbar() -{ -} - -int PlatformScrollbar::width() const -{ - return orientation() == VerticalScrollbar ? - verticalScrollbarWidth(controlSize()) : Widget::width(); -} - -int PlatformScrollbar::height() const -{ - return orientation() == HorizontalScrollbar ? - horizontalScrollbarHeight(controlSize()) : Widget::height(); -} - -void PlatformScrollbar::setRect(const IntRect& rect) -{ - setFrameGeometry(rect); -} - -void PlatformScrollbar::setEnabled(bool enabled) -{ - if (m_enabled == enabled) - return; - - m_enabled = enabled; - invalidate(); -} - -void PlatformScrollbar::DrawTickmarks(GraphicsContext* context) const -{ -#if PLATFORM(WIN_OS) - // We don't draw on the horizontal scrollbar. It is too confusing - // to have the tickmarks appear on both scrollbars. - const bool horz = orientation() == HorizontalScrollbar; - if (horz) - return; - - // We need to as the WidgetClientChromium for the bitmap to use to draw. - WidgetClientChromium* widget_client = static_cast<WidgetClientChromium*>( - WebCore::Widget::client()); - if (!widget_client) - return; // Cannot draw without access to the bitmap. - - // Get the frame view this scroll bar belongs to. - FrameView* view = reinterpret_cast<FrameView*>(parent()); - ASSERT(view); - - // A frame can be null if this function is called for the scroll views - // used when drawing drop-down boxes. We don't need to draw anything in - // such cases. - if (!view->frame()) - return; - - // Find out if the frame has any tickmarks. - const Vector<RefPtr<Range> >& tickmarks = - WebFrameImpl::FromFrame(view->frame())->tickmarks(); - if (tickmarks.isEmpty()) - return; - - RECT track_area; - if (m_segmentRects[Track].x() != -1) { - // Scroll bar is too small to draw a thumb. - track_area.left = m_segmentRects[Track].x(); - track_area.top = m_segmentRects[Track].y(); - track_area.right = m_segmentRects[Track].right() - 1; - track_area.bottom = m_segmentRects[Track].bottom() - 1; - } else { - // Find the area between the arrows of the scroll bar. - track_area.left = m_segmentRects[BeforeThumb].x(); - track_area.top = m_segmentRects[BeforeThumb].y(); - track_area.right = m_segmentRects[AfterThumb].right() - 1; - track_area.bottom = m_segmentRects[AfterThumb].bottom() - 1; - } - - // We now can figure out the actual height and width of the track. - const int track_height = track_area.bottom - track_area.top; - const int track_width = track_area.right - track_area.left; - - if (track_height <= 0 || track_width <= 0) - return; // nothing to draw on. - - // NOTE: We tolerate the platformContext() call here because the scrollbars - // will not be serialized, i.e. composition is done in the renderer and - // never in the browser. - // Prepare the bitmap for drawing the tickmarks on the scroll bar. - gfx::PlatformCanvas* canvas = context->platformContext()->canvas(); - - // Load the image for the tickmark. - static RefPtr<Image> dashImg = Image::loadPlatformResource("tickmarkDash"); - DCHECK(dashImg); - if (dashImg->isNull()) { - ASSERT_NOT_REACHED(); - return; - } - const NativeImageSkia* dash = dashImg->nativeImageForCurrentFrame(); - - for (Vector<RefPtr<Range> >::const_iterator i = - tickmarks.begin(); - i != tickmarks.end(); ++i) { - const RefPtr<Range> range = (*i); - - if (!WebFrameImpl::RangeShouldBeHighlighted(range.get())) - continue; - - const IntRect& bounds = range->boundingBox(); - - // Calculate how far down (in %) the tick-mark should appear. - const float percent = static_cast<float>(bounds.y()) / m_totalSize; - - // Calculate how far down (in pixels) the tick-mark should appear. - const int y_pos = track_area.top + (track_height * percent); - - // Draw the tick-mark as a rounded rect with a slightly curved edge. - canvas->drawBitmap(*dash, track_area.left, y_pos); - } -#endif -} - -// paint in the coordinate space of our parent's content area -void PlatformScrollbar::paint(GraphicsContext* gc, const IntRect& damageRect) -{ -#if PLATFORM(WIN_OS) - if (gc->paintingDisabled()) - return; - - // Don't paint anything if the scrollbar doesn't intersect the damage rect. - if (!frameGeometry().intersects(damageRect)) - return; - - gc->save(); - gc->translate(x(), y()); - - layout(); - - HDC hdc = gc->platformContext()->canvas()->beginPlatformPaint(); - const bool horz = orientation() == HorizontalScrollbar; - const PlatformContextSkia* const skia = gc->platformContext(); - const gfx::NativeTheme* const nativeTheme = skia->nativeTheme(); - gfx::PlatformCanvasWin* const canvas = skia->canvas(); - - // Draw the up/left arrow of the scroll bar. - RECT rect = gfx::SkIRectToRECT(m_segmentRects[Arrow1]); - nativeTheme->PaintScrollbarArrow(hdc, getThemeArrowState(Arrow1), - (horz ? DFCS_SCROLLLEFT : DFCS_SCROLLUP) | - getClassicThemeState(Arrow1), - &rect); - - if (m_segmentRects[Track].x() != -1) { - // The scroll bar is too small to draw the thumb. Just draw a - // single track between the arrows. - rect = gfx::SkIRectToRECT(m_segmentRects[Track]); - nativeTheme->PaintScrollbarTrack(hdc, - horz ? SBP_UPPERTRACKHORZ : - SBP_UPPERTRACKVERT, - getThemeState(Track), - getClassicThemeState(Track), - &rect, &rect, canvas); - DrawTickmarks(gc); - } else { - // Draw the track area before the thumb on the scroll bar. - rect = gfx::SkIRectToRECT(m_segmentRects[BeforeThumb]); - nativeTheme->PaintScrollbarTrack(hdc, - horz ? SBP_UPPERTRACKHORZ : - SBP_UPPERTRACKVERT, - getThemeState(BeforeThumb), - getClassicThemeState(BeforeThumb), - &rect, &rect, canvas); - - // Draw the track area after the thumb on the scroll bar. - rect = gfx::SkIRectToRECT(m_segmentRects[BeforeThumb]); - RECT rect_after = gfx::SkIRectToRECT(m_segmentRects[AfterThumb]); - nativeTheme->PaintScrollbarTrack(hdc, - horz ? SBP_LOWERTRACKHORZ : - SBP_LOWERTRACKVERT, - getThemeState(AfterThumb), - getClassicThemeState(AfterThumb), - &rect_after, - &rect, - canvas); - - // Draw the tick-marks on the scroll bar, if any tick-marks - // exist. Note: The thumb will be drawn on top of the tick-marks, - // which is desired. - DrawTickmarks(gc); - - // Draw the thumb (the box you drag in the scroll bar to scroll). - rect = gfx::SkIRectToRECT(m_segmentRects[Thumb]); - nativeTheme->PaintScrollbarThumb(hdc, - horz ? SBP_THUMBBTNHORZ : - SBP_THUMBBTNVERT, - getThemeState(Thumb), - getClassicThemeState(Thumb), - &rect); - - // Draw the gripper (the three little lines on the thumb). - rect = gfx::SkIRectToRECT(m_segmentRects[Thumb]); - nativeTheme->PaintScrollbarThumb(hdc, - horz ? SBP_GRIPPERHORZ : - SBP_GRIPPERVERT, - getThemeState(Thumb), - getClassicThemeState(Thumb), - &rect); - } - - // Draw the down/right arrow of the scroll bar. - rect = gfx::SkIRectToRECT(m_segmentRects[Arrow2]); - nativeTheme->PaintScrollbarArrow(hdc, getThemeArrowState(Arrow2), - (horz ? - DFCS_SCROLLRIGHT : DFCS_SCROLLDOWN) | - getClassicThemeState(Arrow2), - &rect); - gc->platformContext()->canvas()->endPlatformPaint(); - - gc->restore(); -#endif -} - -void PlatformScrollbar::setFrameGeometry(const IntRect& rect) -{ - if (rect == frameGeometry()) - return; - - Widget::setFrameGeometry(rect); - m_needsLayout = true; - // NOTE: we assume that our caller will invalidate us -} - -bool PlatformScrollbar::handleMouseMoveEvent(const PlatformMouseEvent& e) -{ - if (!parent()) - return true; - - if (m_captureStart != None) { - handleMouseMoveEventWhenCapturing(e); - return true; - } - - IntPoint pos = convertFromContainingWindow(e.pos()); - updateMousePosition(pos.x(), pos.y()); - - // FIXME: Invalidate only the portions that actually changed - invalidate(); - return true; -} - -bool PlatformScrollbar::handleMouseOutEvent(const PlatformMouseEvent& e) -{ - if (!parent()) - return true; - - ASSERT(m_captureStart == None); - - // Pass bogus values that will never match real mouse coords. - updateMousePosition(-1, -1); - - // FIXME: Invalidate only the portions that actually changed - invalidate(); - return true; -} - -bool PlatformScrollbar::handleMouseReleaseEvent(const PlatformMouseEvent& e) -{ - ScrollView* parentView = parent(); - if (!parentView) - return true; - - IntPoint pos = convertFromContainingWindow(e.pos()); - updateMousePosition(pos.x(), pos.y()); - - setCapturingMouse(false); - - // FIXME: Invalidate only the portions that actually changed - invalidate(); - return true; -} - -bool PlatformScrollbar::handleMousePressEvent(const PlatformMouseEvent& e) -{ - if (!parent()) - return true; - - // TODO(pkasting): http://b/583875 Right-click should invoke a context menu - // (maybe this would be better handled elsewhere?) - if (!m_enabled || (e.button() != LeftButton)) { - return true; - } - - ASSERT(m_captureStart == None); - - IntPoint pos = convertFromContainingWindow(e.pos()); - - const bool horz = (orientation() == HorizontalScrollbar); - updateMousePosition(pos.x(), pos.y()); - switch (m_mouseOver) { - case Arrow1: - scroll(horz ? ScrollLeft : ScrollUp, ScrollByLine); - break; - case Track: - return true; - case BeforeThumb: - scroll(horz ? ScrollLeft : ScrollUp, ScrollByPage); - break; - case Thumb: - m_dragOrigin.thumbPos = horz ? pos.x() : pos.y(); - m_dragOrigin.scrollVal = value(); - break; - case AfterThumb: - scroll(horz ? ScrollRight : ScrollDown, ScrollByPage); - break; - case Arrow2: - scroll(horz ? ScrollRight : ScrollDown, ScrollByLine); - break; - default: - ASSERT_NOT_REACHED(); - } - - setCapturingMouse(true); - - // Kick off auto-repeat timer - if (m_mouseOver != Thumb) - m_autorepeatTimer.start(kAutorepeatInitialDelay, - kAutorepeatRepeatInterval); - - m_needsLayout = true; - // FIXME: Invalidate only the portions that actually changed - invalidate(); - - return true; -} - -void PlatformScrollbar::handleMouseMoveEventWhenCapturing(const PlatformMouseEvent& e) -{ - IntPoint pos = convertFromContainingWindow(e.pos()); - updateMousePosition(pos.x(), pos.y()); - - if (m_captureStart != Thumb) { - // FIXME: Invalidate only the portions that actually changed - invalidate(); - return; - } - - int xCancelDistance, yCancelDistance, backgroundSpan, thumbGirth, delta; - // NOTE: The cancel distance calculations are based on the behavior of the - // MSVC8 main window scrollbar + some guessing/extrapolation - if (orientation() == HorizontalScrollbar) { - xCancelDistance = kOffEndMultiplier * horizontalScrollbarHeight(); - yCancelDistance = kOffSideMultiplier * horizontalScrollbarHeight(); - backgroundSpan = m_segmentRects[AfterThumb].right() - - m_segmentRects[BeforeThumb].x(); - thumbGirth = m_segmentRects[Thumb].right() - m_segmentRects[Thumb].x(); - delta = pos.x() - m_dragOrigin.thumbPos; - } else { - xCancelDistance = kOffSideMultiplier * verticalScrollbarWidth(); - yCancelDistance = kOffEndMultiplier * verticalScrollbarWidth(); - backgroundSpan = m_segmentRects[AfterThumb].bottom() - - m_segmentRects[BeforeThumb].y(); - thumbGirth = m_segmentRects[Thumb].bottom() - m_segmentRects[Thumb].y(); - delta = pos.y() - m_dragOrigin.thumbPos; - } - - // Snap scrollbar back to drag origin if mouse gets too far away - if ((m_lastNativePos.x() < - (m_segmentRects[BeforeThumb].x() - xCancelDistance)) || - (m_lastNativePos.x() > - (m_segmentRects[AfterThumb].right() + xCancelDistance)) || - (m_lastNativePos.y() < - (m_segmentRects[BeforeThumb].y() - yCancelDistance)) || - (m_lastNativePos.y() > - (m_segmentRects[AfterThumb].bottom() + yCancelDistance))) - delta = 0; - - // Convert delta from pixel coords to scrollbar logical coords - if (backgroundSpan > thumbGirth) { - if (setValue(m_dragOrigin.scrollVal + (delta * - (m_totalSize - m_visibleSize) / (backgroundSpan - thumbGirth)))) { - m_needsLayout = true; - // FIXME: Invalidate only the portions that actually changed - invalidate(); - } - } -} - -IntRect PlatformScrollbar::windowClipRect() const -{ - if (m_client) - return m_client->windowClipRect(); - - return convertToContainingWindow(IntRect(0, 0, width(), height())); -} - -void PlatformScrollbar::updateThumbPosition() -{ - m_needsLayout = true; - // FIXME: Invalidate only the portions that actually changed - invalidate(); -} - -void PlatformScrollbar::updateThumbProportion() -{ - // RenderLayer::updateScrollInfoAfterLayout changes the enabled state when - // the style is OSCROLL, however it doesn't change it when the style is OAUTO. - // As a workaround we enable the scrollbar if the visible size is less than - // the total size - if (!m_enabled && m_visibleSize < m_totalSize) { - setEnabled(true); - } - - // If the thumb was at the end of the track and the scrollbar was resized - // smaller, we need to cap the value to the new maximum. - if (setValue(value())) - return; // updateThumbPosition() already invalidated as needed - - m_needsLayout = true; - // FIXME: Invalidate only the portions that actually changed - invalidate(); -} - -void PlatformScrollbar::autoscrollTimerFired(Timer<PlatformScrollbar>*) -{ - ASSERT((m_captureStart != None) && (m_mouseOver == m_captureStart)); - - const bool horz = (orientation() == HorizontalScrollbar); - switch (m_captureStart) { - case Arrow1: - scroll(horz ? ScrollLeft : ScrollUp, ScrollByLine); - break; - case BeforeThumb: - scroll(horz ? ScrollLeft : ScrollUp, ScrollByPage); - break; - case AfterThumb: - scroll(horz ? ScrollRight : ScrollDown, ScrollByPage); - break; - case Arrow2: - scroll(horz ? ScrollRight : ScrollDown, ScrollByLine); - break; - default: - ASSERT_NOT_REACHED(); - } -} - -void PlatformScrollbar::setCapturingMouse(bool capturing) -{ - if (capturing) { - m_captureStart = m_mouseOver; - } else { - m_captureStart = None; - m_autorepeatTimer.stop(); - } -} - -int PlatformScrollbar::scrollButtonGirth(int systemMetricsCode, int limit, - int* backgroundSpan) -{ -#if PLATFORM(WIN_OS) - const int girth = webkit_glue::IsLayoutTestMode() ? - kLayoutTestScrollbarButtonGirth : GetSystemMetrics(systemMetricsCode); -#elif PLATFORM(UNIX) - const int girth = kLayoutTestScrollbarButtonGirth; -#endif - *backgroundSpan = limit - 2 * girth; - if (*backgroundSpan < 0) { - *backgroundSpan = 0; - return limit / 2; - } - return girth; -} - -int PlatformScrollbar::scrollThumbGirth(int systemMetricsCode, - int backgroundSpan) -{ -#if PLATFORM(WIN_OS) - const int minimumGirth = webkit_glue::IsLayoutTestMode() ? - kLayoutTestScrollbarThumbGirth : GetSystemMetrics(systemMetricsCode); -#elif PLATFORM(UNIX) - const int minimumGirth = kLayoutTestScrollbarThumbGirth; -#endif - return std::max<int>(m_visibleSize * backgroundSpan / m_totalSize, - minimumGirth); -} - -void PlatformScrollbar::layout() -{ -#if PLATFORM(WIN_OS) - if (!m_needsLayout) - return; - m_needsLayout = false; - - const IntRect invalid(-1, -1, 0, 0); - if (m_totalSize <= 0) { - for (int i = 0; i < NumSegments; ++i) - m_segmentRects[i] = invalid; - return; - } - - int buttonGirth, backgroundSpan, thumbGirth; - RECT box = {0}; - LONG* changingCoord1, * changingCoord2; - // For both orientations, we allow the buttonGirth to determine the - // backgroundSpan directly, to avoid rounding errors. - if (orientation() == HorizontalScrollbar) { - buttonGirth = scrollButtonGirth(SM_CXHSCROLL, width(), &backgroundSpan); - thumbGirth = scrollThumbGirth(SM_CXHTHUMB, backgroundSpan); - box.bottom += horizontalScrollbarHeight(); - changingCoord1 = &box.left; - changingCoord2 = &box.right; - } else { - buttonGirth = scrollButtonGirth(SM_CYVSCROLL, height(), - &backgroundSpan); - thumbGirth = scrollThumbGirth(SM_CYVTHUMB, backgroundSpan); - box.right += verticalScrollbarWidth(); - changingCoord1 = &box.top; - changingCoord2 = &box.bottom; - } - - // Scrollbar: |<|--------|XXX|------|>| - // Start arrow: |<| - *changingCoord2 += buttonGirth; - m_segmentRects[Arrow1] = gfx::RECTToSkIRect(box); - - if (thumbGirth >= backgroundSpan) { - if (backgroundSpan == 0) { - m_segmentRects[Track] = invalid; - } else { - // Track: |-------------------| - *changingCoord1 = *changingCoord2; - *changingCoord2 += backgroundSpan; - m_segmentRects[Track] = gfx::RECTToSkIRect(box); - } - - m_segmentRects[BeforeThumb] = invalid; - m_segmentRects[Thumb] = invalid; - m_segmentRects[AfterThumb] = invalid; - } else { - m_segmentRects[Track] = invalid; - - const int thumbOffset = (m_totalSize <= m_visibleSize) ? 0 : (value() * - (backgroundSpan - thumbGirth) / (m_totalSize - m_visibleSize)); - // Before thumb: |--------| - *changingCoord1 = *changingCoord2; - *changingCoord2 += thumbOffset; - m_segmentRects[BeforeThumb] = gfx::RECTToSkIRect(box); - - // Thumb: |XXX| - *changingCoord1 = *changingCoord2; - *changingCoord2 += thumbGirth; - m_segmentRects[Thumb] = gfx::RECTToSkIRect(box); - - // After thumb: |------| - *changingCoord1 = *changingCoord2; - *changingCoord2 += backgroundSpan - (thumbOffset + thumbGirth); - m_segmentRects[AfterThumb] = gfx::RECTToSkIRect(box); - } - - // End arrow: |>| - *changingCoord1 = *changingCoord2; - *changingCoord2 += buttonGirth; - m_segmentRects[Arrow2] = gfx::RECTToSkIRect(box); - - // Changed layout, so need to update m_mouseOver and m_autorepeatTimer - updateMousePositionInternal(); - - // DO NOT invalidate() here. We already invalidate()d for this layout when - // setting m_needsLayout = true; by the time we reach this point, we're - // called by paint(), so invalidate() is not only unnecessary but will - // waste effort. -#endif -} - -void PlatformScrollbar::updateMousePosition(int x, int y) -{ - m_lastNativePos.setX(x); - m_lastNativePos.setY(y); - - if (m_needsLayout) - layout(); // Calls updateMousePositionInternal() - else - updateMousePositionInternal(); -} - -void PlatformScrollbar::updateMousePositionInternal() -{ - m_mouseOver = None; - for (int i = 0; i < NumSegments; ++i) { - if ((m_lastNativePos.x() >= m_segmentRects[i].x()) && - (m_lastNativePos.x() < m_segmentRects[i].right()) && - (m_lastNativePos.y() >= m_segmentRects[i].y()) && - (m_lastNativePos.y() < m_segmentRects[i].bottom())) { - m_mouseOver = static_cast<Segment>(i); - break; - } - } - - // Start/stop autorepeat timer if capturing something other than the thumb. - if ((m_captureStart != None) && (m_captureStart != Thumb)) { - if (m_mouseOver != m_captureStart) - m_autorepeatTimer.stop(); // Safe to call when already stopped - else if (!m_autorepeatTimer.isActive()) - m_autorepeatTimer.startRepeating(kAutorepeatRepeatInterval); - } -} - -int PlatformScrollbar::getThemeState(Segment target) const -{ -#if PLATFORM(WIN_OS) - // When dragging the thumb, draw thumb pressed and other segments normal - // regardless of where the cursor actually is. See also four places in - // getThemeArrowState(). - if (m_captureStart == Thumb) { - if (target == Thumb) - return SCRBS_PRESSED; - return (win_util::GetWinVersion() < win_util::WINVERSION_VISTA) ? - SCRBS_NORMAL : SCRBS_HOVER; - } - if (!m_enabled) - return SCRBS_DISABLED; - if ((m_mouseOver != target) || (target == Track)) { - return ((m_mouseOver == None) || - (win_util::GetWinVersion() < win_util::WINVERSION_VISTA)) ? - SCRBS_NORMAL : SCRBS_HOVER; - } - if (m_captureStart == None) - return SCRBS_HOT; - return (m_captureStart == target) ? SCRBS_PRESSED : SCRBS_NORMAL; -#elif PLATFORM(UNIX) - return 0; -#endif -} - -int PlatformScrollbar::getThemeArrowState(Segment target) const -{ -#if PLATFORM(WIN_OS) - // We could take advantage of knowing the values in the state enum to write - // some simpler code, but treating the state enum as a black box seems - // clearer and more future-proof. - if (target == Arrow1) { - if (orientation() == HorizontalScrollbar) { - if (m_captureStart == Thumb) { - return - (win_util::GetWinVersion() < win_util::WINVERSION_VISTA) ? - ABS_LEFTNORMAL : ABS_LEFTHOVER; - } - if (!m_enabled) - return ABS_LEFTDISABLED; - if (m_mouseOver != target) { - return ((m_mouseOver == None) || - (win_util::GetWinVersion() < win_util::WINVERSION_VISTA)) ? - ABS_LEFTNORMAL : ABS_LEFTHOVER; - } - if (m_captureStart == None) - return ABS_LEFTHOT; - return (m_captureStart == target) ? - ABS_LEFTPRESSED : ABS_LEFTNORMAL; - } - if (m_captureStart == Thumb) { - return (win_util::GetWinVersion() < win_util::WINVERSION_VISTA) ? - ABS_UPNORMAL : ABS_UPHOVER; - } - if (!m_enabled) - return ABS_UPDISABLED; - if (m_mouseOver != target) { - return ((m_mouseOver == None) || - (win_util::GetWinVersion() < win_util::WINVERSION_VISTA)) ? - ABS_UPNORMAL : ABS_UPHOVER; - } - if (m_captureStart == None) - return ABS_UPHOT; - return (m_captureStart == target) ? ABS_UPPRESSED : ABS_UPNORMAL; - } - if (orientation() == HorizontalScrollbar) { - if (m_captureStart == Thumb) { - return (win_util::GetWinVersion() < win_util::WINVERSION_VISTA) ? - ABS_RIGHTNORMAL : ABS_RIGHTHOVER; - } - if (!m_enabled) - return ABS_RIGHTDISABLED; - if (m_mouseOver != target) { - return ((m_mouseOver == None) || - (win_util::GetWinVersion() < win_util::WINVERSION_VISTA)) ? - ABS_RIGHTNORMAL : ABS_RIGHTHOVER; - } - if (m_captureStart == None) - return ABS_RIGHTHOT; - return (m_captureStart == target) ? ABS_RIGHTPRESSED : ABS_RIGHTNORMAL; - } - if (m_captureStart == Thumb) { - return (win_util::GetWinVersion() < win_util::WINVERSION_VISTA) ? - ABS_DOWNNORMAL : ABS_DOWNHOVER; - } - if (!m_enabled) - return ABS_DOWNDISABLED; - if (m_mouseOver != target) { - return ((m_mouseOver == None) || - (win_util::GetWinVersion() < win_util::WINVERSION_VISTA)) ? - ABS_DOWNNORMAL : ABS_DOWNHOVER; - } - if (m_captureStart == None) - return ABS_DOWNHOT; - return (m_captureStart == target) ? ABS_DOWNPRESSED : ABS_DOWNNORMAL; -#elif PLATFORM(UNIX) - return 0; -#endif -} - -int PlatformScrollbar::getClassicThemeState(Segment target) const -{ -#if PLATFORM(WIN_OS) - // When dragging the thumb, draw the buttons normal even when hovered. - if (m_captureStart == Thumb) - return 0; - if (!m_enabled) - return DFCS_INACTIVE; - if ((m_mouseOver != target) || (target == Track)) - return 0; - if (m_captureStart == None) - return DFCS_HOT; - return (m_captureStart == target) ? (DFCS_PUSHED | DFCS_FLAT) : 0; -#elif PLATFORM(UNIX) - return 0; -#endif -} - -} // namespace WebCore diff --git a/webkit/port/platform/chromium/PlatformWidget.h b/webkit/port/platform/chromium/PlatformWidget.h index a97432b..8751657 100644 --- a/webkit/port/platform/chromium/PlatformWidget.h +++ b/webkit/port/platform/chromium/PlatformWidget.h @@ -27,8 +27,8 @@ // (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 PlatformWidget_h__ -#define PlatformWidget_h__ +#ifndef PlatformWidget_h +#define PlatformWidget_h #include "base/gfx/native_widget_types.h" diff --git a/webkit/port/platform/chromium/PopupMenuChromium.cpp b/webkit/port/platform/chromium/PopupMenuChromium.cpp index 8d63e71..841ca08 100644 --- a/webkit/port/platform/chromium/PopupMenuChromium.cpp +++ b/webkit/port/platform/chromium/PopupMenuChromium.cpp @@ -37,8 +37,10 @@ #include "Document.h" #include "Font.h" #include "Frame.h" +#include "FrameView.h" #include "FontSelector.h" #include "FramelessScrollView.h" +#include "FramelessScrollViewClient.h" #include "GraphicsContext.h" #include "IntRect.h" #include "NotImplemented.h" @@ -46,13 +48,12 @@ #include "PlatformKeyboardEvent.h" #include "PlatformMouseEvent.h" #include "PlatformScreen.h" -#include "PlatformScrollBar.h" #include "PlatformWheelEvent.h" -#include "SystemTime.h" #include "RenderBlock.h" #include "RenderTheme.h" +#include "ScrollbarTheme.h" +#include "SystemTime.h" #include "Widget.h" -#include "WidgetClientChromium.h" #if !PLATFORM(WIN_OS) #include "KeyboardCodes.h" @@ -77,10 +78,12 @@ static const TimeStamp kTypeAheadTimeoutMs = 1000; class PopupListBox; +// TODO(darin): Our FramelessScrollView classes need to implement HostWindow! + // This class holds a PopupListBox. Its sole purpose is to be able to draw // a border around its child. All its paint/event handling is just forwarded // to the child listBox (with the appropriate transforms). -class PopupContainer : public FramelessScrollView { +class PopupContainer : public FramelessScrollView, public RefCounted<PopupContainer> { public: static PassRefPtr<PopupContainer> create(PopupMenuClient* client); @@ -107,6 +110,8 @@ public: PopupListBox* listBox() const { return m_listBox.get(); } private: + friend class RefCounted<PopupContainer>; + PopupContainer(PopupMenuClient* client); ~PopupContainer(); @@ -118,7 +123,7 @@ private: // This class uses WebCore code to paint and handle events for a drop-down list // box ("combobox" on Windows). -class PopupListBox : public FramelessScrollView { +class PopupListBox : public FramelessScrollView, public RefCounted<PopupListBox> { public: // FramelessScrollView virtual void paint(GraphicsContext* gc, const IntRect& rect); @@ -128,6 +133,9 @@ public: virtual bool handleWheelEvent(const PlatformWheelEvent& event); virtual bool handleKeyEvent(const PlatformKeyboardEvent& event); + // ScrollView + virtual HostWindow* hostWindow() const; + // PopupListBox methods // Show the popup @@ -168,6 +176,7 @@ public: private: friend class PopupContainer; + friend class RefCounted<PopupListBox>; // A type of List Item enum ListItemType { @@ -194,7 +203,7 @@ private: , m_repeatingChar(0) , m_lastCharTime(0) { - setScrollbarsMode(ScrollbarAlwaysOff); + setScrollbarModes(ScrollbarAlwaysOff, ScrollbarAlwaysOff); } ~PopupListBox() @@ -273,10 +282,10 @@ private: // The scrollbar which has mouse capture. Mouse events go straight to this // if non-NULL. - RefPtr<PlatformScrollbar> m_capturingScrollbar; + RefPtr<Scrollbar> m_capturingScrollbar; // The last scrollbar that the mouse was over. Used for mouseover highlights. - RefPtr<PlatformScrollbar> m_lastScrollbarUnderMouse; + RefPtr<Scrollbar> m_lastScrollbarUnderMouse; // The string the user has typed so far into the popup. Used for typeAheadFind. String m_typedString; @@ -289,12 +298,12 @@ private: }; static PlatformMouseEvent constructRelativeMouseEvent(const PlatformMouseEvent& e, - FrameView* parent, - FrameView* child) + FramelessScrollView* parent, + FramelessScrollView* child) { IntPoint pos = parent->convertSelfToChild(child, e.pos()); - // FIXME(beng): This is a horrible hack since PlatformWheelEvent has no setters for x/y. + // FIXME(beng): This is a horrible hack since PlatformMouseEvent has no setters for x/y. // Need to add setters and get patch back upstream to webkit source. PlatformMouseEvent relativeEvent = e; IntPoint& relativePos = const_cast<IntPoint&>(relativeEvent.pos()); @@ -304,8 +313,8 @@ static PlatformMouseEvent constructRelativeMouseEvent(const PlatformMouseEvent& } static PlatformWheelEvent constructRelativeWheelEvent(const PlatformWheelEvent& e, - FrameView* parent, - FrameView* child) + FramelessScrollView* parent, + FramelessScrollView* child) { IntPoint pos = parent->convertSelfToChild(child, e.pos()); @@ -334,7 +343,7 @@ PopupContainer::PopupContainer(PopupMenuClient* client) // assign it to a RefPtr. m_listBox->deref(); - setScrollbarsMode(ScrollbarAlwaysOff); + setScrollbarModes(ScrollbarAlwaysOff, ScrollbarAlwaysOff); } PopupContainer::~PopupContainer() @@ -346,25 +355,23 @@ PopupContainer::~PopupContainer() void PopupContainer::showPopup(FrameView* view) { // Pre-layout, our size matches the <select> dropdown control. - int selectHeight = frameGeometry().height(); + int selectHeight = frameRect().height(); // Lay everything out to figure out our preferred size, then tell the view's // WidgetClient about it. It should assign us a client. layout(); - WidgetClientChromium* widgetClient = static_cast<WidgetClientChromium*>( - view->client()); ChromeClientChromium* chromeClient = static_cast<ChromeClientChromium*>( view->frame()->page()->chrome()->client()); - if (widgetClient && chromeClient) { + if (chromeClient) { // If the popup would extend past the bottom of the screen, open upwards // instead. FloatRect screen = screenRect(view); - IntRect widgetRect = chromeClient->windowToScreen(frameGeometry()); + IntRect widgetRect = chromeClient->windowToScreen(frameRect()); if (widgetRect.bottom() > static_cast<int>(screen.bottom())) widgetRect.move(0, -(widgetRect.height() + selectHeight)); - widgetClient->popupOpened(this, widgetRect); + chromeClient->popupOpened(this, widgetRect); } // Must get called after we have a client and containingWindow. @@ -372,7 +379,7 @@ void PopupContainer::showPopup(FrameView* view) // Enable scrollbars after the listbox is inserted into the hierarchy, so // it has a proper WidgetClient. - m_listBox->setVScrollbarMode(ScrollbarAuto); + m_listBox->setVerticalScrollbarMode(ScrollbarAuto); m_listBox->scrollToRevealSelection(); @@ -385,9 +392,10 @@ void PopupContainer::hidePopup() m_listBox->disconnectClient(); removeChild(m_listBox.get()); - + m_listBox = 0; + if (client()) - static_cast<WidgetClientChromium*>(client())->popupClosed(this); + client()->popupClosed(this); } void PopupContainer::layout() @@ -439,7 +447,7 @@ void PopupContainer::hide() { void PopupContainer::paint(GraphicsContext* gc, const IntRect& rect) { // adjust coords for scrolled frame - IntRect r = intersection(rect, frameGeometry()); + IntRect r = intersection(rect, frameRect()); int tx = x(); int ty = y(); @@ -476,10 +484,10 @@ void PopupContainer::paintBorder(GraphicsContext* gc, const IntRect& rect) bool PopupListBox::handleMouseDownEvent(const PlatformMouseEvent& event) { - PlatformScrollbar* scrollbar = scrollbarUnderMouse(event); + Scrollbar* scrollbar = scrollbarUnderMouse(event); if (scrollbar) { m_capturingScrollbar = scrollbar; - m_capturingScrollbar->handleMousePressEvent(event); + m_capturingScrollbar->mouseDown(event); return true; } @@ -492,20 +500,20 @@ bool PopupListBox::handleMouseDownEvent(const PlatformMouseEvent& event) bool PopupListBox::handleMouseMoveEvent(const PlatformMouseEvent& event) { if (m_capturingScrollbar) { - m_capturingScrollbar->handleMouseMoveEvent(event); + m_capturingScrollbar->mouseMoved(event); return true; } - PlatformScrollbar* scrollbar = scrollbarUnderMouse(event); + Scrollbar* scrollbar = scrollbarUnderMouse(event); if (m_lastScrollbarUnderMouse != scrollbar) { // Send mouse exited to the old scrollbar. if (m_lastScrollbarUnderMouse) - m_lastScrollbarUnderMouse->handleMouseOutEvent(event); + m_lastScrollbarUnderMouse->mouseExited(); m_lastScrollbarUnderMouse = scrollbar; } if (scrollbar) { - scrollbar->handleMouseMoveEvent(event); + scrollbar->mouseMoved(event); return true; } @@ -519,7 +527,7 @@ bool PopupListBox::handleMouseMoveEvent(const PlatformMouseEvent& event) bool PopupListBox::handleMouseReleaseEvent(const PlatformMouseEvent& event) { if (m_capturingScrollbar) { - m_capturingScrollbar->handleMouseReleaseEvent(event); + m_capturingScrollbar->mouseUp(); m_capturingScrollbar = 0; return true; } @@ -598,6 +606,13 @@ bool PopupListBox::handleKeyEvent(const PlatformKeyboardEvent& event) return true; } +HostWindow* PopupListBox::hostWindow() const +{ + // Our parent is the root ScrollView, so it is the one that has a + // HostWindow. FrameView::hostWindow() works similarly. + return parent() ? parent()->hostWindow() : 0; +} + // From HTMLSelectElement.cpp static String stripLeadingWhiteSpace(const String& string) { @@ -655,9 +670,9 @@ void PopupListBox::typeAheadFind(const PlatformKeyboardEvent& event) void PopupListBox::paint(GraphicsContext* gc, const IntRect& rect) { // adjust coords for scrolled frame - IntRect r = intersection(rect, frameGeometry()); - int tx = x() - contentsX(); - int ty = y() - contentsY(); + IntRect r = intersection(rect, frameRect()); + int tx = x() - scrollX(); + int ty = y() - scrollY(); r.move(-tx, -ty); @@ -680,12 +695,8 @@ void PopupListBox::paint(GraphicsContext* gc, const IntRect& rect) ScrollView::paint(gc, rect); } -static RenderStyle* getPopupClientStyleForRow(PopupMenuClient* client, int rowIndex) { - RenderStyle* style = client->itemStyle(rowIndex); - if (!style) - style = client->clientStyle(); - return style; -} +static const int separatorPadding = 4; +static const int separatorHeight = 1; void PopupListBox::paintRow(GraphicsContext* gc, const IntRect& rect, int rowIndex) { @@ -695,7 +706,7 @@ void PopupListBox::paintRow(GraphicsContext* gc, const IntRect& rect, int rowInd if (!rowRect.intersects(rect)) return; - RenderStyle* style = getPopupClientStyleForRow(m_popupClient, rowIndex); + PopupMenuStyle style = m_popupClient->itemStyle(rowIndex); // Paint background Color backColor, textColor; @@ -703,16 +714,26 @@ void PopupListBox::paintRow(GraphicsContext* gc, const IntRect& rect, int rowInd backColor = theme()->activeListBoxSelectionBackgroundColor(); textColor = theme()->activeListBoxSelectionForegroundColor(); } else { - backColor = m_popupClient->itemBackgroundColor(rowIndex); - textColor = style->color(); + backColor = style.backgroundColor(); + textColor = style.foregroundColor(); } // If we have a transparent background, make sure it has a color to blend // against. if (backColor.hasAlpha()) - gc->fillRect(rowRect, Color::white); + gc->fillRect(rowRect, Color::white); gc->fillRect(rowRect, backColor); + + if (m_popupClient->itemIsSeparator(rowIndex)) { + IntRect separatorRect( + rowRect.x() + separatorPadding, + rowRect.y() + (rowRect.height() - separatorHeight) / 2, + rowRect.width() - 2 * separatorPadding, separatorHeight); + gc->fillRect(separatorRect, textColor); + return; + } + gc->setFillColor(textColor); Font itemFont = getRowFont(rowIndex); @@ -723,22 +744,22 @@ void PopupListBox::paintRow(GraphicsContext* gc, const IntRect& rect, int rowInd unsigned length = itemText.length(); const UChar* str = itemText.characters(); - TextRun textRun(str, length, false, 0, 0, style->direction() == RTL, style->unicodeBidi() == Override); + TextRun textRun(str, length, false, 0, 0, itemText.defaultWritingDirection() == WTF::Unicode::RightToLeft); + + // TODO(ojan): http://b/1210481 We should get the padding of individual + // option elements. This probably implies changes to PopupMenuClient. // Draw the item text - // TODO(ojan): http://b/1210481 We should get the padding of individual option elements. - rowRect.move(theme()->popupInternalPaddingLeft(style), itemFont.ascent()); - if (style->direction() == RTL) { - // Right-justify the text for RTL style. - rowRect.move(rowRect.width() - itemFont.width(textRun) - - 2 * theme()->popupInternalPaddingLeft(style), 0); + if (style.isVisible()) { + int textX = max(0, m_popupClient->clientPaddingLeft() - m_popupClient->clientInsetLeft()); + int textY = rowRect.y() + itemFont.ascent() + (rowRect.height() - itemFont.height()) / 2; + gc->drawBidiText(textRun, IntPoint(textX, textY)); } - gc->drawBidiText(textRun, rowRect.location()); } Font PopupListBox::getRowFont(int rowIndex) { - Font itemFont = m_popupClient->itemStyle(rowIndex)->font(); + Font itemFont = m_popupClient->itemStyle(rowIndex).font(); if (m_popupClient->itemIsLabel(rowIndex)) { // Bold-ify labels (ie, an <optgroup> heading). FontDescription d = itemFont.fontDescription(); @@ -767,7 +788,7 @@ void PopupListBox::abandon() int PopupListBox::pointToRowIndex(const IntPoint& point) { - int y = contentsY() + point.y(); + int y = scrollY() + point.y(); // TODO(mpcomplete): binary search if perf matters. for (int i = 0; i < numItems(); ++i) { @@ -818,10 +839,7 @@ void PopupListBox::setOriginalIndex(int index) int PopupListBox::getRowHeight(int index) { - RenderStyle* style; - if ((index < 0) || (!(style = m_popupClient->itemStyle(index)))) - style = m_popupClient->clientStyle(); - return style->font().height(); + return m_popupClient->itemStyle(index).font().height(); } IntRect PopupListBox::getRowBounds(int index) @@ -838,7 +856,7 @@ void PopupListBox::invalidateRow(int index) if (index < 0) return; - updateContents(getRowBounds(index)); + invalidateRect(getRowBounds(index)); } void PopupListBox::scrollToRevealRow(int index) @@ -848,12 +866,12 @@ void PopupListBox::scrollToRevealRow(int index) IntRect rowRect = getRowBounds(index); - if (rowRect.y() < contentsY()) { + if (rowRect.y() < scrollY()) { // Row is above current scroll position, scroll up. - ScrollView::setContentsPos(0, rowRect.y()); - } else if (rowRect.bottom() > contentsY() + visibleHeight()) { + ScrollView::setScrollPosition(IntPoint(0, rowRect.y())); + } else if (rowRect.bottom() > scrollY() + visibleHeight()) { // Row is below current scroll position, scroll down. - ScrollView::setContentsPos(0, rowRect.bottom() - visibleHeight()); + ScrollView::setScrollPosition(IntPoint(0, rowRect.bottom() - visibleHeight())); } } @@ -946,10 +964,9 @@ void PopupListBox::layout() int width = itemFont.width(TextRun(text)); baseWidth = max(baseWidth, width); } - RenderStyle* style = getPopupClientStyleForRow(m_popupClient, i); // TODO(ojan): http://b/1210481 We should get the padding of individual option elements. paddingWidth = max(paddingWidth, - theme()->popupInternalPaddingLeft(style) + theme()->popupInternalPaddingRight(style)); + m_popupClient->clientPaddingLeft() + m_popupClient->clientPaddingRight()); } int windowHeight = 0; @@ -970,7 +987,7 @@ void PopupListBox::layout() // Set our widget and scrollable contents sizes. int scrollbarWidth = 0; if (m_visibleRows < numItems()) - scrollbarWidth = PlatformScrollbar::verticalScrollbarWidth(); + scrollbarWidth = ScrollbarTheme::nativeTheme()->scrollbarThickness(); int windowWidth = baseWidth + scrollbarWidth + paddingWidth; int contentWidth = baseWidth; @@ -983,8 +1000,10 @@ void PopupListBox::layout() } resize(windowWidth, windowHeight); - resizeContents(contentWidth, getRowBounds(numItems() - 1).bottom()); - scrollToRevealSelection(); + setContentsSize(IntSize(contentWidth, getRowBounds(numItems() - 1).bottom())); + + if (hostWindow()) + scrollToRevealSelection(); invalidate(); } @@ -1042,7 +1061,7 @@ void PopupMenu::show(const IntRect& r, FrameView* v, int index) location.move(0, r.height()); IntRect popupRect(location, r.size()); - p.m_popup->setFrameGeometry(popupRect); + p.m_popup->setFrameRect(popupRect); p.m_popup->showPopup(v); } diff --git a/webkit/port/platform/chromium/ScrollViewChromium.cpp b/webkit/port/platform/chromium/ScrollViewChromium.cpp deleted file mode 100644 index b773243..0000000 --- a/webkit/port/platform/chromium/ScrollViewChromium.cpp +++ /dev/null @@ -1,1251 +0,0 @@ -/* - * Copyright (C) 2006, 2007 Apple 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: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 "ScrollView.h" - -#include "Chrome.h" -#include "ChromeClient.h" -#include "FloatRect.h" -#include "FocusController.h" -#include "Frame.h" -#include "FrameView.h" -#include "GraphicsContext.h" -#include "IntRect.h" -#include "NotImplemented.h" -#include "Page.h" -#include "PlatformScrollBar.h" -#include "PlatformMouseEvent.h" -#include "PlatformWheelEvent.h" -#include "Range.h" -#include "RenderTheme.h" -#include "ScrollBar.h" -#include "SkiaUtils.h" -#include "WidgetClientChromium.h" -#include <algorithm> -#include <wtf/Assertions.h> -#include <wtf/HashSet.h> - -#undef LOG -#include "base/gfx/platform_canvas.h" -#include "webkit/glue/webframe_impl.h" -#include "webkit/glue/webview_impl.h" - -using namespace std; - -namespace WebCore { - -class ScrollView::ScrollViewPrivate : public ScrollbarClient { -public: - ScrollViewPrivate(ScrollView* view) - : m_view(view) - , m_hasStaticBackground(false) - , m_scrollbarsSuppressed(false) - , m_inUpdateScrollbars(false) - , m_scrollbarsAvoidingResizer(0) - , m_vScrollbarMode(ScrollbarAuto) - , m_hScrollbarMode(ScrollbarAuto) - , m_visible(false) - , m_attachedToWindow(false) - , m_panScrollIconPoint(0,0) - , m_drawPanScrollIcon(false) - { - } - - ~ScrollViewPrivate() - { - setHasHorizontalScrollbar(false); - setHasVerticalScrollbar(false); - } - - void setHasHorizontalScrollbar(bool hasBar); - void setHasVerticalScrollbar(bool hasBar); - - virtual void valueChanged(Scrollbar*); - virtual IntRect windowClipRect() const; - virtual bool isActive() const; - - void scrollBackingStore(const IntSize& scrollDelta); - - // Get the vector containing the result from the FindInPage operation. - const Vector<RefPtr<Range> >* getTickmarks() const; - - // Retrieves the index of the active tickmark for a given frame. If the - // frame does not have an active tickmark (for example if the active - // tickmark resides in another frame) this function returns kNoTickmark. - size_t getActiveTickmarkIndex() const; - - // This is a helper function for accessing the bitmaps that have been cached - // in the renderer. - const SkBitmap* GetPreloadedBitmapFromRenderer(int resource_id) const; - - // Highlight the matches found during FindInPage operation. - void highlightMatches(GraphicsContext* context) const; - - // Highlights the node selected in the DOM inspector. - void highlightInspectedNode(GraphicsContext* context, Frame* frame) const; - -#if PLATFORM(WIN_OS) - // Highlight a certain Range on the page. - void highlightRange(HDC hdc, HDC mem_dc, RefPtr<Range> range) const; -#endif - - void setAllowsScrolling(bool); - bool allowsScrolling() const; - - ScrollView* m_view; - IntSize m_scrollOffset; - IntSize m_contentsSize; - bool m_hasStaticBackground; - bool m_scrollbarsSuppressed; - bool m_inUpdateScrollbars; - int m_scrollbarsAvoidingResizer; - ScrollbarMode m_vScrollbarMode; - ScrollbarMode m_hScrollbarMode; - RefPtr<PlatformScrollbar> m_vBar; - RefPtr<PlatformScrollbar> m_hBar; - HashSet<Widget*> m_children; - bool m_visible; - bool m_attachedToWindow; - IntPoint m_panScrollIconPoint; - bool m_drawPanScrollIcon; -}; - -const int panIconSizeLength = 20; - -void ScrollView::ScrollViewPrivate::setHasHorizontalScrollbar(bool hasBar) -{ - if (Scrollbar::hasPlatformScrollbars()) { - if (hasBar && !m_hBar) { - m_hBar = PlatformScrollbar::create(this, HorizontalScrollbar, RegularScrollbar); - m_view->addChild(m_hBar.get()); - } else if (!hasBar && m_hBar) { - m_view->removeChild(m_hBar.get()); - m_hBar = 0; - } - } -} - -void ScrollView::ScrollViewPrivate::setHasVerticalScrollbar(bool hasBar) -{ - if (Scrollbar::hasPlatformScrollbars()) { - if (hasBar && !m_vBar) { - m_vBar = PlatformScrollbar::create(this, VerticalScrollbar, RegularScrollbar); - m_view->addChild(m_vBar.get()); - } else if (!hasBar && m_vBar) { - m_view->removeChild(m_vBar.get()); - m_vBar = 0; - } - } -} - -void ScrollView::ScrollViewPrivate::valueChanged(Scrollbar* bar) -{ - // Figure out if we really moved. - IntSize newOffset = m_scrollOffset; - if (bar) { - if (bar == m_hBar) - newOffset.setWidth(bar->value()); - else if (bar == m_vBar) - newOffset.setHeight(bar->value()); - } - IntSize scrollDelta = newOffset - m_scrollOffset; - if (scrollDelta == IntSize()) - return; - m_scrollOffset = newOffset; - - if (m_scrollbarsSuppressed) - return; - - scrollBackingStore(scrollDelta); - - if (Frame* frame = static_cast<FrameView*>(m_view)->frame()) { - frame->sendScrollEvent(); - - // Inform the delegate that the scroll position has changed. - WidgetClientChromium* client = - static_cast<WidgetClientChromium*>(m_view->client()); - if (client) - client->onScrollPositionChanged(m_view); - } -} - -void ScrollView::ScrollViewPrivate::scrollBackingStore(const IntSize& scrollDelta) -{ - // Since scrolling is double buffered, we will be blitting the scroll view's intersection - // with the clip rect every time to keep it smooth. - - IntRect clipRect = m_view->windowClipRect(); - IntRect scrollViewRect = m_view->convertToContainingWindow(IntRect(0, 0, m_view->visibleWidth(), m_view->visibleHeight())); - - // Negative when our frame is smaller than the min scrollbar width. - if (scrollViewRect.width() < 0) - scrollViewRect.setWidth(0); - if (scrollViewRect.height() < 0) - scrollViewRect.setHeight(0); - - if (!m_hasStaticBackground) { // The main frame can just blit the WebView window - // FIXME: Find a way to blit subframes without blitting overlapping content - m_view->scrollBackingStore(-scrollDelta.width(), -scrollDelta.height(), scrollViewRect, clipRect); - } else { - IntRect updateRect = clipRect; - updateRect.intersect(scrollViewRect); - - // We need to go ahead and repaint the entire backing store. Do it now before moving the - // plugins. - m_view->addToDirtyRegion(updateRect); - m_view->updateBackingStore(); - } - - // This call will move child HWNDs (plugins) and invalidate them as well. - m_view->geometryChanged(); -} - -void ScrollView::ScrollViewPrivate::setAllowsScrolling(bool flag) -{ - if (flag && m_vScrollbarMode == ScrollbarAlwaysOff) - m_vScrollbarMode = ScrollbarAuto; - else if (!flag) - m_vScrollbarMode = ScrollbarAlwaysOff; - - if (flag && m_hScrollbarMode == ScrollbarAlwaysOff) - m_hScrollbarMode = ScrollbarAuto; - else if (!flag) - m_hScrollbarMode = ScrollbarAlwaysOff; - - m_view->updateScrollbars(m_scrollOffset); -} - -bool ScrollView::ScrollViewPrivate::allowsScrolling() const -{ - // Return YES if either horizontal or vertical scrolling is allowed. - return m_hScrollbarMode != ScrollbarAlwaysOff || m_vScrollbarMode != ScrollbarAlwaysOff; -} - -IntRect ScrollView::ScrollViewPrivate::windowClipRect() const -{ - // FrameView::windowClipRect() will exclude the scrollbars, but here we - // want to include them, so we are forced to cast to FrameView in order to - // call the non-virtual version of windowClipRect :-( - // - // The non-frame case exists to support FramelessScrollView. - - const FrameView* frameView = static_cast<const FrameView*>(m_view); - if (frameView->frame()) - return frameView->windowClipRect(false); - - return m_view->windowClipRect(); -} - -bool ScrollView::ScrollViewPrivate::isActive() const -{ - Page* page = static_cast<const FrameView*>(m_view)->frame()->page(); - return page && page->focusController()->isActive(); -} - -const Vector<RefPtr<Range> >* ScrollView::ScrollViewPrivate::getTickmarks() const -{ - FrameView* view = static_cast<FrameView*>(m_view); - ASSERT(view); - Frame* frame = view->frame(); - - if (!frame) - return NULL; // NOTE: Frame can be null for dropdown boxes. - - WidgetClientChromium* c = - static_cast<WidgetClientChromium*>(m_view->client()); - ASSERT(c); - return c->getTickmarks(view->frame()); -} - -size_t ScrollView::ScrollViewPrivate::getActiveTickmarkIndex() const -{ - FrameView* view = static_cast<FrameView*>(m_view); - ASSERT(view); - Frame* frame = view->frame(); - - // NOTE: Frame can be null for dropdown boxes. - if (!frame) - return WidgetClientChromium::kNoTickmark; - - WidgetClientChromium* c = - static_cast<WidgetClientChromium*>(m_view->client()); - ASSERT(c); - return c->getActiveTickmarkIndex(view->frame()); -} - -const SkBitmap* ScrollView::ScrollViewPrivate::GetPreloadedBitmapFromRenderer( - int resource_id) const -{ - WidgetClientChromium* c = - static_cast<WidgetClientChromium*>(m_view->client()); - if (!c) - return NULL; - - return c->getPreloadedResourceBitmap(resource_id); -} - -#if PLATFORM(WIN_OS) -void ScrollView::ScrollViewPrivate::highlightMatches( - GraphicsContext* context) const -{ - if (context->paintingDisabled()) - return; - - const Vector<RefPtr<Range> >* tickmarks = getTickmarks(); - if (!tickmarks || tickmarks->isEmpty()) - return; - - context->save(); - context->translate(m_view->x(), m_view->y()); - - // NOTE: We tolerate the platformContext() call here because the scrollbars - // will not be serialized, i.e. composition is done in the renderer and - // never in the browser. - // Prepare for drawing the arrows along the scroll bar. - gfx::PlatformCanvas* canvas = context->platformContext()->canvas(); - - int horz_start = 0; - int horz_end = m_view->width(); - int vert_start = 0; - int vert_end = m_view->height(); - - if (m_vBar) { - // Account for the amount of scrolling on the vertical scroll bar. - vert_start += m_scrollOffset.height(); - vert_end += m_scrollOffset.height(); - // Don't draw atop the vertical scrollbar. - horz_end -= PlatformScrollbar::verticalScrollbarWidth() + 1; - } - - if (m_hBar) { - // Account for the amount of scrolling on the horizontal scroll bar. - horz_start += m_scrollOffset.width(); - horz_end += m_scrollOffset.width(); - // Don't draw atop the horizontal scrollbar. - vert_end -= PlatformScrollbar::horizontalScrollbarHeight() + 1; - } - - HDC hdc = canvas->beginPlatformPaint(); - - // We create a memory DC, copy the bits we want to highlight to the DC and - // then MERGE_COPY pieces of it back with a yellow brush selected (which - // gives them yellow highlighting). - HDC mem_dc = CreateCompatibleDC(hdc); - HBITMAP mem_bmp = CreateCompatibleBitmap(hdc, m_view->width(), - m_view->height()); - HGDIOBJ old_bmp = SelectObject(mem_dc, mem_bmp); - - // Now create a brush for hit highlighting. This is needed for the MERGECOPY - // to paint a yellow highlight onto the matches found. For more details, see - // the documentation for BitBlt. - static const COLORREF kFillColor = RGB(255, 250, 150); // Light yellow. - HGDIOBJ inactive_brush = CreateSolidBrush(kFillColor); - static const COLORREF kFillColorActive = RGB(255, 150, 50); // Orange. - HGDIOBJ active_brush = CreateSolidBrush(kFillColorActive); - HGDIOBJ old_brush = SelectObject(hdc, inactive_brush); - - // Keep a copy of what's on screen, so we can MERGECOPY it back later for - // the purpose of highlighting the text. - BitBlt(mem_dc, 0, 0, m_view->width(), m_view->height(), - hdc, 0, 0, SRCCOPY); - - const size_t active_tickmark = getActiveTickmarkIndex(); - for (Vector<RefPtr<Range> >::const_iterator i = tickmarks->begin(); - i != tickmarks->end(); ++i) { - const RefPtr<Range> range = (*i); - const IntRect& bounds = range->boundingBox(); - // To highlight the word, we check if the rectangle boundary is within - // the bounds vertically as well as horizontally. - if (bounds.bottomRight().y() > vert_start && - bounds.topLeft().y() < vert_end && - bounds.bottomRight().x() > horz_start && - bounds.topLeft().x() < horz_end && - WebFrameImpl::RangeShouldBeHighlighted(range.get())) { - // We highlight the active tick-mark with a green color instead - // of the normal yellow color. - SelectObject(hdc, ((i - tickmarks->begin()) == active_tickmark) ? - active_brush : inactive_brush); - highlightRange(hdc, mem_dc, range); - } - } - - SelectObject(mem_dc, old_brush); - DeleteObject(active_brush); - DeleteObject(inactive_brush); - - SelectObject(mem_dc, old_bmp); - DeleteObject(mem_bmp); - - DeleteDC(mem_dc); - - canvas->endPlatformPaint(); - context->restore(); -} -#else -void ScrollView::ScrollViewPrivate::highlightMatches( - GraphicsContext* context) const -{ - notImplemented(); -} -#endif - -// TODO(ojan): http://b/1143983 make this work for inline elements as they can -// wrap (use highlightRange instead?) -void ScrollView::ScrollViewPrivate::highlightInspectedNode( - GraphicsContext* context, Frame* frame) const -{ - WebViewImpl* c = static_cast<WebViewImpl*>(m_view->client()); - const WebCore::Node* inspected_node = c->getInspectedNode(frame); - - if (!inspected_node) - return; - -#if !PLATFORM(CG) - SkPaint paint; - paint.setARGB(122, 255, 225, 0); // Yellow - - // TODO(ojan): http://b/1143991 Once we sync a Skia version that supports - // it, use SkPorterDuff::kScreenMode and remove the transparency. - // Then port highlightMatches/highlightRanges to use this as well. - // Although, perhaps the web inspector really should be using - // an alpha overlay? It's less pretty, but more clear what node - // is being overlayed. In this case, the TODO is to make - // highlightMatches/Ranges use Skia and to leave this as is. - // - // paint.setPorterDuffXfermode(SkPorterDuff::kScreenMode); - - // TODO(ojan): http://b/1143975 Draw the padding/border/margin boxes in - // different colors. - context->platformContext()->paintSkPaint(inspected_node->getRect(), paint); -#else - CGContextRef cg_context = context->platformContext(); - CGContextSaveGState(cg_context); - CGContextSetRGBFillColor(cg_context, 0.4784, 1.0, 0.8824, 1.0); - CGContextSetRGBStrokeColor(cg_context, 0.4784, 1.0, 0.8824, 1.0); - CGContextFillRect(cg_context, inspected_node->getRect()); - CGContextRestoreGState(cg_context); -#endif -} - -#if PLATFORM(WIN_OS) -void ScrollView::ScrollViewPrivate::highlightRange(HDC hdc, HDC mem_dc, - RefPtr<Range> range) const { - // We need to figure out whether the match that we want to - // highlight is on a single line or on multiple lines. - IntRect start = VisiblePosition(range->startPosition()).caretRect(); - IntRect end = VisiblePosition(range->endPosition()).caretRect(); - IntRect bounds = range->boundingBox(); - - // Multi-line bounds have different y pos for start and end. - if (start.y() == end.y()) { - int x = bounds.topLeft().x() - m_scrollOffset.width(); - int y = bounds.topLeft().y() - m_scrollOffset.height(); - int w = bounds.bottomRight().x() - bounds.topLeft().x() + 1; - int h = bounds.bottomRight().y() - bounds.topLeft().y() + 1; - - // MERGECOPY the relevant bits back, creating a highlight. - BitBlt(hdc, x, y, w, h, mem_dc, x, y, MERGECOPY); - } else { - // Multi line bounds, for example, when we need to highlight - // all the numbers (and only the numbers) in this block of - // text: - // - // xxxxxxxxxxxxxxxx11111111 - // 222222222222222222222222 - // 222222222222222222222222 - // 333333333333333xxxxxxxxx - // - // In this case, the bounding box will contain all the text, - // (including the exes (x)). We highlight in three steps. - // First we highlight the segment containing the ones (1) - // above. Then the whole middle section is highlighted, or the - // twos (2), and finally the remaining segment consisting of - // the threes (3) is highlighted. - - const int row_height = start.height(); - int x = 0, y = 0, w = 0, h = 0; - - // The start and end caret can be outside the bounding box, for leading - // and trailing whitespace and we should not highlight those. - if (start.intersects(bounds)) { - // Highlight the first segment. - x = start.x() - m_scrollOffset.width(); - y = start.y() - m_scrollOffset.height(); - w = bounds.topRight().x() - start.x() + 1; - h = row_height; - - BitBlt(hdc, x, y, w, h, mem_dc, x, y, MERGECOPY); - } - - // Figure out how large the middle section is. - int rows_between = (end.y() - start.y()) / row_height - 1; - - if (rows_between > 0) { - // Highlight the middle segment. - x = bounds.x() - m_scrollOffset.width(); - y = bounds.y() - m_scrollOffset.height() + row_height; - w = bounds.width(); - h = rows_between * row_height; - - BitBlt(hdc, x, y, w, h, mem_dc, x, y, MERGECOPY); - } - - // The end caret might not intersect the bounding box, for example - // when highlighting the last letter of a line that wraps. In that - // case the end caret is set to the beginning of the next line, and - // since it doesn't intersect with the bounding box we don't need to - // highlight. - if (end.intersects(bounds)) { - // Highlight the remaining segment. - x = bounds.bottomLeft().x() - m_scrollOffset.width(); - y = bounds.bottomLeft().y() - m_scrollOffset.height() - - row_height + 1; - w = end.x() - bounds.bottomLeft().x(); - h = row_height; - - BitBlt(hdc, x, y, w, h, mem_dc, x, y, MERGECOPY); - } - } -} -#endif - -ScrollView::ScrollView() -{ - m_data = new ScrollViewPrivate(this); -} - -ScrollView::~ScrollView() -{ - delete m_data; -} - -void ScrollView::updateContents(const IntRect& rect, bool now) -{ - if (rect.isEmpty()) - return; - - IntRect containingWindowRect = contentsToWindow(rect); - - if (containingWindowRect.x() < 0) - containingWindowRect.setX(0); - if (containingWindowRect.y() < 0) - containingWindowRect.setY(0); - - updateWindowRect(containingWindowRect, now); -} - -void ScrollView::updateWindowRect(const IntRect& rect, bool now) -{ - // TODO(dglazkov): make sure this is actually the right way to do this - - // Cache the dirty spot. - addToDirtyRegion(rect); - - // since painting always happens asynchronously, we don't have a way to - // honor the "now" parameter. it is unclear if it matters. - if (now) { - // TODO(iyengar): Should we force a layout to occur here? - geometryChanged(); - } -} - -void ScrollView::update() -{ - // TODO(iyengar): Should we force a layout to occur here? - geometryChanged(); -} - -int ScrollView::visibleWidth() const -{ - return width() - (m_data->m_vBar ? m_data->m_vBar->width() : 0); -} - -int ScrollView::visibleHeight() const -{ - return height() - (m_data->m_hBar ? m_data->m_hBar->height() : 0); -} - -FloatRect ScrollView::visibleContentRect() const -{ - return FloatRect(contentsX(), contentsY(), visibleWidth(), visibleHeight()); -} - -FloatRect ScrollView::visibleContentRectConsideringExternalScrollers() const -{ - // external scrollers not supported for now - return visibleContentRect(); -} - -void ScrollView::setContentsPos(int newX, int newY) -{ - int dx = newX - contentsX(); - int dy = newY - contentsY(); - scrollBy(dx, dy); -} - -void ScrollView::resizeContents(int w, int h) -{ - IntSize newContentsSize(w, h); - if (m_data->m_contentsSize != newContentsSize) { - m_data->m_contentsSize = newContentsSize; - updateScrollbars(m_data->m_scrollOffset); - } -} - -void ScrollView::setFrameGeometry(const IntRect& newGeometry) -{ - IntRect normalizedNewGeometry = newGeometry; - - // Webkit sometimes attempts to set negative sizes due to - // sloppy calculations of width with margins and such. - // (RenderPart:updateWidgetPosition is one example.) - // Safeguard against this and prevent negative heights/widths. - if (normalizedNewGeometry.width() < 0) - normalizedNewGeometry.setWidth(0); - if (normalizedNewGeometry.height() < 0) - normalizedNewGeometry.setHeight(0); - - IntRect oldGeometry = frameGeometry(); - Widget::setFrameGeometry(normalizedNewGeometry); - - if (normalizedNewGeometry == oldGeometry) - return; - - if (normalizedNewGeometry.width() != oldGeometry.width() || - normalizedNewGeometry.height() != oldGeometry.height()) { - updateScrollbars(m_data->m_scrollOffset); - - // when used to display a popup menu, we do not have a frame - FrameView* frameView = static_cast<FrameView*>(this); - if (frameView->frame()) - frameView->setNeedsLayout(); - } - - geometryChanged(); -} - -int ScrollView::contentsX() const -{ - return scrollOffset().width(); -} - -int ScrollView::contentsY() const -{ - return scrollOffset().height(); -} - -int ScrollView::contentsWidth() const -{ - return m_data->m_contentsSize.width(); -} - -int ScrollView::contentsHeight() const -{ - return m_data->m_contentsSize.height(); -} - -IntPoint ScrollView::windowToContents(const IntPoint& windowPoint) const -{ - IntPoint viewPoint = convertFromContainingWindow(windowPoint); - return viewPoint + scrollOffset(); -} - -IntPoint ScrollView::contentsToWindow(const IntPoint& contentsPoint) const -{ - IntPoint viewPoint = contentsPoint - scrollOffset(); - return convertToContainingWindow(viewPoint); -} - -IntPoint ScrollView::convertChildToSelf(const Widget* child, const IntPoint& point) const -{ - IntPoint newPoint = point; - if (child != m_data->m_hBar && child != m_data->m_vBar) - newPoint = point - scrollOffset(); - return Widget::convertChildToSelf(child, newPoint); -} - -IntPoint ScrollView::convertSelfToChild(const Widget* child, const IntPoint& point) const -{ - IntPoint newPoint = point; - if (child != m_data->m_hBar && child != m_data->m_vBar) - newPoint = point + scrollOffset(); - return Widget::convertSelfToChild(child, newPoint); -} - -IntSize ScrollView::scrollOffset() const -{ - return m_data->m_scrollOffset; -} - -IntSize ScrollView::maximumScroll() const -{ - // We should not check whether scrolling is allowed for this view before calculating - // the maximumScroll. Please refer to http://b/issue?id=1164704, where in scrolling - // would not work on a scrollview created with scrollbars disabled. The current - // behavior mirrors Safari's webkit implementation. Firefox also behaves similarly. - IntSize delta = (m_data->m_contentsSize - IntSize(visibleWidth(), visibleHeight())) - scrollOffset(); - delta.clampNegativeToZero(); - return delta; -} - -void ScrollView::scrollBy(int dx, int dy) -{ - IntSize scrollOffset = m_data->m_scrollOffset; - IntSize newScrollOffset = scrollOffset + IntSize(dx, dy).shrunkTo(maximumScroll()); - newScrollOffset.clampNegativeToZero(); - - if (newScrollOffset == scrollOffset) - return; - - updateScrollbars(newScrollOffset); -} - -void ScrollView::scrollRectIntoViewRecursively(const IntRect& r) -{ - IntPoint p(max(0, r.x()), max(0, r.y())); - ScrollView* view = this; - while (view) { - view->setContentsPos(p.x(), p.y()); - p.move(view->x() - view->scrollOffset().width(), view->y() - view->scrollOffset().height()); - view = static_cast<ScrollView*>(view->parent()); - } -} - -WebCore::ScrollbarMode ScrollView::hScrollbarMode() const -{ - return m_data->m_hScrollbarMode; -} - -WebCore::ScrollbarMode ScrollView::vScrollbarMode() const -{ - return m_data->m_vScrollbarMode; -} - -void ScrollView::suppressScrollbars(bool suppressed, bool repaintOnSuppress) -{ - m_data->m_scrollbarsSuppressed = suppressed; - if (repaintOnSuppress && !suppressed) { - if (m_data->m_hBar) - m_data->m_hBar->invalidate(); - if (m_data->m_vBar) - m_data->m_vBar->invalidate(); - - // Invalidate the scroll corner too on unsuppress. - IntRect hCorner; - if (m_data->m_hBar && width() - m_data->m_hBar->width() > 0) { - hCorner = IntRect(m_data->m_hBar->width(), - height() - m_data->m_hBar->height(), - width() - m_data->m_hBar->width(), - m_data->m_hBar->height()); - invalidateRect(hCorner); - } - - if (m_data->m_vBar && height() - m_data->m_vBar->height() > 0) { - IntRect vCorner(width() - m_data->m_vBar->width(), - m_data->m_vBar->height(), - m_data->m_vBar->width(), - height() - m_data->m_vBar->height()); - if (vCorner != hCorner) - invalidateRect(vCorner); - } - } -} - -void ScrollView::setHScrollbarMode(ScrollbarMode newMode) -{ - if (m_data->m_hScrollbarMode != newMode) { - m_data->m_hScrollbarMode = newMode; - updateScrollbars(m_data->m_scrollOffset); - } -} - -void ScrollView::setVScrollbarMode(ScrollbarMode newMode) -{ - if (m_data->m_vScrollbarMode != newMode) { - m_data->m_vScrollbarMode = newMode; - updateScrollbars(m_data->m_scrollOffset); - } -} - -void ScrollView::setScrollbarsMode(ScrollbarMode newMode) -{ - if (m_data->m_hScrollbarMode != newMode || - m_data->m_vScrollbarMode != newMode) { - m_data->m_hScrollbarMode = m_data->m_vScrollbarMode = newMode; - updateScrollbars(m_data->m_scrollOffset); - } -} - -void ScrollView::setStaticBackground(bool flag) -{ - m_data->m_hasStaticBackground = flag; -} - -void ScrollView::updateScrollbars(const IntSize& desiredOffset) -{ - // Don't allow re-entrancy into this function. - if (m_data->m_inUpdateScrollbars) - return; - - m_data->m_inUpdateScrollbars = true; - - bool hasVerticalScrollbar = m_data->m_vBar; - bool hasHorizontalScrollbar = m_data->m_hBar; - bool oldHasVertical = hasVerticalScrollbar; - bool oldHasHorizontal = hasHorizontalScrollbar; - ScrollbarMode hScroll = m_data->m_hScrollbarMode; - ScrollbarMode vScroll = m_data->m_vScrollbarMode; - - const int cVerticalWidth = PlatformScrollbar::verticalScrollbarWidth(); - const int cHorizontalHeight = PlatformScrollbar::horizontalScrollbarHeight(); - - // we may not be able to support scrollbars due to our frame geometry - if (width() < cVerticalWidth) - vScroll = ScrollbarAlwaysOff; - if (height() < cHorizontalHeight) - hScroll = ScrollbarAlwaysOff; - - for (int pass = 0; pass < 2; pass++) { - bool scrollsVertically; - bool scrollsHorizontally; - - if (!m_data->m_scrollbarsSuppressed && (hScroll == ScrollbarAuto || vScroll == ScrollbarAuto)) { - // Do a layout if pending before checking if scrollbars are needed. - if (hasVerticalScrollbar != oldHasVertical || hasHorizontalScrollbar != oldHasHorizontal) - static_cast<FrameView*>(this)->layout(); - - scrollsVertically = (vScroll == ScrollbarAlwaysOn) || (vScroll == ScrollbarAuto && contentsHeight() > height()); - if (scrollsVertically) - scrollsHorizontally = (hScroll == ScrollbarAlwaysOn) || (hScroll == ScrollbarAuto && contentsWidth() + cVerticalWidth > width()); - else { - scrollsHorizontally = (hScroll == ScrollbarAlwaysOn) || (hScroll == ScrollbarAuto && contentsWidth() > width()); - if (scrollsHorizontally) - scrollsVertically = (vScroll == ScrollbarAlwaysOn) || (vScroll == ScrollbarAuto && contentsHeight() + cHorizontalHeight > height()); - } - } - else { - scrollsHorizontally = (hScroll == ScrollbarAuto) ? hasHorizontalScrollbar : (hScroll == ScrollbarAlwaysOn); - scrollsVertically = (vScroll == ScrollbarAuto) ? hasVerticalScrollbar : (vScroll == ScrollbarAlwaysOn); - } - - if (hasVerticalScrollbar != scrollsVertically) { - m_data->setHasVerticalScrollbar(scrollsVertically); - hasVerticalScrollbar = scrollsVertically; - } - - if (hasHorizontalScrollbar != scrollsHorizontally) { - m_data->setHasHorizontalScrollbar(scrollsHorizontally); - hasHorizontalScrollbar = scrollsHorizontally; - } - } - - // Set up the range (and page step/line step). - IntSize maxScrollPosition(contentsWidth() - visibleWidth(), contentsHeight() - visibleHeight()); - IntSize scroll = desiredOffset.shrunkTo(maxScrollPosition); - scroll.clampNegativeToZero(); - - if (m_data->m_hBar) { - int clientWidth = visibleWidth(); - m_data->m_hBar->setEnabled(contentsWidth() > clientWidth); - int pageStep = (clientWidth - PAGE_KEEP); - if (pageStep < 0) pageStep = clientWidth; - IntRect oldRect(m_data->m_hBar->frameGeometry()); - IntRect hBarRect = IntRect(0, - height() - m_data->m_hBar->height(), - width() - (m_data->m_vBar ? m_data->m_vBar->width() : 0), - m_data->m_hBar->height()); - m_data->m_hBar->setRect(hBarRect); - if (!m_data->m_scrollbarsSuppressed && oldRect != m_data->m_hBar->frameGeometry()) - m_data->m_hBar->invalidate(); - - if (m_data->m_scrollbarsSuppressed) - m_data->m_hBar->setSuppressInvalidation(true); - m_data->m_hBar->setSteps(LINE_STEP, pageStep); - m_data->m_hBar->setProportion(clientWidth, contentsWidth()); - m_data->m_hBar->setValue(scroll.width()); - if (m_data->m_scrollbarsSuppressed) - m_data->m_hBar->setSuppressInvalidation(false); - } - - if (m_data->m_vBar) { - int clientHeight = visibleHeight(); - m_data->m_vBar->setEnabled(contentsHeight() > clientHeight); - int pageStep = (clientHeight - PAGE_KEEP); - if (pageStep < 0) pageStep = clientHeight; - IntRect oldRect(m_data->m_vBar->frameGeometry()); - IntRect vBarRect = IntRect(width() - m_data->m_vBar->width(), - 0, - m_data->m_vBar->width(), - height() - (m_data->m_hBar ? m_data->m_hBar->height() : 0)); - m_data->m_vBar->setRect(vBarRect); - if (!m_data->m_scrollbarsSuppressed && oldRect != m_data->m_vBar->frameGeometry()) - m_data->m_vBar->invalidate(); - - if (m_data->m_scrollbarsSuppressed) - m_data->m_vBar->setSuppressInvalidation(true); - m_data->m_vBar->setSteps(LINE_STEP, pageStep); - m_data->m_vBar->setProportion(clientHeight, contentsHeight()); - m_data->m_vBar->setValue(scroll.height()); - if (m_data->m_scrollbarsSuppressed) - m_data->m_vBar->setSuppressInvalidation(false); - } - - if (oldHasVertical != (m_data->m_vBar != 0) || oldHasHorizontal != (m_data->m_hBar != 0)) - geometryChanged(); - - // See if our offset has changed in a situation where we might not have scrollbars. - // This can happen when editing a body with overflow:hidden and scrolling to reveal selection. - // It can also happen when maximizing a window that has scrollbars (but the new maximized result - // does not). - IntSize scrollDelta = scroll - m_data->m_scrollOffset; - if (scrollDelta != IntSize()) { - m_data->m_scrollOffset = scroll; - m_data->scrollBackingStore(scrollDelta); - - // Inform the delegate that the scroll position has changed. - WidgetClientChromium* c = static_cast<WidgetClientChromium*>(client()); - if (c) - c->onScrollPositionChanged(this); - } - - m_data->m_inUpdateScrollbars = false; - - ASSERT(visibleWidth() >= 0); - ASSERT(visibleHeight() >= 0); -} - -PlatformScrollbar* ScrollView::scrollbarUnderMouse(const PlatformMouseEvent& mouseEvent) -{ - IntPoint viewPoint = convertFromContainingWindow(mouseEvent.pos()); - if (m_data->m_hBar && m_data->m_hBar->frameGeometry().contains(viewPoint)) - return m_data->m_hBar.get(); - if (m_data->m_vBar && m_data->m_vBar->frameGeometry().contains(viewPoint)) - return m_data->m_vBar.get(); - return 0; -} - -void ScrollView::addChild(Widget* child) -{ - child->setParent(this); - - // There is only one global widget client (which should be the WebViewImpl). - // It is responsible for things like capturing the mouse. - child->setClient(client()); - - m_data->m_children.add(child); -} - -void ScrollView::removeChild(Widget* child) -{ - child->setParent(0); - m_data->m_children.remove(child); -} - -void ScrollView::paint(GraphicsContext* context, const IntRect& rect) -{ - // FIXME: This code is here so we don't have to fork FrameView.h/.cpp. - // In the end, FrameView should just merge with ScrollView. - ASSERT(isFrameView()); - - if (context->paintingDisabled()) - return; - - if (Frame* frame = static_cast<FrameView*>(this)->frame()) { - IntRect documentDirtyRect = rect; - documentDirtyRect.intersect(frameGeometry()); - - context->save(); - - context->translate(x(), y()); - documentDirtyRect.move(-x(), -y()); - - context->translate(-contentsX(), -contentsY()); - documentDirtyRect.move(contentsX(), contentsY()); - - // do not allow painting outside of the dirty rect - context->clip(documentDirtyRect); - - frame->paint(context, documentDirtyRect); - - // Highlights the node selected in the DOM inspector. - m_data->highlightInspectedNode(context, frame); - - context->restore(); - } - - // Highlight the matches found on the page, during a FindInPage operation. - m_data->highlightMatches(context); - - // Now paint the scrollbars. - if (!m_data->m_scrollbarsSuppressed && (m_data->m_hBar || m_data->m_vBar)) { - context->save(); - IntRect scrollViewDirtyRect = rect; - scrollViewDirtyRect.intersect(frameGeometry()); - context->translate(x(), y()); - scrollViewDirtyRect.move(-x(), -y()); - if (m_data->m_hBar) - m_data->m_hBar->paint(context, scrollViewDirtyRect); - if (m_data->m_vBar) - m_data->m_vBar->paint(context, scrollViewDirtyRect); - - // Fill the scroll corner with white. - IntRect hCorner; - if (m_data->m_hBar && width() - m_data->m_hBar->width() > 0) { - hCorner = IntRect(m_data->m_hBar->width(), - height() - m_data->m_hBar->height(), - width() - m_data->m_hBar->width(), - m_data->m_hBar->height()); - if (hCorner.intersects(scrollViewDirtyRect)) - context->fillRect(hCorner, Color::white); - } - - if (m_data->m_vBar && height() - m_data->m_vBar->height() > 0) { - IntRect vCorner(width() - m_data->m_vBar->width(), - m_data->m_vBar->height(), - m_data->m_vBar->width(), - height() - m_data->m_vBar->height()); - if (vCorner != hCorner && vCorner.intersects(scrollViewDirtyRect)) - context->fillRect(vCorner, Color::white); - } - - context->restore(); - } -} - -void ScrollView::themeChanged() -{ - PlatformScrollbar::themeChanged(); - theme()->themeChanged(); - invalidate(); -} - -void ScrollView::wheelEvent(PlatformWheelEvent& e) -{ - if (!m_data->allowsScrolling()) - return; - - // Determine how much we want to scroll. If we can move at all, we will accept the event. - IntSize maxScrollDelta = maximumScroll(); - if ((e.deltaX() < 0 && maxScrollDelta.width() > 0) || - (e.deltaX() > 0 && scrollOffset().width() > 0) || - (e.deltaY() < 0 && maxScrollDelta.height() > 0) || - (e.deltaY() > 0 && scrollOffset().height() > 0)) { - e.accept(); - scrollBy(-e.deltaX() * LINE_STEP, -e.deltaY() * LINE_STEP); - } -} - -HashSet<Widget*>* ScrollView::children() -{ - return &(m_data->m_children); -} - -void ScrollView::geometryChanged() const -{ - HashSet<Widget*>::const_iterator end = m_data->m_children.end(); - for (HashSet<Widget*>::const_iterator current = m_data->m_children.begin(); current != end; ++current) - (*current)->geometryChanged(); -} - -bool ScrollView::scroll(ScrollDirection direction, ScrollGranularity granularity) -{ - if (direction == ScrollUp || direction == ScrollDown) { - if (m_data->m_vBar) - return m_data->m_vBar->scroll(direction, granularity); - } else { - if (m_data->m_hBar) - return m_data->m_hBar->scroll(direction, granularity); - } - return false; -} - -IntRect ScrollView::windowResizerRect() -{ - return IntRect(); -} - -bool ScrollView::resizerOverlapsContent() const -{ - return !m_data->m_scrollbarsAvoidingResizer; -} - -void ScrollView::adjustOverlappingScrollbarCount(int overlapDelta) -{ - int oldCount = m_data->m_scrollbarsAvoidingResizer; - m_data->m_scrollbarsAvoidingResizer += overlapDelta; - if (parent() && parent()->isFrameView()) - static_cast<FrameView*>(parent())->adjustOverlappingScrollbarCount(overlapDelta); - else if (!m_data->m_scrollbarsSuppressed) { - // If we went from n to 0 or from 0 to n and we're the outermost view, - // we need to invalidate the windowResizerRect(), since it will now need to paint - // differently. - if (oldCount > 0 && m_data->m_scrollbarsAvoidingResizer == 0 || - oldCount == 0 && m_data->m_scrollbarsAvoidingResizer > 0) - invalidateRect(windowResizerRect()); - } -} - -void ScrollView::setParent(ScrollView* parentView) -{ - if (!parentView && m_data->m_scrollbarsAvoidingResizer && parent() && parent()->isFrameView()) - static_cast<FrameView*>(parent())->adjustOverlappingScrollbarCount(false); - Widget::setParent(parentView); -} - -void ScrollView::addToDirtyRegion(const IntRect& containingWindowRect) -{ - WidgetClientChromium* c = static_cast<WidgetClientChromium*>(client()); - if (c) - c->invalidateRect(containingWindowRect); -} - -void ScrollView::scrollBackingStore(int dx, int dy, const IntRect& scrollViewRect, const IntRect& clipRect) -{ - // We don't know how to scroll in two directions at once. - if (dx && dy) { - IntRect updateRect = clipRect; - updateRect.intersect(scrollViewRect); - addToDirtyRegion(updateRect); - return; - } - - WidgetClientChromium* c = static_cast<WidgetClientChromium*>(client()); - if (c) { - // TODO(ericroman): would be better to pass both the scroll rect - // and clip rect up to the client and let them decide how best to - // scroll the backing store. - IntRect clippedScrollRect = scrollViewRect; - clippedScrollRect.intersect(clipRect); - c->scrollRect(dx, dy, clippedScrollRect); - } -} - -void ScrollView::updateBackingStore() -{ - // nothing to do. painting happens asynchronously. -} - -bool ScrollView::inWindow() const -{ - WidgetClientChromium* c = static_cast<WidgetClientChromium*>(client()); - if (!c) - return false; - - return !c->isHidden(); -} - -void ScrollView::attachToWindow() -{ - if (m_data->m_attachedToWindow) - return; - - m_data->m_attachedToWindow = true; - - if (m_data->m_visible) { - HashSet<Widget*>::iterator end = m_data->m_children.end(); - for (HashSet<Widget*>::iterator it = m_data->m_children.begin(); it != end; ++it) - (*it)->attachToWindow(); - } -} - -void ScrollView::detachFromWindow() -{ - if (!m_data->m_attachedToWindow) - return; - - if (m_data->m_visible) { - HashSet<Widget*>::iterator end = m_data->m_children.end(); - for (HashSet<Widget*>::iterator it = m_data->m_children.begin(); it != end; ++it) - (*it)->detachFromWindow(); - } - - m_data->m_attachedToWindow = false; -} - -void ScrollView::show() -{ - if (!m_data->m_visible) { - m_data->m_visible = true; - if (isAttachedToWindow()) { - HashSet<Widget*>::iterator end = m_data->m_children.end(); - for (HashSet<Widget*>::iterator it = m_data->m_children.begin(); it != end; ++it) - (*it)->attachToWindow(); - } - } - - Widget::show(); -} - -void ScrollView::hide() -{ - if (m_data->m_visible) { - if (isAttachedToWindow()) { - HashSet<Widget*>::iterator end = m_data->m_children.end(); - for (HashSet<Widget*>::iterator it = m_data->m_children.begin(); it != end; ++it) - (*it)->detachFromWindow(); - } - m_data->m_visible = false; - } - - Widget::hide(); -} - -bool ScrollView::isAttachedToWindow() const -{ - return m_data->m_attachedToWindow; -} - -void ScrollView::setAllowsScrolling(bool flag) -{ - m_data->setAllowsScrolling(flag); -} - -bool ScrollView::allowsScrolling() const -{ - return m_data->allowsScrolling(); -} - -void ScrollView::printPanScrollIcon(const IntPoint& iconPosition) -{ - m_data->m_drawPanScrollIcon = true; - m_data->m_panScrollIconPoint = IntPoint(iconPosition.x() - panIconSizeLength / 2 , iconPosition.y() - panIconSizeLength / 2) ; - - updateWindowRect(IntRect(m_data->m_panScrollIconPoint, IntSize(panIconSizeLength,panIconSizeLength)), true); -} - -void ScrollView::removePanScrollIcon() -{ - m_data->m_drawPanScrollIcon = false; - - updateWindowRect(IntRect(m_data->m_panScrollIconPoint, IntSize(panIconSizeLength, panIconSizeLength)), true); -} - -bool ScrollView::isScrollable() -{ - return m_data->m_vBar != 0 || m_data->m_hBar != 0; -} - -} // namespace WebCore diff --git a/webkit/port/platform/chromium/ScrollbarThemeChromiumWin.cpp b/webkit/port/platform/chromium/ScrollbarThemeChromiumWin.cpp new file mode 100644 index 0000000..e887d59 --- /dev/null +++ b/webkit/port/platform/chromium/ScrollbarThemeChromiumWin.cpp @@ -0,0 +1,361 @@ +/* + * Copyright (C) 2008 Apple 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: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 APPLE INC. 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 "ScrollbarThemeChromiumWin.h" + +#include <windows.h> +#include <vsstyle.h> + +#include "GraphicsContext.h" +#include "PlatformContextSkia.h" +#include "PlatformMouseEvent.h" +#include "Scrollbar.h" + +#include "base/gfx/native_theme.h" +#include "base/win_util.h" +#include "webkit/glue/webkit_glue.h" + +namespace WebCore { + +// The scrollbar size in DumpRenderTree on the Mac - so we can match their +// layout results. Entries are for regular, small, and mini scrollbars. +// Metrics obtained using [NSScroller scrollerWidthForControlSize:] +static const int kMacScrollbarSize[3] = { 15, 11, 15 }; + +static bool runningVista() +{ + return win_util::GetWinVersion() >= win_util::WINVERSION_VISTA; +} + +static RECT toRECT(const IntRect& input) +{ + RECT output; + output.left = input.x(); + output.right = input.right(); + output.top = input.y(); + output.bottom = input.bottom(); + return output; +} + +ScrollbarTheme* ScrollbarTheme::nativeTheme() +{ + static ScrollbarThemeChromiumWin theme; + return &theme; +} + +ScrollbarThemeChromiumWin::ScrollbarThemeChromiumWin() +{ +} + +ScrollbarThemeChromiumWin::~ScrollbarThemeChromiumWin() +{ +} + +int ScrollbarThemeChromiumWin::scrollbarThickness(ScrollbarControlSize controlSize) +{ + static int thickness; + if (!thickness) { + if (webkit_glue::IsLayoutTestMode()) + return kMacScrollbarSize[controlSize]; + thickness = GetSystemMetrics(SM_CXVSCROLL); + } + return thickness; +} + +void ScrollbarThemeChromiumWin::themeChanged() +{ +} + +bool ScrollbarThemeChromiumWin::invalidateOnMouseEnterExit() +{ + return runningVista(); +} + +bool ScrollbarThemeChromiumWin::hasThumb(Scrollbar* scrollbar) +{ + // This method is just called as a paint-time optimization to see if + // painting the thumb can be skipped. We don't have to be exact here. + return thumbLength(scrollbar) > 0; +} + +IntRect ScrollbarThemeChromiumWin::backButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool) +{ + // Windows just has single arrows. + if (part == BackButtonEndPart) + return IntRect(); + + IntSize size = buttonSize(scrollbar); + return IntRect(scrollbar->x(), scrollbar->y(), size.width(), size.height()); +} + +IntRect ScrollbarThemeChromiumWin::forwardButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool) +{ + // Windows just has single arrows. + if (part == ForwardButtonStartPart) + return IntRect(); + + IntSize size = buttonSize(scrollbar); + int x, y; + if (scrollbar->orientation() == HorizontalScrollbar) { + x = scrollbar->x() + scrollbar->width() - size.width(); + y = scrollbar->y(); + } else { + x = scrollbar->x(); + y = scrollbar->y() + scrollbar->height() - size.height(); + } + return IntRect(x, y, size.width(), size.height()); +} + +IntRect ScrollbarThemeChromiumWin::trackRect(Scrollbar* scrollbar, bool) +{ + IntSize bs = buttonSize(scrollbar); + int thickness = scrollbarThickness(); + if (scrollbar->orientation() == HorizontalScrollbar) { + if (scrollbar->width() < 2 * thickness) + return IntRect(); + return IntRect(scrollbar->x() + bs.width(), scrollbar->y(), scrollbar->width() - 2 * bs.width(), thickness); + } + if (scrollbar->height() < 2 * thickness) + return IntRect(); + return IntRect(scrollbar->x(), scrollbar->y() + bs.height(), thickness, scrollbar->height() - 2 * bs.height()); +} + +void ScrollbarThemeChromiumWin::paintTrackBackground(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect) +{ + // Just assume a forward track part. We only paint the track as a single piece when there is no thumb. + if (!hasThumb(scrollbar)) + paintTrackPiece(context, scrollbar, rect, ForwardTrackPart); +} + +void ScrollbarThemeChromiumWin::paintTrackPiece(GraphicsContext* gc, Scrollbar* scrollbar, const IntRect& rect, ScrollbarPart partType) +{ + bool horz = scrollbar->orientation() == HorizontalScrollbar; + + gfx::PlatformCanvasWin* canvas = gc->platformContext()->canvas(); + HDC hdc = canvas->beginPlatformPaint(); + + RECT paintRect = toRECT(rect); + + int partId; + if (partType == BackTrackPart) { + partId = horz ? SBP_UPPERTRACKHORZ : SBP_UPPERTRACKVERT; + } else { + partId = horz ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT; + } + + RECT alignRect = toRECT(trackRect(scrollbar, false)); + + // Draw the track area before/after the thumb on the scroll bar. + gfx::NativeTheme::instance()->PaintScrollbarTrack( + hdc, + partId, + getThemeState(scrollbar, partType), + getClassicThemeState(scrollbar, partType), + &paintRect, + &alignRect, + gc->platformContext()->canvas()); + + canvas->endPlatformPaint(); +} + +void ScrollbarThemeChromiumWin::paintButton(GraphicsContext* gc, Scrollbar* scrollbar, const IntRect& rect, ScrollbarPart part) +{ + bool horz = scrollbar->orientation() == HorizontalScrollbar; + + gfx::PlatformCanvasWin* canvas = gc->platformContext()->canvas(); + HDC hdc = canvas->beginPlatformPaint(); + + RECT paintRect = toRECT(rect); + + int partId; + if (part == BackButtonStartPart || part == ForwardButtonStartPart) { + partId = horz ? DFCS_SCROLLLEFT : DFCS_SCROLLUP; + } else { + partId = horz ? DFCS_SCROLLRIGHT : DFCS_SCROLLDOWN; + } + + // Draw the thumb (the box you drag in the scroll bar to scroll). + gfx::NativeTheme::instance()->PaintScrollbarArrow( + hdc, + getThemeArrowState(scrollbar, part), + partId | getClassicThemeState(scrollbar, part), + &paintRect); + + canvas->endPlatformPaint(); +} + +void ScrollbarThemeChromiumWin::paintThumb(GraphicsContext* gc, Scrollbar* scrollbar, const IntRect& rect) +{ + bool horz = scrollbar->orientation() == HorizontalScrollbar; + + gfx::PlatformCanvasWin* canvas = gc->platformContext()->canvas(); + HDC hdc = canvas->beginPlatformPaint(); + + RECT paintRect = toRECT(rect); + + // Draw the thumb (the box you drag in the scroll bar to scroll). + gfx::NativeTheme::instance()->PaintScrollbarThumb( + hdc, + horz ? SBP_THUMBBTNHORZ : SBP_THUMBBTNVERT, + getThemeState(scrollbar, ThumbPart), + getClassicThemeState(scrollbar, ThumbPart), + &paintRect); + + // Draw the gripper (the three little lines on the thumb). + gfx::NativeTheme::instance()->PaintScrollbarThumb( + hdc, + horz ? SBP_GRIPPERHORZ : SBP_GRIPPERVERT, + getThemeState(scrollbar, ThumbPart), + getClassicThemeState(scrollbar, ThumbPart), + &paintRect); + + canvas->endPlatformPaint(); +} + +void ScrollbarThemeChromiumWin::paintScrollCorner(ScrollView* view, GraphicsContext* context, const IntRect& cornerRect) +{ + // ScrollbarThemeComposite::paintScrollCorner incorrectly assumes that the + // ScrollView is a FrameView (see FramelessScrollView), so we cannot let + // that code run. For FrameView's this is correct since we don't do custom + // scrollbar corner rendering, which ScrollbarThemeComposite supports. + ScrollbarTheme::paintScrollCorner(view, context, cornerRect); +} + +bool ScrollbarThemeChromiumWin::shouldCenterOnThumb(Scrollbar*, const PlatformMouseEvent& evt) +{ + return evt.shiftKey() && evt.button() == LeftButton; +} + +IntSize ScrollbarThemeChromiumWin::buttonSize(Scrollbar* scrollbar) +{ + // Our desired rect is essentially thickness by thickness. + + // Our actual rect will shrink to half the available space when we have < 2 + // times thickness pixels left. This allows the scrollbar to scale down + // and function even at tiny sizes. + + // In layout test mode, we force the button "girth" (i.e., the length of + // the button along the axis of the scrollbar) to be a fixed size. + // FIXME: This is retarded! scrollbarThickness is already fixed in layout + // test mode so that should be enough to result in repeatable results, but + // preserving this hack avoids having to rebaseline pixel tests. + const int kLayoutTestModeGirth = 17; + + int thickness = scrollbarThickness(); + int girth = webkit_glue::IsLayoutTestMode() ? kLayoutTestModeGirth : thickness; + if (scrollbar->orientation() == HorizontalScrollbar) { + int width = scrollbar->width() < 2 * girth ? scrollbar->width() / 2 : girth; + return IntSize(width, thickness); + } + + int height = scrollbar->height() < 2 * girth ? scrollbar->height() / 2 : girth; + return IntSize(thickness, height); +} + +int ScrollbarThemeChromiumWin::getThemeState(Scrollbar* scrollbar, ScrollbarPart part) const +{ + // When dragging the thumb, draw thumb pressed and other segments normal + // regardless of where the cursor actually is. See also four places in + // getThemeArrowState(). + if (scrollbar->pressedPart() == ThumbPart) { + if (part == ThumbPart) + return SCRBS_PRESSED; + return runningVista() ? SCRBS_HOVER : SCRBS_NORMAL; + } + if (!scrollbar->enabled()) + return SCRBS_DISABLED; + if (scrollbar->hoveredPart() != part || part == BackTrackPart || part == ForwardTrackPart) + return (scrollbar->hoveredPart() == NoPart || !runningVista()) ? SCRBS_NORMAL : SCRBS_HOVER; + if (scrollbar->pressedPart() == NoPart) + return SCRBS_HOT; + return (scrollbar->pressedPart() == part) ? SCRBS_PRESSED : SCRBS_NORMAL; +} + +int ScrollbarThemeChromiumWin::getThemeArrowState(Scrollbar* scrollbar, ScrollbarPart part) const +{ + // We could take advantage of knowing the values in the state enum to write + // some simpler code, but treating the state enum as a black box seems + // clearer and more future-proof. + if (part == BackButtonStartPart || part == ForwardButtonStartPart) { + if (scrollbar->orientation() == HorizontalScrollbar) { + if (scrollbar->pressedPart() == ThumbPart) + return !runningVista() ? ABS_LEFTNORMAL : ABS_LEFTHOVER; + if (!scrollbar->enabled()) + return ABS_LEFTDISABLED; + if (scrollbar->hoveredPart() != part) + return ((scrollbar->hoveredPart() == NoPart) || !runningVista()) ? ABS_LEFTNORMAL : ABS_LEFTHOVER; + if (scrollbar->pressedPart() == NoPart) + return ABS_LEFTHOT; + return (scrollbar->pressedPart() == part) ? + ABS_LEFTPRESSED : ABS_LEFTNORMAL; + } + if (scrollbar->pressedPart() == ThumbPart) + return !runningVista() ? ABS_UPNORMAL : ABS_UPHOVER; + if (!scrollbar->enabled()) + return ABS_UPDISABLED; + if (scrollbar->hoveredPart() != part) + return ((scrollbar->hoveredPart() == NoPart) || !runningVista()) ? ABS_UPNORMAL : ABS_UPHOVER; + if (scrollbar->pressedPart() == NoPart) + return ABS_UPHOT; + return (scrollbar->pressedPart() == part) ? ABS_UPPRESSED : ABS_UPNORMAL; + } + if (scrollbar->orientation() == HorizontalScrollbar) { + if (scrollbar->pressedPart() == ThumbPart) + return !runningVista() ? ABS_RIGHTNORMAL : ABS_RIGHTHOVER; + if (!scrollbar->enabled()) + return ABS_RIGHTDISABLED; + if (scrollbar->hoveredPart() != part) + return ((scrollbar->hoveredPart() == NoPart) || !runningVista()) ? ABS_RIGHTNORMAL : ABS_RIGHTHOVER; + if (scrollbar->pressedPart() == NoPart) + return ABS_RIGHTHOT; + return (scrollbar->pressedPart() == part) ? ABS_RIGHTPRESSED : ABS_RIGHTNORMAL; + } + if (scrollbar->pressedPart() == ThumbPart) + return !runningVista() ? ABS_DOWNNORMAL : ABS_DOWNHOVER; + if (!scrollbar->enabled()) + return ABS_DOWNDISABLED; + if (scrollbar->hoveredPart() != part) + return ((scrollbar->hoveredPart() == NoPart) || !runningVista()) ? ABS_DOWNNORMAL : ABS_DOWNHOVER; + if (scrollbar->pressedPart() == NoPart) + return ABS_DOWNHOT; + return (scrollbar->pressedPart() == part) ? ABS_DOWNPRESSED : ABS_DOWNNORMAL; +} + +int ScrollbarThemeChromiumWin::getClassicThemeState(Scrollbar* scrollbar, ScrollbarPart part) const +{ + // When dragging the thumb, draw the buttons normal even when hovered. + if (scrollbar->pressedPart() == ThumbPart) + return 0; + if (!scrollbar->enabled()) + return DFCS_INACTIVE; + if (scrollbar->hoveredPart() != part || part == BackTrackPart || part == ForwardTrackPart) + return 0; + if (scrollbar->pressedPart() == NoPart) + return DFCS_HOT; + return (scrollbar->pressedPart() == part) ? (DFCS_PUSHED | DFCS_FLAT) : 0; +} + +} diff --git a/webkit/port/platform/chromium/ScrollbarThemeChromiumWin.h b/webkit/port/platform/chromium/ScrollbarThemeChromiumWin.h new file mode 100644 index 0000000..5f694da --- /dev/null +++ b/webkit/port/platform/chromium/ScrollbarThemeChromiumWin.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2008 Apple 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: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 APPLE INC. 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 ScrollbarThemeChromiumWin_h +#define ScrollbarThemeChromiumWin_h + +#include "ScrollbarThemeComposite.h" + +namespace WebCore { + +class ScrollbarThemeChromiumWin : public ScrollbarThemeComposite { +public: + ScrollbarThemeChromiumWin(); + virtual ~ScrollbarThemeChromiumWin(); + + virtual int scrollbarThickness(ScrollbarControlSize = RegularScrollbar); + + virtual void themeChanged(); + + virtual bool invalidateOnMouseEnterExit(); + +protected: + virtual bool hasButtons(Scrollbar*) { return true; } + virtual bool hasThumb(Scrollbar*); + + virtual IntRect backButtonRect(Scrollbar*, ScrollbarPart, bool painting = false); + virtual IntRect forwardButtonRect(Scrollbar*, ScrollbarPart, bool painting = false); + virtual IntRect trackRect(Scrollbar*, bool painting = false); + + virtual void paintScrollCorner(ScrollView*, GraphicsContext*, const IntRect&); + virtual bool shouldCenterOnThumb(Scrollbar*, const PlatformMouseEvent&); + + virtual void paintTrackBackground(GraphicsContext*, Scrollbar*, const IntRect&); + virtual void paintTrackPiece(GraphicsContext*, Scrollbar*, const IntRect&, ScrollbarPart); + virtual void paintButton(GraphicsContext*, Scrollbar*, const IntRect&, ScrollbarPart); + virtual void paintThumb(GraphicsContext*, Scrollbar*, const IntRect&); + +private: + IntSize buttonSize(Scrollbar*); + int getThemeState(Scrollbar*, ScrollbarPart) const; + int getThemeArrowState(Scrollbar*, ScrollbarPart) const; + int getClassicThemeState(Scrollbar*, ScrollbarPart) const; +}; + +} +#endif diff --git a/webkit/port/platform/chromium/TemporaryLinkStubs.cpp b/webkit/port/platform/chromium/TemporaryLinkStubs.cpp index 25a4494..11f9459 100644 --- a/webkit/port/platform/chromium/TemporaryLinkStubs.cpp +++ b/webkit/port/platform/chromium/TemporaryLinkStubs.cpp @@ -36,8 +36,8 @@ MSVC_PUSH_WARNING_LEVEL(0); MSVC_POP_WARNING(); using namespace WebCore; - String WebCore::signedPublicKeyAndChallengeString(unsigned, const String&, const KURL&) { notImplemented(); return String(); } +void WebCore::getSupportedKeySizes(Vector<String>&) { notImplemented(); } String KURL::fileSystemPath() const { notImplemented(); return String(); } diff --git a/webkit/port/platform/chromium/WidgetChromium.cpp b/webkit/port/platform/chromium/WidgetChromium.cpp index a36cb2c..9b84698 100644 --- a/webkit/port/platform/chromium/WidgetChromium.cpp +++ b/webkit/port/platform/chromium/WidgetChromium.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,93 +26,41 @@ #include "config.h" #include "Widget.h" -#include "Cursor.h" -#include "Document.h" -#include "Element.h" +#include "Assertions.h" +#include "ChromeClientChromium.h" #include "Frame.h" #include "FrameView.h" -#include "GraphicsContext.h" -#include "IntRect.h" -#include "WidgetClientChromium.h" +#include "Page.h" +#include "NotImplemented.h" namespace WebCore { -class WidgetPrivate +ChromeClientChromium* chromeClientChromium(Widget* widget) { -public: - WidgetClientChromium* client; - ScrollView* parent; - IntRect frameRect; - bool enabled; - bool suppressInvalidation; -}; - -Widget::Widget() - : data(new WidgetPrivate) -{ - data->client = 0; - data->parent = 0; - data->enabled = true; - data->suppressInvalidation = false; -} - -Widget::~Widget() -{ - if (parent()) - parent()->removeChild(this); - delete data; -} - -void Widget::setContainingWindow(PlatformWidget containingWindow) -{ - ASSERT_NOT_REACHED(); -} - -PlatformWidget Widget::containingWindow() const -{ - if (!data->client) - return NULL; - return data->client->containingWindow(); -} - -void Widget::setClient(WidgetClient* c) -{ - data->client = static_cast<WidgetClientChromium*>(c); -} - -WidgetClient* Widget::client() const -{ - return data->client; -} + FrameView* view; + if (widget->isFrameView()) { + view = static_cast<FrameView*>(widget); + } else if (widget->parent() && widget->parent()->isFrameView()) { + view = static_cast<FrameView*>(widget->parent()); + } else { + return 0; + } -IntRect Widget::frameGeometry() const -{ - return data->frameRect; -} + Page* page = view->frame() ? view->frame()->page() : 0; + if (!page) + return 0; -void Widget::setFrameGeometry(const IntRect &rect) -{ - data->frameRect = rect; + return static_cast<ChromeClientChromium*>(page->chrome()->client()); } -void Widget::setParent(ScrollView* v) +Widget::Widget(PlatformWidget widget) { - if (!v || !v->isAttachedToWindow()) - detachFromWindow(); - data->parent = v; - if (v && v->isAttachedToWindow()) - attachToWindow(); + init(widget); } -ScrollView* Widget::parent() const -{ - return data->parent; -} - -void Widget::removeFromParent() +Widget::~Widget() { - if (parent()) - parent()->removeChild(this); + ASSERT(!parent()); } void Widget::show() @@ -125,104 +73,34 @@ void Widget::hide() void Widget::setCursor(const Cursor& cursor) { - if (data->client) - data->client->setCursor(cursor); -} - -IntPoint Widget::convertToContainingWindow(const IntPoint& point) const -{ - IntPoint windowPoint = point; - for (const Widget *parentWidget = parent(), *childWidget = this; - parentWidget; - childWidget = parentWidget, parentWidget = parentWidget->parent()) - windowPoint = parentWidget->convertChildToSelf(childWidget, windowPoint); - return windowPoint; -} - -IntPoint Widget::convertFromContainingWindow(const IntPoint& point) const -{ - IntPoint widgetPoint = point; - for (const Widget *parentWidget = parent(), *childWidget = this; - parentWidget; - childWidget = parentWidget, parentWidget = parentWidget->parent()) - widgetPoint = parentWidget->convertSelfToChild(childWidget, widgetPoint); - return widgetPoint; -} - -IntRect Widget::convertToContainingWindow(const IntRect& rect) const -{ - IntRect convertedRect = rect; - convertedRect.setLocation(convertToContainingWindow(convertedRect.location())); - return convertedRect; -} - -IntPoint Widget::convertChildToSelf(const Widget* child, const IntPoint& point) const -{ - return IntPoint(point.x() + child->x(), point.y() + child->y()); -} - -IntPoint Widget::convertSelfToChild(const Widget* child, const IntPoint& point) const -{ - return IntPoint(point.x() - child->x(), point.y() - child->y()); + ChromeClientChromium* client = chromeClientChromium(this); + if (client) + client->setCursor(cursor); } void Widget::paint(GraphicsContext*, const IntRect&) { } -bool Widget::isEnabled() const -{ - return data->enabled; -} - -void Widget::setEnabled(bool e) -{ - if (e != data->enabled) { - data->enabled = e; - invalidate(); - } -} - -bool Widget::suppressInvalidation() const -{ - return data->suppressInvalidation; -} - -void Widget::setSuppressInvalidation(bool suppress) -{ - data->suppressInvalidation = suppress; -} - -void Widget::invalidate() +void Widget::setFocus() { - invalidateRect(IntRect(0, 0, width(), height())); + ChromeClientChromium* client = chromeClientChromium(this); + if (client) + client->focus(); } -void Widget::invalidateRect(const IntRect& r) +void Widget::setIsSelected(bool) { - if (data->suppressInvalidation) - return; - - if (!data->client) - return; - - IntRect windowRect = convertToContainingWindow(r); - - // Get our clip rect and intersect with it to ensure we don't invalidate too much. - IntRect clipRect = windowClipRect(); - windowRect.intersect(clipRect); - - data->client->invalidateRect(windowRect); } -void Widget::setFocus() +IntRect Widget::frameRect() const { - if (data->client) - data->client->setFocus(); + return m_frame; } -void Widget::setIsSelected(bool) +void Widget::setFrameRect(const IntRect& rect) { + m_frame = rect; } } // namespace WebCore diff --git a/webkit/port/platform/chromium/WidgetClientChromium.h b/webkit/port/platform/chromium/WidgetClientChromium.h deleted file mode 100644 index f39c49b..0000000 --- a/webkit/port/platform/chromium/WidgetClientChromium.h +++ /dev/null @@ -1,75 +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 WidgetClientChromium_H__ -#define WidgetClientChromium_H__ - -#include "base/gfx/native_widget_types.h" -#include "WidgetClient.h" - -class SkBitmap; - -namespace WebCore { - -class Cursor; -class IntRect; -class Range; - -// Generic interface for features needed by the Widget. -class WidgetClientChromium : public WidgetClient { -public: - virtual ~WidgetClientChromium() {} - - // Returns the containing window for the Widget. - // TODO(pinkerton): this needs a better name, "window" is incorrect on other - // platforms. - virtual gfx::ViewHandle containingWindow() = 0; - - // Invalidate a region of the widget's containing window. - virtual void invalidateRect(const IntRect& damagedRect) = 0; - - // Scroll the region of the widget's containing window within the given - // clipRect by the specified dx and dy. - virtual void scrollRect(int dx, int dy, const IntRect& clipRect) = 0; - - // Notifies the client of a new popup widget. The client should place - // and size the widget with the given bounds, relative to the screen. - virtual void popupOpened(Widget* widget, const IntRect& bounds) = 0; - - // Notifies the client that the given popup widget has closed. - virtual void popupClosed(Widget* widget) = 0; - - // Indicates that a new cursor should be shown. - virtual void setCursor(const Cursor& cursor) = 0; - - // Indicates the widget thinks it has focus. This should give focus to the - // window hosting the widget. - virtual void setFocus() = 0; - - // This function is called to retrieve a resource bitmap from the - // renderer that was cached as a result of the renderer receiving a - // ViewMsg_Preload_Bitmap message from the browser. - virtual const SkBitmap* getPreloadedResourceBitmap(int resource_id) = 0; - - // Notification that the given widget's scroll position has changed. This - // function is called AFTER the position has been updated. - virtual void onScrollPositionChanged(Widget* widget) = 0; - - // Retrieves the tick-marks for a given frame. - virtual const WTF::Vector<RefPtr<WebCore::Range> >* getTickmarks( - WebCore::Frame* frame) = 0; - - // Retrieves the index of the active tickmark for a given frame. If the - // frame does not have an active tickmark (for example if the active - // tickmark resides in another frame) this function returns kNoTickmark. - static const size_t kNoTickmark = -1; - virtual size_t getActiveTickmarkIndex(WebCore::Frame* frame) = 0; - - // Returns true if this widget is hidden because it's in a background tab. - virtual bool isHidden() = 0; -}; - -} // namespace WebCore - -#endif // WidgetClientChromium_H__ diff --git a/webkit/port/platform/graphics/GraphicsContextSkia.cpp b/webkit/port/platform/graphics/GraphicsContextSkia.cpp index 1dd027a..e98dbf8 100644 --- a/webkit/port/platform/graphics/GraphicsContextSkia.cpp +++ b/webkit/port/platform/graphics/GraphicsContextSkia.cpp @@ -936,6 +936,27 @@ void GraphicsContext::setLineCap(LineCap cap) } } +void GraphicsContext::setLineDash(const DashArray& dashes, float dashOffset) +{ + // TODO(dglazkov): This is lifted directly off SkiaSupport, lines 49-74 + // so it is not guaranteed to work correctly. I made some minor cosmetic + // refactoring, but not much else. Please fix this? + size_t dashLength = dashes.size(); + if (!dashLength) + return; + + size_t count = (dashLength % 2) == 0 ? dashLength : dashLength * 2; + SkScalar* intervals = new SkScalar[count]; + + for(unsigned int i = 0; i < count; i++) + intervals[i] = dashes[i % dashLength]; + + m_data->setDashPathEffect(new SkDashPathEffect(intervals, + count, dashOffset)); + + delete[] intervals; +} + void GraphicsContext::setLineJoin(LineJoin join) { switch (join) { @@ -1096,22 +1117,4 @@ void GraphicsContext::setImageInterpolationQuality(InterpolationQuality) notImplemented(); } -// Skia platform gradients and patterns are handled at draw time -// Upstream is considering removing these methods anyway -void GraphicsContext::setPlatformStrokePattern(Pattern* pattern) -{ -} - -void GraphicsContext::setPlatformFillPattern(Pattern* pattern) -{ -} - -void GraphicsContext::setPlatformStrokeGradient(Gradient*) -{ -} - -void GraphicsContext::setPlatformFillGradient(Gradient*) -{ -} - } diff --git a/webkit/port/platform/graphics/ImageSkia.cpp b/webkit/port/platform/graphics/ImageSkia.cpp index 5e9d518..5cf364d 100644 --- a/webkit/port/platform/graphics/ImageSkia.cpp +++ b/webkit/port/platform/graphics/ImageSkia.cpp @@ -38,8 +38,8 @@ #include "Logging.h" #include "NativeImageSkia.h" #include "NotImplemented.h" -#include "PlatformScrollBar.h" #include "PlatformString.h" +#include "ScrollbarTheme.h" #include "SkiaUtils.h" #include "SkShader.h" @@ -93,20 +93,19 @@ void TransformDimensions(const SkMatrix& matrix, static PassRefPtr<Image> GetTextAreaResizeCorner() { // Get the size of the resizer. - const int width = PlatformScrollbar::verticalScrollbarWidth(); - const int height = PlatformScrollbar::horizontalScrollbarHeight(); + const int thickness = ScrollbarTheme::nativeTheme()->scrollbarThickness(); // Setup a memory buffer. - gfx::PlatformCanvasWin canvas(width, height, false); + gfx::PlatformCanvasWin canvas(thickness, thickness, false); gfx::PlatformDeviceWin& device = canvas.getTopPlatformDevice(); - device.prepareForGDI(0, 0, width, height); + device.prepareForGDI(0, 0, thickness, thickness); HDC hdc = device.getBitmapDC(); - RECT widgetRect = { 0, 0, width, height }; + RECT widgetRect = { 0, 0, thickness, thickness }; // Do the drawing. gfx::NativeTheme::instance()->PaintStatusGripper(hdc, SP_GRIPPER, 0, 0, &widgetRect); - device.postProcessGDI(0, 0, width, height); + device.postProcessGDI(0, 0, thickness, thickness); return BitmapImageSingleFrameSkia::create(device.accessBitmap(false)); } #endif diff --git a/webkit/port/platform/graphics/PlatformContextSkia.h b/webkit/port/platform/graphics/PlatformContextSkia.h index 67ab1f1f..c2aee46 100644 --- a/webkit/port/platform/graphics/PlatformContextSkia.h +++ b/webkit/port/platform/graphics/PlatformContextSkia.h @@ -10,7 +10,6 @@ namespace WebCore { class GraphicsContext; class GraphicsContextPlatformPrivate; -class PlatformScrollbar; class ScrollView; } diff --git a/webkit/port/platform/graphics/SkPaintContext.cpp b/webkit/port/platform/graphics/SkPaintContext.cpp index 863aaa0..53b165e 100644 --- a/webkit/port/platform/graphics/SkPaintContext.cpp +++ b/webkit/port/platform/graphics/SkPaintContext.cpp @@ -209,7 +209,7 @@ void SkPaintContext::setup_paint_fill(SkPaint* paint) const { int SkPaintContext::setup_paint_stroke(SkPaint* paint, SkRect* rect, - int length) { + int length) const { setup_paint_common(paint); float width = state_->mStrokeThickness; @@ -313,7 +313,7 @@ void SkPaintContext::addPath(const SkPath& path) { path_.addPath(path); } -SkPath* SkPaintContext::currentPath() { +const SkPath* SkPaintContext::currentPath() const { return &path_; } diff --git a/webkit/port/platform/graphics/SkPaintContext.h b/webkit/port/platform/graphics/SkPaintContext.h index 0d7aaae..b14d5f2 100644 --- a/webkit/port/platform/graphics/SkPaintContext.h +++ b/webkit/port/platform/graphics/SkPaintContext.h @@ -51,7 +51,7 @@ class SkPaintContext { // the pen, or 1 if the pen's width is 0 if a non-zero length is provided, // the number of dashes/dots on a dashed/dotted line will be adjusted to // start and end that length with a dash/dot. - int setup_paint_stroke(SkPaint* paint, SkRect* rect, int length); + int setup_paint_stroke(SkPaint* paint, SkRect* rect, int length) const; // State proxying functions SkDrawLooper* setDrawLooper(SkDrawLooper* dl); @@ -69,7 +69,7 @@ class SkPaintContext { void beginPath(); void addPath(const SkPath& path); - SkPath* currentPath(); + const SkPath* currentPath() const; void setGradient(SkShader*); void setPattern(SkShader*); diff --git a/webkit/port/platform/win/ScreenWin.cpp b/webkit/port/platform/win/PlatformScreenWin.cpp index d69888a..1c529d8 100644 --- a/webkit/port/platform/win/ScreenWin.cpp +++ b/webkit/port/platform/win/PlatformScreenWin.cpp @@ -24,7 +24,7 @@ */ #include "config.h" -#include "Screen.h" +#include "PlatformScreen.h" #include "IntRect.h" #include "FloatRect.h" @@ -44,7 +44,8 @@ static FloatRect ToFloatRect(const RECT& rect) { // Returns info for the default monitor if widget is NULL static MONITORINFOEX monitorInfoForWidget(Widget* widget) { - HWND window = widget ? widget->containingWindow() : 0; + // TODO(darin): We should not be dealing with native widgets here! + HWND window = widget ? widget->root()->hostWindow()->platformWindow() : 0; return webkit_glue::GetMonitorInfoForWindow(window); } diff --git a/webkit/port/rendering/RenderThemeWin.cpp b/webkit/port/rendering/RenderThemeWin.cpp index c302118..859df7d 100644 --- a/webkit/port/rendering/RenderThemeWin.cpp +++ b/webkit/port/rendering/RenderThemeWin.cpp @@ -31,7 +31,7 @@ #include "Document.h" #include "FontSelector.h" #include "GraphicsContext.h" -#include "PlatformScrollBar.h" +#include "ScrollbarTheme.h" #include "SkiaUtils.h" #include "base/gfx/native_theme.h" @@ -706,7 +706,7 @@ int RenderThemeWin::menuListInternalPadding(RenderStyle* style, int paddingType) // we don't draw a button, so don't reserve space for it. const int bar_type = style->direction() == LTR ? RightPadding : LeftPadding; if (paddingType == bar_type && style->appearance() != NoAppearance) - padding += PlatformScrollbar::verticalScrollbarWidth(); + padding += ScrollbarTheme::nativeTheme()->scrollbarThickness(); return padding; } diff --git a/webkit/port/svg/SVGElementInstance.idl b/webkit/port/svg/SVGElementInstance.idl new file mode 100644 index 0000000..606aa18 --- /dev/null +++ b/webkit/port/svg/SVGElementInstance.idl @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 2008 Apple 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: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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. + */ + +module svg { + + interface [ + Conditional=SVG, + ObjCCustomInternalImpl, + CustomListeners, + CustomPushEventHandlerScope, + GenerateToJS, + GenerateNativeConverter + ] SVGElementInstance +#if defined(LANGUAGE_OBJECTIVE_C) + : Object, EventTarget +#endif /* defined(LANGUAGE_OBJECTIVE_C) */ + { + readonly attribute SVGElement correspondingElement; + readonly attribute SVGUseElement correspondingUseElement; + readonly attribute SVGElementInstance parentNode; + readonly attribute SVGElementInstanceList childNodes; + readonly attribute SVGElementInstance firstChild; + readonly attribute SVGElementInstance lastChild; + readonly attribute SVGElementInstance previousSibling; + readonly attribute SVGElementInstance nextSibling; + + // EventTarget +#if !defined(LANGUAGE_OBJECTIVE_C) + attribute [DontEnum, Custom=ElementEventHandler] DOMString onabort; + attribute [DontEnum, Custom=ElementEventHandler] DOMString onblur; + attribute [DontEnum, Custom=ElementEventHandler] DOMString onchange; + attribute [DontEnum, Custom=ElementEventHandler] DOMString onclick; + attribute [DontEnum, Custom=ElementEventHandler] DOMString oncontextmenu; + attribute [DontEnum, Custom=ElementEventHandler] DOMString ondblclick; + attribute [DontEnum, Custom=ElementEventHandler] DOMString onerror; + attribute [DontEnum, Custom=ElementEventHandler] DOMString onfocus; + attribute [DontEnum, Custom=ElementEventHandler] DOMString oninput; + attribute [DontEnum, Custom=ElementEventHandler] DOMString onkeydown; + attribute [DontEnum, Custom=ElementEventHandler] DOMString onkeypress; + attribute [DontEnum, Custom=ElementEventHandler] DOMString onkeyup; + attribute [DontEnum, Custom=ElementEventHandler] DOMString onload; + attribute [DontEnum, Custom=ElementEventHandler] DOMString onmousedown; + attribute [DontEnum, Custom=ElementEventHandler] DOMString onmousemove; + attribute [DontEnum, Custom=ElementEventHandler] DOMString onmouseout; + attribute [DontEnum, Custom=ElementEventHandler] DOMString onmouseover; + attribute [DontEnum, Custom=ElementEventHandler] DOMString onmouseup; + attribute [DontEnum, Custom=ElementEventHandler] DOMString onmousewheel; + attribute [DontEnum, Custom=ElementEventHandler] DOMString onbeforecut; + attribute [DontEnum, Custom=ElementEventHandler] DOMString oncut; + attribute [DontEnum, Custom=ElementEventHandler] DOMString onbeforecopy; + attribute [DontEnum, Custom=ElementEventHandler] DOMString oncopy; + attribute [DontEnum, Custom=ElementEventHandler] DOMString onbeforepaste; + attribute [DontEnum, Custom=ElementEventHandler] DOMString onpaste; + attribute [DontEnum, Custom=ElementEventHandler] DOMString ondragenter; + attribute [DontEnum, Custom=ElementEventHandler] DOMString ondragover; + attribute [DontEnum, Custom=ElementEventHandler] DOMString ondragleave; + attribute [DontEnum, Custom=ElementEventHandler] DOMString ondrop; + attribute [DontEnum, Custom=ElementEventHandler] DOMString ondragstart; + attribute [DontEnum, Custom=ElementEventHandler] DOMString ondrag; + attribute [DontEnum, Custom=ElementEventHandler] DOMString ondragend; + attribute [DontEnum, Custom=ElementEventHandler] DOMString onreset; + attribute [DontEnum, Custom=ElementEventHandler] DOMString onresize; + attribute [DontEnum, Custom=ElementEventHandler] DOMString onscroll; + attribute [DontEnum, Custom=ElementEventHandler] DOMString onsearch; + attribute [DontEnum, Custom=ElementEventHandler] DOMString onselect; + attribute [DontEnum, Custom=ElementEventHandler] DOMString onselectstart; + attribute [DontEnum, Custom=ElementEventHandler] DOMString onsubmit; + attribute [DontEnum, Custom=ElementEventHandler] DOMString onunload; + + [Custom] void addEventListener(in DOMString type, + in EventListener listener, + in boolean useCapture); + [Custom] void removeEventListener(in DOMString type, + in EventListener listener, + in boolean useCapture); + boolean dispatchEvent(in Event event) + raises(EventException); +#endif /* defined(LANGUAGE_OBJECTIVE_C) */ + }; +} |