summaryrefslogtreecommitdiffstats
path: root/WebCore/page
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2009-08-18 15:36:45 +0100
committerBen Murdoch <benm@google.com>2009-08-18 19:20:06 +0100
commitd227fc870c7a697500a3c900c31baf05fb9a8524 (patch)
treea3fa109aa5bf52fef562ac49d97a2f723889cc71 /WebCore/page
parentf2c627513266faa73f7669058d98c60769fb3524 (diff)
downloadexternal_webkit-d227fc870c7a697500a3c900c31baf05fb9a8524.zip
external_webkit-d227fc870c7a697500a3c900c31baf05fb9a8524.tar.gz
external_webkit-d227fc870c7a697500a3c900c31baf05fb9a8524.tar.bz2
Merge WebKit r47420
Diffstat (limited to 'WebCore/page')
-rw-r--r--WebCore/page/Chrome.cpp7
-rw-r--r--WebCore/page/Chrome.h7
-rw-r--r--WebCore/page/ChromeClient.h8
-rw-r--r--WebCore/page/DOMWindow.cpp40
-rw-r--r--WebCore/page/DOMWindow.h10
-rw-r--r--WebCore/page/DOMWindow.idl10
-rw-r--r--WebCore/page/EventHandler.cpp8
-rw-r--r--WebCore/page/EventSource.cpp372
-rw-r--r--WebCore/page/EventSource.h146
-rw-r--r--WebCore/page/EventSource.idl65
-rw-r--r--WebCore/page/Geolocation.cpp1
-rw-r--r--WebCore/page/Navigator.cpp20
-rw-r--r--WebCore/page/Navigator.h5
-rw-r--r--WebCore/page/Navigator.idl4
-rw-r--r--WebCore/page/Page.h7
-rw-r--r--WebCore/page/PositionOptions.h2
-rw-r--r--WebCore/page/SecurityOrigin.cpp27
-rw-r--r--WebCore/page/SecurityOrigin.h6
-rw-r--r--WebCore/page/animation/AnimationBase.cpp169
-rw-r--r--WebCore/page/haiku/DragControllerHaiku.cpp5
-rw-r--r--WebCore/page/haiku/EventHandlerHaiku.cpp11
21 files changed, 895 insertions, 35 deletions
diff --git a/WebCore/page/Chrome.cpp b/WebCore/page/Chrome.cpp
index 5a5670e..bcfef79 100644
--- a/WebCore/page/Chrome.cpp
+++ b/WebCore/page/Chrome.cpp
@@ -403,6 +403,13 @@ bool Chrome::setCursor(PlatformCursorHandle cursor)
return m_client->setCursor(cursor);
}
+#if ENABLE(NOTIFICATIONS)
+NotificationPresenter* Chrome::notificationPresenter() const
+{
+ return m_client->notificationPresenter();
+}
+#endif
+
// --------
#if ENABLE(DASHBOARD_SUPPORT)
diff --git a/WebCore/page/Chrome.h b/WebCore/page/Chrome.h
index c26e450..e28661c 100644
--- a/WebCore/page/Chrome.h
+++ b/WebCore/page/Chrome.h
@@ -44,6 +44,9 @@ namespace WebCore {
class IntRect;
class Page;
class String;
+#if ENABLE(NOTIFICATIONS)
+ class NotificationPresenter;
+#endif
struct FrameLoadRequest;
struct WindowFeatures;
@@ -128,6 +131,10 @@ namespace WebCore {
void focusNSView(NSView*);
#endif
+#if ENABLE(NOTIFICATIONS)
+ NotificationPresenter* notificationPresenter() const;
+#endif
+
private:
Page* m_page;
ChromeClient* m_client;
diff --git a/WebCore/page/ChromeClient.h b/WebCore/page/ChromeClient.h
index 409a492..1010273 100644
--- a/WebCore/page/ChromeClient.h
+++ b/WebCore/page/ChromeClient.h
@@ -62,6 +62,10 @@ namespace WebCore {
class GraphicsLayer;
#endif
+#if ENABLE(NOTIFICATIONS)
+ class NotificationPresenter;
+#endif
+
class ChromeClient {
public:
virtual void chromeDestroyed() = 0;
@@ -152,6 +156,10 @@ namespace WebCore {
virtual void dashboardRegionsChanged();
#endif
+#if ENABLE(NOTIFICATIONS)
+ virtual NotificationPresenter* notificationPresenter() const = 0;
+#endif
+
virtual void populateVisitedLinks();
virtual FloatRect customHighlightRect(Node*, const AtomicString& type, const FloatRect& lineRect);
diff --git a/WebCore/page/DOMWindow.cpp b/WebCore/page/DOMWindow.cpp
index e50b488..0cc3e5f 100644
--- a/WebCore/page/DOMWindow.cpp
+++ b/WebCore/page/DOMWindow.cpp
@@ -80,6 +80,10 @@
#include "DOMApplicationCache.h"
#endif
+#if ENABLE(NOTIFICATIONS)
+#include "NotificationCenter.h"
+#endif
+
using std::min;
using std::max;
@@ -454,6 +458,10 @@ void DOMWindow::clear()
m_applicationCache->disconnectFrame();
m_applicationCache = 0;
#endif
+
+#if ENABLE(NOTIFICATIONS)
+ m_notifications = 0;
+#endif
}
Screen* DOMWindow::screen() const
@@ -593,6 +601,28 @@ Storage* DOMWindow::localStorage() const
}
#endif
+#if ENABLE(NOTIFICATIONS)
+NotificationCenter* DOMWindow::webkitNotifications() const
+{
+ if (m_notifications)
+ return m_notifications.get();
+
+ Document* document = this->document();
+ if (!document)
+ return 0;
+
+ Page* page = document->page();
+ if (!page)
+ return 0;
+
+ NotificationPresenter* provider = page->chrome()->notificationPresenter();
+ if (provider)
+ m_notifications = NotificationCenter::create(document, provider);
+
+ return m_notifications.get();
+}
+#endif
+
void DOMWindow::postMessage(const String& message, MessagePort* messagePort, const String& targetOrigin, DOMWindow* source, ExceptionCode& ec)
{
if (!m_frame)
@@ -1532,6 +1562,16 @@ void DOMWindow::setOnfocus(PassRefPtr<EventListener> eventListener)
setAttributeEventListener(eventNames().focusEvent, eventListener);
}
+EventListener* DOMWindow::onhashchange() const
+{
+ return getAttributeEventListener(eventNames().hashchangeEvent);
+}
+
+void DOMWindow::setOnhashchange(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().hashchangeEvent, eventListener);
+}
+
EventListener* DOMWindow::onkeydown() const
{
return getAttributeEventListener(eventNames().keydownEvent);
diff --git a/WebCore/page/DOMWindow.h b/WebCore/page/DOMWindow.h
index 12caf7e..ffe4ef5 100644
--- a/WebCore/page/DOMWindow.h
+++ b/WebCore/page/DOMWindow.h
@@ -56,6 +56,7 @@ namespace WebCore {
class MessagePort;
class Navigator;
class Node;
+ class NotificationCenter;
class PostMessageTimer;
class ScheduledAction;
class Screen;
@@ -205,6 +206,10 @@ namespace WebCore {
DOMApplicationCache* applicationCache() const;
#endif
+#if ENABLE(NOTIFICATIONS)
+ NotificationCenter* webkitNotifications() const;
+#endif
+
void postMessage(const String& message, MessagePort*, const String& targetOrigin, DOMWindow* source, ExceptionCode&);
void postMessageTimerFired(PostMessageTimer*);
@@ -274,6 +279,8 @@ namespace WebCore {
void setOnerror(PassRefPtr<EventListener>);
EventListener* onfocus() const;
void setOnfocus(PassRefPtr<EventListener>);
+ EventListener* onhashchange() const;
+ void setOnhashchange(PassRefPtr<EventListener>);
EventListener* onkeydown() const;
void setOnkeydown(PassRefPtr<EventListener>);
EventListener* onkeypress() const;
@@ -441,6 +448,9 @@ namespace WebCore {
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
mutable RefPtr<DOMApplicationCache> m_applicationCache;
#endif
+#if ENABLE(NOTIFICATIONS)
+ mutable RefPtr<NotificationCenter> m_notifications;
+#endif
RegisteredEventListenerVector m_eventListeners;
};
diff --git a/WebCore/page/DOMWindow.idl b/WebCore/page/DOMWindow.idl
index aba92f0..4e7835e 100644
--- a/WebCore/page/DOMWindow.idl
+++ b/WebCore/page/DOMWindow.idl
@@ -55,7 +55,7 @@ module window {
attribute [Replaceable] Navigator clientInformation;
attribute [DoNotCheckDomainSecurity, JSCCustom, V8CustomSetter, V8DisallowShadowing] Location location;
- attribute [Replaceable, CustomGetter] Event event;
+ attribute [Replaceable, CustomGetter, V8CustomSetter] Event event;
readonly attribute [Custom] Crypto crypto;
@@ -169,6 +169,9 @@ module window {
readonly attribute Storage sessionStorage;
readonly attribute Storage localStorage;
#endif
+#if defined(ENABLE_NOTIFICATIONS) && ENABLE_NOTIFICATIONS
+ readonly attribute NotificationCenter webkitNotifications;
+#endif
attribute [Replaceable] Console console;
@@ -221,6 +224,7 @@ module window {
attribute EventListener onended;
attribute EventListener onerror;
attribute EventListener onfocus;
+ attribute EventListener onhashchange;
attribute EventListener oninput;
attribute EventListener onkeydown;
attribute EventListener onkeypress;
@@ -454,6 +458,10 @@ module window {
attribute RangeConstructor Range;
attribute RangeExceptionConstructor RangeException;
+#if ENABLE_EVENTSOURCE
+ attribute [JSCCustomGetter] EventSourceConstructor EventSource; // Usable with new the operator
+#endif
+
// Mozilla has a separate XMLDocument object for XML documents.
// We just use Document for this.
attribute DocumentConstructor XMLDocument;
diff --git a/WebCore/page/EventHandler.cpp b/WebCore/page/EventHandler.cpp
index 41e859f..99ecce0 100644
--- a/WebCore/page/EventHandler.cpp
+++ b/WebCore/page/EventHandler.cpp
@@ -442,7 +442,7 @@ bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& e
// If the selection is contained in a layer that can scroll, that layer should handle the autoscroll
// Otherwise, let the bridge handle it so the view can scroll itself.
RenderObject* renderer = targetNode->renderer();
- while (renderer && (!renderer->isBox() || !toRenderBox(renderer)->canBeProgramaticallyScrolled(false))) {
+ while (renderer && (!renderer->isBox() || !toRenderBox(renderer)->canBeScrolledAndHasScrollableArea())) {
if (!renderer->parent() && renderer->node() == renderer->document() && renderer->document()->ownerElement())
renderer = renderer->document()->ownerElement()->renderer();
else
@@ -732,7 +732,7 @@ void EventHandler::updateAutoscrollRenderer()
if (Node* nodeAtPoint = hitTest.innerNode())
m_autoscrollRenderer = nodeAtPoint->renderer();
- while (m_autoscrollRenderer && (!m_autoscrollRenderer->isBox() || !toRenderBox(m_autoscrollRenderer)->canBeProgramaticallyScrolled(false)))
+ while (m_autoscrollRenderer && (!m_autoscrollRenderer->isBox() || !toRenderBox(m_autoscrollRenderer)->canBeScrolledAndHasScrollableArea()))
m_autoscrollRenderer = m_autoscrollRenderer->parent();
}
@@ -1172,7 +1172,7 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
if (mouseEvent.button() == MiddleButton && !mev.isOverLink()) {
RenderObject* renderer = mev.targetNode()->renderer();
- while (renderer && (!renderer->isBox() || !toRenderBox(renderer)->canBeProgramaticallyScrolled(false))) {
+ while (renderer && (!renderer->isBox() || !toRenderBox(renderer)->canBeScrolledAndHasScrollableArea())) {
if (!renderer->parent() && renderer->node() == renderer->document() && renderer->document()->ownerElement())
renderer = renderer->document()->ownerElement()->renderer();
else
@@ -2339,7 +2339,7 @@ bool EventHandler::handleTextInputEvent(const String& text, Event* underlyingEve
}
-#if !PLATFORM(MAC) && !PLATFORM(QT)
+#if !PLATFORM(MAC) && !PLATFORM(QT) && !PLATFORM(HAIKU)
bool EventHandler::invertSenseOfTabsToLinks(KeyboardEvent*) const
{
return false;
diff --git a/WebCore/page/EventSource.cpp b/WebCore/page/EventSource.cpp
new file mode 100644
index 0000000..47243d9
--- /dev/null
+++ b/WebCore/page/EventSource.cpp
@@ -0,0 +1,372 @@
+/*
+ * Copyright (C) 2009 Ericsson AB
+ * 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.
+ * 3. Neither the name of Ericsson 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"
+
+#if ENABLE(EVENTSOURCE)
+
+#include "EventSource.h"
+
+#include "Cache.h"
+#include "DOMWindow.h"
+#include "Event.h"
+#include "EventException.h"
+#include "PlatformString.h"
+#include "MessageEvent.h"
+#include "ResourceError.h"
+#include "ResourceRequest.h"
+#include "ResourceResponse.h"
+#include "ScriptExecutionContext.h"
+#include "TextResourceDecoder.h"
+#include "ThreadableLoader.h"
+
+namespace WebCore {
+
+const unsigned long long EventSource::defaultReconnectDelay = 3000;
+
+EventSource::EventSource(const String& url, ScriptExecutionContext* context, ExceptionCode& ec)
+ : ActiveDOMObject(context, this)
+ , m_state(CONNECTING)
+ , m_reconnectTimer(this, &EventSource::reconnectTimerFired)
+ , m_failSilently(false)
+ , m_requestInFlight(false)
+ , m_reconnectDelay(defaultReconnectDelay)
+{
+ if (url.isEmpty() || !(m_url = context->completeURL(url)).isValid()) {
+ ec = SYNTAX_ERR;
+ return;
+ }
+ // FIXME: should support cross-origin requests
+ if (!scriptExecutionContext()->securityOrigin()->canRequest(m_url)) {
+ ec = SECURITY_ERR;
+ return;
+ }
+
+ m_origin = scriptExecutionContext()->securityOrigin()->toString();
+ m_decoder = TextResourceDecoder::create("text/plain", "UTF-8");
+
+ setPendingActivity(this);
+ connect();
+}
+
+EventSource::~EventSource()
+{
+}
+
+void EventSource::connect()
+{
+ ResourceRequest request(m_url);
+ request.setHTTPMethod("GET");
+ request.setHTTPHeaderField("Accept", "text/event-stream");
+ request.setHTTPHeaderField("Cache-Control", "no-cache");
+ if (!m_lastEventId.isEmpty())
+ request.setHTTPHeaderField("Last-Event-ID", m_lastEventId);
+
+ ThreadableLoaderOptions options;
+ options.sendLoadCallbacks = true;
+ options.sniffContent = false;
+ options.allowCredentials = true;
+
+ m_loader = ThreadableLoader::create(scriptExecutionContext(), this, request, options);
+
+ m_requestInFlight = true;
+
+ if (!scriptExecutionContext()->isWorkerContext())
+ cache()->loader()->nonCacheRequestInFlight(m_url);
+}
+
+void EventSource::endRequest()
+{
+ m_requestInFlight = false;
+
+ if (!m_failSilently)
+ dispatchGenericEvent(eventNames().errorEvent);
+
+ if (!scriptExecutionContext()->isWorkerContext())
+ cache()->loader()->nonCacheRequestComplete(m_url);
+
+ if (m_state != CLOSED)
+ scheduleReconnect();
+ else
+ unsetPendingActivity(this);
+}
+
+void EventSource::scheduleReconnect()
+{
+ m_state = CONNECTING;
+ m_reconnectTimer.startOneShot(m_reconnectDelay / 1000);
+}
+
+void EventSource::reconnectTimerFired(Timer<EventSource>*)
+{
+ connect();
+}
+
+String EventSource::url() const
+{
+ return m_url.string();
+}
+
+EventSource::State EventSource::readyState() const
+{
+ return m_state;
+}
+
+void EventSource::close()
+{
+ if (m_state == CLOSED)
+ return;
+
+ if (m_reconnectTimer.isActive()) {
+ m_reconnectTimer.stop();
+ unsetPendingActivity(this);
+ }
+
+ m_state = CLOSED;
+ m_failSilently = true;
+
+ if (m_requestInFlight)
+ m_loader->cancel();
+}
+
+ScriptExecutionContext* EventSource::scriptExecutionContext() const
+{
+ return ActiveDOMObject::scriptExecutionContext();
+}
+
+void EventSource::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool)
+{
+ EventListenersMap::iterator iter = m_eventListeners.find(eventType);
+ if (iter == m_eventListeners.end()) {
+ ListenerVector listeners;
+ listeners.append(eventListener);
+ m_eventListeners.add(eventType, listeners);
+ } else {
+ ListenerVector& listeners = iter->second;
+ for (ListenerVector::iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) {
+ if (*listenerIter == eventListener)
+ return;
+ }
+
+ listeners.append(eventListener);
+ m_eventListeners.add(eventType, listeners);
+ }
+}
+
+void EventSource::removeEventListener(const AtomicString& eventType, EventListener* eventListener, bool)
+{
+ EventListenersMap::iterator iter = m_eventListeners.find(eventType);
+ if (iter == m_eventListeners.end())
+ return;
+
+ ListenerVector& listeners = iter->second;
+ for (ListenerVector::const_iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) {
+ if (*listenerIter == eventListener) {
+ listeners.remove(listenerIter - listeners.begin());
+ return;
+ }
+ }
+}
+
+bool EventSource::dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec)
+{
+ if (!event || event->type().isEmpty()) {
+ ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
+ return true;
+ }
+
+ EventListener* attributeListener = m_attributeListeners.get(event->type()).get();
+ if (attributeListener) {
+ event->setTarget(this);
+ event->setCurrentTarget(this);
+ attributeListener->handleEvent(event.get(), false);
+ }
+
+ ListenerVector listenersCopy = m_eventListeners.get(event->type());
+ for (ListenerVector::const_iterator listenerIter = listenersCopy.begin(); listenerIter != listenersCopy.end(); ++listenerIter) {
+ event->setTarget(this);
+ event->setCurrentTarget(this);
+ listenerIter->get()->handleEvent(event.get(), false);
+ }
+
+ return !event->defaultPrevented();
+}
+
+void EventSource::didReceiveResponse(const ResourceResponse& response)
+{
+ int statusCode = response.httpStatusCode();
+ if (statusCode == 200 && response.httpHeaderField("Content-Type") == "text/event-stream") {
+ m_state = OPEN;
+ dispatchGenericEvent(eventNames().openEvent);
+ } else {
+ if (statusCode <= 200 || statusCode > 299)
+ m_state = CLOSED;
+ m_loader->cancel();
+ }
+}
+
+void EventSource::didReceiveData(const char* data, int length)
+{
+ append(m_receiveBuf, m_decoder->decode(data, length));
+ parseEventStream();
+}
+
+void EventSource::didFinishLoading(unsigned long)
+{
+ if (m_receiveBuf.size() > 0 || m_data.size() > 0) {
+ append(m_receiveBuf, "\n\n");
+ parseEventStream();
+ }
+ m_state = CONNECTING;
+ endRequest();
+}
+
+void EventSource::didFail(const ResourceError& error)
+{
+ int canceled = error.isCancellation();
+ if (((m_state == CONNECTING) && !canceled) || ((m_state == OPEN) && canceled))
+ m_state = CLOSED;
+ endRequest();
+}
+
+void EventSource::didFailRedirectCheck()
+{
+ m_state = CLOSED;
+ m_loader->cancel();
+}
+
+void EventSource::parseEventStream()
+{
+ unsigned int bufPos = 0;
+ unsigned int bufSize = m_receiveBuf.size();
+ for (;;) {
+ int lineLength = -1;
+ int fieldLength = -1;
+ int carriageReturn = 0;
+ for (unsigned int i = bufPos; lineLength < 0 && i < bufSize; i++) {
+ switch (m_receiveBuf[i]) {
+ case ':':
+ if (fieldLength < 0)
+ fieldLength = i - bufPos;
+ break;
+ case '\n':
+ if (i > bufPos && m_receiveBuf[i - 1] == '\r') {
+ carriageReturn++;
+ i--;
+ }
+ lineLength = i - bufPos;
+ break;
+ }
+ }
+
+ if (lineLength < 0)
+ break;
+
+ parseEventStreamLine(bufPos, fieldLength, lineLength);
+ bufPos += lineLength + carriageReturn + 1;
+ }
+
+ if (bufPos == bufSize)
+ m_receiveBuf.clear();
+ else if (bufPos)
+ m_receiveBuf.remove(0, bufPos);
+}
+
+void EventSource::parseEventStreamLine(unsigned int bufPos, int fieldLength, int lineLength)
+{
+ if (!lineLength) {
+ if (!m_data.isEmpty())
+ dispatchMessageEvent();
+ if (!m_eventName.isEmpty())
+ m_eventName = "";
+ } else if (fieldLength) {
+ bool noValue = fieldLength < 0;
+
+ String field(&m_receiveBuf[bufPos], noValue ? lineLength : fieldLength);
+ int step;
+ if (noValue)
+ step = lineLength;
+ else if (m_receiveBuf[bufPos + fieldLength + 1] != ' ')
+ step = fieldLength + 1;
+ else
+ step = fieldLength + 2;
+ bufPos += step;
+ int valueLength = lineLength - step;
+
+ if (field == "data") {
+ if (m_data.size() > 0)
+ m_data.append('\n');
+ if (valueLength)
+ m_data.append(&m_receiveBuf[bufPos], valueLength);
+ } else if (field == "event")
+ m_eventName = valueLength ? String(&m_receiveBuf[bufPos], valueLength) : "";
+ else if (field == "id")
+ m_lastEventId = valueLength ? String(&m_receiveBuf[bufPos], valueLength) : "";
+ else if (field == "retry") {
+ if (!valueLength)
+ m_reconnectDelay = defaultReconnectDelay;
+ else {
+ String value(&m_receiveBuf[bufPos], valueLength);
+ bool ok;
+ unsigned long long retry = value.toUInt64(&ok);
+ if (ok)
+ m_reconnectDelay = retry;
+ }
+ }
+ }
+}
+
+void EventSource::dispatchGenericEvent(const AtomicString& type)
+{
+ RefPtr<Event> evt = Event::create(type, false, false);
+ ExceptionCode ec = 0;
+ dispatchEvent(evt.release(), ec);
+ ASSERT(!ec);
+}
+
+void EventSource::dispatchMessageEvent()
+{
+ RefPtr<MessageEvent> evt = MessageEvent::create();
+ String eventName = m_eventName.isEmpty() ? eventNames().messageEvent.string() : m_eventName;
+ evt->initMessageEvent(eventName, false, false, String::adopt(m_data), m_origin, m_lastEventId, 0, 0);
+ ExceptionCode ec = 0;
+ dispatchEvent(evt.release(), ec);
+ ASSERT(!ec);
+}
+
+void EventSource::stop()
+{
+ close();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(EVENTSOURCE)
diff --git a/WebCore/page/EventSource.h b/WebCore/page/EventSource.h
new file mode 100644
index 0000000..df55694
--- /dev/null
+++ b/WebCore/page/EventSource.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2009 Ericsson AB
+ * 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.
+ * 3. Neither the name of Ericsson nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef EventSource_h
+#define EventSource_h
+
+#if ENABLE(EVENTSOURCE)
+
+#include "ActiveDOMObject.h"
+#include "AtomicStringHash.h"
+#include "EventListener.h"
+#include "EventNames.h"
+#include "EventTarget.h"
+#include "KURL.h"
+#include "ThreadableLoaderClient.h"
+#include "Timer.h"
+
+#include <wtf/HashMap.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+ class ResourceResponse;
+ class TextResourceDecoder;
+ class ThreadableLoader;
+
+ class EventSource : public RefCounted<EventSource>, public EventTarget, private ThreadableLoaderClient, public ActiveDOMObject {
+ public:
+ static PassRefPtr<EventSource> create(const String& url, ScriptExecutionContext* context, ExceptionCode& ec) { return adoptRef(new EventSource(url, context, ec)); }
+ virtual ~EventSource();
+
+ static const unsigned long long defaultReconnectDelay;
+
+ String url() const;
+
+ enum State {
+ CONNECTING = 0,
+ OPEN = 1,
+ CLOSED = 2,
+ };
+
+ State readyState() const;
+
+ void setOnopen(PassRefPtr<EventListener> eventListener) { m_attributeListeners.set(eventNames().openEvent, eventListener); }
+ EventListener* onopen() const { return m_attributeListeners.get(eventNames().openEvent).get(); }
+
+ void setOnmessage(PassRefPtr<EventListener> eventListener) { m_attributeListeners.set(eventNames().messageEvent, eventListener); }
+ EventListener* onmessage() const { return m_attributeListeners.get(eventNames().messageEvent).get(); }
+
+ void setOnerror(PassRefPtr<EventListener> eventListener) { m_attributeListeners.set(eventNames().errorEvent, eventListener); }
+ EventListener* onerror() const { return m_attributeListeners.get(eventNames().errorEvent).get(); }
+
+ void close();
+
+ using RefCounted<EventSource>::ref;
+ using RefCounted<EventSource>::deref;
+
+ virtual EventSource* toEventSource() { return this; }
+ virtual ScriptExecutionContext* scriptExecutionContext() const;
+
+ typedef Vector<RefPtr<EventListener> > ListenerVector;
+ typedef HashMap<AtomicString, ListenerVector> EventListenersMap;
+
+ virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
+ virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
+ virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&);
+ EventListenersMap& eventListeners() { return m_eventListeners; }
+
+ virtual void stop();
+
+ private:
+ EventSource(const String& url, ScriptExecutionContext* context, ExceptionCode& ec);
+
+ virtual void refEventTarget() { ref(); }
+ virtual void derefEventTarget() { deref(); }
+
+ virtual void didReceiveResponse(const ResourceResponse& response);
+ virtual void didReceiveData(const char* data, int length);
+ virtual void didFinishLoading(unsigned long);
+ virtual void didFail(const ResourceError& error);
+ virtual void didFailRedirectCheck();
+
+ void connect();
+ void endRequest();
+ void scheduleReconnect();
+ void reconnectTimerFired(Timer<EventSource>*);
+ void parseEventStream();
+ void parseEventStreamLine(unsigned int pos, int fieldLength, int lineLength);
+ void dispatchGenericEvent(const AtomicString& type);
+ void dispatchMessageEvent();
+
+ KURL m_url;
+ State m_state;
+
+ HashMap<AtomicString, RefPtr<EventListener> > m_attributeListeners;
+ EventListenersMap m_eventListeners;
+
+ RefPtr<TextResourceDecoder> m_decoder;
+ RefPtr<ThreadableLoader> m_loader;
+ Timer<EventSource> m_reconnectTimer;
+ Vector<UChar> m_receiveBuf;
+ bool m_failSilently;
+ bool m_requestInFlight;
+
+ String m_eventName;
+ Vector<UChar> m_data;
+ String m_lastEventId;
+ unsigned long long m_reconnectDelay;
+ String m_origin;
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(EVENTSOURCE)
+
+#endif // EventSource_h
diff --git a/WebCore/page/EventSource.idl b/WebCore/page/EventSource.idl
new file mode 100644
index 0000000..c438e68
--- /dev/null
+++ b/WebCore/page/EventSource.idl
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2009 Ericsson AB
+ * 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.
+ * 3. Neither the name of Ericsson 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.
+ */
+
+module window {
+
+ interface [
+ Conditional=EVENTSOURCE,
+ CustomMarkFunction,
+ NoStaticTables
+ ] EventSource {
+
+ readonly attribute DOMString URL;
+
+ // ready state
+ const unsigned short CONNECTING = 0;
+ const unsigned short OPEN = 1;
+ const unsigned short CLOSED = 2;
+ readonly attribute unsigned short readyState;
+
+ // networking
+ attribute EventListener onopen;
+ attribute EventListener onmessage;
+ attribute EventListener onerror;
+ void close();
+
+ // EventTarget interface
+ [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 evt)
+ raises(EventException);
+
+ };
+}
diff --git a/WebCore/page/Geolocation.cpp b/WebCore/page/Geolocation.cpp
index e57a8b5..f8cc111 100644
--- a/WebCore/page/Geolocation.cpp
+++ b/WebCore/page/Geolocation.cpp
@@ -334,6 +334,7 @@ void Geolocation::requestPermission()
void Geolocation::geolocationServicePositionChanged(GeolocationService*)
{
+ ASSERT_UNUSED(service, service == m_service);
ASSERT(m_service->lastPosition());
// Stop all currently running timers.
diff --git a/WebCore/page/Navigator.cpp b/WebCore/page/Navigator.cpp
index 3603b86..4922860 100644
--- a/WebCore/page/Navigator.cpp
+++ b/WebCore/page/Navigator.cpp
@@ -31,11 +31,13 @@
#include "Language.h"
#include "MimeTypeArray.h"
#include "Page.h"
+#include "PageGroup.h"
#include "PlatformString.h"
#include "PluginArray.h"
#include "PluginData.h"
#include "ScriptController.h"
#include "Settings.h"
+#include "StorageNamespace.h"
namespace WebCore {
@@ -150,5 +152,21 @@ Geolocation* Navigator::geolocation() const
m_geolocation = Geolocation::create(m_frame);
return m_geolocation.get();
}
-
+
+#if ENABLE(DOM_STORAGE)
+void Navigator::getStorageUpdates()
+{
+ if (!m_frame)
+ return;
+
+ Page* page = m_frame->page();
+ if (!page)
+ return;
+
+ StorageNamespace* localStorage = page->group().localStorage();
+ if (localStorage)
+ localStorage->unlock();
+}
+#endif
+
} // namespace WebCore
diff --git a/WebCore/page/Navigator.h b/WebCore/page/Navigator.h
index d50721e..4adebe1 100644
--- a/WebCore/page/Navigator.h
+++ b/WebCore/page/Navigator.h
@@ -55,6 +55,11 @@ namespace WebCore {
// This is used for GC marking.
Geolocation* optionalGeolocation() const { return m_geolocation.get(); }
+#if ENABLE(DOM_STORAGE)
+ // Relinquishes the storage lock, if one exists.
+ void getStorageUpdates();
+#endif
+
private:
Navigator(Frame*);
Frame* m_frame;
diff --git a/WebCore/page/Navigator.idl b/WebCore/page/Navigator.idl
index 8048ff3..80ef4fb 100644
--- a/WebCore/page/Navigator.idl
+++ b/WebCore/page/Navigator.idl
@@ -42,6 +42,10 @@ module window {
#if defined(ENABLE_GEOLOCATION) && ENABLE_GEOLOCATION
readonly attribute Geolocation geolocation;
#endif
+
+#if defined(ENABLE_DOM_STORAGE) && ENABLE_DOM_STORAGE
+ void getStorageUpdates();
+#endif
};
}
diff --git a/WebCore/page/Page.h b/WebCore/page/Page.h
index 9d9af86..fb212a4 100644
--- a/WebCore/page/Page.h
+++ b/WebCore/page/Page.h
@@ -71,6 +71,9 @@ namespace WebCore {
#if ENABLE(WML)
class WMLPageState;
#endif
+#if ENABLE(NOTIFICATIONS)
+ class NotificationPresenter;
+#endif
enum FindDirection { FindDirectionForward, FindDirectionBackward };
@@ -272,6 +275,10 @@ namespace WebCore {
#if ENABLE(WML)
OwnPtr<WMLPageState> m_wmlPageState;
#endif
+
+#if ENABLE(NOTIFICATIONS)
+ NotificationPresenter* m_notificationPresenter;
+#endif
};
} // namespace WebCore
diff --git a/WebCore/page/PositionOptions.h b/WebCore/page/PositionOptions.h
index ee8530a..ed7074b 100644
--- a/WebCore/page/PositionOptions.h
+++ b/WebCore/page/PositionOptions.h
@@ -33,7 +33,7 @@ namespace WebCore {
class PositionOptions : public RefCounted<PositionOptions> {
public:
- static PassRefPtr<PositionOptions> create() { return adoptRef(new PositionOptions); }
+ static PassRefPtr<PositionOptions> create() { return adoptRef(new PositionOptions()); }
bool enableHighAccuracy() const { return m_highAccuracy; }
void setEnableHighAccuracy(bool enable) { m_highAccuracy = enable; }
diff --git a/WebCore/page/SecurityOrigin.cpp b/WebCore/page/SecurityOrigin.cpp
index 14a1b59..8274e0e 100644
--- a/WebCore/page/SecurityOrigin.cpp
+++ b/WebCore/page/SecurityOrigin.cpp
@@ -32,15 +32,10 @@
#include "CString.h"
#include "FrameLoader.h"
#include "KURL.h"
-#include "PlatformString.h"
-#include "StringHash.h"
-#include <wtf/HashSet.h>
#include <wtf/StdLibExtras.h>
namespace WebCore {
-typedef HashSet<String, CaseFoldingHash> URLSchemesMap;
-
static URLSchemesMap& localSchemes()
{
DEFINE_STATIC_LOCAL(URLSchemesMap, localSchemes, ());
@@ -346,6 +341,28 @@ void SecurityOrigin::registerURLSchemeAsLocal(const String& scheme)
}
// static
+void SecurityOrigin::removeURLSchemeRegisteredAsLocal(const String& scheme)
+{
+ if (scheme == "file")
+ return;
+#if PLATFORM(MAC)
+ if (scheme == "applewebdata")
+ return;
+#endif
+#if PLATFORM(QT)
+ if (scheme == "qrc")
+ return;
+#endif
+ localSchemes().remove(scheme);
+}
+
+// static
+const URLSchemesMap& SecurityOrigin::localURLSchemes()
+{
+ return localSchemes();
+}
+
+// static
bool SecurityOrigin::shouldTreatURLAsLocal(const String& url)
{
// This avoids an allocation of another String and the HashSet contains()
diff --git a/WebCore/page/SecurityOrigin.h b/WebCore/page/SecurityOrigin.h
index ab92683..335ed28 100644
--- a/WebCore/page/SecurityOrigin.h
+++ b/WebCore/page/SecurityOrigin.h
@@ -29,14 +29,18 @@
#ifndef SecurityOrigin_h
#define SecurityOrigin_h
+#include <wtf/HashSet.h>
#include <wtf/RefCounted.h>
#include <wtf/PassRefPtr.h>
#include <wtf/Threading.h>
#include "PlatformString.h"
+#include "StringHash.h"
namespace WebCore {
+ typedef HashSet<String, CaseFoldingHash> URLSchemesMap;
+
class KURL;
class SecurityOrigin : public ThreadSafeShared<SecurityOrigin> {
@@ -129,6 +133,8 @@ namespace WebCore {
bool isSameSchemeHostPort(const SecurityOrigin*) const;
static void registerURLSchemeAsLocal(const String&);
+ static void removeURLSchemeRegisteredAsLocal(const String&);
+ static const URLSchemesMap& localURLSchemes();
static bool shouldTreatURLAsLocal(const String&);
static bool shouldTreatURLSchemeAsLocal(const String&);
diff --git a/WebCore/page/animation/AnimationBase.cpp b/WebCore/page/animation/AnimationBase.cpp
index 7503f0a..f85d8e4 100644
--- a/WebCore/page/animation/AnimationBase.cpp
+++ b/WebCore/page/animation/AnimationBase.cpp
@@ -302,11 +302,21 @@ public:
{
ShadowData* shadowA = (a->*m_getter)();
ShadowData* shadowB = (b->*m_getter)();
+
+ while (true) {
+ if (!shadowA && !shadowB) // end of both lists
+ return true;
+
+ if (!shadowA || !shadowB) // end of just one of the lists
+ return false;
+
+ if (*shadowA != *shadowB)
+ return false;
+
+ shadowA = shadowA->next;
+ shadowB = shadowB->next;
+ }
- if ((!shadowA && shadowB) || (shadowA && !shadowB))
- return false;
- if (shadowA && shadowB && (*shadowA != *shadowB))
- return false;
return true;
}
@@ -316,12 +326,22 @@ public:
ShadowData* shadowB = (b->*m_getter)();
ShadowData defaultShadowData(0, 0, 0, 0, Normal, Color::transparent);
- if (!shadowA)
- shadowA = &defaultShadowData;
- if (!shadowB)
- shadowB = &defaultShadowData;
+ ShadowData* newShadowData = 0;
+
+ while (shadowA || shadowB) {
+ ShadowData* srcShadow = shadowA ? shadowA : &defaultShadowData;
+ ShadowData* dstShadow = shadowB ? shadowB : &defaultShadowData;
+
+ if (!newShadowData)
+ newShadowData = blendFunc(anim, srcShadow, dstShadow, progress);
+ else
+ newShadowData->next = blendFunc(anim, srcShadow, dstShadow, progress);
- (dst->*m_setter)(blendFunc(anim, shadowA, shadowB, progress), false);
+ shadowA = shadowA ? shadowA->next : 0;
+ shadowB = shadowB ? shadowB->next : 0;
+ }
+
+ (dst->*m_setter)(newShadowData, false);
}
private:
@@ -365,6 +385,124 @@ private:
void (RenderStyle::*m_setter)(const Color&);
};
+// Wrapper base class for an animatable property in a FillLayer
+class FillLayerPropertyWrapperBase {
+public:
+ FillLayerPropertyWrapperBase()
+ {
+ }
+
+ virtual ~FillLayerPropertyWrapperBase() { }
+
+ virtual bool equals(const FillLayer* a, const FillLayer* b) const = 0;
+ virtual void blend(const AnimationBase* anim, FillLayer* dst, const FillLayer* a, const FillLayer* b, double progress) const = 0;
+};
+
+template <typename T>
+class FillLayerPropertyWrapperGetter : public FillLayerPropertyWrapperBase {
+public:
+ FillLayerPropertyWrapperGetter(T (FillLayer::*getter)() const)
+ : m_getter(getter)
+ {
+ }
+
+ virtual bool equals(const FillLayer* a, const FillLayer* b) const
+ {
+ // If the style pointers are the same, don't bother doing the test.
+ // If either is null, return false. If both are null, return true.
+ if ((!a && !b) || a == b)
+ return true;
+ if (!a || !b)
+ return false;
+ return (a->*m_getter)() == (b->*m_getter)();
+ }
+
+protected:
+ T (FillLayer::*m_getter)() const;
+};
+
+template <typename T>
+class FillLayerPropertyWrapper : public FillLayerPropertyWrapperGetter<T> {
+public:
+ FillLayerPropertyWrapper(T (FillLayer::*getter)() const, void (FillLayer::*setter)(T))
+ : FillLayerPropertyWrapperGetter<T>(getter)
+ , m_setter(setter)
+ {
+ }
+
+ virtual void blend(const AnimationBase* anim, FillLayer* dst, const FillLayer* a, const FillLayer* b, double progress) const
+ {
+ (dst->*m_setter)(blendFunc(anim, (a->*FillLayerPropertyWrapperGetter<T>::m_getter)(), (b->*FillLayerPropertyWrapperGetter<T>::m_getter)(), progress));
+ }
+
+protected:
+ void (FillLayer::*m_setter)(T);
+};
+
+
+class FillLayersPropertyWrapper : public PropertyWrapperBase {
+public:
+ typedef const FillLayer* (RenderStyle::*LayersGetter)() const;
+ typedef FillLayer* (RenderStyle::*LayersAccessor)();
+
+ FillLayersPropertyWrapper(int prop, LayersGetter getter, LayersAccessor accessor)
+ : PropertyWrapperBase(prop)
+ , m_layersGetter(getter)
+ , m_layersAccessor(accessor)
+ {
+ switch (prop) {
+ case CSSPropertyBackgroundPositionX:
+ case CSSPropertyWebkitMaskPositionX:
+ m_fillLayerPropertyWrapper = new FillLayerPropertyWrapper<Length>(&FillLayer::xPosition, &FillLayer::setXPosition);
+ break;
+ case CSSPropertyBackgroundPositionY:
+ case CSSPropertyWebkitMaskPositionY:
+ m_fillLayerPropertyWrapper = new FillLayerPropertyWrapper<Length>(&FillLayer::yPosition, &FillLayer::setYPosition);
+ break;
+ case CSSPropertyWebkitBackgroundSize:
+ case CSSPropertyWebkitMaskSize:
+ m_fillLayerPropertyWrapper = new FillLayerPropertyWrapper<LengthSize>(&FillLayer::size, &FillLayer::setSize);
+ break;
+ }
+ }
+
+ virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
+ {
+ const FillLayer* fromLayer = (a->*m_layersGetter)();
+ const FillLayer* toLayer = (b->*m_layersGetter)();
+
+ while (fromLayer && toLayer) {
+ if (!m_fillLayerPropertyWrapper->equals(fromLayer, toLayer))
+ return false;
+
+ fromLayer = fromLayer->next();
+ toLayer = toLayer->next();
+ }
+
+ return true;
+ }
+
+ virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const
+ {
+ const FillLayer* aLayer = (a->*m_layersGetter)();
+ const FillLayer* bLayer = (b->*m_layersGetter)();
+ FillLayer* dstLayer = (dst->*m_layersAccessor)();
+
+ while (aLayer && bLayer && dstLayer) {
+ m_fillLayerPropertyWrapper->blend(anim, dstLayer, aLayer, bLayer, progress);
+ aLayer = aLayer->next();
+ bLayer = bLayer->next();
+ dstLayer = dstLayer->next();
+ }
+ }
+
+private:
+ FillLayerPropertyWrapperBase* m_fillLayerPropertyWrapper;
+
+ LayersGetter m_layersGetter;
+ LayersAccessor m_layersAccessor;
+};
+
class ShorthandPropertyWrapper : public PropertyWrapperBase {
public:
ShorthandPropertyWrapper(int property, const CSSPropertyLonghand& longhand)
@@ -442,13 +580,14 @@ static void ensurePropertyMap()
gPropertyWrappers->append(new PropertyWrapper<const Color&>(CSSPropertyColor, &RenderStyle::color, &RenderStyle::setColor));
gPropertyWrappers->append(new PropertyWrapper<const Color&>(CSSPropertyBackgroundColor, &RenderStyle::backgroundColor, &RenderStyle::setBackgroundColor));
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyBackgroundPositionX, &RenderStyle::backgroundXPosition, &RenderStyle::setBackgroundXPosition));
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyBackgroundPositionY, &RenderStyle::backgroundYPosition, &RenderStyle::setBackgroundYPosition));
- gPropertyWrappers->append(new PropertyWrapper<LengthSize>(CSSPropertyWebkitBackgroundSize, &RenderStyle::backgroundSize, &RenderStyle::setBackgroundSize));
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyWebkitMaskPositionX, &RenderStyle::maskXPosition, &RenderStyle::setMaskXPosition));
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyWebkitMaskPositionY, &RenderStyle::maskYPosition, &RenderStyle::setMaskYPosition));
- gPropertyWrappers->append(new PropertyWrapper<LengthSize>(CSSPropertyWebkitMaskSize, &RenderStyle::maskSize, &RenderStyle::setMaskSize));
+ gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyBackgroundPositionX, &RenderStyle::backgroundLayers, &RenderStyle::accessBackgroundLayers));
+ gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyBackgroundPositionY, &RenderStyle::backgroundLayers, &RenderStyle::accessBackgroundLayers));
+ gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyWebkitBackgroundSize, &RenderStyle::backgroundLayers, &RenderStyle::accessBackgroundLayers));
+
+ gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyWebkitMaskPositionX, &RenderStyle::maskLayers, &RenderStyle::accessMaskLayers));
+ gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyWebkitMaskPositionY, &RenderStyle::maskLayers, &RenderStyle::accessMaskLayers));
+ gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyWebkitMaskSize, &RenderStyle::maskLayers, &RenderStyle::accessMaskLayers));
gPropertyWrappers->append(new PropertyWrapper<int>(CSSPropertyFontSize, &RenderStyle::fontSize, &RenderStyle::setBlendedFontSize));
gPropertyWrappers->append(new PropertyWrapper<unsigned short>(CSSPropertyWebkitColumnRuleWidth, &RenderStyle::columnRuleWidth, &RenderStyle::setColumnRuleWidth));
diff --git a/WebCore/page/haiku/DragControllerHaiku.cpp b/WebCore/page/haiku/DragControllerHaiku.cpp
index 0b95558..ef08ac2 100644
--- a/WebCore/page/haiku/DragControllerHaiku.cpp
+++ b/WebCore/page/haiku/DragControllerHaiku.cpp
@@ -32,10 +32,9 @@
#include <InterfaceDefs.h>
-namespace WebCore
-{
+namespace WebCore {
-// FIXME: These values are straight out of DragControllerMac, so probably have
+// FIXME: These values are straight out of DragControllerMac, so probably have
// little correlation with Haiku standards...
const int DragController::LinkDragBorderInset = 2;
const int DragController::MaxOriginalImageArea = 1500 * 1500;
diff --git a/WebCore/page/haiku/EventHandlerHaiku.cpp b/WebCore/page/haiku/EventHandlerHaiku.cpp
index 64b8519..203344e 100644
--- a/WebCore/page/haiku/EventHandlerHaiku.cpp
+++ b/WebCore/page/haiku/EventHandlerHaiku.cpp
@@ -36,14 +36,13 @@
#include "HitTestResult.h"
#include "KeyboardEvent.h"
#include "MouseEventWithHitTestResults.h"
+#include "NotImplemented.h"
#include "Page.h"
#include "PlatformKeyboardEvent.h"
#include "PlatformScrollBar.h"
#include "PlatformWheelEvent.h"
#include "RenderWidget.h"
-#include "NotImplemented.h"
-
#include <interface/View.h>
@@ -117,13 +116,15 @@ bool EventHandler::passSubframeEventToSubframe(MouseEventWithHitTestResults& eve
bool EventHandler::passWheelEventToWidget(PlatformWheelEvent& event, Widget* widget)
{
- notImplemented();
- return false;
+ if (!widget->isFrameView())
+ return false;
+
+ return static_cast<FrameView*>(widget)->frame()->eventHandler()->handleWheelEvent(event);
}
PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const
{
- return new ClipboardHaiku(ClipboardWritable, true);
+ return ClipboardHaiku::create(ClipboardWritable, true);
}
bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe)