diff options
author | Steve Block <steveblock@google.com> | 2010-02-02 14:57:50 +0000 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2010-02-04 15:06:55 +0000 |
commit | d0825bca7fe65beaee391d30da42e937db621564 (patch) | |
tree | 7461c49eb5844ffd1f35d1ba2c8b7584c1620823 /WebCore/page | |
parent | 3db770bd97c5a59b6c7574ca80a39e5a51c1defd (diff) | |
download | external_webkit-d0825bca7fe65beaee391d30da42e937db621564.zip external_webkit-d0825bca7fe65beaee391d30da42e937db621564.tar.gz external_webkit-d0825bca7fe65beaee391d30da42e937db621564.tar.bz2 |
Merge webkit.org at r54127 : Initial merge by git
Change-Id: Ib661abb595522f50ea406f72d3a0ce17f7193c82
Diffstat (limited to 'WebCore/page')
75 files changed, 1181 insertions, 795 deletions
diff --git a/WebCore/page/AbstractView.idl b/WebCore/page/AbstractView.idl index 36865de..290bf48 100644 --- a/WebCore/page/AbstractView.idl +++ b/WebCore/page/AbstractView.idl @@ -28,7 +28,8 @@ module views { // Introduced in DOM Level 2: interface [ - ObjCCustomImplementation + ObjCCustomImplementation, + OmitConstructor ] AbstractView { readonly attribute Document document; readonly attribute Media media; diff --git a/WebCore/page/BarInfo.cpp b/WebCore/page/BarInfo.cpp index 0f6cad5..b6ab686 100644 --- a/WebCore/page/BarInfo.cpp +++ b/WebCore/page/BarInfo.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2010 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -60,23 +60,25 @@ bool BarInfo::visible() const { if (!m_frame) return false; + Page* page = m_frame->page(); + if (!page) + return false; switch (m_type) { case Locationbar: - return m_frame->page()->chrome()->toolbarsVisible(); - case Toolbar: - return m_frame->page()->chrome()->toolbarsVisible(); case Personalbar: - return m_frame->page()->chrome()->toolbarsVisible(); + case Toolbar: + return page->chrome()->toolbarsVisible(); case Menubar: - return m_frame->page()->chrome()->menubarVisible(); + return page->chrome()->menubarVisible(); case Scrollbars: - return m_frame->page()->chrome()->scrollbarsVisible(); + return page->chrome()->scrollbarsVisible(); case Statusbar: - return m_frame->page()->chrome()->statusbarVisible(); - default: - return false; + return page->chrome()->statusbarVisible(); } + + ASSERT_NOT_REACHED(); + return false; } } // namespace WebCore diff --git a/WebCore/page/BarInfo.idl b/WebCore/page/BarInfo.idl index 42041c51..2089895 100644 --- a/WebCore/page/BarInfo.idl +++ b/WebCore/page/BarInfo.idl @@ -28,7 +28,7 @@ module window { - interface BarInfo { + interface [OmitConstructor] BarInfo { readonly attribute boolean visible; }; diff --git a/WebCore/page/Chrome.h b/WebCore/page/Chrome.h index 398548f..53dbb7a 100644 --- a/WebCore/page/Chrome.h +++ b/WebCore/page/Chrome.h @@ -138,7 +138,7 @@ namespace WebCore { bool setCursor(PlatformCursorHandle); -#if PLATFORM(MAC) && !ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE) +#if PLATFORM(MAC) void focusNSView(NSView*); #endif diff --git a/WebCore/page/Console.cpp b/WebCore/page/Console.cpp index b1b091a..2273a5e 100644 --- a/WebCore/page/Console.cpp +++ b/WebCore/page/Console.cpp @@ -30,6 +30,7 @@ #include "Console.h" #include "CString.h" +#include "Chrome.h" #include "ChromeClient.h" #include "ConsoleMessage.h" #include "Frame.h" diff --git a/WebCore/page/Console.idl b/WebCore/page/Console.idl index a31b605..b9c0a57 100644 --- a/WebCore/page/Console.idl +++ b/WebCore/page/Console.idl @@ -28,7 +28,7 @@ module window { - interface Console { + interface [OmitConstructor] Console { #if defined(ENABLE_JAVASCRIPT_DEBUGGER) && ENABLE_JAVASCRIPT_DEBUGGER readonly attribute [CustomGetter] Array profiles; diff --git a/WebCore/page/ContextMenuController.cpp b/WebCore/page/ContextMenuController.cpp index 726dee9..d384b02 100644 --- a/WebCore/page/ContextMenuController.cpp +++ b/WebCore/page/ContextMenuController.cpp @@ -31,7 +31,7 @@ #include "Chrome.h" #include "ContextMenu.h" #include "ContextMenuClient.h" -#include "ContextMenuSelectionHandler.h" +#include "ContextMenuProvider.h" #include "Document.h" #include "DocumentFragment.h" #include "DocumentLoader.h" @@ -67,7 +67,6 @@ ContextMenuController::ContextMenuController(Page* page, ContextMenuClient* clie : m_page(page) , m_client(client) , m_contextMenu(0) - , m_selectionHandler(0) { ASSERT_ARG(page, page); ASSERT_ARG(client, client); @@ -81,9 +80,9 @@ ContextMenuController::~ContextMenuController() void ContextMenuController::clearContextMenu() { m_contextMenu.set(0); - if (m_selectionHandler) - m_selectionHandler->contextMenuCleared(); - m_selectionHandler = 0; + if (m_menuProvider) + m_menuProvider->contextMenuCleared(); + m_menuProvider = 0; } void ContextMenuController::handleContextMenuEvent(Event* event) @@ -95,19 +94,17 @@ void ContextMenuController::handleContextMenuEvent(Event* event) showContextMenu(event); } -void ContextMenuController::showContextMenu(Event* event, Vector<ContextMenuItem>& items, PassRefPtr<ContextMenuSelectionHandler> selectionHandler) +void ContextMenuController::showContextMenu(Event* event, PassRefPtr<ContextMenuProvider> menuProvider) { - m_selectionHandler = selectionHandler; + m_menuProvider = menuProvider; m_contextMenu.set(createContextMenu(event)); if (!m_contextMenu) { clearContextMenu(); return; } - for (size_t i = 0; i < items.size(); ++i) { - ContextMenuItem& item = items[i]; - m_contextMenu->appendItem(item); - } + + m_menuProvider->populateContextMenu(m_contextMenu.get()); showContextMenu(event); } @@ -156,8 +153,8 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item) } if (item->action() >= ContextMenuItemBaseCustomTag) { - ASSERT(m_selectionHandler); - m_selectionHandler->contextMenuItemSelected(item); + ASSERT(m_menuProvider); + m_menuProvider->contextMenuItemSelected(item); return; } diff --git a/WebCore/page/ContextMenuController.h b/WebCore/page/ContextMenuController.h index d51bc70..833b909 100644 --- a/WebCore/page/ContextMenuController.h +++ b/WebCore/page/ContextMenuController.h @@ -30,14 +30,13 @@ #include <wtf/OwnPtr.h> #include <wtf/PassRefPtr.h> #include <wtf/RefPtr.h> -#include <wtf/Vector.h> namespace WebCore { class ContextMenu; class ContextMenuClient; class ContextMenuItem; - class ContextMenuSelectionHandler; + class ContextMenuProvider; class Event; class Page; @@ -52,7 +51,7 @@ namespace WebCore { void clearContextMenu(); void handleContextMenuEvent(Event*); - void showContextMenu(Event*, Vector<ContextMenuItem>&, PassRefPtr<ContextMenuSelectionHandler>); + void showContextMenu(Event*, PassRefPtr<ContextMenuProvider>); void contextMenuItemSelected(ContextMenuItem*); @@ -63,7 +62,7 @@ namespace WebCore { Page* m_page; ContextMenuClient* m_client; OwnPtr<ContextMenu> m_contextMenu; - RefPtr<ContextMenuSelectionHandler> m_selectionHandler; + RefPtr<ContextMenuProvider> m_menuProvider; }; } diff --git a/WebCore/page/ContextMenuSelectionHandler.h b/WebCore/page/ContextMenuProvider.h index d5a6631..57598d1 100644 --- a/WebCore/page/ContextMenuSelectionHandler.h +++ b/WebCore/page/ContextMenuProvider.h @@ -28,24 +28,25 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef ContextMenuSelectionHandler_h -#define ContextMenuSelectionHandler_h +#ifndef ContextMenuProvider_h +#define ContextMenuProvider_h #include <wtf/RefCounted.h> namespace WebCore { - class ContextMenuItem; +class ContextMenu; +class ContextMenuItem; - class ContextMenuSelectionHandler : public RefCounted<ContextMenuSelectionHandler> { - public: - ContextMenuSelectionHandler() { } - virtual ~ContextMenuSelectionHandler() { }; +class ContextMenuProvider : public RefCounted<ContextMenuProvider> { +public: + virtual ~ContextMenuProvider() { }; - virtual void contextMenuItemSelected(ContextMenuItem*) = 0; - virtual void contextMenuCleared() = 0; - }; + virtual void populateContextMenu(ContextMenu*) = 0; + virtual void contextMenuItemSelected(ContextMenuItem*) = 0; + virtual void contextMenuCleared() = 0; +}; } -#endif // ContextMenuSelectionHandler_h +#endif // ContextMenuProvider_h diff --git a/WebCore/page/Coordinates.idl b/WebCore/page/Coordinates.idl index f847325..5a5a141 100644 --- a/WebCore/page/Coordinates.idl +++ b/WebCore/page/Coordinates.idl @@ -25,7 +25,7 @@ module core { - interface Coordinates { + interface [OmitConstructor] Coordinates { readonly attribute double latitude; readonly attribute double longitude; readonly attribute [Custom] double altitude; diff --git a/WebCore/page/DOMSelection.idl b/WebCore/page/DOMSelection.idl index be6c2b4..4d0c942 100644 --- a/WebCore/page/DOMSelection.idl +++ b/WebCore/page/DOMSelection.idl @@ -31,7 +31,7 @@ module window { // This is based off of Mozilla's Selection interface // https://developer.mozilla.org/En/DOM/Selection - interface DOMSelection { + interface [OmitConstructor] DOMSelection { readonly attribute Node anchorNode; readonly attribute long anchorOffset; readonly attribute Node focusNode; diff --git a/WebCore/page/DOMWindow.cpp b/WebCore/page/DOMWindow.cpp index 757e32f..3eb2b8e 100644 --- a/WebCore/page/DOMWindow.cpp +++ b/WebCore/page/DOMWindow.cpp @@ -442,6 +442,10 @@ void DOMWindow::clear() if (m_location) m_location->disconnectFrame(); m_location = 0; + + if (m_media) + m_media->disconnectFrame(); + m_media = 0; #if ENABLE(DOM_STORAGE) if (m_sessionStorage) @@ -639,6 +643,13 @@ NotificationCenter* DOMWindow::webkitNotifications() const } #endif +#if ENABLE(INDEXED_DATABASE) +IndexedDatabaseRequest* DOMWindow::indexedDB() const +{ + return 0; +} +#endif + void DOMWindow::postMessage(PassRefPtr<SerializedScriptValue> message, MessagePort* port, const String& targetOrigin, DOMWindow* source, ExceptionCode& ec) { MessagePortArray ports; @@ -1053,7 +1064,9 @@ Document* DOMWindow::document() const PassRefPtr<Media> DOMWindow::media() const { - return Media::create(const_cast<DOMWindow*>(this)); + if (!m_media) + m_media = Media::create(m_frame); + return m_media.get(); } PassRefPtr<CSSStyleDeclaration> DOMWindow::getComputedStyle(Element* elt, const String&) const @@ -1081,7 +1094,9 @@ PassRefPtr<WebKitPoint> DOMWindow::webkitConvertPointFromNodeToPage(Node* node, { if (!node || !p) return 0; - + + m_frame->document()->updateLayoutIgnorePendingStylesheets(); + FloatPoint pagePoint(p->x(), p->y()); pagePoint = node->convertToPage(pagePoint); return WebKitPoint::create(pagePoint.x(), pagePoint.y()); @@ -1091,7 +1106,9 @@ PassRefPtr<WebKitPoint> DOMWindow::webkitConvertPointFromPageToNode(Node* node, { if (!node || !p) return 0; - + + m_frame->document()->updateLayoutIgnorePendingStylesheets(); + FloatPoint nodePoint(p->x(), p->y()); nodePoint = node->convertFromPage(nodePoint); return WebKitPoint::create(nodePoint.x(), nodePoint.y()); @@ -1237,24 +1254,40 @@ void DOMWindow::resizeTo(float width, float height) const page->chrome()->setWindowRect(fr); } -int DOMWindow::setTimeout(ScheduledAction* action, int timeout) +int DOMWindow::setTimeout(ScheduledAction* action, int timeout, ExceptionCode& ec) { - return DOMTimer::install(scriptExecutionContext(), action, timeout, true); + ScriptExecutionContext* context = scriptExecutionContext(); + if (!context) { + ec = INVALID_ACCESS_ERR; + return -1; + } + return DOMTimer::install(context, action, timeout, true); } void DOMWindow::clearTimeout(int timeoutId) { - DOMTimer::removeById(scriptExecutionContext(), timeoutId); + ScriptExecutionContext* context = scriptExecutionContext(); + if (!context) + return; + DOMTimer::removeById(context, timeoutId); } -int DOMWindow::setInterval(ScheduledAction* action, int timeout) +int DOMWindow::setInterval(ScheduledAction* action, int timeout, ExceptionCode& ec) { - return DOMTimer::install(scriptExecutionContext(), action, timeout, false); + ScriptExecutionContext* context = scriptExecutionContext(); + if (!context) { + ec = INVALID_ACCESS_ERR; + return -1; + } + return DOMTimer::install(context, action, timeout, false); } void DOMWindow::clearInterval(int timeoutId) { - DOMTimer::removeById(scriptExecutionContext(), timeoutId); + ScriptExecutionContext* context = scriptExecutionContext(); + if (!context) + return; + DOMTimer::removeById(context, timeoutId); } bool DOMWindow::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture) diff --git a/WebCore/page/DOMWindow.h b/WebCore/page/DOMWindow.h index 0aee619..dc1e68c 100644 --- a/WebCore/page/DOMWindow.h +++ b/WebCore/page/DOMWindow.h @@ -52,6 +52,7 @@ namespace WebCore { class FloatRect; class Frame; class History; + class IndexedDatabaseRequest; class InspectorTimelineAgent; class Location; class Media; @@ -216,6 +217,10 @@ namespace WebCore { NotificationCenter* webkitNotifications() const; #endif +#if ENABLE(INDEXED_DATABASE) + IndexedDatabaseRequest* indexedDB() const; +#endif + void postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray*, const String& targetOrigin, DOMWindow* source, ExceptionCode&); // FIXME: remove this when we update the ObjC bindings (bug #28774). void postMessage(PassRefPtr<SerializedScriptValue> message, MessagePort*, const String& targetOrigin, DOMWindow* source, ExceptionCode&); @@ -232,9 +237,9 @@ namespace WebCore { void resizeTo(float width, float height) const; // Timers - int setTimeout(ScheduledAction*, int timeout); + int setTimeout(ScheduledAction*, int timeout, ExceptionCode&); void clearTimeout(int timeoutId); - int setInterval(ScheduledAction*, int timeout); + int setInterval(ScheduledAction*, int timeout, ExceptionCode&); void clearInterval(int timeoutId); // Events @@ -345,6 +350,7 @@ namespace WebCore { Console* optionalConsole() const { return m_console.get(); } Navigator* optionalNavigator() const { return m_navigator.get(); } Location* optionalLocation() const { return m_location.get(); } + Media* optionalMedia() const { return m_media.get(); } #if ENABLE(DOM_STORAGE) Storage* optionalSessionStorage() const { return m_sessionStorage.get(); } Storage* optionalLocalStorage() const { return m_localStorage.get(); } @@ -381,6 +387,7 @@ namespace WebCore { mutable RefPtr<Console> m_console; mutable RefPtr<Navigator> m_navigator; mutable RefPtr<Location> m_location; + mutable RefPtr<Media> m_media; #if ENABLE(DOM_STORAGE) mutable RefPtr<Storage> m_sessionStorage; mutable RefPtr<Storage> m_localStorage; diff --git a/WebCore/page/DOMWindow.idl b/WebCore/page/DOMWindow.idl index 71d7ca4..626d9c4 100644 --- a/WebCore/page/DOMWindow.idl +++ b/WebCore/page/DOMWindow.idl @@ -37,8 +37,9 @@ module window { CustomMarkFunction, CustomNativeConverter, CustomPutFunction, - ExtendsDOMGlobalObject, EventTarget, + OmitConstructor, + ExtendsDOMGlobalObject, GenerateNativeConverter, LegacyParent=JSDOMWindowBase ] DOMWindow { @@ -169,6 +170,9 @@ module window { #if defined(ENABLE_NOTIFICATIONS) && ENABLE_NOTIFICATIONS readonly attribute [EnabledAtRuntime] NotificationCenter webkitNotifications; #endif +#if defined(ENABLE_INDEXED_DATABASE) && ENABLE_INDEXED_DATABASE + readonly attribute [EnabledAtRuntime] IndexedDatabaseRequest indexedDB; +#endif #if defined(ENABLE_ORIENTATION_EVENTS) && ENABLE_ORIENTATION_EVENTS // This is the interface orientation in degrees. Some examples are: @@ -274,7 +278,6 @@ module window { // attribute EventListener onbeforeprint; // attribute EventListener onformchange; // attribute EventListener onforminput; - // attribute EventListener onpopstate; // attribute EventListener onreadystatechange; // attribute EventListener onredo; // attribute EventListener onshow; @@ -478,6 +481,7 @@ module window { attribute FileConstructor File; attribute FileListConstructor FileList; + attribute BlobConstructor Blob; attribute NodeFilterConstructor NodeFilter; attribute RangeConstructor Range; @@ -544,32 +548,163 @@ module window { #endif #if defined(ENABLE_SVG) && ENABLE_SVG + // Expose all implemented SVG 1.1 interfaces, excluding the SVG MI interfaces: + // SVGAnimatedPathData, SVGAnimatedPoints, SVGExternalResourcesRequired, + // SVGFilterPrimitiveStandardAttributes, SVGFitToViewBox, SVGLangSpace, SVGLocatable + // SVGStylable, SVGTests, SVGTransformable, SVGURIReference, SVGZoomAndPan + attribute SVGAElementConstructor SVGAElement; attribute SVGAngleConstructor SVGAngle; + attribute SVGAnimatedAngleConstructor SVGAnimatedAngle; + attribute SVGAnimatedBooleanConstructor SVGAnimatedBoolean; + attribute SVGAnimatedEnumerationConstructor SVGAnimatedEnumeration; + attribute SVGAnimatedIntegerConstructor SVGAnimatedInteger; + attribute SVGAnimatedLengthConstructor SVGAnimatedLength; + attribute SVGAnimatedLengthListConstructor SVGAnimatedLengthList; + attribute SVGAnimatedNumberConstructor SVGAnimatedNumber; + attribute SVGAnimatedNumberListConstructor SVGAnimatedNumberList; + attribute SVGAnimatedPreserveAspectRatioConstructor SVGAnimatedPreserveAspectRatio; + attribute SVGAnimatedRectConstructor SVGAnimatedRect; + attribute SVGAnimatedStringConstructor SVGAnimatedString; + attribute SVGAnimatedTransformListConstructor SVGAnimatedTransformList; + attribute SVGCircleElementConstructor SVGCircleElement; + attribute SVGClipPathElementConstructor SVGClipPathElement; attribute SVGColorConstructor SVGColor; + attribute SVGCursorElementConstructor SVGCursorElement; // attribute SVGCSSRuleConstructor SVGCSSRule; + attribute SVGDefsElementConstructor SVGDefsElement; + attribute SVGDescElementConstructor SVGDescElement; + attribute SVGDocumentConstructor SVGDocument; + attribute SVGElementConstructor SVGElement; + attribute SVGElementInstanceConstructor SVGElementInstance; + attribute SVGElementInstanceListConstructor SVGElementInstanceList; + attribute SVGEllipseElementConstructor SVGEllipseElement; attribute SVGExceptionConstructor SVGException; + attribute SVGGElementConstructor SVGGElement; attribute SVGGradientElementConstructor SVGGradientElement; + attribute SVGImageElementConstructor SVGImageElement; attribute SVGLengthConstructor SVGLength; + attribute SVGLengthListConstructor SVGLengthList; + attribute SVGLinearGradientElementConstructor SVGLinearGradientElement; + attribute SVGLineElementConstructor SVGLineElement; attribute SVGMarkerElementConstructor SVGMarkerElement; + attribute SVGMaskElementConstructor SVGMaskElement; + attribute SVGMatrixConstructor SVGMatrix; + attribute SVGMetadataElementConstructor SVGMetadataElement; + attribute SVGNumberConstructor SVGNumber; + attribute SVGNumberListConstructor SVGNumberList; attribute SVGPaintConstructor SVGPaint; + attribute SVGPathElementConstructor SVGPathElement; attribute SVGPathSegConstructor SVGPathSeg; + attribute SVGPathSegArcAbsConstructor SVGPathSegArcAbs; + attribute SVGPathSegArcRelConstructor SVGPathSegArcRel; + attribute SVGPathSegClosePathConstructor SVGPathSegClosePath; + attribute SVGPathSegCurvetoCubicAbsConstructor SVGPathSegCurvetoCubicAbs; + attribute SVGPathSegCurvetoCubicRelConstructor SVGPathSegCurvetoCubicRel; + attribute SVGPathSegCurvetoCubicSmoothAbsConstructor SVGPathSegCurvetoCubicSmoothAbs; + attribute SVGPathSegCurvetoCubicSmoothRelConstructor SVGPathSegCurvetoCubicSmoothRel; + attribute SVGPathSegCurvetoQuadraticAbsConstructor SVGPathSegCurvetoQuadraticAbs; + attribute SVGPathSegCurvetoQuadraticRelConstructor SVGPathSegCurvetoQuadraticRel; + attribute SVGPathSegCurvetoQuadraticSmoothAbsConstructor SVGPathSegCurvetoQuadraticSmoothAbs; + attribute SVGPathSegCurvetoQuadraticSmoothRelConstructor SVGPathSegCurvetoQuadraticSmoothRel; + attribute SVGPathSegLinetoAbsConstructor SVGPathSegLinetoAbs; + attribute SVGPathSegLinetoHorizontalAbsConstructor SVGPathSegLinetoHorizontalAbs; + attribute SVGPathSegLinetoHorizontalRelConstructor SVGPathSegLinetoHorizontalRel; + attribute SVGPathSegLinetoRelConstructor SVGPathSegLinetoRel; + attribute SVGPathSegLinetoVerticalAbsConstructor SVGPathSegLinetoVerticalAbs; + attribute SVGPathSegLinetoVerticalRelConstructor SVGPathSegLinetoVerticalRel; + attribute SVGPathSegListConstructor SVGPathSegList; + attribute SVGPathSegMovetoAbsConstructor SVGPathSegMovetoAbs; + attribute SVGPathSegMovetoRelConstructor SVGPathSegMovetoRel; + attribute SVGPatternElementConstructor SVGPatternElement; + attribute SVGPointConstructor SVGPoint; + attribute SVGPointListConstructor SVGPointList; + attribute SVGPolygonElementConstructor SVGPolygonElement; + attribute SVGPolylineElementConstructor SVGPolylineElement; attribute SVGPreserveAspectRatioConstructor SVGPreserveAspectRatio; + attribute SVGRadialGradientElementConstructor SVGRadialGradientElement; + attribute SVGRectConstructor SVGRect; + attribute SVGRectElementConstructor SVGRectElement; attribute SVGRenderingIntentConstructor SVGRenderingIntent; + attribute SVGScriptElementConstructor SVGScriptElement; + attribute SVGStopElementConstructor SVGStopElement; + attribute SVGStringListConstructor SVGStringList; + attribute SVGStyleElementConstructor SVGStyleElement; + attribute SVGSVGElementConstructor SVGSVGElement; + attribute SVGSwitchElementConstructor SVGSwitchElement; + attribute SVGSymbolElementConstructor SVGSymbolElement; attribute SVGTextContentElementConstructor SVGTextContentElement; + attribute SVGTextElementConstructor SVGTextElement; attribute SVGTextPathElementConstructor SVGTextPathElement; + attribute SVGTextPositioningElementConstructor SVGTextPositioningElement; + attribute SVGTitleElementConstructor SVGTitleElement; attribute SVGTransformConstructor SVGTransform; + attribute SVGTransformListConstructor SVGTransformList; + attribute SVGTRefElementConstructor SVGTRefElement; + attribute SVGTSpanElementConstructor SVGTSpanElement; attribute SVGUnitTypesConstructor SVGUnitTypes; -// attribute SVGZoomAndPanConstructor SVGZoomAndPan; + attribute SVGUseElementConstructor SVGUseElement; + attribute SVGViewElementConstructor SVGViewElement; +// attribute SVGViewSpecConstructor SVGViewSpec; + attribute SVGZoomEventConstructor SVGZoomEvent; + +#if defined(ENABLE_SVG_ANIMATION) && ENABLE_SVG_ANIMATION + attribute SVGAnimateColorElementConstructor SVGAnimateColorElement; + attribute SVGAnimateElementConstructor SVGAnimateElement; +// attribute SVGAnimateMotionElementConstructor SVGAnimateMotionElement; + attribute SVGAnimateTransformElementConstructor SVGAnimateTransformElement; +// attribute SVGMPathElementConstructor SVGMPathElement; + attribute SVGSetElementConstructor SVGSetElement; +#endif + +#if ENABLE_SVG_FONTS && ENABLE_SVG_FONTS +// attribute SVGAltGlyphDefElementConstructor SVGAltGlyphDefElement; + attribute SVGAltGlyphElementConstructor SVGAltGlyphElement; +// attribute SVGAltGlyphItemElementConstructor SVGAltGlyphItemElement; +// attribute SVGDefinitionSrcElementConstructor SVGDefinitionSrcElement; + attribute SVGFontElementConstructor SVGFontElement; + attribute SVGFontFaceElementConstructor SVGFontFaceElement; + attribute SVGFontFaceFormatElementConstructor SVGFontFaceFormatElement; + attribute SVGFontFaceNameElementConstructor SVGFontFaceNameElement; + attribute SVGFontFaceSrcElementConstructor SVGFontFaceSrcElement; + attribute SVGFontFaceUriElementConstructor SVGFontFaceUriElement; + attribute SVGGlyphElementConstructor SVGGlyphElement; +// attribute SVGGlyphRefElementConstructor SVGGlyphRefElement; +// attribute SVGHKernElementConstructor SVGHKernElement; + attribute SVGMissingGlyphElementConstructor SVGMissingGlyphElement; +// attribute SVGVKernElementConstructor SVGVKernElement; +#endif + +#if defined(ENABLE_SVG_FOREIGN_OBJECT) && ENABLE_SVG_FOREIGN_OBJECT + attribute SVGForeignObjectElementConstructor SVGForeignObjectElement; +#endif #if defined(ENABLE_FILTERS) && ENABLE_FILTERS attribute SVGComponentTransferFunctionElementConstructor SVGComponentTransferFunctionElement; attribute SVGFEBlendElementConstructor SVGFEBlendElement; attribute SVGFEColorMatrixElementConstructor SVGFEColorMatrixElement; + attribute SVGFEComponentTransferElementConstructor SVGFEComponentTransferElement; attribute SVGFECompositeElementConstructor SVGFECompositeElement; // attribute SVGFEConvolveMatrixElementConstructor SVGFEConvolveMatrixElement; + attribute SVGFEDiffuseLightingElementConstructor SVGFEDiffuseLightingElement; attribute SVGFEDisplacementMapElementConstructor SVGFEDisplacementMapElement; + attribute SVGFEDistantLightElementConstructor SVGFEDistantLightElement; + attribute SVGFEFloodElementConstructor SVGFEFloodElement; + attribute SVGFEFuncAElementConstructor SVGFEFuncAElement; + attribute SVGFEFuncBElementConstructor SVGFEFuncBElement; + attribute SVGFEFuncGElementConstructor SVGFEFuncGElement; + attribute SVGFEFuncRElementConstructor SVGFEFuncRElement; + attribute SVGFEGaussianBlurElementConstructor SVGFEGaussianBlurElement; + attribute SVGFEImageElementConstructor SVGFEImageElement; + attribute SVGFEMergeElementConstructor SVGFEMergeElement; + attribute SVGFEMergeNodeElementConstructor SVGFEMergeNodeElement; attribute SVGFEMorphologyElementConstructor SVGFEMorphologyElement; + attribute SVGFEOffsetElementConstructor SVGFEOffsetElement; + attribute SVGFEPointLightElementConstructor SVGFEPointLightElement; + attribute SVGFESpecularLightingElementConstructor SVGFESpecularLightingElement; + attribute SVGFESpotLightElementConstructor SVGFESpotLightElement; + attribute SVGFETileElementConstructor SVGFETileElement; attribute SVGFETurbulenceElementConstructor SVGFETurbulenceElement; + attribute SVGFilterElementConstructor SVGFilterElement; #endif #endif diff --git a/WebCore/page/DragController.cpp b/WebCore/page/DragController.cpp index 634595a..bde38bc 100644 --- a/WebCore/page/DragController.cpp +++ b/WebCore/page/DragController.cpp @@ -482,21 +482,6 @@ bool DragController::canProcessDrag(DragData* dragData) return true; } -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); @@ -517,10 +502,8 @@ bool DragController::tryDHTMLDrag(DragData* dragData, DragOperation& operation) 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)) { + operation = clipboard->destinationOperation(); + if (!(srcOpMask & operation)) { // The element picked an operation which is not supported by the source operation = DragOperationNone; } diff --git a/WebCore/page/EventHandler.cpp b/WebCore/page/EventHandler.cpp index bdcd6aa..7d45285 100644 --- a/WebCore/page/EventHandler.cpp +++ b/WebCore/page/EventHandler.cpp @@ -29,6 +29,7 @@ #include "AXObjectCache.h" #include "CachedImage.h" +#include "Chrome.h" #include "ChromeClient.h" #include "Cursor.h" #include "Document.h" @@ -80,10 +81,13 @@ #include "TouchEvent.h" #endif +<<<<<<< HEAD #if defined(ANDROID_PLUGINS) #include "WebViewCore.h" #endif +======= +>>>>>>> webkit.org at r54127 namespace WebCore { using namespace HTMLNames; @@ -130,7 +134,7 @@ static inline void scrollAndAcceptEvent(float delta, ScrollDirection positiveDir e.accept(); } -#if !PLATFORM(MAC) +#if !PLATFORM(MAC) || ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE) inline bool EventHandler::eventLoopHandleMouseUp(const MouseEventWithHitTestResults&) { @@ -174,7 +178,7 @@ EventHandler::EventHandler(Frame* frame) , m_mouseDownTimestamp(0) , m_useLatchedWheelEventNode(false) , m_widgetIsLatched(false) -#if PLATFORM(MAC) +#if PLATFORM(MAC) && !ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE) , m_mouseDownView(nil) , m_sendingEventToSubview(false) , m_activationEventNumber(0) @@ -702,6 +706,14 @@ void EventHandler::autoscrollTimerFired(Timer<EventHandler>*) #if ENABLE(PAN_SCROLLING) +void EventHandler::startPanScrolling(RenderObject* renderer) +{ + m_panScrollInProgress = true; + m_panScrollButtonPressed = true; + handleAutoscroll(renderer); + invalidateClick(); +} + void EventHandler::updatePanScrollState() { FrameView* view = m_frame->view(); @@ -1201,25 +1213,6 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent) invalidateClick(); return true; } - - if (mouseEvent.button() == MiddleButton && !mev.isOverLink()) { - RenderObject* renderer = mev.targetNode()->renderer(); - - while (renderer && (!renderer->isBox() || !toRenderBox(renderer)->canBeScrolledAndHasScrollableArea())) { - if (!renderer->parent() && renderer->node() == renderer->document() && renderer->document()->ownerElement()) - renderer = renderer->document()->ownerElement()->renderer(); - else - renderer = renderer->parent(); - } - - if (renderer) { - m_panScrollInProgress = true; - m_panScrollButtonPressed = true; - handleAutoscroll(renderer); - invalidateClick(); - return true; - } - } #endif m_clickCount = mouseEvent.clickCount(); @@ -1631,7 +1624,7 @@ void EventHandler::clearDragState() m_dragTarget = 0; m_capturingMouseEventsNode = 0; m_shouldOnlyFireDragOverEvent = false; -#if PLATFORM(MAC) +#if PLATFORM(MAC) && !ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE) m_sendingEventToSubview = false; #endif } @@ -1804,7 +1797,7 @@ bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targe return swallowEvent; } -#if !PLATFORM(GTK) && !(PLATFORM(CHROMIUM) && PLATFORM(LINUX)) +#if !PLATFORM(GTK) && !(PLATFORM(CHROMIUM) && OS(LINUX)) bool EventHandler::shouldTurnVerticalTicksIntoHorizontal(const HitTestResult&) const { return false; @@ -2317,9 +2310,11 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event) return !mouseDownMayStartSelect() && !m_mouseDownMayStartAutoscroll; // We are starting a text/image/url drag, so the cursor should be an arrow - if (FrameView* view = m_frame->view()) + if (FrameView* view = m_frame->view()) { + // FIXME <rdar://7577595>: Custom cursors aren't supported during drag and drop (default to pointer). view->setCursor(pointerCursor()); - + } + if (!dragHysteresisExceeded(event.event().pos())) return true; @@ -2358,7 +2353,7 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event) if (m_mouseDownMayStartDrag) { // gather values from DHTML element, if it set any - dragState().m_dragClipboard->sourceOperation(srcOp); + srcOp = dragState().m_dragClipboard->sourceOperation(); // Yuck, a draggedImage:moveTo: message can be fired as a result of kicking off the // drag with dragImage! Because of that dumb reentrancy, we may think we've not @@ -2560,6 +2555,7 @@ void EventHandler::updateLastScrollbarUnderMouse(Scrollbar* scrollbar, bool setL } #if ENABLE(TOUCH_EVENTS) +<<<<<<< HEAD #if PLATFORM(ANDROID) // TODO(benm): On Android we return an int back to Java to signify whether the default actions // for longpress/doubletap in the Browser should be prevented. I think that before upstreaming @@ -2568,6 +2564,9 @@ int EventHandler::handleTouchEvent(const PlatformTouchEvent& event) #else bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event) #endif +======= +bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event) +>>>>>>> webkit.org at r54127 { RefPtr<TouchList> touches = TouchList::create(); RefPtr<TouchList> pressedTouches = TouchList::create(); @@ -2603,17 +2602,26 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event) int adjustedPageX = lroundf(pagePoint.x() / m_frame->pageZoomFactor()); int adjustedPageY = lroundf(pagePoint.y() / m_frame->pageZoomFactor()); +<<<<<<< HEAD if ((event.type() == TouchStart #if PLATFORM(ANDROID) || event.type() == TouchDoubleTap || event.type() == TouchLongPress #endif ) && !i) { +======= + RefPtr<Touch> touch = Touch::create(doc->frame(), target, point.id(), + point.screenPos().x(), point.screenPos().y(), + adjustedPageX, adjustedPageY); + + if (event.type() == TouchStart && !i) { +>>>>>>> webkit.org at r54127 m_touchEventTarget = target; m_firstTouchScreenPos = point.screenPos(); m_firstTouchPagePos = pagePoint; } +<<<<<<< HEAD // ANDROID // The touch event should act on m_touchEventTarget, not target // TODO: Upstream this fix to webkit.org @@ -2621,6 +2629,8 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event) point.screenPos().x(), point.screenPos().y(), adjustedPageX, adjustedPageY); +======= +>>>>>>> webkit.org at r54127 if (point.state() == PlatformTouchPoint::TouchReleased) releasedTouches->append(touch); else if (point.state() == PlatformTouchPoint::TouchCancelled) @@ -2639,6 +2649,7 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event) } if (!m_touchEventTarget) +<<<<<<< HEAD #if PLATFORM(ANDROID) return 0; #else @@ -2652,6 +2663,11 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event) bool longPressPrevented = false; bool doubleTapPrevented = false; #endif +======= + return false; + + bool defaultPrevented = false; +>>>>>>> webkit.org at r54127 if (event.type() == TouchCancel) { eventName = &eventNames().touchcancelEvent; @@ -2662,9 +2678,13 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event) m_firstTouchPagePos.x(), m_firstTouchPagePos.y(), event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey()); +<<<<<<< HEAD #if PLATFORM(ANDROID) cancelEv->setCreateTime(static_cast<DOMTimeStamp>(event.eventTime())); #endif +======= + +>>>>>>> webkit.org at r54127 ExceptionCode ec = 0; m_touchEventTarget->dispatchEvent(cancelEv.get(), ec); defaultPrevented |= cancelEv->defaultPrevented(); @@ -2679,6 +2699,7 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event) m_firstTouchPagePos.x(), m_firstTouchPagePos.y(), event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey()); +<<<<<<< HEAD #if PLATFORM(ANDROID) endEv->setCreateTime(static_cast<DOMTimeStamp>(event.eventTime())); #endif @@ -2689,6 +2710,11 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event) #else defaultPrevented = endEv->defaultPrevented(); #endif +======= + ExceptionCode ec = 0; + m_touchEventTarget->dispatchEvent(endEv.get(), ec); + defaultPrevented = endEv->defaultPrevented(); +>>>>>>> webkit.org at r54127 } if (pressedTouches->length() > 0) { // Add pressed touchpoints to touches and targetTouches @@ -2698,6 +2724,7 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event) targetTouches->append(pressedTouches->item(i)); } +<<<<<<< HEAD #if PLATFORM(ANDROID) if (event.type() == TouchLongPress) { eventName = &eventNames().touchlongpressEvent; @@ -2750,6 +2777,20 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event) #endif } +======= + eventName = &eventNames().touchstartEvent; + RefPtr<TouchEvent> startEv = + TouchEvent::create(touches.get(), targetTouches.get(), pressedTouches.get(), + *eventName, m_touchEventTarget->document()->defaultView(), + m_firstTouchScreenPos.x(), m_firstTouchScreenPos.y(), + m_firstTouchPagePos.x(), m_firstTouchPagePos.y(), + event.ctrlKey(), event.altKey(), event.shiftKey(), + event.metaKey()); + ExceptionCode ec = 0; + m_touchEventTarget->dispatchEvent(startEv.get(), ec); + defaultPrevented |= startEv->defaultPrevented(); + } +>>>>>>> webkit.org at r54127 if (movedTouches->length() > 0) { eventName = &eventNames().touchmoveEvent; RefPtr<TouchEvent> moveEv = @@ -2759,9 +2800,12 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event) m_firstTouchPagePos.x(), m_firstTouchPagePos.y(), event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey()); +<<<<<<< HEAD #if PLATFORM(ANDROID) moveEv->setCreateTime(static_cast<DOMTimeStamp>(event.eventTime())); #endif +======= +>>>>>>> webkit.org at r54127 ExceptionCode ec = 0; m_touchEventTarget->dispatchEvent(moveEv.get(), ec); defaultPrevented |= moveEv->defaultPrevented(); @@ -2770,6 +2814,7 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event) if (event.type() == TouchEnd || event.type() == TouchCancel) m_touchEventTarget = 0; +<<<<<<< HEAD #if PLATFORM(ANDROID) // TODO (benm): We should be able to remove this prior to upstreaming once Java side refactorings to make // preventDefault work better are complete. @@ -2782,6 +2827,9 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event) #else return defaultPrevented; #endif +======= + return defaultPrevented; +>>>>>>> webkit.org at r54127 } #endif diff --git a/WebCore/page/EventHandler.h b/WebCore/page/EventHandler.h index 8ccd761..ead384c 100644 --- a/WebCore/page/EventHandler.h +++ b/WebCore/page/EventHandler.h @@ -98,6 +98,7 @@ public: Node* mousePressNode() const; void setMousePressNode(PassRefPtr<Node>); + void startPanScrolling(RenderObject*); bool panScrollInProgress() { return m_panScrollInProgress; } void setPanScrollInProgress(bool inProgress) { m_panScrollInProgress = inProgress; } @@ -205,12 +206,17 @@ public: #endif #if ENABLE(TOUCH_EVENTS) +<<<<<<< HEAD #if PLATFORM(ANDROID) int handleTouchEvent(const PlatformTouchEvent&); #else bool handleTouchEvent(const PlatformTouchEvent&); #endif #endif +======= + bool handleTouchEvent(const PlatformTouchEvent&); +#endif +>>>>>>> webkit.org at r54127 private: #if ENABLE(DRAG_SUPPORT) @@ -424,7 +430,10 @@ private: IntPoint m_firstTouchScreenPos; IntPoint m_firstTouchPagePos; #endif +<<<<<<< HEAD +======= +>>>>>>> webkit.org at r54127 }; } // namespace WebCore diff --git a/WebCore/page/EventSource.cpp b/WebCore/page/EventSource.cpp index 2c9a343..0c79998 100644 --- a/WebCore/page/EventSource.cpp +++ b/WebCore/page/EventSource.cpp @@ -57,6 +57,7 @@ EventSource::EventSource(const String& url, ScriptExecutionContext* context, Exc : ActiveDOMObject(context, this) , m_state(CONNECTING) , m_reconnectTimer(this, &EventSource::reconnectTimerFired) + , m_discardTrailingNewline(false) , m_failSilently(false) , m_requestInFlight(false) , m_reconnectDelay(defaultReconnectDelay) @@ -210,21 +211,24 @@ void EventSource::parseEventStream() { unsigned int bufPos = 0; unsigned int bufSize = m_receiveBuf.size(); - for (;;) { + while (bufPos < bufSize) { + if (m_discardTrailingNewline) { + if (m_receiveBuf[bufPos] == '\n') + bufPos++; + m_discardTrailingNewline = false; + } + 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 '\r': + m_discardTrailingNewline = true; case '\n': - if (i > bufPos && m_receiveBuf[i - 1] == '\r') { - carriageReturn++; - i--; - } lineLength = i - bufPos; break; } @@ -234,7 +238,7 @@ void EventSource::parseEventStream() break; parseEventStreamLine(bufPos, fieldLength, lineLength); - bufPos += lineLength + carriageReturn + 1; + bufPos += lineLength + 1; } if (bufPos == bufSize) diff --git a/WebCore/page/EventSource.h b/WebCore/page/EventSource.h index c7ff2c9..d0d45cb 100644 --- a/WebCore/page/EventSource.h +++ b/WebCore/page/EventSource.h @@ -114,6 +114,7 @@ namespace WebCore { RefPtr<ThreadableLoader> m_loader; Timer<EventSource> m_reconnectTimer; Vector<UChar> m_receiveBuf; + bool m_discardTrailingNewline; bool m_failSilently; bool m_requestInFlight; diff --git a/WebCore/page/EventSource.idl b/WebCore/page/EventSource.idl index 561bd68..ec42556 100644 --- a/WebCore/page/EventSource.idl +++ b/WebCore/page/EventSource.idl @@ -33,6 +33,7 @@ module window { interface [ Conditional=EVENTSOURCE, + CustomConstructor, EventTarget, NoStaticTables ] EventSource { diff --git a/WebCore/page/FocusController.cpp b/WebCore/page/FocusController.cpp index 5e78c7d..bdd3151 100644 --- a/WebCore/page/FocusController.cpp +++ b/WebCore/page/FocusController.cpp @@ -38,8 +38,8 @@ #include "EventNames.h" #include "ExceptionCode.h" #include "Frame.h" -#include "FrameView.h" #include "FrameTree.h" +#include "FrameView.h" #include "HTMLFrameOwnerElement.h" #include "HTMLNames.h" #include "KeyboardEvent.h" @@ -72,14 +72,17 @@ FocusController::FocusController(Page* page) : m_page(page) , m_isActive(false) , m_isFocused(false) + , m_isChangingFocusedFrame(false) { } void FocusController::setFocusedFrame(PassRefPtr<Frame> frame) { - if (m_focusedFrame == frame) + if (m_focusedFrame == frame || m_isChangingFocusedFrame) return; + m_isChangingFocusedFrame = true; + RefPtr<Frame> oldFrame = m_focusedFrame; RefPtr<Frame> newFrame = frame; @@ -95,6 +98,8 @@ void FocusController::setFocusedFrame(PassRefPtr<Frame> frame) newFrame->selection()->setFocused(true); newFrame->document()->dispatchWindowEvent(Event::create(eventNames().focusEvent, false, false)); } + + m_isChangingFocusedFrame = false; } Frame* FocusController::focusedOrMainFrame() diff --git a/WebCore/page/FocusController.h b/WebCore/page/FocusController.h index d86408a..32d4060 100644 --- a/WebCore/page/FocusController.h +++ b/WebCore/page/FocusController.h @@ -33,36 +33,37 @@ namespace WebCore { - class Frame; - class KeyboardEvent; - class Node; - class Page; +class Frame; +class KeyboardEvent; +class Node; +class Page; - class FocusController : public Noncopyable { - public: - FocusController(Page*); +class FocusController : public Noncopyable { +public: + FocusController(Page*); - void setFocusedFrame(PassRefPtr<Frame>); - Frame* focusedFrame() const { return m_focusedFrame.get(); } - Frame* focusedOrMainFrame(); + void setFocusedFrame(PassRefPtr<Frame>); + Frame* focusedFrame() const { return m_focusedFrame.get(); } + Frame* focusedOrMainFrame(); - bool setInitialFocus(FocusDirection, KeyboardEvent*); - bool advanceFocus(FocusDirection, KeyboardEvent*, bool initialFocus = false); + bool setInitialFocus(FocusDirection, KeyboardEvent*); + bool advanceFocus(FocusDirection, KeyboardEvent*, bool initialFocus = false); - bool setFocusedNode(Node*, PassRefPtr<Frame>); + bool setFocusedNode(Node*, PassRefPtr<Frame>); - void setActive(bool); - bool isActive() const { return m_isActive; } + void setActive(bool); + bool isActive() const { return m_isActive; } - void setFocused(bool); - bool isFocused() const { return m_isFocused; } + void setFocused(bool); + bool isFocused() const { return m_isFocused; } - private: - Page* m_page; - RefPtr<Frame> m_focusedFrame; - bool m_isActive; - bool m_isFocused; - }; +private: + Page* m_page; + RefPtr<Frame> m_focusedFrame; + bool m_isActive; + bool m_isFocused; + bool m_isChangingFocusedFrame; +}; } // namespace WebCore diff --git a/WebCore/page/Frame.cpp b/WebCore/page/Frame.cpp index 7e81b3d..947cb06 100644 --- a/WebCore/page/Frame.cpp +++ b/WebCore/page/Frame.cpp @@ -36,6 +36,7 @@ #include "CSSProperty.h" #include "CSSPropertyNames.h" #include "CachedCSSStyleSheet.h" +#include "Chrome.h" #include "DOMWindow.h" #include "DocLoader.h" #include "DocumentType.h" @@ -74,6 +75,7 @@ #include "TextIterator.h" #include "TextResourceDecoder.h" #include "UserContentURLPattern.h" +#include "XMLNSNames.h" #include "XMLNames.h" #include "htmlediting.h" #include "markup.h" @@ -82,7 +84,7 @@ #include <wtf/RefCountedLeakCounter.h> #include <wtf/StdLibExtras.h> -#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN)) +#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN)) #import <Carbon/Carbon.h> #endif @@ -136,7 +138,6 @@ Frame::Frame(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient* , m_script(this) , m_selectionGranularity(CharacterGranularity) , m_selectionController(this) - , m_caretBlinkTimer(this, &Frame::caretBlinkTimerFired) , m_editor(this) , m_eventHandler(this) , m_animationController(this) @@ -144,8 +145,6 @@ Frame::Frame(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient* #if ENABLE(ORIENTATION_EVENTS) , m_orientation(0) #endif - , m_caretVisible(false) - , m_caretPaint(true) , m_highlightTextMatches(false) , m_inViewSourceMode(false) , m_needsReapplyStyles(false) @@ -173,6 +172,7 @@ Frame::Frame(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient* MathMLNames::init(); #endif + XMLNSNames::init(); XMLNames::init(); if (!ownerElement) @@ -419,7 +419,7 @@ static RegularExpression* createRegExpForLabels(const Vector<String>& labels) return new RegularExpression(pattern, TextCaseInsensitive); } -String Frame::searchForLabelsAboveCell(RegularExpression* regExp, HTMLTableCellElement* cell) +String Frame::searchForLabelsAboveCell(RegularExpression* regExp, HTMLTableCellElement* cell, size_t* resultDistanceFromStartOfCell) { RenderObject* cellRenderer = cell->renderer(); @@ -433,23 +433,30 @@ String Frame::searchForLabelsAboveCell(RegularExpression* regExp, HTMLTableCellE if (aboveCell) { // search within the above cell we found for a match + size_t lengthSearched = 0; for (Node* n = aboveCell->firstChild(); n; n = n->traverseNextNode(aboveCell)) { if (n->isTextNode() && n->renderer() && n->renderer()->style()->visibility() == VISIBLE) { // For each text chunk, run the regexp String nodeString = n->nodeValue(); int pos = regExp->searchRev(nodeString); - if (pos >= 0) + if (pos >= 0) { + if (resultDistanceFromStartOfCell) + *resultDistanceFromStartOfCell = lengthSearched; return nodeString.substring(pos, regExp->matchedLength()); + } + lengthSearched += nodeString.length(); } } } } } // Any reason in practice to search all cells in that are above cell? + if (resultDistanceFromStartOfCell) + *resultDistanceFromStartOfCell = notFound; return String(); } -String Frame::searchForLabelsBeforeElement(const Vector<String>& labels, Element* element) +String Frame::searchForLabelsBeforeElement(const Vector<String>& labels, Element* element, size_t* resultDistance, bool* resultIsInCellAbove) { OwnPtr<RegularExpression> regExp(createRegExpForLabels(labels)); // We stop searching after we've seen this many chars @@ -461,6 +468,11 @@ String Frame::searchForLabelsBeforeElement(const Vector<String>& labels, Element HTMLTableCellElement* startingTableCell = 0; bool searchedCellAbove = false; + if (resultDistance) + *resultDistance = notFound; + if (resultIsInCellAbove) + *resultIsInCellAbove = false; + // walk backwards in the node tree, until another element, or form, or end of tree int unsigned lengthSearched = 0; Node* n; @@ -476,9 +488,12 @@ String Frame::searchForLabelsBeforeElement(const Vector<String>& labels, Element } else if (n->hasTagName(tdTag) && !startingTableCell) { startingTableCell = static_cast<HTMLTableCellElement*>(n); } else if (n->hasTagName(trTag) && startingTableCell) { - String result = searchForLabelsAboveCell(regExp.get(), startingTableCell); - if (!result.isEmpty()) + String result = searchForLabelsAboveCell(regExp.get(), startingTableCell, resultDistance); + if (!result.isEmpty()) { + if (resultIsInCellAbove) + *resultIsInCellAbove = true; return result; + } searchedCellAbove = true; } else if (n->isTextNode() && n->renderer() && n->renderer()->style()->visibility() == VISIBLE) { // For each text chunk, run the regexp @@ -487,38 +502,48 @@ String Frame::searchForLabelsBeforeElement(const Vector<String>& labels, Element if (lengthSearched + nodeString.length() > maxCharsSearched) nodeString = nodeString.right(charsSearchedThreshold - lengthSearched); int pos = regExp->searchRev(nodeString); - if (pos >= 0) + if (pos >= 0) { + if (resultDistance) + *resultDistance = lengthSearched; return nodeString.substring(pos, regExp->matchedLength()); + } lengthSearched += nodeString.length(); } } // If we started in a cell, but bailed because we found the start of the form or the // previous element, we still might need to search the row above us for a label. - if (startingTableCell && !searchedCellAbove) - return searchForLabelsAboveCell(regExp.get(), startingTableCell); + if (startingTableCell && !searchedCellAbove) { + String result = searchForLabelsAboveCell(regExp.get(), startingTableCell, resultDistance); + if (!result.isEmpty()) { + if (resultIsInCellAbove) + *resultIsInCellAbove = true; + return result; + } + } return String(); } -String Frame::matchLabelsAgainstElement(const Vector<String>& labels, Element* element) +static String matchLabelsAgainstString(const Vector<String>& labels, const String& stringToMatch) { - String name = element->getAttribute(nameAttr); - if (name.isEmpty()) + if (stringToMatch.isEmpty()) return String(); - // Make numbers and _'s in field names behave like word boundaries, e.g., "address2" - replace(name, RegularExpression("\\d", TextCaseSensitive), " "); - name.replace('_', ' '); + String mutableStringToMatch = stringToMatch; + // Make numbers and _'s in field names behave like word boundaries, e.g., "address2" + replace(mutableStringToMatch, RegularExpression("\\d", TextCaseSensitive), " "); + mutableStringToMatch.replace('_', ' '); + OwnPtr<RegularExpression> regExp(createRegExpForLabels(labels)); - // Use the largest match we can find in the whole name string + // Use the largest match we can find in the whole string int pos; int length; int bestPos = -1; int bestLength = -1; int start = 0; do { - pos = regExp->match(name, start); + pos = regExp->match(mutableStringToMatch, start); if (pos != -1) { length = regExp->matchedLength(); if (length >= bestLength) { @@ -528,11 +553,24 @@ String Frame::matchLabelsAgainstElement(const Vector<String>& labels, Element* e start = pos + 1; } } while (pos != -1); - + if (bestPos != -1) - return name.substring(bestPos, bestLength); + return mutableStringToMatch.substring(bestPos, bestLength); return String(); } + +String Frame::matchLabelsAgainstElement(const Vector<String>& labels, Element* element) +{ + // Match against the name element, then against the id element if no match is found for the name element. + // See 7538330 for one popular site that benefits from the id element check. + // FIXME: This code is mirrored in FrameMac.mm. It would be nice to make the Mac code call the platform-agnostic + // code, which would require converting the NSArray of NSStrings to a Vector of Strings somewhere along the way. + String resultFromNameAttribute = matchLabelsAgainstString(labels, element->getAttribute(nameAttr)); + if (!resultFromNameAttribute.isEmpty()) + return resultFromNameAttribute; + + return matchLabelsAgainstString(labels, element->getAttribute(idAttr)); +} const VisibleSelection& Frame::mark() const { @@ -560,31 +598,6 @@ void Frame::notifyRendererOfSelectionChange(bool userTriggered) toRenderTextControl(renderer)->selectionChanged(userTriggered); } -void Frame::invalidateSelection() -{ - selection()->setNeedsLayout(); - selectionLayoutChanged(); -} - -void Frame::setCaretVisible(bool flag) -{ - if (m_caretVisible == flag) - return; - clearCaretRectIfNeeded(); - m_caretVisible = flag; - selectionLayoutChanged(); -} - -void Frame::clearCaretRectIfNeeded() -{ -#if ENABLE(TEXT_CARET) - if (m_caretPaint) { - m_caretPaint = false; - selection()->invalidateCaretRect(); - } -#endif -} - // Helper function that tells whether a particular node is an element that has an entire // Frame and FrameView, a <frame>, <iframe>, or <object>. static bool isFrameElement(const Node *n) @@ -637,87 +650,6 @@ void Frame::setFocusedNodeIfNeeded() page()->focusController()->setFocusedNode(0, this); } -void Frame::selectionLayoutChanged() -{ - bool caretRectChanged = selection()->recomputeCaretRect(); - -#if ENABLE(TEXT_CARET) - bool caretBrowsing = settings() && settings()->caretBrowsingEnabled(); - bool shouldBlink = m_caretVisible - && selection()->isCaret() && (selection()->isContentEditable() || caretBrowsing); - - // If the caret moved, stop the blink timer so we can restart with a - // black caret in the new location. - if (caretRectChanged || !shouldBlink) - m_caretBlinkTimer.stop(); - - // 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 = page()->theme()->caretBlinkInterval()) - m_caretBlinkTimer.startRepeating(blinkInterval); - - if (!m_caretPaint) { - m_caretPaint = true; - selection()->invalidateCaretRect(); - } - } -#else - if (!caretRectChanged) - return; -#endif - - RenderView* view = contentRenderer(); - if (!view) - return; - - VisibleSelection selection = this->selection()->selection(); - - if (!selection.isRange()) - view->clearSelection(); - else { - // Use the rightmost candidate for the start of the selection, and the leftmost candidate for the end of the selection. - // Example: foo <a>bar</a>. Imagine that a line wrap occurs after 'foo', and that 'bar' is selected. If we pass [foo, 3] - // as the start of the selection, the selection painting code will think that content on the line containing 'foo' is selected - // and will fill the gap before 'bar'. - Position startPos = selection.start(); - if (startPos.downstream().isCandidate()) - startPos = startPos.downstream(); - Position endPos = selection.end(); - if (endPos.upstream().isCandidate()) - endPos = endPos.upstream(); - - // We can get into a state where the selection endpoints map to the same VisiblePosition when a selection is deleted - // because we don't yet notify the SelectionController of text removal. - if (startPos.isNotNull() && endPos.isNotNull() && selection.visibleStart() != selection.visibleEnd()) { - RenderObject *startRenderer = startPos.node()->renderer(); - RenderObject *endRenderer = endPos.node()->renderer(); - view->setSelection(startRenderer, startPos.deprecatedEditingOffset(), endRenderer, endPos.deprecatedEditingOffset()); - } - } -} - -void Frame::caretBlinkTimerFired(Timer<Frame>*) -{ -#if ENABLE(TEXT_CARET) - ASSERT(m_caretVisible); - ASSERT(selection()->isCaret()); - bool caretPaint = m_caretPaint; - if (selection()->isCaretBlinkingSuspended() && caretPaint) - return; - m_caretPaint = !caretPaint; - selection()->invalidateCaretRect(); -#endif -} - -void Frame::paintCaret(GraphicsContext* p, int tx, int ty, const IntRect& clipRect) const -{ -#if ENABLE(TEXT_CARET) - if (m_caretPaint && m_caretVisible) - selection()->paintCaret(p, tx, ty, clipRect); -#endif -} - void Frame::paintDragCaret(GraphicsContext* p, int tx, int ty, const IntRect& clipRect) const { #if ENABLE(TEXT_CARET) @@ -779,6 +711,13 @@ void Frame::setZoomFactor(float percent, bool isTextOnly) } #endif + if (!isTextOnly) { + // Update the scroll position when doing a full page zoom, so the content stays in relatively the same position. + IntPoint scrollPosition = view()->scrollPosition(); + float percentDifference = (percent / m_zoomFactor); + view()->setScrollPosition(IntPoint(scrollPosition.x() * percentDifference, scrollPosition.y() * percentDifference)); + } + m_zoomFactor = percent; m_page->settings()->setZoomsTextOnly(isTextOnly); @@ -922,12 +861,12 @@ bool Frame::isContentEditable() const return m_doc->inDesignMode(); } -#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN)) +#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN)) const short enableRomanKeyboardsOnly = -23; #endif void Frame::setUseSecureKeyboardEntry(bool enable) { -#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN)) +#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN)) if (enable == IsSecureEventInputEnabled()) return; if (enable) { @@ -1570,12 +1509,6 @@ unsigned Frame::markAllMatchesForText(const String& target, bool caseFlag, unsig continue; } - // A non-collapsed result range can in some funky whitespace cases still not - // advance the range's start position (4509328). Break to avoid infinite loop. - VisiblePosition newStart = endVisiblePosition(resultRange.get(), DOWNSTREAM); - if (newStart == startVisiblePosition(searchRange.get(), DOWNSTREAM)) - break; - // Only treat the result as a match if it is visible if (editor()->insideVisibleArea(resultRange.get())) { ++matchCount; @@ -1586,7 +1519,12 @@ unsigned Frame::markAllMatchesForText(const String& target, bool caseFlag, unsig if (limit > 0 && matchCount >= limit) break; - setStart(searchRange.get(), newStart); + // Set the new start for the search range to be the end of the previous + // result range. There is no need to use a VisiblePosition here, + // since findPlainText will use a TextIterator to go over the visible + // text nodes. + searchRange->setStart(resultRange->endContainer(exception), resultRange->endOffset(exception), exception); + Node* shadowTreeRoot = searchRange->shadowTreeRootNode(); if (searchRange->collapsed(exception) && shadowTreeRoot) searchRange->setEnd(shadowTreeRoot, shadowTreeRoot->childNodeCount(), exception); diff --git a/WebCore/page/Frame.h b/WebCore/page/Frame.h index ca9a6d4..33bb435 100644 --- a/WebCore/page/Frame.h +++ b/WebCore/page/Frame.h @@ -29,18 +29,14 @@ #define Frame_h #include "AnimationController.h" -#include "Document.h" #include "DragImage.h" -#include "EditAction.h" #include "Editor.h" #include "EventHandler.h" #include "FrameLoader.h" #include "FrameTree.h" -#include "Range.h" #include "ScriptController.h" #include "ScrollBehavior.h" #include "SelectionController.h" -#include "TextGranularity.h" #include "UserScriptTypes.h" #if PLATFORM(WIN) @@ -64,24 +60,8 @@ typedef struct HBITMAP__* HBITMAP; namespace WebCore { class CSSMutableStyleDeclaration; - class Editor; - class EventHandler; - class FrameLoader; - class RedirectScheduler; - class FrameLoaderClient; - class FrameTree; - class FrameView; - class HTMLFrameOwnerElement; class HTMLTableCellElement; class RegularExpression; - class RenderPart; - class ScriptController; - class SelectionController; - class Settings; - class VisibleSelection; - class Widget; - - template <typename T> class Timer; class Frame : public RefCounted<Frame> { public: @@ -254,15 +234,9 @@ namespace WebCore { bool shouldChangeSelection(const VisibleSelection&) const; bool shouldDeleteSelection(const VisibleSelection&) const; - void clearCaretRectIfNeeded(); void setFocusedNodeIfNeeded(); - void selectionLayoutChanged(); void notifyRendererOfSelectionChange(bool userTriggered); - void invalidateSelection(); - - void setCaretVisible(bool = true); - void paintCaret(GraphicsContext*, int tx, int ty, const IntRect& clipRect) const; void paintDragCaret(GraphicsContext*, int tx, int ty, const IntRect& clipRect) const; bool isContentEditable() const; // if true, everything in frame is editable @@ -284,14 +258,10 @@ namespace WebCore { void setUseSecureKeyboardEntry(bool); - private: - void caretBlinkTimerFired(Timer<Frame>*); - - public: SelectionController* dragCaretController() const; - String searchForLabelsAboveCell(RegularExpression*, HTMLTableCellElement*); - String searchForLabelsBeforeElement(const Vector<String>& labels, Element*); + String searchForLabelsAboveCell(RegularExpression*, HTMLTableCellElement*, size_t* resultDistanceFromStartOfCell); + String searchForLabelsBeforeElement(const Vector<String>& labels, Element*, size_t* resultDistance, bool* resultIsInCellAbove); String matchLabelsAgainstElement(const Vector<String>& labels, Element*); VisiblePosition visiblePositionForPoint(const IntPoint& framePoint); @@ -302,8 +272,8 @@ namespace WebCore { // === undecided, would like to consider moving to another class public: - NSString* searchForNSLabelsAboveCell(RegularExpression*, HTMLTableCellElement*); - NSString* searchForLabelsBeforeElement(NSArray* labels, Element*); + NSString* searchForNSLabelsAboveCell(RegularExpression*, HTMLTableCellElement*, size_t* resultDistanceFromStartOfCell); + NSString* searchForLabelsBeforeElement(NSArray* labels, Element*, size_t* resultDistance, bool* resultIsInCellAbove); NSString* matchLabelsAgainstElement(NSArray* labels, Element*); #if ENABLE(DASHBOARD_SUPPORT) @@ -357,7 +327,6 @@ namespace WebCore { mutable SelectionController m_selectionController; mutable VisibleSelection m_mark; - Timer<Frame> m_caretBlinkTimer; mutable Editor m_editor; mutable EventHandler m_eventHandler; mutable AnimationController m_animationController; @@ -369,9 +338,6 @@ namespace WebCore { #if ENABLE(ORIENTATION_EVENTS) int m_orientation; #endif - - bool m_caretVisible; - bool m_caretPaint; bool m_highlightTextMatches; bool m_inViewSourceMode; diff --git a/WebCore/page/FrameView.cpp b/WebCore/page/FrameView.cpp index b533bad..33d6457 100644 --- a/WebCore/page/FrameView.cpp +++ b/WebCore/page/FrameView.cpp @@ -29,6 +29,7 @@ #include "AXObjectCache.h" #include "CSSStyleSelector.h" +#include "Chrome.h" #include "ChromeClient.h" #include "DocLoader.h" #include "EventHandler.h" @@ -45,8 +46,8 @@ #include "HTMLNames.h" #include "InspectorTimelineAgent.h" #include "OverflowEvent.h" +#include "RenderEmbeddedObject.h" #include "RenderPart.h" -#include "RenderPartObject.h" #include "RenderScrollbar.h" #include "RenderScrollbarPart.h" #include "RenderTheme.h" @@ -354,7 +355,7 @@ PassRefPtr<Scrollbar> FrameView::createScrollbar(ScrollbarOrientation orientatio // Try the <body> element first as a scrollbar source. Element* body = doc ? doc->body() : 0; if (body && body->renderer() && body->renderer()->style()->hasPseudoStyle(SCROLLBAR)) - return RenderScrollbar::createCustomScrollbar(this, orientation, body->renderBox()); + return RenderScrollbar::createCustomScrollbar(this, orientation, body->renderer()->enclosingBox()); // If the <body> didn't have a custom style, then the root element might. Element* docElement = doc ? doc->documentElement() : 0; @@ -452,7 +453,7 @@ void FrameView::updateCompositingLayers() if (!view->usesCompositing()) return; - view->compositor()->updateCompositingLayers(); + view->compositor()->updateCompositingLayers(CompositingUpdateAfterLayoutOrStyleChange); } void FrameView::setNeedsOneShotDrawingSynchronization() @@ -610,7 +611,8 @@ void FrameView::layout(bool allowSubtree) } if (!subtree) { - RenderObject* rootRenderer = document->documentElement() ? document->documentElement()->renderer() : 0; + Node* documentElement = document->documentElement(); + RenderObject* rootRenderer = documentElement ? documentElement->renderer() : 0; Node* body = document->body(); if (body && body->renderer()) { if (body->hasTagName(framesetTag)) { @@ -618,16 +620,22 @@ void FrameView::layout(bool allowSubtree) vMode = ScrollbarAlwaysOff; hMode = ScrollbarAlwaysOff; } else if (body->hasTagName(bodyTag)) { - if (!m_firstLayout && m_size.height() != layoutHeight() - && toRenderBox(body->renderer())->stretchesToViewHeight()) + if (!m_firstLayout && m_size.height() != layoutHeight() && body->renderer()->enclosingBox()->stretchesToViewHeight()) body->renderer()->setChildNeedsLayout(true); // It's sufficient to just check the X overflow, // since it's illegal to have visible in only one direction. RenderObject* o = rootRenderer->style()->overflowX() == OVISIBLE && document->documentElement()->hasTagName(htmlTag) ? body->renderer() : rootRenderer; applyOverflowToViewport(o, hMode, vMode); } - } else if (rootRenderer) + } else if (rootRenderer) { +#if ENABLE(SVG) + if (documentElement->isSVGElement()) { + if (!m_firstLayout && (m_size.width() != layoutWidth() || m_size.height() != layoutHeight())) + rootRenderer->setChildNeedsLayout(true); + } +#endif applyOverflowToViewport(rootRenderer, hMode, vMode); + } #ifdef INSTRUMENT_LAYOUT_SCHEDULING if (m_firstLayout && !document->ownerElement()) printf("Elapsed time before first layout: %d\n", document->elapsedTime()); @@ -672,8 +680,14 @@ void FrameView::layout(bool allowSubtree) pauseScheduledEvents(); - if (subtree) - root->view()->pushLayoutState(root); + bool disableLayoutState = false; + if (subtree) { + RenderView* view = root->view(); + disableLayoutState = view->shouldDisableLayoutStateForSubtree(root); + view->pushLayoutState(root); + if (disableLayoutState) + view->disableLayoutState(); + } m_midLayout = true; beginDeferredRepaints(); @@ -681,11 +695,16 @@ void FrameView::layout(bool allowSubtree) endDeferredRepaints(); m_midLayout = false; - if (subtree) - root->view()->popLayoutState(); + if (subtree) { + RenderView* view = root->view(); + view->popLayoutState(); + if (disableLayoutState) + view->enableLayoutState(); + } m_layoutRoot = 0; - m_frame->invalidateSelection(); + m_frame->selection()->setNeedsLayout(); + m_frame->selection()->updateAppearance(); m_layoutSchedulingEnabled = true; @@ -751,15 +770,15 @@ void FrameView::layout(bool allowSubtree) m_nestedLayoutCount--; } -void FrameView::addWidgetToUpdate(RenderPartObject* object) +void FrameView::addWidgetToUpdate(RenderEmbeddedObject* object) { if (!m_widgetUpdateSet) - m_widgetUpdateSet.set(new HashSet<RenderPartObject*>); + m_widgetUpdateSet.set(new RenderEmbeddedObjectSet); m_widgetUpdateSet->add(object); } -void FrameView::removeWidgetToUpdate(RenderPartObject* object) +void FrameView::removeWidgetToUpdate(RenderEmbeddedObject* object) { if (!m_widgetUpdateSet) return; @@ -946,16 +965,18 @@ void FrameView::scrollPositionChanged() { frame()->eventHandler()->sendScrollEvent(); + // For fixed position elements, update widget positions and compositing layers after scrolling, + // but only if we're not inside of layout. + // FIXME: we could skip this if we knew the page had no fixed position elements. + if (!m_nestedLayoutCount) { + if (RenderView* root = m_frame->contentRenderer()) { + root->updateWidgetPositions(); #if USE(ACCELERATED_COMPOSITING) - // We need to update layer positions after scrolling to account for position:fixed layers. - Document* document = m_frame->document(); - if (!document) - return; - - RenderLayer* layer = document->renderer() ? document->renderer()->enclosingLayer() : 0; - if (layer) - layer->updateLayerPositions(RenderLayer::UpdateCompositingLayers); + if (root->usesCompositing()) + root->compositor()->updateCompositingLayers(CompositingUpdateOnScroll); #endif + } + } } HostWindow* FrameView::hostWindow() const @@ -1360,11 +1381,11 @@ bool FrameView::updateWidgets() if (m_nestedLayoutCount > 1 || !m_widgetUpdateSet || m_widgetUpdateSet->isEmpty()) return true; - Vector<RenderPartObject*> objectVector; + Vector<RenderEmbeddedObject*> objectVector; copyToVector(*m_widgetUpdateSet, objectVector); size_t size = objectVector.size(); for (size_t i = 0; i < size; ++i) { - RenderPartObject* object = objectVector[i]; + RenderEmbeddedObject* object = objectVector[i]; object->updateWidget(false); // updateWidget() can destroy the RenderPartObject, so we need to make sure it's diff --git a/WebCore/page/FrameView.h b/WebCore/page/FrameView.h index 11f8843..b27ffd8 100644 --- a/WebCore/page/FrameView.h +++ b/WebCore/page/FrameView.h @@ -45,7 +45,7 @@ class Node; class PlatformMouseEvent; class RenderLayer; class RenderObject; -class RenderPartObject; +class RenderEmbeddedObject; class ScheduledEvent; class String; @@ -90,7 +90,6 @@ public: RenderObject* layoutRoot(bool onlyDuringLayout = false) const; int layoutCount() const { return m_layoutCount; } - // These two helper functions just pass through to the RenderView. bool needsLayout() const; void setNeedsLayout(); @@ -166,8 +165,8 @@ public: bool wasScrolledByUser() const; void setWasScrolledByUser(bool); - void addWidgetToUpdate(RenderPartObject*); - void removeWidgetToUpdate(RenderPartObject*); + void addWidgetToUpdate(RenderEmbeddedObject*); + void removeWidgetToUpdate(RenderEmbeddedObject*); virtual void paintContents(GraphicsContext*, const IntRect& damageRect); void setPaintBehavior(PaintBehavior); @@ -257,7 +256,9 @@ private: IntSize m_size; IntSize m_margins; - OwnPtr<HashSet<RenderPartObject*> > m_widgetUpdateSet; + + typedef HashSet<RenderEmbeddedObject*> RenderEmbeddedObjectSet; + OwnPtr<RenderEmbeddedObjectSet> m_widgetUpdateSet; RefPtr<Frame> m_frame; bool m_doFullRepaint; diff --git a/WebCore/page/Geolocation.cpp b/WebCore/page/Geolocation.cpp index 237ceaf..0843e81 100644 --- a/WebCore/page/Geolocation.cpp +++ b/WebCore/page/Geolocation.cpp @@ -44,6 +44,14 @@ #include "PositionError.h" #endif +#if ENABLE(CLIENT_BASED_GEOLOCATION) +#include "Coordinates.h" +#include "GeolocationController.h" +#include "GeolocationError.h" +#include "GeolocationPosition.h" +#include "PositionError.h" +#endif + namespace WebCore { static const char permissionDeniedErrorMessage[] = "User denied Geolocation"; @@ -134,6 +142,7 @@ void Geolocation::GeoNotifier::timerFired(Timer<GeoNotifier>*) m_errorCallback->handleEvent(m_fatalError.get()); // This will cause this notifier to be deleted. m_geolocation->fatalErrorOccurred(this); +<<<<<<< HEAD return; } @@ -142,6 +151,8 @@ void Geolocation::GeoNotifier::timerFired(Timer<GeoNotifier>*) // will continue to run. m_useCachedPosition = false; m_geolocation->requestUsesCachedPosition(this); +======= +>>>>>>> webkit.org at r54127 return; } @@ -200,8 +211,12 @@ void Geolocation::Watchers::getNotifiersVector(Vector<RefPtr<GeoNotifier> >& cop } Geolocation::Geolocation(Frame* frame) +<<<<<<< HEAD : EventListener(GeolocationEventListenerType) , m_frame(frame) +======= + : m_frame(frame) +>>>>>>> webkit.org at r54127 #if !ENABLE(CLIENT_BASED_GEOLOCATION) , m_service(GeolocationService::create(this)) #endif @@ -224,6 +239,10 @@ Geolocation::~Geolocation() m_frame->domWindow()->removeEventListener(eventNames().unloadEvent, this, false); } +Geolocation::~Geolocation() +{ +} + void Geolocation::disconnectFrame() { stopUpdating(); @@ -280,6 +299,7 @@ PassRefPtr<Geolocation::GeoNotifier> Geolocation::startRequest(PassRefPtr<Positi if (isDenied()) notifier->setFatalError(PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage)); else { +<<<<<<< HEAD if (haveSuitableCachedPosition(notifier->m_options.get())) notifier->setUseCachedPosition(); else { @@ -292,6 +312,16 @@ PassRefPtr<Geolocation::GeoNotifier> Geolocation::startRequest(PassRefPtr<Positi } else notifier->setFatalError(PositionError::create(PositionError::POSITION_UNAVAILABLE, "Failed to start Geolocation service")); } +======= + if (notifier->hasZeroTimeout() || startUpdating(notifier.get())) { +#if ENABLE(CLIENT_BASED_GEOLOCATION) + // Only start timer if we're not waiting for user permission. + if (!m_startRequestPermissionNotifier) +#endif + notifier->startTimerIfNeeded(); + } else + notifier->setFatalError(PositionError::create(PositionError::POSITION_UNAVAILABLE, "Failed to start Geolocation service")); +>>>>>>> webkit.org at r54127 } return notifier.release(); @@ -314,6 +344,7 @@ void Geolocation::requestTimedOut(GeoNotifier* notifier) if (!hasListeners()) stopUpdating(); +<<<<<<< HEAD } void Geolocation::requestUsesCachedPosition(GeoNotifier* notifier) @@ -375,6 +406,8 @@ bool Geolocation::haveSuitableCachedPosition(PositionOptions* options) return false; DOMTimeStamp currentTimeMillis = currentTime() * 1000.0; return m_positionCache->cachedPosition()->timestamp() > currentTimeMillis - options->maximumAge(); +======= +>>>>>>> webkit.org at r54127 } void Geolocation::clearWatch(int watchId) @@ -427,8 +460,15 @@ void Geolocation::setIsAllowed(bool allowed) return; } #endif +<<<<<<< HEAD if (!isAllowed()) { +======= + + if (isAllowed()) + makeSuccessCallbacks(); + else { +>>>>>>> webkit.org at r54127 RefPtr<PositionError> error = PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage); error->setIsFatal(true); handleError(error.get()); @@ -543,8 +583,11 @@ void Geolocation::requestPermission() void Geolocation::positionChanged(PassRefPtr<Geoposition> newPosition) { m_currentPosition = newPosition; +<<<<<<< HEAD m_positionCache->setCachedPosition(m_currentPosition.get()); +======= +>>>>>>> webkit.org at r54127 // Stop all currently running timers. stopTimers(); @@ -611,9 +654,12 @@ void Geolocation::geolocationServiceErrorOccurred(GeolocationService* service) { ASSERT(service->lastError()); +<<<<<<< HEAD // Note that we do not stop timers here. For one-shots, the request is // cleared in handleError. For watchers, the spec requires that the timer is // not cleared. +======= +>>>>>>> webkit.org at r54127 handleError(service->lastError()); } @@ -661,6 +707,7 @@ void Geolocation::stopUpdating() } +<<<<<<< HEAD bool Geolocation::operator==(const EventListener& listener) { if (listener.type() != GeolocationEventListenerType) @@ -679,4 +726,6 @@ void Geolocation::handleEvent(ScriptExecutionContext*, Event* event) m_watchers.clear(); } +======= +>>>>>>> webkit.org at r54127 } // namespace WebCore diff --git a/WebCore/page/Geolocation.h b/WebCore/page/Geolocation.h index 0db37e4..fc6365e 100644 --- a/WebCore/page/Geolocation.h +++ b/WebCore/page/Geolocation.h @@ -54,7 +54,11 @@ class GeolocationPosition; class GeolocationError; #endif +<<<<<<< HEAD class Geolocation : public EventListener +======= +class Geolocation : public RefCounted<Geolocation> +>>>>>>> webkit.org at r54127 #if !ENABLE(CLIENT_BASED_GEOLOCATION) , public GeolocationServiceClient #endif @@ -83,7 +87,11 @@ public: bool shouldClearCache() const { return m_shouldClearCache; } #if ENABLE(CLIENT_BASED_GEOLOCATION) +<<<<<<< HEAD void setPostion(GeolocationPosition*); +======= + void setPosition(GeolocationPosition*); +>>>>>>> webkit.org at r54127 void setError(GeolocationError*); #endif diff --git a/WebCore/page/Geolocation.idl b/WebCore/page/Geolocation.idl index e125118..76056a3 100644 --- a/WebCore/page/Geolocation.idl +++ b/WebCore/page/Geolocation.idl @@ -25,7 +25,7 @@ module core { - interface Geolocation { + interface [OmitConstructor] Geolocation { readonly attribute Geoposition lastPosition; [Custom] void getCurrentPosition(in PositionCallback successCallback, in PositionErrorCallback errorCallback, in PositionOptions options); diff --git a/WebCore/page/GeolocationController.cpp b/WebCore/page/GeolocationController.cpp index 968e854..bb082e5 100644 --- a/WebCore/page/GeolocationController.cpp +++ b/WebCore/page/GeolocationController.cpp @@ -40,6 +40,11 @@ GeolocationController::GeolocationController(Page* page, GeolocationControllerCl GeolocationController::~GeolocationController() { +<<<<<<< HEAD +======= + if (m_client) + m_client->geolocationDestroyed(); +>>>>>>> webkit.org at r54127 } void GeolocationController::addObserver(Geolocation* observer) @@ -48,7 +53,11 @@ void GeolocationController::addObserver(Geolocation* observer) bool wasEmpty = m_observers.isEmpty(); m_observers.add(observer); +<<<<<<< HEAD if (wasEmpty) +======= + if (wasEmpty && m_client) +>>>>>>> webkit.org at r54127 m_client->startUpdating(); } @@ -58,26 +67,50 @@ void GeolocationController::removeObserver(Geolocation* observer) return; m_observers.remove(observer); +<<<<<<< HEAD if (m_observers.isEmpty()) +======= + if (m_observers.isEmpty() && m_client) +>>>>>>> webkit.org at r54127 m_client->stopUpdating(); } void GeolocationController::positionChanged(GeolocationPosition* position) { +<<<<<<< HEAD HashSet<RefPtr<Geolocation> >::const_iterator end = m_observers.end(); for (HashSet<RefPtr<Geolocation> >::const_iterator it = m_observers.begin(); it != end; ++it) (*it)->setPosition(position); +======= + Vector<RefPtr<Geolocation> > observersVector; + copyToVector(m_observers, observersVector); + for (size_t i = 0; i < observersVector.size(); ++i) + observersVector[i]->setPosition(position); +>>>>>>> webkit.org at r54127 } void GeolocationController::errorOccurred(GeolocationError* error) { +<<<<<<< HEAD HashSet<RefPtr<Geolocation> >::const_iterator end = m_observers.end(); for (HashSet<RefPtr<Geolocation> >::const_iterator it = m_observers.begin(); it != end; ++it) (*it)->setError(error); +======= + Vector<RefPtr<Geolocation> > observersVector; + copyToVector(m_observers, observersVector); + for (size_t i = 0; i < observersVector.size(); ++i) + observersVector[i]->setError(error); +>>>>>>> webkit.org at r54127 } GeolocationPosition* GeolocationController::lastPosition() { +<<<<<<< HEAD +======= + if (!m_client) + return 0; + +>>>>>>> webkit.org at r54127 return m_client->lastPosition(); } diff --git a/WebCore/page/GeolocationControllerClient.h b/WebCore/page/GeolocationControllerClient.h index 830c64b..01b1a27 100644 --- a/WebCore/page/GeolocationControllerClient.h +++ b/WebCore/page/GeolocationControllerClient.h @@ -32,6 +32,11 @@ class GeolocationPosition; class GeolocationControllerClient { public: +<<<<<<< HEAD +======= + virtual void geolocationDestroyed() = 0; + +>>>>>>> webkit.org at r54127 virtual void startUpdating() = 0; virtual void stopUpdating() = 0; virtual GeolocationPosition* lastPosition() = 0; diff --git a/WebCore/page/GeolocationError.h b/WebCore/page/GeolocationError.h index 9761ca6..5c3df15 100644 --- a/WebCore/page/GeolocationError.h +++ b/WebCore/page/GeolocationError.h @@ -30,6 +30,10 @@ #include "PlatformString.h" #include <wtf/PassRefPtr.h> +<<<<<<< HEAD +======= +#include <wtf/RefCounted.h> +>>>>>>> webkit.org at r54127 #include <wtf/RefPtr.h> namespace WebCore { @@ -47,7 +51,15 @@ public: const String& message() const { return m_message; } private: +<<<<<<< HEAD GeolocationError(ErrorCode code, const String& message); +======= + GeolocationError(ErrorCode code, const String& message) + : m_code(code) + , m_message(message) + { + } +>>>>>>> webkit.org at r54127 ErrorCode m_code; String m_message; diff --git a/WebCore/page/GeolocationPosition.h b/WebCore/page/GeolocationPosition.h index c31e9c4..91bd379 100644 --- a/WebCore/page/GeolocationPosition.h +++ b/WebCore/page/GeolocationPosition.h @@ -29,6 +29,10 @@ #if ENABLE(CLIENT_BASED_GEOLOCATION) #include <wtf/PassRefPtr.h> +<<<<<<< HEAD +======= +#include <wtf/RefCounted.h> +>>>>>>> webkit.org at r54127 #include <wtf/RefPtr.h> namespace WebCore { diff --git a/WebCore/page/Geoposition.idl b/WebCore/page/Geoposition.idl index 3ec8b0b..6fa12ff 100644 --- a/WebCore/page/Geoposition.idl +++ b/WebCore/page/Geoposition.idl @@ -25,7 +25,7 @@ module core { - interface Geoposition { + interface [OmitConstructor] Geoposition { readonly attribute Coordinates coords; readonly attribute DOMTimeStamp timestamp; }; diff --git a/WebCore/page/History.cpp b/WebCore/page/History.cpp index ea9819e..78e8ea6 100644 --- a/WebCore/page/History.cpp +++ b/WebCore/page/History.cpp @@ -98,9 +98,8 @@ KURL History::urlForState(const String& urlString) void History::stateObjectAdded(PassRefPtr<SerializedScriptValue> data, const String& title, const String& urlString, StateObjectType stateObjectType, ExceptionCode& ec) { - if (!m_frame) + if (!m_frame || !m_frame->page()) return; - ASSERT(m_frame->page()); KURL fullURL = urlForState(urlString); if (!fullURL.isValid()) { @@ -113,13 +112,13 @@ void History::stateObjectAdded(PassRefPtr<SerializedScriptValue> data, const Str else if (stateObjectType == StateObjectReplace) m_frame->loader()->history()->replaceState(data, title, fullURL.string()); - if (!urlString.isEmpty()) { + if (!urlString.isEmpty()) m_frame->document()->updateURLForPushOrReplaceState(fullURL); - if (stateObjectType == StateObjectPush) - m_frame->loader()->client()->dispatchDidPushStateWithinPage(); - else if (stateObjectType == StateObjectReplace) - m_frame->loader()->client()->dispatchDidReplaceStateWithinPage(); - } + + if (stateObjectType == StateObjectPush) + m_frame->loader()->client()->dispatchDidPushStateWithinPage(); + else if (stateObjectType == StateObjectReplace) + m_frame->loader()->client()->dispatchDidReplaceStateWithinPage(); } } // namespace WebCore diff --git a/WebCore/page/History.idl b/WebCore/page/History.idl index 3790552..3fc2771 100644 --- a/WebCore/page/History.idl +++ b/WebCore/page/History.idl @@ -32,7 +32,8 @@ module window { DelegatingGetOwnPropertySlot, DelegatingPutFunction, CustomDeleteProperty, - CustomGetPropertyNames + CustomGetPropertyNames, + OmitConstructor ] History { readonly attribute unsigned long length; diff --git a/WebCore/page/Location.idl b/WebCore/page/Location.idl index 7d680f2..b020267 100644 --- a/WebCore/page/Location.idl +++ b/WebCore/page/Location.idl @@ -38,7 +38,8 @@ module window { CustomGetPropertyNames, CustomDefineGetter, DelegatingPrototypePutFunction, - CustomPrototypeDefineGetter + CustomPrototypeDefineGetter, + OmitConstructor ] Location { attribute [DoNotCheckDomainSecurityOnSet, CustomSetter, V8DisallowShadowing] DOMString href; diff --git a/WebCore/page/Navigator.cpp b/WebCore/page/Navigator.cpp index 8563a0e..bcc302f 100644 --- a/WebCore/page/Navigator.cpp +++ b/WebCore/page/Navigator.cpp @@ -23,6 +23,7 @@ #include "config.h" #include "Navigator.h" +#include "Chrome.h" #include "CookieJar.h" #if PLATFORM(ANDROID) #include "Connection.h" diff --git a/WebCore/page/Navigator.idl b/WebCore/page/Navigator.idl index 168cf8c..215316f 100644 --- a/WebCore/page/Navigator.idl +++ b/WebCore/page/Navigator.idl @@ -20,7 +20,8 @@ module window { interface [ - CustomMarkFunction + CustomMarkFunction, + OmitConstructor ] Navigator { readonly attribute DOMString appCodeName; readonly attribute DOMString appName; @@ -45,7 +46,7 @@ module window { #endif #if defined(ENABLE_GEOLOCATION) && ENABLE_GEOLOCATION - readonly attribute Geolocation geolocation; + readonly attribute [EnabledAtRuntime] Geolocation geolocation; #endif #if defined(ENABLE_DOM_STORAGE) && ENABLE_DOM_STORAGE diff --git a/WebCore/page/NavigatorBase.cpp b/WebCore/page/NavigatorBase.cpp index 5b0c5d4..ca51a29 100644 --- a/WebCore/page/NavigatorBase.cpp +++ b/WebCore/page/NavigatorBase.cpp @@ -29,19 +29,19 @@ #include "NetworkStateNotifier.h" #include "PlatformString.h" -#if PLATFORM(LINUX) +#if OS(LINUX) #include "sys/utsname.h" #include <wtf/StdLibExtras.h> #endif #ifndef WEBCORE_NAVIGATOR_PLATFORM -#if PLATFORM(MAC) && (PLATFORM(PPC) || PLATFORM(PPC64)) +#if OS(MAC_OS_X) && (CPU(PPC) || CPU(PPC64)) #define WEBCORE_NAVIGATOR_PLATFORM "MacPPC" -#elif PLATFORM(MAC) && (PLATFORM(X86) || PLATFORM(X86_64)) +#elif OS(MAC_OS_X) && (CPU(X86) || CPU(X86_64)) #define WEBCORE_NAVIGATOR_PLATFORM "MacIntel" -#elif PLATFORM(WIN_OS) +#elif OS(WINDOWS) #define WEBCORE_NAVIGATOR_PLATFORM "Win32" -#elif PLATFORM(SYMBIAN) +#elif OS(SYMBIAN) #define WEBCORE_NAVIGATOR_PLATFORM "Symbian" #else #define WEBCORE_NAVIGATOR_PLATFORM "" @@ -85,7 +85,7 @@ String NavigatorBase::appVersion() const String NavigatorBase::platform() const { -#if PLATFORM(LINUX) +#if OS(LINUX) if (String("") != WEBCORE_NAVIGATOR_PLATFORM) return WEBCORE_NAVIGATOR_PLATFORM; struct utsname osname; diff --git a/WebCore/page/Page.cpp b/WebCore/page/Page.cpp index 1a035a5..1704bfb 100644 --- a/WebCore/page/Page.cpp +++ b/WebCore/page/Page.cpp @@ -289,15 +289,8 @@ void Page::goBackOrForward(int distance) void Page::goToItem(HistoryItem* item, FrameLoadType type) { -#if !ASSERT_DISABLED - // If we're navigating to an item with history state for a Document other than the - // current Document, the new Document had better be in the page cache. - if (item->stateObject() && item->document() != m_mainFrame->document()) - ASSERT(item->document()->inPageCache()); -#endif - // Abort any current load unless we're navigating the current document to a new state object - if (!item->stateObject() || item->document() != m_mainFrame->document()) { + if (!item->stateObject() || item->documentSequenceNumber() != m_mainFrame->loader()->history()->currentItem()->documentSequenceNumber()) { // Define what to do with any open database connections. By default we stop them and terminate the database thread. DatabasePolicy databasePolicy = DatabasePolicyStop; @@ -318,7 +311,7 @@ void Page::goToItem(HistoryItem* item, FrameLoadType type) int Page::getHistoryLength() { - return m_backForwardList->backListCount() + 1; + return m_backForwardList->backListCount() + 1 + m_backForwardList->forwardListCount(); } void Page::setGlobalHistoryItem(HistoryItem* item) @@ -485,6 +478,9 @@ const VisibleSelection& Page::selection() const void Page::setDefersLoading(bool defers) { + if (!m_settings->loadDeferringEnabled()) + return; + if (defers == m_defersLoading) return; @@ -689,7 +685,7 @@ void Page::setDebugger(JSC::Debugger* debugger) StorageNamespace* Page::sessionStorage(bool optionalCreate) { if (!m_sessionStorage && optionalCreate) - m_sessionStorage = StorageNamespace::sessionStorageNamespace(); + m_sessionStorage = StorageNamespace::sessionStorageNamespace(this); return m_sessionStorage.get(); } @@ -775,4 +771,16 @@ void Page::didStopPlugin(HaltablePlugin* obj) m_pluginHalter->didStopPlugin(obj); } +#if !ASSERT_DISABLED +void Page::checkFrameCountConsistency() const +{ + ASSERT(m_frameCount >= 0); + + int frameCount = 0; + for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) + ++frameCount; + + ASSERT(m_frameCount + 1 == frameCount); +} +#endif } // namespace WebCore diff --git a/WebCore/page/Page.h b/WebCore/page/Page.h index 40d96a7..1417c87 100644 --- a/WebCore/page/Page.h +++ b/WebCore/page/Page.h @@ -21,20 +21,17 @@ #ifndef Page_h #define Page_h -#include "BackForwardList.h" -#include "Chrome.h" -#include "ContextMenuController.h" #include "FrameLoaderTypes.h" -#include "LinkHash.h" #include "PlatformString.h" +#include <wtf/Forward.h> #include <wtf/HashSet.h> -#include <wtf/OwnPtr.h> +#include <wtf/Noncopyable.h> #if PLATFORM(MAC) #include "SchedulePair.h" #endif -#if PLATFORM(WIN) || (PLATFORM(WX) && PLATFORM(WIN_OS)) || (PLATFORM(QT) && defined(Q_WS_WIN)) +#if PLATFORM(WIN) || (PLATFORM(WX) && OS(WINDOWS)) || (PLATFORM(QT) && defined(Q_WS_WIN)) typedef struct HINSTANCE__* HINSTANCE; #endif @@ -44,6 +41,7 @@ namespace JSC { namespace WebCore { + class BackForwardList; class Chrome; class ChromeClient; class ContextMenuClient; @@ -57,6 +55,7 @@ namespace WebCore { class GeolocationController; class GeolocationControllerClient; class HaltablePlugin; + class HistoryItem; class InspectorClient; class InspectorController; class InspectorTimelineAgent; @@ -81,6 +80,8 @@ namespace WebCore { class NotificationPresenter; #endif + typedef uint64_t LinkHash; + enum FindDirection { FindDirectionForward, FindDirectionBackward }; class Page : public Noncopyable { @@ -131,8 +132,8 @@ namespace WebCore { PageGroup* groupPtr() { return m_group; } // can return 0 void incrementFrameCount() { ++m_frameCount; } - void decrementFrameCount() { --m_frameCount; } - int frameCount() const { return m_frameCount; } + void decrementFrameCount() { ASSERT(m_frameCount); --m_frameCount; } + int frameCount() const { checkFrameCountConsistency(); return m_frameCount; } Chrome* chrome() const { return m_chrome.get(); } SelectionController* dragCaretController() const { return m_dragCaretController.get(); } @@ -203,7 +204,7 @@ namespace WebCore { void setDebugger(JSC::Debugger*); JSC::Debugger* debugger() const { return m_debugger; } -#if PLATFORM(WIN) || (PLATFORM(WX) && PLATFORM(WIN_OS)) || (PLATFORM(QT) && defined(Q_WS_WIN)) +#if PLATFORM(WIN) || (PLATFORM(WX) && OS(WINDOWS)) || (PLATFORM(QT) && defined(Q_WS_WIN)) // The global DLL or application instance used for all windows. static void setInstanceHandle(HINSTANCE instanceHandle) { s_instanceHandle = instanceHandle; } static HINSTANCE instanceHandle() { return s_instanceHandle; } @@ -243,6 +244,12 @@ namespace WebCore { private: void initGroup(); +#if ASSERT_DISABLED + void checkFrameCountConsistency() const { } +#else + void checkFrameCountConsistency() const; +#endif + OwnPtr<Chrome> m_chrome; OwnPtr<SelectionController> m_dragCaretController; #if ENABLE(DRAG_SUPPORT) diff --git a/WebCore/page/PageGroup.cpp b/WebCore/page/PageGroup.cpp index 558c5cb..0ebbfba 100644 --- a/WebCore/page/PageGroup.cpp +++ b/WebCore/page/PageGroup.cpp @@ -26,6 +26,7 @@ #include "config.h" #include "PageGroup.h" +#include "Chrome.h" #include "ChromeClient.h" #include "Document.h" #include "Frame.h" diff --git a/WebCore/page/PositionError.idl b/WebCore/page/PositionError.idl index 91027df..1f28d95 100644 --- a/WebCore/page/PositionError.idl +++ b/WebCore/page/PositionError.idl @@ -25,9 +25,7 @@ module core { - interface [ - GenerateConstructor - ] PositionError { + interface PositionError { readonly attribute unsigned short code; readonly attribute DOMString message; diff --git a/WebCore/page/Screen.idl b/WebCore/page/Screen.idl index ca7d20d..cd181eb 100644 --- a/WebCore/page/Screen.idl +++ b/WebCore/page/Screen.idl @@ -29,7 +29,7 @@ module window { - interface Screen { + interface [OmitConstructor] Screen { readonly attribute unsigned long height; readonly attribute unsigned long width; readonly attribute unsigned long colorDepth; diff --git a/WebCore/page/SecurityOrigin.cpp b/WebCore/page/SecurityOrigin.cpp index f53dbf1..b2a1c89 100644 --- a/WebCore/page/SecurityOrigin.cpp +++ b/WebCore/page/SecurityOrigin.cpp @@ -65,22 +65,24 @@ static URLSchemesMap& localSchemes() return localSchemes; } -static URLSchemesMap& noAccessSchemes() +static URLSchemesMap& schemesWithUniqueOrigins() { - DEFINE_STATIC_LOCAL(URLSchemesMap, noAccessSchemes, ()); + DEFINE_STATIC_LOCAL(URLSchemesMap, schemesWithUniqueOrigins, ()); - if (noAccessSchemes.isEmpty()) - noAccessSchemes.add("data"); + // This is a willful violation of HTML5. + // See https://bugs.webkit.org/show_bug.cgi?id=11885 + if (schemesWithUniqueOrigins.isEmpty()) + schemesWithUniqueOrigins.add("data"); - return noAccessSchemes; + return schemesWithUniqueOrigins; } -SecurityOrigin::SecurityOrigin(const KURL& url) - : m_protocol(url.protocol().isNull() ? "" : url.protocol().lower()) +SecurityOrigin::SecurityOrigin(const KURL& url, SandboxFlags sandboxFlags) + : m_sandboxFlags(sandboxFlags) + , m_protocol(url.protocol().isNull() ? "" : url.protocol().lower()) , m_host(url.host().isNull() ? "" : url.host().lower()) , m_port(url.port()) - , m_sandboxFlags(SandboxNone) - , m_noAccess(false) + , m_isUnique(isSandboxed(SandboxOrigin) || shouldTreatURLSchemeAsNoAccess(m_protocol)) , m_universalAccess(false) , m_domainWasSetInDOM(false) { @@ -88,10 +90,6 @@ SecurityOrigin::SecurityOrigin(const KURL& url) if (m_protocol == "about" || m_protocol == "javascript") m_protocol = ""; - // Some URLs are not allowed access to anything other than themselves. - if (shouldTreatURLSchemeAsNoAccess(m_protocol)) - m_noAccess = true; - // document.domain starts as m_host, but can be set by the DOM. m_domain = m_host; @@ -100,7 +98,7 @@ SecurityOrigin::SecurityOrigin(const KURL& url) if (m_canLoadLocalResources) { // Directories should never be readable. if (!url.hasPath() || url.path().endsWith("/")) - m_noAccess = true; + m_isUnique = true; } if (isDefaultPortForProtocol(m_port, m_protocol)) @@ -108,12 +106,12 @@ SecurityOrigin::SecurityOrigin(const KURL& url) } SecurityOrigin::SecurityOrigin(const SecurityOrigin* other) - : m_protocol(other->m_protocol.threadsafeCopy()) + : m_sandboxFlags(other->m_sandboxFlags) + , m_protocol(other->m_protocol.threadsafeCopy()) , m_host(other->m_host.threadsafeCopy()) , m_domain(other->m_domain.threadsafeCopy()) , m_port(other->m_port) - , m_sandboxFlags(other->m_sandboxFlags) - , m_noAccess(other->m_noAccess) + , m_isUnique(other->m_isUnique) , m_universalAccess(other->m_universalAccess) , m_domainWasSetInDOM(other->m_domainWasSetInDOM) , m_canLoadLocalResources(other->m_canLoadLocalResources) @@ -125,11 +123,11 @@ bool SecurityOrigin::isEmpty() const return m_protocol.isEmpty(); } -PassRefPtr<SecurityOrigin> SecurityOrigin::create(const KURL& url) +PassRefPtr<SecurityOrigin> SecurityOrigin::create(const KURL& url, SandboxFlags sandboxFlags) { if (!url.isValid()) - return adoptRef(new SecurityOrigin(KURL())); - return adoptRef(new SecurityOrigin(url)); + return adoptRef(new SecurityOrigin(KURL(), sandboxFlags)); + return adoptRef(new SecurityOrigin(url, sandboxFlags)); } PassRefPtr<SecurityOrigin> SecurityOrigin::createEmpty() @@ -148,20 +146,45 @@ void SecurityOrigin::setDomainFromDOM(const String& newDomain) m_domain = newDomain.lower(); } +static HashSet<String>& schemesForbiddenFromDomainRelaxation() +{ + DEFINE_STATIC_LOCAL(HashSet<String>, schemes, ()); + return schemes; +} + +void SecurityOrigin::setDomainRelaxationForbiddenForURLScheme(bool forbidden, const String& scheme) +{ + if (scheme.isEmpty()) + return; + + if (forbidden) + schemesForbiddenFromDomainRelaxation().add(scheme); + else + schemesForbiddenFromDomainRelaxation().remove(scheme); +} + +bool SecurityOrigin::isDomainRelaxationForbiddenForURLScheme(const String& scheme) +{ + if (scheme.isEmpty()) + return false; + + return schemesForbiddenFromDomainRelaxation().contains(scheme); +} + bool SecurityOrigin::canAccess(const SecurityOrigin* other) const { if (m_universalAccess) return true; - if (m_noAccess || other->m_noAccess || isSandboxed(SandboxOrigin) || other->isSandboxed(SandboxOrigin)) + if (isUnique() || other->isUnique()) return false; // Here are two cases where we should permit access: // - // 1) Neither document has set document.domain. In this case, we insist + // 1) Neither document has set document.domain. In this case, we insist // that the scheme, host, and port of the URLs match. // - // 2) Both documents have set document.domain. In this case, we insist + // 2) Both documents have set document.domain. In this case, we insist // that the documents have set document.domain to the same value and // that the scheme of the URLs match. // @@ -194,11 +217,11 @@ bool SecurityOrigin::canRequest(const KURL& url) const if (m_universalAccess) return true; - if (m_noAccess || isSandboxed(SandboxOrigin)) + if (isUnique()) return false; RefPtr<SecurityOrigin> targetOrigin = SecurityOrigin::create(url); - if (targetOrigin->m_noAccess) + if (targetOrigin->isUnique()) return false; // We call isSameSchemeHostPort here instead of canAccess because we want @@ -221,11 +244,12 @@ bool SecurityOrigin::taintsCanvas(const KURL& url) const if (canRequest(url)) return false; - // This method exists because we treat data URLs as noAccess, contrary - // to the current (9/19/2009) draft of the HTML5 specification. We still - // want to let folks paint data URLs onto untainted canvases, so we special - // case data URLs below. If we change to match HTML5 w.r.t. data URL - // security, then we can remove this method in favor of !canRequest. + // This function exists because we treat data URLs as having a unique origin, + // contrary to the current (9/19/2009) draft of the HTML5 specification. + // We still want to let folks paint data URLs onto untainted canvases, so + // we special case data URLs below. If we change to match HTML5 w.r.t. + // data URL security, then we can remove this function in favor of + // !canRequest. if (url.protocolIs("data")) return false; @@ -248,8 +272,8 @@ bool SecurityOrigin::canLoad(const KURL& url, const String& referrer, Document* void SecurityOrigin::grantLoadLocalResources() { - // This method exists only to support backwards compatibility with older - // versions of WebKit. Granting privileges to some, but not all, documents + // This function exists only to support backwards compatibility with older + // versions of WebKit. Granting privileges to some, but not all, documents // in a SecurityOrigin is a security hazard because the documents without // the privilege can obtain the privilege by injecting script into the // documents that have been granted the privilege. @@ -262,6 +286,15 @@ void SecurityOrigin::grantUniversalAccess() m_universalAccess = true; } +void SecurityOrigin::setSandboxFlags(SandboxFlags flags) +{ + // Although you might think that we should set m_isUnique based on + // SandboxOrigin, that's not actually the right behavior. We're supposed to + // freeze the origin of a document when it is created, even if the sandbox + // flags change after that point in time. + m_sandboxFlags = flags; +} + bool SecurityOrigin::isLocal() const { return shouldTreatURLSchemeAsLocal(m_protocol); @@ -282,7 +315,7 @@ String SecurityOrigin::toString() const if (isEmpty()) return "null"; - if (m_noAccess || isSandboxed(SandboxOrigin)) + if (isUnique()) return "null"; if (m_protocol == "file") @@ -440,12 +473,12 @@ bool SecurityOrigin::shouldTreatURLSchemeAsLocal(const String& scheme) void SecurityOrigin::registerURLSchemeAsNoAccess(const String& scheme) { - noAccessSchemes().add(scheme); + schemesWithUniqueOrigins().add(scheme); } bool SecurityOrigin::shouldTreatURLSchemeAsNoAccess(const String& scheme) { - return noAccessSchemes().contains(scheme); + return schemesWithUniqueOrigins().contains(scheme); } bool SecurityOrigin::shouldHideReferrer(const KURL& url, const String& referrer) diff --git a/WebCore/page/SecurityOrigin.h b/WebCore/page/SecurityOrigin.h index af83f02..71681d7 100644 --- a/WebCore/page/SecurityOrigin.h +++ b/WebCore/page/SecurityOrigin.h @@ -40,159 +40,169 @@ namespace WebCore { - typedef HashSet<String, CaseFoldingHash> URLSchemesMap; - - class Document; - class KURL; - - class SecurityOrigin : public ThreadSafeShared<SecurityOrigin> { - public: - static PassRefPtr<SecurityOrigin> createFromDatabaseIdentifier(const String&); - static PassRefPtr<SecurityOrigin> createFromString(const String&); - static PassRefPtr<SecurityOrigin> create(const KURL&); - static PassRefPtr<SecurityOrigin> createEmpty(); - - // Create a deep copy of this SecurityOrigin. This method is useful - // when marshalling a SecurityOrigin to another thread. - PassRefPtr<SecurityOrigin> threadsafeCopy(); - - // Set the domain property of this security origin to newDomain. This - // function does not check whether newDomain is a suffix of the current - // domain. The caller is responsible for validating newDomain. - void setDomainFromDOM(const String& newDomain); - bool domainWasSetInDOM() const { return m_domainWasSetInDOM; } - - String protocol() const { return m_protocol; } - String host() const { return m_host; } - String domain() const { return m_domain; } - unsigned short port() const { return m_port; } - - // Returns true if this SecurityOrigin can script objects in the given - // SecurityOrigin. For example, call this function before allowing - // script from one security origin to read or write objects from - // another SecurityOrigin. - bool canAccess(const SecurityOrigin*) const; - - // Returns true if this SecurityOrigin can read content retrieved from - // the given URL. For example, call this function before issuing - // XMLHttpRequests. - bool canRequest(const KURL&) const; - - // Returns true if drawing an image from this URL taints a canvas from - // this security origin. For example, call this function before - // drawing an image onto an HTML canvas element with the drawImage API. - bool taintsCanvas(const KURL&) const; - - // Returns true for any non-local URL. If document parameter is supplied, - // its local load policy dictates, otherwise if referrer is non-empty and - // represents a local file, then the local load is allowed. - static bool canLoad(const KURL&, const String& referrer, Document* document); - - // Returns true if this SecurityOrigin can load local resources, such - // as images, iframes, and style sheets, and can link to local URLs. - // For example, call this function before creating an iframe to a - // file:// URL. - // - // Note: A SecurityOrigin might be allowed to load local resources - // without being able to issue an XMLHttpRequest for a local URL. - // To determine whether the SecurityOrigin can issue an - // XMLHttpRequest for a URL, call canRequest(url). - bool canLoadLocalResources() const { return m_canLoadLocalResources; } - - // Explicitly grant the ability to load local resources to this - // SecurityOrigin. - // - // Note: This method exists only to support backwards compatibility - // with older versions of WebKit. - void grantLoadLocalResources(); - - // Explicitly grant the ability to access very other SecurityOrigin. - // - // WARNING: This is an extremely powerful ability. Use with caution! - void grantUniversalAccess(); - - // Sandboxing status as determined by the frame. - void setSandboxFlags(SandboxFlags flags) { m_sandboxFlags = flags; } - bool isSandboxed(SandboxFlags mask) const { return m_sandboxFlags & mask; } - - bool canAccessDatabase() const { return !isSandboxed(SandboxOrigin); } - bool canAccessStorage() const { return !isSandboxed(SandboxOrigin); } - - bool isSecureTransitionTo(const KURL&) const; - - // The local SecurityOrigin is the most privileged SecurityOrigin. - // The local SecurityOrigin can script any document, navigate to local - // resources, and can set arbitrary headers on XMLHttpRequests. - bool isLocal() const; - - // The empty SecurityOrigin is the least privileged SecurityOrigin. - bool isEmpty() const; - - // Convert this SecurityOrigin into a string. The string - // representation of a SecurityOrigin is similar to a URL, except it - // lacks a path component. The string representation does not encode - // the value of the SecurityOrigin's domain property. - // - // When using the string value, it's important to remember that it - // might be "null". This happens when this SecurityOrigin has - // noAccess to other SecurityOrigins. For example, this SecurityOrigin - // might have come from a data URL, the SecurityOrigin might be empty, - // or we might have explicitly decided that we - // shouldTreatURLSchemeAsNoAccess. - String toString() const; - - // Serialize the security origin to a string that could be used as part of - // file names. This format should be used in storage APIs only. - String databaseIdentifier() const; - - // This method checks for equality between SecurityOrigins, not whether - // one origin can access another. It is used for hash table keys. - // For access checks, use canAccess(). - // FIXME: If this method is really only useful for hash table keys, it - // should be refactored into SecurityOriginHash. - bool equal(const SecurityOrigin*) const; - - // This method checks for equality, ignoring the value of document.domain - // (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 void removeURLSchemeRegisteredAsLocal(const String&); - static const URLSchemesMap& localURLSchemes(); - static bool shouldTreatURLAsLocal(const String&); - static bool shouldTreatURLSchemeAsLocal(const String&); - - static bool shouldHideReferrer(const KURL&, const String& referrer); - - enum LocalLoadPolicy { - AllowLocalLoadsForAll, // No restriction on local loads. - AllowLocalLoadsForLocalAndSubstituteData, - AllowLocalLoadsForLocalOnly, - }; - static void setLocalLoadPolicy(LocalLoadPolicy); - static bool restrictAccessToLocal(); - static bool allowSubstituteDataAccessToLocal(); - - static void registerURLSchemeAsNoAccess(const String&); - static bool shouldTreatURLSchemeAsNoAccess(const String&); - - static void whiteListAccessFromOrigin(const SecurityOrigin& sourceOrigin, const String& destinationProtocol, const String& destinationDomains, bool allowDestinationSubdomains); - static void resetOriginAccessWhiteLists(); - - private: - explicit SecurityOrigin(const KURL&); - explicit SecurityOrigin(const SecurityOrigin*); - - String m_protocol; - String m_host; - String m_domain; - unsigned short m_port; - SandboxFlags m_sandboxFlags; - bool m_noAccess; - bool m_universalAccess; - bool m_domainWasSetInDOM; - bool m_canLoadLocalResources; +typedef HashSet<String, CaseFoldingHash> URLSchemesMap; + +class Document; +class KURL; + +class SecurityOrigin : public ThreadSafeShared<SecurityOrigin> { +public: + static PassRefPtr<SecurityOrigin> createFromDatabaseIdentifier(const String&); + static PassRefPtr<SecurityOrigin> createFromString(const String&); + static PassRefPtr<SecurityOrigin> create(const KURL&, SandboxFlags = SandboxNone); + static PassRefPtr<SecurityOrigin> createEmpty(); + + // Create a deep copy of this SecurityOrigin. This method is useful + // when marshalling a SecurityOrigin to another thread. + PassRefPtr<SecurityOrigin> threadsafeCopy(); + + // Set the domain property of this security origin to newDomain. This + // function does not check whether newDomain is a suffix of the current + // domain. The caller is responsible for validating newDomain. + void setDomainFromDOM(const String& newDomain); + bool domainWasSetInDOM() const { return m_domainWasSetInDOM; } + + static void setDomainRelaxationForbiddenForURLScheme(bool forbidden, const String&); + static bool isDomainRelaxationForbiddenForURLScheme(const String&); + + String protocol() const { return m_protocol; } + String host() const { return m_host; } + String domain() const { return m_domain; } + unsigned short port() const { return m_port; } + + // Returns true if this SecurityOrigin can script objects in the given + // SecurityOrigin. For example, call this function before allowing + // script from one security origin to read or write objects from + // another SecurityOrigin. + bool canAccess(const SecurityOrigin*) const; + + // Returns true if this SecurityOrigin can read content retrieved from + // the given URL. For example, call this function before issuing + // XMLHttpRequests. + bool canRequest(const KURL&) const; + + // Returns true if drawing an image from this URL taints a canvas from + // this security origin. For example, call this function before + // drawing an image onto an HTML canvas element with the drawImage API. + bool taintsCanvas(const KURL&) const; + + // Returns true for any non-local URL. If document parameter is supplied, + // its local load policy dictates, otherwise if referrer is non-empty and + // represents a local file, then the local load is allowed. + static bool canLoad(const KURL&, const String& referrer, Document* document); + + // Returns true if this SecurityOrigin can load local resources, such + // as images, iframes, and style sheets, and can link to local URLs. + // For example, call this function before creating an iframe to a + // file:// URL. + // + // Note: A SecurityOrigin might be allowed to load local resources + // without being able to issue an XMLHttpRequest for a local URL. + // To determine whether the SecurityOrigin can issue an + // XMLHttpRequest for a URL, call canRequest(url). + bool canLoadLocalResources() const { return m_canLoadLocalResources; } + + // Explicitly grant the ability to load local resources to this + // SecurityOrigin. + // + // Note: This method exists only to support backwards compatibility + // with older versions of WebKit. + void grantLoadLocalResources(); + + // Explicitly grant the ability to access very other SecurityOrigin. + // + // WARNING: This is an extremely powerful ability. Use with caution! + void grantUniversalAccess(); + + void setSandboxFlags(SandboxFlags); + bool isSandboxed(SandboxFlags mask) const { return m_sandboxFlags & mask; } + + bool canAccessDatabase() const { return !isUnique(); } + bool canAccessStorage() const { return !isUnique(); } + bool canAccessCookies() const { return !isUnique(); } + + bool isSecureTransitionTo(const KURL&) const; + + // The local SecurityOrigin is the most privileged SecurityOrigin. + // The local SecurityOrigin can script any document, navigate to local + // resources, and can set arbitrary headers on XMLHttpRequests. + bool isLocal() const; + + // The empty SecurityOrigin is the least privileged SecurityOrigin. + bool isEmpty() const; + + // The origin is a globally unique identifier assigned when the Document is + // created. http://www.whatwg.org/specs/web-apps/current-work/#sandboxOrigin + // + // There's a subtle difference between a unique origin and an origin that + // has the SandboxOrigin flag set. The latter implies the former, and, in + // addition, the SandboxOrigin flag is inherited by iframes. + bool isUnique() const { return m_isUnique; } + + // Convert this SecurityOrigin into a string. The string + // representation of a SecurityOrigin is similar to a URL, except it + // lacks a path component. The string representation does not encode + // the value of the SecurityOrigin's domain property. + // + // When using the string value, it's important to remember that it might be + // "null". This happens when this SecurityOrigin is unique. For example, + // this SecurityOrigin might have come from a sandboxed iframe, the + // SecurityOrigin might be empty, or we might have explicitly decided that + // we shouldTreatURLSchemeAsNoAccess. + String toString() const; + + // Serialize the security origin to a string that could be used as part of + // file names. This format should be used in storage APIs only. + String databaseIdentifier() const; + + // This method checks for equality between SecurityOrigins, not whether + // one origin can access another. It is used for hash table keys. + // For access checks, use canAccess(). + // FIXME: If this method is really only useful for hash table keys, it + // should be refactored into SecurityOriginHash. + bool equal(const SecurityOrigin*) const; + + // This method checks for equality, ignoring the value of document.domain + // (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 void removeURLSchemeRegisteredAsLocal(const String&); + static const URLSchemesMap& localURLSchemes(); + static bool shouldTreatURLAsLocal(const String&); + static bool shouldTreatURLSchemeAsLocal(const String&); + + static bool shouldHideReferrer(const KURL&, const String& referrer); + + enum LocalLoadPolicy { + AllowLocalLoadsForAll, // No restriction on local loads. + AllowLocalLoadsForLocalAndSubstituteData, + AllowLocalLoadsForLocalOnly, }; + static void setLocalLoadPolicy(LocalLoadPolicy); + static bool restrictAccessToLocal(); + static bool allowSubstituteDataAccessToLocal(); + + static void registerURLSchemeAsNoAccess(const String&); + static bool shouldTreatURLSchemeAsNoAccess(const String&); + + static void whiteListAccessFromOrigin(const SecurityOrigin& sourceOrigin, const String& destinationProtocol, const String& destinationDomains, bool allowDestinationSubdomains); + static void resetOriginAccessWhiteLists(); + +private: + SecurityOrigin(const KURL&, SandboxFlags); + explicit SecurityOrigin(const SecurityOrigin*); + + SandboxFlags m_sandboxFlags; + String m_protocol; + String m_host; + String m_domain; + unsigned short m_port; + bool m_isUnique; + bool m_universalAccess; + bool m_domainWasSetInDOM; + bool m_canLoadLocalResources; +}; } // namespace WebCore diff --git a/WebCore/page/Settings.cpp b/WebCore/page/Settings.cpp index b250e4d..e57fccf 100644 --- a/WebCore/page/Settings.cpp +++ b/WebCore/page/Settings.cpp @@ -26,6 +26,7 @@ #include "config.h" #include "Settings.h" +#include "BackForwardList.h" #include "Frame.h" #include "FrameTree.h" #include "FrameView.h" @@ -48,7 +49,7 @@ static void setNeedsReapplyStylesInAllFrames(Page* page) bool Settings::gShouldPaintNativeControls = true; #endif -#if PLATFORM(WIN) || (PLATFORM(WIN_OS) && PLATFORM(WX)) +#if PLATFORM(WIN) || (OS(WINDOWS) && PLATFORM(WX)) bool Settings::gShouldUseHighResolutionTimers = true; #endif @@ -79,6 +80,7 @@ Settings::Settings(Page* page) , m_loadsImagesAutomatically(false) , m_privateBrowsingEnabled(false) , m_caretBrowsingEnabled(false) + , m_areImagesEnabled(true) , m_arePluginsEnabled(false) , m_databasesEnabled(false) , m_localStorageEnabled(false) @@ -115,7 +117,7 @@ Settings::Settings(Page* page) , m_usesEncodingDetector(false) , m_allowScriptsToCloseWindows(false) , m_editingBehavior( -#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN)) +#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN)) // (PLATFORM(MAC) is always false in Chromium, hence the extra condition.) EditingMacBehavior #else @@ -132,6 +134,7 @@ Settings::Settings(Page* page) , m_experimentalNotificationsEnabled(false) , m_webGLEnabled(false) , m_geolocationEnabled(true) + , m_loadDeferringEnabled(true) { // A Frame may not have been created yet, so we initialize the AtomicString // hash before trying to use it. @@ -263,6 +266,11 @@ void Settings::setJavaEnabled(bool isJavaEnabled) m_isJavaEnabled = isJavaEnabled; } +void Settings::setImagesEnabled(bool areImagesEnabled) +{ + m_areImagesEnabled = areImagesEnabled; +} + void Settings::setPluginsEnabled(bool arePluginsEnabled) { m_arePluginsEnabled = arePluginsEnabled; @@ -727,7 +735,7 @@ void Settings::setPluginAllowedRunTime(unsigned runTime) m_page->pluginAllowedRunTimeChanged(); } -#if PLATFORM(WIN) || (PLATFORM(WIN_OS) && PLATFORM(WX)) +#if PLATFORM(WIN) || (OS(WINDOWS) && PLATFORM(WX)) void Settings::setShouldUseHighResolutionTimers(bool shouldUseHighResolutionTimers) { gShouldUseHighResolutionTimers = shouldUseHighResolutionTimers; @@ -744,4 +752,9 @@ void Settings::setGeolocationEnabled(bool enabled) m_geolocationEnabled = enabled; } +void Settings::setLoadDeferringEnabled(bool enabled) +{ + m_loadDeferringEnabled = enabled; +} + } // namespace WebCore diff --git a/WebCore/page/Settings.h b/WebCore/page/Settings.h index fbb70b0..8a553de 100644 --- a/WebCore/page/Settings.h +++ b/WebCore/page/Settings.h @@ -117,6 +117,8 @@ namespace WebCore { void setDefaultFixedFontSize(int); int defaultFixedFontSize() const { return m_defaultFixedFontSize; } + // Unlike areImagesEnabled, this only suppresses the network load of + // the image URL. A cached image will still be rendered if requested. void setLoadsImagesAutomatically(bool); bool loadsImagesAutomatically() const { return m_loadsImagesAutomatically; } @@ -139,6 +141,9 @@ namespace WebCore { void setJavaEnabled(bool); bool isJavaEnabled() const { return m_isJavaEnabled; } + void setImagesEnabled(bool); + bool areImagesEnabled() const { return m_areImagesEnabled; } + void setPluginsEnabled(bool); bool arePluginsEnabled() const { return m_arePluginsEnabled; } @@ -323,7 +328,7 @@ namespace WebCore { void setExperimentalNotificationsEnabled(bool); bool experimentalNotificationsEnabled() const { return m_experimentalNotificationsEnabled; } -#if PLATFORM(WIN) || (PLATFORM(WIN_OS) && PLATFORM(WX)) +#if PLATFORM(WIN) || (OS(WINDOWS) && PLATFORM(WX)) static void setShouldUseHighResolutionTimers(bool); static bool shouldUseHighResolutionTimers() { return gShouldUseHighResolutionTimers; } #endif @@ -337,6 +342,9 @@ namespace WebCore { void setGeolocationEnabled(bool); bool geolocationEnabled() const { return m_geolocationEnabled; } + void setLoadDeferringEnabled(bool); + bool loadDeferringEnabled() const { return m_loadDeferringEnabled; } + private: Page* m_page; @@ -400,6 +408,7 @@ namespace WebCore { bool m_loadsImagesAutomatically : 1; bool m_privateBrowsingEnabled : 1; bool m_caretBrowsingEnabled : 1; + bool m_areImagesEnabled : 1; bool m_arePluginsEnabled : 1; bool m_databasesEnabled : 1; bool m_localStorageEnabled : 1; @@ -444,11 +453,12 @@ namespace WebCore { bool m_experimentalNotificationsEnabled : 1; bool m_webGLEnabled : 1; bool m_geolocationEnabled : 1; + bool m_loadDeferringEnabled : 1; #if USE(SAFARI_THEME) static bool gShouldPaintNativeControls; #endif -#if PLATFORM(WIN) || (PLATFORM(WIN_OS) && PLATFORM(WX)) +#if PLATFORM(WIN) || (OS(WINDOWS) && PLATFORM(WX)) static bool gShouldUseHighResolutionTimers; #endif }; diff --git a/WebCore/page/WebKitPoint.idl b/WebCore/page/WebKitPoint.idl index 1eefbc3..fd617b2 100644 --- a/WebCore/page/WebKitPoint.idl +++ b/WebCore/page/WebKitPoint.idl @@ -25,7 +25,7 @@ module window { - interface WebKitPoint { + interface [CustomConstructor] WebKitPoint { attribute float x; attribute float y; }; diff --git a/WebCore/page/WorkerNavigator.idl b/WebCore/page/WorkerNavigator.idl index 195f0bc..ec75f8a 100644 --- a/WebCore/page/WorkerNavigator.idl +++ b/WebCore/page/WorkerNavigator.idl @@ -30,7 +30,8 @@ module threads { interface [ Conditional=WORKERS, - NoStaticTables + NoStaticTables, + OmitConstructor ] WorkerNavigator { readonly attribute DOMString appName; readonly attribute DOMString appVersion; diff --git a/WebCore/page/XSSAuditor.cpp b/WebCore/page/XSSAuditor.cpp index 72c2591..0129b52 100644 --- a/WebCore/page/XSSAuditor.cpp +++ b/WebCore/page/XSSAuditor.cpp @@ -105,7 +105,12 @@ bool XSSAuditor::canEvaluate(const String& code) const if (!isEnabled()) return true; - if (findInRequest(code, false, true)) { + FindTask task; + task.string = code; + task.decodeEntities = false; + task.allowRequestIfNoIllegalURICharacters = true; + + if (findInRequest(task)) { 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, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String()); return false; @@ -118,7 +123,11 @@ bool XSSAuditor::canEvaluateJavaScriptURL(const String& code) const if (!isEnabled()) return true; - if (findInRequest(code, true, false, true)) { + FindTask task; + task.string = code; + task.decodeURLEscapeSequencesTwice = true; + + if (findInRequest(task)) { 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, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String()); return false; @@ -131,7 +140,11 @@ bool XSSAuditor::canCreateInlineEventListener(const String&, const String& code) if (!isEnabled()) return true; - if (findInRequest(code, true, true)) { + FindTask task; + task.string = code; + task.allowRequestIfNoIllegalURICharacters = true; + + if (findInRequest(task)) { 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, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String()); return false; @@ -147,7 +160,11 @@ bool XSSAuditor::canLoadExternalScriptFromSrc(const String& context, const Strin if (isSameOriginResource(url)) return true; - if (findInRequest(context + url)) { + FindTask task; + task.context = context; + task.string = url; + + if (findInRequest(task)) { 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, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String()); return false; @@ -163,7 +180,11 @@ bool XSSAuditor::canLoadObject(const String& url) const if (isSameOriginResource(url)) return true; - if (findInRequest(url)) { + FindTask task; + task.string = url; + task.allowRequestIfNoIllegalURICharacters = true; + + if (findInRequest(task)) { String consoleMessage = String::format("Refused to load an object. URL found within request: \"%s\".\n", url.utf8().data()); m_frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String()); return false; @@ -179,7 +200,11 @@ bool XSSAuditor::canSetBaseElementURL(const String& url) const if (isSameOriginResource(url)) return true; - if (findInRequest(url)) { + FindTask task; + task.string = url; + task.allowRequestIfNoIllegalURICharacters = true; + + if (findInRequest(task)) { DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to load from document base URL. URL found within request.\n")); m_frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String()); return false; @@ -265,20 +290,18 @@ bool XSSAuditor::isSameOriginResource(const String& url) const return (m_frame->document()->url().host() == resourceURL.host() && resourceURL.query().isEmpty()); } -bool XSSAuditor::findInRequest(const String& string, bool decodeEntities, bool allowRequestIfNoIllegalURICharacters, - bool decodeURLEscapeSequencesTwice) const +bool XSSAuditor::findInRequest(const FindTask& task) const { bool result = false; Frame* parentFrame = m_frame->tree()->parent(); if (parentFrame && m_frame->document()->url() == blankURL()) - result = findInRequest(parentFrame, string, decodeEntities, allowRequestIfNoIllegalURICharacters, decodeURLEscapeSequencesTwice); + result = findInRequest(parentFrame, task); if (!result) - result = findInRequest(m_frame, string, decodeEntities, allowRequestIfNoIllegalURICharacters, decodeURLEscapeSequencesTwice); + result = findInRequest(m_frame, task); return result; } -bool XSSAuditor::findInRequest(Frame* frame, const String& string, bool decodeEntities, bool allowRequestIfNoIllegalURICharacters, - bool decodeURLEscapeSequencesTwice) const +bool XSSAuditor::findInRequest(Frame* frame, const FindTask& task) const { ASSERT(frame->document()); @@ -287,17 +310,19 @@ bool XSSAuditor::findInRequest(Frame* frame, const String& string, bool decodeEn return false; } - if (string.isEmpty()) + if (task.string.isEmpty()) return false; FormData* formDataObj = frame->loader()->documentLoader()->originalRequest().httpBody(); + const bool hasFormData = formDataObj && !formDataObj->isEmpty(); String pageURL = frame->document()->url().string(); - if (!formDataObj && string.length() >= 2 * pageURL.length()) { + String canonicalizedString; + if (!hasFormData && task.string.length() > 2 * pageURL.length()) { // Q: Why do we bother to do this check at all? // A: Canonicalizing large inline scripts can be expensive. We want to - // bail out before the call to canonicalize below, which could - // result in an unneeded allocation and memcpy. + // reduce the size of the string before we call canonicalize below, + // since it could result in an unneeded allocation and memcpy. // // Q: Why do we multiply by two here? // A: We attempt to detect reflected XSS even when the server @@ -305,39 +330,32 @@ bool XSSAuditor::findInRequest(Frame* frame, const String& string, bool decodeEn // attacker can do get the server to inflate his/her input by a // factor of two by sending " characters, which the server // transforms to \". - return false; - } + canonicalizedString = task.string.substring(0, 2 * pageURL.length()); + } else + canonicalizedString = task.string; if (frame->document()->url().protocolIs("data")) return false; - String canonicalizedString = canonicalize(string); + canonicalizedString = canonicalize(canonicalizedString); if (canonicalizedString.isEmpty()) return false; - if (string.length() < pageURL.length()) { - // The string can actually fit inside the pageURL. - String decodedPageURL = m_cache.canonicalizeURL(pageURL, frame->document()->decoder()->encoding(), decodeEntities, decodeURLEscapeSequencesTwice); + if (!task.context.isEmpty()) + canonicalizedString = task.context + canonicalizedString; - if (allowRequestIfNoIllegalURICharacters && (!formDataObj || formDataObj->isEmpty()) - && decodedPageURL.find(&isIllegalURICharacter, 0) == -1) - return false; // Injection is impossible because the request does not contain any illegal URI characters. + String decodedPageURL = m_cache.canonicalizeURL(pageURL, frame->document()->decoder()->encoding(), task.decodeEntities, task.decodeURLEscapeSequencesTwice); - if (decodedPageURL.find(canonicalizedString, 0, false) != -1) - return true; // We've found the smoking gun. - } + if (task.allowRequestIfNoIllegalURICharacters && !hasFormData && decodedPageURL.find(&isIllegalURICharacter, 0) == -1) + return false; // Injection is impossible because the request does not contain any illegal URI characters. - 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 = m_cache.canonicalizeURL(formData, frame->document()->decoder()->encoding(), decodeEntities, decodeURLEscapeSequencesTwice); - if (decodedFormData.find(canonicalizedString, 0, false) != -1) - return true; // We found the string in the POST data. - } + if (decodedPageURL.find(canonicalizedString, 0, false) != -1) + return true; // We've found the string in the GET data. + + if (hasFormData) { + String decodedFormData = m_cache.canonicalizeURL(formDataObj->flattenToString(), frame->document()->decoder()->encoding(), task.decodeEntities, task.decodeURLEscapeSequencesTwice); + if (decodedFormData.find(canonicalizedString, 0, false) != -1) + return true; // We found the string in the POST data. } return false; diff --git a/WebCore/page/XSSAuditor.h b/WebCore/page/XSSAuditor.h index b64665b..d976f52 100644 --- a/WebCore/page/XSSAuditor.h +++ b/WebCore/page/XSSAuditor.h @@ -120,16 +120,29 @@ namespace WebCore { String m_cachedCanonicalizedURL; }; + struct FindTask { + FindTask() + : decodeEntities(true) + , allowRequestIfNoIllegalURICharacters(false) + , decodeURLEscapeSequencesTwice(false) + { + } + + String context; + String string; + bool decodeEntities; + bool allowRequestIfNoIllegalURICharacters; + bool decodeURLEscapeSequencesTwice; + }; + static String canonicalize(const String&); static String decodeURL(const String& url, const TextEncoding& encoding, bool decodeEntities, bool decodeURLEscapeSequencesTwice = false); static String decodeHTMLEntities(const String&, bool leaveUndecodableEntitiesUntouched = true); bool isSameOriginResource(const String& url) const; - bool findInRequest(const String&, bool decodeEntities = true, bool allowRequestIfNoIllegalURICharacters = false, - bool decodeURLEscapeSequencesTwice = false) const; - bool findInRequest(Frame*, const String&, bool decodeEntities = true, bool allowRequestIfNoIllegalURICharacters = false, - bool decodeURLEscapeSequencesTwice = false) const; + bool findInRequest(const FindTask&) const; + bool findInRequest(Frame*, const FindTask&) const; // The frame to audit. Frame* m_frame; diff --git a/WebCore/page/animation/AnimationBase.cpp b/WebCore/page/animation/AnimationBase.cpp index f1ee750..2a2ab4b 100644 --- a/WebCore/page/animation/AnimationBase.cpp +++ b/WebCore/page/animation/AnimationBase.cpp @@ -92,10 +92,17 @@ static inline Color blendFunc(const AnimationBase* anim, const Color& from, cons if (progress == 1 && !to.isValid()) return Color(); - return Color(blendFunc(anim, from.red(), to.red(), progress), - blendFunc(anim, from.green(), to.green(), progress), - blendFunc(anim, from.blue(), to.blue(), progress), - blendFunc(anim, from.alpha(), to.alpha(), progress)); + // Contrary to the name, RGBA32 actually stores ARGB, so we can initialize Color directly from premultipliedARGBFromColor(). + // Also, premultipliedARGBFromColor() bails on zero alpha, so special-case that. + Color premultFrom = from.alpha() ? premultipliedARGBFromColor(from) : 0; + Color premultTo = to.alpha() ? premultipliedARGBFromColor(to) : 0; + + Color premultBlended(blendFunc(anim, premultFrom.red(), premultTo.red(), progress), + blendFunc(anim, premultFrom.green(), premultTo.green(), progress), + blendFunc(anim, premultFrom.blue(), premultTo.blue(), progress), + blendFunc(anim, premultFrom.alpha(), premultTo.alpha(), progress)); + + return Color(colorFromPremultipliedARGB(premultBlended.rgb())); } static inline Length blendFunc(const AnimationBase*, const Length& from, const Length& to, double progress) @@ -407,7 +414,7 @@ public: }; template <typename T> -class FillLayerPropertyWrapperGetter : public FillLayerPropertyWrapperBase { +class FillLayerPropertyWrapperGetter : public FillLayerPropertyWrapperBase, public Noncopyable { public: FillLayerPropertyWrapperGetter(T (FillLayer::*getter)() const) : m_getter(getter) @@ -863,7 +870,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param) m_pauseTime = -1; m_requestedStartTime = 0; m_nextIterationDuration = -1; - endAnimation(false); + endAnimation(); return; } @@ -875,7 +882,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param) m_pauseTime = -1; m_requestedStartTime = 0; m_nextIterationDuration = -1; - endAnimation(false); + endAnimation(); if (!paused()) updateStateMachine(AnimationStateInputStartAnimation, -1); @@ -886,7 +893,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param) if (m_animState == AnimationStateStartWaitStyleAvailable) m_compAnim->animationController()->removeFromStyleAvailableWaitList(this); m_animState = AnimationStateDone; - endAnimation(true); + endAnimation(); return; } @@ -894,7 +901,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param) if (m_animState == AnimationStateStartWaitResponse) { // If we are in AnimationStateStartWaitResponse, the animation will get canceled before // we get a response, so move to the next state. - endAnimation(false); + endAnimation(); updateStateMachine(AnimationStateInputStartTimeSet, beginAnimationUpdateTime()); } return; @@ -903,7 +910,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param) if (input == AnimationStateInputResumeOverride) { if (m_animState == AnimationStateLooping || m_animState == AnimationStateEnding) { // Start the animation - startAnimation(m_startTime); + startAnimation(beginAnimationUpdateTime() - m_startTime); } return; } @@ -956,7 +963,12 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param) updateStateMachine(AnimationStateInputStartTimeSet, beginAnimationUpdateTime()); } else { - bool started = startAnimation(0); + double timeOffset = 0; + // If the value for 'animation-delay' is negative then the animation appears to have started in the past. + if (m_animation->delay() < 0) + timeOffset = -m_animation->delay(); + bool started = startAnimation(timeOffset); + m_compAnim->animationController()->addToStartTimeResponseWaitList(this, started); m_fallbackAnimating = !started; } @@ -967,8 +979,12 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param) if (input == AnimationStateInputStartTimeSet) { ASSERT(param >= 0); // We have a start time, set it, unless the startTime is already set - if (m_startTime <= 0) + if (m_startTime <= 0) { m_startTime = param; + // If the value for 'animation-delay' is negative then the animation appears to have started in the past. + if (m_animation->delay() < 0) + m_startTime += m_animation->delay(); + } // Decide whether to go into looping or ending state goIntoEndingOrLoopingState(); @@ -980,7 +996,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param) // We are pausing while waiting for a start response. Cancel the animation and wait. When // we unpause, we will act as though the start timer just fired m_pauseTime = -1; - endAnimation(false); + pauseAnimation(beginAnimationUpdateTime() - m_startTime); m_animState = AnimationStatePausedWaitResponse; } break; @@ -997,7 +1013,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param) } else { // We are pausing while running. Cancel the animation and wait m_pauseTime = beginAnimationUpdateTime(); - endAnimation(false); + pauseAnimation(beginAnimationUpdateTime() - m_startTime); m_animState = AnimationStatePausedRun; } break; @@ -1020,7 +1036,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param) } else { // We are pausing while running. Cancel the animation and wait m_pauseTime = beginAnimationUpdateTime(); - endAnimation(false); + pauseAnimation(beginAnimationUpdateTime() - m_startTime); m_animState = AnimationStatePausedRun; } // |this| may be deleted here @@ -1072,7 +1088,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param) updateStateMachine(AnimationStateInputStartTimeSet, beginAnimationUpdateTime()); m_fallbackAnimating = true; } else { - bool started = startAnimation(m_startTime); + bool started = startAnimation(beginAnimationUpdateTime() - m_startTime); m_compAnim->animationController()->addToStartTimeResponseWaitList(this, started); m_fallbackAnimating = !started; } diff --git a/WebCore/page/animation/AnimationBase.h b/WebCore/page/animation/AnimationBase.h index 3482f65..c367e0a 100644 --- a/WebCore/page/animation/AnimationBase.h +++ b/WebCore/page/animation/AnimationBase.h @@ -186,8 +186,13 @@ protected: virtual void onAnimationStart(double /*elapsedTime*/) { } virtual void onAnimationIteration(double /*elapsedTime*/) { } virtual void onAnimationEnd(double /*elapsedTime*/) { } - virtual bool startAnimation(double /*beginTime*/) { return false; } - virtual void endAnimation(bool /*reset*/) { } + + // timeOffset is an offset from the current time when the animation should start. Negative values are OK. + // Return value indicates whether to expect an asynchronous notifyAnimationStarted() callback. + virtual bool startAnimation(double /*timeOffset*/) { return false; } + // timeOffset is the time at which the animation is being paused. + virtual void pauseAnimation(double /*timeOffset*/) { } + virtual void endAnimation() { } void goIntoEndingOrLoopingState(); diff --git a/WebCore/page/animation/AnimationController.cpp b/WebCore/page/animation/AnimationController.cpp index aa5de2c..422c154 100644 --- a/WebCore/page/animation/AnimationController.cpp +++ b/WebCore/page/animation/AnimationController.cpp @@ -484,7 +484,7 @@ PassRefPtr<RenderStyle> AnimationController::updateAnimations(RenderObject* rend m_data->updateAnimationTimer(); if (blendedStyle != newStyle) { - // If the animations/transitions change opacity or transform, we neeed to update + // If the animations/transitions change opacity or transform, we need to update // the style to impose the stacking rules. Note that this is also // done in CSSStyleSelector::adjustRenderStyle(). if (blendedStyle->hasAutoZIndex() && (blendedStyle->opacity() < 1.0f || blendedStyle->hasTransform())) diff --git a/WebCore/page/animation/AnimationControllerPrivate.h b/WebCore/page/animation/AnimationControllerPrivate.h index 7db3803..682dd75 100644 --- a/WebCore/page/animation/AnimationControllerPrivate.h +++ b/WebCore/page/animation/AnimationControllerPrivate.h @@ -49,7 +49,7 @@ class Node; class RenderObject; class RenderStyle; -class AnimationControllerPrivate { +class AnimationControllerPrivate : public Noncopyable { public: AnimationControllerPrivate(Frame*); ~AnimationControllerPrivate(); diff --git a/WebCore/page/animation/CompositeAnimation.cpp b/WebCore/page/animation/CompositeAnimation.cpp index 8946d80..34f03c7 100644 --- a/WebCore/page/animation/CompositeAnimation.cpp +++ b/WebCore/page/animation/CompositeAnimation.cpp @@ -57,6 +57,7 @@ void CompositeAnimation::clearRenderer() } } if (!m_keyframeAnimations.isEmpty()) { + m_keyframeAnimations.checkConsistency(); AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end(); for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) { KeyframeAnimation* anim = it->second.get(); @@ -186,6 +187,8 @@ void CompositeAnimation::updateKeyframeAnimations(RenderObject* renderer, Render if (m_keyframeAnimations.isEmpty() && !targetStyle->hasAnimations()) return; + m_keyframeAnimations.checkConsistency(); + AnimationNameMap::const_iterator kfend = m_keyframeAnimations.end(); if (currentStyle && currentStyle->hasAnimations() && targetStyle->hasAnimations() && *(currentStyle->animations()) == *(targetStyle->animations())) { @@ -262,6 +265,7 @@ PassRefPtr<RenderStyle> CompositeAnimation::animate(RenderObject* renderer, Rend // We don't do any transitions if we don't have a currentStyle (on startup). updateTransitions(renderer, currentStyle, targetStyle); updateKeyframeAnimations(renderer, currentStyle, targetStyle); + m_keyframeAnimations.checkConsistency(); if (currentStyle) { // Now that we have transition objects ready, let them know about the new goal state. We want them @@ -295,6 +299,8 @@ PassRefPtr<RenderStyle> CompositeAnimation::getAnimatedStyle() const implicitAnimation->getAnimatedStyle(resultStyle); } + m_keyframeAnimations.checkConsistency(); + for (Vector<AtomicStringImpl*>::const_iterator it = m_keyframeAnimationOrderMap.begin(); it != m_keyframeAnimationOrderMap.end(); ++it) { RefPtr<KeyframeAnimation> keyframeAnimation = m_keyframeAnimations.get(*it); if (keyframeAnimation) @@ -315,6 +321,7 @@ void CompositeAnimation::setAnimating(bool animating) } } if (!m_keyframeAnimations.isEmpty()) { + m_keyframeAnimations.checkConsistency(); AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end(); for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) { KeyframeAnimation* anim = it->second.get(); @@ -341,6 +348,7 @@ double CompositeAnimation::timeToNextService() const } } if (!m_keyframeAnimations.isEmpty()) { + m_keyframeAnimations.checkConsistency(); AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end(); for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) { KeyframeAnimation* animation = it->second.get(); @@ -362,6 +370,7 @@ PassRefPtr<KeyframeAnimation> CompositeAnimation::getAnimationForProperty(int pr // We want to send back the last animation with the property if there are multiples. // So we need to iterate through all animations if (!m_keyframeAnimations.isEmpty()) { + m_keyframeAnimations.checkConsistency(); AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end(); for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) { RefPtr<KeyframeAnimation> anim = it->second; @@ -381,6 +390,7 @@ void CompositeAnimation::suspendAnimations() m_isSuspended = true; if (!m_keyframeAnimations.isEmpty()) { + m_keyframeAnimations.checkConsistency(); AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end(); for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) { if (KeyframeAnimation* anim = it->second.get()) @@ -405,6 +415,7 @@ void CompositeAnimation::resumeAnimations() m_isSuspended = false; if (!m_keyframeAnimations.isEmpty()) { + m_keyframeAnimations.checkConsistency(); AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end(); for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) { KeyframeAnimation* anim = it->second.get(); @@ -450,6 +461,7 @@ void CompositeAnimation::resumeOverriddenImplicitAnimations(int property) bool CompositeAnimation::isAnimatingProperty(int property, bool isRunningNow) const { if (!m_keyframeAnimations.isEmpty()) { + m_keyframeAnimations.checkConsistency(); AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end(); for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) { KeyframeAnimation* anim = it->second.get(); @@ -474,6 +486,8 @@ bool CompositeAnimation::pauseAnimationAtTime(const AtomicString& name, double t if (!name) return false; + m_keyframeAnimations.checkConsistency(); + RefPtr<KeyframeAnimation> keyframeAnim = m_keyframeAnimations.get(name.impl()); if (!keyframeAnim || !keyframeAnim->running()) return false; @@ -509,6 +523,7 @@ unsigned CompositeAnimation::numberOfActiveAnimations() const unsigned count = 0; if (!m_keyframeAnimations.isEmpty()) { + m_keyframeAnimations.checkConsistency(); AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end(); for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) { KeyframeAnimation* anim = it->second.get(); diff --git a/WebCore/page/animation/ImplicitAnimation.cpp b/WebCore/page/animation/ImplicitAnimation.cpp index 50fc781..328fe0e 100644 --- a/WebCore/page/animation/ImplicitAnimation.cpp +++ b/WebCore/page/animation/ImplicitAnimation.cpp @@ -55,7 +55,7 @@ ImplicitAnimation::~ImplicitAnimation() { // // Make sure to tell the renderer that we are ending. This will make sure any accelerated animations are removed. if (!postActive()) - endAnimation(true); + endAnimation(); } bool ImplicitAnimation::shouldSendEventForListener(Document::ListenerType inListenerType) const @@ -106,21 +106,21 @@ void ImplicitAnimation::getAnimatedStyle(RefPtr<RenderStyle>& animatedStyle) blendProperties(this, m_animatingProperty, animatedStyle.get(), m_fromStyle.get(), m_toStyle.get(), progress(1, 0, 0)); } -bool ImplicitAnimation::startAnimation(double beginTime) +bool ImplicitAnimation::startAnimation(double timeOffset) { #if USE(ACCELERATED_COMPOSITING) if (m_object && m_object->hasLayer()) { RenderLayer* layer = toRenderBoxModelObject(m_object)->layer(); if (layer->isComposited()) - return layer->backing()->startTransition(beginTime, m_animatingProperty, m_fromStyle.get(), m_toStyle.get()); + return layer->backing()->startTransition(timeOffset, m_animatingProperty, m_fromStyle.get(), m_toStyle.get()); } #else - UNUSED_PARAM(beginTime); + UNUSED_PARAM(timeOffset); #endif return false; } -void ImplicitAnimation::endAnimation(bool /*reset*/) +void ImplicitAnimation::endAnimation() { #if USE(ACCELERATED_COMPOSITING) if (m_object && m_object->hasLayer()) { @@ -143,7 +143,7 @@ void ImplicitAnimation::onAnimationEnd(double elapsedTime) keyframeAnim->setUnanimatedStyle(m_toStyle); sendTransitionEvent(eventNames().webkitTransitionEndEvent, elapsedTime); - endAnimation(true); + endAnimation(); } bool ImplicitAnimation::sendTransitionEvent(const AtomicString& eventType, double elapsedTime) @@ -161,7 +161,7 @@ bool ImplicitAnimation::sendTransitionEvent(const AtomicString& eventType, doubl if (m_object->node() && m_object->node()->isElementNode()) element = static_cast<Element*>(m_object->node()); - ASSERT(!element || element->document() && !element->document()->inPageCache()); + ASSERT(!element || (element->document() && !element->document()->inPageCache())); if (!element) return false; diff --git a/WebCore/page/animation/ImplicitAnimation.h b/WebCore/page/animation/ImplicitAnimation.h index 7e286d2..be5c197 100644 --- a/WebCore/page/animation/ImplicitAnimation.h +++ b/WebCore/page/animation/ImplicitAnimation.h @@ -47,8 +47,9 @@ public: int animatingProperty() const { return m_animatingProperty; } virtual void onAnimationEnd(double elapsedTime); - virtual bool startAnimation(double beginTime); - virtual void endAnimation(bool reset); + virtual bool startAnimation(double timeOffset); + virtual void pauseAnimation(double /*timeOffset*/) { } + virtual void endAnimation(); virtual void animate(CompositeAnimation*, RenderObject*, const RenderStyle* currentStyle, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle); virtual void getAnimatedStyle(RefPtr<RenderStyle>& animatedStyle); diff --git a/WebCore/page/animation/KeyframeAnimation.cpp b/WebCore/page/animation/KeyframeAnimation.cpp index 500bf6f..c5e3660 100644 --- a/WebCore/page/animation/KeyframeAnimation.cpp +++ b/WebCore/page/animation/KeyframeAnimation.cpp @@ -59,7 +59,7 @@ KeyframeAnimation::~KeyframeAnimation() { // Make sure to tell the renderer that we are ending. This will make sure any accelerated animations are removed. if (!postActive()) - endAnimation(true); + endAnimation(); } void KeyframeAnimation::getKeyframeAnimationInterval(const RenderStyle*& fromStyle, const RenderStyle*& toStyle, double& prog) const @@ -192,40 +192,54 @@ bool KeyframeAnimation::hasAnimationForProperty(int property) const return false; } -bool KeyframeAnimation::startAnimation(double beginTime) +bool KeyframeAnimation::startAnimation(double timeOffset) { #if USE(ACCELERATED_COMPOSITING) if (m_object && m_object->hasLayer()) { RenderLayer* layer = toRenderBoxModelObject(m_object)->layer(); if (layer->isComposited()) - return layer->backing()->startAnimation(beginTime, m_animation.get(), m_keyframes); + return layer->backing()->startAnimation(timeOffset, m_animation.get(), m_keyframes); } #else - UNUSED_PARAM(beginTime); + UNUSED_PARAM(timeOffset); #endif return false; } -void KeyframeAnimation::endAnimation(bool reset) +void KeyframeAnimation::pauseAnimation(double timeOffset) { - if (m_object) { + if (!m_object) + return; + #if USE(ACCELERATED_COMPOSITING) - if (m_object->hasLayer()) { - RenderLayer* layer = toRenderBoxModelObject(m_object)->layer(); - if (layer->isComposited()) { - if (reset) - layer->backing()->animationFinished(m_keyframes.animationName()); - else - layer->backing()->animationPaused(m_keyframes.animationName()); - } - } + if (m_object->hasLayer()) { + RenderLayer* layer = toRenderBoxModelObject(m_object)->layer(); + if (layer->isComposited()) + layer->backing()->animationPaused(timeOffset, m_keyframes.animationName()); + } #else - UNUSED_PARAM(reset); + UNUSED_PARAM(timeOffset); #endif - // Restore the original (unanimated) style - if (!paused()) - setNeedsStyleRecalc(m_object->node()); + // Restore the original (unanimated) style + if (!paused()) + setNeedsStyleRecalc(m_object->node()); +} + +void KeyframeAnimation::endAnimation() +{ + if (!m_object) + return; + +#if USE(ACCELERATED_COMPOSITING) + if (m_object->hasLayer()) { + RenderLayer* layer = toRenderBoxModelObject(m_object)->layer(); + if (layer->isComposited()) + layer->backing()->animationFinished(m_keyframes.animationName()); } +#endif + // Restore the original (unanimated) style + if (!paused()) + setNeedsStyleRecalc(m_object->node()); } bool KeyframeAnimation::shouldSendEventForListener(Document::ListenerType listenerType) const @@ -246,7 +260,7 @@ void KeyframeAnimation::onAnimationIteration(double elapsedTime) void KeyframeAnimation::onAnimationEnd(double elapsedTime) { sendAnimationEvent(eventNames().webkitAnimationEndEvent, elapsedTime); - endAnimation(true); + endAnimation(); } bool KeyframeAnimation::sendAnimationEvent(const AtomicString& eventType, double elapsedTime) @@ -267,7 +281,7 @@ bool KeyframeAnimation::sendAnimationEvent(const AtomicString& eventType, double if (m_object->node() && m_object->node()->isElementNode()) element = static_cast<Element*>(m_object->node()); - ASSERT(!element || element->document() && !element->document()->inPageCache()); + ASSERT(!element || (element->document() && !element->document()->inPageCache())); if (!element) return false; diff --git a/WebCore/page/animation/KeyframeAnimation.h b/WebCore/page/animation/KeyframeAnimation.h index e3b8f53..fab0ae8 100644 --- a/WebCore/page/animation/KeyframeAnimation.h +++ b/WebCore/page/animation/KeyframeAnimation.h @@ -64,8 +64,9 @@ protected: virtual void onAnimationStart(double elapsedTime); virtual void onAnimationIteration(double elapsedTime); virtual void onAnimationEnd(double elapsedTime); - virtual bool startAnimation(double beginTime); - virtual void endAnimation(bool reset); + virtual bool startAnimation(double timeOffset); + virtual void pauseAnimation(double timeOffset); + virtual void endAnimation(); virtual void overrideAnimations(); virtual void resumeOverriddenAnimations(); diff --git a/WebCore/page/chromium/DragControllerChromium.cpp b/WebCore/page/chromium/DragControllerChromium.cpp index 18688fd..7b0958d 100644 --- a/WebCore/page/chromium/DragControllerChromium.cpp +++ b/WebCore/page/chromium/DragControllerChromium.cpp @@ -31,7 +31,7 @@ #include "SelectionController.h" #include <wtf/RefPtr.h> -#if PLATFORM(WIN_OS) +#if OS(WINDOWS) #include <windows.h> #endif @@ -57,7 +57,7 @@ DragOperation DragController::dragOperation(DragData* dragData) bool DragController::isCopyKeyDown() { // FIXME: This should not be OS specific. Delegate to the embedder instead. -#if PLATFORM(WIN_OS) +#if OS(WINDOWS) return ::GetAsyncKeyState(VK_CONTROL); #else return false; diff --git a/WebCore/page/chromium/EventHandlerChromium.cpp b/WebCore/page/chromium/EventHandlerChromium.cpp index ac76a29..ff161af 100644 --- a/WebCore/page/chromium/EventHandlerChromium.cpp +++ b/WebCore/page/chromium/EventHandlerChromium.cpp @@ -46,7 +46,7 @@ namespace WebCore { -#if PLATFORM(DARWIN) +#if OS(DARWIN) const double EventHandler::TextDragDelay = 0.15; #else const double EventHandler::TextDragDelay = 0.0; @@ -147,14 +147,14 @@ bool EventHandler::passWidgetMouseDownEventToWidget(RenderWidget* renderWidget) unsigned EventHandler::accessKeyModifiers() { -#if PLATFORM(DARWIN) +#if OS(DARWIN) return PlatformKeyboardEvent::CtrlKey | PlatformKeyboardEvent::AltKey; #else return PlatformKeyboardEvent::AltKey; #endif } -#if PLATFORM(LINUX) +#if OS(LINUX) // GTK+ must scroll horizontally if the mouse pointer is on top of the // horizontal scrollbar while scrolling with the wheel. // This code comes from gtk/EventHandlerGtk.cpp. diff --git a/WebCore/page/chromium/FrameChromium.cpp b/WebCore/page/chromium/FrameChromium.cpp index d79ae68..548e0fa 100644 --- a/WebCore/page/chromium/FrameChromium.cpp +++ b/WebCore/page/chromium/FrameChromium.cpp @@ -25,7 +25,6 @@ */ #include "config.h" -#include "FrameChromium.h" #include "Document.h" #include "FloatRect.h" @@ -36,57 +35,6 @@ using std::min; namespace WebCore { -void computePageRectsForFrame(Frame* frame, const IntRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, Vector<IntRect>& pages, int& outPageHeight) -{ - ASSERT(frame); - - pages.clear(); - outPageHeight = 0; - - if (!frame->document() || !frame->view() || !frame->document()->renderer()) - return; - - RenderView* root = toRenderView(frame->document()->renderer()); - - if (!root) { - LOG_ERROR("document to be printed has no renderer"); - return; - } - - if (userScaleFactor <= 0) { - LOG_ERROR("userScaleFactor has bad value %.2f", userScaleFactor); - return; - } - - float ratio = static_cast<float>(printRect.height()) / static_cast<float>(printRect.width()); - - float pageWidth = static_cast<float>(root->rightLayoutOverflow()); - float pageHeight = pageWidth * ratio; - outPageHeight = static_cast<int>(pageHeight); // this is the height of the page adjusted by margins - pageHeight -= (headerHeight + footerHeight); - - if (pageHeight <= 0) { - LOG_ERROR("pageHeight has bad value %.2f", pageHeight); - return; - } - - float currPageHeight = pageHeight / userScaleFactor; - float docHeight = root->layer()->height(); - float currPageWidth = pageWidth / userScaleFactor; - - - // always return at least one page, since empty files should print a blank page - float printedPagesHeight = 0.0f; - do { - float proposedBottom = min(docHeight, printedPagesHeight + pageHeight); - frame->view()->adjustPageHeight(&proposedBottom, printedPagesHeight, proposedBottom, printedPagesHeight); - currPageHeight = max(1.0f, proposedBottom - printedPagesHeight); - - pages.append(IntRect(0, printedPagesHeight, currPageWidth, currPageHeight)); - printedPagesHeight += currPageHeight; - } while (printedPagesHeight < docHeight); -} - DragImageRef Frame::dragImageForSelection() { if (selection()->isRange()) diff --git a/WebCore/page/chromium/FrameChromium.h b/WebCore/page/chromium/FrameChromium.h deleted file mode 100644 index faa78e7..0000000 --- a/WebCore/page/chromium/FrameChromium.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. - * Copyright (C) 2008 Google Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef FrameChromium_h -#define FrameChromium_h - -#include "Frame.h" - -namespace WebCore { - - // printRect is only used for the width/height ratio. Their absolute values aren't used. - void computePageRectsForFrame(Frame*, const IntRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, Vector<IntRect>& pages, int& pageHeight); - -} - -#endif diff --git a/WebCore/page/mac/ChromeMac.mm b/WebCore/page/mac/ChromeMac.mm index 14c07de..d2ae39d 100644 --- a/WebCore/page/mac/ChromeMac.mm +++ b/WebCore/page/mac/ChromeMac.mm @@ -25,7 +25,6 @@ namespace WebCore { -#if !ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE) void Chrome::focusNSView(NSView* view) { @@ -50,6 +49,4 @@ void Chrome::focusNSView(NSView* view) END_BLOCK_OBJC_EXCEPTIONS; } -#endif - } // namespace WebCore diff --git a/WebCore/page/mac/DragControllerMac.mm b/WebCore/page/mac/DragControllerMac.mm index adf89fa..f080232 100644 --- a/WebCore/page/mac/DragControllerMac.mm +++ b/WebCore/page/mac/DragControllerMac.mm @@ -49,6 +49,11 @@ DragOperation DragController::dragOperation(DragData*) return DragOperationNone; } +bool DragController::isCopyKeyDown() +{ + return false; +} + #else bool DragController::isCopyKeyDown() diff --git a/WebCore/page/mac/EventHandlerMac.mm b/WebCore/page/mac/EventHandlerMac.mm index 92895d9..91a2018 100644 --- a/WebCore/page/mac/EventHandlerMac.mm +++ b/WebCore/page/mac/EventHandlerMac.mm @@ -28,16 +28,18 @@ #include "AXObjectCache.h" #include "BlockExceptions.h" +#include "Chrome.h" #include "ChromeClient.h" #include "ClipboardMac.h" #include "DragController.h" #include "EventNames.h" #include "FocusController.h" -#include "FrameLoader.h" #include "Frame.h" +#include "FrameLoader.h" #include "FrameView.h" #include "KeyboardEvent.h" #include "MouseEventWithHitTestResults.h" +#include "NotImplemented.h" #include "Page.h" #include "PlatformKeyboardEvent.h" #include "PlatformWheelEvent.h" @@ -703,7 +705,7 @@ bool EventHandler::passWidgetMouseDownEventToWidget(const MouseEventWithHitTestR return false; } -bool EventHandler::eventActivatedView(const PlatformMouseEvent& event) const +bool EventHandler::eventActivatedView(const PlatformMouseEvent&) const { notImplemented(); return false; diff --git a/WebCore/page/mac/FrameMac.mm b/WebCore/page/mac/FrameMac.mm index fce5704..9e77387 100644 --- a/WebCore/page/mac/FrameMac.mm +++ b/WebCore/page/mac/FrameMac.mm @@ -143,7 +143,7 @@ static RegularExpression* regExpForLabels(NSArray* labels) return result; } -NSString* Frame::searchForNSLabelsAboveCell(RegularExpression* regExp, HTMLTableCellElement* cell) +NSString* Frame::searchForNSLabelsAboveCell(RegularExpression* regExp, HTMLTableCellElement* cell, size_t* resultDistanceFromStartOfCell) { RenderObject* cellRenderer = cell->renderer(); @@ -157,23 +157,30 @@ NSString* Frame::searchForNSLabelsAboveCell(RegularExpression* regExp, HTMLTable if (aboveCell) { // search within the above cell we found for a match + size_t lengthSearched = 0; for (Node* n = aboveCell->firstChild(); n; n = n->traverseNextNode(aboveCell)) { if (n->isTextNode() && n->renderer() && n->renderer()->style()->visibility() == VISIBLE) { // For each text chunk, run the regexp String nodeString = n->nodeValue(); int pos = regExp->searchRev(nodeString); - if (pos >= 0) + if (pos >= 0) { + if (resultDistanceFromStartOfCell) + *resultDistanceFromStartOfCell = lengthSearched; return nodeString.substring(pos, regExp->matchedLength()); + } + lengthSearched += nodeString.length(); } } } } } // Any reason in practice to search all cells in that are above cell? + if (resultDistanceFromStartOfCell) + *resultDistanceFromStartOfCell = notFound; return nil; } -NSString* Frame::searchForLabelsBeforeElement(NSArray* labels, Element* element) +NSString* Frame::searchForLabelsBeforeElement(NSArray* labels, Element* element, size_t* resultDistance, bool* resultIsInCellAbove) { RegularExpression* regExp = regExpForLabels(labels); // We stop searching after we've seen this many chars @@ -184,6 +191,11 @@ NSString* Frame::searchForLabelsBeforeElement(NSArray* labels, Element* element) // If the starting element is within a table, the cell that contains it HTMLTableCellElement* startingTableCell = 0; bool searchedCellAbove = false; + + if (resultDistance) + *resultDistance = notFound; + if (resultIsInCellAbove) + *resultIsInCellAbove = false; // walk backwards in the node tree, until another element, or form, or end of tree int unsigned lengthSearched = 0; @@ -200,9 +212,12 @@ NSString* Frame::searchForLabelsBeforeElement(NSArray* labels, Element* element) } else if (n->hasTagName(tdTag) && !startingTableCell) { startingTableCell = static_cast<HTMLTableCellElement*>(n); } else if (n->hasTagName(trTag) && startingTableCell) { - NSString* result = searchForLabelsAboveCell(regExp, startingTableCell); - if (result && [result length] > 0) + NSString* result = searchForLabelsAboveCell(regExp, startingTableCell, resultDistance); + if (result && [result length] > 0) { + if (resultIsInCellAbove) + *resultIsInCellAbove = true; return result; + } searchedCellAbove = true; } else if (n->isTextNode() && n->renderer() && n->renderer()->style()->visibility() == VISIBLE) { // For each text chunk, run the regexp @@ -211,9 +226,11 @@ NSString* Frame::searchForLabelsBeforeElement(NSArray* labels, Element* element) if (lengthSearched + nodeString.length() > maxCharsSearched) nodeString = nodeString.right(charsSearchedThreshold - lengthSearched); int pos = regExp->searchRev(nodeString); - if (pos >= 0) + if (pos >= 0) { + if (resultDistance) + *resultDistance = lengthSearched; return nodeString.substring(pos, regExp->matchedLength()); - + } lengthSearched += nodeString.length(); } } @@ -221,33 +238,37 @@ NSString* Frame::searchForLabelsBeforeElement(NSArray* labels, Element* element) // If we started in a cell, but bailed because we found the start of the form or the // previous element, we still might need to search the row above us for a label. if (startingTableCell && !searchedCellAbove) { - NSString* result = searchForLabelsAboveCell(regExp, startingTableCell); - if (result && [result length] > 0) + NSString* result = searchForLabelsAboveCell(regExp, startingTableCell, resultDistance); + if (result && [result length] > 0) { + if (resultIsInCellAbove) + *resultIsInCellAbove = true; return result; + } } return nil; } -NSString* Frame::matchLabelsAgainstElement(NSArray* labels, Element* element) +static NSString *matchLabelsAgainstString(NSArray *labels, const String& stringToMatch) { - String name = element->getAttribute(nameAttr); - if (name.isEmpty()) + if (stringToMatch.isEmpty()) return nil; - + + String mutableStringToMatch = stringToMatch; + // Make numbers and _'s in field names behave like word boundaries, e.g., "address2" - replace(name, RegularExpression("\\d", TextCaseSensitive), " "); - name.replace('_', ' '); - + replace(mutableStringToMatch, RegularExpression("\\d", TextCaseSensitive), " "); + mutableStringToMatch.replace('_', ' '); + RegularExpression* regExp = regExpForLabels(labels); - // Use the largest match we can find in the whole name string + // Use the largest match we can find in the whole string int pos; int length; int bestPos = -1; int bestLength = -1; int start = 0; do { - pos = regExp->match(name, start); + pos = regExp->match(mutableStringToMatch, start); if (pos != -1) { length = regExp->matchedLength(); if (length >= bestLength) { @@ -257,12 +278,25 @@ NSString* Frame::matchLabelsAgainstElement(NSArray* labels, Element* element) start = pos + 1; } } while (pos != -1); - + if (bestPos != -1) - return name.substring(bestPos, bestLength); + return mutableStringToMatch.substring(bestPos, bestLength); return nil; } +NSString* Frame::matchLabelsAgainstElement(NSArray* labels, Element* element) +{ + // Match against the name element, then against the id element if no match is found for the name element. + // See 7538330 for one popular site that benefits from the id element check. + // FIXME: This code is mirrored in Frame.cpp. It would be nice to make the Mac code call the platform-agnostic + // code, which would require converting the NSArray of NSStrings to a Vector of Strings somewhere along the way. + String resultFromNameAttribute = matchLabelsAgainstString(labels, element->getAttribute(nameAttr)); + if (!resultFromNameAttribute.isEmpty()) + return resultFromNameAttribute; + + return matchLabelsAgainstString(labels, element->getAttribute(idAttr)); +} + NSImage* Frame::imageFromRect(NSRect rect) const { NSView* view = m_view->documentView(); diff --git a/WebCore/page/mac/WebCoreViewFactory.h b/WebCore/page/mac/WebCoreViewFactory.h index 43f3f0a..fef856a 100644 --- a/WebCore/page/mac/WebCoreViewFactory.h +++ b/WebCore/page/mac/WebCoreViewFactory.h @@ -139,6 +139,8 @@ - (NSString *)AXCheckedCheckBoxActionVerb; - (NSString *)AXUncheckedCheckBoxActionVerb; - (NSString *)AXLinkActionVerb; +- (NSString *)AXMenuListPopupActionVerb; +- (NSString *)AXMenuListActionVerb; - (NSString *)multipleFileUploadTextForNumberOfFiles:(unsigned)numberOfFiles; // FTP Directory Related diff --git a/WebCore/page/qt/DragControllerQt.cpp b/WebCore/page/qt/DragControllerQt.cpp index e6c7682..33815b5 100644 --- a/WebCore/page/qt/DragControllerQt.cpp +++ b/WebCore/page/qt/DragControllerQt.cpp @@ -66,6 +66,7 @@ const IntSize& DragController::maxDragImageSize() void DragController::cleanupAfterSystemDrag() { + dragEnded(); } } diff --git a/WebCore/page/win/EventHandlerWin.cpp b/WebCore/page/win/EventHandlerWin.cpp index 50e50fb..5511209 100644 --- a/WebCore/page/win/EventHandlerWin.cpp +++ b/WebCore/page/win/EventHandlerWin.cpp @@ -88,7 +88,7 @@ bool EventHandler::eventActivatedView(const PlatformMouseEvent& event) const PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const { -#if PLATFORM(WINCE) +#if OS(WINCE) return 0; #else COMPtr<WCDataObject> dataObject; diff --git a/WebCore/page/win/FrameCairoWin.cpp b/WebCore/page/win/FrameCairoWin.cpp index f5b832e..3e1fe28 100644 --- a/WebCore/page/win/FrameCairoWin.cpp +++ b/WebCore/page/win/FrameCairoWin.cpp @@ -24,6 +24,7 @@ */ #include "config.h" +#include "Frame.h" #include "FrameWin.h" #include "EditorClient.h" diff --git a/WebCore/page/win/FrameWin.h b/WebCore/page/win/FrameWin.h index 2924291..9cf9683 100644 --- a/WebCore/page/win/FrameWin.h +++ b/WebCore/page/win/FrameWin.h @@ -26,13 +26,16 @@ #ifndef FrameWin_H #define FrameWin_H -#include "Frame.h" +#include <wtf/Vector.h> // Forward declared so we don't need wingdi.h. typedef struct HBITMAP__* HBITMAP; namespace WebCore { + class Frame; + class IntRect; + HBITMAP imageFromSelection(Frame* frame, bool forceWhiteText); void computePageRectsForFrame(Frame*, const IntRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, Vector<IntRect>& pages, int& pageHeight); |