diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2009-06-24 13:42:15 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2009-06-24 13:42:15 +0200 |
commit | 259c32cd921fcbb85f79f21923d0efa0d6743d8a (patch) | |
tree | f9629c9be4b8488eb3221b48c0629a42a6ffce4c /src/3rdparty/webkit/WebCore/page | |
parent | ff2b98cf81daf585bb657bee7f5f131769b38eca (diff) |
Updated WebKit from /home/shausman/src/webkit/trunk to qtwebkit-4.6-snapshot-24062009 ( 6d5a2a0472a6af0b7f781da018e76bb8522d57a5 )
++ b/WebKit/qt/ChangeLog
2009-06-19 Daniel <qt-info@nokia.com>
Reviewed by Simon Hausmann.
Remove warnings for QString() constructions from const char *
By explicitly wrapping it with QLatin1String() / QLatin1Char()
* Api/qwebelement.cpp:
(QWebElement::classes): Use QLatin1String.
(QWebElement::addClass): Ditto.
(QWebElement::removeClass): Ditto.
(QWebElement::toggleClass): Ditto.
2009-06-18 Friedemann Kleint <Friedemann.Kleint@nokia.com>
Reviewed by Simon Hausmann.
Fixed MinGW compilation.
* Api/qwebelement.cpp:
(QWebElement::evaluateScript):
2009-06-18 Markus Goetz <Markus.Goetz@nokia.com>
Reviewed by Simon Hausman.
Clarify in docs how to compile with debug information.
* docs/qtwebkit.qdoc:
2009-06-17 Markus Goetz <Markus.Goetz@nokia.com>
Reviewed by Simon Hausmann.
QWebPage: Don't call supportsSsl()
This stops QWebPage from loading the OpenSSL libs,
certificates etc. when they are not needed for the non-HTTPS case.
Loading the SSL libraries can be a very slow operation.
* Api/qwebpage.cpp:
(QWebPage::userAgentForUrl):
2009-06-15 Benjamin C Meyer <benjamin.meyer@torchmobile.com>
Reviewed by Adam Treat.
Support the back/forward/stop/refresh multimedia keys and accept the
event when handling backspace and shift backspace as we should.
* Api/qwebpage.cpp:
(QWebPagePrivate::keyPressEvent):
2009-06-15 Andre Pedralho <andre.pedralho@openbossa.org>
Reviewed by Adam Treat.
https://bugs.webkit.org/show_bug.cgi?id=26351
Remove bool QWebHitTestResult::isScrollBar() const and make sure a null QWebHitTestResult is returned instead.
* Api/qwebframe.cpp:
(QWebFrame::hitTestContent):
* Api/qwebframe.h:
* Api/qwebpage.cpp:
(QWebPage::updatePositionDependentActions):
2009-06-15 Simon Hausmann <simon.hausmann@nokia.com>
Reviewed by Adam Treat.
Fix the logic for disabling the fixed layout feature, when an invalid
QSize is set.
* Api/qwebpage.cpp:
(QWebPage::setFixedContentsSize):
2009-06-13 Adam Barth <abarth@webkit.org>
Reviewed by Darin Fisher.
https://bugs.webkit.org/show_bug.cgi?id=24492
Move registerURLSchemeAsLocal from FrameLoader to SecurityOrigin.
* Api/qwebpage.cpp:
(QWebPage::acceptNavigationRequest):
Rubber-stamped by Simon Hausmann.
2009-06-09 Simon Hausmann <simon.hausmann@nokia.com>
Reviewed by Ariya Hidayat.
Renamed QWebSettings::AllowUniversalAccessFromFileUrls to
LocalContentCanAccessRemoteUrls, as discussed in the API review.
* Api/qwebsettings.cpp:
(QWebSettingsPrivate::apply):
(QWebSettings::QWebSettings):
* Api/qwebsettings.h:
2009-06-09 Simon Hausmann <simon.hausmann@nokia.com>
Reviewed by Ariya Hidayat.
Merged useFixedLayout property with fixedLayoutSize and
renamed the latter to fixedContentsSize.
* Api/qwebpage.cpp:
(QWebPage::fixedContentsSize):
(QWebPage::setFixedContentsSize):
* Api/qwebpage.h:
* WebCoreSupport/FrameLoaderClientQt.cpp:
(WebCore::FrameLoaderClientQt::transitionToCommittedForNewPage):
2009-06-09 Simon Hausmann <simon.hausmann@nokia.com>
Reviewed by Ariya Hidayat.
Renamed QWebHitTestResult::linkTarget to linkElement() and made it return
a QWebElement. The link target itself is always the target DOM attribute.
* Api/qwebframe.cpp:
(QWebHitTestResultPrivate::QWebHitTestResultPrivate):
(QWebHitTestResult::linkElement):
* Api/qwebframe.h:
* Api/qwebframe_p.h:
* tests/qwebframe/tst_qwebframe.cpp:
Diffstat (limited to 'src/3rdparty/webkit/WebCore/page')
25 files changed, 636 insertions, 170 deletions
diff --git a/src/3rdparty/webkit/WebCore/page/Console.cpp b/src/3rdparty/webkit/WebCore/page/Console.cpp index 99a0fc8fea..138423689d 100644 --- a/src/3rdparty/webkit/WebCore/page/Console.cpp +++ b/src/3rdparty/webkit/WebCore/page/Console.cpp @@ -287,6 +287,9 @@ void Console::profile(const JSC::UString& title, ScriptCallStack* callStack) } JSC::Profiler::profiler()->startProfiling(callStack->state(), title); + + const ScriptCallFrame& lastCaller = callStack->at(0); + page->inspectorController()->addStartProfilingMessageToConsole(title, lastCaller.lineNumber(), lastCaller.sourceURL()); } void Console::profileEnd(const JSC::UString& title, ScriptCallStack* callStack) diff --git a/src/3rdparty/webkit/WebCore/page/DOMWindow.cpp b/src/3rdparty/webkit/WebCore/page/DOMWindow.cpp index bc1192d9a6..9c3bfced70 100644 --- a/src/3rdparty/webkit/WebCore/page/DOMWindow.cpp +++ b/src/3rdparty/webkit/WebCore/page/DOMWindow.cpp @@ -87,14 +87,25 @@ namespace WebCore { class PostMessageTimer : public TimerBase { public: - PostMessageTimer(DOMWindow* window, PassRefPtr<MessageEvent> event, SecurityOrigin* targetOrigin) + PostMessageTimer(DOMWindow* window, const String& message, const String& sourceOrigin, PassRefPtr<DOMWindow> source, PassOwnPtr<MessagePortChannel> channel, SecurityOrigin* targetOrigin) : m_window(window) - , m_event(event) + , m_message(message) + , m_origin(sourceOrigin) + , m_source(source) + , m_channel(channel) , m_targetOrigin(targetOrigin) { } - MessageEvent* event() const { return m_event.get(); } + PassRefPtr<MessageEvent> event(ScriptExecutionContext* context) + { + RefPtr<MessagePort> messagePort; + if (m_channel) { + messagePort = MessagePort::create(*context); + messagePort->entangle(m_channel.release()); + } + return MessageEvent::create(m_message, m_origin, "", m_source, messagePort.release()); + } SecurityOrigin* targetOrigin() const { return m_targetOrigin.get(); } private: @@ -104,7 +115,10 @@ private: } RefPtr<DOMWindow> m_window; - RefPtr<MessageEvent> m_event; + String m_message; + String m_origin; + RefPtr<DOMWindow> m_source; + OwnPtr<MessagePortChannel> m_channel; RefPtr<SecurityOrigin> m_targetOrigin; }; @@ -591,9 +605,9 @@ void DOMWindow::postMessage(const String& message, MessagePort* messagePort, con } } - RefPtr<MessagePort> newMessagePort; + OwnPtr<MessagePortChannel> channel; if (messagePort) - newMessagePort = messagePort->clone(ec); + channel = messagePort->disentangle(ec); if (ec) return; @@ -605,7 +619,7 @@ void DOMWindow::postMessage(const String& message, MessagePort* messagePort, con String sourceOrigin = sourceDocument->securityOrigin()->toString(); // Schedule the message. - PostMessageTimer* timer = new PostMessageTimer(this, MessageEvent::create(message, sourceOrigin, "", source, newMessagePort), target.get()); + PostMessageTimer* timer = new PostMessageTimer(this, message, sourceOrigin, source, channel.release(), target.get()); timer->startOneShot(0); } @@ -626,13 +640,8 @@ void DOMWindow::postMessageTimerFired(PostMessageTimer* t) } } - MessagePort* messagePort = timer->event()->messagePort(); - ASSERT(!messagePort || !messagePort->scriptExecutionContext()); - if (messagePort) - messagePort->attachToContext(document()); - ExceptionCode ec = 0; - dispatchEvent(timer->event(), ec); + dispatchEvent(timer->event(document()), ec); } DOMSelection* DOMWindow::getSelection() diff --git a/src/3rdparty/webkit/WebCore/page/DOMWindow.idl b/src/3rdparty/webkit/WebCore/page/DOMWindow.idl index 67ce3802a6..942facca31 100644 --- a/src/3rdparty/webkit/WebCore/page/DOMWindow.idl +++ b/src/3rdparty/webkit/WebCore/page/DOMWindow.idl @@ -133,8 +133,8 @@ module window { attribute [Replaceable, DoNotCheckDomainSecurityOnGet] DOMWindow frames; attribute [Replaceable, DoNotCheckDomainSecurityOnGet, V8CustomSetter] DOMWindow opener; - attribute [Replaceable, DoNotCheckDomainSecurity] DOMWindow parent; - attribute [Replaceable, DoNotCheckDomainSecurity, V8DisallowShadowing, V8ReadOnly] DOMWindow top; + attribute [Replaceable, DoNotCheckDomainSecurityOnGet] DOMWindow parent; + attribute [Replaceable, DoNotCheckDomainSecurityOnGet, V8DisallowShadowing, V8ReadOnly] DOMWindow top; // DOM Level 2 AbstractView Interface readonly attribute Document document; @@ -247,7 +247,6 @@ module window { // Not implemented yet. // attribute EventListener onafterprint; // attribute EventListener onbeforeprint; - // attribute EventListener ondataunavailable; // attribute EventListener onformchange; // attribute EventListener onforminput; // attribute EventListener onhashchange; @@ -309,7 +308,7 @@ module window { // FIXME: Implement the commented-out global constructors for interfaces listed in DOM Level 3 Core specification. attribute DOMCoreExceptionConstructor DOMException; - attribute DOMStringListConstructor DOMStringList; +// attribute DOMStringListConstructor DOMStringList; // attribute NameListConstructor NameList; // attribute DOMImplementationListConstructor DOMImplementationList; // attribute DOMImplementationSourceConstructor DOMImplementationSource; @@ -350,6 +349,8 @@ module window { attribute HTMLBodyElementConstructor HTMLBodyElement; attribute HTMLButtonElementConstructor HTMLButtonElement; attribute HTMLCanvasElementConstructor HTMLCanvasElement; + attribute HTMLDataGridElementConstructor HTMLDataGridElement; + attribute HTMLDataGridColElementConstructor HTMLDataGridColElement; attribute HTMLDListElementConstructor HTMLDListElement; attribute HTMLDirectoryElementConstructor HTMLDirectoryElement; attribute HTMLDivElementConstructor HTMLDivElement; diff --git a/src/3rdparty/webkit/WebCore/page/DragController.cpp b/src/3rdparty/webkit/WebCore/page/DragController.cpp index e1b5ea7625..2fe5d975eb 100644 --- a/src/3rdparty/webkit/WebCore/page/DragController.cpp +++ b/src/3rdparty/webkit/WebCore/page/DragController.cpp @@ -222,17 +222,15 @@ DragOperation DragController::dragEnteredOrUpdated(DragData* dragData) mouseMovedIntoDocument(m_page->mainFrame()->documentAtPoint(dragData->clientPosition())); m_dragDestinationAction = m_client->actionMaskForDrag(dragData); - - DragOperation operation = DragOperationNone; - - if (m_dragDestinationAction == DragDestinationActionNone) + if (m_dragDestinationAction == DragDestinationActionNone) { cancelDrag(); // FIXME: Why not call mouseMovedIntoDocument(0)? - else { - operation = tryDocumentDrag(dragData, m_dragDestinationAction); - if (operation == DragOperationNone && (m_dragDestinationAction & DragDestinationActionLoad)) - return operationForLoad(dragData); + return DragOperationNone; } - + + DragOperation operation = DragOperationNone; + bool handledByDocument = tryDocumentDrag(dragData, m_dragDestinationAction, operation); + if (!handledByDocument && (m_dragDestinationAction & DragDestinationActionLoad)) + return operationForLoad(dragData); return operation; } @@ -256,25 +254,41 @@ static HTMLInputElement* asFileInput(Node* node) return 0; } -DragOperation DragController::tryDocumentDrag(DragData* dragData, DragDestinationAction actionMask) +bool DragController::tryDocumentDrag(DragData* dragData, DragDestinationAction actionMask, DragOperation& operation) { ASSERT(dragData); if (!m_documentUnderMouse) - return DragOperationNone; + return false; - DragOperation operation = DragOperationNone; - if (actionMask & DragDestinationActionDHTML) - operation = tryDHTMLDrag(dragData); - m_isHandlingDrag = operation != DragOperationNone; + m_isHandlingDrag = false; + if (actionMask & DragDestinationActionDHTML) { + m_isHandlingDrag = tryDHTMLDrag(dragData, operation); + // Do not continue if m_documentUnderMouse has been reset by tryDHTMLDrag. + // tryDHTMLDrag fires dragenter event. The event listener that listens + // to this event may create a nested message loop (open a modal dialog), + // which could process dragleave event and reset m_documentUnderMouse in + // dragExited. + if (!m_documentUnderMouse) + return false; + } + // It's unclear why this check is after tryDHTMLDrag. + // We send drag events in tryDHTMLDrag and that may be the reason. RefPtr<FrameView> frameView = m_documentUnderMouse->view(); if (!frameView) - return operation; - + return false; + + if (m_isHandlingDrag) { + m_page->dragCaretController()->clear(); + return true; + } + if ((actionMask & DragDestinationActionEdit) && !m_isHandlingDrag && canProcessDrag(dragData)) { - if (dragData->containsColor()) - return DragOperationGeneric; + if (dragData->containsColor()) { + operation = DragOperationGeneric; + return true; + } IntPoint dragPos = dragData->clientPosition(); IntPoint point = frameView->windowToContents(dragPos); @@ -286,11 +300,10 @@ DragOperation DragController::tryDocumentDrag(DragData* dragData, DragDestinatio } Frame* innerFrame = element->document()->frame(); - return dragIsMove(innerFrame->selection()) ? DragOperationMove : DragOperationCopy; - } - - m_page->dragCaretController()->clear(); - return operation; + operation = dragIsMove(innerFrame->selection()) ? DragOperationMove : DragOperationCopy; + return true; + } + return false; } DragSourceAction DragController::delegateDragSourceAction(const IntPoint& windowPoint) @@ -453,43 +466,51 @@ bool DragController::canProcessDrag(DragData* dragData) return true; } -DragOperation DragController::tryDHTMLDrag(DragData* dragData) +static DragOperation defaultOperationForDrag(DragOperation srcOpMask) +{ + // This is designed to match IE's operation fallback for the case where + // the page calls preventDefault() in a drag event but doesn't set dropEffect. + if (srcOpMask & DragOperationCopy) + return DragOperationCopy; + if (srcOpMask & DragOperationMove || srcOpMask & DragOperationGeneric) + return DragOperationMove; + if (srcOpMask & DragOperationLink) + return DragOperationLink; + + // FIXME: Does IE really return "generic" even if no operations were allowed by the source? + return DragOperationGeneric; +} + +bool DragController::tryDHTMLDrag(DragData* dragData, DragOperation& operation) { ASSERT(dragData); ASSERT(m_documentUnderMouse); - DragOperation op = DragOperationNone; RefPtr<Frame> mainFrame = m_page->mainFrame(); RefPtr<FrameView> viewProtector = mainFrame->view(); if (!viewProtector) - return DragOperationNone; - + return false; + ClipboardAccessPolicy policy = m_documentUnderMouse->securityOrigin()->isLocal() ? ClipboardReadable : ClipboardTypesReadable; RefPtr<Clipboard> clipboard = dragData->createClipboard(policy); - DragOperation srcOp = dragData->draggingSourceOperationMask(); - clipboard->setSourceOperation(srcOp); - - PlatformMouseEvent event = createMouseEvent(dragData); - if (mainFrame->eventHandler()->updateDragAndDrop(event, clipboard.get())) { - // *op unchanged if no source op was set - if (!clipboard->destinationOperation(op)) { - // The element accepted but they didn't pick an operation, so we pick one for them - // (as does WinIE). - if (srcOp & DragOperationCopy) - op = DragOperationCopy; - else if (srcOp & DragOperationMove || srcOp & DragOperationGeneric) - op = DragOperationMove; - else if (srcOp & DragOperationLink) - op = DragOperationLink; - else - op = DragOperationGeneric; - } else if (!(op & srcOp)) { - op = DragOperationNone; - } + DragOperation srcOpMask = dragData->draggingSourceOperationMask(); + clipboard->setSourceOperation(srcOpMask); + PlatformMouseEvent event = createMouseEvent(dragData); + if (!mainFrame->eventHandler()->updateDragAndDrop(event, clipboard.get())) { clipboard->setAccessPolicy(ClipboardNumb); // invalidate clipboard here for security - return op; + return false; + } + + if (!clipboard->destinationOperation(operation)) { + // The element accepted but they didn't pick an operation, so we pick one (to match IE). + operation = defaultOperationForDrag(srcOpMask); + } else if (!(srcOpMask & operation)) { + // The element picked an operation which is not supported by the source + operation = DragOperationNone; } - return op; + + clipboard->setAccessPolicy(ClipboardNumb); // invalidate clipboard here for security + return true; } bool DragController::mayStartDragAtEventLocation(const Frame* frame, const IntPoint& framePos) diff --git a/src/3rdparty/webkit/WebCore/page/DragController.h b/src/3rdparty/webkit/WebCore/page/DragController.h index 6fe1f7f8f2..9472589cb4 100644 --- a/src/3rdparty/webkit/WebCore/page/DragController.h +++ b/src/3rdparty/webkit/WebCore/page/DragController.h @@ -96,8 +96,8 @@ namespace WebCore { bool concludeEditDrag(DragData*); DragOperation dragEnteredOrUpdated(DragData*); DragOperation operationForLoad(DragData*); - DragOperation tryDocumentDrag(DragData*, DragDestinationAction); - DragOperation tryDHTMLDrag(DragData*); + bool tryDocumentDrag(DragData*, DragDestinationAction, DragOperation&); + bool tryDHTMLDrag(DragData*, DragOperation&); DragOperation dragOperation(DragData*); void cancelDrag(); bool dragIsMove(SelectionController*); diff --git a/src/3rdparty/webkit/WebCore/page/EventHandler.cpp b/src/3rdparty/webkit/WebCore/page/EventHandler.cpp index f020e7ab7a..e4129398c0 100644 --- a/src/3rdparty/webkit/WebCore/page/EventHandler.cpp +++ b/src/3rdparty/webkit/WebCore/page/EventHandler.cpp @@ -661,11 +661,10 @@ void EventHandler::setPanScrollCursor() // At the original click location we draw a 4 arrowed icon. Over this icon there won't be any scroll // So we don't want to change the cursor over this area - const int noScrollRadius = 9; - bool east = m_panScrollStartPos.x() < (m_currentMousePosition.x() - noScrollRadius); - bool west = m_panScrollStartPos.x() > (m_currentMousePosition.x() + noScrollRadius); - bool north = m_panScrollStartPos.y() > (m_currentMousePosition.y() + noScrollRadius); - bool south = m_panScrollStartPos.y() < (m_currentMousePosition.y() - noScrollRadius); + bool east = m_panScrollStartPos.x() < (m_currentMousePosition.x() - ScrollView::noPanScrollRadius); + bool west = m_panScrollStartPos.x() > (m_currentMousePosition.x() + ScrollView::noPanScrollRadius); + bool north = m_panScrollStartPos.y() > (m_currentMousePosition.y() + ScrollView::noPanScrollRadius); + bool south = m_panScrollStartPos.y() < (m_currentMousePosition.y() - ScrollView::noPanScrollRadius); if (north) { if (east) diff --git a/src/3rdparty/webkit/WebCore/page/Frame.cpp b/src/3rdparty/webkit/WebCore/page/Frame.cpp index 328f321c81..8905bd9cbf 100644 --- a/src/3rdparty/webkit/WebCore/page/Frame.cpp +++ b/src/3rdparty/webkit/WebCore/page/Frame.cpp @@ -622,7 +622,7 @@ void Frame::selectionLayoutChanged() // Start blinking with a black caret. Be sure not to restart if we're // already blinking in the right location. if (shouldBlink && !m_caretBlinkTimer.isActive()) { - if (double blinkInterval = theme()->caretBlinkInterval()) + if (double blinkInterval = page()->theme()->caretBlinkInterval()) m_caretBlinkTimer.startRepeating(blinkInterval); if (!m_caretPaint) { diff --git a/src/3rdparty/webkit/WebCore/page/FrameView.cpp b/src/3rdparty/webkit/WebCore/page/FrameView.cpp index f6501be007..9ce3c8224f 100644 --- a/src/3rdparty/webkit/WebCore/page/FrameView.cpp +++ b/src/3rdparty/webkit/WebCore/page/FrameView.cpp @@ -6,6 +6,7 @@ * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. * (C) 2006 Graham Dennis (graham.dennis@gmail.com) * (C) 2006 Alexey Proskuryakov (ap@nypop.com) + * Copyright (C) 2009 Google Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -228,6 +229,30 @@ void FrameView::init() } } +void FrameView::detachCustomScrollbars() +{ + if (!m_frame) + return; + + Document* document = m_frame->document(); + if (!document) + return; + + Element* body = document->body(); + if (!body) + return; + + RenderBox* renderBox = body->renderBox(); + + Scrollbar* horizontalBar = horizontalScrollbar(); + if (horizontalBar && horizontalBar->isCustomScrollbar() && reinterpret_cast<RenderScrollbar*>(horizontalBar)->owningRenderer() == renderBox) + setHasHorizontalScrollbar(false); + + Scrollbar* verticalBar = verticalScrollbar(); + if (verticalBar && verticalBar->isCustomScrollbar() && reinterpret_cast<RenderScrollbar*>(verticalBar)->owningRenderer() == renderBox) + setHasVerticalScrollbar(false); +} + void FrameView::clear() { setCanBlitOnScroll(true); @@ -1296,10 +1321,10 @@ void FrameView::updateControlTints() // to define when controls get the tint and to call this function when that changes. // Optimize the common case where we bring a window to the front while it's still empty. - if (!m_frame || m_frame->loader()->url().isEmpty()) + if (!m_frame || m_frame->loader()->url().isEmpty()) return; - - if (theme()->supportsControlTints() && m_frame->contentRenderer()) { + + if (m_frame->contentRenderer() && m_frame->contentRenderer()->theme()->supportsControlTints()) { if (needsLayout()) layout(); PlatformGraphicsContext* const noContext = 0; diff --git a/src/3rdparty/webkit/WebCore/page/FrameView.h b/src/3rdparty/webkit/WebCore/page/FrameView.h index 16eadc500e..9dabe56e92 100644 --- a/src/3rdparty/webkit/WebCore/page/FrameView.h +++ b/src/3rdparty/webkit/WebCore/page/FrameView.h @@ -105,6 +105,7 @@ public: void willMoveOffscreen(); void resetScrollbars(); + void detachCustomScrollbars(); void clear(); diff --git a/src/3rdparty/webkit/WebCore/page/History.idl b/src/3rdparty/webkit/WebCore/page/History.idl index fa308fb8b4..914d441713 100644 --- a/src/3rdparty/webkit/WebCore/page/History.idl +++ b/src/3rdparty/webkit/WebCore/page/History.idl @@ -29,8 +29,8 @@ module window { #if defined(V8_BINDING) && V8_BINDING CheckDomainSecurity, #endif - CustomGetOwnPropertySlot, - CustomPutFunction, + DelegatingGetOwnPropertySlot, + DelegatingPutFunction, CustomDeleteProperty, CustomGetPropertyNames ] History { diff --git a/src/3rdparty/webkit/WebCore/page/Location.idl b/src/3rdparty/webkit/WebCore/page/Location.idl index e7fa31a205..7d680f2f13 100644 --- a/src/3rdparty/webkit/WebCore/page/Location.idl +++ b/src/3rdparty/webkit/WebCore/page/Location.idl @@ -32,12 +32,12 @@ module window { #if defined(V8_BINDING) && V8_BINDING CheckDomainSecurity, #endif - CustomGetOwnPropertySlot, - CustomPutFunction, + DelegatingGetOwnPropertySlot, + DelegatingPutFunction, CustomDeleteProperty, CustomGetPropertyNames, CustomDefineGetter, - CustomPrototypePutFunction, + DelegatingPrototypePutFunction, CustomPrototypeDefineGetter ] Location { attribute [DoNotCheckDomainSecurityOnSet, CustomSetter, V8DisallowShadowing] DOMString href; diff --git a/src/3rdparty/webkit/WebCore/page/Page.cpp b/src/3rdparty/webkit/WebCore/page/Page.cpp index 70b4459cf1..a49ee4a1b1 100644 --- a/src/3rdparty/webkit/WebCore/page/Page.cpp +++ b/src/3rdparty/webkit/WebCore/page/Page.cpp @@ -46,6 +46,7 @@ #include "PluginData.h" #include "ProgressTracker.h" #include "RenderWidget.h" +#include "RenderTheme.h" #include "ScriptController.h" #include "SelectionController.h" #include "Settings.h" @@ -104,6 +105,7 @@ Page::Page(ChromeClient* chromeClient, ContextMenuClient* contextMenuClient, Edi , m_settings(new Settings(this)) , m_progress(new ProgressTracker) , m_backForwardList(BackForwardList::create(this)) + , m_theme(RenderTheme::themeForPage(this)) , m_editorClient(editorClient) , m_frameCount(0) , m_tabKeyCyclesThroughElements(true) diff --git a/src/3rdparty/webkit/WebCore/page/Page.h b/src/3rdparty/webkit/WebCore/page/Page.h index eedd24ce9d..32adcac4f8 100644 --- a/src/3rdparty/webkit/WebCore/page/Page.h +++ b/src/3rdparty/webkit/WebCore/page/Page.h @@ -60,6 +60,7 @@ namespace WebCore { class PageGroup; class PluginData; class ProgressTracker; + class RenderTheme; class VisibleSelection; class SelectionController; #if ENABLE(DOM_STORAGE) @@ -78,7 +79,9 @@ namespace WebCore { Page(ChromeClient*, ContextMenuClient*, EditorClient*, DragClient*, InspectorClient*); ~Page(); - + + RenderTheme* theme() const { return m_theme.get(); }; + static void refreshPlugins(bool reload); PluginData* pluginData() const; @@ -217,6 +220,8 @@ namespace WebCore { mutable RefPtr<PluginData> m_pluginData; + RefPtr<RenderTheme> m_theme; + EditorClient* m_editorClient; int m_frameCount; diff --git a/src/3rdparty/webkit/WebCore/page/PageGroup.cpp b/src/3rdparty/webkit/WebCore/page/PageGroup.cpp index f0951ebf38..f098211a86 100644 --- a/src/3rdparty/webkit/WebCore/page/PageGroup.cpp +++ b/src/3rdparty/webkit/WebCore/page/PageGroup.cpp @@ -97,8 +97,8 @@ void PageGroup::closeLocalStorage() PageGroupMap::iterator end = pageGroups->end(); for (PageGroupMap::iterator it = pageGroups->begin(); it != end; ++it) { - if (LocalStorage* localStorage = it->second->localStorage()) - localStorage->close(); + if (it->second->hasLocalStorage()) + it->second->localStorage()->close(); } #endif } @@ -108,10 +108,6 @@ void PageGroup::addPage(Page* page) ASSERT(page); ASSERT(!m_pages.contains(page)); m_pages.add(page); -#if ENABLE(DOM_STORAGE) - if (!m_localStorage) - m_localStorage = LocalStorage::localStorage(page->settings()->localStorageDatabasePath()); -#endif } void PageGroup::removePage(Page* page) @@ -187,6 +183,13 @@ void PageGroup::setShouldTrackVisitedLinks(bool shouldTrack) #if ENABLE(DOM_STORAGE) LocalStorage* PageGroup::localStorage() { + if (!m_localStorage) { + // Need a page in this page group to query the settings for the local storage database path. + Page* page = *m_pages.begin(); + ASSERT(page); + m_localStorage = LocalStorage::localStorage(page->settings()->localStorageDatabasePath()); + } + return m_localStorage.get(); } #endif diff --git a/src/3rdparty/webkit/WebCore/page/PageGroup.h b/src/3rdparty/webkit/WebCore/page/PageGroup.h index 097fb87227..4da22511d7 100644 --- a/src/3rdparty/webkit/WebCore/page/PageGroup.h +++ b/src/3rdparty/webkit/WebCore/page/PageGroup.h @@ -68,7 +68,9 @@ namespace WebCore { private: void addVisitedLink(LinkHash stringHash); - +#if ENABLE(DOM_STORAGE) + bool hasLocalStorage() { return m_localStorage; } +#endif String m_name; HashSet<Page*> m_pages; diff --git a/src/3rdparty/webkit/WebCore/page/SecurityOrigin.cpp b/src/3rdparty/webkit/WebCore/page/SecurityOrigin.cpp index 187ec31318..baafd4ed18 100644 --- a/src/3rdparty/webkit/WebCore/page/SecurityOrigin.cpp +++ b/src/3rdparty/webkit/WebCore/page/SecurityOrigin.cpp @@ -33,10 +33,41 @@ #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, ()); + + if (localSchemes.isEmpty()) { + localSchemes.add("file"); +#if PLATFORM(MAC) + localSchemes.add("applewebdata"); +#endif +#if PLATFORM(QT) + localSchemes.add("qrc"); +#endif + } + + return localSchemes; +} + +static URLSchemesMap& noAccessSchemes() +{ + DEFINE_STATIC_LOCAL(URLSchemesMap, noAccessSchemes, ()); + + if (noAccessSchemes.isEmpty()) + noAccessSchemes.add("data"); + + return noAccessSchemes; +} + static bool isDefaultPortForProtocol(unsigned short port, const String& protocol) { if (protocol.isEmpty()) @@ -66,7 +97,7 @@ SecurityOrigin::SecurityOrigin(const KURL& url) m_protocol = ""; // Some URLs are not allowed access to anything other than themselves. - if (FrameLoader::shouldTreatURLSchemeAsNoAccess(m_protocol)) + if (shouldTreatURLSchemeAsNoAccess(m_protocol)) m_noAccess = true; // document.domain starts as m_host, but can be set by the DOM. @@ -193,7 +224,7 @@ void SecurityOrigin::grantUniversalAccess() bool SecurityOrigin::isLocal() const { - return FrameLoader::shouldTreatURLSchemeAsLocal(m_protocol); + return shouldTreatURLSchemeAsLocal(m_protocol); } bool SecurityOrigin::isSecureTransitionTo(const KURL& url) const @@ -307,4 +338,62 @@ bool SecurityOrigin::isSameSchemeHostPort(const SecurityOrigin* other) const return true; } +// static +void SecurityOrigin::registerURLSchemeAsLocal(const String& scheme) +{ + localSchemes().add(scheme); +} + +// static +bool SecurityOrigin::shouldTreatURLAsLocal(const String& url) +{ + // This avoids an allocation of another String and the HashSet contains() + // call for the file: and http: schemes. + if (url.length() >= 5) { + const UChar* s = url.characters(); + if (s[0] == 'h' && s[1] == 't' && s[2] == 't' && s[3] == 'p' && s[4] == ':') + return false; + if (s[0] == 'f' && s[1] == 'i' && s[2] == 'l' && s[3] == 'e' && s[4] == ':') + return true; + } + + int loc = url.find(':'); + if (loc == -1) + return false; + + String scheme = url.left(loc); + return localSchemes().contains(scheme); +} + +// static +bool SecurityOrigin::shouldTreatURLSchemeAsLocal(const String& scheme) +{ + // This avoids an allocation of another String and the HashSet contains() + // call for the file: and http: schemes. + if (scheme.length() == 4) { + const UChar* s = scheme.characters(); + if (s[0] == 'h' && s[1] == 't' && s[2] == 't' && s[3] == 'p') + return false; + if (s[0] == 'f' && s[1] == 'i' && s[2] == 'l' && s[3] == 'e') + return true; + } + + if (scheme.isEmpty()) + return false; + + return localSchemes().contains(scheme); +} + +// static +void SecurityOrigin::registerURLSchemeAsNoAccess(const String& scheme) +{ + noAccessSchemes().add(scheme); +} + +// static +bool SecurityOrigin::shouldTreatURLSchemeAsNoAccess(const String& scheme) +{ + return noAccessSchemes().contains(scheme); +} + } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/page/SecurityOrigin.h b/src/3rdparty/webkit/WebCore/page/SecurityOrigin.h index 96f85df657..ab9268347c 100644 --- a/src/3rdparty/webkit/WebCore/page/SecurityOrigin.h +++ b/src/3rdparty/webkit/WebCore/page/SecurityOrigin.h @@ -128,6 +128,13 @@ namespace WebCore { // (and whether it was set) but considering the host. It is used for postMessage. bool isSameSchemeHostPort(const SecurityOrigin*) const; + static void registerURLSchemeAsLocal(const String&); + static bool shouldTreatURLAsLocal(const String&); + static bool shouldTreatURLSchemeAsLocal(const String&); + + static void registerURLSchemeAsNoAccess(const String&); + static bool shouldTreatURLSchemeAsNoAccess(const String&); + private: explicit SecurityOrigin(const KURL&); explicit SecurityOrigin(const SecurityOrigin*); diff --git a/src/3rdparty/webkit/WebCore/page/Settings.cpp b/src/3rdparty/webkit/WebCore/page/Settings.cpp index 91ec0b3546..3a00b8ec38 100644 --- a/src/3rdparty/webkit/WebCore/page/Settings.cpp +++ b/src/3rdparty/webkit/WebCore/page/Settings.cpp @@ -44,7 +44,7 @@ static void setNeedsReapplyStylesInAllFrames(Page* page) } #if USE(SAFARI_THEME) -bool Settings::gShouldPaintNativeControls = false; +bool Settings::gShouldPaintNativeControls = true; #endif Settings::Settings(Page* page) @@ -103,6 +103,7 @@ Settings::Settings(Page* page) // FIXME: This should really be disabled by default as it makes platforms that don't support the feature download files // they can't use by. Leaving enabled for now to not change existing behavior. , m_downloadableBinaryFontsEnabled(true) + , m_xssAuditorEnabled(false) { // A Frame may not have been created yet, so we initialize the AtomicString // hash before trying to use it. @@ -458,4 +459,9 @@ void Settings::setDownloadableBinaryFontsEnabled(bool downloadableBinaryFontsEna m_downloadableBinaryFontsEnabled = downloadableBinaryFontsEnabled; } +void Settings::setXSSAuditorEnabled(bool xssAuditorEnabled) +{ + m_xssAuditorEnabled = xssAuditorEnabled; +} + } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/page/Settings.h b/src/3rdparty/webkit/WebCore/page/Settings.h index 62cf7f6f3a..9d4e422057 100644 --- a/src/3rdparty/webkit/WebCore/page/Settings.h +++ b/src/3rdparty/webkit/WebCore/page/Settings.h @@ -238,6 +238,9 @@ namespace WebCore { void setDownloadableBinaryFontsEnabled(bool); bool downloadableBinaryFontsEnabled() const { return m_downloadableBinaryFontsEnabled; } + void setXSSAuditorEnabled(bool); + bool xssAuditorEnabled() const { return m_xssAuditorEnabled; } + private: Page* m_page; @@ -297,6 +300,7 @@ namespace WebCore { bool m_allowScriptsToCloseWindows : 1; unsigned m_editingBehavior : 1; bool m_downloadableBinaryFontsEnabled : 1; + bool m_xssAuditorEnabled : 1; #if USE(SAFARI_THEME) static bool gShouldPaintNativeControls; diff --git a/src/3rdparty/webkit/WebCore/page/XSSAuditor.cpp b/src/3rdparty/webkit/WebCore/page/XSSAuditor.cpp new file mode 100644 index 0000000000..19c6e4ef78 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/page/XSSAuditor.cpp @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2008, 2009 Daniel Bates (dbates@intudata.com) + * 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 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 "XSSAuditor.h" + +#include <wtf/StdLibExtras.h> + +#include "Console.h" +#include "CString.h" +#include "DocumentLoader.h" +#include "DOMWindow.h" +#include "Frame.h" +#include "KURL.h" +#include "ScriptSourceCode.h" +#include "Settings.h" +#include "TextResourceDecoder.h" + +namespace WebCore { + +// This method also appears in file ResourceResponseBase.cpp. +static bool isControlCharacter(UChar c) +{ + return c < ' ' || c == 127; +} + +XSSAuditor::XSSAuditor(Frame* frame) + : m_frame(frame) +{ +} + +XSSAuditor::~XSSAuditor() +{ +} + +bool XSSAuditor::isEnabled() const +{ + Settings* settings = m_frame->settings(); + return (settings && settings->xssAuditorEnabled()); +} + +bool XSSAuditor::canEvaluate(const String& sourceCode) const +{ + if (!isEnabled()) + return true; + + if (findInRequest(sourceCode)) { + DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute a JavaScript script. Source code of script found within request.\n")); + m_frame->domWindow()->console()->addMessage(JSMessageSource, ErrorMessageLevel, consoleMessage, 1, String()); + return false; + } + return true; +} + +bool XSSAuditor::canCreateInlineEventListener(const String&, const String& code) const +{ + if (!isEnabled()) + return true; + + return canEvaluate(code); +} + +bool XSSAuditor::canLoadExternalScriptFromSrc(const String& url) const +{ + if (!isEnabled()) + return true; + + if (findInRequest(url)) { + DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute a JavaScript script. Source code of script found within request.\n")); + m_frame->domWindow()->console()->addMessage(JSMessageSource, ErrorMessageLevel, consoleMessage, 1, String()); + return false; + } + return true; +} + +bool XSSAuditor::canLoadObject(const String& url) const +{ + if (!isEnabled()) + return true; + + if (findInRequest(url)) { + DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute a JavaScript script. Source code of script found within request")); + m_frame->domWindow()->console()->addMessage(OtherMessageSource, ErrorMessageLevel, consoleMessage, 1, String()); + return false; + } + return true; +} + +String XSSAuditor::decodeURL(const String& str, const TextEncoding& encoding, bool allowNullCharacters) +{ + String result; + String url = str; + + url.replace('+', ' '); + result = decodeURLEscapeSequences(url, encoding); + return allowNullCharacters ? result : result.removeCharacters(&isControlCharacter); +} + +bool XSSAuditor::findInRequest(const String& string) const +{ + ASSERT(m_frame->document()); + String pageURL = m_frame->document()->url().string(); + + if (protocolIs(pageURL, "data")) + return false; + + if (string.isEmpty()) + return false; + + if (string.length() < pageURL.length()) { + // The string can actually fit inside the pageURL. + String decodedPageURL = decodeURL(pageURL, m_frame->document()->decoder()->encoding()); + if (decodedPageURL.find(string, 0, false) != -1) + return true; // We've found the smoking gun. + } + + FormData* formDataObj = m_frame->loader()->documentLoader()->originalRequest().httpBody(); + if (formDataObj && !formDataObj->isEmpty()) { + String formData = formDataObj->flattenToString(); + if (string.length() < formData.length()) { + // Notice it is sufficient to compare the length of the string to + // the url-encoded POST data because the length of the url-decoded + // code is less than or equal to the length of the url-encoded + // string. + String decodedFormData = decodeURL(formData, m_frame->document()->decoder()->encoding()); + if (decodedFormData.find(string, 0, false) != -1) + return true; // We found the string in the POST data. + } + } + + return false; +} + +} // namespace WebCore + diff --git a/src/3rdparty/webkit/WebCore/page/XSSAuditor.h b/src/3rdparty/webkit/WebCore/page/XSSAuditor.h new file mode 100644 index 0000000000..e2b6140dfd --- /dev/null +++ b/src/3rdparty/webkit/WebCore/page/XSSAuditor.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2008, 2009 Daniel Bates (dbates@intudata.com) + * 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 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 XSSAuditor_h +#define XSSAuditor_h + +#include "PlatformString.h" +#include "TextEncoding.h" + +namespace WebCore { + + class Frame; + class ScriptSourceCode; + + // The XSSAuditor class is used to prevent type 1 cross-site scripting + // vulnerabilites (also known as reflected vulnerabilities). + // + // More specifically, the XSSAuditor class decides whether the execution of + // a script is to be allowed or denied based on the content of any + // user-submitted data, including: + // + // * the query string of the URL. + // * the HTTP-POST data. + // + // If the source code of a script resembles any user-submitted data then it + // is denied execution. + // + // When you instantiate the XSSAuditor you must specify the {@link Frame} + // of the page that you wish to audit. + // + // Bindings + // + // An XSSAuditor is instantiated within the contructor of a + // ScriptController object and passed the Frame the script originated. The + // ScriptController calls back to the XSSAuditor to determine whether a + // JavaScript script is safe to execute before executing it. The following + // methods call into XSSAuditor: + // + // * ScriptController::evaluate - used to evaluate JavaScript scripts. + // * ScriptController::createInlineEventListener - used to create JavaScript event handlers. + // * HTMLTokenizer::scriptHandler - used to load external JavaScript scripts. + // + class XSSAuditor { + public: + XSSAuditor(Frame*); + ~XSSAuditor(); + + bool isEnabled() const; + + // Determines whether the script should be allowed or denied execution + // based on the content of any user-submitted data. + bool canEvaluate(const String& sourceCode) const; + + // Determines whether the event listener should be created based on the + // content of any user-submitted data. + bool canCreateInlineEventListener(const String& functionName, const String& code) const; + + // Determines whether the external script should be loaded based on the + // content of any user-submitted data. + bool canLoadExternalScriptFromSrc(const String& url) const; + + // Determines whether object should be loaded based on the content of + // any user-submitted data. + // + // This method is called by FrameLoader::requestObject. + bool canLoadObject(const String& url) const; + + private: + static String decodeURL(const String& url, const TextEncoding& encoding = UTF8Encoding(), bool allowNullCharacters = false); + + bool findInRequest(const String&) const; + + // The frame to audit. + Frame* m_frame; + }; + +} // namespace WebCore + +#endif // XSSAuditor_h diff --git a/src/3rdparty/webkit/WebCore/page/animation/CompositeAnimation.cpp b/src/3rdparty/webkit/WebCore/page/animation/CompositeAnimation.cpp index d60455acf9..b03dfe35ee 100644 --- a/src/3rdparty/webkit/WebCore/page/animation/CompositeAnimation.cpp +++ b/src/3rdparty/webkit/WebCore/page/animation/CompositeAnimation.cpp @@ -67,91 +67,114 @@ void CompositeAnimation::clearRenderer() void CompositeAnimation::updateTransitions(RenderObject* renderer, RenderStyle* currentStyle, RenderStyle* targetStyle) { - RefPtr<RenderStyle> modifiedCurrentStyle; - - // If currentStyle is null, we don't do transitions - if (!currentStyle || !targetStyle->transitions()) + // If currentStyle is null or there are no old or new transitions, just skip it + if (!currentStyle || (!targetStyle->transitions() && m_transitions.isEmpty())) return; + // Mark all existing transitions as no longer active. We will mark the still active ones + // in the next loop and then toss the ones that didn't get marked. + CSSPropertyTransitionsMap::const_iterator end = m_transitions.end(); + for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) + it->second->setActive(false); + + RefPtr<RenderStyle> modifiedCurrentStyle; + // Check to see if we need to update the active transitions - for (size_t i = 0; i < targetStyle->transitions()->size(); ++i) { - const Animation* anim = targetStyle->transitions()->animation(i); - bool isActiveTransition = anim->duration() || anim->delay() > 0; - - int prop = anim->property(); - - if (prop == cAnimateNone) - continue; - - bool all = prop == cAnimateAll; - - // Handle both the 'all' and single property cases. For the single prop case, we make only one pass - // through the loop. - for (int propertyIndex = 0; propertyIndex < AnimationBase::getNumProperties(); ++propertyIndex) { - if (all) { - // Get the next property which is not a shorthand. - bool isShorthand; - prop = AnimationBase::getPropertyAtIndex(propertyIndex, isShorthand); - if (isShorthand) - continue; - } + if (targetStyle->transitions()) { + for (size_t i = 0; i < targetStyle->transitions()->size(); ++i) { + const Animation* anim = targetStyle->transitions()->animation(i); + bool isActiveTransition = anim->duration() || anim->delay() > 0; + + int prop = anim->property(); + + if (prop == cAnimateNone) + continue; - // ImplicitAnimations are always hashed by actual properties, never cAnimateAll - ASSERT(prop >= firstCSSProperty && prop < (firstCSSProperty + numCSSProperties)); - - // If there is a running animation for this property, the transition is overridden - // and we have to use the unanimatedStyle from the animation. We do the test - // against the unanimated style here, but we "override" the transition later. - RefPtr<KeyframeAnimation> keyframeAnim = getAnimationForProperty(prop); - RenderStyle* fromStyle = keyframeAnim ? keyframeAnim->unanimatedStyle() : currentStyle; - - // See if there is a current transition for this prop - ImplicitAnimation* implAnim = m_transitions.get(prop).get(); - bool equal = true; - - if (implAnim) { - // This might be a transition that is just finishing. That would be the case - // if it were postActive. But we still need to check for equality because - // it could be just finishing AND changing to a new goal state. - // - // This implAnim might also not be an already running transition. It might be - // newly added to the list in a previous iteration. This would happen if - // you have both an explicit transition-property and 'all' in the same - // list. In this case, the latter one overrides the earlier one, so we - // behave as though this is a running animation being replaced. - if (!implAnim->isTargetPropertyEqual(prop, targetStyle)) { -#if USE(ACCELERATED_COMPOSITING) - // For accelerated animations we need to return a new RenderStyle with the _current_ value - // of the property, so that restarted transitions use the correct starting point. - if (AnimationBase::animationOfPropertyIsAccelerated(prop) && !implAnim->isFallbackAnimating()) { - if (!modifiedCurrentStyle) - modifiedCurrentStyle = RenderStyle::clone(currentStyle); - - implAnim->blendPropertyValueInStyle(prop, modifiedCurrentStyle.get()); + bool all = prop == cAnimateAll; + + // Handle both the 'all' and single property cases. For the single prop case, we make only one pass + // through the loop. + for (int propertyIndex = 0; propertyIndex < AnimationBase::getNumProperties(); ++propertyIndex) { + if (all) { + // Get the next property which is not a shorthand. + bool isShorthand; + prop = AnimationBase::getPropertyAtIndex(propertyIndex, isShorthand); + if (isShorthand) + continue; + } + + // ImplicitAnimations are always hashed by actual properties, never cAnimateAll + ASSERT(prop >= firstCSSProperty && prop < (firstCSSProperty + numCSSProperties)); + + // If there is a running animation for this property, the transition is overridden + // and we have to use the unanimatedStyle from the animation. We do the test + // against the unanimated style here, but we "override" the transition later. + RefPtr<KeyframeAnimation> keyframeAnim = getAnimationForProperty(prop); + RenderStyle* fromStyle = keyframeAnim ? keyframeAnim->unanimatedStyle() : currentStyle; + + // See if there is a current transition for this prop + ImplicitAnimation* implAnim = m_transitions.get(prop).get(); + bool equal = true; + + if (implAnim) { + implAnim->setActive(true); + + // This might be a transition that is just finishing. That would be the case + // if it were postActive. But we still need to check for equality because + // it could be just finishing AND changing to a new goal state. + // + // This implAnim might also not be an already running transition. It might be + // newly added to the list in a previous iteration. This would happen if + // you have both an explicit transition-property and 'all' in the same + // list. In this case, the latter one overrides the earlier one, so we + // behave as though this is a running animation being replaced. + if (!implAnim->isTargetPropertyEqual(prop, targetStyle)) { + #if USE(ACCELERATED_COMPOSITING) + // For accelerated animations we need to return a new RenderStyle with the _current_ value + // of the property, so that restarted transitions use the correct starting point. + if (AnimationBase::animationOfPropertyIsAccelerated(prop) && !implAnim->isFallbackAnimating()) { + if (!modifiedCurrentStyle) + modifiedCurrentStyle = RenderStyle::clone(currentStyle); + + implAnim->blendPropertyValueInStyle(prop, modifiedCurrentStyle.get()); + } + #endif + m_transitions.remove(prop); + equal = false; } -#endif - m_transitions.remove(prop); - equal = false; + } else { + // We need to start a transition if it is active and the properties don't match + equal = !isActiveTransition || AnimationBase::propertiesEqual(prop, fromStyle, targetStyle); } - } else { - // We need to start a transition if it is active and the properties don't match - equal = !isActiveTransition || AnimationBase::propertiesEqual(prop, fromStyle, targetStyle); - } - // We can be in this loop with an inactive transition (!isActiveTransition). We need - // to do that to check to see if we are canceling a transition. But we don't want to - // start one of the inactive transitions. So short circuit that here. (See - // <https://bugs.webkit.org/show_bug.cgi?id=24787> - if (!equal && isActiveTransition) { - // Add the new transition - m_transitions.set(prop, ImplicitAnimation::create(const_cast<Animation*>(anim), prop, renderer, this, modifiedCurrentStyle ? modifiedCurrentStyle.get() : fromStyle)); + // We can be in this loop with an inactive transition (!isActiveTransition). We need + // to do that to check to see if we are canceling a transition. But we don't want to + // start one of the inactive transitions. So short circuit that here. (See + // <https://bugs.webkit.org/show_bug.cgi?id=24787> + if (!equal && isActiveTransition) { + // Add the new transition + m_transitions.set(prop, ImplicitAnimation::create(const_cast<Animation*>(anim), prop, renderer, this, modifiedCurrentStyle ? modifiedCurrentStyle.get() : fromStyle)); + } + + // We only need one pass for the single prop case + if (!all) + break; } - - // We only need one pass for the single prop case - if (!all) - break; } } + + // Make a list of transitions to be removed + Vector<int> toBeRemoved; + end = m_transitions.end(); + for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) { + ImplicitAnimation* anim = it->second.get(); + if (!anim->active()) + toBeRemoved.append(anim->animatingProperty()); + } + + // Now remove the transitions from the list + for (size_t j = 0; j < toBeRemoved.size(); ++j) + m_transitions.remove(toBeRemoved[j]); } void CompositeAnimation::updateKeyframeAnimations(RenderObject* renderer, RenderStyle* currentStyle, RenderStyle* targetStyle) diff --git a/src/3rdparty/webkit/WebCore/page/animation/ImplicitAnimation.cpp b/src/3rdparty/webkit/WebCore/page/animation/ImplicitAnimation.cpp index e93fee4d54..8edcd5a69c 100644 --- a/src/3rdparty/webkit/WebCore/page/animation/ImplicitAnimation.cpp +++ b/src/3rdparty/webkit/WebCore/page/animation/ImplicitAnimation.cpp @@ -45,6 +45,7 @@ ImplicitAnimation::ImplicitAnimation(const Animation* transition, int animatingP , m_transitionProperty(transition->property()) , m_animatingProperty(animatingProperty) , m_overridden(false) + , m_active(true) , m_fromStyle(fromStyle) { ASSERT(animatingProperty != cAnimateAll); diff --git a/src/3rdparty/webkit/WebCore/page/animation/ImplicitAnimation.h b/src/3rdparty/webkit/WebCore/page/animation/ImplicitAnimation.h index 33fe4e40ec..7e286d2f4f 100644 --- a/src/3rdparty/webkit/WebCore/page/animation/ImplicitAnimation.h +++ b/src/3rdparty/webkit/WebCore/page/animation/ImplicitAnimation.h @@ -66,6 +66,9 @@ public: void blendPropertyValueInStyle(int, RenderStyle* currentStyle); virtual double timeToNextService(); + + bool active() const { return m_active; } + void setActive(bool b) { m_active = b; } protected: bool shouldSendEventForListener(Document::ListenerType) const; @@ -80,6 +83,7 @@ private: int m_transitionProperty; // Transition property as specified in the RenderStyle. May be cAnimateAll int m_animatingProperty; // Specific property for this ImplicitAnimation bool m_overridden; // true when there is a keyframe animation that overrides the transitioning property + bool m_active; // used for culling the list of transitions // The two styles that we are blending. RefPtr<RenderStyle> m_fromStyle; diff --git a/src/3rdparty/webkit/WebCore/page/win/FrameCGWin.cpp b/src/3rdparty/webkit/WebCore/page/win/FrameCGWin.cpp index 8b0408de89..7483627ede 100644 --- a/src/3rdparty/webkit/WebCore/page/win/FrameCGWin.cpp +++ b/src/3rdparty/webkit/WebCore/page/win/FrameCGWin.cpp @@ -28,6 +28,7 @@ #include <windows.h> +#include "BitmapInfo.h" #include "FrameView.h" #include "GraphicsContext.h" #include "Settings.h" @@ -55,7 +56,7 @@ static HBITMAP imageFromRect(const Frame* frame, IntRect& ir) HDC hdc = CreateCompatibleDC(0); int w = ir.width(); int h = ir.height(); - BITMAPINFO bmp = { { sizeof(BITMAPINFOHEADER), w, h, 1, 32 } }; + BitmapInfo bmp = BitmapInfo::create(IntSize(w, h)); HBITMAP hbmp = CreateDIBSection(0, &bmp, DIB_RGB_COLORS, static_cast<void**>(&bits), 0, 0); HBITMAP hbmpOld = static_cast<HBITMAP>(SelectObject(hdc, hbmp)); |