summaryrefslogtreecommitdiffstats
path: root/WebCore/page
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2008-12-17 18:05:15 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2008-12-17 18:05:15 -0800
commit1cbdecfa9fc428ac2d8aca0fa91c9580b3d57353 (patch)
tree4457a7306ea5acb43fe05bfe0973b1f7faf97ba2 /WebCore/page
parent9364f22aed35e1a1e9d07c121510f80be3ab0502 (diff)
downloadexternal_webkit-1cbdecfa9fc428ac2d8aca0fa91c9580b3d57353.zip
external_webkit-1cbdecfa9fc428ac2d8aca0fa91c9580b3d57353.tar.gz
external_webkit-1cbdecfa9fc428ac2d8aca0fa91c9580b3d57353.tar.bz2
Code drop from //branches/cupcake/...@124589
Diffstat (limited to 'WebCore/page')
-rw-r--r--WebCore/page/AXObjectCache.cpp239
-rw-r--r--WebCore/page/AXObjectCache.h113
-rw-r--r--WebCore/page/AbstractView.idl4
-rw-r--r--WebCore/page/AccessibilityImageMapLink.cpp130
-rw-r--r--WebCore/page/AccessibilityImageMapLink.h72
-rw-r--r--WebCore/page/AccessibilityList.cpp94
-rw-r--r--WebCore/page/AccessibilityList.h (renamed from WebCore/page/inspector/ResourcePanel.js)52
-rw-r--r--WebCore/page/AccessibilityListBox.cpp179
-rw-r--r--WebCore/page/AccessibilityListBox.h66
-rw-r--r--WebCore/page/AccessibilityListBoxOption.cpp207
-rw-r--r--WebCore/page/AccessibilityListBoxOption.h79
-rw-r--r--WebCore/page/AccessibilityObject.cpp1030
-rw-r--r--WebCore/page/AccessibilityObject.h419
-rw-r--r--WebCore/page/AccessibilityRenderObject.cpp2378
-rw-r--r--WebCore/page/AccessibilityRenderObject.h236
-rw-r--r--WebCore/page/AccessibilityTable.cpp491
-rw-r--r--WebCore/page/AccessibilityTable.h86
-rw-r--r--WebCore/page/AccessibilityTableCell.cpp122
-rw-r--r--WebCore/page/AccessibilityTableCell.h61
-rw-r--r--WebCore/page/AccessibilityTableColumn.cpp167
-rw-r--r--WebCore/page/AccessibilityTableColumn.h75
-rw-r--r--WebCore/page/AccessibilityTableHeaderContainer.cpp87
-rw-r--r--WebCore/page/AccessibilityTableHeaderContainer.h67
-rw-r--r--WebCore/page/AccessibilityTableRow.cpp110
-rw-r--r--WebCore/page/AccessibilityTableRow.h65
-rw-r--r--WebCore/page/AnimationController.cpp606
-rw-r--r--WebCore/page/BarInfo.h7
-rw-r--r--WebCore/page/Chrome.cpp212
-rw-r--r--WebCore/page/Chrome.h44
-rw-r--r--WebCore/page/ChromeClient.h65
-rw-r--r--WebCore/page/Console.cpp417
-rw-r--r--WebCore/page/Console.h73
-rw-r--r--WebCore/page/Console.idl25
-rw-r--r--WebCore/page/ContextMenuController.cpp30
-rw-r--r--WebCore/page/DOMSelection.cpp123
-rw-r--r--WebCore/page/DOMSelection.h4
-rw-r--r--WebCore/page/DOMWindow.cpp600
-rw-r--r--WebCore/page/DOMWindow.h152
-rw-r--r--WebCore/page/DOMWindow.idl125
-rw-r--r--WebCore/page/DragController.cpp57
-rw-r--r--WebCore/page/EditorClient.h142
-rw-r--r--WebCore/page/EventHandler.cpp788
-rw-r--r--WebCore/page/EventHandler.h53
-rw-r--r--WebCore/page/FocusController.cpp27
-rw-r--r--WebCore/page/Frame.cpp760
-rw-r--r--WebCore/page/Frame.h190
-rw-r--r--WebCore/page/FrameLoadRequest.h18
-rw-r--r--WebCore/page/FramePrivate.h59
-rw-r--r--WebCore/page/FrameTree.cpp54
-rw-r--r--WebCore/page/FrameTree.h9
-rw-r--r--WebCore/page/FrameView.cpp851
-rw-r--r--WebCore/page/FrameView.h60
-rw-r--r--WebCore/page/Geolocation.cpp222
-rw-r--r--WebCore/page/Geolocation.h104
-rw-r--r--WebCore/page/Geolocation.idl38
-rw-r--r--WebCore/page/Geoposition.cpp38
-rw-r--r--WebCore/page/Geoposition.h77
-rw-r--r--WebCore/page/Geoposition.idl42
-rw-r--r--WebCore/page/History.h7
-rw-r--r--WebCore/page/InspectorController.cpp1646
-rw-r--r--WebCore/page/InspectorController.h177
-rw-r--r--WebCore/page/Location.cpp135
-rw-r--r--WebCore/page/Location.h71
-rw-r--r--WebCore/page/Location.idl57
-rw-r--r--WebCore/page/MouseEventWithHitTestResults.cpp2
-rw-r--r--WebCore/page/MouseEventWithHitTestResults.h5
-rw-r--r--WebCore/page/Navigator.cpp218
-rw-r--r--WebCore/page/Navigator.h74
-rw-r--r--WebCore/page/Navigator.idl46
-rw-r--r--WebCore/page/Page.cpp317
-rw-r--r--WebCore/page/Page.h112
-rw-r--r--WebCore/page/PageGroup.cpp184
-rw-r--r--WebCore/page/PageGroup.h85
-rw-r--r--WebCore/page/PositionCallback.h44
-rw-r--r--WebCore/page/PositionCallback.idl34
-rw-r--r--WebCore/page/PositionError.h63
-rw-r--r--WebCore/page/PositionError.idl35
-rw-r--r--WebCore/page/PositionErrorCallback.h44
-rw-r--r--WebCore/page/PositionErrorCallback.idl34
-rw-r--r--WebCore/page/PositionOptions.h56
-rw-r--r--WebCore/page/PositionOptions.idl35
-rw-r--r--WebCore/page/PrintContext.cpp137
-rw-r--r--WebCore/page/PrintContext.h57
-rw-r--r--WebCore/page/Screen.h5
-rw-r--r--WebCore/page/SecurityOrigin.cpp295
-rw-r--r--WebCore/page/SecurityOrigin.h141
-rw-r--r--WebCore/page/SecurityOriginHash.h81
-rw-r--r--WebCore/page/Settings.cpp72
-rw-r--r--WebCore/page/Settings.h57
-rw-r--r--WebCore/page/android/EventHandlerAndroid.cpp25
-rw-r--r--WebCore/page/android/FrameAndroid.cpp301
-rw-r--r--WebCore/page/android/FrameAndroid.h120
-rw-r--r--WebCore/page/android/InspectorControllerAndroid.cpp24
-rw-r--r--WebCore/page/animation/AnimationBase.cpp815
-rw-r--r--WebCore/page/animation/AnimationBase.h254
-rw-r--r--WebCore/page/animation/AnimationController.cpp298
-rw-r--r--WebCore/page/animation/AnimationController.h78
-rw-r--r--WebCore/page/animation/CompositeAnimation.cpp594
-rw-r--r--WebCore/page/animation/CompositeAnimation.h77
-rw-r--r--WebCore/page/animation/ImplicitAnimation.cpp203
-rw-r--r--WebCore/page/animation/ImplicitAnimation.h88
-rw-r--r--WebCore/page/animation/KeyframeAnimation.cpp293
-rw-r--r--WebCore/page/animation/KeyframeAnimation.h92
-rw-r--r--WebCore/page/gtk/AXObjectCacheAtk.cpp52
-rw-r--r--WebCore/page/gtk/AccessibilityObjectAtk.cpp (renamed from WebCore/page/Plugin.h)25
-rw-r--r--WebCore/page/gtk/AccessibilityObjectWrapperAtk.cpp676
-rw-r--r--WebCore/page/gtk/AccessibilityObjectWrapperAtk.h62
-rw-r--r--WebCore/page/gtk/EventHandlerGtk.cpp18
-rw-r--r--WebCore/page/gtk/FrameGtk.cpp23
-rw-r--r--WebCore/page/inspector/ConsolePanel.js459
-rw-r--r--WebCore/page/inspector/Database.js129
-rw-r--r--WebCore/page/inspector/DatabasePanel.js462
-rw-r--r--WebCore/page/inspector/DocumentPanel.js837
-rw-r--r--WebCore/page/inspector/FontPanel.js103
-rw-r--r--WebCore/page/inspector/ImagePanel.js74
-rw-r--r--WebCore/page/inspector/Images/alternateTableRows.pngbin3445 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/attachedShadow.pngbin3458 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/backNormal.pngbin758 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/bottomShadow.pngbin3450 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/breadcrumbBackground.pngbin3460 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/checker.pngbin3471 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/console.pngbin1953 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/darkShadow.pngbin3456 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/database.pngbin4434 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/databaseBrowserViewNormal.pngbin574 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/databaseBrowserViewNormalSelected.pngbin575 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/databaseBrowserViewSmall.pngbin569 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/databaseBrowserViewSmallSelected.pngbin571 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/databaseQueryViewNormal.pngbin630 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/databaseQueryViewNormalSelected.pngbin626 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/databaseQueryViewSmall.pngbin614 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/databaseQueryViewSmallSelected.pngbin609 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/disclosureDownPressed.pngbin212 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/disclosureRightDown.pngbin261 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/disclosureRightPressed.pngbin233 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/document.pngbin799 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/domViewNormal.pngbin604 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/domViewNormalSelected.pngbin599 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/domViewSmall.pngbin595 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/domViewSmallSelected.pngbin599 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/downTriangle.pngbin281 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/errorIcon.pngbin3811 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/errorMediumIcon.pngbin4059 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/folder.pngbin4153 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/forwardNormal.pngbin759 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/glossyHeader.pngbin3563 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/glossyHeaderPressed.pngbin189 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/goArrow.pngbin3591 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/gradient.pngbin3447 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/gradientHighlight.pngbin3454 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/gradientHighlightBottom.pngbin3641 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/hideStatusWidget.pngbin3734 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/hideStatusWidgetPressed.pngbin3729 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/network.pngbin2740 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/paneBottomGrow.pngbin3457 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/paneBottomGrowActive.pngbin3457 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/paneGrowHandleLine.pngbin3443 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/paneHeader.pngbin3476 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/paneHeaderActive.pngbin3477 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/plainDocument.pngbin460 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/popupArrows.pngbin700 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/popupArrowsBlack.pngbin117 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/reload.pngbin971 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/rightTriangle.pngbin308 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/segment.pngbin3848 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/segmentEnd.pngbin3482 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/segmentHover.pngbin3858 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/segmentHoverEnd.pngbin3480 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/segmentSelected.pngbin3836 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/segmentSelectedEnd.pngbin3486 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/showStatusWidget.pngbin3733 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/showStatusWidgetPressed.pngbin3726 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/sidbarItemBackground.pngbin180 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/sidebarActionWidget.pngbin3169 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/sidebarActionWidgetPressed.pngbin3924 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/sidebarAttachWidget.pngbin784 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/sidebarAttachWidgetPressed.pngbin776 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/sidebarDetachWidget.pngbin852 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/sidebarDetachWidgetPressed.pngbin847 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/sidebarResizeWidget.pngbin3646 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/sidebarSelection.pngbin3481 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/sidebarSelectionBlurred.pngbin3475 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/sidebarSelectionBlurredTall.pngbin3476 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/sidebarSelectionGray.pngbin3469 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/sidebarSelectionGrayTall.pngbin3455 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/sidebarSelectionTall.pngbin3464 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/sidebarStatusAreaBackground.pngbin2835 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/sourceViewNormal.pngbin566 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/sourceViewNormalSelected.pngbin566 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/sourceViewSmall.pngbin561 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/sourceViewSmallSelected.pngbin560 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/splitviewDimple.pngbin216 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/splitviewDividerBackground.pngbin149 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/tab.pngbin3952 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/tabSelected.pngbin4012 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/timelinePillBlue.pngbin3346 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/timelinePillGray.pngbin3297 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/timelinePillGreen.pngbin3350 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/timelinePillOrange.pngbin3352 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/timelinePillPurple.pngbin3353 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/timelinePillRed.pngbin3343 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/timelinePillYellow.pngbin3336 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/tipBalloon.pngbin3689 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/tipBalloonBottom.pngbin3139 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/tipIcon.pngbin1212 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/tipIconPressed.pngbin1224 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/toggleDown.pngbin3768 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/toggleUp.pngbin3769 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/toolbarBackground.pngbin3513 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/toolbarBackgroundInactive.pngbin3534 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/toolbarButtonNormal.pngbin956 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/toolbarButtonNormalInactive.pngbin974 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/toolbarButtonNormalPressed.pngbin1203 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/toolbarButtonNormalSelected.pngbin1093 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/toolbarButtonNormalSelectedInactive.pngbin1120 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/toolbarButtonSmall.pngbin899 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/toolbarButtonSmallInactive.pngbin890 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/toolbarButtonSmallPressed.pngbin1058 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/toolbarButtonSmallSelected.pngbin1007 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/toolbarButtonSmallSelectedInactive.pngbin1037 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/toolbarPopupButtonNormal.pngbin1119 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/toolbarPopupButtonNormalInactive.pngbin1142 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/toolbarPopupButtonNormalPressed.pngbin1320 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/toolbarPopupButtonSmall.pngbin1043 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/toolbarPopupButtonSmallInactive.pngbin1038 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/toolbarPopupButtonSmallPressed.pngbin1167 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/toolbarSplitButtonDividerNormal.pngbin582 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/toolbarSplitButtonDividerNormalInactive.pngbin584 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/toolbarSplitButtonDividerSmall.pngbin583 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/toolbarSplitButtonDividerSmallInactive.pngbin584 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/treeDownTriangleBlack.pngbin3570 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/treeDownTriangleWhite.pngbin3531 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/treeLeftTriangleBlack.pngbin3551 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/treeRightTriangleBlack.pngbin3561 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/treeRightTriangleWhite.pngbin3535 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/warningIcon.pngbin3726 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/warningMediumIcon.pngbin3833 -> 0 bytes
-rw-r--r--WebCore/page/inspector/Images/warningsErrors.pngbin5192 -> 0 bytes
-rw-r--r--WebCore/page/inspector/MetricsSidebarPane.js140
-rw-r--r--WebCore/page/inspector/NetworkPanel.js1036
-rw-r--r--WebCore/page/inspector/Panel.js180
-rw-r--r--WebCore/page/inspector/PropertiesSection.js139
-rw-r--r--WebCore/page/inspector/PropertiesSidebarPane.js139
-rw-r--r--WebCore/page/inspector/Resource.js690
-rw-r--r--WebCore/page/inspector/ResourceCategory.js105
-rw-r--r--WebCore/page/inspector/SidebarPane.js123
-rw-r--r--WebCore/page/inspector/SourcePanel.js144
-rw-r--r--WebCore/page/inspector/StylesSidebarPane.js682
-rw-r--r--WebCore/page/inspector/WebKit.qrc137
-rw-r--r--WebCore/page/inspector/inspector.css2169
-rw-r--r--WebCore/page/inspector/inspector.html75
-rw-r--r--WebCore/page/inspector/inspector.js1186
-rw-r--r--WebCore/page/inspector/treeoutline.js728
-rw-r--r--WebCore/page/inspector/utilities.js787
-rw-r--r--WebCore/page/mac/AXObjectCacheMac.mm87
-rw-r--r--WebCore/page/mac/AccessibilityObjectMac.mm38
-rw-r--r--WebCore/page/mac/AccessibilityObjectWrapper.h (renamed from WebCore/page/AnimationController.h)52
-rw-r--r--WebCore/page/mac/AccessibilityObjectWrapper.mm1996
-rw-r--r--WebCore/page/mac/ChromeMac.mm14
-rw-r--r--WebCore/page/mac/EventHandlerMac.mm127
-rw-r--r--WebCore/page/mac/FrameMac.mm259
-rw-r--r--WebCore/page/mac/PageMac.cpp77
-rw-r--r--WebCore/page/mac/WebCoreFrameBridge.h256
-rw-r--r--WebCore/page/mac/WebCoreFrameBridge.mm1244
-rw-r--r--WebCore/page/mac/WebCoreFrameView.h34
-rw-r--r--WebCore/page/mac/WebCoreViewFactory.h28
-rw-r--r--WebCore/page/mac/WebDashboardRegion.h8
-rw-r--r--WebCore/page/mac/WebDashboardRegion.m2
-rw-r--r--WebCore/page/qt/AccessibilityObjectQt.cpp30
-rw-r--r--WebCore/page/qt/EventHandlerQt.cpp31
-rw-r--r--WebCore/page/qt/FrameQt.cpp97
-rw-r--r--WebCore/page/win/AXObjectCacheWin.cpp61
-rw-r--r--WebCore/page/win/AccessibilityObjectWin.cpp37
-rw-r--r--WebCore/page/win/AccessibilityObjectWrapperWin.h54
-rw-r--r--WebCore/page/win/EventHandlerWin.cpp20
-rw-r--r--WebCore/page/win/FrameCGWin.cpp87
-rw-r--r--WebCore/page/win/FrameCairoWin.cpp (renamed from WebCore/page/InspectorClient.h)41
-rw-r--r--WebCore/page/win/FrameWin.cpp101
-rw-r--r--WebCore/page/win/FrameWin.h41
-rw-r--r--WebCore/page/win/PageWin.cpp38
-rw-r--r--WebCore/page/wx/AccessibilityObjectWx.cpp30
-rw-r--r--WebCore/page/wx/EventHandlerWx.cpp18
282 files changed, 19626 insertions, 16951 deletions
diff --git a/WebCore/page/AXObjectCache.cpp b/WebCore/page/AXObjectCache.cpp
new file mode 100644
index 0000000..d9c4c9a
--- /dev/null
+++ b/WebCore/page/AXObjectCache.cpp
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AXObjectCache.h"
+
+#include "AccessibilityList.h"
+#include "AccessibilityListBox.h"
+#include "AccessibilityListBoxOption.h"
+#include "AccessibilityImageMapLink.h"
+#include "AccessibilityRenderObject.h"
+#include "AccessibilityTable.h"
+#include "AccessibilityTableCell.h"
+#include "AccessibilityTableColumn.h"
+#include "AccessibilityTableHeaderContainer.h"
+#include "AccessibilityTableRow.h"
+#include "HTMLNames.h"
+#include "RenderObject.h"
+
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+bool AXObjectCache::gAccessibilityEnabled = false;
+bool AXObjectCache::gAccessibilityEnhancedUserInterfaceEnabled = false;
+
+AXObjectCache::~AXObjectCache()
+{
+ HashMap<AXID, RefPtr<AccessibilityObject> >::iterator end = m_objects.end();
+ for (HashMap<AXID, RefPtr<AccessibilityObject> >::iterator it = m_objects.begin(); it != end; ++it) {
+ AccessibilityObject* obj = (*it).second.get();
+ detachWrapper(obj);
+ obj->detach();
+ }
+}
+
+AccessibilityObject* AXObjectCache::get(RenderObject* renderer)
+{
+ if (!renderer)
+ return 0;
+
+ RefPtr<AccessibilityObject> obj = 0;
+ AXID axID = m_renderObjectMapping.get(renderer);
+ ASSERT(!HashTraits<AXID>::isDeletedValue(axID));
+
+ if (axID)
+ obj = m_objects.get(axID).get();
+
+ Node* element = renderer->element();
+ if (!obj) {
+ if (renderer->isListBox())
+ obj = AccessibilityListBox::create(renderer);
+ else if (element && (element->hasTagName(ulTag) || element->hasTagName(olTag) || element->hasTagName(dlTag)))
+ obj = AccessibilityList::create(renderer);
+ else if (renderer->isTable())
+ obj = AccessibilityTable::create(renderer);
+ else if (renderer->isTableRow())
+ obj = AccessibilityTableRow::create(renderer);
+ else if (renderer->isTableCell())
+ obj = AccessibilityTableCell::create(renderer);
+ else
+ obj = AccessibilityRenderObject::create(renderer);
+
+ getAXID(obj.get());
+
+ m_renderObjectMapping.set(renderer, obj.get()->axObjectID());
+ m_objects.set(obj.get()->axObjectID(), obj);
+ attachWrapper(obj.get());
+ }
+
+ return obj.get();
+}
+
+AccessibilityObject* AXObjectCache::get(AccessibilityRole role)
+{
+ RefPtr<AccessibilityObject> obj = 0;
+
+ // will be filled in...
+ switch (role) {
+ case ListBoxOptionRole:
+ obj = AccessibilityListBoxOption::create();
+ break;
+ case ImageMapLinkRole:
+ obj = AccessibilityImageMapLink::create();
+ break;
+ case ColumnRole:
+ obj = AccessibilityTableColumn::create();
+ break;
+ case TableHeaderContainerRole:
+ obj = AccessibilityTableHeaderContainer::create();
+ break;
+ default:
+ obj = 0;
+ }
+
+ if (obj)
+ getAXID(obj.get());
+ else
+ return 0;
+
+ m_objects.set(obj->axObjectID(), obj);
+ attachWrapper(obj.get());
+ return obj.get();
+}
+
+void AXObjectCache::remove(AXID axID)
+{
+ if (!axID)
+ return;
+
+ // first fetch object to operate some cleanup functions on it
+ AccessibilityObject* obj = m_objects.get(axID).get();
+ if (!obj)
+ return;
+
+ detachWrapper(obj);
+ obj->detach();
+ removeAXID(obj);
+
+ // finally remove the object
+ if (!m_objects.take(axID)) {
+ return;
+ }
+
+ ASSERT(m_objects.size() >= m_idsInUse.size());
+}
+
+void AXObjectCache::remove(RenderObject* renderer)
+{
+ if (!renderer)
+ return;
+
+ AXID axID = m_renderObjectMapping.get(renderer);
+ remove(axID);
+ m_renderObjectMapping.remove(renderer);
+}
+
+AXID AXObjectCache::getAXID(AccessibilityObject* obj)
+{
+ // check for already-assigned ID
+ AXID objID = obj->axObjectID();
+ if (objID) {
+ ASSERT(m_idsInUse.contains(objID));
+ return objID;
+ }
+
+ // generate a new ID
+ static AXID lastUsedID = 0;
+ objID = lastUsedID;
+ do
+ ++objID;
+ while (objID == 0 || HashTraits<AXID>::isDeletedValue(objID) || m_idsInUse.contains(objID));
+ m_idsInUse.add(objID);
+ lastUsedID = objID;
+ obj->setAXObjectID(objID);
+
+ return objID;
+}
+
+void AXObjectCache::removeAXID(AccessibilityObject* obj)
+{
+ AXID objID = obj->axObjectID();
+ if (objID == 0)
+ return;
+ ASSERT(!HashTraits<AXID>::isDeletedValue(objID));
+ ASSERT(m_idsInUse.contains(objID));
+ obj->setAXObjectID(0);
+ m_idsInUse.remove(objID);
+}
+
+void AXObjectCache::childrenChanged(RenderObject* renderer)
+{
+ if (!renderer)
+ return;
+
+ AXID axID = m_renderObjectMapping.get(renderer);
+ if (!axID)
+ return;
+
+ AccessibilityObject* obj = m_objects.get(axID).get();
+ if (obj)
+ obj->childrenChanged();
+}
+
+#if HAVE(ACCESSIBILITY)
+void AXObjectCache::selectedChildrenChanged(RenderObject* renderer)
+{
+ postNotificationToElement(renderer, "AXSelectedChildrenChanged");
+}
+#endif
+
+#if HAVE(ACCESSIBILITY)
+void AXObjectCache::handleActiveDescendantChanged(RenderObject* renderer)
+{
+ if (!renderer)
+ return;
+ AccessibilityObject* obj = get(renderer);
+ if (obj)
+ obj->handleActiveDescendantChanged();
+}
+
+void AXObjectCache::handleAriaRoleChanged(RenderObject* renderer)
+{
+ if (!renderer)
+ return;
+ AccessibilityObject* obj = get(renderer);
+ if (obj && obj->isAccessibilityRenderObject())
+ static_cast<AccessibilityRenderObject*>(obj)->setAriaRole();
+}
+#endif
+
+} // namespace WebCore
diff --git a/WebCore/page/AXObjectCache.h b/WebCore/page/AXObjectCache.h
new file mode 100644
index 0000000..5e95f74
--- /dev/null
+++ b/WebCore/page/AXObjectCache.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AXObjectCache_h
+#define AXObjectCache_h
+
+#include "AccessibilityObject.h"
+#include <limits.h>
+#include <wtf/HashMap.h>
+#include <wtf/HashSet.h>
+#include <wtf/RefPtr.h>
+
+#ifdef __OBJC__
+@class WebCoreTextMarker;
+#else
+class WebCoreTextMarker;
+#endif
+
+namespace WebCore {
+
+ class RenderObject;
+ class String;
+ class VisiblePosition;
+ class AccessibilityObject;
+ class Node;
+
+ typedef unsigned AXID;
+
+ struct TextMarkerData {
+ AXID axID;
+ Node* node;
+ int offset;
+ EAffinity affinity;
+ };
+
+ class AXObjectCache {
+ public:
+ ~AXObjectCache();
+
+ // to be used with render objects
+ AccessibilityObject* get(RenderObject*);
+
+ // used for objects without backing elements
+ AccessibilityObject* get(AccessibilityRole);
+
+ void remove(RenderObject*);
+ void remove(AXID);
+
+ void detachWrapper(AccessibilityObject*);
+ void attachWrapper(AccessibilityObject*);
+ void postNotification(RenderObject*, const String&);
+ void postNotificationToElement(RenderObject*, const String&);
+ void childrenChanged(RenderObject*);
+ void selectedChildrenChanged(RenderObject*);
+ void handleActiveDescendantChanged(RenderObject*);
+ void handleAriaRoleChanged(RenderObject*);
+ void handleFocusedUIElementChanged();
+ static void enableAccessibility() { gAccessibilityEnabled = true; }
+ static void enableEnhancedUserInterfaceAccessibility() { gAccessibilityEnhancedUserInterfaceEnabled = true; }
+
+ static bool accessibilityEnabled() { return gAccessibilityEnabled; }
+ static bool accessibilityEnhancedUserInterfaceEnabled() { return gAccessibilityEnhancedUserInterfaceEnabled; }
+
+ void removeAXID(AccessibilityObject*);
+ bool isIDinUse(AXID id) const { return m_idsInUse.contains(id); }
+
+ private:
+ HashMap<AXID, RefPtr<AccessibilityObject> > m_objects;
+ HashMap<RenderObject*, AXID> m_renderObjectMapping;
+ static bool gAccessibilityEnabled;
+ static bool gAccessibilityEnhancedUserInterfaceEnabled;
+
+ HashSet<AXID> m_idsInUse;
+
+ AXID getAXID(AccessibilityObject*);
+ };
+
+#if !HAVE(ACCESSIBILITY)
+ inline void AXObjectCache::handleActiveDescendantChanged(RenderObject*) { }
+ inline void AXObjectCache::handleAriaRoleChanged(RenderObject*) { }
+ inline void AXObjectCache::handleFocusedUIElementChanged() { }
+ inline void AXObjectCache::detachWrapper(AccessibilityObject*) { }
+ inline void AXObjectCache::attachWrapper(AccessibilityObject*) { }
+ inline void AXObjectCache::selectedChildrenChanged(RenderObject*) { }
+ inline void AXObjectCache::postNotification(RenderObject*, const String&) { }
+ inline void AXObjectCache::postNotificationToElement(RenderObject*, const String&) { }
+#endif
+
+}
+
+#endif
diff --git a/WebCore/page/AbstractView.idl b/WebCore/page/AbstractView.idl
index ca02c82..5b7ce89 100644
--- a/WebCore/page/AbstractView.idl
+++ b/WebCore/page/AbstractView.idl
@@ -27,7 +27,9 @@
module views {
// Introduced in DOM Level 2:
- interface AbstractView {
+ interface [
+ ObjCCustomImplementation
+ ] AbstractView {
readonly attribute Document document;
};
diff --git a/WebCore/page/AccessibilityImageMapLink.cpp b/WebCore/page/AccessibilityImageMapLink.cpp
new file mode 100644
index 0000000..5557446
--- /dev/null
+++ b/WebCore/page/AccessibilityImageMapLink.cpp
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AccessibilityImageMapLink.h"
+
+#include "AccessibilityRenderObject.h"
+#include "AXObjectCache.h"
+#include "Document.h"
+#include "HTMLNames.h"
+#include "IntRect.h"
+#include "RenderObject.h"
+
+using namespace std;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+AccessibilityImageMapLink::AccessibilityImageMapLink()
+ : m_areaElement(0),
+ m_mapElement(0)
+{
+}
+
+AccessibilityImageMapLink::~AccessibilityImageMapLink()
+{
+}
+
+PassRefPtr<AccessibilityImageMapLink> AccessibilityImageMapLink::create()
+{
+ return adoptRef(new AccessibilityImageMapLink());
+}
+
+AccessibilityObject* AccessibilityImageMapLink::parentObject() const
+{
+ if (m_parent)
+ return m_parent;
+
+ if (!m_mapElement || !m_mapElement->renderer())
+ return 0;
+
+ return m_mapElement->document()->axObjectCache()->get(m_mapElement->renderer());
+}
+
+Element* AccessibilityImageMapLink::actionElement() const
+{
+ return anchorElement();
+}
+
+Element* AccessibilityImageMapLink::anchorElement() const
+{
+ return m_areaElement;
+}
+
+String AccessibilityImageMapLink::accessibilityDescription() const
+{
+ if (!m_areaElement)
+ return String();
+
+ const AtomicString& alt = m_areaElement->getAttribute(altAttr);
+ if (!alt.isEmpty())
+ return alt;
+
+ return String();
+}
+
+String AccessibilityImageMapLink::title() const
+{
+ if (!m_areaElement)
+ return String();
+
+ const AtomicString& title = m_areaElement->getAttribute(titleAttr);
+ if (!title.isEmpty())
+ return title;
+ const AtomicString& summary = m_areaElement->getAttribute(summaryAttr);
+ if (!summary.isEmpty())
+ return summary;
+
+ return String();
+}
+
+IntRect AccessibilityImageMapLink::elementRect() const
+{
+ if (!m_mapElement || !m_areaElement)
+ return IntRect();
+
+ RenderObject* renderer;
+ if (m_parent && m_parent->isAccessibilityRenderObject())
+ renderer = static_cast<AccessibilityRenderObject*>(m_parent)->renderer();
+ else
+ renderer = m_mapElement->renderer();
+
+ if (!renderer)
+ return IntRect();
+
+ return m_areaElement->getRect(renderer);
+}
+
+IntSize AccessibilityImageMapLink::size() const
+{
+ return elementRect().size();
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/AccessibilityImageMapLink.h b/WebCore/page/AccessibilityImageMapLink.h
new file mode 100644
index 0000000..7fc8d3c
--- /dev/null
+++ b/WebCore/page/AccessibilityImageMapLink.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 AccessibilityImageMapLink_h
+#define AccessibilityImageMapLink_h
+
+#include "AccessibilityObject.h"
+#include "HTMLAreaElement.h"
+#include "HTMLMapElement.h"
+
+namespace WebCore {
+
+class AccessibilityImageMapLink : public AccessibilityObject {
+
+private:
+ AccessibilityImageMapLink();
+public:
+ static PassRefPtr<AccessibilityImageMapLink> create();
+ virtual ~AccessibilityImageMapLink();
+
+ void setHTMLAreaElement(HTMLAreaElement* element) { m_areaElement = element; }
+ void setHTMLMapElement(HTMLMapElement* element) { m_mapElement = element; }
+ void setParent(AccessibilityObject* parent) { m_parent = parent; }
+
+ virtual AccessibilityRole roleValue() const { return WebCoreLinkRole; }
+ virtual bool accessibilityIsIgnored() const { return false; }
+
+ virtual AccessibilityObject* parentObject() const;
+ virtual Element* anchorElement() const;
+ virtual Element* actionElement() const;
+
+ virtual bool isLink() const { return true; }
+ virtual String title() const;
+ virtual String accessibilityDescription() const;
+
+ virtual IntSize size() const;
+ virtual IntRect elementRect() const;
+
+private:
+ HTMLAreaElement* m_areaElement;
+ HTMLMapElement* m_mapElement;
+ AccessibilityObject* m_parent;
+};
+
+} // namespace WebCore
+
+#endif // AccessibilityImageMapLink_h
diff --git a/WebCore/page/AccessibilityList.cpp b/WebCore/page/AccessibilityList.cpp
new file mode 100644
index 0000000..ad71ff4
--- /dev/null
+++ b/WebCore/page/AccessibilityList.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AccessibilityList.h"
+
+#include "AXObjectCache.h"
+#include "HTMLNames.h"
+#include "RenderObject.h"
+
+using namespace std;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+AccessibilityList::AccessibilityList(RenderObject* renderer)
+ : AccessibilityRenderObject(renderer)
+{
+}
+
+AccessibilityList::~AccessibilityList()
+{
+}
+
+PassRefPtr<AccessibilityList> AccessibilityList::create(RenderObject* renderer)
+{
+ return adoptRef(new AccessibilityList(renderer));
+}
+
+bool AccessibilityList::accessibilityIsIgnored() const
+{
+ // lists don't appear on tiger/leopard on the mac
+#if PLATFORM(MAC) && (defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD))
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool AccessibilityList::isUnorderedList() const
+{
+ if (!m_renderer)
+ return false;
+
+ Node* element = m_renderer->element();
+ return element && element->hasTagName(ulTag);
+}
+
+bool AccessibilityList::isOrderedList() const
+{
+ if (!m_renderer)
+ return false;
+
+ Node* element = m_renderer->element();
+ return element && element->hasTagName(olTag);
+}
+
+bool AccessibilityList::isDefinitionList() const
+{
+ if (!m_renderer)
+ return false;
+
+ Node* element = m_renderer->element();
+ return element && element->hasTagName(dlTag);
+}
+
+
+} // namespace WebCore
diff --git a/WebCore/page/inspector/ResourcePanel.js b/WebCore/page/AccessibilityList.h
index b165c2b..315ccac 100644
--- a/WebCore/page/inspector/ResourcePanel.js
+++ b/WebCore/page/AccessibilityList.h
@@ -1,18 +1,18 @@
/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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.
+ * documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
+ * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@@ -26,25 +26,31 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-WebInspector.ResourcePanel = function(resource, views)
-{
- WebInspector.Panel.call(this, views);
- this.resource = resource;
-}
+#ifndef AccessibilityList_h
+#define AccessibilityList_h
-WebInspector.ResourcePanel.prototype = {
- show: function()
- {
- WebInspector.Panel.prototype.show.call(this);
- this.resource.listItem.select(true); // passing true prevents a cycle
- this.resource.listItem.reveal();
- },
+#include "AccessibilityRenderObject.h"
- hide: function()
- {
- this.resource.listItem.deselect(true); // passing true prevents a cycle
- WebInspector.Panel.prototype.hide.call(this);
- }
-}
+namespace WebCore {
+
+class AccessibilityList : public AccessibilityRenderObject {
+
+private:
+ AccessibilityList(RenderObject*);
+public:
+ static PassRefPtr<AccessibilityList> create(RenderObject*);
+ virtual ~AccessibilityList();
+
+ virtual bool isList() const { return true; };
+ bool isUnorderedList() const;
+ bool isOrderedList() const;
+ bool isDefinitionList() const;
-WebInspector.ResourcePanel.prototype.__proto__ = WebInspector.Panel.prototype;
+ virtual AccessibilityRole roleValue() const { return ListRole; }
+ virtual bool accessibilityIsIgnored() const;
+
+};
+
+} // namespace WebCore
+
+#endif // AccessibilityList_h
diff --git a/WebCore/page/AccessibilityListBox.cpp b/WebCore/page/AccessibilityListBox.cpp
new file mode 100644
index 0000000..912351e
--- /dev/null
+++ b/WebCore/page/AccessibilityListBox.cpp
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AccessibilityListBox.h"
+
+#include "AXObjectCache.h"
+#include "AccessibilityListBoxOption.h"
+#include "HitTestResult.h"
+#include "HTMLNames.h"
+#include "HTMLSelectElement.h"
+#include "RenderListBox.h"
+#include "RenderObject.h"
+
+using namespace std;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+AccessibilityListBox::AccessibilityListBox(RenderObject* renderer)
+ : AccessibilityRenderObject(renderer)
+{
+}
+
+AccessibilityListBox::~AccessibilityListBox()
+{
+}
+
+PassRefPtr<AccessibilityListBox> AccessibilityListBox::create(RenderObject* renderer)
+{
+ return adoptRef(new AccessibilityListBox(renderer));
+}
+
+bool AccessibilityListBox::canSetSelectedChildrenAttribute() const
+{
+ Node* selectNode = m_renderer->node();
+ if (!selectNode)
+ return false;
+
+ return !static_cast<HTMLSelectElement*>(selectNode)->disabled();
+}
+
+void AccessibilityListBox::addChildren()
+{
+ Node* selectNode = m_renderer->node();
+ if (!selectNode)
+ return;
+
+ m_haveChildren = true;
+
+ const Vector<HTMLElement*>& listItems = static_cast<HTMLSelectElement*>(selectNode)->listItems();
+ unsigned length = listItems.size();
+ for (unsigned i = 0; i < length; i++) {
+ AccessibilityObject* listOption = listBoxOptionAccessibilityObject(listItems[i]);
+ if (listOption)
+ m_children.append(listOption);
+ }
+}
+
+void AccessibilityListBox::setSelectedChildren(AccessibilityChildrenVector& children)
+{
+ if (!canSetSelectedChildrenAttribute())
+ return;
+
+ Node* selectNode = m_renderer->node();
+ if (!selectNode)
+ return;
+
+ // disable any selected options
+ unsigned length = m_children.size();
+ for (unsigned i = 0; i < length; i++) {
+ AccessibilityListBoxOption* listBoxOption = static_cast<AccessibilityListBoxOption*>(m_children[i].get());
+ if (listBoxOption->isSelected())
+ listBoxOption->setSelected(false);
+ }
+
+ length = children.size();
+ for (unsigned i = 0; i < length; i++) {
+ AccessibilityObject* obj = children[i].get();
+ if (obj->roleValue() != ListBoxOptionRole)
+ continue;
+
+ static_cast<AccessibilityListBoxOption*>(obj)->setSelected(true);
+ }
+}
+
+void AccessibilityListBox::selectedChildren(AccessibilityChildrenVector& result)
+{
+ ASSERT(result.isEmpty());
+
+ if (!hasChildren())
+ addChildren();
+
+ unsigned length = m_children.size();
+ for (unsigned i = 0; i < length; i++) {
+ if (static_cast<AccessibilityListBoxOption*>(m_children[i].get())->isSelected())
+ result.append(m_children[i]);
+ }
+}
+
+void AccessibilityListBox::visibleChildren(AccessibilityChildrenVector& result)
+{
+ ASSERT(result.isEmpty());
+
+ if (!hasChildren())
+ addChildren();
+
+ unsigned length = m_children.size();
+ for (unsigned i = 0; i < length; i++) {
+ if (static_cast<RenderListBox*>(m_renderer)->listIndexIsVisible(i))
+ result.append(m_children[i]);
+ }
+}
+
+AccessibilityObject* AccessibilityListBox::listBoxOptionAccessibilityObject(HTMLElement* element) const
+{
+ // skip hr elements
+ if (!element || element->hasTagName(hrTag))
+ return 0;
+
+ AccessibilityObject* listBoxObject = m_renderer->document()->axObjectCache()->get(ListBoxOptionRole);
+ static_cast<AccessibilityListBoxOption*>(listBoxObject)->setHTMLElement(element);
+
+ return listBoxObject;
+}
+
+AccessibilityObject* AccessibilityListBox::doAccessibilityHitTest(const IntPoint& point)
+{
+ // the internal HTMLSelectElement methods for returning a listbox option at a point
+ // ignore optgroup elements.
+ if (!m_renderer)
+ return 0;
+
+ Node *element = m_renderer->element();
+ if (!element)
+ return 0;
+
+ if (!hasChildren())
+ addChildren();
+
+ IntRect parentRect = boundingBoxRect();
+
+ unsigned length = m_children.size();
+ for (unsigned i = 0; i < length; i++) {
+ IntRect rect = static_cast<RenderListBox*>(m_renderer)->itemBoundingBoxRect(parentRect.x(), parentRect.y(), i);
+ if (rect.contains(point))
+ return m_children[i].get();
+ }
+
+ return this;
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/AccessibilityListBox.h b/WebCore/page/AccessibilityListBox.h
new file mode 100644
index 0000000..f95a921
--- /dev/null
+++ b/WebCore/page/AccessibilityListBox.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 AccessibilityListBox_h
+#define AccessibilityListBox_h
+
+#include "AccessibilityObject.h"
+#include "AccessibilityRenderObject.h"
+
+namespace WebCore {
+
+class AccessibilityListBox : public AccessibilityRenderObject {
+
+private:
+ AccessibilityListBox(RenderObject*);
+public:
+ static PassRefPtr<AccessibilityListBox> create(RenderObject*);
+ virtual ~AccessibilityListBox();
+
+ virtual AccessibilityObject* doAccessibilityHitTest(const IntPoint&);
+ virtual bool isListBox() const { return true; };
+
+ virtual bool canSetFocusAttribute() const { return true; }
+ virtual bool canSetSelectedChildrenAttribute() const;
+ void setSelectedChildren(AccessibilityChildrenVector&);
+ virtual AccessibilityRole roleValue() const { return ListBoxRole; }
+
+ virtual bool accessibilityIsIgnored() const { return false; }
+
+ virtual void selectedChildren(AccessibilityChildrenVector&);
+ virtual void visibleChildren(AccessibilityChildrenVector&);
+
+ virtual void addChildren();
+
+private:
+ AccessibilityObject* listBoxOptionAccessibilityObject(HTMLElement*) const;
+};
+
+} // namespace WebCore
+
+#endif // AccessibilityListBox_h
diff --git a/WebCore/page/AccessibilityListBoxOption.cpp b/WebCore/page/AccessibilityListBoxOption.cpp
new file mode 100644
index 0000000..fedfe91
--- /dev/null
+++ b/WebCore/page/AccessibilityListBoxOption.cpp
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AccessibilityListBoxOption.h"
+
+#include "AXObjectCache.h"
+#include "AccessibilityListBox.h"
+#include "Element.h"
+#include "HTMLElement.h"
+#include "HTMLNames.h"
+#include "HTMLOptionElement.h"
+#include "HTMLOptGroupElement.h"
+#include "HTMLSelectElement.h"
+#include "IntRect.h"
+#include "RenderObject.h"
+#include "RenderListBox.h"
+
+using namespace std;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+AccessibilityListBoxOption::AccessibilityListBoxOption()
+ : m_optionElement(0)
+{
+}
+
+AccessibilityListBoxOption::~AccessibilityListBoxOption()
+{
+}
+
+PassRefPtr<AccessibilityListBoxOption> AccessibilityListBoxOption::create()
+{
+ return adoptRef(new AccessibilityListBoxOption());
+}
+
+bool AccessibilityListBoxOption::isEnabled() const
+{
+ if (!m_optionElement)
+ return false;
+
+ if (m_optionElement->hasTagName(optgroupTag))
+ return false;
+
+ return true;
+}
+
+bool AccessibilityListBoxOption::isSelected() const
+{
+ if (!m_optionElement)
+ return false;
+
+ if (!m_optionElement->hasTagName(optionTag))
+ return false;
+
+ return static_cast<HTMLOptionElement*>(m_optionElement)->selected();
+}
+
+IntRect AccessibilityListBoxOption::elementRect() const
+{
+ IntRect rect;
+ if (!m_optionElement)
+ return rect;
+
+ HTMLSelectElement* listBoxParentNode = listBoxOptionParentNode();
+ if (!listBoxParentNode)
+ return rect;
+
+ RenderObject* listBoxRenderer = listBoxParentNode->renderer();
+ if (!listBoxRenderer)
+ return rect;
+
+ IntRect parentRect = listBoxRenderer->document()->axObjectCache()->get(listBoxRenderer)->boundingBoxRect();
+ int index = listBoxOptionIndex();
+ if (index != -1)
+ rect = static_cast<RenderListBox*>(listBoxRenderer)->itemBoundingBoxRect(parentRect.x(), parentRect.y(), index);
+
+ return rect;
+}
+
+bool AccessibilityListBoxOption::canSetSelectedAttribute() const
+{
+ if (!m_optionElement)
+ return false;
+
+ if (!m_optionElement->hasTagName(optionTag))
+ return false;
+
+ if (m_optionElement->disabled())
+ return false;
+
+ HTMLSelectElement* selectElement = listBoxOptionParentNode();
+ if (selectElement && selectElement->disabled())
+ return false;
+
+ return true;
+}
+
+String AccessibilityListBoxOption::stringValue() const
+{
+ if (!m_optionElement)
+ return String();
+
+ if (m_optionElement->hasTagName(optionTag))
+ return static_cast<HTMLOptionElement*>(m_optionElement)->text();
+
+ if (m_optionElement->hasTagName(optgroupTag))
+ return static_cast<HTMLOptGroupElement*>(m_optionElement)->groupLabelText();
+
+ return String();
+}
+
+IntSize AccessibilityListBoxOption::size() const
+{
+ return elementRect().size();
+}
+
+Element* AccessibilityListBoxOption::actionElement() const
+{
+ return m_optionElement;
+}
+
+AccessibilityObject* AccessibilityListBoxOption::parentObject() const
+{
+ HTMLSelectElement* parentNode = listBoxOptionParentNode();
+ if (!parentNode)
+ return 0;
+
+ return m_optionElement->document()->axObjectCache()->get(parentNode->renderer());
+}
+
+void AccessibilityListBoxOption::setSelected(bool selected)
+{
+ HTMLSelectElement* selectElement = listBoxOptionParentNode();
+ if (!selectElement)
+ return;
+
+ if (!canSetSelectedAttribute())
+ return;
+
+ bool isOptionSelected = isSelected();
+ if ((isOptionSelected && selected) || (!isOptionSelected && !selected))
+ return;
+
+ selectElement->accessKeySetSelectedIndex(listBoxOptionIndex());
+}
+
+HTMLSelectElement* AccessibilityListBoxOption::listBoxOptionParentNode() const
+{
+ if (!m_optionElement)
+ return 0;
+
+ if (m_optionElement->hasTagName(optionTag))
+ return static_cast<HTMLOptionElement*>(m_optionElement)->ownerSelectElement();
+
+ if (m_optionElement->hasTagName(optgroupTag))
+ return static_cast<HTMLOptGroupElement*>(m_optionElement)->ownerSelectElement();
+
+ return 0;
+}
+
+int AccessibilityListBoxOption::listBoxOptionIndex() const
+{
+ if (!m_optionElement)
+ return -1;
+
+ HTMLSelectElement* selectElement = listBoxOptionParentNode();
+ if (!selectElement)
+ return -1;
+
+ const Vector<HTMLElement*>& listItems = selectElement->listItems();
+ unsigned length = listItems.size();
+ for (unsigned i = 0; i < length; i++)
+ if (listItems[i] == m_optionElement)
+ return i;
+
+ return -1;
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/AccessibilityListBoxOption.h b/WebCore/page/AccessibilityListBoxOption.h
new file mode 100644
index 0000000..1b588cd
--- /dev/null
+++ b/WebCore/page/AccessibilityListBoxOption.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 AccessibilityListBoxOption_h
+#define AccessibilityListBoxOption_h
+
+#include "AccessibilityObject.h"
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class AccessibilityListBox;
+class Element;
+class HTMLElement;
+class HTMLSelectElement;
+class String;
+
+class AccessibilityListBoxOption : public AccessibilityObject {
+
+private:
+ AccessibilityListBoxOption();
+public:
+ static PassRefPtr<AccessibilityListBoxOption> create();
+ virtual ~AccessibilityListBoxOption();
+
+ void setHTMLElement(HTMLElement* element) { m_optionElement = element; }
+
+ virtual AccessibilityRole roleValue() const { return ListBoxOptionRole; }
+ virtual bool accessibilityIsIgnored() const { return false; }
+ virtual bool isSelected() const;
+ virtual bool isEnabled() const;
+ virtual String stringValue() const;
+ virtual Element* actionElement() const;
+
+ virtual void setSelected(bool);
+ virtual bool canSetSelectedAttribute() const;
+
+ virtual IntRect elementRect() const;
+ virtual IntSize size() const;
+ virtual AccessibilityObject* parentObject() const;
+ bool isListBoxOption() const { return true; };
+
+private:
+ HTMLElement* m_optionElement;
+
+ HTMLSelectElement* listBoxOptionParentNode() const;
+ int listBoxOptionIndex() const;
+ IntRect listBoxOptionRect() const;
+ AccessibilityObject* listBoxOptionAccessibilityObject(HTMLElement* element) const;
+};
+
+} // namespace WebCore
+
+#endif // AccessibilityListBoxOption_h
diff --git a/WebCore/page/AccessibilityObject.cpp b/WebCore/page/AccessibilityObject.cpp
new file mode 100644
index 0000000..6be8c1a
--- /dev/null
+++ b/WebCore/page/AccessibilityObject.cpp
@@ -0,0 +1,1030 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AccessibilityObject.h"
+
+#include "AccessibilityRenderObject.h"
+#include "AXObjectCache.h"
+#include "CharacterNames.h"
+#include "FloatRect.h"
+#include "FocusController.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "LocalizedStrings.h"
+#include "NodeList.h"
+#include "NotImplemented.h"
+#include "Page.h"
+#include "RenderImage.h"
+#include "RenderListMarker.h"
+#include "RenderMenuList.h"
+#include "RenderTextControl.h"
+#include "RenderTheme.h"
+#include "RenderView.h"
+#include "RenderWidget.h"
+#include "SelectionController.h"
+#include "TextIterator.h"
+#include "htmlediting.h"
+#include "visible_units.h"
+
+using namespace std;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+AccessibilityObject::AccessibilityObject()
+ : m_id(0)
+ , m_haveChildren(false)
+#if PLATFORM(GTK)
+ , m_wrapper(0)
+#endif
+{
+}
+
+AccessibilityObject::~AccessibilityObject()
+{
+ ASSERT(isDetached());
+}
+
+void AccessibilityObject::detach()
+{
+ removeAXObjectID();
+#if HAVE(ACCESSIBILITY)
+ setWrapper(0);
+#endif
+}
+
+AccessibilityObject* AccessibilityObject::firstChild() const
+{
+ return 0;
+}
+
+AccessibilityObject* AccessibilityObject::lastChild() const
+{
+ return 0;
+}
+
+AccessibilityObject* AccessibilityObject::previousSibling() const
+{
+ return 0;
+}
+
+AccessibilityObject* AccessibilityObject::nextSibling() const
+{
+ return 0;
+}
+
+AccessibilityObject* AccessibilityObject::parentObject() const
+{
+ return 0;
+}
+
+AccessibilityObject* AccessibilityObject::parentObjectUnignored() const
+{
+ AccessibilityObject* parent;
+ for (parent = parentObject(); parent && parent->accessibilityIsIgnored(); parent = parent->parentObject())
+ ;
+ return parent;
+}
+
+int AccessibilityObject::layoutCount() const
+{
+ return 0;
+}
+
+String AccessibilityObject::text() const
+{
+ return String();
+}
+
+String AccessibilityObject::helpText() const
+{
+ return String();
+}
+
+String AccessibilityObject::textUnderElement() const
+{
+ return String();
+}
+
+bool AccessibilityObject::isARIAInput(AccessibilityRole ariaRole)
+{
+ return ariaRole == RadioButtonRole || ariaRole == CheckBoxRole || ariaRole == TextFieldRole;
+}
+
+bool AccessibilityObject::isARIAControl(AccessibilityRole ariaRole)
+{
+ return isARIAInput(ariaRole) || ariaRole == TextAreaRole || ariaRole == ButtonRole
+ || ariaRole == ComboBoxRole || ariaRole == SliderRole;
+}
+
+int AccessibilityObject::intValue() const
+{
+ return 0;
+}
+
+String AccessibilityObject::stringValue() const
+{
+ return String();
+}
+
+String AccessibilityObject::ariaAccessiblityName(const String&) const
+{
+ return String();
+}
+
+String AccessibilityObject::ariaLabeledByAttribute() const
+{
+ return String();
+}
+
+String AccessibilityObject::title() const
+{
+ return String();
+}
+
+String AccessibilityObject::ariaDescribedByAttribute() const
+{
+ return String();
+}
+
+String AccessibilityObject::accessibilityDescription() const
+{
+ return String();
+}
+
+IntRect AccessibilityObject::boundingBoxRect() const
+{
+ return IntRect();
+}
+
+IntRect AccessibilityObject::elementRect() const
+{
+ return IntRect();
+}
+
+IntSize AccessibilityObject::size() const
+{
+ return IntSize();
+}
+
+IntPoint AccessibilityObject::clickPoint() const
+{
+ IntRect rect = elementRect();
+ return IntPoint(rect.x() + rect.width() / 2, rect.y() + rect.height() / 2);
+}
+
+void AccessibilityObject::linkedUIElements(AccessibilityChildrenVector&) const
+{
+ return;
+}
+
+AccessibilityObject* AccessibilityObject::titleUIElement() const
+{
+ return 0;
+}
+
+int AccessibilityObject::textLength() const
+{
+ return 0;
+}
+
+PassRefPtr<Range> AccessibilityObject::ariaSelectedTextDOMRange() const
+{
+ return 0;
+}
+
+String AccessibilityObject::selectedText() const
+{
+ return String();
+}
+
+const AtomicString& AccessibilityObject::accessKey() const
+{
+ return nullAtom;
+}
+
+Selection AccessibilityObject::selection() const
+{
+ return Selection();
+}
+
+PlainTextRange AccessibilityObject::selectedTextRange() const
+{
+ return PlainTextRange();
+}
+
+unsigned AccessibilityObject::selectionStart() const
+{
+ return selectedTextRange().start;
+}
+
+unsigned AccessibilityObject::selectionEnd() const
+{
+ return selectedTextRange().length;
+}
+
+void AccessibilityObject::setSelectedText(const String&)
+{
+ // TODO: set selected text (ReplaceSelectionCommand). <rdar://problem/4712125>
+ notImplemented();
+}
+
+void AccessibilityObject::setSelectedTextRange(const PlainTextRange& range)
+{
+}
+
+void AccessibilityObject::makeRangeVisible(const PlainTextRange&)
+{
+ // TODO: make range visible (scrollRectToVisible). <rdar://problem/4712101>
+ notImplemented();
+}
+
+KURL AccessibilityObject::url() const
+{
+ return KURL();
+}
+
+void AccessibilityObject::setFocused(bool on)
+{
+}
+
+void AccessibilityObject::setValue(const String& string)
+{
+}
+
+void AccessibilityObject::setSelected(bool)
+{
+}
+
+bool AccessibilityObject::press() const
+{
+ Element* actionElem = actionElement();
+ if (!actionElem)
+ return false;
+ if (Frame* f = actionElem->document()->frame())
+ f->loader()->resetMultipleFormSubmissionProtection();
+ actionElem->accessKeyAction(true);
+ return true;
+}
+
+AXObjectCache* AccessibilityObject::axObjectCache() const
+{
+ return 0;
+}
+
+Widget* AccessibilityObject::widget() const
+{
+ return 0;
+}
+
+Widget* AccessibilityObject::widgetForAttachmentView() const
+{
+ return 0;
+}
+
+Element* AccessibilityObject::anchorElement() const
+{
+ return 0;
+}
+
+Element* AccessibilityObject::actionElement() const
+{
+ return 0;
+}
+
+// This function is like a cross-platform version of - (WebCoreTextMarkerRange*)textMarkerRange. It returns
+// a Range that we can convert to a WebCoreRange in the Obj-C file
+VisiblePositionRange AccessibilityObject::visiblePositionRange() const
+{
+ return VisiblePositionRange();
+}
+
+VisiblePositionRange AccessibilityObject::visiblePositionRangeForLine(unsigned lineCount) const
+{
+ return VisiblePositionRange();
+}
+
+VisiblePosition AccessibilityObject::visiblePositionForIndex(int index) const
+{
+ return VisiblePosition();
+}
+
+int AccessibilityObject::indexForVisiblePosition(const VisiblePosition& pos) const
+{
+ return 0;
+}
+
+VisiblePositionRange AccessibilityObject::visiblePositionRangeForUnorderedPositions(const VisiblePosition& visiblePos1, const VisiblePosition& visiblePos2) const
+{
+ if (visiblePos1.isNull() || visiblePos2.isNull())
+ return VisiblePositionRange();
+
+ VisiblePosition startPos;
+ VisiblePosition endPos;
+ bool alreadyInOrder;
+
+ // upstream is ordered before downstream for the same position
+ if (visiblePos1 == visiblePos2 && visiblePos2.affinity() == UPSTREAM)
+ alreadyInOrder = false;
+
+ // use selection order to see if the positions are in order
+ else
+ alreadyInOrder = Selection(visiblePos1, visiblePos2).isBaseFirst();
+
+ if (alreadyInOrder) {
+ startPos = visiblePos1;
+ endPos = visiblePos2;
+ } else {
+ startPos = visiblePos2;
+ endPos = visiblePos1;
+ }
+
+ return VisiblePositionRange(startPos, endPos);
+}
+
+VisiblePositionRange AccessibilityObject::positionOfLeftWord(const VisiblePosition& visiblePos) const
+{
+ VisiblePosition startPosition = startOfWord(visiblePos, LeftWordIfOnBoundary);
+ VisiblePosition endPosition = endOfWord(startPosition);
+ return VisiblePositionRange(startPosition, endPosition);
+}
+
+VisiblePositionRange AccessibilityObject::positionOfRightWord(const VisiblePosition& visiblePos) const
+{
+ VisiblePosition startPosition = startOfWord(visiblePos, RightWordIfOnBoundary);
+ VisiblePosition endPosition = endOfWord(startPosition);
+ return VisiblePositionRange(startPosition, endPosition);
+}
+
+static VisiblePosition updateAXLineStartForVisiblePosition(const VisiblePosition& visiblePosition)
+{
+ // A line in the accessibility sense should include floating objects, such as aligned image, as part of a line.
+ // So let's update the position to include that.
+ VisiblePosition tempPosition;
+ VisiblePosition startPosition = visiblePosition;
+ Position p;
+ RenderObject* renderer;
+ while (true) {
+ tempPosition = startPosition.previous();
+ if (tempPosition.isNull())
+ break;
+ p = tempPosition.deepEquivalent();
+ if (!p.node())
+ break;
+ renderer = p.node()->renderer();
+ if (!renderer || renderer->isRenderBlock() && !p.offset())
+ break;
+ InlineBox* box;
+ int ignoredCaretOffset;
+ p.getInlineBoxAndOffset(tempPosition.affinity(), box, ignoredCaretOffset);
+ if (box)
+ break;
+ startPosition = tempPosition;
+ }
+
+ return startPosition;
+}
+
+VisiblePositionRange AccessibilityObject::leftLineVisiblePositionRange(const VisiblePosition& visiblePos) const
+{
+ if (visiblePos.isNull())
+ return VisiblePositionRange();
+
+ // make a caret selection for the position before marker position (to make sure
+ // we move off of a line start)
+ VisiblePosition prevVisiblePos = visiblePos.previous();
+ if (prevVisiblePos.isNull())
+ return VisiblePositionRange();
+
+ VisiblePosition startPosition = startOfLine(prevVisiblePos);
+
+ // keep searching for a valid line start position. Unless the VisiblePosition is at the very beginning, there should
+ // always be a valid line range. However, startOfLine will return null for position next to a floating object,
+ // since floating object doesn't really belong to any line.
+ // This check will reposition the marker before the floating object, to ensure we get a line start.
+ if (startPosition.isNull()) {
+ while (startPosition.isNull() && prevVisiblePos.isNotNull()) {
+ prevVisiblePos = prevVisiblePos.previous();
+ startPosition = startOfLine(prevVisiblePos);
+ }
+ } else
+ startPosition = updateAXLineStartForVisiblePosition(startPosition);
+
+ VisiblePosition endPosition = endOfLine(prevVisiblePos);
+ return VisiblePositionRange(startPosition, endPosition);
+}
+
+VisiblePositionRange AccessibilityObject::rightLineVisiblePositionRange(const VisiblePosition& visiblePos) const
+{
+ if (visiblePos.isNull())
+ return VisiblePositionRange();
+
+ // make sure we move off of a line end
+ VisiblePosition nextVisiblePos = visiblePos.next();
+ if (nextVisiblePos.isNull())
+ return VisiblePositionRange();
+
+ VisiblePosition startPosition = startOfLine(nextVisiblePos);
+
+ // fetch for a valid line start position
+ if (startPosition.isNull() ) {
+ startPosition = visiblePos;
+ nextVisiblePos = nextVisiblePos.next();
+ } else
+ startPosition = updateAXLineStartForVisiblePosition(startPosition);
+
+ VisiblePosition endPosition = endOfLine(nextVisiblePos);
+
+ // as long as the position hasn't reached the end of the doc, keep searching for a valid line end position
+ // Unless the VisiblePosition is at the very end, there should always be a valid line range. However, endOfLine will
+ // return null for position by a floating object, since floating object doesn't really belong to any line.
+ // This check will reposition the marker after the floating object, to ensure we get a line end.
+ while (endPosition.isNull() && nextVisiblePos.isNotNull()) {
+ nextVisiblePos = nextVisiblePos.next();
+ endPosition = endOfLine(nextVisiblePos);
+ }
+
+ return VisiblePositionRange(startPosition, endPosition);
+}
+
+VisiblePositionRange AccessibilityObject::sentenceForPosition(const VisiblePosition& visiblePos) const
+{
+ // FIXME: FO 2 IMPLEMENT (currently returns incorrect answer)
+ // Related? <rdar://problem/3927736> Text selection broken in 8A336
+ VisiblePosition startPosition = startOfSentence(visiblePos);
+ VisiblePosition endPosition = endOfSentence(startPosition);
+ return VisiblePositionRange(startPosition, endPosition);
+}
+
+VisiblePositionRange AccessibilityObject::paragraphForPosition(const VisiblePosition& visiblePos) const
+{
+ VisiblePosition startPosition = startOfParagraph(visiblePos);
+ VisiblePosition endPosition = endOfParagraph(startPosition);
+ return VisiblePositionRange(startPosition, endPosition);
+}
+
+static VisiblePosition startOfStyleRange(const VisiblePosition visiblePos)
+{
+ RenderObject* renderer = visiblePos.deepEquivalent().node()->renderer();
+ RenderObject* startRenderer = renderer;
+ RenderStyle* style = renderer->style();
+
+ // traverse backward by renderer to look for style change
+ for (RenderObject* r = renderer->previousInPreOrder(); r; r = r->previousInPreOrder()) {
+ // skip non-leaf nodes
+ if (r->firstChild())
+ continue;
+
+ // stop at style change
+ if (r->style() != style)
+ break;
+
+ // remember match
+ startRenderer = r;
+ }
+
+ return VisiblePosition(startRenderer->node(), 0, VP_DEFAULT_AFFINITY);
+}
+
+static VisiblePosition endOfStyleRange(const VisiblePosition visiblePos)
+{
+ RenderObject* renderer = visiblePos.deepEquivalent().node()->renderer();
+ RenderObject* endRenderer = renderer;
+ RenderStyle* style = renderer->style();
+
+ // traverse forward by renderer to look for style change
+ for (RenderObject* r = renderer->nextInPreOrder(); r; r = r->nextInPreOrder()) {
+ // skip non-leaf nodes
+ if (r->firstChild())
+ continue;
+
+ // stop at style change
+ if (r->style() != style)
+ break;
+
+ // remember match
+ endRenderer = r;
+ }
+
+ return VisiblePosition(endRenderer->node(), maxDeepOffset(endRenderer->node()), VP_DEFAULT_AFFINITY);
+}
+
+VisiblePositionRange AccessibilityObject::styleRangeForPosition(const VisiblePosition& visiblePos) const
+{
+ if (visiblePos.isNull())
+ return VisiblePositionRange();
+
+ return VisiblePositionRange(startOfStyleRange(visiblePos), endOfStyleRange(visiblePos));
+}
+
+// NOTE: Consider providing this utility method as AX API
+VisiblePositionRange AccessibilityObject::visiblePositionRangeForRange(const PlainTextRange& range) const
+{
+ if (range.start + range.length > text().length())
+ return VisiblePositionRange();
+
+ VisiblePosition startPosition = visiblePositionForIndex(range.start);
+ startPosition.setAffinity(DOWNSTREAM);
+ VisiblePosition endPosition = visiblePositionForIndex(range.start + range.length);
+ return VisiblePositionRange(startPosition, endPosition);
+}
+
+static bool replacedNodeNeedsCharacter(Node* replacedNode)
+{
+ // we should always be given a rendered node and a replaced node, but be safe
+ // replaced nodes are either attachments (widgets) or images
+ if (!replacedNode || !replacedNode->renderer() || !replacedNode->renderer()->isReplaced() || replacedNode->isTextNode()) {
+ return false;
+ }
+
+ // create an AX object, but skip it if it is not supposed to be seen
+ AccessibilityObject* object = replacedNode->renderer()->document()->axObjectCache()->get(replacedNode->renderer());
+ if (object->accessibilityIsIgnored())
+ return false;
+
+ return true;
+}
+
+String AccessibilityObject::stringForVisiblePositionRange(const VisiblePositionRange& visiblePositionRange) const
+{
+ if (visiblePositionRange.isNull())
+ return String();
+
+ Vector<UChar> resultVector;
+ RefPtr<Range> range = makeRange(visiblePositionRange.start, visiblePositionRange.end);
+ for (TextIterator it(range.get()); !it.atEnd(); it.advance()) {
+ // non-zero length means textual node, zero length means replaced node (AKA "attachments" in AX)
+ if (it.length() != 0) {
+ resultVector.append(it.characters(), it.length());
+ } else {
+ // locate the node and starting offset for this replaced range
+ int exception = 0;
+ Node* node = it.range()->startContainer(exception);
+ ASSERT(node == it.range()->endContainer(exception));
+ int offset = it.range()->startOffset(exception);
+
+ if (replacedNodeNeedsCharacter(node->childNode(offset))) {
+ resultVector.append(objectReplacementCharacter);
+ }
+ }
+ }
+
+ return String::adopt(resultVector);
+}
+
+IntRect AccessibilityObject::boundsForVisiblePositionRange(const VisiblePositionRange& visiblePositionRange) const
+{
+ return IntRect();
+}
+
+int AccessibilityObject::lengthForVisiblePositionRange(const VisiblePositionRange& visiblePositionRange) const
+{
+ // FIXME: Multi-byte support
+ if (visiblePositionRange.isNull())
+ return -1;
+
+ int length = 0;
+ RefPtr<Range> range = makeRange(visiblePositionRange.start, visiblePositionRange.end);
+ for (TextIterator it(range.get()); !it.atEnd(); it.advance()) {
+ // non-zero length means textual node, zero length means replaced node (AKA "attachments" in AX)
+ if (it.length() != 0) {
+ length += it.length();
+ } else {
+ // locate the node and starting offset for this replaced range
+ int exception = 0;
+ Node* node = it.range()->startContainer(exception);
+ ASSERT(node == it.range()->endContainer(exception));
+ int offset = it.range()->startOffset(exception);
+
+ if (replacedNodeNeedsCharacter(node->childNode(offset)))
+ length++;
+ }
+ }
+
+ return length;
+}
+
+void AccessibilityObject::setSelectedVisiblePositionRange(const VisiblePositionRange&) const
+{
+}
+
+VisiblePosition AccessibilityObject::visiblePositionForPoint(const IntPoint& point) const
+{
+ return VisiblePosition();
+}
+
+VisiblePosition AccessibilityObject::nextVisiblePosition(const VisiblePosition& visiblePos) const
+{
+ return visiblePos.next();
+}
+
+VisiblePosition AccessibilityObject::previousVisiblePosition(const VisiblePosition& visiblePos) const
+{
+ return visiblePos.previous();
+}
+
+VisiblePosition AccessibilityObject::nextWordEnd(const VisiblePosition& visiblePos) const
+{
+ if (visiblePos.isNull())
+ return VisiblePosition();
+
+ // make sure we move off of a word end
+ VisiblePosition nextVisiblePos = visiblePos.next();
+ if (nextVisiblePos.isNull())
+ return VisiblePosition();
+
+ return endOfWord(nextVisiblePos, LeftWordIfOnBoundary);
+}
+
+VisiblePosition AccessibilityObject::previousWordStart(const VisiblePosition& visiblePos) const
+{
+ if (visiblePos.isNull())
+ return VisiblePosition();
+
+ // make sure we move off of a word start
+ VisiblePosition prevVisiblePos = visiblePos.previous();
+ if (prevVisiblePos.isNull())
+ return VisiblePosition();
+
+ return startOfWord(prevVisiblePos, RightWordIfOnBoundary);
+}
+
+VisiblePosition AccessibilityObject::nextLineEndPosition(const VisiblePosition& visiblePos) const
+{
+ if (visiblePos.isNull())
+ return VisiblePosition();
+
+ // to make sure we move off of a line end
+ VisiblePosition nextVisiblePos = visiblePos.next();
+ if (nextVisiblePos.isNull())
+ return VisiblePosition();
+
+ VisiblePosition endPosition = endOfLine(nextVisiblePos);
+
+ // as long as the position hasn't reached the end of the doc, keep searching for a valid line end position
+ // There are cases like when the position is next to a floating object that'll return null for end of line. This code will avoid returning null.
+ while (endPosition.isNull() && nextVisiblePos.isNotNull()) {
+ nextVisiblePos = nextVisiblePos.next();
+ endPosition = endOfLine(nextVisiblePos);
+ }
+
+ return endPosition;
+}
+
+VisiblePosition AccessibilityObject::previousLineStartPosition(const VisiblePosition& visiblePos) const
+{
+ if (visiblePos.isNull())
+ return VisiblePosition();
+
+ // make sure we move off of a line start
+ VisiblePosition prevVisiblePos = visiblePos.previous();
+ if (prevVisiblePos.isNull())
+ return VisiblePosition();
+
+ VisiblePosition startPosition = startOfLine(prevVisiblePos);
+
+ // as long as the position hasn't reached the beginning of the doc, keep searching for a valid line start position
+ // There are cases like when the position is next to a floating object that'll return null for start of line. This code will avoid returning null.
+ if (startPosition.isNull()) {
+ while (startPosition.isNull() && prevVisiblePos.isNotNull()) {
+ prevVisiblePos = prevVisiblePos.previous();
+ startPosition = startOfLine(prevVisiblePos);
+ }
+ } else
+ startPosition = updateAXLineStartForVisiblePosition(startPosition);
+
+ return startPosition;
+}
+
+VisiblePosition AccessibilityObject::nextSentenceEndPosition(const VisiblePosition& visiblePos) const
+{
+ // FIXME: FO 2 IMPLEMENT (currently returns incorrect answer)
+ // Related? <rdar://problem/3927736> Text selection broken in 8A336
+ if (visiblePos.isNull())
+ return VisiblePosition();
+
+ // make sure we move off of a sentence end
+ VisiblePosition nextVisiblePos = visiblePos.next();
+ if (nextVisiblePos.isNull())
+ return VisiblePosition();
+
+ // an empty line is considered a sentence. If it's skipped, then the sentence parser will not
+ // see this empty line. Instead, return the end position of the empty line.
+ VisiblePosition endPosition;
+ String lineString = plainText(makeRange(startOfLine(visiblePos), endOfLine(visiblePos)).get());
+ if (lineString.isEmpty())
+ endPosition = nextVisiblePos;
+ else
+ endPosition = endOfSentence(nextVisiblePos);
+
+ return endPosition;
+}
+
+VisiblePosition AccessibilityObject::previousSentenceStartPosition(const VisiblePosition& visiblePos) const
+{
+ // FIXME: FO 2 IMPLEMENT (currently returns incorrect answer)
+ // Related? <rdar://problem/3927736> Text selection broken in 8A336
+ if (visiblePos.isNull())
+ return VisiblePosition();
+
+ // make sure we move off of a sentence start
+ VisiblePosition previousVisiblePos = visiblePos.previous();
+ if (previousVisiblePos.isNull())
+ return VisiblePosition();
+
+ // treat empty line as a separate sentence.
+ VisiblePosition startPosition;
+ String lineString = plainText(makeRange(startOfLine(previousVisiblePos), endOfLine(previousVisiblePos)).get());
+ if (lineString.isEmpty())
+ startPosition = previousVisiblePos;
+ else
+ startPosition = startOfSentence(previousVisiblePos);
+
+ return startPosition;
+}
+
+VisiblePosition AccessibilityObject::nextParagraphEndPosition(const VisiblePosition& visiblePos) const
+{
+ if (visiblePos.isNull())
+ return VisiblePosition();
+
+ // make sure we move off of a paragraph end
+ VisiblePosition nextPos = visiblePos.next();
+ if (nextPos.isNull())
+ return VisiblePosition();
+
+ return endOfParagraph(nextPos);
+}
+
+VisiblePosition AccessibilityObject::previousParagraphStartPosition(const VisiblePosition& visiblePos) const
+{
+ if (visiblePos.isNull())
+ return VisiblePosition();
+
+ // make sure we move off of a paragraph start
+ VisiblePosition previousPos = visiblePos.previous();
+ if (previousPos.isNull())
+ return VisiblePosition();
+
+ return startOfParagraph(previousPos);
+}
+
+// NOTE: Consider providing this utility method as AX API
+VisiblePosition AccessibilityObject::visiblePositionForIndex(unsigned indexValue, bool lastIndexOK) const
+{
+ return VisiblePosition();
+}
+
+AccessibilityObject* AccessibilityObject::accessibilityObjectForPosition(const VisiblePosition& visiblePos) const
+{
+ if (visiblePos.isNull())
+ return 0;
+
+ RenderObject* obj = visiblePos.deepEquivalent().node()->renderer();
+ if (!obj)
+ return 0;
+
+ return obj->document()->axObjectCache()->get(obj);
+}
+
+int AccessibilityObject::lineForPosition(const VisiblePosition& visiblePos) const
+{
+ if (visiblePos.isNull())
+ return 0;
+
+ unsigned lineCount = 0;
+ VisiblePosition currentVisiblePos = visiblePos;
+ VisiblePosition savedVisiblePos;
+
+ // move up until we get to the top
+ // FIXME: This only takes us to the top of the rootEditableElement, not the top of the
+ // top document.
+ while (currentVisiblePos.isNotNull() && !(inSameLine(currentVisiblePos, savedVisiblePos))) {
+ ++lineCount;
+ savedVisiblePos = currentVisiblePos;
+ VisiblePosition prevVisiblePos = previousLinePosition(currentVisiblePos, 0);
+ currentVisiblePos = prevVisiblePos;
+ }
+
+ return lineCount - 1;
+}
+
+// NOTE: Consider providing this utility method as AX API
+PlainTextRange AccessibilityObject::plainTextRangeForVisiblePositionRange(const VisiblePositionRange& positionRange) const
+{
+ int index1 = index(positionRange.start);
+ int index2 = index(positionRange.end);
+ if (index1 < 0 || index2 < 0 || index1 > index2)
+ return PlainTextRange();
+
+ return PlainTextRange(index1, index2 - index1);
+}
+
+// NOTE: Consider providing this utility method as AX API
+int AccessibilityObject::index(const VisiblePosition& position) const
+{
+ return -1;
+}
+
+// Given a line number, the range of characters of the text associated with this accessibility
+// object that contains the line number.
+PlainTextRange AccessibilityObject::doAXRangeForLine(unsigned lineNumber) const
+{
+ return PlainTextRange();
+}
+
+// The composed character range in the text associated with this accessibility object that
+// is specified by the given screen coordinates. This parameterized attribute returns the
+// complete range of characters (including surrogate pairs of multi-byte glyphs) at the given
+// screen coordinates.
+// NOTE: This varies from AppKit when the point is below the last line. AppKit returns an
+// an error in that case. We return textControl->text().length(), 1. Does this matter?
+PlainTextRange AccessibilityObject::doAXRangeForPosition(const IntPoint& point) const
+{
+ int i = index(visiblePositionForPoint(point));
+ if (i < 0)
+ return PlainTextRange();
+
+ return PlainTextRange(i, 1);
+}
+
+// The composed character range in the text associated with this accessibility object that
+// is specified by the given index value. This parameterized attribute returns the complete
+// range of characters (including surrogate pairs of multi-byte glyphs) at the given index.
+PlainTextRange AccessibilityObject::doAXRangeForIndex(unsigned index) const
+{
+ return PlainTextRange();
+}
+
+// Given a character index, the range of text associated with this accessibility object
+// over which the style in effect at that character index applies.
+PlainTextRange AccessibilityObject::doAXStyleRangeForIndex(unsigned index) const
+{
+ VisiblePositionRange range = styleRangeForPosition(visiblePositionForIndex(index, false));
+ return plainTextRangeForVisiblePositionRange(range);
+}
+
+// A substring of the text associated with this accessibility object that is
+// specified by the given character range.
+String AccessibilityObject::doAXStringForRange(const PlainTextRange& range) const
+{
+ return String();
+}
+
+// The bounding rectangle of the text associated with this accessibility object that is
+// specified by the given range. This is the bounding rectangle a sighted user would see
+// on the display screen, in pixels.
+IntRect AccessibilityObject::doAXBoundsForRange(const PlainTextRange& range) const
+{
+ return IntRect();
+}
+
+// Given an indexed character, the line number of the text associated with this accessibility
+// object that contains the character.
+unsigned AccessibilityObject::doAXLineForIndex(unsigned index)
+{
+ return lineForPosition(visiblePositionForIndex(index, false));
+}
+
+FrameView* AccessibilityObject::documentFrameView() const
+{
+ const AccessibilityObject* object = this;
+ while (object && !object->isAccessibilityRenderObject())
+ object = object->parentObject();
+
+ if (!object)
+ return 0;
+
+ return object->documentFrameView();
+}
+
+AccessibilityObject* AccessibilityObject::doAccessibilityHitTest(const IntPoint& point) const
+{
+ return 0;
+}
+
+AccessibilityObject* AccessibilityObject::focusedUIElement() const
+{
+ return 0;
+}
+
+AccessibilityObject* AccessibilityObject::observableObject() const
+{
+ return 0;
+}
+
+AccessibilityRole AccessibilityObject::roleValue() const
+{
+ return UnknownRole;
+}
+
+AccessibilityRole AccessibilityObject::ariaRoleAttribute() const
+{
+ return UnknownRole;
+}
+
+bool AccessibilityObject::isPresentationalChildOfAriaRole() const
+{
+ return false;
+}
+
+bool AccessibilityObject::ariaRoleHasPresentationalChildren() const
+{
+ return false;
+}
+
+void AccessibilityObject::clearChildren()
+{
+ m_haveChildren = false;
+ m_children.clear();
+}
+
+void AccessibilityObject::childrenChanged()
+{
+ return;
+}
+
+void AccessibilityObject::addChildren()
+{
+}
+
+void AccessibilityObject::selectedChildren(AccessibilityChildrenVector&)
+{
+}
+
+void AccessibilityObject::visibleChildren(AccessibilityChildrenVector&)
+{
+}
+
+unsigned AccessibilityObject::axObjectID() const
+{
+ return m_id;
+}
+
+void AccessibilityObject::setAXObjectID(unsigned axObjectID)
+{
+ m_id = axObjectID;
+}
+
+void AccessibilityObject::removeAXObjectID()
+{
+ return;
+}
+
+const String& AccessibilityObject::actionVerb() const
+{
+ // FIXME: Need to add verbs for select elements.
+ static const String buttonAction = AXButtonActionVerb();
+ static const String textFieldAction = AXTextFieldActionVerb();
+ static const String radioButtonAction = AXRadioButtonActionVerb();
+ static const String checkedCheckBoxAction = AXCheckedCheckBoxActionVerb();
+ static const String uncheckedCheckBoxAction = AXUncheckedCheckBoxActionVerb();
+ static const String linkAction = AXLinkActionVerb();
+ static const String noAction;
+
+ switch (roleValue()) {
+ case ButtonRole:
+ return buttonAction;
+ case TextFieldRole:
+ case TextAreaRole:
+ return textFieldAction;
+ case RadioButtonRole:
+ return radioButtonAction;
+ case CheckBoxRole:
+ return isChecked() ? checkedCheckBoxAction : uncheckedCheckBoxAction;
+ case LinkRole:
+ case WebCoreLinkRole:
+ return linkAction;
+ default:
+ return noAction;
+ }
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/AccessibilityObject.h b/WebCore/page/AccessibilityObject.h
new file mode 100644
index 0000000..947757a
--- /dev/null
+++ b/WebCore/page/AccessibilityObject.h
@@ -0,0 +1,419 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Nuanti Ltd.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 AccessibilityObject_h
+#define AccessibilityObject_h
+
+#include "VisiblePosition.h"
+#include <wtf/Platform.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
+
+#if PLATFORM(MAC)
+#include <wtf/RetainPtr.h>
+#elif PLATFORM(WIN)
+#include "AccessibilityObjectWrapperWin.h"
+#include "COMPtr.h"
+#elif PLATFORM(CHROMIUM)
+#include "AccessibilityObjectWrapper.h"
+#endif
+
+typedef struct _NSRange NSRange;
+
+#ifdef __OBJC__
+@class AccessibilityObjectWrapper;
+@class NSArray;
+@class NSAttributedString;
+@class NSData;
+@class NSMutableAttributedString;
+@class NSString;
+@class NSValue;
+@class NSView;
+#else
+class NSArray;
+class NSAttributedString;
+class NSData;
+class NSMutableAttributedString;
+class NSString;
+class NSValue;
+class NSView;
+#if PLATFORM(GTK)
+typedef struct _AtkObject AtkObject;
+typedef struct _AtkObject AccessibilityObjectWrapper;
+#else
+class AccessibilityObjectWrapper;
+#endif
+#endif
+
+namespace WebCore {
+
+class AXObjectCache;
+class Element;
+class Frame;
+class FrameView;
+class HTMLAnchorElement;
+class HTMLAreaElement;
+class IntPoint;
+class IntSize;
+class Node;
+class RenderObject;
+class Selection;
+class String;
+class Widget;
+
+enum AccessibilityRole {
+ UnknownRole = 1,
+ ButtonRole,
+ RadioButtonRole,
+ CheckBoxRole,
+ SliderRole,
+ TabGroupRole,
+ TextFieldRole,
+ StaticTextRole,
+ TextAreaRole,
+ ScrollAreaRole,
+ PopUpButtonRole,
+ MenuButtonRole,
+ TableRole,
+ ApplicationRole,
+ GroupRole,
+ RadioGroupRole,
+ ListRole,
+ ScrollBarRole,
+ ValueIndicatorRole,
+ ImageRole,
+ MenuBarRole,
+ MenuRole,
+ MenuItemRole,
+ ColumnRole,
+ RowRole,
+ ToolbarRole,
+ BusyIndicatorRole,
+ ProgressIndicatorRole,
+ WindowRole,
+ DrawerRole,
+ SystemWideRole,
+ OutlineRole,
+ IncrementorRole,
+ BrowserRole,
+ ComboBoxRole,
+ SplitGroupRole,
+ SplitterRole,
+ ColorWellRole,
+ GrowAreaRole,
+ SheetRole,
+ HelpTagRole,
+ MatteRole,
+ RulerRole,
+ RulerMarkerRole,
+ LinkRole,
+ DisclosureTriangleRole,
+ GridRole,
+ CellRole,
+ // AppKit includes SortButtonRole but it is misnamed and really a subrole of ButtonRole so we do not include it here.
+
+ // WebCore-specific roles
+ WebCoreLinkRole,
+ ImageMapLinkRole,
+ ImageMapRole,
+ ListMarkerRole,
+ WebAreaRole,
+ HeadingRole,
+ ListBoxRole,
+ ListBoxOptionRole,
+ TableHeaderContainerRole,
+ DefinitionListTermRole,
+ DefinitionListDefinitionRole
+};
+
+struct VisiblePositionRange {
+
+ VisiblePosition start;
+ VisiblePosition end;
+
+ VisiblePositionRange() {}
+
+ VisiblePositionRange(const VisiblePosition& s, const VisiblePosition& e)
+ : start(s)
+ , end(e)
+ { }
+
+ bool isNull() const { return start.isNull() || end.isNull(); }
+};
+
+struct PlainTextRange {
+
+ unsigned start;
+ unsigned length;
+
+ PlainTextRange()
+ : start(0)
+ , length(0)
+ { }
+
+ PlainTextRange(unsigned s, unsigned l)
+ : start(s)
+ , length(l)
+ { }
+
+ bool isNull() const { return start == 0 && length == 0; }
+};
+
+class AccessibilityObject : public RefCounted<AccessibilityObject> {
+protected:
+ AccessibilityObject();
+public:
+ virtual ~AccessibilityObject();
+
+ typedef Vector<RefPtr<AccessibilityObject> > AccessibilityChildrenVector;
+
+ virtual bool isAccessibilityRenderObject() const { return false; };
+ virtual bool isAnchor() const { return false; };
+ virtual bool isAttachment() const { return false; };
+ virtual bool isHeading() const { return false; };
+ virtual bool isLink() const { return false; };
+ virtual bool isImage() const { return false; };
+ virtual bool isNativeImage() const { return false; };
+ virtual bool isImageButton() const { return false; };
+ virtual bool isPasswordField() const { return false; };
+ virtual bool isTextControl() const { return false; };
+ virtual bool isNativeTextControl() const { return false; };
+ virtual bool isWebArea() const { return false; };
+ virtual bool isCheckboxOrRadio() const { return false; };
+ virtual bool isListBox() const { return roleValue() == ListBoxRole; };
+ virtual bool isMenuRelated() const { return false; }
+ virtual bool isMenu() const { return false; }
+ virtual bool isMenuBar() const { return false; }
+ virtual bool isMenuButton() const { return false; }
+ virtual bool isMenuItem() const { return false; }
+ virtual bool isFileUploadButton() const { return false; };
+ virtual bool isProgressIndicator() const { return false; };
+ virtual bool isSlider() const { return false; };
+ virtual bool isControl() const { return false; };
+ virtual bool isList() const { return false; };
+ virtual bool isDataTable() const { return false; };
+ virtual bool isTableRow() const { return false; };
+ virtual bool isTableColumn() const { return false; };
+ virtual bool isTableCell() const { return false; };
+ virtual bool isFieldset() const { return false; };
+
+ virtual bool isChecked() const { return false; };
+ virtual bool isEnabled() const { return false; };
+ virtual bool isSelected() const { return false; };
+ virtual bool isFocused() const { return false; };
+ virtual bool isHovered() const { return false; };
+ virtual bool isIndeterminate() const { return false; };
+ virtual bool isLoaded() const { return false; };
+ virtual bool isMultiSelect() const { return false; };
+ virtual bool isOffScreen() const { return false; };
+ virtual bool isPressed() const { return false; };
+ virtual bool isReadOnly() const { return false; };
+ virtual bool isVisited() const { return false; };
+
+ virtual bool canSetFocusAttribute() const { return false; };
+ virtual bool canSetTextRangeAttributes() const { return false; };
+ virtual bool canSetValueAttribute() const { return false; };
+ virtual bool canSetSelectedAttribute() const { return false; }
+ virtual bool canSetSelectedChildrenAttribute() const { return false; }
+
+ virtual bool hasIntValue() const { return false; };
+
+ bool accessibilityShouldUseUniqueId() const { return true; };
+ virtual bool accessibilityIsIgnored() const { return true; };
+
+ virtual int intValue() const;
+ virtual float valueForRange() const { return 0.0f; }
+ virtual float maxValueForRange() const { return 0.0f; }
+ virtual float minValueForRange() const {return 0.0f; }
+ virtual int layoutCount() const;
+ static bool isARIAControl(AccessibilityRole);
+ static bool isARIAInput(AccessibilityRole);
+ unsigned axObjectID() const;
+
+ virtual AccessibilityObject* doAccessibilityHitTest(const IntPoint&) const;
+ virtual AccessibilityObject* focusedUIElement() const;
+ virtual AccessibilityObject* firstChild() const;
+ virtual AccessibilityObject* lastChild() const;
+ virtual AccessibilityObject* previousSibling() const;
+ virtual AccessibilityObject* nextSibling() const;
+ virtual AccessibilityObject* parentObject() const;
+ virtual AccessibilityObject* parentObjectUnignored() const;
+ virtual AccessibilityObject* observableObject() const;
+ virtual void linkedUIElements(AccessibilityChildrenVector&) const;
+ virtual AccessibilityObject* titleUIElement() const;
+ virtual AccessibilityRole ariaRoleAttribute() const;
+ virtual bool isPresentationalChildOfAriaRole() const;
+ virtual bool ariaRoleHasPresentationalChildren() const;
+
+ virtual AccessibilityRole roleValue() const;
+ virtual AXObjectCache* axObjectCache() const;
+
+ virtual Element* anchorElement() const;
+ virtual Element* actionElement() const;
+ virtual IntRect boundingBoxRect() const;
+ virtual IntRect elementRect() const;
+ virtual IntSize size() const;
+ IntPoint clickPoint() const;
+
+ virtual KURL url() const;
+ virtual PlainTextRange selectedTextRange() const;
+ virtual Selection selection() const;
+ unsigned selectionStart() const;
+ unsigned selectionEnd() const;
+ virtual String stringValue() const;
+ virtual String ariaAccessiblityName(const String&) const;
+ virtual String ariaLabeledByAttribute() const;
+ virtual String title() const;
+ virtual String ariaDescribedByAttribute() const;
+ virtual String accessibilityDescription() const;
+ virtual String helpText() const;
+ virtual String textUnderElement() const;
+ virtual String text() const;
+ virtual int textLength() const;
+ virtual PassRefPtr<Range> ariaSelectedTextDOMRange() const;
+ virtual String selectedText() const;
+ virtual const AtomicString& accessKey() const;
+ const String& actionVerb() const;
+ virtual Widget* widget() const;
+ virtual Widget* widgetForAttachmentView() const;
+ virtual Document* document() const { return 0; }
+ virtual FrameView* topDocumentFrameView() const { return 0; }
+ virtual FrameView* documentFrameView() const;
+
+ void setAXObjectID(unsigned);
+ virtual void setFocused(bool);
+ virtual void setSelectedText(const String&);
+ virtual void setSelectedTextRange(const PlainTextRange&);
+ virtual void setValue(const String&);
+ virtual void setSelected(bool);
+
+ virtual void detach();
+ virtual void makeRangeVisible(const PlainTextRange&);
+ virtual bool press() const;
+ bool performDefaultAction() const { return press(); }
+
+ virtual void childrenChanged();
+ virtual const AccessibilityChildrenVector& children() { return m_children; }
+ virtual void addChildren();
+ virtual bool canHaveChildren() const { return true; }
+ virtual bool hasChildren() const { return m_haveChildren; };
+ virtual void selectedChildren(AccessibilityChildrenVector&);
+ virtual void visibleChildren(AccessibilityChildrenVector&);
+ virtual bool shouldFocusActiveDescendant() const { return false; }
+ virtual AccessibilityObject* activeDescendant() const { return 0; }
+ virtual void handleActiveDescendantChanged() { }
+
+ virtual VisiblePositionRange visiblePositionRange() const;
+ virtual VisiblePositionRange visiblePositionRangeForLine(unsigned) const;
+
+ VisiblePositionRange visiblePositionRangeForUnorderedPositions(const VisiblePosition&, const VisiblePosition&) const;
+ VisiblePositionRange positionOfLeftWord(const VisiblePosition&) const;
+ VisiblePositionRange positionOfRightWord(const VisiblePosition&) const;
+ VisiblePositionRange leftLineVisiblePositionRange(const VisiblePosition&) const;
+ VisiblePositionRange rightLineVisiblePositionRange(const VisiblePosition&) const;
+ VisiblePositionRange sentenceForPosition(const VisiblePosition&) const;
+ VisiblePositionRange paragraphForPosition(const VisiblePosition&) const;
+ VisiblePositionRange styleRangeForPosition(const VisiblePosition&) const;
+ VisiblePositionRange visiblePositionRangeForRange(const PlainTextRange&) const;
+
+ String stringForVisiblePositionRange(const VisiblePositionRange&) const;
+ virtual IntRect boundsForVisiblePositionRange(const VisiblePositionRange&) const;
+ int lengthForVisiblePositionRange(const VisiblePositionRange&) const;
+ virtual void setSelectedVisiblePositionRange(const VisiblePositionRange&) const;
+
+ virtual VisiblePosition visiblePositionForPoint(const IntPoint&) const;
+ VisiblePosition nextVisiblePosition(const VisiblePosition&) const;
+ VisiblePosition previousVisiblePosition(const VisiblePosition&) const;
+ VisiblePosition nextWordEnd(const VisiblePosition&) const;
+ VisiblePosition previousWordStart(const VisiblePosition&) const;
+ VisiblePosition nextLineEndPosition(const VisiblePosition&) const;
+ VisiblePosition previousLineStartPosition(const VisiblePosition&) const;
+ VisiblePosition nextSentenceEndPosition(const VisiblePosition&) const;
+ VisiblePosition previousSentenceStartPosition(const VisiblePosition&) const;
+ VisiblePosition nextParagraphEndPosition(const VisiblePosition&) const;
+ VisiblePosition previousParagraphStartPosition(const VisiblePosition&) const;
+ virtual VisiblePosition visiblePositionForIndex(unsigned indexValue, bool lastIndexOK) const;
+
+ virtual VisiblePosition visiblePositionForIndex(int) const;
+ virtual int indexForVisiblePosition(const VisiblePosition&) const;
+
+ AccessibilityObject* accessibilityObjectForPosition(const VisiblePosition&) const;
+ int lineForPosition(const VisiblePosition&) const;
+ PlainTextRange plainTextRangeForVisiblePositionRange(const VisiblePositionRange&) const;
+ virtual int index(const VisiblePosition&) const;
+
+ virtual PlainTextRange doAXRangeForLine(unsigned) const;
+ PlainTextRange doAXRangeForPosition(const IntPoint&) const;
+ virtual PlainTextRange doAXRangeForIndex(unsigned) const;
+ PlainTextRange doAXStyleRangeForIndex(unsigned) const;
+
+ virtual String doAXStringForRange(const PlainTextRange&) const;
+ virtual IntRect doAXBoundsForRange(const PlainTextRange&) const;
+
+ unsigned doAXLineForIndex(unsigned);
+
+#if HAVE(ACCESSIBILITY)
+#if PLATFORM(GTK)
+ AccessibilityObjectWrapper* wrapper() const;
+ void setWrapper(AccessibilityObjectWrapper*);
+#else
+ AccessibilityObjectWrapper* wrapper() const { return m_wrapper.get(); }
+ void setWrapper(AccessibilityObjectWrapper* wrapper)
+ {
+ m_wrapper = wrapper;
+ }
+#endif
+#endif
+
+ // a platform-specific method for determining if an attachment is ignored
+ bool accessibilityIgnoreAttachment() const;
+
+protected:
+ unsigned m_id;
+ AccessibilityChildrenVector m_children;
+ mutable bool m_haveChildren;
+
+ virtual void clearChildren();
+ virtual void removeAXObjectID();
+ virtual bool isDetached() const { return true; }
+
+#if PLATFORM(MAC)
+ RetainPtr<AccessibilityObjectWrapper> m_wrapper;
+#elif PLATFORM(WIN)
+ COMPtr<AccessibilityObjectWrapper> m_wrapper;
+#elif PLATFORM(GTK)
+ AtkObject* m_wrapper;
+#elif PLATFORM(CHROMIUM)
+ RefPtr<AccessibilityObjectWrapper> m_wrapper;
+#endif
+};
+
+} // namespace WebCore
+
+#endif // AccessibilityObject_h
diff --git a/WebCore/page/AccessibilityRenderObject.cpp b/WebCore/page/AccessibilityRenderObject.cpp
new file mode 100644
index 0000000..144aab0
--- /dev/null
+++ b/WebCore/page/AccessibilityRenderObject.cpp
@@ -0,0 +1,2378 @@
+/*
+* Copyright (C) 2008 Apple Inc. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "config.h"
+#include "AccessibilityRenderObject.h"
+
+#include "AXObjectCache.h"
+#include "AccessibilityListBox.h"
+#include "AccessibilityImageMapLink.h"
+#include "CharacterNames.h"
+#include "EventNames.h"
+#include "FloatRect.h"
+#include "FocusController.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "HTMLAreaElement.h"
+#include "HTMLFrameElementBase.h"
+#include "HTMLImageElement.h"
+#include "HTMLInputElement.h"
+#include "HTMLLabelElement.h"
+#include "HTMLMapElement.h"
+#include "HTMLOptGroupElement.h"
+#include "HTMLOptionElement.h"
+#include "HTMLOptionsCollection.h"
+#include "HTMLSelectElement.h"
+#include "HTMLTextAreaElement.h"
+#include "HitTestRequest.h"
+#include "HitTestResult.h"
+#include "LocalizedStrings.h"
+#include "NodeList.h"
+#include "NotImplemented.h"
+#include "Page.h"
+#include "RenderFieldset.h"
+#include "RenderFileUploadControl.h"
+#include "RenderImage.h"
+#include "RenderListBox.h"
+#include "RenderListMarker.h"
+#include "RenderMenuList.h"
+#include "RenderTextControl.h"
+#include "RenderTheme.h"
+#include "RenderView.h"
+#include "RenderWidget.h"
+#include "SelectionController.h"
+#include "Text.h"
+#include "TextIterator.h"
+#include "htmlediting.h"
+#include "visible_units.h"
+
+using namespace std;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+AccessibilityRenderObject::AccessibilityRenderObject(RenderObject* renderer)
+ : m_renderer(renderer)
+ , m_ariaRole(UnknownRole)
+{
+ setAriaRole();
+#ifndef NDEBUG
+ m_renderer->setHasAXObject(true);
+#endif
+}
+
+AccessibilityRenderObject::~AccessibilityRenderObject()
+{
+ ASSERT(isDetached());
+}
+
+PassRefPtr<AccessibilityRenderObject> AccessibilityRenderObject::create(RenderObject* renderer)
+{
+ return adoptRef(new AccessibilityRenderObject(renderer));
+}
+
+void AccessibilityRenderObject::detach()
+{
+ clearChildren();
+ AccessibilityObject::detach();
+
+#ifndef NDEBUG
+ if (m_renderer)
+ m_renderer->setHasAXObject(false);
+#endif
+ m_renderer = 0;
+}
+
+AccessibilityObject* AccessibilityRenderObject::firstChild() const
+{
+ if (!m_renderer)
+ return 0;
+
+ RenderObject* firstChild = m_renderer->firstChild();
+ if (!firstChild)
+ return 0;
+
+ return m_renderer->document()->axObjectCache()->get(firstChild);
+}
+
+AccessibilityObject* AccessibilityRenderObject::lastChild() const
+{
+ if (!m_renderer)
+ return 0;
+
+ RenderObject* lastChild = m_renderer->lastChild();
+ if (!lastChild)
+ return 0;
+
+ return m_renderer->document()->axObjectCache()->get(lastChild);
+}
+
+AccessibilityObject* AccessibilityRenderObject::previousSibling() const
+{
+ if (!m_renderer)
+ return 0;
+
+ RenderObject* previousSibling = m_renderer->previousSibling();
+ if (!previousSibling)
+ return 0;
+
+ return m_renderer->document()->axObjectCache()->get(previousSibling);
+}
+
+AccessibilityObject* AccessibilityRenderObject::nextSibling() const
+{
+ if (!m_renderer)
+ return 0;
+
+ RenderObject* nextSibling = m_renderer->nextSibling();
+ if (!nextSibling)
+ return 0;
+
+ return m_renderer->document()->axObjectCache()->get(nextSibling);
+}
+
+AccessibilityObject* AccessibilityRenderObject::parentObject() const
+{
+ if (!m_renderer)
+ return 0;
+
+ RenderObject *parent = m_renderer->parent();
+ if (!parent)
+ return 0;
+
+ if (ariaRoleAttribute() == MenuBarRole)
+ return m_renderer->document()->axObjectCache()->get(parent);
+
+ // menuButton and its corresponding menu are DOM siblings, but Accessibility needs them to be parent/child
+ if (ariaRoleAttribute() == MenuRole) {
+ AccessibilityObject* parent = menuButtonForMenu();
+ if (parent)
+ return parent;
+ }
+
+ return m_renderer->document()->axObjectCache()->get(parent);
+}
+
+bool AccessibilityRenderObject::isWebArea() const
+{
+ return roleValue() == WebAreaRole;
+}
+
+bool AccessibilityRenderObject::isImageButton() const
+{
+ return isNativeImage() && roleValue() == ButtonRole;
+}
+
+bool AccessibilityRenderObject::isAnchor() const
+{
+ return !isNativeImage() && isLink();
+}
+
+bool AccessibilityRenderObject::isNativeTextControl() const
+{
+ return m_renderer->isTextField() || m_renderer->isTextArea();
+}
+
+bool AccessibilityRenderObject::isTextControl() const
+{
+ AccessibilityRole role = roleValue();
+ return role == TextAreaRole || role == TextFieldRole;
+}
+
+bool AccessibilityRenderObject::isNativeImage() const
+{
+ return m_renderer->isImage();
+}
+
+bool AccessibilityRenderObject::isImage() const
+{
+ return roleValue() == ImageRole;
+}
+
+bool AccessibilityRenderObject::isAttachment() const
+{
+ // Widgets are the replaced elements that we represent to AX as attachments
+ bool isWidget = m_renderer && m_renderer->isWidget();
+ ASSERT(!isWidget || (m_renderer->isReplaced() && !isImage()));
+ return isWidget && ariaRoleAttribute() == UnknownRole;
+}
+
+bool AccessibilityRenderObject::isPasswordField() const
+{
+ ASSERT(m_renderer);
+ if (!m_renderer->element() || !m_renderer->element()->isHTMLElement())
+ return false;
+ return static_cast<HTMLElement*>(m_renderer->element())->isPasswordField() && ariaRoleAttribute() == UnknownRole;
+}
+
+bool AccessibilityRenderObject::isCheckboxOrRadio() const
+{
+ AccessibilityRole role = roleValue();
+ return role == RadioButtonRole || role == CheckBoxRole;
+}
+
+bool AccessibilityRenderObject::isFileUploadButton() const
+{
+ if (m_renderer && m_renderer->element() && m_renderer->element()->hasTagName(inputTag)) {
+ HTMLInputElement* input = static_cast<HTMLInputElement*>(m_renderer->element());
+ return input->inputType() == HTMLInputElement::FILE;
+ }
+
+ return false;
+}
+
+bool AccessibilityRenderObject::isProgressIndicator() const
+{
+ return roleValue() == ProgressIndicatorRole;
+}
+
+bool AccessibilityRenderObject::isSlider() const
+{
+ return roleValue() == SliderRole;
+}
+
+bool AccessibilityRenderObject::isMenuRelated() const
+{
+ AccessibilityRole role = roleValue();
+ return role == MenuRole ||
+ role == MenuBarRole ||
+ role == MenuButtonRole ||
+ role == MenuItemRole;
+}
+
+bool AccessibilityRenderObject::isMenu() const
+{
+ return roleValue() == MenuRole;
+}
+
+bool AccessibilityRenderObject::isMenuBar() const
+{
+ return roleValue() == MenuBarRole;
+}
+
+bool AccessibilityRenderObject::isMenuButton() const
+{
+ return roleValue() == MenuButtonRole;
+}
+
+bool AccessibilityRenderObject::isMenuItem() const
+{
+ return roleValue() == MenuItemRole;
+}
+
+bool AccessibilityRenderObject::isPressed() const
+{
+ ASSERT(m_renderer);
+ if (roleValue() != ButtonRole)
+ return false;
+
+ Node* node = m_renderer->node();
+ if (!node)
+ return false;
+
+ // If this is an ARIA button, check the aria-pressed attribute rather than node()->active()
+ if (ariaRoleAttribute() == ButtonRole) {
+ if (equalIgnoringCase(getAttribute(aria_pressedAttr).string(), "true"))
+ return true;
+ return false;
+ }
+
+ return node->active();
+}
+
+bool AccessibilityRenderObject::isIndeterminate() const
+{
+ ASSERT(m_renderer);
+ return m_renderer->node() && m_renderer->node()->isIndeterminate();
+}
+
+bool AccessibilityRenderObject::isChecked() const
+{
+ ASSERT(m_renderer);
+ return m_renderer->node() && m_renderer->node()->isChecked();
+}
+
+bool AccessibilityRenderObject::isHovered() const
+{
+ ASSERT(m_renderer);
+ return m_renderer->node() && m_renderer->node()->hovered();
+}
+
+bool AccessibilityRenderObject::isMultiSelect() const
+{
+ ASSERT(m_renderer);
+ if (!m_renderer->isListBox())
+ return false;
+ return m_renderer->element() && static_cast<HTMLSelectElement*>(m_renderer->element())->multiple();
+}
+
+bool AccessibilityRenderObject::isReadOnly() const
+{
+ ASSERT(m_renderer);
+
+ if (isWebArea()) {
+ Document* document = m_renderer->document();
+ if (!document)
+ return true;
+
+ Frame* frame = document->frame();
+ if (!frame)
+ return true;
+
+ return !frame->isContentEditable();
+ }
+
+ return !m_renderer->node() || !m_renderer->node()->isContentEditable();
+}
+
+bool AccessibilityRenderObject::isOffScreen() const
+{
+ ASSERT(m_renderer);
+ IntRect contentRect = m_renderer->absoluteClippedOverflowRect();
+ FrameView* view = m_renderer->document()->frame()->view();
+ FloatRect viewRect = view->visibleContentRect();
+ viewRect.intersect(contentRect);
+ return viewRect.isEmpty();
+}
+
+int AccessibilityRenderObject::headingLevel(Node* node)
+{
+ // headings can be in block flow and non-block flow
+ if (!node)
+ return 0;
+
+ if (RenderObject* renderer = node->renderer()) {
+ AccessibilityObject* axObjectForNode = node->document()->axObjectCache()->get(renderer);
+ if (axObjectForNode->ariaRoleAttribute() == HeadingRole) {
+ if (!node->isElementNode())
+ return 0;
+ Element* element = static_cast<Element*>(node);
+ return element->getAttribute(aria_levelAttr).toInt();
+ }
+ }
+
+
+ if (node->hasTagName(h1Tag))
+ return 1;
+
+ if (node->hasTagName(h2Tag))
+ return 2;
+
+ if (node->hasTagName(h3Tag))
+ return 3;
+
+ if (node->hasTagName(h4Tag))
+ return 4;
+
+ if (node->hasTagName(h5Tag))
+ return 5;
+
+ if (node->hasTagName(h6Tag))
+ return 6;
+
+ return 0;
+}
+
+bool AccessibilityRenderObject::isHeading() const
+{
+ return roleValue() == HeadingRole;
+}
+
+bool AccessibilityRenderObject::isLink() const
+{
+ return roleValue() == WebCoreLinkRole;
+}
+
+bool AccessibilityRenderObject::isControl() const
+{
+ if (!m_renderer)
+ return false;
+
+ Node* node = m_renderer->element();
+ return node && (node->isControl() || AccessibilityObject::isARIAControl(ariaRoleAttribute()));
+}
+
+bool AccessibilityRenderObject::isFieldset() const
+{
+ if (!m_renderer)
+ return false;
+
+ return m_renderer->isFieldset();
+}
+
+const AtomicString& AccessibilityRenderObject::getAttribute(const QualifiedName& attribute) const
+{
+ Node* node = m_renderer->element();
+ if (!node)
+ return nullAtom;
+
+ if (!node->isElementNode())
+ return nullAtom;
+
+ Element* element = static_cast<Element*>(node);
+ return element->getAttribute(attribute);
+}
+
+Element* AccessibilityRenderObject::anchorElement() const
+{
+ if (!m_renderer)
+ return 0;
+
+ AXObjectCache* cache = axObjectCache();
+ RenderObject* currRenderer;
+
+ // Search up the render tree for a RenderObject with a DOM node. Defer to an earlier continuation, though.
+ for (currRenderer = m_renderer; currRenderer && !currRenderer->element(); currRenderer = currRenderer->parent()) {
+ if (currRenderer->continuation())
+ return cache->get(currRenderer->continuation())->anchorElement();
+ }
+
+ // bail if none found
+ if (!currRenderer)
+ return 0;
+
+ // search up the DOM tree for an anchor element
+ // NOTE: this assumes that any non-image with an anchor is an HTMLAnchorElement
+ Node* node = currRenderer->node();
+ for ( ; node; node = node->parentNode()) {
+ if (node->hasTagName(aTag) || (node->renderer() && cache->get(node->renderer())->isAnchor()))
+ return static_cast<Element*>(node);
+ }
+
+ return 0;
+}
+
+Element* AccessibilityRenderObject::actionElement() const
+{
+ if (m_renderer->element() && m_renderer->element()->hasTagName(inputTag)) {
+ HTMLInputElement* input = static_cast<HTMLInputElement*>(m_renderer->element());
+ if (!input->disabled() && (isCheckboxOrRadio() || input->isTextButton()))
+ return input;
+ }
+
+ if (isFileUploadButton())
+ return static_cast<Element*>(m_renderer->element());
+
+ if (AccessibilityObject::isARIAInput(ariaRoleAttribute()))
+ return static_cast<Element*>(m_renderer->element());
+
+ if (isImageButton())
+ return static_cast<Element*>(m_renderer->element());
+
+ if (m_renderer->isMenuList())
+ return static_cast<RenderMenuList*>(m_renderer)->selectElement();
+
+ Element* elt = anchorElement();
+ if (!elt)
+ elt = mouseButtonListener();
+ return elt;
+}
+
+Element* AccessibilityRenderObject::mouseButtonListener() const
+{
+ Node* node = m_renderer->element();
+ if (!node)
+ return 0;
+ if (!node->isEventTargetNode())
+ return 0;
+
+ // FIXME: Do the continuation search like anchorElement does
+ for (EventTargetNode* elt = static_cast<EventTargetNode*>(node); elt; elt = static_cast<EventTargetNode*>(elt->parentNode())) {
+ if (elt->inlineEventListenerForType(eventNames().clickEvent) || elt->inlineEventListenerForType(eventNames().mousedownEvent) || elt->inlineEventListenerForType(eventNames().mouseupEvent))
+ return static_cast<Element*>(elt);
+ }
+
+ return 0;
+}
+
+static Element* siblingWithAriaRole(String role, Node* node)
+{
+ Node* sibling = node->parent()->firstChild();
+ while (sibling) {
+ if (sibling->isElementNode()) {
+ String siblingAriaRole = static_cast<Element*>(sibling)->getAttribute(roleAttr).string();
+ if (equalIgnoringCase(siblingAriaRole, role))
+ return static_cast<Element*>(sibling);
+ }
+ sibling = sibling->nextSibling();
+ }
+
+ return 0;
+}
+
+Element* AccessibilityRenderObject::menuElementForMenuButton() const
+{
+ if (ariaRoleAttribute() != MenuButtonRole)
+ return 0;
+
+ return siblingWithAriaRole("menu", renderer()->node());
+}
+
+AccessibilityObject* AccessibilityRenderObject::menuForMenuButton() const
+{
+ Element* menu = menuElementForMenuButton();
+ if (menu && menu->renderer())
+ return m_renderer->document()->axObjectCache()->get(menu->renderer());
+ return 0;
+}
+
+Element* AccessibilityRenderObject::menuItemElementForMenu() const
+{
+ if (ariaRoleAttribute() != MenuRole)
+ return 0;
+
+ return siblingWithAriaRole("menuitem", renderer()->node());
+}
+
+AccessibilityObject* AccessibilityRenderObject::menuButtonForMenu() const
+{
+ Element* menuItem = menuItemElementForMenu();
+
+ if (menuItem && menuItem->renderer()) {
+ // ARIA just has generic menu items. AppKit needs to know if this is a top level items like MenuBarButton or MenuBarItem
+ AccessibilityObject* menuItemAX = m_renderer->document()->axObjectCache()->get(menuItem->renderer());
+ if (menuItemAX->isMenuButton())
+ return menuItemAX;
+ }
+ return 0;
+}
+
+String AccessibilityRenderObject::helpText() const
+{
+ if (!m_renderer)
+ return String();
+
+ for (RenderObject* curr = m_renderer; curr; curr = curr->parent()) {
+ if (curr->element() && curr->element()->isHTMLElement()) {
+ const AtomicString& summary = static_cast<Element*>(curr->element())->getAttribute(summaryAttr);
+ if (!summary.isEmpty())
+ return summary;
+ const AtomicString& title = static_cast<Element*>(curr->element())->getAttribute(titleAttr);
+ if (!title.isEmpty())
+ return title;
+ }
+ }
+
+ return String();
+}
+
+String AccessibilityRenderObject::textUnderElement() const
+{
+ if (!m_renderer)
+ return String();
+
+ if (isFileUploadButton()) {
+ RenderFileUploadControl* uploadControl = static_cast<RenderFileUploadControl*>(m_renderer);
+ return uploadControl->buttonValue();
+ }
+
+ Node* node = m_renderer->element();
+ if (node) {
+ if (Frame* frame = node->document()->frame()) {
+ // catch stale WebCoreAXObject (see <rdar://problem/3960196>)
+ if (frame->document() != node->document())
+ return String();
+ return plainText(rangeOfContents(node).get());
+ }
+ }
+
+ // return the null string for anonymous text because it is non-trivial to get
+ // the actual text and, so far, that is not needed
+ return String();
+}
+
+bool AccessibilityRenderObject::hasIntValue() const
+{
+ if (isHeading())
+ return true;
+
+ if (m_renderer->element() && isCheckboxOrRadio())
+ return true;
+
+ return false;
+}
+
+int AccessibilityRenderObject::intValue() const
+{
+ if (!m_renderer || isPasswordField())
+ return 0;
+
+ if (isHeading())
+ return headingLevel(m_renderer->element());
+
+ Node* node = m_renderer->element();
+ if (!node || !isCheckboxOrRadio())
+ return 0;
+
+ // If this is an ARIA checkbox or radio, check the aria-checked attribute rather than node()->checked()
+ AccessibilityRole ariaRole = ariaRoleAttribute();
+ if (ariaRole == RadioButtonRole || ariaRole == CheckBoxRole) {
+ if (equalIgnoringCase(getAttribute(aria_checkedAttr).string(), "true"))
+ return true;
+ return false;
+ }
+
+ return static_cast<HTMLInputElement*>(node)->checked();
+}
+
+float AccessibilityRenderObject::valueForRange() const
+{
+ if (!isProgressIndicator() && !isSlider())
+ return 0.0f;
+
+ return getAttribute(aria_valuenowAttr).toFloat();
+}
+
+float AccessibilityRenderObject::maxValueForRange() const
+{
+ if (!isProgressIndicator() && !isSlider())
+ return 0.0f;
+
+ return getAttribute(aria_valuemaxAttr).toFloat();
+}
+
+float AccessibilityRenderObject::minValueForRange() const
+{
+ if (!isProgressIndicator() && !isSlider())
+ return 0.0f;
+
+ return getAttribute(aria_valueminAttr).toFloat();
+}
+
+String AccessibilityRenderObject::stringValue() const
+{
+ if (!m_renderer || isPasswordField())
+ return String();
+
+ if (m_renderer->isText())
+ return textUnderElement();
+
+ if (m_renderer->isMenuList())
+ return static_cast<RenderMenuList*>(m_renderer)->text();
+
+ if (m_renderer->isListMarker())
+ return static_cast<RenderListMarker*>(m_renderer)->text();
+
+ if (isWebArea()) {
+ if (m_renderer->document()->frame())
+ return String();
+
+ // FIXME: should use startOfDocument and endOfDocument (or rangeForDocument?) here
+ VisiblePosition startVisiblePosition = m_renderer->positionForCoordinates(0, 0);
+ VisiblePosition endVisiblePosition = m_renderer->positionForCoordinates(INT_MAX, INT_MAX);
+ if (startVisiblePosition.isNull() || endVisiblePosition.isNull())
+ return String();
+
+ return plainText(makeRange(startVisiblePosition, endVisiblePosition).get());
+ }
+
+ if (isTextControl())
+ return text();
+
+ if (isFileUploadButton()) {
+ RenderFileUploadControl* uploadControl = static_cast<RenderFileUploadControl*>(m_renderer);
+ return uploadControl->fileTextValue();
+ }
+
+ // FIXME: We might need to implement a value here for more types
+ // FIXME: It would be better not to advertise a value at all for the types for which we don't implement one;
+ // this would require subclassing or making accessibilityAttributeNames do something other than return a
+ // single static array.
+ return String();
+}
+
+// This function implements the ARIA accessible name as described by the Mozilla
+// ARIA Implementer's Guide.
+static String accessibleNameForNode(Node* node)
+{
+ if (node->isTextNode())
+ return static_cast<Text*>(node)->data();
+
+ if (node->hasTagName(inputTag))
+ return static_cast<HTMLInputElement*>(node)->value();
+
+ if (node->isHTMLElement()) {
+ const AtomicString& alt = static_cast<HTMLElement*>(node)->getAttribute(altAttr);
+ if (!alt.isEmpty())
+ return alt;
+ }
+
+ return String();
+}
+
+String AccessibilityRenderObject::ariaAccessiblityName(const String& s) const
+{
+ Document* document = m_renderer->document();
+ if (!document)
+ return String();
+
+ String idList = s;
+ idList.replace('\n', ' ');
+ Vector<String> idVector;
+ idList.split(' ', idVector);
+
+ Vector<UChar> ariaLabel;
+ unsigned size = idVector.size();
+ for (unsigned i = 0; i < size; ++i) {
+ String idName = idVector[i];
+ Element* idElement = document->getElementById(idName);
+ if (idElement) {
+ String nameFragment = accessibleNameForNode(idElement);
+ ariaLabel.append(nameFragment.characters(), nameFragment.length());
+ for (Node* n = idElement->firstChild(); n; n = n->traverseNextNode(idElement->nextSibling())) {
+ nameFragment = accessibleNameForNode(n);
+ ariaLabel.append(nameFragment.characters(), nameFragment.length());
+ }
+ ariaLabel.append(' ');
+ }
+ }
+ return String::adopt(ariaLabel);
+}
+
+String AccessibilityRenderObject::ariaLabeledByAttribute() const
+{
+ Node* node = m_renderer->node();
+ if (!node)
+ return String();
+
+ if (!node->isElementNode())
+ return String();
+
+ // The ARIA spec uses the British spelling: "labelled." It seems prudent to support the American
+ // spelling ("labeled") as well.
+ String idList = getAttribute(aria_labeledbyAttr).string();
+ if (idList.isEmpty()) {
+ idList = getAttribute(aria_labelledbyAttr).string();
+ if (idList.isEmpty())
+ return String();
+ }
+
+ return ariaAccessiblityName(idList);
+}
+
+static HTMLLabelElement* labelForElement(Element* element)
+{
+ RefPtr<NodeList> list = element->document()->getElementsByTagName("label");
+ unsigned len = list->length();
+ for (unsigned i = 0; i < len; i++) {
+ if (list->item(i)->hasTagName(labelTag)) {
+ HTMLLabelElement* label = static_cast<HTMLLabelElement*>(list->item(i));
+ if (label->correspondingControl() == element)
+ return label;
+ }
+ }
+
+ return 0;
+}
+
+HTMLLabelElement* AccessibilityRenderObject::labelElementContainer() const
+{
+ if (!m_renderer)
+ return false;
+
+ // the control element should not be considered part of the label
+ if (isControl())
+ return false;
+
+ // find if this has a parent that is a label
+ for (Node* parentNode = m_renderer->element(); parentNode; parentNode = parentNode->parentNode()) {
+ if (parentNode->hasTagName(labelTag))
+ return static_cast<HTMLLabelElement*>(parentNode);
+ }
+
+ return 0;
+}
+
+String AccessibilityRenderObject::title() const
+{
+ AccessibilityRole ariaRole = ariaRoleAttribute();
+
+ if (!m_renderer)
+ return String();
+
+ Node* node = m_renderer->element();
+ if (!node)
+ return String();
+
+ String ariaLabel = ariaLabeledByAttribute();
+ if (!ariaLabel.isEmpty())
+ return ariaLabel;
+
+ const AtomicString& title = getAttribute(titleAttr);
+ if (!title.isEmpty())
+ return title;
+
+ bool isInputTag = node->hasTagName(inputTag);
+ if (isInputTag) {
+ HTMLInputElement* input = static_cast<HTMLInputElement*>(node);
+ if (input->isTextButton())
+ return input->value();
+ }
+
+ if (isInputTag || AccessibilityObject::isARIAInput(ariaRole) || isControl()) {
+ HTMLLabelElement* label = labelForElement(static_cast<Element*>(node));
+ if (label)
+ return label->innerText();
+ }
+
+ if (roleValue() == ButtonRole
+ || ariaRole == ListBoxOptionRole
+ || ariaRole == MenuItemRole
+ || ariaRole == MenuButtonRole
+ || isHeading())
+ return textUnderElement();
+
+ if (isLink())
+ return textUnderElement();
+
+ return String();
+}
+
+String AccessibilityRenderObject::ariaDescribedByAttribute() const
+{
+ String idList = getAttribute(aria_describedbyAttr).string();
+ if (idList.isEmpty())
+ return String();
+
+ return ariaAccessiblityName(idList);
+}
+
+String AccessibilityRenderObject::accessibilityDescription() const
+{
+ if (!m_renderer)
+ return String();
+
+ String ariaDescription = ariaDescribedByAttribute();
+ if (!ariaDescription.isEmpty())
+ return ariaDescription;
+
+ if (isImage()) {
+ if (m_renderer->element() && m_renderer->element()->isHTMLElement()) {
+ const AtomicString& alt = static_cast<HTMLElement*>(m_renderer->element())->getAttribute(altAttr);
+ if (alt.isEmpty())
+ return String();
+ return alt;
+ }
+ }
+
+ if (isWebArea()) {
+ Document *document = m_renderer->document();
+ Node* owner = document->ownerElement();
+ if (owner) {
+ if (owner->hasTagName(frameTag) || owner->hasTagName(iframeTag)) {
+ const AtomicString& title = static_cast<HTMLFrameElementBase*>(owner)->getAttribute(titleAttr);
+ if (!title.isEmpty())
+ return title;
+ return static_cast<HTMLFrameElementBase*>(owner)->name();
+ }
+ if (owner->isHTMLElement())
+ return static_cast<HTMLElement*>(owner)->getAttribute(nameAttr);
+ }
+ owner = document->body();
+ if (owner && owner->isHTMLElement())
+ return static_cast<HTMLElement*>(owner)->getAttribute(nameAttr);
+ }
+
+ if (roleValue() == DefinitionListTermRole)
+ return AXDefinitionListTermText();
+ if (roleValue() == DefinitionListDefinitionRole)
+ return AXDefinitionListDefinitionText();
+
+ return String();
+}
+
+IntRect AccessibilityRenderObject::boundingBoxRect() const
+{
+ IntRect rect;
+ RenderObject* obj = m_renderer;
+
+ if (!obj)
+ return IntRect();
+
+ if (obj->isInlineContinuation())
+ obj = obj->element()->renderer();
+
+ // FIXME: This doesn't work correctly with transforms.
+ Vector<IntRect> rects;
+ int x, y;
+ obj->absolutePosition(x, y);
+ obj->absoluteRects(rects, x, y);
+ const size_t n = rects.size();
+ for (size_t i = 0; i < n; ++i) {
+ IntRect r = rects[i];
+ if (!r.isEmpty()) {
+ if (obj->style()->hasAppearance())
+ theme()->adjustRepaintRect(obj, r);
+ rect.unite(r);
+ }
+ }
+ return rect;
+}
+
+IntRect AccessibilityRenderObject::checkboxOrRadioRect() const
+{
+ if (!m_renderer)
+ return IntRect();
+
+ HTMLLabelElement* label = labelForElement(static_cast<Element*>(m_renderer->element()));
+ if (!label || !label->renderer())
+ return boundingBoxRect();
+
+ IntRect labelRect = axObjectCache()->get(label->renderer())->elementRect();
+ labelRect.unite(boundingBoxRect());
+ return labelRect;
+}
+
+IntRect AccessibilityRenderObject::elementRect() const
+{
+ // a checkbox or radio button should encompass its label
+ if (isCheckboxOrRadio())
+ return checkboxOrRadioRect();
+
+ return boundingBoxRect();
+}
+
+IntSize AccessibilityRenderObject::size() const
+{
+ IntRect rect = elementRect();
+ return rect.size();
+}
+
+AccessibilityObject* AccessibilityRenderObject::internalLinkElement() const
+{
+ Element* element = anchorElement();
+ if (!element)
+ return 0;
+
+ // Right now, we do not support ARIA links as internal link elements
+ if (!element->hasTagName(aTag))
+ return 0;
+ HTMLAnchorElement* anchor = static_cast<HTMLAnchorElement*>(element);
+
+ KURL linkURL = anchor->href();
+ String ref = linkURL.ref();
+ if (ref.isEmpty())
+ return 0;
+
+ // check if URL is the same as current URL
+ linkURL.removeRef();
+ if (m_renderer->document()->url() != linkURL)
+ return 0;
+
+ Node* linkedNode = m_renderer->document()->getElementById(ref);
+ if (!linkedNode) {
+ linkedNode = m_renderer->document()->anchors()->namedItem(ref, !m_renderer->document()->inCompatMode());
+ if (!linkedNode)
+ return 0;
+ }
+
+ // the element we find may not be accessible, keep searching until we find a good one
+ AccessibilityObject* linkedAXElement = m_renderer->document()->axObjectCache()->get(linkedNode->renderer());
+ while (linkedAXElement && linkedAXElement->accessibilityIsIgnored()) {
+ linkedNode = linkedNode->traverseNextNode();
+
+ while (linkedNode && !linkedNode->renderer())
+ linkedNode = linkedNode->traverseNextSibling();
+
+ if (!linkedNode)
+ return 0;
+ linkedAXElement = m_renderer->document()->axObjectCache()->get(linkedNode->renderer());
+ }
+
+ return linkedAXElement;
+}
+
+void AccessibilityRenderObject::addRadioButtonGroupMembers(AccessibilityChildrenVector& linkedUIElements) const
+{
+ if (!m_renderer || roleValue() != RadioButtonRole)
+ return;
+
+ Node* node = m_renderer->node();
+ if (!node || !node->hasTagName(inputTag))
+ return;
+
+ HTMLInputElement* input = static_cast<HTMLInputElement*>(node);
+ // if there's a form, then this is easy
+ if (input->form()) {
+ Vector<RefPtr<Node> > formElements;
+ input->form()->getNamedElements(input->name(), formElements);
+
+ unsigned len = formElements.size();
+ for (unsigned i = 0; i < len; ++i) {
+ Node* associateElement = formElements[i].get();
+ if (AccessibilityObject* object = m_renderer->document()->axObjectCache()->get(associateElement->renderer()))
+ linkedUIElements.append(object);
+ }
+ } else {
+ RefPtr<NodeList> list = node->document()->getElementsByTagName("input");
+ unsigned len = list->length();
+ for (unsigned i = 0; i < len; ++i) {
+ if (list->item(i)->hasTagName(inputTag)) {
+ HTMLInputElement* associateElement = static_cast<HTMLInputElement*>(list->item(i));
+ if (associateElement->isRadioButton() && associateElement->name() == input->name()) {
+ if (AccessibilityObject* object = m_renderer->document()->axObjectCache()->get(associateElement->renderer()))
+ linkedUIElements.append(object);
+ }
+ }
+ }
+ }
+}
+
+// linked ui elements could be all the related radio buttons in a group
+// or an internal anchor connection
+void AccessibilityRenderObject::linkedUIElements(AccessibilityChildrenVector& linkedUIElements) const
+{
+ if (isAnchor()) {
+ AccessibilityObject* linkedAXElement = internalLinkElement();
+ if (linkedAXElement)
+ linkedUIElements.append(linkedAXElement);
+ }
+
+ if (roleValue() == RadioButtonRole)
+ addRadioButtonGroupMembers(linkedUIElements);
+}
+
+AccessibilityObject* AccessibilityRenderObject::titleUIElement() const
+{
+ if (!m_renderer)
+ return 0;
+
+ // if isFieldset is true, the renderer is guaranteed to be a RenderFieldset
+ if (isFieldset())
+ return axObjectCache()->get(static_cast<RenderFieldset*>(m_renderer)->findLegend());
+
+ // checkbox and radio hide their labels. Only controls get titleUIElements for now
+ if (isCheckboxOrRadio() || !isControl())
+ return 0;
+
+ Node* element = m_renderer->element();
+ HTMLLabelElement* label = labelForElement(static_cast<Element*>(element));
+ if (label && label->renderer())
+ return axObjectCache()->get(label->renderer());
+
+ return 0;
+}
+
+bool AccessibilityRenderObject::accessibilityIsIgnored() const
+{
+ // ignore invisible element
+ if (!m_renderer || m_renderer->style()->visibility() != VISIBLE)
+ return true;
+
+ if (isPresentationalChildOfAriaRole())
+ return true;
+
+ // ignore popup menu items because AppKit does
+ for (RenderObject* parent = m_renderer->parent(); parent; parent = parent->parent()) {
+ if (parent->isMenuList())
+ return true;
+ }
+
+ // find out if this element is inside of a label element.
+ // if so, it may be ignored because it's the label for a checkbox or radio button
+ HTMLLabelElement* labelElement = labelElementContainer();
+ if (labelElement) {
+ HTMLElement* correspondingControl = labelElement->correspondingControl();
+ if (correspondingControl && correspondingControl->renderer()) {
+ AccessibilityObject* controlObject = axObjectCache()->get(correspondingControl->renderer());
+ if (controlObject->isCheckboxOrRadio())
+ return true;
+ }
+ }
+
+ AccessibilityRole ariaRole = ariaRoleAttribute();
+ if (ariaRole == TextAreaRole || ariaRole == StaticTextRole) {
+ String ariaText = text();
+ return ariaText.isNull() || ariaText.isEmpty();
+ }
+
+ // NOTE: BRs always have text boxes now, so the text box check here can be removed
+ if (m_renderer->isText()) {
+ // static text beneath MenuItems and MenuButtons are just reported along with the menu item, so it's ignored on an individual level
+ if (parentObjectUnignored()->ariaRoleAttribute() == MenuItemRole ||
+ parentObjectUnignored()->ariaRoleAttribute() == MenuButtonRole)
+ return true;
+ return m_renderer->isBR() || !static_cast<RenderText*>(m_renderer)->firstTextBox();
+ }
+
+ if (isHeading())
+ return false;
+
+ if (isLink())
+ return false;
+
+ // all controls are accessible
+ if (isControl())
+ return false;
+
+ // don't ignore labels, because they serve as TitleUIElements
+ Node* node = m_renderer->element();
+ if (node && node->hasTagName(labelTag))
+ return false;
+
+ if (m_renderer->isBlockFlow() && m_renderer->childrenInline())
+ return !static_cast<RenderBlock*>(m_renderer)->firstLineBox() && !mouseButtonListener();
+
+ // ignore images seemingly used as spacers
+ if (isImage()) {
+ if (node && node->isElementNode()) {
+ Element* elt = static_cast<Element*>(node);
+ const AtomicString& alt = elt->getAttribute(altAttr);
+ // don't ignore an image that has an alt tag
+ if (!alt.isEmpty())
+ return false;
+ // informal standard is to ignore images with zero-length alt strings
+ if (!alt.isNull())
+ return true;
+ }
+
+ // check for one-dimensional image
+ if (m_renderer->height() <= 1 || m_renderer->width() <= 1)
+ return true;
+
+ // check whether rendered image was stretched from one-dimensional file image
+ if (isNativeImage()) {
+ RenderImage* image = static_cast<RenderImage*>(m_renderer);
+ if (image->cachedImage()) {
+ IntSize imageSize = image->cachedImage()->imageSize(image->view()->zoomFactor());
+ return imageSize.height() <= 1 || imageSize.width() <= 1;
+ }
+ }
+ return false;
+ }
+
+ if (ariaRole != UnknownRole)
+ return false;
+
+ // make a platform-specific decision
+ if (isAttachment())
+ return accessibilityIgnoreAttachment();
+
+ return !m_renderer->isListMarker() && !isWebArea();
+}
+
+bool AccessibilityRenderObject::isLoaded() const
+{
+ return !m_renderer->document()->tokenizer();
+}
+
+int AccessibilityRenderObject::layoutCount() const
+{
+ if (!m_renderer->isRenderView())
+ return 0;
+ return static_cast<RenderView*>(m_renderer)->frameView()->layoutCount();
+}
+
+String AccessibilityRenderObject::text() const
+{
+ if (!isTextControl() || isPasswordField())
+ return String();
+
+ if (isNativeTextControl())
+ return static_cast<RenderTextControl*>(m_renderer)->text();
+
+ Node* node = m_renderer->element();
+ if (!node)
+ return String();
+ if (!node->isElementNode())
+ return String();
+
+ return static_cast<Element*>(node)->innerText();
+}
+
+int AccessibilityRenderObject::textLength() const
+{
+ ASSERT(isTextControl());
+
+ if (isPasswordField())
+ return -1; // need to return something distinct from 0
+
+ return text().length();
+}
+
+PassRefPtr<Range> AccessibilityRenderObject::ariaSelectedTextDOMRange() const
+{
+ Node* node = m_renderer->element();
+ if (!node)
+ return 0;
+
+ RefPtr<Range> currentSelectionRange = selection().toRange();
+ if (!currentSelectionRange)
+ return 0;
+
+ ExceptionCode ec = 0;
+ if (!currentSelectionRange->intersectsNode(node, ec))
+ return Range::create(currentSelectionRange->ownerDocument());
+
+ RefPtr<Range> ariaRange = rangeOfContents(node);
+ Position startPosition, endPosition;
+
+ // Find intersection of currentSelectionRange and ariaRange
+ if (ariaRange->startOffset() > currentSelectionRange->startOffset())
+ startPosition = ariaRange->startPosition();
+ else
+ startPosition = currentSelectionRange->startPosition();
+
+ if (ariaRange->endOffset() < currentSelectionRange->endOffset())
+ endPosition = ariaRange->endPosition();
+ else
+ endPosition = currentSelectionRange->endPosition();
+
+ return Range::create(ariaRange->ownerDocument(), startPosition, endPosition);
+}
+
+String AccessibilityRenderObject::selectedText() const
+{
+ ASSERT(isTextControl());
+
+ if (isPasswordField())
+ return String(); // need to return something distinct from empty string
+
+ if (isNativeTextControl()) {
+ RenderTextControl* textControl = static_cast<RenderTextControl*>(m_renderer);
+ return textControl->text().substring(textControl->selectionStart(), textControl->selectionEnd() - textControl->selectionStart());
+ }
+
+ if (ariaRoleAttribute() == UnknownRole)
+ return String();
+
+ RefPtr<Range> ariaRange = ariaSelectedTextDOMRange();
+ if (!ariaRange)
+ return String();
+ return ariaRange->text();
+}
+
+const AtomicString& AccessibilityRenderObject::accessKey() const
+{
+ Node* node = m_renderer->element();
+ if (!node)
+ return nullAtom;
+ if (!node->isElementNode())
+ return nullAtom;
+ return static_cast<Element*>(node)->getAttribute(accesskeyAttr);
+}
+
+Selection AccessibilityRenderObject::selection() const
+{
+ return m_renderer->document()->frame()->selection()->selection();
+}
+
+PlainTextRange AccessibilityRenderObject::selectedTextRange() const
+{
+ ASSERT(isTextControl());
+
+ if (isPasswordField())
+ return PlainTextRange();
+
+ AccessibilityRole ariaRole = ariaRoleAttribute();
+ if (isNativeTextControl() && ariaRole == UnknownRole) {
+ RenderTextControl* textControl = static_cast<RenderTextControl*>(m_renderer);
+ return PlainTextRange(textControl->selectionStart(), textControl->selectionEnd() - textControl->selectionStart());
+ }
+
+ if (ariaRole == UnknownRole)
+ return PlainTextRange();
+
+ RefPtr<Range> ariaRange = ariaSelectedTextDOMRange();
+ if (!ariaRange)
+ return PlainTextRange();
+ return PlainTextRange(ariaRange->startOffset(), ariaRange->endOffset());
+}
+
+void AccessibilityRenderObject::setSelectedTextRange(const PlainTextRange& range)
+{
+ if (isNativeTextControl()) {
+ RenderTextControl* textControl = static_cast<RenderTextControl*>(m_renderer);
+ textControl->setSelectionRange(range.start, range.start + range.length);
+ return;
+ }
+
+ Document* document = m_renderer->document();
+ if (!document)
+ return;
+ Frame* frame = document->frame();
+ if (!frame)
+ return;
+ Node* node = m_renderer->element();
+ frame->selection()->setSelection(Selection(Position(node, range.start),
+ Position(node, range.start + range.length), DOWNSTREAM));
+}
+
+KURL AccessibilityRenderObject::url() const
+{
+ if (isAnchor() && m_renderer->element()->hasTagName(aTag)) {
+ if (HTMLAnchorElement* anchor = static_cast<HTMLAnchorElement*>(anchorElement()))
+ return anchor->href();
+ }
+
+ if (isWebArea())
+ return m_renderer->document()->url();
+
+ if (isImage() && m_renderer->element() && m_renderer->element()->hasTagName(imgTag))
+ return static_cast<HTMLImageElement*>(m_renderer->element())->src();
+
+ return KURL();
+}
+
+bool AccessibilityRenderObject::isVisited() const
+{
+ return m_renderer->style()->pseudoState() == PseudoVisited;
+}
+
+bool AccessibilityRenderObject::isSelected() const
+{
+ if (!m_renderer)
+ return false;
+
+ Node* node = m_renderer->node();
+ if (!node)
+ return false;
+
+ return false;
+}
+
+bool AccessibilityRenderObject::isFocused() const
+{
+ if (!m_renderer)
+ return false;
+
+ Document* document = m_renderer->document();
+ if (!document)
+ return false;
+
+ Node* focusedNode = document->focusedNode();
+ if (!focusedNode)
+ return false;
+
+ // A web area is represented by the Document node in the DOM tree, which isn't focusable.
+ // Check instead if the frame's selection controller is focused
+ if (focusedNode == m_renderer->element() ||
+ (roleValue() == WebAreaRole && document->frame()->selection()->isFocusedAndActive()))
+ return true;
+
+ return false;
+}
+
+void AccessibilityRenderObject::setFocused(bool on)
+{
+ if (!canSetFocusAttribute())
+ return;
+
+ if (!on)
+ m_renderer->document()->setFocusedNode(0);
+ else {
+ if (m_renderer->element()->isElementNode())
+ static_cast<Element*>(m_renderer->element())->focus();
+ else
+ m_renderer->document()->setFocusedNode(m_renderer->element());
+ }
+}
+
+void AccessibilityRenderObject::setValue(const String& string)
+{
+ // FIXME: Do we want to do anything here for ARIA textboxes?
+ if (m_renderer->isTextField()) {
+ HTMLInputElement* input = static_cast<HTMLInputElement*>(m_renderer->element());
+ input->setValue(string);
+ } else if (m_renderer->isTextArea()) {
+ HTMLTextAreaElement* textArea = static_cast<HTMLTextAreaElement*>(m_renderer->element());
+ textArea->setValue(string);
+ }
+}
+
+bool AccessibilityRenderObject::isEnabled() const
+{
+ return m_renderer->element() ? m_renderer->element()->isEnabled() : true;
+}
+
+RenderObject* AccessibilityRenderObject::topRenderer() const
+{
+ return m_renderer->document()->topDocument()->renderer();
+}
+
+Document* AccessibilityRenderObject::document() const
+{
+ return m_renderer->document();
+}
+
+FrameView* AccessibilityRenderObject::topDocumentFrameView() const
+{
+ return topRenderer()->view()->frameView();
+}
+
+Widget* AccessibilityRenderObject::widget() const
+{
+ if (!m_renderer->isWidget())
+ return 0;
+
+ return static_cast<RenderWidget*>(m_renderer)->widget();
+}
+
+AXObjectCache* AccessibilityRenderObject::axObjectCache() const
+{
+ return m_renderer->document()->axObjectCache();
+}
+
+AccessibilityObject* AccessibilityRenderObject::accessibilityParentForImageMap(HTMLMapElement* map) const
+{
+ // find an image that is using this map
+ if (!m_renderer || !map)
+ return 0;
+
+ RefPtr<HTMLCollection> coll = m_renderer->document()->images();
+ for (Node* curr = coll->firstItem(); curr; curr = coll->nextItem()) {
+ RenderObject* obj = curr->renderer();
+ if (!obj || !curr->hasTagName(imgTag))
+ continue;
+
+ // The HTMLImageElement's useMap() value includes the '#' symbol at the beginning,
+ // which has to be stripped off
+ if (static_cast<HTMLImageElement*>(curr)->useMap().substring(1) == map->getName())
+ return axObjectCache()->get(obj);
+ }
+
+ return 0;
+}
+
+void AccessibilityRenderObject::getDocumentLinks(AccessibilityChildrenVector& result)
+{
+ Document* document = m_renderer->document();
+ RefPtr<HTMLCollection> coll = document->links();
+ Node* curr = coll->firstItem();
+ while (curr) {
+ RenderObject* obj = curr->renderer();
+ if (obj) {
+ RefPtr<AccessibilityObject> axobj = document->axObjectCache()->get(obj);
+ ASSERT(axobj);
+ ASSERT(axobj->roleValue() == WebCoreLinkRole);
+ if (!axobj->accessibilityIsIgnored())
+ result.append(axobj);
+ } else {
+ Node* parent = curr->parent();
+ if (parent && curr->hasTagName(areaTag) && parent->hasTagName(mapTag)) {
+ AccessibilityImageMapLink* areaObject = static_cast<AccessibilityImageMapLink*>(axObjectCache()->get(ImageMapLinkRole));
+ areaObject->setHTMLAreaElement(static_cast<HTMLAreaElement*>(curr));
+ areaObject->setHTMLMapElement(static_cast<HTMLMapElement*>(parent));
+ areaObject->setParent(accessibilityParentForImageMap(static_cast<HTMLMapElement*>(parent)));
+
+ result.append(areaObject);
+ }
+ }
+ curr = coll->nextItem();
+ }
+}
+
+FrameView* AccessibilityRenderObject::documentFrameView() const
+{
+ if (!m_renderer || !m_renderer->document())
+ return 0;
+
+ // this is the RenderObject's Document's Frame's FrameView
+ return m_renderer->document()->view();
+}
+
+Widget* AccessibilityRenderObject::widgetForAttachmentView() const
+{
+ if (!isAttachment())
+ return 0;
+ return static_cast<RenderWidget*>(m_renderer)->widget();
+}
+
+FrameView* AccessibilityRenderObject::frameViewIfRenderView() const
+{
+ if (!m_renderer->isRenderView())
+ return 0;
+ // this is the RenderObject's Document's renderer's FrameView
+ return m_renderer->view()->frameView();
+}
+
+// This function is like a cross-platform version of - (WebCoreTextMarkerRange*)textMarkerRange. It returns
+// a Range that we can convert to a WebCoreTextMarkerRange in the Obj-C file
+VisiblePositionRange AccessibilityRenderObject::visiblePositionRange() const
+{
+ if (!m_renderer)
+ return VisiblePositionRange();
+
+ // construct VisiblePositions for start and end
+ Node* node = m_renderer->element();
+ if (!node)
+ return VisiblePositionRange();
+
+ VisiblePosition startPos = VisiblePosition(node, 0, VP_DEFAULT_AFFINITY);
+ VisiblePosition endPos = VisiblePosition(node, maxDeepOffset(node), VP_DEFAULT_AFFINITY);
+
+ // the VisiblePositions are equal for nodes like buttons, so adjust for that
+ if (startPos == endPos) {
+ endPos = endPos.next();
+ if (endPos.isNull())
+ endPos = startPos;
+ }
+
+ return VisiblePositionRange(startPos, endPos);
+}
+
+VisiblePositionRange AccessibilityRenderObject::visiblePositionRangeForLine(unsigned lineCount) const
+{
+ if (lineCount == 0 || !m_renderer)
+ return VisiblePositionRange();
+
+ // iterate over the lines
+ // FIXME: this is wrong when lineNumber is lineCount+1, because nextLinePosition takes you to the
+ // last offset of the last line
+ VisiblePosition visiblePos = m_renderer->document()->renderer()->positionForCoordinates(0, 0);
+ VisiblePosition savedVisiblePos;
+ while (--lineCount != 0) {
+ savedVisiblePos = visiblePos;
+ visiblePos = nextLinePosition(visiblePos, 0);
+ if (visiblePos.isNull() || visiblePos == savedVisiblePos)
+ return VisiblePositionRange();
+ }
+
+ // make a caret selection for the marker position, then extend it to the line
+ // NOTE: ignores results of sel.modify because it returns false when
+ // starting at an empty line. The resulting selection in that case
+ // will be a caret at visiblePos.
+ SelectionController selection;
+ selection.setSelection(Selection(visiblePos));
+ selection.modify(SelectionController::EXTEND, SelectionController::RIGHT, LineBoundary);
+
+ return VisiblePositionRange(selection.selection().visibleStart(), selection.selection().visibleEnd());
+}
+
+VisiblePosition AccessibilityRenderObject::visiblePositionForIndex(int index) const
+{
+ if (!m_renderer)
+ return VisiblePosition();
+
+ if (isNativeTextControl())
+ return static_cast<RenderTextControl*>(m_renderer)->visiblePositionForIndex(index);
+
+ if (!isTextControl() && !m_renderer->isText())
+ return VisiblePosition();
+
+ Node* node = m_renderer->node();
+ if (!node)
+ return VisiblePosition();
+
+ if (index <= 0)
+ return VisiblePosition(node, 0, DOWNSTREAM);
+
+ ExceptionCode ec = 0;
+ RefPtr<Range> range = Range::create(m_renderer->document());
+ range->selectNodeContents(node, ec);
+ CharacterIterator it(range.get());
+ it.advance(index - 1);
+ return VisiblePosition(it.range()->endContainer(ec), it.range()->endOffset(ec), UPSTREAM);
+}
+
+int AccessibilityRenderObject::indexForVisiblePosition(const VisiblePosition& pos) const
+{
+ if (isNativeTextControl())
+ return static_cast<RenderTextControl*>(m_renderer)->indexForVisiblePosition(pos);
+
+ if (!isTextControl())
+ return 0;
+
+ Node* node = m_renderer->node();
+ if (!node)
+ return 0;
+
+ Position indexPosition = pos.deepEquivalent();
+ if (!indexPosition.node() || indexPosition.node()->rootEditableElement() != node)
+ return 0;
+
+ ExceptionCode ec = 0;
+ RefPtr<Range> range = Range::create(m_renderer->document());
+ range->setStart(node, 0, ec);
+ range->setEnd(indexPosition.node(), indexPosition.offset(), ec);
+ return TextIterator::rangeLength(range.get());
+}
+
+IntRect AccessibilityRenderObject::boundsForVisiblePositionRange(const VisiblePositionRange& visiblePositionRange) const
+{
+ if (visiblePositionRange.isNull())
+ return IntRect();
+
+ // Create a mutable VisiblePositionRange.
+ VisiblePositionRange range(visiblePositionRange);
+ IntRect rect1 = range.start.caretRect();
+ IntRect rect2 = range.end.caretRect();
+
+ // readjust for position at the edge of a line. This is to exclude line rect that doesn't need to be accounted in the range bounds
+ if (rect2.y() != rect1.y()) {
+ VisiblePosition endOfFirstLine = endOfLine(range.start);
+ if (range.start == endOfFirstLine) {
+ range.start.setAffinity(DOWNSTREAM);
+ rect1 = range.start.caretRect();
+ }
+ if (range.end == endOfFirstLine) {
+ range.end.setAffinity(UPSTREAM);
+ rect2 = range.end.caretRect();
+ }
+ }
+
+ IntRect ourrect = rect1;
+ ourrect.unite(rect2);
+
+ // if the rectangle spans lines and contains multiple text chars, use the range's bounding box intead
+ if (rect1.bottom() != rect2.bottom()) {
+ RefPtr<Range> dataRange = makeRange(range.start, range.end);
+ IntRect boundingBox = dataRange->boundingBox();
+ String rangeString = plainText(dataRange.get());
+ if (rangeString.length() > 1 && !boundingBox.isEmpty())
+ ourrect = boundingBox;
+ }
+
+#if PLATFORM(MAC)
+ return m_renderer->document()->view()->contentsToScreen(ourrect);
+#else
+ return ourrect;
+#endif
+}
+
+void AccessibilityRenderObject::setSelectedVisiblePositionRange(const VisiblePositionRange& range) const
+{
+ if (range.start.isNull() || range.end.isNull())
+ return;
+
+ // make selection and tell the document to use it. if it's zero length, then move to that position
+ if (range.start == range.end) {
+ m_renderer->document()->frame()->selection()->moveTo(range.start, true);
+ }
+ else {
+ Selection newSelection = Selection(range.start, range.end);
+ m_renderer->document()->frame()->selection()->setSelection(newSelection);
+ }
+}
+
+VisiblePosition AccessibilityRenderObject::visiblePositionForPoint(const IntPoint& point) const
+{
+ // convert absolute point to view coordinates
+ FrameView* frameView = m_renderer->document()->topDocument()->renderer()->view()->frameView();
+ RenderObject* renderer = topRenderer();
+ Node* innerNode = 0;
+
+ // locate the node containing the point
+ IntPoint pointResult;
+ while (1) {
+ IntPoint ourpoint;
+#if PLATFORM(MAC)
+ ourpoint = frameView->screenToContents(point);
+#else
+ ourpoint = point;
+#endif
+ HitTestRequest request(true, true);
+ HitTestResult result(ourpoint);
+ renderer->layer()->hitTest(request, result);
+ innerNode = result.innerNode();
+ if (!innerNode || !innerNode->renderer())
+ return VisiblePosition();
+
+ pointResult = result.localPoint();
+
+ // done if hit something other than a widget
+ renderer = innerNode->renderer();
+ if (!renderer->isWidget())
+ break;
+
+ // descend into widget (FRAME, IFRAME, OBJECT...)
+ Widget* widget = static_cast<RenderWidget*>(renderer)->widget();
+ if (!widget || !widget->isFrameView())
+ break;
+ Frame* frame = static_cast<FrameView*>(widget)->frame();
+ if (!frame)
+ break;
+ Document* document = frame->document();
+ if (!document)
+ break;
+ renderer = document->renderer();
+ frameView = static_cast<FrameView*>(widget);
+ }
+
+ return innerNode->renderer()->positionForPoint(pointResult);
+}
+
+// NOTE: Consider providing this utility method as AX API
+VisiblePosition AccessibilityRenderObject::visiblePositionForIndex(unsigned indexValue, bool lastIndexOK) const
+{
+ if (!isTextControl())
+ return VisiblePosition();
+
+ // lastIndexOK specifies whether the position after the last character is acceptable
+ if (indexValue >= text().length()) {
+ if (!lastIndexOK || indexValue > text().length())
+ return VisiblePosition();
+ }
+ VisiblePosition position = visiblePositionForIndex(indexValue);
+ position.setAffinity(DOWNSTREAM);
+ return position;
+}
+
+// NOTE: Consider providing this utility method as AX API
+int AccessibilityRenderObject::index(const VisiblePosition& position) const
+{
+ if (!isTextControl())
+ return -1;
+
+ Node* node = position.deepEquivalent().node();
+ if (!node)
+ return -1;
+
+ for (RenderObject* renderer = node->renderer(); renderer && renderer->element(); renderer = renderer->parent()) {
+ if (renderer == m_renderer)
+ return indexForVisiblePosition(position);
+ }
+
+ return -1;
+}
+
+// Given a line number, the range of characters of the text associated with this accessibility
+// object that contains the line number.
+PlainTextRange AccessibilityRenderObject::doAXRangeForLine(unsigned lineNumber) const
+{
+ if (!isTextControl())
+ return PlainTextRange();
+
+ // iterate to the specified line
+ VisiblePosition visiblePos = visiblePositionForIndex(0);
+ VisiblePosition savedVisiblePos;
+ for (unsigned lineCount = lineNumber; lineCount != 0; lineCount -= 1) {
+ savedVisiblePos = visiblePos;
+ visiblePos = nextLinePosition(visiblePos, 0);
+ if (visiblePos.isNull() || visiblePos == savedVisiblePos)
+ return PlainTextRange();
+ }
+
+ // make a caret selection for the marker position, then extend it to the line
+ // NOTE: ignores results of selection.modify because it returns false when
+ // starting at an empty line. The resulting selection in that case
+ // will be a caret at visiblePos.
+ SelectionController selection;
+ selection.setSelection(Selection(visiblePos));
+ selection.modify(SelectionController::EXTEND, SelectionController::LEFT, LineBoundary);
+ selection.modify(SelectionController::EXTEND, SelectionController::RIGHT, LineBoundary);
+
+ // calculate the indices for the selection start and end
+ VisiblePosition startPosition = selection.selection().visibleStart();
+ VisiblePosition endPosition = selection.selection().visibleEnd();
+ int index1 = indexForVisiblePosition(startPosition);
+ int index2 = indexForVisiblePosition(endPosition);
+
+ // add one to the end index for a line break not caused by soft line wrap (to match AppKit)
+ if (endPosition.affinity() == DOWNSTREAM && endPosition.next().isNotNull())
+ index2 += 1;
+
+ // return nil rather than an zero-length range (to match AppKit)
+ if (index1 == index2)
+ return PlainTextRange();
+
+ return PlainTextRange(index1, index2 - index1);
+}
+
+// The composed character range in the text associated with this accessibility object that
+// is specified by the given index value. This parameterized attribute returns the complete
+// range of characters (including surrogate pairs of multi-byte glyphs) at the given index.
+PlainTextRange AccessibilityRenderObject::doAXRangeForIndex(unsigned index) const
+{
+ if (!isTextControl())
+ return PlainTextRange();
+
+ String elementText = text();
+ if (!elementText.length() || index > elementText.length() - 1)
+ return PlainTextRange();
+
+ return PlainTextRange(index, 1);
+}
+
+// A substring of the text associated with this accessibility object that is
+// specified by the given character range.
+String AccessibilityRenderObject::doAXStringForRange(const PlainTextRange& range) const
+{
+ if (isPasswordField())
+ return String();
+
+ if (range.length == 0)
+ return "";
+
+ if (!isTextControl())
+ return String();
+
+ String elementText = text();
+ if (range.start + range.length > elementText.length())
+ return String();
+
+ return elementText.substring(range.start, range.length);
+}
+
+// The bounding rectangle of the text associated with this accessibility object that is
+// specified by the given range. This is the bounding rectangle a sighted user would see
+// on the display screen, in pixels.
+IntRect AccessibilityRenderObject::doAXBoundsForRange(const PlainTextRange& range) const
+{
+ if (isTextControl())
+ return boundsForVisiblePositionRange(visiblePositionRangeForRange(range));
+ return IntRect();
+}
+
+AccessibilityObject* AccessibilityRenderObject::doAccessibilityHitTest(const IntPoint& point) const
+{
+ if (!m_renderer)
+ return 0;
+
+ RenderLayer* layer = m_renderer->layer();
+ if (!layer)
+ return 0;
+
+ HitTestRequest request(true, true);
+ HitTestResult hitTestResult = HitTestResult(point);
+ layer->hitTest(request, hitTestResult);
+ if (!hitTestResult.innerNode())
+ return 0;
+ Node* node = hitTestResult.innerNode()->shadowAncestorNode();
+ RenderObject* obj = node->renderer();
+ if (!obj)
+ return 0;
+
+ AccessibilityObject *result = obj->document()->axObjectCache()->get(obj);
+
+ if (obj->isListBox())
+ return static_cast<AccessibilityListBox*>(result)->doAccessibilityHitTest(point);
+
+ if (result->accessibilityIsIgnored())
+ result = result->parentObjectUnignored();
+
+ return result;
+}
+
+AccessibilityObject* AccessibilityRenderObject::focusedUIElement() const
+{
+ // get the focused node in the page
+ Page* page = m_renderer->document()->page();
+ if (!page)
+ return 0;
+
+ Document* focusedDocument = page->focusController()->focusedOrMainFrame()->document();
+ Node* focusedNode = focusedDocument->focusedNode();
+ if (!focusedNode)
+ focusedNode = focusedDocument;
+
+ RenderObject* focusedNodeRenderer = focusedNode->renderer();
+ if (!focusedNodeRenderer)
+ return 0;
+
+ AccessibilityObject* obj = focusedNodeRenderer->document()->axObjectCache()->get(focusedNodeRenderer);
+
+ if (obj->shouldFocusActiveDescendant()) {
+ if (AccessibilityObject* descendant = obj->activeDescendant())
+ obj = descendant;
+ }
+
+ // the HTML element, for example, is focusable but has an AX object that is ignored
+ if (obj->accessibilityIsIgnored())
+ obj = obj->parentObjectUnignored();
+
+ return obj;
+}
+
+bool AccessibilityRenderObject::shouldFocusActiveDescendant() const
+{
+ switch (ariaRoleAttribute()) {
+ case GroupRole:
+ case ComboBoxRole:
+ case ListBoxRole:
+ case MenuRole:
+ case MenuBarRole:
+ case RadioGroupRole:
+ case RowRole:
+ case PopUpButtonRole:
+ case ProgressIndicatorRole:
+ case ToolbarRole:
+ case OutlineRole:
+ /* FIXME: replace these with actual roles when they are added to AccessibilityRole
+ composite
+ alert
+ alertdialog
+ grid
+ status
+ timer
+ tree
+ */
+ return true;
+ default:
+ return false;
+ }
+}
+
+AccessibilityObject* AccessibilityRenderObject::activeDescendant() const
+{
+ if (renderer()->element() && !renderer()->element()->isElementNode())
+ return 0;
+ Element* element = static_cast<Element*>(renderer()->element());
+
+ String activeDescendantAttrStr = element->getAttribute(aria_activedescendantAttr).string();
+ if (activeDescendantAttrStr.isNull() || activeDescendantAttrStr.isEmpty())
+ return 0;
+
+ Element* target = renderer()->document()->getElementById(activeDescendantAttrStr);
+ AccessibilityObject* obj = renderer()->document()->axObjectCache()->get(target->renderer());
+ if (obj->isAccessibilityRenderObject())
+ // an activedescendant is only useful if it has a renderer, because that's what's needed to post the notification
+ return obj;
+ return 0;
+}
+
+
+void AccessibilityRenderObject::handleActiveDescendantChanged()
+{
+ Element* element = static_cast<Element*>(renderer()->element());
+ if (!element)
+ return;
+ Document* doc = renderer()->document();
+ if (!doc->frame()->selection()->isFocusedAndActive() || doc->focusedNode() != element)
+ return;
+ AccessibilityRenderObject* activedescendant = static_cast<AccessibilityRenderObject*>(activeDescendant());
+
+ if (activedescendant && shouldFocusActiveDescendant())
+ doc->axObjectCache()->postNotificationToElement(activedescendant->renderer(), "AXFocusedUIElementChanged");
+}
+
+
+AccessibilityObject* AccessibilityRenderObject::observableObject() const
+{
+ for (RenderObject* renderer = m_renderer; renderer && renderer->element(); renderer = renderer->parent()) {
+ if (renderer->isTextField() || renderer->isTextArea())
+ return renderer->document()->axObjectCache()->get(renderer);
+ }
+
+ return 0;
+}
+
+typedef HashMap<String, AccessibilityRole, CaseFoldingHash> ARIARoleMap;
+
+static const ARIARoleMap& createARIARoleMap()
+{
+ struct RoleEntry {
+ String ariaRole;
+ AccessibilityRole webcoreRole;
+ };
+
+ static const RoleEntry roles[] = {
+ { "button", ButtonRole },
+ { "checkbox", CheckBoxRole },
+ { "group", GroupRole },
+ { "heading", HeadingRole },
+ { "img", ImageRole },
+ { "link", WebCoreLinkRole },
+ { "listbox", ListBoxRole },
+ // "option" isn't here because it may map to different roles depending on the parent element's role
+ { "menu", MenuRole },
+ { "menubar", GroupRole },
+ // "menuitem" isn't here because it may map to different roles depending on the parent element's role
+ { "menuitemcheckbox", MenuItemRole },
+ { "menuitemradio", MenuItemRole },
+ { "progressbar", ProgressIndicatorRole },
+ { "radio", RadioButtonRole },
+ { "range", SliderRole },
+ { "slider", SliderRole },
+ { "spinbutton", ProgressIndicatorRole },
+ { "textbox", TextAreaRole }
+ };
+ ARIARoleMap& roleMap = *new ARIARoleMap;
+
+ const unsigned numRoles = sizeof(roles) / sizeof(roles[0]);
+ for (unsigned i = 0; i < numRoles; ++i)
+ roleMap.set(roles[i].ariaRole, roles[i].webcoreRole);
+ return roleMap;
+}
+
+static AccessibilityRole ariaRoleToWebCoreRole(String value)
+{
+ ASSERT(!value.isEmpty() && !value.isNull());
+ static const ARIARoleMap& roleMap = createARIARoleMap();
+ return roleMap.get(value);
+}
+
+AccessibilityRole AccessibilityRenderObject::determineAriaRoleAttribute() const
+{
+ String ariaRole = getAttribute(roleAttr).string();
+ if (ariaRole.isNull() || ariaRole.isEmpty())
+ return UnknownRole;
+
+ AccessibilityRole role = ariaRoleToWebCoreRole(ariaRole);
+ if (role)
+ return role;
+ // selects and listboxes both have options as child roles, but they map to different roles within WebCore
+ if (equalIgnoringCase(ariaRole,"option")) {
+ if (parentObjectUnignored()->ariaRoleAttribute() == MenuRole)
+ return MenuItemRole;
+ if (parentObjectUnignored()->ariaRoleAttribute() == ListBoxRole)
+ return ListBoxOptionRole;
+ }
+ // an aria "menuitem" may map to MenuButton or MenuItem depending on its parent
+ if (equalIgnoringCase(ariaRole,"menuitem")) {
+ if (parentObjectUnignored()->ariaRoleAttribute() == GroupRole)
+ return MenuButtonRole;
+ if (parentObjectUnignored()->ariaRoleAttribute() == MenuRole)
+ return MenuItemRole;
+ }
+
+ return UnknownRole;
+}
+
+void AccessibilityRenderObject::setAriaRole()
+{
+ m_ariaRole = determineAriaRoleAttribute();
+}
+
+AccessibilityRole AccessibilityRenderObject::ariaRoleAttribute() const
+{
+ return m_ariaRole;
+}
+
+AccessibilityRole AccessibilityRenderObject::roleValue() const
+{
+ if (!m_renderer)
+ return UnknownRole;
+
+ Node* node = m_renderer->element();
+ AccessibilityRole ariaRole = ariaRoleAttribute();
+ if (ariaRole != UnknownRole)
+ return ariaRole;
+
+ if (node && node->isLink()) {
+ if (m_renderer->isImage())
+ return ImageMapRole;
+ return WebCoreLinkRole;
+ }
+ if (m_renderer->isListMarker())
+ return ListMarkerRole;
+ if (node && node->hasTagName(buttonTag))
+ return ButtonRole;
+ if (m_renderer->isText())
+ return StaticTextRole;
+ if (m_renderer->isImage()) {
+ if (node && node->hasTagName(inputTag))
+ return ButtonRole;
+ return ImageRole;
+ }
+ if (m_renderer->isRenderView())
+ return WebAreaRole;
+
+ if (m_renderer->isTextField())
+ return TextFieldRole;
+
+ if (m_renderer->isTextArea())
+ return TextAreaRole;
+
+ if (node && node->hasTagName(inputTag)) {
+ HTMLInputElement* input = static_cast<HTMLInputElement*>(node);
+ if (input->inputType() == HTMLInputElement::CHECKBOX)
+ return CheckBoxRole;
+ if (input->inputType() == HTMLInputElement::RADIO)
+ return RadioButtonRole;
+ if (input->isTextButton())
+ return ButtonRole;
+ }
+
+ if (node && node->hasTagName(buttonTag))
+ return ButtonRole;
+
+ if (isFileUploadButton())
+ return ButtonRole;
+
+ if (m_renderer->isMenuList())
+ return PopUpButtonRole;
+
+ if (headingLevel(m_renderer->element()) != 0)
+ return HeadingRole;
+
+ if (node && node->hasTagName(ddTag))
+ return DefinitionListDefinitionRole;
+
+ if (node && node->hasTagName(dtTag))
+ return DefinitionListTermRole;
+
+ if (m_renderer->isBlockFlow() || (node && node->hasTagName(labelTag)))
+ return GroupRole;
+
+ return UnknownRole;
+}
+
+bool AccessibilityRenderObject::isPresentationalChildOfAriaRole() const
+{
+ // Walk the parent chain looking for a parent that has presentational children
+ AccessibilityObject* parent;
+ for (parent = parentObject(); parent && !parent->ariaRoleHasPresentationalChildren(); parent = parent->parentObject())
+ ;
+ return parent;
+}
+
+bool AccessibilityRenderObject::ariaRoleHasPresentationalChildren() const
+{
+ switch (m_ariaRole) {
+ case ButtonRole:
+ case SliderRole:
+ case ImageRole:
+ case ProgressIndicatorRole:
+ //case SeparatorRole:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool AccessibilityRenderObject::canSetFocusAttribute() const
+{
+ // NOTE: It would be more accurate to ask the document whether setFocusedNode() would
+ // do anything. For example, it setFocusedNode() will do nothing if the current focused
+ // node will not relinquish the focus.
+ if (!m_renderer->element() || !m_renderer->element()->isEnabled())
+ return false;
+
+ switch (roleValue()) {
+ case WebCoreLinkRole:
+ case ImageMapLinkRole:
+ case TextFieldRole:
+ case TextAreaRole:
+ case ButtonRole:
+ case PopUpButtonRole:
+ case CheckBoxRole:
+ case RadioButtonRole:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool AccessibilityRenderObject::canSetValueAttribute() const
+{
+ if (isWebArea())
+ return !isReadOnly();
+
+ return isTextControl() || isProgressIndicator() || isSlider();
+}
+
+bool AccessibilityRenderObject::canSetTextRangeAttributes() const
+{
+ return isTextControl();
+}
+
+void AccessibilityRenderObject::childrenChanged()
+{
+ clearChildren();
+
+ if (accessibilityIsIgnored()) {
+ AccessibilityObject* parent = parentObject();
+ if (parent)
+ parent->childrenChanged();
+ }
+}
+
+bool AccessibilityRenderObject::canHaveChildren() const
+{
+ if (!m_renderer)
+ return false;
+
+ // Elements that should not have children
+ switch (roleValue()) {
+ case ImageRole:
+ case ButtonRole:
+ case PopUpButtonRole:
+ case CheckBoxRole:
+ case RadioButtonRole:
+ return false;
+ default:
+ return true;
+ }
+}
+
+const AccessibilityObject::AccessibilityChildrenVector& AccessibilityRenderObject::children()
+{
+ if (!m_haveChildren)
+ addChildren();
+ return m_children;
+}
+
+void AccessibilityRenderObject::addChildren()
+{
+ // If the need to add more children in addition to existing children arises,
+ // childrenChanged should have been called, leaving the object with no children.
+ ASSERT(!m_haveChildren);
+
+ // nothing to add if there is no RenderObject
+ if (!m_renderer)
+ return;
+
+ m_haveChildren = true;
+
+ if (!canHaveChildren())
+ return;
+
+ // add all unignored acc children
+ for (RefPtr<AccessibilityObject> obj = firstChild(); obj; obj = obj->nextSibling()) {
+ if (obj->accessibilityIsIgnored()) {
+ if (!obj->hasChildren())
+ obj->addChildren();
+ AccessibilityChildrenVector children = obj->children();
+ unsigned length = children.size();
+ for (unsigned i = 0; i < length; ++i)
+ m_children.append(children[i]);
+ } else
+ m_children.append(obj);
+ }
+
+ // for a RenderImage, add the <area> elements as individual accessibility objects
+ if (m_renderer->isRenderImage()) {
+ HTMLMapElement* map = static_cast<RenderImage*>(m_renderer)->imageMap();
+ if (map) {
+ for (Node* current = map->firstChild(); current; current = current->traverseNextNode(map)) {
+
+ // add an <area> element for this child if it has a link
+ if (current->isLink()) {
+ AccessibilityImageMapLink* areaObject = static_cast<AccessibilityImageMapLink*>(m_renderer->document()->axObjectCache()->get(ImageMapLinkRole));
+ areaObject->setHTMLAreaElement(static_cast<HTMLAreaElement*>(current));
+ areaObject->setHTMLMapElement(map);
+ areaObject->setParent(this);
+
+ m_children.append(areaObject);
+ }
+ }
+ }
+ }
+}
+
+void AccessibilityRenderObject::ariaListboxSelectedChildren(AccessibilityChildrenVector& result)
+{
+ AccessibilityObject* child = firstChild();
+ bool isMultiselectable = false;
+
+ Element* element = static_cast<Element*>(renderer()->element());
+ if (!element || !element->isElementNode()) // do this check to ensure safety of static_cast above
+ return;
+
+ String multiselectablePropertyStr = element->getAttribute("aria-multiselectable").string();
+ isMultiselectable = equalIgnoringCase(multiselectablePropertyStr, "true");
+
+ while (child) {
+ // every child should have aria-role option, and if so, check for selected attribute/state
+ AccessibilityRole ariaRole = child->ariaRoleAttribute();
+ RenderObject* childRenderer = 0;
+ if (child->isAccessibilityRenderObject())
+ childRenderer = static_cast<AccessibilityRenderObject*>(child)->renderer();
+ if (childRenderer && ariaRole == ListBoxOptionRole) {
+ Element* childElement = static_cast<Element*>(childRenderer->element());
+ if (childElement && childElement->isElementNode()) { // do this check to ensure safety of static_cast above
+ String selectedAttrString = childElement->getAttribute("aria-selected").string();
+ if (equalIgnoringCase(selectedAttrString, "true")) {
+ result.append(child);
+ if (isMultiselectable)
+ return;
+ }
+ }
+ }
+ child = child->nextSibling();
+ }
+}
+
+void AccessibilityRenderObject::selectedChildren(AccessibilityChildrenVector& result)
+{
+ ASSERT(result.isEmpty());
+
+ // only listboxes should be asked for their selected children.
+ if (ariaRoleAttribute() != ListBoxRole) { // native list boxes would be AccessibilityListBoxes, so only check for aria list boxes
+ ASSERT_NOT_REACHED();
+ return;
+ }
+ return ariaListboxSelectedChildren(result);
+}
+
+void AccessibilityRenderObject::ariaListboxVisibleChildren(AccessibilityChildrenVector& result)
+{
+ if (!hasChildren())
+ addChildren();
+
+ unsigned length = m_children.size();
+ for (unsigned i = 0; i < length; i++) {
+ if (!m_children[i]->isOffScreen())
+ result.append(m_children[i]);
+ }
+}
+
+void AccessibilityRenderObject::visibleChildren(AccessibilityChildrenVector& result)
+{
+ ASSERT(result.isEmpty());
+
+ // only listboxes are asked for their visible children.
+ if (ariaRoleAttribute() != ListBoxRole) { // native list boxes would be AccessibilityListBoxes, so only check for aria list boxes
+ ASSERT_NOT_REACHED();
+ return;
+ }
+ return ariaListboxVisibleChildren(result);
+}
+
+void AccessibilityRenderObject::removeAXObjectID()
+{
+ if (!m_id)
+ return;
+#if PLATFORM(MAC)
+ m_renderer->document()->axObjectCache()->removeAXID(this);
+#endif
+}
+
+const String& AccessibilityRenderObject::actionVerb() const
+{
+ // FIXME: Need to add verbs for select elements.
+ static const String buttonAction = AXButtonActionVerb();
+ static const String textFieldAction = AXTextFieldActionVerb();
+ static const String radioButtonAction = AXRadioButtonActionVerb();
+ static const String checkedCheckBoxAction = AXCheckedCheckBoxActionVerb();
+ static const String uncheckedCheckBoxAction = AXUncheckedCheckBoxActionVerb();
+ static const String linkAction = AXLinkActionVerb();
+ static const String noAction;
+
+ switch (roleValue()) {
+ case ButtonRole:
+ return buttonAction;
+ case TextFieldRole:
+ case TextAreaRole:
+ return textFieldAction;
+ case RadioButtonRole:
+ return radioButtonAction;
+ case CheckBoxRole:
+ return isChecked() ? checkedCheckBoxAction : uncheckedCheckBoxAction;
+ case LinkRole:
+ case WebCoreLinkRole:
+ return linkAction;
+ default:
+ return noAction;
+ }
+}
+
+
+} // namespace WebCore
diff --git a/WebCore/page/AccessibilityRenderObject.h b/WebCore/page/AccessibilityRenderObject.h
new file mode 100644
index 0000000..c859b5a
--- /dev/null
+++ b/WebCore/page/AccessibilityRenderObject.h
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 AccessibilityRenderObject_h
+#define AccessibilityRenderObject_h
+
+#include "AccessibilityObject.h"
+
+namespace WebCore {
+
+class AXObjectCache;
+class Element;
+class Frame;
+class FrameView;
+class HitTestResult;
+class HTMLAnchorElement;
+class HTMLAreaElement;
+class HTMLElement;
+class HTMLLabelElement;
+class HTMLMapElement;
+class HTMLSelectElement;
+class IntPoint;
+class IntSize;
+class Node;
+class RenderObject;
+class RenderListBox;
+class RenderTextControl;
+class Selection;
+class String;
+class Widget;
+
+class AccessibilityRenderObject : public AccessibilityObject {
+protected:
+ AccessibilityRenderObject(RenderObject*);
+public:
+ static PassRefPtr<AccessibilityRenderObject> create(RenderObject*);
+ virtual ~AccessibilityRenderObject();
+
+ bool isAccessibilityRenderObject() const { return true; };
+
+ virtual bool isAnchor() const;
+ virtual bool isAttachment() const;
+ virtual bool isHeading() const;
+ virtual bool isLink() const;
+ virtual bool isImageButton() const;
+ virtual bool isImage() const;
+ virtual bool isNativeImage() const;
+ virtual bool isPasswordField() const;
+ virtual bool isTextControl() const;
+ virtual bool isNativeTextControl() const;
+ virtual bool isWebArea() const;
+ virtual bool isCheckboxOrRadio() const;
+ virtual bool isFileUploadButton() const;
+ virtual bool isProgressIndicator() const;
+ virtual bool isSlider() const;
+ virtual bool isMenuRelated() const;
+ virtual bool isMenu() const;
+ virtual bool isMenuBar() const;
+ virtual bool isMenuButton() const;
+ virtual bool isMenuItem() const;
+ virtual bool isControl() const;
+ virtual bool isFieldset() const;
+
+ virtual bool isEnabled() const;
+ virtual bool isSelected() const;
+ virtual bool isFocused() const;
+ virtual bool isChecked() const;
+ virtual bool isHovered() const;
+ virtual bool isIndeterminate() const;
+ virtual bool isLoaded() const;
+ virtual bool isMultiSelect() const;
+ virtual bool isOffScreen() const;
+ virtual bool isPressed() const;
+ virtual bool isReadOnly() const;
+ virtual bool isVisited() const;
+
+ const AtomicString& getAttribute(const QualifiedName&) const;
+ virtual bool canSetFocusAttribute() const;
+ virtual bool canSetTextRangeAttributes() const;
+ virtual bool canSetValueAttribute() const;
+
+ virtual bool hasIntValue() const;
+
+ virtual bool accessibilityIsIgnored() const;
+
+ static int headingLevel(Node*);
+ virtual int intValue() const;
+ virtual float valueForRange() const;
+ virtual float maxValueForRange() const;
+ virtual float minValueForRange() const;
+ virtual int layoutCount() const;
+
+ virtual AccessibilityObject* doAccessibilityHitTest(const IntPoint&) const;
+ virtual AccessibilityObject* focusedUIElement() const;
+ virtual AccessibilityObject* firstChild() const;
+ virtual AccessibilityObject* lastChild() const;
+ virtual AccessibilityObject* previousSibling() const;
+ virtual AccessibilityObject* nextSibling() const;
+ virtual AccessibilityObject* parentObject() const;
+ virtual AccessibilityObject* observableObject() const;
+ virtual void linkedUIElements(AccessibilityChildrenVector&) const;
+ virtual AccessibilityObject* titleUIElement() const;
+ virtual AccessibilityRole ariaRoleAttribute() const;
+ virtual bool isPresentationalChildOfAriaRole() const;
+ virtual bool ariaRoleHasPresentationalChildren() const;
+ void setAriaRole();
+ virtual AccessibilityRole roleValue() const;
+ virtual AXObjectCache* axObjectCache() const;
+
+ virtual Element* actionElement() const;
+ Element* mouseButtonListener() const;
+ FrameView* frameViewIfRenderView() const;
+ virtual Element* anchorElement() const;
+ AccessibilityObject* menuForMenuButton() const;
+ AccessibilityObject* menuButtonForMenu() const;
+
+ virtual IntRect boundingBoxRect() const;
+ virtual IntRect elementRect() const;
+ virtual IntSize size() const;
+
+ void setRenderer(RenderObject* renderer) { m_renderer = renderer; }
+ RenderObject* renderer() const { return m_renderer; }
+ RenderObject* topRenderer() const;
+ RenderTextControl* textControl() const;
+ Document* document() const;
+ FrameView* topDocumentFrameView() const;
+ HTMLLabelElement* labelElementContainer() const;
+
+ virtual KURL url() const;
+ virtual PlainTextRange selectedTextRange() const;
+ virtual Selection selection() const;
+ virtual String stringValue() const;
+ virtual String ariaAccessiblityName(const String&) const;
+ virtual String ariaLabeledByAttribute() const;
+ virtual String title() const;
+ virtual String ariaDescribedByAttribute() const;
+ virtual String accessibilityDescription() const;
+ virtual String helpText() const;
+ virtual String textUnderElement() const;
+ virtual String text() const;
+ virtual int textLength() const;
+ virtual PassRefPtr<Range> ariaSelectedTextDOMRange() const;
+ virtual String selectedText() const;
+ virtual const AtomicString& accessKey() const;
+ virtual const String& actionVerb() const;
+ virtual Widget* widget() const;
+ virtual Widget* widgetForAttachmentView() const;
+ virtual void getDocumentLinks(AccessibilityChildrenVector&);
+ virtual FrameView* documentFrameView() const;
+
+ virtual const AccessibilityChildrenVector& children();
+
+ virtual void setFocused(bool);
+ virtual void setSelectedTextRange(const PlainTextRange&);
+ virtual void setValue(const String&);
+
+ virtual void detach();
+ virtual void childrenChanged();
+ virtual void addChildren();
+ virtual bool canHaveChildren() const;
+ virtual void selectedChildren(AccessibilityChildrenVector&);
+ virtual void visibleChildren(AccessibilityChildrenVector&);
+ virtual bool shouldFocusActiveDescendant() const;
+ virtual AccessibilityObject* activeDescendant() const;
+ virtual void handleActiveDescendantChanged();
+
+ virtual VisiblePositionRange visiblePositionRange() const;
+ virtual VisiblePositionRange visiblePositionRangeForLine(unsigned) const;
+ virtual IntRect boundsForVisiblePositionRange(const VisiblePositionRange&) const;
+ virtual void setSelectedVisiblePositionRange(const VisiblePositionRange&) const;
+
+ virtual VisiblePosition visiblePositionForPoint(const IntPoint&) const;
+ virtual VisiblePosition visiblePositionForIndex(unsigned indexValue, bool lastIndexOK) const;
+ virtual int index(const VisiblePosition&) const;
+
+ virtual VisiblePosition visiblePositionForIndex(int) const;
+ virtual int indexForVisiblePosition(const VisiblePosition&) const;
+
+ virtual PlainTextRange doAXRangeForLine(unsigned) const;
+ virtual PlainTextRange doAXRangeForIndex(unsigned) const;
+
+ virtual String doAXStringForRange(const PlainTextRange&) const;
+ virtual IntRect doAXBoundsForRange(const PlainTextRange&) const;
+
+protected:
+ RenderObject* m_renderer;
+ AccessibilityRole m_ariaRole;
+
+ void setRenderObject(RenderObject* renderer) { m_renderer = renderer; }
+ virtual void removeAXObjectID();
+
+ virtual bool isDetached() const { return !m_renderer; }
+
+private:
+ void ariaListboxSelectedChildren(AccessibilityChildrenVector&);
+ void ariaListboxVisibleChildren(AccessibilityChildrenVector&);
+
+ Element* menuElementForMenuButton() const;
+ Element* menuItemElementForMenu() const;
+ AccessibilityRole determineAriaRoleAttribute() const;
+
+ IntRect checkboxOrRadioRect() const;
+ void addRadioButtonGroupMembers(AccessibilityChildrenVector& linkedUIElements) const;
+ AccessibilityObject* internalLinkElement() const;
+ AccessibilityObject* accessibilityParentForImageMap(HTMLMapElement* map) const;
+
+};
+
+} // namespace WebCore
+
+#endif // AccessibilityRenderObject_h
diff --git a/WebCore/page/AccessibilityTable.cpp b/WebCore/page/AccessibilityTable.cpp
new file mode 100644
index 0000000..11c36ef
--- /dev/null
+++ b/WebCore/page/AccessibilityTable.cpp
@@ -0,0 +1,491 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AccessibilityTable.h"
+
+#include "AccessibilityTableCell.h"
+#include "AccessibilityTableColumn.h"
+#include "AccessibilityTableHeaderContainer.h"
+#include "AccessibilityTableRow.h"
+#include "AXObjectCache.h"
+#include "HTMLNames.h"
+#include "HTMLTableElement.h"
+#include "HTMLTableCaptionElement.h"
+#include "HTMLTableCellElement.h"
+#include "RenderObject.h"
+#include "RenderTable.h"
+#include "RenderTableCell.h"
+#include "RenderTableSection.h"
+
+using namespace std;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+AccessibilityTable::AccessibilityTable(RenderObject* renderer)
+ : AccessibilityRenderObject(renderer),
+ m_headerContainer(0)
+{
+ // AXTables should not appear in tiger or leopard, on the mac
+#if PLATFORM(MAC) && (defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD))
+ m_isAccessibilityTable = false;
+#else
+ m_isAccessibilityTable = isTableExposableThroughAccessibility();
+#endif
+
+}
+
+AccessibilityTable::~AccessibilityTable()
+{
+}
+
+PassRefPtr<AccessibilityTable> AccessibilityTable::create(RenderObject* renderer)
+{
+ return adoptRef(new AccessibilityTable(renderer));
+}
+
+bool AccessibilityTable::isTableExposableThroughAccessibility()
+{
+ // the following is a heuristic used to determine if a
+ // <table> should be exposed as an AXTable. The goal
+ // is to only show "data" tables
+
+ if (!m_renderer || !m_renderer->isTable())
+ return false;
+
+ // if the developer assigned an aria role to this, then we shouldn't
+ // expose it as a table, unless, of course, the aria role is a table
+ AccessibilityRole ariaRole = ariaRoleAttribute();
+ if (ariaRole == TableRole)
+ return true;
+ if (ariaRole != UnknownRole)
+ return false;
+
+ RenderTable* table = static_cast<RenderTable*>(m_renderer);
+
+ // this employs a heuristic to determine if this table should appear.
+ // Only "data" tables should be exposed as tables.
+ // Unfortunately, there is no good way to determine the difference
+ // between a "layout" table and a "data" table
+
+ Node* tableNode = table->element();
+ if (!tableNode || !tableNode->hasTagName(tableTag))
+ return false;
+
+ // if there is a caption element, summary, THEAD, or TFOOT section, it's most certainly a data table
+ HTMLTableElement* tableElement = static_cast<HTMLTableElement*>(tableNode);
+ if (!tableElement->summary().isEmpty() || tableElement->tHead() || tableElement->tFoot() || tableElement->caption())
+ return true;
+
+ // if someone used "rules" attribute than the table should appear
+ if (!tableElement->rules().isEmpty())
+ return true;
+
+ // go through the cell's and check for tell-tale signs of "data" table status
+ // cells have borders, or use attributes like headers, abbr, scope or axis
+ RenderTableSection* firstBody = table->firstBody();
+ if (!firstBody)
+ return false;
+
+ int numCols = firstBody->numColumns();
+ int numRows = firstBody->numRows();
+
+ // if there's only one cell, it's not a good AXTable candidate
+ if (numRows == 1 && numCols == 1)
+ return false;
+
+ // store the background color of the table to check against cell's background colors
+ RenderStyle* tableStyle = table->style();
+ if (!tableStyle)
+ return false;
+ Color tableBGColor = tableStyle->backgroundColor();
+
+ // check enough of the cells to find if the table matches our criteria
+ // Criteria:
+ // 1) must have at least one valid cell (and)
+ // 2) at least half of cells have borders (or)
+ // 3) at least half of cells have different bg colors than the table, and there is cell spacing
+ unsigned validCellCount = 0;
+ unsigned borderedCellCount = 0;
+ unsigned backgroundDifferenceCellCount = 0;
+
+ for (int row = 0; row < numRows; ++row) {
+ for (int col = 0; col < numCols; ++col) {
+ RenderTableCell* cell = firstBody->cellAt(row, col).cell;
+ if (!cell)
+ continue;
+ Node* cellNode = cell->element();
+ if (!cellNode)
+ continue;
+
+ if (cell->width() < 1 || cell->height() < 1)
+ continue;
+
+ validCellCount++;
+
+ HTMLTableCellElement* cellElement = static_cast<HTMLTableCellElement*>(cellNode);
+
+ // in this case, the developer explicitly assigned a "data" table attribute
+ if (!cellElement->headers().isEmpty() || !cellElement->abbr().isEmpty() ||
+ !cellElement->axis().isEmpty() || !cellElement->scope().isEmpty())
+ return true;
+
+ RenderStyle* renderStyle = cell->style();
+ if (!renderStyle)
+ continue;
+
+ // a cell needs to have matching bordered sides, before it can be considered a bordered cell.
+ if ((cell->borderTop() > 0 && cell->borderBottom() > 0) ||
+ (cell->borderLeft() > 0 && cell->borderRight() > 0))
+ borderedCellCount++;
+
+ // if the cell has a different color from the table and there is cell spacing,
+ // then it is probably a data table cell (spacing and colors take the place of borders)
+ Color cellColor = renderStyle->backgroundColor();
+ if (table->hBorderSpacing() > 0 && table->vBorderSpacing() > 0 &&
+ tableBGColor != cellColor && cellColor.alpha() != 1)
+ backgroundDifferenceCellCount++;
+
+ // if we've found 10 "good" cells, we don't need to keep searching
+ if (borderedCellCount >= 10 || backgroundDifferenceCellCount >= 10)
+ return true;
+ }
+ }
+
+ // if there is less than two valid cells, it's not a data table
+ if (validCellCount <= 1)
+ return false;
+
+ // half of the cells had borders, it's a data table
+ unsigned neededCellCount = validCellCount / 2;
+ if (borderedCellCount >= neededCellCount)
+ return true;
+
+ // half had different background colors, it's a data table
+ if (backgroundDifferenceCellCount >= neededCellCount)
+ return true;
+
+ return false;
+}
+
+void AccessibilityTable::clearChildren()
+{
+ m_children.clear();
+ m_rows.clear();
+ m_columns.clear();
+ m_haveChildren = false;
+}
+
+void AccessibilityTable::addChildren()
+{
+ if (!isDataTable()) {
+ AccessibilityRenderObject::addChildren();
+ return;
+ }
+
+ ASSERT(!m_haveChildren);
+
+ m_haveChildren = true;
+ if (!m_renderer)
+ return;
+
+ RenderTable* table = static_cast<RenderTable*>(m_renderer);
+ AXObjectCache* axCache = m_renderer->document()->axObjectCache();
+
+ // go through all the available sections to pull out the rows
+ // and add them as children
+ RenderTableSection* tableSection = table->header();
+ if (!tableSection)
+ tableSection = table->firstBody();
+
+ if (!tableSection)
+ return;
+
+ RenderTableSection* initialTableSection = tableSection;
+
+ while (tableSection) {
+
+ HashSet<AccessibilityObject*> appendedRows;
+
+ unsigned numRows = tableSection->numRows();
+ unsigned numCols = tableSection->numColumns();
+ for (unsigned rowIndex = 0; rowIndex < numRows; ++rowIndex) {
+ for (unsigned colIndex = 0; colIndex < numCols; ++colIndex) {
+
+ RenderTableCell* cell = tableSection->cellAt(rowIndex, colIndex).cell;
+ if (!cell)
+ continue;
+
+ AccessibilityObject* rowObject = axCache->get(cell->parent());
+ if (!rowObject->isTableRow())
+ continue;
+
+ AccessibilityTableRow* row = static_cast<AccessibilityTableRow*>(rowObject);
+ // we need to check every cell for a new row, because cell spans
+ // can cause us to mess rows if we just check the first column
+ if (appendedRows.contains(row))
+ continue;
+
+ row->setRowIndex((int)m_rows.size());
+ m_rows.append(row);
+ m_children.append(row);
+ appendedRows.add(row);
+ }
+ }
+
+ tableSection = table->sectionBelow(tableSection, true);
+ }
+
+ // make the columns based on the number of columns in the first body
+ unsigned length = initialTableSection->numColumns();
+ for (unsigned i = 0; i < length; ++i) {
+ AccessibilityTableColumn* column = static_cast<AccessibilityTableColumn*>(axCache->get(ColumnRole));
+ column->setColumnIndex((int)i);
+ column->setParentTable(this);
+ m_columns.append(column);
+ m_children.append(column);
+ }
+
+ AccessibilityObject* headerContainerObject = headerContainer();
+ if (headerContainerObject)
+ m_children.append(headerContainerObject);
+}
+
+AccessibilityObject* AccessibilityTable::headerContainer()
+{
+ if (m_headerContainer)
+ return m_headerContainer;
+
+ m_headerContainer = static_cast<AccessibilityTableHeaderContainer*>(axObjectCache()->get(TableHeaderContainerRole));
+ m_headerContainer->setParentTable(this);
+
+ return m_headerContainer;
+}
+
+AccessibilityObject::AccessibilityChildrenVector& AccessibilityTable::columns()
+{
+ if (!hasChildren())
+ addChildren();
+
+ return m_columns;
+}
+
+AccessibilityObject::AccessibilityChildrenVector& AccessibilityTable::rows()
+{
+ if (!hasChildren())
+ addChildren();
+
+ return m_rows;
+}
+
+void AccessibilityTable::rowHeaders(AccessibilityChildrenVector& headers)
+{
+ if (!m_renderer)
+ return;
+
+ if (!hasChildren())
+ addChildren();
+
+ unsigned rowCount = m_rows.size();
+ for (unsigned k = 0; k < rowCount; ++k) {
+ AccessibilityObject* header = static_cast<AccessibilityTableRow*>(m_rows[k].get())->headerObject();
+ if (!header)
+ continue;
+ headers.append(header);
+ }
+}
+
+void AccessibilityTable::columnHeaders(AccessibilityChildrenVector& headers)
+{
+ if (!m_renderer)
+ return;
+
+ if (!hasChildren())
+ addChildren();
+
+ unsigned colCount = m_columns.size();
+ for (unsigned k = 0; k < colCount; ++k) {
+ AccessibilityObject* header = static_cast<AccessibilityTableColumn*>(m_columns[k].get())->headerObject();
+ if (!header)
+ continue;
+ headers.append(header);
+ }
+}
+
+void AccessibilityTable::cells(AccessibilityObject::AccessibilityChildrenVector& cells)
+{
+ if (!m_renderer)
+ return;
+
+ if (!hasChildren())
+ addChildren();
+
+ int numRows = m_rows.size();
+ for (int row = 0; row < numRows; ++row) {
+ AccessibilityChildrenVector rowChildren = m_rows[row]->children();
+ cells.append(rowChildren);
+ }
+}
+
+const unsigned AccessibilityTable::columnCount()
+{
+ if (!hasChildren())
+ addChildren();
+
+ return m_columns.size();
+}
+
+const unsigned AccessibilityTable::rowCount()
+{
+ if (!hasChildren())
+ addChildren();
+
+ return m_rows.size();
+}
+
+AccessibilityTableCell* AccessibilityTable::cellForColumnAndRow(unsigned column, unsigned row)
+{
+ if (!m_renderer)
+ return 0;
+
+ if (!hasChildren())
+ addChildren();
+
+ RenderTable* table = static_cast<RenderTable*>(m_renderer);
+ RenderTableSection* tableSection = table->header();
+ if (!tableSection)
+ tableSection = table->firstBody();
+
+ RenderTableCell* cell = 0;
+ unsigned rowCount = 0;
+ unsigned rowOffset = 0;
+ while (tableSection) {
+
+ rowCount += tableSection->numRows();
+ unsigned numCols = tableSection->numColumns();
+
+ if (row < rowCount && column < numCols) {
+ int sectionSpecificRow = row - rowOffset;
+ cell = tableSection->cellAt(sectionSpecificRow, column).cell;
+
+ // we didn't find the cell, which means there's spanning happening
+ // search backwards to find the spanning cell
+ if (!cell) {
+
+ // first try rows
+ for (int testRow = sectionSpecificRow-1; testRow >= 0; --testRow) {
+ cell = tableSection->cellAt(testRow, column).cell;
+ // cell overlapped. use this one
+ if (cell && ((cell->row() + (cell->rowSpan()-1)) >= (int)sectionSpecificRow))
+ break;
+ cell = 0;
+ }
+
+ if (!cell) {
+ // try cols
+ for (int testCol = column-1; testCol >= 0; --testCol) {
+ cell = tableSection->cellAt(sectionSpecificRow, testCol).cell;
+ // cell overlapped. use this one
+ if (cell && ((cell->col() + (cell->colSpan()-1)) >= (int)column))
+ break;
+ cell = 0;
+ }
+ }
+ }
+ }
+
+ if (cell)
+ break;
+
+ rowOffset += rowCount;
+ // we didn't find anything between the rows we should have
+ if (row < rowOffset)
+ break;
+ tableSection = table->sectionBelow(tableSection, true);
+ }
+
+ if (!cell)
+ return 0;
+
+ AccessibilityObject* cellObject = axObjectCache()->get(cell);
+ ASSERT(cellObject->isTableCell());
+
+ return static_cast<AccessibilityTableCell*>(cellObject);
+}
+
+AccessibilityRole AccessibilityTable::roleValue() const
+{
+ if (!isDataTable())
+ return AccessibilityRenderObject::roleValue();
+
+ return TableRole;
+}
+
+bool AccessibilityTable::accessibilityIsIgnored() const
+{
+ if (!isDataTable())
+ return AccessibilityRenderObject::accessibilityIsIgnored();
+
+ return false;
+}
+
+String AccessibilityTable::title() const
+{
+ if (!isDataTable())
+ return AccessibilityRenderObject::title();
+
+ String title;
+ if (!m_renderer)
+ return title;
+
+ // see if there is a caption
+ Node *tableElement = m_renderer->element();
+ if (tableElement) {
+ HTMLTableCaptionElement* caption = static_cast<HTMLTableElement*>(tableElement)->caption();
+ if (caption)
+ title = caption->innerText();
+ }
+
+ // try the standard
+ if (title.isEmpty())
+ title = AccessibilityRenderObject::title();
+
+ return title;
+}
+
+bool AccessibilityTable::isDataTable() const
+{
+ if (!m_renderer)
+ return false;
+
+ return m_isAccessibilityTable;
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/AccessibilityTable.h b/WebCore/page/AccessibilityTable.h
new file mode 100644
index 0000000..b98b6b7
--- /dev/null
+++ b/WebCore/page/AccessibilityTable.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 AccessibilityTable_h
+#define AccessibilityTable_h
+
+#include "AccessibilityRenderObject.h"
+
+namespace WebCore {
+
+class String;
+class AccessibilityTableCell;
+class AccessibilityTableHeaderContainer;
+
+class AccessibilityTable : public AccessibilityRenderObject {
+
+private:
+ AccessibilityTable(RenderObject*);
+public:
+ static PassRefPtr<AccessibilityTable> create(RenderObject*);
+ virtual ~AccessibilityTable();
+
+ virtual bool isDataTable() const;
+ virtual AccessibilityRole roleValue() const;
+
+ virtual bool accessibilityIsIgnored() const;
+
+ virtual void addChildren();
+ virtual void clearChildren();
+
+ AccessibilityChildrenVector& columns();
+ AccessibilityChildrenVector& rows();
+
+ const unsigned columnCount();
+ const unsigned rowCount();
+
+ virtual String title() const;
+
+ // all the cells in the table
+ void cells(AccessibilityChildrenVector&);
+ AccessibilityTableCell* cellForColumnAndRow(unsigned column, unsigned row);
+
+ void columnHeaders(AccessibilityChildrenVector&);
+ void rowHeaders(AccessibilityChildrenVector&);
+
+ // an object that contains, as children, all the objects that act as headers
+ AccessibilityObject* headerContainer();
+
+private:
+ AccessibilityChildrenVector m_rows;
+ AccessibilityChildrenVector m_columns;
+
+ AccessibilityTableHeaderContainer* m_headerContainer;
+ mutable bool m_isAccessibilityTable;
+
+ bool isTableExposableThroughAccessibility();
+};
+
+} // namespace WebCore
+
+#endif // AccessibilityTable_h
diff --git a/WebCore/page/AccessibilityTableCell.cpp b/WebCore/page/AccessibilityTableCell.cpp
new file mode 100644
index 0000000..2062a88
--- /dev/null
+++ b/WebCore/page/AccessibilityTableCell.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AccessibilityTableCell.h"
+
+#include "AXObjectCache.h"
+#include "RenderObject.h"
+#include "RenderTableCell.h"
+
+using namespace std;
+
+namespace WebCore {
+
+AccessibilityTableCell::AccessibilityTableCell(RenderObject* renderer)
+ : AccessibilityRenderObject(renderer)
+{
+}
+
+AccessibilityTableCell::~AccessibilityTableCell()
+{
+}
+
+PassRefPtr<AccessibilityTableCell> AccessibilityTableCell::create(RenderObject* renderer)
+{
+ return adoptRef(new AccessibilityTableCell(renderer));
+}
+
+bool AccessibilityTableCell::accessibilityIsIgnored() const
+{
+ if (!isTableCell())
+ return AccessibilityRenderObject::accessibilityIsIgnored();
+
+ return false;
+}
+
+bool AccessibilityTableCell::isTableCell() const
+{
+ if (!m_renderer)
+ return false;
+
+ AccessibilityObject* renderTable = axObjectCache()->get(static_cast<RenderTableCell*>(m_renderer)->table());
+ if (!renderTable->isDataTable())
+ return false;
+
+ return true;
+}
+
+AccessibilityRole AccessibilityTableCell::roleValue() const
+{
+ if (!isTableCell())
+ return AccessibilityRenderObject::roleValue();
+
+ return CellRole;
+}
+
+void AccessibilityTableCell::rowIndexRange(pair<int, int>& rowRange)
+{
+ if (!m_renderer)
+ return;
+
+ RenderTableCell *renderCell = static_cast<RenderTableCell*>(m_renderer);
+ rowRange.first = renderCell->row();
+ rowRange.second = renderCell->rowSpan();
+
+ // since our table might have multiple sections, we have to offset our row appropriately
+ RenderTableSection* section = renderCell->section();
+ RenderTable* table = renderCell->table();
+ if (!table || !section)
+ return;
+
+ RenderTableSection* tableSection = table->header();
+ if (!tableSection)
+ tableSection = table->firstBody();
+
+ unsigned rowOffset = 0;
+ while (tableSection) {
+ if (tableSection == section)
+ break;
+ rowOffset += tableSection->numRows();
+ tableSection = table->sectionBelow(tableSection, true);
+ }
+
+ rowRange.first += rowOffset;
+}
+
+void AccessibilityTableCell::columnIndexRange(pair<int, int>& columnRange)
+{
+ if (!m_renderer)
+ return;
+
+ RenderTableCell *renderCell = static_cast<RenderTableCell*>(m_renderer);
+ columnRange.first = renderCell->col();
+ columnRange.second = renderCell->colSpan();
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/AccessibilityTableCell.h b/WebCore/page/AccessibilityTableCell.h
new file mode 100644
index 0000000..e77dfb2
--- /dev/null
+++ b/WebCore/page/AccessibilityTableCell.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 AccessibilityTableCell_h
+#define AccessibilityTableCell_h
+
+#include "AccessibilityRenderObject.h"
+
+namespace WebCore {
+
+class AccessibilityTableCell : public AccessibilityRenderObject {
+
+private:
+ AccessibilityTableCell(RenderObject*);
+public:
+ static PassRefPtr<AccessibilityTableCell> create(RenderObject*);
+ virtual ~AccessibilityTableCell();
+
+ virtual bool isTableCell() const;
+ virtual AccessibilityRole roleValue() const;
+
+ virtual bool accessibilityIsIgnored() const;
+
+ // fills in the start location and row span of cell
+ void rowIndexRange(pair<int, int>& rowRange);
+ // fills in the start location and column span of cell
+ void columnIndexRange(pair<int, int>& columnRange);
+
+private:
+ int m_rowIndex;
+
+};
+
+} // namespace WebCore
+
+#endif // AccessibilityTableCell_h
diff --git a/WebCore/page/AccessibilityTableColumn.cpp b/WebCore/page/AccessibilityTableColumn.cpp
new file mode 100644
index 0000000..6e03af9
--- /dev/null
+++ b/WebCore/page/AccessibilityTableColumn.cpp
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AccessibilityTableColumn.h"
+
+#include "AccessibilityTableCell.h"
+#include "AXObjectCache.h"
+#include "HTMLNames.h"
+#include "RenderTable.h"
+#include "RenderTableSection.h"
+#include "RenderTableCell.h"
+
+using namespace std;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+AccessibilityTableColumn::AccessibilityTableColumn()
+ : m_parentTable(0)
+{
+}
+
+AccessibilityTableColumn::~AccessibilityTableColumn()
+{
+}
+
+PassRefPtr<AccessibilityTableColumn> AccessibilityTableColumn::create()
+{
+ return adoptRef(new AccessibilityTableColumn());
+}
+
+void AccessibilityTableColumn::setParentTable(AccessibilityTable* table)
+{
+ m_parentTable = table;
+
+ clearChildren();
+ addChildren();
+}
+
+IntRect AccessibilityTableColumn::elementRect() const
+{
+ // this will be filled in when addChildren is called
+ return m_columnRect;
+}
+
+IntSize AccessibilityTableColumn::size() const
+{
+ return elementRect().size();
+}
+
+const AccessibilityObject::AccessibilityChildrenVector& AccessibilityTableColumn::children()
+{
+ if (!m_haveChildren)
+ addChildren();
+ return m_children;
+}
+
+AccessibilityObject* AccessibilityTableColumn::headerObject()
+{
+ if (!m_parentTable)
+ return 0;
+
+ RenderTable* table = static_cast<RenderTable*>(m_parentTable->renderer());
+
+ AccessibilityObject* headerObject = 0;
+
+ // try the <thead> section first. this doesn't require th tags
+ headerObject = headerObjectForSection(table->header(), false);
+
+ if (headerObject)
+ return headerObject;
+
+ // now try for <th> tags in the first body
+ headerObject = headerObjectForSection(table->firstBody(), true);
+
+ return headerObject;
+}
+
+AccessibilityObject* AccessibilityTableColumn::headerObjectForSection(RenderTableSection* section, bool thTagRequired)
+{
+ if (!section)
+ return 0;
+
+ int numCols = section->numColumns();
+ if (m_columnIndex >= numCols)
+ return 0;
+
+ RenderTableCell* cell = 0;
+ // also account for cells that have a span
+ for (int testCol = m_columnIndex; testCol >= 0; --testCol) {
+ RenderTableCell* testCell = section->cellAt(0, testCol).cell;
+ if (!testCell)
+ continue;
+
+ // we've reached a cell that doesn't even overlap our column
+ // it can't be our header
+ if ((testCell->col() + (testCell->colSpan()-1)) < m_columnIndex)
+ break;
+
+ Node* node = testCell->element();
+ if (!node)
+ continue;
+
+ if (thTagRequired && !node->hasTagName(thTag))
+ continue;
+
+ cell = testCell;
+ }
+
+ if (!cell)
+ return 0;
+
+ return m_parentTable->axObjectCache()->get(cell);
+}
+
+void AccessibilityTableColumn::addChildren()
+{
+ ASSERT(!m_haveChildren);
+
+ m_haveChildren = true;
+ if (!m_parentTable)
+ return;
+
+ int numRows = m_parentTable->rowCount();
+
+ for (int i = 0; i < numRows; i++) {
+ AccessibilityTableCell* cell = m_parentTable->cellForColumnAndRow(m_columnIndex, i);
+ if (!cell)
+ continue;
+
+ // make sure the last one isn't the same as this one (rowspan cells)
+ if (m_children.size() > 0 && m_children.last() == cell)
+ continue;
+
+ m_children.append(cell);
+ m_columnRect.unite(cell->elementRect());
+ }
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/AccessibilityTableColumn.h b/WebCore/page/AccessibilityTableColumn.h
new file mode 100644
index 0000000..6270398
--- /dev/null
+++ b/WebCore/page/AccessibilityTableColumn.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 AccessibilityTableColumn_h
+#define AccessibilityTableColumn_h
+
+#include "AccessibilityObject.h"
+#include "AccessibilityTable.h"
+#include "IntRect.h"
+
+namespace WebCore {
+
+class RenderTableSection;
+
+class AccessibilityTableColumn : public AccessibilityObject {
+
+private:
+ AccessibilityTableColumn();
+public:
+ static PassRefPtr<AccessibilityTableColumn> create();
+ virtual ~AccessibilityTableColumn();
+
+ void setParentTable(AccessibilityTable*);
+ virtual AccessibilityObject* parentObject() const { return m_parentTable; }
+ AccessibilityObject* headerObject();
+
+ virtual AccessibilityRole roleValue() const { return ColumnRole; }
+ virtual bool accessibilityIsIgnored() const { return false; }
+ virtual bool isTableColumn() const { return true; }
+
+ void setColumnIndex(int columnIndex) { m_columnIndex = columnIndex; }
+ int columnIndex() const { return m_columnIndex; }
+
+ virtual const AccessibilityChildrenVector& children();
+ virtual void addChildren();
+
+ virtual IntSize size() const;
+ virtual IntRect elementRect() const;
+
+private:
+ AccessibilityTable* m_parentTable;
+ int m_columnIndex;
+ IntRect m_columnRect;
+
+ AccessibilityObject* headerObjectForSection(RenderTableSection*, bool thTagRequired);
+};
+
+} // namespace WebCore
+
+#endif // AccessibilityTableColumn_h
diff --git a/WebCore/page/AccessibilityTableHeaderContainer.cpp b/WebCore/page/AccessibilityTableHeaderContainer.cpp
new file mode 100644
index 0000000..af9de39
--- /dev/null
+++ b/WebCore/page/AccessibilityTableHeaderContainer.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AccessibilityTableHeaderContainer.h"
+
+#include "AccessibilityTable.h"
+#include "AXObjectCache.h"
+
+using namespace std;
+
+namespace WebCore {
+
+AccessibilityTableHeaderContainer::AccessibilityTableHeaderContainer()
+ : m_parentTable(0)
+{
+}
+
+AccessibilityTableHeaderContainer::~AccessibilityTableHeaderContainer()
+{
+}
+
+PassRefPtr<AccessibilityTableHeaderContainer> AccessibilityTableHeaderContainer::create()
+{
+ return adoptRef(new AccessibilityTableHeaderContainer());
+}
+
+const AccessibilityObject::AccessibilityChildrenVector& AccessibilityTableHeaderContainer::children()
+{
+ if (!m_haveChildren)
+ addChildren();
+ return m_children;
+}
+
+IntRect AccessibilityTableHeaderContainer::elementRect() const
+{
+ // this will be filled in when addChildren is called
+ return m_headerRect;
+}
+
+IntSize AccessibilityTableHeaderContainer::size() const
+{
+ return elementRect().size();
+}
+
+void AccessibilityTableHeaderContainer::addChildren()
+{
+ ASSERT(!m_haveChildren);
+
+ m_haveChildren = true;
+ if (!m_parentTable || !m_parentTable->isDataTable())
+ return;
+
+ static_cast<AccessibilityTable*>(m_parentTable)->columnHeaders(m_children);
+
+ unsigned length = m_children.size();
+ for (unsigned k = 0; k < length; ++k) {
+ m_headerRect.unite(m_children[k]->elementRect());
+ }
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/AccessibilityTableHeaderContainer.h b/WebCore/page/AccessibilityTableHeaderContainer.h
new file mode 100644
index 0000000..8a9448a
--- /dev/null
+++ b/WebCore/page/AccessibilityTableHeaderContainer.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 AccessibilityTableHeaderContainer_h
+#define AccessibilityTableHeaderContainer_h
+
+#include "AccessibilityObject.h"
+#include "AccessibilityTable.h"
+#include "IntRect.h"
+
+namespace WebCore {
+
+class AccessibilityTableHeaderContainer : public AccessibilityObject {
+
+private:
+ AccessibilityTableHeaderContainer();
+public:
+ static PassRefPtr<AccessibilityTableHeaderContainer> create();
+ virtual ~AccessibilityTableHeaderContainer();
+
+ virtual AccessibilityRole roleValue() const { return TableHeaderContainerRole; }
+
+ void setParentTable(AccessibilityTable* table) { m_parentTable = table; }
+ virtual AccessibilityObject* parentObject() const { return m_parentTable; }
+
+ virtual bool accessibilityIsIgnored() const { return false; }
+
+ virtual const AccessibilityChildrenVector& children();
+ virtual void addChildren();
+
+ virtual IntSize size() const;
+ virtual IntRect elementRect() const;
+
+private:
+ AccessibilityTable* m_parentTable;
+ IntRect m_headerRect;
+
+};
+
+} // namespace WebCore
+
+#endif // AccessibilityTableHeaderContainer_h
diff --git a/WebCore/page/AccessibilityTableRow.cpp b/WebCore/page/AccessibilityTableRow.cpp
new file mode 100644
index 0000000..caccff5
--- /dev/null
+++ b/WebCore/page/AccessibilityTableRow.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AccessibilityTableRow.h"
+
+#include "AccessibilityTableCell.h"
+#include "AXObjectCache.h"
+#include "HTMLNames.h"
+#include "HTMLTableRowElement.h"
+#include "RenderObject.h"
+#include "RenderTableCell.h"
+#include "RenderTableRow.h"
+
+using namespace std;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+AccessibilityTableRow::AccessibilityTableRow(RenderObject* renderer)
+ : AccessibilityRenderObject(renderer)
+{
+}
+
+AccessibilityTableRow::~AccessibilityTableRow()
+{
+}
+
+PassRefPtr<AccessibilityTableRow> AccessibilityTableRow::create(RenderObject* renderer)
+{
+ return adoptRef(new AccessibilityTableRow(renderer));
+}
+
+AccessibilityRole AccessibilityTableRow::roleValue() const
+{
+ if (!isTableRow())
+ return AccessibilityRenderObject::roleValue();
+
+ return RowRole;
+}
+
+bool AccessibilityTableRow::isTableRow() const
+{
+ if (!m_renderer)
+ return true;
+
+ AccessibilityObject* renderTable = axObjectCache()->get(static_cast<RenderTableRow*>(m_renderer)->table());
+ if (!renderTable->isDataTable())
+ return false;
+
+ return true;
+}
+
+bool AccessibilityTableRow::accessibilityIsIgnored() const
+{
+ if (!isTableRow())
+ return AccessibilityRenderObject::accessibilityIsIgnored();
+
+ return false;
+}
+
+AccessibilityObject* AccessibilityTableRow::headerObject()
+{
+ AccessibilityChildrenVector rowChildren = children();
+ if (!rowChildren.size())
+ return 0;
+
+ // check the first element in the row to see if it is a TH element
+ AccessibilityObject* cell = rowChildren[0].get();
+ if (!cell->isTableCell())
+ return 0;
+
+ RenderObject* cellRenderer = static_cast<AccessibilityTableCell*>(cell)->renderer();
+ if (!cellRenderer)
+ return 0;
+
+ Node* cellNode = cellRenderer->element();
+ if (!cellNode || !cellNode->hasTagName(thTag))
+ return 0;
+
+ return cell;
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/AccessibilityTableRow.h b/WebCore/page/AccessibilityTableRow.h
new file mode 100644
index 0000000..0ec7f04
--- /dev/null
+++ b/WebCore/page/AccessibilityTableRow.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 AccessibilityTableRow_h
+#define AccessibilityTableRow_h
+
+#include "AccessibilityRenderObject.h"
+
+namespace WebCore {
+
+class AccessibilityTableRow : public AccessibilityRenderObject {
+
+private:
+ AccessibilityTableRow(RenderObject*);
+public:
+ static PassRefPtr<AccessibilityTableRow> create(RenderObject*);
+ virtual ~AccessibilityTableRow();
+
+ virtual bool isTableRow() const;
+ virtual AccessibilityRole roleValue() const;
+
+ // retrieves the "row" header (a th tag in the rightmost column)
+ AccessibilityObject* headerObject();
+
+ virtual bool accessibilityIsIgnored() const;
+
+ void setRowIndex(int rowIndex) { m_rowIndex = rowIndex; }
+ int rowIndex() const { return m_rowIndex; }
+
+ // allows the table to add other children that may not originate
+ // in the row, but their col/row spans overlap into it
+ void appendChild(AccessibilityObject*);
+
+private:
+ int m_rowIndex;
+};
+
+} // namespace WebCore
+
+#endif // AccessibilityTableRow_h
diff --git a/WebCore/page/AnimationController.cpp b/WebCore/page/AnimationController.cpp
deleted file mode 100644
index 0c78364..0000000
--- a/WebCore/page/AnimationController.cpp
+++ /dev/null
@@ -1,606 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "AnimationController.h"
-
-#include "CSSPropertyNames.h"
-#include "Document.h"
-#include "FloatConversion.h"
-#include "Frame.h"
-#include "RenderObject.h"
-#include "RenderStyle.h"
-#include "SystemTime.h"
-#include "Timer.h"
-
-namespace WebCore {
-
-static const double cAnimationTimerDelay = 0.025;
-
-struct CurveData {
- CurveData(double p1x, double p1y, double p2x, double p2y)
- {
- // Calculate the polynomial coefficients, implicit first and last control points are (0,0) and (1,1).
- cx = 3.0 * p1x;
- bx = 3.0 * (p2x - p1x) - cx;
- ax = 1.0 - cx -bx;
-
- cy = 3.0 * p1y;
- by = 3.0 * (p2y - p1y) - cy;
- ay = 1.0 - cy - by;
- }
-
- double sampleCurveX(double t)
- {
- // `ax t^3 + bx t^2 + cx t' expanded using Horner's rule.
- return ((ax * t + bx) * t + cx) * t;
- }
-
- double sampleCurveY(double t)
- {
- return ((ay * t + by) * t + cy) * t;
- }
-
- double sampleCurveDerivativeX(double t)
- {
- return (3.0 * ax * t + 2.0 * bx) * t + cx;
- }
-
- // Given an x value, find a parametric value it came from.
- double solveCurveX(double x, double epsilon)
- {
- double t0;
- double t1;
- double t2;
- double x2;
- double d2;
- int i;
-
- // First try a few iterations of Newton's method -- normally very fast.
- for (t2 = x, i = 0; i < 8; i++) {
- x2 = sampleCurveX(t2) - x;
- if (fabs (x2) < epsilon)
- return t2;
- d2 = sampleCurveDerivativeX(t2);
- if (fabs(d2) < 1e-6)
- break;
- t2 = t2 - x2 / d2;
- }
-
- // Fall back to the bisection method for reliability.
- t0 = 0.0;
- t1 = 1.0;
- t2 = x;
-
- if (t2 < t0)
- return t0;
- if (t2 > t1)
- return t1;
-
- while (t0 < t1) {
- x2 = sampleCurveX(t2);
- if (fabs(x2 - x) < epsilon)
- return t2;
- if (x > x2)
- t0 = t2;
- else
- t1 = t2;
- t2 = (t1 - t0) * .5 + t0;
- }
-
- // Failure.
- return t2;
- }
-
-private:
- double ax;
- double bx;
- double cx;
-
- double ay;
- double by;
- double cy;
-};
-
-// The epsilon value we pass to solveCurveX given that the animation is going to run over |dur| seconds. The longer the
-// animation, the more precision we need in the timing function result to avoid ugly discontinuities.
-static inline double solveEpsilon(double duration) { return 1. / (200. * duration); }
-
-static inline double solveCubicBezierFunction(double p1x, double p1y, double p2x, double p2y, double t, double duration)
-{
- // Convert from input time to parametric value in curve, then from
- // that to output time.
- CurveData c(p1x, p1y, p2x, p2y);
- t = c.solveCurveX(t, solveEpsilon(duration));
- t = c.sampleCurveY(t);
- return t;
-}
-
-class CompositeImplicitAnimation;
-
-class ImplicitAnimation : public Noncopyable {
-public:
- ImplicitAnimation(const Transition*);
- ~ImplicitAnimation();
-
- void animate(CompositeImplicitAnimation*, RenderObject*, RenderStyle* currentStyle, RenderStyle* targetStyle, RenderStyle*& animatedStyle);
-
- void reset(RenderObject*, RenderStyle* from, RenderStyle* to);
-
- double progress() const;
-
- bool finished() const { return m_finished; }
-
-private:
- // The two styles that we are blending.
- RenderStyle* m_fromStyle;
- RenderStyle* m_toStyle;
-
- int m_property;
- TimingFunction m_function;
- double m_duration;
-
- int m_repeatCount;
- int m_iteration;
-
- bool m_finished;
- double m_startTime;
- bool m_paused;
- double m_pauseTime;
-};
-
-class CompositeImplicitAnimation : public Noncopyable {
-public:
- ~CompositeImplicitAnimation() { deleteAllValues(m_animations); }
-
- RenderStyle* animate(RenderObject*, RenderStyle* currentStyle, RenderStyle* targetStyle);
-
- bool animating() const;
-
- bool hasAnimationForProperty(int prop) const { return m_animations.contains(prop); }
-
- void reset(RenderObject*);
-
-private:
- HashMap<int, ImplicitAnimation*> m_animations;
-};
-
-ImplicitAnimation::ImplicitAnimation(const Transition* transition)
-: m_fromStyle(0)
-, m_toStyle(0)
-, m_property(transition->transitionProperty())
-, m_function(transition->transitionTimingFunction())
-, m_duration(transition->transitionDuration() / 1000.0)
-, m_repeatCount(transition->transitionRepeatCount())
-, m_iteration(0)
-, m_finished(false)
-, m_startTime(currentTime())
-, m_paused(false)
-, m_pauseTime(m_startTime)
-{
-}
-
-ImplicitAnimation::~ImplicitAnimation()
-{
- ASSERT(!m_fromStyle && !m_toStyle);
-}
-
-void ImplicitAnimation::reset(RenderObject* renderer, RenderStyle* from, RenderStyle* to)
-{
- if (m_fromStyle)
- m_fromStyle->deref(renderer->renderArena());
- if (m_toStyle)
- m_toStyle->deref(renderer->renderArena());
- m_fromStyle = from;
- if (m_fromStyle)
- m_fromStyle->ref();
- m_toStyle = to;
- if (m_toStyle)
- m_toStyle->ref();
- m_finished = false;
- if (from || to)
- m_startTime = currentTime();
-}
-
-double ImplicitAnimation::progress() const
-{
- double elapsedTime = currentTime() - m_startTime;
-
- if (m_finished || !m_duration || elapsedTime >= m_duration)
- return 1.0;
-
- if (m_function.type() == LinearTimingFunction)
- return elapsedTime / m_duration;
-
- // Cubic bezier.
- return solveCubicBezierFunction(m_function.x1(), m_function.y1(),
- m_function.x2(), m_function.y2(),
- elapsedTime / m_duration, m_duration);
-}
-
-static inline int blendFunc(int from, int to, double progress)
-{
- return int(from + (to - from) * progress);
-}
-
-static inline double blendFunc(double from, double to, double progress)
-{
- return from + (to - from) * progress;
-}
-
-static inline float blendFunc(float from, float to, double progress)
-{
- return narrowPrecisionToFloat(from + (to - from) * progress);
-}
-
-static inline Color blendFunc(const Color& from, const Color& to, double progress)
-{
- return Color(blendFunc(from.red(), to.red(), progress),
- blendFunc(from.green(), to.green(), progress),
- blendFunc(from.blue(), to.blue(), progress),
- blendFunc(from.alpha(), to.alpha(), progress));
-}
-
-static inline Length blendFunc(const Length& from, const Length& to, double progress)
-{
- return to.blend(from, progress);
-}
-
-static inline IntSize blendFunc(const IntSize& from, const IntSize& to, double progress)
-{
- return IntSize(blendFunc(from.width(), to.width(), progress),
- blendFunc(from.height(), to.height(), progress));
-}
-
-static inline ShadowData* blendFunc(const ShadowData* from, const ShadowData* to, double progress)
-{
- ASSERT(from && to);
- return new ShadowData(blendFunc(from->x, to->x, progress), blendFunc(from->y, to->y, progress), blendFunc(from->blur, to->blur, progress), blendFunc(from->color, to->color, progress));
-}
-
-static inline TransformOperations blendFunc(const TransformOperations& from, const TransformOperations& to, double progress)
-{
- // Blend any operations whose types actually match up. Otherwise don't bother.
- unsigned fromSize = from.size();
- unsigned toSize = to.size();
- unsigned size = max(fromSize, toSize);
- TransformOperations result;
- for (unsigned i = 0; i < size; i++) {
- TransformOperation* fromOp = i < fromSize ? from[i].get() : 0;
- TransformOperation* toOp = i < toSize ? to[i].get() : 0;
- TransformOperation* blendedOp = toOp ? toOp->blend(fromOp, progress) : fromOp->blend(0, progress, true);
- result.append(blendedOp);
- }
- return result;
-}
-
-static inline EVisibility blendFunc(EVisibility from, EVisibility to, double progress)
-{
- // Any non-zero result means we consider the object to be visible. Only at 0 do we consider the object to be
- // invisible. The invisible value we use (HIDDEN vs. COLLAPSE) depends on the specified from/to values.
- double fromVal = from == VISIBLE ? 1. : 0.;
- double toVal = to == VISIBLE ? 1. : 0.;
- if (fromVal == toVal)
- return to;
- double result = blendFunc(fromVal, toVal, progress);
- return result > 0. ? VISIBLE : (to != VISIBLE ? to : from);
-}
-
-#define BLEND(prop, getter, setter) \
- if (m_property == prop && m_toStyle->getter() != targetStyle->getter()) \
- reset(renderer, currentStyle, targetStyle); \
- \
- if ((m_property == cAnimateAll && !animation->hasAnimationForProperty(prop)) || m_property == prop) { \
- if (m_fromStyle->getter() != m_toStyle->getter()) {\
- m_finished = false; \
- if (!animatedStyle) \
- animatedStyle = new (renderer->renderArena()) RenderStyle(*targetStyle); \
- animatedStyle->setter(blendFunc(m_fromStyle->getter(), m_toStyle->getter(), progress()));\
- if (m_property == prop) \
- return; \
- }\
- }\
-
-#define BLEND_MAYBE_INVALID_COLOR(prop, getter, setter) \
- if (m_property == prop && m_toStyle->getter() != targetStyle->getter()) \
- reset(renderer, currentStyle, targetStyle); \
- \
- if ((m_property == cAnimateAll && !animation->hasAnimationForProperty(prop)) || m_property == prop) { \
- Color fromColor = m_fromStyle->getter(); \
- Color toColor = m_toStyle->getter(); \
- if (!fromColor.isValid()) \
- fromColor = m_fromStyle->color(); \
- if (!toColor.isValid()) \
- toColor = m_toStyle->color(); \
- if (fromColor != toColor) {\
- m_finished = false; \
- if (!animatedStyle) \
- animatedStyle = new (renderer->renderArena()) RenderStyle(*targetStyle); \
- animatedStyle->setter(blendFunc(fromColor, toColor, progress()));\
- if (m_property == prop) \
- return; \
- }\
- }\
-
-#define BLEND_SHADOW(prop, getter, setter) \
- if (m_property == prop && (!m_toStyle->getter() || !targetStyle->getter() || *m_toStyle->getter() != *targetStyle->getter())) \
- reset(renderer, currentStyle, targetStyle); \
- \
- if ((m_property == cAnimateAll && !animation->hasAnimationForProperty(prop)) || m_property == prop) { \
- if (m_fromStyle->getter() && m_toStyle->getter() && *m_fromStyle->getter() != *m_toStyle->getter()) {\
- m_finished = false; \
- if (!animatedStyle) \
- animatedStyle = new (renderer->renderArena()) RenderStyle(*targetStyle); \
- animatedStyle->setter(blendFunc(m_fromStyle->getter(), m_toStyle->getter(), progress()));\
- if (m_property == prop) \
- return; \
- }\
- }
-
-void ImplicitAnimation::animate(CompositeImplicitAnimation* animation, RenderObject* renderer, RenderStyle* currentStyle, RenderStyle* targetStyle, RenderStyle*& animatedStyle)
-{
- // FIXME: If we have no transition-property, then the only way to tell if our goal state changed is to check
- // every single animatable property. For now we'll just diff the styles to ask that question,
- // but we should really exclude non-animatable properties.
- if (!m_toStyle || (m_property == cAnimateAll && targetStyle->diff(m_toStyle)))
- reset(renderer, currentStyle, targetStyle);
-
- // FIXME: Blow up shorthands so that they can be honored.
- m_finished = true;
- BLEND(CSS_PROP_LEFT, left, setLeft);
- BLEND(CSS_PROP_RIGHT, right, setRight);
- BLEND(CSS_PROP_TOP, top, setTop);
- BLEND(CSS_PROP_BOTTOM, bottom, setBottom);
- BLEND(CSS_PROP_WIDTH, width, setWidth);
- BLEND(CSS_PROP_HEIGHT, height, setHeight);
- BLEND(CSS_PROP_BORDER_LEFT_WIDTH, borderLeftWidth, setBorderLeftWidth);
- BLEND(CSS_PROP_BORDER_RIGHT_WIDTH, borderRightWidth, setBorderRightWidth);
- BLEND(CSS_PROP_BORDER_TOP_WIDTH, borderTopWidth, setBorderTopWidth);
- BLEND(CSS_PROP_BORDER_BOTTOM_WIDTH, borderBottomWidth, setBorderBottomWidth);
- BLEND(CSS_PROP_MARGIN_LEFT, marginLeft, setMarginLeft);
- BLEND(CSS_PROP_MARGIN_RIGHT, marginRight, setMarginRight);
- BLEND(CSS_PROP_MARGIN_TOP, marginTop, setMarginTop);
- BLEND(CSS_PROP_MARGIN_BOTTOM, marginBottom, setMarginBottom);
- BLEND(CSS_PROP_PADDING_LEFT, paddingLeft, setPaddingLeft);
- BLEND(CSS_PROP_PADDING_RIGHT, paddingRight, setPaddingRight);
- BLEND(CSS_PROP_PADDING_TOP, paddingTop, setPaddingTop);
- BLEND(CSS_PROP_PADDING_BOTTOM, paddingBottom, setPaddingBottom);
- BLEND(CSS_PROP_OPACITY, opacity, setOpacity);
- BLEND(CSS_PROP_COLOR, color, setColor);
- BLEND(CSS_PROP_BACKGROUND_COLOR, backgroundColor, setBackgroundColor);
- BLEND_MAYBE_INVALID_COLOR(CSS_PROP__WEBKIT_COLUMN_RULE_COLOR, columnRuleColor, setColumnRuleColor);
- BLEND(CSS_PROP__WEBKIT_COLUMN_RULE_WIDTH, columnRuleWidth, setColumnRuleWidth);
- BLEND(CSS_PROP__WEBKIT_COLUMN_GAP, columnGap, setColumnGap);
- BLEND(CSS_PROP__WEBKIT_COLUMN_COUNT, columnCount, setColumnCount);
- BLEND(CSS_PROP__WEBKIT_COLUMN_WIDTH, columnWidth, setColumnWidth);
- BLEND_MAYBE_INVALID_COLOR(CSS_PROP__WEBKIT_TEXT_STROKE_COLOR, textStrokeColor, setTextStrokeColor);
- BLEND_MAYBE_INVALID_COLOR(CSS_PROP__WEBKIT_TEXT_FILL_COLOR, textFillColor, setTextFillColor);
- BLEND(CSS_PROP__WEBKIT_BORDER_HORIZONTAL_SPACING, horizontalBorderSpacing, setHorizontalBorderSpacing);
- BLEND(CSS_PROP__WEBKIT_BORDER_VERTICAL_SPACING, verticalBorderSpacing, setVerticalBorderSpacing);
- BLEND_MAYBE_INVALID_COLOR(CSS_PROP_BORDER_LEFT_COLOR, borderLeftColor, setBorderLeftColor);
- BLEND_MAYBE_INVALID_COLOR(CSS_PROP_BORDER_RIGHT_COLOR, borderRightColor, setBorderRightColor);
- BLEND_MAYBE_INVALID_COLOR(CSS_PROP_BORDER_TOP_COLOR, borderTopColor, setBorderTopColor);
- BLEND_MAYBE_INVALID_COLOR(CSS_PROP_BORDER_BOTTOM_COLOR, borderBottomColor, setBorderBottomColor);
- BLEND(CSS_PROP_Z_INDEX, zIndex, setZIndex);
- BLEND(CSS_PROP_LINE_HEIGHT, lineHeight, setLineHeight);
- BLEND_MAYBE_INVALID_COLOR(CSS_PROP_OUTLINE_COLOR, outlineColor, setOutlineColor);
- BLEND(CSS_PROP_OUTLINE_OFFSET, outlineOffset, setOutlineOffset);
- BLEND(CSS_PROP_OUTLINE_WIDTH, outlineWidth, setOutlineWidth);
- BLEND(CSS_PROP_LETTER_SPACING, letterSpacing, setLetterSpacing);
- BLEND(CSS_PROP_WORD_SPACING, wordSpacing, setWordSpacing);
- BLEND_SHADOW(CSS_PROP__WEBKIT_BOX_SHADOW, boxShadow, setBoxShadow);
- BLEND_SHADOW(CSS_PROP_TEXT_SHADOW, textShadow, setTextShadow);
- BLEND(CSS_PROP__WEBKIT_TRANSFORM, transform, setTransform);
- BLEND(CSS_PROP__WEBKIT_TRANSFORM_ORIGIN_X, transformOriginX, setTransformOriginX);
- BLEND(CSS_PROP__WEBKIT_TRANSFORM_ORIGIN_Y, transformOriginY, setTransformOriginY);
- BLEND(CSS_PROP__WEBKIT_BORDER_TOP_LEFT_RADIUS, borderTopLeftRadius, setBorderTopLeftRadius);
- BLEND(CSS_PROP__WEBKIT_BORDER_TOP_RIGHT_RADIUS, borderTopRightRadius, setBorderTopRightRadius);
- BLEND(CSS_PROP__WEBKIT_BORDER_BOTTOM_LEFT_RADIUS, borderBottomLeftRadius, setBorderBottomLeftRadius);
- BLEND(CSS_PROP__WEBKIT_BORDER_BOTTOM_RIGHT_RADIUS, borderBottomRightRadius, setBorderBottomRightRadius);
- BLEND(CSS_PROP_VISIBILITY, visibility, setVisibility);
-}
-
-RenderStyle* CompositeImplicitAnimation::animate(RenderObject* renderer, RenderStyle* currentStyle, RenderStyle* targetStyle)
-{
- // Get the animation layers from the target style.
- // For each one, we need to create a new animation unless one exists already (later occurrences of duplicate
- // triggers in the layer list get ignored).
- if (m_animations.isEmpty()) {
- for (const Transition* transition = targetStyle->transitions(); transition; transition = transition->next()) {
- int property = transition->transitionProperty();
- int duration = transition->transitionDuration();
- int repeatCount = transition->transitionRepeatCount();
- if (property && duration && repeatCount && !m_animations.contains(property)) {
- ImplicitAnimation* animation = new ImplicitAnimation(transition);
- m_animations.set(property, animation);
- }
- }
- }
-
- // Now that we have animation objects ready, let them know about the new goal state. We want them
- // to fill in a RenderStyle*& only if needed.
- RenderStyle* result = 0;
- HashMap<int, ImplicitAnimation*>::iterator end = m_animations.end();
- for (HashMap<int, ImplicitAnimation*>::iterator it = m_animations.begin(); it != end; ++it)
- it->second->animate(this, renderer, currentStyle, targetStyle, result);
-
- if (result)
- return result;
-
- return targetStyle;
-}
-
-bool CompositeImplicitAnimation::animating() const
-{
- HashMap<int, ImplicitAnimation*>::const_iterator end = m_animations.end();
- for (HashMap<int, ImplicitAnimation*>::const_iterator it = m_animations.begin(); it != end; ++it)
- if (!it->second->finished())
- return true;
- return false;
-}
-
-void CompositeImplicitAnimation::reset(RenderObject* renderer)
-{
- HashMap<int, ImplicitAnimation*>::const_iterator end = m_animations.end();
- for (HashMap<int, ImplicitAnimation*>::const_iterator it = m_animations.begin(); it != end; ++it)
- it->second->reset(renderer, 0, 0);
-}
-
-class AnimationControllerPrivate {
-public:
- AnimationControllerPrivate(Frame*);
- ~AnimationControllerPrivate();
-
- CompositeImplicitAnimation* get(RenderObject*);
- bool clear(RenderObject*);
-
- void timerFired(Timer<AnimationControllerPrivate>*);
- void updateTimer();
-
- bool hasImplicitAnimations() const { return !m_animations.isEmpty(); }
-
-private:
- HashMap<RenderObject*, CompositeImplicitAnimation*> m_animations;
- Timer<AnimationControllerPrivate> m_timer;
- Frame* m_frame;
-};
-
-AnimationControllerPrivate::AnimationControllerPrivate(Frame* frame)
- : m_timer(this, &AnimationControllerPrivate::timerFired)
- , m_frame(frame)
-{
-}
-
-AnimationControllerPrivate::~AnimationControllerPrivate()
-{
- deleteAllValues(m_animations);
-}
-
-CompositeImplicitAnimation* AnimationControllerPrivate::get(RenderObject* renderer)
-{
- CompositeImplicitAnimation* animation = m_animations.get(renderer);
- if (!animation) {
- animation = new CompositeImplicitAnimation();
- m_animations.set(renderer, animation);
- }
- return animation;
-}
-
-bool AnimationControllerPrivate::clear(RenderObject* renderer)
-{
- CompositeImplicitAnimation* animation = m_animations.take(renderer);
- if (!animation)
- return false;
- animation->reset(renderer);
- delete animation;
- return true;
-}
-
-void AnimationControllerPrivate::updateTimer()
-{
- bool animating = false;
- HashMap<RenderObject*, CompositeImplicitAnimation*>::iterator end = m_animations.end();
- for (HashMap<RenderObject*, CompositeImplicitAnimation*>::iterator it = m_animations.begin(); it != end; ++it) {
- if (it->second->animating()) {
- animating = true;
- break;
- }
- }
-
- if (animating) {
- if (!m_timer.isActive())
- m_timer.startRepeating(cAnimationTimerDelay);
- } else if (m_timer.isActive())
- m_timer.stop();
-}
-
-void AnimationControllerPrivate::timerFired(Timer<AnimationControllerPrivate>* timer)
-{
- // When the timer fires, all we do is call setChanged on all DOM nodes with running animations and then do an immediate
- // updateRendering. It will then call back to us with new information.
- bool animating = false;
- HashMap<RenderObject*, CompositeImplicitAnimation*>::iterator end = m_animations.end();
- for (HashMap<RenderObject*, CompositeImplicitAnimation*>::iterator it = m_animations.begin(); it != end; ++it) {
- if (it->second->animating()) {
- animating = true;
- it->first->element()->setChanged();
- }
- }
-
- m_frame->document()->updateRendering();
-
- updateTimer();
-}
-
-AnimationController::AnimationController(Frame* frame)
-:m_data(new AnimationControllerPrivate(frame))
-{
-
-}
-
-AnimationController::~AnimationController()
-{
- delete m_data;
-}
-
-void AnimationController::cancelImplicitAnimations(RenderObject* renderer)
-{
- if (!m_data->hasImplicitAnimations())
- return;
-
- if (m_data->clear(renderer))
- renderer->element()->setChanged();
-}
-
-RenderStyle* AnimationController::updateImplicitAnimations(RenderObject* renderer, RenderStyle* newStyle)
-{
- // Fetch our current set of implicit animations from a hashtable. We then compare them
- // against the animations in the style and make sure we're in sync. If destination values
- // have changed, we reset the animation. We then do a blend to get new values and we return
- // a new style.
- ASSERT(renderer->element()); // FIXME: We do not animate generated content yet.
-
- CompositeImplicitAnimation* animation = m_data->get(renderer);
- RenderStyle* result = animation->animate(renderer, renderer->style(), newStyle);
- m_data->updateTimer();
- return result;
-}
-
-void AnimationController::suspendAnimations()
-{
- // FIXME: Walk the whole hashtable and call pause on each animation.
- // Kill our timer.
-}
-
-void AnimationController::resumeAnimations()
-{
- // FIXME: Walk the whole hashtable and call resume on each animation.
- // Start our timer.
-}
-
-}
diff --git a/WebCore/page/BarInfo.h b/WebCore/page/BarInfo.h
index 261d3dd..4cbbcfc 100644
--- a/WebCore/page/BarInfo.h
+++ b/WebCore/page/BarInfo.h
@@ -29,6 +29,7 @@
#ifndef BarInfo_h
#define BarInfo_h
+#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
namespace WebCore {
@@ -38,13 +39,15 @@ namespace WebCore {
class BarInfo : public RefCounted<BarInfo> {
public:
enum Type { Locationbar, Menubar, Personalbar, Scrollbars, Statusbar, Toolbar };
-
- BarInfo(Frame*, Type);
+
+ static PassRefPtr<BarInfo> create(Frame* frame, Type type) { return adoptRef(new BarInfo(frame, type)); }
+
void disconnectFrame();
bool visible() const;
private:
+ BarInfo(Frame*, Type);
Frame* m_frame;
Type m_type;
};
diff --git a/WebCore/page/Chrome.cpp b/WebCore/page/Chrome.cpp
index fecbe79..c9b57f2 100644
--- a/WebCore/page/Chrome.cpp
+++ b/WebCore/page/Chrome.cpp
@@ -1,7 +1,6 @@
-// -*- mode: c++; c-basic-offset: 4 -*-
/*
* Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
- * Copyright (C) 2007 Trolltech ASA
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -23,6 +22,9 @@
#include "Chrome.h"
#include "ChromeClient.h"
+#include "DNS.h"
+#include "Document.h"
+#include "FileList.h"
#include "FloatRect.h"
#include "Frame.h"
#include "FrameTree.h"
@@ -32,16 +34,21 @@
#include "HitTestResult.h"
#include "InspectorController.h"
#include "Page.h"
+#include "PageGroup.h"
+#include "PausedTimeouts.h"
#include "ResourceHandle.h"
+#include "ScriptController.h"
+#include "SecurityOrigin.h"
#include "Settings.h"
#include "WindowFeatures.h"
-#include "kjs_window.h"
-#include "PausedTimeouts.h"
-#include "SecurityOrigin.h"
#include <wtf/PassRefPtr.h>
#include <wtf/RefPtr.h>
#include <wtf/Vector.h>
+#if ENABLE(DOM_STORAGE)
+#include "SessionStorage.h"
+#endif
+
namespace WebCore {
using namespace HTMLNames;
@@ -70,6 +77,31 @@ Chrome::~Chrome()
m_client->chromeDestroyed();
}
+void Chrome::repaint(const IntRect& windowRect, bool contentChanged, bool immediate, bool repaintContentOnly)
+{
+ m_client->repaint(windowRect, contentChanged, immediate, repaintContentOnly);
+}
+
+void Chrome::scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
+{
+ m_client->scroll(scrollDelta, rectToScroll, clipRect);
+}
+
+IntPoint Chrome::screenToWindow(const IntPoint& point) const
+{
+ return m_client->screenToWindow(point);
+}
+
+IntRect Chrome::windowToScreen(const IntRect& rect) const
+{
+ return m_client->windowToScreen(rect);
+}
+
+PlatformWidget Chrome::platformWindow() const
+{
+ return m_client->platformWindow();
+}
+
void Chrome::setWindowRect(const FloatRect& rect) const
{
m_client->setWindowRect(rect);
@@ -112,7 +144,15 @@ void Chrome::takeFocus(FocusDirection direction) const
Page* Chrome::createWindow(Frame* frame, const FrameLoadRequest& request, const WindowFeatures& features) const
{
- return m_client->createWindow(frame, request, features);
+ Page* newPage = m_client->createWindow(frame, request, features);
+#if ENABLE(DOM_STORAGE)
+
+ if (newPage) {
+ if (SessionStorage* oldSessionStorage = m_page->sessionStorage(false))
+ newPage->setSessionStorage(oldSessionStorage->copy(newPage));
+ }
+#endif
+ return newPage;
}
void Chrome::show() const
@@ -134,11 +174,6 @@ bool Chrome::canRunModalNow() const
void Chrome::runModal() const
{
- if (m_page->defersLoading()) {
- LOG_ERROR("Tried to run modal in a page when it was deferring loading -- should never happen.");
- return;
- }
-
// Defer callbacks in all the other pages in this group, so we don't try to run JavaScript
// in a way that could interact with this view.
PageGroupLoadDeferrer deferrer(m_page, false);
@@ -192,14 +227,6 @@ void Chrome::setResizable(bool b) const
m_client->setResizable(b);
}
-void Chrome::addMessageToConsole(MessageSource source, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceID)
-{
- if (source == JSMessageSource)
- m_client->addMessageToConsole(message, lineNumber, sourceID);
-
- m_page->inspectorController()->addMessageToConsole(source, level, message, lineNumber, sourceID);
-}
-
bool Chrome::canRunBeforeUnloadConfirmPanel()
{
return m_client->canRunBeforeUnloadConfirmPanel();
@@ -288,24 +315,17 @@ IntRect Chrome::windowResizerRect() const
return m_client->windowResizerRect();
}
-void Chrome::addToDirtyRegion(const IntRect& rect)
-{
- m_client->addToDirtyRegion(rect);
-}
-
-void Chrome::scrollBackingStore(int dx, int dy, const IntRect& scrollViewRect, const IntRect& clipRect)
-{
- m_client->scrollBackingStore(dx, dy, scrollViewRect, clipRect);
-}
-
-void Chrome::updateBackingStore()
-{
- m_client->updateBackingStore();
-}
-
void Chrome::mouseDidMoveOverElement(const HitTestResult& result, unsigned modifierFlags)
{
+ if (result.innerNode()) {
+ Document* document = result.innerNode()->document();
+ if (document && document->isDNSPrefetchEnabled())
+ prefetchDNS(result.absoluteLinkURL().host());
+ }
m_client->mouseDidMoveOverElement(result, modifierFlags);
+
+ if (InspectorController* inspector = m_page->inspectorController())
+ inspector->mouseDidMoveOverElement(result, modifierFlags);
}
void Chrome::setToolTip(const HitTestResult& result)
@@ -331,10 +351,32 @@ void Chrome::setToolTip(const HitTestResult& result)
toolTip = result.absoluteLinkURL().string();
}
- // Lastly we'll consider a tooltip for element with "title" attribute
+ // Next we'll consider a tooltip for element with "title" attribute
if (toolTip.isEmpty())
toolTip = result.title();
+ // Lastly, for <input type="file"> that allow multiple files, we'll consider a tooltip for the selected filenames
+ if (toolTip.isEmpty()) {
+ if (Node* node = result.innerNonSharedNode()) {
+ if (node->hasTagName(inputTag)) {
+ HTMLInputElement* input = static_cast<HTMLInputElement*>(node);
+ if (input->inputType() == HTMLInputElement::FILE) {
+ FileList* files = input->files();
+ unsigned listSize = files->length();
+ if (files && listSize > 1) {
+ Vector<UChar> names;
+ for (size_t i = 0; i < listSize; ++i) {
+ append(names, files->item(i)->fileName());
+ if (i != listSize - 1)
+ names.append('\n');
+ }
+ toolTip = String::adopt(names);
+ }
+ }
+ }
+ }
+ }
+
m_client->setToolTip(toolTip);
}
@@ -343,15 +385,80 @@ void Chrome::print(Frame* frame)
m_client->print(frame);
}
-PageGroupLoadDeferrer::PageGroupLoadDeferrer(Page* page, bool deferSelf)
+void Chrome::disableSuddenTermination()
+{
+ m_client->disableSuddenTermination();
+}
+
+void Chrome::enableSuddenTermination()
+{
+ m_client->enableSuddenTermination();
+}
+
+void Chrome::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> fileChooser)
+{
+ m_client->runOpenPanel(frame, fileChooser);
+}
+// --------
+
+#if ENABLE(DASHBOARD_SUPPORT)
+void ChromeClient::dashboardRegionsChanged()
+{
+}
+#endif
+
+void ChromeClient::populateVisitedLinks()
+{
+}
+
+FloatRect ChromeClient::customHighlightRect(Node*, const AtomicString&, const FloatRect&)
+{
+ return FloatRect();
+}
+
+void ChromeClient::paintCustomHighlight(Node*, const AtomicString&, const FloatRect&, const FloatRect&, bool, bool)
+{
+}
+
+bool ChromeClient::shouldReplaceWithGeneratedFileForUpload(const String&, String&)
{
- const HashSet<Page*>* group = page->frameNamespace();
+ return false;
+}
+
+String ChromeClient::generateReplacementFile(const String&)
+{
+ ASSERT_NOT_REACHED();
+ return String();
+}
+
+void ChromeClient::disableSuddenTermination()
+{
+}
+
+void ChromeClient::enableSuddenTermination()
+{
+}
+
+bool ChromeClient::paintCustomScrollbar(GraphicsContext*, const FloatRect&, ScrollbarControlSize,
+ ScrollbarControlState, ScrollbarPart, bool vertical,
+ float value, float proportion, ScrollbarControlPartMask)
+{
+ return false;
+}
+
+bool ChromeClient::paintCustomScrollCorner(GraphicsContext*, const FloatRect&)
+{
+ return false;
+}
+
+// --------
- if (!group)
- return;
+PageGroupLoadDeferrer::PageGroupLoadDeferrer(Page* page, bool deferSelf)
+{
+ const HashSet<Page*>& pages = page->group().pages();
- HashSet<Page*>::const_iterator end = group->end();
- for (HashSet<Page*>::const_iterator it = group->begin(); it != end; ++it) {
+ HashSet<Page*>::const_iterator end = pages.end();
+ for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) {
Page* otherPage = *it;
if ((deferSelf || otherPage != page)) {
if (!otherPage->defersLoading())
@@ -359,11 +466,10 @@ PageGroupLoadDeferrer::PageGroupLoadDeferrer(Page* page, bool deferSelf)
#if !PLATFORM(MAC)
for (Frame* frame = otherPage->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
- if (KJS::Window* window = KJS::Window::retrieveWindow(frame)) {
- PausedTimeouts* timeouts = window->pauseTimeouts();
-
- m_pausedTimeouts.append(make_pair(frame, timeouts));
- }
+ OwnPtr<PausedTimeouts> timeouts;
+ frame->script()->pauseTimeouts(timeouts);
+ if (timeouts)
+ m_pausedTimeouts.append(make_pair(RefPtr<Frame>(frame), timeouts.release()));
}
#endif
}
@@ -377,19 +483,15 @@ PageGroupLoadDeferrer::PageGroupLoadDeferrer(Page* page, bool deferSelf)
PageGroupLoadDeferrer::~PageGroupLoadDeferrer()
{
- size_t count = m_deferredFrames.size();
- for (size_t i = 0; i < count; ++i)
+ for (size_t i = 0; i < m_deferredFrames.size(); ++i)
if (Page* page = m_deferredFrames[i]->page())
page->setDefersLoading(false);
#if !PLATFORM(MAC)
- count = m_pausedTimeouts.size();
-
- for (size_t i = 0; i < count; i++) {
- KJS::Window* window = KJS::Window::retrieveWindow(m_pausedTimeouts[i].first.get());
- if (window)
- window->resumeTimeouts(m_pausedTimeouts[i].second);
- delete m_pausedTimeouts[i].second;
+ for (size_t i = 0; i < m_pausedTimeouts.size(); i++) {
+ Frame* frame = m_pausedTimeouts[i].first.get();
+ OwnPtr<PausedTimeouts> timeouts(m_pausedTimeouts[i].second);
+ frame->script()->resumeTimeouts(timeouts);
}
#endif
}
diff --git a/WebCore/page/Chrome.h b/WebCore/page/Chrome.h
index 9bc42e0..0dd4013 100644
--- a/WebCore/page/Chrome.h
+++ b/WebCore/page/Chrome.h
@@ -1,4 +1,3 @@
-// -*- mode: c++; c-basic-offset: 4 -*-
/*
* Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
*
@@ -21,9 +20,10 @@
#ifndef Chrome_h
#define Chrome_h
+#include "FileChooser.h"
#include "FocusDirection.h"
+#include "HostWindow.h"
#include <wtf/Forward.h>
-#include <wtf/Noncopyable.h>
#include <wtf/RefPtr.h>
#if PLATFORM(MAC)
@@ -42,32 +42,24 @@ namespace WebCore {
class IntRect;
class Page;
class String;
-
+
struct FrameLoadRequest;
struct WindowFeatures;
- enum MessageSource {
- HTMLMessageSource,
- XMLMessageSource,
- JSMessageSource,
- CSSMessageSource,
- OtherMessageSource
- };
-
- enum MessageLevel {
- TipMessageLevel,
- LogMessageLevel,
- WarningMessageLevel,
- ErrorMessageLevel
- };
-
- class Chrome : Noncopyable {
+ class Chrome : public HostWindow {
public:
Chrome(Page*, ChromeClient*);
~Chrome();
ChromeClient* client() { return m_client; }
+ // HostWindow methods.
+ virtual void repaint(const IntRect&, bool contentChanged, bool immediate = false, bool repaintContentOnly = false);
+ virtual void scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect);
+ virtual IntPoint screenToWindow(const IntPoint&) const;
+ virtual IntRect windowToScreen(const IntRect&) const;
+ virtual PlatformWidget platformWindow() const;
+
void setWindowRect(const FloatRect&) const;
FloatRect windowRect() const;
@@ -102,8 +94,6 @@ namespace WebCore {
void setResizable(bool) const;
- void addMessageToConsole(MessageSource, MessageLevel, const String& message, unsigned lineNumber, const String& sourceID);
-
bool canRunBeforeUnloadConfirmPanel();
bool runBeforeUnloadConfirmPanel(const String& message, Frame* frame);
@@ -111,21 +101,23 @@ namespace WebCore {
void runJavaScriptAlert(Frame*, const String&);
bool runJavaScriptConfirm(Frame*, const String&);
- bool runJavaScriptPrompt(Frame*, const String& message, const String& defaultValue, String& result);
+ bool runJavaScriptPrompt(Frame*, const String& message, const String& defaultValue, String& result);
void setStatusbarText(Frame*, const String&);
bool shouldInterruptJavaScript();
IntRect windowResizerRect() const;
- void addToDirtyRegion(const IntRect&);
- void scrollBackingStore(int dx, int dy, const IntRect& scrollViewRect, const IntRect& clipRect);
- void updateBackingStore();
void mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags);
void setToolTip(const HitTestResult&);
void print(Frame*);
-
+
+ void enableSuddenTermination();
+ void disableSuddenTermination();
+
+ void runOpenPanel(Frame*, PassRefPtr<FileChooser>);
+
#if PLATFORM(MAC)
void focusNSView(NSView*);
#endif
diff --git a/WebCore/page/ChromeClient.h b/WebCore/page/ChromeClient.h
index 5bce1af..7678dc2 100644
--- a/WebCore/page/ChromeClient.h
+++ b/WebCore/page/ChromeClient.h
@@ -1,4 +1,3 @@
-// -*- mode: c++; c-basic-offset: 4 -*-
/*
* Copyright (C) 2006, 2007, 2008 Apple, Inc. All rights reserved.
*
@@ -21,20 +20,38 @@
#ifndef ChromeClient_h
#define ChromeClient_h
+#include "GraphicsContext.h"
#include "FocusDirection.h"
+#include "ScrollTypes.h"
+#include "HostWindow.h"
+#include <wtf/Forward.h>
+#include <wtf/Vector.h>
+
+#if PLATFORM(MAC)
+#include "WebCoreKeyboardUIMode.h"
+#endif
+
+#ifndef __OBJC__
+class NSMenu;
+class NSResponder;
+#endif
namespace WebCore {
+ class AtomicString;
+ class FileChooser;
class FloatRect;
class Frame;
class HitTestResult;
class IntRect;
+ class Node;
class Page;
class String;
+ class Widget;
struct FrameLoadRequest;
struct WindowFeatures;
-
+
class ChromeClient {
public:
virtual void chromeDestroyed() = 0;
@@ -86,15 +103,19 @@ namespace WebCore {
virtual void runJavaScriptAlert(Frame*, const String&) = 0;
virtual bool runJavaScriptConfirm(Frame*, const String&) = 0;
virtual bool runJavaScriptPrompt(Frame*, const String& message, const String& defaultValue, String& result) = 0;
-
virtual void setStatusbarText(const String&) = 0;
virtual bool shouldInterruptJavaScript() = 0;
virtual bool tabsToLinks() const = 0;
virtual IntRect windowResizerRect() const = 0;
- virtual void addToDirtyRegion(const IntRect&) = 0;
- virtual void scrollBackingStore(int dx, int dy, const IntRect& scrollViewRect, const IntRect& clipRect) = 0;
- virtual void updateBackingStore() = 0;
+
+ // Methods used by HostWindow.
+ virtual void repaint(const IntRect&, bool contentChanged, bool immediate = false, bool repaintContentOnly = false) = 0;
+ virtual void scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect) = 0;
+ virtual IntPoint screenToWindow(const IntPoint&) const = 0;
+ virtual IntRect windowToScreen(const IntRect&) const = 0;
+ virtual PlatformWidget platformWindow() const = 0;
+ // End methods used by HostWindow.
virtual void mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags) = 0;
@@ -104,6 +125,38 @@ namespace WebCore {
virtual void exceededDatabaseQuota(Frame*, const String& databaseName) = 0;
+#if ENABLE(DASHBOARD_SUPPORT)
+ virtual void dashboardRegionsChanged();
+#endif
+
+ virtual void populateVisitedLinks();
+
+ virtual FloatRect customHighlightRect(Node*, const AtomicString& type, const FloatRect& lineRect);
+ virtual void paintCustomHighlight(Node*, const AtomicString& type, const FloatRect& boxRect, const FloatRect& lineRect,
+ bool behindText, bool entireLine);
+
+ virtual bool shouldReplaceWithGeneratedFileForUpload(const String& path, String& generatedFilename);
+ virtual String generateReplacementFile(const String& path);
+
+ virtual void enableSuddenTermination();
+ virtual void disableSuddenTermination();
+
+ virtual bool paintCustomScrollbar(GraphicsContext*, const FloatRect&, ScrollbarControlSize,
+ ScrollbarControlState, ScrollbarPart pressedPart, bool vertical,
+ float value, float proportion, ScrollbarControlPartMask);
+ virtual bool paintCustomScrollCorner(GraphicsContext*, const FloatRect&);
+
+ virtual void runOpenPanel(Frame*, PassRefPtr<FileChooser>) = 0;
+
+#if PLATFORM(MAC)
+ virtual KeyboardUIMode keyboardUIMode() { return KeyboardAccessDefault; }
+
+ virtual NSResponder *firstResponder() { return 0; }
+ virtual void makeFirstResponder(NSResponder *) { }
+
+ virtual void willPopUpMenu(NSMenu *) { }
+#endif
+
protected:
virtual ~ChromeClient() { }
};
diff --git a/WebCore/page/Console.cpp b/WebCore/page/Console.cpp
index d45af62..bfcc478 100644
--- a/WebCore/page/Console.cpp
+++ b/WebCore/page/Console.cpp
@@ -29,11 +29,24 @@
#include "config.h"
#include "Console.h"
-#include "Chrome.h"
+#include "ChromeClient.h"
+#include "CString.h"
#include "Frame.h"
#include "FrameLoader.h"
+#include "FrameTree.h"
+#include "InspectorController.h"
+#include "JSDOMBinding.h"
#include "Page.h"
+#include "PageGroup.h"
#include "PlatformString.h"
+#include <runtime/ArgList.h>
+#include <kjs/interpreter.h>
+#include <runtime/JSObject.h>
+#include <VM/Machine.h>
+#include <profiler/Profiler.h>
+#include <stdio.h>
+
+using namespace JSC;
namespace WebCore {
@@ -47,52 +60,422 @@ void Console::disconnectFrame()
m_frame = 0;
}
-void Console::error(const String& message)
+static void printSourceURLAndLine(const String& sourceURL, unsigned lineNumber)
{
- if (!m_frame)
+ if (!sourceURL.isEmpty()) {
+ if (lineNumber > 0)
+ printf("%s:%d: ", sourceURL.utf8().data(), lineNumber);
+ else
+ printf("%s: ", sourceURL.utf8().data());
+ }
+}
+
+static void printMessageSourceAndLevelPrefix(MessageSource source, MessageLevel level)
+{
+ const char* sourceString;
+ switch (source) {
+ case HTMLMessageSource:
+ sourceString = "HTML";
+ break;
+ case XMLMessageSource:
+ sourceString = "XML";
+ break;
+ case JSMessageSource:
+ sourceString = "JS";
+ break;
+ case CSSMessageSource:
+ sourceString = "CSS";
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ // Fall thru.
+ case OtherMessageSource:
+ sourceString = "OTHER";
+ break;
+ }
+
+ const char* levelString;
+ switch (level) {
+ case TipMessageLevel:
+ levelString = "TIP";
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ // Fall thru.
+ case LogMessageLevel:
+ levelString = "LOG";
+ break;
+ case WarningMessageLevel:
+ levelString = "WARN";
+ break;
+ case ErrorMessageLevel:
+ levelString = "ERROR";
+ break;
+ }
+
+ printf("%s %s:", sourceString, levelString);
+}
+
+static void printToStandardOut(MessageSource source, MessageLevel level, const String& message, const String& sourceURL, unsigned lineNumber)
+{
+ if (!Console::shouldPrintExceptions())
return;
- Page* page = m_frame->page();
+ printSourceURLAndLine(sourceURL, lineNumber);
+ printMessageSourceAndLevelPrefix(source, level);
+
+ printf(" %s\n", message.utf8().data());
+}
+
+static void printToStandardOut(MessageLevel level, ExecState* exec, const ArgList& args, const KURL& url)
+{
+ if (!Console::shouldPrintExceptions())
+ return;
+
+ printSourceURLAndLine(url.prettyURL(), 0);
+ printMessageSourceAndLevelPrefix(JSMessageSource, level);
+
+ for (size_t i = 0; i < args.size(); ++i) {
+ UString argAsString = args.at(exec, i)->toString(exec);
+ printf(" %s", argAsString.UTF8String().c_str());
+ }
+
+ printf("\n");
+}
+
+static inline void retrieveLastCaller(ExecState* exec, KURL& url, unsigned& lineNumber)
+{
+ int signedLineNumber;
+ intptr_t sourceID;
+ UString urlString;
+ JSValue* function;
+
+ exec->machine()->retrieveLastCaller(exec, signedLineNumber, sourceID, urlString, function);
+
+ url = KURL(urlString);
+ lineNumber = (signedLineNumber >= 0 ? signedLineNumber : 0);
+}
+
+void Console::addMessage(MessageSource source, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceURL)
+{
+ Page* page = this->page();
if (!page)
return;
- page->chrome()->addMessageToConsole(JSMessageSource, ErrorMessageLevel, message, 0, m_frame->loader()->url().prettyURL());
+ if (source == JSMessageSource)
+ page->chrome()->client()->addMessageToConsole(message, lineNumber, sourceURL);
+
+ page->inspectorController()->addMessageToConsole(source, level, message, lineNumber, sourceURL);
+
+ printToStandardOut(source, level, message, sourceURL, lineNumber);
}
-void Console::info(const String& message)
+void Console::debug(ExecState* exec, const ArgList& args)
{
- if (!m_frame)
+ // In Firebug, console.debug has the same behavior as console.log. So we'll do the same.
+ log(exec, args);
+}
+
+void Console::error(ExecState* exec, const ArgList& args)
+{
+ if (args.isEmpty())
return;
- Page* page = m_frame->page();
+ Page* page = this->page();
if (!page)
return;
- page->chrome()->addMessageToConsole(JSMessageSource, LogMessageLevel, message, 0, m_frame->loader()->url().prettyURL());
+ String message = args.at(exec, 0)->toString(exec);
+
+ KURL url;
+ unsigned lineNumber;
+ retrieveLastCaller(exec, url, lineNumber);
+
+ page->chrome()->client()->addMessageToConsole(message, lineNumber, url.prettyURL());
+ page->inspectorController()->addMessageToConsole(JSMessageSource, ErrorMessageLevel, exec, args, lineNumber, url.string());
+
+ printToStandardOut(ErrorMessageLevel, exec, args, url);
}
-void Console::log(const String& message)
+void Console::info(ExecState* exec, const ArgList& args)
{
- if (!m_frame)
+ if (args.isEmpty())
return;
- Page* page = m_frame->page();
+ Page* page = this->page();
if (!page)
return;
- page->chrome()->addMessageToConsole(JSMessageSource, LogMessageLevel, message, 0, m_frame->loader()->url().prettyURL());
+ String message = args.at(exec, 0)->toString(exec);
+
+ KURL url;
+ unsigned lineNumber;
+ retrieveLastCaller(exec, url, lineNumber);
+
+ page->chrome()->client()->addMessageToConsole(message, lineNumber, url.prettyURL());
+ page->inspectorController()->addMessageToConsole(JSMessageSource, LogMessageLevel, exec, args, lineNumber, url.string());
+
+ printToStandardOut(LogMessageLevel, exec, args, url);
}
-void Console::warn(const String& message)
+void Console::log(ExecState* exec, const ArgList& args)
{
- if (!m_frame)
+ if (args.isEmpty())
return;
- Page* page = m_frame->page();
+ Page* page = this->page();
if (!page)
return;
- page->chrome()->addMessageToConsole(JSMessageSource, WarningMessageLevel, message, 0, m_frame->loader()->url().prettyURL());
+ String message = args.at(exec, 0)->toString(exec);
+
+ KURL url;
+ unsigned lineNumber;
+ retrieveLastCaller(exec, url, lineNumber);
+
+ page->chrome()->client()->addMessageToConsole(message, lineNumber, url.prettyURL());
+ page->inspectorController()->addMessageToConsole(JSMessageSource, LogMessageLevel, exec, args, lineNumber, url.string());
+
+ printToStandardOut(LogMessageLevel, exec, args, url);
+}
+
+void Console::dir(ExecState* exec, const ArgList& args)
+{
+ if (args.isEmpty())
+ return;
+
+ Page* page = this->page();
+ if (!page)
+ return;
+
+ page->inspectorController()->addMessageToConsole(JSMessageSource, ObjectMessageLevel, exec, args, 0, String());
+}
+
+void Console::dirxml(ExecState* exec, const ArgList& args)
+{
+ if (args.isEmpty())
+ return;
+
+ Page* page = this->page();
+ if (!page)
+ return;
+
+ page->inspectorController()->addMessageToConsole(JSMessageSource, NodeMessageLevel, exec, args, 0, String());
+}
+
+void Console::trace(ExecState* exec)
+{
+ Page* page = this->page();
+ if (!page)
+ return;
+
+ int signedLineNumber;
+ intptr_t sourceID;
+ UString urlString;
+ JSValue* func;
+
+ exec->machine()->retrieveLastCaller(exec, signedLineNumber, sourceID, urlString, func);
+
+ ArgList args;
+ while (!func->isNull()) {
+ args.append(func);
+ func = exec->machine()->retrieveCaller(exec, asInternalFunction(func));
+ }
+
+ page->inspectorController()->addMessageToConsole(JSMessageSource, TraceMessageLevel, exec, args, 0, String());
+}
+
+void Console::assertCondition(bool condition, ExecState* exec, const ArgList& args)
+{
+ if (condition)
+ return;
+
+ Page* page = this->page();
+ if (!page)
+ return;
+
+ KURL url;
+ unsigned lineNumber;
+ retrieveLastCaller(exec, url, lineNumber);
+
+ // FIXME: <https://bugs.webkit.org/show_bug.cgi?id=19135> It would be nice to prefix assertion failures with a message like "Assertion failed: ".
+ // FIXME: <https://bugs.webkit.org/show_bug.cgi?id=19136> We should print a message even when args.isEmpty() is true.
+
+ page->inspectorController()->addMessageToConsole(JSMessageSource, ErrorMessageLevel, exec, args, lineNumber, url.string());
+
+ printToStandardOut(ErrorMessageLevel, exec, args, url);
+}
+
+void Console::count(ExecState* exec, const ArgList& args)
+{
+ Page* page = this->page();
+ if (!page)
+ return;
+
+ KURL url;
+ unsigned lineNumber;
+ retrieveLastCaller(exec, url, lineNumber);
+
+ UString title;
+ if (args.size() >= 1)
+ title = valueToStringWithUndefinedOrNullCheck(exec, args.at(exec, 0));
+
+ page->inspectorController()->count(title, lineNumber, url.string());
+}
+
+void Console::profile(ExecState* exec, const ArgList& args)
+{
+ Page* page = this->page();
+ if (!page)
+ return;
+
+ // FIXME: log a console message when profiling is disabled.
+ if (!page->inspectorController()->profilerEnabled())
+ return;
+
+ UString title = args.at(exec, 0)->toString(exec);
+ Profiler::profiler()->startProfiling(exec, title);
+}
+
+void Console::profileEnd(ExecState* exec, const ArgList& args)
+{
+ Page* page = this->page();
+ if (!page)
+ return;
+
+ if (!page->inspectorController()->profilerEnabled())
+ return;
+
+ UString title;
+ if (args.size() >= 1)
+ title = valueToStringWithUndefinedOrNullCheck(exec, args.at(exec, 0));
+
+ RefPtr<Profile> profile = Profiler::profiler()->stopProfiling(exec, title);
+ if (!profile)
+ return;
+
+ m_profiles.append(profile);
+
+ if (Page* page = this->page()) {
+ KURL url;
+ unsigned lineNumber;
+ retrieveLastCaller(exec, url, lineNumber);
+
+ page->inspectorController()->addProfile(profile, lineNumber, url);
+ }
+}
+
+void Console::time(const UString& title)
+{
+ if (title.isNull())
+ return;
+
+ Page* page = this->page();
+ if (!page)
+ return;
+
+ page->inspectorController()->startTiming(title);
+}
+
+void Console::timeEnd(ExecState* exec, const ArgList& args)
+{
+ UString title;
+ if (args.size() >= 1)
+ title = valueToStringWithUndefinedOrNullCheck(exec, args.at(exec, 0));
+ if (title.isNull())
+ return;
+
+ Page* page = this->page();
+ if (!page)
+ return;
+
+ double elapsed;
+ if (!page->inspectorController()->stopTiming(title, elapsed))
+ return;
+
+ String message = String(title) + String::format(": %.0fms", elapsed);
+
+ KURL url;
+ unsigned lineNumber;
+ retrieveLastCaller(exec, url, lineNumber);
+
+ page->inspectorController()->addMessageToConsole(JSMessageSource, LogMessageLevel, message, lineNumber, url.string());
+}
+
+void Console::group(ExecState* exec, const ArgList& arguments)
+{
+ Page* page = this->page();
+ if (!page)
+ return;
+
+ page->inspectorController()->startGroup(JSMessageSource, exec, arguments, 0, String());
+}
+
+void Console::groupEnd()
+{
+ Page* page = this->page();
+ if (!page)
+ return;
+
+ page->inspectorController()->endGroup(JSMessageSource, 0, String());
+}
+
+void Console::warn(ExecState* exec, const ArgList& args)
+{
+ if (args.isEmpty())
+ return;
+
+ Page* page = this->page();
+ if (!page)
+ return;
+
+ String message = args.at(exec, 0)->toString(exec);
+
+ KURL url;
+ unsigned lineNumber;
+ retrieveLastCaller(exec, url, lineNumber);
+
+ page->chrome()->client()->addMessageToConsole(message, lineNumber, url.prettyURL());
+ page->inspectorController()->addMessageToConsole(JSMessageSource, WarningMessageLevel, exec, args, lineNumber, url.string());
+
+ printToStandardOut(WarningMessageLevel, exec, args, url);
+}
+
+void Console::reportException(ExecState* exec, JSValue* exception)
+{
+ UString errorMessage = exception->toString(exec);
+ JSObject* exceptionObject = exception->toObject(exec);
+ int lineNumber = exceptionObject->get(exec, Identifier(exec, "line"))->toInt32(exec);
+ UString exceptionSourceURL = exceptionObject->get(exec, Identifier(exec, "sourceURL"))->toString(exec);
+ addMessage(JSMessageSource, ErrorMessageLevel, errorMessage, lineNumber, exceptionSourceURL);
+ if (exec->hadException())
+ exec->clearException();
+}
+
+void Console::reportCurrentException(ExecState* exec)
+{
+ JSValue* exception = exec->exception();
+ exec->clearException();
+ reportException(exec, exception);
+}
+
+static bool printExceptions = false;
+
+bool Console::shouldPrintExceptions()
+{
+ return printExceptions;
+}
+
+void Console::setShouldPrintExceptions(bool print)
+{
+ printExceptions = print;
+}
+
+Page* Console::page() const
+{
+ if (!m_frame)
+ return 0;
+ return m_frame->page();
}
} // namespace WebCore
diff --git a/WebCore/page/Console.h b/WebCore/page/Console.h
index 81e39be..8f33e96 100644
--- a/WebCore/page/Console.h
+++ b/WebCore/page/Console.h
@@ -29,25 +29,86 @@
#ifndef Console_h
#define Console_h
-#include <wtf/RefCounted.h>
#include "PlatformString.h"
+#include <profiler/Profile.h>
+#include <wtf/RefCounted.h>
+#include <wtf/PassRefPtr.h>
+
+namespace JSC {
+ class ExecState;
+ class ArgList;
+}
namespace WebCore {
+ typedef Vector<RefPtr<JSC::Profile> > ProfilesArray;
+
class Frame;
+ class Page;
+ class String;
+
+ enum MessageSource {
+ HTMLMessageSource,
+ XMLMessageSource,
+ JSMessageSource,
+ CSSMessageSource,
+ OtherMessageSource
+ };
+
+ enum MessageLevel {
+ TipMessageLevel,
+ LogMessageLevel,
+ WarningMessageLevel,
+ ErrorMessageLevel,
+ ObjectMessageLevel,
+ NodeMessageLevel,
+ TraceMessageLevel,
+ StartGroupMessageLevel,
+ EndGroupMessageLevel
+ };
class Console : public RefCounted<Console> {
public:
- Console(Frame*);
+ static PassRefPtr<Console> create(Frame* frame) { return adoptRef(new Console(frame)); }
+
void disconnectFrame();
- void error(const String& message);
- void info(const String& message);
- void log(const String& message);
- void warn(const String& message);
+ void addMessage(MessageSource, MessageLevel, const String& message, unsigned lineNumber, const String& sourceURL);
+
+#if USE(JSC)
+ void debug(JSC::ExecState*, const JSC::ArgList&);
+ void error(JSC::ExecState*, const JSC::ArgList&);
+ void info(JSC::ExecState*, const JSC::ArgList&);
+ void log(JSC::ExecState*, const JSC::ArgList&);
+ void warn(JSC::ExecState*, const JSC::ArgList&);
+ void dir(JSC::ExecState*, const JSC::ArgList&);
+ void dirxml(JSC::ExecState*, const JSC::ArgList& arguments);
+ void trace(JSC::ExecState*);
+ void assertCondition(bool condition, JSC::ExecState*, const JSC::ArgList&);
+ void count(JSC::ExecState*, const JSC::ArgList&);
+ void profile(JSC::ExecState*, const JSC::ArgList&);
+ void profileEnd(JSC::ExecState*, const JSC::ArgList&);
+ void time(const JSC::UString& title);
+ void timeEnd(JSC::ExecState*, const JSC::ArgList&);
+ void group(JSC::ExecState*, const JSC::ArgList&);
+ void groupEnd();
+
+ void reportException(JSC::ExecState*, JSC::JSValue*);
+ void reportCurrentException(JSC::ExecState*);
+
+ static bool shouldPrintExceptions();
+ static void setShouldPrintExceptions(bool);
+
+ const ProfilesArray& profiles() const { return m_profiles; }
+#endif
private:
+ inline Page* page() const;
+
+ Console(Frame*);
+
Frame* m_frame;
+ ProfilesArray m_profiles;
};
} // namespace WebCore
diff --git a/WebCore/page/Console.idl b/WebCore/page/Console.idl
index 3356c0e..9075963 100644
--- a/WebCore/page/Console.idl
+++ b/WebCore/page/Console.idl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,10 +29,25 @@
module window {
interface Console {
- void error(in DOMString message);
- void info(in DOMString message);
- void log(in DOMString message);
- void warn(in DOMString message);
+ readonly attribute [CustomGetter] Array profiles;
+
+ [Custom] void debug();
+ [Custom] void error();
+ [Custom] void info();
+ [Custom] void log();
+ [Custom] void warn();
+ [Custom] void dir();
+ [Custom] void dirxml();
+ [Custom] void trace();
+ [Custom, ImplementationFunction=assertCondition] void assert(in boolean condition);
+ [Custom] void count();
+
+ [Custom] void profile(in DOMString title);
+ [Custom] void profileEnd();
+ void time(in [ConvertUndefinedOrNullToNullString] DOMString title);
+ [Custom] void timeEnd();
+ [Custom] void group();
+ void groupEnd();
};
}
diff --git a/WebCore/page/ContextMenuController.cpp b/WebCore/page/ContextMenuController.cpp
index f2c3c75..813f8e2 100644
--- a/WebCore/page/ContextMenuController.cpp
+++ b/WebCore/page/ContextMenuController.cpp
@@ -43,7 +43,6 @@
#include "HitTestRequest.h"
#include "HitTestResult.h"
#include "InspectorController.h"
-#include "KURL.h"
#include "MouseEvent.h"
#include "Node.h"
#include "Page.h"
@@ -59,8 +58,6 @@
namespace WebCore {
-using namespace EventNames;
-
ContextMenuController::ContextMenuController(Page* page, ContextMenuClient* client)
: m_page(page)
, m_client(client)
@@ -82,7 +79,7 @@ void ContextMenuController::clearContextMenu()
void ContextMenuController::handleContextMenuEvent(Event* event)
{
- ASSERT(event->type() == contextmenuEvent);
+ ASSERT(event->type() == eventNames().contextmenuEvent);
if (!event->isMouseEvent())
return;
MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
@@ -154,10 +151,11 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
frame->editor()->copyImage(result);
break;
case ContextMenuItemTagOpenFrameInNewWindow: {
- KURL url = frame->loader()->documentLoader()->unreachableURL();
- if (frame && url.isEmpty())
- url = frame->loader()->documentLoader()->url();
- openNewWindow(url, frame);
+ DocumentLoader* loader = frame->loader()->documentLoader();
+ if (!loader->unreachableURL().isEmpty())
+ openNewWindow(loader->unreachableURL(), frame);
+ else
+ openNewWindow(loader->url(), frame);
break;
}
case ContextMenuItemTagCopy:
@@ -191,11 +189,11 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
#endif
case ContextMenuItemTagSpellingGuess:
ASSERT(frame->selectedText().length());
- if (frame->editor()->shouldInsertText(item->title(), frame->selectionController()->toRange().get(),
+ if (frame->editor()->shouldInsertText(item->title(), frame->selection()->toRange().get(),
EditorInsertActionPasted)) {
Document* document = frame->document();
RefPtr<ReplaceSelectionCommand> command =
- new ReplaceSelectionCommand(document, createFragmentFromMarkup(document, item->title(), ""),
+ ReplaceSelectionCommand::create(document, createFragmentFromMarkup(document, item->title(), ""),
true, false, true);
applyCommand(command);
frame->revealSelection(RenderLayer::gAlignToEdgeIfNeeded);
@@ -216,8 +214,8 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
break;
case ContextMenuItemTagOpenLink:
if (Frame* targetFrame = result.targetFrame())
- targetFrame->loader()->load(FrameLoadRequest(ResourceRequest(result.absoluteLinkURL(),
- frame->loader()->outgoingReferrer())), false, true, 0, 0, HashMap<String, String>());
+ targetFrame->loader()->loadFrameRequestWithFormAndValues(FrameLoadRequest(ResourceRequest(result.absoluteLinkURL(),
+ frame->loader()->outgoingReferrer())), false, 0, 0, HashMap<String, String>());
else
openNewWindow(result.absoluteLinkURL(), frame);
break;
@@ -236,7 +234,7 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
break;
case ContextMenuItemTagStartSpeaking: {
ExceptionCode ec;
- RefPtr<Range> selectedRange = frame->selectionController()->toRange();
+ RefPtr<Range> selectedRange = frame->selection()->toRange();
if (!selectedRange || selectedRange->collapsed(ec)) {
Document* document = result.innerNonSharedNode()->document();
selectedRange = document->createRange();
@@ -249,13 +247,13 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
m_client->stopSpeaking();
break;
case ContextMenuItemTagDefaultDirection:
- frame->editor()->setBaseWritingDirection("inherit");
+ frame->editor()->setBaseWritingDirection(NaturalWritingDirection);
break;
case ContextMenuItemTagLeftToRight:
- frame->editor()->setBaseWritingDirection("ltr");
+ frame->editor()->setBaseWritingDirection(LeftToRightWritingDirection);
break;
case ContextMenuItemTagRightToLeft:
- frame->editor()->setBaseWritingDirection("rtl");
+ frame->editor()->setBaseWritingDirection(RightToLeftWritingDirection);
break;
#if PLATFORM(MAC)
case ContextMenuItemTagSearchInSpotlight:
diff --git a/WebCore/page/DOMSelection.cpp b/WebCore/page/DOMSelection.cpp
index 66b567a..5dab325 100644
--- a/WebCore/page/DOMSelection.cpp
+++ b/WebCore/page/DOMSelection.cpp
@@ -61,7 +61,7 @@ Node* DOMSelection::anchorNode() const
if (!m_frame)
return 0;
- const Selection& selection = m_frame->selectionController()->selection();
+ const Selection& selection = m_frame->selection()->selection();
Position anchor = selection.isBaseFirst() ? selection.start() : selection.end();
anchor = rangeCompliantEquivalent(anchor);
return anchor.node();
@@ -71,7 +71,7 @@ Node* DOMSelection::baseNode() const
{
if (!m_frame)
return 0;
- return rangeCompliantEquivalent(m_frame->selectionController()->selection().base()).node();
+ return rangeCompliantEquivalent(m_frame->selection()->selection().base()).node();
}
int DOMSelection::anchorOffset() const
@@ -79,7 +79,7 @@ int DOMSelection::anchorOffset() const
if (!m_frame)
return 0;
- const Selection& selection = m_frame->selectionController()->selection();
+ const Selection& selection = m_frame->selection()->selection();
Position anchor = selection.isBaseFirst() ? selection.start() : selection.end();
anchor = rangeCompliantEquivalent(anchor);
return anchor.offset();
@@ -89,7 +89,7 @@ int DOMSelection::baseOffset() const
{
if (!m_frame)
return 0;
- return rangeCompliantEquivalent(m_frame->selectionController()->selection().base()).offset();
+ return rangeCompliantEquivalent(m_frame->selection()->selection().base()).offset();
}
Node* DOMSelection::focusNode() const
@@ -97,7 +97,7 @@ Node* DOMSelection::focusNode() const
if (!m_frame)
return 0;
- const Selection& selection = m_frame->selectionController()->selection();
+ const Selection& selection = m_frame->selection()->selection();
Position focus = selection.isBaseFirst() ? selection.end() : selection.start();
focus = rangeCompliantEquivalent(focus);
return focus.node();
@@ -107,7 +107,7 @@ Node* DOMSelection::extentNode() const
{
if (!m_frame)
return 0;
- return rangeCompliantEquivalent(m_frame->selectionController()->selection().extent()).node();
+ return rangeCompliantEquivalent(m_frame->selection()->selection().extent()).node();
}
int DOMSelection::focusOffset() const
@@ -115,7 +115,7 @@ int DOMSelection::focusOffset() const
if (!m_frame)
return 0;
- const Selection& selection = m_frame->selectionController()->selection();
+ const Selection& selection = m_frame->selection()->selection();
Position focus = selection.isBaseFirst() ? selection.end() : selection.start();
focus = rangeCompliantEquivalent(focus);
return focus.offset();
@@ -125,14 +125,14 @@ int DOMSelection::extentOffset() const
{
if (!m_frame)
return 0;
- return rangeCompliantEquivalent(m_frame->selectionController()->selection().extent()).offset();
+ return rangeCompliantEquivalent(m_frame->selection()->selection().extent()).offset();
}
bool DOMSelection::isCollapsed() const
{
if (!m_frame)
return false;
- return !m_frame->selectionController()->isRange();
+ return !m_frame->selection()->isRange();
}
String DOMSelection::type() const
@@ -140,11 +140,11 @@ String DOMSelection::type() const
if (!m_frame)
return String();
- SelectionController* selectionController = m_frame->selectionController();
+ SelectionController* selection = m_frame->selection();
- if (selectionController->isNone())
+ if (selection->isNone())
return "None";
- if (selectionController->isCaret())
+ if (selection->isCaret())
return "Caret";
return "Range";
}
@@ -153,7 +153,7 @@ int DOMSelection::rangeCount() const
{
if (!m_frame)
return 0;
- return m_frame->selectionController()->isNone() ? 0 : 1;
+ return m_frame->selection()->isNone() ? 0 : 1;
}
void DOMSelection::collapse(Node* node, int offset, ExceptionCode& ec)
@@ -165,7 +165,7 @@ void DOMSelection::collapse(Node* node, int offset, ExceptionCode& ec)
ec = INDEX_SIZE_ERR;
return;
}
- m_frame->selectionController()->moveTo(VisiblePosition(node, offset, DOWNSTREAM));
+ m_frame->selection()->moveTo(VisiblePosition(node, offset, DOWNSTREAM));
}
void DOMSelection::collapseToEnd()
@@ -173,8 +173,8 @@ void DOMSelection::collapseToEnd()
if (!m_frame)
return;
- const Selection& selection = m_frame->selectionController()->selection();
- m_frame->selectionController()->moveTo(VisiblePosition(selection.end(), DOWNSTREAM));
+ const Selection& selection = m_frame->selection()->selection();
+ m_frame->selection()->moveTo(VisiblePosition(selection.end(), DOWNSTREAM));
}
void DOMSelection::collapseToStart()
@@ -182,15 +182,15 @@ void DOMSelection::collapseToStart()
if (!m_frame)
return;
- const Selection& selection = m_frame->selectionController()->selection();
- m_frame->selectionController()->moveTo(VisiblePosition(selection.start(), DOWNSTREAM));
+ const Selection& selection = m_frame->selection()->selection();
+ m_frame->selection()->moveTo(VisiblePosition(selection.start(), DOWNSTREAM));
}
void DOMSelection::empty()
{
if (!m_frame)
return;
- m_frame->selectionController()->moveTo(VisiblePosition());
+ m_frame->selection()->moveTo(VisiblePosition());
}
void DOMSelection::setBaseAndExtent(Node* baseNode, int baseOffset, Node* extentNode, int extentOffset, ExceptionCode& ec)
@@ -205,7 +205,7 @@ void DOMSelection::setBaseAndExtent(Node* baseNode, int baseOffset, Node* extent
VisiblePosition visibleBase = VisiblePosition(baseNode, baseOffset, DOWNSTREAM);
VisiblePosition visibleExtent = VisiblePosition(extentNode, extentOffset, DOWNSTREAM);
- m_frame->selectionController()->moveTo(visibleBase, visibleExtent);
+ m_frame->selection()->moveTo(visibleBase, visibleExtent);
}
void DOMSelection::setPosition(Node* node, int offset, ExceptionCode& ec)
@@ -216,7 +216,7 @@ void DOMSelection::setPosition(Node* node, int offset, ExceptionCode& ec)
ec = INDEX_SIZE_ERR;
return;
}
- m_frame->selectionController()->moveTo(VisiblePosition(node, offset, DOWNSTREAM));
+ m_frame->selection()->moveTo(VisiblePosition(node, offset, DOWNSTREAM));
}
void DOMSelection::modify(const String& alterString, const String& directionString, const String& granularityString)
@@ -224,52 +224,49 @@ void DOMSelection::modify(const String& alterString, const String& directionStri
if (!m_frame)
return;
- String alterStringLower = alterString.lower();
SelectionController::EAlteration alter;
- if (alterStringLower == "extend")
+ if (equalIgnoringCase(alterString, "extend"))
alter = SelectionController::EXTEND;
- else if (alterStringLower == "move")
+ else if (equalIgnoringCase(alterString, "move"))
alter = SelectionController::MOVE;
else
return;
- String directionStringLower = directionString.lower();
SelectionController::EDirection direction;
- if (directionStringLower == "forward")
+ if (equalIgnoringCase(directionString, "forward"))
direction = SelectionController::FORWARD;
- else if (directionStringLower == "backward")
+ else if (equalIgnoringCase(directionString, "backward"))
direction = SelectionController::BACKWARD;
- else if (directionStringLower == "left")
+ else if (equalIgnoringCase(directionString, "left"))
direction = SelectionController::LEFT;
- else if (directionStringLower == "right")
+ else if (equalIgnoringCase(directionString, "right"))
direction = SelectionController::RIGHT;
else
return;
- String granularityStringLower = granularityString.lower();
TextGranularity granularity;
- if (granularityStringLower == "character")
+ if (equalIgnoringCase(granularityString, "character"))
granularity = CharacterGranularity;
- else if (granularityStringLower == "word")
+ else if (equalIgnoringCase(granularityString, "word"))
granularity = WordGranularity;
- else if (granularityStringLower == "sentence")
+ else if (equalIgnoringCase(granularityString, "sentence"))
granularity = SentenceGranularity;
- else if (granularityStringLower == "line")
+ else if (equalIgnoringCase(granularityString, "line"))
granularity = LineGranularity;
- else if (granularityStringLower == "paragraph")
+ else if (equalIgnoringCase(granularityString, "paragraph"))
granularity = ParagraphGranularity;
- else if (granularityStringLower == "lineboundary")
+ else if (equalIgnoringCase(granularityString, "lineboundary"))
granularity = LineBoundary;
- else if (granularityStringLower == "sentenceboundary")
+ else if (equalIgnoringCase(granularityString, "sentenceboundary"))
granularity = SentenceBoundary;
- else if (granularityStringLower == "paragraphboundary")
+ else if (equalIgnoringCase(granularityString, "paragraphboundary"))
granularity = ParagraphBoundary;
- else if (granularityStringLower == "documentboundary")
+ else if (equalIgnoringCase(granularityString, "documentboundary"))
granularity = DocumentBoundary;
else
return;
- m_frame->selectionController()->modify(alter, direction, granularity, false);
+ m_frame->selection()->modify(alter, direction, granularity, false);
}
void DOMSelection::extend(Node* node, int offset, ExceptionCode& ec)
@@ -286,9 +283,9 @@ void DOMSelection::extend(Node* node, int offset, ExceptionCode& ec)
return;
}
- SelectionController* selectionController = m_frame->selectionController();
- selectionController->expandUsingGranularity(CharacterGranularity);
- selectionController->setExtent(VisiblePosition(node, offset, DOWNSTREAM));
+ SelectionController* selection = m_frame->selection();
+ selection->expandUsingGranularity(CharacterGranularity);
+ selection->setExtent(VisiblePosition(node, offset, DOWNSTREAM));
}
PassRefPtr<Range> DOMSelection::getRangeAt(int index, ExceptionCode& ec)
@@ -301,7 +298,7 @@ PassRefPtr<Range> DOMSelection::getRangeAt(int index, ExceptionCode& ec)
return 0;
}
- const Selection& selection = m_frame->selectionController()->selection();
+ const Selection& selection = m_frame->selection()->selection();
return selection.toRange();
}
@@ -309,7 +306,7 @@ void DOMSelection::removeAllRanges()
{
if (!m_frame)
return;
- m_frame->selectionController()->clear();
+ m_frame->selection()->clear();
}
void DOMSelection::addRange(Range* r)
@@ -319,34 +316,34 @@ void DOMSelection::addRange(Range* r)
if (!r)
return;
- SelectionController* selectionController = m_frame->selectionController();
+ SelectionController* selection = m_frame->selection();
- if (selectionController->isNone()) {
- selectionController->setSelection(Selection(r));
+ if (selection->isNone()) {
+ selection->setSelection(Selection(r));
return;
}
- RefPtr<Range> range = selectionController->selection().toRange();
+ RefPtr<Range> range = selection->selection().toRange();
ExceptionCode ec = 0;
if (r->compareBoundaryPoints(Range::START_TO_START, range.get(), ec) == -1) {
// We don't support discontiguous selection. We don't do anything if r and range don't intersect.
- if (r->compareBoundaryPoints(Range::END_TO_START, range.get(), ec) > -1) {
+ if (r->compareBoundaryPoints(Range::START_TO_END, range.get(), ec) > -1) {
if (r->compareBoundaryPoints(Range::END_TO_END, range.get(), ec) == -1)
// The original range and r intersect.
- selectionController->setSelection(Selection(r->startPosition(), range->endPosition(), DOWNSTREAM));
+ selection->setSelection(Selection(r->startPosition(), range->endPosition(), DOWNSTREAM));
else
// r contains the original range.
- selectionController->setSelection(Selection(r));
+ selection->setSelection(Selection(r));
}
} else {
// We don't support discontiguous selection. We don't do anything if r and range don't intersect.
- if (r->compareBoundaryPoints(Range::START_TO_END, range.get(), ec) < 1) {
+ if (r->compareBoundaryPoints(Range::END_TO_START, range.get(), ec) < 1) {
if (r->compareBoundaryPoints(Range::END_TO_END, range.get(), ec) == -1)
// The original range contains r.
- selectionController->setSelection(Selection(range.get()));
+ selection->setSelection(Selection(range.get()));
else
// The original range and r intersect.
- selectionController->setSelection(Selection(range->startPosition(), r->endPosition(), DOWNSTREAM));
+ selection->setSelection(Selection(range->startPosition(), r->endPosition(), DOWNSTREAM));
}
}
}
@@ -356,15 +353,15 @@ void DOMSelection::deleteFromDocument()
if (!m_frame)
return;
- SelectionController* selectionController = m_frame->selectionController();
+ SelectionController* selection = m_frame->selection();
- if (selectionController->isNone())
+ if (selection->isNone())
return;
if (isCollapsed())
- selectionController->modify(SelectionController::EXTEND, SelectionController::BACKWARD, CharacterGranularity);
+ selection->modify(SelectionController::EXTEND, SelectionController::BACKWARD, CharacterGranularity);
- RefPtr<Range> selectedRange = selectionController->selection().toRange();
+ RefPtr<Range> selectedRange = selection->selection().toRange();
ExceptionCode ec = 0;
selectedRange->deleteContents(ec);
@@ -379,14 +376,14 @@ bool DOMSelection::containsNode(const Node* n, bool allowPartial) const
if (!m_frame)
return false;
- SelectionController* selectionController = m_frame->selectionController();
+ SelectionController* selection = m_frame->selection();
- if (!n || selectionController->isNone())
+ if (!n || selection->isNone())
return false;
Node* parentNode = n->parentNode();
unsigned nodeIndex = n->nodeIndex();
- RefPtr<Range> selectedRange = selectionController->selection().toRange();
+ RefPtr<Range> selectedRange = selection->selection().toRange();
if (!parentNode)
return false;
@@ -421,7 +418,7 @@ String DOMSelection::toString()
if (!m_frame)
return String();
- return plainText(m_frame->selectionController()->selection().toRange().get());
+ return plainText(m_frame->selection()->selection().toRange().get());
}
} // namespace WebCore
diff --git a/WebCore/page/DOMSelection.h b/WebCore/page/DOMSelection.h
index d4a579f..fd8d1fc 100644
--- a/WebCore/page/DOMSelection.h
+++ b/WebCore/page/DOMSelection.h
@@ -45,7 +45,7 @@ namespace WebCore {
class DOMSelection : public RefCounted<DOMSelection> {
public:
- DOMSelection(Frame*);
+ static PassRefPtr<DOMSelection> create(Frame* frame) { return adoptRef(new DOMSelection(frame)); }
Frame* frame() const;
void disconnectFrame();
@@ -92,6 +92,8 @@ namespace WebCore {
//TextRange *createRange();
private:
+ DOMSelection(Frame*);
+
Frame* m_frame;
};
diff --git a/WebCore/page/DOMWindow.cpp b/WebCore/page/DOMWindow.cpp
index f091c3d..4ab69ca 100644
--- a/WebCore/page/DOMWindow.cpp
+++ b/WebCore/page/DOMWindow.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,22 +30,31 @@
#include "CSSComputedStyleDeclaration.h"
#include "CSSRuleList.h"
#include "CSSStyleSelector.h"
+#include "CString.h"
#include "Chrome.h"
#include "Console.h"
#include "DOMSelection.h"
#include "Document.h"
#include "Element.h"
+#include "EventListener.h"
+#include "EventNames.h"
+#include "ExceptionCode.h"
#include "FloatRect.h"
#include "Frame.h"
#include "FrameLoader.h"
#include "FrameTree.h"
#include "FrameView.h"
+#include "HTMLFrameOwnerElement.h"
#include "History.h"
+#include "Location.h"
#include "MessageEvent.h"
+#include "Navigator.h"
#include "Page.h"
+#include "PageGroup.h"
#include "PlatformScreen.h"
#include "PlatformString.h"
#include "Screen.h"
+#include "SecurityOrigin.h"
#include <algorithm>
#include <wtf/MathExtras.h>
@@ -53,11 +62,45 @@
#include "Database.h"
#endif
+#if ENABLE(DOM_STORAGE)
+#include "LocalStorage.h"
+#include "SessionStorage.h"
+#include "Storage.h"
+#include "StorageArea.h"
+#endif
+
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+#include "DOMApplicationCache.h"
+#endif
+
using std::min;
using std::max;
namespace WebCore {
+class PostMessageTimer : public TimerBase {
+public:
+ PostMessageTimer(DOMWindow* window, PassRefPtr<MessageEvent> event, SecurityOrigin* targetOrigin)
+ : m_window(window)
+ , m_event(event)
+ , m_targetOrigin(targetOrigin)
+ {
+ }
+
+ MessageEvent* event() const { return m_event.get(); }
+ SecurityOrigin* targetOrigin() const { return m_targetOrigin.get(); }
+
+private:
+ virtual void fired()
+ {
+ m_window->postMessageTimerFired(this);
+ }
+
+ RefPtr<DOMWindow> m_window;
+ RefPtr<MessageEvent> m_event;
+ RefPtr<SecurityOrigin> m_targetOrigin;
+};
+
// This function:
// 1) Validates the pending changes are not changing to NaN
// 2) Constrains the window rect to no smaller than 100 in each dimension and no
@@ -105,6 +148,8 @@ DOMWindow::DOMWindow(Frame* frame)
DOMWindow::~DOMWindow()
{
+ if (m_frame)
+ m_frame->clearFormerDOMWindow(this);
}
void DOMWindow::disconnectFrame()
@@ -154,83 +199,214 @@ void DOMWindow::clear()
if (m_console)
m_console->disconnectFrame();
m_console = 0;
+
+ if (m_navigator)
+ m_navigator->disconnectFrame();
+ m_navigator = 0;
+
+ if (m_location)
+ m_location->disconnectFrame();
+ m_location = 0;
+
+#if ENABLE(DOM_STORAGE)
+ if (m_sessionStorage)
+ m_sessionStorage->disconnectFrame();
+ m_sessionStorage = 0;
+
+ if (m_localStorage)
+ m_localStorage->disconnectFrame();
+ m_localStorage = 0;
+#endif
+
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ if (m_applicationCache)
+ m_applicationCache->disconnectFrame();
+ m_applicationCache = 0;
+#endif
}
Screen* DOMWindow::screen() const
{
if (!m_screen)
- m_screen = new Screen(m_frame);
+ m_screen = Screen::create(m_frame);
return m_screen.get();
}
History* DOMWindow::history() const
{
if (!m_history)
- m_history = new History(m_frame);
+ m_history = History::create(m_frame);
return m_history.get();
}
BarInfo* DOMWindow::locationbar() const
{
if (!m_locationbar)
- m_locationbar = new BarInfo(m_frame, BarInfo::Locationbar);
+ m_locationbar = BarInfo::create(m_frame, BarInfo::Locationbar);
return m_locationbar.get();
}
BarInfo* DOMWindow::menubar() const
{
if (!m_menubar)
- m_menubar = new BarInfo(m_frame, BarInfo::Menubar);
+ m_menubar = BarInfo::create(m_frame, BarInfo::Menubar);
return m_menubar.get();
}
BarInfo* DOMWindow::personalbar() const
{
if (!m_personalbar)
- m_personalbar = new BarInfo(m_frame, BarInfo::Personalbar);
+ m_personalbar = BarInfo::create(m_frame, BarInfo::Personalbar);
return m_personalbar.get();
}
BarInfo* DOMWindow::scrollbars() const
{
if (!m_scrollbars)
- m_scrollbars = new BarInfo(m_frame, BarInfo::Scrollbars);
+ m_scrollbars = BarInfo::create(m_frame, BarInfo::Scrollbars);
return m_scrollbars.get();
}
BarInfo* DOMWindow::statusbar() const
{
if (!m_statusbar)
- m_statusbar = new BarInfo(m_frame, BarInfo::Statusbar);
+ m_statusbar = BarInfo::create(m_frame, BarInfo::Statusbar);
return m_statusbar.get();
}
BarInfo* DOMWindow::toolbar() const
{
if (!m_toolbar)
- m_toolbar = new BarInfo(m_frame, BarInfo::Toolbar);
+ m_toolbar = BarInfo::create(m_frame, BarInfo::Toolbar);
return m_toolbar.get();
}
Console* DOMWindow::console() const
{
if (!m_console)
- m_console = new Console(m_frame);
+ m_console = Console::create(m_frame);
return m_console.get();
}
-#if ENABLE(CROSS_DOCUMENT_MESSAGING)
-void DOMWindow::postMessage(const String& message, const String& domain, const String& uri, DOMWindow* source) const
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+DOMApplicationCache* DOMWindow::applicationCache() const
+{
+ if (!m_applicationCache)
+ m_applicationCache = DOMApplicationCache::create(m_frame);
+ return m_applicationCache.get();
+}
+#endif
+
+Navigator* DOMWindow::navigator() const
+{
+ if (!m_navigator)
+ m_navigator = Navigator::create(m_frame);
+ return m_navigator.get();
+}
+
+Location* DOMWindow::location() const
{
- ExceptionCode ec;
- document()->dispatchEvent(new MessageEvent(message, domain, uri, source), ec, true);
+ if (!m_location)
+ m_location = Location::create(m_frame);
+ return m_location.get();
+}
+
+#if ENABLE(DOM_STORAGE)
+Storage* DOMWindow::sessionStorage() const
+{
+ if (m_sessionStorage)
+ return m_sessionStorage.get();
+
+ Page* page = m_frame->page();
+ if (!page)
+ return 0;
+
+ Document* document = m_frame->document();
+ if (!document)
+ return 0;
+
+ RefPtr<StorageArea> storageArea = page->sessionStorage()->storageArea(document->securityOrigin());
+ m_sessionStorage = Storage::create(m_frame, storageArea.release());
+ return m_sessionStorage.get();
+}
+
+Storage* DOMWindow::localStorage() const
+{
+ Document* document = this->document();
+ if (!document)
+ return 0;
+
+ Page* page = document->page();
+ if (!page)
+ return 0;
+
+ LocalStorage* localStorage = page->group().localStorage();
+ RefPtr<StorageArea> storageArea = localStorage ? localStorage->storageArea(m_frame, document->securityOrigin()) : 0;
+ if (storageArea)
+ m_localStorage = Storage::create(m_frame, storageArea.release());
+
+ return m_localStorage.get();
}
#endif
+void DOMWindow::postMessage(const String& message, MessagePort* messagePort, const String& targetOrigin, DOMWindow* source, ExceptionCode& ec)
+{
+ if (!m_frame)
+ return;
+
+ // Compute the target origin. We need to do this synchronously in order
+ // to generate the SYNTAX_ERR exception correctly.
+ RefPtr<SecurityOrigin> target;
+ if (targetOrigin != "*") {
+ target = SecurityOrigin::create(KURL(targetOrigin));
+ if (target->isEmpty()) {
+ ec = SYNTAX_ERR;
+ return;
+ }
+ }
+
+ RefPtr<MessagePort> newMessagePort;
+ if (messagePort)
+ newMessagePort = messagePort->clone(document(), ec);
+ if (ec)
+ return;
+
+ // Capture the source of the message. We need to do this synchronously
+ // in order to capture the source of the message correctly.
+ Document* sourceDocument = source->document();
+ if (!sourceDocument)
+ return;
+ String sourceOrigin = sourceDocument->securityOrigin()->toString();
+
+ // Schedule the message.
+ PostMessageTimer* timer = new PostMessageTimer(this, MessageEvent::create(message, sourceOrigin, "", source, newMessagePort), target.get());
+ timer->startOneShot(0);
+}
+
+void DOMWindow::postMessageTimerFired(PostMessageTimer* t)
+{
+ OwnPtr<PostMessageTimer> timer(t);
+
+ if (!document())
+ return;
+
+ if (timer->targetOrigin()) {
+ // Check target origin now since the target document may have changed since the simer was scheduled.
+ if (!timer->targetOrigin()->isSameSchemeHostPort(document()->securityOrigin())) {
+ String message = String::format("Unable to post message to %s. Recipient has origin %s.\n",
+ timer->targetOrigin()->toString().utf8().data(), document()->securityOrigin()->toString().utf8().data());
+ console()->addMessage(JSMessageSource, ErrorMessageLevel, message, 0, String());
+ return;
+ }
+ }
+
+ document()->dispatchWindowEvent(timer->event());
+}
+
DOMSelection* DOMWindow::getSelection()
{
if (!m_selection)
- m_selection = new DOMSelection(m_frame);
+ m_selection = DOMSelection::create(m_frame);
return m_selection.get();
}
@@ -239,13 +415,7 @@ Element* DOMWindow::frameElement() const
if (!m_frame)
return 0;
- Document* doc = m_frame->document();
- ASSERT(doc);
- if (!doc)
- return 0;
-
- // FIXME: could this use m_frame->ownerElement() instead of going through the Document.
- return doc->ownerElement();
+ return m_frame->ownerElement();
}
void DOMWindow::focus()
@@ -396,8 +566,8 @@ int DOMWindow::innerHeight() const
FrameView* view = m_frame->view();
if (!view)
return 0;
-
- return view->height();
+
+ return static_cast<int>(view->height() / m_frame->pageZoomFactor());
}
int DOMWindow::innerWidth() const
@@ -409,7 +579,7 @@ int DOMWindow::innerWidth() const
if (!view)
return 0;
- return view->width();
+ return static_cast<int>(view->width() / m_frame->pageZoomFactor());
}
int DOMWindow::screenX() const
@@ -450,7 +620,7 @@ int DOMWindow::scrollX() const
if (doc)
doc->updateLayoutIgnorePendingStylesheets();
- return view->contentsX();
+ return static_cast<int>(view->scrollX() / m_frame->pageZoomFactor());
}
#ifdef ANDROID_ORIENTATION_SUPPORT
@@ -474,7 +644,7 @@ int DOMWindow::scrollY() const
if (doc)
doc->updateLayoutIgnorePendingStylesheets();
- return view->contentsY();
+ return static_cast<int>(view->scrollY() / m_frame->pageZoomFactor());
}
bool DOMWindow::closed() const
@@ -563,7 +733,7 @@ DOMWindow* DOMWindow::parent() const
if (!m_frame)
return 0;
- Frame* parent = m_frame->tree()->parent();
+ Frame* parent = m_frame->tree()->parent(true);
if (parent)
return parent->domWindow();
@@ -579,7 +749,7 @@ DOMWindow* DOMWindow::top() const
if (!page)
return 0;
- return page->mainFrame()->domWindow();
+ return m_frame->tree()->top(true)->domWindow();
}
Document* DOMWindow::document() const
@@ -596,8 +766,8 @@ PassRefPtr<CSSStyleDeclaration> DOMWindow::getComputedStyle(Element* elt, const
if (!elt)
return 0;
- // FIXME: This needs to work with pseudo elements.
- return new CSSComputedStyleDeclaration(elt);
+ // FIXME: This needs take pseudo elements into account.
+ return computedStyle(elt);
}
PassRefPtr<CSSRuleList> DOMWindow::getMatchedCSSRules(Element* elt, const String& pseudoElt, bool authorOnly) const
@@ -611,7 +781,7 @@ PassRefPtr<CSSRuleList> DOMWindow::getMatchedCSSRules(Element* elt, const String
return 0;
if (!pseudoElt.isEmpty())
- return doc->styleSelector()->pseudoStyleRulesForElement(elt, pseudoElt.impl(), authorOnly);
+ return doc->styleSelector()->pseudoStyleRulesForElement(elt, pseudoElt, authorOnly);
return doc->styleSelector()->styleRulesForElement(elt, authorOnly);
}
@@ -656,7 +826,7 @@ void DOMWindow::scrollBy(int x, int y) const
if (!view)
return;
- view->scrollBy(x, y);
+ view->scrollBy(IntSize(x, y));
}
void DOMWindow::scrollTo(int x, int y) const
@@ -673,7 +843,9 @@ void DOMWindow::scrollTo(int x, int y) const
if (!view)
return;
- view->setContentsPos(x, y);
+ int zoomedX = static_cast<int>(x * m_frame->pageZoomFactor());
+ int zoomedY = static_cast<int>(y * m_frame->pageZoomFactor());
+ view->setScrollPosition(IntPoint(zoomedX, zoomedY));
}
void DOMWindow::moveBy(float x, float y) const
@@ -685,6 +857,9 @@ void DOMWindow::moveBy(float x, float y) const
if (!page)
return;
+ if (m_frame != page->mainFrame())
+ return;
+
FloatRect fr = page->chrome()->windowRect();
FloatRect update = fr;
update.move(x, y);
@@ -702,6 +877,9 @@ void DOMWindow::moveTo(float x, float y) const
if (!page)
return;
+ if (m_frame != page->mainFrame())
+ return;
+
FloatRect fr = page->chrome()->windowRect();
FloatRect sr = screenAvailableRect(page->mainFrame()->view());
fr.setLocation(sr.location());
@@ -721,6 +899,9 @@ void DOMWindow::resizeBy(float x, float y) const
if (!page)
return;
+ if (m_frame != page->mainFrame())
+ return;
+
FloatRect fr = page->chrome()->windowRect();
FloatSize dest = fr.size() + FloatSize(x, y);
FloatRect update(fr.location(), dest);
@@ -737,6 +918,9 @@ void DOMWindow::resizeTo(float width, float height) const
if (!page)
return;
+ if (m_frame != page->mainFrame())
+ return;
+
FloatRect fr = page->chrome()->windowRect();
FloatSize dest = FloatSize(width, height);
FloatRect update(fr.location(), dest);
@@ -744,4 +928,352 @@ void DOMWindow::resizeTo(float width, float height) const
page->chrome()->setWindowRect(fr);
}
+inline void DOMWindow::setInlineEventListenerForType(const AtomicString& eventType, PassRefPtr<EventListener> eventListener)
+{
+ Document* document = this->document();
+ if (!document)
+ return;
+ document->setWindowInlineEventListenerForType(eventType, eventListener);
+}
+
+inline EventListener* DOMWindow::inlineEventListenerForType(const AtomicString& eventType) const
+{
+ Document* document = this->document();
+ if (!document)
+ return 0;
+ return document->windowInlineEventListenerForType(eventType);
+}
+
+EventListener* DOMWindow::onabort() const
+{
+ return inlineEventListenerForType(eventNames().abortEvent);
+}
+
+void DOMWindow::setOnabort(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().abortEvent, eventListener);
+}
+
+EventListener* DOMWindow::onblur() const
+{
+ return inlineEventListenerForType(eventNames().blurEvent);
+}
+
+void DOMWindow::setOnblur(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().blurEvent, eventListener);
+}
+
+EventListener* DOMWindow::onchange() const
+{
+ return inlineEventListenerForType(eventNames().changeEvent);
+}
+
+void DOMWindow::setOnchange(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().changeEvent, eventListener);
+}
+
+EventListener* DOMWindow::onclick() const
+{
+ return inlineEventListenerForType(eventNames().clickEvent);
+}
+
+void DOMWindow::setOnclick(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().clickEvent, eventListener);
+}
+
+EventListener* DOMWindow::ondblclick() const
+{
+ return inlineEventListenerForType(eventNames().dblclickEvent);
+}
+
+void DOMWindow::setOndblclick(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().dblclickEvent, eventListener);
+}
+
+EventListener* DOMWindow::onerror() const
+{
+ return inlineEventListenerForType(eventNames().errorEvent);
+}
+
+void DOMWindow::setOnerror(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().errorEvent, eventListener);
+}
+
+EventListener* DOMWindow::onfocus() const
+{
+ return inlineEventListenerForType(eventNames().focusEvent);
+}
+
+void DOMWindow::setOnfocus(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().focusEvent, eventListener);
+}
+
+EventListener* DOMWindow::onkeydown() const
+{
+ return inlineEventListenerForType(eventNames().keydownEvent);
+}
+
+void DOMWindow::setOnkeydown(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().keydownEvent, eventListener);
+}
+
+EventListener* DOMWindow::onkeypress() const
+{
+ return inlineEventListenerForType(eventNames().keypressEvent);
+}
+
+void DOMWindow::setOnkeypress(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().keypressEvent, eventListener);
+}
+
+EventListener* DOMWindow::onkeyup() const
+{
+ return inlineEventListenerForType(eventNames().keyupEvent);
+}
+
+void DOMWindow::setOnkeyup(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().keyupEvent, eventListener);
+}
+
+EventListener* DOMWindow::onload() const
+{
+ return inlineEventListenerForType(eventNames().loadEvent);
+}
+
+void DOMWindow::setOnload(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().loadEvent, eventListener);
+}
+
+EventListener* DOMWindow::onmousedown() const
+{
+ return inlineEventListenerForType(eventNames().mousedownEvent);
+}
+
+void DOMWindow::setOnmousedown(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().mousedownEvent, eventListener);
+}
+
+EventListener* DOMWindow::onmousemove() const
+{
+ return inlineEventListenerForType(eventNames().mousemoveEvent);
+}
+
+void DOMWindow::setOnmousemove(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().mousemoveEvent, eventListener);
+}
+
+EventListener* DOMWindow::onmouseout() const
+{
+ return inlineEventListenerForType(eventNames().mouseoutEvent);
+}
+
+void DOMWindow::setOnmouseout(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().mouseoutEvent, eventListener);
+}
+
+EventListener* DOMWindow::onmouseover() const
+{
+ return inlineEventListenerForType(eventNames().mouseoverEvent);
+}
+
+void DOMWindow::setOnmouseover(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().mouseoverEvent, eventListener);
+}
+
+EventListener* DOMWindow::onmouseup() const
+{
+ return inlineEventListenerForType(eventNames().mouseupEvent);
+}
+
+void DOMWindow::setOnmouseup(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().mouseupEvent, eventListener);
+}
+
+EventListener* DOMWindow::onmousewheel() const
+{
+ return inlineEventListenerForType(eventNames().mousewheelEvent);
+}
+
+void DOMWindow::setOnmousewheel(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().mousewheelEvent, eventListener);
+}
+
+EventListener* DOMWindow::onreset() const
+{
+ return inlineEventListenerForType(eventNames().resetEvent);
+}
+
+void DOMWindow::setOnreset(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().resetEvent, eventListener);
+}
+
+EventListener* DOMWindow::onresize() const
+{
+ return inlineEventListenerForType(eventNames().resizeEvent);
+}
+
+void DOMWindow::setOnresize(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().resizeEvent, eventListener);
+}
+
+EventListener* DOMWindow::onscroll() const
+{
+ return inlineEventListenerForType(eventNames().scrollEvent);
+}
+
+void DOMWindow::setOnscroll(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().scrollEvent, eventListener);
+}
+
+EventListener* DOMWindow::onsearch() const
+{
+ return inlineEventListenerForType(eventNames().searchEvent);
+}
+
+void DOMWindow::setOnsearch(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().searchEvent, eventListener);
+}
+
+EventListener* DOMWindow::onselect() const
+{
+ return inlineEventListenerForType(eventNames().selectEvent);
+}
+
+void DOMWindow::setOnselect(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().selectEvent, eventListener);
+}
+
+EventListener* DOMWindow::onsubmit() const
+{
+ return inlineEventListenerForType(eventNames().submitEvent);
+}
+
+void DOMWindow::setOnsubmit(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().submitEvent, eventListener);
+}
+
+EventListener* DOMWindow::onunload() const
+{
+ return inlineEventListenerForType(eventNames().unloadEvent);
+}
+
+void DOMWindow::setOnunload(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().unloadEvent, eventListener);
+}
+
+EventListener* DOMWindow::onbeforeunload() const
+{
+ return inlineEventListenerForType(eventNames().beforeunloadEvent);
+}
+
+void DOMWindow::setOnbeforeunload(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().beforeunloadEvent, eventListener);
+}
+
+EventListener* DOMWindow::onwebkitanimationstart() const
+{
+ return inlineEventListenerForType(eventNames().webkitAnimationStartEvent);
+}
+
+void DOMWindow::setOnwebkitanimationstart(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().webkitAnimationStartEvent, eventListener);
+}
+
+EventListener* DOMWindow::onwebkitanimationiteration() const
+{
+ return inlineEventListenerForType(eventNames().webkitAnimationIterationEvent);
+}
+
+void DOMWindow::setOnwebkitanimationiteration(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().webkitAnimationIterationEvent, eventListener);
+}
+
+EventListener* DOMWindow::onwebkitanimationend() const
+{
+ return inlineEventListenerForType(eventNames().webkitAnimationEndEvent);
+}
+
+void DOMWindow::setOnwebkitanimationend(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().webkitAnimationEndEvent, eventListener);
+}
+
+EventListener* DOMWindow::onwebkittransitionend() const
+{
+ return inlineEventListenerForType(eventNames().webkitTransitionEndEvent);
+}
+
+void DOMWindow::setOnwebkittransitionend(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().webkitTransitionEndEvent, eventListener);
+}
+
+#if ENABLE(TOUCH_EVENTS) // Android
+EventListener* DOMWindow::ontouchstart() const
+{
+ return inlineEventListenerForType(eventNames().touchstartEvent);
+}
+
+void DOMWindow::setOntouchstart(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().touchstartEvent, eventListener);
+}
+
+EventListener* DOMWindow::ontouchend() const
+{
+ return inlineEventListenerForType(eventNames().touchendEvent);
+}
+
+void DOMWindow::setOntouchend(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().touchendEvent, eventListener);
+}
+
+EventListener* DOMWindow::ontouchmove() const
+{
+ return inlineEventListenerForType(eventNames().touchmoveEvent);
+}
+
+void DOMWindow::setOntouchmove(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().touchmoveEvent, eventListener);
+}
+
+EventListener* DOMWindow::ontouchcancel() const
+{
+ return inlineEventListenerForType(eventNames().touchcancelEvent);
+}
+
+void DOMWindow::setOntouchcancel(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().touchcancelEvent, eventListener);
+}
+#endif
+
} // namespace WebCore
diff --git a/WebCore/page/DOMWindow.h b/WebCore/page/DOMWindow.h
index c814126..da84e35 100644
--- a/WebCore/page/DOMWindow.h
+++ b/WebCore/page/DOMWindow.h
@@ -26,9 +26,11 @@
#ifndef DOMWindow_h
#define DOMWindow_h
+#include "KURL.h"
#include "PlatformString.h"
-#include <wtf/RefCounted.h>
+#include "SecurityOrigin.h"
#include <wtf/Forward.h>
+#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
namespace WebCore {
@@ -41,16 +43,30 @@ namespace WebCore {
class Database;
class Document;
class Element;
+ class EventListener;
class FloatRect;
class Frame;
class History;
+ class Location;
+ class MessagePort;
+ class Navigator;
+ class PostMessageTimer;
class Screen;
+#if ENABLE(DOM_STORAGE)
+ class SessionStorage;
+ class Storage;
+#endif
+
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ class DOMApplicationCache;
+#endif
+
typedef int ExceptionCode;
class DOMWindow : public RefCounted<DOMWindow> {
public:
- DOMWindow(Frame*);
+ static PassRefPtr<DOMWindow> create(Frame* frame) { return adoptRef(new DOMWindow(frame)); }
virtual ~DOMWindow();
Frame* frame() { return m_frame; }
@@ -58,6 +74,12 @@ namespace WebCore {
void clear();
+ void setSecurityOrigin(SecurityOrigin* securityOrigin) { m_securityOrigin = securityOrigin; }
+ SecurityOrigin* securityOrigin() const { return m_securityOrigin.get(); }
+
+ void setURL(const KURL& url) { m_url = url; }
+ KURL url() const { return m_url; }
+
static void adjustWindowRect(const FloatRect& screen, FloatRect& window, const FloatRect& pendingChanges);
// DOM Level 0
@@ -69,6 +91,9 @@ namespace WebCore {
BarInfo* scrollbars() const;
BarInfo* statusbar() const;
BarInfo* toolbar() const;
+ Navigator* navigator() const;
+ Navigator* clientInformation() const { return navigator(); }
+ Location* location() const;
DOMSelection* getSelection();
@@ -143,12 +168,21 @@ namespace WebCore {
PassRefPtr<Database> openDatabase(const String& name, const String& version, const String& displayName, unsigned long estimatedSize, ExceptionCode&);
#endif
+#if ENABLE(DOM_STORAGE)
+ // HTML 5 key/value storage
+ Storage* sessionStorage() const;
+ Storage* localStorage() const;
+#endif
+
Console* console() const;
-
-#if ENABLE(CROSS_DOCUMENT_MESSAGING)
- void postMessage(const String& message, const String& domain, const String& uri, DOMWindow* source) const;
+
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ DOMApplicationCache* applicationCache() const;
#endif
+ void postMessage(const String& message, MessagePort*, const String& targetOrigin, DOMWindow* source, ExceptionCode&);
+ void postMessageTimerFired(PostMessageTimer*);
+
void scrollBy(int x, int y) const;
void scrollTo(int x, int y) const;
void scroll(int x, int y) const { scrollTo(x, y); }
@@ -159,7 +193,106 @@ namespace WebCore {
void resizeBy(float x, float y) const;
void resizeTo(float width, float height) const;
+ EventListener* onabort() const;
+ void setOnabort(PassRefPtr<EventListener>);
+ EventListener* onblur() const;
+ void setOnblur(PassRefPtr<EventListener>);
+ EventListener* onchange() const;
+ void setOnchange(PassRefPtr<EventListener>);
+ EventListener* onclick() const;
+ void setOnclick(PassRefPtr<EventListener>);
+ EventListener* ondblclick() const;
+ void setOndblclick(PassRefPtr<EventListener>);
+ EventListener* onerror() const;
+ void setOnerror(PassRefPtr<EventListener>);
+ EventListener* onfocus() const;
+ void setOnfocus(PassRefPtr<EventListener>);
+ EventListener* onkeydown() const;
+ void setOnkeydown(PassRefPtr<EventListener>);
+ EventListener* onkeypress() const;
+ void setOnkeypress(PassRefPtr<EventListener>);
+ EventListener* onkeyup() const;
+ void setOnkeyup(PassRefPtr<EventListener>);
+ EventListener* onload() const;
+ void setOnload(PassRefPtr<EventListener>);
+ EventListener* onmousedown() const;
+ void setOnmousedown(PassRefPtr<EventListener>);
+ EventListener* onmousemove() const;
+ void setOnmousemove(PassRefPtr<EventListener>);
+ EventListener* onmouseout() const;
+ void setOnmouseout(PassRefPtr<EventListener>);
+ EventListener* onmouseover() const;
+ void setOnmouseover(PassRefPtr<EventListener>);
+ EventListener* onmouseup() const;
+ void setOnmouseup(PassRefPtr<EventListener>);
+ EventListener* onmousewheel() const;
+ void setOnmousewheel(PassRefPtr<EventListener>);
+ EventListener* onreset() const;
+ void setOnreset(PassRefPtr<EventListener>);
+ EventListener* onresize() const;
+ void setOnresize(PassRefPtr<EventListener>);
+ EventListener* onscroll() const;
+ void setOnscroll(PassRefPtr<EventListener>);
+ EventListener* onsearch() const;
+ void setOnsearch(PassRefPtr<EventListener>);
+ EventListener* onselect() const;
+ void setOnselect(PassRefPtr<EventListener>);
+ EventListener* onsubmit() const;
+ void setOnsubmit(PassRefPtr<EventListener>);
+ EventListener* onunload() const;
+ void setOnunload(PassRefPtr<EventListener>);
+ EventListener* onbeforeunload() const;
+ void setOnbeforeunload(PassRefPtr<EventListener>);
+ EventListener* onwebkitanimationstart() const;
+ void setOnwebkitanimationstart(PassRefPtr<EventListener>);
+ EventListener* onwebkitanimationiteration() const;
+ void setOnwebkitanimationiteration(PassRefPtr<EventListener>);
+ EventListener* onwebkitanimationend() const;
+ void setOnwebkitanimationend(PassRefPtr<EventListener>);
+ EventListener* onwebkittransitionend() const;
+ void setOnwebkittransitionend(PassRefPtr<EventListener>);
+#if ENABLE(TOUCH_EVENTS) // Android
+ EventListener* ontouchstart() const;
+ void setOntouchstart(PassRefPtr<EventListener>);
+ EventListener* ontouchend() const;
+ void setOntouchend(PassRefPtr<EventListener>);
+ EventListener* ontouchmove() const;
+ void setOntouchmove(PassRefPtr<EventListener>);
+ EventListener* ontouchcancel() const;
+ void setOntouchcancel(PassRefPtr<EventListener>);
+#endif
+
+ // These methods are used for GC marking. See JSDOMWindow::mark() in
+ // JSDOMWindowCustom.cpp.
+ Screen* optionalScreen() const { return m_screen.get(); }
+ DOMSelection* optionalSelection() const { return m_selection.get(); }
+ History* optionalHistory() const { return m_history.get(); }
+ BarInfo* optionalLocationbar() const { return m_locationbar.get(); }
+ BarInfo* optionalMenubar() const { return m_menubar.get(); }
+ BarInfo* optionalPersonalbar() const { return m_personalbar.get(); }
+ BarInfo* optionalScrollbars() const { return m_scrollbars.get(); }
+ BarInfo* optionalStatusbar() const { return m_statusbar.get(); }
+ BarInfo* optionalToolbar() const { return m_toolbar.get(); }
+ Console* optionalConsole() const { return m_console.get(); }
+ Navigator* optionalNavigator() const { return m_navigator.get(); }
+ Location* optionalLocation() const { return m_location.get(); }
+#if ENABLE(DOM_STORAGE)
+ Storage* optionalSessionStorage() const { return m_sessionStorage.get(); }
+ Storage* optionalLocalStorage() const { return m_sessionStorage.get(); }
+#endif
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ DOMApplicationCache* optionalApplicationCache() const { return m_applicationCache.get(); }
+#endif
+
private:
+ DOMWindow(Frame*);
+
+ void setInlineEventListenerForType(const AtomicString& eventType, PassRefPtr<EventListener>);
+ EventListener* inlineEventListenerForType(const AtomicString& eventType) const;
+
+ RefPtr<SecurityOrigin> m_securityOrigin;
+ KURL m_url;
+
Frame* m_frame;
mutable RefPtr<Screen> m_screen;
mutable RefPtr<DOMSelection> m_selection;
@@ -171,6 +304,15 @@ namespace WebCore {
mutable RefPtr<BarInfo> m_statusbar;
mutable RefPtr<BarInfo> m_toolbar;
mutable RefPtr<Console> m_console;
+ mutable RefPtr<Navigator> m_navigator;
+ mutable RefPtr<Location> m_location;
+#if ENABLE(DOM_STORAGE)
+ mutable RefPtr<Storage> m_sessionStorage;
+ mutable RefPtr<Storage> m_localStorage;
+#endif
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ mutable RefPtr<DOMApplicationCache> m_applicationCache;
+#endif
};
} // namespace WebCore
diff --git a/WebCore/page/DOMWindow.idl b/WebCore/page/DOMWindow.idl
index 33850d0..ce519b5 100644
--- a/WebCore/page/DOMWindow.idl
+++ b/WebCore/page/DOMWindow.idl
@@ -26,14 +26,20 @@
module window {
interface [
- LegacyParent=KJS::Window,
- DoNotCache,
CheckDomainSecurity,
- GenerateNativeConverter,
+ CustomDefineGetter,
+ CustomDefineSetter,
+ CustomDeleteProperty,
CustomGetOwnPropertySlot,
+ CustomGetPropertyAttributes,
+ CustomGetPropertyNames,
+ CustomLookupGetter,
+ CustomLookupSetter,
+ CustomMarkFunction,
+ CustomNativeConverter,
CustomPutFunction,
- CustomDeleteProperty,
- CustomGetPropertyNames
+ GenerateNativeConverter,
+ LegacyParent=JSDOMWindowBase
] DOMWindow {
// DOM Level 0
readonly attribute Screen screen;
@@ -44,6 +50,9 @@ module window {
attribute [Replaceable] BarInfo scrollbars;
attribute [Replaceable] BarInfo statusbar;
attribute [Replaceable] BarInfo toolbar;
+ attribute [Replaceable] Navigator navigator;
+ attribute [Replaceable] Navigator clientInformation;
+ attribute [DoNotCheckDomainSecurity, CustomSetter] Location location;
DOMSelection getSelection();
@@ -130,18 +139,85 @@ module window {
in [Optional] boolean authorOnly);
attribute [Replaceable] double devicePixelRatio;
-#if defined(ENABLE_DATABASE)
+#if ENABLE_OFFLINE_WEB_APPLICATIONS
+ readonly attribute DOMApplicationCache applicationCache;
+#endif
+#if ENABLE_DATABASE
Database openDatabase(in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize)
raises(DOMException);
#endif
+#if ENABLE_DOM_STORAGE
+ readonly attribute Storage sessionStorage;
+ readonly attribute Storage localStorage;
+#endif
attribute [Replaceable] Console console;
-#if defined(ENABLE_CROSS_DOCUMENT_MESSAGING)
// cross-document messaging
- [DoNotCheckDomainSecurity, Custom] void postMessage(in DOMString message);
+ [DoNotCheckDomainSecurity, Custom] void postMessage(in DOMString message, in [Optional] MessagePort messagePort, in DOMString targetOrigin)
+ raises(DOMException);
+
+ // Timers
+ [Custom] long setTimeout(in TimeoutHandler handler, in long timeout);
+ // [Custom] long setTimeout(in DOMString code, in long timeout);
+ [Custom] void clearTimeout(in long handle);
+
+ [Custom] long setInterval(in TimeoutHandler handler, in long timeout);
+ // [Custom] long setInterval(in DOMString code, in long timeout);
+ [Custom] void clearInterval(in long handle);
+
+ // Base64
+ [Custom] DOMString atob(in DOMString string)
+ raises(DOMException);
+ [Custom] DOMString btoa(in DOMString string)
+ raises(DOMException);
+
+ // Events
+ attribute [ProtectedListener] EventListener onabort;
+ attribute [ProtectedListener] EventListener onblur;
+ attribute [ProtectedListener] EventListener onchange;
+ attribute [ProtectedListener] EventListener onclick;
+ attribute [ProtectedListener] EventListener ondblclick;
+ attribute [ProtectedListener] EventListener onerror;
+ attribute [ProtectedListener] EventListener onfocus;
+ attribute [ProtectedListener] EventListener onkeydown;
+ attribute [ProtectedListener] EventListener onkeypress;
+ attribute [ProtectedListener] EventListener onkeyup;
+ attribute [ProtectedListener] EventListener onload;
+ attribute [ProtectedListener] EventListener onmousedown;
+ attribute [ProtectedListener] EventListener onmousemove;
+ attribute [ProtectedListener] EventListener onmouseout;
+ attribute [ProtectedListener] EventListener onmouseover;
+ attribute [ProtectedListener] EventListener onmouseup;
+ attribute [ProtectedListener] EventListener onmousewheel;
+ attribute [ProtectedListener] EventListener onreset;
+ attribute [ProtectedListener] EventListener onresize;
+ attribute [ProtectedListener] EventListener onscroll;
+ attribute [ProtectedListener] EventListener onsearch;
+ attribute [ProtectedListener] EventListener onselect;
+ attribute [ProtectedListener] EventListener onsubmit;
+ attribute [ProtectedListener] EventListener onunload;
+ attribute [ProtectedListener] EventListener onbeforeunload;
+ attribute [ProtectedListener] EventListener onwebkitanimationstart;
+ attribute [ProtectedListener] EventListener onwebkitanimationiteration;
+ attribute [ProtectedListener] EventListener onwebkitanimationend;
+ attribute [ProtectedListener] EventListener onwebkittransitionend;
+#if ENABLE_TOUCH_EVENTS
+ attribute [ProtectedListener] EventListener ontouchstart;
+ attribute [ProtectedListener] EventListener ontouchend;
+ attribute [ProtectedListener] EventListener ontouchmove;
+ attribute [ProtectedListener] EventListener ontouchcancel;
#endif
+ // EventTarget interface
+ [Custom] void addEventListener(in DOMString type,
+ in EventListener listener,
+ in boolean useCapture);
+ [Custom] void removeEventListener(in DOMString type,
+ in EventListener listener,
+ in boolean useCapture);
+ // FIXME: Implement dispatchEvent
+
#if defined(LANGUAGE_JAVASCRIPT)
// Global constructors
attribute StyleSheetConstructor StyleSheet;
@@ -158,6 +234,9 @@ module window {
attribute CSSMediaRuleConstructor CSSMediaRule;
attribute CSSPageRuleConstructor CSSPageRule;
attribute CSSStyleRuleConstructor CSSStyleRule;
+
+ attribute CSSVariablesRuleConstructor CSSVariablesRule;
+ attribute CSSVariablesDeclarationConstructor CSSVariablesDeclaration;
attribute CSSStyleDeclarationConstructor CSSStyleDeclaration;
attribute MediaListConstructor MediaList;
@@ -256,6 +335,11 @@ module window {
attribute HTMLTitleElementConstructor HTMLTitleElement;
attribute HTMLUListElementConstructor HTMLUListElement;
+ attribute HTMLCollectionConstructor HTMLCollection;
+
+ attribute CanvasRenderingContext2DConstructor CanvasRenderingContext2D;
+ attribute TextMetricsConstructor TextMetrics;
+
attribute EventConstructor Event;
attribute KeyboardEventConstructor KeyboardEvent;
attribute MouseEventConstructor MouseEvent;
@@ -265,7 +349,18 @@ module window {
attribute TextEventConstructor TextEvent;
attribute UIEventConstructor UIEvent;
attribute WheelEventConstructor WheelEvent;
+ attribute MessageEventConstructor MessageEvent;
attribute EventExceptionConstructor EventException;
+#if ENABLE_TOUCH_EVENTS
+ attribute TouchEventConstructor TouchEvent;
+#endif
+
+ attribute MessagePortConstructor MessagePort;
+
+ attribute ClipboardConstructor Clipboard;
+
+ attribute FileConstructor File;
+ attribute FileListConstructor FileList;
attribute NodeFilterConstructor NodeFilter;
attribute RangeConstructor Range;
@@ -278,26 +373,28 @@ module window {
attribute DOMParserConstructor DOMParser;
attribute XMLSerializerConstructor XMLSerializer;
+ attribute XMLHttpRequestUploadConstructor XMLHttpRequestUpload;
attribute XMLHttpRequestExceptionConstructor XMLHttpRequestException;
-#if defined(ENABLE_CROSS_DOCUMENT_MESSAGING)
- attribute MessageEventConstructor MessageEvent;
+#if ENABLE_DOM_STORAGE
+ attribute StorageConstructor Storage;
+ attribute StorageEventConstructor StorageEvent;
#endif
-#if defined(ENABLE_VIDEO)
+#if ENABLE_VIDEO
attribute HTMLAudioElementConstructor HTMLAudioElement;
attribute HTMLMediaElementConstructor HTMLMediaElement;
attribute HTMLVideoElementConstructor HTMLVideoElement;
attribute MediaErrorConstructor MediaError;
#endif
-#if defined(ENABLE_XPATH)
+#if ENABLE_XPATH
attribute XPathEvaluatorConstructor XPathEvaluator;
attribute XPathResultConstructor XPathResult;
attribute XPathExceptionConstructor XPathException;
#endif
-#if defined(ENABLE_SVG)
+#if ENABLE_SVG
attribute SVGAngleConstructor SVGAngle;
attribute SVGColorConstructor SVGColor;
// attribute SVGCSSRuleConstructor SVGCSSRule;
@@ -316,7 +413,7 @@ module window {
// attribute SVGZoomAndPanConstructor SVGZoomAndPan;
#endif
-#if defined(ENABLED_SVG_FILTERS)
+#if ENABLE_SVG_FILTERS
attribute SVGComponentTransferFunctionElementConstructor SVGComponentTransferFunctionElement;
attribute SVGFEBlendElementConstructor SVGFEBlendElement;
attribute SVGFEColorMatrixElementConstructor SVGFEColorMatrixElement;
diff --git a/WebCore/page/DragController.cpp b/WebCore/page/DragController.cpp
index 8eec6e0..268397e 100644
--- a/WebCore/page/DragController.cpp
+++ b/WebCore/page/DragController.cpp
@@ -51,7 +51,6 @@
#include "MoveSelectionCommand.h"
#include "Node.h"
#include "Page.h"
-#include "PluginInfoStore.h"
#include "RenderFileUploadControl.h"
#include "RenderImage.h"
#include "ReplaceSelectionCommand.h"
@@ -60,6 +59,7 @@
#include "Settings.h"
#include "SystemTime.h"
#include "Text.h"
+#include "htmlediting.h"
#include "markup.h"
#include <wtf/RefPtr.h>
@@ -126,10 +126,10 @@ static PassRefPtr<DocumentFragment> documentFragmentFromDragData(DragData* dragD
return 0;
}
-bool DragController::dragIsMove(SelectionController* selectionController, DragData* dragData)
+bool DragController::dragIsMove(SelectionController* selection, DragData* dragData)
{
return m_document == m_dragInitiator
- && selectionController->isContentEditable()
+ && selection->isContentEditable()
&& !isCopyKeyDown();
}
@@ -288,7 +288,7 @@ DragOperation DragController::tryDocumentDrag(DragData* dragData, DragDestinatio
m_page->dragCaretController()->setSelection(dragCaret);
}
- return dragIsMove(innerFrame->selectionController(), dragData) ? DragOperationMove : DragOperationCopy;
+ return dragIsMove(innerFrame->selection(), dragData) ? DragOperationMove : DragOperationCopy;
}
m_page->dragCaretController()->clear();
@@ -313,13 +313,13 @@ DragOperation DragController::operationForLoad(DragData* dragData)
static bool setSelectionToDragCaret(Frame* frame, Selection& dragCaret, RefPtr<Range>& range, const IntPoint& point)
{
- frame->selectionController()->setSelection(dragCaret);
- if (frame->selectionController()->isNone()) {
+ frame->selection()->setSelection(dragCaret);
+ if (frame->selection()->isNone()) {
dragCaret = frame->visiblePositionForPoint(point);
- frame->selectionController()->setSelection(dragCaret);
+ frame->selection()->setSelection(dragCaret);
range = dragCaret.toRange();
}
- return !frame->selectionController()->isNone() && frame->selectionController()->isContentEditable();
+ return !frame->selection()->isNone() && frame->selection()->isContentEditable();
}
bool DragController::concludeDrag(DragData* dragData, DragDestinationAction actionMask)
@@ -343,7 +343,7 @@ bool DragController::concludeDrag(DragData* dragData, DragDestinationAction acti
return false;
if (!innerFrame)
return false;
- RefPtr<Range> innerRange = innerFrame->selectionController()->toRange();
+ RefPtr<Range> innerRange = innerFrame->selection()->toRange();
RefPtr<CSSStyleDeclaration> style = m_document->createCSSStyleDeclaration();
ExceptionCode ec;
style->setProperty("color", color.name(), ec);
@@ -360,6 +360,10 @@ bool DragController::concludeDrag(DragData* dragData, DragDestinationAction acti
}
if (HTMLInputElement* fileInput = asFileInput(element)) {
+
+ if (!fileInput->isEnabled())
+ return false;
+
if (!dragData->containsFiles())
return false;
@@ -376,8 +380,7 @@ bool DragController::concludeDrag(DragData* dragData, DragDestinationAction acti
if (!renderer)
return false;
- // Only take the first filename as <input type="file" /> can only accept one
- renderer->receiveDroppedFile(filenames[0]);
+ renderer->receiveDroppedFiles(filenames);
return true;
}
@@ -391,7 +394,7 @@ bool DragController::concludeDrag(DragData* dragData, DragDestinationAction acti
return false;
DocLoader* loader = range->ownerDocument()->docLoader();
loader->setAllowStaleResources(true);
- if (dragIsMove(innerFrame->selectionController(), dragData) || dragCaret.isContentRichlyEditable()) {
+ if (dragIsMove(innerFrame->selection(), dragData) || dragCaret.isContentRichlyEditable()) {
bool chosePlainText = false;
RefPtr<DocumentFragment> fragment = documentFragmentFromDragData(dragData, range, true, chosePlainText);
if (!fragment || !innerFrame->editor()->shouldInsertFragment(fragment, range, EditorInsertActionDropped)) {
@@ -400,14 +403,14 @@ bool DragController::concludeDrag(DragData* dragData, DragDestinationAction acti
}
m_client->willPerformDragDestinationAction(DragDestinationActionEdit, dragData);
- if (dragIsMove(innerFrame->selectionController(), dragData)) {
+ if (dragIsMove(innerFrame->selection(), dragData)) {
bool smartMove = innerFrame->selectionGranularity() == WordGranularity
&& innerFrame->editor()->smartInsertDeleteEnabled()
&& dragData->canSmartReplace();
- applyCommand(new MoveSelectionCommand(fragment, dragCaret.base(), smartMove));
+ applyCommand(MoveSelectionCommand::create(fragment, dragCaret.base(), smartMove));
} else {
if (setSelectionToDragCaret(innerFrame, dragCaret, range, point))
- applyCommand(new ReplaceSelectionCommand(m_document, fragment, true, dragData->canSmartReplace(), chosePlainText));
+ applyCommand(ReplaceSelectionCommand::create(m_document, fragment, true, dragData->canSmartReplace(), chosePlainText));
}
} else {
String text = dragData->asPlainText();
@@ -418,7 +421,7 @@ bool DragController::concludeDrag(DragData* dragData, DragDestinationAction acti
m_client->willPerformDragDestinationAction(DragDestinationActionEdit, dragData);
if (setSelectionToDragCaret(innerFrame, dragCaret, range, point))
- applyCommand(new ReplaceSelectionCommand(m_document, createFragmentFromText(range.get(), text), true, false, true));
+ applyCommand(ReplaceSelectionCommand::create(m_document, createFragmentFromText(range.get(), text), true, false, true));
}
loader->setAllowStaleResources(false);
@@ -435,7 +438,7 @@ bool DragController::canProcessDrag(DragData* dragData)
IntPoint point = m_page->mainFrame()->view()->windowToContents(dragData->clientPosition());
HitTestResult result = HitTestResult(point);
- if (!m_page->mainFrame()->renderer())
+ if (!m_page->mainFrame()->contentRenderer())
return false;
result = m_page->mainFrame()->eventHandler()->hitTestResultAtPoint(point, true);
@@ -499,7 +502,7 @@ bool DragController::mayStartDragAtEventLocation(const Frame* frame, const IntPo
ASSERT(frame);
ASSERT(frame->settings());
- if (!frame->view() || !frame->renderer())
+ if (!frame->view() || !frame->contentRenderer())
return false;
HitTestResult mouseDownTarget = HitTestResult(framePos);
@@ -554,7 +557,7 @@ static void prepareClipboardForImageDrag(Frame* src, Clipboard* clipboard, Eleme
ExceptionCode ec = 0;
range->selectNode(node, ec);
ASSERT(ec == 0);
- src->selectionController()->setSelection(Selection(range.get(), DOWNSTREAM));
+ src->selection()->setSelection(Selection(range.get(), DOWNSTREAM));
clipboard->declareAndWriteDragImage(node, !linkURL.isEmpty() ? linkURL : imageURL, label, src);
}
@@ -594,7 +597,7 @@ bool DragController::startDrag(Frame* src, Clipboard* clipboard, DragOperation s
ASSERT(src);
ASSERT(clipboard);
- if (!src->view() || !src->renderer())
+ if (!src->view() || !src->contentRenderer())
return false;
HitTestResult dragSource = HitTestResult(dragOrigin);
@@ -650,7 +653,17 @@ bool DragController::startDrag(Frame* src, Clipboard* clipboard, DragOperation s
// Simplify whitespace so the title put on the clipboard resembles what the user sees
// on the web page. This includes replacing newlines with spaces.
clipboard->writeURL(linkURL, dragSource.textContent().simplifyWhiteSpace(), src);
-
+
+ if (src->selection()->isCaret() && src->selection()->isContentEditable()) {
+ // a user can initiate a drag on a link without having any text
+ // selected. In this case, we should expand the selection to
+ // the enclosing anchor element
+ Position pos = src->selection()->base();
+ Node* node = enclosingAnchorElement(pos);
+ if (node)
+ src->selection()->setSelection(Selection::selectionFromContentsOfNode(node));
+ }
+
m_client->willPerformDragSourceAction(DragSourceActionLink, dragOrigin, clipboard);
if (!dragImage) {
dragImage = m_client->createDragImageForLink(linkURL, dragSource.textContent(), src);
@@ -660,7 +673,7 @@ bool DragController::startDrag(Frame* src, Clipboard* clipboard, DragOperation s
}
doSystemDrag(dragImage, dragLoc, mouseDraggedPoint, clipboard, src, true);
} else if (isSelected && (m_dragSourceAction & DragSourceActionSelection)) {
- RefPtr<Range> selectionRange = src->selectionController()->toRange();
+ RefPtr<Range> selectionRange = src->selection()->toRange();
ASSERT(selectionRange);
if (!clipboard->hasData())
clipboard->writeRange(selectionRange.get(), src);
diff --git a/WebCore/page/EditorClient.h b/WebCore/page/EditorClient.h
new file mode 100644
index 0000000..b36709f
--- /dev/null
+++ b/WebCore/page/EditorClient.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * 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 EditorClient_h
+#define EditorClient_h
+
+#include "EditorInsertAction.h"
+#include "PlatformString.h"
+#include "TextAffinity.h"
+#include <wtf/Forward.h>
+#include <wtf/Vector.h>
+
+#if PLATFORM(MAC)
+class NSArray;
+class NSData;
+class NSString;
+class NSURL;
+#endif
+
+namespace WebCore {
+
+class CSSStyleDeclaration;
+class EditCommand;
+class Element;
+class Frame;
+class HTMLElement;
+class KeyboardEvent;
+class Node;
+class Range;
+class Selection;
+class String;
+class VisiblePosition;
+
+struct GrammarDetail {
+ int location;
+ int length;
+ Vector<String> guesses;
+ String userDescription;
+};
+
+class EditorClient {
+public:
+ virtual ~EditorClient() { }
+ virtual void pageDestroyed() = 0;
+
+ virtual bool shouldDeleteRange(Range*) = 0;
+ virtual bool shouldShowDeleteInterface(HTMLElement*) = 0;
+ virtual bool smartInsertDeleteEnabled() = 0;
+ virtual bool isContinuousSpellCheckingEnabled() = 0;
+ virtual void toggleContinuousSpellChecking() = 0;
+ virtual bool isGrammarCheckingEnabled() = 0;
+ virtual void toggleGrammarChecking() = 0;
+ virtual int spellCheckerDocumentTag() = 0;
+
+ virtual bool isEditable() = 0;
+
+ virtual bool shouldBeginEditing(Range*) = 0;
+ virtual bool shouldEndEditing(Range*) = 0;
+ virtual bool shouldInsertNode(Node*, Range*, EditorInsertAction) = 0;
+ virtual bool shouldInsertText(const String&, Range*, EditorInsertAction) = 0;
+ virtual bool shouldChangeSelectedRange(Range* fromRange, Range* toRange, EAffinity, bool stillSelecting) = 0;
+
+ virtual bool shouldApplyStyle(CSSStyleDeclaration*, Range*) = 0;
+// virtual bool shouldChangeTypingStyle(CSSStyleDeclaration* fromStyle, CSSStyleDeclaration* toStyle) = 0;
+// virtual bool doCommandBySelector(SEL selector) = 0;
+ virtual bool shouldMoveRangeAfterDelete(Range*, Range*) = 0;
+
+ virtual void didBeginEditing() = 0;
+ virtual void respondToChangedContents() = 0;
+ virtual void respondToChangedSelection() = 0;
+ virtual void didEndEditing() = 0;
+ virtual void didWriteSelectionToPasteboard() = 0;
+ virtual void didSetSelectionTypesForPasteboard() = 0;
+// virtual void didChangeTypingStyle:(NSNotification *)notification = 0;
+// virtual void didChangeSelection:(NSNotification *)notification = 0;
+// virtual NSUndoManager* undoManager:(WebView *)webView = 0;
+
+ virtual void registerCommandForUndo(PassRefPtr<EditCommand>) = 0;
+ virtual void registerCommandForRedo(PassRefPtr<EditCommand>) = 0;
+ virtual void clearUndoRedoOperations() = 0;
+
+ virtual bool canUndo() const = 0;
+ virtual bool canRedo() const = 0;
+
+ virtual void undo() = 0;
+ virtual void redo() = 0;
+
+ virtual void handleKeyboardEvent(KeyboardEvent*) = 0;
+ virtual void handleInputMethodKeydown(KeyboardEvent*) = 0;
+
+ virtual void textFieldDidBeginEditing(Element*) = 0;
+ virtual void textFieldDidEndEditing(Element*) = 0;
+ virtual void textDidChangeInTextField(Element*) = 0;
+ virtual bool doTextFieldCommandFromEvent(Element*, KeyboardEvent*) = 0;
+ virtual void textWillBeDeletedInTextField(Element*) = 0;
+ virtual void textDidChangeInTextArea(Element*) = 0;
+
+#if PLATFORM(MAC)
+ virtual NSString* userVisibleString(NSURL*) = 0;
+#ifdef BUILDING_ON_TIGER
+ virtual NSArray* pasteboardTypesForSelection(Frame*) = 0;
+#endif
+#endif
+
+ virtual void ignoreWordInSpellDocument(const String&) = 0;
+ virtual void learnWord(const String&) = 0;
+ virtual void checkSpellingOfString(const UChar*, int length, int* misspellingLocation, int* misspellingLength) = 0;
+ virtual void checkGrammarOfString(const UChar*, int length, Vector<GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength) = 0;
+ virtual void updateSpellingUIWithGrammarString(const String&, const GrammarDetail& detail) = 0;
+ virtual void updateSpellingUIWithMisspelledWord(const String&) = 0;
+ virtual void showSpellingUI(bool show) = 0;
+ virtual bool spellingUIIsShowing() = 0;
+ virtual void getGuessesForWord(const String&, Vector<String>& guesses) = 0;
+ virtual void setInputMethodState(bool enabled) = 0;
+};
+
+}
+
+#endif // EditorClient_h
diff --git a/WebCore/page/EventHandler.cpp b/WebCore/page/EventHandler.cpp
index 4ecbe13..3f45b92 100644
--- a/WebCore/page/EventHandler.cpp
+++ b/WebCore/page/EventHandler.cpp
@@ -27,6 +27,7 @@
#include "config.h"
#include "EventHandler.h"
+#include "AXObjectCache.h"
#include "CachedImage.h"
#include "ChromeClient.h"
#include "Cursor.h"
@@ -35,6 +36,7 @@
#include "Editor.h"
#include "EventNames.h"
#include "FloatPoint.h"
+#include "FloatRect.h"
#include "FocusController.h"
#include "Frame.h"
#include "FrameLoader.h"
@@ -47,28 +49,35 @@
#include "HTMLInputElement.h"
#include "HTMLNames.h"
#include "Image.h"
+#include "InspectorController.h"
#include "KeyboardEvent.h"
#include "MouseEvent.h"
#include "MouseEventWithHitTestResults.h"
#include "Page.h"
#include "PlatformKeyboardEvent.h"
-#include "PlatformScrollBar.h"
#include "PlatformWheelEvent.h"
+#include "RenderFrameSet.h"
#include "RenderWidget.h"
+#include "RenderView.h"
+#include "Scrollbar.h"
#include "SelectionController.h"
#include "Settings.h"
#include "TextEvent.h"
#if ENABLE(SVG)
-#include "SVGCursorElement.h"
#include "SVGDocument.h"
-#include "SVGLength.h"
+#include "SVGElementInstance.h"
#include "SVGNames.h"
+#include "SVGUseElement.h"
+#endif
+
+#if ENABLE(TOUCH_EVENTS) // Android
+#include "TouchEvent.h"
+#include "PlatformTouchEvent.h"
#endif
namespace WebCore {
-using namespace EventNames;
using namespace HTMLNames;
// The link drag hysteresis is much larger than the others because there
@@ -78,7 +87,6 @@ const int LinkDragHysteresis = 40;
const int ImageDragHysteresis = 5;
const int TextDragHysteresis = 3;
const int GeneralDragHysteresis = 3;
-const double TextDragDelay = 0.15;
// Match key code of composition keydown event on windows.
// IE sends VK_PROCESSKEY which has value 229;
@@ -88,9 +96,27 @@ const int CompositionEventKeyCode = 229;
using namespace SVGNames;
#endif
-const double autoscrollInterval = 0.1;
+// When the autoscroll or the panScroll is triggered when do the scroll every 0.05s to make it smooth
+const double autoscrollInterval = 0.05;
-static Frame* subframeForTargetNode(Node* node);
+static Frame* subframeForTargetNode(Node*);
+static Frame* subframeForHitTestResult(const MouseEventWithHitTestResults&);
+
+static inline void scrollAndAcceptEvent(float delta, ScrollDirection positiveDirection, ScrollDirection negativeDirection, PlatformWheelEvent& e, Node* node)
+{
+ if (!delta)
+ return;
+ if (e.granularity() == ScrollByPageWheelEvent) {
+ if (node->renderer()->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPage, 1))
+ e.accept();
+ return;
+ }
+ float pixelsToScroll = delta > 0 ? delta : -delta;
+ if (e.granularity() == ScrollByLineWheelEvent)
+ pixelsToScroll *= cMouseWheelPixelsPerLineStep;
+ if (node->renderer()->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPixel, pixelsToScroll))
+ e.accept();
+}
EventHandler::EventHandler(Frame* frame)
: m_frame(frame)
@@ -99,9 +125,11 @@ EventHandler::EventHandler(Frame* frame)
, m_mouseDownMayStartDrag(false)
, m_mouseDownWasSingleClickInSelection(false)
, m_beganSelectingText(false)
+ , m_panScrollInProgress(false)
, m_hoverTimer(this, &EventHandler::hoverTimerFired)
, m_autoscrollTimer(this, &EventHandler::autoscrollTimerFired)
, m_autoscrollRenderer(0)
+ , m_autoscrollInProgress(false)
, m_mouseDownMayStartAutoscroll(false)
, m_mouseDownWasInSubframe(false)
#if ENABLE(SVG)
@@ -111,6 +139,8 @@ EventHandler::EventHandler(Frame* frame)
, m_capturingMouseEventsNode(0)
, m_clickCount(0)
, m_mouseDownTimestamp(0)
+ , m_pendingFrameUnloadEventCount(0)
+ , m_pendingFrameBeforeUnloadEventCount(0)
#if PLATFORM(MAC)
, m_mouseDownView(nil)
, m_sendingEventToSubview(false)
@@ -135,10 +165,17 @@ void EventHandler::clear()
m_resizeLayer = 0;
m_nodeUnderMouse = 0;
m_lastNodeUnderMouse = 0;
+#if ENABLE(SVG)
+ m_instanceUnderMouse = 0;
+ m_lastInstanceUnderMouse = 0;
+#endif
m_lastMouseMoveEventSubframe = 0;
m_lastScrollbarUnderMouse = 0;
m_clickCount = 0;
m_clickNode = 0;
+#if ENABLE(TOUCH_EVENTS) // Android
+ m_touch = 0;
+#endif
m_frameSetBeingResized = 0;
m_dragTarget = 0;
m_currentMousePosition = IntPoint();
@@ -165,7 +202,7 @@ void EventHandler::selectClosestWordFromMouseEvent(const MouseEventWithHitTestRe
}
if (m_frame->shouldChangeSelection(newSelection))
- m_frame->selectionController()->setSelection(newSelection);
+ m_frame->selection()->setSelection(newSelection);
}
}
@@ -189,7 +226,7 @@ void EventHandler::selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHit
}
if (m_frame->shouldChangeSelection(newSelection))
- m_frame->selectionController()->setSelection(newSelection);
+ m_frame->selection()->setSelection(newSelection);
}
}
@@ -198,7 +235,7 @@ bool EventHandler::handleMousePressEventDoubleClick(const MouseEventWithHitTestR
if (event.event().button() != LeftButton)
return false;
- if (m_frame->selectionController()->isRange())
+ if (m_frame->selection()->isRange())
// A double-click when range is already selected
// should not change the selection. So, do not call
// selectClosestWordFromMouseEvent, but do set
@@ -232,7 +269,7 @@ bool EventHandler::handleMousePressEventTripleClick(const MouseEventWithHitTestR
}
if (m_frame->shouldChangeSelection(newSelection))
- m_frame->selectionController()->setSelection(newSelection);
+ m_frame->selection()->setSelection(newSelection);
return true;
}
@@ -252,7 +289,7 @@ bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestR
// Don't restart the selection when the mouse is pressed on an
// existing selection so we can allow for text dragging.
IntPoint vPoint = m_frame->view()->windowToContents(event.event().pos());
- if (!extendSelection && m_frame->selectionController()->contains(vPoint)) {
+ if (!extendSelection && m_frame->selection()->contains(vPoint)) {
m_mouseDownWasSingleClickInSelection = true;
return false;
}
@@ -262,9 +299,9 @@ bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestR
visiblePos = VisiblePosition(innerNode, 0, DOWNSTREAM);
Position pos = visiblePos.deepEquivalent();
- Selection newSelection = m_frame->selectionController()->selection();
+ Selection newSelection = m_frame->selection()->selection();
if (extendSelection && newSelection.isCaretOrRange()) {
- m_frame->selectionController()->setLastChangeWasHorizontalExtension(false);
+ m_frame->selection()->setLastChangeWasHorizontalExtension(false);
// See <rdar://problem/3668157> REGRESSION (Mail): shift-click deselects when selection
// was created right-to-left
@@ -285,7 +322,7 @@ bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestR
}
if (m_frame->shouldChangeSelection(newSelection))
- m_frame->selectionController()->setSelection(newSelection);
+ m_frame->selection()->setSelection(newSelection);
return true;
}
@@ -306,7 +343,7 @@ bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& eve
m_mouseDownWasSingleClickInSelection = false;
- if (passWidgetMouseDownEventToWidget(event))
+ if (event.isOverWidget() && passWidgetMouseDownEventToWidget(event))
return true;
#if ENABLE(SVG)
@@ -332,7 +369,7 @@ bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& eve
bool swallowEvent = false;
if (event.event().button() == LeftButton || event.event().button() == MiddleButton) {
- m_frame->selectionController()->setCaretBlinkingSuspended(true);
+ m_frame->selection()->setCaretBlinkingSuspended(true);
m_mousePressed = true;
m_beganSelectingText = false;
@@ -345,7 +382,7 @@ bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& eve
}
m_mouseDownMayStartAutoscroll = m_mouseDownMayStartSelect ||
- (m_mousePressNode && m_mousePressNode->renderer() && m_mousePressNode->renderer()->shouldAutoscroll());
+ (m_mousePressNode && m_mousePressNode->renderer() && m_mousePressNode->renderer()->canBeProgramaticallyScrolled(true));
return swallowEvent;
}
@@ -368,14 +405,23 @@ bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& e
m_mouseDownMayStartDrag = false;
- if (m_mouseDownMayStartAutoscroll) {
+ if (m_mouseDownMayStartAutoscroll && !m_panScrollInProgress) {
// If the selection is contained in a layer that can scroll, that layer should handle the autoscroll
// Otherwise, let the bridge handle it so the view can scroll itself.
RenderObject* renderer = targetNode->renderer();
- while (renderer && !renderer->shouldAutoscroll())
- renderer = renderer->parent();
- if (renderer)
+ while (renderer && !renderer->canBeProgramaticallyScrolled(false)) {
+ if (!renderer->parent() && renderer->node() == renderer->document() && renderer->document()->ownerElement())
+ renderer = renderer->document()->ownerElement()->renderer();
+ else
+ renderer = renderer->parent();
+ }
+
+ if (renderer) {
+ m_autoscrollInProgress = true;
handleAutoscroll(renderer);
+ }
+
+ m_mouseDownMayStartAutoscroll = false;
}
updateSelectionForMouseDrag(targetNode, event.localPoint());
@@ -388,7 +434,7 @@ bool EventHandler::eventMayStartDrag(const PlatformMouseEvent& event) const
// that its logic needs to stay in sync with handleMouseMoveEvent() and the way we setMouseDownMayStartDrag
// in handleMousePressEvent
- if (!m_frame->renderer() || !m_frame->renderer()->hasLayer()
+ if (!m_frame->contentRenderer() || !m_frame->contentRenderer()->hasLayer()
|| event.button() != LeftButton || event.clickCount() != 1)
return false;
@@ -400,7 +446,7 @@ bool EventHandler::eventMayStartDrag(const PlatformMouseEvent& event) const
HitTestRequest request(true, false);
HitTestResult result(m_frame->view()->windowToContents(event.pos()));
- m_frame->renderer()->layer()->hitTest(request, result);
+ m_frame->contentRenderer()->layer()->hitTest(request, result);
bool srcIsDHTML;
return result.innerNode() && result.innerNode()->renderer()->draggableNode(DHTMLFlag, UAFlag, result.point().x(), result.point().y(), srcIsDHTML);
}
@@ -410,7 +456,7 @@ void EventHandler::updateSelectionForMouseDrag()
FrameView* view = m_frame->view();
if (!view)
return;
- RenderObject* renderer = m_frame->renderer();
+ RenderObject* renderer = m_frame->contentRenderer();
if (!renderer)
return;
RenderLayer* layer = renderer->layer();
@@ -445,7 +491,7 @@ void EventHandler::updateSelectionForMouseDrag(Node* targetNode, const IntPoint&
// Restart the selection if this is the first mouse move. This work is usually
// done in handleMousePressEvent, but not if the mouse press was on an existing selection.
- Selection newSelection = m_frame->selectionController()->selection();
+ Selection newSelection = m_frame->selection()->selection();
#if ENABLE(SVG)
// Special case to limit selection to the containing block for SVG text.
@@ -467,8 +513,8 @@ void EventHandler::updateSelectionForMouseDrag(Node* targetNode, const IntPoint&
newSelection.expandUsingGranularity(m_frame->selectionGranularity());
if (m_frame->shouldChangeSelection(newSelection)) {
- m_frame->selectionController()->setLastChangeWasHorizontalExtension(false);
- m_frame->selectionController()->setSelection(newSelection);
+ m_frame->selection()->setLastChangeWasHorizontalExtension(false);
+ m_frame->selection()->setSelection(newSelection);
}
}
@@ -487,14 +533,15 @@ bool EventHandler::handleMouseUp(const MouseEventWithHitTestResults& event)
bool EventHandler::handleMouseReleaseEvent(const MouseEventWithHitTestResults& event)
{
- stopAutoscrollTimer();
+ if (m_autoscrollInProgress)
+ stopAutoscrollTimer();
if (handleMouseUp(event))
return true;
// Used to prevent mouseMoveEvent from initiating a drag before
// the mouse is pressed again.
- m_frame->selectionController()->setCaretBlinkingSuspended(false);
+ m_frame->selection()->setCaretBlinkingSuspended(false);
m_mousePressed = false;
m_mouseDownMayStartDrag = false;
m_mouseDownMayStartSelect = false;
@@ -508,7 +555,7 @@ bool EventHandler::handleMouseReleaseEvent(const MouseEventWithHitTestResults& e
// However, if we are editing, place the caret.
if (m_mouseDownWasSingleClickInSelection && !m_beganSelectingText
&& m_dragStartPos == event.event().pos()
- && m_frame->selectionController()->isRange()) {
+ && m_frame->selection()->isRange()) {
Selection newSelection;
Node *node = event.targetNode();
if (node && node->isContentEditable() && node->renderer()) {
@@ -516,34 +563,96 @@ bool EventHandler::handleMouseReleaseEvent(const MouseEventWithHitTestResults& e
newSelection = Selection(pos);
}
if (m_frame->shouldChangeSelection(newSelection))
- m_frame->selectionController()->setSelection(newSelection);
+ m_frame->selection()->setSelection(newSelection);
handled = true;
}
m_frame->notifyRendererOfSelectionChange(true);
- m_frame->selectionController()->selectFrameElementInParentIfFullySelected();
+ m_frame->selection()->selectFrameElementInParentIfFullySelected();
return handled;
}
void EventHandler::handleAutoscroll(RenderObject* renderer)
{
+ // We don't want to trigger the autoscroll or the panScroll if it's already active
if (m_autoscrollTimer.isActive())
- return;
+ return;
+
setAutoscrollRenderer(renderer);
+
+#if ENABLE(PAN_SCROLLING)
+ if (m_panScrollInProgress) {
+ m_panScrollStartPos = currentMousePosition();
+ m_frame->view()->addPanScrollIcon(m_panScrollStartPos);
+ // If we're not in the top frame we notify it that we are using the panScroll
+ if (m_frame != m_frame->page()->mainFrame())
+ m_frame->page()->mainFrame()->eventHandler()->setPanScrollInProgress(true);
+ }
+#endif
+
startAutoscrollTimer();
}
void EventHandler::autoscrollTimerFired(Timer<EventHandler>*)
{
- if (!m_mousePressed) {
+ RenderObject* r = autoscrollRenderer();
+ if (!r) {
stopAutoscrollTimer();
return;
}
- if (RenderObject* r = autoscrollRenderer())
+
+ if (m_autoscrollInProgress) {
+ if (!m_mousePressed) {
+ stopAutoscrollTimer();
+ return;
+ }
r->autoscroll();
+ } else {
+ // we verify that the main frame hasn't received the order to stop the panScroll
+ if (!m_frame->page()->mainFrame()->eventHandler()->panScrollInProgress()) {
+ stopAutoscrollTimer();
+ return;
+ }
+#if ENABLE(PAN_SCROLLING)
+ setPanScrollCursor();
+ r->panScroll(m_panScrollStartPos);
+#endif
+ }
+}
+
+void EventHandler::setPanScrollCursor()
+{
+ // At the original click location we draw a 4 arrowed icon. Over this icon there won't be any scroll
+ // So we don't want to change the cursor over this area
+ const int noScrollRadius = 9;
+ bool east = m_panScrollStartPos.x() < (m_currentMousePosition.x() - noScrollRadius);
+ bool west = m_panScrollStartPos.x() > (m_currentMousePosition.x() + noScrollRadius);
+ bool north = m_panScrollStartPos.y() > (m_currentMousePosition.y() + noScrollRadius);
+ bool south = m_panScrollStartPos.y() < (m_currentMousePosition.y() - noScrollRadius);
+
+ if (north) {
+ if (east)
+ m_frame->view()->setCursor(northEastPanningCursor());
+ else if (west)
+ m_frame->view()->setCursor(northWestPanningCursor());
+ else
+ m_frame->view()->setCursor(northPanningCursor());
+ } else if (south) {
+ if (east)
+ m_frame->view()->setCursor(southEastPanningCursor());
+ else if (west)
+ m_frame->view()->setCursor(southWestPanningCursor());
+ else
+ m_frame->view()->setCursor(southPanningCursor());
+ } else if (east)
+ m_frame->view()->setCursor(eastPanningCursor());
+ else if (west)
+ m_frame->view()->setCursor(westPanningCursor());
+ else
+ m_frame->view()->setCursor(middlePanningCursor());
}
RenderObject* EventHandler::autoscrollRenderer() const
@@ -551,6 +660,20 @@ RenderObject* EventHandler::autoscrollRenderer() const
return m_autoscrollRenderer;
}
+void EventHandler::updateAutoscrollRenderer()
+{
+ if (!m_autoscrollRenderer)
+ return;
+
+ HitTestResult hitTest = hitTestResultAtPoint(m_panScrollStartPos, true);
+
+ if (Node* nodeAtPoint = hitTest.innerNode())
+ m_autoscrollRenderer = nodeAtPoint->renderer();
+
+ while (m_autoscrollRenderer && !m_autoscrollRenderer->canBeProgramaticallyScrolled(false))
+ m_autoscrollRenderer = m_autoscrollRenderer->parent();
+}
+
void EventHandler::setAutoscrollRenderer(RenderObject* renderer)
{
m_autoscrollRenderer = renderer;
@@ -561,6 +684,7 @@ void EventHandler::allowDHTMLDrag(bool& flagDHTML, bool& flagUA) const
if (!m_frame || !m_frame->document()) {
flagDHTML = false;
flagUA = false;
+ return;
}
unsigned mask = m_frame->page()->dragController()->delegateDragSourceAction(m_frame->view()->contentsToWindow(m_mouseDownPos));
@@ -571,27 +695,37 @@ void EventHandler::allowDHTMLDrag(bool& flagDHTML, bool& flagUA) const
HitTestResult EventHandler::hitTestResultAtPoint(const IntPoint& point, bool allowShadowContent)
{
HitTestResult result(point);
- if (!m_frame->renderer())
+ if (!m_frame->contentRenderer())
return result;
- m_frame->renderer()->layer()->hitTest(HitTestRequest(true, true), result);
+ m_frame->contentRenderer()->layer()->hitTest(HitTestRequest(true, true), result);
while (true) {
Node* n = result.innerNode();
- if (!n || !n->renderer() || !n->renderer()->isWidget())
+ if (!result.isOverWidget() || !n || !n->renderer() || !n->renderer()->isWidget())
break;
Widget* widget = static_cast<RenderWidget*>(n->renderer())->widget();
if (!widget || !widget->isFrameView())
break;
Frame* frame = static_cast<HTMLFrameElementBase*>(n)->contentFrame();
- if (!frame || !frame->renderer())
+ if (!frame || !frame->contentRenderer())
break;
FrameView* view = static_cast<FrameView*>(widget);
- IntPoint widgetPoint(result.localPoint().x() + view->contentsX() - n->renderer()->borderLeft() - n->renderer()->paddingLeft(),
- result.localPoint().y() + view->contentsY() - n->renderer()->borderTop() - n->renderer()->paddingTop());
+ IntPoint widgetPoint(result.localPoint().x() + view->scrollX() - n->renderer()->borderLeft() - n->renderer()->paddingLeft(),
+ result.localPoint().y() + view->scrollY() - n->renderer()->borderTop() - n->renderer()->paddingTop());
HitTestResult widgetHitTestResult(widgetPoint);
- frame->renderer()->layer()->hitTest(HitTestRequest(true, true), widgetHitTestResult);
+ frame->contentRenderer()->layer()->hitTest(HitTestRequest(true, true), widgetHitTestResult);
result = widgetHitTestResult;
}
+
+ // If our HitTestResult is not visible, then we started hit testing too far down the frame chain.
+ // Another hit test at the main frame level should get us the correct visible result.
+ Frame* resultFrame = result.innerNonSharedNode() ? result.innerNonSharedNode()->document()->frame() : 0;
+ Frame* mainFrame = m_frame->page()->mainFrame();
+ if (m_frame != mainFrame && resultFrame && resultFrame != mainFrame && !resultFrame->editor()->insideVisibleArea(result.point())) {
+ IntPoint windowPoint = resultFrame->view()->contentsToWindow(result.point());
+ IntPoint mainFramePoint = mainFrame->view()->windowToContents(windowPoint);
+ result = mainFrame->eventHandler()->hitTestResultAtPoint(mainFramePoint, allowShadowContent);
+ }
if (!allowShadowContent)
result.setToNonShadowAncestor();
@@ -607,16 +741,34 @@ void EventHandler::startAutoscrollTimer()
void EventHandler::stopAutoscrollTimer(bool rendererIsBeingDestroyed)
{
- if (m_mouseDownWasInSubframe) {
- if (Frame* subframe = subframeForTargetNode(m_mousePressNode.get()))
- subframe->eventHandler()->stopAutoscrollTimer(rendererIsBeingDestroyed);
- return;
+ if (m_autoscrollInProgress) {
+ if (m_mouseDownWasInSubframe) {
+ if (Frame* subframe = subframeForTargetNode(m_mousePressNode.get()))
+ subframe->eventHandler()->stopAutoscrollTimer(rendererIsBeingDestroyed);
+ return;
+ }
+ }
+
+ if (autoscrollRenderer()) {
+ if (!rendererIsBeingDestroyed && (m_autoscrollInProgress || m_panScrollInProgress))
+ autoscrollRenderer()->stopAutoscroll();
+#if ENABLE(PAN_SCROLLING)
+ if (m_panScrollInProgress) {
+ m_frame->view()->removePanScrollIcon();
+ m_frame->view()->setCursor(pointerCursor());
+ }
+#endif
+
+ setAutoscrollRenderer(0);
}
- if (!rendererIsBeingDestroyed && autoscrollRenderer())
- autoscrollRenderer()->stopAutoscroll();
- setAutoscrollRenderer(0);
m_autoscrollTimer.stop();
+
+ m_panScrollInProgress = false;
+ // If we're not in the top frame we notify it that we are not using the panScroll anymore
+ if (m_frame->page() && m_frame != m_frame->page()->mainFrame())
+ m_frame->page()->mainFrame()->eventHandler()->setPanScrollInProgress(false);
+ m_autoscrollInProgress = false;
}
Node* EventHandler::mousePressNode() const
@@ -652,6 +804,13 @@ IntPoint EventHandler::currentMousePosition() const
return m_currentMousePosition;
}
+Frame* subframeForHitTestResult(const MouseEventWithHitTestResults& hitTestResult)
+{
+ if (!hitTestResult.isOverWidget())
+ return 0;
+ return subframeForTargetNode(hitTestResult.targetNode());
+}
+
Frame* subframeForTargetNode(Node* node)
{
if (!node)
@@ -677,37 +836,42 @@ static bool isSubmitImage(Node* node)
// Returns true if the node's editable block is not current focused for editing
static bool nodeIsNotBeingEdited(Node* node, Frame* frame)
{
- return frame->selectionController()->rootEditableElement() != node->rootEditableElement();
+ return frame->selection()->rootEditableElement() != node->rootEditableElement();
}
-Cursor EventHandler::selectCursor(const MouseEventWithHitTestResults& event, PlatformScrollbar* scrollbar)
+Cursor EventHandler::selectCursor(const MouseEventWithHitTestResults& event, Scrollbar* scrollbar)
{
// During selection, use an I-beam no matter what we're over.
// If you're capturing mouse events for a particular node, don't treat this as a selection.
- if (m_mousePressed && m_mouseDownMayStartSelect && m_frame->selectionController()->isCaretOrRange() && !m_capturingMouseEventsNode)
+ if (m_mousePressed && m_mouseDownMayStartSelect && m_frame->selection()->isCaretOrRange() && !m_capturingMouseEventsNode)
return iBeamCursor();
Node* node = event.targetNode();
RenderObject* renderer = node ? node->renderer() : 0;
RenderStyle* style = renderer ? renderer->style() : 0;
+ if (renderer && renderer->isFrameSet()) {
+ RenderFrameSet* fs = static_cast<RenderFrameSet*>(renderer);
+ if (fs->canResizeRow(event.localPoint()))
+ return rowResizeCursor();
+ if (fs->canResizeColumn(event.localPoint()))
+ return columnResizeCursor();
+ }
+
if (style && style->cursors()) {
const CursorList* cursors = style->cursors();
for (unsigned i = 0; i < cursors->size(); ++i) {
- CachedImage* cimage = (*cursors)[i].cursorImage;
+ CachedImage* cimage = (*cursors)[i].cursorImage.get();
IntPoint hotSpot = (*cursors)[i].hotSpot;
-#if ENABLE(SVG)
- if (!cimage) {
- Element* e = node->document()->getElementById((*cursors)[i].cursorFragmentId);
- if (e && e->hasTagName(cursorTag)) {
- hotSpot.setX(int(static_cast<SVGCursorElement*>(e)->x().value()));
- hotSpot.setY(int(static_cast<SVGCursorElement*>(e)->y().value()));
- cimage = static_cast<SVGCursorElement*>(e)->cachedImage();
- }
- }
-#endif
if (!cimage)
continue;
+ // Limit the size of cursors so that they cannot be used to cover UI elements in chrome.
+ IntSize size = cimage->image()->size();
+ if (size.width() > 128 || size.height() > 128)
+ continue;
+ // Do not let the hotspot be outside the bounds of the image.
+ if (hotSpot.x() < 0 || hotSpot.y() < 0 || hotSpot.x() > size.width() || hotSpot.y() > size.height())
+ continue;
if (cimage->image()->isNull())
break;
if (!cimage->errorOccurred())
@@ -820,6 +984,10 @@ Cursor EventHandler::selectCursor(const MouseEventWithHitTestResults& event, Pla
return zoomInCursor();
case CURSOR_WEBKIT_ZOOM_OUT:
return zoomOutCursor();
+ case CURSOR_WEBKIT_GRAB:
+ return grabCursor();
+ case CURSOR_WEBKIT_GRABBING:
+ return grabbingCursor();
}
return pointerCursor();
}
@@ -839,7 +1007,7 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
m_mouseDownMayStartAutoscroll = false;
m_mouseDownPos = m_frame->view()->windowToContents(mouseEvent.pos());
m_mouseDownWasInSubframe = false;
-
+
MouseEventWithHitTestResults mev = prepareMouseEvent(HitTestRequest(false, true), mouseEvent);
if (!mev.targetNode()) {
@@ -849,7 +1017,14 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
m_mousePressNode = mev.targetNode();
- Frame* subframe = subframeForTargetNode(mev.targetNode());
+ InspectorController* inspector = m_frame->page()->inspectorController();
+ if (inspector && inspector->enabled() && inspector->searchingForNodeInPage()) {
+ inspector->handleMousePressOnNode(m_mousePressNode.get());
+ invalidateClick();
+ return true;
+ }
+
+ Frame* subframe = subframeForHitTestResult(mev);
if (subframe && passMousePressEventToSubframe(mev, subframe)) {
// Start capturing future events for this frame. We only do this if we didn't clear
// the m_mousePressed flag, which may happen if an AppKit widget entered a modal event loop.
@@ -859,6 +1034,32 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
return true;
}
+#if ENABLE(PAN_SCROLLING)
+ if (m_frame->page()->mainFrame()->eventHandler()->panScrollInProgress() || m_autoscrollInProgress) {
+ stopAutoscrollTimer();
+ invalidateClick();
+ return true;
+ }
+
+ if (mouseEvent.button() == MiddleButton && !mev.isOverLink()) {
+ RenderObject* renderer = mev.targetNode()->renderer();
+
+ while (renderer && !renderer->canBeProgramaticallyScrolled(false)) {
+ if (!renderer->parent() && renderer->node() == renderer->document() && renderer->document()->ownerElement())
+ renderer = renderer->document()->ownerElement()->renderer();
+ else
+ renderer = renderer->parent();
+ }
+
+ if (renderer) {
+ m_panScrollInProgress = true;
+ handleAutoscroll(renderer);
+ invalidateClick();
+ return true;
+ }
+ }
+#endif
+
m_clickCount = mouseEvent.clickCount();
m_clickNode = mev.targetNode();
@@ -872,7 +1073,7 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
return true;
}
- bool swallowEvent = dispatchMouseEvent(mousedownEvent, mev.targetNode(), true, m_clickCount, mouseEvent, true);
+ bool swallowEvent = dispatchMouseEvent(eventNames().mousedownEvent, mev.targetNode(), true, m_clickCount, mouseEvent, true);
// If the hit testing originally determined the event was in a scrollbar, refetch the MouseEventWithHitTestResults
// in case the scrollbar widget was destroyed when the mouse event was handled.
@@ -896,7 +1097,7 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
if (mev.targetNode()->isShadowNode() && mev.targetNode()->shadowParentNode()->hasTagName(inputTag))
mev = prepareMouseEvent(HitTestRequest(true, true), mouseEvent);
- PlatformScrollbar* scrollbar = m_frame->view()->scrollbarUnderMouse(mouseEvent);
+ Scrollbar* scrollbar = m_frame->view()->scrollbarUnderMouse(mouseEvent);
if (!scrollbar)
scrollbar = mev.scrollbar();
if (scrollbar && passMousePressEventToScrollbar(mev, scrollbar))
@@ -921,20 +1122,23 @@ bool EventHandler::handleMouseDoubleClickEvent(const PlatformMouseEvent& mouseEv
m_currentMousePosition = mouseEvent.pos();
MouseEventWithHitTestResults mev = prepareMouseEvent(HitTestRequest(false, true), mouseEvent);
- Frame* subframe = subframeForTargetNode(mev.targetNode());
+ Frame* subframe = subframeForHitTestResult(mev);
if (subframe && passMousePressEventToSubframe(mev, subframe)) {
m_capturingMouseEventsNode = 0;
return true;
}
m_clickCount = mouseEvent.clickCount();
- bool swallowMouseUpEvent = dispatchMouseEvent(mouseupEvent, mev.targetNode(), true, m_clickCount, mouseEvent, false);
+ bool swallowMouseUpEvent = dispatchMouseEvent(eventNames().mouseupEvent, mev.targetNode(), true, m_clickCount, mouseEvent, false);
bool swallowClickEvent = false;
// Don't ever dispatch click events for right clicks
if (mouseEvent.button() != RightButton && mev.targetNode() == m_clickNode)
- swallowClickEvent = dispatchMouseEvent(clickEvent, mev.targetNode(), true, m_clickCount, mouseEvent, true);
+ swallowClickEvent = dispatchMouseEvent(eventNames().clickEvent, mev.targetNode(), true, m_clickCount, mouseEvent, true);
+ if (m_lastScrollbarUnderMouse)
+ swallowMouseUpEvent = m_lastScrollbarUnderMouse->mouseUp();
+
bool swallowMouseReleaseEvent = false;
if (!swallowMouseUpEvent)
swallowMouseReleaseEvent = handleMouseReleaseEvent(mev);
@@ -983,11 +1187,11 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& mouseEvent, Hi
#endif
if (m_frameSetBeingResized)
- return dispatchMouseEvent(mousemoveEvent, m_frameSetBeingResized.get(), false, 0, mouseEvent, false);
+ return dispatchMouseEvent(eventNames().mousemoveEvent, m_frameSetBeingResized.get(), false, 0, mouseEvent, false);
// Send events right to a scrollbar if the mouse is pressed.
if (m_lastScrollbarUnderMouse && m_mousePressed)
- return m_lastScrollbarUnderMouse->handleMouseMoveEvent(mouseEvent);
+ return m_lastScrollbarUnderMouse->mouseMoved(m_lastScrollbarUnderMouse->transformEvent(mouseEvent));
// Treat mouse move events while the mouse is pressed as "read-only" in prepareMouseEvent
// if we are allowed to select.
@@ -998,7 +1202,7 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& mouseEvent, Hi
if (hoveredNode)
*hoveredNode = mev.hitTestResult();
- PlatformScrollbar* scrollbar = 0;
+ Scrollbar* scrollbar = 0;
if (m_resizeLayer && m_resizeLayer->inResizeMode())
m_resizeLayer->resize(mouseEvent, m_offsetFromResizeCorner);
@@ -1012,15 +1216,14 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& mouseEvent, Hi
if (m_lastScrollbarUnderMouse != scrollbar) {
// Send mouse exited to the old scrollbar.
if (m_lastScrollbarUnderMouse)
- m_lastScrollbarUnderMouse->handleMouseOutEvent(mouseEvent);
+ m_lastScrollbarUnderMouse->mouseExited();
m_lastScrollbarUnderMouse = m_mousePressed ? 0 : scrollbar;
}
}
bool swallowEvent = false;
- Node* targetNode = m_capturingMouseEventsNode ? m_capturingMouseEventsNode.get() : mev.targetNode();
- RefPtr<Frame> newSubframe = subframeForTargetNode(targetNode);
-
+ RefPtr<Frame> newSubframe = m_capturingMouseEventsNode.get() ? subframeForTargetNode(m_capturingMouseEventsNode.get()) : subframeForHitTestResult(mev);
+
// We want mouseouts to happen first, from the inside out. First send a move event to the last subframe so that it will fire mouseouts.
if (m_lastMouseMoveEventSubframe && m_lastMouseMoveEventSubframe->tree()->isDescendantOf(m_frame) && m_lastMouseMoveEventSubframe != newSubframe)
passMouseMoveEventToSubframe(mev, m_lastMouseMoveEventSubframe.get());
@@ -1028,11 +1231,15 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& mouseEvent, Hi
if (newSubframe) {
// Update over/out state before passing the event to the subframe.
updateMouseEventTargetNode(mev.targetNode(), mouseEvent, true);
- swallowEvent |= passMouseMoveEventToSubframe(mev, newSubframe.get(), hoveredNode);
+
+ // Event dispatch in updateMouseEventTargetNode may have caused the subframe of the target
+ // node to be detached from its FrameView, in which case the event should not be passed.
+ if (newSubframe->view())
+ swallowEvent |= passMouseMoveEventToSubframe(mev, newSubframe.get(), hoveredNode);
} else {
if (scrollbar && !m_mousePressed)
- scrollbar->handleMouseMoveEvent(mouseEvent); // Handle hover effects on platforms that support visual feedback on scrollbar hovering.
- if ((!m_resizeLayer || !m_resizeLayer->inResizeMode()) && m_frame->view())
+ scrollbar->mouseMoved(scrollbar->transformEvent(mouseEvent)); // Handle hover effects on platforms that support visual feedback on scrollbar hovering.
+ if ((!m_resizeLayer || !m_resizeLayer->inResizeMode()) && !m_frame->page()->mainFrame()->eventHandler()->panScrollInProgress() && m_frame->view())
m_frame->view()->setCursor(selectCursor(mev, scrollbar));
}
@@ -1041,7 +1248,7 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& mouseEvent, Hi
if (swallowEvent)
return true;
- swallowEvent = dispatchMouseEvent(mousemoveEvent, mev.targetNode(), false, 0, mouseEvent, true);
+ swallowEvent = dispatchMouseEvent(eventNames().mousemoveEvent, mev.targetNode(), false, 0, mouseEvent, true);
if (!swallowEvent)
swallowEvent = handleMouseDraggedEvent(mev);
@@ -1073,27 +1280,26 @@ bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& mouseEvent)
#endif
if (m_frameSetBeingResized)
- return dispatchMouseEvent(mouseupEvent, m_frameSetBeingResized.get(), true, m_clickCount, mouseEvent, false);
+ return dispatchMouseEvent(eventNames().mouseupEvent, m_frameSetBeingResized.get(), true, m_clickCount, mouseEvent, false);
if (m_lastScrollbarUnderMouse) {
invalidateClick();
- return m_lastScrollbarUnderMouse->handleMouseReleaseEvent(mouseEvent);
+ return m_lastScrollbarUnderMouse->mouseUp();
}
MouseEventWithHitTestResults mev = prepareMouseEvent(HitTestRequest(false, false, false, true), mouseEvent);
- Node* targetNode = m_capturingMouseEventsNode.get() ? m_capturingMouseEventsNode.get() : mev.targetNode();
- Frame* subframe = subframeForTargetNode(targetNode);
+ Frame* subframe = m_capturingMouseEventsNode.get() ? subframeForTargetNode(m_capturingMouseEventsNode.get()) : subframeForHitTestResult(mev);
if (subframe && passMouseReleaseEventToSubframe(mev, subframe)) {
m_capturingMouseEventsNode = 0;
return true;
}
- bool swallowMouseUpEvent = dispatchMouseEvent(mouseupEvent, mev.targetNode(), true, m_clickCount, mouseEvent, false);
+ bool swallowMouseUpEvent = dispatchMouseEvent(eventNames().mouseupEvent, mev.targetNode(), true, m_clickCount, mouseEvent, false);
// Don't ever dispatch click events for right clicks
bool swallowClickEvent = false;
if (m_clickCount > 0 && mouseEvent.button() != RightButton && mev.targetNode() == m_clickNode)
- swallowClickEvent = dispatchMouseEvent(clickEvent, mev.targetNode(), true, m_clickCount, mouseEvent, true);
+ swallowClickEvent = dispatchMouseEvent(eventNames().clickEvent, mev.targetNode(), true, m_clickCount, mouseEvent, true);
if (m_resizeLayer) {
m_resizeLayer->setInResizeMode(false);
@@ -1113,14 +1319,14 @@ bool EventHandler::dispatchDragEvent(const AtomicString& eventType, Node* dragTa
{
IntPoint contentsPos = m_frame->view()->windowToContents(event.pos());
- RefPtr<MouseEvent> me = new MouseEvent(eventType,
+ RefPtr<MouseEvent> me = MouseEvent::create(eventType,
true, true, m_frame->document()->defaultView(),
0, event.globalX(), event.globalY(), contentsPos.x(), contentsPos.y(),
event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(),
0, 0, clipboard);
ExceptionCode ec = 0;
- EventTargetNodeCast(dragTarget)->dispatchEvent(me.get(), ec, true);
+ EventTargetNodeCast(dragTarget)->dispatchEvent(me.get(), ec);
return me->defaultPrevented();
}
@@ -1151,7 +1357,7 @@ bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard*
if (newTarget->hasTagName(frameTag) || newTarget->hasTagName(iframeTag))
accept = static_cast<HTMLFrameElementBase*>(newTarget)->contentFrame()->eventHandler()->updateDragAndDrop(event, clipboard);
else
- accept = dispatchDragEvent(dragenterEvent, newTarget, event, clipboard);
+ accept = dispatchDragEvent(eventNames().dragenterEvent, newTarget, event, clipboard);
if (m_dragTarget) {
Frame* frame = (m_dragTarget->hasTagName(frameTag) || m_dragTarget->hasTagName(iframeTag))
@@ -1159,14 +1365,14 @@ bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard*
if (frame)
accept = frame->eventHandler()->updateDragAndDrop(event, clipboard);
else
- dispatchDragEvent(dragleaveEvent, m_dragTarget.get(), event, clipboard);
+ dispatchDragEvent(eventNames().dragleaveEvent, m_dragTarget.get(), event, clipboard);
}
} else {
if (newTarget)
if (newTarget->hasTagName(frameTag) || newTarget->hasTagName(iframeTag))
accept = static_cast<HTMLFrameElementBase*>(newTarget)->contentFrame()->eventHandler()->updateDragAndDrop(event, clipboard);
else
- accept = dispatchDragEvent(dragoverEvent, newTarget, event, clipboard);
+ accept = dispatchDragEvent(eventNames().dragoverEvent, newTarget, event, clipboard);
}
m_dragTarget = newTarget;
@@ -1181,7 +1387,7 @@ void EventHandler::cancelDragAndDrop(const PlatformMouseEvent& event, Clipboard*
if (frame)
frame->eventHandler()->cancelDragAndDrop(event, clipboard);
else
- dispatchDragEvent(dragleaveEvent, m_dragTarget.get(), event, clipboard);
+ dispatchDragEvent(eventNames().dragleaveEvent, m_dragTarget.get(), event, clipboard);
}
clearDragState();
}
@@ -1195,7 +1401,7 @@ bool EventHandler::performDragAndDrop(const PlatformMouseEvent& event, Clipboard
if (frame)
accept = frame->eventHandler()->performDragAndDrop(event, clipboard);
else
- accept = dispatchDragEvent(dropEvent, m_dragTarget.get(), event, clipboard);
+ accept = dispatchDragEvent(eventNames().dropEvent, m_dragTarget.get(), event, clipboard);
}
clearDragState();
return accept;
@@ -1210,11 +1416,6 @@ void EventHandler::clearDragState()
#endif
}
-Node* EventHandler::nodeUnderMouse() const
-{
- return m_nodeUnderMouse.get();
-}
-
void EventHandler::setCapturingMouseEventsNode(PassRefPtr<Node> n)
{
m_capturingMouseEventsNode = n;
@@ -1229,6 +1430,25 @@ MouseEventWithHitTestResults EventHandler::prepareMouseEvent(const HitTestReques
return m_frame->document()->prepareMouseEvent(request, documentPoint, mev);
}
+#if ENABLE(SVG)
+static inline SVGElementInstance* instanceAssociatedWithShadowTreeElement(Node* referenceNode)
+{
+ if (!referenceNode || !referenceNode->isSVGElement())
+ return 0;
+
+ Node* shadowTreeElement = referenceNode->shadowTreeRootNode();
+ if (!shadowTreeElement)
+ return 0;
+
+ Node* shadowTreeParentElement = shadowTreeElement->shadowParentNode();
+ if (!shadowTreeParentElement)
+ return 0;
+
+ ASSERT(shadowTreeParentElement->hasTagName(useTag));
+ return static_cast<SVGUseElement*>(shadowTreeParentElement)->instanceForShadowTreeElement(referenceNode);
+}
+#endif
+
void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMouseEvent& mouseEvent, bool fireMouseOverOut)
{
Node* result = targetNode;
@@ -1244,23 +1464,63 @@ void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMo
result = result->shadowAncestorNode();
}
m_nodeUnderMouse = result;
-
+#if ENABLE(SVG)
+ m_instanceUnderMouse = instanceAssociatedWithShadowTreeElement(result);
+
+ // <use> shadow tree elements may have been recloned, update node under mouse in any case
+ if (m_lastInstanceUnderMouse) {
+ SVGElement* lastCorrespondingElement = m_lastInstanceUnderMouse->correspondingElement();
+ SVGElement* lastCorrespondingUseElement = m_lastInstanceUnderMouse->correspondingUseElement();
+
+ if (lastCorrespondingElement && lastCorrespondingUseElement) {
+ HashSet<SVGElementInstance*> instances = lastCorrespondingElement->instancesForElement();
+
+ // Locate the recloned shadow tree element for our corresponding instance
+ HashSet<SVGElementInstance*>::iterator end = instances.end();
+ for (HashSet<SVGElementInstance*>::iterator it = instances.begin(); it != end; ++it) {
+ SVGElementInstance* instance = (*it);
+ ASSERT(instance->correspondingElement() == lastCorrespondingElement);
+
+ if (instance == m_lastInstanceUnderMouse)
+ continue;
+
+ if (instance->correspondingUseElement() != lastCorrespondingUseElement)
+ continue;
+
+ SVGElement* shadowTreeElement = instance->shadowTreeElement();
+ if (!shadowTreeElement->inDocument() || m_lastNodeUnderMouse == shadowTreeElement)
+ continue;
+
+ m_lastNodeUnderMouse = shadowTreeElement;
+ m_lastInstanceUnderMouse = instance;
+ break;
+ }
+ }
+ }
+#endif
+
// Fire mouseout/mouseover if the mouse has shifted to a different node.
if (fireMouseOverOut) {
if (m_lastNodeUnderMouse && m_lastNodeUnderMouse->document() != m_frame->document()) {
m_lastNodeUnderMouse = 0;
m_lastScrollbarUnderMouse = 0;
+#if ENABLE(SVG)
+ m_lastInstanceUnderMouse = 0;
+#endif
}
if (m_lastNodeUnderMouse != m_nodeUnderMouse) {
// send mouseout event to the old node
if (m_lastNodeUnderMouse)
- EventTargetNodeCast(m_lastNodeUnderMouse.get())->dispatchMouseEvent(mouseEvent, mouseoutEvent, 0, m_nodeUnderMouse.get());
+ EventTargetNodeCast(m_lastNodeUnderMouse.get())->dispatchMouseEvent(mouseEvent, eventNames().mouseoutEvent, 0, m_nodeUnderMouse.get());
// send mouseover event to the new node
if (m_nodeUnderMouse)
- EventTargetNodeCast(m_nodeUnderMouse.get())->dispatchMouseEvent(mouseEvent, mouseoverEvent, 0, m_lastNodeUnderMouse.get());
+ EventTargetNodeCast(m_nodeUnderMouse.get())->dispatchMouseEvent(mouseEvent, eventNames().mouseoverEvent, 0, m_lastNodeUnderMouse.get());
}
m_lastNodeUnderMouse = m_nodeUnderMouse;
+#if ENABLE(SVG)
+ m_lastInstanceUnderMouse = instanceAssociatedWithShadowTreeElement(m_nodeUnderMouse.get());
+#endif
}
}
@@ -1273,7 +1533,7 @@ bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targe
if (m_nodeUnderMouse)
swallowEvent = EventTargetNodeCast(m_nodeUnderMouse.get())->dispatchMouseEvent(mouseEvent, eventType, clickCount);
- if (!swallowEvent && eventType == mousedownEvent) {
+ if (!swallowEvent && eventType == eventNames().mousedownEvent) {
// Blur current focus node when a link/button is clicked; this
// is expected by some sites that rely on onChange handlers running
// from form fields before the button click is processed.
@@ -1291,8 +1551,8 @@ bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targe
// will set a selection inside it, which will call setFocuseNodeIfNeeded.
ExceptionCode ec = 0;
Node* n = node->isShadowNode() ? node->shadowParentNode() : node;
- if (m_frame->selectionController()->isRange() &&
- m_frame->selectionController()->toRange()->compareNode(n, ec) == Range::NODE_INSIDE &&
+ if (m_frame->selection()->isRange() &&
+ m_frame->selection()->toRange()->compareNode(n, ec) == Range::NODE_INSIDE &&
n->isDescendantOf(m_frame->document()->focusedNode()))
return false;
@@ -1336,7 +1596,7 @@ bool EventHandler::handleWheelEvent(PlatformWheelEvent& e)
// Figure out which view to send the event to.
RenderObject* target = node->renderer();
- if (target && target->isWidget()) {
+ if (result.isOverWidget() && target && target->isWidget()) {
Widget* widget = static_cast<RenderWidget*>(target)->widget();
if (widget && passWheelEventToWidget(e, widget)) {
@@ -1353,14 +1613,8 @@ bool EventHandler::handleWheelEvent(PlatformWheelEvent& e)
if (node->renderer()) {
// Just break up into two scrolls if we need to. Diagonal movement on
// a MacBook pro is an example of a 2-dimensional mouse wheel event (where both deltaX and deltaY can be set).
- float deltaX = e.isContinuous() ? e.continuousDeltaX() : e.deltaX();
- float deltaY = e.isContinuous() ? e.continuousDeltaY() : e.deltaY();
- if (deltaX && node->renderer()->scroll(deltaX < 0 ? ScrollRight : ScrollLeft, e.isContinuous() ? ScrollByPixel : ScrollByLine,
- deltaX < 0 ? -deltaX : deltaX))
- e.accept();
- if (deltaY && node->renderer()->scroll(deltaY < 0 ? ScrollDown : ScrollUp, e.isContinuous() ? ScrollByPixel : ScrollByLine,
- deltaY < 0 ? -deltaY : deltaY))
- e.accept();
+ scrollAndAcceptEvent(e.deltaX(), ScrollLeft, ScrollRight, e, node);
+ scrollAndAcceptEvent(e.deltaY(), ScrollUp, ScrollDown, e, node);
}
}
@@ -1381,16 +1635,19 @@ bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event)
IntPoint viewportPos = v->windowToContents(event.pos());
MouseEventWithHitTestResults mev = doc->prepareMouseEvent(HitTestRequest(false, true), viewportPos, event);
- if (!m_frame->selectionController()->contains(viewportPos) &&
+ // Context menu events shouldn't select text in GTK+ applications.
+#if !PLATFORM(GTK)
+ if (!m_frame->selection()->contains(viewportPos) &&
// FIXME: In the editable case, word selection sometimes selects content that isn't underneath the mouse.
// If the selection is non-editable, we do word selection to make it easier to use the contextual menu items
// available for text selections. But only if we're above text.
- (m_frame->selectionController()->isContentEditable() || mev.targetNode() && mev.targetNode()->isTextNode())) {
+ (m_frame->selection()->isContentEditable() || mev.targetNode() && mev.targetNode()->isTextNode())) {
m_mouseDownMayStartSelect = true; // context menu events are always allowed to perform a selection
selectClosestWordOrLinkFromMouseEvent(mev);
}
+#endif
- swallowEvent = dispatchMouseEvent(contextmenuEvent, mev.targetNode(), true, 0, event, true);
+ swallowEvent = dispatchMouseEvent(eventNames().contextmenuEvent, mev.targetNode(), true, 0, event, true);
return swallowEvent;
}
@@ -1413,7 +1670,7 @@ bool EventHandler::canMouseDownStartSelect(Node* node)
for (RenderObject* curr = node->renderer(); curr; curr = curr->parent())
if (Node* node = curr->element())
- return EventTargetNodeCast(node)->dispatchHTMLEvent(selectstartEvent, true, true);
+ return EventTargetNodeCast(node)->dispatchEventForType(eventNames().selectstartEvent, true, true);
return true;
}
@@ -1425,7 +1682,7 @@ bool EventHandler::canMouseDragExtendSelect(Node* node)
for (RenderObject* curr = node->renderer(); curr; curr = curr->parent())
if (Node* node = curr->element())
- return EventTargetNodeCast(node)->dispatchHTMLEvent(selectstartEvent, true, true);
+ return EventTargetNodeCast(node)->dispatchEventForType(eventNames().selectstartEvent, true, true);
return true;
}
@@ -1448,7 +1705,7 @@ void EventHandler::hoverTimerFired(Timer<EventHandler>*)
ASSERT(m_frame);
ASSERT(m_frame->document());
- if (RenderObject* renderer = m_frame->renderer()) {
+ if (RenderObject* renderer = m_frame->contentRenderer()) {
HitTestResult result(m_frame->view()->windowToContents(m_currentMousePosition));
renderer->layer()->hitTest(HitTestRequest(false, false, true), result);
m_frame->document()->updateRendering();
@@ -1473,21 +1730,14 @@ static EventTargetNode* eventTargetNodeForDocument(Document* doc)
bool EventHandler::handleAccessKey(const PlatformKeyboardEvent& evt)
{
-#if PLATFORM(MAC) || PLATFORM(QT)
- if (evt.ctrlKey())
-#else
- if (evt.altKey())
-#endif
- {
- String key = evt.unmodifiedText();
- Element* elem = m_frame->document()->getElementByAccessKey(key.lower());
- if (elem) {
- elem->accessKeyAction(false);
- return true;
- }
- }
-
- return false;
+ if ((evt.modifiers() & s_accessKeyModifiers) != s_accessKeyModifiers)
+ return false;
+ String key = evt.unmodifiedText();
+ Element* elem = m_frame->document()->getElementByAccessKey(key.lower());
+ if (!elem)
+ return false;
+ elem->accessKeyAction(false);
+ return true;
}
#if !PLATFORM(MAC)
@@ -1499,6 +1749,18 @@ bool EventHandler::needsKeyboardEventDisambiguationQuirks() const
bool EventHandler::keyEvent(const PlatformKeyboardEvent& initialKeyEvent)
{
+#if ENABLE(PAN_SCROLLING)
+ if (m_frame->page()->mainFrame()->eventHandler()->panScrollInProgress() || m_autoscrollInProgress) {
+ String escKeyId = "U+001B";
+ // If a key is pressed while the autoscroll/panScroll is in progress then we want to stop
+ if (initialKeyEvent.keyIdentifier() == escKeyId && initialKeyEvent.type() == PlatformKeyboardEvent::KeyUp)
+ stopAutoscrollTimer();
+
+ // If we were in autoscroll/panscroll mode, we swallow the key event
+ return true;
+ }
+#endif
+
// Check for cases where we are too early for events -- possible unmatched key up
// from pressing return in the location bar.
RefPtr<EventTargetNode> node = eventTargetNodeForDocument(m_frame->document());
@@ -1527,13 +1789,13 @@ bool EventHandler::keyEvent(const PlatformKeyboardEvent& initialKeyEvent)
PlatformKeyboardEvent keyDownEvent = initialKeyEvent;
if (keyDownEvent.type() != PlatformKeyboardEvent::RawKeyDown)
keyDownEvent.disambiguateKeyDownEvent(PlatformKeyboardEvent::RawKeyDown, backwardCompatibilityMode);
- RefPtr<KeyboardEvent> keydown = new KeyboardEvent(keyDownEvent, m_frame->document()->defaultView());
+ RefPtr<KeyboardEvent> keydown = KeyboardEvent::create(keyDownEvent, m_frame->document()->defaultView());
if (matchedAnAccessKey)
keydown->setDefaultPrevented(true);
keydown->setTarget(node);
if (initialKeyEvent.type() == PlatformKeyboardEvent::RawKeyDown) {
- node->dispatchEvent(keydown, ec, true);
+ node->dispatchEvent(keydown, ec);
return keydown->defaultHandled() || keydown->defaultPrevented();
}
@@ -1548,12 +1810,12 @@ bool EventHandler::keyEvent(const PlatformKeyboardEvent& initialKeyEvent)
if (handledByInputMethod) {
keyDownEvent.setWindowsVirtualKeyCode(CompositionEventKeyCode);
- keydown = new KeyboardEvent(keyDownEvent, m_frame->document()->defaultView());
+ keydown = KeyboardEvent::create(keyDownEvent, m_frame->document()->defaultView());
keydown->setTarget(node);
keydown->setDefaultHandled();
}
- node->dispatchEvent(keydown, ec, true);
+ node->dispatchEvent(keydown, ec);
bool keydownResult = keydown->defaultHandled() || keydown->defaultPrevented();
if (handledByInputMethod || (keydownResult && !backwardCompatibilityMode))
return keydownResult;
@@ -1570,28 +1832,59 @@ bool EventHandler::keyEvent(const PlatformKeyboardEvent& initialKeyEvent)
keyPressEvent.disambiguateKeyDownEvent(PlatformKeyboardEvent::Char, backwardCompatibilityMode);
if (keyPressEvent.text().isEmpty())
return keydownResult;
- RefPtr<KeyboardEvent> keypress = new KeyboardEvent(keyPressEvent, m_frame->document()->defaultView());
+ RefPtr<KeyboardEvent> keypress = KeyboardEvent::create(keyPressEvent, m_frame->document()->defaultView());
keypress->setTarget(node);
if (keydownResult)
keypress->setDefaultPrevented(true);
#if PLATFORM(MAC)
keypress->keypressCommands() = keydown->keypressCommands();
#endif
- node->dispatchEvent(keypress, ec, true);
+ node->dispatchEvent(keypress, ec);
return keydownResult || keypress->defaultPrevented() || keypress->defaultHandled();
}
+void EventHandler::handleKeyboardSelectionMovement(KeyboardEvent* event)
+{
+ if (!event)
+ return;
+
+ String key = event->keyIdentifier();
+ bool isShifted = event->getModifierState("Shift");
+ bool isOptioned = event->getModifierState("Alt");
+
+ if (key == "Up") {
+ m_frame->selection()->modify((isShifted) ? SelectionController::EXTEND : SelectionController::MOVE, SelectionController::BACKWARD, LineGranularity, true);
+ event->setDefaultHandled();
+ }
+ else if (key == "Down") {
+ m_frame->selection()->modify((isShifted) ? SelectionController::EXTEND : SelectionController::MOVE, SelectionController::FORWARD, LineGranularity, true);
+ event->setDefaultHandled();
+ }
+ else if (key == "Left") {
+ m_frame->selection()->modify((isShifted) ? SelectionController::EXTEND : SelectionController::MOVE, SelectionController::LEFT, (isOptioned) ? WordGranularity : CharacterGranularity, true);
+ event->setDefaultHandled();
+ }
+ else if (key == "Right") {
+ m_frame->selection()->modify((isShifted) ? SelectionController::EXTEND : SelectionController::MOVE, SelectionController::RIGHT, (isOptioned) ? WordGranularity : CharacterGranularity, true);
+ event->setDefaultHandled();
+ }
+}
+
void EventHandler::defaultKeyboardEventHandler(KeyboardEvent* event)
{
- if (event->type() == keydownEvent) {
+ if (event->type() == eventNames().keydownEvent) {
m_frame->editor()->handleKeyboardEvent(event);
if (event->defaultHandled())
return;
if (event->keyIdentifier() == "U+0009")
defaultTabEventHandler(event);
+
+ // provides KB navigation and selection for enhanced accessibility users
+ if (AXObjectCache::accessibilityEnhancedUserInterfaceEnabled())
+ handleKeyboardSelectionMovement(event);
}
- if (event->type() == keypressEvent) {
+ if (event->type() == eventNames().keypressEvent) {
m_frame->editor()->handleKeyboardEvent(event);
if (event->defaultHandled())
return;
@@ -1638,7 +1931,7 @@ void EventHandler::dragSourceMovedTo(const PlatformMouseEvent& event)
{
if (dragState().m_dragSrc && dragState().m_dragSrcMayBeDHTML)
// for now we don't care if event handler cancels default behavior, since there is none
- dispatchDragSrcEvent(dragEvent, event);
+ dispatchDragSrcEvent(eventNames().dragEvent, event);
}
void EventHandler::dragSourceEndedAt(const PlatformMouseEvent& event, DragOperation operation)
@@ -1646,7 +1939,7 @@ void EventHandler::dragSourceEndedAt(const PlatformMouseEvent& event, DragOperat
if (dragState().m_dragSrc && dragState().m_dragSrcMayBeDHTML) {
dragState().m_dragClipboard->setDestinationOperation(operation);
// for now we don't care if event handler cancels default behavior, since there is none
- dispatchDragSrcEvent(dragendEvent, event);
+ dispatchDragSrcEvent(eventNames().dragendEvent, event);
}
freeClipboard();
dragState().m_dragSrc = 0;
@@ -1684,7 +1977,7 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event)
// try to find an element that wants to be dragged
HitTestRequest request(true, false);
HitTestResult result(m_mouseDownPos);
- m_frame->renderer()->layer()->hitTest(request, result);
+ m_frame->contentRenderer()->layer()->hitTest(request, result);
Node* node = result.innerNode();
if (node && node->renderer())
dragState().m_dragSrc = node->renderer()->draggableNode(dragState().m_dragSrcMayBeDHTML, dragState().m_dragSrcMayBeUA,
@@ -1702,7 +1995,7 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event)
node = result.innerNonSharedNode();
dragState().m_dragSrcIsImage = node && node->renderer() && node->renderer()->isImage();
- dragState().m_dragSrcInSelection = m_frame->selectionController()->contains(m_mouseDownPos);
+ dragState().m_dragSrcInSelection = m_frame->selection()->contains(m_mouseDownPos);
}
}
@@ -1739,13 +2032,20 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event)
// image and offset
if (dragState().m_dragSrcIsDHTML) {
int srcX, srcY;
- dragState().m_dragSrc->renderer()->absolutePosition(srcX, srcY);
- IntSize delta = m_mouseDownPos - IntPoint(srcX, srcY);
- dragState().m_dragClipboard->setDragImageElement(dragState().m_dragSrc.get(), IntPoint() + delta);
+ if (RenderObject* renderer = dragState().m_dragSrc->renderer()) {
+ renderer->absolutePosition(srcX, srcY);
+ IntSize delta = m_mouseDownPos - IntPoint(srcX, srcY);
+ dragState().m_dragClipboard->setDragImageElement(dragState().m_dragSrc.get(), IntPoint() + delta);
+ } else {
+ // The renderer has disappeared, this can happen if the onStartDrag handler has hidden
+ // the element in some way. In this case we just kill the drag.
+ m_mouseDownMayStartDrag = false;
+ goto cleanupDrag;
+ }
}
- m_mouseDownMayStartDrag = dispatchDragSrcEvent(dragstartEvent, m_mouseDown)
- && !m_frame->selectionController()->isInPasswordField();
+ m_mouseDownMayStartDrag = dispatchDragSrcEvent(eventNames().dragstartEvent, m_mouseDown)
+ && !m_frame->selection()->isInPasswordField();
// Invalidate clipboard here against anymore pasteboard writing for security. The drag
// image can still be changed as we drag, but not the pasteboard data.
@@ -1767,11 +2067,12 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event)
bool startedDrag = dragController && dragController->startDrag(m_frame, dragState().m_dragClipboard.get(), srcOp, event.event(), m_mouseDownPos, dragState().m_dragSrcIsDHTML);
if (!startedDrag && dragState().m_dragSrcMayBeDHTML) {
// Drag was canned at the last minute - we owe m_dragSrc a DRAGEND event
- dispatchDragSrcEvent(dragendEvent, event.event());
+ dispatchDragSrcEvent(eventNames().dragendEvent, event.event());
m_mouseDownMayStartDrag = false;
}
}
-
+
+cleanupDrag:
if (!m_mouseDownMayStartDrag) {
// something failed to start the drag, cleanup
freeClipboard();
@@ -1791,7 +2092,7 @@ bool EventHandler::handleTextInputEvent(const String& text, Event* underlyingEve
// Platforms should differentiate real commands like selectAll from text input in disguise (like insertNewline),
// and avoid dispatching text input events from keydown default handlers.
if (underlyingEvent && underlyingEvent->isKeyboardEvent())
- ASSERT(static_cast<KeyboardEvent*>(underlyingEvent)->type() == keypressEvent);
+ ASSERT(static_cast<KeyboardEvent*>(underlyingEvent)->type() == eventNames().keypressEvent);
#endif
EventTarget* target;
if (underlyingEvent)
@@ -1800,12 +2101,12 @@ bool EventHandler::handleTextInputEvent(const String& text, Event* underlyingEve
target = eventTargetNodeForDocument(m_frame->document());
if (!target)
return false;
- RefPtr<TextEvent> event = new TextEvent(m_frame->domWindow(), text);
+ RefPtr<TextEvent> event = TextEvent::create(m_frame->domWindow(), text);
event->setUnderlyingEvent(underlyingEvent);
event->setIsLineBreak(isLineBreak);
event->setIsBackTab(isBackTab);
ExceptionCode ec;
- return target->dispatchEvent(event.release(), ec, true);
+ return target->dispatchEvent(event.release(), ec);
}
@@ -1873,6 +2174,175 @@ void EventHandler::capsLockStateMayHaveChanged()
if (Node* node = d->focusedNode())
if (RenderObject* r = node->renderer())
r->capsLockStateMayHaveChanged();
-}
+}
+
+unsigned EventHandler::pendingFrameUnloadEventCount()
+{
+ return m_pendingFrameUnloadEventCount;
+}
+
+void EventHandler::addPendingFrameUnloadEventCount()
+{
+ m_pendingFrameUnloadEventCount += 1;
+ m_frame->page()->changePendingUnloadEventCount(1);
+ return;
+}
+
+void EventHandler::removePendingFrameUnloadEventCount()
+{
+ ASSERT( (-1 + (int)m_pendingFrameUnloadEventCount) >= 0 );
+ m_pendingFrameUnloadEventCount -= 1;
+ m_frame->page()->changePendingUnloadEventCount(-1);
+ return;
+}
+
+void EventHandler::clearPendingFrameUnloadEventCount()
+{
+ m_frame->page()->changePendingUnloadEventCount(-((int)m_pendingFrameUnloadEventCount));
+ m_pendingFrameUnloadEventCount = 0;
+ return;
+}
+
+unsigned EventHandler::pendingFrameBeforeUnloadEventCount()
+{
+ return m_pendingFrameBeforeUnloadEventCount;
+}
+
+void EventHandler::addPendingFrameBeforeUnloadEventCount()
+{
+ m_pendingFrameBeforeUnloadEventCount += 1;
+ m_frame->page()->changePendingBeforeUnloadEventCount(1);
+ return;
+}
+
+void EventHandler::removePendingFrameBeforeUnloadEventCount()
+{
+ ASSERT( (-1 + (int)m_pendingFrameBeforeUnloadEventCount) >= 0 );
+ m_pendingFrameBeforeUnloadEventCount -= 1;
+ m_frame->page()->changePendingBeforeUnloadEventCount(-1);
+ return;
+}
+
+ void EventHandler::clearPendingFrameBeforeUnloadEventCount()
+{
+ m_frame->page()->changePendingBeforeUnloadEventCount(-((int)m_pendingFrameBeforeUnloadEventCount));
+ m_pendingFrameBeforeUnloadEventCount = 0;
+ return;
+}
+
+bool EventHandler::passMousePressEventToScrollbar(MouseEventWithHitTestResults& mev, Scrollbar* scrollbar)
+{
+ if (!scrollbar || !scrollbar->enabled())
+ return false;
+ return scrollbar->mouseDown(mev.event());
+}
+
+#if ENABLE(TOUCH_EVENTS) // Android
+bool EventHandler::handleTouchEvent(const PlatformTouchEvent& e)
+{
+ // only handle the touch event in the top frame handler
+ if (m_frame->tree()->parent(true))
+ return m_frame->tree()->parent()->eventHandler()->handleTouchEvent(e);
+
+ Document* doc = m_frame->document();
+ if (!doc)
+ return false;
+
+ RenderObject* docRenderer = doc->renderer();
+ if (!docRenderer)
+ return false;
+
+ if (doc->touchEventListeners().size() == 0)
+ return false;
+
+ TouchEventType type = e.eventType();
+ if (type == TouchEventStart) {
+ Frame* frame = m_frame;
+ IntPoint vPoint = frame->view()->windowToContents(e.pos());
+ HitTestRequest request(true, false);
+ HitTestResult result(vPoint);
+ frame->contentRenderer()->layer()->hitTest(request, result);
+ Node* node = result.innerNode();
+ if (node) {
+ RenderObject* target = node->renderer();
+ while (target && target->isWidget()) {
+ Widget* widget = static_cast<RenderWidget*>(target)->widget();
+ if (widget->isFrameView()) {
+ frame = static_cast<FrameView*>(widget)->frame();
+ vPoint = frame->view()->windowToContents(e.pos());
+ HitTestResult ret(vPoint);
+ frame->contentRenderer()->layer()->hitTest(request, ret);
+ node = ret.innerNode();
+ if (!node)
+ break;
+ else
+ target = node->renderer();
+ } else
+ // plugin view??
+ break;
+ }
+ }
+
+ if (!node || !node->isEventTargetNode()) {
+ // reset to the top document node
+ node = doc;
+ frame = m_frame;
+ vPoint = frame->view()->windowToContents(e.pos());
+ }
+
+ m_touch = Touch::create(frame, EventTargetNodeCast(node), 0,
+ e.x(), e.y(), vPoint.x(), vPoint.y());
+ } else if (m_touch) {
+ if ((type == TouchEventMove) && (e.x() == m_touch->screenX()) &&
+ (e.y() == m_touch->screenY())) {
+ // don't trigger the event if it hasn't really moved
+ return false;
+ }
+
+ IntPoint vPoint = m_touch->frame()->view()->windowToContents(e.pos());
+ m_touch->updateLocation(e.x(), e.y(), vPoint.x(), vPoint.y());
+ } else {
+ return false;
+ }
+
+ RefPtr<TouchList> touchList = TouchList::create();
+ touchList->append(m_touch);
+ RefPtr<TouchEvent> te;
+ switch(type) {
+ case TouchEventStart:
+ te = TouchEvent::create(touchList.get(), touchList.get(), touchList.get(),
+ eventNames().touchstartEvent, m_touch->frame()->document()->defaultView(),
+ m_touch->screenX(), m_touch->screenY(), m_touch->pageX(), m_touch->pageY());
+ break;
+
+ case TouchEventEnd:
+ te = TouchEvent::create(touchList.get(), touchList.get(), touchList.get(),
+ eventNames().touchendEvent, m_touch->frame()->document()->defaultView(),
+ m_touch->screenX(), m_touch->screenY(), m_touch->pageX(), m_touch->pageY());
+ break;
+
+ case TouchEventMove:
+ te = TouchEvent::create(touchList.get(), touchList.get(), touchList.get(),
+ eventNames().touchmoveEvent, m_touch->frame()->document()->defaultView(),
+ m_touch->screenX(), m_touch->screenY(), m_touch->pageX(), m_touch->pageY());
+ break;
+
+ case TouchEventCancel:
+ te = TouchEvent::create(touchList.get(), touchList.get(), touchList.get(),
+ eventNames().touchcancelEvent, m_touch->frame()->document()->defaultView(),
+ m_touch->screenX(), m_touch->screenY(), m_touch->pageX(), m_touch->pageY());
+ break;
+
+ default:
+ return false;
+ }
+ ExceptionCode ec = 0;
+ static_cast<EventTargetNode*>(m_touch->target())->dispatchEvent(te.get(), ec);
+ if (type == TouchEventEnd || type == TouchEventCancel) {
+ m_touch = 0;
+ }
+ return te->defaultPrevented();
+}
+#endif
}
diff --git a/WebCore/page/EventHandler.h b/WebCore/page/EventHandler.h
index 95a976d..8035494 100644
--- a/WebCore/page/EventHandler.h
+++ b/WebCore/page/EventHandler.h
@@ -60,15 +60,20 @@ class KeyboardEvent;
class MouseEventWithHitTestResults;
class Node;
class PlatformKeyboardEvent;
-class PlatformScrollbar;
class PlatformWheelEvent;
class RenderLayer;
class RenderObject;
class RenderWidget;
+class Scrollbar;
class String;
+class SVGElementInstance;
class TextEvent;
class VisiblePosition;
class Widget;
+#if ENABLE(TOUCH_EVENTS) // Android
+class PlatformTouchEvent;
+class Touch;
+#endif
struct HitTestRequest;
@@ -76,7 +81,6 @@ extern const int LinkDragHysteresis;
extern const int ImageDragHysteresis;
extern const int TextDragHysteresis;
extern const int GeneralDragHysteresis;
-extern const double TextDragDelay;
class EventHandler : Noncopyable {
public:
@@ -90,8 +94,12 @@ public:
Node* mousePressNode() const;
void setMousePressNode(PassRefPtr<Node>);
+ bool panScrollInProgress() { return m_panScrollInProgress; }
+ void setPanScrollInProgress(bool inProgress) { m_panScrollInProgress = inProgress; }
+
void stopAutoscrollTimer(bool rendererIsBeingDestroyed = false);
RenderObject* autoscrollRenderer() const;
+ void updateAutoscrollRenderer();
HitTestResult hitTestResultAtPoint(const IntPoint&, bool allowShadowContent);
@@ -130,12 +138,17 @@ public:
bool handleMouseReleaseEvent(const PlatformMouseEvent&);
bool handleWheelEvent(PlatformWheelEvent&);
+#if ENABLE(TOUCH_EVENTS) // Android
+ bool handleTouchEvent(const PlatformTouchEvent&);
+#endif
+
bool sendContextMenuEvent(const PlatformMouseEvent&);
void setMouseDownMayStartAutoscroll() { m_mouseDownMayStartAutoscroll = true; }
bool needsKeyboardEventDisambiguationQuirks() const;
+ static unsigned accessKeyModifiers() { return s_accessKeyModifiers; }
bool handleAccessKey(const PlatformKeyboardEvent&);
bool keyEvent(const PlatformKeyboardEvent&);
void defaultKeyboardEventHandler(KeyboardEvent*);
@@ -153,6 +166,15 @@ public:
void capsLockStateMayHaveChanged();
+ unsigned pendingFrameUnloadEventCount();
+ void addPendingFrameUnloadEventCount();
+ void removePendingFrameUnloadEventCount();
+ void clearPendingFrameUnloadEventCount();
+ unsigned pendingFrameBeforeUnloadEventCount();
+ void addPendingFrameBeforeUnloadEventCount();
+ void removePendingFrameBeforeUnloadEventCount();
+ void clearPendingFrameBeforeUnloadEventCount();
+
#if PLATFORM(MAC)
PassRefPtr<KeyboardEvent> currentKeyboardEvent() const;
@@ -182,8 +204,9 @@ private:
RefPtr<Clipboard> m_dragClipboard; // used on only the source side of dragging
};
static EventHandlerDragState& dragState();
+ static const double TextDragDelay;
- Clipboard* createDraggingClipboard() const;
+ PassRefPtr<Clipboard> createDraggingClipboard() const;
bool eventActivatedView(const PlatformMouseEvent&) const;
void selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults& event);
@@ -198,7 +221,10 @@ private:
bool handleMouseDraggedEvent(const MouseEventWithHitTestResults&);
bool handleMouseReleaseEvent(const MouseEventWithHitTestResults&);
- Cursor selectCursor(const MouseEventWithHitTestResults&, PlatformScrollbar*);
+ void handleKeyboardSelectionMovement(KeyboardEvent*);
+
+ Cursor selectCursor(const MouseEventWithHitTestResults&, Scrollbar*);
+ void setPanScrollCursor();
void hoverTimerFired(Timer<EventHandler>*);
@@ -208,7 +234,6 @@ private:
void handleAutoscroll(RenderObject*);
void startAutoscrollTimer();
void setAutoscrollRenderer(RenderObject*);
-
void autoscrollTimerFired(Timer<EventHandler>*);
void invalidateClick();
@@ -240,7 +265,7 @@ private:
bool passSubframeEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = 0);
- bool passMousePressEventToScrollbar(MouseEventWithHitTestResults&, PlatformScrollbar*);
+ bool passMousePressEventToScrollbar(MouseEventWithHitTestResults&, Scrollbar*);
bool passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults&);
bool passWidgetMouseDownEventToWidget(RenderWidget*);
@@ -279,14 +304,20 @@ private:
IntPoint m_dragStartPos;
+ IntPoint m_panScrollStartPos;
+ bool m_panScrollInProgress;
+
Timer<EventHandler> m_hoverTimer;
Timer<EventHandler> m_autoscrollTimer;
RenderObject* m_autoscrollRenderer;
+ bool m_autoscrollInProgress;
bool m_mouseDownMayStartAutoscroll;
bool m_mouseDownWasInSubframe;
#if ENABLE(SVG)
bool m_svgPan;
+ RefPtr<SVGElementInstance> m_instanceUnderMouse;
+ RefPtr<SVGElementInstance> m_lastInstanceUnderMouse;
#endif
RenderLayer* m_resizeLayer;
@@ -296,10 +327,13 @@ private:
RefPtr<Node> m_nodeUnderMouse;
RefPtr<Node> m_lastNodeUnderMouse;
RefPtr<Frame> m_lastMouseMoveEventSubframe;
- RefPtr<PlatformScrollbar> m_lastScrollbarUnderMouse;
+ RefPtr<Scrollbar> m_lastScrollbarUnderMouse;
int m_clickCount;
RefPtr<Node> m_clickNode;
+#if ENABLE(TOUCH_EVENTS) // Android
+ RefPtr<Touch> m_touch;
+#endif
RefPtr<Node> m_dragTarget;
@@ -312,6 +346,11 @@ private:
double m_mouseDownTimestamp;
PlatformMouseEvent m_mouseDown;
+ static unsigned s_accessKeyModifiers;
+
+ unsigned m_pendingFrameUnloadEventCount;
+ unsigned m_pendingFrameBeforeUnloadEventCount;
+
#if PLATFORM(MAC)
NSView *m_mouseDownView;
bool m_sendingEventToSubview;
diff --git a/WebCore/page/FocusController.cpp b/WebCore/page/FocusController.cpp
index a3542aa..9b30362 100644
--- a/WebCore/page/FocusController.cpp
+++ b/WebCore/page/FocusController.cpp
@@ -34,7 +34,6 @@
#include "Element.h"
#include "Event.h"
#include "EventHandler.h"
-#include "EventNames.h"
#include "Frame.h"
#include "FrameView.h"
#include "FrameTree.h"
@@ -51,7 +50,6 @@
namespace WebCore {
-using namespace EventNames;
using namespace HTMLNames;
FocusController::FocusController(Page* page)
@@ -65,13 +63,13 @@ void FocusController::setFocusedFrame(PassRefPtr<Frame> frame)
if (m_focusedFrame == frame)
return;
- if (m_focusedFrame)
- m_focusedFrame->selectionController()->setFocused(false);
+ if (m_focusedFrame && m_focusedFrame->view())
+ m_focusedFrame->selection()->setFocused(false);
m_focusedFrame = frame;
- if (m_focusedFrame)
- m_focusedFrame->selectionController()->setFocused(true);
+ if (m_focusedFrame && m_focusedFrame->view())
+ m_focusedFrame->selection()->setFocused(true);
}
Frame* FocusController::focusedOrMainFrame()
@@ -228,7 +226,7 @@ static void clearSelectionIfNeeded(Frame* oldFocusedFrame, Frame* newFocusedFram
if (oldFocusedFrame->document() != newFocusedFrame->document())
return;
- SelectionController* s = oldFocusedFrame->selectionController();
+ SelectionController* s = oldFocusedFrame->selection();
if (s->isNone())
return;
@@ -296,15 +294,14 @@ void FocusController::setActive(bool active)
m_isActive = active;
- // FIXME: It would be nice to make Mac use this implementation someday.
- // Right now Mac calls updateControlTints from within WebKit, and moving
- // the call to here is not simple.
-#if !PLATFORM(MAC)
- if (FrameView* view = m_page->mainFrame()->view())
- view->updateControlTints();
-#endif
+ if (FrameView* view = m_page->mainFrame()->view()) {
+ if (!view->platformWidget()) {
+ view->layoutIfNeededRecursive();
+ view->updateControlTints();
+ }
+ }
- focusedOrMainFrame()->selectionController()->pageActivationChanged();
+ focusedOrMainFrame()->selection()->pageActivationChanged();
}
} // namespace WebCore
diff --git a/WebCore/page/Frame.cpp b/WebCore/page/Frame.cpp
index 6e8081e..fa1a514 100644
--- a/WebCore/page/Frame.cpp
+++ b/WebCore/page/Frame.cpp
@@ -7,7 +7,8 @@
* 2001 George Staikos <staikos@kde.org>
* Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
* Copyright (C) 2005 Alexey Proskuryakov <ap@nypop.com>
- * Copyright (C) 2007 Trolltech ASA
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -24,6 +25,9 @@
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
+#ifdef ANDROID_INSTRUMENT
+#define LOG_TAG "WebCore"
+#endif
#include "config.h"
#include "Frame.h"
@@ -45,15 +49,18 @@
#include "FrameLoader.h"
#include "FrameView.h"
#include "GraphicsContext.h"
-#include "HitTestResult.h"
#include "HTMLDocument.h"
#include "HTMLFormElement.h"
#include "HTMLFrameElementBase.h"
-#include "HTMLGenericFormElement.h"
+#include "HTMLFormControlElement.h"
#include "HTMLNames.h"
#include "HTMLTableCellElement.h"
+#include "HitTestResult.h"
+#include "JSDOMWindowShell.h"
#include "Logging.h"
+#include "markup.h"
#include "MediaFeatureNames.h"
+#include "Navigator.h"
#include "NodeList.h"
#include "Page.h"
#include "RegularExpression.h"
@@ -67,29 +74,16 @@
#include "TextIterator.h"
#include "TextResourceDecoder.h"
#include "XMLNames.h"
-#include "bindings/NP_jsobject.h"
-#include "bindings/npruntime_impl.h"
-#include "bindings/runtime_root.h"
-#include "kjs_proxy.h"
-#include "kjs_window.h"
+#include "ScriptController.h"
+#include "npruntime_impl.h"
+#include "runtime_root.h"
#include "visible_units.h"
+#include <wtf/RefCountedLeakCounter.h>
-#ifdef MANUAL_MERGE_REQUIRED
-#ifdef ANDROID_BRIDGE
- #define LOG_TAG "webcore"
- #undef LOG
- #include <utils/Log.h>
-
- #include "WebCoreViewBridge.h"
- #include "FrameAndroid.h"
-#endif
-
-#else // MANUAL_MERGE_REQUIRED
#if FRAME_LOADS_USER_STYLESHEET
#include "UserStyleSheetLoader.h"
#endif
-#endif // MANUAL_MERGE_REQUIRED
#if ENABLE(SVG)
#include "SVGDocument.h"
#include "SVGDocumentExtensions.h"
@@ -97,34 +91,23 @@
#include "XLinkNames.h"
#endif
-using namespace std;
+#if PLATFORM(ANDROID)
+#include "WebViewCore.h"
+#endif
+
+#ifdef ANDROID_INSTRUMENT
+#include "CString.h"
+#include "Cache.h"
+#endif
-using KJS::JSLock;
+using namespace std;
namespace WebCore {
-using namespace EventNames;
using namespace HTMLNames;
-double Frame::s_currentPaintTimeStamp = 0.0;
-
-#ifndef NDEBUG
-WTFLogChannel LogWebCoreFrameLeaks = { 0x00000000, "", WTFLogChannelOn };
-
-struct FrameCounter {
- static int count;
- ~FrameCounter()
- {
- if (count)
-#ifdef ANDROID_BRIDGE
- fprintf(stderr, "LEAK: %d Frame\n", count);
-#else
- LOG(WebCoreFrameLeaks, "LEAK: %d Frame\n", count);
-#endif
- }
-};
-int FrameCounter::count = 0;
-static FrameCounter frameCounter;
+#ifndef NDEBUG
+static WTF::RefCountedLeakCounter frameCounter("Frame");
#endif
static inline Frame* parentFromOwnerElement(HTMLFrameOwnerElement* ownerElement)
@@ -153,15 +136,14 @@ Frame::Frame(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient*
if (!ownerElement)
page->setMainFrame(this);
else {
- // FIXME: Frames were originally created with a refcount of 1.
- // Leave this ref call here until we can straighten that out.
- ref();
page->incrementFrameCount();
+ // Make sure we will not end up with two frames referencing the same owner element.
+ ASSERT((!(ownerElement->m_contentFrame)) || (ownerElement->m_contentFrame->ownerElement() != ownerElement));
ownerElement->m_contentFrame = this;
}
#ifndef NDEBUG
- ++FrameCounter::count;
+ frameCounter.increment();
#endif
}
@@ -169,11 +151,6 @@ Frame::~Frame()
{
setView(0);
loader()->clearRecordedFormValues();
-
-#if PLATFORM(MAC)
- setBridge(0);
-#endif
-
loader()->cancelAndClear();
// FIXME: We should not be doing all this work inside the destructor
@@ -181,22 +158,26 @@ Frame::~Frame()
ASSERT(!d->m_lifeSupportTimer.isActive());
#ifndef NDEBUG
- --FrameCounter::count;
+ frameCounter.decrement();
#endif
- if (d->m_jscript && d->m_jscript->haveGlobalObject())
- static_cast<KJS::Window*>(d->m_jscript->globalObject())->disconnectFrame();
+ if (d->m_script.haveWindowShell())
+ d->m_script.windowShell()->disconnectFrame();
disconnectOwnerElement();
if (d->m_domWindow)
d->m_domWindow->disconnectFrame();
+
+ HashSet<DOMWindow*>::iterator end = d->m_liveFormerWindows.end();
+ for (HashSet<DOMWindow*>::iterator it = d->m_liveFormerWindows.begin(); it != end; ++it)
+ (*it)->disconnectFrame();
if (d->m_view) {
d->m_view->hide();
d->m_view->clearFrame();
}
-
+
ASSERT(!d->m_lifeSupportTimer.isActive());
#if FRAME_LOADS_USER_STYLESHEET
@@ -209,12 +190,12 @@ Frame::~Frame()
void Frame::init()
{
- d->m_loader->init();
+ d->m_loader.init();
}
FrameLoader* Frame::loader() const
{
- return d->m_loader;
+ return &d->m_loader;
}
FrameView* Frame::view() const
@@ -224,6 +205,14 @@ FrameView* Frame::view() const
void Frame::setView(FrameView* view)
{
+#if PLATFORM(ANDROID)
+ if (!view && d->m_view) {
+ // FIXME(for Cary): This is moved from FrameAndroid destructor. Do we
+ // need to call removeFrameGeneration per Frame or per FrameView?
+ android::WebViewCore::getWebViewCore(d->m_view.get())->removeFrameGeneration(this);
+ }
+#endif
+
// Detach the document now, so any onUnload handlers get run - if
// we wait until the view is destroyed, then things won't be
// hooked up enough for some JavaScript calls to work.
@@ -243,18 +232,14 @@ void Frame::setView(FrameView* view)
loader()->resetMultipleFormSubmissionProtection();
}
-KJSProxy *Frame::scriptProxy()
+ScriptController* Frame::script()
{
- if (!d->m_jscript)
- d->m_jscript = new KJSProxy(this);
- return d->m_jscript;
+ return &d->m_script;
}
-Document *Frame::document() const
+Document* Frame::document() const
{
- if (d)
- return d->m_doc.get();
- return 0;
+ return d->m_doc.get();
}
void Frame::setDocument(PassRefPtr<Document> newDoc)
@@ -265,15 +250,14 @@ void Frame::setDocument(PassRefPtr<Document> newDoc)
}
d->m_doc = newDoc;
- if (d->m_doc && selectionController()->isFocusedAndActive())
+ if (d->m_doc && selection()->isFocusedAndActive())
setUseSecureKeyboardEntry(d->m_doc->useSecureKeyboardEntryWhenActive());
if (d->m_doc && !d->m_doc->attached())
d->m_doc->attach();
-
- // Remove the cached 'document' property, which is now stale.
- if (d->m_jscript)
- d->m_jscript->clearDocumentWrapper();
+
+ // Update the cached 'document' property, which is now stale.
+ d->m_script.updateDocument();
}
Settings* Frame::settings() const
@@ -283,7 +267,7 @@ Settings* Frame::settings() const
String Frame::selectedText() const
{
- return plainText(selectionController()->toRange().get());
+ return plainText(selection()->toRange().get());
}
IntRect Frame::firstRectForRange(Range* range) const
@@ -292,11 +276,16 @@ IntRect Frame::firstRectForRange(Range* range) const
ExceptionCode ec = 0;
ASSERT(range->startContainer(ec));
ASSERT(range->endContainer(ec));
- IntRect startCaretRect = range->startContainer(ec)->renderer()->caretRect(range->startOffset(ec), DOWNSTREAM, &extraWidthToEndOfLine);
- ASSERT(!ec);
- IntRect endCaretRect = range->endContainer(ec)->renderer()->caretRect(range->endOffset(ec), UPSTREAM);
- ASSERT(!ec);
-
+ InlineBox* startInlineBox;
+ int startCaretOffset;
+ range->startPosition().getInlineBoxAndOffset(DOWNSTREAM, startInlineBox, startCaretOffset);
+ IntRect startCaretRect = range->startContainer(ec)->renderer()->caretRect(startInlineBox, startCaretOffset, &extraWidthToEndOfLine);
+
+ InlineBox* endInlineBox;
+ int endCaretOffset;
+ range->endPosition().getInlineBoxAndOffset(UPSTREAM, endInlineBox, endCaretOffset);
+ IntRect endCaretRect = range->endContainer(ec)->renderer()->caretRect(endInlineBox, endCaretOffset);
+
if (startCaretRect.y() == endCaretRect.y()) {
// start and end are on the same line
return IntRect(min(startCaretRect.x(), endCaretRect.x()),
@@ -312,7 +301,7 @@ IntRect Frame::firstRectForRange(Range* range) const
startCaretRect.height());
}
-SelectionController* Frame::selectionController() const
+SelectionController* Frame::selection() const
{
return &d->m_selectionController;
}
@@ -338,28 +327,28 @@ SelectionController* Frame::dragCaretController() const
}
-AnimationController* Frame::animationController() const
+AnimationController* Frame::animation() const
{
return &d->m_animationController;
}
-static RegularExpression *createRegExpForLabels(const Vector<String>& labels)
+static RegularExpression* createRegExpForLabels(const Vector<String>& labels)
{
// REVIEW- version of this call in FrameMac.mm caches based on the NSArray ptrs being
// the same across calls. We can't do that.
static RegularExpression wordRegExp = RegularExpression("\\w");
- DeprecatedString pattern("(");
+ String pattern("(");
unsigned int numLabels = labels.size();
unsigned int i;
for (i = 0; i < numLabels; i++) {
- DeprecatedString label = labels[i].deprecatedString();
+ String label = labels[i];
bool startsWithWordChar = false;
bool endsWithWordChar = false;
if (label.length() != 0) {
- startsWithWordChar = wordRegExp.search(label.at(0)) >= 0;
- endsWithWordChar = wordRegExp.search(label.at(label.length() - 1)) >= 0;
+ startsWithWordChar = wordRegExp.search(label.substring(0, 1)) >= 0;
+ endsWithWordChar = wordRegExp.search(label.substring(label.length() - 1, 1)) >= 0;
}
if (i != 0)
@@ -395,10 +384,10 @@ String Frame::searchForLabelsAboveCell(RegularExpression* regExp, HTMLTableCellE
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
- DeprecatedString nodeString = n->nodeValue().deprecatedString();
+ String nodeString = n->nodeValue();
int pos = regExp->searchRev(nodeString);
if (pos >= 0)
- return nodeString.mid(pos, regExp->matchedLength());
+ return nodeString.substring(pos, regExp->matchedLength());
}
}
}
@@ -442,15 +431,14 @@ String Frame::searchForLabelsBeforeElement(const Vector<String>& labels, Element
searchedCellAbove = true;
} else if (n->isTextNode() && n->renderer() && n->renderer()->style()->visibility() == VISIBLE) {
// For each text chunk, run the regexp
- DeprecatedString nodeString = n->nodeValue().deprecatedString();
+ String nodeString = n->nodeValue();
// add 100 for slop, to make it more likely that we'll search whole nodes
if (lengthSearched + nodeString.length() > maxCharsSearched)
nodeString = nodeString.right(charsSearchedThreshold - lengthSearched);
int pos = regExp->searchRev(nodeString);
if (pos >= 0)
- return nodeString.mid(pos, regExp->matchedLength());
- else
- lengthSearched += nodeString.length();
+ return nodeString.substring(pos, regExp->matchedLength());
+ lengthSearched += nodeString.length();
}
}
@@ -464,9 +452,12 @@ String Frame::searchForLabelsBeforeElement(const Vector<String>& labels, Element
String Frame::matchLabelsAgainstElement(const Vector<String>& labels, Element* element)
{
- DeprecatedString name = element->getAttribute(nameAttr).deprecatedString();
+ String name = element->getAttribute(nameAttr);
+ if (name.isEmpty())
+ return String();
+
// Make numbers and _'s in field names behave like word boundaries, e.g., "address2"
- name.replace(RegularExpression("\\d"), " ");
+ replace(name, RegularExpression("\\d"), " ");
name.replace('_', ' ');
OwnPtr<RegularExpression> regExp(createRegExpForLabels(labels));
@@ -484,12 +475,12 @@ String Frame::matchLabelsAgainstElement(const Vector<String>& labels, Element* e
bestPos = pos;
bestLength = length;
}
- start = pos+1;
+ start = pos + 1;
}
} while (pos != -1);
if (bestPos != -1)
- return name.mid(bestPos, bestLength);
+ return name.substring(bestPos, bestLength);
return String();
}
@@ -511,8 +502,8 @@ void Frame::setMark(const Selection& s)
void Frame::notifyRendererOfSelectionChange(bool userTriggered)
{
RenderObject* renderer = 0;
- if (selectionController()->rootEditableElement())
- renderer = selectionController()->rootEditableElement()->shadowAncestorNode()->renderer();
+ if (selection()->rootEditableElement())
+ renderer = selection()->rootEditableElement()->shadowAncestorNode()->renderer();
// If the current selection is in a textfield or textarea, notify the renderer that the selection has changed
if (renderer && (renderer->isTextArea() || renderer->isTextField()))
@@ -521,7 +512,7 @@ void Frame::notifyRendererOfSelectionChange(bool userTriggered)
void Frame::invalidateSelection()
{
- selectionController()->setNeedsLayout();
+ selection()->setNeedsLayout();
selectionLayoutChanged();
}
@@ -536,10 +527,10 @@ void Frame::setCaretVisible(bool flag)
void Frame::clearCaretRectIfNeeded()
{
-#ifndef ANDROID_DRAW_OWN_CARET
+#if ENABLE(TEXT_CARET)
if (d->m_caretPaint) {
d->m_caretPaint = false;
- selectionController()->invalidateCaretRect();
+ selection()->invalidateCaretRect();
}
#endif
}
@@ -559,10 +550,10 @@ static bool isFrameElement(const Node *n)
void Frame::setFocusedNodeIfNeeded()
{
- if (!document() || selectionController()->isNone() || !selectionController()->isFocusedAndActive())
+ if (!document() || selection()->isNone() || !selection()->isFocusedAndActive())
return;
- Node* target = selectionController()->rootEditableElement();
+ Node* target = selection()->rootEditableElement();
if (target) {
RenderObject* renderer = target->renderer();
@@ -586,11 +577,11 @@ void Frame::setFocusedNodeIfNeeded()
void Frame::selectionLayoutChanged()
{
- bool caretRectChanged = selectionController()->recomputeCaretRect();
+ bool caretRectChanged = selection()->recomputeCaretRect();
-#ifndef ANDROID_DRAW_OWN_CARET
+#if ENABLE(TEXT_CARET)
bool shouldBlink = d->m_caretVisible
- && selectionController()->isCaret() && selectionController()->isContentEditable();
+ && selection()->isCaret() && selection()->isContentEditable();
shouldBlink = false;
// If the caret moved, stop the blink timer so we can restart with a
@@ -604,19 +595,19 @@ void Frame::selectionLayoutChanged()
d->m_caretBlinkTimer.startRepeating(theme()->caretBlinkFrequency());
if (!d->m_caretPaint) {
d->m_caretPaint = true;
- selectionController()->invalidateCaretRect();
+ selection()->invalidateCaretRect();
}
}
#else
- if (caretRectChanged == false)
+ if (!caretRectChanged)
return;
#endif
- if (!renderer())
+ RenderView* canvas = contentRenderer();
+ if (!canvas)
return;
- RenderView* canvas = static_cast<RenderView*>(renderer());
- Selection selection = selectionController()->selection();
+ Selection selection = this->selection()->selection();
if (!selection.isRange())
canvas->clearSelection();
@@ -625,10 +616,10 @@ void Frame::selectionLayoutChanged()
// 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.visibleStart().deepEquivalent();
+ Position startPos = selection.start();
if (startPos.downstream().isCandidate())
startPos = startPos.downstream();
- Position endPos = selection.visibleEnd().deepEquivalent();
+ Position endPos = selection.end();
if (endPos.upstream().isCandidate())
endPos = endPos.upstream();
@@ -644,28 +635,28 @@ void Frame::selectionLayoutChanged()
void Frame::caretBlinkTimerFired(Timer<Frame>*)
{
-#ifndef ANDROID_DRAW_OWN_CARET
+#if ENABLE(TEXT_CARET)
ASSERT(d->m_caretVisible);
- ASSERT(selectionController()->isCaret());
+ ASSERT(selection()->isCaret());
bool caretPaint = d->m_caretPaint;
- if (selectionController()->isCaretBlinkingSuspended() && caretPaint)
+ if (selection()->isCaretBlinkingSuspended() && caretPaint)
return;
d->m_caretPaint = !caretPaint;
- selectionController()->invalidateCaretRect();
+ selection()->invalidateCaretRect();
#endif
}
void Frame::paintCaret(GraphicsContext* p, const IntRect& rect) const
{
-#ifndef ANDROID_DRAW_OWN_CARET
+#if ENABLE(TEXT_CARET)
if (d->m_caretPaint && d->m_caretVisible)
- selectionController()->paintCaret(p, rect);
+ selection()->paintCaret(p, rect);
#endif
}
void Frame::paintDragCaret(GraphicsContext* p, const IntRect& rect) const
{
-#ifndef ANDROID_DRAW_OWN_CARET
+#if ENABLE(TEXT_CARET)
SelectionController* dragCaretController = d->m_page->dragCaretController();
ASSERT(dragCaretController->selection().isCaret());
if (dragCaretController->selection().start().node()->document()->frame() == this)
@@ -673,35 +664,68 @@ void Frame::paintDragCaret(GraphicsContext* p, const IntRect& rect) const
#endif
}
-int Frame::zoomFactor() const
+float Frame::zoomFactor() const
+{
+ return d->m_zoomFactor;
+}
+
+bool Frame::isZoomFactorTextOnly() const
{
- return d->m_zoomFactor;
+ return d->m_page->settings()->zoomsTextOnly();
}
-void Frame::setZoomFactor(int percent)
+bool Frame::shouldApplyTextZoom() const
+{
+ if (d->m_zoomFactor == 1.0f || !isZoomFactorTextOnly())
+ return false;
+#if ENABLE(SVG)
+ if (d->m_doc && d->m_doc->isSVGDocument())
+ return false;
+#endif
+ return true;
+}
+
+bool Frame::shouldApplyPageZoom() const
+{
+ if (d->m_zoomFactor == 1.0f || isZoomFactorTextOnly())
+ return false;
+#if ENABLE(SVG)
+ if (d->m_doc && d->m_doc->isSVGDocument())
+ return false;
+#endif
+ return true;
+}
+
+void Frame::setZoomFactor(float percent, bool isTextOnly)
{
- if (d->m_zoomFactor == percent)
- return;
+ if (d->m_zoomFactor == percent && isZoomFactorTextOnly())
+ return;
#if ENABLE(SVG)
+ // SVG doesn't care if the zoom factor is text only. It will always apply a
+ // zoom to the whole SVG.
if (d->m_doc && d->m_doc->isSVGDocument()) {
if (!static_cast<SVGDocument*>(d->m_doc.get())->zoomAndPanEnabled())
return;
d->m_zoomFactor = percent;
+ d->m_page->settings()->setZoomsTextOnly(true); // We do this to avoid doing any scaling of CSS pixels, since the SVG has its own notion of zoom.
if (d->m_doc->renderer())
d->m_doc->renderer()->repaint();
return;
}
#endif
- d->m_zoomFactor = percent;
- if (d->m_doc)
- d->m_doc->recalcStyle(Node::Force);
- for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
- child->setZoomFactor(d->m_zoomFactor);
+ d->m_zoomFactor = percent;
+ d->m_page->settings()->setZoomsTextOnly(isTextOnly);
+
+ if (d->m_doc)
+ d->m_doc->recalcStyle(Node::Force);
+
+ for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
+ child->setZoomFactor(d->m_zoomFactor, isTextOnly);
- if (d->m_doc && d->m_doc->renderer() && d->m_doc->renderer()->needsLayout())
- view()->layout();
+ if (d->m_doc && d->m_doc->renderer() && d->m_doc->renderer()->needsLayout() && view()->didFirstLayout())
+ view()->layout();
}
void Frame::setPrinting(bool printing, float minPageWidth, float maxPageWidth, bool adjustViewSize)
@@ -751,7 +775,8 @@ void Frame::setNeedsReapplyStyles()
// Invalidate the FrameView so that FrameView::layout will get called,
// which calls reapplyStyles.
- view()->invalidate();
+ if (view())
+ view()->invalidate();
}
bool Frame::needsReapplyStyles() const
@@ -787,7 +812,7 @@ void Frame::reapplyStyles()
bool Frame::shouldChangeSelection(const Selection& newSelection) const
{
- return shouldChangeSelection(selectionController()->selection(), newSelection, newSelection.affinity(), false);
+ return shouldChangeSelection(selection()->selection(), newSelection, newSelection.affinity(), false);
}
bool Frame::shouldChangeSelection(const Selection& oldSelection, const Selection& newSelection, EAffinity affinity, bool stillSelecting) const
@@ -820,7 +845,7 @@ void Frame::setUseSecureKeyboardEntry(bool)
void Frame::updateSecureKeyboardEntryIfActive()
{
- if (selectionController()->isFocusedAndActive())
+ if (selection()->isFocusedAndActive())
setUseSecureKeyboardEntry(d->m_doc->useSecureKeyboardEntryWhenActive());
}
@@ -853,15 +878,14 @@ void Frame::computeAndSetTypingStyle(CSSStyleDeclaration *style, EditAction edit
mutableStyle = typingStyle();
}
- Node *node = selectionController()->selection().visibleStart().deepEquivalent().node();
- CSSComputedStyleDeclaration computedStyle(node);
- computedStyle.diff(mutableStyle.get());
+ Node* node = selection()->selection().visibleStart().deepEquivalent().node();
+ computedStyle(node)->diff(mutableStyle.get());
// Handle block styles, substracting these from the typing style.
RefPtr<CSSMutableStyleDeclaration> blockStyle = mutableStyle->copyBlockProperties();
blockStyle->diff(mutableStyle.get());
if (document() && blockStyle->length() > 0)
- applyCommand(new ApplyStyleCommand(document(), blockStyle.get(), editingAction));
+ applyCommand(ApplyStyleCommand::create(document(), blockStyle.get(), editingAction));
// Set the remaining style as the typing style.
d->m_typingStyle = mutableStyle.release();
@@ -885,17 +909,17 @@ String Frame::selectionStartStylePropertyValue(int stylePropertyID) const
return value;
}
-CSSComputedStyleDeclaration *Frame::selectionComputedStyle(Node *&nodeToRemove) const
+PassRefPtr<CSSComputedStyleDeclaration> Frame::selectionComputedStyle(Node*& nodeToRemove) const
{
nodeToRemove = 0;
if (!document())
return 0;
- if (selectionController()->isNone())
+ if (selection()->isNone())
return 0;
- RefPtr<Range> range(selectionController()->toRange());
+ RefPtr<Range> range(selection()->toRange());
Position pos = range->editingStartPosition();
Element *elem = pos.element();
@@ -932,7 +956,7 @@ CSSComputedStyleDeclaration *Frame::selectionComputedStyle(Node *&nodeToRemove)
nodeToRemove = styleElement.get();
}
- return new CSSComputedStyleDeclaration(styleElement);
+ return computedStyle(styleElement.release());
}
void Frame::textFieldDidBeginEditing(Element* e)
@@ -1006,11 +1030,11 @@ void Frame::applyEditingStyleToElement(Element* element) const
ASSERT(style);
ExceptionCode ec = 0;
- style->setProperty(CSS_PROP_WORD_WRAP, "break-word", false, ec);
+ style->setProperty(CSSPropertyWordWrap, "break-word", false, ec);
ASSERT(ec == 0);
- style->setProperty(CSS_PROP__WEBKIT_NBSP_MODE, "space", false, ec);
+ style->setProperty(CSSPropertyWebkitNbspMode, "space", false, ec);
ASSERT(ec == 0);
- style->setProperty(CSS_PROP__WEBKIT_LINE_BREAK, "after-white-space", false, ec);
+ style->setProperty(CSSPropertyWebkitLineBreak, "after-white-space", false, ec);
ASSERT(ec == 0);
}
@@ -1058,141 +1082,88 @@ void Frame::lifeSupportTimerFired(Timer<Frame>*)
deref();
}
-KJS::Bindings::RootObject* Frame::bindingRootObject()
+void Frame::clearDOMWindow()
{
- if (!scriptProxy()->isEnabled())
- return 0;
-
- if (!d->m_bindingRootObject) {
- JSLock lock;
- d->m_bindingRootObject = KJS::Bindings::RootObject::create(0, scriptProxy()->globalObject());
+ if (d->m_domWindow) {
+ d->m_liveFormerWindows.add(d->m_domWindow.get());
+ d->m_domWindow->clear();
}
- return d->m_bindingRootObject.get();
+ d->m_domWindow = 0;
}
-PassRefPtr<KJS::Bindings::RootObject> Frame::createRootObject(void* nativeHandle, KJS::JSGlobalObject* globalObject)
-{
- RootObjectMap::iterator it = d->m_rootObjects.find(nativeHandle);
- if (it != d->m_rootObjects.end())
- return it->second;
-
- RefPtr<KJS::Bindings::RootObject> rootObject = KJS::Bindings::RootObject::create(nativeHandle, globalObject);
-
- d->m_rootObjects.set(nativeHandle, rootObject);
- return rootObject.release();
-}
-
-#if USE(NPOBJECT)
-NPObject* Frame::windowScriptNPObject()
-{
- if (!d->m_windowScriptNPObject) {
- if (scriptProxy()->isEnabled()) {
- // JavaScript is enabled, so there is a JavaScript window object. Return an NPObject bound to the window
- // object.
- KJS::JSLock lock;
- KJS::JSObject* win = KJS::Window::retrieveWindow(this);
- ASSERT(win);
- KJS::Bindings::RootObject* root = bindingRootObject();
- d->m_windowScriptNPObject = _NPN_CreateScriptObject(0, win, root);
- } else {
- // JavaScript is not enabled, so we cannot bind the NPObject to the JavaScript window object.
- // Instead, we create an NPObject of a different class, one which is not bound to a JavaScript object.
- d->m_windowScriptNPObject = _NPN_CreateNoScriptObject();
- }
- }
-
- return d->m_windowScriptNPObject;
-}
-#endif
-
-void Frame::clearScriptProxy()
+RenderView* Frame::contentRenderer() const
{
- if (d->m_jscript)
- d->m_jscript->clear();
+ Document* doc = document();
+ if (!doc)
+ return 0;
+ RenderObject* object = doc->renderer();
+ if (!object)
+ return 0;
+ ASSERT(object->isRenderView());
+ return static_cast<RenderView*>(object);
}
-void Frame::clearDOMWindow()
+HTMLFrameOwnerElement* Frame::ownerElement() const
{
- if (d->m_domWindow)
- d->m_domWindow->clear();
+ return d->m_ownerElement;
}
-void Frame::cleanupScriptObjectsForPlugin(void* nativeHandle)
+RenderPart* Frame::ownerRenderer() const
{
- RootObjectMap::iterator it = d->m_rootObjects.find(nativeHandle);
-
- if (it == d->m_rootObjects.end())
- return;
-
- it->second->invalidate();
- d->m_rootObjects.remove(it);
+ HTMLFrameOwnerElement* ownerElement = d->m_ownerElement;
+ if (!ownerElement)
+ return 0;
+ RenderObject* object = ownerElement->renderer();
+ if (!object)
+ return 0;
+ // FIXME: If <object> is ever fixed to disassociate itself from frames
+ // that it has started but canceled, then this can turn into an ASSERT
+ // since d->m_ownerElement would be 0 when the load is canceled.
+ // https://bugs.webkit.org/show_bug.cgi?id=18585
+ if (!object->isRenderPart())
+ return 0;
+ return static_cast<RenderPart*>(object);
}
-
-void Frame::clearScriptObjects()
-{
- JSLock lock;
-
- RootObjectMap::const_iterator end = d->m_rootObjects.end();
- for (RootObjectMap::const_iterator it = d->m_rootObjects.begin(); it != end; ++it)
- it->second->invalidate();
-
- d->m_rootObjects.clear();
- if (d->m_bindingRootObject) {
- d->m_bindingRootObject->invalidate();
- d->m_bindingRootObject = 0;
- }
-
-#if USE(NPOBJECT)
- if (d->m_windowScriptNPObject) {
- // Call _NPN_DeallocateObject() instead of _NPN_ReleaseObject() so that we don't leak if a plugin fails to release the window
- // script object properly.
- // This shouldn't cause any problems for plugins since they should have already been stopped and destroyed at this point.
- _NPN_DeallocateObject(d->m_windowScriptNPObject);
- d->m_windowScriptNPObject = 0;
- }
-#endif
-
- clearPlatformScriptObjects();
+bool Frame::isDisconnected() const
+{
+ return d->m_isDisconnected;
}
-RenderObject *Frame::renderer() const
+void Frame::setIsDisconnected(bool isDisconnected)
{
- Document *doc = document();
- return doc ? doc->renderer() : 0;
+ d->m_isDisconnected = isDisconnected;
}
-HTMLFrameOwnerElement* Frame::ownerElement() const
+bool Frame::excludeFromTextSearch() const
{
- return d->m_ownerElement;
+ return d->m_excludeFromTextSearch;
}
-RenderPart* Frame::ownerRenderer()
+void Frame::setExcludeFromTextSearch(bool exclude)
{
- HTMLFrameOwnerElement* ownerElement = d->m_ownerElement;
- if (!ownerElement)
- return 0;
- return static_cast<RenderPart*>(ownerElement->renderer());
+ d->m_excludeFromTextSearch = exclude;
}
// returns FloatRect because going through IntRect would truncate any floats
FloatRect Frame::selectionRect(bool clipToVisibleContent) const
{
- RenderView *root = static_cast<RenderView*>(renderer());
- if (!root)
+ RenderView* root = contentRenderer();
+ FrameView* view = d->m_view.get();
+ if (!root || !view)
return IntRect();
IntRect selectionRect = root->selectionRect(clipToVisibleContent);
- return clipToVisibleContent ? intersection(selectionRect, d->m_view->visibleContentRect()) : selectionRect;
+ return clipToVisibleContent ? intersection(selectionRect, view->visibleContentRect()) : selectionRect;
}
void Frame::selectionTextRects(Vector<FloatRect>& rects, bool clipToVisibleContent) const
{
- RenderView *root = static_cast<RenderView*>(renderer());
+ RenderView* root = contentRenderer();
if (!root)
return;
- RefPtr<Range> selectedRange = selectionController()->toRange();
+ RefPtr<Range> selectedRange = selection()->toRange();
Vector<IntRect> intRects;
selectedRange->addLineBoxRects(intRects, true);
@@ -1224,7 +1195,7 @@ static HTMLFormElement *scanForForm(Node *start)
if (n->hasTagName(formTag))
return static_cast<HTMLFormElement*>(n);
else if (n->isHTMLElement() && static_cast<HTMLElement*>(n)->isGenericFormElement())
- return static_cast<HTMLGenericFormElement*>(n)->form();
+ return static_cast<HTMLFormControlElement*>(n)->form();
else if (n->hasTagName(frameTag) || n->hasTagName(iframeTag)) {
Node *childDoc = static_cast<HTMLFrameElementBase*>(n)->contentDocument();
if (HTMLFormElement *frameResult = scanForForm(childDoc))
@@ -1240,7 +1211,7 @@ HTMLFormElement *Frame::currentForm() const
// start looking either at the active (first responder) node, or where the selection is
Node *start = d->m_doc ? d->m_doc->focusedNode() : 0;
if (!start)
- start = selectionController()->start().node();
+ start = selection()->start().node();
// try walking up the node tree to find a form element
Node *n;
@@ -1249,7 +1220,7 @@ HTMLFormElement *Frame::currentForm() const
return static_cast<HTMLFormElement*>(n);
else if (n->isHTMLElement()
&& static_cast<HTMLElement*>(n)->isGenericFormElement())
- return static_cast<HTMLGenericFormElement*>(n)->form();
+ return static_cast<HTMLFormControlElement*>(n)->form();
}
// try walking forward in the node tree to find a form element
@@ -1261,12 +1232,12 @@ void Frame::revealSelection(const RenderLayer::ScrollAlignment& alignment) const
{
IntRect rect;
- switch (selectionController()->state()) {
+ switch (selection()->state()) {
case Selection::NONE:
return;
case Selection::CARET:
- rect = selectionController()->caretRect();
+ rect = selection()->caretRect();
break;
case Selection::RANGE:
@@ -1274,7 +1245,7 @@ void Frame::revealSelection(const RenderLayer::ScrollAlignment& alignment) const
break;
}
- Position start = selectionController()->start();
+ Position start = selection()->start();
ASSERT(start.node());
if (start.node() && start.node()->renderer()) {
@@ -1282,87 +1253,27 @@ void Frame::revealSelection(const RenderLayer::ScrollAlignment& alignment) const
// the selection rect could intersect more than just that.
// See <rdar://problem/4799899>.
if (RenderLayer *layer = start.node()->renderer()->enclosingLayer())
- layer->scrollRectToVisible(rect, alignment, alignment);
+ layer->scrollRectToVisible(rect, false, alignment, alignment);
}
}
void Frame::revealCaret(const RenderLayer::ScrollAlignment& alignment) const
{
- if (selectionController()->isNone())
+ if (selection()->isNone())
return;
- Position extent = selectionController()->extent();
+ Position extent = selection()->extent();
if (extent.node() && extent.node()->renderer()) {
IntRect extentRect = VisiblePosition(extent).caretRect();
RenderLayer* layer = extent.node()->renderer()->enclosingLayer();
if (layer)
- layer->scrollRectToVisible(extentRect, alignment, alignment);
+ layer->scrollRectToVisible(extentRect, false, alignment, alignment);
}
}
-// FIXME: why is this here instead of on the FrameView?
-void Frame::paint(GraphicsContext* p, const IntRect& rect)
-{
-#ifndef NDEBUG
- bool fillWithRed;
- if (!document() || document()->printing())
- fillWithRed = false; // Printing, don't fill with red (can't remember why).
- else if (document()->ownerElement())
- fillWithRed = false; // Subframe, don't fill with red.
- else if (view() && view()->isTransparent())
- fillWithRed = false; // Transparent, don't fill with red.
- else if (d->m_paintRestriction == PaintRestrictionSelectionOnly || d->m_paintRestriction == PaintRestrictionSelectionOnlyBlackText)
- fillWithRed = false; // Selections are transparent, don't fill with red.
- else if (d->m_elementToDraw)
- fillWithRed = false; // Element images are transparent, don't fill with red.
- else
- fillWithRed = true;
-
- if (fillWithRed)
- p->fillRect(rect, Color(0xFF, 0, 0));
-#endif
-
- bool isTopLevelPainter = !s_currentPaintTimeStamp;
- if (isTopLevelPainter)
- s_currentPaintTimeStamp = currentTime();
-
- if (renderer()) {
- ASSERT(d->m_view && !d->m_view->needsLayout());
- ASSERT(!d->m_isPainting);
-
- d->m_isPainting = true;
-
- // d->m_elementToDraw is used to draw only one element
- RenderObject *eltRenderer = d->m_elementToDraw ? d->m_elementToDraw->renderer() : 0;
- if (d->m_paintRestriction == PaintRestrictionNone)
- renderer()->document()->invalidateRenderedRectsForMarkersInRect(rect);
- renderer()->layer()->paint(p, rect, d->m_paintRestriction, eltRenderer);
-
- d->m_isPainting = false;
-
- // Regions may have changed as a result of the visibility/z-index of element changing.
- if (renderer()->document()->dashboardRegionsDirty())
- renderer()->view()->frameView()->updateDashboardRegions();
- } else
- LOG_ERROR("called Frame::paint with nil renderer");
-
- if (isTopLevelPainter)
- s_currentPaintTimeStamp = 0;
-}
-
-void Frame::setPaintRestriction(PaintRestriction pr)
-{
- d->m_paintRestriction = pr;
-}
-
-bool Frame::isPainting() const
-{
- return d->m_isPainting;
-}
-
void Frame::adjustPageHeight(float *newBottom, float oldTop, float oldBottom, float bottomLimit)
{
- RenderView *root = static_cast<RenderView*>(document()->renderer());
+ RenderView* root = contentRenderer();
if (root) {
// Use a context with painting disabled.
GraphicsContext context((PlatformGraphicsContext*)0);
@@ -1436,7 +1347,7 @@ void Frame::forceLayoutWithPageWidthRange(float minPageWidth, float maxPageWidth
void Frame::sendResizeEvent()
{
if (Document* doc = document())
- doc->dispatchWindowEvent(EventNames::resizeEvent, false, false);
+ doc->dispatchWindowEvent(eventNames().resizeEvent, false, false);
}
void Frame::sendScrollEvent()
@@ -1448,25 +1359,25 @@ void Frame::sendScrollEvent()
Document* doc = document();
if (!doc)
return;
- doc->dispatchHTMLEvent(scrollEvent, true, false);
+ doc->dispatchEventForType(eventNames().scrollEvent, true, false);
}
-void Frame::clearTimers(FrameView *view)
+void Frame::clearTimers(FrameView *view, Document *document)
{
if (view) {
view->unscheduleRelayout();
if (view->frame()) {
- Document* document = view->frame()->document();
if (document && document->renderer() && document->renderer()->hasLayer())
document->renderer()->layer()->suspendMarquees();
- view->frame()->animationController()->suspendAnimations();
+ view->frame()->animation()->suspendAnimations(document);
+ view->frame()->eventHandler()->stopAutoscrollTimer();
}
}
}
void Frame::clearTimers()
{
- clearTimers(d->m_view.get());
+ clearTimers(d->m_view.get(), document());
}
RenderStyle *Frame::styleForSelectionStart(Node *&nodeToRemove) const
@@ -1475,10 +1386,10 @@ RenderStyle *Frame::styleForSelectionStart(Node *&nodeToRemove) const
if (!document())
return 0;
- if (selectionController()->isNone())
+ if (selection()->isNone())
return 0;
- Position pos = selectionController()->selection().visibleStart().deepEquivalent();
+ Position pos = selection()->selection().visibleStart().deepEquivalent();
if (!pos.isCandidate())
return 0;
Node *node = pos.node();
@@ -1511,14 +1422,14 @@ void Frame::setSelectionFromNone()
// Put a caret inside the body if the entire frame is editable (either the
// entire WebView is editable or designMode is on for this document).
Document *doc = document();
- if (!doc || !selectionController()->isNone() || !isContentEditable())
+ if (!doc || !selection()->isNone() || !isContentEditable())
return;
Node* node = doc->documentElement();
while (node && !node->hasTagName(bodyTag))
node = node->traverseNextNode();
if (node)
- selectionController()->setSelection(Selection(Position(node, 0), DOWNSTREAM));
+ selection()->setSelection(Selection(Position(node, 0), DOWNSTREAM));
}
bool Frame::inViewSourceMode() const
@@ -1543,51 +1454,75 @@ UChar Frame::backslashAsCurrencySymbol() const
return decoder->encoding().backslashAsCurrencySymbol();
}
-static bool isInShadowTree(Node* node)
-{
- for (Node* n = node; n; n = n->parentNode())
- if (n->isShadowNode())
- return true;
- return false;
-}
-
// Searches from the beginning of the document if nothing is selected.
bool Frame::findString(const String& target, bool forward, bool caseFlag, bool wrapFlag, bool startInSelection)
{
if (target.isEmpty() || !document())
return false;
+ if (excludeFromTextSearch())
+ return false;
+
// Start from an edge of the selection, if there's a selection that's not in shadow content. Which edge
// is used depends on whether we're searching forward or backward, and whether startInSelection is set.
RefPtr<Range> searchRange(rangeOfContents(document()));
- Selection selection(selectionController()->selection());
- Node* selectionBaseNode = selection.base().node();
-
- // FIXME 3099526: We don't search in the shadow trees (e.g. text fields and textareas), though we'd like to
- // someday. If we don't explicitly skip them here, we'll miss hits in the regular content.
- bool selectionIsInMainContent = selectionBaseNode && !isInShadowTree(selectionBaseNode);
+ Selection selection = this->selection()->selection();
+
+ if (forward)
+ setStart(searchRange.get(), startInSelection ? selection.visibleStart() : selection.visibleEnd());
+ else
+ setEnd(searchRange.get(), startInSelection ? selection.visibleEnd() : selection.visibleStart());
- if (selectionIsInMainContent) {
+ Node* shadowTreeRoot = selection.shadowTreeRootNode();
+ if (shadowTreeRoot) {
+ ExceptionCode ec = 0;
if (forward)
- setStart(searchRange.get(), startInSelection ? selection.visibleStart() : selection.visibleEnd());
+ searchRange->setEnd(shadowTreeRoot, shadowTreeRoot->childNodeCount(), ec);
else
- setEnd(searchRange.get(), startInSelection ? selection.visibleEnd() : selection.visibleStart());
+ searchRange->setStart(shadowTreeRoot, 0, ec);
}
+
RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, forward, caseFlag));
// If we started in the selection and the found range exactly matches the existing selection, find again.
// Build a selection with the found range to remove collapsed whitespace.
// Compare ranges instead of selection objects to ignore the way that the current selection was made.
- if (startInSelection && selectionIsInMainContent && *Selection(resultRange.get()).toRange() == *selection.toRange()) {
+ if (startInSelection && *Selection(resultRange.get()).toRange() == *selection.toRange()) {
searchRange = rangeOfContents(document());
if (forward)
setStart(searchRange.get(), selection.visibleEnd());
else
setEnd(searchRange.get(), selection.visibleStart());
+
+ if (shadowTreeRoot) {
+ ExceptionCode ec = 0;
+ if (forward)
+ searchRange->setEnd(shadowTreeRoot, shadowTreeRoot->childNodeCount(), ec);
+ else
+ searchRange->setStart(shadowTreeRoot, 0, ec);
+ }
+
resultRange = findPlainText(searchRange.get(), target, forward, caseFlag);
}
- int exception = 0;
+ ExceptionCode exception = 0;
+
+ // If nothing was found in the shadow tree, search in main content following the shadow tree.
+ if (resultRange->collapsed(exception) && shadowTreeRoot) {
+ searchRange = rangeOfContents(document());
+ if (forward)
+ searchRange->setStartAfter(shadowTreeRoot->shadowParentNode(), exception);
+ else
+ searchRange->setEndBefore(shadowTreeRoot->shadowParentNode(), exception);
+
+ resultRange = findPlainText(searchRange.get(), target, forward, caseFlag);
+ }
+ if (!editor()->insideVisibleArea(resultRange.get())) {
+ resultRange = editor()->nextVisibleRange(resultRange.get(), target, forward, caseFlag, wrapFlag);
+ if (!resultRange)
+ return false;
+ }
+
// If we didn't find anything and we're wrapping, search again in the entire document (this will
// redundantly re-search the area already searched in some cases).
if (resultRange->collapsed(exception) && wrapFlag) {
@@ -1601,7 +1536,7 @@ bool Frame::findString(const String& target, bool forward, bool caseFlag, bool w
if (resultRange->collapsed(exception))
return false;
- selectionController()->setSelection(Selection(resultRange.get(), DOWNSTREAM));
+ this->selection()->setSelection(Selection(resultRange.get(), DOWNSTREAM));
revealSelection();
return true;
}
@@ -1613,12 +1548,18 @@ unsigned Frame::markAllMatchesForText(const String& target, bool caseFlag, unsig
RefPtr<Range> searchRange(rangeOfContents(document()));
- int exception = 0;
+ ExceptionCode exception = 0;
unsigned matchCount = 0;
do {
RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, true, caseFlag));
- if (resultRange->collapsed(exception))
- break;
+ if (resultRange->collapsed(exception)) {
+ if (!resultRange->startContainer()->isInShadowTree())
+ break;
+
+ searchRange = rangeOfContents(document());
+ searchRange->setStartAfter(resultRange->startContainer()->shadowAncestorNode(), exception);
+ 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.
@@ -1626,26 +1567,33 @@ unsigned Frame::markAllMatchesForText(const String& target, bool caseFlag, unsig
if (newStart == startVisiblePosition(searchRange.get(), DOWNSTREAM))
break;
- ++matchCount;
-
- document()->addMarker(resultRange.get(), DocumentMarker::TextMatch);
+ // Only treat the result as a match if it is visible
+ if (editor()->insideVisibleArea(resultRange.get())) {
+ ++matchCount;
+ document()->addMarker(resultRange.get(), DocumentMarker::TextMatch);
+ }
// Stop looking if we hit the specified limit. A limit of 0 means no limit.
if (limit > 0 && matchCount >= limit)
break;
setStart(searchRange.get(), newStart);
+ Node* shadowTreeRoot = searchRange->shadowTreeRootNode();
+ if (searchRange->collapsed(exception) && shadowTreeRoot)
+ searchRange->setEnd(shadowTreeRoot, shadowTreeRoot->childNodeCount(), exception);
} while (true);
// Do a "fake" paint in order to execute the code that computes the rendered rect for
// each text match.
Document* doc = document();
- if (doc && d->m_view && renderer()) {
+ if (doc && d->m_view && contentRenderer()) {
doc->updateLayout(); // Ensure layout is up to date.
- IntRect visibleRect(enclosingIntRect(d->m_view->visibleContentRect()));
- GraphicsContext context((PlatformGraphicsContext*)0);
- context.setPaintingDisabled(true);
- paint(&context, visibleRect);
+ IntRect visibleRect = d->m_view->visibleContentRect();
+ if (!visibleRect.isEmpty()) {
+ GraphicsContext context((PlatformGraphicsContext*)0);
+ context.setPaintingDisabled(true);
+ d->m_view->paintContents(&context, visibleRect);
+ }
}
return matchCount;
@@ -1673,11 +1621,16 @@ FrameTree* Frame::tree() const
DOMWindow* Frame::domWindow() const
{
if (!d->m_domWindow)
- d->m_domWindow = new DOMWindow(const_cast<Frame*>(this));
+ d->m_domWindow = DOMWindow::create(const_cast<Frame*>(this));
return d->m_domWindow.get();
}
+void Frame::clearFormerDOMWindow(DOMWindow* window)
+{
+ d->m_liveFormerWindows.remove(window);
+}
+
Page* Frame::page() const
{
return d->m_page;
@@ -1693,22 +1646,27 @@ void Frame::pageDestroyed()
if (Frame* parent = tree()->parent())
parent->loader()->checkLoadComplete();
- if (d->m_page && d->m_page->focusController()->focusedFrame() == this)
- d->m_page->focusController()->setFocusedFrame(0);
+ // FIXME: It's unclear as to why this is called more than once, but it is,
+ // so page() could be NULL.
+ if (page() && page()->focusController()->focusedFrame() == this)
+ page()->focusController()->setFocusedFrame(0);
+
+ script()->clearWindowShell();
// This will stop any JS timers
- if (d->m_jscript && d->m_jscript->haveGlobalObject())
- if (KJS::Window* w = KJS::Window::retrieveWindow(this))
- w->disconnectFrame();
+ if (script()->haveWindowShell())
+ script()->windowShell()->disconnectFrame();
+
+ script()->clearScriptObjects();
- clearScriptObjects();
-
d->m_page = 0;
}
void Frame::disconnectOwnerElement()
{
if (d->m_ownerElement) {
+ if (Document* doc = document())
+ doc->clearAXObjectCache();
d->m_ownerElement->m_contentFrame = 0;
if (d->m_page)
d->m_page->decrementFrameCount();
@@ -1718,23 +1676,14 @@ void Frame::disconnectOwnerElement()
String Frame::documentTypeString() const
{
- if (Document *doc = document())
- if (DocumentType *doctype = doc->realDocType())
- return doctype->toString();
+ if (Document* doc = document()) {
+ if (DocumentType* doctype = doc->doctype())
+ return createMarkup(doctype);
+ }
return String();
}
-bool Frame::prohibitsScrolling() const
-{
- return d->m_prohibitsScrolling;
-}
-
-void Frame::setProhibitsScrolling(bool prohibit)
-{
- d->m_prohibitsScrolling = prohibit;
-}
-
void Frame::focusWindow()
{
if (!page())
@@ -1770,7 +1719,7 @@ bool Frame::shouldClose()
if (!body)
return true;
- RefPtr<BeforeUnloadEvent> beforeUnloadEvent = new BeforeUnloadEvent;
+ RefPtr<BeforeUnloadEvent> beforeUnloadEvent = BeforeUnloadEvent::create();
beforeUnloadEvent->setTarget(doc);
doc->handleWindowEvent(beforeUnloadEvent.get(), false);
@@ -1803,8 +1752,8 @@ void Frame::respondToChangedSelection(const Selection& oldSelection, bool closeT
if (isContinuousSpellCheckingEnabled) {
Selection newAdjacentWords;
Selection newSelectedSentence;
- if (selectionController()->selection().isContentEditable()) {
- VisiblePosition newStart(selectionController()->selection().visibleStart());
+ if (selection()->selection().isContentEditable()) {
+ VisiblePosition newStart(selection()->selection().visibleStart());
newAdjacentWords = Selection(startOfWord(newStart, LeftWordIfOnBoundary), endOfWord(newStart, RightWordIfOnBoundary));
if (isContinuousGrammarCheckingEnabled)
newSelectedSentence = Selection(startOfSentence(newStart), endOfSentence(newStart));
@@ -1867,7 +1816,7 @@ Document* Frame::documentAtPoint(const IntPoint& point)
IntPoint pt = view()->windowToContents(point);
HitTestResult result = HitTestResult(pt);
- if (renderer())
+ if (contentRenderer())
result = eventHandler()->hitTestResultAtPoint(pt, false);
return result.innerNode() ? result.innerNode()->document() : 0;
}
@@ -1876,41 +1825,66 @@ FramePrivate::FramePrivate(Page* page, Frame* parent, Frame* thisFrame, HTMLFram
FrameLoaderClient* frameLoaderClient)
: m_page(page)
, m_treeNode(thisFrame, parent)
+ , m_loader(thisFrame, frameLoaderClient)
, m_ownerElement(ownerElement)
- , m_jscript(0)
- , m_zoomFactor(parent ? parent->d->m_zoomFactor : 100)
+ , m_script(thisFrame)
+ , m_zoomFactor(parent ? parent->d->m_zoomFactor : 1.0f)
, m_selectionGranularity(CharacterGranularity)
, m_selectionController(thisFrame)
, m_caretBlinkTimer(thisFrame, &Frame::caretBlinkTimerFired)
, m_editor(thisFrame)
, m_eventHandler(thisFrame)
, m_animationController(thisFrame)
+ , m_lifeSupportTimer(thisFrame, &Frame::lifeSupportTimerFired)
, m_caretVisible(false)
, m_caretPaint(true)
- , m_isPainting(false)
- , m_lifeSupportTimer(thisFrame, &Frame::lifeSupportTimerFired)
- , m_loader(new FrameLoader(thisFrame, frameLoaderClient))
- , m_paintRestriction(PaintRestrictionNone)
, m_highlightTextMatches(false)
, m_inViewSourceMode(false)
- , frameCount(0)
- , m_prohibitsScrolling(false)
, m_needsReapplyStyles(false)
- , m_windowScriptNPObject(0)
+ , m_isDisconnected(false)
+ , m_excludeFromTextSearch(false)
#if FRAME_LOADS_USER_STYLESHEET
, m_userStyleSheetLoader(0)
#endif
-#if PLATFORM(MAC)
- , m_windowScriptObject(nil)
- , m_bridge(nil)
-#endif
{
}
FramePrivate::~FramePrivate()
{
- delete m_jscript;
- delete m_loader;
}
+#ifdef ANDROID_INSTRUMENT
+void Frame::resetTimeCounter() {
+ JSC::JSGlobalObject::resetTimeCounter();
+ resetLayoutTimeCounter();
+ resetPaintTimeCounter();
+ resetCSSTimeCounter();
+ resetParsingTimeCounter();
+ resetCalculateStyleTimeCounter();
+ resetFramebridgeTimeCounter();
+ resetSharedTimerTimeCounter();
+ resetResourceLoadTimeCounter();
+ resetWebViewCoreTimeCounter();
+ LOGD("*-* Start browser instrument\n");
+}
+
+void Frame::reportTimeCounter(String url, int total, int totalThreadTime)
+{
+ LOGD("*-* Total load time: %d ms, thread time: %d ms for %s\n",
+ total, totalThreadTime, url.utf8().data());
+ JSC::JSGlobalObject::reportTimeCounter();
+ reportLayoutTimeCounter();
+ reportPaintTimeCounter();
+ reportCSSTimeCounter();
+ reportParsingTimeCounter();
+ reportCalculateStyleTimeCounter();
+ reportFramebridgeTimeCounter();
+ reportSharedTimerTimeCounter();
+ reportResourceLoadTimeCounter();
+ reportWebViewCoreTimeCounter();
+ LOGD("Current cache has %d bytes live and %d bytes dead",
+ cache()->getLiveSize(), cache()->getDeadSize());
+}
+#endif
+
} // namespace WebCore
diff --git a/WebCore/page/Frame.h b/WebCore/page/Frame.h
index ea9eadc..0dd3a71 100644
--- a/WebCore/page/Frame.h
+++ b/WebCore/page/Frame.h
@@ -1,4 +1,3 @@
-// -*- c-basic-offset: 4 -*-
/*
* Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
* 1999-2001 Lars Knoll <knoll@kde.org>
@@ -6,8 +5,9 @@
* 2000-2001 Simon Hausmann <hausmann@kde.org>
* 2000-2001 Dirk Mueller <mueller@kde.org>
* 2000 Stefan Schimanski <1Stein@gmx.de>
- * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
- * Copyright (C) 2007 Trolltech ASA
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -28,101 +28,54 @@
#ifndef Frame_h
#define Frame_h
-#include "Color.h"
-#include "EditAction.h"
#include "DragImage.h"
+#include "EditAction.h"
#include "RenderLayer.h"
#include "TextGranularity.h"
-#include "VisiblePosition.h"
-#include <wtf/unicode/Unicode.h>
-#include <wtf/Forward.h>
-#include <wtf/Vector.h>
-#include "RenderObject.h"
-
-struct NPObject;
-
-namespace KJS {
-
- class Interpreter;
- class JSGlobalObject;
-
- namespace Bindings {
- class Instance;
- class RootObject;
- }
-
-}
#if PLATFORM(MAC)
-#ifdef __OBJC__
-@class NSArray;
-@class NSDictionary;
-@class NSMenu;
-@class NSMutableDictionary;
-@class NSString;
-@class WebCoreFrameBridge;
-@class WebScriptObject;
-#else
+#ifndef __OBJC__
class NSArray;
class NSDictionary;
-class NSMenu;
class NSMutableDictionary;
class NSString;
-class WebCoreFrameBridge;
-class WebScriptObject;
typedef int NSWritingDirection;
#endif
#endif
+#if PLATFORM(ANDROID)
+#include "CacheBuilder.h"
+#endif
+
namespace WebCore {
-class AnimationController;
-class CSSComputedStyleDeclaration;
-class CSSMutableStyleDeclaration;
-class CSSStyleDeclaration;
-class DOMWindow;
-class Document;
class Editor;
-class Element;
class EventHandler;
-class FloatRect;
class FrameLoader;
class FrameLoaderClient;
-class HTMLFrameOwnerElement;
-class HTMLTableCellElement;
class FramePrivate;
class FrameTree;
-class FrameView;
-class GraphicsContext;
-class HTMLFormElement;
-class IntRect;
-class KJSProxy;
-class KURL;
-class Node;
-class Page;
-class Range;
+class HTMLFrameOwnerElement;
+class HTMLTableCellElement;
+class ScriptController;
+class RegularExpression;
class RenderPart;
class Selection;
class SelectionController;
-class Settings;
class Widget;
-struct FrameLoadRequest;
-
template <typename T> class Timer;
class Frame : public RefCounted<Frame> {
public:
- Frame(Page*, HTMLFrameOwnerElement*, FrameLoaderClient*);
- virtual void setView(FrameView*);
- virtual ~Frame();
-
- void init();
+ static PassRefPtr<Frame> create(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient* client)
+ {
+ return adoptRef(new Frame(page, ownerElement, client));
+ }
+ void setView(FrameView*);
+ ~Frame();
-#if PLATFORM(MAC)
- void setBridge(WebCoreFrameBridge*);
- WebCoreFrameBridge* bridge() const;
-#endif
+ void init();
Page* page() const;
HTMLFrameOwnerElement* ownerElement() const;
@@ -134,21 +87,24 @@ public:
FrameView* view() const;
DOMWindow* domWindow() const;
+ void clearFormerDOMWindow(DOMWindow*);
Editor* editor() const;
EventHandler* eventHandler() const;
FrameLoader* loader() const;
- SelectionController* selectionController() const;
+ SelectionController* selection() const;
FrameTree* tree() const;
- AnimationController* animationController() const;
+ AnimationController* animation() const;
+ ScriptController* script();
- // FIXME: Rename to contentRenderer and change type to RenderView.
- RenderObject* renderer() const; // root renderer for the document contained in this frame
- RenderPart* ownerRenderer(); // renderer for the element that contains this frame
+ RenderView* contentRenderer() const; // root renderer for the document contained in this frame
+ RenderPart* ownerRenderer() const; // renderer for the element that contains this frame
+
+ bool isDisconnected() const;
+ void setIsDisconnected(bool);
+ bool excludeFromTextSearch() const;
+ void setExcludeFromTextSearch(bool);
friend class FramePrivate;
-#ifdef ANDROID_BRIDGE
- friend class FrameAndroid;
-#endif
#ifdef ANDROID_INSTRUMENT
void resetTimeCounter();
@@ -166,13 +122,13 @@ private:
void resetLayoutTimeCounter();
void reportLayoutTimeCounter();
-
+
void resetPaintTimeCounter();
void reportPaintTimeCounter();
-
+
void resetSharedTimerTimeCounter();
void reportSharedTimerTimeCounter();
-
+
void resetResourceLoadTimeCounter();
void reportResourceLoadTimeCounter();
@@ -184,6 +140,8 @@ private:
#endif
private:
+ Frame(Page*, HTMLFrameOwnerElement*, FrameLoaderClient*);
+
FramePrivate* d;
// === undecided, would like to consider moving to another class
@@ -208,25 +166,10 @@ public:
static void cancelAllKeepAlive();
#endif
- KJS::Bindings::Instance* createScriptInstanceForWidget(Widget*);
- KJS::Bindings::RootObject* bindingRootObject();
-
- PassRefPtr<KJS::Bindings::RootObject> createRootObject(void* nativeHandle, KJS::JSGlobalObject*);
-
-#if PLATFORM(MAC)
- WebScriptObject* windowScriptObject();
-#endif
-
-#if USE(NPOBJECT)
- NPObject* windowScriptNPObject();
-#endif
-
void setDocument(PassRefPtr<Document>);
- KJSProxy* scriptProxy();
-
void clearTimers();
- static void clearTimers(FrameView*);
+ static void clearTimers(FrameView*, Document*);
// Convenience, to avoid repeating the code to dig down to get this.
UChar backslashAsCurrencySymbol() const;
@@ -237,19 +180,13 @@ public:
String documentTypeString() const;
- void dashboardRegionsChanged();
-
- void clearScriptProxy();
+ // This method -- and the corresponding list of former DOM windows --
+ // should move onto ScriptController
void clearDOMWindow();
- void clearScriptObjects();
- void cleanupScriptObjectsForPlugin(void*);
-
private:
- void clearPlatformScriptObjects();
-
void lifeSupportTimerFired(Timer<Frame>*);
-
+
// === to be moved into Document
public:
@@ -263,26 +200,19 @@ public:
// === to be moved into FrameView
-public:
- void paint(GraphicsContext*, const IntRect&);
- void setPaintRestriction(PaintRestriction);
- bool isPainting() const;
-
- static double currentPaintTimeStamp() { return s_currentPaintTimeStamp; } // returns 0 if not painting
-
+public:
void forceLayout(bool allowSubtree = false);
void forceLayoutWithPageWidthRange(float minPageWidth, float maxPageWidth, bool adjustViewSize);
void adjustPageHeight(float* newBottom, float oldTop, float oldBottom, float bottomLimit);
- void setZoomFactor(int percent);
- int zoomFactor() const; // FIXME: This is a multiplier for text size only; needs a better name.
-
- bool prohibitsScrolling() const;
- void setProhibitsScrolling(const bool);
-
-private:
- static double s_currentPaintTimeStamp; // used for detecting decoded resource thrash in the cache
+ void setZoomFactor(float scale, bool isTextOnly);
+ float zoomFactor() const;
+ bool isZoomFactorTextOnly() const;
+ bool shouldApplyTextZoom() const;
+ bool shouldApplyPageZoom() const;
+ float pageZoomFactor() const { return shouldApplyPageZoom() ? zoomFactor() : 1.0f; }
+ float textZoomFactor() const { return shouldApplyTextZoom() ? zoomFactor() : 1.0f; }
// === to be moved into Chrome
@@ -324,7 +254,7 @@ public:
bool markedTextMatchesAreHighlighted() const;
void setMarkedTextMatchesAreHighlighted(bool flag);
- CSSComputedStyleDeclaration* selectionComputedStyle(Node*& nodeToRemove) const;
+ PassRefPtr<CSSComputedStyleDeclaration> selectionComputedStyle(Node*& nodeToRemove) const;
void textFieldDidBeginEditing(Element*);
void textFieldDidEndEditing(Element*);
@@ -395,31 +325,35 @@ public:
NSString* searchForLabelsBeforeElement(NSArray* labels, Element*);
NSString* matchLabelsAgainstElement(NSArray* labels, Element*);
+#if ENABLE(DASHBOARD_SUPPORT)
NSMutableDictionary* dashboardRegionsDictionary();
-
- void willPopupMenu(NSMenu*);
+#endif
NSImage* selectionImage(bool forceBlackText = false) const;
NSImage* snapshotDragImage(Node*, NSRect* imageRect, NSRect* elementRect) const;
+ NSImage* nodeImage(Node*) const;
private:
NSImage* imageFromRect(NSRect) const;
-// === to be moved into Chrome
-
-public:
- FloatRect customHighlightLineRect(const AtomicString& type, const FloatRect& lineRect, Node*);
- void paintCustomHighlight(const AtomicString& type, const FloatRect& boxRect, const FloatRect& lineRect, bool text, bool line, Node*);
-
// === to be moved into Editor
public:
NSDictionary* fontAttributesForSelectionStart() const;
NSWritingDirection baseWritingDirectionForSelectionStart() const;
- void issuePasteCommand();
#endif
+#if PLATFORM(ANDROID)
+
+public:
+ CacheBuilder& getCacheBuilder() { return m_cacheBuilder; }
+
+private:
+ CacheBuilder m_cacheBuilder;
+ friend class CacheBuilder;
+
+#endif
};
} // namespace WebCore
diff --git a/WebCore/page/FrameLoadRequest.h b/WebCore/page/FrameLoadRequest.h
index c916a05..bfb750c 100644
--- a/WebCore/page/FrameLoadRequest.h
+++ b/WebCore/page/FrameLoadRequest.h
@@ -1,4 +1,3 @@
-// -*- mode: c++; c-basic-offset: 4 -*-
/*
* Copyright (C) 2003, 2006 Apple Computer, Inc. All rights reserved.
*
@@ -35,12 +34,18 @@ namespace WebCore {
public:
FrameLoadRequest()
: m_lockHistory(false)
+#ifdef ANDROID_USER_GESTURE
+ , m_wasUserGesture(true)
+#endif
{
}
FrameLoadRequest(const ResourceRequest& resourceRequest)
: m_resourceRequest(resourceRequest)
, m_lockHistory(false)
+#ifdef ANDROID_USER_GESTURE
+ , m_wasUserGesture(true)
+#endif
{
}
@@ -48,6 +53,9 @@ namespace WebCore {
: m_resourceRequest(resourceRequest)
, m_frameName(frameName)
, m_lockHistory(false)
+#ifdef ANDROID_USER_GESTURE
+ , m_wasUserGesture(true)
+#endif
{
}
@@ -62,10 +70,18 @@ namespace WebCore {
bool lockHistory() const { return m_lockHistory; }
void setLockHistory(bool lock) { m_lockHistory = lock; }
+#ifdef ANDROID_USER_GESTURE
+ void setWasUserGesture(bool wasUserGesture) { m_wasUserGesture = wasUserGesture; }
+ bool wasUserGesture() const { return m_wasUserGesture; }
+#endif
+
private:
ResourceRequest m_resourceRequest;
String m_frameName;
bool m_lockHistory;
+#ifdef ANDROID_USER_GESTURE
+ bool m_wasUserGesture;
+#endif
};
}
diff --git a/WebCore/page/FramePrivate.h b/WebCore/page/FramePrivate.h
index c780db2..2f7c59a 100644
--- a/WebCore/page/FramePrivate.h
+++ b/WebCore/page/FramePrivate.h
@@ -4,8 +4,8 @@
* 2000-2001 Simon Hausmann <hausmann@kde.org>
* 2000-2001 Dirk Mueller <mueller@kde.org>
* 2000 Stefan Schimanski <1Stein@gmx.de>
- * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
- * Copyright (C) 2007 Trolltech ASA
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -29,29 +29,12 @@
#include "AnimationController.h"
#include "Editor.h"
#include "EventHandler.h"
+#include "FrameLoader.h"
#include "FrameTree.h"
#include "Range.h"
#include "SelectionController.h"
#include "StringHash.h"
-
-namespace KJS {
- class Interpreter;
-
- namespace Bindings {
- class Instance;
- class RootObject;
- }
-}
-
-#if PLATFORM(MAC)
-#ifdef __OBJC__
-@class WebCoreFrameBridge;
-@class WebScriptObject;
-#else
-class WebCoreFrameBridge;
-class WebScriptObject;
-#endif
-#endif
+#include "ScriptController.h"
#if PLATFORM(WIN)
#include "FrameWin.h"
@@ -62,8 +45,6 @@ namespace WebCore {
#if FRAME_LOADS_USER_STYLESHEET
class UserStyleSheetLoader;
#endif
-
- typedef HashMap<void*, RefPtr<KJS::Bindings::RootObject> > RootObjectMap;
class FramePrivate {
public:
@@ -72,18 +53,20 @@ namespace WebCore {
Page* m_page;
FrameTree m_treeNode;
+ FrameLoader m_loader;
RefPtr<DOMWindow> m_domWindow;
+ HashSet<DOMWindow*> m_liveFormerWindows;
HTMLFrameOwnerElement* m_ownerElement;
RefPtr<FrameView> m_view;
RefPtr<Document> m_doc;
- KJSProxy* m_jscript;
+ ScriptController m_script;
String m_kjsStatusBarText;
String m_kjsDefaultStatusBarText;
- int m_zoomFactor;
+ float m_zoomFactor;
TextGranularity m_selectionGranularity;
@@ -94,40 +77,22 @@ namespace WebCore {
EventHandler m_eventHandler;
AnimationController m_animationController;
- bool m_caretVisible : 1;
- bool m_caretPaint : 1;
- bool m_isPainting : 1;
-
RefPtr<CSSMutableStyleDeclaration> m_typingStyle;
Timer<Frame> m_lifeSupportTimer;
- FrameLoader* m_loader;
-
- RefPtr<Node> m_elementToDraw;
- PaintRestriction m_paintRestriction;
+ bool m_caretVisible;
+ bool m_caretPaint;
bool m_highlightTextMatches;
-
bool m_inViewSourceMode;
-
- unsigned frameCount;
-
- bool m_prohibitsScrolling;
-
bool m_needsReapplyStyles;
+ bool m_isDisconnected;
+ bool m_excludeFromTextSearch;
- // The root object used for objects bound outside the context of a plugin.
- RefPtr<KJS::Bindings::RootObject> m_bindingRootObject;
- RootObjectMap m_rootObjects;
- NPObject* m_windowScriptNPObject;
#if FRAME_LOADS_USER_STYLESHEET
UserStyleSheetLoader* m_userStyleSheetLoader;
#endif
-#if PLATFORM(MAC)
- RetainPtr<WebScriptObject> m_windowScriptObject;
- WebCoreFrameBridge* m_bridge;
-#endif
};
}
diff --git a/WebCore/page/FrameTree.cpp b/WebCore/page/FrameTree.cpp
index 92e198d..c9b4172 100644
--- a/WebCore/page/FrameTree.cpp
+++ b/WebCore/page/FrameTree.cpp
@@ -1,4 +1,3 @@
-// -*- c-basic-offset: 4 -*-
/*
* Copyright (C) 2006 Apple Computer, Inc.
*
@@ -23,6 +22,7 @@
#include "Frame.h"
#include "Page.h"
+#include "PageGroup.h"
#include <stdarg.h>
#include <wtf/Platform.h>
#include <wtf/StringExtras.h>
@@ -48,6 +48,18 @@ void FrameTree::setName(const AtomicString& name)
m_name = parent()->tree()->uniqueChildName(name);
}
+void FrameTree::clearName()
+{
+ m_name = AtomicString();
+}
+
+Frame* FrameTree::parent(bool checkForDisconnectedFrame) const
+{
+ if (checkForDisconnectedFrame && m_thisFrame->isDisconnected())
+ return 0;
+ return m_parent;
+}
+
void FrameTree::appendChild(PassRefPtr<Frame> child)
{
ASSERT(child->page() == m_thisFrame->page());
@@ -118,7 +130,7 @@ AtomicString FrameTree::uniqueChildName(const AtomicString& requestedName) const
String name;
name += framePathPrefix;
if (frame)
- name += frame->tree()->name().domString().substring(framePathPrefixLength,
+ name += frame->tree()->name().string().substring(framePathPrefixLength,
frame->tree()->name().length() - framePathPrefixLength - framePathSuffixLength);
for (int i = chain.size() - 1; i >= 0; --i) {
frame = chain[i];
@@ -162,7 +174,7 @@ Frame* FrameTree::find(const AtomicString& name) const
return m_thisFrame;
if (name == "_top")
- return m_thisFrame->page()->mainFrame();
+ return top();
if (name == "_parent")
return parent() ? parent() : m_thisFrame;
@@ -178,20 +190,26 @@ Frame* FrameTree::find(const AtomicString& name) const
// Search the entire tree for this page next.
Page* page = m_thisFrame->page();
+
+ // The frame could have been detached from the page, so check it.
+ if (!page)
+ return 0;
+
for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext())
if (frame->tree()->name() == name)
return frame;
- // Search the entire tree for all other pages in this namespace.
- const HashSet<Page*>* pages = page->frameNamespace();
- if (pages) {
- HashSet<Page*>::const_iterator end = pages->end();
- for (HashSet<Page*>::const_iterator it = pages->begin(); it != end; ++it) {
- Page* otherPage = *it;
- if (otherPage != page)
- for (Frame* frame = otherPage->mainFrame(); frame; frame = frame->tree()->traverseNext())
- if (frame->tree()->name() == name)
- return frame;
+ // Search the entire tree of each of the other pages in this namespace.
+ // FIXME: Is random order OK?
+ const HashSet<Page*>& pages = page->group().pages();
+ HashSet<Page*>::const_iterator end = pages.end();
+ for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) {
+ Page* otherPage = *it;
+ if (otherPage != page) {
+ for (Frame* frame = otherPage->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
+ if (frame->tree()->name() == name)
+ return frame;
+ }
}
}
@@ -282,14 +300,14 @@ Frame* FrameTree::deepLastChild() const
return result;
}
-Frame* FrameTree::top() const
+Frame* FrameTree::top(bool checkForDisconnectedFrame) const
{
- if (Page* page = m_thisFrame->page())
- return page->mainFrame();
-
Frame* frame = m_thisFrame;
- while (Frame* parent = frame->tree()->parent())
+ for (Frame* parent = m_thisFrame; parent; parent = parent->tree()->parent()) {
frame = parent;
+ if (checkForDisconnectedFrame && frame->isDisconnected())
+ return frame;
+ }
return frame;
}
diff --git a/WebCore/page/FrameTree.h b/WebCore/page/FrameTree.h
index 3f3e20a..0952dcd 100644
--- a/WebCore/page/FrameTree.h
+++ b/WebCore/page/FrameTree.h
@@ -1,4 +1,3 @@
-// -*- mode: c++; c-basic-offset: 4 -*-
/*
* Copyright (C) 2006 Apple Computer, Inc.
*
@@ -22,11 +21,10 @@
#define FrameTree_h
#include "AtomicString.h"
+#include "Frame.h"
namespace WebCore {
- class Frame;
-
class FrameTree : Noncopyable {
public:
FrameTree(Frame* thisFrame, Frame* parentFrame)
@@ -41,7 +39,8 @@ namespace WebCore {
const AtomicString& name() const { return m_name; }
void setName(const AtomicString&);
- Frame* parent() const { return m_parent; }
+ void clearName();
+ Frame* parent(bool checkForDisconnectedFrame = false) const;
void setParent(Frame* parent) { m_parent = parent; }
Frame* nextSibling() const { return m_nextSibling.get(); }
@@ -64,7 +63,7 @@ namespace WebCore {
AtomicString uniqueChildName(const AtomicString& requestedName) const;
- Frame* top() const;
+ Frame* top(bool checkForDisconnectedFrame = false) const;
private:
Frame* deepLastChild() const;
diff --git a/WebCore/page/FrameView.cpp b/WebCore/page/FrameView.cpp
index 21adc10..e503b0d 100644
--- a/WebCore/page/FrameView.cpp
+++ b/WebCore/page/FrameView.cpp
@@ -3,7 +3,7 @@
* 1999 Lars Knoll <knoll@kde.org>
* 1999 Antti Koivisto <koivisto@kde.org>
* 2000 Dirk Mueller <mueller@kde.org>
- * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
* (C) 2006 Graham Dennis (graham.dennis@gmail.com)
* (C) 2006 Alexey Proskuryakov (ap@nypop.com)
*
@@ -22,29 +22,37 @@
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
+#ifdef ANDROID_INSTRUMENT
+#define LOG_TAG "WebCore"
+#endif
#include "config.h"
#include "FrameView.h"
#include "AXObjectCache.h"
+#include "CSSStyleSelector.h"
+#include "ChromeClient.h"
#include "EventHandler.h"
#include "FloatRect.h"
+#include "FocusController.h"
#include "Frame.h"
#include "FrameLoader.h"
#include "FrameLoaderClient.h"
#include "GraphicsContext.h"
#include "HTMLDocument.h"
+#include "HTMLFrameElement.h"
#include "HTMLFrameSetElement.h"
#include "HTMLNames.h"
#include "OverflowEvent.h"
+#include "Page.h"
#include "RenderPart.h"
#include "RenderPartObject.h"
#include "RenderTheme.h"
#include "RenderView.h"
+#include "Settings.h"
+#include "SystemTime.h"
#ifdef ANDROID_INSTRUMENT
-#undef LOG
-#include <utils/Log.h>
#include "SystemTime.h"
#include "FrameTree.h"
#endif
@@ -53,93 +61,111 @@ namespace WebCore {
using namespace HTMLNames;
+double FrameView::sCurrentPaintTimeStamp = 0.0;
+
struct ScheduledEvent {
RefPtr<Event> m_event;
RefPtr<EventTargetNode> m_eventTarget;
- bool m_tempEvent;
};
class FrameViewPrivate {
public:
FrameViewPrivate(FrameView* view)
: m_slowRepaintObjectCount(0)
- , layoutTimer(view, &FrameView::layoutTimerFired)
- , layoutRoot(0)
- , postLayoutTasksTimer(view, &FrameView::postLayoutTimerFired)
+ , m_layoutTimer(view, &FrameView::layoutTimerFired)
+ , m_layoutRoot(0)
+ , m_postLayoutTasksTimer(view, &FrameView::postLayoutTimerFired)
, m_mediaType("screen")
, m_enqueueEvents(0)
, m_overflowStatusDirty(true)
, m_viewportRenderer(0)
, m_wasScrolledByUser(false)
, m_inProgrammaticScroll(false)
+ , m_shouldUpdateWhileOffscreen(true)
{
- isTransparent = false;
- baseBackgroundColor = Color::white;
- vmode = hmode = ScrollbarAuto;
- needToInitScrollbars = true;
+ m_isTransparent = false;
+ m_baseBackgroundColor = Color::white;
+ m_vmode = m_hmode = ScrollbarAuto;
+ m_needToInitScrollbars = true;
reset();
}
void reset()
{
- useSlowRepaints = false;
- borderX = 30;
- borderY = 30;
- layoutTimer.stop();
- layoutRoot = 0;
- delayedLayout = false;
- doFullRepaint = true;
- layoutSchedulingEnabled = true;
- midLayout = false;
- layoutCount = 0;
- nestedLayoutCount = 0;
- postLayoutTasksTimer.stop();
- firstLayout = true;
- repaintRects.clear();
+ m_useSlowRepaints = false;
+ m_borderX = 30;
+ m_borderY = 30;
+ m_layoutTimer.stop();
+ m_layoutRoot = 0;
+ m_delayedLayout = false;
+ m_doFullRepaint = true;
+ m_layoutSchedulingEnabled = true;
+ m_midLayout = false;
+ m_layoutCount = 0;
+ m_nestedLayoutCount = 0;
+ m_postLayoutTasksTimer.stop();
+ m_firstLayout = true;
+ m_firstLayoutCallbackPending = false;
m_wasScrolledByUser = false;
- lastLayoutSize = IntSize();
+ m_lastLayoutSize = IntSize();
+ m_lastZoomFactor = 1.0f;
+ m_deferringRepaints = 0;
+ m_repaintCount = 0;
+ m_repaintRect = IntRect();
+ m_repaintRects.clear();
+ m_paintRestriction = PaintRestrictionNone;
+ m_isPainting = false;
}
- bool doFullRepaint;
+ bool m_doFullRepaint;
- ScrollbarMode vmode;
- ScrollbarMode hmode;
- bool useSlowRepaints;
+ ScrollbarMode m_vmode;
+ ScrollbarMode m_hmode;
+ bool m_useSlowRepaints;
unsigned m_slowRepaintObjectCount;
- int borderX, borderY;
+ int m_borderX, m_borderY;
- Timer<FrameView> layoutTimer;
- bool delayedLayout;
- RenderObject* layoutRoot;
-
- bool layoutSchedulingEnabled;
- bool midLayout;
- int layoutCount;
- unsigned nestedLayoutCount;
- Timer<FrameView> postLayoutTasksTimer;
-
- bool firstLayout;
- bool needToInitScrollbars;
- bool isTransparent;
- Color baseBackgroundColor;
- IntSize lastLayoutSize;
-
- // Used by objects during layout to communicate repaints that need to take place only
- // after all layout has been completed.
- Vector<RenderObject::RepaintInfo> repaintRects;
+ Timer<FrameView> m_layoutTimer;
+ bool m_delayedLayout;
+ RenderObject* m_layoutRoot;
+ bool m_layoutSchedulingEnabled;
+ bool m_midLayout;
+ int m_layoutCount;
+ unsigned m_nestedLayoutCount;
+ Timer<FrameView> m_postLayoutTasksTimer;
+ bool m_firstLayoutCallbackPending;
+
+ bool m_firstLayout;
+ bool m_needToInitScrollbars;
+ bool m_isTransparent;
+ Color m_baseBackgroundColor;
+ IntSize m_lastLayoutSize;
+ float m_lastZoomFactor;
+
String m_mediaType;
unsigned m_enqueueEvents;
Vector<ScheduledEvent*> m_scheduledEvents;
bool m_overflowStatusDirty;
- bool horizontalOverflow;
+ bool m_horizontalOverflow;
bool m_verticalOverflow;
RenderObject* m_viewportRenderer;
bool m_wasScrolledByUser;
bool m_inProgrammaticScroll;
+
+ unsigned m_deferringRepaints;
+ unsigned m_repaintCount;
+ IntRect m_repaintRect;
+ Vector<IntRect> m_repaintRects;
+
+ bool m_shouldUpdateWhileOffscreen;
+
+ RefPtr<Node> m_nodeToDraw;
+ PaintRestriction m_paintRestriction;
+ bool m_isPainting;
};
FrameView::FrameView(Frame* frame)
@@ -151,34 +177,34 @@ FrameView::FrameView(Frame* frame)
show();
}
-#if !PLATFORM(MAC)
FrameView::FrameView(Frame* frame, const IntSize& initialSize)
: m_refCount(1)
, m_frame(frame)
, d(new FrameViewPrivate(this))
{
init();
- Widget::setFrameGeometry(IntRect(x(), y(), initialSize.width(), initialSize.height()));
+ Widget::setFrameRect(IntRect(x(), y(), initialSize.width(), initialSize.height()));
show();
}
-#endif
FrameView::~FrameView()
{
- if (d->postLayoutTasksTimer.isActive()) {
- d->postLayoutTasksTimer.stop();
+ if (d->m_postLayoutTasksTimer.isActive()) {
+ d->m_postLayoutTasksTimer.stop();
d->m_scheduledEvents.clear();
d->m_enqueueEvents = 0;
}
resetScrollbars();
-
+ setHasHorizontalScrollbar(false); // Remove native scrollbars now before we lose the connection to the HostWindow.
+ setHasVerticalScrollbar(false);
+
ASSERT(m_refCount == 0);
ASSERT(d->m_scheduledEvents.isEmpty());
ASSERT(!d->m_enqueueEvents);
if (m_frame) {
- ASSERT(m_frame->view() != this || !m_frame->document() || !m_frame->document()->renderer());
+ ASSERT(m_frame->view() != this || !m_frame->document() || !m_frame->contentRenderer());
RenderPart* renderer = m_frame->ownerRenderer();
if (renderer && renderer->widget() == this)
renderer->setWidget(0);
@@ -201,22 +227,35 @@ void FrameView::clearFrame()
void FrameView::resetScrollbars()
{
// Reset the document's scrollbars back to our defaults before we yield the floor.
- d->firstLayout = true;
- suppressScrollbars(true);
- ScrollView::setVScrollbarMode(d->vmode);
- ScrollView::setHScrollbarMode(d->hmode);
- suppressScrollbars(false);
+ d->m_firstLayout = true;
+ setScrollbarsSuppressed(true);
+ setScrollbarModes(d->m_hmode, d->m_vmode);
+ setScrollbarsSuppressed(false);
}
void FrameView::init()
{
m_margins = IntSize(-1, -1); // undefined
m_size = IntSize();
+
+ // Propagate the marginwidth/height and scrolling modes to the view.
+ Element* ownerElement = m_frame && m_frame->document() ? m_frame->document()->ownerElement() : 0;
+ if (ownerElement && (ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(iframeTag))) {
+ HTMLFrameElement* frameElt = static_cast<HTMLFrameElement*>(ownerElement);
+ if (frameElt->scrollingMode() == ScrollbarAlwaysOff)
+ setCanHaveScrollbars(false);
+ int marginWidth = frameElt->getMarginWidth();
+ int marginHeight = frameElt->getMarginHeight();
+ if (marginWidth != -1)
+ setMarginWidth(marginWidth);
+ if (marginHeight != -1)
+ setMarginHeight(marginHeight);
+ }
}
void FrameView::clear()
{
- setStaticBackground(false);
+ setCanBlitOnScroll(true);
d->reset();
@@ -224,20 +263,43 @@ void FrameView::clear()
if (RenderPart* renderer = m_frame->ownerRenderer())
renderer->viewCleared();
- suppressScrollbars(true);
+ setScrollbarsSuppressed(true);
}
bool FrameView::didFirstLayout() const
{
- return !d->firstLayout;
+ return !d->m_firstLayout;
}
void FrameView::initScrollbars()
{
- if (!d->needToInitScrollbars)
+ if (!d->m_needToInitScrollbars)
return;
- d->needToInitScrollbars = false;
- setScrollbarsMode(hScrollbarMode());
+ d->m_needToInitScrollbars = false;
+ d->m_hmode = horizontalScrollbarMode();
+ d->m_vmode = verticalScrollbarMode();
+ setScrollbarModes(d->m_hmode, d->m_vmode);
+}
+
+void FrameView::invalidateRect(const IntRect& rect)
+{
+ if (!parent()) {
+ if (hostWindow())
+ hostWindow()->repaint(rect, true);
+ return;
+ }
+
+ if (!m_frame)
+ return;
+
+ RenderPart* renderer = m_frame->ownerRenderer();
+ if (!renderer)
+ return;
+
+ IntRect repaintRect = rect;
+ repaintRect.move(renderer->borderLeft() + renderer->paddingLeft(),
+ renderer->borderTop() + renderer->paddingTop());
+ renderer->repaintRectangle(repaintRect);
}
void FrameView::setMarginWidth(int w)
@@ -252,13 +314,19 @@ void FrameView::setMarginHeight(int h)
m_margins.setHeight(h);
}
+void FrameView::setCanHaveScrollbars(bool canScroll)
+{
+ ScrollView::setCanHaveScrollbars(canScroll);
+ scrollbarModes(d->m_hmode, d->m_vmode);
+}
+
void FrameView::adjustViewSize()
{
ASSERT(m_frame->view() == this);
- RenderView* root = static_cast<RenderView*>(m_frame->renderer());
+ RenderView* root = m_frame->contentRenderer();
if (!root)
return;
- resizeContents(root->overflowWidth(), root->overflowHeight());
+ setContentsSize(IntSize(root->overflowWidth(), root->overflowHeight()));
}
void FrameView::applyOverflowToViewport(RenderObject* o, ScrollbarMode& hMode, ScrollbarMode& vMode)
@@ -302,22 +370,17 @@ void FrameView::applyOverflowToViewport(RenderObject* o, ScrollbarMode& hMode, S
int FrameView::layoutCount() const
{
- return d->layoutCount;
+ return d->m_layoutCount;
}
bool FrameView::needsFullRepaint() const
{
- return d->doFullRepaint;
-}
-
-void FrameView::addRepaintInfo(RenderObject* o, const IntRect& r)
-{
- d->repaintRects.append(RenderObject::RepaintInfo(o, r));
+ return d->m_doFullRepaint;
}
RenderObject* FrameView::layoutRoot(bool onlyDuringLayout) const
{
- return onlyDuringLayout && layoutPending() ? 0 : d->layoutRoot;
+ return onlyDuringLayout && layoutPending() ? 0 : d->m_layoutRoot;
}
#ifdef ANDROID_INSTRUMENT
@@ -332,18 +395,18 @@ void Frame::resetLayoutTimeCounter()
void Frame::reportLayoutTimeCounter()
{
- LOG(LOG_DEBUG, "WebCore", "*-* Total layout time: %d ms called %d times\n",
+ LOGD("*-* Total layout time: %d ms called %d times\n",
sTotalTimeUsed, sCounter);
}
#endif
void FrameView::layout(bool allowSubtree)
{
- if (d->midLayout)
+ if (d->m_midLayout)
return;
- d->layoutTimer.stop();
- d->delayedLayout = false;
+ d->m_layoutTimer.stop();
+ d->m_delayedLayout = false;
// Protect the view from being deleted during layout (in recalcStyle)
RefPtr<FrameView> protector(this);
@@ -356,13 +419,13 @@ void FrameView::layout(bool allowSubtree)
}
// we shouldn't enter layout() while painting
- ASSERT(!m_frame->isPainting());
- if (m_frame->isPainting())
+ ASSERT(!isPainting());
+ if (isPainting())
return;
- if (!allowSubtree && d->layoutRoot) {
- d->layoutRoot->markContainingBlocksForLayout(false);
- d->layoutRoot = 0;
+ if (!allowSubtree && d->m_layoutRoot) {
+ d->m_layoutRoot->markContainingBlocksForLayout(false);
+ d->m_layoutRoot = 0;
}
ASSERT(m_frame->view() == this);
@@ -379,15 +442,20 @@ void FrameView::layout(bool allowSubtree)
return;
}
- d->layoutSchedulingEnabled = false;
+ d->m_layoutSchedulingEnabled = false;
- if (!d->nestedLayoutCount && d->postLayoutTasksTimer.isActive()) {
+ if (!d->m_nestedLayoutCount && d->m_postLayoutTasksTimer.isActive()) {
// This is a new top-level layout. If there are any remaining tasks from the previous
// layout, finish them now.
- d->postLayoutTasksTimer.stop();
+ d->m_postLayoutTasksTimer.stop();
performPostLayoutTasks();
}
+ // Viewport-dependent media queries may cause us to need completely different style information.
+ // Check that here.
+ if (document->styleSelector()->affectedByViewportChange())
+ document->updateStyleSelector();
+
// Always ensure our style info is up-to-date. This can happen in situations where
// the layout beats any sort of style recalc update that needs to occur.
if (m_frame->needsReapplyStyles())
@@ -395,17 +463,17 @@ void FrameView::layout(bool allowSubtree)
else if (document->hasChangedChild())
document->recalcStyle();
- bool subtree = d->layoutRoot;
+ bool subtree = d->m_layoutRoot;
// If there is only one ref to this view left, then its going to be destroyed as soon as we exit,
// so there's no point to continuing to layout
if (protector->hasOneRef())
return;
- RenderObject* root = subtree ? d->layoutRoot : document->renderer();
+ RenderObject* root = subtree ? d->m_layoutRoot : document->renderer();
if (!root) {
// FIXME: Do we need to set m_size here?
- d->layoutSchedulingEnabled = true;
+ d->m_layoutSchedulingEnabled = true;
return;
}
@@ -415,71 +483,60 @@ void FrameView::layout(bool allowSubtree)
startTime = get_thread_msec();
#endif
- d->nestedLayoutCount++;
+ d->m_nestedLayoutCount++;
- ScrollbarMode hMode = d->hmode;
- ScrollbarMode vMode = d->vmode;
+ ScrollbarMode hMode = d->m_hmode;
+ ScrollbarMode vMode = d->m_vmode;
if (!subtree) {
RenderObject* rootRenderer = document->documentElement() ? document->documentElement()->renderer() : 0;
- if (document->isHTMLDocument()) {
- Node* body = static_cast<HTMLDocument*>(document)->body();
- if (body && body->renderer()) {
- if (body->hasTagName(framesetTag)) {
+ Node* body = document->body();
+ if (body && body->renderer()) {
+ if (body->hasTagName(framesetTag)) {
+ body->renderer()->setChildNeedsLayout(true);
+ vMode = ScrollbarAlwaysOff;
+ hMode = ScrollbarAlwaysOff;
+ } else if (body->hasTagName(bodyTag)) {
+ if (!d->m_firstLayout && m_size.height() != visibleHeight()
+ && static_cast<RenderBox*>(body->renderer())->stretchesToViewHeight())
body->renderer()->setChildNeedsLayout(true);
- vMode = ScrollbarAlwaysOff;
- hMode = ScrollbarAlwaysOff;
- } else if (body->hasTagName(bodyTag)) {
- if (!d->firstLayout && m_size.height() != visibleHeight()
- && static_cast<RenderBox*>(body->renderer())->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
- ? body->renderer() : rootRenderer;
- applyOverflowToViewport(o, hMode, vMode); // Only applies to HTML UAs, not to XML/XHTML UAs
- }
+ // 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)
- applyOverflowToViewport(rootRenderer, hMode, vMode); // XML/XHTML UAs use the root element.
+ applyOverflowToViewport(rootRenderer, hMode, vMode);
#ifdef INSTRUMENT_LAYOUT_SCHEDULING
- if (d->firstLayout && !document->ownerElement())
+ if (d->m_firstLayout && !document->ownerElement())
printf("Elapsed time before first layout: %d\n", document->elapsedTime());
#endif
}
- d->doFullRepaint = !subtree && (d->firstLayout || static_cast<RenderView*>(root)->printing());
- ASSERT(d->nestedLayoutCount > 1 || d->repaintRects.isEmpty());
+ d->m_doFullRepaint = !subtree && (d->m_firstLayout || static_cast<RenderView*>(root)->printing());
- bool didFirstLayout = false;
if (!subtree) {
// Now set our scrollbar state for the layout.
- ScrollbarMode currentHMode = hScrollbarMode();
- ScrollbarMode currentVMode = vScrollbarMode();
-
- if (d->firstLayout || (hMode != currentHMode || vMode != currentVMode)) {
- suppressScrollbars(true);
- if (d->firstLayout) {
- d->firstLayout = false;
- didFirstLayout = true;
- d->lastLayoutSize = IntSize(width(), height());
-
+ ScrollbarMode currentHMode = horizontalScrollbarMode();
+ ScrollbarMode currentVMode = verticalScrollbarMode();
+
+ if (d->m_firstLayout || (hMode != currentHMode || vMode != currentVMode)) {
+ setScrollbarsSuppressed(true);
+ if (d->m_firstLayout) {
+ d->m_firstLayout = false;
+ d->m_firstLayoutCallbackPending = true;
+ d->m_lastLayoutSize = IntSize(width(), height());
+ d->m_lastZoomFactor = root->style()->zoom();
+
// Set the initial vMode to AlwaysOn if we're auto.
if (vMode == ScrollbarAuto)
- ScrollView::setVScrollbarMode(ScrollbarAlwaysOn); // This causes a vertical scrollbar to appear.
+ setVerticalScrollbarMode(ScrollbarAlwaysOn); // This causes a vertical scrollbar to appear.
// Set the initial hMode to AlwaysOff if we're auto.
if (hMode == ScrollbarAuto)
- ScrollView::setHScrollbarMode(ScrollbarAlwaysOff); // This causes a horizontal scrollbar to disappear.
- }
-
- if (hMode == vMode)
- ScrollView::setScrollbarsMode(hMode);
- else {
- ScrollView::setHScrollbarMode(hMode);
- ScrollView::setVScrollbarMode(vMode);
+ setHorizontalScrollbarMode(ScrollbarAlwaysOff); // This causes a horizontal scrollbar to disappear.
}
-
- suppressScrollbars(false, true);
+ setScrollbarModes(hMode, vMode);
+ setScrollbarsSuppressed(false, true);
}
IntSize oldSize = m_size;
@@ -487,7 +544,7 @@ void FrameView::layout(bool allowSubtree)
m_size = IntSize(visibleWidth(), visibleHeight());
if (oldSize != m_size)
- d->doFullRepaint = true;
+ d->m_doFullRepaint = true;
}
RenderLayer* layer = root->enclosingLayer();
@@ -496,41 +553,39 @@ void FrameView::layout(bool allowSubtree)
if (subtree)
root->view()->pushLayoutState(root);
- d->midLayout = true;
+
+ d->m_midLayout = true;
+ beginDeferredRepaints();
root->layout();
- d->midLayout = false;
+ endDeferredRepaints();
+ d->m_midLayout = false;
+
if (subtree)
root->view()->popLayoutState();
- d->layoutRoot = 0;
+ d->m_layoutRoot = 0;
m_frame->invalidateSelection();
- d->layoutSchedulingEnabled = true;
+ d->m_layoutSchedulingEnabled = true;
if (!subtree && !static_cast<RenderView*>(root)->printing())
adjustViewSize();
// Now update the positions of all layers.
- layer->updateLayerPositions(d->doFullRepaint);
-
- // FIXME: Could optimize this and have objects removed from this list
- // if they ever do full repaints.
- Vector<RenderObject::RepaintInfo>::iterator end = d->repaintRects.end();
- for (Vector<RenderObject::RepaintInfo>::iterator it = d->repaintRects.begin(); it != end; ++it)
- it->m_object->repaintRectangle(it->m_repaintRect);
- d->repaintRects.clear();
+ beginDeferredRepaints();
+ layer->updateLayerPositions(d->m_doFullRepaint);
+ endDeferredRepaints();
- d->layoutCount++;
+ d->m_layoutCount++;
#if PLATFORM(MAC)
if (AXObjectCache::accessibilityEnabled())
root->document()->axObjectCache()->postNotificationToElement(root, "AXLayoutComplete");
#endif
+#if ENABLE(DASHBOARD_SUPPORT)
updateDashboardRegions();
+#endif
- if (didFirstLayout)
- m_frame->loader()->didFirstLayout();
-
#ifdef ANDROID_INSTRUMENT
if (!m_frame->tree()->parent()) {
uint32_t time = get_thread_msec() - startTime;
@@ -542,13 +597,13 @@ void FrameView::layout(bool allowSubtree)
#endif
ASSERT(!root->needsLayout());
- setStaticBackground(useSlowRepaints());
+ setCanBlitOnScroll(!useSlowRepaints());
if (document->hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
updateOverflowStatus(visibleWidth() < contentsWidth(),
visibleHeight() < contentsHeight());
- if (!d->postLayoutTasksTimer.isActive()) {
+ if (!d->m_postLayoutTasksTimer.isActive()) {
// Calls resumeScheduledEvents()
performPostLayoutTasks();
@@ -556,7 +611,7 @@ void FrameView::layout(bool allowSubtree)
// Post-layout widget updates or an event handler made us need layout again.
// Lay out again, but this time defer widget updates and event dispatch until after
// we return.
- d->postLayoutTasksTimer.startOneShot(0);
+ d->m_postLayoutTasksTimer.startOneShot(0);
pauseScheduledEvents();
layout();
}
@@ -565,7 +620,7 @@ void FrameView::layout(bool allowSubtree)
ASSERT(d->m_enqueueEvents);
}
- d->nestedLayoutCount--;
+ d->m_nestedLayoutCount--;
}
void FrameView::addWidgetToUpdate(RenderPartObject* object)
@@ -584,76 +639,6 @@ void FrameView::removeWidgetToUpdate(RenderPartObject* object)
m_widgetUpdateSet->remove(object);
}
-//
-// Event Handling
-//
-/////////////////
-
-bool FrameView::scrollTo(const IntRect& bounds)
-{
- int x, y, xe, ye;
- x = bounds.x();
- y = bounds.y();
- xe = bounds.right() - 1;
- ye = bounds.bottom() - 1;
-
- int deltax;
- int deltay;
-
- int curHeight = visibleHeight();
- int curWidth = visibleWidth();
-
- if (ye - y>curHeight-d->borderY)
- ye = y + curHeight - d->borderY;
-
- if (xe - x>curWidth-d->borderX)
- xe = x + curWidth - d->borderX;
-
- // is xpos of target left of the view's border?
- if (x < contentsX() + d->borderX)
- deltax = x - contentsX() - d->borderX;
- // is xpos of target right of the view's right border?
- else if (xe + d->borderX > contentsX() + curWidth)
- deltax = xe + d->borderX - (contentsX() + curWidth);
- else
- deltax = 0;
-
- // is ypos of target above upper border?
- if (y < contentsY() + d->borderY)
- deltay = y - contentsY() - d->borderY;
- // is ypos of target below lower border?
- else if (ye + d->borderY > contentsY() + curHeight)
- deltay = ye + d->borderY - (contentsY() + curHeight);
- else
- deltay = 0;
-
- int maxx = curWidth - d->borderX;
- int maxy = curHeight - d->borderY;
-
- int scrollX = deltax > 0 ? (deltax > maxx ? maxx : deltax) : deltax == 0 ? 0 : (deltax > -maxx ? deltax : -maxx);
- int scrollY = deltay > 0 ? (deltay > maxy ? maxy : deltay) : deltay == 0 ? 0 : (deltay > -maxy ? deltay : -maxy);
-
- if (contentsX() + scrollX < 0)
- scrollX = -contentsX();
- else if (contentsWidth() - visibleWidth() - contentsX() < scrollX)
- scrollX = contentsWidth() - visibleWidth() - contentsX();
-
- if (contentsY() + scrollY < 0)
- scrollY = -contentsY();
- else if (contentsHeight() - visibleHeight() - contentsY() < scrollY)
- scrollY = contentsHeight() - visibleHeight() - contentsY();
-
- scrollBy(scrollX, scrollY);
-
- // generate abs(scroll.)
- if (scrollX < 0)
- scrollX = -scrollX;
- if (scrollY < 0)
- scrollY = -scrollY;
-
- return scrollX != maxx && scrollY != maxy;
-}
-
void FrameView::setMediaType(const String& mediaType)
{
d->m_mediaType = mediaType;
@@ -670,19 +655,19 @@ String FrameView::mediaType() const
bool FrameView::useSlowRepaints() const
{
- return d->useSlowRepaints || d->m_slowRepaintObjectCount > 0;
+ return d->m_useSlowRepaints || d->m_slowRepaintObjectCount > 0;
}
void FrameView::setUseSlowRepaints()
{
- d->useSlowRepaints = true;
- setStaticBackground(true);
+ d->m_useSlowRepaints = true;
+ setCanBlitOnScroll(false);
}
void FrameView::addSlowRepaintObject()
{
if (!d->m_slowRepaintObjectCount)
- setStaticBackground(true);
+ setCanBlitOnScroll(false);
d->m_slowRepaintObjectCount++;
}
@@ -691,57 +676,104 @@ void FrameView::removeSlowRepaintObject()
ASSERT(d->m_slowRepaintObjectCount > 0);
d->m_slowRepaintObjectCount--;
if (!d->m_slowRepaintObjectCount)
- setStaticBackground(d->useSlowRepaints);
+ setCanBlitOnScroll(!d->m_useSlowRepaints);
}
-void FrameView::setScrollbarsMode(ScrollbarMode mode)
+void FrameView::restoreScrollbar()
{
- d->vmode = mode;
- d->hmode = mode;
-
- ScrollView::setScrollbarsMode(mode);
+ setScrollbarsSuppressed(false);
}
-void FrameView::setVScrollbarMode(ScrollbarMode mode)
+void FrameView::scrollRectIntoViewRecursively(const IntRect& r)
{
- d->vmode = mode;
- ScrollView::setVScrollbarMode(mode);
+ bool wasInProgrammaticScroll = d->m_inProgrammaticScroll;
+ d->m_inProgrammaticScroll = true;
+ ScrollView::scrollRectIntoViewRecursively(r);
+ d->m_inProgrammaticScroll = wasInProgrammaticScroll;
}
-void FrameView::setHScrollbarMode(ScrollbarMode mode)
+void FrameView::setScrollPosition(const IntPoint& scrollPoint)
{
- d->hmode = mode;
- ScrollView::setHScrollbarMode(mode);
+ bool wasInProgrammaticScroll = d->m_inProgrammaticScroll;
+ d->m_inProgrammaticScroll = true;
+ ScrollView::setScrollPosition(scrollPoint);
+ d->m_inProgrammaticScroll = wasInProgrammaticScroll;
}
-void FrameView::restoreScrollbar()
+HostWindow* FrameView::hostWindow() const
{
- suppressScrollbars(false);
+ Page* page = frame() ? frame()->page() : 0;
+ if (!page)
+ return 0;
+ return page->chrome();
}
-void FrameView::scrollRectIntoViewRecursively(const IntRect& r)
+const unsigned cRepaintRectUnionThreshold = 25;
+
+void FrameView::repaintContentRectangle(const IntRect& r, bool immediate)
{
- if (frame()->prohibitsScrolling())
+ ASSERT(!m_frame->document()->ownerElement());
+
+ if (d->m_deferringRepaints && !immediate) {
+ IntRect visibleContent = visibleContentRect();
+ visibleContent.intersect(r);
+ if (!visibleContent.isEmpty()) {
+ d->m_repaintCount++;
+ d->m_repaintRect.unite(r);
+ if (d->m_repaintCount == cRepaintRectUnionThreshold)
+ d->m_repaintRects.clear();
+ else if (d->m_repaintCount < cRepaintRectUnionThreshold)
+ d->m_repaintRects.append(r);
+ }
+#ifdef ANDROID_CAPTURE_OFFSCREEN_PAINTS
+ else
+ ScrollView::platformOffscreenContentRectangle(r);
+#endif
return;
- bool wasInProgrammaticScroll = d->m_inProgrammaticScroll;
- d->m_inProgrammaticScroll = true;
- ScrollView::scrollRectIntoViewRecursively(r);
- d->m_inProgrammaticScroll = wasInProgrammaticScroll;
+ }
+
+ if (!immediate && isOffscreen() && !shouldUpdateWhileOffscreen())
+ return;
+
+ ScrollView::repaintContentRectangle(r, immediate);
}
-void FrameView::setContentsPos(int x, int y)
+void FrameView::beginDeferredRepaints()
{
- if (frame()->prohibitsScrolling())
- return;
- bool wasInProgrammaticScroll = d->m_inProgrammaticScroll;
- d->m_inProgrammaticScroll = true;
- ScrollView::setContentsPos(x, y);
- d->m_inProgrammaticScroll = wasInProgrammaticScroll;
+ Page* page = m_frame->page();
+ if (page->mainFrame() != m_frame)
+ return page->mainFrame()->view()->beginDeferredRepaints();
+
+ d->m_deferringRepaints++;
+#ifdef ANDROID_FIX // This allows sub frames to accumulate deferred repaints
+ if (d->m_deferringRepaints == 1) {
+#endif
+ d->m_repaintCount = 0;
+ d->m_repaintRect = IntRect();
+ d->m_repaintRects.clear();
+#ifdef ANDROID_FIX
+ }
+#endif
}
-void FrameView::repaintRectangle(const IntRect& r, bool immediate)
+
+void FrameView::endDeferredRepaints()
{
- updateContents(r, immediate);
+ Page* page = m_frame->page();
+ if (page->mainFrame() != m_frame)
+ return page->mainFrame()->view()->endDeferredRepaints();
+
+ ASSERT(d->m_deferringRepaints > 0);
+ if (--d->m_deferringRepaints == 0) {
+ if (d->m_repaintCount >= cRepaintRectUnionThreshold)
+ repaintContentRectangle(d->m_repaintRect, false);
+ else {
+ unsigned size = d->m_repaintRects.size();
+ for (unsigned i = 0; i < size; i++)
+ repaintContentRectangle(d->m_repaintRects[i], false);
+ d->m_repaintRects.clear();
+ }
+ }
}
void FrameView::layoutTimerFired(Timer<FrameView>*)
@@ -758,39 +790,39 @@ void FrameView::scheduleRelayout()
ASSERT(!m_frame->document() || !m_frame->document()->inPageCache());
ASSERT(m_frame->view() == this);
- if (d->layoutRoot) {
- d->layoutRoot->markContainingBlocksForLayout(false);
- d->layoutRoot = 0;
+ if (d->m_layoutRoot) {
+ d->m_layoutRoot->markContainingBlocksForLayout(false);
+ d->m_layoutRoot = 0;
}
- if (!d->layoutSchedulingEnabled)
+ if (!d->m_layoutSchedulingEnabled)
return;
if (!m_frame->document() || !m_frame->document()->shouldScheduleLayout())
return;
+#if defined(FLATTEN_IFRAME) || defined(FLATTEN_FRAMESET)
+ if (m_frame->ownerRenderer())
+ m_frame->ownerRenderer()->setNeedsLayoutAndPrefWidthsRecalc();
+#endif
+
#ifdef ANDROID_MOBILE
int delay = m_frame->document()->minimumLayoutDelay() + m_frame->document()->extraLayoutDelay();
#else
int delay = m_frame->document()->minimumLayoutDelay();
#endif
- if (d->layoutTimer.isActive() && d->delayedLayout && !delay)
+ if (d->m_layoutTimer.isActive() && d->m_delayedLayout && !delay)
unscheduleRelayout();
- if (d->layoutTimer.isActive())
+ if (d->m_layoutTimer.isActive())
return;
- d->delayedLayout = delay != 0;
+ d->m_delayedLayout = delay != 0;
#ifdef INSTRUMENT_LAYOUT_SCHEDULING
if (!m_frame->document()->ownerElement())
printf("Scheduling layout for %d\n", delay);
#endif
-#if defined(FLATTEN_IFRAME) || defined(FLATTEN_FRAMESET)
- if (m_frame->ownerRenderer())
- m_frame->ownerRenderer()->setNeedsLayoutAndPrefWidthsRecalc();
-#endif
-
- d->layoutTimer.startOneShot(delay * 0.001);
+ d->m_layoutTimer.startOneShot(delay * 0.001);
}
static bool isObjectAncestorContainerOf(RenderObject* ancestor, RenderObject* descendant)
@@ -802,33 +834,32 @@ static bool isObjectAncestorContainerOf(RenderObject* ancestor, RenderObject* de
return false;
}
-void FrameView::scheduleRelayoutOfSubtree(RenderObject* o)
+void FrameView::scheduleRelayoutOfSubtree(RenderObject* relayoutRoot)
{
ASSERT(m_frame->view() == this);
- if (!d->layoutSchedulingEnabled || (m_frame->document()
- && m_frame->document()->renderer()
- && m_frame->document()->renderer()->needsLayout())) {
- if (o)
- o->markContainingBlocksForLayout(false);
+ if (!d->m_layoutSchedulingEnabled || (m_frame->contentRenderer()
+ && m_frame->contentRenderer()->needsLayout())) {
+ if (relayoutRoot)
+ relayoutRoot->markContainingBlocksForLayout(false);
return;
}
if (layoutPending()) {
- if (d->layoutRoot != o) {
- if (isObjectAncestorContainerOf(d->layoutRoot, o)) {
+ if (d->m_layoutRoot != relayoutRoot) {
+ if (isObjectAncestorContainerOf(d->m_layoutRoot, relayoutRoot)) {
// Keep the current root
- o->markContainingBlocksForLayout(false, d->layoutRoot);
- } else if (d->layoutRoot && isObjectAncestorContainerOf(o, d->layoutRoot)) {
- // Re-root at o
- d->layoutRoot->markContainingBlocksForLayout(false, o);
- d->layoutRoot = o;
+ relayoutRoot->markContainingBlocksForLayout(false, d->m_layoutRoot);
+ } else if (d->m_layoutRoot && isObjectAncestorContainerOf(relayoutRoot, d->m_layoutRoot)) {
+ // Re-root at relayoutRoot
+ d->m_layoutRoot->markContainingBlocksForLayout(false, relayoutRoot);
+ d->m_layoutRoot = relayoutRoot;
} else {
// Just do a full relayout
- if (d->layoutRoot)
- d->layoutRoot->markContainingBlocksForLayout(false);
- d->layoutRoot = 0;
- o->markContainingBlocksForLayout(false);
+ if (d->m_layoutRoot)
+ d->m_layoutRoot->markContainingBlocksForLayout(false);
+ d->m_layoutRoot = 0;
+ relayoutRoot->markContainingBlocksForLayout(false);
}
}
} else {
@@ -837,15 +868,15 @@ void FrameView::scheduleRelayoutOfSubtree(RenderObject* o)
#else
int delay = m_frame->document()->minimumLayoutDelay();
#endif
- d->layoutRoot = o;
- d->delayedLayout = delay != 0;
- d->layoutTimer.startOneShot(delay * 0.001);
+ d->m_layoutRoot = relayoutRoot;
+ d->m_delayedLayout = delay != 0;
+ d->m_layoutTimer.startOneShot(delay * 0.001);
}
}
bool FrameView::layoutPending() const
{
- return d->layoutTimer.isActive();
+ return d->m_layoutTimer.isActive();
}
bool FrameView::needsLayout() const
@@ -854,21 +885,22 @@ bool FrameView::needsLayout() const
// then we are not allowed to schedule layouts yet, so we won't be pending layout.
if (!m_frame)
return false;
- RenderView* root = static_cast<RenderView*>(m_frame->renderer());
+ RenderView* root = m_frame->contentRenderer();
Document * doc = m_frame->document();
// doc->hasChangedChild() condition can occur when using WebKit ObjC interface
- return layoutPending() || (root && root->needsLayout()) || d->layoutRoot || (doc && doc->hasChangedChild()) || m_frame->needsReapplyStyles();
+ return layoutPending() || (root && root->needsLayout()) || d->m_layoutRoot || (doc && doc->hasChangedChild()) || m_frame->needsReapplyStyles();
}
void FrameView::setNeedsLayout()
{
- if (m_frame->renderer())
- m_frame->renderer()->setNeedsLayout(true);
+ RenderView* root = m_frame->contentRenderer();
+ if (root)
+ root->setNeedsLayout(true);
}
void FrameView::unscheduleRelayout()
{
- if (!d->layoutTimer.isActive())
+ if (!d->m_layoutTimer.isActive())
return;
#ifdef INSTRUMENT_LAYOUT_SCHEDULING
@@ -876,44 +908,53 @@ void FrameView::unscheduleRelayout()
printf("Layout timer unscheduled at %d\n", m_frame->document()->elapsedTime());
#endif
- d->layoutTimer.stop();
- d->delayedLayout = false;
+ d->m_layoutTimer.stop();
+ d->m_delayedLayout = false;
}
bool FrameView::isTransparent() const
{
- return d->isTransparent;
+ return d->m_isTransparent;
}
void FrameView::setTransparent(bool isTransparent)
{
- d->isTransparent = isTransparent;
+ d->m_isTransparent = isTransparent;
}
Color FrameView::baseBackgroundColor() const
{
- return d->baseBackgroundColor;
+ return d->m_baseBackgroundColor;
}
void FrameView::setBaseBackgroundColor(Color bc)
{
if (!bc.isValid())
bc = Color::white;
- d->baseBackgroundColor = bc;
+ d->m_baseBackgroundColor = bc;
+}
+
+bool FrameView::shouldUpdateWhileOffscreen() const
+{
+ return d->m_shouldUpdateWhileOffscreen;
}
-void FrameView::scheduleEvent(PassRefPtr<Event> event, PassRefPtr<EventTargetNode> eventTarget, bool tempEvent)
+void FrameView::setShouldUpdateWhileOffscreen(bool shouldUpdateWhileOffscreen)
+{
+ d->m_shouldUpdateWhileOffscreen = shouldUpdateWhileOffscreen;
+}
+
+void FrameView::scheduleEvent(PassRefPtr<Event> event, PassRefPtr<EventTargetNode> eventTarget)
{
if (!d->m_enqueueEvents) {
ExceptionCode ec = 0;
- eventTarget->dispatchEvent(event, ec, tempEvent);
+ eventTarget->dispatchEvent(event, ec);
return;
}
ScheduledEvent* scheduledEvent = new ScheduledEvent;
scheduledEvent->m_event = event;
scheduledEvent->m_eventTarget = eventTarget;
- scheduledEvent->m_tempEvent = tempEvent;
d->m_scheduledEvents.append(scheduledEvent);
}
@@ -933,10 +974,15 @@ void FrameView::resumeScheduledEvents()
void FrameView::performPostLayoutTasks()
{
- RenderView* root = static_cast<RenderView*>(m_frame->document()->renderer());
+ if (d->m_firstLayoutCallbackPending) {
+ d->m_firstLayoutCallbackPending = false;
+ m_frame->loader()->didFirstLayout();
+ }
+
+ RenderView* root = m_frame->contentRenderer();
root->updateWidgetPositions();
- if (m_widgetUpdateSet && d->nestedLayoutCount <= 1) {
+ if (m_widgetUpdateSet && d->m_nestedLayoutCount <= 1) {
Vector<RenderPartObject*> objectVector;
copyToVector(*m_widgetUpdateSet, objectVector);
size_t size = objectVector.size();
@@ -956,8 +1002,10 @@ void FrameView::performPostLayoutTasks()
if (!root->printing()) {
IntSize currentSize = IntSize(width(), height());
- bool resized = !d->firstLayout && currentSize != d->lastLayoutSize;
- d->lastLayoutSize = currentSize;
+ float currentZoomFactor = root->style()->zoom();
+ bool resized = !d->m_firstLayout && (currentSize != d->m_lastLayoutSize || currentZoomFactor != d->m_lastZoomFactor);
+ d->m_lastLayoutSize = currentSize;
+ d->m_lastZoomFactor = currentZoomFactor;
if (resized)
m_frame->sendResizeEvent();
}
@@ -974,22 +1022,22 @@ void FrameView::updateOverflowStatus(bool horizontalOverflow, bool verticalOverf
return;
if (d->m_overflowStatusDirty) {
- d->horizontalOverflow = horizontalOverflow;
+ d->m_horizontalOverflow = horizontalOverflow;
d->m_verticalOverflow = verticalOverflow;
d->m_overflowStatusDirty = false;
return;
}
- bool horizontalOverflowChanged = (d->horizontalOverflow != horizontalOverflow);
+ bool horizontalOverflowChanged = (d->m_horizontalOverflow != horizontalOverflow);
bool verticalOverflowChanged = (d->m_verticalOverflow != verticalOverflow);
if (horizontalOverflowChanged || verticalOverflowChanged) {
- d->horizontalOverflow = horizontalOverflow;
+ d->m_horizontalOverflow = horizontalOverflow;
d->m_verticalOverflow = verticalOverflow;
- scheduleEvent(new OverflowEvent(horizontalOverflowChanged, horizontalOverflow,
+ scheduleEvent(OverflowEvent::create(horizontalOverflowChanged, horizontalOverflow,
verticalOverflowChanged, verticalOverflow),
- EventTargetNodeCast(d->m_viewportRenderer->element()), true);
+ EventTargetNodeCast(d->m_viewportRenderer->element()));
}
}
@@ -1010,30 +1058,18 @@ void FrameView::dispatchScheduledEvents()
// Only dispatch events to nodes that are in the document
if (scheduledEvent->m_eventTarget->inDocument())
- scheduledEvent->m_eventTarget->dispatchEvent(scheduledEvent->m_event,
- ec, scheduledEvent->m_tempEvent);
+ scheduledEvent->m_eventTarget->dispatchEvent(scheduledEvent->m_event, ec);
delete scheduledEvent;
}
}
-IntRect FrameView::windowClipRect() const
-{
- return windowClipRect(true);
-}
-
IntRect FrameView::windowClipRect(bool clipToContents) const
{
ASSERT(m_frame->view() == this);
// Set our clip rect to be our contents.
- IntRect clipRect;
- if (clipToContents)
- clipRect = enclosingIntRect(visibleContentRect());
- else
- clipRect = IntRect(contentsX(), contentsY(), width(), height());
- clipRect = contentsToWindow(clipRect);
-
+ IntRect clipRect = contentsToWindow(visibleContentRect(!clipToContents));
if (!m_frame || !m_frame->document() || !m_frame->document()->ownerElement())
return clipRect;
@@ -1064,16 +1100,54 @@ IntRect FrameView::windowClipRectForLayer(const RenderLayer* layer, bool clipToL
return intersection(clipRect, windowClipRect());
}
+bool FrameView::isActive() const
+{
+ Page* page = frame()->page();
+ return page && page->focusController()->isActive();
+}
+
+void FrameView::valueChanged(Scrollbar* bar)
+{
+ // Figure out if we really moved.
+ IntSize offset = scrollOffset();
+ ScrollView::valueChanged(bar);
+ if (offset != scrollOffset())
+ frame()->sendScrollEvent();
+}
+
+void FrameView::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
+{
+ // Add in our offset within the FrameView.
+ IntRect dirtyRect = rect;
+ dirtyRect.move(scrollbar->x(), scrollbar->y());
+ invalidateRect(dirtyRect);
+}
+
+IntRect FrameView::windowResizerRect() const
+{
+ Page* page = frame() ? frame()->page() : 0;
+ if (!page)
+ return IntRect();
+ return page->chrome()->windowResizerRect();
+}
+
+#if ENABLE(DASHBOARD_SUPPORT)
void FrameView::updateDashboardRegions()
{
- Document* doc = m_frame->document();
- if (doc->hasDashboardRegions()) {
- Vector<DashboardRegionValue> newRegions;
- doc->renderer()->collectDashboardRegions(newRegions);
- doc->setDashboardRegions(newRegions);
- m_frame.get()->dashboardRegionsChanged();
- }
+ Document* document = m_frame->document();
+ if (!document->hasDashboardRegions())
+ return;
+ Vector<DashboardRegionValue> newRegions;
+ document->renderer()->collectDashboardRegions(newRegions);
+ if (newRegions == document->dashboardRegions())
+ return;
+ document->setDashboardRegions(newRegions);
+ Page* page = m_frame->page();
+ if (!page)
+ return;
+ page->chrome()->client()->dashboardRegionsChanged();
}
+#endif
void FrameView::updateControlTints()
{
@@ -1086,17 +1160,16 @@ void FrameView::updateControlTints()
if (!m_frame || m_frame->loader()->url().isEmpty())
return;
- if (theme()->supportsControlTints() && m_frame->renderer()) {
+ if (theme()->supportsControlTints() && m_frame->contentRenderer()) {
if (needsLayout())
layout();
PlatformGraphicsContext* const noContext = 0;
GraphicsContext context(noContext);
context.setUpdatingControlTints(true);
-#if !PLATFORM(MAC)
- ScrollView::paint(&context, frameGeometry());
-#else
- m_frame->paint(&context, enclosingIntRect(visibleContentRect()));
-#endif
+ if (platformWidget())
+ paintContents(&context, visibleContentRect());
+ else
+ paint(&context, frameRect());
}
}
@@ -1112,7 +1185,82 @@ void FrameView::setWasScrolledByUser(bool wasScrolledByUser)
d->m_wasScrolledByUser = wasScrolledByUser;
}
-#if PLATFORM(WIN) || PLATFORM(GTK) || PLATFORM(QT)
+void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
+{
+ if (!frame())
+ return;
+
+ Document* document = frame()->document();
+ if (!document)
+ return;
+
+#ifndef NDEBUG
+ bool fillWithRed;
+ if (document || document->printing())
+ fillWithRed = false; // Printing, don't fill with red (can't remember why).
+ else if (document->ownerElement())
+ fillWithRed = false; // Subframe, don't fill with red.
+ else if (isTransparent())
+ fillWithRed = false; // Transparent, don't fill with red.
+ else if (d->m_paintRestriction == PaintRestrictionSelectionOnly || d->m_paintRestriction == PaintRestrictionSelectionOnlyBlackText)
+ fillWithRed = false; // Selections are transparent, don't fill with red.
+ else if (d->m_nodeToDraw)
+ fillWithRed = false; // Element images are transparent, don't fill with red.
+ else
+ fillWithRed = true;
+
+ if (fillWithRed)
+ p->fillRect(rect, Color(0xFF, 0, 0));
+#endif
+
+ bool isTopLevelPainter = !sCurrentPaintTimeStamp;
+ if (isTopLevelPainter)
+ sCurrentPaintTimeStamp = currentTime();
+
+ RenderView* contentRenderer = frame()->contentRenderer();
+ if (!contentRenderer) {
+ LOG_ERROR("called Frame::paint with nil renderer");
+ return;
+ }
+
+ ASSERT(!needsLayout());
+ ASSERT(!d->m_isPainting);
+
+ d->m_isPainting = true;
+
+ // m_nodeToDraw is used to draw only one element (and its descendants)
+ RenderObject* eltRenderer = d->m_nodeToDraw ? d->m_nodeToDraw->renderer() : 0;
+ if (d->m_paintRestriction == PaintRestrictionNone)
+ document->invalidateRenderedRectsForMarkersInRect(rect);
+ contentRenderer->layer()->paint(p, rect, d->m_paintRestriction, eltRenderer);
+
+ d->m_isPainting = false;
+
+#if ENABLE(DASHBOARD_SUPPORT)
+ // Regions may have changed as a result of the visibility/z-index of element changing.
+ if (document->dashboardRegionsDirty())
+ updateDashboardRegions();
+#endif
+
+ if (isTopLevelPainter)
+ sCurrentPaintTimeStamp = 0;
+}
+
+void FrameView::setPaintRestriction(PaintRestriction pr)
+{
+ d->m_paintRestriction = pr;
+}
+
+bool FrameView::isPainting() const
+{
+ return d->m_isPainting;
+}
+
+void FrameView::setNodeToDraw(Node* node)
+{
+ d->m_nodeToDraw = node;
+}
+
void FrameView::layoutIfNeededRecursive()
{
// We have to crawl our entire tree looking for any FrameViews that need
@@ -1127,12 +1275,11 @@ void FrameView::layoutIfNeededRecursive()
if (needsLayout())
layout();
- HashSet<Widget*>* viewChildren = children();
- HashSet<Widget*>::iterator end = viewChildren->end();
- for (HashSet<Widget*>::iterator current = viewChildren->begin(); current != end; ++current)
+ const HashSet<Widget*>* viewChildren = children();
+ HashSet<Widget*>::const_iterator end = viewChildren->end();
+ for (HashSet<Widget*>::const_iterator current = viewChildren->begin(); current != end; ++current)
if ((*current)->isFrameView())
static_cast<FrameView*>(*current)->layoutIfNeededRecursive();
}
-#endif
}
diff --git a/WebCore/page/FrameView.h b/WebCore/page/FrameView.h
index 7577b10..84a829f 100644
--- a/WebCore/page/FrameView.h
+++ b/WebCore/page/FrameView.h
@@ -25,8 +25,9 @@
#ifndef FrameView_h
#define FrameView_h
-#include "ScrollView.h"
#include "IntSize.h"
+#include "RenderLayer.h"
+#include "ScrollView.h"
#include <wtf/Forward.h>
#include <wtf/OwnPtr.h>
@@ -49,16 +50,17 @@ template <typename T> class Timer;
class FrameView : public ScrollView {
public:
- FrameView(Frame*);
+ friend class RenderView;
- // On the Mac, FrameViews always get their size from the underlying NSView,
- // so passing in a size is nonsensical.
-#if !PLATFORM(MAC)
+ FrameView(Frame*);
FrameView(Frame*, const IntSize& initialSize);
-#endif
virtual ~FrameView();
+ virtual HostWindow* hostWindow() const;
+
+ virtual void invalidateRect(const IntRect&);
+
Frame* frame() const { return m_frame.get(); }
void clearFrame();
@@ -71,9 +73,7 @@ public:
void setMarginWidth(int);
void setMarginHeight(int);
- virtual void setVScrollbarMode(ScrollbarMode);
- virtual void setHScrollbarMode(ScrollbarMode);
- virtual void setScrollbarsMode(ScrollbarMode);
+ virtual void setCanHaveScrollbars(bool);
void layout(bool allowSubtree = true);
bool didFirstLayout() const;
@@ -91,8 +91,6 @@ public:
void setNeedsLayout();
bool needsFullRepaint() const;
- void repaintRectangle(const IntRect&, bool immediate);
- void addRepaintInfo(RenderObject*, const IntRect&);
void resetScrollbars();
@@ -104,15 +102,23 @@ public:
Color baseBackgroundColor() const;
void setBaseBackgroundColor(Color);
+ bool shouldUpdateWhileOffscreen() const;
+ void setShouldUpdateWhileOffscreen(bool);
+
void adjustViewSize();
void initScrollbars();
- virtual IntRect windowClipRect() const;
- IntRect windowClipRect(bool clipToContents) const;
+ virtual IntRect windowClipRect(bool clipToContents = true) const;
IntRect windowClipRectForLayer(const RenderLayer*, bool clipToLayerContents) const;
+ virtual bool isActive() const;
+ virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&);
+ virtual void valueChanged(Scrollbar*);
+
+ virtual IntRect windowResizerRect() const;
+
virtual void scrollRectIntoViewRecursively(const IntRect&);
- virtual void setContentsPos(int x, int y);
+ virtual void setScrollPosition(const IntPoint&);
String mediaType() const;
void setMediaType(const String&);
@@ -122,12 +128,17 @@ public:
void addSlowRepaintObject();
void removeSlowRepaintObject();
+ void beginDeferredRepaints();
+ void endDeferredRepaints();
+
+#if ENABLE(DASHBOARD_SUPPORT)
void updateDashboardRegions();
+#endif
void updateControlTints();
void restoreScrollbar();
- void scheduleEvent(PassRefPtr<Event>, PassRefPtr<EventTargetNode>, bool tempEvent);
+ void scheduleEvent(PassRefPtr<Event>, PassRefPtr<EventTargetNode>);
void pauseScheduledEvents();
void resumeScheduledEvents();
void postLayoutTimerFired(Timer<FrameView>*);
@@ -138,19 +149,20 @@ public:
void addWidgetToUpdate(RenderPartObject*);
void removeWidgetToUpdate(RenderPartObject*);
- // FIXME: This method should be used by all platforms, but currently depends on ScrollView::children,
- // which not all methods have. Once FrameView and ScrollView are merged, this #if should be removed.
-#if PLATFORM(WIN) || PLATFORM(GTK) || PLATFORM(QT)
+ virtual void paintContents(GraphicsContext*, const IntRect& damageRect);
+ void setPaintRestriction(PaintRestriction);
+ bool isPainting() const;
+ void setNodeToDraw(Node*);
+
+ static double currentPaintTimeStamp() { return sCurrentPaintTimeStamp; } // returns 0 if not painting
+
void layoutIfNeededRecursive();
-#endif
private:
void init();
virtual bool isFrameView() const;
- bool scrollTo(const IntRect&);
-
bool useSlowRepaints() const;
void applyOverflowToViewport(RenderObject*, ScrollbarMode& hMode, ScrollbarMode& vMode);
@@ -160,6 +172,12 @@ private:
void dispatchScheduledEvents();
void performPostLayoutTasks();
+ virtual void repaintContentRectangle(const IntRect&, bool immediate);
+ virtual void contentsResized() { setNeedsLayout(); }
+ virtual void visibleContentsResized() { layout(); }
+
+ static double sCurrentPaintTimeStamp; // used for detecting decoded resource thrash in the cache
+
unsigned m_refCount;
IntSize m_size;
IntSize m_margins;
diff --git a/WebCore/page/Geolocation.cpp b/WebCore/page/Geolocation.cpp
new file mode 100644
index 0000000..a0c9694
--- /dev/null
+++ b/WebCore/page/Geolocation.cpp
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Geolocation.h"
+
+#include "Document.h"
+#include "Frame.h"
+#include "PositionError.h"
+
+namespace WebCore {
+
+Geolocation::GeoNotifier::GeoNotifier(PassRefPtr<PositionCallback> successCallback, PassRefPtr<PositionErrorCallback> errorCallback, PositionOptions* options)
+ : m_successCallback(successCallback)
+ , m_errorCallback(errorCallback)
+ , m_timer(this, &Geolocation::GeoNotifier::timerFired)
+{
+ if (m_errorCallback && options)
+ m_timer.startOneShot(options->timeout() / 1000.0);
+}
+
+void Geolocation::GeoNotifier::timerFired(Timer<GeoNotifier>*)
+{
+ ASSERT(m_errorCallback);
+
+ m_timer.stop();
+
+ RefPtr<PositionError> error = PositionError::create(PositionError::TIMEOUT_ERROR, "Timed out");
+ m_errorCallback->handleEvent(error.get());
+}
+
+Geolocation::Geolocation(Frame* frame)
+ : m_frame(frame)
+ , m_service(GeolocationService::create(this))
+{
+ ASSERT(m_frame->document());
+ m_frame->document()->setUsingGeolocation(true);
+}
+
+void Geolocation::disconnectFrame()
+{
+ m_service->stopUpdating();
+ if (m_frame->document())
+ m_frame->document()->setUsingGeolocation(false);
+ m_frame = 0;
+}
+
+void Geolocation::getCurrentPosition(PassRefPtr<PositionCallback> successCallback, PassRefPtr<PositionErrorCallback> errorCallback, PositionOptions* options)
+{
+ RefPtr<GeoNotifier> notifier = GeoNotifier::create(successCallback, errorCallback, options);
+
+ if (!m_service->startUpdating(options)) {
+ if (notifier->m_errorCallback) {
+ RefPtr<PositionError> error = PositionError::create(PositionError::PERMISSION_ERROR, "Unable to Start");
+ notifier->m_errorCallback->handleEvent(error.get());
+ }
+ return;
+ }
+
+ m_oneShots.add(notifier);
+}
+
+int Geolocation::watchPosition(PassRefPtr<PositionCallback> successCallback, PassRefPtr<PositionErrorCallback> errorCallback, PositionOptions* options)
+{
+ RefPtr<GeoNotifier> notifier = GeoNotifier::create(successCallback, errorCallback, options);
+
+ if (!m_service->startUpdating(options)) {
+ if (notifier->m_errorCallback) {
+ RefPtr<PositionError> error = PositionError::create(PositionError::PERMISSION_ERROR, "Unable to Start");
+ notifier->m_errorCallback->handleEvent(error.get());
+ }
+ return 0;
+ }
+
+ static int sIdentifier = 0;
+
+ m_watchers.set(++sIdentifier, notifier);
+
+ return sIdentifier;
+}
+
+void Geolocation::clearWatch(int watchId)
+{
+ m_watchers.remove(watchId);
+
+ if (!hasListeners())
+ m_service->stopUpdating();
+}
+
+void Geolocation::suspend()
+{
+ if (hasListeners())
+ m_service->suspend();
+}
+
+void Geolocation::resume()
+{
+ if (hasListeners())
+ m_service->resume();
+}
+
+void Geolocation::sendErrorToOneShots(PositionError* error)
+{
+ Vector<RefPtr<GeoNotifier> > copy;
+ copyToVector(m_oneShots, copy);
+
+ Vector<RefPtr<GeoNotifier> >::const_iterator end = copy.end();
+ for (Vector<RefPtr<GeoNotifier> >::const_iterator it = copy.begin(); it != end; ++it) {
+ RefPtr<GeoNotifier> notifier = *it;
+
+ if (notifier->m_errorCallback)
+ notifier->m_errorCallback->handleEvent(error);
+ }
+}
+
+void Geolocation::sendErrorToWatchers(PositionError* error)
+{
+ Vector<RefPtr<GeoNotifier> > copy;
+ copyValuesToVector(m_watchers, copy);
+
+ Vector<RefPtr<GeoNotifier> >::const_iterator end = copy.end();
+ for (Vector<RefPtr<GeoNotifier> >::const_iterator it = copy.begin(); it != end; ++it) {
+ RefPtr<GeoNotifier> notifier = *it;
+
+ if (notifier->m_errorCallback)
+ notifier->m_errorCallback->handleEvent(error);
+ }
+}
+
+void Geolocation::sendPositionToOneShots(Geoposition* position)
+{
+ Vector<RefPtr<GeoNotifier> > copy;
+ copyToVector(m_oneShots, copy);
+
+ Vector<RefPtr<GeoNotifier> >::const_iterator end = copy.end();
+ for (Vector<RefPtr<GeoNotifier> >::const_iterator it = copy.begin(); it != end; ++it) {
+ RefPtr<GeoNotifier> notifier = *it;
+ ASSERT(notifier->m_successCallback);
+
+ notifier->m_timer.stop();
+ bool shouldCallErrorCallback = false;
+ notifier->m_successCallback->handleEvent(position, shouldCallErrorCallback);
+ if (shouldCallErrorCallback) {
+ RefPtr<PositionError> error = PositionError::create(PositionError::UNKNOWN_ERROR, "An exception was thrown");
+ handleError(error.get());
+ }
+ }
+}
+
+void Geolocation::sendPositionToWatchers(Geoposition* position)
+{
+ Vector<RefPtr<GeoNotifier> > copy;
+ copyValuesToVector(m_watchers, copy);
+
+ Vector<RefPtr<GeoNotifier> >::const_iterator end = copy.end();
+ for (Vector<RefPtr<GeoNotifier> >::const_iterator it = copy.begin(); it != end; ++it) {
+ RefPtr<GeoNotifier> notifier = *it;
+ ASSERT(notifier->m_successCallback);
+
+ notifier->m_timer.stop();
+ bool shouldCallErrorCallback = false;
+ notifier->m_successCallback->handleEvent(position, shouldCallErrorCallback);
+ if (shouldCallErrorCallback) {
+ RefPtr<PositionError> error = PositionError::create(PositionError::UNKNOWN_ERROR, "An exception was thrown");
+ handleError(error.get());
+ }
+ }
+}
+
+void Geolocation::handleError(PositionError* error)
+{
+ ASSERT(error);
+
+ sendErrorToOneShots(error);
+ sendErrorToWatchers(error);
+
+ m_oneShots.clear();
+}
+
+void Geolocation::geolocationServicePositionChanged(GeolocationService* service)
+{
+ ASSERT(service->lastPosition());
+
+ sendPositionToOneShots(service->lastPosition());
+ sendPositionToWatchers(service->lastPosition());
+
+ m_oneShots.clear();
+
+ if (!hasListeners())
+ m_service->stopUpdating();
+}
+
+void Geolocation::geolocationServiceErrorOccurred(GeolocationService* service)
+{
+ ASSERT(service->lastError());
+
+ handleError(service->lastError());
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/Geolocation.h b/WebCore/page/Geolocation.h
new file mode 100644
index 0000000..572cbd8
--- /dev/null
+++ b/WebCore/page/Geolocation.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef Geolocation_h
+#define Geolocation_h
+
+#include "GeolocationService.h"
+#include "PositionCallback.h"
+#include "PositionErrorCallback.h"
+#include "PositionOptions.h"
+#include "Timer.h"
+#include <wtf/Platform.h>
+#include <wtf/HashMap.h>
+#include <wtf/HashSet.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class Frame;
+class Geoposition;
+
+class Geolocation : public RefCounted<Geolocation>, public GeolocationServiceClient {
+public:
+ static PassRefPtr<Geolocation> create(Frame* frame) { return adoptRef(new Geolocation(frame)); }
+
+ virtual ~Geolocation() {}
+
+ void disconnectFrame();
+
+ Geoposition* lastPosition() const { return m_service->lastPosition(); }
+
+ void getCurrentPosition(PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PositionOptions*);
+ int watchPosition(PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PositionOptions*);
+ void clearWatch(int watchId);
+
+ void suspend();
+ void resume();
+
+private:
+ Geolocation(Frame*);
+
+ class GeoNotifier : public RefCounted<GeoNotifier> {
+ public:
+ static PassRefPtr<GeoNotifier> create(PassRefPtr<PositionCallback> positionCallback, PassRefPtr<PositionErrorCallback> positionErrorCallback, PositionOptions* options) { return adoptRef(new GeoNotifier(positionCallback, positionErrorCallback, options)); }
+
+ void timerFired(Timer<GeoNotifier>*);
+
+ RefPtr<PositionCallback> m_successCallback;
+ RefPtr<PositionErrorCallback> m_errorCallback;
+ Timer<GeoNotifier> m_timer;
+
+ private:
+ GeoNotifier(PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PositionOptions*);
+ };
+
+ bool hasListeners() const { return !m_oneShots.isEmpty() || !m_watchers.isEmpty(); }
+
+ void sendErrorToOneShots(PositionError*);
+ void sendErrorToWatchers(PositionError*);
+ void sendPositionToOneShots(Geoposition*);
+ void sendPositionToWatchers(Geoposition*);
+
+ void handleError(PositionError*);
+
+ virtual void geolocationServicePositionChanged(GeolocationService*);
+ virtual void geolocationServiceErrorOccurred(GeolocationService*);
+
+ typedef HashSet<RefPtr<GeoNotifier> > GeoNotifierSet;
+ typedef HashMap<int, RefPtr<GeoNotifier> > GeoNotifierMap;
+
+ GeoNotifierSet m_oneShots;
+ GeoNotifierMap m_watchers;
+ Frame* m_frame;
+ OwnPtr<GeolocationService> m_service;
+};
+
+} // namespace WebCore
+
+#endif // Geolocation_h
diff --git a/WebCore/page/Geolocation.idl b/WebCore/page/Geolocation.idl
new file mode 100644
index 0000000..e125118
--- /dev/null
+++ b/WebCore/page/Geolocation.idl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module core {
+
+ interface Geolocation {
+ readonly attribute Geoposition lastPosition;
+
+ [Custom] void getCurrentPosition(in PositionCallback successCallback, in PositionErrorCallback errorCallback, in PositionOptions options);
+
+ [Custom] long watchPosition(in PositionCallback successCallback, in PositionErrorCallback errorCallback, in PositionOptions options);
+
+ void clearWatch(in long watchId);
+ };
+
+}
diff --git a/WebCore/page/Geoposition.cpp b/WebCore/page/Geoposition.cpp
new file mode 100644
index 0000000..1792a1f
--- /dev/null
+++ b/WebCore/page/Geoposition.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Geoposition.h"
+
+namespace WebCore {
+
+String Geoposition::toString() const
+{
+ return String::format("position(%.6lg, %.6lg, %.6lg, %.6lg, %.6lg, %.6lg, %.6lg, %.lld)",
+ m_latitude, m_longitude, m_altitude, m_accuracy,
+ m_altitudeAccuracy, m_heading, m_speed, m_timestamp);
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/Geoposition.h b/WebCore/page/Geoposition.h
new file mode 100644
index 0000000..9ce50e5
--- /dev/null
+++ b/WebCore/page/Geoposition.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef Geoposition_h
+#define Geoposition_h
+
+#include "Event.h"
+#include "PlatformString.h"
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+typedef int ExceptionCode;
+
+class Geoposition : public RefCounted<Geoposition> {
+public:
+ static PassRefPtr<Geoposition> create(double latitude, double longitude, double altitude, double accuracy, double altitudeAccuracy, double heading, double speed, DOMTimeStamp timestamp) { return adoptRef(new Geoposition(latitude, longitude, altitude, accuracy, altitudeAccuracy, heading, speed, timestamp)); }
+
+ double latitude() const { return m_latitude; }
+ double longitude() const { return m_longitude; }
+ double altitude() const { return m_altitude; }
+ double accuracy() const { return m_accuracy; }
+ double altitudeAccuracy() const { return m_altitudeAccuracy; }
+ double heading() const { return m_heading; }
+ double speed() const { return m_speed; }
+ DOMTimeStamp timestamp() const { return m_timestamp; }
+
+ String toString() const;
+
+private:
+ Geoposition(double latitude, double longitude, double altitude, double accuracy, double altitudeAccuracy, double heading, double speed, DOMTimeStamp timestamp)
+ : m_latitude(latitude)
+ , m_longitude(longitude)
+ , m_altitude(altitude)
+ , m_accuracy(accuracy)
+ , m_altitudeAccuracy(altitudeAccuracy)
+ , m_heading(heading)
+ , m_speed(speed)
+ , m_timestamp(timestamp)
+ {
+ }
+
+ double m_latitude;
+ double m_longitude;
+ double m_altitude;
+ double m_accuracy;
+ double m_altitudeAccuracy;
+ double m_heading;
+ double m_speed;
+ DOMTimeStamp m_timestamp;
+};
+
+} // namespace WebCore
+
+#endif // Geoposition_h
diff --git a/WebCore/page/Geoposition.idl b/WebCore/page/Geoposition.idl
new file mode 100644
index 0000000..554bb30
--- /dev/null
+++ b/WebCore/page/Geoposition.idl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module core {
+
+ interface Geoposition {
+ readonly attribute double latitude;
+ readonly attribute double longitude;
+ readonly attribute double altitude;
+ readonly attribute double accuracy;
+ readonly attribute double altitudeAccuracy;
+ readonly attribute double heading;
+ readonly attribute double speed;
+ readonly attribute DOMTimeStamp timestamp;
+
+#if defined(LANGUAGE_JAVASCRIPT)
+ [DontEnum] DOMString toString();
+#endif
+ };
+}
diff --git a/WebCore/page/History.h b/WebCore/page/History.h
index 815a44d..f0df2de 100644
--- a/WebCore/page/History.h
+++ b/WebCore/page/History.h
@@ -26,6 +26,7 @@
#ifndef History_h
#define History_h
+#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
namespace WebCore {
@@ -34,8 +35,8 @@ namespace WebCore {
class History : public RefCounted<History> {
public:
- History(Frame*);
-
+ static PassRefPtr<History> create(Frame* frame) { return adoptRef(new History(frame)); }
+
Frame* frame() const;
void disconnectFrame();
@@ -45,6 +46,8 @@ namespace WebCore {
void go(int distance);
private:
+ History(Frame*);
+
Frame* m_frame;
};
diff --git a/WebCore/page/InspectorController.cpp b/WebCore/page/InspectorController.cpp
deleted file mode 100644
index df748a0..0000000
--- a/WebCore/page/InspectorController.cpp
+++ /dev/null
@@ -1,1646 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "InspectorController.h"
-
-#include "CString.h"
-#include "CachedResource.h"
-#include "DocLoader.h"
-#include "Document.h"
-#include "DocumentLoader.h"
-#include "Element.h"
-#include "FloatConversion.h"
-#include "FloatRect.h"
-#include "Frame.h"
-#include "FrameLoader.h"
-#include "FrameTree.h"
-#include "FrameView.h"
-#include "GraphicsContext.h"
-#include "HTMLFrameOwnerElement.h"
-#include "InspectorClient.h"
-#include "JSRange.h"
-#include "Page.h"
-#include "Range.h"
-#include "ResourceRequest.h"
-#include "ResourceResponse.h"
-#include "Settings.h"
-#include "SharedBuffer.h"
-#include "SystemTime.h"
-#include "TextEncoding.h"
-#include "TextIterator.h"
-#include "kjs_dom.h"
-#include "kjs_proxy.h"
-#include "kjs_window.h"
-#include <JavaScriptCore/APICast.h>
-#include <JavaScriptCore/JSLock.h>
-#include <JavaScriptCore/JSRetainPtr.h>
-#include <JavaScriptCore/JSStringRef.h>
-#include <wtf/RefCounted.h>
-
-#if ENABLE(DATABASE)
-#include "Database.h"
-#include "JSDatabase.h"
-#endif
-
-namespace WebCore {
-
-static JSValueRef callSimpleFunction(JSContextRef context, JSObjectRef thisObject, const char* functionName)
-{
- ASSERT_ARG(context, context);
- ASSERT_ARG(thisObject, thisObject);
-
- JSRetainPtr<JSStringRef> functionNameString(Adopt, JSStringCreateWithUTF8CString(functionName));
- JSObjectRef function = JSValueToObject(context, JSObjectGetProperty(context, thisObject, functionNameString.get(), 0), 0);
-
- return JSObjectCallAsFunction(context, function, thisObject, 0, 0, 0);
-}
-
-#pragma mark -
-#pragma mark ConsoleMessage Struct
-
-struct ConsoleMessage {
- ConsoleMessage(MessageSource s, MessageLevel l, const String& m, unsigned li, const String& u)
- : source(s)
- , level(l)
- , message(m)
- , line(li)
- , url(u)
- {
- }
-
- MessageSource source;
- MessageLevel level;
- String message;
- unsigned line;
- String url;
-};
-
-#pragma mark -
-#pragma mark InspectorResource Struct
-
-struct InspectorResource : public RefCounted<InspectorResource> {
- // Keep these in sync with WebInspector.Resource.Type
- enum Type {
- Doc,
- Stylesheet,
- Image,
- Font,
- Script,
- Other
- };
-
- InspectorResource(long long identifier, DocumentLoader* documentLoader, Frame* frame)
- : identifier(identifier)
- , loader(documentLoader)
- , frame(frame)
- , scriptContext(0)
- , scriptObject(0)
- , expectedContentLength(0)
- , cached(false)
- , finished(false)
- , failed(false)
- , length(0)
- , responseStatusCode(0)
- , startTime(-1.0)
- , responseReceivedTime(-1.0)
- , endTime(-1.0)
- {
- }
-
- ~InspectorResource()
- {
- setScriptObject(0, 0);
- }
-
- Type type() const
- {
- if (requestURL == loader->requestURL())
- return Doc;
-
- if (loader->frameLoader() && requestURL == loader->frameLoader()->iconURL())
- return Image;
-
- CachedResource* cachedResource = frame->document()->docLoader()->cachedResource(requestURL.string());
- if (!cachedResource)
- return Other;
-
- switch (cachedResource->type()) {
- case CachedResource::ImageResource:
- return Image;
- case CachedResource::FontResource:
- return Font;
- case CachedResource::CSSStyleSheet:
-#if ENABLE(XSLT)
- case CachedResource::XSLStyleSheet:
-#endif
- return Stylesheet;
- case CachedResource::Script:
- return Script;
- default:
- return Other;
- }
- }
-
- void setScriptObject(JSContextRef context, JSObjectRef newScriptObject)
- {
- if (scriptContext && scriptObject)
- JSValueUnprotect(scriptContext, scriptObject);
-
- scriptObject = newScriptObject;
- scriptContext = context;
-
- ASSERT((context && newScriptObject) || (!context && !newScriptObject));
- if (context && newScriptObject)
- JSValueProtect(context, newScriptObject);
- }
-
- long long identifier;
- RefPtr<DocumentLoader> loader;
- RefPtr<Frame> frame;
- KURL requestURL;
- HTTPHeaderMap requestHeaderFields;
- HTTPHeaderMap responseHeaderFields;
- String mimeType;
- String suggestedFilename;
- JSContextRef scriptContext;
- JSObjectRef scriptObject;
- long long expectedContentLength;
- bool cached;
- bool finished;
- bool failed;
- int length;
- int responseStatusCode;
- double startTime;
- double responseReceivedTime;
- double endTime;
-};
-
-#pragma mark -
-#pragma mark InspectorDatabaseResource Struct
-
-#if ENABLE(DATABASE)
-struct InspectorDatabaseResource : public RefCounted<InspectorDatabaseResource> {
- InspectorDatabaseResource(Database* database, String domain, String name, String version)
- : database(database)
- , domain(domain)
- , name(name)
- , version(version)
- , scriptContext(0)
- , scriptObject(0)
- {
- }
-
- InspectorDatabaseResource()
- {
- setScriptObject(0, 0);
- }
-
- void setScriptObject(JSContextRef context, JSObjectRef newScriptObject)
- {
- if (scriptContext && scriptObject)
- JSValueUnprotect(scriptContext, scriptObject);
-
- scriptObject = newScriptObject;
- scriptContext = context;
-
- ASSERT((context && newScriptObject) || (!context && !newScriptObject));
- if (context && newScriptObject)
- JSValueProtect(context, newScriptObject);
- }
-
- RefPtr<Database> database;
- String domain;
- String name;
- String version;
- JSContextRef scriptContext;
- JSObjectRef scriptObject;
-};
-#endif
-
-#pragma mark -
-#pragma mark JavaScript Callbacks
-
-static JSValueRef addSourceToFrame(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* /*exception*/)
-{
- JSValueRef undefined = JSValueMakeUndefined(ctx);
-
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (argumentCount < 2 || !controller)
- return undefined;
-
- JSValueRef identifierValue = arguments[0];
- if (!JSValueIsNumber(ctx, identifierValue))
- return undefined;
-
- unsigned long identifier = static_cast<unsigned long>(JSValueToNumber(ctx, identifierValue, 0));
- RefPtr<InspectorResource> resource = controller->resources().get(identifier);
- ASSERT(resource);
- if (!resource)
- return undefined;
-
- RefPtr<SharedBuffer> buffer;
- String textEncodingName;
- if (resource->requestURL == resource->loader->requestURL()) {
- buffer = resource->loader->mainResourceData();
- textEncodingName = resource->frame->document()->inputEncoding();
- } else {
- CachedResource* cachedResource = resource->frame->document()->docLoader()->cachedResource(resource->requestURL.string());
- if (!cachedResource)
- return undefined;
-
- buffer = cachedResource->data();
- textEncodingName = cachedResource->encoding();
- }
-
- if (!buffer)
- return undefined;
-
- TextEncoding encoding(textEncodingName);
- if (!encoding.isValid())
- encoding = WindowsLatin1Encoding();
- String sourceString = encoding.decode(buffer->data(), buffer->size());
-
- Node* node = toNode(toJS(arguments[1]));
- ASSERT(node);
- if (!node)
- return undefined;
-
- if (!node->attached()) {
- ASSERT_NOT_REACHED();
- return undefined;
- }
-
- ASSERT(node->isElementNode());
- if (!node->isElementNode())
- return undefined;
-
- Element* element = static_cast<Element*>(node);
- ASSERT(element->isFrameOwnerElement());
- if (!element->isFrameOwnerElement())
- return undefined;
-
- HTMLFrameOwnerElement* frameOwner = static_cast<HTMLFrameOwnerElement*>(element);
- ASSERT(frameOwner->contentFrame());
- if (!frameOwner->contentFrame())
- return undefined;
-
- FrameLoader* loader = frameOwner->contentFrame()->loader();
-
- loader->setResponseMIMEType(resource->mimeType);
- loader->begin();
- loader->write(sourceString);
- loader->end();
-
- return undefined;
-}
-
-static JSValueRef getResourceDocumentNode(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* /*exception*/)
-{
- JSValueRef undefined = JSValueMakeUndefined(ctx);
-
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!argumentCount || argumentCount > 1 || !controller)
- return undefined;
-
- JSValueRef identifierValue = arguments[0];
- if (!JSValueIsNumber(ctx, identifierValue))
- return undefined;
-
- unsigned long identifier = static_cast<unsigned long>(JSValueToNumber(ctx, identifierValue, 0));
- RefPtr<InspectorResource> resource = controller->resources().get(identifier);
- ASSERT(resource);
- if (!resource)
- return undefined;
-
- Document* document = resource->frame->document();
- if (!document)
- return undefined;
-
- if (document->isPluginDocument() || document->isImageDocument())
- return undefined;
-
- KJS::JSLock lock;
- JSValueRef documentValue = toRef(toJS(toJS(controller->scriptContext()), document));
- return documentValue;
-}
-
-static JSValueRef highlightDOMNode(JSContextRef context, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* /*exception*/)
-{
- JSValueRef undefined = JSValueMakeUndefined(context);
-
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (argumentCount < 1 || !controller)
- return undefined;
-
- Node* node = toNode(toJS(arguments[0]));
- if (!node)
- return undefined;
-
- controller->highlight(node);
-
- return undefined;
-}
-
-static JSValueRef hideDOMNodeHighlight(JSContextRef context, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* /*exception*/)
-{
- JSValueRef undefined = JSValueMakeUndefined(context);
-
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (argumentCount || !controller)
- return undefined;
-
- controller->hideHighlight();
-
- return undefined;
-}
-
-static JSValueRef loaded(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t /*argumentCount*/, const JSValueRef[] /*arguments[]*/, JSValueRef* /*exception*/)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- controller->scriptObjectReady();
- return JSValueMakeUndefined(ctx);
-}
-
-static JSValueRef unloading(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t /*argumentCount*/, const JSValueRef[] /*arguments[]*/, JSValueRef* /*exception*/)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- controller->close();
- return JSValueMakeUndefined(ctx);
-}
-
-static JSValueRef attach(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t /*argumentCount*/, const JSValueRef[] /*arguments[]*/, JSValueRef* /*exception*/)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- controller->attachWindow();
- return JSValueMakeUndefined(ctx);
-}
-
-static JSValueRef detach(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t /*argumentCount*/, const JSValueRef[] /*arguments[]*/, JSValueRef* /*exception*/)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- controller->detachWindow();
- return JSValueMakeUndefined(ctx);
-}
-
-static JSValueRef search(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* /*exception*/)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- if (argumentCount < 2 || !JSValueIsString(ctx, arguments[1]))
- return JSValueMakeUndefined(ctx);
-
- Node* node = toNode(toJS(arguments[0]));
- if (!node)
- return JSValueMakeUndefined(ctx);
-
- JSRetainPtr<JSStringRef> searchString(Adopt, JSValueToStringCopy(ctx, arguments[1], 0));
- String target(JSStringGetCharactersPtr(searchString.get()), JSStringGetLength(searchString.get()));
-
- JSObjectRef global = JSContextGetGlobalObject(ctx);
- JSRetainPtr<JSStringRef> arrayString(Adopt, JSStringCreateWithUTF8CString("Array"));
- JSObjectRef arrayConstructor = JSValueToObject(ctx, JSObjectGetProperty(ctx, global, arrayString.get(), 0), 0);
-
- JSObjectRef result = JSObjectCallAsConstructor(ctx, arrayConstructor, 0, 0, 0);
-
- JSRetainPtr<JSStringRef> pushString(Adopt, JSStringCreateWithUTF8CString("push"));
- JSObjectRef pushFunction = JSValueToObject(ctx, JSObjectGetProperty(ctx, result, pushString.get(), 0), 0);
-
- RefPtr<Range> searchRange(rangeOfContents(node));
-
- int exception = 0;
- do {
- RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, true, false));
- if (resultRange->collapsed(exception))
- break;
-
- // 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;
-
- KJS::JSLock lock;
- JSValueRef arg0 = toRef(toJS(toJS(ctx), resultRange.get()));
- JSObjectCallAsFunction(ctx, pushFunction, result, 1, &arg0, 0);
-
- setStart(searchRange.get(), newStart);
- } while (true);
-
- return result;
-}
-
-#if ENABLE(DATABASE)
-static JSValueRef databaseTableNames(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* /*exception*/)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- if (argumentCount < 1)
- return JSValueMakeUndefined(ctx);
-
- Database* database = toDatabase(toJS(arguments[0]));
- if (!database)
- return JSValueMakeUndefined(ctx);
-
- JSObjectRef global = JSContextGetGlobalObject(ctx);
- JSRetainPtr<JSStringRef> arrayString(Adopt, JSStringCreateWithUTF8CString("Array"));
- JSObjectRef arrayConstructor = JSValueToObject(ctx, JSObjectGetProperty(ctx, global, arrayString.get(), 0), 0);
-
- JSObjectRef result = JSObjectCallAsConstructor(ctx, arrayConstructor, 0, 0, 0);
-
- JSRetainPtr<JSStringRef> pushString(Adopt, JSStringCreateWithUTF8CString("push"));
- JSObjectRef pushFunction = JSValueToObject(ctx, JSObjectGetProperty(ctx, result, pushString.get(), 0), 0);
-
- Vector<String> tableNames = database->tableNames();
- unsigned length = tableNames.size();
- for (unsigned i = 0; i < length; ++i) {
- String tableName = tableNames[i];
- JSRetainPtr<JSStringRef> tableNameString(Adopt, JSStringCreateWithCharacters(tableName.characters(), tableName.length()));
- JSValueRef tableNameValue = JSValueMakeString(ctx, tableNameString.get());
-
- JSValueRef pushArguments[] = { tableNameValue };
- JSObjectCallAsFunction(ctx, pushFunction, result, 1, pushArguments, 0);
- }
-
- return result;
-}
-#endif
-
-static JSValueRef inspectedWindow(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t /*argumentCount*/, const JSValueRef[] /*arguments[]*/, JSValueRef* /*exception*/)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- return toRef(KJS::Window::retrieve(controller->inspectedPage()->mainFrame()));
-}
-
-static JSValueRef localizedStrings(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t /*argumentCount*/, const JSValueRef[] /*arguments[]*/, JSValueRef* /*exception*/)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- String url = controller->localizedStringsURL();
- if (url.isNull())
- return JSValueMakeNull(ctx);
-
- JSRetainPtr<JSStringRef> urlString(Adopt, JSStringCreateWithCharacters(url.characters(), url.length()));
- return JSValueMakeString(ctx, urlString.get());
-}
-
-static JSValueRef platform(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t /*argumentCount*/, const JSValueRef[] /*arguments[]*/, JSValueRef* /*exception*/)
-{
-#if PLATFORM(MAC)
-#ifdef BUILDING_ON_TIGER
- static const String platform = "mac-tiger";
-#else
- static const String platform = "mac-leopard";
-#endif
-#elif PLATFORM(WIN_OS)
- static const String platform = "windows";
-#elif PLATFORM(QT)
- static const String platform = "qt";
-#elif PLATFORM(GTK)
- static const String platform = "gtk";
-#elif PLATFORM(WX)
- static const String platform = "wx";
-#else
- static const String platform = "unknown";
-#endif
-
- JSRetainPtr<JSStringRef> platformString(Adopt, JSStringCreateWithCharacters(platform.characters(), platform.length()));
- JSValueRef platformValue = JSValueMakeString(ctx, platformString.get());
-
- return platformValue;
-}
-
-static JSValueRef moveByUnrestricted(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* /*exception*/)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- if (argumentCount < 2)
- return JSValueMakeUndefined(ctx);
-
- controller->moveWindowBy(narrowPrecisionToFloat(JSValueToNumber(ctx, arguments[0], 0)), narrowPrecisionToFloat(JSValueToNumber(ctx, arguments[1], 0)));
-
- return JSValueMakeUndefined(ctx);
-}
-
-#pragma mark -
-#pragma mark InspectorController Class
-
-InspectorController::InspectorController(Page* page, InspectorClient* client)
- : m_inspectedPage(page)
- , m_client(client)
- , m_page(0)
- , m_scriptObject(0)
- , m_controllerScriptObject(0)
- , m_scriptContext(0)
- , m_windowVisible(false)
- , m_showAfterVisible(FocusedNodeDocumentPanel)
- , m_nextIdentifier(-2)
-{
- ASSERT_ARG(page, page);
- ASSERT_ARG(client, client);
-}
-
-InspectorController::~InspectorController()
-{
- m_client->inspectorDestroyed();
-
- if (m_scriptContext) {
- JSObjectRef global = JSContextGetGlobalObject(m_scriptContext);
- JSRetainPtr<JSStringRef> controllerProperty(Adopt, JSStringCreateWithUTF8CString("InspectorController"));
- JSObjectRef controller = JSValueToObject(m_scriptContext, JSObjectGetProperty(m_scriptContext, global, controllerProperty.get(), 0), 0);
- if (controller)
- JSObjectSetPrivate(controller, 0);
- }
-
- if (m_page)
- m_page->setParentInspectorController(0);
-
- deleteAllValues(m_frameResources);
- deleteAllValues(m_consoleMessages);
-}
-
-bool InspectorController::enabled() const
-{
- return m_inspectedPage->settings()->developerExtrasEnabled();
-}
-
-String InspectorController::localizedStringsURL()
-{
- if (!enabled())
- return String();
- return m_client->localizedStringsURL();
-}
-
-// Trying to inspect something in a frame with JavaScript disabled would later lead to
-// crashes trying to create JavaScript wrappers. Some day we could fix this issue, but
-// for now prevent crashes here by never targeting a node in such a frame.
-static bool canPassNodeToJavaScript(Node* node)
-{
- if (!node)
- return false;
- Frame* frame = node->document()->frame();
- return frame && frame->scriptProxy()->isEnabled();
-}
-
-void InspectorController::inspect(Node* node)
-{
- if (!canPassNodeToJavaScript(node) || !enabled())
- return;
-
- show();
-
- if (node->nodeType() != Node::ELEMENT_NODE && node->nodeType() != Node::DOCUMENT_NODE)
- node = node->parentNode();
- m_nodeToFocus = node;
-
- if (!m_scriptObject) {
- m_showAfterVisible = FocusedNodeDocumentPanel;
- return;
- }
-
- if (windowVisible())
- focusNode();
-}
-
-void InspectorController::focusNode()
-{
- if (!enabled())
- return;
-
- ASSERT(m_scriptContext);
- ASSERT(m_scriptObject);
- ASSERT(m_nodeToFocus);
-
- JSValueRef arg0;
-
- {
- KJS::JSLock lock;
- arg0 = toRef(toJS(toJS(m_scriptContext), m_nodeToFocus.get()));
- }
-
- m_nodeToFocus = 0;
-
- JSRetainPtr<JSStringRef> functionProperty(Adopt, JSStringCreateWithUTF8CString("updateFocusedNode"));
- JSObjectRef function = JSValueToObject(m_scriptContext, JSObjectGetProperty(m_scriptContext, m_scriptObject, functionProperty.get(), 0), 0);
- ASSERT(function);
-
- JSObjectCallAsFunction(m_scriptContext, function, m_scriptObject, 1, &arg0, 0);
-}
-
-void InspectorController::highlight(Node* node)
-{
- if (!enabled())
- return;
- ASSERT_ARG(node, node);
- m_highlightedNode = node;
- m_client->highlight(node);
-}
-
-void InspectorController::hideHighlight()
-{
- if (!enabled())
- return;
- m_client->hideHighlight();
-}
-
-bool InspectorController::windowVisible()
-{
- return m_windowVisible;
-}
-
-void InspectorController::setWindowVisible(bool visible)
-{
- if (visible == m_windowVisible)
- return;
-
- m_windowVisible = visible;
-
- if (!m_scriptContext || !m_scriptObject)
- return;
-
- if (m_windowVisible) {
- populateScriptResources();
- if (m_nodeToFocus)
- focusNode();
- if (m_showAfterVisible == ConsolePanel)
- showConsole();
- else if (m_showAfterVisible == TimelinePanel)
- showTimeline();
- } else {
- clearScriptResources();
- clearScriptConsoleMessages();
- clearDatabaseScriptResources();
- clearNetworkTimeline();
- }
-
- m_showAfterVisible = FocusedNodeDocumentPanel;
-}
-
-void InspectorController::addMessageToConsole(MessageSource source, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceID)
-{
- if (!enabled())
- return;
-
- ConsoleMessage* consoleMessage = new ConsoleMessage(source, level, message, lineNumber, sourceID);
- m_consoleMessages.append(consoleMessage);
-
- if (windowVisible())
- addScriptConsoleMessage(consoleMessage);
-}
-
-void InspectorController::attachWindow()
-{
- if (!enabled())
- return;
- m_client->attachWindow();
-}
-
-void InspectorController::detachWindow()
-{
- if (!enabled())
- return;
- m_client->detachWindow();
-}
-
-void InspectorController::windowScriptObjectAvailable()
-{
- if (!m_page || !enabled())
- return;
-
- m_scriptContext = toRef(m_page->mainFrame()->scriptProxy()->globalObject()->globalExec());
-
- JSObjectRef global = JSContextGetGlobalObject(m_scriptContext);
- ASSERT(global);
-
- static JSStaticFunction staticFunctions[] = {
- { "addSourceToFrame", addSourceToFrame, kJSPropertyAttributeNone },
- { "getResourceDocumentNode", getResourceDocumentNode, kJSPropertyAttributeNone },
- { "highlightDOMNode", highlightDOMNode, kJSPropertyAttributeNone },
- { "hideDOMNodeHighlight", hideDOMNodeHighlight, kJSPropertyAttributeNone },
- { "loaded", loaded, kJSPropertyAttributeNone },
- { "windowUnloading", unloading, kJSPropertyAttributeNone },
- { "attach", attach, kJSPropertyAttributeNone },
- { "detach", detach, kJSPropertyAttributeNone },
- { "search", search, kJSPropertyAttributeNone },
-#if ENABLE(DATABASE)
- { "databaseTableNames", databaseTableNames, kJSPropertyAttributeNone },
-#endif
- { "inspectedWindow", inspectedWindow, kJSPropertyAttributeNone },
- { "localizedStringsURL", localizedStrings, kJSPropertyAttributeNone },
- { "platform", platform, kJSPropertyAttributeNone },
- { "moveByUnrestricted", moveByUnrestricted, kJSPropertyAttributeNone },
- { 0, 0, 0 }
- };
-
- JSClassDefinition inspectorControllerDefinition = {
- 0, kJSClassAttributeNone, "InspectorController", 0, 0, staticFunctions,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- };
-
- JSClassRef controllerClass = JSClassCreate(&inspectorControllerDefinition);
- ASSERT(controllerClass);
-
- m_controllerScriptObject = JSObjectMake(m_scriptContext, controllerClass, reinterpret_cast<void*>(this));
- ASSERT(m_controllerScriptObject);
-
- JSRetainPtr<JSStringRef> controllerObjectString(Adopt, JSStringCreateWithUTF8CString("InspectorController"));
- JSObjectSetProperty(m_scriptContext, global, controllerObjectString.get(), m_controllerScriptObject, kJSPropertyAttributeNone, 0);
-}
-
-void InspectorController::scriptObjectReady()
-{
- ASSERT(m_scriptContext);
- if (!m_scriptContext)
- return;
-
- JSObjectRef global = JSContextGetGlobalObject(m_scriptContext);
- ASSERT(global);
-
- JSRetainPtr<JSStringRef> inspectorString(Adopt, JSStringCreateWithUTF8CString("WebInspector"));
- JSValueRef inspectorValue = JSObjectGetProperty(m_scriptContext, global, inspectorString.get(), 0);
-
- ASSERT(inspectorValue);
- if (!inspectorValue)
- return;
-
- m_scriptObject = JSValueToObject(m_scriptContext, inspectorValue, 0);
- ASSERT(m_scriptObject);
-
- JSValueProtect(m_scriptContext, m_scriptObject);
-
- // Make sure our window is visible now that the page loaded
- m_client->showWindow();
-}
-
-void InspectorController::show()
-{
- if (!enabled())
- return;
-
- if (!m_page) {
- m_page = m_client->createPage();
- if (!m_page)
- return;
- m_page->setParentInspectorController(this);
-
- // m_client->showWindow() will be called after the page loads in scriptObjectReady()
- return;
- }
-
- m_client->showWindow();
-}
-
-void InspectorController::showConsole()
-{
- if (!enabled())
- return;
-
- show();
-
- if (!m_scriptObject) {
- m_showAfterVisible = ConsolePanel;
- return;
- }
-
- callSimpleFunction(m_scriptContext, m_scriptObject, "showConsole");
-}
-
-void InspectorController::showTimeline()
-{
- if (!enabled())
- return;
-
- show();
-
- if (!m_scriptObject) {
- m_showAfterVisible = TimelinePanel;
- return;
- }
-
- callSimpleFunction(m_scriptContext, m_scriptObject, "showTimeline");
-}
-
-void InspectorController::close()
-{
- if (!enabled())
- return;
-
- m_client->closeWindow();
- if (m_page)
- m_page->setParentInspectorController(0);
-
- ASSERT(m_scriptContext && m_scriptObject);
- JSValueUnprotect(m_scriptContext, m_scriptObject);
-
- m_page = 0;
- m_scriptObject = 0;
- m_scriptContext = 0;
-}
-
-static void addHeaders(JSContextRef context, JSObjectRef object, const HTTPHeaderMap& headers)
-{
- ASSERT_ARG(context, context);
- ASSERT_ARG(object, object);
-
- HTTPHeaderMap::const_iterator end = headers.end();
- for (HTTPHeaderMap::const_iterator it = headers.begin(); it != end; ++it) {
- JSRetainPtr<JSStringRef> field(Adopt, JSStringCreateWithCharacters(it->first.characters(), it->first.length()));
- JSRetainPtr<JSStringRef> valueString(Adopt, JSStringCreateWithCharacters(it->second.characters(), it->second.length()));
- JSValueRef value = JSValueMakeString(context, valueString.get());
- JSObjectSetProperty(context, object, field.get(), value, kJSPropertyAttributeNone, 0);
- }
-}
-
-static JSObjectRef scriptObjectForRequest(JSContextRef context, const InspectorResource* resource)
-{
- ASSERT_ARG(context, context);
-
- JSObjectRef object = JSObjectMake(context, 0, 0);
- addHeaders(context, object, resource->requestHeaderFields);
-
- return object;
-}
-
-static JSObjectRef scriptObjectForResponse(JSContextRef context, const InspectorResource* resource)
-{
- ASSERT_ARG(context, context);
-
- JSObjectRef object = JSObjectMake(context, 0, 0);
- addHeaders(context, object, resource->responseHeaderFields);
-
- return object;
-}
-
-JSObjectRef InspectorController::addScriptResource(InspectorResource* resource)
-{
- ASSERT_ARG(resource, resource);
-
- ASSERT(m_scriptContext);
- ASSERT(m_scriptObject);
- if (!m_scriptContext || !m_scriptObject)
- return 0;
-
- if (!resource->scriptObject) {
- JSRetainPtr<JSStringRef> resourceString(Adopt, JSStringCreateWithUTF8CString("Resource"));
- JSObjectRef resourceConstructor = JSValueToObject(m_scriptContext, JSObjectGetProperty(m_scriptContext, m_scriptObject, resourceString.get(), 0), 0);
-
- String urlString = resource->requestURL.string();
- JSRetainPtr<JSStringRef> url(Adopt, JSStringCreateWithCharacters(urlString.characters(), urlString.length()));
- JSValueRef urlValue = JSValueMakeString(m_scriptContext, url.get());
-
- urlString = resource->requestURL.host();
- JSRetainPtr<JSStringRef> domain(Adopt, JSStringCreateWithCharacters(urlString.characters(), urlString.length()));
- JSValueRef domainValue = JSValueMakeString(m_scriptContext, domain.get());
-
- urlString = resource->requestURL.path();
- JSRetainPtr<JSStringRef> path(Adopt, JSStringCreateWithCharacters(urlString.characters(), urlString.length()));
- JSValueRef pathValue = JSValueMakeString(m_scriptContext, path.get());
-
- urlString = resource->requestURL.lastPathComponent();
- JSRetainPtr<JSStringRef> lastPathComponent(Adopt, JSStringCreateWithCharacters(urlString.characters(), urlString.length()));
- JSValueRef lastPathComponentValue = JSValueMakeString(m_scriptContext, lastPathComponent.get());
-
- JSValueRef identifier = JSValueMakeNumber(m_scriptContext, resource->identifier);
- JSValueRef mainResource = JSValueMakeBoolean(m_scriptContext, m_mainResource == resource);
- JSValueRef cached = JSValueMakeBoolean(m_scriptContext, resource->cached);
-
- JSValueRef arguments[] = { scriptObjectForRequest(m_scriptContext, resource), urlValue, domainValue, pathValue, lastPathComponentValue, identifier, mainResource, cached };
- JSObjectRef result = JSObjectCallAsConstructor(m_scriptContext, resourceConstructor, 8, arguments, 0);
- ASSERT(result);
-
- resource->setScriptObject(m_scriptContext, result);
- }
-
- JSRetainPtr<JSStringRef> addResourceString(Adopt, JSStringCreateWithUTF8CString("addResource"));
- JSObjectRef addResourceFunction = JSValueToObject(m_scriptContext, JSObjectGetProperty(m_scriptContext, m_scriptObject, addResourceString.get(), 0), 0);
-
- JSValueRef addArguments[] = { resource->scriptObject };
- JSObjectCallAsFunction(m_scriptContext, addResourceFunction, m_scriptObject, 1, addArguments, 0);
-
- return resource->scriptObject;
-}
-
-JSObjectRef InspectorController::addAndUpdateScriptResource(InspectorResource* resource)
-{
- ASSERT_ARG(resource, resource);
-
- JSObjectRef scriptResource = addScriptResource(resource);
- updateScriptResourceResponse(resource);
- updateScriptResource(resource, resource->length);
- updateScriptResource(resource, resource->startTime, resource->responseReceivedTime, resource->endTime);
- updateScriptResource(resource, resource->finished, resource->failed);
- return scriptResource;
-}
-
-void InspectorController::removeScriptResource(InspectorResource* resource)
-{
- ASSERT(m_scriptContext);
- ASSERT(m_scriptObject);
- if (!m_scriptContext || !m_scriptObject)
- return;
-
- ASSERT(resource);
- ASSERT(resource->scriptObject);
- if (!resource || !resource->scriptObject)
- return;
-
- JSRetainPtr<JSStringRef> removeResourceString(Adopt, JSStringCreateWithUTF8CString("removeResource"));
- JSObjectRef removeResourceFunction = JSValueToObject(m_scriptContext, JSObjectGetProperty(m_scriptContext, m_scriptObject, removeResourceString.get(), 0), 0);
-
- JSValueRef arguments[] = { resource->scriptObject };
- JSObjectCallAsFunction(m_scriptContext, removeResourceFunction, m_scriptObject, 1, arguments, 0);
-
- resource->setScriptObject(0, 0);
-}
-
-static void updateResourceRequest(InspectorResource* resource, const ResourceRequest& request)
-{
- resource->requestHeaderFields = request.httpHeaderFields();
- resource->requestURL = request.url();
-}
-
-static void updateResourceResponse(InspectorResource* resource, const ResourceResponse& response)
-{
- resource->expectedContentLength = response.expectedContentLength();
- resource->mimeType = response.mimeType();
- resource->responseHeaderFields = response.httpHeaderFields();
- resource->responseStatusCode = response.httpStatusCode();
- resource->suggestedFilename = response.suggestedFilename();
-}
-
-void InspectorController::updateScriptResourceRequest(InspectorResource* resource)
-{
- ASSERT(resource->scriptObject);
- ASSERT(m_scriptContext);
- if (!resource->scriptObject || !m_scriptContext)
- return;
-
- String urlString = resource->requestURL.string();
- JSRetainPtr<JSStringRef> url(Adopt, JSStringCreateWithCharacters(urlString.characters(), urlString.length()));
- JSValueRef urlValue = JSValueMakeString(m_scriptContext, url.get());
-
- urlString = resource->requestURL.host();
- JSRetainPtr<JSStringRef> domain(Adopt, JSStringCreateWithCharacters(urlString.characters(), urlString.length()));
- JSValueRef domainValue = JSValueMakeString(m_scriptContext, domain.get());
-
- urlString = resource->requestURL.path();
- JSRetainPtr<JSStringRef> path(Adopt, JSStringCreateWithCharacters(urlString.characters(), urlString.length()));
- JSValueRef pathValue = JSValueMakeString(m_scriptContext, path.get());
-
- urlString = resource->requestURL.lastPathComponent();
- JSRetainPtr<JSStringRef> lastPathComponent(Adopt, JSStringCreateWithCharacters(urlString.characters(), urlString.length()));
- JSValueRef lastPathComponentValue = JSValueMakeString(m_scriptContext, lastPathComponent.get());
-
- JSValueRef mainResourceValue = JSValueMakeBoolean(m_scriptContext, m_mainResource == resource);
-
- JSRetainPtr<JSStringRef> propertyName(Adopt, JSStringCreateWithUTF8CString("url"));
- JSObjectSetProperty(m_scriptContext, resource->scriptObject, propertyName.get(), urlValue, kJSPropertyAttributeNone, 0);
-
- propertyName.adopt(JSStringCreateWithUTF8CString("domain"));
- JSObjectSetProperty(m_scriptContext, resource->scriptObject, propertyName.get(), domainValue, kJSPropertyAttributeNone, 0);
-
- propertyName.adopt(JSStringCreateWithUTF8CString("path"));
- JSObjectSetProperty(m_scriptContext, resource->scriptObject, propertyName.get(), pathValue, kJSPropertyAttributeNone, 0);
-
- propertyName.adopt(JSStringCreateWithUTF8CString("lastPathComponent"));
- JSObjectSetProperty(m_scriptContext, resource->scriptObject, propertyName.get(), lastPathComponentValue, kJSPropertyAttributeNone, 0);
-
- propertyName.adopt(JSStringCreateWithUTF8CString("requestHeaders"));
- JSObjectSetProperty(m_scriptContext, resource->scriptObject, propertyName.get(), scriptObjectForRequest(m_scriptContext, resource), kJSPropertyAttributeNone, 0);
-
- propertyName.adopt(JSStringCreateWithUTF8CString("mainResource"));
- JSObjectSetProperty(m_scriptContext, resource->scriptObject, propertyName.get(), mainResourceValue, kJSPropertyAttributeNone, 0);
-}
-
-void InspectorController::updateScriptResourceResponse(InspectorResource* resource)
-{
- ASSERT(resource->scriptObject);
- ASSERT(m_scriptContext);
- if (!resource->scriptObject || !m_scriptContext)
- return;
-
- JSRetainPtr<JSStringRef> mimeType(Adopt, JSStringCreateWithCharacters(resource->mimeType.characters(), resource->mimeType.length()));
- JSValueRef mimeTypeValue = JSValueMakeString(m_scriptContext, mimeType.get());
-
- JSRetainPtr<JSStringRef> suggestedFilename(Adopt, JSStringCreateWithCharacters(resource->suggestedFilename.characters(), resource->suggestedFilename.length()));
- JSValueRef suggestedFilenameValue = JSValueMakeString(m_scriptContext, suggestedFilename.get());
-
- JSValueRef expectedContentLengthValue = JSValueMakeNumber(m_scriptContext, static_cast<double>(resource->expectedContentLength));
- JSValueRef statusCodeValue = JSValueMakeNumber(m_scriptContext, resource->responseStatusCode);
-
- JSRetainPtr<JSStringRef> propertyName(Adopt, JSStringCreateWithUTF8CString("mimeType"));
- JSObjectSetProperty(m_scriptContext, resource->scriptObject, propertyName.get(), mimeTypeValue, kJSPropertyAttributeNone, 0);
-
- propertyName.adopt(JSStringCreateWithUTF8CString("suggestedFilename"));
- JSObjectSetProperty(m_scriptContext, resource->scriptObject, propertyName.get(), suggestedFilenameValue, kJSPropertyAttributeNone, 0);
-
- propertyName.adopt(JSStringCreateWithUTF8CString("expectedContentLength"));
- JSObjectSetProperty(m_scriptContext, resource->scriptObject, propertyName.get(), expectedContentLengthValue, kJSPropertyAttributeNone, 0);
-
- propertyName.adopt(JSStringCreateWithUTF8CString("statusCode"));
- JSObjectSetProperty(m_scriptContext, resource->scriptObject, propertyName.get(), statusCodeValue, kJSPropertyAttributeNone, 0);
-
- propertyName.adopt(JSStringCreateWithUTF8CString("responseHeaders"));
- JSObjectSetProperty(m_scriptContext, resource->scriptObject, propertyName.get(), scriptObjectForResponse(m_scriptContext, resource), kJSPropertyAttributeNone, 0);
-
- JSValueRef typeValue = JSValueMakeNumber(m_scriptContext, resource->type());
- propertyName.adopt(JSStringCreateWithUTF8CString("type"));
- JSObjectSetProperty(m_scriptContext, resource->scriptObject, propertyName.get(), typeValue, kJSPropertyAttributeNone, 0);
-}
-
-void InspectorController::updateScriptResource(InspectorResource* resource, int length)
-{
- ASSERT(resource->scriptObject);
- ASSERT(m_scriptContext);
- if (!resource->scriptObject || !m_scriptContext)
- return;
-
- JSValueRef lengthValue = JSValueMakeNumber(m_scriptContext, length);
-
- JSRetainPtr<JSStringRef> propertyName(Adopt, JSStringCreateWithUTF8CString("contentLength"));
- JSObjectSetProperty(m_scriptContext, resource->scriptObject, propertyName.get(), lengthValue, kJSPropertyAttributeNone, 0);
-}
-
-void InspectorController::updateScriptResource(InspectorResource* resource, bool finished, bool failed)
-{
- ASSERT(resource->scriptObject);
- ASSERT(m_scriptContext);
- if (!resource->scriptObject || !m_scriptContext)
- return;
-
- JSValueRef failedValue = JSValueMakeBoolean(m_scriptContext, failed);
- JSValueRef finishedValue = JSValueMakeBoolean(m_scriptContext, finished);
-
- JSRetainPtr<JSStringRef> propertyName(Adopt, JSStringCreateWithUTF8CString("failed"));
- JSObjectSetProperty(m_scriptContext, resource->scriptObject, propertyName.get(), failedValue, kJSPropertyAttributeNone, 0);
-
- propertyName.adopt(JSStringCreateWithUTF8CString("finished"));
- JSObjectSetProperty(m_scriptContext, resource->scriptObject, propertyName.get(), finishedValue, kJSPropertyAttributeNone, 0);
-}
-
-void InspectorController::updateScriptResource(InspectorResource* resource, double startTime, double responseReceivedTime, double endTime)
-{
- ASSERT(resource->scriptObject);
- ASSERT(m_scriptContext);
- if (!resource->scriptObject || !m_scriptContext)
- return;
-
- JSValueRef startTimeValue = JSValueMakeNumber(m_scriptContext, startTime);
- JSValueRef responseReceivedTimeValue = JSValueMakeNumber(m_scriptContext, responseReceivedTime);
- JSValueRef endTimeValue = JSValueMakeNumber(m_scriptContext, endTime);
-
- JSRetainPtr<JSStringRef> propertyName(Adopt, JSStringCreateWithUTF8CString("startTime"));
- JSObjectSetProperty(m_scriptContext, resource->scriptObject, propertyName.get(), startTimeValue, kJSPropertyAttributeNone, 0);
-
- propertyName.adopt(JSStringCreateWithUTF8CString("responseReceivedTime"));
- JSObjectSetProperty(m_scriptContext, resource->scriptObject, propertyName.get(), responseReceivedTimeValue, kJSPropertyAttributeNone, 0);
-
- propertyName.adopt(JSStringCreateWithUTF8CString("endTime"));
- JSObjectSetProperty(m_scriptContext, resource->scriptObject, propertyName.get(), endTimeValue, kJSPropertyAttributeNone, 0);
-}
-
-void InspectorController::populateScriptResources()
-{
- ASSERT(m_scriptContext);
- if (!m_scriptContext)
- return;
-
- clearScriptResources();
- clearScriptConsoleMessages();
- clearDatabaseScriptResources();
- clearNetworkTimeline();
-
- ResourcesMap::iterator resourcesEnd = m_resources.end();
- for (ResourcesMap::iterator it = m_resources.begin(); it != resourcesEnd; ++it)
- addAndUpdateScriptResource(it->second.get());
-
- unsigned messageCount = m_consoleMessages.size();
- for (unsigned i = 0; i < messageCount; ++i)
- addScriptConsoleMessage(m_consoleMessages[i]);
-
-#if ENABLE(DATABASE)
- DatabaseResourcesSet::iterator databasesEnd = m_databaseResources.end();
- for (DatabaseResourcesSet::iterator it = m_databaseResources.begin(); it != databasesEnd; ++it)
- addDatabaseScriptResource((*it).get());
-#endif
-}
-
-#if ENABLE(DATABASE)
-JSObjectRef InspectorController::addDatabaseScriptResource(InspectorDatabaseResource* resource)
-{
- ASSERT_ARG(resource, resource);
-
- if (resource->scriptObject)
- return resource->scriptObject;
-
- ASSERT(m_scriptContext);
- ASSERT(m_scriptObject);
- if (!m_scriptContext || !m_scriptObject)
- return 0;
-
- JSRetainPtr<JSStringRef> databaseString(Adopt, JSStringCreateWithUTF8CString("Database"));
- JSObjectRef databaseConstructor = JSValueToObject(m_scriptContext, JSObjectGetProperty(m_scriptContext, m_scriptObject, databaseString.get(), 0), 0);
-
- JSValueRef database;
-
- {
- KJS::JSLock lock;
- database = toRef(toJS(toJS(m_scriptContext), resource->database.get()));
- }
-
- JSRetainPtr<JSStringRef> domain(Adopt, JSStringCreateWithCharacters(resource->domain.characters(), resource->domain.length()));
- JSValueRef domainValue = JSValueMakeString(m_scriptContext, domain.get());
-
- JSRetainPtr<JSStringRef> name(Adopt, JSStringCreateWithCharacters(resource->name.characters(), resource->name.length()));
- JSValueRef nameValue = JSValueMakeString(m_scriptContext, name.get());
-
- JSRetainPtr<JSStringRef> version(Adopt, JSStringCreateWithCharacters(resource->version.characters(), resource->version.length()));
- JSValueRef versionValue = JSValueMakeString(m_scriptContext, version.get());
-
- JSValueRef arguments[] = { database, domainValue, nameValue, versionValue };
- JSObjectRef result = JSObjectCallAsConstructor(m_scriptContext, databaseConstructor, 4, arguments, 0);
-
- resource->setScriptObject(m_scriptContext, result);
-
- ASSERT(result);
-
- JSRetainPtr<JSStringRef> addResourceString(Adopt, JSStringCreateWithUTF8CString("addResource"));
- JSObjectRef addResourceFunction = JSValueToObject(m_scriptContext, JSObjectGetProperty(m_scriptContext, m_scriptObject, addResourceString.get(), 0), 0);
-
- JSValueRef addArguments[] = { result };
- JSObjectCallAsFunction(m_scriptContext, addResourceFunction, m_scriptObject, 1, addArguments, 0);
-
- return result;
-}
-
-void InspectorController::removeDatabaseScriptResource(InspectorDatabaseResource* resource)
-{
- ASSERT(m_scriptContext);
- ASSERT(m_scriptObject);
- if (!m_scriptContext || !m_scriptObject)
- return;
-
- ASSERT(resource);
- ASSERT(resource->scriptObject);
- if (!resource || !resource->scriptObject)
- return;
-
- JSRetainPtr<JSStringRef> removeResourceString(Adopt, JSStringCreateWithUTF8CString("removeResource"));
- JSObjectRef removeResourceFunction = JSValueToObject(m_scriptContext, JSObjectGetProperty(m_scriptContext, m_scriptObject, removeResourceString.get(), 0), 0);
-
- JSValueRef arguments[] = { resource->scriptObject };
- JSObjectCallAsFunction(m_scriptContext, removeResourceFunction, m_scriptObject, 1, arguments, 0);
-
- resource->setScriptObject(0, 0);
-}
-#endif
-
-void InspectorController::addScriptConsoleMessage(const ConsoleMessage* message)
-{
- ASSERT_ARG(message, message);
-
- JSRetainPtr<JSStringRef> messageConstructorString(Adopt, JSStringCreateWithUTF8CString("ConsoleMessage"));
- JSObjectRef messageConstructor = JSValueToObject(m_scriptContext, JSObjectGetProperty(m_scriptContext, m_scriptObject, messageConstructorString.get(), 0), 0);
-
- JSRetainPtr<JSStringRef> addMessageString(Adopt, JSStringCreateWithUTF8CString("addMessageToConsole"));
- JSObjectRef addMessage = JSValueToObject(m_scriptContext, JSObjectGetProperty(m_scriptContext, m_scriptObject, addMessageString.get(), 0), 0);
-
- JSValueRef sourceValue = JSValueMakeNumber(m_scriptContext, message->source);
- JSValueRef levelValue = JSValueMakeNumber(m_scriptContext, message->level);
- JSRetainPtr<JSStringRef> messageString(Adopt, JSStringCreateWithCharacters(message->message.characters(), message->message.length()));
- JSValueRef messageValue = JSValueMakeString(m_scriptContext, messageString.get());
- JSValueRef lineValue = JSValueMakeNumber(m_scriptContext, message->line);
- JSRetainPtr<JSStringRef> urlString(Adopt, JSStringCreateWithCharacters(message->url.characters(), message->url.length()));
- JSValueRef urlValue = JSValueMakeString(m_scriptContext, urlString.get());
-
- JSValueRef args[] = { sourceValue, levelValue, messageValue, lineValue, urlValue };
- JSObjectRef messageObject = JSObjectCallAsConstructor(m_scriptContext, messageConstructor, 5, args, 0);
-
- JSObjectCallAsFunction(m_scriptContext, addMessage, m_scriptObject, 1, &messageObject, 0);
-}
-
-void InspectorController::clearScriptResources()
-{
- if (!m_scriptContext || !m_scriptObject)
- return;
-
- ResourcesMap::iterator resourcesEnd = m_resources.end();
- for (ResourcesMap::iterator it = m_resources.begin(); it != resourcesEnd; ++it) {
- InspectorResource* resource = it->second.get();
- resource->setScriptObject(0, 0);
- }
-
- callSimpleFunction(m_scriptContext, m_scriptObject, "clearResources");
-}
-
-void InspectorController::clearDatabaseScriptResources()
-{
-#if ENABLE(DATABASE)
- if (!m_scriptContext || !m_scriptObject)
- return;
-
- DatabaseResourcesSet::iterator databasesEnd = m_databaseResources.end();
- for (DatabaseResourcesSet::iterator it = m_databaseResources.begin(); it != databasesEnd; ++it) {
- InspectorDatabaseResource* resource = (*it).get();
- resource->setScriptObject(0, 0);
- }
-
- callSimpleFunction(m_scriptContext, m_scriptObject, "clearDatabaseResources");
-#endif
-}
-
-void InspectorController::clearScriptConsoleMessages()
-{
- if (!m_scriptContext || !m_scriptObject)
- return;
-
- callSimpleFunction(m_scriptContext, m_scriptObject, "clearConsoleMessages");
-}
-
-void InspectorController::clearNetworkTimeline()
-{
- if (!m_scriptContext || !m_scriptObject)
- return;
-
- callSimpleFunction(m_scriptContext, m_scriptObject, "clearNetworkTimeline");
-}
-
-void InspectorController::pruneResources(ResourcesMap* resourceMap, DocumentLoader* loaderToKeep)
-{
- ASSERT_ARG(resourceMap, resourceMap);
-
- ResourcesMap mapCopy(*resourceMap);
- ResourcesMap::iterator end = mapCopy.end();
- for (ResourcesMap::iterator it = mapCopy.begin(); it != end; ++it) {
- InspectorResource* resource = (*it).second.get();
- if (resource == m_mainResource)
- continue;
-
- if (!loaderToKeep || resource->loader != loaderToKeep) {
- removeResource(resource);
- if (windowVisible() && resource->scriptObject)
- removeScriptResource(resource);
- }
- }
-}
-
-void InspectorController::didCommitLoad(DocumentLoader* loader)
-{
- if (!enabled())
- return;
-
- if (loader->frame() == m_inspectedPage->mainFrame()) {
- m_client->inspectedURLChanged(loader->url().string());
-
- deleteAllValues(m_consoleMessages);
- m_consoleMessages.clear();
-
-#if ENABLE(DATABASE)
- m_databaseResources.clear();
-#endif
-
- if (windowVisible()) {
- clearScriptConsoleMessages();
-#if ENABLE(DATABASE)
- clearDatabaseScriptResources();
-#endif
- clearNetworkTimeline();
-
- if (!loader->isLoadingFromCachedPage()) {
- ASSERT(m_mainResource && m_mainResource->loader == loader);
- // We don't add the main resource until its load is committed. This is
- // needed to keep the load for a user-entered URL from showing up in the
- // list of resources for the page they are navigating away from.
- addAndUpdateScriptResource(m_mainResource.get());
- } else {
- // Pages loaded from the page cache are committed before
- // m_mainResource is the right resource for this load, so we
- // clear it here. It will be re-assigned in
- // identifierForInitialRequest.
- m_mainResource = 0;
- }
- }
- }
-
- for (Frame* frame = loader->frame(); frame; frame = frame->tree()->traverseNext(loader->frame()))
- if (ResourcesMap* resourceMap = m_frameResources.get(frame))
- pruneResources(resourceMap, loader);
-}
-
-void InspectorController::frameDetachedFromParent(Frame* frame)
-{
- if (!enabled())
- return;
- if (ResourcesMap* resourceMap = m_frameResources.get(frame))
- removeAllResources(resourceMap);
-}
-
-void InspectorController::addResource(InspectorResource* resource)
-{
- m_resources.set(resource->identifier, resource);
-
- Frame* frame = resource->frame.get();
- ResourcesMap* resourceMap = m_frameResources.get(frame);
- if (resourceMap)
- resourceMap->set(resource->identifier, resource);
- else {
- resourceMap = new ResourcesMap;
- resourceMap->set(resource->identifier, resource);
- m_frameResources.set(frame, resourceMap);
- }
-}
-
-void InspectorController::removeResource(InspectorResource* resource)
-{
- m_resources.remove(resource->identifier);
-
- Frame* frame = resource->frame.get();
- ResourcesMap* resourceMap = m_frameResources.get(frame);
- if (!resourceMap) {
- ASSERT_NOT_REACHED();
- return;
- }
-
- resourceMap->remove(resource->identifier);
- if (resourceMap->isEmpty()) {
- m_frameResources.remove(frame);
- delete resourceMap;
- }
-}
-
-void InspectorController::didLoadResourceFromMemoryCache(DocumentLoader* loader, const ResourceRequest& request, const ResourceResponse& response, int length)
-{
- if (!enabled())
- return;
-
- InspectorResource* resource = new InspectorResource(m_nextIdentifier--, loader, loader->frame());
- resource->finished = true;
-
- updateResourceRequest(resource, request);
- updateResourceResponse(resource, response);
-
- resource->length = length;
- resource->cached = true;
- resource->startTime = currentTime();
- resource->responseReceivedTime = resource->startTime;
- resource->endTime = resource->startTime;
-
- if (loader->frame() == m_inspectedPage->mainFrame() && request.url() == loader->requestURL())
- m_mainResource = resource;
-
- addResource(resource);
-
- if (windowVisible())
- addAndUpdateScriptResource(resource);
-}
-
-void InspectorController::identifierForInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request)
-{
- if (!enabled())
- return;
-
- InspectorResource* resource = new InspectorResource(identifier, loader, loader->frame());
-
- updateResourceRequest(resource, request);
-
- if (loader->frame() == m_inspectedPage->mainFrame() && request.url() == loader->requestURL())
- m_mainResource = resource;
-
- addResource(resource);
-
- if (windowVisible() && loader->isLoadingFromCachedPage() && resource == m_mainResource)
- addAndUpdateScriptResource(resource);
-}
-
-void InspectorController::willSendRequest(DocumentLoader* loader, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse)
-{
- if (!enabled())
- return;
-
- InspectorResource* resource = m_resources.get(identifier).get();
- if (!resource)
- return;
-
- resource->startTime = currentTime();
-
- if (!redirectResponse.isNull()) {
- updateResourceRequest(resource, request);
- updateResourceResponse(resource, redirectResponse);
- }
-
- if (resource != m_mainResource && windowVisible()) {
- if (!resource->scriptObject)
- addScriptResource(resource);
- else
- updateScriptResourceRequest(resource);
-
- updateScriptResource(resource, resource->startTime, resource->responseReceivedTime, resource->endTime);
-
- if (!redirectResponse.isNull())
- updateScriptResourceResponse(resource);
- }
-}
-
-void InspectorController::didReceiveResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse& response)
-{
- if (!enabled())
- return;
-
- InspectorResource* resource = m_resources.get(identifier).get();
- if (!resource)
- return;
-
- updateResourceResponse(resource, response);
-
- resource->responseReceivedTime = currentTime();
-
- if (windowVisible() && resource->scriptObject) {
- updateScriptResourceResponse(resource);
- updateScriptResource(resource, resource->startTime, resource->responseReceivedTime, resource->endTime);
- }
-}
-
-void InspectorController::didReceiveContentLength(DocumentLoader*, unsigned long identifier, int lengthReceived)
-{
- if (!enabled())
- return;
-
- InspectorResource* resource = m_resources.get(identifier).get();
- if (!resource)
- return;
-
- resource->length += lengthReceived;
-
- if (windowVisible() && resource->scriptObject)
- updateScriptResource(resource, resource->length);
-}
-
-void InspectorController::didFinishLoading(DocumentLoader* loader, unsigned long identifier)
-{
- if (!enabled())
- return;
-
- RefPtr<InspectorResource> resource = m_resources.get(identifier);
- if (!resource)
- return;
-
- removeResource(resource.get());
-
- resource->finished = true;
- resource->endTime = currentTime();
-
- addResource(resource.get());
-
- if (windowVisible() && resource->scriptObject) {
- updateScriptResource(resource.get(), resource->startTime, resource->responseReceivedTime, resource->endTime);
- updateScriptResource(resource.get(), resource->finished);
- }
-}
-
-void InspectorController::didFailLoading(DocumentLoader* loader, unsigned long identifier, const ResourceError& /*error*/)
-{
- if (!enabled())
- return;
-
- RefPtr<InspectorResource> resource = m_resources.get(identifier);
- if (!resource)
- return;
-
- removeResource(resource.get());
-
- resource->finished = true;
- resource->failed = true;
- resource->endTime = currentTime();
-
- addResource(resource.get());
-
- if (windowVisible() && resource->scriptObject) {
- updateScriptResource(resource.get(), resource->startTime, resource->responseReceivedTime, resource->endTime);
- updateScriptResource(resource.get(), resource->finished, resource->failed);
- }
-}
-
-#if ENABLE(DATABASE)
-void InspectorController::didOpenDatabase(Database* database, const String& domain, const String& name, const String& version)
-{
- if (!enabled())
- return;
-
- InspectorDatabaseResource* resource = new InspectorDatabaseResource(database, domain, name, version);
-
- m_databaseResources.add(resource);
-
- if (windowVisible())
- addDatabaseScriptResource(resource);
-}
-#endif
-
-void InspectorController::moveWindowBy(float x, float y) const
-{
- if (!m_page || !enabled())
- return;
-
- FloatRect frameRect = m_page->chrome()->windowRect();
- frameRect.move(x, y);
- m_page->chrome()->setWindowRect(frameRect);
-}
-
-void InspectorController::drawNodeHighlight(GraphicsContext& context) const
-{
- static const Color overlayFillColor(0, 0, 0, 128);
- static const int outlineThickness = 1;
-
- if (!m_highlightedNode)
- return;
-
- RenderObject* renderer = m_highlightedNode->renderer();
- if (!renderer)
- return;
- IntRect nodeRect(renderer->absoluteBoundingBoxRect());
-
- Vector<IntRect> rects;
- if (renderer->isInline() || (renderer->isText() && !m_highlightedNode->isSVGElement()))
- renderer->addLineBoxRects(rects);
- if (rects.isEmpty())
- rects.append(nodeRect);
-
- FrameView* view = m_inspectedPage->mainFrame()->view();
- FloatRect overlayRect = static_cast<ScrollView*>(view)->visibleContentRect();
-
- if (!overlayRect.contains(nodeRect) && !nodeRect.contains(enclosingIntRect(overlayRect))) {
- Element* element;
- if (m_highlightedNode->isElementNode())
- element = static_cast<Element*>(m_highlightedNode.get());
- else
- element = static_cast<Element*>(m_highlightedNode->parent());
- element->scrollIntoViewIfNeeded();
- overlayRect = static_cast<ScrollView*>(view)->visibleContentRect();
- }
-
- context.translate(-overlayRect.x(), -overlayRect.y());
-
- // Draw translucent gray fill, out of which we will cut holes.
- context.fillRect(overlayRect, overlayFillColor);
-
- // Draw white frames around holes in first pass, so they will be erased in
- // places where holes overlap or abut.
- for (size_t i = 0; i < rects.size(); ++i) {
- IntRect rect = rects[i];
- rect.inflate(outlineThickness);
- context.fillRect(rect, Color::white);
- }
-
- // Erase holes in second pass.
- for (size_t i = 0; i < rects.size(); ++i)
- context.clearRect(rects[i]);
-}
-
-} // namespace WebCore
diff --git a/WebCore/page/InspectorController.h b/WebCore/page/InspectorController.h
deleted file mode 100644
index 46a5df3..0000000
--- a/WebCore/page/InspectorController.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 InspectorController_h
-#define InspectorController_h
-
-#include "Chrome.h"
-#include <JavaScriptCore/JSContextRef.h>
-#include <wtf/HashMap.h>
-#include <wtf/HashSet.h>
-#include <wtf/Vector.h>
-
-namespace WebCore {
-
-class Database;
-class DocumentLoader;
-class GraphicsContext;
-class InspectorClient;
-class Node;
-class ResourceResponse;
-class ResourceError;
-
-struct ConsoleMessage;
-struct InspectorDatabaseResource;
-struct InspectorResource;
-class ResourceRequest;
-
-class InspectorController {
-public:
- typedef HashMap<long long, RefPtr<InspectorResource> > ResourcesMap;
- typedef HashMap<RefPtr<Frame>, ResourcesMap*> FrameResourcesMap;
- typedef HashSet<RefPtr<InspectorDatabaseResource> > DatabaseResourcesSet;
-
- typedef enum {
- FocusedNodeDocumentPanel,
- ConsolePanel,
- TimelinePanel
- } SpecialPanels;
-
- InspectorController(Page*, InspectorClient*);
- ~InspectorController();
-
- void pageDestroyed() { m_page = 0; }
-
- bool enabled() const;
-
- Page* inspectedPage() const { return m_inspectedPage; }
-
- String localizedStringsURL();
-
- void inspect(Node*);
- void highlight(Node*);
- void hideHighlight();
-
- void show();
- void showConsole();
- void showTimeline();
- void close();
-
- bool windowVisible();
- void setWindowVisible(bool visible = true);
-
- void addMessageToConsole(MessageSource, MessageLevel, const String& message, unsigned lineNumber, const String& sourceID);
-
- void attachWindow();
- void detachWindow();
-
- JSContextRef scriptContext() const { return m_scriptContext; };
- void setScriptContext(JSContextRef context) { m_scriptContext = context; };
-
- void windowScriptObjectAvailable();
-
- void scriptObjectReady();
-
- void populateScriptResources();
- void clearScriptResources();
-
- void didCommitLoad(DocumentLoader*);
- void frameDetachedFromParent(Frame*);
-
- void didLoadResourceFromMemoryCache(DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int length);
-
- void identifierForInitialRequest(unsigned long identifier, DocumentLoader*, const ResourceRequest&);
- void willSendRequest(DocumentLoader*, unsigned long identifier, ResourceRequest&, const ResourceResponse& redirectResponse);
- void didReceiveResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse&);
- void didReceiveContentLength(DocumentLoader*, unsigned long identifier, int lengthReceived);
- void didFinishLoading(DocumentLoader*, unsigned long identifier);
- void didFailLoading(DocumentLoader*, unsigned long identifier, const ResourceError&);
-
-#if ENABLE(DATABASE)
- void didOpenDatabase(Database*, const String& domain, const String& name, const String& version);
-#endif
-
- const ResourcesMap& resources() const { return m_resources; }
-
- void moveWindowBy(float x, float y) const;
-
- void drawNodeHighlight(GraphicsContext&) const;
-
-private:
- void focusNode();
-
- void addScriptConsoleMessage(const ConsoleMessage*);
- void clearScriptConsoleMessages();
-
- void clearNetworkTimeline();
- void clearDatabaseScriptResources();
-
- void addResource(InspectorResource*);
- void removeResource(InspectorResource*);
-
- JSObjectRef addScriptResource(InspectorResource*);
- void removeScriptResource(InspectorResource*);
-
- JSObjectRef addAndUpdateScriptResource(InspectorResource*);
- void updateScriptResourceRequest(InspectorResource*);
- void updateScriptResourceResponse(InspectorResource*);
- void updateScriptResource(InspectorResource*, int length);
- void updateScriptResource(InspectorResource*, bool finished, bool failed = false);
- void updateScriptResource(InspectorResource*, double startTime, double responseReceivedTime, double endTime);
-
- void pruneResources(ResourcesMap*, DocumentLoader* loaderToKeep = 0);
- void removeAllResources(ResourcesMap* map) { pruneResources(map); }
-
-#if ENABLE(DATABASE)
- JSObjectRef addDatabaseScriptResource(InspectorDatabaseResource*);
- void removeDatabaseScriptResource(InspectorDatabaseResource*);
-#endif
-
- Page* m_inspectedPage;
- InspectorClient* m_client;
- Page* m_page;
- RefPtr<Node> m_nodeToFocus;
- RefPtr<InspectorResource> m_mainResource;
- ResourcesMap m_resources;
- FrameResourcesMap m_frameResources;
- Vector<ConsoleMessage*> m_consoleMessages;
-#if ENABLE(DATABASE)
- DatabaseResourcesSet m_databaseResources;
-#endif
- JSObjectRef m_scriptObject;
- JSObjectRef m_controllerScriptObject;
- JSContextRef m_scriptContext;
- bool m_windowVisible;
- SpecialPanels m_showAfterVisible;
- long long m_nextIdentifier;
- RefPtr<Node> m_highlightedNode;
-};
-
-} // namespace WebCore
-
-#endif // !defined(InspectorController_h)
diff --git a/WebCore/page/Location.cpp b/WebCore/page/Location.cpp
new file mode 100644
index 0000000..454aa78
--- /dev/null
+++ b/WebCore/page/Location.cpp
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Location.h"
+
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "KURL.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+Location::Location(Frame* frame)
+ : m_frame(frame)
+{
+}
+
+void Location::disconnectFrame()
+{
+ m_frame = 0;
+}
+
+inline const KURL& Location::url() const
+{
+ ASSERT(m_frame);
+ return m_frame->loader()->url();
+}
+
+String Location::href() const
+{
+ if (!m_frame)
+ return String();
+
+ const KURL& url = this->url();
+ return url.hasPath() ? url.prettyURL() : url.prettyURL() + "/";
+}
+
+String Location::protocol() const
+{
+ if (!m_frame)
+ return String();
+
+ return url().protocol() + ":";
+}
+
+String Location::host() const
+{
+ if (!m_frame)
+ return String();
+
+ // Note: this is the IE spec. The NS spec swaps the two, it says
+ // "The hostname property is the concatenation of the host and port properties, separated by a colon."
+ const KURL& url = this->url();
+ return url.port() ? url.host() + ":" + String::number((static_cast<int>(url.port()))) : url.host();
+}
+
+String Location::hostname() const
+{
+ if (!m_frame)
+ return String();
+
+ return url().host();
+}
+
+String Location::port() const
+{
+ if (!m_frame)
+ return String();
+
+ const KURL& url = this->url();
+ return url.port() ? String::number(static_cast<int>(url.port())) : "";
+}
+
+String Location::pathname() const
+{
+ if (!m_frame)
+ return String();
+
+ const KURL& url = this->url();
+ return url.path().isEmpty() ? "/" : url.path();
+}
+
+String Location::search() const
+{
+ if (!m_frame)
+ return String();
+
+ return url().query();
+}
+
+String Location::hash() const
+{
+ if (!m_frame)
+ return String();
+
+ const KURL& url = this->url();
+ return url.ref().isNull() ? "" : "#" + url.ref();
+}
+
+String Location::toString() const
+{
+ if (!m_frame)
+ return String();
+
+ const KURL& url = this->url();
+ return url.hasPath() ? url.prettyURL() : url.prettyURL() + "/";
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/Location.h b/WebCore/page/Location.h
new file mode 100644
index 0000000..065bde1
--- /dev/null
+++ b/WebCore/page/Location.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 Location_h
+#define Location_h
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+ class Frame;
+ class KURL;
+ class String;
+
+ class Location : public RefCounted<Location> {
+ public:
+ static PassRefPtr<Location> create(Frame* frame) { return adoptRef(new Location(frame)); }
+
+ Frame* frame() const { return m_frame; }
+ void disconnectFrame();
+
+ String href() const;
+
+ // URI decomposition attributes
+ String protocol() const;
+ String host() const;
+ String hostname() const;
+ String port() const;
+ String pathname() const;
+ String search() const;
+ String hash() const;
+
+ String toString() const;
+
+ private:
+ Location(Frame*);
+
+ const KURL& url() const;
+
+ Frame* m_frame;
+ };
+
+} // namespace WebCore
+
+#endif // Location_h
diff --git a/WebCore/page/Location.idl b/WebCore/page/Location.idl
new file mode 100644
index 0000000..91822ab
--- /dev/null
+++ b/WebCore/page/Location.idl
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module window {
+
+ interface [
+ CustomGetOwnPropertySlot,
+ CustomPutFunction,
+ CustomDeleteProperty,
+ CustomGetPropertyNames
+ ] Location {
+ attribute [CustomSetter] DOMString href;
+
+ [Custom] void assign(in DOMString url);
+ [Custom] void replace(in DOMString url);
+ [Custom] void reload();
+
+ // URI decomposition attributes
+ attribute [CustomSetter] DOMString protocol;
+ attribute [CustomSetter] DOMString host;
+ attribute [CustomSetter] DOMString hostname;
+ attribute [CustomSetter] DOMString port;
+ attribute [CustomSetter] DOMString pathname;
+ attribute [CustomSetter] DOMString search;
+ attribute [CustomSetter] DOMString hash;
+
+#if defined(LANGUAGE_JAVASCRIPT)
+ [DontEnum, Custom] DOMString toString();
+#endif
+ };
+
+}
diff --git a/WebCore/page/MouseEventWithHitTestResults.cpp b/WebCore/page/MouseEventWithHitTestResults.cpp
index d7596ce..0fc8c17 100644
--- a/WebCore/page/MouseEventWithHitTestResults.cpp
+++ b/WebCore/page/MouseEventWithHitTestResults.cpp
@@ -61,7 +61,7 @@ const IntPoint MouseEventWithHitTestResults::localPoint() const
return m_hitTestResult.localPoint();
}
-PlatformScrollbar* MouseEventWithHitTestResults::scrollbar() const
+Scrollbar* MouseEventWithHitTestResults::scrollbar() const
{
return m_hitTestResult.scrollbar();
}
diff --git a/WebCore/page/MouseEventWithHitTestResults.h b/WebCore/page/MouseEventWithHitTestResults.h
index 8392702..c4e419c 100644
--- a/WebCore/page/MouseEventWithHitTestResults.h
+++ b/WebCore/page/MouseEventWithHitTestResults.h
@@ -26,7 +26,7 @@
namespace WebCore {
-class PlatformScrollbar;
+class Scrollbar;
// FIXME: Why doesn't this class just cache a HitTestResult instead of copying all of HitTestResult's fields over?
class MouseEventWithHitTestResults {
@@ -37,8 +37,9 @@ public:
const HitTestResult& hitTestResult() const { return m_hitTestResult; }
Node* targetNode() const;
const IntPoint localPoint() const;
- PlatformScrollbar* scrollbar() const;
+ Scrollbar* scrollbar() const;
bool isOverLink() const;
+ bool isOverWidget() const { return m_hitTestResult.isOverWidget(); }
private:
PlatformMouseEvent m_event;
diff --git a/WebCore/page/Navigator.cpp b/WebCore/page/Navigator.cpp
new file mode 100644
index 0000000..6045062
--- /dev/null
+++ b/WebCore/page/Navigator.cpp
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2000 Harri Porten (porten@kde.org)
+ * Copyright (c) 2000 Daniel Molkentin (molkentin@kde.org)
+ * Copyright (c) 2000 Stefan Schimanski (schimmi@kde.org)
+ * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "Navigator.h"
+
+#include "CookieJar.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "FrameLoaderClient.h"
+#include "Geolocation.h"
+#include "Language.h"
+#include "MimeTypeArray.h"
+#include "NetworkStateNotifier.h"
+#include "Page.h"
+#include "PlatformString.h"
+#include "PluginArray.h"
+#include "PluginData.h"
+#include "ScriptController.h"
+#include "Settings.h"
+
+#ifndef WEBCORE_NAVIGATOR_PLATFORM
+#if PLATFORM(MAC) && PLATFORM(PPC)
+#define WEBCORE_NAVIGATOR_PLATFORM "MacPPC"
+#elif PLATFORM(MAC) && PLATFORM(X86)
+#define WEBCORE_NAVIGATOR_PLATFORM "MacIntel"
+#elif PLATFORM(WIN_OS)
+#define WEBCORE_NAVIGATOR_PLATFORM "Win32"
+#elif PLATFORM(ANDROID)
+#define WEBCORE_NAVIGATOR_PLATFORM "Android"
+#else
+#define WEBCORE_NAVIGATOR_PLATFORM ""
+#endif
+#endif // ifndef WEBCORE_NAVIGATOR_PLATFORM
+
+#ifndef WEBCORE_NAVIGATOR_PRODUCT
+#define WEBCORE_NAVIGATOR_PRODUCT "Gecko"
+#endif // ifndef WEBCORE_NAVIGATOR_PRODUCT
+
+#ifndef WEBCORE_NAVIGATOR_PRODUCT_SUB
+#define WEBCORE_NAVIGATOR_PRODUCT_SUB "20030107"
+#endif // ifndef WEBCORE_NAVIGATOR_PRODUCT_SUB
+
+#ifndef WEBCORE_NAVIGATOR_VENDOR
+#define WEBCORE_NAVIGATOR_VENDOR "Apple Computer, Inc."
+#endif // ifndef WEBCORE_NAVIGATOR_VENDOR
+
+#ifndef WEBCORE_NAVIGATOR_VENDOR_SUB
+#define WEBCORE_NAVIGATOR_VENDOR_SUB ""
+#endif // ifndef WEBCORE_NAVIGATOR_VENDOR_SUB
+
+
+namespace WebCore {
+
+Navigator::Navigator(Frame* frame)
+ : m_frame(frame)
+{
+}
+
+Navigator::~Navigator()
+{
+ disconnectFrame();
+}
+
+void Navigator::disconnectFrame()
+{
+ if (m_plugins) {
+ m_plugins->disconnectFrame();
+ m_plugins = 0;
+ }
+ if (m_mimeTypes) {
+ m_mimeTypes->disconnectFrame();
+ m_mimeTypes = 0;
+ }
+ if (m_geolocation) {
+ m_geolocation->disconnectFrame();
+ m_geolocation = 0;
+ }
+ m_frame = 0;
+}
+
+String Navigator::appCodeName() const
+{
+ return "Mozilla";
+}
+
+String Navigator::appName() const
+{
+ return "Netscape";
+}
+
+// If this function returns true, we need to hide the substring "4." that would otherwise
+// appear in the appVersion string. This is to avoid problems with old versions of a
+// library called OpenCube QuickMenu, which as of this writing is still being used on
+// sites such as nwa.com -- the library thinks Safari is Netscape 4 if we don't do this!
+static bool shouldHideFourDot(Frame* frame)
+{
+ const String* sourceURL = frame->script()->sourceURL();
+ if (!sourceURL)
+ return false;
+ if (!(sourceURL->endsWith("/dqm_script.js") || sourceURL->endsWith("/dqm_loader.js")))
+ return false;
+ Settings* settings = frame->settings();
+ if (!settings)
+ return false;
+ return settings->needsSiteSpecificQuirks();
+}
+
+String Navigator::appVersion() const
+{
+ if (!m_frame)
+ return String();
+ // Version is everything in the user agent string past the "Mozilla/" prefix.
+ const String& userAgent = m_frame->loader()->userAgent(m_frame->document() ? m_frame->document()->url() : KURL());
+ String appVersion = userAgent.substring(userAgent.find('/') + 1);
+ if (shouldHideFourDot(m_frame))
+ appVersion.replace("4.", "4_");
+ return appVersion;
+}
+
+String Navigator::language() const
+{
+ return defaultLanguage();
+}
+
+String Navigator::userAgent() const
+{
+ if (!m_frame)
+ return String();
+ return m_frame->loader()->userAgent(m_frame->document() ? m_frame->document()->url() : KURL());
+}
+
+String Navigator::platform() const
+{
+ return WEBCORE_NAVIGATOR_PLATFORM;
+}
+
+PluginArray* Navigator::plugins() const
+{
+ if (!m_plugins)
+ m_plugins = PluginArray::create(m_frame);
+ return m_plugins.get();
+}
+
+MimeTypeArray* Navigator::mimeTypes() const
+{
+ if (!m_mimeTypes)
+ m_mimeTypes = MimeTypeArray::create(m_frame);
+ return m_mimeTypes.get();
+}
+
+String Navigator::product() const
+{
+ return WEBCORE_NAVIGATOR_PRODUCT;
+}
+
+String Navigator::productSub() const
+{
+ return WEBCORE_NAVIGATOR_PRODUCT_SUB;
+}
+
+String Navigator::vendor() const
+{
+ return WEBCORE_NAVIGATOR_VENDOR;
+}
+
+String Navigator::vendorSub() const
+{
+ return WEBCORE_NAVIGATOR_VENDOR_SUB;
+}
+
+bool Navigator::cookieEnabled() const
+{
+ if (m_frame->page() && !m_frame->page()->cookieEnabled())
+ return false;
+
+ return cookiesEnabled(m_frame->document());
+}
+
+bool Navigator::javaEnabled() const
+{
+ if (!m_frame)
+ return false;
+ return m_frame->settings()->isJavaEnabled();
+}
+
+bool Navigator::onLine() const
+{
+ return networkStateNotifier().onLine();
+}
+
+Geolocation* Navigator::geolocation() const
+{
+ if (!m_geolocation)
+ m_geolocation = Geolocation::create(m_frame);
+ return m_geolocation.get();
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/Navigator.h b/WebCore/page/Navigator.h
new file mode 100644
index 0000000..ea5d780
--- /dev/null
+++ b/WebCore/page/Navigator.h
@@ -0,0 +1,74 @@
+/*
+ Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef Navigator_h
+#define Navigator_h
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+ class Frame;
+ class Geolocation;
+ class MimeTypeArray;
+ class PluginData;
+ class PluginArray;
+ class String;
+
+ class Navigator : public RefCounted<Navigator> {
+ public:
+ static PassRefPtr<Navigator> create(Frame* frame) { return adoptRef(new Navigator(frame)); }
+ ~Navigator();
+
+ void disconnectFrame();
+ Frame* frame() const { return m_frame; }
+
+ String appCodeName() const;
+ String appName() const;
+ String appVersion() const;
+ String language() const;
+ String userAgent() const;
+ String platform() const;
+ PluginArray* plugins() const;
+ MimeTypeArray* mimeTypes() const;
+ String product() const;
+ String productSub() const;
+ String vendor() const;
+ String vendorSub() const;
+ bool cookieEnabled() const;
+ bool javaEnabled() const;
+
+ bool onLine() const;
+ Geolocation* geolocation() const;
+ // This is used for GC marking.
+ Geolocation* optionalGeolocation() const { return m_geolocation.get(); }
+
+ private:
+ Navigator(Frame*);
+ Frame* m_frame;
+ mutable RefPtr<PluginArray> m_plugins;
+ mutable RefPtr<MimeTypeArray> m_mimeTypes;
+ mutable RefPtr<Geolocation> m_geolocation;
+ };
+
+}
+
+#endif
diff --git a/WebCore/page/Navigator.idl b/WebCore/page/Navigator.idl
new file mode 100644
index 0000000..905159c
--- /dev/null
+++ b/WebCore/page/Navigator.idl
@@ -0,0 +1,46 @@
+/*
+ Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+module window {
+
+ interface [
+ CustomMarkFunction
+ ] Navigator {
+ readonly attribute DOMString appCodeName;
+ readonly attribute DOMString appName;
+ readonly attribute [CustomGetter] DOMString appVersion;
+ readonly attribute DOMString language;
+ readonly attribute DOMString userAgent;
+ readonly attribute DOMString platform;
+ readonly attribute PluginArray plugins;
+ readonly attribute MimeTypeArray mimeTypes;
+ readonly attribute DOMString product;
+ readonly attribute DOMString productSub;
+ readonly attribute DOMString vendor;
+ readonly attribute DOMString vendorSub;
+ readonly attribute boolean cookieEnabled;
+ boolean javaEnabled();
+
+ readonly attribute boolean onLine;
+#if ENABLE_GEOLOCATION
+ readonly attribute Geolocation geolocation;
+#endif
+ };
+
+}
diff --git a/WebCore/page/Page.cpp b/WebCore/page/Page.cpp
index efae3bf..3c573d6 100644
--- a/WebCore/page/Page.cpp
+++ b/WebCore/page/Page.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -24,8 +24,11 @@
#include "ChromeClient.h"
#include "ContextMenuClient.h"
#include "ContextMenuController.h"
+#include "CSSStyleSelector.h"
#include "EditorClient.h"
+#include "DOMWindow.h"
#include "DragController.h"
+#include "EventNames.h"
#include "FileSystem.h"
#include "FocusController.h"
#include "Frame.h"
@@ -35,6 +38,10 @@
#include "HistoryItem.h"
#include "InspectorController.h"
#include "Logging.h"
+#include "NetworkStateNotifier.h"
+#include "Navigator.h"
+#include "PageGroup.h"
+#include "PluginData.h"
#include "ProgressTracker.h"
#include "RenderWidget.h"
#include "SelectionController.h"
@@ -42,32 +49,58 @@
#include "StringHash.h"
#include "TextResourceDecoder.h"
#include "Widget.h"
+#include "ScriptController.h"
#include <kjs/collector.h>
-#include <kjs/JSLock.h>
+#include <runtime/JSLock.h>
#include <wtf/HashMap.h>
+#include <wtf/RefCountedLeakCounter.h>
-using namespace KJS;
+#if ENABLE(DOM_STORAGE)
+#include "LocalStorage.h"
+#include "SessionStorage.h"
+#include "StorageArea.h"
+#endif
+
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+#include "JavaScriptDebugServer.h"
+#endif
namespace WebCore {
static HashSet<Page*>* allPages;
-static HashMap<String, HashSet<Page*>*>* frameNamespaces;
#ifndef NDEBUG
-WTFLogChannel LogWebCorePageLeaks = { 0x00000000, "", WTFLogChannelOn };
-
-struct PageCounter {
- static int count;
- ~PageCounter()
- {
- if (count)
- LOG(WebCorePageLeaks, "LEAK: %d Page\n", count);
- }
-};
-int PageCounter::count = 0;
-static PageCounter pageCounter;
+static WTF::RefCountedLeakCounter pageCounter("Page");
#endif
+static void networkStateChanged()
+{
+ Vector<RefPtr<Frame> > frames;
+
+ // Get all the frames of all the pages in all the page groups
+ HashSet<Page*>::iterator end = allPages->end();
+ for (HashSet<Page*>::iterator it = allPages->begin(); it != end; ++it) {
+ for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext())
+ frames.append(frame);
+ }
+
+ AtomicString eventName = networkStateNotifier().onLine() ? eventNames().onlineEvent : eventNames().offlineEvent;
+
+ for (unsigned i = 0; i < frames.size(); i++) {
+ Document* document = frames[i]->document();
+
+ if (!document)
+ continue;
+
+ // If the document does not have a body the event should be dispatched to the document
+ EventTargetNode* eventTarget = document->body();
+ if (!eventTarget)
+ eventTarget = document;
+
+ eventTarget->dispatchEventForType(eventName, false, false);
+ }
+}
+
Page::Page(ChromeClient* chromeClient, ContextMenuClient* contextMenuClient, EditorClient* editorClient, DragClient* dragClient, InspectorClient* inspectorClient)
: m_chrome(new Chrome(this, chromeClient))
, m_dragCaretController(new SelectionController(0, true))
@@ -77,26 +110,38 @@ Page::Page(ChromeClient* chromeClient, ContextMenuClient* contextMenuClient, Edi
, m_inspectorController(new InspectorController(this, inspectorClient))
, m_settings(new Settings(this))
, m_progress(new ProgressTracker)
- , m_backForwardList(new BackForwardList(this))
+ , m_backForwardList(BackForwardList::create(this))
, m_editorClient(editorClient)
, m_frameCount(0)
, m_tabKeyCyclesThroughElements(true)
, m_defersLoading(false)
, m_inLowQualityInterpolationMode(false)
+ , m_cookieEnabled(true)
, m_parentInspectorController(0)
, m_didLoadUserStyleSheet(false)
, m_userStyleSheetModificationTime(0)
+ , m_group(0)
+ , m_debugger(0)
+ , m_pendingUnloadEventCount(0)
+ , m_pendingBeforeUnloadEventCount(0)
+ , m_customHTMLTokenizerTimeDelay(-1)
+ , m_customHTMLTokenizerChunkSize(-1)
{
if (!allPages) {
allPages = new HashSet<Page*>;
- setFocusRingColorChangeFunction(setNeedsReapplyStyles);
+
+ networkStateNotifier().setNetworkStateChangedFunction(networkStateChanged);
}
ASSERT(!allPages->contains(this));
allPages->add(this);
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+ JavaScriptDebugServer::shared().pageCreated(this);
+#endif
+
#ifndef NDEBUG
- ++PageCounter::count;
+ pageCounter.increment();
#endif
}
@@ -106,15 +151,20 @@ Page::~Page()
setGroupName(String());
allPages->remove(this);
- for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext())
+ for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) {
+ if (frame->document())
+ frame->document()->documentWillBecomeInactive();
frame->pageDestroyed();
+ }
m_editorClient->pageDestroyed();
- m_inspectorController->pageDestroyed();
+ if (m_parentInspectorController)
+ m_parentInspectorController->pageDestroyed();
+ m_inspectorController->inspectedPageDestroyed();
m_backForwardList->close();
#ifndef NDEBUG
- --PageCounter::count;
+ pageCounter.decrement();
// Cancel keepAlive timers, to ensure we release all Frames before exiting.
// It's safe to do this because we prohibit closing a Page while JavaScript
@@ -165,37 +215,33 @@ void Page::goToItem(HistoryItem* item, FrameLoadType type)
void Page::setGroupName(const String& name)
{
- if (frameNamespaces && !m_groupName.isEmpty()) {
- HashSet<Page*>* oldNamespace = frameNamespaces->get(m_groupName);
- if (oldNamespace) {
- oldNamespace->remove(this);
- if (oldNamespace->isEmpty()) {
- frameNamespaces->remove(m_groupName);
- delete oldNamespace;
- }
- }
+ if (m_group && !m_group->name().isEmpty()) {
+ ASSERT(m_group != m_singlePageGroup.get());
+ ASSERT(!m_singlePageGroup);
+ m_group->removePage(this);
}
- m_groupName = name;
- if (!name.isEmpty()) {
- if (!frameNamespaces)
- frameNamespaces = new HashMap<String, HashSet<Page*>*>;
- HashSet<Page*>* newNamespace = frameNamespaces->get(name);
- if (!newNamespace) {
- newNamespace = new HashSet<Page*>;
- frameNamespaces->add(name, newNamespace);
- }
- newNamespace->add(this);
+
+ if (name.isEmpty())
+ m_group = 0;
+ else {
+ m_singlePageGroup.clear();
+ m_group = PageGroup::pageGroup(name);
+ m_group->addPage(this);
}
}
-const HashSet<Page*>* Page::frameNamespace() const
+const String& Page::groupName() const
{
- return (frameNamespaces && !m_groupName.isEmpty()) ? frameNamespaces->get(m_groupName) : 0;
+ static String nullString;
+ return m_group ? m_group->name() : nullString;
}
-const HashSet<Page*>* Page::frameNamespace(const String& groupName)
+void Page::initGroup()
{
- return (frameNamespaces && !groupName.isEmpty()) ? frameNamespaces->get(groupName) : 0;
+ ASSERT(!m_singlePageGroup);
+ ASSERT(!m_group);
+ m_singlePageGroup.set(new PageGroup(this));
+ m_group = m_singlePageGroup.get();
}
void Page::setNeedsReapplyStyles()
@@ -208,6 +254,38 @@ void Page::setNeedsReapplyStyles()
frame->setNeedsReapplyStyles();
}
+void Page::refreshPlugins(bool reload)
+{
+ if (!allPages)
+ return;
+
+ PluginData::refresh();
+
+ Vector<RefPtr<Frame> > framesNeedingReload;
+
+ HashSet<Page*>::iterator end = allPages->end();
+ for (HashSet<Page*>::iterator it = allPages->begin(); it != end; ++it) {
+ (*it)->m_pluginData = 0;
+
+ if (reload) {
+ for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
+ if (frame->loader()->containsPlugins())
+ framesNeedingReload.append(frame);
+ }
+ }
+ }
+
+ for (size_t i = 0; i < framesNeedingReload.size(); ++i)
+ framesNeedingReload[i]->loader()->reload();
+}
+
+PluginData* Page::pluginData() const
+{
+ if (!m_pluginData)
+ m_pluginData = PluginData::create(this);
+ return m_pluginData.get();
+}
+
static Frame* incrementFrame(Frame* curr, bool forward, bool wrapFlag)
{
return forward
@@ -225,7 +303,7 @@ bool Page::findString(const String& target, TextCaseSensitivity caseSensitivity,
do {
if (frame->findString(target, direction == FindDirectionForward, caseSensitivity == TextCaseSensitive, false, true)) {
if (frame != startFrame)
- startFrame->selectionController()->clear();
+ startFrame->selection()->clear();
focusController()->setFocusedFrame(frame);
return true;
}
@@ -234,7 +312,7 @@ bool Page::findString(const String& target, TextCaseSensitivity caseSensitivity,
// Search contents of startFrame, on the other side of the selection that we did earlier.
// We cheat a bit and just research with wrap on
- if (shouldWrap && !startFrame->selectionController()->isNone()) {
+ if (shouldWrap && !startFrame->selection()->isNone()) {
bool found = startFrame->findString(target, direction == FindDirectionForward, caseSensitivity == TextCaseSensitive, true, true);
focusController()->setFocusedFrame(frame);
return found;
@@ -275,7 +353,7 @@ void Page::unmarkAllTextMatches()
const Selection& Page::selection() const
{
- return focusController()->focusedOrMainFrame()->selectionController()->selection();
+ return focusController()->focusedOrMainFrame()->selection()->selection();
}
void Page::setDefersLoading(bool defers)
@@ -355,9 +433,150 @@ const String& Page::userStyleSheet() const
if (!data)
return m_userStyleSheet;
- m_userStyleSheet = TextResourceDecoder("text/css").decode(data->data(), data->size());
+ m_userStyleSheet = TextResourceDecoder::create("text/css")->decode(data->data(), data->size());
return m_userStyleSheet;
}
+void Page::removeAllVisitedLinks()
+{
+ if (!allPages)
+ return;
+ HashSet<PageGroup*> groups;
+ HashSet<Page*>::iterator pagesEnd = allPages->end();
+ for (HashSet<Page*>::iterator it = allPages->begin(); it != pagesEnd; ++it) {
+ if (PageGroup* group = (*it)->groupPtr())
+ groups.add(group);
+ }
+ HashSet<PageGroup*>::iterator groupsEnd = groups.end();
+ for (HashSet<PageGroup*>::iterator it = groups.begin(); it != groupsEnd; ++it)
+ (*it)->removeVisitedLinks();
+}
+
+void Page::allVisitedStateChanged(PageGroup* group)
+{
+ ASSERT(group);
+ ASSERT(allPages);
+ HashSet<Page*>::iterator pagesEnd = allPages->end();
+ for (HashSet<Page*>::iterator it = allPages->begin(); it != pagesEnd; ++it) {
+ Page* page = *it;
+ if (page->m_group != group)
+ continue;
+ for (Frame* frame = page->m_mainFrame.get(); frame; frame = frame->tree()->traverseNext()) {
+ if (CSSStyleSelector* styleSelector = frame->document()->styleSelector())
+ styleSelector->allVisitedStateChanged();
+ }
+ }
+}
+
+void Page::visitedStateChanged(PageGroup* group, unsigned visitedLinkHash)
+{
+ ASSERT(group);
+ ASSERT(allPages);
+ HashSet<Page*>::iterator pagesEnd = allPages->end();
+ for (HashSet<Page*>::iterator it = allPages->begin(); it != pagesEnd; ++it) {
+ Page* page = *it;
+ if (page->m_group != group)
+ continue;
+ for (Frame* frame = page->m_mainFrame.get(); frame; frame = frame->tree()->traverseNext()) {
+ if (CSSStyleSelector* styleSelector = frame->document()->styleSelector())
+ styleSelector->visitedStateChanged(visitedLinkHash);
+ }
+ }
+}
+
+void Page::setDebuggerForAllPages(JSC::Debugger* debugger)
+{
+ ASSERT(allPages);
+
+ HashSet<Page*>::iterator end = allPages->end();
+ for (HashSet<Page*>::iterator it = allPages->begin(); it != end; ++it)
+ (*it)->setDebugger(debugger);
+}
+
+void Page::setDebugger(JSC::Debugger* debugger)
+{
+ if (m_debugger == debugger)
+ return;
+
+ m_debugger = debugger;
+
+ for (Frame* frame = m_mainFrame.get(); frame; frame = frame->tree()->traverseNext())
+ frame->script()->attachDebugger(m_debugger);
+}
+
+#if ENABLE(DOM_STORAGE)
+SessionStorage* Page::sessionStorage(bool optionalCreate)
+{
+ if (!m_sessionStorage && optionalCreate)
+ m_sessionStorage = SessionStorage::create(this);
+
+ return m_sessionStorage.get();
+}
+
+void Page::setSessionStorage(PassRefPtr<SessionStorage> newStorage)
+{
+ ASSERT(newStorage->page() == this);
+ m_sessionStorage = newStorage;
+}
+#endif
+
+unsigned Page::pendingUnloadEventCount()
+{
+ return m_pendingUnloadEventCount;
+}
+
+void Page::changePendingUnloadEventCount(int delta)
+{
+ if (!delta)
+ return;
+ ASSERT( (delta + (int)m_pendingUnloadEventCount) >= 0 );
+
+ if (m_pendingUnloadEventCount == 0)
+ m_chrome->disableSuddenTermination();
+ else if ((m_pendingUnloadEventCount + delta) == 0)
+ m_chrome->enableSuddenTermination();
+
+ m_pendingUnloadEventCount += delta;
+ return;
+}
+
+unsigned Page::pendingBeforeUnloadEventCount()
+{
+ return m_pendingBeforeUnloadEventCount;
+}
+
+void Page::changePendingBeforeUnloadEventCount(int delta)
+{
+ if (!delta)
+ return;
+ ASSERT( (delta + (int)m_pendingBeforeUnloadEventCount) >= 0 );
+
+ if (m_pendingBeforeUnloadEventCount == 0)
+ m_chrome->disableSuddenTermination();
+ else if ((m_pendingBeforeUnloadEventCount + delta) == 0)
+ m_chrome->enableSuddenTermination();
+
+ m_pendingBeforeUnloadEventCount += delta;
+ return;
+}
+
+void Page::setCustomHTMLTokenizerTimeDelay(double customHTMLTokenizerTimeDelay)
+{
+ if (customHTMLTokenizerTimeDelay < 0) {
+ m_customHTMLTokenizerTimeDelay = -1;
+ return;
+ }
+ m_customHTMLTokenizerTimeDelay = customHTMLTokenizerTimeDelay;
+}
+
+void Page::setCustomHTMLTokenizerChunkSize(int customHTMLTokenizerChunkSize)
+{
+ if (customHTMLTokenizerChunkSize < 0) {
+ m_customHTMLTokenizerChunkSize = -1;
+ return;
+ }
+ m_customHTMLTokenizerChunkSize = customHTMLTokenizerChunkSize;
+}
+
} // namespace WebCore
diff --git a/WebCore/page/Page.h b/WebCore/page/Page.h
index 501890f..9c00ba7 100644
--- a/WebCore/page/Page.h
+++ b/WebCore/page/Page.h
@@ -1,6 +1,5 @@
-// -*- mode: c++; c-basic-offset: 4 -*-
/*
- * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -26,34 +25,19 @@
#include "ContextMenuController.h"
#include "FrameLoaderTypes.h"
#include "PlatformString.h"
+#if PLATFORM(MAC)
+#include "SchedulePair.h"
+#endif
#include <wtf/HashSet.h>
#include <wtf/OwnPtr.h>
-#if PLATFORM(WIN) || (PLATFORM(WX) && PLATFORM(WIN_OS))
+#if PLATFORM(WIN) || (PLATFORM(WX) && PLATFORM(WIN_OS)) || (PLATFORM(QT) && defined(Q_WS_WIN))
typedef struct HINSTANCE__* HINSTANCE;
#endif
-#ifdef ANDROID_FIX
-enum TextCaseSensitivity {
- TextCaseSensitive,
- TextCaseInsensitive
-};
-
-enum FindDirection {
- FindDirectionForward,
- FindDirectionBackward
-};
-#else
-typedef enum TextCaseSensitivity {
- TextCaseSensitive,
- TextCaseInsensitive
-};
-
-typedef enum FindDirection {
- FindDirectionForward,
- FindDirectionBackward
-};
-#endif
+namespace JSC {
+ class Debugger;
+}
namespace WebCore {
@@ -61,6 +45,7 @@ namespace WebCore {
class ChromeClient;
class ContextMenuClient;
class ContextMenuController;
+ class Document;
class DragClient;
class DragController;
class EditorClient;
@@ -69,19 +54,29 @@ namespace WebCore {
class InspectorClient;
class InspectorController;
class Node;
+ class PageGroup;
+ class PluginData;
class ProgressTracker;
class Selection;
class SelectionController;
+#if ENABLE(DOM_STORAGE)
+ class SessionStorage;
+#endif
class Settings;
+ enum TextCaseSensitivity { TextCaseSensitive, TextCaseInsensitive };
+ enum FindDirection { FindDirectionForward, FindDirectionBackward };
+
class Page : Noncopyable {
public:
static void setNeedsReapplyStyles();
- static const HashSet<Page*>* frameNamespace(const String&);
Page(ChromeClient*, ContextMenuClient*, EditorClient*, DragClient*, InspectorClient*);
~Page();
+ static void refreshPlugins(bool reload);
+ PluginData* pluginData() const;
+
EditorClient* editorClient() const { return m_editorClient; }
void setMainFrame(PassRefPtr<Frame>);
@@ -98,9 +93,10 @@ namespace WebCore {
void goToItem(HistoryItem*, FrameLoadType);
void setGroupName(const String&);
- String groupName() const { return m_groupName; }
+ const String& groupName() const;
- const HashSet<Page*>* frameNamespace() const;
+ PageGroup& group() { if (!m_group) initGroup(); return *m_group; }
+ PageGroup* groupPtr() { return m_group; } // can return 0
void incrementFrameCount() { ++m_frameCount; }
void decrementFrameCount() { --m_frameCount; }
@@ -125,6 +121,14 @@ namespace WebCore {
unsigned int markAllMatchesForText(const String&, TextCaseSensitivity, bool shouldHighlight, unsigned);
void unmarkAllTextMatches();
+#if PLATFORM(MAC)
+ void addSchedulePair(PassRefPtr<SchedulePair>);
+ void removeSchedulePair(PassRefPtr<SchedulePair>);
+ SchedulePairHashSet* scheduledRunLoopPairs() { return m_scheduledRunLoopPairs.get(); }
+
+ OwnPtr<SchedulePairHashSet> m_scheduledRunLoopPairs;
+#endif
+
const Selection& selection() const;
void setDefersLoading(bool);
@@ -135,16 +139,48 @@ namespace WebCore {
bool inLowQualityImageInterpolationMode() const;
void setInLowQualityImageInterpolationMode(bool = true);
+ bool cookieEnabled() const { return m_cookieEnabled; }
+ void setCookieEnabled(bool enabled) { m_cookieEnabled = enabled; }
+
void userStyleSheetLocationChanged();
const String& userStyleSheet() const;
+
+ void changePendingUnloadEventCount(int delta);
+ unsigned pendingUnloadEventCount();
+ void changePendingBeforeUnloadEventCount(int delta);
+ unsigned pendingBeforeUnloadEventCount();
+
+ static void setDebuggerForAllPages(JSC::Debugger*);
+ void setDebugger(JSC::Debugger*);
+ JSC::Debugger* debugger() const { return m_debugger; }
-#if PLATFORM(WIN) || (PLATFORM(WX) && PLATFORM(WIN_OS))
+#if PLATFORM(WIN) || (PLATFORM(WX) && PLATFORM(WIN_OS)) || (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; }
#endif
+ static void removeAllVisitedLinks();
+
+ static void allVisitedStateChanged(PageGroup*);
+ static void visitedStateChanged(PageGroup*, unsigned visitedHash);
+
+#if ENABLE(DOM_STORAGE)
+ SessionStorage* sessionStorage(bool optionalCreate = true);
+ void setSessionStorage(PassRefPtr<SessionStorage>);
+#endif
+
+ void setCustomHTMLTokenizerTimeDelay(double);
+ bool hasCustomHTMLTokenizerTimeDelay() const { return m_customHTMLTokenizerTimeDelay != -1; }
+ double customHTMLTokenizerTimeDelay() const { ASSERT(m_customHTMLTokenizerTimeDelay != -1); return m_customHTMLTokenizerTimeDelay; }
+
+ void setCustomHTMLTokenizerChunkSize(int);
+ bool hasCustomHTMLTokenizerChunkSize() const { return m_customHTMLTokenizerChunkSize != -1; }
+ int customHTMLTokenizerChunkSize() const { ASSERT(m_customHTMLTokenizerChunkSize != -1); return m_customHTMLTokenizerChunkSize; }
+
private:
+ void initGroup();
+
OwnPtr<Chrome> m_chrome;
OwnPtr<SelectionController> m_dragCaretController;
OwnPtr<DragController> m_dragController;
@@ -156,7 +192,8 @@ namespace WebCore {
RefPtr<BackForwardList> m_backForwardList;
RefPtr<Frame> m_mainFrame;
- RefPtr<Node> m_focusedNode;
+
+ mutable RefPtr<PluginData> m_pluginData;
EditorClient* m_editorClient;
@@ -167,6 +204,7 @@ namespace WebCore {
bool m_defersLoading;
bool m_inLowQualityInterpolationMode;
+ bool m_cookieEnabled;
InspectorController* m_parentInspectorController;
@@ -175,7 +213,21 @@ namespace WebCore {
mutable bool m_didLoadUserStyleSheet;
mutable time_t m_userStyleSheetModificationTime;
-#if PLATFORM(WIN) || (PLATFORM(WX) && defined(__WXMSW__))
+ OwnPtr<PageGroup> m_singlePageGroup;
+ PageGroup* m_group;
+
+ JSC::Debugger* m_debugger;
+
+ unsigned m_pendingUnloadEventCount;
+ unsigned m_pendingBeforeUnloadEventCount;
+
+ double m_customHTMLTokenizerTimeDelay;
+ int m_customHTMLTokenizerChunkSize;
+
+#if ENABLE(DOM_STORAGE)
+ RefPtr<SessionStorage> m_sessionStorage;
+#endif
+#if PLATFORM(WIN) || (PLATFORM(WX) && defined(__WXMSW__)) || (PLATFORM(QT) && defined(Q_WS_WIN))
static HINSTANCE s_instanceHandle;
#endif
};
diff --git a/WebCore/page/PageGroup.cpp b/WebCore/page/PageGroup.cpp
new file mode 100644
index 0000000..6b72be2
--- /dev/null
+++ b/WebCore/page/PageGroup.cpp
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PageGroup.h"
+
+#include "ChromeClient.h"
+#include "Document.h"
+#include "Page.h"
+#include "Settings.h"
+
+#if ENABLE(DOM_STORAGE)
+#include "LocalStorage.h"
+#include "StorageArea.h"
+#endif
+
+namespace WebCore {
+
+static unsigned getUniqueIdentifier()
+{
+ static unsigned currentIdentifier = 0;
+ return ++currentIdentifier;
+}
+
+// --------
+
+static bool shouldTrackVisitedLinks;
+
+PageGroup::PageGroup(const String& name)
+ : m_name(name)
+ , m_visitedLinksPopulated(false)
+ , m_identifier(getUniqueIdentifier())
+{
+}
+
+PageGroup::PageGroup(Page* page)
+ : m_visitedLinksPopulated(false)
+ , m_identifier(getUniqueIdentifier())
+{
+ ASSERT(page);
+ addPage(page);
+}
+
+typedef HashMap<String, PageGroup*> PageGroupMap;
+static PageGroupMap* pageGroups = 0;
+
+PageGroup* PageGroup::pageGroup(const String& groupName)
+{
+ ASSERT(!groupName.isEmpty());
+
+ if (!pageGroups)
+ pageGroups = new PageGroupMap;
+
+ pair<PageGroupMap::iterator, bool> result = pageGroups->add(groupName, 0);
+
+ if (result.second) {
+ ASSERT(!result.first->second);
+ result.first->second = new PageGroup(groupName);
+ }
+
+ ASSERT(result.first->second);
+ return result.first->second;
+}
+
+void PageGroup::closeLocalStorage()
+{
+#if ENABLE(DOM_STORAGE)
+ if (!pageGroups)
+ return;
+
+ PageGroupMap::iterator end = pageGroups->end();
+
+ for (PageGroupMap::iterator it = pageGroups->begin(); it != end; ++it) {
+ if (LocalStorage* localStorage = it->second->localStorage())
+ localStorage->close();
+ }
+#endif
+}
+
+void PageGroup::addPage(Page* page)
+{
+ ASSERT(page);
+ ASSERT(!m_pages.contains(page));
+ m_pages.add(page);
+#if ENABLE(DOM_STORAGE)
+ if (!m_localStorage)
+ m_localStorage = LocalStorage::localStorage(page->settings()->localStorageDatabasePath());
+#endif
+}
+
+void PageGroup::removePage(Page* page)
+{
+ ASSERT(page);
+ ASSERT(m_pages.contains(page));
+ m_pages.remove(page);
+}
+
+bool PageGroup::isLinkVisited(unsigned visitedLinkHash)
+{
+ if (!m_visitedLinksPopulated) {
+ m_visitedLinksPopulated = true;
+ ASSERT(!m_pages.isEmpty());
+ (*m_pages.begin())->chrome()->client()->populateVisitedLinks();
+ }
+ return m_visitedLinkHashes.contains(visitedLinkHash);
+}
+
+inline void PageGroup::addVisitedLink(unsigned stringHash)
+{
+ ASSERT(shouldTrackVisitedLinks);
+ unsigned visitedLinkHash = AlreadyHashed::avoidDeletedValue(stringHash);
+ if (!m_visitedLinkHashes.add(visitedLinkHash).second)
+ return;
+ Page::visitedStateChanged(this, visitedLinkHash);
+}
+
+void PageGroup::addVisitedLink(const KURL& url)
+{
+ if (!shouldTrackVisitedLinks)
+ return;
+ ASSERT(!url.isEmpty());
+ addVisitedLink(url.string().impl()->hash());
+}
+
+void PageGroup::addVisitedLink(const UChar* characters, size_t length)
+{
+ if (!shouldTrackVisitedLinks)
+ return;
+ addVisitedLink(StringImpl::computeHash(characters, length));
+}
+
+void PageGroup::removeVisitedLinks()
+{
+ m_visitedLinksPopulated = false;
+ if (m_visitedLinkHashes.isEmpty())
+ return;
+ m_visitedLinkHashes.clear();
+ Page::allVisitedStateChanged(this);
+}
+
+void PageGroup::removeAllVisitedLinks()
+{
+ Page::removeAllVisitedLinks();
+}
+
+void PageGroup::setShouldTrackVisitedLinks(bool shouldTrack)
+{
+ if (shouldTrackVisitedLinks == shouldTrack)
+ return;
+ shouldTrackVisitedLinks = shouldTrack;
+ if (!shouldTrackVisitedLinks)
+ removeAllVisitedLinks();
+}
+
+#if ENABLE(DOM_STORAGE)
+LocalStorage* PageGroup::localStorage()
+{
+ return m_localStorage.get();
+}
+#endif
+
+} // namespace WebCore
diff --git a/WebCore/page/PageGroup.h b/WebCore/page/PageGroup.h
new file mode 100644
index 0000000..b25892d
--- /dev/null
+++ b/WebCore/page/PageGroup.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PageGroup_h
+#define PageGroup_h
+
+#include <wtf/HashSet.h>
+#include <wtf/Noncopyable.h>
+#include "StringHash.h"
+
+namespace WebCore {
+
+ class KURL;
+ class LocalStorage;
+ class Page;
+
+ class PageGroup : Noncopyable {
+ public:
+ PageGroup(const String& name);
+ PageGroup(Page*);
+
+ static PageGroup* pageGroup(const String& groupName);
+ static void closeLocalStorage();
+
+ const HashSet<Page*>& pages() const { return m_pages; }
+
+ void addPage(Page*);
+ void removePage(Page*);
+
+ bool isLinkVisited(unsigned visitedLinkHash);
+
+ void addVisitedLink(const KURL&);
+ void addVisitedLink(const UChar*, size_t);
+ void removeVisitedLinks();
+
+ static void setShouldTrackVisitedLinks(bool);
+ static void removeAllVisitedLinks();
+
+ const String& name() { return m_name; }
+ unsigned identifier() { return m_identifier; }
+
+#if ENABLE(DOM_STORAGE)
+ LocalStorage* localStorage();
+#endif
+
+ private:
+ void addVisitedLink(unsigned stringHash);
+
+ String m_name;
+
+ HashSet<Page*> m_pages;
+ HashSet<unsigned, AlreadyHashed> m_visitedLinkHashes;
+ bool m_visitedLinksPopulated;
+
+ unsigned m_identifier;
+#if ENABLE(DOM_STORAGE)
+ RefPtr<LocalStorage> m_localStorage;
+#endif
+ };
+
+} // namespace WebCore
+
+#endif // PageGroup_h
diff --git a/WebCore/page/PositionCallback.h b/WebCore/page/PositionCallback.h
new file mode 100644
index 0000000..5f32c75
--- /dev/null
+++ b/WebCore/page/PositionCallback.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PositionCallback_h
+#define PositionCallback_h
+
+#include <wtf/Platform.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+ class Geoposition;
+
+ class PositionCallback : public RefCounted<PositionCallback> {
+ public:
+ virtual ~PositionCallback() { }
+ virtual void handleEvent(Geoposition* position, bool& raisedException) = 0;
+ };
+
+} // namespace WebCore
+
+#endif // PositionCallback_h
diff --git a/WebCore/page/PositionCallback.idl b/WebCore/page/PositionCallback.idl
new file mode 100644
index 0000000..e862538
--- /dev/null
+++ b/WebCore/page/PositionCallback.idl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module core {
+
+ interface [
+ GenerateConstructor
+ ] PositionCallback {
+ void handleEvent(in Geoposition position);
+ };
+
+}
diff --git a/WebCore/page/PositionError.h b/WebCore/page/PositionError.h
new file mode 100644
index 0000000..1d68bde
--- /dev/null
+++ b/WebCore/page/PositionError.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PositionError_h
+#define PositionError_h
+
+#include "PlatformString.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class PositionError : public RefCounted<PositionError> {
+public:
+ enum ErrorCode {
+ PERMISSION_ERROR = 1,
+ LOCATION_PROVIDER_ERROR,
+ POSITION_NOT_FOUND_ERROR,
+ TIMEOUT_ERROR,
+ UNKNOWN_ERROR
+ };
+
+ static PassRefPtr<PositionError> create(ErrorCode code, const String& message) { return adoptRef(new PositionError(code, message)); }
+
+ ErrorCode code() const { return m_code; }
+ const String& message() const { return m_message; }
+
+private:
+ PositionError(ErrorCode code, const String& message)
+ : m_code(code)
+ , m_message(message)
+ {
+ }
+
+ ErrorCode m_code;
+ String m_message;
+};
+
+} // namespace WebCore
+
+#endif // PositionError_h
diff --git a/WebCore/page/PositionError.idl b/WebCore/page/PositionError.idl
new file mode 100644
index 0000000..8c8c335
--- /dev/null
+++ b/WebCore/page/PositionError.idl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module core {
+
+ interface [
+ GenerateConstructor
+ ] PositionError {
+ readonly attribute long code;
+ readonly attribute DOMString message;
+ };
+
+}
diff --git a/WebCore/page/PositionErrorCallback.h b/WebCore/page/PositionErrorCallback.h
new file mode 100644
index 0000000..c23e883
--- /dev/null
+++ b/WebCore/page/PositionErrorCallback.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PositionErrorCallback_h
+#define PositionErrorCallback_h
+
+#include <wtf/Platform.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+ class PositionError;
+
+ class PositionErrorCallback : public RefCounted<PositionErrorCallback> {
+ public:
+ virtual ~PositionErrorCallback() { }
+ virtual void handleEvent(PositionError*) = 0;
+ };
+
+} // namespace WebCore
+
+#endif // PositionErrorCallback_h
diff --git a/WebCore/page/PositionErrorCallback.idl b/WebCore/page/PositionErrorCallback.idl
new file mode 100644
index 0000000..07edfa6
--- /dev/null
+++ b/WebCore/page/PositionErrorCallback.idl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module core {
+
+ interface [
+ GenerateConstructor
+ ] PositionErrorCallback {
+ void handleEvent(in PositionError error);
+ };
+
+}
diff --git a/WebCore/page/PositionOptions.h b/WebCore/page/PositionOptions.h
new file mode 100644
index 0000000..dc9c167
--- /dev/null
+++ b/WebCore/page/PositionOptions.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PositionOptions_h
+#define PositionOptions_h
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class PositionOptions : public RefCounted<PositionOptions> {
+public:
+ static PassRefPtr<PositionOptions> create(bool highAccuracy, unsigned timeout) { return adoptRef(new PositionOptions(highAccuracy, timeout)); }
+
+ bool enableHighAccuracy() const { return m_highAccuracy; }
+ void setEnableHighAccuracy(bool enable) { m_highAccuracy = enable; }
+ unsigned timeout() const { return m_timeout; }
+ void setTimeout(unsigned t) { m_timeout = t; }
+
+private:
+ PositionOptions(bool highAccuracy, unsigned timeout)
+ : m_highAccuracy(highAccuracy)
+ , m_timeout(timeout)
+ {
+ }
+
+ bool m_highAccuracy;
+ unsigned m_timeout;
+};
+
+} // namespace WebCore
+
+#endif // PositionOptions_h
diff --git a/WebCore/page/PositionOptions.idl b/WebCore/page/PositionOptions.idl
new file mode 100644
index 0000000..29253df
--- /dev/null
+++ b/WebCore/page/PositionOptions.idl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module core {
+
+ interface [
+ GenerateConstructor
+ ] PositionOptions {
+ attribute boolean enableHighAccuracy;
+ attribute unsigned long timeout;
+ };
+
+}
diff --git a/WebCore/page/PrintContext.cpp b/WebCore/page/PrintContext.cpp
new file mode 100644
index 0000000..79672a3
--- /dev/null
+++ b/WebCore/page/PrintContext.cpp
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2007 Alp Toker <alp@atoker.com>
+ * Copyright (C) 2007 Apple Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "PrintContext.h"
+
+#include "GraphicsContext.h"
+#include "Frame.h"
+#include "FrameView.h"
+#include "RenderView.h"
+
+using namespace WebCore;
+
+namespace WebCore {
+
+PrintContext::PrintContext(Frame* frame)
+ : m_frame(frame)
+{
+}
+
+PrintContext::~PrintContext()
+{
+ m_pageRects.clear();
+}
+
+int PrintContext::pageCount() const
+{
+ return m_pageRects.size();
+}
+
+void PrintContext::computePageRects(const FloatRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, float& outPageHeight)
+{
+ m_pageRects.clear();
+ outPageHeight = 0;
+
+ if (!m_frame->document() || !m_frame->view() || !m_frame->document()->renderer())
+ return;
+
+ RenderView* root = static_cast<RenderView*>(m_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 = printRect.height() / printRect.width();
+
+ float pageWidth = (float)root->docWidth();
+ float pageHeight = pageWidth * ratio;
+ outPageHeight = 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.0;
+ do {
+ float proposedBottom = std::min(docHeight, printedPagesHeight + pageHeight);
+ m_frame->adjustPageHeight(&proposedBottom, printedPagesHeight, proposedBottom, printedPagesHeight);
+ currPageHeight = max(1.0f, proposedBottom - printedPagesHeight);
+
+ m_pageRects.append(IntRect(0, (int)printedPagesHeight, (int)currPageWidth, (int)currPageHeight));
+ printedPagesHeight += currPageHeight;
+ } while (printedPagesHeight < docHeight);
+}
+
+void PrintContext::begin(float width)
+{
+ // By imaging to a width a little wider than the available pixels,
+ // thin pages will be scaled down a little, matching the way they
+ // print in IE and Camino. This lets them use fewer sheets than they
+ // would otherwise, which is presumably why other browsers do this.
+ // Wide pages will be scaled down more than this.
+ const float PrintingMinimumShrinkFactor = 1.25f;
+
+ // This number determines how small we are willing to reduce the page content
+ // in order to accommodate the widest line. If the page would have to be
+ // reduced smaller to make the widest line fit, we just clip instead (this
+ // behavior matches MacIE and Mozilla, at least)
+ const float PrintingMaximumShrinkFactor = 2.0f;
+
+ float minLayoutWidth = width * PrintingMinimumShrinkFactor;
+ float maxLayoutWidth = width * PrintingMaximumShrinkFactor;
+
+ // FIXME: This will modify the rendering of the on-screen frame.
+ // Could lead to flicker during printing.
+ m_frame->setPrinting(true, minLayoutWidth, maxLayoutWidth, true);
+}
+
+void PrintContext::spoolPage(GraphicsContext& ctx, int pageNumber, float width)
+{
+ IntRect pageRect = m_pageRects[pageNumber];
+ float scale = width / pageRect.width();
+
+ ctx.save();
+ ctx.scale(FloatSize(scale, scale));
+ ctx.translate(-pageRect.x(), -pageRect.y());
+ ctx.clip(pageRect);
+ m_frame->view()->paintContents(&ctx, pageRect);
+ ctx.restore();
+}
+
+void PrintContext::end()
+{
+ m_frame->setPrinting(false, 0, 0, true);
+}
+
+}
diff --git a/WebCore/page/PrintContext.h b/WebCore/page/PrintContext.h
new file mode 100644
index 0000000..0b3b303
--- /dev/null
+++ b/WebCore/page/PrintContext.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2007 Alp Toker <alp@atoker.com>
+ * Copyright (C) 2007 Apple Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef PrintContext_h
+#define PrintContext_h
+
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class Frame;
+class FloatRect;
+class GraphicsContext;
+class IntRect;
+
+class PrintContext {
+public:
+ PrintContext(Frame*);
+ ~PrintContext();
+
+ int pageCount() const;
+
+ void computePageRects(const FloatRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, float& outPageHeight);
+
+ // TODO: eliminate width param
+ void begin(float width);
+
+ // TODO: eliminate width param
+ void spoolPage(GraphicsContext& ctx, int pageNumber, float width);
+
+ void end();
+
+protected:
+ Frame* m_frame;
+ Vector<IntRect> m_pageRects;
+};
+
+}
+
+#endif
diff --git a/WebCore/page/Screen.h b/WebCore/page/Screen.h
index 510cefd..a740ccb 100644
--- a/WebCore/page/Screen.h
+++ b/WebCore/page/Screen.h
@@ -30,6 +30,7 @@
#ifndef Screen_h
#define Screen_h
+#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
namespace WebCore {
@@ -38,7 +39,7 @@ namespace WebCore {
class Screen : public RefCounted<Screen> {
public:
- Screen(Frame*);
+ static PassRefPtr<Screen> create(Frame *frame) { return adoptRef(new Screen(frame)); }
void disconnectFrame();
unsigned height() const;
@@ -54,6 +55,8 @@ namespace WebCore {
#endif
private:
+ Screen(Frame*);
+
Frame* m_frame;
};
diff --git a/WebCore/page/SecurityOrigin.cpp b/WebCore/page/SecurityOrigin.cpp
new file mode 100644
index 0000000..6de7508
--- /dev/null
+++ b/WebCore/page/SecurityOrigin.cpp
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SecurityOrigin.h"
+
+#include "CString.h"
+#include "FrameLoader.h"
+#include "KURL.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+static bool isDefaultPortForProtocol(unsigned short port, const String& protocol)
+{
+ if (protocol.isEmpty())
+ return false;
+
+ static HashMap<String, unsigned> defaultPorts;
+ if (defaultPorts.isEmpty()) {
+ defaultPorts.set("http", 80);
+ defaultPorts.set("https", 443);
+ defaultPorts.set("ftp", 21);
+ defaultPorts.set("ftps", 990);
+ }
+ return defaultPorts.get(protocol) == port;
+}
+
+SecurityOrigin::SecurityOrigin(const KURL& url)
+ : m_protocol(url.protocol().isNull() ? "" : url.protocol().lower())
+ , m_host(url.host().isNull() ? "" : url.host().lower())
+ , m_port(url.port())
+ , m_noAccess(false)
+ , m_domainWasSetInDOM(false)
+{
+ // These protocols do not create security origins; the owner frame provides the origin
+ if (m_protocol == "about" || m_protocol == "javascript")
+ m_protocol = "";
+
+ // data: URLs are not allowed access to anything other than themselves.
+ if (m_protocol == "data")
+ m_noAccess = true;
+
+ // document.domain starts as m_host, but can be set by the DOM.
+ m_domain = m_host;
+
+ // By default, only local SecurityOrigins can load local resources.
+ m_canLoadLocalResources = isLocal();
+
+ if (isDefaultPortForProtocol(m_port, m_protocol))
+ m_port = 0;
+}
+
+SecurityOrigin::SecurityOrigin(const SecurityOrigin* other)
+ : m_protocol(other->m_protocol.copy())
+ , m_host(other->m_host.copy())
+ , m_domain(other->m_domain.copy())
+ , m_port(other->m_port)
+ , m_noAccess(other->m_noAccess)
+ , m_domainWasSetInDOM(other->m_domainWasSetInDOM)
+ , m_canLoadLocalResources(other->m_canLoadLocalResources)
+{
+}
+
+bool SecurityOrigin::isEmpty() const
+{
+ return m_protocol.isEmpty();
+}
+
+PassRefPtr<SecurityOrigin> SecurityOrigin::create(const KURL& url)
+{
+ return adoptRef(new SecurityOrigin(url));
+}
+
+PassRefPtr<SecurityOrigin> SecurityOrigin::createEmpty()
+{
+ return create(KURL());
+}
+
+PassRefPtr<SecurityOrigin> SecurityOrigin::copy()
+{
+ return adoptRef(new SecurityOrigin(this));
+}
+
+void SecurityOrigin::setDomainFromDOM(const String& newDomain)
+{
+ m_domainWasSetInDOM = true;
+ m_domain = newDomain.lower();
+}
+
+bool SecurityOrigin::canAccess(const SecurityOrigin* other) const
+{
+ if (isLocal())
+ return true;
+
+ if (m_noAccess || other->m_noAccess)
+ return false;
+
+ // Here are two cases where we should permit access:
+ //
+ // 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
+ // that the documents have set document.domain to the same value and
+ // that the scheme of the URLs match.
+ //
+ // This matches the behavior of Firefox 2 and Internet Explorer 6.
+ //
+ // Internet Explorer 7 and Opera 9 are more strict in that they require
+ // the port numbers to match when both pages have document.domain set.
+ //
+ // FIXME: Evaluate whether we can tighten this policy to require matched
+ // port numbers.
+ //
+ // Opera 9 allows access when only one page has set document.domain, but
+ // this is a security vulnerability.
+
+ if (m_protocol == other->m_protocol) {
+ if (!m_domainWasSetInDOM && !other->m_domainWasSetInDOM) {
+ if (m_host == other->m_host && m_port == other->m_port)
+ return true;
+ } else if (m_domainWasSetInDOM && other->m_domainWasSetInDOM) {
+ if (m_domain == other->m_domain)
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool SecurityOrigin::canRequest(const KURL& url) const
+{
+ if (isLocal())
+ return true;
+
+ if (m_noAccess)
+ return false;
+
+ RefPtr<SecurityOrigin> targetOrigin = SecurityOrigin::create(url);
+
+ // We call isSameSchemeHostPort here instead of canAccess because we want
+ // to ignore document.domain effects.
+ return isSameSchemeHostPort(targetOrigin.get());
+}
+
+void SecurityOrigin::grantLoadLocalResources()
+{
+ // This method 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.
+ ASSERT(FrameLoader::allowSubstituteDataAccessToLocal());
+ m_canLoadLocalResources = true;
+}
+
+bool SecurityOrigin::isLocal() const
+{
+ return FrameLoader::shouldTreatSchemeAsLocal(m_protocol);
+}
+
+bool SecurityOrigin::isSecureTransitionTo(const KURL& url) const
+{
+ // New window created by the application
+ if (isEmpty())
+ return true;
+
+ RefPtr<SecurityOrigin> other = SecurityOrigin::create(url);
+ return canAccess(other.get());
+}
+
+String SecurityOrigin::toString() const
+{
+ if (isEmpty())
+ return "null";
+
+ if (m_noAccess)
+ return "null";
+
+ if (m_protocol == "file")
+ return String("file://");
+
+ Vector<UChar> result;
+ result.reserveCapacity(m_protocol.length() + m_host.length() + 10);
+ append(result, m_protocol);
+ append(result, "://");
+ append(result, m_host);
+
+ if (m_port) {
+ append(result, ":");
+ append(result, String::number(m_port));
+ }
+
+ return String::adopt(result);
+}
+
+PassRefPtr<SecurityOrigin> SecurityOrigin::createFromString(const String& originString)
+{
+ return SecurityOrigin::create(KURL(originString));
+}
+
+static const char SeparatorCharacter = '_';
+
+PassRefPtr<SecurityOrigin> SecurityOrigin::createFromDatabaseIdentifier(const String& databaseIdentifier)
+{
+ // Make sure there's a first separator
+ int separator1 = databaseIdentifier.find(SeparatorCharacter);
+ if (separator1 == -1)
+ return create(KURL());
+
+ // Make sure there's a second separator
+ int separator2 = databaseIdentifier.find(SeparatorCharacter, separator1 + 1);
+ if (separator2 == -1)
+ return create(KURL());
+
+ // Make sure there's not a third separator
+ if (databaseIdentifier.reverseFind(SeparatorCharacter) != separator2)
+ return create(KURL());
+
+ // Make sure the port section is a valid port number or doesn't exist
+ bool portOkay;
+ int port = databaseIdentifier.right(databaseIdentifier.length() - separator2 - 1).toInt(&portOkay);
+ if (!portOkay && separator2 + 1 == static_cast<int>(databaseIdentifier.length()))
+ return create(KURL());
+
+ if (port < 0 || port > 65535)
+ return create(KURL());
+
+ // Split out the 3 sections of data
+ String protocol = databaseIdentifier.substring(0, separator1);
+ String host = databaseIdentifier.substring(separator1 + 1, separator2 - separator1 - 1);
+ return create(KURL(protocol + "://" + host + ":" + String::number(port)));
+}
+
+String SecurityOrigin::databaseIdentifier() const
+{
+ static String separatorString = String(&SeparatorCharacter, 1);
+ return m_protocol + separatorString + m_host + separatorString + String::number(m_port);
+}
+
+bool SecurityOrigin::equal(const SecurityOrigin* other) const
+{
+ if (!isSameSchemeHostPort(other))
+ return false;
+
+ if (m_domainWasSetInDOM != other->m_domainWasSetInDOM)
+ return false;
+
+ if (m_domainWasSetInDOM && m_domain != other->m_domain)
+ return false;
+
+ return true;
+}
+
+bool SecurityOrigin::isSameSchemeHostPort(const SecurityOrigin* other) const
+{
+ if (m_host != other->m_host)
+ return false;
+
+ if (m_protocol != other->m_protocol)
+ return false;
+
+ if (m_port != other->m_port)
+ return false;
+
+ return true;
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/SecurityOrigin.h b/WebCore/page/SecurityOrigin.h
new file mode 100644
index 0000000..1f2624e
--- /dev/null
+++ b/WebCore/page/SecurityOrigin.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2007,2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 SecurityOrigin_h
+#define SecurityOrigin_h
+
+#include <wtf/RefCounted.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/Threading.h>
+
+#include "PlatformString.h"
+
+namespace WebCore {
+
+ 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> copy();
+
+ // 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 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();
+
+ 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. The empty
+ // SecurityOrigin is represented with the string "null".
+ String toString() const;
+
+ // Serialize the security origin for storage in the database. This format is
+ // deprecated and should be used only for compatibility with old databases;
+ // use toString() and createFromString() instead.
+ 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;
+
+ private:
+ explicit SecurityOrigin(const KURL&);
+ explicit SecurityOrigin(const SecurityOrigin*);
+
+ String m_protocol;
+ String m_host;
+ String m_domain;
+ unsigned short m_port;
+ bool m_noAccess;
+ bool m_domainWasSetInDOM;
+ bool m_canLoadLocalResources;
+ };
+
+} // namespace WebCore
+
+#endif // SecurityOrigin_h
diff --git a/WebCore/page/SecurityOriginHash.h b/WebCore/page/SecurityOriginHash.h
new file mode 100644
index 0000000..1915fc7
--- /dev/null
+++ b/WebCore/page/SecurityOriginHash.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 SecurityOriginHash_h
+#define SecurityOriginHash_h
+
+#include "KURL.h"
+#include "SecurityOrigin.h"
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+struct SecurityOriginHash {
+ static unsigned hash(SecurityOrigin* origin)
+ {
+ unsigned hashCodes[3] = {
+ origin->protocol().impl() ? origin->protocol().impl()->hash() : 0,
+ origin->host().impl() ? origin->host().impl()->hash() : 0,
+ origin->port()
+ };
+ return StringImpl::computeHash(reinterpret_cast<UChar*>(hashCodes), sizeof(hashCodes) / sizeof(UChar));
+ }
+ static unsigned hash(const RefPtr<SecurityOrigin>& origin)
+ {
+ return hash(origin.get());
+ }
+
+ static bool equal(SecurityOrigin* a, SecurityOrigin* b)
+ {
+ // FIXME: The hash function above compares three specific fields.
+ // This code to compare those three specific fields should be moved here from
+ // SecurityOrigin as mentioned in SecurityOrigin.h so we don't accidentally change
+ // equal without changing hash to match it.
+ if (!a || !b)
+ return a == b;
+ return a->equal(b);
+ }
+ static bool equal(SecurityOrigin* a, const RefPtr<SecurityOrigin>& b)
+ {
+ return equal(a, b.get());
+ }
+ static bool equal(const RefPtr<SecurityOrigin>& a, SecurityOrigin* b)
+ {
+ return equal(a.get(), b);
+ }
+ static bool equal(const RefPtr<SecurityOrigin>& a, const RefPtr<SecurityOrigin>& b)
+ {
+ return equal(a.get(), b.get());
+ }
+
+ static const bool safeToCompareToEmptyOrDeleted = false;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/WebCore/page/Settings.cpp b/WebCore/page/Settings.cpp
index 9a8adb0..b9b3925 100644
--- a/WebCore/page/Settings.cpp
+++ b/WebCore/page/Settings.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,9 +28,10 @@
#include "Frame.h"
#include "FrameTree.h"
+#include "HistoryItem.h"
#include "Page.h"
#include "PageCache.h"
-#include "HistoryItem.h"
+#include <limits>
#if ENABLE(DATABASE)
#include "DatabaseTracker.h"
@@ -44,6 +45,10 @@ static void setNeedsReapplyStylesInAllFrames(Page* page)
frame->setNeedsReapplyStyles();
}
+#if USE(SAFARI_THEME)
+bool Settings::gShouldPaintNativeControls = false;
+#endif
+
Settings::Settings(Page* page)
: m_page(page)
#ifdef ANDROID_LAYOUT
@@ -71,7 +76,9 @@ Settings::Settings(Page* page)
, m_javaScriptCanOpenWindowsAutomatically(false)
, m_shouldPrintBackgrounds(false)
, m_textAreasAreResizable(false)
+#if ENABLE(DASHBOARD_SUPPORT)
, m_usesDashboardBackwardCompatibilityMode(false)
+#endif
, m_needsAdobeFrameReloadingQuirk(false)
, m_needsKeyboardEventDisambiguationQuirks(false)
, m_isDOMPasteAllowed(false)
@@ -83,6 +90,14 @@ Settings::Settings(Page* page)
, m_authorAndUserStylesEnabled(true)
, m_needsSiteSpecificQuirks(false)
, m_fontRenderingMode(0)
+ , m_webArchiveDebugModeEnabled(false)
+ , m_inApplicationChromeMode(false)
+ , m_offlineWebApplicationCacheEnabled(false)
+ , m_rangeMutationDisabledForOldAppleMail(false)
+ , m_shouldPaintCustomScrollbars(false)
+ , m_zoomsTextOnly(false)
+ , m_enforceCSSMIMETypeInStrictMode(true)
+ , m_maximumDecodedImageSize(std::numeric_limits<size_t>::max())
{
// A Frame may not have been created yet, so we initialize the AtomicString
// hash before trying to use it.
@@ -261,10 +276,12 @@ void Settings::setEditableLinkBehavior(EditableLinkBehavior editableLinkBehavior
m_editableLinkBehavior = editableLinkBehavior;
}
+#if ENABLE(DASHBOARD_SUPPORT)
void Settings::setUsesDashboardBackwardCompatibilityMode(bool usesDashboardBackwardCompatibilityMode)
{
m_usesDashboardBackwardCompatibilityMode = usesDashboardBackwardCompatibilityMode;
}
+#endif
// FIXME: This quirk is needed because of Radar 4674537 and 5211271. We need to phase it out once Adobe
// can fix the bug from their end.
@@ -441,4 +458,55 @@ void Settings::setNeedsSiteSpecificQuirks(bool needsQuirks)
m_needsSiteSpecificQuirks = needsQuirks;
}
+void Settings::setWebArchiveDebugModeEnabled(bool enabled)
+{
+ m_webArchiveDebugModeEnabled = enabled;
+}
+
+void Settings::setLocalStorageDatabasePath(const String& path)
+{
+ m_localStorageDatabasePath = path;
+}
+
+void Settings::disableRangeMutationForOldAppleMail(bool disable)
+{
+ m_rangeMutationDisabledForOldAppleMail = disable;
+}
+
+void Settings::setApplicationChromeMode(bool mode)
+{
+ m_inApplicationChromeMode = mode;
+}
+
+void Settings::setOfflineWebApplicationCacheEnabled(bool enabled)
+{
+ m_offlineWebApplicationCacheEnabled = enabled;
+}
+
+void Settings::setShouldPaintCustomScrollbars(bool shouldPaintCustomScrollbars)
+{
+ m_shouldPaintCustomScrollbars = shouldPaintCustomScrollbars;
+}
+
+void Settings::setZoomsTextOnly(bool zoomsTextOnly)
+{
+ if (zoomsTextOnly == m_zoomsTextOnly)
+ return;
+
+ m_zoomsTextOnly = zoomsTextOnly;
+ setNeedsReapplyStylesInAllFrames(m_page);
+}
+
+void Settings::setEnforceCSSMIMETypeInStrictMode(bool enforceCSSMIMETypeInStrictMode)
+{
+ m_enforceCSSMIMETypeInStrictMode = enforceCSSMIMETypeInStrictMode;
+}
+
+#if USE(SAFARI_THEME)
+void Settings::setShouldPaintNativeControls(bool shouldPaintNativeControls)
+{
+ gShouldPaintNativeControls = shouldPaintNativeControls;
+}
+#endif
+
} // namespace WebCore
diff --git a/WebCore/page/Settings.h b/WebCore/page/Settings.h
index 28b92c3..8acc998 100644
--- a/WebCore/page/Settings.h
+++ b/WebCore/page/Settings.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003, 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved.
* (C) 2006 Graham Dennis (graham.dennis@gmail.com)
*
* Redistribution and use in source and binary forms, with or without
@@ -28,8 +28,8 @@
#define Settings_h
#include "AtomicString.h"
-#include "KURL.h"
#include "FontDescription.h"
+#include "KURL.h"
namespace WebCore {
@@ -43,8 +43,7 @@ namespace WebCore {
EditableLinkNeverLive
};
- class Settings
- {
+ class Settings {
public:
Settings(Page*);
@@ -139,8 +138,10 @@ namespace WebCore {
void setEditableLinkBehavior(EditableLinkBehavior);
EditableLinkBehavior editableLinkBehavior() const { return m_editableLinkBehavior; }
+#if ENABLE(DASHBOARD_SUPPORT)
void setUsesDashboardBackwardCompatibilityMode(bool);
bool usesDashboardBackwardCompatibilityMode() const { return m_usesDashboardBackwardCompatibilityMode; }
+#endif
void setNeedsAdobeFrameReloadingQuirk(bool);
bool needsAcrobatFrameReloadingQuirk() const { return m_needsAdobeFrameReloadingQuirk; }
@@ -195,6 +196,39 @@ namespace WebCore {
void setNeedsSiteSpecificQuirks(bool);
bool needsSiteSpecificQuirks() const { return m_needsSiteSpecificQuirks; }
+
+ void setWebArchiveDebugModeEnabled(bool);
+ bool webArchiveDebugModeEnabled() const { return m_webArchiveDebugModeEnabled; }
+
+ void setLocalStorageDatabasePath(const String&);
+ const String& localStorageDatabasePath() const { return m_localStorageDatabasePath; }
+
+ void disableRangeMutationForOldAppleMail(bool);
+ bool rangeMutationDisabledForOldAppleMail() const { return m_rangeMutationDisabledForOldAppleMail; }
+
+ void setApplicationChromeMode(bool);
+ bool inApplicationChromeMode() const { return m_inApplicationChromeMode; }
+
+ void setOfflineWebApplicationCacheEnabled(bool);
+ bool offlineWebApplicationCacheEnabled() const { return m_offlineWebApplicationCacheEnabled; }
+
+ void setShouldPaintCustomScrollbars(bool);
+ bool shouldPaintCustomScrollbars() const { return m_shouldPaintCustomScrollbars; }
+
+ void setZoomsTextOnly(bool);
+ bool zoomsTextOnly() const { return m_zoomsTextOnly; }
+
+ void setEnforceCSSMIMETypeInStrictMode(bool);
+ bool enforceCSSMIMETypeInStrictMode() { return m_enforceCSSMIMETypeInStrictMode; }
+
+ void setMaximumDecodedImageSize(size_t size) { m_maximumDecodedImageSize = size; }
+ size_t maximumDecodedImageSize() const { return m_maximumDecodedImageSize; }
+
+#if USE(SAFARI_THEME)
+ // Windows debugging pref (global) for switching between the Aqua look and a native windows look.
+ static void setShouldPaintNativeControls(bool);
+ static bool shouldPaintNativeControls() { return gShouldPaintNativeControls; }
+#endif
private:
Page* m_page;
@@ -204,6 +238,7 @@ namespace WebCore {
#ifdef ANDROID_PLUGINS
String m_pluginsPath;
#endif
+ String m_localStorageDatabasePath;
KURL m_userStyleSheetLocation;
AtomicString m_standardFontFamily;
AtomicString m_fixedFontFamily;
@@ -258,7 +293,9 @@ namespace WebCore {
bool m_javaScriptCanOpenWindowsAutomatically : 1;
bool m_shouldPrintBackgrounds : 1;
bool m_textAreasAreResizable : 1;
+#if ENABLE(DASHBOARD_SUPPORT)
bool m_usesDashboardBackwardCompatibilityMode : 1;
+#endif
bool m_needsAdobeFrameReloadingQuirk : 1;
bool m_needsKeyboardEventDisambiguationQuirks : 1;
bool m_isDOMPasteAllowed : 1;
@@ -270,6 +307,18 @@ namespace WebCore {
bool m_authorAndUserStylesEnabled : 1;
bool m_needsSiteSpecificQuirks : 1;
unsigned m_fontRenderingMode : 1;
+ bool m_webArchiveDebugModeEnabled : 1;
+ bool m_inApplicationChromeMode : 1;
+ bool m_offlineWebApplicationCacheEnabled : 1;
+ bool m_rangeMutationDisabledForOldAppleMail : 1;
+ bool m_shouldPaintCustomScrollbars : 1;
+ bool m_zoomsTextOnly : 1;
+ bool m_enforceCSSMIMETypeInStrictMode : 1;
+ size_t m_maximumDecodedImageSize;
+
+#if USE(SAFARI_THEME)
+ static bool gShouldPaintNativeControls;
+#endif
};
} // namespace WebCore
diff --git a/WebCore/page/android/EventHandlerAndroid.cpp b/WebCore/page/android/EventHandlerAndroid.cpp
index ca74a79..aa522a3 100644
--- a/WebCore/page/android/EventHandlerAndroid.cpp
+++ b/WebCore/page/android/EventHandlerAndroid.cpp
@@ -22,6 +22,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define LOG_TAG "WebCore"
#include "config.h"
#include "EventHandler.h"
@@ -33,20 +34,17 @@
#include "FrameView.h"
#include "KeyboardEvent.h"
#include "MouseEventWithHitTestResults.h"
+#include "NotImplemented.h"
#include "Page.h"
-#include "PlatformScrollBar.h"
+#include "PlatformKeyboardEvent.h"
#include "PlatformWheelEvent.h"
#include "RenderWidget.h"
-#define LOG_TAG "WebCore"
-#undef LOG
-#include <utils/Log.h>
-
namespace WebCore {
-using namespace EventNames;
+// using namespace EventNames;
-#define notImplemented() { LOGV("%s: Not Implemented", __FUNCTION__); }
+unsigned EventHandler::s_accessKeyModifiers = PlatformKeyboardEvent::AltKey;
bool EventHandler::tabsToAllControls(KeyboardEvent* ) const
{
@@ -78,7 +76,7 @@ bool EventHandler::passWidgetMouseDownEventToWidget(RenderWidget* renderWidget)
// work around for the Mac platform which does not support double clicks, but browsers do.
bool EventHandler::passMouseDownEventToWidget(Widget* widget)
{
- notImplemented();
+ // return false so the normal propogation handles the event
return false;
}
@@ -124,14 +122,11 @@ bool EventHandler::passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&
return passSubframeEventToSubframe(mev, subframe);
}
-bool EventHandler::passMousePressEventToScrollbar(MouseEventWithHitTestResults&, PlatformScrollbar* scrollbar)
-{
- notImplemented();
- return false;
-}
-
// functions new to Jun-07 tip of tree merge:
-Clipboard* EventHandler::createDraggingClipboard() const { return NULL; }
+class Clipboard : public RefCounted<Clipboard> {};
+PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const { return PassRefPtr<Clipboard>(NULL); }
+ // new as of SVN change 36269, Sept 8, 2008
+const double EventHandler::TextDragDelay = 0.0;
}
diff --git a/WebCore/page/android/FrameAndroid.cpp b/WebCore/page/android/FrameAndroid.cpp
deleted file mode 100644
index ca86bb5..0000000
--- a/WebCore/page/android/FrameAndroid.cpp
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#include "config.h"
-#include "FrameAndroid.h"
-
-#include <JavaScriptCore/bindings/runtime_root.h>
-#include <JavaScriptCore/bindings/runtime_object.h>
-#include <JavaScriptCore/bindings/jni/jni_utility.h>
-#include "jni.h"
-#include "kjs_proxy.h"
-#include "kjs_window.h"
-
-#include "CacheBuilder.h"
-#include "CachedImage.h"
-#include "Document.h"
-#include "EventNames.h"
-#include "FrameLoader.h"
-#include "FramePrivate.h"
-#include "FrameView.h"
-#include "HTMLAreaElement.h"
-#include "HTMLImageElement.h"
-#include "HTMLNames.h"
-#include "Image.h"
-#include "Page.h"
-#include "PlatformKeyboardEvent.h"
-#include "PlatformString.h"
-#ifdef ANDROID_PLUGINS
-#include "Plugin.h"
-#include "PluginViewAndroid.h"
-#endif
-#include "RenderImage.h"
-#include "RenderTable.h"
-#include "RenderTextControl.h"
-#include "RenderTheme.h"
-#include "RenderView.h"
-#include "RenderWidget.h"
-#include "SelectionController.h"
-#include "Settings.h"
-#include "SkScalar.h"
-#include "Text.h"
-#include "WebCoreFrameBridge.h"
-#include "WebCoreViewBridge.h"
-
-#define LOG_TAG "WebCore"
-#undef LOG
-#include <utils/Log.h>
-
-#ifdef ANDROID_INSTRUMENT
-#include "CString.h"
-#include "Cache.h"
-#endif
-
-using KJS::JSLock;
-using KJS::JSValue;
-
-namespace WebCore {
-
-#ifdef ANDROID_INSTRUMENT
-// The following code should be inside Frame.cpp. But android LOG is conflict
-// with webcore LOG
-void Frame::resetTimeCounter() {
- KJS::JSGlobalObject::resetTimeCounter();
- resetLayoutTimeCounter();
- resetPaintTimeCounter();
- resetCSSTimeCounter();
- resetParsingTimeCounter();
- resetCalculateStyleTimeCounter();
- resetFramebridgeTimeCounter();
- resetSharedTimerTimeCounter();
- resetResourceLoadTimeCounter();
- resetWebViewCoreTimeCounter();
- LOG(LOG_DEBUG, "WebCore", "*-* Start browser instrument\n");
-}
-
-void Frame::reportTimeCounter(String url, int total, int totalThreadTime)
-{
- LOG(LOG_DEBUG, "WebCore",
- "*-* Total load time: %d ms, thread time: %d ms for %s\n",
- total, totalThreadTime, url.utf8().data());
- KJS::JSGlobalObject::reportTimeCounter();
- reportLayoutTimeCounter();
- reportPaintTimeCounter();
- reportCSSTimeCounter();
- reportParsingTimeCounter();
- reportCalculateStyleTimeCounter();
- reportFramebridgeTimeCounter();
- reportSharedTimerTimeCounter();
- reportResourceLoadTimeCounter();
- reportWebViewCoreTimeCounter();
- LOG(LOG_DEBUG, "WebCore", "Current cache has %d bytes live and %d bytes dead", cache()->getLiveSize(), cache()->getDeadSize());
-}
-#endif
-
-#ifdef ANDROID_PLUGINS
-KJS::Bindings::Instance* Frame::createScriptInstanceForWidget(Widget* widget)
-{
- if (widget->isFrameView())
- return 0;
-
- return static_cast<PluginViewAndroid*>(widget)->bindingInstance();
-}
-#endif
-
-FrameAndroid::FrameAndroid(Page* page, HTMLFrameOwnerElement* element, FrameLoaderClient* client)
- : Frame(page, element, client),
- m_bindingRoot(NULL), m_bridge(NULL)
-{
-}
-
-FrameAndroid::~FrameAndroid()
-{
- if (view() != NULL)
- view()->getWebCoreViewBridge()->removeFrameGeneration(this);
- Release(m_bridge);
- setView(0);
- loader()->clearRecordedFormValues();
-}
-
-void FrameAndroid::select(int selectionStart, int selectionEnd)
-{
- if (selectionStart > selectionEnd) {
- int temp = selectionStart;
- selectionStart = selectionEnd;
- selectionEnd = temp;
- }
- Document* doc = document();
- if (!doc)
- return;
- Node* focus = doc->focusedNode();
- if (!focus)
- return;
- RenderObject* renderer = focus->renderer();
- if (renderer && (renderer->isTextField() || renderer->isTextArea())) {
- RenderTextControl* rtc = static_cast<RenderTextControl*>(renderer);
- rtc->setSelectionRange(selectionStart, selectionEnd);
- Frame::revealSelection();
- }
-}
-
-void FrameAndroid::cleanupForFullLayout(RenderObject* obj)
-{
- recursiveCleanupForFullLayout(obj);
-}
-
-void FrameAndroid::recursiveCleanupForFullLayout(RenderObject* obj)
-{
- obj->setNeedsLayout(true, false);
-#ifdef ANDROID_LAYOUT
- if (obj->isTable())
- (static_cast<RenderTable *>(obj))->clearSingleColumn();
-#endif
- for (RenderObject* n = obj->firstChild(); n; n = n->nextSibling())
- recursiveCleanupForFullLayout(n);
-}
-
-KJS::Bindings::RootObject* FrameAndroid::bindingRootObject()
-{
- if (!m_bindingRoot)
- m_bindingRoot = KJS::Bindings::RootObject::create(0, scriptProxy()->globalObject()); // The root gets deleted by JavaScriptCore.
- ASSERT(settings()->isJavaScriptEnabled());
- // The root gets deleted by JavaScriptCore.
- m_bindingRoot = KJS::Bindings::RootObject::create(0, scriptProxy()->globalObject());
- return m_bindingRoot.get();
-}
-
-/*
-* This function provides the ability to add a Java class to Javascript and
-* expose it through the Window object.
-* The code to access the object would look something like: window.<objectName>.<class method>
-*/
-void FrameAndroid::addJavascriptInterface(void *javaVM, void* objectInstance, const char* objectNameStr)
-{
- // Obtain the window object from KJS
- KJS::Bindings::RootObject *root = bindingRootObject();
- KJS::JSObject *rootObject = root->globalObject();
- KJS::ExecState *exec = root->globalObject()->globalExec();
- KJS::JSObject *window = rootObject->get(exec, KJS::Identifier("window"))->getObject();
- if (!window) {
- LOGE("Warning: couldn't get window object");
- return;
- }
-
- KJS::Bindings::setJavaVM((JavaVM*)javaVM);
-
- // Add the binding to JS environment
- KJS::JSObject *addedObject =
- KJS::Bindings::Instance::createRuntimeObject(KJS::Bindings::Instance::JavaLanguage,
- (jobject)objectInstance, root);
-
- // Add the binding name to the window's table of child objects.
- window->put(exec, KJS::Identifier(objectNameStr), addedObject);
-}
-
-/*
-* This function executes the provided javascript string in the context of
-* the frame's document. The code is based on the implementation of the same
-* function in WebCoreFrameBridge.mm
-*/
-String FrameAndroid::stringByEvaluatingJavaScriptFromString(const char* script)
-{
- ASSERT(document());
- JSValue* result = loader()->executeScript(String(script), true);
- if (!result)
- return String();
- JSLock lock;
- // note: result->getString() returns a UString.
- return String(result->isString() ? result->getString() :
- result->toString(scriptProxy()->globalObject()->globalExec()));
-}
-
-#if 0 // disabled for now by <reed>
-// experimental function to allow portable code to query our bg-ness
-bool android_should_draw_background(RenderObject* obj)
-{
- Document* doc = obj->document();
- if (doc) {
- Frame* frame = doc->frame();
- if (frame) {
- Page* page = frame->page();
- if (page) {
- frame = page->mainFrame();
- if (frame) {
- return AsAndroidFrame(frame)->shouldDrawBackgroundPhase();
- }
- }
- }
- }
- return false;
-}
-#endif
-
-///////////////!!!!!!!!!!!! MUST COMPLETE THESE
-
-#define verifiedOk() { } // not a problem that it's not implemented
-
-// These two functions are called by JavaScript Window.focus() and Window.blur() methods. If
-// a window has the window focus method called on it, it should be moved to the top of the
-// browser window stack. If blur is called, it is moved to the bottom of the stack.
-void FrameAndroid::focusWindow() { verifiedOk(); notImplemented(); }
-void FrameAndroid::unfocusWindow() { verifiedOk(); notImplemented(); }
-
-// This function is called by JavaScript when window.print() is called. It would normally map
-// straight to the menu print item.
-// It is ok that we don't support this at this time.
-void FrameAndroid::print() { verifiedOk(); }
-
-// These functions are used to interact with the platform's clipboard. It is ok that we don't
-// support these at this time as we currently don't support sites that would use this
-// functionality.
-void FrameAndroid::issueCutCommand() { verifiedOk(); }
-void FrameAndroid::issueCopyCommand() { verifiedOk(); }
-void FrameAndroid::issuePasteCommand() { verifiedOk(); }
-void FrameAndroid::issuePasteAndMatchStyleCommand() { verifiedOk(); }
-
-// This function seems to switch the two characters around the cursor.
-// See WebHTMLView.mm:transpose.
-// We are currently not implementing it.
-void FrameAndroid::issueTransposeCommand() { verifiedOk(); }
-
-// These functions are called when JavaScript tries to access the script interface for
-// these objects. For Object and Embed, the interface expected from the 'plugin' is
-// well defined here:
-// http://www.mozilla.org/projects/plugins/npruntime.html
-KJS::Bindings::Instance* FrameAndroid::getObjectInstanceForWidget(Widget *) { ASSERT(0); notImplemented(); return 0; }
-KJS::Bindings::Instance* FrameAndroid::getEmbedInstanceForWidget(Widget *) { ASSERT(0); notImplemented(); return 0; }
-KJS::Bindings::Instance* FrameAndroid::getAppletInstanceForWidget(Widget*) { ASSERT(0); notImplemented(); return 0; }
-
-// These two functions are used to handle spell checking and context menus on selected text.
-// It seems that if the text is selected, and the user tries to change the selection, the
-// shouldChange function indicates if it is allowed or not. The second function is used for
-// spell checking - check FrameMac.mm implementation for details.
-bool FrameAndroid::shouldChangeSelection(Selection const&,Selection const&,EAffinity,bool) const { notImplemented(); return true; }
-void FrameAndroid::respondToChangedSelection(Selection const&,bool) { notImplemented(); }
-
-// This function is called when an textbox needs to find out if it's contents
-// is marked. It is used in conjunction with the set method which uses
-// NSArray, a Mac specific type. The set method is called whenever text is
-// added (not removed) via a single key press (paste does not count)
-Range* FrameAndroid::markedTextRange() const { return 0; }
-
-// This function is called when determining the correct mimetype for a file that is going
-// to be POSTed. That is when the form element <input type="file"> is used, and the file is
-// being sent the server, the client should set the mimetype of the file.
-String FrameAndroid::mimeTypeForFileName(String const&) const { ASSERT(0); notImplemented(); return String(); }
-
-}; /* WebCore namespace */
diff --git a/WebCore/page/android/FrameAndroid.h b/WebCore/page/android/FrameAndroid.h
deleted file mode 100644
index c0948df..0000000
--- a/WebCore/page/android/FrameAndroid.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#ifndef FrameAndroid_H
-#define FrameAndroid_H
-
-#include "CacheBuilder.h"
-#include "Frame.h"
-#include "FrameLoaderTypes.h"
-#include "PlatformGraphicsContext.h"
-#include "Plugin.h"
-#include "StringHash.h"
-#include "WebCoreFrameBridge.h"
-
-class WebCoreResourceHandleClientBridge;
-
-namespace KJS {
- namespace Bindings {
- class RootObject;
- }
-}
-
-namespace WebCore {
-
-class EditCommand;
-class MouseEventWithHitTestResults;
-class Node;
-class ResourceHandle;
-class ResourceRequest;
-struct LinkArray;
-struct LinkArray;
-
-enum KWQSelectionDirection {
- KWQSelectingNext,
- KWQSelectingPrevious
-};
-
-class FrameAndroid : public Frame
-{
-public:
- FrameAndroid(Page*, HTMLFrameOwnerElement*, FrameLoaderClient*);
- virtual ~FrameAndroid();
-
- /* WebCoreFrameBridge setter and getter */
- inline void setBridge(android::WebCoreFrameBridge* bridge)
- {
- Release(m_bridge);
- m_bridge = bridge;
- Retain(m_bridge);
- }
- inline android::WebCoreFrameBridge* bridge() const { return m_bridge; }
-
- virtual void focusWindow();
- virtual void unfocusWindow();
-
- virtual Range* markedTextRange() const;
-
- virtual String mimeTypeForFileName(const String&) const;
-
- virtual KJS::Bindings::Instance* getEmbedInstanceForWidget(Widget*);
- virtual KJS::Bindings::Instance* getObjectInstanceForWidget(Widget*);
- virtual KJS::Bindings::Instance* getAppletInstanceForWidget(Widget*);
- virtual KJS::Bindings::RootObject* bindingRootObject();
-
- virtual void issueCutCommand();
- virtual void issueCopyCommand();
- virtual void issuePasteCommand();
- virtual void issuePasteAndMatchStyleCommand();
- virtual void issueTransposeCommand();
- virtual void respondToChangedSelection(const Selection& oldSelection, bool closeTyping);
- virtual bool shouldChangeSelection(const Selection& oldSelection,
- const Selection& newSelection,
- EAffinity affinity,
- bool stillSelecting) const;
-
- virtual void print();
-
- void addJavascriptInterface(void* javaVM, void* objectInstance, const char* objectNameStr);
- String stringByEvaluatingJavaScriptFromString(const char* script);
-
- /* FrameAndroid specific */
- CacheBuilder& getCacheBuilder() { return m_cacheBuilder; }
- void select(int, int);
-
- void cleanupForFullLayout(RenderObject *);
-
-private:
- static void recursiveCleanupForFullLayout(RenderObject *);
-
- RefPtr<KJS::Bindings::RootObject> m_bindingRoot; // The root object used for objects
- // bound outside the context of a plugin.
- /* End FrameAndroid specific */
-
- android::WebCoreFrameBridge* m_bridge;
- CacheBuilder m_cacheBuilder;
- friend class CacheBuilder;
-};
-
-inline FrameAndroid* Android(Frame* frame) { return static_cast<FrameAndroid*>(frame); }
-inline const FrameAndroid* Android(const Frame* frame) { return static_cast<const FrameAndroid*>(frame); }
-
-inline FrameAndroid* AsAndroidFrame(Frame* frame) { return static_cast<FrameAndroid*>(frame); }
-
-}
-
-#endif
diff --git a/WebCore/page/android/InspectorControllerAndroid.cpp b/WebCore/page/android/InspectorControllerAndroid.cpp
index b39d32b..c3b88b7 100644
--- a/WebCore/page/android/InspectorControllerAndroid.cpp
+++ b/WebCore/page/android/InspectorControllerAndroid.cpp
@@ -19,6 +19,7 @@
#include "InspectorController.h"
#include "Frame.h"
#include "Node.h"
+#include "Profile.h"
/*
// This stub file was created to avoid building and linking in all the
@@ -53,7 +54,8 @@ struct InspectorResource : public RefCounted<InspectorResource> {
struct InspectorDatabaseResource : public RefCounted<InspectorDatabaseResource> {
};
-InspectorController::InspectorController(Page*, InspectorClient*) {}
+InspectorController::InspectorController(Page*, InspectorClient*) :
+ m_startProfiling(this, NULL) {}
InspectorController::~InspectorController() {}
void InspectorController::windowScriptObjectAvailable() {}
@@ -66,12 +68,30 @@ void InspectorController::didFinishLoading(DocumentLoader*, unsigned long) {}
void InspectorController::didLoadResourceFromMemoryCache(DocumentLoader*, ResourceRequest const&, ResourceResponse const&, int) {}
void InspectorController::frameDetachedFromParent(Frame*) {}
-void InspectorController::addMessageToConsole(MessageSource, MessageLevel, String const&, unsigned int, String const&) {}
+void InspectorController::addMessageToConsole(MessageSource, MessageLevel, JSC::ExecState*, JSC::ArgList const&, unsigned int, String const&) {}
+void InspectorController::addMessageToConsole(MessageSource, MessageLevel, const String& message, unsigned lineNumber, const String& sourceID) {}
#if ENABLE(DATABASE)
void InspectorController::didOpenDatabase(Database*, String const&, String const&, String const&) {}
#endif
bool InspectorController::enabled() const { return false; }
void InspectorController::inspect(Node*) {}
bool InspectorController::windowVisible() { return false; }
+void InspectorController::addProfile(PassRefPtr<JSC::Profile>, unsigned int, const JSC::UString&) {}
+void InspectorController::inspectedPageDestroyed() {}
+void InspectorController::resourceRetrievedByXMLHttpRequest(unsigned long identifier, JSC::UString& sourceString) {}
+ // new as of SVN change 36269, Sept 8, 2008
+void InspectorController::inspectedWindowScriptObjectCleared(Frame* frame) {}
+void InspectorController::startGroup(MessageSource source, JSC::ExecState* exec, const JSC::ArgList& arguments, unsigned lineNumber, const String& sourceURL) {}
+void InspectorController::endGroup(MessageSource source, unsigned lineNumber, const String& sourceURL) {}
+void InspectorController::startTiming(const JSC::UString& title) {}
+bool InspectorController::stopTiming(const JSC::UString& title, double& elapsed) { return false; }
+void InspectorController::count(const JSC::UString& title, unsigned lineNumber, const String& sourceID) {}
+
+ // new as of SVN change 38068, Nov 5, 2008
+void InspectorController::mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags) {}
+void InspectorController::handleMousePressOnNode(Node*) {}
+void InspectorController::failedToParseSource(JSC::ExecState* exec, const JSC::SourceCode& source, int errorLine, const JSC::UString& errorMessage) {}
+void InspectorController::didParseSource(JSC::ExecState* exec, const JSC::SourceCode& source) {}
+void InspectorController::didPause() {}
}
diff --git a/WebCore/page/animation/AnimationBase.cpp b/WebCore/page/animation/AnimationBase.cpp
new file mode 100644
index 0000000..fc28469
--- /dev/null
+++ b/WebCore/page/animation/AnimationBase.cpp
@@ -0,0 +1,815 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AnimationBase.h"
+
+#include "AnimationController.h"
+#include "CSSPropertyNames.h"
+#include "CString.h"
+#include "CompositeAnimation.h"
+#include "Document.h"
+#include "EventNames.h"
+#include "FloatConversion.h"
+#include "Frame.h"
+#include "IdentityTransformOperation.h"
+#include "ImplicitAnimation.h"
+#include "KeyframeAnimation.h"
+#include "MatrixTransformOperation.h"
+#include "RenderObject.h"
+#include "RenderStyle.h"
+#include "SystemTime.h"
+#include "UnitBezier.h"
+
+namespace WebCore {
+
+static const double cAnimationTimerDelay = 0.025;
+
+// The epsilon value we pass to UnitBezier::solve given that the animation is going to run over |dur| seconds. The longer the
+// animation, the more precision we need in the timing function result to avoid ugly discontinuities.
+static inline double solveEpsilon(double duration)
+{
+ return 1.0 / (200.0 * duration);
+}
+
+static inline double solveCubicBezierFunction(double p1x, double p1y, double p2x, double p2y, double t, double duration)
+{
+ // Convert from input time to parametric value in curve, then from
+ // that to output time.
+ UnitBezier bezier(p1x, p1y, p2x, p2y);
+ return bezier.solve(t, solveEpsilon(duration));
+}
+
+void AnimationTimerCallback::timerFired(Timer<AnimationTimerBase>*)
+{
+ m_anim->animationTimerCallbackFired(m_eventType, m_elapsedTime);
+}
+
+static inline int blendFunc(const AnimationBase* anim, int from, int to, double progress)
+{
+ return int(from + (to - from) * progress);
+}
+
+static inline double blendFunc(const AnimationBase* anim, double from, double to, double progress)
+{
+ return from + (to - from) * progress;
+}
+
+static inline float blendFunc(const AnimationBase* anim, float from, float to, double progress)
+{
+ return narrowPrecisionToFloat(from + (to - from) * progress);
+}
+
+static inline Color blendFunc(const AnimationBase* anim, const Color& from, const Color& to, double progress)
+{
+ 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));
+}
+
+static inline Length blendFunc(const AnimationBase* anim, const Length& from, const Length& to, double progress)
+{
+ return to.blend(from, progress);
+}
+
+static inline IntSize blendFunc(const AnimationBase* anim, const IntSize& from, const IntSize& to, double progress)
+{
+ return IntSize(blendFunc(anim, from.width(), to.width(), progress),
+ blendFunc(anim, from.height(), to.height(), progress));
+}
+
+static inline ShadowData* blendFunc(const AnimationBase* anim, const ShadowData* from, const ShadowData* to, double progress)
+{
+ ASSERT(from && to);
+ return new ShadowData(blendFunc(anim, from->x, to->x, progress), blendFunc(anim, from->y, to->y, progress),
+ blendFunc(anim, from->blur, to->blur, progress), blendFunc(anim, from->color, to->color, progress));
+}
+
+static inline TransformOperations blendFunc(const AnimationBase* anim, const TransformOperations& from, const TransformOperations& to, double progress)
+{
+ TransformOperations result;
+
+ // If we have a transform function list, use that to do a per-function animation. Otherwise do a Matrix animation
+ if (anim->isTransformFunctionListValid()) {
+ unsigned fromSize = from.operations().size();
+ unsigned toSize = to.operations().size();
+ unsigned size = max(fromSize, toSize);
+ for (unsigned i = 0; i < size; i++) {
+ RefPtr<TransformOperation> fromOp = (i < fromSize) ? from.operations()[i].get() : 0;
+ RefPtr<TransformOperation> toOp = (i < toSize) ? to.operations()[i].get() : 0;
+ RefPtr<TransformOperation> blendedOp = toOp ? toOp->blend(fromOp.get(), progress) : (fromOp ? fromOp->blend(0, progress, true) : 0);
+ if (blendedOp)
+ result.operations().append(blendedOp);
+ else {
+ RefPtr<TransformOperation> identityOp = IdentityTransformOperation::create();
+ if (progress > 0.5)
+ result.operations().append(toOp ? toOp : identityOp);
+ else
+ result.operations().append(fromOp ? fromOp : identityOp);
+ }
+ }
+ } else {
+ // Convert the TransformOperations into matrices
+ IntSize size = anim->renderer()->borderBox().size();
+ AffineTransform fromT;
+ AffineTransform toT;
+ from.apply(size, fromT);
+ to.apply(size, toT);
+
+ toT.blend(fromT, progress);
+
+ // Append the result
+ result.operations().append(MatrixTransformOperation::create(toT.a(), toT.b(), toT.c(), toT.d(), toT.e(), toT.f()));
+ }
+ return result;
+}
+
+static inline EVisibility blendFunc(const AnimationBase* anim, EVisibility from, EVisibility to, double progress)
+{
+ // Any non-zero result means we consider the object to be visible. Only at 0 do we consider the object to be
+ // invisible. The invisible value we use (HIDDEN vs. COLLAPSE) depends on the specified from/to values.
+ double fromVal = from == VISIBLE ? 1. : 0.;
+ double toVal = to == VISIBLE ? 1. : 0.;
+ if (fromVal == toVal)
+ return to;
+ double result = blendFunc(anim, fromVal, toVal, progress);
+ return result > 0. ? VISIBLE : (to != VISIBLE ? to : from);
+}
+
+class PropertyWrapperBase {
+public:
+ PropertyWrapperBase(int prop)
+ : m_prop(prop)
+ {
+ }
+
+ virtual ~PropertyWrapperBase() { }
+ virtual bool equals(const RenderStyle* a, const RenderStyle* b) const = 0;
+ virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const = 0;
+
+ int property() const { return m_prop; }
+
+private:
+ int m_prop;
+};
+
+template <typename T>
+class PropertyWrapperGetter : public PropertyWrapperBase {
+public:
+ PropertyWrapperGetter(int prop, T (RenderStyle::*getter)() const)
+ : PropertyWrapperBase(prop)
+ , m_getter(getter)
+ {
+ }
+
+ virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
+ {
+ // If the style pointers are the same, don't bother doing the test.
+ // If either is null, return false. If both are null, return true.
+ if (!a && !b || a == b)
+ return true;
+ if (!a || !b)
+ return false;
+ return (a->*m_getter)() == (b->*m_getter)();
+ }
+
+protected:
+ T (RenderStyle::*m_getter)() const;
+};
+
+template <typename T>
+class PropertyWrapper : public PropertyWrapperGetter<T> {
+public:
+ PropertyWrapper(int prop, T (RenderStyle::*getter)() const, void (RenderStyle::*setter)(T))
+ : PropertyWrapperGetter<T>(prop, getter)
+ , m_setter(setter)
+ {
+ }
+
+ virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const
+ {
+ (dst->*m_setter)(blendFunc(anim, (a->*PropertyWrapperGetter<T>::m_getter)(), (b->*PropertyWrapperGetter<T>::m_getter)(), progress));
+ }
+
+protected:
+ void (RenderStyle::*m_setter)(T);
+};
+
+class PropertyWrapperShadow : public PropertyWrapperGetter<ShadowData*> {
+public:
+ PropertyWrapperShadow(int prop, ShadowData* (RenderStyle::*getter)() const, void (RenderStyle::*setter)(ShadowData*, bool))
+ : PropertyWrapperGetter<ShadowData*>(prop, getter)
+ , m_setter(setter)
+ {
+ }
+
+ virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
+ {
+ ShadowData* shadowA = (a->*m_getter)();
+ ShadowData* shadowB = (b->*m_getter)();
+
+ if (!shadowA && shadowB || shadowA && !shadowB)
+ return false;
+ if (shadowA && shadowB && (*shadowA != *shadowB))
+ return false;
+ return true;
+ }
+
+ virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const
+ {
+ ShadowData* shadowA = (a->*m_getter)();
+ ShadowData* shadowB = (b->*m_getter)();
+ ShadowData defaultShadowData(0, 0, 0, Color::transparent);
+
+ if (!shadowA)
+ shadowA = &defaultShadowData;
+ if (!shadowB)
+ shadowB = &defaultShadowData;
+
+ (dst->*m_setter)(blendFunc(anim, shadowA, shadowB, progress), false);
+ }
+
+private:
+ void (RenderStyle::*m_setter)(ShadowData*, bool);
+};
+
+class PropertyWrapperMaybeInvalidColor : public PropertyWrapperBase {
+public:
+ PropertyWrapperMaybeInvalidColor(int prop, const Color& (RenderStyle::*getter)() const, void (RenderStyle::*setter)(const Color&))
+ : PropertyWrapperBase(prop)
+ , m_getter(getter)
+ , m_setter(setter)
+ {
+ }
+
+ virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
+ {
+ Color fromColor = (a->*m_getter)();
+ Color toColor = (b->*m_getter)();
+ if (!fromColor.isValid())
+ fromColor = a->color();
+ if (!toColor.isValid())
+ toColor = b->color();
+
+ return fromColor == toColor;
+ }
+
+ virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const
+ {
+ Color fromColor = (a->*m_getter)();
+ Color toColor = (b->*m_getter)();
+ if (!fromColor.isValid())
+ fromColor = a->color();
+ if (!toColor.isValid())
+ toColor = b->color();
+ (dst->*m_setter)(blendFunc(anim, fromColor, toColor, progress));
+ }
+
+private:
+ const Color& (RenderStyle::*m_getter)() const;
+ void (RenderStyle::*m_setter)(const Color&);
+};
+
+static Vector<PropertyWrapperBase*>* gPropertyWrappers = 0;
+static int gPropertyWrapperMap[numCSSProperties];
+
+static void ensurePropertyMap()
+{
+ // FIXME: This data is never destroyed. Maybe we should ref count it and toss it when the last AnimationController is destroyed?
+ if (gPropertyWrappers == 0) {
+ gPropertyWrappers = new Vector<PropertyWrapperBase*>();
+
+ // build the list of property wrappers to do the comparisons and blends
+ gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyLeft, &RenderStyle::left, &RenderStyle::setLeft));
+ gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyRight, &RenderStyle::right, &RenderStyle::setRight));
+ gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyTop, &RenderStyle::top, &RenderStyle::setTop));
+ gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyBottom, &RenderStyle::bottom, &RenderStyle::setBottom));
+ gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyWidth, &RenderStyle::width, &RenderStyle::setWidth));
+ gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyHeight, &RenderStyle::height, &RenderStyle::setHeight));
+ gPropertyWrappers->append(new PropertyWrapper<unsigned short>(CSSPropertyBorderLeftWidth, &RenderStyle::borderLeftWidth, &RenderStyle::setBorderLeftWidth));
+ gPropertyWrappers->append(new PropertyWrapper<unsigned short>(CSSPropertyBorderRightWidth, &RenderStyle::borderRightWidth, &RenderStyle::setBorderRightWidth));
+ gPropertyWrappers->append(new PropertyWrapper<unsigned short>(CSSPropertyBorderTopWidth, &RenderStyle::borderTopWidth, &RenderStyle::setBorderTopWidth));
+ gPropertyWrappers->append(new PropertyWrapper<unsigned short>(CSSPropertyBorderBottomWidth, &RenderStyle::borderBottomWidth, &RenderStyle::setBorderBottomWidth));
+ gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyMarginLeft, &RenderStyle::marginLeft, &RenderStyle::setMarginLeft));
+ gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyMarginRight, &RenderStyle::marginRight, &RenderStyle::setMarginRight));
+ gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyMarginTop, &RenderStyle::marginTop, &RenderStyle::setMarginTop));
+ gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyMarginBottom, &RenderStyle::marginBottom, &RenderStyle::setMarginBottom));
+ gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyPaddingLeft, &RenderStyle::paddingLeft, &RenderStyle::setPaddingLeft));
+ gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyPaddingRight, &RenderStyle::paddingRight, &RenderStyle::setPaddingRight));
+ gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyPaddingTop, &RenderStyle::paddingTop, &RenderStyle::setPaddingTop));
+ gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyPaddingBottom, &RenderStyle::paddingBottom, &RenderStyle::setPaddingBottom));
+ gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyOpacity, &RenderStyle::opacity, &RenderStyle::setOpacity));
+ gPropertyWrappers->append(new PropertyWrapper<const Color&>(CSSPropertyColor, &RenderStyle::color, &RenderStyle::setColor));
+ gPropertyWrappers->append(new PropertyWrapper<const Color&>(CSSPropertyBackgroundColor, &RenderStyle::backgroundColor, &RenderStyle::setBackgroundColor));
+ gPropertyWrappers->append(new PropertyWrapper<int>(CSSPropertyFontSize, &RenderStyle::fontSize, &RenderStyle::setBlendedFontSize));
+ gPropertyWrappers->append(new PropertyWrapper<unsigned short>(CSSPropertyWebkitColumnRuleWidth, &RenderStyle::columnRuleWidth, &RenderStyle::setColumnRuleWidth));
+ gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyWebkitColumnGap, &RenderStyle::columnGap, &RenderStyle::setColumnGap));
+ gPropertyWrappers->append(new PropertyWrapper<unsigned short>(CSSPropertyWebkitColumnCount, &RenderStyle::columnCount, &RenderStyle::setColumnCount));
+ gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyWebkitColumnWidth, &RenderStyle::columnWidth, &RenderStyle::setColumnWidth));
+ gPropertyWrappers->append(new PropertyWrapper<short>(CSSPropertyWebkitBorderHorizontalSpacing, &RenderStyle::horizontalBorderSpacing, &RenderStyle::setHorizontalBorderSpacing));
+ gPropertyWrappers->append(new PropertyWrapper<short>(CSSPropertyWebkitBorderVerticalSpacing, &RenderStyle::verticalBorderSpacing, &RenderStyle::setVerticalBorderSpacing));
+ gPropertyWrappers->append(new PropertyWrapper<int>(CSSPropertyZIndex, &RenderStyle::zIndex, &RenderStyle::setZIndex));
+ gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyLineHeight, &RenderStyle::lineHeight, &RenderStyle::setLineHeight));
+ gPropertyWrappers->append(new PropertyWrapper<int>(CSSPropertyOutlineOffset, &RenderStyle::outlineOffset, &RenderStyle::setOutlineOffset));
+ gPropertyWrappers->append(new PropertyWrapper<unsigned short>(CSSPropertyOutlineWidth, &RenderStyle::outlineWidth, &RenderStyle::setOutlineWidth));
+ gPropertyWrappers->append(new PropertyWrapper<int>(CSSPropertyLetterSpacing, &RenderStyle::letterSpacing, &RenderStyle::setLetterSpacing));
+ gPropertyWrappers->append(new PropertyWrapper<int>(CSSPropertyWordSpacing, &RenderStyle::wordSpacing, &RenderStyle::setWordSpacing));
+ gPropertyWrappers->append(new PropertyWrapper<const TransformOperations&>(CSSPropertyWebkitTransform, &RenderStyle::transform, &RenderStyle::setTransform));
+ gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyWebkitTransformOriginX, &RenderStyle::transformOriginX, &RenderStyle::setTransformOriginX));
+ gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyWebkitTransformOriginY, &RenderStyle::transformOriginY, &RenderStyle::setTransformOriginY));
+ gPropertyWrappers->append(new PropertyWrapper<const IntSize&>(CSSPropertyWebkitBorderTopLeftRadius, &RenderStyle::borderTopLeftRadius, &RenderStyle::setBorderTopLeftRadius));
+ gPropertyWrappers->append(new PropertyWrapper<const IntSize&>(CSSPropertyWebkitBorderTopRightRadius, &RenderStyle::borderTopRightRadius, &RenderStyle::setBorderTopRightRadius));
+ gPropertyWrappers->append(new PropertyWrapper<const IntSize&>(CSSPropertyWebkitBorderBottomLeftRadius, &RenderStyle::borderBottomLeftRadius, &RenderStyle::setBorderBottomLeftRadius));
+ gPropertyWrappers->append(new PropertyWrapper<const IntSize&>(CSSPropertyWebkitBorderBottomRightRadius, &RenderStyle::borderBottomRightRadius, &RenderStyle::setBorderBottomRightRadius));
+ gPropertyWrappers->append(new PropertyWrapper<EVisibility>(CSSPropertyVisibility, &RenderStyle::visibility, &RenderStyle::setVisibility));
+ gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyZoom, &RenderStyle::zoom, &RenderStyle::setZoom));
+ gPropertyWrappers->append(new PropertyWrapperMaybeInvalidColor(CSSPropertyWebkitColumnRuleColor, &RenderStyle::columnRuleColor, &RenderStyle::setColumnRuleColor));
+ gPropertyWrappers->append(new PropertyWrapperMaybeInvalidColor(CSSPropertyWebkitTextStrokeColor, &RenderStyle::textStrokeColor, &RenderStyle::setTextStrokeColor));
+ gPropertyWrappers->append(new PropertyWrapperMaybeInvalidColor(CSSPropertyWebkitTextFillColor, &RenderStyle::textFillColor, &RenderStyle::setTextFillColor));
+ gPropertyWrappers->append(new PropertyWrapperMaybeInvalidColor(CSSPropertyBorderLeftColor, &RenderStyle::borderLeftColor, &RenderStyle::setBorderLeftColor));
+ gPropertyWrappers->append(new PropertyWrapperMaybeInvalidColor(CSSPropertyBorderRightColor, &RenderStyle::borderRightColor, &RenderStyle::setBorderRightColor));
+ gPropertyWrappers->append(new PropertyWrapperMaybeInvalidColor(CSSPropertyBorderTopColor, &RenderStyle::borderTopColor, &RenderStyle::setBorderTopColor));
+ gPropertyWrappers->append(new PropertyWrapperMaybeInvalidColor(CSSPropertyBorderBottomColor, &RenderStyle::borderBottomColor, &RenderStyle::setBorderBottomColor));
+ gPropertyWrappers->append(new PropertyWrapperMaybeInvalidColor(CSSPropertyOutlineColor, &RenderStyle::outlineColor, &RenderStyle::setOutlineColor));
+
+ // These are for shadows
+ gPropertyWrappers->append(new PropertyWrapperShadow(CSSPropertyWebkitBoxShadow, &RenderStyle::boxShadow, &RenderStyle::setBoxShadow));
+ gPropertyWrappers->append(new PropertyWrapperShadow(CSSPropertyTextShadow, &RenderStyle::textShadow, &RenderStyle::setTextShadow));
+
+#if ENABLE(SVG)
+ gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyFillOpacity, &RenderStyle::fillOpacity, &RenderStyle::setFillOpacity));
+ gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyFloodOpacity, &RenderStyle::floodOpacity, &RenderStyle::setFloodOpacity));
+ gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyStrokeOpacity, &RenderStyle::strokeOpacity, &RenderStyle::setStrokeOpacity));
+#endif
+
+ // Make sure unused slots have a value
+ for (unsigned int i = 0; i < (unsigned int) numCSSProperties; ++i)
+ gPropertyWrapperMap[i] = CSSPropertyInvalid;
+
+ size_t n = gPropertyWrappers->size();
+ for (unsigned int i = 0; i < n; ++i) {
+ ASSERT((*gPropertyWrappers)[i]->property() - firstCSSProperty < numCSSProperties);
+ gPropertyWrapperMap[(*gPropertyWrappers)[i]->property() - firstCSSProperty] = i;
+ }
+ }
+}
+
+AnimationBase::AnimationBase(const Animation* transition, RenderObject* renderer, CompositeAnimation* compAnim)
+ : m_animState(AnimationStateNew)
+ , m_iteration(0)
+ , m_isAnimating(false)
+ , m_waitedForResponse(false)
+ , m_startTime(0)
+ , m_pauseTime(-1)
+ , m_object(renderer)
+ , m_animationTimerCallback(const_cast<AnimationBase*>(this))
+ , m_animation(const_cast<Animation*>(transition))
+ , m_compAnim(compAnim)
+ , m_transformFunctionListValid(false)
+{
+}
+
+AnimationBase::~AnimationBase()
+{
+ if (m_animState == AnimationStateStartWaitStyleAvailable)
+ m_compAnim->setWaitingForStyleAvailable(false);
+}
+
+bool AnimationBase::propertiesEqual(int prop, const RenderStyle* a, const RenderStyle* b)
+{
+ ensurePropertyMap();
+ if (prop == cAnimateAll) {
+ size_t n = gPropertyWrappers->size();
+ for (unsigned int i = 0; i < n; ++i) {
+ if (!(*gPropertyWrappers)[i]->equals(a, b))
+ return false;
+ }
+ } else {
+ int propIndex = prop - firstCSSProperty;
+
+ if (propIndex >= 0 && propIndex < numCSSProperties) {
+ int i = gPropertyWrapperMap[propIndex];
+ return i >= 0 ? (*gPropertyWrappers)[i]->equals(a, b) : true;
+ }
+ }
+ return true;
+}
+
+int AnimationBase::getPropertyAtIndex(int i)
+{
+ ensurePropertyMap();
+ if (i < 0 || i >= static_cast<int>(gPropertyWrappers->size()))
+ return CSSPropertyInvalid;
+
+ return (*gPropertyWrappers)[i]->property();
+}
+
+int AnimationBase::getNumProperties()
+{
+ ensurePropertyMap();
+ return gPropertyWrappers->size();
+}
+
+// Returns true if we need to start animation timers
+bool AnimationBase::blendProperties(const AnimationBase* anim, int prop, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress)
+{
+ ASSERT(prop != cAnimateAll);
+ // FIXME: Why can this happen?
+
+ ensurePropertyMap();
+ if (prop == cAnimateAll) {
+ bool needsTimer = false;
+
+ size_t n = gPropertyWrappers->size();
+ for (unsigned int i = 0; i < n; ++i) {
+ PropertyWrapperBase* wrapper = (*gPropertyWrappers)[i];
+ if (!wrapper->equals(a, b)) {
+ wrapper->blend(anim, dst, a, b, progress);
+ needsTimer = true;
+ }
+ }
+ return needsTimer;
+ }
+
+ int propIndex = prop - firstCSSProperty;
+ if (propIndex >= 0 && propIndex < numCSSProperties) {
+ int i = gPropertyWrapperMap[propIndex];
+ if (i >= 0) {
+ PropertyWrapperBase* wrapper = (*gPropertyWrappers)[i];
+ wrapper->blend(anim, dst, a, b, progress);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void AnimationBase::setChanged(Node* node)
+{
+ ASSERT(!node || (node->document() && !node->document()->inPageCache()));
+ node->setChanged(AnimationStyleChange);
+}
+
+double AnimationBase::duration() const
+{
+ return m_animation->duration();
+}
+
+bool AnimationBase::playStatePlaying() const
+{
+ return m_animation && m_animation->playState() == AnimPlayStatePlaying;
+}
+
+bool AnimationBase::animationsMatch(const Animation* anim) const
+{
+ return m_animation->animationsMatch(anim);
+}
+
+void AnimationBase::updateStateMachine(AnimStateInput input, double param)
+{
+ // If we get AnimationStateInputRestartAnimation then we force a new animation, regardless of state.
+ if (input == AnimationStateInputMakeNew) {
+ if (m_animState == AnimationStateStartWaitStyleAvailable)
+ m_compAnim->setWaitingForStyleAvailable(false);
+ m_animState = AnimationStateNew;
+ m_startTime = 0;
+ m_pauseTime = -1;
+ m_waitedForResponse = false;
+ endAnimation(false);
+ return;
+ }
+
+ if (input == AnimationStateInputRestartAnimation) {
+ cancelTimers();
+ if (m_animState == AnimationStateStartWaitStyleAvailable)
+ m_compAnim->setWaitingForStyleAvailable(false);
+ m_animState = AnimationStateNew;
+ m_startTime = 0;
+ m_pauseTime = -1;
+ endAnimation(false);
+
+ if (!paused())
+ updateStateMachine(AnimationStateInputStartAnimation, -1);
+ return;
+ }
+
+ if (input == AnimationStateInputEndAnimation) {
+ cancelTimers();
+ if (m_animState == AnimationStateStartWaitStyleAvailable)
+ m_compAnim->setWaitingForStyleAvailable(false);
+ m_animState = AnimationStateDone;
+ endAnimation(true);
+ return;
+ }
+
+ if (input == AnimationStateInputPauseOverride) {
+ 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);
+ updateStateMachine(AnimationStateInputStartTimeSet, currentTime());
+ }
+ return;
+ }
+
+ if (input == AnimationStateInputResumeOverride) {
+ if (m_animState == AnimationStateLooping || m_animState == AnimationStateEnding) {
+ // Start the animation
+ startAnimation(m_startTime);
+ }
+ return;
+ }
+
+ // Execute state machine
+ switch(m_animState) {
+ case AnimationStateNew:
+ ASSERT(input == AnimationStateInputStartAnimation || input == AnimationStateInputPlayStateRunnning || input == AnimationStateInputPlayStatePaused);
+ if (input == AnimationStateInputStartAnimation || input == AnimationStateInputPlayStateRunnning) {
+ // Set the start timer to the initial delay (0 if no delay)
+ m_waitedForResponse = false;
+ m_animState = AnimationStateStartWaitTimer;
+ m_animationTimerCallback.startTimer(m_animation->delay(), eventNames().webkitAnimationStartEvent, m_animation->delay());
+ }
+ break;
+ case AnimationStateStartWaitTimer:
+ ASSERT(input == AnimationStateInputStartTimerFired || input == AnimationStateInputPlayStatePaused);
+
+ if (input == AnimationStateInputStartTimerFired) {
+ ASSERT(param >= 0);
+ // Start timer has fired, tell the animation to start and wait for it to respond with start time
+ m_animState = AnimationStateStartWaitStyleAvailable;
+ m_compAnim->setWaitingForStyleAvailable(true);
+
+ // Trigger a render so we can start the animation
+ setChanged(m_object->element());
+ m_object->animation()->startUpdateRenderingDispatcher();
+ } else {
+ ASSERT(!paused());
+ // We're waiting for the start timer to fire and we got a pause. Cancel the timer, pause and wait
+ m_pauseTime = currentTime();
+ cancelTimers();
+ m_animState = AnimationStatePausedWaitTimer;
+ }
+ break;
+ case AnimationStateStartWaitStyleAvailable:
+ ASSERT(input == AnimationStateInputStyleAvailable || input == AnimationStateInputPlayStatePaused);
+
+ m_compAnim->setWaitingForStyleAvailable(false);
+
+ if (input == AnimationStateInputStyleAvailable) {
+ // Start timer has fired, tell the animation to start and wait for it to respond with start time
+ m_animState = AnimationStateStartWaitResponse;
+
+ overrideAnimations();
+
+ // Send start event, if needed
+ onAnimationStart(0); // The elapsedTime is always 0 here
+
+ // Start the animation
+ if (overridden() || !startAnimation(0)) {
+ // We're not going to get a startTime callback, so fire the start time here
+ m_animState = AnimationStateStartWaitResponse;
+ updateStateMachine(AnimationStateInputStartTimeSet, currentTime());
+ } else
+ m_waitedForResponse = true;
+ } else {
+ ASSERT(!paused());
+ // We're waiting for the a notification that the style has been setup. If we're asked to wait
+ // at this point, the style must have been processed, so we can deal with this like we would
+ // for WAIT_RESPONSE, except that we don't need to do an endAnimation().
+ m_pauseTime = 0;
+ m_animState = AnimationStateStartWaitResponse;
+ }
+ break;
+ case AnimationStateStartWaitResponse:
+ ASSERT(input == AnimationStateInputStartTimeSet || input == AnimationStateInputPlayStatePaused);
+
+ if (input == AnimationStateInputStartTimeSet) {
+ ASSERT(param >= 0);
+ // We have a start time, set it, unless the startTime is already set
+ if (m_startTime <= 0)
+ m_startTime = param;
+
+ // Decide when the end or loop event needs to fire
+ primeEventTimers();
+
+ // Trigger a render so we can start the animation
+ setChanged(m_object->element());
+ m_object->animation()->startUpdateRenderingDispatcher();
+ } else {
+ // 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 = 0;
+ endAnimation(false);
+ m_animState = AnimationStatePausedWaitResponse;
+ }
+ break;
+ case AnimationStateLooping:
+ ASSERT(input == AnimationStateInputLoopTimerFired || input == AnimationStateInputPlayStatePaused);
+
+ if (input == AnimationStateInputLoopTimerFired) {
+ ASSERT(param >= 0);
+ // Loop timer fired, loop again or end.
+ onAnimationIteration(param);
+ primeEventTimers();
+ } else {
+ // We are pausing while running. Cancel the animation and wait
+ m_pauseTime = currentTime();
+ cancelTimers();
+ endAnimation(false);
+ m_animState = AnimationStatePausedRun;
+ }
+ break;
+ case AnimationStateEnding:
+ ASSERT(input == AnimationStateInputEndTimerFired || input == AnimationStateInputPlayStatePaused);
+
+ if (input == AnimationStateInputEndTimerFired) {
+ ASSERT(param >= 0);
+ // End timer fired, finish up
+ onAnimationEnd(param);
+
+ resumeOverriddenAnimations();
+
+ // Fire off another style change so we can set the final value
+ setChanged(m_object->element());
+ m_animState = AnimationStateDone;
+ m_object->animation()->startUpdateRenderingDispatcher();
+ // |this| may be deleted here when we've been called from timerFired()
+ } else {
+ // We are pausing while running. Cancel the animation and wait
+ m_pauseTime = currentTime();
+ cancelTimers();
+ endAnimation(false);
+ m_animState = AnimationStatePausedRun;
+ }
+ // |this| may be deleted here
+ break;
+ case AnimationStatePausedWaitTimer:
+ ASSERT(input == AnimationStateInputPlayStateRunnning);
+ ASSERT(paused());
+ // Update the times
+ m_startTime += currentTime() - m_pauseTime;
+ m_pauseTime = -1;
+
+ // we were waiting for the start timer to fire, go back and wait again
+ m_animState = AnimationStateNew;
+ updateStateMachine(AnimationStateInputStartAnimation, 0);
+ break;
+ case AnimationStatePausedWaitResponse:
+ case AnimationStatePausedRun:
+ // We treat these two cases the same. The only difference is that, when we are in
+ // AnimationStatePausedWaitResponse, we don't yet have a valid startTime, so we send 0 to startAnimation.
+ // When the AnimationStateInputStartTimeSet comes in and we were in AnimationStatePausedRun, we will notice
+ // that we have already set the startTime and will ignore it.
+ ASSERT(input == AnimationStateInputPlayStateRunnning);
+ ASSERT(paused());
+ // Update the times
+ if (m_animState == AnimationStatePausedRun)
+ m_startTime += currentTime() - m_pauseTime;
+ else
+ m_startTime = 0;
+ m_pauseTime = -1;
+
+ // We were waiting for a begin time response from the animation, go back and wait again
+ m_animState = AnimationStateStartWaitResponse;
+
+ // Start the animation
+ if (overridden() || !startAnimation(m_startTime)) {
+ // We're not going to get a startTime callback, so fire the start time here
+ updateStateMachine(AnimationStateInputStartTimeSet, currentTime());
+ } else
+ m_waitedForResponse = true;
+ break;
+ case AnimationStateDone:
+ // We're done. Stay in this state until we are deleted
+ break;
+ }
+ // |this| may be deleted here if we came out of AnimationStateEnding when we've been called from timerFired()
+}
+
+void AnimationBase::animationTimerCallbackFired(const AtomicString& eventType, double elapsedTime)
+{
+ ASSERT(m_object->document() && !m_object->document()->inPageCache());
+
+ // FIXME: use an enum
+ if (eventType == eventNames().webkitAnimationStartEvent)
+ updateStateMachine(AnimationStateInputStartTimerFired, elapsedTime);
+ else if (eventType == eventNames().webkitAnimationIterationEvent)
+ updateStateMachine(AnimationStateInputLoopTimerFired, elapsedTime);
+ else if (eventType == eventNames().webkitAnimationEndEvent) {
+ updateStateMachine(AnimationStateInputEndTimerFired, elapsedTime);
+ // |this| may be deleted here
+ }
+}
+
+void AnimationBase::updatePlayState(bool run)
+{
+ if (paused() == run || isNew())
+ updateStateMachine(run ? AnimationStateInputPlayStateRunnning : AnimationStateInputPlayStatePaused, -1);
+}
+
+double AnimationBase::progress(double scale, double offset, const TimingFunction* tf) const
+{
+ if (preActive())
+ return 0;
+
+ double elapsedTime = running() ? (currentTime() - m_startTime) : (m_pauseTime - m_startTime);
+ if (running() && elapsedTime < 0)
+ return 0;
+
+ double dur = m_animation->duration();
+ if (m_animation->iterationCount() > 0)
+ dur *= m_animation->iterationCount();
+
+ if (postActive() || !m_animation->duration() || (m_animation->iterationCount() > 0 && elapsedTime >= dur))
+ return 1.0;
+
+ // Compute the fractional time, taking into account direction.
+ // There is no need to worry about iterations, we assume that we would have
+ // short circuited above if we were done.
+ double fractionalTime = elapsedTime / m_animation->duration();
+ int integralTime = static_cast<int>(fractionalTime);
+ fractionalTime -= integralTime;
+
+ if (m_animation->direction() && (integralTime & 1))
+ fractionalTime = 1 - fractionalTime;
+
+ if (scale != 1 || offset)
+ fractionalTime = (fractionalTime - offset) * scale;
+
+ if (!tf)
+ tf = &m_animation->timingFunction();
+
+ if (tf->type() == LinearTimingFunction)
+ return fractionalTime;
+
+ // Cubic bezier.
+ double result = solveCubicBezierFunction(tf->x1(),
+ tf->y1(),
+ tf->x2(),
+ tf->y2(),
+ fractionalTime, m_animation->duration());
+ return result;
+}
+
+void AnimationBase::primeEventTimers()
+{
+ // Decide when the end or loop event needs to fire
+ double ct = currentTime();
+ const double elapsedDuration = ct - m_startTime;
+ ASSERT(elapsedDuration >= 0);
+
+ double totalDuration = -1;
+ if (m_animation->iterationCount() > 0)
+ totalDuration = m_animation->duration() * m_animation->iterationCount();
+
+ double durationLeft = 0;
+ double nextIterationTime = totalDuration;
+ if (totalDuration < 0 || elapsedDuration < totalDuration) {
+ durationLeft = m_animation->duration() - fmod(elapsedDuration, m_animation->duration());
+ nextIterationTime = elapsedDuration + durationLeft;
+ }
+
+ // At this point, we may have 0 durationLeft, if we've gotten the event late and we are already
+ // past totalDuration. In this case we still fire an end timer before processing the end.
+ // This defers the call to sendAnimationEvents to avoid re-entrant calls that destroy
+ // the RenderObject, and therefore |this| before we're done with it.
+ if (totalDuration < 0 || nextIterationTime < totalDuration) {
+ // We are not at the end yet, send a loop event
+ ASSERT(nextIterationTime > 0);
+ m_animState = AnimationStateLooping;
+ m_animationTimerCallback.startTimer(durationLeft, eventNames().webkitAnimationIterationEvent, nextIterationTime);
+ } else {
+ // We are at the end, send an end event
+ m_animState = AnimationStateEnding;
+ m_animationTimerCallback.startTimer(durationLeft, eventNames().webkitAnimationEndEvent, nextIterationTime);
+ }
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/animation/AnimationBase.h b/WebCore/page/animation/AnimationBase.h
new file mode 100644
index 0000000..925c0d5
--- /dev/null
+++ b/WebCore/page/animation/AnimationBase.h
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 AnimationBase_h
+#define AnimationBase_h
+
+#include "AtomicString.h"
+#include "Timer.h"
+#include <wtf/HashMap.h>
+
+namespace WebCore {
+
+class Animation;
+class AnimationBase;
+class AnimationController;
+class CompositeAnimation;
+class Element;
+class Node;
+class RenderObject;
+class RenderStyle;
+class TimingFunction;
+
+class AnimationTimerBase {
+public:
+ AnimationTimerBase(AnimationBase* anim)
+ : m_timer(this, &AnimationTimerBase::timerFired)
+ , m_anim(anim)
+ {
+ m_timer.startOneShot(0);
+ }
+
+ virtual ~AnimationTimerBase() { }
+
+ void startTimer(double timeout = 0)
+ {
+ m_timer.startOneShot(timeout);
+ }
+
+ void cancelTimer()
+ {
+ m_timer.stop();
+ }
+
+ virtual void timerFired(Timer<AnimationTimerBase>*) = 0;
+
+private:
+ Timer<AnimationTimerBase> m_timer;
+
+protected:
+ AnimationBase* m_anim;
+};
+
+class AnimationTimerCallback : public AnimationTimerBase {
+public:
+ AnimationTimerCallback(AnimationBase* anim)
+ : AnimationTimerBase(anim)
+ , m_elapsedTime(0)
+ {
+ }
+
+ virtual ~AnimationTimerCallback() { }
+
+ virtual void timerFired(Timer<AnimationTimerBase>*);
+
+ void startTimer(double timeout, const AtomicString& eventType, double elapsedTime)
+ {
+ m_eventType = eventType;
+ m_elapsedTime = elapsedTime;
+ AnimationTimerBase::startTimer(timeout);
+ }
+
+private:
+ AtomicString m_eventType;
+ double m_elapsedTime;
+};
+
+class AnimationBase : public RefCounted<AnimationBase> {
+ friend class CompositeAnimationPrivate;
+
+public:
+ AnimationBase(const Animation* transition, RenderObject* renderer, CompositeAnimation* compAnim);
+ virtual ~AnimationBase();
+
+ RenderObject* renderer() const { return m_object; }
+ double startTime() const { return m_startTime; }
+ double duration() const;
+
+ void cancelTimers()
+ {
+ m_animationTimerCallback.cancelTimer();
+ }
+
+ // Animations and Transitions go through the states below. When entering the STARTED state
+ // the animation is started. This may or may not require deferred response from the animator.
+ // If so, we stay in this state until that response is received (and it returns the start time).
+ // Otherwise, we use the current time as the start time and go immediately to AnimationStateLooping
+ // or AnimationStateEnding.
+ enum AnimState {
+ AnimationStateNew, // animation just created, animation not running yet
+ AnimationStateStartWaitTimer, // start timer running, waiting for fire
+ AnimationStateStartWaitStyleAvailable, // waiting for style setup so we can start animations
+ AnimationStateStartWaitResponse, // animation started, waiting for response
+ AnimationStateLooping, // response received, animation running, loop timer running, waiting for fire
+ AnimationStateEnding, // received, animation running, end timer running, waiting for fire
+ AnimationStatePausedWaitTimer, // in pause mode when animation started
+ AnimationStatePausedWaitResponse, // animation paused when in STARTING state
+ AnimationStatePausedRun, // animation paused when in LOOPING or ENDING state
+ AnimationStateDone // end timer fired, animation finished and removed
+ };
+
+ enum AnimStateInput {
+ AnimationStateInputMakeNew, // reset back to new from any state
+ AnimationStateInputStartAnimation, // animation requests a start
+ AnimationStateInputRestartAnimation, // force a restart from any state
+ AnimationStateInputStartTimerFired, // start timer fired
+ AnimationStateInputStyleAvailable, // style is setup, ready to start animating
+ AnimationStateInputStartTimeSet, // m_startTime was set
+ AnimationStateInputLoopTimerFired, // loop timer fired
+ AnimationStateInputEndTimerFired, // end timer fired
+ AnimationStateInputPauseOverride, // pause an animation due to override
+ AnimationStateInputResumeOverride, // resume an overridden animation
+ AnimationStateInputPlayStateRunnning, // play state paused -> running
+ AnimationStateInputPlayStatePaused, // play state running -> paused
+ AnimationStateInputEndAnimation // force an end from any state
+ };
+
+ // Called when animation is in AnimationStateNew to start animation
+ void updateStateMachine(AnimStateInput, double param);
+
+ // Animation has actually started, at passed time
+ void onAnimationStartResponse(double startTime);
+
+ // Called to change to or from paused state
+ void updatePlayState(bool running);
+ bool playStatePlaying() const;
+
+ bool waitingToStart() const { return m_animState == AnimationStateNew || m_animState == AnimationStateStartWaitTimer; }
+ bool preActive() const
+ {
+ return m_animState == AnimationStateNew || m_animState == AnimationStateStartWaitTimer || m_animState == AnimationStateStartWaitStyleAvailable || m_animState == AnimationStateStartWaitResponse;
+ }
+
+ bool postActive() const { return m_animState == AnimationStateDone; }
+ bool active() const { return !postActive() && !preActive(); }
+ bool running() const { return !isNew() && !postActive(); }
+ bool paused() const { return m_pauseTime >= 0; }
+ bool isNew() const { return m_animState == AnimationStateNew; }
+ bool waitingForStartTime() const { return m_animState == AnimationStateStartWaitResponse; }
+ bool waitingForStyleAvailable() const { return m_animState == AnimationStateStartWaitStyleAvailable; }
+
+ // "animating" means that something is running that requires a timer to keep firing
+ // (e.g. a software animation)
+ void setAnimating(bool inAnimating = true) { m_isAnimating = inAnimating; }
+ bool isAnimating() const { return m_isAnimating; }
+
+ double progress(double scale, double offset, const TimingFunction*) const;
+
+ virtual void animate(CompositeAnimation*, RenderObject*, const RenderStyle* currentStyle,
+ const RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle) { }
+
+ virtual bool shouldFireEvents() const { return false; }
+
+ void animationTimerCallbackFired(const AtomicString& eventType, double elapsedTime);
+
+ bool animationsMatch(const Animation*) const;
+
+ void setAnimation(const Animation* anim) { m_animation = const_cast<Animation*>(anim); }
+
+ // Return true if this animation is overridden. This will only be the case for
+ // ImplicitAnimations and is used to determine whether or not we should force
+ // set the start time. If an animation is overridden, it will probably not get
+ // back the AnimationStateInputStartTimeSet input.
+ virtual bool overridden() const { return false; }
+
+ // Does this animation/transition involve the given property?
+ virtual bool affectsProperty(int property) const { return false; }
+ bool isAnimatingProperty(int property, bool isRunningNow) const
+ {
+ if (isRunningNow)
+ return (!waitingToStart() && !postActive()) && affectsProperty(property);
+
+ return !postActive() && affectsProperty(property);
+ }
+
+ bool isTransformFunctionListValid() const { return m_transformFunctionListValid; }
+
+protected:
+ virtual void overrideAnimations() { }
+ virtual void resumeOverriddenAnimations() { }
+
+ CompositeAnimation* compositeAnimation() { return m_compAnim; }
+
+ // These are called when the corresponding timer fires so subclasses can do any extra work
+ 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) { }
+
+ void primeEventTimers();
+
+ static bool propertiesEqual(int prop, const RenderStyle* a, const RenderStyle* b);
+ static int getPropertyAtIndex(int);
+ static int getNumProperties();
+
+ // Return true if we need to start software animation timers
+ static bool blendProperties(const AnimationBase* anim, int prop, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress);
+
+ static void setChanged(Node*);
+
+protected:
+ AnimState m_animState;
+ int m_iteration;
+
+ bool m_isAnimating; // transition/animation requires continual timer firing
+ bool m_waitedForResponse;
+ double m_startTime;
+ double m_pauseTime;
+ RenderObject* m_object;
+
+ AnimationTimerCallback m_animationTimerCallback;
+ RefPtr<Animation> m_animation;
+ CompositeAnimation* m_compAnim;
+ bool m_transformFunctionListValid;
+};
+
+} // namespace WebCore
+
+#endif // AnimationBase_h
diff --git a/WebCore/page/animation/AnimationController.cpp b/WebCore/page/animation/AnimationController.cpp
new file mode 100644
index 0000000..d449afe
--- /dev/null
+++ b/WebCore/page/animation/AnimationController.cpp
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AnimationController.h"
+#include "CompositeAnimation.h"
+#include "Frame.h"
+#include "Timer.h"
+
+namespace WebCore {
+
+static const double cAnimationTimerDelay = 0.025;
+
+class AnimationControllerPrivate {
+public:
+ AnimationControllerPrivate(Frame*);
+ ~AnimationControllerPrivate();
+
+ CompositeAnimation* accessCompositeAnimation(RenderObject*);
+ bool clear(RenderObject*);
+
+ void animationTimerFired(Timer<AnimationControllerPrivate>*);
+ void updateAnimationTimer();
+
+ void updateRenderingDispatcherFired(Timer<AnimationControllerPrivate>*);
+ void startUpdateRenderingDispatcher();
+
+ bool hasAnimations() const { return !m_compositeAnimations.isEmpty(); }
+
+ void suspendAnimations(Document*);
+ void resumeAnimations(Document*);
+
+ void styleAvailable();
+
+ bool isAnimatingPropertyOnRenderer(RenderObject*, int property, bool isRunningNow) const;
+
+private:
+ typedef HashMap<RenderObject*, CompositeAnimation*> RenderObjectAnimationMap;
+
+ RenderObjectAnimationMap m_compositeAnimations;
+ Timer<AnimationControllerPrivate> m_animationTimer;
+ Timer<AnimationControllerPrivate> m_updateRenderingDispatcher;
+ Frame* m_frame;
+};
+
+AnimationControllerPrivate::AnimationControllerPrivate(Frame* frame)
+ : m_animationTimer(this, &AnimationControllerPrivate::animationTimerFired)
+ , m_updateRenderingDispatcher(this, &AnimationControllerPrivate::updateRenderingDispatcherFired)
+ , m_frame(frame)
+{
+}
+
+AnimationControllerPrivate::~AnimationControllerPrivate()
+{
+ deleteAllValues(m_compositeAnimations);
+}
+
+CompositeAnimation* AnimationControllerPrivate::accessCompositeAnimation(RenderObject* renderer)
+{
+ CompositeAnimation* animation = m_compositeAnimations.get(renderer);
+ if (!animation) {
+ animation = new CompositeAnimation(m_frame->animation());
+ m_compositeAnimations.set(renderer, animation);
+ }
+ return animation;
+}
+
+bool AnimationControllerPrivate::clear(RenderObject* renderer)
+{
+ // Return false if we didn't do anything OR we are suspended (so we don't try to
+ // do a setChanged() when suspended).
+ CompositeAnimation* animation = m_compositeAnimations.take(renderer);
+ if (!animation)
+ return false;
+ animation->resetTransitions(renderer);
+ bool wasSuspended = animation->isSuspended();
+ delete animation;
+ return !wasSuspended;
+}
+
+void AnimationControllerPrivate::styleAvailable()
+{
+ RenderObjectAnimationMap::const_iterator animationsEnd = m_compositeAnimations.end();
+ for (RenderObjectAnimationMap::const_iterator it = m_compositeAnimations.begin(); it != animationsEnd; ++it)
+ it->second->styleAvailable();
+}
+
+void AnimationControllerPrivate::updateAnimationTimer()
+{
+ bool isAnimating = false;
+
+ RenderObjectAnimationMap::const_iterator animationsEnd = m_compositeAnimations.end();
+ for (RenderObjectAnimationMap::const_iterator it = m_compositeAnimations.begin(); it != animationsEnd; ++it) {
+ CompositeAnimation* compAnim = it->second;
+ if (!compAnim->isSuspended() && compAnim->isAnimating()) {
+ isAnimating = true;
+ break;
+ }
+ }
+
+ if (isAnimating) {
+ if (!m_animationTimer.isActive())
+ m_animationTimer.startRepeating(cAnimationTimerDelay);
+ } else if (m_animationTimer.isActive())
+ m_animationTimer.stop();
+}
+
+void AnimationControllerPrivate::updateRenderingDispatcherFired(Timer<AnimationControllerPrivate>*)
+{
+ if (m_frame && m_frame->document())
+ m_frame->document()->updateRendering();
+}
+
+void AnimationControllerPrivate::startUpdateRenderingDispatcher()
+{
+ if (!m_updateRenderingDispatcher.isActive())
+ m_updateRenderingDispatcher.startOneShot(0);
+}
+
+void AnimationControllerPrivate::animationTimerFired(Timer<AnimationControllerPrivate>* timer)
+{
+ // When the timer fires, all we do is call setChanged on all DOM nodes with running animations and then do an immediate
+ // updateRendering. It will then call back to us with new information.
+ bool isAnimating = false;
+ RenderObjectAnimationMap::const_iterator animationsEnd = m_compositeAnimations.end();
+ for (RenderObjectAnimationMap::const_iterator it = m_compositeAnimations.begin(); it != animationsEnd; ++it) {
+ CompositeAnimation* compAnim = it->second;
+ if (!compAnim->isSuspended() && compAnim->isAnimating()) {
+ isAnimating = true;
+ compAnim->setAnimating(false);
+
+ Node* node = it->first->element();
+ ASSERT(!node || (node->document() && !node->document()->inPageCache()));
+ node->setChanged(AnimationStyleChange);
+ }
+ }
+
+ m_frame->document()->updateRendering();
+
+ updateAnimationTimer();
+}
+
+bool AnimationControllerPrivate::isAnimatingPropertyOnRenderer(RenderObject* renderer, int property, bool isRunningNow) const
+{
+ CompositeAnimation* animation = m_compositeAnimations.get(renderer);
+ if (!animation)
+ return false;
+
+ return animation->isAnimatingProperty(property, isRunningNow);
+}
+
+void AnimationControllerPrivate::suspendAnimations(Document* document)
+{
+ RenderObjectAnimationMap::const_iterator animationsEnd = m_compositeAnimations.end();
+ for (RenderObjectAnimationMap::const_iterator it = m_compositeAnimations.begin(); it != animationsEnd; ++it) {
+ RenderObject* renderer = it->first;
+ CompositeAnimation* compAnim = it->second;
+ if (renderer->document() == document)
+ compAnim->suspendAnimations();
+ }
+
+ updateAnimationTimer();
+}
+
+void AnimationControllerPrivate::resumeAnimations(Document* document)
+{
+ RenderObjectAnimationMap::const_iterator animationsEnd = m_compositeAnimations.end();
+ for (RenderObjectAnimationMap::const_iterator it = m_compositeAnimations.begin(); it != animationsEnd; ++it) {
+ RenderObject* renderer = it->first;
+ CompositeAnimation* compAnim = it->second;
+ if (renderer->document() == document)
+ compAnim->resumeAnimations();
+ }
+
+ updateAnimationTimer();
+}
+
+AnimationController::AnimationController(Frame* frame)
+ : m_data(new AnimationControllerPrivate(frame))
+ , m_numStyleAvailableWaiters(0)
+{
+}
+
+AnimationController::~AnimationController()
+{
+ delete m_data;
+}
+
+void AnimationController::cancelAnimations(RenderObject* renderer)
+{
+ if (!m_data->hasAnimations())
+ return;
+
+ if (m_data->clear(renderer)) {
+ Node* node = renderer->element();
+ ASSERT(!node || (node->document() && !node->document()->inPageCache()));
+ node->setChanged(AnimationStyleChange);
+ }
+}
+
+PassRefPtr<RenderStyle> AnimationController::updateAnimations(RenderObject* renderer, RenderStyle* newStyle)
+{
+ // Don't do anything if we're in the cache
+ if (!renderer->document() || renderer->document()->inPageCache())
+ return newStyle;
+
+ RenderStyle* oldStyle = renderer->style();
+
+ if ((!oldStyle || (!oldStyle->animations() && !oldStyle->transitions())) && (!newStyle->animations() && !newStyle->transitions()))
+ return newStyle;
+
+ // Fetch our current set of implicit animations from a hashtable. We then compare them
+ // against the animations in the style and make sure we're in sync. If destination values
+ // have changed, we reset the animation. We then do a blend to get new values and we return
+ // a new style.
+ ASSERT(renderer->element()); // FIXME: We do not animate generated content yet.
+
+ CompositeAnimation* rendererAnimations = m_data->accessCompositeAnimation(renderer);
+ RefPtr<RenderStyle> blendedStyle = rendererAnimations->animate(renderer, oldStyle, newStyle);
+
+ m_data->updateAnimationTimer();
+
+ if (blendedStyle != newStyle) {
+ // If the animations/transitions change opacity or transform, we neeed 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()))
+ blendedStyle->setZIndex(0);
+ }
+ return blendedStyle.release();
+}
+
+void AnimationController::setAnimationStartTime(RenderObject* renderer, double t)
+{
+ CompositeAnimation* rendererAnimations = m_data->accessCompositeAnimation(renderer);
+ rendererAnimations->setAnimationStartTime(t);
+}
+
+void AnimationController::setTransitionStartTime(RenderObject* renderer, int property, double t)
+{
+ CompositeAnimation* rendererAnimations = m_data->accessCompositeAnimation(renderer);
+ rendererAnimations->setTransitionStartTime(property, t);
+}
+
+bool AnimationController::isAnimatingPropertyOnRenderer(RenderObject* renderer, int property, bool isRunningNow) const
+{
+ return m_data->isAnimatingPropertyOnRenderer(renderer, property, isRunningNow);
+}
+
+void AnimationController::suspendAnimations(Document* document)
+{
+ m_data->suspendAnimations(document);
+}
+
+void AnimationController::resumeAnimations(Document* document)
+{
+ m_data->resumeAnimations(document);
+}
+
+void AnimationController::startUpdateRenderingDispatcher()
+{
+ m_data->startUpdateRenderingDispatcher();
+}
+
+void AnimationController::styleAvailable()
+{
+ if (!m_numStyleAvailableWaiters)
+ return;
+
+ m_data->styleAvailable();
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/animation/AnimationController.h b/WebCore/page/animation/AnimationController.h
new file mode 100644
index 0000000..bc13a2a
--- /dev/null
+++ b/WebCore/page/animation/AnimationController.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 AnimationController_h
+#define AnimationController_h
+
+#include <wtf/Forward.h>
+
+namespace WebCore {
+
+class AnimationControllerPrivate;
+class Document;
+class Frame;
+class RenderObject;
+class RenderStyle;
+
+class AnimationController {
+public:
+ AnimationController(Frame*);
+ ~AnimationController();
+
+ void cancelAnimations(RenderObject*);
+ PassRefPtr<RenderStyle> updateAnimations(RenderObject*, RenderStyle* newStyle);
+
+ void setAnimationStartTime(RenderObject*, double t);
+ void setTransitionStartTime(RenderObject*, int property, double t);
+
+ bool isAnimatingPropertyOnRenderer(RenderObject*, int property, bool isRunningNow) const;
+
+ void suspendAnimations(Document*);
+ void resumeAnimations(Document*);
+ void updateAnimationTimer();
+
+ void startUpdateRenderingDispatcher();
+
+ void styleAvailable();
+
+ void setWaitingForStyleAvailable(bool waiting)
+ {
+ if (waiting)
+ m_numStyleAvailableWaiters++;
+ else
+ m_numStyleAvailableWaiters--;
+ }
+
+private:
+ AnimationControllerPrivate* m_data;
+ unsigned m_numStyleAvailableWaiters;
+};
+
+} // namespace WebCore
+
+#endif // AnimationController_h
diff --git a/WebCore/page/animation/CompositeAnimation.cpp b/WebCore/page/animation/CompositeAnimation.cpp
new file mode 100644
index 0000000..2ae68d9
--- /dev/null
+++ b/WebCore/page/animation/CompositeAnimation.cpp
@@ -0,0 +1,594 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CompositeAnimation.h"
+
+#include "AnimationController.h"
+#include "CSSPropertyNames.h"
+#include "ImplicitAnimation.h"
+#include "KeyframeAnimation.h"
+#include "RenderObject.h"
+#include "RenderStyle.h"
+
+namespace WebCore {
+
+class CompositeAnimationPrivate {
+public:
+ CompositeAnimationPrivate(AnimationController* animationController, CompositeAnimation* compositeAnimation)
+ : m_isSuspended(false)
+ , m_animationController(animationController)
+ , m_compositeAnimation(compositeAnimation)
+ , m_numStyleAvailableWaiters(0)
+ {
+ }
+
+ ~CompositeAnimationPrivate();
+
+ PassRefPtr<RenderStyle> animate(RenderObject*, RenderStyle* currentStyle, RenderStyle* targetStyle);
+
+ void setAnimating(bool);
+ bool isAnimating() const;
+
+ const KeyframeAnimation* getAnimationForProperty(int property) const;
+
+ void resetTransitions(RenderObject*);
+ void resetAnimations(RenderObject*);
+
+ void cleanupFinishedAnimations(RenderObject*);
+
+ void setAnimationStartTime(double t);
+ void setTransitionStartTime(int property, double t);
+
+ void suspendAnimations();
+ void resumeAnimations();
+ bool isSuspended() const { return m_isSuspended; }
+
+ void overrideImplicitAnimations(int property);
+ void resumeOverriddenImplicitAnimations(int property);
+
+ void styleAvailable();
+
+ bool isAnimatingProperty(int property, bool isRunningNow) const;
+
+ void setWaitingForStyleAvailable(bool);
+
+protected:
+ void updateTransitions(RenderObject*, RenderStyle* currentStyle, RenderStyle* targetStyle);
+ void updateKeyframeAnimations(RenderObject*, RenderStyle* currentStyle, RenderStyle* targetStyle);
+
+private:
+ typedef HashMap<int, RefPtr<ImplicitAnimation> > CSSPropertyTransitionsMap;
+ typedef HashMap<AtomicStringImpl*, RefPtr<KeyframeAnimation> > AnimationNameMap;
+
+ CSSPropertyTransitionsMap m_transitions;
+ AnimationNameMap m_keyframeAnimations;
+ bool m_isSuspended;
+ AnimationController* m_animationController;
+ CompositeAnimation* m_compositeAnimation;
+ unsigned m_numStyleAvailableWaiters;
+};
+
+CompositeAnimationPrivate::~CompositeAnimationPrivate()
+{
+ m_transitions.clear();
+ m_keyframeAnimations.clear();
+}
+
+void CompositeAnimationPrivate::updateTransitions(RenderObject* renderer, RenderStyle* currentStyle, RenderStyle* targetStyle)
+{
+ // If currentStyle is null, we don't do transitions
+ if (!currentStyle || !targetStyle->transitions())
+ return;
+
+ // Check to see if we need to update the active transitions
+ for (size_t i = 0; i < targetStyle->transitions()->size(); ++i) {
+ const Animation* anim = targetStyle->transitions()->animation(i);
+ bool isActiveTransition = anim->duration() || anim->delay() > 0;
+
+ int prop = anim->property();
+
+ if (prop == cAnimateNone)
+ continue;
+
+ bool all = prop == cAnimateAll;
+
+ // Handle both the 'all' and single property cases. For the single prop case, we make only one pass
+ // through the loop.
+ for (int propertyIndex = 0; propertyIndex < AnimationBase::getNumProperties(); ++propertyIndex) {
+ if (all) {
+ // Get the next property
+ prop = AnimationBase::getPropertyAtIndex(propertyIndex);
+ }
+
+ // ImplicitAnimations are always hashed by actual properties, never cAnimateAll
+ ASSERT(prop > firstCSSProperty && prop < (firstCSSProperty + numCSSProperties));
+
+ // If there is a running animation for this property, the transition is overridden
+ // and we have to use the unanimatedStyle from the animation. We do the test
+ // against the unanimated style here, but we "override" the transition later.
+ const KeyframeAnimation* keyframeAnim = getAnimationForProperty(prop);
+ RenderStyle* fromStyle = keyframeAnim ? keyframeAnim->unanimatedStyle() : currentStyle;
+
+ // See if there is a current transition for this prop
+ ImplicitAnimation* implAnim = m_transitions.get(prop).get();
+ bool equal = true;
+
+ if (implAnim) {
+ // This implAnim might not be an already running transition. It might be
+ // newly added to the list in a previous iteration. This would happen if
+ // you have both an explicit transition-property and 'all' in the same
+ // list. In this case, the latter one overrides the earlier one, so we
+ // behave as though this is a running animation being replaced.
+ if (!isActiveTransition)
+ m_transitions.remove(prop);
+ else if (!implAnim->isTargetPropertyEqual(prop, targetStyle)) {
+ m_transitions.remove(prop);
+ equal = false;
+ }
+ } else {
+ // We need to start a transition if it is active and the properties don't match
+ equal = !isActiveTransition || AnimationBase::propertiesEqual(prop, fromStyle, targetStyle);
+ }
+
+ if (!equal) {
+ // Add the new transition
+ m_transitions.set(prop, ImplicitAnimation::create(const_cast<Animation*>(anim), prop, renderer, m_compositeAnimation, fromStyle));
+ }
+
+ // We only need one pass for the single prop case
+ if (!all)
+ break;
+ }
+ }
+}
+
+void CompositeAnimationPrivate::updateKeyframeAnimations(RenderObject* renderer, RenderStyle* currentStyle, RenderStyle* targetStyle)
+{
+ // Nothing to do if we don't have any animations, and didn't have any before
+ if (m_keyframeAnimations.isEmpty() && !targetStyle->hasAnimations())
+ return;
+
+ // Nothing to do if the current and target animations are the same
+ if (currentStyle && currentStyle->hasAnimations() && targetStyle->hasAnimations() && *(currentStyle->animations()) == *(targetStyle->animations()))
+ return;
+
+ // Mark all existing animations as no longer active
+ AnimationNameMap::const_iterator kfend = m_keyframeAnimations.end();
+ for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != kfend; ++it)
+ it->second->setIndex(-1);
+
+ // Now mark any still active animations as active and add any new animations
+ if (targetStyle->animations()) {
+ int numAnims = targetStyle->animations()->size();
+ for (int i = 0; i < numAnims; ++i) {
+ const Animation* anim = targetStyle->animations()->animation(i);
+ AtomicString animationName(anim->name());
+
+ if (!anim->isValidAnimation())
+ continue;
+
+ // See if there is a current animation for this name
+ RefPtr<KeyframeAnimation> keyframeAnim = m_keyframeAnimations.get(animationName.impl());
+
+ if (keyframeAnim) {
+ // There is one so it is still active
+
+ // Animations match, but play states may differ. update if needed
+ keyframeAnim->updatePlayState(anim->playState() == AnimPlayStatePlaying);
+
+ // Set the saved animation to this new one, just in case the play state has changed
+ keyframeAnim->setAnimation(anim);
+ keyframeAnim->setIndex(i);
+ } else if ((anim->duration() || anim->delay()) && anim->iterationCount()) {
+ keyframeAnim = KeyframeAnimation::create(const_cast<Animation*>(anim), renderer, i, m_compositeAnimation, currentStyle ? currentStyle : targetStyle);
+ m_keyframeAnimations.set(keyframeAnim->name().impl(), keyframeAnim);
+ }
+ }
+ }
+
+ // Make a list of animations to be removed
+ Vector<AtomicStringImpl*> animsToBeRemoved;
+ kfend = m_keyframeAnimations.end();
+ for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != kfend; ++it) {
+ KeyframeAnimation* keyframeAnim = it->second.get();
+ if (keyframeAnim->index() < 0)
+ animsToBeRemoved.append(keyframeAnim->name().impl());
+ }
+
+ // Now remove the animations from the list
+ for (size_t j = 0; j < animsToBeRemoved.size(); ++j)
+ m_keyframeAnimations.remove(animsToBeRemoved[j]);
+}
+
+PassRefPtr<RenderStyle> CompositeAnimationPrivate::animate(RenderObject* renderer, RenderStyle* currentStyle, RenderStyle* targetStyle)
+{
+ RefPtr<RenderStyle> resultStyle;
+
+ // Update animations first so we can see if any transitions are overridden
+ updateKeyframeAnimations(renderer, currentStyle, targetStyle);
+
+ // We don't do any transitions if we don't have a currentStyle (on startup)
+ updateTransitions(renderer, currentStyle, targetStyle);
+
+ if (currentStyle) {
+ // Now that we have transition objects ready, let them know about the new goal state. We want them
+ // to fill in a RenderStyle*& only if needed.
+ CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
+ if (ImplicitAnimation* anim = it->second.get())
+ anim->animate(m_compositeAnimation, renderer, currentStyle, targetStyle, resultStyle);
+ }
+ }
+
+ // Now that we have animation objects ready, let them know about the new goal state. We want them
+ // to fill in a RenderStyle*& only if needed.
+ if (targetStyle->hasAnimations()) {
+ for (size_t i = 0; i < targetStyle->animations()->size(); ++i) {
+ const Animation* anim = targetStyle->animations()->animation(i);
+
+ if (anim->isValidAnimation()) {
+ AtomicString animationName(anim->name());
+ RefPtr<KeyframeAnimation> keyframeAnim = m_keyframeAnimations.get(animationName.impl());
+ if (keyframeAnim)
+ keyframeAnim->animate(m_compositeAnimation, renderer, currentStyle, targetStyle, resultStyle);
+ }
+ }
+ }
+
+ cleanupFinishedAnimations(renderer);
+
+ return resultStyle ? resultStyle.release() : targetStyle;
+}
+
+// "animating" means that something is running that requires the timer to keep firing
+void CompositeAnimationPrivate::setAnimating(bool animating)
+{
+ CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
+ ImplicitAnimation* transition = it->second.get();
+ transition->setAnimating(animating);
+ }
+
+ AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
+ for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
+ KeyframeAnimation* anim = it->second.get();
+ anim->setAnimating(animating);
+ }
+}
+
+bool CompositeAnimationPrivate::isAnimating() const
+{
+ CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
+ ImplicitAnimation* transition = it->second.get();
+ if (transition && transition->isAnimating() && transition->running())
+ return true;
+ }
+
+ AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
+ for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
+ KeyframeAnimation* anim = it->second.get();
+ if (anim && !anim->paused() && anim->isAnimating() && anim->active())
+ return true;
+ }
+
+ return false;
+}
+
+const KeyframeAnimation* CompositeAnimationPrivate::getAnimationForProperty(int property) const
+{
+ const KeyframeAnimation* retval = 0;
+
+ // We want to send back the last animation with the property if there are multiples.
+ // So we need to iterate through all animations
+ AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
+ for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
+ const KeyframeAnimation* anim = it->second.get();
+ if (anim->hasAnimationForProperty(property))
+ retval = anim;
+ }
+
+ return retval;
+}
+
+void CompositeAnimationPrivate::resetTransitions(RenderObject* renderer)
+{
+ m_transitions.clear();
+}
+
+void CompositeAnimationPrivate::resetAnimations(RenderObject*)
+{
+ m_keyframeAnimations.clear();
+}
+
+void CompositeAnimationPrivate::cleanupFinishedAnimations(RenderObject* renderer)
+{
+ if (isSuspended())
+ return;
+
+ // Make a list of transitions to be deleted
+ Vector<int> finishedTransitions;
+ CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
+
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
+ ImplicitAnimation* anim = it->second.get();
+ if (!anim)
+ continue;
+ if (anim->postActive())
+ finishedTransitions.append(anim->animatingProperty());
+ }
+
+ // Delete them
+ size_t finishedTransitionCount = finishedTransitions.size();
+ for (size_t i = 0; i < finishedTransitionCount; ++i)
+ m_transitions.remove(finishedTransitions[i]);
+
+ // Make a list of animations to be deleted
+ Vector<AtomicStringImpl*> finishedAnimations;
+ AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
+
+ for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
+ KeyframeAnimation* anim = it->second.get();
+ if (!anim)
+ continue;
+ if (anim->postActive())
+ finishedAnimations.append(anim->name().impl());
+ }
+
+ // Delete them
+ size_t finishedAnimationCount = finishedAnimations.size();
+ for (size_t i = 0; i < finishedAnimationCount; ++i)
+ m_keyframeAnimations.remove(finishedAnimations[i]);
+}
+
+void CompositeAnimationPrivate::setAnimationStartTime(double t)
+{
+ // Set start time on all animations waiting for it
+ AnimationNameMap::const_iterator end = m_keyframeAnimations.end();
+ for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != end; ++it) {
+ KeyframeAnimation* anim = it->second.get();
+ if (anim && anim->waitingForStartTime())
+ anim->updateStateMachine(AnimationBase::AnimationStateInputStartTimeSet, t);
+ }
+}
+
+void CompositeAnimationPrivate::setTransitionStartTime(int property, double t)
+{
+ // Set the start time for given property transition
+ CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
+ ImplicitAnimation* anim = it->second.get();
+ if (anim && anim->waitingForStartTime() && anim->animatingProperty() == property)
+ anim->updateStateMachine(AnimationBase::AnimationStateInputStartTimeSet, t);
+ }
+}
+
+void CompositeAnimationPrivate::suspendAnimations()
+{
+ if (m_isSuspended)
+ return;
+
+ m_isSuspended = true;
+
+ AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
+ for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
+ if (KeyframeAnimation* anim = it->second.get())
+ anim->updatePlayState(false);
+ }
+
+ CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
+ ImplicitAnimation* anim = it->second.get();
+ if (anim && anim->hasStyle())
+ anim->updatePlayState(false);
+ }
+}
+
+void CompositeAnimationPrivate::resumeAnimations()
+{
+ if (!m_isSuspended)
+ return;
+
+ m_isSuspended = false;
+
+ AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
+ for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
+ KeyframeAnimation* anim = it->second.get();
+ if (anim && anim->playStatePlaying())
+ anim->updatePlayState(true);
+ }
+
+ CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
+ ImplicitAnimation* anim = it->second.get();
+ if (anim && anim->hasStyle())
+ anim->updatePlayState(true);
+ }
+}
+
+void CompositeAnimationPrivate::overrideImplicitAnimations(int property)
+{
+ CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
+ ImplicitAnimation* anim = it->second.get();
+ if (anim && anim->animatingProperty() == property)
+ anim->setOverridden(true);
+ }
+}
+
+void CompositeAnimationPrivate::resumeOverriddenImplicitAnimations(int property)
+{
+ CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
+ ImplicitAnimation* anim = it->second.get();
+ if (anim && anim->animatingProperty() == property)
+ anim->setOverridden(false);
+ }
+}
+
+static inline bool compareAnimationIndices(RefPtr<KeyframeAnimation> a, const RefPtr<KeyframeAnimation> b)
+{
+ return a->index() < b->index();
+}
+
+void CompositeAnimationPrivate::styleAvailable()
+{
+ if (m_numStyleAvailableWaiters == 0)
+ return;
+
+ // We have to go through animations in the order in which they appear in
+ // the style, because order matters for additivity.
+ Vector<RefPtr<KeyframeAnimation> > animations(m_keyframeAnimations.size());
+ copyValuesToVector(m_keyframeAnimations, animations);
+
+ if (animations.size() > 1)
+ std::stable_sort(animations.begin(), animations.end(), compareAnimationIndices);
+
+ for (size_t i = 0; i < animations.size(); ++i) {
+ KeyframeAnimation* anim = animations[i].get();
+ if (anim && anim->waitingForStyleAvailable())
+ anim->updateStateMachine(AnimationBase::AnimationStateInputStyleAvailable, -1);
+ }
+
+ CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
+ ImplicitAnimation* anim = it->second.get();
+ if (anim && anim->waitingForStyleAvailable())
+ anim->updateStateMachine(AnimationBase::AnimationStateInputStyleAvailable, -1);
+ }
+}
+
+bool CompositeAnimationPrivate::isAnimatingProperty(int property, bool isRunningNow) const
+{
+ AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
+ for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
+ KeyframeAnimation* anim = it->second.get();
+ if (anim && anim->isAnimatingProperty(property, isRunningNow))
+ return true;
+ }
+
+ CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
+ ImplicitAnimation* anim = it->second.get();
+ if (anim && anim->isAnimatingProperty(property, isRunningNow))
+ return true;
+ }
+ return false;
+}
+
+void CompositeAnimationPrivate::setWaitingForStyleAvailable(bool waiting)
+{
+ if (waiting)
+ m_numStyleAvailableWaiters++;
+ else
+ m_numStyleAvailableWaiters--;
+ m_animationController->setWaitingForStyleAvailable(waiting);
+}
+
+CompositeAnimation::CompositeAnimation(AnimationController* animationController)
+ : m_data(new CompositeAnimationPrivate(animationController, this))
+{
+}
+
+CompositeAnimation::~CompositeAnimation()
+{
+ delete m_data;
+}
+
+PassRefPtr<RenderStyle> CompositeAnimation::animate(RenderObject* renderer, RenderStyle* currentStyle, RenderStyle* targetStyle)
+{
+ return m_data->animate(renderer, currentStyle, targetStyle);
+}
+
+bool CompositeAnimation::isAnimating() const
+{
+ return m_data->isAnimating();
+}
+
+void CompositeAnimation::setWaitingForStyleAvailable(bool b)
+{
+ m_data->setWaitingForStyleAvailable(b);
+}
+
+void CompositeAnimation::resetTransitions(RenderObject* renderer)
+{
+ m_data->resetTransitions(renderer);
+}
+
+void CompositeAnimation::suspendAnimations()
+{
+ m_data->suspendAnimations();
+}
+
+void CompositeAnimation::resumeAnimations()
+{
+ m_data->resumeAnimations();
+}
+
+bool CompositeAnimation::isSuspended() const
+{
+ return m_data->isSuspended();
+}
+
+void CompositeAnimation::styleAvailable()
+{
+ m_data->styleAvailable();
+}
+
+void CompositeAnimation::setAnimating(bool b)
+{
+ m_data->setAnimating(b);
+}
+
+bool CompositeAnimation::isAnimatingProperty(int property, bool isRunningNow) const
+{
+ return m_data->isAnimatingProperty(property, isRunningNow);
+}
+
+void CompositeAnimation::setAnimationStartTime(double t)
+{
+ m_data->setAnimationStartTime(t);
+}
+
+void CompositeAnimation::setTransitionStartTime(int property, double t)
+{
+ m_data->setTransitionStartTime(property, t);
+}
+
+void CompositeAnimation::overrideImplicitAnimations(int property)
+{
+ m_data->overrideImplicitAnimations(property);
+}
+
+void CompositeAnimation::resumeOverriddenImplicitAnimations(int property)
+{
+ m_data->resumeOverriddenImplicitAnimations(property);
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/animation/CompositeAnimation.h b/WebCore/page/animation/CompositeAnimation.h
new file mode 100644
index 0000000..13f1179
--- /dev/null
+++ b/WebCore/page/animation/CompositeAnimation.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 CompositeAnimation_h
+#define CompositeAnimation_h
+
+#include "AtomicString.h"
+
+#include <wtf/HashMap.h>
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+class CompositeAnimationPrivate;
+class AnimationController;
+class RenderObject;
+class RenderStyle;
+
+// A CompositeAnimation represents a collection of animations that are running
+// on a single RenderObject, such as a number of properties transitioning at once.
+class CompositeAnimation : public Noncopyable {
+public:
+ CompositeAnimation(AnimationController* animationController);
+ ~CompositeAnimation();
+
+ PassRefPtr<RenderStyle> animate(RenderObject*, RenderStyle* currentStyle, RenderStyle* targetStyle);
+ bool isAnimating() const;
+
+ void setWaitingForStyleAvailable(bool);
+ void resetTransitions(RenderObject*);
+
+ void suspendAnimations();
+ void resumeAnimations();
+ bool isSuspended() const;
+
+ void styleAvailable();
+ void setAnimating(bool);
+ bool isAnimatingProperty(int property, bool isRunningNow) const;
+
+ void setAnimationStartTime(double t);
+ void setTransitionStartTime(int property, double t);
+
+ void overrideImplicitAnimations(int property);
+ void resumeOverriddenImplicitAnimations(int property);
+
+private:
+ CompositeAnimationPrivate* m_data;
+};
+
+} // namespace WebCore
+
+#endif // CompositeAnimation_h
diff --git a/WebCore/page/animation/ImplicitAnimation.cpp b/WebCore/page/animation/ImplicitAnimation.cpp
new file mode 100644
index 0000000..4d470e4
--- /dev/null
+++ b/WebCore/page/animation/ImplicitAnimation.cpp
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CSSPropertyNames.h"
+#include "EventNames.h"
+#include "ImplicitAnimation.h"
+#include "RenderObject.h"
+
+namespace WebCore {
+
+ImplicitAnimation::ImplicitAnimation(const Animation* transition, int animatingProperty, RenderObject* renderer, CompositeAnimation* compAnim, RenderStyle* fromStyle)
+ : AnimationBase(transition, renderer, compAnim)
+ , m_transitionProperty(transition->property())
+ , m_animatingProperty(animatingProperty)
+ , m_overridden(false)
+ , m_fromStyle(fromStyle)
+{
+ ASSERT(animatingProperty != cAnimateAll);
+}
+
+ImplicitAnimation::~ImplicitAnimation()
+{
+ // Do the cleanup here instead of in the base class so the specialized methods get called
+ if (!postActive())
+ updateStateMachine(AnimationStateInputEndAnimation, -1);
+}
+
+bool ImplicitAnimation::shouldSendEventForListener(Document::ListenerType inListenerType)
+{
+ return m_object->document()->hasListenerType(inListenerType);
+}
+
+void ImplicitAnimation::animate(CompositeAnimation* animation, RenderObject* renderer, RenderStyle* currentStyle,
+ RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle)
+{
+ if (paused())
+ return;
+
+ // If we get this far and the animation is done, it means we are cleaning up a just finished animation.
+ // So just return. Everything is already all cleaned up.
+ if (postActive())
+ return;
+
+ // Reset to start the transition if we are new
+ if (isNew())
+ reset(targetStyle);
+
+ // Run a cycle of animation.
+ // We know we will need a new render style, so make one if needed
+ if (!animatedStyle)
+ animatedStyle = RenderStyle::clone(targetStyle);
+
+ if (blendProperties(this, m_animatingProperty, animatedStyle.get(), m_fromStyle.get(), m_toStyle.get(), progress(1, 0, 0)))
+ setAnimating();
+}
+
+void ImplicitAnimation::onAnimationEnd(double elapsedTime)
+{
+ if (!sendTransitionEvent(eventNames().webkitTransitionEndEvent, elapsedTime)) {
+ // We didn't dispatch an event, which would call endAnimation(), so we'll just call it here.
+ endAnimation(true);
+ }
+}
+
+bool ImplicitAnimation::sendTransitionEvent(const AtomicString& eventType, double elapsedTime)
+{
+ if (eventType == eventNames().webkitTransitionEndEvent) {
+ Document::ListenerType listenerType = Document::TRANSITIONEND_LISTENER;
+
+ if (shouldSendEventForListener(listenerType)) {
+ String propertyName;
+ if (m_animatingProperty != cAnimateAll)
+ propertyName = getPropertyName(static_cast<CSSPropertyID>(m_animatingProperty));
+
+ // Dispatch the event
+ RefPtr<Element> element = 0;
+ if (m_object->node() && m_object->node()->isElementNode())
+ element = static_cast<Element*>(m_object->node());
+
+ ASSERT(!element || element->document() && !element->document()->inPageCache());
+ if (!element)
+ return false;
+
+ // Keep a reference to this ImplicitAnimation so it doesn't go away in the handler
+ RefPtr<ImplicitAnimation> retainer(this);
+
+ // Call the event handler
+ element->dispatchWebKitTransitionEvent(eventType, propertyName, elapsedTime);
+
+ // Restore the original (unanimated) style
+ if (eventType == eventNames().webkitAnimationEndEvent && element->renderer())
+ setChanged(element.get());
+
+ return true; // Did dispatch an event
+ }
+ }
+
+ return false; // Didn't dispatch an event
+}
+
+void ImplicitAnimation::reset(RenderStyle* to)
+{
+ ASSERT(to);
+ ASSERT(m_fromStyle);
+
+
+ m_toStyle = to;
+
+ // Restart the transition
+ if (m_fromStyle && m_toStyle)
+ updateStateMachine(AnimationStateInputRestartAnimation, -1);
+
+ // set the transform animation list
+ validateTransformFunctionList();
+}
+
+void ImplicitAnimation::setOverridden(bool b)
+{
+ if (b == m_overridden)
+ return;
+
+ m_overridden = b;
+ updateStateMachine(m_overridden ? AnimationStateInputPauseOverride : AnimationStateInputResumeOverride, -1);
+}
+
+bool ImplicitAnimation::affectsProperty(int property) const
+{
+ return (m_animatingProperty == property);
+}
+
+bool ImplicitAnimation::isTargetPropertyEqual(int prop, const RenderStyle* targetStyle)
+{
+ return propertiesEqual(prop, m_toStyle.get(), targetStyle);
+}
+
+void ImplicitAnimation::blendPropertyValueInStyle(int prop, RenderStyle* currentStyle)
+{
+ blendProperties(this, prop, currentStyle, m_fromStyle.get(), m_toStyle.get(), progress(1, 0, 0));
+}
+
+void ImplicitAnimation::validateTransformFunctionList()
+{
+ m_transformFunctionListValid = false;
+
+ if (!m_fromStyle || !m_toStyle)
+ return;
+
+ const TransformOperations* val = &m_fromStyle->transform();
+ const TransformOperations* toVal = &m_toStyle->transform();
+
+ if (val->operations().isEmpty())
+ val = toVal;
+
+ if (val->operations().isEmpty())
+ return;
+
+ // See if the keyframes are valid
+ if (val != toVal) {
+ // A list of length 0 matches anything
+ if (!toVal->operations().isEmpty()) {
+ // If the sizes of the function lists don't match, the lists don't match
+ if (val->operations().size() != toVal->operations().size())
+ return;
+
+ // If the types of each function are not the same, the lists don't match
+ for (size_t j = 0; j < val->operations().size(); ++j) {
+ if (!val->operations()[j]->isSameType(*toVal->operations()[j]))
+ return;
+ }
+ }
+ }
+
+ // Keyframes are valid
+ m_transformFunctionListValid = true;
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/animation/ImplicitAnimation.h b/WebCore/page/animation/ImplicitAnimation.h
new file mode 100644
index 0000000..7c9d50f
--- /dev/null
+++ b/WebCore/page/animation/ImplicitAnimation.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 ImplicitAnimation_h
+#define ImplicitAnimation_h
+
+#include "AnimationBase.h"
+#include "Document.h"
+
+namespace WebCore {
+
+// An ImplicitAnimation tracks the state of a transition of a specific CSS property
+// for a single RenderObject.
+class ImplicitAnimation : public AnimationBase {
+public:
+ static PassRefPtr<ImplicitAnimation> create(const Animation* animation, int animatingProperty, RenderObject* renderer, CompositeAnimation* compositeAnimation, RenderStyle* fromStyle)
+ {
+ return adoptRef(new ImplicitAnimation(animation, animatingProperty, renderer, compositeAnimation, fromStyle));
+ };
+
+ int transitionProperty() const { return m_transitionProperty; }
+ int animatingProperty() const { return m_animatingProperty; }
+
+ virtual void onAnimationEnd(double elapsedTime);
+
+ virtual void animate(CompositeAnimation*, RenderObject*, RenderStyle* currentStyle, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle);
+ virtual void reset(RenderStyle* to);
+
+ void setOverridden(bool);
+ virtual bool overridden() const { return m_overridden; }
+
+ virtual bool shouldFireEvents() const { return true; }
+
+ virtual bool affectsProperty(int) const;
+
+ bool hasStyle() const { return m_fromStyle && m_toStyle; }
+
+ bool isTargetPropertyEqual(int, const RenderStyle* targetStyle);
+
+ void blendPropertyValueInStyle(int, RenderStyle* currentStyle);
+
+protected:
+ bool shouldSendEventForListener(Document::ListenerType);
+ bool sendTransitionEvent(const AtomicString&, double elapsedTime);
+
+ void validateTransformFunctionList();
+
+private:
+ ImplicitAnimation(const Animation*, int animatingProperty, RenderObject*, CompositeAnimation*, RenderStyle* fromStyle);
+ virtual ~ImplicitAnimation();
+
+ int m_transitionProperty; // Transition property as specified in the RenderStyle. May be cAnimateAll
+ int m_animatingProperty; // Specific property for this ImplicitAnimation
+ bool m_overridden; // true when there is a keyframe animation that overrides the transitioning property
+
+ // The two styles that we are blending.
+ RefPtr<RenderStyle> m_fromStyle;
+ RefPtr<RenderStyle> m_toStyle;
+};
+
+} // namespace WebCore
+
+#endif // ImplicitAnimation_h
diff --git a/WebCore/page/animation/KeyframeAnimation.cpp b/WebCore/page/animation/KeyframeAnimation.cpp
new file mode 100644
index 0000000..69fdd11
--- /dev/null
+++ b/WebCore/page/animation/KeyframeAnimation.cpp
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "KeyframeAnimation.h"
+
+#include "CSSPropertyNames.h"
+#include "CSSStyleSelector.h"
+#include "CompositeAnimation.h"
+#include "EventNames.h"
+#include "RenderObject.h"
+#include "SystemTime.h"
+
+namespace WebCore {
+
+KeyframeAnimation::KeyframeAnimation(const Animation* animation, RenderObject* renderer, int index, CompositeAnimation* compAnim, RenderStyle* unanimatedStyle)
+ : AnimationBase(animation, renderer, compAnim)
+ , m_keyframes(renderer, animation->name())
+ , m_index(index)
+ , m_unanimatedStyle(unanimatedStyle)
+{
+ // Get the keyframe RenderStyles
+ if (m_object && m_object->element() && m_object->element()->isElementNode())
+ m_object->document()->styleSelector()->keyframeStylesForAnimation(static_cast<Element*>(m_object->element()), unanimatedStyle, m_keyframes);
+
+ // Update the m_transformFunctionListValid flag based on whether the function lists in the keyframes match.
+ validateTransformFunctionList();
+}
+
+KeyframeAnimation::~KeyframeAnimation()
+{
+ // Do the cleanup here instead of in the base class so the specialized methods get called
+ if (!postActive())
+ updateStateMachine(AnimationStateInputEndAnimation, -1);
+}
+
+void KeyframeAnimation::animate(CompositeAnimation* animation, RenderObject* renderer, const RenderStyle* currentStyle,
+ const RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle)
+{
+ // If we have not yet started, we will not have a valid start time, so just start the animation if needed.
+ if (isNew() && m_animation->playState() == AnimPlayStatePlaying)
+ updateStateMachine(AnimationStateInputStartAnimation, -1);
+
+ // If we get this far and the animation is done, it means we are cleaning up a just finished animation.
+ // If so, we need to send back the targetStyle.
+ if (postActive()) {
+ if (!animatedStyle)
+ animatedStyle = const_cast<RenderStyle*>(targetStyle);
+ return;
+ }
+
+ // If we are waiting for the start timer, we don't want to change the style yet.
+ // Special case - if the delay time is 0, then we do want to set the first frame of the
+ // animation right away. This avoids a flash when the animation starts.
+ if (waitingToStart() && m_animation->delay() > 0)
+ return;
+
+ // FIXME: we need to be more efficient about determining which keyframes we are animating between.
+ // We should cache the last pair or something.
+
+ // Find the first key
+ double elapsedTime = (m_startTime > 0) ? ((!paused() ? currentTime() : m_pauseTime) - m_startTime) : 0;
+ if (elapsedTime < 0)
+ elapsedTime = 0;
+
+ double t = m_animation->duration() ? (elapsedTime / m_animation->duration()) : 1;
+ int i = static_cast<int>(t);
+ t -= i;
+ if (m_animation->direction() && (i & 1))
+ t = 1 - t;
+
+ const RenderStyle* fromStyle = 0;
+ const RenderStyle* toStyle = 0;
+ double scale = 1;
+ double offset = 0;
+ Vector<KeyframeValue>::const_iterator endKeyframes = m_keyframes.endKeyframes();
+ for (Vector<KeyframeValue>::const_iterator it = m_keyframes.beginKeyframes(); it != endKeyframes; ++it) {
+ if (t < it->key()) {
+ // The first key should always be 0, so we should never succeed on the first key
+ if (!fromStyle)
+ break;
+ scale = 1.0 / (it->key() - offset);
+ toStyle = it->style();
+ break;
+ }
+
+ offset = it->key();
+ fromStyle = it->style();
+ }
+
+ // If either style is 0 we have an invalid case, just stop the animation.
+ if (!fromStyle || !toStyle) {
+ updateStateMachine(AnimationStateInputEndAnimation, -1);
+ return;
+ }
+
+ // Run a cycle of animation.
+ // We know we will need a new render style, so make one if needed.
+ if (!animatedStyle)
+ animatedStyle = RenderStyle::clone(targetStyle);
+
+ const TimingFunction* timingFunction = 0;
+ if (fromStyle->animations() && fromStyle->animations()->size() > 0)
+ timingFunction = &(fromStyle->animations()->animation(0)->timingFunction());
+
+ double prog = progress(scale, offset, timingFunction);
+
+ HashSet<int>::const_iterator endProperties = m_keyframes.endProperties();
+ for (HashSet<int>::const_iterator it = m_keyframes.beginProperties(); it != endProperties; ++it) {
+ if (blendProperties(this, *it, animatedStyle.get(), fromStyle, toStyle, prog))
+ setAnimating();
+ }
+}
+
+bool KeyframeAnimation::hasAnimationForProperty(int property) const
+{
+ HashSet<int>::const_iterator end = m_keyframes.endProperties();
+ for (HashSet<int>::const_iterator it = m_keyframes.beginProperties(); it != end; ++it) {
+ if (*it == property)
+ return true;
+ }
+
+ return false;
+}
+
+void KeyframeAnimation::endAnimation(bool)
+{
+ // Restore the original (unanimated) style
+ if (m_object)
+ setChanged(m_object->element());
+}
+
+bool KeyframeAnimation::shouldSendEventForListener(Document::ListenerType listenerType)
+{
+ return m_object->document()->hasListenerType(listenerType);
+}
+
+void KeyframeAnimation::onAnimationStart(double elapsedTime)
+{
+ sendAnimationEvent(eventNames().webkitAnimationStartEvent, elapsedTime);
+}
+
+void KeyframeAnimation::onAnimationIteration(double elapsedTime)
+{
+ sendAnimationEvent(eventNames().webkitAnimationIterationEvent, elapsedTime);
+}
+
+void KeyframeAnimation::onAnimationEnd(double elapsedTime)
+{
+ if (!sendAnimationEvent(eventNames().webkitAnimationEndEvent, elapsedTime)) {
+ // We didn't dispatch an event, which would call endAnimation(), so we'll just call it here.
+ endAnimation(true);
+ }
+}
+
+bool KeyframeAnimation::sendAnimationEvent(const AtomicString& eventType, double elapsedTime)
+{
+ Document::ListenerType listenerType;
+ if (eventType == eventNames().webkitAnimationIterationEvent)
+ listenerType = Document::ANIMATIONITERATION_LISTENER;
+ else if (eventType == eventNames().webkitAnimationEndEvent)
+ listenerType = Document::ANIMATIONEND_LISTENER;
+ else {
+ ASSERT(eventType == eventNames().webkitAnimationStartEvent);
+ listenerType = Document::ANIMATIONSTART_LISTENER;
+ }
+
+ if (shouldSendEventForListener(listenerType)) {
+ // Dispatch the event
+ RefPtr<Element> element;
+ if (m_object->node() && m_object->node()->isElementNode())
+ element = static_cast<Element*>(m_object->node());
+
+ ASSERT(!element || element->document() && !element->document()->inPageCache());
+ if (!element)
+ return false;
+
+ // Keep a reference to this ImplicitAnimation so it doesn't go away in the handler
+ RefPtr<KeyframeAnimation> retainer(this);
+
+ // Call the event handler
+ element->dispatchWebKitAnimationEvent(eventType, m_keyframes.animationName(), elapsedTime);
+
+ // Restore the original (unanimated) style
+ if (eventType == eventNames().webkitAnimationEndEvent && element->renderer())
+ setChanged(element.get());
+
+ return true; // Did dispatch an event
+ }
+
+ return false; // Did not dispatch an event
+}
+
+void KeyframeAnimation::overrideAnimations()
+{
+ // This will override implicit animations that match the properties in the keyframe animation
+ HashSet<int>::const_iterator end = m_keyframes.endProperties();
+ for (HashSet<int>::const_iterator it = m_keyframes.beginProperties(); it != end; ++it)
+ compositeAnimation()->overrideImplicitAnimations(*it);
+}
+
+void KeyframeAnimation::resumeOverriddenAnimations()
+{
+ // This will resume overridden implicit animations
+ HashSet<int>::const_iterator end = m_keyframes.endProperties();
+ for (HashSet<int>::const_iterator it = m_keyframes.beginProperties(); it != end; ++it)
+ compositeAnimation()->resumeOverriddenImplicitAnimations(*it);
+}
+
+bool KeyframeAnimation::affectsProperty(int property) const
+{
+ HashSet<int>::const_iterator end = m_keyframes.endProperties();
+ for (HashSet<int>::const_iterator it = m_keyframes.beginProperties(); it != end; ++it) {
+ if (*it == property)
+ return true;
+ }
+ return false;
+}
+
+void KeyframeAnimation::validateTransformFunctionList()
+{
+ m_transformFunctionListValid = false;
+
+ if (m_keyframes.size() < 2 || !m_keyframes.containsProperty(CSSPropertyWebkitTransform))
+ return;
+
+ Vector<KeyframeValue>::const_iterator end = m_keyframes.endKeyframes();
+
+ // Empty transforms match anything, so find the first non-empty entry as the reference
+ size_t firstIndex = 0;
+ Vector<KeyframeValue>::const_iterator firstIt = end;
+
+ for (Vector<KeyframeValue>::const_iterator it = m_keyframes.beginKeyframes(); it != end; ++it, ++firstIndex) {
+ if (it->style()->transform().operations().size() > 0) {
+ firstIt = it;
+ break;
+ }
+ }
+
+ if (firstIt == end)
+ return;
+
+ const TransformOperations* firstVal = &firstIt->style()->transform();
+
+ // See if the keyframes are valid
+ for (Vector<KeyframeValue>::const_iterator it = firstIt+1; it != end; ++it) {
+ const TransformOperations* val = &it->style()->transform();
+
+ // A null transform matches anything
+ if (val->operations().isEmpty())
+ continue;
+
+ // If the sizes of the function lists don't match, the lists don't match
+ if (firstVal->operations().size() != val->operations().size())
+ return;
+
+ // If the types of each function are not the same, the lists don't match
+ for (size_t j = 0; j < firstVal->operations().size(); ++j) {
+ if (!firstVal->operations()[j]->isSameType(*val->operations()[j]))
+ return;
+ }
+ }
+
+ // Keyframes are valid
+ m_transformFunctionListValid = true;
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/animation/KeyframeAnimation.h b/WebCore/page/animation/KeyframeAnimation.h
new file mode 100644
index 0000000..55b429a
--- /dev/null
+++ b/WebCore/page/animation/KeyframeAnimation.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 KeyframeAnimation_h
+#define KeyframeAnimation_h
+
+#include "AnimationBase.h"
+#include "Document.h"
+#include "KeyframeList.h"
+#include "RenderStyle.h"
+
+namespace WebCore {
+
+// A KeyframeAnimation tracks the state of an explicit animation
+// for a single RenderObject.
+class KeyframeAnimation : public AnimationBase {
+public:
+ static PassRefPtr<KeyframeAnimation> create(const Animation* animation, RenderObject* renderer, int index, CompositeAnimation* compositeAnimation, RenderStyle* unanimatedStyle)
+ {
+ return adoptRef(new KeyframeAnimation(animation, renderer, index, compositeAnimation, unanimatedStyle));
+ };
+
+ virtual void animate(CompositeAnimation*, RenderObject*, const RenderStyle* currentStyle, const RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle);
+
+ const AtomicString& name() const { return m_keyframes.animationName(); }
+ int index() const { return m_index; }
+ void setIndex(int i) { m_index = i; }
+
+ virtual bool shouldFireEvents() const { return true; }
+
+ bool hasAnimationForProperty(int property) const;
+
+ RenderStyle* unanimatedStyle() const { return m_unanimatedStyle.get(); }
+
+protected:
+ virtual void onAnimationStart(double elapsedTime);
+ virtual void onAnimationIteration(double elapsedTime);
+ virtual void onAnimationEnd(double elapsedTime);
+ virtual void endAnimation(bool reset);
+
+ virtual void overrideAnimations();
+ virtual void resumeOverriddenAnimations();
+
+ bool shouldSendEventForListener(Document::ListenerType inListenerType);
+ bool sendAnimationEvent(const AtomicString&, double elapsedTime);
+
+ virtual bool affectsProperty(int) const;
+
+ void validateTransformFunctionList();
+
+private:
+ KeyframeAnimation(const Animation* animation, RenderObject*, int index, CompositeAnimation*, RenderStyle* unanimatedStyle);
+ virtual ~KeyframeAnimation();
+
+ // The keyframes that we are blending.
+ KeyframeList m_keyframes;
+
+ // The order in which this animation appears in the animation-name style.
+ int m_index;
+
+ // The style just before we started animation
+ RefPtr<RenderStyle> m_unanimatedStyle;
+};
+
+} // namespace WebCore
+
+#endif // KeyframeAnimation_h
diff --git a/WebCore/page/gtk/AXObjectCacheAtk.cpp b/WebCore/page/gtk/AXObjectCacheAtk.cpp
new file mode 100644
index 0000000..3535cf1
--- /dev/null
+++ b/WebCore/page/gtk/AXObjectCacheAtk.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2008 Nuanti Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "AXObjectCache.h"
+
+#include "AccessibilityObject.h"
+#include "AccessibilityObjectWrapperAtk.h"
+
+namespace WebCore {
+
+void AXObjectCache::detachWrapper(AccessibilityObject* obj)
+{
+ webkit_accessible_detach(WEBKIT_ACCESSIBLE(obj->wrapper()));
+}
+
+void AXObjectCache::attachWrapper(AccessibilityObject* obj)
+{
+ AtkObject* atkObj = ATK_OBJECT(webkit_accessible_new(obj));
+ obj->setWrapper(atkObj);
+ g_object_unref(atkObj);
+}
+
+void AXObjectCache::postNotification(RenderObject*, const String&)
+{
+}
+
+void AXObjectCache::postNotificationToElement(RenderObject*, const String&)
+{
+}
+
+void AXObjectCache::handleFocusedUIElementChanged()
+{
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/Plugin.h b/WebCore/page/gtk/AccessibilityObjectAtk.cpp
index f5b4c63..b755645 100644
--- a/WebCore/page/Plugin.h
+++ b/WebCore/page/gtk/AccessibilityObjectAtk.cpp
@@ -1,6 +1,5 @@
-// -*- mode: c++; c-basic-offset: 4 -*-
/*
- * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2008 Apple Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -18,24 +17,14 @@
* Boston, MA 02110-1301, USA.
*/
-#ifndef Plugin_h
-#define Plugin_h
-
-#include <wtf/RefCounted.h>
+#include "config.h"
+#include "AccessibilityObject.h"
namespace WebCore {
- class Widget;
+bool AccessibilityObject::accessibilityIgnoreAttachment() const
+{
+ return false;
+}
- class Plugin : public RefCounted<Plugin> {
- public:
- Plugin(Widget* view) : m_view(view) { }
- Widget* view() const { return m_view; }
-
- private:
- Widget* m_view;
- };
-
} // namespace WebCore
-
-#endif // Plugin_h
diff --git a/WebCore/page/gtk/AccessibilityObjectWrapperAtk.cpp b/WebCore/page/gtk/AccessibilityObjectWrapperAtk.cpp
new file mode 100644
index 0000000..b46fb60
--- /dev/null
+++ b/WebCore/page/gtk/AccessibilityObjectWrapperAtk.cpp
@@ -0,0 +1,676 @@
+/*
+ * Copyright (C) 2008 Nuanti Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "AccessibilityObjectWrapperAtk.h"
+
+#include "AXObjectCache.h"
+#include "AccessibilityListBox.h"
+#include "AccessibilityRenderObject.h"
+#include "AtomicString.h"
+#include "CString.h"
+#include "Document.h"
+#include "Editor.h"
+#include "Frame.h"
+#include "FrameView.h"
+#include "IntRect.h"
+#include "NotImplemented.h"
+
+#include <atk/atk.h>
+
+using namespace WebCore;
+
+// Used to provide const char* returns.
+static const char* returnString(const String& str)
+{
+ static CString returnedString;
+ returnedString = str.utf8();
+ return returnedString.data();
+}
+
+static AccessibilityObject* core(WebKitAccessible* accessible)
+{
+ if (!accessible)
+ return 0;
+
+ return accessible->m_object;
+}
+
+static AccessibilityObject* core(AtkObject* object)
+{
+ if (!WEBKIT_IS_ACCESSIBLE(object))
+ return 0;
+
+ return core(WEBKIT_ACCESSIBLE(object));
+}
+
+static AccessibilityObject* core(AtkAction* action)
+{
+ return core(ATK_OBJECT(action));
+}
+
+static AccessibilityObject* core(AtkStreamableContent* streamable)
+{
+ return core(ATK_OBJECT(streamable));
+}
+
+static AccessibilityObject* core(AtkText* text)
+{
+ return core(ATK_OBJECT(text));
+}
+
+static AccessibilityObject* core(AtkEditableText* text)
+{
+ return core(ATK_OBJECT(text));
+}
+
+extern "C" {
+
+static gpointer parent_class = NULL;
+
+static void webkit_accessible_init(AtkObject* object, gpointer data)
+{
+ g_return_if_fail(WEBKIT_IS_ACCESSIBLE(object));
+ g_return_if_fail(data);
+
+ if (ATK_OBJECT_CLASS(parent_class)->initialize)
+ ATK_OBJECT_CLASS(parent_class)->initialize(object, data);
+
+ WEBKIT_ACCESSIBLE(object)->m_object = reinterpret_cast<AccessibilityObject*>(data);
+}
+
+static void webkit_accessible_finalize(GObject* object)
+{
+ // This is a good time to clear the return buffer.
+ returnString(String());
+
+ if (G_OBJECT_CLASS(parent_class)->finalize)
+ G_OBJECT_CLASS(parent_class)->finalize(object);
+}
+
+static const gchar* webkit_accessible_get_name(AtkObject* object)
+{
+ // TODO: Deal with later changes.
+ if (!object->name)
+ atk_object_set_name(object, core(object)->title().utf8().data());
+ return object->name;
+}
+
+static const gchar* webkit_accessible_get_description(AtkObject* object)
+{
+ // TODO: the Mozilla MSAA implementation prepends "Description: "
+ // Should we do this too?
+
+ // TODO: Deal with later changes.
+ if (!object->description)
+ atk_object_set_description(object, core(object)->accessibilityDescription().utf8().data());
+ return object->description;
+}
+
+static AtkObject* webkit_accessible_get_parent(AtkObject* object)
+{
+ AccessibilityObject* coreParent = core(object)->parentObject();
+
+ if (!coreParent)
+ return NULL;
+
+ return coreParent->wrapper();
+}
+
+static gint webkit_accessible_get_n_children(AtkObject* object)
+{
+ return core(object)->children().size();
+}
+
+static AtkObject* webkit_accessible_ref_child(AtkObject* object, gint index)
+{
+ AccessibilityObject* coreObject = core(object);
+
+ g_return_val_if_fail(index >= 0, NULL);
+ g_return_val_if_fail(static_cast<size_t>(index) < coreObject->children().size(), NULL);
+
+ AccessibilityObject* coreChild = coreObject->children().at(index).get();
+
+ if (!coreChild)
+ return NULL;
+
+ AtkObject* child = coreChild->wrapper();
+ // TODO: Should we call atk_object_set_parent() here?
+ //atk_object_set_parent(child, object);
+ g_object_ref(child);
+
+ return child;
+}
+
+static gint webkit_accessible_get_index_in_parent(AtkObject* object)
+{
+ // FIXME: This needs to be implemented.
+ notImplemented();
+ return 0;
+}
+
+static AtkRole atkRole(AccessibilityRole role)
+{
+ switch (role) {
+ case WebCore::ButtonRole:
+ return ATK_ROLE_PUSH_BUTTON;
+ case WebCore::RadioButtonRole:
+ return ATK_ROLE_RADIO_BUTTON;
+ case WebCore::CheckBoxRole:
+ return ATK_ROLE_CHECK_BOX;
+ case WebCore::SliderRole:
+ return ATK_ROLE_SLIDER;
+ case WebCore::TabGroupRole:
+ return ATK_ROLE_PAGE_TAB_LIST;
+ case WebCore::TextFieldRole:
+ case WebCore::TextAreaRole:
+ case WebCore::ListMarkerRole:
+ return ATK_ROLE_ENTRY;
+ case WebCore::StaticTextRole:
+ return ATK_ROLE_TEXT; //?
+ case WebCore::OutlineRole:
+ return ATK_ROLE_TREE;
+ case WebCore::ColumnRole:
+ return ATK_ROLE_UNKNOWN; //?
+ case WebCore::RowRole:
+ return ATK_ROLE_LIST_ITEM;
+ case WebCore::GroupRole:
+ return ATK_ROLE_UNKNOWN; //?
+ case WebCore::ListRole:
+ return ATK_ROLE_LIST;
+ case WebCore::TableRole:
+ return ATK_ROLE_TABLE;
+ case WebCore::LinkRole:
+ case WebCore::WebCoreLinkRole:
+ return ATK_ROLE_LINK;
+ case WebCore::ImageMapRole:
+ case WebCore::ImageRole:
+ return ATK_ROLE_IMAGE;
+ default:
+ return ATK_ROLE_UNKNOWN;
+ }
+}
+
+static AtkRole webkit_accessible_get_role(AtkObject* object)
+{
+ return atkRole(core(object)->roleValue());
+}
+
+static void webkit_accessible_class_init(AtkObjectClass* klass)
+{
+ GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
+
+ parent_class = g_type_class_peek_parent(klass);
+
+ klass->initialize = webkit_accessible_init;
+
+ gobject_class->finalize = webkit_accessible_finalize;
+
+ klass->get_name = webkit_accessible_get_name;
+ klass->get_description = webkit_accessible_get_description;
+ klass->get_parent = webkit_accessible_get_parent;
+ klass->get_n_children = webkit_accessible_get_n_children;
+ klass->ref_child = webkit_accessible_ref_child;
+ //klass->get_index_in_parent = webkit_accessible_get_index_in_parent;
+ klass->get_role = webkit_accessible_get_role;
+ //klass->get_attributes = webkit_accessible_get_attributes;
+ //klass->ref_state_set = webkit_accessible_ref_state_set;
+ //klass->ref_relation_set = webkit_accessible_ref_relation_set;
+}
+
+static gboolean webkit_accessible_action_do_action(AtkAction* action, gint i)
+{
+ g_return_val_if_fail(i == 0, FALSE);
+ return core(action)->performDefaultAction();
+}
+
+static gint webkit_accessible_action_get_n_actions(AtkAction* action)
+{
+ return 1;
+}
+
+static const gchar* webkit_accessible_action_get_description(AtkAction* action, gint i)
+{
+ g_return_val_if_fail(i == 0, NULL);
+ // TODO: Need a way to provide/localize action descriptions.
+ notImplemented();
+ return "";
+}
+
+static const gchar* webkit_accessible_action_get_keybinding(AtkAction* action, gint i)
+{
+ g_return_val_if_fail(i == 0, NULL);
+ // FIXME: Construct a proper keybinding string.
+ return returnString(core(action)->accessKey().string());
+}
+
+static const gchar* webkit_accessible_action_get_name(AtkAction* action, gint i)
+{
+ g_return_val_if_fail(i == 0, NULL);
+ return returnString(core(action)->actionVerb());
+}
+
+static void atk_action_interface_init(AtkActionIface* iface)
+{
+ g_return_if_fail(iface);
+
+ iface->do_action = webkit_accessible_action_do_action;
+ iface->get_n_actions = webkit_accessible_action_get_n_actions;
+ iface->get_description = webkit_accessible_action_get_description;
+ iface->get_keybinding = webkit_accessible_action_get_keybinding;
+ iface->get_name = webkit_accessible_action_get_name;
+}
+
+// Text
+
+static gchar* webkit_accessible_text_get_text(AtkText* text, gint start_offset, gint end_offset)
+{
+ String ret = core(text)->doAXStringForRange(PlainTextRange(start_offset, end_offset - start_offset));
+ // TODO: Intentionally copied?
+ return g_strdup(ret.utf8().data());
+}
+
+static gchar* webkit_accessible_text_get_text_after_offset(AtkText* text, gint offset, AtkTextBoundary boundary_type, gint* start_offset, gint* end_offset)
+{
+ notImplemented();
+ return NULL;
+}
+
+static gchar* webkit_accessible_text_get_text_at_offset(AtkText* text, gint offset, AtkTextBoundary boundary_type, gint* start_offset, gint* end_offset)
+{
+ notImplemented();
+ return NULL;
+}
+
+static gunichar webkit_accessible_text_get_character_at_offset(AtkText* text, gint offset)
+{
+ notImplemented();
+ return 0;
+}
+
+static gchar* webkit_accessible_text_get_text_before_offset(AtkText* text, gint offset, AtkTextBoundary boundary_type, gint* start_offset, gint* end_offset)
+{
+ notImplemented();
+ return NULL;
+}
+
+static gint webkit_accessible_text_get_caret_offset(AtkText* text)
+{
+ // TODO: Verify this, especially for RTL text.
+ return core(text)->selectionStart();
+}
+
+static AtkAttributeSet* webkit_accessible_text_get_run_attributes(AtkText* text, gint offset, gint* start_offset, gint* end_offset)
+{
+ notImplemented();
+ return NULL;
+}
+
+static AtkAttributeSet* webkit_accessible_text_get_default_attributes(AtkText* text)
+{
+ notImplemented();
+ return NULL;
+}
+
+static void webkit_accessible_text_get_character_extents(AtkText* text, gint offset, gint* x, gint* y, gint* width, gint* height, AtkCoordType coords)
+{
+ IntRect extents = core(text)->doAXBoundsForRange(PlainTextRange(offset, 1));
+ // FIXME: Use the AtkCoordType
+ // Requires WebCore::ScrollView::contentsToScreen() to be implemented
+
+#if 0
+ switch(coords) {
+ case ATK_XY_SCREEN:
+ extents = core(text)->document()->view()->contentsToScreen(extents);
+ break;
+ case ATK_XY_WINDOW:
+ // No-op
+ break;
+ }
+#endif
+
+ *x = extents.x();
+ *y = extents.y();
+ *width = extents.width();
+ *height = extents.height();
+}
+
+static gint webkit_accessible_text_get_character_count(AtkText* text)
+{
+ return core(text)->textLength();
+}
+
+static gint webkit_accessible_text_get_offset_at_point(AtkText* text, gint x, gint y, AtkCoordType coords)
+{
+ // FIXME: Use the AtkCoordType
+ // TODO: Is it correct to ignore range.length?
+ IntPoint pos(x, y);
+ PlainTextRange range = core(text)->doAXRangeForPosition(pos);
+ return range.start;
+}
+
+static gint webkit_accessible_text_get_n_selections(AtkText* text)
+{
+ notImplemented();
+ return 0;
+}
+
+static gchar* webkit_accessible_text_get_selection(AtkText* text, gint selection_num, gint* start_offset, gint* end_offset)
+{
+ notImplemented();
+ return NULL;
+}
+
+static gboolean webkit_accessible_text_add_selection(AtkText* text, gint start_offset, gint end_offset)
+{
+ notImplemented();
+ return FALSE;
+}
+
+static gboolean webkit_accessible_text_remove_selection(AtkText* text, gint selection_num)
+{
+ notImplemented();
+ return FALSE;
+}
+
+static gboolean webkit_accessible_text_set_selection(AtkText* text, gint selection_num, gint start_offset, gint end_offset)
+{
+ notImplemented();
+ return FALSE;
+}
+
+static gboolean webkit_accessible_text_set_caret_offset(AtkText* text, gint offset)
+{
+ // TODO: Verify
+ //core(text)->setSelectedTextRange(PlainTextRange(offset, 0));
+ AccessibilityObject* coreObject = core(text);
+ coreObject->setSelectedVisiblePositionRange(coreObject->visiblePositionRangeForRange(PlainTextRange(offset, 0)));
+ return TRUE;
+}
+
+#if 0
+// Signal handlers
+static void webkit_accessible_text_text_changed(AtkText* text, gint position, gint length)
+{
+}
+
+static void webkit_accessible_text_text_caret_moved(AtkText* text, gint location)
+{
+}
+
+static void webkit_accessible_text_text_selection_changed(AtkText* text)
+{
+}
+
+static void webkit_accessible_text_text_attributes_changed(AtkText* text)
+{
+}
+
+static void webkit_accessible_text_get_range_extents(AtkText* text, gint start_offset, gint end_offset, AtkCoordType coord_type, AtkTextRectangle* rect)
+{
+}
+
+static AtkTextRange** webkit_accessible_text_get_bounded_ranges(AtkText* text, AtkTextRectangle* rect, AtkCoordType coord_type, AtkTextClipType x_clip_type, AtkTextClipType y_clip_type)
+{
+}
+#endif
+
+static void atk_text_interface_init(AtkTextIface* iface)
+{
+ g_return_if_fail(iface);
+
+ iface->get_text = webkit_accessible_text_get_text;
+ iface->get_text_after_offset = webkit_accessible_text_get_text_after_offset;
+ iface->get_text_at_offset = webkit_accessible_text_get_text_at_offset;
+ iface->get_character_at_offset = webkit_accessible_text_get_character_at_offset;
+ iface->get_text_before_offset = webkit_accessible_text_get_text_before_offset;
+ iface->get_caret_offset = webkit_accessible_text_get_caret_offset;
+ iface->get_run_attributes = webkit_accessible_text_get_run_attributes;
+ iface->get_default_attributes = webkit_accessible_text_get_default_attributes;
+ iface->get_character_extents = webkit_accessible_text_get_character_extents;
+ //iface->get_range_extents = ;
+ iface->get_character_count = webkit_accessible_text_get_character_count;
+ iface->get_offset_at_point = webkit_accessible_text_get_offset_at_point;
+ iface->get_n_selections = webkit_accessible_text_get_n_selections;
+ iface->get_selection = webkit_accessible_text_get_selection;
+
+ // set methods
+ iface->add_selection = webkit_accessible_text_add_selection;
+ iface->remove_selection = webkit_accessible_text_remove_selection;
+ iface->set_selection = webkit_accessible_text_set_selection;
+ iface->set_caret_offset = webkit_accessible_text_set_caret_offset;
+}
+
+// EditableText
+
+static gboolean webkit_accessible_editable_text_set_run_attributes(AtkEditableText* text, AtkAttributeSet* attrib_set, gint start_offset, gint end_offset)
+{
+ notImplemented();
+ return FALSE;
+}
+
+static void webkit_accessible_editable_text_set_text_contents(AtkEditableText* text, const gchar* string)
+{
+ // FIXME: string nullcheck?
+ core(text)->setValue(String::fromUTF8(string));
+}
+
+static void webkit_accessible_editable_text_insert_text(AtkEditableText* text, const gchar* string, gint length, gint* position)
+{
+ // FIXME: string nullcheck?
+
+ AccessibilityObject* coreObject = core(text);
+ // FIXME: Not implemented in WebCore
+ //coreObject->setSelectedTextRange(PlainTextRange(*position, 0));
+ //coreObject->setSelectedText(String::fromUTF8(string));
+
+ if (!coreObject->document() || !coreObject->document()->frame())
+ return;
+ coreObject->setSelectedVisiblePositionRange(coreObject->visiblePositionRangeForRange(PlainTextRange(*position, 0)));
+ coreObject->setFocused(true);
+ // FIXME: We should set position to the actual inserted text length, which may be less than that requested.
+ if (coreObject->document()->frame()->editor()->insertTextWithoutSendingTextEvent(String::fromUTF8(string), false, 0))
+ *position += length;
+}
+
+static void webkit_accessible_editable_text_copy_text(AtkEditableText* text, gint start_pos, gint end_pos)
+{
+ notImplemented();
+}
+
+static void webkit_accessible_editable_text_cut_text(AtkEditableText* text, gint start_pos, gint end_pos)
+{
+ notImplemented();
+}
+
+static void webkit_accessible_editable_text_delete_text(AtkEditableText* text, gint start_pos, gint end_pos)
+{
+ AccessibilityObject* coreObject = core(text);
+ // FIXME: Not implemented in WebCore
+ //coreObject->setSelectedTextRange(PlainTextRange(start_pos, end_pos - start_pos));
+ //coreObject->setSelectedText(String());
+
+ if (!coreObject->document() || !coreObject->document()->frame())
+ return;
+ coreObject->setSelectedVisiblePositionRange(coreObject->visiblePositionRangeForRange(PlainTextRange(start_pos, end_pos - start_pos)));
+ coreObject->setFocused(true);
+ coreObject->document()->frame()->editor()->performDelete();
+}
+
+static void webkit_accessible_editable_text_paste_text(AtkEditableText* text, gint position)
+{
+ notImplemented();
+}
+
+static void atk_editable_text_interface_init(AtkEditableTextIface* iface)
+{
+ g_return_if_fail(iface);
+
+ iface->set_run_attributes = webkit_accessible_editable_text_set_run_attributes;
+ iface->set_text_contents = webkit_accessible_editable_text_set_text_contents;
+ iface->insert_text = webkit_accessible_editable_text_insert_text;
+ iface->copy_text = webkit_accessible_editable_text_copy_text;
+ iface->cut_text = webkit_accessible_editable_text_cut_text;
+ iface->delete_text = webkit_accessible_editable_text_delete_text;
+ iface->paste_text = webkit_accessible_editable_text_paste_text;
+}
+
+// StreamableContent
+
+static gint webkit_accessible_streamable_content_get_n_mime_types(AtkStreamableContent* streamable)
+{
+ notImplemented();
+ return 0;
+}
+
+static G_CONST_RETURN gchar* webkit_accessible_streamable_content_get_mime_type(AtkStreamableContent* streamable, gint i)
+{
+ notImplemented();
+ return "";
+}
+
+static GIOChannel* webkit_accessible_streamable_content_get_stream(AtkStreamableContent* streamable, const gchar* mime_type)
+{
+ notImplemented();
+ return NULL;
+}
+
+static G_CONST_RETURN gchar* webkit_accessible_streamable_content_get_uri(AtkStreamableContent* streamable, const gchar* mime_type)
+{
+ notImplemented();
+ return NULL;
+}
+
+static void atk_streamable_content_interface_init(AtkStreamableContentIface* iface)
+{
+ g_return_if_fail(iface);
+
+ iface->get_n_mime_types = webkit_accessible_streamable_content_get_n_mime_types;
+ iface->get_mime_type = webkit_accessible_streamable_content_get_mime_type;
+ iface->get_stream = webkit_accessible_streamable_content_get_stream;
+ iface->get_uri = webkit_accessible_streamable_content_get_uri;
+}
+
+GType webkit_accessible_get_type()
+{
+ static GType type = 0;
+
+ if (!type) {
+ static const GTypeInfo tinfo = {
+ sizeof(WebKitAccessibleClass),
+ (GBaseInitFunc)NULL,
+ (GBaseFinalizeFunc)NULL,
+ (GClassInitFunc)webkit_accessible_class_init,
+ (GClassFinalizeFunc)NULL,
+ NULL, /* class data */
+ sizeof(WebKitAccessible), /* instance size */
+ 0, /* nb preallocs */
+ (GInstanceInitFunc)NULL,
+ NULL /* value table */
+ };
+
+ type = g_type_register_static(ATK_TYPE_OBJECT, "WebKitAccessible", &tinfo, static_cast<GTypeFlags>(0));
+
+ // TODO: Only implement interfaces when necessary, not for all objects.
+ static const GInterfaceInfo atk_action_info =
+ {
+ (GInterfaceInitFunc) atk_action_interface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+ g_type_add_interface_static(type, ATK_TYPE_ACTION, &atk_action_info);
+
+ static const GInterfaceInfo atk_text_info =
+ {
+ (GInterfaceInitFunc) atk_text_interface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+ g_type_add_interface_static(type, ATK_TYPE_TEXT, &atk_text_info);
+
+ static const GInterfaceInfo atk_editable_text_info =
+ {
+ (GInterfaceInitFunc) atk_editable_text_interface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+ g_type_add_interface_static(type, ATK_TYPE_EDITABLE_TEXT, &atk_editable_text_info);
+
+ static const GInterfaceInfo atk_streamable_content_info =
+ {
+ (GInterfaceInitFunc) atk_streamable_content_interface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+ g_type_add_interface_static(type, ATK_TYPE_STREAMABLE_CONTENT, &atk_streamable_content_info);
+ }
+ return type;
+}
+
+WebKitAccessible* webkit_accessible_new(AccessibilityObject* coreObject)
+{
+ GType type = WEBKIT_TYPE_ACCESSIBLE;
+ AtkObject* object = static_cast<AtkObject*>(g_object_new(type, NULL));
+ atk_object_initialize(object, coreObject);
+ return WEBKIT_ACCESSIBLE(object);
+}
+
+AccessibilityObject* webkit_accessible_get_accessibility_object(WebKitAccessible* accessible)
+{
+ return accessible->m_object;
+}
+
+// FIXME: Remove this static initialization.
+static AXObjectCache* fallbackCache = new AXObjectCache();
+
+void webkit_accessible_detach(WebKitAccessible* accessible)
+{
+ ASSERT(accessible->m_object);
+
+ // We replace the WebCore AccessibilityObject with a fallback object that
+ // provides default implementations to avoid repetitive null-checking after
+ // detachment.
+
+ // FIXME: Using fallbackCache->get(ListBoxOptionRole) is a hack.
+ accessible->m_object = fallbackCache->get(ListBoxOptionRole);
+}
+
+}
+
+namespace WebCore {
+
+// AccessibilityObject implementations
+
+AccessibilityObjectWrapper* AccessibilityObject::wrapper() const
+{
+ return m_wrapper;
+}
+
+void AccessibilityObject::setWrapper(AccessibilityObjectWrapper* wrapper)
+{
+ if (m_wrapper)
+ g_object_unref(m_wrapper);
+
+ m_wrapper = wrapper;
+
+ if (m_wrapper)
+ g_object_ref(m_wrapper);
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/gtk/AccessibilityObjectWrapperAtk.h b/WebCore/page/gtk/AccessibilityObjectWrapperAtk.h
new file mode 100644
index 0000000..ecfb99e
--- /dev/null
+++ b/WebCore/page/gtk/AccessibilityObjectWrapperAtk.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2008 Nuanti Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef AccessibilityObjectWrapperAtk_h
+#define AccessibilityObjectWrapperAtk_h
+
+#include <atk/atk.h>
+
+namespace WebCore {
+ class AccessibilityObject;
+}
+
+G_BEGIN_DECLS
+
+#define WEBKIT_TYPE_ACCESSIBLE (webkit_accessible_get_type ())
+#define WEBKIT_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), WEBKIT_TYPE_ACCESSIBLE, WebKitAccessible))
+#define WEBKIT_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), WEBKIT_TYPE_ACCESSIBLE, WebKitAccessibleClass))
+#define WEBKIT_IS_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), WEBKIT_TYPE_ACCESSIBLE))
+#define WEBKIT_IS_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), WEBKIT_TYPE_ACCESSIBLE))
+#define WEBKIT_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), WEBKIT_TYPE_ACCESSIBLE, WebKitAccessibleClass))
+
+typedef struct _WebKitAccessible WebKitAccessible;
+typedef struct _WebKitAccessibleClass WebKitAccessibleClass;
+
+struct _WebKitAccessible
+{
+ AtkObject parent;
+ WebCore::AccessibilityObject* m_object;
+};
+
+struct _WebKitAccessibleClass
+{
+ AtkObjectClass parent_class;
+};
+
+GType webkit_accessible_get_type (void) G_GNUC_CONST;
+
+WebKitAccessible* webkit_accessible_new (WebCore::AccessibilityObject* core_object);
+
+WebCore::AccessibilityObject* webkit_accessible_get_accessibility_object (WebKitAccessible* accessible);
+
+void webkit_accessible_detach (WebKitAccessible* accessible);
+
+G_END_DECLS
+
+#endif // AccessibilityObjectWrapperAtk_h
diff --git a/WebCore/page/gtk/EventHandlerGtk.cpp b/WebCore/page/gtk/EventHandlerGtk.cpp
index 8215a4e..bb650b4 100644
--- a/WebCore/page/gtk/EventHandlerGtk.cpp
+++ b/WebCore/page/gtk/EventHandlerGtk.cpp
@@ -27,7 +27,6 @@
#include "EventHandler.h"
#include "ClipboardGtk.h"
-#include "EventNames.h"
#include "FloatPoint.h"
#include "FocusController.h"
#include "Frame.h"
@@ -36,13 +35,16 @@
#include "MouseEventWithHitTestResults.h"
#include "NotImplemented.h"
#include "Page.h"
-#include "PlatformScrollBar.h"
+#include "PlatformKeyboardEvent.h"
#include "PlatformWheelEvent.h"
#include "RenderWidget.h"
+#include "Scrollbar.h"
namespace WebCore {
-using namespace EventNames;
+unsigned EventHandler::s_accessKeyModifiers = PlatformKeyboardEvent::AltKey;
+
+const double EventHandler::TextDragDelay = 0.0;
bool EventHandler::tabsToAllControls(KeyboardEvent* event) const
{
@@ -95,9 +97,9 @@ bool EventHandler::passWheelEventToWidget(PlatformWheelEvent& event, Widget* wid
return static_cast<FrameView*>(widget)->frame()->eventHandler()->handleWheelEvent(event);
}
-Clipboard* EventHandler::createDraggingClipboard() const
+PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const
{
- return new ClipboardGtk(ClipboardWritable, true);
+ return ClipboardGtk::create(ClipboardWritable, true);
}
bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe)
@@ -118,10 +120,4 @@ bool EventHandler::passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&
return true;
}
-bool EventHandler::passMousePressEventToScrollbar(MouseEventWithHitTestResults&, PlatformScrollbar* scrollbar)
-{
- notImplemented();
- return false;
-}
-
}
diff --git a/WebCore/page/gtk/FrameGtk.cpp b/WebCore/page/gtk/FrameGtk.cpp
index b2afcbd..3cab5a0 100644
--- a/WebCore/page/gtk/FrameGtk.cpp
+++ b/WebCore/page/gtk/FrameGtk.cpp
@@ -1,9 +1,4 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
- * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com
- * Copyright (C) 2007 Holger Hans Peter Freyther
- * All rights reserved.
- *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -28,31 +23,15 @@
#include "config.h"
#include "Frame.h"
-#include "NotImplemented.h"
+#include "NotImplemented.h"
namespace WebCore {
-KJS::Bindings::Instance* Frame::createScriptInstanceForWidget(Widget*)
-{
- notImplemented();
- return 0;
-}
-
-void Frame::clearPlatformScriptObjects()
-{
- notImplemented();
-}
-
DragImageRef Frame::dragImageForSelection()
{
notImplemented();
return 0;
}
-void Frame::dashboardRegionsChanged()
-{
- notImplemented();
-}
-
}
diff --git a/WebCore/page/inspector/ConsolePanel.js b/WebCore/page/inspector/ConsolePanel.js
deleted file mode 100644
index 57bf331..0000000
--- a/WebCore/page/inspector/ConsolePanel.js
+++ /dev/null
@@ -1,459 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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.
- */
-
-WebInspector.ConsolePanel = function()
-{
- WebInspector.Panel.call(this);
-
- this.messages = [];
-
- this.commandHistory = [];
- this.commandOffset = 0;
-
- this.messageList = document.createElement("ol");
- this.messageList.className = "console-message-list";
- this.element.appendChild(this.messageList);
-
- this.messageList.addEventListener("click", this.messageListClicked.bind(this), true);
-
- this.consolePrompt = document.createElement("textarea");
- this.consolePrompt.className = "console-prompt";
- this.element.appendChild(this.consolePrompt);
-
- this.consolePrompt.addEventListener("keydown", this.promptKeyDown.bind(this), false);
-
- var clearButtonText = WebInspector.UIString("Clear");
- this.clearMessagesElement = document.createElement("button");
- this.clearMessagesElement.appendChild(document.createTextNode(clearButtonText));
- this.clearMessagesElement.title = clearButtonText;
- this.clearMessagesElement.addEventListener("click", this.clearButtonClicked.bind(this), false);
-}
-
-WebInspector.ConsolePanel.prototype = {
- show: function()
- {
- WebInspector.Panel.prototype.show.call(this);
- WebInspector.consoleListItem.select();
-
- this.clearMessagesElement.removeStyleClass("hidden");
- if (!this.clearMessagesElement.parentNode)
- document.getElementById("toolbarButtons").appendChild(this.clearMessagesElement);
- },
-
- hide: function()
- {
- WebInspector.Panel.prototype.hide.call(this);
- WebInspector.consoleListItem.deselect();
- this.clearMessagesElement.addStyleClass("hidden");
- },
-
- addMessage: function(msg)
- {
- if (msg.url in WebInspector.resourceURLMap) {
- msg.resource = WebInspector.resourceURLMap[msg.url];
- switch (msg.level) {
- case WebInspector.ConsoleMessage.MessageLevel.Warning:
- ++msg.resource.warnings;
- msg.resource.panel.addMessageToSource(msg);
- break;
- case WebInspector.ConsoleMessage.MessageLevel.Error:
- ++msg.resource.errors;
- msg.resource.panel.addMessageToSource(msg);
- break;
- }
- }
- this.messages.push(msg);
-
- var item = msg.toListItem();
- item.message = msg;
- this.messageList.appendChild(item);
- item.scrollIntoView(false);
- },
-
- clearMessages: function()
- {
- for (var i = 0; i < this.messages.length; ++i) {
- var resource = this.messages[i].resource;
- if (!resource)
- continue;
-
- resource.errors = 0;
- resource.warnings = 0;
- }
-
- this.messages = [];
- this.messageList.removeChildren();
- },
-
- clearButtonClicked: function()
- {
- this.clearMessages();
- },
-
- messageListClicked: function(event)
- {
- var link = event.target.firstParentOrSelfWithNodeName("a");
- if (link && link.representedNode) {
- WebInspector.updateFocusedNode(link.representedNode);
- return;
- }
-
- var item = event.target.firstParentOrSelfWithNodeName("li");
- if (!item)
- return;
-
- var resource = item.message.resource;
- if (!resource)
- return;
-
- if (link && link.hasStyleClass("console-message-url")) {
- WebInspector.navigateToResource(resource);
- resource.panel.showSourceLine(item.message.line);
- }
-
- event.stopPropagation();
- event.preventDefault();
- },
-
- promptKeyDown: function(event)
- {
- switch (event.keyIdentifier) {
- case "Enter":
- this._onEnterPressed(event);
- break;
- case "Up":
- this._onUpPressed(event);
- break;
- case "Down":
- this._onDownPressed(event);
- break;
- }
- },
-
- _onEnterPressed: function(event)
- {
- event.preventDefault();
- event.stopPropagation();
-
- var str = this.consolePrompt.value;
- if (!str.length)
- return;
-
- this.commandHistory.push(str);
- this.commandOffset = 0;
-
- this.consolePrompt.value = "";
-
- var result;
- var exception = false;
- try {
- // This with block is needed to work around http://bugs.webkit.org/show_bug.cgi?id=11399
- with (InspectorController.inspectedWindow()) {
- result = eval(str);
- }
- } catch(e) {
- result = e;
- exception = true;
- }
-
- var level = exception ? WebInspector.ConsoleMessage.MessageLevel.Error : WebInspector.ConsoleMessage.MessageLevel.Log;
-
- this.addMessage(new WebInspector.ConsoleCommand(str, this._format(result)));
- },
-
- _onUpPressed: function(event)
- {
- event.preventDefault();
- event.stopPropagation();
-
- if (this.commandOffset == this.commandHistory.length)
- return;
-
- if (this.commandOffset == 0)
- this.tempSavedCommand = this.consolePrompt.value;
-
- ++this.commandOffset;
- this.consolePrompt.value = this.commandHistory[this.commandHistory.length - this.commandOffset];
- this.consolePrompt.moveCursorToEnd();
- },
-
- _onDownPressed: function(event)
- {
- event.preventDefault();
- event.stopPropagation();
-
- if (this.commandOffset == 0)
- return;
-
- --this.commandOffset;
-
- if (this.commandOffset == 0) {
- this.consolePrompt.value = this.tempSavedCommand;
- this.consolePrompt.moveCursorToEnd();
- delete this.tempSavedCommand;
- return;
- }
-
- this.consolePrompt.value = this.commandHistory[this.commandHistory.length - this.commandOffset];
- this.consolePrompt.moveCursorToEnd();
- },
-
- _format: function(output)
- {
- var type = Object.type(output);
- if (type === "object") {
- if (output instanceof Node)
- type = "node";
- }
-
- // We don't perform any special formatting on these types, so we just
- // pass them through the simple _formatvalue function.
- var undecoratedTypes = {
- "undefined": 1,
- "null": 1,
- "boolean": 1,
- "number": 1,
- "date": 1,
- "function": 1,
- };
-
- var formatter;
- if (type in undecoratedTypes)
- formatter = "_formatvalue";
- else {
- formatter = "_format" + type;
- if (!(formatter in this)) {
- formatter = "_formatobject";
- type = "object";
- }
- }
-
- var span = document.createElement("span");
- span.addStyleClass("console-formatted-" + type);
- this[formatter](output, span);
- return span;
- },
-
- _formatvalue: function(val, elem)
- {
- elem.appendChild(document.createTextNode(val));
- },
-
- _formatstring: function(str, elem)
- {
- elem.appendChild(document.createTextNode("\"" + str + "\""));
- },
-
- _formatregexp: function(re, elem)
- {
- var formatted = String(re).replace(/([\\\/])/g, "\\$1").replace(/\\(\/[gim]*)$/, "$1").substring(1);
- elem.appendChild(document.createTextNode(formatted));
- },
-
- _formatarray: function(arr, elem)
- {
- elem.appendChild(document.createTextNode("["));
- for (var i = 0; i < arr.length; ++i) {
- elem.appendChild(this._format(arr[i]));
- if (i < arr.length - 1)
- elem.appendChild(document.createTextNode(", "));
- }
- elem.appendChild(document.createTextNode("]"));
- },
-
- _formatnode: function(node, elem)
- {
- var anchor = document.createElement("a");
- anchor.innerHTML = node.titleInfo().title;
- anchor.representedNode = node;
- elem.appendChild(anchor);
- },
-
- _formatobject: function(obj, elem)
- {
- elem.appendChild(document.createTextNode(Object.describe(obj)));
- },
-}
-
-WebInspector.ConsolePanel.prototype.__proto__ = WebInspector.Panel.prototype;
-
-WebInspector.ConsoleMessage = function(source, level, message, line, url)
-{
- this.source = source;
- this.level = level;
- this.message = message;
- this.line = line;
- this.url = url;
-}
-
-WebInspector.ConsoleMessage.prototype = {
- get shortURL()
- {
- if (this.resource)
- return this.resource.displayName;
- return this.url;
- },
-
- toListItem: function()
- {
- var item = document.createElement("li");
- item.className = "console-message";
- switch (this.source) {
- case WebInspector.ConsoleMessage.MessageSource.HTML:
- item.className += " console-html-source";
- break;
- case WebInspector.ConsoleMessage.MessageSource.XML:
- item.className += " console-xml-source";
- break;
- case WebInspector.ConsoleMessage.MessageSource.JS:
- item.className += " console-js-source";
- break;
- case WebInspector.ConsoleMessage.MessageSource.CSS:
- item.className += " console-css-source";
- break;
- case WebInspector.ConsoleMessage.MessageSource.Other:
- item.className += " console-other-source";
- break;
- }
-
- switch (this.level) {
- case WebInspector.ConsoleMessage.MessageLevel.Tip:
- item.className += " console-tip-level";
- break;
- case WebInspector.ConsoleMessage.MessageLevel.Log:
- item.className += " console-log-level";
- break;
- case WebInspector.ConsoleMessage.MessageLevel.Warning:
- item.className += " console-warning-level";
- break;
- case WebInspector.ConsoleMessage.MessageLevel.Error:
- item.className += " console-error-level";
- }
-
- var messageDiv = document.createElement("div");
- messageDiv.className = "console-message-message";
- messageDiv.textContent = this.message;
- item.appendChild(messageDiv);
-
- if (this.url && this.url !== "undefined") {
- var urlElement = document.createElement("a");
- urlElement.className = "console-message-url";
-
- if (this.line > 0)
- urlElement.textContent = WebInspector.UIString("%s (line %d)", this.url, this.line);
- else
- urlElement.textContent = this.url;
-
- item.appendChild(urlElement);
- }
-
- return item;
- },
-
- toString: function()
- {
- var sourceString;
- switch (this.source) {
- case WebInspector.ConsoleMessage.MessageSource.HTML:
- sourceString = "HTML";
- break;
- case WebInspector.ConsoleMessage.MessageSource.XML:
- sourceString = "XML";
- break;
- case WebInspector.ConsoleMessage.MessageSource.JS:
- sourceString = "JS";
- break;
- case WebInspector.ConsoleMessage.MessageSource.CSS:
- sourceString = "CSS";
- break;
- case WebInspector.ConsoleMessage.MessageSource.Other:
- sourceString = "Other";
- break;
- }
-
- var levelString;
- switch (this.level) {
- case WebInspector.ConsoleMessage.MessageLevel.Tip:
- levelString = "Tip";
- break;
- case WebInspector.ConsoleMessage.MessageLevel.Log:
- levelString = "Log";
- break;
- case WebInspector.ConsoleMessage.MessageLevel.Warning:
- levelString = "Warning";
- break;
- case WebInspector.ConsoleMessage.MessageLevel.Error:
- levelString = "Error";
- break;
- }
-
- return sourceString + " " + levelString + ": " + this.message + "\n" + this.url + " line " + this.line;
- }
-}
-
-// Note: Keep these constants in sync with the ones in Chrome.h
-WebInspector.ConsoleMessage.MessageSource = {
- HTML: 0,
- XML: 1,
- JS: 2,
- CSS: 3,
- Other: 4,
-};
-
-WebInspector.ConsoleMessage.MessageLevel = {
- Tip: 0,
- Log: 1,
- Warning: 2,
- Error: 3,
-};
-
-WebInspector.ConsoleCommand = function(input, output)
-{
- this.input = input;
- this.output = output;
-}
-
-WebInspector.ConsoleCommand.prototype = {
- toListItem: function()
- {
- var item = document.createElement("li");
- item.className = "console-command";
-
- var inputDiv = document.createElement("div");
- inputDiv.className = "console-command-input";
- inputDiv.textContent = this.input;
- item.appendChild(inputDiv);
-
- var outputDiv = document.createElement("div");
- outputDiv.className = "console-command-output";
- outputDiv.appendChild(this.output);
- item.appendChild(outputDiv);
-
- return item;
- }
-}
diff --git a/WebCore/page/inspector/Database.js b/WebCore/page/inspector/Database.js
deleted file mode 100644
index 36e89da..0000000
--- a/WebCore/page/inspector/Database.js
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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.
- */
-
-WebInspector.Database = function(database, domain, name, version)
-{
- this.database = database;
- this.domain = domain;
- this.name = name;
- this.version = version;
-
- this.listItem = new WebInspector.ResourceTreeElement(this);
- this.updateTitle();
-
- this.category.addResource(this);
-}
-
-WebInspector.Database.prototype = {
- get database()
- {
- return this._database;
- },
-
- set database(x)
- {
- if (this._database === x)
- return;
- this._database = x;
- },
-
- get name()
- {
- return this._name;
- },
-
- set name(x)
- {
- if (this._name === x)
- return;
- this._name = x;
- this.updateTitleSoon();
- },
-
- get version()
- {
- return this._version;
- },
-
- set version(x)
- {
- if (this._version === x)
- return;
- this._version = x;
- },
-
- get domain()
- {
- return this._domain;
- },
-
- set domain(x)
- {
- if (this._domain === x)
- return;
- this._domain = x;
- this.updateTitleSoon();
- },
-
- get category()
- {
- return WebInspector.resourceCategories.databases;
- },
-
- updateTitle: function()
- {
- delete this.updateTitleTimeout;
-
- var title = this.name;
-
- var info = "";
- if (this.domain && (!WebInspector.mainResource || (WebInspector.mainResource && this.domain !== WebInspector.mainResource.domain)))
- info = this.domain;
-
- var fullTitle = "<span class=\"title" + (info && info.length ? "" : " only") + "\">" + title.escapeHTML() + "</span>";
- if (info && info.length)
- fullTitle += "<span class=\"info\">" + info.escapeHTML() + "</span>";
- fullTitle += "<div class=\"icon database\"></div>";
-
- this.listItem.title = fullTitle;
- },
-
- get panel()
- {
- if (!this._panel)
- this._panel = new WebInspector.DatabasePanel(this);
- return this._panel;
- },
-
- // Inherit the other functions from the Resource prototype.
- updateTitleSoon: WebInspector.Resource.prototype.updateTitleSoon,
- select: WebInspector.Resource.prototype.select,
- deselect: WebInspector.Resource.prototype.deselect,
- attach: WebInspector.Resource.prototype.attach,
- detach: WebInspector.Resource.prototype.detach
-}
diff --git a/WebCore/page/inspector/DatabasePanel.js b/WebCore/page/inspector/DatabasePanel.js
deleted file mode 100644
index 9101b9c..0000000
--- a/WebCore/page/inspector/DatabasePanel.js
+++ /dev/null
@@ -1,462 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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.
- */
-
-WebInspector.DatabasePanel = function(database, views)
-{
- var allViews = [{ title: WebInspector.UIString("Query"), name: "query" }, { title: WebInspector.UIString("Browse"), name: "browse" }];
- if (views)
- allViews = allViews.concat(views);
-
- WebInspector.ResourcePanel.call(this, database, allViews);
-
- this.currentView = this.views.browse;
-
- this.queryPromptElement = document.createElement("textarea");
- this.queryPromptElement.className = "database-prompt";
- this.element.appendChild(this.queryPromptElement);
-
- this.queryPromptElement.addEventListener("keydown", this.queryInputKeyDown.bind(this), false);
-
- this.queryPromptHistory = [];
- this.queryPromptHistoryOffset = 0;
-
- var queryView = this.views.query;
-
- queryView.commandListElement = document.createElement("ol");
- queryView.commandListElement.className = "database-command-list";
- queryView.contentElement.appendChild(queryView.commandListElement);
-
- var panel = this;
- queryView.show = function()
- {
- panel.queryPromptElement.focus();
- this.commandListElement.scrollTop = this.previousScrollTop;
- };
-
- queryView.hide = function()
- {
- this.previousScrollTop = this.commandListElement.scrollTop;
- };
-
- var browseView = this.views.browse;
-
- browseView.reloadTableElement = document.createElement("button");
- browseView.reloadTableElement.appendChild(document.createElement("img"));
- browseView.reloadTableElement.className = "database-table-reload";
- browseView.reloadTableElement.title = WebInspector.UIString("Reload");
- browseView.reloadTableElement.addEventListener("click", this.reloadClicked.bind(this), false);
-
- browseView.show = function()
- {
- panel.updateTableList();
- panel.queryPromptElement.focus();
-
- this.tableSelectElement.removeStyleClass("hidden");
- if (!this.tableSelectElement.parentNode)
- document.getElementById("toolbarButtons").appendChild(this.tableSelectElement);
-
- this.reloadTableElement.removeStyleClass("hidden");
- if (!this.reloadTableElement.parentNode)
- document.getElementById("toolbarButtons").appendChild(this.reloadTableElement);
-
- this.contentElement.scrollTop = this.previousScrollTop;
- };
-
- browseView.hide = function()
- {
- this.tableSelectElement.addStyleClass("hidden");
- this.reloadTableElement.addStyleClass("hidden");
- this.previousScrollTop = this.contentElement.scrollTop;
- };
-}
-
-// FIXME: The function and local variables are a workaround for http://bugs.webkit.org/show_bug.cgi?id=15574.
-WebInspector.DatabasePanel.prototype = (function() {
-var document = window.document;
-var Math = window.Math;
-return {
- show: function()
- {
- WebInspector.ResourcePanel.prototype.show.call(this);
- this.queryPromptElement.focus();
- },
-
- get currentTable()
- {
- return this._currentTable;
- },
-
- set currentTable(x)
- {
- if (this._currentTable === x)
- return;
-
- this._currentTable = x;
-
- if (x) {
- var browseView = this.views.browse;
- if (browseView.tableSelectElement) {
- var length = browseView.tableSelectElement.options.length;
- for (var i = 0; i < length; ++i) {
- var option = browseView.tableSelectElement.options[i];
- if (option.value === x) {
- browseView.tableSelectElement.selectedIndex = i;
- break;
- }
- }
- }
-
- this.updateTableBrowser();
- }
- },
-
- reloadClicked: function()
- {
- this.updateTableList();
- this.updateTableBrowser();
- },
-
- updateTableList: function()
- {
- var browseView = this.views.browse;
- if (!browseView.tableSelectElement) {
- browseView.tableSelectElement = document.createElement("select");
- browseView.tableSelectElement.className = "database-table-select hidden";
-
- var panel = this;
- var changeTableFunction = function()
- {
- var index = browseView.tableSelectElement.selectedIndex;
- if (index != -1)
- panel.currentTable = browseView.tableSelectElement.options[index].value;
- else
- panel.currentTable = null;
- };
-
- browseView.tableSelectElement.addEventListener("change", changeTableFunction, false);
- }
-
- browseView.tableSelectElement.removeChildren();
-
- var selectedTableName = this.currentTable;
- var tableNames = InspectorController.databaseTableNames(this.resource.database).sort();
-
- var length = tableNames.length;
- for (var i = 0; i < length; ++i) {
- var option = document.createElement("option");
- option.value = tableNames[i];
- option.text = tableNames[i];
- browseView.tableSelectElement.appendChild(option);
-
- if (tableNames[i] === selectedTableName)
- browseView.tableSelectElement.selectedIndex = i;
- }
-
- if (!selectedTableName && length)
- this.currentTable = tableNames[0];
- },
-
- updateTableBrowser: function()
- {
- if (!this.currentTable) {
- this.views.browse.contentElement.removeChildren();
- return;
- }
-
- var panel = this;
- var query = "SELECT * FROM " + this.currentTable;
- this.resource.database.transaction(function(tx)
- {
- tx.executeSql(query, [], function(tx, result) { panel.browseQueryFinished(result) }, function(tx, error) { panel.browseQueryError(error) });
- }, function(tx, error) { panel.browseQueryError(error) });
- },
-
- browseQueryFinished: function(result)
- {
- this.views.browse.contentElement.removeChildren();
-
- var table = this._tableForResult(result);
- if (!table) {
- var emptyMsgElement = document.createElement("div");
- emptyMsgElement.className = "database-table-empty";
- emptyMsgElement.textContent = WebInspector.UIString("The “%s”\ntable is empty.", this.currentTable);
- this.views.browse.contentElement.appendChild(emptyMsgElement);
- return;
- }
-
- var rowCount = table.getElementsByTagName("tr").length;
- var columnCount = table.getElementsByTagName("tr").item(0).getElementsByTagName("th").length;
-
- var tr = document.createElement("tr");
- tr.className = "database-result-filler-row";
- table.appendChild(tr);
-
- if (!(rowCount % 2))
- tr.addStyleClass("alternate");
-
- for (var i = 0; i < columnCount; ++i) {
- var td = document.createElement("td");
- tr.appendChild(td);
- }
-
- table.addStyleClass("database-browse-table");
- this.views.browse.contentElement.appendChild(table);
- },
-
- browseQueryError: function(error)
- {
- this.views.browse.contentElement.removeChildren();
-
- var errorMsgElement = document.createElement("div");
- errorMsgElement.className = "database-table-error";
- errorMsgElement.textContent = WebInspector.UIString("An error occurred trying to\nread the “%s” table.", this.currentTable);
- this.views.browse.contentElement.appendChild(errorMsgElement);
- },
-
- queryInputKeyDown: function(event)
- {
- switch (event.keyIdentifier) {
- case "Enter":
- this._onQueryInputEnterPressed(event);
- break;
- case "Up":
- this._onQueryInputUpPressed(event);
- break;
- case "Down":
- this._onQueryInputDownPressed(event);
- break;
- }
- },
-
- appendQueryResult: function(query, result, resultClassName)
- {
- var commandItem = document.createElement("li");
- commandItem.className = "database-command";
-
- var queryDiv = document.createElement("div");
- queryDiv.className = "database-command-query";
- queryDiv.textContent = query;
- commandItem.appendChild(queryDiv);
-
- var resultDiv = document.createElement("div");
- resultDiv.className = "database-command-result";
- commandItem.appendChild(resultDiv);
-
- if (resultClassName)
- resultDiv.addStyleClass(resultClassName);
-
- if (typeof result === "string" || result instanceof String)
- resultDiv.textContent = result;
- else if (result && result.nodeName)
- resultDiv.appendChild(result);
-
- this.views.query.commandListElement.appendChild(commandItem);
- commandItem.scrollIntoView(false);
- },
-
- queryFinished: function(query, result)
- {
- this.appendQueryResult(query, this._tableForResult(result));
- },
-
- queryError: function(query, error)
- {
- if (this.currentView !== this.views.query)
- this.currentView = this.views.query;
-
- if (error.code == 1)
- var message = error.message;
- else if (error.code == 2)
- var message = WebInspector.UIString("Database no longer has expected version.");
- else
- var message = WebInspector.UIString("An unexpected error %s occured.", error.code);
-
- this.appendQueryResult(query, message, "error");
- },
-
- _onQueryInputEnterPressed: function(event)
- {
- event.preventDefault();
- event.stopPropagation();
-
- var query = this.queryPromptElement.value;
- if (!query.length)
- return;
-
- var panel = this;
- this.resource.database.transaction(function(tx)
- {
- tx.executeSql(query, [], function(tx, result) { panel.queryFinished(query, result) }, function(tx, error) { panel.queryError(query, error) });
- }, function(tx, error) { panel.queryError(query, error) });
-
- this.queryPromptHistory.push(query);
- this.queryPromptHistoryOffset = 0;
-
- this.queryPromptElement.value = "";
-
- if (query.match(/^select /i)) {
- if (this.currentView !== this.views.query)
- this.currentView = this.views.query;
- } else {
- if (query.match(/^create /i) || query.match(/^drop table /i))
- this.updateTableList();
-
- // FIXME: we should only call updateTableBrowser() is we know the current table was modified
- this.updateTableBrowser();
- }
- },
-
- _onQueryInputUpPressed: function(event)
- {
- event.preventDefault();
- event.stopPropagation();
-
- if (this.queryPromptHistoryOffset == this.queryPromptHistory.length)
- return;
-
- if (this.queryPromptHistoryOffset == 0)
- this.tempSavedQuery = this.queryPromptElement.value;
-
- ++this.queryPromptHistoryOffset;
- this.queryPromptElement.value = this.queryPromptHistory[this.queryPromptHistory.length - this.queryPromptHistoryOffset];
- this.queryPromptElement.moveCursorToEnd();
- },
-
- _onQueryInputDownPressed: function(event)
- {
- event.preventDefault();
- event.stopPropagation();
-
- if (this.queryPromptHistoryOffset == 0)
- return;
-
- --this.queryPromptHistoryOffset;
-
- if (this.queryPromptHistoryOffset == 0) {
- this.queryPromptElement.value = this.tempSavedQuery;
- this.queryPromptElement.moveCursorToEnd();
- delete this.tempSavedQuery;
- return;
- }
-
- this.queryPromptElement.value = this.queryPromptHistory[this.queryPromptHistory.length - this.queryPromptHistoryOffset];
- this.queryPromptElement.moveCursorToEnd();
- },
-
- _tableForResult: function(result)
- {
- if (!result.rows.length)
- return null;
-
- var rows = result.rows;
- var length = rows.length;
- var columnWidths = [];
-
- var table = document.createElement("table");
- table.className = "database-result-table";
-
- var headerRow = document.createElement("tr");
- table.appendChild(headerRow);
-
- var j = 0;
- for (var column in rows.item(0)) {
- var th = document.createElement("th");
- headerRow.appendChild(th);
-
- var div = document.createElement("div");
- div.textContent = column;
- div.title = column;
- th.appendChild(div);
-
- columnWidths[j++] = column.length;
- }
-
- for (var i = 0; i < length; ++i) {
- var row = rows.item(i);
- var tr = document.createElement("tr");
- if (i % 2)
- tr.className = "alternate";
- table.appendChild(tr);
-
- var j = 0;
- for (var column in row) {
- var td = document.createElement("td");
- tr.appendChild(td);
-
- var text = row[column];
- var div = document.createElement("div");
- div.textContent = text;
- div.title = text;
- td.appendChild(div);
-
- if (text.length > columnWidths[j])
- columnWidths[j] = text.length;
- ++j;
- }
- }
-
- var totalColumnWidths = 0;
- length = columnWidths.length;
- for (var i = 0; i < length; ++i)
- totalColumnWidths += columnWidths[i];
-
- // Calculate the percentage width for the columns.
- var minimumPrecent = 5;
- var recoupPercent = 0;
- for (var i = 0; i < length; ++i) {
- columnWidths[i] = Math.round((columnWidths[i] / totalColumnWidths) * 100);
- if (columnWidths[i] < minimumPrecent) {
- recoupPercent += (minimumPrecent - columnWidths[i]);
- columnWidths[i] = minimumPrecent;
- }
- }
-
- // Enforce the minimum percentage width.
- while (recoupPercent > 0) {
- for (var i = 0; i < length; ++i) {
- if (columnWidths[i] > minimumPrecent) {
- --columnWidths[i];
- --recoupPercent;
- if (!recoupPercent)
- break;
- }
- }
- }
-
- length = headerRow.childNodes.length;
- for (var i = 0; i < length; ++i) {
- var th = headerRow.childNodes[i];
- th.style.width = columnWidths[i] + "%";
- }
-
- return table;
- }
-}
-})();
-
-WebInspector.DatabasePanel.prototype.__proto__ = WebInspector.ResourcePanel.prototype;
diff --git a/WebCore/page/inspector/DocumentPanel.js b/WebCore/page/inspector/DocumentPanel.js
deleted file mode 100644
index 770f9ba..0000000
--- a/WebCore/page/inspector/DocumentPanel.js
+++ /dev/null
@@ -1,837 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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.
- */
-
-WebInspector.DocumentPanel = function(resource, views)
-{
- var allViews = [{ title: WebInspector.UIString("DOM"), name: "dom" }];
- if (views)
- allViews = allViews.concat(views);
-
- WebInspector.SourcePanel.call(this, resource, allViews);
-
- var panel = this;
- var domView = this.views.dom;
- domView.hide = function() { InspectorController.hideDOMNodeHighlight() };
- domView.show = function() {
- InspectorController.highlightDOMNode(panel.focusedDOMNode);
- panel.updateBreadcrumb();
- panel.updateTreeSelection();
- };
-
- domView.sideContentElement = document.createElement("div");
- domView.sideContentElement.className = "content side";
-
- domView.treeContentElement = document.createElement("div");
- domView.treeContentElement.className = "content tree outline-disclosure";
-
- domView.treeListElement = document.createElement("ol");
- domView.treeOutline = new TreeOutline(domView.treeListElement);
- domView.treeOutline.panel = this;
-
- domView.crumbsElement = document.createElement("div");
- domView.crumbsElement.className = "crumbs";
-
- domView.innerCrumbsElement = document.createElement("div");
- domView.crumbsElement.appendChild(domView.innerCrumbsElement);
-
- domView.sidebarPanes = {};
- domView.sidebarPanes.styles = new WebInspector.StylesSidebarPane();
- domView.sidebarPanes.metrics = new WebInspector.MetricsSidebarPane();
- domView.sidebarPanes.properties = new WebInspector.PropertiesSidebarPane();
-
- domView.sidebarPanes.styles.onexpand = function() { panel.updateStyles() };
- domView.sidebarPanes.metrics.onexpand = function() { panel.updateMetrics() };
- domView.sidebarPanes.properties.onexpand = function() { panel.updateProperties() };
-
- domView.sidebarPanes.styles.expanded = true;
-
- domView.sidebarElement = document.createElement("div");
- domView.sidebarElement.className = "sidebar";
-
- domView.sidebarElement.appendChild(domView.sidebarPanes.styles.element);
- domView.sidebarElement.appendChild(domView.sidebarPanes.metrics.element);
- domView.sidebarElement.appendChild(domView.sidebarPanes.properties.element);
-
- domView.sideContentElement.appendChild(domView.treeContentElement);
- domView.sideContentElement.appendChild(domView.crumbsElement);
- domView.treeContentElement.appendChild(domView.treeListElement);
-
- domView.sidebarResizeElement = document.createElement("div");
- domView.sidebarResizeElement.className = "sidebar-resizer-vertical sidebar-resizer-vertical-right";
- domView.sidebarResizeElement.addEventListener("mousedown", this.rightSidebarResizerDragStart.bind(this), false);
-
- domView.contentElement.appendChild(domView.sideContentElement);
- domView.contentElement.appendChild(domView.sidebarElement);
- domView.contentElement.appendChild(domView.sidebarResizeElement);
-
- this.rootDOMNode = this.resource.documentNode;
-}
-
-WebInspector.DocumentPanel.prototype = {
- resize: function()
- {
- this.updateTreeSelection();
- this.updateBreadcrumbSizes();
- },
-
- updateTreeSelection: function()
- {
- if (!this.views.dom.treeOutline || !this.views.dom.treeOutline.selectedTreeElement)
- return;
- var element = this.views.dom.treeOutline.selectedTreeElement;
- element.updateSelection();
- },
-
- get rootDOMNode()
- {
- return this._rootDOMNode;
- },
-
- set rootDOMNode(x)
- {
- if (this._rootDOMNode === x)
- return;
-
- this._rootDOMNode = x;
-
- this.updateBreadcrumb();
- this.updateTreeOutline();
- },
-
- get focusedDOMNode()
- {
- return this._focusedDOMNode;
- },
-
- set focusedDOMNode(x)
- {
- if (this._focusedDOMNode === x) {
- var nodeItem = this.revealNode(x);
- if (nodeItem)
- nodeItem.select();
- return;
- }
-
- this._focusedDOMNode = x;
-
- this.updateBreadcrumb();
-
- for (var pane in this.views.dom.sidebarPanes)
- this.views.dom.sidebarPanes[pane].needsUpdate = true;
-
- this.updateStyles();
- this.updateMetrics();
- this.updateProperties();
-
- InspectorController.highlightDOMNode(x);
-
- var nodeItem = this.revealNode(x);
- if (nodeItem)
- nodeItem.select();
- },
-
- revealNode: function(node)
- {
- var nodeItem = this.views.dom.treeOutline.findTreeElement(node, function(a, b) { return isAncestorNode.call(a, b); }, function(a) { return a.parentNode; });
- if (!nodeItem)
- return;
-
- nodeItem.reveal();
- return nodeItem;
- },
-
- updateTreeOutline: function()
- {
- this.views.dom.treeOutline.removeChildrenRecursive();
-
- if (!this.rootDOMNode)
- return;
-
- // FIXME: this could use findTreeElement to reuse a tree element if it already exists
- var node = (Preferences.ignoreWhitespace ? firstChildSkippingWhitespace.call(this.rootDOMNode) : this.rootDOMNode.firstChild);
- while (node) {
- this.views.dom.treeOutline.appendChild(new WebInspector.DOMNodeTreeElement(node));
- node = Preferences.ignoreWhitespace ? nextSiblingSkippingWhitespace.call(node) : node.nextSibling;
- }
-
- this.updateTreeSelection();
- },
-
- updateBreadcrumb: function()
- {
- if (!this.visible)
- return;
-
- var crumbs = this.views.dom.innerCrumbsElement;
-
- var handled = false;
- var foundRoot = false;
- var crumb = crumbs.firstChild;
- while (crumb) {
- if (crumb.representedObject === this.rootDOMNode)
- foundRoot = true;
-
- if (foundRoot)
- crumb.addStyleClass("dimmed");
- else
- crumb.removeStyleClass("dimmed");
-
- if (crumb.representedObject === this.focusedDOMNode) {
- crumb.addStyleClass("selected");
- handled = true;
- } else {
- crumb.removeStyleClass("selected");
- }
-
- crumb = crumb.nextSibling;
- }
-
- if (handled) {
- // We don't need to rebuild the crumbs, but we need to adjust sizes
- // to reflect the new focused or root node.
- this.updateBreadcrumbSizes();
- return;
- }
-
- crumbs.removeChildren();
-
- var panel = this;
- var selectCrumbFunction = function(event) {
- var crumb = event.currentTarget;
- if (crumb.hasStyleClass("collapsed")) {
- // Clicking a collapsed crumb will expose the hidden crumbs.
- if (crumb === panel.views.dom.innerCrumbsElement.firstChild) {
- // If the focused crumb is the first child, pick the farthest crumb
- // that is still hidden. This allows the user to expose every crumb.
- var currentCrumb = crumb;
- while (currentCrumb) {
- var hidden = currentCrumb.hasStyleClass("hidden");
- var collapsed = currentCrumb.hasStyleClass("collapsed");
- if (!hidden && !collapsed)
- break;
- crumb = currentCrumb;
- currentCrumb = currentCrumb.nextSibling;
- }
- }
-
- panel.updateBreadcrumbSizes(crumb);
- } else {
- // Clicking a dimmed crumb or double clicking (event.detail >= 2)
- // will change the root node in addition to the focused node.
- if (event.detail >= 2 || crumb.hasStyleClass("dimmed"))
- panel.rootDOMNode = crumb.representedObject.parentNode;
- panel.focusedDOMNode = crumb.representedObject;
- }
-
- event.preventDefault();
- };
-
- var mouseOverCrumbFunction = function(event) {
- panel.mouseOverCrumb = true;
-
- if ("mouseOutTimeout" in panel) {
- clearTimeout(panel.mouseOutTimeout);
- delete panel.mouseOutTimeout;
- }
- };
-
- var mouseOutCrumbFunction = function(event) {
- delete panel.mouseOverCrumb;
-
- if ("mouseOutTimeout" in panel) {
- clearTimeout(panel.mouseOutTimeout);
- delete panel.mouseOutTimeout;
- }
-
- var timeoutFunction = function() {
- if (!panel.mouseOverCrumb)
- panel.updateBreadcrumbSizes();
- };
-
- panel.mouseOutTimeout = setTimeout(timeoutFunction, 500);
- };
-
- foundRoot = false;
- var current = this.focusedDOMNode;
- while (current) {
- if (current.nodeType === Node.DOCUMENT_NODE)
- break;
-
- if (current === this.rootDOMNode)
- foundRoot = true;
-
- var crumb = document.createElement("span");
- crumb.className = "crumb";
- crumb.representedObject = current;
- crumb.addEventListener("mousedown", selectCrumbFunction, false);
- crumb.addEventListener("mouseover", mouseOverCrumbFunction, false);
- crumb.addEventListener("mouseout", mouseOutCrumbFunction, false);
-
- var crumbTitle;
- switch (current.nodeType) {
- case Node.ELEMENT_NODE:
- crumbTitle = current.nodeName.toLowerCase();
-
- var nameElement = document.createElement("span");
- nameElement.textContent = crumbTitle;
- crumb.appendChild(nameElement);
-
- var idAttribute = current.getAttribute("id");
- if (idAttribute) {
- var idElement = document.createElement("span");
- crumb.appendChild(idElement);
-
- var part = "#" + idAttribute;
- crumbTitle += part;
- idElement.appendChild(document.createTextNode(part));
-
- // Mark the name as extra, since the ID is more important.
- nameElement.className = "extra";
- }
-
- var classAttribute = current.getAttribute("class");
- if (classAttribute) {
- var classes = classAttribute.split(/\s+/);
- var foundClasses = {};
-
- if (classes.length) {
- var classesElement = document.createElement("span");
- classesElement.className = "extra";
- crumb.appendChild(classesElement);
-
- for (var i = 0; i < classes.length; ++i) {
- var className = classes[i];
- if (className && !(className in foundClasses)) {
- var part = "." + className;
- crumbTitle += part;
- classesElement.appendChild(document.createTextNode(part));
- foundClasses[className] = true;
- }
- }
- }
- }
-
- break;
-
- case Node.TEXT_NODE:
- if (isNodeWhitespace.call(current))
- crumbTitle = WebInspector.UIString("(whitespace)");
- else
- crumbTitle = WebInspector.UIString("(text)");
- break
-
- case Node.COMMENT_NODE:
- crumbTitle = "<!-->";
- break;
-
- default:
- crumbTitle = current.nodeName.toLowerCase();
- }
-
- if (!crumb.childNodes.length) {
- var nameElement = document.createElement("span");
- nameElement.textContent = crumbTitle;
- crumb.appendChild(nameElement);
- }
-
- crumb.title = crumbTitle;
-
- if (foundRoot)
- crumb.addStyleClass("dimmed");
- if (current === this.focusedDOMNode)
- crumb.addStyleClass("selected");
- if (!crumbs.childNodes.length)
- crumb.addStyleClass("end");
- if (current.parentNode.nodeType === Node.DOCUMENT_NODE)
- crumb.addStyleClass("start");
-
- crumbs.appendChild(crumb);
- current = current.parentNode;
- }
-
- this.updateBreadcrumbSizes();
- },
-
- updateBreadcrumbSizes: function(focusedCrumb)
- {
- if (!this.visible)
- return;
-
- if (document.body.offsetWidth <= 0) {
- // The stylesheet hasn't loaded yet, so we need to update later.
- setTimeout(this.updateBreadcrumbSizes.bind(this), 0);
- return;
- }
-
- var crumbs = this.views.dom.innerCrumbsElement;
- if (!crumbs.childNodes.length)
- return; // No crumbs, do nothing.
-
- var crumbsContainer = this.views.dom.crumbsElement;
- if (crumbsContainer.offsetWidth <= 0 || crumbs.offsetWidth <= 0)
- return;
-
- // A Zero index is the right most child crumb in the breadcrumb.
- var selectedIndex = 0;
- var focusedIndex = 0;
- var selectedCrumb;
-
- var i = 0;
- var crumb = crumbs.firstChild;
- while (crumb) {
- // Find the selected crumb and index.
- if (!selectedCrumb && crumb.hasStyleClass("selected")) {
- selectedCrumb = crumb;
- selectedIndex = i;
- }
-
- // Find the focused crumb index.
- if (crumb === focusedCrumb)
- focusedIndex = i;
-
- // Remove any styles that affect size before
- // deciding to shorten any crumbs.
- if (crumb !== crumbs.lastChild)
- crumb.removeStyleClass("start");
- if (crumb !== crumbs.firstChild)
- crumb.removeStyleClass("end");
-
- crumb.removeStyleClass("compact");
- crumb.removeStyleClass("collapsed");
- crumb.removeStyleClass("hidden");
-
- crumb = crumb.nextSibling;
- ++i;
- }
-
- // Restore the start and end crumb classes in case they got removed in coalesceCollapsedCrumbs().
- // The order of the crumbs in the document is opposite of the visual order.
- crumbs.firstChild.addStyleClass("end");
- crumbs.lastChild.addStyleClass("start");
-
- function crumbsAreSmallerThanContainer()
- {
- // There is some fixed extra space that is not returned in the crumbs' offsetWidth.
- // This padding is added to the crumbs' offsetWidth when comparing to the crumbsContainer.
- var rightPadding = 9;
- return ((crumbs.offsetWidth + rightPadding) < crumbsContainer.offsetWidth);
- }
-
- if (crumbsAreSmallerThanContainer())
- return; // No need to compact the crumbs, they all fit at full size.
-
- var BothSides = 0;
- var AncestorSide = -1;
- var ChildSide = 1;
-
- function makeCrumbsSmaller(shrinkingFunction, direction, significantCrumb)
- {
- if (!significantCrumb)
- significantCrumb = (focusedCrumb || selectedCrumb);
-
- if (significantCrumb === selectedCrumb)
- var significantIndex = selectedIndex;
- else if (significantCrumb === focusedCrumb)
- var significantIndex = focusedIndex;
- else {
- var significantIndex = 0;
- for (var i = 0; i < crumbs.childNodes.length; ++i) {
- if (crumbs.childNodes[i] === significantCrumb) {
- significantIndex = i;
- break;
- }
- }
- }
-
- function shrinkCrumbAtIndex(index)
- {
- var shrinkCrumb = crumbs.childNodes[index];
- if (shrinkCrumb && shrinkCrumb !== significantCrumb)
- shrinkingFunction(shrinkCrumb);
- if (crumbsAreSmallerThanContainer())
- return true; // No need to compact the crumbs more.
- return false;
- }
-
- // Shrink crumbs one at a time by applying the shrinkingFunction until the crumbs
- // fit in the crumbsContainer or we run out of crumbs to shrink.
- if (direction) {
- // Crumbs are shrunk on only one side (based on direction) of the signifcant crumb.
- var index = (direction > 0 ? 0 : crumbs.childNodes.length - 1);
- while (index !== significantIndex) {
- if (shrinkCrumbAtIndex(index))
- return true;
- index += (direction > 0 ? 1 : -1);
- }
- } else {
- // Crumbs are shrunk in order of descending distance from the signifcant crumb,
- // with a tie going to child crumbs.
- var startIndex = 0;
- var endIndex = crumbs.childNodes.length - 1;
- while (startIndex != significantIndex || endIndex != significantIndex) {
- var startDistance = significantIndex - startIndex;
- var endDistance = endIndex - significantIndex;
- if (startDistance >= endDistance)
- var index = startIndex++;
- else
- var index = endIndex--;
- if (shrinkCrumbAtIndex(index))
- return true;
- }
- }
-
- // We are not small enough yet, return false so the caller knows.
- return false;
- }
-
- function coalesceCollapsedCrumbs()
- {
- var crumb = crumbs.firstChild;
- var collapsedRun = false;
- var newStartNeeded = false;
- var newEndNeeded = false;
- while (crumb) {
- var hidden = crumb.hasStyleClass("hidden");
- if (!hidden) {
- var collapsed = crumb.hasStyleClass("collapsed");
- if (collapsedRun && collapsed) {
- crumb.addStyleClass("hidden");
- crumb.removeStyleClass("compact");
- crumb.removeStyleClass("collapsed");
-
- if (crumb.hasStyleClass("start")) {
- crumb.removeStyleClass("start");
- newStartNeeded = true;
- }
-
- if (crumb.hasStyleClass("end")) {
- crumb.removeStyleClass("end");
- newEndNeeded = true;
- }
-
- continue;
- }
-
- collapsedRun = collapsed;
-
- if (newEndNeeded) {
- newEndNeeded = false;
- crumb.addStyleClass("end");
- }
- } else
- collapsedRun = true;
- crumb = crumb.nextSibling;
- }
-
- if (newStartNeeded) {
- crumb = crumbs.lastChild;
- while (crumb) {
- if (!crumb.hasStyleClass("hidden")) {
- crumb.addStyleClass("start");
- break;
- }
- crumb = crumb.previousSibling;
- }
- }
- }
-
- function compact(crumb)
- {
- if (crumb.hasStyleClass("hidden"))
- return;
- crumb.addStyleClass("compact");
- }
-
- function collapse(crumb, dontCoalesce)
- {
- if (crumb.hasStyleClass("hidden"))
- return;
- crumb.addStyleClass("collapsed");
- crumb.removeStyleClass("compact");
- if (!dontCoalesce)
- coalesceCollapsedCrumbs();
- }
-
- function compactDimmed(crumb)
- {
- if (crumb.hasStyleClass("dimmed"))
- compact(crumb);
- }
-
- function collapseDimmed(crumb)
- {
- if (crumb.hasStyleClass("dimmed"))
- collapse(crumb);
- }
-
- if (!focusedCrumb) {
- // When not focused on a crumb we can be biased and collapse less important
- // crumbs that the user might not care much about.
-
- // Compact child crumbs.
- if (makeCrumbsSmaller(compact, ChildSide))
- return;
-
- // Collapse child crumbs.
- if (makeCrumbsSmaller(collapse, ChildSide))
- return;
-
- // Compact dimmed ancestor crumbs.
- if (makeCrumbsSmaller(compactDimmed, AncestorSide))
- return;
-
- // Collapse dimmed ancestor crumbs.
- if (makeCrumbsSmaller(collapseDimmed, AncestorSide))
- return;
- }
-
- // Compact ancestor crumbs, or from both sides if focused.
- if (makeCrumbsSmaller(compact, (focusedCrumb ? BothSides : AncestorSide)))
- return;
-
- // Collapse ancestor crumbs, or from both sides if focused.
- if (makeCrumbsSmaller(collapse, (focusedCrumb ? BothSides : AncestorSide)))
- return;
-
- if (!selectedCrumb)
- return;
-
- // Compact the selected crumb.
- compact(selectedCrumb);
- if (crumbsAreSmallerThanContainer())
- return;
-
- // Collapse the selected crumb as a last resort. Pass true to prevent coalescing.
- collapse(selectedCrumb, true);
- },
-
- updateStyles: function()
- {
- var stylesSidebarPane = this.views.dom.sidebarPanes.styles;
- if (!stylesSidebarPane.expanded || !stylesSidebarPane.needsUpdate)
- return;
-
- stylesSidebarPane.update(this.focusedDOMNode);
- stylesSidebarPane.needsUpdate = false;
- },
-
- updateMetrics: function()
- {
- var metricsSidebarPane = this.views.dom.sidebarPanes.metrics;
- if (!metricsSidebarPane.expanded || !metricsSidebarPane.needsUpdate)
- return;
-
- metricsSidebarPane.update(this.focusedDOMNode);
- metricsSidebarPane.needsUpdate = false;
- },
-
- updateProperties: function()
- {
- var propertiesSidebarPane = this.views.dom.sidebarPanes.properties;
- if (!propertiesSidebarPane.expanded || !propertiesSidebarPane.needsUpdate)
- return;
-
- propertiesSidebarPane.update(this.focusedDOMNode);
- propertiesSidebarPane.needsUpdate = false;
- },
-
- handleKeyEvent: function(event)
- {
- if (this.views.dom.treeOutline && this.currentView && this.currentView === this.views.dom)
- this.views.dom.treeOutline.handleKeyEvent(event);
- },
-
- handleCopyEvent: function(event)
- {
- if (this.currentView !== this.views.dom)
- return;
-
- // Don't prevent the normal copy if the user has a selection.
- if (!window.getSelection().isCollapsed)
- return;
-
- switch (this.focusedDOMNode.nodeType) {
- case Node.ELEMENT_NODE:
- var data = this.focusedDOMNode.outerHTML;
- break;
-
- case Node.COMMENT_NODE:
- var data = "<!--" + this.focusedDOMNode.nodeValue + "-->";
- break;
-
- default:
- case Node.TEXT_NODE:
- var data = this.focusedDOMNode.nodeValue;
- }
-
- event.clipboardData.clearData();
- event.preventDefault();
-
- if (data)
- event.clipboardData.setData("text/plain", data);
- },
-
- rightSidebarResizerDragStart: function(event)
- {
- if (this.sidebarDragEventListener || this.sidebarDragEndEventListener)
- return this.rightSidebarResizerDragEnd(event);
-
- this.sidebarDragEventListener = this.rightSidebarResizerDrag.bind(this);
- this.sidebarDragEndEventListener = this.rightSidebarResizerDragEnd.bind(this);
- WebInspector.elementDragStart(this.views.dom.sidebarElement, this.sidebarDragEventListener, this.sidebarDragEndEventListener, event, "col-resize");
- },
-
- rightSidebarResizerDragEnd: function(event)
- {
- WebInspector.elementDragEnd(this.views.dom.sidebarElement, this.sidebarDragEventListener, this.sidebarDragEndEventListener, event);
- delete this.sidebarDragEventListener;
- delete this.sidebarDragEndEventListener;
- },
-
- rightSidebarResizerDrag: function(event)
- {
- var x = event.pageX;
-
- var leftSidebarWidth = document.getElementById("sidebar").offsetWidth;
- var newWidth = Number.constrain(window.innerWidth - x, 100, window.innerWidth - leftSidebarWidth - 100);
-
- this.views.dom.sidebarElement.style.width = newWidth + "px";
- this.views.dom.sideContentElement.style.right = newWidth + "px";
- this.views.dom.sidebarResizeElement.style.right = (newWidth - 3) + "px";
-
- this.updateTreeSelection();
- this.updateBreadcrumbSizes();
-
- event.preventDefault();
- }
-}
-
-WebInspector.DocumentPanel.prototype.__proto__ = WebInspector.SourcePanel.prototype;
-
-WebInspector.DOMNodeTreeElement = function(node)
-{
- var hasChildren = (Preferences.ignoreWhitespace ? (firstChildSkippingWhitespace.call(node) ? true : false) : node.hasChildNodes());
- var titleInfo = nodeTitleInfo.call(node, hasChildren, WebInspector.linkifyURL);
-
- if (titleInfo.hasChildren)
- this.whitespaceIgnored = Preferences.ignoreWhitespace;
-
- TreeElement.call(this, titleInfo.title, node, titleInfo.hasChildren);
-}
-
-WebInspector.DOMNodeTreeElement.prototype = {
- updateSelection: function()
- {
- var listItemElement = this.listItemElement;
- if (!listItemElement)
- return;
-
- if (document.body.offsetWidth <= 0) {
- // The stylesheet hasn't loaded yet, so we need to update later.
- setTimeout(this.updateSelection.bind(this), 0);
- return;
- }
-
- if (!this.selectionElement) {
- this.selectionElement = document.createElement("div");
- this.selectionElement.className = "selection selected";
- listItemElement.insertBefore(this.selectionElement, listItemElement.firstChild);
- }
-
- this.selectionElement.style.height = listItemElement.offsetHeight + "px";
- },
-
- onattach: function()
- {
- this.listItemElement.addEventListener("mousedown", this.onmousedown.bind(this), false);
- },
-
- onpopulate: function()
- {
- if (this.children.length || this.whitespaceIgnored !== Preferences.ignoreWhitespace)
- return;
-
- this.removeChildren();
- this.whitespaceIgnored = Preferences.ignoreWhitespace;
-
- var node = (Preferences.ignoreWhitespace ? firstChildSkippingWhitespace.call(this.representedObject) : this.representedObject.firstChild);
- while (node) {
- this.appendChild(new WebInspector.DOMNodeTreeElement(node));
- node = Preferences.ignoreWhitespace ? nextSiblingSkippingWhitespace.call(node) : node.nextSibling;
- }
-
- if (this.representedObject.nodeType == Node.ELEMENT_NODE) {
- var title = "<span class=\"webkit-html-tag close\">&lt;/" + this.representedObject.nodeName.toLowerCase().escapeHTML() + "&gt;</span>";
- var item = new TreeElement(title, this.representedObject, false);
- item.selectable = false;
- this.appendChild(item);
- }
- },
-
- onexpand: function()
- {
- this.treeOutline.panel.updateTreeSelection();
- },
-
- oncollapse: function()
- {
- this.treeOutline.panel.updateTreeSelection();
- },
-
- onreveal: function()
- {
- if (!this.listItemElement || !this.treeOutline)
- return;
- this.treeOutline.panel.views.dom.treeContentElement.scrollToElement(this.listItemElement);
- },
-
- onselect: function()
- {
- this.treeOutline.panel.focusedDOMNode = this.representedObject;
- this.updateSelection();
- },
-
- onmousedown: function(event)
- {
- // Prevent selecting the nearest word on double click.
- if (event.detail >= 2)
- event.preventDefault();
- },
-
- ondblclick: function()
- {
- var panel = this.treeOutline.panel;
- panel.rootDOMNode = this.representedObject.parentNode;
- panel.focusedDOMNode = this.representedObject;
-
- if (this.hasChildren && !this.expanded)
- this.expand();
- }
-}
-
-WebInspector.DOMNodeTreeElement.prototype.__proto__ = TreeElement.prototype;
diff --git a/WebCore/page/inspector/FontPanel.js b/WebCore/page/inspector/FontPanel.js
deleted file mode 100644
index c1ffd2f..0000000
--- a/WebCore/page/inspector/FontPanel.js
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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.
- */
-
-WebInspector.FontPanel = function(resource)
-{
- WebInspector.ResourcePanel.call(this, resource);
-
- this.element.addStyleClass("font");
-
- var uniqueFontName = "WebInspectorFontPreview" + this.resource.identifier;
-
- this.fontPreviewElement = document.createElement("div");
- this.fontPreviewElement.className = "preview";
- this.element.appendChild(this.fontPreviewElement);
-
- this.fontPreviewElement.style.setProperty("font-family", uniqueFontName, null);
- this.fontPreviewElement.innerHTML = "ABCDEFGHIJKLM<br>NOPQRSTUVWXYZ<br>abcdefghijklm<br>nopqrstuvwxyz<br>1234567890";
-
- this.updateFontPreviewSize();
-}
-
-WebInspector.FontPanel.prototype = {
- show: function()
- {
- WebInspector.ResourcePanel.prototype.show.call(this);
- this.updateFontPreviewSize();
- },
-
- resize: function()
- {
- this.updateFontPreviewSize();
- },
-
- updateFontPreviewSize: function ()
- {
- if (!this.fontPreviewElement || !this.visible)
- return;
-
- this.fontPreviewElement.removeStyleClass("preview");
-
- var measureFontSize = 50;
- this.fontPreviewElement.style.setProperty("position", "absolute", null);
- this.fontPreviewElement.style.setProperty("font-size", measureFontSize + "px", null);
- this.fontPreviewElement.style.removeProperty("height");
-
- var height = this.fontPreviewElement.offsetHeight;
- var width = this.fontPreviewElement.offsetWidth;
-
- var containerHeight = this.element.offsetHeight;
- var containerWidth = this.element.offsetWidth;
-
- if (!height || !width || !containerHeight || !containerWidth) {
- this.fontPreviewElement.style.removeProperty("font-size");
- this.fontPreviewElement.style.removeProperty("position");
- this.fontPreviewElement.addStyleClass("preview");
- return;
- }
-
- var lineCount = this.fontPreviewElement.getElementsByTagName("br").length + 1;
- var realLineHeight = Math.floor(height / lineCount);
- var fontSizeLineRatio = measureFontSize / realLineHeight;
- var widthRatio = containerWidth / width;
- var heightRatio = containerHeight / height;
-
- if (heightRatio < widthRatio)
- var finalFontSize = Math.floor(realLineHeight * heightRatio * fontSizeLineRatio) - 1;
- else
- var finalFontSize = Math.floor(realLineHeight * widthRatio * fontSizeLineRatio) - 1;
-
- this.fontPreviewElement.style.setProperty("font-size", finalFontSize + "px", null);
- this.fontPreviewElement.style.setProperty("height", this.fontPreviewElement.offsetHeight + "px", null);
- this.fontPreviewElement.style.removeProperty("position");
-
- this.fontPreviewElement.addStyleClass("preview");
- }
-}
-
-WebInspector.FontPanel.prototype.__proto__ = WebInspector.ResourcePanel.prototype;
diff --git a/WebCore/page/inspector/ImagePanel.js b/WebCore/page/inspector/ImagePanel.js
deleted file mode 100644
index 402b754..0000000
--- a/WebCore/page/inspector/ImagePanel.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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.
- */
-
-WebInspector.ImagePanel = function(resource)
-{
- WebInspector.ResourcePanel.call(this, resource);
-
- this.element.addStyleClass("image");
-
- var container = document.createElement("div");
- container.className = "image";
- this.element.appendChild(container);
-
- this.imagePreviewElement = document.createElement("img");
- this.imagePreviewElement.setAttribute("src", this.resource.url);
-
- container.appendChild(this.imagePreviewElement);
-
- container = document.createElement("div");
- container.className = "info";
- this.element.appendChild(container);
-
- var imageNameElement = document.createElement("h1");
- imageNameElement.className = "title";
- imageNameElement.textContent = this.resource.displayName;
- container.appendChild(imageNameElement);
-
- var infoListElement = document.createElement("dl");
- infoListElement.className = "infoList";
-
- var imageProperties = [
- { name: WebInspector.UIString("Dimensions"), value: WebInspector.UIString("%d × %d", this.imagePreviewElement.naturalWidth, this.imagePreviewElement.height) },
- { name: WebInspector.UIString("File size"), value: WebInspector.UIString("%.2fKB", (this.resource.contentLength / 1024)) },
- { name: WebInspector.UIString("MIME type"), value: this.resource.mimeType }
- ];
-
- var listHTML = '';
- for (var i = 0; i < imageProperties.length; ++i)
- listHTML += "<dt>" + imageProperties[i].name + "</dt><dd>" + imageProperties[i].value + "</dd>";
-
- infoListElement.innerHTML = listHTML;
- container.appendChild(infoListElement);
-}
-
-WebInspector.ImagePanel.prototype = {
-
-}
-
-WebInspector.ImagePanel.prototype.__proto__ = WebInspector.ResourcePanel.prototype;
diff --git a/WebCore/page/inspector/Images/alternateTableRows.png b/WebCore/page/inspector/Images/alternateTableRows.png
deleted file mode 100644
index 7706f50..0000000
--- a/WebCore/page/inspector/Images/alternateTableRows.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/attachedShadow.png b/WebCore/page/inspector/Images/attachedShadow.png
deleted file mode 100644
index b0b687c..0000000
--- a/WebCore/page/inspector/Images/attachedShadow.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/backNormal.png b/WebCore/page/inspector/Images/backNormal.png
deleted file mode 100644
index cff21a5..0000000
--- a/WebCore/page/inspector/Images/backNormal.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/bottomShadow.png b/WebCore/page/inspector/Images/bottomShadow.png
deleted file mode 100644
index 61699c4..0000000
--- a/WebCore/page/inspector/Images/bottomShadow.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/breadcrumbBackground.png b/WebCore/page/inspector/Images/breadcrumbBackground.png
deleted file mode 100644
index 516452b..0000000
--- a/WebCore/page/inspector/Images/breadcrumbBackground.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/checker.png b/WebCore/page/inspector/Images/checker.png
deleted file mode 100644
index 8349908..0000000
--- a/WebCore/page/inspector/Images/checker.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/console.png b/WebCore/page/inspector/Images/console.png
deleted file mode 100644
index c85fed0..0000000
--- a/WebCore/page/inspector/Images/console.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/darkShadow.png b/WebCore/page/inspector/Images/darkShadow.png
deleted file mode 100644
index 2761b7d..0000000
--- a/WebCore/page/inspector/Images/darkShadow.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/database.png b/WebCore/page/inspector/Images/database.png
deleted file mode 100644
index 2c13789..0000000
--- a/WebCore/page/inspector/Images/database.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/databaseBrowserViewNormal.png b/WebCore/page/inspector/Images/databaseBrowserViewNormal.png
deleted file mode 100644
index 0d55522..0000000
--- a/WebCore/page/inspector/Images/databaseBrowserViewNormal.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/databaseBrowserViewNormalSelected.png b/WebCore/page/inspector/Images/databaseBrowserViewNormalSelected.png
deleted file mode 100644
index af32982..0000000
--- a/WebCore/page/inspector/Images/databaseBrowserViewNormalSelected.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/databaseBrowserViewSmall.png b/WebCore/page/inspector/Images/databaseBrowserViewSmall.png
deleted file mode 100644
index fa33eec..0000000
--- a/WebCore/page/inspector/Images/databaseBrowserViewSmall.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/databaseBrowserViewSmallSelected.png b/WebCore/page/inspector/Images/databaseBrowserViewSmallSelected.png
deleted file mode 100644
index 6880954..0000000
--- a/WebCore/page/inspector/Images/databaseBrowserViewSmallSelected.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/databaseQueryViewNormal.png b/WebCore/page/inspector/Images/databaseQueryViewNormal.png
deleted file mode 100644
index 326e8c3..0000000
--- a/WebCore/page/inspector/Images/databaseQueryViewNormal.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/databaseQueryViewNormalSelected.png b/WebCore/page/inspector/Images/databaseQueryViewNormalSelected.png
deleted file mode 100644
index 8ffda5c..0000000
--- a/WebCore/page/inspector/Images/databaseQueryViewNormalSelected.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/databaseQueryViewSmall.png b/WebCore/page/inspector/Images/databaseQueryViewSmall.png
deleted file mode 100644
index d11a127..0000000
--- a/WebCore/page/inspector/Images/databaseQueryViewSmall.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/databaseQueryViewSmallSelected.png b/WebCore/page/inspector/Images/databaseQueryViewSmallSelected.png
deleted file mode 100644
index 35be952..0000000
--- a/WebCore/page/inspector/Images/databaseQueryViewSmallSelected.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/disclosureDownPressed.png b/WebCore/page/inspector/Images/disclosureDownPressed.png
deleted file mode 100644
index 32ac517..0000000
--- a/WebCore/page/inspector/Images/disclosureDownPressed.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/disclosureRightDown.png b/WebCore/page/inspector/Images/disclosureRightDown.png
deleted file mode 100644
index 104ea86..0000000
--- a/WebCore/page/inspector/Images/disclosureRightDown.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/disclosureRightPressed.png b/WebCore/page/inspector/Images/disclosureRightPressed.png
deleted file mode 100644
index 41c9b20..0000000
--- a/WebCore/page/inspector/Images/disclosureRightPressed.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/document.png b/WebCore/page/inspector/Images/document.png
deleted file mode 100644
index fa9c3f5..0000000
--- a/WebCore/page/inspector/Images/document.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/domViewNormal.png b/WebCore/page/inspector/Images/domViewNormal.png
deleted file mode 100644
index 6cd4ac4..0000000
--- a/WebCore/page/inspector/Images/domViewNormal.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/domViewNormalSelected.png b/WebCore/page/inspector/Images/domViewNormalSelected.png
deleted file mode 100644
index 5831819..0000000
--- a/WebCore/page/inspector/Images/domViewNormalSelected.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/domViewSmall.png b/WebCore/page/inspector/Images/domViewSmall.png
deleted file mode 100644
index e9fb0da..0000000
--- a/WebCore/page/inspector/Images/domViewSmall.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/domViewSmallSelected.png b/WebCore/page/inspector/Images/domViewSmallSelected.png
deleted file mode 100644
index 517479d..0000000
--- a/WebCore/page/inspector/Images/domViewSmallSelected.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/downTriangle.png b/WebCore/page/inspector/Images/downTriangle.png
deleted file mode 100644
index 18a2a89..0000000
--- a/WebCore/page/inspector/Images/downTriangle.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/errorIcon.png b/WebCore/page/inspector/Images/errorIcon.png
deleted file mode 100644
index d6ec461..0000000
--- a/WebCore/page/inspector/Images/errorIcon.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/errorMediumIcon.png b/WebCore/page/inspector/Images/errorMediumIcon.png
deleted file mode 100644
index 6ca32bb..0000000
--- a/WebCore/page/inspector/Images/errorMediumIcon.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/folder.png b/WebCore/page/inspector/Images/folder.png
deleted file mode 100644
index 9bd7d9e..0000000
--- a/WebCore/page/inspector/Images/folder.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/forwardNormal.png b/WebCore/page/inspector/Images/forwardNormal.png
deleted file mode 100644
index 5cb2c1b..0000000
--- a/WebCore/page/inspector/Images/forwardNormal.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/glossyHeader.png b/WebCore/page/inspector/Images/glossyHeader.png
deleted file mode 100644
index 8c80b6b..0000000
--- a/WebCore/page/inspector/Images/glossyHeader.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/glossyHeaderPressed.png b/WebCore/page/inspector/Images/glossyHeaderPressed.png
deleted file mode 100644
index 6b0dd60..0000000
--- a/WebCore/page/inspector/Images/glossyHeaderPressed.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/goArrow.png b/WebCore/page/inspector/Images/goArrow.png
deleted file mode 100644
index f318a56..0000000
--- a/WebCore/page/inspector/Images/goArrow.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/gradient.png b/WebCore/page/inspector/Images/gradient.png
deleted file mode 100644
index aa8568b..0000000
--- a/WebCore/page/inspector/Images/gradient.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/gradientHighlight.png b/WebCore/page/inspector/Images/gradientHighlight.png
deleted file mode 100644
index 93bc9c1..0000000
--- a/WebCore/page/inspector/Images/gradientHighlight.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/gradientHighlightBottom.png b/WebCore/page/inspector/Images/gradientHighlightBottom.png
deleted file mode 100644
index 89b0b67..0000000
--- a/WebCore/page/inspector/Images/gradientHighlightBottom.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/hideStatusWidget.png b/WebCore/page/inspector/Images/hideStatusWidget.png
deleted file mode 100644
index 52ecece..0000000
--- a/WebCore/page/inspector/Images/hideStatusWidget.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/hideStatusWidgetPressed.png b/WebCore/page/inspector/Images/hideStatusWidgetPressed.png
deleted file mode 100644
index f041662..0000000
--- a/WebCore/page/inspector/Images/hideStatusWidgetPressed.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/network.png b/WebCore/page/inspector/Images/network.png
deleted file mode 100644
index bc215bc..0000000
--- a/WebCore/page/inspector/Images/network.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/paneBottomGrow.png b/WebCore/page/inspector/Images/paneBottomGrow.png
deleted file mode 100644
index d55b865..0000000
--- a/WebCore/page/inspector/Images/paneBottomGrow.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/paneBottomGrowActive.png b/WebCore/page/inspector/Images/paneBottomGrowActive.png
deleted file mode 100644
index ef3f259..0000000
--- a/WebCore/page/inspector/Images/paneBottomGrowActive.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/paneGrowHandleLine.png b/WebCore/page/inspector/Images/paneGrowHandleLine.png
deleted file mode 100644
index 4eaf61b..0000000
--- a/WebCore/page/inspector/Images/paneGrowHandleLine.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/paneHeader.png b/WebCore/page/inspector/Images/paneHeader.png
deleted file mode 100644
index cc66afa..0000000
--- a/WebCore/page/inspector/Images/paneHeader.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/paneHeaderActive.png b/WebCore/page/inspector/Images/paneHeaderActive.png
deleted file mode 100644
index 08205fb..0000000
--- a/WebCore/page/inspector/Images/paneHeaderActive.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/plainDocument.png b/WebCore/page/inspector/Images/plainDocument.png
deleted file mode 100644
index 2e92b71..0000000
--- a/WebCore/page/inspector/Images/plainDocument.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/popupArrows.png b/WebCore/page/inspector/Images/popupArrows.png
deleted file mode 100644
index b980e46..0000000
--- a/WebCore/page/inspector/Images/popupArrows.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/popupArrowsBlack.png b/WebCore/page/inspector/Images/popupArrowsBlack.png
deleted file mode 100644
index 9c9b061..0000000
--- a/WebCore/page/inspector/Images/popupArrowsBlack.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/reload.png b/WebCore/page/inspector/Images/reload.png
deleted file mode 100644
index 9797d26..0000000
--- a/WebCore/page/inspector/Images/reload.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/rightTriangle.png b/WebCore/page/inspector/Images/rightTriangle.png
deleted file mode 100644
index 9f519f2..0000000
--- a/WebCore/page/inspector/Images/rightTriangle.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/segment.png b/WebCore/page/inspector/Images/segment.png
deleted file mode 100644
index bcef26a..0000000
--- a/WebCore/page/inspector/Images/segment.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/segmentEnd.png b/WebCore/page/inspector/Images/segmentEnd.png
deleted file mode 100644
index 374a53d..0000000
--- a/WebCore/page/inspector/Images/segmentEnd.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/segmentHover.png b/WebCore/page/inspector/Images/segmentHover.png
deleted file mode 100644
index f54c029..0000000
--- a/WebCore/page/inspector/Images/segmentHover.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/segmentHoverEnd.png b/WebCore/page/inspector/Images/segmentHoverEnd.png
deleted file mode 100644
index e377c2d..0000000
--- a/WebCore/page/inspector/Images/segmentHoverEnd.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/segmentSelected.png b/WebCore/page/inspector/Images/segmentSelected.png
deleted file mode 100644
index a7f3a8f..0000000
--- a/WebCore/page/inspector/Images/segmentSelected.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/segmentSelectedEnd.png b/WebCore/page/inspector/Images/segmentSelectedEnd.png
deleted file mode 100644
index be2c61b..0000000
--- a/WebCore/page/inspector/Images/segmentSelectedEnd.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/showStatusWidget.png b/WebCore/page/inspector/Images/showStatusWidget.png
deleted file mode 100644
index 051d883..0000000
--- a/WebCore/page/inspector/Images/showStatusWidget.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/showStatusWidgetPressed.png b/WebCore/page/inspector/Images/showStatusWidgetPressed.png
deleted file mode 100644
index 5622c9c..0000000
--- a/WebCore/page/inspector/Images/showStatusWidgetPressed.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/sidbarItemBackground.png b/WebCore/page/inspector/Images/sidbarItemBackground.png
deleted file mode 100644
index 5b94167..0000000
--- a/WebCore/page/inspector/Images/sidbarItemBackground.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/sidebarActionWidget.png b/WebCore/page/inspector/Images/sidebarActionWidget.png
deleted file mode 100644
index daa1aff..0000000
--- a/WebCore/page/inspector/Images/sidebarActionWidget.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/sidebarActionWidgetPressed.png b/WebCore/page/inspector/Images/sidebarActionWidgetPressed.png
deleted file mode 100644
index 794b187..0000000
--- a/WebCore/page/inspector/Images/sidebarActionWidgetPressed.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/sidebarAttachWidget.png b/WebCore/page/inspector/Images/sidebarAttachWidget.png
deleted file mode 100644
index 5f13f36..0000000
--- a/WebCore/page/inspector/Images/sidebarAttachWidget.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/sidebarAttachWidgetPressed.png b/WebCore/page/inspector/Images/sidebarAttachWidgetPressed.png
deleted file mode 100644
index f70dd32..0000000
--- a/WebCore/page/inspector/Images/sidebarAttachWidgetPressed.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/sidebarDetachWidget.png b/WebCore/page/inspector/Images/sidebarDetachWidget.png
deleted file mode 100644
index 2443c21..0000000
--- a/WebCore/page/inspector/Images/sidebarDetachWidget.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/sidebarDetachWidgetPressed.png b/WebCore/page/inspector/Images/sidebarDetachWidgetPressed.png
deleted file mode 100644
index e13f4c1..0000000
--- a/WebCore/page/inspector/Images/sidebarDetachWidgetPressed.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/sidebarResizeWidget.png b/WebCore/page/inspector/Images/sidebarResizeWidget.png
deleted file mode 100644
index 7c1ff70..0000000
--- a/WebCore/page/inspector/Images/sidebarResizeWidget.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/sidebarSelection.png b/WebCore/page/inspector/Images/sidebarSelection.png
deleted file mode 100644
index fccfa0f..0000000
--- a/WebCore/page/inspector/Images/sidebarSelection.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/sidebarSelectionBlurred.png b/WebCore/page/inspector/Images/sidebarSelectionBlurred.png
deleted file mode 100644
index 1e49cdf..0000000
--- a/WebCore/page/inspector/Images/sidebarSelectionBlurred.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/sidebarSelectionBlurredTall.png b/WebCore/page/inspector/Images/sidebarSelectionBlurredTall.png
deleted file mode 100644
index 33a7cfc..0000000
--- a/WebCore/page/inspector/Images/sidebarSelectionBlurredTall.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/sidebarSelectionGray.png b/WebCore/page/inspector/Images/sidebarSelectionGray.png
deleted file mode 100644
index f4faf2c..0000000
--- a/WebCore/page/inspector/Images/sidebarSelectionGray.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/sidebarSelectionGrayTall.png b/WebCore/page/inspector/Images/sidebarSelectionGrayTall.png
deleted file mode 100644
index 01379d2..0000000
--- a/WebCore/page/inspector/Images/sidebarSelectionGrayTall.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/sidebarSelectionTall.png b/WebCore/page/inspector/Images/sidebarSelectionTall.png
deleted file mode 100644
index 0bb56da..0000000
--- a/WebCore/page/inspector/Images/sidebarSelectionTall.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/sidebarStatusAreaBackground.png b/WebCore/page/inspector/Images/sidebarStatusAreaBackground.png
deleted file mode 100644
index 0127d9d..0000000
--- a/WebCore/page/inspector/Images/sidebarStatusAreaBackground.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/sourceViewNormal.png b/WebCore/page/inspector/Images/sourceViewNormal.png
deleted file mode 100644
index 2b23460..0000000
--- a/WebCore/page/inspector/Images/sourceViewNormal.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/sourceViewNormalSelected.png b/WebCore/page/inspector/Images/sourceViewNormalSelected.png
deleted file mode 100644
index 0c24b1c..0000000
--- a/WebCore/page/inspector/Images/sourceViewNormalSelected.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/sourceViewSmall.png b/WebCore/page/inspector/Images/sourceViewSmall.png
deleted file mode 100644
index 82d06ef..0000000
--- a/WebCore/page/inspector/Images/sourceViewSmall.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/sourceViewSmallSelected.png b/WebCore/page/inspector/Images/sourceViewSmallSelected.png
deleted file mode 100644
index fe0351e..0000000
--- a/WebCore/page/inspector/Images/sourceViewSmallSelected.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/splitviewDimple.png b/WebCore/page/inspector/Images/splitviewDimple.png
deleted file mode 100644
index 584ffd4..0000000
--- a/WebCore/page/inspector/Images/splitviewDimple.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/splitviewDividerBackground.png b/WebCore/page/inspector/Images/splitviewDividerBackground.png
deleted file mode 100644
index 1120a7f..0000000
--- a/WebCore/page/inspector/Images/splitviewDividerBackground.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/tab.png b/WebCore/page/inspector/Images/tab.png
deleted file mode 100644
index 2f5000a..0000000
--- a/WebCore/page/inspector/Images/tab.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/tabSelected.png b/WebCore/page/inspector/Images/tabSelected.png
deleted file mode 100644
index 76c2f66..0000000
--- a/WebCore/page/inspector/Images/tabSelected.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/timelinePillBlue.png b/WebCore/page/inspector/Images/timelinePillBlue.png
deleted file mode 100644
index c897faa..0000000
--- a/WebCore/page/inspector/Images/timelinePillBlue.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/timelinePillGray.png b/WebCore/page/inspector/Images/timelinePillGray.png
deleted file mode 100644
index 2128896..0000000
--- a/WebCore/page/inspector/Images/timelinePillGray.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/timelinePillGreen.png b/WebCore/page/inspector/Images/timelinePillGreen.png
deleted file mode 100644
index 9b66125..0000000
--- a/WebCore/page/inspector/Images/timelinePillGreen.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/timelinePillOrange.png b/WebCore/page/inspector/Images/timelinePillOrange.png
deleted file mode 100644
index dd944fb..0000000
--- a/WebCore/page/inspector/Images/timelinePillOrange.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/timelinePillPurple.png b/WebCore/page/inspector/Images/timelinePillPurple.png
deleted file mode 100644
index 21b96f7..0000000
--- a/WebCore/page/inspector/Images/timelinePillPurple.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/timelinePillRed.png b/WebCore/page/inspector/Images/timelinePillRed.png
deleted file mode 100644
index f5e213b..0000000
--- a/WebCore/page/inspector/Images/timelinePillRed.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/timelinePillYellow.png b/WebCore/page/inspector/Images/timelinePillYellow.png
deleted file mode 100644
index ae2a5a2..0000000
--- a/WebCore/page/inspector/Images/timelinePillYellow.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/tipBalloon.png b/WebCore/page/inspector/Images/tipBalloon.png
deleted file mode 100644
index 4cdf738..0000000
--- a/WebCore/page/inspector/Images/tipBalloon.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/tipBalloonBottom.png b/WebCore/page/inspector/Images/tipBalloonBottom.png
deleted file mode 100644
index 3317a5a..0000000
--- a/WebCore/page/inspector/Images/tipBalloonBottom.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/tipIcon.png b/WebCore/page/inspector/Images/tipIcon.png
deleted file mode 100644
index 8ca6124..0000000
--- a/WebCore/page/inspector/Images/tipIcon.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/tipIconPressed.png b/WebCore/page/inspector/Images/tipIconPressed.png
deleted file mode 100644
index 443e410..0000000
--- a/WebCore/page/inspector/Images/tipIconPressed.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/toggleDown.png b/WebCore/page/inspector/Images/toggleDown.png
deleted file mode 100644
index 9e73bfb..0000000
--- a/WebCore/page/inspector/Images/toggleDown.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/toggleUp.png b/WebCore/page/inspector/Images/toggleUp.png
deleted file mode 100644
index 6b62aee..0000000
--- a/WebCore/page/inspector/Images/toggleUp.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/toolbarBackground.png b/WebCore/page/inspector/Images/toolbarBackground.png
deleted file mode 100644
index 257d63d..0000000
--- a/WebCore/page/inspector/Images/toolbarBackground.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/toolbarBackgroundInactive.png b/WebCore/page/inspector/Images/toolbarBackgroundInactive.png
deleted file mode 100644
index a62b8df..0000000
--- a/WebCore/page/inspector/Images/toolbarBackgroundInactive.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/toolbarButtonNormal.png b/WebCore/page/inspector/Images/toolbarButtonNormal.png
deleted file mode 100644
index bd16c12..0000000
--- a/WebCore/page/inspector/Images/toolbarButtonNormal.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/toolbarButtonNormalInactive.png b/WebCore/page/inspector/Images/toolbarButtonNormalInactive.png
deleted file mode 100644
index 3c9d5bc..0000000
--- a/WebCore/page/inspector/Images/toolbarButtonNormalInactive.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/toolbarButtonNormalPressed.png b/WebCore/page/inspector/Images/toolbarButtonNormalPressed.png
deleted file mode 100644
index aca9b02..0000000
--- a/WebCore/page/inspector/Images/toolbarButtonNormalPressed.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/toolbarButtonNormalSelected.png b/WebCore/page/inspector/Images/toolbarButtonNormalSelected.png
deleted file mode 100644
index 41013b3..0000000
--- a/WebCore/page/inspector/Images/toolbarButtonNormalSelected.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/toolbarButtonNormalSelectedInactive.png b/WebCore/page/inspector/Images/toolbarButtonNormalSelectedInactive.png
deleted file mode 100644
index f6fdb08..0000000
--- a/WebCore/page/inspector/Images/toolbarButtonNormalSelectedInactive.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/toolbarButtonSmall.png b/WebCore/page/inspector/Images/toolbarButtonSmall.png
deleted file mode 100644
index 04398fd..0000000
--- a/WebCore/page/inspector/Images/toolbarButtonSmall.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/toolbarButtonSmallInactive.png b/WebCore/page/inspector/Images/toolbarButtonSmallInactive.png
deleted file mode 100644
index a6928be..0000000
--- a/WebCore/page/inspector/Images/toolbarButtonSmallInactive.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/toolbarButtonSmallPressed.png b/WebCore/page/inspector/Images/toolbarButtonSmallPressed.png
deleted file mode 100644
index 0d83a38..0000000
--- a/WebCore/page/inspector/Images/toolbarButtonSmallPressed.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/toolbarButtonSmallSelected.png b/WebCore/page/inspector/Images/toolbarButtonSmallSelected.png
deleted file mode 100644
index d5433cb..0000000
--- a/WebCore/page/inspector/Images/toolbarButtonSmallSelected.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/toolbarButtonSmallSelectedInactive.png b/WebCore/page/inspector/Images/toolbarButtonSmallSelectedInactive.png
deleted file mode 100644
index 41a3249..0000000
--- a/WebCore/page/inspector/Images/toolbarButtonSmallSelectedInactive.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/toolbarPopupButtonNormal.png b/WebCore/page/inspector/Images/toolbarPopupButtonNormal.png
deleted file mode 100644
index 438b5ea..0000000
--- a/WebCore/page/inspector/Images/toolbarPopupButtonNormal.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/toolbarPopupButtonNormalInactive.png b/WebCore/page/inspector/Images/toolbarPopupButtonNormalInactive.png
deleted file mode 100644
index 0e8f6a2..0000000
--- a/WebCore/page/inspector/Images/toolbarPopupButtonNormalInactive.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/toolbarPopupButtonNormalPressed.png b/WebCore/page/inspector/Images/toolbarPopupButtonNormalPressed.png
deleted file mode 100644
index 23bcafd..0000000
--- a/WebCore/page/inspector/Images/toolbarPopupButtonNormalPressed.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/toolbarPopupButtonSmall.png b/WebCore/page/inspector/Images/toolbarPopupButtonSmall.png
deleted file mode 100644
index efa68a3..0000000
--- a/WebCore/page/inspector/Images/toolbarPopupButtonSmall.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/toolbarPopupButtonSmallInactive.png b/WebCore/page/inspector/Images/toolbarPopupButtonSmallInactive.png
deleted file mode 100644
index 55e3c0c..0000000
--- a/WebCore/page/inspector/Images/toolbarPopupButtonSmallInactive.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/toolbarPopupButtonSmallPressed.png b/WebCore/page/inspector/Images/toolbarPopupButtonSmallPressed.png
deleted file mode 100644
index 56e574c..0000000
--- a/WebCore/page/inspector/Images/toolbarPopupButtonSmallPressed.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/toolbarSplitButtonDividerNormal.png b/WebCore/page/inspector/Images/toolbarSplitButtonDividerNormal.png
deleted file mode 100644
index bf6de38..0000000
--- a/WebCore/page/inspector/Images/toolbarSplitButtonDividerNormal.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/toolbarSplitButtonDividerNormalInactive.png b/WebCore/page/inspector/Images/toolbarSplitButtonDividerNormalInactive.png
deleted file mode 100644
index c61541c..0000000
--- a/WebCore/page/inspector/Images/toolbarSplitButtonDividerNormalInactive.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/toolbarSplitButtonDividerSmall.png b/WebCore/page/inspector/Images/toolbarSplitButtonDividerSmall.png
deleted file mode 100644
index 9f248f6..0000000
--- a/WebCore/page/inspector/Images/toolbarSplitButtonDividerSmall.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/toolbarSplitButtonDividerSmallInactive.png b/WebCore/page/inspector/Images/toolbarSplitButtonDividerSmallInactive.png
deleted file mode 100644
index 7365c34..0000000
--- a/WebCore/page/inspector/Images/toolbarSplitButtonDividerSmallInactive.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/treeDownTriangleBlack.png b/WebCore/page/inspector/Images/treeDownTriangleBlack.png
deleted file mode 100644
index 0821112..0000000
--- a/WebCore/page/inspector/Images/treeDownTriangleBlack.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/treeDownTriangleWhite.png b/WebCore/page/inspector/Images/treeDownTriangleWhite.png
deleted file mode 100644
index 1667b51..0000000
--- a/WebCore/page/inspector/Images/treeDownTriangleWhite.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/treeLeftTriangleBlack.png b/WebCore/page/inspector/Images/treeLeftTriangleBlack.png
deleted file mode 100644
index 81bc7e0..0000000
--- a/WebCore/page/inspector/Images/treeLeftTriangleBlack.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/treeRightTriangleBlack.png b/WebCore/page/inspector/Images/treeRightTriangleBlack.png
deleted file mode 100644
index 90de820..0000000
--- a/WebCore/page/inspector/Images/treeRightTriangleBlack.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/treeRightTriangleWhite.png b/WebCore/page/inspector/Images/treeRightTriangleWhite.png
deleted file mode 100644
index 2b6a82f..0000000
--- a/WebCore/page/inspector/Images/treeRightTriangleWhite.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/warningIcon.png b/WebCore/page/inspector/Images/warningIcon.png
deleted file mode 100644
index f37727e..0000000
--- a/WebCore/page/inspector/Images/warningIcon.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/warningMediumIcon.png b/WebCore/page/inspector/Images/warningMediumIcon.png
deleted file mode 100644
index 291e111..0000000
--- a/WebCore/page/inspector/Images/warningMediumIcon.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/Images/warningsErrors.png b/WebCore/page/inspector/Images/warningsErrors.png
deleted file mode 100644
index 878b593..0000000
--- a/WebCore/page/inspector/Images/warningsErrors.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/page/inspector/MetricsSidebarPane.js b/WebCore/page/inspector/MetricsSidebarPane.js
deleted file mode 100644
index e805560..0000000
--- a/WebCore/page/inspector/MetricsSidebarPane.js
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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.
- */
-
-WebInspector.MetricsSidebarPane = function()
-{
- WebInspector.SidebarPane.call(this, WebInspector.UIString("Metrics"));
-}
-
-WebInspector.MetricsSidebarPane.prototype = {
- update: function(node)
- {
- var body = this.bodyElement;
-
- body.removeChildren();
-
- if (!node)
- return;
-
- var style;
- if (node.nodeType === Node.ELEMENT_NODE)
- style = node.ownerDocument.defaultView.getComputedStyle(node);
- if (!style)
- return;
-
- var metricsElement = document.createElement("div");
- metricsElement.className = "metrics";
-
- function boxPartValue(style, name, suffix)
- {
- var value = style.getPropertyValue(name + suffix);
- if (value === "" || value === "0px")
- value = "\u2012";
- return value.replace(/px$/, "");
- }
-
- // Display types for which margin is ignored.
- var noMarginDisplayType = {
- "table-cell": true,
- "table-column": true,
- "table-column-group": true,
- "table-footer-group": true,
- "table-header-group": true,
- "table-row": true,
- "table-row-group": true
- };
-
- // Display types for which padding is ignored.
- var noPaddingDisplayType = {
- "table-column": true,
- "table-column-group": true,
- "table-footer-group": true,
- "table-header-group": true,
- "table-row": true,
- "table-row-group": true
- };
-
- var boxes = ["content", "padding", "border", "margin"];
- var boxLabels = [WebInspector.UIString("content"), WebInspector.UIString("padding"), WebInspector.UIString("border"), WebInspector.UIString("margin")];
- var previousBox;
- for (var i = 0; i < boxes.length; ++i) {
- var name = boxes[i];
-
- if (name === "margin" && noMarginDisplayType[style.display])
- continue;
- if (name === "padding" && noPaddingDisplayType[style.display])
- continue;
-
- var boxElement = document.createElement("div");
- boxElement.className = name;
-
- if (name === "content") {
- var width = style.width.replace(/px$/, "");
- var height = style.height.replace(/px$/, "");
- boxElement.textContent = width + " \u00D7 " + height;
- } else {
- var suffix = (name === "border" ? "-width" : "");
-
- var labelElement = document.createElement("div");
- labelElement.className = "label";
- labelElement.textContent = boxLabels[i];
- boxElement.appendChild(labelElement);
-
- var topElement = document.createElement("div");
- topElement.className = "top";
- topElement.textContent = boxPartValue(style, name + "-top", suffix);
- boxElement.appendChild(topElement);
-
- var leftElement = document.createElement("div");
- leftElement.className = "left";
- leftElement.textContent = boxPartValue(style, name + "-left", suffix);
- boxElement.appendChild(leftElement);
-
- if (previousBox)
- boxElement.appendChild(previousBox);
-
- var rightElement = document.createElement("div");
- rightElement.className = "right";
- rightElement.textContent = boxPartValue(style, name + "-right", suffix);
- boxElement.appendChild(rightElement);
-
- var bottomElement = document.createElement("div");
- bottomElement.className = "bottom";
- bottomElement.textContent = boxPartValue(style, name + "-bottom", suffix);
- boxElement.appendChild(bottomElement);
- }
-
- previousBox = boxElement;
- }
-
- metricsElement.appendChild(previousBox);
- body.appendChild(metricsElement);
- }
-}
-
-WebInspector.MetricsSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;
diff --git a/WebCore/page/inspector/NetworkPanel.js b/WebCore/page/inspector/NetworkPanel.js
deleted file mode 100644
index 2f000ee..0000000
--- a/WebCore/page/inspector/NetworkPanel.js
+++ /dev/null
@@ -1,1036 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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.
- */
-
-WebInspector.NetworkPanel = function()
-{
- WebInspector.Panel.call(this);
-
- this.timelineEntries = [];
-
- this.timelineElement = document.createElement("div");
- this.timelineElement.className = "network-timeline";
- this.element.appendChild(this.timelineElement);
-
- this.summaryElement = document.createElement("div");
- this.summaryElement.className = "network-summary";
- this.element.appendChild(this.summaryElement);
-
- this.dividersElement = document.createElement("div");
- this.dividersElement.className = "network-dividers";
- this.timelineElement.appendChild(this.dividersElement);
-
- this.resourcesElement = document.createElement("div");
- this.resourcesElement.className = "network-resources";
- this.resourcesElement.addEventListener("click", this.resourcesClicked.bind(this), false);
- this.timelineElement.appendChild(this.resourcesElement);
-
- var graphArea = document.createElement("div");
- graphArea.className = "network-graph-area";
- this.summaryElement.appendChild(graphArea);
-
- this.graphLabelElement = document.createElement("div");
- this.graphLabelElement.className = "network-graph-label";
- graphArea.appendChild(this.graphLabelElement);
-
- this.graphModeSelectElement = document.createElement("select");
- this.graphModeSelectElement.className = "network-graph-mode";
- this.graphModeSelectElement.addEventListener("change", this.changeGraphMode.bind(this), false);
- this.graphLabelElement.appendChild(this.graphModeSelectElement);
- this.graphLabelElement.appendChild(document.createElement("br"));
-
- var sizeOptionElement = document.createElement("option");
- sizeOptionElement.calculator = new WebInspector.TransferSizeCalculator();
- sizeOptionElement.textContent = sizeOptionElement.calculator.title;
- this.graphModeSelectElement.appendChild(sizeOptionElement);
-
- var timeOptionElement = document.createElement("option");
- timeOptionElement.calculator = new WebInspector.TransferTimeCalculator();
- timeOptionElement.textContent = timeOptionElement.calculator.title;
- this.graphModeSelectElement.appendChild(timeOptionElement);
-
- var graphSideElement = document.createElement("div");
- graphSideElement.className = "network-graph-side";
- graphArea.appendChild(graphSideElement);
-
- this.summaryGraphElement = document.createElement("canvas");
- this.summaryGraphElement.setAttribute("width", "450");
- this.summaryGraphElement.setAttribute("height", "38");
- this.summaryGraphElement.className = "network-summary-graph";
- graphSideElement.appendChild(this.summaryGraphElement);
-
- this.legendElement = document.createElement("div");
- this.legendElement.className = "network-graph-legend";
- graphSideElement.appendChild(this.legendElement);
-
- this.drawSummaryGraph(); // draws an empty graph
-
- this.needsRefresh = true;
-}
-
-WebInspector.NetworkPanel.prototype = {
- show: function()
- {
- WebInspector.Panel.prototype.show.call(this);
- WebInspector.networkListItem.select();
- this.refreshIfNeeded();
- },
-
- hide: function()
- {
- WebInspector.Panel.prototype.hide.call(this);
- WebInspector.networkListItem.deselect();
- },
-
- resize: function()
- {
- this.updateTimelineDividersIfNeeded();
- },
-
- resourcesClicked: function(event)
- {
- // If the click wasn't inside a network resource row, ignore it.
- var resourceElement = event.target.firstParentOrSelfWithClass("network-resource");
- if (!resourceElement)
- return;
-
- // If the click was within the network info element, ignore it.
- var networkInfo = event.target.firstParentOrSelfWithClass("network-info");
- if (networkInfo)
- return;
-
- // If the click was within the tip balloon element, hide it.
- var balloon = event.target.firstParentOrSelfWithClass("tip-balloon");
- if (balloon) {
- resourceElement.timelineEntry.showingTipBalloon = false;
- return;
- }
-
- resourceElement.timelineEntry.toggleShowingInfo();
- },
-
- changeGraphMode: function(event)
- {
- this.updateSummaryGraph();
- },
-
- get calculator()
- {
- return this.graphModeSelectElement.options[this.graphModeSelectElement.selectedIndex].calculator;
- },
-
- get totalDuration()
- {
- return this.latestEndTime - this.earliestStartTime;
- },
-
- get needsRefresh()
- {
- return this._needsRefresh;
- },
-
- set needsRefresh(x)
- {
- if (this._needsRefresh === x)
- return;
- this._needsRefresh = x;
- if (x && this.visible)
- this.refresh();
- },
-
- refreshIfNeeded: function()
- {
- if (this.needsRefresh)
- this.refresh();
- },
-
- refresh: function()
- {
- this.needsRefresh = false;
-
- // calling refresh will call updateTimelineBoundriesIfNeeded, which can clear needsRefresh for future entries,
- // so find all the entries that needs refresh first, then loop back trough them to call refresh
- var entriesNeedingRefresh = [];
- var entriesLength = this.timelineEntries.length;
- for (var i = 0; i < entriesLength; ++i) {
- var entry = this.timelineEntries[i];
- if (entry.needsRefresh || entry.infoNeedsRefresh)
- entriesNeedingRefresh.push(entry);
- }
-
- entriesLength = entriesNeedingRefresh.length;
- for (var i = 0; i < entriesLength; ++i)
- entriesNeedingRefresh[i].refresh(false, true, true);
-
- this.updateTimelineDividersIfNeeded();
- this.sortTimelineEntriesIfNeeded();
- this.updateSummaryGraph();
- },
-
- makeLegendElement: function(label, value, color)
- {
- var legendElement = document.createElement("label");
- legendElement.className = "network-graph-legend-item";
-
- if (color) {
- var swatch = document.createElement("canvas");
- swatch.className = "network-graph-legend-swatch";
- swatch.setAttribute("width", "13");
- swatch.setAttribute("height", "24");
-
- legendElement.appendChild(swatch);
-
- this.drawSwatch(swatch, color);
- }
-
- var labelElement = document.createElement("div");
- labelElement.className = "network-graph-legend-label";
- legendElement.appendChild(labelElement);
-
- var headerElement = document.createElement("div");
- var headerElement = document.createElement("div");
- headerElement.className = "network-graph-legend-header";
- headerElement.textContent = label;
- labelElement.appendChild(headerElement);
-
- var valueElement = document.createElement("div");
- valueElement.className = "network-graph-legend-value";
- valueElement.textContent = value;
- labelElement.appendChild(valueElement);
-
- return legendElement;
- },
-
- sortTimelineEntriesSoonIfNeeded: function()
- {
- if ("sortTimelineEntriesTimeout" in this)
- return;
- this.sortTimelineEntriesTimeout = setTimeout(this.sortTimelineEntriesIfNeeded.bind(this), 500);
- },
-
- sortTimelineEntriesIfNeeded: function()
- {
- if ("sortTimelineEntriesTimeout" in this) {
- clearTimeout(this.sortTimelineEntriesTimeout);
- delete this.sortTimelineEntriesTimeout;
- }
-
- this.timelineEntries.sort(WebInspector.NetworkPanel.timelineEntryCompare);
-
- var nextSibling = null;
- for (var i = (this.timelineEntries.length - 1); i >= 0; --i) {
- var entry = this.timelineEntries[i];
- if (entry.resourceElement.nextSibling !== nextSibling)
- this.resourcesElement.insertBefore(entry.resourceElement, nextSibling);
- nextSibling = entry.resourceElement;
- }
- },
-
- updateTimelineBoundriesIfNeeded: function(resource, immediate)
- {
- var didUpdate = false;
- if (resource.startTime !== -1 && (this.earliestStartTime === undefined || resource.startTime < this.earliestStartTime)) {
- this.earliestStartTime = resource.startTime;
- didUpdate = true;
- }
-
- if (resource.endTime !== -1 && (this.latestEndTime === undefined || resource.endTime > this.latestEndTime)) {
- this.latestEndTime = resource.endTime;
- didUpdate = true;
- }
-
- if (didUpdate) {
- if (immediate) {
- this.refreshAllTimelineEntries(true, true, immediate);
- this.updateTimelineDividersIfNeeded();
- } else {
- this.refreshAllTimelineEntriesSoon(true, true, immediate);
- this.updateTimelineDividersSoonIfNeeded();
- }
- }
-
- return didUpdate;
- },
-
- updateTimelineDividersSoonIfNeeded: function()
- {
- if ("updateTimelineDividersTimeout" in this)
- return;
- this.updateTimelineDividersTimeout = setTimeout(this.updateTimelineDividersIfNeeded.bind(this), 500);
- },
-
- updateTimelineDividersIfNeeded: function()
- {
- if ("updateTimelineDividersTimeout" in this) {
- clearTimeout(this.updateTimelineDividersTimeout);
- delete this.updateTimelineDividersTimeout;
- }
-
- if (!this.visible) {
- this.needsRefresh = true;
- return;
- }
-
- if (document.body.offsetWidth <= 0) {
- // The stylesheet hasn't loaded yet, so we need to update later.
- setTimeout(this.updateTimelineDividersIfNeeded.bind(this), 0);
- return;
- }
-
- var dividerCount = Math.round(this.dividersElement.offsetWidth / 64);
- var timeSlice = this.totalDuration / dividerCount;
-
- if (this.lastDividerTimeSlice === timeSlice)
- return;
-
- this.lastDividerTimeSlice = timeSlice;
-
- this.dividersElement.removeChildren();
-
- for (var i = 1; i <= dividerCount; ++i) {
- var divider = document.createElement("div");
- divider.className = "network-divider";
- if (i === dividerCount)
- divider.addStyleClass("last");
- divider.style.left = ((i / dividerCount) * 100) + "%";
-
- var label = document.createElement("div");
- label.className = "network-divider-label";
- label.textContent = Number.secondsToString(timeSlice * i);
- divider.appendChild(label);
-
- this.dividersElement.appendChild(divider);
- }
- },
-
- refreshAllTimelineEntriesSoon: function(skipBoundryUpdate, skipTimelineSort, immediate)
- {
- if ("refreshAllTimelineEntriesTimeout" in this)
- return;
- this.refreshAllTimelineEntriesTimeout = setTimeout(this.refreshAllTimelineEntries.bind(this), 500, skipBoundryUpdate, skipTimelineSort, immediate);
- },
-
- refreshAllTimelineEntries: function(skipBoundryUpdate, skipTimelineSort, immediate)
- {
- if ("refreshAllTimelineEntriesTimeout" in this) {
- clearTimeout(this.refreshAllTimelineEntriesTimeout);
- delete this.refreshAllTimelineEntriesTimeout;
- }
-
- var entriesLength = this.timelineEntries.length;
- for (var i = 0; i < entriesLength; ++i)
- this.timelineEntries[i].refresh(skipBoundryUpdate, skipTimelineSort, immediate);
- },
-
- fadeOutRect: function(ctx, x, y, w, h, a1, a2)
- {
- ctx.save();
-
- var gradient = ctx.createLinearGradient(x, y, x, y + h);
- gradient.addColorStop(0.0, "rgba(0, 0, 0, " + (1.0 - a1) + ")");
- gradient.addColorStop(0.8, "rgba(0, 0, 0, " + (1.0 - a2) + ")");
- gradient.addColorStop(1.0, "rgba(0, 0, 0, 1.0)");
-
- ctx.globalCompositeOperation = "destination-out";
-
- ctx.fillStyle = gradient;
- ctx.fillRect(x, y, w, h);
-
- ctx.restore();
- },
-
- drawSwatch: function(canvas, color)
- {
- var ctx = canvas.getContext("2d");
-
- function drawSwatchSquare() {
- ctx.fillStyle = color;
- ctx.fillRect(0, 0, 13, 13);
-
- var gradient = ctx.createLinearGradient(0, 0, 13, 13);
- gradient.addColorStop(0.0, "rgba(255, 255, 255, 0.2)");
- gradient.addColorStop(1.0, "rgba(255, 255, 255, 0.0)");
-
- ctx.fillStyle = gradient;
- ctx.fillRect(0, 0, 13, 13);
-
- gradient = ctx.createLinearGradient(13, 13, 0, 0);
- gradient.addColorStop(0.0, "rgba(0, 0, 0, 0.2)");
- gradient.addColorStop(1.0, "rgba(0, 0, 0, 0.0)");
-
- ctx.fillStyle = gradient;
- ctx.fillRect(0, 0, 13, 13);
-
- ctx.strokeStyle = "rgba(0, 0, 0, 0.6)";
- ctx.strokeRect(0.5, 0.5, 12, 12);
- }
-
- ctx.clearRect(0, 0, 13, 24);
-
- drawSwatchSquare();
-
- ctx.save();
-
- ctx.translate(0, 25);
- ctx.scale(1, -1);
-
- drawSwatchSquare();
-
- ctx.restore();
-
- this.fadeOutRect(ctx, 0, 13, 13, 13, 0.5, 0.0);
- },
-
- drawSummaryGraph: function(segments)
- {
- if (!this.summaryGraphElement)
- return;
-
- if (!segments || !segments.length)
- segments = [{color: "white", value: 1}];
-
- // Calculate the total of all segments.
- var total = 0;
- for (var i = 0; i < segments.length; ++i)
- total += segments[i].value;
-
- // Calculate the percentage of each segment, rounded to the nearest percent.
- var percents = segments.map(function(s) { return Math.max(Math.round(100 * s.value / total), 1) });
-
- // Calculate the total percentage.
- var percentTotal = 0;
- for (var i = 0; i < percents.length; ++i)
- percentTotal += percents[i];
-
- // Make sure our percentage total is not greater-than 100, it can be greater
- // if we rounded up for a few segments.
- while (percentTotal > 100) {
- for (var i = 0; i < percents.length && percentTotal > 100; ++i) {
- if (percents[i] > 1) {
- --percents[i];
- --percentTotal;
- }
- }
- }
-
- // Make sure our percentage total is not less-than 100, it can be less
- // if we rounded down for a few segments.
- while (percentTotal < 100) {
- for (var i = 0; i < percents.length && percentTotal < 100; ++i) {
- ++percents[i];
- ++percentTotal;
- }
- }
-
- var ctx = this.summaryGraphElement.getContext("2d");
-
- var x = 0;
- var y = 0;
- var w = 450;
- var h = 19;
- var r = (h / 2);
-
- function drawPillShadow()
- {
- // This draws a line with a shadow that is offset away from the line. The line is stroked
- // twice with different X shadow offsets to give more feathered edges. Later we erase the
- // line with destination-out 100% transparent black, leaving only the shadow. This only
- // works if nothing has been drawn into the canvas yet.
-
- ctx.beginPath();
- ctx.moveTo(x + 4, y + h - 3 - 0.5);
- ctx.lineTo(x + w - 4, y + h - 3 - 0.5);
- ctx.closePath();
-
- ctx.save();
-
- ctx.shadowBlur = 2;
- ctx.shadowColor = "rgba(0, 0, 0, 0.5)";
- ctx.shadowOffsetX = 3;
- ctx.shadowOffsetY = 5;
-
- ctx.strokeStyle = "white";
- ctx.lineWidth = 1;
-
- ctx.stroke();
-
- ctx.shadowOffsetX = -3;
-
- ctx.stroke();
-
- ctx.restore();
-
- ctx.save();
-
- ctx.globalCompositeOperation = "destination-out";
- ctx.strokeStyle = "rgba(0, 0, 0, 1)";
- ctx.lineWidth = 1;
-
- ctx.stroke();
-
- ctx.restore();
- }
-
- function drawPill()
- {
- // Make a rounded rect path.
- ctx.beginPath();
- ctx.moveTo(x, y + r);
- ctx.lineTo(x, y + h - r);
- ctx.quadraticCurveTo(x, y + h, x + r, y + h);
- ctx.lineTo(x + w - r, y + h);
- ctx.quadraticCurveTo(x + w, y + h, x + w, y + h - r);
- ctx.lineTo(x + w, y + r);
- ctx.quadraticCurveTo(x + w, y, x + w - r, y);
- ctx.lineTo(x + r, y);
- ctx.quadraticCurveTo(x, y, x, y + r);
- ctx.closePath();
-
- // Clip to the rounded rect path.
- ctx.save();
- ctx.clip();
-
- // Fill the segments with the associated color.
- var previousSegmentsWidth = 0;
- for (var i = 0; i < segments.length; ++i) {
- var segmentWidth = Math.round(w * percents[i] / 100);
- ctx.fillStyle = segments[i].color;
- ctx.fillRect(x + previousSegmentsWidth, y, segmentWidth, h);
- previousSegmentsWidth += segmentWidth;
- }
-
- // Draw the segment divider lines.
- ctx.lineWidth = 1;
- for (var i = 1; i < 20; ++i) {
- ctx.beginPath();
- ctx.moveTo(x + (i * Math.round(w / 20)) + 0.5, y);
- ctx.lineTo(x + (i * Math.round(w / 20)) + 0.5, y + h);
- ctx.closePath();
-
- ctx.strokeStyle = "rgba(0, 0, 0, 0.2)";
- ctx.stroke();
-
- ctx.beginPath();
- ctx.moveTo(x + (i * Math.round(w / 20)) + 1.5, y);
- ctx.lineTo(x + (i * Math.round(w / 20)) + 1.5, y + h);
- ctx.closePath();
-
- ctx.strokeStyle = "rgba(255, 255, 255, 0.2)";
- ctx.stroke();
- }
-
- // Draw the pill shading.
- var lightGradient = ctx.createLinearGradient(x, y, x, y + (h / 1.5));
- lightGradient.addColorStop(0.0, "rgba(220, 220, 220, 0.6)");
- lightGradient.addColorStop(0.4, "rgba(220, 220, 220, 0.2)");
- lightGradient.addColorStop(1.0, "rgba(255, 255, 255, 0.0)");
-
- var darkGradient = ctx.createLinearGradient(x, y + (h / 3), x, y + h);
- darkGradient.addColorStop(0.0, "rgba(0, 0, 0, 0.0)");
- darkGradient.addColorStop(0.8, "rgba(0, 0, 0, 0.2)");
- darkGradient.addColorStop(1.0, "rgba(0, 0, 0, 0.5)");
-
- ctx.fillStyle = darkGradient;
- ctx.fillRect(x, y, w, h);
-
- ctx.fillStyle = lightGradient;
- ctx.fillRect(x, y, w, h);
-
- ctx.restore();
- }
-
- ctx.clearRect(x, y, w, (h * 2));
-
- drawPillShadow();
- drawPill();
-
- ctx.save();
-
- ctx.translate(0, (h * 2) + 1);
- ctx.scale(1, -1);
-
- drawPill();
-
- ctx.restore();
-
- this.fadeOutRect(ctx, x, y + h + 1, w, h, 0.5, 0.0);
- },
-
- updateSummaryGraphSoon: function()
- {
- if ("updateSummaryGraphTimeout" in this)
- return;
- this.updateSummaryGraphTimeout = setTimeout(this.updateSummaryGraph.bind(this), 500);
- },
-
- updateSummaryGraph: function()
- {
- if ("updateSummaryGraphTimeout" in this) {
- clearTimeout(this.updateSummaryGraphTimeout);
- delete this.updateSummaryGraphTimeout;
- }
-
- var graphInfo = this.calculator.computeValues(this.timelineEntries);
-
- var categoryOrder = ["documents", "stylesheets", "images", "scripts", "fonts", "other"];
- var categoryColors = {documents: {r: 47, g: 102, b: 236}, stylesheets: {r: 157, g: 231, b: 119}, images: {r: 164, g: 60, b: 255}, scripts: {r: 255, g: 121, b: 0}, fonts: {r: 231, g: 231, b: 10}, other: {r: 186, g: 186, b: 186}};
- var fillSegments = [];
-
- this.legendElement.removeChildren();
-
- if (this.totalLegendLabel)
- this.totalLegendLabel.parentNode.removeChild(this.totalLegendLabel);
-
- this.totalLegendLabel = this.makeLegendElement(this.calculator.totalTitle, this.calculator.formatValue(graphInfo.total));
- this.totalLegendLabel.addStyleClass("network-graph-legend-total");
- this.graphLabelElement.appendChild(this.totalLegendLabel);
-
- for (var i = 0; i < categoryOrder.length; ++i) {
- var category = categoryOrder[i];
- var size = graphInfo.categoryValues[category];
- if (!size)
- continue;
-
- var color = categoryColors[category];
- var colorString = "rgb(" + color.r + ", " + color.g + ", " + color.b + ")";
-
- var fillSegment = {color: colorString, value: size};
- fillSegments.push(fillSegment);
-
- var legendLabel = this.makeLegendElement(WebInspector.resourceCategories[category].title, this.calculator.formatValue(size), colorString);
- this.legendElement.appendChild(legendLabel);
- }
-
- this.drawSummaryGraph(fillSegments);
- },
-
- clearTimeline: function()
- {
- delete this.earliestStartTime;
- delete this.latestEndTime;
-
- var entriesLength = this.timelineEntries.length;
- for (var i = 0; i < entriesLength; ++i)
- delete this.timelineEntries[i].resource.networkTimelineEntry;
-
- this.timelineEntries = [];
- this.resourcesElement.removeChildren();
-
- this.drawSummaryGraph(); // draws an empty graph
- },
-
- addResourceToTimeline: function(resource)
- {
- var timelineEntry = new WebInspector.NetworkTimelineEntry(this, resource);
- this.timelineEntries.push(timelineEntry);
- this.resourcesElement.appendChild(timelineEntry.resourceElement);
-
- timelineEntry.refresh();
- this.updateSummaryGraphSoon();
- }
-}
-
-WebInspector.NetworkPanel.prototype.__proto__ = WebInspector.Panel.prototype;
-
-WebInspector.NetworkPanel.timelineEntryCompare = function(a, b)
-{
- if (a.resource.startTime < b.resource.startTime)
- return -1;
- if (a.resource.startTime > b.resource.startTime)
- return 1;
- if (a.resource.endTime < b.resource.endTime)
- return -1;
- if (a.resource.endTime > b.resource.endTime)
- return 1;
- return 0;
-}
-
-WebInspector.NetworkTimelineEntry = function(panel, resource)
-{
- this.panel = panel;
- this.resource = resource;
- resource.networkTimelineEntry = this;
-
- this.resourceElement = document.createElement("div");
- this.resourceElement.className = "network-resource";
- this.resourceElement.timelineEntry = this;
-
- this.titleElement = document.createElement("div");
- this.titleElement.className = "network-title";
- this.resourceElement.appendChild(this.titleElement);
-
- this.fileElement = document.createElement("div");
- this.fileElement.className = "network-file";
- this.fileElement.innerHTML = WebInspector.linkifyURL(resource.url, resource.displayName);
- this.titleElement.appendChild(this.fileElement);
-
- this.tipButtonElement = document.createElement("button");
- this.tipButtonElement.className = "tip-button";
- this.showingTipButton = this.resource.tips.length;
- this.fileElement.insertBefore(this.tipButtonElement, this.fileElement.firstChild);
-
- this.tipButtonElement.addEventListener("click", this.toggleTipBalloon.bind(this), false );
-
- this.areaElement = document.createElement("div");
- this.areaElement.className = "network-area";
- this.titleElement.appendChild(this.areaElement);
-
- this.barElement = document.createElement("div");
- this.areaElement.appendChild(this.barElement);
-
- this.infoElement = document.createElement("div");
- this.infoElement.className = "network-info hidden";
- this.resourceElement.appendChild(this.infoElement);
-}
-
-WebInspector.NetworkTimelineEntry.prototype = {
- refresh: function(skipBoundryUpdate, skipTimelineSort, immediate)
- {
- if (!this.panel.visible) {
- this.needsRefresh = true;
- this.panel.needsRefresh = true;
- return;
- }
-
- delete this.needsRefresh;
-
- if (!skipBoundryUpdate) {
- if (this.panel.updateTimelineBoundriesIfNeeded(this.resource, immediate))
- return; // updateTimelineBoundriesIfNeeded calls refresh() on all entries, so we can just return
- }
-
- if (!skipTimelineSort) {
- if (immediate)
- this.panel.sortTimelineEntriesIfNeeded();
- else
- this.panel.sortTimelineEntriesSoonIfNeeded();
- }
-
- if (this.resource.startTime !== -1) {
- var percentStart = ((this.resource.startTime - this.panel.earliestStartTime) / this.panel.totalDuration) * 100;
- this.barElement.style.left = percentStart + "%";
- } else {
- this.barElement.style.left = null;
- }
-
- if (this.resource.endTime !== -1) {
- var percentEnd = ((this.panel.latestEndTime - this.resource.endTime) / this.panel.totalDuration) * 100;
- this.barElement.style.right = percentEnd + "%";
- } else {
- this.barElement.style.right = "0px";
- }
-
- this.barElement.className = "network-bar network-category-" + this.resource.category.name;
-
- if (this.infoNeedsRefresh)
- this.refreshInfo();
- },
-
- refreshInfo: function()
- {
- if (!this.showingInfo) {
- this.infoNeedsRefresh = true;
- return;
- }
-
- if (!this.panel.visible) {
- this.panel.needsRefresh = true;
- this.infoNeedsRefresh = true;
- return;
- }
-
- this.infoNeedsRefresh = false;
-
- this.infoElement.removeChildren();
-
- var sections = [
- {title: WebInspector.UIString("Request"), info: this.resource.sortedRequestHeaders},
- {title: WebInspector.UIString("Response"), info: this.resource.sortedResponseHeaders}
- ];
-
- function createSectionTable(section)
- {
- if (!section.info.length)
- return;
-
- var table = document.createElement("table");
- this.infoElement.appendChild(table);
-
- var heading = document.createElement("th");
- heading.textContent = section.title;
-
- var row = table.createTHead().insertRow(-1).appendChild(heading);
- var body = document.createElement("tbody");
- table.appendChild(body);
-
- section.info.forEach(function(header) {
- var row = body.insertRow(-1);
- var th = document.createElement("th");
- th.textContent = header.header;
- row.appendChild(th);
- row.insertCell(-1).textContent = header.value;
- });
- }
-
- sections.forEach(createSectionTable, this);
- },
-
- refreshInfoIfNeeded: function()
- {
- if (this.infoNeedsRefresh === false)
- return;
-
- this.refreshInfo();
- },
-
- toggleShowingInfo: function()
- {
- this.showingInfo = !this.showingInfo;
- },
-
- get showingInfo()
- {
- return this._showingInfo;
- },
-
- set showingInfo(x)
- {
- if (this._showingInfo === x)
- return;
-
- this._showingInfo = x;
-
- var element = this.infoElement;
- if (x) {
- element.removeStyleClass("hidden");
- element.style.setProperty("overflow", "hidden");
- this.refreshInfoIfNeeded();
- WebInspector.animateStyle([{element: element, start: {height: 0}, end: {height: element.offsetHeight}}], 250, function() { element.style.removeProperty("height"); element.style.removeProperty("overflow") });
- } else {
- element.style.setProperty("overflow", "hidden");
- WebInspector.animateStyle([{element: element, end: {height: 0}}], 250, function() { element.addStyleClass("hidden"); element.style.removeProperty("height") });
- }
- },
-
- get showingTipButton()
- {
- return !this.tipButtonElement.hasStyleClass("hidden");
- },
-
- set showingTipButton(x)
- {
- if (x)
- this.tipButtonElement.removeStyleClass("hidden");
- else
- this.tipButtonElement.addStyleClass("hidden");
- },
-
- toggleTipBalloon: function(event)
- {
- this.showingTipBalloon = !this.showingTipBalloon;
- event.stopPropagation();
- },
-
- get showingTipBalloon()
- {
- return this._showingTipBalloon;
- },
-
- set showingTipBalloon(x)
- {
- if (this._showingTipBalloon === x)
- return;
-
- this._showingTipBalloon = x;
-
- if (x) {
- if (!this.tipBalloonElement) {
- this.tipBalloonElement = document.createElement("div");
- this.tipBalloonElement.className = "tip-balloon";
- this.titleElement.appendChild(this.tipBalloonElement);
-
- this.tipBalloonContentElement = document.createElement("div");
- this.tipBalloonContentElement.className = "tip-balloon-content";
- this.tipBalloonElement.appendChild(this.tipBalloonContentElement);
- var tipText = "";
- for (var id in this.resource.tips)
- tipText += this.resource.tips[id].message + "\n";
- this.tipBalloonContentElement.textContent = tipText;
- }
-
- this.tipBalloonElement.removeStyleClass("hidden");
- WebInspector.animateStyle([{element: this.tipBalloonElement, start: {left: 160, opacity: 0}, end: {left: 145, opacity: 1}}], 250);
- } else {
- var element = this.tipBalloonElement;
- WebInspector.animateStyle([{element: this.tipBalloonElement, start: {left: 145, opacity: 1}, end: {left: 160, opacity: 0}}], 250, function() { element.addStyleClass("hidden") });
- }
- }
-}
-
-WebInspector.TimelineValueCalculator = function()
-{
-}
-
-WebInspector.TimelineValueCalculator.prototype = {
- computeValues: function(entries)
- {
- var total = 0;
- var categoryValues = {};
-
- function compute(entry)
- {
- var value = this._value(entry);
- if (value === undefined)
- return;
-
- if (!(entry.resource.category.name in categoryValues))
- categoryValues[entry.resource.category.name] = 0;
- categoryValues[entry.resource.category.name] += value;
- total += value;
- }
- entries.forEach(compute, this);
-
- return {categoryValues: categoryValues, total: total};
- },
-
- _value: function(entry)
- {
- return 0;
- },
-
- get title()
- {
- return "";
- },
-
- formatValue: function(value)
- {
- return value.toString();
- }
-}
-
-WebInspector.TransferTimeCalculator = function()
-{
- WebInspector.TimelineValueCalculator.call(this);
-}
-
-WebInspector.TransferTimeCalculator.prototype = {
- computeValues: function(entries)
- {
- var entriesByCategory = {};
- entries.forEach(function(entry) {
- if (!(entry.resource.category.name in entriesByCategory))
- entriesByCategory[entry.resource.category.name] = [];
- entriesByCategory[entry.resource.category.name].push(entry);
- });
-
- var earliestStart;
- var latestEnd;
- var categoryValues = {};
- for (var category in entriesByCategory) {
- entriesByCategory[category].sort(WebInspector.NetworkPanel.timelineEntryCompare);
- categoryValues[category] = 0;
-
- var segment = {start: -1, end: -1};
- entriesByCategory[category].forEach(function(entry) {
- if (entry.resource.startTime == -1 || entry.resource.endTime == -1)
- return;
-
- if (earliestStart === undefined)
- earliestStart = entry.resource.startTime;
- else
- earliestStart = Math.min(earliestStart, entry.resource.startTime);
-
- if (latestEnd === undefined)
- latestEnd = entry.resource.endTime;
- else
- latestEnd = Math.max(latestEnd, entry.resource.endTime);
-
- if (entry.resource.startTime <= segment.end) {
- segment.end = Math.max(segment.end, entry.resource.endTime);
- return;
- }
-
- categoryValues[category] += segment.end - segment.start;
-
- segment.start = entry.resource.startTime;
- segment.end = entry.resource.endTime;
- });
-
- // Add the last segment
- categoryValues[category] += segment.end - segment.start;
- }
-
- return {categoryValues: categoryValues, total: latestEnd - earliestStart};
- },
-
- get title()
- {
- return WebInspector.UIString("Transfer Time");
- },
-
- get totalTitle()
- {
- return WebInspector.UIString("Total Time");
- },
-
- formatValue: function(value)
- {
- return Number.secondsToString(value);
- }
-}
-
-WebInspector.TransferTimeCalculator.prototype.__proto__ = WebInspector.TimelineValueCalculator.prototype;
-
-WebInspector.TransferSizeCalculator = function()
-{
- WebInspector.TimelineValueCalculator.call(this);
-}
-
-WebInspector.TransferSizeCalculator.prototype = {
- _value: function(entry)
- {
- return entry.resource.contentLength;
- },
-
- get title()
- {
- return WebInspector.UIString("Transfer Size");
- },
-
- get totalTitle()
- {
- return WebInspector.UIString("Total Size");
- },
-
- formatValue: function(value)
- {
- return Number.bytesToString(value);
- }
-}
-
-WebInspector.TransferSizeCalculator.prototype.__proto__ = WebInspector.TimelineValueCalculator.prototype;
diff --git a/WebCore/page/inspector/Panel.js b/WebCore/page/inspector/Panel.js
deleted file mode 100644
index 7631fa3..0000000
--- a/WebCore/page/inspector/Panel.js
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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.
- */
-
-WebInspector.Panel = function(views)
-{
- this._visible = false;
-
- this.element = document.createElement("div");
- this.element.className = "panel";
-
- this.views = {};
- this.viewButtons = [];
-
- if (views) {
- var selectViewFunction = function(event)
- {
- var clickedView = event.currentTarget.view;
- clickedView.panel.currentView = clickedView;
- };
-
- for (var i = 0; i < views.length; ++i) {
- var view = views[i];
- view.panel = this;
-
- view.buttonElement = document.createElement("button");
- view.buttonElement.title = view.title;
- view.buttonElement.addEventListener("click", selectViewFunction, false);
- view.buttonElement.appendChild(document.createElement("img"));
- view.buttonElement.view = view;
-
- view.contentElement = document.createElement("div");
- view.contentElement.className = "content " + view.name;
-
- this.views[view.name] = view;
- this.viewButtons.push(view.buttonElement);
- this.element.appendChild(view.contentElement);
- }
- }
-}
-
-WebInspector.Panel.prototype = {
- show: function()
- {
- this._visible = true;
- if (!this.element.parentNode)
- this.attach();
- this.element.addStyleClass("selected");
- this.updateToolbar();
- if (this.currentView && this.currentView.show)
- this.currentView.show();
- },
-
- hide: function()
- {
- if (this.currentView && this.currentView.hide)
- this.currentView.hide();
- document.getElementById("toolbarButtons").removeChildren();
- this.element.removeStyleClass("selected");
- this._visible = false;
- },
-
- updateToolbar: function()
- {
- var buttonContainer = document.getElementById("toolbarButtons");
- buttonContainer.removeChildren();
-
- var buttons = this.viewButtons;
- if (buttons.length < 2)
- return;
-
- for (var i = 0; i < buttons.length; ++i) {
- var button = buttons[i];
-
- if (i === 0)
- button.addStyleClass("first");
- else if (i === (buttons.length - 1))
- button.addStyleClass("last");
-
- if (i) {
- var divider = document.createElement("img");
- divider.className = "split-button-divider";
- buttonContainer.appendChild(divider);
- }
-
- button.addStyleClass("split-button");
- button.addStyleClass("view-button-" + button.title.toLowerCase());
-
- buttonContainer.appendChild(button);
- }
- },
-
- attach: function()
- {
- document.getElementById("panels").appendChild(this.element);
- },
-
- detach: function()
- {
- if (WebInspector.currentPanel === this)
- WebInspector.currentPanel = null;
- if (this.element && this.element.parentNode)
- this.element.parentNode.removeChild(this.element);
- },
-
- get currentView()
- {
- return this._currentView;
- },
-
- set currentView(x)
- {
- if (typeof x === "string" || x instanceof String)
- x = this.views[x];
-
- if (this._currentView === x)
- return;
-
- if (this !== x.panel) {
- console.error("Set currentView to a view " + x.title + " whose panel is not this panel");
- return;
- }
-
- if (this._currentView) {
- this._currentView.buttonElement.removeStyleClass("selected");
- this._currentView.contentElement.removeStyleClass("selected");
- if (this._currentView.hide)
- this._currentView.hide();
- }
-
- this._currentView = x;
-
- if (x) {
- x.buttonElement.addStyleClass("selected");
- x.contentElement.addStyleClass("selected");
- if (x.show)
- x.show();
- }
- },
-
- get visible()
- {
- return this._visible;
- },
-
- set visible(x)
- {
- if (this._visible === x)
- return;
-
- if (x)
- this.show();
- else
- this.hide();
- }
-}
diff --git a/WebCore/page/inspector/PropertiesSection.js b/WebCore/page/inspector/PropertiesSection.js
deleted file mode 100644
index b2a3473..0000000
--- a/WebCore/page/inspector/PropertiesSection.js
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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.
- */
-
-WebInspector.PropertiesSection = function(title, subtitle)
-{
- this.element = document.createElement("div");
- this.element.className = "section";
-
- this.headerElement = document.createElement("div");
- this.headerElement.className = "header";
-
- this.titleElement = document.createElement("div");
- this.titleElement.className = "title";
-
- this.subtitleElement = document.createElement("div");
- this.subtitleElement.className = "subtitle";
-
- this.headerElement.appendChild(this.titleElement);
- this.headerElement.appendChild(this.subtitleElement);
- this.headerElement.addEventListener("click", this.toggleExpanded.bind(this), false);
-
- this.propertiesElement = document.createElement("ol");
- this.propertiesElement.className = "properties";
- this.propertiesTreeOutline = new TreeOutline(this.propertiesElement);
- this.propertiesTreeOutline.section = this;
-
- this.element.appendChild(this.headerElement);
- this.element.appendChild(this.propertiesElement);
-
- this.title = title;
- this.subtitle = subtitle;
- this.expanded = false;
-}
-
-WebInspector.PropertiesSection.prototype = {
- get title()
- {
- return this._title;
- },
-
- set title(x)
- {
- if (this._title === x)
- return;
- this._title = x;
- this.titleElement.textContent = x;
- },
-
- get subtitle()
- {
- return this._subtitle;
- },
-
- set subtitle(x)
- {
- if (this._subtitle === x)
- return;
- this._subtitle = x;
- this.subtitleElement.innerHTML = x;
- },
-
- get expanded()
- {
- return this._expanded;
- },
-
- set expanded(x)
- {
- if (x)
- this.expand();
- else
- this.collapse();
- },
-
- get populated()
- {
- return this._populated;
- },
-
- set populated(x)
- {
- this._populated = x;
- if (!x && this.onpopulate && this._expanded) {
- this.onpopulate(this);
- this._populated = true;
- }
- },
-
- expand: function()
- {
- if (this._expanded)
- return;
- this._expanded = true;
- this.element.addStyleClass("expanded");
-
- if (!this._populated && this.onpopulate) {
- this.onpopulate(this);
- this._populated = true;
- }
- },
-
- collapse: function()
- {
- if (!this._expanded)
- return;
- this._expanded = false;
- this.element.removeStyleClass("expanded");
- },
-
- toggleExpanded: function()
- {
- this.expanded = !this.expanded;
- }
-}
diff --git a/WebCore/page/inspector/PropertiesSidebarPane.js b/WebCore/page/inspector/PropertiesSidebarPane.js
deleted file mode 100644
index 0266d53..0000000
--- a/WebCore/page/inspector/PropertiesSidebarPane.js
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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.
- */
-
-WebInspector.PropertiesSidebarPane = function()
-{
- WebInspector.SidebarPane.call(this, WebInspector.UIString("Properties"));
-}
-
-WebInspector.PropertiesSidebarPane.prototype = {
- update: function(object)
- {
- var body = this.bodyElement;
-
- body.removeChildren();
-
- this.sections = [];
-
- if (!object)
- return;
-
- for (var prototype = object; prototype; prototype = prototype.__proto__) {
- var section = new WebInspector.ObjectPropertiesSection(prototype);
- this.sections.push(section);
- body.appendChild(section.element);
- }
- }
-}
-
-WebInspector.PropertiesSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;
-
-WebInspector.ObjectPropertiesSection = function(object)
-{
- var title = Object.describe(object);
- var subtitle;
- if (title.match(/Prototype$/)) {
- title = title.replace(/Prototype$/, "");
- subtitle = WebInspector.UIString("Prototype");
- }
-
- this.object = object;
-
- WebInspector.PropertiesSection.call(this, title, subtitle);
-}
-
-WebInspector.ObjectPropertiesSection.prototype = {
- onpopulate: function()
- {
- var properties = Object.sortedProperties(this.object);
- for (var i = 0; i < properties.length; ++i) {
- var propertyName = properties[i];
- if (!this.object.hasOwnProperty(propertyName) || propertyName === "__treeElementIdentifier")
- continue;
- this.propertiesTreeOutline.appendChild(new WebInspector.ObjectPropertyTreeElement(this.object, propertyName));
- }
- }
-}
-
-WebInspector.ObjectPropertiesSection.prototype.__proto__ = WebInspector.PropertiesSection.prototype;
-
-WebInspector.ObjectPropertyTreeElement = function(parentObject, propertyName)
-{
- this.parentObject = parentObject;
- this.propertyName = propertyName;
-
- var childObject = this.safePropertyValue(parentObject, propertyName);
- var isGetter = parentObject.__lookupGetter__(propertyName);
-
- var title = "<span class=\"name\">" + propertyName.escapeHTML() + "</span>: ";
- if (!isGetter)
- title += "<span class=\"value\">" + Object.describe(childObject, true).escapeHTML() + "</span>";
- else
- // FIXME: this should show something like "getter" once we can change localization (bug 16734).
- title += "<span class=\"value dimmed\">&mdash;</span>";
-
- var hasSubProperties = false;
- var type = typeof childObject;
- if (childObject && (type === "object" || type === "function")) {
- for (subPropertyName in childObject) {
- if (subPropertyName === "__treeElementIdentifier")
- continue;
- hasSubProperties = true;
- break;
- }
- }
-
- TreeElement.call(this, title, null, hasSubProperties);
-}
-
-WebInspector.ObjectPropertyTreeElement.prototype = {
- safePropertyValue: function(object, propertyName)
- {
- var getter = object.__lookupGetter__(propertyName);
- if (getter)
- return;
- return object[propertyName];
- },
-
- onpopulate: function()
- {
- if (this.children.length)
- return;
-
- var childObject = this.safePropertyValue(this.parentObject, this.propertyName);
- var properties = Object.sortedProperties(childObject);
- for (var i = 0; i < properties.length; ++i) {
- var propertyName = properties[i];
- if (propertyName === "__treeElementIdentifier")
- continue;
- this.appendChild(new WebInspector.ObjectPropertyTreeElement(childObject, propertyName));
- }
- }
-}
-
-WebInspector.ObjectPropertyTreeElement.prototype.__proto__ = TreeElement.prototype;
diff --git a/WebCore/page/inspector/Resource.js b/WebCore/page/inspector/Resource.js
deleted file mode 100644
index 2f87b13..0000000
--- a/WebCore/page/inspector/Resource.js
+++ /dev/null
@@ -1,690 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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.
- */
-
-WebInspector.Resource = function(requestHeaders, url, domain, path, lastPathComponent, identifier, mainResource, cached)
-{
- this.identifier = identifier;
-
- this.startTime = -1;
- this.endTime = -1;
- this.mainResource = mainResource;
- this.requestHeaders = requestHeaders;
- this.url = url;
- this.domain = domain;
- this.path = path;
- this.lastPathComponent = lastPathComponent;
- this.cached = cached;
-
- this.listItem = new WebInspector.ResourceTreeElement(this);
- this.updateTitle();
-
- this.category = WebInspector.resourceCategories.other;
-}
-
-// Keep these in sync with WebCore::InspectorResource::Type
-WebInspector.Resource.Type = {
- Document: 0,
- Stylesheet: 1,
- Image: 2,
- Font: 3,
- Script: 4,
- Other: 5,
-
- isTextType: function(type)
- {
- return (type == this.Document) || (type == this.Stylesheet) || (type == this.Script);
- },
-
- toString: function(type)
- {
- switch (type) {
- case this.Document:
- return WebInspector.UIString("document");
- case this.Stylesheet:
- return WebInspector.UIString("stylesheet");
- case this.Image:
- return WebInspector.UIString("image");
- case this.Font:
- return WebInspector.UIString("font");
- case this.Script:
- return WebInspector.UIString("script");
- case this.Other:
- default:
- return WebInspector.UIString("other");
- }
- }
-}
-
-WebInspector.Resource.prototype = {
- get url()
- {
- return this._url;
- },
-
- set url(x)
- {
- if (this._url === x)
- return;
-
- var oldURL = this._url;
- this._url = x;
- WebInspector.resourceURLChanged(this, oldURL);
- this.updateTitleSoon();
- },
-
- get domain()
- {
- return this._domain;
- },
-
- set domain(x)
- {
- if (this._domain === x)
- return;
- this._domain = x;
- this.updateTitleSoon();
- },
-
- get lastPathComponent()
- {
- return this._lastPathComponent;
- },
-
- set lastPathComponent(x)
- {
- if (this._lastPathComponent === x)
- return;
- this._lastPathComponent = x;
- this._lastPathComponentLowerCase = x ? x.toLowerCase() : null;
- this.updateTitleSoon();
- },
-
- get displayName()
- {
- var title = this.lastPathComponent;
- if (!title)
- title = this.domain;
- if (!title)
- title = this.url;
- return title;
- },
-
- get startTime()
- {
- return this._startTime;
- },
-
- set startTime(x)
- {
- if (this._startTime === x)
- return;
-
- this._startTime = x;
-
- if (this.networkTimelineEntry)
- this.networkTimelineEntry.refresh();
- },
-
- get responseReceivedTime()
- {
- return this._responseReceivedTime;
- },
-
- set responseReceivedTime(x)
- {
- if (this._responseReceivedTime === x)
- return;
-
- this._responseReceivedTime = x;
-
- if (this.networkTimelineEntry)
- this.networkTimelineEntry.refresh();
- },
-
- get endTime()
- {
- return this._endTime;
- },
-
- set endTime(x)
- {
- if (this._endTime === x)
- return;
-
- this._endTime = x;
-
- if (this.networkTimelineEntry)
- this.networkTimelineEntry.refresh();
- },
-
- get contentLength()
- {
- return this._contentLength;
- },
-
- set contentLength(x)
- {
- if (this._contentLength === x)
- return;
-
- this._contentLength = x;
-
- if (this._expectedContentLength && this._expectedContentLength > x) {
- this.updateTitle();
- var canvas = document.getElementById("loadingIcon" + this.identifier);
- if (canvas)
- WebInspector.drawLoadingPieChart(canvas, (x / this._expectedContentLength));
- }
-
- WebInspector.networkPanel.updateSummaryGraphSoon();
- },
-
- get expectedContentLength()
- {
- return this._expectedContentLength;
- },
-
- set expectedContentLength(x)
- {
- if (this._expectedContentLength === x)
- return;
-
- this._expectedContentLength = x;
-
- if (x && this._contentLength && this._contentLength <= x) {
- var canvas = document.getElementById("loadingIcon" + this.identifier);
- if (canvas)
- WebInspector.drawLoadingPieChart(canvas, (this._contentLength / x));
- }
- },
-
- get finished()
- {
- return this._finished;
- },
-
- set finished(x)
- {
- if (this._finished === x)
- return;
-
- this._finished = x;
-
- if (x) {
- var canvas = document.getElementById("loadingIcon" + this.identifier);
- if (canvas)
- canvas.parentNode.removeChild(canvas);
-
- this._checkTips();
- this._checkWarnings();
- }
-
- this.updateTitleSoon();
- this.updatePanel();
- },
-
- get failed()
- {
- return this._failed;
- },
-
- set failed(x)
- {
- this._failed = x;
-
- this.updateTitleSoon();
- this.updatePanel();
- },
-
- get category()
- {
- return this._category;
- },
-
- set category(x)
- {
- if (this._category === x)
- return;
-
- var oldCategory = this._category;
- if (oldCategory)
- oldCategory.removeResource(this);
-
- this._category = x;
- this.updateTitle();
-
- if (this._category)
- this._category.addResource(this);
-
- this.updatePanel();
- },
-
- get mimeType()
- {
- return this._mimeType;
- },
-
- set mimeType(x)
- {
- if (this._mimeType === x)
- return;
-
- this._mimeType = x;
- },
-
- get type()
- {
- return this._type;
- },
-
- set type(x)
- {
- if (this._type === x)
- return;
-
- this._type = x;
-
- switch (x) {
- case WebInspector.Resource.Type.Document:
- this.category = WebInspector.resourceCategories.documents;
- break;
- case WebInspector.Resource.Type.Stylesheet:
- this.category = WebInspector.resourceCategories.stylesheets;
- break;
- case WebInspector.Resource.Type.Script:
- this.category = WebInspector.resourceCategories.scripts;
- break;
- case WebInspector.Resource.Type.Image:
- this.category = WebInspector.resourceCategories.images;
- break;
- case WebInspector.Resource.Type.Font:
- this.category = WebInspector.resourceCategories.fonts;
- break;
- case WebInspector.Resource.Type.Other:
- default:
- this.category = WebInspector.resourceCategories.other;
- break;
- }
- },
-
- get documentNode() {
- if ("identifier" in this)
- return InspectorController.getResourceDocumentNode(this.identifier);
- return null;
- },
-
- get requestHeaders()
- {
- if (this._requestHeaders === undefined)
- this._requestHeaders = {};
- return this._requestHeaders;
- },
-
- set requestHeaders(x)
- {
- if (this._requestHeaders === x)
- return;
-
- this._requestHeaders = x;
- delete this._sortedRequestHeaders;
-
- if (this.networkTimelineEntry)
- this.networkTimelineEntry.refreshInfo();
- },
-
- get sortedRequestHeaders()
- {
- if (this._sortedRequestHeaders !== undefined)
- return this._sortedRequestHeaders;
-
- this._sortedRequestHeaders = [];
- for (var key in this.requestHeaders)
- this._sortedRequestHeaders.push({header: key, value: this.requestHeaders[key]});
- this._sortedRequestHeaders.sort(function(a,b) { return a.header.localeCompare(b.header) });
-
- return this._sortedRequestHeaders;
- },
-
- get responseHeaders()
- {
- if (this._responseHeaders === undefined)
- this._responseHeaders = {};
- return this._responseHeaders;
- },
-
- set responseHeaders(x)
- {
- if (this._responseHeaders === x)
- return;
-
- this._responseHeaders = x;
- delete this._sortedResponseHeaders;
-
- if (this.networkTimelineEntry)
- this.networkTimelineEntry.refreshInfo();
- },
-
- get sortedResponseHeaders()
- {
- if (this._sortedResponseHeaders !== undefined)
- return this._sortedResponseHeaders;
-
- this._sortedResponseHeaders = [];
- for (var key in this.responseHeaders)
- this._sortedResponseHeaders.push({header: key, value: this.responseHeaders[key]});
- this._sortedResponseHeaders.sort(function(a,b) { return a.header.localeCompare(b.header) });
-
- return this._sortedResponseHeaders;
- },
-
- get tips()
- {
- if (!("_tips" in this))
- this._tips = {};
- return this._tips;
- },
-
- _addTip: function(tip)
- {
- if (tip.id in this.tips)
- return;
-
- this.tips[tip.id] = tip;
-
- // FIXME: Re-enable this code once we have a scope bar in the Console.
- // Otherwise, we flood the Console with too many tips.
- /*
- var msg = new WebInspector.ConsoleMessage(WebInspector.ConsoleMessage.MessageSource.Other,
- WebInspector.ConsoleMessage.MessageLevel.Tip, tip.message, -1, this.url);
- WebInspector.consolePanel.addMessage(msg);
- */
-
- if (this.networkTimelineEntry)
- this.networkTimelineEntry.showingTipButton = true;
- },
-
- _checkTips: function()
- {
- for (var tip in WebInspector.Tips)
- this._checkTip(WebInspector.Tips[tip]);
- },
-
- _checkTip: function(tip)
- {
- var addTip = false;
- switch (tip.id) {
- case WebInspector.Tips.ResourceNotCompressed.id:
- addTip = this._shouldCompress();
- break;
- }
-
- if (addTip)
- this._addTip(tip);
- },
-
- _shouldCompress: function()
- {
- return WebInspector.Resource.Type.isTextType(this.type)
- && this.domain
- && !("Content-Encoding" in this.responseHeaders)
- && this.contentLength !== undefined
- && this.contentLength >= 512;
- },
-
- _mimeTypeIsConsistentWithType: function()
- {
- if (this.type === undefined || this.type === WebInspector.Resource.Type.Other)
- return true;
-
- if (this.mimeType in WebInspector.MIMETypes)
- return this.type in WebInspector.MIMETypes[this.mimeType];
-
- return true;
- },
-
- _checkWarnings: function()
- {
- for (var warning in WebInspector.Warnings)
- this._checkWarning(WebInspector.Warnings[warning]);
- },
-
- _checkWarning: function(warning)
- {
- var addWarning = false;
- var msg;
- switch (warning.id) {
- case WebInspector.Warnings.IncorrectMIMEType.id:
- if (!this._mimeTypeIsConsistentWithType())
- msg = new WebInspector.ConsoleMessage(WebInspector.ConsoleMessage.MessageSource.Other,
- WebInspector.ConsoleMessage.MessageLevel.Warning,
- String.sprintf(WebInspector.Warnings.IncorrectMIMEType.message,
- WebInspector.Resource.Type.toString(this.type), this.mimeType),
- -1, this.url);
- break;
- }
-
- if (msg)
- WebInspector.consolePanel.addMessage(msg);
- },
-
- updateTitleSoon: function()
- {
- if (this.updateTitleTimeout)
- return;
- this.updateTitleTimeout = setTimeout(this.updateTitle.bind(this), 0);
- },
-
- updateTitle: function()
- {
- delete this.updateTitleTimeout;
-
- var title = this.displayName;
-
- var info = "";
- if (this.domain && (!WebInspector.mainResource || (WebInspector.mainResource && this.domain !== WebInspector.mainResource.domain)))
- info = this.domain;
-
- if (this.path && this.lastPathComponent) {
- var lastPathComponentIndex = this.path.lastIndexOf("/" + this.lastPathComponent);
- if (lastPathComponentIndex != -1)
- info += this.path.substring(0, lastPathComponentIndex);
- }
-
- var fullTitle = "";
-
- if (this.errors)
- fullTitle += "<span class=\"count errors\">" + (this.errors + this.warnings) + "</span>";
- else if (this.warnings)
- fullTitle += "<span class=\"count warnings\">" + this.warnings + "</span>";
-
- fullTitle += "<span class=\"title" + (info && info.length ? "" : " only") + "\">" + title.escapeHTML() + "</span>";
- if (info && info.length)
- fullTitle += "<span class=\"info\">" + info.escapeHTML() + "</span>";
-
- var iconClass = "icon";
- switch (this.category) {
- default:
- break;
- case WebInspector.resourceCategories.images:
- case WebInspector.resourceCategories.other:
- iconClass = "icon plain";
- break;
- case WebInspector.resourceCategories.fonts:
- iconClass = "icon font";
- }
-
- if (!this.finished)
- fullTitle += "<div class=\"" + iconClass + "\"><canvas id=\"loadingIcon" + this.identifier + "\" class=\"progress\" width=\"16\" height=\"16\"></canvas></div>";
- else if (this.category === WebInspector.resourceCategories.images)
- fullTitle += "<div class=\"" + iconClass + "\"><img class=\"preview\" src=\"" + this.url + "\"></div>";
- else if (this.category === WebInspector.resourceCategories.fonts) {
- var uniqueFontName = "WebInspectorFontPreview" + this.identifier;
-
- this.fontStyleElement = document.createElement("style");
- this.fontStyleElement.textContent = "@font-face { font-family: \"" + uniqueFontName + "\"; src: url(" + this.url + "); }";
- document.getElementsByTagName("head").item(0).appendChild(this.fontStyleElement);
-
- fullTitle += "<div class=\"" + iconClass + "\"><div class=\"preview\" style=\"font-family: " + uniqueFontName + "\">Ag</div></div>";
- } else
- fullTitle += "<div class=\"" + iconClass + "\"></div>";
-
- this.listItem.title = fullTitle;
- this.listItem.tooltip = this.url;
- },
-
- updatePanel: function()
- {
- if (this._panel) {
- var current = (WebInspector.currentPanel === this._panel);
-
- this._panel.detach();
- delete this._panel;
-
- if (current)
- WebInspector.currentPanel = this.panel;
- }
- },
-
- get panel()
- {
- if (!this._panel) {
- if (this.finished && !this.failed) {
- switch (this.category) {
- case WebInspector.resourceCategories.documents:
- this._panel = new WebInspector.DocumentPanel(this);
- break;
- case WebInspector.resourceCategories.stylesheets:
- case WebInspector.resourceCategories.scripts:
- this._panel = new WebInspector.SourcePanel(this);
- break;
- case WebInspector.resourceCategories.images:
- this._panel = new WebInspector.ImagePanel(this);
- break;
- case WebInspector.resourceCategories.fonts:
- this._panel = new WebInspector.FontPanel(this);
- break;
- }
- }
-
- if (!this._panel)
- this._panel = new WebInspector.ResourcePanel(this);
- }
-
- return this._panel;
- },
-
- select: function()
- {
- WebInspector.navigateToResource(this);
- },
-
- deselect: function()
- {
- this.listItem.deselect(true);
- if (WebInspector.currentPanel === this._panel)
- WebInspector.currentPanel = null;
- },
-
- attach: function()
- {
- if (this._panel)
- this._panel.attach();
- },
-
- detach: function()
- {
- if (this._panel)
- this._panel.detach();
- if (this.fontStyleElement && this.fontStyleElement.parentNode)
- this.fontStyleElement.parentNode.removeChild(this.fontStyleElement);
- },
-
- get errors()
- {
- if (!("_errors" in this))
- this._errors = 0;
-
- return this._errors;
- },
-
- set errors(x)
- {
- if (this._errors === x)
- return;
-
- this._errors = x;
- this.updateTitleSoon();
- },
-
- get warnings()
- {
- if (!("_warnings" in this))
- this._warnings = 0;
-
- return this._warnings;
- },
-
- set warnings(x)
- {
- if (this._warnings === x)
- return;
-
- this._warnings = x;
- this.updateTitleSoon();
- }
-}
-
-WebInspector.ResourceTreeElement = function(resource)
-{
- TreeElement.call(this, "", resource, false);
- this.resource = resource;
-}
-
-WebInspector.ResourceTreeElement.prototype = {
- onselect: function()
- {
- var selectedElement = WebInspector.fileOutline.selectedTreeElement;
- if (selectedElement)
- selectedElement.deselect();
- this.resource.select();
- },
-
- ondeselect: function()
- {
- this.resource.deselect();
- },
-
- onreveal: function()
- {
- if (!this.listItemElement || !this.treeOutline || !this.treeOutline.childrenListElement)
- return;
- this.treeOutline.childrenListElement.scrollToElement(this.listItemElement);
- }
-}
-
-WebInspector.ResourceTreeElement.prototype.__proto__ = TreeElement.prototype;
diff --git a/WebCore/page/inspector/ResourceCategory.js b/WebCore/page/inspector/ResourceCategory.js
deleted file mode 100644
index a2f2ba4..0000000
--- a/WebCore/page/inspector/ResourceCategory.js
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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.
- */
-
-WebInspector.ResourceCategory = function(title, name)
-{
- this.name = name;
- this.title = title;
- this.resources = [];
- this.listItem = new WebInspector.ResourceCategoryTreeElement(this);
- this.listItem.hidden = true;
- WebInspector.fileOutline.appendChild(this.listItem);
-}
-
-WebInspector.ResourceCategory.prototype = {
- toString: function()
- {
- return this.title;
- },
-
- addResource: function(resource)
- {
- var a = resource;
- var resourcesLength = this.resources.length;
- for (var i = 0; i < resourcesLength; ++i) {
- var b = this.resources[i];
- if (a._lastPathComponentLowerCase && b._lastPathComponentLowerCase)
- if (a._lastPathComponentLowerCase < b._lastPathComponentLowerCase)
- break;
- else if (a.name && b.name)
- if (a.name < b.name)
- break;
- }
-
- this.resources.splice(i, 0, resource);
- this.listItem.insertChild(resource.listItem, i);
- this.listItem.hidden = false;
-
- resource.attach();
- },
-
- removeResource: function(resource)
- {
- resource.detach();
-
- var resourcesLength = this.resources.length;
- for (var i = 0; i < resourcesLength; ++i) {
- if (this.resources[i] === resource) {
- this.resources.splice(i, 1);
- break;
- }
- }
-
- this.listItem.removeChild(resource.listItem);
-
- if (!this.resources.length)
- this.listItem.hidden = true;
- },
-
- removeAllResources: function(resource)
- {
- var resourcesLength = this.resources.length;
- for (var i = 0; i < resourcesLength; ++i)
- this.resources[i].detach();
- this.resources = [];
- this.listItem.removeChildren();
- this.listItem.hidden = true;
- }
-}
-
-WebInspector.ResourceCategoryTreeElement = function(category)
-{
- TreeElement.call(this, category.title, category, true);
-}
-
-WebInspector.ResourceCategoryTreeElement.prototype = {
- selectable: false,
- arrowToggleWidth: 20
-}
-
-WebInspector.ResourceCategoryTreeElement.prototype.__proto__ = TreeElement.prototype;
diff --git a/WebCore/page/inspector/SidebarPane.js b/WebCore/page/inspector/SidebarPane.js
deleted file mode 100644
index 53f9d6d..0000000
--- a/WebCore/page/inspector/SidebarPane.js
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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.
- */
-
-WebInspector.SidebarPane = function(title)
-{
- this.element = document.createElement("div");
- this.element.className = "pane";
-
- this.titleElement = document.createElement("div");
- this.titleElement.className = "title";
- this.titleElement.addEventListener("click", this.toggleExpanded.bind(this), false);
-
- this.bodyElement = document.createElement("div");
- this.bodyElement.className = "body";
-
- this.element.appendChild(this.titleElement);
- this.element.appendChild(this.bodyElement);
-
- this.title = title;
- this.growbarVisible = false;
- this.expanded = false;
-}
-
-WebInspector.SidebarPane.prototype = {
- get title()
- {
- return this._title;
- },
-
- set title(x)
- {
- if (this._title === x)
- return;
- this._title = x;
- this.titleElement.textContent = x;
- },
-
- get growbarVisible()
- {
- return this._growbarVisible;
- },
-
- set growbarVisible(x)
- {
- if (this._growbarVisible === x)
- return;
-
- this._growbarVisible = x;
-
- if (x && !this._growbarElement) {
- this._growbarElement = document.createElement("div");
- this._growbarElement.className = "growbar";
- this.element.appendChild(this._growbarElement);
- } else if (!x && this._growbarElement) {
- if (this._growbarElement.parentNode)
- this._growbarElement.parentNode(this._growbarElement);
- delete this._growbarElement;
- }
- },
-
- get expanded()
- {
- return this._expanded;
- },
-
- set expanded(x)
- {
- if (x)
- this.expand();
- else
- this.collapse();
- },
-
- expand: function()
- {
- if (this._expanded)
- return;
- this._expanded = true;
- this.element.addStyleClass("expanded");
- if (this.onexpand)
- this.onexpand(this);
- },
-
- collapse: function()
- {
- if (!this._expanded)
- return;
- this._expanded = false;
- this.element.removeStyleClass("expanded");
- if (this.oncollapse)
- this.oncollapse(this);
- },
-
- toggleExpanded: function()
- {
- this.expanded = !this.expanded;
- }
-}
diff --git a/WebCore/page/inspector/SourcePanel.js b/WebCore/page/inspector/SourcePanel.js
deleted file mode 100644
index 9d4139c..0000000
--- a/WebCore/page/inspector/SourcePanel.js
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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.
- */
-
-WebInspector.SourcePanel = function(resource, views)
-{
- var allViews = [{ title: WebInspector.UIString("Source"), name: "source" }];
- if (views)
- allViews = allViews.concat(views);
-
- WebInspector.ResourcePanel.call(this, resource, allViews);
-
- this.currentView = this.views.source;
-
- var sourceView = this.views.source;
-
- sourceView.messages = [];
- sourceView.frameNeedsSetup = true;
-
- sourceView.frameElement = document.createElement("iframe");
- sourceView.frameElement.setAttribute("viewsource", "true");
- sourceView.contentElement.appendChild(sourceView.frameElement);
-}
-
-WebInspector.SourcePanel.prototype = {
- show: function()
- {
- WebInspector.ResourcePanel.prototype.show.call(this);
- this.setupSourceFrameIfNeeded();
- },
-
- setupSourceFrameIfNeeded: function()
- {
- if (this.views.source.frameNeedsSetup) {
- this.attach();
-
- InspectorController.addSourceToFrame(this.resource.identifier, this.views.source.frameElement);
- WebInspector.addMainEventListeners(this.views.source.frameElement.contentDocument);
-
- var length = this.views.source.messages;
- for (var i = 0; i < length; ++i)
- this._addMessageToSource(this.views.source.messages[i]);
-
- delete this.views.source.frameNeedsSetup;
- }
- },
-
- sourceRow: function(lineNumber)
- {
- this.setupSourceFrameIfNeeded();
-
- var doc = this.views.source.frameElement.contentDocument;
- var rows = doc.getElementsByTagName("table")[0].rows;
-
- // Line numbers are a 1-based index, but the rows collection is 0-based.
- --lineNumber;
- if (lineNumber >= rows.length)
- lineNumber = rows.length - 1;
-
- return rows[lineNumber];
- },
-
- showSourceLine: function(lineNumber)
- {
- var row = this.sourceRow(lineNumber);
- if (!row)
- return;
- this.currentView = this.views.source;
- row.scrollIntoView(true);
- },
-
- addMessageToSource: function(msg)
- {
- this.views.source.messages.push(msg);
- if (!this.views.source.frameNeedsSetup)
- this._addMessageToSource(msg);
- },
-
- _addMessageToSource: function(msg)
- {
- var row = this.sourceRow(msg.line);
- if (!row)
- return;
-
- var doc = this.views.source.frameElement.contentDocument;
- var cell = row.getElementsByTagName("td")[1];
-
- var errorDiv = cell.lastChild;
- if (!errorDiv || errorDiv.nodeName.toLowerCase() !== "div" || !errorDiv.hasStyleClass("webkit-html-message-bubble")) {
- errorDiv = doc.createElement("div");
- errorDiv.className = "webkit-html-message-bubble";
- cell.appendChild(errorDiv);
- }
-
- var imageURL;
- switch (msg.level) {
- case WebInspector.ConsoleMessage.MessageLevel.Error:
- errorDiv.addStyleClass("webkit-html-error-message");
- imageURL = "Images/errorIcon.png";
- break;
- case WebInspector.ConsoleMessage.MessageLevel.Warning:
- errorDiv.addStyleClass("webkit-html-warning-message");
- imageURL = "Images/warningIcon.png";
- break;
- }
-
- var lineDiv = doc.createElement("div");
- lineDiv.className = "webkit-html-message-line";
- errorDiv.appendChild(lineDiv);
-
- var image = doc.createElement("img");
- image.src = imageURL;
- image.className = "webkit-html-message-icon";
- lineDiv.appendChild(image);
-
- lineDiv.appendChild(doc.createTextNode(msg.message));
- }
-}
-
-WebInspector.SourcePanel.prototype.__proto__ = WebInspector.ResourcePanel.prototype;
diff --git a/WebCore/page/inspector/StylesSidebarPane.js b/WebCore/page/inspector/StylesSidebarPane.js
deleted file mode 100644
index 915fc1a..0000000
--- a/WebCore/page/inspector/StylesSidebarPane.js
+++ /dev/null
@@ -1,682 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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.
- */
-
-WebInspector.StylesSidebarPane = function()
-{
- WebInspector.SidebarPane.call(this, WebInspector.UIString("Styles"));
-}
-
-WebInspector.StylesSidebarPane.prototype = {
- update: function(node, editedSection)
- {
- var refresh = false;
-
- if (!node || node === this.node)
- refresh = true;
-
- if (node && node.nodeType === Node.TEXT_NODE && node.parentNode)
- node = node.parentNode;
-
- if (node && node.nodeType !== Node.ELEMENT_NODE)
- node = null;
-
- if (node)
- this.node = node;
- else
- node = this.node;
-
- var body = this.bodyElement;
- if (!refresh || !node) {
- body.removeChildren();
- this.sections = [];
- }
-
- if (!node)
- return;
-
- var styleRules = [];
-
- if (refresh) {
- for (var i = 0; i < this.sections.length; ++i) {
- var section = this.sections[i];
- if (section.computedStyle)
- section.styleRule.style = node.ownerDocument.defaultView.getComputedStyle(node);
- var styleRule = { section: section, style: section.styleRule.style, computedStyle: section.computedStyle };
- styleRules.push(styleRule);
- }
- } else {
- var computedStyle = node.ownerDocument.defaultView.getComputedStyle(node);
- styleRules.push({ computedStyle: true, selectorText: WebInspector.UIString("Computed Style"), style: computedStyle, editable: false });
-
- var nodeName = node.nodeName.toLowerCase();
- for (var i = 0; i < node.attributes.length; ++i) {
- var attr = node.attributes[i];
- if (attr.style) {
- var attrStyle = { style: attr.style, editable: false };
- attrStyle.subtitle = WebInspector.UIString("element’s “%s” attribute", attr.name);
- attrStyle.selectorText = nodeName + "[" + attr.name;
- if (attr.value.length)
- attrStyle.selectorText += "=" + attr.value;
- attrStyle.selectorText += "]";
- styleRules.push(attrStyle);
- }
- }
-
- if (node.style && node.style.length) {
- var inlineStyle = { selectorText: WebInspector.UIString("Inline Style Attribute"), style: node.style };
- inlineStyle.subtitle = WebInspector.UIString("element’s “%s” attribute", "style");
- styleRules.push(inlineStyle);
- }
-
- var matchedStyleRules = node.ownerDocument.defaultView.getMatchedCSSRules(node, "", !Preferences.showUserAgentStyles);
- if (matchedStyleRules) {
- // Add rules in reverse order to match the cascade order.
- for (var i = (matchedStyleRules.length - 1); i >= 0; --i)
- styleRules.push(matchedStyleRules[i]);
- }
- }
-
- var usedProperties = {};
- var priorityUsed = false;
-
- // Walk the style rules and make a list of all used and overloaded properties.
- for (var i = 0; i < styleRules.length; ++i) {
- var styleRule = styleRules[i];
- if (styleRule.computedStyle)
- continue;
-
- styleRule.usedProperties = {};
-
- var style = styleRule.style;
- for (var j = 0; j < style.length; ++j) {
- var name = style[j];
-
- if (!priorityUsed && style.getPropertyPriority(name).length)
- priorityUsed = true;
-
- // If the property name is already used by another rule then this rule's
- // property is overloaded, so don't add it to the rule's usedProperties.
- if (!(name in usedProperties))
- styleRule.usedProperties[name] = true;
-
- if (name === "font") {
- // The font property is not reported as a shorthand. Report finding the individual
- // properties so they are visible in computed style.
- // FIXME: remove this when http://bugs.webkit.org/show_bug.cgi?id=15598 is fixed.
- styleRule.usedProperties["font-family"] = true;
- styleRule.usedProperties["font-size"] = true;
- styleRule.usedProperties["font-style"] = true;
- styleRule.usedProperties["font-variant"] = true;
- styleRule.usedProperties["font-weight"] = true;
- styleRule.usedProperties["line-height"] = true;
- }
- }
-
- // Add all the properties found in this style to the used properties list.
- // Do this here so only future rules are affect by properties used in this rule.
- for (var name in styleRules[i].usedProperties)
- usedProperties[name] = true;
- }
-
- if (priorityUsed) {
- // Walk the properties again and account for !important.
- var foundPriorityProperties = [];
-
- // Walk in reverse to match the order !important overrides.
- for (var i = (styleRules.length - 1); i >= 0; --i) {
- if (styleRules[i].computedStyle)
- continue;
-
- var style = styleRules[i].style;
- var uniqueProperties = style.getUniqueProperties();
- for (var j = 0; j < uniqueProperties.length; ++j) {
- var name = uniqueProperties[j];
- if (style.getPropertyPriority(name).length) {
- if (!(name in foundPriorityProperties))
- styleRules[i].usedProperties[name] = true;
- else
- delete styleRules[i].usedProperties[name];
- foundPriorityProperties[name] = true;
- } else if (name in foundPriorityProperties)
- delete styleRules[i].usedProperties[name];
- }
- }
- }
-
- if (refresh) {
- // Walk the style rules and update the sections with new overloaded and used properties.
- for (var i = 0; i < styleRules.length; ++i) {
- var styleRule = styleRules[i];
- var section = styleRule.section;
- section._usedProperties = (styleRule.usedProperties || usedProperties);
- section.update((section === editedSection) || styleRule.computedStyle);
- }
- } else {
- // Make a property section for each style rule.
- for (var i = 0; i < styleRules.length; ++i) {
- var styleRule = styleRules[i];
- var subtitle = styleRule.subtitle;
- delete styleRule.subtitle;
-
- var computedStyle = styleRule.computedStyle;
- delete styleRule.computedStyle;
-
- var ruleUsedProperties = styleRule.usedProperties;
- delete styleRule.usedProperties;
-
- var editable = styleRule.editable;
- delete styleRule.editable;
-
- // Default editable to true if it was omitted.
- if (typeof editable === "undefined")
- editable = true;
-
- var section = new WebInspector.StylePropertiesSection(styleRule, subtitle, computedStyle, (ruleUsedProperties || usedProperties), editable);
- section.expanded = true;
- section.pane = this;
-
- body.appendChild(section.element);
- this.sections.push(section);
- }
- }
- }
-}
-
-WebInspector.StylesSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;
-
-WebInspector.StylePropertiesSection = function(styleRule, subtitle, computedStyle, usedProperties, editable)
-{
- WebInspector.PropertiesSection.call(this, styleRule.selectorText);
-
- this.styleRule = styleRule;
- this.computedStyle = computedStyle;
- this.editable = (editable && !computedStyle);
-
- // Prevent editing the user agent rules.
- if (this.styleRule.parentStyleSheet && !this.styleRule.parentStyleSheet.ownerNode)
- this.editable = false;
-
- this._usedProperties = usedProperties;
-
- if (computedStyle) {
- if (Preferences.showInheritedComputedStyleProperties)
- this.element.addStyleClass("show-inherited");
-
- var showInheritedLabel = document.createElement("label");
- var showInheritedInput = document.createElement("input");
- showInheritedInput.type = "checkbox";
- showInheritedInput.checked = Preferences.showInheritedComputedStyleProperties;
-
- var computedStyleSection = this;
- var showInheritedToggleFunction = function(event) {
- Preferences.showInheritedComputedStyleProperties = showInheritedInput.checked;
- if (Preferences.showInheritedComputedStyleProperties)
- computedStyleSection.element.addStyleClass("show-inherited");
- else
- computedStyleSection.element.removeStyleClass("show-inherited");
- event.stopPropagation();
- };
-
- showInheritedLabel.addEventListener("click", showInheritedToggleFunction, false);
-
- showInheritedLabel.appendChild(showInheritedInput);
- showInheritedLabel.appendChild(document.createTextNode(WebInspector.UIString("Show inherited properties")));
- this.subtitleElement.appendChild(showInheritedLabel);
- } else {
- if (!subtitle) {
- if (this.styleRule.parentStyleSheet && this.styleRule.parentStyleSheet.href) {
- var url = this.styleRule.parentStyleSheet.href;
- subtitle = WebInspector.linkifyURL(url, url.trimURL(WebInspector.mainResource.domain).escapeHTML());
- this.subtitleElement.addStyleClass("file");
- } else if (this.styleRule.parentStyleSheet && !this.styleRule.parentStyleSheet.ownerNode)
- subtitle = WebInspector.UIString("user agent stylesheet");
- else
- subtitle = WebInspector.UIString("inline stylesheet");
- }
-
- this.subtitle = subtitle;
- }
-}
-
-WebInspector.StylePropertiesSection.prototype = {
- get usedProperties()
- {
- return this._usedProperties || {};
- },
-
- set usedProperties(x)
- {
- this._usedProperties = x;
- this.update();
- },
-
- isPropertyInherited: function(property)
- {
- if (!this.computedStyle || !this._usedProperties)
- return false;
- // These properties should always show for Computed Style.
- var alwaysShowComputedProperties = { "display": true, "height": true, "width": true };
- return !(property in this.usedProperties) && !(property in alwaysShowComputedProperties);
- },
-
- isPropertyOverloaded: function(property, shorthand)
- {
- if (this.computedStyle || !this._usedProperties)
- return false;
-
- var used = (property in this.usedProperties);
- if (used || !shorthand)
- return !used;
-
- // Find out if any of the individual longhand properties of the shorthand
- // are used, if none are then the shorthand is overloaded too.
- var longhandProperties = this.styleRule.style.getLonghandProperties(property);
- for (var j = 0; j < longhandProperties.length; ++j) {
- var individualProperty = longhandProperties[j];
- if (individualProperty in this.usedProperties)
- return false;
- }
-
- return true;
- },
-
- update: function(full)
- {
- if (full || this.computedStyle) {
- this.propertiesTreeOutline.removeChildren();
- this.populated = false;
- } else {
- var child = this.propertiesTreeOutline.children[0];
- while (child) {
- child.overloaded = this.isPropertyOverloaded(child.name, child.shorthand);
- child = child.traverseNextTreeElement(false, null, true);
- }
- }
- },
-
- onpopulate: function()
- {
- var style = this.styleRule.style;
- if (!style.length)
- return;
-
- var foundShorthands = {};
- var uniqueProperties = style.getUniqueProperties();
- uniqueProperties.sort();
-
- for (var i = 0; i < uniqueProperties.length; ++i) {
- var name = uniqueProperties[i];
- var shorthand = style.getPropertyShorthand(name);
-
- if (shorthand && shorthand in foundShorthands)
- continue;
-
- if (shorthand) {
- foundShorthands[shorthand] = true;
- name = shorthand;
- }
-
- var isShorthand = (shorthand ? true : false);
- var inherited = this.isPropertyInherited(name);
- var overloaded = this.isPropertyOverloaded(name, isShorthand);
-
- var item = new WebInspector.StylePropertyTreeElement(style, name, isShorthand, inherited, overloaded);
- this.propertiesTreeOutline.appendChild(item);
- }
- }
-}
-
-WebInspector.StylePropertiesSection.prototype.__proto__ = WebInspector.PropertiesSection.prototype;
-
-WebInspector.StylePropertyTreeElement = function(style, name, shorthand, inherited, overloaded)
-{
- this.style = style;
- this.name = name;
- this.shorthand = shorthand;
- this._inherited = inherited;
- this._overloaded = overloaded;
-
- // Pass an empty title, the title gets made later in onattach.
- TreeElement.call(this, "", null, shorthand);
-}
-
-WebInspector.StylePropertyTreeElement.prototype = {
- get inherited()
- {
- return this._inherited;
- },
-
- set inherited(x)
- {
- if (x === this._inherited)
- return;
- this._inherited = x;
- this.updateState();
- },
-
- get overloaded()
- {
- return this._overloaded;
- },
-
- set overloaded(x)
- {
- if (x === this._overloaded)
- return;
- this._overloaded = x;
- this.updateState();
- },
-
- onattach: function()
- {
- this.updateTitle();
- },
-
- updateTitle: function()
- {
- // "Nicknames" for some common values that are easier to read.
- var valueNicknames = {
- "rgb(0, 0, 0)": "black",
- "#000": "black",
- "#000000": "black",
- "rgb(255, 255, 255)": "white",
- "#fff": "white",
- "#ffffff": "white",
- "#FFF": "white",
- "#FFFFFF": "white",
- "rgba(0, 0, 0, 0)": "transparent",
- "rgb(255, 0, 0)": "red",
- "rgb(0, 255, 0)": "lime",
- "rgb(0, 0, 255)": "blue",
- "rgb(255, 255, 0)": "yellow",
- "rgb(255, 0, 255)": "magenta",
- "rgb(0, 255, 255)": "cyan"
- };
-
- var priority = (this.shorthand ? this.style.getShorthandPriority(this.name) : this.style.getPropertyPriority(this.name));
- var value = (this.shorthand ? this.style.getShorthandValue(this.name) : this.style.getPropertyValue(this.name));
- var htmlValue = value;
-
- if (priority && !priority.length)
- delete priority;
- if (priority)
- priority = "!" + priority;
-
- if (value) {
- var urls = value.match(/url\([^)]+\)/);
- if (urls) {
- for (var i = 0; i < urls.length; ++i) {
- var url = urls[i].substring(4, urls[i].length - 1);
- htmlValue = htmlValue.replace(urls[i], "url(" + WebInspector.linkifyURL(url) + ")");
- }
- } else {
- if (value in valueNicknames)
- htmlValue = valueNicknames[value];
- htmlValue = htmlValue.escapeHTML();
- }
- } else
- htmlValue = value = "";
-
- this.updateState();
-
- var nameElement = document.createElement("span");
- nameElement.className = "name";
- nameElement.textContent = this.name;
-
- var valueElement = document.createElement("span");
- valueElement.className = "value";
- valueElement.innerHTML = htmlValue;
-
- if (priority) {
- var priorityElement = document.createElement("span");
- priorityElement.className = "priority";
- priorityElement.textContent = priority;
- }
-
- this.listItemElement.removeChildren();
-
- this.listItemElement.appendChild(nameElement);
- this.listItemElement.appendChild(document.createTextNode(": "));
- this.listItemElement.appendChild(valueElement);
-
- if (priorityElement) {
- this.listItemElement.appendChild(document.createTextNode(" "));
- this.listItemElement.appendChild(priorityElement);
- }
-
- this.listItemElement.appendChild(document.createTextNode(";"));
-
- if (value) {
- // FIXME: this dosen't catch keyword based colors like black and white
- var colors = value.match(/((rgb|hsl)a?\([^)]+\))|(#[0-9a-fA-F]{6})|(#[0-9a-fA-F]{3})/g);
- if (colors) {
- var colorsLength = colors.length;
- for (var i = 0; i < colorsLength; ++i) {
- var swatchElement = document.createElement("span");
- swatchElement.className = "swatch";
- swatchElement.style.setProperty("background-color", colors[i]);
- this.listItemElement.appendChild(swatchElement);
- }
- }
- }
-
- this.tooltip = this.name + ": " + (valueNicknames[value] || value) + (priority ? " " + priority : "");
- },
-
- updateState: function()
- {
- if (!this.listItemElement)
- return;
-
- var value = (this.shorthand ? this.style.getShorthandValue(this.name) : this.style.getPropertyValue(this.name));
- if (this.style.isPropertyImplicit(this.name) || value === "initial")
- this.listItemElement.addStyleClass("implicit");
- else
- this.listItemElement.removeStyleClass("implicit");
-
- if (this.inherited)
- this.listItemElement.addStyleClass("inherited");
- else
- this.listItemElement.removeStyleClass("inherited");
-
- if (this.overloaded)
- this.listItemElement.addStyleClass("overloaded");
- else
- this.listItemElement.removeStyleClass("overloaded");
- },
-
- onpopulate: function()
- {
- // Only populate once and if this property is a shorthand.
- if (this.children.length || !this.shorthand)
- return;
-
- var longhandProperties = this.style.getLonghandProperties(this.name);
- for (var i = 0; i < longhandProperties.length; ++i) {
- var name = longhandProperties[i];
-
- if (this.treeOutline.section) {
- var inherited = this.treeOutline.section.isPropertyInherited(name);
- var overloaded = this.treeOutline.section.isPropertyOverloaded(name);
- }
-
- var item = new WebInspector.StylePropertyTreeElement(this.style, name, false, inherited, overloaded);
- this.appendChild(item);
- }
- },
-
- ondblclick: function(element, event)
- {
- this.startEditing(event.target);
- },
-
- startEditing: function(selectElement)
- {
- // FIXME: we don't allow editing of longhand properties under a shorthand right now.
- if (this.parent.shorthand)
- return;
-
- if (this.editing || (this.treeOutline.section && !this.treeOutline.section.editable))
- return;
-
- this.editing = true;
- this.previousTextContent = this.listItemElement.textContent;
-
- this.listItemElement.addStyleClass("focusable");
- this.listItemElement.addStyleClass("editing");
- this.wasExpanded = this.expanded;
- this.collapse();
- // Lie about out children to prevent toggling on click.
- this.hasChildren = false;
-
- if (!selectElement)
- selectElement = this.listItemElement;
-
- window.getSelection().setBaseAndExtent(selectElement, 0, selectElement, 1);
-
- var treeElement = this;
- this.listItemElement.blurred = function() { treeElement.commitEditing() };
- this.listItemElement.handleKeyEvent = function(event) {
- if (event.keyIdentifier === "Enter") {
- treeElement.commitEditing();
- event.preventDefault();
- } else if (event.keyCode === 27) { // Escape key
- treeElement.cancelEditing();
- event.preventDefault();
- }
- };
-
- this.previousFocusElement = WebInspector.currentFocusElement;
- WebInspector.currentFocusElement = this.listItemElement;
- },
-
- endEditing: function()
- {
- // Revert the changes done in startEditing().
- delete this.listItemElement.blurred;
- delete this.listItemElement.handleKeyEvent;
-
- WebInspector.currentFocusElement = this.previousFocusElement;
- delete this.previousFocusElement;
-
- delete this.previousTextContent;
- delete this.editing;
-
- this.listItemElement.removeStyleClass("focusable");
- this.listItemElement.removeStyleClass("editing");
- this.hasChildren = (this.children.length ? true : false);
- if (this.wasExpanded) {
- delete this.wasExpanded;
- this.expand();
- }
- },
-
- cancelEditing: function()
- {
- this.endEditing();
- this.updateTitle();
- },
-
- commitEditing: function()
- {
- var previousContent = this.previousTextContent;
-
- this.endEditing();
-
- var userInput = this.listItemElement.textContent;
- if (userInput === previousContent)
- return; // nothing changed, so do nothing else
-
- var userInputLength = userInput.trimWhitespace().length;
-
- // Create a new element to parse the user input CSS.
- var parseElement = document.createElement("span");
- parseElement.setAttribute("style", userInput);
-
- var userInputStyle = parseElement.style;
- if (userInputStyle.length || !userInputLength) {
- // The input was parsable or the user deleted everything, so remove the
- // original property from the real style declaration. If this represents
- // a shorthand remove all the longhand properties.
- if (this.shorthand) {
- var longhandProperties = this.style.getLonghandProperties(this.name);
- for (var i = 0; i < longhandProperties.length; ++i)
- this.style.removeProperty(longhandProperties[i]);
- } else
- this.style.removeProperty(this.name);
- }
-
- if (!userInputLength) {
- // The user deleted the everything, so remove the tree element and update.
- if (this.treeOutline.section && this.treeOutline.section.pane)
- this.treeOutline.section.pane.update();
- this.parent.removeChild(this);
- return;
- }
-
- if (!userInputStyle.length) {
- // The user typed something, but it didn't parse. Just abort and restore
- // the original title for this property.
- this.updateTitle();
- return;
- }
-
- // Iterate of the properties on the test element's style declaration and
- // add them to the real style declaration. We take care to move shorthands.
- var foundShorthands = {};
- var uniqueProperties = userInputStyle.getUniqueProperties();
- for (var i = 0; i < uniqueProperties.length; ++i) {
- var name = uniqueProperties[i];
- var shorthand = userInputStyle.getPropertyShorthand(name);
-
- if (shorthand && shorthand in foundShorthands)
- continue;
-
- if (shorthand) {
- var value = userInputStyle.getShorthandValue(shorthand);
- var priority = userInputStyle.getShorthandPriority(shorthand);
- foundShorthands[shorthand] = true;
- } else {
- var value = userInputStyle.getPropertyValue(name);
- var priority = userInputStyle.getPropertyPriority(name);
- }
-
- // Set the property on the real style declaration.
- this.style.setProperty((shorthand || name), value, priority);
- }
-
- if (this.treeOutline.section && this.treeOutline.section.pane)
- this.treeOutline.section.pane.update(null, this.treeOutline.section);
- else if (this.treeOutline.section)
- this.treeOutline.section.update(true);
- else
- this.updateTitle(); // FIXME: this will not show new properties. But we don't hit his case yet.
- }
-}
-
-WebInspector.StylePropertyTreeElement.prototype.__proto__ = TreeElement.prototype;
diff --git a/WebCore/page/inspector/WebKit.qrc b/WebCore/page/inspector/WebKit.qrc
deleted file mode 100644
index 0a5e164..0000000
--- a/WebCore/page/inspector/WebKit.qrc
+++ /dev/null
@@ -1,137 +0,0 @@
-<!DOCTYPE RCC><RCC version="1.0">
-<qresource prefix="/webkit/inspector">
- <file>ConsolePanel.js</file>
- <file>NetworkPanel.js</file>
- <file>Resource.js</file>
- <file>ResourceCategory.js</file>
- <file>ResourcePanel.js</file>
- <file>inspector.css</file>
- <file>inspector.html</file>
- <file>inspector.js</file>
- <file>treeoutline.js</file>
- <file>utilities.js</file>
- <file>Images/alternateTableRows.png</file>
- <file>Images/attachedShadow.png</file>
- <file>Images/backNormal.png</file>
- <file>Images/bottomShadow.png</file>
- <file>Images/breadcrumbBackground.png</file>
- <file>Images/checker.png</file>
- <file>Images/console.png</file>
- <file>Images/darkShadow.png</file>
- <file>Images/database.png</file>
- <file>Images/databaseBrowserViewNormal.png</file>
- <file>Images/databaseBrowserViewNormalSelected.png</file>
- <file>Images/databaseBrowserViewSmall.png</file>
- <file>Images/databaseBrowserViewSmallSelected.png</file>
- <file>Images/databaseQueryViewNormal.png</file>
- <file>Images/databaseQueryViewNormalSelected.png</file>
- <file>Images/databaseQueryViewSmall.png</file>
- <file>Images/databaseQueryViewSmallSelected.png</file>
- <file>Images/disclosureDownPressed.png</file>
- <file>Images/disclosureRightDown.png</file>
- <file>Images/disclosureRightPressed.png</file>
- <file>Images/document.png</file>
- <file>Images/domViewNormal.png</file>
- <file>Images/domViewNormalSelected.png</file>
- <file>Images/domViewSmall.png</file>
- <file>Images/domViewSmallSelected.png</file>
- <file>Images/downTriangle.png</file>
- <file>Images/errorIcon.png</file>
- <file>Images/errorMediumIcon.png</file>
- <file>Images/folder.png</file>
- <file>Images/forwardNormal.png</file>
- <file>Images/glossyHeader.png</file>
- <file>Images/glossyHeaderPressed.png</file>
- <file>Images/goArrow.png</file>
- <file>Images/gradient.png</file>
- <file>Images/gradientHighlight.png</file>
- <file>Images/gradientHighlightBottom.png</file>
- <file>Images/hideStatusWidget.png</file>
- <file>Images/hideStatusWidgetPressed.png</file>
- <file>Images/network.png</file>
- <file>Images/paneBottomGrow.png</file>
- <file>Images/paneBottomGrowActive.png</file>
- <file>Images/paneGrowHandleLine.png</file>
- <file>Images/paneHeader.png</file>
- <file>Images/paneHeaderActive.png</file>
- <file>Images/plainDocument.png</file>
- <file>Images/popupArrows.png</file>
- <file>Images/popupArrowsBlack.png</file>
- <file>Images/reload.png</file>
- <file>Images/rightTriangle.png</file>
- <file>Images/segment.png</file>
- <file>Images/segmentEnd.png</file>
- <file>Images/segmentHover.png</file>
- <file>Images/segmentHoverEnd.png</file>
- <file>Images/segmentSelected.png</file>
- <file>Images/segmentSelectedEnd.png</file>
- <file>Images/showStatusWidget.png</file>
- <file>Images/showStatusWidgetPressed.png</file>
- <file>Images/sidbarItemBackground.png</file>
- <file>Images/sidebarActionWidget.png</file>
- <file>Images/sidebarActionWidgetPressed.png</file>
- <file>Images/sidebarAttachWidget.png</file>
- <file>Images/sidebarAttachWidgetPressed.png</file>
- <file>Images/sidebarDetachWidget.png</file>
- <file>Images/sidebarDetachWidgetPressed.png</file>
- <file>Images/sidebarResizeWidget.png</file>
- <file>Images/sidebarSelection.png</file>
- <file>Images/sidebarSelectionBlurred.png</file>
- <file>Images/sidebarSelectionBlurredTall.png</file>
- <file>Images/sidebarSelectionGray.png</file>
- <file>Images/sidebarSelectionGrayTall.png</file>
- <file>Images/sidebarSelectionTall.png</file>
- <file>Images/sidebarStatusAreaBackground.png</file>
- <file>Images/sourceViewNormal.png</file>
- <file>Images/sourceViewNormalSelected.png</file>
- <file>Images/sourceViewSmall.png</file>
- <file>Images/sourceViewSmallSelected.png</file>
- <file>Images/splitviewDimple.png</file>
- <file>Images/splitviewDividerBackground.png</file>
- <file>Images/tab.png</file>
- <file>Images/tabSelected.png</file>
- <file>Images/timelinePillBlue.png</file>
- <file>Images/timelinePillGray.png</file>
- <file>Images/timelinePillGreen.png</file>
- <file>Images/timelinePillOrange.png</file>
- <file>Images/timelinePillPurple.png</file>
- <file>Images/timelinePillRed.png</file>
- <file>Images/timelinePillYellow.png</file>
- <file>Images/tipBalloon.png</file>
- <file>Images/tipBalloonBottom.png</file>
- <file>Images/tipIcon.png</file>
- <file>Images/tipIconPressed.png</file>
- <file>Images/toggleDown.png</file>
- <file>Images/toggleUp.png</file>
- <file>Images/toolbarBackground.png</file>
- <file>Images/toolbarBackgroundInactive.png</file>
- <file>Images/toolbarButtonNormal.png</file>
- <file>Images/toolbarButtonNormalInactive.png</file>
- <file>Images/toolbarButtonNormalPressed.png</file>
- <file>Images/toolbarButtonNormalSelected.png</file>
- <file>Images/toolbarButtonNormalSelectedInactive.png</file>
- <file>Images/toolbarButtonSmall.png</file>
- <file>Images/toolbarButtonSmallInactive.png</file>
- <file>Images/toolbarButtonSmallPressed.png</file>
- <file>Images/toolbarButtonSmallSelected.png</file>
- <file>Images/toolbarButtonSmallSelectedInactive.png</file>
- <file>Images/toolbarPopupButtonNormal.png</file>
- <file>Images/toolbarPopupButtonNormalInactive.png</file>
- <file>Images/toolbarPopupButtonNormalPressed.png</file>
- <file>Images/toolbarPopupButtonSmall.png</file>
- <file>Images/toolbarPopupButtonSmallInactive.png</file>
- <file>Images/toolbarPopupButtonSmallPressed.png</file>
- <file>Images/toolbarSplitButtonDividerNormal.png</file>
- <file>Images/toolbarSplitButtonDividerNormalInactive.png</file>
- <file>Images/toolbarSplitButtonDividerSmall.png</file>
- <file>Images/toolbarSplitButtonDividerSmallInactive.png</file>
- <file>Images/treeDownTriangleBlack.png</file>
- <file>Images/treeDownTriangleWhite.png</file>
- <file>Images/treeLeftTriangleBlack.png</file>
- <file>Images/treeRightTriangleBlack.png</file>
- <file>Images/treeRightTriangleWhite.png</file>
- <file>Images/warningIcon.png</file>
- <file>Images/warningMediumIcon.png</file>
- <file>Images/warningsErrors.png</file>
-</qresource>
-</RCC>
diff --git a/WebCore/page/inspector/inspector.css b/WebCore/page/inspector/inspector.css
deleted file mode 100644
index 2ba3208..0000000
--- a/WebCore/page/inspector/inspector.css
+++ /dev/null
@@ -1,2169 +0,0 @@
-/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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.
- */
-
-body {
- -webkit-user-select: none;
- cursor: default;
- height: 100%;
- width: 100%;
- overflow: hidden;
- font-family: Lucida Grande, sans-serif;
- margin: 0;
- -webkit-text-size-adjust: none;
-}
-
-iframe, a img {
- border: none;
-}
-
-img {
- -webkit-user-drag: none;
-}
-
-.focused .selected {
- background-color: rgb(56, 121, 217);
-}
-
-.blurred .selected, body.inactive .selected {
- background-color: rgb(212, 212, 212);
-}
-
-.hidden {
- display: none;
-}
-
-#toolbar {
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- height: 32px;
- background-color: rgb(245, 245, 250);
- background-image: url(Images/toolbarBackground.png);
- background-repeat: repeat-x;
- background-position: top;
- border-bottom: 1px solid rgb(80, 80, 80);
- padding: 2px 8px;
- -webkit-box-sizing: border-box;
- -webkit-background-size: auto 135%;
-}
-
-body.detached.platform-mac-leopard #toolbar {
- background: transparent !important;
-}
-
-body.inactive #toolbar {
- background-image: url(Images/toolbarBackgroundInactive.png);
- border-bottom: 1px solid rgb(64%, 64%, 64%);
-}
-
-body.attached #toolbar {
- height: 28px;
- border-top: 1px solid rgb(80, 80, 80);
- background-image: url(Images/darkShadow.png), url(Images/toolbarBackground.png);
- background-position: center -2px, top;
- -webkit-background-size: auto auto, auto 135%;
-}
-
-body.attached.inactive #toolbar {
- background-image: url(Images/darkShadow.png), url(Images/toolbarBackgroundInactive.png);
- background-position: center -3px, top;
- border-top: 1px solid rgb(100, 100, 100);
- border-bottom: 1px solid rgb(64%, 64%, 64%);
-}
-
-#toolbar button, #toolbar button:disabled:active {
- border-width: 3px 3px 4px 3px;
- border-style: none;
- border-color: transparent;
- background-color: transparent;
- -webkit-border-image: url(Images/toolbarButtonNormal.png) 3 3 4 3;
- height: 23px;
- -webkit-box-sizing: border-box;
- vertical-align: middle;
- line-height: 10px;
-}
-
-#toolbar button:focus {
- outline: none;
-}
-
-#toolbar button:active {
- -webkit-border-image: url(Images/toolbarButtonNormalPressed.png) 3 3 4 3;
-}
-
-#toolbar button.selected {
- -webkit-border-image: url(Images/toolbarButtonNormalSelected.png) 3 3 4 3;
-}
-
-body.inactive #toolbar button:active {
- -webkit-border-image: url(Images/toolbarButtonNormalPressedInactive.png) 3 3 4 3;
-}
-
-body.inactive #toolbar button.selected {
- -webkit-border-image: url(Images/toolbarButtonNormalSelectedInactive.png) 3 3 4 3;
-}
-
-body.inactive #toolbar button, body.inactive #toolbar button:disabled:active {
- -webkit-border-image: url(Images/toolbarButtonNormalInactive.png) 3 3 4 3;
-}
-
-body.attached #toolbar button {
- height: 19px;
- line-height: 7px;
- -webkit-border-image: url(Images/toolbarButtonSmall.png) 3 3 4 3;
-}
-
-body.attached #toolbar button:active {
- -webkit-border-image: url(Images/toolbarButtonSmallPressed.png) 3 3 4 3;
-}
-
-body.attached #toolbar button.selected {
- -webkit-border-image: url(Images/toolbarButtonSmallSelected.png) 3 3 4 3;
-}
-
-body.attached.inactive #toolbar button:active {
- -webkit-border-image: url(Images/toolbarButtonSmallPressedInactive.png) 3 3 4 3;
-}
-
-body.attached.inactive #toolbar button.selected {
- -webkit-border-image: url(Images/toolbarButtonSmallSelectedInactive.png) 3 3 4 3;
-}
-
-body.attached.inactive #toolbar button, body.inactive #toolbar button:disabled:active {
- -webkit-border-image: url(Images/toolbarButtonSmallInactive.png) 3 3 4 3;
-}
-
-#toolbar select, #toolbar select:disabled:active {
- background-color: transparent;
- border-width: 3px 10px 4px 3px;
- border-color: transparent;
- -webkit-border-image: url(Images/toolbarPopupButtonNormal.png) 3 10 4 3;
- height: 23px;
- font-size: 10px;
- padding-left: 8px;
- padding-right: 6px;
- -webkit-box-sizing: border-box;
- -webkit-border-radius: 0;
- -webkit-appearance: none;
- vertical-align: middle;
-}
-
-#toolbar select:focus {
- outline: none;
-}
-
-#toolbar select:active {
- -webkit-border-image: url(Images/toolbarPopupButtonNormalPressed.png) 3 10 4 3;
-}
-
-body.inactive #toolbar select:active {
- -webkit-border-image: url(Images/toolbarPopupButtonNormalPressedInactive.png) 3 10 4 3;
-}
-
-body.inactive #toolbar select, body.inactive #toolbar select:disabled:active {
- -webkit-border-image: url(Images/toolbarPopupButtonNormalInactive.png) 3 10 4 3;
-}
-
-body.attached #toolbar select, #toolbar select:disabled:active {
- -webkit-border-image: url(Images/toolbarPopupButtonSmall.png) 3 10 4 3;
- height: 19px;
-}
-
-body.attached #toolbar select:active {
- -webkit-border-image: url(Images/toolbarPopupButtonSmallPressed.png) 3 10 4 3;
-}
-
-body.attached.inactive #toolbar select:active {
- -webkit-border-image: url(Images/toolbarPopupButtonSmallPressedInactive.png) 3 10 4 3;
-}
-
-body.attached.inactive #toolbar select, body.inactive #toolbar select:disabled:active {
- -webkit-border-image: url(Images/toolbarPopupButtonSmallInactive.png) 3 10 4 3;
-}
-
-#toolbar .split-button-divider {
- width: 1px;
- height: 23px;
- content: url(Images/toolbarSplitButtonDividerNormal.png);
- vertical-align: middle;
-}
-
-body.inactive #toolbar .split-button-divider {
- content: url(Images/toolbarSplitButtonDividerNormalInactive.png);
-}
-
-body.attached #toolbar .split-button-divider {
- height: 19px;
- content: url(Images/toolbarSplitButtonDividerSmall.png);
-}
-
-body.attached.inactive #toolbar .split-button-divider {
- content: url(Images/toolbarSplitButtonDividerSmallInactive.png);
-}
-
-#toolbar .split-button {
- padding: 0;
- width: 26px;
-}
-
-body.attached #toolbar .split-button {
- width: 20px;
-}
-
-#toolbar .split-button.middle {
- border-left: transparent none 0 !important;
- border-right: transparent none 0 !important;
-}
-
-#toolbar .split-button.first {
- border-right: transparent none 0 !important;
-}
-
-#toolbar .split-button.last {
- border-left: transparent none 0 !important;
-}
-
-#back img {
- content: url(Images/backNormal.png);
- vertical-align: middle;
- margin-top: -1px;
- width: 8px;
- height: 10px;
-}
-
-body.attached #back img {
- content: url(Images/treeLeftTriangleBlack.png);
- margin-top: -1px;
- margin-left: -1px;
- width: 8px;
- height: 8px;
-}
-
-#back:disabled img, #forward:disabled img {
- opacity: 0.45;
-}
-
-#forward img {
- content: url(Images/forwardNormal.png);
- vertical-align: middle;
- margin-top: -1px;
- margin-left: 1px;
- width: 8px;
- height: 10px;
-}
-
-body.attached #forward img {
- content: url(Images/treeRightTriangleBlack.png);
- margin-top: -1px;
- width: 8px;
- height: 8px;
-}
-
-.view-button-source img {
- content: url(Images/sourceViewNormal.png);
- vertical-align: middle;
- margin-top: 1px;
- margin-left: -1px;
- width: 11px;
- height: 11px;
-}
-
-.view-button-source.selected img {
- content: url(Images/sourceViewNormalSelected.png);
-}
-
-body.attached .view-button-source img {
- content: url(Images/sourceViewSmall.png);
- width: 8px;
- height: 8px;
-}
-
-body.attached .view-button-source.selected img {
- content: url(Images/sourceViewSmallSelected.png);
-}
-
-.view-button-dom img {
- content: url(Images/domViewNormal.png);
- vertical-align: middle;
- margin-top: 1px;
- margin-left: 3px;
- width: 11px;
- height: 11px;
-}
-
-.view-button-dom.selected img {
- content: url(Images/domViewNormalSelected.png);
-}
-
-body.attached .view-button-dom img {
- content: url(Images/domViewSmall.png);
- width: 10px;
- height: 8px;
-}
-
-body.attached .view-button-dom.selected img {
- content: url(Images/domViewSmallSelected.png);
-}
-
-#toolbarButtons {
- position: absolute;
- left: 200px;
- padding-left: 8px;
-}
-
-#search {
- float: right;
- width: 210px;
- font-size: 16px;
-}
-
-body.attached #search {
- font-size: 12px;
-}
-
-#searchResults {
- position: absolute;
- top: -100px;
- left: 0;
- right: 0;
- height: 100px;
- z-index: -1;
- background-color: white;
- border-bottom: 1px solid rgb(180, 180, 180);
- overflow-y: auto;
- overflow-x: hidden;
- -webkit-box-sizing: border-box;
-}
-
-.search-results-section {
- color: gray;
- width: 28px;
- float: left;
- margin-left: -45px;
- text-align: right;
- font-size: 10px;
- margin-top: 1px;
- white-space: nowrap;
-}
-
-.selected .search-results-section {
- color: rgba(255, 255, 255, 0.8);
-}
-
-body.inactive .focused .selected .search-results-section {
- color: rgba(0, 0, 0, 0.5);
-}
-
-.blurred .selected .search-results-section {
- color: rgba(0, 0, 0, 0.5);
-}
-
-#searchResults > ol > ol > li {
- padding-left: 45px;
- white-space: nowrap;
-}
-
-.search-matched-string {
- background-color: #ff8;
-}
-
-.selected .search-matched-string {
- background-color: transparent;
-}
-
-#sidebar {
- position: absolute;
- top: 32px;
- left: 0;
- bottom: 0;
- width: 200px;
- background-color: rgb(214, 221, 229);
- border-right: 1px solid rgb(64%, 64%, 64%);
- -webkit-box-sizing: border-box;
-}
-
-body.inactive #sidebar {
- background-color: rgb(232, 232, 232);
-}
-
-body.attached #sidebar {
- top: 28px;
-}
-
-#statusbar {
- position: absolute;
- padding: 0;
- left: 0;
- right: 0;
- bottom: 0;
- height: 21px;
- border-top: 1px solid #bbb;
- -webkit-box-sizing: border-box;
- background-image: url(Images/sidebarStatusAreaBackground.png);
- background-position: right, center;
- background-repeat: no-repeat, repeat-x;
-}
-
-#statusbar #sidebarResizeWidget {
- display: block;
- float: right;
- width: 17px;
- height: 20px;
- background: url(Images/sidebarResizeWidget.png) right no-repeat;
- cursor: col-resize;
-}
-
-#statusbar button {
- -webkit-apearance: none;
- vertical-align: top;
- border: 0;
- width: 32px;
- height: 20px;
- margin: 0;
- margin-left: -1px;
- padding: 0;
-}
-
-#statusbar button:focus {
- outline: none;
-}
-
-#statusbar button.action {
- background-image: url(Images/sidebarActionWidget.png);
-}
-
-#statusbar button.action:active {
- background-image: url(Images/sidebarActionWidgetPressed.png);
-}
-
-body.detached #attachToggle {
- background-image: url(Images/sidebarAttachWidget.png);
-}
-
-body.detached #attachToggle:active {
- background-image: url(Images/sidebarAttachWidgetPressed.png);
-}
-
-body.attached #attachToggle {
- background-image: url(Images/sidebarDetachWidget.png);
-}
-
-body.attached #attachToggle:active {
- background-image: url(Images/sidebarDetachWidgetPressed.png);
-}
-
-#status {
- overflow: hidden;
- position: absolute;
- bottom: 21px;
- left: 0;
- width: 100%;
- height: 78px;
- padding: 2px 0;
- margin: 0;
- border-top: 1px solid rgb(64%, 64%, 64%);
- -webkit-box-sizing: border-box;
- list-style: none;
- font-size: 11px;
- -webkit-transition: bottom 250ms ease-in-out;
-}
-
-#status li {
- position: relative;
- height: 37px;
- -webkit-box-sizing: border-box;
-}
-
-#status li.selected {
- background-image: url(Images/sidebarSelectionTall.png);
- background-repeat: repeat-x;
- background-position: center;
- background-color: transparent !important;
- color: white;
- font-weight: bold;
- text-shadow: rgba(0, 0, 0, 0.4) 0 1px 0;
-}
-
-#status .icon {
- position: absolute;
- top: 2px;
- left: 15px;
- width: 32px;
- height: 32px;
- background-repeat: no-repeat;
- background-position: center center;
-}
-
-#status .icon.console {
- background-image: url(Images/console.png);
-}
-
-#status .icon.network {
- background-image: url(Images/network.png);
-}
-
-#status .title {
- -webkit-box-sizing: border-box;
- position: relative;
- top: 5px;
- padding-left: 58px;
- right: 5px;
- display: block;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-#status .title.only {
- top: 10px;
-}
-
-#status .info {
- -webkit-box-sizing: border-box;
- position: relative;
- margin-top: 6px;
- padding-left: 58px;
- right: 5px;
- display: block;
- font-size: 9px;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-#list {
- overflow-x: hidden;
- overflow-y: auto;
- position: absolute;
- top: 0;
- left: 0;
- bottom: 99px;
- width: 100%;
- padding: 2px 0;
- margin: 0;
- -webkit-box-sizing: border-box;
- list-style: none;
- font-size: 11px;
- -webkit-transition: bottom 250ms ease-in-out;
-}
-
-#list > li {
- height: 26px;
- color: rgb(96, 110, 128);
- text-shadow: rgba(255, 255, 255, 0.75) 0 1px 0;
- font-weight: bold;
- line-height: 20px;
- text-indent: 20px;
- background-image: url(Images/rightTriangle.png);
- background-repeat: no-repeat;
- background-position: 10px 6px;
- text-transform: uppercase;
-}
-
-#list > ol + li {
- margin-top: 5px;
-}
-
-#list > li + li {
- margin-top: 5px;
-}
-
-#list > li.expanded {
- background-image: url(Images/downTriangle.png);
- background-position: 10px 7px;
-}
-
-#list > ol {
- display: none;
- list-style: none;
- padding: 0;
- margin: 0;
-}
-
-#list > ol.expanded {
- display: block;
-}
-
-#list > ol > li {
- position: relative;
- height: 37px;
- -webkit-box-sizing: border-box;
-}
-
-#list > ol > li:-webkit-drag {
- background: transparent !important;
- color: black !important;
- font-weight: normal !important;
-}
-
-#sidebar li:-webkit-drag .count {
- display: none;
-}
-
-#list .icon {
- position: absolute;
- top: 2px;
- left: 15px;
- width: 32px;
- height: 32px;
- background-image: url(Images/document.png);
- background-repeat: no-repeat;
- background-position: center center;
-}
-
-#list .icon.database {
- background-image: url(Images/database.png);
-}
-
-#list .icon.plain {
- background-image: url(Images/plainDocument.png);
-}
-
-#list .icon.font {
- background-image: url(Images/plainDocument.png);
-}
-
-#list .icon.font .preview {
- overflow: hidden;
- text-align: center;
- font-size: 14px;
- line-height: 14px;
- font-weight: normal;
- color: black;
- text-shadow: none;
-}
-
-#list .icon .preview {
- margin: auto;
- display: block;
- position: absolute;
- top: 0;
- bottom: 0;
- left: 0;
- right: 0;
- max-width: 20px;
- max-height: 22px;
- -webkit-box-sizing: border-box;
- border-top: 6px solid transparent;
-}
-
-#list .icon .progress {
- margin: auto;
- display: block;
- position: absolute;
- top: 0;
- bottom: 0;
- left: 0;
- right: 0;
-}
-
-#list .title {
- -webkit-box-sizing: border-box;
- position: relative;
- top: 5px;
- padding-left: 58px;
- right: 5px;
- display: block;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-#list .title.only {
- top: 10px;
-}
-
-#sidebar li .count {
- float: right;
- margin-top: 11px;
- margin-right: 6px;
- font-family: Helvetica, sans-serif;
- font-weight: bold;
- font-size: 11px;
- line-height: 10px;
- -webkit-border-radius: 7px;
- color: white;
- text-shadow: none;
- background-image: url(Images/gradientHighlight.png), url(Images/gradient.png);
- -webkit-background-size: auto 100%, auto 100%;
- background-position: center;
- padding: 2px 4px;
- text-align: center;
- text-indent: 0;
- min-width: 20px;
- -webkit-box-sizing: border-box;
-}
-
-#sidebar li .count.warnings {
- background-color: orange;
-}
-
-#sidebar li .count.errors {
- background-color: red;
-}
-
-#list .info {
- -webkit-box-sizing: border-box;
- position: relative;
- margin-top: 6px;
- padding-left: 58px;
- right: 5px;
- display: block;
- font-size: 9px;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-#list li.selected {
- background-image: url(Images/sidebarSelectionTall.png);
- background-repeat: repeat-x;
- background-position: center;
- background-color: transparent !important;
- color: white;
- font-weight: bold;
- text-shadow: rgba(0, 0, 0, 0.4) 0 1px 0;
-}
-
-#sidebar.blurred li.selected {
- background-image: url(Images/sidebarSelectionBlurredTall.png);
-}
-
-body.inactive #sidebar li.selected {
- background-image: url(Images/sidebarSelectionGrayTall.png);
-}
-
-#main {
- position: absolute;
- top: 32px;
- left: 200px;
- right: 0;
- bottom: 0;
- overflow: hidden;
- background-color: white;
- z-index: -100;
-}
-
-body.attached #main {
- top: 28px;
-}
-
-#panels {
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- overflow: hidden;
- z-index: -100;
-}
-
-.panel {
- display: none;
- overflow: hidden;
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
-}
-
-.panel.selected {
- display: block;
- background-color: transparent !important;
-}
-
-.content {
- display: none;
- -webkit-user-select: text;
- cursor: auto;
- overflow: none;
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
-}
-
-.content.selected {
- display: block;
- background-color: transparent !important;
-}
-
-.panel.font {
- font-size: 60px;
- white-space: pre-wrap;
- word-wrap: break-word;
- text-align: center;
-}
-
-.panel.font .preview {
- position: absolute;
- margin-top: auto;
- margin-bottom: auto;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
-}
-
-.panel.image {
- position: relative;
- width: 100%;
- height: 100%;
-}
-
-.panel.image > .image {
- position: relative;
- -webkit-box-sizing: border-box;
- height: 70%;
- padding: 20px;
-}
-
-.panel.image > .info {
- position: relative;
- -webkit-box-sizing: border-box;
- height: 30%;
- padding-top: 10px;
- overflow: auto;
- font-size: 11px;
-}
-
-.panel.image img {
- margin: auto;
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- max-width: 80%;
- max-height: 80%;
- background-image: url(Images/checker.png);
- -webkit-box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.5);
-}
-
-.panel.image .title {
- text-align: center;
- font-size: 13px;
-}
-
-.panel.image .infoList {
- margin: 0;
-}
-
-.panel.image .infoList dt {
- font-weight: bold;
- display: inline-block;
- width: 50%;
- text-align: right;
-}
-
-.panel.image .infoList dd {
- -webkit-box-sizing: border-box;
- display: inline-block;
- padding-left: 10px;
- width: 50%;
- text-align: left;
- margin: 0;
-}
-
-.panel.image .infoList dd::after {
- white-space: pre;
- content: "\A";
-}
-
-.content.network {
-}
-
-.content.other {
- font-family: Monaco, monospace;
- font-size: 10px;
- white-space: pre-wrap;
- padding: 6px;
-}
-
-.content.side {
- display: block;
- overflow: hidden;
- position: absolute;
- top: 0;
- left: 0;
- right: 225px;
- bottom: 0;
-}
-
-.content.source iframe {
- width: 100%;
- height: 100%;
-}
-
-.content.tree {
- display: block;
- overflow: auto;
- padding: 0;
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 21px;
-}
-
-.sidebar {
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- width: 225px;
- background-color: rgb(232, 232, 232);
- border-left: 1px solid rgb(64%, 64%, 64%);
- -webkit-box-sizing: border-box;
- -webkit-user-select: none;
- cursor: default;
- overflow: auto;
- padding: 0;
-}
-
-.crumbs {
- -webkit-user-select: none;
- cursor: default;
- -webkit-box-sizing: border-box;
- position: absolute;
- left: 0;
- right: 0;
- bottom: 0;
- height: 21px;
- background-image: url(Images/breadcrumbBackground.png);
- background-repeat: repeat-x;
- border-top: 1px solid #bbb;
- font-size: 11px;
- line-height: 19px;
- text-shadow: rgba(255, 255, 255, 0.75) 0 1px 0;
- color: rgb(20, 20, 20);
- overflow: hidden;
-}
-
-.crumbs > div {
- position: absolute;
-}
-
-.crumbs .crumb {
- -webkit-box-sizing: border-box;
- height: 20px;
- border-width: 0 11px 0 0;
- -webkit-border-image: url(Images/segment.png) 0 11 0 0;
- margin-right: -11px;
- padding-left: 15px;
- padding-right: 2px;
- white-space: nowrap;
- float: right;
-}
-
-.crumbs .crumb.collapsed > * {
- display: none;
-}
-
-.crumbs .crumb.collapsed::before {
- content: "\2026"; /* ellipses */
- font-weight: bold;
-}
-
-.crumbs .crumb.compact .extra {
- display: none;
-}
-
-.crumbs .crumb.dimmed {
- color: rgba(0, 0, 0, 0.45);
-}
-
-.crumbs .crumb.start {
- padding-left: 7px;
-}
-
-.crumbs .crumb.end {
- border-width: 0 2px 0 0;
- padding-right: 6px;
- -webkit-border-image: url(Images/segmentEnd.png) 0 2 0 0;
-}
-
-.crumbs .crumb.selected {
- -webkit-border-image: url(Images/segmentSelected.png) 0 11 0 0;
- background-color: transparent !important;
- color: black;
-}
-
-.crumbs .crumb.selected:hover {
- -webkit-border-image: url(Images/segmentSelected.png) 0 11 0 0;
-}
-
-.crumbs .crumb.selected.end, .crumbs .crumb.selected.end:hover {
- -webkit-border-image: url(Images/segmentSelectedEnd.png) 0 2 0 0;
-}
-
-.crumbs .crumb:hover {
- -webkit-border-image: url(Images/segmentHover.png) 0 11 0 0;
- color: black;
-}
-
-.crumbs .crumb.dimmed:hover {
- -webkit-border-image: url(Images/segmentHover.png) 0 11 0 0;
- color: rgba(0, 0, 0, 0.75);
-}
-
-.crumbs .crumb.end:hover {
- -webkit-border-image: url(Images/segmentHoverEnd.png) 0 2 0 0;
-}
-
-.outline-disclosure li .selection {
- display: none;
- position: absolute;
- left: 0;
- right: 0;
- height: 15px;
- z-index: -1;
-}
-
-.outline-disclosure li.selected .selection {
- display: block;
-}
-
-.content.tree > ol, #searchResults > ol {
- position: relative;
- padding: 2px 6px !important;
- margin: 0;
- color: black;
- -webkit-user-select: none;
- cursor: default;
- min-width: 100%;
- -webkit-box-sizing: border-box;
-}
-
-.outline-disclosure, .outline-disclosure ol {
- list-style-type: none;
- font-size: 11px;
- -webkit-padding-start: 12px;
- margin: 0;
-}
-
-.outline-disclosure li {
- padding: 0 0 2px 14px;
- -webkit-box-sizing: border-box;
- margin-top: 1px;
- margin-bottom: 1px;
- word-wrap: break-word;
- text-indent: -2px
-}
-
-.blurred .outline-disclosure li.selected, body.inactive .outline-disclosure li.selected {
- background-color: transparent !important;
- color: black;
-}
-
-.outline-disclosure li.selected {
- background-color: transparent !important;
- color: white;
-}
-
-.outline-disclosure li.parent {
- text-indent: -12px
-}
-
-.content.tree li .webkit-html-tag.close {
- margin-left: -12px;
-}
-
-.outline-disclosure li.parent::before {
- content: url(Images/treeRightTriangleBlack.png);
- float: left;
- width: 8px;
- height: 8px;
- margin-top: 1px;
- padding-right: 2px;
-}
-
-.blurred .outline-disclosure li.parent.selected::before, body.inactive .outline-disclosure li.parent.selected::before {
- content: url(Images/treeRightTriangleBlack.png);
-}
-
-.outline-disclosure li.parent.selected::before {
- content: url(Images/treeRightTriangleWhite.png);
-}
-
-.blurred .outline-disclosure li.parent.expanded.selected::before, body.inactive .outline-disclosure li.parent.expanded.selected::before {
- content: url(Images/treeDownTriangleBlack.png);
-}
-
-.outline-disclosure li.parent.expanded:before {
- content: url(Images/treeDownTriangleBlack.png);
-}
-
-.outline-disclosure li.parent.expanded.selected::before {
- content: url(Images/treeDownTriangleWhite.png);
-}
-
-.outline-disclosure ol.children {
- display: none;
-}
-
-.outline-disclosure ol.children.expanded {
- display: block;
-}
-
-.webkit-html-comment {
- /* Keep this in sync with view-source.css (.webkit-html-comment) */
- color: rgb(35, 110, 37);
-}
-
-.webkit-html-tag {
- /* Keep this in sync with view-source.css (.webkit-html-tag) */
- color: rgb(136, 18, 128);
-}
-
-.webkit-html-attribute-name {
- /* Keep this in sync with view-source.css (.webkit-html-attribute-name) */
- color: rgb(153, 69, 0);
-}
-
-.webkit-html-attribute-value {
- /* Keep this in sync with view-source.css (.webkit-html-attribute-value) */
- color: rgb(26, 26, 166);
-}
-
-.webkit-html-external-link, .webkit-html-resource-link {
- /* Keep this in sync with view-source.css (.webkit-html-external-link, .webkit-html-resource-link) */
- color: #00e;
-}
-
-.webkit-html-external-link {
- /* Keep this in sync with view-source.css (.webkit-html-external-link) */
- text-decoration: none;
-}
-
-.webkit-html-external-link:hover {
- /* Keep this in sync with view-source.css (.webkit-html-external-link:hover) */
- text-decoration: underline;
-}
-
-body:not(.inactive) .focused .outline-disclosure li.selected * {
- color: inherit;
-}
-
-.section {
- display: block;
- -webkit-box-shadow: rgba(0, 0, 0, .5) 2px 2px 5px;
- -webkit-border-radius: 8px;
- background-color: white;
- font-size: 11px;
- margin-bottom: 8px;
-}
-
-.section .header {
- padding: 2px 8px 4px;
- border: 2px solid rgba(255, 255, 255, 0.5);
- background-color: rgb(214, 221, 229);
- background-image: url(Images/gradient.png);
- background-repeat: repeat-x;
- background-position: bottom;
- -webkit-background-size: auto 100%;
- -webkit-border-radius: 8px;
- text-shadow: rgba(255, 255, 255, 0.75) 0 1px 0;
-}
-
-.section.expanded .header {
- border-bottom: 2px ridge rgba(214, 221, 229, 0.5);
- -webkit-border-top-right-radius: 8px;
- -webkit-border-top-left-radius: 8px;
- -webkit-border-bottom-right-radius: 0;
- -webkit-border-bottom-left-radius: 0;
-}
-
-.section .header .title {
- font-weight: bold;
- word-wrap: break-word;
-}
-
-.section .header label {
- display: none;
-}
-
-.section.expanded .header label {
- display: inline;
-}
-
-.section .header input[type=checkbox] {
- height: 1em;
- width: 1em;
- margin-left: 0;
- margin-top: 0;
- margin-bottom: 0;
- vertical-align: top;
-}
-
-.section .header .subtitle {
- margin-top: 2px;
- font-size: 10px;
- word-wrap: break-word;
-}
-
-.section .header .subtitle a {
- color: inherit;
-}
-
-.section .properties {
- display: none;
- margin: 0;
- padding: 2px 6px 5px;
- list-style: none;
-}
-
-.section.expanded .properties {
- display: block;
-}
-
-.section .properties li {
- margin-left: 10px;
- white-space: nowrap;
- text-overflow: ellipsis;
- overflow: hidden;
- -webkit-user-select: text;
- cursor: auto;
- outline: none;
-}
-
-.section .properties li.parent {
- margin-left: 0;
-}
-
-.section .properties li.selected {
- background-color: transparent !important;
-}
-
-.section .properties ol {
- display: none;
- margin: 0;
- -webkit-padding-start: 12px;
- list-style: none;
-}
-
-.section .properties ol.expanded {
- display: block;
-}
-
-.section .properties li.parent::before {
- content: url(Images/treeRightTriangleBlack.png);
- opacity: 0.75;
- float: left;
- width: 8px;
- height: 8px;
- margin-top: 0;
- padding-right: 2px;
- -webkit-user-select: none;
- cursor: default;
-}
-
-.section .properties li.parent.expanded::before {
- content: url(Images/treeDownTriangleBlack.png);
- margin-top: 1px;
-}
-
-.section .properties li.editing {
- -webkit-box-shadow: rgba(0, 0, 0, .5) 3px 3px 4px;
- outline: 1px solid rgb(66%, 66%, 66%);
- background-color: white;
- -webkit-user-modify: read-write-plaintext-only;
- text-overflow: clip;
- margin-left: 8px;
- padding-left: 2px;
- margin-bottom: -1px;
- padding-bottom: 1px;
- text-decoration: none !important;
- opacity: 1.0 !important;
-}
-
-.section .properties li.editing.parent::before {
- display: none;
-}
-
-.section .properties li.editing * {
- color: black !important;
-}
-
-.section .properties .overloaded {
- text-decoration: line-through;
-}
-
-.section .properties .implicit, .section .properties .inherited {
- opacity: 0.5;
-}
-
-.section:not(.show-inherited) .properties .inherited {
- display: none;
-}
-
-.section .properties .name {
- color: rgb(136, 19, 145);
-}
-
-.section .properties .value.dimmed {
- color: rgb(100, 100, 100);
-}
-
-.section .properties .number {
- color: blue;
-}
-
-.section .properties .priority {
- color: rgb(128, 0, 0);
-}
-
-.section .properties .keyword {
- color: rgb(136, 19, 79);
-}
-
-.section .properties .color {
- color: rgb(118, 15, 21);
-}
-
-.swatch {
- display: inline-block;
- vertical-align: middle;
- margin-left: 4px;
- width: 0.75em;
- height: 0.75em;
- border: 1px solid rgb(180, 180, 180);
-}
-
-.pane {
- margin-top: 1px;
-}
-
-.pane > .title {
- background-image: url(Images/paneHeader.png);
- background-repeat: repeat-x;
- background-position: bottom;
- -webkit-background-size: auto 100%;
- height: 14px;
- padding: 0 6px;
- border-top: 1px solid rgb(129, 129, 129);
- border-bottom: 1px solid rgb(129, 129, 129);
- font-weight: bold;
- font-size: 11px;
- color: rgb(85, 85, 85);
-}
-
-.pane > .title:active {
- background-image: url(Images/paneHeaderActive.png);
-}
-
-.pane > .title::before {
- content: url(Images/treeRightTriangleBlack.png);
- opacity: 0.75;
- float: left;
- width: 8px;
- height: 8px;
- margin-right: 3px;
- margin-top: 0;
-}
-
-.pane.expanded > .title::before {
- margin-top: 1px;
- content: url(Images/treeDownTriangleBlack.png);
-}
-
-.pane > .body {
- position: relative;
- padding: 8px;
- display: none;
- overflow: auto;
-}
-
-.pane.expanded > .body, .pane.expanded > .growbar {
- display: block;
-}
-
-.pane > .growbar {
- display: none;
- background-image: url(Images/paneGrowHandleLine.png), url(Images/paneBottomGrow.png);
- background-repeat: no-repeat, repeat-x;
- background-position: center center, bottom;
- -webkit-background-size: auto 100%, auto 100%;
- height: 5px;
-}
-
-.metrics {
- font-size: 10px;
- text-align: center;
- white-space: nowrap;
-}
-
-.metrics .label {
- position: absolute;
- margin-top: -10px;
- font-size: 9px;
- color: grey;
- background-color: rgb(232, 232, 232);
- margin-left: 3px;
- padding-left: 2px;
- padding-right: 2px;
-}
-
-.metrics .margin {
- border: 1px dashed;
- display: inline-block;
- -webkit-box-sizing: border-box;
- padding: 3px;
- margin: 3px;
-}
-
-.metrics .border {
- border: 1px black solid;
- display: inline-block;
- vertical-align: middle;
- -webkit-box-sizing: border-box;
- padding: 3px;
- margin: 3px;
-}
-
-.metrics .padding {
- border: 1px grey dashed;
- display: inline-block;
- vertical-align: middle;
- -webkit-box-sizing: border-box;
- padding: 3px;
- margin: 3px;
-}
-
-.metrics .content {
- position: static;
- border: 1px grey solid;
- display: inline-block;
- vertical-align: middle;
- -webkit-box-sizing: border-box;
- padding: 3px;
- margin: 3px;
- min-width: 80px;
- text-align: center;
- overflow: visible;
-}
-
-.metrics .left {
- display: inline-block;
- text-align: center;
- vertical-align: middle;
- -webkit-box-sizing: border-box;
-}
-
-.metrics .right {
- display: inline-block;
- text-align: center;
- vertical-align: middle;
- -webkit-box-sizing: border-box;
-}
-
-.metrics .top {
- text-align: center;
-}
-
-.metrics .bottom {
- text-align: center;
-}
-
-.console-message-list {
- list-style: none;
- margin: 0;
- padding: 0;
- position: absolute;
- top: 0;
- bottom: 20px;
- left: 0;
- right: 0;
- overflow: auto;
- -webkit-user-select: text;
- cursor: auto;
-}
-
-.console-prompt {
- font-family: monospace;
- font-size: 11px;
- margin: 0;
- padding: 2px 0 0;
- position: absolute;
- bottom: 0;
- left: 0;
- right: 0;
- height: 18px;
- resize: none;
- outline: none;
- border: none;
- border-top: 1px solid rgb(64%, 64%, 64%);
-}
-
-.console-message, .console-command {
- font-size: 10px;
- margin: 0;
- padding: 3px 3px 3px 24px;
- border-bottom: 1px solid rgb(75%, 75%, 75%);
- word-break: break-word;
- position: relative;
-}
-
-.console-command a:hover {
- text-decoration: underline;
- cursor: pointer;
-}
-
-.console-message-message {
- font-size: 11px;
- white-space: pre-wrap;
-}
-
-.console-message-url {
- color: rgb(33%, 33%, 33%);
- cursor: pointer;
-}
-
-.console-message-url::after {
- content: url(Images/goArrow.png);
- margin-left: 3px;
- width: 12px;
- height: 12px;
- vertical-align: middle;
- opacity: 0.75;
- -webkit-user-select: none;
-}
-
-.console-message-url:hover {
- color: rgb(15%, 15%, 15%);
-}
-
-.console-message-url:hover::after {
- opacity: 1;
-}
-
-.console-error-level::before {
- content: url(Images/errorMediumIcon.png);
- position: absolute;
- left: 5px;
- top: 2px;
- -webkit-user-select: none;
-}
-
-.console-warning-level::before {
- content: url(Images/warningMediumIcon.png);
- position: absolute;
- left: 4px;
- top: 2px;
- -webkit-user-select: none;
-}
-
-.console-command-input, .console-command-output {
- font-size: 11px;
- white-space: pre-wrap;
-}
-
-.console-command-input::before {
- content: ">";
- font-weight: bold;
- font-size: 15px;
- color: blue;
- position: absolute;
- left: 8px;
- top: 1px;
- -webkit-user-select: none;
-}
-
-.view-button-browse img {
- content: url(Images/databaseBrowserViewNormal.png);
- vertical-align: middle;
- margin-top: -1px;
- margin-left: 1px;
- width: 11px;
- height: 11px;
-}
-
-.view-button-browse.selected img {
- content: url(Images/databaseBrowserViewNormalSelected.png);
-}
-
-body.attached .view-button-browse img {
- content: url(Images/databaseBrowserViewSmall.png);
- width: 11px;
- height: 8px;
- margin-top: 1px;
- margin-left: 2px;
-}
-
-body.attached .view-button-browse.selected img {
- content: url(Images/databaseBrowserViewSmallSelected.png);
-}
-
-.view-button-query img {
- content: url(Images/databaseQueryViewNormal.png);
- vertical-align: middle;
- margin-top: -1px;
- margin-left: -1px;
- width: 11px;
- height: 11px;
-}
-
-.view-button-query.selected img {
- content: url(Images/databaseQueryViewNormalSelected.png);
-}
-
-body.attached .view-button-query img {
- content: url(Images/databaseQueryViewSmall.png);
- width: 10px;
- height: 8px;
- margin-top: 1px;
-}
-
-body.attached .view-button-query.selected img {
- content: url(Images/databaseQueryViewSmallSelected.png);
-}
-
-.database-table-reload {
- padding-left: 0;
- padding-right: 0;
- width: 28px;
- margin-left: 6px;
-}
-
-body.attached .database-table-reload {
- width: 20px;
-}
-
-.database-table-reload img {
- content: url(Images/reload.png);
- vertical-align: middle;
- margin-top: -2px;
- width: 10px;
- height: 13px;
-}
-
-.query.content {
- bottom: 21px;
-}
-
-.browse.content {
- font-size: 10px;
- overflow-y: auto;
- overflow-x: hidden;
- bottom: 21px;
-}
-
-.browse.content .database-result-table {
- border: none;
-}
-
-.browse.content .database-table-empty, .browse.content .database-table-error {
- position: absolute;
- top: 0;
- bottom: 25%;
- left: 0;
- right: 0;
- font-size: 24px;
- color: rgb(75%, 75%, 75%);
- margin-top: auto;
- margin-bottom: auto;
- height: 50px;
- line-height: 26px;
- text-align: center;
- font-weight: bold;
- padding: 10px;
- white-space: pre-wrap;
-}
-
-.browse.content .database-table-error {
- color: rgb(66%, 33%, 33%);
-}
-
-.database-browse-table {
- height: 100%;
-}
-
-.database-result-table .database-result-filler-row {
- height: auto;
-}
-
-.database-result-table .database-result-filler-row.alternate td {
- background-position-y: 16px;
-}
-
-.database-result-filler-row td {
- background-image: url(Images/alternateTableRows.png);
-}
-
-.database-table-select {
- margin-left: 6px;
- max-width: 150px;
- min-width: 75px;
-}
-
-.database-command-list {
- list-style: none;
- margin: 0;
- padding: 0;
- position: absolute;
- top: 0;
- bottom: 0;
- left: 0;
- right: 0;
- overflow-y: auto;
- overflow-x: hidden;
-}
-
-.database-prompt {
- font-family: monospace;
- font-size: 11px;
- margin: 0;
- padding: 2px 0 0;
- position: absolute;
- bottom: 0;
- left: 0;
- right: 0;
- height: 18px;
- resize: none;
- outline: none;
- border: none;
- border-top: 1px solid rgb(64%, 64%, 64%);
-}
-
-.database-command {
- font-size: 10px;
- margin: 0;
- padding: 5px;
- border-bottom: 1px solid rgb(75%, 75%, 75%);
- word-break: break-word;
- position: relative;
-}
-
-.database-command a:hover {
- text-decoration: underline;
- cursor: pointer;
-}
-
-.database-command-query {
- font-family: monospace;
- font-size: 11px;
- white-space: pre-wrap;
-}
-
-.database-command-result {
- margin-top: 3px;
-}
-
-.database-command-result.error {
- color: red;
-}
-
-.database-result-table {
- border: 1px solid #aaa;
- table-layout: fixed;
- border-spacing: 0;
- border-collapse: collapse;
- width: 100%;
- -webkit-box-sizing: border-box;
-}
-
-.database-result-table th {
- text-align: left;
- background: url(Images/glossyHeader.png) repeat-x;
- border-right: 1px solid #aaa;
- height: 15px;
- -webkit-box-sizing: border-box;
- border-bottom: 1px solid #aaa;
- font-weight: normal;
- vertical-align: middle;
- padding: 0 4px;
- white-space: nowrap;
-}
-
-.database-result-table tr {
- height: 16px;
-}
-
-.database-result-table tr.alternate {
- background-color: rgb(236, 243, 254);
-}
-
-.database-result-table td {
- vertical-align: top;
- padding: 2px 4px;
- -webkit-box-sizing: border-box;
- white-space: nowrap;
- border-right: 1px solid #aaa;
-}
-
-.database-result-table td > div, .database-result-table th > div {
- white-space: nowrap;
- text-overflow: ellipsis;
- overflow: hidden;
-}
-
-.network-timeline {
- position: absolute;
- top: 0;
- bottom: 99px;
- left: 0;
- right: 0;
- font-family: Lucida Grande, sans-serif;
- font-size: 11px;
-}
-
-.network-divider {
- width: 1px;
- height: 100%;
- position: absolute;
- background-color: rgba(0, 0, 0, 0.1);
-}
-
-.network-divider.last {
- background-color: rgb(66%, 66%, 66%);
-}
-
-.network-divider-label {
- position: absolute;
- top: 2px;
- right: 3px;
- font-size: 9px;
- color: rgb(50%, 50%, 50%);
-}
-
-.network-dividers {
- position: absolute;
- left: 153px;
- right: 20px;
- bottom: 0;
- top: 0;
- z-index: -100;
- border-left: 1px solid rgb(66%, 66%, 66%);
- -webkit-box-sizing: border-box;
-}
-
-.network-resources {
- position: absolute;
- width: 100%;
- overflow-y: overlay;
- overflow-x: hidden;
- border-top: 1px solid rgb(66%, 66%, 66%);
- top: 15px;
- bottom: 0;
-}
-
-.network-title {
- position: relative;
- height: 18px;
-}
-
-.network-title:hover {
- background-color: rgba(0, 0, 200, 0.1);
-}
-
-.network-info {
- background-color: rgb(225, 225, 235);
- background-image: url(Images/attachedShadow.png), url(Images/bottomShadow.png);
- background-repeat: repeat-x;
- background-position: top, bottom;
- overflow: hidden;
- -webkit-user-select: text;
- cursor: auto;
-}
-
-.network-info table {
- font-size: 11px;
- margin: 5px 15px 5px 5px;
-}
-
-.network-info th {
- width: 145px;
-}
-
-.network-info thead th {
- text-align: right;
-}
-
-.network-info tbody th {
- white-space: nowrap;
- text-align: right;
- font-weight: bold;
- color: rgba(0, 0, 0, 0.5);
- vertical-align: top;
-}
-
-.network-info td {
- word-break: break-word;
- white-space: normal;
-}
-
-.network-file {
- position: absolute;
- left: 5px;
- height: 100%;
- width: 145px;
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
- line-height: 18px;
- -webkit-user-select: text;
-}
-
-.network-file a {
- color: inherit;
- text-decoration: none;
-}
-
-.network-file a:hover {
- text-decoration: underline;
-}
-
-.network-area {
- position: absolute;
- left: 162px;
- right: 28px;
- height: 100%;
-}
-
-.network-bar {
- position: absolute;
- top: 0;
- bottom: 0;
- margin: auto -7px;
- border-width: 6px 7px 6px 7px;
- height: 13px;
- min-width: 14px;
- -webkit-box-sizing: border-box;
- opacity: 0.8;
- -webkit-border-image: url(Images/timelinePillGray.png) 6 7 6 7;
-}
-
-.network-bar.network-category-documents {
- -webkit-border-image: url(Images/timelinePillBlue.png) 6 7 6 7;
-}
-
-.network-bar.network-category-stylesheets {
- -webkit-border-image: url(Images/timelinePillGreen.png) 6 7 6 7;
-}
-
-.network-bar.network-category-images {
- -webkit-border-image: url(Images/timelinePillPurple.png) 6 7 6 7;
-}
-
-.network-bar.network-category-fonts {
- -webkit-border-image: url(Images/timelinePillYellow.png) 6 7 6 7;
-}
-
-.network-bar.network-category-scripts {
- -webkit-border-image: url(Images/timelinePillOrange.png) 6 7 6 7;
-}
-
-.network-summary {
- position: absolute;
- bottom: 0;
- left: 0;
- right: 0;
- height: 99px;
- background-color: rgb(101, 111, 130);
- background-image: url(Images/darkShadow.png), url(Images/gradientHighlightBottom.png);
- background-repeat: repeat-x;
- background-position: top, bottom;
-}
-
-.network-graph-area {
- padding-top: 20px;
- position: absolute;
- margin: auto;
- top: 0;
- bottom: 0;
- right: 0;
- left: 0;
- width: 575px;
- white-space: nowrap;
- color: white;
- text-shadow: black 0px 1px 1px;
-}
-
-.network-graph-label {
- height: 38px;
- display: inline-block;
- vertical-align: top;
- margin-right: 5px;
- margin-top: -2px;
- text-align: right;
-}
-
-.network-graph-side {
- position: relative;
- display: inline-block;
- vertical-align: top;
-}
-
-.network-graph-legend-total {
- margin-top: 12px;
- padding-right: 5px;
-}
-
-.network-graph-legend-total .network-graph-legend-label {
- text-align: right;
-}
-
-.network-graph-mode {
- -webkit-appearance: none;
- background-color: transparent;
- border: none;
- font-weight: bold;
- font-size: 12px;
- height: 18px;
- line-height: 11px;
- text-align: right;
- vertical-align: middle;
- padding: 2px 16px 2px 8px;
- margin: 0;
- background-image: url(Images/popupArrows.png);
- background-position: right center;
- background-repeat: no-repeat;
- color: inherit;
- border: 1px solid transparent;
- text-shadow: black 0px 2px 2px;
-}
-
-.network-graph-mode:focus {
- outline: none;
-}
-
-.network-graph-mode:hover {
- -webkit-border-radius: 9px;
- background-color: rgba(0, 0, 0, 0.2);
- border: 1px solid white;
- -webkit-box-shadow: black 0px 1px 1px;
-}
-
-.network-graph-legend {
- margin-top: -8px;
- text-align: center;
-}
-
-.network-graph-legend-item {
- display: inline-block;
- font-weight: bold;
- margin-right: 15px;
- vertical-align: top;
-}
-
-.network-graph-legend-label {
- display: inline-block;
- text-align: left;
-}
-
-.network-graph-legend-header {
- font-size: 12px;
- text-transform: capitalize;
-}
-
-.network-graph-legend-value {
- font-size: 10px;
-}
-
-.network-graph-legend-swatch {
- vertical-align: top;
- margin-top: 1px;
- margin-right: 3px;
-}
-
-.network-summary-graph {
- vertical-align: middle;
-}
-
-.tip-button {
- background-image: url(Images/tipIcon.png);
- border: none;
- width: 16px;
- height: 16px;
- float: right;
- background-color: transparent;
- margin-top: 1px;
-}
-
-.tip-button:active {
- background-image: url(Images/tipIconPressed.png);
-}
-
-.tip-balloon {
- position: absolute;
- left: 145px;
- top: -5px;
- z-index: 1000;
- border-width: 51px 15px 18px 37px;
- -webkit-border-image: url(Images/tipBalloon.png) 51 15 18 37;
- width: 265px;
-}
-
-.tip-balloon.bottom {
- position: absolute;
- left: 145px;
- top: auto;
- bottom: -7px;
- z-index: 1000;
- border-width: 18px 15px 51px 37px;
- -webkit-border-image: url(Images/tipBalloonBottom.png) 18 15 51 37;
-}
-
-.tip-balloon-content {
- margin-top: -40px;
- margin-bottom: -2px;
- margin-left: 2px;
-}
-
-.tip-balloon.bottom .tip-balloon-content {
- margin-top: -10px;
- margin-bottom: -35px;
-}
-
-.sidebar-resizer-vertical {
- position: absolute;
- top: 0;
- bottom: 0;
- width: 5px;
- z-index: 100;
- cursor: col-resize;
-}
-
-.sidebar-resizer-vertical-left {
- left: 197px;
-}
-
-.sidebar-resizer-vertical-right {
- right: 222px;
-}
-
-#searchResultsResizer {
- position: absolute;
- height: 5px;
- left: 0;
- right: 0;
- cursor: row-resize;
-}
diff --git a/WebCore/page/inspector/inspector.html b/WebCore/page/inspector/inspector.html
deleted file mode 100644
index 3ba0300..0000000
--- a/WebCore/page/inspector/inspector.html
+++ /dev/null
@@ -1,75 +0,0 @@
-<!--
-Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
-EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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.
--->
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
- <meta http-equiv="content-type" content="text/html; charset=utf-8" />
- <link rel="stylesheet" type="text/css" href="inspector.css" />
- <script type="text/javascript" src="utilities.js"></script>
- <script type="text/javascript" src="treeoutline.js"></script>
- <script type="text/javascript" src="inspector.js"></script>
- <script type="text/javascript" src="Resource.js"></script>
- <script type="text/javascript" src="ResourceCategory.js"></script>
- <script type="text/javascript" src="Database.js"></script>
- <script type="text/javascript" src="SidebarPane.js"></script>
- <script type="text/javascript" src="PropertiesSection.js"></script>
- <script type="text/javascript" src="MetricsSidebarPane.js"></script>
- <script type="text/javascript" src="PropertiesSidebarPane.js"></script>
- <script type="text/javascript" src="StylesSidebarPane.js"></script>
- <script type="text/javascript" src="Panel.js"></script>
- <script type="text/javascript" src="ResourcePanel.js"></script>
- <script type="text/javascript" src="SourcePanel.js"></script>
- <script type="text/javascript" src="ConsolePanel.js"></script>
- <script type="text/javascript" src="DatabasePanel.js"></script>
- <script type="text/javascript" src="DocumentPanel.js"></script>
- <script type="text/javascript" src="FontPanel.js"></script>
- <script type="text/javascript" src="ImagePanel.js"></script>
- <script type="text/javascript" src="NetworkPanel.js"></script>
-</head>
-<body class="detached">
- <div id="toolbar">
- <button id="back" class="split-button first"><img></button><img class="split-button-divider"><button id="forward" class="split-button last"><img></button>
- <span id="toolbarButtons"></span>
- <input id="search" type="search" autosave="inspectorSearch" results="20" incremental="incremental" onsearch="WebInspector.performSearch(this.value)">
- </div>
- <div id="sidebar" class="focusable focused">
- <ol id="list"></ol>
- <ol id="status"></ol>
- <div id="statusbar">
- <button id="attachToggle"></button>
- <span id="sidebarResizeWidget"></span>
- </div>
- <div id="sidebarResizer" class="sidebar-resizer-vertical sidebar-resizer-vertical-left"></div>
- </div>
- <div id="main" class="focusable blurred">
- <div id="searchResults" class="focusable hidden"></div>
- <div id="searchResultsResizer" class="hidden"></div>
- <div id="panels"></div>
- </div>
-</body>
-</html>
diff --git a/WebCore/page/inspector/inspector.js b/WebCore/page/inspector/inspector.js
deleted file mode 100644
index 04e78e6..0000000
--- a/WebCore/page/inspector/inspector.js
+++ /dev/null
@@ -1,1186 +0,0 @@
-/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
- * Copyright (C) 2007 Matt Lilek (pewtermoose@gmail.com).
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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.
- */
-
-var Preferences = {
- ignoreWhitespace: true,
- showUserAgentStyles: true,
- maxInlineTextChildLength: 80,
- maxTextSearchResultLength: 80,
- showInheritedComputedStyleProperties: false,
- showMissingLocalizedStrings: false
-}
-
-var WebInspector = {
- resources: [],
- resourceURLMap: {},
- backForwardList: [],
- searchResultsHeight: 100,
- localizedStrings: {},
- missingLocalizedStrings: {},
-
- get consolePanel()
- {
- if (!this._consolePanel)
- this._consolePanel = new WebInspector.ConsolePanel();
-
- return this._consolePanel;
- },
-
- get networkPanel()
- {
- if (!this._networkPanel)
- this._networkPanel = new WebInspector.NetworkPanel();
-
- return this._networkPanel;
- },
-
- get currentBackForwardIndex()
- {
- if (this._currentBackForwardIndex === undefined)
- this._currentBackForwardIndex = -1;
-
- return this._currentBackForwardIndex;
- },
-
- set currentBackForwardIndex(x)
- {
- if (this._currentBackForwardIndex === x)
- return;
-
- this._currentBackForwardIndex = x;
- this.updateBackForwardButtons();
- },
-
- get currentFocusElement()
- {
- return this._currentFocusElement;
- },
-
- set currentFocusElement(x)
- {
- if (!x || this._currentFocusElement === x)
- return;
-
- if (this._currentFocusElement) {
- this._currentFocusElement.removeStyleClass("focused");
- this._currentFocusElement.addStyleClass("blurred");
- if (this._currentFocusElement.blurred)
- this._currentFocusElement.blurred();
- }
-
- this._currentFocusElement = x;
-
- if (x) {
- x.addStyleClass("focused");
- x.removeStyleClass("blurred");
- if (this._currentFocusElement.focused)
- this._currentFocusElement.focused();
- }
- },
-
- get currentPanel()
- {
- return this._currentPanel;
- },
-
- set currentPanel(x)
- {
- if (this._currentPanel === x)
- return;
-
- if (this._currentPanel)
- this._currentPanel.hide();
-
- this._currentPanel = x;
-
- if (x)
- x.show();
- },
-
- get attached()
- {
- return this._attached;
- },
-
- set attached(x)
- {
- if (this._attached === x)
- return;
-
- this._attached = x;
-
- var body = document.body;
- if (x) {
- InspectorController.attach();
- body.removeStyleClass("detached");
- body.addStyleClass("attached");
- } else {
- InspectorController.detach();
- body.removeStyleClass("attached");
- body.addStyleClass("detached");
- }
- },
-
- get showingSearchResults()
- {
- return this._showingSearchResults;
- },
-
- set showingSearchResults(x)
- {
- if (this._showingSearchResults === x)
- return;
-
- this._showingSearchResults = x;
-
- var resultsContainer = document.getElementById("searchResults");
- var searchResultsResizer = document.getElementById("searchResultsResizer");
-
- if (x) {
- resultsContainer.removeStyleClass("hidden");
- searchResultsResizer.removeStyleClass("hidden");
-
- var animations = [
- {element: resultsContainer, end: {top: 0}},
- {element: searchResultsResizer, end: {top: WebInspector.searchResultsHeight - 3}},
- {element: document.getElementById("panels"), end: {top: WebInspector.searchResultsHeight}}
- ];
-
- WebInspector.animateStyle(animations, 250);
- } else {
- searchResultsResizer.addStyleClass("hidden");
-
- var animations = [
- {element: resultsContainer, end: {top: -WebInspector.searchResultsHeight}},
- {element: searchResultsResizer, end: {top: 0}},
- {element: document.getElementById("panels"), end: {top: 0}}
- ];
-
- var animationFinished = function()
- {
- resultsContainer.addStyleClass("hidden");
- resultsContainer.removeChildren();
- delete this.searchResultsTree;
- };
-
- WebInspector.animateStyle(animations, 250, animationFinished);
- }
- }
-}
-
-WebInspector.loaded = function()
-{
- var platform = InspectorController.platform();
- document.body.addStyleClass("platform-" + platform);
-
- this.fileOutline = new TreeOutline(document.getElementById("list"));
- this.fileOutline.expandTreeElementsWhenArrowing = true;
-
- this.statusOutline = new TreeOutline(document.getElementById("status"));
- this.statusOutline.expandTreeElementsWhenArrowing = true;
-
- this.resourceCategories = {
- documents: new WebInspector.ResourceCategory(WebInspector.UIString("documents"), "documents"),
- stylesheets: new WebInspector.ResourceCategory(WebInspector.UIString("stylesheets"), "stylesheets"),
- images: new WebInspector.ResourceCategory(WebInspector.UIString("images"), "images"),
- scripts: new WebInspector.ResourceCategory(WebInspector.UIString("scripts"), "scripts"),
- fonts: new WebInspector.ResourceCategory(WebInspector.UIString("fonts"), "fonts"),
- databases: new WebInspector.ResourceCategory(WebInspector.UIString("databases"), "databases"),
- other: new WebInspector.ResourceCategory(WebInspector.UIString("other"), "other")
- };
-
- this.Tips = {
- ResourceNotCompressed: {id: 0, message: WebInspector.UIString("You could save bandwidth by having your web server compress this transfer with gzip or zlib.")}
- };
-
- this.Warnings = {
- IncorrectMIMEType: {id: 0, message: WebInspector.UIString("Resource interpreted as %s but transferred with MIME type %s.")}
- };
-
- this.consoleListItem = new WebInspector.ConsoleStatusTreeElement(WebInspector.consolePanel);
- this.statusOutline.appendChild(this.consoleListItem);
-
- this.networkListItem = new WebInspector.StatusTreeElement(WebInspector.UIString("Network"), "network", WebInspector.networkPanel);
- this.statusOutline.appendChild(this.networkListItem);
-
- this.resourceCategories.documents.listItem.expand();
-
- this.currentFocusElement = document.getElementById("sidebar");
-
- this.addMainEventListeners(document);
-
- window.addEventListener("unload", this.windowUnload.bind(this), true);
- window.addEventListener("resize", this.windowResize.bind(this), true);
-
- document.addEventListener("mousedown", this.changeFocus.bind(this), true);
- document.addEventListener("focus", this.changeFocus.bind(this), true);
- document.addEventListener("keydown", this.documentKeyDown.bind(this), true);
- document.addEventListener("beforecopy", this.documentCanCopy.bind(this), true);
- document.addEventListener("copy", this.documentCopy.bind(this), true);
-
- document.getElementById("back").title = WebInspector.UIString("Show previous panel.");
- document.getElementById("forward").title = WebInspector.UIString("Show next panel.");
-
- document.getElementById("search").setAttribute("placeholder", WebInspector.UIString("Search"));
-
- document.getElementById("back").addEventListener("click", this.back.bind(this), true);
- document.getElementById("forward").addEventListener("click", this.forward.bind(this), true);
- this.updateBackForwardButtons();
-
- document.getElementById("attachToggle").addEventListener("click", this.toggleAttach.bind(this), true);
-
- document.getElementById("sidebarResizeWidget").addEventListener("mousedown", this.sidebarResizerDragStart, true);
- document.getElementById("sidebarResizer").addEventListener("mousedown", this.sidebarResizerDragStart, true);
- document.getElementById("searchResultsResizer").addEventListener("mousedown", this.searchResultsResizerDragStart, true);
-
- if (platform === "mac-leopard")
- document.getElementById("toolbar").addEventListener("mousedown", this.toolbarDragStart, true);
-
- document.body.addStyleClass("detached");
-
- InspectorController.loaded();
-}
-
-var windowLoaded = function()
-{
- var localizedStringsURL = InspectorController.localizedStringsURL();
- if (localizedStringsURL) {
- var localizedStringsScriptElement = document.createElement("script");
- localizedStringsScriptElement.addEventListener("load", WebInspector.loaded.bind(WebInspector), false);
- localizedStringsScriptElement.type = "text/javascript";
- localizedStringsScriptElement.src = localizedStringsURL;
- document.getElementsByTagName("head").item(0).appendChild(localizedStringsScriptElement);
- } else
- WebInspector.loaded();
-
- window.removeEventListener("load", windowLoaded, false);
- delete windowLoaded;
-};
-
-window.addEventListener("load", windowLoaded, false);
-
-WebInspector.windowUnload = function(event)
-{
- InspectorController.windowUnloading();
-}
-
-WebInspector.windowResize = function(event)
-{
- if (this.currentPanel && this.currentPanel.resize)
- this.currentPanel.resize();
-}
-
-WebInspector.windowFocused = function(event)
-{
- if (event.target.nodeType === Node.DOCUMENT_NODE)
- document.body.removeStyleClass("inactive");
-}
-
-WebInspector.windowBlured = function(event)
-{
- if (event.target.nodeType === Node.DOCUMENT_NODE)
- document.body.addStyleClass("inactive");
-}
-
-WebInspector.changeFocus = function(event)
-{
- var nextFocusElement;
-
- var current = event.target;
- while (current) {
- if (current.nodeName.toLowerCase() === "input")
- nextFocusElement = current;
- current = current.parentNode;
- }
-
- if (!nextFocusElement)
- nextFocusElement = event.target.firstParentWithClass("focusable");
-
- this.currentFocusElement = nextFocusElement;
-}
-
-WebInspector.documentClick = function(event)
-{
- var anchor = event.target.firstParentOrSelfWithNodeName("a");
- if (!anchor || !anchor.hasStyleClass("webkit-html-resource-link"))
- return;
-
- if (WebInspector.showResourceForURL(anchor.getAttribute("href"))) {
- event.preventDefault();
- event.stopPropagation();
- }
-}
-
-WebInspector.documentKeyDown = function(event)
-{
- if (!this.currentFocusElement)
- return;
- if (this.currentFocusElement.handleKeyEvent)
- this.currentFocusElement.handleKeyEvent(event);
- else if (this.currentFocusElement.id && this.currentFocusElement.id.length && WebInspector[this.currentFocusElement.id + "KeyDown"])
- WebInspector[this.currentFocusElement.id + "KeyDown"](event);
-}
-
-WebInspector.documentCanCopy = function(event)
-{
- if (!this.currentFocusElement)
- return;
- // Calling preventDefault() will say "we support copying, so enable the Copy menu".
- if (this.currentFocusElement.handleCopyEvent)
- event.preventDefault();
- else if (this.currentFocusElement.id && this.currentFocusElement.id.length && WebInspector[this.currentFocusElement.id + "Copy"])
- event.preventDefault();
-}
-
-WebInspector.documentCopy = function(event)
-{
- if (!this.currentFocusElement)
- return;
- if (this.currentFocusElement.handleCopyEvent)
- this.currentFocusElement.handleCopyEvent(event);
- else if (this.currentFocusElement.id && this.currentFocusElement.id.length && WebInspector[this.currentFocusElement.id + "Copy"])
- WebInspector[this.currentFocusElement.id + "Copy"](event);
-}
-
-WebInspector.sidebarKeyDown = function(event)
-{
- var nextSelectedElement;
-
- if (this.fileOutline.selectedTreeElement) {
- if (!this.fileOutline.handleKeyEvent(event) && event.keyIdentifier === "Down" && !event.altKey) {
- var nextSelectedElement = this.statusOutline.children[0];
- while (nextSelectedElement && !nextSelectedElement.selectable)
- nextSelectedElement = nextSelectedElement.traverseNextTreeElement(false);
- }
- } else if (this.statusOutline.selectedTreeElement) {
- if (!this.statusOutline.handleKeyEvent(event) && event.keyIdentifier === "Up" && !event.altKey) {
- var nextSelectedElement = this.fileOutline.children[0];
- var lastSelectable = null;
-
- while (nextSelectedElement) {
- if (nextSelectedElement.selectable)
- lastSelectable = nextSelectedElement;
- nextSelectedElement = nextSelectedElement.traverseNextTreeElement(false);
- }
-
- nextSelectedElement = lastSelectable;
- }
- }
-
- if (nextSelectedElement) {
- nextSelectedElement.reveal();
- nextSelectedElement.select();
-
- event.preventDefault();
- event.stopPropagation();
- }
-}
-
-WebInspector.sidebarCopy = function(event)
-{
- event.clipboardData.clearData();
- event.preventDefault();
-
- var selectedElement = this.fileOutline.selectedTreeElement;
- if (!selectedElement || !selectedElement.representedObject || !selectedElement.representedObject.url)
- return;
-
- event.clipboardData.setData("URL", this.fileOutline.selectedTreeElement.representedObject.url);
-}
-
-WebInspector.mainKeyDown = function(event)
-{
- if (this.currentPanel && this.currentPanel.handleKeyEvent)
- this.currentPanel.handleKeyEvent(event);
-}
-
-WebInspector.mainCopy = function(event)
-{
- if (this.currentPanel && this.currentPanel.handleCopyEvent)
- this.currentPanel.handleCopyEvent(event);
-}
-
-WebInspector.searchResultsKeyDown = function(event)
-{
- if (this.searchResultsTree)
- this.searchResultsTree.handleKeyEvent(event);
-}
-
-WebInspector.animateStyle = function(animations, duration, callback, complete)
-{
- if (complete === undefined)
- complete = 0;
- var slice = (1000 / 30); // 30 frames per second
-
- var defaultUnit = "px";
- var propertyUnit = {opacity: ""};
-
- for (var i = 0; i < animations.length; ++i) {
- var animation = animations[i];
- var element = null;
- var start = null;
- var current = null;
- var end = null;
- for (key in animation) {
- if (key === "element")
- element = animation[key];
- else if (key === "start")
- start = animation[key];
- else if (key === "current")
- current = animation[key];
- else if (key === "end")
- end = animation[key];
- }
-
- if (!element || !end)
- continue;
-
- var computedStyle = element.ownerDocument.defaultView.getComputedStyle(element);
- if (!start) {
- start = {};
- for (key in end)
- start[key] = parseInt(computedStyle.getPropertyValue(key));
- animation.start = start;
- } else if (complete == 0)
- for (key in start)
- element.style.setProperty(key, start[key] + (key in propertyUnit ? propertyUnit[key] : defaultUnit));
-
- if (!current) {
- current = {};
- for (key in start)
- current[key] = start[key];
- animation.current = current;
- }
-
- function cubicInOut(t, b, c, d)
- {
- if ((t/=d/2) < 1) return c/2*t*t*t + b;
- return c/2*((t-=2)*t*t + 2) + b;
- }
-
- var style = element.style;
- for (key in end) {
- var startValue = start[key];
- var currentValue = current[key];
- var endValue = end[key];
- if ((complete + slice) < duration) {
- var delta = (endValue - startValue) / (duration / slice);
- var newValue = cubicInOut(complete, startValue, endValue - startValue, duration);
- style.setProperty(key, newValue + (key in propertyUnit ? propertyUnit[key] : defaultUnit));
- current[key] = newValue;
- } else {
- style.setProperty(key, endValue + (key in propertyUnit ? propertyUnit[key] : defaultUnit));
- }
- }
- }
-
- if (complete < duration)
- setTimeout(WebInspector.animateStyle, slice, animations, duration, callback, complete + slice);
- else if (callback)
- callback();
-}
-
-WebInspector.toggleAttach = function()
-{
- this.attached = !this.attached;
-}
-
-WebInspector.toolbarDragStart = function(event)
-{
- var toolbar = document.getElementById("toolbar");
- if (event.target !== toolbar || WebInspector.attached)
- return;
-
- toolbar.lastScreenX = event.screenX;
- toolbar.lastScreenY = event.screenY;
-
- document.addEventListener("mousemove", WebInspector.toolbarDrag, true);
- document.addEventListener("mouseup", WebInspector.toolbarDragEnd, true);
- document.body.style.cursor = "default";
-
- event.preventDefault();
-}
-
-WebInspector.toolbarDragEnd = function(event)
-{
- var toolbar = document.getElementById("toolbar");
- delete toolbar.lastScreenX;
- delete toolbar.lastScreenY;
-
- document.removeEventListener("mousemove", WebInspector.toolbarDrag, true);
- document.removeEventListener("mouseup", WebInspector.toolbarDragEnd, true);
- document.body.style.removeProperty("cursor");
-
- event.preventDefault();
-}
-
-WebInspector.toolbarDrag = function(event)
-{
- var toolbar = document.getElementById("toolbar");
-
- var x = event.screenX - toolbar.lastScreenX;
- var y = event.screenY - toolbar.lastScreenY;
-
- toolbar.lastScreenX = event.screenX;
- toolbar.lastScreenY = event.screenY;
-
- // We cannot call window.moveBy here because it restricts the movement of the window
- // at the edges.
- InspectorController.moveByUnrestricted(x, y);
-
- event.preventDefault();
-}
-
-WebInspector.sidebarResizerDragStart = function(event)
-{
- WebInspector.elementDragStart(document.getElementById("sidebar"), WebInspector.sidebarResizerDrag, WebInspector.sidebarResizerDragEnd, event, "col-resize");
-}
-
-WebInspector.sidebarResizerDragEnd = function(event)
-{
- WebInspector.elementDragEnd(document.getElementById("sidebar"), WebInspector.sidebarResizerDrag, WebInspector.sidebarResizerDragEnd, event);
-}
-
-WebInspector.sidebarResizerDrag = function(event)
-{
- var x = event.pageX;
-
- // FIXME: We can should come up with a better hueristic for constraining the size of the sidebar.
- var newWidth = Number.constrain(x, 100, window.innerWidth - 100);
-
- document.getElementById("sidebar").style.width = newWidth + "px";
- document.getElementById("sidebarResizer").style.left = (newWidth - 3) + "px";
- document.getElementById("main").style.left = newWidth + "px";
- document.getElementById("toolbarButtons").style.left = newWidth + "px";
-
- if (WebInspector.currentPanel && WebInspector.currentPanel.resize)
- WebInspector.currentPanel.resize();
-
- event.preventDefault();
-}
-
-WebInspector.searchResultsResizerDragStart = function(event)
-{
- WebInspector.elementDragStart(document.getElementById("searchResults"), WebInspector.searchResultsResizerDrag, WebInspector.searchResultsResizerDragEnd, event, "row-resize");
-}
-
-WebInspector.searchResultsResizerDragEnd = function(event)
-{
- WebInspector.elementDragEnd(document.getElementById("searchResults"), WebInspector.searchResultsResizerDrag, WebInspector.searchResultsResizerDragEnd, event);
-}
-
-WebInspector.searchResultsResizerDrag = function(event)
-{
- var y = event.pageY - document.getElementById("main").offsetTop;
- var newHeight = Number.constrain(y, 100, window.innerHeight - 100);
-
- WebInspector.searchResultsHeight = newHeight;
-
- document.getElementById("searchResults").style.height = WebInspector.searchResultsHeight + "px";
- document.getElementById("panels").style.top = newHeight + "px";
- document.getElementById("searchResultsResizer").style.top = (newHeight - 3) + "px";
-
- event.preventDefault();
-}
-
-WebInspector.elementDragStart = function(element, dividerDrag, elementDragEnd, event, cursor)
-{
- if (WebInspector.draggingElement)
- return elementDragEnd(event);
-
- WebInspector.draggingElement = true;
-
- document.addEventListener("mousemove", dividerDrag, true);
- document.addEventListener("mouseup", elementDragEnd, true);
- document.body.style.cursor = cursor;
-
- event.preventDefault();
-}
-
-WebInspector.elementDragEnd = function(element, dividerDrag, elementDragEnd, event)
-{
- document.removeEventListener("mousemove", dividerDrag, true);
- document.removeEventListener("mouseup", elementDragEnd, true);
- document.body.style.removeProperty("cursor");
-
- delete WebInspector.draggingElement;
-
- event.preventDefault();
-}
-
-WebInspector.back = function()
-{
- if (this.currentBackForwardIndex <= 0) {
- console.error("Can't go back from index " + this.currentBackForwardIndex);
- return;
- }
-
- this.navigateToPanel(this.backForwardList[--this.currentBackForwardIndex], null, true);
-}
-
-WebInspector.forward = function()
-{
- if (this.currentBackForwardIndex >= this.backForwardList.length - 1) {
- console.error("Can't go forward from index " + this.currentBackForwardIndex);
- return;
- }
-
- this.navigateToPanel(this.backForwardList[++this.currentBackForwardIndex], null, true);
-}
-
-WebInspector.updateBackForwardButtons = function()
-{
- var index = this.currentBackForwardIndex;
-
- document.getElementById("back").disabled = index <= 0;
- document.getElementById("forward").disabled = index >= this.backForwardList.length - 1;
-}
-
-WebInspector.showConsole = function()
-{
- this.navigateToPanel(WebInspector.consolePanel);
-}
-
-WebInspector.showTimeline = function()
-{
- this.navigateToPanel(WebInspector.networkPanel);
-}
-
-WebInspector.addResource = function(resource)
-{
- this.resources.push(resource);
-
- if (resource.mainResource)
- this.mainResource = resource;
-
- if (resource.url) {
- this.resourceURLMap[resource.url] = resource;
- this.networkPanel.addResourceToTimeline(resource);
- }
-}
-
-WebInspector.removeResource = function(resource)
-{
- resource.detach();
-
- resource.category.removeResource(resource);
-
- if (resource.url)
- delete this.resourceURLMap[resource.url];
-
- var resourcesLength = this.resources.length;
- for (var i = 0; i < resourcesLength; ++i) {
- if (this.resources[i] === resource) {
- this.resources.splice(i, 1);
- break;
- }
- }
-}
-
-WebInspector.clearResources = function()
-{
- for (var category in this.resourceCategories)
- this.resourceCategories[category].removeAllResources();
- this.resources = [];
- this.backForwardList = [];
- this.currentBackForwardIndex = -1;
- delete this.mainResource;
-}
-
-WebInspector.clearDatabaseResources = function()
-{
- this.resourceCategories.databases.removeAllResources();
-}
-
-WebInspector.resourceURLChanged = function(resource, oldURL)
-{
- delete this.resourceURLMap[oldURL];
- this.resourceURLMap[resource.url] = resource;
-}
-
-WebInspector.addMessageToConsole = function(msg)
-{
- this.consolePanel.addMessage(msg);
- switch (msg.level) {
- case WebInspector.ConsoleMessage.MessageLevel.Warning:
- ++this.consoleListItem.warnings;
- break;
- case WebInspector.ConsoleMessage.MessageLevel.Error:
- ++this.consoleListItem.errors;
- break;
- }
-}
-
-WebInspector.clearConsoleMessages = function()
-{
- this.consolePanel.clearMessages();
- this.consoleListItem.warnings = this.consoleListItem.errors = 0;
-}
-
-WebInspector.clearNetworkTimeline = function()
-{
- if (this._networkPanel)
- this._networkPanel.clearTimeline();
-}
-
-WebInspector.drawLoadingPieChart = function(canvas, percent) {
- var g = canvas.getContext("2d");
- var darkColor = "rgb(122, 168, 218)";
- var lightColor = "rgb(228, 241, 251)";
- var cx = 8;
- var cy = 8;
- var r = 7;
-
- g.beginPath();
- g.arc(cx, cy, r, 0, Math.PI * 2, false);
- g.closePath();
-
- g.lineWidth = 1;
- g.strokeStyle = darkColor;
- g.fillStyle = lightColor;
- g.fill();
- g.stroke();
-
- var startangle = -Math.PI / 2;
- var endangle = startangle + (percent * Math.PI * 2);
-
- g.beginPath();
- g.moveTo(cx, cy);
- g.arc(cx, cy, r, startangle, endangle, false);
- g.closePath();
-
- g.fillStyle = darkColor;
- g.fill();
-}
-
-WebInspector.updateFocusedNode = function(node)
-{
- if (!node)
- // FIXME: Should we deselect if null is passed in?
- return;
-
- for (var i = 0; i < this.resourceCategories.documents.resources.length; ++i) {
- var resource = this.resourceCategories.documents.resources[i];
- if (resource.documentNode !== node.ownerDocument)
- continue;
-
- this.navigateToPanel(resource.panel, "dom");
- resource.panel.focusedDOMNode = node;
-
- this.currentFocusElement = document.getElementById("main");
-
- break;
- }
-}
-
-WebInspector.resourceForURL = function(url)
-{
- for (var resourceURL in this.resourceURLMap) {
- if (resourceURL.hasSubstring(url))
- return this.resourceURLMap[resourceURL];
- }
-
- return null;
-}
-
-WebInspector.showResourceForURL = function(url)
-{
- var resource = this.resourceForURL(url);
- if (!resource)
- return false;
-
- this.navigateToResource(resource);
- return true;
-}
-
-WebInspector.linkifyURL = function(url, linkText, classes, isExternal)
-{
- if (linkText === undefined)
- linkText = url.escapeHTML();
- classes = (classes === undefined) ? "" : classes + " ";
- classes += isExternal ? "webkit-html-external-link" : "webkit-html-resource-link";
- var link = "<a href=\"" + url + "\" class=\"" + classes + "\" title=\"" + url + "\" target=\"_blank\">" + linkText + "</a>";
- return link;
-}
-
-WebInspector.addMainEventListeners = function(doc)
-{
- doc.defaultView.addEventListener("focus", function(event) { WebInspector.windowFocused(event) }, true);
- doc.defaultView.addEventListener("blur", function(event) { WebInspector.windowBlured(event) }, true);
- doc.addEventListener("click", function(event) { WebInspector.documentClick(event) }, true);
-}
-
-WebInspector.performSearch = function(query)
-{
- if (!query || !query.length) {
- this.showingSearchResults = false;
- return;
- }
-
- var resultsContainer = document.getElementById("searchResults");
- resultsContainer.removeChildren();
-
- var isXPath = query.indexOf("/") !== -1;
-
- var xpathQuery;
- if (isXPath)
- xpathQuery = query;
- else {
- var escapedQuery = query.escapeCharacters("'");
- xpathQuery = "//*[contains(name(),'" + escapedQuery + "') or contains(@*,'" + escapedQuery + "')] | //text()[contains(.,'" + escapedQuery + "')] | //comment()[contains(.,'" + escapedQuery + "')]";
- }
-
- var resourcesToSearch = [].concat(this.resourceCategories.documents.resources, this.resourceCategories.stylesheets.resources, this.resourceCategories.scripts.resources, this.resourceCategories.other.resources);
-
- var files = [];
- for (var i = 0; i < resourcesToSearch.length; ++i) {
- var resource = resourcesToSearch[i];
-
- var sourceResults = [];
- if (!isXPath && "source" in resource.panel.views) {
- resource.panel.setupSourceFrameIfNeeded();
- sourceResults = InspectorController.search(resource.panel.views.source.frameElement.contentDocument, query);
- }
-
- var domResults = [];
- const searchResultsProperty = "__includedInInspectorSearchResults";
- function addNodesToDOMResults(nodes, length, getItem)
- {
- for (var i = 0; i < length; ++i) {
- var node = getItem(nodes, i);
- if (searchResultsProperty in node)
- continue;
- node[searchResultsProperty] = true;
- domResults.push(node);
- }
- }
-
- function cleanUpDOMResultsNodes()
- {
- for (var i = 0; i < domResults.length; ++i)
- delete domResults[i][searchResultsProperty];
- }
-
- if (resource.category === this.resourceCategories.documents) {
- var doc = resource.documentNode;
- try {
- var result = Document.prototype.evaluate.call(doc, xpathQuery, doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
- addNodesToDOMResults(result, result.snapshotLength, function(l, i) { return l.snapshotItem(i); });
- } catch(err) {
- // ignore any exceptions. the query might be malformed, but we allow that.
- }
-
- var result = Document.prototype.querySelectorAll.call(doc, query);
- addNodesToDOMResults(result, result.length, function(l, i) { return l.item(i); });
-
- cleanUpDOMResultsNodes();
- }
-
- if ((!sourceResults || !sourceResults.length) && !domResults.length)
- continue;
-
- files.push({resource: resource, sourceResults: sourceResults, domResults: domResults});
- }
-
- if (!files.length)
- return;
-
- this.showingSearchResults = true;
-
- var fileList = document.createElement("ol");
- fileList.className = "outline-disclosure";
- resultsContainer.appendChild(fileList);
-
- this.searchResultsTree = new TreeOutline(fileList);
- this.searchResultsTree.expandTreeElementsWhenArrowing = true;
-
- var sourceResultSelected = function(element)
- {
- var selection = window.getSelection();
- selection.removeAllRanges();
- selection.addRange(element.representedObject.range);
-
- WebInspector.navigateToPanel(element.representedObject.panel, "source");
- element.representedObject.line.scrollIntoView(true);
- resultsContainer.scrollToElement(element.listItemElement);
- }
-
- var domResultSelected = function(element)
- {
- WebInspector.navigateToPanel(element.representedObject.panel, "dom");
- element.representedObject.panel.focusedDOMNode = element.representedObject.node;
- resultsContainer.scrollToElement(element.listItemElement);
- }
-
- for (var i = 0; i < files.length; ++i) {
- var file = files[i];
-
- var fileItem = new TreeElement(file.resource.displayName, {}, true);
- fileItem.expanded = true;
- fileItem.selectable = false;
- this.searchResultsTree.appendChild(fileItem);
-
- if (file.sourceResults && file.sourceResults.length) {
- for (var j = 0; j < file.sourceResults.length; ++j) {
- var range = file.sourceResults[j];
-
- var line = range.startContainer;
- while (line.parentNode && line.nodeName.toLowerCase() != "tr")
- line = line.parentNode;
- var lineRange = file.resource.panel.views.source.frameElement.contentDocument.createRange();
- lineRange.selectNodeContents(line);
-
- // Don't include any error bubbles in the search result
- var end = line.lastChild.lastChild;
- if (end.nodeName.toLowerCase() == "div" && end.hasStyleClass("webkit-html-message-bubble")) {
- while (end && end.nodeName.toLowerCase() == "div" && end.hasStyleClass("webkit-html-message-bubble"))
- end = end.previousSibling;
- lineRange.setEndAfter(end);
- }
-
- var beforeRange = file.resource.panel.views.source.frameElement.contentDocument.createRange();
- beforeRange.setStart(lineRange.startContainer, lineRange.startOffset);
- beforeRange.setEnd(range.startContainer, range.startOffset);
-
- var afterRange = file.resource.panel.views.source.frameElement.contentDocument.createRange();
- afterRange.setStart(range.endContainer, range.endOffset);
- afterRange.setEnd(lineRange.endContainer, lineRange.endOffset);
-
- var beforeText = beforeRange.toString().trimLeadingWhitespace();
- var text = range.toString();
- var afterText = afterRange.toString().trimTrailingWhitespace();
-
- var length = beforeText.length + text.length + afterText.length;
- if (length > Preferences.maxTextSearchResultLength) {
- var beforeAfterLength = (Preferences.maxTextSearchResultLength - text.length) / 2;
- if (beforeText.length > beforeAfterLength)
- beforeText = "\u2026" + beforeText.substr(-beforeAfterLength);
- if (afterText.length > beforeAfterLength)
- afterText = afterText.substr(0, beforeAfterLength) + "\u2026";
- }
-
- var title = "<div class=\"selection selected\"></div>";
- if (j == 0)
- title += "<div class=\"search-results-section\">" + WebInspector.UIString("Source") + "</div>";
- title += beforeText.escapeHTML() + "<span class=\"search-matched-string\">" + text.escapeHTML() + "</span>" + afterText.escapeHTML();
- var item = new TreeElement(title, {panel: file.resource.panel, line: line, range: range}, false);
- item.onselect = sourceResultSelected;
- fileItem.appendChild(item);
- }
- }
-
- if (file.domResults.length) {
- for (var j = 0; j < file.domResults.length; ++j) {
- var node = file.domResults[j];
- var title = "<div class=\"selection selected\"></div>";
- if (j == 0)
- title += "<div class=\"search-results-section\">" + WebInspector.UIString("DOM") + "</div>";
- title += nodeTitleInfo.call(node).title;
- var item = new TreeElement(title, {panel: file.resource.panel, node: node}, false);
- item.onselect = domResultSelected;
- fileItem.appendChild(item);
- }
- }
- }
-}
-
-WebInspector.navigateToResource = function(resource)
-{
- this.navigateToPanel(resource.panel);
-}
-
-WebInspector.navigateToPanel = function(panel, view, fromBackForwardAction)
-{
- if (this.currentPanel === panel) {
- if (panel && view)
- panel.currentView = view;
- return;
- }
-
- if (!fromBackForwardAction) {
- var oldIndex = this.currentBackForwardIndex;
- if (oldIndex >= 0)
- this.backForwardList.splice(oldIndex + 1, this.backForwardList.length - oldIndex);
- this.currentBackForwardIndex++;
- this.backForwardList.push(panel);
- }
-
- this.currentPanel = panel;
- if (panel && view)
- panel.currentView = view;
-}
-
-WebInspector.UIString = function(string)
-{
- if (string in this.localizedStrings)
- string = this.localizedStrings[string];
- else {
- if (!(string in this.missingLocalizedStrings)) {
- console.error("Localized string \"" + string + "\" not found.");
- this.missingLocalizedStrings[string] = true;
- }
-
- if (Preferences.showMissingLocalizedStrings)
- string += " (not localized)";
- }
-
- return String.vsprintf(string, Array.prototype.slice.call(arguments, 1));
-}
-
-WebInspector.StatusTreeElement = function(title, iconClass, panel)
-{
- TreeElement.call(this, "<span class=\"title only\">" + title + "</span><span class=\"icon " + iconClass + "\"></span>", null, false);
- this.panel = panel;
-}
-
-WebInspector.StatusTreeElement.prototype = {
- onselect: function()
- {
- var selectedElement = WebInspector.fileOutline.selectedTreeElement;
- if (selectedElement)
- selectedElement.deselect();
- if (this.panel)
- WebInspector.navigateToPanel(this.panel);
- },
-
- ondeselect: function()
- {
- if (this.panel)
- this.panel.hide();
- }
-}
-
-WebInspector.StatusTreeElement.prototype.__proto__ = TreeElement.prototype;
-
-WebInspector.ConsoleStatusTreeElement = function(panel)
-{
- WebInspector.StatusTreeElement.call(this, WebInspector.UIString("Console"), "console", panel);
-}
-
-WebInspector.ConsoleStatusTreeElement.prototype = {
- get warnings()
- {
- if (!("_warnings" in this))
- this._warnings = 0;
-
- return this._warnings;
- },
-
- set warnings(x)
- {
- if (this._warnings === x)
- return;
-
- this._warnings = x;
-
- this._updateTitle();
- },
-
- get errors()
- {
- if (!("_errors" in this))
- this._errors = 0;
-
- return this._errors;
- },
-
- set errors(x)
- {
- if (this._errors === x)
- return;
-
- this._errors = x;
-
- this._updateTitle();
- },
-
- _updateTitle: function()
- {
- var title = "<span class=\"title";
- if (!this.warnings && !this.errors)
- title += " only";
- title += "\">" + WebInspector.UIString("Console") + "</span><span class=\"icon console\"></span>";
-
- if (this.warnings || this.errors) {
- title += "<span class=\"info\">";
- if (this.errors) {
- title += this.errors + " error";
- if (this.errors > 1)
- title += "s";
- }
- if (this.warnings) {
- if (this.errors)
- title += ", ";
- title += this.warnings + " warning";
- if (this.warnings > 1)
- title += "s";
- }
- title += "</span>";
- }
-
- this.title = title;
- }
-}
-
-WebInspector.ConsoleStatusTreeElement.prototype.__proto__ = WebInspector.StatusTreeElement.prototype;
-
-// This table maps MIME types to the Resource.Types which are valid for them.
-// The following line:
-// "text/html": {0: 1},
-// means that text/html is a valid MIME type for resources that have type
-// WebInspector.Resource.Type.Document (which has a value of 0).
-WebInspector.MIMETypes = {
- "text/html": {0: true},
- "text/xml": {0: true},
- "text/plain": {0: true},
- "application/xhtml+xml": {0: true},
- "text/css": {1: true},
- "text/xsl": {1: true},
- "image/jpeg": {2: true},
- "image/png": {2: true},
- "image/gif": {2: true},
- "image/bmp": {2: true},
- "image/x-icon": {2: true},
- "image/x-xbitmap": {2: true},
- "font/ttf": {3: true},
- "font/opentype": {3: true},
- "application/x-font-type1": {3: true},
- "application/x-font-ttf": {3: true},
- "application/x-truetype-font": {3: true},
- "text/javascript": {4: true},
- "text/ecmascript": {4: true},
- "application/javascript": {4: true},
- "application/ecmascript": {4: true},
- "application/x-javascript": {4: true},
- "text/javascript1.1": {4: true},
- "text/javascript1.2": {4: true},
- "text/javascript1.3": {4: true},
- "text/jscript": {4: true},
- "text/livescript": {4: true},
-}
diff --git a/WebCore/page/inspector/treeoutline.js b/WebCore/page/inspector/treeoutline.js
deleted file mode 100644
index 228136a..0000000
--- a/WebCore/page/inspector/treeoutline.js
+++ /dev/null
@@ -1,728 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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.
- */
-
-function TreeOutline(listNode)
-{
- this.children = [];
- this.selectedTreeElement = null;
- this._childrenListNode = listNode;
- this._childrenListNode.removeChildren();
- this._knownTreeElements = [];
- this._treeElementsExpandedState = [];
- this.expandTreeElementsWhenArrowing = false;
- this.root = true;
- this.hasChildren = false;
- this.expanded = true;
- this.selected = false;
- this.treeOutline = this;
-}
-
-TreeOutline._knownTreeElementNextIdentifier = 1;
-
-TreeOutline._appendChild = function(child)
-{
- if (!child)
- throw("child can't be undefined or null");
-
- var lastChild = this.children[this.children.length - 1];
- if (lastChild) {
- lastChild.nextSibling = child;
- child.previousSibling = lastChild;
- } else {
- child.previousSibling = null;
- child.nextSibling = null;
- }
-
- this.children.push(child);
- this.hasChildren = true;
- child.parent = this;
- child.treeOutline = this.treeOutline;
- child.treeOutline._rememberTreeElement(child);
-
- var current = child.children[0];
- while (current) {
- current.treeOutline = this.treeOutline;
- current.treeOutline._rememberTreeElement(current);
- current = current.traverseNextTreeElement(false, child, true);
- }
-
- if (child.hasChildren && child.treeOutline._treeElementsExpandedState[child.identifier] !== undefined)
- child.expanded = child.treeOutline._treeElementsExpandedState[child.identifier];
-
- if (!this._childrenListNode) {
- this._childrenListNode = this.treeOutline._childrenListNode.ownerDocument.createElement("ol");
- this._childrenListNode.parentTreeElement = this;
- this._childrenListNode.addStyleClass("children");
- if (this.hidden)
- this._childrenListNode.addStyleClass("hidden");
- }
-
- child._attach();
-}
-
-TreeOutline._insertChild = function(child, index)
-{
- if (!child)
- throw("child can't be undefined or null");
-
- var previousChild = (index > 0 ? this.children[index - 1] : null);
- if (previousChild) {
- previousChild.nextSibling = child;
- child.previousSibling = previousChild;
- } else {
- child.previousSibling = null;
- }
-
- var nextChild = this.children[index];
- if (nextChild) {
- nextChild.previousSibling = child;
- child.nextSibling = nextChild;
- } else {
- child.nextSibling = null;
- }
-
- this.children.splice(index, 0, child);
- this.hasChildren = true;
- child.parent = this;
- child.treeOutline = this.treeOutline;
- child.treeOutline._rememberTreeElement(child);
-
- var current = child.children[0];
- while (current) {
- current.treeOutline = this.treeOutline;
- current.treeOutline._rememberTreeElement(current);
- current = current.traverseNextTreeElement(false, child, true);
- }
-
- if (child.hasChildren && child.treeOutline._treeElementsExpandedState[child.identifier] !== undefined)
- child.expanded = child.treeOutline._treeElementsExpandedState[child.identifier];
-
- if (!this._childrenListNode) {
- this._childrenListNode = this.treeOutline._childrenListNode.ownerDocument.createElement("ol");
- this._childrenListNode.parentTreeElement = this;
- this._childrenListNode.addStyleClass("children");
- if (this.hidden)
- this._childrenListNode.addStyleClass("hidden");
- }
-
- child._attach();
-}
-
-TreeOutline._removeChild = function(child)
-{
- if (!child)
- throw("child can't be undefined or null");
-
- for (var i = 0; i < this.children.length; ++i) {
- if (this.children[i] === child) {
- this.children.splice(i, 1);
- break;
- }
- }
-
- child.deselect();
-
- if (child.previousSibling)
- child.previousSibling.nextSibling = child.nextSibling;
- if (child.nextSibling)
- child.nextSibling.previousSibling = child.previousSibling;
-
- if (child.treeOutline)
- child.treeOutline._forgetTreeElement(child);
- child._detach();
- child.treeOutline = null;
- child.parent = null;
- child.nextSibling = null;
- child.previousSibling = null;
-}
-
-TreeOutline._removeChildren = function()
-{
- for (var i = 0; i < this.children.length; ++i) {
- var child = this.children[i];
- child.deselect();
- if (child.treeOutline)
- child.treeOutline._forgetTreeElement(child);
- child._detach();
- child.treeOutline = null;
- child.parent = null;
- child.nextSibling = null;
- child.previousSibling = null;
- }
-
- this.children = [];
-
- if (this._childrenListNode)
- this._childrenListNode.offsetTop; // force layout
-}
-
-TreeOutline._removeChildrenRecursive = function()
-{
- var childrenToRemove = this.children;
-
- var child = this.children[0];
- while (child) {
- if (child.children.length)
- childrenToRemove = childrenToRemove.concat(child.children);
- child = child.traverseNextTreeElement(false, this, true);
- }
-
- for (var i = 0; i < childrenToRemove.length; ++i) {
- var child = childrenToRemove[i];
- child.deselect();
- if (child.treeOutline)
- child.treeOutline._forgetTreeElement(child);
- child._detach();
- child.children = [];
- child.treeOutline = null;
- child.parent = null;
- child.nextSibling = null;
- child.previousSibling = null;
- }
-
- this.children = [];
-}
-
-TreeOutline.prototype._rememberTreeElement = function(element)
-{
- if (!this._knownTreeElements[element.identifier])
- this._knownTreeElements[element.identifier] = [];
-
- // check if the element is already known
- var elements = this._knownTreeElements[element.identifier];
- for (var i = 0; i < elements.length; ++i)
- if (elements[i] === element)
- return;
-
- // add the element
- elements.push(element);
-}
-
-TreeOutline.prototype._forgetTreeElement = function(element)
-{
- if (!this._knownTreeElements[element.identifier])
- return;
-
- var elements = this._knownTreeElements[element.identifier];
- for (var i = 0; i < elements.length; ++i) {
- if (elements[i] === element) {
- elements.splice(i, 1);
- break;
- }
- }
-}
-
-TreeOutline.prototype.findTreeElement = function(representedObject, isAncestor, getParent)
-{
- if (!representedObject)
- return null;
-
- if ("__treeElementIdentifier" in representedObject) {
- var elements = this._knownTreeElements[representedObject.__treeElementIdentifier];
- if (elements) {
- for (var i = 0; i < elements.length; ++i)
- if (elements[i].representedObject === representedObject)
- return elements[i];
- }
- }
-
- if (!isAncestor || !(isAncestor instanceof Function) || !getParent || !(getParent instanceof Function))
- return null;
-
- var item;
- var found = false;
- for (var i = 0; i < this.children.length; ++i) {
- item = this.children[i];
- if (item.representedObject === representedObject || isAncestor(item.representedObject, representedObject)) {
- found = true;
- break;
- }
- }
-
- if (!found)
- return null;
-
- var ancestors = [];
- var currentObject = representedObject;
- while (currentObject) {
- ancestors.unshift(currentObject);
- if (currentObject === item.representedObject)
- break;
- currentObject = getParent(currentObject);
- }
-
- for (var i = 0; i < ancestors.length; ++i) {
- item = this.findTreeElement(ancestors[i], isAncestor, getParent);
- if (ancestors[i] !== representedObject && item && item.onpopulate)
- item.onpopulate(item);
- }
-
- return item;
-}
-
-TreeOutline.prototype.handleKeyEvent = function(event)
-{
- if (!this.selectedTreeElement || event.shiftKey || event.metaKey || event.ctrlKey)
- return false;
-
- var handled = false;
- var nextSelectedElement;
- if (event.keyIdentifier === "Up" && !event.altKey) {
- nextSelectedElement = this.selectedTreeElement.traversePreviousTreeElement(true);
- while (nextSelectedElement && !nextSelectedElement.selectable)
- nextSelectedElement = nextSelectedElement.traversePreviousTreeElement(!this.expandTreeElementsWhenArrowing);
- handled = nextSelectedElement ? true : false;
- } else if (event.keyIdentifier === "Down" && !event.altKey) {
- nextSelectedElement = this.selectedTreeElement.traverseNextTreeElement(true);
- while (nextSelectedElement && !nextSelectedElement.selectable)
- nextSelectedElement = nextSelectedElement.traverseNextTreeElement(!this.expandTreeElementsWhenArrowing);
- handled = nextSelectedElement ? true : false;
- } else if (event.keyIdentifier === "Left") {
- if (this.selectedTreeElement.expanded) {
- if (event.altKey)
- this.selectedTreeElement.collapseRecursively();
- else
- this.selectedTreeElement.collapse();
- handled = true;
- } else if (this.selectedTreeElement.parent && !this.selectedTreeElement.parent.root) {
- handled = true;
- if (this.selectedTreeElement.parent.selectable) {
- nextSelectedElement = this.selectedTreeElement.parent;
- handled = nextSelectedElement ? true : false;
- } else if (this.selectedTreeElement.parent)
- this.selectedTreeElement.parent.collapse();
- }
- } else if (event.keyIdentifier === "Right") {
- if (!this.selectedTreeElement.revealed()) {
- this.selectedTreeElement.reveal();
- handled = true;
- } else if (this.selectedTreeElement.hasChildren) {
- handled = true;
- if (this.selectedTreeElement.expanded) {
- nextSelectedElement = this.selectedTreeElement.children[0];
- handled = nextSelectedElement ? true : false;
- } else {
- if (event.altKey)
- this.selectedTreeElement.expandRecursively();
- else
- this.selectedTreeElement.expand();
- }
- }
- }
-
- if (nextSelectedElement) {
- nextSelectedElement.reveal();
- nextSelectedElement.select();
- }
-
- if (handled) {
- event.preventDefault();
- event.stopPropagation();
- }
-
- return handled;
-}
-
-TreeOutline.prototype.expand = function()
-{
- // this is the root, do nothing
-}
-
-TreeOutline.prototype.collapse = function()
-{
- // this is the root, do nothing
-}
-
-TreeOutline.prototype.revealed = function()
-{
- return true;
-}
-
-TreeOutline.prototype.reveal = function()
-{
- // this is the root, do nothing
-}
-
-TreeOutline.prototype.appendChild = TreeOutline._appendChild;
-TreeOutline.prototype.insertChild = TreeOutline._insertChild;
-TreeOutline.prototype.removeChild = TreeOutline._removeChild;
-TreeOutline.prototype.removeChildren = TreeOutline._removeChildren;
-TreeOutline.prototype.removeChildrenRecursive = TreeOutline._removeChildrenRecursive;
-
-function TreeElement(title, representedObject, hasChildren)
-{
- this._title = title;
- this.representedObject = (representedObject || {});
-
- if (this.representedObject.__treeElementIdentifier)
- this.identifier = this.representedObject.__treeElementIdentifier;
- else {
- this.identifier = TreeOutline._knownTreeElementNextIdentifier++;
- this.representedObject.__treeElementIdentifier = this.identifier;
- }
-
- this._hidden = false;
- this.expanded = false;
- this.selected = false;
- this.hasChildren = hasChildren;
- this.children = [];
- this.treeOutline = null;
- this.parent = null;
- this.previousSibling = null;
- this.nextSibling = null;
- this._listItemNode = null;
-}
-
-TreeElement.prototype = {
- selectable: true,
- arrowToggleWidth: 10,
-
- get listItemElement() {
- return this._listItemNode;
- },
-
- get childrenListElement() {
- return this._childrenListNode;
- },
-
- get title() {
- return this._title;
- },
-
- set title(x) {
- this._title = x;
- if (this._listItemNode)
- this._listItemNode.innerHTML = x;
- },
-
- get tooltip() {
- return this._tooltip;
- },
-
- set tooltip(x) {
- this._tooltip = x;
- if (this._listItemNode)
- this._listItemNode.title = x ? x : "";
- },
-
- get hidden() {
- return this._hidden;
- },
-
- set hidden(x) {
- if (this._hidden === x)
- return;
-
- this._hidden = x;
-
- if (x) {
- if (this._listItemNode)
- this._listItemNode.addStyleClass("hidden");
- if (this._childrenListNode)
- this._childrenListNode.addStyleClass("hidden");
- } else {
- if (this._listItemNode)
- this._listItemNode.removeStyleClass("hidden");
- if (this._childrenListNode)
- this._childrenListNode.removeStyleClass("hidden");
- }
- }
-}
-
-TreeElement.prototype.appendChild = TreeOutline._appendChild;
-TreeElement.prototype.insertChild = TreeOutline._insertChild;
-TreeElement.prototype.removeChild = TreeOutline._removeChild;
-TreeElement.prototype.removeChildren = TreeOutline._removeChildren;
-TreeElement.prototype.removeChildrenRecursive = TreeOutline._removeChildrenRecursive;
-
-TreeElement.prototype._attach = function()
-{
- if (!this._listItemNode || this.parent.refreshChildren) {
- if (this._listItemNode && this._listItemNode.parentNode)
- this._listItemNode.parentNode.removeChild(this._listItemNode);
-
- this._listItemNode = this.treeOutline._childrenListNode.ownerDocument.createElement("li");
- this._listItemNode.treeElement = this;
- this._listItemNode.innerHTML = this._title;
- this._listItemNode.title = this._tooltip ? this._tooltip : "";
-
- if (this.hidden)
- this._listItemNode.addStyleClass("hidden");
- if (this.hasChildren)
- this._listItemNode.addStyleClass("parent");
- if (this.expanded)
- this._listItemNode.addStyleClass("expanded");
- if (this.selected)
- this._listItemNode.addStyleClass("selected");
-
- this._listItemNode.addEventListener("mousedown", TreeElement.treeElementSelected, false);
- this._listItemNode.addEventListener("click", TreeElement.treeElementToggled, false);
- this._listItemNode.addEventListener("dblclick", TreeElement.treeElementDoubleClicked, false);
-
- if (this.onattach)
- this.onattach(this);
- }
-
- this.parent._childrenListNode.insertBefore(this._listItemNode, (this.nextSibling ? this.nextSibling._listItemNode : null));
- if (this._childrenListNode)
- this.parent._childrenListNode.insertBefore(this._childrenListNode, this._listItemNode.nextSibling);
- if (this.selected)
- this.select();
- if (this.expanded)
- this.expand();
-}
-
-TreeElement.prototype._detach = function()
-{
- if (this._listItemNode && this._listItemNode.parentNode)
- this._listItemNode.parentNode.removeChild(this._listItemNode);
- if (this._childrenListNode && this._childrenListNode.parentNode)
- this._childrenListNode.parentNode.removeChild(this._childrenListNode);
-}
-
-TreeElement.treeElementSelected = function(event)
-{
- var element = event.currentTarget;
- if (!element || !element.treeElement || !element.treeElement.selectable)
- return;
-
- if (event.offsetX > element.treeElement.arrowToggleWidth || !element.treeElement.hasChildren)
- element.treeElement.select();
-}
-
-TreeElement.treeElementToggled = function(event)
-{
- var element = event.currentTarget;
- if (!element || !element.treeElement)
- return;
-
- if (event.offsetX <= element.treeElement.arrowToggleWidth && element.treeElement.hasChildren) {
- if (element.treeElement.expanded) {
- if (event.altKey)
- element.treeElement.collapseRecursively();
- else
- element.treeElement.collapse();
- } else {
- if (event.altKey)
- element.treeElement.expandRecursively();
- else
- element.treeElement.expand();
- }
- }
-}
-
-TreeElement.treeElementDoubleClicked = function(event)
-{
- var element = event.currentTarget;
- if (!element || !element.treeElement)
- return;
-
- if (element.treeElement.ondblclick)
- element.treeElement.ondblclick(element.treeElement, event);
- else if (element.treeElement.hasChildren && !element.treeElement.expanded)
- element.treeElement.expand();
-}
-
-TreeElement.prototype.collapse = function()
-{
- if (this._listItemNode)
- this._listItemNode.removeStyleClass("expanded");
- if (this._childrenListNode)
- this._childrenListNode.removeStyleClass("expanded");
-
- this.expanded = false;
- if (this.treeOutline)
- this.treeOutline._treeElementsExpandedState[this.identifier] = true;
-
- if (this.oncollapse)
- this.oncollapse(this);
-}
-
-TreeElement.prototype.collapseRecursively = function()
-{
- var item = this;
- while (item) {
- if (item.expanded)
- item.collapse();
- item = item.traverseNextTreeElement(false, this, true);
- }
-}
-
-TreeElement.prototype.expand = function()
-{
- if (!this.hasChildren || (this.expanded && !this.refreshChildren && this._childrenListNode))
- return;
-
- if (!this._childrenListNode || this.refreshChildren) {
- if (this._childrenListNode && this._childrenListNode.parentNode)
- this._childrenListNode.parentNode.removeChild(this._childrenListNode);
-
- this._childrenListNode = this.treeOutline._childrenListNode.ownerDocument.createElement("ol");
- this._childrenListNode.parentTreeElement = this;
- this._childrenListNode.addStyleClass("children");
-
- if (this.hidden)
- this._childrenListNode.addStyleClass("hidden");
-
- if (this.onpopulate)
- this.onpopulate(this);
-
- for (var i = 0; i < this.children.length; ++i)
- this.children[i]._attach();
-
- delete this.refreshChildren;
- }
-
- if (this._listItemNode) {
- this._listItemNode.addStyleClass("expanded");
- if (this._childrenListNode.parentNode != this._listItemNode.parentNode)
- this.parent._childrenListNode.insertBefore(this._childrenListNode, this._listItemNode.nextSibling);
- }
-
- if (this._childrenListNode)
- this._childrenListNode.addStyleClass("expanded");
-
- this.expanded = true;
- if (this.treeOutline)
- this.treeOutline._treeElementsExpandedState[this.identifier] = true;
-
- if (this.onexpand)
- this.onexpand(this);
-}
-
-TreeElement.prototype.expandRecursively = function()
-{
- var item = this;
- while (item) {
- item.expand();
- item = item.traverseNextTreeElement(false, this);
- }
-}
-
-TreeElement.prototype.reveal = function()
-{
- var currentAncestor = this.parent;
- while (currentAncestor && !currentAncestor.root) {
- if (!currentAncestor.expanded)
- currentAncestor.expand();
- currentAncestor = currentAncestor.parent;
- }
-
- if (this.onreveal)
- this.onreveal(this);
-}
-
-TreeElement.prototype.revealed = function()
-{
- var currentAncestor = this.parent;
- while (currentAncestor && !currentAncestor.root) {
- if (!currentAncestor.expanded)
- return false;
- currentAncestor = currentAncestor.parent;
- }
-
- return true;
-}
-
-TreeElement.prototype.select = function(supressOnSelect)
-{
- if (!this.treeOutline || !this.selectable || this.selected)
- return;
-
- if (this.treeOutline.selectedTreeElement)
- this.treeOutline.selectedTreeElement.deselect();
-
- this.selected = true;
- this.treeOutline.selectedTreeElement = this;
- if (this._listItemNode)
- this._listItemNode.addStyleClass("selected");
-
- if (this.onselect && !supressOnSelect)
- this.onselect(this);
-}
-
-TreeElement.prototype.deselect = function(supressOnDeselect)
-{
- if (!this.treeOutline || this.treeOutline.selectedTreeElement !== this || !this.selected)
- return;
-
- this.selected = false;
- this.treeOutline.selectedTreeElement = null;
- if (this._listItemNode)
- this._listItemNode.removeStyleClass("selected");
-
- if (this.ondeselect && !supressOnDeselect)
- this.ondeselect(this);
-}
-
-TreeElement.prototype.traverseNextTreeElement = function(skipHidden, stayWithin, dontPopulate)
-{
- if (!dontPopulate && this.hasChildren && this.onpopulate)
- this.onpopulate(this);
-
- var element = skipHidden ? (this.revealed() ? this.children[0] : null) : this.children[0];
- if (element && (!skipHidden || (skipHidden && this.expanded)))
- return element;
-
- if (this === stayWithin)
- return null;
-
- element = skipHidden ? (this.revealed() ? this.nextSibling : null) : this.nextSibling;
- if (element)
- return element;
-
- element = this;
- while (element && !element.root && !(skipHidden ? (element.revealed() ? element.nextSibling : null) : element.nextSibling) && element.parent !== stayWithin)
- element = element.parent;
-
- if (!element)
- return null;
-
- return (skipHidden ? (element.revealed() ? element.nextSibling : null) : element.nextSibling);
-}
-
-TreeElement.prototype.traversePreviousTreeElement = function(skipHidden, dontPopulate)
-{
- var element = skipHidden ? (this.revealed() ? this.previousSibling : null) : this.previousSibling;
- if (!dontPopulate && element && element.hasChildren && element.onpopulate)
- element.onpopulate(element);
-
- while (element && (skipHidden ? (element.revealed() && element.expanded ? element.children[element.children.length - 1] : null) : element.children[element.children.length - 1])) {
- if (!dontPopulate && element.hasChildren && element.onpopulate)
- element.onpopulate(element);
- element = (skipHidden ? (element.revealed() && element.expanded ? element.children[element.children.length - 1] : null) : element.children[element.children.length - 1]);
- }
-
- if (element)
- return element;
-
- if (!this.parent || this.parent.root)
- return null;
-
- return this.parent;
-}
diff --git a/WebCore/page/inspector/utilities.js b/WebCore/page/inspector/utilities.js
deleted file mode 100644
index a92fe4d..0000000
--- a/WebCore/page/inspector/utilities.js
+++ /dev/null
@@ -1,787 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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.
- */
-
-Object.type = function(obj)
-{
- if (obj === null)
- return "null";
-
- var type = typeof obj;
- if (type !== "object" && type !== "function")
- return type;
-
- if (obj instanceof String)
- return "string";
- if (obj instanceof Array)
- return "array";
- if (obj instanceof Boolean)
- return "boolean";
- if (obj instanceof Number)
- return "number";
- if (obj instanceof Date)
- return "date";
- if (obj instanceof RegExp)
- return "regexp";
- if (obj instanceof Error)
- return "error";
- return type;
-}
-
-Object.describe = function(obj, abbreviated)
-{
- switch (Object.type(obj)) {
- case "object":
- return Object.prototype.toString.call(obj).replace(/^\[object (.*)\]$/i, "$1");
- case "array":
- return "[" + obj.toString() + "]";
- case "string":
- if (obj.length > 100)
- return "\"" + obj.substring(0, 100) + "\u2026\"";
- return "\"" + obj + "\"";
- case "function":
- var objectText = String(obj);
- if (!/^function /.test(objectText))
- objectText = (type2 == "object") ? type1 : type2;
- else if (abbreviated)
- objectText = /.*/.exec(obj)[0].replace(/ +$/g, "");
- return objectText;
- case "regexp":
- return String(obj).replace(/([\\\/])/g, "\\$1").replace(/\\(\/[gim]*)$/, "$1").substring(1);
- default:
- return String(obj);
- }
-}
-
-Object.sortedProperties = function(obj)
-{
- var properties = [];
- for (var prop in obj)
- properties.push(prop);
- properties.sort();
- return properties;
-}
-
-Function.prototype.bind = function(thisObject)
-{
- var func = this;
- var args = Array.prototype.slice.call(arguments, 1);
- return function() { return func.apply(thisObject, args.concat(Array.prototype.slice.call(arguments, 0))) };
-}
-
-Element.prototype.removeStyleClass = function(className)
-{
- // Test for the simple case before using a RegExp.
- if (this.className === className) {
- this.className = "";
- return;
- }
-
- var regex = new RegExp("(^|\\s+)" + className.escapeForRegExp() + "($|\\s+)");
- if (regex.test(this.className))
- this.className = this.className.replace(regex, " ");
-}
-
-Element.prototype.addStyleClass = function(className)
-{
- if (className && !this.hasStyleClass(className))
- this.className += (this.className.length ? " " + className : className);
-}
-
-Element.prototype.hasStyleClass = function(className)
-{
- if (!className)
- return false;
- // Test for the simple case before using a RegExp.
- if (this.className === className)
- return true;
- var regex = new RegExp("(^|\\s)" + className.escapeForRegExp() + "($|\\s)");
- return regex.test(this.className);
-}
-
-Element.prototype.scrollToElement = function(element)
-{
- if (!element || !this.isAncestor(element))
- return;
-
- var offsetTop = 0;
- var current = element
- while (current && current !== this) {
- offsetTop += current.offsetTop;
- current = current.offsetParent;
- }
-
- if (this.scrollTop > offsetTop)
- this.scrollTop = offsetTop;
- else if ((this.scrollTop + this.offsetHeight) < (offsetTop + element.offsetHeight))
- this.scrollTop = offsetTop - this.offsetHeight + element.offsetHeight;
-}
-
-Node.prototype.firstParentOrSelfWithNodeName = function(nodeName)
-{
- for (var node = this; node && (node !== document); node = node.parentNode)
- if (node.nodeName.toLowerCase() === nodeName.toLowerCase())
- return node;
- return null;
-}
-
-Node.prototype.firstParentOrSelfWithClass = function(className)
-{
- for (var node = this; node && (node !== document); node = node.parentNode)
- if (node.nodeType === Node.ELEMENT_NODE && node.hasStyleClass(className))
- return node;
- return null;
-}
-
-Node.prototype.firstParentWithClass = function(className)
-{
- if (!this.parentNode)
- return null;
- return this.parentNode.firstParentOrSelfWithClass(className);
-}
-
-Element.prototype.query = function(query)
-{
- return document.evaluate(query, this, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
-}
-
-Element.prototype.removeChildren = function()
-{
- while (this.firstChild)
- this.removeChild(this.firstChild);
-}
-
-Element.prototype.firstChildSkippingWhitespace = firstChildSkippingWhitespace;
-Element.prototype.lastChildSkippingWhitespace = lastChildSkippingWhitespace;
-
-Node.prototype.isWhitespace = isNodeWhitespace;
-Node.prototype.nodeTypeName = nodeTypeName;
-Node.prototype.displayName = nodeDisplayName;
-Node.prototype.contentPreview = nodeContentPreview;
-Node.prototype.isAncestor = isAncestorNode;
-Node.prototype.isDescendant = isDescendantNode;
-Node.prototype.firstCommonAncestor = firstCommonNodeAncestor;
-Node.prototype.nextSiblingSkippingWhitespace = nextSiblingSkippingWhitespace;
-Node.prototype.previousSiblingSkippingWhitespace = previousSiblingSkippingWhitespace;
-Node.prototype.traverseNextNode = traverseNextNode;
-Node.prototype.traversePreviousNode = traversePreviousNode;
-Node.prototype.onlyTextChild = onlyTextChild;
-Node.prototype.titleInfo = nodeTitleInfo;
-
-String.prototype.hasSubstring = function(string, caseInsensitive)
-{
- if (!caseInsensitive)
- return this.indexOf(string) !== -1;
- return this.match(new RegExp(string.escapeForRegExp(), "i"));
-}
-
-String.prototype.escapeCharacters = function(chars)
-{
- var foundChar = false;
- for (var i = 0; i < chars.length; ++i) {
- if (this.indexOf(chars.charAt(i)) !== -1) {
- foundChar = true;
- break;
- }
- }
-
- if (!foundChar)
- return this;
-
- var result = "";
- for (var i = 0; i < this.length; ++i) {
- if (chars.indexOf(this.charAt(i)) !== -1)
- result += "\\";
- result += this.charAt(i);
- }
-
- return result;
-}
-
-String.prototype.escapeForRegExp = function()
-{
- return this.escapeCharacters("^[]{}()\\.$*+?|");
-}
-
-String.prototype.escapeHTML = function()
-{
- return this.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
-}
-
-String.prototype.collapseWhitespace = function()
-{
- return this.replace(/[\s\xA0]+/g, " ");
-}
-
-String.prototype.trimLeadingWhitespace = function()
-{
- return this.replace(/^[\s\xA0]+/g, "");
-}
-
-String.prototype.trimTrailingWhitespace = function()
-{
- return this.replace(/[\s\xA0]+$/g, "");
-}
-
-String.prototype.trimWhitespace = function()
-{
- return this.replace(/^[\s\xA0]+|[\s\xA0]+$/g, "");
-}
-
-String.prototype.trimURL = function(baseURLDomain)
-{
- var result = this.replace(new RegExp("^http[s]?:\/\/", "i"), "");
- if (baseURLDomain)
- result = result.replace(new RegExp("^" + baseURLDomain.escapeForRegExp(), "i"), "");
- return result;
-}
-
-CSSStyleDeclaration.prototype.getShorthandValue = function(shorthandProperty)
-{
- var value = this.getPropertyValue(shorthandProperty);
- if (!value) {
- // Some shorthands (like border) return a null value, so compute a shorthand value.
- // FIXME: remove this when http://bugs.webkit.org/show_bug.cgi?id=15823 is fixed.
-
- var foundProperties = {};
- for (var i = 0; i < this.length; ++i) {
- var individualProperty = this[i];
- if (individualProperty in foundProperties || this.getPropertyShorthand(individualProperty) !== shorthandProperty)
- continue;
-
- var individualValue = this.getPropertyValue(individualProperty);
- if (this.isPropertyImplicit(individualProperty) || individualValue === "initial")
- continue;
-
- foundProperties[individualProperty] = true;
-
- if (!value)
- value = "";
- else if (value.length)
- value += " ";
- value += individualValue;
- }
- }
- return value;
-}
-
-CSSStyleDeclaration.prototype.getShorthandPriority = function(shorthandProperty)
-{
- var priority = this.getPropertyPriority(shorthandProperty);
- if (!priority) {
- for (var i = 0; i < this.length; ++i) {
- var individualProperty = this[i];
- if (this.getPropertyShorthand(individualProperty) !== shorthandProperty)
- continue;
- priority = this.getPropertyPriority(individualProperty);
- break;
- }
- }
- return priority;
-}
-
-CSSStyleDeclaration.prototype.getLonghandProperties = function(shorthandProperty)
-{
- var properties = [];
- var foundProperties = {};
-
- for (var i = 0; i < this.length; ++i) {
- var individualProperty = this[i];
- if (individualProperty in foundProperties || this.getPropertyShorthand(individualProperty) !== shorthandProperty)
- continue;
- foundProperties[individualProperty] = true;
- properties.push(individualProperty);
- }
-
- return properties;
-}
-
-CSSStyleDeclaration.prototype.getUniqueProperties = function()
-{
- var properties = [];
- var foundProperties = {};
-
- for (var i = 0; i < this.length; ++i) {
- var property = this[i];
- if (property in foundProperties)
- continue;
- foundProperties[property] = true;
- properties.push(property);
- }
-
- return properties;
-}
-
-function isNodeWhitespace()
-{
- if (!this || this.nodeType !== Node.TEXT_NODE)
- return false;
- if (!this.nodeValue.length)
- return true;
- return this.nodeValue.match(/^[\s\xA0]+$/);
-}
-
-function nodeTypeName()
-{
- if (!this)
- return "(unknown)";
-
- switch (this.nodeType) {
- case Node.ELEMENT_NODE: return "Element";
- case Node.ATTRIBUTE_NODE: return "Attribute";
- case Node.TEXT_NODE: return "Text";
- case Node.CDATA_SECTION_NODE: return "Character Data";
- case Node.ENTITY_REFERENCE_NODE: return "Entity Reference";
- case Node.ENTITY_NODE: return "Entity";
- case Node.PROCESSING_INSTRUCTION_NODE: return "Processing Instruction";
- case Node.COMMENT_NODE: return "Comment";
- case Node.DOCUMENT_NODE: return "Document";
- case Node.DOCUMENT_TYPE_NODE: return "Document Type";
- case Node.DOCUMENT_FRAGMENT_NODE: return "Document Fragment";
- case Node.NOTATION_NODE: return "Notation";
- }
-
- return "(unknown)";
-}
-
-function nodeDisplayName()
-{
- if (!this)
- return "";
-
- switch (this.nodeType) {
- case Node.DOCUMENT_NODE:
- return "Document";
-
- case Node.ELEMENT_NODE:
- var name = "<" + this.nodeName.toLowerCase();
-
- if (this.hasAttributes()) {
- var value = this.getAttribute("id");
- if (value)
- name += " id=\"" + value + "\"";
- value = this.getAttribute("class");
- if (value)
- name += " class=\"" + value + "\"";
- if (this.nodeName.toLowerCase() === "a") {
- value = this.getAttribute("name");
- if (value)
- name += " name=\"" + value + "\"";
- value = this.getAttribute("href");
- if (value)
- name += " href=\"" + value + "\"";
- } else if (this.nodeName.toLowerCase() === "img") {
- value = this.getAttribute("src");
- if (value)
- name += " src=\"" + value + "\"";
- } else if (this.nodeName.toLowerCase() === "iframe") {
- value = this.getAttribute("src");
- if (value)
- name += " src=\"" + value + "\"";
- } else if (this.nodeName.toLowerCase() === "input") {
- value = this.getAttribute("name");
- if (value)
- name += " name=\"" + value + "\"";
- value = this.getAttribute("type");
- if (value)
- name += " type=\"" + value + "\"";
- } else if (this.nodeName.toLowerCase() === "form") {
- value = this.getAttribute("action");
- if (value)
- name += " action=\"" + value + "\"";
- }
- }
-
- return name + ">";
-
- case Node.TEXT_NODE:
- if (isNodeWhitespace.call(this))
- return "(whitespace)";
- return "\"" + this.nodeValue + "\"";
-
- case Node.COMMENT_NODE:
- return "<!--" + this.nodeValue + "-->";
- }
-
- return this.nodeName.toLowerCase().collapseWhitespace();
-}
-
-function nodeContentPreview()
-{
- if (!this || !this.hasChildNodes || !this.hasChildNodes())
- return "";
-
- var limit = 0;
- var preview = "";
-
- // always skip whitespace here
- var currentNode = traverseNextNode.call(this, true, this);
- while (currentNode) {
- if (currentNode.nodeType === Node.TEXT_NODE)
- preview += currentNode.nodeValue.escapeHTML();
- else
- preview += nodeDisplayName.call(currentNode).escapeHTML();
-
- currentNode = traverseNextNode.call(currentNode, true, this);
-
- if (++limit > 4) {
- preview += "&#x2026;"; // ellipsis
- break;
- }
- }
-
- return preview.collapseWhitespace();
-}
-
-function isAncestorNode(ancestor)
-{
- if (!this || !ancestor)
- return false;
-
- var currentNode = ancestor.parentNode;
- while (currentNode) {
- if (this === currentNode)
- return true;
- currentNode = currentNode.parentNode;
- }
-
- return false;
-}
-
-function isDescendantNode(descendant)
-{
- return isAncestorNode.call(descendant, this);
-}
-
-function firstCommonNodeAncestor(node)
-{
- if (!this || !node)
- return;
-
- var node1 = this.parentNode;
- var node2 = node.parentNode;
-
- if ((!node1 || !node2) || node1 !== node2)
- return null;
-
- while (node1 && node2) {
- if (!node1.parentNode || !node2.parentNode)
- break;
- if (node1 !== node2)
- break;
-
- node1 = node1.parentNode;
- node2 = node2.parentNode;
- }
-
- return node1;
-}
-
-function nextSiblingSkippingWhitespace()
-{
- if (!this)
- return;
- var node = this.nextSibling;
- while (node && node.nodeType === Node.TEXT_NODE && isNodeWhitespace.call(node))
- node = node.nextSibling;
- return node;
-}
-
-function previousSiblingSkippingWhitespace()
-{
- if (!this)
- return;
- var node = this.previousSibling;
- while (node && node.nodeType === Node.TEXT_NODE && isNodeWhitespace.call(node))
- node = node.previousSibling;
- return node;
-}
-
-function firstChildSkippingWhitespace()
-{
- if (!this)
- return;
- var node = this.firstChild;
- while (node && node.nodeType === Node.TEXT_NODE && isNodeWhitespace.call(node))
- node = nextSiblingSkippingWhitespace.call(node);
- return node;
-}
-
-function lastChildSkippingWhitespace()
-{
- if (!this)
- return;
- var node = this.lastChild;
- while (node && node.nodeType === Node.TEXT_NODE && isNodeWhitespace.call(node))
- node = previousSiblingSkippingWhitespace.call(node);
- return node;
-}
-
-function traverseNextNode(skipWhitespace, stayWithin)
-{
- if (!this)
- return;
-
- var node = skipWhitespace ? firstChildSkippingWhitespace.call(this) : this.firstChild;
- if (node)
- return node;
-
- if (stayWithin && this === stayWithin)
- return null;
-
- node = skipWhitespace ? nextSiblingSkippingWhitespace.call(this) : this.nextSibling;
- if (node)
- return node;
-
- node = this;
- while (node && !(skipWhitespace ? nextSiblingSkippingWhitespace.call(node) : node.nextSibling) && (!stayWithin || !node.parentNode || node.parentNode !== stayWithin))
- node = node.parentNode;
- if (!node)
- return null;
-
- return skipWhitespace ? nextSiblingSkippingWhitespace.call(node) : node.nextSibling;
-}
-
-function traversePreviousNode(skipWhitespace)
-{
- if (!this)
- return;
- var node = skipWhitespace ? previousSiblingSkippingWhitespace.call(this) : this.previousSibling;
- while (node && (skipWhitespace ? lastChildSkippingWhitespace.call(node) : node.lastChild) )
- node = skipWhitespace ? lastChildSkippingWhitespace.call(node) : node.lastChild;
- if (node)
- return node;
- return this.parentNode;
-}
-
-function onlyTextChild(ignoreWhitespace)
-{
- if (!this)
- return null;
-
- var firstChild = ignoreWhitespace ? firstChildSkippingWhitespace.call(this) : this.firstChild;
- if (!firstChild || firstChild.nodeType !== Node.TEXT_NODE)
- return null;
-
- var sibling = ignoreWhitespace ? nextSiblingSkippingWhitespace.call(firstChild) : firstChild.nextSibling;
- return sibling ? null : firstChild;
-}
-
-function nodeTitleInfo(hasChildren, linkify)
-{
- var info = {title: "", hasChildren: hasChildren};
-
- switch (this.nodeType) {
- case Node.DOCUMENT_NODE:
- info.title = "Document";
- break;
-
- case Node.ELEMENT_NODE:
- info.title = "<span class=\"webkit-html-tag\">&lt;" + this.nodeName.toLowerCase().escapeHTML();
-
- if (this.hasAttributes()) {
- for (var i = 0; i < this.attributes.length; ++i) {
- var attr = this.attributes[i];
- var value = attr.value.escapeHTML();
- value = value.replace(/([\/;:\)\]\}])/g, "$1&#8203;");
-
- info.title += " <span class=\"webkit-html-attribute-name\">" + attr.name.escapeHTML() + "</span>=&#8203;";
-
- if (linkify && (attr.name === "src" || attr.name === "href"))
- info.title += linkify(attr.value, value, "webkit-html-attribute-value", this.nodeName.toLowerCase() == "a");
- else
- info.title += "<span class=\"webkit-html-attribute-value\">\"" + value + "\"</span>";
- }
- }
- info.title += "&gt;</span>&#8203;";
-
- // If this element only has a single child that is a text node,
- // just show that text and the closing tag inline rather than
- // create a subtree for them
-
- var textChild = onlyTextChild.call(this, Preferences.ignoreWhitespace);
- var showInlineText = textChild && textChild.textContent.length < Preferences.maxInlineTextChildLength;
-
- if (showInlineText) {
- info.title += textChild.nodeValue.escapeHTML() + "&#8203;<span class=\"webkit-html-tag\">&lt;/" + this.nodeName.toLowerCase().escapeHTML() + "&gt;</span>";
- info.hasChildren = false;
- }
- break;
-
- case Node.TEXT_NODE:
- if (isNodeWhitespace.call(this))
- info.title = "(whitespace)";
- else
- info.title = "\"" + this.nodeValue.escapeHTML() + "\"";
- break
-
- case Node.COMMENT_NODE:
- info.title = "<span class=\"webkit-html-comment\">&lt;!--" + this.nodeValue.escapeHTML() + "--&gt;</span>";
- break;
-
- default:
- info.title = this.nodeName.toLowerCase().collapseWhitespace().escapeHTML();
- }
-
- return info;
-}
-
-Number.secondsToString = function(seconds)
-{
- var ms = seconds * 1000;
- if (ms < 1000)
- return Math.round(ms) + "ms";
-
- if (seconds < 60)
- return (Math.round(seconds * 100) / 100) + "s";
-
- var minutes = seconds / 60;
- if (minutes < 60)
- return (Math.round(minutes * 10) / 10) + "min";
-
- var hours = minutes / 60;
- if (hours < 24)
- return (Math.round(hours * 10) / 10) + "hrs";
-
- var days = hours / 24;
- return (Math.round(days * 10) / 10) + " days";
-}
-
-Number.bytesToString = function(bytes)
-{
- if (bytes < 1024)
- return bytes + "B";
-
- var kilobytes = bytes / 1024;
- if (kilobytes < 1024)
- return (Math.round(kilobytes * 100) / 100) + "KB";
-
- var megabytes = kilobytes / 1024;
- return (Math.round(megabytes * 1000) / 1000) + "MB";
-}
-
-Number.constrain = function(num, min, max)
-{
- if (num < min)
- num = min;
- else if (num > max)
- num = max;
- return num;
-}
-
-HTMLTextAreaElement.prototype.moveCursorToEnd = function()
-{
- var length = this.value.length;
- this.setSelectionRange(length, length);
-}
-
-String.sprintf = function(format)
-{
- return String.vsprintf(format, Array.prototype.slice.call(arguments, 1));
-}
-
-String.vsprintf = function(format, substitutions)
-{
- if (!format || !substitutions || !substitutions.length)
- return format;
-
- var result = "";
- var substitutionIndex = 0;
-
- var index = 0;
- for (var precentIndex = format.indexOf("%", index); precentIndex !== -1; precentIndex = format.indexOf("%", index)) {
- result += format.substring(index, precentIndex);
- index = precentIndex + 1;
-
- if (format[index] === "%") {
- result += "%";
- ++index;
- continue;
- }
-
- if (!isNaN(format[index])) {
- // The first character is a number, it might be a substitution index.
- var number = parseInt(format.substring(index));
- while (!isNaN(format[index]))
- ++index;
- // If the number is greater than zero and ends with a "$",
- // then this is a substitution index.
- if (number > 0 && format[index] === "$") {
- substitutionIndex = (number - 1);
- ++index;
- }
- }
-
- var precision = -1;
- if (format[index] === ".") {
- // This is a precision specifier. If no digit follows the ".",
- // then the precision should be zero.
- ++index;
- precision = parseInt(format.substring(index));
- if (isNaN(precision))
- precision = 0;
- while (!isNaN(format[index]))
- ++index;
- }
-
- if (substitutionIndex >= substitutions.length) {
- // If there are not enough substitutions for the current substitutionIndex
- // just output the format specifier literally and move on.
- console.error("String.vsprintf(\"" + format + "\", \"" + substitutions.join("\", \"") + "\"): not enough substitution arguments. Had " + substitutions.length + " but needed " + (substitutionIndex + 1) + ", so substitution was skipped.");
- index = precentIndex + 1;
- result += "%";
- continue;
- }
-
- switch (format[index]) {
- case "d":
- var substitution = parseInt(substitutions[substitutionIndex]);
- result += (!isNaN(substitution) ? substitution : 0);
- break;
- case "f":
- var substitution = parseFloat(substitutions[substitutionIndex]);
- if (substitution && precision > -1)
- substitution = substitution.toFixed(precision);
- result += (!isNaN(substitution) ? substitution : (precision > -1 ? Number(0).toFixed(precision) : 0));
- break;
- default:
- // Encountered an unsupported format character, treat as a string.
- console.warn("String.vsprintf(\"" + format + "\", \"" + substitutions.join("\", \"") + "\"): unsupported format character \u201C" + format[index] + "\u201D. Treating as a string.");
- // Fall through to treat this like a string.
- case "s":
- result += substitutions[substitutionIndex];
- break;
- }
-
- ++substitutionIndex;
- ++index;
- }
-
- result += format.substring(index);
-
- return result;
-}
diff --git a/WebCore/page/mac/AXObjectCacheMac.mm b/WebCore/page/mac/AXObjectCacheMac.mm
new file mode 100644
index 0000000..10ae1cc
--- /dev/null
+++ b/WebCore/page/mac/AXObjectCacheMac.mm
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "AXObjectCache.h"
+
+#import "AccessibilityObject.h"
+#import "AccessibilityObjectWrapper.h"
+#import "RenderObject.h"
+#import "WebCoreViewFactory.h"
+
+#import <wtf/PassRefPtr.h>
+
+// The simple Cocoa calls in this file don't throw exceptions.
+
+namespace WebCore {
+
+void AXObjectCache::detachWrapper(AccessibilityObject* obj)
+{
+ [obj->wrapper() detach];
+ [obj->wrapper() release];
+ obj->setWrapper(0);
+}
+
+void AXObjectCache::attachWrapper(AccessibilityObject* obj)
+{
+ obj->setWrapper([[AccessibilityObjectWrapper alloc] initWithAccessibilityObject:obj]);
+}
+
+void AXObjectCache::postNotification(RenderObject* renderer, const String& message)
+{
+ if (!renderer)
+ return;
+
+ // notifications for text input objects are sent to that object
+ // all others are sent to the top WebArea
+ RefPtr<AccessibilityObject> obj = get(renderer)->observableObject();
+ if (!obj)
+ obj = get(renderer->document()->renderer());
+
+ if (!obj)
+ return;
+
+ NSAccessibilityPostNotification(obj->wrapper(), message);
+}
+
+void AXObjectCache::postNotificationToElement(RenderObject* renderer, const String& message)
+{
+ // send the notification to the specified element itself, not one of its ancestors
+ if (!renderer)
+ return;
+
+ RefPtr<AccessibilityObject> obj = get(renderer);
+ if (!obj)
+ return;
+
+ NSAccessibilityPostNotification(obj->wrapper(), message);
+}
+
+void AXObjectCache::handleFocusedUIElementChanged()
+{
+ [[WebCoreViewFactory sharedFactory] accessibilityHandleFocusChanged];
+}
+
+}
diff --git a/WebCore/page/mac/AccessibilityObjectMac.mm b/WebCore/page/mac/AccessibilityObjectMac.mm
new file mode 100644
index 0000000..872e108
--- /dev/null
+++ b/WebCore/page/mac/AccessibilityObjectMac.mm
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "AccessibilityObject.h"
+
+#import "AccessibilityObjectWrapper.h"
+
+namespace WebCore {
+
+bool AccessibilityObject::accessibilityIgnoreAttachment() const
+{
+ return [[wrapper() attachmentView] accessibilityIsIgnored];
+}
+
+} // WebCore
diff --git a/WebCore/page/AnimationController.h b/WebCore/page/mac/AccessibilityObjectWrapper.h
index fda1143..5a55fe0 100644
--- a/WebCore/page/AnimationController.h
+++ b/WebCore/page/mac/AccessibilityObjectWrapper.h
@@ -1,18 +1,18 @@
/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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.
+ * documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
+ * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@@ -25,33 +25,31 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
+#import <wtf/RefPtr.h>
-#ifndef AnimationController_h
-#define AnimationController_h
+#ifdef __OBJC__
+@class WebCoreTextMarker;
+@class WebCoreTextMarkerRange;
+#else
+class WebCoreTextMarker;
+class WebCoreTextMarkerRange;
+#endif
namespace WebCore {
+ class AccessibilityObject;
+ class VisiblePosition;
+}
-class AnimationControllerPrivate;
-class Frame;
-class RenderObject;
-class RenderStyle;
-
-class AnimationController
+@interface AccessibilityObjectWrapper : NSObject
{
-public:
- AnimationController(Frame*);
- ~AnimationController();
-
- void cancelImplicitAnimations(RenderObject*);
- RenderStyle* updateImplicitAnimations(RenderObject*, RenderStyle* newStyle);
-
- void suspendAnimations();
- void resumeAnimations();
-
-private:
- AnimationControllerPrivate* m_data;
-};
-
+ WebCore::AccessibilityObject* m_object;
}
+
+- (id)initWithAccessibilityObject:(WebCore::AccessibilityObject*)axObject;
+- (void)detach;
+- (WebCore::AccessibilityObject*)accessibilityObject;
-#endif
+- (NSView*)attachmentView;
+
+@end
diff --git a/WebCore/page/mac/AccessibilityObjectWrapper.mm b/WebCore/page/mac/AccessibilityObjectWrapper.mm
new file mode 100644
index 0000000..2104ca9
--- /dev/null
+++ b/WebCore/page/mac/AccessibilityObjectWrapper.mm
@@ -0,0 +1,1996 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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.
+ */
+
+#import "config.h"
+#import "AccessibilityObjectWrapper.h"
+
+#import "AXObjectCache.h"
+#import "AccessibilityListBox.h"
+#import "AccessibilityList.h"
+#import "AccessibilityRenderObject.h"
+#import "AccessibilityTable.h"
+#import "AccessibilityTableCell.h"
+#import "AccessibilityTableRow.h"
+#import "AccessibilityTableColumn.h"
+#import "ColorMac.h"
+#import "Frame.h"
+#import "HTMLAnchorElement.h"
+#import "HTMLAreaElement.h"
+#import "HTMLImageElement.h"
+#import "HTMLInputElement.h"
+#import "HTMLTextAreaElement.h"
+#import "LocalizedStrings.h"
+#import "RenderTextControl.h"
+#import "RenderView.h"
+#import "RenderWidget.h"
+#import "SelectionController.h"
+#import "SimpleFontData.h"
+#import "TextIterator.h"
+#import "WebCoreFrameView.h"
+#import "WebCoreObjCExtras.h"
+#import "WebCoreViewFactory.h"
+#import "htmlediting.h"
+#import "visible_units.h"
+
+using namespace WebCore;
+using namespace HTMLNames;
+using namespace std;
+
+// Cell Tables
+#ifndef NSAccessibilitySelectedCellsAttribute
+#define NSAccessibilitySelectedCellsAttribute @"AXSelectedCells"
+#endif
+
+#ifndef NSAccessibilityVisibleCellsAttribute
+#define NSAccessibilityVisibleCellsAttribute @"AXVisibleCells"
+#endif
+
+#ifndef NSAccessibilityRowHeaderUIElementsAttribute
+#define NSAccessibilityRowHeaderUIElementsAttribute @"AXRowHeaderUIElements"
+#endif
+
+#ifndef NSAccessibilityRowIndexRangeAttribute
+#define NSAccessibilityRowIndexRangeAttribute @"AXRowIndexRange"
+#endif
+
+#ifndef NSAccessibilityColumnIndexRangeAttribute
+#define NSAccessibilityColumnIndexRangeAttribute @"AXColumnIndexRange"
+#endif
+
+#ifndef NSAccessibilityCellForColumnAndRowParameterizedAttribute
+#define NSAccessibilityCellForColumnAndRowParameterizedAttribute @"AXCellForColumnAndRow"
+#endif
+
+#ifndef NSAccessibilityCellRole
+#define NSAccessibilityCellRole @"AXCell"
+#endif
+
+// Lists
+#ifndef NSAccessibilityContentListSubrole
+#define NSAccessibilityContentListSubrole @"AXContentList"
+#endif
+
+#ifndef NSAccessibilityDefinitionListSubrole
+#define NSAccessibilityDefinitionListSubrole @"AXDefinitionList"
+#endif
+
+#ifdef BUILDING_ON_TIGER
+typedef unsigned NSUInteger;
+#endif
+
+@interface NSObject (WebKitAccessibilityArrayCategory)
+
+- (NSUInteger)accessibilityIndexOfChild:(id)child;
+- (NSUInteger)accessibilityArrayAttributeCount:(NSString *)attribute;
+- (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute index:(NSUInteger)index maxCount:(NSUInteger)maxCount;
+
+@end
+
+@implementation AccessibilityObjectWrapper
+
+#ifndef BUILDING_ON_TIGER
++ (void)initialize
+{
+ WebCoreObjCFinalizeOnMainThread(self);
+}
+#endif
+
+- (id)initWithAccessibilityObject:(AccessibilityObject*)axObject
+{
+ [super init];
+
+ m_object = axObject;
+ return self;
+}
+
+- (void)unregisterUniqueIdForUIElement
+{
+ [[WebCoreViewFactory sharedFactory] unregisterUniqueIdForUIElement:self];
+}
+
+- (void)detach
+{
+ // Send unregisterUniqueIdForUIElement unconditionally because if it is
+ // ever accidently not done (via other bugs in our AX implementation) you
+ // end up with a crash like <rdar://problem/4273149>. It is safe and not
+ // expensive to send even if the object is not registered.
+ [self unregisterUniqueIdForUIElement];
+ m_object = 0;
+}
+
+- (AccessibilityObject*)accessibilityObject
+{
+ return m_object;
+}
+
+- (NSView*)attachmentView
+{
+ ASSERT(m_object->isAttachment());
+ Widget* widget = m_object->widgetForAttachmentView();
+ if (!widget)
+ return nil;
+ return widget->platformWidget();
+}
+
+static WebCoreTextMarker* textMarkerForVisiblePosition(const VisiblePosition& visiblePos)
+{
+ if (visiblePos.isNull())
+ return nil;
+
+ Position deepPos = visiblePos.deepEquivalent();
+ Node* domNode = deepPos.node();
+ ASSERT(domNode);
+ if (!domNode)
+ return nil;
+
+ if (domNode->isHTMLElement())
+ if (static_cast<HTMLElement*>(domNode)->isPasswordField())
+ return nil;
+
+ // locate the renderer, which must exist for a visible dom node
+ RenderObject* renderer = domNode->renderer();
+ ASSERT(renderer);
+
+ // find or create an accessibility object for this renderer
+ AXObjectCache* cache = renderer->document()->axObjectCache();
+ RefPtr<AccessibilityObject> obj = cache->get(renderer);
+
+ // create a text marker, adding an ID for the AccessibilityObject if needed
+ TextMarkerData textMarkerData;
+
+ // The compiler can add padding to this struct.
+ // This memory must be bzero'd so instances of TextMarkerData can be tested for byte-equivalence.
+ bzero(&textMarkerData, sizeof(TextMarkerData));
+ textMarkerData.axID = obj.get()->axObjectID();
+ textMarkerData.node = domNode;
+ textMarkerData.offset = deepPos.offset();
+ textMarkerData.affinity = visiblePos.affinity();
+ return [[WebCoreViewFactory sharedFactory] textMarkerWithBytes:&textMarkerData length:sizeof(textMarkerData)];
+}
+
+static VisiblePosition visiblePositionForTextMarker(WebCoreTextMarker* textMarker)
+{
+ TextMarkerData textMarkerData;
+
+ if (![[WebCoreViewFactory sharedFactory] getBytes:&textMarkerData fromTextMarker:textMarker length:sizeof(textMarkerData)])
+ return VisiblePosition();
+
+ VisiblePosition visiblePos = VisiblePosition(textMarkerData.node, textMarkerData.offset, textMarkerData.affinity);
+ Position deepPos = visiblePos.deepEquivalent();
+ if (deepPos.isNull())
+ return VisiblePosition();
+
+ RenderObject* renderer = deepPos.node()->renderer();
+ if (!renderer)
+ return VisiblePosition();
+
+ AXObjectCache* cache = renderer->document()->axObjectCache();
+ if (!cache->isIDinUse(textMarkerData.axID))
+ return VisiblePosition();
+
+ if (deepPos.node() != textMarkerData.node || deepPos.offset() != textMarkerData.offset)
+ return VisiblePosition();
+
+ return visiblePos;
+}
+
+static VisiblePosition visiblePositionForStartOfTextMarkerRange(WebCoreTextMarkerRange* textMarkerRange)
+{
+ return visiblePositionForTextMarker([[WebCoreViewFactory sharedFactory] startOfTextMarkerRange:textMarkerRange]);
+}
+
+static VisiblePosition visiblePositionForEndOfTextMarkerRange(WebCoreTextMarkerRange* textMarkerRange)
+{
+ return visiblePositionForTextMarker([[WebCoreViewFactory sharedFactory] endOfTextMarkerRange:textMarkerRange]);
+}
+
+static WebCoreTextMarkerRange* textMarkerRangeFromMarkers(WebCoreTextMarker* textMarker1, WebCoreTextMarker* textMarker2)
+{
+ if (!textMarker1 || !textMarker2)
+ return nil;
+
+ return [[WebCoreViewFactory sharedFactory] textMarkerRangeWithStart:textMarker1 end:textMarker2];
+}
+
+static void AXAttributeStringSetFont(NSMutableAttributedString* attrString, NSString* attribute, NSFont* font, NSRange range)
+{
+ NSDictionary* dict;
+
+ if (font) {
+ dict = [NSDictionary dictionaryWithObjectsAndKeys:
+ [font fontName] , NSAccessibilityFontNameKey,
+ [font familyName] , NSAccessibilityFontFamilyKey,
+ [font displayName] , NSAccessibilityVisibleNameKey,
+ [NSNumber numberWithFloat:[font pointSize]] , NSAccessibilityFontSizeKey,
+ nil];
+
+ [attrString addAttribute:attribute value:dict range:range];
+ } else
+ [attrString removeAttribute:attribute range:range];
+
+}
+
+static CGColorRef CreateCGColorIfDifferent(NSColor* nsColor, CGColorRef existingColor)
+{
+ // get color information assuming NSDeviceRGBColorSpace
+ NSColor* rgbColor = [nsColor colorUsingColorSpaceName:NSDeviceRGBColorSpace];
+ if (rgbColor == nil)
+ rgbColor = [NSColor blackColor];
+ CGFloat components[4];
+ [rgbColor getRed:&components[0] green:&components[1] blue:&components[2] alpha:&components[3]];
+
+ // create a new CGColorRef to return
+ CGColorSpaceRef cgColorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
+ CGColorRef cgColor = CGColorCreate(cgColorSpace, components);
+ CGColorSpaceRelease(cgColorSpace);
+ CFMakeCollectable(cgColor);
+
+ // check for match with existing color
+ if (existingColor && CGColorEqualToColor(cgColor, existingColor))
+ cgColor = nil;
+
+ return cgColor;
+}
+
+static void AXAttributeStringSetColor(NSMutableAttributedString* attrString, NSString* attribute, NSColor* color, NSRange range)
+{
+ if (color) {
+ CGColorRef existingColor = (CGColorRef) [attrString attribute:attribute atIndex:range.location effectiveRange:nil];
+ CGColorRef cgColor = CreateCGColorIfDifferent(color, existingColor);
+ if (cgColor) {
+ [attrString addAttribute:attribute value:(id)cgColor range:range];
+ CGColorRelease(cgColor);
+ }
+ } else
+ [attrString removeAttribute:attribute range:range];
+}
+
+static void AXAttributeStringSetNumber(NSMutableAttributedString* attrString, NSString* attribute, NSNumber* number, NSRange range)
+{
+ if (number)
+ [attrString addAttribute:attribute value:number range:range];
+ else
+ [attrString removeAttribute:attribute range:range];
+}
+
+static void AXAttributeStringSetStyle(NSMutableAttributedString* attrString, RenderObject* renderer, NSRange range)
+{
+ RenderStyle* style = renderer->style();
+
+ // set basic font info
+ AXAttributeStringSetFont(attrString, NSAccessibilityFontTextAttribute, style->font().primaryFont()->getNSFont(), range);
+
+ // set basic colors
+ AXAttributeStringSetColor(attrString, NSAccessibilityForegroundColorTextAttribute, nsColor(style->color()), range);
+ AXAttributeStringSetColor(attrString, NSAccessibilityBackgroundColorTextAttribute, nsColor(style->backgroundColor()), range);
+
+ // set super/sub scripting
+ EVerticalAlign alignment = style->verticalAlign();
+ if (alignment == SUB)
+ AXAttributeStringSetNumber(attrString, NSAccessibilitySuperscriptTextAttribute, [NSNumber numberWithInt:(-1)], range);
+ else if (alignment == SUPER)
+ AXAttributeStringSetNumber(attrString, NSAccessibilitySuperscriptTextAttribute, [NSNumber numberWithInt:1], range);
+ else
+ [attrString removeAttribute:NSAccessibilitySuperscriptTextAttribute range:range];
+
+ // set shadow
+ if (style->textShadow())
+ AXAttributeStringSetNumber(attrString, NSAccessibilityShadowTextAttribute, [NSNumber numberWithBool:YES], range);
+ else
+ [attrString removeAttribute:NSAccessibilityShadowTextAttribute range:range];
+
+ // set underline and strikethrough
+ int decor = style->textDecorationsInEffect();
+ if ((decor & UNDERLINE) == 0) {
+ [attrString removeAttribute:NSAccessibilityUnderlineTextAttribute range:range];
+ [attrString removeAttribute:NSAccessibilityUnderlineColorTextAttribute range:range];
+ }
+
+ if ((decor & LINE_THROUGH) == 0) {
+ [attrString removeAttribute:NSAccessibilityStrikethroughTextAttribute range:range];
+ [attrString removeAttribute:NSAccessibilityStrikethroughColorTextAttribute range:range];
+ }
+
+ if ((decor & (UNDERLINE | LINE_THROUGH)) != 0) {
+ // find colors using quirk mode approach (strict mode would use current
+ // color for all but the root line box, which would use getTextDecorationColors)
+ Color underline, overline, linethrough;
+ renderer->getTextDecorationColors(decor, underline, overline, linethrough);
+
+ if ((decor & UNDERLINE) != 0) {
+ AXAttributeStringSetNumber(attrString, NSAccessibilityUnderlineTextAttribute, [NSNumber numberWithBool:YES], range);
+ AXAttributeStringSetColor(attrString, NSAccessibilityUnderlineColorTextAttribute, nsColor(underline), range);
+ }
+
+ if ((decor & LINE_THROUGH) != 0) {
+ AXAttributeStringSetNumber(attrString, NSAccessibilityStrikethroughTextAttribute, [NSNumber numberWithBool:YES], range);
+ AXAttributeStringSetColor(attrString, NSAccessibilityStrikethroughColorTextAttribute, nsColor(linethrough), range);
+ }
+ }
+}
+
+static int blockquoteLevel(RenderObject* renderer)
+{
+ int result = 0;
+ for (Node* node = renderer->element(); node; node = node->parent()) {
+ if (node->hasTagName(blockquoteTag))
+ result += 1;
+ }
+
+ return result;
+}
+
+static void AXAttributeStringSetBlockquoteLevel(NSMutableAttributedString* attrString, RenderObject* renderer, NSRange range)
+{
+ int quoteLevel = blockquoteLevel(renderer);
+
+ if (quoteLevel)
+ [attrString addAttribute:@"AXBlockQuoteLevel" value:[NSNumber numberWithInt:quoteLevel] range:range];
+ else
+ [attrString removeAttribute:@"AXBlockQuoteLevel" range:range];
+}
+
+static void AXAttributeStringSetSpelling(NSMutableAttributedString* attrString, Node* node, int offset, NSRange range)
+{
+ Vector<DocumentMarker> markers = node->renderer()->document()->markersForNode(node);
+ Vector<DocumentMarker>::iterator markerIt = markers.begin();
+
+ unsigned endOffset = (unsigned)offset + range.length;
+ for ( ; markerIt != markers.end(); markerIt++) {
+ DocumentMarker marker = *markerIt;
+
+ if (marker.type != DocumentMarker::Spelling)
+ continue;
+
+ if (marker.endOffset <= (unsigned)offset)
+ continue;
+
+ if (marker.startOffset > endOffset)
+ break;
+
+ // add misspelling attribute for the intersection of the marker and the range
+ int rStart = range.location + (marker.startOffset - offset);
+ int rLength = MIN(marker.endOffset, endOffset) - marker.startOffset;
+ NSRange spellRange = NSMakeRange(rStart, rLength);
+ AXAttributeStringSetNumber(attrString, NSAccessibilityMisspelledTextAttribute, [NSNumber numberWithBool:YES], spellRange);
+
+ if (marker.endOffset > endOffset + 1)
+ break;
+ }
+}
+
+static void AXAttributeStringSetHeadingLevel(AccessibilityObject* object, NSMutableAttributedString* attrString, RenderObject* renderer, NSRange range)
+{
+ int parentHeadingLevel = AccessibilityRenderObject::headingLevel(renderer->parent()->element());
+
+ if (parentHeadingLevel)
+ [attrString addAttribute:@"AXHeadingLevel" value:[NSNumber numberWithInt:parentHeadingLevel] range:range];
+ else
+ [attrString removeAttribute:@"AXHeadingLevel" range:range];
+}
+
+static AccessibilityObject* AXLinkElementForNode(Node* node)
+{
+ RenderObject* obj = node->renderer();
+ if (!obj)
+ return 0;
+
+ RefPtr<AccessibilityObject> axObj = obj->document()->axObjectCache()->get(obj);
+ Element* anchor = axObj->anchorElement();
+ if (!anchor)
+ return 0;
+
+ RenderObject* anchorRenderer = anchor->renderer();
+ if (!anchorRenderer)
+ return 0;
+
+ return anchorRenderer->document()->axObjectCache()->get(anchorRenderer);
+}
+
+static void AXAttributeStringSetElement(NSMutableAttributedString* attrString, NSString* attribute, AccessibilityObject* object, NSRange range)
+{
+ if (object && object->isAccessibilityRenderObject()) {
+ // make a serialiazable AX object
+
+ RenderObject* renderer = static_cast<AccessibilityRenderObject*>(object)->renderer();
+ if (!renderer)
+ return;
+
+ Document* doc = renderer->document();
+ if (!doc)
+ return;
+
+ AXObjectCache* cache = doc->axObjectCache();
+ if (!cache)
+ return;
+
+ AXUIElementRef axElement = [[WebCoreViewFactory sharedFactory] AXUIElementForElement:object->wrapper()];
+ if (axElement) {
+ [attrString addAttribute:attribute value:(id)axElement range:range];
+ CFRelease(axElement);
+ }
+ } else
+ [attrString removeAttribute:attribute range:range];
+}
+
+static void AXAttributedStringAppendText(AccessibilityObject* object, NSMutableAttributedString* attrString, Node* node, int offset, const UChar* chars, int length)
+{
+ // skip invisible text
+ if (!node->renderer())
+ return;
+
+ // easier to calculate the range before appending the string
+ NSRange attrStringRange = NSMakeRange([attrString length], length);
+
+ // append the string from this node
+ [[attrString mutableString] appendString:[NSString stringWithCharacters:chars length:length]];
+
+ // add new attributes and remove irrelevant inherited ones
+ // NOTE: color attributes are handled specially because -[NSMutableAttributedString addAttribute: value: range:] does not merge
+ // identical colors. Workaround is to not replace an existing color attribute if it matches what we are adding. This also means
+ // we cannot just pre-remove all inherited attributes on the appended string, so we have to remove the irrelevant ones individually.
+
+ // remove inherited attachment from prior AXAttributedStringAppendReplaced
+ [attrString removeAttribute:NSAccessibilityAttachmentTextAttribute range:attrStringRange];
+
+ // set new attributes
+ AXAttributeStringSetStyle(attrString, node->renderer(), attrStringRange);
+ AXAttributeStringSetHeadingLevel(object, attrString, node->renderer(), attrStringRange);
+ AXAttributeStringSetBlockquoteLevel(attrString, node->renderer(), attrStringRange);
+ AXAttributeStringSetElement(attrString, NSAccessibilityLinkTextAttribute, AXLinkElementForNode(node), attrStringRange);
+
+ // do spelling last because it tends to break up the range
+ AXAttributeStringSetSpelling(attrString, node, offset, attrStringRange);
+}
+
+static NSString* nsStringForReplacedNode(Node* replacedNode)
+{
+ // we should always be given a rendered node and a replaced node, but be safe
+ // replaced nodes are either attachments (widgets) or images
+ if (!replacedNode || !replacedNode->renderer() || !replacedNode->renderer()->isReplaced() || replacedNode->isTextNode()) {
+ ASSERT_NOT_REACHED();
+ return nil;
+ }
+
+ // create an AX object, but skip it if it is not supposed to be seen
+ RefPtr<AccessibilityObject> obj = replacedNode->renderer()->document()->axObjectCache()->get(replacedNode->renderer());
+ if (obj->accessibilityIsIgnored())
+ return nil;
+
+ // use the attachmentCharacter to represent the replaced node
+ const UniChar attachmentChar = NSAttachmentCharacter;
+ return [NSString stringWithCharacters:&attachmentChar length:1];
+}
+
+- (NSAttributedString*)doAXAttributedStringForTextMarkerRange:(WebCoreTextMarkerRange*)textMarkerRange
+{
+ // extract the start and end VisiblePosition
+ VisiblePosition startVisiblePosition = visiblePositionForStartOfTextMarkerRange(textMarkerRange);
+ if (startVisiblePosition.isNull())
+ return nil;
+
+ VisiblePosition endVisiblePosition = visiblePositionForEndOfTextMarkerRange(textMarkerRange);
+ if (endVisiblePosition.isNull())
+ return nil;
+
+ // iterate over the range to build the AX attributed string
+ NSMutableAttributedString* attrString = [[NSMutableAttributedString alloc] init];
+ TextIterator it(makeRange(startVisiblePosition, endVisiblePosition).get());
+ while (!it.atEnd()) {
+ // locate the node and starting offset for this range
+ int exception = 0;
+ Node* node = it.range()->startContainer(exception);
+ ASSERT(node == it.range()->endContainer(exception));
+ int offset = it.range()->startOffset(exception);
+
+ // non-zero length means textual node, zero length means replaced node (AKA "attachments" in AX)
+ if (it.length() != 0) {
+ AXAttributedStringAppendText(m_object, attrString, node, offset, it.characters(), it.length());
+ } else {
+ Node* replacedNode = node->childNode(offset);
+ NSString *attachmentString = nsStringForReplacedNode(replacedNode);
+ if (attachmentString) {
+ NSRange attrStringRange = NSMakeRange([attrString length], [attachmentString length]);
+
+ // append the placeholder string
+ [[attrString mutableString] appendString:attachmentString];
+
+ // remove all inherited attributes
+ [attrString setAttributes:nil range:attrStringRange];
+
+ // add the attachment attribute
+ AccessibilityObject* obj = replacedNode->renderer()->document()->axObjectCache()->get(replacedNode->renderer());
+ AXAttributeStringSetElement(attrString, NSAccessibilityAttachmentTextAttribute, obj, attrStringRange);
+ }
+ }
+ it.advance();
+ }
+
+ return [attrString autorelease];
+}
+
+static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePosition startPosition, VisiblePosition endPosition)
+{
+ WebCoreTextMarker* startTextMarker = textMarkerForVisiblePosition(startPosition);
+ WebCoreTextMarker* endTextMarker = textMarkerForVisiblePosition(endPosition);
+ return textMarkerRangeFromMarkers(startTextMarker, endTextMarker);
+}
+
+- (NSArray*)accessibilityActionNames
+{
+ static NSArray* actionElementActions = [[NSArray alloc] initWithObjects: NSAccessibilityPressAction, NSAccessibilityShowMenuAction, nil];
+ static NSArray* defaultElementActions = [[NSArray alloc] initWithObjects: NSAccessibilityShowMenuAction, nil];
+ static NSArray* menuElementActions = [[NSArray alloc] initWithObjects: NSAccessibilityCancelAction, NSAccessibilityPressAction, nil];
+
+ NSArray *actions;
+ if (m_object->actionElement())
+ actions = actionElementActions;
+ else if (m_object->isMenuRelated())
+ actions = menuElementActions;
+ else if (m_object->isAttachment())
+ actions = [[self attachmentView] accessibilityActionNames];
+ else
+ actions = defaultElementActions;
+
+ return actions;
+}
+
+- (NSArray*)accessibilityAttributeNames
+{
+ if (m_object->isAttachment())
+ return [[self attachmentView] accessibilityAttributeNames];
+
+ static NSArray* attributes = nil;
+ static NSArray* anchorAttrs = nil;
+ static NSArray* webAreaAttrs = nil;
+ static NSArray* textAttrs = nil;
+ static NSArray* listBoxAttrs = nil;
+ static NSArray* rangeAttrs = nil;
+ static NSArray* commonMenuAttrs = nil;
+ static NSArray* menuAttrs = nil;
+ static NSArray* menuBarAttrs = nil;
+ static NSArray* menuItemAttrs = nil;
+ static NSArray* menuButtonAttrs = nil;
+ static NSArray* controlAttrs = nil;
+ static NSArray* tableAttrs = nil;
+ static NSArray* tableRowAttrs = nil;
+ static NSArray* tableColAttrs = nil;
+ static NSArray* tableCellAttrs = nil;
+ NSMutableArray* tempArray;
+ if (attributes == nil) {
+ attributes = [[NSArray alloc] initWithObjects: NSAccessibilityRoleAttribute,
+ NSAccessibilitySubroleAttribute,
+ NSAccessibilityRoleDescriptionAttribute,
+ NSAccessibilityChildrenAttribute,
+ NSAccessibilityHelpAttribute,
+ NSAccessibilityParentAttribute,
+ NSAccessibilityPositionAttribute,
+ NSAccessibilitySizeAttribute,
+ NSAccessibilityTitleAttribute,
+ NSAccessibilityDescriptionAttribute,
+ NSAccessibilityValueAttribute,
+ NSAccessibilityFocusedAttribute,
+ NSAccessibilityEnabledAttribute,
+ NSAccessibilityWindowAttribute,
+ @"AXSelectedTextMarkerRange",
+ @"AXStartTextMarker",
+ @"AXEndTextMarker",
+ @"AXVisited",
+ NSAccessibilityLinkedUIElementsAttribute,
+ NSAccessibilitySelectedAttribute,
+ @"AXBlockQuoteLevel",
+ NSAccessibilityTopLevelUIElementAttribute,
+ nil];
+ }
+ if (commonMenuAttrs == nil) {
+ commonMenuAttrs = [[NSArray alloc] initWithObjects: NSAccessibilityRoleAttribute,
+ NSAccessibilityRoleDescriptionAttribute,
+ NSAccessibilityChildrenAttribute,
+ NSAccessibilityParentAttribute,
+ NSAccessibilityEnabledAttribute,
+ NSAccessibilityPositionAttribute,
+ NSAccessibilitySizeAttribute,
+ nil];
+ }
+ if (anchorAttrs == nil) {
+ tempArray = [[NSMutableArray alloc] initWithArray:attributes];
+ [tempArray addObject:NSAccessibilityURLAttribute];
+ anchorAttrs = [[NSArray alloc] initWithArray:tempArray];
+ [tempArray release];
+ }
+ if (webAreaAttrs == nil) {
+ tempArray = [[NSMutableArray alloc] initWithArray:attributes];
+ [tempArray addObject:@"AXLinkUIElements"];
+ [tempArray addObject:@"AXLoaded"];
+ [tempArray addObject:@"AXLayoutCount"];
+ [tempArray addObject:NSAccessibilityURLAttribute];
+ webAreaAttrs = [[NSArray alloc] initWithArray:tempArray];
+ [tempArray release];
+ }
+ if (textAttrs == nil) {
+ tempArray = [[NSMutableArray alloc] initWithArray:attributes];
+ [tempArray addObject:NSAccessibilityNumberOfCharactersAttribute];
+ [tempArray addObject:NSAccessibilitySelectedTextAttribute];
+ [tempArray addObject:NSAccessibilitySelectedTextRangeAttribute];
+ [tempArray addObject:NSAccessibilityVisibleCharacterRangeAttribute];
+ [tempArray addObject:NSAccessibilityInsertionPointLineNumberAttribute];
+ [tempArray addObject:NSAccessibilityTitleUIElementAttribute];
+ textAttrs = [[NSArray alloc] initWithArray:tempArray];
+ [tempArray release];
+ }
+ if (listBoxAttrs == nil) {
+ tempArray = [[NSMutableArray alloc] initWithArray:attributes];
+ [tempArray addObject:NSAccessibilitySelectedChildrenAttribute];
+ [tempArray addObject:NSAccessibilityVisibleChildrenAttribute];
+ [tempArray addObject:NSAccessibilityOrientationAttribute];
+ [tempArray addObject:NSAccessibilityTitleUIElementAttribute];
+ listBoxAttrs = [[NSArray alloc] initWithArray:tempArray];
+ [tempArray release];
+ }
+ if (rangeAttrs == nil) {
+ tempArray = [[NSMutableArray alloc] initWithArray:attributes];
+ [tempArray addObject:NSAccessibilityTopLevelUIElementAttribute];
+ [tempArray addObject:NSAccessibilityValueAttribute];
+ [tempArray addObject:NSAccessibilityMinValueAttribute];
+ [tempArray addObject:NSAccessibilityMaxValueAttribute];
+ rangeAttrs = [[NSArray alloc] initWithArray:tempArray];
+ [tempArray release];
+ }
+ if (menuBarAttrs == nil) {
+ tempArray = [[NSMutableArray alloc] initWithArray:commonMenuAttrs];
+ [tempArray addObject:NSAccessibilitySelectedChildrenAttribute];
+ [tempArray addObject:NSAccessibilityVisibleChildrenAttribute];
+ [tempArray addObject:NSAccessibilityTitleUIElementAttribute];
+ menuBarAttrs = [[NSArray alloc] initWithArray:tempArray];
+ [tempArray release];
+ }
+ if (menuAttrs == nil) {
+ tempArray = [[NSMutableArray alloc] initWithArray:commonMenuAttrs];
+ [tempArray addObject:NSAccessibilitySelectedChildrenAttribute];
+ [tempArray addObject:NSAccessibilityVisibleChildrenAttribute];
+ [tempArray addObject:NSAccessibilityTitleUIElementAttribute];
+ menuAttrs = [[NSArray alloc] initWithArray:tempArray];
+ [tempArray release];
+ }
+ if (menuItemAttrs == nil) {
+ tempArray = [[NSMutableArray alloc] initWithArray:commonMenuAttrs];
+ [tempArray addObject:NSAccessibilityTitleAttribute];
+ [tempArray addObject:NSAccessibilityHelpAttribute];
+ [tempArray addObject:NSAccessibilitySelectedAttribute];
+ [tempArray addObject:(NSString*)kAXMenuItemCmdCharAttribute];
+ [tempArray addObject:(NSString*)kAXMenuItemCmdVirtualKeyAttribute];
+ [tempArray addObject:(NSString*)kAXMenuItemCmdGlyphAttribute];
+ [tempArray addObject:(NSString*)kAXMenuItemCmdModifiersAttribute];
+ [tempArray addObject:(NSString*)kAXMenuItemMarkCharAttribute];
+ [tempArray addObject:(NSString*)kAXMenuItemPrimaryUIElementAttribute];
+ [tempArray addObject:NSAccessibilityServesAsTitleForUIElementsAttribute];
+ menuItemAttrs = [[NSArray alloc] initWithArray:tempArray];
+ [tempArray release];
+ }
+ if (menuButtonAttrs == nil) {
+ menuButtonAttrs = [[NSArray alloc] initWithObjects:NSAccessibilityRoleAttribute,
+ NSAccessibilityRoleDescriptionAttribute,
+ NSAccessibilityParentAttribute,
+ NSAccessibilityPositionAttribute,
+ NSAccessibilitySizeAttribute,
+ NSAccessibilityWindowAttribute,
+ NSAccessibilityTopLevelUIElementAttribute,
+ NSAccessibilityEnabledAttribute,
+ NSAccessibilityFocusedAttribute,
+ NSAccessibilityTitleAttribute,
+ NSAccessibilityChildrenAttribute, nil];
+ }
+ if (controlAttrs == nil) {
+ tempArray = [[NSMutableArray alloc] initWithArray:attributes];
+ [tempArray addObject:NSAccessibilityTitleUIElementAttribute];
+ controlAttrs = [[NSArray alloc] initWithArray:tempArray];
+ [tempArray release];
+ }
+ if (tableAttrs == nil) {
+ tempArray = [[NSMutableArray alloc] initWithArray:attributes];
+ [tempArray addObject:NSAccessibilityRowsAttribute];
+ [tempArray addObject:NSAccessibilityVisibleRowsAttribute];
+ [tempArray addObject:NSAccessibilityColumnsAttribute];
+ [tempArray addObject:NSAccessibilityVisibleColumnsAttribute];
+ [tempArray addObject:NSAccessibilityVisibleCellsAttribute];
+ [tempArray addObject:(NSString *)kAXColumnHeaderUIElementsAttribute];
+ [tempArray addObject:NSAccessibilityRowHeaderUIElementsAttribute];
+ [tempArray addObject:NSAccessibilityHeaderAttribute];
+ tableAttrs = [[NSArray alloc] initWithArray:tempArray];
+ [tempArray release];
+ }
+ if (tableRowAttrs == nil) {
+ tempArray = [[NSMutableArray alloc] initWithArray:attributes];
+ [tempArray addObject:NSAccessibilityIndexAttribute];
+ tableRowAttrs = [[NSArray alloc] initWithArray:tempArray];
+ [tempArray release];
+ }
+ if (tableColAttrs == nil) {
+ tempArray = [[NSMutableArray alloc] initWithArray:attributes];
+ [tempArray addObject:NSAccessibilityIndexAttribute];
+ [tempArray addObject:NSAccessibilityHeaderAttribute];
+ [tempArray addObject:NSAccessibilityRowsAttribute];
+ [tempArray addObject:NSAccessibilityVisibleRowsAttribute];
+ tableColAttrs = [[NSArray alloc] initWithArray:tempArray];
+ [tempArray release];
+ }
+ if (tableCellAttrs == nil) {
+ tempArray = [[NSMutableArray alloc] initWithArray:attributes];
+ [tempArray addObject:NSAccessibilityRowIndexRangeAttribute];
+ [tempArray addObject:NSAccessibilityColumnIndexRangeAttribute];
+ tableCellAttrs = [[NSArray alloc] initWithArray:tempArray];
+ [tempArray release];
+ }
+
+ if (m_object->isPasswordField())
+ return attributes;
+
+ if (m_object->isWebArea())
+ return webAreaAttrs;
+
+ if (m_object->isTextControl())
+ return textAttrs;
+
+ if (m_object->isAnchor() || m_object->isImage())
+ return anchorAttrs;
+
+ if (m_object->isDataTable())
+ return tableAttrs;
+ if (m_object->isTableRow())
+ return tableRowAttrs;
+ if (m_object->isTableColumn())
+ return tableColAttrs;
+ if (m_object->isTableCell())
+ return tableCellAttrs;
+
+ if (m_object->isListBox() || m_object->isList())
+ return listBoxAttrs;
+
+ if (m_object->isProgressIndicator() || m_object->isSlider())
+ return rangeAttrs;
+
+ if (m_object->isControl())
+ return controlAttrs;
+
+ if (m_object->isMenu())
+ return menuAttrs;
+ if (m_object->isMenuBar())
+ return menuBarAttrs;
+ if (m_object->isMenuButton())
+ return menuButtonAttrs;
+ if (m_object->isMenuItem())
+ return menuItemAttrs;
+
+ return attributes;
+}
+
+- (VisiblePositionRange)visiblePositionRangeForTextMarkerRange:(WebCoreTextMarkerRange*) textMarkerRange
+{
+ return VisiblePositionRange(visiblePositionForStartOfTextMarkerRange(textMarkerRange), visiblePositionForEndOfTextMarkerRange(textMarkerRange));
+}
+
+- (NSArray*)renderWidgetChildren
+{
+ Widget* widget = m_object->widget();
+ if (!widget)
+ return nil;
+ return [(widget->getOuterView()) accessibilityAttributeValue: NSAccessibilityChildrenAttribute];
+}
+
+static void convertToVector(NSArray* array, AccessibilityObject::AccessibilityChildrenVector& vector)
+{
+ unsigned length = [array count];
+ vector.reserveCapacity(length);
+ for (unsigned i = 0; i < length; ++i) {
+ AccessibilityObject* obj = [[array objectAtIndex:i] accessibilityObject];
+ if (obj)
+ vector.append(obj);
+ }
+}
+
+static NSMutableArray* convertToNSArray(const AccessibilityObject::AccessibilityChildrenVector& vector)
+{
+ unsigned length = vector.size();
+ NSMutableArray* array = [NSMutableArray arrayWithCapacity: length];
+ for (unsigned i = 0; i < length; ++i) {
+ ASSERT(vector[i]->wrapper());
+ if (vector[i]->wrapper())
+ [array addObject:vector[i]->wrapper()];
+ }
+ return array;
+}
+
+- (WebCoreTextMarkerRange*)textMarkerRangeForSelection
+{
+ Selection selection = m_object->selection();
+ if (selection.isNone())
+ return nil;
+ return textMarkerRangeFromVisiblePositions(selection.visibleStart(), selection.visibleEnd());
+}
+
+- (NSValue*)position
+{
+ IntRect rect = m_object->elementRect();
+
+ // The Cocoa accessibility API wants the lower-left corner.
+ NSPoint point = NSMakePoint(rect.x(), rect.bottom());
+ FrameView* frameView = m_object->documentFrameView();
+ if (frameView) {
+ NSView* view = frameView->documentView();
+ point = [[view window] convertBaseToScreen: [view convertPoint: point toView:nil]];
+ }
+
+ return [NSValue valueWithPoint: point];
+}
+
+typedef HashMap<int, NSString*> AccessibilityRoleMap;
+
+static const AccessibilityRoleMap& createAccessibilityRoleMap()
+{
+ struct RoleEntry {
+ AccessibilityRole value;
+ NSString* string;
+ };
+
+ static const RoleEntry roles[] = {
+ { UnknownRole, NSAccessibilityUnknownRole },
+ { ButtonRole, NSAccessibilityButtonRole },
+ { RadioButtonRole, NSAccessibilityRadioButtonRole },
+ { CheckBoxRole, NSAccessibilityCheckBoxRole },
+ { SliderRole, NSAccessibilitySliderRole },
+ { TabGroupRole, NSAccessibilityTabGroupRole },
+ { TextFieldRole, NSAccessibilityTextFieldRole },
+ { StaticTextRole, NSAccessibilityStaticTextRole },
+ { TextAreaRole, NSAccessibilityTextAreaRole },
+ { ScrollAreaRole, NSAccessibilityScrollAreaRole },
+ { PopUpButtonRole, NSAccessibilityPopUpButtonRole },
+ { MenuButtonRole, NSAccessibilityMenuButtonRole },
+ { TableRole, NSAccessibilityTableRole },
+ { ApplicationRole, NSAccessibilityApplicationRole },
+ { GroupRole, NSAccessibilityGroupRole },
+ { RadioGroupRole, NSAccessibilityRadioGroupRole },
+ { ListRole, NSAccessibilityListRole },
+ { ScrollBarRole, NSAccessibilityScrollBarRole },
+ { ValueIndicatorRole, NSAccessibilityValueIndicatorRole },
+ { ImageRole, NSAccessibilityImageRole },
+ { MenuBarRole, NSAccessibilityMenuBarRole },
+ { MenuRole, NSAccessibilityMenuRole },
+ { MenuItemRole, NSAccessibilityMenuItemRole },
+ { ColumnRole, NSAccessibilityColumnRole },
+ { RowRole, NSAccessibilityRowRole },
+ { ToolbarRole, NSAccessibilityToolbarRole },
+ { BusyIndicatorRole, NSAccessibilityBusyIndicatorRole },
+ { ProgressIndicatorRole, NSAccessibilityProgressIndicatorRole },
+ { WindowRole, NSAccessibilityWindowRole },
+ { DrawerRole, NSAccessibilityDrawerRole },
+ { SystemWideRole, NSAccessibilitySystemWideRole },
+ { OutlineRole, NSAccessibilityOutlineRole },
+ { IncrementorRole, NSAccessibilityIncrementorRole },
+ { BrowserRole, NSAccessibilityBrowserRole },
+ { ComboBoxRole, NSAccessibilityComboBoxRole },
+ { SplitGroupRole, NSAccessibilitySplitGroupRole },
+ { SplitterRole, NSAccessibilitySplitterRole },
+ { ColorWellRole, NSAccessibilityColorWellRole },
+ { GrowAreaRole, NSAccessibilityGrowAreaRole },
+ { SheetRole, NSAccessibilitySheetRole },
+ { HelpTagRole, NSAccessibilityHelpTagRole },
+ { MatteRole, NSAccessibilityMatteRole },
+ { RulerRole, NSAccessibilityRulerRole },
+ { RulerMarkerRole, NSAccessibilityRulerMarkerRole },
+ { LinkRole, NSAccessibilityLinkRole },
+#ifndef BUILDING_ON_TIGER
+ { DisclosureTriangleRole, NSAccessibilityDisclosureTriangleRole },
+ { GridRole, NSAccessibilityGridRole },
+#endif
+ { WebCoreLinkRole, NSAccessibilityLinkRole },
+ { ImageMapLinkRole, NSAccessibilityLinkRole },
+ { ImageMapRole, @"AXImageMap" },
+ { ListMarkerRole, @"AXListMarker" },
+ { WebAreaRole, @"AXWebArea" },
+ { HeadingRole, @"AXHeading" },
+ { ListBoxRole, NSAccessibilityListRole },
+ { ListBoxOptionRole, NSAccessibilityStaticTextRole },
+ // cells don't exist on tiger or leopard
+#if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD)
+ { CellRole, NSAccessibilityGroupRole },
+#else
+ { CellRole, NSAccessibilityCellRole },
+#endif
+ { TableHeaderContainerRole, NSAccessibilityGroupRole },
+ { DefinitionListDefinitionRole, NSAccessibilityGroupRole },
+ { DefinitionListTermRole, NSAccessibilityGroupRole }
+
+ };
+ AccessibilityRoleMap& roleMap = *new AccessibilityRoleMap;
+
+ const unsigned numRoles = sizeof(roles) / sizeof(roles[0]);
+ for (unsigned i = 0; i < numRoles; ++i)
+ roleMap.set(roles[i].value, roles[i].string);
+ return roleMap;
+}
+
+static NSString* roleValueToNSString(AccessibilityRole value)
+{
+ ASSERT(value);
+ static const AccessibilityRoleMap& roleMap = createAccessibilityRoleMap();
+ return roleMap.get(value);
+}
+
+- (NSString*)role
+{
+ if (m_object->isAttachment())
+ return [[self attachmentView] accessibilityAttributeValue:NSAccessibilityRoleAttribute];
+ NSString* string = roleValueToNSString(m_object->roleValue());
+ if (string != nil)
+ return string;
+ return NSAccessibilityUnknownRole;
+}
+
+- (NSString*)subrole
+{
+ if (m_object->isPasswordField())
+ return NSAccessibilitySecureTextFieldSubrole;
+
+ if (m_object->isAttachment()) {
+ NSView* attachView = [self attachmentView];
+ if ([[attachView accessibilityAttributeNames] containsObject:NSAccessibilitySubroleAttribute]) {
+ return [attachView accessibilityAttributeValue:NSAccessibilitySubroleAttribute];
+ }
+ }
+
+ if (m_object->isList()) {
+ AccessibilityList* listObject = static_cast<AccessibilityList*>(m_object);
+ if (listObject->isUnorderedList() || listObject->isOrderedList())
+ return NSAccessibilityContentListSubrole;
+ if (listObject->isDefinitionList())
+ return NSAccessibilityDefinitionListSubrole;
+ }
+
+ return nil;
+}
+
+- (NSString*)roleDescription
+{
+ if (!m_object)
+ return nil;
+
+ // attachments have the AXImage role, but a different subrole
+ if (m_object->isAttachment())
+ return [[self attachmentView] accessibilityAttributeValue:NSAccessibilityRoleDescriptionAttribute];
+
+ // FIXME 3447564: It would be better to call some AppKit API to get these strings
+ // (which would be the best way to localize them)
+
+ NSString* axRole = [self role];
+ if ([axRole isEqualToString:NSAccessibilityButtonRole])
+ return NSAccessibilityRoleDescription(NSAccessibilityButtonRole, [self subrole]);
+
+ if ([axRole isEqualToString:NSAccessibilityPopUpButtonRole])
+ return NSAccessibilityRoleDescription(NSAccessibilityPopUpButtonRole, [self subrole]);
+
+ if ([axRole isEqualToString:NSAccessibilityStaticTextRole])
+ return NSAccessibilityRoleDescription(NSAccessibilityStaticTextRole, [self subrole]);
+
+ if ([axRole isEqualToString:NSAccessibilityImageRole])
+ return NSAccessibilityRoleDescription(NSAccessibilityImageRole, [self subrole]);
+
+ if ([axRole isEqualToString:NSAccessibilityGroupRole])
+ return NSAccessibilityRoleDescription(NSAccessibilityGroupRole, [self subrole]);
+
+ if ([axRole isEqualToString:NSAccessibilityCheckBoxRole])
+ return NSAccessibilityRoleDescription(NSAccessibilityCheckBoxRole, [self subrole]);
+
+ if ([axRole isEqualToString:NSAccessibilityRadioButtonRole])
+ return NSAccessibilityRoleDescription(NSAccessibilityRadioButtonRole, [self subrole]);
+
+ if ([axRole isEqualToString:NSAccessibilityTextFieldRole])
+ return NSAccessibilityRoleDescription(NSAccessibilityTextFieldRole, [self subrole]);
+
+ if ([axRole isEqualToString:NSAccessibilityTextAreaRole])
+ return NSAccessibilityRoleDescription(NSAccessibilityTextAreaRole, [self subrole]);
+
+ if ([axRole isEqualToString:NSAccessibilityListRole])
+ return NSAccessibilityRoleDescription(NSAccessibilityListRole, [self subrole]);
+
+ if ([axRole isEqualToString:NSAccessibilityTableRole])
+ return NSAccessibilityRoleDescription(NSAccessibilityTableRole, [self subrole]);
+
+ if ([axRole isEqualToString:NSAccessibilityRowRole])
+ return NSAccessibilityRoleDescription(NSAccessibilityRowRole, [self subrole]);
+
+ if ([axRole isEqualToString:NSAccessibilityColumnRole])
+ return NSAccessibilityRoleDescription(NSAccessibilityColumnRole, [self subrole]);
+
+ if ([axRole isEqualToString:NSAccessibilityCellRole])
+ return NSAccessibilityRoleDescription(NSAccessibilityCellRole, [self subrole]);
+
+ if ([axRole isEqualToString:@"AXWebArea"])
+ return AXWebAreaText();
+
+ if ([axRole isEqualToString:@"AXLink"])
+ return AXLinkText();
+
+ if ([axRole isEqualToString:@"AXListMarker"])
+ return AXListMarkerText();
+
+ if ([axRole isEqualToString:@"AXImageMap"])
+ return AXImageMapText();
+
+ if ([axRole isEqualToString:@"AXHeading"])
+ return AXHeadingText();
+
+ if ([axRole isEqualToString:(NSString*)kAXMenuBarItemRole] ||
+ [axRole isEqualToString:NSAccessibilityMenuRole])
+ return nil;
+
+ if ([axRole isEqualToString:NSAccessibilityMenuButtonRole])
+ return NSAccessibilityRoleDescription(NSAccessibilityMenuButtonRole, [self subrole]);
+
+ return NSAccessibilityRoleDescription(NSAccessibilityUnknownRole, nil);
+}
+
+// FIXME: split up this function in a better way.
+// suggestions: Use a hash table that maps attribute names to function calls,
+// or maybe pointers to member functions
+- (id)accessibilityAttributeValue:(NSString*)attributeName
+{
+ if (!m_object)
+ return nil;
+
+ if ([attributeName isEqualToString: NSAccessibilityRoleAttribute])
+ return [self role];
+
+ if ([attributeName isEqualToString: NSAccessibilitySubroleAttribute])
+ return [self subrole];
+
+ if ([attributeName isEqualToString: NSAccessibilityRoleDescriptionAttribute])
+ return [self roleDescription];
+
+ if ([attributeName isEqualToString: NSAccessibilityParentAttribute]) {
+ if (m_object->isAccessibilityRenderObject()) {
+ FrameView* fv = static_cast<AccessibilityRenderObject*>(m_object)->frameViewIfRenderView();
+ if (fv)
+ return fv->platformWidget();
+ }
+
+ return m_object->parentObjectUnignored()->wrapper();
+ }
+
+ if ([attributeName isEqualToString: NSAccessibilityChildrenAttribute]) {
+ if (m_object->children().isEmpty()) {
+ NSArray* children = [self renderWidgetChildren];
+ if (children != nil)
+ return children;
+ }
+ return convertToNSArray(m_object->children());
+ }
+
+ if ([attributeName isEqualToString: NSAccessibilitySelectedChildrenAttribute]) {
+ if (m_object->isListBox()) {
+ AccessibilityObject::AccessibilityChildrenVector selectedChildrenCopy;
+ m_object->selectedChildren(selectedChildrenCopy);
+ return convertToNSArray(selectedChildrenCopy);
+ }
+ return nil;
+ }
+
+ if ([attributeName isEqualToString: NSAccessibilityVisibleChildrenAttribute]) {
+ if (m_object->isListBox()) {
+ AccessibilityObject::AccessibilityChildrenVector visibleChildrenCopy;
+ m_object->visibleChildren(visibleChildrenCopy);
+ return convertToNSArray(visibleChildrenCopy);
+ }
+ else if (m_object->isList())
+ return [self accessibilityAttributeValue:NSAccessibilityChildrenAttribute];
+
+ return nil;
+ }
+
+
+ if (m_object->isWebArea()) {
+ if ([attributeName isEqualToString: @"AXLinkUIElements"]) {
+ AccessibilityObject::AccessibilityChildrenVector links;
+ static_cast<AccessibilityRenderObject*>(m_object)->getDocumentLinks(links);
+ return convertToNSArray(links);
+ }
+ if ([attributeName isEqualToString: @"AXLoaded"])
+ return [NSNumber numberWithBool: m_object->isLoaded()];
+ if ([attributeName isEqualToString: @"AXLayoutCount"])
+ return [NSNumber numberWithInt: m_object->layoutCount()];
+ }
+
+ if (m_object->isTextControl()) {
+ if ([attributeName isEqualToString: NSAccessibilityNumberOfCharactersAttribute]) {
+ int length = m_object->textLength();
+ if (length < 0)
+ return nil;
+ return [NSNumber numberWithUnsignedInt:length];
+ }
+ if ([attributeName isEqualToString: NSAccessibilitySelectedTextAttribute]) {
+ String selectedText = m_object->selectedText();
+ if (selectedText.isNull())
+ return nil;
+ return (NSString*)selectedText;
+ }
+ if ([attributeName isEqualToString: NSAccessibilitySelectedTextRangeAttribute]) {
+ PlainTextRange textRange = m_object->selectedTextRange();
+ if (textRange.isNull())
+ return nil;
+ return [NSValue valueWithRange:NSMakeRange(textRange.start, textRange.length)];
+ }
+ // TODO: Get actual visible range. <rdar://problem/4712101>
+ if ([attributeName isEqualToString: NSAccessibilityVisibleCharacterRangeAttribute])
+ return m_object->isPasswordField() ? nil : [NSValue valueWithRange: NSMakeRange(0, m_object->textLength())];
+ if ([attributeName isEqualToString: NSAccessibilityInsertionPointLineNumberAttribute]) {
+ // if selectionEnd > 0, then there is selected text and this question should not be answered
+ if (m_object->isPasswordField() || m_object->selectionEnd() > 0)
+ return nil;
+ int lineNumber = m_object->lineForPosition(m_object->visiblePositionForIndex(m_object->selectionStart(), true));
+ if (lineNumber < 0)
+ return nil;
+ return [NSNumber numberWithInt:lineNumber];
+ }
+ }
+
+ if ([attributeName isEqualToString: NSAccessibilityURLAttribute]) {
+ KURL url = m_object->url();
+ if (url.isNull())
+ return nil;
+ return (NSURL*)url;
+ }
+
+ if ([attributeName isEqualToString: @"AXVisited"])
+ return [NSNumber numberWithBool: m_object->isVisited()];
+
+ if ([attributeName isEqualToString: NSAccessibilityTitleAttribute]) {
+ if (m_object->isAttachment()) {
+ if ([[[self attachmentView] accessibilityAttributeNames] containsObject:NSAccessibilityTitleAttribute])
+ return [[self attachmentView] accessibilityAttributeValue:NSAccessibilityTitleAttribute];
+ }
+ return m_object->title();
+ }
+
+ if ([attributeName isEqualToString: NSAccessibilityDescriptionAttribute]) {
+ if (m_object->isAttachment()) {
+ if ([[[self attachmentView] accessibilityAttributeNames] containsObject:NSAccessibilityDescriptionAttribute])
+ return [[self attachmentView] accessibilityAttributeValue:NSAccessibilityDescriptionAttribute];
+ }
+ return m_object->accessibilityDescription();
+ }
+
+ if ([attributeName isEqualToString: NSAccessibilityValueAttribute]) {
+ if (m_object->isAttachment()) {
+ if ([[[self attachmentView] accessibilityAttributeNames] containsObject:NSAccessibilityValueAttribute])
+ return [[self attachmentView] accessibilityAttributeValue:NSAccessibilityValueAttribute];
+ }
+ if (m_object->isProgressIndicator() || m_object->isSlider())
+ return [NSNumber numberWithFloat:m_object->valueForRange()];
+ if (m_object->hasIntValue())
+ return [NSNumber numberWithInt:m_object->intValue()];
+ return m_object->stringValue();
+ }
+
+ if ([attributeName isEqualToString: NSAccessibilityMinValueAttribute])
+ return [NSNumber numberWithFloat:m_object->minValueForRange()];
+
+ if ([attributeName isEqualToString: NSAccessibilityMaxValueAttribute])
+ return [NSNumber numberWithFloat:m_object->maxValueForRange()];
+
+ if ([attributeName isEqualToString: NSAccessibilityHelpAttribute])
+ return m_object->helpText();
+
+ if ([attributeName isEqualToString: NSAccessibilityFocusedAttribute])
+ return [NSNumber numberWithBool: m_object->isFocused()];
+
+ if ([attributeName isEqualToString: NSAccessibilityEnabledAttribute])
+ return [NSNumber numberWithBool: m_object->isEnabled()];
+
+ if ([attributeName isEqualToString: NSAccessibilitySizeAttribute]) {
+ IntSize s = m_object->size();
+ return [NSValue valueWithSize: NSMakeSize(s.width(), s.height())];
+ }
+
+ if ([attributeName isEqualToString: NSAccessibilityPositionAttribute])
+ return [self position];
+
+ if ([attributeName isEqualToString: NSAccessibilityWindowAttribute] ||
+ [attributeName isEqualToString: NSAccessibilityTopLevelUIElementAttribute]) {
+ FrameView* fv = m_object->documentFrameView();
+ if (fv)
+ return [fv->platformWidget() window];
+ return nil;
+ }
+
+ if (m_object->isDataTable()) {
+ // TODO: distinguish between visible and non-visible rows
+ if ([attributeName isEqualToString:NSAccessibilityRowsAttribute] ||
+ [attributeName isEqualToString:NSAccessibilityVisibleRowsAttribute]) {
+ return convertToNSArray(static_cast<AccessibilityTable*>(m_object)->rows());
+ }
+ // TODO: distinguish between visible and non-visible columns
+ if ([attributeName isEqualToString:NSAccessibilityColumnsAttribute] ||
+ [attributeName isEqualToString:NSAccessibilityVisibleColumnsAttribute]) {
+ return convertToNSArray(static_cast<AccessibilityTable*>(m_object)->columns());
+ }
+
+ // HTML tables don't support these
+ if ([attributeName isEqualToString:NSAccessibilitySelectedColumnsAttribute] ||
+ [attributeName isEqualToString:NSAccessibilitySelectedRowsAttribute] ||
+ [attributeName isEqualToString:NSAccessibilitySelectedCellsAttribute])
+ return nil;
+
+ if ([attributeName isEqualToString:(NSString *)kAXColumnHeaderUIElementsAttribute]) {
+ AccessibilityObject::AccessibilityChildrenVector columnHeaders;
+ static_cast<AccessibilityTable*>(m_object)->columnHeaders(columnHeaders);
+ return convertToNSArray(columnHeaders);
+ }
+
+ if ([attributeName isEqualToString:NSAccessibilityHeaderAttribute]) {
+ AccessibilityObject* headerContainer = static_cast<AccessibilityTable*>(m_object)->headerContainer();
+ if (headerContainer)
+ return headerContainer->wrapper();
+ return nil;
+ }
+
+ if ([attributeName isEqualToString:NSAccessibilityRowHeaderUIElementsAttribute]) {
+ AccessibilityObject::AccessibilityChildrenVector rowHeaders;
+ static_cast<AccessibilityTable*>(m_object)->rowHeaders(rowHeaders);
+ return convertToNSArray(rowHeaders);
+ }
+
+ if ([attributeName isEqualToString:NSAccessibilityVisibleCellsAttribute]) {
+ AccessibilityObject::AccessibilityChildrenVector cells;
+ static_cast<AccessibilityTable*>(m_object)->cells(cells);
+ return convertToNSArray(cells);
+ }
+ }
+
+ if (m_object->isTableRow()) {
+ if ([attributeName isEqualToString:NSAccessibilityIndexAttribute])
+ return [NSNumber numberWithInt:static_cast<AccessibilityTableRow*>(m_object)->rowIndex()];
+ }
+
+ if (m_object->isTableColumn()) {
+ if ([attributeName isEqualToString:NSAccessibilityIndexAttribute])
+ return [NSNumber numberWithInt:static_cast<AccessibilityTableColumn*>(m_object)->columnIndex()];
+
+ // rows attribute for a column is the list of all the elements in that column at each row
+ if ([attributeName isEqualToString:NSAccessibilityRowsAttribute] ||
+ [attributeName isEqualToString:NSAccessibilityVisibleRowsAttribute]) {
+ return convertToNSArray(static_cast<AccessibilityTableColumn*>(m_object)->children());
+ }
+ if ([attributeName isEqualToString:NSAccessibilityHeaderAttribute]) {
+ AccessibilityObject* header = static_cast<AccessibilityTableColumn*>(m_object)->headerObject();
+ if (!header)
+ return nil;
+ return header->wrapper();
+ }
+ }
+
+ if (m_object->isTableCell()) {
+ if ([attributeName isEqualToString:NSAccessibilityRowIndexRangeAttribute]) {
+ pair<int, int> rowRange;
+ static_cast<AccessibilityTableCell*>(m_object)->rowIndexRange(rowRange);
+ return [NSValue valueWithRange:NSMakeRange(rowRange.first, rowRange.second)];
+ }
+ if ([attributeName isEqualToString:NSAccessibilityColumnIndexRangeAttribute]) {
+ pair<int, int> columnRange;
+ static_cast<AccessibilityTableCell*>(m_object)->columnIndexRange(columnRange);
+ return [NSValue valueWithRange:NSMakeRange(columnRange.first, columnRange.second)];
+ }
+ }
+
+ if ((m_object->isListBox() ||m_object->isList()) && [attributeName isEqualToString:NSAccessibilityOrientationAttribute])
+ return NSAccessibilityVerticalOrientationValue;
+
+ if ([attributeName isEqualToString: @"AXSelectedTextMarkerRange"])
+ return [self textMarkerRangeForSelection];
+
+ if (m_object->isAccessibilityRenderObject()) {
+ RenderObject* renderer = static_cast<AccessibilityRenderObject*>(m_object)->renderer();
+ if (!renderer)
+ return nil;
+
+ if ([attributeName isEqualToString: @"AXStartTextMarker"])
+ return textMarkerForVisiblePosition(startOfDocument(renderer->document()));
+ if ([attributeName isEqualToString: @"AXEndTextMarker"])
+ return textMarkerForVisiblePosition(endOfDocument(renderer->document()));
+
+ if ([attributeName isEqualToString: @"AXBlockQuoteLevel"])
+ return [NSNumber numberWithInt:blockquoteLevel(renderer)];
+ }
+
+ if ([attributeName isEqualToString: NSAccessibilityLinkedUIElementsAttribute]) {
+ AccessibilityObject::AccessibilityChildrenVector linkedUIElements;
+ m_object->linkedUIElements(linkedUIElements);
+ if (linkedUIElements.size() == 0)
+ return nil;
+ return convertToNSArray(linkedUIElements);
+ }
+
+ if ([attributeName isEqualToString: NSAccessibilitySelectedAttribute])
+ return [NSNumber numberWithBool:m_object->isSelected()];
+
+ if ([attributeName isEqualToString: NSAccessibilityServesAsTitleForUIElementsAttribute] && m_object->isMenuButton()) {
+ AccessibilityObject* uiElement = static_cast<AccessibilityRenderObject*>(m_object)->menuForMenuButton();
+ if (uiElement)
+ return [NSArray arrayWithObject:uiElement->wrapper()];
+ }
+
+ if ([attributeName isEqualToString:NSAccessibilityTitleUIElementAttribute]) {
+ AccessibilityObject* obj = m_object->titleUIElement();
+ if (obj)
+ return obj->wrapper();
+ return nil;
+ }
+
+ return nil;
+}
+
+- (id)accessibilityFocusedUIElement
+{
+ RefPtr<AccessibilityObject> focusedObj = m_object->focusedUIElement();
+
+ if (!focusedObj)
+ return nil;
+
+ return focusedObj->wrapper();
+}
+
+- (id)accessibilityHitTest:(NSPoint)point
+{
+ RefPtr<AccessibilityObject> axObject = m_object->doAccessibilityHitTest(IntPoint(point));
+ if (axObject)
+ return NSAccessibilityUnignoredAncestor(axObject->wrapper());
+ return NSAccessibilityUnignoredAncestor(self);
+}
+
+- (BOOL)accessibilityIsAttributeSettable:(NSString*)attributeName
+{
+ if ([attributeName isEqualToString: @"AXSelectedTextMarkerRange"])
+ return YES;
+
+ if ([attributeName isEqualToString: NSAccessibilityFocusedAttribute])
+ return m_object->canSetFocusAttribute();
+
+ if ([attributeName isEqualToString: NSAccessibilityValueAttribute])
+ return m_object->canSetValueAttribute();
+
+ if ([attributeName isEqualToString: NSAccessibilitySelectedAttribute])
+ return m_object->canSetSelectedAttribute();
+
+ if ([attributeName isEqualToString: NSAccessibilitySelectedChildrenAttribute])
+ return m_object->canSetSelectedChildrenAttribute();
+
+ if ([attributeName isEqualToString: NSAccessibilitySelectedTextAttribute] ||
+ [attributeName isEqualToString: NSAccessibilitySelectedTextRangeAttribute] ||
+ [attributeName isEqualToString: NSAccessibilityVisibleCharacterRangeAttribute])
+ return m_object->canSetTextRangeAttributes();
+
+ return NO;
+}
+
+// accessibilityShouldUseUniqueId is an AppKit method we override so that
+// objects will be given a unique ID, and therefore allow AppKit to know when they
+// become obsolete (e.g. when the user navigates to a new web page, making this one
+// unrendered but not deallocated because it is in the back/forward cache).
+// It is important to call NSAccessibilityUnregisterUniqueIdForUIElement in the
+// appropriate place (e.g. dealloc) to remove these non-retained references from
+// AppKit's id mapping tables. We do this in detach by calling unregisterUniqueIdForUIElement.
+//
+// Registering an object is also required for observing notifications. Only registered objects can be observed.
+- (BOOL)accessibilityIsIgnored
+{
+ if (m_object->isAttachment())
+ return [[self attachmentView] accessibilityIsIgnored];
+ return m_object->accessibilityIsIgnored();
+}
+
+- (NSArray* )accessibilityParameterizedAttributeNames
+{
+ if (m_object->isAttachment())
+ return nil;
+
+ static NSArray* paramAttrs = nil;
+ static NSArray* textParamAttrs = nil;
+ static NSArray* tableParamAttrs = nil;
+ if (paramAttrs == nil) {
+ paramAttrs = [[NSArray alloc] initWithObjects:
+ @"AXUIElementForTextMarker",
+ @"AXTextMarkerRangeForUIElement",
+ @"AXLineForTextMarker",
+ @"AXTextMarkerRangeForLine",
+ @"AXStringForTextMarkerRange",
+ @"AXTextMarkerForPosition",
+ @"AXBoundsForTextMarkerRange",
+ @"AXAttributedStringForTextMarkerRange",
+ @"AXTextMarkerRangeForUnorderedTextMarkers",
+ @"AXNextTextMarkerForTextMarker",
+ @"AXPreviousTextMarkerForTextMarker",
+ @"AXLeftWordTextMarkerRangeForTextMarker",
+ @"AXRightWordTextMarkerRangeForTextMarker",
+ @"AXLeftLineTextMarkerRangeForTextMarker",
+ @"AXRightLineTextMarkerRangeForTextMarker",
+ @"AXSentenceTextMarkerRangeForTextMarker",
+ @"AXParagraphTextMarkerRangeForTextMarker",
+ @"AXNextWordEndTextMarkerForTextMarker",
+ @"AXPreviousWordStartTextMarkerForTextMarker",
+ @"AXNextLineEndTextMarkerForTextMarker",
+ @"AXPreviousLineStartTextMarkerForTextMarker",
+ @"AXNextSentenceEndTextMarkerForTextMarker",
+ @"AXPreviousSentenceStartTextMarkerForTextMarker",
+ @"AXNextParagraphEndTextMarkerForTextMarker",
+ @"AXPreviousParagraphStartTextMarkerForTextMarker",
+ @"AXStyleTextMarkerRangeForTextMarker",
+ @"AXLengthForTextMarkerRange",
+ NSAccessibilityBoundsForRangeParameterizedAttribute,
+ nil];
+ }
+
+ if (textParamAttrs == nil) {
+ NSMutableArray* tempArray = [[NSMutableArray alloc] initWithArray:paramAttrs];
+ [tempArray addObject:(NSString*)kAXLineForIndexParameterizedAttribute];
+ [tempArray addObject:(NSString*)kAXRangeForLineParameterizedAttribute];
+ [tempArray addObject:(NSString*)kAXStringForRangeParameterizedAttribute];
+ [tempArray addObject:(NSString*)kAXRangeForPositionParameterizedAttribute];
+ [tempArray addObject:(NSString*)kAXRangeForIndexParameterizedAttribute];
+ [tempArray addObject:(NSString*)kAXBoundsForRangeParameterizedAttribute];
+ [tempArray addObject:(NSString*)kAXRTFForRangeParameterizedAttribute];
+ [tempArray addObject:(NSString*)kAXAttributedStringForRangeParameterizedAttribute];
+ [tempArray addObject:(NSString*)kAXStyleRangeForIndexParameterizedAttribute];
+ textParamAttrs = [[NSArray alloc] initWithArray:tempArray];
+ [tempArray release];
+ }
+ if (tableParamAttrs == nil) {
+ NSMutableArray* tempArray = [[NSMutableArray alloc] initWithArray:paramAttrs];
+ [tempArray addObject:NSAccessibilityCellForColumnAndRowParameterizedAttribute];
+ tableParamAttrs = [[NSArray alloc] initWithArray:tempArray];
+ [tempArray release];
+ }
+
+ if (m_object->isPasswordField())
+ return [NSArray array];
+
+ if (!m_object->isAccessibilityRenderObject())
+ return paramAttrs;
+
+ if (m_object->isTextControl())
+ return textParamAttrs;
+
+ if (m_object->isDataTable())
+ return tableParamAttrs;
+
+ if (m_object->isMenuRelated())
+ return nil;
+
+ return paramAttrs;
+}
+
+- (void)accessibilityPerformPressAction
+{
+ if (m_object->isAttachment())
+ [[self attachmentView] accessibilityPerformAction:NSAccessibilityPressAction];
+
+ m_object->press();
+}
+
+- (void)accessibilityPerformShowMenuAction
+{
+ // This needs to be performed in an iteration of the run loop that did not start from an AX call.
+ // If it's the same run loop iteration, the menu open notification won't be sent
+ [self performSelector:@selector(accessibilityShowContextMenu) withObject:nil afterDelay:0.0];
+}
+
+- (void)accessibilityShowContextMenu
+{
+ FrameView* frameView = m_object->documentFrameView();
+ if (!frameView)
+ return;
+
+ // simulate a click in the middle of the object
+ IntPoint clickPoint = m_object->clickPoint();
+ NSPoint nsClickPoint = NSMakePoint(clickPoint.x(), clickPoint.y());
+
+ NSView* view = nil;
+ if (m_object->isAttachment())
+ view = [self attachmentView];
+ else
+ view = frameView->documentView();
+
+ if (!view)
+ return;
+
+ NSPoint nsScreenPoint = [view convertPoint:nsClickPoint toView:nil];
+
+ // Show the contextual menu for this event.
+ NSEvent* event = [NSEvent mouseEventWithType:NSRightMouseDown location:nsScreenPoint modifierFlags:0 timestamp:0 windowNumber:[[view window] windowNumber] context:0 eventNumber:0 clickCount:1 pressure:1];
+ NSMenu* menu = [view menuForEvent:event];
+
+ if (menu)
+ [NSMenu popUpContextMenu:menu withEvent:event forView:view];
+}
+
+- (void)accessibilityPerformAction:(NSString*)action
+{
+ if ([action isEqualToString:NSAccessibilityPressAction])
+ [self accessibilityPerformPressAction];
+
+ else if ([action isEqualToString:NSAccessibilityShowMenuAction])
+ [self accessibilityPerformShowMenuAction];
+}
+
+- (void)accessibilitySetValue:(id)value forAttribute:(NSString*)attributeName
+{
+ WebCoreTextMarkerRange* textMarkerRange = nil;
+ NSNumber* number = nil;
+ NSString* string = nil;
+ NSRange range = {0, 0};
+ NSArray* array = nil;
+
+ // decode the parameter
+ if ([[WebCoreViewFactory sharedFactory] objectIsTextMarkerRange:value])
+ textMarkerRange = (WebCoreTextMarkerRange*) value;
+
+ else if ([value isKindOfClass:[NSNumber self]])
+ number = value;
+
+ else if ([value isKindOfClass:[NSString self]])
+ string = value;
+
+ else if ([value isKindOfClass:[NSValue self]])
+ range = [value rangeValue];
+
+ else if ([value isKindOfClass:[NSArray self]])
+ array = value;
+
+ // handle the command
+ if ([attributeName isEqualToString: @"AXSelectedTextMarkerRange"]) {
+ ASSERT(textMarkerRange);
+ m_object->setSelectedVisiblePositionRange([self visiblePositionRangeForTextMarkerRange:textMarkerRange]);
+ } else if ([attributeName isEqualToString: NSAccessibilityFocusedAttribute]) {
+ ASSERT(number);
+ m_object->setFocused([number intValue] != 0);
+ } else if ([attributeName isEqualToString: NSAccessibilityValueAttribute]) {
+ if (!string)
+ return;
+ m_object->setValue(string);
+ } else if ([attributeName isEqualToString: NSAccessibilitySelectedAttribute]) {
+ if (!number)
+ return;
+ m_object->setSelected([number boolValue]);
+ } else if ([attributeName isEqualToString: NSAccessibilitySelectedChildrenAttribute]) {
+ if (!array || m_object->roleValue() != ListBoxRole)
+ return;
+ AccessibilityObject::AccessibilityChildrenVector selectedChildren;
+ convertToVector(array, selectedChildren);
+ static_cast<AccessibilityListBox*>(m_object)->setSelectedChildren(selectedChildren);
+ } else if (m_object->isTextControl()) {
+ if ([attributeName isEqualToString: NSAccessibilitySelectedTextAttribute]) {
+ m_object->setSelectedText(string);
+ } else if ([attributeName isEqualToString: NSAccessibilitySelectedTextRangeAttribute]) {
+ m_object->setSelectedTextRange(PlainTextRange(range.location, range.length));
+ } else if ([attributeName isEqualToString: NSAccessibilityVisibleCharacterRangeAttribute]) {
+ m_object->makeRangeVisible(PlainTextRange(range.location, range.length));
+ }
+ }
+}
+
+static RenderObject* rendererForView(NSView* view)
+{
+ if (![view conformsToProtocol:@protocol(WebCoreFrameView)])
+ return 0;
+
+ NSView<WebCoreFrameView>* frameView = (NSView<WebCoreFrameView>*)view;
+ Frame* frame = [frameView _web_frame];
+ if (!frame)
+ return 0;
+
+ Node* node = frame->document()->ownerElement();
+ if (!node)
+ return 0;
+
+ return node->renderer();
+}
+
+- (id)_accessibilityParentForSubview:(NSView*)subview
+{
+ RenderObject* renderer = rendererForView(subview);
+ if (!renderer)
+ return nil;
+
+ AccessibilityObject* obj = renderer->document()->axObjectCache()->get(renderer);
+ if (obj)
+ return obj->parentObjectUnignored()->wrapper();
+ return nil;
+}
+
+- (NSString*)accessibilityActionDescription:(NSString*)action
+{
+ // we have no custom actions
+ return NSAccessibilityActionDescription(action);
+}
+
+// The CFAttributedStringType representation of the text associated with this accessibility
+// object that is specified by the given range.
+- (NSAttributedString*)doAXAttributedStringForRange:(NSRange)range
+{
+ PlainTextRange textRange = PlainTextRange(range.location, range.length);
+ VisiblePositionRange visiblePosRange = m_object->visiblePositionRangeForRange(textRange);
+ return [self doAXAttributedStringForTextMarkerRange:textMarkerRangeFromVisiblePositions(visiblePosRange.start, visiblePosRange.end)];
+}
+
+// The RTF representation of the text associated with this accessibility object that is
+// specified by the given range.
+- (NSData*)doAXRTFForRange:(NSRange)range
+{
+ NSAttributedString* attrString = [self doAXAttributedStringForRange:range];
+ return [attrString RTFFromRange: NSMakeRange(0, [attrString length]) documentAttributes: nil];
+}
+
+- (id)accessibilityAttributeValue:(NSString*)attribute forParameter:(id)parameter
+{
+ WebCoreTextMarker* textMarker = nil;
+ WebCoreTextMarkerRange* textMarkerRange = nil;
+ NSNumber* number = nil;
+ NSArray* array = nil;
+ RefPtr<AccessibilityObject> uiElement = 0;
+ NSPoint point = NSZeroPoint;
+ bool pointSet = false;
+ NSRange range = {0, 0};
+ bool rangeSet = false;
+
+ // basic parameter validation
+ if (!m_object || !attribute || !parameter)
+ return nil;
+
+ // common parameter type check/casting. Nil checks in handlers catch wrong type case.
+ // NOTE: This assumes nil is not a valid parameter, because it is indistinguishable from
+ // a parameter of the wrong type.
+ if ([[WebCoreViewFactory sharedFactory] objectIsTextMarker:parameter])
+ textMarker = (WebCoreTextMarker*) parameter;
+
+ else if ([[WebCoreViewFactory sharedFactory] objectIsTextMarkerRange:parameter])
+ textMarkerRange = (WebCoreTextMarkerRange*) parameter;
+
+ else if ([parameter isKindOfClass:[AccessibilityObjectWrapper self]])
+ uiElement = [(AccessibilityObjectWrapper*)parameter accessibilityObject];
+
+ else if ([parameter isKindOfClass:[NSNumber self]])
+ number = parameter;
+
+ else if ([parameter isKindOfClass:[NSArray self]])
+ array = parameter;
+
+ else if ([parameter isKindOfClass:[NSValue self]] && strcmp([(NSValue*)parameter objCType], @encode(NSPoint)) == 0) {
+ pointSet = true;
+ point = [(NSValue*)parameter pointValue];
+
+ } else if ([parameter isKindOfClass:[NSValue self]] && strcmp([(NSValue*)parameter objCType], @encode(NSRange)) == 0) {
+ rangeSet = true;
+ range = [(NSValue*)parameter rangeValue];
+
+ } else {
+ // got a parameter of a type we never use
+ // NOTE: No ASSERT_NOT_REACHED because this can happen accidentally
+ // while using accesstool (e.g.), forcing you to start over
+ return nil;
+ }
+
+ // Convert values to WebCore types
+ // FIXME: prepping all of these values as WebCore types is unnecessary in many
+ // cases. Re-organization of this function or performing the conversion on a
+ // need basis are possible improvements.
+ VisiblePosition visiblePos;
+ if (textMarker)
+ visiblePos = visiblePositionForTextMarker(textMarker);
+ int intNumber = [number intValue];
+ VisiblePositionRange visiblePosRange;
+ if (textMarkerRange)
+ visiblePosRange = [self visiblePositionRangeForTextMarkerRange:textMarkerRange];
+ IntPoint webCorePoint = IntPoint(point);
+ PlainTextRange plainTextRange = PlainTextRange(range.location, range.length);
+
+ // dispatch
+ if ([attribute isEqualToString: @"AXUIElementForTextMarker"])
+ return m_object->accessibilityObjectForPosition(visiblePos)->wrapper();
+
+ if ([attribute isEqualToString: @"AXTextMarkerRangeForUIElement"]) {
+ VisiblePositionRange vpRange = uiElement.get()->visiblePositionRange();
+ return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end);
+ }
+
+ if ([attribute isEqualToString: @"AXLineForTextMarker"])
+ return [NSNumber numberWithUnsignedInt:m_object->lineForPosition(visiblePos)];
+
+ if ([attribute isEqualToString: @"AXTextMarkerRangeForLine"]) {
+ VisiblePositionRange vpRange = m_object->visiblePositionRangeForLine(intNumber);
+ return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end);
+ }
+
+ if ([attribute isEqualToString: @"AXStringForTextMarkerRange"])
+ return m_object->stringForVisiblePositionRange(visiblePosRange);
+
+ if ([attribute isEqualToString: @"AXTextMarkerForPosition"])
+ return pointSet ? textMarkerForVisiblePosition(m_object->visiblePositionForPoint(webCorePoint)) : nil;
+
+ if ([attribute isEqualToString: @"AXBoundsForTextMarkerRange"]) {
+ NSRect rect = m_object->boundsForVisiblePositionRange(visiblePosRange);
+ return [NSValue valueWithRect:rect];
+ }
+
+ if ([attribute isEqualToString:NSAccessibilityBoundsForRangeParameterizedAttribute]) {
+ VisiblePosition start = m_object->visiblePositionForIndex(range.location);
+ VisiblePosition end = m_object->visiblePositionForIndex(range.location+range.length);
+ if (start.isNull() || end.isNull())
+ return nil;
+ NSRect rect = m_object->boundsForVisiblePositionRange(VisiblePositionRange(start, end));
+ return [NSValue valueWithRect:rect];
+ }
+
+ if ([attribute isEqualToString: @"AXAttributedStringForTextMarkerRange"])
+ return [self doAXAttributedStringForTextMarkerRange:textMarkerRange];
+
+ if ([attribute isEqualToString: @"AXTextMarkerRangeForUnorderedTextMarkers"]) {
+ if ([array count] < 2)
+ return nil;
+
+ WebCoreTextMarker* textMarker1 = (WebCoreTextMarker*) [array objectAtIndex:0];
+ WebCoreTextMarker* textMarker2 = (WebCoreTextMarker*) [array objectAtIndex:1];
+ if (![[WebCoreViewFactory sharedFactory] objectIsTextMarker:textMarker1]
+ || ![[WebCoreViewFactory sharedFactory] objectIsTextMarker:textMarker2])
+ return nil;
+
+ VisiblePosition visiblePos1 = visiblePositionForTextMarker(textMarker1);
+ VisiblePosition visiblePos2 = visiblePositionForTextMarker(textMarker2);
+ VisiblePositionRange vpRange = m_object->visiblePositionRangeForUnorderedPositions(visiblePos1, visiblePos2);
+ return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end);
+ }
+
+ if ([attribute isEqualToString: @"AXNextTextMarkerForTextMarker"])
+ return textMarkerForVisiblePosition(m_object->nextVisiblePosition(visiblePos));
+
+ if ([attribute isEqualToString: @"AXPreviousTextMarkerForTextMarker"])
+ return textMarkerForVisiblePosition(m_object->previousVisiblePosition(visiblePos));
+
+ if ([attribute isEqualToString: @"AXLeftWordTextMarkerRangeForTextMarker"]) {
+ VisiblePositionRange vpRange = m_object->positionOfLeftWord(visiblePos);
+ return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end);
+ }
+
+ if ([attribute isEqualToString: @"AXRightWordTextMarkerRangeForTextMarker"]) {
+ VisiblePositionRange vpRange = m_object->positionOfRightWord(visiblePos);
+ return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end);
+ }
+
+ if ([attribute isEqualToString: @"AXLeftLineTextMarkerRangeForTextMarker"]) {
+ VisiblePositionRange vpRange = m_object->leftLineVisiblePositionRange(visiblePos);
+ return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end);
+ }
+
+ if ([attribute isEqualToString: @"AXRightLineTextMarkerRangeForTextMarker"]) {
+ VisiblePositionRange vpRange = m_object->rightLineVisiblePositionRange(visiblePos);
+ return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end);
+ }
+
+ if ([attribute isEqualToString: @"AXSentenceTextMarkerRangeForTextMarker"]) {
+ VisiblePositionRange vpRange = m_object->sentenceForPosition(visiblePos);
+ return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end);
+ }
+
+ if ([attribute isEqualToString: @"AXParagraphTextMarkerRangeForTextMarker"]) {
+ VisiblePositionRange vpRange = m_object->paragraphForPosition(visiblePos);
+ return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end);
+ }
+
+ if ([attribute isEqualToString: @"AXNextWordEndTextMarkerForTextMarker"])
+ return textMarkerForVisiblePosition(m_object->nextWordEnd(visiblePos));
+
+ if ([attribute isEqualToString: @"AXPreviousWordStartTextMarkerForTextMarker"])
+ return textMarkerForVisiblePosition(m_object->previousWordStart(visiblePos));
+
+ if ([attribute isEqualToString: @"AXNextLineEndTextMarkerForTextMarker"])
+ return textMarkerForVisiblePosition(m_object->nextLineEndPosition(visiblePos));
+
+ if ([attribute isEqualToString: @"AXPreviousLineStartTextMarkerForTextMarker"])
+ return textMarkerForVisiblePosition(m_object->previousLineStartPosition(visiblePos));
+
+ if ([attribute isEqualToString: @"AXNextSentenceEndTextMarkerForTextMarker"])
+ return textMarkerForVisiblePosition(m_object->nextSentenceEndPosition(visiblePos));
+
+ if ([attribute isEqualToString: @"AXPreviousSentenceStartTextMarkerForTextMarker"])
+ return textMarkerForVisiblePosition(m_object->previousSentenceStartPosition(visiblePos));
+
+ if ([attribute isEqualToString: @"AXNextParagraphEndTextMarkerForTextMarker"])
+ return textMarkerForVisiblePosition(m_object->nextParagraphEndPosition(visiblePos));
+
+ if ([attribute isEqualToString: @"AXPreviousParagraphStartTextMarkerForTextMarker"])
+ return textMarkerForVisiblePosition(m_object->previousParagraphStartPosition(visiblePos));
+
+ if ([attribute isEqualToString: @"AXStyleTextMarkerRangeForTextMarker"]) {
+ VisiblePositionRange vpRange = m_object->styleRangeForPosition(visiblePos);
+ return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end);
+ }
+
+ if ([attribute isEqualToString: @"AXLengthForTextMarkerRange"]) {
+ int length = m_object->lengthForVisiblePositionRange(visiblePosRange);
+ if (length < 0)
+ return nil;
+ return [NSNumber numberWithInt:length];
+ }
+
+ if (m_object->isDataTable()) {
+ if ([attribute isEqualToString:NSAccessibilityCellForColumnAndRowParameterizedAttribute]) {
+ if (array == nil || [array count] != 2)
+ return nil;
+ AccessibilityTableCell* cell = static_cast<AccessibilityTable*>(m_object)->cellForColumnAndRow([[array objectAtIndex:0] unsignedIntValue], [[array objectAtIndex:1] unsignedIntValue]);
+ if (!cell)
+ return nil;
+
+ return cell->wrapper();
+ }
+ }
+
+ if (m_object->isTextControl()) {
+ if ([attribute isEqualToString: (NSString *)kAXLineForIndexParameterizedAttribute]) {
+ int lineNumber = m_object->doAXLineForIndex(intNumber);
+ if (lineNumber < 0)
+ return nil;
+ return [NSNumber numberWithUnsignedInt:lineNumber];
+ }
+
+ if ([attribute isEqualToString: (NSString *)kAXRangeForLineParameterizedAttribute]) {
+ PlainTextRange textRange = m_object->doAXRangeForLine(intNumber);
+ return [NSValue valueWithRange: NSMakeRange(textRange.start, textRange.length)];
+ }
+
+ if ([attribute isEqualToString: (NSString*)kAXStringForRangeParameterizedAttribute])
+ return rangeSet ? (id)(m_object->doAXStringForRange(plainTextRange)) : nil;
+
+ if ([attribute isEqualToString: (NSString*)kAXRangeForPositionParameterizedAttribute]) {
+ if (!pointSet)
+ return nil;
+ PlainTextRange textRange = m_object->doAXRangeForPosition(webCorePoint);
+ return [NSValue valueWithRange: NSMakeRange(textRange.start, textRange.length)];
+ }
+
+ if ([attribute isEqualToString: (NSString*)kAXRangeForIndexParameterizedAttribute]) {
+ PlainTextRange textRange = m_object->doAXRangeForIndex(intNumber);
+ return [NSValue valueWithRange: NSMakeRange(textRange.start, textRange.length)];
+ }
+
+ if ([attribute isEqualToString: (NSString*)kAXBoundsForRangeParameterizedAttribute]) {
+ if (!rangeSet)
+ return nil;
+ NSRect rect = m_object->doAXBoundsForRange(plainTextRange);
+ return [NSValue valueWithRect:rect];
+ }
+
+ if ([attribute isEqualToString: (NSString*)kAXRTFForRangeParameterizedAttribute])
+ return rangeSet ? [self doAXRTFForRange:range] : nil;
+
+ if ([attribute isEqualToString: (NSString*)kAXAttributedStringForRangeParameterizedAttribute])
+ return rangeSet ? [self doAXAttributedStringForRange:range] : nil;
+
+ if ([attribute isEqualToString: (NSString*)kAXStyleRangeForIndexParameterizedAttribute]) {
+ PlainTextRange textRange = m_object->doAXStyleRangeForIndex(intNumber);
+ return [NSValue valueWithRange: NSMakeRange(textRange.start, textRange.length)];
+ }
+ }
+
+ return nil;
+}
+
+- (BOOL)accessibilityShouldUseUniqueId
+{
+ return m_object->accessibilityShouldUseUniqueId();
+}
+
+// API that AppKit uses for faster access
+- (NSUInteger)accessibilityIndexOfChild:(id)child
+{
+ const AccessibilityObject::AccessibilityChildrenVector& children = m_object->children();
+
+ if (children.isEmpty())
+ return [[self renderWidgetChildren] indexOfObject:child];
+
+ unsigned count = children.size();
+ for (unsigned k = 0; k < count; ++k) {
+ if (children[k]->wrapper() == child)
+ return k;
+ }
+
+ return NSNotFound;
+}
+
+- (NSUInteger)accessibilityArrayAttributeCount:(NSString *)attribute
+{
+ if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
+ const AccessibilityObject::AccessibilityChildrenVector& children = m_object->children();
+ if (children.isEmpty())
+ return [[self renderWidgetChildren] count];
+
+ return children.size();
+ }
+
+ return [super accessibilityArrayAttributeCount:attribute];
+}
+
+- (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute index:(NSUInteger)index maxCount:(NSUInteger)maxCount
+{
+ if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
+ if (m_object->children().isEmpty()) {
+ NSArray *children = [self renderWidgetChildren];
+ if (!children)
+ return nil;
+
+ NSUInteger childCount = [children count];
+ if (index >= childCount)
+ return nil;
+
+ NSUInteger arrayLength = min(childCount - index, maxCount);
+ return [children subarrayWithRange:NSMakeRange(index, arrayLength)];
+ }
+
+ const AccessibilityObject::AccessibilityChildrenVector& children = m_object->children();
+ unsigned childCount = children.size();
+ if (index >= childCount)
+ return nil;
+
+ unsigned available = min(childCount - index, maxCount);
+
+ NSMutableArray *subarray = [NSMutableArray arrayWithCapacity:available];
+ for (unsigned added = 0; added < available; ++index, ++added)
+ [subarray addObject:children[index]->wrapper()];
+
+ return subarray;
+ }
+
+ return [super accessibilityArrayAttributeValues:attribute index:index maxCount:maxCount];
+}
+
+@end
diff --git a/WebCore/page/mac/ChromeMac.mm b/WebCore/page/mac/ChromeMac.mm
index 9fc8107..aba3449 100644
--- a/WebCore/page/mac/ChromeMac.mm
+++ b/WebCore/page/mac/ChromeMac.mm
@@ -1,6 +1,5 @@
-// -*- mode: c++; c-basic-offset: 4 -*-
/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -22,8 +21,7 @@
#import "Chrome.h"
#import "BlockExceptions.h"
-#import "Frame.h"
-#import "Page.h"
+#import "ChromeClient.h"
namespace WebCore {
@@ -31,25 +29,23 @@ void Chrome::focusNSView(NSView* view)
{
BEGIN_BLOCK_OBJC_EXCEPTIONS;
- WebCoreFrameBridge *bridge = m_page->mainFrame()->bridge();
- NSResponder *firstResponder = [bridge firstResponder];
+ NSResponder *firstResponder = client()->firstResponder();
if (firstResponder == view)
return;
if (![view window] || ![view superview] || ![view acceptsFirstResponder])
return;
- [bridge makeFirstResponder:view];
+ client()->makeFirstResponder(view);
// Setting focus can actually cause a style change which might
// remove the view from its superview while it's being made
// first responder. This confuses AppKit so we must restore
// the old first responder.
if (![view superview])
- [bridge makeFirstResponder:firstResponder];
+ client()->makeFirstResponder(firstResponder);
END_BLOCK_OBJC_EXCEPTIONS;
}
} // namespace WebCore
-
diff --git a/WebCore/page/mac/EventHandlerMac.mm b/WebCore/page/mac/EventHandlerMac.mm
index ca2f94c..562c1dd 100644
--- a/WebCore/page/mac/EventHandlerMac.mm
+++ b/WebCore/page/mac/EventHandlerMac.mm
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,35 +27,27 @@
#include "EventHandler.h"
#include "BlockExceptions.h"
+#include "ChromeClient.h"
#include "ClipboardMac.h"
-#include "Cursor.h"
-#include "Document.h"
-#include "DragController.h"
#include "EventNames.h"
-#include "FloatPoint.h"
#include "FocusController.h"
-#include "FoundationExtras.h"
#include "FrameLoader.h"
#include "Frame.h"
-#include "FrameTree.h"
#include "FrameView.h"
-#include "HTMLFrameOwnerElement.h"
-#include "HTMLFrameSetElement.h"
-#include "HitTestRequest.h"
-#include "HitTestResult.h"
#include "KeyboardEvent.h"
#include "MouseEventWithHitTestResults.h"
#include "Page.h"
#include "PlatformKeyboardEvent.h"
-#include "PlatformScrollBar.h"
#include "PlatformWheelEvent.h"
#include "RenderWidget.h"
+#include "Scrollbar.h"
#include "Settings.h"
-#include "WebCoreFrameBridge.h"
namespace WebCore {
-using namespace EventNames;
+unsigned EventHandler::s_accessKeyModifiers = PlatformKeyboardEvent::CtrlKey | PlatformKeyboardEvent::AltKey;
+
+const double EventHandler::TextDragDelay = 0.15;
static RetainPtr<NSEvent>& currentEvent()
{
@@ -91,10 +83,10 @@ PassRefPtr<KeyboardEvent> EventHandler::currentKeyboardEvent() const
case NSKeyDown: {
PlatformKeyboardEvent platformEvent(event);
platformEvent.disambiguateKeyDownEvent(PlatformKeyboardEvent::RawKeyDown);
- return new KeyboardEvent(platformEvent, m_frame->document() ? m_frame->document()->defaultView() : 0);
+ return KeyboardEvent::create(platformEvent, m_frame->document() ? m_frame->document()->defaultView() : 0);
}
case NSKeyUp:
- return new KeyboardEvent(event, m_frame->document() ? m_frame->document()->defaultView() : 0);
+ return KeyboardEvent::create(event, m_frame->document() ? m_frame->document()->defaultView() : 0);
default:
return 0;
}
@@ -103,9 +95,9 @@ PassRefPtr<KeyboardEvent> EventHandler::currentKeyboardEvent() const
static inline bool isKeyboardOptionTab(KeyboardEvent* event)
{
return event
- && (event->type() == keydownEvent || event->type() == keypressEvent)
- && event->altKey()
- && event->keyIdentifier() == "U+0009";
+ && (event->type() == eventNames().keydownEvent || event->type() == eventNames().keypressEvent)
+ && event->altKey()
+ && event->keyIdentifier() == "U+0009";
}
bool EventHandler::invertSenseOfTabsToLinks(KeyboardEvent* event) const
@@ -115,7 +107,11 @@ bool EventHandler::invertSenseOfTabsToLinks(KeyboardEvent* event) const
bool EventHandler::tabsToAllControls(KeyboardEvent* event) const
{
- KeyboardUIMode keyboardUIMode = [m_frame->bridge() keyboardUIMode];
+ Page* page = m_frame->page();
+ if (!page)
+ return false;
+
+ KeyboardUIMode keyboardUIMode = page->chrome()->client()->keyboardUIMode();
bool handlingOptionTab = isKeyboardOptionTab(event);
// If tab-to-links is off, option-tab always highlights all controls
@@ -148,12 +144,21 @@ bool EventHandler::needsKeyboardEventDisambiguationQuirks() const
return false;
// RSS view needs arrow key keypress events.
- if (isSafari && document->url().startsWith("feed:", false) || document->url().startsWith("feeds:", false))
+ if (isSafari && document->url().protocolIs("feed") || document->url().protocolIs("feeds"))
return true;
Settings* settings = m_frame->settings();
if (!settings)
return false;
- return settings->usesDashboardBackwardCompatibilityMode() || settings->needsKeyboardEventDisambiguationQuirks();
+
+#if ENABLE(DASHBOARD_SUPPORT)
+ if (settings->usesDashboardBackwardCompatibilityMode())
+ return true;
+#endif
+
+ if (settings->needsKeyboardEventDisambiguationQuirks())
+ return true;
+
+ return false;
}
bool EventHandler::keyEvent(NSEvent *event)
@@ -184,10 +189,11 @@ void EventHandler::focusDocumentView()
if (!page)
return;
- if (FrameView* frameView = m_frame->view())
- if (NSView *documentView = frameView->getDocumentView())
+ if (FrameView* frameView = m_frame->view()) {
+ if (NSView *documentView = frameView->documentView())
page->chrome()->focusNSView(documentView);
-
+ }
+
page->focusController()->setFocusedFrame(m_frame);
}
@@ -239,7 +245,7 @@ bool EventHandler::passMouseDownEventToWidget(Widget* widget)
BEGIN_BLOCK_OBJC_EXCEPTIONS;
- NSView *nodeView = widget->getView();
+ NSView *nodeView = widget->platformWidget();
ASSERT(nodeView);
ASSERT([nodeView superview]);
NSView *view = [nodeView hitTest:[[nodeView superview] convertPoint:[currentEvent().get() locationInWindow] fromView:nil]];
@@ -248,11 +254,15 @@ bool EventHandler::passMouseDownEventToWidget(Widget* widget)
return true;
}
- if ([m_frame->bridge() firstResponder] != view) {
+ Page* page = m_frame->page();
+ if (!page)
+ return true;
+
+ if (page->chrome()->client()->firstResponder() != view) {
// Normally [NSWindow sendEvent:] handles setting the first responder.
// But in our case, the event was sent to the view representing the entire web page.
if ([currentEvent().get() clickCount] <= 1 && [view acceptsFirstResponder] && [view needsPanelToBecomeKey])
- [m_frame->bridge() makeFirstResponder:view];
+ page->chrome()->client()->makeFirstResponder(view);
}
// We need to "defer loading" while tracking the mouse, because tearing down the
@@ -262,9 +272,9 @@ bool EventHandler::passMouseDownEventToWidget(Widget* widget)
// mouse. We should confirm that, and then remove the deferrsLoading
// hack entirely.
- bool wasDeferringLoading = m_frame->page()->defersLoading();
+ bool wasDeferringLoading = page->defersLoading();
if (!wasDeferringLoading)
- m_frame->page()->setDefersLoading(true);
+ page->setDefersLoading(true);
ASSERT(!m_sendingEventToSubview);
m_sendingEventToSubview = true;
@@ -272,7 +282,7 @@ bool EventHandler::passMouseDownEventToWidget(Widget* widget)
m_sendingEventToSubview = false;
if (!wasDeferringLoading)
- m_frame->page()->setDefersLoading(false);
+ page->setDefersLoading(false);
// Remember which view we sent the event to, so we can direct the release event properly.
m_mouseDownView = view;
@@ -319,7 +329,7 @@ NSView *EventHandler::mouseDownViewIfStillGood()
return nil;
}
FrameView* topFrameView = m_frame->view();
- NSView *topView = topFrameView ? topFrameView->getView() : nil;
+ NSView *topView = topFrameView ? topFrameView->platformWidget() : nil;
if (!topView || !findViewInSubviews(topView, mouseDownView)) {
m_mouseDownView = nil;
return nil;
@@ -350,13 +360,13 @@ bool EventHandler::eventLoopHandleMouseDragged(const MouseEventWithHitTestResult
return true;
}
-Clipboard* EventHandler::createDraggingClipboard() const
+PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const
{
NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName:NSDragPboard];
// Must be done before ondragstart adds types and data to the pboard,
// also done for security, as it erases data from the last drag
[pasteboard declareTypes:[NSArray array] owner:nil];
- return new ClipboardMac(true, pasteboard, ClipboardWritable, m_frame);
+ return ClipboardMac::create(true, pasteboard, ClipboardWritable, m_frame);
}
bool EventHandler::eventLoopHandleMouseUp(const MouseEventWithHitTestResults&)
@@ -442,7 +452,7 @@ bool EventHandler::passWheelEventToWidget(PlatformWheelEvent&, Widget* widget)
if ([currentEvent().get() type] != NSScrollWheel || m_sendingEventToSubview || !widget)
return false;
- NSView *nodeView = widget->getView();
+ NSView* nodeView = widget->platformWidget();
ASSERT(nodeView);
ASSERT([nodeView superview]);
NSView *view = [nodeView hitTest:[[nodeView superview] convertPoint:[currentEvent().get() locationInWindow] fromView:nil]];
@@ -545,6 +555,10 @@ void EventHandler::mouseUp(NSEvent *event)
*/
void EventHandler::sendFakeEventsAfterWidgetTracking(NSEvent *initiatingEvent)
{
+ FrameView* view = m_frame->view();
+ if (!view)
+ return;
+
BEGIN_BLOCK_OBJC_EXCEPTIONS;
m_sendingEventToSubview = false;
@@ -553,34 +567,34 @@ void EventHandler::sendFakeEventsAfterWidgetTracking(NSEvent *initiatingEvent)
NSEvent *fakeEvent = nil;
if (eventType == NSLeftMouseDown) {
fakeEvent = [NSEvent mouseEventWithType:NSLeftMouseUp
- location:[initiatingEvent locationInWindow]
- modifierFlags:[initiatingEvent modifierFlags]
- timestamp:[initiatingEvent timestamp]
- windowNumber:[initiatingEvent windowNumber]
- context:[initiatingEvent context]
- eventNumber:[initiatingEvent eventNumber]
- clickCount:[initiatingEvent clickCount]
- pressure:[initiatingEvent pressure]];
+ location:[initiatingEvent locationInWindow]
+ modifierFlags:[initiatingEvent modifierFlags]
+ timestamp:[initiatingEvent timestamp]
+ windowNumber:[initiatingEvent windowNumber]
+ context:[initiatingEvent context]
+ eventNumber:[initiatingEvent eventNumber]
+ clickCount:[initiatingEvent clickCount]
+ pressure:[initiatingEvent pressure]];
[NSApp postEvent:fakeEvent atStart:YES];
} else { // eventType == NSKeyDown
fakeEvent = [NSEvent keyEventWithType:NSKeyUp
- location:[initiatingEvent locationInWindow]
- modifierFlags:[initiatingEvent modifierFlags]
- timestamp:[initiatingEvent timestamp]
- windowNumber:[initiatingEvent windowNumber]
- context:[initiatingEvent context]
- characters:[initiatingEvent characters]
- charactersIgnoringModifiers:[initiatingEvent charactersIgnoringModifiers]
- isARepeat:[initiatingEvent isARepeat]
- keyCode:[initiatingEvent keyCode]];
+ location:[initiatingEvent locationInWindow]
+ modifierFlags:[initiatingEvent modifierFlags]
+ timestamp:[initiatingEvent timestamp]
+ windowNumber:[initiatingEvent windowNumber]
+ context:[initiatingEvent context]
+ characters:[initiatingEvent characters]
+ charactersIgnoringModifiers:[initiatingEvent charactersIgnoringModifiers]
+ isARepeat:[initiatingEvent isARepeat]
+ keyCode:[initiatingEvent keyCode]];
[NSApp postEvent:fakeEvent atStart:YES];
}
- // FIXME: We should really get the current modifierFlags here, but there's no way to poll
+ // FIXME: We should really get the current modifierFlags here, but there's no way to poll
// them in Cocoa, and because the event stream was stolen by the Carbon menu code we have
// no up-to-date cache of them anywhere.
fakeEvent = [NSEvent mouseEventWithType:NSMouseMoved
- location:[[m_frame->bridge() window] convertScreenToBase:[NSEvent mouseLocation]]
+ location:[[view->platformWidget() window] convertScreenToBase:[NSEvent mouseLocation]]
modifierFlags:[initiatingEvent modifierFlags]
timestamp:[initiatingEvent timestamp]
windowNumber:[initiatingEvent windowNumber]
@@ -629,9 +643,4 @@ bool EventHandler::passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&
return passSubframeEventToSubframe(mev, subframe);
}
-bool EventHandler::passMousePressEventToScrollbar(MouseEventWithHitTestResults&, PlatformScrollbar* scrollbar)
-{
- return passMouseDownEventToWidget(scrollbar);
-}
-
}
diff --git a/WebCore/page/mac/FrameMac.mm b/WebCore/page/mac/FrameMac.mm
index 8a75797..66e2d04 100644
--- a/WebCore/page/mac/FrameMac.mm
+++ b/WebCore/page/mac/FrameMac.mm
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
- * Copyright (C) 2007 Trolltech ASA
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,35 +28,17 @@
#import "config.h"
#import "Frame.h"
-#import "AXObjectCache.h"
-#import "BeforeUnloadEvent.h"
#import "BlockExceptions.h"
-#import "CSSHelper.h"
-#import "Cache.h"
-#import "Chrome.h"
-#import "ClipboardEvent.h"
-#import "ClipboardMac.h"
#import "ColorMac.h"
#import "Cursor.h"
#import "DOMInternal.h"
#import "DocumentLoader.h"
-#import "EditCommand.h"
#import "EditorClient.h"
#import "Event.h"
-#import "EventNames.h"
-#import "FloatRect.h"
-#import "FoundationExtras.h"
-#import "FrameLoadRequest.h"
-#import "FrameLoader.h"
#import "FrameLoaderClient.h"
-#import "FrameLoaderTypes.h"
#import "FramePrivate.h"
#import "FrameView.h"
#import "GraphicsContext.h"
-#import "HTMLDocument.h"
-#import "HTMLFormElement.h"
-#import "HTMLGenericFormElement.h"
-#import "HTMLInputElement.h"
#import "HTMLNames.h"
#import "HTMLTableCellElement.h"
#import "HitTestRequest.h"
@@ -66,76 +48,34 @@
#import "MouseEventWithHitTestResults.h"
#import "Page.h"
#import "PlatformKeyboardEvent.h"
-#import "PlatformScrollBar.h"
#import "PlatformWheelEvent.h"
-#import "Plugin.h"
#import "RegularExpression.h"
-#import "RenderImage.h"
-#import "RenderListItem.h"
-#import "RenderPart.h"
#import "RenderTableCell.h"
-#import "RenderTheme.h"
-#import "RenderView.h"
-#import "ResourceHandle.h"
-#import "Settings.h"
+#import "Scrollbar.h"
#import "SimpleFontData.h"
-#import "SystemTime.h"
-#import "TextResourceDecoder.h"
#import "UserStyleSheetLoader.h"
-#import "WebCoreFrameBridge.h"
-#import "WebCoreSystemInterface.h"
#import "WebCoreViewFactory.h"
-#import "WebDashboardRegion.h"
-#import "WebScriptObjectPrivate.h"
-#import "kjs_proxy.h"
-#import "kjs_window.h"
#import "visible_units.h"
-#import <Carbon/Carbon.h>
-#import <JavaScriptCore/NP_jsobject.h>
-#import <JavaScriptCore/npruntime_impl.h>
-#undef _webcore_TIMING
+#import <Carbon/Carbon.h>
+#import <runtime/JSLock.h>
-@interface NSObject (WebPlugIn)
-- (id)objectForWebScript;
-- (NPObject *)createPluginScriptableObject;
-@end
+#if ENABLE(DASHBOARD_SUPPORT)
+#import "WebDashboardRegion.h"
+#endif
@interface NSView (WebCoreHTMLDocumentView)
- (void)drawSingleRect:(NSRect)rect;
@end
using namespace std;
-using namespace KJS::Bindings;
-using KJS::JSLock;
+using JSC::JSLock;
namespace WebCore {
-using namespace EventNames;
using namespace HTMLNames;
-void Frame::setBridge(WebCoreFrameBridge* bridge)
-{
- if (d->m_bridge == bridge)
- return;
-
- if (!bridge) {
- [d->m_bridge clearFrame];
- HardRelease(d->m_bridge);
- d->m_bridge = nil;
- return;
- }
- HardRetain(bridge);
- HardRelease(d->m_bridge);
- d->m_bridge = bridge;
-}
-
-WebCoreFrameBridge* Frame::bridge() const
-{
- return d->m_bridge;
-}
-
// Either get cached regexp or build one that matches any of the labels.
// The regexp we build is of the form: (STR1|STR2|STRN)
RegularExpression* regExpForLabels(NSArray* labels)
@@ -158,17 +98,17 @@ RegularExpression* regExpForLabels(NSArray* labels)
if (cacheHit != NSNotFound)
result = regExps.at(cacheHit);
else {
- DeprecatedString pattern("(");
+ String pattern("(");
unsigned int numLabels = [labels count];
unsigned int i;
for (i = 0; i < numLabels; i++) {
- DeprecatedString label = DeprecatedString::fromNSString((NSString*)[labels objectAtIndex:i]);
+ String label = [labels objectAtIndex:i];
bool startsWithWordChar = false;
bool endsWithWordChar = false;
if (label.length() != 0) {
- startsWithWordChar = wordRegExp.search(label.at(0)) >= 0;
- endsWithWordChar = wordRegExp.search(label.at(label.length() - 1)) >= 0;
+ startsWithWordChar = wordRegExp.search(label.substring(0, 1)) >= 0;
+ endsWithWordChar = wordRegExp.search(label.substring(label.length() - 1, 1)) >= 0;
}
if (i != 0)
@@ -176,13 +116,11 @@ RegularExpression* regExpForLabels(NSArray* labels)
// Search for word boundaries only if label starts/ends with "word characters".
// If we always searched for word boundaries, this wouldn't work for languages
// such as Japanese.
- if (startsWithWordChar) {
+ if (startsWithWordChar)
pattern.append("\\b");
- }
pattern.append(label);
- if (endsWithWordChar) {
+ if (endsWithWordChar)
pattern.append("\\b");
- }
}
pattern.append(")");
result = new RegularExpression(pattern, false);
@@ -225,10 +163,10 @@ NSString* Frame::searchForNSLabelsAboveCell(RegularExpression* regExp, HTMLTable
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
- DeprecatedString nodeString = n->nodeValue().deprecatedString();
+ String nodeString = n->nodeValue();
int pos = regExp->searchRev(nodeString);
if (pos >= 0)
- return nodeString.mid(pos, regExp->matchedLength()).getNSString();
+ return nodeString.substring(pos, regExp->matchedLength());
}
}
}
@@ -272,13 +210,13 @@ NSString* Frame::searchForLabelsBeforeElement(NSArray* labels, Element* element)
searchedCellAbove = true;
} else if (n->isTextNode() && n->renderer() && n->renderer()->style()->visibility() == VISIBLE) {
// For each text chunk, run the regexp
- DeprecatedString nodeString = n->nodeValue().deprecatedString();
+ String nodeString = n->nodeValue();
// add 100 for slop, to make it more likely that we'll search whole nodes
if (lengthSearched + nodeString.length() > maxCharsSearched)
nodeString = nodeString.right(charsSearchedThreshold - lengthSearched);
int pos = regExp->searchRev(nodeString);
if (pos >= 0)
- return nodeString.mid(pos, regExp->matchedLength()).getNSString();
+ return nodeString.substring(pos, regExp->matchedLength());
lengthSearched += nodeString.length();
}
@@ -297,11 +235,14 @@ NSString* Frame::searchForLabelsBeforeElement(NSArray* labels, Element* element)
NSString* Frame::matchLabelsAgainstElement(NSArray* labels, Element* element)
{
- DeprecatedString name = element->getAttribute(nameAttr).deprecatedString();
+ String name = element->getAttribute(nameAttr);
+ if (name.isEmpty())
+ return nil;
+
// Make numbers and _'s in field names behave like word boundaries, e.g., "address2"
- name.replace(RegularExpression("\\d"), " ");
+ replace(name, RegularExpression("\\d"), " ");
name.replace('_', ' ');
-
+
RegularExpression* regExp = regExpForLabels(labels);
// Use the largest match we can find in the whole name string
int pos;
@@ -317,18 +258,18 @@ NSString* Frame::matchLabelsAgainstElement(NSArray* labels, Element* element)
bestPos = pos;
bestLength = length;
}
- start = pos+1;
+ start = pos + 1;
}
} while (pos != -1);
if (bestPos != -1)
- return name.mid(bestPos, bestLength).getNSString();
+ return name.substring(bestPos, bestLength);
return nil;
}
NSImage* Frame::imageFromRect(NSRect rect) const
{
- NSView* view = d->m_view->getDocumentView();
+ NSView* view = d->m_view->documentView();
if (!view)
return nil;
if (![view respondsToSelector:@selector(drawSingleRect:)])
@@ -373,10 +314,10 @@ NSImage* Frame::imageFromRect(NSRect rect) const
NSImage* Frame::selectionImage(bool forceBlackText) const
{
- d->m_paintRestriction = forceBlackText ? PaintRestrictionSelectionOnlyBlackText : PaintRestrictionSelectionOnly;
+ d->m_view->setPaintRestriction(forceBlackText ? PaintRestrictionSelectionOnlyBlackText : PaintRestrictionSelectionOnly);
d->m_doc->updateLayout();
NSImage* result = imageFromRect(selectionRect());
- d->m_paintRestriction = PaintRestrictionNone;
+ d->m_view->setPaintRestriction(PaintRestrictionNone);
return result;
}
@@ -392,11 +333,11 @@ NSImage* Frame::snapshotDragImage(Node* node, NSRect* imageRect, NSRect* element
IntRect topLevelRect;
NSRect paintingRect = renderer->paintingRootRect(topLevelRect);
- d->m_elementToDraw = node; // invoke special sub-tree drawing mode
+ d->m_view->setNodeToDraw(node); // invoke special sub-tree drawing mode
NSImage* result = imageFromRect(paintingRect);
renderer->updateDragState(false);
d->m_doc->updateLayout();
- d->m_elementToDraw = 0;
+ d->m_view->setNodeToDraw(0);
if (elementRect)
*elementRect = topLevelRect;
@@ -405,6 +346,24 @@ NSImage* Frame::snapshotDragImage(Node* node, NSRect* imageRect, NSRect* element
return result;
}
+NSImage* Frame::nodeImage(Node* node) const
+{
+ RenderObject* renderer = node->renderer();
+ if (!renderer)
+ return nil;
+
+ d->m_doc->updateLayout(); // forces style recalc
+
+ IntRect topLevelRect;
+ NSRect paintingRect = renderer->paintingRootRect(topLevelRect);
+
+ d->m_view->setNodeToDraw(node); // invoke special sub-tree drawing mode
+ NSImage* result = imageFromRect(paintingRect);
+ d->m_view->setNodeToDraw(0);
+
+ return result;
+}
+
NSDictionary* Frame::fontAttributesForSelectionStart() const
{
Node* nodeToRemove;
@@ -473,11 +432,22 @@ NSWritingDirection Frame::baseWritingDirectionForSelectionStart() const
{
NSWritingDirection result = NSWritingDirectionLeftToRight;
- Position pos = selectionController()->selection().visibleStart().deepEquivalent();
+ Position pos = selection()->selection().visibleStart().deepEquivalent();
Node* node = pos.node();
- if (!node || !node->renderer() || !node->renderer()->containingBlock())
+ if (!node)
return result;
- RenderStyle* style = node->renderer()->containingBlock()->style();
+
+ RenderObject* renderer = node->renderer();
+ if (!renderer)
+ return result;
+
+ if (!renderer->isBlockFlow()) {
+ renderer = renderer->containingBlock();
+ if (!renderer)
+ return result;
+ }
+
+ RenderStyle* style = renderer->style();
if (!style)
return result;
@@ -493,11 +463,6 @@ NSWritingDirection Frame::baseWritingDirectionForSelectionStart() const
return result;
}
-void Frame::issuePasteCommand()
-{
- [d->m_bridge issuePasteCommand];
-}
-
const short enableRomanKeyboardsOnly = -23;
void Frame::setUseSecureKeyboardEntry(bool enable)
{
@@ -522,6 +487,7 @@ void Frame::setUseSecureKeyboardEntry(bool enable)
}
}
+#if ENABLE(DASHBOARD_SUPPORT)
NSMutableDictionary* Frame::dashboardRegionsDictionary()
{
Document* doc = document();
@@ -559,106 +525,15 @@ NSMutableDictionary* Frame::dashboardRegionsDictionary()
return webRegions;
}
-
-void Frame::dashboardRegionsChanged()
-{
- NSMutableDictionary *webRegions = dashboardRegionsDictionary();
- [d->m_bridge dashboardRegionsChanged:webRegions];
-}
-
-void Frame::willPopupMenu(NSMenu * menu)
-{
- [d->m_bridge willPopupMenu:menu];
-}
-
-FloatRect Frame::customHighlightLineRect(const AtomicString& type, const FloatRect& lineRect, Node* node)
-{
- return [d->m_bridge customHighlightRect:type forLine:lineRect representedNode:node];
-}
-
-void Frame::paintCustomHighlight(const AtomicString& type, const FloatRect& boxRect, const FloatRect& lineRect, bool text, bool line, Node* node)
-{
- [d->m_bridge paintCustomHighlight:type forBox:boxRect onLine:lineRect behindText:text entireLine:line representedNode:node];
-}
+#endif
DragImageRef Frame::dragImageForSelection()
{
- if (!selectionController()->isRange())
+ if (!selection()->isRange())
return nil;
return selectionImage();
}
-
-KJS::Bindings::Instance* Frame::createScriptInstanceForWidget(WebCore::Widget* widget)
-{
- NSView* aView = widget->getView();
- if (!aView)
- return 0;
-
- void* nativeHandle = aView;
- CreateRootObjectFunction createRootObject = RootObject::createRootObject();
- RefPtr<RootObject> rootObject = createRootObject(nativeHandle);
-
- if ([aView respondsToSelector:@selector(objectForWebScript)]) {
- id objectForWebScript = [aView objectForWebScript];
- if (objectForWebScript)
- return Instance::createBindingForLanguageInstance(Instance::ObjectiveCLanguage, objectForWebScript, rootObject.release());
- return 0;
- } else if ([aView respondsToSelector:@selector(createPluginScriptableObject)]) {
-#if USE(NPOBJECT)
- NPObject* npObject = [aView createPluginScriptableObject];
- if (npObject) {
- Instance* instance = Instance::createBindingForLanguageInstance(Instance::CLanguage, npObject, rootObject.release());
-
- // -createPluginScriptableObject returns a retained NPObject. The caller is expected to release it.
- _NPN_ReleaseObject(npObject);
- return instance;
- }
-#endif
- return 0;
- }
-
- jobject applet;
-
- // Get a pointer to the actual Java applet instance.
- if ([d->m_bridge respondsToSelector:@selector(getAppletInView:)])
- applet = [d->m_bridge getAppletInView:aView];
- else
- applet = [d->m_bridge pollForAppletInView:aView];
-
- if (applet) {
- // Wrap the Java instance in a language neutral binding and hand
- // off ownership to the APPLET element.
- Instance* instance = Instance::createBindingForLanguageInstance(Instance::JavaLanguage, applet, rootObject.release());
- return instance;
- }
-
- return 0;
-}
-
-WebScriptObject* Frame::windowScriptObject()
-{
- if (!scriptProxy()->isEnabled())
- return 0;
-
- if (!d->m_windowScriptObject) {
- KJS::JSLock lock;
- KJS::JSObject* win = KJS::Window::retrieveWindow(this);
- KJS::Bindings::RootObject *root = bindingRootObject();
- d->m_windowScriptObject = [WebScriptObject scriptObjectForJSObject:toRef(win) originRootObject:root rootObject:root];
- }
-
- return d->m_windowScriptObject.get();
-}
-
-void Frame::clearPlatformScriptObjects()
-{
- if (d->m_windowScriptObject) {
- KJS::Bindings::RootObject* root = bindingRootObject();
- [d->m_windowScriptObject.get() _setOriginRootObject:root andRootObject:root];
- }
-}
-
void Frame::setUserStyleSheetLocation(const KURL& url)
{
delete d->m_userStyleSheetLoader;
diff --git a/WebCore/page/mac/PageMac.cpp b/WebCore/page/mac/PageMac.cpp
new file mode 100644
index 0000000..7386eea
--- /dev/null
+++ b/WebCore/page/mac/PageMac.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DocumentLoader.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "FrameTree.h"
+#include "Page.h"
+
+namespace WebCore {
+
+void Page::addSchedulePair(PassRefPtr<SchedulePair> prpPair)
+{
+ RefPtr<SchedulePair> pair = prpPair;
+
+ if (!m_scheduledRunLoopPairs)
+ m_scheduledRunLoopPairs.set(new SchedulePairHashSet);
+ m_scheduledRunLoopPairs->add(pair);
+
+#ifndef BUILDING_ON_TIGER
+ for (Frame* frame = m_mainFrame.get(); frame; frame = frame->tree()->traverseNext()) {
+ if (DocumentLoader* documentLoader = frame->loader()->documentLoader())
+ documentLoader->schedule(pair.get());
+ if (DocumentLoader* documentLoader = frame->loader()->provisionalDocumentLoader())
+ documentLoader->schedule(pair.get());
+ }
+#endif
+
+ // FIXME: make SharedTimerMac use these SchedulePairs.
+}
+
+void Page::removeSchedulePair(PassRefPtr<SchedulePair> prpPair)
+{
+ ASSERT(m_scheduledRunLoopPairs);
+ if (!m_scheduledRunLoopPairs)
+ return;
+
+ RefPtr<SchedulePair> pair = prpPair;
+ m_scheduledRunLoopPairs->remove(pair);
+
+#ifndef BUILDING_ON_TIGER
+ for (Frame* frame = m_mainFrame.get(); frame; frame = frame->tree()->traverseNext()) {
+ if (DocumentLoader* documentLoader = frame->loader()->documentLoader())
+ documentLoader->unschedule(pair.get());
+ if (DocumentLoader* documentLoader = frame->loader()->provisionalDocumentLoader())
+ documentLoader->unschedule(pair.get());
+ }
+#endif
+}
+
+} // namespace
diff --git a/WebCore/page/mac/WebCoreFrameBridge.h b/WebCore/page/mac/WebCoreFrameBridge.h
deleted file mode 100644
index a67f1b3..0000000
--- a/WebCore/page/mac/WebCoreFrameBridge.h
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#import <Cocoa/Cocoa.h>
-#import <JavaVM/jni.h>
-#import <WebCore/WebCoreKeyboardUIMode.h>
-#import <WebCore/EditAction.h>
-#import <WebCore/FrameLoaderTypes.h>
-#import <WebCore/SelectionController.h>
-#import <WebCore/TextAffinity.h>
-#import <WebCore/TextGranularity.h>
-
-#if USE(NPOBJECT)
-#import <JavaScriptCore/npruntime.h>
-#endif
-
-namespace WebCore {
- class Frame;
- class HTMLFrameOwnerElement;
- class Page;
- class String;
-}
-
-@class DOMCSSStyleDeclaration;
-@class DOMDocument;
-@class DOMDocumentFragment;
-@class DOMElement;
-@class DOMHTMLInputElement;
-@class DOMHTMLTextAreaElement;
-@class DOMNode;
-@class DOMRange;
-@class NSMenu;
-
-@protocol WebCoreRenderTreeCopier;
-
-enum WebCoreDeviceType {
- WebCoreDeviceScreen,
- WebCoreDevicePrinter
-};
-
-enum WebScrollDirection {
- WebScrollUp,
- WebScrollDown,
- WebScrollLeft,
- WebScrollRight
-};
-
-enum WebScrollGranularity {
- WebScrollLine,
- WebScrollPage,
- WebScrollDocument,
- WebScrollWheel
-};
-
-@protocol WebCoreOpenPanelResultListener <NSObject>
-- (void)chooseFilename:(NSString *)fileName;
-- (void)cancel;
-@end
-
-// WebCoreFrameBridge objects are used by WebCore to abstract away operations that need
-// to be implemented by library clients, for example WebKit. The objects are also
-// used in the opposite direction, for simple access to WebCore functions without dealing
-// directly with the KHTML C++ classes.
-
-// A WebCoreFrameBridge creates and holds a reference to a Frame.
-
-// The WebCoreFrameBridge interface contains methods for use by the non-WebCore side of the bridge.
-
-@interface WebCoreFrameBridge : NSObject
-{
-@public
- WebCore::Frame* m_frame;
- BOOL _shouldCreateRenderers;
- BOOL _closed;
-}
-
-- (WebCore::Frame*)_frame; // underscore to prevent conflict with -[NSView frame]
-
-+ (WebCoreFrameBridge *)bridgeForDOMDocument:(DOMDocument *)document;
-
-- (id)init;
-- (void)close;
-
-- (void)clearFrame;
-
-- (NSURL *)baseURL;
-
-- (void)installInFrame:(NSView *)view;
-
-- (BOOL)scrollOverflowInDirection:(WebScrollDirection)direction granularity:(WebScrollGranularity)granularity;
-
-- (void)createFrameViewWithNSView:(NSView *)view marginWidth:(int)mw marginHeight:(int)mh;
-
-- (void)reapplyStylesForDeviceType:(WebCoreDeviceType)deviceType;
-- (void)forceLayoutAdjustingViewSize:(BOOL)adjustSizeFlag;
-- (void)forceLayoutWithMinimumPageWidth:(float)minPageWidth maximumPageWidth:(float)maxPageWidth adjustingViewSize:(BOOL)adjustSizeFlag;
-- (void)sendScrollEvent;
-- (BOOL)needsLayout;
-- (void)drawRect:(NSRect)rect;
-- (void)adjustPageHeightNew:(float *)newBottom top:(float)oldTop bottom:(float)oldBottom limit:(float)bottomLimit;
-- (NSArray*)computePageRectsWithPrintWidthScaleFactor:(float)printWidthScaleFactor printHeight:(float)printHeight;
-
-- (NSObject *)copyRenderTree:(id <WebCoreRenderTreeCopier>)copier;
-- (NSString *)renderTreeAsExternalRepresentation;
-
-- (NSURL *)URLWithAttributeString:(NSString *)string;
-
-- (DOMElement *)elementWithName:(NSString *)name inForm:(DOMElement *)form;
-- (BOOL)elementDoesAutoComplete:(DOMElement *)element;
-- (BOOL)elementIsPassword:(DOMElement *)element;
-- (DOMElement *)formForElement:(DOMElement *)element;
-- (DOMElement *)currentForm;
-- (NSArray *)controlsInForm:(DOMElement *)form;
-- (NSString *)searchForLabels:(NSArray *)labels beforeElement:(DOMElement *)element;
-- (NSString *)matchLabels:(NSArray *)labels againstElement:(DOMElement *)element;
-
-- (BOOL)searchFor:(NSString *)string direction:(BOOL)forward caseSensitive:(BOOL)caseFlag wrap:(BOOL)wrapFlag startInSelection:(BOOL)startInSelection;
-- (unsigned)markAllMatchesForText:(NSString *)string caseSensitive:(BOOL)caseFlag limit:(unsigned)limit;
-- (BOOL)markedTextMatchesAreHighlighted;
-- (void)setMarkedTextMatchesAreHighlighted:(BOOL)doHighlight;
-- (void)unmarkAllTextMatches;
-- (NSArray *)rectsForTextMatches;
-
-- (void)setTextSizeMultiplier:(float)multiplier;
-
-- (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)string;
-- (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)string forceUserGesture:(BOOL)forceUserGesture;
-- (NSAppleEventDescriptor *)aeDescByEvaluatingJavaScriptFromString:(NSString *)string;
-
-- (NSString *)selectedString;
-
-- (NSString *)stringForRange:(DOMRange *)range;
-
-- (NSString *)markupStringFromNode:(DOMNode *)node nodes:(NSArray **)nodes;
-- (NSString *)markupStringFromRange:(DOMRange *)range nodes:(NSArray **)nodes;
-
-- (NSRect)caretRectAtNode:(DOMNode *)node offset:(int)offset affinity:(NSSelectionAffinity)affinity;
-- (NSRect)firstRectForDOMRange:(DOMRange *)range;
-- (void)scrollDOMRangeToVisible:(DOMRange *)range;
-
-- (NSFont *)fontForSelection:(BOOL *)hasMultipleFonts;
-
-- (NSString *)stringWithData:(NSData *)data; // using the encoding of the frame's main resource
-+ (NSString *)stringWithData:(NSData *)data textEncodingName:(NSString *)textEncodingName; // nil for textEncodingName means Latin-1
-
-- (void)setShouldCreateRenderers:(BOOL)shouldCreateRenderers;
-
-- (void)setBaseBackgroundColor:(NSColor *)backgroundColor;
-- (void)setDrawsBackground:(BOOL)drawsBackround;
-
-- (id)accessibilityTree;
-
-- (DOMRange *)rangeByAlteringCurrentSelection:(WebCore::SelectionController::EAlteration)alteration direction:(WebCore::SelectionController::EDirection)direction granularity:(WebCore::TextGranularity)granularity;
-- (WebCore::TextGranularity)selectionGranularity;
-- (void)smartInsertForString:(NSString *)pasteString replacingRange:(DOMRange *)charRangeToReplace beforeString:(NSString **)beforeString afterString:(NSString **)afterString;
-- (void)selectNSRange:(NSRange)range;
-- (NSRange)selectedNSRange;
-- (NSRange)markedTextNSRange;
-- (DOMRange *)convertNSRangeToDOMRange:(NSRange)range;
-- (NSRange)convertDOMRangeToNSRange:(DOMRange *)range;
-
-- (DOMDocumentFragment *)documentFragmentWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString;
-- (DOMDocumentFragment *)documentFragmentWithText:(NSString *)text inContext:(DOMRange *)context;
-- (DOMDocumentFragment *)documentFragmentWithNodesAsParagraphs:(NSArray *)nodes;
-
-- (void)replaceSelectionWithFragment:(DOMDocumentFragment *)fragment selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace matchStyle:(BOOL)matchStyle;
-- (void)replaceSelectionWithNode:(DOMNode *)node selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace matchStyle:(BOOL)matchStyle;
-- (void)replaceSelectionWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace;
-- (void)replaceSelectionWithText:(NSString *)text selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace;
-
-- (void)insertParagraphSeparatorInQuotedContent;
-
-- (DOMRange *)characterRangeAtPoint:(NSPoint)point;
-
-- (DOMCSSStyleDeclaration *)typingStyle;
-- (void)setTypingStyle:(DOMCSSStyleDeclaration *)style withUndoAction:(WebCore::EditAction)undoAction;
-
-- (void)dragSourceMovedTo:(NSPoint)windowLoc;
-- (void)dragSourceEndedAt:(NSPoint)windowLoc operation:(NSDragOperation)operation;
-
-- (BOOL)getData:(NSData **)data andResponse:(NSURLResponse **)response forURL:(NSString *)URL;
-- (void)getAllResourceDatas:(NSArray **)datas andResponses:(NSArray **)responses;
-
-- (BOOL)canProvideDocumentSource;
-- (BOOL)canSaveAsWebArchive;
-
-- (void)receivedData:(NSData *)data textEncodingName:(NSString *)textEncodingName;
-
-@end
-
-// The WebCoreFrameBridge protocol contains methods for use by the WebCore side of the bridge.
-
-@protocol WebCoreFrameBridge
-
-- (NSWindow *)window;
-
-- (NSResponder *)firstResponder;
-- (void)makeFirstResponder:(NSResponder *)responder;
-
-- (void)runOpenPanelForFileButtonWithResultListener:(id <WebCoreOpenPanelResultListener>)resultListener;
-
-- (jobject)getAppletInView:(NSView *)view;
-
-// Deprecated, use getAppletInView: instead.
-- (jobject)pollForAppletInView:(NSView *)view;
-
-- (void)issuePasteCommand;
-
-- (void)setIsSelected:(BOOL)isSelected forView:(NSView *)view;
-
-- (void)dashboardRegionsChanged:(NSMutableDictionary *)regions;
-- (void)willPopupMenu:(NSMenu *)menu;
-
-- (NSRect)customHighlightRect:(NSString*)type forLine:(NSRect)lineRect representedNode:(WebCore::Node *)node;
-- (void)paintCustomHighlight:(NSString*)type forBox:(NSRect)boxRect onLine:(NSRect)lineRect behindText:(BOOL)text entireLine:(BOOL)line representedNode:(WebCore::Node *)node;
-
-- (WebCore::KeyboardUIMode)keyboardUIMode;
-
-- (NSString*)imageTitleForFilename:(NSString*)filename size:(NSSize)size;
-
-@end
-
-// This interface definition allows those who hold a WebCoreFrameBridge * to call all the methods
-// in the WebCoreFrameBridge protocol without requiring the base implementation to supply the methods.
-// This idiom is appropriate because WebCoreFrameBridge is an abstract class.
-
-@interface WebCoreFrameBridge (SubclassResponsibility) <WebCoreFrameBridge>
-@end
-
-// Protocols that make up part of the interfaces above.
-
-@protocol WebCoreRenderTreeCopier <NSObject>
-- (NSObject *)nodeWithName:(NSString *)name position:(NSPoint)p rect:(NSRect)rect view:(NSView *)view children:(NSArray *)children;
-@end
diff --git a/WebCore/page/mac/WebCoreFrameBridge.mm b/WebCore/page/mac/WebCoreFrameBridge.mm
deleted file mode 100644
index d280bcb..0000000
--- a/WebCore/page/mac/WebCoreFrameBridge.mm
+++ /dev/null
@@ -1,1244 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. All rights reserved.
- * Copyright (C) 2005, 2006 Alexey Proskuryakov (ap@nypop.com)
- * Copyright (C) 2006 David Smith (catfish.man@gmail.com)
- *
- * 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.
- */
-
-#import "config.h"
-#import "WebCoreFrameBridge.h"
-
-#import "AXObjectCache.h"
-#import "CSSHelper.h"
-#import "Cache.h"
-#import "ClipboardMac.h"
-#import "ColorMac.h"
-#import "DOMImplementation.h"
-#import "DOMInternal.h"
-#import "DOMWindow.h"
-#import "DeleteSelectionCommand.h"
-#import "DocLoader.h"
-#import "DocumentFragment.h"
-#import "DocumentLoader.h"
-#import "DocumentType.h"
-#import "Editor.h"
-#import "EditorClient.h"
-#import "EventHandler.h"
-#import "FloatRect.h"
-#import "FormDataStreamMac.h"
-#import "Frame.h"
-#import "FrameLoader.h"
-#import "FrameLoaderClient.h"
-#import "FrameTree.h"
-#import "FrameView.h"
-#import "GraphicsContext.h"
-#import "HTMLDocument.h"
-#import "HTMLFormElement.h"
-#import "HTMLInputElement.h"
-#import "HTMLNames.h"
-#import "HitTestResult.h"
-#import "Image.h"
-#import "LoaderNSURLExtras.h"
-#import "MoveSelectionCommand.h"
-#import "Page.h"
-#import "PlatformMouseEvent.h"
-#import "PlatformScreen.h"
-#import "PluginInfoStore.h"
-#import "RenderImage.h"
-#import "RenderPart.h"
-#import "RenderTreeAsText.h"
-#import "RenderView.h"
-#import "RenderWidget.h"
-#import "ReplaceSelectionCommand.h"
-#import "ResourceRequest.h"
-#import "SelectionController.h"
-#import "SimpleFontData.h"
-#import "SmartReplace.h"
-#import "SubresourceLoader.h"
-#import "SystemTime.h"
-#import "Text.h"
-#import "TextEncoding.h"
-#import "TextIterator.h"
-#import "TextResourceDecoder.h"
-#import "TypingCommand.h"
-#import "WebCoreSystemInterface.h"
-#import "WebCoreViewFactory.h"
-#import "XMLTokenizer.h"
-#import "htmlediting.h"
-#import "kjs_proxy.h"
-#import "kjs_window.h"
-#import "markup.h"
-#import "visible_units.h"
-#import <OpenScripting/ASRegistry.h>
-#import <JavaScriptCore/array_instance.h>
-#import <JavaScriptCore/date_object.h>
-#import <JavaScriptCore/runtime_root.h>
-#import <wtf/RetainPtr.h>
-
-@class NSView;
-
-using namespace std;
-using namespace WebCore;
-using namespace HTMLNames;
-
-using KJS::ArrayInstance;
-using KJS::BooleanType;
-using KJS::DateInstance;
-using KJS::ExecState;
-using KJS::GetterSetterType;
-using KJS::JSImmediate;
-using KJS::JSLock;
-using KJS::JSObject;
-using KJS::JSValue;
-using KJS::NullType;
-using KJS::NumberType;
-using KJS::ObjectType;
-using KJS::SavedBuiltins;
-using KJS::SavedProperties;
-using KJS::StringType;
-using KJS::UndefinedType;
-using KJS::UnspecifiedType;
-using KJS::Window;
-
-using KJS::Bindings::RootObject;
-
-static PassRefPtr<RootObject> createRootObject(void* nativeHandle)
-{
- NSView *view = (NSView *)nativeHandle;
- WebCoreFrameBridge *bridge = [[WebCoreViewFactory sharedFactory] bridgeForView:view];
- if (!bridge)
- return 0;
-
- Frame* frame = [bridge _frame];
- return frame->createRootObject(nativeHandle, frame->scriptProxy()->globalObject());
-}
-
-static pthread_t mainThread = 0;
-
-static void updateRenderingForBindings(ExecState* exec, JSObject* rootObject)
-{
- if (pthread_self() != mainThread)
- return;
-
- if (!rootObject)
- return;
-
- Window* window = static_cast<Window*>(rootObject);
- if (!window)
- return;
-
- if (Frame* frame = window->impl()->frame())
- if (Document* doc = frame->document())
- doc->updateRendering();
-}
-
-static NSAppleEventDescriptor* aeDescFromJSValue(ExecState* exec, JSValue* jsValue)
-{
- NSAppleEventDescriptor* aeDesc = 0;
- switch (jsValue->type()) {
- case BooleanType:
- aeDesc = [NSAppleEventDescriptor descriptorWithBoolean:jsValue->getBoolean()];
- break;
- case StringType:
- aeDesc = [NSAppleEventDescriptor descriptorWithString:String(jsValue->getString())];
- break;
- case NumberType: {
- double value = jsValue->getNumber();
- int intValue = (int)value;
- if (value == intValue)
- aeDesc = [NSAppleEventDescriptor descriptorWithDescriptorType:typeSInt32 bytes:&intValue length:sizeof(intValue)];
- else
- aeDesc = [NSAppleEventDescriptor descriptorWithDescriptorType:typeIEEE64BitFloatingPoint bytes:&value length:sizeof(value)];
- break;
- }
- case ObjectType: {
- JSObject* object = jsValue->getObject();
- if (object->inherits(&DateInstance::info)) {
- DateInstance* date = static_cast<DateInstance*>(object);
- double ms = 0;
- int tzOffset = 0;
- if (date->getTime(ms, tzOffset)) {
- CFAbsoluteTime utcSeconds = ms / 1000 - kCFAbsoluteTimeIntervalSince1970;
- LongDateTime ldt;
- if (noErr == UCConvertCFAbsoluteTimeToLongDateTime(utcSeconds, &ldt))
- aeDesc = [NSAppleEventDescriptor descriptorWithDescriptorType:typeLongDateTime bytes:&ldt length:sizeof(ldt)];
- }
- }
- else if (object->inherits(&ArrayInstance::info)) {
- static HashSet<JSObject*> visitedElems;
- if (!visitedElems.contains(object)) {
- visitedElems.add(object);
-
- ArrayInstance* array = static_cast<ArrayInstance*>(object);
- aeDesc = [NSAppleEventDescriptor listDescriptor];
- unsigned numItems = array->getLength();
- for (unsigned i = 0; i < numItems; ++i)
- [aeDesc insertDescriptor:aeDescFromJSValue(exec, array->getItem(i)) atIndex:0];
-
- visitedElems.remove(object);
- }
- }
- if (!aeDesc) {
- JSValue* primitive = object->toPrimitive(exec);
- if (exec->hadException()) {
- exec->clearException();
- return [NSAppleEventDescriptor nullDescriptor];
- }
- return aeDescFromJSValue(exec, primitive);
- }
- break;
- }
- case UndefinedType:
- aeDesc = [NSAppleEventDescriptor descriptorWithTypeCode:cMissingValue];
- break;
- default:
- LOG_ERROR("Unknown JavaScript type: %d", jsValue->type());
- // no break;
- case UnspecifiedType:
- case NullType:
- case GetterSetterType:
- aeDesc = [NSAppleEventDescriptor nullDescriptor];
- break;
- }
-
- return aeDesc;
-}
-
-@implementation WebCoreFrameBridge
-
-static inline WebCoreFrameBridge *bridge(Frame *frame)
-{
- if (!frame)
- return nil;
- return frame->bridge();
-}
-
-- (NSString *)domain
-{
- Document *doc = m_frame->document();
- if (doc)
- return doc->domain();
- return nil;
-}
-
-+ (WebCoreFrameBridge *)bridgeForDOMDocument:(DOMDocument *)document
-{
- return bridge([document _document]->frame());
-}
-
-- (id)init
-{
- static bool initializedKJS;
- if (!initializedKJS) {
- initializedKJS = true;
-
- mainThread = pthread_self();
- RootObject::setCreateRootObject(createRootObject);
- KJS::Bindings::Instance::setDidExecuteFunction(updateRenderingForBindings);
- }
-
- if (!(self = [super init]))
- return nil;
-
- _shouldCreateRenderers = YES;
- return self;
-}
-
-- (void)dealloc
-{
- ASSERT(_closed);
- [super dealloc];
-}
-
-- (void)finalize
-{
- ASSERT(_closed);
- [super finalize];
-}
-
-- (void)close
-{
- [self clearFrame];
- _closed = YES;
-}
-
-- (void)addData:(NSData *)data
-{
- Document *doc = m_frame->document();
-
- // Document may be nil if the part is about to redirect
- // as a result of JS executing during load, i.e. one frame
- // changing another's location before the frame's document
- // has been created.
- if (doc) {
- doc->setShouldCreateRenderers(_shouldCreateRenderers);
- m_frame->loader()->addData((const char *)[data bytes], [data length]);
- }
-}
-
-- (BOOL)scrollOverflowInDirection:(WebScrollDirection)direction granularity:(WebScrollGranularity)granularity
-{
- if (!m_frame)
- return NO;
- return m_frame->eventHandler()->scrollOverflow((ScrollDirection)direction, (ScrollGranularity)granularity);
-}
-
-- (void)clearFrame
-{
- m_frame = 0;
-}
-
-- (void)createFrameViewWithNSView:(NSView *)view marginWidth:(int)mw marginHeight:(int)mh
-{
- // If we own the view, delete the old one - otherwise the render m_frame will take care of deleting the view.
- if (m_frame)
- m_frame->setView(0);
-
- FrameView* frameView = new FrameView(m_frame);
- m_frame->setView(frameView);
- frameView->deref();
-
- frameView->setView(view);
- if (mw >= 0)
- frameView->setMarginWidth(mw);
- if (mh >= 0)
- frameView->setMarginHeight(mh);
-}
-
-- (NSString *)_stringWithDocumentTypeStringAndMarkupString:(NSString *)markupString
-{
- return m_frame->documentTypeString() + markupString;
-}
-
-- (NSArray *)nodesFromList:(Vector<Node*> *)nodesVector
-{
- size_t size = nodesVector->size();
- NSMutableArray *nodes = [NSMutableArray arrayWithCapacity:size];
- for (size_t i = 0; i < size; ++i)
- [nodes addObject:[DOMNode _wrapNode:(*nodesVector)[i]]];
- return nodes;
-}
-
-- (NSString *)markupStringFromNode:(DOMNode *)node nodes:(NSArray **)nodes
-{
- // FIXME: This is never "for interchange". Is that right? See the next method.
- Vector<Node*> nodeList;
- NSString *markupString = createMarkup([node _node], IncludeNode, nodes ? &nodeList : 0);
- if (nodes)
- *nodes = [self nodesFromList:&nodeList];
-
- return [self _stringWithDocumentTypeStringAndMarkupString:markupString];
-}
-
-- (NSString *)markupStringFromRange:(DOMRange *)range nodes:(NSArray **)nodes
-{
- // FIXME: This is always "for interchange". Is that right? See the previous method.
- Vector<Node*> nodeList;
- NSString *markupString = createMarkup([range _range], nodes ? &nodeList : 0, AnnotateForInterchange);
- if (nodes)
- *nodes = [self nodesFromList:&nodeList];
-
- return [self _stringWithDocumentTypeStringAndMarkupString:markupString];
-}
-
-- (NSString *)selectedString
-{
- String text = m_frame->selectedText();
- text.replace('\\', m_frame->backslashAsCurrencySymbol());
- return text;
-}
-
-- (NSString *)stringForRange:(DOMRange *)range
-{
- // This will give a system malloc'd buffer that can be turned directly into an NSString
- unsigned length;
- UChar* buf = plainTextToMallocAllocatedBuffer([range _range], length);
-
- if (!buf)
- return [NSString string];
-
- UChar backslashAsCurrencySymbol = m_frame->backslashAsCurrencySymbol();
- if (backslashAsCurrencySymbol != '\\')
- for (unsigned n = 0; n < length; n++)
- if (buf[n] == '\\')
- buf[n] = backslashAsCurrencySymbol;
-
- // Transfer buffer ownership to NSString
- return [[[NSString alloc] initWithCharactersNoCopy:buf length:length freeWhenDone:YES] autorelease];
-}
-
-- (void)reapplyStylesForDeviceType:(WebCoreDeviceType)deviceType
-{
- if (m_frame->view())
- m_frame->view()->setMediaType(deviceType == WebCoreDeviceScreen ? "screen" : "print");
- Document *doc = m_frame->document();
- if (doc)
- doc->setPrinting(deviceType == WebCoreDevicePrinter);
- m_frame->reapplyStyles();
-}
-
-- (void)forceLayoutAdjustingViewSize:(BOOL)flag
-{
- m_frame->forceLayout(!flag);
- if (flag)
- m_frame->view()->adjustViewSize();
-}
-
-- (void)forceLayoutWithMinimumPageWidth:(float)minPageWidth maximumPageWidth:(float)maxPageWidth adjustingViewSize:(BOOL)flag
-{
- m_frame->forceLayoutWithPageWidthRange(minPageWidth, maxPageWidth, flag);
-}
-
-- (void)sendScrollEvent
-{
- m_frame->sendScrollEvent();
-}
-
-- (void)drawRect:(NSRect)rect
-{
- PlatformGraphicsContext* platformContext = static_cast<PlatformGraphicsContext*>([[NSGraphicsContext currentContext] graphicsPort]);
- ASSERT([[NSGraphicsContext currentContext] isFlipped]);
- GraphicsContext context(platformContext);
-
- m_frame->paint(&context, enclosingIntRect(rect));
-}
-
-// Used by pagination code called from AppKit when a standalone web page is printed.
-- (NSArray*)computePageRectsWithPrintWidthScaleFactor:(float)printWidthScaleFactor printHeight:(float)printHeight
-{
- NSMutableArray* pages = [NSMutableArray arrayWithCapacity:5];
- if (printWidthScaleFactor <= 0) {
- LOG_ERROR("printWidthScaleFactor has bad value %.2f", printWidthScaleFactor);
- return pages;
- }
-
- if (printHeight <= 0) {
- LOG_ERROR("printHeight has bad value %.2f", printHeight);
- return pages;
- }
-
- if (!m_frame || !m_frame->document() || !m_frame->view()) return pages;
- RenderView* root = static_cast<RenderView *>(m_frame->document()->renderer());
- if (!root) return pages;
-
- FrameView* view = m_frame->view();
- if (!view)
- return pages;
-
- NSView* documentView = view->getDocumentView();
- if (!documentView)
- return pages;
-
- float currPageHeight = printHeight;
- float docHeight = root->layer()->height();
- float docWidth = root->layer()->width();
- float printWidth = docWidth/printWidthScaleFactor;
-
- // We need to give the part the opportunity to adjust the page height at each step.
- for (float i = 0; i < docHeight; i += currPageHeight) {
- float proposedBottom = min(docHeight, i + printHeight);
- m_frame->adjustPageHeight(&proposedBottom, i, proposedBottom, i);
- currPageHeight = max(1.0f, proposedBottom - i);
- for (float j = 0; j < docWidth; j += printWidth) {
- NSValue* val = [NSValue valueWithRect: NSMakeRect(j, i, printWidth, currPageHeight)];
- [pages addObject: val];
- }
- }
-
- return pages;
-}
-
-// This is to support the case where a webview is embedded in the view that's being printed
-- (void)adjustPageHeightNew:(float *)newBottom top:(float)oldTop bottom:(float)oldBottom limit:(float)bottomLimit
-{
- m_frame->adjustPageHeight(newBottom, oldTop, oldBottom, bottomLimit);
-}
-
-- (NSObject *)copyRenderNode:(RenderObject *)node copier:(id <WebCoreRenderTreeCopier>)copier
-{
- NSMutableArray *children = [[NSMutableArray alloc] init];
- for (RenderObject *child = node->firstChild(); child; child = child->nextSibling()) {
- [children addObject:[self copyRenderNode:child copier:copier]];
- }
-
- NSString *name = [[NSString alloc] initWithUTF8String:node->renderName()];
-
- RenderWidget* renderWidget = node->isWidget() ? static_cast<RenderWidget*>(node) : 0;
- Widget* widget = renderWidget ? renderWidget->widget() : 0;
- NSView *view = widget ? widget->getView() : nil;
-
- int nx, ny;
- node->absolutePosition(nx, ny);
- NSObject *copiedNode = [copier nodeWithName:name
- position:NSMakePoint(nx,ny)
- rect:NSMakeRect(node->xPos(), node->yPos(), node->width(), node->height())
- view:view
- children:children];
-
- [name release];
- [children release];
-
- return copiedNode;
-}
-
-- (NSObject *)copyRenderTree:(id <WebCoreRenderTreeCopier>)copier
-{
- RenderObject *renderer = m_frame->renderer();
- if (!renderer) {
- return nil;
- }
- return [self copyRenderNode:renderer copier:copier];
-}
-
-- (void)installInFrame:(NSView *)view
-{
- // If this isn't the main frame, it must have a render m_frame set, or it
- // won't ever get installed in the view hierarchy.
- ASSERT(m_frame == m_frame->page()->mainFrame() || m_frame->ownerElement());
-
- m_frame->view()->setView(view);
- // FIXME: frame tries to do this too, is it needed?
- if (m_frame->ownerRenderer()) {
- m_frame->ownerRenderer()->setWidget(m_frame->view());
- // Now the render part owns the view, so we don't any more.
- }
-
- m_frame->view()->initScrollbars();
-}
-
-static HTMLInputElement* inputElementFromDOMElement(DOMElement* element)
-{
- Node* node = [element _node];
- if (node->hasTagName(inputTag))
- return static_cast<HTMLInputElement*>(node);
- return nil;
-}
-
-static HTMLFormElement *formElementFromDOMElement(DOMElement *element)
-{
- Node *node = [element _node];
- // This should not be necessary, but an XSL file on
- // maps.google.com crashes otherwise because it is an xslt file
- // that contains <form> elements that aren't in any namespace, so
- // they come out as generic CML elements
- if (node && node->hasTagName(formTag)) {
- return static_cast<HTMLFormElement *>(node);
- }
- return nil;
-}
-
-- (DOMElement *)elementWithName:(NSString *)name inForm:(DOMElement *)form
-{
- HTMLFormElement *formElement = formElementFromDOMElement(form);
- if (formElement) {
- Vector<HTMLGenericFormElement*>& elements = formElement->formElements;
- AtomicString targetName = name;
- for (unsigned int i = 0; i < elements.size(); i++) {
- HTMLGenericFormElement *elt = elements[i];
- // Skip option elements, other duds
- if (elt->name() == targetName)
- return [DOMElement _wrapElement:elt];
- }
- }
- return nil;
-}
-
-- (BOOL)elementDoesAutoComplete:(DOMElement *)element
-{
- HTMLInputElement *inputElement = inputElementFromDOMElement(element);
- return inputElement != nil
- && inputElement->inputType() == HTMLInputElement::TEXT
- && inputElement->autoComplete();
-}
-
-- (BOOL)elementIsPassword:(DOMElement *)element
-{
- HTMLInputElement *inputElement = inputElementFromDOMElement(element);
- return inputElement != nil
- && inputElement->inputType() == HTMLInputElement::PASSWORD;
-}
-
-- (DOMElement *)formForElement:(DOMElement *)element;
-{
- HTMLInputElement *inputElement = inputElementFromDOMElement(element);
- if (inputElement) {
- HTMLFormElement *formElement = inputElement->form();
- if (formElement) {
- return [DOMElement _wrapElement:formElement];
- }
- }
- return nil;
-}
-
-- (DOMElement *)currentForm
-{
- return [DOMElement _wrapElement:m_frame->currentForm()];
-}
-
-- (NSArray *)controlsInForm:(DOMElement *)form
-{
- NSMutableArray *results = nil;
- HTMLFormElement *formElement = formElementFromDOMElement(form);
- if (formElement) {
- Vector<HTMLGenericFormElement*>& elements = formElement->formElements;
- for (unsigned int i = 0; i < elements.size(); i++) {
- if (elements.at(i)->isEnumeratable()) { // Skip option elements, other duds
- DOMElement *de = [DOMElement _wrapElement:elements.at(i)];
- if (!results) {
- results = [NSMutableArray arrayWithObject:de];
- } else {
- [results addObject:de];
- }
- }
- }
- }
- return results;
-}
-
-- (NSString *)searchForLabels:(NSArray *)labels beforeElement:(DOMElement *)element
-{
- return m_frame->searchForLabelsBeforeElement(labels, [element _element]);
-}
-
-- (NSString *)matchLabels:(NSArray *)labels againstElement:(DOMElement *)element
-{
- return m_frame->matchLabelsAgainstElement(labels, [element _element]);
-}
-
-- (NSURL *)URLWithAttributeString:(NSString *)string
-{
- Document *doc = m_frame->document();
- if (!doc)
- return nil;
- // FIXME: is parseURL appropriate here?
- DeprecatedString rel = parseURL(string).deprecatedString();
- return KURL(doc->completeURL(rel)).getNSURL();
-}
-
-- (BOOL)searchFor:(NSString *)string direction:(BOOL)forward caseSensitive:(BOOL)caseFlag wrap:(BOOL)wrapFlag startInSelection:(BOOL)startInSelection
-{
- return m_frame->findString(string, forward, caseFlag, wrapFlag, startInSelection);
-}
-
-- (unsigned)markAllMatchesForText:(NSString *)string caseSensitive:(BOOL)caseFlag limit:(unsigned)limit
-{
- return m_frame->markAllMatchesForText(string, caseFlag, limit);
-}
-
-- (BOOL)markedTextMatchesAreHighlighted
-{
- return m_frame->markedTextMatchesAreHighlighted();
-}
-
-- (void)setMarkedTextMatchesAreHighlighted:(BOOL)doHighlight
-{
- m_frame->setMarkedTextMatchesAreHighlighted(doHighlight);
-}
-
-- (void)unmarkAllTextMatches
-{
- Document *doc = m_frame->document();
- if (!doc) {
- return;
- }
- doc->removeMarkers(DocumentMarker::TextMatch);
-}
-
-- (NSArray *)rectsForTextMatches
-{
- Document *doc = m_frame->document();
- if (!doc)
- return [NSArray array];
-
- NSMutableArray *result = [NSMutableArray array];
- Vector<IntRect> rects = doc->renderedRectsForMarkers(DocumentMarker::TextMatch);
- unsigned count = rects.size();
- for (unsigned index = 0; index < count; ++index)
- [result addObject:[NSValue valueWithRect:rects[index]]];
-
- return result;
-}
-
-- (void)setTextSizeMultiplier:(float)multiplier
-{
- int newZoomFactor = (int)rint(multiplier * 100);
- if (m_frame->zoomFactor() == newZoomFactor) {
- return;
- }
- m_frame->setZoomFactor(newZoomFactor);
-}
-
-- (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)string
-{
- return [self stringByEvaluatingJavaScriptFromString:string forceUserGesture:true];
-}
-
-- (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)string forceUserGesture:(BOOL)forceUserGesture
-{
- ASSERT(m_frame->document());
-
- JSValue* result = m_frame->loader()->executeScript(string, forceUserGesture);
-
- if (!m_frame) // In case the script removed our frame from the page.
- return @"";
-
- // This bizarre set of rules matches behavior from WebKit for Safari 2.0.
- // If you don't like it, use -[WebScriptObject evaluateWebScript:] or
- // JSEvaluateScript instead, since they have less surprising semantics.
- if (!result || !result->isBoolean() && !result->isString() && !result->isNumber())
- return @"";
-
- JSLock lock;
- return String(result->toString(m_frame->scriptProxy()->globalObject()->globalExec()));
-}
-
-- (NSAppleEventDescriptor *)aeDescByEvaluatingJavaScriptFromString:(NSString *)string
-{
- ASSERT(m_frame->document());
- ASSERT(m_frame == m_frame->page()->mainFrame());
- JSValue* result = m_frame->loader()->executeScript(string, true);
- if (!result) // FIXME: pass errors
- return 0;
- JSLock lock;
- return aeDescFromJSValue(m_frame->scriptProxy()->globalObject()->globalExec(), result);
-}
-
-- (NSRect)caretRectAtNode:(DOMNode *)node offset:(int)offset affinity:(NSSelectionAffinity)affinity
-{
- return [node _node]->renderer()->caretRect(offset, static_cast<EAffinity>(affinity));
-}
-
-- (NSRect)firstRectForDOMRange:(DOMRange *)range
-{
- return m_frame->firstRectForRange([range _range]);
-}
-
-- (void)scrollDOMRangeToVisible:(DOMRange *)range
-{
- NSRect rangeRect = [self firstRectForDOMRange:range];
- Node *startNode = [[range startContainer] _node];
-
- if (startNode && startNode->renderer()) {
- RenderLayer *layer = startNode->renderer()->enclosingLayer();
- if (layer)
- layer->scrollRectToVisible(enclosingIntRect(rangeRect), RenderLayer::gAlignToEdgeIfNeeded, RenderLayer::gAlignToEdgeIfNeeded);
- }
-}
-
-- (NSURL *)baseURL
-{
- return m_frame->loader()->completeURL(m_frame->document()->baseURL()).getNSURL();
-}
-
-- (NSString *)stringWithData:(NSData *)data
-{
- Document* doc = m_frame->document();
- if (!doc)
- return nil;
- TextResourceDecoder* decoder = doc->decoder();
- if (!decoder)
- return nil;
- return decoder->encoding().decode(reinterpret_cast<const char*>([data bytes]), [data length]);
-}
-
-+ (NSString *)stringWithData:(NSData *)data textEncodingName:(NSString *)textEncodingName
-{
- WebCore::TextEncoding encoding(textEncodingName);
- if (!encoding.isValid())
- encoding = WindowsLatin1Encoding();
- return encoding.decode(reinterpret_cast<const char*>([data bytes]), [data length]);
-}
-
-- (BOOL)needsLayout
-{
- return m_frame->view() ? m_frame->view()->needsLayout() : false;
-}
-
-- (NSString *)renderTreeAsExternalRepresentation
-{
- return externalRepresentation(m_frame->renderer()).getNSString();
-}
-
-- (void)setShouldCreateRenderers:(BOOL)f
-{
- _shouldCreateRenderers = f;
-}
-
-- (id)accessibilityTree
-{
- AXObjectCache::enableAccessibility();
- if (!m_frame || !m_frame->document())
- return nil;
- RenderView* root = static_cast<RenderView *>(m_frame->document()->renderer());
- if (!root)
- return nil;
- return m_frame->document()->axObjectCache()->get(root);
-}
-
-- (void)setBaseBackgroundColor:(NSColor *)backgroundColor
-{
- if (m_frame && m_frame->view()) {
- Color color = colorFromNSColor([backgroundColor colorUsingColorSpaceName:NSDeviceRGBColorSpace]);
- m_frame->view()->setBaseBackgroundColor(color);
- }
-}
-
-- (void)setDrawsBackground:(BOOL)drawsBackground
-{
- if (m_frame && m_frame->view())
- m_frame->view()->setTransparent(!drawsBackground);
-}
-
-- (DOMRange *)rangeByAlteringCurrentSelection:(SelectionController::EAlteration)alteration direction:(SelectionController::EDirection)direction granularity:(TextGranularity)granularity
-{
- if (m_frame->selectionController()->isNone())
- return nil;
-
- SelectionController selectionController;
- selectionController.setSelection(m_frame->selectionController()->selection());
- selectionController.modify(alteration, direction, granularity);
- return [DOMRange _wrapRange:selectionController.toRange().get()];
-}
-
-- (TextGranularity)selectionGranularity
-{
- return m_frame->selectionGranularity();
-}
-
-- (NSRange)convertToNSRange:(Range *)range
-{
- int exception = 0;
-
- if (!range || range->isDetached())
- return NSMakeRange(NSNotFound, 0);
-
- Element* selectionRoot = m_frame->selectionController()->rootEditableElement();
- Element* scope = selectionRoot ? selectionRoot : m_frame->document()->documentElement();
-
- // Mouse events may cause TSM to attempt to create an NSRange for a portion of the view
- // that is not inside the current editable region. These checks ensure we don't produce
- // potentially invalid data when responding to such requests.
- if (range->startContainer(exception) != scope && !range->startContainer(exception)->isDescendantOf(scope))
- return NSMakeRange(NSNotFound, 0);
- if(range->endContainer(exception) != scope && !range->endContainer(exception)->isDescendantOf(scope))
- return NSMakeRange(NSNotFound, 0);
-
- RefPtr<Range> testRange = new Range(scope->document(), scope, 0, range->startContainer(exception), range->startOffset(exception));
- ASSERT(testRange->startContainer(exception) == scope);
- int startPosition = TextIterator::rangeLength(testRange.get());
-
- testRange->setEnd(range->endContainer(exception), range->endOffset(exception), exception);
- ASSERT(testRange->startContainer(exception) == scope);
- int endPosition = TextIterator::rangeLength(testRange.get());
-
- return NSMakeRange(startPosition, endPosition - startPosition);
-}
-
-- (PassRefPtr<Range>)convertToDOMRange:(NSRange)nsrange
-{
- if (nsrange.location > INT_MAX)
- return 0;
- if (nsrange.length > INT_MAX || nsrange.location + nsrange.length > INT_MAX)
- nsrange.length = INT_MAX - nsrange.location;
-
- // our critical assumption is that we are only called by input methods that
- // concentrate on a given area containing the selection
- // We have to do this because of text fields and textareas. The DOM for those is not
- // directly in the document DOM, so serialization is problematic. Our solution is
- // to use the root editable element of the selection start as the positional base.
- // That fits with AppKit's idea of an input context.
- Element* selectionRoot = m_frame->selectionController()->rootEditableElement();
- Element* scope = selectionRoot ? selectionRoot : m_frame->document()->documentElement();
- return TextIterator::rangeFromLocationAndLength(scope, nsrange.location, nsrange.length);
-}
-
-- (DOMRange *)convertNSRangeToDOMRange:(NSRange)nsrange
-{
- return [DOMRange _wrapRange:[self convertToDOMRange:nsrange].get()];
-}
-
-- (NSRange)convertDOMRangeToNSRange:(DOMRange *)range
-{
- return [self convertToNSRange:[range _range]];
-}
-
-- (void)selectNSRange:(NSRange)range
-{
- RefPtr<Range> domRange = [self convertToDOMRange:range];
- if (domRange)
- m_frame->selectionController()->setSelection(Selection(domRange.get(), SEL_DEFAULT_AFFINITY));
-}
-
-- (NSRange)selectedNSRange
-{
- return [self convertToNSRange:m_frame->selectionController()->toRange().get()];
-}
-
-- (DOMRange *)markDOMRange
-{
- return [DOMRange _wrapRange:m_frame->mark().toRange().get()];
-}
-
-- (NSRange)markedTextNSRange
-{
- return [self convertToNSRange:m_frame->editor()->compositionRange().get()];
-}
-
-// Given proposedRange, returns an extended range that includes adjacent whitespace that should
-// be deleted along with the proposed range in order to preserve proper spacing and punctuation of
-// the text surrounding the deletion.
-- (DOMRange *)smartDeleteRangeForProposedRange:(DOMRange *)proposedRange
-{
- Node *startContainer = [[proposedRange startContainer] _node];
- Node *endContainer = [[proposedRange endContainer] _node];
- if (startContainer == nil || endContainer == nil)
- return nil;
-
- ASSERT(startContainer->document() == endContainer->document());
-
- m_frame->document()->updateLayoutIgnorePendingStylesheets();
-
- Position start(startContainer, [proposedRange startOffset]);
- Position end(endContainer, [proposedRange endOffset]);
- Position newStart = start.upstream().leadingWhitespacePosition(DOWNSTREAM, true);
- if (newStart.isNull())
- newStart = start;
- Position newEnd = end.downstream().trailingWhitespacePosition(DOWNSTREAM, true);
- if (newEnd.isNull())
- newEnd = end;
-
- newStart = rangeCompliantEquivalent(newStart);
- newEnd = rangeCompliantEquivalent(newEnd);
-
- RefPtr<Range> range = m_frame->document()->createRange();
- int exception = 0;
- range->setStart(newStart.node(), newStart.offset(), exception);
- range->setEnd(newStart.node(), newStart.offset(), exception);
- return [DOMRange _wrapRange:range.get()];
-}
-
-// Determines whether whitespace needs to be added around aString to preserve proper spacing and
-// punctuation when it’s inserted into the receiver’s text over charRange. Returns by reference
-// in beforeString and afterString any whitespace that should be added, unless either or both are
-// nil. Both are returned as nil if aString is nil or if smart insertion and deletion are disabled.
-- (void)smartInsertForString:(NSString *)pasteString replacingRange:(DOMRange *)rangeToReplace beforeString:(NSString **)beforeString afterString:(NSString **)afterString
-{
- // give back nil pointers in case of early returns
- if (beforeString)
- *beforeString = nil;
- if (afterString)
- *afterString = nil;
-
- // inspect destination
- Node *startContainer = [[rangeToReplace startContainer] _node];
- Node *endContainer = [[rangeToReplace endContainer] _node];
-
- Position startPos(startContainer, [rangeToReplace startOffset]);
- Position endPos(endContainer, [rangeToReplace endOffset]);
-
- VisiblePosition startVisiblePos = VisiblePosition(startPos, VP_DEFAULT_AFFINITY);
- VisiblePosition endVisiblePos = VisiblePosition(endPos, VP_DEFAULT_AFFINITY);
-
- // this check also ensures startContainer, startPos, endContainer, and endPos are non-null
- if (startVisiblePos.isNull() || endVisiblePos.isNull())
- return;
-
- bool addLeadingSpace = startPos.leadingWhitespacePosition(VP_DEFAULT_AFFINITY, true).isNull() && !isStartOfParagraph(startVisiblePos);
- if (addLeadingSpace)
- if (UChar previousChar = startVisiblePos.previous().characterAfter())
- addLeadingSpace = !isCharacterSmartReplaceExempt(previousChar, true);
-
- bool addTrailingSpace = endPos.trailingWhitespacePosition(VP_DEFAULT_AFFINITY, true).isNull() && !isEndOfParagraph(endVisiblePos);
- if (addTrailingSpace)
- if (UChar thisChar = endVisiblePos.characterAfter())
- addTrailingSpace = !isCharacterSmartReplaceExempt(thisChar, false);
-
- // inspect source
- bool hasWhitespaceAtStart = false;
- bool hasWhitespaceAtEnd = false;
- unsigned pasteLength = [pasteString length];
- if (pasteLength > 0) {
- NSCharacterSet *whiteSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];
-
- if ([whiteSet characterIsMember:[pasteString characterAtIndex:0]]) {
- hasWhitespaceAtStart = YES;
- }
- if ([whiteSet characterIsMember:[pasteString characterAtIndex:(pasteLength - 1)]]) {
- hasWhitespaceAtEnd = YES;
- }
- }
-
- // issue the verdict
- if (beforeString && addLeadingSpace && !hasWhitespaceAtStart)
- *beforeString = @" ";
- if (afterString && addTrailingSpace && !hasWhitespaceAtEnd)
- *afterString = @" ";
-}
-
-- (DOMDocumentFragment *)documentFragmentWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString
-{
- if (!m_frame || !m_frame->document())
- return 0;
-
- return [DOMDocumentFragment _wrapDocumentFragment:createFragmentFromMarkup(m_frame->document(), markupString, baseURLString).get()];
-}
-
-- (DOMDocumentFragment *)documentFragmentWithText:(NSString *)text inContext:(DOMRange *)context
-{
- return [DOMDocumentFragment _wrapDocumentFragment:createFragmentFromText([context _range], text).get()];
-}
-
-- (DOMDocumentFragment *)documentFragmentWithNodesAsParagraphs:(NSArray *)nodes
-{
- if (!m_frame || !m_frame->document())
- return 0;
-
- NSEnumerator *nodeEnum = [nodes objectEnumerator];
- Vector<Node*> nodesVector;
- DOMNode *node;
- while ((node = [nodeEnum nextObject]))
- nodesVector.append([node _node]);
-
- return [DOMDocumentFragment _wrapDocumentFragment:createFragmentFromNodes(m_frame->document(), nodesVector).get()];
-}
-
-- (void)replaceSelectionWithFragment:(DOMDocumentFragment *)fragment selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace matchStyle:(BOOL)matchStyle
-{
- if (m_frame->selectionController()->isNone() || !fragment)
- return;
-
- applyCommand(new ReplaceSelectionCommand(m_frame->document(), [fragment _documentFragment], selectReplacement, smartReplace, matchStyle));
- m_frame->revealSelection(RenderLayer::gAlignToEdgeIfNeeded);
-}
-
-- (void)replaceSelectionWithNode:(DOMNode *)node selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace matchStyle:(BOOL)matchStyle
-{
- DOMDocumentFragment *fragment = [DOMDocumentFragment _wrapDocumentFragment:m_frame->document()->createDocumentFragment().get()];
- [fragment appendChild:node];
- [self replaceSelectionWithFragment:fragment selectReplacement:selectReplacement smartReplace:smartReplace matchStyle:matchStyle];
-}
-
-- (void)replaceSelectionWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace
-{
- DOMDocumentFragment *fragment = [self documentFragmentWithMarkupString:markupString baseURLString:baseURLString];
- [self replaceSelectionWithFragment:fragment selectReplacement:selectReplacement smartReplace:smartReplace matchStyle:NO];
-}
-
-- (void)replaceSelectionWithText:(NSString *)text selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace
-{
- [self replaceSelectionWithFragment:[self documentFragmentWithText:text
- inContext:[DOMRange _wrapRange:m_frame->selectionController()->toRange().get()]]
- selectReplacement:selectReplacement smartReplace:smartReplace matchStyle:YES];
-}
-
-- (void)insertParagraphSeparatorInQuotedContent
-{
- if (m_frame->selectionController()->isNone())
- return;
-
- TypingCommand::insertParagraphSeparatorInQuotedContent(m_frame->document());
- m_frame->revealSelection(RenderLayer::gAlignToEdgeIfNeeded);
-}
-
-- (VisiblePosition)_visiblePositionForPoint:(NSPoint)point
-{
- IntPoint outerPoint(point);
- HitTestResult result = m_frame->eventHandler()->hitTestResultAtPoint(outerPoint, true);
- Node* node = result.innerNode();
- if (!node)
- return VisiblePosition();
- RenderObject* renderer = node->renderer();
- if (!renderer)
- return VisiblePosition();
- VisiblePosition visiblePos = renderer->positionForCoordinates(result.localPoint().x(), result.localPoint().y());
- if (visiblePos.isNull())
- visiblePos = VisiblePosition(Position(node, 0));
- return visiblePos;
-}
-
-- (DOMRange *)characterRangeAtPoint:(NSPoint)point
-{
- VisiblePosition position = [self _visiblePositionForPoint:point];
- if (position.isNull())
- return nil;
-
- VisiblePosition previous = position.previous();
- if (previous.isNotNull()) {
- DOMRange *previousCharacterRange = [DOMRange _wrapRange:makeRange(previous, position).get()];
- NSRect rect = [self firstRectForDOMRange:previousCharacterRange];
- if (NSPointInRect(point, rect))
- return previousCharacterRange;
- }
-
- VisiblePosition next = position.next();
- if (next.isNotNull()) {
- DOMRange *nextCharacterRange = [DOMRange _wrapRange:makeRange(position, next).get()];
- NSRect rect = [self firstRectForDOMRange:nextCharacterRange];
- if (NSPointInRect(point, rect))
- return nextCharacterRange;
- }
-
- return nil;
-}
-
-- (DOMCSSStyleDeclaration *)typingStyle
-{
- if (!m_frame || !m_frame->typingStyle())
- return nil;
- return [DOMCSSStyleDeclaration _wrapCSSStyleDeclaration:m_frame->typingStyle()->copy().get()];
-}
-
-- (void)setTypingStyle:(DOMCSSStyleDeclaration *)style withUndoAction:(EditAction)undoAction
-{
- if (!m_frame)
- return;
- m_frame->computeAndSetTypingStyle([style _CSSStyleDeclaration], undoAction);
-}
-
-- (NSFont *)fontForSelection:(BOOL *)hasMultipleFonts
-{
- bool multipleFonts = false;
- NSFont *font = nil;
- if (m_frame) {
- const SimpleFontData* fd = m_frame->editor()->fontForSelection(multipleFonts);
- if (fd)
- font = fd->getNSFont();
- }
-
- if (hasMultipleFonts)
- *hasMultipleFonts = multipleFonts;
- return font;
-}
-
-- (void)dragSourceMovedTo:(NSPoint)windowLoc
-{
- if (m_frame) {
- // FIXME: Fake modifier keys here.
- PlatformMouseEvent event(IntPoint(windowLoc), globalPoint(windowLoc, [self window]),
- LeftButton, MouseEventMoved, 0, false, false, false, false, currentTime());
- m_frame->eventHandler()->dragSourceMovedTo(event);
- }
-}
-
-- (void)dragSourceEndedAt:(NSPoint)windowLoc operation:(NSDragOperation)operation
-{
- if (m_frame) {
- // FIXME: Fake modifier keys here.
- PlatformMouseEvent event(IntPoint(windowLoc), globalPoint(windowLoc, [self window]),
- LeftButton, MouseEventMoved, 0, false, false, false, false, currentTime());
- m_frame->eventHandler()->dragSourceEndedAt(event, (DragOperation)operation);
- }
-}
-
-- (BOOL)getData:(NSData **)data andResponse:(NSURLResponse **)response forURL:(NSString *)url
-{
- Document* doc = m_frame->document();
- if (!doc)
- return NO;
-
- CachedResource* resource = doc->docLoader()->cachedResource(url);
- if (!resource)
- return NO;
-
- SharedBuffer* buffer = resource->data();
- if (buffer)
- *data = [buffer->createNSData() autorelease];
- else
- *data = nil;
-
- *response = resource->response().nsURLResponse();
- return YES;
-}
-
-- (void)getAllResourceDatas:(NSArray **)datas andResponses:(NSArray **)responses
-{
- Document* doc = m_frame->document();
- if (!doc) {
- NSArray* emptyArray = [NSArray array];
- *datas = emptyArray;
- *responses = emptyArray;
- return;
- }
-
- const HashMap<String, CachedResource*>& allResources = doc->docLoader()->allCachedResources();
-
- NSMutableArray *d = [[NSMutableArray alloc] initWithCapacity:allResources.size()];
- NSMutableArray *r = [[NSMutableArray alloc] initWithCapacity:allResources.size()];
-
- HashMap<String, CachedResource*>::const_iterator end = allResources.end();
- for (HashMap<String, CachedResource*>::const_iterator it = allResources.begin(); it != end; ++it) {
- SharedBuffer* buffer = it->second->data();
- NSData *data;
- if (buffer)
- data = buffer->createNSData();
- else
- data = [[NSData alloc] init];
- [d addObject:data];
- [data release];
- [r addObject:it->second->response().nsURLResponse()];
- }
-
- *datas = [d autorelease];
- *responses = [r autorelease];
-}
-
-- (BOOL)canProvideDocumentSource
-{
- String mimeType = m_frame->loader()->responseMIMEType();
-
- if (WebCore::DOMImplementation::isTextMIMEType(mimeType) ||
- Image::supportsType(mimeType) ||
- PluginInfoStore::supportsMIMEType(mimeType))
- return NO;
-
- return YES;
-}
-
-- (BOOL)canSaveAsWebArchive
-{
- // Currently, all documents that we can view source for
- // (HTML and XML documents) can also be saved as web archives
- return [self canProvideDocumentSource];
-}
-
-- (void)receivedData:(NSData *)data textEncodingName:(NSString *)textEncodingName
-{
- // Set the encoding. This only needs to be done once, but it's harmless to do it again later.
- String encoding;
- if (m_frame)
- encoding = m_frame->loader()->documentLoader()->overrideEncoding();
- bool userChosen = !encoding.isNull();
- if (encoding.isNull())
- encoding = textEncodingName;
- m_frame->loader()->setEncoding(encoding, userChosen);
- [self addData:data];
-}
-
-// -------------------
-
-- (Frame*)_frame
-{
- return m_frame;
-}
-
-@end
diff --git a/WebCore/page/mac/WebCoreFrameView.h b/WebCore/page/mac/WebCoreFrameView.h
index a478dca..977b1a7 100644
--- a/WebCore/page/mac/WebCoreFrameView.h
+++ b/WebCore/page/mac/WebCoreFrameView.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2003, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,32 +23,18 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-@class WebCoreFrameBridge;
+#include "ScrollTypes.h"
-// This protocol is a way for an NSScrollView to detect
-// that the view it's embedded in is one that should be resized when the
-// scroll view is resized.
-
-typedef enum {
- WebCoreScrollbarAuto,
- WebCoreScrollbarAlwaysOff,
- WebCoreScrollbarAlwaysOn
-} WebCoreScrollbarMode;
-
-@protocol WebCoreFrameView
-- (void)setHorizontalScrollingMode:(WebCoreScrollbarMode)mode;
-- (void)setVerticalScrollingMode:(WebCoreScrollbarMode)mode;
-- (void)setScrollingMode:(WebCoreScrollbarMode)mode;
-
-- (WebCoreScrollbarMode)horizontalScrollingMode;
-- (WebCoreScrollbarMode)verticalScrollingMode;
+namespace WebCore {
+ class Frame;
+}
+@protocol WebCoreFrameScrollView
+- (void)setScrollingModes:(WebCore::ScrollbarMode)hMode vertical:(WebCore::ScrollbarMode)vMode andLock:(BOOL)lock;
+- (void)scrollingModes:(WebCore::ScrollbarMode*)hMode vertical:(WebCore::ScrollbarMode*)vMode;
- (void)setScrollBarsSuppressed:(BOOL)suppressed repaintOnUnsuppress:(BOOL)repaint;
-
@end
-// This protocol is a way for WebCore to gain access to its information
-// about WebKit subclasses of NSView
-@protocol WebCoreBridgeHolder
-- (WebCoreFrameBridge *) webCoreBridge;
+@protocol WebCoreFrameView
+- (WebCore::Frame*)_web_frame;
@end
diff --git a/WebCore/page/mac/WebCoreViewFactory.h b/WebCore/page/mac/WebCoreViewFactory.h
index 55514ed..4caef54 100644
--- a/WebCore/page/mac/WebCoreViewFactory.h
+++ b/WebCore/page/mac/WebCoreViewFactory.h
@@ -23,21 +23,13 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-@class NSArray;
-@class NSDictionary;
-@class NSMenu;
-@class NSString;
-@class NSView;
-@class WebCoreFrameBridge;
@class WebCoreTextMarker;
@class WebCoreTextMarkerRange;
@protocol WebCoreViewFactory
- (NSArray *)pluginsInfo; // array of id <WebCorePluginInfo>
-- (void)refreshPlugins:(BOOL)reloadPages;
-- (NSString *)pluginNameForMIMEType:(NSString *)MIMEType;
-- (BOOL)pluginSupportsMIMEType:(NSString *)MIMEType;
+- (void)refreshPlugins;
- (NSString *)inputElementAltText;
- (NSString *)resetButtonDefaultLabel;
@@ -98,6 +90,8 @@
- (NSString *)defaultLanguageCode;
+- (NSString *)imageTitleForFilename:(NSString *)filename width:(int)width height:(int)height;
+
- (BOOL)objectIsTextMarker:(id)object;
- (BOOL)objectIsTextMarkerRange:(id)object;
@@ -113,25 +107,29 @@
- (AXUIElementRef)AXUIElementForElement:(id)element;
- (void)unregisterUniqueIdForUIElement:(id)element;
-- (WebCoreFrameBridge *)bridgeForView:(NSView *)aView;
-
- (NSString *)AXWebAreaText;
- (NSString *)AXLinkText;
- (NSString *)AXListMarkerText;
- (NSString *)AXImageMapText;
- (NSString *)AXHeadingText;
+- (NSString *)AXDefinitionListTermText;
+- (NSString *)AXDefinitionListDefinitionText;
+
+- (NSString *)AXButtonActionVerb;
+- (NSString *)AXRadioButtonActionVerb;
+- (NSString *)AXTextFieldActionVerb;
+- (NSString *)AXCheckedCheckBoxActionVerb;
+- (NSString *)AXUncheckedCheckBoxActionVerb;
+- (NSString *)AXLinkActionVerb;
+- (NSString *)multipleFileUploadTextForNumberOfFiles:(unsigned)numberOfFiles;
// FTP Directory Related
- (NSString *)unknownFileSizeText;
@end
@interface WebCoreViewFactory : NSObject
-{
-}
-
+ (WebCoreViewFactory *)sharedFactory;
-
@end
@interface WebCoreViewFactory (SubclassResponsibility) <WebCoreViewFactory>
diff --git a/WebCore/page/mac/WebDashboardRegion.h b/WebCore/page/mac/WebDashboardRegion.h
index 81113e9..4963d04 100644
--- a/WebCore/page/mac/WebDashboardRegion.h
+++ b/WebCore/page/mac/WebDashboardRegion.h
@@ -23,6 +23,12 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#if !defined(ENABLE_DASHBOARD_SUPPORT)
+#define ENABLE_DASHBOARD_SUPPORT 1
+#endif
+
+#if ENABLE_DASHBOARD_SUPPORT
+
typedef enum {
WebDashboardRegionTypeNone,
WebDashboardRegionTypeCircle,
@@ -41,3 +47,5 @@ typedef enum {
- (NSRect)dashboardRegionRect;
- (WebDashboardRegionType)dashboardRegionType;
@end
+
+#endif
diff --git a/WebCore/page/mac/WebDashboardRegion.m b/WebCore/page/mac/WebDashboardRegion.m
index 958e599..d2eb07f 100644
--- a/WebCore/page/mac/WebDashboardRegion.m
+++ b/WebCore/page/mac/WebDashboardRegion.m
@@ -25,6 +25,7 @@
#include "config.h"
#import "WebDashboardRegion.h"
+#if ENABLE(DASHBOARD_SUPPORT)
@implementation WebDashboardRegion
- initWithRect:(NSRect)r clip:(NSRect)c type:(WebDashboardRegionType)t
{
@@ -73,3 +74,4 @@
}
@end
+#endif
diff --git a/WebCore/page/qt/AccessibilityObjectQt.cpp b/WebCore/page/qt/AccessibilityObjectQt.cpp
new file mode 100644
index 0000000..b755645
--- /dev/null
+++ b/WebCore/page/qt/AccessibilityObjectQt.cpp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2008 Apple Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "AccessibilityObject.h"
+
+namespace WebCore {
+
+bool AccessibilityObject::accessibilityIgnoreAttachment() const
+{
+ return false;
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/qt/EventHandlerQt.cpp b/WebCore/page/qt/EventHandlerQt.cpp
index ce16f5b..421caaf 100644
--- a/WebCore/page/qt/EventHandlerQt.cpp
+++ b/WebCore/page/qt/EventHandlerQt.cpp
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2006 Zack Rusin <zack@kde.org>
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
- * Copyright (C) 2007 Trolltech ASA
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -45,19 +45,25 @@
#include "MouseEventWithHitTestResults.h"
#include "Page.h"
#include "PlatformKeyboardEvent.h"
-#include "PlatformScrollBar.h"
#include "PlatformWheelEvent.h"
#include "RenderWidget.h"
+#include "Scrollbar.h"
#include "NotImplemented.h"
+QT_BEGIN_NAMESPACE
+extern Q_GUI_EXPORT bool qt_tab_all_widgets; // from qapplication.cpp
+QT_END_NAMESPACE
+
namespace WebCore {
-using namespace EventNames;
+unsigned EventHandler::s_accessKeyModifiers = PlatformKeyboardEvent::CtrlKey;
+
+const double EventHandler::TextDragDelay = 0.0;
static bool isKeyboardOptionTab(KeyboardEvent* event)
{
return event
- && (event->type() == keydownEvent || event->type() == keypressEvent)
+ && (event->type() == eventNames().keydownEvent || event->type() == eventNames().keypressEvent)
&& event->altKey()
&& event->keyIdentifier() == "U+0009";
}
@@ -69,9 +75,7 @@ bool EventHandler::invertSenseOfTabsToLinks(KeyboardEvent* event) const
bool EventHandler::tabsToAllControls(KeyboardEvent* event) const
{
- bool handlingOptionTab = isKeyboardOptionTab(event);
-
- return handlingOptionTab;
+ return (isKeyboardOptionTab(event) ? !qt_tab_all_widgets : qt_tab_all_widgets);
}
void EventHandler::focusDocumentView()
@@ -105,9 +109,9 @@ bool EventHandler::passWheelEventToWidget(PlatformWheelEvent& event, Widget* wid
return static_cast<FrameView*>(widget)->frame()->eventHandler()->handleWheelEvent(event);
}
-Clipboard* EventHandler::createDraggingClipboard() const
+PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const
{
- return new ClipboardQt(ClipboardWritable, true);
+ return ClipboardQt::create(ClipboardWritable, true);
}
bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe)
@@ -128,11 +132,4 @@ bool EventHandler::passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&
return true;
}
-bool EventHandler::passMousePressEventToScrollbar(MouseEventWithHitTestResults& mev, PlatformScrollbar* scrollbar)
-{
- if (!scrollbar || !scrollbar->isEnabled())
- return false;
- return scrollbar->handleMousePressEvent(mev.event());
-}
-
}
diff --git a/WebCore/page/qt/FrameQt.cpp b/WebCore/page/qt/FrameQt.cpp
index 7ae1dd9..1bbbff5 100644
--- a/WebCore/page/qt/FrameQt.cpp
+++ b/WebCore/page/qt/FrameQt.cpp
@@ -1,14 +1,4 @@
/*
- * Copyright (C) 2006 Dirk Mueller <mueller@kde.org>
- * Copyright (C) 2006 Zack Rusin <zack@kde.org>
- * Copyright (C) 2006 George Staikos <staikos@kde.org>
- * Copyright (C) 2006 Simon Hausmann <hausmann@kde.org>
- * Copyright (C) 2006 Rob Buis <buis@kde.org>
- * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) 2007 Trolltech ASA
- *
- * All rights reserved.
- *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -33,91 +23,30 @@
#include "config.h"
#include "Frame.h"
-
-#include "Element.h"
-#include "RenderObject.h"
-#include "RenderWidget.h"
-#include "RenderLayer.h"
-#include "Page.h"
-#include "Document.h"
-#include "HTMLElement.h"
-#include "DOMWindow.h"
-#include "FrameLoadRequest.h"
-#include "FrameLoaderClientQt.h"
-#include "DOMImplementation.h"
-#include "ResourceHandleInternal.h"
-#include "Document.h"
-#include "Settings.h"
-#include "Plugin.h"
-#include "FrameView.h"
#include "FramePrivate.h"
-#include "GraphicsContext.h"
-#include "HTMLDocument.h"
-#include "ResourceHandle.h"
-#include "FrameLoader.h"
-#include "PlatformMouseEvent.h"
-#include "PlatformKeyboardEvent.h"
-#include "PlatformWheelEvent.h"
-#include "MouseEventWithHitTestResults.h"
-#include "SelectionController.h"
-#include "kjs_proxy.h"
-#include "TypingCommand.h"
-#include "JSLock.h"
-#include "kjs_window.h"
-#include "runtime_root.h"
-#include "runtime.h"
-#include <QScrollArea>
-#include "NotImplemented.h"
+#include "UserStyleSheetLoader.h"
namespace WebCore {
-// FIXME: Turned this off to fix buildbot. This function be either deleted or used.
-#if 0
-static void doScroll(const RenderObject* r, bool isHorizontal, int multiplier)
-{
- // FIXME: The scrolling done here should be done in the default handlers
- // of the elements rather than here in the part.
- if (!r)
- return;
-
- //broken since it calls scroll on scrollbars
- //and we have none now
- //r->scroll(direction, KWQScrollWheel, multiplier);
- if (!r->layer())
- return;
-
- int x = r->layer()->scrollXOffset();
- int y = r->layer()->scrollYOffset();
- if (isHorizontal)
- x += multiplier;
- else
- y += multiplier;
-
- r->layer()->scrollToOffset(x, y, true, true);
-}
-#endif
-
-KJS::Bindings::Instance* Frame::createScriptInstanceForWidget(WebCore::Widget* widget)
+DragImageRef Frame::dragImageForSelection()
{
- QWidget* nativeWidget = widget->nativeWidget();
- if (!nativeWidget)
- return 0;
- return KJS::Bindings::Instance::createBindingForLanguageInstance(KJS::Bindings::Instance::QtLanguage,
- nativeWidget,
- bindingRootObject());
+ return 0;
}
-void Frame::clearPlatformScriptObjects()
+void Frame::setUserStyleSheetLocation(const KURL& url)
{
+ delete d->m_userStyleSheetLoader;
+ d->m_userStyleSheetLoader = 0;
+ if (d->m_doc && d->m_doc->docLoader())
+ d->m_userStyleSheetLoader = new UserStyleSheetLoader(d->m_doc, url.string());
}
-DragImageRef Frame::dragImageForSelection()
-{
- return 0;
-}
-
-void Frame::dashboardRegionsChanged()
+void Frame::setUserStyleSheet(const String& styleSheet)
{
+ delete d->m_userStyleSheetLoader;
+ d->m_userStyleSheetLoader = 0;
+ if (d->m_doc)
+ d->m_doc->setUserStyleSheet(styleSheet);
}
}
diff --git a/WebCore/page/win/AXObjectCacheWin.cpp b/WebCore/page/win/AXObjectCacheWin.cpp
new file mode 100644
index 0000000..da30ac5
--- /dev/null
+++ b/WebCore/page/win/AXObjectCacheWin.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "config.h"
+#include "AXObjectCache.h"
+
+#include "AccessibilityObject.h"
+
+namespace WebCore {
+
+void AXObjectCache::detachWrapper(AccessibilityObject* obj)
+{
+ // On Windows, AccessibilityObjects are created when get_accChildCount is
+ // called, but they are not wrapped until get_accChild is called, so this
+ // object may not have a wrapper.
+ if (AccessibilityObjectWrapper* wrapper = obj->wrapper())
+ wrapper->detach();
+}
+
+void AXObjectCache::attachWrapper(AccessibilityObject*)
+{
+ // On Windows, AccessibilityObjects are wrapped when the accessibility
+ // software requests them via get_accChild.
+}
+
+void AXObjectCache::postNotification(RenderObject*, const String&)
+{
+}
+
+void AXObjectCache::postNotificationToElement(RenderObject*, const String&)
+{
+}
+
+void AXObjectCache::handleFocusedUIElementChanged()
+{
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/win/AccessibilityObjectWin.cpp b/WebCore/page/win/AccessibilityObjectWin.cpp
new file mode 100644
index 0000000..e309ac8
--- /dev/null
+++ b/WebCore/page/win/AccessibilityObjectWin.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "config.h"
+#include "AccessibilityObject.h"
+
+namespace WebCore {
+
+bool AccessibilityObject::accessibilityIgnoreAttachment() const
+{
+ return false;
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/win/AccessibilityObjectWrapperWin.h b/WebCore/page/win/AccessibilityObjectWrapperWin.h
new file mode 100644
index 0000000..779443c
--- /dev/null
+++ b/WebCore/page/win/AccessibilityObjectWrapperWin.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef AccessibilityObjectWrapperWin_h
+#define AccessibilityObjectWrapperWin_h
+
+namespace WebCore {
+
+ class AccessibilityObject;
+
+ class AccessibilityObjectWrapper : public IUnknown {
+ public:
+ // IUnknown
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject) = 0;
+ virtual ULONG STDMETHODCALLTYPE AddRef(void) = 0;
+ virtual ULONG STDMETHODCALLTYPE Release(void) = 0;
+
+ virtual void detach() = 0;
+ bool attached() const { return m_object; }
+ AccessibilityObject* accessibilityObject() const { return m_object; }
+
+ protected:
+ AccessibilityObjectWrapper(AccessibilityObject* obj) : m_object(obj) { }
+ AccessibilityObjectWrapper() : m_object(0) { }
+
+ AccessibilityObject* m_object;
+ };
+
+} // namespace WebCore
+
+#endif // AccessibilityObjectWrapperWin_h
diff --git a/WebCore/page/win/EventHandlerWin.cpp b/WebCore/page/win/EventHandlerWin.cpp
index 5e349e3..bfd2b02 100644
--- a/WebCore/page/win/EventHandlerWin.cpp
+++ b/WebCore/page/win/EventHandlerWin.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -36,14 +36,19 @@
#include "HitTestResult.h"
#include "MouseEventWithHitTestResults.h"
#include "Page.h"
-#include "PlatformScrollbar.h"
+#include "PlatformKeyboardEvent.h"
#include "PlatformWheelEvent.h"
+#include "Scrollbar.h"
#include "SelectionController.h"
#include "WCDataObject.h"
#include "NotImplemented.h"
namespace WebCore {
+unsigned EventHandler::s_accessKeyModifiers = PlatformKeyboardEvent::AltKey;
+
+const double EventHandler::TextDragDelay = 0.0;
+
bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe)
{
subframe->eventHandler()->handleMousePressEvent(mev.event());
@@ -72,13 +77,6 @@ bool EventHandler::passWheelEventToWidget(PlatformWheelEvent& wheelEvent, Widget
return static_cast<FrameView*>(widget)->frame()->eventHandler()->handleWheelEvent(wheelEvent);
}
-bool EventHandler::passMousePressEventToScrollbar(MouseEventWithHitTestResults& mev, PlatformScrollbar* scrollbar)
-{
- if (!scrollbar || !scrollbar->isEnabled())
- return false;
- return scrollbar->handleMousePressEvent(mev.event());
-}
-
bool EventHandler::tabsToAllControls(KeyboardEvent*) const
{
return true;
@@ -89,11 +87,11 @@ bool EventHandler::eventActivatedView(const PlatformMouseEvent& event) const
return event.activatedWebView();
}
-Clipboard* EventHandler::createDraggingClipboard() const
+PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const
{
COMPtr<WCDataObject> dataObject;
WCDataObject::createInstance(&dataObject);
- return new ClipboardWin(true, dataObject.get(), ClipboardWritable);
+ return ClipboardWin::create(true, dataObject.get(), ClipboardWritable);
}
void EventHandler::focusDocumentView()
diff --git a/WebCore/page/win/FrameCGWin.cpp b/WebCore/page/win/FrameCGWin.cpp
new file mode 100644
index 0000000..ad22967
--- /dev/null
+++ b/WebCore/page/win/FrameCGWin.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "FrameWin.h"
+
+#include <windows.h>
+
+#include "FrameView.h"
+#include "GraphicsContext.h"
+#include "Settings.h"
+
+#include <CoreGraphics/CoreGraphics.h>
+
+using std::min;
+
+namespace WebCore {
+
+static void drawRectIntoContext(IntRect rect, FrameView* view, GraphicsContext* gc)
+{
+ IntSize offset = view->scrollOffset();
+ rect.move(-offset.width(), -offset.height());
+ rect = view->convertToContainingWindow(rect);
+
+ gc->concatCTM(AffineTransform().translate(-rect.x(), -rect.y()));
+
+ view->paint(gc, rect);
+}
+
+HBITMAP imageFromSelection(Frame* frame, bool forceBlackText)
+{
+ frame->view()->setPaintRestriction(forceBlackText ? PaintRestrictionSelectionOnlyBlackText : PaintRestrictionSelectionOnly);
+ FloatRect fr = frame->selectionRect();
+ IntRect ir(static_cast<int>(fr.x()), static_cast<int>(fr.y()),
+ static_cast<int>(fr.width()), static_cast<int>(fr.height()));
+
+ void* bits;
+ HDC hdc = CreateCompatibleDC(0);
+ int w = ir.width();
+ int h = ir.height();
+ BITMAPINFO bmp = { { sizeof(BITMAPINFOHEADER), w, h, 1, 32 } };
+
+ HBITMAP hbmp = CreateDIBSection(0, &bmp, DIB_RGB_COLORS, static_cast<void**>(&bits), 0, 0);
+ HBITMAP hbmpOld = static_cast<HBITMAP>(SelectObject(hdc, hbmp));
+ CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB();
+ CGContextRef context = CGBitmapContextCreate(static_cast<void*>(bits), w, h,
+ 8, w * sizeof(RGBQUAD), deviceRGB, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
+ CGColorSpaceRelease(deviceRGB);
+ CGContextSaveGState(context);
+
+ GraphicsContext gc(context);
+
+ frame->document()->updateLayout();
+ drawRectIntoContext(ir, frame->view(), &gc);
+
+ CGContextRelease(context);
+ SelectObject(hdc, hbmpOld);
+ DeleteDC(hdc);
+
+ frame->view()->setPaintRestriction(PaintRestrictionNone);
+
+ return hbmp;
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/InspectorClient.h b/WebCore/page/win/FrameCairoWin.cpp
index ec1ee92..a645a10 100644
--- a/WebCore/page/InspectorClient.h
+++ b/WebCore/page/win/FrameCairoWin.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,37 +23,20 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef InspectorClient_h
-#define InspectorClient_h
+#include "config.h"
+#include "FrameWin.h"
-namespace WebCore {
-
-class Node;
-class Page;
-class String;
-
-class InspectorClient {
-public:
- virtual ~InspectorClient() { }
-
- virtual void inspectorDestroyed() = 0;
-
- virtual Page* createPage() = 0;
+#include "EditorClient.h"
+#include "NotImplemented.h"
- virtual String localizedStringsURL() = 0;
+using std::min;
- virtual void showWindow() = 0;
- virtual void closeWindow() = 0;
-
- virtual void attachWindow() = 0;
- virtual void detachWindow() = 0;
-
- virtual void highlight(Node*) = 0;
- virtual void hideHighlight() = 0;
+namespace WebCore {
- virtual void inspectedURLChanged(const String& newURL) = 0;
-};
+HBITMAP imageFromSelection(Frame* frame, bool forceBlackText)
+{
+ notImplemented();
+ return 0;
+}
} // namespace WebCore
-
-#endif // !defined(InspectorClient_h)
diff --git a/WebCore/page/win/FrameWin.cpp b/WebCore/page/win/FrameWin.cpp
new file mode 100644
index 0000000..536f5d8
--- /dev/null
+++ b/WebCore/page/win/FrameWin.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "runtime.h"
+#include "FrameWin.h"
+
+#include "AffineTransform.h"
+#include "FloatRect.h"
+#include "Document.h"
+#include "FramePrivate.h"
+#include "RenderView.h"
+#include "Settings.h"
+
+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 = static_cast<RenderView*>(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->docWidth());
+ 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 docWidth = root->layer()->width();
+ 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->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())
+ return imageFromSelection(this, false);
+
+ return 0;
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/win/FrameWin.h b/WebCore/page/win/FrameWin.h
new file mode 100644
index 0000000..405c7b2
--- /dev/null
+++ b/WebCore/page/win/FrameWin.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FrameWin_H
+#define FrameWin_H
+
+#include "Frame.h"
+
+// Forward declared so we don't need wingdi.h.
+typedef struct HBITMAP__* HBITMAP;
+
+namespace WebCore {
+
+ HBITMAP imageFromSelection(Frame* frame, bool forceWhiteText);
+ void computePageRectsForFrame(Frame*, const IntRect& printRect, float headerHeight, float footerHeight, float userScaleFactor,Vector<IntRect>& pages, int& pageHeight);
+
+}
+
+#endif
diff --git a/WebCore/page/win/PageWin.cpp b/WebCore/page/win/PageWin.cpp
new file mode 100644
index 0000000..f4c744a
--- /dev/null
+++ b/WebCore/page/win/PageWin.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Page.h"
+
+#include "Frame.h"
+#include "FrameView.h"
+#include "FloatRect.h"
+#include <windows.h>
+
+namespace WebCore {
+
+HINSTANCE Page::s_instanceHandle = 0;
+
+} // namespace WebCore
diff --git a/WebCore/page/wx/AccessibilityObjectWx.cpp b/WebCore/page/wx/AccessibilityObjectWx.cpp
new file mode 100644
index 0000000..b755645
--- /dev/null
+++ b/WebCore/page/wx/AccessibilityObjectWx.cpp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2008 Apple Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "AccessibilityObject.h"
+
+namespace WebCore {
+
+bool AccessibilityObject::accessibilityIgnoreAttachment() const
+{
+ return false;
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/wx/EventHandlerWx.cpp b/WebCore/page/wx/EventHandlerWx.cpp
index 6670c18..ce4473f 100644
--- a/WebCore/page/wx/EventHandlerWx.cpp
+++ b/WebCore/page/wx/EventHandlerWx.cpp
@@ -24,20 +24,25 @@
*/
#include "config.h"
+#include "EventHandler.h"
#include "ClipboardWx.h"
-#include "EventHandler.h"
#include "FocusController.h"
#include "Frame.h"
#include "FrameView.h"
#include "KeyboardEvent.h"
#include "MouseEventWithHitTestResults.h"
#include "Page.h"
-#include "PlatformScrollBar.h"
+#include "PlatformKeyboardEvent.h"
#include "RenderWidget.h"
+#include "Scrollbar.h"
namespace WebCore {
+unsigned EventHandler::s_accessKeyModifiers = PlatformKeyboardEvent::AltKey;
+
+const double EventHandler::TextDragDelay = 0.0;
+
bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe)
{
return passSubframeEventToSubframe(mev, subframe);
@@ -53,11 +58,6 @@ bool EventHandler::passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&
return passSubframeEventToSubframe(mev, subframe);
}
-bool EventHandler::passMousePressEventToScrollbar(MouseEventWithHitTestResults& mouseEvent, PlatformScrollbar* scrollbar)
-{
- return passMouseDownEventToWidget(scrollbar);
-}
-
bool EventHandler::passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults& event)
{
// Figure out which view to send the event to.
@@ -86,9 +86,9 @@ bool EventHandler::eventActivatedView(const PlatformMouseEvent&) const
return false;
}
-Clipboard* EventHandler::createDraggingClipboard() const
+PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const
{
- return new ClipboardWx(ClipboardWritable, true);
+ return ClipboardWx::create(ClipboardWritable, true);
}
}