summaryrefslogtreecommitdiffstats
path: root/WebKitTools
diff options
context:
space:
mode:
Diffstat (limited to 'WebKitTools')
-rwxr-xr-xWebKitTools/BuildSlaveSupport/build-launcher-app165
-rwxr-xr-xWebKitTools/BuildSlaveSupport/build-launcher-dmg136
-rw-r--r--WebKitTools/BuildSlaveSupport/build.webkit.org-config/Makefile19
-rw-r--r--WebKitTools/BuildSlaveSupport/build.webkit.org-config/buildbot.css108
-rw-r--r--WebKitTools/BuildSlaveSupport/build.webkit.org-config/buildbot.tac10
-rw-r--r--WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg22
-rw-r--r--WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/__init__.py5
-rw-r--r--WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/auth.py9
-rw-r--r--WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/basesteps.py51
-rw-r--r--WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/builders.py35
-rw-r--r--WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/factories.py70
-rw-r--r--WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/schedulers.py15
-rw-r--r--WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/status.py19
-rw-r--r--WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/steps.py220
-rwxr-xr-xWebKitTools/BuildSlaveSupport/run-performance-tests80
-rw-r--r--WebKitTools/CLWrapper/CLWrapper.cpp52
-rw-r--r--WebKitTools/CLWrapper/CLWrapper.sln20
-rw-r--r--WebKitTools/CLWrapper/CLWrapper.vcproj199
-rw-r--r--WebKitTools/CodeCoverage/README22
-rw-r--r--WebKitTools/CodeCoverage/amber.pngbin0 -> 127 bytes
-rw-r--r--WebKitTools/CodeCoverage/cov.py201
-rw-r--r--WebKitTools/CodeCoverage/emerald.pngbin0 -> 127 bytes
-rw-r--r--WebKitTools/CodeCoverage/gcov.css116
-rw-r--r--WebKitTools/CodeCoverage/glass.pngbin0 -> 127 bytes
-rwxr-xr-xWebKitTools/CodeCoverage/regenerate-coverage-display408
-rw-r--r--WebKitTools/CodeCoverage/ruby.pngbin0 -> 127 bytes
-rwxr-xr-xWebKitTools/CodeCoverage/run-generate-coverage-data240
-rw-r--r--WebKitTools/CodeCoverage/snow.pngbin0 -> 127 bytes
-rw-r--r--WebKitTools/CygwinDownloader/cygwin-downloader.py157
-rw-r--r--WebKitTools/CygwinDownloader/cygwin-downloader.zipbin0 -> 2978596 bytes
-rwxr-xr-xWebKitTools/CygwinDownloader/make-zip.sh30
-rw-r--r--WebKitTools/CygwinDownloader/setup.py4
-rw-r--r--WebKitTools/DrawTest/AppDelegate.h37
-rw-r--r--WebKitTools/DrawTest/AppDelegate.m52
-rw-r--r--WebKitTools/DrawTest/DrawTest.xcodeproj/project.pbxproj388
-rw-r--r--WebKitTools/DrawTest/DrawTestDocument.h45
-rw-r--r--WebKitTools/DrawTest/DrawTestDocument.m151
-rw-r--r--WebKitTools/DrawTest/DrawTestInspectorController.h37
-rw-r--r--WebKitTools/DrawTest/DrawTestInspectorController.m48
-rw-r--r--WebKitTools/DrawTest/DrawTestToolbarController.h37
-rw-r--r--WebKitTools/DrawTest/DrawTestToolbarController.m354
-rw-r--r--WebKitTools/DrawTest/DrawTestView.h38
-rw-r--r--WebKitTools/DrawTest/DrawTestView.m43
-rw-r--r--WebKitTools/DrawTest/DrawTest_Prefix.pch37
-rw-r--r--WebKitTools/DrawTest/English.lproj/DrawTestDocument.nib/classes.nib34
-rw-r--r--WebKitTools/DrawTest/English.lproj/DrawTestDocument.nib/info.nib22
-rw-r--r--WebKitTools/DrawTest/English.lproj/DrawTestDocument.nib/keyedobjects.nibbin0 -> 6746 bytes
-rw-r--r--WebKitTools/DrawTest/English.lproj/InfoPlist.stringsbin0 -> 262 bytes
-rw-r--r--WebKitTools/DrawTest/English.lproj/Inspector.nib/classes.nib12
-rw-r--r--WebKitTools/DrawTest/English.lproj/Inspector.nib/info.nib16
-rw-r--r--WebKitTools/DrawTest/English.lproj/Inspector.nib/keyedobjects.nibbin0 -> 9256 bytes
-rw-r--r--WebKitTools/DrawTest/English.lproj/MainMenu.nib/classes.nib44
-rw-r--r--WebKitTools/DrawTest/English.lproj/MainMenu.nib/info.nib21
-rw-r--r--WebKitTools/DrawTest/English.lproj/MainMenu.nib/keyedobjects.nibbin0 -> 17633 bytes
-rw-r--r--WebKitTools/DrawTest/English.lproj/TestViewer.nib/classes.nib36
-rw-r--r--WebKitTools/DrawTest/English.lproj/TestViewer.nib/info.nib17
-rw-r--r--WebKitTools/DrawTest/English.lproj/TestViewer.nib/keyedobjects.nibbin0 -> 11724 bytes
-rw-r--r--WebKitTools/DrawTest/Info.plist49
-rw-r--r--WebKitTools/DrawTest/SVGTest.h48
-rw-r--r--WebKitTools/DrawTest/SVGTest.m113
-rw-r--r--WebKitTools/DrawTest/ScalingImageView.h33
-rw-r--r--WebKitTools/DrawTest/ScalingImageView.m57
-rw-r--r--WebKitTools/DrawTest/TestController.h72
-rw-r--r--WebKitTools/DrawTest/TestController.m270
-rw-r--r--WebKitTools/DrawTest/TestViewerSplitView.h31
-rw-r--r--WebKitTools/DrawTest/TestViewerSplitView.m77
-rw-r--r--WebKitTools/DrawTest/main.m29
-rw-r--r--WebKitTools/Drosera/DebuggerDocument.cpp364
-rw-r--r--WebKitTools/Drosera/DebuggerDocument.h105
-rw-r--r--WebKitTools/Drosera/Drosera.icnsbin0 -> 123560 bytes
-rw-r--r--WebKitTools/Drosera/DroseraWin.make13
-rw-r--r--WebKitTools/Drosera/English.lproj/Debugger.nib/classes.nib12
-rw-r--r--WebKitTools/Drosera/English.lproj/Debugger.nib/info.nib16
-rw-r--r--WebKitTools/Drosera/English.lproj/Debugger.nib/keyedobjects.nibbin0 -> 4330 bytes
-rw-r--r--WebKitTools/Drosera/English.lproj/MainMenu.nib/classes.nib40
-rw-r--r--WebKitTools/Drosera/English.lproj/MainMenu.nib/info.nib22
-rw-r--r--WebKitTools/Drosera/English.lproj/MainMenu.nib/keyedobjects.nibbin0 -> 16697 bytes
-rw-r--r--WebKitTools/Drosera/ForwardingHeaders/wtf/Assertions.h1
-rw-r--r--WebKitTools/Drosera/ForwardingHeaders/wtf/HashTraits.h1
-rw-r--r--WebKitTools/Drosera/ForwardingHeaders/wtf/Noncopyable.h1
-rw-r--r--WebKitTools/Drosera/ForwardingHeaders/wtf/OwnPtr.h1
-rw-r--r--WebKitTools/Drosera/ForwardingHeaders/wtf/Platform.h1
-rw-r--r--WebKitTools/Drosera/ForwardingHeaders/wtf/RetainPtr.h1
-rw-r--r--WebKitTools/Drosera/Images/Drosera.icobin0 -> 145950 bytes
-rw-r--r--WebKitTools/Drosera/Images/SourceArrow.pngbin0 -> 663 bytes
-rw-r--r--WebKitTools/Drosera/Images/SourceArrowBlank.pngbin0 -> 150 bytes
-rw-r--r--WebKitTools/Drosera/Images/SourceArrowOpen.pngbin0 -> 676 bytes
-rw-r--r--WebKitTools/Drosera/Images/background_stripe.pngbin0 -> 548 bytes
-rw-r--r--WebKitTools/Drosera/Images/breakPoint.tifbin0 -> 628 bytes
-rw-r--r--WebKitTools/Drosera/Images/breakPointDisabled.tifbin0 -> 634 bytes
-rw-r--r--WebKitTools/Drosera/Images/breakpointeditor.pngbin0 -> 1627 bytes
-rw-r--r--WebKitTools/Drosera/Images/close.tifbin0 -> 15388 bytes
-rw-r--r--WebKitTools/Drosera/Images/close_active.tifbin0 -> 15416 bytes
-rw-r--r--WebKitTools/Drosera/Images/close_hover.tifbin0 -> 15444 bytes
-rw-r--r--WebKitTools/Drosera/Images/console.pngbin0 -> 1932 bytes
-rw-r--r--WebKitTools/Drosera/Images/continue.tifbin0 -> 2302 bytes
-rw-r--r--WebKitTools/Drosera/Images/fileIcon.jpgbin0 -> 406 bytes
-rw-r--r--WebKitTools/Drosera/Images/finishFunction.tifbin0 -> 2378 bytes
-rw-r--r--WebKitTools/Drosera/Images/glossyFooterFill.tifbin0 -> 226 bytes
-rw-r--r--WebKitTools/Drosera/Images/glossyHeader.pngbin0 -> 3563 bytes
-rw-r--r--WebKitTools/Drosera/Images/glossyHeaderPressed.pngbin0 -> 189 bytes
-rw-r--r--WebKitTools/Drosera/Images/gradientBackground.pngbin0 -> 3585 bytes
-rw-r--r--WebKitTools/Drosera/Images/gutter.pngbin0 -> 3549 bytes
-rw-r--r--WebKitTools/Drosera/Images/navLeftDisabled.pngbin0 -> 3017 bytes
-rw-r--r--WebKitTools/Drosera/Images/navLeftNormal.pngbin0 -> 3005 bytes
-rw-r--r--WebKitTools/Drosera/Images/navLeftPressed.pngbin0 -> 3029 bytes
-rw-r--r--WebKitTools/Drosera/Images/navRightDisabled.pngbin0 -> 3017 bytes
-rw-r--r--WebKitTools/Drosera/Images/navRightNormal.pngbin0 -> 2998 bytes
-rw-r--r--WebKitTools/Drosera/Images/navRightPressed.pngbin0 -> 3028 bytes
-rw-r--r--WebKitTools/Drosera/Images/pause.tifbin0 -> 2232 bytes
-rw-r--r--WebKitTools/Drosera/Images/popUpArrows.pngbin0 -> 368 bytes
-rw-r--r--WebKitTools/Drosera/Images/programCounter.tifbin0 -> 16420 bytes
-rw-r--r--WebKitTools/Drosera/Images/programCounterBreakPoint.tifbin0 -> 19668 bytes
-rw-r--r--WebKitTools/Drosera/Images/programCounterBreakPointDisabled.tifbin0 -> 21236 bytes
-rw-r--r--WebKitTools/Drosera/Images/run.tifbin0 -> 2208 bytes
-rw-r--r--WebKitTools/Drosera/Images/siteCollapsed.tifbin0 -> 26960 bytes
-rw-r--r--WebKitTools/Drosera/Images/siteExpanded.tifbin0 -> 26968 bytes
-rw-r--r--WebKitTools/Drosera/Images/siteIcon.tifbin0 -> 26744 bytes
-rw-r--r--WebKitTools/Drosera/Images/small.icobin0 -> 145950 bytes
-rw-r--r--WebKitTools/Drosera/Images/splitterBar.tifbin0 -> 456 bytes
-rw-r--r--WebKitTools/Drosera/Images/splitterDimple.tifbin0 -> 290 bytes
-rw-r--r--WebKitTools/Drosera/Images/step.tifbin0 -> 2322 bytes
-rw-r--r--WebKitTools/Drosera/Images/stepOut.tifbin0 -> 2314 bytes
-rw-r--r--WebKitTools/Drosera/Images/stepOver.tifbin0 -> 2368 bytes
-rw-r--r--WebKitTools/Drosera/Images/stop.tifbin0 -> 2110 bytes
-rw-r--r--WebKitTools/Drosera/Images/toolbarBackground.pngbin0 -> 825 bytes
-rw-r--r--WebKitTools/Drosera/Images/verticalSplitterBar.tiffbin0 -> 2598 bytes
-rw-r--r--WebKitTools/Drosera/Images/verticalSplitterDimple.tiffbin0 -> 738 bytes
-rw-r--r--WebKitTools/Drosera/Makefile3
-rw-r--r--WebKitTools/Drosera/breakpointEditor.html1
-rw-r--r--WebKitTools/Drosera/config.h44
-rw-r--r--WebKitTools/Drosera/console.css106
-rw-r--r--WebKitTools/Drosera/console.html47
-rw-r--r--WebKitTools/Drosera/console.js111
-rw-r--r--WebKitTools/Drosera/debugger.css314
-rw-r--r--WebKitTools/Drosera/debugger.html92
-rw-r--r--WebKitTools/Drosera/debugger.js1433
-rw-r--r--WebKitTools/Drosera/mac/DebuggerApplication.h39
-rw-r--r--WebKitTools/Drosera/mac/DebuggerApplication.mm154
-rw-r--r--WebKitTools/Drosera/mac/DebuggerClient.h52
-rw-r--r--WebKitTools/Drosera/mac/DebuggerClient.mm387
-rw-r--r--WebKitTools/Drosera/mac/DebuggerDocumentPlatform.mm205
-rw-r--r--WebKitTools/Drosera/mac/Drosera.xcodeproj/project.pbxproj659
-rw-r--r--WebKitTools/Drosera/mac/Info.plist30
-rw-r--r--WebKitTools/Drosera/mac/LauncherInfo.plist26
-rw-r--r--WebKitTools/Drosera/mac/Makefile2
-rw-r--r--WebKitTools/Drosera/mac/ServerConnection.h53
-rw-r--r--WebKitTools/Drosera/mac/ServerConnection.mm265
-rw-r--r--WebKitTools/Drosera/mac/launcher.m108
-rw-r--r--WebKitTools/Drosera/mac/main.m34
-rw-r--r--WebKitTools/Drosera/viewer.css146
-rw-r--r--WebKitTools/Drosera/viewer.html48
-rw-r--r--WebKitTools/Drosera/win/BaseDelegate.h313
-rw-r--r--WebKitTools/Drosera/win/DebuggerClient.cpp341
-rw-r--r--WebKitTools/Drosera/win/DebuggerClient.h107
-rw-r--r--WebKitTools/Drosera/win/DebuggerDocumentPlatform.cpp160
-rw-r--r--WebKitTools/Drosera/win/Drosera.cpp392
-rw-r--r--WebKitTools/Drosera/win/Drosera.h70
-rwxr-xr-xWebKitTools/Drosera/win/Drosera.vcproj/Drosera.rc196
-rwxr-xr-xWebKitTools/Drosera/win/Drosera.vcproj/Drosera.vcproj449
-rw-r--r--WebKitTools/Drosera/win/DroseraPrefix.cpp29
-rw-r--r--WebKitTools/Drosera/win/DroseraPrefix.h58
-rw-r--r--WebKitTools/Drosera/win/Info.plist26
-rw-r--r--WebKitTools/Drosera/win/ServerConnection.cpp368
-rw-r--r--WebKitTools/Drosera/win/ServerConnection.h128
-rw-r--r--WebKitTools/Drosera/win/resource.h47
-rw-r--r--WebKitTools/DumpRenderTree/DumpRenderTree.h61
-rw-r--r--WebKitTools/DumpRenderTree/DumpRenderTree.sln47
-rw-r--r--WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj752
-rw-r--r--WebKitTools/DumpRenderTree/DumpRenderTreePrefix.h33
-rw-r--r--WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/ASCIICType.h1
-rw-r--r--WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Assertions.h1
-rw-r--r--WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/HashMap.h1
-rw-r--r--WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/HashSet.h1
-rwxr-xr-xWebKitTools/DumpRenderTree/ForwardingHeaders/wtf/HashTraits.h1
-rw-r--r--WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/MathExtras.h1
-rw-r--r--WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Noncopyable.h1
-rw-r--r--WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/OwnPtr.h1
-rw-r--r--WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Platform.h1
-rw-r--r--WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/RetainPtr.h1
-rw-r--r--WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/StringExtras.h1
-rw-r--r--WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Vector.h1
-rw-r--r--WebKitTools/DumpRenderTree/GCController.cpp108
-rw-r--r--WebKitTools/DumpRenderTree/GCController.h51
-rw-r--r--WebKitTools/DumpRenderTree/JavaScriptThreading.h40
-rw-r--r--WebKitTools/DumpRenderTree/LayoutTestController.cpp720
-rw-r--r--WebKitTools/DumpRenderTree/LayoutTestController.h168
-rw-r--r--WebKitTools/DumpRenderTree/Makefile2
-rw-r--r--WebKitTools/DumpRenderTree/PixelDumpSupport.h40
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/Info.plist60
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.cpp470
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.h48
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/TestObject.cpp107
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/TestObject.h29
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/main.cpp264
-rw-r--r--WebKitTools/DumpRenderTree/WorkQueue.cpp89
-rw-r--r--WebKitTools/DumpRenderTree/WorkQueue.h51
-rw-r--r--WebKitTools/DumpRenderTree/WorkQueueItem.h108
-rw-r--r--WebKitTools/DumpRenderTree/cg/ImageDiffCG.cpp208
-rw-r--r--WebKitTools/DumpRenderTree/cg/PixelDumpSupportCG.cpp126
-rw-r--r--WebKitTools/DumpRenderTree/cg/PixelDumpSupportCG.h55
-rw-r--r--WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp374
-rw-r--r--WebKitTools/DumpRenderTree/gtk/DumpRenderTree.pro19
-rw-r--r--WebKitTools/DumpRenderTree/gtk/DumpRenderTreeGtk.h38
-rw-r--r--WebKitTools/DumpRenderTree/gtk/GCControllerGtk.cpp42
-rw-r--r--WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp223
-rw-r--r--WebKitTools/DumpRenderTree/gtk/WorkQueueItemGtk.cpp72
-rw-r--r--WebKitTools/DumpRenderTree/mac/AppleScriptController.h39
-rw-r--r--WebKitTools/DumpRenderTree/mac/AppleScriptController.m126
-rw-r--r--WebKitTools/DumpRenderTree/mac/CheckedMalloc.cpp59
-rw-r--r--WebKitTools/DumpRenderTree/mac/CheckedMalloc.h31
-rw-r--r--WebKitTools/DumpRenderTree/mac/Configurations/Base.xcconfig16
-rw-r--r--WebKitTools/DumpRenderTree/mac/Configurations/DebugRelease.xcconfig5
-rw-r--r--WebKitTools/DumpRenderTree/mac/Configurations/DumpRenderTree.xcconfig4
-rw-r--r--WebKitTools/DumpRenderTree/mac/Configurations/ImageDiff.xcconfig1
-rw-r--r--WebKitTools/DumpRenderTree/mac/Configurations/TestNetscapePlugIn.xcconfig6
-rw-r--r--WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm931
-rw-r--r--WebKitTools/DumpRenderTree/mac/DumpRenderTreeDraggingInfo.h53
-rw-r--r--WebKitTools/DumpRenderTree/mac/DumpRenderTreeDraggingInfo.mm108
-rw-r--r--WebKitTools/DumpRenderTree/mac/DumpRenderTreeMac.h57
-rw-r--r--WebKitTools/DumpRenderTree/mac/DumpRenderTreePasteboard.h37
-rw-r--r--WebKitTools/DumpRenderTree/mac/DumpRenderTreePasteboard.m202
-rw-r--r--WebKitTools/DumpRenderTree/mac/DumpRenderTreeWindow.h36
-rw-r--r--WebKitTools/DumpRenderTree/mac/DumpRenderTreeWindow.mm85
-rw-r--r--WebKitTools/DumpRenderTree/mac/EditingDelegate.h38
-rw-r--r--WebKitTools/DumpRenderTree/mac/EditingDelegate.mm191
-rw-r--r--WebKitTools/DumpRenderTree/mac/EventSendingController.h53
-rw-r--r--WebKitTools/DumpRenderTree/mac/EventSendingController.mm589
-rw-r--r--WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.h37
-rw-r--r--WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.mm333
-rw-r--r--WebKitTools/DumpRenderTree/mac/GCControllerMac.mm47
-rw-r--r--WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm282
-rw-r--r--WebKitTools/DumpRenderTree/mac/NavigationController.h39
-rw-r--r--WebKitTools/DumpRenderTree/mac/NavigationController.m109
-rw-r--r--WebKitTools/DumpRenderTree/mac/ObjCController.h38
-rw-r--r--WebKitTools/DumpRenderTree/mac/ObjCController.m231
-rw-r--r--WebKitTools/DumpRenderTree/mac/ObjCPlugin.h36
-rw-r--r--WebKitTools/DumpRenderTree/mac/ObjCPlugin.m206
-rw-r--r--WebKitTools/DumpRenderTree/mac/ObjCPluginFunction.h34
-rw-r--r--WebKitTools/DumpRenderTree/mac/ObjCPluginFunction.m37
-rw-r--r--WebKitTools/DumpRenderTree/mac/PixelDumpSupportMac.mm162
-rw-r--r--WebKitTools/DumpRenderTree/mac/PolicyDelegate.h35
-rw-r--r--WebKitTools/DumpRenderTree/mac/PolicyDelegate.mm45
-rw-r--r--WebKitTools/DumpRenderTree/mac/ResourceLoadDelegate.h35
-rw-r--r--WebKitTools/DumpRenderTree/mac/ResourceLoadDelegate.mm179
-rw-r--r--WebKitTools/DumpRenderTree/mac/TextInputController.h42
-rw-r--r--WebKitTools/DumpRenderTree/mac/TextInputController.m423
-rw-r--r--WebKitTools/DumpRenderTree/mac/UIDelegate.h37
-rw-r--r--WebKitTools/DumpRenderTree/mac/UIDelegate.mm153
-rw-r--r--WebKitTools/DumpRenderTree/mac/WorkQueueItemMac.mm77
-rw-r--r--WebKitTools/DumpRenderTree/pthreads/JavaScriptThreadingPthreads.cpp129
-rw-r--r--WebKitTools/DumpRenderTree/qt/DumpRenderTree.cpp310
-rw-r--r--WebKitTools/DumpRenderTree/qt/DumpRenderTree.h98
-rw-r--r--WebKitTools/DumpRenderTree/qt/DumpRenderTree.pro18
-rw-r--r--WebKitTools/DumpRenderTree/qt/fonts.conf258
-rw-r--r--WebKitTools/DumpRenderTree/qt/fonts/AHEM____.TTFbin0 -> 12480 bytes
-rw-r--r--WebKitTools/DumpRenderTree/qt/jsobjects.cpp360
-rw-r--r--WebKitTools/DumpRenderTree/qt/jsobjects.h139
-rw-r--r--WebKitTools/DumpRenderTree/qt/main.cpp177
-rw-r--r--WebKitTools/DumpRenderTree/qt/testplugin.cpp71
-rw-r--r--WebKitTools/DumpRenderTree/qt/testplugin.h52
-rw-r--r--WebKitTools/DumpRenderTree/win/DraggingInfo.h62
-rw-r--r--WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp1103
-rw-r--r--WebKitTools/DumpRenderTree/win/DumpRenderTree.vcproj374
-rw-r--r--WebKitTools/DumpRenderTree/win/DumpRenderTreeWin.h74
-rw-r--r--WebKitTools/DumpRenderTree/win/EditingDelegate.cpp354
-rw-r--r--WebKitTools/DumpRenderTree/win/EditingDelegate.h176
-rw-r--r--WebKitTools/DumpRenderTree/win/EventSender.cpp566
-rw-r--r--WebKitTools/DumpRenderTree/win/EventSender.h42
-rw-r--r--WebKitTools/DumpRenderTree/win/FrameLoadDelegate.cpp296
-rw-r--r--WebKitTools/DumpRenderTree/win/FrameLoadDelegate.h137
-rw-r--r--WebKitTools/DumpRenderTree/win/GCControllerWin.cpp59
-rw-r--r--WebKitTools/DumpRenderTree/win/ImageDiff.vcproj159
-rw-r--r--WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp563
-rw-r--r--WebKitTools/DumpRenderTree/win/MD5.cpp77
-rw-r--r--WebKitTools/DumpRenderTree/win/MD5.h45
-rw-r--r--WebKitTools/DumpRenderTree/win/PixelDumpSupportWin.cpp67
-rw-r--r--WebKitTools/DumpRenderTree/win/PolicyDelegate.cpp85
-rw-r--r--WebKitTools/DumpRenderTree/win/PolicyDelegate.h74
-rw-r--r--WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.cpp256
-rw-r--r--WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.h103
-rw-r--r--WebKitTools/DumpRenderTree/win/TestNetscapePlugin/TestNetscapePlugin.def6
-rw-r--r--WebKitTools/DumpRenderTree/win/TestNetscapePlugin/TestNetscapePlugin.rc101
-rw-r--r--WebKitTools/DumpRenderTree/win/TestNetscapePlugin/TestNetscapePlugin.vcproj257
-rw-r--r--WebKitTools/DumpRenderTree/win/TestNetscapePlugin/main.c183
-rw-r--r--WebKitTools/DumpRenderTree/win/TestNetscapePlugin/main.cpp191
-rw-r--r--WebKitTools/DumpRenderTree/win/TestNetscapePlugin/resource.h14
-rwxr-xr-xWebKitTools/DumpRenderTree/win/UIDelegate.cpp415
-rwxr-xr-xWebKitTools/DumpRenderTree/win/UIDelegate.h316
-rw-r--r--WebKitTools/DumpRenderTree/win/WorkQueueItemWin.cpp133
-rw-r--r--WebKitTools/FindSafari/FindSafari.cpp201
-rw-r--r--WebKitTools/FindSafari/FindSafari.vcproj110
-rw-r--r--WebKitTools/GNUmakefile.am48
-rw-r--r--WebKitTools/GtkLauncher/GtkLauncher.pro10
-rw-r--r--WebKitTools/GtkLauncher/main.c203
-rw-r--r--WebKitTools/GtkLauncher/simple.svg15
-rw-r--r--WebKitTools/GtkLauncher/text.html9
-rw-r--r--WebKitTools/MIDLWrapper/MIDLWrapper.cpp86
-rw-r--r--WebKitTools/MIDLWrapper/MIDLWrapper.sln20
-rw-r--r--WebKitTools/MIDLWrapper/MIDLWrapper.vcproj199
-rw-r--r--WebKitTools/Makefile30
-rw-r--r--WebKitTools/Scripts/SpacingHeuristics.pm101
-rw-r--r--WebKitTools/Scripts/VCSUtils.pm121
-rwxr-xr-xWebKitTools/Scripts/bisect-builds417
-rwxr-xr-xWebKitTools/Scripts/build-drawtest48
-rwxr-xr-xWebKitTools/Scripts/build-drosera53
-rwxr-xr-xWebKitTools/Scripts/build-dumprendertree54
-rwxr-xr-xWebKitTools/Scripts/build-testkjs54
-rwxr-xr-xWebKitTools/Scripts/build-webkit351
-rwxr-xr-xWebKitTools/Scripts/check-dom-results141
-rwxr-xr-xWebKitTools/Scripts/check-for-global-initializers131
-rwxr-xr-xWebKitTools/Scripts/clean-header-guards53
-rwxr-xr-xWebKitTools/Scripts/commit-log-editor189
-rwxr-xr-xWebKitTools/Scripts/compare-timing-files88
-rwxr-xr-xWebKitTools/Scripts/debug-safari38
-rwxr-xr-xWebKitTools/Scripts/do-file-rename110
-rwxr-xr-xWebKitTools/Scripts/do-webcore-rename345
-rwxr-xr-xWebKitTools/Scripts/extract-localizable-strings359
-rwxr-xr-xWebKitTools/Scripts/find-extra-includes102
-rwxr-xr-xWebKitTools/Scripts/find-included-framework-headers10
-rw-r--r--WebKitTools/Scripts/gdb-drosera59
-rwxr-xr-xWebKitTools/Scripts/gdb-safari61
-rwxr-xr-xWebKitTools/Scripts/generate-coverage-data71
-rwxr-xr-xWebKitTools/Scripts/make-js-test-wrappers103
-rwxr-xr-xWebKitTools/Scripts/num-cpus16
-rwxr-xr-xWebKitTools/Scripts/parallelcl224
-rwxr-xr-xWebKitTools/Scripts/parse-malloc-history154
-rwxr-xr-xWebKitTools/Scripts/pdevenv24
-rwxr-xr-xWebKitTools/Scripts/prepare-ChangeLog1256
-rwxr-xr-xWebKitTools/Scripts/report-include-statistics114
-rwxr-xr-xWebKitTools/Scripts/resolve-ChangeLogs305
-rwxr-xr-xWebKitTools/Scripts/run-drawtest47
-rw-r--r--WebKitTools/Scripts/run-drosera41
-rw-r--r--WebKitTools/Scripts/run-drosera-nightly.cmd12
-rwxr-xr-xWebKitTools/Scripts/run-drosera.cmd5
-rwxr-xr-xWebKitTools/Scripts/run-iexploder-tests170
-rwxr-xr-xWebKitTools/Scripts/run-javascriptcore-tests173
-rwxr-xr-xWebKitTools/Scripts/run-launcher75
-rwxr-xr-xWebKitTools/Scripts/run-leaks212
-rwxr-xr-xWebKitTools/Scripts/run-mangleme-tests173
-rwxr-xr-xWebKitTools/Scripts/run-pageloadtest92
-rwxr-xr-xWebKitTools/Scripts/run-safari41
-rwxr-xr-xWebKitTools/Scripts/run-sunspider123
-rwxr-xr-xWebKitTools/Scripts/run-testkjs58
-rwxr-xr-xWebKitTools/Scripts/run-webkit-app50
-rwxr-xr-xWebKitTools/Scripts/run-webkit-httpd127
-rwxr-xr-xWebKitTools/Scripts/run-webkit-nightly.cmd10
-rwxr-xr-xWebKitTools/Scripts/run-webkit-tests1627
-rwxr-xr-xWebKitTools/Scripts/set-webkit-configuration41
-rwxr-xr-xWebKitTools/Scripts/sort-Xcode-project-file115
-rwxr-xr-xWebKitTools/Scripts/split-file-by-class159
-rwxr-xr-xWebKitTools/Scripts/sunspider-compare-results101
-rwxr-xr-xWebKitTools/Scripts/svn-apply438
-rwxr-xr-xWebKitTools/Scripts/svn-create-patch442
-rwxr-xr-xWebKitTools/Scripts/svn-unapply374
-rwxr-xr-xWebKitTools/Scripts/update-iexploder-cssproperties112
-rwxr-xr-xWebKitTools/Scripts/update-javascriptcore-test-results73
-rwxr-xr-xWebKitTools/Scripts/update-webkit92
-rwxr-xr-xWebKitTools/Scripts/update-webkit-auxiliary-libs121
-rwxr-xr-xWebKitTools/Scripts/update-webkit-localizable-strings45
-rwxr-xr-xWebKitTools/Scripts/update-webkit-support-libs105
-rw-r--r--WebKitTools/Scripts/webkitdirs.pm947
-rwxr-xr-xWebKitTools/Scripts/wkstyle66
-rw-r--r--WebKitTools/WebKitLauncher/Info.plist476
-rw-r--r--WebKitTools/WebKitLauncher/VERSION1
-rw-r--r--WebKitTools/WebKitLauncher/WebKitLauncher.xcodeproj/project.pbxproj359
-rw-r--r--WebKitTools/WebKitLauncher/WebKitNightlyEnabler.m165
-rw-r--r--WebKitTools/WebKitLauncher/main.m175
-rw-r--r--WebKitTools/WebKitLauncher/start.html33
-rw-r--r--WebKitTools/WebKitLauncher/webkit.icnsbin0 -> 56937 bytes
-rw-r--r--WebKitTools/WinLauncher/WinLauncher.cpp408
-rw-r--r--WebKitTools/WinLauncher/WinLauncher.h109
-rw-r--r--WebKitTools/WinLauncher/WinLauncher.icobin0 -> 23558 bytes
-rw-r--r--WebKitTools/WinLauncher/WinLauncher.rc136
-rw-r--r--WebKitTools/WinLauncher/WinLauncher.vcproj255
-rw-r--r--WebKitTools/WinLauncher/resource.h27
-rw-r--r--WebKitTools/WinLauncher/small.icobin0 -> 23558 bytes
-rw-r--r--WebKitTools/WinLauncher/stdafx.cpp33
-rw-r--r--WebKitTools/WinLauncher/stdafx.h69
-rw-r--r--WebKitTools/iExploder/CHANGELOG.txt328
-rw-r--r--WebKitTools/iExploder/LICENSE.txt20
-rw-r--r--WebKitTools/iExploder/README.txt149
-rw-r--r--WebKitTools/iExploder/htdocs/config.rb6
-rw-r--r--WebKitTools/iExploder/htdocs/cssproperties.in348
-rw-r--r--WebKitTools/iExploder/htdocs/cssvalues.in339
-rw-r--r--WebKitTools/iExploder/htdocs/htmlattrs.in259
-rw-r--r--WebKitTools/iExploder/htdocs/htmltags.in128
-rw-r--r--WebKitTools/iExploder/htdocs/htmlvalues.in35
-rwxr-xr-xWebKitTools/iExploder/htdocs/iexploder.cgi45
-rw-r--r--WebKitTools/iExploder/htdocs/iexploder.rb337
-rw-r--r--WebKitTools/iExploder/htdocs/index.html34
-rwxr-xr-xWebKitTools/iExploder/htdocs/webserver.rb75
-rwxr-xr-xWebKitTools/iExploder/tools/lasthit.rb53
-rwxr-xr-xWebKitTools/iExploder/tools/osx_last_crash.rb48
-rwxr-xr-xWebKitTools/iExploder/tools/showtest.rb43
-rw-r--r--WebKitTools/mangleme/LICENSE504
-rw-r--r--WebKitTools/mangleme/Makefile16
-rw-r--r--WebKitTools/mangleme/README20
-rw-r--r--WebKitTools/mangleme/mangle.cgi.c122
-rw-r--r--WebKitTools/mangleme/remangle.cgi.c125
-rw-r--r--WebKitTools/mangleme/tags.h76
-rwxr-xr-xWebKitTools/vcbin/cl.exebin0 -> 6656 bytes
-rwxr-xr-xWebKitTools/vcbin/midl.exebin0 -> 7168 bytes
-rw-r--r--WebKitTools/wx/browser/browser.bkl64
-rw-r--r--WebKitTools/wx/browser/browser.cpp62
-rwxr-xr-xWebKitTools/wx/build-wxwebkit377
-rwxr-xr-xWebKitTools/wx/install-unix-extras172
407 files changed, 48264 insertions, 0 deletions
diff --git a/WebKitTools/BuildSlaveSupport/build-launcher-app b/WebKitTools/BuildSlaveSupport/build-launcher-app
new file mode 100755
index 0000000..79f47bf
--- /dev/null
+++ b/WebKitTools/BuildSlaveSupport/build-launcher-app
@@ -0,0 +1,165 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+# Copyright (C) 2006 Mark Rowe <opendarwin.org@bdash.net.nz>. 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.
+
+# Creates the launcher WebKit.app with bundled frameworks.
+
+use strict;
+
+use FindBin;
+use lib "$FindBin::Bin/../Scripts";
+use Cwd 'realpath';
+use webkitdirs;
+use VCSUtils;
+
+my $tigerProductDir = realpath("$FindBin::Bin/../../WebKitBuildTiger");
+my $leopardProductDir = realpath("$FindBin::Bin/../../WebKitBuildLeopard");
+setBaseProductDir($tigerProductDir);
+
+my @xcodeBuildArguments = XcodeOptions();
+unshift @xcodeBuildArguments, "SYMROOT=$tigerProductDir";
+unshift @xcodeBuildArguments, "OBJROOT=$tigerProductDir";
+
+my $nightlyLauncherTemplatePath = "$FindBin::Bin/../WebKitLauncher";
+my $nightlyLauncherStagingPath = productDir() . "/WebKit.app";
+my $droseraProjectPath = "$FindBin::Bin/../Drosera/mac";
+my $droseraStagingPath = productDir() . "/DroseraLauncher.app";
+
+
+sub buildNightlyLauncher
+{
+ chdir($nightlyLauncherTemplatePath);
+ system("xcodebuild", "clean", "-alltargets", @xcodeBuildArguments, @ARGV) == 0 or die "Failed cleaning WebKitLauncher project";
+ system("xcodebuild", @xcodeBuildArguments, @ARGV) == 0 or die "Failed building WebKitLauncher project";
+ chdirWebKit();
+}
+
+sub currentRevision
+{
+ my $sourceDir = sourceDir();
+ if (isSVNDirectory($sourceDir)) {
+ return currentSVNRevision();
+ } elsif (isGitDirectory($sourceDir)) {
+ my $gitLog = `cd $sourceDir && LC_ALL=C git log --grep='git-svn-id: ' -n 1 | grep git-svn-id:`;
+ (my $revision) = ($gitLog =~ m/ +git-svn-id: .+@(\d+) /g);
+ return $revision;
+ }
+}
+
+sub currentBranch
+{
+ my $sourceDir = sourceDir();
+ my ($url, $branch);
+ if (isSVNDirectory($sourceDir)) {
+ my $svnInfo = `LC_ALL=C svn info $sourceDir | grep URL:`;
+ ($url) = ($svnInfo =~ m/URL: (.+)/g);
+ } elsif (isGitDirectory($sourceDir)) {
+ my $gitLog = `cd $sourceDir && LC_ALL=C git log --grep='git-svn-id: ' -n 1 | grep git-svn-id:`;
+ ($url) = ($gitLog =~ m/ +git-svn-id: (.+)@\d+ /g);
+ }
+ ($branch) = ($url =~ m/\/webkit\/(trunk|branches\/[^\/]+)/);
+ die "Unable to determine current SVN branch in $sourceDir" unless (defined $branch);
+ $branch =~ s/^branches\///;
+ return $branch;
+}
+
+sub copyNightlyLauncher
+{
+ my $revision = currentRevision();
+ my $branch = currentBranch();
+ my $configuration = configuration();
+
+ my $infoPlist = "$nightlyLauncherStagingPath/Contents/Info.plist";
+ my $versionFile = "$nightlyLauncherStagingPath/Contents/Resources/VERSION";
+ my $branchFile = "$nightlyLauncherStagingPath/Contents/Resources/BRANCH";
+ my $data;
+ open(IN, $infoPlist) or die "Couldn't open Info.plist in built application for reading";
+ {
+ undef $/;
+ $data = <IN>;
+ }
+ close(IN);
+ open(OUT, ">$infoPlist") or die "Couldn't open Info.plist in built application for writing";
+ $data =~ s/VERSION/$revision/g;
+ print OUT $data;
+ close(OUT);
+
+ open(OUT, ">$versionFile") or die "Couldn't open VERSION in built application for writing";
+ print OUT "$revision\n";
+ close(OUT);
+
+ open(OUT, ">$branchFile") or die "Couldn't open BRANCH in built application for writing";
+ print OUT "$branch\n";
+ close(OUT);
+
+ my @frameworks = ("JavaScriptCore", "JavaScriptGlue", "WebCore", "WebKit");
+ for my $framework (@frameworks) {
+ my $tigerFramework = "$tigerProductDir/$configuration/$framework.framework";
+ my $leopardFramework = "$leopardProductDir/$configuration/$framework.framework";
+ system("ditto", $tigerFramework, "$nightlyLauncherStagingPath/Contents/Frameworks/10.4/$framework.framework") == 0 or die "Failed copying $tigerFramework into $nightlyLauncherStagingPath";
+ system("ditto", $leopardFramework, "$nightlyLauncherStagingPath/Contents/Frameworks/10.5/$framework.framework") == 0 or die "Failed copying $leopardFramework into $nightlyLauncherStagingPath";
+ }
+}
+
+sub buildDroseraLauncher
+{
+ chdir($droseraProjectPath);
+ system("xcodebuild", "clean", "-alltargets", @xcodeBuildArguments, @ARGV) == 0 or die "Failed cleaning Drosera project";
+ # Build native platform only right now, as building universal with the 10.4u SDK cause Xcode to look for WebKit,
+ # WebCore & JavaScriptCore in the SDK under /Developer/SDKs/MacOSX10.4u.sdk/$(BUILT_PRODUCTS_DIR) where they do not exist
+ system("xcodebuild", "-alltargets", @xcodeBuildArguments, @ARGV) == 0 or die "Failed building Drosera project";
+ chdirWebKit();
+}
+
+sub setDroseraLauncherVersion
+{
+ my $revision = currentRevision();
+ my $infoPlist = "$droseraStagingPath/Contents/Info.plist";
+ my $data;
+ open(IN, $infoPlist) or die "Couldn't open Info.plist in built application for reading";
+ {
+ undef $/;
+ $data = <IN>;
+ }
+ close(IN);
+ open(OUT, ">$infoPlist") or die "Couldn't open Info.plist in built application for writing";
+ $data =~ s/VERSION/$revision/g;
+ print OUT $data;
+ close(OUT);
+}
+
+my $b = currentBranch();
+my $r = currentRevision();
+print "Branch: ", $b, "\n";
+print "Revision: ", $r, "\n";
+
+chdirWebKit();
+buildNightlyLauncher();
+copyNightlyLauncher();
+buildDroseraLauncher();
+setDroseraLauncherVersion();
diff --git a/WebKitTools/BuildSlaveSupport/build-launcher-dmg b/WebKitTools/BuildSlaveSupport/build-launcher-dmg
new file mode 100755
index 0000000..ff1a22d
--- /dev/null
+++ b/WebKitTools/BuildSlaveSupport/build-launcher-dmg
@@ -0,0 +1,136 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+# Copyright (C) 2006 Mark Rowe <opendarwin.org@bdash.net.nz>. 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.
+
+# Script used by build slaves to create a disk-image containing WebKit.app.
+
+use strict;
+
+use File::Basename;
+use Getopt::Long;
+use FindBin;
+use lib "$FindBin::Bin/../Scripts";
+use Cwd 'realpath';
+use webkitdirs;
+use VCSUtils;
+
+my $tigerProductDir = realpath("$FindBin::Bin/../../WebKitBuildTiger");
+my $leopardProductDir = realpath("$FindBin::Bin/../../WebKitBuildLeopard");
+setBaseProductDir($tigerProductDir);
+
+my $nightlyLauncherStagingPath = productDir() . "/WebKit.app";
+my $droseraStagingPath = productDir() . "/DroseraLauncher.app";
+my $nightlyLauncherDiskImagePath;
+
+my $nightlyRemoteHost = 'webkit-nightlies@live.nightly.webkit.org';
+my $nightlyRemotePath = "/home/webkit-nightlies";
+my $nightlyRemoteLatestPath = "$nightlyRemotePath/update-latest.sh";
+
+sub currentRevision
+{
+ my $sourceDir = sourceDir();
+ if (isSVNDirectory($sourceDir)) {
+ return currentSVNRevision();
+ } elsif (isGitDirectory($sourceDir)) {
+ my $gitLog = `cd $sourceDir && LC_ALL=C git log --grep='git-svn-id: ' -n 1 | grep git-svn-id:`;
+ (my $revision) = ($gitLog =~ m/ +git-svn-id: .+@(\d+) /g);
+ return $revision;
+ }
+}
+
+sub buildDiskImage
+{
+ my $revision = currentRevision();
+ my $productDir = productDir();
+ $nightlyLauncherDiskImagePath = productDir() . "/WebKit-SVN-r$revision.dmg";
+
+ print "Removing previous temp source directory (if any)...\n";
+ `rm -rf /tmp/WebKitNightly`;
+ die "Removing previous temp source directory failed" if $?;
+
+ print "Making a new temp source directory...\n";
+ `mkdir /tmp/WebKitNightly`;
+ die "Making a new temp source directory failed" if $?;
+
+ print "Copying WebKit.app to temp source directory...\n";
+ `cp -R \"$nightlyLauncherStagingPath\" /tmp/WebKitNightly/WebKit.app`;
+ die "Copying WebKit.app to temp source directory failed" if $?;
+
+ print "Copying Drosera.app to temp source directory...\n";
+ `cp -R \"$droseraStagingPath\" /tmp/WebKitNightly/Drosera.app`;
+ die "Copying Drosera.app to temp source directory failed" if $?;
+
+ print "Creating disk image...\n";
+ `hdiutil create \"$nightlyLauncherDiskImagePath\" -ov -srcfolder /tmp/WebKitNightly -fs HFS+ -volname \"WebKit\"`;
+ die "Creating disk image failed" if $?;
+
+ print "Removing temp source directory...\n";
+ `rm -rf /tmp/WebKitNightly`;
+ die "Removing temp source directory failed" if $?;
+
+ print "Compressing disk image...\n";
+ system("mv", "-f", $nightlyLauncherDiskImagePath, "$nightlyLauncherDiskImagePath.uncompressed.dmg") == 0 or die "Renaming disk image failed";
+ system("hdiutil", "convert", "-quiet", "$nightlyLauncherDiskImagePath.uncompressed.dmg", "-format", "UDBZ", "-imagekey", "zlib-level=9", "-o", "$nightlyLauncherDiskImagePath");
+ die "Compressing disk image failed" if $?;
+
+ unlink "$nightlyLauncherDiskImagePath.uncompressed.dmg";
+}
+
+sub uploadNightlyDiskImage
+{
+ my $buildTag = shift(@_);
+ my $nightlyRemoteDiskImagePath = "$nightlyRemotePath/builds/$buildTag/mac/" . basename($nightlyLauncherDiskImagePath);
+ my $revision = currentRevision();
+ system("rsync", "-vP", $nightlyLauncherDiskImagePath, "$nightlyRemoteHost:$nightlyRemoteDiskImagePath") == 0 or die "Failed uploading disk image";
+ system("ssh", $nightlyRemoteHost, $nightlyRemoteLatestPath, $buildTag, "mac", $nightlyRemoteDiskImagePath, $revision) == 0 or die "Failed linking disk image to latest";
+}
+
+sub uploadBuildSlaveDiskImage
+{
+ my $remoteDiskImagePath = shift(@_) . basename($nightlyLauncherDiskImagePath);
+ system("rsync", "-vP", $nightlyLauncherDiskImagePath, $remoteDiskImagePath) == 0 or die "Failed uploading disk image";
+}
+
+
+my $uploadTo;
+my $nightlyBuild = 0;
+my $buildTag = 'trunk';
+GetOptions('upload-to-host=s' => \$uploadTo,
+ 'upload-as-nightly!' => \$nightlyBuild,
+ 'tag=s' => \$buildTag);
+
+chdirWebKit();
+buildDiskImage($buildTag);
+
+if ($nightlyBuild) {
+ uploadNightlyDiskImage($buildTag);
+} elsif ($uploadTo) {
+ uploadBuildSlaveDiskImage($uploadTo);
+} else {
+ print "Disk image left at $nightlyLauncherDiskImagePath\n";
+}
diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/Makefile b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/Makefile
new file mode 100644
index 0000000..c3a935f
--- /dev/null
+++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/Makefile
@@ -0,0 +1,19 @@
+# -*- makefile -*-
+
+# This is a simple makefile which lives in a buildmaster/buildslave
+# directory (next to the buildbot.tac file). It allows you to start/stop the
+# master or slave by doing 'make start' or 'make stop'.
+
+# The 'reconfig' target will tell a buildmaster to reload its config file.
+
+start:
+ twistd --no_save -y buildbot.tac
+
+stop:
+ kill `cat twistd.pid`
+
+reconfig:
+ kill -HUP `cat twistd.pid`
+
+log:
+ tail -f twistd.log
diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/buildbot.css b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/buildbot.css
new file mode 100644
index 0000000..81de950
--- /dev/null
+++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/buildbot.css
@@ -0,0 +1,108 @@
+* {
+ font-family: Verdana, Cursor;
+ font-size: 10px;
+ font-weight: bold;
+}
+
+a:link,a:visited,a:active {
+ color: #444;
+}
+a:hover {
+ color: #FFFFFF;
+}
+
+table {
+ border-spacing: 1px 1px;
+}
+
+table td {
+ padding: 3px 0px 3px 0px;
+ text-align: center;
+}
+
+.Project {
+ width: 100px;
+}
+
+.LastBuild, .Activity {
+ width: 230px;
+ padding: 0 0 0 4px;
+}
+
+td.Time {
+ color: #000;
+ border-bottom: 1px solid #aaa;
+ background-color: #eee;
+}
+
+td.Activity, td.Change, td.Builder {
+ color: #333333;
+ background-color: #CCCCCC;
+}
+
+td.Change {
+ border-radius: 5px;
+ -webkit-border-radius: 5px;
+}
+td.Event {
+ color: #777;
+ background-color: #ddd;
+ border-radius: 5px;
+ -webkit-border-radius: 5px;
+}
+
+td.Activity {
+ border-top-left-radius: 10px;
+ -webkit-border-top-left-radius: 10px;
+ min-height: 20px;
+ padding: 8px 0 8px 0;
+}
+
+td.idle, td.waiting, td.offline, td.building {
+ border-top-left-radius: 0px;
+ -webkit-border-top-left-radius: 0px;
+}
+
+.LastBuild {
+ border-top-left-radius: 5px;
+ -webkit-border-top-left-radius: 5px;
+ border-top-right-radius: 5px;
+ -webkit-border-top-right-radius: 5px;
+}
+
+/* LastBuild, BuildStep states */
+.success {
+ color: #FFFFFF;
+ background-color: #8fdf5f;
+}
+
+.failure {
+ color: #FFFFFF;
+ background-color: #e98080;
+}
+
+.warnings {
+ color: #FFFFFF;
+ background-color: #ffc343;
+}
+
+.exception, td.offline {
+ color: #FFFFFF;
+ background-color: #e0b0ff;
+}
+
+.start,.running, td.building {
+ color: #666666;
+ background-color: #fffc6c;
+}
+
+.start {
+ border-bottom-left-radius: 10px;
+ -webkit-border-bottom-left-radius: 10px;
+ border-bottom-right-radius: 10px;
+ -webkit-border-bottom-right-radius: 10px;
+}
+
+td.Project a:hover, td.start a:hover {
+ color: #000;
+}
diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/buildbot.tac b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/buildbot.tac
new file mode 100644
index 0000000..f66e068
--- /dev/null
+++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/buildbot.tac
@@ -0,0 +1,10 @@
+
+from twisted.application import service
+from buildbot.master import BuildMaster
+
+basedir = r'/home/mrowe/sites/build.webkit.org/buildbot'
+configfile = r'master.cfg'
+
+application = service.Application('buildmaster')
+BuildMaster(basedir, configfile).setServiceParent(application)
+
diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg
new file mode 100644
index 0000000..ea7966a
--- /dev/null
+++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg
@@ -0,0 +1,22 @@
+# -*- python -*-
+
+import os
+from twisted.web import static
+static.File.contentTypes = static.loadMimeTypes(['/etc/mime.types', os.path.join(basedir, 'mime.types')])
+
+from buildbot.changes.pb import PBChangeSource
+import webkit
+reload(webkit)
+
+c = BuildmasterConfig = {}
+
+c['slaves'] = webkit.auth.getSlaveAuthenticationDetails()
+c['change_source'] = [PBChangeSource(prefix="trunk")]
+c['builders'] = webkit.builders.getBuilders()
+c['schedulers'] = webkit.schedulers.getSchedulers(c['builders'])
+c['status'] = webkit.status.getStatusListeners()
+
+c['slavePortnum'] = 9989
+c['projectName'] = "WebKit"
+c['projectURL'] = "http://webkit.org/"
+c['buildbotURL'] = "http://build.webkit.org/"
diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/__init__.py b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/__init__.py
new file mode 100644
index 0000000..f81fcae
--- /dev/null
+++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/__init__.py
@@ -0,0 +1,5 @@
+from webkit import auth, status, builders, schedulers
+reload(auth)
+reload(status)
+reload(builders)
+reload(schedulers)
diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/auth.py b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/auth.py
new file mode 100644
index 0000000..b182e16
--- /dev/null
+++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/auth.py
@@ -0,0 +1,9 @@
+from buildbot.buildslave import BuildSlave
+
+def getSlaveAuthenticationDetails():
+ def createBuildSlave((name, password)):
+ return BuildSlave(name, password, max_builds=1)
+ return map(createBuildSlave, _getSlaveAuthenticationDetails())
+
+def _getSlaveAuthenticationDetails():
+ return [("slave-name", "password")]
diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/basesteps.py b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/basesteps.py
new file mode 100644
index 0000000..8bba881
--- /dev/null
+++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/basesteps.py
@@ -0,0 +1,51 @@
+from buildbot.steps import shell, source
+import os
+
+
+def buildStepWithDefaultTimeout(klass, default_timeout=75*60):
+ class Step(klass):
+ timeout = default_timeout
+ def __init__(self, *args, **kwargs):
+ kwargs['timeout'] = self.timeout
+ klass.__init__(self, *args, **kwargs)
+
+ return Step
+
+
+Test = buildStepWithDefaultTimeout(shell.Test)
+Compile = buildStepWithDefaultTimeout(shell.Compile)
+ShellCommand = buildStepWithDefaultTimeout(shell.ShellCommand)
+SVN = buildStepWithDefaultTimeout(source.SVN)
+
+
+class UploadCommand:
+ def initializeForUpload(self):
+ try:
+ try:
+ umask = os.umask(0)
+ os.makedirs(self.getDestinationPath(), 042770)
+ except OSError, e:
+ if e.errno != 17:
+ raise
+ finally:
+ os.umask(umask)
+
+ def getDestinationPath(self):
+ return "/home/buildresults%s" % (self.getURLPath(), )
+
+ def getRemotePath(self):
+ return "buildresults@build.webkit.org:%s" % (self.getDestinationPath(), )
+
+ def getURLPath(self):
+ return '/results/%s/%s/' % (self.getBuild().builder.name, self.getBuild().getProperty("buildnumber"), )
+
+ def getBuild(self):
+ return self.build
+
+
+ def getText(self, cmd, results):
+ return self.getText2(cmd, results)
+
+ def getText2(self, cmd, results):
+ return ['<a href="%s">%s</a>' % (self.getURLPath(), self.name)]
+
diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/builders.py b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/builders.py
new file mode 100644
index 0000000..b4e087e
--- /dev/null
+++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/builders.py
@@ -0,0 +1,35 @@
+from webkit.factories import *
+from buildbot import locks
+
+# There are four build slaves that take care of the majority of builds, with two other specialist slaves at Apple
+# Slave 1 isn older G4 PowerMac dedicated to the PLT builds, as it needs extra configuration
+# Slave 2 is a Windows PC dedicated to the Windows builds
+# Slaves 3 and 4 are older G4 PowerMacs with relatively low amounts of RAM which leads to insanely slow leaks tests
+# Slaves 4 and 5 are newer G5 PowerMacs with ATI graphics cards that lead to kernel panics during pixel tests
+
+nonATIPowerPCBuilders = ['apple-slave-%d' % i for i in (3, 4)]
+ATIPowerPCBuilders = ['apple-slave-%d' % i for i in (1, 5, 6)]
+allPowerPCBuilders = nonATIPowerPCBuilders + ATIPowerPCBuilders
+allIntelBuilders = ['bdash-slave-1', 'bdash-slave-2']
+
+_builders = [('post-commit-powerpc-mac-os-x', StandardBuildFactory, allPowerPCBuilders),
+ ('post-commit-intel-mac-os-x', StandardBuildFactory, allIntelBuilders),
+ ('post-commit-leaks-powerpc-mac-os-x', LeakBuildFactory, allPowerPCBuilders),
+ ('post-commit-leaks-intel-mac-os-x', LeakBuildFactory, allIntelBuilders),
+# ('page-layout-test-mac-os-x', PageLoadTestBuildFactory, ['apple-slave-1']),
+# ('post-commit-pixel-powerpc-mac-os-x', PixelTestBuildFactory, nonATIPowerPCBuilders),
+ ('post-commit-win32', Win32BuildFactory, ['apple-slave-2']),
+ ('post-commit-linux-qt', StandardBuildFactory, ['webtroll-slave-1']),
+ ('post-commit-linux-gtk', GtkBuildFactory, ['zecke-slave-1']),
+ ('periodic-powerpc-mac-os-x-no-svg', NoSVGBuildFactory, allPowerPCBuilders),
+ ('periodic-intel-mac-os-x-coverage', CoverageDataBuildFactory, allIntelBuilders),
+ ]
+
+def getBuilders():
+ result = []
+ for name, factory, slaves in _builders:
+ result.append({'name': name,
+ 'slavenames': slaves,
+ 'builddir': name,
+ 'factory': factory()})
+ return result
diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/factories.py b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/factories.py
new file mode 100644
index 0000000..781375f
--- /dev/null
+++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/factories.py
@@ -0,0 +1,70 @@
+from webkit.steps import *
+from buildbot.process import factory
+
+s = factory.s
+
+class BuildFactory(factory.BuildFactory):
+ useProgress = False
+ def __init__(self):
+ factory.BuildFactory.__init__(self, [s(CheckOutSource)])
+
+class StandardBuildFactory(BuildFactory):
+ def __init__(self):
+ BuildFactory.__init__(self)
+ self.steps.append(s(SetConfiguration, configuration="release"))
+ self.steps.append(s(self.getCompileStep(), configuration="release"))
+ self.steps.append(s(self.getJavaScriptCoreTestStep()))
+ self.steps.append(s(LayoutTest))
+ self.steps.append(s(UploadLayoutResults))
+# self.steps.append(s(UploadDiskImage))
+
+ def getCompileStep(self):
+ return CompileWebKit
+
+ def getJavaScriptCoreTestStep(self):
+ return JavaScriptCoreTest
+
+
+class NoSVGBuildFactory(StandardBuildFactory):
+ def getCompileStep(self):
+ return CompileWebKitNoSVG
+
+
+class PixelTestBuildFactory(BuildFactory):
+ def __init__(self):
+ BuildFactory.__init__(self)
+ self.steps.append(s(SetConfiguration, configuration="release"))
+ self.steps.append(s(CompileWebKit, configuration="release"))
+ self.steps.append(s(PixelLayoutTest))
+ self.steps.append(s(UploadLayoutResults))
+
+class LeakBuildFactory(BuildFactory):
+ def __init__(self):
+ BuildFactory.__init__(self)
+ self.steps.append(s(SetConfiguration, configuration="debug"))
+ self.steps.append(s(CompileWebKit, configuration="debug"))
+ self.steps.append(s(JavaScriptCoreTest))
+ self.steps.append(s(LeakTest))
+ self.steps.append(s(UploadLayoutResults))
+# self.steps.append(s(UploadDiskImage))
+
+class PageLoadTestBuildFactory(BuildFactory):
+ def __init__(self):
+ BuildFactory.__init__(self)
+ self.steps.append(s(CompileWebKit, configuration="release"))
+ self.steps.append(s(PageLoadTest))
+
+Win32BuildFactory = StandardBuildFactory
+
+class GtkBuildFactory(StandardBuildFactory):
+ def getCompileStep(self):
+ return CompileWebKitGtk
+
+ def getJavaScriptCoreTestStep(self):
+ return JavaScriptCoreTestGtk
+
+class CoverageDataBuildFactory(BuildFactory):
+ def __init__(self):
+ BuildFactory.__init__(self)
+ self.steps.append(s(GenerateCoverageData))
+ self.steps.append(s(UploadCoverageData))
diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/schedulers.py b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/schedulers.py
new file mode 100644
index 0000000..11f9d41
--- /dev/null
+++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/schedulers.py
@@ -0,0 +1,15 @@
+from buildbot.scheduler import Scheduler, Periodic
+
+def getSchedulers(builders):
+ builder_names = map(lambda builder: builder['name'], builders)
+ post_commit_builders = [name for name in builder_names if name.startswith('post-commit-')] + ['page-layout-test-mac-os-x']
+ post_commit_builders = [name for name in post_commit_builders if name in builder_names]
+ post_commit_builders.sort()
+
+ periodic_builders = [b['name'] for b in builders if b['name'].startswith('periodic-')]
+ periodic_builders.sort()
+
+ post_commit = Scheduler(name="post-commit", branch=None, treeStableTimer=90, builderNames=post_commit_builders)
+ periodic = Periodic("periodic", periodic_builders, 6 * 60 * 60)
+
+ return [post_commit, periodic]
diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/status.py b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/status.py
new file mode 100644
index 0000000..ad5519e
--- /dev/null
+++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/status.py
@@ -0,0 +1,19 @@
+from buildbot.status import html, mail, words
+
+web = html.WebStatus(http_port=8010)
+
+allBuildsEmail = mail.MailNotifier(fromaddr="buildbot@webkit.org",
+ extraRecipients=["mark+webkit-builds@bdash.net.nz"],
+ sendToInterestedUsers=False)
+breakageEmail = mail.MailNotifier(fromaddr="buildbot@webkit.org",
+ lookup=mail.Domain("webkit.org"),
+ mode="failing")
+
+IRC = words.IRC(host="irc.freenode.net",
+ nick="webkit-build",
+ channels=["#webkit-build"],
+# announceAllBuilds=True
+ )
+
+def getStatusListeners():
+ return [web, allBuildsEmail, breakageEmail, IRC]
diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/steps.py b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/steps.py
new file mode 100644
index 0000000..c1933a3
--- /dev/null
+++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/steps.py
@@ -0,0 +1,220 @@
+from webkit.basesteps import ShellCommand, SVN, Test, Compile, UploadCommand
+from buildbot.status.builder import SUCCESS, FAILURE, WARNINGS
+
+class CheckOutSource(SVN):
+ svnurl = "http://svn.webkit.org/repository/webkit/trunk"
+ mode = "update"
+ def __init__(self, *args, **kwargs):
+ SVN.__init__(self, svnurl=self.svnurl, mode=self.mode, *args, **kwargs)
+
+class SetConfiguration(ShellCommand):
+ command = ["./WebKitTools/Scripts/set-webkit-configuration"]
+
+ def __init__(self, *args, **kwargs):
+ configuration = kwargs.pop('configuration')
+ self.command = self.command + ['--' + configuration]
+ self.name = "set-configuration-%s" % (configuration, )
+ self.description = ["set configuration %s" % (configuration, )]
+ self.descriptionDone = ["set configuration %s" % (configuration, )]
+ ShellCommand.__init__(self, *args, **kwargs)
+
+
+class LayoutTest(Test):
+ name = "layout-test"
+ description = ["layout-tests running"]
+ descriptionDone = ["layout-tests"]
+ command = ["./WebKitTools/Scripts/run-webkit-tests", "--no-launch-safari", "--no-new-test-results", "--results-directory", "layout-test-results"]
+
+ def commandComplete(self, cmd):
+ Test.commandComplete(self, cmd)
+
+ logText = cmd.logs['stdio'].getText()
+ incorrectLayoutLines = [line for line in logText.splitlines() if line.find('had incorrect layout') >= 0 or (line.find('test case') >= 0 and line.find(' crashed') >= 0)]
+ if incorrectLayoutLines:
+ self.incorrectLayoutLines = incorrectLayoutLines
+ else:
+ self.incorrectLayoutLines = None
+
+ def getText(self, cmd, results):
+ return self.getText2(cmd, results)
+
+ def getText2(self, cmd, results):
+ if results != SUCCESS and self.incorrectLayoutLines:
+ return self.incorrectLayoutLines
+
+ return [self.name]
+
+
+class JavaScriptCoreTest(Test):
+ name = "jscore-test"
+ description = ["jscore-tests running"]
+ descriptionDone = ["jscore-tests"]
+ command = ["./WebKitTools/Scripts/run-javascriptcore-tests"]
+ logfiles = {'results': 'JavaScriptCore/tests/mozilla/actual.html'}
+
+ def commandComplete(self, cmd):
+ Test.commandComplete(self, cmd)
+
+ logText = cmd.logs['stdio'].getText()
+ statusLines = [line for line in logText.splitlines() if line.find('regression') >= 0 and line.find(' found.') >= 0]
+ if statusLines and statusLines[0].split()[0] != '0':
+ self.regressionLine = statusLines[0]
+ else:
+ self.regressionLine = None
+
+ def evaluateCommand(self, cmd):
+ if cmd.rc != 0:
+ return FAILURE
+
+ if self.regressionLine:
+ return FAILURE
+
+ return SUCCESS
+
+ def getText(self, cmd, results):
+ return self.getText2(cmd, results)
+
+ def getText2(self, cmd, results):
+ if results != SUCCESS and self.regressionLine:
+ return [self.name, self.regressionLine]
+
+ return [self.name]
+
+class PixelLayoutTest(LayoutTest):
+ name = "pixel-layout-test"
+ description = ["pixel-layout-tests running"]
+ descriptionDone = ["pixel-layout-tests"]
+ command = LayoutTest.command + ["--pixel"]
+
+
+class LeakTest(Test):
+ name = "leak-test"
+ description = ["leak-tests running"]
+ descriptionDone = ["leak-tests"]
+ command = ["./WebKitTools/Scripts/run-webkit-tests", "--no-launch-safari", "--leaks", "--results-directory", "layout-test-results"]
+
+ def commandComplete(self, cmd):
+ Test.commandComplete(self, cmd)
+
+ logText = cmd.logs['stdio'].getText()
+ lines = logText.splitlines()
+ self.totalLeakLines = [line for line in lines if line.find('total leaks found!') >= 0]
+ self.totalLeakLines += [line for line in lines if line.find('LEAK: ') >= 0]
+ self.totalLeakLines = [' '.join(x.split()[1:]) for x in self.totalLeakLines]
+ self.totalLeakLines += [line for line in lines if line.find('test case') >= 0 and line.find('crashed') >= 0]
+
+
+ def evaluateCommand(self, cmd):
+ if cmd.rc != 0:
+ return FAILURE
+
+ if self.totalLeakLines:
+ return FAILURE
+
+ return SUCCESS
+
+ def getText(self, cmd, results):
+ return self.getText2(cmd, results)
+
+ def getText2(self, cmd, results):
+ if results != SUCCESS and self.totalLeakLines:
+ return self.totalLeakLines
+ return [self.name]
+
+
+class UploadLayoutResults(UploadCommand, ShellCommand):
+ name = "upload-results"
+ description = ["uploading results"]
+ descriptionDone = ["uploaded-results"]
+ command = "echo Disabled for now"
+
+ def __init__(self, *args, **kwargs):
+ ShellCommand.__init__(self, *args, **kwargs)
+
+ def setBuild(self, build):
+ ShellCommand.setBuild(self, build)
+ self.initializeForUpload()
+
+ self.command = '''\
+ if [[ -d layout-test-results ]]; then \
+ find layout-test-results -type d -print0 | xargs -0 chmod ug+rx; \
+ find layout-test-results -type f -print0 | xargs -0 chmod ug+r; \
+ rsync -rlvzP --rsync-path="/home/buildresults/bin/rsync" layout-test-results/ %s && rm -rf layout-test-results; \
+ fi; \
+ CRASH_LOG=~/Library/Logs/CrashReporter/DumpRenderTree*.crash*; \
+ if [[ -f $(ls -1 $CRASH_LOG | head -n 1 ) ]]; then \
+ chmod ug+r $CRASH_LOG; \
+ rsync -rlvzP --rsync-path="/home/buildresults/bin/rsync" $CRASH_LOG %s && rm -rf $CRASH_LOG; \
+ fi;''' % (self.getRemotePath(), self.getRemotePath())
+
+ self.addFactoryArguments(command=self.command)
+
+
+class CompileWebKit(Compile):
+ command = ["./WebKitTools/Scripts/build-webkit", "--no-color"]
+ env = {'WEBKITSUPPORTLIBRARIESZIPDIR': 'C:\\cygwin\\home\\buildbot'}
+ def __init__(self, *args, **kwargs):
+ configuration = kwargs.pop('configuration')
+
+ self.name = "compile-" + configuration
+ self.description = ["compiling " + configuration]
+ self.descriptionDone = ["compiled " + configuration]
+
+ Compile.__init__(self, *args, **kwargs)
+
+
+class CompileWebKitNoSVG(CompileWebKit):
+ command = 'rm -rf WebKitBuild && ./WebKitTools/Scripts/build-webkit --no-svg --no-color'
+
+class CompileWebKitGtk(CompileWebKit):
+ command = CompileWebKit.command + ['--gtk']
+
+class JavaScriptCoreTestGtk(JavaScriptCoreTest):
+ command = JavaScriptCoreTest.command + ['--gtk']
+
+class InstallWin32Dependencies(ShellCommand):
+ description = ["installing Windows dependencies"]
+ descriptionDone = ["installed Windows dependencies"]
+ command = ["WebKitTools/Scripts/update-webkit-auxiliary-libs"]
+
+
+# class UploadDiskImage(UploadCommand, ShellCommand):
+# description = ["uploading disk image"]
+# descriptionDone = ["uploaded disk image"]
+# name = "upload-disk-image"
+
+# def __init__(self, *args, **kwargs):
+# UploadCommand.__init__(self, *args, **kwargs)
+# self.command = 'umask 002 && ./WebKitTools/BuildSlaveSupport/build-launcher-app && ./WebKitTools/BuildSlaveSupport/build-launcher-dmg --upload-to-host %s' % (self.getRemotePath(), )
+# ShellCommand.__init__(self, *args, **kwargs)
+
+class GenerateCoverageData(Compile):
+ command = ["./WebKitTools/Scripts/generate-coverage-data"]
+ description = ["generating coverage data"]
+ descriptionDone = ["generated coverage data"]
+
+
+class UploadCoverageData(UploadCommand, ShellCommand):
+ name = "upload-coverage-data"
+ description = ["uploading coverage data"]
+ descriptionDone = ["uploaded-coverage-data"]
+ command = "echo Disabled for now"
+
+ def __init__(self, *args, **kwargs):
+ ShellCommand.__init__(self, *args, **kwargs)
+
+ def setBuild(self, build):
+ ShellCommand.setBuild(self, build)
+ self.initializeForUpload()
+
+ self.command = '''\
+ if [[ -d WebKitBuild/Coverage/html ]]; then \
+ find WebKitBuild/Coverage/html -type d -print0 | xargs -0 chmod ug+rx; \
+ find WebKitBuild/Coverage/html -type f -print0 | xargs -0 chmod ug+r; \
+ rsync -rlvzP --rsync-path="/home/buildresults/bin/rsync" WebKitBuild/Coverage/html/ %s && rm -rf WebKitBuild/Coverage/html; \
+ fi;''' % (self.getRemotePath(), )
+
+ self.addFactoryArguments(command=self.command)
+
+ def getURLPath(self):
+ return "/results/code-coverage/"
diff --git a/WebKitTools/BuildSlaveSupport/run-performance-tests b/WebKitTools/BuildSlaveSupport/run-performance-tests
new file mode 100755
index 0000000..5d6ea44
--- /dev/null
+++ b/WebKitTools/BuildSlaveSupport/run-performance-tests
@@ -0,0 +1,80 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2006 Apple Computer, 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.
+
+# Script used by WebKit build slave to kick off performance tests.
+
+use strict;
+
+use FindBin;
+use lib "$FindBin::Bin/../Scripts";
+use webkitdirs;
+
+use Getopt::Long;
+use IO::Socket;
+my $shouldPrebuild = 1;
+
+my $perfMaster = "webkit-build-1.local";
+my $perfSlave = "webkit-build-2.local";
+my $slaveUser = "buildbot";
+my $reportPort = 54481; # Something that looks sorta like SAFARI
+my $slaveDirectory = "/ToTest";
+
+my $buildDirectory = determineConfigurationProductDir();
+
+my $userAndHost = $slaveUser . "@" . $perfSlave;
+my $resultsUploadDestination;
+
+GetOptions('upload-results=s' => \$resultsUploadDestination);
+
+print "Copying built frameworks to PLT slave...\n";
+my @frameworks = ("$buildDirectory/JavaScriptCore.framework", "$buildDirectory/WebCore.framework", "$buildDirectory/WebKit.framework");
+die "Failed to copy to slave\n" unless (system("rsync", "-avz", @frameworks, "$userAndHost:$slaveDirectory") == 0);
+
+print "Opening reponse port for PLT slave...\n";
+my $sock = new IO::Socket::INET(LocalHost => $perfMaster,
+ LocalPort => $reportPort,
+ Proto => 'tcp',
+ Listen => 1,
+ Reuse => 1);
+die "Could not create socket for port $reportPort: $!\n" unless $sock;
+
+print "Starting performance tests on PLT slave...\n";
+die "Failed to start slave!\n" unless (system("ssh", $userAndHost, "autovicki", $slaveDirectory, "--safari", "$slaveDirectory/Safari.app", "--count", 5, "--clean-exit", "--webkit-revision", currentSVNRevision(), "--show-results", "send-completed-results.command") == 0);
+
+print "Waiting for PLT slave to respond...\n";
+my $new_sock = $sock->accept();
+while(<$new_sock>) {
+ print $_;
+}
+close($sock);
+
+if ($resultsUploadDestination) {
+ print "Uploading results to $resultsUploadDestination\n";
+ die "Failed to upload xml results file." unless (system("scp", "$userAndHost:/Results/PerformanceReportSummary.xml", $resultsUploadDestination) == 0);
+ die "Failed to upload svg results file." unless (system("scp", "$userAndHost:/Results/PerformanceGraph.svg", $resultsUploadDestination) == 0);
+}
diff --git a/WebKitTools/CLWrapper/CLWrapper.cpp b/WebKitTools/CLWrapper/CLWrapper.cpp
new file mode 100644
index 0000000..7d41f2b
--- /dev/null
+++ b/WebKitTools/CLWrapper/CLWrapper.cpp
@@ -0,0 +1,52 @@
+// CLWrapper.cpp : Calls the perl script parallelcl to perform parallel compilation
+
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+#include <process.h>
+#include <stdio.h>
+#include <string>
+#include <windows.h>
+
+using namespace std;
+
+int wmain(int argc, wchar_t* argv[])
+{
+ const int numArgs = 3;
+
+#ifndef NDEBUG
+ fwprintf(stderr, L"######### im in ur IDE, compiling ur c0des ########\n");
+#endif
+
+ wstring** args = new wstring*[numArgs];
+
+ args[0] = new wstring(L"sh");
+ args[1] = new wstring(L"-c");
+
+ args[2] = new wstring(L"\"parallelcl");
+ for (int i = 1; i < argc; ++i) {
+ args[2]->append(L" '");
+ args[2]->append(argv[i]);
+ if (i < argc - 1)
+ args[2]->append(L"' ");
+ else
+ args[2]->append(L"'");
+ }
+ args[2]->append(L"\"");
+
+ for (unsigned i = 0; i < args[2]->length(); i++) {
+ if (args[2]->at(i) == '\\')
+ args[2]->at(i) = '/';
+ }
+
+ wchar_t** newArgv = new wchar_t*[numArgs + 1];
+ for (int i = 0; i < numArgs; i++)
+ newArgv[i] = (wchar_t*)args[i]->c_str();
+
+ newArgv[numArgs] = 0;
+
+#ifndef NDEBUG
+ fwprintf(stderr, L"exec(\"%s\", \"%s\", \"%s\", \"%s\")\n", L"sh", newArgv[0], newArgv[1], newArgv[2]);
+#endif
+
+ return _wspawnvp(_P_WAIT, L"sh", newArgv);
+}
+
diff --git a/WebKitTools/CLWrapper/CLWrapper.sln b/WebKitTools/CLWrapper/CLWrapper.sln
new file mode 100644
index 0000000..add0423
--- /dev/null
+++ b/WebKitTools/CLWrapper/CLWrapper.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CLWrapper", "CLWrapper.vcproj", "{230BF635-9BD8-434A-8857-0B096EBC7233}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {230BF635-9BD8-434A-8857-0B096EBC7233}.Debug|Win32.ActiveCfg = Debug|Win32
+ {230BF635-9BD8-434A-8857-0B096EBC7233}.Debug|Win32.Build.0 = Debug|Win32
+ {230BF635-9BD8-434A-8857-0B096EBC7233}.Release|Win32.ActiveCfg = Release|Win32
+ {230BF635-9BD8-434A-8857-0B096EBC7233}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/WebKitTools/CLWrapper/CLWrapper.vcproj b/WebKitTools/CLWrapper/CLWrapper.vcproj
new file mode 100644
index 0000000..668a874
--- /dev/null
+++ b/WebKitTools/CLWrapper/CLWrapper.vcproj
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="CLWrapper"
+ ProjectGUID="{230BF635-9BD8-434A-8857-0B096EBC7233}"
+ RootNamespace="CLWrapper"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="..\vcbin"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\cl.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="..\vcbin"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\cl.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\CLWrapper.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/WebKitTools/CodeCoverage/README b/WebKitTools/CodeCoverage/README
new file mode 100644
index 0000000..5315f4a
--- /dev/null
+++ b/WebKitTools/CodeCoverage/README
@@ -0,0 +1,22 @@
+Generate coverage on Mac
+
+call WebKitTools/Script/generate-coverage-data
+
+or by hand
+
+
+# delete
+find . -name '*.gcda' -delete
+
+# build, -framework CoreFoundation might suffice as well
+WebKitTools/Scripts/build-webkit GCC_GENERATE_TEST_COVERAGE_FILES=YES GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES EXTRA_LINK=" -ftest-coverage -fprofile-arcs" OTHER_CFLAGS=" -MD " OTHER_LDFLAGS=" -ftest-coverage -fprofile-arcs -framework AppKit"
+WebKitTools/Scripts/run-webkit-tests
+WebKitTools/Scripts/run-javascriptcore-tests GCC_GENERATE_TEST_COVERAGE_FILES=YES GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES EXTRA_LINK=" -ftest-coverage -fprofile-arcs" OTHER_CFLAGS=" -MD " OTHER_LDFLAGS=" -ftest-coverage -fprofile-arcs -framework AppKit"
+
+
+# Collect files
+WebKitTools/CodeCoverage/run-generate-coverage-data <RUN_ID> ../coverage-results/
+
+
+# Generate graph
+WebKitTools/CodeCoverage/regenerate-coverage-display ../coverage-results/ ../coverage-results/html
diff --git a/WebKitTools/CodeCoverage/amber.png b/WebKitTools/CodeCoverage/amber.png
new file mode 100644
index 0000000..ee5d920
--- /dev/null
+++ b/WebKitTools/CodeCoverage/amber.png
Binary files differ
diff --git a/WebKitTools/CodeCoverage/cov.py b/WebKitTools/CodeCoverage/cov.py
new file mode 100644
index 0000000..443e601
--- /dev/null
+++ b/WebKitTools/CodeCoverage/cov.py
@@ -0,0 +1,201 @@
+# Copyright (C) 2004, 2005, 2006 Nathaniel Smith
+# Copyright (C) 2006, 2007 Holger Hans Peter Freyther
+#
+# 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 csv
+import time
+import os.path
+import shutil
+
+def analyze_coverage(possible_gcov_files, source_files, runid, data_dir, base):
+
+ if not os.path.exists(data_dir):
+ os.makedirs(data_dir)
+
+ output = open(os.path.join(data_dir, runid + ".csv"), "w")
+ w = csv.writer(output)
+ # First row: id and time
+ w.writerow([runid, time.time()])
+
+ results = scan_gcov_files(possible_gcov_files, source_files)
+ annotated_dir = os.path.join(data_dir, runid + ".annotated")
+ if os.path.exists(annotated_dir):
+ shutil.rmtree(annotated_dir)
+
+ keys = results.keys()
+ keys.sort()
+ for path in keys:
+ (total, covered, annotated_data) = results[path]
+ path = path[path.find(base)+len(base):]
+ # Rest of the rows: filename, total_lines, covered_lines
+ w.writerow([path, total, covered])
+
+ if path[:1] == "/":
+ path = path[1:]
+ annotated_path = os.path.join(annotated_dir, path)
+ try:
+ os.makedirs(os.path.dirname(annotated_path))
+ except OSError:
+ pass
+ a = open(annotated_path, "w")
+ a.write(annotated_data)
+ a.close()
+
+
+# zecke's rewrite
+STATE_NOT_CODE = -1
+STATE_NOT_SEEN = -2
+STATE_TEST_CODE = -3
+
+def find_gcov(f, possible_gcovs):
+ """
+ Find .gcov files that could be of interest for us
+ """
+ try:
+ return possible_gcovs[f]
+ except:
+ return []
+
+
+def parse_source_file(file):
+ """
+ Parse one source file and return a list of lines
+ """
+ f_source_list = []
+ init_state = STATE_NOT_SEEN
+ in_test_code = False
+ nesting = 0
+
+ for line in open(file, "r"):
+ code = line.split(":", 2)[-1]
+ if not in_test_code and code.startswith("#ifdef BUILD_UNIT_TESTS"):
+ in_test_code = 1
+ if in_test_code and code.startswith("#if"):
+ nesting += 1
+ if in_test_code and code.startswith("#endif"):
+ nesting -= 1
+ if not nesting:
+ in_test_code = True
+ if in_test_code:
+ init_state = STATE_TEST_CODE
+ else:
+ init_state = STATE_NOT_SEEN
+ f_source_list.append([init_state, line.split(":", 1)[1]])
+
+ return f_source_list
+
+# Runner-up, 3rd annual "write Python that looks like Perl" competition,
+# Well, not really. It doesn't even use regexps.
+# He is right so I'm cleaning it up (zecke)
+def scan_gcov_files(possible_gcov_files, source_files):
+ """Takes a list of gcov filenames and a list of source filenames.
+
+ The gcov files should have names of the form foo.o##foo.cc.gcov, as
+ created by 'gcov -l'.
+
+ Returns a dict mapping source filenames to tuples
+ (total_lines, tested_lines, gcov_annotated_source)
+ which are a number, a number, and a very long string, respectively.
+
+ The fun bit is that we merge .gcov output generated by different object
+ files; this way we can provide accurate information for header files and
+ for monotone's current unit test system."""
+ results = {}
+ for f in source_files:
+ possible_gcovs = find_gcov(f, possible_gcov_files)
+ base_name = os.path.splitext(os.path.basename(f))[0]
+ if len(possible_gcovs) == 0:
+ print "No gcov files found for: '%s' but it was compiled" % f
+ continue
+
+ (garbage,extension) = os.path.splitext(f)
+ if extension in [".cc", ".c", ".moc", ".cpp", ".cxx", ".m", ".mm"]:
+ lines = open(f, "r").readlines()
+ results[f] = (len(lines), 0, "".join(lines))
+ continue
+ elif len(possible_gcovs) > 1:
+ print "More than one gcov file for %s %d" % (f,len(possible_gcovs))
+ base_gcov_lines = parse_source_file(possible_gcovs[0])
+
+ # Now we will try hard to merge the results with others
+ # Our requirement is that we have the same amount of lines as
+ # as the original file
+ for cov_file in possible_gcovs:
+ lines = open(cov_file, "r").readlines()
+
+ # e.g. with phonon we have visualisation.h and we can not know
+ # which header file (foldername) it is refering to. This is a gcov
+ # limitation and i have no workaround yet. We just hope we will pick
+ # the right header file...
+ if len(lines) != len(base_gcov_lines):
+ print "Error Base: %s and Target: %s have different amount of lines" % (possible_gcovs[0],cov_file)
+ continue
+
+ # now do the merging of the file. If it has the same basename
+ # and the same number of lines things might work out
+ # In the future take a look at the header of the file
+ i = 0
+ for line in lines:
+ accumulator = base_gcov_lines[i]
+ if accumulator[0] != STATE_TEST_CODE:
+ info = line.split(":", 1)[0]
+ if info.endswith("-"):
+ if accumulator[0] == STATE_NOT_SEEN:
+ accumulator[0] = STATE_NOT_CODE
+ else:
+ if info.endswith("#"):
+ num = 0
+ else:
+ num = int(info)
+ if accumulator[0] in (STATE_NOT_SEEN, STATE_NOT_CODE):
+ accumulator[0] = 0
+ accumulator[0] += num
+ i += 1
+
+ # post processing of ths file
+ (total_lines, total_covered) = (0, 0)
+ annotated_lines = []
+ for state, line in base_gcov_lines:
+ if state == STATE_NOT_SEEN:
+ desc = "?????"
+ elif state == STATE_TEST_CODE:
+ desc = "+"
+ elif state == STATE_NOT_CODE:
+ desc = "-"
+ elif state == 0:
+ desc = "#####"
+ total_lines += 1
+ else:
+ desc = str(state)
+ total_lines += 1
+ total_covered += 1
+ annotated_lines.append(":".join([desc.rjust(9), line]))
+ results[f] = (total_lines, total_covered, "".join(annotated_lines))
+ return results
+
+
+
+ return results
diff --git a/WebKitTools/CodeCoverage/emerald.png b/WebKitTools/CodeCoverage/emerald.png
new file mode 100644
index 0000000..0e60294
--- /dev/null
+++ b/WebKitTools/CodeCoverage/emerald.png
Binary files differ
diff --git a/WebKitTools/CodeCoverage/gcov.css b/WebKitTools/CodeCoverage/gcov.css
new file mode 100644
index 0000000..71ca080
--- /dev/null
+++ b/WebKitTools/CodeCoverage/gcov.css
@@ -0,0 +1,116 @@
+body {
+ color: black; background-color: white;
+ font-family: Helvetica,Arial,sans-serif;
+ margin: 0; padding: 0em;
+ text-align: center;
+}
+
+.title {
+ text-align:center;
+ font-weight:bold;
+ font-style:italic;
+ font-size:1.8em;
+ padding:10px;
+}
+
+.ruler {
+ height:3px;
+ background-color:#638AD6;
+ margin-left:10px;
+ margin-right:10px;
+}
+
+.headerItem {
+ text-align:right;
+ font-weight:bold;
+}
+
+.headerValue {
+ text-align:left;
+ font-weight:bold;
+ color:#638AD6;
+}
+
+.tableHead {
+ text-align:center;
+ font-weight:bold;
+ background-color:#638AD6;
+ color:white;
+
+}
+
+.coverFile {
+ font-family: Courier;
+ background-color:#DEE7FF;
+ padding:3px;
+ width:70%;
+}
+
+.coverBar {
+ background-color:#DEE7FF;
+ padding:3px;
+ width:5%;
+}
+
+.coverBarOutline {
+}
+
+.coverPerHi {
+ font-family: Times;
+ text-align:center;
+ font-weight:bold;
+ background-color:lightgreen;
+ padding:3px;
+ width:5%;
+}
+
+.coverNumHi {
+ font-family: Times;
+ text-align:right;
+ background-color:lightgreen;
+ padding:3px;
+ width:25%;
+}
+
+.coverPerMed {
+ font-family: Times;
+ text-align:center;
+ font-weight:bold;
+ background-color:yellow;
+ padding:3px;
+}
+
+.coverNumMed {
+ font-family: Times;
+ text-align:right;
+ background-color:yellow;
+ padding:3px;
+}
+
+.coverPerLo {
+ font-family: Times;
+ text-align:center;
+ font-weight:bold;
+ background-color:red;
+ padding:3px;
+}
+
+.coverNumLo {
+ font-family: Times;
+ text-align:right;
+ background-color:red;
+ padding:3px;
+}
+
+.lineNum {
+ background-color:#EFE384;
+}
+
+.lineCov {
+ background-color:#CED7FF;
+}
+
+.lineNoCov {
+ background-color:#FF6131;
+}
+
diff --git a/WebKitTools/CodeCoverage/glass.png b/WebKitTools/CodeCoverage/glass.png
new file mode 100644
index 0000000..a4ba373
--- /dev/null
+++ b/WebKitTools/CodeCoverage/glass.png
Binary files differ
diff --git a/WebKitTools/CodeCoverage/regenerate-coverage-display b/WebKitTools/CodeCoverage/regenerate-coverage-display
new file mode 100755
index 0000000..9139c9a
--- /dev/null
+++ b/WebKitTools/CodeCoverage/regenerate-coverage-display
@@ -0,0 +1,408 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2004, 2005, 2006 Nathaniel Smith
+# Copyright (C) 2007 Holger Hans Peter Freyther
+#
+# 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.
+
+#
+# HTML output inspired by the output of lcov as found on the GStreamer
+# site. I assume this is not copyrightable.
+#
+
+
+#
+# Read all CSV files and
+# Create an overview file
+#
+#
+
+
+import sys
+import csv
+import glob
+import time
+import os
+import os.path
+import datetime
+import shutil
+
+os.environ["TTFPATH"] = ":".join(["/usr/share/fonts/truetype/" + d
+ for d in "ttf-bitstream-vera",
+ "freefont",
+ "msttcorefonts"])
+import matplotlib
+matplotlib.use("Agg")
+import matplotlib.pylab as m
+
+level_LOW = 10
+level_MEDIUM = 70
+
+def copy_files(dest_dir):
+ """
+ Copy the CSS and the png's to the destination directory
+ """
+ images = ["amber.png", "emerald.png", "glass.png", "ruby.png", "snow.png"]
+ css = "gcov.css"
+ (base_path, name) = os.path.split(__file__)
+ base_path = os.path.abspath(base_path)
+
+ shutil.copyfile(os.path.join(base_path,css), os.path.join(dest_dir,css))
+ map(lambda x: shutil.copyfile(os.path.join(base_path,x), os.path.join(dest_dir,x)), images)
+
+def sumcov(cov):
+ return "%.2f%% (%s/%s)" % (cov[1] * 100.0 / (cov[0] or 1), cov[1], cov[0])
+
+def create_page(dest_dir, name):
+ index = open(os.path.join(dest_dir, name), "w")
+ index.write("""<HTML>
+ <HEAD>
+ <TITLE>WebKit test coverage information</TITLE>
+ <link rel="stylesheet" type="text/css" href="gcov.css">
+ </HEAD>
+ <BODY>
+ """)
+ return index
+
+def generate_header(file, last_time, total_lines, total_executed, path, image):
+ product = "WebKit"
+ date = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(last_time))
+ covered_lines = sumcov((total_lines, total_executed))
+
+ file.write("""<table width="100%%" border=0 cellspacing=0 cellpadding=0>
+ <tr><td class="title">GCOV code coverage report</td></tr>
+ <tr><td class="ruler"><img src="glass.png" width=3 height=3 alt=""></td></tr>
+
+ <tr>
+ <td width="100%%">
+ <table cellpadding=1 border=0 width="100%%">
+ <tr>
+ <td class="headerItem" width="20%%">Current&nbsp;view:</td>
+ <td class="headerValue" width="80%%" colspan=4>%(path)s</td>
+ </tr>
+ <tr>
+ <td class="headerItem" width="20%%">Test:</td>
+ <td class="headerValue" width="80%%" colspan=4>%(product)s</td>
+ </tr>
+ <tr>
+ <td class="headerItem" width="20%%">Date:</td>
+ <td class="headerValue" width="20%%">%(date)s</td>
+ <td width="20%%"></td>
+ <td class="headerItem" width="20%%">Instrumented&nbsp;lines:</td>
+ <td class="headerValue" width="20%%">%(total_lines)s</td>
+ </tr>
+ <tr>
+ <td class="headerItem" width="20%%">Code&nbsp;covered:</td>
+ <td class="headerValue" width="20%%">%(covered_lines)s</td>
+ <td width="20%%"></td>
+ <td class="headerItem" width="20%%">Executed&nbsp;lines:</td>
+ <td class="headerValue" width="20%%">%(total_executed)s</td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr><td class="ruler"><img src="glass.png" width=3 height=3 alt=""></td></tr>
+ </table>""" % vars())
+ # disabled for now <tr><td><img src="%(image)s"></td></tr>
+
+def generate_table_item(file, name, total_lines, covered_lines):
+ covered_precise = (covered_lines*100.0)/(total_lines or 1.0)
+ covered = int(round(covered_precise))
+ remainder = 100-covered
+ (image,perClass,numClass) = coverage_icon(covered_precise)
+ site = "%s.html" % name.replace(os.path.sep,'__')
+ file.write("""
+ <tr>
+ <td class="coverFile"><a href="%(site)s">%(name)s</a></td>
+ <td class="coverBar" align="center">
+ <table border=0 cellspacing=0 cellpadding=1><tr><td class="coverBarOutline"><img src="%(image)s" width=%(covered)s height=10 alt="%(covered_precise).2f"><img src="snow.png" width=%(remainder)s height=10 alt="%(covered_precise).2f"></td></tr></table>
+ </td>
+ <td class="%(perClass)s">%(covered_precise).2f&nbsp;%%</td>
+ <td class="%(numClass)s">%(covered_lines)s&nbsp;/&nbsp;%(total_lines)s&nbsp;lines</td>
+ </tr>
+ """ % vars())
+
+def generate_table_header_start(file):
+ file.write("""<center>
+ <table width="80%%" cellpadding=2 cellspacing=1 border=0>
+
+ <tr>
+ <td width="50%%"><br></td>
+ <td width="15%%"></td>
+ <td width="15%%"></td>
+ <td width="20%%"></td>
+ </tr>
+
+ <tr>
+ <td class="tableHead">Directory&nbsp;name</td>
+ <td class="tableHead" colspan=3>Coverage</td>
+ </tr>
+ """)
+
+def coverage_icon(percent):
+ if percent < level_LOW:
+ return ("ruby.png", "coverPerLo", "coverNumLo")
+ elif percent < level_MEDIUM:
+ return ("amber.png", "coverPerMed", "coverNumMed")
+ else:
+ return ("emerald.png", "coverPerHi", "coverNumHi")
+
+def replace(text, *pairs):
+ """
+ From pydoc... almost identical at least
+ """
+ from string import split, join
+ while pairs:
+ (a,b) = pairs[0]
+ text = join(split(text, a), b)
+ pairs = pairs[1:]
+ return text
+
+def escape(text):
+ """
+ Escape string to be conform HTML
+ """
+ return replace(text,
+ ('&', '&amp;'),
+ ('<', '&lt;' ),
+ ('>', '&gt;' ) )
+
+def generate_table_header_end(file):
+ file.write("""</table>
+ </center>""")
+
+def write_title_page(dest_dir,plot_files, last_time, last_tot_lines, last_tot_covered, dir_series):
+ """
+ Write the index.html with a overview of each directory
+ """
+ index= create_page(dest_dir, "index.html")
+ generate_header(index, last_time, last_tot_lines, last_tot_covered, "directory", "images/Total.png")
+ # Create the directory overview
+ generate_table_header_start(index)
+ dirs = dir_series.keys()
+ dirs.sort()
+ for dir in dirs:
+ (dir_files, total_lines, covered_lines,_) = dir_series[dir][-1]
+ generate_table_item(index, dir, total_lines, covered_lines)
+ generate_table_header_end(index)
+
+ index.write("""</BODY></HTML>""")
+ index.close()
+
+def write_directory_site(dest_dir, plot_files, dir_name, last_time, dir_series, file_series):
+ escaped_dir = dir_name.replace(os.path.sep,'__')
+ site = create_page(dest_dir, "%s.html" % escaped_dir)
+ (_,tot_lines,tot_covered,files) = dir_series[dir_name][-1]
+ generate_header(site, last_time, tot_lines, tot_covered, "directory - %s" % dir_name, "images/%s.png" % escaped_dir)
+
+ files.sort()
+
+ generate_table_header_start(site)
+ for file in files:
+ (lines,covered) = file_series[file][-1]
+ generate_table_item(site, file, lines, covered)
+
+ generate_table_header_end(site)
+ site.write("""</BODY></HTML>""")
+ site.close()
+
+def write_file_site(dest_dir, plot_files, file_name, last_time, data_dir, last_id, file_series):
+ escaped_name = file_name.replace(os.path.sep,'__')
+ site = create_page(dest_dir, "%s.html" % escaped_name)
+ (tot_lines,tot_covered) = file_series[file_name][-1]
+ generate_header(site, last_time, tot_lines, tot_covered, "file - %s" % file_name, "images/%s.png" % escaped_name)
+
+ path = "%s/%s.annotated%s" % (data_dir,last_id,file_name)
+
+ # In contrast to the lcov we want to show files that have been compiled
+ # but have not been tested at all. This means we have sourcefiles with 0
+ # lines covered in the path but they are not lcov files.
+ # To identify them we check the first line now. If we see that we can
+ # continue
+ # -: 0:Source:
+ try:
+ file = open(path, "r")
+ except:
+ return
+ all_lines = file.read().split("\n")
+
+ # Convert the gcov file to HTML if we have a chanche to do so
+ # Scan each line and see if it was covered or not and escape the
+ # text
+ if len(all_lines) == 0 or not "-: 0:Source:" in all_lines[0]:
+ site.write("<p>The file was not excercised</p>")
+ else:
+ site.write("""</br><table cellpadding=0 cellspacing=0 border=0>
+ <tr>
+ <td><br></td>
+ </tr>
+ <tr>
+ <td><pre class="source">
+ """)
+ for line in all_lines:
+ split_line = line.split(':',2)
+ # e.g. at the EOF
+ if len(split_line) == 1:
+ continue
+ line_number = split_line[1].strip()
+ if line_number == "0":
+ continue
+ covered = 15*" "
+ end = ""
+ if "#####" in split_line[0]:
+ covered = '<span class="lineNoCov">%15s' % "0"
+ end = "</span>"
+ elif split_line[0].strip() != "-":
+ covered = '<span class="lineCov">%15s' % split_line[0].strip()
+ end = "</span>"
+
+ escaped_line = escape(split_line[2])
+ str = '<span class="lineNum">%(line_number)10s </span>%(covered)s: %(escaped_line)s%(end)s\n' % vars()
+ site.write(str)
+ site.write("</pre></td></tr></table>")
+ site.write("</BODY></HTML>")
+ site.close()
+
+def main(progname, args):
+ if len(args) != 2:
+ sys.exit("Usage: %s DATADIR OUTDIR" % progname)
+
+ branch = "WebKit from trunk"
+ datadir, outdir = args
+
+ # First, load in all data from the data directory.
+ data = []
+ for datapath in glob.glob(os.path.join(datadir, "*.csv")):
+ data.append(read_csv(datapath))
+ # Sort by time
+ data.sort()
+
+ # Calculate time series for each file.
+ times = [sample[0] for sample in data]
+ times = [datetime.datetime.utcfromtimestamp(t) for t in times]
+ times = m.date2num(times)
+ all_files = {}
+ all_dirs = {}
+ for sample in data:
+ t, i, tot_line, tot_cover, per_file, per_dir = sample
+ all_files.update(per_file)
+ all_dirs.update(per_dir)
+ total_series = []
+ file_serieses = dict([[k, [(0, 0)] * len(times)] for k in all_files.keys()])
+ dir_serieses = dict([[k, [(0, 0, 0, [])] * len(times)] for k in all_dirs.keys()])
+ data_idx = 0
+ for sample in data:
+ t, i, tot_line, tot_cover, per_file, per_dir = sample
+ total_series.append([tot_line, tot_cover])
+ for f, covinfo in per_file.items():
+ file_serieses[f][data_idx] = covinfo
+ for f, covinfo in per_dir.items():
+ dir_serieses[f][data_idx] = covinfo
+ data_idx += 1
+
+
+ # Okay, ready to start outputting. First make sure our directories
+ # exist.
+ if not os.path.exists(outdir):
+ os.makedirs(outdir)
+ rel_imgdir = "images"
+ imgdir = os.path.join(outdir, rel_imgdir)
+ if not os.path.exists(imgdir):
+ os.makedirs(imgdir)
+
+ # Now plot the actual graphs
+ plot_files = {}
+ #plot_files["Total"] = plot_coverage(times, total_series, imgdir, "Total")
+ #for dir, series in dir_serieses.items():
+ # plot_files[dir] = plot_coverage(times, map(lambda (a,b,c,d):(b,c), series), imgdir, dir)
+ #for f, series in file_serieses.items():
+ # plot_files[f] = plot_coverage(times, series, imgdir, f)
+
+ # And look up the latest revision id, and coverage information
+ last_time, last_id, last_tot_lines, last_tot_covered = data[-1][:4]
+
+ # Now start generating our html file
+ copy_files(outdir)
+ write_title_page(outdir, plot_files, last_time, last_tot_lines, last_tot_covered, dir_serieses)
+
+ dir_keys = dir_serieses.keys()
+ dir_keys.sort()
+ for dir_name in dir_keys:
+ write_directory_site(outdir, plot_files, dir_name, last_time, dir_serieses, file_serieses)
+
+ file_keys = file_serieses.keys()
+ for file_name in file_keys:
+ write_file_site(outdir, plot_files, file_name, last_time, datadir, last_id, file_serieses)
+
+def read_csv(path):
+ r = csv.reader(open(path, "r"))
+ # First line is id, time
+ for row in r:
+ id, time_str = row
+ break
+ time = int(float(time_str))
+ # Rest of lines are path, total_lines, covered_lines
+ per_file = {}
+ per_dir = {}
+ grand_total_lines, grand_covered_lines = 0, 0
+ for row in r:
+ path, total_lines_str, covered_lines_str = row
+ total_lines = int(total_lines_str)
+ covered_lines = int(covered_lines_str)
+ grand_total_lines += total_lines
+ grand_covered_lines += covered_lines
+ per_file[path] = [total_lines, covered_lines]
+
+ # Update dir statistics
+ dirname = os.path.dirname(path)
+ if not dirname in per_dir:
+ per_dir[dirname] = (0,0,0,[])
+ (dir_files,dir_total_lines,dir_covered_lines, files) = per_dir[dirname]
+ dir_files += 1
+ dir_total_lines += total_lines
+ dir_covered_lines += covered_lines
+ files.append(path)
+ per_dir[dirname] = (dir_files,dir_total_lines,dir_covered_lines,files)
+ return [time, id, grand_total_lines, grand_covered_lines, per_file, per_dir]
+
+
+def plot_coverage(times, series, imgdir, name):
+ percentages = [cov * 100.0 / (tot or 1) for tot, cov in series]
+ m.plot_date(times, percentages, "b-")
+ m.plot_date(times, percentages, "bo")
+ m.title(name)
+ m.ylim(0, 100)
+ m.xlabel("Date")
+ m.ylabel("Statement Coverage (%)")
+ outfile_base = name.replace("/", "__") + ".png"
+ outfile = os.path.join(imgdir, outfile_base)
+ m.savefig(outfile, dpi=75)
+ m.close()
+ return outfile_base
+
+
+if __name__ == "__main__":
+ import sys
+ main(sys.argv[0], sys.argv[1:])
diff --git a/WebKitTools/CodeCoverage/ruby.png b/WebKitTools/CodeCoverage/ruby.png
new file mode 100644
index 0000000..a582d35
--- /dev/null
+++ b/WebKitTools/CodeCoverage/ruby.png
Binary files differ
diff --git a/WebKitTools/CodeCoverage/run-generate-coverage-data b/WebKitTools/CodeCoverage/run-generate-coverage-data
new file mode 100755
index 0000000..a87da1d
--- /dev/null
+++ b/WebKitTools/CodeCoverage/run-generate-coverage-data
@@ -0,0 +1,240 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2004, 2005, 2006 Nathaniel Smith
+# Copyright (C) 2007 Holger Hans Peter Freyther
+#
+# 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 os, sys
+
+# from BitBake
+def mkdirhier(dir):
+ """Create a directory like 'mkdir -p', but does not complain if
+ directory already exists like os.makedirs
+ """
+ try:
+ os.makedirs(dir)
+ except OSError, e:
+ if e.errno != 17: raise e
+
+def collect_base(src,match_array):
+ """
+ Collect all files that match the match_array.
+ """
+
+ sources = []
+ for root, dirs, files in os.walk(src):
+ if ".svn" in root:
+ continue
+
+ for file in files:
+ base,ext = os.path.splitext(file)
+ if ext in match_array:
+ sources.append( os.path.join(root, file) )
+
+ return sources
+
+def collect_depends(src):
+ return collect_base(src, [".d"])
+
+def parse_dependency_file(src, base_dir, black_list):
+ """
+ Parse the .d files of the gcc
+
+ Wow, the first time os.path.join is doing the right thing. We might
+ have a relative path in the depends using os.path.join(dirname of .d, dep)
+ we will end up in
+ """
+ file = open(src)
+ file = file.read()
+ file = file.replace('\\', '').replace('\n', '')
+
+ # We now have object: dependencies splitted
+ ar = file.split(':', 1)
+ obj = ar[0].strip()
+ dir = os.path.dirname(obj)
+ deps = ar[1].split(' ')
+
+ # Remove files outside WebKit, make path absolute
+ deps = filter(lambda x: base_dir in x, deps)
+ deps = map(lambda x: os.path.abspath(os.path.join(dir, x)), deps)
+ return (obj, dir, deps)
+
+def collect_cov(base_path,targets):
+ """
+ Collect gcov files, collect_sources is not used as it also creates
+ dirs and needs to do substituting.
+ Actually we will build a mapping from source file to gcov files of
+ interest. This is because we could have bytestream.h in many different
+ subdirectories. And we would endup with bla.cpp##bytestream.h and we
+ do not know which bytestream file was tested
+ """
+ def find_source_file(root,cov_file):
+ """ Find a Source line or crash
+
+ '#Users#ich#projekte#src#threadmessage.cpp###space#dports#include#qt3#qstring.h.gcov'
+ '#Users#ich#projekte#src#threadmessage.cpp##..#^#src#threadmessage.cpp.gcov'
+
+ ### is absolute path
+ ##..#^# is relative path... well a gcov bug as well
+ ## normal split file in the same directory
+ """
+ if '###' in cov_file:
+ split = cov_file.split('###')
+ if not len(split) == 2:
+ raise "Unexpected split result"
+ filepath = split[1][:-5].replace('#',os.path.sep)
+ return os.path.join(os.path.sep,filepath)
+ elif '##..#^#' in cov_file:
+ split = cov_file.split('##..#^#')
+ if not len(split) == 2:
+ raise "Unexpected split result"
+ filepath = split[1][:-5].replace('#',os.path.sep)
+ return os.path.abspath(os.path.join(root,os.path.pardir,os.path.pardir,filepath))
+ elif '##' in cov_file:
+ split = cov_file.split('##')
+ if not len(split) == 2:
+ raise "Unexpected split result"
+ filepath = split[1][:-5].replace('#',os.path.sep)
+ return os.path.abspath(os.path.join(root,filepath))
+ elif '#' in cov_file:
+ # wow a not broken gcov on OSX
+ basename=os.path.basename(cov_file).replace('#',os.path.sep)[:-5]
+ return os.path.abspath(os.path.join(root,basename))
+
+ else:
+ raise "No source found %s" % cov_file
+
+ def sanitize_path(path):
+ """
+ Well fix up paths once again /usr/lib/gcc/i486-linux-gnu/4.1.2/^/^/^/^/include/c++/4.1.2/bits/stl_pair.h
+ according to gcov '^' is a relative path, we will now build one from this one. Somehow it depends
+ on the gcov version if .. really gets replaced to ^....
+ """
+ import os
+ split = path.split(os.path.sep)
+ str = ""
+ for part in split:
+ if part == '':
+ str = os.path.sep
+ elif part == '^':
+ str = "%s..%s" % (str,os.path.sep)
+ else:
+ str = "%s%s%s" % (str,part,os.path.sep)
+ return os.path.abspath(str)
+
+
+ gcov = {}
+ for root, dirs, files in os.walk(base_path):
+ if ".svn" in root:
+ continue
+ for file in files:
+ base,ext = os.path.splitext(file)
+ if ext in [".gcov"]:
+ try:
+ cov = os.path.join(root, file)
+ src = find_source_file( root, cov )
+ src = sanitize_path( src )
+
+ if not src in gcov:
+ gcov[src] = []
+ gcov[src].append( cov )
+ except Exception,e:
+ print "Exception on ", e
+ #import sys
+ #sys.exit(0)
+ pass
+
+ #print gcov
+ return gcov
+
+def generate_covs(candidates):
+ """
+ Generate gcov files in the right directory
+
+ candidtaes contains the directories we have used when
+ building. Each directory contains a set of files we will
+ try to generate gcov files for.
+ """
+ print candidates.keys()
+ for dir in candidates.keys():
+ print "Trying in %s" % (dir)
+ for dep in candidates[dir].keys():
+ cmd = "cd %s; gcov -p -l %s" % (dir, dep)
+ os.system("%s > /dev/null 2>&1 " % cmd)
+
+
+def analyze_coverage(sources,data,dirs,runid,base):
+ """
+ sources actual source files relative to src_dir e.g kdelibs/kdecore/klibloader.cpp
+ data Where to put the stuff
+ dirs Where to take a look for gcov files
+ base The base directory for files. All files not inside base will be ignored
+ """
+ import cov
+ print base
+ gcov = collect_cov(base,dirs)
+ result = cov.analyze_coverage(gcov, sources, runid, data, base)
+ print result
+
+if __name__ == "__main__":
+ #global targets
+ if not len(sys.argv) == 3:
+ print "This script needs three parameters"
+ print "Call it with generate_cov RUNID ResultsDir"
+ sys.exit(-1)
+ runid = sys.argv[1]
+ results = sys.argv[2]
+
+ # create directories for out result
+ mkdirhier(results)
+
+ print "Collection Sources and preparing data tree"
+ base_dir = os.path.abspath(os.path.curdir)
+ depends = collect_depends(base_dir)
+ candidates = map(lambda x: parse_dependency_file(x,base_dir,[]), depends)
+
+ # Build a number of sources from the candidates. This is a Set for the poor
+ # Two level dict. One for
+ dirs = {}
+ files = {}
+ for (_,dir,deps) in candidates:
+ if not dir in dirs:
+ dirs[dir] = {}
+ for dep in deps:
+ if not dep in dirs[dir]:
+ dirs[dir][dep] = dep
+ if not dep in files:
+ files[dep] = dep
+
+ sources = files.keys()
+
+ print "Found %d candidates" % (len(sources))
+ print "Will run inefficient generation of gcov files now"
+ generate_covs(dirs)
+
+ print "Analyzing Gcov"
+ analyze_coverage(sources, results, dirs.keys(), runid, base_dir)
+ print "Done"
diff --git a/WebKitTools/CodeCoverage/snow.png b/WebKitTools/CodeCoverage/snow.png
new file mode 100644
index 0000000..a4ba373
--- /dev/null
+++ b/WebKitTools/CodeCoverage/snow.png
Binary files differ
diff --git a/WebKitTools/CygwinDownloader/cygwin-downloader.py b/WebKitTools/CygwinDownloader/cygwin-downloader.py
new file mode 100644
index 0000000..a0e7089
--- /dev/null
+++ b/WebKitTools/CygwinDownloader/cygwin-downloader.py
@@ -0,0 +1,157 @@
+#!/usr/bin/env python
+
+import os, random, sys, time, urllib
+
+#
+# Options
+#
+
+dry_run = len(sys.argv) > 1 and "--dry-run" in set(sys.argv[1:])
+quiet = len(sys.argv) > 1 and "--quiet" in set(sys.argv[1:])
+
+#
+# Functions and constants
+#
+
+def download_progress_hook(block_count, block_size, total_blocks):
+ if quiet or random.random() > 0.5:
+ return
+ sys.stdout.write(".")
+ sys.stdout.flush()
+
+def download_url_to_file(url, file, message):
+ if not quiet:
+ print message + " ",
+ if not dry_run:
+ dir = os.path.dirname(file)
+ if len(dir) and not os.path.exists(dir):
+ os.makedirs(dir)
+ urllib.urlretrieve(url, file, download_progress_hook)
+ if not quiet:
+ print
+
+# This is mostly just the list of North America http mirrors from http://cygwin.com/mirrors.html,
+# but a few have been removed that seemed unresponsive from Cupertino.
+mirror_servers = ["http://cygwin.elite-systems.org/",
+ "http://mirror.mcs.anl.gov/cygwin/",
+ "http://cygwin.osuosl.org/",
+ "http://mirrors.kernel.org/sourceware/cygwin/",
+ "http://cygwin.mirrors.hoobly.com/",
+ "http://cygwin.rtin.bz/",
+ "http://mirrors.wikifusion.info/cygwin/",
+ "http://mirrors.xmission.com/cygwin/",
+ "http://sourceware.mirrors.tds.net/pub/sourceware.org/cygwin/"]
+
+package_mirror_url = mirror_servers[random.choice(range(len(mirror_servers)))]
+
+def download_package(package, message):
+ download_url_to_file(package_mirror_url + package["path"], package["path"], message)
+
+required_packages = frozenset(["apache",
+ "bc",
+ "bison",
+ "curl",
+ "diffutils",
+ "e2fsprogs",
+ "emacs",
+ "flex",
+ "gcc",
+ "gperf",
+ "keychain",
+ "make",
+ "nano",
+ "openssh",
+ "patch",
+ "perl",
+ "perl-libwin32",
+ "python",
+ "rebase",
+ "rsync",
+ "subversion",
+ "unzip",
+ "vim",
+ "zip"])
+
+#
+# Main
+#
+
+print "Using Cygwin mirror server " + package_mirror_url + " to download setup.ini..."
+
+urllib.urlretrieve(package_mirror_url + "setup.ini", "setup.ini.orig")
+
+downloaded_packages_file_path = "setup.ini.orig"
+downloaded_packages_file = file(downloaded_packages_file_path, "r")
+if not dry_run:
+ modified_packages_file = file("setup.ini", "w")
+
+packages = {}
+current_package = ''
+for line in downloaded_packages_file.readlines():
+ if line[0] == "@":
+ current_package = line[2:-1]
+ packages[current_package] = {"name": current_package, "needs_download": False, "requires": [], "path": ""}
+ elif line[:10] == "category: ":
+ if current_package in required_packages:
+ line = "category: Base\n"
+ if "Base" in set(line[10:-1].split()):
+ packages[current_package]["needs_download"] = True
+ elif line[:10] == "requires: ":
+ packages[current_package]["requires"] = line[10:].split()
+ packages[current_package]["requires"].sort()
+ elif line[:9] == "install: " and not len(packages[current_package]["path"]):
+ end_of_path = line.find(" ", 9)
+ if end_of_path != -1:
+ packages[current_package]["path"] = line[9:end_of_path]
+ if not dry_run:
+ modified_packages_file.write(line)
+
+downloaded_packages_file.close()
+os.remove(downloaded_packages_file_path)
+if not dry_run:
+ modified_packages_file.close()
+
+names_to_download = set()
+package_names = packages.keys()
+package_names.sort()
+
+def add_package_and_dependencies(name):
+ if name in names_to_download:
+ return
+ packages[name]["needs_download"] = True
+ names_to_download.add(name)
+ for dep in packages[name]["requires"]:
+ add_package_and_dependencies(dep)
+
+for name in package_names:
+ if packages[name]["needs_download"]:
+ add_package_and_dependencies(name)
+
+downloaded_so_far = 0
+for name in package_names:
+ if packages[name]["needs_download"]:
+ downloaded_so_far += 1
+ download_package(packages[name], "Downloading package %3d of %3d (%s)" % (downloaded_so_far, len(names_to_download), name))
+
+download_url_to_file("http://cygwin.com/setup.exe", "setup.exe", "Downloading setup.exe")
+
+seconds_to_sleep = 10
+
+print """
+Finished downloading Cygwin. In %d seconds,
+I will run setup.exe. Select the "Install
+from Local Directory" option and browse to
+"%s"
+when asked for the "Local Package Directory".
+""" % (seconds_to_sleep, os.getcwd())
+
+
+while seconds_to_sleep > 0:
+ print "%d..." % seconds_to_sleep,
+ sys.stdout.flush()
+ time.sleep(1)
+ seconds_to_sleep -= 1
+print
+
+if not dry_run:
+ os.execl("setup.exe")
diff --git a/WebKitTools/CygwinDownloader/cygwin-downloader.zip b/WebKitTools/CygwinDownloader/cygwin-downloader.zip
new file mode 100644
index 0000000..40f43b3
--- /dev/null
+++ b/WebKitTools/CygwinDownloader/cygwin-downloader.zip
Binary files differ
diff --git a/WebKitTools/CygwinDownloader/make-zip.sh b/WebKitTools/CygwinDownloader/make-zip.sh
new file mode 100755
index 0000000..4a389a9
--- /dev/null
+++ b/WebKitTools/CygwinDownloader/make-zip.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+PYTHONEXE=$(cygpath -u "${SYSTEMDRIVE}\\Python25\\python.exe")
+ZIPNAME="cygwin-downloader.zip"
+
+if [[ ! -f "${PYTHONEXE}" ]]; then
+ echo "Couldn't find python.exe at ${PYTHONEXE}" 1>&2
+ exit 1
+fi
+
+"${PYTHONEXE}" setup.py py2exe || {
+ echo "Failed executing setup.py" 1>&2
+ exit 1
+}
+
+rm -f "${ZIPNAME}"
+
+cd dist
+
+zip -r ../"${ZIPNAME}" * || {
+ echo "Failed to create cygwin-downloader" 1>&2
+ exit 1
+}
+
+cd ..
+
+rm -rf build dist || {
+ echo "Failed to cleanup cygwin-downloader and build directories" 1>&2
+ exit 1
+}
diff --git a/WebKitTools/CygwinDownloader/setup.py b/WebKitTools/CygwinDownloader/setup.py
new file mode 100644
index 0000000..c3171d9
--- /dev/null
+++ b/WebKitTools/CygwinDownloader/setup.py
@@ -0,0 +1,4 @@
+from distutils.core import setup
+import py2exe
+
+setup(console=['cygwin-downloader.py'])
diff --git a/WebKitTools/DrawTest/AppDelegate.h b/WebKitTools/DrawTest/AppDelegate.h
new file mode 100644
index 0000000..7103bb8
--- /dev/null
+++ b/WebKitTools/DrawTest/AppDelegate.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2005 Apple Computer, 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>
+
+
+@interface AppDelegate : NSObject {
+ IBOutlet NSWindow *svgImageRepTestWindow;
+}
+
+- (IBAction)showTestsPanel:(id)sender;
+- (IBAction)showImageRepTestWindow:(id)sender;
+- (IBAction)showInspectorPanel:(id)sender;
+
+@end
diff --git a/WebKitTools/DrawTest/AppDelegate.m b/WebKitTools/DrawTest/AppDelegate.m
new file mode 100644
index 0000000..0f20b35
--- /dev/null
+++ b/WebKitTools/DrawTest/AppDelegate.m
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2005 Apple Computer, 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 "AppDelegate.h"
+
+#import "TestController.h"
+#import "DrawTestInspectorController.h"
+
+@implementation AppDelegate
+
+- (IBAction)showTestsPanel:(id)sender
+{
+ [[TestController sharedController] showTestsPanel:sender];
+}
+
+- (IBAction)showImageRepTestWindow:(id)sender
+{
+ [svgImageRepTestWindow makeKeyAndOrderFront:sender];
+}
+
+- (IBAction)showInspectorPanel:(id)sender
+{
+ [[DrawTestInspectorController sharedInstance] showInspectorPanel:sender];
+}
+
+- (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender
+{
+ return NO;
+}
+
+@end
diff --git a/WebKitTools/DrawTest/DrawTest.xcodeproj/project.pbxproj b/WebKitTools/DrawTest/DrawTest.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..8d62751
--- /dev/null
+++ b/WebKitTools/DrawTest/DrawTest.xcodeproj/project.pbxproj
@@ -0,0 +1,388 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 42;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 78662E6D096B4E1600907EA7 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 78662E6C096B4E1600907EA7 /* WebKit.framework */; };
+ 8D11072A0486CEB800E47090 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 29B97318FDCFA39411CA2CEA /* MainMenu.nib */; };
+ 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
+ 8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
+ 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+ A8C006CF0898634600BA5114 /* SVGTest.m in Sources */ = {isa = PBXBuildFile; fileRef = A8C006B00898634600BA5114 /* SVGTest.m */; };
+ A8C006D00898634600BA5114 /* ScalingImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = A8C006B20898634600BA5114 /* ScalingImageView.m */; };
+ A8C006D20898634600BA5114 /* DrawTestView.m in Sources */ = {isa = PBXBuildFile; fileRef = A8C006B50898634600BA5114 /* DrawTestView.m */; };
+ A8C006D30898634600BA5114 /* DrawTestToolbarController.m in Sources */ = {isa = PBXBuildFile; fileRef = A8C006B70898634600BA5114 /* DrawTestToolbarController.m */; };
+ A8C006D40898634600BA5114 /* DrawTestInspectorController.m in Sources */ = {isa = PBXBuildFile; fileRef = A8C006BB0898634600BA5114 /* DrawTestInspectorController.m */; };
+ A8C006D50898634600BA5114 /* DrawTestDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = A8C006BD0898634600BA5114 /* DrawTestDocument.m */; };
+ A8C006E10898634600BA5114 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A8C006CA0898634600BA5114 /* AppDelegate.m */; };
+ A8C006E20898634600BA5114 /* TestViewerSplitView.m in Sources */ = {isa = PBXBuildFile; fileRef = A8C006CC0898634600BA5114 /* TestViewerSplitView.m */; };
+ A8C006E30898634600BA5114 /* TestController.m in Sources */ = {isa = PBXBuildFile; fileRef = A8C006CE0898634600BA5114 /* TestController.m */; };
+ A8C006F3089865E900BA5114 /* DrawTestDocument.nib in Resources */ = {isa = PBXBuildFile; fileRef = A8C006ED089865E900BA5114 /* DrawTestDocument.nib */; };
+ A8C006F4089865E900BA5114 /* Inspector.nib in Resources */ = {isa = PBXBuildFile; fileRef = A8C006EF089865E900BA5114 /* Inspector.nib */; };
+ A8C006F5089865E900BA5114 /* TestViewer.nib in Resources */ = {isa = PBXBuildFile; fileRef = A8C006F1089865E900BA5114 /* TestViewer.nib */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+ 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
+ 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
+ 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+ 29B97319FDCFA39411CA2CEA /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/MainMenu.nib; sourceTree = "<group>"; };
+ 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
+ 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
+ 32CA4F630368D1EE00C91783 /* DrawTest_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DrawTest_Prefix.pch; sourceTree = "<group>"; };
+ 78662E6C096B4E1600907EA7 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = WebKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Info.plist; sourceTree = "<group>"; };
+ 8D1107320486CEB800E47090 /* DrawTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DrawTest.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ A8C006AF0898634600BA5114 /* TestController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestController.h; sourceTree = "<group>"; };
+ A8C006B00898634600BA5114 /* SVGTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SVGTest.m; sourceTree = "<group>"; };
+ A8C006B10898634600BA5114 /* SVGTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGTest.h; sourceTree = "<group>"; };
+ A8C006B20898634600BA5114 /* ScalingImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ScalingImageView.m; sourceTree = "<group>"; };
+ A8C006B30898634600BA5114 /* ScalingImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScalingImageView.h; sourceTree = "<group>"; };
+ A8C006B50898634600BA5114 /* DrawTestView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DrawTestView.m; sourceTree = "<group>"; };
+ A8C006B60898634600BA5114 /* DrawTestView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DrawTestView.h; sourceTree = "<group>"; };
+ A8C006B70898634600BA5114 /* DrawTestToolbarController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DrawTestToolbarController.m; sourceTree = "<group>"; };
+ A8C006B80898634600BA5114 /* DrawTestDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DrawTestDocument.h; sourceTree = "<group>"; };
+ A8C006BA0898634600BA5114 /* DrawTestToolbarController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DrawTestToolbarController.h; sourceTree = "<group>"; };
+ A8C006BB0898634600BA5114 /* DrawTestInspectorController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DrawTestInspectorController.m; sourceTree = "<group>"; };
+ A8C006BC0898634600BA5114 /* DrawTestInspectorController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DrawTestInspectorController.h; sourceTree = "<group>"; };
+ A8C006BD0898634600BA5114 /* DrawTestDocument.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DrawTestDocument.m; sourceTree = "<group>"; };
+ A8C006CA0898634600BA5114 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
+ A8C006CB0898634600BA5114 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
+ A8C006CC0898634600BA5114 /* TestViewerSplitView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TestViewerSplitView.m; sourceTree = "<group>"; };
+ A8C006CD0898634600BA5114 /* TestViewerSplitView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestViewerSplitView.h; sourceTree = "<group>"; };
+ A8C006CE0898634600BA5114 /* TestController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TestController.m; sourceTree = "<group>"; };
+ A8C006EE089865E900BA5114 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/DrawTestDocument.nib; sourceTree = "<group>"; };
+ A8C006F0089865E900BA5114 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/Inspector.nib; sourceTree = "<group>"; };
+ A8C006F2089865E900BA5114 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/TestViewer.nib; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 8D11072E0486CEB800E47090 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */,
+ 78662E6D096B4E1600907EA7 /* WebKit.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 080E96DDFE201D6D7F000001 /* Classes */ = {
+ isa = PBXGroup;
+ children = (
+ A8C006E5089863A100BA5114 /* Viewer */,
+ A8C006E6089863B100BA5114 /* Test Browser */,
+ A8C006CA0898634600BA5114 /* AppDelegate.m */,
+ A8C006CB0898634600BA5114 /* AppDelegate.h */,
+ A8C006B20898634600BA5114 /* ScalingImageView.m */,
+ A8C006B30898634600BA5114 /* ScalingImageView.h */,
+ );
+ name = Classes;
+ sourceTree = "<group>";
+ };
+ 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 78662E6C096B4E1600907EA7 /* WebKit.framework */,
+ 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */,
+ );
+ name = "Linked Frameworks";
+ sourceTree = "<group>";
+ };
+ 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 29B97324FDCFA39411CA2CEA /* AppKit.framework */,
+ 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */,
+ 29B97325FDCFA39411CA2CEA /* Foundation.framework */,
+ );
+ name = "Other Frameworks";
+ sourceTree = "<group>";
+ };
+ 19C28FACFE9D520D11CA2CBB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 8D1107320486CEB800E47090 /* DrawTest.app */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 29B97314FDCFA39411CA2CEA /* DrawTest */ = {
+ isa = PBXGroup;
+ children = (
+ 080E96DDFE201D6D7F000001 /* Classes */,
+ 29B97315FDCFA39411CA2CEA /* Other Sources */,
+ 29B97317FDCFA39411CA2CEA /* Resources */,
+ 29B97323FDCFA39411CA2CEA /* Frameworks */,
+ 19C28FACFE9D520D11CA2CBB /* Products */,
+ );
+ name = DrawTest;
+ sourceTree = "<group>";
+ };
+ 29B97315FDCFA39411CA2CEA /* Other Sources */ = {
+ isa = PBXGroup;
+ children = (
+ 32CA4F630368D1EE00C91783 /* DrawTest_Prefix.pch */,
+ 29B97316FDCFA39411CA2CEA /* main.m */,
+ );
+ name = "Other Sources";
+ sourceTree = "<group>";
+ };
+ 29B97317FDCFA39411CA2CEA /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ 8D1107310486CEB800E47090 /* Info.plist */,
+ 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */,
+ 29B97318FDCFA39411CA2CEA /* MainMenu.nib */,
+ A8C006ED089865E900BA5114 /* DrawTestDocument.nib */,
+ A8C006EF089865E900BA5114 /* Inspector.nib */,
+ A8C006F1089865E900BA5114 /* TestViewer.nib */,
+ );
+ name = Resources;
+ sourceTree = "<group>";
+ };
+ 29B97323FDCFA39411CA2CEA /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */,
+ 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+ A8C006E5089863A100BA5114 /* Viewer */ = {
+ isa = PBXGroup;
+ children = (
+ A8C006BA0898634600BA5114 /* DrawTestToolbarController.h */,
+ A8C006B70898634600BA5114 /* DrawTestToolbarController.m */,
+ A8C006B60898634600BA5114 /* DrawTestView.h */,
+ A8C006B50898634600BA5114 /* DrawTestView.m */,
+ A8C006B80898634600BA5114 /* DrawTestDocument.h */,
+ A8C006BD0898634600BA5114 /* DrawTestDocument.m */,
+ );
+ name = Viewer;
+ sourceTree = "<group>";
+ };
+ A8C006E6089863B100BA5114 /* Test Browser */ = {
+ isa = PBXGroup;
+ children = (
+ A8C006B00898634600BA5114 /* SVGTest.m */,
+ A8C006B10898634600BA5114 /* SVGTest.h */,
+ A8C006BB0898634600BA5114 /* DrawTestInspectorController.m */,
+ A8C006BC0898634600BA5114 /* DrawTestInspectorController.h */,
+ A8C006AF0898634600BA5114 /* TestController.h */,
+ A8C006CE0898634600BA5114 /* TestController.m */,
+ A8C006CC0898634600BA5114 /* TestViewerSplitView.m */,
+ A8C006CD0898634600BA5114 /* TestViewerSplitView.h */,
+ );
+ name = "Test Browser";
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 8D1107260486CEB800E47090 /* DrawTest */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A8C006740898624E00BA5114 /* Build configuration list for PBXNativeTarget "DrawTest" */;
+ buildPhases = (
+ 8D1107290486CEB800E47090 /* Resources */,
+ 8D11072C0486CEB800E47090 /* Sources */,
+ 8D11072E0486CEB800E47090 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = DrawTest;
+ productInstallPath = "$(HOME)/Applications";
+ productName = DrawTest;
+ productReference = 8D1107320486CEB800E47090 /* DrawTest.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 29B97313FDCFA39411CA2CEA /* Project object */ = {
+ isa = PBXProject;
+ buildConfigurationList = A8C006780898624E00BA5114 /* Build configuration list for PBXProject "DrawTest" */;
+ compatibilityVersion = "Xcode 2.4";
+ hasScannedForEncodings = 1;
+ mainGroup = 29B97314FDCFA39411CA2CEA /* DrawTest */;
+ projectDirPath = "";
+ projectRoot = "";
+ shouldCheckCompatibility = 1;
+ targets = (
+ 8D1107260486CEB800E47090 /* DrawTest */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 8D1107290486CEB800E47090 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A8C006F3089865E900BA5114 /* DrawTestDocument.nib in Resources */,
+ 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */,
+ A8C006F4089865E900BA5114 /* Inspector.nib in Resources */,
+ 8D11072A0486CEB800E47090 /* MainMenu.nib in Resources */,
+ A8C006F5089865E900BA5114 /* TestViewer.nib in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 8D11072C0486CEB800E47090 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A8C006E10898634600BA5114 /* AppDelegate.m in Sources */,
+ A8C006D50898634600BA5114 /* DrawTestDocument.m in Sources */,
+ A8C006D40898634600BA5114 /* DrawTestInspectorController.m in Sources */,
+ A8C006D30898634600BA5114 /* DrawTestToolbarController.m in Sources */,
+ A8C006D20898634600BA5114 /* DrawTestView.m in Sources */,
+ A8C006CF0898634600BA5114 /* SVGTest.m in Sources */,
+ A8C006D00898634600BA5114 /* ScalingImageView.m in Sources */,
+ A8C006E30898634600BA5114 /* TestController.m in Sources */,
+ A8C006E20898634600BA5114 /* TestViewerSplitView.m in Sources */,
+ 8D11072D0486CEB800E47090 /* main.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 089C165DFE840E0CC02AAC07 /* English */,
+ );
+ name = InfoPlist.strings;
+ sourceTree = "<group>";
+ };
+ 29B97318FDCFA39411CA2CEA /* MainMenu.nib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 29B97319FDCFA39411CA2CEA /* English */,
+ );
+ name = MainMenu.nib;
+ sourceTree = "<group>";
+ };
+ A8C006ED089865E900BA5114 /* DrawTestDocument.nib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ A8C006EE089865E900BA5114 /* English */,
+ );
+ name = DrawTestDocument.nib;
+ sourceTree = "<group>";
+ };
+ A8C006EF089865E900BA5114 /* Inspector.nib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ A8C006F0089865E900BA5114 /* English */,
+ );
+ name = Inspector.nib;
+ sourceTree = "<group>";
+ };
+ A8C006F1089865E900BA5114 /* TestViewer.nib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ A8C006F2089865E900BA5114 /* English */,
+ );
+ name = TestViewer.nib;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ A8C006750898624E00BA5114 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = DrawTest_Prefix.pch;
+ GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ INFOPLIST_FILE = Info.plist;
+ INSTALL_PATH = "$(HOME)/Applications";
+ PREBINDING = NO;
+ PRODUCT_NAME = DrawTest;
+ WRAPPER_EXTENSION = app;
+ ZERO_LINK = YES;
+ };
+ name = Debug;
+ };
+ A8C006760898624E00BA5114 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = YES;
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = DrawTest_Prefix.pch;
+ GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ INFOPLIST_FILE = Info.plist;
+ INSTALL_PATH = "$(HOME)/Applications";
+ PREBINDING = NO;
+ PRODUCT_NAME = DrawTest;
+ WRAPPER_EXTENSION = app;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A8C006790898624E00BA5114 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ };
+ name = Debug;
+ };
+ A8C0067A0898624E00BA5114 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ A8C006740898624E00BA5114 /* Build configuration list for PBXNativeTarget "DrawTest" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A8C006750898624E00BA5114 /* Debug */,
+ A8C006760898624E00BA5114 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A8C006780898624E00BA5114 /* Build configuration list for PBXProject "DrawTest" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A8C006790898624E00BA5114 /* Debug */,
+ A8C0067A0898624E00BA5114 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
+}
diff --git a/WebKitTools/DrawTest/DrawTestDocument.h b/WebKitTools/DrawTest/DrawTestDocument.h
new file mode 100644
index 0000000..b0b16d9
--- /dev/null
+++ b/WebKitTools/DrawTest/DrawTestDocument.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Nefaur Khandker <nefaurk@gmail.com> All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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>
+
+@class DrawTestView;
+@class DrawTestToolbarController;
+
+@interface DrawTestDocument : NSDocument
+{
+ IBOutlet DrawTestView *drawView;
+ IBOutlet NSDrawer *debugDrawer;
+
+ DrawTestToolbarController *toolbarController;
+}
+
+// Debug menu
+- (IBAction)dumpSVGToConsole:(id)sender;
+- (IBAction)toggleDebugDrawer:(id)sender;
+- (IBAction)runWindowResizeTest:(id)sender;
+
+@end
diff --git a/WebKitTools/DrawTest/DrawTestDocument.m b/WebKitTools/DrawTest/DrawTestDocument.m
new file mode 100644
index 0000000..c71e7ad
--- /dev/null
+++ b/WebKitTools/DrawTest/DrawTestDocument.m
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Nefaur Khandker <nefaurk@gmail.com> All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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 "DrawTestDocument.h"
+#import "DrawTestView.h"
+#import "DrawTestToolbarController.h"
+#import <WebKit/WebView.h>
+#import <WebKit/WebFrame.h>
+#import <WebKit/WebDataSource.h>
+
+@implementation DrawTestDocument
+
+- (id)initWithType:(NSString *)typeName error:(NSError **)outError
+{
+ if (outError) {
+ NSDictionary *errorInfo = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"No document could be created.", NSLocalizedDescriptionKey,
+ @"New document creation not yet supported.", NSLocalizedFailureReasonErrorKey,
+ nil];
+ *outError = [NSError errorWithDomain:NSCocoaErrorDomain code:0 userInfo:errorInfo];
+ }
+ [self release];
+ return nil;
+}
+
+- (void)dealloc
+{
+ [toolbarController release];
+ [super dealloc];
+}
+
+- (NSString *)windowNibName
+{
+ return @"DrawTestDocument";
+}
+
+- (BOOL)readFromFile:(NSString *)filename ofType:(NSString *)docType
+{
+ // TODO: Check the validity of the document before returning YES.
+ return YES;
+}
+
+- (void)windowControllerDidLoadNib:(NSWindowController *)aController
+{
+ [super windowControllerDidLoadNib:aController];
+ toolbarController = [[DrawTestToolbarController alloc] initWithDrawView:drawView];
+ [drawView setDocument:[self fileURL]];
+}
+
+- (IBAction)dumpSVGToConsole:(id)sender
+{
+ WebDataSource* dataSource = [[drawView mainFrame] dataSource];
+ NSLog(@"SVG Markup for file %@:\n%@", [self fileURL], [[dataSource representation] documentSource]);
+}
+
+- (IBAction)openSourceForSelection:(id)sender
+{
+ // TODO: The "path" message (below) will not produce a valid pathname if we are dealing with a remote file.
+ NSString *filename = [[self fileURL] path];
+ [[NSWorkspace sharedWorkspace] openFile:filename withApplication:@"TextEdit"];
+}
+
+- (NSData *)dataRepresentationOfType:(NSString *)aType
+{
+ WebDataSource* dataSource = [[drawView mainFrame] dataSource];
+ return [dataSource data];
+}
+
+#pragma mark -
+#pragma mark Debug Methods
+
+- (IBAction)toggleDebugDrawer:(id)sender
+{
+ [debugDrawer toggle:sender];
+}
+
+- (id)outlineView:(NSOutlineView *)outlineView child:(int)index ofItem:(id)item
+{
+ return nil;
+}
+
+- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item
+{
+ return NO;
+}
+
+- (int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
+{
+ return 0;
+}
+
+- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
+{
+ return nil;
+}
+
+- (IBAction)runWindowResizeTest:(id)sender
+{
+ NSWindow *window = [drawView window];
+ NSScreen *screen = [window screen];
+ float screenHeight = [screen visibleFrame].size.height;
+ NSRect originalFrame = [window frame];
+ // initial setup
+ BOOL toolbarVisible = [[window toolbar] isVisible];
+ if (toolbarVisible) [window toggleToolbarShown:self];
+ [window setFrame:NSMakeRect(0,screenHeight-100,100,100) display:YES];
+
+ // grab time.
+ CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();
+
+ // run test
+ for (int x = 0; x < 3; x++) {
+ for (float size = 100; size < 500.f; size += 20.f) {
+ [window setFrame:NSMakeRect(0, screenHeight-size, size, size) display:YES];
+ }
+ }
+
+ double elapsed = CFAbsoluteTimeGetCurrent() - start;
+
+ // log
+ NSLog(@"Window resize test: %fs", elapsed);
+
+ // restore
+ if (toolbarVisible) [window toggleToolbarShown:self];
+ [window setFrame:originalFrame display:YES];
+}
+
+@end
diff --git a/WebKitTools/DrawTest/DrawTestInspectorController.h b/WebKitTools/DrawTest/DrawTestInspectorController.h
new file mode 100644
index 0000000..43c06f0
--- /dev/null
+++ b/WebKitTools/DrawTest/DrawTestInspectorController.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2005 Apple Computer, 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>
+
+
+@interface DrawTestInspectorController : NSObject {
+ IBOutlet NSPanel *_inspectorPanel;
+}
+
++ (id)sharedInstance;
+
+- (IBAction)showInspectorPanel:(id)sender;
+
+@end
diff --git a/WebKitTools/DrawTest/DrawTestInspectorController.m b/WebKitTools/DrawTest/DrawTestInspectorController.m
new file mode 100644
index 0000000..604bf03
--- /dev/null
+++ b/WebKitTools/DrawTest/DrawTestInspectorController.m
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2005 Apple Computer, 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 "DrawTestInspectorController.h"
+
+@implementation DrawTestInspectorController
+
++ (id)sharedInstance
+{
+ static DrawTestInspectorController *__sharedController = nil;
+ if (!__sharedController) {
+ __sharedController = [[self alloc] init];
+ }
+ return __sharedController;
+}
+
+- (IBAction)showInspectorPanel:(id)sender
+{
+ if (!_inspectorPanel) {
+ [NSBundle loadNibNamed:@"Inspector" owner:self];
+ }
+ [_inspectorPanel makeKeyAndOrderFront:self];
+}
+
+
+@end
diff --git a/WebKitTools/DrawTest/DrawTestToolbarController.h b/WebKitTools/DrawTest/DrawTestToolbarController.h
new file mode 100644
index 0000000..a69fb57
--- /dev/null
+++ b/WebKitTools/DrawTest/DrawTestToolbarController.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2005 Apple Computer, 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>
+
+@class WebView;
+
+@interface DrawTestToolbarController : NSObject {
+ WebView *_drawView;
+ NSMutableDictionary *_toolbarItems;
+}
+
+- (id)initWithDrawView:(WebView *)drawView;
+
+@end
diff --git a/WebKitTools/DrawTest/DrawTestToolbarController.m b/WebKitTools/DrawTest/DrawTestToolbarController.m
new file mode 100644
index 0000000..9190252
--- /dev/null
+++ b/WebKitTools/DrawTest/DrawTestToolbarController.m
@@ -0,0 +1,354 @@
+/*
+ * Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Nefaur Khandker <nefaurk@gmail.com> All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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 "DrawTestToolbarController.h"
+
+enum
+{
+ ToolbarBrowseToolTag = 0,
+ ToolbarPanToolTag,
+ ToolbarZoomToolTag,
+
+ ToolbarPointerToolTag,
+ ToolbarLineToolTag,
+ ToolbarRectangleToolTag,
+ ToolbarElipseToolTag,
+ ToolbarTriangleToolTag,
+ ToolbarPolyLineToolTag,
+ ToolbarArcToolTag,
+
+ ToolbarDeleteSelectionTag,
+
+ ToolbarMoveForwardTag,
+ ToolbarMoveBackwardTag,
+ ToolbarMoveToFrontTag,
+ ToolbarMoveToBackTag,
+ ToolbarMiscItem
+};
+
+// Constants
+NSString *ToolbarIdentifier = @"Main Document Toolbar";
+
+NSString *ToolbarBrowseToolIdentifier = @"Browse";
+NSString *ToolbarPanToolIdentifier = @"Pan";
+NSString *ToolbarZoomToolIdentifier = @"Zoom";
+
+NSString *ToolbarPointerToolIdentifier = @"Pointer";
+NSString *ToolbarRectangleToolIdentifier = @"Rectangle";
+NSString *ToolbarElipseToolIdentifier = @"Oval";
+NSString *ToolbarTriangleToolIdentifier = @"Triangle";
+NSString *ToolbarPolyLineToolIdentifier = @"PolyLine";
+NSString *ToolbarArcToolIdentifier = @"Arc";
+
+NSString *ToolbarDeleteShapeIdentifier = @"Delete";
+NSString *ToolbarMoveForwardIdentifier = @"Forward";
+NSString *ToolbarMoveBackwardIdentifier = @"Backward";
+NSString *ToolbarMoveToFrontIdentifier = @"Front";
+NSString *ToolbarMoveToBackIdentifier = @"Back";
+
+NSString *ToolbarPointerToolImage = @"Toolbar_Pointer";
+NSString *ToolbarRectangleToolImage = @"Toolbar_Rectangle";
+NSString *ToolbarElipseToolImage = @"Toolbar_Oval";
+NSString *ToolbarTriangleToolImage = @"Toolbar_Triangle";
+
+NSString *ToolbarDeleteShapeImage = @"Toolbar_Delete";
+NSString *ToolbarMoveForwardImage = @"Toolbar_Forward";
+NSString *ToolbarMoveBackwardImage = @"Toolbar_Backward";
+NSString *ToolbarMoveToFrontImage = @"Toolbar_Front";
+NSString *ToolbarMoveToBackImage = @"Toolbar_Back";
+
+@interface DrawTestToolbarController (InternalMethods)
+- (void)setupToolbar;
+- (void)addToolbarItemWithIdentifier:(NSString *)identifier withImage:(NSString *)image withTag:(int)tag;
+- (void)addToolbarItemWithIdentifier:(NSString *)identifier withImage:(NSString *)image;
+- (void)addToolbarItem:(NSString *)identifier
+ withLabel:(NSString *)label
+ withPaletteLabel:(NSString *)paletteLabel
+ withImage:(NSString *)imageName
+ withToolTip:(NSString *)toolTip
+ withTag:(int)tag;
+@end
+
+
+@implementation DrawTestToolbarController
+
+- (id)initWithDrawView:(WebView *)drawView
+{
+ if (self = [super init]){
+ _drawView = [drawView retain];
+ [self setupToolbar]; // could be done lazily.
+ }
+ return self;
+}
+
+- (void)dealloc
+{
+ [_toolbarItems release];
+ [super dealloc];
+}
+
+
+- (void)addToolbarItemWithIdentifier:(NSString *)identifier withImage:(NSString *)image withTag:(int)tag
+{
+
+ [self addToolbarItem:identifier
+ withLabel:identifier
+ withPaletteLabel:identifier
+ withImage:image
+ withToolTip:identifier
+ withTag:tag];
+}
+
+- (void)addToolbarItemWithIdentifier:(NSString *)identifier withImage:(NSString *)image
+{
+ [self addToolbarItemWithIdentifier:identifier withImage:image withTag:ToolbarMiscItem];
+}
+
+- (void)addToolbarItem:(NSString *)identifier
+ withLabel:(NSString *)label
+ withPaletteLabel:(NSString *)paletteLabel
+ withImage:(NSString *)imageName
+ withToolTip:(NSString *)toolTip
+ withTag:(int)tag
+{
+ NSToolbarItem *item = [[[NSToolbarItem alloc] initWithItemIdentifier:identifier] autorelease];
+
+ [item setLabel:label];
+ [item setPaletteLabel:paletteLabel];
+ [item setToolTip:toolTip];
+ [item setImage:[NSImage imageNamed:imageName]];
+ [item setTarget:self];
+ [item setAction:@selector(clickedToolbarItem:)];
+ [item setTag:tag];
+
+ [_toolbarItems setObject:item forKey:identifier];
+}
+
+- (void)setupToolbar
+{
+ _toolbarItems = [[NSMutableDictionary alloc] init];
+
+ [self addToolbarItemWithIdentifier:ToolbarBrowseToolIdentifier
+ withImage:ToolbarPointerToolImage
+ withTag:ToolbarBrowseToolTag];
+ [[_toolbarItems objectForKey:ToolbarBrowseToolIdentifier] setImage:[[NSCursor pointingHandCursor] image]];
+
+ [self addToolbarItemWithIdentifier:ToolbarPanToolIdentifier
+ withImage:ToolbarPointerToolImage
+ withTag:ToolbarPanToolTag];
+ [[_toolbarItems objectForKey:ToolbarPanToolIdentifier] setImage:[[NSCursor openHandCursor] image]];
+
+ [self addToolbarItemWithIdentifier:ToolbarZoomToolIdentifier
+ withImage:ToolbarPointerToolImage
+ withTag:ToolbarZoomToolTag];
+
+
+ [self addToolbarItemWithIdentifier:ToolbarPointerToolIdentifier
+ withImage:ToolbarPointerToolImage
+ withTag:ToolbarPointerToolTag];
+
+ [self addToolbarItemWithIdentifier:ToolbarRectangleToolIdentifier
+ withImage:ToolbarRectangleToolImage
+ withTag:ToolbarRectangleToolTag];
+
+ [self addToolbarItemWithIdentifier:ToolbarElipseToolIdentifier
+ withImage:ToolbarElipseToolImage
+ withTag:ToolbarElipseToolTag];
+
+ [self addToolbarItemWithIdentifier:ToolbarTriangleToolIdentifier
+ withImage:ToolbarTriangleToolImage
+ withTag:ToolbarTriangleToolTag];
+
+ [self addToolbarItemWithIdentifier:ToolbarDeleteShapeIdentifier
+ withImage:ToolbarDeleteShapeImage
+ withTag:ToolbarDeleteSelectionTag];
+
+ [self addToolbarItemWithIdentifier:ToolbarMoveForwardIdentifier
+ withImage:ToolbarMoveForwardImage
+ withTag:ToolbarMoveForwardTag];
+
+ [self addToolbarItemWithIdentifier:ToolbarMoveBackwardIdentifier
+ withImage:ToolbarMoveBackwardImage
+ withTag:ToolbarMoveBackwardTag];
+
+ [self addToolbarItemWithIdentifier:ToolbarMoveToFrontIdentifier
+ withImage:ToolbarMoveToFrontImage
+ withTag:ToolbarMoveToFrontTag];
+
+ [self addToolbarItemWithIdentifier:ToolbarMoveToBackIdentifier
+ withImage:ToolbarMoveToBackImage
+ withTag:ToolbarMoveToBackTag];
+
+
+ NSToolbar *toolbar = [[[NSToolbar alloc] initWithIdentifier:ToolbarIdentifier] autorelease];
+
+ [toolbar setAllowsUserCustomization:YES];
+ [toolbar setAutosavesConfiguration:YES];
+ [toolbar setDisplayMode:NSToolbarDisplayModeIconAndLabel];
+ [toolbar setSizeMode:NSToolbarSizeModeSmall];
+ [toolbar setDisplayMode:NSToolbarDisplayModeLabelOnly];
+ [toolbar setDelegate:self];
+ [toolbar setSelectedItemIdentifier:ToolbarBrowseToolIdentifier];
+ [toolbar setVisible:NO];
+
+ [[_drawView window] setToolbar:toolbar];
+}
+
+
+- (void)clickedToolbarItem:(id)sender
+{
+ int tag = [sender tag];
+
+ switch(tag) {
+#if 0
+ case ToolbarBrowseToolTag:
+ [_drawView setToolMode:DrawViewToolBrowse];
+ break;
+ case ToolbarPanToolTag:
+ [_drawView setToolMode:DrawViewToolPan];
+ break;
+ case ToolbarZoomToolTag:
+ [_drawView setToolMode:DrawViewToolZoom];
+ break;
+ case ToolbarPointerToolTag:
+ [_drawView setToolMode:DrawViewToolArrow];
+ break;
+ case ToolbarRectangleToolTag:
+ [_drawView setToolMode:DrawViewToolRectangle];
+ break;
+ case ToolbarElipseToolTag:
+ [_drawView setToolMode:DrawViewToolElipse];
+ break;
+ case ToolbarTriangleToolTag:
+ [_drawView setToolMode:DrawViewToolTriangle];
+ break;
+ case ToolbarMoveForwardTag:
+ [_drawView moveSelectionForward:sender];
+ break;
+ case ToolbarMoveBackwardTag:
+ [_drawView moveSelectionBackward:sender];
+ break;
+ case ToolbarDeleteSelectionTag:
+ [_drawView deleteSelection:sender];
+ break;
+#endif
+ default:
+ NSLog(@"Toolbar item: %i not implemented!", tag);
+ }
+
+ [_drawView setNeedsDisplay:YES];
+}
+
+// NSToolbar delegate methods
+- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdent
+ willBeInsertedIntoToolbar:(BOOL)willBeInserted
+{
+ NSToolbarItem * toolbarItem = [_toolbarItems objectForKey:itemIdent];
+
+ if( toolbarItem == nil )
+ toolbarItem = [[[NSToolbarItem alloc] initWithItemIdentifier:itemIdent] autorelease];
+
+ return toolbarItem;
+}
+
+- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar
+{
+ return [NSArray arrayWithObjects:
+ ToolbarBrowseToolIdentifier,
+ ToolbarPanToolIdentifier,
+ ToolbarZoomToolIdentifier,
+ ToolbarPointerToolIdentifier,
+ ToolbarRectangleToolIdentifier,
+ ToolbarElipseToolIdentifier,
+ ToolbarTriangleToolIdentifier,
+ ToolbarDeleteShapeIdentifier,
+ NSToolbarShowColorsItemIdentifier,
+ ToolbarMoveForwardIdentifier,
+ ToolbarMoveBackwardIdentifier,
+ ToolbarMoveToFrontIdentifier,
+ ToolbarMoveToBackIdentifier,
+ NSToolbarCustomizeToolbarItemIdentifier,
+ NSToolbarFlexibleSpaceItemIdentifier,
+ NSToolbarSpaceItemIdentifier,
+ NSToolbarSeparatorItemIdentifier, nil];
+}
+
+- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar
+{
+ return [NSArray arrayWithObjects:
+ ToolbarBrowseToolIdentifier,
+ ToolbarPanToolIdentifier,
+ //ToolbarZoomToolIdentifier,
+ NSToolbarFlexibleSpaceItemIdentifier,
+ ToolbarPointerToolIdentifier,
+ ToolbarRectangleToolIdentifier,
+ ToolbarElipseToolIdentifier,
+ //ToolbarTriangleToolIdentifier,
+ //NSToolbarSeparatorItemIdentifier,
+ ToolbarDeleteShapeIdentifier,
+ //ToolbarMoveForwardIdentifier,
+ //ToolbarMoveBackwardIdentifier,
+ //ToolbarMoveToFrontIdentifier,
+ //ToolbarMoveToBackIdentifier,
+ NSToolbarSeparatorItemIdentifier,
+ //NSToolbarShowColorsItemIdentifier,
+ //NSToolbarFlexibleSpaceItemIdentifier,
+ NSToolbarCustomizeToolbarItemIdentifier,
+ nil];
+}
+
+- (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar
+{
+ return [NSArray arrayWithObjects:
+ ToolbarBrowseToolIdentifier,
+ ToolbarPanToolIdentifier,
+ ToolbarZoomToolIdentifier,
+ ToolbarPointerToolIdentifier,
+ ToolbarRectangleToolIdentifier,
+ ToolbarElipseToolIdentifier,
+ ToolbarTriangleToolIdentifier,
+ nil];
+}
+
+- (BOOL)validateToolbarItem:(NSToolbarItem *)theItem
+{
+ BOOL enabled = YES;
+
+#if 0
+ switch([theItem tag]) {
+ case ToolbarMoveForwardTag:
+ case ToolbarMoveBackwardTag:
+ case ToolbarMoveToFrontTag:
+ case ToolbarMoveToBackTag:
+ case ToolbarDeleteSelectionTag:
+ enabled = ([[_drawView selectedCanvasItems] count] != 0);
+ }
+#endif
+
+ return enabled;
+}
+
+@end
diff --git a/WebKitTools/DrawTest/DrawTestView.h b/WebKitTools/DrawTest/DrawTestView.h
new file mode 100644
index 0000000..95d5956
--- /dev/null
+++ b/WebKitTools/DrawTest/DrawTestView.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Nefaur Khandker <nefaurk@gmail.com> All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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 <WebKit/WebView.h>
+
+@interface DrawTestView : WebView
+{
+
+}
+
+- (void)setDocument:(NSURL *)documentURL;
+
+@end
diff --git a/WebKitTools/DrawTest/DrawTestView.m b/WebKitTools/DrawTest/DrawTestView.m
new file mode 100644
index 0000000..c865f99
--- /dev/null
+++ b/WebKitTools/DrawTest/DrawTestView.m
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Nefaur Khandker <nefaurk@gmail.com> All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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 <WebKit/WebFrame.h>
+
+#import "DrawTestView.h"
+
+@implementation DrawTestView
+
+- (void)setDocument:(NSURL *)documentURL
+{
+ [[self mainFrame] loadRequest:[NSURLRequest requestWithURL:documentURL]];
+}
+
+- (BOOL)acceptsFirstResponder
+{
+ return YES;
+}
+
+@end
diff --git a/WebKitTools/DrawTest/DrawTest_Prefix.pch b/WebKitTools/DrawTest/DrawTest_Prefix.pch
new file mode 100644
index 0000000..8393f01
--- /dev/null
+++ b/WebKitTools/DrawTest/DrawTest_Prefix.pch
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2005 Apple Computer, 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.
+ */
+
+//
+// Prefix header for all source files of the 'DrawTest' target in the 'DrawTest' project
+//
+
+#ifdef __OBJC__
+#import <Cocoa/Cocoa.h>
+
+#define foreacharray(__variable, __container) \
+ for (int __variable##__i=0, __variable##__n=[__container count]; \
+ __variable##__i < __variable##__n && (__variable = [__container objectAtIndex:__variable##__i]); \
+ ++__variable##__i)
+#endif
diff --git a/WebKitTools/DrawTest/English.lproj/DrawTestDocument.nib/classes.nib b/WebKitTools/DrawTest/English.lproj/DrawTestDocument.nib/classes.nib
new file mode 100644
index 0000000..296ffc3
--- /dev/null
+++ b/WebKitTools/DrawTest/English.lproj/DrawTestDocument.nib/classes.nib
@@ -0,0 +1,34 @@
+{
+ IBClasses = (
+ {
+ ACTIONS = {toggleShowDebugAxes = id; toggleShowDebugString = id; };
+ CLASS = DrawTestView;
+ LANGUAGE = ObjC;
+ SUPERCLASS = DrawView;
+ },
+ {
+ ACTIONS = {
+ deleteSelection = id;
+ moveSelectionBackward = id;
+ moveSelectionForward = id;
+ zoomIn = id;
+ zoomOriginal = id;
+ zoomOut = id;
+ zoomToFit = id;
+ };
+ CLASS = DrawView;
+ LANGUAGE = ObjC;
+ SUPERCLASS = NSView;
+ },
+ {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
+ {
+ ACTIONS = {dumpSVGToConsole = id; };
+ CLASS = MyDocument;
+ LANGUAGE = ObjC;
+ OUTLETS = {drawView = KCanvasTestView; };
+ SUPERCLASS = NSDocument;
+ },
+ {CLASS = NSSegmentedControl; LANGUAGE = ObjC; SUPERCLASS = NSControl; }
+ );
+ IBVersion = 1;
+} \ No newline at end of file
diff --git a/WebKitTools/DrawTest/English.lproj/DrawTestDocument.nib/info.nib b/WebKitTools/DrawTest/English.lproj/DrawTestDocument.nib/info.nib
new file mode 100644
index 0000000..3c96fd5
--- /dev/null
+++ b/WebKitTools/DrawTest/English.lproj/DrawTestDocument.nib/info.nib
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IBDocumentLocation</key>
+ <string>86 30 356 240 0 0 1024 746 </string>
+ <key>IBEditorPositions</key>
+ <dict>
+ <key>50</key>
+ <string>377 327 270 342 0 0 1024 746 </string>
+ </dict>
+ <key>IBFramework Version</key>
+ <string>437.0</string>
+ <key>IBOpenObjects</key>
+ <array>
+ <integer>50</integer>
+ <integer>5</integer>
+ </array>
+ <key>IBSystem Version</key>
+ <string>8C42</string>
+</dict>
+</plist>
diff --git a/WebKitTools/DrawTest/English.lproj/DrawTestDocument.nib/keyedobjects.nib b/WebKitTools/DrawTest/English.lproj/DrawTestDocument.nib/keyedobjects.nib
new file mode 100644
index 0000000..b78ff2c
--- /dev/null
+++ b/WebKitTools/DrawTest/English.lproj/DrawTestDocument.nib/keyedobjects.nib
Binary files differ
diff --git a/WebKitTools/DrawTest/English.lproj/InfoPlist.strings b/WebKitTools/DrawTest/English.lproj/InfoPlist.strings
new file mode 100644
index 0000000..0a7822d
--- /dev/null
+++ b/WebKitTools/DrawTest/English.lproj/InfoPlist.strings
Binary files differ
diff --git a/WebKitTools/DrawTest/English.lproj/Inspector.nib/classes.nib b/WebKitTools/DrawTest/English.lproj/Inspector.nib/classes.nib
new file mode 100644
index 0000000..725f5a4
--- /dev/null
+++ b/WebKitTools/DrawTest/English.lproj/Inspector.nib/classes.nib
@@ -0,0 +1,12 @@
+{
+ IBClasses = (
+ {
+ CLASS = DrawTestInspectorController;
+ LANGUAGE = ObjC;
+ OUTLETS = {"_inspectorPanel" = NSPanel; };
+ SUPERCLASS = NSObject;
+ },
+ {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }
+ );
+ IBVersion = 1;
+} \ No newline at end of file
diff --git a/WebKitTools/DrawTest/English.lproj/Inspector.nib/info.nib b/WebKitTools/DrawTest/English.lproj/Inspector.nib/info.nib
new file mode 100644
index 0000000..d930763
--- /dev/null
+++ b/WebKitTools/DrawTest/English.lproj/Inspector.nib/info.nib
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IBDocumentLocation</key>
+ <string>261 184 356 240 0 0 1024 746 </string>
+ <key>IBFramework Version</key>
+ <string>437.0</string>
+ <key>IBOpenObjects</key>
+ <array>
+ <integer>7</integer>
+ </array>
+ <key>IBSystem Version</key>
+ <string>8B9</string>
+</dict>
+</plist>
diff --git a/WebKitTools/DrawTest/English.lproj/Inspector.nib/keyedobjects.nib b/WebKitTools/DrawTest/English.lproj/Inspector.nib/keyedobjects.nib
new file mode 100644
index 0000000..02869ca
--- /dev/null
+++ b/WebKitTools/DrawTest/English.lproj/Inspector.nib/keyedobjects.nib
Binary files differ
diff --git a/WebKitTools/DrawTest/English.lproj/MainMenu.nib/classes.nib b/WebKitTools/DrawTest/English.lproj/MainMenu.nib/classes.nib
new file mode 100644
index 0000000..c0ca441
--- /dev/null
+++ b/WebKitTools/DrawTest/English.lproj/MainMenu.nib/classes.nib
@@ -0,0 +1,44 @@
+{
+ IBClasses = (
+ {
+ ACTIONS = {showImageRepTestWindow = id; showInspectorPanel = id; showTestsPanel = id; };
+ CLASS = AppDelegate;
+ LANGUAGE = ObjC;
+ OUTLETS = {svgImageRepTestWindow = NSWindow; };
+ SUPERCLASS = NSObject;
+ },
+ {
+ ACTIONS = {
+ dumpSVGToConsole = id;
+ openSelectionInViewer = id;
+ openSourceForSelection = id;
+ runWindowResizeTest = id;
+ showCompositeWindow = id;
+ showImageRepTestWindow = id;
+ showInspectorPanel = id;
+ showTestsPanel = id;
+ toggleDebugDrawer = id;
+ toggleFilterSupport = id;
+ toggleShowDebugAxes = id;
+ toggleShowDebugString = id;
+ toggleViewersScaleRule = id;
+ zoomIn = id;
+ zoomOriginal = id;
+ zoomOut = id;
+ zoomToContent = id;
+ };
+ CLASS = FirstResponder;
+ LANGUAGE = ObjC;
+ SUPERCLASS = NSObject;
+ },
+ {CLASS = KCanvasTestView; LANGUAGE = ObjC; SUPERCLASS = NSView; },
+ {
+ ACTIONS = {dumpSVGToConsole = id; };
+ CLASS = MyDocument;
+ LANGUAGE = ObjC;
+ OUTLETS = {canvasView = KCanvasTestView; };
+ SUPERCLASS = NSDocument;
+ }
+ );
+ IBVersion = 1;
+} \ No newline at end of file
diff --git a/WebKitTools/DrawTest/English.lproj/MainMenu.nib/info.nib b/WebKitTools/DrawTest/English.lproj/MainMenu.nib/info.nib
new file mode 100644
index 0000000..9b783e0
--- /dev/null
+++ b/WebKitTools/DrawTest/English.lproj/MainMenu.nib/info.nib
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IBDocumentLocation</key>
+ <string>274 58 356 240 0 0 1024 746 </string>
+ <key>IBEditorPositions</key>
+ <dict>
+ <key>29</key>
+ <string>128 678 355 44 0 0 1024 746 </string>
+ </dict>
+ <key>IBFramework Version</key>
+ <string>439.0</string>
+ <key>IBOpenObjects</key>
+ <array>
+ <integer>29</integer>
+ </array>
+ <key>IBSystem Version</key>
+ <string>8C32</string>
+</dict>
+</plist>
diff --git a/WebKitTools/DrawTest/English.lproj/MainMenu.nib/keyedobjects.nib b/WebKitTools/DrawTest/English.lproj/MainMenu.nib/keyedobjects.nib
new file mode 100644
index 0000000..642b5ae
--- /dev/null
+++ b/WebKitTools/DrawTest/English.lproj/MainMenu.nib/keyedobjects.nib
Binary files differ
diff --git a/WebKitTools/DrawTest/English.lproj/TestViewer.nib/classes.nib b/WebKitTools/DrawTest/English.lproj/TestViewer.nib/classes.nib
new file mode 100644
index 0000000..eb82ec7
--- /dev/null
+++ b/WebKitTools/DrawTest/English.lproj/TestViewer.nib/classes.nib
@@ -0,0 +1,36 @@
+{
+ IBClasses = (
+ {CLASS = DrawView; LANGUAGE = ObjC; SUPERCLASS = NSView; },
+ {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
+ {CLASS = KCanvasTestView; LANGUAGE = ObjC; SUPERCLASS = NSView; },
+ {CLASS = MyImageView; LANGUAGE = ObjC; SUPERCLASS = NSImageView; },
+ {
+ ACTIONS = {
+ browse = id;
+ jumpToParentDirectory = id;
+ openSelectionInViewer = id;
+ openSourceForSelection = id;
+ openTestViewerForSelection = id;
+ showCompositeWindow = id;
+ showTestWindow = id;
+ showTestsPanel = id;
+ toggleViewersScaleRule = id;
+ };
+ CLASS = TestController;
+ LANGUAGE = ObjC;
+ OUTLETS = {
+ "_compositeImageView" = NSImageView;
+ "_compositeWindow" = NSWindow;
+ "_parentDirectoryPopup" = NSPopUpButton;
+ "_splitView" = TestViewerSplitView;
+ "_testPanel" = NSPanel;
+ "_testWindow" = NSWindow;
+ "_testsArrayController" = NSArrayController;
+ "_testsTableView" = NSTableView;
+ };
+ SUPERCLASS = NSObject;
+ },
+ {CLASS = TestViewerSplitView; LANGUAGE = ObjC; SUPERCLASS = NSView; }
+ );
+ IBVersion = 1;
+} \ No newline at end of file
diff --git a/WebKitTools/DrawTest/English.lproj/TestViewer.nib/info.nib b/WebKitTools/DrawTest/English.lproj/TestViewer.nib/info.nib
new file mode 100644
index 0000000..ca801e8
--- /dev/null
+++ b/WebKitTools/DrawTest/English.lproj/TestViewer.nib/info.nib
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IBDocumentLocation</key>
+ <string>263 119 356 240 0 0 1024 746 </string>
+ <key>IBFramework Version</key>
+ <string>437.0</string>
+ <key>IBOpenObjects</key>
+ <array>
+ <integer>24</integer>
+ <integer>60</integer>
+ </array>
+ <key>IBSystem Version</key>
+ <string>8C26</string>
+</dict>
+</plist>
diff --git a/WebKitTools/DrawTest/English.lproj/TestViewer.nib/keyedobjects.nib b/WebKitTools/DrawTest/English.lproj/TestViewer.nib/keyedobjects.nib
new file mode 100644
index 0000000..46b8964
--- /dev/null
+++ b/WebKitTools/DrawTest/English.lproj/TestViewer.nib/keyedobjects.nib
Binary files differ
diff --git a/WebKitTools/DrawTest/Info.plist b/WebKitTools/DrawTest/Info.plist
new file mode 100644
index 0000000..0fd092b
--- /dev/null
+++ b/WebKitTools/DrawTest/Info.plist
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleDocumentTypes</key>
+ <array>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>svg</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>SVG Document</string>
+ <key>CFBundleTypeOSTypes</key>
+ <array>
+ <string>????</string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Editor</string>
+ <key>LSTypeIsPackage</key>
+ <false/>
+ <key>NSDocumentClass</key>
+ <string>DrawTestDocument</string>
+ <key>NSPersistentStoreTypeKey</key>
+ <string>Binary</string>
+ </dict>
+ </array>
+ <key>CFBundleExecutable</key>
+ <string>DrawTest</string>
+ <key>CFBundleGetInfoString</key>
+ <string>420+, Copyright 2005, 2006 Apple Computer, Inc.</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.apple.DrawTest</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>NSMainNibFile</key>
+ <string>MainMenu</string>
+ <key>NSPrincipalClass</key>
+ <string>NSApplication</string>
+</dict>
+</plist>
diff --git a/WebKitTools/DrawTest/SVGTest.h b/WebKitTools/DrawTest/SVGTest.h
new file mode 100644
index 0000000..70eed41
--- /dev/null
+++ b/WebKitTools/DrawTest/SVGTest.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Nefaur Khandker <nefaurk@gmail.com> All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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>
+
+@interface SVGTest : NSObject {
+ NSString *_svgPath;
+ NSString *_imagePath;
+
+ NSImage *_image;
+ NSImage *_compositeImage;
+ BOOL _hasPassed;
+}
+
++ (id)testWithSVGPath:(NSString *)svgPath imagePath:(NSString *)imagePath;
+- (id)initWithSVGPath:(NSString *)svgPath imagePath:(NSString *)imagePath;
+
+- (NSString *)imagePath;
+- (NSString *)svgPath;
+
+- (NSImage *)image;
+- (NSImage *)compositeImage;
+- (NSString *)name;
+
+@end
diff --git a/WebKitTools/DrawTest/SVGTest.m b/WebKitTools/DrawTest/SVGTest.m
new file mode 100644
index 0000000..4ea562d
--- /dev/null
+++ b/WebKitTools/DrawTest/SVGTest.m
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Nefaur Khandker <nefaurk@gmail.com> All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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 "SVGTest.h"
+
+#import <WebKit/WebView.h>
+
+@implementation SVGTest
+
++ (id)testWithSVGPath:(NSString *)svgPath imagePath:(NSString *)imagePath
+{
+ SVGTest *test = [[self alloc] initWithSVGPath:svgPath imagePath:imagePath];
+ return [test autorelease];
+}
+
+static WebView *__sharedDrawView = nil;
++ (WebView *)sharedDrawView
+{
+ if (!__sharedDrawView) {
+ __sharedDrawView = [[WebView alloc] initWithFrame:NSMakeRect(0,0,0,0)];
+ }
+ return __sharedDrawView;
+}
+
+- (id)initWithSVGPath:(NSString *)svgPath imagePath:(NSString *)imagePath
+{
+ if (self = [super init]) {
+ _svgPath = [svgPath copy];
+ _imagePath = [imagePath copy];
+ }
+ return self;
+}
+
+- (NSString *)imagePath
+{
+ return _imagePath;
+}
+
+- (NSString *)svgPath
+{
+ return _svgPath;
+}
+
+- (NSImage *)image
+{
+ if (!_image && _imagePath) {
+ _image = [[NSImage alloc] initByReferencingFile:_imagePath];
+ }
+ return _image;
+}
+
+- (NSString *)name
+{
+ NSMutableString *name = [[[[_svgPath lastPathComponent] stringByDeletingPathExtension] mutableCopy] autorelease];
+ [name replaceOccurrencesOfString:@"_" withString:@" " options:0 range:NSMakeRange(0, [name length])];
+ return [name capitalizedString];
+}
+
+- (void)generateCompositeIfNecessary
+{
+ if (!_compositeImage) {
+ WebView *view = [SVGTest sharedDrawView];
+ NSSize svgSize = [view bounds].size;
+
+ NSImage *image = [self image];
+ NSSize imageSize = [image size];
+
+ NSBitmapImageRep *svgImage = [view bitmapImageRepForCachingDisplayInRect:[view bounds]];
+ [view cacheDisplayInRect:[view bounds] toBitmapImageRep:svgImage];
+
+ NSSize unionSize = NSMakeSize(MAX(svgSize.width, imageSize.width), MAX(svgSize.height, imageSize.height));
+ _compositeImage = [[NSImage alloc] initWithSize:unionSize];
+
+ [_compositeImage lockFocus];
+ [svgImage drawInRect:NSMakeRect(0,0,svgSize.width,svgSize.height)];
+ [image drawInRect:NSMakeRect(0,0,imageSize.width,imageSize.height)
+ fromRect:NSMakeRect(0,0,imageSize.width,imageSize.height)
+ operation:NSCompositeXOR fraction:1.0];
+ [_compositeImage unlockFocus];
+ }
+}
+
+- (NSImage *)compositeImage
+{
+ [self generateCompositeIfNecessary];
+ return _compositeImage;
+}
+
+
+@end
diff --git a/WebKitTools/DrawTest/ScalingImageView.h b/WebKitTools/DrawTest/ScalingImageView.h
new file mode 100644
index 0000000..4370ff5
--- /dev/null
+++ b/WebKitTools/DrawTest/ScalingImageView.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2005 Apple Computer, 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>
+
+
+@interface ScalingImageView : NSImageView {
+
+}
+
+@end
diff --git a/WebKitTools/DrawTest/ScalingImageView.m b/WebKitTools/DrawTest/ScalingImageView.m
new file mode 100644
index 0000000..605397a
--- /dev/null
+++ b/WebKitTools/DrawTest/ScalingImageView.m
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2005 Apple Computer, 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 "ScalingImageView.h"
+
+@implementation ScalingImageView
+
+/*
+ This class offers two behaviors different from the standard NSImageView
+ (and which were not available w/o subclassing)
+ 1. Scale an image proportionally up to fit a larger view (NSImageView refuses)
+ 2. Draw a background color w/o needing to show a bezel.
+*/
+
+- (void)drawRect:(NSRect)dirtyRect
+{
+ [[NSColor whiteColor] set];
+ NSRectFill(dirtyRect);
+
+ NSSize imageSize = [[self image] size];
+ float scale = 1.0f;
+ if ([self imageScaling] == NSScaleProportionally && imageSize.width && imageSize.height) {
+ float widthScale = [self bounds].size.width / imageSize.width;
+ float heightScale = [self bounds].size.height / imageSize.height;
+ scale = MIN(widthScale, heightScale);
+ }
+
+ float scaledHeight = imageSize.height * scale;
+ NSRect destRect = NSMakeRect(0,[self bounds].size.height - scaledHeight,imageSize.width * scale, scaledHeight);
+ [[self image] drawInRect:destRect
+ fromRect:NSMakeRect(0,0,imageSize.width, imageSize.height) operation:NSCompositeSourceOver fraction:1.0];
+}
+
+@end
diff --git a/WebKitTools/DrawTest/TestController.h b/WebKitTools/DrawTest/TestController.h
new file mode 100644
index 0000000..1e781fe
--- /dev/null
+++ b/WebKitTools/DrawTest/TestController.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Nefaur Khandker <nefaurk@gmail.com> All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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>
+
+@class DrawTestView;
+@class SVGTest;
+@class TestViewerSplitView;
+
+@interface TestController : NSObject {
+ IBOutlet NSPanel *_testPanel;
+ IBOutlet NSWindow *_testWindow;
+ IBOutlet TestViewerSplitView *_splitView;
+
+ IBOutlet NSArrayController *_testsArrayController;
+ IBOutlet NSPopUpButton *_parentDirectoryPopup;
+ IBOutlet NSTableView *_testsTableView;
+
+ IBOutlet NSWindow *_compositeWindow;
+ IBOutlet NSImageView *_compositeImageView;
+
+@private
+ NSString *_currentPath;
+ NSArray *_tests;
+ SVGTest *_selectedTest;
+
+ DrawTestView *_drawView;
+ NSImageView *_imageView;
+}
+
++ (id)sharedController;
+
+- (IBAction)showTestsPanel:(id)sender;
+- (IBAction)showTestWindow:(id)sender;
+- (IBAction)showCompositeWindow:(id)sender;
+
+- (IBAction)browse:(id)sender;
+- (IBAction)jumpToParentDirectory:(id)sender;
+- (IBAction)openTestViewerForSelection:(id)sender;
+- (IBAction)openSourceForSelection:(id)sender;
+- (IBAction)openSelectionInViewer:(id)sender;
+- (IBAction)toggleViewersScaleRule:(id)sender;
+
+- (NSArray *)tests;
+- (NSString *)currentPath;
+- (void)setCurrentPath:(NSString *)newPath;
+- (NSArray *)directoryHierarchy;
+
+@end
diff --git a/WebKitTools/DrawTest/TestController.m b/WebKitTools/DrawTest/TestController.m
new file mode 100644
index 0000000..506920b
--- /dev/null
+++ b/WebKitTools/DrawTest/TestController.m
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Nefaur Khandker <nefaurk@gmail.com> All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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 "TestController.h"
+#import "SVGTest.h"
+#import "TestViewerSplitView.h"
+#import "ScalingImageView.h"
+#import "DrawTestView.h"
+
+#import <WebKit/WebView.h>
+
+@interface NSArray (TestControllerAdditions)
+- (id)firstObject;
+@end
+
+@implementation NSArray (TestControllerAdditions)
+- (id)firstObject
+{
+ if ([self count])
+ return [self objectAtIndex:0];
+ return nil;
+}
+@end
+
+static TestController *__sharedInstance = nil;
+
+@implementation TestController
+
+- (id)init
+{
+ if (self = [super init]) {
+ NSString *path = [[NSUserDefaults standardUserDefaults] objectForKey:@"TestDirectory"];
+ BOOL isDirectory = NO;
+ if (![[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDirectory] || !isDirectory) {
+ path = [@"~" stringByStandardizingPath];
+ }
+ [self setCurrentPath:path];
+ }
+ return self;
+}
+
++ (void)initialize
+{
+ [self setKeys:[NSArray arrayWithObject:@"currentPath"] triggerChangeNotificationsForDependentKey:@"directoryHierarchy"];
+ [self setKeys:[NSArray arrayWithObject:@"currentPath"] triggerChangeNotificationsForDependentKey:@"tests"];
+}
+
++ (id)sharedController
+{
+ if (!__sharedInstance) {
+ __sharedInstance = [[self alloc] init];
+ }
+ return __sharedInstance;
+}
+
+- (void)loadNibIfNecessary
+{
+ if (!_testPanel) {
+ [NSBundle loadNibNamed:@"TestViewer" owner:self];
+ }
+}
+
+- (void)awakeFromNib
+{
+ [_testsTableView setTarget:self];
+ [_testsTableView setDoubleAction:@selector(openTestViewerForSelection:)];
+ _drawView = [[DrawTestView alloc] initWithFrame:NSZeroRect];
+ _imageView = [[ScalingImageView alloc] initWithFrame:NSZeroRect];
+ [_splitView addSubview:_drawView];
+ [_splitView addSubview:_imageView];
+}
+
+- (IBAction)showTestsPanel:(id)sender
+{
+ [self loadNibIfNecessary];
+ [_testPanel makeKeyAndOrderFront:sender];
+}
+
+- (IBAction)showTestWindow:(id)sender
+{
+ [self loadNibIfNecessary];
+ [_testWindow makeKeyAndOrderFront:sender];
+}
+
+- (IBAction)showCompositeWindow:(id)sender
+{
+ [self loadNibIfNecessary];
+ NSLog(@"showCompositeWindow: %@", _compositeWindow);
+ [_compositeWindow makeKeyAndOrderFront:sender];
+}
+
+- (IBAction)browse:(id)sender
+{
+ NSOpenPanel *openPanel = [NSOpenPanel openPanel];
+ [openPanel setCanChooseDirectories:YES];
+ [openPanel setCanChooseFiles:NO];
+ [openPanel beginSheetForDirectory:nil file:nil modalForWindow:_testPanel modalDelegate:self didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:) contextInfo:NULL];
+}
+
+- (void)openPanelDidEnd:(NSOpenPanel *)openPanel returnCode:(int)returnCode contextInfo:(void *)contextInfo
+{
+ if (returnCode == NSOKButton) {
+ NSArray *folders = [openPanel filenames];
+ NSString *selectedFolder = [folders firstObject];
+ [self setCurrentPath:selectedFolder];
+ }
+}
+
+- (IBAction)jumpToParentDirectory:(id)sender
+{
+ int index = [_parentDirectoryPopup indexOfSelectedItem];
+ NSArray *components = [_currentPath pathComponents];
+ NSArray *newComponents = [components subarrayWithRange:NSMakeRange(0, [components count] - index)];
+ NSString *newPath = [NSString pathWithComponents:newComponents];
+ [self setCurrentPath:newPath];
+}
+
+- (void)setSelectedTest:(SVGTest *)selectedTest
+{
+ id oldTest = _selectedTest;
+ _selectedTest = [selectedTest retain];
+ [oldTest release];
+
+ if ([_testWindow isVisible]) {
+ [_testWindow setTitle:[NSString stringWithFormat:@"Test Viewer - %@", [_selectedTest name]]];
+ [_drawView setDocument:[NSURL fileURLWithPath:[_selectedTest svgPath]]];
+ [_imageView setImage:[_selectedTest image]];
+ if ([_compositeWindow isVisible])
+ [_compositeImageView setImage:[_selectedTest compositeImage]];
+ }
+}
+
+- (void)tableViewSelectionDidChange:(NSNotification *)aNotification
+{
+ [self setSelectedTest:[[_testsArrayController selectedObjects] firstObject]];
+}
+
+- (IBAction)openTestViewerForSelection:(id)sender
+{
+ [self showTestWindow:sender];
+ [_drawView setDocument:[NSURL fileURLWithPath:[_selectedTest svgPath]]];
+ [_imageView setImage:[_selectedTest image]];
+}
+
+- (IBAction)openSourceForSelection:(id)sender
+{
+ [[NSWorkspace sharedWorkspace] openFile:[_selectedTest svgPath] withApplication:@"TextEdit"];
+}
+
+- (IBAction)openSelectionInViewer:(id)sender
+{
+ [[NSWorkspace sharedWorkspace] openFile:[_selectedTest svgPath]];
+}
+
+- (NSString *)imagePathForSVGPath:(NSString *)svgPath
+{
+ // eventually this code will build an array instead...
+
+ NSString *currentDirectory = [self currentPath];
+ NSString *parentDirectory = [currentDirectory stringByDeletingLastPathComponent];
+
+ NSString *testName = [[svgPath lastPathComponent] stringByDeletingPathExtension];
+ NSString *imageName, *imageDirectory, *imagePath;
+
+ // first look in ../png/test.png -- SVG 1.1 baselines
+ // The SVG 1.1 spec has various different pngs, we should allow the
+ // tester to choose...
+ imageName = [[@"full-" stringByAppendingString:testName] stringByAppendingPathExtension:@"png"];
+ imageDirectory = [parentDirectory stringByAppendingPathComponent:@"png"];
+ imagePath = [imageDirectory stringByAppendingPathComponent:imageName];
+ if ([[NSFileManager defaultManager] fileExistsAtPath:imagePath]) return imagePath;
+
+ // then look for ../name.png -- openclipart.org
+ imageName = [testName stringByAppendingPathExtension:@"png"];
+ imageDirectory = parentDirectory;
+ imagePath = [imageDirectory stringByAppendingPathComponent:imageName];
+ if ([[NSFileManager defaultManager] fileExistsAtPath:imagePath]) return imagePath;
+
+ // then look for ./name-w3c.png -- WebCore tests
+ imageName = [[testName stringByAppendingString:@"-w3c"] stringByAppendingPathExtension:@"png"];
+ imageDirectory = currentDirectory;
+ imagePath = [imageDirectory stringByAppendingPathComponent:imageName];
+ if ([[NSFileManager defaultManager] fileExistsAtPath:imagePath]) return imagePath;
+
+ // finally try name-baseline.png -- ksvg regression baselines
+ imageName = [[testName stringByAppendingString:@"-baseline"] stringByAppendingPathExtension:@"png"];
+ imageDirectory = currentDirectory;
+ imagePath = [imageDirectory stringByAppendingPathComponent:imageName];
+ if ([[NSFileManager defaultManager] fileExistsAtPath:imagePath]) return imagePath;
+
+ return nil;
+}
+
+- (NSArray *)tests
+{
+ if (!_tests) {
+ NSMutableArray *newTests = [[NSMutableArray alloc] init];
+ NSArray *files = [[NSFileManager defaultManager] directoryContentsAtPath:[self currentPath]];
+ NSString *file = nil;
+ foreacharray(file, files) {
+ if ([[file pathExtension] isEqualToString:@"svg"]) {
+ NSString *svgPath = [[self currentPath] stringByAppendingPathComponent:file];
+ NSString *imagePath = [self imagePathForSVGPath:svgPath];
+ [newTests addObject:[SVGTest testWithSVGPath:svgPath imagePath:imagePath]];
+ }
+ }
+ [self setValue:newTests forKey:@"tests"];
+ }
+ return _tests;
+}
+
+- (NSArray *)directoryHierarchy
+{
+ // A hackish way to reverse an array.
+ return [[[_currentPath pathComponents] reverseObjectEnumerator] allObjects];
+}
+
+- (NSString *)currentPath
+{
+ return _currentPath;
+}
+
+- (void)setCurrentPath:(NSString *)newPath
+{
+ if (![newPath isEqualToString:_currentPath]) {
+ [_currentPath release];
+ _currentPath = [newPath copy];
+ [self setValue:nil forKey:@"tests"];
+ }
+
+ [[NSUserDefaults standardUserDefaults] setObject:_currentPath forKey:@"TestDirectory"];
+}
+
+- (IBAction)toggleViewersScaleRule:(id)sender
+{
+#if 0
+ if ([_drawView imageScaling] == NSScaleProportionally) {
+ [_drawView setImageScaling:NSScaleNone];
+ [_imageView setImageScaling:NSScaleNone];
+ } else {
+ [_drawView setImageScaling:NSScaleProportionally];
+ [_imageView setImageScaling:NSScaleProportionally];
+ }
+#endif
+}
+
+@end
diff --git a/WebKitTools/DrawTest/TestViewerSplitView.h b/WebKitTools/DrawTest/TestViewerSplitView.h
new file mode 100644
index 0000000..e663f23
--- /dev/null
+++ b/WebKitTools/DrawTest/TestViewerSplitView.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2005 Apple Computer, 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>
+
+@interface TestViewerSplitView : NSView {
+ NSMutableArray *subviewLabels;
+}
+
+@end
diff --git a/WebKitTools/DrawTest/TestViewerSplitView.m b/WebKitTools/DrawTest/TestViewerSplitView.m
new file mode 100644
index 0000000..96f2055
--- /dev/null
+++ b/WebKitTools/DrawTest/TestViewerSplitView.m
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2005 Apple Computer, 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 "TestViewerSplitView.h"
+
+@implementation TestViewerSplitView
+
+- (void)drawRect:(NSRect)rect
+{
+ NSArray *subviews = [self subviews];
+ int subviewCount = [subviews count];
+ for (int x=0; x < subviewCount; x++) {
+ NSView *subview = [subviews objectAtIndex:x];
+ [subview drawRect:rect];
+#if 0
+ NSString *label = [subviewLabels objectAtIndex:0];
+ [label drawAtPoint:[subview frame].origin withAttributes:NULL];
+#endif
+ }
+}
+
+- (void)retileSubviews
+{
+ NSRect bounds = [self bounds];
+ NSArray *subviews = [self subviews];
+ int subviewCount = [subviews count];
+ if (!subviewCount) return;
+ float subviewWidth = bounds.size.width / subviewCount;
+
+ for (int x=0; x < subviewCount; x++) {
+ [[subviews objectAtIndex:x] setFrame:NSMakeRect(x * subviewWidth, 0, subviewWidth, bounds.size.height)];
+ }
+}
+
+- (void)didAddSubview:(NSView *)subview
+{
+ [super didAddSubview:subview];
+ [self retileSubviews];
+}
+
+- (void)willRemoveSubview:(NSView *)subview
+{
+ [super willRemoveSubview:subview];
+ [self retileSubviews];
+}
+
+- (void)setFrame:(NSRect)newFrame
+{
+ // ideally we also want to catch when the bounds changes without the
+ // frame changing, but we're not bothering with that now - ECS 7/29/05
+ [super setFrame:newFrame];
+ [self retileSubviews];
+}
+
+@end
diff --git a/WebKitTools/DrawTest/main.m b/WebKitTools/DrawTest/main.m
new file mode 100644
index 0000000..90337b6
--- /dev/null
+++ b/WebKitTools/DrawTest/main.m
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2005 Apple Computer, 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.
+ */
+
+int main (int argc, const char *argv[])
+{
+ return NSApplicationMain(argc, argv);
+}
diff --git a/WebKitTools/Drosera/DebuggerDocument.cpp b/WebKitTools/Drosera/DebuggerDocument.cpp
new file mode 100644
index 0000000..f5dbf87
--- /dev/null
+++ b/WebKitTools/Drosera/DebuggerDocument.cpp
@@ -0,0 +1,364 @@
+/*
+ * 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 "DebuggerDocument.h"
+
+#include "ServerConnection.h"
+
+#include <JavaScriptCore/JSContextRef.h>
+#include <JavaScriptCore/JSRetainPtr.h>
+#include <JavaScriptCore/JSStringRefCF.h>
+#include <JavaScriptCore/RetainPtr.h>
+
+DebuggerDocument::DebuggerDocument(ServerConnection* serverConn)
+ : m_server(serverConn)
+{
+ ASSERT(m_server);
+}
+
+//-- Callbacks
+
+JSValueRef DebuggerDocument::breakpointEditorHTMLCallback(JSContextRef context, JSObjectRef /*function*/, JSObjectRef /*thisObject*/, size_t /*argumentCount*/, const JSValueRef /*arguments*/[], JSValueRef* /*exception*/)
+{
+ RetainPtr<CFURLRef> htmlURLRef(AdoptCF, ::CFBundleCopyResourceURL(::CFBundleGetBundleWithIdentifier(CFSTR("org.webkit.drosera")), CFSTR("breakpointEditor"), CFSTR("html"), 0));
+ if (!htmlURLRef)
+ return JSValueMakeUndefined(context);
+
+ // FIXME: I'm open to a better way to do this. We convert from UInt8 to CFString to JSString (3 string types!)
+ RetainPtr<CFReadStreamRef> readStreamRef(AdoptCF, CFReadStreamCreateWithFile(0, htmlURLRef.get()));
+ CFReadStreamRef readStream = readStreamRef.get();
+
+ if (!CFReadStreamOpen(readStream))
+ return JSValueMakeUndefined(context);
+
+ // Large enough for current BreakPointEditor.html but won't need to be changed if that file changes
+ // because we loop over the entire file and read it in bufferLength pieces at a time
+ const CFIndex bufferLength = 740;
+ UInt8 buffer[bufferLength];
+ Vector<UInt8, bufferLength> charBuffer;
+ CFIndex readResult = bufferLength;
+ while (readResult == bufferLength) {
+ readResult = CFReadStreamRead(readStream, buffer, bufferLength);
+
+ // Error condition (-1) will not copy any data
+ for (int i = 0; i < readResult; i++)
+ charBuffer.append(buffer[i]);
+ }
+
+ CFReadStreamClose(readStream);
+ if (readResult == -1)
+ return JSValueMakeUndefined(context);
+
+ // FIXME: Is there a way to determine the encoding?
+ RetainPtr<CFStringRef> fileContents(AdoptCF, CFStringCreateWithBytes(0, charBuffer.data(), charBuffer.size(), kCFStringEncodingUTF8, true));
+ JSRetainPtr<JSStringRef> fileContentsJS(Adopt, JSStringCreateWithCFString(fileContents.get()));
+ JSValueRef ret = JSValueMakeString(context, fileContentsJS.get());
+
+ return ret;
+}
+
+JSValueRef DebuggerDocument::pauseCallback(JSContextRef context, JSObjectRef /*function*/, JSObjectRef thisObject, size_t /*argumentCount*/, const JSValueRef /*arguments*/[], JSValueRef* /*exception*/)
+{
+ DebuggerDocument* debuggerDocument = reinterpret_cast<DebuggerDocument*>(JSObjectGetPrivate(thisObject));
+
+ debuggerDocument->platformPause();
+ return JSValueMakeUndefined(context);
+}
+
+JSValueRef DebuggerDocument::resumeCallback(JSContextRef context, JSObjectRef /*function*/, JSObjectRef thisObject, size_t /*argumentCount*/, const JSValueRef /*arguments*/[], JSValueRef* /*exception*/)
+{
+ DebuggerDocument* debuggerDocument = reinterpret_cast<DebuggerDocument*>(JSObjectGetPrivate(thisObject));
+ debuggerDocument->platformResume();
+ return JSValueMakeUndefined(context);
+}
+
+JSValueRef DebuggerDocument::stepIntoCallback(JSContextRef context, JSObjectRef /*function*/, JSObjectRef thisObject, size_t /*argumentCount*/, const JSValueRef /*arguments*/[], JSValueRef* /*exception*/)
+{
+ DebuggerDocument* debuggerDocument = reinterpret_cast<DebuggerDocument*>(JSObjectGetPrivate(thisObject));
+ debuggerDocument->platformStepInto();
+ return JSValueMakeUndefined(context);
+}
+
+JSValueRef DebuggerDocument::evaluateScriptCallback(JSContextRef context, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ DebuggerDocument* debuggerDocument = reinterpret_cast<DebuggerDocument*>(JSObjectGetPrivate(thisObject));
+ if (argumentCount < 2)
+ return JSValueMakeUndefined(context);
+
+ if (!JSValueIsNumber(context, arguments[1]))
+ return JSValueMakeUndefined(context);
+
+ double callFrame = JSValueToNumber(context, arguments[1], exception);
+ ASSERT(!*exception);
+
+ JSRetainPtr<JSStringRef> script(Adopt, JSValueToStringCopy(context, arguments[0], exception));
+ ASSERT(!*exception);
+
+ JSValueRef ret = debuggerDocument->platformEvaluateScript(context, script.get(), (int)callFrame);
+
+ return ret;
+}
+
+JSValueRef DebuggerDocument::currentFunctionStackCallback(JSContextRef context, JSObjectRef /*function*/, JSObjectRef thisObject, size_t /*argumentCount*/, const JSValueRef /*arguments*/[], JSValueRef* exception)
+{
+ DebuggerDocument* debuggerDocument = reinterpret_cast<DebuggerDocument*>(JSObjectGetPrivate(thisObject));
+ Vector<JSValueRef> stack;
+ debuggerDocument->getPlatformCurrentFunctionStack(context, stack);
+ return DebuggerDocument::toJSArray(context, stack, exception);
+}
+
+JSValueRef DebuggerDocument::localScopeVariableNamesForCallFrameCallback(JSContextRef context, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ DebuggerDocument* debuggerDocument = reinterpret_cast<DebuggerDocument*>(JSObjectGetPrivate(thisObject));
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ if (!JSValueIsNumber(context, arguments[0]))
+ return JSValueMakeUndefined(context);
+
+ double callFrame = JSValueToNumber(context, arguments[0], exception);
+ ASSERT(!*exception);
+
+ // Get the variable names
+ Vector<JSValueRef> localVariableNames;
+
+ debuggerDocument->getPlatformLocalScopeVariableNamesForCallFrame(context, static_cast<int>(callFrame), localVariableNames);
+ return DebuggerDocument::toJSArray(context, localVariableNames, exception);
+}
+
+JSValueRef DebuggerDocument::valueForScopeVariableNamedCallback(JSContextRef context, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ DebuggerDocument* debuggerDocument = reinterpret_cast<DebuggerDocument*>(JSObjectGetPrivate(thisObject));
+
+ if (argumentCount < 2)
+ return JSValueMakeUndefined(context);
+
+ if (!JSValueIsString(context, arguments[0]))
+ return JSValueMakeUndefined(context);
+
+ JSRetainPtr<JSStringRef> key(Adopt, JSValueToStringCopy(context, arguments[0], exception));
+ ASSERT(!*exception);
+
+ if (!JSValueIsNumber(context, arguments[1]))
+ return JSValueMakeUndefined(context);
+
+ double callFrame = JSValueToNumber(context, arguments[1], exception);
+ ASSERT(!*exception);
+
+ return debuggerDocument->platformValueForScopeVariableNamed(context, key.get(), (int)callFrame);
+}
+
+JSValueRef DebuggerDocument::logCallback(JSContextRef context, JSObjectRef /*function*/, JSObjectRef /*thisObject*/, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ if (!JSValueIsString(context, arguments[0]))
+ return JSValueMakeUndefined(context);
+
+ JSRetainPtr<JSStringRef> msg(Adopt, JSValueToStringCopy(context, arguments[0], exception));
+ ASSERT(!*exception);
+
+ DebuggerDocument::platformLog(msg.get());
+ return JSValueMakeUndefined(context);
+}
+
+//-- These are the calls into the JS. --//
+
+bool DebuggerDocument::isPaused(JSContextRef context) const
+{
+ JSObjectRef globalObject = JSContextGetGlobalObject(context);
+ JSRetainPtr<JSStringRef> string(Adopt, JSStringCreateWithUTF8CString("isPaused"));
+ JSValueRef objectProperty = JSObjectGetProperty(context, globalObject, string.get(), 0);
+ return JSValueToBoolean(context, objectProperty);
+}
+
+void DebuggerDocument::updateFileSource(JSContextRef context, JSStringRef documentSource, JSStringRef url)
+{
+ JSValueRef documentSourceValue = JSValueMakeString(context, documentSource);
+ JSValueRef urlValue = JSValueMakeString(context, url);
+ JSValueRef forceValue = JSValueMakeBoolean(context, true);
+
+ JSValueRef arguments[] = { documentSourceValue, urlValue, forceValue };
+ int argumentsSize = sizeof(arguments)/sizeof(arguments[0]);
+
+ DebuggerDocument::callGlobalFunction(context, "updateFileSource", argumentsSize, arguments);
+}
+
+void DebuggerDocument::didParseScript(JSContextRef context, JSStringRef source, JSStringRef documentSource, JSStringRef url, JSValueRef sourceId, JSValueRef baseLine)
+{
+ JSValueRef sourceValue = JSValueMakeString(context, source);
+ JSValueRef documentSourceValue = JSValueMakeString(context, documentSource);
+ JSValueRef urlValue = JSValueMakeString(context, url);
+
+ JSValueRef arguments[] = { sourceValue, documentSourceValue, urlValue, sourceId, baseLine };
+ int argumentsSize = sizeof(arguments)/sizeof(arguments[0]);
+
+ DebuggerDocument::callGlobalFunction(context, "didParseScript", argumentsSize, arguments);
+}
+
+void DebuggerDocument::willExecuteStatement(JSContextRef context, JSValueRef sourceId, JSValueRef lineno, JSValueRef* exception)
+{
+ JSValueRef arguments[] = { sourceId, lineno };
+ int argumentsSize = sizeof(arguments)/sizeof(arguments[0]);
+
+ DebuggerDocument::callGlobalFunction(context, "willExecuteStatement", argumentsSize, arguments, exception);
+ if (exception && *exception)
+ logException(context, *exception);
+}
+
+void DebuggerDocument::didEnterCallFrame(JSContextRef context, JSValueRef sourceId, JSValueRef lineno, JSValueRef* exception)
+{
+ JSValueRef arguments[] = { sourceId, lineno };
+ int argumentsSize = sizeof(arguments)/sizeof(arguments[0]);
+
+ DebuggerDocument::callGlobalFunction(context, "didEnterCallFrame", argumentsSize, arguments, exception);
+ if (exception && *exception)
+ logException(context, *exception);
+}
+
+void DebuggerDocument::willLeaveCallFrame(JSContextRef context, JSValueRef sourceId, JSValueRef lineno, JSValueRef* exception)
+{
+ JSValueRef arguments[] = { sourceId, lineno };
+ int argumentsSize = sizeof(arguments)/sizeof(arguments[0]);
+
+ DebuggerDocument::callGlobalFunction(context, "willLeaveCallFrame", argumentsSize, arguments, exception);
+ if (exception && *exception)
+ logException(context, *exception);
+}
+
+void DebuggerDocument::exceptionWasRaised(JSContextRef context, JSValueRef sourceId, JSValueRef lineno, JSValueRef* exception)
+{
+ JSValueRef arguments[] = { sourceId, lineno };
+ int argumentsSize = sizeof(arguments)/sizeof(arguments[0]);
+
+ DebuggerDocument::callGlobalFunction(context, "exceptionWasRaised", argumentsSize, arguments, exception);
+}
+
+void DebuggerDocument::windowScriptObjectAvailable(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> droseraStr(Adopt, JSStringCreateWithUTF8CString("DebuggerDocument"));
+ JSValueRef droseraObject = JSObjectMake(context, getDroseraJSClass(), this);
+
+ JSObjectSetProperty(context, windowObject, droseraStr.get(), droseraObject, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, exception);
+ if (exception && *exception)
+ logException(context, *exception);
+}
+
+JSValueRef DebuggerDocument::toJSArray(JSContextRef context, Vector<JSValueRef>& vectorValues, JSValueRef* exception)
+{
+ JSObjectRef globalObject = JSContextGetGlobalObject(context);
+ JSRetainPtr<JSStringRef> constructorString(Adopt, JSStringCreateWithUTF8CString("Array"));
+ JSValueRef constructorProperty = JSObjectGetProperty(context, globalObject, constructorString.get(), exception);
+ ASSERT(!*exception);
+
+ JSObjectRef arrayConstructor = JSValueToObject(context, constructorProperty, exception);
+ ASSERT(!*exception);
+
+ JSObjectRef array = JSObjectCallAsConstructor(context, arrayConstructor, 0, 0, exception);
+ ASSERT(!*exception);
+
+ JSRetainPtr<JSStringRef> pushString(Adopt, JSStringCreateWithUTF8CString("push"));
+ JSValueRef pushValue = JSObjectGetProperty(context, array, pushString.get(), exception);
+ ASSERT(!*exception);
+
+ JSObjectRef push = JSValueToObject(context, pushValue, exception);
+ ASSERT(!*exception);
+
+ for (Vector<JSValueRef>::iterator it = vectorValues.begin(); it != vectorValues.end(); ++it) {
+ JSObjectCallAsFunction(context, push, array, 1, it, exception);
+ ASSERT(!*exception);
+ }
+
+ return array;
+}
+
+// Private
+JSValueRef DebuggerDocument::callGlobalFunction(JSContextRef context, const char* functionName, int argumentCount, JSValueRef arguments[], JSValueRef* exception)
+{
+ JSObjectRef globalObject = JSContextGetGlobalObject(context);
+ return callFunctionOnObject(context, globalObject, functionName, argumentCount, arguments, exception);
+}
+
+JSValueRef DebuggerDocument::callFunctionOnObject(JSContextRef context, JSObjectRef object, const char* functionName, int argumentCount, JSValueRef arguments[], JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> string(Adopt, JSStringCreateWithUTF8CString(functionName));
+ JSValueRef objectProperty = JSObjectGetProperty(context, object, string.get(), exception);
+
+ JSObjectRef function = JSValueToObject(context, objectProperty, exception);
+ ASSERT(JSObjectIsFunction(context, function));
+
+ JSValueRef returnValue = JSObjectCallAsFunction(context, function, 0, argumentCount, arguments, exception);
+ if (exception && *exception)
+ logException(context, *exception);
+
+ return returnValue;
+}
+
+JSClassRef DebuggerDocument::getDroseraJSClass()
+{
+ static JSClassRef droseraClass = 0;
+
+ if (!droseraClass) {
+ JSClassDefinition classDefinition = {0};
+ classDefinition.staticFunctions = DebuggerDocument::staticFunctions();
+
+ droseraClass = JSClassCreate(&classDefinition);
+ }
+
+ return droseraClass;
+}
+
+JSStaticFunction* DebuggerDocument::staticFunctions()
+{
+ static JSStaticFunction staticFunctions[] = {
+ { "breakpointEditorHTML", DebuggerDocument::breakpointEditorHTMLCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "currentFunctionStack", DebuggerDocument::currentFunctionStackCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "evaluateScript", DebuggerDocument::evaluateScriptCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "localScopeVariableNamesForCallFrame", DebuggerDocument::localScopeVariableNamesForCallFrameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "pause", DebuggerDocument::pauseCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "resume", DebuggerDocument::resumeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "stepInto", DebuggerDocument::stepIntoCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "valueForScopeVariableNamed", DebuggerDocument::valueForScopeVariableNamedCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "log", DebuggerDocument::logCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { 0, 0, 0 }
+ };
+
+ return staticFunctions;
+}
+
+void DebuggerDocument::logException(JSContextRef context, JSValueRef exception)
+{
+ if (!exception)
+ return;
+
+ JSRetainPtr<JSStringRef> msg(Adopt, JSValueToStringCopy(context, exception, 0));
+ DebuggerDocument::platformLog(msg.get());
+}
+
diff --git a/WebKitTools/Drosera/DebuggerDocument.h b/WebKitTools/Drosera/DebuggerDocument.h
new file mode 100644
index 0000000..7043ba1
--- /dev/null
+++ b/WebKitTools/Drosera/DebuggerDocument.h
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ */
+
+#ifndef DebuggerDocument_H
+#define DebuggerDocument_H
+
+#pragma warning(push)
+#pragma warning(disable: 4510 4512 4610)
+#include <JavaScriptCore/JSObjectRef.h>
+#pragma warning(pop)
+
+#include <JavaScriptCore/Vector.h>
+
+// Forward Declarations
+#if PLATFORM(MAC)
+#include <JavaScriptCore/RetainPtr.h>
+@class ServerConnection;
+typedef RetainPtr<ServerConnection> ServerConnectionRef;
+#else if PLATFORM(WIN)
+#include <wtf/OwnPtr.h>
+class ServerConnection;
+typedef OwnPtr<ServerConnection> ServerConnectionRef;
+#endif
+
+typedef struct OpaqueJSString* JSStringRef;
+typedef struct OpaqueJSValue* JSObjectRef;
+
+class DebuggerDocument {
+public:
+ DebuggerDocument(ServerConnection*);
+
+ // These are all calls from the JS
+ static JSValueRef breakpointEditorHTMLCallback(JSContextRef context, JSObjectRef /*function*/, JSObjectRef /*thisObject*/, size_t /*argumentCount*/, const JSValueRef /*arguments*/[], JSValueRef* /*exception*/);
+ static JSValueRef pauseCallback(JSContextRef context, JSObjectRef /*function*/, JSObjectRef /*thisObject*/, size_t /*argumentCount*/, const JSValueRef /*arguments*/[], JSValueRef* /*exception*/);
+ static JSValueRef resumeCallback(JSContextRef context, JSObjectRef /*function*/, JSObjectRef /*thisObject*/, size_t /*argumentCount*/, const JSValueRef /*arguments*/[], JSValueRef* /*exception*/);
+ static JSValueRef stepIntoCallback(JSContextRef context, JSObjectRef /*function*/, JSObjectRef /*thisObject*/, size_t /*argumentCount*/, const JSValueRef /*arguments*/[], JSValueRef* /*exception*/);
+ static JSValueRef evaluateScriptCallback(JSContextRef context, JSObjectRef /*function*/, JSObjectRef /*thisObject*/, size_t /*argumentCount*/, const JSValueRef /*arguments*/[], JSValueRef* /*exception*/);
+ static JSValueRef currentFunctionStackCallback(JSContextRef /*context*/, JSObjectRef /*function*/, JSObjectRef /*thisObject*/, size_t /*argumentCount*/, const JSValueRef /*arguments*/[], JSValueRef* /*exception*/);
+ static JSValueRef localScopeVariableNamesForCallFrameCallback(JSContextRef context, JSObjectRef /*function*/, JSObjectRef /*thisObject*/, size_t /*argumentCount*/, const JSValueRef /*arguments*/[], JSValueRef* /*exception*/);
+ static JSValueRef valueForScopeVariableNamedCallback(JSContextRef context, JSObjectRef /*function*/, JSObjectRef /*thisObject*/, size_t /*argumentCount*/, const JSValueRef /*arguments*/[], JSValueRef* /*exception*/);
+ static JSValueRef logCallback(JSContextRef context, JSObjectRef /*function*/, JSObjectRef /*thisObject*/, size_t /*argumentCount*/, const JSValueRef /*arguments*/[], JSValueRef* /*exception*/);
+
+ // Non Cross-platform functions
+ void platformPause();
+ void platformResume();
+ void platformStepInto();
+ JSValueRef platformEvaluateScript(JSContextRef, JSStringRef script, int callFrame);
+ void getPlatformCurrentFunctionStack(JSContextRef, Vector<JSValueRef>& currentStack);
+ void getPlatformLocalScopeVariableNamesForCallFrame(JSContextRef, int callFrame, Vector<JSValueRef>& variableNames);
+ JSValueRef platformValueForScopeVariableNamed(JSContextRef, JSStringRef key, int callFrame);
+ static void platformLog(JSStringRef msg);
+
+ // These are the calls into the JS.
+ bool isPaused(JSContextRef) const;
+ static void updateFileSource(JSContextRef, JSStringRef documentSource, JSStringRef url);
+ static void didParseScript(JSContextRef, JSStringRef source, JSStringRef documentSource, JSStringRef url, JSValueRef sourceId, JSValueRef baseLine);
+ static void willExecuteStatement(JSContextRef, JSValueRef sourceId, JSValueRef lineno, JSValueRef* exception = 0);
+ static void didEnterCallFrame(JSContextRef, JSValueRef sourceId, JSValueRef lineno, JSValueRef* exception = 0);
+ static void willLeaveCallFrame(JSContextRef, JSValueRef sourceId, JSValueRef lineno, JSValueRef* exception = 0);
+ static void exceptionWasRaised(JSContextRef, JSValueRef sourceId, JSValueRef lineno, JSValueRef* exception = 0);
+
+ static JSValueRef toJSArray(JSContextRef, Vector<JSValueRef>&, JSValueRef* exception);
+ static JSValueRef callGlobalFunction(JSContextRef, const char* functionName, int argumentCount, JSValueRef arguments[], JSValueRef* exception = 0); // Implementation for calls into JS
+
+ void windowScriptObjectAvailable(JSContextRef, JSObjectRef windowObject, JSValueRef* exception = 0);
+
+ ServerConnection* server() const { return m_server.get(); }
+
+private:
+ static JSValueRef callFunctionOnObject(JSContextRef, JSObjectRef object, const char* functionName, int argumentCount, JSValueRef arguments[], JSValueRef* exception = 0); // Implementation for calls into JS
+ static JSClassRef getDroseraJSClass();
+ static JSStaticFunction* staticFunctions();
+
+ static void logException(JSContextRef, JSValueRef exception);
+
+ ServerConnectionRef m_server;
+};
+
+#endif //DebuggerDocument_H
+
diff --git a/WebKitTools/Drosera/Drosera.icns b/WebKitTools/Drosera/Drosera.icns
new file mode 100644
index 0000000..ead895e
--- /dev/null
+++ b/WebKitTools/Drosera/Drosera.icns
Binary files differ
diff --git a/WebKitTools/Drosera/DroseraWin.make b/WebKitTools/Drosera/DroseraWin.make
new file mode 100644
index 0000000..b69d47d
--- /dev/null
+++ b/WebKitTools/Drosera/DroseraWin.make
@@ -0,0 +1,13 @@
+!IF !defined(BUILDSTYLE)
+BUILDSTYLE=Release
+!ELSEIF "$(BUILDSTYLE)"=="DEBUG"
+BUILDSTYLE=Debug_Internal
+!ENDIF
+
+install:
+ set WebKitLibrariesDir=$(SRCROOT)\AppleInternal
+ set WebKitOutputDir=$(OBJROOT)
+ set PRODUCTION=1
+ devenv "win\Drosera.vcproj\Drosera.vcproj" /rebuild $(BUILDSTYLE)
+ xcopy "$(OBJROOT)\bin\*" "$(DSTROOT)\AppleInternal\bin\" /e/v/i/h/y
+ xcopy "$(OBJROOT)\bin\Drosera.resources\*" "$(DSTROOT)\AppleInternal\bin\Drosera.resources" /e/v/i/h/y
diff --git a/WebKitTools/Drosera/English.lproj/Debugger.nib/classes.nib b/WebKitTools/Drosera/English.lproj/Debugger.nib/classes.nib
new file mode 100644
index 0000000..3e0e4cb
--- /dev/null
+++ b/WebKitTools/Drosera/English.lproj/Debugger.nib/classes.nib
@@ -0,0 +1,12 @@
+{
+ IBClasses = (
+ {
+ CLASS = DebuggerDocument;
+ LANGUAGE = ObjC;
+ OUTLETS = {server = id; webView = WebView; };
+ SUPERCLASS = NSWindowController;
+ },
+ {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }
+ );
+ IBVersion = 1;
+} \ No newline at end of file
diff --git a/WebKitTools/Drosera/English.lproj/Debugger.nib/info.nib b/WebKitTools/Drosera/English.lproj/Debugger.nib/info.nib
new file mode 100644
index 0000000..7564e3e
--- /dev/null
+++ b/WebKitTools/Drosera/English.lproj/Debugger.nib/info.nib
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IBDocumentLocation</key>
+ <string>907 177 356 240 0 0 1280 832 </string>
+ <key>IBFramework Version</key>
+ <string>446.1</string>
+ <key>IBOpenObjects</key>
+ <array>
+ <integer>5</integer>
+ </array>
+ <key>IBSystem Version</key>
+ <string>8L127</string>
+</dict>
+</plist>
diff --git a/WebKitTools/Drosera/English.lproj/Debugger.nib/keyedobjects.nib b/WebKitTools/Drosera/English.lproj/Debugger.nib/keyedobjects.nib
new file mode 100644
index 0000000..3978af2
--- /dev/null
+++ b/WebKitTools/Drosera/English.lproj/Debugger.nib/keyedobjects.nib
Binary files differ
diff --git a/WebKitTools/Drosera/English.lproj/MainMenu.nib/classes.nib b/WebKitTools/Drosera/English.lproj/MainMenu.nib/classes.nib
new file mode 100644
index 0000000..f192cda
--- /dev/null
+++ b/WebKitTools/Drosera/English.lproj/MainMenu.nib/classes.nib
@@ -0,0 +1,40 @@
+{
+ IBClasses = (
+ {
+ ACTIONS = {attach = id; showAttachPanel = id; };
+ CLASS = DebuggerApplication;
+ LANGUAGE = ObjC;
+ OUTLETS = {attachButton = NSButton; attachTable = NSTableView; attachWindow = NSPanel; };
+ SUPERCLASS = NSObject;
+ },
+ {
+ ACTIONS = {
+ closeCurrentFile = id;
+ pause = id;
+ resume = id;
+ showConsole = id;
+ stepInto = id;
+ stepOut = id;
+ stepOver = id;
+ };
+ CLASS = DebuggerDocument;
+ LANGUAGE = ObjC;
+ OUTLETS = {server = id; webView = WebView; };
+ SUPERCLASS = NSWindowController;
+ },
+ {
+ ACTIONS = {
+ closeCurrentFile = id;
+ myAction = id;
+ showConsole = id;
+ stepInto = id;
+ stepOut = id;
+ stepOver = id;
+ };
+ CLASS = FirstResponder;
+ LANGUAGE = ObjC;
+ SUPERCLASS = NSObject;
+ }
+ );
+ IBVersion = 1;
+} \ No newline at end of file
diff --git a/WebKitTools/Drosera/English.lproj/MainMenu.nib/info.nib b/WebKitTools/Drosera/English.lproj/MainMenu.nib/info.nib
new file mode 100644
index 0000000..838fde9
--- /dev/null
+++ b/WebKitTools/Drosera/English.lproj/MainMenu.nib/info.nib
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IBDocumentLocation</key>
+ <string>488 89 356 240 0 0 1280 1002 </string>
+ <key>IBEditorPositions</key>
+ <dict>
+ <key>29</key>
+ <string>190 724 343 44 0 0 1280 1002 </string>
+ </dict>
+ <key>IBFramework Version</key>
+ <string>446.1</string>
+ <key>IBOpenObjects</key>
+ <array>
+ <integer>217</integer>
+ <integer>29</integer>
+ </array>
+ <key>IBSystem Version</key>
+ <string>8N1037</string>
+</dict>
+</plist>
diff --git a/WebKitTools/Drosera/English.lproj/MainMenu.nib/keyedobjects.nib b/WebKitTools/Drosera/English.lproj/MainMenu.nib/keyedobjects.nib
new file mode 100644
index 0000000..b78326d
--- /dev/null
+++ b/WebKitTools/Drosera/English.lproj/MainMenu.nib/keyedobjects.nib
Binary files differ
diff --git a/WebKitTools/Drosera/ForwardingHeaders/wtf/Assertions.h b/WebKitTools/Drosera/ForwardingHeaders/wtf/Assertions.h
new file mode 100644
index 0000000..2144410
--- /dev/null
+++ b/WebKitTools/Drosera/ForwardingHeaders/wtf/Assertions.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/Assertions.h>
diff --git a/WebKitTools/Drosera/ForwardingHeaders/wtf/HashTraits.h b/WebKitTools/Drosera/ForwardingHeaders/wtf/HashTraits.h
new file mode 100644
index 0000000..412fa98
--- /dev/null
+++ b/WebKitTools/Drosera/ForwardingHeaders/wtf/HashTraits.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/HashTraits.h>
diff --git a/WebKitTools/Drosera/ForwardingHeaders/wtf/Noncopyable.h b/WebKitTools/Drosera/ForwardingHeaders/wtf/Noncopyable.h
new file mode 100644
index 0000000..f8484d2
--- /dev/null
+++ b/WebKitTools/Drosera/ForwardingHeaders/wtf/Noncopyable.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/Noncopyable.h>
diff --git a/WebKitTools/Drosera/ForwardingHeaders/wtf/OwnPtr.h b/WebKitTools/Drosera/ForwardingHeaders/wtf/OwnPtr.h
new file mode 100644
index 0000000..9211d38
--- /dev/null
+++ b/WebKitTools/Drosera/ForwardingHeaders/wtf/OwnPtr.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/OwnPtr.h>
diff --git a/WebKitTools/Drosera/ForwardingHeaders/wtf/Platform.h b/WebKitTools/Drosera/ForwardingHeaders/wtf/Platform.h
new file mode 100644
index 0000000..3b22955
--- /dev/null
+++ b/WebKitTools/Drosera/ForwardingHeaders/wtf/Platform.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/Platform.h>
diff --git a/WebKitTools/Drosera/ForwardingHeaders/wtf/RetainPtr.h b/WebKitTools/Drosera/ForwardingHeaders/wtf/RetainPtr.h
new file mode 100644
index 0000000..65fc27b
--- /dev/null
+++ b/WebKitTools/Drosera/ForwardingHeaders/wtf/RetainPtr.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/RetainPtr.h>
diff --git a/WebKitTools/Drosera/Images/Drosera.ico b/WebKitTools/Drosera/Images/Drosera.ico
new file mode 100644
index 0000000..18a459d
--- /dev/null
+++ b/WebKitTools/Drosera/Images/Drosera.ico
Binary files differ
diff --git a/WebKitTools/Drosera/Images/SourceArrow.png b/WebKitTools/Drosera/Images/SourceArrow.png
new file mode 100644
index 0000000..f493903
--- /dev/null
+++ b/WebKitTools/Drosera/Images/SourceArrow.png
Binary files differ
diff --git a/WebKitTools/Drosera/Images/SourceArrowBlank.png b/WebKitTools/Drosera/Images/SourceArrowBlank.png
new file mode 100644
index 0000000..d178ac0
--- /dev/null
+++ b/WebKitTools/Drosera/Images/SourceArrowBlank.png
Binary files differ
diff --git a/WebKitTools/Drosera/Images/SourceArrowOpen.png b/WebKitTools/Drosera/Images/SourceArrowOpen.png
new file mode 100644
index 0000000..4016402
--- /dev/null
+++ b/WebKitTools/Drosera/Images/SourceArrowOpen.png
Binary files differ
diff --git a/WebKitTools/Drosera/Images/background_stripe.png b/WebKitTools/Drosera/Images/background_stripe.png
new file mode 100644
index 0000000..d9ddebc
--- /dev/null
+++ b/WebKitTools/Drosera/Images/background_stripe.png
Binary files differ
diff --git a/WebKitTools/Drosera/Images/breakPoint.tif b/WebKitTools/Drosera/Images/breakPoint.tif
new file mode 100644
index 0000000..95431b4
--- /dev/null
+++ b/WebKitTools/Drosera/Images/breakPoint.tif
Binary files differ
diff --git a/WebKitTools/Drosera/Images/breakPointDisabled.tif b/WebKitTools/Drosera/Images/breakPointDisabled.tif
new file mode 100644
index 0000000..2000bd2
--- /dev/null
+++ b/WebKitTools/Drosera/Images/breakPointDisabled.tif
Binary files differ
diff --git a/WebKitTools/Drosera/Images/breakpointeditor.png b/WebKitTools/Drosera/Images/breakpointeditor.png
new file mode 100644
index 0000000..8bb992b
--- /dev/null
+++ b/WebKitTools/Drosera/Images/breakpointeditor.png
Binary files differ
diff --git a/WebKitTools/Drosera/Images/close.tif b/WebKitTools/Drosera/Images/close.tif
new file mode 100644
index 0000000..a221ac7
--- /dev/null
+++ b/WebKitTools/Drosera/Images/close.tif
Binary files differ
diff --git a/WebKitTools/Drosera/Images/close_active.tif b/WebKitTools/Drosera/Images/close_active.tif
new file mode 100644
index 0000000..104799d
--- /dev/null
+++ b/WebKitTools/Drosera/Images/close_active.tif
Binary files differ
diff --git a/WebKitTools/Drosera/Images/close_hover.tif b/WebKitTools/Drosera/Images/close_hover.tif
new file mode 100644
index 0000000..cd86fa5
--- /dev/null
+++ b/WebKitTools/Drosera/Images/close_hover.tif
Binary files differ
diff --git a/WebKitTools/Drosera/Images/console.png b/WebKitTools/Drosera/Images/console.png
new file mode 100644
index 0000000..fe7cbe6
--- /dev/null
+++ b/WebKitTools/Drosera/Images/console.png
Binary files differ
diff --git a/WebKitTools/Drosera/Images/continue.tif b/WebKitTools/Drosera/Images/continue.tif
new file mode 100644
index 0000000..58b9893
--- /dev/null
+++ b/WebKitTools/Drosera/Images/continue.tif
Binary files differ
diff --git a/WebKitTools/Drosera/Images/fileIcon.jpg b/WebKitTools/Drosera/Images/fileIcon.jpg
new file mode 100644
index 0000000..c651a78
--- /dev/null
+++ b/WebKitTools/Drosera/Images/fileIcon.jpg
Binary files differ
diff --git a/WebKitTools/Drosera/Images/finishFunction.tif b/WebKitTools/Drosera/Images/finishFunction.tif
new file mode 100644
index 0000000..af75e60
--- /dev/null
+++ b/WebKitTools/Drosera/Images/finishFunction.tif
Binary files differ
diff --git a/WebKitTools/Drosera/Images/glossyFooterFill.tif b/WebKitTools/Drosera/Images/glossyFooterFill.tif
new file mode 100644
index 0000000..d5ea4d4
--- /dev/null
+++ b/WebKitTools/Drosera/Images/glossyFooterFill.tif
Binary files differ
diff --git a/WebKitTools/Drosera/Images/glossyHeader.png b/WebKitTools/Drosera/Images/glossyHeader.png
new file mode 100644
index 0000000..8c80b6b
--- /dev/null
+++ b/WebKitTools/Drosera/Images/glossyHeader.png
Binary files differ
diff --git a/WebKitTools/Drosera/Images/glossyHeaderPressed.png b/WebKitTools/Drosera/Images/glossyHeaderPressed.png
new file mode 100644
index 0000000..6b0dd60
--- /dev/null
+++ b/WebKitTools/Drosera/Images/glossyHeaderPressed.png
Binary files differ
diff --git a/WebKitTools/Drosera/Images/gradientBackground.png b/WebKitTools/Drosera/Images/gradientBackground.png
new file mode 100644
index 0000000..c0ce0a5
--- /dev/null
+++ b/WebKitTools/Drosera/Images/gradientBackground.png
Binary files differ
diff --git a/WebKitTools/Drosera/Images/gutter.png b/WebKitTools/Drosera/Images/gutter.png
new file mode 100644
index 0000000..9b698c1
--- /dev/null
+++ b/WebKitTools/Drosera/Images/gutter.png
Binary files differ
diff --git a/WebKitTools/Drosera/Images/navLeftDisabled.png b/WebKitTools/Drosera/Images/navLeftDisabled.png
new file mode 100644
index 0000000..edd7c26
--- /dev/null
+++ b/WebKitTools/Drosera/Images/navLeftDisabled.png
Binary files differ
diff --git a/WebKitTools/Drosera/Images/navLeftNormal.png b/WebKitTools/Drosera/Images/navLeftNormal.png
new file mode 100644
index 0000000..9a14bbf
--- /dev/null
+++ b/WebKitTools/Drosera/Images/navLeftNormal.png
Binary files differ
diff --git a/WebKitTools/Drosera/Images/navLeftPressed.png b/WebKitTools/Drosera/Images/navLeftPressed.png
new file mode 100644
index 0000000..840a4b4
--- /dev/null
+++ b/WebKitTools/Drosera/Images/navLeftPressed.png
Binary files differ
diff --git a/WebKitTools/Drosera/Images/navRightDisabled.png b/WebKitTools/Drosera/Images/navRightDisabled.png
new file mode 100644
index 0000000..6057aae
--- /dev/null
+++ b/WebKitTools/Drosera/Images/navRightDisabled.png
Binary files differ
diff --git a/WebKitTools/Drosera/Images/navRightNormal.png b/WebKitTools/Drosera/Images/navRightNormal.png
new file mode 100644
index 0000000..936cd91
--- /dev/null
+++ b/WebKitTools/Drosera/Images/navRightNormal.png
Binary files differ
diff --git a/WebKitTools/Drosera/Images/navRightPressed.png b/WebKitTools/Drosera/Images/navRightPressed.png
new file mode 100644
index 0000000..faf78ce
--- /dev/null
+++ b/WebKitTools/Drosera/Images/navRightPressed.png
Binary files differ
diff --git a/WebKitTools/Drosera/Images/pause.tif b/WebKitTools/Drosera/Images/pause.tif
new file mode 100644
index 0000000..460aeed
--- /dev/null
+++ b/WebKitTools/Drosera/Images/pause.tif
Binary files differ
diff --git a/WebKitTools/Drosera/Images/popUpArrows.png b/WebKitTools/Drosera/Images/popUpArrows.png
new file mode 100644
index 0000000..f47eaa5
--- /dev/null
+++ b/WebKitTools/Drosera/Images/popUpArrows.png
Binary files differ
diff --git a/WebKitTools/Drosera/Images/programCounter.tif b/WebKitTools/Drosera/Images/programCounter.tif
new file mode 100644
index 0000000..e65d549
--- /dev/null
+++ b/WebKitTools/Drosera/Images/programCounter.tif
Binary files differ
diff --git a/WebKitTools/Drosera/Images/programCounterBreakPoint.tif b/WebKitTools/Drosera/Images/programCounterBreakPoint.tif
new file mode 100644
index 0000000..093b639
--- /dev/null
+++ b/WebKitTools/Drosera/Images/programCounterBreakPoint.tif
Binary files differ
diff --git a/WebKitTools/Drosera/Images/programCounterBreakPointDisabled.tif b/WebKitTools/Drosera/Images/programCounterBreakPointDisabled.tif
new file mode 100644
index 0000000..1c1a699
--- /dev/null
+++ b/WebKitTools/Drosera/Images/programCounterBreakPointDisabled.tif
Binary files differ
diff --git a/WebKitTools/Drosera/Images/run.tif b/WebKitTools/Drosera/Images/run.tif
new file mode 100644
index 0000000..f9e815f
--- /dev/null
+++ b/WebKitTools/Drosera/Images/run.tif
Binary files differ
diff --git a/WebKitTools/Drosera/Images/siteCollapsed.tif b/WebKitTools/Drosera/Images/siteCollapsed.tif
new file mode 100644
index 0000000..07d8a12
--- /dev/null
+++ b/WebKitTools/Drosera/Images/siteCollapsed.tif
Binary files differ
diff --git a/WebKitTools/Drosera/Images/siteExpanded.tif b/WebKitTools/Drosera/Images/siteExpanded.tif
new file mode 100644
index 0000000..8044385
--- /dev/null
+++ b/WebKitTools/Drosera/Images/siteExpanded.tif
Binary files differ
diff --git a/WebKitTools/Drosera/Images/siteIcon.tif b/WebKitTools/Drosera/Images/siteIcon.tif
new file mode 100644
index 0000000..d32654f
--- /dev/null
+++ b/WebKitTools/Drosera/Images/siteIcon.tif
Binary files differ
diff --git a/WebKitTools/Drosera/Images/small.ico b/WebKitTools/Drosera/Images/small.ico
new file mode 100644
index 0000000..18a459d
--- /dev/null
+++ b/WebKitTools/Drosera/Images/small.ico
Binary files differ
diff --git a/WebKitTools/Drosera/Images/splitterBar.tif b/WebKitTools/Drosera/Images/splitterBar.tif
new file mode 100644
index 0000000..0e7425d
--- /dev/null
+++ b/WebKitTools/Drosera/Images/splitterBar.tif
Binary files differ
diff --git a/WebKitTools/Drosera/Images/splitterDimple.tif b/WebKitTools/Drosera/Images/splitterDimple.tif
new file mode 100644
index 0000000..d112854
--- /dev/null
+++ b/WebKitTools/Drosera/Images/splitterDimple.tif
Binary files differ
diff --git a/WebKitTools/Drosera/Images/step.tif b/WebKitTools/Drosera/Images/step.tif
new file mode 100644
index 0000000..457f1cd
--- /dev/null
+++ b/WebKitTools/Drosera/Images/step.tif
Binary files differ
diff --git a/WebKitTools/Drosera/Images/stepOut.tif b/WebKitTools/Drosera/Images/stepOut.tif
new file mode 100644
index 0000000..ff9e64b
--- /dev/null
+++ b/WebKitTools/Drosera/Images/stepOut.tif
Binary files differ
diff --git a/WebKitTools/Drosera/Images/stepOver.tif b/WebKitTools/Drosera/Images/stepOver.tif
new file mode 100644
index 0000000..6c18c71
--- /dev/null
+++ b/WebKitTools/Drosera/Images/stepOver.tif
Binary files differ
diff --git a/WebKitTools/Drosera/Images/stop.tif b/WebKitTools/Drosera/Images/stop.tif
new file mode 100644
index 0000000..a65c6df
--- /dev/null
+++ b/WebKitTools/Drosera/Images/stop.tif
Binary files differ
diff --git a/WebKitTools/Drosera/Images/toolbarBackground.png b/WebKitTools/Drosera/Images/toolbarBackground.png
new file mode 100644
index 0000000..018e001
--- /dev/null
+++ b/WebKitTools/Drosera/Images/toolbarBackground.png
Binary files differ
diff --git a/WebKitTools/Drosera/Images/verticalSplitterBar.tiff b/WebKitTools/Drosera/Images/verticalSplitterBar.tiff
new file mode 100644
index 0000000..4810d01
--- /dev/null
+++ b/WebKitTools/Drosera/Images/verticalSplitterBar.tiff
Binary files differ
diff --git a/WebKitTools/Drosera/Images/verticalSplitterDimple.tiff b/WebKitTools/Drosera/Images/verticalSplitterDimple.tiff
new file mode 100644
index 0000000..fee927b
--- /dev/null
+++ b/WebKitTools/Drosera/Images/verticalSplitterDimple.tiff
Binary files differ
diff --git a/WebKitTools/Drosera/Makefile b/WebKitTools/Drosera/Makefile
new file mode 100644
index 0000000..4fce090
--- /dev/null
+++ b/WebKitTools/Drosera/Makefile
@@ -0,0 +1,3 @@
+OTHER_OPTIONS = -project mac/Drosera.xcodeproj
+SCRIPTS_PATH = ../Scripts
+include ../../Makefile.shared
diff --git a/WebKitTools/Drosera/breakpointEditor.html b/WebKitTools/Drosera/breakpointEditor.html
new file mode 100644
index 0000000..30ef0c9
--- /dev/null
+++ b/WebKitTools/Drosera/breakpointEditor.html
@@ -0,0 +1 @@
+<div class="top">Breakpoint:<label>Enable:<input class="enable" type="checkbox" onclick="window.parent.toggleBreakpointOnLine(this.firstParentWithClass('editor').id)"></input></label><label>Hit Count:<span class="hitCounter">0</span></label><label>Action:<select class="editorDropdown" onchange="window.parent.updateBreakpointTypeOnLine(this.firstParentWithClass('editor').id)"><option value="pause">Pause</option><option value="log">Log</option></select></label><input type="button" class="close" onmouseup="window.parent.toggleBreakpointEditorOnLine(this.firstParentWithClass('editor').id)">&nbsp;</input></div><div class="bottom"><label class="conditionLabel" for="editorCondition">Condition:</label><div class="condition"></div></div> \ No newline at end of file
diff --git a/WebKitTools/Drosera/config.h b/WebKitTools/Drosera/config.h
new file mode 100644
index 0000000..0b4a2c8
--- /dev/null
+++ b/WebKitTools/Drosera/config.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2004-2007 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
+ * 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 <wtf/Platform.h>
+
+#if PLATFORM(MAC)
+
+#import <WebKit/WebKit.h>
+#import <WebKit/WebScriptDebugServer.h>
+
+#endif
+
+#if PLATFORM(WIN)
+
+// If we don't define these, they get defined in windef.h.
+// We want to use std::min and std::max
+#ifndef max
+#define max max
+#endif
+#ifndef min
+#define min min
+#endif
+
+#include <tchar.h>
+
+#endif // PLATFORM(WIN)
+
diff --git a/WebKitTools/Drosera/console.css b/WebKitTools/Drosera/console.css
new file mode 100644
index 0000000..02c37b7
--- /dev/null
+++ b/WebKitTools/Drosera/console.css
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * 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.
+ * 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.
+ */
+
+img { padding: 0; margin: 0; }
+body { margin: 0; padding: 0; overflow: hidden; }
+
+#main {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+}
+
+#top {
+ position: absolute;
+ top: 0;
+ bottom: 50px;
+ left: 0;
+ right: 0;
+}
+
+#history {
+ position: absolute;
+ top: 0;
+ bottom: 10px;
+ left: 0;
+ right: 0;
+ overflow-y: auto;
+ overflow-x: hidden;
+}
+
+#divider {
+ cursor: row-resize;
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ background: url(splitterDimple.tif) 50% no-repeat, url(splitterBar.tif) repeat-x;
+ height: 10px;
+}
+
+#input {
+ position: absolute;
+ -webkit-box-sizing: border-box;
+ height: 50px;
+ max-height: 150px;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ -webkit-user-modify: read-write-plaintext-only;
+ -webkit-nbsp-mode: space;
+ -webkit-line-break: after-white-space;
+ word-wrap: break-word;
+ outline: none;
+ font-family: monospace;
+ font-size: 11px;
+ line-height: 14px;
+ padding: 3px;
+}
+
+#history .row {
+ min-height: 38px;
+ padding: 4px;
+ -webkit-box-sizing: border-box;
+ font-family: monospace;
+ font-size: 12px;
+}
+
+#history .row.alt {
+ background-color: rgb(237, 243, 254);
+}
+
+.expression {
+ color: blue;
+}
+
+.result {
+ color: navy;
+}
diff --git a/WebKitTools/Drosera/console.html b/WebKitTools/Drosera/console.html
new file mode 100644
index 0000000..888878b
--- /dev/null
+++ b/WebKitTools/Drosera/console.html
@@ -0,0 +1,47 @@
+<!--
+Copyright (C) 2006 Apple Computer, 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" />
+ <title>Console</title>
+ <script type="text/javascript" src="console.js"></script>
+ <style type="text/css">
+ @import "console.css";
+ </style>
+</head>
+<body onload="loaded()" onunload="unloading()">
+<div id="main">
+<div id="top">
+<div id="history"></div>
+<div id="divider"></div>
+</div>
+<div id="input"></div>
+</div>
+</body>
+</html>
diff --git a/WebKitTools/Drosera/console.js b/WebKitTools/Drosera/console.js
new file mode 100644
index 0000000..7db3fb4
--- /dev/null
+++ b/WebKitTools/Drosera/console.js
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * 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.
+ * 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 inputElement = null;
+var mainWindow = window.opener;
+var history = [""];
+var historyIndex = 0;
+
+function loaded()
+{
+ inputElement = document.getElementById("input");
+ inputElement.addEventListener("keydown", inputKeyDown, false);
+ inputElement.addEventListener("keyup", inputKeyUp, false);
+ inputElement.focus();
+}
+
+function inputKeyDown(event)
+{
+ if (event.keyCode == 13 && !event.altKey) {
+ if (mainWindow.isPaused && mainWindow.currentStack) {
+ history[history.length - 1] = inputElement.innerText;
+ sendScript(inputElement.innerText);
+ inputElement.innerText = "";
+ history.push("");
+ historyIndex = history.length - 1;
+ inputElement.focus();
+ } else
+ alert("The debugger needs to be paused.\tIn order to evaluate your script input you need to pause the debugger in the context of another script.");
+ event.preventDefault();
+ } else if (event.keyCode == 38 && !event.altKey && historyIndex > 0) {
+ historyIndex--;
+ inputElement.innerText = history[historyIndex];
+ inputElement.focus()
+ event.preventDefault();
+ } else if (event.keyCode == 40 && !event.altKey && historyIndex < (history.length - 1)) {
+ historyIndex++;
+ inputElement.innerText = history[historyIndex];
+ inputElement.focus()
+ event.preventDefault();
+ }
+}
+
+function inputKeyUp(event)
+{
+ if (event.keyCode != 38 && event.keyCode != 40 && event.keyCode != 13) {
+ history[historyIndex] = inputElement.innerText;
+ }
+}
+
+function appendMessage(exp, msg)
+{
+ var historyDisplay = document.getElementById("history");
+ var row = document.createElement("div");
+ row.className = "row";
+ if (historyDisplay.childNodes.length % 2)
+ row.className += " alt";
+
+ if (exp.length > 0) {
+ var expression = document.createElement("div");
+ expression.className = "expression";
+ expression.innerText = exp;
+ row.appendChild(expression);
+ }
+
+ var result = document.createElement("div");
+ result.className = "result";
+ result.innerText = msg;
+
+ row.appendChild(result);
+
+ historyDisplay.appendChild(row);
+ historyDisplay.scrollTop = historyDisplay.scrollHeight;
+}
+
+function sendScript(script)
+{
+ appendMessage(script, mainWindow.DebuggerDocument.evaluateScript(script, mainWindow.currentCallFrame.index));
+ if (script.indexOf("=") >= 0)
+ mainWindow.currentCallFrame.loadVariables();
+}
+
+function unloading()
+{
+ mainWindow.consoleWindow = null;
+}
diff --git a/WebKitTools/Drosera/debugger.css b/WebKitTools/Drosera/debugger.css
new file mode 100644
index 0000000..f15d572
--- /dev/null
+++ b/WebKitTools/Drosera/debugger.css
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Vladimir Olexa (vladimir.olexa@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.
+ */
+
+img { padding: 0; margin: 0; }
+body { margin: 0; padding: 0; overflow: hidden; }
+iframe { border: none; }
+
+#fileBrowser { position: absolute; top: 0; bottom: 0; left: 0; right: 0; width: 220px;}
+#fileList { position: absolute; top: 0; bottom: 0; left: 0; right: 10px; padding: 0; margin: 0; }
+#filesDivider { position: absolute; z-index: 10; right: 0px; bottom: 0px; top: 0; width: 10px; cursor: col-resize; background: url(verticalSplitterDimple.tiff) 50% no-repeat, url(verticalSplitterBar.tiff) repeat-y; width: 10px; }
+#masterMain { position: absolute; top: 0; bottom: 0; left: 0; right: 0; }
+#main { position: absolute; top: 0; bottom: 0; left: 220px; right: 0; }
+#info { position: absolute; top: 0; height: 175px; left: 0; right: 0; }
+#divider { cursor: row-resize; position: absolute; bottom: 0; left: 0; right: 0; background: url(splitterDimple.tif) 50% no-repeat, url(splitterBar.tif) repeat-x; height: 10px }
+#body { position: absolute; top: 175px; left: 0; right: 0; bottom: 0; }
+#sourcesContainer { position: absolute; top: 16px; left: 0; right: 0; bottom: 21px; background-color: white; }
+#sources { width: 100%; height: 100% }
+#header { vertical-align: top; height: 16px; -webkit-box-sizing: border-box; border-bottom: 1px solid #aaa; background: url(glossyHeader.png) repeat-x; position: absolute; top: 0; left: 0; right: 0; }
+#header > * { vertical-align: top; }
+.footer { height: 21px; -webkit-box-sizing: border-box; border-top: 1px solid #aaa; background: url(glossyFooterFill.tif) repeat-x; position: absolute; bottom: 0; left: 0; right: 0; }
+#infoDivider { position: absolute; z-index: 10; right: 0; left: 0; top: 0; bottom: 9px; width: 10px; cursor: col-resize; background: url(verticalSplitterDimple.tiff) 50% no-repeat, url(verticalSplitterBar.tiff) repeat-y; width: 10px; }
+
+#filesBrowserSites {
+ position: absolute;
+ font-family: "Lucida Grande", sans-serif;
+ font-size: 11px;
+ padding: 2px;
+ overflow-x: hidden;
+ overflow-y: auto;
+ top: 16px;
+ left: 0;
+ right: 0;
+ bottom: 21px;
+ background-color: white;
+}
+
+#filesBrowserSites div {
+ font-weight: normal;
+ overflow: hidden;
+ white-space: nowrap;
+ padding-left: 26px;
+ background: url(siteExpanded.tif) no-repeat 0px 0px;
+ cursor: default;
+ margin-bottom: 2px;
+}
+
+#filesBrowserSites div.expanded {
+ background: url(siteExpanded.tif) no-repeat 0px 0px;
+}
+#filesBrowserSites div.collapsed {
+ background: url(siteCollapsed.tif) no-repeat 0px 0px;
+}
+
+#filesBrowserSites div ul {
+ margin: 0;
+ padding: 0;
+ list-style-type: none;
+ font-weight: normal;
+}
+
+#filesBrowserSites div ul li {
+ margin-left: -25px;
+ height: 15px;
+ padding-left: 38px;
+ margin-top: 1px;
+ margin-bottom: 1px;
+ background: url(fileIcon.jpg) no-repeat 26px 0%;
+ cursor: default;
+ overflow: hidden;
+}
+
+#filesBrowserSites div ul li.active {
+ background-color: #ccc;
+}
+
+#filesBrowserSites div ul li.passive {
+ background-color: white;
+}
+
+#files, #functions {
+ opacity: 0;
+ position: absolute;
+ top: -2px;
+ left: -3px;
+ right: 0;
+ z-index: 10;
+ margin: 0;
+ padding: 0;
+ min-width: 100px;
+}
+
+button.popup {
+ background: url(popUpArrows.png) right no-repeat;
+ border: none;
+ height: 15px;
+ font-size: 10px;
+ line-height: 10px;
+ padding: 0 20px 0 5px;
+ margin: 0;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ position: relative;
+ min-width: 100px;
+ max-width: 350px;
+}
+
+#filesPopupButtonContent, #functionButtonContent {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ width: 100%;
+ height: 100%;
+ line-height: 12px;
+ text-align: left;
+}
+
+.placeholder { color: rgba(0, 0, 0, 0.6) }
+
+button.nav {
+ position: relative;
+ width: 32px;
+ height: 15px;
+ border: none;
+ margin: 0;
+ padding: 0;
+ border-left: 1px solid transparent;
+ border-right: 1px solid #aaa;
+}
+
+button.nav.right {
+ background: url(navRightNormal.png) no-repeat;
+}
+
+button.nav.right:disabled, button.nav.right:disabled:active {
+ border-left: 1px solid transparent;
+ background: url(navRightDisabled.png) no-repeat;
+}
+
+button.nav.right:active {
+ border-left: 1px solid rgba(0, 0, 0, 0.3);
+ background: url(navRightPressed.png) no-repeat;
+}
+
+button.nav.left {
+ background: url(navLeftNormal.png) no-repeat;
+}
+
+button.nav.left:disabled, button.nav.left:disabled:active {
+ border-left: 1px solid transparent;
+ background: url(navLeftDisabled.png) no-repeat;
+}
+
+button.nav.left:active {
+ margin-left: 0;
+ border-left: 1px solid rgba(0, 0, 0, 0.3);
+ background: url(navLeftPressed.png) no-repeat;
+}
+
+#leftPane {
+ position: absolute;
+ top: 0;
+ bottom: 10px;
+ left: 0;
+ width: 253px;
+ padding: 0;
+ margin: 0;
+}
+
+#rightPane {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ right: 0;
+ left: 253px;
+ padding: 0;
+ margin: 0;
+}
+
+#stackframe {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ right: 0;
+ left: 0;
+}
+
+#stackframeBody {
+ overflow-y: scroll;
+ overflow-x: hidden;
+ position: absolute;
+ top: 16px;
+ bottom: 0;
+ right: 0;
+ left: 0;
+}
+
+#variables {
+ position: absolute;
+ top: 0;
+ bottom: 10px;
+ right: 0;
+ left: 10px;
+}
+
+#variablesBody {
+ overflow-y: scroll;
+ overflow-x: hidden;
+ position: absolute;
+ top: 16px;
+ bottom: 0;
+ right: 0;
+ left: 0;
+}
+
+.infoBackground {
+ background: url(background_stripe.png) repeat;
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ right: 0;
+ left: 0;
+ z-index: -1;
+}
+
+table {
+ font-family: "Lucida Grande", sans-serif;
+ font-size: 11px;
+ border-collapse: collapse;
+ border-spacing: 0;
+ width: 100%;
+ padding: 0;
+ margin: 0;
+ border: 0;
+}
+
+td {
+ padding: 3px 7px 3px 9px;
+ height: 15px;
+ -webkit-box-sizing: border-box;
+ -webkit-user-select: none;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+tr.current {
+ background-color: rgb(56, 117, 215);
+ color: white;
+}
+
+.stackNumber {
+ width: 2em;
+ padding: 3px 0;
+ text-align: center;
+}
+
+.variable {
+ width: 170px;
+}
+
+.column th.scrollCorner {
+ width: 15px;
+ padding: 0;
+ border-right: none;
+}
+
+#variableColumnResizer {
+ position: absolute;
+ top: 0;
+ left: 168px;
+ width: 4px;
+ height: 16px;
+ cursor: col-resize;
+}
+
+.column th {
+ background: url(glossyHeader.png) repeat-x;
+ border-right: 1px solid #d9d9d9;
+ height: 15px;
+ -webkit-box-sizing: border-box;
+ border-bottom: 1px solid #aaa;
+ font-weight: normal;
+ vertical-align: middle;
+ padding: 0 8px;
+ text-align: left;
+ -webkit-user-select: none;
+}
diff --git a/WebKitTools/Drosera/debugger.html b/WebKitTools/Drosera/debugger.html
new file mode 100644
index 0000000..4b9685d
--- /dev/null
+++ b/WebKitTools/Drosera/debugger.html
@@ -0,0 +1,92 @@
+<!--
+Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+Copyright (C) 2006, 2007 Vladimir Olexa (vladimir.olexa@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.
+-->
+<!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" />
+ <title>Debugger</title>
+ <script type="text/javascript" src="debugger.js"></script>
+ <style type="text/css">
+ @import "debugger.css";
+ </style>
+</head>
+<body onload="loaded()">
+<div id="masterMain">
+<div id="fileBrowser">
+<div id="fileList">
+<table id="fileListTableHeader">
+<tr class="column"><th onmousedown="headerMouseDown(this);" onmouseup="headerMouseUp(this);" onmouseout="headerMouseOut(this);">Files</th><th class="scrollCorner"></th></tr>
+</table>
+<div id="filesBrowserSites">
+</div>
+<div class="footer"></div>
+</div>
+<div id="filesDivider"></div>
+</div>
+<div id="main">
+<div id="info">
+<div id="leftPane">
+<div id="stackframe">
+<table id="stackframeTableHeader">
+<tr class="column"><th class="stackNumber" onmousedown="headerMouseDown(this);" onmouseup="headerMouseUp(this);" onmouseout="headerMouseOut(this);">#</th><th onmousedown="headerMouseDown(this);" onmouseup="headerMouseUp(this);" onmouseout="headerMouseOut(this);">Function</th><th class="scrollCorner"></th></tr>
+</table>
+<div id="stackframeBody">
+<div class="infoBackground"></div>
+<table id="stackframeTable"></table>
+</div>
+</div>
+</div>
+<div id="rightPane">
+<div id="infoDivider"></div>
+<div id="variables">
+<table id="variablesTableHeader">
+<tr class="column"><th class="variable" id="variable" onmousedown="headerMouseDown(this);" onmouseup="headerMouseUp(this);" onmouseout="headerMouseOut(this);">Variable<div id="variableColumnResizer"></div>
+</th><th onmousedown="headerMouseDown(this);" onmouseup="headerMouseUp(this);" onmouseout="headerMouseOut(this);">Value</th><th class="scrollCorner"></th></tr>
+</table>
+<div id="variablesBody">
+<div class="infoBackground"></div>
+<table id="variablesTable"></table>
+</div>
+</div>
+</div>
+<div id="divider"></div>
+</div>
+<div id="body">
+<div id="header">
+<button id="navFileLeftButton" class="nav left" disabled onclick="navFilePrevious(this)"></button><button id="navFileRightButton" class="nav right" disabled onclick="navFileNext(this)"></button>
+<button class="popup"><select size="1" id="files" onchange="switchFile()"></select><div id="filesPopupButtonContent"><span class="placeholder">&lt;No files loaded&gt;</span></div></button>
+<button class="popup" id="functionNamesPopup" style="display: none"><select size="1" id="functions" onchange="switchFunction(this.selectedIndex)"></select><div id="functionPopupButtonContent"><span class="placeholder">&lt;No selected symbol&gt;</span></div></button>
+</div>
+<div id="sourcesContainer"><iframe name="sourcesFrame" id="sources" src="viewer.html"></iframe></div>
+<div class="footer"></div>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/WebKitTools/Drosera/debugger.js b/WebKitTools/Drosera/debugger.js
new file mode 100644
index 0000000..076fedf
--- /dev/null
+++ b/WebKitTools/Drosera/debugger.js
@@ -0,0 +1,1433 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 David Smith (catfish.man@gmail.com)
+ * Copyright (C) 2007 Vladimir Olexa (vladimir.olexa@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 files = new Array();
+var filesLookup = new Object();
+var scripts = new Array();
+var currentFile = -1;
+var currentRow = null;
+var currentStack = null;
+var currentCallFrame = null;
+var lastStatement = null;
+var frameLineNumberStack = new Array();
+var previousFiles = new Array();
+var nextFiles = new Array();
+var isResizingColumn = false;
+var draggingBreakpoint = null;
+var steppingOut = false;
+var steppingOver = false;
+var steppingStack = 0;
+var pauseOnNextStatement = false;
+var pausedWhileLeavingFrame = false;
+var consoleWindow = null;
+var breakpointEditorHTML = DebuggerDocument.breakpointEditorHTML();
+var pendingAction = null;
+var isPaused = false;
+
+ScriptCallFrame = function (functionName, index, row)
+{
+ this.functionName = functionName;
+ this.index = index;
+ this.row = row;
+ this.localVariableNames = null;
+}
+
+ScriptCallFrame.prototype.valueForScopeVariable = function (name)
+{
+ return DebuggerDocument.valueForScopeVariableNamed(name, this.index);
+}
+
+ScriptCallFrame.prototype.loadVariables = function ()
+{
+ if (!this.localVariableNames)
+ this.localVariableNames = DebuggerDocument.localScopeVariableNamesForCallFrame(this.index);
+
+ var variablesTable = document.getElementById("variablesTable");
+ variablesTable.innerHTML = "";
+
+ if (!this.localVariableNames)
+ return;
+
+ for(var i = 0; i < this.localVariableNames.length; i++) {
+ var tr = document.createElement("tr");
+ var td = document.createElement("td");
+ td.innerText = this.localVariableNames[i];
+ td.className = "variable";
+ tr.appendChild(td);
+
+ td = document.createElement("td");
+ td.innerText = this.valueForScopeVariable(this.localVariableNames[i]);
+ tr.appendChild(td);
+ tr.addEventListener("click", selectVariable, true);
+
+ variablesTable.appendChild(tr);
+ }
+}
+
+function sleep(numberMillis)
+{
+ var now = new Date();
+ var exitTime = now.getTime() + numberMillis;
+ while (true) {
+ now = new Date();
+ if (now.getTime() > exitTime)
+ return;
+ }
+}
+
+function headerMouseDown(element)
+{
+ if (!isResizingColumn)
+ element.style.background = "url(glossyHeaderPressed.png) repeat-x";
+}
+
+function headerMouseUp(element)
+{
+ element.style.background = "url(glossyHeader.png) repeat-x";
+}
+
+function headerMouseOut(element)
+{
+ element.style.background = "url(glossyHeader.png) repeat-x";
+}
+
+function filesDividerDragStart(event)
+{
+ dividerDragStart(document.getElementById("filesDivider"), filesDividerDrag, filesDividerDragEnd, event, "col-resize");
+}
+
+function filesDividerDragEnd(event)
+{
+ dividerDragEnd(document.getElementById("filesDivider"), filesDividerDrag, filesDividerDragEnd, event);
+}
+
+function filesDividerDrag(event)
+{
+ var element = document.getElementById("filesDivider");
+ if (document.getElementById("filesDivider").dragging == true) {
+ var masterMain = document.getElementById("masterMain");
+ var main = document.getElementById("main");
+ var fileBrowser = document.getElementById("fileBrowser");
+ var x = event.clientX + window.scrollX;
+ var delta = element.dragLastX - x;
+ var newWidth = constrainedWidthFromElement(fileBrowser.clientWidth - delta, masterMain, 0.1, 0.9);
+ if ((fileBrowser.clientWidth - delta) == newWidth) // the width wasn't constrained
+ element.dragLastX = x;
+ fileBrowser.style.width = newWidth + "px";
+ main.style.left = newWidth + "px";
+ event.preventDefault();
+ }
+}
+
+function dividerDragStart(element, dividerDrag, dividerDragEnd, event, cursor)
+{
+ element.dragging = true;
+ element.dragLastY = event.clientY + window.scrollY;
+ element.dragLastX = event.clientX + window.scrollX;
+ document.addEventListener("mousemove", dividerDrag, true);
+ document.addEventListener("mouseup", dividerDragEnd, true);
+ document.body.style.cursor = cursor;
+ event.preventDefault();
+}
+
+function dividerDragEnd(element, dividerDrag, dividerDragEnd, event)
+{
+ element.dragging = false;
+ document.removeEventListener("mousemove", dividerDrag, true);
+ document.removeEventListener("mouseup", dividerDragEnd, true);
+ document.body.style.removeProperty("cursor");
+}
+
+function dividerDrag(event)
+{
+ var element = document.getElementById("divider");
+ if (document.getElementById("divider").dragging == true) {
+ var main = document.getElementById("main");
+ var top = document.getElementById("info");
+ var bottom = document.getElementById("body");
+ var y = event.clientY + window.scrollY;
+ var delta = element.dragLastY - y;
+ var newHeight = constrainedHeightFromElement(top.clientHeight - delta, main);
+ if ((top.clientHeight - delta) == newHeight) // the height wasn't constrained
+ element.dragLastY = y;
+ top.style.height = newHeight + "px";
+ bottom.style.top = newHeight + "px";
+ event.preventDefault();
+ }
+}
+
+function sourceDividerDragStart(event)
+{
+ dividerDragStart(document.getElementById("divider"), dividerDrag, sourceDividerDragEnd, event, "row-resize");
+}
+
+function sourceDividerDragEnd(event)
+{
+ dividerDragEnd(document.getElementById("divider"), dividerDrag, sourceDividerDragEnd, event);
+}
+
+function infoDividerDragStart(event)
+{
+ dividerDragStart(document.getElementById("infoDivider"), infoDividerDrag, infoDividerDragEnd, event, "col-resize");
+}
+
+function infoDividerDragEnd(event)
+{
+ dividerDragEnd(document.getElementById("infoDivider"), infoDividerDrag, infoDividerDragEnd, event);
+}
+
+function infoDividerDrag(event)
+{
+ var element = document.getElementById("infoDivider");
+ if (document.getElementById("infoDivider").dragging == true) {
+ var main = document.getElementById("main");
+ var leftPane = document.getElementById("leftPane");
+ var rightPane = document.getElementById("rightPane");
+ var x = event.clientX + window.scrollX;
+ var delta = element.dragLastX - x;
+ var newWidth = constrainedWidthFromElement(leftPane.clientWidth - delta, main);
+ if ((leftPane.clientWidth - delta) == newWidth) // the width wasn't constrained
+ element.dragLastX = x;
+ leftPane.style.width = newWidth + "px";
+ rightPane.style.left = newWidth + "px";
+ event.preventDefault();
+ }
+}
+
+function columnResizerDragStart(event)
+{
+ isResizingColumn = true;
+ dividerDragStart(document.getElementById("variableColumnResizer"), columnResizerDrag, columnResizerDragEnd, event, "col-resize");
+}
+
+function columnResizerDragEnd(event)
+{
+ isResizingColumn = false;
+ dividerDragEnd(document.getElementById("variableColumnResizer"), columnResizerDrag, columnResizerDragEnd, event);
+}
+
+function columnResizerDrag(event)
+{
+ var element = document.getElementById("variableColumnResizer");
+ if (element.dragging == true) {
+ var main = document.getElementById("rightPane");
+ var variableColumn = document.getElementById("variable");
+ var rules = document.defaultView.getMatchedCSSRules(variableColumn, "");
+ for (var i = 0; i < rules.length; i++) {
+ if (rules[i].selectorText == ".variable") {
+ var columnRule = rules[i];
+ break;
+ }
+ }
+
+ var x = event.clientX + window.scrollX;
+ var delta = element.dragLastX - x;
+ var newWidth = constrainedWidthFromElement(variableColumn.clientWidth - delta, main);
+ if ((variableColumn.clientWidth - delta) == newWidth) // the width wasn't constrained
+ element.dragLastX = x;
+ columnRule.style.width = newWidth + "px";
+ element.style.left = newWidth + "px";
+ event.preventDefault();
+ }
+}
+
+function constrainedWidthFromElement(width, element, constrainLeft, constrainRight)
+{
+ if (constrainLeft === undefined) constrainLeft = 0.25;
+ if (constrainRight === undefined) constrainRight = 0.75;
+
+ if (width < element.clientWidth * constrainLeft)
+ width = element.clientWidth * constrainLeft;
+ else if (width > element.clientWidth * constrainRight)
+ width = element.clientWidth * constrainRight;
+ return width;
+}
+
+function constrainedHeightFromElement(height, element)
+{
+ if (height < element.clientHeight * 0.25)
+ height = element.clientHeight * 0.25;
+ else if (height > element.clientHeight * 0.75)
+ height = element.clientHeight * 0.75;
+ return height;
+}
+
+function loaded()
+{
+ document.getElementById("divider").addEventListener("mousedown", sourceDividerDragStart, false);
+ document.getElementById("infoDivider").addEventListener("mousedown", infoDividerDragStart, false);
+ document.getElementById("filesDivider").addEventListener("mousedown", filesDividerDragStart, false);
+ document.getElementById("variableColumnResizer").addEventListener("mousedown", columnResizerDragStart, false);
+}
+
+function pause()
+{
+ DebuggerDocument.pause();
+ isPaused = true;
+}
+
+function resume()
+{
+ if (currentRow) {
+ currentRow.removeStyleClass("current");
+ currentRow = null;
+ }
+
+ var stackframeTable = document.getElementById("stackframeTable");
+ stackframeTable.innerHTML = ""; // clear the content
+ var variablesTable = document.getElementById("variablesTable");
+ variablesTable.innerHTML = ""; // clear the content
+ currentStack = null;
+ currentCallFrame = null;
+
+ pauseOnNextStatement = false;
+ pausedWhileLeavingFrame = false;
+ steppingOut = false;
+ steppingOver = false;
+ steppingStack = 0;
+
+ DebuggerDocument.resume();
+ isPaused = false;
+}
+
+function stepInto()
+{
+ pauseOnNextStatement = false;
+ steppingOut = false;
+ steppingOver = false;
+ steppingStack = 0;
+ DebuggerDocument.stepInto();
+}
+
+function stepOver()
+{
+ pauseOnNextStatement = false;
+ steppingOver = true;
+ steppingStack = 0;
+ DebuggerDocument.resume();
+}
+
+function stepOut()
+{
+ pauseOnNextStatement = pausedWhileLeavingFrame;
+ steppingOver = false;
+ steppingStack = 0;
+ steppingOut = true;
+ DebuggerDocument.resume();
+}
+
+Element.prototype.removeStyleClass = function(className)
+{
+ if (this.hasStyleClass(className))
+ this.className = this.className.replace(className, "");
+}
+
+Element.prototype.addStyleClass = function(className)
+{
+ if (!this.hasStyleClass(className))
+ this.className += (this.className.length ? " " + className : className);
+}
+
+Element.prototype.hasStyleClass = function(className)
+{
+ return this.className.indexOf(className) != -1;
+}
+
+Element.prototype.firstParentWithClass = function(className)
+{
+ var node = this.parentNode;
+ while(!node.hasStyleClass(className)) {
+ if (node == document)
+ return null;
+ node = node.parentNode;
+ }
+ return node;
+}
+
+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);
+}
+
+function breakpointAction(event)
+{
+ var file = files[currentFile];
+ var lineNum = event.target.title;
+
+ if (!file.breakpoints[lineNum])
+ file.breakpoints[lineNum] = new BreakPoint(event.target.parentNode, file, lineNum);
+ else
+ toggleBreakpointOnLine(lineNum);
+}
+
+BreakPoint = function(row, file, line)
+{
+ this.row = row;
+ this.file = file;
+ this.line = line;
+ row.addStyleClass("breakpoint");
+ row.removeStyleClass("disabled");
+ this.value = "break";
+ this.enabled = true;
+ this.editor = null;
+ this.type = 0;
+ this.hitcount = 0;
+}
+
+function toggleBreakpointEditorOnLine(lineNum)
+{
+ if (pendingAction) {
+ clearTimeout(pendingAction);
+ pendingAction = null;
+ }
+ var file = files[currentFile];
+ bp = file.breakpoints[lineNum];
+ if (bp) {
+ var editor = bp.editor;
+ if (!editor) {
+ var sourcesDocument = document.getElementById("sources").contentDocument;
+ editor = sourcesDocument.createElement("div");
+ editor.className = "editor";
+ editor.id = lineNum;
+ editor.innerHTML = breakpointEditorHTML;
+
+ bp.row.childNodes[1].appendChild(editor);
+
+ bp.editor = editor;
+ file.breakpoints[lineNum] = bp;
+
+ editor.query('.//input[@class="enable"]').checked = bp.enabled;
+
+ editor.query('.//select[@class="editorDropdown"]').selectedIndex = bp.type;
+ updateBreakpointTypeOnLine(lineNum);
+
+ editor.query('.//span[@class="hitCounter"]').innerText = bp.hitcount;
+
+ setConditionFieldText(bp);
+ } else {
+ saveBreakpointOnLine(lineNum);
+ bp.row.childNodes[1].removeChild(editor);
+ bp.editor = null;
+ }
+ }
+}
+
+function updateBreakpointTypeOnLine(line)
+{
+ var breakpoint = files[currentFile].breakpoints[line];
+ var editor = breakpoint.editor;
+ var label = editor.query('.//label[@class="conditionLabel"]');
+ var dropdown = editor.query('.//select[@class="editorDropdown"]');
+ breakpoint.type = dropdown.selectedIndex;
+ switch(breakpoint.type) {
+ case 0:
+ label.innerText = "Condition:";
+ break;
+ case 1:
+ label.innerText = "Expression:";
+ break;
+ }
+}
+
+function setConditionFieldText(breakpoint)
+{
+ var conditionField = breakpoint.editor.query('.//div[@class="condition"]');
+
+ var functionBody = breakpoint.value;
+ if (!functionBody || functionBody == "break")
+ functionBody = "";
+ else {
+ var startIndex = functionBody.indexOf("return((") + 8;
+ var endIndex = null;
+ if (startIndex != 7) //-1 + 8, yes, that's lame
+ endIndex = functionBody.lastIndexOf("))");
+ else {
+ startIndex = functionBody.indexOf("{") + 1;
+ endIndex = functionBody.lastIndexOf("}");
+ }
+ functionBody = functionBody.substring(startIndex, endIndex);
+ }
+ conditionField.innerText = functionBody;
+ conditionField.addEventListener("keyup", new Function("saveBreakpointOnLine(" + breakpoint.line + ");"), false);
+ conditionField.focus();
+}
+
+function saveBreakpointOnLine(lineNum)
+{
+ var file = files[currentFile];
+ var breakpoint = file.breakpoints[lineNum];
+ row = file.element.firstChild.childNodes.item(lineNum - 1);
+ var editor = breakpoint.editor;
+ var body = editor.query('.//div[@class="condition"]').innerText;
+ var actionIndex = editor.query('.//select[@class="editorDropdown"]').selectedIndex;
+ if (body.length == 0)
+ breakpoint.value = "break";
+ else if (body.indexOf("return") != -1)
+ breakpoint.value = "__drosera_breakpoint_conditional_func = function() {" + body + "}; __drosera_breakpoint_conditional_func();";
+ else
+ breakpoint.value = "__drosera_breakpoint_conditional_func = function() { return((" + body + ")); }; __drosera_breakpoint_conditional_func();";
+}
+
+function toggleBreakpointOnLine(lineNum)
+{
+ var breakpoint = files[currentFile].breakpoints[lineNum];
+ pendingAction = null;
+ if (breakpoint.enabled)
+ breakpoint.row.addStyleClass("disabled");
+ else
+ breakpoint.row.removeStyleClass("disabled");
+
+ var hack = breakpoint.row.offsetTop; // force a relayout if needed.
+
+ breakpoint.enabled = !breakpoint.enabled;
+ var editor = breakpoint.editor;
+ if (editor) {
+ editor.query('.//input[@class="enable"]').checked = breakpoint.enabled;
+ setConditionFieldText(breakpoint, lineNum);
+ }
+}
+
+function moveBreakPoint(event)
+{
+ if (event.target.parentNode.hasStyleClass("breakpoint")) {
+ draggingBreakpoint = event.target;
+ draggingBreakpoint.started = false;
+ draggingBreakpoint.dragLastY = event.clientY + window.scrollY;
+ draggingBreakpoint.dragLastX = event.clientX + window.scrollX;
+ var sourcesDocument = document.getElementById("sources").contentDocument;
+ sourcesDocument.addEventListener("mousemove", breakpointDrag, true);
+ sourcesDocument.addEventListener("mouseup", breakpointDragEnd, true);
+ sourcesDocument.body.style.cursor = "default";
+ }
+}
+
+function breakpointDrag(event)
+{
+ var sourcesDocument = document.getElementById("sources").contentDocument;
+ if (!draggingBreakpoint) {
+ sourcesDocument.removeEventListener("mousemove", breakpointDrag, true);
+ sourcesDocument.removeEventListener("mouseup", breakpointDragEnd, true);
+ sourcesDocument.body.style.removeProperty("cursor");
+ return;
+ }
+
+ var x = event.clientX + window.scrollX;
+ var y = event.clientY + window.scrollY;
+ var deltaX = draggingBreakpoint.dragLastX - x;
+ var deltaY = draggingBreakpoint.dragLastY - y;
+ if (draggingBreakpoint.started || deltaX > 4 || deltaY > 4 || deltaX < -4 || deltaY < -4) {
+
+ if (!draggingBreakpoint.started) {
+ var lineNum = draggingBreakpoint.title;
+ var file = files[currentFile];
+ var breakpoint = file.breakpoints[lineNum];
+ draggingBreakpoint.breakpoint = breakpoint;
+ breakpoint.row.removeStyleClass("breakpoint");
+ breakpoint.row.removeStyleClass("disabled");
+
+ var editor = breakpoint.editor;
+ if (editor)
+ toggleBreakpointEditorOnLine(lineNum);
+
+ draggingBreakpoint.started = true;
+
+ file.breakpoints[lineNum] = null;
+
+ var dragImage = sourcesDocument.createElement("img");
+ if (draggingBreakpoint.breakpoint.enabled)
+ dragImage.src = "breakPoint.tif";
+ else
+ dragImage.src = "breakPointDisabled.tif";
+
+ dragImage.id = "breakpointDrag";
+ dragImage.style.top = y - 8 + "px";
+ dragImage.style.left = x - 12 + "px";
+ sourcesDocument.body.appendChild(dragImage);
+ } else {
+ var dragImage = sourcesDocument.getElementById("breakpointDrag");
+ if (!dragImage) {
+ sourcesDocument.removeEventListener("mousemove", breakpointDrag, true);
+ sourcesDocument.removeEventListener("mouseup", breakpointDragEnd, true);
+ sourcesDocument.body.style.removeProperty("cursor");
+ return;
+ }
+
+ dragImage.style.top = y - 8 + "px";
+ dragImage.style.left = x - 12 + "px";
+ if (x > 40)
+ dragImage.style.visibility = "hidden";
+ else
+ dragImage.style.removeProperty("visibility");
+ }
+
+ draggingBreakpoint.dragLastX = x;
+ draggingBreakpoint.dragLastY = y;
+ }
+}
+
+function breakpointDragEnd(event)
+{
+ var sourcesDocument = document.getElementById("sources").contentDocument;
+ sourcesDocument.removeEventListener("mousemove", breakpointDrag, true);
+ sourcesDocument.removeEventListener("mouseup", breakpointDragEnd, true);
+ sourcesDocument.body.style.removeProperty("cursor");
+
+ var dragImage = sourcesDocument.getElementById("breakpointDrag");
+ if (!dragImage)
+ return;
+
+ dragImage.parentNode.removeChild(dragImage);
+
+ var x = event.clientX + window.scrollX;
+ if (x > 40 || !draggingBreakpoint)
+ return;
+
+ var y = event.clientY + window.scrollY;
+ var rowHeight = draggingBreakpoint.parentNode.offsetHeight;
+ var row = Math.ceil(y / rowHeight);
+ if (row <= 0)
+ row = 1;
+
+ var file = files[currentFile];
+ var table = file.element.firstChild;
+ if (row > table.childNodes.length)
+ return;
+
+ var tr = table.childNodes.item(row - 1);
+ if (!tr)
+ return;
+
+ var breakpoint = draggingBreakpoint.breakpoint;
+ breakpoint.row = tr;
+
+ // leave the editor there if it exists... we'll want to update it to the new values
+ breakpoint.editor = file.breakpoints[row].editor;
+
+ file.breakpoints[row] = breakpoint;
+
+ if (breakpoint.editor) {
+ breakpoint.editor.id = row;
+ updateBreakpointTypeOnLine(row);
+ setConditionFieldText(breakpoint);
+ }
+
+ if (!breakpoint.enabled)
+ tr.addStyleClass("disabled");
+
+ tr.addStyleClass("breakpoint");
+
+ draggingBreakpoint = null;
+}
+
+function totalOffsetTop(element, stop)
+{
+ var currentTop = 0;
+ while (element.offsetParent) {
+ currentTop += element.offsetTop
+ element = element.offsetParent;
+ if (element == stop)
+ break;
+ }
+ return currentTop;
+}
+
+function switchFile(fileIndex)
+{
+ var filesSelect = document.getElementById("files");
+
+ if (fileIndex === undefined)
+ fileIndex = filesSelect.selectedIndex;
+
+ fileClicked(filesSelect.options[fileIndex].value, false);
+ loadFile(filesSelect.options[fileIndex].value, true);
+}
+
+function syntaxHighlight(code, file)
+{
+ var keywords = { 'abstract': 1, 'boolean': 1, 'break': 1, 'byte': 1, 'case': 1, 'catch': 1, 'char': 1, 'class': 1, 'const': 1, 'continue': 1, 'debugger': 1, 'default': 1, 'delete': 1, 'do': 1, 'double': 1, 'else': 1, 'enum': 1, 'export': 1, 'extends': 1, 'false': 1, 'final': 1, 'finally': 1, 'float': 1, 'for': 1, 'function': 1, 'goto': 1, 'if': 1, 'implements': 1, 'import': 1, 'in': 1, 'instanceof': 1, 'int': 1, 'interface': 1, 'long': 1, 'native': 1, 'new': 1, 'null': 1, 'package': 1, 'private': 1, 'protected': 1, 'public': 1, 'return': 1, 'short': 1, 'static': 1, 'super': 1, 'switch': 1, 'synchronized': 1, 'this': 1, 'throw': 1, 'throws': 1, 'transient': 1, 'true': 1, 'try': 1, 'typeof': 1, 'var': 1, 'void': 1, 'volatile': 1, 'while': 1, 'with': 1 };
+
+ function echoChar(c) {
+ if (c == '<')
+ result += '&lt;';
+ else if (c == '>')
+ result += '&gt;';
+ else if (c == '&')
+ result += '&amp;';
+ else if (c == '\t')
+ result += ' ';
+ else
+ result += c;
+ }
+
+ function isDigit(number) {
+ var string = "1234567890";
+ if (string.indexOf(number) != -1)
+ return true;
+ return false;
+ }
+
+ function isHex(hex) {
+ var string = "1234567890abcdefABCDEF";
+ if (string.indexOf(hex) != -1)
+ return true;
+ return false;
+ }
+
+ function isLetter(letter) {
+ var string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ if (string.indexOf(letter) != -1)
+ return true;
+ return false;
+ }
+
+ var result = "";
+ var cPrev = "";
+ var c = "";
+ var cNext = "";
+ for (var i = 0; i < code.length; i++) {
+ cPrev = c;
+ c = code.charAt(i);
+ cNext = code.charAt(i + 1);
+
+ if (c == "/" && cNext == "*") {
+ result += "<span class=\"comment\">";
+ echoChar(c);
+ echoChar(cNext);
+ for (i += 2; i < code.length; i++) {
+ c = code.charAt(i);
+ if (c == "\n")
+ result += "</span>";
+ echoChar(c);
+ if (c == "\n")
+ result += "<span class=\"comment\">";
+ if (cPrev == "*" && c == "/")
+ break;
+ cPrev = c;
+ }
+ result += "</span>";
+ continue;
+ } else if (c == "/" && cNext == "/") {
+ result += "<span class=\"comment\">";
+ echoChar(c);
+ echoChar(cNext);
+ for (i += 2; i < code.length; i++) {
+ c = code.charAt(i);
+ if (c == "\n")
+ break;
+ echoChar(c);
+ }
+ result += "</span>";
+ echoChar(c);
+ continue;
+ } else if (c == "\"" || c == "'") {
+ var instringtype = c;
+ var stringstart = i;
+ result += "<span class=\"string\">";
+ echoChar(c);
+ for (i += 1; i < code.length; i++) {
+ c = code.charAt(i);
+ if (stringstart < (i - 1) && cPrev == instringtype && code.charAt(i - 2) != "\\")
+ break;
+ echoChar(c);
+ cPrev = c;
+ }
+ result += "</span>";
+ echoChar(c);
+ continue;
+ } else if (c == "0" && cNext == "x" && (i == 0 || (!isLetter(cPrev) && !isDigit(cPrev)))) {
+ result += "<span class=\"number\">";
+ echoChar(c);
+ echoChar(cNext);
+ for (i += 2; i < code.length; i++) {
+ c = code.charAt(i);
+ if (!isHex(c))
+ break;
+ echoChar(c);
+ }
+ result += "</span>";
+ echoChar(c);
+ continue;
+ } else if ((isDigit(c) || ((c == "-" || c == ".") && isDigit(cNext))) && (i == 0 || (!isLetter(cPrev) && !isDigit(cPrev)))) {
+ result += "<span class=\"number\">";
+ echoChar(c);
+ for (i += 1; i < code.length; i++) {
+ c = code.charAt(i);
+ if (!isDigit(c) && c != ".")
+ break;
+ echoChar(c);
+ }
+ result += "</span>";
+ echoChar(c);
+ continue;
+ } else if (isLetter(c) && (i == 0 || !isLetter(cPrev))) {
+ var keyword = c;
+ var cj = "";
+ for (var j = i + 1; j < i + 12 && j < code.length; j++) {
+ cj = code.charAt(j);
+ if (!isLetter(cj))
+ break;
+ keyword += cj;
+ }
+
+ if (keywords[keyword]) {
+ var functionName = "";
+ var functionIsAnonymous = false;
+ if (keyword == "function") {
+ var functionKeywordOffset = 8;
+ for (var j = i + functionKeywordOffset; j < code.length; j++) {
+ cj = code.charAt(j);
+ if (cj == " ")
+ continue;
+ if (cj == "(")
+ break;
+ functionName += cj;
+ }
+
+ if (!functionName.length) {
+ functionIsAnonymous = true;
+ var functionAssignmentFound = false;
+ var functionNameStart = -1;
+ var functionNameEnd = -1;
+
+ for (var j = i - 1; j >= 0; j--) {
+ cj = code.charAt(j);
+ if (cj == ":" || cj == "=") {
+ functionAssignmentFound = true;
+ continue;
+ }
+
+ var curCharIsSpace = (cj == " " || cj == "\t" || cj == "\n");
+ if (functionAssignmentFound && functionNameEnd == -1 && !curCharIsSpace) {
+ functionNameEnd = j + 1;
+ } else if (!functionAssignmentFound && !curCharIsSpace) {
+ break;
+ } else if (functionNameEnd != -1 && curCharIsSpace) {
+ functionNameStart = j;
+ break;
+ }
+ }
+
+ if (functionNameStart != -1 && functionNameEnd != -1)
+ functionName = code.substring(functionNameStart, functionNameEnd);
+ }
+
+ if (!functionName.length)
+ functionName = "function";
+
+ file.functionNames.push(functionName);
+ }
+
+ var fileIndex = filesLookup[file.url];
+
+ if (keyword == "function" && functionIsAnonymous)
+ result += "<span class=\"keyword\"><a name=\"function-" + fileIndex + "-" + file.functionNames.length + "\" id=\"" + fileIndex + "-" + file.functionNames.length + "\">" + keyword + "</a></span>";
+ else
+ result += "<span class=\"keyword\">" + keyword + "</span>";
+
+ if (functionName.length && !functionIsAnonymous) {
+ result += " <a name=\"function-" + fileIndex + "-" + file.functionNames.length + "\" id=\"" + fileIndex + "-" + file.functionNames.length + "\">" + functionName + "</a>";
+ i += keyword.length + functionName.length;
+ } else
+ i += keyword.length - 1;
+
+ continue;
+ }
+ }
+
+ echoChar(c);
+ }
+
+ return result;
+}
+
+function navFilePrevious(element)
+{
+ if (element.disabled)
+ return;
+ var lastFile = previousFiles.pop();
+ if (currentFile != -1)
+ nextFiles.unshift(currentFile);
+ loadFile(lastFile, false);
+}
+
+function navFileNext(element)
+{
+ if (element.disabled)
+ return;
+ var lastFile = nextFiles.shift();
+ if (currentFile != -1)
+ previousFiles.push(currentFile);
+ loadFile(lastFile, false);
+}
+
+function updateFunctionStack()
+{
+ var stackframeTable = document.getElementById("stackframeTable");
+ stackframeTable.innerHTML = ""; // clear the content
+
+ currentStack = new Array();
+ var stack = DebuggerDocument.currentFunctionStack();
+ for(var i = 0; i < stack.length; i++) {
+ var tr = document.createElement("tr");
+ var td = document.createElement("td");
+ td.className = "stackNumber";
+ td.innerText = i;
+ tr.appendChild(td);
+
+ td = document.createElement("td");
+ td.innerText = stack[i];
+ tr.appendChild(td);
+ tr.addEventListener("click", selectStackFrame, true);
+
+ stackframeTable.appendChild(tr);
+
+ var frame = new ScriptCallFrame(stack[i], i, tr);
+ tr.callFrame = frame;
+ currentStack.push(frame);
+
+ if (i == 0) {
+ tr.addStyleClass("current");
+ frame.loadVariables();
+ currentCallFrame = frame;
+ }
+ }
+}
+
+function selectStackFrame(event)
+{
+ var stackframeTable = document.getElementById("stackframeTable");
+ var rows = stackframeTable.childNodes;
+ for (var i = 0; i < rows.length; i++)
+ rows[i].removeStyleClass("current");
+ this.addStyleClass("current");
+ this.callFrame.loadVariables();
+ currentCallFrame = this.callFrame;
+
+ if (frameLineNumberInfo = frameLineNumberStack[this.callFrame.index - 1])
+ jumpToLine(frameLineNumberInfo[0], frameLineNumberInfo[1]);
+ else if (this.callFrame.index == 0)
+ jumpToLine(lastStatement[0], lastStatement[1]);
+}
+
+function selectVariable(event)
+{
+ var variablesTable = document.getElementById("variablesTable");
+ var rows = variablesTable.childNodes;
+ for (var i = 0; i < rows.length; i++)
+ rows[i].removeStyleClass("current");
+ this.addStyleClass("current");
+}
+
+function switchFunction(index, shouldResetPopup)
+{
+ if (shouldResetPopup === undefined) shouldResetPopup = false;
+ var sourcesFrame = window.frames['sourcesFrame'];
+
+ if (shouldResetPopup || index == 0) {
+ document.getElementById("functionPopupButtonContent").innerHTML = '<span class="placeholder">&lt;No selected symbol&gt;</span>';
+ return;
+ }
+
+ var functionSelect = document.getElementById("functions");
+ var selectedFunction = functionSelect.childNodes[index];
+ var selection = sourcesFrame.getSelection();
+ var currentFunction = selectedFunction.value;
+ var currentFunctionElement = sourcesFrame.document.getElementById(currentFunction);
+
+ functionSelect.blur();
+ sourcesFrame.focus();
+ selection.setBaseAndExtent(currentFunctionElement, 0, currentFunctionElement, 1);
+ sourcesFrame.location.hash = "#function-" + selectedFunction.value;
+ document.getElementById("functionPopupButtonContent").innerText = selectedFunction.innerText;
+}
+
+function loadFile(fileIndex, manageNavLists)
+{
+ var file = files[fileIndex];
+ if (!file)
+ return;
+
+ if (currentFile != -1 && files[currentFile] && files[currentFile].element)
+ files[currentFile].element.style.display = "none";
+
+ if (!file.loaded) {
+ var sourcesDocument = document.getElementById("sources").contentDocument;
+ var sourcesDiv = sourcesDocument.body;
+ var sourceDiv = sourcesDocument.createElement("div");
+ sourceDiv.id = "file" + fileIndex;
+ sourcesDiv.appendChild(sourceDiv);
+ file.element = sourceDiv;
+
+ var table = sourcesDocument.createElement("table");
+ sourceDiv.appendChild(table);
+
+ var normalizedSource = file.source.replace(/\r\n|\r/g, "\n"); // normalize line endings
+ var lines = syntaxHighlight(normalizedSource, file).split("\n");
+ for( var i = 0; i < lines.length; i++ ) {
+ var tr = sourcesDocument.createElement("tr");
+ var td = sourcesDocument.createElement("td");
+ td.className = "gutter";
+ td.title = (i + 1);
+ td.addEventListener("click", breakpointAction, true);
+ td.addEventListener("dblclick", function(event) { toggleBreakpointEditorOnLine(event.target.title); }, true);
+ td.addEventListener("mousedown", moveBreakPoint, true);
+ tr.appendChild(td);
+
+ td = sourcesDocument.createElement("td");
+ td.className = "source";
+ td.innerHTML = (lines[i].length ? lines[i] : "&nbsp;");
+ tr.appendChild(td);
+ table.appendChild(tr);
+ }
+
+ file.loaded = true;
+ }
+
+ file.element.style.removeProperty("display");
+
+ document.getElementById("filesPopupButtonContent").innerText = (file.url ? file.url : "(unknown script)");
+
+ var filesSelect = document.getElementById("files");
+ for (var i = 0; i < filesSelect.childNodes.length; i++) {
+ if (filesSelect.childNodes[i].value == fileIndex) {
+ filesSelect.selectedIndex = i;
+ break;
+ }
+ }
+
+ // Populate the function names pop-up
+ if (file.functionNames.length > 0) {
+ var functionSelect = document.getElementById("functions");
+ var functionOption = document.createElement("option");
+
+ document.getElementById("functionNamesPopup").style.display = "inline";
+ switchFunction(0, true);
+
+ functionSelect.removeChildren();
+ functionOption.value = null;
+ functionOption.text = "<No selected symbol>";
+ functionSelect.appendChild(functionOption);
+
+ for (var i = 0; i < file.functionNames.length; i++) {
+ functionOption = document.createElement("option");
+ functionOption.value = fileIndex + "-" + (i+1);
+ functionOption.text = file.functionNames[i] + "()";
+ functionSelect.appendChild(functionOption);
+ }
+ } else
+ document.getElementById("functionNamesPopup").style.display = "none";
+
+ if (manageNavLists) {
+ nextFiles = new Array();
+ if (currentFile != -1)
+ previousFiles.push(currentFile);
+ }
+
+ document.getElementById("navFileLeftButton").disabled = (previousFiles.length == 0);
+ document.getElementById("navFileRightButton").disabled = (nextFiles.length == 0);
+
+ //Remember and recall scroll position for current file and file we just loaded
+ var frameBody = document.getElementById("sources").contentDocument.body;
+ if (currentFile != -1)
+ files[currentFile].scrollPosition = frameBody.scrollTop;
+ frameBody.scrollTop = file.scrollPosition;
+ frameBody.scrollLeft = 0;
+
+ currentFile = fileIndex;
+}
+
+function updateFileSource(source, url, force)
+{
+ var fileIndex = filesLookup[url];
+ if (!fileIndex || !source.length)
+ return;
+
+ var file = files[fileIndex];
+ if (force || file.source.length != source.length || file.source != source) {
+ file.source = source;
+ file.loaded = false;
+
+ if (file.element) {
+ file.element.parentNode.removeChild(file.element);
+ file.element = null;
+ }
+
+ if (currentFile == fileIndex || force)
+ loadFile(fileIndex, false);
+ }
+}
+
+/**
+* ParsedURL - this object chops up full URL into two parts:
+ * 1) The domain: everything from http:// to the end of the domain name
+ * 2) The relative path: everything after the domain
+ *
+ * @param string url URL to be processed
+ */
+function ParsedURL(url)
+{
+ // Since we're getting the URL from the browser, we're safe to assume the URL is already well formatted
+ // and so there is no need for more sophisticated regular expression here
+ var url_parts = ((url.substring(0,4)).toLowerCase() == "file") ? url.match(/(file:[\/]{2,3}(\w|\.|-|_|\/|\%|\:)+)\/(.*)/) : url.match(/(http[s]?:\/\/(www)?\.?(\w|\.|-)+\w(:\d{1,5})?)\/?(.*)/);
+ // the domain here is considered the whole http://www.example.org:8000 or file:///Users/user/folder/file.htm string for display purposes
+ this.domain = url_parts[1];
+ // the relative path is everything following the domain
+ this.relativePath = (url_parts[5] === undefined) ? "/" + url_parts[3] : "/" + url_parts[5];
+}
+
+/**
+* SiteBrowser - modifies the file tree via DOM as new files are being open
+ *
+ */
+function SiteBrowser()
+{
+ var fileBrowser = document.getElementById("filesBrowserSites");
+
+ this.addURL = function add(url, fileIndex)
+ {
+ var parsedURL = new ParsedURL(url);
+ var divs = fileBrowser.getElementsByTagName("div");
+
+ if (divs.length == 0) {
+ addNewDomain(parsedURL, fileIndex);
+ } else {
+ var isNew = true;
+ for (var i = 0; i < divs.length; i++) {
+ if (divs[i].id == parsedURL.domain) {
+ var uls = divs[i].getElementsByTagName("ul");
+ var ul = (uls.length > 0) ? uls[0] : document.createElement("ul");
+ var li = document.createElement("li");
+
+ li.id = fileIndex;
+ li.addEventListener("click", fileBrowserMouseEvents, false);
+ li.title = li.innerText = parsedURL.relativePath ? parsedURL.relativePath : "/";
+ ul.appendChild(li);
+ isNew = false;
+ break;
+ }
+ }
+ if (isNew) {
+ addNewDomain(parsedURL, fileIndex);
+ }
+ }
+ }
+
+ this.selectInitialFile = function sf()
+ {
+ if (currentFile == -1)
+ document.getElementById("1").className = "active";
+ }
+
+ function addNewDomain(parsedURL, fileIndex)
+ {
+ var div = document.createElement("div");
+ var ul = document.createElement("ul");
+ var li = document.createElement("li");
+
+ div.id = div.innerText = div.title = parsedURL.domain;
+ div.addEventListener("click", fileBrowserMouseEvents, false);
+ // Maybe we can add some roll-overs here...
+ //div.addEventListener("mouseover", fileBrowserMouseEvents, false);
+ //div.addEventListener("mouseout", fileBrowserMouseEvents, false);
+ li.id = fileIndex;
+ li.addEventListener("click", fileBrowserMouseEvents, false);
+ li.title = li.innerText = parsedURL.relativePath ? parsedURL.relativePath : "/";
+ ul.appendChild(li);
+ div.appendChild(ul);
+ fileBrowser.appendChild(div);
+ }
+
+ function removeFile(fileIndex)
+ {
+ var theFile = document.getElementById(fileIndex);
+ // If we are removing the last file from its site, go ahead and remove the whole site
+ if (theFile.parentNode.childNodes.length < 2) {
+ var theSite = theFile.parentNode.parentNode;
+ theSite.removeChildren();
+ theSite.parentNode.removeChild(theSite);
+ }
+ else
+ theFile.parentNode.removeChild(theFile);
+ }
+}
+
+function fileBrowserMouseEvents(event)
+{
+ switch (event.type)
+ {
+ case "click":
+ // If we clicked on a site, collapse/expand it, if on a file, display it. Since we're only capturing this
+ // event from either a DIV or LI element, we don't have to worry about any ambiguity
+ (event.target.nodeName.toUpperCase() == "DIV") ? toggleCollapseSite(event) : fileClicked(event.target.id);
+ break;
+ }
+}
+
+function fileClicked(fileId, shouldLoadFile)
+{
+ if (shouldLoadFile === undefined)
+ shouldLoadFile = true;
+ if (currentFile != -1)
+ document.getElementById(currentFile).className = "passive";
+ document.getElementById(fileId).className = "active";
+ if (shouldLoadFile)
+ loadFile(fileId, false);
+}
+
+function toggleCollapseSite(event)
+{
+ var thisSite = document.getElementById(event.target.id);
+ var siteFiles = thisSite.getElementsByTagName("ul");
+
+ if (siteFiles[0].style.display == "block" || !siteFiles[0].style.display) {
+ siteFiles[0].style.display = "none";
+ thisSite.className = "collapsed";
+ } else {
+ siteFiles[0].style.display = "block";
+ thisSite.className = "expanded";
+ }
+}
+
+function didParseScript(source, fileSource, url, sourceId, baseLineNumber)
+{
+ var fileIndex = filesLookup[url];
+ var file = files[fileIndex];
+ var firstLoad = false;
+
+ if (!fileIndex || !file) {
+ fileIndex = files.length + 1;
+ if (url.length)
+ filesLookup[url] = fileIndex;
+
+ file = new Object();
+ file.scripts = new Array();
+ file.breakpoints = new Array();
+ file.functionNames = new Array();
+ file.source = (fileSource.length ? fileSource : source);
+ file.url = (url.length ? url : null);
+ file.loaded = false;
+
+ files[fileIndex] = file;
+
+ var filesSelect = document.getElementById("files");
+ var option = document.createElement("option");
+ files[fileIndex].menuOption = option;
+ option.value = fileIndex;
+ option.text = (file.url ? file.url : "(unknown script)");
+ filesSelect.appendChild(option);
+
+ var siteBrowser = new SiteBrowser();
+ siteBrowser.addURL(file.url, fileIndex);
+ siteBrowser.selectInitialFile();
+
+ firstLoad = true;
+ }
+
+ var sourceObj = new Object();
+ sourceObj.file = fileIndex;
+ sourceObj.baseLineNumber = baseLineNumber;
+ file.scripts.push(sourceId);
+ scripts[sourceId] = sourceObj;
+
+ if (!firstLoad)
+ updateFileSource((fileSource.length ? fileSource : source), url, false);
+
+ if (currentFile == -1)
+ loadFile(fileIndex, false);
+}
+
+function jumpToLine(sourceId, line)
+{
+ var script = scripts[sourceId];
+ if (line <= 0 || !script)
+ return;
+
+ var file = files[script.file];
+ if (!file)
+ return;
+
+ if (currentFile != script.file)
+ loadFile(script.file, true);
+ if (currentRow)
+ currentRow.removeStyleClass("current");
+ if (!file.element)
+ return;
+ if (line > file.element.firstChild.childNodes.length)
+ return;
+
+ currentRow = file.element.firstChild.childNodes.item(line - 1);
+ if (!currentRow)
+ return;
+
+ currentRow.addStyleClass("current");
+
+ var sourcesDiv = document.getElementById("sources");
+ var sourcesDocument = document.getElementById("sources").contentDocument;
+ var parent = sourcesDocument.body;
+ var offset = totalOffsetTop(currentRow, parent);
+ if (offset < (parent.scrollTop + 20) || offset > (parent.scrollTop + sourcesDiv.clientHeight - 20))
+ parent.scrollTop = totalOffsetTop(currentRow, parent) - (sourcesDiv.clientHeight / 2) + 10;
+}
+
+function willExecuteStatement(sourceId, line, fromLeavingFrame)
+{
+ var script = scripts[sourceId];
+ if (line <= 0 || !script)
+ return;
+
+ var file = files[script.file];
+ if (!file)
+ return;
+
+ lastStatement = [sourceId, line];
+
+ var breakpoint = file.breakpoints[line];
+
+ var shouldBreak = false;
+
+ if (breakpoint && breakpoint.enabled) {
+ switch(breakpoint.type) {
+ case 0:
+ shouldBreak = (breakpoint.value == "break" || DebuggerDocument.evaluateScript(breakpoint.value, 0) == 1);
+ if (shouldBreak)
+ breakpoint.hitcount++;
+ break;
+ case 1:
+ var message = "Hit breakpoint on line " + line;
+ if (breakpoint.value != "break")
+ message = DebuggerDocument.evaluateScript(breakpoint.value, 0);
+ if (consoleWindow)
+ consoleWindow.appendMessage("", message);
+ breakpoint.hitcount++;
+ break;
+ }
+ var editor = breakpoint.editor;
+ var counter = null;
+ if (editor)
+ counter = breakpoint.editor.query('.//span[@class="hitCounter"]');
+ if (counter)
+ counter.innerText = breakpoint.hitcount;
+ }
+
+ if (pauseOnNextStatement || shouldBreak || (steppingOver && !steppingStack)) {
+ pause();
+ pauseOnNextStatement = false;
+ pausedWhileLeavingFrame = fromLeavingFrame || false;
+ }
+
+ if (isPaused) {
+ updateFunctionStack();
+ jumpToLine(sourceId, line);
+ }
+}
+
+function didEnterCallFrame(sourceId, line)
+{
+ if (steppingOver || steppingOut)
+ steppingStack++;
+
+ if (lastStatement)
+ frameLineNumberStack.unshift(lastStatement);
+ willExecuteStatement(sourceId, line);
+}
+
+function willLeaveCallFrame(sourceId, line)
+{
+ if (line <= 0)
+ resume();
+ willExecuteStatement(sourceId, line, true);
+ frameLineNumberStack.shift();
+ if (!steppingStack)
+ steppingOver = false;
+ if (steppingOut && !steppingStack) {
+ steppingOut = false;
+ pauseOnNextStatement = true;
+ }
+ if ((steppingOver || steppingOut) && steppingStack >= 1)
+ steppingStack--;
+}
+
+function exceptionWasRaised(sourceId, line)
+{
+ pause();
+ updateFunctionStack();
+ jumpToLine(sourceId, line);
+}
+
+function showConsoleWindow()
+{
+ if (!consoleWindow)
+ consoleWindow = window.open("console.html", "console", "top=200, left=200, width=500, height=300, toolbar=yes, resizable=yes");
+ else
+ consoleWindow.focus();
+}
+
+function closeFile(fileIndex)
+{
+ if (fileIndex != -1) {
+ currentFile = -1;
+ var file = files[fileIndex];
+ var sourcesDocument = document.getElementById("sources").contentDocument;
+ // Clean up our file's content
+ sourcesDocument.getElementById("file" + fileIndex).removeChildren();
+ // Remove the file from the open files pool
+ delete sourcesDocument.getElementById("file" + fileIndex);
+
+ var filesSelect = document.getElementById("files");
+ // Select the next loaded file. If we're at the end of the list, loop back to beginning.
+ var nextSelectedFile = (filesSelect.selectedIndex + 1 >= filesSelect.options.length) ? 0 : filesSelect.selectedIndex;
+ // Remove the file from file lists
+ filesSelect.options[filesSelect.selectedIndex] = null;
+ SiteBrowser.removeFile(fileIndex);
+ delete files[fileIndex];
+
+ // Clean up the function list
+ document.getElementById("functions").removeChildren();
+
+ // Display appropriate place-holders, if we closed all files
+ if (filesSelect.options.length < 1) {
+ document.getElementById("filesPopupButtonContent").innerHTML = "<span class='placeholder'>&lt;No files loaded&gt;</span>";
+ document.getElementById("functionNamesPopup").style.display = "none";
+ }
+ else
+ switchFile(nextSelectedFile);
+ }
+}
+
+function closeCurrentFile()
+{
+ closeFile(currentFile);
+}
diff --git a/WebKitTools/Drosera/mac/DebuggerApplication.h b/WebKitTools/Drosera/mac/DebuggerApplication.h
new file mode 100644
index 0000000..4722437
--- /dev/null
+++ b/WebKitTools/Drosera/mac/DebuggerApplication.h
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+@interface DebuggerApplication : NSObject {
+ NSMutableDictionary *knownServerNames;
+ IBOutlet NSPanel *attachWindow;
+ IBOutlet NSTableView *attachTable;
+ IBOutlet NSButton *attachButton;
+}
+- (IBAction)showAttachPanel:(id)sender;
+- (IBAction)attach:(id)sender;
+
+- (NSDictionary *)knownServers;
+@end
diff --git a/WebKitTools/Drosera/mac/DebuggerApplication.mm b/WebKitTools/Drosera/mac/DebuggerApplication.mm
new file mode 100644
index 0000000..35cfa24
--- /dev/null
+++ b/WebKitTools/Drosera/mac/DebuggerApplication.mm
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Computer, 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 "DebuggerApplication.h"
+
+#import "DebuggerClient.h"
+#import "ServerConnection.h"
+
+#import <WebKit/WebCoreStatistics.h>
+
+@implementation DebuggerApplication
+- (void)awakeFromNib
+{
+ NSTableColumn *column = [attachTable tableColumnWithIdentifier:@"name"];
+ NSBrowserCell *cell = [[NSBrowserCell alloc] init];
+ [cell setLeaf:YES];
+ [column setDataCell:cell];
+ [cell release];
+}
+
+- (void)applicationDidFinishLaunching:(NSNotification *)notification
+{
+ [WebCoreStatistics setShouldPrintExceptions:YES];
+
+ knownServerNames = [[NSMutableDictionary alloc] init];
+
+ [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(serverLoaded:) name:WebScriptDebugServerDidLoadNotification object:nil];
+ [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(serverLoaded:) name:WebScriptDebugServerQueryReplyNotification object:nil];
+ [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(serverUnloaded:) name:WebScriptDebugServerWillUnloadNotification object:nil];
+ [[NSDistributedNotificationCenter defaultCenter] postNotificationName:WebScriptDebugServerQueryNotification object:nil];
+
+ [self showAttachPanel:nil];
+}
+
+#pragma mark -
+#pragma mark Server Detection Callbacks
+
+- (void)serverLoaded:(NSNotification *)notification
+{
+ int processId = [[[notification userInfo] objectForKey:WebScriptDebugServerProcessIdentifierKey] intValue];
+ if (processId == [[NSProcessInfo processInfo] processIdentifier])
+ return;
+
+ NSMutableDictionary *info = [[notification userInfo] mutableCopy];
+ if (!info)
+ return;
+ [knownServerNames setObject:info forKey:[notification object]];
+ [info release];
+
+ [attachTable reloadData];
+}
+
+- (void)serverUnloaded:(NSNotification *)notification
+{
+ [knownServerNames removeObjectForKey:[notification object]];
+ [attachTable reloadData];
+}
+
+- (NSDictionary *)knownServers
+{
+ return knownServerNames;
+}
+
+#pragma mark -
+#pragma mark Attach Panel Actions
+
+- (IBAction)showAttachPanel:(id)sender
+{
+ if (![attachWindow isVisible])
+ [attachWindow center];
+ [attachTable reloadData];
+ [attachTable setTarget:self];
+ [attachTable setDoubleAction:@selector(attach:)];
+ [attachWindow makeKeyAndOrderFront:sender];
+}
+
+- (IBAction)attach:(id)sender
+{
+ if ([[attachTable selectedRowIndexes] count] != 1)
+ return;
+
+ [attachWindow orderOut:sender];
+
+ unsigned int row = [[attachTable selectedRowIndexes] firstIndex];
+ NSString *key = [[knownServerNames allKeys] objectAtIndex:row];
+
+ DebuggerClient *document = [[DebuggerClient alloc] initWithServerName:key];
+ [document showWindow:sender];
+}
+
+#pragma mark -
+#pragma mark Table View Delegate
+
+- (int)numberOfRowsInTableView:(NSTableView *)tableView
+{
+ return [knownServerNames count];
+}
+
+- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row
+{
+ return @"";
+}
+
+- (void)tableView:(NSTableView *)tableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn row:(int)row
+{
+ NSString *key = [[knownServerNames allKeys] objectAtIndex:row];
+ NSMutableDictionary *info = [knownServerNames objectForKey:key];
+ NSString *processName = [info objectForKey:WebScriptDebugServerProcessNameKey];
+ NSImage *icon = [info objectForKey:@"icon"];
+
+ if (!icon) {
+ NSString *path = [[NSWorkspace sharedWorkspace] fullPathForApplication:processName];
+ if (path) icon = [[NSWorkspace sharedWorkspace] iconForFile:path];
+ if (!icon) icon = [[NSWorkspace sharedWorkspace] iconForFileType:@"app"];
+ if (icon) [info setObject:icon forKey:@"icon"];
+ [icon setScalesWhenResized:YES];
+ [icon setSize:NSMakeSize(32, 32)];
+ }
+
+ [cell setImage:icon];
+ [cell setTitle:processName];
+}
+
+- (void)tableViewSelectionDidChange:(NSNotification *)notification
+{
+ [attachButton setEnabled:([[attachTable selectedRowIndexes] count])];
+}
+@end
diff --git a/WebKitTools/Drosera/mac/DebuggerClient.h b/WebKitTools/Drosera/mac/DebuggerClient.h
new file mode 100644
index 0000000..808d331
--- /dev/null
+++ b/WebKitTools/Drosera/mac/DebuggerClient.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007 Vladimir Olexa (vladimir.olexa@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.
+ */
+
+class DebuggerDocument;
+
+@class ServerConnection;
+@class WebView;
+
+@interface DebuggerClient : NSWindowController
+{
+ IBOutlet WebView *webView;
+ BOOL webViewLoaded;
+ DebuggerDocument* debuggerDocument;
+ ServerConnection *server;
+}
+
+- (id)initWithServerName:(NSString *)serverConn;
+- (IBAction)pause:(id)sender;
+- (IBAction)resume:(id)sender;
+- (IBAction)stepInto:(id)sender;
+- (IBAction)stepOver:(id)sender;
+- (IBAction)stepOut:(id)sender;
+- (IBAction)showConsole:(id)sender;
+- (IBAction)closeCurrentFile:(id)sender;
+
+@end
diff --git a/WebKitTools/Drosera/mac/DebuggerClient.mm b/WebKitTools/Drosera/mac/DebuggerClient.mm
new file mode 100644
index 0000000..71cfa8b
--- /dev/null
+++ b/WebKitTools/Drosera/mac/DebuggerClient.mm
@@ -0,0 +1,387 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007 Vladimir Olexa (vladimir.olexa@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.
+ */
+
+#import "config.h"
+#import "DebuggerClient.h"
+
+#import "DebuggerApplication.h"
+#import "DebuggerDocument.h"
+#import "ServerConnection.h"
+
+#import <JavaScriptCore/JSContextRef.h>
+
+static NSString *DebuggerConsoleToolbarItem = @"DebuggerConsoleToolbarItem";
+static NSString *DebuggerContinueToolbarItem = @"DebuggerContinueToolbarItem";
+static NSString *DebuggerPauseToolbarItem = @"DebuggerPauseToolbarItem";
+static NSString *DebuggerStepIntoToolbarItem = @"DebuggerStepIntoToolbarItem";
+static NSString *DebuggerStepOverToolbarItem = @"DebuggerStepOverToolbarItem";
+static NSString *DebuggerStepOutToolbarItem = @"DebuggerStepOutToolbarItem";
+
+@implementation DebuggerClient
++ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
+{
+ return NO;
+}
+
++ (BOOL)isKeyExcludedFromWebScript:(const char *)name
+{
+ return NO;
+}
+
+#pragma mark -
+
+- (id)initWithServerName:(NSString *)serverName;
+{
+ if ((self = [super init])) {
+ server = [[ServerConnection alloc] initWithServerName:serverName];
+ debuggerDocument = new DebuggerDocument(server);
+ }
+
+ return self;
+}
+
+- (void)dealloc
+{
+ delete debuggerDocument;
+ [server release];
+ [super dealloc];
+}
+
+#pragma mark -
+#pragma mark Interface Actions
+
+- (IBAction)pause:(id)sender
+{
+ DebuggerDocument::callGlobalFunction([[webView mainFrame] globalContext], "pause", 0, 0);
+}
+
+- (IBAction)resume:(id)sender
+{
+ DebuggerDocument::callGlobalFunction([[webView mainFrame] globalContext], "resume", 0, 0);
+}
+
+- (IBAction)stepInto:(id)sender
+{
+ DebuggerDocument::callGlobalFunction([[webView mainFrame] globalContext], "stepInto", 0, 0);
+}
+
+- (IBAction)stepOver:(id)sender
+{
+ DebuggerDocument::callGlobalFunction([[webView mainFrame] globalContext], "stepOver", 0, 0);
+}
+
+- (IBAction)stepOut:(id)sender
+{
+ DebuggerDocument::callGlobalFunction([[webView mainFrame] globalContext], "stepOut", 0, 0);
+}
+
+- (IBAction)showConsole:(id)sender
+{
+ DebuggerDocument::callGlobalFunction([[webView mainFrame] globalContext], "showConsoleWindow", 0, 0);
+}
+
+- (IBAction)closeCurrentFile:(id)sender
+{
+ DebuggerDocument::callGlobalFunction([[webView mainFrame] globalContext], "closeCurrentFile", 0, 0);
+}
+
+#pragma mark -
+#pragma mark Window Controller Overrides
+
+- (NSString *)windowNibName
+{
+ return @"Debugger";
+}
+
+- (void)windowDidLoad
+{
+ [super windowDidLoad];
+
+ NSString *path = [[NSBundle mainBundle] pathForResource:@"debugger" ofType:@"html" inDirectory:nil];
+ [[webView mainFrame] loadRequest:[[[NSURLRequest alloc] initWithURL:[NSURL fileURLWithPath:path]] autorelease]];
+
+ NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:@"debugger"];
+ [toolbar setDelegate:self];
+ [toolbar setAllowsUserCustomization:YES];
+ [toolbar setAutosavesConfiguration:YES];
+ [[self window] setToolbar:toolbar];
+ [toolbar release];
+}
+
+- (void)windowWillClose:(NSNotification *)notification
+{
+ [[webView windowScriptObject] removeWebScriptKey:@"DebuggerDocument"];
+
+ [server switchToServerNamed:nil];
+
+ [self autorelease]; // DebuggerApplication expects us to release on close
+}
+
+#pragma mark -
+#pragma mark Toolbar Delegate
+
+- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag
+{
+ if ([itemIdentifier isEqualToString:DebuggerContinueToolbarItem]) {
+ NSToolbarItem *item = [[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier];
+
+ [item setLabel:@"Continue"];
+ [item setPaletteLabel:@"Continue"];
+
+ [item setToolTip:@"Continue script execution"];
+ [item setImage:[NSImage imageNamed:@"continue"]];
+
+ [item setTarget:self];
+ [item setAction:@selector(resume:)];
+
+ return [item autorelease];
+ } else if ([itemIdentifier isEqualToString:DebuggerConsoleToolbarItem]) {
+ NSToolbarItem *item = [[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier];
+
+ [item setLabel:@"Console"];
+ [item setPaletteLabel:@"Console"];
+
+ [item setToolTip:@"Console"];
+ [item setImage:[NSImage imageNamed:@"console"]];
+
+ [item setTarget:self];
+ [item setAction:@selector(showConsole:)];
+
+ return [item autorelease];
+ } else if ([itemIdentifier isEqualToString:DebuggerPauseToolbarItem]) {
+ NSToolbarItem *item = [[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier];
+
+ [item setLabel:@"Pause"];
+ [item setPaletteLabel:@"Pause"];
+
+ [item setToolTip:@"Pause script execution"];
+ [item setImage:[NSImage imageNamed:@"pause"]];
+
+ [item setTarget:self];
+ [item setAction:@selector(pause:)];
+
+ return [item autorelease];
+ } else if ([itemIdentifier isEqualToString:DebuggerStepIntoToolbarItem]) {
+ NSToolbarItem *item = [[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier];
+
+ [item setLabel:@"Step Into"];
+ [item setPaletteLabel:@"Step Into"];
+
+ [item setToolTip:@"Step into function call"];
+ [item setImage:[NSImage imageNamed:@"step"]];
+
+ [item setTarget:self];
+ [item setAction:@selector(stepInto:)];
+
+ return [item autorelease];
+ } else if ([itemIdentifier isEqualToString:DebuggerStepOverToolbarItem]) {
+ NSToolbarItem *item = [[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier];
+
+ [item setLabel:@"Step Over"];
+ [item setPaletteLabel:@"Step Over"];
+
+ [item setToolTip:@"Step over function call"];
+ [item setImage:[NSImage imageNamed:@"stepOver"]];
+
+ [item setTarget:self];
+ [item setAction:@selector(stepOver:)];
+
+ return [item autorelease];
+ } else if ([itemIdentifier isEqualToString:DebuggerStepOutToolbarItem]) {
+ NSToolbarItem *item = [[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier];
+
+ [item setLabel:@"Step Out"];
+ [item setPaletteLabel:@"Step Over"];
+
+ [item setToolTip:@"Step out of current function"];
+ [item setImage:[NSImage imageNamed:@"stepOut"]];
+
+ [item setTarget:self];
+ [item setAction:@selector(stepOut:)];
+
+ return [item autorelease];
+ }
+
+ return nil;
+}
+
+- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar
+{
+ return [NSArray arrayWithObjects:DebuggerContinueToolbarItem, DebuggerPauseToolbarItem,
+ NSToolbarSeparatorItemIdentifier, DebuggerStepIntoToolbarItem, DebuggerStepOutToolbarItem,
+ DebuggerStepOverToolbarItem, NSToolbarFlexibleSpaceItemIdentifier, DebuggerConsoleToolbarItem, nil];
+}
+
+- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar*)toolbar
+{
+ return [NSArray arrayWithObjects:DebuggerConsoleToolbarItem, DebuggerContinueToolbarItem, DebuggerPauseToolbarItem,
+ DebuggerStepIntoToolbarItem, DebuggerStepOutToolbarItem, DebuggerStepOverToolbarItem, NSToolbarCustomizeToolbarItemIdentifier,
+ NSToolbarFlexibleSpaceItemIdentifier, NSToolbarSpaceItemIdentifier, NSToolbarSeparatorItemIdentifier, nil];
+}
+
+- (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)interfaceItem
+{
+ SEL action = [interfaceItem action];
+ if (action == @selector(pause:)) {
+ if (!webViewLoaded)
+ return NO;
+
+ return !debuggerDocument->isPaused([[webView mainFrame] globalContext]);
+ }
+ if (action == @selector(resume:) ||
+ action == @selector(stepOver:) ||
+ action == @selector(stepOut:) ||
+ action == @selector(stepInto:)) {
+ if (!webViewLoaded)
+ return YES;
+
+ return debuggerDocument->isPaused([[webView mainFrame] globalContext]);
+ }
+ return YES;
+}
+
+#pragma mark -
+#pragma mark WebView UI Delegate
+
+- (WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request
+{
+ WebView *newWebView = [[WebView alloc] initWithFrame:NSZeroRect frameName:nil groupName:nil];
+ [newWebView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
+ [newWebView setUIDelegate:self];
+ [newWebView setPolicyDelegate:self];
+ [newWebView setFrameLoadDelegate:self];
+ if (request)
+ [[newWebView mainFrame] loadRequest:request];
+
+ NSWindow *window = [[NSWindow alloc] initWithContentRect:NSZeroRect styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask | NSUnifiedTitleAndToolbarWindowMask) backing:NSBackingStoreBuffered defer:NO screen:[[webView window] screen]];
+ [window setReleasedWhenClosed:YES];
+ [newWebView setFrame:[[window contentView] frame]];
+ [[window contentView] addSubview:newWebView];
+ [newWebView release];
+
+ return newWebView;
+}
+
+- (void)webViewShow:(WebView *)sender
+{
+ [[sender window] makeKeyAndOrderFront:sender];
+}
+
+- (BOOL)webViewAreToolbarsVisible:(WebView *)sender
+{
+ return [[[sender window] toolbar] isVisible];
+}
+
+- (void)webView:(WebView *)sender setToolbarsVisible:(BOOL)visible
+{
+ [[[sender window] toolbar] setVisible:visible];
+}
+
+- (void)webView:(WebView *)sender setResizable:(BOOL)resizable
+{
+ [[sender window] setShowsResizeIndicator:resizable];
+ [[[sender window] standardWindowButton:NSWindowZoomButton] setEnabled:resizable];
+}
+
+- (void)webView:(WebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame
+{
+ NSRange range = [message rangeOfString:@"\t"];
+ NSString *title = @"Alert";
+ if (range.location != NSNotFound) {
+ title = [message substringToIndex:range.location];
+ message = [message substringFromIndex:(range.location + range.length)];
+ }
+
+ NSBeginInformationalAlertSheet(title, nil, nil, nil, [sender window], nil, NULL, NULL, NULL, message);
+}
+
+- (void)scriptConfirmSheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(long *)contextInfo
+{
+ *contextInfo = returnCode;
+}
+
+- (BOOL)webView:(WebView *)sender runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame
+{
+ NSRange range = [message rangeOfString:@"\t"];
+ NSString *title = @"Alert";
+ if (range.location != NSNotFound) {
+ title = [message substringToIndex:range.location];
+ message = [message substringFromIndex:(range.location + range.length)];
+ }
+
+ long result = NSNotFound;
+ NSBeginInformationalAlertSheet(title, nil, @"Cancel", nil, [sender window], self, @selector(scriptConfirmSheetDidEnd:returnCode:contextInfo:), NULL, &result, message);
+
+ while (result == NSNotFound) {
+ NSEvent *nextEvent = [[NSApplication sharedApplication] nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantFuture] inMode:NSDefaultRunLoopMode dequeue:YES];
+ [[NSApplication sharedApplication] sendEvent:nextEvent];
+ }
+
+ return result;
+}
+
+#pragma mark -
+#pragma mark WebView Frame Load Delegate
+
+- (void)webView:(WebView *)sender windowScriptObjectAvailable:(WebScriptObject *)windowScriptObject
+{
+ // note: this is the Debuggers's own WebView, not the one being debugged
+ JSContextRef context = [[webView mainFrame] globalContext];
+ JSObjectRef globalObject = JSContextGetGlobalObject(context);
+
+ debuggerDocument->windowScriptObjectAvailable(context, globalObject);
+}
+
+- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
+{
+ // note: this is the Debuggers's own WebView, not the one being debugged
+ if ([[sender window] isEqual:[self window]]) {
+ webViewLoaded = YES;
+ [server setGlobalContext:[[webView mainFrame] globalContext]];
+ }
+}
+
+- (void)webView:(WebView *)sender didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame
+{
+ // note: this is the Debuggers's own WebViews, not the one being debugged
+ if ([frame isEqual:[sender mainFrame]]) {
+ NSDictionary *info = [[(DebuggerApplication *)[[NSApplication sharedApplication] delegate] knownServers] objectForKey:[server currentServerName]];
+ NSString *processName = [info objectForKey:WebScriptDebugServerProcessNameKey];
+ if (info && [processName length]) {
+ NSMutableString *newTitle = [[NSMutableString alloc] initWithString:processName];
+ [newTitle appendString:@" - "];
+ [newTitle appendString:title];
+ [[sender window] setTitle:newTitle];
+ [newTitle release];
+ } else
+ [[sender window] setTitle:title];
+ }
+}
+
+@end
diff --git a/WebKitTools/Drosera/mac/DebuggerDocumentPlatform.mm b/WebKitTools/Drosera/mac/DebuggerDocumentPlatform.mm
new file mode 100644
index 0000000..b49338c
--- /dev/null
+++ b/WebKitTools/Drosera/mac/DebuggerDocumentPlatform.mm
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007 Vladimir Olexa (vladimir.olexa@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.
+ */
+
+#import "config.h"
+#import "DebuggerDocument.h"
+
+#import "DebuggerClient.h"
+#import "ServerConnection.h"
+
+#import <JavaScriptCore/JSRetainPtr.h>
+#import <JavaScriptCore/JSStringRefCF.h>
+#import <JavaScriptCore/RetainPtr.h>
+
+// Converting string types
+NSString* NSStringCreateWithJSStringRef(JSStringRef jsString)
+{
+ CFStringRef cfString = JSStringCopyCFString(kCFAllocatorDefault, jsString);
+ return (NSString *)cfString;
+}
+
+JSValueRef JSValueRefCreateWithNSString(JSContextRef context, NSString* nsString)
+{
+ JSRetainPtr<JSStringRef> jsString(Adopt, JSStringCreateWithCFString((CFStringRef)nsString));
+ return JSValueMakeString(context, jsString.get());
+}
+
+@interface NSString (WebScriptStringExtras)
++ (NSString *)stringOrNilFromWebScriptResult:(id)scriptResult;
+@end
+
+@implementation NSString (WebScriptStringExtras)
++ (NSString *)stringOrNilFromWebScriptResult:(id)scriptResult
+{
+ NSString *ret = nil;
+
+ if ([scriptResult isKindOfClass:NSClassFromString(@"WebScriptObject")])
+ ret = [scriptResult callWebScriptMethod:@"toString" withArguments:nil];
+ else if (scriptResult && ![scriptResult isKindOfClass:[NSString class]])
+ ret = [scriptResult description];
+ else if (scriptResult)
+ ret = scriptResult;
+
+ return ret;
+}
+@end
+
+@interface WebScriptObject (WebScriptObjectExtras)
++ (NSArray *)webScriptAttributeKeys:(WebScriptObject *)object;
+@end
+
+@implementation WebScriptObject (WebScriptObjectExtras)
++ (NSArray *)webScriptAttributeKeys:(WebScriptObject *)object;
+{
+ WebScriptObject *enumerateAttributes = [object evaluateWebScript:@"(function () { var result = new Array(); for (var x in this) { result.push(x); } return result; })"];
+
+ NSMutableArray *result = [[NSMutableArray alloc] init];
+ WebScriptObject *variables = [enumerateAttributes callWebScriptMethod:@"call" withArguments:[NSArray arrayWithObject:object]];
+ unsigned length = [[variables valueForKey:@"length"] intValue];
+ for (unsigned i = 0; i < length; i++) {
+ NSString *key = [variables webScriptValueAtIndex:i];
+ [result addObject:key];
+ }
+
+ [result sortUsingSelector:@selector(compare:)];
+ return [result autorelease];
+}
+@end
+
+// DebuggerDocument platform specific implementations
+
+void DebuggerDocument::platformPause()
+{
+ [m_server.get() pause];
+}
+
+void DebuggerDocument::platformResume()
+{
+ [m_server.get() resume];
+}
+
+void DebuggerDocument::platformStepInto()
+{
+ [m_server.get() stepInto];
+}
+
+JSValueRef DebuggerDocument::platformEvaluateScript(JSContextRef context, JSStringRef script, int callFrame)
+{
+ WebScriptCallFrame *cframe = [m_server.get() currentFrame];
+ for (unsigned count = 0; count < callFrame; count++)
+ cframe = [cframe caller];
+
+ if (!cframe)
+ return JSValueMakeUndefined(context);
+
+ RetainPtr<NSString> scriptNS(AdoptNS, NSStringCreateWithJSStringRef(script));
+ id value = [cframe evaluateWebScript:scriptNS.get()];
+ NSString *result = [NSString stringOrNilFromWebScriptResult:value];
+ if (!result)
+ return JSValueMakeNull(context);
+
+ return JSValueRefCreateWithNSString(context, result);
+}
+
+void DebuggerDocument::getPlatformCurrentFunctionStack(JSContextRef context, Vector<JSValueRef>& currentStack)
+{
+ for (WebScriptCallFrame *frame = [m_server.get() currentFrame]; frame;) {
+ CFStringRef function;
+ if ([frame functionName])
+ function = (CFStringRef)[frame functionName];
+ else if ([frame caller])
+ function = CFSTR("(anonymous function)");
+ else
+ function = CFSTR("(global scope)");
+ frame = [frame caller];
+
+ currentStack.append(JSValueRefCreateWithNSString(context, (NSString *)function));
+ }
+}
+
+void DebuggerDocument::getPlatformLocalScopeVariableNamesForCallFrame(JSContextRef context, int callFrame, Vector<JSValueRef>& variableNames)
+{
+ WebScriptCallFrame *cframe = [m_server.get() currentFrame];
+ for (unsigned count = 0; count < callFrame; count++)
+ cframe = [cframe caller];
+
+ if (!cframe)
+ return;
+ if (![[cframe scopeChain] count])
+ return;
+
+ WebScriptObject *scope = [[cframe scopeChain] objectAtIndex:0]; // local is always first
+ NSArray *localScopeVariableNames = [WebScriptObject webScriptAttributeKeys:scope];
+
+ for (int i = 0; i < [localScopeVariableNames count]; ++i) {
+ variableNames.append(JSValueRefCreateWithNSString(context, [localScopeVariableNames objectAtIndex:i]));
+ }
+}
+
+JSValueRef DebuggerDocument::platformValueForScopeVariableNamed(JSContextRef context, JSStringRef key, int callFrame)
+{
+ WebScriptCallFrame *cframe = [m_server.get() currentFrame];
+ for (unsigned count = 0; count < callFrame; count++)
+ cframe = [cframe caller];
+
+ if (!cframe)
+ return JSValueMakeUndefined(context);
+
+ unsigned scopeCount = [[cframe scopeChain] count];
+
+ if (!scopeCount)
+ return JSValueMakeUndefined(context);
+
+ NSString *resultString = nil;
+
+ for (unsigned i = 0; i < scopeCount && resultString == nil; i++) {
+ WebScriptObject *scope = [[cframe scopeChain] objectAtIndex:i];
+
+ id value = nil;
+ @try {
+ RetainPtr<NSString> keyNS(AdoptNS, NSStringCreateWithJSStringRef(key));
+ value = [scope valueForKey:keyNS.get()];
+ } @catch(NSException* localException) { // The value wasn't found.
+ }
+
+ resultString = [NSString stringOrNilFromWebScriptResult:value];
+ }
+
+ if (!resultString)
+ return JSValueMakeUndefined(context);
+
+ return JSValueRefCreateWithNSString(context, resultString);
+}
+
+void DebuggerDocument::platformLog(JSStringRef msg)
+{
+ RetainPtr<NSString> msgNS(AdoptNS, NSStringCreateWithJSStringRef(msg));
+ NSLog(@"%@", msgNS.get());
+}
+
diff --git a/WebKitTools/Drosera/mac/Drosera.xcodeproj/project.pbxproj b/WebKitTools/Drosera/mac/Drosera.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..3ef8b64
--- /dev/null
+++ b/WebKitTools/Drosera/mac/Drosera.xcodeproj/project.pbxproj
@@ -0,0 +1,659 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 42;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 15CE85540ADBEA620078A734 /* fileIcon.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 15CE854F0ADBEA610078A734 /* fileIcon.jpg */; };
+ 15CE85550ADBEA620078A734 /* siteCollapsed.tif in Resources */ = {isa = PBXBuildFile; fileRef = 15CE85500ADBEA610078A734 /* siteCollapsed.tif */; };
+ 15CE85560ADBEA620078A734 /* siteExpanded.tif in Resources */ = {isa = PBXBuildFile; fileRef = 15CE85510ADBEA610078A734 /* siteExpanded.tif */; };
+ 15CE85570ADBEA620078A734 /* siteIcon.tif in Resources */ = {isa = PBXBuildFile; fileRef = 15CE85520ADBEA610078A734 /* siteIcon.tif */; };
+ 15CE85580ADBEA620078A734 /* SourceArrowOpen.png in Resources */ = {isa = PBXBuildFile; fileRef = 15CE85530ADBEA610078A734 /* SourceArrowOpen.png */; };
+ 1C2632D30A4AF0A800EA7CD8 /* verticalSplitterBar.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 1C2632D10A4AF0A800EA7CD8 /* verticalSplitterBar.tiff */; };
+ 1C2632D40A4AF0A800EA7CD8 /* verticalSplitterDimple.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 1C2632D20A4AF0A800EA7CD8 /* verticalSplitterDimple.tiff */; };
+ 1C2632D70A4AF0B800EA7CD8 /* SourceArrow.png in Resources */ = {isa = PBXBuildFile; fileRef = 1C2632D50A4AF0B800EA7CD8 /* SourceArrow.png */; };
+ 1C2632D80A4AF0B800EA7CD8 /* SourceArrowBlank.png in Resources */ = {isa = PBXBuildFile; fileRef = 1C2632D60A4AF0B800EA7CD8 /* SourceArrowBlank.png */; };
+ 1C2632DA0A4AF0D200EA7CD8 /* background_stripe.png in Resources */ = {isa = PBXBuildFile; fileRef = 1C2632D90A4AF0D200EA7CD8 /* background_stripe.png */; };
+ 1C27ABC60A413B720016ECF4 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1C27ABC50A413B720016ECF4 /* WebKit.framework */; };
+ 1C27AC200A413D2D0016ECF4 /* debugger.html in Resources */ = {isa = PBXBuildFile; fileRef = 1C27AC1F0A413D2D0016ECF4 /* debugger.html */; };
+ 1C27B1260A421D870016ECF4 /* debugger.js in Resources */ = {isa = PBXBuildFile; fileRef = 1C27AC230A413D660016ECF4 /* debugger.js */; };
+ 1C3487980A81208400101C5C /* Drosera.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1C3487970A81208400101C5C /* Drosera.icns */; };
+ 1C4FF7440A44F52C0000D05D /* debugger.css in Resources */ = {isa = PBXBuildFile; fileRef = 1C4FF7430A44F5260000D05D /* debugger.css */; };
+ 1C4FF7540A44F6320000D05D /* gutter.png in Resources */ = {isa = PBXBuildFile; fileRef = 1C4FF7530A44F6320000D05D /* gutter.png */; };
+ 1C4FF9210A45F3520000D05D /* glossyHeader.png in Resources */ = {isa = PBXBuildFile; fileRef = 1C4FF91F0A45F3520000D05D /* glossyHeader.png */; };
+ 1C4FF94E0A45F5060000D05D /* popUpArrows.png in Resources */ = {isa = PBXBuildFile; fileRef = 1C4FF94D0A45F5060000D05D /* popUpArrows.png */; };
+ 1C4FFE5E0A466F5D0000D05D /* programCounterBreakPoint.tif in Resources */ = {isa = PBXBuildFile; fileRef = 1C4FFE5C0A466F5D0000D05D /* programCounterBreakPoint.tif */; };
+ 1C4FFE5F0A466F5D0000D05D /* programCounterBreakPointDisabled.tif in Resources */ = {isa = PBXBuildFile; fileRef = 1C4FFE5D0A466F5D0000D05D /* programCounterBreakPointDisabled.tif */; };
+ 1C6F83FF0A58E97D004FCD89 /* stepOut.tif in Resources */ = {isa = PBXBuildFile; fileRef = 1C6F83FE0A58E97D004FCD89 /* stepOut.tif */; };
+ 1C6F84520A58EDFE004FCD89 /* console.png in Resources */ = {isa = PBXBuildFile; fileRef = 1C6F84510A58EDFE004FCD89 /* console.png */; };
+ 1C6F84550A58EE06004FCD89 /* console.css in Resources */ = {isa = PBXBuildFile; fileRef = 1C6F84530A58EE06004FCD89 /* console.css */; };
+ 1C6F84560A58EE06004FCD89 /* console.html in Resources */ = {isa = PBXBuildFile; fileRef = 1C6F84540A58EE06004FCD89 /* console.html */; };
+ 1C6F86730A59A18B004FCD89 /* console.js in Resources */ = {isa = PBXBuildFile; fileRef = 1C6F861F0A599F65004FCD89 /* console.js */; };
+ 1C74F0350A47BF8300FEC632 /* viewer.html in Resources */ = {isa = PBXBuildFile; fileRef = 1C74F0340A47BF8300FEC632 /* viewer.html */; };
+ 1C74F04B0A47BFE800FEC632 /* viewer.css in Resources */ = {isa = PBXBuildFile; fileRef = 1C74F03A0A47BFD600FEC632 /* viewer.css */; };
+ 1C74F1850A47DEE600FEC632 /* DebuggerApplication.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1C74F1840A47DEE600FEC632 /* DebuggerApplication.mm */; };
+ 1CC058EE0A44A210006FE533 /* breakPoint.tif in Resources */ = {isa = PBXBuildFile; fileRef = 1CC058B80A44A210006FE533 /* breakPoint.tif */; };
+ 1CC058EF0A44A210006FE533 /* breakPointDisabled.tif in Resources */ = {isa = PBXBuildFile; fileRef = 1CC058B90A44A210006FE533 /* breakPointDisabled.tif */; };
+ 1CC059020A44A210006FE533 /* glossyFooterFill.tif in Resources */ = {isa = PBXBuildFile; fileRef = 1CC058CC0A44A210006FE533 /* glossyFooterFill.tif */; };
+ 1CC0590E0A44A210006FE533 /* navLeftDisabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 1CC058D80A44A210006FE533 /* navLeftDisabled.png */; };
+ 1CC0590F0A44A210006FE533 /* navLeftNormal.png in Resources */ = {isa = PBXBuildFile; fileRef = 1CC058D90A44A210006FE533 /* navLeftNormal.png */; };
+ 1CC059100A44A210006FE533 /* navLeftPressed.png in Resources */ = {isa = PBXBuildFile; fileRef = 1CC058DA0A44A210006FE533 /* navLeftPressed.png */; };
+ 1CC059110A44A210006FE533 /* navRightDisabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 1CC058DB0A44A210006FE533 /* navRightDisabled.png */; };
+ 1CC059120A44A210006FE533 /* navRightNormal.png in Resources */ = {isa = PBXBuildFile; fileRef = 1CC058DC0A44A210006FE533 /* navRightNormal.png */; };
+ 1CC059130A44A210006FE533 /* navRightPressed.png in Resources */ = {isa = PBXBuildFile; fileRef = 1CC058DD0A44A210006FE533 /* navRightPressed.png */; };
+ 1CC059160A44A210006FE533 /* programCounter.tif in Resources */ = {isa = PBXBuildFile; fileRef = 1CC058E00A44A210006FE533 /* programCounter.tif */; };
+ 1CC059170A44A210006FE533 /* splitterBar.tif in Resources */ = {isa = PBXBuildFile; fileRef = 1CC058E10A44A210006FE533 /* splitterBar.tif */; };
+ 1CC059180A44A210006FE533 /* splitterDimple.tif in Resources */ = {isa = PBXBuildFile; fileRef = 1CC058E20A44A210006FE533 /* splitterDimple.tif */; };
+ 1CC0591A0A44A210006FE533 /* continue.tif in Resources */ = {isa = PBXBuildFile; fileRef = 1CC058E40A44A210006FE533 /* continue.tif */; };
+ 1CC0591D0A44A210006FE533 /* pause.tif in Resources */ = {isa = PBXBuildFile; fileRef = 1CC058E70A44A210006FE533 /* pause.tif */; };
+ 1CC0591E0A44A210006FE533 /* run.tif in Resources */ = {isa = PBXBuildFile; fileRef = 1CC058E80A44A210006FE533 /* run.tif */; };
+ 1CC0591F0A44A210006FE533 /* step.tif in Resources */ = {isa = PBXBuildFile; fileRef = 1CC058E90A44A210006FE533 /* step.tif */; };
+ 1CC059200A44A210006FE533 /* stepOver.tif in Resources */ = {isa = PBXBuildFile; fileRef = 1CC058EA0A44A210006FE533 /* stepOver.tif */; };
+ 1CC059700A44A485006FE533 /* toolbarBackground.png in Resources */ = {isa = PBXBuildFile; fileRef = 1CC0596F0A44A485006FE533 /* toolbarBackground.png */; };
+ 1CD434B20A4B86F800A007AB /* glossyHeaderPressed.png in Resources */ = {isa = PBXBuildFile; fileRef = 1CD434B10A4B86F800A007AB /* glossyHeaderPressed.png */; };
+ 1CD8D5690A49041C00E5677B /* launcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 1CD8D5680A49041C00E5677B /* launcher.m */; };
+ 1CD8D56C0A49043E00E5677B /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A7FEA54F5311CA2CBB /* Cocoa.framework */; };
+ 1CD8D5A60A49102900E5677B /* Drosera.app in Resources */ = {isa = PBXBuildFile; fileRef = 8D15AC370486D014006FF6A4 /* Drosera.app */; };
+ 5D2C827F0A816BA700C193FD /* Drosera.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1C3487970A81208400101C5C /* Drosera.icns */; };
+ 63D54BD70AE600560064C440 /* breakpointeditor.png in Resources */ = {isa = PBXBuildFile; fileRef = 63D54BD60AE600560064C440 /* breakpointeditor.png */; };
+ 63D54CBD0AE72C990064C440 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D54CBC0AE72C990064C440 /* Carbon.framework */; };
+ 63D54D7E0AE75CF10064C440 /* close_active.tif in Resources */ = {isa = PBXBuildFile; fileRef = 63D54D7B0AE75CF10064C440 /* close_active.tif */; };
+ 63D54D7F0AE75CF10064C440 /* close_hover.tif in Resources */ = {isa = PBXBuildFile; fileRef = 63D54D7C0AE75CF10064C440 /* close_hover.tif */; };
+ 63D54D800AE75CF10064C440 /* close.tif in Resources */ = {isa = PBXBuildFile; fileRef = 63D54D7D0AE75CF10064C440 /* close.tif */; };
+ 63D54F780AE8280F0064C440 /* breakpointEditor.html in Resources */ = {isa = PBXBuildFile; fileRef = 63D54F770AE8280F0064C440 /* breakpointEditor.html */; };
+ 8D15AC2D0486D014006FF6A4 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 2A37F4B6FDCFA73011CA2CEA /* MainMenu.nib */; };
+ 8D15AC2E0486D014006FF6A4 /* Debugger.nib in Resources */ = {isa = PBXBuildFile; fileRef = 2A37F4B4FDCFA73011CA2CEA /* Debugger.nib */; };
+ 8D15AC320486D014006FF6A4 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A37F4B0FDCFA73011CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
+ 8D15AC340486D014006FF6A4 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A7FEA54F5311CA2CBB /* Cocoa.framework */; };
+ 957876850C9A226A008B6383 /* ServerConnection.mm in Sources */ = {isa = PBXBuildFile; fileRef = 957876840C9A226A008B6383 /* ServerConnection.mm */; };
+ 95B2A4500C95EECD00850C41 /* DebuggerClient.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95B2A44F0C95EECD00850C41 /* DebuggerClient.mm */; };
+ 95B955250C975C7500AAB83B /* DebuggerDocumentPlatform.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95B955240C975C7500AAB83B /* DebuggerDocumentPlatform.mm */; };
+ D23E47C60C4460C600B7CD07 /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D23E47C50C4460C600B7CD07 /* JavaScriptCore.framework */; };
+ D2D794FD0C4BED83004784F7 /* DebuggerDocument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D2D794ED0C4BED83004784F7 /* DebuggerDocument.cpp */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 1CD8D5A90A49104E00E5677B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 2A37F4A9FDCFA73011CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 8D15AC270486D014006FF6A4;
+ remoteInfo = Drosera;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ 1058C7A7FEA54F5311CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
+ 13E42FBA07B3F13500E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
+ 15CE854F0ADBEA610078A734 /* fileIcon.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = fileIcon.jpg; path = ../Images/fileIcon.jpg; sourceTree = SOURCE_ROOT; };
+ 15CE85500ADBEA610078A734 /* siteCollapsed.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = siteCollapsed.tif; path = ../Images/siteCollapsed.tif; sourceTree = SOURCE_ROOT; };
+ 15CE85510ADBEA610078A734 /* siteExpanded.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = siteExpanded.tif; path = ../Images/siteExpanded.tif; sourceTree = SOURCE_ROOT; };
+ 15CE85520ADBEA610078A734 /* siteIcon.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = siteIcon.tif; path = ../Images/siteIcon.tif; sourceTree = SOURCE_ROOT; };
+ 15CE85530ADBEA610078A734 /* SourceArrowOpen.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = SourceArrowOpen.png; path = ../Images/SourceArrowOpen.png; sourceTree = SOURCE_ROOT; };
+ 1C2632D10A4AF0A800EA7CD8 /* verticalSplitterBar.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = verticalSplitterBar.tiff; path = ../Images/verticalSplitterBar.tiff; sourceTree = SOURCE_ROOT; };
+ 1C2632D20A4AF0A800EA7CD8 /* verticalSplitterDimple.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = verticalSplitterDimple.tiff; path = ../Images/verticalSplitterDimple.tiff; sourceTree = SOURCE_ROOT; };
+ 1C2632D50A4AF0B800EA7CD8 /* SourceArrow.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = SourceArrow.png; path = ../Images/SourceArrow.png; sourceTree = SOURCE_ROOT; };
+ 1C2632D60A4AF0B800EA7CD8 /* SourceArrowBlank.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = SourceArrowBlank.png; path = ../Images/SourceArrowBlank.png; sourceTree = SOURCE_ROOT; };
+ 1C2632D90A4AF0D200EA7CD8 /* background_stripe.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = background_stripe.png; path = ../Images/background_stripe.png; sourceTree = SOURCE_ROOT; };
+ 1C27ABC50A413B720016ECF4 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = /System/Library/Frameworks/WebKit.framework; sourceTree = "<absolute>"; };
+ 1C27AC1F0A413D2D0016ECF4 /* debugger.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = debugger.html; path = ../debugger.html; sourceTree = SOURCE_ROOT; tabWidth = 8; usesTabs = 0; };
+ 1C27AC230A413D660016ECF4 /* debugger.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = debugger.js; path = ../debugger.js; sourceTree = SOURCE_ROOT; tabWidth = 8; usesTabs = 0; };
+ 1C3487970A81208400101C5C /* Drosera.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = Drosera.icns; path = ../Drosera.icns; sourceTree = SOURCE_ROOT; };
+ 1C4FF7430A44F5260000D05D /* debugger.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = debugger.css; path = ../debugger.css; sourceTree = SOURCE_ROOT; tabWidth = 8; usesTabs = 0; };
+ 1C4FF7530A44F6320000D05D /* gutter.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = gutter.png; path = ../Images/gutter.png; sourceTree = SOURCE_ROOT; };
+ 1C4FF91F0A45F3520000D05D /* glossyHeader.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = glossyHeader.png; path = ../Images/glossyHeader.png; sourceTree = SOURCE_ROOT; };
+ 1C4FF94D0A45F5060000D05D /* popUpArrows.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = popUpArrows.png; path = ../Images/popUpArrows.png; sourceTree = SOURCE_ROOT; };
+ 1C4FFE5C0A466F5D0000D05D /* programCounterBreakPoint.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = programCounterBreakPoint.tif; path = ../Images/programCounterBreakPoint.tif; sourceTree = SOURCE_ROOT; };
+ 1C4FFE5D0A466F5D0000D05D /* programCounterBreakPointDisabled.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = programCounterBreakPointDisabled.tif; path = ../Images/programCounterBreakPointDisabled.tif; sourceTree = SOURCE_ROOT; };
+ 1C6F83FE0A58E97D004FCD89 /* stepOut.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = stepOut.tif; path = ../Images/stepOut.tif; sourceTree = SOURCE_ROOT; };
+ 1C6F84510A58EDFE004FCD89 /* console.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = console.png; path = ../Images/console.png; sourceTree = SOURCE_ROOT; };
+ 1C6F84530A58EE06004FCD89 /* console.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = console.css; path = ../console.css; sourceTree = SOURCE_ROOT; };
+ 1C6F84540A58EE06004FCD89 /* console.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = console.html; path = ../console.html; sourceTree = SOURCE_ROOT; };
+ 1C6F861F0A599F65004FCD89 /* console.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = console.js; path = ../console.js; sourceTree = SOURCE_ROOT; };
+ 1C74F0340A47BF8300FEC632 /* viewer.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = viewer.html; path = ../viewer.html; sourceTree = SOURCE_ROOT; tabWidth = 8; usesTabs = 0; };
+ 1C74F03A0A47BFD600FEC632 /* viewer.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = viewer.css; path = ../viewer.css; sourceTree = SOURCE_ROOT; tabWidth = 8; usesTabs = 0; };
+ 1C74F1830A47DEE600FEC632 /* DebuggerApplication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebuggerApplication.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
+ 1C74F1840A47DEE600FEC632 /* DebuggerApplication.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DebuggerApplication.mm; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
+ 1CC058B80A44A210006FE533 /* breakPoint.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = breakPoint.tif; path = ../Images/breakPoint.tif; sourceTree = SOURCE_ROOT; };
+ 1CC058B90A44A210006FE533 /* breakPointDisabled.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = breakPointDisabled.tif; path = ../Images/breakPointDisabled.tif; sourceTree = SOURCE_ROOT; };
+ 1CC058CC0A44A210006FE533 /* glossyFooterFill.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = glossyFooterFill.tif; path = ../Images/glossyFooterFill.tif; sourceTree = SOURCE_ROOT; };
+ 1CC058D80A44A210006FE533 /* navLeftDisabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = navLeftDisabled.png; path = ../Images/navLeftDisabled.png; sourceTree = SOURCE_ROOT; };
+ 1CC058D90A44A210006FE533 /* navLeftNormal.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = navLeftNormal.png; path = ../Images/navLeftNormal.png; sourceTree = SOURCE_ROOT; };
+ 1CC058DA0A44A210006FE533 /* navLeftPressed.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = navLeftPressed.png; path = ../Images/navLeftPressed.png; sourceTree = SOURCE_ROOT; };
+ 1CC058DB0A44A210006FE533 /* navRightDisabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = navRightDisabled.png; path = ../Images/navRightDisabled.png; sourceTree = SOURCE_ROOT; };
+ 1CC058DC0A44A210006FE533 /* navRightNormal.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = navRightNormal.png; path = ../Images/navRightNormal.png; sourceTree = SOURCE_ROOT; };
+ 1CC058DD0A44A210006FE533 /* navRightPressed.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = navRightPressed.png; path = ../Images/navRightPressed.png; sourceTree = SOURCE_ROOT; };
+ 1CC058E00A44A210006FE533 /* programCounter.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = programCounter.tif; path = ../Images/programCounter.tif; sourceTree = SOURCE_ROOT; };
+ 1CC058E10A44A210006FE533 /* splitterBar.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = splitterBar.tif; path = ../Images/splitterBar.tif; sourceTree = SOURCE_ROOT; };
+ 1CC058E20A44A210006FE533 /* splitterDimple.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = splitterDimple.tif; path = ../Images/splitterDimple.tif; sourceTree = SOURCE_ROOT; };
+ 1CC058E40A44A210006FE533 /* continue.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = continue.tif; path = ../Images/continue.tif; sourceTree = SOURCE_ROOT; };
+ 1CC058E60A44A210006FE533 /* finishFunction.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = finishFunction.tif; sourceTree = "<group>"; };
+ 1CC058E70A44A210006FE533 /* pause.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = pause.tif; path = ../Images/pause.tif; sourceTree = SOURCE_ROOT; };
+ 1CC058E80A44A210006FE533 /* run.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = run.tif; path = ../Images/run.tif; sourceTree = SOURCE_ROOT; };
+ 1CC058E90A44A210006FE533 /* step.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = step.tif; path = ../Images/step.tif; sourceTree = SOURCE_ROOT; };
+ 1CC058EA0A44A210006FE533 /* stepOver.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = stepOver.tif; path = ../Images/stepOver.tif; sourceTree = SOURCE_ROOT; };
+ 1CC058EB0A44A210006FE533 /* stop.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = stop.tif; sourceTree = "<group>"; };
+ 1CC0596F0A44A485006FE533 /* toolbarBackground.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = toolbarBackground.png; path = ../Images/toolbarBackground.png; sourceTree = SOURCE_ROOT; };
+ 1CD434B10A4B86F800A007AB /* glossyHeaderPressed.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = glossyHeaderPressed.png; path = ../Images/glossyHeaderPressed.png; sourceTree = SOURCE_ROOT; };
+ 1CD8D54D0A4902B000E5677B /* DroseraLauncher.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DroseraLauncher.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 1CD8D54F0A4902B000E5677B /* LauncherInfo.plist */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = LauncherInfo.plist; sourceTree = "<group>"; };
+ 1CD8D5680A49041C00E5677B /* launcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = launcher.m; sourceTree = "<group>"; };
+ 2A37F4B0FDCFA73011CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
+ 2A37F4B5FDCFA73011CA2CEA /* Debugger.nib */ = {isa = PBXFileReference; explicitFileType = wrapper.nib; name = Debugger.nib; path = ../English.lproj/Debugger.nib; sourceTree = "<group>"; };
+ 2A37F4B7FDCFA73011CA2CEA /* MainMenu.nib */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = MainMenu.nib; path = ../English.lproj/MainMenu.nib; sourceTree = "<group>"; };
+ 2A37F4C4FDCFA73011CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
+ 2A37F4C5FDCFA73011CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
+ 63D54BD60AE600560064C440 /* breakpointeditor.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = breakpointeditor.png; path = ../Images/breakpointeditor.png; sourceTree = SOURCE_ROOT; };
+ 63D54CBC0AE72C990064C440 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
+ 63D54D7B0AE75CF10064C440 /* close_active.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = close_active.tif; path = ../Images/close_active.tif; sourceTree = SOURCE_ROOT; };
+ 63D54D7C0AE75CF10064C440 /* close_hover.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = close_hover.tif; path = ../Images/close_hover.tif; sourceTree = SOURCE_ROOT; };
+ 63D54D7D0AE75CF10064C440 /* close.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = close.tif; path = ../Images/close.tif; sourceTree = SOURCE_ROOT; };
+ 63D54F770AE8280F0064C440 /* breakpointEditor.html */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.html; name = breakpointEditor.html; path = ../breakpointEditor.html; sourceTree = SOURCE_ROOT; };
+ 8D15AC360486D014006FF6A4 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
+ 8D15AC370486D014006FF6A4 /* Drosera.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Drosera.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 957876760C9A221B008B6383 /* ServerConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ServerConnection.h; sourceTree = "<group>"; };
+ 957876840C9A226A008B6383 /* ServerConnection.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ServerConnection.mm; sourceTree = "<group>"; };
+ 957879610C9B37BC008B6383 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = config.h; path = ../config.h; sourceTree = SOURCE_ROOT; };
+ 95B2A44E0C95EECD00850C41 /* DebuggerClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebuggerClient.h; sourceTree = "<group>"; };
+ 95B2A44F0C95EECD00850C41 /* DebuggerClient.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DebuggerClient.mm; sourceTree = "<group>"; };
+ 95B955240C975C7500AAB83B /* DebuggerDocumentPlatform.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DebuggerDocumentPlatform.mm; sourceTree = "<group>"; };
+ 95C906AF0C8E439200F9BE0F /* Platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Platform.h; path = ../ForwardingHeaders/wtf/Platform.h; sourceTree = SOURCE_ROOT; };
+ D23E47C50C4460C600B7CD07 /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = /System/Library/Frameworks/JavaScriptCore.framework; sourceTree = "<absolute>"; };
+ D2D794ED0C4BED83004784F7 /* DebuggerDocument.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 30; name = DebuggerDocument.cpp; path = ../DebuggerDocument.cpp; sourceTree = SOURCE_ROOT; };
+ D2D794EE0C4BED83004784F7 /* DebuggerDocument.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 30; name = DebuggerDocument.h; path = ../DebuggerDocument.h; sourceTree = SOURCE_ROOT; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 1CD8D54B0A4902B000E5677B /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 1CD8D56C0A49043E00E5677B /* Cocoa.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 8D15AC330486D014006FF6A4 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 63D54CBD0AE72C990064C440 /* Carbon.framework in Frameworks */,
+ 8D15AC340486D014006FF6A4 /* Cocoa.framework in Frameworks */,
+ D23E47C60C4460C600B7CD07 /* JavaScriptCore.framework in Frameworks */,
+ 1C27ABC60A413B720016ECF4 /* WebKit.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 1058C7A6FEA54F5311CA2CBB /* Linked Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 63D54CBC0AE72C990064C440 /* Carbon.framework */,
+ 1058C7A7FEA54F5311CA2CBB /* Cocoa.framework */,
+ 1C27ABC50A413B720016ECF4 /* WebKit.framework */,
+ );
+ name = "Linked Frameworks";
+ sourceTree = "<group>";
+ };
+ 1058C7A8FEA54F5311CA2CBB /* Other Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 2A37F4C4FDCFA73011CA2CEA /* AppKit.framework */,
+ 13E42FBA07B3F13500E4EEF1 /* CoreData.framework */,
+ 2A37F4C5FDCFA73011CA2CEA /* Foundation.framework */,
+ );
+ name = "Other Frameworks";
+ sourceTree = "<group>";
+ };
+ 19C28FB0FE9D524F11CA2CBB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 8D15AC370486D014006FF6A4 /* Drosera.app */,
+ 1CD8D54D0A4902B000E5677B /* DroseraLauncher.app */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 1CC058B70A44A210006FE533 /* Images */ = {
+ isa = PBXGroup;
+ children = (
+ 63D54D7B0AE75CF10064C440 /* close_active.tif */,
+ 63D54D7C0AE75CF10064C440 /* close_hover.tif */,
+ 63D54D7D0AE75CF10064C440 /* close.tif */,
+ 63D54BD60AE600560064C440 /* breakpointeditor.png */,
+ 15CE854F0ADBEA610078A734 /* fileIcon.jpg */,
+ 15CE85500ADBEA610078A734 /* siteCollapsed.tif */,
+ 15CE85510ADBEA610078A734 /* siteExpanded.tif */,
+ 15CE85520ADBEA610078A734 /* siteIcon.tif */,
+ 15CE85530ADBEA610078A734 /* SourceArrowOpen.png */,
+ 1C6F84510A58EDFE004FCD89 /* console.png */,
+ 1C4FF7530A44F6320000D05D /* gutter.png */,
+ 1C4FF91F0A45F3520000D05D /* glossyHeader.png */,
+ 1CD434B10A4B86F800A007AB /* glossyHeaderPressed.png */,
+ 1C4FF94D0A45F5060000D05D /* popUpArrows.png */,
+ 1CC058B80A44A210006FE533 /* breakPoint.tif */,
+ 1CC058B90A44A210006FE533 /* breakPointDisabled.tif */,
+ 1CC058E00A44A210006FE533 /* programCounter.tif */,
+ 1C4FFE5C0A466F5D0000D05D /* programCounterBreakPoint.tif */,
+ 1C4FFE5D0A466F5D0000D05D /* programCounterBreakPointDisabled.tif */,
+ 1CC058CC0A44A210006FE533 /* glossyFooterFill.tif */,
+ 1CC058D80A44A210006FE533 /* navLeftDisabled.png */,
+ 1CC058D90A44A210006FE533 /* navLeftNormal.png */,
+ 1CC058DA0A44A210006FE533 /* navLeftPressed.png */,
+ 1CC058DB0A44A210006FE533 /* navRightDisabled.png */,
+ 1CC058DC0A44A210006FE533 /* navRightNormal.png */,
+ 1CC058DD0A44A210006FE533 /* navRightPressed.png */,
+ 1CC058E10A44A210006FE533 /* splitterBar.tif */,
+ 1CC058E20A44A210006FE533 /* splitterDimple.tif */,
+ 1CC058E60A44A210006FE533 /* finishFunction.tif */,
+ 1CC058E40A44A210006FE533 /* continue.tif */,
+ 1CC058E70A44A210006FE533 /* pause.tif */,
+ 1CC058E80A44A210006FE533 /* run.tif */,
+ 1CC058E90A44A210006FE533 /* step.tif */,
+ 1C6F83FE0A58E97D004FCD89 /* stepOut.tif */,
+ 1CC058EA0A44A210006FE533 /* stepOver.tif */,
+ 1CC058EB0A44A210006FE533 /* stop.tif */,
+ 1CC0596F0A44A485006FE533 /* toolbarBackground.png */,
+ 1C2632D10A4AF0A800EA7CD8 /* verticalSplitterBar.tiff */,
+ 1C2632D20A4AF0A800EA7CD8 /* verticalSplitterDimple.tiff */,
+ 1C2632D50A4AF0B800EA7CD8 /* SourceArrow.png */,
+ 1C2632D60A4AF0B800EA7CD8 /* SourceArrowBlank.png */,
+ 1C2632D90A4AF0D200EA7CD8 /* background_stripe.png */,
+ );
+ name = Images;
+ path = ../Images;
+ sourceTree = "<group>";
+ };
+ 1CD8D53C0A49025D00E5677B /* Nightly Support */ = {
+ isa = PBXGroup;
+ children = (
+ 1CD8D54F0A4902B000E5677B /* LauncherInfo.plist */,
+ 1CD8D5680A49041C00E5677B /* launcher.m */,
+ );
+ name = "Nightly Support";
+ sourceTree = "<group>";
+ };
+ 2A37F4AAFDCFA73011CA2CEA /* SafariBug */ = {
+ isa = PBXGroup;
+ children = (
+ D23E47C50C4460C600B7CD07 /* JavaScriptCore.framework */,
+ 2A37F4ABFDCFA73011CA2CEA /* Classes */,
+ 2A37F4AFFDCFA73011CA2CEA /* Other Sources */,
+ 2A37F4B8FDCFA73011CA2CEA /* Resources */,
+ 1CD8D53C0A49025D00E5677B /* Nightly Support */,
+ 2A37F4C3FDCFA73011CA2CEA /* Frameworks */,
+ 19C28FB0FE9D524F11CA2CBB /* Products */,
+ );
+ name = SafariBug;
+ sourceTree = "<group>";
+ };
+ 2A37F4ABFDCFA73011CA2CEA /* Classes */ = {
+ isa = PBXGroup;
+ children = (
+ 63D54F770AE8280F0064C440 /* breakpointEditor.html */,
+ 1C6F84530A58EE06004FCD89 /* console.css */,
+ 1C6F84540A58EE06004FCD89 /* console.html */,
+ 1C6F861F0A599F65004FCD89 /* console.js */,
+ 1C74F1830A47DEE600FEC632 /* DebuggerApplication.h */,
+ 1C74F1840A47DEE600FEC632 /* DebuggerApplication.mm */,
+ 95B2A44E0C95EECD00850C41 /* DebuggerClient.h */,
+ 95B2A44F0C95EECD00850C41 /* DebuggerClient.mm */,
+ D2D794ED0C4BED83004784F7 /* DebuggerDocument.cpp */,
+ D2D794EE0C4BED83004784F7 /* DebuggerDocument.h */,
+ 95B955240C975C7500AAB83B /* DebuggerDocumentPlatform.mm */,
+ 1C27AC230A413D660016ECF4 /* debugger.js */,
+ 1C27AC1F0A413D2D0016ECF4 /* debugger.html */,
+ 1C4FF7430A44F5260000D05D /* debugger.css */,
+ 95C906AF0C8E439200F9BE0F /* Platform.h */,
+ 957876760C9A221B008B6383 /* ServerConnection.h */,
+ 957876840C9A226A008B6383 /* ServerConnection.mm */,
+ 1C74F0340A47BF8300FEC632 /* viewer.html */,
+ 1C74F03A0A47BFD600FEC632 /* viewer.css */,
+ );
+ name = Classes;
+ sourceTree = "<group>";
+ tabWidth = 8;
+ usesTabs = 0;
+ };
+ 2A37F4AFFDCFA73011CA2CEA /* Other Sources */ = {
+ isa = PBXGroup;
+ children = (
+ 957879610C9B37BC008B6383 /* config.h */,
+ 2A37F4B0FDCFA73011CA2CEA /* main.m */,
+ );
+ name = "Other Sources";
+ sourceTree = "<group>";
+ tabWidth = 8;
+ usesTabs = 0;
+ };
+ 2A37F4B8FDCFA73011CA2CEA /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ 1C3487970A81208400101C5C /* Drosera.icns */,
+ 2A37F4B6FDCFA73011CA2CEA /* MainMenu.nib */,
+ 2A37F4B4FDCFA73011CA2CEA /* Debugger.nib */,
+ 8D15AC360486D014006FF6A4 /* Info.plist */,
+ 1CC058B70A44A210006FE533 /* Images */,
+ );
+ name = Resources;
+ sourceTree = "<group>";
+ tabWidth = 8;
+ usesTabs = 0;
+ };
+ 2A37F4C3FDCFA73011CA2CEA /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 1058C7A6FEA54F5311CA2CBB /* Linked Frameworks */,
+ 1058C7A8FEA54F5311CA2CBB /* Other Frameworks */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 1CD8D54C0A4902B000E5677B /* Drosera (Nightly Launcher) */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 1CD8D5500A4902B000E5677B /* Build configuration list for PBXNativeTarget "Drosera (Nightly Launcher)" */;
+ buildPhases = (
+ 1CD8D5490A4902B000E5677B /* Resources */,
+ 1CD8D54A0A4902B000E5677B /* Sources */,
+ 1CD8D54B0A4902B000E5677B /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 1CD8D5AA0A49104E00E5677B /* PBXTargetDependency */,
+ );
+ name = "Drosera (Nightly Launcher)";
+ productName = "Drosera (Nightly Launcher)";
+ productReference = 1CD8D54D0A4902B000E5677B /* DroseraLauncher.app */;
+ productType = "com.apple.product-type.application";
+ };
+ 8D15AC270486D014006FF6A4 /* Drosera */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = C05733C708A9546B00998B17 /* Build configuration list for PBXNativeTarget "Drosera" */;
+ buildPhases = (
+ 8D15AC2B0486D014006FF6A4 /* Resources */,
+ 8D15AC300486D014006FF6A4 /* Sources */,
+ 8D15AC330486D014006FF6A4 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = Drosera;
+ productInstallPath = "$(HOME)/Applications";
+ productName = SafariBug;
+ productReference = 8D15AC370486D014006FF6A4 /* Drosera.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 2A37F4A9FDCFA73011CA2CEA /* Project object */ = {
+ isa = PBXProject;
+ buildConfigurationList = C05733CB08A9546B00998B17 /* Build configuration list for PBXProject "Drosera" */;
+ compatibilityVersion = "Xcode 2.4";
+ hasScannedForEncodings = 1;
+ mainGroup = 2A37F4AAFDCFA73011CA2CEA /* SafariBug */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 8D15AC270486D014006FF6A4 /* Drosera */,
+ 1CD8D54C0A4902B000E5677B /* Drosera (Nightly Launcher) */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 1CD8D5490A4902B000E5677B /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 1CD8D5A60A49102900E5677B /* Drosera.app in Resources */,
+ 5D2C827F0A816BA700C193FD /* Drosera.icns in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 8D15AC2B0486D014006FF6A4 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8D15AC2E0486D014006FF6A4 /* Debugger.nib in Resources */,
+ 1C3487980A81208400101C5C /* Drosera.icns in Resources */,
+ 8D15AC2D0486D014006FF6A4 /* MainMenu.nib in Resources */,
+ 1C2632D70A4AF0B800EA7CD8 /* SourceArrow.png in Resources */,
+ 1C2632D80A4AF0B800EA7CD8 /* SourceArrowBlank.png in Resources */,
+ 15CE85580ADBEA620078A734 /* SourceArrowOpen.png in Resources */,
+ 1C2632DA0A4AF0D200EA7CD8 /* background_stripe.png in Resources */,
+ 1CC058EE0A44A210006FE533 /* breakPoint.tif in Resources */,
+ 1CC058EF0A44A210006FE533 /* breakPointDisabled.tif in Resources */,
+ 63D54F780AE8280F0064C440 /* breakpointEditor.html in Resources */,
+ 63D54BD70AE600560064C440 /* breakpointeditor.png in Resources */,
+ 63D54D800AE75CF10064C440 /* close.tif in Resources */,
+ 63D54D7E0AE75CF10064C440 /* close_active.tif in Resources */,
+ 63D54D7F0AE75CF10064C440 /* close_hover.tif in Resources */,
+ 1C6F84550A58EE06004FCD89 /* console.css in Resources */,
+ 1C6F84560A58EE06004FCD89 /* console.html in Resources */,
+ 1C6F86730A59A18B004FCD89 /* console.js in Resources */,
+ 1C6F84520A58EDFE004FCD89 /* console.png in Resources */,
+ 1CC0591A0A44A210006FE533 /* continue.tif in Resources */,
+ 1C4FF7440A44F52C0000D05D /* debugger.css in Resources */,
+ 1C27AC200A413D2D0016ECF4 /* debugger.html in Resources */,
+ 1C27B1260A421D870016ECF4 /* debugger.js in Resources */,
+ 15CE85540ADBEA620078A734 /* fileIcon.jpg in Resources */,
+ 1CC059020A44A210006FE533 /* glossyFooterFill.tif in Resources */,
+ 1C4FF9210A45F3520000D05D /* glossyHeader.png in Resources */,
+ 1CD434B20A4B86F800A007AB /* glossyHeaderPressed.png in Resources */,
+ 1C4FF7540A44F6320000D05D /* gutter.png in Resources */,
+ 1CC0590E0A44A210006FE533 /* navLeftDisabled.png in Resources */,
+ 1CC0590F0A44A210006FE533 /* navLeftNormal.png in Resources */,
+ 1CC059100A44A210006FE533 /* navLeftPressed.png in Resources */,
+ 1CC059110A44A210006FE533 /* navRightDisabled.png in Resources */,
+ 1CC059120A44A210006FE533 /* navRightNormal.png in Resources */,
+ 1CC059130A44A210006FE533 /* navRightPressed.png in Resources */,
+ 1CC0591D0A44A210006FE533 /* pause.tif in Resources */,
+ 1C4FF94E0A45F5060000D05D /* popUpArrows.png in Resources */,
+ 1CC059160A44A210006FE533 /* programCounter.tif in Resources */,
+ 1C4FFE5E0A466F5D0000D05D /* programCounterBreakPoint.tif in Resources */,
+ 1C4FFE5F0A466F5D0000D05D /* programCounterBreakPointDisabled.tif in Resources */,
+ 1CC0591E0A44A210006FE533 /* run.tif in Resources */,
+ 15CE85550ADBEA620078A734 /* siteCollapsed.tif in Resources */,
+ 15CE85560ADBEA620078A734 /* siteExpanded.tif in Resources */,
+ 15CE85570ADBEA620078A734 /* siteIcon.tif in Resources */,
+ 1CC059170A44A210006FE533 /* splitterBar.tif in Resources */,
+ 1CC059180A44A210006FE533 /* splitterDimple.tif in Resources */,
+ 1CC0591F0A44A210006FE533 /* step.tif in Resources */,
+ 1C6F83FF0A58E97D004FCD89 /* stepOut.tif in Resources */,
+ 1CC059200A44A210006FE533 /* stepOver.tif in Resources */,
+ 1CC059700A44A485006FE533 /* toolbarBackground.png in Resources */,
+ 1C2632D30A4AF0A800EA7CD8 /* verticalSplitterBar.tiff in Resources */,
+ 1C2632D40A4AF0A800EA7CD8 /* verticalSplitterDimple.tiff in Resources */,
+ 1C74F04B0A47BFE800FEC632 /* viewer.css in Resources */,
+ 1C74F0350A47BF8300FEC632 /* viewer.html in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 1CD8D54A0A4902B000E5677B /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 1CD8D5690A49041C00E5677B /* launcher.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 8D15AC300486D014006FF6A4 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 1C74F1850A47DEE600FEC632 /* DebuggerApplication.mm in Sources */,
+ 95B2A4500C95EECD00850C41 /* DebuggerClient.mm in Sources */,
+ D2D794FD0C4BED83004784F7 /* DebuggerDocument.cpp in Sources */,
+ 95B955250C975C7500AAB83B /* DebuggerDocumentPlatform.mm in Sources */,
+ 957876850C9A226A008B6383 /* ServerConnection.mm in Sources */,
+ 8D15AC320486D014006FF6A4 /* main.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ 1CD8D5AA0A49104E00E5677B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 8D15AC270486D014006FF6A4 /* Drosera */;
+ targetProxy = 1CD8D5A90A49104E00E5677B /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+ 2A37F4B4FDCFA73011CA2CEA /* Debugger.nib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 2A37F4B5FDCFA73011CA2CEA /* Debugger.nib */,
+ );
+ name = Debugger.nib;
+ sourceTree = "<group>";
+ };
+ 2A37F4B6FDCFA73011CA2CEA /* MainMenu.nib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 2A37F4B7FDCFA73011CA2CEA /* MainMenu.nib */,
+ );
+ name = MainMenu.nib;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 1CD8D5510A4902B000E5677B /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ GCC_DEBUGGING_SYMBOLS = full;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_MODEL_TUNING = G5;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ INFOPLIST_FILE = LauncherInfo.plist;
+ INSTALL_PATH = "$(HOME)/Applications";
+ PRODUCT_NAME = DroseraLauncher;
+ WRAPPER_EXTENSION = app;
+ };
+ name = Debug;
+ };
+ 1CD8D5520A4902B000E5677B /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ DEPLOYMENT_POSTPROCESSING = YES;
+ GCC_DEBUGGING_SYMBOLS = full;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+ INFOPLIST_FILE = LauncherInfo.plist;
+ INSTALL_PATH = "$(HOME)/Applications";
+ PRODUCT_NAME = DroseraLauncher;
+ WRAPPER_EXTENSION = app;
+ };
+ name = Release;
+ };
+ C05733C808A9546B00998B17 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ GCC_C_LANGUAGE_STANDARD = c99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+ GCC_MODEL_TUNING = G5;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = "";
+ HEADER_SEARCH_PATHS = ../ForwardingHeaders;
+ INFOPLIST_FILE = Info.plist;
+ PRODUCT_NAME = Drosera;
+ USER_HEADER_SEARCH_PATHS = ../ForwardingHeaders/;
+ VALID_ARCHS = "ppc7400 ppc970 i386 ppc";
+ WRAPPER_EXTENSION = app;
+ ZERO_LINK = NO;
+ };
+ name = Debug;
+ };
+ C05733C908A9546B00998B17 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_C_LANGUAGE_STANDARD = c99;
+ GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+ GCC_MODEL_TUNING = G5;
+ GCC_PREFIX_HEADER = "";
+ HEADER_SEARCH_PATHS = ../ForwardingHeaders;
+ INFOPLIST_FILE = Info.plist;
+ PRODUCT_NAME = Drosera;
+ USER_HEADER_SEARCH_PATHS = ../ForwardingHeaders/;
+ VALID_ARCHS = "ppc7400 ppc970 i386 ppc";
+ WRAPPER_EXTENSION = app;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ C05733CC08A9546B00998B17 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ PREBINDING = NO;
+ USER_HEADER_SEARCH_PATHS = ../ForwardingHeaders/;
+ };
+ name = Debug;
+ };
+ C05733CD08A9546B00998B17 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ PREBINDING = NO;
+ USER_HEADER_SEARCH_PATHS = ../ForwardingHeaders/;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 1CD8D5500A4902B000E5677B /* Build configuration list for PBXNativeTarget "Drosera (Nightly Launcher)" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1CD8D5510A4902B000E5677B /* Debug */,
+ 1CD8D5520A4902B000E5677B /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ C05733C708A9546B00998B17 /* Build configuration list for PBXNativeTarget "Drosera" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C05733C808A9546B00998B17 /* Debug */,
+ C05733C908A9546B00998B17 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ C05733CB08A9546B00998B17 /* Build configuration list for PBXProject "Drosera" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C05733CC08A9546B00998B17 /* Debug */,
+ C05733CD08A9546B00998B17 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 2A37F4A9FDCFA73011CA2CEA /* Project object */;
+}
diff --git a/WebKitTools/Drosera/mac/Info.plist b/WebKitTools/Drosera/mac/Info.plist
new file mode 100644
index 0000000..536f5a3
--- /dev/null
+++ b/WebKitTools/Drosera/mac/Info.plist
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleGetInfoString</key>
+ <string>420+, Copyright 2006 Apple Computer, Inc.</string>
+ <key>CFBundleIdentifier</key>
+ <string>org.webkit.drosera</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>CFBundleIconFile</key>
+ <string>Drosera</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>NSMainNibFile</key>
+ <string>MainMenu</string>
+ <key>NSPrincipalClass</key>
+ <string>NSApplication</string>
+</dict>
+</plist>
diff --git a/WebKitTools/Drosera/mac/LauncherInfo.plist b/WebKitTools/Drosera/mac/LauncherInfo.plist
new file mode 100644
index 0000000..12c4472
--- /dev/null
+++ b/WebKitTools/Drosera/mac/LauncherInfo.plist
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIconFile</key>
+ <string>Drosera</string>
+ <key>CFBundleIdentifier</key>
+ <string>org.webkit.drosera.launcher</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>VERSION</string>
+ <key>NSMainNibFile</key>
+ <string>MainMenu</string>
+ <key>NSPrincipalClass</key>
+ <string>NSApplication</string>
+</dict>
+</plist>
diff --git a/WebKitTools/Drosera/mac/Makefile b/WebKitTools/Drosera/mac/Makefile
new file mode 100644
index 0000000..058c21e
--- /dev/null
+++ b/WebKitTools/Drosera/mac/Makefile
@@ -0,0 +1,2 @@
+SCRIPTS_PATH = ../../Scripts
+include ../../../Makefile.shared
diff --git a/WebKitTools/Drosera/mac/ServerConnection.h b/WebKitTools/Drosera/mac/ServerConnection.h
new file mode 100644
index 0000000..f2b1303
--- /dev/null
+++ b/WebKitTools/Drosera/mac/ServerConnection.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007 Vladimir Olexa (vladimir.olexa@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.
+ */
+
+@class DebuggerClient;
+@class NSString;
+@class WebScriptCallFrame;
+@class WebScriptDebugServer;
+
+@interface ServerConnection : NSObject <WebScriptDebugListener>
+{
+ NSString *currentServerName;
+ WebScriptCallFrame *currentFrame;
+ id<WebScriptDebugServer> server;
+ JSGlobalContextRef globalContext;
+}
+
+- (id)initWithServerName:(NSString *)serverName;
+- (void)setGlobalContext:(JSGlobalContextRef)globalContextRef;
+- (void)pause;
+- (void)resume;
+- (void)stepInto;
+- (void)switchToServerNamed:(NSString *)name;
+- (void)applicationTerminating:(NSNotification *)notifiction;
+- (WebScriptCallFrame *)currentFrame;
+- (NSString *)currentServerName;
+
+@end
diff --git a/WebKitTools/Drosera/mac/ServerConnection.mm b/WebKitTools/Drosera/mac/ServerConnection.mm
new file mode 100644
index 0000000..8444ee9
--- /dev/null
+++ b/WebKitTools/Drosera/mac/ServerConnection.mm
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007 Vladimir Olexa (vladimir.olexa@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.
+ */
+
+#import "config.h"
+#import "ServerConnection.h"
+
+#import "DebuggerDocument.h"
+
+#import <JavaScriptCore/JSContextRef.h>
+#import <JavaScriptCore/JSRetainPtr.h>
+#import <JavaScriptCore/JSStringRefCF.h>
+#import <JavaScriptCore/RetainPtr.h>
+
+@implementation ServerConnection
+
+#pragma mark -
+- (id)initWithServerName:(NSString *)serverName;
+{
+ if (!(self = [super init]))
+ return nil;
+
+ [self switchToServerNamed:serverName];
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationTerminating:) name:NSApplicationWillTerminateNotification object:nil];
+
+ return self;
+}
+
+- (void)dealloc
+{
+ [[NSNotificationCenter defaultCenter] removeObserver:self name:NSApplicationWillTerminateNotification object:nil];
+
+ [currentServerName release];
+ [currentFrame release];
+ [server release];
+ JSGlobalContextRelease(globalContext);
+ [super dealloc];
+}
+
+- (void)setGlobalContext:(JSGlobalContextRef)globalContextRef
+{
+ globalContext = JSGlobalContextRetain(globalContextRef);
+}
+
+#pragma mark -
+#pragma mark Pause & Step
+
+- (void)pause
+{
+ if ([[(NSDistantObject *)server connectionForProxy] isValid])
+ [server pause];
+ [[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
+}
+
+- (void)resume
+{
+ if ([[(NSDistantObject *)server connectionForProxy] isValid])
+ [server resume];
+}
+
+- (void)stepInto
+{
+ if ([[(NSDistantObject *)server connectionForProxy] isValid])
+ [server step];
+}
+
+#pragma mark -
+#pragma mark Connection Handling
+
+- (void)switchToServerNamed:(NSString *)name
+{
+ if (server) {
+ [[NSNotificationCenter defaultCenter] removeObserver:self name:NSConnectionDidDieNotification object:[(NSDistantObject *)server connectionForProxy]];
+ if ([[(NSDistantObject *)server connectionForProxy] isValid]) {
+ [server removeListener:self];
+ [self resume];
+ }
+ }
+
+ id<WebScriptDebugServer> oldServer = server;
+ server = [name length] ? [[NSConnection rootProxyForConnectionWithRegisteredName:name host:nil] retain] : nil;
+ [oldServer release];
+
+ NSString *oldServerName = currentServerName;
+ currentServerName = [name retain];
+ [oldServerName release];
+
+ if (server) {
+ @try {
+ [(NSDistantObject *)server setProtocolForProxy:@protocol(WebScriptDebugServer)];
+ [server addListener:self];
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(serverConnectionDidDie:) name:NSConnectionDidDieNotification object:[(NSDistantObject *)server connectionForProxy]];
+ } @catch (NSException *exception) {
+ [currentServerName release];
+ currentServerName = nil;
+ [server release];
+ server = nil;
+ }
+ }
+}
+
+- (void)applicationTerminating:(NSNotification *)notifiction
+{
+ if (server && [[(NSDistantObject *)server connectionForProxy] isValid]) {
+ [self switchToServerNamed:nil];
+ // call the runloop for a while to make sure our removeListener: is sent to the server
+ [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.25]];
+ }
+}
+
+- (void)serverConnectionDidDie:(NSNotification *)notifiction
+{
+ [self switchToServerNamed:nil];
+}
+
+#pragma mark -
+#pragma mark Debug Listener Callbacks
+
+- (void)webView:(WebView *)view didLoadMainResourceForDataSource:(WebDataSource *)dataSource
+{
+ // Get document source
+ NSString *documentSource = nil;
+ id <WebDocumentRepresentation> rep = [dataSource representation];
+ if ([rep canProvideDocumentSource])
+ documentSource = [rep documentSource];
+
+ if (!documentSource)
+ return;
+
+ JSRetainPtr<JSStringRef> documentSourceJS(Adopt, JSStringCreateWithCFString((CFStringRef)documentSource));
+
+ // Get URL
+ NSString *url = [[[dataSource response] URL] absoluteString];
+ JSRetainPtr<JSStringRef> urlJS(Adopt, JSStringCreateWithCFString(url ? (CFStringRef)url : CFSTR("")));
+
+ DebuggerDocument::updateFileSource(globalContext, documentSourceJS.get(), urlJS.get());
+}
+
+- (void)webView:(WebView *)view didParseSource:(NSString *)source baseLineNumber:(unsigned)baseLine fromURL:(NSURL *)url sourceId:(int)sid forWebFrame:(WebFrame *)webFrame
+{
+ if (!globalContext)
+ return;
+
+ RetainPtr<NSString> sourceCopy = source;
+ if (!sourceCopy.get())
+ return;
+
+ RetainPtr<NSString> documentSourceCopy;
+ RetainPtr<NSString> urlCopy = [url absoluteString];
+
+ WebDataSource *dataSource = [webFrame dataSource];
+ if (!url || [[[dataSource response] URL] isEqual:url]) {
+ id <WebDocumentRepresentation> rep = [dataSource representation];
+ if ([rep canProvideDocumentSource])
+ documentSourceCopy = [rep documentSource];
+ if (!urlCopy.get())
+ urlCopy = [[[dataSource response] URL] absoluteString];
+ }
+
+ JSRetainPtr<JSStringRef> sourceCopyJS(Adopt, JSStringCreateWithCFString((CFStringRef)sourceCopy.get())); // We checked for NULL earlier.
+ JSRetainPtr<JSStringRef> documentSourceCopyJS(Adopt, JSStringCreateWithCFString(documentSourceCopy.get() ? (CFStringRef)documentSourceCopy.get() : CFSTR("")));
+ JSRetainPtr<JSStringRef> urlCopyJS(Adopt, JSStringCreateWithCFString(urlCopy.get() ? (CFStringRef)urlCopy.get() : CFSTR("")));
+ JSValueRef sidJS = JSValueMakeNumber(globalContext, sid);
+ JSValueRef baseLineJS = JSValueMakeNumber(globalContext, baseLine);
+
+ DebuggerDocument::didParseScript(globalContext, sourceCopyJS.get(), documentSourceCopyJS.get(), urlCopyJS.get(), sidJS, baseLineJS);
+}
+
+- (void)webView:(WebView *)view failedToParseSource:(NSString *)source baseLineNumber:(unsigned)baseLine fromURL:(NSURL *)url withError:(NSError *)error forWebFrame:(WebFrame *)webFrame
+{
+}
+
+- (void)webView:(WebView *)view didEnterCallFrame:(WebScriptCallFrame *)frame sourceId:(int)sid line:(int)lineno forWebFrame:(WebFrame *)webFrame
+{
+ if (!globalContext)
+ return;
+
+ id old = currentFrame;
+ currentFrame = [frame retain];
+ [old release];
+
+ JSValueRef sidJS = JSValueMakeNumber(globalContext, sid);
+ JSValueRef linenoJS = JSValueMakeNumber(globalContext, lineno);
+
+ DebuggerDocument::didEnterCallFrame(globalContext, sidJS, linenoJS);
+}
+
+- (void)webView:(WebView *)view willExecuteStatement:(WebScriptCallFrame *)frame sourceId:(int)sid line:(int)lineno forWebFrame:(WebFrame *)webFrame
+{
+ if (!globalContext)
+ return;
+
+ JSValueRef sidJS = JSValueMakeNumber(globalContext, sid);
+ JSValueRef linenoJS = JSValueMakeNumber(globalContext, lineno);
+
+ DebuggerDocument::willExecuteStatement(globalContext, sidJS, linenoJS);
+}
+
+- (void)webView:(WebView *)view willLeaveCallFrame:(WebScriptCallFrame *)frame sourceId:(int)sid line:(int)lineno forWebFrame:(WebFrame *)webFrame
+{
+ if (!globalContext)
+ return;
+
+ JSValueRef sidJS = JSValueMakeNumber(globalContext, sid);
+ JSValueRef linenoJS = JSValueMakeNumber(globalContext, lineno);
+
+ DebuggerDocument::willLeaveCallFrame(globalContext, sidJS, linenoJS);
+
+ id old = currentFrame;
+ currentFrame = [[frame caller] retain];
+ [old release];
+}
+
+- (void)webView:(WebView *)view exceptionWasRaised:(WebScriptCallFrame *)frame sourceId:(int)sid line:(int)lineno forWebFrame:(WebFrame *)webFrame
+{
+ if (!globalContext)
+ return;
+
+ JSValueRef sidJS = JSValueMakeNumber(globalContext, sid);
+ JSValueRef linenoJS = JSValueMakeNumber(globalContext, lineno);
+
+ DebuggerDocument::exceptionWasRaised(globalContext, sidJS, linenoJS);
+}
+
+#pragma mark -
+#pragma mark Stack & Variables
+
+- (WebScriptCallFrame *)currentFrame
+{
+ return currentFrame;
+}
+
+#pragma mark -
+#pragma mark Server Detection Callbacks
+
+-(NSString *)currentServerName
+{
+ return currentServerName;
+}
+@end
diff --git a/WebKitTools/Drosera/mac/launcher.m b/WebKitTools/Drosera/mac/launcher.m
new file mode 100644
index 0000000..7722312
--- /dev/null
+++ b/WebKitTools/Drosera/mac/launcher.m
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ */
+
+#import <Cocoa/Cocoa.h>
+#import <CoreFoundation/CoreFoundation.h>
+
+void displayErrorAndQuit(NSString *title, NSString *message)
+{
+ NSApplicationLoad();
+ NSRunCriticalAlertPanel(title, message, @"Quit", nil, nil);
+ exit(0);
+}
+
+void checkMacOSXVersion()
+{
+ long versionNumber = 0;
+ OSErr error = Gestalt(gestaltSystemVersion, &versionNumber);
+ if (error != noErr || versionNumber < 0x1040)
+ displayErrorAndQuit(@"Mac OS X 10.4 is Required", @"Nightly builds of Drosera require Mac OS X 10.4 or newer.");
+}
+
+static void myExecve(NSString *executable, NSArray *args, NSDictionary *environment)
+{
+ char **argv = (char **)calloc(sizeof(char *), [args count] + 1);
+ char **env = (char **)calloc(sizeof(char *), [environment count] + 1);
+
+ NSEnumerator *e = [args objectEnumerator];
+ NSString *s;
+ int i = 0;
+ while (s = [e nextObject])
+ argv[i++] = (char *) [s UTF8String];
+
+ e = [environment keyEnumerator];
+ i = 0;
+ while (s = [e nextObject])
+ env[i++] = (char *) [[NSString stringWithFormat:@"%@=%@", s, [environment objectForKey:s]] UTF8String];
+
+ execve([executable fileSystemRepresentation], argv, env);
+}
+
+NSString *currentSystemVersion()
+{
+ long version;
+ if (Gestalt(gestaltSystemVersion, &version) != noErr)
+ return @"10.4";
+
+ return [NSString stringWithFormat:@"%x.%x", (version & 0xFF00) >> 8, (version & 0x00F0) >> 4];
+}
+
+int main(int argc, char *argv[])
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ checkMacOSXVersion();
+
+ CFURLRef webkitURL = nil;
+ OSStatus err = LSFindApplicationForInfo(kLSUnknownCreator, CFSTR("org.webkit.nightly.WebKit"), nil, nil, &webkitURL);
+ if (err != noErr)
+ displayErrorAndQuit(@"Unable to locate WebKit.app", @"Drosera nightly builds require WebKit.app to run. Please check that it is available and then try again.");
+
+ NSBundle *webKitAppBundle = [NSBundle bundleWithPath:[(NSURL *)webkitURL path]];
+ NSString *frameworkPath = [[webKitAppBundle privateFrameworksPath] stringByAppendingPathComponent:currentSystemVersion()];
+ NSBundle *droseraBundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"Drosera" ofType:@"app"]];
+ NSString *executablePath = [droseraBundle executablePath];
+ NSString *pathToEnablerLib = [webKitAppBundle pathForResource:@"WebKitNightlyEnabler" ofType:@"dylib"];
+
+ NSMutableArray *arguments = [NSMutableArray arrayWithObjects:executablePath, @"-WebKitDeveloperExtras", @"YES", nil];
+
+ while (*++argv)
+ [arguments addObject:[NSString stringWithUTF8String:*argv]];
+
+ NSDictionary *environment = [NSDictionary dictionaryWithObjectsAndKeys:frameworkPath, @"DYLD_FRAMEWORK_PATH",
+ @"YES", @"WEBKIT_UNSET_DYLD_FRAMEWORK_PATH", pathToEnablerLib, @"DYLD_INSERT_LIBRARIES",
+ [[NSBundle mainBundle] executablePath], @"WebKitAppPath", nil];
+
+ myExecve(executablePath, arguments, environment);
+
+ char *error = strerror(errno);
+ NSString *errorMessage = [NSString stringWithFormat:@"Launching Drosera at %@ failed with the error '%s' (%d)", [(NSURL *)webkitURL path], error, errno];
+ displayErrorAndQuit(@"Unable to launch Drosera", errorMessage);
+
+ [pool release];
+ return 0;
+}
diff --git a/WebKitTools/Drosera/mac/main.m b/WebKitTools/Drosera/mac/main.m
new file mode 100644
index 0000000..2c09761
--- /dev/null
+++ b/WebKitTools/Drosera/mac/main.m
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2006 Apple Computer, 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 <Cocoa/Cocoa.h>
+
+int main(int argc, char *argv[])
+{
+ return NSApplicationMain(argc, (const char **) argv);
+}
diff --git a/WebKitTools/Drosera/viewer.css b/WebKitTools/Drosera/viewer.css
new file mode 100644
index 0000000..aaac7a9
--- /dev/null
+++ b/WebKitTools/Drosera/viewer.css
@@ -0,0 +1,146 @@
+/*
+ * 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 { background-image: url(gutter.png); background-repeat: repeat-y; margin: 0; padding: 0; }
+img { padding: 0; margin: 0; }
+
+table { border-spacing: 0; padding: 0; margin: 0; width: 100%; }
+.gutter { -webkit-user-select: none; cursor: default; width: 32px; min-width: 32px; max-width: 32px; -webkit-box-sizing: border-box; font-size: 9px; font-family: Helvetica; color: #888; text-align: right; padding-right: 4px; }
+.source { font-family: Monaco, monospace; white-space: pre; padding-left: 4px; padding-right: 4px; font-size: 11px; line-height: 14px; }
+
+.keyword { color: #8b0053 }
+.string { color: #a00000 }
+.number { color: #2900ff }
+.comment { color: #007215 }
+
+td.gutter:after { content: attr(title); -webkit-user-select: none; }
+
+.breakpoint td.gutter, .current td.gutter { padding-right: 1px; vertical-align: top; }
+.breakpoint td.gutter:after { content: url(breakPoint.tif); -webkit-user-select: none; vertical-align: middle; }
+.breakpoint.disabled td.gutter:after { content: url(breakPointDisabled.tif); }
+
+.current td.gutter:after { content: url(programCounter.tif); -webkit-user-select: none; vertical-align: middle; }
+.current.breakpoint td.gutter:after { content: url(programCounterBreakPoint.tif); }
+.current.breakpoint.disabled td.gutter:after { content: url(programCounterBreakPointDisabled.tif); }
+.current td.source { background-color: #abbffe; outline: 1px solid #406ffd; }
+
+#breakpointDrag {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 100;
+ -webkit-user-select: none;
+ cursor: default;
+}
+
+.editor {
+ top: -2px;
+ left: -2px;
+ margin-bottom: -2px;
+ position: relative;
+ min-width: 350px;
+ max-width: 500px;
+ border-width: 20px 12px 11px 36px;
+ border-color: transparent;
+ border-style: solid;
+ -webkit-border-image: url(breakpointeditor.png) 20 12 11 36;
+ font-size: 11px;
+ font-family: 'Lucida Grande', sans-serif;
+}
+
+.editor .top {
+ position: absolute;
+ height: 20px;
+ -webkit-border-top-right-radius: 6px;
+ background-color: rgb(0, 134, 226);
+ border-bottom: 2px solid rgb(0, 110, 208);
+ top: -4px;
+ right: -5px;
+ left: -5px;
+ padding-left: 5px;
+ padding-right: 5px;
+}
+
+.editor .bottom {
+ position: relative;
+ padding: 5px 0;
+ top: 20px;
+}
+
+.editor .top label {
+ margin-left: 15px;
+}
+
+.editor span.hitCounter {
+ margin-right: 4px;
+ margin-top: 1px;
+ padding-right: 2px;
+ padding-left: 2px;
+}
+
+.editor select.editorDropdown {
+ margin-top: -1px;
+}
+
+.editor div.condition {
+ position: relative;
+ background-color: white;
+ -webkit-user-modify: read-write-plaintext-only;
+ -webkit-nbsp-mode: space;
+ -webkit-line-break: after-white-space;
+ word-wrap: break-word;
+ outline: none;
+ font-family: monospace;
+ font-size: 10px;
+ line-height: 10px;
+ padding: 3px;
+ border: 1px solid darkgray;
+ top: -15px;
+ left: 65px;
+ margin-right: 65px;
+}
+
+.editor input.close {
+ margin:0px;
+ margin-right: -4px;
+ float: right;
+ background-color: transparent;
+ background-image:url("close.tif");
+ background-repeat: no-repeat;
+ height: 13px;
+ width: 12px;
+ border: none;
+}
+
+.editor input.close:active {
+ background-image:url("close_active.tif");
+}
+
+.editor input.close:hover {
+ background-image:url("close_hover.tif");
+}
diff --git a/WebKitTools/Drosera/viewer.html b/WebKitTools/Drosera/viewer.html
new file mode 100644
index 0000000..fb4a21c
--- /dev/null
+++ b/WebKitTools/Drosera/viewer.html
@@ -0,0 +1,48 @@
+<!--
+Copyright (C) 2006 Apple Computer, 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" />
+ <script type="text/javascript">
+ Element.prototype.firstParentWithClass = function(className) {
+ var node = this.parentNode;
+ while(node.className.indexOf(className) == -1) {
+ if (node == document)
+ return null;
+ node = node.parentNode;
+ }
+ return node;
+ }
+ </script>
+ <style type="text/css">
+ @import "viewer.css";
+ </style>
+</head>
+<body></body>
+</html>
diff --git a/WebKitTools/Drosera/win/BaseDelegate.h b/WebKitTools/Drosera/win/BaseDelegate.h
new file mode 100644
index 0000000..6bc2f3f
--- /dev/null
+++ b/WebKitTools/Drosera/win/BaseDelegate.h
@@ -0,0 +1,313 @@
+/*
+ * 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.
+ */
+
+#ifndef BaseDelegate_H
+#define BaseDelegate_H
+
+#include <WebKit/WebKit.h>
+
+struct IDataObject;
+struct IPropertyBag;
+struct IWebView;
+struct IWebFrame;
+struct IWebError;
+struct IWebURLRequest;
+struct IWebOpenPanelResultListener;
+
+class BaseDelegate : public IWebFrameLoadDelegate, public IWebUIDelegate {
+public:
+ // IUnknown
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(
+ /* [in] */ REFIID,
+ /* [retval][out] */ void**)
+ { return E_NOTIMPL; };
+
+ // IWebFrameLoadDelegate
+ virtual HRESULT STDMETHODCALLTYPE didFinishLoadForFrame(
+ /* [in] */ IWebView*,
+ /* [in] */ IWebFrame*) { return E_NOTIMPL; };
+
+ virtual HRESULT STDMETHODCALLTYPE windowScriptObjectAvailable(
+ /* [in] */ IWebView*,
+ /* [in] */ JSContextRef,
+ /* [in] */ JSObjectRef) { return E_NOTIMPL; };
+
+ virtual HRESULT STDMETHODCALLTYPE didStartProvisionalLoadForFrame(
+ /* [in] */ IWebView*,
+ /* [in] */ IWebFrame*) { return E_NOTIMPL; };
+
+ virtual HRESULT STDMETHODCALLTYPE didReceiveServerRedirectForProvisionalLoadForFrame(
+ /* [in] */ IWebView*,
+ /* [in] */ IWebFrame*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE didFailProvisionalLoadWithError(
+ /* [in] */ IWebView*,
+ /* [in] */ IWebError*,
+ /* [in] */ IWebFrame*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE didCommitLoadForFrame(
+ /* [in] */ IWebView*,
+ /* [in] */ IWebFrame*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE didReceiveTitle(
+ /* [in] */ IWebView*,
+ /* [in] */ BSTR,
+ /* [in] */ IWebFrame*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE didReceiveIcon(
+ /* [in] */ IWebView*,
+ /* [in] */ OLE_HANDLE,
+ /* [in] */ IWebFrame*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE didFailLoadWithError(
+ /* [in] */ IWebView*,
+ /* [in] */ IWebError*,
+ /* [in] */ IWebFrame*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE didChangeLocationWithinPageForFrame(
+ /* [in] */ IWebView*,
+ /* [in] */ IWebFrame*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE willPerformClientRedirectToURL(
+ /* [in] */ IWebView*,
+ /* [in] */ BSTR,
+ /* [in] */ double /*delaySeconds*/,
+ /* [in] */ DATE,
+ /* [in] */ IWebFrame*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE didCancelClientRedirectForFrame(
+ /* [in] */ IWebView*,
+ /* [in] */ IWebFrame*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE willCloseFrame(
+ /* [in] */ IWebView*,
+ /* [in] */ IWebFrame*) { return E_NOTIMPL; }
+
+ // IWebUIDelegate
+ virtual HRESULT STDMETHODCALLTYPE createWebViewWithRequest(
+ /* [in] */ IWebView*,
+ /* [in] */ IWebURLRequest*,
+ /* [retval][out] */ IWebView**) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewShow(
+ /* [in] */ IWebView*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewClose(
+ /* [in] */ IWebView*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewFocus(
+ /* [in] */ IWebView*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewUnfocus(
+ /* [in] */ IWebView*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewFirstResponder(
+ /* [in] */ IWebView*,
+ /* [retval][out] */ OLE_HANDLE*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE makeFirstResponder(
+ /* [in] */ IWebView*,
+ /* [in] */ OLE_HANDLE) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE setStatusText(
+ /* [in] */ IWebView*,
+ /* [in] */ BSTR) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewStatusText(
+ /* [in] */ IWebView*,
+ /* [retval][out] */ BSTR*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewAreToolbarsVisible(
+ /* [in] */ IWebView*,
+ /* [retval][out] */ BOOL*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE setToolbarsVisible(
+ /* [in] */ IWebView*,
+ /* [in] */ BOOL) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewIsStatusBarVisible(
+ /* [in] */ IWebView*,
+ /* [retval][out] */ BOOL*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE setStatusBarVisible(
+ /* [in] */ IWebView*,
+ /* [in] */ BOOL) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewIsResizable(
+ /* [in] */ IWebView*,
+ /* [retval][out] */ BOOL*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE setResizable(
+ /* [in] */ IWebView*,
+ /* [in] */ BOOL) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE setFrame(
+ /* [in] */ IWebView*,
+ /* [in] */ RECT*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewFrame(
+ /* [in] */ IWebView*,
+ /* [retval][out] */ RECT*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE setContentRect(
+ /* [in] */ IWebView*,
+ /* [in] */ RECT*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewContentRect(
+ /* [in] */ IWebView*,
+ /* [retval][out] */ RECT*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE runJavaScriptAlertPanelWithMessage(
+ /* [in] */ IWebView*,
+ /* [in] */ BSTR) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE runJavaScriptConfirmPanelWithMessage(
+ /* [in] */ IWebView*,
+ /* [in] */ BSTR,
+ /* [retval][out] */ BOOL*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE runJavaScriptTextInputPanelWithPrompt(
+ /* [in] */ IWebView*,
+ /* [in] */ BSTR /*message*/,
+ /* [in] */ BSTR /*defaultText*/,
+ /* [retval][out] */ BSTR*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE runBeforeUnloadConfirmPanelWithMessage(
+ /* [in] */ IWebView*,
+ /* [in] */ BSTR /*message*/,
+ /* [in] */ IWebFrame* /*initiatedByFrame*/,
+ /* [retval][out] */ BOOL*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE runOpenPanelForFileButtonWithResultListener(
+ /* [in] */ IWebView*,
+ /* [in] */ IWebOpenPanelResultListener*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE mouseDidMoveOverElement(
+ /* [in] */ IWebView*,
+ /* [in] */ IPropertyBag*,
+ /* [in] */ UINT /*modifierFlags*/) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE contextMenuItemsForElement(
+ /* [in] */ IWebView*,
+ /* [in] */ IPropertyBag*,
+ /* [in] */ OLE_HANDLE,
+ /* [retval][out] */ OLE_HANDLE*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE validateUserInterfaceItem(
+ /* [in] */ IWebView*,
+ /* [in] */ UINT,
+ /* [in] */ BOOL,
+ /* [retval][out] */ BOOL*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE shouldPerformAction(
+ /* [in] */ IWebView*,
+ /* [in] */ UINT /*itemCommandID*/,
+ /* [in] */ UINT /*sender*/) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE dragDestinationActionMaskForDraggingInfo(
+ /* [in] */ IWebView*,
+ /* [in] */ IDataObject*,
+ /* [retval][out] */ WebDragDestinationAction*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE willPerformDragDestinationAction(
+ /* [in] */ IWebView*,
+ /* [in] */ WebDragDestinationAction,
+ /* [in] */ IDataObject*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE dragSourceActionMaskForPoint(
+ /* [in] */ IWebView*,
+ /* [in] */ LPPOINT,
+ /* [retval][out] */ WebDragSourceAction*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE willPerformDragSourceAction(
+ /* [in] */ IWebView*,
+ /* [in] */ WebDragSourceAction,
+ /* [in] */ LPPOINT,
+ /* [in] */ IDataObject*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE contextMenuItemSelected(
+ /* [in] */ IWebView*,
+ /* [in] */ void* /*item*/,
+ /* [in] */ IPropertyBag*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE hasCustomMenuImplementation(
+ /* [retval][out] */ BOOL*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE trackCustomPopupMenu(
+ /* [in] */ IWebView*,
+ /* [in] */ OLE_HANDLE,
+ /* [in] */ LPPOINT) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE measureCustomMenuItem(
+ /* [in] */ IWebView*,
+ /* [in] */ void* /*measureItem*/) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE drawCustomMenuItem(
+ /* [in] */ IWebView*,
+ /* [in] */ void* /*drawItem*/) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE addCustomMenuDrawingData(
+ /* [in] */ IWebView*,
+ /* [in] */ OLE_HANDLE) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE cleanUpCustomMenuDrawingData(
+ /* [in] */ IWebView*,
+ /* [in] */ OLE_HANDLE) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE canTakeFocus(
+ /* [in] */ IWebView*,
+ /* [in] */ BOOL /*forward*/,
+ /* [out] */ BOOL*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE takeFocus(
+ /* [in] */ IWebView*,
+ /* [in] */ BOOL /*forward*/) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE registerUndoWithTarget(
+ /* [in] */ IWebUndoTarget*,
+ /* [in] */ BSTR /*actionName*/,
+ /* [in] */ IUnknown* /*actionArg*/) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE removeAllActionsWithTarget(
+ /* [in] */ IWebUndoTarget*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE setActionTitle(
+ /* [in] */ BSTR) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE undo( void) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE redo( void) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE canUndo(
+ /* [retval][out] */ BOOL*) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE canRedo(
+ /* [retval][out] */ BOOL*) { return E_NOTIMPL; }
+};
+
+#endif //BaseDelegate_H
diff --git a/WebKitTools/Drosera/win/DebuggerClient.cpp b/WebKitTools/Drosera/win/DebuggerClient.cpp
new file mode 100644
index 0000000..77b689c
--- /dev/null
+++ b/WebKitTools/Drosera/win/DebuggerClient.cpp
@@ -0,0 +1,341 @@
+/*
+ * 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 "DebuggerClient.h"
+
+#include "DebuggerDocument.h"
+#include "Drosera.h"
+#include "ServerConnection.h"
+
+#include <WebKit/ForEachCoClass.h>
+#include <WebKit/WebKit.h>
+#include <JavaScriptCore/JSContextRef.h>
+
+static LPCTSTR kConsoleTitle = _T("Console");
+static LPCTSTR kConsoleClassName = _T("DroseraConsoleWindowClass");
+
+static LRESULT CALLBACK consoleWndProc(HWND, UINT, WPARAM, LPARAM);
+
+void registerConsoleClass(HINSTANCE hInstance)
+{
+ static bool haveRegisteredWindowClass = false;
+
+ if (haveRegisteredWindowClass) {
+ haveRegisteredWindowClass = true;
+ return;
+ }
+
+ WNDCLASSEX wcex;
+
+ wcex.cbSize = sizeof(WNDCLASSEX);
+
+ wcex.style = 0;
+ wcex.lpfnWndProc = consoleWndProc;
+ wcex.cbClsExtra = 0;
+ wcex.cbWndExtra = sizeof(DebuggerClient*);
+ wcex.hInstance = hInstance;
+ wcex.hIcon = 0;
+ wcex.hCursor = LoadCursor(0, IDC_ARROW);
+ wcex.hbrBackground = 0;
+ wcex.lpszMenuName = 0;
+ wcex.lpszClassName = kConsoleClassName;
+ wcex.hIconSm = 0;
+
+ RegisterClassEx(&wcex);
+}
+
+static LRESULT CALLBACK consoleWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ LONG_PTR longPtr = GetWindowLongPtr(hWnd, 0);
+ DebuggerClient* client = reinterpret_cast<DebuggerClient*>(longPtr);
+
+ switch (message) {
+ case WM_SIZE:
+ if (!client)
+ return 0;
+ return client->onSize(wParam, lParam);
+ case WM_PAINT: {
+ PAINTSTRUCT ps;
+ BeginPaint(hWnd, &ps);
+ EndPaint(hWnd, &ps);
+ break;
+ }
+ default:
+ return DefWindowProc(hWnd, message, wParam, lParam);
+ }
+
+ return 0;
+}
+
+LRESULT DebuggerClient::onSize(WPARAM, LPARAM)
+{
+ if (!m_webViewPrivate)
+ return 0;
+
+ RECT clientRect = {0};
+ if (!GetClientRect(m_consoleWindow, &clientRect))
+ return 0;
+
+ HWND viewWindow;
+ if (SUCCEEDED(m_webViewPrivate->viewWindow(reinterpret_cast<OLE_HANDLE*>(&viewWindow))))
+ SetWindowPos(viewWindow, 0, clientRect.left, clientRect.top, clientRect.right - clientRect.left, clientRect.bottom - clientRect.top, SWP_NOZORDER);
+
+ return 0;
+}
+
+DebuggerClient::DebuggerClient()
+ : m_webViewLoaded(false)
+ , m_debuggerDocument(new DebuggerDocument(new ServerConnection()))
+ , m_globalContext(0)
+{
+}
+
+DebuggerClient::~DebuggerClient()
+{
+ if (m_globalContext)
+ JSGlobalContextRelease(m_globalContext);
+}
+
+// IUnknown ------------------------------
+HRESULT STDMETHODCALLTYPE DebuggerClient::QueryInterface(REFIID riid, void** ppvObject)
+{
+ *ppvObject = 0;
+ if (IsEqualGUID(riid, IID_IUnknown))
+ *ppvObject = this;
+ else if (IsEqualGUID(riid, IID_IWebFrameLoadDelegate))
+ *ppvObject = static_cast<IWebFrameLoadDelegate*>(this);
+ else if (IsEqualGUID(riid, IID_IWebUIDelegate))
+ *ppvObject = static_cast<IWebUIDelegate*>(this);
+ else
+ return E_NOINTERFACE;
+
+ AddRef();
+ return S_OK;
+}
+
+ULONG STDMETHODCALLTYPE DebuggerClient::AddRef()
+{
+ // COM ref-counting isn't useful to us because we're in charge of the lifetime of the WebView.
+ return 1;
+}
+
+ULONG STDMETHODCALLTYPE DebuggerClient::Release()
+{
+ // COM ref-counting isn't useful to us because we're in charge of the lifetime of the WebView.
+ return 1;
+}
+
+// IWebFrameLoadDelegate ------------------------------
+HRESULT STDMETHODCALLTYPE DebuggerClient::didFinishLoadForFrame(
+ /* [in] */ IWebView* webView,
+ /* [in] */ IWebFrame*)
+{
+ HRESULT ret = S_OK;
+
+ m_webViewLoaded = true;
+
+ COMPtr<IWebFrame> mainFrame;
+ ret = webView->mainFrame(&mainFrame);
+ if (FAILED(ret))
+ return ret;
+
+ if (!m_globalContext) {
+ JSGlobalContextRef context = mainFrame->globalContext();
+ if (!context)
+ return E_FAIL;
+
+ m_globalContext = JSGlobalContextRetain(context);
+ }
+
+ if (serverConnected())
+ m_debuggerDocument->server()->setGlobalContext(m_globalContext);
+
+ return ret;
+}
+
+HRESULT STDMETHODCALLTYPE DebuggerClient::windowScriptObjectAvailable(
+ /* [in] */ IWebView*,
+ /* [in] */ JSContextRef context,
+ /* [in] */ JSObjectRef windowObject)
+{
+ JSValueRef exception = 0;
+ if (m_debuggerDocument)
+ m_debuggerDocument->windowScriptObjectAvailable(context, windowObject, &exception);
+
+ if (exception)
+ return E_FAIL;
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE DebuggerClient::createWebViewWithRequest(
+ /* [in] */ IWebView*,
+ /* [in] */ IWebURLRequest* request,
+ /* [retval][out] */ IWebView** newWebView)
+{
+ HRESULT ret = S_OK;
+
+ if (!newWebView)
+ return E_POINTER;
+
+ *newWebView = 0;
+
+ HINSTANCE instance = Drosera::getInst();
+
+ registerConsoleClass(instance);
+
+ m_consoleWindow = CreateWindow(kConsoleClassName, kConsoleTitle, WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT, 0, 500, 350, 0, 0, instance, 0);
+
+ if (!m_consoleWindow)
+ return HRESULT_FROM_WIN32(GetLastError());
+
+ SetLastError(0);
+ SetWindowLongPtr(m_consoleWindow, 0, reinterpret_cast<LONG_PTR>(this));
+ ret = HRESULT_FROM_WIN32(GetLastError());
+ if (FAILED(ret))
+ return ret;
+
+ CLSID clsid = CLSID_NULL;
+ ret = CLSIDFromProgID(PROGID(WebView), &clsid);
+ if (FAILED(ret))
+ return ret;
+
+ COMPtr<IWebView> view;
+ ret = CoCreateInstance(clsid, 0, CLSCTX_ALL, IID_IWebView, (void**)&view);
+ if (FAILED(ret))
+ return ret;
+
+ m_webViewPrivate.query(view);
+ if (!m_webViewPrivate)
+ return E_FAIL;
+
+ ret = view->setHostWindow(reinterpret_cast<OLE_HANDLE>(m_consoleWindow));
+ if (FAILED(ret))
+ return ret;
+
+ RECT clientRect = {0};
+ GetClientRect(m_consoleWindow, &clientRect);
+ ret = view->initWithFrame(clientRect, 0, 0);
+ if (FAILED(ret))
+ return ret;
+
+ ret = view->setUIDelegate(this);
+ if (FAILED(ret))
+ return ret;
+
+ ret = view->setFrameLoadDelegate(this);
+ if (FAILED(ret))
+ return ret;
+
+ if (request) {
+ BOOL requestIsEmpty = FALSE;
+ ret = request->isEmpty(&requestIsEmpty);
+ if (FAILED(ret))
+ return ret;
+
+ if (!requestIsEmpty) {
+ COMPtr<IWebFrame> mainFrame;
+ ret = view->mainFrame(&mainFrame);
+ if (FAILED(ret))
+ return ret;
+
+ ret = mainFrame->loadRequest(request);
+ if (FAILED(ret))
+ return ret;
+ }
+ }
+
+ ShowWindow(m_consoleWindow, SW_SHOW);
+ UpdateWindow(m_consoleWindow);
+
+ *newWebView = view.releaseRef();
+
+ return S_OK;
+}
+
+// IWebUIDelegate ------------------------------
+HRESULT STDMETHODCALLTYPE DebuggerClient::runJavaScriptAlertPanelWithMessage( // For debugging purposes
+ /* [in] */ IWebView*,
+ /* [in] */ BSTR message)
+{
+#ifndef NDEBUG
+ fwprintf(stderr, L"%s\n", message ? message : L"");
+#else
+ (void)message;
+#endif
+ return S_OK;
+}
+
+// Pause & Step -------------------------------
+void DebuggerClient::resume()
+{
+ DebuggerDocument::callGlobalFunction(m_globalContext, "resume", 0, 0);
+}
+
+void DebuggerClient::pause()
+{
+ DebuggerDocument::callGlobalFunction(m_globalContext, "pause", 0, 0);
+}
+
+void DebuggerClient::stepInto()
+{
+ DebuggerDocument::callGlobalFunction(m_globalContext, "stepInto", 0, 0);
+}
+
+void DebuggerClient::stepOver()
+{
+ DebuggerDocument::callGlobalFunction(m_globalContext, "stepOver", 0, 0);
+}
+
+void DebuggerClient::stepOut()
+{
+ DebuggerDocument::callGlobalFunction(m_globalContext, "stepOut", 0, 0);
+}
+
+void DebuggerClient::showConsole()
+{
+ DebuggerDocument::callGlobalFunction(m_globalContext, "showConsoleWindow", 0, 0);
+}
+
+void DebuggerClient::closeCurrentFile()
+{
+ DebuggerDocument::callGlobalFunction(m_globalContext, "closeCurrentFile", 0, 0);
+}
+
+
+// Server Connection Functions ----------------
+bool DebuggerClient::serverConnected() const
+{
+ return m_debuggerDocument->server()->serverConnected();
+}
+
+void DebuggerClient::attemptToCreateServerConnection()
+{
+ m_debuggerDocument->server()->attemptToCreateServerConnection(m_globalContext);
+}
diff --git a/WebKitTools/Drosera/win/DebuggerClient.h b/WebKitTools/Drosera/win/DebuggerClient.h
new file mode 100644
index 0000000..7297615
--- /dev/null
+++ b/WebKitTools/Drosera/win/DebuggerClient.h
@@ -0,0 +1,107 @@
+/*
+ * 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.
+ */
+
+#ifndef DebuggerClient_H
+#define DebuggerClient_H
+
+#include "BaseDelegate.h"
+
+#include <string>
+#include <WebCore/COMPtr.h>
+#include <wtf/OwnPtr.h>
+
+class DebuggerDocument;
+interface IWebView;
+interface IWebFrame;
+interface IWebViewPrivate;
+
+typedef const struct OpaqueJSContext* JSContextRef;
+typedef struct OpaqueJSValue* JSObjectRef;
+
+class DebuggerClient : public BaseDelegate {
+public:
+ DebuggerClient();
+ ~DebuggerClient();
+ explicit DebuggerClient(const std::wstring& serverName);
+
+ LRESULT DebuggerClient::onSize(WPARAM, LPARAM);
+
+ // IUnknown
+ HRESULT STDMETHODCALLTYPE QueryInterface(
+ /* [in] */ REFIID riid,
+ /* [retval][out] */ void** ppvObject);
+
+ ULONG STDMETHODCALLTYPE AddRef();
+ ULONG STDMETHODCALLTYPE Release();
+
+ // IWebFrameLoadDelegate
+ HRESULT STDMETHODCALLTYPE didFinishLoadForFrame(
+ /* [in] */ IWebView*,
+ /* [in] */ IWebFrame*);
+
+ HRESULT STDMETHODCALLTYPE windowScriptObjectAvailable(
+ /* [in] */ IWebView*,
+ /* [in] */ JSContextRef,
+ /* [in] */ JSObjectRef);
+
+ // IWebUIDelegate
+ HRESULT STDMETHODCALLTYPE runJavaScriptAlertPanelWithMessage(
+ /* [in] */ IWebView*,
+ /* [in] */ BSTR);
+
+ HRESULT STDMETHODCALLTYPE createWebViewWithRequest(
+ /* [in] */ IWebView*,
+ /* [in] */ IWebURLRequest*,
+ /* [retval][out] */ IWebView**);
+
+ bool webViewLoaded() const { return m_webViewLoaded; }
+
+ // Pause & Step
+ void resume();
+ void pause();
+ void stepInto();
+ void stepOver();
+ void stepOut();
+ void showConsole();
+ void closeCurrentFile();
+
+ // Server Connection Functions
+ bool serverConnected() const;
+ void attemptToCreateServerConnection();
+
+private:
+ bool m_webViewLoaded;
+ JSGlobalContextRef m_globalContext;
+
+ HWND m_consoleWindow;
+ COMPtr<IWebViewPrivate> m_webViewPrivate;
+
+ OwnPtr<DebuggerDocument> m_debuggerDocument;
+};
+
+#endif //DebuggerClient_H
diff --git a/WebKitTools/Drosera/win/DebuggerDocumentPlatform.cpp b/WebKitTools/Drosera/win/DebuggerDocumentPlatform.cpp
new file mode 100644
index 0000000..f23daf7
--- /dev/null
+++ b/WebKitTools/Drosera/win/DebuggerDocumentPlatform.cpp
@@ -0,0 +1,160 @@
+/*
+ * 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 "DebuggerDocument.h"
+
+#include "ServerConnection.h"
+
+#include <JavaScriptCore/JSRetainPtr.h>
+#include <JavaScriptCore/JSStringRef.h>
+#include <JavaScriptCore/JSStringRefBSTR.h>
+#include <WebKit/WebKit.h>
+
+JSValueRef JSValueRefCreateWithBSTR(JSContextRef context, BSTR string)
+{
+ JSRetainPtr<JSStringRef> jsString(Adopt, JSStringCreateWithBSTR(string));
+ return JSValueMakeString(context, jsString.get());
+}
+
+// DebuggerDocument platform specific implementations
+
+void DebuggerDocument::platformPause()
+{
+ m_server->pause();
+}
+
+void DebuggerDocument::platformResume()
+{
+ m_server->resume();
+}
+
+void DebuggerDocument::platformStepInto()
+{
+ m_server->stepInto();
+}
+
+JSValueRef DebuggerDocument::platformEvaluateScript(JSContextRef context, JSStringRef script, int callFrame)
+{
+ HRESULT ret = S_OK;
+
+ COMPtr<IWebScriptCallFrame> cframe = m_server->getCallerFrame(callFrame);
+ if (!cframe)
+ return JSValueMakeUndefined(context);
+
+ // Convert script to BSTR
+ BSTR scriptBSTR = JSStringCopyBSTR(script);
+ BSTR value = 0;
+ ret = cframe->stringByEvaluatingJavaScriptFromString(scriptBSTR, &value);
+ SysFreeString(scriptBSTR);
+ if (FAILED(ret)) {
+ SysFreeString(value);
+ return JSValueMakeUndefined(context);
+ }
+
+ JSValueRef returnValue = JSValueRefCreateWithBSTR(context, value);
+ SysFreeString(value);
+ return returnValue;
+
+}
+
+void DebuggerDocument::getPlatformCurrentFunctionStack(JSContextRef context, Vector<JSValueRef>& currentStack)
+{
+ COMPtr<IWebScriptCallFrame> frame = m_server->currentFrame();
+ while (frame) {
+ COMPtr<IWebScriptCallFrame> caller;
+ BSTR function = 0;
+ if (FAILED(frame->functionName(&function)))
+ return;
+
+ if (FAILED(frame->caller(&caller)))
+ return;
+
+ if (!function) {
+ if (caller)
+ function = SysAllocString(L"(anonymous function)");
+ else
+ function = SysAllocString(L"(global scope)");
+ }
+
+ currentStack.append(JSValueRefCreateWithBSTR(context, function));
+ SysFreeString(function);
+
+ frame = caller;
+ }
+}
+
+void DebuggerDocument::getPlatformLocalScopeVariableNamesForCallFrame(JSContextRef context, int callFrame, Vector<JSValueRef>& variableNames)
+{
+ COMPtr<IWebScriptCallFrame> cframe = m_server->getCallerFrame(callFrame);
+ if (!cframe)
+ return;
+
+ VARIANT var;
+ VariantInit(&var);
+
+ COMPtr<IEnumVARIANT> localScopeVariableNames;
+ if (FAILED(cframe->variableNames(&localScopeVariableNames)))
+ return;
+
+ while (localScopeVariableNames->Next(1, &var, 0) == S_OK) {
+ ASSERT(V_VT(&var) == VT_BSTR);
+ BSTR variableName;
+
+ variableName = V_BSTR(&var);
+ variableNames.append(JSValueRefCreateWithBSTR(context, variableName));
+
+ SysFreeString(variableName);
+ VariantClear(&var);
+ }
+}
+
+JSValueRef DebuggerDocument::platformValueForScopeVariableNamed(JSContextRef context, JSStringRef key, int callFrame)
+{
+ COMPtr<IWebScriptCallFrame> cframe = m_server->getCallerFrame(callFrame);
+ if (!cframe)
+ return JSValueMakeUndefined(context);
+
+ BSTR bstrKey = JSStringCopyBSTR(key);
+
+ BSTR variableValue;
+ HRESULT hr = cframe->valueForVariable(bstrKey, &variableValue);
+ SysFreeString(bstrKey);
+ if (FAILED(hr))
+ return JSValueMakeUndefined(context);
+
+ JSValueRef returnValue = JSValueRefCreateWithBSTR(context, variableValue);
+ SysFreeString(variableValue);
+
+ return returnValue;
+}
+
+
+void DebuggerDocument::platformLog(JSStringRef msg)
+{
+ printf("%S\n", JSStringGetCharactersPtr(msg));
+}
diff --git a/WebKitTools/Drosera/win/Drosera.cpp b/WebKitTools/Drosera/win/Drosera.cpp
new file mode 100644
index 0000000..820054f
--- /dev/null
+++ b/WebKitTools/Drosera/win/Drosera.cpp
@@ -0,0 +1,392 @@
+/*
+ * 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 "Drosera.h"
+
+#include "DebuggerClient.h"
+#include "DebuggerDocument.h"
+#include "resource.h"
+#include "ServerConnection.h"
+
+#include <JavaScriptCore/JSStringRef.h>
+#include <WebKit/ForEachCoClass.h>
+#include <WebKit/WebKit.h>
+#include <wtf/RetainPtr.h>
+
+const unsigned MAX_LOADSTRING = 100;
+
+TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
+TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
+
+static LPCTSTR s_DroseraPointerProp = TEXT("DroseraPointer");
+static HINSTANCE hInst;
+
+BSTR cfStringToBSTR(CFStringRef cfstr);
+
+void registerDroseraClass(HINSTANCE hInstance);
+LRESULT CALLBACK droseraWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK aboutWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
+
+HINSTANCE Drosera::getInst() { return hInst; }
+void Drosera::setInst(HINSTANCE in) { hInst = in; }
+void launchConsoleWindow();
+
+extern "C" __declspec(dllimport) HANDLE* __pioinfo;
+
+int APIENTRY _tWinMain(HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPTSTR lpCmdLine,
+ int nCmdShow)
+{
+ UNREFERENCED_PARAMETER(hPrevInstance);
+ UNREFERENCED_PARAMETER(lpCmdLine);
+
+ MSG msg;
+
+#ifndef NDEBUG
+ launchConsoleWindow();
+#endif
+
+ Drosera drosera;
+
+ HRESULT ret = drosera.init(hInstance, nCmdShow);
+ if (FAILED(ret))
+ return ret;
+
+ HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_DROSERA));
+
+ // Main message loop:
+ while (GetMessage(&msg, 0, 0, 0)) {
+ if (!drosera.serverConnected())
+ drosera.attemptToCreateServerConnection();
+
+ if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+
+ return static_cast<int>(msg.wParam);
+}
+
+void launchConsoleWindow()
+{
+ if (AllocConsole()) {
+ // MSVCRT exports __pioinfo which is an array of ioinfo handles. the first three are stdout, stdin, and stderr
+ // the first pointer in the ioinfo object is the kernel handle for the console, so we can simplify the expression
+ // to just deref the exported symbol, setting it to the newly allocated console handle.
+ *__pioinfo = GetStdHandle(STD_OUTPUT_HANDLE);
+ // When an app is created without a console, stdout, stderr and stdin are all invalid handles (i.e. negative)
+ // Since we've introduced new handles, we can reset their file index - which is the index into the ioinfo array.
+ // This hooks up the standard cruntime APIS to the new console, allowing a functional output. As for input YMMV.
+ stdout->_file = 0;
+ stderr->_file = 0;
+ }
+}
+
+////////////////// Setup Windows Specific Interface //////////////////
+
+void registerDroseraClass(HINSTANCE hInstance)
+{
+ WNDCLASSEX wcex;
+
+ wcex.cbSize = sizeof(WNDCLASSEX);
+
+ wcex.style = CS_HREDRAW | CS_VREDRAW;
+ wcex.lpfnWndProc = ::droseraWndProc;
+ wcex.cbClsExtra = 0;
+ wcex.cbWndExtra = sizeof(Drosera*);
+ wcex.hInstance = hInstance;
+ wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_DROSERA));
+ wcex.hCursor = LoadCursor(0, IDC_ARROW);
+ wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
+ wcex.lpszMenuName = MAKEINTRESOURCE(IDC_DROSERA);
+ wcex.lpszClassName = szWindowClass;
+ wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
+
+ RegisterClassEx(&wcex);
+}
+
+//Processes messages for the main window.
+LRESULT CALLBACK droseraWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ PAINTSTRUCT ps;
+ HDC hdc;
+
+ LONG_PTR longPtr = GetWindowLongPtr(hWnd, 0);
+ Drosera* drosera = reinterpret_cast<Drosera*>(longPtr);
+
+ switch (message) {
+ case WM_COMMAND:
+ return drosera->handleCommand(hWnd, message, wParam, lParam);
+ break;
+ case WM_SIZE:
+ if (!drosera)
+ return 0;
+ return drosera->webViewLoaded() ? drosera->onSize(wParam, lParam) : 0;
+ case WM_PAINT:
+ hdc = BeginPaint(hWnd, &ps);
+ EndPaint(hWnd, &ps);
+ break;
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ break;
+ default:
+ return DefWindowProc(hWnd, message, wParam, lParam);
+ }
+
+ return 0;
+}
+
+LRESULT CALLBACK Drosera::handleCommand(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ int wmId = LOWORD(wParam);
+ switch (wmId) {
+ case ID_DEBUG_CONTINUE:
+ m_debuggerClient->resume();
+ break;
+ case ID_DEBUG_PAUSE:
+ m_debuggerClient->pause();
+ break;
+ case ID_DEBUG_STEPINTO:
+ m_debuggerClient->stepInto();
+ break;
+ case ID_DEBUG_STEPOVER:
+ m_debuggerClient->stepOver();
+ break;
+ case ID_DEBUG_STEPOUT:
+ m_debuggerClient->stepOut();
+ break;
+ case ID_DEBUG_SHOWCONSOLE:
+ m_debuggerClient->showConsole();
+ break;
+ case ID_HELP_ABOUT:
+ DialogBox(Drosera::getInst(), MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, ::aboutWndProc);
+ break;
+ case ID_FILE_EXIT:
+ DestroyWindow(hWnd);
+ break;
+ default:
+ return DefWindowProc(hWnd, message, wParam, lParam);
+ }
+
+ return 0;
+}
+
+// Message handler for about box.
+INT_PTR CALLBACK aboutWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ UNREFERENCED_PARAMETER(lParam);
+ switch (message) {
+ case WM_INITDIALOG:
+ return (INT_PTR)TRUE;
+
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) {
+ EndDialog(hDlg, LOWORD(wParam));
+ return (INT_PTR)TRUE;
+ }
+ break;
+ }
+ return (INT_PTR)FALSE;
+}
+
+////////////////// End Setup Windows Specific Interface //////////////////
+
+Drosera::Drosera()
+ : m_hWnd(0)
+ , m_debuggerClient(new DebuggerClient())
+{
+}
+
+HRESULT Drosera::init(HINSTANCE hInstance, int nCmdShow)
+{
+ HRESULT ret = initUI(hInstance, nCmdShow);
+ if (FAILED(ret))
+ return ret;
+
+ ret = attach();
+ return ret;
+}
+
+
+HRESULT Drosera::initUI(HINSTANCE hInstance, int nCmdShow)
+{
+ // Initialize global strings
+ LoadString(hInstance, IDS_APP_TITLE, szTitle, ARRAYSIZE(szTitle));
+ LoadString(hInstance, IDC_DROSERA, szWindowClass, ARRAYSIZE(szWindowClass));
+ registerDroseraClass(hInstance);
+
+ Drosera::setInst(hInstance); // Store instance handle in our local variable
+
+ m_hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 0, 0, hInstance, 0);
+
+ if (!m_hWnd)
+ return HRESULT_FROM_WIN32(GetLastError());
+
+ SetLastError(0);
+ SetWindowLongPtr(m_hWnd, 0, reinterpret_cast<LONG_PTR>(this));
+ HRESULT ret = HRESULT_FROM_WIN32(GetLastError());
+ if (FAILED(ret))
+ return ret;
+
+ CLSID clsid = CLSID_NULL;
+ ret = CLSIDFromProgID(PROGID(WebView), &clsid);
+ if (FAILED(ret))
+ return ret;
+
+ ret = CoCreateInstance(clsid, 0, CLSCTX_ALL, IID_IWebView, (void**)&m_webView);
+ if (FAILED(ret))
+ return ret;
+
+ m_webViewPrivate.query(m_webView.get());
+ if (!m_webViewPrivate)
+ return E_FAIL;
+
+ ret = m_webView->setHostWindow(reinterpret_cast<OLE_HANDLE>(m_hWnd));
+ if (FAILED(ret))
+ return ret;
+
+ RECT clientRect = {0};
+ ::GetClientRect(m_hWnd, &clientRect);
+ ret = m_webView->initWithFrame(clientRect, 0, 0);
+ if (FAILED(ret))
+ return ret;
+
+ HWND viewWindow;
+ ret = m_webViewPrivate->viewWindow(reinterpret_cast<OLE_HANDLE*>(&viewWindow));
+ if (FAILED(ret))
+ return ret;
+
+ SetProp(viewWindow, s_DroseraPointerProp, (HANDLE)this);
+
+ // FIXME: Implement window size/position save/restore
+ ShowWindow(m_hWnd, nCmdShow);
+ UpdateWindow(m_hWnd);
+
+ return ret;
+}
+
+LRESULT Drosera::onSize(WPARAM, LPARAM)
+{
+ if (!m_webViewPrivate)
+ return 0;
+
+ RECT clientRect = {0};
+ ::GetClientRect(m_hWnd, &clientRect);
+
+ HWND viewWindow;
+ if (SUCCEEDED(m_webViewPrivate->viewWindow(reinterpret_cast<OLE_HANDLE*>(&viewWindow))))
+ // FIXME should this be the height-command bars height?
+ ::SetWindowPos(viewWindow, 0, clientRect.left, clientRect.top, clientRect.right - clientRect.left, clientRect.bottom - clientRect.top, SWP_NOZORDER);
+
+ return 0;
+}
+
+bool Drosera::webViewLoaded() const
+{
+ return m_debuggerClient->webViewLoaded();
+}
+
+// Server Detection Callbacks
+
+HRESULT Drosera::attach()
+{
+ // Get selected server
+ HRESULT ret = m_webView->setFrameLoadDelegate(m_debuggerClient.get());
+ if (FAILED(ret))
+ return ret;
+
+ ret = m_webView->setUIDelegate(m_debuggerClient.get());
+ if (FAILED(ret))
+ return ret;
+
+ CLSID clsid = CLSID_NULL;
+ ret = CLSIDFromProgID(PROGID(WebMutableURLRequest), &clsid);
+ if (FAILED(ret))
+ return ret;
+
+ COMPtr<IWebMutableURLRequest> request;
+ ret = CoCreateInstance(clsid, 0, CLSCTX_ALL, IID_IWebMutableURLRequest, (void**)&request);
+ if (FAILED(ret))
+ return ret;
+
+ RetainPtr<CFURLRef> htmlURLRef(AdoptCF, ::CFBundleCopyResourceURL(::CFBundleGetBundleWithIdentifier(CFSTR("org.webkit.drosera")), CFSTR("debugger"), CFSTR("html"), CFSTR("Drosera")));
+ if (!htmlURLRef)
+ return E_FAIL;
+
+ CFStringRef urlStringRef = ::CFURLGetString(htmlURLRef.get());
+ BSTR tempStr = cfStringToBSTR(urlStringRef); // Both initWithRUL and SysFreeString can handle 0.
+ ret = request->initWithURL(tempStr, WebURLRequestUseProtocolCachePolicy, 60);
+ SysFreeString(tempStr);
+ if (FAILED(ret))
+ return ret;
+
+ COMPtr<IWebFrame> mainFrame;
+ ret = m_webView->mainFrame(&mainFrame);
+ if (FAILED(ret))
+ return ret;
+
+ ret = mainFrame->loadRequest(request.get());
+ if (FAILED(ret))
+ return ret;
+
+ return ret;
+}
+
+BSTR cfStringToBSTR(CFStringRef cfstr)
+{
+ if (!cfstr)
+ return 0;
+
+ const UniChar* uniChars = CFStringGetCharactersPtr(cfstr);
+ if (uniChars)
+ return SysAllocStringLen((LPCTSTR)uniChars, CFStringGetLength(cfstr));
+
+ CFIndex length = CFStringGetLength(cfstr);
+ BSTR bstr = SysAllocStringLen(0, length);
+ CFStringGetCharacters(cfstr, CFRangeMake(0, length), (UniChar*)bstr);
+ bstr[length] = 0;
+
+ return bstr;
+}
+
+// Server Connection Functions
+
+bool Drosera::serverConnected() const
+{
+ return m_debuggerClient->serverConnected();
+}
+
+void Drosera::attemptToCreateServerConnection()
+{
+ m_debuggerClient->attemptToCreateServerConnection();
+}
+
diff --git a/WebKitTools/Drosera/win/Drosera.h b/WebKitTools/Drosera/win/Drosera.h
new file mode 100644
index 0000000..a73c7f7
--- /dev/null
+++ b/WebKitTools/Drosera/win/Drosera.h
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+#ifndef Drosera_H
+#define Drosera_H
+
+#include "DebuggerDocument.h"
+
+#include <WebCore/COMPtr.h>
+#include <wtf/OwnPtr.h>
+
+class DebuggerClient;
+interface IWebView;
+interface IWebViewPrivate;
+
+class Drosera {
+public:
+ Drosera();
+
+ static HINSTANCE getInst();
+ static void setInst(HINSTANCE);
+
+ HRESULT init(HINSTANCE hInstance, int nCmdShow);
+ LRESULT onSize(WPARAM, LPARAM);
+ LRESULT CALLBACK handleCommand(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
+
+ bool webViewLoaded() const;
+
+ // Server connection functions
+ bool serverConnected() const;
+ void attemptToCreateServerConnection();
+
+private:
+ HRESULT initUI(HINSTANCE hInstance, int nCmdShow);
+ HRESULT attach();
+
+ HWND m_hWnd;
+
+ COMPtr<IWebView> m_webView;
+ COMPtr<IWebViewPrivate> m_webViewPrivate;
+
+ OwnPtr<DebuggerClient> m_debuggerClient;
+};
+
+#endif //Drosera_H
diff --git a/WebKitTools/Drosera/win/Drosera.vcproj/Drosera.rc b/WebKitTools/Drosera/win/Drosera.vcproj/Drosera.rc
new file mode 100755
index 0000000..6f8a8c8
--- /dev/null
+++ b/WebKitTools/Drosera/win/Drosera.vcproj/Drosera.rc
@@ -0,0 +1,196 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+#ifndef APSTUDIO_INVOKED
+#include "autoversion.h"
+#endif
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#define APSTUDIO_HIDDEN_SYMBOLS
+#include "windows.h"
+#undef APSTUDIO_HIDDEN_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_DROSERA ICON "Drosera.ico"
+IDI_SMALL ICON "small.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDC_DROSERA MENU
+BEGIN
+ POPUP "&File"
+ BEGIN
+ MENUITEM "Close Current File", ID_FILE_CLOSECURRENTFILE
+ MENUITEM "Exit", ID_FILE_EXIT
+ END
+ POPUP "Edit"
+ BEGIN
+ MENUITEM "Undo", ID_EDIT_UNDO
+ MENUITEM "Redo", ID_EDIT_REDO
+ MENUITEM SEPARATOR
+ MENUITEM "Cut", ID_EDIT_CUT
+ MENUITEM "Copy", ID_EDIT_COPY
+ MENUITEM "Paste", ID_EDIT_PASTE
+ MENUITEM "Select All", ID_EDIT_SELECTALL
+ MENUITEM SEPARATOR
+ POPUP "Find"
+ BEGIN
+ MENUITEM "Find", ID_FIND_FIND
+ MENUITEM "Find Next", ID_FIND_FINDNEXT
+ MENUITEM "Find Previous", ID_FIND_FINDPREVIOUS
+ MENUITEM "Use Selection for Find", ID_FIND_USESELECTIONFORFIND
+ MENUITEM "Jump to Selection", ID_FIND_JUMPTOSELECTION
+ END
+ MENUITEM SEPARATOR
+ MENUITEM "Special Characters", ID_EDIT_SPECIALCHARACTERS
+ END
+ POPUP "Debug"
+ BEGIN
+ MENUITEM "Show Console", ID_DEBUG_SHOWCONSOLE
+ MENUITEM SEPARATOR
+ MENUITEM "Continue", ID_DEBUG_CONTINUE
+ MENUITEM "Pause", ID_DEBUG_PAUSE
+ MENUITEM "Step Into", ID_DEBUG_STEPINTO
+ MENUITEM "Step Over", ID_DEBUG_STEPOVER
+ MENUITEM "Step Out", ID_DEBUG_STEPOUT
+ END
+ MENUITEM "Window", ID_WINDOW
+ POPUP "Help"
+ BEGIN
+ MENUITEM "About", ID_HELP_ABOUT
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_ABOUTBOX DIALOGEX 0, 0, 146, 62
+STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_CAPTION | WS_SYSMENU
+CAPTION "About"
+FONT 8, "System", 0, 0, 0x0
+BEGIN
+ ICON IDI_DROSERA,IDC_MYICON,64,10,20,20
+ CTEXT "Drosera Version 1.0",IDC_STATIC,0,37,146,8,SS_NOPREFIX
+END
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
+ "#include ""windows.h""\r\n"
+ "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION __VERSION_MAJOR__,__BUILD_NUMBER_MAJOR__,__BUILD_NUMBER_MINOR__,__BUILD_NUMBER_VARIANT__
+ PRODUCTVERSION __VERSION_MAJOR__,__VERSION_MINOR__,__VERSION_TINY__,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "FileDescription", "Drosera JavaScript Debugger"
+ VALUE "FileVersion", __VERSION_TEXT__
+ VALUE "CompanyName", "Apple Inc."
+ VALUE "InternalName", "Drosera"
+ VALUE "LegalCopyright", "Copyright Apple Inc. 2006-2008"
+ VALUE "OriginalFilename", "Drosera.exe"
+ VALUE "ProductName", "Drosera"
+ VALUE "ProductVersion", __VERSION_TEXT__
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ IDS_APP_TITLE "Drosera"
+ IDC_DROSERA "DROSERA"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/WebKitTools/Drosera/win/Drosera.vcproj/Drosera.vcproj b/WebKitTools/Drosera/win/Drosera.vcproj/Drosera.vcproj
new file mode 100755
index 0000000..3f72dda
--- /dev/null
+++ b/WebKitTools/Drosera/win/Drosera.vcproj/Drosera.vcproj
@@ -0,0 +1,449 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="Drosera"
+ ProjectGUID="{91671475-2114-4D8F-A051-9A1B270F6467}"
+ RootNamespace="Drosera"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;bash &quot;$(WebKitLibrariesDir)\tools\scripts\auto-version.sh&quot; &quot;$(IntDir)&quot;&#x0D;&#x0A;"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="&quot;$(ProjectDir)&quot;;&quot;$(ProjectDir)\..&quot;;&quot;$(ProjectDir)\..\..&quot;;&quot;$(ProjectDir)\..\..\ForwardingHeaders&quot;;&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\Include&quot;;&quot;$(WebKitLibrariesDir)\Include\JavaScriptCore&quot;;&quot;$(IntDir)\include&quot;"
+ PreprocessorDefinitions="STRICT;__APPLICATION_NAME__=\&quot;$(ProjectName)\&quot;"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="DroseraPrefix.h"
+ ForcedIncludeFiles="DroseraPrefix.h"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;__APPLICATION_NAME__=\&quot;$(ProjectName)\&quot;"
+ Culture="1033"
+ AdditionalIncludeDirectories="&quot;$(IntDir)\include&quot;"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ CommandLine=""
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkLibraryDependencies="false"
+ AdditionalDependencies="CoreFoundation$(LibraryConfigSuffix).lib CoreGraphics$(LibraryConfigSuffix).lib WebKit$(WebKitDLLConfigSuffix).lib WebKitGUID$(WebKitConfigSuffix).lib WTF$(WebKitConfigSuffix).lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="&quot;$(WebKitOutputDir)\lib&quot;;&quot;$(WebKitLibrariesDir)\lib&quot;"
+ IgnoreAllDefaultLibraries="false"
+ EmbedManagedResourceFile=""
+ DelayLoadDLLs=""
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ LinkTimeCodeGeneration="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CFNetwork$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CFNetwork$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin36$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin36$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc36$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc36$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\libxml2$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\libxslt$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\pthreadVC2$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\pthreadVC2$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\SQLite3$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\SQLite3$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(OutDir)\$(ProjectName).resources&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\Info.plist&quot; &quot;$(OutDir)\$(ProjectName).resources&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(OutDir)\$(ProjectName).resources\$(ProjectName)&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\..\*.css&quot; &quot;$(OutDir)\$(ProjectName).resources\$(ProjectName)&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\..\*.html&quot; &quot;$(OutDir)\$(ProjectName).resources\$(ProjectName)&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\..\*.js&quot; &quot;$(OutDir)\$(ProjectName).resources\$(ProjectName)&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\..\Images\*&quot; &quot;$(OutDir)\$(ProjectName).resources\$(ProjectName)&quot;&#x0D;&#x0A;"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\release.vsprops"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;bash &quot;$(WebKitLibrariesDir)\tools\scripts\auto-version.sh&quot; &quot;$(IntDir)&quot;&#x0D;&#x0A;"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions="/EHsc"
+ AdditionalIncludeDirectories="&quot;$(ProjectDir)&quot;;&quot;$(ProjectDir)\..&quot;;&quot;$(ProjectDir)\..\..&quot;;&quot;$(ProjectDir)\..\..\ForwardingHeaders&quot;;&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\Include&quot;;&quot;$(WebKitLibrariesDir)\Include\JavaScriptCore&quot;;&quot;$(IntDir)\include&quot;"
+ PreprocessorDefinitions="STRICT;__APPLICATION_NAME__=\&quot;$(ProjectName)\&quot;"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="DroseraPrefix.h"
+ ForcedIncludeFiles="DroseraPrefix.h"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;__APPLICATION_NAME__=\&quot;$(ProjectName)\&quot;"
+ Culture="1033"
+ AdditionalIncludeDirectories="&quot;$(IntDir)\include&quot;"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkLibraryDependencies="false"
+ AdditionalDependencies="CoreFoundation$(LibraryConfigSuffix).lib CoreGraphics$(LibraryConfigSuffix).lib WebKit$(WebKitDLLConfigSuffix).lib WebKitGUID$(WebKitConfigSuffix).lib WTF$(WebKitConfigSuffix).lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="&quot;$(WebKitOutputDir)\lib&quot;;&quot;$(WebKitLibrariesDir)\lib&quot;"
+ DelayLoadDLLs=""
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="0"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CFNetwork$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CFNetwork$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin36$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin36$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc36$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc36$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\libxml2$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\libxslt$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\pthreadVC2$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\pthreadVC2$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\SQLite3$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\SQLite3$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(OutDir)\$(ProjectName).resources&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\Info.plist&quot; &quot;$(OutDir)\$(ProjectName).resources&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(OutDir)\$(ProjectName).resources\$(ProjectName)&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\..\*.css&quot; &quot;$(OutDir)\$(ProjectName).resources\$(ProjectName)&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\..\*.html&quot; &quot;$(OutDir)\$(ProjectName).resources\$(ProjectName)&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\..\*.js&quot; &quot;$(OutDir)\$(ProjectName).resources\$(ProjectName)&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\..\Images\*&quot; &quot;$(OutDir)\$(ProjectName).resources\$(ProjectName)&quot;&#x0D;&#x0A;"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug_Internal|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_internal.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;bash &quot;$(WebKitLibrariesDir)\tools\scripts\auto-version.sh&quot; &quot;$(IntDir)&quot;&#x0D;&#x0A;"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="&quot;$(ProjectDir)&quot;;&quot;$(ProjectDir)\..&quot;;&quot;$(ProjectDir)\..\..&quot;;&quot;$(ProjectDir)\..\..\ForwardingHeaders&quot;;&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\Include&quot;;&quot;$(WebKitLibrariesDir)\Include\JavaScriptCore&quot;;&quot;$(IntDir)\include&quot;"
+ PreprocessorDefinitions="STRICT;__APPLICATION_NAME__=\&quot;$(ProjectName)\&quot;"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="DroseraPrefix.h"
+ ForcedIncludeFiles="DroseraPrefix.h"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;__APPLICATION_NAME__=\&quot;$(ProjectName)\&quot;"
+ Culture="1033"
+ AdditionalIncludeDirectories="&quot;$(IntDir)\include&quot;"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ CommandLine=""
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkLibraryDependencies="false"
+ AdditionalDependencies="CoreFoundation$(LibraryConfigSuffix).lib CoreGraphics$(LibraryConfigSuffix).lib WebKit$(WebKitDLLConfigSuffix).lib WebKitGUID$(WebKitConfigSuffix).lib WTF$(WebKitConfigSuffix).lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="&quot;$(WebKitOutputDir)\lib&quot;;&quot;$(WebKitLibrariesDir)\lib&quot;"
+ IgnoreAllDefaultLibraries="false"
+ EmbedManagedResourceFile=""
+ DelayLoadDLLs=""
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ LinkTimeCodeGeneration="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CFNetwork$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CFNetwork$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin36$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin36$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc36$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc36$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\libxml2$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\libxslt$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\pthreadVC2$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\pthreadVC2$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\SQLite3$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\SQLite3$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(OutDir)\$(ProjectName).resources&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\Info.plist&quot; &quot;$(OutDir)\$(ProjectName).resources&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(OutDir)\$(ProjectName).resources\$(ProjectName)&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\..\*.css&quot; &quot;$(OutDir)\$(ProjectName).resources\$(ProjectName)&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\..\*.html&quot; &quot;$(OutDir)\$(ProjectName).resources\$(ProjectName)&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\..\*.js&quot; &quot;$(OutDir)\$(ProjectName).resources\$(ProjectName)&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\..\Images\*&quot; &quot;$(OutDir)\$(ProjectName).resources\$(ProjectName)&quot;&#x0D;&#x0A;"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\DebuggerClient.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\DebuggerDocument.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\DebuggerDocumentPlatform.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\Drosera.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\DroseraPrefix.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug_Internal|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\ServerConnection.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\BaseDelegate.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\config.h"
+ >
+ </File>
+ <File
+ RelativePath="..\DebuggerClient.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\DebuggerDocument.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Drosera.h"
+ >
+ </File>
+ <File
+ RelativePath="..\DroseraPrefix.h"
+ >
+ </File>
+ <File
+ RelativePath="..\ServerConnection.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ <File
+ RelativePath="..\..\Images\Drosera.ico"
+ >
+ </File>
+ <File
+ RelativePath=".\Drosera.rc"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="&quot;$(InputDir)\WTL75\include&quot;;&quot;$(IntDir)\include&quot;;&quot;$(ProjectDir)..&quot;;&quot;$(ProjectDir)..\..\Images&quot;"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="&quot;$(ProjectDir)..&quot;;&quot;$(ProjectDir)..\..\Images&quot;"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug_Internal|Win32"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="&quot;$(InputDir)\WTL75\include&quot;;&quot;$(IntDir)\include&quot;;&quot;$(ProjectDir)..&quot;;&quot;$(ProjectDir)..\..\Images&quot;"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\resource.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Images\small.ico"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="WebSource"
+ >
+ <File
+ RelativePath="..\..\breakpointEditor.html"
+ >
+ </File>
+ <File
+ RelativePath="..\..\console.css"
+ >
+ </File>
+ <File
+ RelativePath="..\..\console.html"
+ >
+ </File>
+ <File
+ RelativePath="..\..\console.js"
+ >
+ </File>
+ <File
+ RelativePath="..\..\debugger.css"
+ >
+ </File>
+ <File
+ RelativePath="..\..\debugger.html"
+ >
+ </File>
+ <File
+ RelativePath="..\..\debugger.js"
+ >
+ </File>
+ <File
+ RelativePath="..\..\viewer.css"
+ >
+ </File>
+ <File
+ RelativePath="..\..\viewer.html"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/WebKitTools/Drosera/win/DroseraPrefix.cpp b/WebKitTools/Drosera/win/DroseraPrefix.cpp
new file mode 100644
index 0000000..39d3f80
--- /dev/null
+++ b/WebKitTools/Drosera/win/DroseraPrefix.cpp
@@ -0,0 +1,29 @@
+/*
+ * 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 "DroseraPrefix.h"
diff --git a/WebKitTools/Drosera/win/DroseraPrefix.h b/WebKitTools/Drosera/win/DroseraPrefix.h
new file mode 100644
index 0000000..fe608c7
--- /dev/null
+++ b/WebKitTools/Drosera/win/DroseraPrefix.h
@@ -0,0 +1,58 @@
+/*
+ * 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 droseraPrefix_H
+#define droseraPrefix_H
+
+// Modify the following defines if you have to target a platform prior to the ones specified below.
+// Refer to MSDN for the latest info on corresponding values for different platforms.
+#ifndef WINVER // Allow use of features specific to Windows XP or later.
+#define WINVER 0x0501 // Change this to the appropriate value to target other versions of Windows.
+#endif
+
+#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later.
+#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
+#endif
+
+#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later.
+#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
+#endif
+
+#ifndef _WIN32_IE // Allow use of features specific to IE 6.0 or later.
+#define _WIN32_IE 0x0600 // Change this to the appropriate value to target other versions of IE.
+#endif
+
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+#endif
+
+#ifndef WIN32
+#define WIN32 1
+#endif
+
+#endif //droseraPrefix_H
diff --git a/WebKitTools/Drosera/win/Info.plist b/WebKitTools/Drosera/win/Info.plist
new file mode 100644
index 0000000..ce4a0f7
--- /dev/null
+++ b/WebKitTools/Drosera/win/Info.plist
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>Drosera</string>
+ <key>CFBundleIconFile</key>
+ <string>Drosera</string>
+ <key>CFBundleIdentifier</key>
+ <string>org.webkit.drosera</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>21081</string>
+ <key>NSMainNibFile</key>
+ <string>MainMenu</string>
+ <key>NSPrincipalClass</key>
+ <string>NSApplication</string>
+</dict>
+</plist>
diff --git a/WebKitTools/Drosera/win/ServerConnection.cpp b/WebKitTools/Drosera/win/ServerConnection.cpp
new file mode 100644
index 0000000..de2b416
--- /dev/null
+++ b/WebKitTools/Drosera/win/ServerConnection.cpp
@@ -0,0 +1,368 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007 Vladimir Olexa (vladimir.olexa@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.
+ */
+
+#include "config.h"
+#include "ServerConnection.h"
+
+#include "DebuggerDocument.h"
+
+#include <JavaScriptCore/JSContextRef.h>
+#include <JavaScriptCore/JSRetainPtr.h>
+#include <JavaScriptCore/JSStringRefBSTR.h>
+#include <JavaScriptCore/RetainPtr.h>
+#include <WebKit/ForEachCoClass.h>
+#include <WebKit/WebKit.h>
+
+#include <iostream>
+
+ServerConnection::ServerConnection()
+ : m_globalContext(0)
+ , m_serverConnected(false)
+{
+ OleInitialize(0);
+ attemptToCreateServerConnection();
+}
+
+ServerConnection::~ServerConnection()
+{
+ if (m_server)
+ m_server->removeListener(this);
+
+ if (m_globalContext)
+ JSGlobalContextRelease(m_globalContext);
+}
+
+void ServerConnection::attemptToCreateServerConnection(JSGlobalContextRef globalContextRef)
+{
+ COMPtr<IWebScriptDebugServer> tempServer;
+
+ CLSID clsid = CLSID_NULL;
+ if (FAILED(CLSIDFromProgID(PROGID(WebScriptDebugServer), &clsid)))
+ return;
+
+ if (FAILED(CoCreateInstance(clsid, 0, CLSCTX_LOCAL_SERVER, IID_IWebScriptDebugServer, (void**)&tempServer)))
+ return;
+
+ if (FAILED(tempServer->sharedWebScriptDebugServer(&m_server)))
+ return;
+
+ if (FAILED(m_server->addListener(this))) {
+ m_server = 0;
+ return;
+ }
+
+ m_serverConnected = true;
+
+ if (globalContextRef)
+ m_globalContext = JSGlobalContextRetain(globalContextRef);
+}
+
+void ServerConnection::setGlobalContext(JSGlobalContextRef globalContextRef)
+{
+ m_globalContext = JSGlobalContextRetain(globalContextRef);
+}
+
+// Pause & Step
+
+void ServerConnection::pause()
+{
+ if (m_server)
+ m_server->pause();
+}
+
+void ServerConnection::resume()
+{
+ if (m_server)
+ m_server->resume();
+}
+
+void ServerConnection::stepInto()
+{
+ if (m_server)
+ m_server->step();
+}
+
+// IUnknown --------------------------------------------------
+HRESULT STDMETHODCALLTYPE ServerConnection::QueryInterface(REFIID riid, void** ppvObject)
+{
+ *ppvObject = 0;
+ if (IsEqualGUID(riid, IID_IUnknown))
+ *ppvObject = this;
+ else if (IsEqualGUID(riid, IID_IWebScriptDebugListener))
+ *ppvObject = static_cast<IWebScriptDebugListener*>(this);
+ else
+ return E_NOINTERFACE;
+
+ AddRef();
+ return S_OK;
+}
+
+ULONG STDMETHODCALLTYPE ServerConnection::AddRef(void)
+{
+ // COM ref-counting isn't useful to us because we're in charge of the lifetime of the WebView.
+ return 1;
+}
+
+ULONG STDMETHODCALLTYPE ServerConnection::Release(void)
+{
+ // COM ref-counting isn't useful to us because we're in charge of the lifetime of the WebView.
+ return 1;
+}
+// IWebScriptDebugListener -----------------------------------
+HRESULT STDMETHODCALLTYPE ServerConnection::didLoadMainResourceForDataSource(
+ /* [in] */ IWebView*,
+ /* [in] */ IWebDataSource* dataSource)
+{
+ HRESULT ret = S_OK;
+ if (!m_globalContext || !dataSource)
+ return ret;
+
+ // Get document source
+ COMPtr<IWebDocumentRepresentation> rep;
+ ret = dataSource->representation(&rep);
+ if (FAILED(ret))
+ return ret;
+
+ BOOL canProvideDocumentSource = FALSE;
+ ret = rep->canProvideDocumentSource(&canProvideDocumentSource);
+ if (FAILED(ret))
+ return ret;
+
+ BSTR documentSource = 0;
+ if (canProvideDocumentSource)
+ ret = rep->documentSource(&documentSource);
+
+ if (FAILED(ret) || !documentSource)
+ return ret;
+
+ JSRetainPtr<JSStringRef> documentSourceJS(Adopt, JSStringCreateWithBSTR(documentSource));
+ SysFreeString(documentSource);
+
+ // Get URL
+ COMPtr<IWebURLResponse> response;
+ ret = dataSource->response(&response);
+ if (FAILED(ret))
+ return ret;
+
+ BSTR url = 0;
+ ret = response->URL(&url);
+ if (FAILED(ret))
+ return ret;
+
+ JSRetainPtr<JSStringRef> urlJS(Adopt, JSStringCreateWithBSTR(url));
+ SysFreeString(url);
+
+ DebuggerDocument::updateFileSource(m_globalContext, documentSourceJS.get(), urlJS.get());
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE ServerConnection::didParseSource(
+ /* [in] */ IWebView*,
+ /* [in] */ BSTR sourceCode,
+ /* [in] */ UINT baseLineNumber,
+ /* [in] */ BSTR url,
+ /* [in] */ int sourceID,
+ /* [in] */ IWebFrame* webFrame)
+{
+ HRESULT ret = S_OK;
+ if (!m_globalContext || !sourceCode)
+ return ret;
+
+ COMPtr<IWebDataSource> dataSource;
+ ret = webFrame->dataSource(&dataSource);
+ if (FAILED(ret))
+ return ret;
+
+ COMPtr<IWebURLResponse> response;
+ ret = dataSource->response(&response);
+ if (FAILED(ret))
+ return ret;
+
+ BSTR responseURL;
+ ret = response->URL(&responseURL);
+ if (FAILED(ret))
+ return ret;
+
+ BSTR documentSource = 0;
+ if (!url || !wcscmp(responseURL, url)) {
+ COMPtr<IWebDocumentRepresentation> rep;
+ ret = dataSource->representation(&rep);
+ if (FAILED(ret))
+ return ret;
+
+ BOOL canProvideDocumentSource;
+ rep->canProvideDocumentSource(&canProvideDocumentSource);
+ if (FAILED(ret))
+ return ret;
+
+ if (canProvideDocumentSource) {
+ ret = rep->documentSource(&documentSource);
+ if (FAILED(ret))
+ return ret;
+ }
+
+ if (!url) {
+ ret = response->URL(&url);
+ if (FAILED(ret))
+ return ret;
+ }
+ }
+ SysFreeString(responseURL);
+
+ JSRetainPtr<JSStringRef> sourceJS(Adopt, JSStringCreateWithBSTR(sourceCode));
+ JSRetainPtr<JSStringRef> documentSourceJS(Adopt, JSStringCreateWithBSTR(documentSource));
+ SysFreeString(documentSource);
+ JSRetainPtr<JSStringRef> urlJS(Adopt, JSStringCreateWithBSTR(url));
+ JSValueRef sidJS = JSValueMakeNumber(m_globalContext, sourceID);
+ JSValueRef baseLineJS = JSValueMakeNumber(m_globalContext, baseLineNumber);
+
+ DebuggerDocument::didParseScript(m_globalContext, sourceJS.get(), documentSourceJS.get(), urlJS.get(), sidJS, baseLineJS);
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE ServerConnection::failedToParseSource(
+ /* [in] */ IWebView*,
+ /* [in] */ BSTR,
+ /* [in] */ UINT,
+ /* [in] */ BSTR,
+ /* [in] */ BSTR,
+ /* [in] */ IWebFrame*)
+{
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE ServerConnection::didEnterCallFrame(
+ /* [in] */ IWebView*,
+ /* [in] */ IWebScriptCallFrame* frame,
+ /* [in] */ int sourceID,
+ /* [in] */ int lineNumber,
+ /* [in] */ IWebFrame*)
+{
+ HRESULT ret = S_OK;
+ if (!m_globalContext)
+ return ret;
+
+ m_currentFrame = frame;
+
+ JSValueRef sidJS = JSValueMakeNumber(m_globalContext, sourceID);
+ JSValueRef linenoJS = JSValueMakeNumber(m_globalContext, lineNumber);
+
+ DebuggerDocument::didEnterCallFrame(m_globalContext, sidJS, linenoJS);
+
+ return ret;
+}
+
+HRESULT STDMETHODCALLTYPE ServerConnection::willExecuteStatement(
+ /* [in] */ IWebView*,
+ /* [in] */ IWebScriptCallFrame*,
+ /* [in] */ int sourceID,
+ /* [in] */ int lineNumber,
+ /* [in] */ IWebFrame*)
+{
+ HRESULT ret = S_OK;
+ if (!m_globalContext)
+ return ret;
+
+ JSValueRef sidJS = JSValueMakeNumber(m_globalContext, sourceID);
+ JSValueRef linenoJS = JSValueMakeNumber(m_globalContext, lineNumber);
+
+ DebuggerDocument::willExecuteStatement(m_globalContext, sidJS, linenoJS);
+ return ret;
+}
+
+HRESULT STDMETHODCALLTYPE ServerConnection::willLeaveCallFrame(
+ /* [in] */ IWebView*,
+ /* [in] */ IWebScriptCallFrame* frame,
+ /* [in] */ int sourceID,
+ /* [in] */ int lineNumber,
+ /* [in] */ IWebFrame*)
+{
+ HRESULT ret = S_OK;
+ if (!m_globalContext)
+ return ret;
+
+ JSValueRef sidJS = JSValueMakeNumber(m_globalContext, sourceID);
+ JSValueRef linenoJS = JSValueMakeNumber(m_globalContext, lineNumber);
+
+ DebuggerDocument::willLeaveCallFrame(m_globalContext, sidJS, linenoJS);
+
+ m_currentFrame = frame;
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE ServerConnection::exceptionWasRaised(
+ /* [in] */ IWebView*,
+ /* [in] */ IWebScriptCallFrame*,
+ /* [in] */ int sourceID,
+ /* [in] */ int lineNumber,
+ /* [in] */ IWebFrame*)
+{
+ HRESULT ret = S_OK;
+ if (!m_globalContext)
+ return ret;
+
+ JSValueRef sidJS = JSValueMakeNumber(m_globalContext, sourceID);
+ JSValueRef linenoJS = JSValueMakeNumber(m_globalContext, lineNumber);
+
+ DebuggerDocument::exceptionWasRaised(m_globalContext, sidJS, linenoJS);
+
+ return ret;
+}
+
+HRESULT STDMETHODCALLTYPE ServerConnection::serverDidDie()
+{
+ m_server = 0;
+ m_currentFrame = 0;
+ m_serverConnected = false;
+ return S_OK;
+}
+
+// Stack & Variables
+
+IWebScriptCallFrame* ServerConnection::currentFrame() const
+{
+ return m_currentFrame.get();
+}
+
+COMPtr<IWebScriptCallFrame> ServerConnection::getCallerFrame(int callFrame) const
+{
+ COMPtr<IWebScriptCallFrame> cframe = currentFrame();
+ for (int count = 0; count < callFrame; count++) {
+ COMPtr<IWebScriptCallFrame> callerFrame;
+ if (FAILED(cframe->caller(&callerFrame)))
+ return 0;
+
+ cframe = callerFrame;
+ }
+
+ return cframe;
+}
diff --git a/WebKitTools/Drosera/win/ServerConnection.h b/WebKitTools/Drosera/win/ServerConnection.h
new file mode 100644
index 0000000..c0b64cf
--- /dev/null
+++ b/WebKitTools/Drosera/win/ServerConnection.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007 Vladimir Olexa (vladimir.olexa@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.
+ */
+
+#ifndef ServerConnection_H
+#define ServerConnection_H
+
+#include <string>
+#include <WebCore/COMPtr.h>
+#include <WebKit/WebKit.h>
+
+class DebuggerClient;
+interface IWebScriptCallFrame;
+interface IWebScriptDebugServer;
+
+typedef struct OpaqueJSContext* JSGlobalContextRef;
+
+class ServerConnection : public IWebScriptDebugListener {
+public:
+ ServerConnection();
+ ~ServerConnection();
+
+ bool serverConnected() const { return m_serverConnected; }
+ void attemptToCreateServerConnection(JSGlobalContextRef = 0);
+ void setGlobalContext(JSGlobalContextRef);
+
+ // Pause & Step
+ void pause();
+ void resume();
+ void stepInto();
+
+ // IUnknown
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(
+ /* [in] */ REFIID riid,
+ /* [retval][out] */ void** ppvObject);
+
+ virtual ULONG STDMETHODCALLTYPE AddRef();
+ virtual ULONG STDMETHODCALLTYPE Release();
+
+ // IWebScriptDebugListener
+ virtual HRESULT STDMETHODCALLTYPE didLoadMainResourceForDataSource(
+ /* [in] */ IWebView*,
+ /* [in] */ IWebDataSource* dataSource);
+
+ virtual HRESULT STDMETHODCALLTYPE didParseSource(
+ /* [in] */ IWebView*,
+ /* [in] */ BSTR sourceCode,
+ /* [in] */ UINT baseLineNumber,
+ /* [in] */ BSTR url,
+ /* [in] */ int sourceID,
+ /* [in] */ IWebFrame* webFrame);
+
+ virtual HRESULT STDMETHODCALLTYPE failedToParseSource(
+ /* [in] */ IWebView*,
+ /* [in] */ BSTR sourceCode,
+ /* [in] */ UINT baseLineNumber,
+ /* [in] */ BSTR url,
+ /* [in] */ BSTR error,
+ /* [in] */ IWebFrame*);
+
+ virtual HRESULT STDMETHODCALLTYPE didEnterCallFrame(
+ /* [in] */ IWebView*,
+ /* [in] */ IWebScriptCallFrame* frame,
+ /* [in] */ int sourceID,
+ /* [in] */ int lineNumber,
+ /* [in] */ IWebFrame*);
+
+ virtual HRESULT STDMETHODCALLTYPE willExecuteStatement(
+ /* [in] */ IWebView*,
+ /* [in] */ IWebScriptCallFrame*,
+ /* [in] */ int sourceID,
+ /* [in] */ int lineNumber,
+ /* [in] */ IWebFrame*);
+
+ virtual HRESULT STDMETHODCALLTYPE willLeaveCallFrame(
+ /* [in] */ IWebView*,
+ /* [in] */ IWebScriptCallFrame* frame,
+ /* [in] */ int sourceID,
+ /* [in] */ int lineNumber,
+ /* [in] */ IWebFrame*);
+
+ virtual HRESULT STDMETHODCALLTYPE exceptionWasRaised(
+ /* [in] */ IWebView*,
+ /* [in] */ IWebScriptCallFrame*,
+ /* [in] */ int sourceID,
+ /* [in] */ int lineNumber,
+ /* [in] */ IWebFrame*);
+
+ virtual HRESULT STDMETHODCALLTYPE serverDidDie();
+
+ // Stack & Variables
+ IWebScriptCallFrame* currentFrame() const;
+ COMPtr<IWebScriptCallFrame> getCallerFrame(int callFrame) const;
+
+private:
+ bool m_serverConnected;
+
+ COMPtr<IWebScriptCallFrame> m_currentFrame;
+ COMPtr<IWebScriptDebugServer> m_server;
+ JSGlobalContextRef m_globalContext;
+};
+
+#endif //ServerConnection_H
diff --git a/WebKitTools/Drosera/win/resource.h b/WebKitTools/Drosera/win/resource.h
new file mode 100644
index 0000000..4ba014e
--- /dev/null
+++ b/WebKitTools/Drosera/win/resource.h
@@ -0,0 +1,47 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by Drosera.rc
+//
+#define IDC_MYICON 2
+#define IDS_APP_TITLE 103
+#define IDD_ABOUTBOX 103
+#define IDI_DROSERA 107
+#define IDI_SMALL 108
+#define IDC_DROSERA 109
+#define IDC_LIST1 1001
+#define ID_DEBUG_SHOWCONSOLE 32771
+#define ID_DEBUG_CONTINUE 32772
+#define ID_DEBUG_PAUSE 32773
+#define ID_DEBUG_STEPINTO 32774
+#define ID_DEBUG_STEPOVER 32775
+#define ID_DEBUG_STEPOUT 32776
+#define ID_EDIT_UNDO 32777
+#define ID_EDIT_REDO 32778
+#define ID_EDIT_CUT 32779
+#define ID_EDIT_COPY 32780
+#define ID_EDIT_PASTE 32781
+#define ID_EDIT_SELECTALL 32782
+#define ID_FIND_FIND 32784
+#define ID_FIND_FINDNEXT 32785
+#define ID_FIND_FINDPREVIOUS 32786
+#define ID_FIND_USESELECTIONFORFIND 32787
+#define ID_FIND_JUMPTOSELECTION 32788
+#define ID_EDIT_SPECIALCHARACTERS 32789
+#define ID_FILE_EXIT 32791
+#define ID_WINDOW 32793
+#define ID_HELP_ABOUT 32794
+#define ID_FILE_CLOSE_CURRENT_FILE 32795
+#define ID_FILE_CLOSECURRENTFILE 32798
+#define IDC_STATIC -1
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NO_MFC 1
+#define _APS_NEXT_RESOURCE_VALUE 131
+#define _APS_NEXT_COMMAND_VALUE 32799
+#define _APS_NEXT_CONTROL_VALUE 1002
+#define _APS_NEXT_SYMED_VALUE 110
+#endif
+#endif
diff --git a/WebKitTools/DumpRenderTree/DumpRenderTree.h b/WebKitTools/DumpRenderTree/DumpRenderTree.h
new file mode 100644
index 0000000..e74d4bc
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/DumpRenderTree.h
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+#ifndef DumpRenderTree_h
+#define DumpRenderTree_h
+
+#include <wtf/Platform.h>
+
+#if PLATFORM(MAC)
+#include "DumpRenderTreeMac.h"
+#elif PLATFORM(WIN)
+#include "DumpRenderTreeWin.h"
+#elif PLATFORM(GTK)
+#include "DumpRenderTreeGtk.h"
+#endif
+
+#if PLATFORM(CF)
+#include <CoreFoundation/CoreFoundation.h>
+extern CFRunLoopTimerRef waitToDumpWatchdog;
+#endif
+
+#include <string>
+
+std::wstring urlSuitableForTestResult(const std::wstring& url);
+
+class LayoutTestController;
+
+extern volatile bool done;
+
+// FIXME: This is a bad abstraction. We should insted pass this to other controller objects which need access to it.
+extern LayoutTestController* layoutTestController;
+
+void dump();
+void displayWebView();
+
+#endif // DumpRenderTree_h
diff --git a/WebKitTools/DumpRenderTree/DumpRenderTree.sln b/WebKitTools/DumpRenderTree/DumpRenderTree.sln
new file mode 100644
index 0000000..5a6a35f
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/DumpRenderTree.sln
@@ -0,0 +1,47 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual C++ Express 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DumpRenderTree", "win\DumpRenderTree.vcproj", "{6567DFD4-D6DE-4CD5-825D-17E353D160E1}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestNetscapePlugin", "win\TestNetscapePlugin\TestNetscapePlugin.vcproj", "{C0737398-3565-439E-A2B8-AB2BE4D5430C}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FindSafari", "..\FindSafari\FindSafari.vcproj", "{DA31DA52-6675-48D4-89E0-333A7144397C}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ImageDiff", "win\ImageDiff.vcproj", "{59CC0547-70AC-499C-9B19-EC01C6F61137}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug_Internal|Win32 = Debug_Internal|Win32
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {6567DFD4-D6DE-4CD5-825D-17E353D160E1}.Debug_Internal|Win32.ActiveCfg = Debug_Internal|Win32
+ {6567DFD4-D6DE-4CD5-825D-17E353D160E1}.Debug_Internal|Win32.Build.0 = Debug_Internal|Win32
+ {6567DFD4-D6DE-4CD5-825D-17E353D160E1}.Debug|Win32.ActiveCfg = Debug|Win32
+ {6567DFD4-D6DE-4CD5-825D-17E353D160E1}.Debug|Win32.Build.0 = Debug|Win32
+ {6567DFD4-D6DE-4CD5-825D-17E353D160E1}.Release|Win32.ActiveCfg = Release|Win32
+ {6567DFD4-D6DE-4CD5-825D-17E353D160E1}.Release|Win32.Build.0 = Release|Win32
+ {C0737398-3565-439E-A2B8-AB2BE4D5430C}.Debug_Internal|Win32.ActiveCfg = Debug_Internal|Win32
+ {C0737398-3565-439E-A2B8-AB2BE4D5430C}.Debug_Internal|Win32.Build.0 = Debug_Internal|Win32
+ {C0737398-3565-439E-A2B8-AB2BE4D5430C}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C0737398-3565-439E-A2B8-AB2BE4D5430C}.Debug|Win32.Build.0 = Debug|Win32
+ {C0737398-3565-439E-A2B8-AB2BE4D5430C}.Release|Win32.ActiveCfg = Release|Win32
+ {C0737398-3565-439E-A2B8-AB2BE4D5430C}.Release|Win32.Build.0 = Release|Win32
+ {DA31DA52-6675-48D4-89E0-333A7144397C}.Debug_Internal|Win32.ActiveCfg = Debug|Win32
+ {DA31DA52-6675-48D4-89E0-333A7144397C}.Debug_Internal|Win32.Build.0 = Debug|Win32
+ {DA31DA52-6675-48D4-89E0-333A7144397C}.Debug|Win32.ActiveCfg = Debug|Win32
+ {DA31DA52-6675-48D4-89E0-333A7144397C}.Debug|Win32.Build.0 = Debug|Win32
+ {DA31DA52-6675-48D4-89E0-333A7144397C}.Release|Win32.ActiveCfg = Release|Win32
+ {DA31DA52-6675-48D4-89E0-333A7144397C}.Release|Win32.Build.0 = Release|Win32
+ {59CC0547-70AC-499C-9B19-EC01C6F61137}.Debug_Internal|Win32.ActiveCfg = Debug|Win32
+ {59CC0547-70AC-499C-9B19-EC01C6F61137}.Debug_Internal|Win32.Build.0 = Debug|Win32
+ {59CC0547-70AC-499C-9B19-EC01C6F61137}.Debug|Win32.ActiveCfg = Debug|Win32
+ {59CC0547-70AC-499C-9B19-EC01C6F61137}.Debug|Win32.Build.0 = Debug|Win32
+ {59CC0547-70AC-499C-9B19-EC01C6F61137}.Release|Win32.ActiveCfg = Release|Win32
+ {59CC0547-70AC-499C-9B19-EC01C6F61137}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj b/WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..1a59f19
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj
@@ -0,0 +1,752 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 42;
+ objects = {
+
+/* Begin PBXAggregateTarget section */
+ A84F608D08B1370600E9745F /* All */ = {
+ isa = PBXAggregateTarget;
+ buildConfigurationList = A84F609208B1371400E9745F /* Build configuration list for PBXAggregateTarget "All" */;
+ buildPhases = (
+ );
+ dependencies = (
+ A84F609108B1370E00E9745F /* PBXTargetDependency */,
+ A84F608F08B1370E00E9745F /* PBXTargetDependency */,
+ 141BF238096A451E00E0753C /* PBXTargetDependency */,
+ );
+ name = All;
+ productName = All;
+ };
+/* End PBXAggregateTarget section */
+
+/* Begin PBXBuildFile section */
+ 141BF435096A455900E0753C /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9335435F03D75502008635CE /* WebKit.framework */; };
+ 141BF436096A455900E0753C /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A84F608908B136DA00E9745F /* Cocoa.framework */; };
+ 141BF438096A455900E0753C /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A817090308B164D300CCB9FB /* JavaScriptCore.framework */; };
+ 141BF439096A455900E0753C /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AE8257EF08D22389000507AB /* Carbon.framework */; };
+ 141BF44C096A45C800E0753C /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 141BF448096A45C800E0753C /* Info.plist */; };
+ 141BF453096A45EB00E0753C /* PluginObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 141BF447096A45C800E0753C /* PluginObject.h */; };
+ 14770FE20A22ADF7009342EE /* GCController.h in Headers */ = {isa = PBXBuildFile; fileRef = 14770FE00A22ADF7009342EE /* GCController.h */; };
+ 1A8F02E80BB9B4EC008CFA34 /* TestObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8F024C0BB9B056008CFA34 /* TestObject.h */; };
+ 1AC6C8490D07638600CD3161 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AC6C77F0D07589B00CD3161 /* main.cpp */; };
+ 1AC6C84A0D07638600CD3161 /* PluginObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AC6C7800D07589B00CD3161 /* PluginObject.cpp */; };
+ 1AC6C84B0D07638600CD3161 /* TestObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AC6C7810D07589B00CD3161 /* TestObject.cpp */; };
+ 9340994C08540CAE007F3BC8 /* DumpRenderTreePrefix.h in Headers */ = {isa = PBXBuildFile; fileRef = 32A70AAB03705E1F00C91783 /* DumpRenderTreePrefix.h */; };
+ 9340995108540CAE007F3BC8 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9335435F03D75502008635CE /* WebKit.framework */; };
+ A817090008B163EF00CCB9FB /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A84F608908B136DA00E9745F /* Cocoa.framework */; };
+ A817090408B164D300CCB9FB /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A817090308B164D300CCB9FB /* JavaScriptCore.framework */; };
+ A84F608A08B136DA00E9745F /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A84F608908B136DA00E9745F /* Cocoa.framework */; };
+ A8B91ADA0CF3B32F008F91FF /* DumpRenderTreePasteboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A8B91AD70CF3B32F008F91FF /* DumpRenderTreePasteboard.m */; };
+ A8B91ADC0CF3B32F008F91FF /* DumpRenderTreeWindow.mm in Sources */ = {isa = PBXBuildFile; fileRef = A8B91AD90CF3B32F008F91FF /* DumpRenderTreeWindow.mm */; };
+ A8B91AE00CF3B372008F91FF /* DumpRenderTreeWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A8B91ADD0CF3B372008F91FF /* DumpRenderTreeWindow.h */; };
+ A8B91AE20CF3B372008F91FF /* DumpRenderTreePasteboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A8B91ADF0CF3B372008F91FF /* DumpRenderTreePasteboard.h */; };
+ A8B91BFD0CF522B4008F91FF /* CheckedMalloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8B91BF70CF522B4008F91FF /* CheckedMalloc.cpp */; };
+ A8B91BFF0CF522B4008F91FF /* CheckedMalloc.h in Headers */ = {isa = PBXBuildFile; fileRef = A8B91BF90CF522B4008F91FF /* CheckedMalloc.h */; };
+ AE8259F308D22463000507AB /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AE8257EF08D22389000507AB /* Carbon.framework */; };
+ AE8259F408D22463000507AB /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AE8257EF08D22389000507AB /* Carbon.framework */; };
+ B5A752A208AF5D1F00138E45 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5A752A108AF5D1F00138E45 /* QuartzCore.framework */; };
+ BC0131DA0C9772010087317D /* LayoutTestController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC0131D80C9772010087317D /* LayoutTestController.cpp */; };
+ BC0131DB0C9772010087317D /* LayoutTestController.h in Headers */ = {isa = PBXBuildFile; fileRef = BC0131D90C9772010087317D /* LayoutTestController.h */; };
+ BC47412A0D038A4C0072B006 /* JavaScriptThreading.h in Headers */ = {isa = PBXBuildFile; fileRef = BC4741290D038A4C0072B006 /* JavaScriptThreading.h */; };
+ BC4741410D038A570072B006 /* JavaScriptThreadingPthreads.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC4741400D038A570072B006 /* JavaScriptThreadingPthreads.cpp */; };
+ BC9D90240C97472E0099A4A3 /* WorkQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC9D90210C97472D0099A4A3 /* WorkQueue.cpp */; };
+ BC9D90250C97472E0099A4A3 /* WorkQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = BC9D90220C97472E0099A4A3 /* WorkQueue.h */; };
+ BC9D90260C97472E0099A4A3 /* WorkQueueItem.h in Headers */ = {isa = PBXBuildFile; fileRef = BC9D90230C97472E0099A4A3 /* WorkQueueItem.h */; };
+ BCA18B230C9B014B00114369 /* GCControllerMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B210C9B014B00114369 /* GCControllerMac.mm */; };
+ BCA18B240C9B014B00114369 /* LayoutTestControllerMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B220C9B014B00114369 /* LayoutTestControllerMac.mm */; };
+ BCA18B260C9B015C00114369 /* WorkQueueItemMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B250C9B015C00114369 /* WorkQueueItemMac.mm */; };
+ BCA18B310C9B01B400114369 /* ObjCController.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA18B2F0C9B01B400114369 /* ObjCController.h */; };
+ BCA18B320C9B01B400114369 /* ObjCController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B300C9B01B400114369 /* ObjCController.m */; };
+ BCA18B380C9B021900114369 /* AppleScriptController.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA18B360C9B021900114369 /* AppleScriptController.h */; };
+ BCA18B390C9B021900114369 /* AppleScriptController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B370C9B021900114369 /* AppleScriptController.m */; };
+ BCA18B3C0C9B024900114369 /* TextInputController.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA18B3A0C9B024900114369 /* TextInputController.h */; };
+ BCA18B490C9B02C400114369 /* TextInputController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B480C9B02C400114369 /* TextInputController.m */; };
+ BCA18B610C9B08C200114369 /* EditingDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA18B570C9B08C200114369 /* EditingDelegate.h */; };
+ BCA18B620C9B08C200114369 /* EditingDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B580C9B08C200114369 /* EditingDelegate.mm */; };
+ BCA18B630C9B08C200114369 /* FrameLoadDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA18B590C9B08C200114369 /* FrameLoadDelegate.h */; };
+ BCA18B640C9B08C200114369 /* FrameLoadDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B5A0C9B08C200114369 /* FrameLoadDelegate.mm */; };
+ BCA18B650C9B08C200114369 /* PolicyDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA18B5B0C9B08C200114369 /* PolicyDelegate.h */; };
+ BCA18B660C9B08C200114369 /* PolicyDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B5C0C9B08C200114369 /* PolicyDelegate.mm */; };
+ BCA18B670C9B08C200114369 /* ResourceLoadDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA18B5D0C9B08C200114369 /* ResourceLoadDelegate.h */; };
+ BCA18B680C9B08C200114369 /* ResourceLoadDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B5E0C9B08C200114369 /* ResourceLoadDelegate.mm */; };
+ BCA18B690C9B08C200114369 /* UIDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA18B5F0C9B08C200114369 /* UIDelegate.h */; };
+ BCA18B6A0C9B08C200114369 /* UIDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B600C9B08C200114369 /* UIDelegate.mm */; };
+ BCA18B6F0C9B08DB00114369 /* EventSendingController.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA18B6B0C9B08DB00114369 /* EventSendingController.h */; };
+ BCA18B700C9B08DB00114369 /* EventSendingController.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B6C0C9B08DB00114369 /* EventSendingController.mm */; };
+ BCA18B710C9B08DB00114369 /* NavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA18B6D0C9B08DB00114369 /* NavigationController.h */; };
+ BCA18B720C9B08DB00114369 /* NavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B6E0C9B08DB00114369 /* NavigationController.m */; };
+ BCA18B7A0C9B08F100114369 /* DumpRenderTreeDraggingInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA18B730C9B08F100114369 /* DumpRenderTreeDraggingInfo.h */; };
+ BCA18B7B0C9B08F100114369 /* DumpRenderTreeDraggingInfo.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B740C9B08F100114369 /* DumpRenderTreeDraggingInfo.mm */; };
+ BCA18B7D0C9B08F100114369 /* ObjCPlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA18B760C9B08F100114369 /* ObjCPlugin.h */; };
+ BCA18B7E0C9B08F100114369 /* ObjCPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B770C9B08F100114369 /* ObjCPlugin.m */; };
+ BCA18B7F0C9B08F100114369 /* ObjCPluginFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA18B780C9B08F100114369 /* ObjCPluginFunction.h */; };
+ BCA18B800C9B08F100114369 /* ObjCPluginFunction.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B790C9B08F100114369 /* ObjCPluginFunction.m */; };
+ BCA18C0B0C9B59EF00114369 /* DumpRenderTreeMac.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA18C0A0C9B59EF00114369 /* DumpRenderTreeMac.h */; };
+ BCA18C470C9B5B9400114369 /* DumpRenderTree.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCA18C460C9B5B9400114369 /* DumpRenderTree.mm */; settings = {COMPILER_FLAGS = "-Wno-deprecated-declarations"; }; };
+ BCB284C70CFA83C4007E533E /* PixelDumpSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB2848A0CFA820F007E533E /* PixelDumpSupport.h */; };
+ BCB284CD0CFA83C8007E533E /* PixelDumpSupportCG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCB284880CFA8202007E533E /* PixelDumpSupportCG.cpp */; };
+ BCB284D00CFA83CC007E533E /* PixelDumpSupportCG.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB284890CFA8202007E533E /* PixelDumpSupportCG.h */; };
+ BCB284D60CFA83D1007E533E /* PixelDumpSupportMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCB2848C0CFA8221007E533E /* PixelDumpSupportMac.mm */; };
+ BCB284F60CFA84F8007E533E /* ImageDiffCG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCB284F30CFA84F2007E533E /* ImageDiffCG.cpp */; };
+ BCF6C6500C98E9C000AC063E /* GCController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCF6C64F0C98E9C000AC063E /* GCController.cpp */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 141BF237096A451E00E0753C /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 141BF21E096A441D00E0753C;
+ remoteInfo = TestNetscapePlugIn;
+ };
+ A84F608E08B1370E00E9745F /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B5A7525A08AF4A4A00138E45;
+ remoteInfo = ImageDiff;
+ };
+ A84F609008B1370E00E9745F /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 9340994A08540CAE007F3BC8;
+ remoteInfo = DumpRenderTree;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ 141BF233096A44CF00E0753C /* TestNetscapePlugIn.plugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TestNetscapePlugIn.plugin; sourceTree = BUILT_PRODUCTS_DIR; };
+ 141BF447096A45C800E0753C /* PluginObject.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PluginObject.h; sourceTree = "<group>"; };
+ 141BF448096A45C800E0753C /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; path = Info.plist; sourceTree = "<group>"; };
+ 14770FE00A22ADF7009342EE /* GCController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCController.h; sourceTree = "<group>"; };
+ 1A8F024C0BB9B056008CFA34 /* TestObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestObject.h; sourceTree = "<group>"; };
+ 1AC6C77F0D07589B00CD3161 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
+ 1AC6C7800D07589B00CD3161 /* PluginObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PluginObject.cpp; sourceTree = "<group>"; };
+ 1AC6C7810D07589B00CD3161 /* TestObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TestObject.cpp; sourceTree = "<group>"; };
+ 32A70AAB03705E1F00C91783 /* DumpRenderTreePrefix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DumpRenderTreePrefix.h; sourceTree = "<group>"; };
+ 9335435F03D75502008635CE /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = WebKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 9340995408540CAF007F3BC8 /* DumpRenderTree */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = DumpRenderTree; sourceTree = BUILT_PRODUCTS_DIR; };
+ A803FF7409CAAD08009B2A37 /* DumpRenderTree.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = DumpRenderTree.h; sourceTree = "<group>"; };
+ A817090308B164D300CCB9FB /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = JavaScriptCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ A84F608908B136DA00E9745F /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
+ A8B91AD70CF3B32F008F91FF /* DumpRenderTreePasteboard.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DumpRenderTreePasteboard.m; path = mac/DumpRenderTreePasteboard.m; sourceTree = "<group>"; };
+ A8B91AD90CF3B32F008F91FF /* DumpRenderTreeWindow.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = DumpRenderTreeWindow.mm; path = mac/DumpRenderTreeWindow.mm; sourceTree = "<group>"; };
+ A8B91ADD0CF3B372008F91FF /* DumpRenderTreeWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DumpRenderTreeWindow.h; path = mac/DumpRenderTreeWindow.h; sourceTree = "<group>"; };
+ A8B91ADF0CF3B372008F91FF /* DumpRenderTreePasteboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DumpRenderTreePasteboard.h; path = mac/DumpRenderTreePasteboard.h; sourceTree = "<group>"; };
+ A8B91BF70CF522B4008F91FF /* CheckedMalloc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CheckedMalloc.cpp; path = mac/CheckedMalloc.cpp; sourceTree = "<group>"; };
+ A8B91BF90CF522B4008F91FF /* CheckedMalloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CheckedMalloc.h; path = mac/CheckedMalloc.h; sourceTree = "<group>"; };
+ AA7F10C20CB3C1030003BDC9 /* AHEM____.TTF */ = {isa = PBXFileReference; lastKnownFileType = file; name = "AHEM____.TTF"; path = "qt/fonts/AHEM____.TTF"; sourceTree = "<group>"; };
+ AE8257EF08D22389000507AB /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
+ B5A7526708AF4A4A00138E45 /* ImageDiff */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ImageDiff; sourceTree = BUILT_PRODUCTS_DIR; };
+ B5A752A108AF5D1F00138E45 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = /System/Library/Frameworks/QuartzCore.framework; sourceTree = "<absolute>"; };
+ BC0131D80C9772010087317D /* LayoutTestController.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 30; path = LayoutTestController.cpp; sourceTree = "<group>"; };
+ BC0131D90C9772010087317D /* LayoutTestController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LayoutTestController.h; sourceTree = "<group>"; };
+ BC4741290D038A4C0072B006 /* JavaScriptThreading.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JavaScriptThreading.h; sourceTree = "<group>"; };
+ BC4741400D038A570072B006 /* JavaScriptThreadingPthreads.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JavaScriptThreadingPthreads.cpp; path = pthreads/JavaScriptThreadingPthreads.cpp; sourceTree = "<group>"; };
+ BC9D90210C97472D0099A4A3 /* WorkQueue.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 30; path = WorkQueue.cpp; sourceTree = "<group>"; };
+ BC9D90220C97472E0099A4A3 /* WorkQueue.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = WorkQueue.h; sourceTree = "<group>"; };
+ BC9D90230C97472E0099A4A3 /* WorkQueueItem.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = WorkQueueItem.h; sourceTree = "<group>"; };
+ BCA18B210C9B014B00114369 /* GCControllerMac.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = GCControllerMac.mm; path = mac/GCControllerMac.mm; sourceTree = "<group>"; };
+ BCA18B220C9B014B00114369 /* LayoutTestControllerMac.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = LayoutTestControllerMac.mm; path = mac/LayoutTestControllerMac.mm; sourceTree = "<group>"; };
+ BCA18B250C9B015C00114369 /* WorkQueueItemMac.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = WorkQueueItemMac.mm; path = mac/WorkQueueItemMac.mm; sourceTree = "<group>"; };
+ BCA18B2F0C9B01B400114369 /* ObjCController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ObjCController.h; path = mac/ObjCController.h; sourceTree = "<group>"; };
+ BCA18B300C9B01B400114369 /* ObjCController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = ObjCController.m; path = mac/ObjCController.m; sourceTree = "<group>"; };
+ BCA18B360C9B021900114369 /* AppleScriptController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AppleScriptController.h; path = mac/AppleScriptController.h; sourceTree = "<group>"; };
+ BCA18B370C9B021900114369 /* AppleScriptController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = AppleScriptController.m; path = mac/AppleScriptController.m; sourceTree = "<group>"; };
+ BCA18B3A0C9B024900114369 /* TextInputController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = TextInputController.h; path = mac/TextInputController.h; sourceTree = "<group>"; };
+ BCA18B480C9B02C400114369 /* TextInputController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = TextInputController.m; path = mac/TextInputController.m; sourceTree = "<group>"; };
+ BCA18B570C9B08C200114369 /* EditingDelegate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = EditingDelegate.h; path = mac/EditingDelegate.h; sourceTree = "<group>"; };
+ BCA18B580C9B08C200114369 /* EditingDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = EditingDelegate.mm; path = mac/EditingDelegate.mm; sourceTree = "<group>"; };
+ BCA18B590C9B08C200114369 /* FrameLoadDelegate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = FrameLoadDelegate.h; path = mac/FrameLoadDelegate.h; sourceTree = "<group>"; };
+ BCA18B5A0C9B08C200114369 /* FrameLoadDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = FrameLoadDelegate.mm; path = mac/FrameLoadDelegate.mm; sourceTree = "<group>"; };
+ BCA18B5B0C9B08C200114369 /* PolicyDelegate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PolicyDelegate.h; path = mac/PolicyDelegate.h; sourceTree = "<group>"; };
+ BCA18B5C0C9B08C200114369 /* PolicyDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = PolicyDelegate.mm; path = mac/PolicyDelegate.mm; sourceTree = "<group>"; };
+ BCA18B5D0C9B08C200114369 /* ResourceLoadDelegate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ResourceLoadDelegate.h; path = mac/ResourceLoadDelegate.h; sourceTree = "<group>"; };
+ BCA18B5E0C9B08C200114369 /* ResourceLoadDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = ResourceLoadDelegate.mm; path = mac/ResourceLoadDelegate.mm; sourceTree = "<group>"; };
+ BCA18B5F0C9B08C200114369 /* UIDelegate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = UIDelegate.h; path = mac/UIDelegate.h; sourceTree = "<group>"; };
+ BCA18B600C9B08C200114369 /* UIDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = UIDelegate.mm; path = mac/UIDelegate.mm; sourceTree = "<group>"; };
+ BCA18B6B0C9B08DB00114369 /* EventSendingController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = EventSendingController.h; path = mac/EventSendingController.h; sourceTree = "<group>"; };
+ BCA18B6C0C9B08DB00114369 /* EventSendingController.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = EventSendingController.mm; path = mac/EventSendingController.mm; sourceTree = "<group>"; };
+ BCA18B6D0C9B08DB00114369 /* NavigationController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = NavigationController.h; path = mac/NavigationController.h; sourceTree = "<group>"; };
+ BCA18B6E0C9B08DB00114369 /* NavigationController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = NavigationController.m; path = mac/NavigationController.m; sourceTree = "<group>"; };
+ BCA18B730C9B08F100114369 /* DumpRenderTreeDraggingInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DumpRenderTreeDraggingInfo.h; path = mac/DumpRenderTreeDraggingInfo.h; sourceTree = "<group>"; };
+ BCA18B740C9B08F100114369 /* DumpRenderTreeDraggingInfo.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = DumpRenderTreeDraggingInfo.mm; path = mac/DumpRenderTreeDraggingInfo.mm; sourceTree = "<group>"; };
+ BCA18B760C9B08F100114369 /* ObjCPlugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ObjCPlugin.h; path = mac/ObjCPlugin.h; sourceTree = "<group>"; };
+ BCA18B770C9B08F100114369 /* ObjCPlugin.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = ObjCPlugin.m; path = mac/ObjCPlugin.m; sourceTree = "<group>"; };
+ BCA18B780C9B08F100114369 /* ObjCPluginFunction.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ObjCPluginFunction.h; path = mac/ObjCPluginFunction.h; sourceTree = "<group>"; };
+ BCA18B790C9B08F100114369 /* ObjCPluginFunction.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = ObjCPluginFunction.m; path = mac/ObjCPluginFunction.m; sourceTree = "<group>"; };
+ BCA18C0A0C9B59EF00114369 /* DumpRenderTreeMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DumpRenderTreeMac.h; path = mac/DumpRenderTreeMac.h; sourceTree = "<group>"; };
+ BCA18C460C9B5B9400114369 /* DumpRenderTree.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = DumpRenderTree.mm; path = mac/DumpRenderTree.mm; sourceTree = "<group>"; };
+ BCB281EE0CFA713D007E533E /* Base.xcconfig */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xcconfig; name = Base.xcconfig; path = mac/Configurations/Base.xcconfig; sourceTree = "<group>"; };
+ BCB281F00CFA713D007E533E /* DumpRenderTree.xcconfig */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xcconfig; name = DumpRenderTree.xcconfig; path = mac/Configurations/DumpRenderTree.xcconfig; sourceTree = "<group>"; };
+ BCB282F40CFA7450007E533E /* DebugRelease.xcconfig */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xcconfig; name = DebugRelease.xcconfig; path = mac/Configurations/DebugRelease.xcconfig; sourceTree = "<group>"; };
+ BCB283D80CFA7AFD007E533E /* ImageDiff.xcconfig */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xcconfig; name = ImageDiff.xcconfig; path = mac/Configurations/ImageDiff.xcconfig; sourceTree = "<group>"; };
+ BCB283DE0CFA7C20007E533E /* TestNetscapePlugIn.xcconfig */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xcconfig; name = TestNetscapePlugIn.xcconfig; path = mac/Configurations/TestNetscapePlugIn.xcconfig; sourceTree = "<group>"; };
+ BCB284880CFA8202007E533E /* PixelDumpSupportCG.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 30; name = PixelDumpSupportCG.cpp; path = cg/PixelDumpSupportCG.cpp; sourceTree = "<group>"; };
+ BCB284890CFA8202007E533E /* PixelDumpSupportCG.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PixelDumpSupportCG.h; path = cg/PixelDumpSupportCG.h; sourceTree = "<group>"; };
+ BCB2848A0CFA820F007E533E /* PixelDumpSupport.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PixelDumpSupport.h; sourceTree = "<group>"; };
+ BCB2848C0CFA8221007E533E /* PixelDumpSupportMac.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = PixelDumpSupportMac.mm; path = mac/PixelDumpSupportMac.mm; sourceTree = "<group>"; };
+ BCB284B20CFA82CB007E533E /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = /System/Library/Frameworks/ApplicationServices.framework; sourceTree = "<absolute>"; };
+ BCB284F30CFA84F2007E533E /* ImageDiffCG.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ImageDiffCG.cpp; path = cg/ImageDiffCG.cpp; sourceTree = "<group>"; };
+ BCF6C64F0C98E9C000AC063E /* GCController.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 30; path = GCController.cpp; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 141BF21D096A441D00E0753C /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 141BF439096A455900E0753C /* Carbon.framework in Frameworks */,
+ 141BF436096A455900E0753C /* Cocoa.framework in Frameworks */,
+ 141BF438096A455900E0753C /* JavaScriptCore.framework in Frameworks */,
+ 141BF435096A455900E0753C /* WebKit.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 9340994F08540CAE007F3BC8 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AE8259F308D22463000507AB /* Carbon.framework in Frameworks */,
+ A84F608A08B136DA00E9745F /* Cocoa.framework in Frameworks */,
+ A817090408B164D300CCB9FB /* JavaScriptCore.framework in Frameworks */,
+ 9340995108540CAE007F3BC8 /* WebKit.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B5A7525F08AF4A4A00138E45 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AE8259F408D22463000507AB /* Carbon.framework in Frameworks */,
+ A817090008B163EF00CCB9FB /* Cocoa.framework in Frameworks */,
+ B5A752A208AF5D1F00138E45 /* QuartzCore.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 08FB7794FE84155DC02AAC07 /* DumpRenderTree */ = {
+ isa = PBXGroup;
+ children = (
+ 32A70AAB03705E1F00C91783 /* DumpRenderTreePrefix.h */,
+ 1422A2750AF6F4BD00E1A883 /* Delegates */,
+ 1422A2690AF6F45200E1A883 /* Controllers */,
+ BCB284870CFA81ED007E533E /* PixelDump */,
+ A803FF7409CAAD08009B2A37 /* DumpRenderTree.h */,
+ BCA18C460C9B5B9400114369 /* DumpRenderTree.mm */,
+ A8B91BF70CF522B4008F91FF /* CheckedMalloc.cpp */,
+ A8B91BF90CF522B4008F91FF /* CheckedMalloc.h */,
+ BC4741290D038A4C0072B006 /* JavaScriptThreading.h */,
+ BC4741400D038A570072B006 /* JavaScriptThreadingPthreads.cpp */,
+ BCA18C0A0C9B59EF00114369 /* DumpRenderTreeMac.h */,
+ BCA18B730C9B08F100114369 /* DumpRenderTreeDraggingInfo.h */,
+ BCA18B740C9B08F100114369 /* DumpRenderTreeDraggingInfo.mm */,
+ BC9D90210C97472D0099A4A3 /* WorkQueue.cpp */,
+ BC9D90220C97472E0099A4A3 /* WorkQueue.h */,
+ BC9D90230C97472E0099A4A3 /* WorkQueueItem.h */,
+ A8B91AD20CF3B305008F91FF /* AppKit Overrides */,
+ A8B91AC40CF3B170008F91FF /* ObjCPlugin */,
+ 141BF1F5096A439800E0753C /* TestNetscapePlugIn.subproj */,
+ 9345229B0BD12B2C0086EDA0 /* Resources */,
+ A803FF6409CAACC1009B2A37 /* Frameworks */,
+ 9340995508540CAF007F3BC8 /* Products */,
+ BCB281ED0CFA711D007E533E /* Configurations */,
+ );
+ name = DumpRenderTree;
+ sourceTree = "<group>";
+ };
+ 141BF1F5096A439800E0753C /* TestNetscapePlugIn.subproj */ = {
+ isa = PBXGroup;
+ children = (
+ 1AC6C77F0D07589B00CD3161 /* main.cpp */,
+ 1AC6C7800D07589B00CD3161 /* PluginObject.cpp */,
+ 141BF447096A45C800E0753C /* PluginObject.h */,
+ 1AC6C7810D07589B00CD3161 /* TestObject.cpp */,
+ 1A8F024C0BB9B056008CFA34 /* TestObject.h */,
+ 141BF448096A45C800E0753C /* Info.plist */,
+ );
+ path = TestNetscapePlugIn.subproj;
+ sourceTree = "<group>";
+ };
+ 1422A2690AF6F45200E1A883 /* Controllers */ = {
+ isa = PBXGroup;
+ children = (
+ BCA18B360C9B021900114369 /* AppleScriptController.h */,
+ BCA18B370C9B021900114369 /* AppleScriptController.m */,
+ BCA18B6B0C9B08DB00114369 /* EventSendingController.h */,
+ BCA18B6C0C9B08DB00114369 /* EventSendingController.mm */,
+ BCF6C64F0C98E9C000AC063E /* GCController.cpp */,
+ 14770FE00A22ADF7009342EE /* GCController.h */,
+ BCA18B210C9B014B00114369 /* GCControllerMac.mm */,
+ BC0131D80C9772010087317D /* LayoutTestController.cpp */,
+ BC0131D90C9772010087317D /* LayoutTestController.h */,
+ BCA18B220C9B014B00114369 /* LayoutTestControllerMac.mm */,
+ BCA18B6D0C9B08DB00114369 /* NavigationController.h */,
+ BCA18B6E0C9B08DB00114369 /* NavigationController.m */,
+ BCA18B2F0C9B01B400114369 /* ObjCController.h */,
+ BCA18B300C9B01B400114369 /* ObjCController.m */,
+ BCA18B3A0C9B024900114369 /* TextInputController.h */,
+ BCA18B480C9B02C400114369 /* TextInputController.m */,
+ );
+ name = Controllers;
+ sourceTree = "<group>";
+ };
+ 1422A2750AF6F4BD00E1A883 /* Delegates */ = {
+ isa = PBXGroup;
+ children = (
+ BCA18B570C9B08C200114369 /* EditingDelegate.h */,
+ BCA18B580C9B08C200114369 /* EditingDelegate.mm */,
+ BCA18B590C9B08C200114369 /* FrameLoadDelegate.h */,
+ BCA18B5A0C9B08C200114369 /* FrameLoadDelegate.mm */,
+ BCA18B5B0C9B08C200114369 /* PolicyDelegate.h */,
+ BCA18B5C0C9B08C200114369 /* PolicyDelegate.mm */,
+ BCA18B5D0C9B08C200114369 /* ResourceLoadDelegate.h */,
+ BCA18B5E0C9B08C200114369 /* ResourceLoadDelegate.mm */,
+ BCA18B5F0C9B08C200114369 /* UIDelegate.h */,
+ BCA18B600C9B08C200114369 /* UIDelegate.mm */,
+ );
+ name = Delegates;
+ sourceTree = "<group>";
+ };
+ 9340995508540CAF007F3BC8 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 9340995408540CAF007F3BC8 /* DumpRenderTree */,
+ B5A7526708AF4A4A00138E45 /* ImageDiff */,
+ 141BF233096A44CF00E0753C /* TestNetscapePlugIn.plugin */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 9345229B0BD12B2C0086EDA0 /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ AA7F10C20CB3C1030003BDC9 /* AHEM____.TTF */,
+ );
+ name = Resources;
+ sourceTree = "<group>";
+ };
+ A803FF6409CAACC1009B2A37 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ BCB284B20CFA82CB007E533E /* ApplicationServices.framework */,
+ AE8257EF08D22389000507AB /* Carbon.framework */,
+ A84F608908B136DA00E9745F /* Cocoa.framework */,
+ A817090308B164D300CCB9FB /* JavaScriptCore.framework */,
+ B5A752A108AF5D1F00138E45 /* QuartzCore.framework */,
+ 9335435F03D75502008635CE /* WebKit.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+ A8B91AC40CF3B170008F91FF /* ObjCPlugin */ = {
+ isa = PBXGroup;
+ children = (
+ BCA18B250C9B015C00114369 /* WorkQueueItemMac.mm */,
+ BCA18B760C9B08F100114369 /* ObjCPlugin.h */,
+ BCA18B770C9B08F100114369 /* ObjCPlugin.m */,
+ BCA18B780C9B08F100114369 /* ObjCPluginFunction.h */,
+ BCA18B790C9B08F100114369 /* ObjCPluginFunction.m */,
+ );
+ name = ObjCPlugin;
+ sourceTree = "<group>";
+ };
+ A8B91AD20CF3B305008F91FF /* AppKit Overrides */ = {
+ isa = PBXGroup;
+ children = (
+ A8B91ADF0CF3B372008F91FF /* DumpRenderTreePasteboard.h */,
+ A8B91AD70CF3B32F008F91FF /* DumpRenderTreePasteboard.m */,
+ A8B91ADD0CF3B372008F91FF /* DumpRenderTreeWindow.h */,
+ A8B91AD90CF3B32F008F91FF /* DumpRenderTreeWindow.mm */,
+ );
+ name = "AppKit Overrides";
+ sourceTree = "<group>";
+ };
+ BCB281ED0CFA711D007E533E /* Configurations */ = {
+ isa = PBXGroup;
+ children = (
+ BCB281EE0CFA713D007E533E /* Base.xcconfig */,
+ BCB282F40CFA7450007E533E /* DebugRelease.xcconfig */,
+ BCB281F00CFA713D007E533E /* DumpRenderTree.xcconfig */,
+ BCB283D80CFA7AFD007E533E /* ImageDiff.xcconfig */,
+ BCB283DE0CFA7C20007E533E /* TestNetscapePlugIn.xcconfig */,
+ );
+ name = Configurations;
+ sourceTree = "<group>";
+ };
+ BCB284870CFA81ED007E533E /* PixelDump */ = {
+ isa = PBXGroup;
+ children = (
+ BCB284F30CFA84F2007E533E /* ImageDiffCG.cpp */,
+ BCB2848A0CFA820F007E533E /* PixelDumpSupport.h */,
+ BCB284880CFA8202007E533E /* PixelDumpSupportCG.cpp */,
+ BCB284890CFA8202007E533E /* PixelDumpSupportCG.h */,
+ BCB2848C0CFA8221007E533E /* PixelDumpSupportMac.mm */,
+ );
+ name = PixelDump;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+ 141BF44E096A45DD00E0753C /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 141BF453096A45EB00E0753C /* PluginObject.h in Headers */,
+ 1A8F02E80BB9B4EC008CFA34 /* TestObject.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 9340994B08540CAE007F3BC8 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ BCA18B380C9B021900114369 /* AppleScriptController.h in Headers */,
+ BCA18B7A0C9B08F100114369 /* DumpRenderTreeDraggingInfo.h in Headers */,
+ BCA18C0B0C9B59EF00114369 /* DumpRenderTreeMac.h in Headers */,
+ 9340994C08540CAE007F3BC8 /* DumpRenderTreePrefix.h in Headers */,
+ BCA18B610C9B08C200114369 /* EditingDelegate.h in Headers */,
+ BCA18B6F0C9B08DB00114369 /* EventSendingController.h in Headers */,
+ BCA18B630C9B08C200114369 /* FrameLoadDelegate.h in Headers */,
+ 14770FE20A22ADF7009342EE /* GCController.h in Headers */,
+ BC0131DB0C9772010087317D /* LayoutTestController.h in Headers */,
+ BCA18B710C9B08DB00114369 /* NavigationController.h in Headers */,
+ BCA18B310C9B01B400114369 /* ObjCController.h in Headers */,
+ BCA18B7D0C9B08F100114369 /* ObjCPlugin.h in Headers */,
+ BCA18B7F0C9B08F100114369 /* ObjCPluginFunction.h in Headers */,
+ BCA18B650C9B08C200114369 /* PolicyDelegate.h in Headers */,
+ BCA18B670C9B08C200114369 /* ResourceLoadDelegate.h in Headers */,
+ BCA18B3C0C9B024900114369 /* TextInputController.h in Headers */,
+ BCA18B690C9B08C200114369 /* UIDelegate.h in Headers */,
+ BC9D90250C97472E0099A4A3 /* WorkQueue.h in Headers */,
+ BC9D90260C97472E0099A4A3 /* WorkQueueItem.h in Headers */,
+ A8B91AE00CF3B372008F91FF /* DumpRenderTreeWindow.h in Headers */,
+ A8B91AE20CF3B372008F91FF /* DumpRenderTreePasteboard.h in Headers */,
+ A8B91BFF0CF522B4008F91FF /* CheckedMalloc.h in Headers */,
+ BCB284C70CFA83C4007E533E /* PixelDumpSupport.h in Headers */,
+ BCB284D00CFA83CC007E533E /* PixelDumpSupportCG.h in Headers */,
+ BC47412A0D038A4C0072B006 /* JavaScriptThreading.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B5A7525B08AF4A4A00138E45 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+ 141BF21E096A441D00E0753C /* TestNetscapePlugIn */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 141BF221096A441E00E0753C /* Build configuration list for PBXNativeTarget "TestNetscapePlugIn" */;
+ buildPhases = (
+ 141BF21B096A441D00E0753C /* Resources */,
+ 141BF44E096A45DD00E0753C /* Headers */,
+ 141BF21C096A441D00E0753C /* Sources */,
+ 141BF21D096A441D00E0753C /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = TestNetscapePlugIn;
+ productName = TestNetscapePlugIn.plugin;
+ productReference = 141BF233096A44CF00E0753C /* TestNetscapePlugIn.plugin */;
+ productType = "com.apple.product-type.bundle";
+ };
+ 9340994A08540CAE007F3BC8 /* DumpRenderTree */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 149C29BF08902C6D008A9EFC /* Build configuration list for PBXNativeTarget "DumpRenderTree" */;
+ buildPhases = (
+ 9340994B08540CAE007F3BC8 /* Headers */,
+ 9340994D08540CAE007F3BC8 /* Sources */,
+ 9340994F08540CAE007F3BC8 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = DumpRenderTree;
+ productInstallPath = "$(HOME)/bin";
+ productName = DumpRenderTree;
+ productReference = 9340995408540CAF007F3BC8 /* DumpRenderTree */;
+ productType = "com.apple.product-type.tool";
+ };
+ B5A7525A08AF4A4A00138E45 /* ImageDiff */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = B5A7526408AF4A4A00138E45 /* Build configuration list for PBXNativeTarget "ImageDiff" */;
+ buildPhases = (
+ B5A7525B08AF4A4A00138E45 /* Headers */,
+ B5A7525D08AF4A4A00138E45 /* Sources */,
+ B5A7525F08AF4A4A00138E45 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = ImageDiff;
+ productInstallPath = "$(HOME)/bin";
+ productName = DumpRenderTree;
+ productReference = B5A7526708AF4A4A00138E45 /* ImageDiff */;
+ productType = "com.apple.product-type.tool";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 08FB7793FE84155DC02AAC07 /* Project object */ = {
+ isa = PBXProject;
+ buildConfigurationList = 149C29C308902C6D008A9EFC /* Build configuration list for PBXProject "DumpRenderTree" */;
+ compatibilityVersion = "Xcode 2.4";
+ hasScannedForEncodings = 1;
+ mainGroup = 08FB7794FE84155DC02AAC07 /* DumpRenderTree */;
+ productRefGroup = 9340995508540CAF007F3BC8 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ A84F608D08B1370600E9745F /* All */,
+ 9340994A08540CAE007F3BC8 /* DumpRenderTree */,
+ B5A7525A08AF4A4A00138E45 /* ImageDiff */,
+ 141BF21E096A441D00E0753C /* TestNetscapePlugIn */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 141BF21B096A441D00E0753C /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 141BF44C096A45C800E0753C /* Info.plist in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 141BF21C096A441D00E0753C /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 1AC6C8490D07638600CD3161 /* main.cpp in Sources */,
+ 1AC6C84A0D07638600CD3161 /* PluginObject.cpp in Sources */,
+ 1AC6C84B0D07638600CD3161 /* TestObject.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 9340994D08540CAE007F3BC8 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ BCA18B390C9B021900114369 /* AppleScriptController.m in Sources */,
+ BCA18C470C9B5B9400114369 /* DumpRenderTree.mm in Sources */,
+ BCA18B7B0C9B08F100114369 /* DumpRenderTreeDraggingInfo.mm in Sources */,
+ BCA18B620C9B08C200114369 /* EditingDelegate.mm in Sources */,
+ BCA18B700C9B08DB00114369 /* EventSendingController.mm in Sources */,
+ BCA18B640C9B08C200114369 /* FrameLoadDelegate.mm in Sources */,
+ BCF6C6500C98E9C000AC063E /* GCController.cpp in Sources */,
+ BCA18B230C9B014B00114369 /* GCControllerMac.mm in Sources */,
+ BC0131DA0C9772010087317D /* LayoutTestController.cpp in Sources */,
+ BCA18B240C9B014B00114369 /* LayoutTestControllerMac.mm in Sources */,
+ BCA18B720C9B08DB00114369 /* NavigationController.m in Sources */,
+ BCA18B320C9B01B400114369 /* ObjCController.m in Sources */,
+ BCA18B7E0C9B08F100114369 /* ObjCPlugin.m in Sources */,
+ BCA18B800C9B08F100114369 /* ObjCPluginFunction.m in Sources */,
+ BCA18B660C9B08C200114369 /* PolicyDelegate.mm in Sources */,
+ BCA18B680C9B08C200114369 /* ResourceLoadDelegate.mm in Sources */,
+ BCA18B490C9B02C400114369 /* TextInputController.m in Sources */,
+ BCA18B6A0C9B08C200114369 /* UIDelegate.mm in Sources */,
+ BC9D90240C97472E0099A4A3 /* WorkQueue.cpp in Sources */,
+ BCA18B260C9B015C00114369 /* WorkQueueItemMac.mm in Sources */,
+ A8B91ADA0CF3B32F008F91FF /* DumpRenderTreePasteboard.m in Sources */,
+ A8B91ADC0CF3B32F008F91FF /* DumpRenderTreeWindow.mm in Sources */,
+ A8B91BFD0CF522B4008F91FF /* CheckedMalloc.cpp in Sources */,
+ BCB284CD0CFA83C8007E533E /* PixelDumpSupportCG.cpp in Sources */,
+ BCB284D60CFA83D1007E533E /* PixelDumpSupportMac.mm in Sources */,
+ BC4741410D038A570072B006 /* JavaScriptThreadingPthreads.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B5A7525D08AF4A4A00138E45 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ BCB284F60CFA84F8007E533E /* ImageDiffCG.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ 141BF238096A451E00E0753C /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 141BF21E096A441D00E0753C /* TestNetscapePlugIn */;
+ targetProxy = 141BF237096A451E00E0753C /* PBXContainerItemProxy */;
+ };
+ A84F608F08B1370E00E9745F /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = B5A7525A08AF4A4A00138E45 /* ImageDiff */;
+ targetProxy = A84F608E08B1370E00E9745F /* PBXContainerItemProxy */;
+ };
+ A84F609108B1370E00E9745F /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 9340994A08540CAE007F3BC8 /* DumpRenderTree */;
+ targetProxy = A84F609008B1370E00E9745F /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+ 141BF222096A441E00E0753C /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = BCB283DE0CFA7C20007E533E /* TestNetscapePlugIn.xcconfig */;
+ buildSettings = {
+ };
+ name = Debug;
+ };
+ 141BF223096A441E00E0753C /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = BCB283DE0CFA7C20007E533E /* TestNetscapePlugIn.xcconfig */;
+ buildSettings = {
+ };
+ name = Release;
+ };
+ 149C29C008902C6D008A9EFC /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = BCB281F00CFA713D007E533E /* DumpRenderTree.xcconfig */;
+ buildSettings = {
+ };
+ name = Debug;
+ };
+ 149C29C108902C6D008A9EFC /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = BCB281F00CFA713D007E533E /* DumpRenderTree.xcconfig */;
+ buildSettings = {
+ };
+ name = Release;
+ };
+ 149C29C408902C6D008A9EFC /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = BCB282F40CFA7450007E533E /* DebugRelease.xcconfig */;
+ buildSettings = {
+ GCC_OPTIMIZATION_LEVEL = 0;
+ };
+ name = Debug;
+ };
+ 149C29C508902C6D008A9EFC /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = BCB282F40CFA7450007E533E /* DebugRelease.xcconfig */;
+ buildSettings = {
+ };
+ name = Release;
+ };
+ A84F609308B1371400E9745F /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+ OPTIMIZATION_CFLAGS = "-O0";
+ OTHER_CFLAGS = "";
+ OTHER_REZFLAGS = "";
+ PRODUCT_NAME = All;
+ SECTORDER_FLAGS = "";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ };
+ name = Debug;
+ };
+ A84F609408B1371400E9745F /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = YES;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+ OPTIMIZATION_CFLAGS = "-O0";
+ OTHER_CFLAGS = "";
+ OTHER_REZFLAGS = "";
+ PRODUCT_NAME = All;
+ SECTORDER_FLAGS = "";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ };
+ name = Release;
+ };
+ B5A7526508AF4A4A00138E45 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = BCB283D80CFA7AFD007E533E /* ImageDiff.xcconfig */;
+ buildSettings = {
+ };
+ name = Debug;
+ };
+ B5A7526608AF4A4A00138E45 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = BCB283D80CFA7AFD007E533E /* ImageDiff.xcconfig */;
+ buildSettings = {
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 141BF221096A441E00E0753C /* Build configuration list for PBXNativeTarget "TestNetscapePlugIn" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 141BF222096A441E00E0753C /* Debug */,
+ 141BF223096A441E00E0753C /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 149C29BF08902C6D008A9EFC /* Build configuration list for PBXNativeTarget "DumpRenderTree" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 149C29C008902C6D008A9EFC /* Debug */,
+ 149C29C108902C6D008A9EFC /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 149C29C308902C6D008A9EFC /* Build configuration list for PBXProject "DumpRenderTree" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 149C29C408902C6D008A9EFC /* Debug */,
+ 149C29C508902C6D008A9EFC /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A84F609208B1371400E9745F /* Build configuration list for PBXAggregateTarget "All" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A84F609308B1371400E9745F /* Debug */,
+ A84F609408B1371400E9745F /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ B5A7526408AF4A4A00138E45 /* Build configuration list for PBXNativeTarget "ImageDiff" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ B5A7526508AF4A4A00138E45 /* Debug */,
+ B5A7526608AF4A4A00138E45 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
+}
diff --git a/WebKitTools/DumpRenderTree/DumpRenderTreePrefix.h b/WebKitTools/DumpRenderTree/DumpRenderTreePrefix.h
new file mode 100644
index 0000000..cb40968
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/DumpRenderTreePrefix.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2005 Apple Computer, 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.
+ */
+
+#ifdef __OBJC__
+
+#import <Foundation/Foundation.h>
+
+#endif
diff --git a/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/ASCIICType.h b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/ASCIICType.h
new file mode 100644
index 0000000..f2258d2
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/ASCIICType.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/ASCIICType.h>
diff --git a/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Assertions.h b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Assertions.h
new file mode 100644
index 0000000..2144410
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Assertions.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/Assertions.h>
diff --git a/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/HashMap.h b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/HashMap.h
new file mode 100644
index 0000000..9f262e2
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/HashMap.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/HashMap.h>
diff --git a/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/HashSet.h b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/HashSet.h
new file mode 100644
index 0000000..cfe2d80
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/HashSet.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/HashSet.h>
diff --git a/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/HashTraits.h b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/HashTraits.h
new file mode 100755
index 0000000..412fa98
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/HashTraits.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/HashTraits.h>
diff --git a/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/MathExtras.h b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/MathExtras.h
new file mode 100644
index 0000000..2955786
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/MathExtras.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/MathExtras.h>
diff --git a/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Noncopyable.h b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Noncopyable.h
new file mode 100644
index 0000000..f8484d2
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Noncopyable.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/Noncopyable.h>
diff --git a/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/OwnPtr.h b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/OwnPtr.h
new file mode 100644
index 0000000..9211d38
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/OwnPtr.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/OwnPtr.h>
diff --git a/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Platform.h b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Platform.h
new file mode 100644
index 0000000..3b22955
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Platform.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/Platform.h>
diff --git a/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/RetainPtr.h b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/RetainPtr.h
new file mode 100644
index 0000000..65fc27b
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/RetainPtr.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/RetainPtr.h>
diff --git a/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/StringExtras.h b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/StringExtras.h
new file mode 100644
index 0000000..063d500
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/StringExtras.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/StringExtras.h>
diff --git a/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Vector.h b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Vector.h
new file mode 100644
index 0000000..c6d15fd
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Vector.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/Vector.h>
diff --git a/WebKitTools/DumpRenderTree/GCController.cpp b/WebKitTools/DumpRenderTree/GCController.cpp
new file mode 100644
index 0000000..38c45bf
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/GCController.cpp
@@ -0,0 +1,108 @@
+/*
+ * 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 "DumpRenderTree.h"
+#include "GCController.h"
+
+#include <JavaScriptCore/JSObjectRef.h>
+#include <JavaScriptCore/JSRetainPtr.h>
+
+GCController::GCController()
+{
+}
+
+GCController::~GCController()
+{
+}
+
+// Static Functions
+
+static JSValueRef collectCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ GCController* controller = reinterpret_cast<GCController*>(JSObjectGetPrivate(thisObject));
+ controller->collect();
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef collectOnAlternateThreadCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ bool waitUntilDone = false;
+ if (argumentCount > 0)
+ waitUntilDone = JSValueToBoolean(context, arguments[0]);
+
+ GCController* controller = reinterpret_cast<GCController*>(JSObjectGetPrivate(thisObject));
+ controller->collectOnAlternateThread(waitUntilDone);
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef getJSObjectCountCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ GCController* controller = reinterpret_cast<GCController*>(JSObjectGetPrivate(thisObject));
+ size_t jsObjectCount = controller->getJSObjectCount();
+
+ return JSValueMakeNumber(context, jsObjectCount);
+}
+
+// Object Creation
+
+void GCController::makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> gcControllerStr(Adopt, JSStringCreateWithUTF8CString("GCController"));
+ JSValueRef gcControllerObject = JSObjectMake(context, getJSClass(), this);
+ JSObjectSetProperty(context, windowObject, gcControllerStr.get(), gcControllerObject, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, exception);
+}
+
+JSClassRef GCController::getJSClass()
+{
+ static JSClassRef gcControllerClass = 0;
+
+ if (!gcControllerClass) {
+ JSStaticFunction* staticFunctions = GCController::staticFunctions();
+ JSClassDefinition classDefinition = {
+ 0, kJSClassAttributeNone, "GCController", 0, 0, staticFunctions,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+
+ gcControllerClass = JSClassCreate(&classDefinition);
+ }
+
+ return gcControllerClass;
+}
+
+JSStaticFunction* GCController::staticFunctions()
+{
+ static JSStaticFunction staticFunctions[] = {
+ { "collect", collectCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "collectOnAlternateThread", collectOnAlternateThreadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "getJSObjectCount", getJSObjectCountCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { 0, 0, 0 }
+ };
+
+ return staticFunctions;
+}
diff --git a/WebKitTools/DumpRenderTree/GCController.h b/WebKitTools/DumpRenderTree/GCController.h
new file mode 100644
index 0000000..4284275
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/GCController.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2006 Apple Computer, 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 GCController_h
+#define GCController_h
+
+#include <JavaScriptCore/JSObjectRef.h>
+
+class GCController {
+public:
+ GCController();
+ ~GCController();
+
+ void makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception);
+
+ // Controller Methods - platfrom independant implementations
+ void collect() const;
+ void collectOnAlternateThread(bool waitUntilDone) const;
+ size_t getJSObjectCount() const;
+
+private:
+ static JSClassRef getJSClass();
+ static JSStaticFunction* staticFunctions();
+};
+
+#endif // GCController_h
diff --git a/WebKitTools/DumpRenderTree/JavaScriptThreading.h b/WebKitTools/DumpRenderTree/JavaScriptThreading.h
new file mode 100644
index 0000000..43795a1
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/JavaScriptThreading.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
+ * (C) 2007 Graham Dennis (graham.dennis@gmail.com)
+ * (C) 2007 Eric Seidel <eric@webkit.org>
+ *
+ * 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 JavaScriptThreading_h
+#define JavaScriptThreading_h
+
+/* These functions start/stop threads used to abuse the JavaScript interpreter
+ and assure that our JS implementation remains threadsafe */
+
+void startJavaScriptThreads();
+void stopJavaScriptThreads();
+
+#endif // JavaScriptThreading_h
diff --git a/WebKitTools/DumpRenderTree/LayoutTestController.cpp b/WebKitTools/DumpRenderTree/LayoutTestController.cpp
new file mode 100644
index 0000000..4920066
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/LayoutTestController.cpp
@@ -0,0 +1,720 @@
+/*
+ * 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 "DumpRenderTree.h"
+#include "LayoutTestController.h"
+
+#include <JavaScriptCore/JSObjectRef.h>
+#include <JavaScriptCore/JSRetainPtr.h>
+#include <wtf/Assertions.h>
+#include <wtf/MathExtras.h>
+
+LayoutTestController::LayoutTestController(bool testRepaintDefault, bool testRepaintSweepHorizontallyDefault)
+ : m_dumpAsText(false)
+ , m_dumpBackForwardList(false)
+ , m_dumpChildFrameScrollPositions(false)
+ , m_dumpChildFramesAsText(false)
+ , m_dumpDatabaseCallbacks(false)
+ , m_dumpDOMAsWebArchive(false)
+ , m_dumpSelectionRect(false)
+ , m_dumpSourceAsWebArchive(false)
+ , m_dumpStatusCallbacks(false)
+ , m_dumpTitleChanges(false)
+ , m_dumpEditingCallbacks(false)
+ , m_dumpResourceLoadCallbacks(false)
+ , m_dumpFrameLoadCallbacks(false)
+ , m_addFileToPasteboardOnDrag(false)
+ , m_callCloseOnWebViews(true)
+ , m_canOpenWindows(false)
+ , m_closeRemainingWindowsWhenComplete(true)
+ , m_testRepaint(testRepaintDefault)
+ , m_testRepaintSweepHorizontally(testRepaintSweepHorizontallyDefault)
+ , m_waitToDump(false)
+ , m_windowIsKey(true)
+ , m_globalFlag(false)
+{
+}
+
+// Static Functions
+
+static JSValueRef dumpAsTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setDumpAsText(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef dumpBackForwardListCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setDumpBackForwardList(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef dumpChildFramesAsTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setDumpChildFramesAsText(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef dumpChildFrameScrollPositionsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setDumpChildFrameScrollPositions(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef dumpDatabaseCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setDumpDatabaseCallbacks(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef dumpDOMAsWebArchiveCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setDumpDOMAsWebArchive(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef dumpEditingCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setDumpEditingCallbacks(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef dumpFrameLoadCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setDumpFrameLoadCallbacks(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef dumpResourceLoadCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setDumpResourceLoadCallbacks(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef dumpSelectionRectCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setDumpSelectionRect(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef dumpSourceAsWebArchiveCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setDumpSourceAsWebArchive(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef dumpStatusCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setDumpStatusCallbacks(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef dumpTitleChangesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setDumpTitleChanges(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef pathToLocalResourceCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ JSRetainPtr<JSStringRef> localPath(Adopt, JSValueToStringCopy(context, arguments[0], exception));
+ ASSERT(!*exception);
+
+ JSRetainPtr<JSStringRef> convertedPath(Adopt, controller->pathToLocalResource(context, localPath.get()));
+ if (!convertedPath)
+ return JSValueMakeUndefined(context);
+
+ return JSValueMakeString(context, convertedPath.get());
+}
+
+static JSValueRef repaintSweepHorizontallyCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setTestRepaintSweepHorizontally(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef setCallCloseOnWebViewsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setCallCloseOnWebViews(JSValueToBoolean(context, arguments[0]));
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef setCanOpenWindowsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setCanOpenWindows(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef setCloseRemainingWindowsWhenCompleteCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setCloseRemainingWindowsWhenComplete(JSValueToBoolean(context, arguments[0]));
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef testRepaintCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setTestRepaint(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef addFileToPasteboardOnDragCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setAddFileToPasteboardOnDrag(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef addDisallowedURLCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ JSRetainPtr<JSStringRef> url(Adopt, JSValueToStringCopy(context, arguments[0], exception));
+ ASSERT(!*exception);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->addDisallowedURL(url.get());
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef clearAllDatabasesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->clearAllDatabases();
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef clearBackForwardListCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->clearBackForwardList();
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef clearPersistentUserStyleSheetCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->clearPersistentUserStyleSheet();
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef decodeHostNameCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
+ ASSERT(!*exception);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ JSRetainPtr<JSStringRef> decodedHostName(Adopt, controller->copyDecodedHostName(name.get()));
+ return JSValueMakeString(context, decodedHostName.get());
+}
+
+static JSValueRef displayCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->display();
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef encodeHostNameCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
+ ASSERT(!*exception);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ JSRetainPtr<JSStringRef> encodedHostName(Adopt, controller->copyEncodedHostName(name.get()));
+ return JSValueMakeString(context, encodedHostName.get());
+}
+
+static JSValueRef execCommandCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has Mac & Windows implementations.
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
+ ASSERT(!*exception);
+
+ // Ignoring the second parameter (userInterface), as this command emulates a manual action.
+
+ JSRetainPtr<JSStringRef> value;
+ if (argumentCount >= 3) {
+ value.adopt(JSValueToStringCopy(context, arguments[2], exception));
+ ASSERT(!*exception);
+ } else
+ value.adopt(JSStringCreateWithUTF8CString(""));
+
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->execCommand(name.get(), value.get());
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef keepWebHistoryCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac implementation
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->keepWebHistory();
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef notifyDoneCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ // May be able to be made platform independant by using shared WorkQueue
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->notifyDone();
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef queueBackNavigationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ // May be able to be made platform independant by using shared WorkQueue
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ double howFarBackDouble = JSValueToNumber(context, arguments[0], exception);
+ ASSERT(!*exception);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->queueBackNavigation(static_cast<int>(howFarBackDouble));
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef queueForwardNavigationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ // May be able to be made platform independant by using shared WorkQueue
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ double howFarForwardDouble = JSValueToNumber(context, arguments[0], exception);
+ ASSERT(!*exception);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->queueForwardNavigation(static_cast<int>(howFarForwardDouble));
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef queueLoadCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ // May be able to be made platform independant by using shared WorkQueue
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ JSRetainPtr<JSStringRef> url(Adopt, JSValueToStringCopy(context, arguments[0], exception));
+ ASSERT(!*exception);
+
+ JSRetainPtr<JSStringRef> target;
+ if (argumentCount >= 2) {
+ target.adopt(JSValueToStringCopy(context, arguments[1], exception));
+ ASSERT(!*exception);
+ } else
+ target.adopt(JSStringCreateWithUTF8CString(""));
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->queueLoad(url.get(), target.get());
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef queueReloadCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ // May be able to be made platform independant by using shared WorkQueue
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->queueReload();
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef queueScriptCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ // May be able to be made platform independant by using shared WorkQueue
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ JSRetainPtr<JSStringRef> script(Adopt, JSValueToStringCopy(context, arguments[0], exception));
+ ASSERT(!*exception);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->queueScript(script.get());
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef setAcceptsEditingCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setAcceptsEditing(JSValueToBoolean(context, arguments[0]));
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef setAuthorAndUserStylesEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setAuthorAndUserStylesEnabled(JSValueToBoolean(context, arguments[0]));
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef setCustomPolicyDelegateCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setCustomPolicyDelegate(JSValueToBoolean(context, arguments[0]));
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef setDatabaseQuotaCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+
+ double quota = JSValueToNumber(context, arguments[0], NULL);
+ if (!isnan(quota))
+ controller->setDatabaseQuota(static_cast<unsigned long long>(quota));
+
+ return JSValueMakeUndefined(context);
+
+}
+
+static JSValueRef setMainFrameIsFirstResponderCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setMainFrameIsFirstResponder(JSValueToBoolean(context, arguments[0]));
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef setPersistentUserStyleSheetLocationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ JSRetainPtr<JSStringRef> path(Adopt, JSValueToStringCopy(context, arguments[0], exception));
+ ASSERT(!*exception);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setPersistentUserStyleSheetLocation(path.get());
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef setPrivateBrowsingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setPrivateBrowsingEnabled(JSValueToBoolean(context, arguments[0]));
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef setTabKeyCyclesThroughElementsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setTabKeyCyclesThroughElements(JSValueToBoolean(context, arguments[0]));
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef setUseDashboardCompatibilityModeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setUseDashboardCompatibilityMode(JSValueToBoolean(context, arguments[0]));
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef setUserStyleSheetEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setUserStyleSheetEnabled(JSValueToBoolean(context, arguments[0]));
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef setUserStyleSheetLocationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ JSRetainPtr<JSStringRef> path(Adopt, JSValueToStringCopy(context, arguments[0], exception));
+ ASSERT(!*exception);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setUserStyleSheetLocation(path.get());
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef setWindowIsKeyCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setWindowIsKey(JSValueToBoolean(context, arguments[0]));
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef waitUntilDoneCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setWaitToDump(true);
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef windowCountCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac implementation
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ int windows = controller->windowCount();
+ return JSValueMakeNumber(context, windows);
+}
+
+static JSValueRef setPopupBlockingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setPopupBlockingEnabled(JSValueToBoolean(context, arguments[0]));
+
+ return JSValueMakeUndefined(context);
+}
+
+
+// Static Values
+
+static JSValueRef getGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ return JSValueMakeBoolean(context, controller->globalFlag());
+}
+
+static bool setGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setGlobalFlag(JSValueToBoolean(context, value));
+ return true;
+}
+
+// Object Creation
+
+void LayoutTestController::makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> layoutTestContollerStr(Adopt, JSStringCreateWithUTF8CString("layoutTestController"));
+ JSValueRef layoutTestContollerObject = JSObjectMake(context, getJSClass(), this);
+ JSObjectSetProperty(context, windowObject, layoutTestContollerStr.get(), layoutTestContollerObject, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, exception);
+}
+
+JSClassRef LayoutTestController::getJSClass()
+{
+ static JSClassRef layoutTestControllerClass;
+
+ if (!layoutTestControllerClass) {
+ JSStaticValue* staticValues = LayoutTestController::staticValues();
+ JSStaticFunction* staticFunctions = LayoutTestController::staticFunctions();
+ JSClassDefinition classDefinition = {
+ 0, kJSClassAttributeNone, "LayoutTestController", 0, staticValues, staticFunctions,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+
+ layoutTestControllerClass = JSClassCreate(&classDefinition);
+ }
+
+ return layoutTestControllerClass;
+}
+
+JSStaticValue* LayoutTestController::staticValues()
+{
+ static JSStaticValue staticValues[] = {
+ { "globalFlag", getGlobalFlagCallback, setGlobalFlagCallback, kJSPropertyAttributeNone },
+ { 0, 0, 0, 0 }
+ };
+ return staticValues;
+
+}
+
+JSStaticFunction* LayoutTestController::staticFunctions()
+{
+ static JSStaticFunction staticFunctions[] = {
+ { "addDisallowedURL", addDisallowedURLCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "addFileToPasteboardOnDrag", addFileToPasteboardOnDragCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "clearAllDatabases", clearAllDatabasesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "clearBackForwardList", clearBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "clearPersistentUserStyleSheet", clearPersistentUserStyleSheetCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "decodeHostName", decodeHostNameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "display", displayCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "dumpAsText", dumpAsTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "dumpBackForwardList", dumpBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "dumpChildFramesAsText", dumpChildFramesAsTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "dumpChildFrameScrollPositions", dumpChildFrameScrollPositionsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "dumpDatabaseCallbacks", dumpDatabaseCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "dumpDOMAsWebArchive", dumpDOMAsWebArchiveCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "dumpEditingCallbacks", dumpEditingCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "dumpFrameLoadCallbacks", dumpFrameLoadCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "dumpResourceLoadCallbacks", dumpResourceLoadCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "dumpSelectionRect", dumpSelectionRectCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "dumpSourceAsWebArchive", dumpSourceAsWebArchiveCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "dumpStatusCallbacks", dumpStatusCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "dumpTitleChanges", dumpTitleChangesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "encodeHostName", encodeHostNameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "execCommand", execCommandCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "keepWebHistory", keepWebHistoryCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "notifyDone", notifyDoneCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "pathToLocalResource", pathToLocalResourceCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "queueBackNavigation", queueBackNavigationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "queueForwardNavigation", queueForwardNavigationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "queueLoad", queueLoadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "queueReload", queueReloadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "queueScript", queueScriptCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "repaintSweepHorizontally", repaintSweepHorizontallyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setAcceptsEditing", setAcceptsEditingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setAuthorAndUserStylesEnabled", setAuthorAndUserStylesEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setCallCloseOnWebViews", setCallCloseOnWebViewsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setCanOpenWindows", setCanOpenWindowsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setCloseRemainingWindowsWhenComplete", setCloseRemainingWindowsWhenCompleteCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setCustomPolicyDelegate", setCustomPolicyDelegateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setDatabaseQuota", setDatabaseQuotaCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setMainFrameIsFirstResponder", setMainFrameIsFirstResponderCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setPersistentUserStyleSheetLocation", setPersistentUserStyleSheetLocationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setPrivateBrowsingEnabled", setPrivateBrowsingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setPopupBlockingEnabled", setPopupBlockingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setTabKeyCyclesThroughElements", setTabKeyCyclesThroughElementsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setUseDashboardCompatibilityMode", setUseDashboardCompatibilityModeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setUserStyleSheetEnabled", setUserStyleSheetEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setUserStyleSheetLocation", setUserStyleSheetLocationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setWindowIsKey", setWindowIsKeyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "testRepaint", testRepaintCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "waitUntilDone", waitUntilDoneCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "windowCount", windowCountCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { 0, 0, 0 }
+ };
+
+ return staticFunctions;
+}
+
+
diff --git a/WebKitTools/DumpRenderTree/LayoutTestController.h b/WebKitTools/DumpRenderTree/LayoutTestController.h
new file mode 100644
index 0000000..754d8ce
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/LayoutTestController.h
@@ -0,0 +1,168 @@
+/*
+ * 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 LayoutTestController_h
+#define LayoutTestController_h
+
+#include <JavaScriptCore/JSObjectRef.h>
+
+class LayoutTestController {
+public:
+ LayoutTestController(bool testRepaintDefault, bool testRepaintSweepHorizontallyDefault);
+ ~LayoutTestController();
+
+ void makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception);
+
+ // Controller Methods - platfrom independant implementations
+ void addDisallowedURL(JSStringRef url);
+ void clearAllDatabases();
+ void clearBackForwardList();
+ JSStringRef copyDecodedHostName(JSStringRef name);
+ JSStringRef copyEncodedHostName(JSStringRef name);
+ void execCommand(JSStringRef name, JSStringRef value);
+ void display();
+ void keepWebHistory();
+ void notifyDone();
+ JSStringRef pathToLocalResource(JSContextRef, JSStringRef url);
+ void queueBackNavigation(int howFarBackward);
+ void queueForwardNavigation(int howFarForward);
+ void queueLoad(JSStringRef url, JSStringRef target);
+ void queueReload();
+ void queueScript(JSStringRef url);
+ void setAcceptsEditing(bool acceptsEditing);
+ void setAuthorAndUserStylesEnabled(bool);
+ void setCustomPolicyDelegate(bool setDelegate);
+ void setDatabaseQuota(unsigned long long quota);
+ void setMainFrameIsFirstResponder(bool flag);
+ void setPrivateBrowsingEnabled(bool flag);
+ void setPopupBlockingEnabled(bool flag);
+ void setTabKeyCyclesThroughElements(bool cycles);
+ void setUseDashboardCompatibilityMode(bool flag);
+ void setUserStyleSheetEnabled(bool flag);
+ void setUserStyleSheetLocation(JSStringRef path);
+ void setPersistentUserStyleSheetLocation(JSStringRef path);
+ void clearPersistentUserStyleSheet();
+ int windowCount();
+
+ bool dumpAsText() const { return m_dumpAsText; }
+ void setDumpAsText(bool dumpAsText) { m_dumpAsText = dumpAsText; }
+
+ bool dumpBackForwardList() const { return m_dumpBackForwardList; }
+ void setDumpBackForwardList(bool dumpBackForwardList) { m_dumpBackForwardList = dumpBackForwardList; }
+
+ bool dumpChildFrameScrollPositions() const { return m_dumpChildFrameScrollPositions; }
+ void setDumpChildFrameScrollPositions(bool dumpChildFrameScrollPositions) { m_dumpChildFrameScrollPositions = dumpChildFrameScrollPositions; }
+
+ bool dumpChildFramesAsText() const { return m_dumpChildFramesAsText; }
+ void setDumpChildFramesAsText(bool dumpChildFramesAsText) { m_dumpChildFramesAsText = dumpChildFramesAsText; }
+
+ bool dumpDatabaseCallbacks() const { return m_dumpDatabaseCallbacks; }
+ void setDumpDatabaseCallbacks(bool dumpDatabaseCallbacks) { m_dumpDatabaseCallbacks = dumpDatabaseCallbacks; }
+
+ bool dumpStatusCallbacks() const { return m_dumpStatusCallbacks; }
+ void setDumpStatusCallbacks(bool dumpStatusCallbacks) { m_dumpStatusCallbacks = dumpStatusCallbacks; }
+
+ bool dumpDOMAsWebArchive() const { return m_dumpDOMAsWebArchive; }
+ void setDumpDOMAsWebArchive(bool dumpDOMAsWebArchive) { m_dumpDOMAsWebArchive = dumpDOMAsWebArchive; }
+
+ bool dumpSelectionRect() const { return m_dumpSelectionRect; }
+ void setDumpSelectionRect(bool dumpSelectionRect) { m_dumpSelectionRect = dumpSelectionRect; }
+
+ bool dumpSourceAsWebArchive() const { return m_dumpSourceAsWebArchive; }
+ void setDumpSourceAsWebArchive(bool dumpSourceAsWebArchive) { m_dumpSourceAsWebArchive = dumpSourceAsWebArchive; }
+
+ bool dumpTitleChanges() const { return m_dumpTitleChanges; }
+ void setDumpTitleChanges(bool dumpTitleChanges) { m_dumpTitleChanges = dumpTitleChanges; }
+
+ bool dumpEditingCallbacks() const { return m_dumpEditingCallbacks; }
+ void setDumpEditingCallbacks(bool dumpEditingCallbacks) { m_dumpEditingCallbacks = dumpEditingCallbacks; }
+
+ bool dumpResourceLoadCallbacks() const { return m_dumpResourceLoadCallbacks; }
+ void setDumpResourceLoadCallbacks(bool dumpResourceLoadCallbacks) { m_dumpResourceLoadCallbacks = dumpResourceLoadCallbacks; }
+
+ bool dumpFrameLoadCallbacks() const { return m_dumpFrameLoadCallbacks; }
+ void setDumpFrameLoadCallbacks(bool dumpFrameLoadCallbacks) { m_dumpFrameLoadCallbacks = dumpFrameLoadCallbacks; }
+
+ bool addFileToPasteboardOnDrag() const { return m_addFileToPasteboardOnDrag; }
+ void setAddFileToPasteboardOnDrag(bool addFileToPasteboardOnDrag) { m_addFileToPasteboardOnDrag = addFileToPasteboardOnDrag; }
+
+ bool callCloseOnWebViews() const { return m_callCloseOnWebViews; }
+ void setCallCloseOnWebViews(bool callCloseOnWebViews) { m_callCloseOnWebViews = callCloseOnWebViews; }
+
+ bool canOpenWindows() const { return m_canOpenWindows; }
+ void setCanOpenWindows(bool canOpenWindows) { m_canOpenWindows = canOpenWindows; }
+
+ bool closeRemainingWindowsWhenComplete() const { return m_closeRemainingWindowsWhenComplete; }
+ void setCloseRemainingWindowsWhenComplete(bool closeRemainingWindowsWhenComplete) { m_closeRemainingWindowsWhenComplete = closeRemainingWindowsWhenComplete; }
+
+ bool testRepaint() const { return m_testRepaint; }
+ void setTestRepaint(bool testRepaint) { m_testRepaint = testRepaint; }
+
+ bool testRepaintSweepHorizontally() const { return m_testRepaintSweepHorizontally; }
+ void setTestRepaintSweepHorizontally(bool testRepaintSweepHorizontally) { m_testRepaintSweepHorizontally = testRepaintSweepHorizontally; }
+
+ bool waitToDump() const { return m_waitToDump; }
+ void setWaitToDump(bool waitToDump);
+
+ bool windowIsKey() const { return m_windowIsKey; }
+ void setWindowIsKey(bool windowIsKey);
+
+ bool globalFlag() const { return m_globalFlag; }
+ void setGlobalFlag(bool globalFlag) { m_globalFlag = globalFlag; }
+
+private:
+ bool m_dumpAsText;
+ bool m_dumpBackForwardList;
+ bool m_dumpChildFrameScrollPositions;
+ bool m_dumpChildFramesAsText;
+ bool m_dumpDatabaseCallbacks;
+ bool m_dumpDOMAsWebArchive;
+ bool m_dumpSelectionRect;
+ bool m_dumpSourceAsWebArchive;
+ bool m_dumpStatusCallbacks;
+ bool m_dumpTitleChanges;
+ bool m_dumpEditingCallbacks;
+ bool m_dumpResourceLoadCallbacks;
+ bool m_dumpFrameLoadCallbacks;
+ bool m_addFileToPasteboardOnDrag;
+ bool m_callCloseOnWebViews;
+ bool m_canOpenWindows;
+ bool m_closeRemainingWindowsWhenComplete;
+ bool m_testRepaint;
+ bool m_testRepaintSweepHorizontally;
+ bool m_waitToDump; // True if waitUntilDone() has been called, but notifyDone() has not yet been called.
+ bool m_windowIsKey;
+
+ bool m_globalFlag;
+
+ static JSClassRef getJSClass();
+ static JSStaticValue* staticValues();
+ static JSStaticFunction* staticFunctions();
+};
+
+#endif // LayoutTestController_h
diff --git a/WebKitTools/DumpRenderTree/Makefile b/WebKitTools/DumpRenderTree/Makefile
new file mode 100644
index 0000000..1f1dbbc
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/Makefile
@@ -0,0 +1,2 @@
+SCRIPTS_PATH = ../Scripts
+include ../../Makefile.shared
diff --git a/WebKitTools/DumpRenderTree/PixelDumpSupport.h b/WebKitTools/DumpRenderTree/PixelDumpSupport.h
new file mode 100644
index 0000000..3214d04
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/PixelDumpSupport.h
@@ -0,0 +1,40 @@
+/*
+ * 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 PixelDumpSupport_h
+#define PixelDumpSupport_h
+
+void dumpWebViewAsPixelsAndCompareWithExpected(const char* currentTest, bool forceAllTestsToDumpPixels);
+
+// Can be used as a signal handler
+void restoreColorSpace(int ignored);
+
+// May change your color space, requiring a call to restoreColorSpace
+void initializeColorSpaceAndScreeBufferForPixelTests();
+
+#endif // PixelDumpSupport_h
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/Info.plist b/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/Info.plist
new file mode 100644
index 0000000..1f4cfe3
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/Info.plist
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>TestNetscapePlugIn</string>
+ <key>CFBundleGetInfoString</key>
+ <string>420+, Copyright 2006 Apple Computer, Inc.</string>
+ <key>CFBundleIconFile</key>
+ <string></string>
+ <key>CFBundleIdentifier</key>
+ <string>com.apple.testnetscapeplugin</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>BRPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>CFPlugInDynamicRegisterFunction</key>
+ <string></string>
+ <key>CFPlugInDynamicRegistration</key>
+ <string>NO</string>
+ <key>CFPlugInFactories</key>
+ <dict>
+ <key>00000000-0000-0000-0000-000000000000</key>
+ <string>MyFactoryFunction</string>
+ </dict>
+ <key>CFPlugInTypes</key>
+ <dict>
+ <key>00000000-0000-0000-0000-000000000000</key>
+ <array>
+ <string>00000000-0000-0000-0000-000000000000</string>
+ </array>
+ </dict>
+ <key>CFPlugInUnloadFunction</key>
+ <string></string>
+ <key>WebPluginDescription</key>
+ <string>Simple Netscape plug-in that handles test content for WebKit</string>
+ <key>WebPluginMIMETypes</key>
+ <dict>
+ <key>application/x-webkit-test-netscape</key>
+ <dict>
+ <key>WebPluginExtensions</key>
+ <array>
+ <string>testnetscape</string>
+ </array>
+ <key>WebPluginTypeDescription</key>
+ <string>test netscape content</string>
+ </dict>
+ </dict>
+ <key>WebPluginName</key>
+ <string>WebKit Test PlugIn</string>
+</dict>
+</plist>
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.cpp
new file mode 100644
index 0000000..20c0e53
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.cpp
@@ -0,0 +1,470 @@
+/*
+ * 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 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 "PluginObject.h"
+
+#include "TestObject.h"
+#include <assert.h>
+#include <stdio.h>
+
+static void pluginInvalidate(NPObject *obj);
+static bool pluginHasProperty(NPObject *obj, NPIdentifier name);
+static bool pluginHasMethod(NPObject *obj, NPIdentifier name);
+static bool pluginGetProperty(NPObject *obj, NPIdentifier name, NPVariant *variant);
+static bool pluginSetProperty(NPObject *obj, NPIdentifier name, const NPVariant *variant);
+static bool pluginInvoke(NPObject *obj, NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result);
+static bool pluginInvokeDefault(NPObject *obj, const NPVariant *args, uint32_t argCount, NPVariant *result);
+static NPObject *pluginAllocate(NPP npp, NPClass *theClass);
+static void pluginDeallocate(NPObject *obj);
+
+NPNetscapeFuncs *browser;
+
+static NPClass pluginClass = {
+ NP_CLASS_STRUCT_VERSION,
+ pluginAllocate,
+ pluginDeallocate,
+ pluginInvalidate,
+ pluginHasMethod,
+ pluginInvoke,
+ pluginInvokeDefault,
+ pluginHasProperty,
+ pluginGetProperty,
+ pluginSetProperty,
+};
+
+NPClass *getPluginClass(void)
+{
+ return &pluginClass;
+}
+
+static bool identifiersInitialized = false;
+
+#define ID_PROPERTY_PROPERTY 0
+#define ID_PROPERTY_EVENT_LOGGING 1
+#define ID_PROPERTY_HAS_STREAM 2
+#define ID_PROPERTY_TEST_OBJECT 3
+#define ID_PROPERTY_LOG_DESTROY 4
+#define NUM_PROPERTY_IDENTIFIERS 5
+
+static NPIdentifier pluginPropertyIdentifiers[NUM_PROPERTY_IDENTIFIERS];
+static const NPUTF8 *pluginPropertyIdentifierNames[NUM_PROPERTY_IDENTIFIERS] = {
+ "property",
+ "eventLoggingEnabled",
+ "hasStream",
+ "testObject",
+ "logDestroy",
+};
+
+#define ID_TEST_CALLBACK_METHOD 0
+#define ID_TEST_GETURL 1
+#define ID_REMOVE_DEFAULT_METHOD 2
+#define ID_TEST_DOM_ACCESS 3
+#define ID_TEST_GET_URL_NOTIFY 4
+#define ID_TEST_INVOKE_DEFAULT 5
+#define ID_DESTROY_STREAM 6
+#define ID_TEST_ENUMERATE 7
+#define ID_TEST_GETINTIDENTIFIER 8
+#define ID_TEST_GET_PROPERTY 9
+#define ID_TEST_EVALUATE 10
+#define ID_TEST_GET_PROPERTY_RETURN_VALUE 11
+#define NUM_METHOD_IDENTIFIERS 12
+
+static NPIdentifier pluginMethodIdentifiers[NUM_METHOD_IDENTIFIERS];
+static const NPUTF8 *pluginMethodIdentifierNames[NUM_METHOD_IDENTIFIERS] = {
+ "testCallback",
+ "getURL",
+ "removeDefaultMethod",
+ "testDOMAccess",
+ "getURLNotify",
+ "testInvokeDefault",
+ "destroyStream",
+ "testEnumerate",
+ "testGetIntIdentifier",
+ "testGetProperty",
+ "testEvaluate",
+ "testGetPropertyReturnValue",
+};
+
+static NPUTF8* createCStringFromNPVariant(const NPVariant *variant)
+{
+ size_t length = NPVARIANT_TO_STRING(*variant).UTF8Length;
+ NPUTF8* result = (NPUTF8*)malloc(length + 1);
+ memcpy(result, NPVARIANT_TO_STRING(*variant).UTF8Characters, length);
+ result[length] = '\0';
+ return result;
+}
+
+static void initializeIdentifiers(void)
+{
+ browser->getstringidentifiers(pluginPropertyIdentifierNames, NUM_PROPERTY_IDENTIFIERS, pluginPropertyIdentifiers);
+ browser->getstringidentifiers(pluginMethodIdentifierNames, NUM_METHOD_IDENTIFIERS, pluginMethodIdentifiers);
+}
+
+static bool pluginHasProperty(NPObject *obj, NPIdentifier name)
+{
+ for (int i = 0; i < NUM_PROPERTY_IDENTIFIERS; i++)
+ if (name == pluginPropertyIdentifiers[i])
+ return true;
+ return false;
+}
+
+static bool pluginHasMethod(NPObject *obj, NPIdentifier name)
+{
+ for (int i = 0; i < NUM_METHOD_IDENTIFIERS; i++)
+ if (name == pluginMethodIdentifiers[i])
+ return true;
+ return false;
+}
+
+static bool pluginGetProperty(NPObject *obj, NPIdentifier name, NPVariant *variant)
+{
+ if (name == pluginPropertyIdentifiers[ID_PROPERTY_PROPERTY]) {
+ STRINGZ_TO_NPVARIANT("property", *variant);
+ return true;
+ } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_EVENT_LOGGING]) {
+ BOOLEAN_TO_NPVARIANT(((PluginObject *)obj)->eventLogging, *variant);
+ return true;
+ } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_LOG_DESTROY]) {
+ BOOLEAN_TO_NPVARIANT(((PluginObject *)obj)->logDestroy, *variant);
+ return true;
+ } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_HAS_STREAM]) {
+ BOOLEAN_TO_NPVARIANT(((PluginObject *)obj)->stream != 0, *variant);
+ return true;
+ } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_TEST_OBJECT]) {
+ NPObject *testObject = ((PluginObject *)obj)->testObject;
+ browser->retainobject(testObject);
+ OBJECT_TO_NPVARIANT(testObject, *variant);
+ return true;
+ }
+ return false;
+}
+
+static bool pluginSetProperty(NPObject *obj, NPIdentifier name, const NPVariant *variant)
+{
+ if (name == pluginPropertyIdentifiers[ID_PROPERTY_EVENT_LOGGING]) {
+ ((PluginObject *)obj)->eventLogging = NPVARIANT_TO_BOOLEAN(*variant);
+ return true;
+ } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_LOG_DESTROY]) {
+ ((PluginObject *)obj)->logDestroy = NPVARIANT_TO_BOOLEAN(*variant);
+ return true;
+ }
+
+ return false;
+}
+
+static void testDOMAccess(PluginObject *obj)
+{
+ // Get plug-in's DOM element
+ NPObject *elementObject;
+ if (browser->getvalue(obj->npp, NPNVPluginElementNPObject, &elementObject) == NPERR_NO_ERROR) {
+ // Get style
+ NPVariant styleVariant;
+ NPIdentifier styleIdentifier = browser->getstringidentifier("style");
+ if (browser->getproperty(obj->npp, elementObject, styleIdentifier, &styleVariant) && NPVARIANT_IS_OBJECT(styleVariant)) {
+ // Set style.border
+ NPIdentifier borderIdentifier = browser->getstringidentifier("border");
+ NPVariant borderVariant;
+ STRINGZ_TO_NPVARIANT("3px solid red", borderVariant);
+ browser->setproperty(obj->npp, NPVARIANT_TO_OBJECT(styleVariant), borderIdentifier, &borderVariant);
+ browser->releasevariantvalue(&styleVariant);
+ }
+
+ browser->releaseobject(elementObject);
+ }
+}
+
+static bool pluginInvoke(NPObject *header, NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result)
+{
+ PluginObject *obj = (PluginObject *)header;
+ if (name == pluginMethodIdentifiers[ID_TEST_CALLBACK_METHOD]) {
+ // call whatever method name we're given
+ if (argCount > 0 && NPVARIANT_IS_STRING(args[0])) {
+ NPObject *windowScriptObject;
+ browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
+
+ NPUTF8* callbackString = createCStringFromNPVariant(&args[0]);
+ NPIdentifier callbackIdentifier = browser->getstringidentifier(callbackString);
+ free(callbackString);
+
+ NPVariant browserResult;
+ browser->invoke(obj->npp, windowScriptObject, callbackIdentifier, 0, 0, &browserResult);
+ browser->releasevariantvalue(&browserResult);
+
+ VOID_TO_NPVARIANT(*result);
+ return true;
+ }
+ } else if (name == pluginMethodIdentifiers[ID_TEST_GETURL]) {
+ if (argCount == 2 && NPVARIANT_IS_STRING(args[0]) && NPVARIANT_IS_STRING(args[1])) {
+ NPUTF8* urlString = createCStringFromNPVariant(&args[0]);
+ NPUTF8* targetString = createCStringFromNPVariant(&args[1]);
+ browser->geturl(obj->npp, urlString, targetString);
+ free(urlString);
+ free(targetString);
+
+ VOID_TO_NPVARIANT(*result);
+ return true;
+ } else if (argCount == 1 && NPVARIANT_IS_STRING(args[0])) {
+ NPUTF8* urlString = createCStringFromNPVariant(&args[0]);
+ browser->geturl(obj->npp, urlString, 0);
+ free(urlString);
+
+ VOID_TO_NPVARIANT(*result);
+ return true;
+ }
+ } else if (name == pluginMethodIdentifiers[ID_REMOVE_DEFAULT_METHOD]) {
+ pluginClass.invokeDefault = 0;
+ VOID_TO_NPVARIANT(*result);
+ return true;
+ } else if (name == pluginMethodIdentifiers[ID_TEST_DOM_ACCESS]) {
+ testDOMAccess(obj);
+ VOID_TO_NPVARIANT(*result);
+ return true;
+ } else if (name == pluginMethodIdentifiers[ID_TEST_GET_URL_NOTIFY]) {
+ if (argCount == 3
+ && NPVARIANT_IS_STRING(args[0])
+ && (NPVARIANT_IS_STRING(args[1]) || NPVARIANT_IS_NULL(args[1]))
+ && NPVARIANT_IS_STRING(args[2])) {
+ NPUTF8* urlString = createCStringFromNPVariant(&args[0]);
+ NPUTF8* targetString = (NPVARIANT_IS_STRING(args[1]) ? createCStringFromNPVariant(&args[1]) : NULL);
+ NPUTF8* callbackString = createCStringFromNPVariant(&args[2]);
+
+ NPIdentifier callbackIdentifier = browser->getstringidentifier(callbackString);
+ browser->geturlnotify(obj->npp, urlString, targetString, callbackIdentifier);
+
+ free(urlString);
+ free(targetString);
+ free(callbackString);
+
+ VOID_TO_NPVARIANT(*result);
+ return true;
+ }
+ } else if (name == pluginMethodIdentifiers[ID_TEST_INVOKE_DEFAULT] && NPVARIANT_IS_OBJECT(args[0])) {
+ NPObject *callback = NPVARIANT_TO_OBJECT(args[0]);
+
+ NPVariant args[1];
+ NPVariant browserResult;
+
+ STRINGZ_TO_NPVARIANT("test", args[0]);
+ bool retval = browser->invokeDefault(obj->npp, callback, args, 1, &browserResult);
+
+ if (retval)
+ browser->releasevariantvalue(&browserResult);
+
+ BOOLEAN_TO_NPVARIANT(retval, *result);
+ return true;
+ } else if (name == pluginMethodIdentifiers[ID_TEST_ENUMERATE]) {
+ if (argCount == 2 && NPVARIANT_IS_OBJECT(args[0]) && NPVARIANT_IS_OBJECT(args[1])) {
+ uint32_t count;
+ NPIdentifier* identifiers;
+
+ if (browser->enumerate(obj->npp, NPVARIANT_TO_OBJECT(args[0]), &identifiers, &count)) {
+ NPObject* outArray = NPVARIANT_TO_OBJECT(args[1]);
+ NPIdentifier pushIdentifier = browser->getstringidentifier("push");
+
+ for (uint32_t i = 0; i < count; i++) {
+ NPUTF8* string = browser->utf8fromidentifier(identifiers[i]);
+
+ if (!string)
+ continue;
+
+ NPVariant args[1];
+ STRINGZ_TO_NPVARIANT(string, args[0]);
+ NPVariant browserResult;
+ browser->invoke(obj->npp, outArray, pushIdentifier, args, 1, &browserResult);
+ browser->releasevariantvalue(&browserResult);
+ browser->memfree(string);
+ }
+
+ browser->memfree(identifiers);
+ }
+
+ VOID_TO_NPVARIANT(*result);
+ return true;
+ }
+ } else if (name == pluginMethodIdentifiers[ID_DESTROY_STREAM]) {
+ NPError npError = browser->destroystream(obj->npp, obj->stream, NPRES_USER_BREAK);
+ INT32_TO_NPVARIANT(npError, *result);
+ return true;
+ } else if (name == pluginMethodIdentifiers[ID_TEST_GETINTIDENTIFIER]) {
+ if (argCount == 1 && NPVARIANT_IS_DOUBLE(args[0])) {
+ NPIdentifier identifier = browser->getintidentifier((int)NPVARIANT_TO_DOUBLE(args[0]));
+ INT32_TO_NPVARIANT((int32)identifier, *result);
+ return true;
+ }
+ } else if (name == pluginMethodIdentifiers[ID_TEST_EVALUATE] &&
+ argCount == 1 && NPVARIANT_IS_STRING(args[0])) {
+ NPObject *windowScriptObject;
+ browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
+
+ NPString s = NPVARIANT_TO_STRING(args[0]);
+
+ bool retval = browser->evaluate(obj->npp, windowScriptObject, &s, result);
+ browser->releaseobject(windowScriptObject);
+ return retval;
+ } else if (name == pluginMethodIdentifiers[ID_TEST_GET_PROPERTY] &&
+ argCount > 0) {
+ NPObject *object;
+ browser->getvalue(obj->npp, NPNVWindowNPObject, &object);
+
+ for (uint32_t i = 0; i < argCount; i++) {
+ assert(NPVARIANT_IS_STRING(args[i]));
+ NPUTF8* propertyString = createCStringFromNPVariant(&args[i]);
+ NPIdentifier propertyIdentifier = browser->getstringidentifier(propertyString);
+ free(propertyString);
+
+ NPVariant variant;
+ bool retval = browser->getproperty(obj->npp, object, propertyIdentifier, &variant);
+ browser->releaseobject(object);
+
+ if (!retval)
+ break;
+
+ if (i + 1 < argCount) {
+ assert(NPVARIANT_IS_OBJECT(variant));
+ object = NPVARIANT_TO_OBJECT(variant);
+ } else {
+ *result = variant;
+ return true;
+ }
+ }
+
+ VOID_TO_NPVARIANT(*result);
+ return false;
+ } else if (name == pluginMethodIdentifiers[ID_TEST_GET_PROPERTY_RETURN_VALUE] &&
+ argCount == 2 && NPVARIANT_IS_OBJECT(args[0]) && NPVARIANT_IS_STRING(args[1])) {
+ NPUTF8* propertyString = createCStringFromNPVariant(&args[1]);
+ NPIdentifier propertyIdentifier = browser->getstringidentifier(propertyString);
+ free(propertyString);
+
+ NPVariant variant;
+ bool retval = browser->getproperty(obj->npp, NPVARIANT_TO_OBJECT(args[0]), propertyIdentifier, &variant);
+ if (retval)
+ browser->releasevariantvalue(&variant);
+
+ BOOLEAN_TO_NPVARIANT(retval, *result);
+ return true;
+ }
+ return false;
+}
+
+static bool pluginInvokeDefault(NPObject *obj, const NPVariant *args, uint32_t argCount, NPVariant *result)
+{
+ INT32_TO_NPVARIANT(1, *result);
+ return true;
+}
+
+static void pluginInvalidate(NPObject *obj)
+{
+}
+
+static NPObject *pluginAllocate(NPP npp, NPClass *theClass)
+{
+ PluginObject *newInstance = (PluginObject*)malloc(sizeof(PluginObject));
+
+ if (!identifiersInitialized) {
+ identifiersInitialized = true;
+ initializeIdentifiers();
+ }
+
+ newInstance->npp = npp;
+ newInstance->testObject = browser->createobject(npp, getTestClass());
+ newInstance->eventLogging = FALSE;
+ newInstance->logDestroy = FALSE;
+ newInstance->logSetWindow = FALSE;
+ newInstance->returnErrorFromNewStream = FALSE;
+ newInstance->stream = 0;
+
+ newInstance->firstUrl = NULL;
+ newInstance->firstHeaders = NULL;
+ newInstance->lastUrl = NULL;
+ newInstance->lastHeaders = NULL;
+
+ return (NPObject *)newInstance;
+}
+
+static void pluginDeallocate(NPObject *header)
+{
+ PluginObject* obj = (PluginObject*)header;
+
+ browser->releaseobject(obj->testObject);
+
+ free(obj->firstUrl);
+ free(obj->firstHeaders);
+ free(obj->lastUrl);
+ free(obj->lastHeaders);
+
+ free(obj);
+}
+
+void handleCallback(PluginObject* object, const char *url, NPReason reason, void *notifyData)
+{
+ assert(object);
+
+ NPVariant args[2];
+
+ NPObject *windowScriptObject;
+ browser->getvalue(object->npp, NPNVWindowNPObject, &windowScriptObject);
+
+ NPIdentifier callbackIdentifier = notifyData;
+
+ INT32_TO_NPVARIANT(reason, args[0]);
+
+ char *strHdr = NULL;
+ if (object->firstUrl && object->firstHeaders && object->lastUrl && object->lastHeaders) {
+ // Format expected by JavaScript validator: four fields separated by \n\n:
+ // First URL; first header block; last URL; last header block.
+ // Note that header blocks already end with \n due to how NPStream::headers works.
+ int len = strlen(object->firstUrl) + 2
+ + strlen(object->firstHeaders) + 1
+ + strlen(object->lastUrl) + 2
+ + strlen(object->lastHeaders) + 1;
+ strHdr = (char*)malloc(len + 1);
+ snprintf(strHdr, len + 1, "%s\n\n%s\n%s\n\n%s\n",
+ object->firstUrl, object->firstHeaders, object->lastUrl, object->lastHeaders);
+ STRINGN_TO_NPVARIANT(strHdr, len, args[1]);
+ } else
+ NULL_TO_NPVARIANT(args[1]);
+
+ NPVariant browserResult;
+ browser->invoke(object->npp, windowScriptObject, callbackIdentifier, args, 2, &browserResult);
+ browser->releasevariantvalue(&browserResult);
+
+ free(strHdr);
+}
+
+void notifyStream(PluginObject* object, const char *url, const char *headers)
+{
+ if (object->firstUrl == NULL) {
+ if (url)
+ object->firstUrl = strdup(url);
+ if (headers)
+ object->firstHeaders = strdup(headers);
+ } else {
+ free(object->lastUrl);
+ free(object->lastHeaders);
+ object->lastUrl = (url ? strdup(url) : NULL);
+ object->lastHeaders = (headers ? strdup(headers) : NULL);
+ }
+}
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.h b/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.h
new file mode 100644
index 0000000..31dbb96
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.h
@@ -0,0 +1,48 @@
+/*
+ * 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 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 <WebKit/npfunctions.h>
+
+extern NPNetscapeFuncs *browser;
+
+typedef struct {
+ NPObject header;
+ NPP npp;
+ NPBool eventLogging;
+ NPBool logSetWindow;
+ NPBool logDestroy;
+ NPBool returnErrorFromNewStream;
+ NPObject* testObject;
+ NPStream* stream;
+ char* onStreamLoad;
+ char* firstUrl;
+ char* firstHeaders;
+ char* lastUrl;
+ char* lastHeaders;
+} PluginObject;
+
+extern NPClass *getPluginClass(void);
+extern void handleCallback(PluginObject* object, const char *url, NPReason reason, void *notifyData);
+extern void notifyStream(PluginObject* object, const char *url, const char *headers);
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/TestObject.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/TestObject.cpp
new file mode 100644
index 0000000..a62f6a7
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/TestObject.cpp
@@ -0,0 +1,107 @@
+/*
+ * 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.
+ *
+ * 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 "TestObject.h"
+#include "PluginObject.h"
+
+static bool testEnumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count);
+static bool testHasProperty(NPObject *obj, NPIdentifier name);
+static NPObject *testAllocate(NPP npp, NPClass *theClass);
+static void testDeallocate(NPObject *obj);
+
+static NPClass testClass = {
+ NP_CLASS_STRUCT_VERSION,
+ testAllocate,
+ testDeallocate,
+ 0,
+ 0,
+ 0,
+ 0,
+ testHasProperty,
+ 0,
+ 0,
+ 0,
+ testEnumerate
+};
+
+NPClass *getTestClass(void)
+{
+ return &testClass;
+}
+
+static bool identifiersInitialized = false;
+
+#define NUM_TEST_IDENTIFIERS 2
+
+static NPIdentifier testIdentifiers[NUM_TEST_IDENTIFIERS];
+static const NPUTF8 *testIdentifierNames[NUM_TEST_IDENTIFIERS] = {
+ "foo",
+ "bar"
+};
+
+static void initializeIdentifiers(void)
+{
+ browser->getstringidentifiers(testIdentifierNames, NUM_TEST_IDENTIFIERS, testIdentifiers);
+}
+
+static NPObject *testAllocate(NPP npp, NPClass *theClass)
+{
+ NPObject *newInstance = (NPObject*)malloc(sizeof(NPObject));
+
+ if (!identifiersInitialized) {
+ identifiersInitialized = true;
+ initializeIdentifiers();
+ }
+
+ return newInstance;
+}
+
+static void testDeallocate(NPObject *obj)
+{
+ free(obj);
+}
+
+static bool testHasProperty(NPObject *obj, NPIdentifier name)
+{
+ for (unsigned i = 0; i < NUM_TEST_IDENTIFIERS; i++) {
+ if (testIdentifiers[i] == name)
+ return true;
+ }
+
+ return false;
+}
+
+
+static bool testEnumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count)
+{
+ *count = NUM_TEST_IDENTIFIERS;
+
+ *value = (NPIdentifier*)browser->memalloc(NUM_TEST_IDENTIFIERS * sizeof(NPIdentifier));
+ memcpy(*value, testIdentifiers, sizeof(NPIdentifier) * NUM_TEST_IDENTIFIERS);
+
+ return true;
+}
+
+
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/TestObject.h b/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/TestObject.h
new file mode 100644
index 0000000..1295fb7
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/TestObject.h
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ *
+ * 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 <WebKit/npapi.h>
+#include <WebKit/npruntime.h>
+
+NPClass *getTestClass(void);
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/main.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/main.cpp
new file mode 100644
index 0000000..ebbc9e4
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/main.cpp
@@ -0,0 +1,264 @@
+/*
+ * 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 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.
+ */
+
+#import "PluginObject.h"
+
+// Mach-o entry points
+extern "C" {
+ NPError NP_Initialize(NPNetscapeFuncs *browserFuncs);
+ NPError NP_GetEntryPoints(NPPluginFuncs *pluginFuncs);
+ void NP_Shutdown(void);
+}
+
+// Mach-o entry points
+NPError NP_Initialize(NPNetscapeFuncs *browserFuncs)
+{
+ browser = browserFuncs;
+ return NPERR_NO_ERROR;
+}
+
+NPError NP_GetEntryPoints(NPPluginFuncs *pluginFuncs)
+{
+ pluginFuncs->version = 11;
+ pluginFuncs->size = sizeof(pluginFuncs);
+ pluginFuncs->newp = NPP_New;
+ pluginFuncs->destroy = NPP_Destroy;
+ pluginFuncs->setwindow = NPP_SetWindow;
+ pluginFuncs->newstream = NPP_NewStream;
+ pluginFuncs->destroystream = NPP_DestroyStream;
+ pluginFuncs->asfile = NPP_StreamAsFile;
+ pluginFuncs->writeready = NPP_WriteReady;
+ pluginFuncs->write = (NPP_WriteProcPtr)NPP_Write;
+ pluginFuncs->print = NPP_Print;
+ pluginFuncs->event = NPP_HandleEvent;
+ pluginFuncs->urlnotify = NPP_URLNotify;
+ pluginFuncs->getvalue = NPP_GetValue;
+ pluginFuncs->setvalue = NPP_SetValue;
+
+ return NPERR_NO_ERROR;
+}
+
+void NP_Shutdown(void)
+{
+}
+
+NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char *argn[], char *argv[], NPSavedData *saved)
+{
+ if (browser->version >= 14) {
+ PluginObject* obj = (PluginObject*)browser->createobject(instance, getPluginClass());
+
+ obj->onStreamLoad = NULL;
+
+ for (int i = 0; i < argc; i++) {
+ if (strcasecmp(argn[i], "onstreamload") == 0 && !obj->onStreamLoad)
+ obj->onStreamLoad = strdup(argv[i]);
+ else if (strcasecmp(argn[i], "src") == 0 &&
+ strcasecmp(argv[i], "data:application/x-webkit-test-netscape,returnerrorfromnewstream") == 0)
+ obj->returnErrorFromNewStream = TRUE;
+ else if (strcasecmp(argn[i], "logfirstsetwindow") == 0)
+ obj->logSetWindow = TRUE;
+ }
+
+ instance->pdata = obj;
+ }
+
+ return NPERR_NO_ERROR;
+}
+
+NPError NPP_Destroy(NPP instance, NPSavedData **save)
+{
+ PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
+ if (obj) {
+ if (obj->onStreamLoad)
+ free(obj->onStreamLoad);
+
+ if (obj->logDestroy)
+ printf("PLUGIN: NPP_Destroy\n");
+
+ browser->releaseobject(&obj->header);
+ }
+ return NPERR_NO_ERROR;
+}
+
+NPError NPP_SetWindow(NPP instance, NPWindow *window)
+{
+ PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
+
+ if (obj) {
+ if (obj->logSetWindow) {
+ printf("PLUGIN: NPP_SetWindow: %d %d\n", (int)window->width, (int)window->height);
+ obj->logSetWindow = false;
+ }
+ }
+
+ return NPERR_NO_ERROR;
+}
+
+NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream *stream, NPBool seekable, uint16 *stype)
+{
+ PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
+ obj->stream = stream;
+ *stype = NP_ASFILEONLY;
+
+ if (obj->returnErrorFromNewStream)
+ return NPERR_GENERIC_ERROR;
+
+ if (browser->version >= NPVERS_HAS_RESPONSE_HEADERS)
+ notifyStream(obj, stream->url, stream->headers);
+
+ if (obj->onStreamLoad) {
+ NPObject *windowScriptObject;
+ browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
+
+ NPString script;
+ script.UTF8Characters = obj->onStreamLoad;
+ script.UTF8Length = strlen(obj->onStreamLoad);
+
+ NPVariant browserResult;
+ browser->evaluate(obj->npp, windowScriptObject, &script, &browserResult);
+ browser->releasevariantvalue(&browserResult);
+ }
+
+ return NPERR_NO_ERROR;
+}
+
+NPError NPP_DestroyStream(NPP instance, NPStream *stream, NPReason reason)
+{
+ return NPERR_NO_ERROR;
+}
+
+int32 NPP_WriteReady(NPP instance, NPStream *stream)
+{
+ return 0;
+}
+
+int32 NPP_Write(NPP instance, NPStream *stream, int32 offset, int32 len, void *buffer)
+{
+ return 0;
+}
+
+void NPP_StreamAsFile(NPP instance, NPStream *stream, const char *fname)
+{
+}
+
+void NPP_Print(NPP instance, NPPrint *platformPrint)
+{
+}
+
+int16 NPP_HandleEvent(NPP instance, void *event)
+{
+ PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
+ if (!obj->eventLogging)
+ return 0;
+
+ EventRecord* evt = static_cast<EventRecord*>(event);
+ Point pt = { evt->where.v, evt->where.h };
+ switch (evt->what) {
+ case nullEvent:
+ // these are delivered non-deterministically, don't log.
+ break;
+ case mouseDown:
+ GlobalToLocal(&pt);
+ printf("PLUGIN: mouseDown at (%d, %d)\n", pt.h, pt.v);
+ break;
+ case mouseUp:
+ GlobalToLocal(&pt);
+ printf("PLUGIN: mouseUp at (%d, %d)\n", pt.h, pt.v);
+ break;
+ case keyDown:
+ printf("PLUGIN: keyDown '%c'\n", (char)(evt->message & 0xFF));
+ break;
+ case keyUp:
+ printf("PLUGIN: keyUp '%c'\n", (char)(evt->message & 0xFF));
+ break;
+ case autoKey:
+ printf("PLUGIN: autoKey '%c'\n", (char)(evt->message & 0xFF));
+ break;
+ case updateEvt:
+ printf("PLUGIN: updateEvt\n");
+ break;
+ case diskEvt:
+ printf("PLUGIN: diskEvt\n");
+ break;
+ case activateEvt:
+ printf("PLUGIN: activateEvt\n");
+ break;
+ case osEvt:
+ printf("PLUGIN: osEvt - ");
+ switch ((evt->message & 0xFF000000) >> 24) {
+ case suspendResumeMessage:
+ printf("%s\n", (evt->message & 0x1) ? "resume" : "suspend");
+ break;
+ case mouseMovedMessage:
+ printf("mouseMoved\n");
+ break;
+ default:
+ printf("%08lX\n", evt->message);
+ }
+ break;
+ case kHighLevelEvent:
+ printf("PLUGIN: kHighLevelEvent\n");
+ break;
+ // NPAPI events
+ case getFocusEvent:
+ printf("PLUGIN: getFocusEvent\n");
+ break;
+ case loseFocusEvent:
+ printf("PLUGIN: loseFocusEvent\n");
+ break;
+ case adjustCursorEvent:
+ printf("PLUGIN: adjustCursorEvent\n");
+ break;
+ default:
+ printf("PLUGIN: event %d\n", evt->what);
+ }
+
+ return 0;
+}
+
+void NPP_URLNotify(NPP instance, const char *url, NPReason reason, void *notifyData)
+{
+ PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
+
+ handleCallback(obj, url, reason, notifyData);
+}
+
+NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value)
+{
+ if (variable == NPPVpluginScriptableNPObject) {
+ void **v = (void **)value;
+ PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
+ // Return value is expected to be retained
+ browser->retainobject((NPObject *)obj);
+ *v = obj;
+ return NPERR_NO_ERROR;
+ }
+ return NPERR_GENERIC_ERROR;
+}
+
+NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value)
+{
+ return NPERR_GENERIC_ERROR;
+}
diff --git a/WebKitTools/DumpRenderTree/WorkQueue.cpp b/WebKitTools/DumpRenderTree/WorkQueue.cpp
new file mode 100644
index 0000000..87c7af5
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/WorkQueue.cpp
@@ -0,0 +1,89 @@
+/*
+ * 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 "DumpRenderTree.h"
+#include "WorkQueue.h"
+
+#include "WorkQueueItem.h"
+#include <wtf/Assertions.h>
+
+static const unsigned queueLength = 1024;
+
+static WorkQueueItem* theQueue[queueLength];
+static unsigned startOfQueue;
+static unsigned endOfQueue;
+
+WorkQueue* WorkQueue::shared()
+{
+ static WorkQueue* sharedInstance = new WorkQueue;
+ return sharedInstance;
+}
+
+WorkQueue::WorkQueue()
+ : m_frozen(false)
+{
+}
+
+void WorkQueue::queue(WorkQueueItem* item)
+{
+ ASSERT(endOfQueue < queueLength);
+ ASSERT(endOfQueue >= startOfQueue);
+
+ if (m_frozen) {
+ delete item;
+ return;
+ }
+
+ theQueue[endOfQueue++] = item;
+}
+
+WorkQueueItem* WorkQueue::dequeue()
+{
+ ASSERT(endOfQueue >= startOfQueue);
+
+ if (startOfQueue == endOfQueue)
+ return 0;
+
+ return theQueue[startOfQueue++];
+}
+
+unsigned WorkQueue::count()
+{
+ return endOfQueue - startOfQueue;
+}
+
+void WorkQueue::clear()
+{
+ for (unsigned i = startOfQueue; i < endOfQueue; ++i) {
+ delete theQueue[i];
+ theQueue[i] = 0;
+ }
+
+ startOfQueue = 0;
+ endOfQueue = 0;
+}
diff --git a/WebKitTools/DumpRenderTree/WorkQueue.h b/WebKitTools/DumpRenderTree/WorkQueue.h
new file mode 100644
index 0000000..c2850c5
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/WorkQueue.h
@@ -0,0 +1,51 @@
+/*
+ * 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 WorkQueue_h
+#define WorkQueue_h
+
+class WorkQueueItem;
+
+class WorkQueue {
+public:
+ static WorkQueue* shared();
+
+ void queue(WorkQueueItem*);
+ WorkQueueItem* dequeue();
+ void clear();
+ unsigned count();
+
+ void setFrozen(bool b) { m_frozen = b; }
+
+private:
+ WorkQueue();
+
+ bool m_frozen;
+};
+
+#endif // !defined(WorkQueue_h)
diff --git a/WebKitTools/DumpRenderTree/WorkQueueItem.h b/WebKitTools/DumpRenderTree/WorkQueueItem.h
new file mode 100644
index 0000000..fd15329
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/WorkQueueItem.h
@@ -0,0 +1,108 @@
+/*
+ * 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 WorkQueueItem_h
+#define WorkQueueItem_h
+
+#include <JavaScriptCore/JSRetainPtr.h>
+#include <JavaScriptCore/JSBase.h>
+
+class WorkQueueItem {
+public:
+ virtual ~WorkQueueItem() { }
+ virtual void invoke() const = 0;
+};
+
+class LoadItem : public WorkQueueItem {
+public:
+ LoadItem(const JSStringRef url, const JSStringRef target)
+ : m_url(url)
+ , m_target(target)
+ {
+ }
+
+ const JSStringRef url() const { return m_url.get(); }
+ const JSStringRef target() const { return m_target.get(); }
+
+ virtual void invoke() const;
+
+private:
+ JSRetainPtr<JSStringRef> m_url;
+ JSRetainPtr<JSStringRef> m_target;
+};
+
+class ReloadItem : public WorkQueueItem {
+public:
+ virtual void invoke() const;
+};
+
+class ScriptItem : public WorkQueueItem {
+public:
+ ScriptItem(const JSStringRef script)
+ : m_script(script)
+ {
+ }
+
+ const JSStringRef script() const { return m_script.get(); }
+
+ virtual void invoke() const;
+
+private:
+ JSRetainPtr<JSStringRef> m_script;
+};
+
+class BackForwardItem : public WorkQueueItem {
+public:
+ virtual void invoke() const;
+
+protected:
+ BackForwardItem(int howFar)
+ : m_howFar(howFar)
+ {
+ }
+
+ int m_howFar;
+};
+
+class BackItem : public BackForwardItem {
+public:
+ BackItem(unsigned howFar)
+ : BackForwardItem(-howFar)
+ {
+ }
+};
+
+class ForwardItem : public BackForwardItem {
+public:
+ ForwardItem(unsigned howFar)
+ : BackForwardItem(howFar)
+ {
+ }
+};
+
+#endif // !defined(WorkQueueItem_h)
diff --git a/WebKitTools/DumpRenderTree/cg/ImageDiffCG.cpp b/WebKitTools/DumpRenderTree/cg/ImageDiffCG.cpp
new file mode 100644
index 0000000..6a84b79
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/cg/ImageDiffCG.cpp
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2005, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2005 Ben La Monica <ben.lamonica@gmail.com>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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.
+ */
+
+#define min min
+
+#include <CoreGraphics/CGBitmapContext.h>
+#include <CoreGraphics/CGImage.h>
+#include <ImageIO/CGImageDestination.h>
+#include <stdio.h>
+#include <wtf/Platform.h>
+#include <wtf/RetainPtr.h>
+
+#if PLATFORM(WIN)
+#include <fcntl.h>
+#include <io.h>
+#endif
+
+#if PLATFORM(MAC)
+#include <LaunchServices/UTCoreTypes.h>
+#endif
+
+#ifndef CGFLOAT_DEFINED
+#ifdef __LP64__
+typedef double CGFloat;
+#else
+typedef float CGFloat;
+#endif
+#define CGFLOAT_DEFINED 1
+#endif
+
+using namespace std;
+
+#if PLATFORM(WIN)
+static const CFStringRef kUTTypePNG = CFSTR("public.png");
+#endif
+
+static RetainPtr<CGImageRef> createImageFromStdin(int bytesRemaining)
+{
+ unsigned char buffer[2048];
+ RetainPtr<CFMutableDataRef> data(AdoptCF, CFDataCreateMutable(0, bytesRemaining));
+
+ while (bytesRemaining > 0) {
+ size_t bytesToRead = min(bytesRemaining, 2048);
+ size_t bytesRead = fread(buffer, 1, bytesToRead, stdin);
+ CFDataAppendBytes(data.get(), buffer, static_cast<CFIndex>(bytesRead));
+ bytesRemaining -= static_cast<int>(bytesRead);
+ }
+ RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateWithCFData(data.get()));
+ return RetainPtr<CGImageRef>(AdoptCF, CGImageCreateWithPNGDataProvider(dataProvider.get(), 0, false, kCGRenderingIntentDefault));
+}
+
+static RetainPtr<CGContextRef> getDifferenceBitmap(CGImageRef testBitmap, CGImageRef referenceBitmap)
+{
+ // we must have both images to take diff
+ if (!testBitmap || !referenceBitmap)
+ return 0;
+
+ RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
+ static CFMutableDataRef data = CFDataCreateMutable(kCFAllocatorDefault, 0);
+ CFDataSetLength(data, CGImageGetHeight(testBitmap) * CGImageGetBytesPerRow(testBitmap));
+ RetainPtr<CGContextRef> context(AdoptCF, CGBitmapContextCreate(CFDataGetMutableBytePtr(data), CGImageGetWidth(testBitmap), CGImageGetHeight(testBitmap),
+ CGImageGetBitsPerComponent(testBitmap), CGImageGetBytesPerRow(testBitmap), colorSpace.get(), kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst));
+
+ CGContextSetBlendMode(context.get(), kCGBlendModeNormal);
+ CGContextDrawImage(context.get(), CGRectMake(0, 0, static_cast<CGFloat>(CGImageGetWidth(testBitmap)), static_cast<CGFloat>(CGImageGetHeight(testBitmap))), testBitmap);
+ CGContextSetBlendMode(context.get(), kCGBlendModeDifference);
+ CGContextDrawImage(context.get(), CGRectMake(0, 0, static_cast<CGFloat>(CGImageGetWidth(referenceBitmap)), static_cast<CGFloat>(CGImageGetHeight(referenceBitmap))), referenceBitmap);
+
+ return context;
+}
+
+/**
+ * Counts the number of non-black pixels, and returns the percentage
+ * of non-black pixels to total pixels in the image.
+ */
+static float computePercentageDifferent(CGContextRef diffBitmap, unsigned threshold)
+{
+ // if diffBiatmap is nil, then there was an error, and it didn't match.
+ if (!diffBitmap)
+ return 100.0f;
+
+ size_t pixelsHigh = CGBitmapContextGetHeight(diffBitmap);
+ size_t pixelsWide = CGBitmapContextGetWidth(diffBitmap);
+ size_t bytesPerRow = CGBitmapContextGetBytesPerRow(diffBitmap);
+ unsigned char* pixelRowData = static_cast<unsigned char*>(CGBitmapContextGetData(diffBitmap));
+ unsigned differences = 0;
+
+ // NOTE: This may not be safe when switching between ENDIAN types
+ for (unsigned row = 0; row < pixelsHigh; row++) {
+ for (unsigned col = 0; col < (pixelsWide * 4); col += 4) {
+ unsigned char* red = pixelRowData + col;
+ unsigned char* green = red + 1;
+ unsigned char* blue = red + 2;
+ unsigned distance = *red + *green + *blue;
+ if (distance > threshold) {
+ differences++;
+ // shift the pixels towards white to make them more visible
+ *red = static_cast<unsigned char>(min(UCHAR_MAX, *red + 100));
+ *green = static_cast<unsigned char>(min(UCHAR_MAX, *green + 100));
+ *blue = static_cast<unsigned char>(min(UCHAR_MAX, *blue + 100));
+ }
+ }
+ pixelRowData += bytesPerRow;
+ }
+
+ float totalPixels = static_cast<float>(pixelsHigh * pixelsWide);
+ return (differences * 100.f) / totalPixels;
+}
+
+static void compareImages(CGImageRef actualBitmap, CGImageRef baselineBitmap, unsigned threshold)
+{
+ // prepare the difference blend to check for pixel variations
+ RetainPtr<CGContextRef> diffBitmap = getDifferenceBitmap(actualBitmap, baselineBitmap);
+
+ float percentage = computePercentageDifferent(diffBitmap.get(), threshold);
+
+ percentage = (float)((int)(percentage * 100.0f)) / 100.0f; // round to 2 decimal places
+
+ // send message to let them know if an image was wrong
+ if (percentage > 0.0f) {
+ // since the diff might actually show something, send it to stdout
+ RetainPtr<CGImageRef> image(AdoptCF, CGBitmapContextCreateImage(diffBitmap.get()));
+ RetainPtr<CFMutableDataRef> imageData(AdoptCF, CFDataCreateMutable(0, 0));
+ RetainPtr<CGImageDestinationRef> imageDest(AdoptCF, CGImageDestinationCreateWithData(imageData.get(), kUTTypePNG, 1, 0));
+ CGImageDestinationAddImage(imageDest.get(), image.get(), 0);
+ CGImageDestinationFinalize(imageDest.get());
+ printf("Content-length: %lu\n", CFDataGetLength(imageData.get()));
+ fwrite(CFDataGetBytePtr(imageData.get()), 1, CFDataGetLength(imageData.get()), stdout);
+ fprintf(stdout, "diff: %01.2f%% failed\n", percentage);
+ } else
+ fprintf(stdout, "diff: %01.2f%% passed\n", percentage);
+}
+
+int main(int argc, const char* argv[])
+{
+#if PLATFORM(WIN)
+ _setmode(0, _O_BINARY);
+ _setmode(1, _O_BINARY);
+#endif
+
+ unsigned threshold = 0;
+
+ for (int i = 1; i < argc; ++i) {
+ if (!strcmp(argv[i], "-t") || !strcmp(argv[i], "--threshold")) {
+ if (i >= argc - 1)
+ exit(1);
+ threshold = strtol(argv[i + 1], 0, 0);
+ ++i;
+ continue;
+ }
+ }
+
+ char buffer[2048];
+ RetainPtr<CGImageRef> actualImage;
+ RetainPtr<CGImageRef> baselineImage;
+
+ while (fgets(buffer, sizeof(buffer), stdin)) {
+ // remove the CR
+ char* newLineCharacter = strchr(buffer, '\n');
+ if (newLineCharacter)
+ *newLineCharacter = '\0';
+
+ if (!strncmp("Content-length: ", buffer, 16)) {
+ strtok(buffer, " ");
+ int imageSize = strtol(strtok(0, " "), 0, 10);
+
+ if (imageSize > 0 && !actualImage)
+ actualImage = createImageFromStdin(imageSize);
+ else if (imageSize > 0 && !baselineImage)
+ baselineImage = createImageFromStdin(imageSize);
+ else
+ fputs("error, image size must be specified.\n", stdout);
+ }
+
+ if (actualImage && baselineImage) {
+ compareImages(actualImage.get(), baselineImage.get(), threshold);
+ actualImage = 0;
+ baselineImage = 0;
+ }
+
+ fflush(stdout);
+ }
+
+ return 0;
+}
diff --git a/WebKitTools/DumpRenderTree/cg/PixelDumpSupportCG.cpp b/WebKitTools/DumpRenderTree/cg/PixelDumpSupportCG.cpp
new file mode 100644
index 0000000..e2e790c
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/cg/PixelDumpSupportCG.cpp
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
+ * (C) 2007 Graham Dennis (graham.dennis@gmail.com)
+ * (C) 2007 Eric Seidel <eric@webkit.org>
+ *
+ * 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 "DumpRenderTree.h"
+#include "PixelDumpSupportCG.h"
+
+#include "LayoutTestController.h"
+#include <ImageIO/CGImageDestination.h>
+#include <wtf/Assertions.h>
+#include <wtf/RetainPtr.h>
+#include <wtf/StringExtras.h>
+
+#if PLATFORM(WIN)
+#include "MD5.h"
+#elif PLATFORM(MAC)
+#include <LaunchServices/UTCoreTypes.h>
+#define COMMON_DIGEST_FOR_OPENSSL
+#include <CommonCrypto/CommonDigest.h>
+#endif
+
+#if PLATFORM(WIN)
+static const CFStringRef kUTTypePNG = CFSTR("public.png");
+#endif
+
+static void printPNG(CGImageRef image)
+{
+ RetainPtr<CFMutableDataRef> imageData(AdoptCF, CFDataCreateMutable(0, 0));
+ RetainPtr<CGImageDestinationRef> imageDest(AdoptCF, CGImageDestinationCreateWithData(imageData.get(), kUTTypePNG, 1, 0));
+ CGImageDestinationAddImage(imageDest.get(), image, 0);
+ CGImageDestinationFinalize(imageDest.get());
+ printf("Content-length: %lu\n", CFDataGetLength(imageData.get()));
+ fwrite(CFDataGetBytePtr(imageData.get()), 1, CFDataGetLength(imageData.get()), stdout);
+}
+
+static void getMD5HashStringForBitmap(CGContextRef bitmap, char string[33])
+{
+ MD5_CTX md5Context;
+ unsigned char hash[16];
+
+ size_t bitsPerPixel = CGBitmapContextGetBitsPerPixel(bitmap);
+ ASSERT(bitsPerPixel == 32); // ImageDiff assumes 32 bit RGBA, we must as well.
+ size_t bytesPerPixel = bitsPerPixel / 8;
+ size_t pixelsHigh = CGBitmapContextGetHeight(bitmap);
+ size_t pixelsWide = CGBitmapContextGetWidth(bitmap);
+ size_t bytesPerRow = CGBitmapContextGetBytesPerRow(bitmap);
+ ASSERT(bytesPerRow >= (pixelsWide * bytesPerPixel));
+
+ MD5_Init(&md5Context);
+ unsigned char* bitmapData = static_cast<unsigned char*>(CGBitmapContextGetData(bitmap));
+ for (unsigned row = 0; row < pixelsHigh; row++) {
+ MD5_Update(&md5Context, bitmapData, static_cast<unsigned>(pixelsWide * bytesPerPixel));
+ bitmapData += bytesPerRow;
+ }
+ MD5_Final(hash, &md5Context);
+
+ string[0] = '\0';
+ for (int i = 0; i < 16; i++)
+ snprintf(string, 33, "%s%02x", string, hash[i]);
+}
+
+void drawSelectionRect(CGContextRef context, const CGRect& rect)
+{
+ CGContextSaveGState(context);
+ CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0);
+ CGContextStrokeRect(context, rect);
+ CGContextRestoreGState(context);
+}
+
+void dumpWebViewAsPixelsAndCompareWithExpected(const char* /*currentTest*/, bool /*forceAllTestsToDumpPixels*/)
+{
+ RetainPtr<CGContextRef> context = getBitmapContextFromWebView();
+
+#if PLATFORM(MAC)
+ if (layoutTestController->testRepaint())
+ repaintWebView(context.get(), layoutTestController->testRepaintSweepHorizontally());
+ else
+ paintWebView(context.get());
+
+ if (layoutTestController->dumpSelectionRect())
+ drawSelectionRect(context.get(), getSelectionRect());
+#endif
+
+ // Compute the actual hash to compare to the expected image's hash.
+ char actualHash[33];
+ getMD5HashStringForBitmap(context.get(), actualHash);
+ printf("\nActualHash: %s\n", actualHash);
+
+ // FIXME: We should compare the actualHash to the expected hash here and
+ // only set dumpImage to true if they don't match, but DRT doesn't have
+ // enough information currently to find the expected checksum file.
+ bool dumpImage = true;
+
+ if (dumpImage) {
+ RetainPtr<CGImageRef> image(AdoptCF, CGBitmapContextCreateImage(context.get()));
+ printPNG(image.get());
+ }
+
+ printf("#EOF\n");
+}
diff --git a/WebKitTools/DumpRenderTree/cg/PixelDumpSupportCG.h b/WebKitTools/DumpRenderTree/cg/PixelDumpSupportCG.h
new file mode 100644
index 0000000..0abdea6
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/cg/PixelDumpSupportCG.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
+ * (C) 2007 Graham Dennis (graham.dennis@gmail.com)
+ * (C) 2007 Eric Seidel <eric@webkit.org>
+ *
+ * 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 PixelDumpSupportCG_h
+#define PixelDumpSupportCG_h
+
+#include <wtf/RetainPtr.h>
+
+#ifndef CGFLOAT_DEFINED
+#ifdef __LP64__
+typedef double CGFloat;
+#else
+typedef float CGFloat;
+#endif
+#define CGFLOAT_DEFINED 1
+#endif
+
+typedef struct CGContext* CGContextRef;
+struct CGRect;
+
+RetainPtr<CGContextRef> getBitmapContextFromWebView();
+CGRect getSelectionRect();
+
+void paintWebView(CGContextRef);
+void repaintWebView(CGContextRef context, bool horizontal);
+void drawSelectionRect(CGContextRef, const CGRect&);
+
+#endif // PixelDumpSupportCG_h
diff --git a/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp b/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp
new file mode 100644
index 0000000..271da15
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp
@@ -0,0 +1,374 @@
+/*
+ * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
+ *
+ * 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 "LayoutTestController.h"
+#include "WorkQueue.h"
+#include "WorkQueueItem.h"
+
+#include <gtk/gtk.h>
+#include <webkit/webkit.h>
+
+#include <JavaScriptCore/JSBase.h>
+#include <JavaScriptCore/JSContextRef.h>
+#include <JavaScriptCore/JSObjectRef.h>
+#include <JavaScriptCore/JSStringRef.h>
+#include <JavaScriptCore/JSValueRef.h>
+
+#include <wtf/Assertions.h>
+
+#include <cassert>
+#include <getopt.h>
+#include <stdlib.h>
+#include <string.h>
+
+extern "C" {
+// This API is not yet public.
+extern GSList* webkit_web_frame_get_children(WebKitWebFrame* frame);
+extern gchar* webkit_web_frame_get_inner_text(WebKitWebFrame* frame);
+}
+
+volatile bool done;
+static bool printSeparators;
+static int testRepaintDefault;
+static int repaintSweepHorizontallyDefault;
+static int dumpPixels;
+static int dumpTree = 1;
+static gchar* currentTest;
+
+LayoutTestController* layoutTestController = 0;
+static WebKitWebView* webView;
+WebKitWebFrame* mainFrame = 0;
+WebKitWebFrame* topLoadingFrame = 0;
+guint waitToDumpWatchdog = 0;
+
+const unsigned maxViewHeight = 600;
+const unsigned maxViewWidth = 800;
+
+static gchar* autocorrectURL(const gchar* url)
+{
+ if (strncmp("http://", url, 7) != 0 && strncmp("https://", url, 8) != 0) {
+ GString* string = g_string_new("file://");
+ g_string_append(string, url);
+ return g_string_free(string, FALSE);
+ }
+
+ return g_strdup(url);
+}
+
+static bool shouldLogFrameLoadDelegates(const char* pathOrURL)
+{
+ return strstr(pathOrURL, "loading/");
+}
+
+void dumpFrameScrollPosition(WebKitWebFrame* frame)
+{
+
+}
+
+void displayWebView()
+{
+
+}
+
+static void appendString(gchar*& target, gchar* string)
+{
+ gchar* oldString = target;
+ target = g_strconcat(target, string, NULL);
+ g_free(oldString);
+}
+
+static gchar* dumpFramesAsText(WebKitWebFrame* frame)
+{
+ gchar* result = 0;
+
+ // Add header for all but the main frame.
+ bool isMainFrame = (webkit_web_view_get_main_frame(webView) == frame);
+
+ if (isMainFrame) {
+ gchar* innerText = webkit_web_frame_get_inner_text(frame);
+ result = g_strdup_printf("%s\n", innerText);
+ g_free(innerText);
+ } else {
+ const gchar* frameName = webkit_web_frame_get_name(frame);
+ gchar* innerText = webkit_web_frame_get_inner_text(frame);
+
+ result = g_strdup_printf("\n--------\nFrame: '%s'\n--------\n%s\n", frameName, innerText);
+
+ g_free(innerText);
+ }
+
+ if (layoutTestController->dumpChildFramesAsText()) {
+ GSList* children = webkit_web_frame_get_children(frame);
+ for (;children; children = g_slist_next(children))
+ appendString(result, dumpFramesAsText((WebKitWebFrame*)children->data));
+ }
+
+ return result;
+}
+
+static gchar* dumpRenderTreeAsText(WebKitWebFrame* frame)
+{
+ // FIXME: this will require new WebKitGtk SPI
+ return strdup("foo");
+}
+
+static void invalidateAnyPreviousWaitToDumpWatchdog()
+{
+ if (waitToDumpWatchdog) {
+ g_source_remove(waitToDumpWatchdog);
+ waitToDumpWatchdog = 0;
+ }
+}
+
+void dump()
+{
+ invalidateAnyPreviousWaitToDumpWatchdog();
+ if (dumpTree) {
+ char* result = 0;
+
+ bool dumpAsText = layoutTestController->dumpAsText();
+ // FIXME: Also dump text resuls as text.
+ layoutTestController->setDumpAsText(dumpAsText);
+ if (layoutTestController->dumpAsText())
+ result = dumpFramesAsText(mainFrame);
+ else {
+ bool isSVGW3CTest = (g_strrstr(currentTest, "svg/W3C-SVG-1.1"));
+ if (isSVGW3CTest)
+ gtk_widget_set_size_request(GTK_WIDGET(webView), 480, 360);
+ else
+ gtk_widget_set_size_request(GTK_WIDGET(webView), maxViewWidth, maxViewHeight);
+ result = dumpRenderTreeAsText(mainFrame);
+ }
+
+ if (!result) {
+ const char* errorMessage;
+ if (layoutTestController->dumpAsText())
+ errorMessage = "[documentElement innerText]";
+ else if (layoutTestController->dumpDOMAsWebArchive())
+ errorMessage = "[[mainFrame DOMDocument] webArchive]";
+ else if (layoutTestController->dumpSourceAsWebArchive())
+ errorMessage = "[[mainFrame dataSource] webArchive]";
+ else
+ errorMessage = "[mainFrame renderTreeAsExternalRepresentation]";
+ printf("ERROR: nil result from %s", errorMessage);
+ } else {
+ printf("%s", result);
+ g_free(result);
+ if (!layoutTestController->dumpAsText() && !layoutTestController->dumpDOMAsWebArchive() && !layoutTestController->dumpSourceAsWebArchive())
+ dumpFrameScrollPosition(mainFrame);
+ }
+
+ if (layoutTestController->dumpBackForwardList()) {
+ // FIXME: not implemented
+ }
+
+ if (printSeparators)
+ puts("#EOF");
+ }
+
+ if (dumpPixels) {
+ if (!layoutTestController->dumpAsText() && !layoutTestController->dumpDOMAsWebArchive() && !layoutTestController->dumpSourceAsWebArchive()) {
+ // FIXME: Add support for dumping pixels
+ }
+ }
+
+ fflush(stdout);
+
+ // FIXME: call displayWebView here when we support --paint
+
+ done = true;
+}
+
+static void runTest(const char* pathOrURL)
+{
+ gchar* url = autocorrectURL(pathOrURL);
+
+ layoutTestController = new LayoutTestController(testRepaintDefault, repaintSweepHorizontallyDefault);
+
+ done = false;
+ topLoadingFrame = 0;
+
+ if (shouldLogFrameLoadDelegates(pathOrURL))
+ layoutTestController->setDumpFrameLoadCallbacks(true);
+
+ if (currentTest)
+ g_free(currentTest);
+ currentTest = url;
+
+ WorkQueue::shared()->clear();
+ WorkQueue::shared()->setFrozen(false);
+
+ webkit_web_view_open(webView, url);
+
+ while (!done)
+ g_main_context_iteration(NULL, true);
+
+ WorkQueue::shared()->clear();
+
+ delete layoutTestController;
+ layoutTestController = 0;
+}
+
+void webViewLoadStarted(WebKitWebView* view, WebKitWebFrame* frame, void*)
+{
+ // Make sure we only set this once per test. If it gets cleared, and then set again, we might
+ // end up doing two dumps for one test.
+ if (!topLoadingFrame && !done)
+ topLoadingFrame = frame;
+}
+
+static gboolean processWork(void* data)
+{
+ // quit doing work once a load is in progress
+ while (WorkQueue::shared()->count() > 0 && !topLoadingFrame) {
+ WorkQueueItem* item = WorkQueue::shared()->dequeue();
+ ASSERT(item);
+ item->invoke();
+ delete item;
+ }
+
+ // if we didn't start a new load, then we finished all the commands, so we're ready to dump state
+ if (!topLoadingFrame && !layoutTestController->waitToDump())
+ dump();
+
+ return FALSE;
+}
+
+void webViewLoadFinished(WebKitWebView* view, WebKitWebFrame* frame, void*)
+{
+ if (frame != topLoadingFrame)
+ return;
+
+ topLoadingFrame = 0;
+ WorkQueue::shared()->setFrozen(true); // first complete load freezes the queue for the rest of this test
+ if (layoutTestController->waitToDump())
+ return;
+
+ if (WorkQueue::shared()->count())
+ g_timeout_add(0, processWork, 0);
+ else
+ dump();
+}
+
+void webViewWindowObjectCleared(WebKitWebView* view, WebKitWebFrame* frame, JSGlobalContextRef context, JSObjectRef globalObject)
+{
+ JSValueRef exception = 0;
+ assert(layoutTestController);
+ layoutTestController->makeWindowObject(context, globalObject, &exception);
+ assert(!exception);
+}
+
+gboolean webViewConsoleMessage(WebKitWebView* view, const gchar* message, unsigned int line, const gchar* sourceId)
+{
+ fprintf(stdout, "CONSOLE MESSAGE: line %d: %s\n", line, message);
+ return TRUE;
+}
+
+
+gboolean webViewScriptAlert(WebKitWebView* view, WebKitWebFrame* frame, const gchar* message)
+{
+ fprintf(stdout, "ALERT: %s\n", message);
+ return TRUE;
+}
+
+gboolean webViewScriptPrompt(WebKitWebView* webView, WebKitWebFrame* frame, const gchar* message, const gchar* defaultValue, gchar** value)
+{
+ fprintf(stdout, "PROMPT: %s, default text: %s\n", message, defaultValue);
+ *value = g_strdup(defaultValue);
+ return TRUE;
+}
+
+gboolean webViewScriptConfirm(WebKitWebView* view, WebKitWebFrame* frame, const gchar* message, gboolean* didConfirm)
+{
+ fprintf(stdout, "CONFIRM: %s\n", message);
+ *didConfirm = TRUE;
+ return TRUE;
+}
+
+
+int main(int argc, char* argv[])
+{
+ struct option options[] = {
+ {"horizontal-sweep", no_argument, &repaintSweepHorizontallyDefault, true},
+ {"notree", no_argument, &dumpTree, false},
+ {"pixel-tests", no_argument, &dumpPixels, true},
+ {"repaint", no_argument, &testRepaintDefault, true},
+ {"tree", no_argument, &dumpTree, true},
+ {NULL, 0, NULL, 0}
+ };
+
+ int option;
+ while ((option = getopt_long(argc, (char* const*)argv, "", options, NULL)) != -1)
+ switch (option) {
+ case '?': // unknown or ambiguous option
+ case ':': // missing argument
+ exit(1);
+ break;
+ }
+
+ gtk_init(&argc, &argv);
+
+ GtkWidget* window = gtk_window_new(GTK_WINDOW_POPUP);
+ GtkContainer* container = GTK_CONTAINER(gtk_fixed_new());
+ gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(container));
+ gtk_widget_realize(window);
+
+ webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ gtk_container_add(container, GTK_WIDGET(webView));
+ gtk_widget_realize(GTK_WIDGET(webView));
+ mainFrame = webkit_web_view_get_main_frame(webView);
+
+ g_signal_connect(G_OBJECT(webView), "load-started", G_CALLBACK(webViewLoadStarted), 0);
+ g_signal_connect(G_OBJECT(webView), "load-finished", G_CALLBACK(webViewLoadFinished), 0);
+ g_signal_connect(G_OBJECT(webView), "window-object-cleared", G_CALLBACK(webViewWindowObjectCleared), 0);
+ g_signal_connect(G_OBJECT(webView), "console-message", G_CALLBACK(webViewConsoleMessage), 0);
+ g_signal_connect(G_OBJECT(webView), "script-alert", G_CALLBACK(webViewScriptAlert), 0);
+ g_signal_connect(G_OBJECT(webView), "script-prompt", G_CALLBACK(webViewScriptPrompt), 0);
+ g_signal_connect(G_OBJECT(webView), "script-confirm", G_CALLBACK(webViewScriptConfirm), 0);
+
+ if (argc == optind+1 && strcmp(argv[optind], "-") == 0) {
+ char filenameBuffer[2048];
+ printSeparators = true;
+ while (fgets(filenameBuffer, sizeof(filenameBuffer), stdin)) {
+ char* newLineCharacter = strchr(filenameBuffer, '\n');
+ if (newLineCharacter)
+ *newLineCharacter = '\0';
+
+ if (strlen(filenameBuffer) == 0)
+ continue;
+
+ runTest(filenameBuffer);
+ }
+ } else {
+ printSeparators = (optind < argc-1 || (dumpPixels && dumpTree));
+ for (int i = optind; i != argc; ++i)
+ runTest(argv[i]);
+ }
+
+ return 0;
+}
diff --git a/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.pro b/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.pro
new file mode 100644
index 0000000..51fdd65
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.pro
@@ -0,0 +1,19 @@
+TEMPLATE = app
+SOURCES += DumpRenderTree.cpp \
+ ../LayoutTestController.cpp \
+ ../GCController.cpp \
+ ../WorkQueue.cpp \
+ GCControllerGtk.cpp \
+ LayoutTestControllerGtk.cpp \
+ WorkQueueItemGtk.cpp
+
+CONFIG -= app_bundle
+
+BASE_DIR = $$PWD/../../..
+
+include(../../../WebKit.pri)
+
+INCLUDEPATH += \
+ $$BASE_DIR/WebKitTools/DumpRenderTree
+
+QMAKE_RPATHDIR += $$OUTPUT_DIR/lib
diff --git a/WebKitTools/DumpRenderTree/gtk/DumpRenderTreeGtk.h b/WebKitTools/DumpRenderTree/gtk/DumpRenderTreeGtk.h
new file mode 100644
index 0000000..7be651a
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/gtk/DumpRenderTreeGtk.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
+ *
+ * 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 DumpRenderTreeGtk_h
+#define DumpRenderTreeGtk_h
+
+#include <webkit/webkitdefines.h>
+
+extern WebKitWebFrame* mainFrame;
+extern WebKitWebFrame* topLoadingFrame;
+extern guint waitToDumpWatchdog;
+
+#endif // DumpRenderTreeGtk_h
diff --git a/WebKitTools/DumpRenderTree/gtk/GCControllerGtk.cpp b/WebKitTools/DumpRenderTree/gtk/GCControllerGtk.cpp
new file mode 100644
index 0000000..b3e6ad3
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/gtk/GCControllerGtk.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
+ *
+ * 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 "GCController.h"
+
+void GCController::collect() const
+{
+}
+
+void GCController::collectOnAlternateThread(bool waitUntilDone) const
+{
+}
+
+size_t GCController::getJSObjectCount() const
+{
+ return 0;
+}
diff --git a/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp b/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp
new file mode 100644
index 0000000..eae73db
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
+ *
+ * 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 "LayoutTestController.h"
+
+#include "DumpRenderTree.h"
+#include "WorkQueue.h"
+#include "WorkQueueItem.h"
+#include <JavaScriptCore/JSRetainPtr.h>
+#include <JavaScriptCore/JSStringRef.h>
+
+#include <glib.h>
+
+LayoutTestController::~LayoutTestController()
+{
+ // FIXME: implement
+}
+
+void LayoutTestController::addDisallowedURL(JSStringRef url)
+{
+ // FIXME: implement
+}
+
+void LayoutTestController::clearBackForwardList()
+{
+ // FIXME: implement
+}
+
+JSStringRef LayoutTestController::copyDecodedHostName(JSStringRef name)
+{
+ // FIXME: implement
+ return 0;
+}
+
+JSStringRef LayoutTestController::copyEncodedHostName(JSStringRef name)
+{
+ // FIXME: implement
+ return 0;
+}
+
+void LayoutTestController::display()
+{
+ displayWebView();
+}
+
+void LayoutTestController::keepWebHistory()
+{
+ // FIXME: implement
+}
+
+void LayoutTestController::notifyDone()
+{
+ if (m_waitToDump && !topLoadingFrame && !WorkQueue::shared()->count())
+ dump();
+ m_waitToDump = false;
+}
+
+JSStringRef LayoutTestController::pathToLocalResource(JSContextRef context, JSStringRef url)
+{
+ // Function introduced in r28690. This may need special-casing on Windows.
+ return url; // Do nothing on Unix.
+}
+
+void LayoutTestController::queueBackNavigation(int howFarBack)
+{
+ WorkQueue::shared()->queue(new BackItem(howFarBack));
+}
+
+void LayoutTestController::queueForwardNavigation(int howFarForward)
+{
+ WorkQueue::shared()->queue(new ForwardItem(howFarForward));
+}
+
+void LayoutTestController::queueLoad(JSStringRef url, JSStringRef target)
+{
+ // FIXME: We need to resolve relative URLs here
+ WorkQueue::shared()->queue(new LoadItem(url, target));
+}
+
+void LayoutTestController::queueReload()
+{
+ WorkQueue::shared()->queue(new ReloadItem);
+}
+
+void LayoutTestController::queueScript(JSStringRef script)
+{
+ WorkQueue::shared()->queue(new ScriptItem(script));
+}
+
+void LayoutTestController::setAcceptsEditing(bool newAcceptsEditing)
+{
+ // FIXME: implement
+}
+
+void LayoutTestController::setCustomPolicyDelegate(bool setDelegate)
+{
+ // FIXME: implement
+}
+
+void LayoutTestController::setMainFrameIsFirstResponder(bool flag)
+{
+ // FIXME: implement
+}
+
+void LayoutTestController::setTabKeyCyclesThroughElements(bool cycles)
+{
+ // FIXME: implement
+}
+
+void LayoutTestController::setUseDashboardCompatibilityMode(bool flag)
+{
+ // FIXME: implement
+}
+
+void LayoutTestController::setUserStyleSheetEnabled(bool flag)
+{
+ // FIXME: implement
+}
+
+void LayoutTestController::setUserStyleSheetLocation(JSStringRef path)
+{
+ // FIXME: implement
+}
+
+void LayoutTestController::setWindowIsKey(bool windowIsKey)
+{
+ // FIXME: implement
+}
+
+static gboolean waitToDumpWatchdogFired(void*)
+{
+ const char* message = "FAIL: Timed out waiting for notifyDone to be called\n";
+ fprintf(stderr, "%s", message);
+ fprintf(stdout, "%s", message);
+ dump();
+ return FALSE;
+}
+
+void LayoutTestController::setWaitToDump(bool waitUntilDone)
+{
+ static const int timeoutSeconds = 10;
+
+ m_waitToDump = waitUntilDone;
+ if (m_waitToDump && !waitToDumpWatchdog)
+#if GLIB_CHECK_VERSION(2,14,0)
+ waitToDumpWatchdog = g_timeout_add_seconds(timeoutSeconds, waitToDumpWatchdogFired, 0);
+#else
+ waitToDumpWatchdog = g_timeout_add(timeoutSeconds * 1000, waitToDumpWatchdogFired, 0);
+#endif
+}
+
+int LayoutTestController::windowCount()
+{
+ // FIXME: implement
+ return 0;
+}
+
+void LayoutTestController::setPrivateBrowsingEnabled(bool privateBrowsingEnabled)
+{
+ // FIXME: implement
+}
+
+void LayoutTestController::setAuthorAndUserStylesEnabled(bool flag)
+{
+ // FIXME: implement
+}
+
+void LayoutTestController::setPopupBlockingEnabled(bool popupBlockingEnabled)
+{
+ // FIXME: implement
+}
+
+void LayoutTestController::execCommand(JSStringRef name, JSStringRef value)
+{
+ // FIXME: implement
+}
+
+void LayoutTestController::setPersistentUserStyleSheetLocation(JSStringRef jsURL)
+{
+ // FIXME: implement
+}
+
+void LayoutTestController::clearPersistentUserStyleSheet()
+{
+ // FIXME: implement
+}
+
+void LayoutTestController::clearAllDatabases()
+{
+ // FIXME: implement
+}
+
+void LayoutTestController::setDatabaseQuota(unsigned long long quota)
+{
+ // FIXME: implement
+}
+
diff --git a/WebKitTools/DumpRenderTree/gtk/WorkQueueItemGtk.cpp b/WebKitTools/DumpRenderTree/gtk/WorkQueueItemGtk.cpp
new file mode 100644
index 0000000..ee77683
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/gtk/WorkQueueItemGtk.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2007 Alp Toker <alp@atoker.com>
+ *
+ * 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 "WorkQueueItem.h"
+#include "DumpRenderTree.h"
+
+#include <JavaScriptCore/JSStringRef.h>
+#include <webkit/webkit.h>
+
+// Returns a newly allocated UTF-8 character buffer which must be freed with g_free()
+static gchar* JSStringCopyUTF8CString(JSStringRef jsString)
+{
+ size_t dataSize = JSStringGetMaximumUTF8CStringSize(jsString);
+ gchar* utf8 = (gchar*)g_malloc(dataSize);
+ JSStringGetUTF8CString(jsString, utf8, dataSize);
+
+ return utf8;
+}
+
+void LoadItem::invoke() const
+{
+ gchar* targetString = JSStringCopyUTF8CString(target());
+
+ WebKitWebFrame* targetFrame;
+ if (!strlen(targetString))
+ targetFrame = mainFrame;
+ else
+ targetFrame = webkit_web_frame_find_frame(mainFrame, targetString);
+ g_free(targetString);
+
+ gchar* urlString = JSStringCopyUTF8CString(url());
+ WebKitNetworkRequest* request = webkit_network_request_new(urlString);
+ g_free(urlString);
+ webkit_web_frame_load_request(targetFrame, request);
+ g_object_unref(request);
+}
+
+void ReloadItem::invoke() const
+{
+ webkit_web_frame_reload(mainFrame);
+}
+
+void ScriptItem::invoke() const
+{
+ WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame);
+ gchar* scriptString = JSStringCopyUTF8CString(script());
+ // TODO: does this return something we need to free? If not, why not?
+ webkit_web_view_execute_script(webView, scriptString);
+ g_free(scriptString);
+}
+
+void BackForwardItem::invoke() const
+{
+ WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame);
+ webkit_web_view_go_back_or_forward(webView, m_howFar);
+}
diff --git a/WebKitTools/DumpRenderTree/mac/AppleScriptController.h b/WebKitTools/DumpRenderTree/mac/AppleScriptController.h
new file mode 100644
index 0000000..c29789c
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/AppleScriptController.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.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.
+ */
+
+#import <Foundation/Foundation.h>
+
+@class WebView;
+
+@interface AppleScriptController : NSObject
+{
+ WebView *webView;
+}
+- (id)initWithWebView:(WebView *)view;
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/AppleScriptController.m b/WebKitTools/DumpRenderTree/mac/AppleScriptController.m
new file mode 100644
index 0000000..86d2881
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/AppleScriptController.m
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.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.
+ */
+
+#import "AppleScriptController.h"
+
+#import <WebKit/WebView.h>
+#import <WebKit/WebViewPrivate.h> // for aeDescByEvaluatingJavaScriptFromString, which is pending API review
+
+@implementation AppleScriptController
+
++ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
+{
+ if (aSelector == @selector(doJavaScript:))
+ return NO;
+ return YES;
+}
+
++ (NSString *)webScriptNameForSelector:(SEL)aSelector
+{
+ if (aSelector == @selector(doJavaScript:))
+ return @"doJavaScript";
+
+ return nil;
+}
+
+- (id)initWithWebView:(WebView *)wv
+{
+ self = [super init];
+ webView = wv;
+ return self;
+}
+
+static id convertAEDescToObject(NSAppleEventDescriptor *aeDesc)
+{
+ id value = nil;
+
+ DescType descType = [aeDesc descriptorType];
+ switch (descType) {
+ case typeUnicodeText:
+ value = [NSString stringWithFormat:@"\"%@\"", [aeDesc stringValue]];
+ break;
+ case typeLongDateTime:
+ if ([[aeDesc data] length] == sizeof(LongDateTime)) {
+ LongDateTime d;
+ [[aeDesc data] getBytes:&d];
+ value = [NSString stringWithFormat:@"%016llX", (unsigned long long)d];
+ }
+ break;
+ case typeAEList:
+ value = [NSMutableString stringWithString:@"("];
+ int numItems = [aeDesc numberOfItems];
+ for (int i = 0; i < numItems; ++i) {
+ if (i != 0)
+ [(NSMutableString*)value appendString:@", "];
+ id obj = convertAEDescToObject([aeDesc descriptorAtIndex:(i + 1)]);
+ [(NSMutableString*)value appendString:[obj description]];
+ }
+ [(NSMutableString*)value appendString:@")"];
+ break;
+ case typeType: {
+ OSType type = [aeDesc typeCodeValue];
+
+ char typeStr[5];
+ typeStr[0] = type >> 24;
+ typeStr[1] = type >> 16;
+ typeStr[2] = type >> 8;
+ typeStr[3] = type;
+ typeStr[4] = 0;
+
+ value = [NSString stringWithFormat:@"'%s'", typeStr];
+ break;
+ }
+ }
+
+ if (!value)
+ value = [aeDesc stringValue];
+ if (!value)
+ value = [aeDesc data];
+
+ return value;
+}
+
+- (NSString *)doJavaScript:(NSString *)aString
+{
+ NSAppleEventDescriptor *aeDesc = [webView aeDescByEvaluatingJavaScriptFromString:aString];
+ if (!aeDesc)
+ return @"(null)";
+
+ DescType descType = [aeDesc descriptorType];
+ char descTypeStr[5];
+ descTypeStr[0] = descType >> 24;
+ descTypeStr[1] = descType >> 16;
+ descTypeStr[2] = descType >> 8;
+ descTypeStr[3] = descType;
+ descTypeStr[4] = 0;
+
+ return [NSString stringWithFormat:@"%@ ('%s')", convertAEDescToObject(aeDesc), descTypeStr];
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/CheckedMalloc.cpp b/WebKitTools/DumpRenderTree/mac/CheckedMalloc.cpp
new file mode 100644
index 0000000..467f1bb
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/CheckedMalloc.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2005, 2006, 2007 Apple, Inc. All rights reserved.
+ * (C) 2007 Graham Dennis (graham.dennis@gmail.com)
+ * (C) 2007 Eric Seidel <eric@webkit.org>
+ *
+ * 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 "CheckedMalloc.h"
+
+#import <malloc/malloc.h>
+
+static void* (*savedMalloc)(malloc_zone_t*, size_t);
+static void* (*savedRealloc)(malloc_zone_t*, void*, size_t);
+
+static void* checkedMalloc(malloc_zone_t* zone, size_t size)
+{
+ if (size >= 0x10000000)
+ return 0;
+ return savedMalloc(zone, size);
+}
+
+static void* checkedRealloc(malloc_zone_t* zone, void* ptr, size_t size)
+{
+ if (size >= 0x10000000)
+ return 0;
+ return savedRealloc(zone, ptr, size);
+}
+
+void makeLargeMallocFailSilently()
+{
+ malloc_zone_t* zone = malloc_default_zone();
+ savedMalloc = zone->malloc;
+ savedRealloc = zone->realloc;
+ zone->malloc = checkedMalloc;
+ zone->realloc = checkedRealloc;
+}
diff --git a/WebKitTools/DumpRenderTree/mac/CheckedMalloc.h b/WebKitTools/DumpRenderTree/mac/CheckedMalloc.h
new file mode 100644
index 0000000..c03bd20
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/CheckedMalloc.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2005, 2006, 2007 Apple, Inc. All rights reserved.
+ * (C) 2007 Graham Dennis (graham.dennis@gmail.com)
+ * (C) 2007 Eric Seidel <eric@webkit.org>
+ *
+ * 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.
+ */
+
+void makeLargeMallocFailSilently();
diff --git a/WebKitTools/DumpRenderTree/mac/Configurations/Base.xcconfig b/WebKitTools/DumpRenderTree/mac/Configurations/Base.xcconfig
new file mode 100644
index 0000000..d2291a0
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/Configurations/Base.xcconfig
@@ -0,0 +1,16 @@
+HEADER_SEARCH_PATHS = ForwardingHeaders
+FRAMEWORK_SEARCH_PATHS = $(FRAMEWORK_SEARCH_PATHS_$(MAC_OS_X_VERSION_MAJOR));
+FRAMEWORK_SEARCH_PATHS_ = $(SYSTEM_LIBRARY_DIR)/Frameworks/Quartz.framework/Frameworks $(SYSTEM_LIBRARY_DIR)/Frameworks/ApplicationServices.framework/Frameworks
+FRAMEWORK_SEARCH_PATHS_1040 = $(SYSTEM_LIBRARY_DIR)/Frameworks/Quartz.framework/Frameworks $(SYSTEM_LIBRARY_DIR)/Frameworks/ApplicationServices.framework/Frameworks
+FRAMEWORK_SEARCH_PATHS_1050 = $(SYSTEM_LIBRARY_DIR)/Frameworks/Quartz.framework/Frameworks $(SYSTEM_LIBRARY_DIR)/Frameworks/ApplicationServices.framework/Frameworks $(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks
+FRAMEWORK_SEARCH_PATHS_1060 = $(SYSTEM_LIBRARY_DIR)/Frameworks/Quartz.framework/Frameworks $(SYSTEM_LIBRARY_DIR)/Frameworks/ApplicationServices.framework/Frameworks $(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks
+DEBUG_INFORMATION_FORMAT = dwarf
+PREBINDING = NO
+GCC_C_LANGUAGE_STANDARD = gnu99
+GCC_PRECOMPILE_PREFIX_HEADER = YES
+GCC_TREAT_WARNINGS_AS_ERRORS = YES
+GCC_WARN_UNUSED_FUNCTION = YES
+GCC_WARN_UNUSED_VARIABLE = YES
+GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO
+WARNING_CFLAGS = -Wall -W -Wno-unused-parameter
+VALID_ARCHS = ppc7400 ppc970 i386 ppc
diff --git a/WebKitTools/DumpRenderTree/mac/Configurations/DebugRelease.xcconfig b/WebKitTools/DumpRenderTree/mac/Configurations/DebugRelease.xcconfig
new file mode 100644
index 0000000..e17439e
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/Configurations/DebugRelease.xcconfig
@@ -0,0 +1,5 @@
+#include "Base.xcconfig"
+MACOSX_DEPLOYMENT_TARGET = $(MACOSX_DEPLOYMENT_TARGET_$(MAC_OS_X_VERSION_MAJOR))
+MACOSX_DEPLOYMENT_TARGET_ = 10.4
+MACOSX_DEPLOYMENT_TARGET_1040 = 10.4
+MACOSX_DEPLOYMENT_TARGET_1050 = 10.5
diff --git a/WebKitTools/DumpRenderTree/mac/Configurations/DumpRenderTree.xcconfig b/WebKitTools/DumpRenderTree/mac/Configurations/DumpRenderTree.xcconfig
new file mode 100644
index 0000000..c8a7bdc
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/Configurations/DumpRenderTree.xcconfig
@@ -0,0 +1,4 @@
+OTHER_LDFLAGS = -sectcreate __DATA Ahem qt/fonts/AHEM____.TTF
+PRODUCT_NAME = DumpRenderTree
+GCC_ENABLE_OBJC_EXCEPTIONS = YES
+GCC_PREFIX_HEADER = DumpRenderTreePrefix.h
diff --git a/WebKitTools/DumpRenderTree/mac/Configurations/ImageDiff.xcconfig b/WebKitTools/DumpRenderTree/mac/Configurations/ImageDiff.xcconfig
new file mode 100644
index 0000000..fcd64c5
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/Configurations/ImageDiff.xcconfig
@@ -0,0 +1 @@
+PRODUCT_NAME = ImageDiff
diff --git a/WebKitTools/DumpRenderTree/mac/Configurations/TestNetscapePlugIn.xcconfig b/WebKitTools/DumpRenderTree/mac/Configurations/TestNetscapePlugIn.xcconfig
new file mode 100644
index 0000000..ea17629
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/Configurations/TestNetscapePlugIn.xcconfig
@@ -0,0 +1,6 @@
+PRODUCT_NAME = TestNetscapePlugIn
+WRAPPER_EXTENSION = plugin
+INFOPLIST_FILE = TestNetscapePlugIn.subproj/Info.plist
+INSTALL_PATH = "$(USER_LIBRARY_DIR)/Plugins"
+WARNING_CFLAGS = -Wmost -Wno-four-char-constants -Wno-unknown-pragmas
+LIBRARY_STYLE = BUNDLE
diff --git a/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm b/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm
new file mode 100644
index 0000000..4d5ea72
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm
@@ -0,0 +1,931 @@
+/*
+ * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
+ * (C) 2007 Graham Dennis (graham.dennis@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.
+ */
+
+#import "DumpRenderTree.h"
+
+#import "CheckedMalloc.h"
+#import "DumpRenderTreePasteboard.h"
+#import "DumpRenderTreeWindow.h"
+#import "EditingDelegate.h"
+#import "EventSendingController.h"
+#import "FrameLoadDelegate.h"
+#import "JavaScriptThreading.h"
+#import "LayoutTestController.h"
+#import "NavigationController.h"
+#import "ObjCPlugin.h"
+#import "ObjCPluginFunction.h"
+#import "PixelDumpSupport.h"
+#import "PolicyDelegate.h"
+#import "ResourceLoadDelegate.h"
+#import "UIDelegate.h"
+#import "WorkQueue.h"
+#import "WorkQueueItem.h"
+#import <CoreFoundation/CoreFoundation.h>
+#import <WebKit/DOMElementPrivate.h>
+#import <WebKit/DOMExtensions.h>
+#import <WebKit/DOMRange.h>
+#import <WebKit/WebBackForwardList.h>
+#import <WebKit/WebCoreStatistics.h>
+#import <WebKit/WebDatabaseManagerPrivate.h>
+#import <WebKit/WebDataSourcePrivate.h>
+#import <WebKit/WebDocumentPrivate.h>
+#import <WebKit/WebEditingDelegate.h>
+#import <WebKit/WebFrameView.h>
+#import <WebKit/WebHistory.h>
+#import <WebKit/WebHistoryItemPrivate.h>
+#import <WebKit/WebPluginDatabase.h>
+#import <WebKit/WebPreferences.h>
+#import <WebKit/WebPreferencesPrivate.h>
+#import <WebKit/WebResourceLoadDelegate.h>
+#import <WebKit/WebViewPrivate.h>
+#import <getopt.h>
+#import <mach-o/getsect.h>
+#import <objc/objc-runtime.h>
+#import <wtf/Assertions.h>
+#import <wtf/RetainPtr.h>
+
+@interface DumpRenderTreeEvent : NSEvent
+@end
+
+static void runTest(const char *pathOrURL);
+
+// Deciding when it's OK to dump out the state is a bit tricky. All these must be true:
+// - There is no load in progress
+// - There is no work queued up (see workQueue var, below)
+// - waitToDump==NO. This means either waitUntilDone was never called, or it was called
+// and notifyDone was called subsequently.
+// Note that the call to notifyDone and the end of the load can happen in either order.
+
+volatile bool done;
+
+NavigationController* navigationController = 0;
+LayoutTestController* layoutTestController = 0;
+
+WebFrame *mainFrame = 0;
+// This is the topmost frame that is loading, during a given load, or nil when no load is
+// in progress. Usually this is the same as the main frame, but not always. In the case
+// where a frameset is loaded, and then new content is loaded into one of the child frames,
+// that child frame is the "topmost frame that is loading".
+WebFrame *topLoadingFrame = nil; // !nil iff a load is in progress
+
+
+CFMutableSetRef disallowedURLs = 0;
+CFRunLoopTimerRef waitToDumpWatchdog = 0;
+
+// Delegates
+static FrameLoadDelegate *frameLoadDelegate;
+static UIDelegate *uiDelegate;
+static EditingDelegate *editingDelegate;
+static ResourceLoadDelegate *resourceLoadDelegate;
+PolicyDelegate *policyDelegate;
+
+static int dumpPixels;
+static int dumpAllPixels;
+static int threaded;
+static int testRepaintDefault;
+static int repaintSweepHorizontallyDefault;
+static int dumpTree = YES;
+static BOOL printSeparators;
+static NSString *currentTest = nil;
+static RetainPtr<CFStringRef> persistentUserStyleSheetLocation;
+
+static WebHistoryItem *prevTestBFItem = nil; // current b/f item at the end of the previous test
+
+const unsigned maxViewHeight = 600;
+const unsigned maxViewWidth = 800;
+
+void setPersistentUserStyleSheetLocation(CFStringRef url)
+{
+ persistentUserStyleSheetLocation = url;
+}
+
+static BOOL shouldIgnoreWebCoreNodeLeaks(CFStringRef URLString)
+{
+ static CFStringRef const ignoreSet[] = {
+ // Keeping this infrastructure around in case we ever need it again.
+ };
+ static const int ignoreSetCount = sizeof(ignoreSet) / sizeof(CFStringRef);
+
+ for (int i = 0; i < ignoreSetCount; i++) {
+ CFStringRef ignoreString = ignoreSet[i];
+ CFRange range = CFRangeMake(0, CFStringGetLength(URLString));
+ CFOptionFlags flags = kCFCompareAnchored | kCFCompareBackwards | kCFCompareCaseInsensitive;
+ if (CFStringFindWithOptions(URLString, ignoreString, range, flags, NULL))
+ return YES;
+ }
+ return NO;
+}
+
+static void activateAhemFont()
+{
+ unsigned long fontDataLength;
+ char* fontData = getsectdata("__DATA", "Ahem", &fontDataLength);
+ if (!fontData) {
+ fprintf(stderr, "Failed to locate the Ahem font.\n");
+ exit(1);
+ }
+
+ ATSFontContainerRef fontContainer;
+ OSStatus status = ATSFontActivateFromMemory(fontData, fontDataLength, kATSFontContextLocal, kATSFontFormatUnspecified, NULL, kATSOptionFlagsDefault, &fontContainer);
+
+ if (status != noErr) {
+ fprintf(stderr, "Failed to activate the Ahem font.\n");
+ exit(1);
+ }
+}
+
+WebView *createWebViewAndOffscreenWindow()
+{
+ NSRect rect = NSMakeRect(0, 0, maxViewWidth, maxViewHeight);
+ WebView *webView = [[WebView alloc] initWithFrame:rect frameName:nil groupName:@"org.webkit.DumpRenderTree"];
+
+ [webView setUIDelegate:uiDelegate];
+ [webView setFrameLoadDelegate:frameLoadDelegate];
+ [webView setEditingDelegate:editingDelegate];
+ [webView setResourceLoadDelegate:resourceLoadDelegate];
+
+ // Register the same schemes that Safari does
+ [WebView registerURLSchemeAsLocal:@"feed"];
+ [WebView registerURLSchemeAsLocal:@"feeds"];
+ [WebView registerURLSchemeAsLocal:@"feedsearch"];
+
+ [webView setContinuousSpellCheckingEnabled:YES];
+
+ // To make things like certain NSViews, dragging, and plug-ins work, put the WebView a window, but put it off-screen so you don't see it.
+ // Put it at -10000, -10000 in "flipped coordinates", since WebCore and the DOM use flipped coordinates.
+ NSRect windowRect = NSOffsetRect(rect, -10000, [[[NSScreen screens] objectAtIndex:0] frame].size.height - rect.size.height + 10000);
+ DumpRenderTreeWindow *window = [[DumpRenderTreeWindow alloc] initWithContentRect:windowRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES];
+ [[window contentView] addSubview:webView];
+ [window orderBack:nil];
+ [window setAutodisplay:NO];
+
+ // For reasons that are not entirely clear, the following pair of calls makes WebView handle its
+ // dynamic scrollbars properly. Without it, every frame will always have scrollbars.
+ NSBitmapImageRep *imageRep = [webView bitmapImageRepForCachingDisplayInRect:[webView bounds]];
+ [webView cacheDisplayInRect:[webView bounds] toBitmapImageRep:imageRep];
+
+ return webView;
+}
+
+void testStringByEvaluatingJavaScriptFromString()
+{
+ // maps expected result <= JavaScript expression
+ NSDictionary *expressions = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"0", @"0",
+ @"0", @"'0'",
+ @"", @"",
+ @"", @"''",
+ @"", @"new String()",
+ @"", @"new String('0')",
+ @"", @"throw 1",
+ @"", @"{ }",
+ @"", @"[ ]",
+ @"", @"//",
+ @"", @"a.b.c",
+ @"", @"(function() { throw 'error'; })()",
+ @"", @"null",
+ @"", @"undefined",
+ @"true", @"true",
+ @"false", @"false",
+ nil
+ ];
+
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ WebView *webView = [[WebView alloc] initWithFrame:NSZeroRect frameName:@"" groupName:@""];
+
+ NSEnumerator *enumerator = [expressions keyEnumerator];
+ id expression;
+ while ((expression = [enumerator nextObject])) {
+ NSString *expectedResult = [expressions objectForKey:expression];
+ NSString *result = [webView stringByEvaluatingJavaScriptFromString:expression];
+ assert([result isEqualToString:expectedResult]);
+ }
+
+ [webView close];
+ [webView release];
+ [pool release];
+}
+
+static void setDefaultsToConsistentValuesForTesting()
+{
+ // Give some clear to undocumented defaults values
+ static const int MediumFontSmoothing = 2;
+ static const int BlueTintedAppearance = 1;
+
+ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+ [defaults setObject:@"DoubleMax" forKey:@"AppleScrollBarVariant"];
+ [defaults setInteger:4 forKey:@"AppleAntiAliasingThreshold"]; // smallest font size to CG should perform antialiasing on
+ [defaults setInteger:MediumFontSmoothing forKey:@"AppleFontSmoothing"];
+ [defaults setInteger:BlueTintedAppearance forKey:@"AppleAquaColorVariant"];
+ [defaults setObject:@"0.709800 0.835300 1.000000" forKey:@"AppleHighlightColor"];
+ [defaults setObject:@"0.500000 0.500000 0.500000" forKey:@"AppleOtherHighlightColor"];
+ [defaults setObject:[NSArray arrayWithObject:@"en"] forKey:@"AppleLanguages"];
+
+ NSString *libraryPath = [@"~/Library/Application Support/DumpRenderTree" stringByExpandingTildeInPath];
+ [defaults setObject:[libraryPath stringByAppendingPathComponent:@"Databases"] forKey:WebDatabaseDirectoryDefaultsKey];
+
+ WebPreferences *preferences = [WebPreferences standardPreferences];
+
+ [preferences setStandardFontFamily:@"Times"];
+ [preferences setFixedFontFamily:@"Courier"];
+ [preferences setSerifFontFamily:@"Times"];
+ [preferences setSansSerifFontFamily:@"Helvetica"];
+ [preferences setCursiveFontFamily:@"Apple Chancery"];
+ [preferences setFantasyFontFamily:@"Papyrus"];
+ [preferences setDefaultFontSize:16];
+ [preferences setDefaultFixedFontSize:13];
+ [preferences setMinimumFontSize:1];
+ [preferences setJavaEnabled:NO];
+ [preferences setEditableLinkBehavior:WebKitEditableLinkOnlyLiveWithShiftKey];
+ [preferences setTabsToLinks:NO];
+ [preferences setDOMPasteAllowed:YES];
+
+ // The back/forward cache is causing problems due to layouts during transition from one page to another.
+ // So, turn it off for now, but we might want to turn it back on some day.
+ [preferences setUsesPageCache:NO];
+}
+
+static void crashHandler(int sig)
+{
+ fprintf(stderr, "%s\n", strsignal(sig));
+ restoreColorSpace(0);
+ exit(128 + sig);
+}
+
+static void installSignalHandlers()
+{
+ signal(SIGILL, crashHandler); /* 4: illegal instruction (not reset when caught) */
+ signal(SIGTRAP, crashHandler); /* 5: trace trap (not reset when caught) */
+ signal(SIGEMT, crashHandler); /* 7: EMT instruction */
+ signal(SIGFPE, crashHandler); /* 8: floating point exception */
+ signal(SIGBUS, crashHandler); /* 10: bus error */
+ signal(SIGSEGV, crashHandler); /* 11: segmentation violation */
+ signal(SIGSYS, crashHandler); /* 12: bad argument to system call */
+ signal(SIGPIPE, crashHandler); /* 13: write on a pipe with no reader */
+ signal(SIGXCPU, crashHandler); /* 24: exceeded CPU time limit */
+ signal(SIGXFSZ, crashHandler); /* 25: exceeded file size limit */
+}
+
+static void allocateGlobalControllers()
+{
+ // FIXME: We should remove these and move to the ObjC standard [Foo sharedInstance] model
+ navigationController = [[NavigationController alloc] init];
+ frameLoadDelegate = [[FrameLoadDelegate alloc] init];
+ uiDelegate = [[UIDelegate alloc] init];
+ editingDelegate = [[EditingDelegate alloc] init];
+ resourceLoadDelegate = [[ResourceLoadDelegate alloc] init];
+ policyDelegate = [[PolicyDelegate alloc] init];
+}
+
+// ObjC++ doens't seem to let me pass NSObject*& sadly.
+static inline void releaseAndZero(NSObject** object)
+{
+ [*object release];
+ *object = nil;
+}
+
+static void releaseGlobalControllers()
+{
+ releaseAndZero(&navigationController);
+ releaseAndZero(&frameLoadDelegate);
+ releaseAndZero(&editingDelegate);
+ releaseAndZero(&resourceLoadDelegate);
+ releaseAndZero(&uiDelegate);
+ releaseAndZero(&policyDelegate);
+}
+
+static void initializeGlobalsFromCommandLineOptions(int argc, const char *argv[])
+{
+ struct option options[] = {
+ {"dump-all-pixels", no_argument, &dumpAllPixels, YES},
+ {"horizontal-sweep", no_argument, &repaintSweepHorizontallyDefault, YES},
+ {"notree", no_argument, &dumpTree, NO},
+ {"pixel-tests", no_argument, &dumpPixels, YES},
+ {"repaint", no_argument, &testRepaintDefault, YES},
+ {"tree", no_argument, &dumpTree, YES},
+ {"threaded", no_argument, &threaded, YES},
+ {NULL, 0, NULL, 0}
+ };
+
+ int option;
+ while ((option = getopt_long(argc, (char * const *)argv, "", options, NULL)) != -1) {
+ switch (option) {
+ case '?': // unknown or ambiguous option
+ case ':': // missing argument
+ exit(1);
+ break;
+ }
+ }
+}
+
+static void addTestPluginsToPluginSearchPath(const char* executablePath)
+{
+ NSString *pwd = [[NSString stringWithUTF8String:executablePath] stringByDeletingLastPathComponent];
+ [WebPluginDatabase setAdditionalWebPlugInPaths:[NSArray arrayWithObject:pwd]];
+ [[WebPluginDatabase sharedDatabase] refresh];
+}
+
+static bool useLongRunningServerMode(int argc, const char *argv[])
+{
+ // This assumes you've already called getopt_long
+ return (argc == optind+1 && strcmp(argv[optind], "-") == 0);
+}
+
+static void runTestingServerLoop()
+{
+ // When DumpRenderTree run in server mode, we just wait around for file names
+ // to be passed to us and read each in turn, passing the results back to the client
+ char filenameBuffer[2048];
+ while (fgets(filenameBuffer, sizeof(filenameBuffer), stdin)) {
+ char *newLineCharacter = strchr(filenameBuffer, '\n');
+ if (newLineCharacter)
+ *newLineCharacter = '\0';
+
+ if (strlen(filenameBuffer) == 0)
+ continue;
+
+ runTest(filenameBuffer);
+ }
+}
+
+static void prepareConsistentTestingEnvironment()
+{
+ class_poseAs(objc_getClass("DumpRenderTreePasteboard"), objc_getClass("NSPasteboard"));
+ class_poseAs(objc_getClass("DumpRenderTreeEvent"), objc_getClass("NSEvent"));
+
+ setDefaultsToConsistentValuesForTesting();
+ activateAhemFont();
+
+ if (dumpPixels)
+ initializeColorSpaceAndScreeBufferForPixelTests();
+ allocateGlobalControllers();
+
+ makeLargeMallocFailSilently();
+}
+
+void dumpRenderTree(int argc, const char *argv[])
+{
+ initializeGlobalsFromCommandLineOptions(argc, argv);
+ prepareConsistentTestingEnvironment();
+ addTestPluginsToPluginSearchPath(argv[0]);
+ if (dumpPixels)
+ installSignalHandlers();
+
+ WebView *webView = createWebViewAndOffscreenWindow();
+ mainFrame = [webView mainFrame];
+
+ [[NSURLCache sharedURLCache] removeAllCachedResponses];
+
+ // <rdar://problem/5222911>
+ testStringByEvaluatingJavaScriptFromString();
+
+ if (threaded)
+ startJavaScriptThreads();
+
+ if (useLongRunningServerMode(argc, argv)) {
+ printSeparators = YES;
+ runTestingServerLoop();
+ } else {
+ printSeparators = (optind < argc-1 || (dumpPixels && dumpTree));
+ for (int i = optind; i != argc; ++i)
+ runTest(argv[i]);
+ }
+
+ if (threaded)
+ stopJavaScriptThreads();
+
+ [WebCoreStatistics emptyCache]; // Otherwise SVGImages trigger false positives for Frame/Node counts
+ [webView close];
+ mainFrame = nil;
+
+ // Work around problem where registering drag types leaves an outstanding
+ // "perform selector" on the window, which retains the window. It's a bit
+ // inelegant and perhaps dangerous to just blow them all away, but in practice
+ // it probably won't cause any trouble (and this is just a test tool, after all).
+ NSWindow *window = [webView window];
+ [NSObject cancelPreviousPerformRequestsWithTarget:window];
+
+ [window close]; // releases when closed
+ [webView release];
+
+ releaseGlobalControllers();
+
+ [DumpRenderTreePasteboard releaseLocalPasteboards];
+
+ // FIXME: This should be moved onto LayoutTestController and made into a HashSet
+ if (disallowedURLs) {
+ CFRelease(disallowedURLs);
+ disallowedURLs = 0;
+ }
+
+ if (dumpPixels)
+ restoreColorSpace(0);
+}
+
+int main(int argc, const char *argv[])
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ [NSApplication sharedApplication]; // Force AppKit to init itself
+ dumpRenderTree(argc, argv);
+ [WebCoreStatistics garbageCollectJavaScriptObjects];
+ [pool release];
+ return 0;
+}
+
+static int compareHistoryItems(id item1, id item2, void *context)
+{
+ return [[item1 target] caseInsensitiveCompare:[item2 target]];
+}
+
+static void dumpHistoryItem(WebHistoryItem *item, int indent, BOOL current)
+{
+ int start = 0;
+ if (current) {
+ printf("curr->");
+ start = 6;
+ }
+ for (int i = start; i < indent; i++)
+ putchar(' ');
+ printf("%s", [[item URLString] UTF8String]);
+ NSString *target = [item target];
+ if (target && [target length] > 0)
+ printf(" (in frame \"%s\")", [target UTF8String]);
+ if ([item isTargetItem])
+ printf(" **nav target**");
+ putchar('\n');
+ NSArray *kids = [item children];
+ if (kids) {
+ // must sort to eliminate arbitrary result ordering which defeats reproducible testing
+ kids = [kids sortedArrayUsingFunction:&compareHistoryItems context:nil];
+ for (unsigned i = 0; i < [kids count]; i++)
+ dumpHistoryItem([kids objectAtIndex:i], indent+4, NO);
+ }
+}
+
+static void dumpFrameScrollPosition(WebFrame *f)
+{
+ NSPoint scrollPosition = [[[[f frameView] documentView] superview] bounds].origin;
+ if (ABS(scrollPosition.x) > 0.00000001 || ABS(scrollPosition.y) > 0.00000001) {
+ if ([f parentFrame] != nil)
+ printf("frame '%s' ", [[f name] UTF8String]);
+ printf("scrolled to %.f,%.f\n", scrollPosition.x, scrollPosition.y);
+ }
+
+ if (layoutTestController->dumpChildFrameScrollPositions()) {
+ NSArray *kids = [f childFrames];
+ if (kids)
+ for (unsigned i = 0; i < [kids count]; i++)
+ dumpFrameScrollPosition([kids objectAtIndex:i]);
+ }
+}
+
+static NSString *dumpFramesAsText(WebFrame *frame)
+{
+ DOMDocument *document = [frame DOMDocument];
+ DOMElement *documentElement = [document documentElement];
+
+ if (!documentElement)
+ return @"";
+
+ NSMutableString *result = [[[NSMutableString alloc] init] autorelease];
+
+ // Add header for all but the main frame.
+ if ([frame parentFrame])
+ result = [NSMutableString stringWithFormat:@"\n--------\nFrame: '%@'\n--------\n", [frame name]];
+
+ [result appendFormat:@"%@\n", [documentElement innerText]];
+
+ if (layoutTestController->dumpChildFramesAsText()) {
+ NSArray *kids = [frame childFrames];
+ if (kids) {
+ for (unsigned i = 0; i < [kids count]; i++)
+ [result appendString:dumpFramesAsText([kids objectAtIndex:i])];
+ }
+ }
+
+ return result;
+}
+
+static void convertMIMEType(NSMutableString *mimeType)
+{
+ if ([mimeType isEqualToString:@"application/x-javascript"])
+ [mimeType setString:@"text/javascript"];
+}
+
+static void convertWebResourceDataToString(NSMutableDictionary *resource)
+{
+ NSMutableString *mimeType = [resource objectForKey:@"WebResourceMIMEType"];
+ convertMIMEType(mimeType);
+
+ if ([mimeType hasPrefix:@"text/"]) {
+ NSData *data = [resource objectForKey:@"WebResourceData"];
+ NSString *dataAsString = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
+ [resource setObject:dataAsString forKey:@"WebResourceData"];
+ }
+}
+
+static void normalizeWebResourceURL(NSMutableString *webResourceURL)
+{
+ static int fileUrlLength = [@"file://" length];
+ NSRange layoutTestsWebArchivePathRange = [webResourceURL rangeOfString:@"/LayoutTests/" options:NSBackwardsSearch];
+ if (layoutTestsWebArchivePathRange.location == NSNotFound)
+ return;
+ NSRange currentWorkingDirectoryRange = NSMakeRange(fileUrlLength, layoutTestsWebArchivePathRange.location - fileUrlLength);
+ [webResourceURL replaceCharactersInRange:currentWorkingDirectoryRange withString:@""];
+}
+
+static void convertWebResourceResponseToDictionary(NSMutableDictionary *propertyList)
+{
+ NSURLResponse *response = nil;
+ NSData *responseData = [propertyList objectForKey:@"WebResourceResponse"]; // WebResourceResponseKey in WebResource.m
+ if ([responseData isKindOfClass:[NSData class]]) {
+ // Decode NSURLResponse
+ NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:responseData];
+ response = [unarchiver decodeObjectForKey:@"WebResourceResponse"]; // WebResourceResponseKey in WebResource.m
+ [unarchiver finishDecoding];
+ [unarchiver release];
+ }
+
+ NSMutableDictionary *responseDictionary = [[NSMutableDictionary alloc] init];
+
+ NSMutableString *urlString = [[[response URL] description] mutableCopy];
+ normalizeWebResourceURL(urlString);
+ [responseDictionary setObject:urlString forKey:@"URL"];
+ [urlString release];
+
+ NSMutableString *mimeTypeString = [[response MIMEType] mutableCopy];
+ convertMIMEType(mimeTypeString);
+ [responseDictionary setObject:mimeTypeString forKey:@"MIMEType"];
+ [mimeTypeString release];
+
+ NSString *textEncodingName = [response textEncodingName];
+ if (textEncodingName)
+ [responseDictionary setObject:textEncodingName forKey:@"textEncodingName"];
+ [responseDictionary setObject:[NSNumber numberWithLongLong:[response expectedContentLength]] forKey:@"expectedContentLength"];
+
+ if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
+ NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
+
+ [responseDictionary setObject:[httpResponse allHeaderFields] forKey:@"allHeaderFields"];
+ [responseDictionary setObject:[NSNumber numberWithInt:[httpResponse statusCode]] forKey:@"statusCode"];
+ }
+
+ [propertyList setObject:responseDictionary forKey:@"WebResourceResponse"];
+ [responseDictionary release];
+}
+
+static NSString *serializeWebArchiveToXML(WebArchive *webArchive)
+{
+ NSString *errorString;
+ NSMutableDictionary *propertyList = [NSPropertyListSerialization propertyListFromData:[webArchive data]
+ mutabilityOption:NSPropertyListMutableContainersAndLeaves
+ format:NULL
+ errorDescription:&errorString];
+ if (!propertyList)
+ return errorString;
+
+ NSMutableArray *resources = [NSMutableArray arrayWithCapacity:1];
+ [resources addObject:propertyList];
+
+ while ([resources count]) {
+ NSMutableDictionary *resourcePropertyList = [resources objectAtIndex:0];
+ [resources removeObjectAtIndex:0];
+
+ NSMutableDictionary *mainResource = [resourcePropertyList objectForKey:@"WebMainResource"];
+ normalizeWebResourceURL([mainResource objectForKey:@"WebResourceURL"]);
+ convertWebResourceDataToString(mainResource);
+
+ // Add subframeArchives to list for processing
+ NSMutableArray *subframeArchives = [resourcePropertyList objectForKey:@"WebSubframeArchives"]; // WebSubframeArchivesKey in WebArchive.m
+ if (subframeArchives)
+ [resources addObjectsFromArray:subframeArchives];
+
+ NSMutableArray *subresources = [resourcePropertyList objectForKey:@"WebSubresources"]; // WebSubresourcesKey in WebArchive.m
+ NSEnumerator *enumerator = [subresources objectEnumerator];
+ NSMutableDictionary *subresourcePropertyList;
+ while ((subresourcePropertyList = [enumerator nextObject])) {
+ normalizeWebResourceURL([subresourcePropertyList objectForKey:@"WebResourceURL"]);
+ convertWebResourceResponseToDictionary(subresourcePropertyList);
+ convertWebResourceDataToString(subresourcePropertyList);
+ }
+ }
+
+ NSData *xmlData = [NSPropertyListSerialization dataFromPropertyList:propertyList
+ format:NSPropertyListXMLFormat_v1_0
+ errorDescription:&errorString];
+ if (!xmlData)
+ return errorString;
+
+ NSMutableString *string = [[[NSMutableString alloc] initWithData:xmlData encoding:NSUTF8StringEncoding] autorelease];
+
+ // Replace "Apple Computer" with "Apple" in the DTD declaration.
+ NSRange range = [string rangeOfString:@"-//Apple Computer//"];
+ if (range.location != NSNotFound)
+ [string replaceCharactersInRange:range withString:@"-//Apple//"];
+
+ return string;
+}
+
+static void dumpBackForwardListForWebView(WebView *view)
+{
+ printf("\n============== Back Forward List ==============\n");
+ WebBackForwardList *bfList = [view backForwardList];
+
+ // Print out all items in the list after prevTestBFItem, which was from the previous test
+ // Gather items from the end of the list, the print them out from oldest to newest
+ NSMutableArray *itemsToPrint = [[NSMutableArray alloc] init];
+ for (int i = [bfList forwardListCount]; i > 0; i--) {
+ WebHistoryItem *item = [bfList itemAtIndex:i];
+ // something is wrong if the item from the last test is in the forward part of the b/f list
+ assert(item != prevTestBFItem);
+ [itemsToPrint addObject:item];
+ }
+
+ assert([bfList currentItem] != prevTestBFItem);
+ [itemsToPrint addObject:[bfList currentItem]];
+ int currentItemIndex = [itemsToPrint count] - 1;
+
+ for (int i = -1; i >= -[bfList backListCount]; i--) {
+ WebHistoryItem *item = [bfList itemAtIndex:i];
+ if (item == prevTestBFItem)
+ break;
+ [itemsToPrint addObject:item];
+ }
+
+ for (int i = [itemsToPrint count]-1; i >= 0; i--)
+ dumpHistoryItem([itemsToPrint objectAtIndex:i], 8, i == currentItemIndex);
+
+ [itemsToPrint release];
+ printf("===============================================\n");
+}
+
+static void sizeWebViewForCurrentTest()
+{
+ // W3C SVG tests expect to be 480x360
+ bool isSVGW3CTest = ([currentTest rangeOfString:@"svg/W3C-SVG-1.1"].length);
+ if (isSVGW3CTest)
+ [[mainFrame webView] setFrameSize:NSMakeSize(480, 360)];
+ else
+ [[mainFrame webView] setFrameSize:NSMakeSize(maxViewWidth, maxViewHeight)];
+}
+
+static const char *methodNameStringForFailedTest()
+{
+ const char *errorMessage;
+ if (layoutTestController->dumpAsText())
+ errorMessage = "[documentElement innerText]";
+ else if (layoutTestController->dumpDOMAsWebArchive())
+ errorMessage = "[[mainFrame DOMDocument] webArchive]";
+ else if (layoutTestController->dumpSourceAsWebArchive())
+ errorMessage = "[[mainFrame dataSource] webArchive]";
+ else
+ errorMessage = "[mainFrame renderTreeAsExternalRepresentation]";
+
+ return errorMessage;
+}
+
+static void dumpBackForwardListForAllWindows()
+{
+ CFArrayRef openWindows = (CFArrayRef)[DumpRenderTreeWindow openWindows];
+ unsigned count = CFArrayGetCount(openWindows);
+ for (unsigned i = 0; i < count; i++) {
+ NSWindow *window = (NSWindow *)CFArrayGetValueAtIndex(openWindows, i);
+ WebView *webView = [[[window contentView] subviews] objectAtIndex:0];
+ dumpBackForwardListForWebView(webView);
+ }
+}
+
+static void invalidateAnyPreviousWaitToDumpWatchdog()
+{
+ if (waitToDumpWatchdog) {
+ CFRunLoopTimerInvalidate(waitToDumpWatchdog);
+ CFRelease(waitToDumpWatchdog);
+ waitToDumpWatchdog = 0;
+ }
+}
+
+void dump()
+{
+ invalidateAnyPreviousWaitToDumpWatchdog();
+
+ if (dumpTree) {
+ NSString *resultString = nil;
+ NSData *resultData = nil;
+
+ bool dumpAsText = layoutTestController->dumpAsText();
+ dumpAsText |= [[[mainFrame dataSource] _responseMIMEType] isEqualToString:@"text/plain"];
+ layoutTestController->setDumpAsText(dumpAsText);
+ if (layoutTestController->dumpAsText()) {
+ resultString = dumpFramesAsText(mainFrame);
+ } else if (layoutTestController->dumpDOMAsWebArchive()) {
+ WebArchive *webArchive = [[mainFrame DOMDocument] webArchive];
+ resultString = serializeWebArchiveToXML(webArchive);
+ } else if (layoutTestController->dumpSourceAsWebArchive()) {
+ WebArchive *webArchive = [[mainFrame dataSource] webArchive];
+ resultString = serializeWebArchiveToXML(webArchive);
+ } else {
+ sizeWebViewForCurrentTest();
+ resultString = [mainFrame renderTreeAsExternalRepresentation];
+ }
+
+ if (resultString && !resultData)
+ resultData = [resultString dataUsingEncoding:NSUTF8StringEncoding];
+
+ if (resultData) {
+ fwrite([resultData bytes], 1, [resultData length], stdout);
+
+ if (!layoutTestController->dumpAsText() && !layoutTestController->dumpDOMAsWebArchive() && !layoutTestController->dumpSourceAsWebArchive())
+ dumpFrameScrollPosition(mainFrame);
+
+ if (layoutTestController->dumpBackForwardList())
+ dumpBackForwardListForAllWindows();
+ } else
+ printf("ERROR: nil result from %s", methodNameStringForFailedTest());
+
+ if (printSeparators)
+ puts("#EOF");
+ }
+
+ if (dumpPixels)
+ dumpWebViewAsPixelsAndCompareWithExpected([currentTest UTF8String], dumpAllPixels);
+
+ fflush(stdout);
+
+ done = YES;
+}
+
+static bool shouldLogFrameLoadDelegates(const char *pathOrURL)
+{
+ return strstr(pathOrURL, "loading/");
+}
+
+static CFURLRef createCFURLFromPathOrURL(CFStringRef pathOrURLString)
+{
+ CFURLRef URL;
+ if (CFStringHasPrefix(pathOrURLString, CFSTR("http://")) || CFStringHasPrefix(pathOrURLString, CFSTR("https://")))
+ URL = CFURLCreateWithString(NULL, pathOrURLString, NULL);
+ else
+ URL = CFURLCreateWithFileSystemPath(NULL, pathOrURLString, kCFURLPOSIXPathStyle, FALSE);
+ return URL;
+}
+
+static void resetWebViewToConsistentStateBeforeTesting()
+{
+ WebView *webView = [mainFrame webView];
+ [(EditingDelegate *)[webView editingDelegate] setAcceptsEditing:YES];
+ [webView makeTextStandardSize:nil];
+ [webView setTabKeyCyclesThroughElements: YES];
+ [webView setPolicyDelegate:nil];
+ [webView _setDashboardBehavior:WebDashboardBehaviorUseBackwardCompatibilityMode to:NO];
+
+ WebPreferences *preferences = [webView preferences];
+ [preferences setPrivateBrowsingEnabled:NO];
+ [preferences setAuthorAndUserStylesEnabled:YES];
+ [preferences setJavaScriptCanOpenWindowsAutomatically:YES];
+
+ if (persistentUserStyleSheetLocation) {
+ [preferences setUserStyleSheetLocation:[NSURL URLWithString:(NSString *)(persistentUserStyleSheetLocation.get())]];
+ [preferences setUserStyleSheetEnabled:YES];
+ } else
+ [preferences setUserStyleSheetEnabled:NO];
+
+ [WebView _setUsesTestModeFocusRingColor:YES];
+}
+
+static void runTest(const char *pathOrURL)
+{
+ CFStringRef pathOrURLString = CFStringCreateWithCString(NULL, pathOrURL, kCFStringEncodingUTF8);
+ if (!pathOrURLString) {
+ fprintf(stderr, "Failed to parse filename as UTF-8: %s\n", pathOrURL);
+ return;
+ }
+
+ CFURLRef URL = createCFURLFromPathOrURL(pathOrURLString);
+ if (!URL) {
+ CFRelease(pathOrURLString);
+ fprintf(stderr, "Can't turn %s into a CFURL\n", pathOrURL);
+ return;
+ }
+
+ resetWebViewToConsistentStateBeforeTesting();
+
+ layoutTestController = new LayoutTestController(testRepaintDefault, repaintSweepHorizontallyDefault);
+ topLoadingFrame = nil;
+ done = NO;
+
+ if (disallowedURLs)
+ CFSetRemoveAllValues(disallowedURLs);
+ if (shouldLogFrameLoadDelegates(pathOrURL))
+ layoutTestController->setDumpFrameLoadCallbacks(true);
+
+ if ([WebHistory optionalSharedHistory])
+ [WebHistory setOptionalSharedHistory:nil];
+ lastMousePosition = NSZeroPoint;
+ lastClickPosition = NSZeroPoint;
+
+ if (currentTest != nil)
+ CFRelease(currentTest);
+ currentTest = (NSString *)pathOrURLString;
+ [prevTestBFItem release];
+ prevTestBFItem = [[[[mainFrame webView] backForwardList] currentItem] retain];
+
+ WorkQueue::shared()->clear();
+ WorkQueue::shared()->setFrozen(false);
+
+ BOOL _shouldIgnoreWebCoreNodeLeaks = shouldIgnoreWebCoreNodeLeaks(CFURLGetString(URL));
+ if (_shouldIgnoreWebCoreNodeLeaks)
+ [WebCoreStatistics startIgnoringWebCoreNodeLeaks];
+
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ [mainFrame loadRequest:[NSURLRequest requestWithURL:(NSURL *)URL]];
+ CFRelease(URL);
+ [pool release];
+ while (!done) {
+ pool = [[NSAutoreleasePool alloc] init];
+ [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]];
+ [pool release];
+ }
+ pool = [[NSAutoreleasePool alloc] init];
+ [EventSendingController clearSavedEvents];
+ [[mainFrame webView] setSelectedDOMRange:nil affinity:NSSelectionAffinityDownstream];
+
+ WorkQueue::shared()->clear();
+
+ if (layoutTestController->closeRemainingWindowsWhenComplete()) {
+ NSArray* array = [DumpRenderTreeWindow openWindows];
+
+ unsigned count = [array count];
+ for (unsigned i = 0; i < count; i++) {
+ NSWindow *window = [array objectAtIndex:i];
+
+ // Don't try to close the main window
+ if (window == [[mainFrame webView] window])
+ continue;
+
+ WebView *webView = [[[window contentView] subviews] objectAtIndex:0];
+
+ [webView close];
+ [window close];
+ }
+ }
+
+ [mainFrame loadHTMLString:@"<html></html>" baseURL:[NSURL URLWithString:@"about:blank"]];
+ [mainFrame stopLoading];
+
+ [pool release];
+
+ // We should only have our main window left open when we're done
+ ASSERT(CFArrayGetCount(openWindowsRef) == 1);
+ ASSERT(CFArrayGetValueAtIndex(openWindowsRef, 0) == [[mainFrame webView] window]);
+
+ delete layoutTestController;
+ layoutTestController = 0;
+
+ if (_shouldIgnoreWebCoreNodeLeaks)
+ [WebCoreStatistics stopIgnoringWebCoreNodeLeaks];
+}
+
+void displayWebView()
+{
+ NSView *webView = [mainFrame webView];
+ [webView display];
+ [webView lockFocus];
+ [[[NSColor blackColor] colorWithAlphaComponent:0.66] set];
+ NSRectFillUsingOperation([webView frame], NSCompositeSourceOver);
+ [webView unlockFocus];
+}
+
+@implementation DumpRenderTreeEvent
+
++ (NSPoint)mouseLocation
+{
+ return [[[mainFrame webView] window] convertBaseToScreen:lastMousePosition];
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/DumpRenderTreeDraggingInfo.h b/WebKitTools/DumpRenderTree/mac/DumpRenderTreeDraggingInfo.h
new file mode 100644
index 0000000..249809c
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/DumpRenderTreeDraggingInfo.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2005, 2006 Apple Computer, 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 <Cocoa/Cocoa.h>
+
+@interface DumpRenderTreeDraggingInfo : NSObject <NSDraggingInfo> {
+@private
+ NSSize offset;
+ NSImage *draggedImage;
+ NSPasteboard *draggingPasteboard;
+ id draggingSource;
+}
+
+- (id)initWithImage:(NSImage *)image offset:(NSSize)offset pasteboard:(NSPasteboard *)pasteboard source:(id)source;
+
+- (NSWindow *)draggingDestinationWindow;
+- (NSDragOperation)draggingSourceOperationMask;
+- (NSPoint)draggingLocation;
+- (NSPoint)draggedImageLocation;
+- (NSImage *)draggedImage;
+- (NSPasteboard *)draggingPasteboard;
+- (id)draggingSource;
+- (int)draggingSequenceNumber;
+
+- (void)slideDraggedImageTo:(NSPoint)screenPoint;
+- (NSArray *)namesOfPromisedFilesDroppedAtDestination:(NSURL *)dropDestination;
+@end
+
diff --git a/WebKitTools/DumpRenderTree/mac/DumpRenderTreeDraggingInfo.mm b/WebKitTools/DumpRenderTree/mac/DumpRenderTreeDraggingInfo.mm
new file mode 100644
index 0000000..41aa639
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/DumpRenderTreeDraggingInfo.mm
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2005, 2006 Apple Computer, 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 "DumpRenderTreeDraggingInfo.h"
+
+#import "DumpRenderTree.h"
+#import "EventSendingController.h"
+#import <WebKit/WebKit.h>
+
+@implementation DumpRenderTreeDraggingInfo
+
+- (id)initWithImage:(NSImage *)anImage offset:(NSSize)o pasteboard:(NSPasteboard *)pboard source:(id)source
+{
+ draggedImage = [anImage retain];
+ draggingPasteboard = [pboard retain];
+ draggingSource = [source retain];
+ offset = o;
+
+ return [super init];
+}
+
+- (void)dealloc
+{
+ [draggedImage release];
+ [draggingPasteboard release];
+ [draggingSource release];
+ [super dealloc];
+}
+
+- (NSWindow *)draggingDestinationWindow
+{
+ return [[mainFrame webView] window];
+}
+
+- (NSDragOperation)draggingSourceOperationMask
+{
+ return [draggingSource draggingSourceOperationMaskForLocal:YES];
+}
+
+- (NSPoint)draggingLocation
+{
+ return lastMousePosition;
+}
+
+- (NSPoint)draggedImageLocation
+{
+ return NSMakePoint(lastMousePosition.x + offset.width, lastMousePosition.y + offset.height);
+}
+
+- (NSImage *)draggedImage
+{
+ return draggedImage;
+}
+
+- (NSPasteboard *)draggingPasteboard
+{
+ return draggingPasteboard;
+}
+
+- (id)draggingSource
+{
+ return draggingSource;
+}
+
+- (int)draggingSequenceNumber
+{
+ NSLog(@"DumpRenderTree doesn't support draggingSequenceNumber");
+ return 0;
+}
+
+- (void)slideDraggedImageTo:(NSPoint)screenPoint
+{
+ NSLog(@"DumpRenderTree doesn't support slideDraggedImageTo:");
+}
+
+- (NSArray *)namesOfPromisedFilesDroppedAtDestination:(NSURL *)dropDestination
+{
+ NSLog(@"DumpRenderTree doesn't support namesOfPromisedFilesDroppedAtDestination:");
+ return nil;
+}
+
+@end
+
diff --git a/WebKitTools/DumpRenderTree/mac/DumpRenderTreeMac.h b/WebKitTools/DumpRenderTree/mac/DumpRenderTreeMac.h
new file mode 100644
index 0000000..c4c7573
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/DumpRenderTreeMac.h
@@ -0,0 +1,57 @@
+/*
+ * 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 DumpRenderTreeMac_h
+#define DumpRenderTreeMac_h
+
+// FIXME: we should add a config.h file for DumpRenderTree.
+#define WTF_PLATFORM_CF 1
+
+@class DumpRenderTreeDraggingInfo;
+@class NavigationController;
+@class PolicyDelegate;
+@class WebFrame;
+@class WebView;
+
+typedef const struct __CFString* CFStringRef;
+
+extern CFMutableArrayRef openWindowsRef;
+extern CFMutableSetRef disallowedURLs;
+extern WebFrame* mainFrame;
+extern WebFrame* topLoadingFrame;
+extern DumpRenderTreeDraggingInfo *draggingInfo;
+extern NavigationController* navigationController;
+extern PolicyDelegate* policyDelegate;
+
+extern const unsigned maxViewHeight;
+extern const unsigned maxViewWidth;
+
+WebView* createWebViewAndOffscreenWindow();
+void setPersistentUserStyleSheetLocation(CFStringRef);
+
+#endif // DumpRenderTreeMac_h
diff --git a/WebKitTools/DumpRenderTree/mac/DumpRenderTreePasteboard.h b/WebKitTools/DumpRenderTree/mac/DumpRenderTreePasteboard.h
new file mode 100644
index 0000000..6a01a42
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/DumpRenderTreePasteboard.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2005, 2006, 2007 Apple, Inc. All rights reserved.
+ * (C) 2007 Graham Dennis (graham.dennis@gmail.com)
+ * (C) 2007 Eric Seidel <eric@webkit.org>
+ *
+ * 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 <AppKit/AppKit.h>
+
+@interface DumpRenderTreePasteboard : NSPasteboard
+- (int)declareType:(NSString *)type owner:(id)newOwner;
++ (void)releaseLocalPasteboards;
+@end
+
diff --git a/WebKitTools/DumpRenderTree/mac/DumpRenderTreePasteboard.m b/WebKitTools/DumpRenderTree/mac/DumpRenderTreePasteboard.m
new file mode 100644
index 0000000..b5a9b7a
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/DumpRenderTreePasteboard.m
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2005, 2006, 2007 Apple, Inc. All rights reserved.
+ * (C) 2007 Graham Dennis (graham.dennis@gmail.com)
+ * (C) 2007 Eric Seidel <eric@webkit.org>
+ *
+ * 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 "DumpRenderTreePasteboard.h"
+
+@interface LocalPasteboard : NSPasteboard
+{
+ NSMutableArray *typesArray;
+ NSMutableSet *typesSet;
+ NSMutableDictionary *dataByType;
+ int changeCount;
+}
+@end
+
+static NSMutableDictionary *localPasteboards;
+
+@implementation DumpRenderTreePasteboard
+
+// Return a local pasteboard so we don't disturb the real pasteboards when running tests.
++ (NSPasteboard *)_pasteboardWithName:(NSString *)name
+{
+ static int number = 0;
+ if (!name)
+ name = [NSString stringWithFormat:@"LocalPasteboard%d", ++number];
+ if (!localPasteboards)
+ localPasteboards = [[NSMutableDictionary alloc] init];
+ LocalPasteboard *pasteboard = [localPasteboards objectForKey:name];
+ if (pasteboard)
+ return pasteboard;
+ pasteboard = [[LocalPasteboard alloc] init];
+ [localPasteboards setObject:pasteboard forKey:name];
+ [pasteboard release];
+ return pasteboard;
+}
+
++ (void)releaseLocalPasteboards
+{
+ [localPasteboards release];
+ localPasteboards = nil;
+}
+
+// Convenience method for JS so that it doesn't have to try and create a NSArray on the objc side instead
+// of the usual WebScriptObject that is passed around
+- (int)declareType:(NSString *)type owner:(id)newOwner
+{
+ return [self declareTypes:[NSArray arrayWithObject:type] owner:newOwner];
+}
+
+@end
+
+@implementation LocalPasteboard
+
++ (id)alloc
+{
+ return NSAllocateObject(self, 0, 0);
+}
+
+- (id)init
+{
+ typesArray = [[NSMutableArray alloc] init];
+ typesSet = [[NSMutableSet alloc] init];
+ dataByType = [[NSMutableDictionary alloc] init];
+ return self;
+}
+
+- (void)dealloc
+{
+ [typesArray release];
+ [typesSet release];
+ [dataByType release];
+ [super dealloc];
+}
+
+- (NSString *)name
+{
+ return nil;
+}
+
+- (void)releaseGlobally
+{
+}
+
+- (int)declareTypes:(NSArray *)newTypes owner:(id)newOwner
+{
+ [typesArray removeAllObjects];
+ [typesSet removeAllObjects];
+ [dataByType removeAllObjects];
+ return [self addTypes:newTypes owner:newOwner];
+}
+
+- (int)addTypes:(NSArray *)newTypes owner:(id)newOwner
+{
+ unsigned count = [newTypes count];
+ unsigned i;
+ for (i = 0; i < count; ++i) {
+ NSString *type = [newTypes objectAtIndex:i];
+ NSString *setType = [typesSet member:type];
+ if (!setType) {
+ setType = [type copy];
+ [typesArray addObject:setType];
+ [typesSet addObject:setType];
+ [setType release];
+ }
+ if (newOwner && [newOwner respondsToSelector:@selector(pasteboard:provideDataForType:)])
+ [newOwner pasteboard:self provideDataForType:setType];
+ }
+ return ++changeCount;
+}
+
+- (int)changeCount
+{
+ return changeCount;
+}
+
+- (NSArray *)types
+{
+ return typesArray;
+}
+
+- (NSString *)availableTypeFromArray:(NSArray *)types
+{
+ unsigned count = [types count];
+ unsigned i;
+ for (i = 0; i < count; ++i) {
+ NSString *type = [types objectAtIndex:i];
+ NSString *setType = [typesSet member:type];
+ if (setType)
+ return setType;
+ }
+ return nil;
+}
+
+- (BOOL)setData:(NSData *)data forType:(NSString *)dataType
+{
+ if (data == nil)
+ data = [NSData data];
+ if (![typesSet containsObject:dataType])
+ return NO;
+ [dataByType setObject:data forKey:dataType];
+ ++changeCount;
+ return YES;
+}
+
+- (NSData *)dataForType:(NSString *)dataType
+{
+ return [dataByType objectForKey:dataType];
+}
+
+- (BOOL)setPropertyList:(id)propertyList forType:(NSString *)dataType;
+{
+ CFDataRef data = NULL;
+ if (propertyList)
+ data = CFPropertyListCreateXMLData(NULL, propertyList);
+ BOOL result = [self setData:(NSData *)data forType:dataType];
+ if (data)
+ CFRelease(data);
+ return result;
+}
+
+- (BOOL)setString:(NSString *)string forType:(NSString *)dataType
+{
+ CFDataRef data = NULL;
+ if (string) {
+ if ([string length] == 0)
+ data = CFDataCreate(NULL, NULL, 0);
+ else
+ data = CFStringCreateExternalRepresentation(NULL, (CFStringRef)string, kCFStringEncodingUTF8, 0);
+ }
+ BOOL result = [self setData:(NSData *)data forType:dataType];
+ if (data)
+ CFRelease(data);
+ return result;
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/DumpRenderTreeWindow.h b/WebKitTools/DumpRenderTree/mac/DumpRenderTreeWindow.h
new file mode 100644
index 0000000..3ac3223
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/DumpRenderTreeWindow.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2005, 2006, 2007 Apple, Inc. All rights reserved.
+ * (C) 2007 Graham Dennis (graham.dennis@gmail.com)
+ * (C) 2007 Eric Seidel <eric@webkit.org>
+ *
+ * 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 <AppKit/AppKit.h>
+
+@interface DumpRenderTreeWindow : NSWindow
+// I'm not sure why we can't just use [NSApp windows]
++ (NSArray *)openWindows;
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/DumpRenderTreeWindow.mm b/WebKitTools/DumpRenderTree/mac/DumpRenderTreeWindow.mm
new file mode 100644
index 0000000..9e5e104
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/DumpRenderTreeWindow.mm
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2005, 2006, 2007 Apple, Inc. All rights reserved.
+ * (C) 2007 Graham Dennis (graham.dennis@gmail.com)
+ * (C) 2007 Eric Seidel <eric@webkit.org>
+ *
+ * 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 "DumpRenderTreeWindow.h"
+
+#import "DumpRenderTree.h"
+
+// FIXME: This file is ObjC++ only because of this include. :(
+#import "LayoutTestController.h"
+
+CFMutableArrayRef openWindowsRef = 0;
+
+static CFArrayCallBacks NonRetainingArrayCallbacks = {
+ 0,
+ NULL,
+ NULL,
+ CFCopyDescription,
+ CFEqual
+};
+
+@implementation DumpRenderTreeWindow
+
++ (NSArray *)openWindows
+{
+ return [[(NSArray *)openWindowsRef copy] autorelease];
+}
+
+- (id)initWithContentRect:(NSRect)contentRect styleMask:(unsigned int)styleMask backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation
+{
+ if (!openWindowsRef)
+ openWindowsRef = CFArrayCreateMutable(NULL, 0, &NonRetainingArrayCallbacks);
+
+ CFArrayAppendValue(openWindowsRef, self);
+
+ return [super initWithContentRect:contentRect styleMask:styleMask backing:bufferingType defer:deferCreation];
+}
+
+- (void)close
+{
+ CFRange arrayRange = CFRangeMake(0, CFArrayGetCount(openWindowsRef));
+ CFIndex i = CFArrayGetFirstIndexOfValue(openWindowsRef, arrayRange, self);
+ assert(i != -1);
+ CFArrayRemoveValueAtIndex(openWindowsRef, i);
+ [super close];
+}
+
+- (BOOL)isKeyWindow
+{
+ return layoutTestController ? layoutTestController->windowIsKey() : YES;
+}
+
+- (void)keyDown:(id)sender
+{
+ // Do nothing, avoiding the beep we'd otherwise get from NSResponder,
+ // once we get to the end of the responder chain.
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/EditingDelegate.h b/WebKitTools/DumpRenderTree/mac/EditingDelegate.h
new file mode 100644
index 0000000..b5563c8
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/EditingDelegate.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2005, 2006 Apple Computer, 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 <Cocoa/Cocoa.h>
+
+@interface EditingDelegate : NSObject
+{
+ BOOL acceptsEditing;
+}
+
+- (void)setAcceptsEditing:(BOOL)newAcceptsEditing;
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/EditingDelegate.mm b/WebKitTools/DumpRenderTree/mac/EditingDelegate.mm
new file mode 100644
index 0000000..a8f0815
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/EditingDelegate.mm
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2005, 2006 Apple Computer, 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 "EditingDelegate.h"
+
+#import "DumpRenderTree.h"
+#import "LayoutTestController.h"
+#import <WebKit/WebKit.h>
+
+@interface DOMNode (dumpPath)
+- (NSString *)dumpPath;
+@end
+
+@implementation DOMNode (dumpPath)
+- (NSString *)dumpPath
+{
+ DOMNode *parent = [self parentNode];
+ NSString *str = [NSString stringWithFormat:@"%@", [self nodeName]];
+ if (parent != nil) {
+ str = [str stringByAppendingString:@" > "];
+ str = [str stringByAppendingString:[parent dumpPath]];
+ }
+ return str;
+}
+@end
+
+@interface DOMRange (dump)
+- (NSString *)dump;
+@end
+
+@implementation DOMRange (dump)
+- (NSString *)dump
+{
+ return [NSString stringWithFormat:@"range from %ld of %@ to %ld of %@", [self startOffset], [[self startContainer] dumpPath], [self endOffset], [[self endContainer] dumpPath]];
+}
+@end
+
+@implementation EditingDelegate
+
+- (id)init
+{
+ self = [super init];
+ if (!self)
+ return nil;
+ acceptsEditing = YES;
+ return self;
+}
+
+- (BOOL)webView:(WebView *)webView shouldBeginEditingInDOMRange:(DOMRange *)range
+{
+ if (!done && layoutTestController->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: shouldBeginEditingInDOMRange:%s\n", [[range dump] UTF8String]);
+ return acceptsEditing;
+}
+
+- (BOOL)webView:(WebView *)webView shouldEndEditingInDOMRange:(DOMRange *)range
+{
+ if (!done && layoutTestController->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: shouldEndEditingInDOMRange:%s\n", [[range dump] UTF8String]);
+ return acceptsEditing;
+}
+
+- (BOOL)webView:(WebView *)webView shouldInsertNode:(DOMNode *)node replacingDOMRange:(DOMRange *)range givenAction:(WebViewInsertAction)action
+{
+ static const char *insertactionstring[] = {
+ "WebViewInsertActionTyped",
+ "WebViewInsertActionPasted",
+ "WebViewInsertActionDropped",
+ };
+
+ if (!done && layoutTestController->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: shouldInsertNode:%s replacingDOMRange:%s givenAction:%s\n", [[node dumpPath] UTF8String], [[range dump] UTF8String], insertactionstring[action]);
+ return acceptsEditing;
+}
+
+- (BOOL)webView:(WebView *)webView shouldInsertText:(NSString *)text replacingDOMRange:(DOMRange *)range givenAction:(WebViewInsertAction)action
+{
+ static const char *insertactionstring[] = {
+ "WebViewInsertActionTyped",
+ "WebViewInsertActionPasted",
+ "WebViewInsertActionDropped",
+ };
+
+ if (!done && layoutTestController->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: shouldInsertText:%s replacingDOMRange:%s givenAction:%s\n", [[text description] UTF8String], [[range dump] UTF8String], insertactionstring[action]);
+ return acceptsEditing;
+}
+
+- (BOOL)webView:(WebView *)webView shouldDeleteDOMRange:(DOMRange *)range
+{
+ if (!done && layoutTestController->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: shouldDeleteDOMRange:%s\n", [[range dump] UTF8String]);
+ return acceptsEditing;
+}
+
+- (BOOL)webView:(WebView *)webView shouldShowDeleteInterfaceForElement:(DOMHTMLElement *)element
+{
+ return [[element className] isEqualToString:@"needsDeletionUI"];
+}
+
+- (BOOL)webView:(WebView *)webView shouldChangeSelectedDOMRange:(DOMRange *)currentRange toDOMRange:(DOMRange *)proposedRange affinity:(NSSelectionAffinity)selectionAffinity stillSelecting:(BOOL)flag
+{
+ static const char *affinitystring[] = {
+ "NSSelectionAffinityUpstream",
+ "NSSelectionAffinityDownstream"
+ };
+ static const char *boolstring[] = {
+ "FALSE",
+ "TRUE"
+ };
+
+ if (!done && layoutTestController->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: shouldChangeSelectedDOMRange:%s toDOMRange:%s affinity:%s stillSelecting:%s\n", [[currentRange dump] UTF8String], [[proposedRange dump] UTF8String], affinitystring[selectionAffinity], boolstring[flag]);
+ return acceptsEditing;
+}
+
+- (BOOL)webView:(WebView *)webView shouldApplyStyle:(DOMCSSStyleDeclaration *)style toElementsInDOMRange:(DOMRange *)range
+{
+ if (!done && layoutTestController->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: shouldApplyStyle:%s toElementsInDOMRange:%s\n", [[style description] UTF8String], [[range dump] UTF8String]);
+ return acceptsEditing;
+}
+
+- (BOOL)webView:(WebView *)webView shouldChangeTypingStyle:(DOMCSSStyleDeclaration *)currentStyle toStyle:(DOMCSSStyleDeclaration *)proposedStyle
+{
+ if (!done && layoutTestController->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: shouldChangeTypingStyle:%s toStyle:%s\n", [[currentStyle description] UTF8String], [[proposedStyle description] UTF8String]);
+ return acceptsEditing;
+}
+
+- (void)webViewDidBeginEditing:(NSNotification *)notification
+{
+ if (!done && layoutTestController->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: webViewDidBeginEditing:%s\n", [[notification name] UTF8String]);
+}
+
+- (void)webViewDidChange:(NSNotification *)notification
+{
+ if (!done && layoutTestController->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: webViewDidChange:%s\n", [[notification name] UTF8String]);
+}
+
+- (void)webViewDidEndEditing:(NSNotification *)notification
+{
+ if (!done && layoutTestController->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: webViewDidEndEditing:%s\n", [[notification name] UTF8String]);
+}
+
+- (void)webViewDidChangeTypingStyle:(NSNotification *)notification
+{
+ if (!done && layoutTestController->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: webViewDidChangeTypingStyle:%s\n", [[notification name] UTF8String]);
+}
+
+- (void)webViewDidChangeSelection:(NSNotification *)notification
+{
+ if (!done && layoutTestController->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: webViewDidChangeSelection:%s\n", [[notification name] UTF8String]);
+}
+
+- (void)setAcceptsEditing:(BOOL)newAcceptsEditing
+{
+ acceptsEditing = newAcceptsEditing;
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/EventSendingController.h b/WebKitTools/DumpRenderTree/mac/EventSendingController.h
new file mode 100644
index 0000000..28d0385
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/EventSendingController.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 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.
+ * 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 <Cocoa/Cocoa.h>
+#import <WebKit/WebKit.h>
+
+@interface EventSendingController : NSObject <DOMEventListener>
+{
+ BOOL down;
+ BOOL dragMode;
+ int clickCount;
+ NSTimeInterval lastClick;
+ int eventNumber;
+ double timeOffset;
+}
+
++ (void)saveEvent:(NSInvocation *)event;
++ (void)replaySavedEvents;
++ (void)clearSavedEvents;
+
+- (void)enableDOMUIEventLogging:(WebScriptObject *)node;
+
+- (void)handleEvent:(DOMEvent *)event;
+
+@end
+
+extern NSPoint lastMousePosition;
+extern NSPoint lastClickPosition; \ No newline at end of file
diff --git a/WebKitTools/DumpRenderTree/mac/EventSendingController.mm b/WebKitTools/DumpRenderTree/mac/EventSendingController.mm
new file mode 100644
index 0000000..8e9be38
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/EventSendingController.mm
@@ -0,0 +1,589 @@
+/*
+ * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Jonas Witt <jonas.witt@gmail.com>
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.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.
+ */
+
+#import "EventSendingController.h"
+
+#import "DumpRenderTree.h"
+#import "DumpRenderTreeDraggingInfo.h"
+
+#import <Carbon/Carbon.h> // for GetCurrentEventTime()
+#import <WebKit/WebKit.h>
+#import <WebKit/DOMPrivate.h>
+
+extern "C" void _NSNewKillRingSequence();
+
+NSPoint lastMousePosition;
+NSPoint lastClickPosition;
+NSArray *webkitDomEventNames;
+NSMutableArray *savedMouseEvents; // mouse events sent between mouseDown and mouseUp are stored here, and then executed at once.
+BOOL replayingSavedEvents;
+
+@implementation EventSendingController
+
++ (void)initialize
+{
+ webkitDomEventNames = [[NSArray alloc] initWithObjects:
+ @"abort",
+ @"beforecopy",
+ @"beforecut",
+ @"beforepaste",
+ @"blur",
+ @"change",
+ @"click",
+ @"contextmenu",
+ @"copy",
+ @"cut",
+ @"dblclick",
+ @"drag",
+ @"dragend",
+ @"dragenter",
+ @"dragleave",
+ @"dragover",
+ @"dragstart",
+ @"drop",
+ @"error",
+ @"focus",
+ @"input",
+ @"keydown",
+ @"keypress",
+ @"keyup",
+ @"load",
+ @"mousedown",
+ @"mousemove",
+ @"mouseout",
+ @"mouseover",
+ @"mouseup",
+ @"mousewheel",
+ @"beforeunload",
+ @"paste",
+ @"readystatechange",
+ @"reset",
+ @"resize",
+ @"scroll",
+ @"search",
+ @"select",
+ @"selectstart",
+ @"submit",
+ @"textInput",
+ @"textzoomin",
+ @"textzoomout",
+ @"unload",
+ @"zoom",
+ nil];
+}
+
++ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
+{
+ if (aSelector == @selector(mouseDown)
+ || aSelector == @selector(mouseUp)
+ || aSelector == @selector(contextClick)
+ || aSelector == @selector(mouseMoveToX:Y:)
+ || aSelector == @selector(leapForward:)
+ || aSelector == @selector(keyDown:withModifiers:)
+ || aSelector == @selector(enableDOMUIEventLogging:)
+ || aSelector == @selector(fireKeyboardEventsToElement:)
+ || aSelector == @selector(clearKillRing)
+ || aSelector == @selector(textZoomIn)
+ || aSelector == @selector(textZoomOut))
+ return NO;
+ return YES;
+}
+
++ (BOOL)isKeyExcludedFromWebScript:(const char*)name
+{
+ if (strcmp(name, "dragMode") == 0)
+ return NO;
+ return YES;
+}
+
++ (NSString *)webScriptNameForSelector:(SEL)aSelector
+{
+ if (aSelector == @selector(mouseMoveToX:Y:))
+ return @"mouseMoveTo";
+ if (aSelector == @selector(leapForward:))
+ return @"leapForward";
+ if (aSelector == @selector(keyDown:withModifiers:))
+ return @"keyDown";
+ if (aSelector == @selector(enableDOMUIEventLogging:))
+ return @"enableDOMUIEventLogging";
+ if (aSelector == @selector(fireKeyboardEventsToElement:))
+ return @"fireKeyboardEventsToElement";
+ if (aSelector == @selector(setDragMode:))
+ return @"setDragMode";
+ return nil;
+}
+
+- (id)init
+{
+ self = [super init];
+ if (self)
+ dragMode = YES;
+ return self;
+}
+
+- (void)dealloc
+{
+ [super dealloc];
+}
+
+- (double)currentEventTime
+{
+ return GetCurrentEventTime() + timeOffset;
+}
+
+- (void)leapForward:(int)milliseconds
+{
+ if (dragMode && down && !replayingSavedEvents) {
+ NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[EventSendingController instanceMethodSignatureForSelector:@selector(leapForward:)]];
+ [invocation setTarget:self];
+ [invocation setSelector:@selector(leapForward:)];
+ [invocation setArgument:&milliseconds atIndex:2];
+
+ [EventSendingController saveEvent:invocation];
+
+ return;
+ }
+
+ timeOffset += milliseconds / 1000.0;
+}
+
+- (void)clearKillRing
+{
+ _NSNewKillRingSequence();
+}
+
+- (void)mouseDown
+{
+ [[[mainFrame frameView] documentView] layout];
+ if (([self currentEventTime] - lastClick >= 1) ||
+ !NSEqualPoints(lastMousePosition, lastClickPosition))
+ clickCount = 1;
+ else
+ clickCount++;
+ NSEvent *event = [NSEvent mouseEventWithType:NSLeftMouseDown
+ location:lastMousePosition
+ modifierFlags:0
+ timestamp:[self currentEventTime]
+ windowNumber:[[[mainFrame webView] window] windowNumber]
+ context:[NSGraphicsContext currentContext]
+ eventNumber:++eventNumber
+ clickCount:clickCount
+ pressure:0.0];
+
+ NSView *subView = [[mainFrame webView] hitTest:[event locationInWindow]];
+ if (subView) {
+ [subView mouseDown:event];
+ down = YES;
+ }
+}
+
+- (void)textZoomIn
+{
+ [[mainFrame webView] makeTextLarger:self];
+}
+
+- (void)textZoomOut
+{
+ [[mainFrame webView] makeTextSmaller:self];
+}
+
+- (void)mouseUp
+{
+ if (dragMode && !replayingSavedEvents) {
+ NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[EventSendingController instanceMethodSignatureForSelector:@selector(mouseUp)]];
+ [invocation setTarget:self];
+ [invocation setSelector:@selector(mouseUp)];
+
+ [EventSendingController saveEvent:invocation];
+ [EventSendingController replaySavedEvents];
+
+ return;
+ }
+
+ [[[mainFrame frameView] documentView] layout];
+ NSEvent *event = [NSEvent mouseEventWithType:NSLeftMouseUp
+ location:lastMousePosition
+ modifierFlags:0
+ timestamp:[self currentEventTime]
+ windowNumber:[[[mainFrame webView] window] windowNumber]
+ context:[NSGraphicsContext currentContext]
+ eventNumber:++eventNumber
+ clickCount:clickCount
+ pressure:0.0];
+
+ NSView *targetView = [[mainFrame webView] hitTest:[event locationInWindow]];
+ // FIXME: Silly hack to teach DRT to respect capturing mouse events outside the WebView.
+ // The right solution is just to use NSApplication's built-in event sending methods,
+ // instead of rolling our own algorithm for selecting an event target.
+ targetView = targetView ? targetView : [[mainFrame frameView] documentView];
+ assert(targetView);
+ [targetView mouseUp:event];
+ down = NO;
+ lastClick = [event timestamp];
+ lastClickPosition = lastMousePosition;
+ if (draggingInfo) {
+ WebView *webView = [mainFrame webView];
+
+ NSDragOperation dragOperation = [webView draggingUpdated:draggingInfo];
+
+ if (dragOperation != NSDragOperationNone)
+ [webView performDragOperation:draggingInfo];
+ else
+ [webView draggingExited:draggingInfo];
+ [[draggingInfo draggingSource] draggedImage:[draggingInfo draggedImage] endedAt:lastMousePosition operation:dragOperation];
+ [draggingInfo release];
+ draggingInfo = nil;
+ }
+}
+
+- (void)mouseMoveToX:(int)x Y:(int)y
+{
+ if (dragMode && down && !replayingSavedEvents) {
+ NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[EventSendingController instanceMethodSignatureForSelector:@selector(mouseMoveToX:Y:)]];
+ [invocation setTarget:self];
+ [invocation setSelector:@selector(mouseMoveToX:Y:)];
+ [invocation setArgument:&x atIndex:2];
+ [invocation setArgument:&y atIndex:3];
+
+ [EventSendingController saveEvent:invocation];
+
+ return;
+ }
+
+ NSView *view = [mainFrame webView];
+ lastMousePosition = [view convertPoint:NSMakePoint(x, [view frame].size.height - y) toView:nil];
+ NSEvent *event = [NSEvent mouseEventWithType:(down ? NSLeftMouseDragged : NSMouseMoved)
+ location:lastMousePosition
+ modifierFlags:0
+ timestamp:[self currentEventTime]
+ windowNumber:[[view window] windowNumber]
+ context:[NSGraphicsContext currentContext]
+ eventNumber:++eventNumber
+ clickCount:(down ? clickCount : 0)
+ pressure:0.0];
+
+ NSView *subView = [[mainFrame webView] hitTest:[event locationInWindow]];
+ if (subView) {
+ if (down) {
+ [subView mouseDragged:event];
+ if (draggingInfo) {
+ [[draggingInfo draggingSource] draggedImage:[draggingInfo draggedImage] movedTo:lastMousePosition];
+ [[mainFrame webView] draggingUpdated:draggingInfo];
+ }
+ } else
+ [subView mouseMoved:event];
+ }
+}
+
+- (void)contextClick
+{
+ [[[mainFrame frameView] documentView] layout];
+ if ([self currentEventTime] - lastClick >= 1)
+ clickCount = 1;
+ else
+ clickCount++;
+ NSEvent *event = [NSEvent mouseEventWithType:NSRightMouseDown
+ location:lastMousePosition
+ modifierFlags:0
+ timestamp:[self currentEventTime]
+ windowNumber:[[[mainFrame webView] window] windowNumber]
+ context:[NSGraphicsContext currentContext]
+ eventNumber:++eventNumber
+ clickCount:clickCount
+ pressure:0.0];
+
+ NSView *subView = [[mainFrame webView] hitTest:[event locationInWindow]];
+ if (subView)
+ [subView menuForEvent:event];
+}
+
++ (void)saveEvent:(NSInvocation *)event
+{
+ if (!savedMouseEvents)
+ savedMouseEvents = [[NSMutableArray alloc] init];
+ [savedMouseEvents addObject:event];
+}
+
++ (void)replaySavedEvents
+{
+ replayingSavedEvents = YES;
+ while ([savedMouseEvents count]) {
+ // if a drag is initiated, the remaining saved events will be dispatched from our dragging delegate
+ NSInvocation *invocation = [[[savedMouseEvents objectAtIndex:0] retain] autorelease];
+ [savedMouseEvents removeObjectAtIndex:0];
+ [invocation invoke];
+ }
+ replayingSavedEvents = NO;
+}
+
++ (void)clearSavedEvents
+{
+ [savedMouseEvents release];
+ savedMouseEvents = nil;
+}
+
+- (void)keyDown:(NSString *)character withModifiers:(WebScriptObject *)modifiers
+{
+ NSString *eventCharacter = character;
+ if ([character isEqualToString:@"leftArrow"]) {
+ const unichar ch = NSLeftArrowFunctionKey;
+ eventCharacter = [NSString stringWithCharacters:&ch length:1];
+ } else if ([character isEqualToString:@"rightArrow"]) {
+ const unichar ch = NSRightArrowFunctionKey;
+ eventCharacter = [NSString stringWithCharacters:&ch length:1];
+ } else if ([character isEqualToString:@"upArrow"]) {
+ const unichar ch = NSUpArrowFunctionKey;
+ eventCharacter = [NSString stringWithCharacters:&ch length:1];
+ } else if ([character isEqualToString:@"downArrow"]) {
+ const unichar ch = NSDownArrowFunctionKey;
+ eventCharacter = [NSString stringWithCharacters:&ch length:1];
+ } else if ([character isEqualToString:@"pageUp"]) {
+ const unichar ch = NSPageUpFunctionKey;
+ eventCharacter = [NSString stringWithCharacters:&ch length:1];
+ } else if ([character isEqualToString:@"pageDown"]) {
+ const unichar ch = NSPageDownFunctionKey;
+ eventCharacter = [NSString stringWithCharacters:&ch length:1];
+ } else if ([character isEqualToString:@"home"]) {
+ const unichar ch = NSHomeFunctionKey;
+ eventCharacter = [NSString stringWithCharacters:&ch length:1];
+ } else if ([character isEqualToString:@"end"]) {
+ const unichar ch = NSEndFunctionKey;
+ eventCharacter = [NSString stringWithCharacters:&ch length:1];
+ } else if ([character isEqualToString:@"delete"]) {
+ const unichar ch = 0x7f;
+ eventCharacter = [NSString stringWithCharacters:&ch length:1];
+ }
+
+ NSString *charactersIgnoringModifiers = eventCharacter;
+
+ int modifierFlags = 0;
+
+ if ([character length] == 1 && [character characterAtIndex:0] >= 'A' && [character characterAtIndex:0] <= 'Z') {
+ modifierFlags |= NSShiftKeyMask;
+ charactersIgnoringModifiers = [character lowercaseString];
+ }
+
+ if ([modifiers isKindOfClass:[WebScriptObject class]])
+ for (unsigned i = 0; [[modifiers webScriptValueAtIndex:i] isKindOfClass:[NSString class]]; i++) {
+ NSString *modifier = (NSString *)[modifiers webScriptValueAtIndex:i];
+ if ([modifier isEqual:@"ctrlKey"])
+ modifierFlags |= NSControlKeyMask;
+ else if ([modifier isEqual:@"shiftKey"])
+ modifierFlags |= NSShiftKeyMask;
+ else if ([modifier isEqual:@"altKey"])
+ modifierFlags |= NSAlternateKeyMask;
+ else if ([modifier isEqual:@"metaKey"])
+ modifierFlags |= NSCommandKeyMask;
+ }
+
+ [[[mainFrame frameView] documentView] layout];
+
+ NSEvent *event = [NSEvent keyEventWithType:NSKeyDown
+ location:NSMakePoint(5, 5)
+ modifierFlags:modifierFlags
+ timestamp:[self currentEventTime]
+ windowNumber:[[[mainFrame webView] window] windowNumber]
+ context:[NSGraphicsContext currentContext]
+ characters:eventCharacter
+ charactersIgnoringModifiers:charactersIgnoringModifiers
+ isARepeat:NO
+ keyCode:0];
+
+ [[[[mainFrame webView] window] firstResponder] keyDown:event];
+
+ event = [NSEvent keyEventWithType:NSKeyUp
+ location:NSMakePoint(5, 5)
+ modifierFlags:modifierFlags
+ timestamp:[self currentEventTime]
+ windowNumber:[[[mainFrame webView] window] windowNumber]
+ context:[NSGraphicsContext currentContext]
+ characters:eventCharacter
+ charactersIgnoringModifiers:charactersIgnoringModifiers
+ isARepeat:NO
+ keyCode:0];
+
+ [[[[mainFrame webView] window] firstResponder] keyUp:event];
+}
+
+- (void)enableDOMUIEventLogging:(WebScriptObject *)node
+{
+ NSEnumerator *eventEnumerator = [webkitDomEventNames objectEnumerator];
+ id eventName;
+ while ((eventName = [eventEnumerator nextObject])) {
+ [(id<DOMEventTarget>)node addEventListener:eventName listener:self useCapture:NO];
+ }
+}
+
+- (void)handleEvent:(DOMEvent *)event
+{
+ DOMNode *target = [event target];
+
+ printf("event type: %s\n", [[event type] UTF8String]);
+ printf(" target: <%s>\n", [[[target nodeName] lowercaseString] UTF8String]);
+
+ if ([event isKindOfClass:[DOMEvent class]]) {
+ printf(" eventPhase: %d\n", [event eventPhase]);
+ printf(" bubbles: %d\n", [event bubbles] ? 1 : 0);
+ printf(" cancelable: %d\n", [event cancelable] ? 1 : 0);
+ }
+
+ if ([event isKindOfClass:[DOMUIEvent class]]) {
+ printf(" detail: %d\n", [(DOMUIEvent*)event detail]);
+
+ DOMAbstractView *view = [(DOMUIEvent*)event view];
+ if (view) {
+ printf(" view: OK");
+ if ([view document])
+ printf(" (document: OK)");
+ printf("\n");
+ }
+ }
+
+ if ([event isKindOfClass:[DOMKeyboardEvent class]]) {
+ printf(" keyIdentifier: %s\n", [[(DOMKeyboardEvent*)event keyIdentifier] UTF8String]);
+ printf(" keyLocation: %d\n", [(DOMKeyboardEvent*)event keyLocation]);
+ printf(" modifier keys: c:%d s:%d a:%d m:%d\n",
+ [(DOMKeyboardEvent*)event ctrlKey] ? 1 : 0,
+ [(DOMKeyboardEvent*)event shiftKey] ? 1 : 0,
+ [(DOMKeyboardEvent*)event altKey] ? 1 : 0,
+ [(DOMKeyboardEvent*)event metaKey] ? 1 : 0);
+ printf(" keyCode: %d\n", [(DOMKeyboardEvent*)event keyCode]);
+ printf(" charCode: %d\n", [(DOMKeyboardEvent*)event charCode]);
+ }
+
+ if ([event isKindOfClass:[DOMMouseEvent class]]) {
+ printf(" button: %d\n", [(DOMMouseEvent*)event button]);
+ printf(" clientX: %d\n", [(DOMMouseEvent*)event clientX]);
+ printf(" clientY: %d\n", [(DOMMouseEvent*)event clientY]);
+ printf(" screenX: %d\n", [(DOMMouseEvent*)event screenX]);
+ printf(" screenY: %d\n", [(DOMMouseEvent*)event screenY]);
+ printf(" modifier keys: c:%d s:%d a:%d m:%d\n",
+ [(DOMMouseEvent*)event ctrlKey] ? 1 : 0,
+ [(DOMMouseEvent*)event shiftKey] ? 1 : 0,
+ [(DOMMouseEvent*)event altKey] ? 1 : 0,
+ [(DOMMouseEvent*)event metaKey] ? 1 : 0);
+ id relatedTarget = [(DOMMouseEvent*)event relatedTarget];
+ if (relatedTarget) {
+ printf(" relatedTarget: %s", [[[relatedTarget class] description] UTF8String]);
+ if ([relatedTarget isKindOfClass:[DOMNode class]])
+ printf(" (nodeName: %s)", [[(DOMNode*)relatedTarget nodeName] UTF8String]);
+ printf("\n");
+ }
+ }
+
+ if ([event isKindOfClass:[DOMMutationEvent class]]) {
+ printf(" prevValue: %s\n", [[(DOMMutationEvent*)event prevValue] UTF8String]);
+ printf(" newValue: %s\n", [[(DOMMutationEvent*)event newValue] UTF8String]);
+ printf(" attrName: %s\n", [[(DOMMutationEvent*)event attrName] UTF8String]);
+ printf(" attrChange: %d\n", [(DOMMutationEvent*)event attrChange]);
+ DOMNode *relatedNode = [(DOMMutationEvent*)event relatedNode];
+ if (relatedNode) {
+ printf(" relatedNode: %s (nodeName: %s)\n",
+ [[[relatedNode class] description] UTF8String],
+ [[relatedNode nodeName] UTF8String]);
+ }
+ }
+
+ if ([event isKindOfClass:[DOMWheelEvent class]]) {
+ printf(" clientX: %d\n", [(DOMWheelEvent*)event clientX]);
+ printf(" clientY: %d\n", [(DOMWheelEvent*)event clientY]);
+ printf(" screenX: %d\n", [(DOMWheelEvent*)event screenX]);
+ printf(" screenY: %d\n", [(DOMWheelEvent*)event screenY]);
+ printf(" modifier keys: c:%d s:%d a:%d m:%d\n",
+ [(DOMWheelEvent*)event ctrlKey] ? 1 : 0,
+ [(DOMWheelEvent*)event shiftKey] ? 1 : 0,
+ [(DOMWheelEvent*)event altKey] ? 1 : 0,
+ [(DOMWheelEvent*)event metaKey] ? 1 : 0);
+ printf(" isHorizontal: %d\n", [(DOMWheelEvent*)event isHorizontal] ? 1 : 0);
+ printf(" wheelDelta: %d\n", [(DOMWheelEvent*)event wheelDelta]);
+ }
+}
+
+// FIXME: It's not good to have a test hard-wired into this controller like this.
+// Instead we need to get testing framework based on the Objective-C bindings
+// to work well enough that we can test that way instead.
+- (void)fireKeyboardEventsToElement:(WebScriptObject *)element {
+
+ if (![element isKindOfClass:[DOMHTMLElement class]]) {
+ return;
+ }
+
+ DOMHTMLElement *target = (DOMHTMLElement*)element;
+ DOMDocument *document = [target ownerDocument];
+
+ // Keyboard Event 1
+
+ DOMEvent *domEvent = [document createEvent:@"KeyboardEvent"];
+ [(DOMKeyboardEvent*)domEvent initKeyboardEvent:@"keydown"
+ canBubble:YES
+ cancelable:YES
+ view:[document defaultView]
+ keyIdentifier:@"U+000041"
+ keyLocation:0
+ ctrlKey:YES
+ altKey:NO
+ shiftKey:NO
+ metaKey:NO];
+ [target dispatchEvent:domEvent];
+
+ // Keyboard Event 2
+
+ domEvent = [document createEvent:@"KeyboardEvent"];
+ [(DOMKeyboardEvent*)domEvent initKeyboardEvent:@"keypress"
+ canBubble:YES
+ cancelable:YES
+ view:[document defaultView]
+ keyIdentifier:@"U+000045"
+ keyLocation:1
+ ctrlKey:NO
+ altKey:YES
+ shiftKey:NO
+ metaKey:NO];
+ [target dispatchEvent:domEvent];
+
+ // Keyboard Event 3
+
+ domEvent = [document createEvent:@"KeyboardEvent"];
+ [(DOMKeyboardEvent*)domEvent initKeyboardEvent:@"keyup"
+ canBubble:YES
+ cancelable:YES
+ view:[document defaultView]
+ keyIdentifier:@"U+000056"
+ keyLocation:0
+ ctrlKey:NO
+ altKey:NO
+ shiftKey:NO
+ metaKey:NO];
+ [target dispatchEvent:domEvent];
+
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.h b/WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.h
new file mode 100644
index 0000000..3b86fdf
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.h
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+#import <Foundation/Foundation.h>
+
+class GCController;
+
+@interface FrameLoadDelegate : NSObject
+{
+ GCController* gcController;
+}
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.mm b/WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.mm
new file mode 100644
index 0000000..98b6bac
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.mm
@@ -0,0 +1,333 @@
+/*
+ * 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.
+ */
+
+#import "DumpRenderTree.h"
+#import "FrameLoadDelegate.h"
+
+#import "AppleScriptController.h"
+#import "EventSendingController.h"
+#import "GCController.h"
+#import "LayoutTestController.h"
+#import "NavigationController.h"
+#import "ObjCController.h"
+#import "ObjCPlugin.h"
+#import "ObjCPluginFunction.h"
+#import "TextInputController.h"
+#import "WorkQueue.h"
+#import "WorkQueueItem.h"
+#import <JavaScriptCore/JavaScriptCore.h>
+#import <WebKit/WebFramePrivate.h>
+#import <WebKit/WebHTMLViewPrivate.h>
+#import <WebKit/WebKit.h>
+#import <WebKit/WebNSURLExtras.h>
+#import <wtf/Assertions.h>
+
+@interface NSURLRequest (PrivateThingsWeShouldntReallyUse)
++(void)setAllowsAnyHTTPSCertificate:(BOOL)allow forHost:(NSString *)host;
+@end
+
+@interface NSURL (DRTExtras)
+- (NSString *)_drt_descriptionSuitableForTestResult;
+@end
+
+@interface NSError (DRTExtras)
+- (NSString *)_drt_descriptionSuitableForTestResult;
+@end
+
+@interface NSURLResponse (DRTExtras)
+- (NSString *)_drt_descriptionSuitableForTestResult;
+@end
+
+@interface NSURLRequest (DRTExtras)
+- (NSString *)_drt_descriptionSuitableForTestResult;
+@end
+
+@interface WebFrame (DRTExtras)
+- (NSString *)_drt_descriptionSuitableForTestResult;
+@end
+
+@implementation WebFrame (DRTExtras)
+- (NSString *)_drt_descriptionSuitableForTestResult
+{
+ BOOL isMainFrame = (self == [[self webView] mainFrame]);
+ NSString *name = [self name];
+ if (isMainFrame) {
+ if ([name length])
+ return [NSString stringWithFormat:@"main frame \"%@\"", name];
+ else
+ return @"main frame";
+ } else {
+ if (name)
+ return [NSString stringWithFormat:@"frame \"%@\"", name];
+ else
+ return @"frame (anonymous)";
+ }
+}
+@end
+
+@implementation FrameLoadDelegate
+
+- (id)init
+{
+ if ((self = [super init]))
+ gcController = new GCController;
+ return self;
+}
+
+- (void)dealloc
+{
+ delete gcController;
+ [super dealloc];
+}
+
+// Exec messages in the work queue until they're all done, or one of them starts a new load
+- (void)processWork:(id)dummy
+{
+ // quit doing work once a load is in progress
+ while (WorkQueue::shared()->count() > 0 && !topLoadingFrame) {
+ WorkQueueItem* item = WorkQueue::shared()->dequeue();
+ ASSERT(item);
+ item->invoke();
+ delete item;
+ }
+
+ // if we didn't start a new load, then we finished all the commands, so we're ready to dump state
+ if (!topLoadingFrame && !layoutTestController->waitToDump())
+ dump();
+}
+
+- (void)webView:(WebView *)c locationChangeDone:(NSError *)error forDataSource:(WebDataSource *)dataSource
+{
+ if ([dataSource webFrame] == topLoadingFrame) {
+ topLoadingFrame = nil;
+ WorkQueue::shared()->setFrozen(true); // first complete load freezes the queue for the rest of this test
+ if (!layoutTestController->waitToDump()) {
+ if (WorkQueue::shared()->count())
+ [self performSelector:@selector(processWork:) withObject:nil afterDelay:0];
+ else
+ dump();
+ }
+ }
+}
+
+- (void)webView:(WebView *)sender didStartProvisionalLoadForFrame:(WebFrame *)frame
+{
+ if (!done && layoutTestController->dumpFrameLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - didStartProvisionalLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
+ printf ("%s\n", [string UTF8String]);
+ }
+
+ ASSERT([frame provisionalDataSource]);
+ // Make sure we only set this once per test. If it gets cleared, and then set again, we might
+ // end up doing two dumps for one test.
+ if (!topLoadingFrame && !done)
+ topLoadingFrame = frame;
+}
+
+- (void)webView:(WebView *)sender didCommitLoadForFrame:(WebFrame *)frame
+{
+ if (!done && layoutTestController->dumpFrameLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - didCommitLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
+ printf ("%s\n", [string UTF8String]);
+ }
+
+ ASSERT(![frame provisionalDataSource]);
+ ASSERT([frame dataSource]);
+
+ layoutTestController->setWindowIsKey(true);
+ NSView *documentView = [[mainFrame frameView] documentView];
+ [[[mainFrame webView] window] makeFirstResponder:documentView];
+ if ([documentView isKindOfClass:[WebHTMLView class]])
+ [(WebHTMLView *)documentView _updateFocusedAndActiveState];
+}
+
+- (void)webView:(WebView *)sender didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame
+{
+ if (!done && layoutTestController->dumpFrameLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - didFailProvisionalLoadWithError", [frame _drt_descriptionSuitableForTestResult]];
+ printf ("%s\n", [string UTF8String]);
+ }
+
+ if ([error domain] == NSURLErrorDomain && [error code] == NSURLErrorServerCertificateHasUnknownRoot) {
+ NSURL *failedURL = [[error userInfo] objectForKey:@"NSErrorFailingURLKey"];
+ [NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[failedURL _web_hostString]];
+ [frame loadRequest:[[[[frame provisionalDataSource] request] mutableCopy] autorelease]];
+ return;
+ }
+
+ ASSERT([frame provisionalDataSource]);
+ [self webView:sender locationChangeDone:error forDataSource:[frame provisionalDataSource]];
+}
+
+- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
+{
+ ASSERT([frame dataSource]);
+ ASSERT(frame == [[frame dataSource] webFrame]);
+
+ if (!done && layoutTestController->dumpFrameLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - didFinishLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
+ printf ("%s\n", [string UTF8String]);
+ }
+
+ // FIXME: This call to displayIfNeeded can be removed when <rdar://problem/5092361> is fixed.
+ // After that is fixed, we will reenable painting after WebCore is done loading the document,
+ // and this call will no longer be needed.
+ if ([[sender mainFrame] isEqual:frame])
+ [sender displayIfNeeded];
+ [self webView:sender locationChangeDone:nil forDataSource:[frame dataSource]];
+ [navigationController webView:sender didFinishLoadForFrame:frame];
+}
+
+- (void)webView:(WebView *)sender didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame;
+{
+ if (!done && layoutTestController->dumpFrameLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - didFailLoadWithError", [frame _drt_descriptionSuitableForTestResult]];
+ printf ("%s\n", [string UTF8String]);
+ }
+
+ ASSERT(![frame provisionalDataSource]);
+ ASSERT([frame dataSource]);
+
+ [self webView:sender locationChangeDone:error forDataSource:[frame dataSource]];
+}
+
+- (void)webView:(WebView *)webView windowScriptObjectAvailable:(WebScriptObject *)windowScriptObject;
+{
+ if (!done && layoutTestController->dumpFrameLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"?? - windowScriptObjectAvailable"];
+ printf ("%s\n", [string UTF8String]);
+ }
+
+ ASSERT_NOT_REACHED();
+}
+
+- (void)webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)obj forFrame:(WebFrame *)frame
+{
+ ASSERT(obj == [frame windowObject]);
+ ASSERT([obj JSObject] == JSContextGetGlobalObject([frame globalContext]));
+
+ // Make New-Style LayoutTestController
+ JSContextRef context = [frame globalContext];
+ JSObjectRef globalObject = JSContextGetGlobalObject(context);
+ JSValueRef exception = 0;
+
+ ASSERT(layoutTestController);
+ layoutTestController->makeWindowObject(context, globalObject, &exception);
+ ASSERT(!exception);
+
+ gcController->makeWindowObject(context, globalObject, &exception);
+ ASSERT(!exception);
+
+ // Make Old-Style controllers
+ EventSendingController *esc = [[EventSendingController alloc] init];
+ [obj setValue:esc forKey:@"eventSender"];
+ [esc release];
+
+ TextInputController *tic = [[TextInputController alloc] initWithWebView:sender];
+ [obj setValue:tic forKey:@"textInputController"];
+ [tic release];
+
+ AppleScriptController *asc = [[AppleScriptController alloc] initWithWebView:sender];
+ [obj setValue:asc forKey:@"appleScriptController"];
+ [asc release];
+
+ ObjCController *occ = [[ObjCController alloc] init];
+ [obj setValue:occ forKey:@"objCController"];
+ [occ release];
+
+ [obj setValue:navigationController forKey:@"navigationController"];
+
+ ObjCPlugin *plugin = [[ObjCPlugin alloc] init];
+ [obj setValue:plugin forKey:@"objCPlugin"];
+ [plugin release];
+
+ ObjCPluginFunction *pluginFunction = [[ObjCPluginFunction alloc] init];
+ [obj setValue:pluginFunction forKey:@"objCPluginFunction"];
+ [pluginFunction release];
+}
+
+- (void)webView:(WebView *)sender didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame
+{
+ if (!done && layoutTestController->dumpFrameLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - didReceiveTitle: %@", [frame _drt_descriptionSuitableForTestResult], title];
+ printf ("%s\n", [string UTF8String]);
+ }
+
+ if (layoutTestController->dumpTitleChanges())
+ printf("TITLE CHANGED: %s\n", [title UTF8String]);
+}
+
+- (void)webView:(WebView *)sender didReceiveServerRedirectForProvisionalLoadForFrame:(WebFrame *)frame
+{
+ if (!done && layoutTestController->dumpFrameLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - didReceiveServerRedirectForProvisionalLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
+ printf ("%s\n", [string UTF8String]);
+ }
+}
+
+- (void)webView:(WebView *)sender didChangeLocationWithinPageForFrame:(WebFrame *)frame
+{
+ if (!done && layoutTestController->dumpFrameLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - didChangeLocationWithinPageForFrame", [frame _drt_descriptionSuitableForTestResult]];
+ printf ("%s\n", [string UTF8String]);
+ }
+}
+
+- (void)webView:(WebView *)sender willPerformClientRedirectToURL:(NSURL *)URL delay:(NSTimeInterval)seconds fireDate:(NSDate *)date forFrame:(WebFrame *)frame
+{
+ if (!done && layoutTestController->dumpFrameLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - willPerformClientRedirectToURL: %@ ", [frame _drt_descriptionSuitableForTestResult], [URL _drt_descriptionSuitableForTestResult]];
+ printf ("%s\n", [string UTF8String]);
+ }
+}
+
+- (void)webView:(WebView *)sender didCancelClientRedirectForFrame:(WebFrame *)frame
+{
+ if (!done && layoutTestController->dumpFrameLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - didCancelClientRedirectForFrame", [frame _drt_descriptionSuitableForTestResult]];
+ printf ("%s\n", [string UTF8String]);
+ }
+}
+
+- (void)webView:(WebView *)sender didFinishDocumentLoadForFrame:(WebFrame *)frame;
+{
+ if (!done && layoutTestController->dumpFrameLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - didFinishDocumentLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
+ printf ("%s\n", [string UTF8String]);
+ }
+}
+
+- (void)webView:(WebView *)sender didHandleOnloadEventsForFrame:(WebFrame *)frame;
+{
+ if (!done && layoutTestController->dumpFrameLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - didHandleOnloadEventsForFrame", [frame _drt_descriptionSuitableForTestResult]];
+ printf ("%s\n", [string UTF8String]);
+ }
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/GCControllerMac.mm b/WebKitTools/DumpRenderTree/mac/GCControllerMac.mm
new file mode 100644
index 0000000..4b845ba
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/GCControllerMac.mm
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.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.
+ */
+
+#import "GCController.h"
+#import <WebKit/WebCoreStatistics.h>
+
+
+void GCController::collect() const
+{
+ [WebCoreStatistics garbageCollectJavaScriptObjects];
+}
+
+void GCController::collectOnAlternateThread(bool waitUntilDone) const
+{
+ [WebCoreStatistics garbageCollectJavaScriptObjectsOnAlternateThreadForDebugging:waitUntilDone];
+}
+
+size_t GCController::getJSObjectCount() const
+{
+ return [WebCoreStatistics javaScriptObjectsCount];
+}
diff --git a/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm b/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm
new file mode 100644
index 0000000..4774310
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm
@@ -0,0 +1,282 @@
+/*
+ * 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.
+ */
+
+#import "DumpRenderTree.h"
+#import "LayoutTestController.h"
+
+#import "EditingDelegate.h"
+#import "WorkQueue.h"
+#import "WorkQueueItem.h"
+#import <Foundation/Foundation.h>
+#import <JavaScriptCore/JSRetainPtr.h>
+#import <JavaScriptCore/JSStringRef.h>
+#import <JavaScriptCore/JSStringRefCF.h>
+#import <WebKit/WebBackForwardList.h>
+#import <WebKit/WebDatabaseManagerPrivate.h>
+#import <WebKit/WebFrame.h>
+#import <WebKit/WebHTMLViewPrivate.h>
+#import <WebKit/WebHistory.h>
+#import <WebKit/WebNSURLExtras.h>
+#import <WebKit/WebPreferences.h>
+#import <WebKit/WebPreferencesPrivate.h>
+#import <WebKit/WebSecurityOriginPrivate.h>
+#import <WebKit/WebView.h>
+#import <WebKit/WebViewPrivate.h>
+#import <wtf/RetainPtr.h>
+
+LayoutTestController::~LayoutTestController()
+{
+}
+
+void LayoutTestController::addDisallowedURL(JSStringRef url)
+{
+ RetainPtr<CFStringRef> urlCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, url));
+
+ if (!disallowedURLs)
+ disallowedURLs = CFSetCreateMutable(kCFAllocatorDefault, 0, NULL);
+
+ // Canonicalize the URL
+ NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:(NSString *)urlCF.get()]];
+ request = [NSURLProtocol canonicalRequestForRequest:request];
+
+ CFSetAddValue(disallowedURLs, [request URL]);
+}
+
+void LayoutTestController::clearAllDatabases()
+{
+ [[WebDatabaseManager sharedWebDatabaseManager] deleteAllDatabases];
+}
+
+void LayoutTestController::clearBackForwardList()
+{
+ WebBackForwardList *backForwardList = [[mainFrame webView] backForwardList];
+ WebHistoryItem *item = [[backForwardList currentItem] retain];
+
+ // We clear the history by setting the back/forward list's capacity to 0
+ // then restoring it back and adding back the current item.
+ int capacity = [backForwardList capacity];
+ [backForwardList setCapacity:0];
+ [backForwardList setCapacity:capacity];
+ [backForwardList addItem:item];
+ [backForwardList goToItem:item];
+ [item release];
+}
+
+JSStringRef LayoutTestController::copyDecodedHostName(JSStringRef name)
+{
+ RetainPtr<CFStringRef> nameCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, name));
+ NSString *nameNS = (NSString *)nameCF.get();
+ return JSStringCreateWithCFString((CFStringRef)[nameNS _web_decodeHostName]);
+}
+
+JSStringRef LayoutTestController::copyEncodedHostName(JSStringRef name)
+{
+ RetainPtr<CFStringRef> nameCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, name));
+ NSString *nameNS = (NSString *)nameCF.get();
+ return JSStringCreateWithCFString((CFStringRef)[nameNS _web_encodeHostName]);
+}
+
+void LayoutTestController::display()
+{
+ displayWebView();
+}
+
+void LayoutTestController::keepWebHistory()
+{
+ if (![WebHistory optionalSharedHistory]) {
+ WebHistory *history = [[WebHistory alloc] init];
+ [WebHistory setOptionalSharedHistory:history];
+ [history release];
+ }
+}
+
+void LayoutTestController::notifyDone()
+{
+ if (m_waitToDump && !topLoadingFrame && !WorkQueue::shared()->count())
+ dump();
+ m_waitToDump = false;
+}
+
+JSStringRef LayoutTestController::pathToLocalResource(JSContextRef context, JSStringRef url)
+{
+ return JSStringRetain(url); // Do nothing on mac.
+}
+
+void LayoutTestController::queueBackNavigation(int howFarBack)
+{
+ WorkQueue::shared()->queue(new BackItem(howFarBack));
+}
+
+void LayoutTestController::queueForwardNavigation(int howFarForward)
+{
+ WorkQueue::shared()->queue(new ForwardItem(howFarForward));
+}
+
+void LayoutTestController::queueLoad(JSStringRef url, JSStringRef target)
+{
+ RetainPtr<CFStringRef> urlCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, url));
+ NSString *urlNS = (NSString *)urlCF.get();
+
+ NSURL *nsurl = [NSURL URLWithString:urlNS relativeToURL:[[[mainFrame dataSource] response] URL]];
+ NSString* nsurlString = [nsurl absoluteString];
+
+ JSRetainPtr<JSStringRef> absoluteURL(Adopt, JSStringCreateWithUTF8CString([nsurlString UTF8String]));
+ WorkQueue::shared()->queue(new LoadItem(absoluteURL.get(), target));
+}
+
+void LayoutTestController::queueReload()
+{
+ WorkQueue::shared()->queue(new ReloadItem);
+}
+
+void LayoutTestController::queueScript(JSStringRef script)
+{
+ WorkQueue::shared()->queue(new ScriptItem(script));
+}
+
+void LayoutTestController::setAcceptsEditing(bool newAcceptsEditing)
+{
+ [(EditingDelegate *)[[mainFrame webView] editingDelegate] setAcceptsEditing:newAcceptsEditing];
+}
+
+void LayoutTestController::setAuthorAndUserStylesEnabled(bool flag)
+{
+ [[[mainFrame webView] preferences] setAuthorAndUserStylesEnabled:flag];
+}
+
+void LayoutTestController::setCustomPolicyDelegate(bool setDelegate)
+{
+ if (setDelegate)
+ [[mainFrame webView] setPolicyDelegate:policyDelegate];
+ else
+ [[mainFrame webView] setPolicyDelegate:nil];
+}
+
+void LayoutTestController::setDatabaseQuota(unsigned long long quota)
+{
+ WebSecurityOrigin *origin = [[WebSecurityOrigin alloc] initWithProtocol:@"file" domain:nil];
+ [origin setQuota:quota];
+ [origin release];
+}
+
+void LayoutTestController::setMainFrameIsFirstResponder(bool flag)
+{
+ NSView *documentView = [[mainFrame frameView] documentView];
+
+ NSResponder *firstResponder = flag ? documentView : nil;
+ [[[mainFrame webView] window] makeFirstResponder:firstResponder];
+
+ if ([documentView isKindOfClass:[WebHTMLView class]])
+ [(WebHTMLView *)documentView _updateFocusedAndActiveState];
+}
+
+void LayoutTestController::setPrivateBrowsingEnabled(bool privateBrowsingEnabled)
+{
+ [[[mainFrame webView] preferences] setPrivateBrowsingEnabled:privateBrowsingEnabled];
+}
+
+void LayoutTestController::setPopupBlockingEnabled(bool popupBlockingEnabled)
+{
+ [[[mainFrame webView] preferences] setJavaScriptCanOpenWindowsAutomatically:!popupBlockingEnabled];
+}
+
+void LayoutTestController::setTabKeyCyclesThroughElements(bool cycles)
+{
+ [[mainFrame webView] setTabKeyCyclesThroughElements:cycles];
+}
+
+void LayoutTestController::setUseDashboardCompatibilityMode(bool flag)
+{
+ [[mainFrame webView] _setDashboardBehavior:WebDashboardBehaviorUseBackwardCompatibilityMode to:flag];
+}
+
+void LayoutTestController::setUserStyleSheetEnabled(bool flag)
+{
+ [[WebPreferences standardPreferences] setUserStyleSheetEnabled:flag];
+}
+
+void LayoutTestController::setUserStyleSheetLocation(JSStringRef path)
+{
+ RetainPtr<CFStringRef> pathCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, path));
+ NSURL *url = [NSURL URLWithString:(NSString *)pathCF.get()];
+ [[WebPreferences standardPreferences] setUserStyleSheetLocation:url];
+}
+
+void LayoutTestController::setPersistentUserStyleSheetLocation(JSStringRef jsURL)
+{
+ RetainPtr<CFStringRef> urlString(AdoptCF, JSStringCopyCFString(0, jsURL));
+ ::setPersistentUserStyleSheetLocation(urlString.get());
+}
+
+void LayoutTestController::clearPersistentUserStyleSheet()
+{
+ ::setPersistentUserStyleSheetLocation(0);
+}
+
+void LayoutTestController::setWindowIsKey(bool windowIsKey)
+{
+ m_windowIsKey = windowIsKey;
+ NSView *documentView = [[mainFrame frameView] documentView];
+ if ([documentView isKindOfClass:[WebHTMLView class]])
+ [(WebHTMLView *)documentView _updateFocusedAndActiveState];
+}
+
+static const CFTimeInterval waitToDumpWatchdogInterval = 10.0;
+
+static void waitUntilDoneWatchdogFired(CFRunLoopTimerRef timer, void* info)
+{
+ const char* message = "FAIL: Timed out waiting for notifyDone to be called\n";
+ fprintf(stderr, message);
+ fprintf(stdout, message);
+ dump();
+}
+
+void LayoutTestController::setWaitToDump(bool waitUntilDone)
+{
+ m_waitToDump = waitUntilDone;
+ if (m_waitToDump && !waitToDumpWatchdog) {
+ waitToDumpWatchdog = CFRunLoopTimerCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent() + waitToDumpWatchdogInterval, 0, 0, 0, waitUntilDoneWatchdogFired, NULL);
+ CFRunLoopAddTimer(CFRunLoopGetCurrent(), waitToDumpWatchdog, kCFRunLoopCommonModes);
+ }
+}
+
+int LayoutTestController::windowCount()
+{
+ return CFArrayGetCount(openWindowsRef);
+}
+
+void LayoutTestController::execCommand(JSStringRef name, JSStringRef value)
+{
+ RetainPtr<CFStringRef> nameCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, name));
+ NSString *nameNS = (NSString *)nameCF.get();
+
+ RetainPtr<CFStringRef> valueCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, value));
+ NSString *valueNS = (NSString *)valueCF.get();
+
+ [[mainFrame webView] _executeCoreCommandByName:nameNS value:valueNS];
+}
diff --git a/WebKitTools/DumpRenderTree/mac/NavigationController.h b/WebKitTools/DumpRenderTree/mac/NavigationController.h
new file mode 100644
index 0000000..8ee3432
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/NavigationController.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2006 Apple Computer, 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 <Cocoa/Cocoa.h>
+#import <WebKit/WebView.h>
+
+@interface NavigationController : NSObject
+{
+ enum { None, Load, GoBack, ExecuteScript } pendingAction;
+ NSString *pendingScript;
+ NSURLRequest *pendingRequest;
+}
+- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame;
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/NavigationController.m b/WebKitTools/DumpRenderTree/mac/NavigationController.m
new file mode 100644
index 0000000..44aed8a
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/NavigationController.m
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2006 Apple Computer, 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 <WebKit/WebFrame.h>
+#import <WebKit/WebScriptObject.h>
+#import "NavigationController.h"
+
+@implementation NavigationController
++ (BOOL)isSelectorExcludedFromWebScript:(SEL)selector
+{
+ if (selector == @selector(evaluateWebScript:afterBackForwardNavigation:))
+ return NO;
+ return YES;
+}
+
++ (NSString *)webScriptNameForSelector:(SEL)selector
+{
+ if (selector == @selector(evaluateWebScript:afterBackForwardNavigation:))
+ return @"evalAfterBackForwardNavigation";
+ return nil;
+}
+
+- (void)setPendingScript:(NSString *)script
+{
+ if (script != pendingScript) {
+ [pendingScript release];
+ pendingScript = [script copy];
+ }
+}
+
+- (void)setPendingRequest:(NSURLRequest *)request
+{
+ if (request != pendingRequest) {
+ [pendingRequest release];
+ pendingRequest = [request copy];
+ }
+}
+
+- (void)evaluateWebScript:(NSString *)script afterBackForwardNavigation:(NSString *)navigation
+{
+ // Allow both arguments to be optional
+ if (![script isKindOfClass:[NSString class]])
+ script = @"";
+ if (![navigation isKindOfClass:[NSString class]])
+ navigation = @"about:blank";
+
+ [self setPendingScript:script];
+ [self setPendingRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:navigation]]];
+ pendingAction = Load;
+}
+
+- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
+{
+ if (frame == [[frame webView] mainFrame]) {
+ switch (pendingAction) {
+ case Load:
+ pendingAction = GoBack;
+ [frame loadRequest:pendingRequest];
+ [self setPendingRequest:nil];
+ break;
+ case GoBack:
+ pendingAction = ExecuteScript;
+ [[frame webView] goBack];
+ break;
+ case ExecuteScript:
+ pendingAction = None;
+ [[[frame webView] windowScriptObject] evaluateWebScript:pendingScript];
+ [self setPendingScript:nil];
+ break;
+ case None:
+ default:
+ break;
+ }
+ }
+}
+
+- (void)dealloc
+{
+ [self setPendingScript:nil];
+ [self setPendingRequest:nil];
+ [super dealloc];
+}
+@end
+
diff --git a/WebKitTools/DumpRenderTree/mac/ObjCController.h b/WebKitTools/DumpRenderTree/mac/ObjCController.h
new file mode 100644
index 0000000..d1d001c
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/ObjCController.h
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+#import <Foundation/Foundation.h>
+
+@class WebScriptObject;
+
+// This controller should be used to test Objective-C language features and the WebScriptObject.
+@interface ObjCController : NSObject
+{
+ WebScriptObject *storedWebScriptObject;
+}
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/ObjCController.m b/WebKitTools/DumpRenderTree/mac/ObjCController.m
new file mode 100644
index 0000000..9ca9299
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/ObjCController.m
@@ -0,0 +1,231 @@
+/*
+ * 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.
+ */
+
+#import "ObjCController.h"
+
+#import <JavaScriptCore/JavaScriptCore.h>
+#import <WebKit/DOMAbstractView.h>
+#import <WebKit/WebScriptObject.h>
+#import <WebKit/WebView.h>
+#import <pthread.h>
+#import <wtf/Assertions.h>
+
+static void* runJavaScriptThread(void* arg)
+{
+ JSGlobalContextRef ctx = JSGlobalContextCreate(0);
+ JSStringRef scriptRef = JSStringCreateWithUTF8CString("'Hello World!'");
+
+ JSValueRef exception = 0;
+ JSEvaluateScript(ctx, scriptRef, 0, 0, 0, &exception);
+ ASSERT(!exception);
+
+ JSGlobalContextRelease(ctx);
+ JSStringRelease(scriptRef);
+
+ return 0;
+}
+
+@implementation ObjCController
+
++ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
+{
+ if (0
+ || aSelector == @selector(classNameOf:)
+ || aSelector == @selector(objectOfClass:)
+ || aSelector == @selector(identityIsEqual::)
+ || aSelector == @selector(longLongRoundTrip:)
+ || aSelector == @selector(unsignedLongLongRoundTrip:)
+ || aSelector == @selector(testWrapperRoundTripping:)
+ || aSelector == @selector(accessStoredWebScriptObject)
+ || aSelector == @selector(storeWebScriptObject:)
+ || aSelector == @selector(testValueForKey)
+ )
+ return NO;
+ return YES;
+}
+
++ (NSString *)webScriptNameForSelector:(SEL)aSelector
+{
+ if (aSelector == @selector(classNameOf:))
+ return @"className";
+ if (aSelector == @selector(objectOfClass:))
+ return @"objectOfClass";
+ if (aSelector == @selector(identityIsEqual::))
+ return @"identityIsEqual";
+ if (aSelector == @selector(longLongRoundTrip:))
+ return @"longLongRoundTrip";
+ if (aSelector == @selector(unsignedLongLongRoundTrip:))
+ return @"unsignedLongLongRoundTrip";
+ if (aSelector == @selector(testWrapperRoundTripping:))
+ return @"testWrapperRoundTripping";
+ if (aSelector == @selector(storeWebScriptObject:))
+ return @"storeWebScriptObject";
+ if (aSelector == @selector(testValueForKey))
+ return @"testValueForKey";
+
+ return nil;
+}
+
+- (NSString *)classNameOf:(id)object
+{
+ if (!object)
+ return @"nil";
+ return NSStringFromClass([object class]);
+}
+
+- (id)objectOfClass:(NSString *)aClass
+{
+ if ([aClass isEqualToString:@"NSNull"])
+ return [NSNull null];
+ if ([aClass isEqualToString:@"WebUndefined"])
+ return [WebUndefined undefined];
+ if ([aClass isEqualToString:@"NSCFBoolean"])
+ return [NSNumber numberWithBool:true];
+ if ([aClass isEqualToString:@"NSCFNumber"])
+ return [NSNumber numberWithInt:1];
+ if ([aClass isEqualToString:@"NSCFString"])
+ return @"";
+ if ([aClass isEqualToString:@"WebScriptObject"])
+ return self;
+ if ([aClass isEqualToString:@"NSArray"])
+ return [NSArray array];
+
+ return nil;
+}
+
+- (BOOL)identityIsEqual:(WebScriptObject *)a :(WebScriptObject *)b
+{
+ if ([a isKindOfClass:[NSString class]] && [b isKindOfClass:[NSString class]])
+ return [(NSString *)a isEqualToString:(NSString *)b];
+ return a == b;
+}
+
+- (long long)longLongRoundTrip:(long long)num
+{
+ return num;
+}
+
+- (unsigned long long)unsignedLongLongRoundTrip:(unsigned long long)num
+{
+ return num;
+}
+
+- (void)testValueForKey
+{
+ ASSERT(storedWebScriptObject);
+
+ @try {
+ [storedWebScriptObject valueForKey:@"ThisKeyDoesNotExist"];
+ } @catch (NSException *e) {
+ }
+
+ pthread_t pthread;
+ pthread_create(&pthread, 0, &runJavaScriptThread, 0);
+ pthread_join(pthread, 0);
+}
+
+- (BOOL)testWrapperRoundTripping:(WebScriptObject *)webScriptObject
+{
+ JSObjectRef jsObject = [webScriptObject JSObject];
+
+ if (!jsObject)
+ return false;
+
+ if (!webScriptObject)
+ return false;
+
+ if ([[webScriptObject evaluateWebScript:@"({ })"] class] != [webScriptObject class])
+ return false;
+
+ [webScriptObject setValue:[NSNumber numberWithInt:666] forKey:@"key"];
+ if (![[webScriptObject valueForKey:@"key"] isKindOfClass:[NSNumber class]] ||
+ ![[webScriptObject valueForKey:@"key"] isEqualToNumber:[NSNumber numberWithInt:666]])
+ return false;
+
+ [webScriptObject removeWebScriptKey:@"key"];
+ @try {
+ if ([webScriptObject valueForKey:@"key"])
+ return false;
+ } @catch(NSException *exception) {
+ // NSObject throws an exception if the key doesn't exist.
+ }
+
+ [webScriptObject setWebScriptValueAtIndex:0 value:webScriptObject];
+ if ([webScriptObject webScriptValueAtIndex:0] != webScriptObject)
+ return false;
+
+ if ([[webScriptObject stringRepresentation] isEqualToString:@"[Object object]"])
+ return false;
+
+ if ([webScriptObject callWebScriptMethod:@"returnThis" withArguments:nil] != webScriptObject)
+ return false;
+
+ return true;
+}
+
+- (void)accessStoredWebScriptObject
+{
+#if !ASSERT_DISABLED
+ BOOL isWindowObject = [storedWebScriptObject isKindOfClass:[DOMAbstractView class]];
+#endif
+ JSObjectRef jsObject = [storedWebScriptObject JSObject];
+ ASSERT((jsObject && isWindowObject) || (!jsObject && !isWindowObject));
+
+ [storedWebScriptObject callWebScriptMethod:@"" withArguments:nil];
+ [storedWebScriptObject evaluateWebScript:@""];
+ [storedWebScriptObject setValue:[WebUndefined undefined] forKey:@"key"];
+ [storedWebScriptObject valueForKey:@"key"];
+ [storedWebScriptObject removeWebScriptKey:@"key"];
+ [storedWebScriptObject stringRepresentation];
+ [storedWebScriptObject webScriptValueAtIndex:0];
+ [storedWebScriptObject setWebScriptValueAtIndex:0 value:[WebUndefined undefined]];
+ [storedWebScriptObject setException:@"exception"];
+}
+
+- (void)storeWebScriptObject:(WebScriptObject *)webScriptObject
+{
+ if (webScriptObject == storedWebScriptObject)
+ return;
+
+ [storedWebScriptObject release];
+ storedWebScriptObject = [webScriptObject retain];
+}
+
+- (void)dealloc
+{
+ [storedWebScriptObject release];
+ [super dealloc];
+}
+
+- (id)invokeUndefinedMethodFromWebScript:(NSString *)name withArguments:(NSArray *)args
+{
+ // FIXME: Perhaps we should log that this has been called.
+ return nil;
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/ObjCPlugin.h b/WebKitTools/DumpRenderTree/mac/ObjCPlugin.h
new file mode 100644
index 0000000..a6d3e50
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/ObjCPlugin.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2005 Apple Computer, 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 THE AUTHOR ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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>
+
+
+@interface ObjCPlugin : NSObject
+{
+ BOOL throwOnDealloc;
+}
+
+- (void)removeBridgeRestrictions:(id)container;
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/ObjCPlugin.m b/WebKitTools/DumpRenderTree/mac/ObjCPlugin.m
new file mode 100644
index 0000000..18b174c
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/ObjCPlugin.m
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 James G. Speth (speth@end.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 THE AUTHOR ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 "ObjCPlugin.h"
+#import <objc/objc-runtime.h>
+#import <WebKit/WebKit.h>
+
+
+// === NSObject category to expose almost everything to JavaScript ===
+
+// Warning: this class introduces huge security weaknesses, and should only be used
+// for testing inside of DumpRenderTree, and only with trusted code. By default, it has
+// the same restrictive behavior as the standard WebKit setup. However, scripts can use the
+// plugin's removeBridgeRestrictions: method to open up almost total access to the Cocoa
+// frameworks.
+
+static BOOL _allowsScriptsFullAccess = NO;
+
+@interface NSObject (ObjCScriptAccess)
+
++ (void)setAllowsScriptsFullAccess:(BOOL)value;
++ (BOOL)allowsScriptsFullAccess;
+
+@end
+
+@implementation NSObject (ObjCScriptAccess)
+
++ (void)setAllowsScriptsFullAccess:(BOOL)value
+{
+ _allowsScriptsFullAccess = value;
+}
+
++ (BOOL)allowsScriptsFullAccess
+{
+ return _allowsScriptsFullAccess;
+}
+
++ (BOOL)isSelectorExcludedFromWebScript:(SEL)selector
+{
+ return !_allowsScriptsFullAccess;
+}
+
++ (NSString *)webScriptNameForSelector:(SEL)selector
+{
+ return nil;
+}
+
+@end
+
+@interface JSObjC : NSObject {
+}
+
+// expose some useful objc functions to the scripting environment
+- (id)lookUpClass:(NSString *)name;
+- (void)log:(NSString *)message;
+- (id)retainObject:(id)obj;
+- (id)classOfObject:(id)obj;
+- (NSString *)classNameOfObject:(id)obj;
+
+@end
+
+@implementation JSObjC
+
++ (BOOL)isSelectorExcludedFromWebScript:(SEL)selector
+{
+ return NO;
+}
+
++ (NSString *)webScriptNameForSelector:(SEL)selector
+{
+ return nil;
+}
+
+- (id)invokeDefaultMethodWithArguments:(NSArray *)args
+{
+ // this is a useful shortcut for accessing objective-c classes from the scripting
+ // environment, e.g. 'var myObject = objc("NSObject").alloc().init();'
+ if ([args count] == 1)
+ return [self lookUpClass:[args objectAtIndex:0]];
+ return nil;
+}
+
+- (id)lookUpClass:(NSString *)name
+{
+ return NSClassFromString(name);
+}
+
+- (void)log:(NSString *)message
+{
+ NSLog(message);
+}
+
+- (id)retainObject:(id)obj
+{
+ return [obj retain];
+}
+
+- (id)classOfObject:(id)obj
+{
+ return (id)[obj class];
+}
+
+- (NSString *)classNameOfObject:(id)obj
+{
+ return [obj className];
+}
+
+@end
+
+@implementation ObjCPlugin
+
++ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
+{
+ if (aSelector == @selector(removeBridgeRestrictions:))
+ return NO;
+
+ if (aSelector == @selector(echo:))
+ return NO;
+
+ if (aSelector == @selector(throwIfArgumentIsNotHello:))
+ return NO;
+
+ return YES;
+}
+
++ (NSString *)webScriptNameForSelector:(SEL)aSelector
+{
+ if (aSelector == @selector(echo:))
+ return @"echo";
+
+ if (aSelector == @selector(throwIfArgumentIsNotHello:))
+ return @"throwIfArgumentIsNotHello";
+
+ return nil;
+}
+
++ (NSString *)webScriptNameForKey:(const char *)key
+{
+ if (strcmp(key, "throwOnDealloc") == 0)
+ return @"throwOnDealloc";
+
+ return nil;
+}
+
++ (BOOL)isKeyExcludedFromWebScript:(const char *)key
+{
+ if (strcmp(key, "throwOnDealloc") == 0)
+ return NO;
+
+ return YES;
+}
+
+- (void)removeBridgeRestrictions:(id)container
+{
+ // let scripts invoke any selector
+ [NSObject setAllowsScriptsFullAccess:YES];
+
+ // store a JSObjC instance into the provided container
+ JSObjC *objc = [[JSObjC alloc] init];
+ [container setValue:objc forKey:@"objc"];
+ [objc release];
+}
+
+- (id)echo:(id)obj
+{
+ return obj;
+}
+
+- (void)throwIfArgumentIsNotHello:(NSString *)str
+{
+ if (![str isEqualToString:@"Hello"])
+ [WebScriptObject throwException:[NSString stringWithFormat:@"%@ != Hello", str]];
+}
+
+- (void)dealloc
+{
+ if (throwOnDealloc)
+ [WebScriptObject throwException:@"Throwing exception on dealloc of ObjCPlugin"];
+
+ [super dealloc];
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/ObjCPluginFunction.h b/WebKitTools/DumpRenderTree/mac/ObjCPluginFunction.h
new file mode 100644
index 0000000..1e81b21
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/ObjCPluginFunction.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2006 Apple Computer, 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 THE AUTHOR ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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>
+
+
+@interface ObjCPluginFunction : NSObject
+{
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/ObjCPluginFunction.m b/WebKitTools/DumpRenderTree/mac/ObjCPluginFunction.m
new file mode 100644
index 0000000..5cd16f8
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/ObjCPluginFunction.m
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2006 Apple Computer, 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 THE AUTHOR ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 "ObjCPluginFunction.h"
+
+
+@implementation ObjCPluginFunction
+
+- (id)invokeDefaultMethodWithArguments:(NSArray *)args
+{
+ return @"test";
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/PixelDumpSupportMac.mm b/WebKitTools/DumpRenderTree/mac/PixelDumpSupportMac.mm
new file mode 100644
index 0000000..5a19164
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/PixelDumpSupportMac.mm
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
+ * (C) 2007 Graham Dennis (graham.dennis@gmail.com)
+ * (C) 2007 Eric Seidel <eric@webkit.org>
+ *
+ * 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 "DumpRenderTree.h"
+#include "PixelDumpSupport.h"
+#include "PixelDumpSupportCG.h"
+
+#include "LayoutTestController.h"
+#include <CoreGraphics/CGBitmapContext.h>
+#include <wtf/Assertions.h>
+#include <wtf/RetainPtr.h>
+
+#import <WebKit/WebDocumentPrivate.h>
+#import <WebKit/WebKit.h>
+
+static unsigned char* screenCaptureBuffer;
+
+static CMProfileRef currentColorProfile = 0;
+static CGColorSpaceRef sharedColorSpace;
+
+void restoreColorSpace(int ignored)
+{
+ // This is used as a signal handler, and thus the calls into ColorSync are unsafe
+ // But we might as well try to restore the user's color profile, we're going down anyway...
+ if (currentColorProfile) {
+ // This call is deprecated in Leopard, but there appears to be no replacement.
+ int error = CMSetDefaultProfileByUse(cmDisplayUse, currentColorProfile);
+ if (error)
+ fprintf(stderr, "Failed to retore previous color profile! You may need to open System Preferences : Displays : Color and manually restore your color settings. (Error: %i)", error);
+ currentColorProfile = 0;
+ }
+}
+
+static void setDefaultColorProfileToRGB()
+{
+ CMProfileRef genericProfile = (CMProfileRef)[[NSColorSpace genericRGBColorSpace] colorSyncProfile];
+ CMProfileRef previousProfile;
+ int error = CMGetDefaultProfileByUse(cmDisplayUse, &previousProfile);
+ if (error) {
+ fprintf(stderr, "Failed to get current color profile. I will not be able to restore your current profile, thus I'm not changing it. Many pixel tests may fail as a result. (Error: %i)\n", error);
+ return;
+ }
+ if (previousProfile == genericProfile)
+ return;
+ CFStringRef previousProfileName;
+ CFStringRef genericProfileName;
+ char previousProfileNameString[1024];
+ char genericProfileNameString[1024];
+ CMCopyProfileDescriptionString(previousProfile, &previousProfileName);
+ CMCopyProfileDescriptionString(genericProfile, &genericProfileName);
+ CFStringGetCString(previousProfileName, previousProfileNameString, sizeof(previousProfileNameString), kCFStringEncodingUTF8);
+ CFStringGetCString(genericProfileName, genericProfileNameString, sizeof(previousProfileNameString), kCFStringEncodingUTF8);
+ CFRelease(previousProfileName);
+ CFRelease(genericProfileName);
+
+ fprintf(stderr, "\n\nWARNING: Temporarily changing your system color profile from \"%s\" to \"%s\".\n", previousProfileNameString, genericProfileNameString);
+ fprintf(stderr, "This allows the WebKit pixel-based regression tests to have consistent color values across all machines.\n");
+ fprintf(stderr, "The colors on your screen will change for the duration of the testing.\n\n");
+
+ if ((error = CMSetDefaultProfileByUse(cmDisplayUse, genericProfile))) {
+ fprintf(stderr, "Failed to set color profile to \"%s\"! Many pixel tests will fail as a result. (Error: %i)",
+ genericProfileNameString, error);
+ } else {
+ currentColorProfile = previousProfile;
+ signal(SIGINT, restoreColorSpace);
+ signal(SIGHUP, restoreColorSpace);
+ signal(SIGTERM, restoreColorSpace);
+ }
+}
+
+void initializeColorSpaceAndScreeBufferForPixelTests()
+{
+ setDefaultColorProfileToRGB();
+ screenCaptureBuffer = (unsigned char *)malloc(maxViewHeight * maxViewWidth * 4);
+ sharedColorSpace = CGColorSpaceCreateDeviceRGB();
+}
+
+// Declared in PixelDumpSupportCG.h
+
+RetainPtr<CGContextRef> getBitmapContextFromWebView()
+{
+ NSSize webViewSize = [[mainFrame webView] frame].size;
+ return RetainPtr<CGContextRef>(AdoptCF, CGBitmapContextCreate(screenCaptureBuffer, static_cast<size_t>(webViewSize.width), static_cast<size_t>(webViewSize.height), 8, static_cast<size_t>(webViewSize.width) * 4, sharedColorSpace, kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedLast));
+}
+
+void paintWebView(CGContextRef context)
+{
+ RetainPtr<NSGraphicsContext> savedContext = [NSGraphicsContext currentContext];
+
+ NSGraphicsContext* nsContext = [NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:NO];
+ [NSGraphicsContext setCurrentContext:nsContext];
+
+ WebView* view = [mainFrame webView];
+ [view displayIfNeeded];
+ [view lockFocus];
+ NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:[view frame]];
+ [view unlockFocus];
+ [imageRep draw];
+ [imageRep release];
+
+ [NSGraphicsContext setCurrentContext:savedContext.get()];
+}
+
+void repaintWebView(CGContextRef context, bool horizontal)
+{
+ RetainPtr<NSGraphicsContext> savedContext = [NSGraphicsContext currentContext];
+
+ NSGraphicsContext* nsContext = [NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:NO];
+ [NSGraphicsContext setCurrentContext:nsContext];
+
+ WebView *view = [mainFrame webView];
+ NSSize webViewSize = [view frame].size;
+
+ if (horizontal) {
+ for (NSRect column = NSMakeRect(0, 0, 1, webViewSize.height); column.origin.x < webViewSize.width; column.origin.x++)
+ [view displayRectIgnoringOpacity:column inContext:nsContext];
+ } else {
+ for (NSRect line = NSMakeRect(0, 0, webViewSize.width, 1); line.origin.y < webViewSize.height; line.origin.y++)
+ [view displayRectIgnoringOpacity:line inContext:nsContext];
+ }
+
+ [NSGraphicsContext setCurrentContext:savedContext.get()];
+}
+
+CGRect getSelectionRect()
+{
+ NSView *documentView = [[mainFrame frameView] documentView];
+ if ([documentView conformsToProtocol:@protocol(WebDocumentSelection)]) {
+ NSRect rect = [documentView convertRect:[(id <WebDocumentSelection>)documentView selectionRect] fromView:nil];
+ return CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
+ }
+
+ ASSERT_NOT_REACHED();
+ return CGRectZero;
+}
diff --git a/WebKitTools/DumpRenderTree/mac/PolicyDelegate.h b/WebKitTools/DumpRenderTree/mac/PolicyDelegate.h
new file mode 100644
index 0000000..f8bce68
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/PolicyDelegate.h
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+
+@interface PolicyDelegate : NSObject {
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/PolicyDelegate.mm b/WebKitTools/DumpRenderTree/mac/PolicyDelegate.mm
new file mode 100644
index 0000000..fc4ac74
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/PolicyDelegate.mm
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+#import "PolicyDelegate.h"
+
+#import "DumpRenderTree.h"
+#import "DumpRenderTreeDraggingInfo.h"
+#import <WebKit/WebPolicyDelegate.h>
+
+@implementation PolicyDelegate
+- (void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary *)actionInformation
+ request:(NSURLRequest *)request
+ frame:(WebFrame *)frame
+ decisionListener:(id<WebPolicyDecisionListener>)listener
+{
+ printf("Policy delegate: attempt to load %s\n", [[[request URL] absoluteString] UTF8String]);
+ [listener ignore];
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/ResourceLoadDelegate.h b/WebKitTools/DumpRenderTree/mac/ResourceLoadDelegate.h
new file mode 100644
index 0000000..0c4618e
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/ResourceLoadDelegate.h
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+
+@interface ResourceLoadDelegate : NSObject {
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/ResourceLoadDelegate.mm b/WebKitTools/DumpRenderTree/mac/ResourceLoadDelegate.mm
new file mode 100644
index 0000000..cc0eb4a
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/ResourceLoadDelegate.mm
@@ -0,0 +1,179 @@
+/*
+ * 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.
+ */
+
+#import "ResourceLoadDelegate.h"
+
+#import "DumpRenderTree.h"
+#import "LayoutTestController.h"
+#import <WebKit/WebKit.h>
+#import <wtf/Assertions.h>
+
+@interface NSURL (DRTExtras)
+- (NSString *)_drt_descriptionSuitableForTestResult;
+@end
+
+@interface NSError (DRTExtras)
+- (NSString *)_drt_descriptionSuitableForTestResult;
+@end
+
+@interface NSURLResponse (DRTExtras)
+- (NSString *)_drt_descriptionSuitableForTestResult;
+@end
+
+@interface NSURLRequest (DRTExtras)
+- (NSString *)_drt_descriptionSuitableForTestResult;
+@end
+
+@implementation NSError (DRTExtras)
+- (NSString *)_drt_descriptionSuitableForTestResult
+{
+ NSString *str = [NSString stringWithFormat:@"<NSError domain %@, code %d", [self domain], [self code]];
+ NSURL *failingURL;
+
+ if ((failingURL = [[self userInfo] objectForKey:@"NSErrorFailingURLKey"]))
+ str = [str stringByAppendingFormat:@", failing URL \"%@\"", [failingURL _drt_descriptionSuitableForTestResult]];
+
+ str = [str stringByAppendingFormat:@">"];
+
+ return str;
+}
+
+@end
+
+@implementation NSURL (DRTExtras)
+
+- (NSString *)_drt_descriptionSuitableForTestResult
+{
+ if (![self isFileURL])
+ return [self absoluteString];
+
+ WebDataSource *dataSource = [mainFrame dataSource];
+ if (!dataSource)
+ dataSource = [mainFrame provisionalDataSource];
+
+ NSString *basePath = [[[[dataSource request] URL] path] stringByDeletingLastPathComponent];
+
+ return [[self path] substringFromIndex:[basePath length] + 1];
+}
+
+@end
+
+@implementation NSURLResponse (DRTExtras)
+
+- (NSString *)_drt_descriptionSuitableForTestResult
+{
+ return [NSString stringWithFormat:@"<NSURLResponse %@>", [[self URL] _drt_descriptionSuitableForTestResult]];
+}
+
+@end
+
+@implementation NSURLRequest (DRTExtras)
+
+- (NSString *)_drt_descriptionSuitableForTestResult
+{
+ return [NSString stringWithFormat:@"<NSURLRequest %@>", [[self URL] _drt_descriptionSuitableForTestResult]];
+}
+
+@end
+
+@implementation ResourceLoadDelegate
+
+- webView: (WebView *)wv identifierForInitialRequest: (NSURLRequest *)request fromDataSource: (WebDataSource *)dataSource
+{
+ ASSERT([[dataSource webFrame] dataSource] || [[dataSource webFrame] provisionalDataSource]);
+
+ if (!done && layoutTestController->dumpResourceLoadCallbacks())
+ return [[request URL] _drt_descriptionSuitableForTestResult];
+
+ return @"<unknown>";
+}
+
+-(NSURLRequest *)webView: (WebView *)wv resource:identifier willSendRequest: (NSURLRequest *)newRequest redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)dataSource
+{
+ if (!done && layoutTestController->dumpResourceLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - willSendRequest %@ redirectResponse %@", identifier, [newRequest _drt_descriptionSuitableForTestResult],
+ [redirectResponse _drt_descriptionSuitableForTestResult]];
+ printf ("%s\n", [string UTF8String]);
+ }
+
+ if (disallowedURLs && CFSetContainsValue(disallowedURLs, [newRequest URL]))
+ return nil;
+
+ return newRequest;
+}
+
+- (void)webView:(WebView *)wv resource:(id)identifier didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge fromDataSource:(WebDataSource *)dataSource
+{
+}
+
+- (void)webView:(WebView *)wv resource:(id)identifier didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge fromDataSource:(WebDataSource *)dataSource
+{
+}
+
+-(void)webView: (WebView *)wv resource:identifier didReceiveResponse: (NSURLResponse *)response fromDataSource:(WebDataSource *)dataSource
+{
+ if (!done && layoutTestController->dumpResourceLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - didReceiveResponse %@", identifier, [response _drt_descriptionSuitableForTestResult]];
+ printf ("%s\n", [string UTF8String]);
+ }
+}
+
+-(void)webView: (WebView *)wv resource:identifier didReceiveContentLength: (unsigned)length fromDataSource:(WebDataSource *)dataSource
+{
+}
+
+-(void)webView: (WebView *)wv resource:identifier didFinishLoadingFromDataSource:(WebDataSource *)dataSource
+{
+ if (!done && layoutTestController->dumpResourceLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - didFinishLoading", identifier];
+ printf ("%s\n", [string UTF8String]);
+ }
+}
+
+-(void)webView: (WebView *)wv resource:identifier didFailLoadingWithError:(NSError *)error fromDataSource:(WebDataSource *)dataSource
+{
+ if (!done && layoutTestController->dumpResourceLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - didFailLoadingWithError: %@", identifier, [error _drt_descriptionSuitableForTestResult]];
+ printf ("%s\n", [string UTF8String]);
+ }
+}
+
+- (void)webView: (WebView *)wv plugInFailedWithError:(NSError *)error dataSource:(WebDataSource *)dataSource
+{
+}
+
+-(NSCachedURLResponse *) webView: (WebView *)wv resource:(id)identifier willCacheResponse:(NSCachedURLResponse *)response fromDataSource:(WebDataSource *)dataSource
+{
+ if (!done && layoutTestController->dumpResourceLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - willCacheResponse: called", identifier];
+ printf ("%s\n", [string UTF8String]);
+ }
+ return response;
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/TextInputController.h b/WebKitTools/DumpRenderTree/mac/TextInputController.h
new file mode 100644
index 0000000..767e72f
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/TextInputController.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2005 Apple Computer, 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 <Foundation/Foundation.h>
+
+@class WebView;
+@class WebHTMLView;
+@class WebScriptObject;
+
+@interface TextInputController : NSObject
+{
+ WebView *webView;
+ WebHTMLView *inputMethodView;
+ WebScriptObject *inputMethodHandler;
+}
+- (id)initWithWebView:(WebView *)view;
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/TextInputController.m b/WebKitTools/DumpRenderTree/mac/TextInputController.m
new file mode 100644
index 0000000..88b480b
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/TextInputController.m
@@ -0,0 +1,423 @@
+/*
+ * Copyright (C) 2005, 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.
+ */
+
+#import "TextInputController.h"
+
+#import <AppKit/NSInputManager.h>
+#import <WebKit/WebDocument.h>
+#import <WebKit/WebFrame.h>
+#import <WebKit/WebFrameView.h>
+#import <WebKit/WebHTMLViewPrivate.h>
+#import <WebKit/WebScriptObject.h>
+#import <WebKit/WebView.h>
+
+@interface TextInputController (DumpRenderTreeInputMethodHandler)
+- (BOOL)interpretKeyEvents:(NSArray *)eventArray withSender:(WebHTMLView *)sender;
+@end
+
+@interface WebHTMLView (DumpRenderTreeInputMethodHandler)
+- (void)interpretKeyEvents:(NSArray *)eventArray;
+@end
+
+@interface WebHTMLView (WebKitSecretsTextInputControllerIsAwareOf)
+- (WebFrame *)_frame;
+@end
+
+@implementation WebHTMLView (DumpRenderTreeInputMethodHandler)
+- (void)interpretKeyEvents:(NSArray *)eventArray
+{
+ WebScriptObject *obj = [[self _frame] windowObject];
+ TextInputController *tic = [obj valueForKey:@"textInputController"];
+ if (![tic interpretKeyEvents:eventArray withSender:self])
+ [super interpretKeyEvents:eventArray];
+}
+@end
+
+@implementation NSMutableAttributedString (TextInputController)
+
++ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
+{
+ if (aSelector == @selector(string)
+ || aSelector == @selector(getLength)
+ || aSelector == @selector(attributeNamesAtIndex:)
+ || aSelector == @selector(valueOfAttribute:atIndex:)
+ || aSelector == @selector(addAttribute:value:)
+ || aSelector == @selector(addAttribute:value:from:length:)
+ || aSelector == @selector(addColorAttribute:red:green:blue:alpha:)
+ || aSelector == @selector(addColorAttribute:red:green:blue:alpha:from:length:)
+ || aSelector == @selector(addFontAttribute:fontName:size:)
+ || aSelector == @selector(addFontAttribute:fontName:size:from:length:))
+ return NO;
+ return YES;
+}
+
++ (NSString *)webScriptNameForSelector:(SEL)aSelector
+{
+ if (aSelector == @selector(getLength))
+ return @"length";
+ if (aSelector == @selector(attributeNamesAtIndex:))
+ return @"getAttributeNamesAtIndex";
+ if (aSelector == @selector(valueOfAttribute:atIndex:))
+ return @"getAttributeValueAtIndex";
+ if (aSelector == @selector(addAttribute:value:))
+ return @"addAttribute";
+ if (aSelector == @selector(addAttribute:value:from:length:))
+ return @"addAttributeForRange";
+ if (aSelector == @selector(addColorAttribute:red:green:blue:alpha:))
+ return @"addColorAttribute";
+ if (aSelector == @selector(addColorAttribute:red:green:blue:alpha:from:length:))
+ return @"addColorAttributeForRange";
+ if (aSelector == @selector(addFontAttribute:fontName:size:))
+ return @"addFontAttribute";
+ if (aSelector == @selector(addFontAttribute:fontName:size:from:length:))
+ return @"addFontAttributeForRange";
+
+ return nil;
+}
+
+- (int)getLength
+{
+ return (int)[self length];
+}
+
+- (NSArray *)attributeNamesAtIndex:(int)index
+{
+ NSDictionary *attributes = [self attributesAtIndex:(unsigned)index effectiveRange:nil];
+ return [attributes allKeys];
+}
+
+- (id)valueOfAttribute:(NSString *)attrName atIndex:(int)index
+{
+ return [self attribute:attrName atIndex:(unsigned)index effectiveRange:nil];
+}
+
+- (void)addAttribute:(NSString *)attrName value:(id)value
+{
+ [self addAttribute:attrName value:value range:NSMakeRange(0, [self length])];
+}
+
+- (void)addAttribute:(NSString *)attrName value:(id)value from:(int)from length:(int)length
+{
+ [self addAttribute:attrName value:value range:NSMakeRange((unsigned)from, (unsigned)length)];
+}
+
+- (void)addColorAttribute:(NSString *)attrName red:(float)red green:(float)green blue:(float)blue alpha:(float)alpha
+{
+ [self addAttribute:attrName value:[NSColor colorWithDeviceRed:red green:green blue:blue alpha:alpha] range:NSMakeRange(0, [self length])];
+}
+
+- (void)addColorAttribute:(NSString *)attrName red:(float)red green:(float)green blue:(float)blue alpha:(float)alpha from:(int)from length:(int)length
+{
+ [self addAttribute:attrName value:[NSColor colorWithDeviceRed:red green:green blue:blue alpha:alpha] range:NSMakeRange((unsigned)from, (unsigned)length)];
+}
+
+- (void)addFontAttribute:(NSString *)attrName fontName:(NSString *)fontName size:(float)fontSize
+{
+ [self addAttribute:attrName value:[NSFont fontWithName:fontName size:fontSize] range:NSMakeRange(0, [self length])];
+}
+
+- (void)addFontAttribute:(NSString *)attrName fontName:(NSString *)fontName size:(float)fontSize from:(int)from length:(int)length
+{
+ [self addAttribute:attrName value:[NSFont fontWithName:fontName size:fontSize] range:NSMakeRange((unsigned)from, (unsigned)length)];
+}
+
+@end
+
+@implementation TextInputController
+
++ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
+{
+ if (aSelector == @selector(insertText:)
+ || aSelector == @selector(doCommand:)
+ || aSelector == @selector(setMarkedText:selectedFrom:length:)
+ || aSelector == @selector(unmarkText)
+ || aSelector == @selector(hasMarkedText)
+ || aSelector == @selector(conversationIdentifier)
+ || aSelector == @selector(substringFrom:length:)
+ || aSelector == @selector(attributedSubstringFrom:length:)
+ || aSelector == @selector(markedRange)
+ || aSelector == @selector(selectedRange)
+ || aSelector == @selector(firstRectForCharactersFrom:length:)
+ || aSelector == @selector(characterIndexForPointX:Y:)
+ || aSelector == @selector(validAttributesForMarkedText)
+ || aSelector == @selector(attributedStringWithString:)
+ || aSelector == @selector(setInputMethodHandler:))
+ return NO;
+ return YES;
+}
+
++ (NSString *)webScriptNameForSelector:(SEL)aSelector
+{
+ if (aSelector == @selector(insertText:))
+ return @"insertText";
+ else if (aSelector == @selector(doCommand:))
+ return @"doCommand";
+ else if (aSelector == @selector(setMarkedText:selectedFrom:length:))
+ return @"setMarkedText";
+ else if (aSelector == @selector(substringFrom:length:))
+ return @"substringFromRange";
+ else if (aSelector == @selector(attributedSubstringFrom:length:))
+ return @"attributedSubstringFromRange";
+ else if (aSelector == @selector(firstRectForCharactersFrom:length:))
+ return @"firstRectForCharacterRange";
+ else if (aSelector == @selector(characterIndexForPointX:Y:))
+ return @"characterIndexForPoint";
+ else if (aSelector == @selector(attributedStringWithString:))
+ return @"makeAttributedString"; // just a factory method, doesn't call into NSTextInput
+ else if (aSelector == @selector(setInputMethodHandler:))
+ return @"setInputMethodHandler";
+
+ return nil;
+}
+
+- (id)initWithWebView:(WebView *)wv
+{
+ self = [super init];
+ webView = wv;
+ inputMethodView = nil;
+ inputMethodHandler = nil;
+ return self;
+}
+
+- (void)dealloc
+{
+ [inputMethodHandler release];
+ inputMethodHandler = nil;
+
+ [super dealloc];
+}
+
+- (NSObject <NSTextInput> *)textInput
+{
+ NSView <NSTextInput> *view = inputMethodView ? inputMethodView : (id)[[[webView mainFrame] frameView] documentView];
+ return [view conformsToProtocol:@protocol(NSTextInput)] ? view : nil;
+}
+
+- (void)insertText:(id)aString
+{
+ NSObject <NSTextInput> *textInput = [self textInput];
+
+ if (textInput)
+ [textInput insertText:aString];
+}
+
+- (void)doCommand:(NSString *)aCommand
+{
+ NSObject <NSTextInput> *textInput = [self textInput];
+
+ if (textInput)
+ [textInput doCommandBySelector:NSSelectorFromString(aCommand)];
+}
+
+- (void)setMarkedText:(NSString *)aString selectedFrom:(int)from length:(int)length
+{
+ NSObject <NSTextInput> *textInput = [self textInput];
+
+ if (textInput)
+ [textInput setMarkedText:aString selectedRange:NSMakeRange(from, length)];
+}
+
+- (void)unmarkText
+{
+ NSObject <NSTextInput> *textInput = [self textInput];
+
+ if (textInput)
+ [textInput unmarkText];
+}
+
+- (BOOL)hasMarkedText
+{
+ NSObject <NSTextInput> *textInput = [self textInput];
+
+ if (textInput)
+ return [textInput hasMarkedText];
+
+ return FALSE;
+}
+
+- (long)conversationIdentifier
+{
+ NSObject <NSTextInput> *textInput = [self textInput];
+
+ if (textInput)
+ return [textInput conversationIdentifier];
+
+ return 0;
+}
+
+- (NSString *)substringFrom:(int)from length:(int)length
+{
+ NSObject <NSTextInput> *textInput = [self textInput];
+
+ if (textInput)
+ return [[textInput attributedSubstringFromRange:NSMakeRange(from, length)] string];
+
+ return @"";
+}
+
+- (NSMutableAttributedString *)attributedSubstringFrom:(int)from length:(int)length
+{
+ NSObject <NSTextInput> *textInput = [self textInput];
+
+ NSMutableAttributedString *ret = [[[NSMutableAttributedString alloc] init] autorelease];
+
+ if (textInput)
+ [ret setAttributedString:[textInput attributedSubstringFromRange:NSMakeRange(from, length)]];
+
+ return ret;
+}
+
+- (NSArray *)markedRange
+{
+ NSObject <NSTextInput> *textInput = [self textInput];
+
+ if (textInput) {
+ NSRange range = [textInput markedRange];
+ return [NSArray arrayWithObjects:[NSNumber numberWithUnsignedInt:range.location], [NSNumber numberWithUnsignedInt:range.length], nil];
+ }
+
+ return nil;
+}
+
+- (NSArray *)selectedRange
+{
+ NSObject <NSTextInput> *textInput = [self textInput];
+
+ if (textInput) {
+ NSRange range = [textInput selectedRange];
+ return [NSArray arrayWithObjects:[NSNumber numberWithUnsignedInt:range.location], [NSNumber numberWithUnsignedInt:range.length], nil];
+ }
+
+ return nil;
+}
+
+
+- (NSArray *)firstRectForCharactersFrom:(int)from length:(int)length
+{
+ NSObject <NSTextInput> *textInput = [self textInput];
+
+ if (textInput) {
+ NSRect rect = [textInput firstRectForCharacterRange:NSMakeRange(from, length)];
+ if (rect.origin.x || rect.origin.y || rect.size.width || rect.size.height) {
+ rect.origin = [[webView window] convertScreenToBase:rect.origin];
+ rect = [webView convertRect:rect fromView:nil];
+ }
+ return [NSArray arrayWithObjects:
+ [NSNumber numberWithFloat:rect.origin.x],
+ [NSNumber numberWithFloat:rect.origin.y],
+ [NSNumber numberWithFloat:rect.size.width],
+ [NSNumber numberWithFloat:rect.size.height],
+ nil];
+ }
+
+ return nil;
+}
+
+- (int)characterIndexForPointX:(float)x Y:(float)y
+{
+ NSObject <NSTextInput> *textInput = [self textInput];
+
+ if (textInput) {
+ NSPoint point = NSMakePoint(x, y);
+ point = [webView convertPoint:point toView:nil];
+ point = [[webView window] convertBaseToScreen:point];
+ return [textInput characterIndexForPoint:point];
+ }
+
+ return 0;
+}
+
+- (NSArray *)validAttributesForMarkedText
+{
+ NSObject <NSTextInput> *textInput = [self textInput];
+
+ if (textInput)
+ return [textInput validAttributesForMarkedText];
+
+ return nil;
+}
+
+- (NSMutableAttributedString *)attributedStringWithString:(NSString *)aString
+{
+ return [[[NSMutableAttributedString alloc] initWithString:aString] autorelease];
+}
+
+- (void)setInputMethodHandler:(WebScriptObject *)handler
+{
+ if (inputMethodHandler == handler)
+ return;
+ [handler retain];
+ [inputMethodHandler release];
+ inputMethodHandler = handler;
+}
+
+- (BOOL)interpretKeyEvents:(NSArray *)eventArray withSender:(WebHTMLView *)sender
+{
+ if (!inputMethodHandler)
+ return NO;
+
+ inputMethodView = sender;
+
+ NSEvent *event = [eventArray objectAtIndex:0];
+ unsigned modifierFlags = [event modifierFlags];
+ NSMutableArray *modifiers = [[NSMutableArray alloc] init];
+ if (modifierFlags & NSAlphaShiftKeyMask)
+ [modifiers addObject:@"NSAlphaShiftKeyMask"];
+ if (modifierFlags & NSShiftKeyMask)
+ [modifiers addObject:@"NSShiftKeyMask"];
+ if (modifierFlags & NSControlKeyMask)
+ [modifiers addObject:@"NSControlKeyMask"];
+ if (modifierFlags & NSAlternateKeyMask)
+ [modifiers addObject:@"NSAlternateKeyMask"];
+ if (modifierFlags & NSCommandKeyMask)
+ [modifiers addObject:@"NSCommandKeyMask"];
+ if (modifierFlags & NSNumericPadKeyMask)
+ [modifiers addObject:@"NSNumericPadKeyMask"];
+ if (modifierFlags & NSHelpKeyMask)
+ [modifiers addObject:@"NSHelpKeyMask"];
+ if (modifierFlags & NSFunctionKeyMask)
+ [modifiers addObject:@"NSFunctionKeyMask"];
+
+ WebScriptObject* eventParam = [inputMethodHandler evaluateWebScript:@"new Object();"];
+ [eventParam setValue:[event characters] forKey:@"characters"];
+ [eventParam setValue:[event charactersIgnoringModifiers] forKey:@"charactersIgnoringModifiers"];
+ [eventParam setValue:[NSNumber numberWithBool:[event isARepeat]] forKey:@"isARepeat"];
+ [eventParam setValue:[NSNumber numberWithUnsignedShort:[event keyCode]] forKey:@"keyCode"];
+ [eventParam setValue:modifiers forKey:@"modifierFlags"];
+
+ [modifiers release];
+
+ id result = [inputMethodHandler callWebScriptMethod:@"call" withArguments:[NSArray arrayWithObjects:inputMethodHandler, eventParam, nil]];
+ if (![result respondsToSelector:@selector(boolValue)] || ![result boolValue])
+ [sender doCommandBySelector:@selector(noop:)]; // AppKit sends noop: if the ime does not handle an event
+
+ inputMethodView = nil;
+ return YES;
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/UIDelegate.h b/WebKitTools/DumpRenderTree/mac/UIDelegate.h
new file mode 100644
index 0000000..da472d6
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/UIDelegate.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2006 Apple Computer, 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 <Cocoa/Cocoa.h>
+
+@interface UIDelegate : NSObject {
+
+@private
+ NSRect m_frame;
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/UIDelegate.mm b/WebKitTools/DumpRenderTree/mac/UIDelegate.mm
new file mode 100644
index 0000000..9c440a7
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/UIDelegate.mm
@@ -0,0 +1,153 @@
+/*
+ * 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.
+ */
+
+#import "DumpRenderTree.h"
+#import "UIDelegate.h"
+
+#import "DumpRenderTreeDraggingInfo.h"
+#import "EventSendingController.h"
+#import "LayoutTestController.h"
+#import <WebKit/WebFramePrivate.h>
+#import <WebKit/WebHTMLViewPrivate.h>
+#import <WebKit/WebView.h>
+#import <WebKit/WebSecurityOriginPrivate.h>
+#import <wtf/Assertions.h>
+
+DumpRenderTreeDraggingInfo *draggingInfo = nil;
+
+@implementation UIDelegate
+
+- (void)webView:(WebView *)sender setFrame:(NSRect)frame
+{
+ m_frame = frame;
+}
+
+- (NSRect)webViewFrame:(WebView *)sender;
+{
+ return m_frame;
+}
+
+- (void)webView:(WebView *)sender addMessageToConsole:(NSDictionary *)dictionary
+{
+ NSString *message = [dictionary objectForKey:@"message"];
+ NSNumber *lineNumber = [dictionary objectForKey:@"lineNumber"];
+
+ NSRange range = [message rangeOfString:@"file://"];
+ if (range.location != NSNotFound)
+ message = [[message substringToIndex:range.location] stringByAppendingString:[[message substringFromIndex:NSMaxRange(range)] lastPathComponent]];
+
+ printf ("CONSOLE MESSAGE: line %d: %s\n", [lineNumber intValue], [message UTF8String]);
+}
+
+- (void)webView:(WebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame
+{
+ if (!done)
+ printf("ALERT: %s\n", [message UTF8String]);
+}
+
+- (BOOL)webView:(WebView *)sender runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame
+{
+ if (!done)
+ printf("CONFIRM: %s\n", [message UTF8String]);
+ return YES;
+}
+
+- (NSString *)webView:(WebView *)sender runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WebFrame *)frame
+{
+ if (!done)
+ printf("PROMPT: %s, default text: %s\n", [prompt UTF8String], [defaultText UTF8String]);
+ return defaultText;
+}
+
+- (void)webView:(WebView *)sender dragImage:(NSImage *)anImage at:(NSPoint)viewLocation offset:(NSSize)initialOffset event:(NSEvent *)event pasteboard:(NSPasteboard *)pboard source:(id)sourceObj slideBack:(BOOL)slideFlag forView:(NSView *)view
+{
+ assert(!draggingInfo);
+ if (layoutTestController->addFileToPasteboardOnDrag()) {
+ [pboard declareTypes:[NSArray arrayWithObject:NSFilenamesPboardType] owner:nil];
+ [pboard setPropertyList:[NSArray arrayWithObject:@"DRTFakeFile"] forType:NSFilenamesPboardType];
+ }
+ draggingInfo = [[DumpRenderTreeDraggingInfo alloc] initWithImage:anImage offset:initialOffset pasteboard:pboard source:sourceObj];
+ [EventSendingController replaySavedEvents];
+}
+
+- (void)webViewFocus:(WebView *)webView
+{
+ layoutTestController->setWindowIsKey(true);
+ NSView *documentView = [[mainFrame frameView] documentView];
+ if ([documentView isKindOfClass:[WebHTMLView class]])
+ [(WebHTMLView *)documentView _updateFocusedAndActiveState];
+}
+
+- (WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request
+{
+ if (!layoutTestController->canOpenWindows())
+ return nil;
+
+ // Make sure that waitUntilDone has been called.
+ ASSERT(layoutTestController->waitToDump());
+
+ WebView *webView = createWebViewAndOffscreenWindow();
+
+ return [webView autorelease];
+}
+
+- (void)webViewClose:(WebView *)sender
+{
+ NSWindow* window = [sender window];
+
+ if (layoutTestController->callCloseOnWebViews())
+ [sender close];
+
+ [window close];
+}
+
+- (void)webView:(WebView *)sender frame:(WebFrame *)frame exceededDatabaseQuotaForSecurityOrigin:(WebSecurityOrigin *)origin database:(NSString *)databaseIdentifier
+{
+ if (!done && layoutTestController->dumpDatabaseCallbacks())
+ printf("UI DELEGATE DATABASE CALLBACK: exceededDatabaseQuotaForSecurityOrigin:{%s, %s, %i} database:%s\n", [[origin protocol] UTF8String], [[origin domain] UTF8String],
+ [origin port], [databaseIdentifier UTF8String]);
+
+ static const unsigned long long defaultQuota = 5 * 1024 * 1024;
+ [origin setQuota:defaultQuota];
+}
+
+- (void)webView:(WebView *)sender setStatusText:(NSString *)text
+{
+ if (layoutTestController->dumpStatusCallbacks())
+ printf("UI DELEGATE STATUS CALLBACK: setStatusText:%s\n", [text UTF8String]);
+}
+
+- (void)dealloc
+{
+ [draggingInfo release];
+ draggingInfo = nil;
+
+ [super dealloc];
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/WorkQueueItemMac.mm b/WebKitTools/DumpRenderTree/mac/WorkQueueItemMac.mm
new file mode 100644
index 0000000..3a7b0e2
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/WorkQueueItemMac.mm
@@ -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.
+ */
+
+#import "DumpRenderTree.h"
+#import "WorkQueueItem.h"
+
+#import <JavaScriptCore/JSStringRef.h>
+#import <JavaScriptCore/JSStringRefCF.h>
+#import <WebKit/WebBackForwardList.h>
+#import <WebKit/WebFrame.h>
+#import <WebKit/WebScriptObject.h>
+#import <WebKit/WebView.h>
+#import <wtf/RetainPtr.h>
+
+void LoadItem::invoke() const
+{
+ RetainPtr<CFStringRef> urlCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, m_url.get()));
+ NSString *urlNS = (NSString *)urlCF.get();
+ RetainPtr<CFStringRef> targetCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, m_target.get()));
+ NSString *targetNS = (NSString *)targetCF.get();
+
+ WebFrame *targetFrame;
+ if (targetNS && [targetNS length])
+ targetFrame = [mainFrame findFrameNamed:targetNS];
+ else
+ targetFrame = mainFrame;
+ [targetFrame loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlNS]]];
+}
+
+void ReloadItem::invoke() const
+{
+ [[mainFrame webView] reload:nil];
+}
+
+void ScriptItem::invoke() const
+{
+ RetainPtr<CFStringRef> scriptCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, m_script.get()));
+ NSString *scriptNS = (NSString *)scriptCF.get();
+ [[mainFrame webView] stringByEvaluatingJavaScriptFromString:scriptNS];
+}
+
+void BackForwardItem::invoke() const
+{
+ if (m_howFar == 1)
+ [[mainFrame webView] goForward];
+ else if (m_howFar == -1)
+ [[mainFrame webView] goBack];
+ else {
+ WebBackForwardList *bfList = [[mainFrame webView] backForwardList];
+ [[mainFrame webView] goToBackForwardItem:[bfList itemAtIndex:m_howFar]];
+ }
+}
diff --git a/WebKitTools/DumpRenderTree/pthreads/JavaScriptThreadingPthreads.cpp b/WebKitTools/DumpRenderTree/pthreads/JavaScriptThreadingPthreads.cpp
new file mode 100644
index 0000000..19f6dc2
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/pthreads/JavaScriptThreadingPthreads.cpp
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
+ * (C) 2007 Graham Dennis (graham.dennis@gmail.com)
+ * (C) 2007 Eric Seidel <eric@webkit.org>
+ *
+ * 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 "JavaScriptThreading.h"
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <JavaScriptCore/JavaScriptCore.h>
+#include <pthread.h>
+#include <wtf/Assertions.h>
+#include <wtf/HashSet.h>
+
+static pthread_mutex_t javaScriptThreadsMutex = PTHREAD_MUTEX_INITIALIZER;
+static bool javaScriptThreadsShouldTerminate;
+
+static const int javaScriptThreadsCount = 4;
+
+typedef HashSet<pthread_t> ThreadSet;
+
+static ThreadSet* javaScriptThreads()
+{
+ ASSERT(pthread_mutex_trylock(&javaScriptThreadsMutex) == EBUSY);
+ static ThreadSet staticJavaScriptThreads;
+ return &staticJavaScriptThreads;
+}
+
+// Loops forever, running a script and randomly respawning, until
+// javaScriptThreadsShouldTerminate becomes true.
+void* runJavaScriptThread(void* arg)
+{
+ const char* const script =
+ "var array = [];"
+ "for (var i = 0; i < 10; i++) {"
+ " array.push(String(i));"
+ "}";
+
+ while (1) {
+ JSGlobalContextRef ctx = JSGlobalContextCreate(0);
+ JSStringRef scriptRef = JSStringCreateWithUTF8CString(script);
+
+ JSValueRef exception = 0;
+ JSEvaluateScript(ctx, scriptRef, 0, 0, 0, &exception);
+ ASSERT(!exception);
+
+ JSGlobalContextRelease(ctx);
+ JSStringRelease(scriptRef);
+
+ JSGarbageCollect(ctx);
+
+ pthread_mutex_lock(&javaScriptThreadsMutex);
+
+ // Check for cancellation.
+ if (javaScriptThreadsShouldTerminate) {
+ pthread_mutex_unlock(&javaScriptThreadsMutex);
+ return 0;
+ }
+
+ // Respawn probabilistically.
+ if (random() % 5 == 0) {
+ pthread_t pthread;
+ pthread_create(&pthread, 0, &runJavaScriptThread, 0);
+ pthread_detach(pthread);
+
+ javaScriptThreads()->remove(pthread_self());
+ javaScriptThreads()->add(pthread);
+
+ pthread_mutex_unlock(&javaScriptThreadsMutex);
+ return 0;
+ }
+
+ pthread_mutex_unlock(&javaScriptThreadsMutex);
+ }
+}
+
+void startJavaScriptThreads()
+{
+ pthread_mutex_lock(&javaScriptThreadsMutex);
+
+ for (int i = 0; i < javaScriptThreadsCount; i++) {
+ pthread_t pthread;
+ pthread_create(&pthread, 0, &runJavaScriptThread, 0);
+ javaScriptThreads()->add(pthread);
+ }
+
+ pthread_mutex_unlock(&javaScriptThreadsMutex);
+}
+
+void stopJavaScriptThreads()
+{
+ pthread_mutex_lock(&javaScriptThreadsMutex);
+
+ javaScriptThreadsShouldTerminate = true;
+
+ ASSERT(javaScriptThreads()->size() == javaScriptThreadsCount);
+
+ pthread_mutex_unlock(&javaScriptThreadsMutex);
+
+ ThreadSet::iterator end = javaScriptThreads()->end();
+ for (ThreadSet::iterator it = javaScriptThreads()->begin(); it != end; ++it) {
+ pthread_t pthread = *it;
+ pthread_join(pthread, 0);
+ }
+}
diff --git a/WebKitTools/DumpRenderTree/qt/DumpRenderTree.cpp b/WebKitTools/DumpRenderTree/qt/DumpRenderTree.cpp
new file mode 100644
index 0000000..5df8a38
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/qt/DumpRenderTree.cpp
@@ -0,0 +1,310 @@
+/*
+ * Copyright (C) 2005, 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
+ *
+ * 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 "DumpRenderTree.h"
+#include "jsobjects.h"
+
+#include <QDir>
+#include <QFile>
+#include <QTimer>
+#include <QBoxLayout>
+#include <QScrollArea>
+#include <QApplication>
+#include <QUrl>
+#include <QFocusEvent>
+
+#include <qwebpage.h>
+#include <qwebframe.h>
+#include <qwebview.h>
+#include <qwebsettings.h>
+
+#include <unistd.h>
+#include <qdebug.h>
+extern void qt_drt_run(bool b);
+extern void qt_dump_set_accepts_editing(bool b);
+
+
+namespace WebCore {
+
+// Choose some default values.
+const unsigned int maxViewWidth = 800;
+const unsigned int maxViewHeight = 600;
+
+class WebPage : public QWebPage {
+ Q_OBJECT
+public:
+ WebPage(QWidget *parent, DumpRenderTree *drt);
+
+ QWebPage *createWindow();
+
+ void javaScriptAlert(QWebFrame *frame, const QString& message);
+ void javaScriptConsoleMessage(const QString& message, unsigned int lineNumber, const QString& sourceID);
+ bool javaScriptConfirm(QWebFrame *frame, const QString& msg);
+ bool javaScriptPrompt(QWebFrame *frame, const QString& msg, const QString& defaultValue, QString* result);
+
+private slots:
+ void setViewGeometry(const QRect &r)
+ {
+ QWidget *v = view();
+ if (v)
+ v->setGeometry(r);
+ }
+private:
+ DumpRenderTree *m_drt;
+};
+
+WebPage::WebPage(QWidget *parent, DumpRenderTree *drt)
+ : QWebPage(parent), m_drt(drt)
+{
+ settings()->setAttribute(QWebSettings::JavascriptCanOpenWindows, true);
+ settings()->setAttribute(QWebSettings::JavascriptCanAccessClipboard, true);
+ settings()->setAttribute(QWebSettings::LinksIncludedInFocusChain, false);
+ connect(this, SIGNAL(geometryChangeRequest(const QRect &)),
+ this, SLOT(setViewGeometry(const QRect & )));
+}
+
+QWebPage *WebPage::createWindow()
+{
+ return m_drt->createWindow();
+}
+
+void WebPage::javaScriptAlert(QWebFrame *frame, const QString& message)
+{
+ fprintf(stdout, "ALERT: %s\n", message.toUtf8().constData());
+}
+
+void WebPage::javaScriptConsoleMessage(const QString& message, unsigned int lineNumber, const QString&)
+{
+ fprintf (stdout, "CONSOLE MESSAGE: line %d: %s\n", lineNumber, message.toUtf8().constData());
+}
+
+bool WebPage::javaScriptConfirm(QWebFrame *frame, const QString& msg)
+{
+ fprintf(stdout, "CONFIRM: %s\n", msg.toUtf8().constData());
+ return true;
+}
+
+bool WebPage::javaScriptPrompt(QWebFrame *frame, const QString& msg, const QString& defaultValue, QString* result)
+{
+ fprintf(stdout, "PROMPT: %s, default text: %s\n", msg.toUtf8().constData(), defaultValue.toUtf8().constData());
+ *result = defaultValue;
+ return true;
+}
+
+DumpRenderTree::DumpRenderTree()
+ : m_stdin(0)
+ , m_notifier(0)
+{
+ m_controller = new LayoutTestController(this);
+ connect(m_controller, SIGNAL(done()), this, SLOT(dump()), Qt::QueuedConnection);
+
+ QWebView *view = new QWebView(0);
+ view->resize(QSize(maxViewWidth, maxViewHeight));
+ m_page = new WebPage(view, this);
+ view->setPage(m_page);
+ connect(m_page, SIGNAL(frameCreated(QWebFrame *)), this, SLOT(connectFrame(QWebFrame *)));
+ connectFrame(m_page->mainFrame());
+
+ m_page->mainFrame()->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ m_page->mainFrame()->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ connect(m_page->mainFrame(), SIGNAL(titleChanged(const QString&)),
+ SLOT(titleChanged(const QString&)));
+
+ m_eventSender = new EventSender(m_page);
+ m_textInputController = new TextInputController(m_page);
+
+ QObject::connect(this, SIGNAL(quit()), qApp, SLOT(quit()), Qt::QueuedConnection);
+ qt_drt_run(true);
+ QFocusEvent event(QEvent::FocusIn, Qt::ActiveWindowFocusReason);
+ QApplication::sendEvent(view, &event);
+}
+
+DumpRenderTree::~DumpRenderTree()
+{
+ delete m_page;
+
+ delete m_stdin;
+ delete m_notifier;
+}
+
+void DumpRenderTree::open()
+{
+ if (!m_stdin) {
+ m_stdin = new QFile;
+ m_stdin->open(stdin, QFile::ReadOnly);
+ }
+
+ if (!m_notifier) {
+ m_notifier = new QSocketNotifier(STDIN_FILENO, QSocketNotifier::Read);
+ connect(m_notifier, SIGNAL(activated(int)), this, SLOT(readStdin(int)));
+ }
+}
+
+void DumpRenderTree::open(const QUrl& url)
+{
+ resetJSObjects();
+ m_page->mainFrame()->load(url);
+}
+
+void DumpRenderTree::readStdin(int /* socket */)
+{
+ // Read incoming data from stdin...
+ QByteArray line = m_stdin->readLine();
+ if (line.endsWith('\n'))
+ line.truncate(line.size()-1);
+ //fprintf(stderr, "\n opening %s\n", line.constData());
+ if (line.isEmpty())
+ quit();
+ QFileInfo fi(line);
+ open(QUrl::fromLocalFile(fi.absoluteFilePath()));
+ fflush(stdout);
+}
+
+void DumpRenderTree::resetJSObjects()
+{
+ m_controller->reset();
+ foreach(QWidget *widget, windows)
+ delete widget;
+ windows.clear();
+}
+
+void DumpRenderTree::initJSObjects()
+{
+ QWebFrame *frame = qobject_cast<QWebFrame*>(sender());
+ Q_ASSERT(frame);
+ frame->addToJSWindowObject(QLatin1String("layoutTestController"), m_controller);
+ frame->addToJSWindowObject(QLatin1String("eventSender"), m_eventSender);
+ frame->addToJSWindowObject(QLatin1String("textInputController"), m_textInputController);
+}
+
+
+QString DumpRenderTree::dumpFramesAsText(QWebFrame* frame)
+{
+ if (!frame)
+ return QString();
+
+ QString result;
+ QWebFrame *parent = qobject_cast<QWebFrame *>(frame->parent());
+ if (parent) {
+ result.append(QLatin1String("\n--------\nFrame: '"));
+ result.append(frame->name());
+ result.append(QLatin1String("'\n--------\n"));
+ }
+
+ result.append(frame->innerText());
+ result.append(QLatin1String("\n"));
+
+ if (m_controller->shouldDumpChildrenAsText()) {
+ QList<QWebFrame *> children = frame->childFrames();
+ for (int i = 0; i < children.size(); ++i)
+ result += dumpFramesAsText(children.at(i));
+ }
+
+ return result;
+}
+
+void DumpRenderTree::dump()
+{
+ QWebFrame *frame = m_page->mainFrame();
+
+ //fprintf(stderr, " Dumping\n");
+ if (!m_notifier) {
+ // Dump markup in single file mode...
+ QString markup = frame->markup();
+ fprintf(stdout, "Source:\n\n%s\n", markup.toUtf8().constData());
+ }
+
+ // Dump render text...
+ QString renderDump;
+ if (m_controller->shouldDumpAsText()) {
+ renderDump = dumpFramesAsText(frame);
+ } else {
+ renderDump = frame->renderTreeDump();
+ }
+ if (renderDump.isEmpty()) {
+ printf("ERROR: nil result from %s", m_controller->shouldDumpAsText() ? "[documentElement innerText]" : "[frame renderTreeAsExternalRepresentation]");
+ } else {
+ fprintf(stdout, "%s", renderDump.toUtf8().constData());
+ }
+
+ fprintf(stdout, "#EOF\n");
+
+ fflush(stdout);
+
+ if (!m_notifier) {
+ // Exit now in single file mode...
+ quit();
+ }
+}
+
+void DumpRenderTree::titleChanged(const QString &s)
+{
+ if (m_controller->shouldDumpTitleChanges())
+ printf("TITLE CHANGED: %s\n", s.toUtf8().data());
+}
+
+void DumpRenderTree::connectFrame(QWebFrame *frame)
+{
+ connect(frame, SIGNAL(cleared()), this, SLOT(initJSObjects()));
+ connect(frame, SIGNAL(provisionalLoad()),
+ layoutTestController(), SLOT(provisionalLoad()));
+
+ if (frame == m_page->mainFrame()) {
+ connect(frame, SIGNAL(loadDone(bool)),
+ layoutTestController(), SLOT(maybeDump(bool)));
+ }
+}
+
+QWebPage *DumpRenderTree::createWindow()
+{
+ if (!m_controller->canOpenWindows())
+ return 0;
+ QWidget *container = new QWidget(0);
+ container->resize(0, 0);
+ container->move(-1, -1);
+ container->hide();
+ QWebPage *page = new WebPage(container, this);
+ connect(m_page, SIGNAL(frameCreated(QWebFrame *)), this, SLOT(connectFrame(QWebFrame *)));
+ windows.append(container);
+ return page;
+}
+
+int DumpRenderTree::windowCount() const
+{
+ int count = 0;
+ foreach(QWidget *w, windows) {
+ if (w->children().count())
+ ++count;
+ }
+ return count + 1;
+}
+
+}
+
+#include "DumpRenderTree.moc"
diff --git a/WebKitTools/DumpRenderTree/qt/DumpRenderTree.h b/WebKitTools/DumpRenderTree/qt/DumpRenderTree.h
new file mode 100644
index 0000000..b939fad
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/qt/DumpRenderTree.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
+ *
+ * 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 DUMPRENDERTREE_H
+#define DUMPRENDERTREE_H
+
+#include <QList>
+#include <QObject>
+#include <QTextStream>
+#include <QSocketNotifier>
+class QUrl;
+class QFile;
+class QWebPage;
+class QWebFrame;
+
+class LayoutTestController;
+class EventSender;
+class TextInputController;
+
+namespace WebCore {
+
+class DumpRenderTree : public QObject {
+Q_OBJECT
+
+public:
+ DumpRenderTree();
+ virtual ~DumpRenderTree();
+
+ // Initialize in multi-file mode, used by run-webkit-tests.
+ void open();
+
+ // Initialize in single-file mode.
+ void open(const QUrl& url);
+
+ void resetJSObjects();
+
+ LayoutTestController *layoutTestController() const { return m_controller; }
+ EventSender *eventSender() const { return m_eventSender; }
+ TextInputController *textInputController() const { return m_textInputController; }
+
+ QWebPage *createWindow();
+ int windowCount() const;
+
+ QWebPage *webPage() const { return m_page; }
+
+public Q_SLOTS:
+ void initJSObjects();
+ void readStdin(int);
+ void dump();
+ void titleChanged(const QString &s);
+ void connectFrame(QWebFrame *frame);
+
+Q_SIGNALS:
+ void quit();
+
+private:
+ QString dumpFramesAsText(QWebFrame* frame);
+ LayoutTestController *m_controller;
+
+ QWebPage *m_page;
+
+ EventSender *m_eventSender;
+ TextInputController *m_textInputController;
+
+ QFile *m_stdin;
+ QSocketNotifier* m_notifier;
+
+ QList<QWidget *> windows;
+};
+
+}
+
+#endif
diff --git a/WebKitTools/DumpRenderTree/qt/DumpRenderTree.pro b/WebKitTools/DumpRenderTree/qt/DumpRenderTree.pro
new file mode 100644
index 0000000..8c3dbbf
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/qt/DumpRenderTree.pro
@@ -0,0 +1,18 @@
+TARGET = DumpRenderTree
+CONFIG -= app_bundle
+
+include(../../../WebKit.pri)
+INCLUDEPATH += /usr/include/freetype2
+INCLUDEPATH += ../../../JavaScriptCore/kjs
+DESTDIR = ../../../bin
+
+
+QT = core gui
+macx: QT += xml network
+
+HEADERS = DumpRenderTree.h jsobjects.h testplugin.h
+SOURCES = DumpRenderTree.cpp main.cpp jsobjects.cpp testplugin.cpp
+
+unix:!mac {
+ QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR
+}
diff --git a/WebKitTools/DumpRenderTree/qt/fonts.conf b/WebKitTools/DumpRenderTree/qt/fonts.conf
new file mode 100644
index 0000000..3540c47
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/qt/fonts.conf
@@ -0,0 +1,258 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<fontconfig>
+
+<!--
+ Accept deprecated 'mono' alias, replacing it with 'monospace'
+-->
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>mono</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>monospace</string>
+ </edit>
+ </match>
+
+<!--
+ Accept alternate 'sans serif' spelling, replacing it with 'sans-serif'
+-->
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>sans serif</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>sans-serif</string>
+ </edit>
+ </match>
+
+<!--
+ Accept deprecated 'sans' alias, replacing it with 'sans-serif'
+-->
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>sans</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>sans-serif</string>
+ </edit>
+ </match>
+
+
+ <config>
+<!--
+ These are the default Unicode chars that are expected to be blank
+ in fonts. All other blank chars are assumed to be broken and
+ won't appear in the resulting charsets
+ -->
+ <blank>
+ <int>0x0020</int> <!-- SPACE -->
+ <int>0x00A0</int> <!-- NO-BREAK SPACE -->
+ <int>0x00AD</int> <!-- SOFT HYPHEN -->
+ <int>0x034F</int> <!-- COMBINING GRAPHEME JOINER -->
+ <int>0x0600</int> <!-- ARABIC NUMBER SIGN -->
+ <int>0x0601</int> <!-- ARABIC SIGN SANAH -->
+ <int>0x0602</int> <!-- ARABIC FOOTNOTE MARKER -->
+ <int>0x0603</int> <!-- ARABIC SIGN SAFHA -->
+ <int>0x06DD</int> <!-- ARABIC END OF AYAH -->
+ <int>0x070F</int> <!-- SYRIAC ABBREVIATION MARK -->
+ <int>0x115F</int> <!-- HANGUL CHOSEONG FILLER -->
+ <int>0x1160</int> <!-- HANGUL JUNGSEONG FILLER -->
+ <int>0x1680</int> <!-- OGHAM SPACE MARK -->
+ <int>0x17B4</int> <!-- KHMER VOWEL INHERENT AQ -->
+ <int>0x17B5</int> <!-- KHMER VOWEL INHERENT AA -->
+ <int>0x180E</int> <!-- MONGOLIAN VOWEL SEPARATOR -->
+ <int>0x2000</int> <!-- EN QUAD -->
+ <int>0x2001</int> <!-- EM QUAD -->
+ <int>0x2002</int> <!-- EN SPACE -->
+ <int>0x2003</int> <!-- EM SPACE -->
+ <int>0x2004</int> <!-- THREE-PER-EM SPACE -->
+ <int>0x2005</int> <!-- FOUR-PER-EM SPACE -->
+ <int>0x2006</int> <!-- SIX-PER-EM SPACE -->
+ <int>0x2007</int> <!-- FIGURE SPACE -->
+ <int>0x2008</int> <!-- PUNCTUATION SPACE -->
+ <int>0x2009</int> <!-- THIN SPACE -->
+ <int>0x200A</int> <!-- HAIR SPACE -->
+ <int>0x200B</int> <!-- ZERO WIDTH SPACE -->
+ <int>0x200C</int> <!-- ZERO WIDTH NON-JOINER -->
+ <int>0x200D</int> <!-- ZERO WIDTH JOINER -->
+ <int>0x200E</int> <!-- LEFT-TO-RIGHT MARK -->
+ <int>0x200F</int> <!-- RIGHT-TO-LEFT MARK -->
+ <int>0x2028</int> <!-- LINE SEPARATOR -->
+ <int>0x2029</int> <!-- PARAGRAPH SEPARATOR -->
+ <int>0x202A</int> <!-- LEFT-TO-RIGHT EMBEDDING -->
+ <int>0x202B</int> <!-- RIGHT-TO-LEFT EMBEDDING -->
+ <int>0x202C</int> <!-- POP DIRECTIONAL FORMATTING -->
+ <int>0x202D</int> <!-- LEFT-TO-RIGHT OVERRIDE -->
+ <int>0x202E</int> <!-- RIGHT-TO-LEFT OVERRIDE -->
+ <int>0x202F</int> <!-- NARROW NO-BREAK SPACE -->
+ <int>0x205F</int> <!-- MEDIUM MATHEMATICAL SPACE -->
+ <int>0x2060</int> <!-- WORD JOINER -->
+ <int>0x2061</int> <!-- FUNCTION APPLICATION -->
+ <int>0x2062</int> <!-- INVISIBLE TIMES -->
+ <int>0x2063</int> <!-- INVISIBLE SEPARATOR -->
+ <int>0x206A</int> <!-- INHIBIT SYMMETRIC SWAPPING -->
+ <int>0x206B</int> <!-- ACTIVATE SYMMETRIC SWAPPING -->
+ <int>0x206C</int> <!-- INHIBIT ARABIC FORM SHAPING -->
+ <int>0x206D</int> <!-- ACTIVATE ARABIC FORM SHAPING -->
+ <int>0x206E</int> <!-- NATIONAL DIGIT SHAPES -->
+ <int>0x206F</int> <!-- NOMINAL DIGIT SHAPES -->
+ <int>0x3000</int> <!-- IDEOGRAPHIC SPACE -->
+ <int>0x3164</int> <!-- HANGUL FILLER -->
+ <int>0xFEFF</int> <!-- ZERO WIDTH NO-BREAK SPACE -->
+ <int>0xFFA0</int> <!-- HALFWIDTH HANGUL FILLER -->
+ <int>0xFFF9</int> <!-- INTERLINEAR ANNOTATION ANCHOR -->
+ <int>0xFFFA</int> <!-- INTERLINEAR ANNOTATION SEPARATOR -->
+ <int>0xFFFB</int> <!-- INTERLINEAR ANNOTATION TERMINATOR -->
+ </blank>
+<!--
+ Rescan configuration every 30 seconds when FcFontSetList is called
+ -->
+ <rescan>
+ <int>30</int>
+ </rescan>
+ </config>
+
+<!--
+ URW provides metric and shape compatible fonts for these 10 Adobe families.
+
+ However, these fonts are quite ugly and do not render well on-screen,
+ so we avoid matching them if the application said `anymetrics'; in that
+ case, a more generic font with different metrics but better appearance
+ will be used.
+ -->
+ <match target="pattern">
+ <test name="family">
+ <string>Avant Garde</string>
+ </test>
+ <test name="anymetrics" qual="all" compare="not_eq">
+ <bool>true</bool>
+ </test>
+ <edit name="family" mode="append">
+ <string>URW Gothic L</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test name="family">
+ <string>Bookman</string>
+ </test>
+ <test name="anymetrics" qual="all" compare="not_eq">
+ <bool>true</bool>
+ </test>
+ <edit name="family" mode="append">
+ <string>URW Bookman L</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test name="family">
+ <string>Courier</string>
+ </test>
+ <test name="anymetrics" qual="all" compare="not_eq">
+ <bool>true</bool>
+ </test>
+ <edit name="family" mode="append">
+ <string>Nimbus Mono L</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test name="family">
+ <string>Helvetica</string>
+ </test>
+ <test name="anymetrics" qual="all" compare="not_eq">
+ <bool>true</bool>
+ </test>
+ <edit name="family" mode="append">
+ <string>Nimbus Sans L</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test name="family">
+ <string>New Century Schoolbook</string>
+ </test>
+ <test name="anymetrics" qual="all" compare="not_eq">
+ <bool>true</bool>
+ </test>
+ <edit name="family" mode="append">
+ <string>Century Schoolbook L</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test name="family">
+ <string>Palatino</string>
+ </test>
+ <test name="anymetrics" qual="all" compare="not_eq">
+ <bool>true</bool>
+ </test>
+ <edit name="family" mode="append">
+ <string>URW Palladio L</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test name="family">
+ <string>Times</string>
+ </test>
+ <test name="anymetrics" qual="all" compare="not_eq">
+ <bool>true</bool>
+ </test>
+ <edit name="family" mode="append">
+ <string>Nimbus Roman No9 L</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test name="family">
+ <string>Zapf Chancery</string>
+ </test>
+ <test name="anymetrics" qual="all" compare="not_eq">
+ <bool>true</bool>
+ </test>
+ <edit name="family" mode="append">
+ <string>URW Chancery L</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test name="family">
+ <string>Zapf Dingbats</string>
+ </test>
+ <test name="anymetrics" qual="all" compare="not_eq">
+ <bool>true</bool>
+ </test>
+ <edit name="family" mode="append">
+ <string>Dingbats</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test name="family">
+ <string>Symbol</string>
+ </test>
+ <test name="anymetrics" qual="all" compare="not_eq">
+ <bool>true</bool>
+ </test>
+ <edit name="family" mode="append" binding="same">
+ <string>Standard Symbols L</string>
+ </edit>
+ </match>
+
+<!--
+ Serif faces
+ -->
+ <alias>
+ <family>Nimbus Roman No9 L</family>
+ <default><family>serif</family></default>
+ </alias>
+<!--
+ Sans-serif faces
+ -->
+ <alias>
+ <family>Nimbus Sans L</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+<!--
+ Monospace faces
+ -->
+ <alias>
+ <family>Nimbus Mono L</family>
+ <default><family>monospace</family></default>
+ </alias>
+
+
+</fontconfig>
diff --git a/WebKitTools/DumpRenderTree/qt/fonts/AHEM____.TTF b/WebKitTools/DumpRenderTree/qt/fonts/AHEM____.TTF
new file mode 100644
index 0000000..ac81cb0
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/qt/fonts/AHEM____.TTF
Binary files differ
diff --git a/WebKitTools/DumpRenderTree/qt/jsobjects.cpp b/WebKitTools/DumpRenderTree/qt/jsobjects.cpp
new file mode 100644
index 0000000..78a93fe
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/qt/jsobjects.cpp
@@ -0,0 +1,360 @@
+/*
+ * Copyright (C) 2006 Trolltech ASA
+ *
+ * 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 <jsobjects.h>
+#include <qwebpage.h>
+#include <qwebhistory.h>
+#include <qwebframe.h>
+#include <qevent.h>
+#include <qapplication.h>
+#include <qevent.h>
+
+#include "DumpRenderTree.h"
+extern void qt_dump_editing_callbacks(bool b);
+
+LayoutTestController::LayoutTestController(WebCore::DumpRenderTree *drt)
+ : QObject()
+ , m_drt(drt)
+{
+ m_timeoutTimer = 0;
+ reset();
+}
+
+void LayoutTestController::reset()
+{
+ m_isLoading = true;
+ m_textDump = false;
+ m_dumpChildrenAsText = false;
+ m_canOpenWindows = false;
+ m_waitForDone = false;
+ m_dumpTitleChanges = false;
+ if (m_timeoutTimer) {
+ killTimer(m_timeoutTimer);
+ m_timeoutTimer = 0;
+ }
+ m_topLoadingFrame = 0;
+ qt_dump_editing_callbacks(false);
+}
+
+void LayoutTestController::maybeDump(bool ok)
+{
+ QWebFrame *frame = qobject_cast<QWebFrame*>(sender());
+ if (frame != m_topLoadingFrame)
+ return;
+
+ m_topLoadingFrame = 0;
+
+ if (!shouldWaitUntilDone()) {
+ emit done();
+ m_isLoading = false;
+ }
+}
+
+void LayoutTestController::waitUntilDone()
+{
+ //qDebug() << ">>>>waitForDone";
+ m_waitForDone = true;
+ m_timeoutTimer = startTimer(11000);
+}
+
+void LayoutTestController::notifyDone()
+{
+ //qDebug() << ">>>>notifyDone";
+ if (!m_timeoutTimer)
+ return;
+ killTimer(m_timeoutTimer);
+ m_timeoutTimer = 0;
+ emit done();
+ m_isLoading = false;
+}
+
+int LayoutTestController::windowCount()
+{
+ return m_drt->windowCount();
+}
+
+void LayoutTestController::clearBackForwardList()
+{
+ m_drt->webPage()->history()->clear();
+}
+
+
+void LayoutTestController::dumpEditingCallbacks()
+{
+ qDebug() << ">>>dumpEditingCallbacks";
+ qt_dump_editing_callbacks(true);
+}
+
+void LayoutTestController::queueReload()
+{
+ //qDebug() << ">>>queueReload";
+}
+
+void LayoutTestController::provisionalLoad()
+{
+ QWebFrame *frame = qobject_cast<QWebFrame*>(sender());
+ if (!m_topLoadingFrame && m_isLoading)
+ m_topLoadingFrame = frame;
+}
+
+void LayoutTestController::timerEvent(QTimerEvent *)
+{
+ qDebug() << ">>>>>>>>>>>>> timeout";
+ notifyDone();
+}
+
+QString LayoutTestController::encodeHostName(const QString &host)
+{
+ QString encoded = QString::fromLatin1(QUrl::toAce(host + QLatin1String(".no")));
+ encoded.truncate(encoded.length() - 3); // strip .no
+ return encoded;
+}
+
+QString LayoutTestController::decodeHostName(const QString &host)
+{
+ QString decoded = QUrl::fromAce(host.toLatin1() + QByteArray(".no"));
+ decoded.truncate(decoded.length() - 3);
+ return decoded;
+}
+
+
+EventSender::EventSender(QWebPage *parent)
+ : QObject(parent)
+{
+ m_page = parent;
+}
+
+void EventSender::mouseDown()
+{
+// qDebug() << "EventSender::mouseDown" << frame;
+ QMouseEvent event(QEvent::MouseButtonPress, m_mousePos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
+ QApplication::sendEvent(m_page, &event);
+}
+
+void EventSender::mouseUp()
+{
+// qDebug() << "EventSender::mouseUp" << frame;
+ QMouseEvent event(QEvent::MouseButtonRelease, m_mousePos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
+ QApplication::sendEvent(m_page, &event);
+}
+
+void EventSender::mouseMoveTo(int x, int y)
+{
+// qDebug() << "EventSender::mouseMoveTo" << x << y;
+ m_mousePos = QPoint(x, y);
+ QMouseEvent event(QEvent::MouseMove, m_mousePos, Qt::NoButton, Qt::NoButton, Qt::NoModifier);
+ QApplication::sendEvent(m_page, &event);
+}
+
+void EventSender::leapForward(int ms)
+{
+ m_timeLeap += ms;
+ qDebug() << "EventSender::leapForward" << ms;
+}
+
+void EventSender::keyDown(const QString &string, const QStringList &modifiers)
+{
+ QString s = string;
+ Qt::KeyboardModifiers modifs = 0;
+ for (int i = 0; i < modifiers.size(); ++i) {
+ const QString &m = modifiers.at(i);
+ if (m == "ctrlKey")
+ modifs |= Qt::ControlModifier;
+ else if (m == "shiftKey")
+ modifs |= Qt::ShiftModifier;
+ else if (m == "altKey")
+ modifs |= Qt::AltModifier;
+ else if (m == "metaKey")
+ modifs |= Qt::MetaModifier;
+ }
+ int code = 0;
+ if (string.length() == 1) {
+ code = string.unicode()->unicode();
+ qDebug() << ">>>>>>>>> keyDown" << code << (char)code;
+ // map special keycodes used by the tests to something that works for Qt/X11
+ if (code == '\t') {
+ code = Qt::Key_Tab;
+ if (modifs == Qt::ShiftModifier)
+ code = Qt::Key_Backtab;
+ s = QString();
+ } else if (code == 127) {
+ code = Qt::Key_Backspace;
+ if (modifs == Qt::AltModifier)
+ modifs = Qt::ControlModifier;
+ s = QString();
+ } else if (code == 'o' && modifs == Qt::ControlModifier) {
+ s = QLatin1String("\n");
+ code = '\n';
+ modifs = 0;
+ } else if (code == 'y' && modifs == Qt::ControlModifier) {
+ s = QLatin1String("c");
+ code = 'c';
+ } else if (code == 'k' && modifs == Qt::ControlModifier) {
+ s = QLatin1String("x");
+ code = 'x';
+ } else if (code == 'a' && modifs == Qt::ControlModifier) {
+ s = QString();
+ code = Qt::Key_Home;
+ modifs = 0;
+ } else if (code == 0xf702) {
+ s = QString();
+ code = Qt::Key_Left;
+ if (modifs & Qt::MetaModifier) {
+ code = Qt::Key_Home;
+ modifs &= ~Qt::MetaModifier;
+ }
+ } else if (code == 0xf703) {
+ s = QString();
+ code = Qt::Key_Right;
+ if (modifs & Qt::MetaModifier) {
+ code = Qt::Key_End;
+ modifs &= ~Qt::MetaModifier;
+ }
+ } else if (code == 'a' && modifs == Qt::ControlModifier) {
+ s = QString();
+ code = Qt::Key_Home;
+ modifs = 0;
+ } else {
+ code = string.unicode()->toUpper().unicode();
+ }
+ }
+ QKeyEvent event(QEvent::KeyPress, code, modifs, s);
+ QApplication::sendEvent(m_page, &event);
+}
+
+QWebFrame *EventSender::frameUnderMouse() const
+{
+ QWebFrame *frame = m_page->mainFrame();
+
+redo:
+ QList<QWebFrame*> children = frame->childFrames();
+ for (int i = 0; i < children.size(); ++i) {
+ if (children.at(i)->geometry().contains(m_mousePos)) {
+ frame = children.at(i);
+ goto redo;
+ }
+ }
+ if (frame->geometry().contains(m_mousePos))
+ return frame;
+ return 0;
+}
+
+
+TextInputController::TextInputController(QWebPage *parent)
+ : QObject(parent)
+{
+}
+
+void TextInputController::doCommand(const QString &command)
+{
+ Qt::KeyboardModifiers modifiers = Qt::NoModifier;
+ int keycode = 0;
+ if (command == "moveBackwardAndModifySelection:") {
+ modifiers |= Qt::ShiftModifier;
+ keycode = Qt::Key_Left;
+ } else if(command =="moveDown:") {
+ keycode = Qt::Key_Down;
+ } else if(command =="moveDownAndModifySelection:") {
+ modifiers |= Qt::ShiftModifier;
+ keycode = Qt::Key_Down;
+ } else if(command =="moveForward:") {
+ keycode = Qt::Key_Right;
+ } else if(command =="moveForwardAndModifySelection:") {
+ modifiers |= Qt::ShiftModifier;
+ keycode = Qt::Key_Right;
+ } else if(command =="moveLeft:") {
+ keycode = Qt::Key_Left;
+ } else if(command =="moveLeftAndModifySelection:") {
+ modifiers |= Qt::ShiftModifier;
+ keycode = Qt::Key_Left;
+ } else if(command =="moveRight:") {
+ keycode = Qt::Key_Right;
+ } else if(command =="moveRightAndModifySelection:") {
+ modifiers |= Qt::ShiftModifier;
+ keycode = Qt::Key_Right;
+ } else if(command =="moveToBeginningOfDocument:") {
+ modifiers |= Qt::ControlModifier;
+ keycode = Qt::Key_Home;
+ } else if(command =="moveToBeginningOfLine:") {
+ keycode = Qt::Key_Home;
+// } else if(command =="moveToBeginningOfParagraph:") {
+ } else if(command =="moveToEndOfDocument:") {
+ modifiers |= Qt::ControlModifier;
+ keycode = Qt::Key_End;
+ } else if(command =="moveToEndOfLine:") {
+ keycode = Qt::Key_End;
+// } else if(command =="moveToEndOfParagraph:") {
+ } else if(command =="moveUp:") {
+ keycode = Qt::Key_Up;
+ } else if(command =="moveUpAndModifySelection:") {
+ modifiers |= Qt::ShiftModifier;
+ keycode = Qt::Key_Up;
+ } else if(command =="moveWordBackward:") {
+ modifiers |= Qt::ControlModifier;
+ keycode = Qt::Key_Up;
+ } else if(command =="moveWordBackwardAndModifySelection:") {
+ modifiers |= Qt::ShiftModifier;
+ modifiers |= Qt::ControlModifier;
+ keycode = Qt::Key_Left;
+ } else if(command =="moveWordForward:") {
+ modifiers |= Qt::ControlModifier;
+ keycode = Qt::Key_Right;
+ } else if(command =="moveWordForwardAndModifySelection:") {
+ modifiers |= Qt::ControlModifier;
+ modifiers |= Qt::ShiftModifier;
+ keycode = Qt::Key_Right;
+ } else if(command =="moveWordLeft:") {
+ modifiers |= Qt::ControlModifier;
+ keycode = Qt::Key_Left;
+ } else if(command =="moveWordRight:") {
+ modifiers |= Qt::ControlModifier;
+ keycode = Qt::Key_Left;
+ } else if(command =="moveWordRightAndModifySelection:") {
+ modifiers |= Qt::ShiftModifier;
+ modifiers |= Qt::ControlModifier;
+ keycode = Qt::Key_Right;
+ } else if(command =="moveWordLeftAndModifySelection:") {
+ modifiers |= Qt::ShiftModifier;
+ modifiers |= Qt::ControlModifier;
+ keycode = Qt::Key_Left;
+ } else if(command =="pageDown:") {
+ keycode = Qt::Key_PageDown;
+ } else if(command =="pageUp:") {
+ keycode = Qt::Key_PageUp;
+ } else if(command == "deleteWordBackward:") {
+ modifiers |= Qt::ControlModifier;
+ keycode = Qt::Key_Backspace;
+ } else if(command == "deleteBackward:") {
+ keycode = Qt::Key_Backspace;
+ } else if(command == "deleteForward:") {
+ keycode = Qt::Key_Delete;
+ }
+ QKeyEvent event(QEvent::KeyPress, keycode, modifiers);
+ QApplication::sendEvent(parent(), &event);
+ QKeyEvent event2(QEvent::KeyRelease, keycode, modifiers);
+ QApplication::sendEvent(parent(), &event2);
+}
diff --git a/WebKitTools/DumpRenderTree/qt/jsobjects.h b/WebKitTools/DumpRenderTree/qt/jsobjects.h
new file mode 100644
index 0000000..511e857
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/qt/jsobjects.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2006 Trolltech ASA
+ *
+ * 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 JSOBJECTS_H
+#define JSOBJECTS_H
+
+#include <qobject.h>
+#include <qdebug.h>
+#include <qpoint.h>
+#include <qstringlist.h>
+
+class QWebFrame;
+namespace WebCore {
+ class DumpRenderTree;
+}
+class LayoutTestController : public QObject
+{
+ Q_OBJECT
+public:
+ LayoutTestController(WebCore::DumpRenderTree *drt);
+
+ bool isLoading() const { return m_isLoading; }
+ void setLoading(bool loading) { m_isLoading = loading; }
+
+ bool shouldDumpAsText() const { return m_textDump; }
+ bool shouldDumpChildrenAsText() const { return m_dumpChildrenAsText; }
+ bool shouldWaitUntilDone() const { return m_waitForDone; }
+ bool canOpenWindows() const { return m_canOpenWindows; }
+ bool shouldDumpTitleChanges() const { return m_dumpTitleChanges; }
+
+ void reset();
+
+protected:
+ void timerEvent(QTimerEvent *);
+
+signals:
+ void done();
+
+public slots:
+ void maybeDump(bool ok);
+ void dumpAsText() { m_textDump = true; }
+ void dumpChildFramesAsText() { m_dumpChildrenAsText = true; }
+ void setCanOpenWindows() { m_canOpenWindows = true; }
+ void waitUntilDone();
+ void notifyDone();
+ void dumpEditingCallbacks();
+ void queueReload();
+ void provisionalLoad();
+ void setCloseRemainingWindowsWhenComplete(bool=false) {}
+ int windowCount();
+ void display() {}
+ void clearBackForwardList();
+ void dumpTitleChanges() { m_dumpTitleChanges = true; }
+ QString encodeHostName(const QString &host);
+ QString decodeHostName(const QString &host);
+ void dumpSelectionRect() const {}
+
+private:
+ bool m_isLoading;
+ bool m_textDump;
+ bool m_dumpChildrenAsText;
+ bool m_canOpenWindows;
+ bool m_waitForDone;
+ bool m_dumpTitleChanges;
+ int m_timeoutTimer;
+ QWebFrame *m_topLoadingFrame;
+ WebCore::DumpRenderTree *m_drt;
+};
+
+class QWebPage;
+class QWebFrame;
+
+class EventSender : public QObject
+{
+ Q_OBJECT
+public:
+ EventSender(QWebPage *parent);
+
+public slots:
+ void mouseDown();
+ void mouseUp();
+ void mouseMoveTo(int x, int y);
+ void leapForward(int ms);
+ void keyDown(const QString &string, const QStringList &modifiers=QStringList());
+ void clearKillRing() {}
+
+private:
+ QPoint m_mousePos;
+ QWebPage *m_page;
+ int m_timeLeap;
+ QWebFrame *frameUnderMouse() const;
+};
+
+class TextInputController : public QObject
+{
+ Q_OBJECT
+public:
+ TextInputController(QWebPage *parent);
+
+public slots:
+ void doCommand(const QString &command);
+// void setMarkedText(const QString &str, int from, int length);
+// bool hasMarkedText();
+// void unmarkText();
+// QList<int> markedRange();
+// QList<int> selectedRange();
+// void validAttributesForMarkedText();
+// void inserText(const QString &);
+// void firstRectForCharacterRange();
+// void characterIndexForPoint(int, int);
+// void substringFromRange(int, int);
+// void conversationIdentifier();
+};
+
+#endif
diff --git a/WebKitTools/DumpRenderTree/qt/main.cpp b/WebKitTools/DumpRenderTree/qt/main.cpp
new file mode 100644
index 0000000..dd4c0e9
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/qt/main.cpp
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2007 Trolltech ASA
+ *
+ * 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 "DumpRenderTree.h"
+#include "testplugin.h"
+
+#include <qstringlist.h>
+#include <qapplication.h>
+#include <qurl.h>
+#include <qdir.h>
+#include <qdebug.h>
+#include <qfont.h>
+
+#ifdef Q_WS_X11
+#include <qx11info_x11.h>
+#include <fontconfig/fontconfig.h>
+#endif
+
+#include <limits.h>
+#include <signal.h>
+
+#if defined(__GLIBC__)
+#include <execinfo.h>
+#endif
+
+#if QT_VERSION < 0x040400
+Q_IMPORT_PLUGIN(testplugin)
+#endif
+
+void messageHandler(QtMsgType type, const char *message)
+{
+ if (type == QtCriticalMsg) {
+ fprintf(stderr, "%s\n", message);
+ return;
+ }
+ // do nothing
+}
+
+QString get_backtrace() {
+ QString s;
+
+#if defined(__GLIBC__)
+ void* array[256];
+ size_t size; /* number of stack frames */
+
+ size = backtrace(array, 256);
+
+ if (!size)
+ return s;
+
+ char** strings = backtrace_symbols(array, size);
+ for (int i = 0; i < size; ++i) {
+ s += QString::number(i) +
+ QLatin1String(": ") +
+ QLatin1String(strings[i]) + QLatin1String("\n");
+ }
+
+ if (strings)
+ free (strings);
+#endif
+
+ return s;
+}
+
+static void crashHandler(int sig)
+{
+ fprintf(stderr, "%s\n", strsignal(sig));
+ fprintf(stderr, "%s\n", get_backtrace().toLatin1().constData());
+ exit(128 + sig);
+}
+
+int main(int argc, char* argv[])
+{
+#ifdef Q_WS_X11
+ FcInit();
+ FcConfig *config = FcConfigCreate();
+ QByteArray fontDir = getenv("WEBKIT_TESTFONTS");
+ if (fontDir.isEmpty() || !QDir(fontDir).exists()) {
+ fprintf(stderr,
+ "\n\n"
+ "--------------------------------------------------------------------\n"
+ "WEBKIT_TESTFONTS environment variable is not set correctly.\n"
+ "This variable has to point to the directory containing the fonts\n"
+ "you can checkout from svn://labs.trolltech.com/svn/webkit/testfonts\n"
+ "--------------------------------------------------------------------\n"
+);
+ exit(1);
+ }
+ char currentPath[PATH_MAX+1];
+ getcwd(currentPath, PATH_MAX);
+ QByteArray configFile = currentPath;
+ configFile += "/WebKitTools/DumpRenderTree/qt/fonts.conf";
+ if (!FcConfigParseAndLoad (config, (FcChar8*) configFile.data(), true))
+ qFatal("Couldn't load font configuration file");
+ if (!FcConfigAppFontAddDir (config, (FcChar8*) fontDir.data()))
+ qFatal("Couldn't add font dir!");
+ FcConfigSetCurrent(config);
+#endif
+ QApplication app(argc, argv);
+#ifdef Q_WS_X11
+ QX11Info::setAppDpiY(0, 96);
+ QX11Info::setAppDpiX(0, 96);
+#endif
+
+ QFont f("Sans Serif");
+ f.setPointSize(9);
+ f.setWeight(QFont::Normal);
+ f.setStyle(QFont::StyleNormal);
+ app.setFont(f);
+ app.setStyle(QLatin1String("Plastique"));
+
+
+ signal(SIGILL, crashHandler); /* 4: illegal instruction (not reset when caught) */
+ signal(SIGTRAP, crashHandler); /* 5: trace trap (not reset when caught) */
+ signal(SIGFPE, crashHandler); /* 8: floating point exception */
+ signal(SIGBUS, crashHandler); /* 10: bus error */
+ signal(SIGSEGV, crashHandler); /* 11: segmentation violation */
+ signal(SIGSYS, crashHandler); /* 12: bad argument to system call */
+ signal(SIGPIPE, crashHandler); /* 13: write on a pipe with no reader */
+ signal(SIGXCPU, crashHandler); /* 24: exceeded CPU time limit */
+ signal(SIGXFSZ, crashHandler); /* 25: exceeded file size limit */
+
+ QStringList args = app.arguments();
+ if (args.count() < 2) {
+ qDebug() << "Usage: DumpRenderTree [-v] filename";
+ exit(0);
+ }
+
+ // supress debug output from Qt if not started with -v
+ if (!args.contains(QLatin1String("-v")))
+ qInstallMsgHandler(messageHandler);
+
+ WebCore::DumpRenderTree dumper;
+
+ if (args.last() == QLatin1String("-")) {
+ dumper.open();
+ } else {
+ if (!args.last().startsWith("/")
+ && !args.last().startsWith("file:")) {
+ QString path = QDir::currentPath();
+ if (!path.endsWith('/'))
+ path.append('/');
+ args.last().prepend(path);
+ }
+ dumper.open(QUrl(args.last()));
+ }
+ return app.exec();
+#ifdef Q_WS_X11
+ FcConfigSetCurrent(0);
+#endif
+}
diff --git a/WebKitTools/DumpRenderTree/qt/testplugin.cpp b/WebKitTools/DumpRenderTree/qt/testplugin.cpp
new file mode 100644
index 0000000..27558c9
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/qt/testplugin.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2007 Trolltech ASA
+ *
+ * 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 "testplugin.h"
+
+#if QT_VERSION < 0x040400
+
+TestPlugin::TestPlugin(QObject *parent)
+ : QWebObjectPlugin(parent)
+{
+}
+
+TestPlugin::~TestPlugin()
+{
+}
+
+QStringList TestPlugin::keys() const
+{
+ return QStringList(QLatin1String("testplugin"));
+}
+
+QString TestPlugin::descriptionForKey(const QString &) const
+{
+ return QLatin1String("testdescription");
+}
+
+QStringList TestPlugin::mimetypesForKey(const QString &) const
+{
+ return QStringList(QLatin1String("testtype"));
+}
+
+QStringList TestPlugin::extensionsForMimetype(const QString &) const
+{
+ return QStringList(QLatin1String("testsuffixes"));
+}
+
+QObject *TestPlugin::create(QWebObjectPluginConnector *,
+ const QUrl &,
+ const QString &,
+ const QStringList &,
+ const QStringList &) const
+{
+ return 0;
+}
+
+Q_EXPORT_PLUGIN2(testplugin, TestPlugin)
+#endif
diff --git a/WebKitTools/DumpRenderTree/qt/testplugin.h b/WebKitTools/DumpRenderTree/qt/testplugin.h
new file mode 100644
index 0000000..e305069
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/qt/testplugin.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2007 Trolltech ASA
+ *
+ * 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 <qglobal.h>
+#if QT_VERSION < 0x040400
+#define QT_STATICPLUGIN
+#include <qwebobjectplugin.h>
+
+
+class TestPlugin : public QWebObjectPlugin
+{
+public:
+ explicit TestPlugin(QObject *parent = 0);
+ virtual ~TestPlugin();
+
+ virtual QStringList keys() const;
+
+ virtual QString descriptionForKey(const QString &key) const;
+ virtual QStringList mimetypesForKey(const QString &key) const;
+ virtual QStringList extensionsForMimetype(const QString &mimeType) const;
+ virtual QObject *create(QWebObjectPluginConnector *connector,
+ const QUrl &url,
+ const QString &mimeType,
+ const QStringList &argumentNames,
+ const QStringList &argumentValues) const;
+};
+
+#endif
diff --git a/WebKitTools/DumpRenderTree/win/DraggingInfo.h b/WebKitTools/DumpRenderTree/win/DraggingInfo.h
new file mode 100644
index 0000000..2ead457
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/DraggingInfo.h
@@ -0,0 +1,62 @@
+/*
+ * 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 DraggingInfo_h
+#define DraggingInfo_h
+
+#include <objidl.h>
+
+class DraggingInfo {
+public:
+ DraggingInfo(IDataObject* object, IDropSource* source)
+ : m_object(object)
+ , m_source(source)
+ {
+ m_object->AddRef();
+ m_source->AddRef();
+ }
+
+ ~DraggingInfo()
+ {
+ if (m_object)
+ m_object->Release();
+ m_object = 0;
+ if (m_source)
+ m_source->Release();
+ m_source = 0;
+ }
+
+ IDataObject* dataObject() const { return m_object; }
+ IDropSource* dropSource() const { return m_source; }
+
+private:
+ IDataObject* m_object;
+ IDropSource* m_source;
+};
+
+#endif // !defined(DraggingInfo_h)
diff --git a/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp b/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp
new file mode 100644
index 0000000..bf08ff2
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp
@@ -0,0 +1,1103 @@
+/*
+ * Copyright (C) 2005, 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.
+ * 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 "DumpRenderTree.h"
+
+#include "EditingDelegate.h"
+#include "FrameLoadDelegate.h"
+#include "LayoutTestController.h"
+#include "PixelDumpSupport.h"
+#include "PolicyDelegate.h"
+#include "ResourceLoadDelegate.h"
+#include "UIDelegate.h"
+#include "WorkQueueItem.h"
+#include "WorkQueue.h"
+#include <wtf/RetainPtr.h>
+#include <wtf/Vector.h>
+#include <WebCore/COMPtr.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <CFNetwork/CFURLCachePriv.h>
+#include <JavaScriptCore/JavaScriptCore.h>
+#include <math.h>
+#include <pthread.h>
+#include <string>
+#include <tchar.h>
+#include <WebKit/WebKit.h>
+#include <fcntl.h>
+#include <io.h>
+#include <windows.h>
+#include <stdio.h>
+#include <shlwapi.h>
+
+using std::wstring;
+
+#ifndef NDEBUG
+const LPWSTR TestPluginDir = L"TestNetscapePlugin_Debug";
+#else
+const LPWSTR TestPluginDir = L"TestNetscapePlugin";
+#endif
+
+static LPCWSTR fontsEnvironmentVariable = L"WEBKIT_TESTFONTS";
+#define USE_MAC_FONTS
+
+const LPCWSTR kDumpRenderTreeClassName = L"DumpRenderTreeWindow";
+
+static bool dumpTree = true;
+static bool dumpPixels;
+static bool dumpAllPixels;
+static bool printSeparators;
+static bool leakChecking = false;
+static bool timedOut = false;
+static bool threaded = false;
+static RetainPtr<CFStringRef> persistentUserStyleSheetLocation;
+
+static const char* currentTest;
+
+volatile bool done;
+// This is the topmost frame that is loading, during a given load, or nil when no load is
+// in progress. Usually this is the same as the main frame, but not always. In the case
+// where a frameset is loaded, and then new content is loaded into one of the child frames,
+// that child frame is the "topmost frame that is loading".
+IWebFrame* topLoadingFrame; // !nil iff a load is in progress
+static COMPtr<IWebHistoryItem> prevTestBFItem; // current b/f item at the end of the previous test
+IWebPolicyDelegate* policyDelegate;
+COMPtr<FrameLoadDelegate> sharedFrameLoadDelegate;
+COMPtr<UIDelegate> sharedUIDelegate;
+COMPtr<EditingDelegate> sharedEditingDelegate;
+COMPtr<ResourceLoadDelegate> sharedResourceLoadDelegate;
+
+IWebFrame* frame;
+HWND webViewWindow;
+
+LayoutTestController* layoutTestController = 0;
+CFRunLoopTimerRef waitToDumpWatchdog = 0;
+
+static const unsigned timeoutValue = 60000;
+static const unsigned timeoutId = 10;
+
+const unsigned maxViewWidth = 800;
+const unsigned maxViewHeight = 600;
+
+void setPersistentUserStyleSheetLocation(CFStringRef url)
+{
+ persistentUserStyleSheetLocation = url;
+}
+
+wstring urlSuitableForTestResult(const wstring& url)
+{
+ if (!url.c_str() || url.find(L"file://") == wstring::npos)
+ return url;
+
+ return PathFindFileNameW(url.c_str());
+}
+
+static LRESULT CALLBACK DumpRenderTreeWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_TIMER:
+ // The test ran long enough to time out
+ timedOut = true;
+ PostQuitMessage(0);
+ return 0;
+ break;
+ case WM_DESTROY:
+ for (unsigned i = openWindows().size() - 1; i >= 0; --i) {
+ if (openWindows()[i] == hWnd) {
+ openWindows().remove(i);
+ windowToWebViewMap().remove(hWnd);
+ break;
+ }
+ }
+ return 0;
+ break;
+ default:
+ return DefWindowProc(hWnd, msg, wParam, lParam);
+ }
+}
+
+static const wstring& exePath()
+{
+ static wstring path;
+ static bool initialized;
+
+ if (initialized)
+ return path;
+ initialized = true;
+
+ TCHAR buffer[MAX_PATH];
+ GetModuleFileName(GetModuleHandle(0), buffer, ARRAYSIZE(buffer));
+ path = buffer;
+ int lastSlash = path.rfind('\\');
+ if (lastSlash != -1 && lastSlash + 1 < path.length())
+ path = path.substr(0, lastSlash + 1);
+
+ return path;
+}
+
+static const wstring& fontsPath()
+{
+ static wstring path;
+ static bool initialized;
+
+ if (initialized)
+ return path;
+ initialized = true;
+
+ DWORD size = GetEnvironmentVariable(fontsEnvironmentVariable, 0, 0);
+ Vector<TCHAR> buffer(size);
+ if (GetEnvironmentVariable(fontsEnvironmentVariable, buffer.data(), buffer.size())) {
+ path = buffer.data();
+ if (path[path.length() - 1] != '\\')
+ path.append(L"\\");
+ return path;
+ }
+
+ path = exePath() + TEXT("DumpRenderTree.resources\\");
+ return path;
+}
+
+#ifdef DEBUG_WEBKIT_HAS_SUFFIX
+#define WEBKITDLL TEXT("WebKit_debug.dll")
+#else
+#define WEBKITDLL TEXT("WebKit.dll")
+#endif
+
+static void initialize()
+{
+ if (HMODULE webKitModule = LoadLibrary(WEBKITDLL))
+ if (FARPROC dllRegisterServer = GetProcAddress(webKitModule, "DllRegisterServer"))
+ dllRegisterServer();
+
+ // Init COM
+ OleInitialize(0);
+
+ static LPCTSTR fontsToInstall[] = {
+ TEXT("AHEM____.ttf"),
+ TEXT("Apple Chancery.ttf"),
+ TEXT("Courier Bold.ttf"),
+ TEXT("Courier.ttf"),
+ TEXT("Helvetica Bold Oblique.ttf"),
+ TEXT("Helvetica Bold.ttf"),
+ TEXT("Helvetica Oblique.ttf"),
+ TEXT("Helvetica.ttf"),
+ TEXT("Helvetica Neue Bold Italic.ttf"),
+ TEXT("Helvetica Neue Bold.ttf"),
+ TEXT("Helvetica Neue Condensed Black.ttf"),
+ TEXT("Helvetica Neue Condensed Bold.ttf"),
+ TEXT("Helvetica Neue Italic.ttf"),
+ TEXT("Helvetica Neue Light Italic.ttf"),
+ TEXT("Helvetica Neue Light.ttf"),
+ TEXT("Helvetica Neue UltraLight Italic.ttf"),
+ TEXT("Helvetica Neue UltraLight.ttf"),
+ TEXT("Helvetica Neue.ttf"),
+ TEXT("Lucida Grande.ttf"),
+ TEXT("Lucida Grande Bold.ttf"),
+ TEXT("Monaco.ttf"),
+ TEXT("Papyrus.ttf"),
+ TEXT("Times Bold Italic.ttf"),
+ TEXT("Times Bold.ttf"),
+ TEXT("Times Italic.ttf"),
+ TEXT("Times Roman.ttf"),
+ TEXT("WebKit Layout Tests.ttf")
+ };
+
+ wstring resourcesPath = fontsPath();
+
+ COMPtr<IWebTextRenderer> textRenderer;
+ if (SUCCEEDED(CoCreateInstance(CLSID_WebTextRenderer, 0, CLSCTX_ALL, IID_IWebTextRenderer, (void**)&textRenderer)))
+ for (int i = 0; i < ARRAYSIZE(fontsToInstall); ++i)
+ textRenderer->registerPrivateFont(wstring(resourcesPath + fontsToInstall[i]).c_str());
+
+ // Register a host window
+ WNDCLASSEX wcex;
+
+ wcex.cbSize = sizeof(WNDCLASSEX);
+
+ wcex.style = CS_HREDRAW | CS_VREDRAW;
+ wcex.lpfnWndProc = DumpRenderTreeWndProc;
+ wcex.cbClsExtra = 0;
+ wcex.cbWndExtra = 0;
+ wcex.hInstance = GetModuleHandle(0);
+ wcex.hIcon = 0;
+ wcex.hCursor = LoadCursor(0, IDC_ARROW);
+ wcex.hbrBackground = 0;
+ wcex.lpszMenuName = 0;
+ wcex.lpszClassName = kDumpRenderTreeClassName;
+ wcex.hIconSm = 0;
+
+ RegisterClassEx(&wcex);
+}
+
+void displayWebView()
+{
+ ::InvalidateRect(webViewWindow, 0, TRUE);
+ ::UpdateWindow(webViewWindow);
+}
+
+void dumpFrameScrollPosition(IWebFrame* frame)
+{
+ if (!frame)
+ return;
+
+ COMPtr<IWebFramePrivate> framePrivate;
+ if (FAILED(frame->QueryInterface(&framePrivate)))
+ return;
+
+ SIZE scrollPosition;
+ if (FAILED(framePrivate->scrollOffset(&scrollPosition)))
+ return;
+
+ if (abs(scrollPosition.cx) > 0.00000001 || abs(scrollPosition.cy) > 0.00000001) {
+ COMPtr<IWebFrame> parent;
+ if (FAILED(frame->parentFrame(&parent)))
+ return;
+ if (parent) {
+ BSTR name;
+ if (FAILED(frame->name(&name)))
+ return;
+ printf("frame '%S' ", name ? name : L"");
+ SysFreeString(name);
+ }
+ printf("scrolled to %.f,%.f\n", (double)scrollPosition.cx, (double)scrollPosition.cy);
+ }
+
+ if (::layoutTestController->dumpChildFrameScrollPositions()) {
+ COMPtr<IEnumVARIANT> enumKids;
+ if (FAILED(frame->childFrames(&enumKids)))
+ return;
+ VARIANT var;
+ VariantInit(&var);
+ while (enumKids->Next(1, &var, 0) == S_OK) {
+ ASSERT(V_VT(&var) == VT_UNKNOWN);
+ COMPtr<IWebFrame> framePtr;
+ V_UNKNOWN(&var)->QueryInterface(IID_IWebFrame, (void**)&framePtr);
+ dumpFrameScrollPosition(framePtr.get());
+ VariantClear(&var);
+ }
+ }
+}
+
+static wstring dumpFramesAsText(IWebFrame* frame)
+{
+ if (!frame)
+ return L"";
+
+ COMPtr<IDOMDocument> document;
+ if (FAILED(frame->DOMDocument(&document)))
+ return L"";
+
+ COMPtr<IDOMElement> documentElement;
+ if (FAILED(document->documentElement(&documentElement)))
+ return L"";
+
+ wstring result;
+
+ // Add header for all but the main frame.
+ COMPtr<IWebFrame> parent;
+ if (FAILED(frame->parentFrame(&parent)))
+ return L"";
+ if (parent) {
+ BSTR name = L"";
+ if (FAILED(frame->name(&name)))
+ return L"";
+
+ result.append(L"\n--------\nFrame: '");
+ result.append(name ? name : L"", SysStringLen(name));
+ result.append(L"'\n--------\n");
+
+ SysFreeString(name);
+ }
+
+ BSTR innerText = 0;
+ COMPtr<IDOMElementPrivate> docPrivate;
+ if (SUCCEEDED(documentElement->QueryInterface(&docPrivate)))
+ docPrivate->innerText(&innerText);
+
+ result.append(innerText ? innerText : L"", SysStringLen(innerText));
+ result.append(L"\n");
+
+ SysFreeString(innerText);
+
+ if (::layoutTestController->dumpChildFramesAsText()) {
+ COMPtr<IEnumVARIANT> enumKids;
+ if (FAILED(frame->childFrames(&enumKids)))
+ return L"";
+ VARIANT var;
+ VariantInit(&var);
+ while (enumKids->Next(1, &var, 0) == S_OK) {
+ ASSERT(V_VT(&var) == VT_UNKNOWN);
+ COMPtr<IWebFrame> framePtr;
+ V_UNKNOWN(&var)->QueryInterface(IID_IWebFrame, (void**)&framePtr);
+ result.append(dumpFramesAsText(framePtr.get()));
+ VariantClear(&var);
+ }
+ }
+
+ return result;
+}
+
+static int compareHistoryItems(const void* item1, const void* item2)
+{
+ COMPtr<IWebHistoryItemPrivate> itemA;
+ if (FAILED((*(COMPtr<IUnknown>*)item1)->QueryInterface(&itemA)))
+ return 0;
+
+ COMPtr<IWebHistoryItemPrivate> itemB;
+ if (FAILED((*(COMPtr<IUnknown>*)item2)->QueryInterface(&itemB)))
+ return 0;
+
+ BSTR targetA;
+ if (FAILED(itemA->target(&targetA)))
+ return 0;
+
+ BSTR targetB;
+ if (FAILED(itemB->target(&targetB))) {
+ SysFreeString(targetA);
+ return 0;
+ }
+
+ int result = wcsicmp(wstring(targetA, SysStringLen(targetA)).c_str(), wstring(targetB, SysStringLen(targetB)).c_str());
+ SysFreeString(targetA);
+ SysFreeString(targetB);
+ return result;
+}
+
+static void dumpHistoryItem(IWebHistoryItem* item, int indent, bool current)
+{
+ assert(item);
+
+ int start = 0;
+ if (current) {
+ printf("curr->");
+ start = 6;
+ }
+ for (int i = start; i < indent; i++)
+ putchar(' ');
+
+ BSTR url;
+ if (FAILED(item->URLString(&url)))
+ return;
+ printf("%S", url ? url : L"");
+ SysFreeString(url);
+
+ COMPtr<IWebHistoryItemPrivate> itemPrivate;
+ if (FAILED(item->QueryInterface(&itemPrivate)))
+ return;
+
+ BSTR target;
+ if (FAILED(itemPrivate->target(&target)))
+ return;
+ if (SysStringLen(target))
+ printf(" (in frame \"%S\")", target);
+ SysFreeString(target);
+ BOOL isTargetItem = FALSE;
+ if (FAILED(itemPrivate->isTargetItem(&isTargetItem)))
+ return;
+ if (isTargetItem)
+ printf(" **nav target**");
+ putchar('\n');
+
+ unsigned kidsCount;
+ SAFEARRAY* arrPtr;
+ if (FAILED(itemPrivate->children(&kidsCount, &arrPtr)) || !kidsCount)
+ return;
+
+ Vector<COMPtr<IUnknown> > kidsVector;
+
+ LONG lowerBound;
+ if (FAILED(::SafeArrayGetLBound(arrPtr, 1, &lowerBound)))
+ goto exit;
+
+ LONG upperBound;
+ if (FAILED(::SafeArrayGetUBound(arrPtr, 1, &upperBound)))
+ goto exit;
+
+ LONG length = upperBound - lowerBound + 1;
+ if (!length)
+ goto exit;
+ ASSERT(length == kidsCount);
+
+ IUnknown** safeArrayData;
+ if (FAILED(::SafeArrayAccessData(arrPtr, (void**)&safeArrayData)))
+ goto exit;
+
+ for (int i = 0; i < length; ++i)
+ kidsVector.append(safeArrayData[i]);
+ ::SafeArrayUnaccessData(arrPtr);
+
+ // must sort to eliminate arbitrary result ordering which defeats reproducible testing
+ qsort(kidsVector.data(), kidsCount, sizeof(kidsVector[0]), compareHistoryItems);
+
+ for (unsigned i = 0; i < kidsCount; ++i) {
+ COMPtr<IWebHistoryItem> item;
+ kidsVector[i]->QueryInterface(&item);
+ dumpHistoryItem(item.get(), indent + 4, false);
+ }
+
+exit:
+ if (arrPtr && SUCCEEDED(::SafeArrayUnlock(arrPtr)))
+ ::SafeArrayDestroy(arrPtr);
+}
+
+static void dumpBackForwardList(IWebView* webView)
+{
+ ASSERT(webView);
+
+ printf("\n============== Back Forward List ==============\n");
+
+ COMPtr<IWebBackForwardList> bfList;
+ if (FAILED(webView->backForwardList(&bfList)))
+ return;
+
+ // Print out all items in the list after prevTestBFItem, which was from the previous test
+ // Gather items from the end of the list, the print them out from oldest to newest
+
+ Vector<COMPtr<IUnknown> > itemsToPrint;
+
+ int forwardListCount;
+ if (FAILED(bfList->forwardListCount(&forwardListCount)))
+ return;
+
+ for (int i = forwardListCount; i > 0; --i) {
+ COMPtr<IWebHistoryItem> item;
+ if (FAILED(bfList->itemAtIndex(i, &item)))
+ return;
+ // something is wrong if the item from the last test is in the forward part of the b/f list
+ assert(item != prevTestBFItem);
+ COMPtr<IUnknown> itemUnknown;
+ item->QueryInterface(&itemUnknown);
+ itemsToPrint.append(itemUnknown);
+ }
+
+ COMPtr<IWebHistoryItem> currentItem;
+ if (FAILED(bfList->currentItem(&currentItem)))
+ return;
+
+ assert(currentItem != prevTestBFItem);
+ COMPtr<IUnknown> currentItemUnknown;
+ currentItem->QueryInterface(&currentItemUnknown);
+ itemsToPrint.append(currentItemUnknown);
+ int currentItemIndex = itemsToPrint.size() - 1;
+
+ int backListCount;
+ if (FAILED(bfList->backListCount(&backListCount)))
+ return;
+
+ for (int i = -1; i >= -backListCount; --i) {
+ COMPtr<IWebHistoryItem> item;
+ if (FAILED(bfList->itemAtIndex(i, &item)))
+ return;
+ if (item == prevTestBFItem)
+ break;
+ COMPtr<IUnknown> itemUnknown;
+ item->QueryInterface(&itemUnknown);
+ itemsToPrint.append(itemUnknown);
+ }
+
+ for (int i = itemsToPrint.size() - 1; i >= 0; --i) {
+ COMPtr<IWebHistoryItem> historyItemToPrint;
+ itemsToPrint[i]->QueryInterface(&historyItemToPrint);
+ dumpHistoryItem(historyItemToPrint.get(), 8, i == currentItemIndex);
+ }
+
+ printf("===============================================\n");
+}
+
+static void dumpBackForwardListForAllWindows()
+{
+ unsigned count = openWindows().size();
+ for (unsigned i = 0; i < count; i++) {
+ HWND window = openWindows()[i];
+ IWebView* webView = windowToWebViewMap().get(window);
+ dumpBackForwardList(webView);
+ }
+}
+
+void dump()
+{
+ COMPtr<IWebDataSource> dataSource;
+ if (SUCCEEDED(frame->dataSource(&dataSource))) {
+ COMPtr<IWebURLResponse> response;
+ if (SUCCEEDED(dataSource->response(&response)) && response) {
+ BSTR mimeType;
+ if (SUCCEEDED(response->MIMEType(&mimeType)))
+ ::layoutTestController->setDumpAsText(::layoutTestController->dumpAsText() | !_tcscmp(mimeType, TEXT("text/plain")));
+ SysFreeString(mimeType);
+ }
+ }
+
+ BSTR resultString = 0;
+
+ if (dumpTree) {
+ if (::layoutTestController->dumpAsText()) {
+ ::InvalidateRect(webViewWindow, 0, TRUE);
+ ::SendMessage(webViewWindow, WM_PAINT, 0, 0);
+ wstring result = dumpFramesAsText(frame);
+ resultString = SysAllocStringLen(result.data(), result.size());
+ } else {
+ bool isSVGW3CTest = strstr(currentTest, "svg\\W3C-SVG-1.1");
+ unsigned width;
+ unsigned height;
+ if (isSVGW3CTest) {
+ width = 480;
+ height = 360;
+ } else {
+ width = maxViewWidth;
+ height = maxViewHeight;
+ }
+
+ ::SetWindowPos(webViewWindow, 0, 0, 0, width, height, SWP_NOMOVE);
+ ::InvalidateRect(webViewWindow, 0, TRUE);
+ ::SendMessage(webViewWindow, WM_PAINT, 0, 0);
+
+ COMPtr<IWebFramePrivate> framePrivate;
+ if (FAILED(frame->QueryInterface(&framePrivate)))
+ goto fail;
+ framePrivate->renderTreeAsExternalRepresentation(&resultString);
+ }
+
+ if (!resultString)
+ printf("ERROR: nil result from %s", ::layoutTestController->dumpAsText() ? "IDOMElement::innerText" : "IFrameViewPrivate::renderTreeAsExternalRepresentation");
+ else {
+ unsigned stringLength = SysStringLen(resultString);
+ int bufferSize = ::WideCharToMultiByte(CP_UTF8, 0, resultString, stringLength, 0, 0, 0, 0);
+ char* buffer = (char*)malloc(bufferSize + 1);
+ ::WideCharToMultiByte(CP_UTF8, 0, resultString, stringLength, buffer, bufferSize + 1, 0, 0);
+ fwrite(buffer, 1, bufferSize, stdout);
+ free(buffer);
+ if (!::layoutTestController->dumpAsText())
+ dumpFrameScrollPosition(frame);
+ }
+ if (::layoutTestController->dumpBackForwardList())
+ dumpBackForwardListForAllWindows();
+ }
+
+ if (printSeparators)
+ puts("#EOF");
+
+ if (dumpPixels) {
+ if (layoutTestController->dumpAsText() || layoutTestController->dumpDOMAsWebArchive() || layoutTestController->dumpSourceAsWebArchive())
+ printf("#EOF\n");
+ else
+ dumpWebViewAsPixelsAndCompareWithExpected(currentTest, dumpAllPixels);
+ }
+
+fail:
+ SysFreeString(resultString);
+ // This will exit from our message loop
+ PostQuitMessage(0);
+ done = true;
+}
+
+static bool shouldLogFrameLoadDelegates(const char* pathOrURL)
+{
+ return strstr(pathOrURL, "loading/");
+}
+
+static void resetWebViewToConsistentStateBeforeTesting()
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ webView->setPolicyDelegate(0);
+
+ COMPtr<IWebIBActions> webIBActions(Query, webView);
+ if (webIBActions)
+ webIBActions->makeTextStandardSize(0);
+
+ COMPtr<IWebPreferences> preferences;
+ if (SUCCEEDED(webView->preferences(&preferences))) {
+ preferences->setPrivateBrowsingEnabled(FALSE);
+ preferences->setJavaScriptCanOpenWindowsAutomatically(TRUE);
+
+ if (persistentUserStyleSheetLocation) {
+ Vector<wchar_t> urlCharacters(CFStringGetLength(persistentUserStyleSheetLocation.get()));
+ CFStringGetCharacters(persistentUserStyleSheetLocation.get(), CFRangeMake(0, CFStringGetLength(persistentUserStyleSheetLocation.get())), (UniChar *)urlCharacters.data());
+ BSTR url = SysAllocStringLen(urlCharacters.data(), urlCharacters.size());
+ preferences->setUserStyleSheetLocation(url);
+ SysFreeString(url);
+ preferences->setUserStyleSheetEnabled(TRUE);
+ } else
+ preferences->setUserStyleSheetEnabled(FALSE);
+
+ COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences);
+ if (prefsPrivate)
+ prefsPrivate->setAuthorAndUserStylesEnabled(TRUE);
+ }
+
+ COMPtr<IWebViewPrivate> webViewPrivate(Query, webView);
+ if (!webViewPrivate)
+ return;
+
+ HWND viewWindow;
+ if (SUCCEEDED(webViewPrivate->viewWindow(reinterpret_cast<OLE_HANDLE*>(&viewWindow))) && viewWindow)
+ SetFocus(viewWindow);
+}
+
+static void runTest(const char* pathOrURL)
+{
+ static BSTR methodBStr = SysAllocString(TEXT("GET"));
+
+ BSTR urlBStr;
+
+ CFStringRef str = CFStringCreateWithCString(0, pathOrURL, kCFStringEncodingWindowsLatin1);
+ CFURLRef url = CFURLCreateWithString(0, str, 0);
+
+ if (!url)
+ url = CFURLCreateWithFileSystemPath(0, str, kCFURLWindowsPathStyle, false);
+
+ CFRelease(str);
+
+ str = CFURLGetString(url);
+
+ CFIndex length = CFStringGetLength(str);
+ UniChar* buffer = new UniChar[length];
+
+ CFStringGetCharacters(str, CFRangeMake(0, length), buffer);
+ urlBStr = SysAllocStringLen((OLECHAR*)buffer, length);
+ delete[] buffer;
+
+ CFRelease(url);
+
+ currentTest = pathOrURL;
+
+ ::layoutTestController = new LayoutTestController(false, false);
+ done = false;
+ topLoadingFrame = 0;
+ timedOut = false;
+
+ if (shouldLogFrameLoadDelegates(pathOrURL))
+ layoutTestController->setDumpFrameLoadCallbacks(true);
+
+ COMPtr<IWebHistory> history(Create, CLSID_WebHistory);
+ if (history)
+ history->setOptionalSharedHistory(0);
+
+ resetWebViewToConsistentStateBeforeTesting();
+ sharedUIDelegate->resetUndoManager();
+
+ prevTestBFItem = 0;
+ COMPtr<IWebView> webView;
+ if (SUCCEEDED(frame->webView(&webView))) {
+ COMPtr<IWebBackForwardList> bfList;
+ if (SUCCEEDED(webView->backForwardList(&bfList)))
+ bfList->currentItem(&prevTestBFItem);
+ }
+
+ WorkQueue::shared()->clear();
+ WorkQueue::shared()->setFrozen(false);
+
+ HWND hostWindow;
+ webView->hostWindow(reinterpret_cast<OLE_HANDLE*>(&hostWindow));
+
+ // Set the test timeout timer
+ SetTimer(hostWindow, timeoutId, timeoutValue, 0);
+
+ COMPtr<IWebMutableURLRequest> request;
+ HRESULT hr = CoCreateInstance(CLSID_WebMutableURLRequest, 0, CLSCTX_ALL, IID_IWebMutableURLRequest, (void**)&request);
+ if (FAILED(hr))
+ goto exit;
+
+ request->initWithURL(urlBStr, WebURLRequestUseProtocolCachePolicy, 60);
+
+ request->setHTTPMethod(methodBStr);
+ frame->loadRequest(request.get());
+
+ MSG msg;
+ while (GetMessage(&msg, 0, 0, 0)) {
+ // We get spurious WM_MOUSELEAVE events which make event handling machinery think that mouse button
+ // is released during dragging (see e.g. fast\dynamic\layer-hit-test-crash.html).
+ // Mouse can never leave WebView during normal DumpRenderTree operation, so we just ignore all such events.
+ if (msg.message == WM_MOUSELEAVE)
+ continue;
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ KillTimer(hostWindow, timeoutId);
+
+ if (timedOut) {
+ fprintf(stderr, "ERROR: Timed out running %s\n", pathOrURL);
+ printf("ERROR: Timed out loading page\n");
+
+ if (printSeparators)
+ puts("#EOF");
+ }
+
+ frame->stopLoading();
+
+ if (::layoutTestController->closeRemainingWindowsWhenComplete()) {
+ Vector<HWND> windows = openWindows();
+ unsigned size = windows.size();
+ for (unsigned i = 0; i < size; i++) {
+ HWND window = windows[i];
+
+ // Don't try to close the main window
+ if (window == hostWindow)
+ continue;
+
+ DestroyWindow(window);
+ }
+ }
+
+exit:
+ SysFreeString(urlBStr);
+ delete ::layoutTestController;
+
+ return;
+}
+
+static void initializePreferences(IWebPreferences* preferences)
+{
+#ifdef USE_MAC_FONTS
+ BSTR standardFamily = SysAllocString(TEXT("Times"));
+ BSTR fixedFamily = SysAllocString(TEXT("Courier"));
+ BSTR sansSerifFamily = SysAllocString(TEXT("Helvetica"));
+ BSTR cursiveFamily = SysAllocString(TEXT("Apple Chancery"));
+ BSTR fantasyFamily = SysAllocString(TEXT("Papyrus"));
+#else
+ BSTR standardFamily = SysAllocString(TEXT("Times New Roman"));
+ BSTR fixedFamily = SysAllocString(TEXT("Courier New"));
+ BSTR sansSerifFamily = SysAllocString(TEXT("Arial"));
+ BSTR cursiveFamily = SysAllocString(TEXT("Comic Sans MS")); // Not actually cursive, but it's what IE and Firefox use.
+ BSTR fantasyFamily = SysAllocString(TEXT("Times New Roman"));
+#endif
+
+ preferences->setStandardFontFamily(standardFamily);
+ preferences->setFixedFontFamily(fixedFamily);
+ preferences->setSerifFontFamily(standardFamily);
+ preferences->setSansSerifFontFamily(sansSerifFamily);
+ preferences->setCursiveFontFamily(cursiveFamily);
+ preferences->setFantasyFontFamily(fantasyFamily);
+
+ preferences->setAutosaves(FALSE);
+ preferences->setJavaEnabled(FALSE);
+ preferences->setPlugInsEnabled(TRUE);
+ preferences->setDOMPasteAllowed(TRUE);
+ preferences->setEditableLinkBehavior(WebKitEditableLinkOnlyLiveWithShiftKey);
+ preferences->setFontSmoothing(FontSmoothingTypeStandard);
+ preferences->setUsesPageCache(FALSE);
+
+ SysFreeString(standardFamily);
+ SysFreeString(fixedFamily);
+ SysFreeString(sansSerifFamily);
+ SysFreeString(cursiveFamily);
+ SysFreeString(fantasyFamily);
+}
+
+static Boolean pthreadEqualCallback(const void* value1, const void* value2)
+{
+ return (Boolean)pthread_equal(*(pthread_t*)value1, *(pthread_t*)value2);
+}
+
+static CFDictionaryKeyCallBacks pthreadKeyCallbacks = { 0, 0, 0, 0, pthreadEqualCallback, 0 };
+
+static pthread_mutex_t javaScriptThreadsMutex = PTHREAD_MUTEX_INITIALIZER;
+static bool javaScriptThreadsShouldTerminate;
+
+static const int javaScriptThreadsCount = 4;
+static CFMutableDictionaryRef javaScriptThreads()
+{
+ assert(pthread_mutex_trylock(&javaScriptThreadsMutex) == EBUSY);
+ static CFMutableDictionaryRef staticJavaScriptThreads;
+ if (!staticJavaScriptThreads)
+ staticJavaScriptThreads = CFDictionaryCreateMutable(0, 0, &pthreadKeyCallbacks, 0);
+ return staticJavaScriptThreads;
+}
+
+// Loops forever, running a script and randomly respawning, until
+// javaScriptThreadsShouldTerminate becomes true.
+void* runJavaScriptThread(void* arg)
+{
+ const char* const script =
+ " \
+ var array = []; \
+ for (var i = 0; i < 10; i++) { \
+ array.push(String(i)); \
+ } \
+ ";
+
+ while (true) {
+ JSGlobalContextRef ctx = JSGlobalContextCreate(0);
+ JSStringRef scriptRef = JSStringCreateWithUTF8CString(script);
+
+ JSValueRef exception = 0;
+ JSEvaluateScript(ctx, scriptRef, 0, 0, 0, &exception);
+ assert(!exception);
+
+ JSGlobalContextRelease(ctx);
+ JSStringRelease(scriptRef);
+
+ JSGarbageCollect(ctx);
+
+ pthread_mutex_lock(&javaScriptThreadsMutex);
+
+ // Check for cancellation.
+ if (javaScriptThreadsShouldTerminate) {
+ pthread_mutex_unlock(&javaScriptThreadsMutex);
+ return 0;
+ }
+
+ // Respawn probabilistically.
+ if (rand() % 5 == 0) {
+ pthread_t pthread;
+ pthread_create(&pthread, 0, &runJavaScriptThread, 0);
+ pthread_detach(pthread);
+
+ pthread_t self = pthread_self();
+ CFDictionaryRemoveValue(javaScriptThreads(), self.p);
+ CFDictionaryAddValue(javaScriptThreads(), pthread.p, 0);
+
+ pthread_mutex_unlock(&javaScriptThreadsMutex);
+ return 0;
+ }
+
+ pthread_mutex_unlock(&javaScriptThreadsMutex);
+ }
+}
+
+static void startJavaScriptThreads(void)
+{
+ pthread_mutex_lock(&javaScriptThreadsMutex);
+
+ for (int i = 0; i < javaScriptThreadsCount; i++) {
+ pthread_t pthread;
+ pthread_create(&pthread, 0, &runJavaScriptThread, 0);
+ pthread_detach(pthread);
+ CFDictionaryAddValue(javaScriptThreads(), pthread.p, 0);
+ }
+
+ pthread_mutex_unlock(&javaScriptThreadsMutex);
+}
+
+static void stopJavaScriptThreads(void)
+{
+ pthread_mutex_lock(&javaScriptThreadsMutex);
+
+ javaScriptThreadsShouldTerminate = true;
+
+ pthread_t* pthreads[javaScriptThreadsCount] = {0};
+ int threadDictCount = CFDictionaryGetCount(javaScriptThreads());
+ assert(threadDictCount == javaScriptThreadsCount);
+ CFDictionaryGetKeysAndValues(javaScriptThreads(), (const void**)pthreads, 0);
+
+ pthread_mutex_unlock(&javaScriptThreadsMutex);
+
+ for (int i = 0; i < javaScriptThreadsCount; i++) {
+ pthread_t* pthread = pthreads[i];
+ pthread_join(*pthread, 0);
+ free(pthread);
+ }
+}
+
+Vector<HWND>& openWindows()
+{
+ static Vector<HWND> vector;
+ return vector;
+}
+
+HashMap<HWND, IWebView*>& windowToWebViewMap()
+{
+ static HashMap<HWND, IWebView*> map;
+ return map;
+}
+
+IWebView* createWebViewAndOffscreenWindow(HWND* webViewWindow)
+{
+ HWND hostWindow = CreateWindowEx(WS_EX_TOOLWINDOW, kDumpRenderTreeClassName, TEXT("DumpRenderTree"), WS_POPUP,
+ -maxViewWidth, -maxViewHeight, maxViewWidth, maxViewHeight, 0, 0, GetModuleHandle(0), 0);
+
+ IWebView* webView;
+
+ HRESULT hr = CoCreateInstance(CLSID_WebView, 0, CLSCTX_ALL, IID_IWebView, (void**)&webView);
+ if (FAILED(hr)) {
+ fprintf(stderr, "Failed to create CLSID_WebView instance, error 0x%x\n", hr);
+ return 0;
+ }
+
+ if (FAILED(webView->setHostWindow((OLE_HANDLE)(ULONG64)hostWindow)))
+ return 0;
+
+ RECT clientRect;
+ clientRect.bottom = clientRect.left = clientRect.top = clientRect.right = 0;
+ BSTR groupName = SysAllocString(L"org.webkit.DumpRenderTree");
+ bool failed = FAILED(webView->initWithFrame(clientRect, 0, groupName));
+ SysFreeString(groupName);
+ if (failed)
+ return 0;
+
+ COMPtr<IWebViewPrivate> viewPrivate;
+ if (FAILED(webView->QueryInterface(&viewPrivate)))
+ return 0;
+
+ viewPrivate->setShouldApplyMacFontAscentHack(TRUE);
+
+ BSTR pluginPath = SysAllocStringLen(0, exePath().length() + _tcslen(TestPluginDir));
+ _tcscpy(pluginPath, exePath().c_str());
+ _tcscat(pluginPath, TestPluginDir);
+ failed = FAILED(viewPrivate->addAdditionalPluginPath(pluginPath));
+ SysFreeString(pluginPath);
+ if (failed)
+ return 0;
+
+ HWND viewWindow;
+ if (FAILED(viewPrivate->viewWindow(reinterpret_cast<OLE_HANDLE*>(&viewWindow))))
+ return 0;
+ if (webViewWindow)
+ *webViewWindow = viewWindow;
+
+ SetWindowPos(viewWindow, 0, 0, 0, maxViewWidth, maxViewHeight, 0);
+ ShowWindow(hostWindow, SW_SHOW);
+
+ if (FAILED(webView->setFrameLoadDelegate(sharedFrameLoadDelegate.get())))
+ return 0;
+
+ if (FAILED(viewPrivate->setFrameLoadDelegatePrivate(sharedFrameLoadDelegate.get())))
+ return 0;
+
+ if (FAILED(webView->setUIDelegate(sharedUIDelegate.get())))
+ return 0;
+
+ COMPtr<IWebViewEditing> viewEditing;
+ if (FAILED(webView->QueryInterface(&viewEditing)))
+ return 0;
+
+ if (FAILED(viewEditing->setEditingDelegate(sharedEditingDelegate.get())))
+ return 0;
+
+ if (FAILED(webView->setResourceLoadDelegate(sharedResourceLoadDelegate.get())))
+ return 0;
+
+ COMPtr<IWebPreferences> preferences;
+ if (FAILED(webView->preferences(&preferences)))
+ return 0;
+
+ initializePreferences(preferences.get());
+
+ openWindows().append(hostWindow);
+ windowToWebViewMap().set(hostWindow, webView);
+ return webView;
+}
+
+int main(int argc, char* argv[])
+{
+ leakChecking = false;
+
+ _setmode(1, _O_BINARY);
+
+ initialize();
+
+ Vector<const char*> tests;
+
+ for (int i = 1; i < argc; ++i) {
+ if (!stricmp(argv[i], "--threaded")) {
+ threaded = true;
+ continue;
+ }
+
+ if (!stricmp(argv[i], "--dump-all-pixels")) {
+ dumpAllPixels = true;
+ continue;
+ }
+
+ if (!stricmp(argv[i], "--pixel-tests")) {
+ dumpPixels = true;
+ continue;
+ }
+
+ tests.append(argv[i]);
+ }
+
+ policyDelegate = new PolicyDelegate();
+ sharedFrameLoadDelegate.adoptRef(new FrameLoadDelegate);
+ sharedUIDelegate.adoptRef(new UIDelegate);
+ sharedEditingDelegate.adoptRef(new EditingDelegate);
+ sharedResourceLoadDelegate.adoptRef(new ResourceLoadDelegate);
+
+ COMPtr<IWebView> webView(AdoptCOM, createWebViewAndOffscreenWindow(&webViewWindow));
+ if (!webView)
+ return -1;
+
+ COMPtr<IWebIconDatabase> iconDatabase;
+ COMPtr<IWebIconDatabase> tmpIconDatabase;
+ if (FAILED(CoCreateInstance(CLSID_WebIconDatabase, 0, CLSCTX_ALL, IID_IWebIconDatabase, (void**)&tmpIconDatabase)))
+ return -1;
+ if (FAILED(tmpIconDatabase->sharedIconDatabase(&iconDatabase)))
+ return -1;
+
+ if (FAILED(webView->mainFrame(&frame)))
+ return -1;
+
+ CFURLCacheRemoveAllCachedResponses(CFURLCacheSharedURLCache());
+
+#ifdef _DEBUG
+ _CrtMemState entryToMainMemCheckpoint;
+ if (leakChecking)
+ _CrtMemCheckpoint(&entryToMainMemCheckpoint);
+#endif
+
+ if (threaded)
+ startJavaScriptThreads();
+
+ if (tests.size() == 1 && !strcmp(tests[0], "-")) {
+ char filenameBuffer[2048];
+ printSeparators = true;
+ while (fgets(filenameBuffer, sizeof(filenameBuffer), stdin)) {
+ char* newLineCharacter = strchr(filenameBuffer, '\n');
+ if (newLineCharacter)
+ *newLineCharacter = '\0';
+
+ if (strlen(filenameBuffer) == 0)
+ continue;
+
+ runTest(filenameBuffer);
+ fflush(stdout);
+ }
+ } else {
+ printSeparators = tests.size() > 1;
+ for (int i = 0; i < tests.size(); i++)
+ runTest(tests[i]);
+ }
+
+ if (threaded)
+ stopJavaScriptThreads();
+
+ delete policyDelegate;
+ frame->Release();
+
+#ifdef _DEBUG
+ if (leakChecking) {
+ // dump leaks to stderr
+ _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
+ _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
+ _CrtMemDumpAllObjectsSince(&entryToMainMemCheckpoint);
+ }
+#endif
+
+ return 0;
+}
diff --git a/WebKitTools/DumpRenderTree/win/DumpRenderTree.vcproj b/WebKitTools/DumpRenderTree/win/DumpRenderTree.vcproj
new file mode 100644
index 0000000..a357f29
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/DumpRenderTree.vcproj
@@ -0,0 +1,374 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="DumpRenderTree"
+ ProjectGUID="{6567DFD4-D6DE-4CD5-825D-17E353D160E1}"
+ RootNamespace="DumpRenderTree"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\DumpRenderTree&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="&quot;$(ProjectDir)\.&quot;;&quot;$(ProjectDir)\..&quot;;&quot;$(ProjectDir)\..\cg&quot;;&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(WebKitOutputDir)\Include\DumpRenderTree\ForwardingHeaders&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\Include&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;&quot;$(WebKitOutputDir)\Include\WebCore&quot;;&quot;$(WebKitLibrariesDir)\Include\WebCore&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;"
+ PreprocessorDefinitions="_CONSOLE"
+ DisableSpecificWarnings="4146"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="WebKitGUID$(WebKitConfigSuffix).lib WebKit$(WebKitDLLConfigSuffix).lib WTF$(WebKitConfigSuffix).lib CoreGraphics$(LibraryConfigSuffix).lib CoreFoundation$(LibraryConfigSuffix).lib CFNetwork$(LibraryConfigSuffix).lib pthreadVC2$(LibraryConfigSuffix).lib gdi32.lib ole32.lib oleaut32.lib user32.lib shlwapi.lib"
+ AdditionalLibraryDirectories=""
+ DelayLoadDLLs=""
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="&#x0D;&#x0A;"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\release.vsprops"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\DumpRenderTree&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="&quot;$(ProjectDir)\.&quot;;&quot;$(ProjectDir)\..&quot;;&quot;$(ProjectDir)\..\cg&quot;;&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(WebKitOutputDir)\Include\DumpRenderTree\ForwardingHeaders&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\Include&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;&quot;$(WebKitOutputDir)\Include\WebCore&quot;;&quot;$(WebKitLibrariesDir)\Include\WebCore&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;"
+ PreprocessorDefinitions="_CONSOLE"
+ DisableSpecificWarnings="4146"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="WebKitGUID$(WebKitConfigSuffix).lib WebKit$(WebKitDLLConfigSuffix).lib WTF$(WebKitConfigSuffix).lib CoreGraphics$(LibraryConfigSuffix).lib CoreFoundation$(LibraryConfigSuffix).lib CFNetwork$(LibraryConfigSuffix).lib pthreadVC2$(LibraryConfigSuffix).lib gdi32.lib ole32.lib oleaut32.lib user32.lib shlwapi.lib"
+ AdditionalLibraryDirectories=""
+ DelayLoadDLLs=""
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="&#x0D;&#x0A;"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug_Internal|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_internal.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\DumpRenderTree&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="&quot;$(ProjectDir)\.&quot;;&quot;$(ProjectDir)\..&quot;;&quot;$(ProjectDir)\..\cg&quot;;&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(WebKitOutputDir)\Include\DumpRenderTree\ForwardingHeaders&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\Include&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;&quot;$(WebKitOutputDir)\Include\WebCore&quot;;&quot;$(WebKitLibrariesDir)\Include\WebCore&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;"
+ PreprocessorDefinitions="_CONSOLE;DEBUG_WEBKIT_HAS_SUFFIX"
+ DisableSpecificWarnings="4146"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="WebKitGUID$(WebKitConfigSuffix).lib WebKit$(WebKitDLLConfigSuffix).lib WTF$(WebKitConfigSuffix).lib CoreGraphics$(LibraryConfigSuffix).lib CoreFoundation$(LibraryConfigSuffix).lib CFNetwork$(LibraryConfigSuffix).lib pthreadVC2$(LibraryConfigSuffix).lib gdi32.lib ole32.lib oleaut32.lib user32.lib shlwapi.lib"
+ AdditionalLibraryDirectories=""
+ DelayLoadDLLs=""
+ SubSystem="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="&#x0D;&#x0A;"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Controllers"
+ >
+ <File
+ RelativePath=".\EventSender.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\EventSender.h"
+ >
+ </File>
+ <File
+ RelativePath="..\GCController.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\GCController.h"
+ >
+ </File>
+ <File
+ RelativePath=".\GCControllerWin.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\LayoutTestController.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\LayoutTestController.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LayoutTestControllerWin.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Delegates"
+ >
+ <File
+ RelativePath=".\EditingDelegate.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\EditingDelegate.h"
+ >
+ </File>
+ <File
+ RelativePath=".\FrameLoadDelegate.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\FrameLoadDelegate.h"
+ >
+ </File>
+ <File
+ RelativePath=".\PolicyDelegate.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\PolicyDelegate.h"
+ >
+ </File>
+ <File
+ RelativePath=".\ResourceLoadDelegate.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\ResourceLoadDelegate.h"
+ >
+ </File>
+ <File
+ RelativePath=".\UIDelegate.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\UIDelegate.h"
+ >
+ </File>
+ </Filter>
+ <File
+ RelativePath=".\DraggingInfo.h"
+ >
+ </File>
+ <File
+ RelativePath=".\DumpRenderTree.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\DumpRenderTree.h"
+ >
+ </File>
+ <File
+ RelativePath=".\DumpRenderTreeWin.h"
+ >
+ </File>
+ <File
+ RelativePath=".\MD5.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\MD5.h"
+ >
+ </File>
+ <File
+ RelativePath=".\PixelDumpSupport.h"
+ >
+ </File>
+ <File
+ RelativePath="..\cg\PixelDumpSupportCG.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\cg\PixelDumpSupportCG.h"
+ >
+ </File>
+ <File
+ RelativePath=".\PixelDumpSupportWin.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\WorkQueue.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\WorkQueue.h"
+ >
+ </File>
+ <File
+ RelativePath="..\WorkQueueItem.h"
+ >
+ </File>
+ <File
+ RelativePath=".\WorkQueueItemWin.cpp"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/WebKitTools/DumpRenderTree/win/DumpRenderTreeWin.h b/WebKitTools/DumpRenderTree/win/DumpRenderTreeWin.h
new file mode 100644
index 0000000..54dc697
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/DumpRenderTreeWin.h
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+#ifndef DumpRenderTreeWin_h
+#define DumpRenderTreeWin_h
+
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0500
+
+#undef WINVER
+#define WINVER 0x0500
+
+// If we don't define these, they get defined in windef.h.
+// We want to use std::min and std::max
+#undef max
+#define max max
+#undef min
+#define min min
+
+#undef _WINSOCKAPI_
+#define _WINSOCKAPI_ // Prevent inclusion of winsock.h in windows.h
+
+// FIXME: we should add a config.h file for DumpRenderTree.
+#define WTF_PLATFORM_CF 1
+
+struct IWebFrame;
+struct IWebPolicyDelegate;
+struct IWebView;
+typedef const struct __CFString* CFStringRef;
+typedef struct HWND__* HWND;
+
+extern IWebFrame* topLoadingFrame;
+extern IWebFrame* frame;
+extern IWebPolicyDelegate* policyDelegate;
+
+extern HWND webViewWindow;
+
+#include <string>
+#include <wtf/HashMap.h>
+#include <wtf/Vector.h>
+
+std::wstring urlSuitableForTestResult(const std::wstring& url);
+IWebView* createWebViewAndOffscreenWindow(HWND* webViewWindow = 0);
+Vector<HWND>& openWindows();
+HashMap<HWND, IWebView*>& windowToWebViewMap();
+
+void setPersistentUserStyleSheetLocation(CFStringRef);
+
+#endif // DumpRenderTreeWin_h
diff --git a/WebKitTools/DumpRenderTree/win/EditingDelegate.cpp b/WebKitTools/DumpRenderTree/win/EditingDelegate.cpp
new file mode 100644
index 0000000..7add64e
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/EditingDelegate.cpp
@@ -0,0 +1,354 @@
+/*
+ * 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 "DumpRenderTree.h"
+#include "EditingDelegate.h"
+
+#include "LayoutTestController.h"
+#include <WebCore/COMPtr.h>
+#include <wtf/Platform.h>
+#include <JavaScriptCore/Assertions.h>
+#include <string>
+#include <tchar.h>
+
+using std::wstring;
+
+EditingDelegate::EditingDelegate()
+ : m_refCount(1)
+ , m_acceptsEditing(true)
+{
+}
+
+// IUnknown
+HRESULT STDMETHODCALLTYPE EditingDelegate::QueryInterface(REFIID riid, void** ppvObject)
+{
+ *ppvObject = 0;
+ if (IsEqualGUID(riid, IID_IUnknown))
+ *ppvObject = static_cast<IWebEditingDelegate*>(this);
+ else if (IsEqualGUID(riid, IID_IWebEditingDelegate))
+ *ppvObject = static_cast<IWebEditingDelegate*>(this);
+ else
+ return E_NOINTERFACE;
+
+ AddRef();
+ return S_OK;
+}
+
+ULONG STDMETHODCALLTYPE EditingDelegate::AddRef(void)
+{
+ return ++m_refCount;
+}
+
+ULONG STDMETHODCALLTYPE EditingDelegate::Release(void)
+{
+ ULONG newRef = --m_refCount;
+ if (!newRef)
+ delete this;
+
+ return newRef;
+}
+
+static wstring dumpPath(IDOMNode* node)
+{
+ ASSERT(node);
+
+ wstring result;
+
+ BSTR name;
+ if (FAILED(node->nodeName(&name)))
+ return result;
+ result.assign(name, SysStringLen(name));
+ SysFreeString(name);
+
+ COMPtr<IDOMNode> parent;
+ if (SUCCEEDED(node->parentNode(&parent)))
+ result += TEXT(" > ") + dumpPath(parent.get());
+
+ return result;
+}
+
+static wstring dump(IDOMRange* range)
+{
+ ASSERT(range);
+
+ int startOffset;
+ if (FAILED(range->startOffset(&startOffset)))
+ return 0;
+
+ int endOffset;
+ if (FAILED(range->endOffset(&endOffset)))
+ return 0;
+
+ COMPtr<IDOMNode> startContainer;
+ if (FAILED(range->startContainer(&startContainer)))
+ return 0;
+
+ COMPtr<IDOMNode> endContainer;
+ if (FAILED(range->endContainer(&endContainer)))
+ return 0;
+
+ wchar_t buffer[1024];
+ _snwprintf(buffer, ARRAYSIZE(buffer), L"range from %ld of %s to %ld of %s", startOffset, dumpPath(startContainer.get()), endOffset, dumpPath(endContainer.get()));
+ return buffer;
+}
+
+HRESULT STDMETHODCALLTYPE EditingDelegate::shouldBeginEditingInDOMRange(
+ /* [in] */ IWebView* webView,
+ /* [in] */ IDOMRange* range,
+ /* [retval][out] */ BOOL* result)
+{
+ if (!result) {
+ ASSERT_NOT_REACHED();
+ return E_POINTER;
+ }
+
+ if (::layoutTestController->dumpEditingCallbacks() && !done)
+ _tprintf(TEXT("EDITING DELEGATE: shouldBeginEditingInDOMRange:%s\n"), dump(range));
+
+ *result = m_acceptsEditing;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE EditingDelegate::shouldEndEditingInDOMRange(
+ /* [in] */ IWebView* webView,
+ /* [in] */ IDOMRange* range,
+ /* [retval][out] */ BOOL* result)
+{
+ if (!result) {
+ ASSERT_NOT_REACHED();
+ return E_POINTER;
+ }
+
+ if (::layoutTestController->dumpEditingCallbacks() && !done)
+ _tprintf(TEXT("EDITING DELEGATE: shouldEndEditingInDOMRange:%s\n"), dump(range));
+
+ *result = m_acceptsEditing;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE EditingDelegate::shouldInsertNode(
+ /* [in] */ IWebView* webView,
+ /* [in] */ IDOMNode* node,
+ /* [in] */ IDOMRange* range,
+ /* [in] */ WebViewInsertAction action)
+{
+ static LPCTSTR insertactionstring[] = {
+ TEXT("WebViewInsertActionTyped"),
+ TEXT("WebViewInsertActionPasted"),
+ TEXT("WebViewInsertActionDropped"),
+ };
+
+ if (::layoutTestController->dumpEditingCallbacks() && !done)
+ _tprintf(TEXT("EDITING DELEGATE: shouldInsertNode:%s replacingDOMRange:%s givenAction:%s\n"), dumpPath(node), dump(range), insertactionstring[action]);
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE EditingDelegate::shouldInsertText(
+ /* [in] */ IWebView* webView,
+ /* [in] */ BSTR text,
+ /* [in] */ IDOMRange* range,
+ /* [in] */ WebViewInsertAction action,
+ /* [retval][out] */ BOOL* result)
+{
+ if (!result) {
+ ASSERT_NOT_REACHED();
+ return E_POINTER;
+ }
+
+ static LPCTSTR insertactionstring[] = {
+ TEXT("WebViewInsertActionTyped"),
+ TEXT("WebViewInsertActionPasted"),
+ TEXT("WebViewInsertActionDropped"),
+ };
+
+ if (::layoutTestController->dumpEditingCallbacks() && !done)
+ _tprintf(TEXT("EDITING DELEGATE: shouldInsertText:%s replacingDOMRange:%s givenAction:%s\n"), text ? text : TEXT(""), dump(range), insertactionstring[action]);
+
+ *result = m_acceptsEditing;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE EditingDelegate::shouldDeleteDOMRange(
+ /* [in] */ IWebView* webView,
+ /* [in] */ IDOMRange* range,
+ /* [retval][out] */ BOOL* result)
+{
+ if (!result) {
+ ASSERT_NOT_REACHED();
+ return E_POINTER;
+ }
+
+ if (::layoutTestController->dumpEditingCallbacks() && !done)
+ _tprintf(TEXT("EDITING DELEGATE: shouldDeleteDOMRange:%s\n"), dump(range));
+
+ *result = m_acceptsEditing;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE EditingDelegate::shouldChangeSelectedDOMRange(
+ /* [in] */ IWebView* webView,
+ /* [in] */ IDOMRange* currentRange,
+ /* [in] */ IDOMRange* proposedRange,
+ /* [in] */ WebSelectionAffinity selectionAffinity,
+ /* [in] */ BOOL stillSelecting,
+ /* [retval][out] */ BOOL* result)
+{
+ if (!result) {
+ ASSERT_NOT_REACHED();
+ return E_POINTER;
+ }
+
+ static LPCTSTR affinitystring[] = {
+ TEXT("NSSelectionAffinityUpstream"),
+ TEXT("NSSelectionAffinityDownstream")
+ };
+ static LPCTSTR boolstring[] = {
+ TEXT("FALSE"),
+ TEXT("TRUE")
+ };
+
+ if (::layoutTestController->dumpEditingCallbacks() && !done)
+ _tprintf(TEXT("EDITING DELEGATE: shouldChangeSelectedDOMRange:%s toDOMRange:%s affinity:%s stillSelecting:%s\n"), dump(currentRange), dump(proposedRange), affinitystring[selectionAffinity], boolstring[stillSelecting]);
+
+ *result = m_acceptsEditing;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE EditingDelegate::shouldApplyStyle(
+ /* [in] */ IWebView* webView,
+ /* [in] */ IDOMCSSStyleDeclaration* style,
+ /* [in] */ IDOMRange* range,
+ /* [retval][out] */ BOOL* result)
+{
+ if (!result) {
+ ASSERT_NOT_REACHED();
+ return E_POINTER;
+ }
+
+ if (::layoutTestController->dumpEditingCallbacks() && !done)
+ _tprintf(TEXT("EDITING DELEGATE: shouldApplyStyle:%s toElementsInDOMRange:%s\n"), TEXT("'style description'")/*[[style description] UTF8String]*/, dump(range));
+
+ *result = m_acceptsEditing;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE EditingDelegate::shouldChangeTypingStyle(
+ /* [in] */ IWebView* webView,
+ /* [in] */ IDOMCSSStyleDeclaration* currentStyle,
+ /* [in] */ IDOMCSSStyleDeclaration* proposedStyle,
+ /* [retval][out] */ BOOL* result)
+{
+ if (!result) {
+ ASSERT_NOT_REACHED();
+ return E_POINTER;
+ }
+
+ if (::layoutTestController->dumpEditingCallbacks() && !done)
+ _tprintf(TEXT("EDITING DELEGATE: shouldChangeTypingStyle:%s toStyle:%s\n"), TEXT("'currentStyle description'"), TEXT("'proposedStyle description'"));
+
+ *result = m_acceptsEditing;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE EditingDelegate::doPlatformCommand(
+ /* [in] */ IWebView *webView,
+ /* [in] */ BSTR command,
+ /* [retval][out] */ BOOL *result)
+{
+ if (!result) {
+ ASSERT_NOT_REACHED();
+ return E_POINTER;
+ }
+
+ if (::layoutTestController->dumpEditingCallbacks() && !done)
+ _tprintf(TEXT("EDITING DELEGATE: doPlatformCommand:%s\n"), command ? command : TEXT(""));
+
+ *result = m_acceptsEditing;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE EditingDelegate::webViewDidBeginEditing(
+ /* [in] */ IWebNotification* notification)
+{
+ if (::layoutTestController->dumpEditingCallbacks() && !done) {
+ BSTR name;
+ notification->name(&name);
+ _tprintf(TEXT("EDITING DELEGATE: webViewDidBeginEditing:%s\n"), name ? name : TEXT(""));
+ SysFreeString(name);
+ }
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE EditingDelegate::webViewDidChange(
+ /* [in] */ IWebNotification *notification)
+{
+ if (::layoutTestController->dumpEditingCallbacks() && !done) {
+ BSTR name;
+ notification->name(&name);
+ _tprintf(TEXT("EDITING DELEGATE: webViewDidBeginEditing:%s\n"), name ? name : TEXT(""));
+ SysFreeString(name);
+ }
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE EditingDelegate::webViewDidEndEditing(
+ /* [in] */ IWebNotification *notification)
+{
+ if (::layoutTestController->dumpEditingCallbacks() && !done) {
+ BSTR name;
+ notification->name(&name);
+ _tprintf(TEXT("EDITING DELEGATE: webViewDidEndEditing:%s\n"), name ? name : TEXT(""));
+ SysFreeString(name);
+ }
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE EditingDelegate::webViewDidChangeTypingStyle(
+ /* [in] */ IWebNotification *notification)
+{
+ if (::layoutTestController->dumpEditingCallbacks() && !done) {
+ BSTR name;
+ notification->name(&name);
+ _tprintf(TEXT("EDITING DELEGATE: webViewDidChangeTypingStyle:%s\n"), name ? name : TEXT(""));
+ SysFreeString(name);
+ }
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE EditingDelegate::webViewDidChangeSelection(
+ /* [in] */ IWebNotification *notification)
+{
+ if (::layoutTestController->dumpEditingCallbacks() && !done) {
+ BSTR name;
+ notification->name(&name);
+ _tprintf(TEXT("EDITING DELEGATE: webViewDidChangeSelection:%s\n"), name ? name : TEXT(""));
+ SysFreeString(name);
+ }
+ return S_OK;
+}
diff --git a/WebKitTools/DumpRenderTree/win/EditingDelegate.h b/WebKitTools/DumpRenderTree/win/EditingDelegate.h
new file mode 100644
index 0000000..6dba675
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/EditingDelegate.h
@@ -0,0 +1,176 @@
+/*
+ * 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 EditingDelegate_h
+#define EditingDelegate_h
+
+#include <WebKit/WebKit.h>
+
+class __declspec(uuid("265DCD4B-79C3-44a2-84BC-511C3EDABD6F")) EditingDelegate : public IWebEditingDelegate {
+public:
+ EditingDelegate();
+
+ void setAcceptsEditing(bool b) { m_acceptsEditing = b; }
+
+ // IUnknown
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
+ virtual ULONG STDMETHODCALLTYPE AddRef(void);
+ virtual ULONG STDMETHODCALLTYPE Release(void);
+
+ // IWebEditingDelegate
+ virtual HRESULT STDMETHODCALLTYPE shouldBeginEditingInDOMRange(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IDOMRange *range,
+ /* [retval][out] */ BOOL *result);
+
+ virtual HRESULT STDMETHODCALLTYPE shouldEndEditingInDOMRange(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IDOMRange *range,
+ /* [retval][out] */ BOOL *result);
+
+ virtual HRESULT STDMETHODCALLTYPE shouldInsertNode(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IDOMNode *node,
+ /* [in] */ IDOMRange *range,
+ /* [in] */ WebViewInsertAction action);
+
+ virtual HRESULT STDMETHODCALLTYPE shouldInsertText(
+ /* [in] */ IWebView *webView,
+ /* [in] */ BSTR text,
+ /* [in] */ IDOMRange *range,
+ /* [in] */ WebViewInsertAction action,
+ /* [retval][out] */ BOOL *result);
+
+ virtual HRESULT STDMETHODCALLTYPE shouldDeleteDOMRange(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IDOMRange *range,
+ /* [retval][out] */ BOOL *result);
+
+ virtual HRESULT STDMETHODCALLTYPE shouldChangeSelectedDOMRange(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IDOMRange *currentRange,
+ /* [in] */ IDOMRange *proposedRange,
+ /* [in] */ WebSelectionAffinity selectionAffinity,
+ /* [in] */ BOOL stillSelecting,
+ /* [retval][out] */ BOOL *result);
+
+ virtual HRESULT STDMETHODCALLTYPE shouldApplyStyle(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IDOMCSSStyleDeclaration *style,
+ /* [in] */ IDOMRange *range,
+ /* [retval][out] */ BOOL *result);
+
+ virtual HRESULT STDMETHODCALLTYPE shouldChangeTypingStyle(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IDOMCSSStyleDeclaration *currentStyle,
+ /* [in] */ IDOMCSSStyleDeclaration *proposedStyle,
+ /* [retval][out] */ BOOL *result);
+
+ virtual HRESULT STDMETHODCALLTYPE doPlatformCommand(
+ /* [in] */ IWebView *webView,
+ /* [in] */ BSTR command,
+ /* [retval][out] */ BOOL *result);
+
+ virtual HRESULT STDMETHODCALLTYPE webViewDidBeginEditing(
+ /* [in] */ IWebNotification *notification);
+
+ virtual HRESULT STDMETHODCALLTYPE webViewDidChange(
+ /* [in] */ IWebNotification *notification);
+
+ virtual HRESULT STDMETHODCALLTYPE webViewDidEndEditing(
+ /* [in] */ IWebNotification *notification);
+
+ virtual HRESULT STDMETHODCALLTYPE webViewDidChangeTypingStyle(
+ /* [in] */ IWebNotification *notification);
+
+ virtual HRESULT STDMETHODCALLTYPE webViewDidChangeSelection(
+ /* [in] */ IWebNotification *notification);
+
+ virtual HRESULT STDMETHODCALLTYPE undoManagerForWebView(
+ /* [in] */ IWebView *webView,
+ /* [retval][out] */ IWebUndoManager **undoManager) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE ignoreWordInSpellDocument(
+ /* [in] */ IWebView *view,
+ /* [in] */ BSTR word) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE learnWord(
+ /* [in] */ BSTR word) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE checkSpellingOfString(
+ /* [in] */ IWebView *view,
+ /* [in] */ LPCTSTR text,
+ /* [in] */ int length,
+ /* [out] */ int *misspellingLocation,
+ /* [out] */ int *misspellingLength) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE checkGrammarOfString(
+ /* [in] */ IWebView *view,
+ /* [in] */ LPCTSTR text,
+ /* [in] */ int length,
+ /* [out] */ IEnumWebGrammarDetails **grammarDetails,
+ /* [out] */ int *badGrammarLocation,
+ /* [out] */ int *badGrammarLength) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE updateSpellingUIWithGrammarString(
+ /* [in] */ BSTR string,
+ /* [in] */ int location,
+ /* [in] */ int length,
+ /* [in] */ BSTR userDescription,
+ /* [in] */ BSTR *guesses,
+ /* [in] */ int guessesCount) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE updateSpellingUIWithMisspelledWord(
+ /* [in] */ BSTR word) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE showSpellingUI(
+ /* [in] */ BOOL show) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE spellingUIIsShowing(
+ /* [retval][out] */ BOOL *result) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE guessesForWord(
+ /* [in] */ BSTR word,
+ /* [retval][out] */ IEnumSpellingGuesses **guesses) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE closeSpellDocument(
+ /* [in] */ IWebView *view) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE sharedSpellCheckerExists(
+ /* [retval][out] */ BOOL *exists) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE preflightChosenSpellServer( void) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE updateGrammar( void) { return E_NOTIMPL; }
+
+private:
+ bool m_acceptsEditing;
+ ULONG m_refCount;
+};
+
+#endif // !defined(EditingDelegate_h)
diff --git a/WebKitTools/DumpRenderTree/win/EventSender.cpp b/WebKitTools/DumpRenderTree/win/EventSender.cpp
new file mode 100644
index 0000000..ddff01c
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/EventSender.cpp
@@ -0,0 +1,566 @@
+/*
+ * 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.
+ */
+
+#include "DumpRenderTree.h"
+#include "EventSender.h"
+
+#include "DraggingInfo.h"
+
+#include <WebCore/COMPtr.h>
+#include <wtf/ASCIICType.h>
+#include <wtf/Platform.h>
+#include <JavaScriptCore/JavaScriptCore.h>
+#include <JavaScriptCore/Assertions.h>
+#include <WebKit/WebKit.h>
+#include <windows.h>
+
+#define WM_DRT_SEND_QUEUED_EVENT (WM_APP+1)
+
+static bool down;
+static bool dragMode = true;
+static bool replayingSavedEvents;
+static int timeOffset;
+static POINT lastMousePosition;
+
+struct DelayedMessage {
+ MSG msg;
+ unsigned delay;
+};
+
+static DelayedMessage msgQueue[1024];
+static unsigned endOfQueue;
+static unsigned startOfQueue;
+
+static bool didDragEnter;
+DraggingInfo* draggingInfo = 0;
+
+static JSValueRef getDragModeCallback(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
+{
+ return JSValueMakeBoolean(context, dragMode);
+}
+
+static bool setDragModeCallback(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
+{
+ dragMode = JSValueToBoolean(context, value);
+ return true;
+}
+
+static JSValueRef getConstantCallback(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
+{
+ if (JSStringIsEqualToUTF8CString(propertyName, "WM_KEYDOWN"))
+ return JSValueMakeNumber(context, WM_KEYDOWN);
+ if (JSStringIsEqualToUTF8CString(propertyName, "WM_KEYUP"))
+ return JSValueMakeNumber(context, WM_KEYUP);
+ if (JSStringIsEqualToUTF8CString(propertyName, "WM_CHAR"))
+ return JSValueMakeNumber(context, WM_CHAR);
+ if (JSStringIsEqualToUTF8CString(propertyName, "WM_DEADCHAR"))
+ return JSValueMakeNumber(context, WM_DEADCHAR);
+ if (JSStringIsEqualToUTF8CString(propertyName, "WM_SYSKEYDOWN"))
+ return JSValueMakeNumber(context, WM_SYSKEYDOWN);
+ if (JSStringIsEqualToUTF8CString(propertyName, "WM_SYSKEYUP"))
+ return JSValueMakeNumber(context, WM_SYSKEYUP);
+ if (JSStringIsEqualToUTF8CString(propertyName, "WM_SYSCHAR"))
+ return JSValueMakeNumber(context, WM_SYSCHAR);
+ if (JSStringIsEqualToUTF8CString(propertyName, "WM_SYSDEADCHAR"))
+ return JSValueMakeNumber(context, WM_SYSDEADCHAR);
+ ASSERT_NOT_REACHED();
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef leapForwardCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ if (argumentCount > 0) {
+ msgQueue[endOfQueue].delay = JSValueToNumber(context, arguments[0], exception);
+ ASSERT(!exception || !*exception);
+ }
+
+ return JSValueMakeUndefined(context);
+}
+
+static DWORD currentEventTime()
+{
+ return ::GetTickCount() + timeOffset;
+}
+
+static MSG makeMsg(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ MSG result = {0};
+ result.hwnd = hwnd;
+ result.message = message;
+ result.wParam = wParam;
+ result.lParam = lParam;
+ result.time = currentEventTime();
+ result.pt = lastMousePosition;
+
+ return result;
+}
+
+static LRESULT dispatchMessage(const MSG* msg)
+{
+ ASSERT(msg);
+ ::TranslateMessage(msg);
+ return ::DispatchMessage(msg);
+}
+
+static JSValueRef contextClickCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ COMPtr<IWebFramePrivate> framePrivate;
+ if (SUCCEEDED(frame->QueryInterface(&framePrivate)))
+ framePrivate->layout();
+
+ down = true;
+ MSG msg = makeMsg(webViewWindow, WM_RBUTTONDOWN, 0, MAKELPARAM(lastMousePosition.x, lastMousePosition.y));
+ dispatchMessage(&msg);
+ down = false;
+ msg = makeMsg(webViewWindow, WM_RBUTTONUP, 0, MAKELPARAM(lastMousePosition.x, lastMousePosition.y));
+ dispatchMessage(&msg);
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef mouseDownCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ COMPtr<IWebFramePrivate> framePrivate;
+ if (SUCCEEDED(frame->QueryInterface(&framePrivate)))
+ framePrivate->layout();
+
+ down = true;
+ MSG msg = makeMsg(webViewWindow, WM_LBUTTONDOWN, 0, MAKELPARAM(lastMousePosition.x, lastMousePosition.y));
+ if (!msgQueue[endOfQueue].delay)
+ dispatchMessage(&msg);
+ else {
+ // replaySavedEvents has the required logic to make leapForward delays work
+ msgQueue[endOfQueue++].msg = msg;
+ replaySavedEvents();
+ }
+
+ return JSValueMakeUndefined(context);
+}
+
+static inline POINTL pointl(const POINT& point)
+{
+ POINTL result;
+ result.x = point.x;
+ result.y = point.y;
+ return result;
+}
+
+static void doMouseUp(MSG msg)
+{
+ COMPtr<IWebFramePrivate> framePrivate;
+ if (SUCCEEDED(frame->QueryInterface(&framePrivate)))
+ framePrivate->layout();
+
+ dispatchMessage(&msg);
+ down = false;
+
+ if (draggingInfo) {
+ COMPtr<IWebView> webView;
+ COMPtr<IDropTarget> webViewDropTarget;
+ if (SUCCEEDED(frame->webView(&webView)) && SUCCEEDED(webView->QueryInterface(IID_IDropTarget, (void**)&webViewDropTarget))) {
+ POINT screenPoint = msg.pt;
+ DWORD effect = 0;
+ ::ClientToScreen(webViewWindow, &screenPoint);
+ if (!didDragEnter) {
+ webViewDropTarget->DragEnter(draggingInfo->dataObject(), 0, pointl(screenPoint), &effect);
+ didDragEnter = true;
+ }
+ HRESULT hr = draggingInfo->dropSource()->QueryContinueDrag(0, 0);
+ webViewDropTarget->DragOver(0, pointl(screenPoint), &effect);
+ if (hr == DRAGDROP_S_DROP && effect != DROPEFFECT_NONE) {
+ DWORD effect = 0;
+ webViewDropTarget->Drop(draggingInfo->dataObject(), 0, pointl(screenPoint), &effect);
+ } else
+ webViewDropTarget->DragLeave();
+
+ delete draggingInfo;
+ draggingInfo = 0;
+ }
+ }
+}
+
+static JSValueRef mouseUpCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ MSG msg = makeMsg(webViewWindow, WM_LBUTTONUP, 0, MAKELPARAM(lastMousePosition.x, lastMousePosition.y));
+
+ if ((dragMode && !replayingSavedEvents) || msgQueue[endOfQueue].delay) {
+ msgQueue[endOfQueue++].msg = msg;
+ replaySavedEvents();
+ } else
+ doMouseUp(msg);
+
+ return JSValueMakeUndefined(context);
+}
+
+static void doMouseMove(MSG msg)
+{
+ COMPtr<IWebFramePrivate> framePrivate;
+ if (SUCCEEDED(frame->QueryInterface(&framePrivate)))
+ framePrivate->layout();
+
+ dispatchMessage(&msg);
+
+ if (down && draggingInfo) {
+ POINT screenPoint = msg.pt;
+ ::ClientToScreen(webViewWindow, &screenPoint);
+
+ IWebView* webView;
+ COMPtr<IDropTarget> webViewDropTarget;
+ if (SUCCEEDED(frame->webView(&webView)) && SUCCEEDED(webView->QueryInterface(IID_IDropTarget, (void**)&webViewDropTarget))) {
+ DWORD effect = 0;
+ if (didDragEnter)
+ webViewDropTarget->DragOver(MK_LBUTTON, pointl(screenPoint), &effect);
+ else {
+ webViewDropTarget->DragEnter(draggingInfo->dataObject(), 0, pointl(screenPoint), &effect);
+ didDragEnter = true;
+ }
+ draggingInfo->dropSource()->GiveFeedback(effect);
+ }
+ }
+}
+
+static JSValueRef mouseMoveToCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ if (argumentCount < 2)
+ return JSValueMakeUndefined(context);
+
+ lastMousePosition.x = (int)JSValueToNumber(context, arguments[0], exception);
+ ASSERT(!exception || !*exception);
+ lastMousePosition.y = (int)JSValueToNumber(context, arguments[1], exception);
+ ASSERT(!exception || !*exception);
+
+ MSG msg = makeMsg(webViewWindow, WM_MOUSEMOVE, down ? MK_LBUTTON : 0, MAKELPARAM(lastMousePosition.x, lastMousePosition.y));
+
+ if (dragMode && down && !replayingSavedEvents) {
+ msgQueue[endOfQueue++].msg = msg;
+ return JSValueMakeUndefined(context);
+ }
+
+ doMouseMove(msg);
+
+ return JSValueMakeUndefined(context);
+}
+
+void replaySavedEvents()
+{
+ replayingSavedEvents = true;
+
+ MSG msg = { 0 };
+
+ while (startOfQueue < endOfQueue && !msgQueue[startOfQueue].delay) {
+ msg = msgQueue[startOfQueue++].msg;
+ switch (msg.message) {
+ case WM_LBUTTONUP:
+ doMouseUp(msg);
+ break;
+ case WM_MOUSEMOVE:
+ doMouseMove(msg);
+ break;
+ case WM_LBUTTONDOWN:
+ dispatchMessage(&msg);
+ break;
+ default:
+ // Not reached
+ break;
+ }
+ }
+
+ int numQueuedMessages = endOfQueue - startOfQueue;
+ if (!numQueuedMessages) {
+ startOfQueue = 0;
+ endOfQueue = 0;
+ replayingSavedEvents = false;
+ ASSERT(!down);
+ return;
+ }
+
+ if (msgQueue[startOfQueue].delay) {
+ ::Sleep(msgQueue[startOfQueue].delay);
+ msgQueue[startOfQueue].delay = 0;
+ }
+
+ ::PostMessage(webViewWindow, WM_DRT_SEND_QUEUED_EVENT, 0, 0);
+ while (::GetMessage(&msg, webViewWindow, 0, 0)) {
+ // FIXME: Why do we get a WM_MOUSELEAVE? it breaks tests
+ if (msg.message == WM_MOUSELEAVE)
+ continue;
+ if (msg.message != WM_DRT_SEND_QUEUED_EVENT) {
+ dispatchMessage(&msg);
+ continue;
+ }
+ msg = msgQueue[startOfQueue++].msg;
+ switch (msg.message) {
+ case WM_LBUTTONUP:
+ doMouseUp(msg);
+ break;
+ case WM_MOUSEMOVE:
+ doMouseMove(msg);
+ break;
+ case WM_LBUTTONDOWN:
+ dispatchMessage(&msg);
+ break;
+ default:
+ // Not reached
+ break;
+ }
+ if (startOfQueue >= endOfQueue)
+ break;
+ ::Sleep(msgQueue[startOfQueue].delay);
+ msgQueue[startOfQueue].delay = 0;
+ ::PostMessage(webViewWindow, WM_DRT_SEND_QUEUED_EVENT, 0, 0);
+ }
+ startOfQueue = 0;
+ endOfQueue = 0;
+
+ replayingSavedEvents = false;
+}
+
+static JSValueRef keyDownCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ static const JSStringRef lengthProperty = JSStringCreateWithUTF8CString("length");
+
+ COMPtr<IWebFramePrivate> framePrivate;
+ if (SUCCEEDED(frame->QueryInterface(&framePrivate)))
+ framePrivate->layout();
+
+ JSStringRef character = JSValueToStringCopy(context, arguments[0], exception);
+ ASSERT(!*exception);
+ int virtualKeyCode;
+ int charCode = 0;
+ int keyData = 1;
+ bool needsShiftKeyModifier = false;
+ if (JSStringIsEqualToUTF8CString(character, "leftArrow")) {
+ virtualKeyCode = VK_LEFT;
+ keyData += KF_EXTENDED << 16; // In this case, extended means "not keypad".
+ } else if (JSStringIsEqualToUTF8CString(character, "rightArrow")) {
+ virtualKeyCode = VK_RIGHT;
+ keyData += KF_EXTENDED << 16;
+ } else if (JSStringIsEqualToUTF8CString(character, "upArrow")) {
+ virtualKeyCode = VK_UP;
+ keyData += KF_EXTENDED << 16;
+ } else if (JSStringIsEqualToUTF8CString(character, "downArrow")) {
+ virtualKeyCode = VK_DOWN;
+ keyData += KF_EXTENDED << 16;
+ } else if (JSStringIsEqualToUTF8CString(character, "pageUp"))
+ virtualKeyCode = VK_PRIOR;
+ else if (JSStringIsEqualToUTF8CString(character, "pageDown"))
+ virtualKeyCode = VK_NEXT;
+ else if (JSStringIsEqualToUTF8CString(character, "home"))
+ virtualKeyCode = VK_HOME;
+ else if (JSStringIsEqualToUTF8CString(character, "end"))
+ virtualKeyCode = VK_END;
+ else if (JSStringIsEqualToUTF8CString(character, "delete"))
+ virtualKeyCode = VK_BACK;
+ else {
+ charCode = JSStringGetCharactersPtr(character)[0];
+ virtualKeyCode = LOBYTE(VkKeyScan(charCode));
+ if (WTF::isASCIIUpper(charCode))
+ needsShiftKeyModifier = true;
+ }
+ JSStringRelease(character);
+
+ BYTE keyState[256];
+ if (argumentCount > 1 || needsShiftKeyModifier) {
+ ::GetKeyboardState(keyState);
+
+ BYTE newKeyState[256];
+ memcpy(newKeyState, keyState, sizeof(keyState));
+
+ if (needsShiftKeyModifier)
+ newKeyState[VK_SHIFT] = 0x80;
+
+ if (argumentCount > 1) {
+ JSObjectRef modifiersArray = JSValueToObject(context, arguments[1], exception);
+ if (modifiersArray) {
+ int modifiersCount = JSValueToNumber(context, JSObjectGetProperty(context, modifiersArray, lengthProperty, 0), 0);
+ for (int i = 0; i < modifiersCount; ++i) {
+ JSValueRef value = JSObjectGetPropertyAtIndex(context, modifiersArray, i, 0);
+ JSStringRef string = JSValueToStringCopy(context, value, 0);
+ if (JSStringIsEqualToUTF8CString(string, "ctrlKey"))
+ newKeyState[VK_CONTROL] = 0x80;
+ else if (JSStringIsEqualToUTF8CString(string, "shiftKey"))
+ newKeyState[VK_SHIFT] = 0x80;
+ else if (JSStringIsEqualToUTF8CString(string, "altKey"))
+ newKeyState[VK_MENU] = 0x80;
+
+ JSStringRelease(string);
+ }
+ }
+ }
+
+ ::SetKeyboardState(newKeyState);
+ }
+
+ MSG msg = makeMsg(webViewWindow, (::GetKeyState(VK_MENU) & 0x8000) ? WM_SYSKEYDOWN : WM_KEYDOWN, virtualKeyCode, keyData);
+ if (virtualKeyCode != 255)
+ dispatchMessage(&msg);
+ else {
+ // For characters that do not exist in the active keyboard layout,
+ // ::Translate will not work, so we post an WM_CHAR event ourselves.
+ ::PostMessage(webViewWindow, WM_CHAR, charCode, 0);
+ }
+
+ // Tests expect that all messages are processed by the time keyDown() returns.
+ if (::PeekMessage(&msg, webViewWindow, WM_CHAR, WM_CHAR, PM_REMOVE) || ::PeekMessage(&msg, webViewWindow, WM_SYSCHAR, WM_SYSCHAR, PM_REMOVE))
+ ::DispatchMessage(&msg);
+
+ MSG msgUp = makeMsg(webViewWindow, (::GetKeyState(VK_MENU) & 0x8000) ? WM_SYSKEYUP : WM_KEYUP, virtualKeyCode, keyData);
+ ::DispatchMessage(&msgUp);
+
+ if (argumentCount > 1 || needsShiftKeyModifier)
+ ::SetKeyboardState(keyState);
+
+ return JSValueMakeUndefined(context);
+}
+
+// eventSender.dispatchMessage(message, wParam, lParam, time = currentEventTime(), x = lastMousePosition.x, y = lastMousePosition.y)
+static JSValueRef dispatchMessageCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ if (argumentCount < 3)
+ return JSValueMakeUndefined(context);
+
+ COMPtr<IWebFramePrivate> framePrivate;
+ if (SUCCEEDED(frame->QueryInterface(&framePrivate)))
+ framePrivate->layout();
+
+ MSG msg = {};
+ msg.hwnd = webViewWindow;
+ msg.message = JSValueToNumber(context, arguments[0], exception);
+ ASSERT(!*exception);
+ msg.wParam = JSValueToNumber(context, arguments[1], exception);
+ ASSERT(!*exception);
+ msg.lParam = static_cast<ULONG_PTR>(JSValueToNumber(context, arguments[2], exception));
+ ASSERT(!*exception);
+ if (argumentCount >= 4) {
+ msg.time = JSValueToNumber(context, arguments[3], exception);
+ ASSERT(!*exception);
+ }
+ if (!msg.time)
+ msg.time = currentEventTime();
+ if (argumentCount >= 6) {
+ msg.pt.x = JSValueToNumber(context, arguments[4], exception);
+ ASSERT(!*exception);
+ msg.pt.y = JSValueToNumber(context, arguments[5], exception);
+ ASSERT(!*exception);
+ } else
+ msg.pt = lastMousePosition;
+
+ ::DispatchMessage(&msg);
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef textZoomInCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return JSValueMakeUndefined(context);
+
+ COMPtr<IWebIBActions> webIBActions;
+ if (FAILED(webView->QueryInterface(IID_IWebIBActions, (void**)&webIBActions)))
+ return JSValueMakeUndefined(context);
+
+ webIBActions->makeTextLarger(0);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef textZoomOutCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return JSValueMakeUndefined(context);
+
+ COMPtr<IWebIBActions> webIBActions;
+ if (FAILED(webView->QueryInterface(IID_IWebIBActions, (void**)&webIBActions)))
+ return JSValueMakeUndefined(context);
+
+ webIBActions->makeTextSmaller(0);
+ return JSValueMakeUndefined(context);
+}
+
+static JSStaticFunction staticFunctions[] = {
+ { "contextClick", contextClickCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "mouseDown", mouseDownCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "mouseUp", mouseUpCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "mouseMoveTo", mouseMoveToCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "leapForward", leapForwardCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "keyDown", keyDownCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "dispatchMessage", dispatchMessageCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "textZoomIn", textZoomInCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "textZoomOut", textZoomOutCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { 0, 0, 0 }
+};
+
+static JSStaticValue staticValues[] = {
+ { "dragMode", getDragModeCallback, setDragModeCallback, kJSPropertyAttributeNone },
+ { "WM_KEYDOWN", getConstantCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeNone },
+ { "WM_KEYUP", getConstantCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeNone },
+ { "WM_CHAR", getConstantCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeNone },
+ { "WM_DEADCHAR", getConstantCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeNone },
+ { "WM_SYSKEYDOWN", getConstantCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeNone },
+ { "WM_SYSKEYUP", getConstantCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeNone },
+ { "WM_SYSCHAR", getConstantCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeNone },
+ { "WM_SYSDEADCHAR", getConstantCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeNone },
+ { 0, 0, 0, 0 }
+};
+
+static JSClassRef getClass(JSContextRef context)
+{
+ static JSClassRef eventSenderClass = 0;
+
+ if (!eventSenderClass) {
+ JSClassDefinition classDefinition = {0};
+ classDefinition.staticFunctions = staticFunctions;
+ classDefinition.staticValues = staticValues;
+
+ eventSenderClass = JSClassCreate(&classDefinition);
+ }
+
+ return eventSenderClass;
+}
+
+JSObjectRef makeEventSender(JSContextRef context)
+{
+ down = false;
+ dragMode = true;
+ replayingSavedEvents = false;
+ timeOffset = 0;
+ lastMousePosition.x = 0;
+ lastMousePosition.y = 0;
+
+ endOfQueue = 0;
+ startOfQueue = 0;
+
+ didDragEnter = false;
+ draggingInfo = 0;
+
+ return JSObjectMake(context, getClass(context), 0);
+}
diff --git a/WebKitTools/DumpRenderTree/win/EventSender.h b/WebKitTools/DumpRenderTree/win/EventSender.h
new file mode 100644
index 0000000..9ae0aec
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/EventSender.h
@@ -0,0 +1,42 @@
+/*
+ * 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 EventSender_h
+#define EventSender_h
+
+class DraggingInfo;
+
+typedef const struct OpaqueJSContext* JSContextRef;
+typedef struct OpaqueJSValue* JSObjectRef;
+
+JSObjectRef makeEventSender(JSContextRef context);
+void replaySavedEvents();
+
+extern DraggingInfo* draggingInfo;
+
+#endif
diff --git a/WebKitTools/DumpRenderTree/win/FrameLoadDelegate.cpp b/WebKitTools/DumpRenderTree/win/FrameLoadDelegate.cpp
new file mode 100644
index 0000000..b21d34e
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/FrameLoadDelegate.cpp
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 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.
+ * 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 "DumpRenderTree.h"
+#include "FrameLoadDelegate.h"
+
+#include "EventSender.h"
+#include "GCController.h"
+#include "LayoutTestController.h"
+#include "WorkQueueItem.h"
+#include "WorkQueue.h"
+#include <WebCore/COMPtr.h>
+#include <JavaScriptCore/Assertions.h>
+#include <JavaScriptCore/JavaScriptCore.h>
+#include <WebKit/WebKit.h>
+#include <wtf/Vector.h>
+#include <stdio.h>
+#include <string>
+
+using std::string;
+
+static FrameLoadDelegate* g_delegateWaitingOnTimer;
+
+string BSTRtoString(BSTR bstr)
+{
+ int result = WideCharToMultiByte(CP_UTF8, 0, bstr, SysStringLen(bstr) + 1, 0, 0, 0, 0);
+ Vector<char> utf8Vector(result);
+ result = WideCharToMultiByte(CP_UTF8, 0, bstr, SysStringLen(bstr) + 1, utf8Vector.data(), result, 0, 0);
+ if (!result)
+ return string();
+
+ return string(utf8Vector.data(), utf8Vector.size() - 1);
+}
+
+string descriptionSuitableForTestResult(IWebFrame* webFrame)
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(webFrame->webView(&webView)))
+ return string();
+
+ COMPtr<IWebFrame> mainFrame;
+ if (FAILED(webView->mainFrame(&mainFrame)))
+ return string();
+
+ if (webFrame == mainFrame)
+ return "main frame";
+
+ BSTR frameNameBSTR;
+ if (FAILED(webFrame->name(&frameNameBSTR)))
+ return string();
+
+ string frameName = "frame \"" + BSTRtoString(frameNameBSTR) + "\"";
+ SysFreeString(frameNameBSTR);
+
+ return frameName;
+}
+
+FrameLoadDelegate::FrameLoadDelegate()
+ : m_refCount(1)
+ , m_gcController(new GCController)
+{
+}
+
+FrameLoadDelegate::~FrameLoadDelegate()
+{
+}
+
+HRESULT STDMETHODCALLTYPE FrameLoadDelegate::QueryInterface(REFIID riid, void** ppvObject)
+{
+ *ppvObject = 0;
+ if (IsEqualGUID(riid, IID_IUnknown))
+ *ppvObject = static_cast<IWebFrameLoadDelegate*>(this);
+ else if (IsEqualGUID(riid, IID_IWebFrameLoadDelegate))
+ *ppvObject = static_cast<IWebFrameLoadDelegate*>(this);
+ else if (IsEqualGUID(riid, IID_IWebFrameLoadDelegate2))
+ *ppvObject = static_cast<IWebFrameLoadDelegate*>(this);
+ else if (IsEqualGUID(riid, IID_IWebFrameLoadDelegatePrivate))
+ *ppvObject = static_cast<IWebFrameLoadDelegatePrivate*>(this);
+ else
+ return E_NOINTERFACE;
+
+ AddRef();
+ return S_OK;
+}
+
+ULONG STDMETHODCALLTYPE FrameLoadDelegate::AddRef(void)
+{
+ return ++m_refCount;
+}
+
+ULONG STDMETHODCALLTYPE FrameLoadDelegate::Release(void)
+{
+ ULONG newRef = --m_refCount;
+ if (!newRef)
+ delete(this);
+
+ return newRef;
+}
+
+
+HRESULT STDMETHODCALLTYPE FrameLoadDelegate::didStartProvisionalLoadForFrame(
+ /* [in] */ IWebView* webView,
+ /* [in] */ IWebFrame* frame)
+{
+ if (!done && layoutTestController->dumpFrameLoadCallbacks())
+ printf("%s - didStartProvisionalLoadForFrame\n",
+ descriptionSuitableForTestResult(frame).c_str());
+
+ // Make sure we only set this once per test. If it gets cleared, and then set again, we might
+ // end up doing two dumps for one test.
+ if (!topLoadingFrame && !done)
+ topLoadingFrame = frame;
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FrameLoadDelegate::didFailProvisionalLoadWithError(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebError *error,
+ /* [in] */ IWebFrame *frame)
+{
+ if (!done && layoutTestController->dumpFrameLoadCallbacks())
+ printf("%s - didFailProvisionalLoadWithError\n",
+ descriptionSuitableForTestResult(frame).c_str());
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FrameLoadDelegate::didCommitLoadForFrame(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebFrame *frame)
+{
+ COMPtr<IWebViewPrivate> webViewPrivate;
+ HRESULT hr = webView->QueryInterface(&webViewPrivate);
+ if (FAILED(hr))
+ return hr;
+ webViewPrivate->updateFocusedAndActiveState();
+
+ if (!done && layoutTestController->dumpFrameLoadCallbacks())
+ printf("%s - didCommitLoadForFrame\n",
+ descriptionSuitableForTestResult(frame).c_str());
+
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FrameLoadDelegate::didReceiveTitle(
+ /* [in] */ IWebView *webView,
+ /* [in] */ BSTR title,
+ /* [in] */ IWebFrame *frame)
+{
+ if (::layoutTestController->dumpTitleChanges() && !done)
+ printf("TITLE CHANGED: %S\n", title ? title : L"");
+ return S_OK;
+}
+
+void FrameLoadDelegate::processWork()
+{
+ // quit doing work once a load is in progress
+ while (!topLoadingFrame && WorkQueue::shared()->count()) {
+ WorkQueueItem* item = WorkQueue::shared()->dequeue();
+ ASSERT(item);
+ item->invoke();
+ }
+
+ // if we didn't start a new load, then we finished all the commands, so we're ready to dump state
+ if (!topLoadingFrame && !::layoutTestController->waitToDump())
+ dump();
+}
+
+static void CALLBACK processWorkTimer(HWND, UINT, UINT_PTR id, DWORD)
+{
+ ::KillTimer(0, id);
+ FrameLoadDelegate* d = g_delegateWaitingOnTimer;
+ g_delegateWaitingOnTimer = 0;
+ d->processWork();
+}
+
+void FrameLoadDelegate::locationChangeDone(IWebError*, IWebFrame* frame)
+{
+ if (frame != topLoadingFrame)
+ return;
+
+ topLoadingFrame = 0;
+ WorkQueue::shared()->setFrozen(true);
+
+ if (::layoutTestController->waitToDump())
+ return;
+
+ if (WorkQueue::shared()->count()) {
+ ASSERT(!g_delegateWaitingOnTimer);
+ g_delegateWaitingOnTimer = this;
+ ::SetTimer(0, 0, 0, processWorkTimer);
+ return;
+ }
+
+ dump();
+}
+
+HRESULT STDMETHODCALLTYPE FrameLoadDelegate::didFinishLoadForFrame(
+ /* [in] */ IWebView* webView,
+ /* [in] */ IWebFrame* frame)
+{
+ if (!done && layoutTestController->dumpFrameLoadCallbacks())
+ printf("%s - didFinishLoadForFrame\n",
+ descriptionSuitableForTestResult(frame).c_str());
+
+ locationChangeDone(0, frame);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FrameLoadDelegate::didFailLoadWithError(
+ /* [in] */ IWebView* webView,
+ /* [in] */ IWebError* error,
+ /* [in] */ IWebFrame* forFrame)
+{
+ locationChangeDone(error, forFrame);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FrameLoadDelegate::willCloseFrame(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebFrame *frame)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE FrameLoadDelegate::didClearWindowObject(
+ /* [in] */ IWebView*webView,
+ /* [in] */ JSContextRef context,
+ /* [in] */ JSObjectRef windowObject,
+ /* [in] */ IWebFrame* frame)
+{
+ JSValueRef exception = 0;
+
+ ::layoutTestController->makeWindowObject(context, windowObject, &exception);
+ ASSERT(!exception);
+
+ m_gcController->makeWindowObject(context, windowObject, &exception);
+ ASSERT(!exception);
+
+ JSStringRef eventSenderStr = JSStringCreateWithUTF8CString("eventSender");
+ JSValueRef eventSender = makeEventSender(context);
+ JSObjectSetProperty(context, windowObject, eventSenderStr, eventSender, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, 0);
+ JSStringRelease(eventSenderStr);
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FrameLoadDelegate::didFinishDocumentLoadForFrame(
+ /* [in] */ IWebView *sender,
+ /* [in] */ IWebFrame *frame)
+{
+ if (!done && layoutTestController->dumpFrameLoadCallbacks())
+ printf("%s - didFinishDocumentLoadForFrame\n",
+ descriptionSuitableForTestResult(frame).c_str());
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FrameLoadDelegate::didHandleOnloadEventsForFrame(
+ /* [in] */ IWebView *sender,
+ /* [in] */ IWebFrame *frame)
+{
+ if (!done && layoutTestController->dumpFrameLoadCallbacks())
+ printf("%s - didHandleOnloadEventsForFrame\n",
+ descriptionSuitableForTestResult(frame).c_str());
+
+ return S_OK;
+}
+
diff --git a/WebKitTools/DumpRenderTree/win/FrameLoadDelegate.h b/WebKitTools/DumpRenderTree/win/FrameLoadDelegate.h
new file mode 100644
index 0000000..a2ba647
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/FrameLoadDelegate.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 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.
+ * 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 FrameLoadDelegate_h
+#define FrameLoadDelegate_h
+
+#include <WebKit/WebKit.h>
+#include <wtf/OwnPtr.h>
+
+class GCController;
+
+class FrameLoadDelegate : public IWebFrameLoadDelegate2, public IWebFrameLoadDelegatePrivate {
+public:
+ FrameLoadDelegate();
+ virtual ~FrameLoadDelegate();
+
+ void processWork();
+
+ // IUnknown
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
+ virtual ULONG STDMETHODCALLTYPE AddRef(void);
+ virtual ULONG STDMETHODCALLTYPE Release(void);
+
+ // IWebFrameLoadDelegate
+ virtual HRESULT STDMETHODCALLTYPE didStartProvisionalLoadForFrame(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebFrame *frame);
+
+ virtual HRESULT STDMETHODCALLTYPE didReceiveServerRedirectForProvisionalLoadForFrame(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebFrame *frame) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE didFailProvisionalLoadWithError(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebError *error,
+ /* [in] */ IWebFrame *frame);
+
+ virtual HRESULT STDMETHODCALLTYPE didCommitLoadForFrame(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebFrame *frame);
+
+ virtual HRESULT STDMETHODCALLTYPE didReceiveTitle(
+ /* [in] */ IWebView *webView,
+ /* [in] */ BSTR title,
+ /* [in] */ IWebFrame *frame);
+
+ virtual HRESULT STDMETHODCALLTYPE didReceiveIcon(
+ /* [in] */ IWebView *webView,
+ /* [in] */ OLE_HANDLE image,
+ /* [in] */ IWebFrame *frame) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE didFinishLoadForFrame(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebFrame *frame);
+
+ virtual HRESULT STDMETHODCALLTYPE didFailLoadWithError(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebError *error,
+ /* [in] */ IWebFrame *forFrame);
+
+ virtual HRESULT STDMETHODCALLTYPE didChangeLocationWithinPageForFrame(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebFrame *frame) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE willPerformClientRedirectToURL(
+ /* [in] */ IWebView *webView,
+ /* [in] */ BSTR url,
+ /* [in] */ double delaySeconds,
+ /* [in] */ DATE fireDate,
+ /* [in] */ IWebFrame *frame) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE didCancelClientRedirectForFrame(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebFrame *frame) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE willCloseFrame(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebFrame *frame);
+
+ virtual HRESULT STDMETHODCALLTYPE windowScriptObjectAvailable(
+ /* [in] */ IWebView *sender,
+ /* [in] */ JSContextRef context,
+ /* [in] */ JSObjectRef windowObject) { return E_NOTIMPL; }
+
+ // IWebFrameLoadDelegatePrivate
+ virtual HRESULT STDMETHODCALLTYPE didFinishDocumentLoadForFrame(
+ /* [in] */ IWebView *sender,
+ /* [in] */ IWebFrame *frame);
+
+ virtual HRESULT STDMETHODCALLTYPE didFirstLayoutInFrame(
+ /* [in] */ IWebView *sender,
+ /* [in] */ IWebFrame *frame) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE didHandleOnloadEventsForFrame(
+ /* [in] */ IWebView *sender,
+ /* [in] */ IWebFrame *frame);
+
+ // IWebFrameLoadDelegate2
+ virtual /* [local] */ HRESULT STDMETHODCALLTYPE didClearWindowObject(
+ /* [in] */ IWebView* webView,
+ /* [in] */ JSContextRef context,
+ /* [in] */ JSObjectRef windowObject,
+ /* [in] */ IWebFrame* frame);
+
+protected:
+ void locationChangeDone(IWebError*, IWebFrame*);
+
+ ULONG m_refCount;
+ OwnPtr<GCController> m_gcController;
+};
+
+#endif // FrameLoadDelegate_h
diff --git a/WebKitTools/DumpRenderTree/win/GCControllerWin.cpp b/WebKitTools/DumpRenderTree/win/GCControllerWin.cpp
new file mode 100644
index 0000000..24392af
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/GCControllerWin.cpp
@@ -0,0 +1,59 @@
+/*
+ * 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 "DumpRenderTree.h"
+#include "GCController.h"
+
+#include <WebCore/COMPtr.h>
+#include <WebKit/WebKit.h>
+
+void GCController::collect() const
+{
+ COMPtr<IWebJavaScriptCollector> collector;
+ if (FAILED(::CoCreateInstance(CLSID_WebJavaScriptCollector, 0, CLSCTX_ALL, IID_IWebJavaScriptCollector, (void**)&collector)))
+ return;
+ collector->collect();
+}
+
+void GCController::collectOnAlternateThread(bool waitUntilDone) const
+{
+ COMPtr<IWebJavaScriptCollector> collector;
+ if (FAILED(::CoCreateInstance(CLSID_WebJavaScriptCollector, 0, CLSCTX_ALL, IID_IWebJavaScriptCollector, (void**)&collector)))
+ return;
+ collector->collectOnAlternateThread(waitUntilDone ? TRUE : FALSE);
+}
+
+size_t GCController::getJSObjectCount() const
+{
+ COMPtr<IWebJavaScriptCollector> collector;
+ if (FAILED(::CoCreateInstance(CLSID_WebJavaScriptCollector, 0, CLSCTX_ALL, IID_IWebJavaScriptCollector, (void**)&collector)))
+ return 0;
+ UINT objects = 0;
+ collector->objectCount(&objects);
+ return objects;
+}
diff --git a/WebKitTools/DumpRenderTree/win/ImageDiff.vcproj b/WebKitTools/DumpRenderTree/win/ImageDiff.vcproj
new file mode 100644
index 0000000..2dc17c5
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/ImageDiff.vcproj
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="ImageDiff"
+ ProjectGUID="{59CC0547-70AC-499C-9B19-EC01C6F61137}"
+ RootNamespace="ImageDiff"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\include&quot;"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="CoreGraphics$(LibraryConfigSuffix).lib CoreFoundation$(LibraryConfigSuffix).lib"
+ AdditionalLibraryDirectories=""
+ SubSystem="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\release.vsprops;$(WebKitLibrariesDir)\tools\vsprops\common.vsprops"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\include&quot;"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="CoreGraphics$(LibraryConfigSuffix).lib CoreFoundation$(LibraryConfigSuffix).lib"
+ AdditionalLibraryDirectories=""
+ SubSystem="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <File
+ RelativePath="..\cg\ImageDiffCG.cpp"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp b/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp
new file mode 100644
index 0000000..373091b
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp
@@ -0,0 +1,563 @@
+/*
+ * 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.
+ */
+
+#include "DumpRenderTree.h"
+#include "LayoutTestController.h"
+
+#include "EditingDelegate.h"
+#include "PolicyDelegate.h"
+#include "WorkQueue.h"
+#include "WorkQueueItem.h"
+#include <WebCore/COMPtr.h>
+#include <wtf/Platform.h>
+#include <wtf/RetainPtr.h>
+#include <wtf/Vector.h>
+#include <JavaScriptCore/Assertions.h>
+#include <JavaScriptCore/JavaScriptCore.h>
+#include <JavaScriptCore/JSRetainPtr.h>
+#include <WebKit/WebKit.h>
+#include <string>
+#include <CoreFoundation/CoreFoundation.h>
+#include <shlwapi.h>
+#include <shlguid.h>
+#include <shobjidl.h>
+
+using std::string;
+using std::wstring;
+
+static bool resolveCygwinPath(const wstring& cygwinPath, wstring& windowsPath);
+
+LayoutTestController::~LayoutTestController()
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ // reset webview-related states back to default values in preparation for next test
+
+ COMPtr<IWebViewPrivate> viewPrivate;
+ if (SUCCEEDED(webView->QueryInterface(&viewPrivate)))
+ viewPrivate->setTabKeyCyclesThroughElements(TRUE);
+
+ COMPtr<IWebViewEditing> viewEditing;
+ if (FAILED(webView->QueryInterface(&viewEditing)))
+ return;
+ COMPtr<IWebEditingDelegate> delegate;
+ if (FAILED(viewEditing->editingDelegate(&delegate)))
+ return;
+ COMPtr<EditingDelegate> editingDelegate(Query, viewEditing.get());
+ if (editingDelegate)
+ editingDelegate->setAcceptsEditing(TRUE);
+}
+
+void LayoutTestController::addDisallowedURL(JSStringRef url)
+{
+ // FIXME: Implement!
+}
+
+void LayoutTestController::clearBackForwardList()
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ COMPtr<IWebBackForwardList> backForwardList;
+ if (FAILED(webView->backForwardList(&backForwardList)))
+ return;
+
+ COMPtr<IWebHistoryItem> item;
+ if (FAILED(backForwardList->currentItem(&item)))
+ return;
+
+ // We clear the history by setting the back/forward list's capacity to 0
+ // then restoring it back and adding back the current item.
+ int capacity;
+ if (FAILED(backForwardList->capacity(&capacity)))
+ return;
+
+ backForwardList->setCapacity(0);
+ backForwardList->setCapacity(capacity);
+ backForwardList->addItem(item.get());
+ backForwardList->goToItem(item.get());
+}
+
+JSStringRef LayoutTestController::copyDecodedHostName(JSStringRef name)
+{
+ // FIXME: Implement!
+ return 0;
+}
+
+JSStringRef LayoutTestController::copyEncodedHostName(JSStringRef name)
+{
+ // FIXME: Implement!
+ return 0;
+}
+
+void LayoutTestController::display()
+{
+ displayWebView();
+}
+
+void LayoutTestController::keepWebHistory()
+{
+ COMPtr<IWebHistory> history(Create, CLSID_WebHistory);
+ if (!history)
+ return;
+
+ COMPtr<IWebHistory> sharedHistory(Create, CLSID_WebHistory);
+ if (!sharedHistory)
+ return;
+
+ history->setOptionalSharedHistory(sharedHistory.get());
+}
+
+void LayoutTestController::notifyDone()
+{
+ // Same as on mac. This can be shared.
+ if (m_waitToDump && !topLoadingFrame && !WorkQueue::shared()->count())
+ dump();
+ m_waitToDump = false;
+}
+
+JSStringRef LayoutTestController::pathToLocalResource(JSContextRef context, JSStringRef url)
+{
+ wstring input(JSStringGetCharactersPtr(url), JSStringGetLength(url));
+
+ wstring localPath;
+ if (!resolveCygwinPath(input, localPath)) {
+ printf("ERROR: Failed to resolve Cygwin path %S\n", input.c_str());
+ return 0;
+ }
+
+ return JSStringCreateWithCharacters(localPath.c_str(), localPath.length());
+}
+
+void LayoutTestController::queueBackNavigation(int howFarBack)
+{
+ // Same as on mac. This can be shared.
+ WorkQueue::shared()->queue(new BackItem(howFarBack));
+}
+
+void LayoutTestController::queueForwardNavigation(int howFarForward)
+{
+ // Same as on mac. This can be shared.
+ WorkQueue::shared()->queue(new ForwardItem(howFarForward));
+}
+
+static wstring jsStringRefToWString(JSStringRef jsStr)
+{
+ size_t length = JSStringGetLength(jsStr);
+ Vector<WCHAR> buffer(length + 1);
+ memcpy(buffer.data(), JSStringGetCharactersPtr(jsStr), length * sizeof(WCHAR));
+ buffer[length] = '\0';
+
+ return buffer.data();
+}
+
+void LayoutTestController::queueLoad(JSStringRef url, JSStringRef target)
+{
+ COMPtr<IWebDataSource> dataSource;
+ if (FAILED(frame->dataSource(&dataSource)))
+ return;
+
+ COMPtr<IWebURLResponse> response;
+ if (FAILED(dataSource->response(&response)) || !response)
+ return;
+
+ BSTR responseURLBSTR;
+ if (FAILED(response->URL(&responseURLBSTR)))
+ return;
+ wstring responseURL(responseURLBSTR, SysStringLen(responseURLBSTR));
+ SysFreeString(responseURLBSTR);
+
+ // FIXME: We should do real relative URL resolution here.
+ int lastSlash = responseURL.rfind('/');
+ if (lastSlash != -1)
+ responseURL = responseURL.substr(0, lastSlash);
+
+ wstring wURL = jsStringRefToWString(url);
+ wstring wAbsoluteURL = responseURL + TEXT("/") + wURL;
+ JSRetainPtr<JSStringRef> jsAbsoluteURL(Adopt, JSStringCreateWithCharacters(wAbsoluteURL.data(), wAbsoluteURL.length()));
+
+ WorkQueue::shared()->queue(new LoadItem(jsAbsoluteURL.get(), target));
+}
+
+void LayoutTestController::queueReload()
+{
+ WorkQueue::shared()->queue(new ReloadItem);
+}
+
+void LayoutTestController::queueScript(JSStringRef script)
+{
+ WorkQueue::shared()->queue(new ScriptItem(script));
+}
+
+void LayoutTestController::setAcceptsEditing(bool acceptsEditing)
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ COMPtr<IWebViewEditing> viewEditing;
+ if (FAILED(webView->QueryInterface(&viewEditing)))
+ return;
+
+ COMPtr<IWebEditingDelegate> delegate;
+ if (FAILED(viewEditing->editingDelegate(&delegate)))
+ return;
+
+ EditingDelegate* editingDelegate = (EditingDelegate*)(IWebEditingDelegate*)delegate.get();
+ editingDelegate->setAcceptsEditing(acceptsEditing);
+}
+
+void LayoutTestController::setAuthorAndUserStylesEnabled(bool flag)
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ COMPtr<IWebPreferences> preferences;
+ if (FAILED(webView->preferences(&preferences)))
+ return;
+
+ COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences);
+ if (!prefsPrivate)
+ return;
+
+ prefsPrivate->setAuthorAndUserStylesEnabled(flag);
+}
+
+void LayoutTestController::setCustomPolicyDelegate(bool setDelegate)
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ if (setDelegate)
+ webView->setPolicyDelegate(policyDelegate);
+ else
+ webView->setPolicyDelegate(NULL);
+}
+
+void LayoutTestController::setMainFrameIsFirstResponder(bool flag)
+{
+ // FIXME: Implement!
+}
+
+void LayoutTestController::setPrivateBrowsingEnabled(bool privateBrowsingEnabled)
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ COMPtr<IWebPreferences> preferences;
+ if (FAILED(webView->preferences(&preferences)))
+ return;
+
+ preferences->setPrivateBrowsingEnabled(privateBrowsingEnabled);
+}
+
+void LayoutTestController::setPopupBlockingEnabled(bool privateBrowsingEnabled)
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ COMPtr<IWebPreferences> preferences;
+ if (FAILED(webView->preferences(&preferences)))
+ return;
+
+ preferences->setJavaScriptCanOpenWindowsAutomatically(!privateBrowsingEnabled);
+}
+
+void LayoutTestController::setTabKeyCyclesThroughElements(bool shouldCycle)
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ COMPtr<IWebViewPrivate> viewPrivate;
+ if (FAILED(webView->QueryInterface(&viewPrivate)))
+ return;
+
+ viewPrivate->setTabKeyCyclesThroughElements(shouldCycle ? TRUE : FALSE);
+}
+
+void LayoutTestController::setUseDashboardCompatibilityMode(bool flag)
+{
+ // FIXME: Implement!
+}
+
+void LayoutTestController::setUserStyleSheetEnabled(bool flag)
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ COMPtr<IWebPreferences> preferences;
+ if (FAILED(webView->preferences(&preferences)))
+ return;
+
+ preferences->setUserStyleSheetEnabled(flag);
+}
+
+bool appendComponentToPath(wstring& path, const wstring& component)
+{
+ WCHAR buffer[MAX_PATH];
+
+ if (path.size() + 1 > MAX_PATH)
+ return false;
+
+ memcpy(buffer, path.data(), path.size() * sizeof(WCHAR));
+ buffer[path.size()] = '\0';
+
+ if (!PathAppendW(buffer, component.c_str()))
+ return false;
+
+ path = wstring(buffer);
+ return true;
+}
+
+static bool followShortcuts(wstring& path)
+{
+ if (PathFileExists(path.c_str()))
+ return true;
+
+ // Do we have a shortcut?
+ path.append(TEXT(".lnk"));
+ if (!PathFileExists(path.c_str()))
+ return false;
+
+ // We have a shortcut, find its target.
+ COMPtr<IShellLink> shortcut(Create, CLSID_ShellLink);
+ if (!shortcut)
+ return false;
+ COMPtr<IPersistFile> persistFile(Query, shortcut);
+ if (!shortcut)
+ return false;
+ if (FAILED(persistFile->Load(path.c_str(), STGM_READ)))
+ return false;
+ if (FAILED(shortcut->Resolve(0, 0)))
+ return false;
+ WCHAR targetPath[MAX_PATH];
+ DWORD targetPathLen = _countof(targetPath);
+ if (FAILED(shortcut->GetPath(targetPath, targetPathLen, 0, 0)))
+ return false;
+ if (!PathFileExists(targetPath))
+ return false;
+ // Use the target path as the result path instead.
+ path = wstring(targetPath);
+
+ return true;
+}
+
+static bool resolveCygwinPath(const wstring& cygwinPath, wstring& windowsPath)
+{
+ wstring fileProtocol = L"file://";
+ bool isFileProtocol = cygwinPath.find(fileProtocol) != string::npos;
+ if (cygwinPath[isFileProtocol ? 7 : 0] != '/') // ensure path is absolute
+ return false;
+
+ // Get the Root path.
+ WCHAR rootPath[MAX_PATH];
+ DWORD rootPathSize = _countof(rootPath);
+ DWORD keyType;
+ DWORD result = ::SHGetValueW(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Cygnus Solutions\\Cygwin\\mounts v2\\/"), TEXT("native"), &keyType, &rootPath, &rootPathSize);
+
+ if (result != ERROR_SUCCESS || keyType != REG_SZ)
+ return false;
+
+ windowsPath = wstring(rootPath, rootPathSize);
+
+ int oldPos = isFileProtocol ? 8 : 1;
+ while (1) {
+ int newPos = cygwinPath.find('/', oldPos);
+
+ if (newPos == -1) {
+ wstring pathComponent = cygwinPath.substr(oldPos);
+
+ if (!appendComponentToPath(windowsPath, pathComponent))
+ return false;
+
+ if (!followShortcuts(windowsPath))
+ return false;
+
+ break;
+ }
+
+ wstring pathComponent = cygwinPath.substr(oldPos, newPos - oldPos);
+ if (!appendComponentToPath(windowsPath, pathComponent))
+ return false;
+
+ if (!followShortcuts(windowsPath))
+ return false;
+
+ oldPos = newPos + 1;
+ }
+
+ if (isFileProtocol)
+ windowsPath = fileProtocol + windowsPath;
+
+ return true;
+}
+
+static wstring cfStringRefToWString(CFStringRef cfStr)
+{
+ Vector<wchar_t> v(CFStringGetLength(cfStr));
+ CFStringGetCharacters(cfStr, CFRangeMake(0, CFStringGetLength(cfStr)), (UniChar *)v.data());
+
+ return wstring(v.data(), v.size());
+}
+
+void LayoutTestController::setUserStyleSheetLocation(JSStringRef jsURL)
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ COMPtr<IWebPreferences> preferences;
+ if (FAILED(webView->preferences(&preferences)))
+ return;
+
+ RetainPtr<CFStringRef> urlString(AdoptCF, JSStringCopyCFString(0, jsURL));
+ RetainPtr<CFURLRef> url(AdoptCF, CFURLCreateWithString(0, urlString.get(), 0));
+ if (!url)
+ return;
+
+ // Now copy the file system path, POSIX style.
+ RetainPtr<CFStringRef> pathCF(AdoptCF, CFURLCopyFileSystemPath(url.get(), kCFURLPOSIXPathStyle));
+ if (!pathCF)
+ return;
+
+ wstring path = cfStringRefToWString(pathCF.get());
+
+ wstring resultPath;
+ if (!resolveCygwinPath(path, resultPath))
+ return;
+
+ // The path has been resolved, now convert it back to a CFURL.
+ int result = WideCharToMultiByte(CP_UTF8, 0, resultPath.c_str(), resultPath.size() + 1, 0, 0, 0, 0);
+ Vector<char> utf8Vector(result);
+ result = WideCharToMultiByte(CP_UTF8, 0, resultPath.c_str(), resultPath.size() + 1, utf8Vector.data(), result, 0, 0);
+ if (!result)
+ return;
+
+ url = CFURLCreateFromFileSystemRepresentation(0, (const UInt8*)utf8Vector.data(), utf8Vector.size() - 1, false);
+ if (!url)
+ return;
+
+ resultPath = cfStringRefToWString(CFURLGetString(url.get()));
+
+ BSTR resultPathBSTR = SysAllocStringLen(resultPath.data(), resultPath.size());
+ preferences->setUserStyleSheetLocation(resultPathBSTR);
+ SysFreeString(resultPathBSTR);
+}
+
+void LayoutTestController::setPersistentUserStyleSheetLocation(JSStringRef jsURL)
+{
+ RetainPtr<CFStringRef> urlString(AdoptCF, JSStringCopyCFString(0, jsURL));
+ ::setPersistentUserStyleSheetLocation(urlString.get());
+}
+
+void LayoutTestController::clearPersistentUserStyleSheet()
+{
+ ::setPersistentUserStyleSheetLocation(0);
+}
+
+void LayoutTestController::setWindowIsKey(bool flag)
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ COMPtr<IWebViewPrivate> viewPrivate;
+ if (FAILED(webView->QueryInterface(&viewPrivate)))
+ return;
+
+ HWND webViewWindow;
+ if (FAILED(viewPrivate->viewWindow((OLE_HANDLE*)&webViewWindow)))
+ return;
+
+ ::SendMessage(webViewWindow, flag ? WM_SETFOCUS : WM_KILLFOCUS, (WPARAM)::GetDesktopWindow(), 0);
+}
+
+static const CFTimeInterval waitToDumpWatchdogInterval = 10.0;
+
+static void waitUntilDoneWatchdogFired(CFRunLoopTimerRef timer, void* info)
+{
+ const char* message = "FAIL: Timed out waiting for notifyDone to be called\n";
+ fprintf(stderr, message);
+ fprintf(stdout, message);
+ dump();
+}
+
+void LayoutTestController::setWaitToDump(bool waitUntilDone)
+{
+ // Same as on mac. This can be shared.
+ m_waitToDump = waitUntilDone;
+ if (m_waitToDump && !waitToDumpWatchdog) {
+ waitToDumpWatchdog = CFRunLoopTimerCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent() + waitToDumpWatchdogInterval, 0, 0, 0, waitUntilDoneWatchdogFired, NULL);
+ CFRunLoopAddTimer(CFRunLoopGetCurrent(), waitToDumpWatchdog, kCFRunLoopCommonModes);
+ }
+}
+
+int LayoutTestController::windowCount()
+{
+ return openWindows().size();
+}
+
+void LayoutTestController::execCommand(JSStringRef name, JSStringRef value)
+{
+ wstring wName = jsStringRefToWString(name);
+ wstring wValue = jsStringRefToWString(value);
+
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ COMPtr<IWebViewPrivate> viewPrivate;
+ if (FAILED(webView->QueryInterface(&viewPrivate)))
+ return;
+
+ BSTR nameBSTR = SysAllocStringLen((OLECHAR*)wName.c_str(), wName.length());
+ BSTR valueBSTR = SysAllocStringLen((OLECHAR*)wValue.c_str(), wValue.length());
+ viewPrivate->executeCoreCommandByName(nameBSTR, valueBSTR);
+
+ SysFreeString(nameBSTR);
+ SysFreeString(valueBSTR);
+}
+
+void LayoutTestController::clearAllDatabases()
+{
+ printf("ERROR: LayoutTestController::clearAllDatabases() not implemented\n");
+}
+
+void LayoutTestController::setDatabaseQuota(unsigned long long quota)
+{
+ printf("ERROR: LayoutTestController::setDatabaseQuota() not implemented\n");
+}
diff --git a/WebKitTools/DumpRenderTree/win/MD5.cpp b/WebKitTools/DumpRenderTree/win/MD5.cpp
new file mode 100644
index 0000000..4d4c848
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/MD5.cpp
@@ -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.
+ */
+
+#include "MD5.h"
+
+#include <windows.h>
+
+typedef void (WINAPI*initPtr)(MD5_CTX*);
+typedef void (WINAPI*updatePtr)(MD5_CTX*, unsigned char*, unsigned);
+typedef void (WINAPI*finalPtr)(MD5_CTX*);
+
+static HMODULE cryptDLL()
+{
+ static HMODULE module = LoadLibraryW(L"Cryptdll.dll");
+ return module;
+}
+
+static initPtr init()
+{
+ static initPtr ptr = reinterpret_cast<initPtr>(GetProcAddress(cryptDLL(), "MD5Init"));
+ return ptr;
+}
+
+static updatePtr update()
+{
+ static updatePtr ptr = reinterpret_cast<updatePtr>(GetProcAddress(cryptDLL(), "MD5Update"));
+ return ptr;
+}
+
+static finalPtr final()
+{
+ static finalPtr ptr = reinterpret_cast<finalPtr>(GetProcAddress(cryptDLL(), "MD5Final"));
+ return ptr;
+}
+
+void MD5_Init(MD5_CTX* context)
+{
+ init()(context);
+}
+
+void MD5_Update(MD5_CTX* context, unsigned char* input, unsigned length)
+{
+ update()(context, input, length);
+}
+
+void MD5_Final(unsigned char hash[16], MD5_CTX* context)
+{
+ final()(context);
+
+ for (int i = 0; i < 16; ++i)
+ hash[i] = context->digest[i];
+}
diff --git a/WebKitTools/DumpRenderTree/win/MD5.h b/WebKitTools/DumpRenderTree/win/MD5.h
new file mode 100644
index 0000000..326e21d
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/MD5.h
@@ -0,0 +1,45 @@
+/*
+ * 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 MD5_h
+#define MD5_h
+
+typedef unsigned long ULONG;
+
+struct MD5_CTX {
+ ULONG i[2];
+ ULONG buf[4];
+ unsigned char in[64];
+ unsigned char digest[16];
+};
+
+void MD5_Init(MD5_CTX*);
+void MD5_Update(MD5_CTX*, unsigned char* input, unsigned length);
+void MD5_Final(unsigned char hash[16], MD5_CTX*);
+
+#endif // MD5_h
diff --git a/WebKitTools/DumpRenderTree/win/PixelDumpSupportWin.cpp b/WebKitTools/DumpRenderTree/win/PixelDumpSupportWin.cpp
new file mode 100644
index 0000000..f6dd82d
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/PixelDumpSupportWin.cpp
@@ -0,0 +1,67 @@
+/*
+ * 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 "DumpRenderTree.h"
+#include "PixelDumpSupportCG.h"
+
+#include <CoreGraphics/CGBitmapContext.h>
+#include <wtf/Assertions.h>
+#include <wtf/RetainPtr.h>
+
+RetainPtr<CGContextRef> getBitmapContextFromWebView()
+{
+ RECT frame;
+ if (!GetWindowRect(webViewWindow, &frame))
+ return 0;
+
+ BITMAPINFO bmp = {0};
+ bmp.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmp.bmiHeader.biWidth = frame.right - frame.left;
+ bmp.bmiHeader.biHeight = -(frame.bottom - frame.top);
+ bmp.bmiHeader.biPlanes = 1;
+ bmp.bmiHeader.biBitCount = 32;
+ bmp.bmiHeader.biCompression = BI_RGB;
+
+ // FIXME: Currently we leak this HBITMAP because we don't have a good way
+ // to destroy it when the CGBitmapContext gets destroyed.
+ void* bits = 0;
+ HBITMAP bitmap = CreateDIBSection(0, &bmp, DIB_RGB_COLORS, &bits, 0, 0);
+
+ HDC memoryDC = CreateCompatibleDC(0);
+ SelectObject(memoryDC, bitmap);
+ SendMessage(webViewWindow, WM_PRINTCLIENT, reinterpret_cast<WPARAM>(memoryDC), PRF_CLIENT | PRF_CHILDREN | PRF_OWNED);
+ DeleteDC(memoryDC);
+
+ BITMAP info = {0};
+ GetObject(bitmap, sizeof(info), &info);
+ ASSERT(info.bmBitsPixel == 32);
+
+ RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
+ return RetainPtr<CGContextRef>(AdoptCF, CGBitmapContextCreate(info.bmBits, info.bmWidth, info.bmHeight, 8,
+ info.bmWidthBytes, colorSpace.get(), kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst));
+}
diff --git a/WebKitTools/DumpRenderTree/win/PolicyDelegate.cpp b/WebKitTools/DumpRenderTree/win/PolicyDelegate.cpp
new file mode 100644
index 0000000..c6a9fb0
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/PolicyDelegate.cpp
@@ -0,0 +1,85 @@
+/*
+ * 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 "DumpRenderTree.h"
+#include "PolicyDelegate.h"
+
+#include <string>
+
+using std::wstring;
+
+PolicyDelegate::PolicyDelegate()
+ : m_refCount(1)
+{
+}
+
+// IUnknown
+HRESULT STDMETHODCALLTYPE PolicyDelegate::QueryInterface(REFIID riid, void** ppvObject)
+{
+ *ppvObject = 0;
+ if (IsEqualGUID(riid, IID_IUnknown))
+ *ppvObject = static_cast<IWebPolicyDelegate*>(this);
+ else if (IsEqualGUID(riid, IID_IWebPolicyDelegate))
+ *ppvObject = static_cast<IWebPolicyDelegate*>(this);
+ else
+ return E_NOINTERFACE;
+
+ AddRef();
+ return S_OK;
+}
+
+ULONG STDMETHODCALLTYPE PolicyDelegate::AddRef(void)
+{
+ return ++m_refCount;
+}
+
+ULONG STDMETHODCALLTYPE PolicyDelegate::Release(void)
+{
+ ULONG newRef = --m_refCount;
+ if (!newRef)
+ delete this;
+
+ return newRef;
+}
+
+HRESULT STDMETHODCALLTYPE PolicyDelegate::decidePolicyForNavigationAction(
+ /*[in]*/ IWebView* /*webView*/,
+ /*[in]*/ IPropertyBag* /*actionInformation*/,
+ /*[in]*/ IWebURLRequest* request,
+ /*[in]*/ IWebFrame* frame,
+ /*[in]*/ IWebPolicyDecisionListener* listener)
+{
+ BSTR url;
+ request->URL(&url);
+
+ printf("Policy delegate: attempt to load %S\n", url ? url : TEXT(""));
+ SysFreeString(url);
+ listener->ignore();
+
+ return S_OK;
+}
diff --git a/WebKitTools/DumpRenderTree/win/PolicyDelegate.h b/WebKitTools/DumpRenderTree/win/PolicyDelegate.h
new file mode 100644
index 0000000..b9844f4
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/PolicyDelegate.h
@@ -0,0 +1,74 @@
+/*
+ * 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 PolicyDelegate_h
+#define PolicyDelegate_h
+
+#include <WebKit/WebKit.h>
+
+class PolicyDelegate : public IWebPolicyDelegate {
+public:
+ PolicyDelegate();
+
+ // IUnknown
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
+ virtual ULONG STDMETHODCALLTYPE AddRef(void);
+ virtual ULONG STDMETHODCALLTYPE Release(void);
+
+ // IWebPolicyDelegate
+ virtual HRESULT STDMETHODCALLTYPE decidePolicyForNavigationAction(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IPropertyBag *actionInformation,
+ /* [in] */ IWebURLRequest *request,
+ /* [in] */ IWebFrame *frame,
+ /* [in] */ IWebPolicyDecisionListener *listener);
+
+ virtual HRESULT STDMETHODCALLTYPE decidePolicyForNewWindowAction(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IPropertyBag *actionInformation,
+ /* [in] */ IWebURLRequest *request,
+ /* [in] */ BSTR frameName,
+ /* [in] */ IWebPolicyDecisionListener *listener){ return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE decidePolicyForMIMEType(
+ /* [in] */ IWebView *webView,
+ /* [in] */ BSTR type,
+ /* [in] */ IWebURLRequest *request,
+ /* [in] */ IWebFrame *frame,
+ /* [in] */ IWebPolicyDecisionListener *listener){ return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE unableToImplementPolicyWithError(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebError *error,
+ /* [in] */ IWebFrame *frame){ return E_NOTIMPL; }
+
+private:
+ ULONG m_refCount;
+};
+
+#endif // PolicyDelegate_h
diff --git a/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.cpp b/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.cpp
new file mode 100644
index 0000000..0f15648
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.cpp
@@ -0,0 +1,256 @@
+/*
+ * 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 "DumpRenderTree.h"
+#include "ResourceLoadDelegate.h"
+
+#include "LayoutTestController.h"
+#include <wtf/HashMap.h>
+#include <wtf/Vector.h>
+#include <sstream>
+
+using std::wstring;
+using std::wiostream;
+
+static inline wstring wstringFromBSTR(BSTR str)
+{
+ return wstring(str, ::SysStringLen(str));
+}
+
+wstring wstringFromInt(int i)
+{
+ std::wostringstream ss;
+ ss << i;
+ return ss.str();
+}
+
+typedef HashMap<unsigned long, wstring> IdentifierMap;
+
+IdentifierMap& urlMap()
+{
+ static IdentifierMap urlMap;
+
+ return urlMap;
+}
+
+static wstring descriptionSuitableForTestResult(unsigned long identifier)
+{
+ IdentifierMap::iterator it = urlMap().find(identifier);
+
+ if (it == urlMap().end())
+ return L"<unknown>";
+
+ return urlSuitableForTestResult(it->second);
+}
+
+static wstring descriptionSuitableForTestResult(IWebURLRequest* request)
+{
+ if (!request)
+ return L"(null)";
+
+ BSTR urlBSTR;
+ if (FAILED(request->URL(&urlBSTR)))
+ return wstring();
+
+ wstring url = urlSuitableForTestResult(wstringFromBSTR(urlBSTR));
+ ::SysFreeString(urlBSTR);
+
+ return L"<NSURLRequest " + url + L">";
+}
+
+static wstring descriptionSuitableForTestResult(IWebURLResponse* response)
+{
+ if (!response)
+ return L"(null)";
+
+ BSTR urlBSTR;
+ if (FAILED(response->URL(&urlBSTR)))
+ return wstring();
+
+ wstring url = urlSuitableForTestResult(wstringFromBSTR(urlBSTR));
+ ::SysFreeString(urlBSTR);
+
+ return L"<NSURLResponse " + url + L">";
+}
+
+static wstring descriptionSuitableForTestResult(IWebError* error, unsigned long identifier)
+{
+ wstring result = L"<NSError ";
+
+ BSTR domainSTR;
+ if (FAILED(error->domain(&domainSTR)))
+ return wstring();
+
+ wstring domain = wstringFromBSTR(domainSTR);
+ ::SysFreeString(domainSTR);
+
+ int code;
+ if (FAILED(error->code(&code)))
+ return wstring();
+
+ if (domain == L"CFURLErrorDomain") {
+ domain = L"NSURLErrorDomain";
+
+ // Convert kCFURLErrorUnknown to NSURLErrorUnknown
+ if (code == -998)
+ code = -1;
+ } else if (domain == L"kCFErrorDomainWinSock") {
+ domain = L"NSURLErrorDomain";
+
+ // Convert the winsock error code to an NSURLError code.
+ if (code == WSAEADDRNOTAVAIL)
+ code = -1004; // NSURLErrorCannotConnectToHose;
+ }
+
+ result += L"domain " + domain;
+ result += L", code " + wstringFromInt(code);
+
+ BSTR failingURLSTR;
+ if (FAILED(error->failingURL(&failingURLSTR)))
+ return wstring();
+
+ wstring failingURL;
+
+ // If the error doesn't have a failing URL, we fake one by using the URL the resource had
+ // at creation time. This seems to work fine for now.
+ // See <rdar://problem/5064234> CFErrors should have failingURL key.
+ if (failingURLSTR)
+ failingURL = wstringFromBSTR(failingURLSTR);
+ else
+ failingURL = descriptionSuitableForTestResult(identifier);
+
+ ::SysFreeString(failingURLSTR);
+
+ result += L", failing URL \"" + urlSuitableForTestResult(failingURL) + L"\">";
+
+ return result;
+}
+
+ResourceLoadDelegate::ResourceLoadDelegate()
+ : m_refCount(1)
+{
+}
+
+ResourceLoadDelegate::~ResourceLoadDelegate()
+{
+}
+
+HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::QueryInterface(REFIID riid, void** ppvObject)
+{
+ *ppvObject = 0;
+ if (IsEqualGUID(riid, IID_IUnknown))
+ *ppvObject = static_cast<IWebResourceLoadDelegate*>(this);
+ else if (IsEqualGUID(riid, IID_IWebResourceLoadDelegate))
+ *ppvObject = static_cast<IWebResourceLoadDelegate*>(this);
+ else
+ return E_NOINTERFACE;
+
+ AddRef();
+ return S_OK;
+}
+
+ULONG STDMETHODCALLTYPE ResourceLoadDelegate::AddRef(void)
+{
+ return ++m_refCount;
+}
+
+ULONG STDMETHODCALLTYPE ResourceLoadDelegate::Release(void)
+{
+ ULONG newRef = --m_refCount;
+ if (!newRef)
+ delete(this);
+
+ return newRef;
+}
+
+HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::identifierForInitialRequest(
+ /* [in] */ IWebView* webView,
+ /* [in] */ IWebURLRequest* request,
+ /* [in] */ IWebDataSource* dataSource,
+ /* [in] */ unsigned long identifier)
+{
+ if (!done && layoutTestController->dumpResourceLoadCallbacks()) {
+ BSTR urlStr;
+ if (FAILED(request->URL(&urlStr)))
+ return E_FAIL;
+
+ urlMap().set(identifier, wstringFromBSTR(urlStr));
+ }
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::willSendRequest(
+ /* [in] */ IWebView* webView,
+ /* [in] */ unsigned long identifier,
+ /* [in] */ IWebURLRequest* request,
+ /* [in] */ IWebURLResponse* redirectResponse,
+ /* [in] */ IWebDataSource* dataSource,
+ /* [retval][out] */ IWebURLRequest **newRequest)
+{
+ if (!done && layoutTestController->dumpResourceLoadCallbacks()) {
+ printf("%S - willSendRequest %S redirectResponse %S\n",
+ descriptionSuitableForTestResult(identifier).c_str(),
+ descriptionSuitableForTestResult(request).c_str(),
+ descriptionSuitableForTestResult(redirectResponse).c_str());
+ }
+
+ request->AddRef();
+ *newRequest = request;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::didFinishLoadingFromDataSource(
+ /* [in] */ IWebView* webView,
+ /* [in] */ unsigned long identifier,
+ /* [in] */ IWebDataSource* dataSource)
+{
+ if (!done && layoutTestController->dumpResourceLoadCallbacks()) {
+ printf("%S - didFinishLoading\n",
+ descriptionSuitableForTestResult(identifier).c_str()),
+ urlMap().remove(identifier);
+ }
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::didFailLoadingWithError(
+ /* [in] */ IWebView* webView,
+ /* [in] */ unsigned long identifier,
+ /* [in] */ IWebError* error,
+ /* [in] */ IWebDataSource* dataSource)
+{
+ if (!done && layoutTestController->dumpResourceLoadCallbacks()) {
+ printf("%S - didFailLoadingWithError: %S\n",
+ descriptionSuitableForTestResult(identifier).c_str(),
+ descriptionSuitableForTestResult(error, identifier).c_str());
+ urlMap().remove(identifier);
+ }
+
+ return S_OK;
+}
diff --git a/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.h b/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.h
new file mode 100644
index 0000000..e259adc
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.h
@@ -0,0 +1,103 @@
+/*
+ * 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 ResourceLoadDelegate_h
+#define ResourceLoadDelegate_h
+
+#include <WebKit/WebKit.h>
+
+class ResourceLoadDelegate : public IWebResourceLoadDelegate {
+public:
+ ResourceLoadDelegate();
+ virtual ~ResourceLoadDelegate();
+
+ // IUnknown
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
+ virtual ULONG STDMETHODCALLTYPE AddRef(void);
+ virtual ULONG STDMETHODCALLTYPE Release(void);
+
+ // IWebResourceLoadDelegate
+ virtual HRESULT STDMETHODCALLTYPE identifierForInitialRequest(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebURLRequest *request,
+ /* [in] */ IWebDataSource *dataSource,
+ /* [in] */ unsigned long identifier);
+
+ virtual HRESULT STDMETHODCALLTYPE willSendRequest(
+ /* [in] */ IWebView *webView,
+ /* [in] */ unsigned long identifier,
+ /* [in] */ IWebURLRequest *request,
+ /* [in] */ IWebURLResponse *redirectResponse,
+ /* [in] */ IWebDataSource *dataSource,
+ /* [retval][out] */ IWebURLRequest **newRequest);
+
+ virtual HRESULT STDMETHODCALLTYPE didReceiveAuthenticationChallenge(
+ /* [in] */ IWebView *webView,
+ /* [in] */ unsigned long identifier,
+ /* [in] */ IWebURLAuthenticationChallenge *challenge,
+ /* [in] */ IWebDataSource *dataSource) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE didCancelAuthenticationChallenge(
+ /* [in] */ IWebView *webView,
+ /* [in] */ unsigned long identifier,
+ /* [in] */ IWebURLAuthenticationChallenge *challenge,
+ /* [in] */ IWebDataSource *dataSource) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE didReceiveResponse(
+ /* [in] */ IWebView *webView,
+ /* [in] */ unsigned long identifier,
+ /* [in] */ IWebURLResponse *response,
+ /* [in] */ IWebDataSource *dataSource) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE didReceiveContentLength(
+ /* [in] */ IWebView *webView,
+ /* [in] */ unsigned long identifier,
+ /* [in] */ UINT length,
+ /* [in] */ IWebDataSource *dataSource) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE didFinishLoadingFromDataSource(
+ /* [in] */ IWebView *webView,
+ /* [in] */ unsigned long identifier,
+ /* [in] */ IWebDataSource *dataSource);
+
+ virtual HRESULT STDMETHODCALLTYPE didFailLoadingWithError(
+ /* [in] */ IWebView *webView,
+ /* [in] */ unsigned long identifier,
+ /* [in] */ IWebError *error,
+ /* [in] */ IWebDataSource *dataSource);
+
+ virtual HRESULT STDMETHODCALLTYPE plugInFailedWithError(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebError *error,
+ /* [in] */ IWebDataSource *dataSource) { return E_NOTIMPL; }
+
+protected:
+ ULONG m_refCount;
+};
+
+#endif // ResourceLoadDelegate_h
diff --git a/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/TestNetscapePlugin.def b/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/TestNetscapePlugin.def
new file mode 100644
index 0000000..92cdb12
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/TestNetscapePlugin.def
@@ -0,0 +1,6 @@
+LIBRARY "TestNetscapePlugin"
+
+EXPORTS
+ NP_GetEntryPoints @1
+ NP_Initialize @2
+ NP_Shutdown @3
diff --git a/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/TestNetscapePlugin.rc b/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/TestNetscapePlugin.rc
new file mode 100644
index 0000000..7801de9
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/TestNetscapePlugin.rc
@@ -0,0 +1,101 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION 1,0,0,1
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904e4"
+ BEGIN
+ VALUE "CompanyName", "Apple Inc."
+ VALUE "FileDescription", "TestNetscapePlugIn"
+ VALUE "FileOpenName", "test netscape content"
+ VALUE "LegalCopyright", "Copyright Apple Inc. 2007-2008"
+ VALUE "MIMEType", "application/x-webkit-test-netscape"
+ VALUE "OriginalFilename", "npTestNetscapePlugin.dll"
+ VALUE "ProductName", "TestNetscapePlugIn"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1252
+ END
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/TestNetscapePlugin.vcproj b/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/TestNetscapePlugin.vcproj
new file mode 100644
index 0000000..0bc77f6
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/TestNetscapePlugin.vcproj
@@ -0,0 +1,257 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8,00"
+ Name="TestNetscapePlugin"
+ ProjectGUID="{C0737398-3565-439E-A2B8-AB2BE4D5430C}"
+ RootNamespace="TestNetscapePlugin"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders&quot;;&quot;$(ProjectDir)..\..\TestNetscapePlugin.subproj&quot;"
+ PreprocessorDefinitions="_USRDLL;TESTNETSCAPEPLUGIN_EXPORTS;snprintf=_snprintf"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories=""
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\$(ProjectName)$(WebKitConfigSuffix)\np$(ProjectName)$(WebKitConfigSuffix).dll"
+ ModuleDefinitionFile="TestNetscapePlugin.def"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\release.vsprops"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders&quot;;&quot;$(ProjectDir)..\..\TestNetscapePlugin.subproj&quot;"
+ PreprocessorDefinitions="_USRDLL;TESTNETSCAPEPLUGIN_EXPORTS;snprintf=_snprintf"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories=""
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\$(ProjectName)$(WebKitConfigSuffix)\np$(ProjectName)$(WebKitConfigSuffix).dll"
+ ModuleDefinitionFile="TestNetscapePlugin.def"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug_Internal|Win32"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_internal.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders&quot;;&quot;$(ProjectDir)..\..\TestNetscapePlugin.subproj&quot;"
+ PreprocessorDefinitions="_USRDLL;TESTNETSCAPEPLUGIN_EXPORTS;snprintf=_snprintf"
+ RuntimeLibrary="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories=""
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\$(ProjectName)$(WebKitConfigSuffix)\np$(ProjectName)$(WebKitConfigSuffix).dll"
+ ModuleDefinitionFile="TestNetscapePlugin.def"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <File
+ RelativePath=".\main.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\TestNetscapePlugIn.subproj\PluginObject.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\TestNetscapePlugIn.subproj\PluginObject.h"
+ >
+ </File>
+ <File
+ RelativePath=".\resource.h"
+ >
+ </File>
+ <File
+ RelativePath=".\TestNetscapePlugin.def"
+ >
+ </File>
+ <File
+ RelativePath=".\TestNetscapePlugin.rc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\TestNetscapePlugIn.subproj\TestObject.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\TestNetscapePlugIn.subproj\TestObject.h"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/main.c b/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/main.c
new file mode 100644
index 0000000..829a32c
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/main.c
@@ -0,0 +1,183 @@
+/*
+ * 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.
+ *
+ * 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 "PluginObject.h"
+
+#include <stdio.h>
+
+extern "C"
+NPError __stdcall NP_Initialize(NPNetscapeFuncs* browserFuncs)
+{
+ browser = browserFuncs;
+ return NPERR_NO_ERROR;
+}
+
+extern "C"
+NPError __stdcall NP_GetEntryPoints(NPPluginFuncs* pluginFuncs)
+{
+ pluginFuncs->version = 11;
+ pluginFuncs->size = sizeof(pluginFuncs);
+ pluginFuncs->newp = NPP_New;
+ pluginFuncs->destroy = NPP_Destroy;
+ pluginFuncs->setwindow = NPP_SetWindow;
+ pluginFuncs->newstream = NPP_NewStream;
+ pluginFuncs->destroystream = NPP_DestroyStream;
+ pluginFuncs->asfile = NPP_StreamAsFile;
+ pluginFuncs->writeready = NPP_WriteReady;
+ pluginFuncs->write = (NPP_WriteProcPtr)NPP_Write;
+ pluginFuncs->print = NPP_Print;
+ pluginFuncs->event = NPP_HandleEvent;
+ pluginFuncs->urlnotify = NPP_URLNotify;
+ pluginFuncs->getvalue = NPP_GetValue;
+ pluginFuncs->setvalue = NPP_SetValue;
+
+ return NPERR_NO_ERROR;
+}
+
+
+extern "C"
+NPError __stdcall NP_Shutdown()
+{
+ return NPERR_NO_ERROR;
+}
+
+
+NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char *argn[], char *argv[], NPSavedData *saved)
+{
+ if (browser->version >= 14) {
+ PluginObject* obj = (PluginObject*)browser->createobject(instance, getPluginClass());
+
+ obj->onStreamLoad = NULL;
+
+ for (int16 i = 0; i < argc; i++) {
+ if (_stricmp(argn[i], "onstreamload") == 0 && !obj->onStreamLoad)
+ obj->onStreamLoad = _strdup(argv[i]);
+ }
+
+ instance->pdata = obj;
+ }
+
+ return NPERR_NO_ERROR;
+}
+
+NPError NPP_Destroy(NPP instance, NPSavedData **save)
+{
+ PluginObject *obj = (PluginObject*)instance->pdata;
+ if (obj) {
+ if (obj->onStreamLoad)
+ free(obj->onStreamLoad);
+
+ if (obj->logDestroy)
+ printf("PLUGIN: NPP_Destroy\n");
+
+ browser->releaseobject(&obj->header);
+ }
+ return NPERR_NO_ERROR;
+}
+
+NPError NPP_SetWindow(NPP instance, NPWindow *window)
+{
+ return NPERR_NO_ERROR;
+}
+
+NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream *stream, NPBool seekable, uint16 *stype)
+{
+ PluginObject* obj = (PluginObject*)instance->pdata;
+ obj->stream = stream;
+ *stype = NP_ASFILEONLY;
+
+ if (obj->onStreamLoad) {
+ NPObject *windowScriptObject;
+ browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
+
+ NPString script;
+ script.UTF8Characters = obj->onStreamLoad;
+ script.UTF8Length = strlen(obj->onStreamLoad);
+
+ NPVariant browserResult;
+ browser->evaluate(obj->npp, windowScriptObject, &script, &browserResult);
+ browser->releasevariantvalue(&browserResult);
+ }
+
+ return NPERR_NO_ERROR;
+}
+
+NPError NPP_DestroyStream(NPP instance, NPStream *stream, NPReason reason)
+{
+ return NPERR_NO_ERROR;
+}
+
+int32 NPP_WriteReady(NPP instance, NPStream *stream)
+{
+ return 0;
+}
+
+int32 NPP_Write(NPP instance, NPStream *stream, int32 offset, int32 len, void *buffer)
+{
+ return 0;
+}
+
+void NPP_StreamAsFile(NPP instance, NPStream *stream, const char *fname)
+{
+}
+
+void NPP_Print(NPP instance, NPPrint *platformPrint)
+{
+}
+
+int16 NPP_HandleEvent(NPP instance, void *event)
+{
+ PluginObject *obj = (PluginObject*)instance->pdata;
+ if (!obj->eventLogging)
+ return 0;
+
+ // FIXME: Implement this
+ return 0;
+}
+
+void NPP_URLNotify(NPP instance, const char *url, NPReason reason, void *notifyData)
+{
+ PluginObject *obj = (PluginObject*)instance->pdata;
+
+ handleCallback(obj, url, reason, notifyData);
+}
+
+NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value)
+{
+ if (variable == NPPVpluginScriptableNPObject) {
+ void **v = (void **)value;
+ PluginObject *obj = (PluginObject*)instance->pdata;
+ // Return value is expected to be retained
+ browser->retainobject((NPObject *)obj);
+ *v = obj;
+ return NPERR_NO_ERROR;
+ }
+ return NPERR_GENERIC_ERROR;
+}
+
+NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value)
+{
+ return NPERR_GENERIC_ERROR;
+}
diff --git a/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/main.cpp b/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/main.cpp
new file mode 100644
index 0000000..8c542ed
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/main.cpp
@@ -0,0 +1,191 @@
+/*
+ IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. ("Apple") in
+ consideration of your agreement to the following terms, and your use, installation,
+ modification or redistribution of this Apple software constitutes acceptance of these
+ terms. If you do not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject to these
+ terms, Apple grants you a personal, non-exclusive license, under AppleÕs copyrights in
+ this original Apple software (the "Apple Software"), to use, reproduce, modify and
+ redistribute the Apple Software, with or without modifications, in source and/or binary
+ forms; provided that if you redistribute the Apple Software in its entirety and without
+ modifications, you must retain this notice and the following text and disclaimers in all
+ such redistributions of the Apple Software. Neither the name, trademarks, service marks
+ or logos of Apple Computer, Inc. may be used to endorse or promote products derived from
+ the Apple Software without specific prior written permission from Apple. Except as expressly
+ stated in this notice, no other rights or licenses, express or implied, are granted by Apple
+ herein, including but not limited to any patent rights that may be infringed by your
+ derivative works or by other works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES,
+ EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT,
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS
+ USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE,
+ REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND
+ WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR
+ OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "PluginObject.h"
+
+#include <stdio.h>
+
+extern "C"
+NPError __stdcall NP_Initialize(NPNetscapeFuncs* browserFuncs)
+{
+ browser = browserFuncs;
+ return NPERR_NO_ERROR;
+}
+
+extern "C"
+NPError __stdcall NP_GetEntryPoints(NPPluginFuncs* pluginFuncs)
+{
+ pluginFuncs->version = 11;
+ pluginFuncs->size = sizeof(pluginFuncs);
+ pluginFuncs->newp = NPP_New;
+ pluginFuncs->destroy = NPP_Destroy;
+ pluginFuncs->setwindow = NPP_SetWindow;
+ pluginFuncs->newstream = NPP_NewStream;
+ pluginFuncs->destroystream = NPP_DestroyStream;
+ pluginFuncs->asfile = NPP_StreamAsFile;
+ pluginFuncs->writeready = NPP_WriteReady;
+ pluginFuncs->write = (NPP_WriteProcPtr)NPP_Write;
+ pluginFuncs->print = NPP_Print;
+ pluginFuncs->event = NPP_HandleEvent;
+ pluginFuncs->urlnotify = NPP_URLNotify;
+ pluginFuncs->getvalue = NPP_GetValue;
+ pluginFuncs->setvalue = NPP_SetValue;
+
+ return NPERR_NO_ERROR;
+}
+
+
+extern "C"
+NPError __stdcall NP_Shutdown()
+{
+ return NPERR_NO_ERROR;
+}
+
+
+NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char *argn[], char *argv[], NPSavedData *saved)
+{
+ if (browser->version >= 14) {
+ PluginObject* obj = (PluginObject*)browser->createobject(instance, getPluginClass());
+
+ obj->onStreamLoad = NULL;
+
+ for (int16 i = 0; i < argc; i++) {
+ if (_stricmp(argn[i], "onstreamload") == 0 && !obj->onStreamLoad)
+ obj->onStreamLoad = _strdup(argv[i]);
+ }
+
+ instance->pdata = obj;
+ }
+
+ return NPERR_NO_ERROR;
+}
+
+NPError NPP_Destroy(NPP instance, NPSavedData **save)
+{
+ PluginObject *obj = (PluginObject*)instance->pdata;
+ if (obj) {
+ if (obj->onStreamLoad)
+ free(obj->onStreamLoad);
+
+ if (obj->logDestroy)
+ printf("PLUGIN: NPP_Destroy\n");
+
+ browser->releaseobject(&obj->header);
+ }
+ return NPERR_NO_ERROR;
+}
+
+NPError NPP_SetWindow(NPP instance, NPWindow *window)
+{
+ return NPERR_NO_ERROR;
+}
+
+NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream *stream, NPBool seekable, uint16 *stype)
+{
+ PluginObject* obj = (PluginObject*)instance->pdata;
+ obj->stream = stream;
+ *stype = NP_ASFILEONLY;
+
+ if (obj->onStreamLoad) {
+ NPObject *windowScriptObject;
+ browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
+
+ NPString script;
+ script.UTF8Characters = obj->onStreamLoad;
+ script.UTF8Length = strlen(obj->onStreamLoad);
+
+ NPVariant browserResult;
+ browser->evaluate(obj->npp, windowScriptObject, &script, &browserResult);
+ browser->releasevariantvalue(&browserResult);
+ }
+
+ return NPERR_NO_ERROR;
+}
+
+NPError NPP_DestroyStream(NPP instance, NPStream *stream, NPReason reason)
+{
+ return NPERR_NO_ERROR;
+}
+
+int32 NPP_WriteReady(NPP instance, NPStream *stream)
+{
+ return 0;
+}
+
+int32 NPP_Write(NPP instance, NPStream *stream, int32 offset, int32 len, void *buffer)
+{
+ return 0;
+}
+
+void NPP_StreamAsFile(NPP instance, NPStream *stream, const char *fname)
+{
+}
+
+void NPP_Print(NPP instance, NPPrint *platformPrint)
+{
+}
+
+int16 NPP_HandleEvent(NPP instance, void *event)
+{
+ PluginObject *obj = (PluginObject*)instance->pdata;
+ if (!obj->eventLogging)
+ return 0;
+
+ // FIXME: Implement this
+ return 0;
+}
+
+void NPP_URLNotify(NPP instance, const char *url, NPReason reason, void *notifyData)
+{
+ PluginObject *obj = (PluginObject*)instance->pdata;
+
+ handleCallback(obj, url, reason, notifyData);
+}
+
+NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value)
+{
+ if (variable == NPPVpluginScriptableNPObject) {
+ void **v = (void **)value;
+ PluginObject *obj = (PluginObject*)instance->pdata;
+ // Return value is expected to be retained
+ browser->retainobject((NPObject *)obj);
+ *v = obj;
+ return NPERR_NO_ERROR;
+ }
+ return NPERR_GENERIC_ERROR;
+}
+
+NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value)
+{
+ return NPERR_GENERIC_ERROR;
+}
diff --git a/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/resource.h b/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/resource.h
new file mode 100644
index 0000000..b0ce340
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/resource.h
@@ -0,0 +1,14 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by TestNetscapePlugin.rc
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/WebKitTools/DumpRenderTree/win/UIDelegate.cpp b/WebKitTools/DumpRenderTree/win/UIDelegate.cpp
new file mode 100755
index 0000000..a0362c3
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/UIDelegate.cpp
@@ -0,0 +1,415 @@
+/*
+ * Copyright (C) 2005, 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.
+ * 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 "DumpRenderTree.h"
+#include "UIDelegate.h"
+
+#include "DraggingInfo.h"
+#include "EventSender.h"
+#include "LayoutTestController.h"
+
+#include <WebCore/COMPtr.h>
+#include <wtf/Platform.h>
+#include <wtf/Vector.h>
+#include <JavaScriptCore/Assertions.h>
+#include <JavaScriptCore/JavaScriptCore.h>
+#include <WebKit/WebKit.h>
+#include <stdio.h>
+
+using std::wstring;
+
+class DRTUndoObject {
+public:
+ DRTUndoObject(IWebUndoTarget* target, BSTR actionName, IUnknown* obj)
+ : m_target(target)
+ , m_actionName(SysAllocString(actionName))
+ , m_obj(obj)
+ {
+ }
+
+ ~DRTUndoObject()
+ {
+ SysFreeString(m_actionName);
+ }
+
+ void invoke()
+ {
+ m_target->invoke(m_actionName, m_obj.get());
+ }
+
+private:
+ IWebUndoTarget* m_target;
+ BSTR m_actionName;
+ COMPtr<IUnknown> m_obj;
+};
+
+class DRTUndoStack {
+public:
+ ~DRTUndoStack() { deleteAllValues(m_undoVector); }
+
+ bool isEmpty() const { return m_undoVector.isEmpty(); }
+ void clear() { deleteAllValues(m_undoVector); m_undoVector.clear(); }
+
+ void push(DRTUndoObject* undoObject) { m_undoVector.append(undoObject); }
+ DRTUndoObject* pop() { DRTUndoObject* top = m_undoVector.last(); m_undoVector.removeLast(); return top; }
+
+private:
+ Vector<DRTUndoObject*> m_undoVector;
+};
+
+class DRTUndoManager {
+public:
+ DRTUndoManager();
+
+ void removeAllActions();
+ void registerUndoWithTarget(IWebUndoTarget* target, BSTR actionName, IUnknown* obj);
+ void redo();
+ void undo();
+ bool canRedo() { return !m_redoStack->isEmpty(); }
+ bool canUndo() { return !m_undoStack->isEmpty(); }
+
+private:
+ OwnPtr<DRTUndoStack> m_redoStack;
+ OwnPtr<DRTUndoStack> m_undoStack;
+ bool m_isRedoing;
+ bool m_isUndoing;
+};
+
+DRTUndoManager::DRTUndoManager()
+ : m_redoStack(new DRTUndoStack)
+ , m_undoStack(new DRTUndoStack)
+ , m_isRedoing(false)
+ , m_isUndoing(false)
+{
+}
+
+void DRTUndoManager::removeAllActions()
+{
+ m_redoStack->clear();
+ m_undoStack->clear();
+}
+
+void DRTUndoManager::registerUndoWithTarget(IWebUndoTarget* target, BSTR actionName, IUnknown* obj)
+{
+ if (!m_isUndoing && !m_isRedoing)
+ m_redoStack->clear();
+
+ DRTUndoStack* stack = m_isUndoing ? m_redoStack.get() : m_undoStack.get();
+ stack->push(new DRTUndoObject(target, actionName, obj));
+}
+
+void DRTUndoManager::redo()
+{
+ if (!canRedo())
+ return;
+
+ m_isRedoing = true;
+
+ DRTUndoObject* redoObject = m_redoStack->pop();
+ redoObject->invoke();
+ delete redoObject;
+
+ m_isRedoing = false;
+}
+
+void DRTUndoManager::undo()
+{
+ if (!canUndo())
+ return;
+
+ m_isUndoing = true;
+
+ DRTUndoObject* undoObject = m_undoStack->pop();
+ undoObject->invoke();
+ delete undoObject;
+
+ m_isUndoing = false;
+}
+
+UIDelegate::UIDelegate()
+ : m_refCount(1)
+ , m_undoManager(new DRTUndoManager)
+{
+ m_frame.bottom = 0;
+ m_frame.top = 0;
+ m_frame.left = 0;
+ m_frame.right = 0;
+}
+
+void UIDelegate::resetUndoManager()
+{
+ m_undoManager.set(new DRTUndoManager);
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::QueryInterface(REFIID riid, void** ppvObject)
+{
+ *ppvObject = 0;
+ if (IsEqualGUID(riid, IID_IUnknown))
+ *ppvObject = static_cast<IWebUIDelegate*>(this);
+ else if (IsEqualGUID(riid, IID_IWebUIDelegate))
+ *ppvObject = static_cast<IWebUIDelegate*>(this);
+ else if (IsEqualGUID(riid, IID_IWebUIDelegatePrivate))
+ *ppvObject = static_cast<IWebUIDelegatePrivate*>(this);
+ else if (IsEqualGUID(riid, IID_IWebUIDelegatePrivate2))
+ *ppvObject = static_cast<IWebUIDelegatePrivate2*>(this);
+ else if (IsEqualGUID(riid, IID_IWebUIDelegatePrivate3))
+ *ppvObject = static_cast<IWebUIDelegatePrivate3*>(this);
+ else
+ return E_NOINTERFACE;
+
+ AddRef();
+ return S_OK;
+}
+
+ULONG STDMETHODCALLTYPE UIDelegate::AddRef()
+{
+ return ++m_refCount;
+}
+
+ULONG STDMETHODCALLTYPE UIDelegate::Release()
+{
+ ULONG newRef = --m_refCount;
+ if (!newRef)
+ delete(this);
+
+ return newRef;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::hasCustomMenuImplementation(
+ /* [retval][out] */ BOOL *hasCustomMenus)
+{
+ *hasCustomMenus = TRUE;
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::trackCustomPopupMenu(
+ /* [in] */ IWebView *sender,
+ /* [in] */ OLE_HANDLE menu,
+ /* [in] */ LPPOINT point)
+{
+ // Do nothing
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::registerUndoWithTarget(
+ /* [in] */ IWebUndoTarget* target,
+ /* [in] */ BSTR actionName,
+ /* [in] */ IUnknown* actionArg)
+{
+ m_undoManager->registerUndoWithTarget(target, actionName, actionArg);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::removeAllActionsWithTarget(
+ /* [in] */ IWebUndoTarget*)
+{
+ m_undoManager->removeAllActions();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::setActionTitle(
+ /* [in] */ BSTR actionTitle)
+{
+ // It is not neccessary to implement this for DRT because there is
+ // menu to write out the title to.
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::undo()
+{
+ m_undoManager->undo();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::redo()
+{
+ m_undoManager->redo();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::canUndo(
+ /* [retval][out] */ BOOL* result)
+{
+ if (!result)
+ return E_POINTER;
+
+ *result = m_undoManager->canUndo();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::canRedo(
+ /* [retval][out] */ BOOL* result)
+{
+ if (!result)
+ return E_POINTER;
+
+ *result = m_undoManager->canRedo();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::setFrame(
+ /* [in] */ IWebView* /*sender*/,
+ /* [in] */ RECT* frame)
+{
+ m_frame = *frame;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::webViewFrame(
+ /* [in] */ IWebView* /*sender*/,
+ /* [retval][out] */ RECT* frame)
+{
+ *frame = m_frame;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::runJavaScriptAlertPanelWithMessage(
+ /* [in] */ IWebView* /*sender*/,
+ /* [in] */ BSTR message)
+{
+ printf("ALERT: %S\n", message ? message : L"");
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::runJavaScriptConfirmPanelWithMessage(
+ /* [in] */ IWebView* sender,
+ /* [in] */ BSTR message,
+ /* [retval][out] */ BOOL* result)
+{
+ printf("CONFIRM: %S\n", message ? message : L"");
+ *result = TRUE;
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::runJavaScriptTextInputPanelWithPrompt(
+ /* [in] */ IWebView *sender,
+ /* [in] */ BSTR message,
+ /* [in] */ BSTR defaultText,
+ /* [retval][out] */ BSTR *result)
+{
+ printf("PROMPT: %S, default text: %S\n", message ? message : L"", defaultText ? defaultText : L"");
+ *result = SysAllocString(defaultText);
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::webViewAddMessageToConsole(
+ /* [in] */ IWebView* sender,
+ /* [in] */ BSTR message,
+ /* [in] */ int lineNumber,
+ /* [in] */ BSTR url,
+ /* [in] */ BOOL isError)
+{
+ wstring newMessage;
+ if (message) {
+ newMessage = message;
+ size_t fileProtocol = newMessage.find(L"file://");
+ if (fileProtocol != wstring::npos)
+ newMessage = newMessage.substr(0, fileProtocol) + urlSuitableForTestResult(newMessage.substr(fileProtocol));
+ }
+
+ printf("CONSOLE MESSAGE: line %d: %S\n", lineNumber, newMessage.c_str());
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::doDragDrop(
+ /* [in] */ IWebView* sender,
+ /* [in] */ IDataObject* object,
+ /* [in] */ IDropSource* source,
+ /* [in] */ DWORD okEffect,
+ /* [retval][out] */ DWORD* performedEffect)
+{
+ if (!performedEffect)
+ return E_POINTER;
+
+ *performedEffect = 0;
+
+ draggingInfo = new DraggingInfo(object, source);
+ replaySavedEvents();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::webViewGetDlgCode(
+ /* [in] */ IWebView* /*sender*/,
+ /* [in] */ UINT /*keyCode*/,
+ /* [retval][out] */ LONG_PTR *code)
+{
+ if (!code)
+ return E_POINTER;
+ *code = 0;
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::createWebViewWithRequest(
+ /* [in] */ IWebView *sender,
+ /* [in] */ IWebURLRequest *request,
+ /* [retval][out] */ IWebView **newWebView)
+{
+ if (!::layoutTestController->canOpenWindows())
+ return E_FAIL;
+ *newWebView = createWebViewAndOffscreenWindow();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::webViewClose(
+ /* [in] */ IWebView *sender)
+{
+ HWND hostWindow;
+ sender->hostWindow(reinterpret_cast<OLE_HANDLE*>(&hostWindow));
+ DestroyWindow(hostWindow);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::webViewPainted(
+ /* [in] */ IWebView *sender)
+{
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::exceededDatabaseQuota(
+ /* [in] */ IWebView *sender,
+ /* [in] */ IWebFrame *frame,
+ /* [in] */ IWebSecurityOrigin *origin,
+ /* [in] */ BSTR databaseIdentifier)
+{
+ static const unsigned long long defaultQuota = 5 * 1024 * 1024;
+ origin->setQuota(defaultQuota);
+
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE UIDelegate::setStatusText(IWebView*, BSTR text)
+{
+ if (layoutTestController->dumpStatusCallbacks())
+ printf("UI DELEGATE STATUS CALLBACK: setStatusText:%S\n", text ? text : L"");
+ return S_OK;
+}
diff --git a/WebKitTools/DumpRenderTree/win/UIDelegate.h b/WebKitTools/DumpRenderTree/win/UIDelegate.h
new file mode 100755
index 0000000..0acab81
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/UIDelegate.h
@@ -0,0 +1,316 @@
+/*
+ * Copyright (C) 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.
+ * 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 UIDelegate_h
+#define UIDelegate_h
+
+#include <WebKit/WebKit.h>
+#include <wtf/OwnPtr.h>
+#include <windef.h>
+
+class DRTUndoManager;
+
+class UIDelegate : public IWebUIDelegate, IWebUIDelegatePrivate3 {
+public:
+ UIDelegate();
+
+ void resetUndoManager();
+
+ // IUnknown
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
+ virtual ULONG STDMETHODCALLTYPE AddRef(void);
+ virtual ULONG STDMETHODCALLTYPE Release(void);
+
+ // IWebUIDelegate
+ virtual HRESULT STDMETHODCALLTYPE createWebViewWithRequest(
+ /* [in] */ IWebView *sender,
+ /* [in] */ IWebURLRequest *request,
+ /* [retval][out] */ IWebView **newWebView);
+
+ virtual HRESULT STDMETHODCALLTYPE webViewShow(
+ /* [in] */ IWebView *sender) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewClose(
+ /* [in] */ IWebView *sender);
+
+ virtual HRESULT STDMETHODCALLTYPE webViewFocus(
+ /* [in] */ IWebView *sender) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewUnfocus(
+ /* [in] */ IWebView *sender) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewFirstResponder(
+ /* [in] */ IWebView *sender,
+ /* [retval][out] */ OLE_HANDLE *responder) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE makeFirstResponder(
+ /* [in] */ IWebView *sender,
+ /* [in] */ OLE_HANDLE responder) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE setStatusText(
+ /* [in] */ IWebView *sender,
+ /* [in] */ BSTR text);
+
+ virtual HRESULT STDMETHODCALLTYPE webViewStatusText(
+ /* [in] */ IWebView *sender,
+ /* [retval][out] */ BSTR *text) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewAreToolbarsVisible(
+ /* [in] */ IWebView *sender,
+ /* [retval][out] */ BOOL *visible) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE setToolbarsVisible(
+ /* [in] */ IWebView *sender,
+ /* [in] */ BOOL visible) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewIsStatusBarVisible(
+ /* [in] */ IWebView *sender,
+ /* [retval][out] */ BOOL *visible) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE setStatusBarVisible(
+ /* [in] */ IWebView *sender,
+ /* [in] */ BOOL visible) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewIsResizable(
+ /* [in] */ IWebView *sender,
+ /* [retval][out] */ BOOL *resizable) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE setResizable(
+ /* [in] */ IWebView *sender,
+ /* [in] */ BOOL resizable) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE setFrame(
+ /* [in] */ IWebView *sender,
+ /* [in] */ RECT *frame);
+
+ virtual HRESULT STDMETHODCALLTYPE webViewFrame(
+ /* [in] */ IWebView *sender,
+ /* [retval][out] */ RECT *frame);
+
+ virtual HRESULT STDMETHODCALLTYPE setContentRect(
+ /* [in] */ IWebView *sender,
+ /* [in] */ RECT *contentRect) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewContentRect(
+ /* [in] */ IWebView *sender,
+ /* [retval][out] */ RECT *contentRect) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE runJavaScriptAlertPanelWithMessage(
+ /* [in] */ IWebView *sender,
+ /* [in] */ BSTR message);
+
+ virtual HRESULT STDMETHODCALLTYPE runJavaScriptConfirmPanelWithMessage(
+ /* [in] */ IWebView *sender,
+ /* [in] */ BSTR message,
+ /* [retval][out] */ BOOL *result);
+
+ virtual HRESULT STDMETHODCALLTYPE runJavaScriptTextInputPanelWithPrompt(
+ /* [in] */ IWebView *sender,
+ /* [in] */ BSTR message,
+ /* [in] */ BSTR defaultText,
+ /* [retval][out] */ BSTR *result);
+
+ virtual HRESULT STDMETHODCALLTYPE runBeforeUnloadConfirmPanelWithMessage(
+ /* [in] */ IWebView *sender,
+ /* [in] */ BSTR message,
+ /* [in] */ IWebFrame *initiatedByFrame,
+ /* [retval][out] */ BOOL *result) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE runOpenPanelForFileButtonWithResultListener(
+ /* [in] */ IWebView *sender,
+ /* [in] */ IWebOpenPanelResultListener *resultListener) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE mouseDidMoveOverElement(
+ /* [in] */ IWebView *sender,
+ /* [in] */ IPropertyBag *elementInformation,
+ /* [in] */ UINT modifierFlags) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE contextMenuItemsForElement(
+ /* [in] */ IWebView *sender,
+ /* [in] */ IPropertyBag *element,
+ /* [in] */ OLE_HANDLE defaultItems,
+ /* [retval][out] */ OLE_HANDLE *resultMenu) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE validateUserInterfaceItem(
+ /* [in] */ IWebView *webView,
+ /* [in] */ UINT itemCommandID,
+ /* [in] */ BOOL defaultValidation,
+ /* [retval][out] */ BOOL *isValid) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE shouldPerformAction(
+ /* [in] */ IWebView *webView,
+ /* [in] */ UINT itemCommandID,
+ /* [in] */ UINT sender) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE dragDestinationActionMaskForDraggingInfo(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IDataObject *draggingInfo,
+ /* [retval][out] */ WebDragDestinationAction *action) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE willPerformDragDestinationAction(
+ /* [in] */ IWebView *webView,
+ /* [in] */ WebDragDestinationAction action,
+ /* [in] */ IDataObject *draggingInfo) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE dragSourceActionMaskForPoint(
+ /* [in] */ IWebView *webView,
+ /* [in] */ LPPOINT point,
+ /* [retval][out] */ WebDragSourceAction *action) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE willPerformDragSourceAction(
+ /* [in] */ IWebView *webView,
+ /* [in] */ WebDragSourceAction action,
+ /* [in] */ LPPOINT point,
+ /* [in] */ IDataObject *pasteboard) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE contextMenuItemSelected(
+ /* [in] */ IWebView *sender,
+ /* [in] */ void *item,
+ /* [in] */ IPropertyBag *element) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE hasCustomMenuImplementation(
+ /* [retval][out] */ BOOL *hasCustomMenus);
+
+ virtual HRESULT STDMETHODCALLTYPE trackCustomPopupMenu(
+ /* [in] */ IWebView *sender,
+ /* [in] */ OLE_HANDLE menu,
+ /* [in] */ LPPOINT point);
+
+ virtual HRESULT STDMETHODCALLTYPE measureCustomMenuItem(
+ /* [in] */ IWebView *sender,
+ /* [in] */ void *measureItem) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE drawCustomMenuItem(
+ /* [in] */ IWebView *sender,
+ /* [in] */ void *drawItem) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE addCustomMenuDrawingData(
+ /* [in] */ IWebView *sender,
+ /* [in] */ OLE_HANDLE menu) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE cleanUpCustomMenuDrawingData(
+ /* [in] */ IWebView *sender,
+ /* [in] */ OLE_HANDLE menu) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE canTakeFocus(
+ /* [in] */ IWebView *sender,
+ /* [in] */ BOOL forward,
+ /* [out] */ BOOL *result) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE takeFocus(
+ /* [in] */ IWebView *sender,
+ /* [in] */ BOOL forward) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE registerUndoWithTarget(
+ /* [in] */ IWebUndoTarget *target,
+ /* [in] */ BSTR actionName,
+ /* [in] */ IUnknown *actionArg);
+
+ virtual HRESULT STDMETHODCALLTYPE removeAllActionsWithTarget(
+ /* [in] */ IWebUndoTarget *target);
+
+ virtual HRESULT STDMETHODCALLTYPE setActionTitle(
+ /* [in] */ BSTR actionTitle);
+
+ virtual HRESULT STDMETHODCALLTYPE undo();
+
+ virtual HRESULT STDMETHODCALLTYPE redo();
+
+ virtual HRESULT STDMETHODCALLTYPE canUndo(
+ /* [retval][out] */ BOOL *result);
+
+ virtual HRESULT STDMETHODCALLTYPE canRedo(
+ /* [retval][out] */ BOOL *result);
+
+protected:
+ // IWebUIDelegatePrivate
+
+ virtual HRESULT STDMETHODCALLTYPE webViewResizerRect(
+ /* [in] */ IWebView *sender,
+ /* [retval][out] */ RECT *rect) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewDrawResizer(
+ /* [in] */ IWebView *sender,
+ /* [in] */ HDC dc,
+ /* [in] */ BOOL overlapsContent,
+ /* [in] */ RECT *rect) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewScrolled(
+ /* [in] */ IWebView *sender) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewAddMessageToConsole(
+ /* [in] */ IWebView *sender,
+ /* [in] */ BSTR message,
+ /* [in] */ int lineNumber,
+ /* [in] */ BSTR url,
+ /* [in] */ BOOL isError);
+
+ virtual HRESULT STDMETHODCALLTYPE webViewShouldInterruptJavaScript(
+ /* [in] */ IWebView *sender,
+ /* [retval][out] */ BOOL *result) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewReceivedFocus(
+ /* [in] */ IWebView *sender) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewLostFocus(
+ /* [in] */ IWebView *sender,
+ /* [in] */ OLE_HANDLE loseFocusTo) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE doDragDrop(
+ /* [in] */ IWebView *sender,
+ /* [in] */ IDataObject *dataObject,
+ /* [in] */ IDropSource *dropSource,
+ /* [in] */ DWORD okEffect,
+ /* [retval][out] */ DWORD *performedEffect);
+
+ virtual HRESULT STDMETHODCALLTYPE webViewGetDlgCode(
+ /* [in] */ IWebView *sender,
+ /* [in] */ UINT keyCode,
+ /* [retval][out] */ LONG_PTR *code);
+
+ // IWebUIDelegatePrivate2
+
+ virtual HRESULT STDMETHODCALLTYPE webViewPainted(
+ /* [in] */ IWebView *sender);
+
+ // IWebUIDelegatePrivate3
+
+ virtual HRESULT STDMETHODCALLTYPE exceededDatabaseQuota(
+ /* [in] */ IWebView *sender,
+ /* [in] */ IWebFrame *frame,
+ /* [in] */ IWebSecurityOrigin *origin,
+ /* [in] */ BSTR databaseIdentifier);
+
+ ULONG m_refCount;
+
+private:
+ RECT m_frame;
+ OwnPtr<DRTUndoManager> m_undoManager;
+};
+
+#endif
diff --git a/WebKitTools/DumpRenderTree/win/WorkQueueItemWin.cpp b/WebKitTools/DumpRenderTree/win/WorkQueueItemWin.cpp
new file mode 100644
index 0000000..4113c9e
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/WorkQueueItemWin.cpp
@@ -0,0 +1,133 @@
+/*
+ * 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 "DumpRenderTree.h"
+#include "WorkQueueItem.h"
+
+#include <WebCore/COMPtr.h>
+#include <WebKit/WebKit.h>
+#include <JavaScriptCore/JSStringRef.h>
+#include <JavaScriptCore/JSStringRefCF.h>
+#include <JavaScriptCore/RetainPtr.h>
+#include <wtf/Vector.h>
+#include <string>
+
+using std::wstring;
+
+static wstring jsStringRefToWString(JSStringRef jsStr)
+{
+ size_t length = JSStringGetLength(jsStr);
+ Vector<WCHAR> buffer(length + 1);
+ memcpy(buffer.data(), JSStringGetCharactersPtr(jsStr), length * sizeof(WCHAR));
+ buffer[length] = '\0';
+
+ return buffer.data();
+}
+
+void LoadItem::invoke() const
+{
+ wstring targetString = jsStringRefToWString(target());
+
+ COMPtr<IWebFrame> targetFrame;
+ if (targetString.empty())
+ targetFrame = frame;
+ else {
+ BSTR targetBSTR = SysAllocString(targetString.c_str());
+ bool failed = FAILED(frame->findFrameNamed(targetBSTR, &targetFrame));
+ SysFreeString(targetBSTR);
+ if (failed)
+ return;
+ }
+
+ COMPtr<IWebURLRequest> request;
+ if (FAILED(CoCreateInstance(CLSID_WebURLRequest, 0, CLSCTX_ALL, IID_IWebURLRequest, (void**)&request)))
+ return;
+
+ wstring urlString = jsStringRefToWString(url());
+ BSTR urlBSTR = SysAllocString(urlString.c_str());
+ bool failed = FAILED(request->initWithURL(urlBSTR, WebURLRequestUseProtocolCachePolicy, 60));
+ SysFreeString(urlBSTR);
+ if (failed)
+ return;
+
+ targetFrame->loadRequest(request.get());
+}
+
+void ReloadItem::invoke() const
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ COMPtr<IWebIBActions> webActions;
+ if (SUCCEEDED(webView->QueryInterface(&webActions)))
+ webActions->reload(0);
+}
+
+void ScriptItem::invoke() const
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ wstring scriptString = jsStringRefToWString(script());
+
+ BSTR result;
+ BSTR scriptBSTR = SysAllocString(scriptString.c_str());
+ webView->stringByEvaluatingJavaScriptFromString(scriptBSTR, &result);
+ SysFreeString(result);
+ SysFreeString(scriptBSTR);
+}
+
+void BackForwardItem::invoke() const
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ BOOL result;
+ if (m_howFar == 1) {
+ webView->goForward(&result);
+ return;
+ }
+
+ if (m_howFar == -1) {
+ webView->goBack(&result);
+ return;
+ }
+
+ COMPtr<IWebBackForwardList> bfList;
+ if (FAILED(webView->backForwardList(&bfList)))
+ return;
+
+ COMPtr<IWebHistoryItem> item;
+ if (FAILED(bfList->itemAtIndex(m_howFar, &item)))
+ return;
+
+ webView->goToBackForwardItem(item.get(), &result);
+}
diff --git a/WebKitTools/FindSafari/FindSafari.cpp b/WebKitTools/FindSafari/FindSafari.cpp
new file mode 100644
index 0000000..83626bb
--- /dev/null
+++ b/WebKitTools/FindSafari/FindSafari.cpp
@@ -0,0 +1,201 @@
+/*
+ * 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 <shlwapi.h>
+#include <stdio.h>
+#include <tchar.h>
+#include <windows.h>
+
+#define LOG(header, ...) \
+ do { \
+ _ftprintf(stderr, header); \
+ _ftprintf(stderr, __VA_ARGS__); \
+ } while (0)
+#define LOG_WARNING(...) LOG(TEXT("WARNING: "), __VA_ARGS__)
+#define LOG_ERROR(...) LOG(TEXT("ERROR: "), __VA_ARGS__)
+
+static TCHAR* getStringValue(HKEY key, LPCTSTR valueName)
+{
+ DWORD type = 0;
+ DWORD bufferSize = 0;
+ if (RegQueryValueEx(key, valueName, 0, &type, 0, &bufferSize) != ERROR_SUCCESS || type != REG_SZ)
+ return 0;
+
+ TCHAR* buffer = (TCHAR*)malloc(bufferSize);
+ if (RegQueryValueEx(key, 0, 0, &type, reinterpret_cast<LPBYTE>(buffer), &bufferSize) != ERROR_SUCCESS) {
+ free(buffer);
+ return 0;
+ }
+
+ return buffer;
+}
+
+static LPOLESTR getWebViewCLSID()
+{
+ LPCTSTR webViewProgID = TEXT("WebKit.WebView");
+
+ CLSID clsid = CLSID_NULL;
+ HRESULT hr = CLSIDFromProgID(webViewProgID, &clsid);
+ if (FAILED(hr)) {
+ LOG_WARNING(TEXT("Failed to get CLSID for %s\n"), webViewProgID);
+ return 0;
+ }
+
+ LPOLESTR clsidString = 0;
+ if (FAILED(StringFromCLSID(clsid, &clsidString))) {
+ LOG_WARNING(TEXT("Failed to get string representation of CLSID for WebView\n"));
+ return 0;
+ }
+
+ return clsidString;
+}
+
+static TCHAR* getInstalledWebKitDirectory()
+{
+ LPCTSTR keyPrefix = TEXT("SOFTWARE\\Classes\\CLSID\\");
+ LPCTSTR keySuffix = TEXT("\\InprocServer32");
+
+ LPOLESTR clsid = getWebViewCLSID();
+ if (!clsid)
+ return 0;
+
+ size_t keyBufferLength = _tcslen(keyPrefix) + _tcslen(clsid) + _tcslen(keySuffix) + 1;
+ TCHAR* keyString = (TCHAR*)malloc(keyBufferLength * sizeof(TCHAR));
+
+ int ret = _sntprintf_s(keyString, keyBufferLength, keyBufferLength - 1, TEXT("%s%s%s"), keyPrefix, clsid, keySuffix);
+ CoTaskMemFree(clsid);
+ if (ret == -1) {
+ LOG_WARNING(TEXT("Failed to construct InprocServer32 key\n"));
+ return 0;
+ }
+
+ HKEY serverKey = 0;
+ LONG error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyString, 0, KEY_READ, &serverKey);
+ free(keyString);
+ if (error != ERROR_SUCCESS) {
+ LOG_WARNING(TEXT("Failed to open registry key %s\n"), keyString);
+ return 0;
+ }
+
+ TCHAR* webKitPath = getStringValue(serverKey, 0);
+ RegCloseKey(serverKey);
+ if (!webKitPath) {
+ LOG_WARNING(TEXT("Couldn't retrieve value for registry key %s\n"), keyString);
+ return 0;
+ }
+
+ TCHAR* startOfFileName = PathFindFileName(webKitPath);
+ if (startOfFileName == webKitPath) {
+ LOG_WARNING(TEXT("Couldn't find filename from path %s\n"), webKitPath);
+ free(webKitPath);
+ return 0;
+ }
+
+ *startOfFileName = '\0';
+ return webKitPath;
+}
+
+int _tmain(int argc, TCHAR* argv[])
+{
+ TCHAR* path = getInstalledWebKitDirectory();
+ if (!path) {
+ LOG_ERROR(TEXT("Couldn't determine installed Safari path\n"));
+ return 1;
+ }
+
+ bool printLauncher = false;
+ bool printEnvironment = false;
+ bool debugger = false;
+
+ for (int i = 1; i < argc; ++i) {
+ if (!_tcscmp(argv[i], TEXT("/printSafariLauncher"))) {
+ printLauncher = true;
+ continue;
+ }
+ if (!_tcscmp(argv[i], TEXT("/printSafariEnvironment"))) {
+ printEnvironment = true;
+ continue;
+ }
+ if (!_tcscmp(argv[i], TEXT("/debugger"))) {
+ debugger = true;
+ continue;
+ }
+ }
+
+ // printLauncher is inclusive of printEnvironment, so do not
+ // leave both enabled:
+ if (printLauncher && printEnvironment)
+ printEnvironment = false;
+
+ if (!printLauncher && !printEnvironment) {
+ _tprintf(TEXT("%s\n"), path);
+ free(path);
+ return 0;
+ }
+
+ LPCTSTR lines[] = {
+ TEXT("@echo off"),
+ TEXT("mkdir 2>NUL \"%%TMP%%\\WebKitNightly\\Safari.resources\""),
+ TEXT("xcopy /y /i /d \"%sSafari.exe\" \"%%TMP%%\\WebKitNightly\""),
+ TEXT("xcopy /y /i /d /e \"%sSafari.resources\" \"%%TMP%%\\WebKitNightly\\Safari.resources\""),
+ TEXT("xcopy /y /i /d /e \"%splugins\" \"%%TMP%%\\WebKitNightly\\plugins\""),
+ TEXT("set PATH=%%CD%%;%s;%%PATH%%"),
+ };
+
+ LPCTSTR command = TEXT("\"%TMP%\\WebKitNightly\\Safari.exe\" /customWebKit");
+
+ LPCTSTR launchLines[] = {
+ TEXT("%s"),
+ };
+
+ LPCTSTR debuggerLines[] = {
+ TEXT("if exist \"%%DevEnvDir%%\\VCExpress.exe\" ("),
+ TEXT("\"%%DevEnvDir%%\\VCExpress.exe\" /debugExe %s"),
+ TEXT(") else ("),
+ TEXT("\"%%DevEnvDir%%\\devenv.exe\" /debugExe %s"),
+ TEXT(")"),
+ };
+
+ for (int i = 0; i < ARRAYSIZE(lines); ++i) {
+ _tprintf(lines[i], path);
+ _tprintf(TEXT("\n"));
+ }
+
+ LPCTSTR* endLines = debugger ? debuggerLines : launchLines;
+
+ // Don't print launch command if we just want the environment set up...
+ if (!printEnvironment) {
+ for (unsigned i = 0; i < (debugger ? ARRAYSIZE(debuggerLines) : ARRAYSIZE(launchLines)); ++i) {
+ _tprintf(endLines[i], command);
+ _tprintf(TEXT("\n"));
+ }
+ }
+
+ free(path);
+ return 0;
+}
diff --git a/WebKitTools/FindSafari/FindSafari.vcproj b/WebKitTools/FindSafari/FindSafari.vcproj
new file mode 100644
index 0000000..93f8647
--- /dev/null
+++ b/WebKitTools/FindSafari/FindSafari.vcproj
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="FindSafari"
+ ProjectGUID="{DA31DA52-6675-48D4-89E0-333A7144397C}"
+ RootNamespace="FindSafari"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_internal.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="shlwapi.lib advapi32.lib ole32.lib"
+ OutputFile="$(OutDir)\$(ProjectName).exe"
+ SubSystem="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\FindSafari.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/WebKitTools/GNUmakefile.am b/WebKitTools/GNUmakefile.am
new file mode 100644
index 0000000..26758b5
--- /dev/null
+++ b/WebKitTools/GNUmakefile.am
@@ -0,0 +1,48 @@
+noinst_PROGRAMS += \
+ Programs/GtkLauncher \
+ Programs/DumpRenderTree
+
+# GtkLauncher
+Programs_GtkLauncher_CPPFLAGS = \
+ -I$(srcdir)/WebKit/gtk \
+ $(global_cppflags)
+
+Programs_GtkLauncher_SOURCES = \
+ WebKitTools/GtkLauncher/main.c
+
+Programs_GtkLauncher_CFLAGS = \
+ $(GLOBALDEPS_CFLAGS) \
+ $(WEBKITDEPS_CFLAGS) \
+ $(global_cflags)
+
+Programs_GtkLauncher_LDADD = \
+ libwebkit-1.0.la
+
+Programs_GtkLauncher_LDFLAGS = -rpath $(CURDIR)/.libs
+
+# DumpRenderTree
+Programs_DumpRenderTree_CPPFLAGS = \
+ -I$(srcdir)/WebKitTools/DumpRenderTree \
+ -I$(srcdir)/WebKitTools/DumpRenderTree/gtk \
+ -I$(srcdir)/WebKit/gtk \
+ $(global_cppflags)
+
+Programs_DumpRenderTree_SOURCES = \
+ WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp \
+ WebKitTools/DumpRenderTree/LayoutTestController.cpp \
+ WebKitTools/DumpRenderTree/GCController.cpp \
+ WebKitTools/DumpRenderTree/WorkQueue.cpp \
+ WebKitTools/DumpRenderTree/gtk/GCControllerGtk.cpp \
+ WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp \
+ WebKitTools/DumpRenderTree/gtk/WorkQueueItemGtk.cpp
+
+Programs_DumpRenderTree_CXXFLAGS = \
+ $(GLOBALDEPS_CFLAGS) \
+ $(WEBKITDEPS_CFLAGS) \
+ $(global_cxxflags) \
+ $(global_cflags)
+
+Programs_DumpRenderTree_LDADD = \
+ libwebkit-1.0.la
+
+Programs_DumpRenderTree_LDFLAGS = -rpath $(CURDIR)/.libs
diff --git a/WebKitTools/GtkLauncher/GtkLauncher.pro b/WebKitTools/GtkLauncher/GtkLauncher.pro
new file mode 100644
index 0000000..b8c4aa8
--- /dev/null
+++ b/WebKitTools/GtkLauncher/GtkLauncher.pro
@@ -0,0 +1,10 @@
+TEMPLATE = app
+SOURCES += main.c
+CONFIG -= app_bundle
+
+BASE_DIR = $$PWD/../..
+
+include(../../WebKit.pri)
+
+
+QMAKE_RPATHDIR += $$OUTPUT_DIR/lib
diff --git a/WebKitTools/GtkLauncher/main.c b/WebKitTools/GtkLauncher/main.c
new file mode 100644
index 0000000..8ed2690
--- /dev/null
+++ b/WebKitTools/GtkLauncher/main.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc.
+ * Copyright (C) 2007 Alp Toker <alp@atoker.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.
+ */
+
+#include <gtk/gtk.h>
+#include <webkit/webkit.h>
+
+static GtkWidget* main_window;
+static GtkWidget* uri_entry;
+static GtkStatusbar* main_statusbar;
+static WebKitWebView* web_view;
+static gchar* main_title;
+static gint load_progress;
+static guint status_context_id;
+
+static void
+activate_uri_entry_cb (GtkWidget* entry, gpointer data)
+{
+ const gchar* uri = gtk_entry_get_text (GTK_ENTRY (entry));
+ g_assert (uri);
+ webkit_web_view_open (web_view, uri);
+}
+
+static void
+update_title (GtkWindow* window)
+{
+ GString* string = g_string_new (main_title);
+ g_string_append (string, " - WebKit Launcher");
+ if (load_progress < 100)
+ g_string_append_printf (string, " (%d%%)", load_progress);
+ gchar* title = g_string_free (string, FALSE);
+ gtk_window_set_title (window, title);
+ g_free (title);
+}
+
+static void
+link_hover_cb (WebKitWebView* page, const gchar* title, const gchar* link, gpointer data)
+{
+ /* underflow is allowed */
+ gtk_statusbar_pop (main_statusbar, status_context_id);
+ if (link)
+ gtk_statusbar_push (main_statusbar, status_context_id, link);
+}
+
+static void
+title_change_cb (WebKitWebView* web_view, WebKitWebFrame* web_frame, const gchar* title, gpointer data)
+{
+ if (main_title)
+ g_free (main_title);
+ main_title = g_strdup (title);
+ update_title (GTK_WINDOW (main_window));
+}
+
+static void
+progress_change_cb (WebKitWebView* page, gint progress, gpointer data)
+{
+ load_progress = progress;
+ update_title (GTK_WINDOW (main_window));
+}
+
+static void
+load_commit_cb (WebKitWebView* page, WebKitWebFrame* frame, gpointer data)
+{
+ const gchar* uri = webkit_web_frame_get_uri(frame);
+ if (uri)
+ gtk_entry_set_text (GTK_ENTRY (uri_entry), uri);
+}
+
+static void
+destroy_cb (GtkWidget* widget, gpointer data)
+{
+ gtk_main_quit ();
+}
+
+static void
+go_back_cb (GtkWidget* widget, gpointer data)
+{
+ webkit_web_view_go_back (web_view);
+}
+
+static void
+go_forward_cb (GtkWidget* widget, gpointer data)
+{
+ webkit_web_view_go_forward (web_view);
+}
+
+static GtkWidget*
+create_browser ()
+{
+ GtkWidget* scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+
+ web_view = WEBKIT_WEB_VIEW (webkit_web_view_new ());
+ gtk_container_add (GTK_CONTAINER (scrolled_window), GTK_WIDGET (web_view));
+
+ g_signal_connect (G_OBJECT (web_view), "title-changed", G_CALLBACK (title_change_cb), web_view);
+ g_signal_connect (G_OBJECT (web_view), "load-progress-changed", G_CALLBACK (progress_change_cb), web_view);
+ g_signal_connect (G_OBJECT (web_view), "load-committed", G_CALLBACK (load_commit_cb), web_view);
+ g_signal_connect (G_OBJECT (web_view), "hovering-over-link", G_CALLBACK (link_hover_cb), web_view);
+
+ return scrolled_window;
+}
+
+static GtkWidget*
+create_statusbar ()
+{
+ main_statusbar = GTK_STATUSBAR (gtk_statusbar_new ());
+ status_context_id = gtk_statusbar_get_context_id (main_statusbar, "Link Hover");
+
+ return (GtkWidget*)main_statusbar;
+}
+
+static GtkWidget*
+create_toolbar ()
+{
+ GtkWidget* toolbar = gtk_toolbar_new ();
+
+ gtk_toolbar_set_orientation (GTK_TOOLBAR (toolbar), GTK_ORIENTATION_HORIZONTAL);
+ gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_BOTH_HORIZ);
+
+ GtkToolItem* item;
+
+ /* the back button */
+ item = gtk_tool_button_new_from_stock (GTK_STOCK_GO_BACK);
+ g_signal_connect (G_OBJECT (item), "clicked", G_CALLBACK (go_back_cb), NULL);
+ gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
+
+ /* The forward button */
+ item = gtk_tool_button_new_from_stock (GTK_STOCK_GO_FORWARD);
+ g_signal_connect (G_OBJECT (item), "clicked", G_CALLBACK (go_forward_cb), NULL);
+ gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
+
+ /* The URL entry */
+ item = gtk_tool_item_new ();
+ gtk_tool_item_set_expand (item, TRUE);
+ uri_entry = gtk_entry_new ();
+ gtk_container_add (GTK_CONTAINER (item), uri_entry);
+ g_signal_connect (G_OBJECT (uri_entry), "activate", G_CALLBACK (activate_uri_entry_cb), NULL);
+ gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
+
+ /* The go button */
+ item = gtk_tool_button_new_from_stock (GTK_STOCK_OK);
+ g_signal_connect_swapped (G_OBJECT (item), "clicked", G_CALLBACK (activate_uri_entry_cb), (gpointer)uri_entry);
+ gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
+
+ return toolbar;
+}
+
+static GtkWidget*
+create_window ()
+{
+ GtkWidget* window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_default_size (GTK_WINDOW (window), 800, 600);
+ gtk_widget_set_name (window, "GtkLauncher");
+ g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (destroy_cb), NULL);
+
+ return window;
+}
+
+int
+main (int argc, char* argv[])
+{
+ gtk_init (&argc, &argv);
+
+ GtkWidget* vbox = gtk_vbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox), create_toolbar (), FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox), create_browser (), TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox), create_statusbar (), FALSE, FALSE, 0);
+
+ main_window = create_window ();
+ gtk_container_add (GTK_CONTAINER (main_window), vbox);
+
+ gchar* uri = (gchar*) (argc > 1 ? argv[1] : "http://www.google.com/");
+ webkit_web_view_open (web_view, uri);
+
+ gtk_widget_grab_focus (GTK_WIDGET (web_view));
+ gtk_widget_show_all (main_window);
+ gtk_main ();
+
+ return 0;
+}
diff --git a/WebKitTools/GtkLauncher/simple.svg b/WebKitTools/GtkLauncher/simple.svg
new file mode 100644
index 0000000..30b13ac
--- /dev/null
+++ b/WebKitTools/GtkLauncher/simple.svg
@@ -0,0 +1,15 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
+<svg width="5cm" height="4cm"
+xmlns="http://www.w3.org/2000/svg">
+<desc>Four separate rectangles
+</desc>
+<rect x="0.5cm" y="0.5cm" width="2cm" height="1cm"/>
+<rect x="0.5cm" y="2cm" width="1cm" height="1.5cm"/>
+<rect x="3cm" y="0.5cm" width="1.5cm" height="2cm"/>
+<rect x="3.5cm" y="3cm" width="1cm" height="0.5cm"/>
+<!-- Show outline of canvas using 'rect' element -->
+<rect x=".01cm" y=".01cm" width="4.98cm" height="3.98cm"
+fill="none" stroke="blue" stroke-width=".02cm" />
+</svg>
diff --git a/WebKitTools/GtkLauncher/text.html b/WebKitTools/GtkLauncher/text.html
new file mode 100644
index 0000000..607df72
--- /dev/null
+++ b/WebKitTools/GtkLauncher/text.html
@@ -0,0 +1,9 @@
+<html>
+<head>
+<title>Hello World</title>
+<body bgcolor=#00ffff text=#000000>
+<p>
+Hello world
+</p>
+</body>
+</html>
diff --git a/WebKitTools/MIDLWrapper/MIDLWrapper.cpp b/WebKitTools/MIDLWrapper/MIDLWrapper.cpp
new file mode 100644
index 0000000..2132af8
--- /dev/null
+++ b/WebKitTools/MIDLWrapper/MIDLWrapper.cpp
@@ -0,0 +1,86 @@
+// MIDLWrapper.cpp : Just calls the built-in midl.exe with the given arguments.
+
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+#include <process.h>
+#include <stdio.h>
+#include <string>
+#include <windows.h>
+
+using namespace std;
+
+int wmain(int argc, wchar_t* argv[], wchar_t* envp[])
+{
+#ifndef NDEBUG
+ fwprintf(stderr, L"######### im in ur IDE, compiling ur c0des ########\n");
+#endif
+
+ int pathIndex = -1;
+ for (int i = 0; envp[i]; ++i)
+ if (!wcsncmp(envp[i], L"PATH=", 5)) {
+ pathIndex = i;
+ break;
+ }
+
+ if (pathIndex == -1) {
+ fwprintf(stderr, L"Couldn't find PATH environment variable!\n");
+ return -1;
+ }
+
+ wchar_t* vcbin = wcsstr(envp[pathIndex], L"WebKitTools\\vcbin");
+ if (!vcbin) {
+ fwprintf(stderr, L"Couldn't find WebKitTools\\vcbin in PATH!\n");
+ return -1;
+ }
+
+ wchar_t saved = *vcbin;
+ *vcbin = 0;
+
+ wchar_t* afterLeadingSemiColon = wcsrchr(envp[pathIndex], ';');
+ if (!afterLeadingSemiColon)
+ afterLeadingSemiColon = envp[pathIndex] + 5; // +5 for the length of "PATH="
+ else
+ afterLeadingSemiColon++;
+
+ *vcbin = saved;
+
+ size_t pathLength = wcslen(envp[pathIndex]);
+
+ wchar_t* trailingSemiColon = wcschr(vcbin, ';');
+ if (!trailingSemiColon)
+ trailingSemiColon = envp[pathIndex] + pathLength;
+
+ int vcbinLength = trailingSemiColon - afterLeadingSemiColon;
+
+ size_t newPathLength = pathLength - vcbinLength;
+
+ wchar_t* newPath = new wchar_t[newPathLength + 1];
+
+ // Copy everything before the vcbin path...
+ wchar_t* d = newPath;
+ wchar_t* s = envp[pathIndex];
+ while (s < afterLeadingSemiColon)
+ *d++ = *s++;
+
+ // Copy everything after the vcbin path...
+ s = trailingSemiColon;
+ while (*d++ = *s++);
+
+ envp[pathIndex] = newPath;
+
+#ifndef NDEBUG
+ fwprintf(stderr, L"New path: %s\n", envp[pathIndex]);
+#endif
+
+ wchar_t** newArgv = new wchar_t*[argc + 1];
+ for (int i = 0; i < argc; ++i) {
+ size_t length = wcslen(argv[i]);
+ newArgv[i] = new wchar_t[length + 3];
+ *newArgv[i] = '\"';
+ wcscpy_s(newArgv[i] + 1, length + 2, argv[i]);
+ *(newArgv[i] + 1 + length) = '\"';
+ *(newArgv[i] + 2 + length) = 0;
+ }
+ newArgv[argc] = 0;
+
+ return _wspawnvpe(_P_WAIT, L"midl", newArgv, envp);
+}
diff --git a/WebKitTools/MIDLWrapper/MIDLWrapper.sln b/WebKitTools/MIDLWrapper/MIDLWrapper.sln
new file mode 100644
index 0000000..b066df5
--- /dev/null
+++ b/WebKitTools/MIDLWrapper/MIDLWrapper.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MIDLWrapper", "MIDLWrapper.vcproj", "{CBE6BA0B-1A76-4936-BF54-7EB84E1B0F21}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {CBE6BA0B-1A76-4936-BF54-7EB84E1B0F21}.Debug|Win32.ActiveCfg = Debug|Win32
+ {CBE6BA0B-1A76-4936-BF54-7EB84E1B0F21}.Debug|Win32.Build.0 = Debug|Win32
+ {CBE6BA0B-1A76-4936-BF54-7EB84E1B0F21}.Release|Win32.ActiveCfg = Release|Win32
+ {CBE6BA0B-1A76-4936-BF54-7EB84E1B0F21}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/WebKitTools/MIDLWrapper/MIDLWrapper.vcproj b/WebKitTools/MIDLWrapper/MIDLWrapper.vcproj
new file mode 100644
index 0000000..471813d
--- /dev/null
+++ b/WebKitTools/MIDLWrapper/MIDLWrapper.vcproj
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="MIDLWrapper"
+ ProjectGUID="{CBE6BA0B-1A76-4936-BF54-7EB84E1B0F21}"
+ RootNamespace="MIDLWrapper"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="..\vcbin"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\midl.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="..\vcbin"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\midl.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\MIDLWrapper.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/WebKitTools/Makefile b/WebKitTools/Makefile
new file mode 100644
index 0000000..364eadb
--- /dev/null
+++ b/WebKitTools/Makefile
@@ -0,0 +1,30 @@
+MODULES = Drosera DumpRenderTree
+
+all:
+ @for dir in $(MODULES); do ${MAKE} $@ -C $$dir; exit_status=$$?; \
+ if [ $$exit_status -ne 0 ]; then exit $$exit_status; fi; done
+
+debug d development dev develop:
+ @for dir in $(MODULES); do ${MAKE} $@ -C $$dir; exit_status=$$?; \
+ if [ $$exit_status -ne 0 ]; then exit $$exit_status; fi; done
+
+release r deployment dep deploy:
+ @for dir in $(MODULES); do ${MAKE} $@ -C $$dir; exit_status=$$?; \
+ if [ $$exit_status -ne 0 ]; then exit $$exit_status; fi; done
+
+universal u:
+ @for dir in $(MODULES); do ${MAKE} $@ -C $$dir; exit_status=$$?; \
+ if [ $$exit_status -ne 0 ]; then exit $$exit_status; fi; done
+
+64:
+ @for dir in $(MODULES); do ${MAKE} $@ -C $$dir; exit_status=$$?; \
+ if [ $$exit_status -ne 0 ]; then exit $$exit_status; fi; done
+
+64u:
+ @for dir in $(MODULES); do ${MAKE} $@ -C $$dir; exit_status=$$?; \
+ if [ $$exit_status -ne 0 ]; then exit $$exit_status; fi; done
+
+clean:
+ @for dir in $(MODULES); do ${MAKE} $@ -C $$dir; exit_status=$$?; \
+ if [ $$exit_status -ne 0 ]; then exit $$exit_status; fi; done
+
diff --git a/WebKitTools/Scripts/SpacingHeuristics.pm b/WebKitTools/Scripts/SpacingHeuristics.pm
new file mode 100644
index 0000000..7de0172
--- /dev/null
+++ b/WebKitTools/Scripts/SpacingHeuristics.pm
@@ -0,0 +1,101 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2006 Apple Computer, 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.
+
+# Used for helping remove extra blank lines from files when processing.
+# see split-class for an example usage (or other scripts in bugzilla)
+
+BEGIN {
+ use Exporter ();
+ our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
+ $VERSION = 1.00;
+ @ISA = qw(Exporter);
+ @EXPORT = qw(&resetSpacingHeuristics &isOnlyWhiteSpace &applySpacingHeuristicsAndPrint &setPreviousAllowedLine &setPreviousAllowedLine &printPendingEmptyLines &ignoringLine);
+ %EXPORT_TAGS = ();
+ @EXPORT_OK = ();
+}
+
+our @EXPORT_OK;
+
+my $justFoundEmptyLine = 0;
+my $previousLineWasDisallowed = 0;
+my $previousAllowedLine = "";
+my $pendingEmptyLines = "";
+
+sub resetSpacingHeuristics
+{
+ $justFoundEmptyLine = 0;
+ $previousLineWasDisallowed = 0;
+ $previousAllowedLine = "";
+ $pendingEmptyLines = "";
+}
+
+sub isOnlyWhiteSpace
+{
+ my $line = shift;
+ my $isOnlyWhiteSpace = ($line =~ m/^\s+$/);
+ $pendingEmptyLines .= $line if ($isOnlyWhiteSpace);
+ return $isOnlyWhiteSpace;
+}
+
+sub applySpacingHeuristicsAndPrint
+{
+ my ($out, $line) = @_;
+
+ printPendingEmptyLines($out, $line);
+ $previousLineWasDisallowed = 0;
+ print $out $line;
+}
+
+sub setPreviousAllowedLine
+{
+ my $line = shift;
+ $previousAllowedLine = $line;
+}
+
+sub printPendingEmptyLines
+{
+ my $out = shift;
+ my $line = shift;
+ if ($previousLineWasDisallowed) {
+ if (!($pendingEmptyLines eq "") && !($previousAllowedLine =~ m/{\s*$/) && !($line =~ m/^\s*}/)) {
+ $pendingEmptyLines = "\n";
+ } else {
+ $pendingEmptyLines = "";
+ }
+ }
+ print $out $pendingEmptyLines;
+ $pendingEmptyLines = "";
+}
+
+sub ignoringLine
+{
+ # my $line = shift; # ignoring input argument
+ $previousLineWasDisallowed = 1;
+}
+
+1; \ No newline at end of file
diff --git a/WebKitTools/Scripts/VCSUtils.pm b/WebKitTools/Scripts/VCSUtils.pm
new file mode 100644
index 0000000..26401f4
--- /dev/null
+++ b/WebKitTools/Scripts/VCSUtils.pm
@@ -0,0 +1,121 @@
+# 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.
+
+# Module to share code to work with various version control systems.
+
+use strict;
+use warnings;
+use File::Spec;
+use webkitdirs;
+
+BEGIN {
+ use Exporter ();
+ our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
+ $VERSION = 1.00;
+ @ISA = qw(Exporter);
+ @EXPORT = qw(&isGitDirectory &isGit &isSVNDirectory &isSVN &makeFilePathRelative);
+ %EXPORT_TAGS = ( );
+ @EXPORT_OK = ();
+}
+
+our @EXPORT_OK;
+
+my $isGit;
+my $isSVN;
+my $gitBranch;
+my $isGitBranchBuild;
+
+sub isGitDirectory($)
+{
+ my ($dir) = @_;
+ return system("cd $dir && git rev-parse > /dev/null 2>&1") == 0;
+}
+
+sub isGit()
+{
+ return $isGit if defined $isGit;
+
+ $isGit = isGitDirectory(".");
+ return $isGit;
+}
+
+sub gitBranch()
+{
+ unless (defined $gitBranch) {
+ chomp($gitBranch = `git symbolic-ref -q HEAD`);
+ $gitBranch = "" if exitStatus($?);
+ $gitBranch =~ s#^refs/heads/##;
+ $gitBranch = "" if $gitBranch eq "master";
+ }
+
+ return $gitBranch;
+}
+
+sub isGitBranchBuild()
+{
+ my $branch = gitBranch();
+ chomp(my $override = `git config --bool branch.$branch.webKitBranchBuild`);
+ return 1 if $override eq "true";
+ return 0 if $override eq "false";
+
+ unless (defined $isGitBranchBuild) {
+ chomp(my $gitBranchBuild = `git config --bool core.webKitBranchBuild`);
+ $isGitBranchBuild = $gitBranchBuild eq "true";
+ }
+
+ return $isGitBranchBuild;
+}
+
+sub isSVNDirectory($)
+{
+ my ($dir) = @_;
+
+ return -d File::Spec->catdir($dir, ".svn");
+}
+
+sub isSVN()
+{
+ return $isSVN if defined $isSVN;
+
+ $isSVN = isSVNDirectory(".");
+ return $isSVN;
+}
+
+my $gitRoot;
+sub makeFilePathRelative($)
+{
+ my ($path) = @_;
+ return $path unless isGit();
+
+ unless (defined $gitRoot) {
+ chomp($gitRoot = `git rev-parse --git-dir`);
+ $gitRoot =~ s/\.git$//;
+ }
+ my $result = File::Spec->abs2rel(File::Spec->rel2abs($path, $gitRoot));
+ return $result;
+}
+
+1;
diff --git a/WebKitTools/Scripts/bisect-builds b/WebKitTools/Scripts/bisect-builds
new file mode 100755
index 0000000..43e3889
--- /dev/null
+++ b/WebKitTools/Scripts/bisect-builds
@@ -0,0 +1,417 @@
+#!/usr/bin/perl -w
+
+# 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.
+
+# This script attempts to find the point at which a regression (or progression)
+# of behavior occurred by searching WebKit nightly builds.
+
+# To override the location where the nightly builds are downloaded or the path
+# to the Safari web browser, create a ~/.bisect-buildsrc file with one or more of
+# the following lines (use "~/" to specify a path from your home directory):
+#
+# $branch = "branch-name";
+# $nightlyDownloadDirectory = "~/path/to/nightly/downloads";
+# $safariPath = "/path/to/Safari.app";
+
+use strict;
+
+use File::Basename;
+use File::Path;
+use File::Spec;
+use File::Temp;
+use Getopt::Long;
+use Time::HiRes qw(usleep);
+
+sub createTempFile($);
+sub downloadNightly($$$);
+sub findMacOSXVersion();
+sub findNearestNightlyIndex(\@$$);
+sub findSafariVersion($);
+sub loadSettings();
+sub makeNightlyList($$$$);
+sub mountAndRunNightly($$$$);
+sub parseRevisions($$;$);
+sub printStatus($$$);
+sub promptForTest($);
+
+loadSettings();
+
+my %validBranches = map { $_ => 1 } qw(feature-branch trunk);
+my $branch = $Settings::branch;
+my $nightlyDownloadDirectory = $Settings::nightlyDownloadDirectory;
+my $safariPath = $Settings::safariPath;
+
+my @nightlies;
+
+my $isProgression;
+my $localOnly;
+my @revisions;
+my $sanityCheck;
+my $showHelp;
+my $testURL;
+
+# Fix up -r switches in @ARGV
+@ARGV = map { /^(-r)(.+)$/ ? ($1, $2) : $_ } @ARGV;
+
+my $result = GetOptions(
+ "b|branch=s" => \$branch,
+ "d|download-directory=s" => \$nightlyDownloadDirectory,
+ "h|help" => \$showHelp,
+ "l|local!" => \$localOnly,
+ "p|progression!" => \$isProgression,
+ "r|revisions=s" => \&parseRevisions,
+ "safari-path=s" => \$safariPath,
+ "s|sanity-check!" => \$sanityCheck,
+);
+$testURL = shift @ARGV;
+
+$branch = "feature-branch" if $branch eq "feature";
+if (!exists $validBranches{$branch}) {
+ print STDERR "ERROR: Invalid branch '$branch'\n";
+ $showHelp = 1;
+}
+
+if (!$result || $showHelp || scalar(@ARGV) > 0) {
+ print STDERR "Search WebKit nightly builds for changes in behavior.\n";
+ print STDERR "Usage: " . basename($0) . " [options] [url]\n";
+ print STDERR <<END;
+ [-b|--branch name] name of the nightly build branch (default: trunk)
+ [-d|--download-directory dir] nightly build download directory (default: ~/Library/Caches/WebKit-Nightlies)
+ [-h|--help] show this help message
+ [-l|--local] only use local (already downloaded) nightlies
+ [-p|--progression] searching for a progression, not a regression
+ [-r|--revision M[:N]] specify starting (and optional ending) revisions to search
+ [--safari-path path] path to Safari application bundle (default: /Applications/Safari.app)
+ [-s|--sanity-check] verify both starting and ending revisions before bisecting
+END
+ exit 1;
+}
+
+my $nightlyWebSite = "http://nightly.webkit.org";
+my $nightlyBuildsURLBase = $nightlyWebSite . File::Spec->catdir("/builds", $branch, "mac");
+my $nightlyFilesURLBase = $nightlyWebSite . File::Spec->catdir("/files", $branch, "mac");
+
+$nightlyDownloadDirectory = glob($nightlyDownloadDirectory) if $nightlyDownloadDirectory =~ /^~/;
+$safariPath = glob($safariPath) if $safariPath =~ /^~/;
+$safariPath = File::Spec->catdir($safariPath, "Contents/MacOS/Safari") if $safariPath =~ m#\.app/*#;
+
+$nightlyDownloadDirectory = File::Spec->catdir($nightlyDownloadDirectory, $branch);
+if (! -d $nightlyDownloadDirectory) {
+ mkpath($nightlyDownloadDirectory, 0, 0755) || die "Could not create $nightlyDownloadDirectory: $!";
+}
+
+@nightlies = makeNightlyList($localOnly, $nightlyDownloadDirectory, findMacOSXVersion(), findSafariVersion($safariPath));
+
+my $startIndex = $revisions[0] ? findNearestNightlyIndex(@nightlies, $revisions[0], 'ceil') : 0;
+my $endIndex = $revisions[1] ? findNearestNightlyIndex(@nightlies, $revisions[1], 'floor') : $#nightlies;
+
+my $tempFile = createTempFile($testURL);
+
+if ($sanityCheck) {
+ my $didReproduceBug;
+
+ do {
+ printf "\nChecking starting revision (r%s)...\n",
+ $nightlies[$startIndex]->{rev};
+ downloadNightly($nightlies[$startIndex]->{file}, $nightlyFilesURLBase, $nightlyDownloadDirectory);
+ mountAndRunNightly($nightlies[$startIndex]->{file}, $nightlyDownloadDirectory, $safariPath, $tempFile);
+ $didReproduceBug = promptForTest($nightlies[$startIndex]->{rev});
+ $startIndex-- if $didReproduceBug < 0;
+ } while ($didReproduceBug < 0);
+ die "ERROR: Bug reproduced in starting revision! Do you need to test an earlier revision or for a progression?"
+ if $didReproduceBug && !$isProgression;
+ die "ERROR: Bug not reproduced in starting revision! Do you need to test an earlier revision or for a regression?"
+ if !$didReproduceBug && $isProgression;
+
+ do {
+ printf "\nChecking ending revision (r%s)...\n",
+ $nightlies[$endIndex]->{rev};
+ downloadNightly($nightlies[$endIndex]->{file}, $nightlyFilesURLBase, $nightlyDownloadDirectory);
+ mountAndRunNightly($nightlies[$endIndex]->{file}, $nightlyDownloadDirectory, $safariPath, $tempFile);
+ $didReproduceBug = promptForTest($nightlies[$endIndex]->{rev});
+ $endIndex++ if $didReproduceBug < 0;
+ } while ($didReproduceBug < 0);
+ die "ERROR: Bug NOT reproduced in ending revision! Do you need to test a later revision or for a progression?"
+ if !$didReproduceBug && !$isProgression;
+ die "ERROR: Bug reproduced in ending revision! Do you need to test a later revision or for a regression?"
+ if $didReproduceBug && $isProgression;
+}
+
+printStatus($nightlies[$startIndex]->{rev}, $nightlies[$endIndex]->{rev}, $isProgression);
+
+my %brokenRevisions = ();
+while (abs($endIndex - $startIndex) > 1) {
+ my $index = $startIndex + int(($endIndex - $startIndex) / 2);
+
+ my $didReproduceBug;
+ do {
+ if (exists $nightlies[$index]) {
+ printf "\nChecking revision (r%s)...\n", $nightlies[$index]->{rev};
+ downloadNightly($nightlies[$index]->{file}, $nightlyFilesURLBase, $nightlyDownloadDirectory);
+ mountAndRunNightly($nightlies[$index]->{file}, $nightlyDownloadDirectory, $safariPath, $tempFile);
+ $didReproduceBug = promptForTest($nightlies[$index]->{rev});
+ }
+ if ($didReproduceBug < 0) {
+ $brokenRevisions{$nightlies[$index]->{rev}} = $nightlies[$index]->{file};
+ delete $nightlies[$index];
+ $endIndex--;
+ $index = $startIndex + int(($endIndex - $startIndex) / 2);
+ }
+ } while ($didReproduceBug < 0);
+
+ if ($didReproduceBug && !$isProgression || !$didReproduceBug && $isProgression) {
+ $endIndex = $index;
+ } else {
+ $startIndex = $index;
+ }
+
+ print "\nBroken revisions skipped: r" . join(", r", keys %brokenRevisions) . "\n"
+ if scalar keys %brokenRevisions > 0;
+ printStatus($nightlies[$startIndex]->{rev}, $nightlies[$endIndex]->{rev}, $isProgression);
+}
+
+unlink $tempFile if $tempFile;
+
+exit 0;
+
+sub createTempFile($)
+{
+ my ($url) = @_;
+
+ return undef if !$url;
+
+ my $fh = new File::Temp(
+ DIR => ($ENV{'TMPDIR'} || "/tmp"),
+ SUFFIX => ".html",
+ TEMPLATE => basename($0) . "-XXXXXXXX",
+ UNLINK => 0,
+ );
+ my $tempFile = $fh->filename();
+ print $fh "<meta http-equiv=\"refresh\" content=\"0; $url\">\n";
+ close($fh);
+
+ return $tempFile;
+}
+
+sub downloadNightly($$$)
+{
+ my ($filename, $urlBase, $directory) = @_;
+ my $path = File::Spec->catfile($directory, $filename);
+ if (! -f $path) {
+ print "Downloading $filename to $directory...\n";
+ `curl -# -o '$path' '$urlBase/$filename'`;
+ }
+}
+
+sub findMacOSXVersion()
+{
+ my $version;
+ open(SW_VERS, "-|", "/usr/bin/sw_vers") || die;
+ while (<SW_VERS>) {
+ $version = $1 if /^ProductVersion:\s+([^\s]+)/;
+ }
+ close(SW_VERS);
+ return $version;
+}
+
+sub findNearestNightlyIndex(\@$$)
+{
+ my ($nightlies, $revision, $round) = @_;
+
+ my $lowIndex = 0;
+ my $highIndex = $#{$nightlies};
+
+ return $highIndex if uc($revision) eq 'HEAD' || $revision >= $nightlies->[$highIndex]->{rev};
+ return $lowIndex if $revision <= $nightlies->[$lowIndex]->{rev};
+
+ while (abs($highIndex - $lowIndex) > 1) {
+ my $index = $lowIndex + int(($highIndex - $lowIndex) / 2);
+ if ($revision < $nightlies->[$index]->{rev}) {
+ $highIndex = $index;
+ } elsif ($revision > $nightlies->[$index]->{rev}) {
+ $lowIndex = $index;
+ } else {
+ return $index;
+ }
+ }
+
+ return ($round eq "floor") ? $lowIndex : $highIndex;
+}
+
+sub findSafariVersion($)
+{
+ my ($path) = @_;
+ my $versionPlist = File::Spec->catdir(dirname(dirname($path)), "version.plist");
+ my $version;
+ open(PLIST, "< $versionPlist") || die;
+ while (<PLIST>) {
+ if (m#^\s*<key>CFBundleShortVersionString</key>#) {
+ $version = <PLIST>;
+ $version =~ s#^\s*<string>(.+)</string>\s*[\r\n]*#$1#;
+ }
+ }
+ close(PLIST);
+ return $version;
+}
+
+sub loadSettings()
+{
+ package Settings;
+
+ our $branch = "trunk";
+ our $nightlyDownloadDirectory = File::Spec->catdir($ENV{HOME}, "Library/Caches/WebKit-Nightlies");
+ our $safariPath = "/Applications/Safari.app";
+
+ my $rcfile = File::Spec->catdir($ENV{HOME}, ".bisect-buildsrc");
+ return if !-f $rcfile;
+
+ my $result = do $rcfile;
+ die "Could not parse $rcfile: $@" if $@;
+}
+
+sub makeNightlyList($$$$)
+{
+ my ($useLocalFiles, $localDirectory, $macOSXVersion, $safariVersion) = @_;
+ my @files;
+
+ if ($useLocalFiles) {
+ opendir(DIR, $localDirectory) || die "$!";
+ foreach my $file (readdir(DIR)) {
+ if ($file =~ /^WebKit-SVN-r([0-9]+)\.dmg$/) {
+ push(@files, +{ rev => $1, file => $file });
+ }
+ }
+ closedir(DIR);
+ } else {
+ open(NIGHTLIES, "curl -s $nightlyBuildsURLBase/all |") || die;
+
+ while (my $line = <NIGHTLIES>) {
+ chomp $line;
+ my ($revision, $timestamp, $url) = split(/,/, $line);
+ my $nightly = basename($url);
+ push(@files, +{ rev => $revision, file => $nightly });
+ }
+ close(NIGHTLIES);
+ }
+
+ if (eval "v$macOSXVersion" ge v10.5) {
+ if (eval "v$safariVersion" ge v3.0) {
+ @files = grep { $_->{rev} >= 25124 } @files;
+ } elsif (eval "v$safariVersion" ge v2.0) {
+ @files = grep { $_->{rev} >= 19594 } @files;
+ } else {
+ die "Requires Safari 2.0 or newer";
+ }
+ } elsif (eval "v$macOSXVersion" ge v10.4) {
+ if (eval "v$safariVersion" ge v3.0) {
+ @files = grep { $_->{rev} >= 19992 } @files;
+ } elsif (eval "v$safariVersion" ge v2.0) {
+ @files = grep { $_->{rev} >= 11976 } @files;
+ } else {
+ die "Requires Safari 2.0 or newer";
+ }
+ } else {
+ die "Requires Mac OS X 10.4 (Tiger) or 10.5 (Leopard)";
+ }
+
+ my $nightlycmp = sub { return $a->{rev} <=> $b->{rev}; };
+
+ return sort $nightlycmp @files;
+}
+
+sub mountAndRunNightly($$$$)
+{
+ my ($filename, $directory, $safari, $tempFile) = @_;
+ my $mountPath = "/Volumes/WebKit";
+ my $webkitApp = File::Spec->catfile($mountPath, "WebKit.app");
+ my $diskImage = File::Spec->catfile($directory, $filename);
+
+ my $i = 0;
+ while (-e $mountPath) {
+ $i++;
+ usleep 100 if $i > 1;
+ `hdiutil detach '$mountPath' 2> /dev/null`;
+ die "Could not unmount $diskImage at $mountPath" if $i > 100;
+ }
+ die "Can't mount $diskImage: $mountPath already exists!" if -e $mountPath;
+
+ print "Mounting disk image and running WebKit...\n";
+ `hdiutil attach '$diskImage'`;
+ $i = 0;
+ while (! -e $webkitApp) {
+ usleep 100;
+ $i++;
+ die "Could not mount $diskImage at $mountPath" if $i > 100;
+ }
+
+ my $frameworkPath;
+ if (-d "/Volumes/WebKit/WebKit.app/Contents/Frameworks") {
+ my $osXVersion = join('.', (split(/\./, findMacOSXVersion()))[0..1]);
+ $frameworkPath = "/Volumes/WebKit/WebKit.app/Contents/Frameworks/$osXVersion";
+ } else {
+ $frameworkPath = "/Volumes/WebKit/WebKit.app/Contents/Resources";
+ }
+
+ $tempFile ||= "";
+ `DYLD_FRAMEWORK_PATH=$frameworkPath WEBKIT_UNSET_DYLD_FRAMEWORK_PATH=YES $safari $tempFile`;
+
+ `hdiutil detach '$mountPath' 2> /dev/null`;
+}
+
+sub parseRevisions($$;$)
+{
+ my ($optionName, $value, $ignored) = @_;
+
+ if ($value =~ /^r?([0-9]+|HEAD):?$/i) {
+ push(@revisions, $1);
+ die "Too many revision arguments specified" if scalar @revisions > 2;
+ } elsif ($value =~ /^r?([0-9]+):?r?([0-9]+|HEAD)$/i) {
+ $revisions[0] = $1;
+ $revisions[1] = $2;
+ } else {
+ die "Unknown revision '$value': expected 'M' or 'M:N'";
+ }
+}
+
+sub printStatus($$$)
+{
+ my ($startRevision, $endRevision, $isProgression) = @_;
+ printf "\n%s: r%s %s: r%s\n",
+ $isProgression ? "Fails" : "Works", $startRevision,
+ $isProgression ? "Works" : "Fails", $endRevision;
+}
+
+sub promptForTest($)
+{
+ my ($revision) = @_;
+ print "Did the bug reproduce in r$revision (yes/no/broken)? ";
+ my $answer = <STDIN>;
+ return 1 if $answer =~ /^(1|y.*)$/i;
+ return -1 if $answer =~ /^(-1|b.*)$/i; # Broken
+ return 0;
+}
+
diff --git a/WebKitTools/Scripts/build-drawtest b/WebKitTools/Scripts/build-drawtest
new file mode 100755
index 0000000..fa9b7c2
--- /dev/null
+++ b/WebKitTools/Scripts/build-drawtest
@@ -0,0 +1,48 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005, 2006 Apple Computer, 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.
+
+# Simplified build script for WebKit Open Source Project.
+# Modified copy of build-dumprendertree. Perhaps these could share code.
+
+use strict;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+
+checkRequiredSystemConfig();
+setConfiguration();
+chdirWebKit();
+my @options = XcodeOptions();
+
+# Check to see that all the frameworks are built (w/ SVG support).
+checkFrameworks();
+checkWebCoreSVGSupport(1);
+
+# Build
+chdir "WebKitTools/DrawTest" or die;
+exit system "xcodebuild", "-project", "DrawTest.xcodeproj", @options;
diff --git a/WebKitTools/Scripts/build-drosera b/WebKitTools/Scripts/build-drosera
new file mode 100755
index 0000000..f3b1144
--- /dev/null
+++ b/WebKitTools/Scripts/build-drosera
@@ -0,0 +1,53 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2006 Apple Computer, 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.
+
+# Simplified build script for Web Kit Open Source Project.
+# Modified copy of build-webkit. Perhaps these could share code.
+# Currently only works for the Deployment build style.
+
+use strict;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+use POSIX;
+
+checkRequiredSystemConfig();
+setConfiguration();
+chdirWebKit();
+my @options = XcodeOptions();
+
+# Build
+chdir "WebKitTools/Drosera/mac" or die;
+my $result;
+if (isOSX()) {
+ print "xcodebuild -project Drosera.xcodeproj ", join(" ", @options), "\n";
+ $result = system "xcodebuild", "-project", "Drosera.xcodeproj", @options;
+} else {
+ die "Building not defined for this platform!\n";
+}
+exit exitStatus($result);
diff --git a/WebKitTools/Scripts/build-dumprendertree b/WebKitTools/Scripts/build-dumprendertree
new file mode 100755
index 0000000..7f48a59
--- /dev/null
+++ b/WebKitTools/Scripts/build-dumprendertree
@@ -0,0 +1,54 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005 Apple Computer, 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.
+
+
+use strict;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+use POSIX;
+
+checkRequiredSystemConfig();
+setConfiguration();
+chdirWebKit();
+my @options = XcodeOptions();
+
+# Build
+chdir "WebKitTools/DumpRenderTree" or die;
+my $result;
+if (isOSX()) {
+ $result = system "xcodebuild", "-project", "DumpRenderTree.xcodeproj", @options;
+} elsif (isCygwin()) {
+ $result = buildVisualStudioProject("DumpRenderTree.sln");
+} elsif (isQt() || isGtk()) {
+ # Qt and Gtk build everything in one shot. No need to build anything here.
+ $result = 0;
+} else {
+ die "Building not defined for this platform!\n";
+}
+exit exitStatus($result);
diff --git a/WebKitTools/Scripts/build-testkjs b/WebKitTools/Scripts/build-testkjs
new file mode 100755
index 0000000..5dc28ad
--- /dev/null
+++ b/WebKitTools/Scripts/build-testkjs
@@ -0,0 +1,54 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
+# Copyright (C) 2007 Eric Seidel <eric@webkit.org>
+#
+# 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.
+
+
+use strict;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+use POSIX;
+
+checkRequiredSystemConfig();
+setConfiguration();
+chdirWebKit();
+my @options = XcodeOptions();
+
+chdir "JavaScriptCore" or die "Can't find JavaScriptCore directory to build from";
+my $result;
+if (isOSX()) {
+ $result = system "sh", "-c", 'xcodebuild -project JavaScriptCore.xcodeproj -target testkjs "$@" | grep -v setenv && exit ${PIPESTATUS[0]}', "xcodebuild", @options, @ARGV;
+} elsif (isCygwin()) {
+ $result = buildVisualStudioProject("JavaScriptCore.vcproj/JavaScriptCore.sln");
+} elsif (isQt() or isGtk() or isWx()) {
+ # Qt and Gtk build everything in one-shot. No need to build anything here.
+ $result = 0;
+} else {
+ die "Building not defined for this platform!\n";
+}
+exit exitStatus($result);
diff --git a/WebKitTools/Scripts/build-webkit b/WebKitTools/Scripts/build-webkit
new file mode 100755
index 0000000..f4c99e6
--- /dev/null
+++ b/WebKitTools/Scripts/build-webkit
@@ -0,0 +1,351 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005, 2006 Apple Computer, 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.
+
+# Simplified build script for Web Kit Open Source Project.
+
+use strict;
+use File::Basename;
+use File::Spec;
+use FindBin;
+use Getopt::Long qw(:config pass_through);
+use lib $FindBin::Bin;
+use webkitdirs;
+use POSIX;
+
+my $originalWorkingDirectory = getcwd();
+
+my $crossDocumentMessagingSupport = 1;
+my $databaseSupport = 1;
+my $iconDatabaseSupport = 1;
+my $svgSupport = 1;
+my $svgExperimentalSupport = 0;
+my $svgAnimationSupport = $svgExperimentalSupport;
+my $svgFiltersSupport = $svgExperimentalSupport;
+my $svgForeignObjectSupport = 1;
+my $svgUseSupport = 1;
+my $svgFontsSupport = 1;
+my $svgAsImageSupport = 1;
+my $xpathSupport = 1;
+my $xsltSupport = 1;
+my $coverageSupport = 0;
+my $videoSupport = isOSX() || isCygwin(); # Enable by default on OSX and Windows
+my $showHelp = 0;
+my $clean = 0;
+my $buildUniversal = 0;
+my $buildSixtyFourBit = 0;
+
+my $programName = basename($0);
+my $usage = <<EOF;
+Usage: $programName [options] [options to pass to build system]
+ --help Show this help message
+ --clean Perform a clean build
+ --universal Build 2-way universal (PPC and Intel 32-bit)
+ --64-bit Build 64-bit, combine with --universal to build 4-way universal
+ --[no-]cross-document-messaging Toggle cross-document messaging support (default: $crossDocumentMessagingSupport)
+ --[no-]database Toggle Database Support (default: $databaseSupport)
+ --[no-]icon-database Toggle Icon database support (default: $iconDatabaseSupport)
+ --[no-]svg Toggle SVG support (default: $svgSupport)
+ --[no-]svg-experimental Toggle SVG experimental features support (default: $svgExperimentalSupport,
+ implies SVG Support)
+ --[no-]svg-animation Toggle SVG animation support (default: $svgAnimationSupport, implies SVG Support)
+ --[no-]svg-filters Toggle SVG filters support (default: $svgFiltersSupport, implies SVG Support)
+ --[no-]svg-foreign-object Toggle SVG forgeing object support (default: $svgForeignObjectSupport, implies SVG Support)
+ --[no-]svg-fonts Toggle SVG fonts support (default: $svgFontsSupport, implies SVG Support)
+ --[no-]svg-as-image Toggle SVG as Image support (default: $svgAsImageSupport, implies SVG Support)
+ --[no-]svg-use Toggle SVG use element support (default: $svgUseSupport, implies SVG Support)
+ --[no-]xpath Toggle XPath support (default: $xpathSupport)
+ --[no-]xslt Toggle XSLT support (default: $xsltSupport)
+ --[no-]video Toggle Video support (default: $videoSupport)
+ --[no-]coverage Toggle code coverage support (default: $coverageSupport)
+EOF
+
+GetOptions('cross-document-messaging!' => \$crossDocumentMessagingSupport,
+ 'database!' => \$databaseSupport,
+ 'icon-database!' => \$iconDatabaseSupport,
+ 'svg!' => \$svgSupport,
+ 'svg-experimental!' => \$svgExperimentalSupport,
+ 'svg-animation!' => \$svgAnimationSupport,
+ 'svg-filters!' => \$svgFiltersSupport,
+ 'svg-foreign-object!' => \$svgForeignObjectSupport,
+ 'svg-fonts!' => \$svgFontsSupport,
+ 'svg-as-image!' => \$svgAsImageSupport,
+ 'svg-use!' => \$svgUseSupport,
+ 'xpath!' => \$xpathSupport,
+ 'xslt!' => \$xsltSupport,
+ 'video!' => \$videoSupport,
+ 'coverage!' => \$coverageSupport,
+ 'help' => \$showHelp,
+ 'universal' => \$buildUniversal,
+ '64-bit' => \$buildSixtyFourBit,
+ 'clean' => \$clean);
+
+if ($showHelp) {
+ print STDERR $usage;
+ exit 1;
+}
+
+$svgExperimentalSupport = 0 unless $svgSupport;
+$svgAnimationSupport = 0 unless $svgSupport;
+$svgFiltersSupport = 0 unless $svgSupport;
+$svgForeignObjectSupport = 0 unless $svgSupport;
+$svgFontsSupport = 0 unless $svgSupport;
+$svgAsImageSupport = 0 unless $svgSupport;
+$svgUseSupport = 0 unless $svgSupport;
+
+if ($svgExperimentalSupport) {
+ $svgAnimationSupport = 1;
+ $svgFiltersSupport = 1;
+ $svgForeignObjectSupport = 1;
+ $svgFontsSupport = 1;
+ $svgAsImageSupport = 1;
+ $svgUseSupport = 1;
+}
+
+checkRequiredSystemConfig();
+setConfiguration();
+chdirWebKit();
+
+# FIXME: Migrate build-wxwebkit commands into build-webkit.
+if (isWx()) {
+ my @opts = ();
+ $ENV{"WEBKITOUTPUTDIR"} = productDir();
+ foreach (@ARGV) {
+ if ($_ eq "wxgc" || $_ eq "wxpython") {
+ push(@opts, $_);
+ }
+ }
+ if ($clean) {
+ push(@opts, "clean");
+ }
+ system "WebKitTools/wx/build-wxwebkit @opts";
+ exit exitStatus($?);
+}
+
+
+my $productDir = productDir();
+my @overrideFeatureDefinesOption = ();
+
+push @overrideFeatureDefinesOption, "ENABLE_CROSS_DOCUMENT_MESSAGING" if $crossDocumentMessagingSupport;
+push @overrideFeatureDefinesOption, "ENABLE_DATABASE" if $databaseSupport;
+push @overrideFeatureDefinesOption, "ENABLE_ICONDATABASE" if $iconDatabaseSupport;
+push @overrideFeatureDefinesOption, "ENABLE_SVG" if $svgSupport;
+push @overrideFeatureDefinesOption, "ENABLE_SVG_ANIMATION" if $svgAnimationSupport;
+push @overrideFeatureDefinesOption, "ENABLE_SVG_FILTERS" if $svgFiltersSupport;
+push @overrideFeatureDefinesOption, "ENABLE_SVG_FOREIGN_OBJECT" if $svgForeignObjectSupport;
+push @overrideFeatureDefinesOption, "ENABLE_SVG_FONTS" if $svgFontsSupport;
+push @overrideFeatureDefinesOption, "ENABLE_SVG_AS_IMAGE" if $svgAsImageSupport;
+push @overrideFeatureDefinesOption, "ENABLE_SVG_USE" if $svgUseSupport;
+push @overrideFeatureDefinesOption, "ENABLE_XPATH" if $xpathSupport;
+push @overrideFeatureDefinesOption, "ENABLE_XSLT" if $xsltSupport;
+push @overrideFeatureDefinesOption, "ENABLE_VIDEO" if $videoSupport;
+my $overrideFeatureDefinesString = "FEATURE_DEFINES=" . join(" ", @overrideFeatureDefinesOption);
+
+my @coverageSupportOption = ();
+if ($coverageSupport) {
+ push @coverageSupportOption, "GCC_GENERATE_TEST_COVERAGE_FILES=YES";
+ push @coverageSupportOption, "GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES";
+ push @coverageSupportOption, "EXTRA_LINK= -ftest-coverage -fprofile-arcs";
+ push @coverageSupportOption, "OTHER_CFLAGS= -MD";
+ push @coverageSupportOption, "OTHER_LDFLAGS=\$(OTHER_LDFLAGS) -ftest-coverage -fprofile-arcs -framework AppKit";
+}
+
+# Check that all the project directories are there.
+my @projects = ("JavaScriptCore", "JavaScriptGlue", "WebCore", "WebKit");
+my @otherDirs = ("WebKitLibraries");
+for my $dir (@projects, @otherDirs) {
+ if (! -d $dir) {
+ die "Error: No $dir directory found. Please do a fresh checkout.\n";
+ }
+}
+
+my @options = ();
+
+if ($clean && isOSX()) {
+ push(@options, "-alltargets");
+ push(@options, "clean");
+}
+
+if ($buildSixtyFourBit && isOSX()) {
+ my $cpuVendor = `sysctl -n machdep.cpu.vendor`;
+ chomp $cpuVendor;
+
+ if ($buildUniversal) {
+ push(@options, "ARCHS=ppc ppc64 i386 x86_64");
+ } elsif ($cpuVendor eq "GenuineIntel") {
+ push(@options, "ARCHS=i386 x86_64");
+ } else {
+ push(@options, "ARCHS=ppc ppc64");
+ }
+} elsif ($buildUniversal && isOSX()) {
+ push(@options, "ARCHS=ppc i386");
+}
+
+# enable autotool options accordingly
+if ($ENV{WEBKITAUTOTOOLS}) {
+ push @options, autotoolsFlag($crossDocumentMessagingSupport, "cross-document-messaging");
+ push @options, autotoolsFlag($databaseSupport, "database");
+ push @options, autotoolsFlag($iconDatabaseSupport, "icon-database");
+ push @options, autotoolsFlag($svgSupport, "svg");
+ push @options, autotoolsFlag($svgAnimationSupport, "svg-animation");
+ push @options, autotoolsFlag($svgFiltersSupport, "svg-filters");
+ push @options, autotoolsFlag($svgForeignObjectSupport, "svg-foreign-object");
+ push @options, autotoolsFlag($svgFontsSupport, "svg-fonts");
+ push @options, autotoolsFlag($svgAsImageSupport, "svg-as-image");
+ push @options, autotoolsFlag($svgUseSupport, "svg-use-element");
+ push @options, autotoolsFlag($xpathSupport, "xpath");
+ push @options, autotoolsFlag($xsltSupport, "xslt");
+ push @options, autotoolsFlag($videoSupport, "video");
+ push @options, autotoolsFlag($coverageSupport, "coverage");
+}
+
+if (isOSX()) {
+
+ push(@options, XcodeOptions());
+
+ # Copy library and header from WebKitLibraries to a findable place in the product directory.
+ my $srcLib = "WebKitLibraries/libWebKitSystemInterfaceTiger.a";
+ my $lib = "$productDir/libWebKitSystemInterfaceTiger.a";
+ if (!-e $lib || -M $lib > -M $srcLib) {
+ print "Updating $lib\n";
+ system "ditto", $srcLib, $lib;
+ system "ranlib", $lib;
+ }
+
+ $srcLib = "WebKitLibraries/libWebKitSystemInterfaceLeopard.a";
+ $lib = "$productDir/libWebKitSystemInterfaceLeopard.a";
+ if (!-e $lib || -M $lib > -M $srcLib) {
+ print "Updating $lib\n";
+ system "ditto", $srcLib, $lib;
+ system "ranlib", $lib;
+ }
+
+ my $srcHeader = "WebKitLibraries/WebKitSystemInterface.h";
+ my $header = "$productDir/usr/local/include/WebKitSystemInterface.h";
+ if (!-e $header || -M $header > -M $srcHeader) {
+ print "Updating $header\n";
+ system "mkdir", "-p", "$productDir/usr/local/include";
+ system "ditto", $srcHeader, $header;
+ }
+
+ $srcLib = "WebKitLibraries/libWebCoreSQLite3.a";
+ $lib = "$productDir/libWebCoreSQLite3.a";
+ if (!-e $lib || -M $lib > -M $srcLib) {
+ print "Updating $lib\n";
+ system "ditto", $srcLib, $lib;
+ system "ranlib", $lib;
+ }
+
+ my $srcHeaderDir = "WebKitLibraries/WebCoreSQLite3";
+ my $headerDir = "$productDir/WebCoreSQLite3";
+ if (!-e $headerDir || -M $headerDir > -M $srcHeaderDir) {
+ print "Updating $headerDir\n";
+ system "ditto", $srcHeaderDir, $headerDir;
+ }
+}
+
+if (isGtk() && isDarwin() && !$ENV{WEBKITAUTOTOOLS} && !$ENV{QMAKESPEC}) {
+ # The qmake from Trolltech's binary "QT for Mac" distribution tries to
+ # create xcode projects, not Makefiles
+ $ENV{QMAKESPEC} = "macx-g++";
+}
+
+if (isCygwin()) {
+ # Copy WebKitSupportLibrary to the correct location in WebKitLibraries so it can be found.
+ # Will fail if WebKitSupportLibrary.zip is not in source root.
+ (system("perl WebKitTools/Scripts/update-webkit-support-libs") == 0) or die;
+}
+
+# Force re-link of existing libraries if different than expected
+removeLibraryDependingOnSVG("WebCore", $svgSupport);
+
+# Build, and abort if the build fails.
+for my $dir (@projects) {
+ chdir $dir or die;
+ my $result = 0;
+
+ if (isGtk()) {
+ if ($dir ne "WebKit") {
+ chdir ".." or die;
+ next;
+ }
+
+ $result = buildGtkProject($dir, $clean, @options);
+ } elsif (isQt()) {
+ if ($dir ne "WebKit") {
+ chdir ".." or die;
+ next;
+ }
+ $result = buildQMakeQtProject($dir, $clean);
+ } elsif (isOSX()) {
+ $result = system "xcodebuild", "-project", "$dir.xcodeproj", @options, $overrideFeatureDefinesString, @coverageSupportOption, @ARGV;
+ } elsif (isCygwin()) {
+ if ($dir eq "WebKit") {
+ $result = buildVisualStudioProject("win/WebKit.vcproj/WebKit.sln", $clean);
+ }
+ }
+
+ if (exitStatus($result)) {
+ if (isCygwin()) {
+ print "\n\n===== BUILD FAILED ======\n\n";
+ my $scriptDir = relativeScriptsDir();
+ print "Please ensure you have run $scriptDir/update-webkit to install depenedencies.\n\n";
+ my $baseProductDir = baseProductDir();
+ print "You can view build errors by checking the BuildLog.htm files located at:\n$baseProductDir/obj/<project>/<config>.\n";
+ }
+ exit exitStatus($result);
+ }
+ chdir ".." or die;
+}
+
+# Don't report the "WebKit is now built" message after a clean operation.
+exit if $clean;
+
+# Write out congratulations message.
+
+my $launcherPath = launcherPath();
+my $launcherName = launcherName();
+
+print "\n";
+print "===========================================================\n";
+print " WebKit is now built. To run $launcherName with this newly-built\n";
+print " code, use the \"$launcherPath\" script.\n";
+if ($svgSupport) {
+ print "\n NOTE: WebKit has been built with SVG support enabled.\n";
+ print " $launcherName will have SVG viewing capabilities.\n";
+}
+if ($svgAnimationSupport or $svgFiltersSupport or $svgForeignObjectSupport or $svgFontsSupport or $svgAsImageSupport or $svgUseSupport) {
+ print "\n NOTE: WebKit has been built with experimental SVG features enabled.\n";
+ print " Your build supports: \n";
+ print " * Basic SVG animation.\n" if $svgAnimationSupport;
+ print " * SVG filters.\n" if $svgFiltersSupport;
+ print " * SVG foreign object.\n" if $svgForeignObjectSupport;
+ print " * SVG fonts.\n" if $svgFontsSupport;
+ print " * SVG as image.\n" if $svgAsImageSupport;
+ print " * SVG <use> support.\n" if $svgUseSupport;
+}
+print "===========================================================\n";
diff --git a/WebKitTools/Scripts/check-dom-results b/WebKitTools/Scripts/check-dom-results
new file mode 100755
index 0000000..0b32406
--- /dev/null
+++ b/WebKitTools/Scripts/check-dom-results
@@ -0,0 +1,141 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005 Apple Computer, 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.
+
+# Script to check status of W3C DOM tests that are part of the WebKit tests.
+
+use strict;
+use FindBin;
+use Cwd;
+use lib $FindBin::Bin;
+use webkitdirs;
+
+chdirWebKit();
+
+my $verbose = $ARGV[0] && $ARGV[0] eq "-v";
+
+my $workingDir = getcwd();
+my $testDirectory = "$workingDir/LayoutTests";
+
+my @suites = ( {"name" => "DOM Level 1 Core (html)", "directory" => "dom/html/level1/core"},
+ {"name" => "DOM Level 2 Core (html)", "directory" => "dom/html/level2/core"},
+ {"name" => "DOM Level 2 Events (html)", "directory" => "dom/html/level2/events"},
+ {"name" => "DOM Level 2 HTML (html)", "directory" => "dom/html/level2/html"},
+ {"name" => "DOM Level 1 Core (xhtml)", "directory" => "dom/xhtml/level1/core"},
+ {"name" => "DOM Level 2 Core (xhtml)", "directory" => "dom/xhtml/level2/core"},
+ {"name" => "DOM Level 2 Events (xhtml)", "directory" => "dom/xhtml/level2/events"},
+ {"name" => "DOM Level 2 HTML (xhtml)", "directory" => "dom/xhtml/level2/html"},
+ {"name" => "DOM Level 3 Core (xhtml)", "directory" => "dom/xhtml/level3/core"},
+ {"name" => "DOM Level 3 XPath (svg)", "directory" => "dom/svg/level3/xpath"});
+
+my $totalCount = 0;
+my $totalSuccesses = 0;
+my $totalDisabled = 0;
+my $totalFailed = 0;
+
+foreach my $suite (@suites) {
+
+ my %suite = %$suite;
+ my $directory = $suite{"directory"};
+ my $name = $suite{"name"};
+ my @results = `find "${testDirectory}/${directory}" -name "*-expected.txt"`;
+ my @disabled = `find "${testDirectory}/${directory}" -name "*-disabled"`;
+
+ my @failures = ();
+ my $count = 0;
+
+ foreach my $result (@results) {
+ $count++;
+ my $success = 0;
+ open RESULT, "<$result";
+ while (<RESULT>) {
+ if (/Success/) {
+ $success = 1;
+ last;
+ }
+ }
+ close RESULT;
+ if (!$success) {
+ push @failures, $result;
+ }
+ }
+
+ my $disabledCount = (scalar @disabled);
+ my $failureCount = (scalar @failures);
+
+ $count += $disabledCount;
+
+ my $successCount = $count - $failureCount - $disabledCount;
+ my $percentage = (sprintf "%.1f", ($successCount * 100.0 / $count));
+
+ if ($percentage == 100) {
+ print "${name}: all ${count} tests succeeded";
+ } else {
+ print "${name}: ${successCount} out of ${count} tests succeeded (${percentage}%)";
+ }
+ print " ($disabledCount disabled)" if $disabledCount;
+ print "\n";
+ if ($verbose) {
+ print "\n";
+ if (@disabled) {
+ print " Disabled:\n";
+
+ foreach my $failure (sort @disabled) {
+ $failure =~ s|.*/||;
+ $failure =~ s|-disabled||;
+ print " ${directory}/${failure}";
+ }
+ }
+ if (@failures) {
+ print " Failed:\n";
+
+ foreach my $failure (sort @failures) {
+ $directory =~ m|^dom/(\w+)|;
+ my $extension = $1;
+ $failure =~ s|.*/||;
+ $failure =~ s|-expected\.txt|.${extension}|;
+ print " ${directory}/${failure}";
+ }
+ }
+
+ print "\n";
+ }
+
+ $totalCount += $count;
+ $totalSuccesses += $successCount;
+ $totalDisabled += $disabledCount;
+ $totalFailed += $failureCount;
+}
+
+
+my $totalPercentage = (sprintf "%.1f", ($totalSuccesses * 100.0 / $totalCount));
+my $totalDisabledPercentage = (sprintf "%.1f", ($totalDisabled * 100.0 / $totalCount));
+my $totalFailedPercentage = (sprintf "%.1f", ($totalFailed * 100.0 / $totalCount));
+
+print "Total: ${totalSuccesses} out of ${totalCount} tests succeeded (${totalPercentage}%)\n";
+print " ${totalDisabled} tests disabled (${totalDisabledPercentage}%)\n";
+print " ${totalFailed} tests failed (${totalFailedPercentage}%)\n";
diff --git a/WebKitTools/Scripts/check-for-global-initializers b/WebKitTools/Scripts/check-for-global-initializers
new file mode 100755
index 0000000..c73b8cc
--- /dev/null
+++ b/WebKitTools/Scripts/check-for-global-initializers
@@ -0,0 +1,131 @@
+#!/usr/bin/perl
+
+# 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.
+# 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.
+
+# "check-for-global-initializers" script for Web Kit Open Source Project
+
+# Intended to be invoked from an Xcode build step to check if there are
+# any global initializers in a target.
+
+use warnings;
+use strict;
+
+use File::Basename;
+
+sub touch($);
+
+my $arch = $ENV{'CURRENT_ARCH'};
+my $configuration = $ENV{'CONFIGURATION'};
+my $target = $ENV{'TARGET_NAME'};
+my $variant = $ENV{'CURRENT_VARIANT'};
+my $coverageBuild = $ENV{'WEBKIT_COVERAGE_BUILD'};
+my $debugRoot = $ENV{'WEBKIT_DEBUG_ROOT'};
+
+$arch = $ENV{'NATIVE_ARCH'} if !$arch; # for Xcode 2.1, which does not have CURRENT_ARCH
+$variant = "normal" if !$variant; # for Xcode 2.1, which does not have CURRENT_VARIANT
+
+my $executablePath = "$ENV{'TARGET_BUILD_DIR'}/$ENV{'EXECUTABLE_PATH'}";
+
+my $buildTimestampPath = $ENV{'TARGET_TEMP_DIR'} . "/" . basename($0) . ".timestamp";
+my $buildTimestampAge = -M $buildTimestampPath;
+
+touch($buildTimestampPath);
+
+my $list = $ENV{"LINK_FILE_LIST_${variant}_${arch}"};
+
+if (!open LIST, $list) {
+ print "Could not open $list\n";
+ exit 1;
+}
+
+my @files = <LIST>;
+chomp @files;
+close LIST;
+
+my $sawError = 0;
+
+for my $file (sort @files) {
+ if (defined $buildTimestampAge) {
+ my $fileAge = -M $file;
+ next if defined $fileAge && $fileAge > $buildTimestampAge;
+ }
+ if (!open NM, "(nm '$file' | sed 's/^/STDOUT:/') 2>&1 |") {
+ print "Could not open $file\n";
+ $sawError = 1;
+ next;
+ }
+ my $sawGlobal = 0;
+ while (<NM>) {
+ if (/^STDOUT:/) {
+ $sawGlobal = 1 if /__GLOBAL__I/;
+ } else {
+ print STDERR if $_ ne "nm: no name list\n";
+ }
+ }
+ close NM;
+ if ($sawGlobal) {
+ my $shortName = $file;
+ $shortName =~ s/.*\///;
+
+ # Special cases for files that have initializers in debug builds.
+ if ($configuration eq "Debug" or $debugRoot ) {
+ if ($target eq "JavaScriptCore") {
+ next if $shortName eq "nodes.o";
+ next if $shortName eq "AllInOneFile.o";
+ }
+ if ($target eq "WebCore") {
+ next if $shortName eq "CachedPage.o";
+ next if $shortName eq "Frame.o";
+ next if $shortName eq "JSCustomSQLTransactionCallback.o";
+ next if $shortName eq "Node.o";
+ next if $shortName eq "Page.o";
+ next if $shortName eq "Range.o";
+ next if $shortName eq "RenderObject.o";
+ next if $shortName eq "SubresourceLoader.o";
+ next if $shortName eq "bidi.o";
+ next if $shortName eq "kjs_events.o";
+ }
+ }
+
+ print "$shortName has a global initializer in it! ($file)\n";
+ $sawError = 1;
+ }
+}
+
+if ($sawError and !$coverageBuild) {
+ unlink $executablePath;
+ exit 1;
+}
+
+exit 0;
+
+sub touch($)
+{
+ my ($path) = @_;
+ open(TOUCH, ">", $path) or die "$!";
+ close(TOUCH);
+}
diff --git a/WebKitTools/Scripts/clean-header-guards b/WebKitTools/Scripts/clean-header-guards
new file mode 100755
index 0000000..2bad046
--- /dev/null
+++ b/WebKitTools/Scripts/clean-header-guards
@@ -0,0 +1,53 @@
+#!/usr/bin/ruby
+
+require 'find'
+require 'optparse'
+
+options = {}
+OptionParser.new do |opts|
+ opts.banner = "Usage: clean-header-guards [options]"
+
+ opts.on("--prefix [PREFIX]", "Append a header prefix to all guards") do |prefix|
+ options[:prefix] = prefix
+ end
+end.parse!
+
+IgnoredFilenamePatterns = [
+ # ignore headers which are known not to have guard
+ /WebCorePrefix/,
+ /ForwardingHeaders/,
+ %r|bindings/objc|,
+ /vcproj/, # anything inside a vcproj is in the windows wasteland
+
+ # we don't own any of these headers
+ %r|icu/unicode|,
+ %r|platform/graphics/cairo|,
+ %r|platform/image-decoders|,
+
+ /config.h/ # changing this one sounds scary
+].freeze
+
+IgnoreFileNamesPattern = Regexp.union(*IgnoredFilenamePatterns).freeze
+
+Find::find(".") do |filename|
+ next unless filename =~ /\.h$/
+ next if filename.match(IgnoreFileNamesPattern)
+
+ File.open(filename, "r+") do |file|
+ contents = file.read
+ match_results = contents.match(/#ifndef (\S+)\n#define \1/s)
+ if match_results
+ current_guard = match_results[1]
+ new_guard = File.basename(filename).sub('.', '_')
+ new_guard = options[:prefix] + '_' + new_guard if options[:prefix]
+ contents.gsub!(/#{current_guard}\b/, new_guard)
+ else
+ puts "Ignoring #{filename}, failed to find existing header guards."
+ end
+ tmp_filename = filename + ".tmp"
+ File.open(tmp_filename, "w+") do |new_file|
+ new_file.write(contents)
+ end
+ File.rename tmp_filename, filename
+ end
+end
diff --git a/WebKitTools/Scripts/commit-log-editor b/WebKitTools/Scripts/commit-log-editor
new file mode 100755
index 0000000..e7ee5155
--- /dev/null
+++ b/WebKitTools/Scripts/commit-log-editor
@@ -0,0 +1,189 @@
+#!/usr/bin/perl -w
+
+# 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.
+
+# Script to put change log comments in as default check-in comment.
+
+use strict;
+use File::Basename;
+use File::Spec;
+use FindBin;
+use lib $FindBin::Bin;
+use VCSUtils;
+use webkitdirs;
+
+my $log = $ARGV[0];
+
+my $baseDir = baseProductDir();
+
+my $editor = $ENV{SVN_LOG_EDITOR};
+if (!$editor) {
+ $editor = $ENV{CVS_LOG_EDITOR};
+}
+if (!$editor) {
+ my $builtEditorApplication = "$baseDir/Release/Commit Log Editor.app/Contents/MacOS/Commit Log Editor";
+ $editor = $builtEditorApplication if -x $builtEditorApplication;
+}
+if (!$editor) {
+ my $builtEditorApplication = "$baseDir/Debug/Commit Log Editor.app/Contents/MacOS/Commit Log Editor";
+ $editor = $builtEditorApplication if -x $builtEditorApplication;
+}
+if (!$editor) {
+ my $installedEditorApplication = "$ENV{HOME}/Applications/Commit Log Editor.app/Contents/MacOS/Commit Log Editor";
+ $editor = $installedEditorApplication if -x $installedEditorApplication;
+}
+if (!$editor) {
+ $editor = $ENV{EDITOR} || "/usr/bin/vi";
+}
+
+my $inChangesToBeCommitted = !isGit();
+my @changeLogs = ();
+my $logContents = "";
+my $existingLog = 0;
+open LOG, $log or die;
+while (<LOG>) {
+ if (isGit()) {
+ if (/^# Changes to be committed:$/) {
+ $inChangesToBeCommitted = 1;
+ } elsif ($inChangesToBeCommitted && /^# \S/) {
+ $inChangesToBeCommitted = 0;
+ }
+ }
+
+ $logContents .= $_;
+ $existingLog = isGit() && !(/^#/ || /^\s*$/) unless $existingLog;
+
+ push @changeLogs, makeFilePathRelative($1) if $inChangesToBeCommitted && (/^M....(.*ChangeLog)$/ || /^#\tmodified: (.*ChangeLog)/) && !/-ChangeLog/;
+}
+close LOG;
+
+# Don't change anything if there's already a log message
+# (as can happen with git-commit --amend)
+exec $editor, @ARGV if $existingLog;
+
+my $topLevel = topLevelSourceDirectory();
+
+my %changeLogSort;
+my %changeLogContents;
+for my $changeLog (@changeLogs) {
+ open CHANGELOG, $changeLog or die "Can't open $changeLog";
+ my $contents = "";
+ my $blankLines = "";
+ while (<CHANGELOG>) {
+ if (/^\S/) {
+ last if $contents;
+ next;
+ } elsif (/\S/) {
+ $contents .= $blankLines if $contents;
+ $blankLines = "";
+ $contents .= $_;
+ } else {
+ $blankLines .= $_;
+ }
+ }
+ close CHANGELOG;
+
+ $changeLog = File::Spec->abs2rel(File::Spec->rel2abs($changeLog), $topLevel);
+
+ my $label = dirname($changeLog);
+ $label = "top level" unless length $label;
+
+ my $sortKey = lc $label;
+ if ($label eq "top level") {
+ $sortKey = "";
+ } elsif ($label eq "Tools") {
+ $sortKey = "-, just after top level";
+ } elsif ($label eq "WebBrowser") {
+ $sortKey = lc "WebKit, WebBrowser after";
+ } elsif ($label eq "WebCore") {
+ $sortKey = lc "WebFoundation, WebCore after";
+ } elsif ($label eq "LayoutTests") {
+ $sortKey = lc "~, LayoutTests last";
+ }
+
+ $changeLogSort{$sortKey} = $label;
+ $changeLogContents{$label} = $contents;
+}
+
+my $first = 1;
+open NEWLOG, ">$log.edit" or die;
+for my $sortKey (sort keys %changeLogSort) {
+ my $label = $changeLogSort{$sortKey};
+ if (keys %changeLogSort > 1) {
+ print NEWLOG "\n" if !$first;
+ $first = 0;
+ print NEWLOG "$label:\n\n";
+ }
+ print NEWLOG $changeLogContents{$label};
+}
+print NEWLOG $logContents;
+close NEWLOG;
+
+system $editor, "$log.edit";
+
+open NEWLOG, "$log.edit" or exit;
+my $foundComment = 0;
+while (<NEWLOG>) {
+ $foundComment = 1 if (/\S/ && !/^CVS:/);
+}
+close NEWLOG;
+
+if ($foundComment) {
+ open NEWLOG, "$log.edit" or die;
+ open LOG, ">$log" or die;
+ while (<NEWLOG>) {
+ print LOG;
+ }
+ close LOG;
+ close NEWLOG;
+}
+
+unlink "$log.edit";
+
+sub topLevelSourceDirectory
+{
+ if (isGit()) {
+ chomp(my $gitDir = `git rev-parse --git-dir`);
+ return dirname($gitDir);
+ } elsif (isSVN()) {
+ open(INFO, "-|", qw(svn info)) or die;
+ my ($root, $url);
+ while (my $line = <INFO>) {
+ if ($line =~ /^Repository Root: (.*)$/) {
+ $root = $1;
+ } elsif ($line =~ /^URL: (.*)$/) {
+ $url = $1;
+ }
+ }
+ close(INFO);
+
+ my $path = $url;
+ $path =~ s/^\Q$root\E//;
+ $path =~ s/^\/?(branches\/[^\/]*|trunk)\/?//;
+ return File::Spec->rel2abs(File::Spec->catdir(map { ".." } File::Spec->splitdir($path)));
+ }
+}
diff --git a/WebKitTools/Scripts/compare-timing-files b/WebKitTools/Scripts/compare-timing-files
new file mode 100755
index 0000000..11b470b
--- /dev/null
+++ b/WebKitTools/Scripts/compare-timing-files
@@ -0,0 +1,88 @@
+#!/usr/bin/perl
+
+# Copyright (C) 2006 Apple Computer, 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.
+
+# This script takes two files that are lists of timings and compares them.
+
+use warnings;
+use strict;
+use Getopt::Long;
+
+my $usage = "compare-timing-files [-c|--count results] oldFile newFile";
+
+my $count = 1;
+GetOptions("c|count=i" => \$count);
+
+my ($file1, $file2) = @ARGV;
+die "$usage\n" unless ($file1 && $file2 && @ARGV == 2);
+
+my ($oldAverage, $oldRange, $oldRangePercent) = parseResults($file1);
+my ($newAverage, $newRange, $newRangePercent) = parseResults($file2);
+
+print "\n===== $file1 =====\n";
+if ($count == 1) {
+ print("fastest run: $oldAverage\n");
+} else {
+ print("average of fastest $count runs: $oldAverage\n");
+ printf("range of fastest $count runs: %.2f%% (%d)\n", $oldRangePercent, $oldRange);
+}
+
+print "\n===== $file2 =====\n";
+if ($count == 1) {
+ print("fastest run: $newAverage\n");
+} else {
+ print("average of fastest $count runs: $newAverage\n");
+ printf("range of fastest $count runs: %.2f%% (%d)\n", $newRangePercent, $newRange);
+}
+
+my $gainOrLoss = $newAverage <= $oldAverage ? "GAIN" : "LOSS";
+my $difference = abs($newAverage - $oldAverage);
+my $differencePercent = $difference / $oldAverage * 100;
+printf("\nperformance %s of %.2f%% (%.1f / %.1f)\n", $gainOrLoss, $differencePercent, $difference, $oldAverage);
+print "\n";
+
+sub parseResults
+{
+ my ($file) = @_;
+
+ open(FILE, $file) or die "Couldn't open file: $file";
+ my @results = <FILE>;
+ close(FILE);
+
+ @results = sort(@results);
+ my $total = 0;
+ for (my $i = 0; $i < $count; $i++) {
+ $results[$i] =~ s/\D*//; # cut out non-digits
+ $total += $results[$i];
+ }
+ my $average = $total / $count;
+ my $range = $results[$count - 1] - $results[0];
+ my $rangePercent = $range / $results[$count - 1] * 100;
+
+ return ($average, $range, $rangePercent);
+}
+
diff --git a/WebKitTools/Scripts/debug-safari b/WebKitTools/Scripts/debug-safari
new file mode 100755
index 0000000..52e97fe
--- /dev/null
+++ b/WebKitTools/Scripts/debug-safari
@@ -0,0 +1,38 @@
+#!/usr/bin/perl -w
+
+# 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.
+
+# Script to run Safari in the platform's debugger for the WebKit Open Source Project.
+
+use strict;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+
+setConfiguration();
+
+exit exitStatus(runSafari(1));
diff --git a/WebKitTools/Scripts/do-file-rename b/WebKitTools/Scripts/do-file-rename
new file mode 100755
index 0000000..23a460c
--- /dev/null
+++ b/WebKitTools/Scripts/do-file-rename
@@ -0,0 +1,110 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2006 Apple Computer, 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.
+
+# Script to do file renaming.
+
+use strict;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+use File::Find;
+
+setConfiguration();
+chdirWebKit();
+
+my %words;
+
+# find all files we want to process
+
+my @paths;
+find(\&wanted, "WebCore");
+
+sub wanted
+{
+ my $file = $_;
+
+ if ($file eq "icu") {
+ $File::Find::prune = 1;
+ return;
+ }
+
+ if ($file =~ /^\../) {
+ $File::Find::prune = 1;
+ return;
+ }
+
+ return if $file =~ /^ChangeLog/;
+ return if -d $file;
+
+ push @paths, $File::Find::name;
+}
+
+my %renames = (
+ "xxx.mm" => "yyy.mm",
+);
+
+# rename files
+
+my %newFile;
+for my $file (sort @paths) {
+ my $f = $file;
+ $f = "$1$renames{$2}" if $f =~ /^(.*\/)(\w+\.\w+)$/ && $renames{$2};
+ $newFile{$file} = $f if $f ne $file;
+}
+
+for my $file (sort @paths) {
+ if ($newFile{$file}) {
+ my $newFile = $newFile{$file};
+ print "Renaming $file to $newFile\n";
+ system "svn move $file $newFile";
+ }
+}
+
+# change all file contents
+
+for my $file (sort @paths) {
+ $file = $newFile{$file} if $newFile{$file};
+ my $contents;
+ {
+ local $/;
+ open FILE, $file or die;
+ $contents = <FILE>;
+ close FILE;
+ }
+ my $newContents = $contents;
+
+ for my $from (keys %renames) {
+ $newContents =~ s/\b\Q$from\E(?!["\w])/$renames{$from}/g; # this " unconfuses Xcode syntax highlighting
+ }
+
+ if ($newContents ne $contents) {
+ open FILE, ">", $file or die;
+ print FILE $newContents;
+ close FILE;
+ }
+}
diff --git a/WebKitTools/Scripts/do-webcore-rename b/WebKitTools/Scripts/do-webcore-rename
new file mode 100755
index 0000000..36f894a
--- /dev/null
+++ b/WebKitTools/Scripts/do-webcore-rename
@@ -0,0 +1,345 @@
+#!/usr/bin/perl -w
+
+# 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.
+# 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.
+
+# Script to do a rename in JavaScriptCore, WebCore, and WebKit.
+
+use strict;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+use File::Find;
+
+setConfiguration();
+chdirWebKit();
+
+my %words;
+
+# find all files we want to process
+
+my @paths;
+find(\&wanted, "JavaScriptCore");
+find(\&wanted, "JavaScriptGlue");
+find(\&wanted, "WebCore");
+find(\&wanted, "WebKit");
+
+sub wanted
+{
+ my $file = $_;
+
+ if ($file eq "icu") {
+ $File::Find::prune = 1;
+ return;
+ }
+
+ if ($file =~ /^\../) {
+ $File::Find::prune = 1;
+ return;
+ }
+
+ return if $file =~ /^ChangeLog/;
+ return if -d $file;
+
+ push @paths, $File::Find::name;
+}
+
+my %renames = (
+ "XSLTProcessorPrototypeTable" => "JSXSLTProcessorPrototypeTable",
+ "ActivationImp" => "Activation",
+ "ActivationImpData" => "ActivationData",
+ "ArrayInstance" => "JSArray",
+ "ArrayObjectImp" => "ArrayConstructor",
+ "ArrayProtoFuncConcat" => "ArrayFunctionConcat",
+ "ArrayProtoFuncEvery" => "ArrayFunctionEvery",
+ "ArrayProtoFuncFilter" => "ArrayFunctionFilter",
+ "ArrayProtoFuncForEach" => "ArrayFunctionForEach",
+ "ArrayProtoFuncIndexOf" => "ArrayFunctionIndexOf",
+ "ArrayProtoFuncJoin" => "ArrayFunctionJoin",
+ "ArrayProtoFuncLastIndexOf" => "ArrayFunctionLastIndexOf",
+ "ArrayProtoFuncMap" => "ArrayFunctionMap",
+ "ArrayProtoFuncPop" => "ArrayFunctionPop",
+ "ArrayProtoFuncPush" => "ArrayFunctionPush",
+ "ArrayProtoFuncReverse" => "ArrayFunctionReverse",
+ "ArrayProtoFuncShift" => "ArrayFunctionShift",
+ "ArrayProtoFuncSlice" => "ArrayFunctionSlice",
+ "ArrayProtoFuncSome" => "ArrayFunctionSome",
+ "ArrayProtoFuncSort" => "ArrayFunctionSort",
+ "ArrayProtoFuncSplice" => "ArrayFunctionSplice",
+ "ArrayProtoFuncToLocaleString" => "ArrayFunctionToLocaleString",
+ "ArrayProtoFuncToString" => "ArrayFunctionToString",
+ "ArrayProtoFuncUnShift" => "ArrayFunctionUnshift",
+ "BooleanInstance" => "BooleanObject",
+ "BooleanObjectImp" => "BooleanConstructor",
+ "BooleanProtoFunc" => "BooleanFunction",
+ "DateObjectFuncImp" => "DateFunction",
+ "DateObjectImp" => "DateConstructor",
+ "DateProtoFuncGetDate" => "DateFunctionGetDate",
+ "DateProtoFuncGetDay" => "DateFunctionGetDay",
+ "DateProtoFuncGetFullYear" => "DateFunctionGetFullYear",
+ "DateProtoFuncGetHours" => "DateFunctionGetHours",
+ "DateProtoFuncGetMilliSeconds" => "DateFunctionGetMilliSeconds",
+ "DateProtoFuncGetMinutes" => "DateFunctionGetMinutes",
+ "DateProtoFuncGetMonth" => "DateFunctionGetMonth",
+ "DateProtoFuncGetSeconds" => "DateFunctionGetSeconds",
+ "DateProtoFuncGetTime" => "DateFunctionGetTime",
+ "DateProtoFuncGetTimezoneOffset" => "DateFunctionGetTimezoneOffset",
+ "DateProtoFuncGetUTCDate" => "DateFunctionGetUTCDate",
+ "DateProtoFuncGetUTCDay" => "DateFunctionGetUTCDay",
+ "DateProtoFuncGetUTCFullYear" => "DateFunctionGetUTCFullYear",
+ "DateProtoFuncGetUTCHours" => "DateFunctionGetUTCHours",
+ "DateProtoFuncGetUTCMilliseconds" => "DateFunctionGetUTCMilliseconds",
+ "DateProtoFuncGetUTCMinutes" => "DateFunctionGetUTCMinutes",
+ "DateProtoFuncGetUTCMonth" => "DateFunctionGetUTCMonth",
+ "DateProtoFuncGetUTCSeconds" => "DateFunctionGetUTCSeconds",
+ "DateProtoFuncGetYear" => "DateFunctionGetYear",
+ "DateProtoFuncSetDate" => "DateFunctionSetDate",
+ "DateProtoFuncSetFullYear" => "DateFunctionSetFullYear",
+ "DateProtoFuncSetHours" => "DateFunctionSetHours",
+ "DateProtoFuncSetMilliSeconds" => "DateFunctionSetMilliSeconds",
+ "DateProtoFuncSetMinutes" => "DateFunctionSetMinutes",
+ "DateProtoFuncSetMonth" => "DateFunctionSetMonth",
+ "DateProtoFuncSetSeconds" => "DateFunctionSetSeconds",
+ "DateProtoFuncSetTime" => "DateFunctionSetTime",
+ "DateProtoFuncSetUTCDate" => "DateFunctionSetUTCDate",
+ "DateProtoFuncSetUTCFullYear" => "DateFunctionSetUTCFullYear",
+ "DateProtoFuncSetUTCHours" => "DateFunctionSetUTCHours",
+ "DateProtoFuncSetUTCMilliseconds" => "DateFunctionSetUTCMilliseconds",
+ "DateProtoFuncSetUTCMinutes" => "DateFunctionSetUTCMinutes",
+ "DateProtoFuncSetUTCMonth" => "DateFunctionSetUTCMonth",
+ "DateProtoFuncSetUTCSeconds" => "DateFunctionSetUTCSeconds",
+ "DateProtoFuncSetYear" => "DateFunctionSetYear",
+ "DateProtoFuncToDateString" => "DateFunctionToDateString",
+ "DateProtoFuncToGMTString" => "DateFunctionToGMTString",
+ "DateProtoFuncToLocaleDateString" => "DateFunctionToLocaleDateString",
+ "DateProtoFuncToLocaleString" => "DateFunctionToLocaleString",
+ "DateProtoFuncToLocaleTimeString" => "DateFunctionToLocaleTimeString",
+ "DateProtoFuncToString" => "DateFunctionToString",
+ "DateProtoFuncToTimeString" => "DateFunctionToTimeString",
+ "DateProtoFuncToUTCString" => "DateFunctionToUTCString",
+ "DateProtoFuncValueOf" => "DateFunctionValueOf",
+ "DebuggerImp" => "DebuggerData",
+ "ErrorObjectImp" => "ErrorConstructor",
+ "ErrorProtoFuncToString" => "ErrorFunction",
+ "FRAMES_ON_STACK" => "numFramesOnStack",
+ "FTPDirectoryTokenizer" => "FTPDirectoryDocumentBuilder",
+ "FunctionImp" => "JSFunction",
+ "FunctionObjectImp" => "FunctionConstructor",
+ "FunctionProtoFunc" => "FunctionFunction",
+ "GetterSetterImp" => "JSGetterSetter",
+ "GlobalFuncImp" => "GlobalFunction",
+ "GlobalImp" => "TestGlobalObject",
+ "HTMLGenericFormElement" => "HTMLFormControlElement",
+ "HTMLGenericFormElement_h" => "HTMLFormControlElement_h",
+ "HTMLTokenizer" => "HTMLDocumentBuilder",
+ "ImageConstructorImp" => "JSImageConstructor",
+ "ImageTokenizer" => "ImageDocumentBuilder",
+ "InternalFunctionImp" => "InternalFunction",
+ "JSXMLHttpRequestConstructorImp" => "JSXMLHttpRequestConstructor",
+ "KURL" => "URL",
+ "KURLCFNet" => "URLCF",
+ "KURLMac" => "URLMac",
+ "KURL_H_" => "URL_h",
+ "List" => "JSArgumentList",
+ "MathObjectImp" => "MathObject",
+ "MathProtoFuncACos" => "MathFunctionACos",
+ "MathProtoFuncASin" => "MathFunctionASin",
+ "MathProtoFuncATan" => "MathFunctionATan",
+ "MathProtoFuncATan2" => "MathFunctionATan2",
+ "MathProtoFuncAbs" => "MathFunctionAbs",
+ "MathProtoFuncCeil" => "MathFunctionCeil",
+ "MathProtoFuncCos" => "MathFunctionCos",
+ "MathProtoFuncExp" => "MathFunctionExp",
+ "MathProtoFuncFloor" => "MathFunctionFloor",
+ "MathProtoFuncLog" => "MathFunctionLog",
+ "MathProtoFuncMax" => "MathFunctionMax",
+ "MathProtoFuncMin" => "MathFunctionMin",
+ "MathProtoFuncPow" => "MathFunctionPow",
+ "MathProtoFuncRandom" => "MathFunctionRandom",
+ "MathProtoFuncRound" => "MathFunctionRound",
+ "MathProtoFuncSin" => "MathFunctionSin",
+ "MathProtoFuncSqrt" => "MathFunctionSqrt",
+ "MathProtoFuncTan" => "MathFunctionTan",
+ "NativeErrorImp" => "NativeErrorConstructor",
+ "Navigator" => "JSNavigator",
+ "NumberImp" => "JSNumberCell",
+ "NumberInstance" => "NumberObject",
+ "NumberObjectImp" => "NumberConstructor",
+ "NumberProtoFunc" => "NumberFunction",
+ "ObjcFallbackObjectImp" => "ObjCFallbackObject",
+ "ObjectObjectImp" => "ObjectConstructor",
+ "ObjectProtoFunc" => "ObjectFunction",
+ "PluginTokenizer" => "PluginDocumetBuilder",
+ "RECURSIVE_MATCH_STARTNG_NEW_GROUP" => "RECURSIVE_MATCH_NEW_GROUP",
+ "RegExpImp" => "RegExpObject",
+ "RegExpObjectImp" => "RegExpConstructor",
+ "RegExpObjectImpPrivate" => "RegExpConstructorPrivate",
+ "RegExpProtoFunc" => "RegExpFunction",
+ "RuntimeObjectImp" => "ForeignObject",
+ "StringImp" => "JSString",
+ "StringImpl" => "SharedString",
+ "StringInstance" => "StringObject",
+ "StringInstanceThatMasqueradesAsUndefined" => "StringObjectThatMasqueradesAsUndefined",
+ "StringObjectFuncImp" => "StringConstructorFunction",
+ "StringObjectImp" => "StringConstructor",
+ "StringProtoFuncAnchor" => "StringFunctionAnchor",
+ "StringProtoFuncBig" => "StringFunctionBig",
+ "StringProtoFuncBlink" => "StringFunctionBlink",
+ "StringProtoFuncBold" => "StringFunctionBold",
+ "StringProtoFuncCharAt" => "StringFunctionCharAt",
+ "StringProtoFuncCharCodeAt" => "StringFunctionCharCodeAt",
+ "StringProtoFuncConcat" => "StringFunctionConcat",
+ "StringProtoFuncFixed" => "StringFunctionFixed",
+ "StringProtoFuncFontcolor" => "StringFunctionFontcolor",
+ "StringProtoFuncFontsize" => "StringFunctionFontsize",
+ "StringProtoFuncIndexOf" => "StringFunctionIndexOf",
+ "StringProtoFuncItalics" => "StringFunctionItalics",
+ "StringProtoFuncLastIndexOf" => "StringFunctionLastIndexOf",
+ "StringProtoFuncLink" => "StringFunctionLink",
+ "StringProtoFuncLocaleCompare" => "StringFunctionLocaleCompare",
+ "StringProtoFuncMatch" => "StringFunctionMatch",
+ "StringProtoFuncReplace" => "StringFunctionReplace",
+ "StringProtoFuncSearch" => "StringFunctionSearch",
+ "StringProtoFuncSlice" => "StringFunctionSlice",
+ "StringProtoFuncSmall" => "StringFunctionSmall",
+ "StringProtoFuncSplit" => "StringFunctionSplit",
+ "StringProtoFuncStrike" => "StringFunctionStrike",
+ "StringProtoFuncSub" => "StringFunctionSub",
+ "StringProtoFuncSubstr" => "StringFunctionSubstr",
+ "StringProtoFuncSubstring" => "StringFunctionSubstring",
+ "StringProtoFuncSup" => "StringFunctionSup",
+ "StringProtoFuncToLocaleLowerCase" => "StringFunctionToLocaleLowerCase",
+ "StringProtoFuncToLocaleUpperCase" => "StringFunctionToLocaleUpperCase",
+ "StringProtoFuncToLowerCase" => "StringFunctionToLowerCase",
+ "StringProtoFuncToString" => "StringFunctionToString",
+ "StringProtoFuncToUpperCase" => "StringFunctionToUpperCase",
+ "StringProtoFuncValueOf" => "StringFunctionValueOf",
+ "TestFunctionImp" => "TestFunction",
+ "TextTokenizer" => "TextDocumentBuilder",
+ "ThreadSafeShared" => "ThreadSafeRefCounted",
+ "Tokenizer" => "DocumentBuilder",
+ "Tokenizer_h" => "DocumentBuilder_h",
+ "XMLTokenizer" => "XMLDocumentBuilder",
+ "XSLTProcessorConstructorImp" => "JSXSLTProcessorConstructor",
+ "XSLTProcessorPrototype" => "JSXSLTProcessorPrototype",
+ "animationController" => "animation",
+ "branchfirstbyte" => "branchFirstByte",
+ "branchreqbyte" => "branchReqByte",
+ "class_charcount" => "classCharCount",
+ "class_lastchar" => "classLastChar",
+ "codeptr" => "codePtr",
+ "createTokenizer" => "createBuilder",
+ "domString" => "string",
+ "equalIgnoringCase" => "equalFoldingCase",
+ "errorcodeptr" => "errorCodePtr",
+ "errorptr" => "errorPtr",
+ "first_byte" => "firstByte",
+ "first_byte_caseless" => "firstByteIsCaseless",
+ "first_char" => "firstChar",
+ "firstbyte" => "firstByte",
+ "groupsetfirstbyte" => "didGroupSetFirstByte",
+ "isHTMLTokenizer" => "isHTMLDocumentBuilder",
+ "is_quantifier" => "isQuantifier",
+ "isclass" => "isClass",
+ "kjs_binding" => "JSDOMBinding",
+ "kjs_binding_h" => "JSDOMBinding_h",
+ "kjs_css" => "JSRGBColor",
+ "kjs_css_h" => "JSRGBColor_h",
+ "kjs_proxy" => "ScriptController",
+ "kjs_proxy_h" => "ScriptController_h",
+ "last_branch" => "lastBranch",
+ "m_tokenizer" => "m_builder",
+ "mclength" => "mcLength",
+ "negate_class" => "negateClass",
+ "offsetcount" => "offsetCount",
+ "op_type" => "opType",
+ "prev_length" => "prevLength",
+ "ptrptr" => "ptrPtr",
+ "repeat_min" => "repeatMin",
+ "repeat_type" => "repeatType",
+ "req_byte" => "reqByte",
+ "req_byte2" => "reqByte2",
+ "req_byte_caseless" => "reqByteIsCaseless",
+ "req_caseopt" => "reqCaseOpt",
+ "req_varyopt" => "reqVaryOpt",
+ "reqbyte" => "reqByte",
+ "resetcount" => "resetCount",
+ "scriptProxy" => "script",
+ "selectionController" => "selection",
+ "should_flip_negation" => "shouldFlipNegation",
+ "skipbytes" => "skipBytes",
+ "subfirstbyte" => "subFirstByte",
+ "subreqbyte" => "subReqByte",
+ "tokenizerProcessedData" => "documentBuilderProcessedData",
+ "top_backref" => "topBackref",
+ "top_bracket" => "topBracket",
+ "using_temporary_offsets" => "usingTemporaryOffsets",
+ "zerofirstbyte" => "zeroFirstByte",
+ "zeroreqbyte" => "zeroReqByte",
+);
+
+# rename files
+
+my %newFile;
+for my $file (sort @paths) {
+ my $f = $file;
+ $f = "$1$renames{$2}$3" if $f =~ /^(.*\/)(\w+)(\.\w+)$/ && $renames{$2};
+ if ($f ne $file) {
+ $newFile{$file} = $f;
+ }
+}
+
+for my $file (sort @paths) {
+ if ($newFile{$file}) {
+ my $newFile = $newFile{$file};
+ print "Renaming $file to $newFile\n";
+ system "svn move $file $newFile";
+ }
+}
+
+# change all file contents
+
+for my $file (sort @paths) {
+ $file = $newFile{$file} if $newFile{$file};
+ my $contents;
+ {
+ local $/;
+ open FILE, $file or die;
+ $contents = <FILE>;
+ close FILE;
+ }
+ my $newContents = $contents;
+
+ for my $from (keys %renames) {
+ $newContents =~ s/\b$from(?!["\w])/$renames{$from}/g; # this " unconfuses Xcode syntax highlighting
+ }
+
+ if ($newContents ne $contents) {
+ open FILE, ">", $file or die;
+ print FILE $newContents;
+ close FILE;
+ }
+}
diff --git a/WebKitTools/Scripts/extract-localizable-strings b/WebKitTools/Scripts/extract-localizable-strings
new file mode 100755
index 0000000..15d6782
--- /dev/null
+++ b/WebKitTools/Scripts/extract-localizable-strings
@@ -0,0 +1,359 @@
+#!/usr/bin/perl -w
+
+# 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.
+
+# This script is like the genstrings tool (minus most of the options) with these differences.
+#
+# 1) It uses the names UI_STRING and UI_STRING_WITH_KEY for the macros, rather than the macros
+# from NSBundle.h, and doesn't support tables (although they would be easy to add).
+# 2) It supports UTF-8 in key strings (and hence uses "" strings rather than @"" strings;
+# @"" strings only reliably support ASCII since they are decoded based on the system encoding
+# at runtime, so give different results on US and Japanese systems for example).
+# 3) It looks for strings that are not marked for localization, using both macro names that are
+# known to be used for debugging in Intrigue source code and an exceptions file.
+# 4) It finds the files to work on rather than taking them as parameters, and also uses a
+# hardcoded location for both the output file and the exceptions file.
+# It would have been nice to use the project to find the source files, but it's too hard to
+# locate source files after parsing a .pbxproj file.
+
+# The exceptions file has a list of strings in quotes, filenames, and filename/string pairs separated by :.
+
+use strict;
+
+my $stringsFile = "English.lproj/Localizable.strings";
+my %isDebugMacro = ( ASSERT_WITH_MESSAGE => 1, LOG_ERROR => 1, ERROR => 1, NSURL_ERROR => 1, FATAL => 1, LOG => 1, dprintf => 1, NSException => 1, NSLog => 1, printf => 1 );
+
+@ARGV >= 1 or die "Usage: extract-localizable-strings <exceptions file> [ directory... ]\nDid you mean to run extract-webkit-localizable-strings instead?\n";
+
+my $exceptionsFile = shift @ARGV;
+-f $exceptionsFile or die "Couldn't find exceptions file $exceptionsFile\n";
+
+my @directories = ();
+my @directoriesToSkip = ();
+if (@ARGV < 1) {
+ push(@directories, ".");
+} else {
+ for my $dir (@ARGV) {
+ if ($dir =~ /^-(.*)$/) {
+ push @directoriesToSkip, $1;
+ } else {
+ push @directories, $dir;
+ }
+ }
+}
+
+my $sawError = 0;
+
+my $localizedCount = 0;
+my $keyCollisionCount = 0;
+my $notLocalizedCount = 0;
+my $NSLocalizeCount = 0;
+
+my %exception;
+my %usedException;
+
+if (open EXCEPTIONS, $exceptionsFile) {
+ while (<EXCEPTIONS>) {
+ chomp;
+ if (/^"([^\\"]|\\.)*"$/ or /^[-_\/\w.]+.(h|m|mm|c|cpp)$/ or /^[-_\/\w.]+.(h|m|mm|c|cpp):"([^\\"]|\\.)*"$/) {
+ if ($exception{$_}) {
+ print "$exceptionsFile:$.:exception for $_ appears twice\n";
+ print "$exceptionsFile:$exception{$_}:first appearance\n";
+ } else {
+ $exception{$_} = $.;
+ }
+ } else {
+ print "$exceptionsFile:$.:syntax error\n";
+ }
+ }
+ close EXCEPTIONS;
+}
+
+my $quotedDirectoriesString = '"' . join('" "', @directories) . '"';
+for my $dir (@directoriesToSkip) {
+ $quotedDirectoriesString .= ' -path "' . $dir . '" -prune';
+}
+
+my @files = ( split "\n", `find $quotedDirectoriesString -name "*.h" -o -name "*.m" -o -name "*.mm" -o -name "*.c" -o -name "*.cpp"` );
+
+for my $file (sort @files) {
+ next if $file =~ /\/WebLocalizableStrings\.h$/;
+ next if $file =~ /\/icu\//;
+
+ $file =~ s-^./--;
+
+ open SOURCE, $file or die "can't open $file\n";
+
+ my $inComment = 0;
+
+ my $expected = "";
+ my $macroLine;
+ my $macro;
+ my $UIString;
+ my $key;
+ my $comment;
+
+ my $string;
+ my $stringLine;
+ my $nestingLevel;
+
+ my $previousToken = "";
+
+ while (<SOURCE>) {
+ chomp;
+
+ # Handle continued multi-line comment.
+ if ($inComment) {
+ next unless s-.*\*/--;
+ $inComment = 0;
+ }
+
+ # Handle all the tokens in the line.
+ while (s-^\s*([#\w]+|/\*|//|[^#\w/'"()\[\],]+|.)--) {
+ my $token = $1;
+
+ if ($token eq "\"") {
+ if ($expected and $expected ne "a quoted string") {
+ print "$file:$.:ERROR:found a quoted string but expected $expected\n";
+ $sawError = 1;
+ $expected = "";
+ }
+ if (s-^(([^\\$token]|\\.)*?)$token--) {
+ if (!defined $string) {
+ $stringLine = $.;
+ $string = $1;
+ } else {
+ $string .= $1;
+ }
+ } else {
+ print "$file:$.:ERROR:mismatched quotes\n";
+ $sawError = 1;
+ $_ = "";
+ }
+ next;
+ }
+
+ if (defined $string) {
+handleString:
+ if ($expected) {
+ if (!defined $UIString) {
+ # FIXME: Validate UTF-8 here?
+ $UIString = $string;
+ $expected = ",";
+ } elsif (($macro eq "UI_STRING_KEY" or $macro eq "LPCTSTR_UI_STRING_KEY") and !defined $key) {
+ # FIXME: Validate UTF-8 here?
+ $key = $string;
+ $expected = ",";
+ } elsif (!defined $comment) {
+ # FIXME: Validate UTF-8 here?
+ $comment = $string;
+ $expected = ")";
+ }
+ } else {
+ if (defined $nestingLevel) {
+ # In a debug macro, no need to localize.
+ } elsif ($previousToken eq "#include" or $previousToken eq "#import") {
+ # File name, no need to localize.
+ } elsif ($previousToken eq "extern" and $string eq "C") {
+ # extern "C", no need to localize.
+ } elsif ($string eq "") {
+ # Empty string can sometimes be localized, but we need not complain if not.
+ } elsif ($exception{$file}) {
+ $usedException{$file} = 1;
+ } elsif ($exception{"\"$string\""}) {
+ $usedException{"\"$string\""} = 1;
+ } elsif ($exception{"$file:\"$string\""}) {
+ $usedException{"$file:\"$string\""} = 1;
+ } else {
+ print "$file:$stringLine:\"$string\" is not marked for localization\n";
+ $notLocalizedCount++;
+ }
+ }
+ $string = undef;
+ last if !defined $token;
+ }
+
+ $previousToken = $token;
+
+ if ($token =~ /^NSLocalized/ && $token !~ /NSLocalizedDescriptionKey/ && $token !~ /NSLocalizedStringFromTableInBundle/) {
+ print "$file:$.:ERROR:found a use of an NSLocalized macro; not supported\n";
+ $nestingLevel = 0 if !defined $nestingLevel;
+ $sawError = 1;
+ $NSLocalizeCount++;
+ } elsif ($token eq "/*") {
+ if (!s-^.*?\*/--) {
+ $_ = ""; # If the comment doesn't end, discard the result of the line and set flag
+ $inComment = 1;
+ }
+ } elsif ($token eq "//") {
+ $_ = ""; # Discard the rest of the line
+ } elsif ($token eq "'") {
+ if (!s-([^\\]|\\.)'--) { #' <-- that single quote makes the Project Builder editor less confused
+ print "$file:$.:ERROR:mismatched single quote\n";
+ $sawError = 1;
+ $_ = "";
+ }
+ } else {
+ if ($expected and $expected ne $token) {
+ print "$file:$.:ERROR:found $token but expected $expected\n";
+ $sawError = 1;
+ $expected = "";
+ }
+ if ($token eq "UI_STRING" or $token eq "UI_STRING_KEY" or $token eq "LPCTSTR_UI_STRING" or $token eq "LPCTSTR_UI_STRING_KEY") {
+ $expected = "(";
+ $macro = $token;
+ $UIString = undef;
+ $key = undef;
+ $comment = undef;
+ $macroLine = $.;
+ } elsif ($token eq "(" or $token eq "[") {
+ ++$nestingLevel if defined $nestingLevel;
+ $expected = "a quoted string" if $expected;
+ } elsif ($token eq ",") {
+ $expected = "a quoted string" if $expected;
+ } elsif ($token eq ")" or $token eq "]") {
+ $nestingLevel = undef if defined $nestingLevel && !--$nestingLevel;
+ if ($expected) {
+ $key = $UIString if !defined $key;
+ HandleUIString($UIString, $key, $comment, $file, $macroLine);
+ $macro = "";
+ $expected = "";
+ $localizedCount++;
+ }
+ } elsif ($isDebugMacro{$token}) {
+ $nestingLevel = 0 if !defined $nestingLevel;
+ }
+ }
+ }
+
+ }
+
+ goto handleString if defined $string;
+
+ if ($expected) {
+ print "$file:ERROR:reached end of file but expected $expected\n";
+ $sawError = 1;
+ }
+
+ close SOURCE;
+}
+
+my %stringByKey;
+my %commentByKey;
+my %fileByKey;
+my %lineByKey;
+
+sub HandleUIString
+{
+ my ($string, $key, $comment, $file, $line) = @_;
+
+ my $bad = 0;
+ if (grep { $_ == 0xFFFD } unpack "U*", $string) {
+ print "$file:$line:ERROR:string for translation has illegal UTF-8 -- most likely a problem with the Text Encoding of the source file\n";
+ $bad = 1;
+ }
+ if ($string ne $key && grep { $_ == 0xFFFD } unpack "U*", $key) {
+ print "$file:$line:ERROR:key has illegal UTF-8 -- most likely a problem with the Text Encoding of the source file\n";
+ $bad = 1;
+ }
+ if (grep { $_ == 0xFFFD } unpack "U*", $comment) {
+ print "$file:$line:ERROR:comment for translation has illegal UTF-8 -- most likely a problem with the Text Encoding of the source file\n";
+ $bad = 1;
+ }
+ if ($bad) {
+ $sawError = 1;
+ return;
+ }
+
+ if ($stringByKey{$key} && $stringByKey{$key} ne $string) {
+ print "$file:$line:encountered the same key, \"$key\", twice, with different strings\n";
+ print "$fileByKey{$key}:$lineByKey{$key}:previous occurrence\n";
+ $keyCollisionCount++;
+ return;
+ }
+ if ($commentByKey{$key} && $commentByKey{$key} ne $comment) {
+ print "$file:$line:encountered the same key, \"$key\", twice, with different comments\n";
+ print "$fileByKey{$key}:$lineByKey{$key}:previous occurrence\n";
+ $keyCollisionCount++;
+ return;
+ }
+
+ $fileByKey{$key} = $file;
+ $lineByKey{$key} = $line;
+ $stringByKey{$key} = $string;
+ $commentByKey{$key} = $comment;
+}
+
+print "\n" if $sawError || $notLocalizedCount || $NSLocalizeCount;
+
+my @unusedExceptions = sort grep { !$usedException{$_} } keys %exception;
+if (@unusedExceptions) {
+ for my $unused (@unusedExceptions) {
+ print "$exceptionsFile:$exception{$unused}:exception $unused not used\n";
+ }
+ print "\n";
+}
+
+print "$localizedCount localizable strings\n" if $localizedCount;
+print "$keyCollisionCount key collisions\n" if $keyCollisionCount;
+print "$notLocalizedCount strings not marked for localization\n" if $notLocalizedCount;
+print "$NSLocalizeCount uses of NSLocalize\n" if $NSLocalizeCount;
+print scalar(@unusedExceptions), " unused exceptions\n" if @unusedExceptions;
+
+if ($sawError) {
+ print "\nErrors encountered. Exiting without writing a $stringsFile file.\n";
+ exit 1;
+}
+
+my $localizedStrings = "";
+
+for my $key (sort keys %commentByKey) {
+ $localizedStrings .= "/* $commentByKey{$key} */\n\"$key\" = \"$stringByKey{$key}\";\n\n";
+}
+
+# Write out the strings file in UTF-16 with a BOM.
+utf8::decode($localizedStrings) if $^V ge chr(5).chr(8);
+my $output = pack "n*", (0xFEFF, unpack "U*", $localizedStrings);
+foreach my $directory (@directories) {
+ if (-e "$directory/mac/$stringsFile") {
+ open STRINGS, ">", "$directory/mac/$stringsFile" or die;
+ print STRINGS $output;
+ close STRINGS;
+ }
+
+ if (-e "$directory/win/$stringsFile") {
+ open STRINGS, ">", "$directory/win/$stringsFile" or die;
+ print STRINGS $output;
+ close STRINGS;
+ }
+
+ if (-e "$directory/$stringsFile") {
+ open STRINGS, ">", "$directory/$stringsFile" or die;
+ print STRINGS $output;
+ close STRINGS;
+ }
+}
diff --git a/WebKitTools/Scripts/find-extra-includes b/WebKitTools/Scripts/find-extra-includes
new file mode 100755
index 0000000..1286cd5
--- /dev/null
+++ b/WebKitTools/Scripts/find-extra-includes
@@ -0,0 +1,102 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005 Apple Computer, 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.
+
+# "find-extra-includes" script for Web Kit Open Source Project
+
+use strict;
+use File::Find;
+
+find(\&wanted, @ARGV ? @ARGV : ".");
+
+my %paths;
+my %includes;
+
+sub wanted
+{
+ my $file = $_;
+
+ if ($file eq "icu") {
+ $File::Find::prune = 1;
+ return;
+ }
+
+ if ($file !~ /^\./ && $file =~ /\.(h|cpp|c|mm|m)$/) {
+ $paths{$file} = $File::Find::name;
+ open FILE, $file or die;
+ while (<FILE>) {
+ if (m-^\s*#\s*(include|import)\s+["<]((\S+/)*)(\S+)[">]-) {
+ my $include = ($2 eq "sys/" ? $2 : "") . $4;
+ $includes{$file}{$include}++;
+ }
+ }
+ close FILE;
+ }
+}
+
+my %totalIncludes;
+
+sub fillOut
+{
+ my ($file) = @_;
+
+ return if defined $totalIncludes{$file};
+
+ for my $include (keys %{ $includes{$file} }) {
+ $totalIncludes{$file}{$include} = 1;
+ fillOut($include);
+ for my $i (keys %{ $totalIncludes{$include} }) {
+ $totalIncludes{$file}{$i} = 1;
+ }
+ }
+}
+
+sub check
+{
+ my ($file) = @_;
+
+ for my $include (keys %{ $includes{$file} }) {
+ fillOut($include);
+ }
+ for my $i1 (sort keys %{ $includes{$file} }) {
+ for my $i2 (keys %{ $includes{$file} }) {
+ next if $i1 eq $i2;
+ if ($totalIncludes{$i2}{$i1}) {
+ my $b1 = $i1;
+ my $b2 = $file;
+ $b1 =~ s/\..+$//;
+ $b2 =~ s/\..+$//;
+ print "$paths{$file} does not need to include $i1, because $i2 does\n" if $b1 ne $b2;
+ last;
+ }
+ }
+ }
+}
+
+for my $file (sort keys %includes) {
+ check($file);
+}
diff --git a/WebKitTools/Scripts/find-included-framework-headers b/WebKitTools/Scripts/find-included-framework-headers
new file mode 100755
index 0000000..3e7aaf6
--- /dev/null
+++ b/WebKitTools/Scripts/find-included-framework-headers
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+FILE_EXTENSIONS_TO_SEARCH="cpp h m mm"
+
+for framework in $*; do
+ echo -e "\n$framework\n=================="
+ for ext in ${FILE_EXTENSIONS_TO_SEARCH}; do
+ find . -name "*.$ext" -exec grep $framework {} ';' | grep '\(include\|import\)' | sed -e 's|.*/\(.*\.h\).*|\1|'
+ done | sort | uniq
+done
diff --git a/WebKitTools/Scripts/gdb-drosera b/WebKitTools/Scripts/gdb-drosera
new file mode 100644
index 0000000..fcde476
--- /dev/null
+++ b/WebKitTools/Scripts/gdb-drosera
@@ -0,0 +1,59 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2007 Apple Computer, 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.
+
+# Simplified "run under gdb" script for Web Kit Open Source Project.
+
+use strict;
+use Getopt::Long;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+use File::Temp qw/:mktemp/;
+
+setConfiguration();
+my $productDir = productDir();
+my $droseraPath = "$productDir/Drosera.app/Contents/MacOS/Drosera";
+
+# Check to see that gdb is in the usual place.
+my $gdbPath = "/usr/bin/gdb";
+die "Can't find gdb executable. Is gdb installed?\n" unless -x $gdbPath;
+
+# Check to see that all the frameworks are built.
+checkFrameworks();
+
+# Put a command to set DYLD_FRAMEWORK_PATH in a temp file.
+my ($fh, $path) = mkstemp("/tmp/gdb-drosera-XXXX");
+print $fh "set env DYLD_FRAMEWORK_PATH $productDir\n";
+
+# Start up Drosera.
+print "Start Drosera under gdb with DYLD_FRAMEWORK_PATH set to point to built WebKit in $productDir.\n";
+exec $gdbPath, "-x", $path, $droseraPath or die;
+
+# Delete the temporary file.
+unlink0($fh, $path) or die "Error unlinking file $path safely";
+
diff --git a/WebKitTools/Scripts/gdb-safari b/WebKitTools/Scripts/gdb-safari
new file mode 100755
index 0000000..b94dc12
--- /dev/null
+++ b/WebKitTools/Scripts/gdb-safari
@@ -0,0 +1,61 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005 Apple Computer, 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.
+
+# Simplified "run under gdb" script for Web Kit Open Source Project.
+
+use strict;
+use Getopt::Long;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+use File::Temp qw/:mktemp/;
+
+setConfiguration();
+my $productDir = productDir();
+my $safariPath = safariPath();
+
+# Check to see that gdb is in the usual place.
+my $gdbPath = "/usr/bin/gdb";
+die "Can't find gdb executable. Is gdb installed?\n" unless -x $gdbPath;
+
+# Check to see that all the frameworks are built.
+checkFrameworks();
+
+# Put a command to set DYLD_FRAMEWORK_PATH in a temp file.
+# Also set WEBKIT_UNSET_DYLD_FRAMEWORK_PATH to YES in this environment, so that
+# executables launched by Safari don't inherit using the new frameworks.
+my ($fh, $path) = mkstemp("/tmp/gdb-safari-XXXX");
+print $fh "set env DYLD_FRAMEWORK_PATH $productDir\n";
+print $fh "set env WEBKIT_UNSET_DYLD_FRAMEWORK_PATH YES\n";
+
+# Start up Safari.
+print "Start Safari under gdb with DYLD_FRAMEWORK_PATH set to point to built WebKit in $productDir.\n";
+exec $gdbPath, "-x", $path, $safariPath or die;
+
+# Delete the temporary file.
+unlink0($fh, $path) or die "Error unlinking file $path safely";
diff --git a/WebKitTools/Scripts/generate-coverage-data b/WebKitTools/Scripts/generate-coverage-data
new file mode 100755
index 0000000..7ed36aa
--- /dev/null
+++ b/WebKitTools/Scripts/generate-coverage-data
@@ -0,0 +1,71 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005, 2006 Apple Computer, Inc. All rights reserved.
+# 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:
+#
+# 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.
+
+# Simple script to build, run and visualize coverage information
+
+use strict;
+use File::Basename;
+use File::Spec;
+use FindBin;
+use Getopt::Long qw(:config pass_through);
+use lib $FindBin::Bin;
+use webkitdirs;
+use POSIX;
+
+# Generate a name for our results
+my $svnVersion = determineCurrentSVNRevision();
+my @timeData = localtime(time);
+my $resultName = $svnVersion . "-" . join('_', @timeData);
+my @otherOptions = ();
+
+# Move to the source directory
+# Delete old gcov files
+# Compile WebKit and run the tests
+# Generate the coverage graph...
+# Upload
+
+$ENV{'WEBKIT_COVERAGE_BUILD'} = 1;
+chdirWebKit();
+
+# Clean-up old files
+print "Cleaning up\n";
+system("if [ -d WebKitBuild ]; then find WebKitBuild -name '*.gcda' -delete; fi;") == 0 or die;
+
+
+print "Building and testing\n";
+system("WebKitTools/Scripts/build-webkit", "--coverage", @ARGV) == 0 or die;
+system "WebKitTools/Scripts/run-webkit-tests", "--no-launch-safari";
+system "WebKitTools/Scripts/run-javascriptcore-tests", "--coverage", @ARGV;
+
+# Collect the data and generate a report
+print "Collecting coverage data\n";
+system("WebKitTools/CodeCoverage/run-generate-coverage-data", $resultName, "WebKitBuild/Coverage") == 0 or die;
+system("WebKitTools/CodeCoverage/regenerate-coverage-display", "WebKitBuild/Coverage", "WebKitBuild/Coverage/html") == 0 or die;
+
+print "Done\n";
diff --git a/WebKitTools/Scripts/make-js-test-wrappers b/WebKitTools/Scripts/make-js-test-wrappers
new file mode 100755
index 0000000..b58978f
--- /dev/null
+++ b/WebKitTools/Scripts/make-js-test-wrappers
@@ -0,0 +1,103 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2006 Apple Computer, 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.
+
+# Script to generate HTML wrappers for JavaScript tests from templates
+
+use strict;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+
+setConfiguration();
+my $productDir = productDir();
+
+use strict;
+
+chdirWebKit();
+
+my @templates = `find LayoutTests -name "TEMPLATE.html"`;
+
+for my $tfile (@templates) {
+
+ chomp $tfile;
+
+ my $tpath = $tfile;
+ $tpath =~ s:/resources/TEMPLATE.html$::;
+
+ print "${tpath}\n";
+
+ chdirWebKit();
+ chdir($tpath);
+
+ my @files = `find resources -name "*.js"`;
+
+ open TEMPLATE, "<resources/TEMPLATE.html";
+ my $template = do { local $/; <TEMPLATE> };
+ close TEMPLATE;
+
+ my $templateNegative = $template;
+ if (-e "resources/TEMPLATE-n.html") {
+ open TEMPLATE, "<resources/TEMPLATE-n.html";
+ $templateNegative = do { local $/; <TEMPLATE> };
+ close TEMPLATE;
+ }
+
+ for my $file (@files) {
+ chomp $file;
+ next if $file =~ /js-test-.*\.js$/;
+ next if $file =~ /SVGTestCase\.js/;
+ next if $file =~ m:resources/attr-case-sensitivity\.js$:;
+ next if $file =~ m:resources/frame-loading-via-document-write\.js$:;
+ next if $file =~ m:resources/intersectsNode\.js$:;
+ next if $file =~ m:resources/script-element-gc\.js$:;
+ next if $file =~ m:resources/script-element-gc\.js$:;
+ next if $file =~ m:resources/script3\.js$:;
+ next if $file =~ m:resources/script4\.js$:;
+ next if $file =~ m:resources/script5\.js$:;
+ next if $file =~ m:resources/select-options-remove\.js$:;
+ next if $file =~ m:resources/wrapper-identity-base\.js$:;
+
+ my $html = $file;
+ $html =~ s:resources/(.*)\.js:$1.html:;
+ next if -f "$html-disabled";
+
+ system("grep -q 'successfullyParsed =' $file");
+ if ($? != 0) {
+ `echo "" >> "${file}"`;
+ `echo "var successfullyParsed = true;" >> "${file}"`;
+ }
+
+ print " ${html}\n";
+ open HTML, ">$html";
+ my $output = ($file =~ /-n\.js/) ? $templateNegative : $template;
+ $output =~ s:YOUR_JS_FILE_HERE:$file:;
+ print HTML $output;
+
+ close HTML;
+ }
+}
diff --git a/WebKitTools/Scripts/num-cpus b/WebKitTools/Scripts/num-cpus
new file mode 100755
index 0000000..c5f28a1
--- /dev/null
+++ b/WebKitTools/Scripts/num-cpus
@@ -0,0 +1,16 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Win32API::Registry 0.21 qw( :ALL );
+
+
+my $key;
+my $i = 0;
+while (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\$i", 0, KEY_READ, $key)) {
+ $i++;
+ RegCloseKey($key);
+}
+
+print "$i\n";
diff --git a/WebKitTools/Scripts/parallelcl b/WebKitTools/Scripts/parallelcl
new file mode 100755
index 0000000..532079f
--- /dev/null
+++ b/WebKitTools/Scripts/parallelcl
@@ -0,0 +1,224 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use File::Basename;
+use File::Spec;
+use File::Temp;
+use POSIX;
+
+sub makeJob(\@$);
+sub forkAndCompileFiles(\@$);
+sub Exec($);
+sub waitForChild(\@);
+sub cleanup(\@);
+
+my $debug = 0;
+
+chomp(my $clexe = `cygpath -u '$ENV{'VS80COMNTOOLS'}/../../VC/bin/cl.exe'`);
+
+if ($debug) {
+ print STDERR "Received " . @ARGV . " arguments:\n";
+ foreach my $arg (@ARGV) {
+ print STDERR "$arg\n";
+ }
+}
+
+my $commandFile;
+foreach my $arg (@ARGV) {
+ if ($arg =~ /^[\/-](E|EP|P)$/) {
+ print STDERR "The invoking process wants preprocessed source, so let's hand off this whole command to the real cl.exe\n" if $debug;
+ Exec("\"$clexe\" \"" . join('" "', @ARGV) . "\"");
+ } elsif ($arg =~ /^@(.*)$/) {
+ chomp($commandFile = `cygpath -u '$1'`);
+ }
+}
+
+die "No command file specified!" unless $commandFile;
+die "Couldn't find $commandFile!" unless -f $commandFile;
+
+my @sources;
+
+open(COMMAND, '<:raw:encoding(UTF16-LE):crlf:utf8', $commandFile) or die "Couldn't open $commandFile!";
+
+# The first line of the command file contains all the options to cl.exe plus the first (possibly quoted) filename
+my $firstLine = <COMMAND>;
+$firstLine =~ s/\r?\n$//;
+
+# To find the start of the first filename, look for either the last space on the line.
+# If the filename is quoted, the last character on the line will be a quote, so look for the quote before that.
+my $firstFileIndex;
+print STDERR "Last character of first line = '" . substr($firstLine, -1, 1) . "'\n" if $debug;
+if (substr($firstLine, -1, 1) eq '"') {
+ print STDERR "First file is quoted\n" if $debug;
+ $firstFileIndex = rindex($firstLine, '"', length($firstLine) - 2);
+} else {
+ print STDERR "First file is NOT quoted\n" if $debug;
+ $firstFileIndex = rindex($firstLine, ' ') + 1;
+}
+
+my $options = substr($firstLine, 0, $firstFileIndex) . join(' ', @ARGV[1 .. $#ARGV]);
+my $possibleFirstFile = substr($firstLine, $firstFileIndex);
+if ($possibleFirstFile =~ /\.(cpp|c)/) {
+ push(@sources, $possibleFirstFile);
+} else {
+ $options .= " $possibleFirstFile";
+}
+
+print STDERR "######## Found options $options ##########\n" if $debug;
+print STDERR "####### Found first source file $sources[0] ########\n" if @sources && $debug;
+
+# The rest of the lines of the command file just contain source files, one per line
+while (my $source = <COMMAND>) {
+ chomp($source);
+ $source =~ s/^\s+//;
+ $source =~ s/\s+$//;
+ push(@sources, $source) if length($source);
+}
+close(COMMAND);
+
+my $numSources = @sources;
+exit unless $numSources > 0;
+
+my $numJobs;
+if ($options =~ s/-j\s*([0-9]+)//) {
+ $numJobs = $1;
+} else {
+ chomp($numJobs = `num-cpus`);
+}
+
+print STDERR "\n\n####### RUNNING AT MOST $numJobs PARALLEL INSTANCES OF cl.exe ###########\n\n";# if $debug;
+
+# Magic determination of job size
+# The hope is that by splitting the source files up into 2*$numJobs pieces, we
+# won't suffer too much if one job finishes much more quickly than another.
+# However, we don't want to split it up too much due to cl.exe overhead, so set
+# the minimum job size to 5.
+my $jobSize = POSIX::ceil($numSources / (2 * $numJobs));
+$jobSize = $jobSize < 5 ? 5 : $jobSize;
+
+print STDERR "######## jobSize = $jobSize ##########\n" if $debug;
+
+# Sort the source files randomly so that we don't end up with big clumps of large files (aka SVG)
+sub fisher_yates_shuffle(\@)
+{
+ my ($array) = @_;
+ for (my $i = @{$array}; --$i; ) {
+ my $j = int(rand($i+1));
+ next if $i == $j;
+ @{$array}[$i,$j] = @{$array}[$j,$i];
+ }
+}
+
+fisher_yates_shuffle(@sources); # permutes @array in place
+
+my @children;
+my @tmpFiles;
+my $status = 0;
+while (@sources) {
+ while (@sources && @children < $numJobs) {
+ my $pid;
+ my $tmpFile;
+ my $job = makeJob(@sources, $jobSize);
+ ($pid, $tmpFile) = forkAndCompileFiles(@{$job}, $options);
+
+ print STDERR "####### Spawned child with PID $pid and tmpFile $tmpFile ##########\n" if $debug;
+ push(@children, $pid);
+ push(@tmpFiles, $tmpFile);
+ }
+
+ $status |= waitForChild(@children);
+}
+
+while (@children) {
+ $status |= waitForChild(@children);
+}
+cleanup(@tmpFiles);
+
+exit WEXITSTATUS($status);
+
+
+sub makeJob(\@$)
+{
+ my ($files, $jobSize) = @_;
+
+ my @job;
+ if (@{$files} > ($jobSize * 1.5)) {
+ @job = splice(@{$files}, -$jobSize);
+ } else {
+ # Compile all the remaining files in this job to avoid having a small job later
+ @job = splice(@{$files});
+ }
+
+ return \@job;
+}
+
+sub forkAndCompileFiles(\@$)
+{
+ print STDERR "######## forkAndCompileFiles()\n" if $debug;
+ my ($files, $options) = @_;
+
+ if ($debug) {
+ foreach my $file (@{$files}) {
+ print STDERR "######## $file\n";
+ }
+ }
+
+ my (undef, $tmpFile) = File::Temp::tempfile('clcommandXXXXX', DIR => File::Spec->tmpdir, OPEN => 0);
+
+ my $pid = fork();
+ die "Fork failed" unless defined($pid);
+
+ unless ($pid) {
+ # Child process
+ open(TMP, '>:raw:encoding(UTF16-LE):crlf:utf8', $tmpFile) or die "Couldn't open $tmpFile";
+ print TMP "$options\n";
+ foreach my $file (@{$files}) {
+ print TMP "$file\n";
+ }
+ close(TMP);
+
+ chomp(my $winTmpFile = `cygpath -m $tmpFile`);
+ Exec "\"$clexe\" \@\"$winTmpFile\"";
+ } else {
+ return ($pid, $tmpFile);
+ }
+}
+
+sub Exec($)
+{
+ my ($command) = @_;
+
+ print STDERR "Exec($command)\n" if $debug;
+
+ exec($command);
+}
+
+sub waitForChild(\@)
+{
+ my ($children) = @_;
+
+ return unless @{$children};
+
+ my $deceased = wait();
+ my $status = $?;
+ print STDERR "######## Child with PID $deceased finished ###########\n" if $debug;
+ for (my $i = 0; $i < @{$children}; $i++) {
+ if ($children->[$i] == $deceased) {
+ splice(@{$children}, $i, 1);
+ last;
+ }
+ }
+
+ return $status;
+}
+
+sub cleanup(\@)
+{
+ my ($tmpFiles) = @_;
+
+ foreach my $file (@{$tmpFiles}) {
+ unlink $file;
+ }
+}
diff --git a/WebKitTools/Scripts/parse-malloc-history b/WebKitTools/Scripts/parse-malloc-history
new file mode 100755
index 0000000..76ca74b
--- /dev/null
+++ b/WebKitTools/Scripts/parse-malloc-history
@@ -0,0 +1,154 @@
+#!/usr/bin/perl
+
+# 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.
+
+# Parses the callstacks in a file with malloc_history formatted content, sorting
+# based on total number of bytes allocated, and filtering based on command-line
+# parameters.
+
+use Getopt::Long;
+use File::Basename;
+
+use strict;
+use warnings;
+
+sub commify($);
+
+sub main()
+{
+ my $usage =
+ "Usage: " . basename($0) . " [options] malloc_history.txt\n" .
+ " --grep-regexp Include only call stacks that match this regular expression.\n" .
+ " --byte-minimum Include only call stacks with allocation sizes >= this value.\n" .
+ " --merge-regexp Merge all call stacks that match this regular expression.\n" .
+ " --merge-depth Merge all call stacks that match at this stack depth and above.\n";
+
+ my $grepRegexp = "";
+ my $byteMinimum = "";
+ my @mergeRegexps = ();
+ my $mergeDepth = "";
+ my $getOptionsResult = GetOptions(
+ "grep-regexp:s" => \$grepRegexp,
+ "byte-minimum:i" => \$byteMinimum,
+ "merge-regexp:s" => \@mergeRegexps,
+ "merge-depth:i" => \$mergeDepth
+ );
+ my $fileName = $ARGV[0];
+ die $usage if (!$getOptionsResult || !$fileName);
+
+ open FILE, "<$fileName" or die "bad file: $fileName";
+ my @file = <FILE>;
+ close FILE;
+
+ my %callstacks = ();
+ my $byteCountTotal = 0;
+
+ for (my $i = 0; $i < @file; $i++) {
+ my $line = $file[$i];
+ my ($callCount, $byteCount);
+
+ next if $line =~ /^\-/;
+
+ # First try malloc_history format
+ # 6 calls for 664 bytes thread_ffffffff |0x0 | start
+ ($callCount, $byteCount) = ($line =~ /(\d+) calls for (\d+) bytes/);
+
+ # Then try leaks format
+ # Leak: 0x0ac3ca40 size=48
+ # 0x00020001 0x00000001 0x00000000 0x00000000 ................
+ # Call stack: [thread ffffffff]: | 0x0 | start
+ if (!$callCount || !$byteCount) {
+ $callCount = 1;
+ ($byteCount) = ($line =~ /Leak: [x[:xdigit:]]* size=(\d+)/);
+
+ if ($byteCount) {
+ while (!($line =~ "Call stack: ")) {
+ $i++;
+ $line = $file[$i];
+ }
+ }
+ }
+
+ # Then give up
+ next if (!$callCount || !$byteCount);
+
+ $byteCountTotal += $byteCount;
+
+ next if ($grepRegexp && !($line =~ $grepRegexp));
+
+ my $callstackBegin = 0;
+ if ($mergeDepth) {
+ # count stack frames backwards from end of callstack
+ $callstackBegin = length($line);
+ for (my $pipeCount = 0; $pipeCount < $mergeDepth; $pipeCount++) {
+ my $rindexResult = rindex($line, "|", $callstackBegin - 1);
+ last if $rindexResult == -1;
+ $callstackBegin = $rindexResult;
+ }
+ } else {
+ # start at beginning of callstack
+ $callstackBegin = index($line, "|");
+ }
+
+ my $callstack = substr($line, $callstackBegin + 2); # + 2 skips "| "
+ for my $regexp (@mergeRegexps) {
+ if ($callstack =~ $regexp) {
+ $callstack = $regexp . "\n";
+ last;
+ }
+ }
+
+ if (!$callstacks{$callstack}) {
+ $callstacks{$callstack} = {"callCount" => 0, "byteCount" => 0};
+ }
+
+ $callstacks{$callstack}{"callCount"} += $callCount;
+ $callstacks{$callstack}{"byteCount"} += $byteCount;
+ }
+
+ my $byteCountTotalReported = 0;
+ for my $callstack (sort { $callstacks{$b}{"byteCount"} <=> $callstacks{$a}{"byteCount"} } keys %callstacks) {
+ my $callCount = $callstacks{$callstack}{"callCount"};
+ my $byteCount = $callstacks{$callstack}{"byteCount"};
+ last if ($byteMinimum && $byteCount < $byteMinimum);
+
+ $byteCountTotalReported += $byteCount;
+ print commify($callCount) . " calls for " . commify($byteCount) . " bytes: $callstack\n";
+ }
+
+ print "total: " . commify($byteCountTotalReported) . " bytes (" . commify($byteCountTotal - $byteCountTotalReported) . " bytes excluded).\n";
+}
+
+exit(main());
+
+# Copied from perldoc -- please excuse the style
+sub commify($)
+{
+ local $_ = shift;
+ 1 while s/^([-+]?\d+)(\d{3})/$1,$2/;
+ return $_;
+}
diff --git a/WebKitTools/Scripts/pdevenv b/WebKitTools/Scripts/pdevenv
new file mode 100755
index 0000000..8072adf
--- /dev/null
+++ b/WebKitTools/Scripts/pdevenv
@@ -0,0 +1,24 @@
+#!/usr/bin/perl -w
+
+use strict;
+use warnings;
+
+use File::Temp qw/tempfile/;
+use FindBin;
+
+my ($fh, $path) = tempfile(UNLINK => 0, SUFFIX => '.cmd') or die;
+
+chomp(my $vcBin = `cygpath -w "$FindBin::Bin/../vcbin"`);
+
+print $fh "\@echo off\n\n";
+print $fh "call \"\%VS80COMNTOOLS\%\\vsvars32.bat\"\n\n";
+print $fh "set PATH=$vcBin;\%PATH\%\n\n";
+print $fh "devenv.com /useenv " . join(" ", @ARGV) . "\n";
+
+close $fh;
+
+chmod 0755, $path;
+
+chomp($path = `cygpath -w -s '$path'`);
+
+exec("cmd /c \"call $path\"");
diff --git a/WebKitTools/Scripts/prepare-ChangeLog b/WebKitTools/Scripts/prepare-ChangeLog
new file mode 100755
index 0000000..913eea5
--- /dev/null
+++ b/WebKitTools/Scripts/prepare-ChangeLog
@@ -0,0 +1,1256 @@
+#!/usr/bin/perl -w
+# -*- Mode: perl; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+
+#
+# Copyright (C) 2000, 2001 Eazel, Inc.
+# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
+#
+# prepare-ChangeLog is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# prepare-ChangeLog 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
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with this program; if not, write to the Free
+# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+
+# Perl script to create a ChangeLog entry with names of files
+# and functions from a diff.
+#
+# Darin Adler <darin@bentspoon.com>, started 20 April 2000
+# Java support added by Maciej Stachowiak <mjs@eazel.com>
+# Objective-C, C++ and Objective-C++ support added by Maciej Stachowiak <mjs@apple.com>
+# Git support added by Adam Roben <aroben@apple.com>
+
+
+#
+# TODO:
+# List functions that have been removed too.
+# Decide what a good logical order is for the changed files
+# other than a normal text "sort" (top level first?)
+# (group directories?) (.h before .c?)
+# Handle yacc source files too (other languages?).
+# Help merge when there are ChangeLog conflicts or if there's
+# already a partly written ChangeLog entry.
+# Add command line option to put the ChangeLog into a separate
+# file or just spew it out stdout.
+# Add SVN version numbers for commit (can't do that until
+# the changes are checked in, though).
+# Work around diff stupidity where deleting a function that starts
+# with a comment makes diff think that the following function
+# has been changed (if the following function starts with a comment
+# with the same first line, such as /**)
+# Work around diff stupidity where deleting an entire function and
+# the blank lines before it makes diff think you've changed the
+# previous function.
+
+use strict;
+use warnings;
+
+use File::Basename;
+use File::Spec;
+use FindBin;
+use Getopt::Long;
+use lib $FindBin::Bin;
+use POSIX qw(strftime);
+use VCSUtils;
+
+sub changeLogDate($);
+sub firstDirectoryOrCwd();
+sub diffFromToString();
+sub diffCommand(@);
+sub statusCommand(@);
+sub createPatchCommand($);
+sub diffHeaderFormat();
+sub findOriginalFileFromSvn($);
+sub generateFileList(\@\@\%);
+sub gitConfig($);
+sub isModifiedStatus($);
+sub isAddedStatus($);
+sub isConflictStatus($);
+sub statusDescription($$);
+sub extractLineRange($);
+sub canonicalizePath($);
+sub testListForChangeLog(@);
+sub get_function_line_ranges($$);
+sub get_function_line_ranges_for_c($$);
+sub get_function_line_ranges_for_java($$);
+sub method_decl_to_selector($);
+sub processPaths(\@);
+sub reviewerAndDescriptionForGitCommit($);
+
+# Project time zone for Cupertino, CA, US
+my $changeLogTimeZone = "PST8PDT";
+
+my $gitCommit = 0;
+my $gitReviewer = "";
+my $openChangeLogs = 0;
+my $showHelp = 0;
+my $spewDiff = $ENV{"PREPARE_CHANGELOG_DIFF"};
+my $updateChangeLogs = 1;
+my $parseOptionsResult =
+ GetOptions("diff|d!" => \$spewDiff,
+ "git-commit:s" => \$gitCommit,
+ "git-reviewer:s" => \$gitReviewer,
+ "help|h!" => \$showHelp,
+ "open|o!" => \$openChangeLogs,
+ "update!" => \$updateChangeLogs);
+if (!$parseOptionsResult || $showHelp) {
+ print STDERR basename($0) . " [-d|--diff] [-h|--help] [-o|--open] [--git-commit=<committish>] [--git-reviewer=<name>] [svndir1 [svndir2 ...]]\n";
+ print STDERR " -d|--diff Spew diff to stdout when running\n";
+ print STDERR " --git-commit Populate the ChangeLogs from the specified git commit\n";
+ print STDERR " --git-reviewer When populating the ChangeLogs from a git commit claim that the spcified name reviewed the change.\n";
+ print STDERR " This option is useful when the git commit lacks a Signed-Off-By: line\n";
+ print STDERR " -h|--help Show this help message\n";
+ print STDERR " -o|--open Open ChangeLogs in an editor when done\n";
+ print STDERR " --[no-]update Update ChangeLogs from svn before adding entry (default: update)\n";
+ exit 1;
+}
+
+my %paths = processPaths(@ARGV);
+
+my $isGit = isGitDirectory(firstDirectoryOrCwd());
+my $isSVN = isSVNDirectory(firstDirectoryOrCwd());
+
+$isSVN || $isGit || die "Couldn't determine your version control system.";
+
+# Find the list of modified files
+my @changed_files;
+my $changed_files_string;
+my %changed_line_ranges;
+my %function_lists;
+my @conflict_files;
+
+my $SVN = "svn";
+my $GIT = "git";
+
+my %supportedTestExtensions = map { $_ => 1 } qw(html shtml svg xml xhtml pl php);
+my @addedRegressionTests = ();
+my $didChangeRegressionTests = 0;
+
+generateFileList(@changed_files, @conflict_files, %function_lists);
+
+if (!@changed_files && !@conflict_files && !keys %function_lists) {
+ print STDERR " No changes found.\n";
+ exit 1;
+}
+
+if (@conflict_files) {
+ print STDERR " The following files have conflicts. Run prepare-ChangeLog again after fixing the conflicts:\n";
+ print STDERR join("\n", @conflict_files), "\n";
+ exit 1;
+}
+
+if (@changed_files) {
+ $changed_files_string = "'" . join ("' '", @changed_files) . "'";
+
+ # For each file, build a list of modified lines.
+ # Use line numbers from the "after" side of each diff.
+ print STDERR " Reviewing diff to determine which lines changed.\n";
+ my $file;
+ open DIFF, "-|", diffCommand(@changed_files) or die "The diff failed: $!.\n";
+ while (<DIFF>) {
+ $file = makeFilePathRelative($1) if $_ =~ diffHeaderFormat();
+ if (defined $file) {
+ my ($start, $end) = extractLineRange($_);
+ if ($start >= 0 && $end >= 0) {
+ push @{$changed_line_ranges{$file}}, [ $start, $end ];
+ } elsif (/DO_NOT_COMMIT/) {
+ print STDERR "WARNING: file $file contains the string DO_NOT_COMMIT, line $.\n";
+ }
+ }
+ }
+ close DIFF;
+}
+
+# For each source file, convert line range to function list.
+if (%changed_line_ranges) {
+ print STDERR " Extracting affected function names from source files.\n";
+ foreach my $file (keys %changed_line_ranges) {
+ # Only look for function names in .c files.
+ next unless $file =~ /\.(c|cpp|m|mm|h|java)/;
+
+ # Find all the functions in the file.
+ open SOURCE, $file or next;
+ my @function_ranges = get_function_line_ranges(\*SOURCE, $file);
+ close SOURCE;
+
+ # Find all the modified functions.
+ my @functions;
+ my %saw_function;
+ my @change_ranges = (@{$changed_line_ranges{$file}}, []);
+ my @change_range = (0, 0);
+ FUNCTION: foreach my $function_range_ref (@function_ranges) {
+ my @function_range = @$function_range_ref;
+
+ # Advance to successive change ranges.
+ for (;; @change_range = @{shift @change_ranges}) {
+ last FUNCTION unless @change_range;
+
+ # If past this function, move on to the next one.
+ next FUNCTION if $change_range[0] > $function_range[1];
+
+ # If an overlap with this function range, record the function name.
+ if ($change_range[1] >= $function_range[0]
+ and $change_range[0] <= $function_range[1]) {
+ if (!$saw_function{$function_range[2]}) {
+ $saw_function{$function_range[2]} = 1;
+ push @functions, $function_range[2];
+ }
+ next FUNCTION;
+ }
+ }
+ }
+
+ # Format the list of functions now.
+
+ if (@functions) {
+ $function_lists{$file} = "" if !defined $function_lists{$file};
+ $function_lists{$file} .= "\n (" . join("):\n (", @functions) . "):";
+ }
+ }
+}
+
+# Get some parameters for the ChangeLog we are about to write.
+my $date = changeLogDate($changeLogTimeZone);
+my $name = $ENV{CHANGE_LOG_NAME}
+ || $ENV{REAL_NAME}
+ || gitConfig("user.name")
+ || (split /\s*,\s*/, (getpwuid $<)[6])[0]
+ || "set REAL_NAME environment variable";
+my $email_address = $ENV{CHANGE_LOG_EMAIL_ADDRESS}
+ || $ENV{EMAIL_ADDRESS}
+ || gitConfig("user.email")
+ || "set EMAIL_ADDRESS environment variable";
+
+if ($gitCommit) {
+ $name = `$GIT log --max-count=1 --pretty=\"format:%an\" \"$gitCommit\"`;
+ $email_address = `$GIT log --max-count=1 --pretty=\"format:%ae\" \"$gitCommit\"`;
+}
+
+# Remove trailing parenthesized notes from user name (bit of hack).
+$name =~ s/\(.*?\)\s*$//g;
+
+# Find the change logs.
+my %has_log;
+my %files;
+foreach my $file (sort keys %function_lists) {
+ my $prefix = $file;
+ my $has_log = 0;
+ while ($prefix) {
+ $prefix =~ s-/[^/]+/?$-/- or $prefix = "";
+ $has_log = $has_log{$prefix};
+ if (!defined $has_log) {
+ $has_log = -f "${prefix}ChangeLog";
+ $has_log{$prefix} = $has_log;
+ }
+ last if $has_log;
+ }
+ if (!$has_log) {
+ print STDERR "No ChangeLog found for $file.\n";
+ } else {
+ push @{$files{$prefix}}, $file;
+ }
+}
+
+# Get the latest ChangeLog files from svn.
+my @logs = ();
+foreach my $prefix (sort keys %files) {
+ push @logs, File::Spec->catfile($prefix || ".", "ChangeLog");
+}
+
+if (@logs && $updateChangeLogs && $isSVN) {
+ print STDERR " Running 'svn update' to update ChangeLog files.\n";
+ open ERRORS, "-|", $SVN, "update", @logs
+ or die "The svn update of ChangeLog files failed: $!.\n";
+ my @conflictedChangeLogs;
+ while (my $line = <ERRORS>) {
+ print STDERR " ", $line;
+ push @conflictedChangeLogs, $1 if $line =~ m/^C\s+(.+)\s*$/;
+ }
+ close ERRORS;
+
+ if (@conflictedChangeLogs) {
+ print STDERR " Attempting to merge conflicted ChangeLogs.\n";
+ my $resolveChangeLogsPath = File::Spec->catfile(dirname($0), "resolve-ChangeLogs");
+ open RESOLVE, "-|", $resolveChangeLogsPath, "--no-warnings", @conflictedChangeLogs
+ or die "Could not open resolve-ChangeLogs script: $!.\n";
+ print STDERR " $_" while <RESOLVE>;
+ close RESOLVE;
+ }
+}
+
+# Write out a new ChangeLog file.
+foreach my $prefix (sort keys %files) {
+ my $changeLogPath = File::Spec->catfile($prefix || ".", "ChangeLog");
+ print STDERR " Editing the ${changeLogPath} file.\n";
+ open OLD_CHANGE_LOG, ${changeLogPath} or die "Could not open ${changeLogPath} file: $!.\n";
+ # It's less efficient to read the whole thing into memory than it would be
+ # to read it while we prepend to it later, but I like doing this part first.
+ my @old_change_log = <OLD_CHANGE_LOG>;
+ close OLD_CHANGE_LOG;
+ open CHANGE_LOG, "> ${changeLogPath}" or die "Could not write ${changeLogPath}\n.";
+ print CHANGE_LOG "$date $name <$email_address>\n\n";
+
+ my ($reviewer, $description) = reviewerAndDescriptionForGitCommit($gitCommit) if $gitCommit;
+ $reviewer = "NOBODY (OO" . "PS!)" if !$reviewer;
+
+ print CHANGE_LOG " Reviewed by $reviewer.\n\n";
+ print CHANGE_LOG $description . "\n" if $description;
+
+ if ($prefix =~ m/WebCore/ || `pwd` =~ m/WebCore/) {
+ if ($didChangeRegressionTests) {
+ print CHANGE_LOG testListForChangeLog(sort @addedRegressionTests);
+ } else {
+ print CHANGE_LOG " WARNING: NO TEST CASES ADDED OR CHANGED\n\n";
+ }
+ }
+
+ foreach my $file (sort @{$files{$prefix}}) {
+ my $file_stem = substr $file, length $prefix;
+ print CHANGE_LOG " * $file_stem:$function_lists{$file}\n";
+ }
+ print CHANGE_LOG "\n", @old_change_log;
+ close CHANGE_LOG;
+}
+
+# Write out another diff.
+if ($spewDiff && @changed_files) {
+ print STDERR " Running diff to help you write the ChangeLog entries.\n";
+ local $/ = undef; # local slurp mode
+ open DIFF, "-|", createPatchCommand($changed_files_string) or die "The diff failed: $!.\n";
+ print <DIFF>;
+ close DIFF;
+}
+
+# Open ChangeLogs.
+if ($openChangeLogs && @logs) {
+ print STDERR " Opening the edited ChangeLog files.\n";
+ my $editor = $ENV{"CHANGE_LOG_EDIT_APPLICATION"};
+ if ($editor) {
+ system "open", "-a", $editor, @logs;
+ } else {
+ system "open", "-e", @logs;
+ }
+}
+
+# Done.
+exit;
+
+sub canonicalizePath($)
+{
+ my ($file) = @_;
+
+ # Remove extra slashes and '.' directories in path
+ $file = File::Spec->canonpath($file);
+
+ # Remove '..' directories in path
+ my @dirs = ();
+ foreach my $dir (File::Spec->splitdir($file)) {
+ if ($dir eq '..' && $#dirs >= 0 && $dirs[$#dirs] ne '..') {
+ pop(@dirs);
+ } else {
+ push(@dirs, $dir);
+ }
+ }
+ return ($#dirs >= 0) ? File::Spec->catdir(@dirs) : ".";
+}
+
+sub changeLogDate($)
+{
+ my ($timeZone) = @_;
+ my $savedTimeZone = $ENV{'TZ'};
+ # Set TZ temporarily so that localtime() is in that time zone
+ $ENV{'TZ'} = $timeZone;
+ my $date = strftime("%Y-%m-%d", localtime());
+ if (defined $savedTimeZone) {
+ $ENV{'TZ'} = $savedTimeZone;
+ } else {
+ delete $ENV{'TZ'};
+ }
+ return $date;
+}
+
+sub get_function_line_ranges($$)
+{
+ my ($file_handle, $file_name) = @_;
+
+ if ($file_name =~ /\.(c|cpp|m|mm|h)$/) {
+ return get_function_line_ranges_for_c ($file_handle, $file_name);
+ } elsif ($file_name =~ /\.java$/) {
+ return get_function_line_ranges_for_java ($file_handle, $file_name);
+ }
+ return ();
+}
+
+
+sub method_decl_to_selector($)
+{
+ (my $method_decl) = @_;
+
+ $_ = $method_decl;
+
+ if ((my $comment_stripped) = m-([^/]*)(//|/*).*-) {
+ $_ = $comment_stripped;
+ }
+
+ s/,\s*...//;
+
+ if (/:/) {
+ my @components = split /:/;
+ pop @components if (scalar @components > 1);
+ $_ = (join ':', map {s/.*[^[:word:]]//; scalar $_;} @components) . ':';
+ } else {
+ s/\s*$//;
+ s/.*[^[:word:]]//;
+ }
+
+ return $_;
+}
+
+
+
+# Read a file and get all the line ranges of the things that look like C functions.
+# A function name is the last word before an open parenthesis before the outer
+# level open brace. A function starts at the first character after the last close
+# brace or semicolon before the function name and ends at the close brace.
+# Comment handling is simple-minded but will work for all but pathological cases.
+#
+# Result is a list of triples: [ start_line, end_line, function_name ].
+
+sub get_function_line_ranges_for_c($$)
+{
+ my ($file_handle, $file_name) = @_;
+
+ my @ranges;
+
+ my $in_comment = 0;
+ my $in_macro = 0;
+ my $in_method_declaration = 0;
+ my $in_parentheses = 0;
+ my $in_braces = 0;
+ my $brace_start = 0;
+ my $brace_end = 0;
+ my $skip_til_brace_or_semicolon = 0;
+
+ my $word = "";
+ my $interface_name = "";
+
+ my $potential_method_char = "";
+ my $potential_method_spec = "";
+
+ my $potential_start = 0;
+ my $potential_name = "";
+
+ my $start = 0;
+ my $name = "";
+
+ my $next_word_could_be_namespace = 0;
+ my $potential_namespace = "";
+ my @namespaces;
+
+ while (<$file_handle>) {
+ # Handle continued multi-line comment.
+ if ($in_comment) {
+ next unless s-.*\*/--;
+ $in_comment = 0;
+ }
+
+ # Handle continued macro.
+ if ($in_macro) {
+ $in_macro = 0 unless /\\$/;
+ next;
+ }
+
+ # Handle start of macro (or any preprocessor directive).
+ if (/^\s*\#/) {
+ $in_macro = 1 if /^([^\\]|\\.)*\\$/;
+ next;
+ }
+
+ # Handle comments and quoted text.
+ while (m-(/\*|//|\'|\")-) { # \' and \" keep emacs perl mode happy
+ my $match = $1;
+ if ($match eq "/*") {
+ if (!s-/\*.*?\*/--) {
+ s-/\*.*--;
+ $in_comment = 1;
+ }
+ } elsif ($match eq "//") {
+ s-//.*--;
+ } else { # ' or "
+ if (!s-$match([^\\]|\\.)*?$match--) {
+ warn "mismatched quotes at line $. in $file_name\n";
+ s-$match.*--;
+ }
+ }
+ }
+
+
+ # continued method declaration
+ if ($in_method_declaration) {
+ my $original = $_;
+ my $method_cont = $_;
+
+ chomp $method_cont;
+ $method_cont =~ s/[;\{].*//;
+ $potential_method_spec = "${potential_method_spec} ${method_cont}";
+
+ $_ = $original;
+ if (/;/) {
+ $potential_start = 0;
+ $potential_method_spec = "";
+ $potential_method_char = "";
+ $in_method_declaration = 0;
+ s/^[^;\{]*//;
+ } elsif (/{/) {
+ my $selector = method_decl_to_selector ($potential_method_spec);
+ $potential_name = "${potential_method_char}\[${interface_name} ${selector}\]";
+
+ $potential_method_spec = "";
+ $potential_method_char = "";
+ $in_method_declaration = 0;
+
+ $_ = $original;
+ s/^[^;{]*//;
+ } elsif (/\@end/) {
+ $in_method_declaration = 0;
+ $interface_name = "";
+ $_ = $original;
+ } else {
+ next;
+ }
+ }
+
+
+ # start of method declaration
+ if ((my $method_char, my $method_spec) = m&^([-+])([^0-9;][^;]*);?$&) {
+ my $original = $_;
+
+ if ($interface_name) {
+ chomp $method_spec;
+ $method_spec =~ s/\{.*//;
+
+ $potential_method_char = $method_char;
+ $potential_method_spec = $method_spec;
+ $potential_start = $.;
+ $in_method_declaration = 1;
+ } else {
+ warn "declaring a method but don't have interface on line $. in $file_name\n";
+ }
+ $_ = $original;
+ if (/\{/) {
+ my $selector = method_decl_to_selector ($potential_method_spec);
+ $potential_name = "${potential_method_char}\[${interface_name} ${selector}\]";
+
+ $potential_method_spec = "";
+ $potential_method_char = "";
+ $in_method_declaration = 0;
+ $_ = $original;
+ s/^[^{]*//;
+ } elsif (/\@end/) {
+ $in_method_declaration = 0;
+ $interface_name = "";
+ $_ = $original;
+ } else {
+ next;
+ }
+ }
+
+
+ # Find function, interface and method names.
+ while (m&((?:[[:word:]]+::)*operator(?:[ \t]*\(\)|[^()]*)|[[:word:]:~]+|[(){}:;])|\@(?:implementation|interface|protocol)\s+(\w+)[^{]*&g) {
+ # interface name
+ if ($2) {
+ $interface_name = $2;
+ next;
+ }
+
+ # Open parenthesis.
+ if ($1 eq "(") {
+ $potential_name = $word unless $in_parentheses || $skip_til_brace_or_semicolon;
+ $in_parentheses++;
+ next;
+ }
+
+ # Close parenthesis.
+ if ($1 eq ")") {
+ $in_parentheses--;
+ next;
+ }
+
+ # C++ constructor initializers
+ if ($1 eq ":") {
+ $skip_til_brace_or_semicolon = 1 unless ($in_parentheses || $in_braces);
+ }
+
+ # Open brace.
+ if ($1 eq "{") {
+ $skip_til_brace_or_semicolon = 0;
+
+ if ($potential_namespace) {
+ push @namespaces, $potential_namespace;
+ $potential_namespace = "";
+ next;
+ }
+
+ # Promote potential name to real function name at the
+ # start of the outer level set of braces (function body?).
+ if (!$in_braces and $potential_start) {
+ $start = $potential_start;
+ $name = $potential_name;
+ if (@namespaces && (length($name) < 2 || substr($name,1,1) ne "[")) {
+ $name = join ('::', @namespaces, $name);
+ }
+ }
+
+ $in_method_declaration = 0;
+
+ $brace_start = $. if (!$in_braces);
+ $in_braces++;
+ next;
+ }
+
+ # Close brace.
+ if ($1 eq "}") {
+ if (!$in_braces && @namespaces) {
+ pop @namespaces;
+ next;
+ }
+
+ $in_braces--;
+ $brace_end = $. if (!$in_braces);
+
+ # End of an outer level set of braces.
+ # This could be a function body.
+ if (!$in_braces and $name) {
+ push @ranges, [ $start, $., $name ];
+ $name = "";
+ }
+
+ $potential_start = 0;
+ $potential_name = "";
+ next;
+ }
+
+ # Semicolon.
+ if ($1 eq ";") {
+ $skip_til_brace_or_semicolon = 0;
+ $potential_start = 0;
+ $potential_name = "";
+ $in_method_declaration = 0;
+ next;
+ }
+
+ # Ignore "const" method qualifier.
+ if ($1 eq "const") {
+ next;
+ }
+
+ if ($1 eq "namespace" || $1 eq "class" || $1 eq "struct") {
+ $next_word_could_be_namespace = 1;
+ next;
+ }
+
+ # Word.
+ $word = $1;
+ if (!$skip_til_brace_or_semicolon) {
+ if ($next_word_could_be_namespace) {
+ $potential_namespace = $word;
+ $next_word_could_be_namespace = 0;
+ } elsif ($potential_namespace) {
+ $potential_namespace = "";
+ }
+
+ if (!$in_parentheses) {
+ $potential_start = 0;
+ $potential_name = "";
+ }
+ if (!$potential_start) {
+ $potential_start = $.;
+ $potential_name = "";
+ }
+ }
+ }
+ }
+
+ warn "missing close braces in $file_name (probable start at $brace_start)\n" if ($in_braces > 0);
+ warn "too many close braces in $file_name (probable start at $brace_end)\n" if ($in_braces < 0);
+
+ warn "mismatched parentheses in $file_name\n" if $in_parentheses;
+
+ return @ranges;
+}
+
+
+
+# Read a file and get all the line ranges of the things that look like Java
+# classes, interfaces and methods.
+#
+# A class or interface name is the word that immediately follows
+# `class' or `interface' when followed by an open curly brace and not
+# a semicolon. It can appear at the top level, or inside another class
+# or interface block, but not inside a function block
+#
+# A class or interface starts at the first character after the first close
+# brace or after the function name and ends at the close brace.
+#
+# A function name is the last word before an open parenthesis before
+# an open brace rather than a semicolon. It can appear at top level or
+# inside a class or interface block, but not inside a function block.
+#
+# A function starts at the first character after the first close
+# brace or after the function name and ends at the close brace.
+#
+# Comment handling is simple-minded but will work for all but pathological cases.
+#
+# Result is a list of triples: [ start_line, end_line, function_name ].
+
+sub get_function_line_ranges_for_java($$)
+{
+ my ($file_handle, $file_name) = @_;
+
+ my @current_scopes;
+
+ my @ranges;
+
+ my $in_comment = 0;
+ my $in_macro = 0;
+ my $in_parentheses = 0;
+ my $in_braces = 0;
+ my $in_non_block_braces = 0;
+ my $class_or_interface_just_seen = 0;
+
+ my $word = "";
+
+ my $potential_start = 0;
+ my $potential_name = "";
+ my $potential_name_is_class_or_interface = 0;
+
+ my $start = 0;
+ my $name = "";
+ my $current_name_is_class_or_interface = 0;
+
+ while (<$file_handle>) {
+ # Handle continued multi-line comment.
+ if ($in_comment) {
+ next unless s-.*\*/--;
+ $in_comment = 0;
+ }
+
+ # Handle continued macro.
+ if ($in_macro) {
+ $in_macro = 0 unless /\\$/;
+ next;
+ }
+
+ # Handle start of macro (or any preprocessor directive).
+ if (/^\s*\#/) {
+ $in_macro = 1 if /^([^\\]|\\.)*\\$/;
+ next;
+ }
+
+ # Handle comments and quoted text.
+ while (m-(/\*|//|\'|\")-) { # \' and \" keep emacs perl mode happy
+ my $match = $1;
+ if ($match eq "/*") {
+ if (!s-/\*.*?\*/--) {
+ s-/\*.*--;
+ $in_comment = 1;
+ }
+ } elsif ($match eq "//") {
+ s-//.*--;
+ } else { # ' or "
+ if (!s-$match([^\\]|\\.)*?$match--) {
+ warn "mismatched quotes at line $. in $file_name\n";
+ s-$match.*--;
+ }
+ }
+ }
+
+ # Find function names.
+ while (m-(\w+|[(){};])-g) {
+ # Open parenthesis.
+ if ($1 eq "(") {
+ if (!$in_parentheses) {
+ $potential_name = $word;
+ $potential_name_is_class_or_interface = 0;
+ }
+ $in_parentheses++;
+ next;
+ }
+
+ # Close parenthesis.
+ if ($1 eq ")") {
+ $in_parentheses--;
+ next;
+ }
+
+ # Open brace.
+ if ($1 eq "{") {
+ # Promote potential name to real function name at the
+ # start of the outer level set of braces (function/class/interface body?).
+ if (!$in_non_block_braces
+ and (!$in_braces or $current_name_is_class_or_interface)
+ and $potential_start) {
+ if ($name) {
+ push @ranges, [ $start, ($. - 1),
+ join ('.', @current_scopes) ];
+ }
+
+
+ $current_name_is_class_or_interface = $potential_name_is_class_or_interface;
+
+ $start = $potential_start;
+ $name = $potential_name;
+
+ push (@current_scopes, $name);
+ } else {
+ $in_non_block_braces++;
+ }
+
+ $potential_name = "";
+ $potential_start = 0;
+
+ $in_braces++;
+ next;
+ }
+
+ # Close brace.
+ if ($1 eq "}") {
+ $in_braces--;
+
+ # End of an outer level set of braces.
+ # This could be a function body.
+ if (!$in_non_block_braces) {
+ if ($name) {
+ push @ranges, [ $start, $.,
+ join ('.', @current_scopes) ];
+
+ pop (@current_scopes);
+
+ if (@current_scopes) {
+ $current_name_is_class_or_interface = 1;
+
+ $start = $. + 1;
+ $name = $current_scopes[$#current_scopes-1];
+ } else {
+ $current_name_is_class_or_interface = 0;
+ $start = 0;
+ $name = "";
+ }
+ }
+ } else {
+ $in_non_block_braces-- if $in_non_block_braces;
+ }
+
+ $potential_start = 0;
+ $potential_name = "";
+ next;
+ }
+
+ # Semicolon.
+ if ($1 eq ";") {
+ $potential_start = 0;
+ $potential_name = "";
+ next;
+ }
+
+ if ($1 eq "class" or $1 eq "interface") {
+ $class_or_interface_just_seen = 1;
+ next;
+ }
+
+ # Word.
+ $word = $1;
+ if (!$in_parentheses) {
+ if ($class_or_interface_just_seen) {
+ $potential_name = $word;
+ $potential_start = $.;
+ $class_or_interface_just_seen = 0;
+ $potential_name_is_class_or_interface = 1;
+ next;
+ }
+ }
+ if (!$potential_start) {
+ $potential_start = $.;
+ $potential_name = "";
+ }
+ $class_or_interface_just_seen = 0;
+ }
+ }
+
+ warn "mismatched braces in $file_name\n" if $in_braces;
+ warn "mismatched parentheses in $file_name\n" if $in_parentheses;
+
+ return @ranges;
+}
+
+sub processPaths(\@)
+{
+ my ($paths) = @_;
+ return ("." => 1) if (!@{$paths});
+
+ my %result = ();
+
+ for my $file (@{$paths}) {
+ die "can't handle absolute paths like \"$file\"\n" if File::Spec->file_name_is_absolute($file);
+ die "can't handle empty string path\n" if $file eq "";
+ die "can't handle path with single quote in the name like \"$file\"\n" if $file =~ /'/; # ' (keep Xcode syntax highlighting happy)
+
+ my $untouchedFile = $file;
+
+ $file = canonicalizePath($file);
+
+ die "can't handle paths with .. like \"$untouchedFile\"\n" if $file =~ m|/\.\./|;
+
+ $result{$file} = 1;
+ }
+
+ return ("." => 1) if ($result{"."});
+
+ # Remove any paths that also have a parent listed.
+ for my $path (keys %result) {
+ for (my $parent = dirname($path); $parent ne '.'; $parent = dirname($parent)) {
+ if ($result{$parent}) {
+ delete $result{$path};
+ last;
+ }
+ }
+ }
+
+ return %result;
+}
+
+sub diffFromToString()
+{
+ return "" if $isSVN;
+ return $gitCommit if $gitCommit =~ m/.+\.\..+/;
+ return "\"$gitCommit^\" \"$gitCommit\"" if $gitCommit;
+ return "HEAD" if $isGit;
+}
+
+sub diffCommand(@)
+{
+ my @paths = @_;
+
+ my $pathsString = "'" . join("' '", @paths) . "'";
+
+ my $command;
+ if ($isSVN) {
+ $command = "$SVN diff --diff-cmd diff -x -N $pathsString";
+ } elsif ($isGit) {
+ $command = "$GIT diff " . diffFromToString();
+ $command .= " -- $pathsString" unless $gitCommit;
+ }
+
+ return $command;
+}
+
+sub statusCommand(@)
+{
+ my @files = @_;
+
+ my $filesString = "'" . join ("' '", @files) . "'";
+ my $command;
+ if ($isSVN) {
+ $command = "$SVN stat $filesString";
+ } elsif ($isGit) {
+ $command = "$GIT diff -r --name-status -C -C -M " . diffFromToString();
+ $command .= " -- $filesString" unless $gitCommit;
+ }
+
+ return "$command 2>&1";
+}
+
+sub createPatchCommand($)
+{
+ my ($changedFilesString) = @_;
+
+ my $command;
+ if ($isSVN) {
+ $command = "'$FindBin::Bin/svn-create-patch' $changedFilesString";
+ } elsif ($isGit) {
+ $command = "$GIT diff -C -C -M " . diffFromToString();
+ $command .= " -- $changedFilesString" unless $gitCommit;
+ }
+
+ return $command;
+}
+
+sub diffHeaderFormat()
+{
+ return qr/^Index: (\S+)$/ if $isSVN;
+ return qr/^diff --git a\/.+ b\/(.+)$/ if $isGit;
+}
+
+sub findOriginalFileFromSvn($)
+{
+ my ($file) = @_;
+ my $baseUrl;
+ open INFO, "$SVN info . |" or die;
+ while (<INFO>) {
+ if (/^URL: (.+)/) {
+ $baseUrl = $1;
+ last;
+ }
+ }
+ close INFO;
+ my $sourceFile;
+ open INFO, "$SVN info '$file' |" or die;
+ while (<INFO>) {
+ if (/^Copied From URL: (.+)/) {
+ $sourceFile = File::Spec->abs2rel($1, $baseUrl);
+ last;
+ }
+ }
+ close INFO;
+ return $sourceFile;
+}
+
+sub generateFileList(\@\@\%)
+{
+ my ($changedFiles, $conflictFiles, $functionLists) = @_;
+ print STDERR " Running status to find changed, added, or removed files.\n";
+ open STAT, "-|", statusCommand(keys %paths) or die "The status failed: $!.\n";
+ my $inGitCommitSection = 0;
+ while (<STAT>) {
+ my $status;
+ my $original;
+ my $file;
+
+ if ($isSVN) {
+ if (/^([ACDMR]).{5} (.+)$/) {
+ $status = $1;
+ $file = $2;
+ $original = findOriginalFileFromSvn($file) if substr($_, 3, 1) eq "+";
+ } else {
+ print; # error output from svn stat
+ }
+ } elsif ($isGit) {
+ if (/^([ADM])\t(.+)$/) {
+ $status = $1;
+ $file = $2;
+ } elsif (/^([CR])[0-9]{1,3}\t([^\t]+)\t([^\t\n]+)$/) { # for example: R90% newfile oldfile
+ $status = $1;
+ $original = $2;
+ $file = $3;
+ } else {
+ print; # error output from git diff
+ }
+ }
+
+ next unless $status;
+
+ $file = makeFilePathRelative($file);
+
+ if (isModifiedStatus($status) || isAddedStatus($status)) {
+ my @components = File::Spec->splitdir($file);
+ if ($components[0] eq "LayoutTests") {
+ $didChangeRegressionTests = 1;
+ push @addedRegressionTests, $file
+ if isAddedStatus($status)
+ && $file =~ /\.([a-zA-Z]+)$/
+ && $supportedTestExtensions{lc($1)}
+ && !scalar(grep(/^resources$/i, @components));
+ }
+ push @{$changedFiles}, $file if $components[$#components] ne "ChangeLog";
+ } elsif (isConflictStatus($status)) {
+ push @{$conflictFiles}, $file;
+ }
+ my $description = statusDescription($status, $original);
+ $functionLists->{$file} = $description if defined $description;
+ }
+ close STAT;
+}
+
+sub gitConfig($)
+{
+ return unless $isGit;
+
+ my ($config) = @_;
+
+ my $result = `$GIT config $config`;
+ if (($? >> 8) != 0) {
+ $result = `$GIT repo-config $config`;
+ }
+ chomp $result;
+ return $result;
+}
+
+sub isModifiedStatus($)
+{
+ my ($status) = @_;
+
+ my %statusCodes = (
+ "M" => 1,
+ );
+
+ return $statusCodes{$status};
+}
+
+sub isAddedStatus($)
+{
+ my ($status) = @_;
+
+ my %statusCodes = (
+ "A" => 1,
+ "C" => $isGit,
+ "R" => 1,
+ );
+
+ return $statusCodes{$status};
+}
+
+sub isConflictStatus($)
+{
+ my ($status) = @_;
+
+ my %svn = (
+ "C" => 1,
+ );
+
+ my %git = (
+ "U" => 1,
+ );
+
+ return 0 if $gitCommit; # an existing commit cannot have conflicts
+ return $svn{$status} if $isSVN;
+ return $git{$status} if $isGit;
+}
+
+sub statusDescription($$)
+{
+ my ($status, $original) = @_;
+
+ my %svn = (
+ "A" => defined $original ? " Copied from \%s." : " Added.",
+ "D" => " Removed.",
+ "M" => "",
+ "R" => defined $original ? " Replaced with \%s." : " Replaced.",
+ );
+
+ my %git = %svn;
+ $git{"A"} = " Added.";
+ $git{"C"} = " Copied from \%s.";
+ $git{"R"} = " Renamed from \%s.";
+
+ return sprintf($svn{$status}, $original) if $isSVN && exists $svn{$status};
+ return sprintf($git{$status}, $original) if $isGit && exists $git{$status};
+ return undef;
+}
+
+sub extractLineRange($)
+{
+ my ($string) = @_;
+
+ my ($start, $end) = (-1, -1);
+
+ if ($isSVN && $string =~ /^\d+(,\d+)?[acd](\d+)(,(\d+))?/) {
+ $start = $2;
+ $end = $4 || $2;
+ } elsif ($isGit && $string =~ /^@@ -\d+,\d+ \+(\d+),(\d+) @@/) {
+ $start = $1;
+ $end = $1 + $2 - 1;
+
+ # git-diff shows 3 lines of context above and below the actual changes,
+ # so we need to subtract that context to find the actual changed range.
+
+ # FIXME: This won't work if there's a change at the very beginning or
+ # very end of a file.
+
+ $start += 3;
+ $end -= 6;
+ }
+
+ return ($start, $end);
+}
+
+sub firstDirectoryOrCwd()
+{
+ my $dir = ".";
+ my @dirs = keys(%paths);
+
+ $dir = -d $dirs[0] ? $dirs[0] : dirname($dirs[0]) if @dirs;
+
+ return $dir;
+}
+
+sub testListForChangeLog(@)
+{
+ my (@tests) = @_;
+
+ return "" unless @tests;
+
+ my $leadString = " Test" . (@tests == 1 ? "" : "s") . ": ";
+ my $list = $leadString;
+ foreach my $i (0..$#tests) {
+ $list .= " " x length($leadString) if $i;
+ my $test = $tests[$i];
+ $test =~ s/^LayoutTests\///;
+ $list .= "$test\n";
+ }
+ $list .= "\n";
+
+ return $list;
+}
+
+sub reviewerAndDescriptionForGitCommit($)
+{
+ my ($commit) = @_;
+
+ my $description = '';
+ my $reviewer;
+
+ my @args = qw(rev-list --pretty);
+ push @args, '-1' if $commit !~ m/.+\.\..+/;
+ my $gitLog;
+ {
+ local $/ = undef;
+ open(GIT, "-|", $GIT, @args, $commit) || die;
+ $gitLog = <GIT>;
+ close(GIT);
+ }
+
+ my @commitLogs = split(/^[Cc]ommit [a-f0-9]{40}/m, $gitLog);
+ shift @commitLogs; # Remove initial blank commit log
+ my $commitLogCount = 0;
+ foreach my $commitLog (@commitLogs) {
+ $description .= "\n" if $commitLogCount;
+ $commitLogCount++;
+ my $inHeader = 1;
+ my @lines = split(/\n/, $commitLog);
+ shift @lines; # Remove initial blank line
+ foreach my $line (@lines) {
+ if ($inHeader) {
+ if (!$line) {
+ $inHeader = 0;
+ }
+ next;
+ } elsif ($line =~ /[Ss]igned-[Oo]ff-[Bb]y: (.+)/) {
+ if (!$reviewer) {
+ $reviewer = $1;
+ } else {
+ $reviewer .= ", " . $1;
+ }
+ } elsif (length $line == 0) {
+ $description = $description . "\n";
+ } else {
+ $line =~ s/^\s*//;
+ $description = $description . " " . $line . "\n";
+ }
+ }
+ }
+ if (!$reviewer) {
+ $reviewer = $gitReviewer;
+ }
+
+ return ($reviewer, $description);
+}
diff --git a/WebKitTools/Scripts/report-include-statistics b/WebKitTools/Scripts/report-include-statistics
new file mode 100755
index 0000000..f81c3c3
--- /dev/null
+++ b/WebKitTools/Scripts/report-include-statistics
@@ -0,0 +1,114 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005, 2006 Apple Computer, 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.
+
+# "report-include-statistics" script for Web Kit Open Source Project
+
+use strict;
+use File::Find;
+
+find(\&wanted, @ARGV ? @ARGV : ".");
+
+my %paths;
+my %sources;
+my %includes;
+
+sub wanted
+{
+ my $file = $_;
+
+ if ($file eq "icu") {
+ $File::Find::prune = 1;
+ return;
+ }
+
+ if ($file !~ /^\./ && $file =~ /\.(h|cpp|c|mm|m)$/) {
+ $paths{$file} = $File::Find::name;
+ $sources{$file} = $File::Find::name if $file !~ /\.h/;
+ open FILE, $file or die;
+ while (<FILE>) {
+ if (m-^\s*#\s*(include|import)\s+["<]((\S+/)*)(\S+)[">]-) {
+ my $include = ($2 eq "sys/" ? $2 : "") . $4;
+ $includes{$file}{$include}++;
+ }
+ }
+ close FILE;
+ }
+}
+
+my %totalIncludes;
+
+sub fillOut
+{
+ my ($file) = @_;
+
+ return if defined $totalIncludes{$file};
+
+ for my $include (keys %{ $includes{$file} }) {
+ $totalIncludes{$file}{$include} = 1;
+ fillOut($include);
+ for my $i (keys %{ $totalIncludes{$include} }) {
+ $totalIncludes{$file}{$i} = 1;
+ }
+ }
+}
+
+my %inclusionCounts;
+for my $file (keys %includes) {
+ $inclusionCounts{$file} = 0;
+ fillOut($file);
+}
+
+for my $file (keys %sources) {
+ for my $include (keys %{ $totalIncludes{$file} }) {
+ $inclusionCounts{$include}++;
+ }
+}
+
+for my $file (sort mostincludedcmp keys %includes) {
+ next if !$paths{$file};
+ my $count = $inclusionCounts{$file};
+ my $numIncludes = keys %{ $includes{$file} };
+ my $numTotalIncludes = keys %{ $totalIncludes{$file} };
+ print "$file is included $count times, includes $numIncludes files directly, $numTotalIncludes files total.\n"
+}
+
+# Sort most-included files first.
+sub mostincludedcmp($$)
+{
+ my ($filea, $fileb) = @_;
+
+ my $counta = $inclusionCounts{$filea} || 0;
+ my $countb = $inclusionCounts{$fileb} || 0;
+ return $countb <=> $counta if $counta != $countb;
+
+ my $ta = keys %{ $totalIncludes{$filea} };
+ my $tb = keys %{ $totalIncludes{$fileb} };
+ return $ta <=> $tb if $ta != $tb;
+
+ return $filea cmp $fileb;
+}
diff --git a/WebKitTools/Scripts/resolve-ChangeLogs b/WebKitTools/Scripts/resolve-ChangeLogs
new file mode 100755
index 0000000..fa01243
--- /dev/null
+++ b/WebKitTools/Scripts/resolve-ChangeLogs
@@ -0,0 +1,305 @@
+#!/usr/bin/perl -w
+
+# 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.
+
+# Merge and resolve ChangeLog conflicts for svn and git repositories
+
+use strict;
+
+use FindBin;
+use lib $FindBin::Bin;
+
+use File::Basename;
+use File::Spec;
+use Getopt::Long;
+use VCSUtils;
+
+sub conflictFiles($);
+sub fixChangeLogPatch($);
+sub mergeChanges($$$);
+sub resolveConflict($);
+sub showStatus($;$);
+
+my $SVN = "svn";
+my $GIT = "git";
+
+my $printWarnings = 1;
+my $showHelp;
+
+my $getOptionsResult = GetOptions(
+ 'h|help' => \$showHelp,
+ 'w|warnings!' => \$printWarnings,
+);
+
+sub findChangeLog {
+ return $_ if basename($_) eq "ChangeLog";
+
+ my $file = File::Spec->catfile($_, "ChangeLog");
+ return $file if -d $_ and -e $file;
+
+ return undef;
+}
+
+my @changeLogFiles = grep { defined $_ } map { findChangeLog($_) } @ARGV;
+
+if (scalar(@changeLogFiles) != scalar(@ARGV)) {
+ print STDERR "ERROR: Files listed on command-line that are not ChangeLogs.\n";
+ undef $getOptionsResult;
+} elsif (scalar(@changeLogFiles) == 0) {
+ print STDERR "ERROR: No ChangeLog files listed on command-line.\n";
+ undef $getOptionsResult;
+}
+
+if (!$getOptionsResult || $showHelp) {
+ print STDERR <<__END__;
+Usage: @{[ basename($0) ]} [options] path/to/ChangeLog [path/to/another/ChangeLog ...]
+ -h|--help show this help message
+ -w|--[no-]warnings show or suppress warnings (default: show warnings)
+__END__
+ exit 1;
+}
+
+for my $file (@changeLogFiles) {
+ my ($fileMine, $fileOlder, $fileNewer) = conflictFiles($file);
+ if (!$fileMine || !$fileOlder || !$fileNewer) {
+ next;
+ }
+ if (mergeChanges($fileMine, $fileOlder, $fileNewer)) {
+ if ($file ne $fileNewer) {
+ unlink($file);
+ rename($fileNewer, $file) || die;
+ }
+ unlink($fileMine, $fileOlder);
+ resolveConflict($file);
+ showStatus($file, 1);
+ } else {
+ showStatus($file);
+ print STDERR "WARNING: ${file} could not be merged using fuzz level 3.\n" if $printWarnings;
+ unlink($fileMine, $fileOlder, $fileNewer) if isGit();
+ }
+}
+
+exit 0;
+
+sub conflictFiles($)
+{
+ my ($file) = @_;
+ my $fileMine;
+ my $fileOlder;
+ my $fileNewer;
+
+ if (-e $file && -e "$file.orig" && -e "$file.rej") {
+ return ("$file.rej", "$file.orig", $file);
+ }
+
+ if (isSVN()) {
+ open STAT, "-|", $SVN, "status", $file || die;
+ my $status = <STAT>;
+ close STAT;
+ if (!$status || $status !~ m/^C\s+/) {
+ print STDERR "WARNING: ${file} is not in a conflicted state.\n" if $printWarnings;
+ return ();
+ }
+
+ $fileMine = "${file}.mine" if -e "${file}.mine";
+
+ my $currentRevision;
+ open INFO, "-|", $SVN, "info", $file || die;
+ while (my $line = <INFO>) {
+ $currentRevision = $1 if $line =~ m/^Revision: ([0-9]+)/;
+ }
+ close INFO;
+ $fileNewer = "${file}.r${currentRevision}" if -e "${file}.r${currentRevision}";
+
+ my @matchingFiles = grep { $_ ne $fileNewer } glob("${file}.r[0-9][0-9]*");
+ if (scalar(@matchingFiles) > 1) {
+ print STDERR "WARNING: Too many conflict files exist for ${file}!\n" if $printWarnings;
+ } else {
+ $fileOlder = shift @matchingFiles;
+ }
+ } elsif (isGit()) {
+ my $gitPrefix = `$GIT rev-parse --show-prefix`;
+ chomp $gitPrefix;
+ open GIT, "-|", $GIT, "ls-files", "--unmerged", $file || die;
+ while (my $line = <GIT>) {
+ my ($mode, $hash, $stage, $fileName) = split(' ', $line);
+ my $outputFile;
+ if ($stage == 1) {
+ $fileOlder = "${file}.BASE.$$";
+ $outputFile = $fileOlder;
+ } elsif ($stage == 2) {
+ $fileNewer = "${file}.LOCAL.$$";
+ $outputFile = $fileNewer;
+ } elsif ($stage == 3) {
+ $fileMine = "${file}.REMOTE.$$";
+ $outputFile = $fileMine;
+ } else {
+ die "Unknown file stage: $stage";
+ }
+ system("$GIT cat-file blob :${stage}:${gitPrefix}${file} > $outputFile");
+ }
+ close GIT;
+ } else {
+ die "Unknown version control system";
+ }
+
+ if (!$fileMine && !$fileOlder && !$fileNewer) {
+ print STDERR "WARNING: ${file} does not need merging.\n" if $printWarnings;
+ } elsif (!$fileMine || !$fileOlder || !$fileNewer) {
+ print STDERR "WARNING: ${file} is missing some conflict files.\n" if $printWarnings;
+ }
+
+ return ($fileMine, $fileOlder, $fileNewer);
+}
+
+sub fixChangeLogPatch($)
+{
+ my $patch = shift;
+ my $contextLineCount = 3;
+
+ return $patch if $patch !~ /\n@@ -1,(\d+) \+1,(\d+) @@\n( .*\n)+(\+.*\n)+( .*\n){$contextLineCount}$/m;
+ my ($oldLineCount, $newLineCount) = ($1, $2);
+ return $patch if $oldLineCount <= $contextLineCount;
+
+ # The diff(1) command is greedy when matching lines, so a new ChangeLog entry will
+ # have lines of context at the top of a patch when the existing entry has the same
+ # date and author as the new entry. This nifty loop alters a ChangeLog patch so
+ # that the added lines ("+") in the patch always start at the beginning of the
+ # patch and there are no initial lines of context.
+ my $newPatch;
+ my $lineCountInState = 0;
+ my $oldContentLineCountReduction = $oldLineCount - $contextLineCount;
+ my $newContentLineCountWithoutContext = $newLineCount - $oldLineCount - $oldContentLineCountReduction;
+ my ($stateHeader, $statePreContext, $stateNewChanges, $statePostContext) = (1..4);
+ my $state = $stateHeader;
+ foreach my $line (split(/\n/, $patch)) {
+ $lineCountInState++;
+ if ($state == $stateHeader && $line =~ /^@@ -1,$oldLineCount \+1,$newLineCount @\@$/) {
+ $line = "@@ -1,$contextLineCount +1," . ($newLineCount - $oldContentLineCountReduction) . " @@";
+ $lineCountInState = 0;
+ $state = $statePreContext;
+ } elsif ($state == $statePreContext && substr($line, 0, 1) eq " ") {
+ $line = "+" . substr($line, 1);
+ if ($lineCountInState == $oldContentLineCountReduction) {
+ $lineCountInState = 0;
+ $state = $stateNewChanges;
+ }
+ } elsif ($state == $stateNewChanges && substr($line, 0, 1) eq "+") {
+ # No changes to these lines
+ if ($lineCountInState == $newContentLineCountWithoutContext) {
+ $lineCountInState = 0;
+ $state = $statePostContext;
+ }
+ } elsif ($state == $statePostContext) {
+ if (substr($line, 0, 1) eq "+" && $lineCountInState <= $oldContentLineCountReduction) {
+ $line = " " . substr($line, 1);
+ } elsif ($lineCountInState > $contextLineCount && substr($line, 0, 1) eq " ") {
+ next; # Discard
+ }
+ }
+ $newPatch .= $line . "\n";
+ }
+
+ return $newPatch;
+}
+
+sub mergeChanges($$$)
+{
+ my ($fileMine, $fileOlder, $fileNewer) = @_;
+
+ my $traditionalReject = $fileMine =~ /\.rej$/ ? 1 : 0;
+
+ local $/ = undef;
+
+ my $patch;
+ if ($traditionalReject) {
+ open(DIFF, "<", $fileMine);
+ $patch = <DIFF>;
+ close(DIFF);
+ rename($fileMine, "$fileMine.save");
+ rename($fileOlder, "$fileOlder.save");
+ } else {
+ open(DIFF, "-|", qw(diff -u), $fileOlder, $fileMine) || die;
+ $patch = <DIFF>;
+ close(DIFF);
+ }
+
+ unlink("${fileNewer}.orig");
+ unlink("${fileNewer}.rej");
+
+ open(PATCH, "| patch --fuzz=3 $fileNewer > /dev/null") || die;
+ print PATCH fixChangeLogPatch($patch);
+ close(PATCH);
+
+ my $result;
+
+ # Refuse to merge the patch if it did not apply cleanly
+ if (-e "${fileNewer}.rej") {
+ unlink("${fileNewer}.rej");
+ unlink($fileNewer);
+ rename("${fileNewer}.orig", $fileNewer);
+ $result = 0;
+ } else {
+ unlink("${fileNewer}.orig");
+ $result = 1;
+ }
+
+ if ($traditionalReject) {
+ rename("$fileMine.save", $fileMine);
+ rename("$fileOlder.save", $fileOlder);
+ }
+
+ return $result;
+}
+
+sub resolveConflict($)
+{
+ my ($file) = @_;
+
+ if (isSVN()) {
+ system($SVN, "resolved", $file);
+ } elsif (isGit()) {
+ system($GIT, "add", $file);
+ } else {
+ die "Unknown version control system";
+ }
+}
+
+sub showStatus($;$)
+{
+ my ($file, $isConflictResolved) = @_;
+
+ if (isSVN()) {
+ system($SVN, "status", $file);
+ } elsif (isGit()) {
+ my @args = qw(--name-status);
+ unshift @args, qw(--cached) if $isConflictResolved;
+ system($GIT, "diff", @args, $file);
+ } else {
+ die "Unknown version control system";
+ }
+}
diff --git a/WebKitTools/Scripts/run-drawtest b/WebKitTools/Scripts/run-drawtest
new file mode 100755
index 0000000..2cd61de
--- /dev/null
+++ b/WebKitTools/Scripts/run-drawtest
@@ -0,0 +1,47 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005 Apple Computer, 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.
+
+# Simplified "run" script for WebKit Open Source Project.
+
+use strict;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+
+setConfiguration();
+my $productDir = productDir();
+
+# Check to see that all the frameworks are built (w/ SVG support).
+checkFrameworks();
+checkWebCoreSVGSupport(1);
+
+# Set up DYLD_FRAMEWORK_PATH to point to the product directory.
+print "Start DrawTest with DYLD_FRAMEWORK_PATH set to point to built WebKit in $productDir.\n";
+$ENV{DYLD_FRAMEWORK_PATH} = $productDir;
+my $drawtestPath = "$productDir/DrawTest.app/Contents/MacOS/DrawTest";
+exec $drawtestPath or die;
diff --git a/WebKitTools/Scripts/run-drosera b/WebKitTools/Scripts/run-drosera
new file mode 100644
index 0000000..925293c
--- /dev/null
+++ b/WebKitTools/Scripts/run-drosera
@@ -0,0 +1,41 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005, 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.
+
+# Simplified "run" script for Web Kit Open Source Project.
+
+use strict;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+
+setConfiguration();
+
+# Check to see that all the frameworks are built.
+checkFrameworks();
+
+exit exitStatus(runDrosera());
diff --git a/WebKitTools/Scripts/run-drosera-nightly.cmd b/WebKitTools/Scripts/run-drosera-nightly.cmd
new file mode 100644
index 0000000..4f547fb
--- /dev/null
+++ b/WebKitTools/Scripts/run-drosera-nightly.cmd
@@ -0,0 +1,12 @@
+@echo off
+set script="%TMP%\run-drosera-nightly2.cmd"
+set vsvars="%VS80COMNTOOLS%\vsvars32.bat"
+if exist %vsvars% (
+ copy %vsvars% "%script%"
+) else (
+ del "%script%"
+)
+
+FindSafari.exe %1 /printSafariEnvironment >> "%script%"
+echo Drosera.exe >> "%script%"
+call %script%
diff --git a/WebKitTools/Scripts/run-drosera.cmd b/WebKitTools/Scripts/run-drosera.cmd
new file mode 100755
index 0000000..3b6e1f0
--- /dev/null
+++ b/WebKitTools/Scripts/run-drosera.cmd
@@ -0,0 +1,5 @@
+@echo off
+set script="%TMP%\run-drosera2.cmd"
+FindSafari.exe %1 /printSafariEnvironment > "%script%"
+call %script%
+Drosera.exe
diff --git a/WebKitTools/Scripts/run-iexploder-tests b/WebKitTools/Scripts/run-iexploder-tests
new file mode 100755
index 0000000..6acff18
--- /dev/null
+++ b/WebKitTools/Scripts/run-iexploder-tests
@@ -0,0 +1,170 @@
+#!/usr/bin/perl
+
+# Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.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.
+
+# A script to semi-automatically run iExploder tests.
+
+use strict;
+use warnings;
+
+use Cwd;
+use FindBin;
+use Getopt::Long;
+use IPC::Open2;
+
+use lib $FindBin::Bin;
+use webkitdirs;
+
+sub openHTTPDIfNeeded();
+sub closeHTTPD();
+sub runSafari();
+
+# Argument handling
+my $guardMalloc = '';
+my $httpdPort = 8000;
+my $downloadTest;
+
+GetOptions(
+ 'guard-malloc|g' => \$guardMalloc,
+ 'get=s' => \$downloadTest,
+ 'port=i' => \$httpdPort
+);
+
+
+setConfiguration();
+my $productDir = productDir();
+
+chdirWebKit();
+
+checkFrameworks();
+
+my $httpdOpen = 0;
+openHTTPDIfNeeded();
+
+if ($downloadTest) {
+ system "/usr/bin/curl -o ~/Desktop/iexploder$downloadTest.html \"http://127.0.0.1:$httpdPort/iexploder.cgi?lookup=1&test=$downloadTest\"";
+ print "Saved the test as iexploder$downloadTest.html on the desktop\n";
+} else {
+ runSafari();
+ print "Last generated tests:\n";
+ system "grep 'iexploder.cgi' /tmp/WebKit/access_log.txt | tail -n -5 | awk -F'[ =&\\?]' '{if (\$8 == \"lookup\") print \$11; else print \$9}'";
+}
+
+closeHTTPD();
+
+
+sub runSafari()
+{
+ my $redirectTo;
+ if (@ARGV) {
+ $redirectTo = "http://127.0.0.1:$httpdPort/iexploder.cgi?lookup=1&test=$ARGV[0]";
+ } else {
+ $redirectTo = "http://127.0.0.1:$httpdPort/index.html";
+ }
+
+ open REDIRECT_HTML, ">", "/tmp/WebKit/redirect.html" or die;
+ print REDIRECT_HTML "<html>\n";
+ print REDIRECT_HTML " <head>\n";
+ print REDIRECT_HTML " <meta http-equiv=\"refresh\" content=\"1;URL=$redirectTo\" />\n";
+ print REDIRECT_HTML " <script type=\"text/javascript\">\n";
+ print REDIRECT_HTML " document.location = \"$redirectTo\";\n";
+ print REDIRECT_HTML " </script>\n";
+ print REDIRECT_HTML " </head>\n";
+ print REDIRECT_HTML " <body>\n";
+ print REDIRECT_HTML " </body>\n";
+ print REDIRECT_HTML "</html>\n";
+ close REDIRECT_HTML;
+
+ local %ENV;
+ $ENV{DYLD_INSERT_LIBRARIES} = "/usr/lib/libgmalloc.dylib" if $guardMalloc;
+ system "WebKitTools/Scripts/run-safari", "-NSOpen", "/tmp/WebKit/redirect.html";
+}
+
+sub openHTTPDIfNeeded()
+{
+ return if $httpdOpen;
+
+ mkdir "/tmp/WebKit";
+
+ if (-f "/tmp/WebKit/httpd.pid") {
+ my $oldPid = `cat /tmp/WebKit/httpd.pid`;
+ chomp $oldPid;
+ if (0 != kill 0, $oldPid) {
+ print "\nhttpd is already running: pid $oldPid, killing...\n";
+ kill 15, $oldPid;
+
+ my $retryCount = 20;
+ while ((0 != kill 0, $oldPid) && $retryCount) {
+ sleep 1;
+ --$retryCount;
+ }
+
+ die "Timed out waiting for httpd to quit" unless $retryCount;
+ }
+ }
+
+ my $testDirectory = getcwd() . "/LayoutTests";
+ my $iExploderDirectory = getcwd() . "/WebKitTools/iExploder";
+ my $httpdPath = "/usr/sbin/httpd";
+ my $httpdConfig = "$testDirectory/http/conf/httpd.conf";
+ $httpdConfig = "$testDirectory/http/conf/apache2-httpd.conf" if `$httpdPath -v` =~ m|Apache/2|;
+ my $documentRoot = "$iExploderDirectory/htdocs";
+ my $typesConfig = "$testDirectory/http/conf/mime.types";
+ my $listen = "127.0.0.1:$httpdPort";
+
+ open2(\*HTTPDIN, \*HTTPDOUT, $httpdPath,
+ "-f", "$httpdConfig",
+ "-C", "DocumentRoot \"$documentRoot\"",
+ "-C", "Listen $listen",
+ "-c", "TypesConfig \"$typesConfig\"",
+ "-c", "CustomLog \"/tmp/WebKit/access_log.txt\" common",
+ "-c", "ErrorLog \"/tmp/WebKit/error_log.txt\"",
+ # Apache wouldn't run CGIs with permissions==700 otherwise
+ "-c", "User \"#$<\"");
+
+ my $retryCount = 20;
+ while (system("/usr/bin/curl -q --silent --stderr - --output /dev/null $listen") && $retryCount) {
+ sleep 1;
+ --$retryCount;
+ }
+
+ die "Timed out waiting for httpd to start" unless $retryCount;
+
+ $httpdOpen = 1;
+}
+
+sub closeHTTPD()
+{
+ return if !$httpdOpen;
+
+ close HTTPDIN;
+ close HTTPDOUT;
+
+ kill 15, `cat /tmp/WebKit/httpd.pid` if -f "/tmp/WebKit/httpd.pid";
+
+ $httpdOpen = 0;
+}
diff --git a/WebKitTools/Scripts/run-javascriptcore-tests b/WebKitTools/Scripts/run-javascriptcore-tests
new file mode 100755
index 0000000..16522ca
--- /dev/null
+++ b/WebKitTools/Scripts/run-javascriptcore-tests
@@ -0,0 +1,173 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
+# Copyright (C) 2007 Eric Seidel <eric@webkit.org>
+#
+# 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.
+
+# Script to run the Web Kit Open Source Project JavaScriptCore tests (adapted from Mozilla).
+
+use strict;
+use FindBin;
+use Getopt::Long qw(:config pass_through);
+use lib $FindBin::Bin;
+use webkitdirs;
+use POSIX;
+
+my $coverageSupport = 0;
+GetOptions('coverage!' => \$coverageSupport);
+
+my @coverageSupportOption = ();
+if ($coverageSupport) {
+ push @coverageSupportOption, "GCC_GENERATE_TEST_COVERAGE_FILES=YES";
+ push @coverageSupportOption, "GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES";
+ push @coverageSupportOption, "EXTRA_LINK= -ftest-coverage -fprofile-arcs";
+ push @coverageSupportOption, "OTHER_CFLAGS= -MD";
+ push @coverageSupportOption, "OTHER_LDFLAGS= -ftest-coverage -fprofile-arcs -framework AppKit";
+}
+
+# determine configuration
+my $configuration;
+setConfiguration();
+$configuration = configuration();
+
+my @jsArgs;
+my @xcodeArgs;
+my $root;
+
+# pre-evaluate arguments. jsDriver args have - preceding, xcode args do not.
+# special arguments
+# --root=<path to webkit root> use pre-built root
+# --gtk build gtk
+foreach my $arg(@ARGV) {
+ print $arg."\n";
+ if( $arg =~ /root=(.*)/ ){
+ $root = $1;
+ } elsif( $arg =~ /^--gtk$/i || $arg =~ /^--qt$/i || $arg =~ /^--wx$/i ){
+ } elsif( $arg =~ /^-/ or !($arg =~/=/)){
+ push( @jsArgs, $arg );
+ } else {
+ push( @xcodeArgs, $arg );
+ }
+}
+
+setConfigurationProductDir(Cwd::abs_path($root)) if (defined($root));
+
+if(!defined($root)){
+ chdirWebKit();
+ push(@xcodeArgs, "--" . $configuration);
+
+ # FIXME: These should be stored per-config and ignored here
+ push(@xcodeArgs, "--qt") if isQt();
+ push(@xcodeArgs, "--gtk") if isGtk();
+ push(@xcodeArgs, "--wx") if isWx();
+
+ my $buildResult = system "perl", "WebKitTools/Scripts/build-testkjs", @xcodeArgs;
+ if ($buildResult) {
+ print STDERR "Compiling testkjs failed!\n";
+ exit exitStatus($buildResult);
+ }
+}
+
+# Find JavaScriptCore directory
+chdirWebKit();
+chdir("JavaScriptCore");
+
+my $productDir = productDir();
+chdir "tests/mozilla" or die;
+
+$productDir .= "/JavaScriptCore" if (isQt() or isGtk());
+$ENV{DYLD_FRAMEWORK_PATH} = $productDir;
+setPathForRunningWebKitApp(\%ENV) if isCygwin();
+
+sub testKJSPath($)
+{
+ my ($productDir) = @_;
+ my $testkjsName = "testkjs";
+ $testkjsName .= "_debug" if (isCygwin() && ($configuration eq "Debug"));
+ return "$productDir/$testkjsName";
+}
+
+my $result = system "perl", "jsDriver.pl", "-e", "kjs", "-s", testKJSPath($productDir), "-f", "actual.html", @jsArgs;
+exit exitStatus($result) if $result;
+
+my %failures;
+
+open EXPECTED, "expected.html" or die;
+while (<EXPECTED>) {
+ last if /failures reported\.$/;
+}
+while (<EXPECTED>) {
+ chomp;
+ $failures{$_} = 1;
+}
+close EXPECTED;
+
+my %newFailures;
+
+open ACTUAL, "actual.html" or die;
+while (<ACTUAL>) {
+ last if /failures reported\.$/;
+}
+while (<ACTUAL>) {
+ chomp;
+ if ($failures{$_}) {
+ delete $failures{$_};
+ } else {
+ $newFailures{$_} = 1;
+ }
+}
+close ACTUAL;
+
+my $numNewFailures = keys %newFailures;
+if ($numNewFailures) {
+ print "\n** Danger, Will Robinson! Danger! The following failures have been introduced:\n";
+ foreach my $failure (sort keys %newFailures) {
+ print "\t$failure\n";
+ }
+}
+
+my $numOldFailures = keys %failures;
+if ($numOldFailures) {
+ print "\nYou fixed the following test";
+ print "s" if $numOldFailures != 1;
+ print ":\n";
+ foreach my $failure (sort keys %failures) {
+ print "\t$failure\n";
+ }
+}
+
+print "\n";
+
+print "$numNewFailures regression";
+print "s" if $numNewFailures != 1;
+print " found.\n";
+
+print "$numOldFailures test";
+print "s" if $numOldFailures != 1;
+print " fixed.\n";
+
+print "OK.\n" if $numNewFailures == 0;
+exit(1) if $numNewFailures;
diff --git a/WebKitTools/Scripts/run-launcher b/WebKitTools/Scripts/run-launcher
new file mode 100755
index 0000000..60f3c86
--- /dev/null
+++ b/WebKitTools/Scripts/run-launcher
@@ -0,0 +1,75 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2007 Apple Computer, Inc. All rights reserved.
+# Copyright (C) 2007 Staikos Computing Services, Inc. <info@staikos.net>
+#
+# 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.
+
+# Simplified "run" script for Web Kit Open Source Project.
+
+use strict;
+use File::Spec::Functions qw/catdir/;
+use File::Temp qw/tempfile/;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+
+setConfiguration();
+my $productDir = productDir();
+my $launcherPath = productDir();
+my @args = @ARGV;
+
+# Check to see that all the frameworks are built.
+checkFrameworks();
+
+# Set paths according to the build system used
+if (!$ENV{WEBKITAUTOTOOLS}) {
+ my $libDir = catdir(productDir(), 'lib');
+
+ if (isGtk()) {
+ $launcherPath = catdir($launcherPath, "WebKitTools", "GtkLauncher", "GtkLauncher");
+ # Strip --gtk from the arg-list, since otherwise GtkLauncher will try to
+ # interpret it as a URL.
+ @args = grep(!/^(--gtk)$/, @args);
+ } elsif (isQt()) {
+ $launcherPath = catdir($launcherPath, "bin", "QtLauncher");
+ }
+
+ # Set up LD_LIBRARY_PATH to point to the product directory.
+ print "Starting webkit launcher with LD_LIBRARY_PATH set to point to built WebKit in $libDir.\n";
+
+ $ENV{LD_LIBRARY_PATH} = $ENV{LD_LIBRARY_PATH} ? "$libDir:$ENV{LD_LIBRARY_PATH}" : $libDir;
+} else {
+
+ if (isGtk()) {
+ $launcherPath = catdir($launcherPath, "Programs", "GtkLauncher");
+ @args = grep(!/^(--gtk)$/, @args);
+ }
+
+ print "Starting webkit launcher.\n";
+}
+
+exec $launcherPath, @args or die;
+
diff --git a/WebKitTools/Scripts/run-leaks b/WebKitTools/Scripts/run-leaks
new file mode 100755
index 0000000..d8f89d3
--- /dev/null
+++ b/WebKitTools/Scripts/run-leaks
@@ -0,0 +1,212 @@
+#!/usr/bin/perl
+
+# 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.
+
+# Script to run the Mac OS X leaks tool with more expressive '-exclude' lists.
+
+use strict;
+use warnings;
+
+use File::Basename;
+use Getopt::Long;
+
+sub runLeaks($);
+sub parseLeaksOutput(\@);
+sub removeMatchingRecords(\@$\@);
+sub reportError($);
+
+sub main()
+{
+ # Read options.
+ my $usage =
+ "Usage: " . basename($0) . " [options] pid | executable name\n" .
+ " --exclude-callstack regexp Exclude leaks whose call stacks match the regular expression 'regexp'.\n" .
+ " --exclude-type regexp Exclude leaks whose data types match the regular expression 'regexp'.\n" .
+ " --help Show this help message.\n";
+
+ my @callStacksToExclude = ();
+ my @typesToExclude = ();
+ my $help = 0;
+
+ my $getOptionsResult = GetOptions(
+ 'exclude-callstack:s' => \@callStacksToExclude,
+ 'exclude-type:s' => \@typesToExclude,
+ 'help' => \$help
+ );
+ my $pidOrExecutableName = $ARGV[0];
+
+ if (!$getOptionsResult || $help) {
+ print STDERR $usage;
+ return 1;
+ }
+
+ if (!$pidOrExecutableName) {
+ reportError("Missing argument: pid | executable.");
+ print STDERR $usage;
+ return 1;
+ }
+
+ # Run leaks tool.
+ my $leaksOutput = runLeaks($pidOrExecutableName);
+ if (!$leaksOutput) {
+ return 1;
+ }
+
+ my $leakList = parseLeaksOutput(@$leaksOutput);
+ if (!$leakList) {
+ return 1;
+ }
+
+ # Filter output.
+ my $leakCount = @$leakList;
+ removeMatchingRecords(@$leakList, "callStack", @callStacksToExclude);
+ removeMatchingRecords(@$leakList, "type", @typesToExclude);
+ my $excludeCount = $leakCount - @$leakList;
+
+ # Dump results.
+ print $leaksOutput->[0];
+ print $leaksOutput->[1];
+ foreach my $leak (@$leakList) {
+ print $leak->{"leaksOutput"};
+ }
+
+ if ($excludeCount) {
+ print "$excludeCount leaks excluded (not printed)\n";
+ }
+
+ return 0;
+}
+
+exit(main());
+
+# Returns the output of the leaks tool in list form.
+sub runLeaks($)
+{
+ my ($pidOrExecutableName) = @_;
+
+ my @leaksOutput = `leaks $pidOrExecutableName`;
+ if (!@leaksOutput) {
+ reportError("Error running leaks tool.");
+ return;
+ }
+
+ return \@leaksOutput;
+}
+
+# Returns a list of hash references with the keys { address, size, type, callStack, leaksOutput }
+sub parseLeaksOutput(\@)
+{
+ my ($leaksOutput) = @_;
+
+ # Format:
+ # Process 00000: 1234 nodes malloced for 1234 KB
+ # Process 00000: XX leaks for XXX total leaked bytes.
+ # Leak: 0x00000000 size=1234 [instance of 'blah']
+ # 0x00000000 0x00000000 0x00000000 0x00000000 a..d.e.e
+ # ...
+ # Call stack: leak_caller() | leak() | malloc
+ #
+ # We treat every line except for Process 00000: and Leak: as optional
+
+ my ($leakCount) = ($leaksOutput->[1] =~ /[[:blank:]]+([0-9]+)[[:blank:]]+leaks?/);
+ if (!defined($leakCount)) {
+ reportError("Could not parse leak count reported by leaks tool.");
+ return;
+ }
+
+ my @leakList = ();
+ for my $line (@$leaksOutput) {
+ next if $line =~ /^Process/;
+ next if $line =~ /^node buffer added/;
+
+ if ($line =~ /^Leak: /) {
+ my ($address) = ($line =~ /Leak: ([[:xdigit:]x]+)/);
+ if (!defined($address)) {
+ reportError("Could not parse Leak address.");
+ return;
+ }
+
+ my ($size) = ($line =~ /size=([[:digit:]]+)/);
+ if (!defined($size)) {
+ reportError("Could not parse Leak size.");
+ return;
+ }
+
+ my ($type) = ($line =~ /'([^']+)'/); #'
+ if (!defined($type)) {
+ $type = ""; # The leaks tool sometimes omits the type.
+ }
+
+ my %leak = (
+ "address" => $address,
+ "size" => $size,
+ "type" => $type,
+ "callStack" => "", # The leaks tool sometimes omits the call stack.
+ "leaksOutput" => $line
+ );
+ push(@leakList, \%leak);
+ } else {
+ $leakList[$#leakList]->{"leaksOutput"} .= $line;
+ if ($line =~ /Call stack:/) {
+ $leakList[$#leakList]->{"callStack"} = $line;
+ }
+ }
+ }
+
+ if (@leakList != $leakCount) {
+ my $parsedLeakCount = @leakList;
+ reportError("Parsed leak count($parsedLeakCount) does not match leak count reported by leaks tool($leakCount).");
+ return;
+ }
+
+ return \@leakList;
+}
+
+sub removeMatchingRecords(\@$\@)
+{
+ my ($recordList, $key, $regexpList) = @_;
+
+ RECORD: for (my $i = 0; $i < @$recordList;) {
+ my $record = $recordList->[$i];
+
+ foreach my $regexp (@$regexpList) {
+ if ($record->{$key} =~ $regexp) {
+ splice(@$recordList, $i, 1);
+ next RECORD;
+ }
+ }
+
+ $i++;
+ }
+}
+
+sub reportError($)
+{
+ my ($errorMessage) = @_;
+
+ print STDERR basename($0) . ": $errorMessage\n";
+}
diff --git a/WebKitTools/Scripts/run-mangleme-tests b/WebKitTools/Scripts/run-mangleme-tests
new file mode 100755
index 0000000..78b5d14
--- /dev/null
+++ b/WebKitTools/Scripts/run-mangleme-tests
@@ -0,0 +1,173 @@
+#!/usr/bin/perl
+
+# Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.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.
+
+# A script to semi-automatically run mangleme tests.
+
+use strict;
+use warnings;
+
+use Cwd;
+use FindBin;
+use Getopt::Long;
+use IPC::Open2;
+
+use lib $FindBin::Bin;
+use webkitdirs;
+
+sub openHTTPDIfNeeded();
+sub closeHTTPD();
+sub runSafari();
+
+# Argument handling
+my $guardMalloc = '';
+my $httpdPort = 8000;
+my $downloadTest;
+
+GetOptions(
+ 'guard-malloc|g' => \$guardMalloc,
+ 'get=s' => \$downloadTest,
+ 'port=i' => \$httpdPort
+);
+
+
+setConfiguration();
+my $productDir = productDir();
+
+chdirWebKit();
+
+checkFrameworks();
+
+mkdir "WebKitBuild/mangleme";
+(system "/usr/bin/make", "-C", "WebKitTools/mangleme") == 0 or die;
+
+my $httpdOpen = 0;
+openHTTPDIfNeeded();
+
+if ($downloadTest) {
+ system "/usr/bin/curl -o ~/Desktop/mangleme$downloadTest.html http://127.0.0.1:$httpdPort/remangle.cgi?$downloadTest";
+ print "Saved the test as mangleme$downloadTest.html on the desktop\n";
+} else {
+ runSafari();
+ print "Last generated tests:\n";
+ system "grep 'Mangle attempt' /tmp/WebKit/error_log.txt | tail -n -5 | awk ' {print \$4}'";
+}
+
+closeHTTPD();
+
+
+sub runSafari()
+{
+ my $redirectTo;
+ if (@ARGV) {
+ $redirectTo = "http://127.0.0.1:$httpdPort/remangle.cgi?$ARGV[0]";
+ } else {
+ $redirectTo = "http://127.0.0.1:$httpdPort/mangle.cgi";
+ }
+
+ open REDIRECT_HTML, ">", "/tmp/WebKit/redirect.html" or die;
+ print REDIRECT_HTML "<html>\n";
+ print REDIRECT_HTML " <head>\n";
+ print REDIRECT_HTML " <meta http-equiv=\"refresh\" content=\"1;URL=$redirectTo\" />\n";
+ print REDIRECT_HTML " <script type=\"text/javascript\">\n";
+ print REDIRECT_HTML " document.location = \"$redirectTo\";\n";
+ print REDIRECT_HTML " </script>\n";
+ print REDIRECT_HTML " </head>\n";
+ print REDIRECT_HTML " <body>\n";
+ print REDIRECT_HTML " </body>\n";
+ print REDIRECT_HTML "</html>\n";
+ close REDIRECT_HTML;
+
+ local %ENV;
+ $ENV{DYLD_INSERT_LIBRARIES} = "/usr/lib/libgmalloc.dylib" if $guardMalloc;
+ system "WebKitTools/Scripts/run-safari", "-NSOpen", "/tmp/WebKit/redirect.html";
+}
+
+sub openHTTPDIfNeeded()
+{
+ return if $httpdOpen;
+
+ mkdir "/tmp/WebKit";
+
+ if (-f "/tmp/WebKit/httpd.pid") {
+ my $oldPid = `cat /tmp/WebKit/httpd.pid`;
+ chomp $oldPid;
+ if (0 != kill 0, $oldPid) {
+ print "\nhttpd is already running: pid $oldPid, killing...\n";
+ kill 15, $oldPid;
+
+ my $retryCount = 20;
+ while ((0 != kill 0, $oldPid) && $retryCount) {
+ sleep 1;
+ --$retryCount;
+ }
+
+ die "Timed out waiting for httpd to quit" unless $retryCount;
+ }
+ }
+
+ my $testDirectory = getcwd() . "/LayoutTests";
+ my $manglemeDirectory = getcwd() . "/WebKitBuild/mangleme";
+ my $httpdPath = "/usr/sbin/httpd";
+ my $httpdConfig = "$testDirectory/http/conf/httpd.conf";
+ $httpdConfig = "$testDirectory/http/conf/apache2-httpd.conf" if `$httpdPath -v` =~ m|Apache/2|;
+ my $documentRoot = "$manglemeDirectory";
+ my $typesConfig = "$testDirectory/http/conf/mime.types";
+ my $listen = "127.0.0.1:$httpdPort";
+
+ open2(\*HTTPDIN, \*HTTPDOUT, $httpdPath,
+ "-f", "$httpdConfig",
+ "-C", "DocumentRoot \"$documentRoot\"",
+ "-C", "Listen $listen",
+ "-c", "TypesConfig \"$typesConfig\"",
+ "-c", "CustomLog \"/tmp/WebKit/access_log.txt\" common",
+ "-c", "ErrorLog \"/tmp/WebKit/error_log.txt\"",
+ # Apache wouldn't run CGIs with permissions==700 otherwise
+ "-c", "User \"#$<\"");
+
+ my $retryCount = 20;
+ while (system("/usr/bin/curl -q --silent --stderr - --output /dev/null $listen") && $retryCount) {
+ sleep 1;
+ --$retryCount;
+ }
+
+ die "Timed out waiting for httpd to start" unless $retryCount;
+
+ $httpdOpen = 1;
+}
+
+sub closeHTTPD()
+{
+ return if !$httpdOpen;
+
+ close HTTPDIN;
+ close HTTPDOUT;
+
+ kill 15, `cat /tmp/WebKit/httpd.pid` if -f "/tmp/WebKit/httpd.pid";
+
+ $httpdOpen = 0;
+}
diff --git a/WebKitTools/Scripts/run-pageloadtest b/WebKitTools/Scripts/run-pageloadtest
new file mode 100755
index 0000000..ad6daa1
--- /dev/null
+++ b/WebKitTools/Scripts/run-pageloadtest
@@ -0,0 +1,92 @@
+#!/usr/bin/perl
+
+# Copyright (C) 2006 Eric Seidel (eric@webkit.org)
+#
+# 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.
+
+# Script to run the WebKit Open Source Project page load tests (PLTs).
+
+# Run all the tests passed in on the command line.
+
+use strict;
+use warnings;
+
+use File::Basename;
+use File::Spec;
+use FindBin;
+use Getopt::Long;
+
+use lib $FindBin::Bin;
+use webkitdirs;
+
+# Argument handling
+my $testName = 'svg';
+my $showHelp = 0;
+
+my $usage =
+ "Usage: " . basename($0) . "[options] testName\n" .
+ " --help Show this help message\n";
+
+my $getOptionsResult = GetOptions('help' => \$showHelp);
+
+if (!$getOptionsResult || $showHelp) {
+ print STDERR $usage;
+ exit 1;
+}
+
+$testName = shift @ARGV if (@ARGV);
+
+my $safariExecutablePath = safariPath();
+my $safariResourcePath = File::Spec->catdir(dirname(dirname($safariExecutablePath)), "Resources");
+
+# Check to see that all the frameworks are built.
+checkFrameworks();
+
+chdirWebKit();
+
+if ($testName eq 'svg') {
+ my $suiteFile = "PageLoadTests/$testName/$testName.pltsuite";
+ my $webkitPath = sourceDir();
+ `cat "$suiteFile" | perl -pe 's|WEBKIT_PATH|$webkitPath|' > $safariResourcePath/$testName.pltsuite`
+}
+
+die "Please copy ${testName}.pltsuite to ${safariResourcePath}/${testName}.pltsuite"
+ if (! -f "${safariResourcePath}/${testName}.pltsuite");
+
+setConfiguration();
+
+my $productDir = productDir();
+
+# Set up DYLD_FRAMEWORK_PATH to point to the product directory.
+print "Starting Safari with DYLD_FRAMEWORK_PATH set to point to built WebKit in $productDir.\n";
+$ENV{DYLD_FRAMEWORK_PATH} = $productDir;
+$ENV{WEBKIT_UNSET_DYLD_FRAMEWORK_PATH} = "YES";
+
+my @testCommands = ('activate');
+# Autovicki would clear history, we skip that here as this is likely an active user account
+@testCommands = (@testCommands, ("run $testName", 'emptyCache', 'wait 30'));
+@testCommands = (@testCommands, (("run $testName", 'wait 10') x 3));
+my $testCommandsString = join('; ', @testCommands);
+exec $safariExecutablePath, '--test-commands', $testCommandsString or die;
diff --git a/WebKitTools/Scripts/run-safari b/WebKitTools/Scripts/run-safari
new file mode 100755
index 0000000..4474b69
--- /dev/null
+++ b/WebKitTools/Scripts/run-safari
@@ -0,0 +1,41 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005, 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.
+
+# Simplified "run" script for Web Kit Open Source Project.
+
+use strict;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+
+setConfiguration();
+
+# Check to see that all the frameworks are built.
+checkFrameworks();
+
+exit exitStatus(runSafari());
diff --git a/WebKitTools/Scripts/run-sunspider b/WebKitTools/Scripts/run-sunspider
new file mode 100755
index 0000000..8dfeabb
--- /dev/null
+++ b/WebKitTools/Scripts/run-sunspider
@@ -0,0 +1,123 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2007 Apple Inc. All rights reserved.
+# Copyright (C) 2007 Eric Seidel <eric@webkit.org>
+#
+# 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.
+
+use strict;
+use FindBin;
+use Getopt::Long qw(:config pass_through);
+use lib $FindBin::Bin;
+use webkitdirs;
+use POSIX;
+
+# determine configuration, but default to "Release" instead of last-used configuration
+setConfiguration("Release");
+setConfiguration();
+my $configuration = configuration();
+
+my $root;
+my $testRuns = 10; # This number may be different from what sunspider defaults to (that's OK)
+my $runShark = 0;
+my $runShark20 = 0;
+my $runSharkCache = 0;
+my $setBaseline = 0;
+my $showHelp = 0;
+my $testsPattern;
+
+my $programName = basename($0);
+my $usage = <<EOF;
+Usage: $programName [options] [options to pass to build system]
+ --help Show this help message
+ --set-baseline Set baseline for future comparisons
+ --root Path to root tools build
+ --runs Number of times to run tests (default: $testRuns)
+ --tests Only run tests matching provided pattern
+ --shark Sample with the Mac OS X "Shark" performance testing tool (implies --runs=1)
+ --shark20 Like --shark, but with a 20 microsecond sampling interval
+ --shark-cache Like --shark, but performs a L2 cache-miss sample instead of time sample
+EOF
+
+GetOptions('root=s' => sub { my ($value) = @_; $root = $value; setConfigurationProductDir(Cwd::abs_path($root)); },
+ 'runs=i' => \$testRuns,
+ 'set-baseline' => \$setBaseline,
+ 'shark' => \$runShark,
+ 'shark20' => \$runShark20,
+ 'shark-cache' => \$runSharkCache,
+ 'tests=s' => \$testsPattern,
+ 'help' => \$showHelp);
+
+if ($showHelp) {
+ print STDERR $usage;
+ exit 1;
+}
+
+sub buildTestKJS
+{
+ if (!defined($root)){
+ push(@ARGV, "--" . $configuration);
+
+ chdirWebKit();
+ my $buildResult = system "WebKitTools/Scripts/build-testkjs", @ARGV;
+ if ($buildResult) {
+ print STDERR "Compiling testkjs failed!\n";
+ exit exitStatus($buildResult);
+ }
+ }
+}
+
+sub setupEnvironmentForExecution($)
+{
+ my ($productDir) = @_;
+ print "Starting sunspider with DYLD_FRAMEWORK_PATH set to point to built JavaScriptCore in $productDir.\n";
+ $ENV{DYLD_FRAMEWORK_PATH} = $productDir;
+ # FIXME: Other platforms may wish to augment this method to use LD_LIBRARY_PATH, etc.
+}
+
+sub testKJSPath($)
+{
+ my ($productDir) = @_;
+ my $testkjsName = "testkjs";
+ $testkjsName .= "_debug" if (isCygwin() && ($configuration eq "Debug"));
+ return "$productDir/$testkjsName";
+}
+
+buildTestKJS();
+
+chdirWebKit();
+chdir("SunSpider");
+
+my $productDir = productDir();
+# FIXME: This hack should be pushed down into productDir()
+$productDir .= "/JavaScriptCore" if (isQt() or isGtk());
+
+setupEnvironmentForExecution($productDir);
+my @args = ("--shell", testKJSPath($productDir), "--runs", $testRuns);
+# This code could be removed if we chose to pass extra args to sunspider instead of Xcode
+push @args, "--set-baseline" if $setBaseline;
+push @args, "--shark" if $runShark;
+push @args, "--shark20" if $runShark20;
+push @args, "--shark-cache" if $runSharkCache;
+push @args, "--tests", $testsPattern if $testsPattern;
+
+exec "./sunspider", @args;
diff --git a/WebKitTools/Scripts/run-testkjs b/WebKitTools/Scripts/run-testkjs
new file mode 100755
index 0000000..5610bad
--- /dev/null
+++ b/WebKitTools/Scripts/run-testkjs
@@ -0,0 +1,58 @@
+#!/usr/bin/perl
+
+# Copyright (C) 2006 Apple Computer, 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.
+
+# This script runs a list of scripts through testkjs a specified number of times.
+
+use strict;
+use warnings;
+use FindBin;
+use lib $FindBin::Bin;
+use Getopt::Long;
+use webkitdirs;
+
+my $usage = "Usage: run-testkjs [--count run_count] [--verbose] shell_file [file2...]";
+
+my $count = 1;
+my $verbose = 0;
+GetOptions("count|c=i" => \$count,
+ "verbose|v" => \$verbose);
+die "$usage\n" if (@ARGV < 1);
+
+my $testkjs = productDir() . "/testkjs @ARGV";
+$testkjs .= " 2> /dev/null" unless $verbose;
+
+my $dyld = productDir();
+
+$ENV{"DYLD_FRAMEWORK_PATH"} = $dyld;
+print STDERR "Running $count time(s): DYLD_FRAMEWORK_PATH=$dyld $testkjs\n";
+while ($count--) {
+ if (system("$testkjs") != 0) {
+ last;
+ }
+}
+
diff --git a/WebKitTools/Scripts/run-webkit-app b/WebKitTools/Scripts/run-webkit-app
new file mode 100755
index 0000000..36b9a58
--- /dev/null
+++ b/WebKitTools/Scripts/run-webkit-app
@@ -0,0 +1,50 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005 Apple Computer, 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.
+
+# Simplified "run" script for Web Kit Open Source Project.
+
+use strict;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+
+setConfiguration();
+my $productDir = productDir();
+
+die "Did not specify an application to open (e.g. run-webkit-app AppName).\n" unless length($ARGV[0]) > 0;
+
+# Check to see that all the frameworks are built.
+checkFrameworks();
+
+# Set up DYLD_FRAMEWORK_PATH to point to the product directory.
+print "Start $ARGV[0] with DYLD_FRAMEWORK_PATH set to point to built WebKit in $productDir.\n";
+$ENV{DYLD_FRAMEWORK_PATH} = $productDir;
+$ENV{WEBKIT_UNSET_DYLD_FRAMEWORK_PATH} = "YES";
+
+unshift(@ARGV, "-a");
+exec "open", @ARGV;
diff --git a/WebKitTools/Scripts/run-webkit-httpd b/WebKitTools/Scripts/run-webkit-httpd
new file mode 100755
index 0000000..a64eef6
--- /dev/null
+++ b/WebKitTools/Scripts/run-webkit-httpd
@@ -0,0 +1,127 @@
+#!/usr/bin/perl
+
+# Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
+# Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.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 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.
+
+# Script to run Apache with the same configuration as used in http layout tests.
+
+use strict;
+use warnings;
+
+use Cwd;
+use File::Basename;
+use Getopt::Long;
+use FindBin;
+
+use lib $FindBin::Bin;
+use webkitdirs;
+
+# Argument handling
+my $httpdPort = 8000;
+my $allInterfaces = 0;
+my $showHelp;
+
+my $result = GetOptions(
+ 'all-interfaces|a' => \$allInterfaces,
+ 'help|h' => \$showHelp,
+ 'port=i' => \$httpdPort,
+);
+
+if (!$result || @ARGV || $showHelp) {
+ print "Usage: " . basename($0) . " [options]\n";
+ print " -a|--all-interfaces Bind to all interfaces\n";
+ print " -h|--help Show this help message\n";
+ print " -p|--port NNNN Bind to port NNNN\n";
+ exit 1;
+}
+
+setConfiguration();
+my $productDir = productDir();
+chdirWebKit();
+
+mkdir "/tmp/WebKit";
+
+if (-f "/tmp/WebKit/httpd.pid") {
+ my $oldPid = `cat /tmp/WebKit/httpd.pid`;
+ chomp $oldPid;
+ if (0 != kill 0, $oldPid) {
+ print "\nhttpd is already running: pid $oldPid, killing...\n";
+ kill 15, $oldPid;
+
+ my $retryCount = 20;
+ while ((0 != kill 0, $oldPid) && $retryCount) {
+ sleep 1;
+ --$retryCount;
+ }
+
+ die "Timed out waiting for httpd to quit" unless $retryCount;
+ }
+}
+
+my $testDirectory = getcwd() . "/LayoutTests";
+my $httpdPath = "/usr/sbin/httpd";
+$httpdPath = "/usr/sbin/apache2" if isDebianBased();
+my $httpdConfig = "$testDirectory/http/conf/httpd.conf";
+$httpdConfig = "$testDirectory/http/conf/cygwin-httpd.conf" if isCygwin();
+$httpdConfig = "$testDirectory/http/conf/apache2-httpd.conf" if `$httpdPath -v` =~ m|Apache/2|;
+$httpdConfig = "$testDirectory/http/conf/apache2-debian-httpd.conf" if isDebianBased();
+my $documentRoot = "$testDirectory/http/tests";
+my $typesConfig = "$testDirectory/http/conf/mime.types";
+my $sslCertificate = "$testDirectory/http/conf/webkit-httpd.pem";
+
+my $listen = "127.0.0.1:$httpdPort";
+$listen = "$httpdPort" if ($allInterfaces);
+
+if ($allInterfaces) {
+ print "Starting httpd on port $httpdPort (all interfaces)...\n";
+} else {
+ print "Starting httpd on <http://$listen/>...\n";
+}
+print "Press Ctrl+C to stop it.\n\n";
+
+my @args = (
+ "-f", "$httpdConfig",
+ "-C", "DocumentRoot \"$documentRoot\"",
+ "-C", "Listen $listen",
+ "-c", "TypesConfig \"$typesConfig\"",
+ "-c", "CustomLog |/usr/bin/tee common",
+ "-c", "ErrorLog |/usr/bin/tee",
+ # Apache wouldn't run CGIs with permissions==700 otherwise.
+ "-c", "User \"#$<\"",
+ # Run in single-process mode, do not detach from the controlling terminal.
+ "-X",
+ # Disable Keep-Alive support. Makes testing in multiple browsers easier (no need to wait
+ # for another browser's connection to expire).
+ "-c", "KeepAlive 0"
+);
+
+# FIXME: Enable this on Windows once <rdar://problem/5345985> is fixed
+push(@args, "-c", "SSLCertificateFile \"$sslCertificate\"") unless isCygwin();
+
+system($httpdPath, @args);
+
+unlink "/tmp/WebKit/httpd.pid";
diff --git a/WebKitTools/Scripts/run-webkit-nightly.cmd b/WebKitTools/Scripts/run-webkit-nightly.cmd
new file mode 100755
index 0000000..93037ab
--- /dev/null
+++ b/WebKitTools/Scripts/run-webkit-nightly.cmd
@@ -0,0 +1,10 @@
+@echo off
+set script="%TMP%\run-webkit-nightly2.cmd"
+set vsvars="%VS80COMNTOOLS%\vsvars32.bat"
+if exist %vsvars% (
+ copy %vsvars% "%script%"
+) else (
+ del "%script%"
+)
+FindSafari.exe %1 /printSafariLauncher >> "%script%"
+call %script%
diff --git a/WebKitTools/Scripts/run-webkit-tests b/WebKitTools/Scripts/run-webkit-tests
new file mode 100755
index 0000000..3b6bbb3
--- /dev/null
+++ b/WebKitTools/Scripts/run-webkit-tests
@@ -0,0 +1,1627 @@
+#!/usr/bin/perl
+
+# Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
+# Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
+# Copyright (C) 2007 Matt Lilek (pewtermoose@gmail.com)
+# Copyright (C) 2007 Eric Seidel <eric@webkit.org>
+#
+# 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.
+
+# Script to run the Web Kit Open Source Project layout tests.
+
+# Run all the tests passed in on the command line.
+# If no tests are passed, find all the .html, .shtml, .xml, .xhtml, .pl, .php (and svg) files in the test directory.
+
+# Run each text.
+# Compare against the existing file xxx-expected.txt.
+# If there is a mismatch, generate xxx-actual.txt and xxx-diffs.txt.
+
+# At the end, report:
+# the number of tests that got the expected results
+# the number of tests that ran, but did not get the expected results
+# the number of tests that failed to run
+# the number of tests that were run but had no expected results to compare against
+
+use strict;
+use warnings;
+
+use Cwd;
+use File::Basename;
+use File::Copy;
+use File::Find;
+use File::Path;
+use File::Spec;
+use File::Spec::Functions;
+use FindBin;
+use Getopt::Long;
+use IPC::Open2;
+use IPC::Open3;
+use Time::HiRes qw(time);
+
+use List::Util 'shuffle';
+
+use lib $FindBin::Bin;
+use webkitdirs;
+use POSIX;
+
+sub openDumpTool();
+sub closeDumpTool();
+sub dumpToolDidCrash();
+sub closeHTTPD();
+sub countAndPrintLeaks($$$);
+sub fileNameWithNumber($$);
+sub numericcmp($$);
+sub openHTTPDIfNeeded();
+sub pathcmp($$);
+sub processIgnoreTests($);
+sub slowestcmp($$);
+sub splitpath($);
+sub stripExtension($);
+sub isTextOnlyTest($);
+sub expectedDirectoryForTest($;$;$);
+sub printFailureMessageForTest($$);
+sub toURL($);
+sub toWindowsPath($);
+sub closeCygpaths();
+sub validateSkippedArg($$;$);
+sub htmlForExpectedAndActualResults($);
+sub deleteExpectedAndActualResults($);
+sub recordActualResultsAndDiff($$);
+sub buildPlatformHierarchy();
+sub epiloguesAndPrologues($$);
+sub parseLeaksandPrintUniqueLeaks();
+
+# Argument handling
+my $addPlatformExceptions = 0;
+my $configuration = configuration();
+my $guardMalloc = '';
+my $httpdPort = 8000;
+my $httpdSSLPort = 8443;
+my $ignoreTests = '';
+my $launchSafari = 1;
+my $platform;
+my $pixelTests = '';
+my $quiet = '';
+my $repaintSweepHorizontally = '';
+my $repaintTests = '';
+my $report10Slowest = 0;
+my $resetResults = 0;
+my $shouldCheckLeaks = 0;
+my $showHelp = 0;
+my $testsPerDumpTool = 1000;
+my $testHTTP = 1;
+my $testMedia = 1;
+my $testResultsDirectory = "/tmp/layout-test-results";
+my $threaded = 0;
+my $threshold = 0;
+my $treatSkipped = "default";
+my $verbose = 0;
+my $useValgrind = 0;
+my $strictTesting = 0;
+my $generateNewResults = 1;
+my $stripEditingCallbacks = isCygwin();
+my $root;
+my $reverseTests = 0;
+my $randomizeTests = 0;
+my $mergeDepth;
+my @leaksFilenames;
+
+# Default to --no-http for Qt, Gtk and wx for now.
+$testHTTP = 0 if (isQt() || isGtk() || isWx());
+
+my $expectedTag = "expected";
+my $actualTag = "actual";
+my $diffsTag = "diffs";
+my $errorTag = "stderr";
+
+if (isTiger()) {
+ $platform = "mac-tiger";
+} elsif (isLeopard()) {
+ $platform = "mac-leopard";
+} elsif (isOSX()) {
+ $platform = "mac";
+} elsif (isQt()) {
+ $platform = "qt";
+} elsif (isGtk()) {
+ $platform = "gtk";
+} elsif (isCygwin()) {
+ $platform = "win";
+}
+
+if (!defined($platform)) {
+ print "WARNING: Your platform is not recognized. Any platform-specific results will be generated in platform/undefined.\n";
+ $platform = "undefined";
+}
+
+my $programName = basename($0);
+my $launchSafariDefault = $launchSafari ? "launch" : "do not launch";
+my $httpDefault = $testHTTP ? "run" : "do not run";
+
+# FIXME: "--strict" should be renamed to qt-mac-comparison, or something along those lines.
+my $usage = <<EOF;
+Usage: $programName [options] [testdir|testpath ...]
+ --add-platform-exceptions Put new results for non-platform-specific failing tests into the platform-specific results directory
+ -c|--configuration config Set DumpRenderTree build configuration
+ -g|--guard-malloc Enable malloc guard
+ --help Show this help message
+ -h|--horizontal-sweep Change repaint to sweep horizontally instead of vertically (implies --repaint-tests)
+ --[no-]http Run (or do not run) http tests (default: $httpDefault)
+ -i|--ignore-tests Comma-separated list of directories or tests to ignore
+ --[no-]launch-safari Launch (or do not launch) Safari to display test results (default: $launchSafariDefault)
+ -l|--leaks Enable leaks checking
+ --[no-]new-test-results Generate results for new tests
+ -p|--pixel-tests Enable pixel tests
+ --platform Override the detected platform to use for tests and results (default: $platform)
+ --port Web server port to use with http tests
+ -q|--quiet Less verbose output
+ -r|--repaint-tests Run repaint tests (implies --pixel-tests)
+ --reset-results Reset ALL results (including pixel tests if --pixel-tests is set)
+ -o|--results-directory Output results directory (default: $testResultsDirectory)
+ --random Run the tests in a random order
+ --reverse Run the tests in reverse alphabetical order
+ --root Path to root tools build
+ -1|--singly Isolate each test case run (implies --verbose)
+ --skipped=[default|ignore|only] Specifies how to treat the Skipped file
+ default: Tests/directories listed in the Skipped file are not tested
+ ignore: The Skipped file is ignored
+ only: Only those tests/directories listed in the Skipped file will be run
+ --slowest Report the 10 slowest tests
+ --strict Do a comparison with the output on Mac (Qt only)
+ --[no-]strip-editing-callbacks Remove editing callbacks from expected results
+ -t|--threaded Run a concurrent JavaScript thead with each test
+ --threshold t Ignore pixel value deviations less than or equal to t
+ --valgrind Run DumpRenderTree inside valgrind (Qt/Linux only)
+ -v|--verbose More verbose output (overrides --quiet)
+ -m|--merge-leak-depth arg Merges leak callStacks and prints the number of unique leaks beneath a callstack depth of arg. Defaults to 5.
+EOF
+
+my $getOptionsResult = GetOptions(
+ 'c|configuration=s' => \$configuration,
+ 'debug|devel' => sub { $configuration = "Debug" },
+ 'guard-malloc|g' => \$guardMalloc,
+ 'help' => \$showHelp,
+ 'horizontal-sweep|h' => \$repaintSweepHorizontally,
+ 'http!' => \$testHTTP,
+ 'ignore-tests|i=s' => \$ignoreTests,
+ 'launch-safari!' => \$launchSafari,
+ 'leaks|l' => \$shouldCheckLeaks,
+ 'pixel-tests|p' => \$pixelTests,
+ 'platform=s' => \$platform,
+ 'port=i' => \$httpdPort,
+ 'quiet|q' => \$quiet,
+ 'release|deploy' => sub { $configuration = "Release" },
+ 'repaint-tests|r' => \$repaintTests,
+ 'reset-results' => \$resetResults,
+ 'new-test-results!' => \$generateNewResults,
+ 'results-directory|o=s' => \$testResultsDirectory,
+ 'singly|1' => sub { $testsPerDumpTool = 1; },
+ 'nthly=i' => \$testsPerDumpTool,
+ 'skipped=s' => \&validateSkippedArg,
+ 'slowest' => \$report10Slowest,
+ 'threaded|t' => \$threaded,
+ 'threshold=i' => \$threshold,
+ 'verbose|v' => \$verbose,
+ 'valgrind' => \$useValgrind,
+ 'strict' => \$strictTesting,
+ 'strip-editing-callbacks!' => \$stripEditingCallbacks,
+ 'random' => \$randomizeTests,
+ 'reverse' => \$reverseTests,
+ 'root=s' => \$root,
+ 'add-platform-exceptions' => \$addPlatformExceptions,
+ 'merge-leak-depth|m:5' => \$mergeDepth,
+);
+
+if (!$getOptionsResult || $showHelp) {
+ print STDERR $usage;
+ exit 1;
+}
+
+my $ignoreSkipped = $treatSkipped eq "ignore";
+my $skippedOnly = $treatSkipped eq "only";
+
+!$skippedOnly || @ARGV == 0 or die "--skipped=only cannot be used when tests are specified on the command line.";
+
+setConfiguration($configuration);
+
+my $configurationOption = "--" . lc($configuration);
+
+$repaintTests = 1 if $repaintSweepHorizontally;
+
+$pixelTests = 1 if $repaintTests;
+$pixelTests = 1 if $threshold > 0;
+
+$verbose = 1 if $testsPerDumpTool == 1;
+
+if ($shouldCheckLeaks && $testsPerDumpTool > 1000) {
+ print STDERR "\nWARNING: Running more than 1000 tests at a time with MallocStackLogging enabled may cause a crash.\n\n";
+}
+
+# Stack logging does not play well with QuickTime on Tiger (rdar://problem/5537157)
+$testMedia = 0 if $shouldCheckLeaks && isTiger();
+
+setConfigurationProductDir(Cwd::abs_path($root)) if (defined($root));
+my $productDir = productDir();
+$productDir .= "/bin" if (isQt());
+
+if (isGtk()) {
+ if ($ENV{WEBKITAUTOTOOLS}) {
+ $productDir .= "/Programs";
+ } else {
+ $productDir .= "/WebKitTools/DumpRenderTree/gtk";
+ }
+}
+
+chdirWebKit();
+
+if(!defined($root)){
+ # Push the parameters to build-dumprendertree as an array
+ my @args;
+ push(@args, "--" . $configuration);
+ push(@args, "--qt") if isQt();
+ push(@args, "--gtk") if isGtk();
+
+ my $buildResult = system "WebKitTools/Scripts/build-dumprendertree", @args;
+ if ($buildResult) {
+ print STDERR "Compiling DumpRenderTree failed!\n";
+ exit exitStatus($buildResult);
+ }
+}
+
+my $dumpToolName = "DumpRenderTree";
+$dumpToolName .= "_debug" if isCygwin() && $configuration ne "Release";
+my $dumpTool = "$productDir/$dumpToolName";
+die "can't find executable $dumpToolName (looked in $productDir)\n" unless -x $dumpTool;
+
+my $imageDiffTool = "$productDir/ImageDiff";
+die "can't find executable $imageDiffTool (looked in $productDir)\n" if $pixelTests && !-x $imageDiffTool;
+
+checkFrameworks() unless isCygwin();
+
+my $layoutTestsName = "LayoutTests";
+my $testDirectory = File::Spec->rel2abs($layoutTestsName);
+my $expectedDirectory = $testDirectory;
+my $platformBaseDirectory = catdir($testDirectory, "platform");
+my $platformTestDirectory = catdir($platformBaseDirectory, $platform);
+my @platformHierarchy = buildPlatformHierarchy();
+
+$expectedDirectory = $ENV{"WebKitExpectedTestResultsDirectory"} if $ENV{"WebKitExpectedTestResultsDirectory"};
+
+my $testResults = catfile($testResultsDirectory, "results.html");
+
+print "Running tests from $testDirectory\n";
+
+my @tests = ();
+my %testType = ();
+
+system "ln", "-s", $testDirectory, "/tmp/LayoutTests" unless -x "/tmp/LayoutTests";
+
+my %ignoredFiles = ();
+my %ignoredDirectories = map { $_ => 1 } qw(platform);
+my %ignoredLocalDirectories = map { $_ => 1 } qw(.svn _svn resources);
+my %supportedFileExtensions = map { $_ => 1 } qw(html shtml xml xhtml pl php);
+if (checkWebCoreSVGSupport(0)) {
+ $supportedFileExtensions{'svg'} = 1;
+} elsif (isCygwin()) {
+ # FIXME: We should fix webkitdirs.pm:hasSVGSupport() to do the correct
+ # check for Windows instead of forcing this here.
+ $supportedFileExtensions{'svg'} = 1;
+} else {
+ $ignoredLocalDirectories{'svg'} = 1;
+}
+if (!$testHTTP) {
+ $ignoredDirectories{'http'} = 1;
+}
+
+if (!$testMedia) {
+ $ignoredDirectories{'media'} = 1;
+ $ignoredDirectories{'http/tests/media'} = 1;
+}
+
+if ($ignoreTests) {
+ processIgnoreTests($ignoreTests);
+}
+
+if (!$ignoreSkipped) {
+ foreach my $level (@platformHierarchy) {
+ if (open SKIPPED, "<", "$level/Skipped") {
+ if ($verbose && !$skippedOnly) {
+ my ($dir, $name) = splitpath($level);
+ print "Skipped tests in $name:\n";
+ }
+
+ while (<SKIPPED>) {
+ my $skipped = $_;
+ chomp $skipped;
+ $skipped =~ s/^[ \n\r]+//;
+ $skipped =~ s/[ \n\r]+$//;
+ if ($skipped && $skipped !~ /^#/) {
+ if ($skippedOnly) {
+ push(@ARGV, $skipped);
+ } else {
+ if ($verbose) {
+ print " $skipped\n";
+ }
+ processIgnoreTests($skipped);
+ }
+ }
+ }
+ close SKIPPED;
+ }
+ }
+}
+
+
+my $directoryFilter = sub {
+ return () if exists $ignoredLocalDirectories{basename($File::Find::dir)};
+ return () if exists $ignoredDirectories{File::Spec->abs2rel($File::Find::dir, $testDirectory)};
+ return @_;
+};
+
+my $fileFilter = sub {
+ my $filename = $_;
+ if ($filename =~ /\.([^.]+)$/) {
+ if (exists $supportedFileExtensions{$1}) {
+ my $path = File::Spec->abs2rel(catfile($File::Find::dir, $filename), $testDirectory);
+ push @tests, $path if !exists $ignoredFiles{$path};
+ }
+ }
+};
+
+for my $test (@ARGV) {
+ $test =~ s/^($layoutTestsName|$testDirectory)\///;
+ my $fullPath = catfile($testDirectory, $test);
+ if (file_name_is_absolute($test)) {
+ print "can't run test $test outside $testDirectory\n";
+ } elsif (-f $fullPath) {
+ my ($filename, $pathname, $fileExtension) = fileparse($test, qr{\.[^.]+$});
+ if (!exists $supportedFileExtensions{substr($fileExtension, 1)}) {
+ print "test $test does not have a supported extension\n";
+ } elsif ($testHTTP || $pathname !~ /^http\//) {
+ push @tests, $test;
+ }
+ } elsif (-d $fullPath) {
+ find({ preprocess => $directoryFilter, wanted => $fileFilter }, $fullPath);
+
+ for my $level (@platformHierarchy) {
+ my $platformPath = catfile($level, $test);
+ find({ preprocess => $directoryFilter, wanted => $fileFilter }, $platformPath) if (-d $platformPath);
+ }
+ } else {
+ print "test $test not found\n";
+ }
+}
+if (!scalar @ARGV) {
+ find({ preprocess => $directoryFilter, wanted => $fileFilter }, $testDirectory);
+
+ for my $level (@platformHierarchy) {
+ find({ preprocess => $directoryFilter, wanted => $fileFilter }, $level);
+ }
+}
+
+die "no tests to run\n" if !@tests;
+
+@tests = sort pathcmp @tests;
+
+my %counts;
+my %tests;
+my %imagesPresent;
+my %imageDifferences;
+my %durations;
+my $count = 0;
+my $leaksOutputFileNumber = 1;
+my $totalLeaks = 0;
+
+my @toolArgs = ();
+push @toolArgs, "--dump-all-pixels" if $pixelTests && $resetResults;
+push @toolArgs, "--pixel-tests" if $pixelTests;
+push @toolArgs, "--repaint" if $repaintTests;
+push @toolArgs, "--horizontal-sweep" if $repaintSweepHorizontally;
+push @toolArgs, "--threaded" if $threaded;
+push @toolArgs, "-";
+
+my @diffToolArgs = ();
+push @diffToolArgs, "--threshold", $threshold;
+
+$| = 1;
+
+my $imageDiffToolPID;
+if ($pixelTests) {
+ local %ENV;
+ $ENV{MallocStackLogging} = 1 if $shouldCheckLeaks;
+ $imageDiffToolPID = open2(\*DIFFIN, \*DIFFOUT, $imageDiffTool, @diffToolArgs) or die "unable to open $imageDiffTool\n";
+}
+
+my $dumpToolPID;
+my $isDumpToolOpen = 0;
+my $dumpToolCrashed = 0;
+
+my $atLineStart = 1;
+my $lastDirectory = "";
+
+my $isHttpdOpen = 0;
+
+sub catch_pipe { $dumpToolCrashed = 1; }
+$SIG{"PIPE"} = "catch_pipe";
+
+print "Testing ", scalar @tests, " test cases.\n";
+my $overallStartTime = time;
+
+my %expectedResultDirectory;
+
+# Reverse the tests
+@tests = reverse @tests if $reverseTests;
+
+# Shuffle the array
+@tests = shuffle(@tests) if $randomizeTests;
+
+for my $test (@tests) {
+ next if $test eq 'results.html';
+
+ my $newDumpTool = not $isDumpToolOpen;
+ openDumpTool();
+
+ my $base = stripExtension($test);
+
+ my $dir = $base;
+ $dir =~ s|/[^/]+$||;
+
+ if ($newDumpTool || $dir ne $lastDirectory) {
+ foreach my $logue (epiloguesAndPrologues($newDumpTool ? "" : $lastDirectory, $dir)) {
+ if (isCygwin()) {
+ $logue = toWindowsPath($logue);
+ } else {
+ $logue = canonpath($logue);
+ }
+ if ($verbose) {
+ print "running epilogue or prologue $logue\n";
+ }
+ print OUT "$logue\n";
+ # Discard the output.
+ while (<IN>) {
+ last if /#EOF/;
+ }
+ }
+ }
+
+ if ($verbose) {
+ print "running $test -> ";
+ $atLineStart = 0;
+ } elsif (!$quiet) {
+ if ($dir ne $lastDirectory) {
+ print "\n" unless $atLineStart;
+ print "$dir ";
+ }
+ print ".";
+ $atLineStart = 0;
+ }
+
+ $lastDirectory = $dir;
+
+ my $result;
+
+ my $startTime = time if $report10Slowest;
+
+ if ($test !~ /^http\//) {
+ my $testPath = "$testDirectory/$test";
+ if (isCygwin()) {
+ $testPath = toWindowsPath($testPath);
+ } else {
+ $testPath = canonpath($testPath);
+ }
+ print OUT "$testPath\n";
+ } else {
+ openHTTPDIfNeeded();
+ if ($test !~ /^http\/tests\/local\// && $test !~ /^http\/tests\/ssl\// && $test !~ /^http\/tests\/media\//) {
+ my $path = canonpath($test);
+ $path =~ s/^http\/tests\///;
+ print OUT "http://127.0.0.1:$httpdPort/$path\n";
+ } elsif ($test =~ /^http\/tests\/ssl\//) {
+ my $path = canonpath($test);
+ $path =~ s/^http\/tests\///;
+ print OUT "https://127.0.0.1:$httpdSSLPort/$path\n";
+ } else {
+ my $testPath = "$testDirectory/$test";
+ if (isCygwin()) {
+ $testPath = toWindowsPath($testPath);
+ } else {
+ $testPath = canonpath($testPath);
+ }
+ print OUT "$testPath\n";
+ }
+ }
+
+ my $actual = "";
+ while (<IN>) {
+ last if /#EOF/;
+ $actual .= $_;
+ }
+
+ my $isText = isTextOnlyTest($actual);
+
+ $durations{$test} = time - $startTime if $report10Slowest;
+
+ my $expected;
+ my $expectedDir = expectedDirectoryForTest($base, $isText, 0);
+ $expectedResultDirectory{$base} = $expectedDir;
+
+ if (!$resetResults && open EXPECTED, "<", "$expectedDir/$base-$expectedTag.txt") {
+ $expected = "";
+ while (<EXPECTED>) {
+ next if $stripEditingCallbacks && $_ =~ /^EDITING DELEGATE:/;
+ $expected .= $_;
+ }
+ close EXPECTED;
+ }
+ my $expectedMac;
+ if (!isOSX() && $strictTesting && !$isText) {
+ if (!$resetResults && open EXPECTED, "<", "$testDirectory/platform/mac/$base-$expectedTag.txt") {
+ $expectedMac = "";
+ while (<EXPECTED>) {
+ $expectedMac .= $_;
+ }
+ close EXPECTED;
+ }
+ }
+
+ if ($shouldCheckLeaks && $testsPerDumpTool == 1) {
+ print " $test -> ";
+ }
+
+ my $actualPNG = "";
+ my $diffPNG = "";
+ my $diffPercentage = "";
+ my $diffResult = "passed";
+
+ if ($pixelTests) {
+ my $expectedPixelDir = expectedDirectoryForTest($base, $isText, 1);
+
+ my $actualHash = "";
+ my $expectedHash = "";
+ my $actualPNGSize = 0;
+
+ while (<IN>) {
+ last if /#EOF/;
+ if (/ActualHash: ([a-f0-9]{32})/) {
+ $actualHash = $1;
+ } elsif (/BaselineHash: ([a-f0-9]{32})/) {
+ $expectedHash = $1;
+ } elsif (/Content-length: (\d+)\s*/) {
+ $actualPNGSize = $1;
+ read(IN, $actualPNG, $actualPNGSize);
+ }
+ }
+
+ if ($expectedHash ne $actualHash && -f "$expectedPixelDir/$base-$expectedTag.png") {
+ my $expectedPNGSize = -s "$expectedPixelDir/$base-$expectedTag.png";
+ my $expectedPNG = "";
+ open EXPECTEDPNG, "$expectedPixelDir/$base-$expectedTag.png";
+ read(EXPECTEDPNG, $expectedPNG, $expectedPNGSize);
+
+ print DIFFOUT "Content-length: $actualPNGSize\n";
+ print DIFFOUT $actualPNG;
+
+ print DIFFOUT "Content-length: $expectedPNGSize\n";
+ print DIFFOUT $expectedPNG;
+
+ while (<DIFFIN>) {
+ last if /^error/ || /^diff:/;
+ if (/Content-length: (\d+)\s*/) {
+ read(DIFFIN, $diffPNG, $1);
+ }
+ }
+
+ if (/^diff: (.+)% (passed|failed)/) {
+ $diffPercentage = $1;
+ $imageDifferences{$base} = $diffPercentage;
+ $diffResult = $2;
+ }
+ }
+
+ if ($actualPNGSize && ($resetResults || !-f "$expectedPixelDir/$base-$expectedTag.png")) {
+ mkpath catfile($expectedPixelDir, dirname($base)) if $testDirectory ne $expectedPixelDir;
+ open EXPECTED, ">", "$expectedPixelDir/$base-expected.png" or die "could not create $expectedPixelDir/$base-expected.png\n";
+ print EXPECTED $actualPNG;
+ close EXPECTED;
+ }
+
+ # update the expected hash if the image diff said that there was no difference
+ if ($actualHash ne "" && ($resetResults || !-f "$expectedPixelDir/$base-$expectedTag.checksum")) {
+ open EXPECTED, ">", "$expectedPixelDir/$base-$expectedTag.checksum" or die "could not create $expectedPixelDir/$base-$expectedTag.checksum\n";
+ print EXPECTED $actualHash;
+ close EXPECTED;
+ }
+ }
+
+ if (!isOSX() && $strictTesting && !$isText) {
+ if (defined $expectedMac) {
+ my $simplified_actual;
+ $simplified_actual = $actual;
+ $simplified_actual =~ s/at \(-?[0-9]+,-?[0-9]+\) *//g;
+ $simplified_actual =~ s/size -?[0-9]+x-?[0-9]+ *//g;
+ $simplified_actual =~ s/text run width -?[0-9]+: //g;
+ $simplified_actual =~ s/text run width -?[0-9]+ [a-zA-Z ]+: //g;
+ $simplified_actual =~ s/RenderButton {BUTTON} .*/RenderButton {BUTTON}/g;
+ $simplified_actual =~ s/RenderImage {INPUT} .*/RenderImage {INPUT}/g;
+ $simplified_actual =~ s/RenderBlock {INPUT} .*/RenderBlock {INPUT}/g;
+ $simplified_actual =~ s/RenderTextControl {INPUT} .*/RenderTextControl {INPUT}/g;
+ $simplified_actual =~ s/\([0-9]+px/px/g;
+ $simplified_actual =~ s/ *" *\n +" */ /g;
+ $simplified_actual =~ s/" +$/"/g;
+
+ $simplified_actual =~ s/- /-/g;
+ $simplified_actual =~ s/\n( *)"\s+/\n$1"/g;
+ $simplified_actual =~ s/\s+"\n/"\n/g;
+
+ $expectedMac =~ s/at \(-?[0-9]+,-?[0-9]+\) *//g;
+ $expectedMac =~ s/size -?[0-9]+x-?[0-9]+ *//g;
+ $expectedMac =~ s/text run width -?[0-9]+: //g;
+ $expectedMac =~ s/text run width -?[0-9]+ [a-zA-Z ]+: //g;
+ $expectedMac =~ s/RenderButton {BUTTON} .*/RenderButton {BUTTON}/g;
+ $expectedMac =~ s/RenderImage {INPUT} .*/RenderImage {INPUT}/g;
+ $expectedMac =~ s/RenderBlock {INPUT} .*/RenderBlock {INPUT}/g;
+ $expectedMac =~ s/RenderTextControl {INPUT} .*/RenderTextControl {INPUT}/g;
+ $expectedMac =~ s/\([0-9]+px/px/g;
+ $expectedMac =~ s/ *" *\n +" */ /g;
+ $expectedMac =~ s/" +$/"/g;
+
+ $expectedMac =~ s/- /-/g;
+ $expectedMac =~ s/\n( *)"\s+/\n$1"/g;
+ $expectedMac =~ s/\s+"\n/"\n/g;
+
+ if ($simplified_actual ne $expectedMac) {
+ open ACTUAL, ">", "/tmp/actual.txt" or die;
+ print ACTUAL $simplified_actual;
+ close ACTUAL;
+ open ACTUAL, ">", "/tmp/expected.txt" or die;
+ print ACTUAL $expectedMac;
+ close ACTUAL;
+ system "diff -u \"/tmp/expected.txt\" \"/tmp/actual.txt\" > \"/tmp/simplified.diff\"";
+
+ $diffResult = "failed";
+ if($verbose) {
+ print "\n";
+ system "cat /tmp/simplified.diff";
+ print "failed!!!!!";
+ }
+ }
+ }
+ }
+
+ if (dumpToolDidCrash()) {
+ $result = "crash";
+
+ printFailureMessageForTest($test, "crashed");
+
+ my $dir = "$testResultsDirectory/$base";
+ $dir =~ s|/([^/]+)$|| or die "Failed to find test name from base\n";
+ mkpath $dir;
+
+ deleteExpectedAndActualResults($base);
+
+ open CRASH, ">", "$testResultsDirectory/$base-$errorTag.txt" or die;
+ print CRASH <ERROR>;
+ close CRASH;
+
+ recordActualResultsAndDiff($base, $actual);
+
+ closeDumpTool();
+ } elsif (!defined $expected) {
+ if ($verbose) {
+ print "new " . ($resetResults ? "result" : "test") ."\n";
+ $atLineStart = 1;
+ }
+ $result = "new";
+
+ if ($generateNewResults || $resetResults) {
+ mkpath catfile($expectedDir, dirname($base)) if $testDirectory ne $expectedDir;
+ open EXPECTED, ">", "$expectedDir/$base-$expectedTag.txt" or die "could not create $expectedDir/$base-$expectedTag.txt\n";
+ print EXPECTED $actual;
+ close EXPECTED;
+ }
+ deleteExpectedAndActualResults($base);
+ unless ($resetResults) {
+ # Always print the file name for new tests, as they will probably need some manual inspection.
+ # in verbose mode we already printed the test case, so no need to do it again.
+ unless ($verbose) {
+ print "\n" unless $atLineStart;
+ print "$test -> ";
+ }
+ my $resultsDir = catdir($expectedDir, dirname($base));
+ print "new (results generated in $resultsDir)\n";
+ $atLineStart = 1;
+ }
+ } elsif ($actual eq $expected && $diffResult eq "passed") {
+ if ($verbose) {
+ print "succeeded\n";
+ $atLineStart = 1;
+ }
+ $result = "match";
+ deleteExpectedAndActualResults($base);
+ } else {
+ $result = "mismatch";
+
+ my $message = $actual eq $expected ? "pixel test failed" : "failed";
+
+ if ($actual ne $expected && $addPlatformExceptions) {
+ my $testBase = catfile($testDirectory, $base);
+ my $expectedBase = catfile($expectedDir, $base);
+ my $testIsMaximallyPlatformSpecific = $testBase =~ m|^\Q$platformTestDirectory\E/|;
+ my $expectedResultIsMaximallyPlatformSpecific = $expectedBase =~ m|^\Q$platformTestDirectory\E/|;
+ if (!$testIsMaximallyPlatformSpecific && !$expectedResultIsMaximallyPlatformSpecific) {
+ mkpath catfile($platformTestDirectory, dirname($base));
+ my $expectedFile = catfile($platformTestDirectory, "$base-$expectedTag.txt");
+ open EXPECTED, ">", $expectedFile or die "could not create $expectedFile\n";
+ print EXPECTED $actual;
+ close EXPECTED;
+ $message .= " (results generated in $platformTestDirectory)";
+ }
+ }
+
+ printFailureMessageForTest($test, $message);
+
+ my $dir = "$testResultsDirectory/$base";
+ $dir =~ s|/([^/]+)$|| or die "Failed to find test name from base\n";
+ my $testName = $1;
+ mkpath $dir;
+
+ deleteExpectedAndActualResults($base);
+ recordActualResultsAndDiff($base, $actual);
+
+ if ($pixelTests && $diffPNG && $diffPNG ne "") {
+ $imagesPresent{$base} = 1;
+
+ open ACTUAL, ">", "$testResultsDirectory/$base-$actualTag.png" or die;
+ print ACTUAL $actualPNG;
+ close ACTUAL;
+
+ open DIFF, ">", "$testResultsDirectory/$base-$diffsTag.png" or die;
+ print DIFF $diffPNG;
+ close DIFF;
+
+ copy("$expectedDir/$base-$expectedTag.png", "$testResultsDirectory/$base-$expectedTag.png");
+
+ open DIFFHTML, ">$testResultsDirectory/$base-$diffsTag.html" or die;
+ print DIFFHTML "<html>\n";
+ print DIFFHTML "<head>\n";
+ print DIFFHTML "<title>$base Image Compare</title>\n";
+ print DIFFHTML "<script language=\"Javascript\" type=\"text/javascript\">\n";
+ print DIFFHTML "var currentImage = 0;\n";
+ print DIFFHTML "var imageNames = new Array(\"Actual\", \"Expected\");\n";
+ print DIFFHTML "var imagePaths = new Array(\"$testName-$actualTag.png\", \"$testName-$expectedTag.png\");\n";
+ if (-f "$testDirectory/$base-w3c.png") {
+ copy("$testDirectory/$base-w3c.png", "$testResultsDirectory/$base-w3c.png");
+ print DIFFHTML "imageNames.push(\"W3C\");\n";
+ print DIFFHTML "imagePaths.push(\"$testName-w3c.png\");\n";
+ }
+ print DIFFHTML "function animateImage() {\n";
+ print DIFFHTML " var image = document.getElementById(\"animatedImage\");\n";
+ print DIFFHTML " var imageText = document.getElementById(\"imageText\");\n";
+ print DIFFHTML " image.src = imagePaths[currentImage];\n";
+ print DIFFHTML " imageText.innerHTML = imageNames[currentImage] + \" Image\";\n";
+ print DIFFHTML " currentImage = (currentImage + 1) % imageNames.length;\n";
+ print DIFFHTML " setTimeout('animateImage()',2000);\n";
+ print DIFFHTML "}\n";
+ print DIFFHTML "</script>\n";
+ print DIFFHTML "</head>\n";
+ print DIFFHTML "<body onLoad=\"animateImage();\">\n";
+ print DIFFHTML "<table>\n";
+ if ($diffPercentage) {
+ print DIFFHTML "<tr>\n";
+ print DIFFHTML "<td>Difference between images: <a href=\"$testName-$diffsTag.png\">$diffPercentage%</a></td>\n";
+ print DIFFHTML "</tr>\n";
+ }
+ print DIFFHTML "<tr>\n";
+ print DIFFHTML "<td><a href=\"" . toURL("$testDirectory/$test") . "\">test file</a></td>\n";
+ print DIFFHTML "</tr>\n";
+ print DIFFHTML "<tr>\n";
+ print DIFFHTML "<td id=\"imageText\" style=\"text-weight: bold;\">Actual Image</td>\n";
+ print DIFFHTML "</tr>\n";
+ print DIFFHTML "<tr>\n";
+ print DIFFHTML "<td><img src=\"$testName-$actualTag.png\" id=\"animatedImage\"></td>\n";
+ print DIFFHTML "</tr>\n";
+ print DIFFHTML "</table>\n";
+ print DIFFHTML "</body>\n";
+ print DIFFHTML "</html>\n";
+ }
+ }
+
+ if (($count + 1) % $testsPerDumpTool == 0 || $count == $#tests) {
+ if ($shouldCheckLeaks) {
+ my $fileName;
+ if ($testsPerDumpTool == 1) {
+ $fileName = "$testResultsDirectory/$base-leaks.txt";
+ } else {
+ $fileName = "$testResultsDirectory/" . fileNameWithNumber($dumpToolName, $leaksOutputFileNumber) . "-leaks.txt";
+ }
+ my $leakCount = countAndPrintLeaks($dumpToolName, $dumpToolPID, $fileName);
+ $totalLeaks += $leakCount;
+ $leaksOutputFileNumber++ if ($leakCount);
+ }
+
+ closeDumpTool();
+ }
+
+ $count++;
+ $counts{$result}++;
+ push @{$tests{$result}}, $test;
+ $testType{$test} = $isText;
+}
+printf "\n%0.2fs total testing time\n", (time - $overallStartTime) . "";
+
+!$isDumpToolOpen || die "Failed to close $dumpToolName.\n";
+
+closeHTTPD();
+
+# Because multiple instances of this script are running concurrently we cannot
+# safely delete this symlink.
+# system "rm /tmp/LayoutTests";
+
+# FIXME: Do we really want to check the image-comparison tool for leaks every time?
+if ($shouldCheckLeaks && $pixelTests) {
+ $totalLeaks += countAndPrintLeaks("ImageDiff", $imageDiffToolPID, "$testResultsDirectory/ImageDiff-leaks.txt");
+}
+
+if ($totalLeaks) {
+ if ($mergeDepth) {
+ parseLeaksandPrintUniqueLeaks();
+ }
+ else {
+ print "\nWARNING: $totalLeaks total leaks found!\n";
+ print "See above for individual leaks results.\n" if ($leaksOutputFileNumber > 2);
+ }
+}
+
+close IN;
+close OUT;
+close ERROR;
+
+if ($report10Slowest) {
+ print "\n\nThe 10 slowest tests:\n\n";
+ my $count = 0;
+ for my $test (sort slowestcmp keys %durations) {
+ printf "%0.2f secs: %s\n", $durations{$test}, $test;
+ last if ++$count == 10;
+ }
+}
+
+print "\n";
+
+if ($skippedOnly && $counts{"match"}) {
+ print "The following tests are in the Skipped file (" . File::Spec->abs2rel("$platformTestDirectory/Skipped", $testDirectory) . "), but succeeded:\n";
+ foreach my $test (@{$tests{"match"}}) {
+ print " $test\n";
+ }
+}
+
+if ($resetResults || ($counts{match} && $counts{match} == $count)) {
+ print "all $count test cases succeeded\n";
+ unlink $testResults;
+ exit;
+}
+
+
+my %text = (
+ match => "succeeded",
+ mismatch => "had incorrect layout",
+ new => "were new",
+ crash => "crashed",
+);
+
+for my $type ("match", "mismatch", "new", "crash") {
+ my $c = $counts{$type};
+ if ($c) {
+ my $t = $text{$type};
+ my $message;
+ if ($c == 1) {
+ $t =~ s/were/was/;
+ $message = sprintf "1 test case (%d%%) %s\n", 1 * 100 / $count, $t;
+ } else {
+ $message = sprintf "%d test cases (%d%%) %s\n", $c, $c * 100 / $count, $t;
+ }
+ $message =~ s-\(0%\)-(<1%)-;
+ print $message;
+ }
+}
+
+mkpath $testResultsDirectory;
+
+open HTML, ">", $testResults or die;
+print HTML "<html>\n";
+print HTML "<head>\n";
+print HTML "<title>Layout Test Results</title>\n";
+print HTML "</head>\n";
+print HTML "<body>\n";
+
+if ($counts{mismatch}) {
+ print HTML "<p>Tests where results did not match expected results:</p>\n";
+ print HTML "<table>\n";
+ for my $test (@{$tests{mismatch}}) {
+ my $base = stripExtension($test);
+ print HTML "<tr>\n";
+ print HTML "<td><a href=\"" . toURL("$testDirectory/$test") . "\">$test</a></td>\n";
+ print HTML htmlForExpectedAndActualResults($base);
+ if ($pixelTests) {
+ if ($imagesPresent{$base}) {
+ print HTML "<td><a href=\"$base-$expectedTag.png\">expected image</a></td>\n";
+ print HTML "<td><a href=\"$base-$diffsTag.html\">image diffs</a>\n";
+ print HTML "<a href=\"$base-$diffsTag.png\">$imageDifferences{$base}%</a></td>\n";
+ } else {
+ print HTML "<td></td><td></td>\n";
+ }
+ }
+ print HTML "</tr>\n";
+ }
+ print HTML "</table>\n";
+}
+
+if ($counts{crash}) {
+ print HTML "<p>Tests that caused the DumpRenderTree tool to crash:</p>\n";
+ print HTML "<table>\n";
+ for my $test (@{$tests{crash}}) {
+ my $base = stripExtension($test);
+ my $expectedDir = $expectedResultDirectory{$base};
+ print HTML "<tr>\n";
+ print HTML "<td><a href=\"" . toURL("$testDirectory/$test") . "\">$base</a></td>\n";
+ print HTML htmlForExpectedAndActualResults($base);
+ print HTML "<td><a href=\"$base-$errorTag.txt\">stderr</a></td>\n";
+ print HTML "</tr>\n";
+ }
+ print HTML "</table>\n";
+}
+
+if ($counts{new}) {
+ print HTML "<p>Tests that had no expected results (probably new):</p>\n";
+ print HTML "<table>\n";
+ for my $test (@{$tests{new}}) {
+ my $base = stripExtension($test);
+ my $expectedDir = $expectedResultDirectory{$base};
+ print HTML "<tr>\n";
+ print HTML "<td><a href=\"" . toURL("$testDirectory/$test") . "\">$base</a></td>\n";
+ print HTML "<td><a href=\"" . toURL("$expectedDir/$base-$expectedTag.txt") . "\">results</a></td>\n";
+ if ($pixelTests && -f "$expectedDir/$base-$expectedTag.png") {
+ print HTML "<td><a href=\"" . toURL("$expectedDir/$base-$expectedTag.png") . "\">image</a></td>\n";
+ }
+ print HTML "</tr>\n";
+ }
+ print HTML "</table>\n";
+}
+
+print HTML "</body>\n";
+print HTML "</html>\n";
+close HTML;
+
+if (isQt()) {
+ system "konqueror", $testResults if $launchSafari;
+} elsif (isGtk()) {
+ system "WebKitTools/Scripts/run-launcher", "--gtk", $configurationOption, $testResults if $launchSafari;
+} elsif (isCygwin()) {
+ system "cygstart", $testResults if $launchSafari;
+} else {
+ system "WebKitTools/Scripts/run-safari", $configurationOption, "-NSOpen", $testResults if $launchSafari;
+}
+
+closeCygpaths() if isCygwin();
+
+exit 1;
+
+sub countAndPrintLeaks($$$)
+{
+ my ($dumpToolName, $dumpToolPID, $leaksFilePath) = @_;
+
+ print "\n" unless $atLineStart;
+ $atLineStart = 1;
+
+ # We are excluding the following reported leaks so they don't get in our way when looking for WebKit leaks:
+ # This allows us ignore known leaks and only be alerted when new leaks occur. Some leaks are in the old
+ # versions of the system frameworks that are being used by the leaks bots. Even though a leak has been
+ # fixed, it will be listed here until the bot has been updated with the newer frameworks.
+
+ my @typesToExclude = (
+ );
+
+ my @callStacksToExclude = (
+ "Flash_EnforceLocalSecurity" # leaks in Flash plug-in code, rdar://problem/4449747
+ );
+
+ if (isTiger()) {
+ # Leak list for the version of Tiger used on the build bot.
+ push @callStacksToExclude, (
+ "CFRunLoopRunSpecific \\| malloc_zone_malloc", "CFRunLoopRunSpecific \\| CFAllocatorAllocate ", # leak in CFRunLoopRunSpecific, rdar://problem/4670839
+ "CGImageSourceGetPropertiesAtIndex", # leak in ImageIO, rdar://problem/4628809
+ "FOGetCoveredUnicodeChars", # leak in ATS, rdar://problem/3943604
+ "GetLineDirectionPreference", "InitUnicodeUtilities", # leaks tool falsely reporting leak in CFNotificationCenterAddObserver, rdar://problem/4964790
+ "ICCFPrefWrapper::GetPrefDictionary", # leaks in Internet Config. code, rdar://problem/4449794
+ "NSHTTPURLProtocol setResponseHeader:", # leak in multipart/mixed-replace handling in Foundation, no Radar, but fixed in Leopard
+ "NSURLCache cachedResponseForRequest", # leak in CFURL cache, rdar://problem/4768430
+ "PCFragPrepareClosureFromFile", # leak in Code Fragment Manager, rdar://problem/3426998
+ "WebCore::Selection::toRange", # bug in 'leaks', rdar://problem/4967949
+ "WebCore::SubresourceLoader::create", # bug in 'leaks', rdar://problem/4985806
+ "_CFPreferencesDomainDeepCopyDictionary", # leak in CFPreferences, rdar://problem/4220786
+ "_objc_msgForward", # leak in NSSpellChecker, rdar://problem/4965278
+ "gldGetString", # leak in OpenGL, rdar://problem/5013699
+ "_setDefaultUserInfoFromURL", # leak in NSHTTPAuthenticator, rdar://problem/5546453
+ "SSLHandshake", # leak in SSL, rdar://problem/5546440
+ "SecCertificateCreateFromData", # leak in SSL code, rdar://problem/4464397
+ );
+ push @typesToExclude, (
+ "THRD", # bug in 'leaks', rdar://problem/3387783
+ "DRHT", # ditto (endian little hate i)
+ );
+ }
+
+ if (isLeopard()) {
+ # Leak list for the version of Leopard used on the build bot.
+ push @callStacksToExclude, (
+ "CFHTTPMessageAppendBytes", # leak in CFNetwork, rdar://problem/5435912
+ "sendDidReceiveDataCallback", # leak in CFNetwork, rdar://problem/5441619
+ "_CFHTTPReadStreamReadMark", # leak in CFNetwork, rdar://problem/5441468
+ "httpProtocolStart", # leak in CFNetwork, rdar://problem/5468837
+ "_CFURLConnectionSendCallbacks", # leak in CFNetwork, rdar://problem/5441600
+ "DispatchQTMsg", # leak in Quicktime, PPC only, <rdar://problem/5667132>
+ "QTMovieContentView createVisualContext", # leak in Quicktime, PPC only, <rdar://problem/5667132>
+ );
+ }
+
+ my $leaksTool = sourceDir() . "/WebKitTools/Scripts/run-leaks";
+ my $excludeString = "--exclude-callstack '" . (join "' --exclude-callstack '", @callStacksToExclude) . "'";
+ $excludeString .= " --exclude-type '" . (join "' --exclude-type '", @typesToExclude) . "'" if @typesToExclude;
+
+ print " ? checking for leaks in $dumpToolName\n";
+ my $leaksOutput = `$leaksTool $excludeString $dumpToolPID`;
+ my ($count, $bytes) = $leaksOutput =~ /Process $dumpToolPID: (\d+) leaks? for (\d+) total/;
+ my ($excluded) = $leaksOutput =~ /(\d+) leaks? excluded/;
+
+ my $adjustedCount = $count;
+ $adjustedCount -= $excluded if $excluded;
+
+ if (!$adjustedCount) {
+ print " - no leaks found\n";
+ unlink $leaksFilePath;
+ return 0;
+ } else {
+ my $dir = $leaksFilePath;
+ $dir =~ s|/[^/]+$|| or die;
+ mkpath $dir;
+
+ if ($excluded) {
+ print " + $adjustedCount leaks ($bytes bytes including $excluded excluded leaks) were found, details in $leaksFilePath\n";
+ } else {
+ print " + $count leaks ($bytes bytes) were found, details in $leaksFilePath\n";
+ }
+
+ open LEAKS, ">", $leaksFilePath or die;
+ print LEAKS $leaksOutput;
+ close LEAKS;
+
+ push( @leaksFilenames, $leaksFilePath );
+ }
+
+ return $adjustedCount;
+}
+
+# Break up a path into the directory (with slash) and base name.
+sub splitpath($)
+{
+ my ($path) = @_;
+
+ my $pathSeparator = "/";
+ my $dirname = dirname($path) . $pathSeparator;
+ $dirname = "" if $dirname eq "." . $pathSeparator;
+
+ return ($dirname, basename($path));
+}
+
+# Sort first by directory, then by file, so all paths in one directory are grouped
+# rather than being interspersed with items from subdirectories.
+# Use numericcmp to sort directory and filenames to make order logical.
+sub pathcmp($$)
+{
+ my ($patha, $pathb) = @_;
+
+ my ($dira, $namea) = splitpath($patha);
+ my ($dirb, $nameb) = splitpath($pathb);
+
+ return numericcmp($dira, $dirb) if $dira ne $dirb;
+ return numericcmp($namea, $nameb);
+}
+
+# Sort numeric parts of strings as numbers, other parts as strings.
+# Makes 1.33 come after 1.3, which is cool.
+sub numericcmp($$)
+{
+ my ($aa, $bb) = @_;
+
+ my @a = split /(\d+)/, $aa;
+ my @b = split /(\d+)/, $bb;
+
+ # Compare one chunk at a time.
+ # Each chunk is either all numeric digits, or all not numeric digits.
+ while (@a && @b) {
+ my $a = shift @a;
+ my $b = shift @b;
+
+ # Use numeric comparison if chunks are non-equal numbers.
+ return $a <=> $b if $a =~ /^\d/ && $b =~ /^\d/ && $a != $b;
+
+ # Use string comparison if chunks are any other kind of non-equal string.
+ return $a cmp $b if $a ne $b;
+ }
+
+ # One of the two is now empty; compare lengths for result in this case.
+ return @a <=> @b;
+}
+
+# Sort slowest tests first.
+sub slowestcmp($$)
+{
+ my ($testa, $testb) = @_;
+
+ my $dura = $durations{$testa};
+ my $durb = $durations{$testb};
+ return $durb <=> $dura if $dura != $durb;
+ return pathcmp($testa, $testb);
+}
+
+sub openDumpTool()
+{
+ return if $isDumpToolOpen;
+
+ # Save some requires variables for the linux environment...
+ my $homeDir = $ENV{'HOME'};
+ my $libraryPath = $ENV{'LD_LIBRARY_PATH'};
+ my $dyldLibraryPath = $ENV{'DYLD_LIBRARY_PATH'};
+ my $dbusAddress = $ENV{'DBUS_SESSION_BUS_ADDRESS'};
+ my $display = $ENV{'DISPLAY'};
+ my $testfonts = $ENV{'WEBKIT_TESTFONTS'};
+
+ my $homeDrive = $ENV{'HOMEDRIVE'};
+ my $homePath = $ENV{'HOMEPATH'};
+
+ local %ENV;
+ if (isQt() || isGtk()) {
+ if (defined $display) {
+ $ENV{DISPLAY} = $display;
+ } else {
+ $ENV{DISPLAY} = ":1";
+ }
+ $ENV{'WEBKIT_TESTFONTS'} = $testfonts if defined($testfonts);
+ $ENV{HOME} = $homeDir;
+ if (defined $libraryPath) {
+ $ENV{LD_LIBRARY_PATH} = $libraryPath;
+ }
+ if (defined $dyldLibraryPath) {
+ $ENV{DYLD_LIBRARY_PATH} = $dyldLibraryPath;
+ }
+ if (defined $dbusAddress) {
+ $ENV{DBUS_SESSION_BUS_ADDRESS} = $dbusAddress;
+ }
+ }
+ $ENV{DYLD_FRAMEWORK_PATH} = $productDir;
+ $ENV{XML_CATALOG_FILES} = ""; # work around missing /etc/catalog <rdar://problem/4292995>
+ $ENV{MallocStackLogging} = 1 if $shouldCheckLeaks;
+ $ENV{DYLD_INSERT_LIBRARIES} = "/usr/lib/libgmalloc.dylib" if $guardMalloc;
+
+ if (isCygwin()) {
+ $ENV{HOMEDRIVE} = $homeDrive;
+ $ENV{HOMEPATH} = $homePath;
+ if ($testfonts) {
+ $ENV{WEBKIT_TESTFONTS} = $testfonts;
+ }
+ setPathForRunningWebKitApp(\%ENV) if isCygwin();
+ }
+
+ my @args = ();
+ if ($useValgrind) {
+ push @args, $dumpTool;
+ }
+ push @args, @toolArgs;
+ if ($useValgrind) {
+ $dumpTool = "valgrind";
+ }
+ $dumpToolPID = open3(\*OUT, \*IN, \*ERROR, $dumpTool, @args) or die "Failed to start tool: $dumpTool\n";
+ $isDumpToolOpen = 1;
+ $dumpToolCrashed = 0;
+}
+
+sub closeDumpTool()
+{
+ return if !$isDumpToolOpen;
+
+ close IN;
+ close OUT;
+ close ERROR;
+ waitpid $dumpToolPID, 0;
+ $isDumpToolOpen = 0;
+}
+
+sub dumpToolDidCrash()
+{
+ return 1 if $dumpToolCrashed;
+ return 0 unless $isDumpToolOpen;
+
+ my $pid = waitpid(-1, WNOHANG);
+ return $pid == $dumpToolPID;
+}
+
+sub openHTTPDIfNeeded()
+{
+ return if $isHttpdOpen;
+
+ mkdir "/tmp/WebKit";
+
+ if (-f "/tmp/WebKit/httpd.pid") {
+ my $oldPid = `cat /tmp/WebKit/httpd.pid`;
+ chomp $oldPid;
+ if (0 != kill 0, $oldPid) {
+ print "\nhttpd is already running: pid $oldPid, killing...\n";
+ kill 15, $oldPid;
+
+ my $retryCount = 20;
+ while ((0 != kill 0, $oldPid) && $retryCount) {
+ sleep 1;
+ --$retryCount;
+ }
+
+ die "Timed out waiting for httpd to quit" unless $retryCount;
+ }
+ }
+
+ my $httpdPath = "/usr/sbin/httpd";
+ my $httpdConfig;
+ if (isCygwin()) {
+ my $windowsConfDirectory = "$testDirectory/http/conf/";
+ unless (-x "/usr/lib/apache/libphp4.dll") {
+ copy("$windowsConfDirectory/libphp4.dll", "/usr/lib/apache/libphp4.dll");
+ chmod(0755, "/usr/lib/apache/libphp4.dll");
+ }
+ $httpdConfig = "$windowsConfDirectory/cygwin-httpd.conf";
+ } elsif (isDebianBased()) {
+ $httpdPath = "/usr/sbin/apache2";
+ $httpdConfig = "$testDirectory/http/conf/apache2-debian-httpd.conf";
+ } else {
+ $httpdConfig = "$testDirectory/http/conf/httpd.conf";
+ $httpdConfig = "$testDirectory/http/conf/apache2-httpd.conf" if `$httpdPath -v` =~ m|Apache/2|;
+ }
+ my $documentRoot = "$testDirectory/http/tests";
+ my $typesConfig = "$testDirectory/http/conf/mime.types";
+ my $listen = "127.0.0.1:$httpdPort";
+ my $absTestResultsDirectory = File::Spec->rel2abs(glob $testResultsDirectory);
+ my $sslCertificate = "$testDirectory/http/conf/webkit-httpd.pem";
+
+ mkpath $absTestResultsDirectory;
+
+ my @args = (
+ "-f", "$httpdConfig",
+ "-C", "DocumentRoot \"$documentRoot\"",
+ "-C", "Listen $listen",
+ "-c", "TypesConfig \"$typesConfig\"",
+ "-c", "CustomLog \"$absTestResultsDirectory/access_log.txt\" common",
+ "-c", "ErrorLog \"$absTestResultsDirectory/error_log.txt\"",
+ # Apache wouldn't run CGIs with permissions==700 otherwise
+ "-c", "User \"#$<\""
+ );
+
+ # FIXME: Enable this on Windows once <rdar://problem/5345985> is fixed
+ push(@args, "-c", "SSLCertificateFile \"$sslCertificate\"") unless isCygwin();
+
+ open2(\*HTTPDIN, \*HTTPDOUT, $httpdPath, @args);
+
+ my $retryCount = 20;
+ while (system("/usr/bin/curl -q --silent --stderr - --output /dev/null $listen") && $retryCount) {
+ sleep 1;
+ --$retryCount;
+ }
+
+ die "Timed out waiting for httpd to start" unless $retryCount;
+
+ $isHttpdOpen = 1;
+}
+
+sub closeHTTPD()
+{
+ return if !$isHttpdOpen;
+
+ close HTTPDIN;
+ close HTTPDOUT;
+
+ kill 15, `cat /tmp/WebKit/httpd.pid` if -f "/tmp/WebKit/httpd.pid";
+
+ $isHttpdOpen = 0;
+}
+
+sub fileNameWithNumber($$)
+{
+ my ($base, $number) = @_;
+ return "$base$number" if ($number > 1);
+ return $base;
+}
+
+sub processIgnoreTests($) {
+ my @ignoreList = split(/\s*,\s*/, shift);
+ my $addIgnoredDirectories = sub {
+ return () if exists $ignoredLocalDirectories{basename($File::Find::dir)};
+ $ignoredDirectories{File::Spec->abs2rel($File::Find::dir, $testDirectory)} = 1;
+ return @_;
+ };
+ foreach my $item (@ignoreList) {
+ my $path = catfile($testDirectory, $item);
+ if (-d $path) {
+ $ignoredDirectories{$item} = 1;
+ find({ preprocess => $addIgnoredDirectories, wanted => sub {} }, $path);
+ }
+ elsif (-f $path) {
+ $ignoredFiles{$item} = 1;
+ }
+ else {
+ print "ignoring '$item' on ignore-tests list\n";
+ }
+ }
+}
+
+sub stripExtension($)
+{
+ my ($test) = @_;
+
+ $test =~ s/\.[a-zA-Z]+$//;
+ return $test;
+}
+
+sub isTextOnlyTest($)
+{
+ my ($actual) = @_;
+ my $isText;
+ if ($actual =~ /^layer at/ms) {
+ $isText = 0;
+ } else {
+ $isText = 1;
+ }
+ return $isText;
+}
+
+sub expectedDirectoryForTest($;$;$)
+{
+ my ($base, $isText, $isPixelTest) = @_;
+
+ my @directories = @platformHierarchy;
+ push @directories, map { catdir($platformBaseDirectory, $_) } qw(mac-leopard mac) if isCygwin();
+ push @directories, $expectedDirectory;
+
+ # If we already have expected results, just return their location.
+ if ($isPixelTest) {
+ foreach my $directory (@directories) {
+ return $directory if (-f "$directory/$base-$expectedTag.png");
+ }
+ } else {
+ foreach my $directory (@directories) {
+ return $directory if (-f "$directory/$base-$expectedTag.txt");
+ }
+ }
+
+ # For platform-specific tests, the results should go right next to the test itself.
+ # Note: The return value of this subroutine will be concatenated with $base
+ # to determine the location of the new results, so returning $expectedDirectory
+ # will put the results right next to the test.
+ # FIXME: We want to allow platform/mac tests with platform/mac-leopard results,
+ # so this needs to be enhanced.
+ return $expectedDirectory if $base =~ /^platform/;
+
+ # For cross-platform tests, text-only results should go in the cross-platform directory,
+ # while render tree dumps should go in the least-specific platform directory.
+ return $isText ? $expectedDirectory : $platformHierarchy[$#platformHierarchy];
+}
+
+sub printFailureMessageForTest($$)
+{
+ my ($test, $description) = @_;
+
+ unless ($verbose) {
+ print "\n" unless $atLineStart;
+ print "$test -> ";
+ }
+ print "$description\n";
+ $atLineStart = 1;
+}
+
+my %cygpaths = ();
+
+sub openCygpathIfNeeded($)
+{
+ my ($options) = @_;
+
+ return unless isCygwin();
+ return $cygpaths{$options} if $cygpaths{$options} && $cygpaths{$options}->{"open"};
+
+ local (*CYGPATHIN, *CYGPATHOUT);
+ my $pid = open2(\*CYGPATHIN, \*CYGPATHOUT, "cygpath -f - $options");
+ my $cygpath = {
+ "pid" => $pid,
+ "in" => *CYGPATHIN,
+ "out" => *CYGPATHOUT,
+ "open" => 1
+ };
+
+ $cygpaths{$options} = $cygpath;
+
+ return $cygpath;
+}
+
+sub closeCygpaths()
+{
+ return unless isCygwin();
+
+ foreach my $cygpath (values(%cygpaths)) {
+ close $cygpath->{"in"};
+ close $cygpath->{"out"};
+ waitpid($cygpath->{"pid"}, 0);
+ $cygpath->{"open"} = 0;
+
+ }
+}
+
+sub convertPathUsingCygpath($$)
+{
+ my ($path, $options) = @_;
+
+ my $cygpath = openCygpathIfNeeded($options);
+ local *inFH = $cygpath->{"in"};
+ local *outFH = $cygpath->{"out"};
+ print outFH $path . "\n";
+ chomp(my $convertedPath = <inFH>);
+ return $convertedPath;
+}
+
+sub toWindowsPath($)
+{
+ my ($path) = @_;
+ return unless isCygwin();
+
+ return convertPathUsingCygpath($path, "-w");
+}
+
+sub toURL($)
+{
+ my ($path) = @_;
+ return $path unless isCygwin();
+
+ return "file:///" . convertPathUsingCygpath($path, "-m");
+}
+
+sub validateSkippedArg($$;$)
+{
+ my ($option, $value, $value2) = @_;
+ my %validSkippedValues = map { $_ => 1 } qw(default ignore only);
+ $value = lc($value);
+ die "Invalid argument '" . $value . "' for option $option" unless $validSkippedValues{$value};
+ $treatSkipped = $value;
+}
+
+sub htmlForExpectedAndActualResults($)
+{
+ my ($base) = @_;
+
+ return "<td></td><td></td><td></td>\n" unless -s "$testResultsDirectory/$base-$diffsTag.txt";
+
+ return "<td><a href=\"$base-$expectedTag.txt\">expected</a></td>\n"
+ . "<td><a href=\"$base-$actualTag.txt\">actual</a></td>\n"
+ . "<td><a href=\"$base-$diffsTag.txt\">diffs</a></td>\n";
+}
+
+sub deleteExpectedAndActualResults($)
+{
+ my ($base) = @_;
+
+ unlink "$testResultsDirectory/$base-$actualTag.txt";
+ unlink "$testResultsDirectory/$base-$diffsTag.txt";
+ unlink "$testResultsDirectory/$base-$errorTag.txt";
+}
+
+sub recordActualResultsAndDiff($$)
+{
+ my ($base, $actual) = @_;
+
+ return unless length($actual);
+
+ open ACTUAL, ">", "$testResultsDirectory/$base-$actualTag.txt" or die "Couldn't open actual results file for $base";
+ print ACTUAL $actual;
+ close ACTUAL;
+
+ my $expectedDir = $expectedResultDirectory{$base};
+ copy("$expectedDir/$base-$expectedTag.txt", "$testResultsDirectory/$base-$expectedTag.txt");
+
+ system "diff -u \"$testResultsDirectory/$base-$expectedTag.txt\" \"$testResultsDirectory/$base-$actualTag.txt\" > \"$testResultsDirectory/$base-$diffsTag.txt\"";
+}
+
+sub buildPlatformHierarchy()
+{
+ mkpath($platformTestDirectory) if ($platform eq "undefined" && !-d "$platformTestDirectory");
+
+ my @platforms = split('-', $platform);
+ my @hierarchy;
+ for (my $i=0; $i < @platforms; $i++) {
+ my $scoped = catdir($platformBaseDirectory, join('-', @platforms[0..($#platforms - $i)]));
+ push(@hierarchy, $scoped) if (-d $scoped);
+ }
+
+ return @hierarchy;
+}
+
+sub epiloguesAndPrologues($$) {
+ my ($lastDirectory, $directory) = @_;
+ my @lastComponents = split('/', $lastDirectory);
+ my @components = split('/', $directory);
+
+ while (@lastComponents) {
+ if ($lastComponents[0] ne $components[0]) {
+ last;
+ }
+ shift @components;
+ shift @lastComponents;
+ }
+
+ my @result;
+ my $leaving = $lastDirectory;
+ foreach (@lastComponents) {
+ my $epilogue = $leaving . "/resources/run-webkit-tests-epilogue.html";
+ foreach (@platformHierarchy) {
+ push @result, catdir($_, $epilogue) if (stat(catdir($_, $epilogue)));
+ }
+ push @result, catdir($testDirectory, $epilogue) if (stat(catdir($testDirectory, $epilogue)));
+ $leaving =~ s|(^\|/)[^/]+$||;
+ }
+
+ my $entering = $leaving;
+ foreach (@components) {
+ $entering .= '/' . $_;
+ my $prologue = $entering . "/resources/run-webkit-tests-prologue.html";
+ push @result, catdir($testDirectory, $prologue) if (stat(catdir($testDirectory, $prologue)));
+ foreach (reverse @platformHierarchy) {
+ push @result, catdir($_, $prologue) if (stat(catdir($_, $prologue)));
+ }
+ }
+ return @result;
+}
+
+sub parseLeaksandPrintUniqueLeaks() {
+ return unless @leaksFilenames;
+
+ my $mergedFilenames = join " ", @leaksFilenames;
+ my $parseMallocHistoryTool = sourceDir() . "/WebKitTools/Scripts/parse-malloc-history";
+
+ open MERGED_LEAKS, "cat $mergedFilenames | $parseMallocHistoryTool --merge-depth $mergeDepth - |" ;
+ my @leakLines = <MERGED_LEAKS>;
+ close MERGED_LEAKS;
+
+ my $uniqueLeakCount = 0;
+ my $totalBytes;
+ foreach my $line (@leakLines) {
+ ++$uniqueLeakCount if ($line =~ /^(\d*)\scalls/);
+ $totalBytes = $1 if $line =~ /^total\:\s(.*)\s\(/;
+ }
+
+ print "\nWARNING: $totalLeaks total leaks found for a total of $totalBytes!\n";
+ print "WARNING: $uniqueLeakCount unique leaks found!\n";
+ print "See above for individual leaks results.\n" if ($leaksOutputFileNumber > 2);
+
+}
diff --git a/WebKitTools/Scripts/set-webkit-configuration b/WebKitTools/Scripts/set-webkit-configuration
new file mode 100755
index 0000000..8735140
--- /dev/null
+++ b/WebKitTools/Scripts/set-webkit-configuration
@@ -0,0 +1,41 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005 Apple Computer, 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.
+
+use strict;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+
+my $configuration = passedConfiguration();
+die "Please specify either --debug or --release.\n" if !$configuration;
+
+my $baseProductDir = baseProductDir();
+system "mkdir", "-p", "$baseProductDir";
+open CONFIGURATION, ">", "$baseProductDir/Configuration" or die;
+print CONFIGURATION $configuration;
+close CONFIGURATION;
diff --git a/WebKitTools/Scripts/sort-Xcode-project-file b/WebKitTools/Scripts/sort-Xcode-project-file
new file mode 100755
index 0000000..e9b7a56
--- /dev/null
+++ b/WebKitTools/Scripts/sort-Xcode-project-file
@@ -0,0 +1,115 @@
+#!/usr/bin/perl -w
+
+# 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.
+
+# Script to sort "files=(...);" sections in Xcode project.pbxproj files
+
+use strict;
+
+use File::Basename;
+use File::Temp;
+use Getopt::Long;
+
+sub sortByFileName($$);
+
+my $printWarnings = 1;
+my $showHelp;
+
+my $getOptionsResult = GetOptions(
+ 'h|help' => \$showHelp,
+ 'w|warnings!' => \$printWarnings,
+);
+
+if (scalar(@ARGV) == 0) {
+ print STDERR "ERROR: No Xcode project files (project.pbxproj) listed on command-line.\n";
+ undef $getOptionsResult;
+}
+
+if (!$getOptionsResult || $showHelp) {
+ print STDERR <<__END__;
+Usage: @{[ basename($0) ]} [options] path/to/project.pbxproj [path/to/project.pbxproj ...]
+ -h|--help show this help message
+ -w|--[no-]warnings show or suppress warnings (default: show warnings)
+__END__
+ exit 1;
+}
+
+for my $projectFile (@ARGV) {
+ if (basename($projectFile) ne "project.pbxproj") {
+ print STDERR "WARNING: Not an Xcode project file: $projectFile\n" if $printWarnings;
+ next;
+ }
+
+ my $OUT = new File::Temp(
+ DIR => dirname($projectFile),
+ TEMPLATE => basename($projectFile) . "-XXXXXXXX",
+ UNLINK => 0,
+ );
+ my $tempFileName = $OUT->filename();
+
+ # Clean up temp file in case of die()
+ $SIG{__DIE__} = sub {
+ close(IN);
+ close($OUT);
+ unlink($tempFileName);
+ };
+
+ open(IN, "< $projectFile") || die "Could not open $projectFile: $!";
+ while (my $line = <IN>) {
+ if ($line =~ /^(\s*)files = \(\s*$/) {
+ print $OUT $line;
+ my $endMarker = $1 . ");";
+ my @files;
+ while (my $fileLine = <IN>) {
+ if ($fileLine =~ /^\Q$endMarker\E\s*$/) {
+ $endMarker = $fileLine;
+ last;
+ }
+ push @files, $fileLine;
+ }
+ print $OUT sort sortByFileName @files;
+ print $OUT $endMarker;
+ } else {
+ print $OUT $line;
+ }
+ }
+ close(IN);
+ close($OUT);
+
+ unlink($projectFile) || die "Could not delete $projectFile: $!";
+ rename($tempFileName, $projectFile) || die "Could not rename $tempFileName to $projectFile: $!";
+}
+
+exit 0;
+
+sub sortByFileName($$)
+{
+ my ($a, $b) = @_;
+ my $aFileName = $1 if $a =~ /^\s*[A-Z0-9]{24} \/\* (.+) in /;
+ my $bFileName = $1 if $b =~ /^\s*[A-Z0-9]{24} \/\* (.+) in /;
+ return $aFileName cmp $bFileName;
+}
diff --git a/WebKitTools/Scripts/split-file-by-class b/WebKitTools/Scripts/split-file-by-class
new file mode 100755
index 0000000..b6aeb68
--- /dev/null
+++ b/WebKitTools/Scripts/split-file-by-class
@@ -0,0 +1,159 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2006 Apple Computer, 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.
+
+# Used for splitting a single file into multiple class files
+# Usage: split-class <header file>
+
+use strict;
+use File::Copy;
+use FindBin;
+use lib $FindBin::Bin;
+use SpacingHeuristics;
+
+
+for my $filename (@ARGV) {
+
+ $filename =~ m/^(\w+)\.h$/ or die "Command line args must be .h files.\n";
+ my $basename = $1;
+
+ open(OLDFILE, "<", $filename) or die "File does not exist: $filename\n";
+ print "Splitting class $filename.{h,cpp}:\n";
+
+ my $currentClassName = "";
+ my $classIndent = "";
+ my $fileContent = "";
+ my %classDefs = ();
+ while (my $line = <OLDFILE>) {
+ if ($currentClassName) {
+ $classDefs{$currentClassName} .= $line;
+ if ($line =~ /^$classIndent};\s*$/) {
+ $currentClassName = "";
+ }
+ } else {
+ if ($line =~ /^(\s*)class\s+(\w+)\s+[^;]*$/) {
+ $classIndent = $1;
+ $currentClassName = $2;
+ $classDefs{$currentClassName} .= $line;
+ $fileContent .= "###CLASS###$currentClassName\n";
+ } else {
+ $fileContent .= $line;
+ }
+ }
+ }
+ close(OLDFILE);
+
+ if (scalar(keys(%classDefs)) == 1) { # degenerate case
+ my ($classname) = keys(%classDefs);
+ if (!($classname eq $basename)) {
+ print "Skipping $filename, already correctly named.\n";
+ } else {
+ print "$filename only includes one class, renaming to $classname.h\n";
+ system("svn rm --force $classname.h") if (-r "$classname.h");
+ system "svn mv $basename.h $classname.h";
+ }
+ } else {
+ while (my ($classname, $classDef) = each(%classDefs)) {
+ if (($classname eq $basename)) {
+ print "Skipping $filename, already correctly named.\n";
+ } else {
+ print "Using SVN to copy $basename.{h,cpp} to $classname.{h,cpp}\n";
+
+ system("svn rm --force $classname.h") if (-r "$classname.h");
+ system "svn cp $basename.h $classname.h";
+
+ system("svn rm --force $classname.cpp") if (-r "$classname.cpp");
+ system "svn cp $basename.cpp $classname.cpp";
+ }
+
+ print "Fixing $classname.h as much as possible.\n";
+ open(NEWHEADER, ">", "$classname.h") or die "File does not exist: $filename\n";
+ my @lines = split("\n", $fileContent);
+ foreach my $line (@lines) {
+ if ($line =~ /^###CLASS###(\w+)/) {
+ if ($1 eq $classname) {
+ print NEWHEADER $classDef . "\n";
+ }
+ } else {
+ print NEWHEADER $line . "\n";
+ }
+ }
+ close(NEWHEADER);
+
+ print "Fixing $classname.cpp as much as possible.\n";
+ copy("$classname.cpp", "$classname.cpp.original");
+ open(OLDCPP, "<", "$classname.cpp.original") or die "Failed to copy file for reading: $filename\n";
+ open(NEWCPP, ">", "$classname.cpp") or die "File does not exist: $filename\n";
+ my $insideMemberFunction = 0;
+ my $shouldPrintMemberFunction = 0;
+ resetSpacingHeuristics();
+ while (my $line = <OLDCPP>) {
+ if ($insideMemberFunction) {
+ if ($shouldPrintMemberFunction) {
+ print NEWCPP $line;
+ #setPreviousAllowedLine($line);
+ } else {
+ ignoringLine($line);
+ }
+ if ($line =~ /^}\s*$/) {
+ $insideMemberFunction = 0;
+ }
+ } elsif ($line =~ /$filename/) {
+ print NEWCPP "#include \"config.h\"\n";
+ print NEWCPP "#include \"$classname.h\"\n";
+ } elsif ($line =~ /#include/ || $line =~ /#import/) {
+ next; # skip includes, they're generally wrong or unecessary anyway.
+ } else {
+ $line =~ s/DOM:://;
+ $line =~ s/khtml:://;
+ $line =~ s/namespace DOM/namespace WebCore/;
+ $line =~ s/namespace khtml/namespace WebCore/;
+
+ if ($line =~ /^(.*?\s+)?(\*|&)?(\w+)::(~)?\w+\s*\(/) {
+ $insideMemberFunction = 1;
+ $shouldPrintMemberFunction = ($classname eq $3);
+ if ($shouldPrintMemberFunction) {
+ printPendingEmptyLines(*NEWCPP, $line);
+ print NEWCPP $line;
+ }
+ } else {
+ next if isOnlyWhiteSpace($line);
+ next if ($line =~ m/------------/);
+ printPendingEmptyLines(*NEWCPP, $line);
+ applySpacingHeuristicsAndPrint(*NEWCPP, $line);
+ }
+ }
+ }
+ close(NEWCPP);
+ close(OLDCPP);
+ unlink("$classname.cpp.original");
+ }
+ }
+
+ print "Opening new files...\n";
+ system("open " . join(".* ", keys(%classDefs)) . ".*");
+} \ No newline at end of file
diff --git a/WebKitTools/Scripts/sunspider-compare-results b/WebKitTools/Scripts/sunspider-compare-results
new file mode 100755
index 0000000..cf18aae
--- /dev/null
+++ b/WebKitTools/Scripts/sunspider-compare-results
@@ -0,0 +1,101 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2007 Apple Inc. All rights reserved.
+# Copyright (C) 2007 Eric Seidel <eric@webkit.org>
+#
+# 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.
+
+use strict;
+use File::Spec;
+use FindBin;
+use Getopt::Long qw(:config pass_through);
+use lib $FindBin::Bin;
+use webkitdirs;
+use POSIX;
+
+# determine configuration, but default to "Release" instead of last-used configuration to match run-sunspider
+setConfiguration("Release");
+setConfiguration();
+my $configuration = configuration();
+
+my $root;
+my $showHelp = 0;
+
+my $programName = basename($0);
+my $usage = <<EOF;
+Usage: $programName [options] FILE FILE
+ --help Show this help message
+ --root Path to root tools build
+EOF
+
+GetOptions('root=s' => sub { my ($argName, $value); setConfigurationProductDir(Cwd::abs_path($value)); },
+ 'help' => \$showHelp);
+
+if ($showHelp) {
+ print STDERR $usage;
+ exit 1;
+}
+
+@ARGV = map { File::Spec->rel2abs($_) } @ARGV;
+
+sub buildTestKJS
+{
+ if (!defined($root)){
+ chdirWebKit();
+ my $buildResult = system "WebKitTools/Scripts/build-testkjs", "--" . $configuration;
+ if ($buildResult) {
+ print STDERR "Compiling testkjs failed!\n";
+ exit WEXITSTATUS($buildResult);
+ }
+ }
+}
+
+sub setupEnvironmentForExecution($)
+{
+ my ($productDir) = @_;
+ print "Starting sunspider-compare-results with DYLD_FRAMEWORK_PATH set to point to built JavaScriptCore in $productDir.\n";
+ $ENV{DYLD_FRAMEWORK_PATH} = $productDir;
+ # FIXME: Other platforms may wish to augment this method to use LD_LIBRARY_PATH, etc.
+}
+
+sub testKJSPath($)
+{
+ my ($productDir) = @_;
+ my $testkjsName = "testkjs";
+ $testkjsName .= "_debug" if (isCygwin() && ($configuration eq "Debug"));
+ return "$productDir/$testkjsName";
+}
+
+buildTestKJS();
+
+chdirWebKit();
+chdir("SunSpider");
+
+my $productDir = productDir();
+# FIXME: This hack should be pushed down into productDir()
+$productDir .= "/JavaScriptCore" if (isQt() or isGtk());
+
+setupEnvironmentForExecution($productDir);
+my @args = ("--shell", testKJSPath($productDir));
+# This code could be removed if we chose to pass extra args to sunspider instead of Xcode
+
+exec "./sunspider-compare-results", @args, @ARGV;
diff --git a/WebKitTools/Scripts/svn-apply b/WebKitTools/Scripts/svn-apply
new file mode 100755
index 0000000..5845917
--- /dev/null
+++ b/WebKitTools/Scripts/svn-apply
@@ -0,0 +1,438 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 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.
+# 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.
+
+# "patch" script for WebKit Open Source Project, used to apply patches.
+
+# Differences from invoking "patch -p0":
+#
+# Handles added files (does a svn add with logic to handle local changes).
+# Handles added directories (does a svn add).
+# Handles removed files (does a svn rm with logic to handle local changes).
+# Handles removed directories--those with no more files or directories left in them
+# (does a svn rm).
+# Has mode where it will roll back to svn version numbers in the patch file so svn
+# can do a 3-way merge.
+# Paths from Index: lines are used rather than the paths on the patch lines, which
+# makes patches generated by "cvs diff" work (increasingly unimportant since we
+# use Subversion now).
+# ChangeLog patches use --fuzz=3 to prevent rejects, and the entry date is set in
+# the patch to today's date using $changeLogTimeZone.
+# Handles binary files (requires patches made by svn-create-patch).
+# Handles copied and moved files (requires patches made by svn-create-patch).
+# Handles git-diff patches (without binary changes) created at the top-level directory
+#
+# Missing features:
+#
+# Handle property changes.
+# Handle copied and moved directories (would require patches made by svn-create-patch).
+# When doing a removal, check that old file matches what's being removed.
+# Notice a patch that's being applied at the "wrong level" and make it work anyway.
+# Do a dry run on the whole patch and don't do anything if part of the patch is
+# going to fail (probably too strict unless we exclude ChangeLog).
+# Handle git-diff patches with binary changes
+
+use strict;
+use warnings;
+
+use Cwd;
+use Digest::MD5;
+use File::Basename;
+use File::Spec;
+use Getopt::Long;
+use MIME::Base64;
+use POSIX qw(strftime);
+
+sub addDirectoriesIfNeeded($);
+sub applyPatch($$;$);
+sub checksum($);
+sub fixChangeLogPatch($);
+sub gitdiff2svndiff($);
+sub handleBinaryChange($$);
+sub isDirectoryEmptyForRemoval($);
+sub patch($);
+sub removeDirectoriesIfNeeded();
+sub setChangeLogDate($);
+sub svnStatus($);
+
+# Project time zone for Cupertino, CA, US
+my $changeLogTimeZone = "PST8PDT";
+
+my $merge = 0;
+my $showHelp = 0;
+if (!GetOptions("merge!" => \$merge, "help!" => \$showHelp) || $showHelp) {
+ print STDERR basename($0) . " [-h|--help] [-m|--merge] patch1 [patch2 ...]\n";
+ exit 1;
+}
+
+my %removeDirectoryIgnoreList = (
+ '.' => 1,
+ '..' => 1,
+ '.svn' => 1,
+ '_svn' => 1,
+);
+
+my %checkedDirectories;
+my %copiedFiles;
+my @patches;
+my %versions;
+
+my $copiedFromPath;
+my $filter;
+my $indexPath;
+my $patch;
+while (<>) {
+ s/\r//g;
+ chomp;
+ if (!defined($indexPath) && m#^diff --git a/#) {
+ $filter = \&gitdiff2svndiff;
+ }
+ $_ = &$filter($_) if $filter;
+ if (/^Index: (.+)/) {
+ $indexPath = $1;
+ if ($patch) {
+ if (!$copiedFromPath) {
+ push @patches, $patch;
+ }
+ $copiedFromPath = "";
+ $patch = "";
+ }
+ }
+ if ($indexPath) {
+ # Fix paths on diff, ---, and +++ lines to match preceding Index: line.
+ s/\S+$/$indexPath/ if /^diff/;
+ s/^--- \S+/--- $indexPath/;
+ if (/^--- .+\(from (\S+):(\d+)\)$/) {
+ $copiedFromPath = $1;
+ $copiedFiles{$indexPath} = $copiedFromPath;
+ $versions{$copiedFromPath} = $2 if ($2 != 0);
+ }
+ elsif (/^--- .+\(revision (\d+)\)$/) {
+ $versions{$indexPath} = $1 if ($1 != 0);
+ }
+ if (s/^\+\+\+ \S+/+++ $indexPath/) {
+ $indexPath = "";
+ }
+ }
+ $patch .= $_;
+ $patch .= "\n";
+}
+
+if ($patch && !$copiedFromPath) {
+ push @patches, $patch;
+}
+
+if ($merge) {
+ for my $file (sort keys %versions) {
+ print "Getting version $versions{$file} of $file\n";
+ system "svn", "update", "-r", $versions{$file}, $file;
+ }
+}
+
+# Handle copied and moved files first since moved files may have their source deleted before the move.
+for my $file (keys %copiedFiles) {
+ addDirectoriesIfNeeded(dirname($file));
+ system "svn", "copy", $copiedFiles{$file}, $file;
+}
+
+for $patch (@patches) {
+ patch($patch);
+}
+
+removeDirectoriesIfNeeded();
+
+exit 0;
+
+sub addDirectoriesIfNeeded($)
+{
+ my ($path) = @_;
+ my @dirs = File::Spec->splitdir($path);
+ my $dir = ".";
+ while (scalar @dirs) {
+ $dir = File::Spec->catdir($dir, shift @dirs);
+ next if exists $checkedDirectories{$dir};
+ if (! -e $dir) {
+ mkdir $dir or die "Failed to create required directory '$dir' for path '$path'\n";
+ system "svn", "add", $dir;
+ $checkedDirectories{$dir} = 1;
+ }
+ elsif (-d $dir) {
+ my $svnOutput = svnStatus($dir);
+ if ($svnOutput && $svnOutput =~ m#\?\s+$dir\n#) {
+ system "svn", "add", $dir;
+ }
+ $checkedDirectories{$dir} = 1;
+ }
+ else {
+ die "'$dir' is not a directory";
+ }
+ }
+}
+
+sub applyPatch($$;$)
+{
+ my ($patch, $fullPath, $options) = @_;
+ $options = [] if (! $options);
+ my $command = "patch " . join(" ", "-p0", @{$options});
+ open PATCH, "| $command" or die "Failed to patch $fullPath\n";
+ print PATCH $patch;
+ close PATCH;
+}
+
+sub checksum($)
+{
+ my $file = shift;
+ open(FILE, $file) or die "Can't open '$file': $!";
+ binmode(FILE);
+ my $checksum = Digest::MD5->new->addfile(*FILE)->hexdigest();
+ close(FILE);
+ return $checksum;
+}
+
+sub fixChangeLogPatch($)
+{
+ my $patch = shift;
+ my $contextLineCount = 3;
+
+ return $patch if $patch !~ /\n@@ -1,(\d+) \+1,(\d+) @@\n( .*\n)+(\+.*\n)+( .*\n){$contextLineCount}$/m;
+ my ($oldLineCount, $newLineCount) = ($1, $2);
+ return $patch if $oldLineCount <= $contextLineCount;
+
+ # The diff(1) command is greedy when matching lines, so a new ChangeLog entry will
+ # have lines of context at the top of a patch when the existing entry has the same
+ # date and author as the new entry. This nifty loop alters a ChangeLog patch so
+ # that the added lines ("+") in the patch always start at the beginning of the
+ # patch and there are no initial lines of context.
+ my $newPatch;
+ my $lineCountInState = 0;
+ my $oldContentLineCountReduction = $oldLineCount - $contextLineCount;
+ my $newContentLineCountWithoutContext = $newLineCount - $oldLineCount - $oldContentLineCountReduction;
+ my ($stateHeader, $statePreContext, $stateNewChanges, $statePostContext) = (1..4);
+ my $state = $stateHeader;
+ foreach my $line (split(/\n/, $patch)) {
+ $lineCountInState++;
+ if ($state == $stateHeader && $line =~ /^@@ -1,$oldLineCount \+1,$newLineCount @\@$/) {
+ $line = "@@ -1,$contextLineCount +1," . ($newLineCount - $oldContentLineCountReduction) . " @@";
+ $lineCountInState = 0;
+ $state = $statePreContext;
+ } elsif ($state == $statePreContext && substr($line, 0, 1) eq " ") {
+ $line = "+" . substr($line, 1);
+ if ($lineCountInState == $oldContentLineCountReduction) {
+ $lineCountInState = 0;
+ $state = $stateNewChanges;
+ }
+ } elsif ($state == $stateNewChanges && substr($line, 0, 1) eq "+") {
+ # No changes to these lines
+ if ($lineCountInState == $newContentLineCountWithoutContext) {
+ $lineCountInState = 0;
+ $state = $statePostContext;
+ }
+ } elsif ($state == $statePostContext) {
+ if (substr($line, 0, 1) eq "+" && $lineCountInState <= $oldContentLineCountReduction) {
+ $line = " " . substr($line, 1);
+ } elsif ($lineCountInState > $contextLineCount && substr($line, 0, 1) eq " ") {
+ next; # Discard
+ }
+ }
+ $newPatch .= $line . "\n";
+ }
+
+ return $newPatch;
+}
+
+sub gitdiff2svndiff($)
+{
+ $_ = shift @_;
+ if (m#^diff --git a/(.+) b/(.+)#) {
+ return "Index: $1";
+ } elsif (m/^new file.*/) {
+ return "";
+ } elsif (m#^index [0-9a-f]{7}\.\.[0-9a-f]{7} [0-9]{6}#) {
+ return "===================================================================";
+ } elsif (m#^--- a/(.+)#) {
+ return "--- $1";
+ } elsif (m#^\+\+\+ b/(.+)#) {
+ return "+++ $1";
+ }
+ return $_;
+}
+
+sub handleBinaryChange($$)
+{
+ my ($fullPath, $contents) = @_;
+ if ($contents =~ m#((\n[A-Za-z0-9+/]{76})+\n[A-Za-z0-9+/=]{4,76}\n)#) {
+ # Addition or Modification
+ open FILE, ">", $fullPath or die;
+ print FILE decode_base64($1);
+ close FILE;
+ my $svnOutput = svnStatus($fullPath);
+ if ($svnOutput && substr($svnOutput, 0, 1) eq "?") {
+ # Addition
+ system "svn", "add", $fullPath;
+ } else {
+ # Modification
+ print $svnOutput if $svnOutput;
+ }
+ } else {
+ # Deletion
+ system "svn", "rm", $fullPath;
+ }
+}
+
+sub isDirectoryEmptyForRemoval($)
+{
+ my ($dir) = @_;
+ my $directoryIsEmpty = 1;
+ opendir DIR, $dir or die "Could not open '$dir' to list files: $?";
+ for (my $item = readdir DIR; $item && $directoryIsEmpty; $item = readdir DIR) {
+ next if exists $removeDirectoryIgnoreList{$item};
+ if (! -d File::Spec->catdir($dir, $item)) {
+ $directoryIsEmpty = 0;
+ } else {
+ my $svnOutput = svnStatus(File::Spec->catdir($dir, $item));
+ next if $svnOutput && substr($svnOutput, 0, 1) eq "D";
+ $directoryIsEmpty = 0;
+ }
+ }
+ closedir DIR;
+ return $directoryIsEmpty;
+}
+
+sub patch($)
+{
+ my ($patch) = @_;
+ return if !$patch;
+
+ unless ($patch =~ m|^Index: ([^\n]+)|) {
+ my $separator = '-' x 67;
+ warn "Failed to find 'Index:' in:\n$separator\n$patch\n$separator\n";
+ return;
+ }
+ my $fullPath = $1;
+
+ my $deletion = 0;
+ my $addition = 0;
+ my $isBinary = 0;
+
+ $addition = 1 if $patch =~ /\n--- .+\(revision 0\)\n/;
+ $deletion = 1 if $patch =~ /\n@@ .* \+0,0 @@/;
+ $isBinary = 1 if $patch =~ /\nCannot display: file marked as a binary type\./;
+
+ if (!$addition && !$deletion && !$isBinary) {
+ # Standard patch, patch tool can handle this.
+ if (basename($fullPath) eq "ChangeLog") {
+ my $changeLogDotOrigExisted = -f "${fullPath}.orig";
+ applyPatch(setChangeLogDate(fixChangeLogPatch($patch)), $fullPath, ["--fuzz=3"]);
+ unlink("${fullPath}.orig") if (! $changeLogDotOrigExisted);
+ } else {
+ applyPatch($patch, $fullPath);
+ }
+ } else {
+ # Either a deletion, an addition or a binary change.
+
+ addDirectoriesIfNeeded(dirname($fullPath));
+
+ if ($isBinary) {
+ # Binary change
+ handleBinaryChange($fullPath, $patch);
+ } elsif ($deletion) {
+ # Deletion
+ applyPatch($patch, $fullPath, ["--force"]);
+ system "svn", "rm", "--force", $fullPath;
+ } else {
+ # Addition
+ rename($fullPath, "$fullPath.orig") if -e $fullPath;
+ applyPatch($patch, $fullPath);
+ unlink("$fullPath.orig") if -e "$fullPath.orig" && checksum($fullPath) eq checksum("$fullPath.orig");
+ system "svn", "add", $fullPath;
+ system "svn", "stat", "$fullPath.orig" if -e "$fullPath.orig";
+ }
+ }
+}
+
+sub removeDirectoriesIfNeeded()
+{
+ foreach my $dir (reverse sort keys %checkedDirectories) {
+ if (isDirectoryEmptyForRemoval($dir)) {
+ my $svnOutput;
+ open SVN, "svn rm '$dir' |" or die;
+ # Only save the last line since Subversion lists all changed statuses below $dir
+ while (<SVN>) {
+ $svnOutput = $_;
+ }
+ close SVN;
+ print $svnOutput if $svnOutput;
+ }
+ }
+}
+
+sub setChangeLogDate($)
+{
+ my $patch = shift;
+ my $savedTimeZone = $ENV{'TZ'};
+ # Set TZ temporarily so that localtime() is in that time zone
+ $ENV{'TZ'} = $changeLogTimeZone;
+ my $newDate = strftime("%Y-%m-%d", localtime());
+ if (defined $savedTimeZone) {
+ $ENV{'TZ'} = $savedTimeZone;
+ } else {
+ delete $ENV{'TZ'};
+ }
+ $patch =~ s/(\n\+)\d{4}-[^-]{2}-[^-]{2}( )/$1$newDate$2/;
+ return $patch;
+}
+
+sub svnStatus($)
+{
+ my ($fullPath) = @_;
+ my $svnStatus;
+ open SVN, "svn status --non-interactive --non-recursive '$fullPath' |" or die;
+ if (-d $fullPath) {
+ # When running "svn stat" on a directory, we can't assume that only one
+ # status will be returned (since any files with a status below the
+ # directory will be returned), and we can't assume that the directory will
+ # be first (since any files with unknown status will be listed first).
+ my $normalizedFullPath = File::Spec->catdir(File::Spec->splitdir($fullPath));
+ while (<SVN>) {
+ chomp;
+ my $normalizedStatPath = File::Spec->catdir(File::Spec->splitdir(substr($_, 7)));
+ if ($normalizedFullPath eq $normalizedStatPath) {
+ $svnStatus = $_;
+ last;
+ }
+ }
+ # Read the rest of the svn command output to avoid a broken pipe warning.
+ local $/ = undef;
+ <SVN>;
+ }
+ else {
+ # Files will have only one status returned.
+ $svnStatus = <SVN>;
+ }
+ close SVN;
+ return $svnStatus;
+}
diff --git a/WebKitTools/Scripts/svn-create-patch b/WebKitTools/Scripts/svn-create-patch
new file mode 100755
index 0000000..365737a
--- /dev/null
+++ b/WebKitTools/Scripts/svn-create-patch
@@ -0,0 +1,442 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005, 2006 Apple Computer, 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.
+
+# Extended "svn diff" script for WebKit Open Source Project, used to make patches.
+
+# Differences from standard "svn diff":
+#
+# Uses the real diff, not svn's built-in diff.
+# Always passes "-p" to diff so it will try to include function names.
+# Handles binary files (encoded as a base64 chunk of text).
+# Sorts the diffs alphabetically by text files, then binary files.
+# Handles copied and moved files.
+#
+# Missing features:
+#
+# Handle copied and moved directories.
+
+use strict;
+use warnings;
+
+use Config;
+use Cwd;
+use File::Basename;
+use File::Spec;
+use File::stat;
+use Getopt::Long;
+use MIME::Base64;
+use POSIX qw(:errno_h);
+use Time::gmtime;
+
+sub binarycmp($$);
+sub canonicalizePath($);
+sub findBaseUrl($);
+sub findMimeType($;$);
+sub findModificationType($);
+sub findSourceFileAndRevision($);
+sub fixChangeLogPatch($);
+sub generateDiff($);
+sub generateFileList($\%);
+sub isBinaryMimeType($);
+sub manufacturePatchForAdditionWithHistory($);
+sub numericcmp($$);
+sub outputBinaryContent($);
+sub patchpathcmp($$);
+sub pathcmp($$);
+sub processPaths(\@);
+sub splitpath($);
+sub testfilecmp($$);
+
+$ENV{'LC_ALL'} = 'C';
+
+my $showHelp;
+
+my $result = GetOptions(
+ "help" => \$showHelp,
+);
+if (!$result || $showHelp) {
+ print STDERR basename($0) . " [-h|--help] [svndir1 [svndir2 ...]]\n";
+ exit 1;
+}
+
+# Sort the diffs for easier reviewing.
+my %paths = processPaths(@ARGV);
+
+# Generate a list of files requiring diffs.
+my %diffFiles;
+for my $path (keys %paths) {
+ generateFileList($path, %diffFiles);
+}
+
+# Generate the diffs, in a order chosen for easy reviewing.
+for my $path (sort patchpathcmp values %diffFiles) {
+ generateDiff($path);
+}
+
+exit 0;
+
+# Overall sort, considering multiple criteria.
+sub patchpathcmp($$)
+{
+ my ($a, $b) = @_;
+
+ # All binary files come after all non-binary files.
+ my $result = binarycmp($a, $b);
+ return $result if $result;
+
+ # All test files come after all non-test files.
+ $result = testfilecmp($a, $b);
+ return $result if $result;
+
+ # Final sort is a "smart" sort by directory and file name.
+ return pathcmp($a, $b);
+}
+
+# Sort so text files appear before binary files.
+sub binarycmp($$)
+{
+ my ($fileDataA, $fileDataB) = @_;
+ return $fileDataA->{isBinary} <=> $fileDataB->{isBinary};
+}
+
+sub canonicalizePath($)
+{
+ my ($file) = @_;
+
+ # Remove extra slashes and '.' directories in path
+ $file = File::Spec->canonpath($file);
+
+ # Remove '..' directories in path
+ my @dirs = ();
+ foreach my $dir (File::Spec->splitdir($file)) {
+ if ($dir eq '..' && $#dirs >= 0 && $dirs[$#dirs] ne '..') {
+ pop(@dirs);
+ } else {
+ push(@dirs, $dir);
+ }
+ }
+ return ($#dirs >= 0) ? File::Spec->catdir(@dirs) : ".";
+}
+
+sub findBaseUrl($)
+{
+ my ($infoPath) = @_;
+ my $baseUrl;
+ open INFO, "svn info '$infoPath' |" or die;
+ while (<INFO>) {
+ if (/^URL: (.+)/) {
+ $baseUrl = $1;
+ last;
+ }
+ }
+ close INFO;
+ return $baseUrl;
+}
+
+sub findMimeType($;$)
+{
+ my ($file, $revision) = @_;
+ my $args = $revision ? "--revision $revision" : "";
+ open PROPGET, "svn propget svn:mime-type $args '$file' |" or die;
+ my $mimeType = <PROPGET>;
+ close PROPGET;
+ chomp $mimeType if $mimeType;
+ return $mimeType;
+}
+
+sub findModificationType($)
+{
+ my ($stat) = @_;
+ my $fileStat = substr($stat, 0, 1);
+ my $propertyStat = substr($stat, 1, 1);
+ if ($fileStat eq "A") {
+ my $additionWithHistory = substr($stat, 3, 1);
+ return $additionWithHistory eq "+" ? "additionWithHistory" : "addition";
+ }
+ return "modification" if ($fileStat eq "M" || $propertyStat eq "M");
+ return "deletion" if ($fileStat eq "D");
+ return undef;
+}
+
+sub findSourceFileAndRevision($)
+{
+ my ($file) = @_;
+ my $baseUrl = findBaseUrl(".");
+ my $sourceFile;
+ my $sourceRevision;
+ open INFO, "svn info '$file' |" or die;
+ while (<INFO>) {
+ if (/^Copied From URL: (.+)/) {
+ $sourceFile = File::Spec->abs2rel($1, $baseUrl);
+ } elsif (/^Copied From Rev: ([0-9]+)/) {
+ $sourceRevision = $1;
+ }
+ }
+ close INFO;
+ return ($sourceFile, $sourceRevision);
+}
+
+sub fixChangeLogPatch($)
+{
+ my $patch = shift;
+ my $contextLineCount = 3;
+
+ return $patch if $patch !~ /\n@@ -1,(\d+) \+1,(\d+) @@\n( .*\n)+(\+.*\n)+( .*\n){$contextLineCount}$/m;
+ my ($oldLineCount, $newLineCount) = ($1, $2);
+ return $patch if $oldLineCount <= $contextLineCount;
+
+ # The diff(1) command is greedy when matching lines, so a new ChangeLog entry will
+ # have lines of context at the top of a patch when the existing entry has the same
+ # date and author as the new entry. This nifty loop alters a ChangeLog patch so
+ # that the added lines ("+") in the patch always start at the beginning of the
+ # patch and there are no initial lines of context.
+ my $newPatch;
+ my $lineCountInState = 0;
+ my $oldContentLineCountReduction = $oldLineCount - $contextLineCount;
+ my $newContentLineCountWithoutContext = $newLineCount - $oldLineCount - $oldContentLineCountReduction;
+ my ($stateHeader, $statePreContext, $stateNewChanges, $statePostContext) = (1..4);
+ my $state = $stateHeader;
+ foreach my $line (split(/\n/, $patch)) {
+ $lineCountInState++;
+ if ($state == $stateHeader && $line =~ /^@@ -1,$oldLineCount \+1,$newLineCount @\@$/) {
+ $line = "@@ -1,$contextLineCount +1," . ($newLineCount - $oldContentLineCountReduction) . " @@";
+ $lineCountInState = 0;
+ $state = $statePreContext;
+ } elsif ($state == $statePreContext && substr($line, 0, 1) eq " ") {
+ $line = "+" . substr($line, 1);
+ if ($lineCountInState == $oldContentLineCountReduction) {
+ $lineCountInState = 0;
+ $state = $stateNewChanges;
+ }
+ } elsif ($state == $stateNewChanges && substr($line, 0, 1) eq "+") {
+ # No changes to these lines
+ if ($lineCountInState == $newContentLineCountWithoutContext) {
+ $lineCountInState = 0;
+ $state = $statePostContext;
+ }
+ } elsif ($state == $statePostContext) {
+ if (substr($line, 0, 1) eq "+" && $lineCountInState <= $oldContentLineCountReduction) {
+ $line = " " . substr($line, 1);
+ } elsif ($lineCountInState > $contextLineCount && substr($line, 0, 1) eq " ") {
+ next; # Discard
+ }
+ }
+ $newPatch .= $line . "\n";
+ }
+
+ return $newPatch;
+}
+
+sub generateDiff($)
+{
+ my ($fileData) = @_;
+ my $file = $fileData->{path};
+ my $patch;
+ if ($fileData->{modificationType} eq "additionWithHistory") {
+ manufacturePatchForAdditionWithHistory($fileData);
+ }
+ open DIFF, "svn diff --diff-cmd diff -x -uaNp '$file' |" or die;
+ while (<DIFF>) {
+ $patch .= $_;
+ }
+ close DIFF;
+ $patch = fixChangeLogPatch($patch) if basename($file) eq "ChangeLog";
+ print $patch if $patch;
+ if ($fileData->{isBinary}) {
+ print "\n" if ($patch && $patch =~ m/\n\S+$/m);
+ outputBinaryContent($file);
+ }
+}
+
+sub generateFileList($\%)
+{
+ my ($statPath, $diffFiles) = @_;
+ my %testDirectories = map { $_ => 1 } qw(LayoutTests);
+ open STAT, "svn stat '$statPath' |" or die;
+ while (my $line = <STAT>) {
+ chomp $line;
+ my $stat = substr($line, 0, 7);
+ my $path = substr($line, 7);
+ next if -d $path;
+ my $modificationType = findModificationType($stat);
+ if ($modificationType) {
+ $diffFiles->{$path}->{path} = $path;
+ $diffFiles->{$path}->{modificationType} = $modificationType;
+ $diffFiles->{$path}->{isBinary} = isBinaryMimeType($path);
+ $diffFiles->{$path}->{isTestFile} = exists $testDirectories{(File::Spec->splitdir($path))[0]} ? 1 : 0;
+ if ($modificationType eq "additionWithHistory") {
+ my ($sourceFile, $sourceRevision) = findSourceFileAndRevision($path);
+ $diffFiles->{$path}->{sourceFile} = $sourceFile;
+ $diffFiles->{$path}->{sourceRevision} = $sourceRevision;
+ }
+ } else {
+ print STDERR $line, "\n";
+ }
+ }
+ close STAT;
+}
+
+sub isBinaryMimeType($)
+{
+ my ($file) = @_;
+ my $mimeType = findMimeType($file);
+ return 0 if (!$mimeType || substr($mimeType, 0, 5) eq "text/");
+ return 1;
+}
+
+sub manufacturePatchForAdditionWithHistory($)
+{
+ my ($fileData) = @_;
+ my $file = $fileData->{path};
+ print "Index: ${file}\n";
+ print "=" x 67, "\n";
+ my $sourceFile = $fileData->{sourceFile};
+ my $sourceRevision = $fileData->{sourceRevision};
+ print "--- ${file}\t(revision ${sourceRevision})\t(from ${sourceFile}:${sourceRevision})\n";
+ print "+++ ${file}\t(working copy)\n";
+ if ($fileData->{isBinary}) {
+ print "\nCannot display: file marked as a binary type.\n";
+ my $mimeType = findMimeType($file, $sourceRevision);
+ print "svn:mime-type = ${mimeType}\n\n";
+ } else {
+ print `svn cat ${sourceFile} | diff -u /dev/null - | tail -n +3`;
+ }
+}
+
+# Sort numeric parts of strings as numbers, other parts as strings.
+# Makes 1.33 come after 1.3, which is cool.
+sub numericcmp($$)
+{
+ my ($aa, $bb) = @_;
+
+ my @a = split /(\d+)/, $aa;
+ my @b = split /(\d+)/, $bb;
+
+ # Compare one chunk at a time.
+ # Each chunk is either all numeric digits, or all not numeric digits.
+ while (@a && @b) {
+ my $a = shift @a;
+ my $b = shift @b;
+
+ # Use numeric comparison if chunks are non-equal numbers.
+ return $a <=> $b if $a =~ /^\d/ && $b =~ /^\d/ && $a != $b;
+
+ # Use string comparison if chunks are any other kind of non-equal string.
+ return $a cmp $b if $a ne $b;
+ }
+
+ # One of the two is now empty; compare lengths for result in this case.
+ return @a <=> @b;
+}
+
+sub outputBinaryContent($)
+{
+ my ($path) = @_;
+ # Deletion
+ return if (! -e $path);
+ # Addition or Modification
+ my $buffer;
+ open BINARY, $path or die;
+ while (read(BINARY, $buffer, 60*57)) {
+ print encode_base64($buffer);
+ }
+ close BINARY;
+ print "\n";
+}
+
+# Sort first by directory, then by file, so all paths in one directory are grouped
+# rather than being interspersed with items from subdirectories.
+# Use numericcmp to sort directory and filenames to make order logical.
+# Also include a special case for ChangeLog, which comes first in any directory.
+sub pathcmp($$)
+{
+ my ($fileDataA, $fileDataB) = @_;
+
+ my ($dira, $namea) = splitpath($fileDataA->{path});
+ my ($dirb, $nameb) = splitpath($fileDataB->{path});
+
+ return numericcmp($dira, $dirb) if $dira ne $dirb;
+ return -1 if $namea eq "ChangeLog" && $nameb ne "ChangeLog";
+ return +1 if $namea ne "ChangeLog" && $nameb eq "ChangeLog";
+ return numericcmp($namea, $nameb);
+}
+
+sub processPaths(\@)
+{
+ my ($paths) = @_;
+ return ("." => 1) if (!@{$paths});
+
+ my %result = ();
+
+ for my $file (@{$paths}) {
+ die "can't handle absolute paths like \"$file\"\n" if File::Spec->file_name_is_absolute($file);
+ die "can't handle empty string path\n" if $file eq "";
+ die "can't handle path with single quote in the name like \"$file\"\n" if $file =~ /'/; # ' (keep Xcode syntax highlighting happy)
+
+ my $untouchedFile = $file;
+
+ $file = canonicalizePath($file);
+
+ die "can't handle paths with .. like \"$untouchedFile\"\n" if $file =~ m|/\.\./|;
+
+ $result{$file} = 1;
+ }
+
+ return ("." => 1) if ($result{"."});
+
+ # Remove any paths that also have a parent listed.
+ for my $path (keys %result) {
+ for (my $parent = dirname($path); $parent ne '.'; $parent = dirname($parent)) {
+ if ($result{$parent}) {
+ delete $result{$path};
+ last;
+ }
+ }
+ }
+
+ return %result;
+}
+
+# Break up a path into the directory (with slash) and base name.
+sub splitpath($)
+{
+ my ($path) = @_;
+
+ my $pathSeparator = "/";
+ my $dirname = dirname($path) . $pathSeparator;
+ $dirname = "" if $dirname eq "." . $pathSeparator;
+
+ return ($dirname, basename($path));
+}
+
+# Sort so source code files appear before test files.
+sub testfilecmp($$)
+{
+ my ($fileDataA, $fileDataB) = @_;
+ return $fileDataA->{isTestFile} <=> $fileDataB->{isTestFile};
+}
diff --git a/WebKitTools/Scripts/svn-unapply b/WebKitTools/Scripts/svn-unapply
new file mode 100755
index 0000000..05910ad
--- /dev/null
+++ b/WebKitTools/Scripts/svn-unapply
@@ -0,0 +1,374 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 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.
+# 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.
+
+# "unpatch" script for Web Kit Open Source Project, used to remove patches.
+
+# Differences from invoking "patch -p0 -R":
+#
+# Handles added files (does a svn revert with additional logic to handle local changes).
+# Handles added directories (does a svn revert and a rmdir).
+# Handles removed files (does a svn revert with additional logic to handle local changes).
+# Handles removed directories (does a svn revert).
+# Paths from Index: lines are used rather than the paths on the patch lines, which
+# makes patches generated by "cvs diff" work (increasingly unimportant since we
+# use Subversion now).
+# ChangeLog patches use --fuzz=3 to prevent rejects, and the entry date is reset in
+# the patch before it is applied (svn-apply sets it when applying a patch).
+# Handles binary files (requires patches made by svn-create-patch).
+# Handles copied and moved files (requires patches made by svn-create-patch).
+# Handles git-diff patches (without binary changes) created at the top-level directory
+#
+# Missing features:
+#
+# Handle property changes.
+# Handle copied and moved directories (would require patches made by svn-create-patch).
+# Use version numbers in the patch file and do a 3-way merge.
+# When reversing an addition, check that the file matches what's being removed.
+# Notice a patch that's being unapplied at the "wrong level" and make it work anyway.
+# Do a dry run on the whole patch and don't do anything if part of the patch is
+# going to fail (probably too strict unless we exclude ChangeLog).
+# Handle git-diff patches with binary changes
+
+use strict;
+use warnings;
+
+use Cwd;
+use Digest::MD5;
+use Fcntl qw(:DEFAULT :seek);
+use File::Basename;
+use File::Spec;
+use File::Temp qw(tempfile);
+use Getopt::Long;
+
+sub checksum($);
+sub fixChangeLogPatch($);
+sub gitdiff2svndiff($);
+sub patch($);
+sub revertDirectories();
+sub svnStatus($);
+sub unapplyPatch($$;$);
+sub unsetChangeLogDate($$);
+
+my $showHelp = 0;
+if (!GetOptions("help!" => \$showHelp) || $showHelp) {
+ print STDERR basename($0) . " [-h|--help] patch1 [patch2 ...]\n";
+ exit 1;
+}
+
+my @copiedFiles;
+my %directoriesToCheck;
+
+my $copiedFromPath;
+my $filter;
+my $indexPath;
+my $patch;
+while (<>) {
+ s/\r//g;
+ chomp;
+ if (!defined($indexPath) && m#^diff --git a/#) {
+ $filter = \&gitdiff2svndiff;
+ }
+ $_ = &$filter($_) if $filter;
+ if (/^Index: (.*)/) {
+ $indexPath = $1;
+ if ($patch) {
+ if ($copiedFromPath) {
+ push @copiedFiles, $patch;
+ } else {
+ patch($patch);
+ }
+ $copiedFromPath = "";
+ $patch = "";
+ }
+ }
+ if ($indexPath) {
+ # Fix paths on diff, ---, and +++ lines to match preceding Index: line.
+ s/^--- \S+/--- $indexPath/;
+ if (/^--- .+\(from (\S+):\d+\)$/) {
+ $copiedFromPath = $1;
+ }
+ if (s/^\+\+\+ \S+/+++ $indexPath/) {
+ $indexPath = "";
+ }
+ }
+ $patch .= $_;
+ $patch .= "\n";
+}
+
+if ($patch) {
+ if ($copiedFromPath) {
+ push @copiedFiles, $patch;
+ } else {
+ patch($patch);
+ }
+}
+
+# Handle copied and moved files last since they may have had post-copy changes that have now been unapplied
+for $patch (@copiedFiles) {
+ patch($patch);
+}
+
+revertDirectories();
+
+exit 0;
+
+sub checksum($)
+{
+ my $file = shift;
+ open(FILE, $file) or die "Can't open '$file': $!";
+ binmode(FILE);
+ my $checksum = Digest::MD5->new->addfile(*FILE)->hexdigest();
+ close(FILE);
+ return $checksum;
+}
+
+sub fixChangeLogPatch($)
+{
+ my $patch = shift;
+ my $contextLineCount = 3;
+
+ return $patch if $patch !~ /\n@@ -1,(\d+) \+1,(\d+) @@\n( .*\n)+(\+.*\n)+( .*\n){$contextLineCount}$/m;
+ my ($oldLineCount, $newLineCount) = ($1, $2);
+ return $patch if $oldLineCount <= $contextLineCount;
+
+ # The diff(1) command is greedy when matching lines, so a new ChangeLog entry will
+ # have lines of context at the top of a patch when the existing entry has the same
+ # date and author as the new entry. This nifty loop alters a ChangeLog patch so
+ # that the added lines ("+") in the patch always start at the beginning of the
+ # patch and there are no initial lines of context.
+ my $newPatch;
+ my $lineCountInState = 0;
+ my $oldContentLineCountReduction = $oldLineCount - $contextLineCount;
+ my $newContentLineCountWithoutContext = $newLineCount - $oldLineCount - $oldContentLineCountReduction;
+ my ($stateHeader, $statePreContext, $stateNewChanges, $statePostContext) = (1..4);
+ my $state = $stateHeader;
+ foreach my $line (split(/\n/, $patch)) {
+ $lineCountInState++;
+ if ($state == $stateHeader && $line =~ /^@@ -1,$oldLineCount \+1,$newLineCount @\@$/) {
+ $line = "@@ -1,$contextLineCount +1," . ($newLineCount - $oldContentLineCountReduction) . " @@";
+ $lineCountInState = 0;
+ $state = $statePreContext;
+ } elsif ($state == $statePreContext && substr($line, 0, 1) eq " ") {
+ $line = "+" . substr($line, 1);
+ if ($lineCountInState == $oldContentLineCountReduction) {
+ $lineCountInState = 0;
+ $state = $stateNewChanges;
+ }
+ } elsif ($state == $stateNewChanges && substr($line, 0, 1) eq "+") {
+ # No changes to these lines
+ if ($lineCountInState == $newContentLineCountWithoutContext) {
+ $lineCountInState = 0;
+ $state = $statePostContext;
+ }
+ } elsif ($state == $statePostContext) {
+ if (substr($line, 0, 1) eq "+" && $lineCountInState <= $oldContentLineCountReduction) {
+ $line = " " . substr($line, 1);
+ } elsif ($lineCountInState > $contextLineCount && substr($line, 0, 1) eq " ") {
+ next; # Discard
+ }
+ }
+ $newPatch .= $line . "\n";
+ }
+
+ return $newPatch;
+}
+
+sub gitdiff2svndiff($)
+{
+ $_ = shift @_;
+ if (m#^diff --git a/(.+) b/(.+)#) {
+ return "Index: $1";
+ } elsif (m/^new file.*/) {
+ return "";
+ } elsif (m#^index [0-9a-f]{7}\.\.[0-9a-f]{7} [0-9]{6}#) {
+ return "===================================================================";
+ } elsif (m#^--- a/(.+)#) {
+ return "--- $1";
+ } elsif (m#^\+\+\+ b/(.+)#) {
+ return "+++ $1";
+ }
+ return $_;
+}
+
+sub patch($)
+{
+ my ($patch) = @_;
+ return if !$patch;
+
+ unless ($patch =~ m|^Index: ([^\n]+)|) {
+ my $separator = '-' x 67;
+ warn "Failed to find 'Index:' in:\n$separator\n$patch\n$separator\n";
+ return;
+ }
+ my $fullPath = $1;
+ $directoriesToCheck{dirname($fullPath)} = 1;
+
+ my $deletion = 0;
+ my $addition = 0;
+ my $isBinary = 0;
+
+ $addition = 1 if ($patch =~ /\n--- .+\(revision 0\)\n/ || $patch =~ /\n@@ -0,0 .* @@/);
+ $deletion = 1 if $patch =~ /\n@@ .* \+0,0 @@/;
+ $isBinary = 1 if $patch =~ /\nCannot display: file marked as a binary type\./;
+
+ if (!$addition && !$deletion && !$isBinary) {
+ # Standard patch, patch tool can handle this.
+ if (basename($fullPath) eq "ChangeLog") {
+ my $changeLogDotOrigExisted = -f "${fullPath}.orig";
+ unapplyPatch(unsetChangeLogDate($fullPath, fixChangeLogPatch($patch)), $fullPath, ["--fuzz=3"]);
+ unlink("${fullPath}.orig") if (! $changeLogDotOrigExisted);
+ } else {
+ unapplyPatch($patch, $fullPath);
+ }
+ } else {
+ # Either a deletion, an addition or a binary change.
+
+ if ($isBinary) {
+ # Reverse binary change
+ unlink($fullPath) if (-e $fullPath);
+ system "svn", "revert", $fullPath;
+ } elsif ($deletion) {
+ # Reverse deletion
+ rename($fullPath, "$fullPath.orig") if -e $fullPath;
+
+ unapplyPatch($patch, $fullPath);
+
+ # If we don't ask for the filehandle here, we always get a warning.
+ my ($fh, $tempPath) = tempfile(basename($fullPath) . "-XXXXXXXX",
+ DIR => dirname($fullPath), UNLINK => 1);
+ close($fh);
+
+ # Keep the version from the patch in case it's different from svn.
+ rename($fullPath, $tempPath);
+ system "svn", "revert", $fullPath;
+ rename($tempPath, $fullPath);
+
+ # This works around a bug in the svn client.
+ # [Issue 1960] file modifications get lost due to FAT 2s time resolution
+ # http://subversion.tigris.org/issues/show_bug.cgi?id=1960
+ system "touch", $fullPath;
+
+ # Remove $fullPath.orig if it is the same as $fullPath
+ unlink("$fullPath.orig") if -e "$fullPath.orig" && checksum($fullPath) eq checksum("$fullPath.orig");
+
+ # Show status if the file is modifed
+ system "svn", "stat", $fullPath;
+ } else {
+ # Reverse addition
+ unapplyPatch($patch, $fullPath, ["--force"]);
+ unlink($fullPath) if -z $fullPath;
+ system "svn", "revert", $fullPath;
+ }
+ }
+}
+
+sub revertDirectories()
+{
+ my %checkedDirectories;
+ foreach my $path (reverse sort keys %directoriesToCheck) {
+ my @dirs = File::Spec->splitdir($path);
+ while (scalar @dirs) {
+ my $dir = File::Spec->catdir(@dirs);
+ pop(@dirs);
+ next if (exists $checkedDirectories{$dir});
+ if (-d $dir) {
+ my $svnOutput = svnStatus($dir);
+ if ($svnOutput && $svnOutput =~ m#A\s+$dir\n#) {
+ system "svn", "revert", $dir;
+ rmdir $dir;
+ }
+ elsif ($svnOutput && $svnOutput =~ m#D\s+$dir\n#) {
+ system "svn", "revert", $dir;
+ }
+ else {
+ # Modification
+ print $svnOutput if $svnOutput;
+ }
+ $checkedDirectories{$dir} = 1;
+ }
+ else {
+ die "'$dir' is not a directory";
+ }
+ }
+ }
+}
+
+sub svnStatus($)
+{
+ my ($fullPath) = @_;
+ my $svnStatus;
+ open SVN, "svn status --non-interactive --non-recursive '$fullPath' |" or die;
+ if (-d $fullPath) {
+ # When running "svn stat" on a directory, we can't assume that only one
+ # status will be returned (since any files with a status below the
+ # directory will be returned), and we can't assume that the directory will
+ # be first (since any files with unknown status will be listed first).
+ my $normalizedFullPath = File::Spec->catdir(File::Spec->splitdir($fullPath));
+ while (<SVN>) {
+ chomp;
+ my $normalizedStatPath = File::Spec->catdir(File::Spec->splitdir(substr($_, 7)));
+ if ($normalizedFullPath eq $normalizedStatPath) {
+ $svnStatus = $_;
+ last;
+ }
+ }
+ # Read the rest of the svn command output to avoid a broken pipe warning.
+ local $/ = undef;
+ <SVN>;
+ }
+ else {
+ # Files will have only one status returned.
+ $svnStatus = <SVN>;
+ }
+ close SVN;
+ return $svnStatus;
+}
+
+sub unapplyPatch($$;$)
+{
+ my ($patch, $fullPath, $options) = @_;
+ $options = [] if (! $options);
+ my $command = "patch " . join(" ", "-p0", "-R", @{$options});
+ open PATCH, "| $command" or die "Failed to patch $fullPath: $!";
+ print PATCH $patch;
+ close PATCH;
+}
+
+sub unsetChangeLogDate($$)
+{
+ my $fullPath = shift;
+ my $patch = shift;
+ my $newDate;
+ sysopen(CHANGELOG, $fullPath, O_RDONLY) or die "Failed to open $fullPath: $!";
+ sysseek(CHANGELOG, 0, SEEK_SET);
+ my $byteCount = sysread(CHANGELOG, $newDate, 10);
+ die "Failed reading $fullPath: $!" if !$byteCount || $byteCount != 10;
+ close(CHANGELOG);
+ $patch =~ s/(\n\+)\d{4}-[^-]{2}-[^-]{2}( )/$1$newDate$2/;
+ return $patch;
+}
diff --git a/WebKitTools/Scripts/update-iexploder-cssproperties b/WebKitTools/Scripts/update-iexploder-cssproperties
new file mode 100755
index 0000000..b7ae6cb
--- /dev/null
+++ b/WebKitTools/Scripts/update-iexploder-cssproperties
@@ -0,0 +1,112 @@
+#!/usr/bin/perl
+
+# 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 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.
+
+# This script updates WebKitTools/iExploder/htdocs/cssproperties.in based on
+# WebCore/css/CSSPropertyNames.in.
+
+use warnings;
+use strict;
+
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+
+use File::Spec;
+
+sub generateSectionFromCSSPropertyNamesFile();
+sub readiExploderFile();
+sub svnRevision($);
+sub writeiExploderFile();
+
+my $iExploderFile = File::Spec->catfile(sourceDir(), split("/", "WebKitTools/iExploder/htdocs/cssproperties.in"));
+my $cssPropertyNamesFile = File::Spec->catfile(sourceDir(), split("/", "WebCore/css/CSSPropertyNames.in"));
+
+my @sections = readiExploderFile();
+$sections[0] = generateSectionFromCSSPropertyNamesFile();
+writeiExploderFile();
+
+print `svn stat $iExploderFile`;
+print "Successfully updated!\n";
+
+exit 0;
+
+sub generateSectionFromCSSPropertyNamesFile()
+{
+ my $revision = svnRevision($cssPropertyNamesFile);
+ my $path = File::Spec->abs2rel($cssPropertyNamesFile, sourceDir());
+ my $result = "# From WebKit svn r" . $revision . " (" . $path . ")\n";
+
+ my @properties = ();
+
+ open(IN, $cssPropertyNamesFile) || die "$!";
+ while (my $l = <IN>) {
+ chomp $l;
+ next if $l =~ m/^\s*#/ || $l =~ m/^\s*$/;
+ push(@properties, $l);
+ }
+ close(IN);
+
+ $result .= join("\n", sort { $a cmp $b } @properties) . "\n\n";
+
+ return $result;
+}
+
+sub readiExploderFile()
+{
+ my @sections = ();
+ local $/ = "\n\n";
+
+ open(IN, $iExploderFile) || die "$!";
+ @sections = <IN>;
+ close(IN);
+
+ return @sections;
+}
+
+sub svnRevision($)
+{
+ my ($file) = @_;
+ my $revision = "";
+
+ open INFO, "svn info '$file' |" or die;
+ while (<INFO>) {
+ if (/^Revision: (.+)/) {
+ $revision = $1;
+ }
+ }
+ close INFO;
+
+ return $revision ? $revision : "UNKNOWN";
+}
+
+sub writeiExploderFile()
+{
+ open(OUT, "> $iExploderFile") || die "$!";
+ print OUT join("", @sections);
+ close(OUT);
+}
diff --git a/WebKitTools/Scripts/update-javascriptcore-test-results b/WebKitTools/Scripts/update-javascriptcore-test-results
new file mode 100755
index 0000000..dd8b9b6
--- /dev/null
+++ b/WebKitTools/Scripts/update-javascriptcore-test-results
@@ -0,0 +1,73 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005, 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.
+
+use strict;
+use FindBin;
+use Getopt::Long;
+use lib $FindBin::Bin;
+use webkitdirs;
+
+chdirWebKit();
+chdir "JavaScriptCore/tests/mozilla" or die;
+
+my $force = 0;
+GetOptions('force' => \$force);
+
+open EXPECTED, "expected.html" or die;
+while (<EXPECTED>) {
+ last if /failures reported\.$/;
+}
+my %expected;
+while (<EXPECTED>) {
+ chomp;
+ $expected{$_} = 1;
+}
+close EXPECTED;
+
+open ACTUAL, "actual.html" or die;
+my $actual;
+while (<ACTUAL>) {
+ $actual .= $_;
+ last if /failures reported\.$/;
+}
+my $failed = 0;
+while (<ACTUAL>) {
+ $actual .= $_;
+ chomp;
+ if (!$expected{$_}) {
+ $failed = 1;
+ print "failure not expected: $_\n";
+ }
+}
+close ACTUAL;
+
+die "won't update, failures introduced\n" if $failed && !$force;
+
+open EXPECTED, ">expected.html";
+print EXPECTED $actual;
+close EXPECTED;
diff --git a/WebKitTools/Scripts/update-webkit b/WebKitTools/Scripts/update-webkit
new file mode 100755
index 0000000..6d974b1
--- /dev/null
+++ b/WebKitTools/Scripts/update-webkit
@@ -0,0 +1,92 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005, 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.
+# 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.
+
+# Update script for Web Kit Open Source Project.
+
+use strict;
+use FindBin;
+use lib $FindBin::Bin;
+use File::Basename;
+use File::Spec;
+use Getopt::Long;
+use webkitdirs;
+
+sub runSvnUpdate();
+
+# Handle options
+my $quiet = '';
+my $showHelp;
+
+my $getOptionsResult = GetOptions(
+ 'h|help' => \$showHelp,
+ 'q|quiet' => \$quiet,
+);
+
+if (!$getOptionsResult || $showHelp) {
+ print STDERR <<__END__;
+Usage: @{[ basename($0) ]} [options]
+ -h|--help show the help message
+ -q|--quiet pass -q to svn update for quiet updates
+__END__
+ exit 1;
+}
+
+my @svnOptions = ();
+push @svnOptions, '-q' if $quiet;
+
+chdirWebKit();
+print "Updating OpenSource\n" unless $quiet;
+runSvnUpdate();
+
+if (-d "../Internal") {
+ chdir("../Internal");
+ print "Updating Internal\n" unless $quiet;
+ runSvnUpdate();
+} elsif (isCygwin()) {
+ system("perl", "WebKitTools/Scripts/update-webkit-auxiliary-libs") == 0 or die;
+}
+
+exit 0;
+
+sub runSvnUpdate()
+{
+ open UPDATE, "-|", "svn", "update", @svnOptions or die;
+ my @conflictedChangeLogs;
+ while (my $line = <UPDATE>) {
+ print $line;
+ push @conflictedChangeLogs, $1 if $line =~ m/^C\s+(.+)\s*$/ && basename($1) eq "ChangeLog";
+ }
+ close UPDATE;
+
+ if (@conflictedChangeLogs) {
+ print "Attempting to merge conflicted ChangeLogs.\n";
+ my $resolveChangeLogsPath = File::Spec->catfile(dirname($0), "resolve-ChangeLogs");
+ (system($resolveChangeLogsPath, "--no-warnings", @conflictedChangeLogs) == 0)
+ or die "Could not open resolve-ChangeLogs script: $!.\n";
+ }
+}
diff --git a/WebKitTools/Scripts/update-webkit-auxiliary-libs b/WebKitTools/Scripts/update-webkit-auxiliary-libs
new file mode 100755
index 0000000..1d6943c
--- /dev/null
+++ b/WebKitTools/Scripts/update-webkit-auxiliary-libs
@@ -0,0 +1,121 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005, 2006, 2007 Apple Computer, 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.
+
+# Updates a development environment to the new WebKitAuxiliaryLibrary
+
+use strict;
+use warnings;
+
+use HTTP::Date qw(str2time);
+use File::Find;
+use File::Temp;
+use File::Spec;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+
+sub lastModifiedToUnixTime($);
+
+# Time in seconds that the new zip file must be newer than the old for us to
+# consider them to be different. If the difference in modification time is less
+# than this threshold, we assume that the files are the same. We need this
+# because the zip file is served from a set of mirrors with slightly different
+# Last-Modified times.
+my $newnessThreshold = 30;
+
+my $sourceDir = sourceDir();
+my $file = "WebKitAuxiliaryLibrary";
+my $zipFile = "$file.zip";
+my $auxiliaryLibsURL = "http://developer.apple.com/opensource/internet/$zipFile";
+my $webkitLibrariesDir = toUnixPath($ENV{'WEBKITLIBRARIESDIR'}) || "$sourceDir/WebKitLibraries/win";
+my $tmpDir = File::Spec->rel2abs(File::Temp::tempdir("webkitlibsXXXXXXX", TMPDIR => 1, CLEANUP => 1));
+
+print "Checking Last-Modified date of $zipFile...\n";
+
+my $result = system "curl -s -I $auxiliaryLibsURL | grep Last-Modified > \"$tmpDir/$file.headers\"";
+print STDERR "Couldn't check Last-Modified date of new $zipFile.\n" if $result;
+
+if (!$result && open NEW, "$tmpDir/$file.headers") {
+ my $new = lastModifiedToUnixTime(<NEW>);
+ close NEW;
+
+ if (defined $new && open OLD, "$webkitLibrariesDir/$file.headers") {
+ my $old = lastModifiedToUnixTime(<OLD>);
+ close OLD;
+ if (defined $old && abs($new - $old) < $newnessThreshold) {
+ print "Current $file is up to date\n";
+ exit 0;
+ }
+ }
+}
+
+print "Downloading $zipFile...\n\n";
+$result = system "curl -o \"$tmpDir/$zipFile\" $auxiliaryLibsURL";
+die "Couldn't download $zipFile!" if $result;
+
+$result = system "unzip", "-q", "-d", $tmpDir, "$tmpDir/$zipFile";
+die "Couldn't unzip $zipFile." if $result;
+
+print "\nInstalling $file...\n";
+
+sub wanted
+{
+ my $relativeName = File::Spec->abs2rel($File::Find::name, "$tmpDir/$file/win");
+ my $destination = "$webkitLibrariesDir/$relativeName";
+
+ if (-d $_) {
+ mkdir $destination;
+ return;
+ }
+
+ system "cp", $_, $destination;
+}
+
+File::Find::find(\&wanted, "$tmpDir/$file");
+
+$result = system "mv", "$tmpDir/$file.headers", $webkitLibrariesDir;
+print STDERR "Couldn't move $file.headers to $webkitLibrariesDir" . ".\n" if $result;
+
+print "The $file has been sucessfully installed in\n $webkitLibrariesDir\n";
+exit;
+
+sub toUnixPath
+{
+ my $path = shift;
+ return unless $path;
+ chomp($path = `cygpath -u '$path'`);
+ return $path;
+}
+
+sub lastModifiedToUnixTime($)
+{
+ my ($str) = @_;
+
+ $str =~ /^Last-Modified: (.*)$/ or return;
+ return str2time($1);
+}
diff --git a/WebKitTools/Scripts/update-webkit-localizable-strings b/WebKitTools/Scripts/update-webkit-localizable-strings
new file mode 100755
index 0000000..53037a6
--- /dev/null
+++ b/WebKitTools/Scripts/update-webkit-localizable-strings
@@ -0,0 +1,45 @@
+#!/usr/bin/perl -w
+
+# 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.
+
+use strict;
+use warnings;
+
+use File::Basename;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+
+my @directoriesToScan = ("WebKit/mac", "WebKit/win");
+my $exceptionsFile = "WebKit/StringsNotToBeLocalized.txt";
+
+@ARGV == 0 or die "Usage: " . basename($0) . "\n";
+
+chdirWebKit();
+
+system "sort -u $exceptionsFile -o $exceptionsFile";
+exec "extract-localizable-strings", $exceptionsFile, @directoriesToScan;
diff --git a/WebKitTools/Scripts/update-webkit-support-libs b/WebKitTools/Scripts/update-webkit-support-libs
new file mode 100755
index 0000000..e9c302b
--- /dev/null
+++ b/WebKitTools/Scripts/update-webkit-support-libs
@@ -0,0 +1,105 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005, 2006, 2007 Apple Computer, 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.
+
+# Updates a development environment to the new WebKitSupportLibrary
+
+use strict;
+use warnings;
+
+use File::Find;
+use File::Temp;
+use File::Spec;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+
+my $sourceDir = sourceDir();
+my $file = "WebKitSupportLibrary";
+my $zipFile = "$file.zip";
+my $zipDirectory = toUnixPath($ENV{'WEBKITSUPPORTLIBRARIESZIPDIR'}) || $sourceDir;
+my $pathToZip = File::Spec->catfile($zipDirectory, $zipFile);
+my $webkitLibrariesDir = toUnixPath($ENV{'WEBKITLIBRARIESDIR'}) || "$sourceDir/WebKitLibraries/win";
+my $tmpDir = File::Spec->rel2abs(File::Temp::tempdir("webkitlibsXXXXXXX", TMPDIR => 1, CLEANUP => 1));
+
+# Make sure the file zipfile exists before doing anything.
+die "$zipFile could not be found in your root source directory. Please\n" .
+ "download it from http://developer.apple.com/opensource/internet/webkit_sptlib_agree.html and place it in \n" .
+ "$sourceDir\n and then run update-webkit again.\n" unless (-f "$pathToZip");
+
+print "Checking mod-date of $zipFile...\n";
+open MOD, ">$tmpDir/$file.modified" or die "Couldn't open $tmpDir/$file.modified for writing";
+print MOD (stat $pathToZip)[9] . "\n";
+close MOD;
+
+if (open NEW, "$tmpDir/$file.modified") {
+ my $new = <NEW>;
+ close NEW;
+
+ if (open OLD, "$webkitLibrariesDir/$file.modified") {
+ my $old = <OLD>;
+ close OLD;
+ if ($old eq $new) {
+ print "Current $file is up to date\n";
+ exit 0;
+ }
+ }
+}
+
+my $result = system "unzip", "-q", "-d", $tmpDir, $pathToZip;
+die "Couldn't unzip $zipFile." if $result;
+
+print "\nInstalling $file...\n";
+
+sub wanted
+{
+ my $relativeName = File::Spec->abs2rel($File::Find::name, "$tmpDir/$file/win");
+ my $destination = "$webkitLibrariesDir/$relativeName";
+
+ if (-d $_) {
+ mkdir $destination;
+ return;
+ }
+
+ system "cp", $_, $destination;
+}
+
+File::Find::find(\&wanted, "$tmpDir/$file");
+
+$result = system "mv", "$tmpDir/$file.modified", $webkitLibrariesDir;
+print STDERR "Couldn't move $file.modified to $webkitLibrariesDir" . ".\n" if $result;
+
+print "The $file has been sucessfully installed in\n $webkitLibrariesDir\n";
+exit;
+
+sub toUnixPath
+{
+ my $path = shift;
+ return unless $path;
+ chomp($path = `cygpath -u '$path'`);
+ return $path;
+}
diff --git a/WebKitTools/Scripts/webkitdirs.pm b/WebKitTools/Scripts/webkitdirs.pm
new file mode 100644
index 0000000..478da8a
--- /dev/null
+++ b/WebKitTools/Scripts/webkitdirs.pm
@@ -0,0 +1,947 @@
+# Copyright (C) 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.
+# 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 to share code to get to WebKit directories.
+
+use strict;
+use warnings;
+use FindBin;
+use File::Basename;
+use POSIX;
+use VCSUtils;
+
+BEGIN {
+ use Exporter ();
+ our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
+ $VERSION = 1.00;
+ @ISA = qw(Exporter);
+ @EXPORT = qw(&chdirWebKit &baseProductDir &productDir &XcodeOptions &XcodeOptionString &XcodeOptionStringNoConfig &passedConfiguration &setConfiguration &safariPath &checkFrameworks &currentSVNRevision);
+ %EXPORT_TAGS = ( );
+ @EXPORT_OK = ();
+}
+
+our @EXPORT_OK;
+
+my $baseProductDir;
+my @baseProductDirOption;
+my $configuration;
+my $configurationForVisualStudio;
+my $configurationProductDir;
+my $sourceDir;
+my $currentSVNRevision;
+my $osXVersion;
+my $isQt;
+my $isGtk;
+my $isWx;
+
+# Variables for Win32 support
+my $vcBuildPath;
+my $windowsTmpPath;
+
+sub determineSourceDir
+{
+ return if $sourceDir;
+ $sourceDir = $FindBin::Bin;
+
+ # walks up path checking each directory to see if it is the main WebKit project dir,
+ # defined by containing JavaScriptCore, WebCore, and WebKit
+ until ((-d "$sourceDir/JavaScriptCore" && -d "$sourceDir/WebCore" && -d "$sourceDir/WebKit") || (-d "$sourceDir/Internal" && -d "$sourceDir/OpenSource"))
+ {
+ if ($sourceDir !~ s|/[^/]+$||) {
+ die "Could not find top level webkit directory above source directory using FindBin.\n";
+ }
+ }
+
+ $sourceDir = "$sourceDir/OpenSource" if -d "$sourceDir/OpenSource";
+}
+
+# used for scripts which are stored in a non-standard location
+sub setSourceDir($)
+{
+ ($sourceDir) = @_;
+}
+
+sub determineBaseProductDir
+{
+ return if defined $baseProductDir;
+ determineSourceDir();
+ if (isOSX()) {
+ open PRODUCT, "defaults read com.apple.Xcode PBXApplicationwideBuildSettings 2> /dev/null |" or die;
+ $baseProductDir = join '', <PRODUCT>;
+ close PRODUCT;
+
+ $baseProductDir = $1 if $baseProductDir =~ /SYMROOT\s*=\s*\"(.*?)\";/s;
+ undef $baseProductDir unless $baseProductDir =~ /^\//;
+
+ if (!defined($baseProductDir)) {
+ open PRODUCT, "defaults read com.apple.Xcode PBXProductDirectory 2> /dev/null |" or die;
+ $baseProductDir = <PRODUCT>;
+ close PRODUCT;
+ if ($baseProductDir) {
+ chomp $baseProductDir;
+ undef $baseProductDir unless $baseProductDir =~ /^\//;
+ }
+ }
+ } else {
+ $baseProductDir = $ENV{"WEBKITOUTPUTDIR"};
+ if (isCygwin() && $baseProductDir) {
+ my $unixBuildPath = `cygpath --unix \"$baseProductDir\"`;
+ chomp $unixBuildPath;
+ $baseProductDir = $unixBuildPath;
+ }
+ }
+
+ if ($baseProductDir && isOSX()) {
+ $baseProductDir =~ s|^\Q$(SRCROOT)/..\E$|$sourceDir|;
+ $baseProductDir =~ s|^\Q$(SRCROOT)/../|$sourceDir/|;
+ $baseProductDir =~ s|^~/|$ENV{HOME}/|;
+ die "Can't handle Xcode product directory with a ~ in it.\n" if $baseProductDir =~ /~/;
+ die "Can't handle Xcode product directory with a variable in it.\n" if $baseProductDir =~ /\$/;
+ @baseProductDirOption = ();
+ }
+
+ if (!defined($baseProductDir)) {
+ $baseProductDir = "$sourceDir/WebKitBuild";
+
+ if (isGit() && isGitBranchBuild()) {
+ my $branch = gitBranch();
+ $baseProductDir = "$baseProductDir/$branch";
+ }
+
+ @baseProductDirOption = ("SYMROOT=$baseProductDir", "OBJROOT=$baseProductDir") if (isOSX());
+ if (isCygwin()) {
+ my $dosBuildPath = `cygpath --windows \"$baseProductDir\"`;
+ chomp $dosBuildPath;
+ $ENV{"WEBKITOUTPUTDIR"} = $dosBuildPath;
+ }
+ }
+}
+
+sub setBaseProductDir($)
+{
+ ($baseProductDir) = @_;
+}
+
+sub determineConfiguration
+{
+ return if defined $configuration;
+ determineBaseProductDir();
+ if (open CONFIGURATION, "$baseProductDir/Configuration") {
+ $configuration = <CONFIGURATION>;
+ close CONFIGURATION;
+ }
+ if ($configuration) {
+ chomp $configuration;
+ # compatibility for people who have old Configuration files
+ $configuration = "Release" if $configuration eq "Deployment";
+ $configuration = "Debug" if $configuration eq "Development";
+ } else {
+ $configuration = "Release";
+ }
+}
+
+sub determineConfigurationForVisualStudio
+{
+ return if defined $configurationForVisualStudio;
+ determineConfiguration();
+ $configurationForVisualStudio = $configuration;
+ return unless $configuration eq "Debug";
+ setupCygwinEnv();
+ chomp(my $dir = `cygpath -ua '$ENV{WEBKITLIBRARIESDIR}'`);
+ $configurationForVisualStudio = "Debug_Internal" if -f "$dir/bin/CoreFoundation_debug.dll";
+}
+
+sub determineConfigurationProductDir
+{
+ return if defined $configurationProductDir;
+ determineBaseProductDir();
+ if(isCygwin() && !isWx()) {
+ $configurationProductDir = "$baseProductDir/bin";
+ } else {
+ determineConfiguration();
+ $configurationProductDir = "$baseProductDir/$configuration";
+ }
+}
+
+sub setConfigurationProductDir($)
+{
+ ($configurationProductDir) = @_;
+}
+
+sub determineCurrentSVNRevision
+{
+ return if defined $currentSVNRevision;
+ determineSourceDir();
+ my $svnInfo = `LC_ALL=C svn info $sourceDir | grep Revision:`;
+ ($currentSVNRevision) = ($svnInfo =~ m/Revision: (\d+).*/g);
+ die "Unable to determine current SVN revision in $sourceDir" unless (defined $currentSVNRevision);
+ return $currentSVNRevision;
+}
+
+
+sub chdirWebKit
+{
+ determineSourceDir();
+ chdir $sourceDir or die;
+}
+
+sub baseProductDir
+{
+ determineBaseProductDir();
+ return $baseProductDir;
+}
+
+sub sourceDir
+{
+ determineSourceDir();
+ return $sourceDir;
+}
+
+sub productDir
+{
+ determineConfigurationProductDir();
+ return $configurationProductDir;
+}
+
+sub configuration()
+{
+ determineConfiguration();
+ return $configuration;
+}
+
+sub configurationForVisualStudio()
+{
+ determineConfigurationForVisualStudio();
+ return $configurationForVisualStudio;
+}
+
+sub currentSVNRevision
+{
+ determineCurrentSVNRevision();
+ return $currentSVNRevision;
+}
+
+sub XcodeOptions
+{
+ determineBaseProductDir();
+ determineConfiguration();
+ return (@baseProductDirOption, "-configuration", $configuration);
+}
+
+sub XcodeOptionString
+{
+ return join " ", XcodeOptions();
+}
+
+sub XcodeOptionStringNoConfig
+{
+ return join " ", @baseProductDirOption;
+}
+
+my $passedConfiguration;
+my $searchedForPassedConfiguration;
+sub determinePassedConfiguration
+{
+ return if $searchedForPassedConfiguration;
+ $searchedForPassedConfiguration = 1;
+ for my $i (0 .. $#ARGV) {
+ my $opt = $ARGV[$i];
+ if ($opt =~ /^--debug$/i || $opt =~ /^--devel/i) {
+ splice(@ARGV, $i, 1);
+ $passedConfiguration = "Debug";
+ return;
+ }
+ if ($opt =~ /^--release$/i || $opt =~ /^--deploy/i) {
+ splice(@ARGV, $i, 1);
+ $passedConfiguration = "Release";
+ return;
+ }
+ }
+ $passedConfiguration = undef;
+}
+
+sub passedConfiguration
+{
+ determinePassedConfiguration();
+ return $passedConfiguration;
+}
+
+sub setConfiguration
+{
+ if (my $config = shift @_) {
+ $configuration = $config;
+ return;
+ }
+
+ determinePassedConfiguration();
+ $configuration = $passedConfiguration if $passedConfiguration;
+}
+
+sub safariPathFromSafariBundle
+{
+ my ($safariBundle) = @_;
+
+ return "$safariBundle/Contents/MacOS/Safari" if isOSX();
+ return $safariBundle if isCygwin();
+}
+
+sub installedSafariPath
+{
+ my $safariBundle;
+
+ if (isOSX()) {
+ $safariBundle = "/Applications/Safari.app";
+ } elsif (isCygwin()) {
+ $safariBundle = `"$configurationProductDir/FindSafari.exe"`;
+ $safariBundle =~ s/[\r\n]+$//;
+ $safariBundle = `cygpath -u '$safariBundle'`;
+ $safariBundle =~ s/[\r\n]+$//;
+ $safariBundle .= "Safari.exe";
+ }
+
+ return safariPathFromSafariBundle($safariBundle);
+}
+
+# Locate Safari.
+sub safariPath
+{
+ # Use WEBKIT_SAFARI environment variable if present.
+ my $safariBundle = $ENV{WEBKIT_SAFARI};
+ if (!$safariBundle) {
+ determineConfigurationProductDir();
+ # Use Safari.app in product directory if present (good for Safari development team).
+ if (isOSX() && -d "$configurationProductDir/Safari.app") {
+ $safariBundle = "$configurationProductDir/Safari.app";
+ } elsif (isCygwin() && -x "$configurationProductDir/bin/Safari.exe") {
+ $safariBundle = "$configurationProductDir/bin/Safari.exe";
+ } else {
+ return installedSafariPath();
+ }
+ }
+ my $safariPath = safariPathFromSafariBundle($safariBundle);
+ die "Can't find executable at $safariPath.\n" if isOSX() && !-x $safariPath;
+ return $safariPath;
+}
+
+sub builtDylibPathForName
+{
+ my $framework = shift;
+ determineConfigurationProductDir();
+ if (isQt() or isGtk()) {
+ return "$configurationProductDir/$framework";
+ }
+ if (isOSX()) {
+ return "$configurationProductDir/$framework.framework/Versions/A/$framework";
+ }
+ if (isCygwin()) {
+ if ($framework eq "JavaScriptCore") {
+ return "$baseProductDir/lib/$framework.lib";
+ } else {
+ return "$baseProductDir/$framework.intermediate/$configuration/$framework.intermediate/$framework.lib";
+ }
+ }
+
+ die "Unsupported platform, can't determine built library locations.";
+}
+
+# Check to see that all the frameworks are built.
+sub checkFrameworks
+{
+ return if isCygwin();
+ my @frameworks = ("JavaScriptCore", "WebCore");
+ push(@frameworks, "WebKit") if isOSX();
+ for my $framework (@frameworks) {
+ my $path = builtDylibPathForName($framework);
+ die "Can't find built framework at \"$path\".\n" unless -x $path;
+ }
+}
+
+sub hasSVGSupport
+{
+ return 0 if isCygwin();
+
+ my $path = shift;
+
+ if (isQt()) {
+ return 1;
+ }
+
+ if (isGtk() and $path =~ /WebCore/) {
+ $path .= "/../lib/libWebKitGtk.so" if !$ENV{WEBKITAUTOTOOLS};
+ $path .= "/../.libs/libWebKitGtk.so" if $ENV{WEBKITAUTOTOOLS};
+ }
+
+ my $hasSVGSupport = 0;
+ if (-e $path) {
+ open NM, "-|", "nm", $path or die;
+ while (<NM>) {
+ $hasSVGSupport = 1 if /SVGElement/;
+ }
+ close NM;
+ }
+ return $hasSVGSupport;
+}
+
+sub removeLibraryDependingOnSVG
+{
+ my $frameworkName = shift;
+ my $shouldHaveSVG = shift;
+
+ my $path = builtDylibPathForName($frameworkName);
+ return unless -x $path;
+
+ my $hasSVG = hasSVGSupport($path);
+ system "rm -f $path" if ($shouldHaveSVG xor $hasSVG);
+}
+
+sub checkWebCoreSVGSupport
+{
+ my $required = shift;
+ my $framework = "WebCore";
+ my $path = builtDylibPathForName($framework);
+ my $hasSVG = hasSVGSupport($path);
+ if ($required && !$hasSVG) {
+ die "$framework at \"$path\" does not include SVG Support, please run build-webkit --svg\n";
+ }
+ return $hasSVG;
+}
+
+sub isQt()
+{
+ determineIsQt();
+ return $isQt;
+}
+
+sub checkArgv($)
+{
+ my $argToCheck = shift;
+ foreach my $opt (@ARGV) {
+ if ($opt =~ /^$argToCheck/i ) {
+ @ARGV = grep(!/^$argToCheck/i, @ARGV);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+sub determineIsQt()
+{
+ return if defined($isQt);
+
+ # Allow override in case QTDIR is not set.
+ if (checkArgv("--qt")) {
+ $isQt = 1;
+ return;
+ }
+
+ # The presence of QTDIR only means Qt if --gtk is not on the command-line
+ if (isGtk()) {
+ $isQt = 0;
+ return;
+ }
+
+ $isQt = defined($ENV{'QTDIR'});
+}
+
+sub isGtk()
+{
+ determineIsGtk();
+ return $isGtk;
+}
+
+sub determineIsGtk()
+{
+ return if defined($isGtk);
+
+ if (checkArgv("--gtk")) {
+ $isGtk = 1;
+ } else {
+ $isGtk = 0;
+ }
+}
+
+sub isWx()
+{
+ determineIsWx();
+ return $isWx;
+}
+
+sub determineIsWx()
+{
+ return if defined($isWx);
+
+ if (checkArgv("--wx")) {
+ $isWx = 1;
+ } else {
+ $isWx = 0;
+ }
+}
+
+# Determine if this is debian, ubuntu, linspire, or something similar.
+sub isDebianBased()
+{
+ return -e "/etc/debian_version";
+}
+
+sub isCygwin()
+{
+ return ($^O eq "cygwin");
+}
+
+sub isDarwin()
+{
+ return ($^O eq "darwin");
+}
+
+sub isOSX()
+{
+ return isDarwin() unless (isQt() or isGtk() or isWx());
+ return 0;
+}
+
+sub determineOSXVersion()
+{
+ return if $osXVersion;
+
+ if (!isOSX()) {
+ $osXVersion = -1;
+ return;
+ }
+
+ my $version = `sw_vers -productVersion`;
+ my @splitVersion = split(/\./, $version);
+ @splitVersion >= 2 or die "Invalid version $version";
+ $osXVersion = {
+ "major" => $splitVersion[0],
+ "minor" => $splitVersion[1],
+ "subminor" => (defined($splitVersion[2]) ? $splitVersion[2] : 0),
+ };
+}
+
+sub osXVersion()
+{
+ determineOSXVersion();
+ return $osXVersion;
+}
+
+sub isTiger()
+{
+ return isOSX() && osXVersion()->{"minor"} == 4;
+}
+
+sub isLeopard()
+{
+ return isOSX() && osXVersion()->{"minor"} == 5;
+}
+
+sub relativeScriptsDir()
+{
+ my $scriptDir = File::Spec->catpath("", File::Spec->abs2rel(dirname($0), getcwd()), "");
+ if ($scriptDir eq "") {
+ $scriptDir = ".";
+ }
+ return $scriptDir;
+}
+
+sub launcherPath()
+{
+ my $relativeScriptsPath = relativeScriptsDir();
+ if (isGtk() || isQt()) {
+ return "$relativeScriptsPath/run-launcher";
+ } elsif (isOSX() || isCygwin()) {
+ return "$relativeScriptsPath/run-safari";
+ }
+}
+
+sub launcherName()
+{
+ if (isGtk()) {
+ return "GtkLauncher";
+ } elsif (isQt()) {
+ return "QtLauncher";
+ } elsif (isOSX() || isCygwin()) {
+ return "Safari";
+ }
+}
+
+sub checkRequiredSystemConfig
+{
+ if (isOSX()) {
+ chomp(my $productVersion = `sw_vers -productVersion`);
+ if ($productVersion lt "10.4") {
+ print "*************************************************************\n";
+ print "Mac OS X Version 10.4.0 or later is required to build WebKit.\n";
+ print "You have " . $productVersion . ", thus the build will most likely fail.\n";
+ print "*************************************************************\n";
+ }
+ my $xcodeVersion = `xcodebuild -version`;
+ if ($xcodeVersion !~ /DevToolsCore-(\d+)/ || $1 < 747) {
+ print "*************************************************************\n";
+ print "Xcode Version 2.3 or later is required to build WebKit.\n";
+ print "You have an earlier version of Xcode, thus the build will\n";
+ print "most likely fail. The latest Xcode is available from the web:\n";
+ print "http://developer.apple.com/tools/xcode\n";
+ print "*************************************************************\n";
+ }
+ } elsif (isGtk() or isQt() or isWx()) {
+ my @cmds = qw(flex bison gperf);
+ my @missing = ();
+ foreach my $cmd (@cmds) {
+ if (not `$cmd --version`) {
+ push @missing, $cmd;
+ }
+ }
+ if (@missing) {
+ my $list = join ", ", @missing;
+ die "ERROR: $list missing but required to build WebKit.\n";
+ }
+ }
+ # Win32 and other platforms may want to check for minimum config
+}
+
+sub setupCygwinEnv()
+{
+ return if !isCygwin();
+ return if $vcBuildPath;
+
+ my $programFilesPath = `cygpath "$ENV{'PROGRAMFILES'}"`;
+ chomp $programFilesPath;
+ $vcBuildPath = "$programFilesPath/Microsoft Visual Studio 8/Common7/IDE/devenv.com";
+ if (! -e $vcBuildPath) {
+ # VC++ not found, try VC++ Express
+ my $vsInstallDir;
+ if ($ENV{'VSINSTALLDIR'}) {
+ $vsInstallDir = $ENV{'VSINSTALLDIR'};
+ } else {
+ $programFilesPath = $ENV{'PROGRAMFILES'} || "C:\\Program Files";
+ $vsInstallDir = "$programFilesPath/Microsoft Visual Studio 8";
+ }
+ $vsInstallDir = `cygpath "$vsInstallDir"`;
+ chomp $vsInstallDir;
+ $vcBuildPath = "$vsInstallDir/Common7/IDE/VCExpress.exe";
+ if (! -e $vcBuildPath) {
+ print "*************************************************************\n";
+ print "Cannot find '$vcBuildPath'\n";
+ print "Please execute the file 'vcvars32.bat' from\n";
+ print "'$programFilesPath\\Microsoft Visual Studio 8\\VC\\bin\\'\n";
+ print "to setup the necessary environment variables.\n";
+ print "*************************************************************\n";
+ die;
+ }
+ }
+
+ my $qtSDKPath = "$programFilesPath/QuickTime SDK";
+ if (0 && ! -e $qtSDKPath) {
+ print "*************************************************************\n";
+ print "Cannot find '$qtSDKPath'\n";
+ print "Please download the QuickTime SDK for Windows from\n";
+ print "http://developer.apple.com/quicktime/download/\n";
+ print "*************************************************************\n";
+ die;
+ }
+
+ chomp($ENV{'WEBKITLIBRARIESDIR'} = `cygpath -wa "$sourceDir/WebKitLibraries/win"`) unless $ENV{'WEBKITLIBRARIESDIR'};
+
+ $windowsTmpPath = `cygpath -w /tmp`;
+ chomp $windowsTmpPath;
+ print "Building results into: ", baseProductDir(), "\n";
+ print "WEBKITOUTPUTDIR is set to: ", $ENV{"WEBKITOUTPUTDIR"}, "\n";
+ print "WEBKITLIBRARIESDIR is set to: ", $ENV{"WEBKITLIBRARIESDIR"}, "\n";
+}
+
+sub buildVisualStudioProject
+{
+ my ($project, $clean) = @_;
+ setupCygwinEnv();
+
+ my $config = configurationForVisualStudio();
+
+ chomp(my $winProjectPath = `cygpath -w "$project"`);
+
+ my $command = "/build";
+ if ($clean) {
+ $command = "/clean";
+ }
+
+ print "$vcBuildPath $winProjectPath /build $config\n";
+ return system $vcBuildPath, $winProjectPath, $command, $config;
+}
+
+sub qtMakeCommand($)
+{
+ my ($qmakebin) = @_;
+ chomp(my $mkspec = `$qmakebin -query QMAKE_MKSPECS`);
+ $mkspec .= "/default";
+
+ my $compiler = "";
+ open SPEC, "<$mkspec/qmake.conf" or return "make";
+ while (<SPEC>) {
+ if ($_ =~ /QMAKE_CC\s*=\s*([^\s]+)/) {
+ $compiler = $1;
+ }
+ }
+ close SPEC;
+
+ #print "default spec: " . $mkspec . "\n";
+ #print "compiler found: " . $compiler . "\n";
+
+ if ($compiler eq "cl") {
+ return "nmake";
+ }
+
+ return "make";
+}
+
+sub autotoolsFlag($$)
+{
+ my ($flag, $feature) = @_;
+ my $prefix = $flag ? "--enable" : "--disable";
+
+ return $prefix . '-' . $feature;
+}
+
+sub buildAutotoolsProject($@)
+{
+ my ($clean, @buildArgs) = @_;
+
+ my $make = 'make';
+ my $dir = productDir();
+ my $config = passedConfiguration() || configuration();
+ my $prefix = $ENV{"WebKitInstallationPrefix"};
+
+ # check if configuration is Debug
+ if ($config =~ m/debug/i) {
+ push @buildArgs, "--enable-debug";
+ } else {
+ push @buildArgs, "--disable-debug";
+ }
+
+ if (! -d $dir) {
+ system "mkdir", "-p", "$dir";
+ if (! -d $dir) {
+ die "Failed to create build directory " . $dir;
+ }
+ }
+
+ chdir $dir or die "Failed to cd into " . $dir . "\n";
+
+ my $result;
+ if ($clean) {
+ $result = system $make, "distclean";
+ return $result;
+ }
+
+ print "Calling configure in " . $dir . "\n\n";
+ print "Installation directory: $prefix\n" if(defined($prefix));
+
+ $result = system "$sourceDir/autogen.sh", @buildArgs;
+ if ($result ne 0) {
+ die "Failed to setup build environment using 'autotools'!\n";
+ }
+
+ $result = system $make;
+ if ($result ne 0) {
+ die "\nFailed to build WebKit using '$make'!\n";
+ }
+
+ chdir ".." or die;
+ return $result;
+}
+
+sub buildQMakeProject($@)
+{
+ my ($clean, @buildArgs) = @_;
+
+ push @buildArgs, "-r";
+
+ my $qmakebin = "qmake"; # Allow override of the qmake binary from $PATH
+ for my $i (0 .. $#ARGV) {
+ my $opt = $ARGV[$i];
+ if ($opt =~ /^--qmake=(.*)/i ) {
+ $qmakebin = $1;
+ } elsif ($opt =~ /^--qmakearg=(.*)/i ) {
+ push @buildArgs, $1;
+ }
+ }
+
+ my $make = qtMakeCommand($qmakebin);
+ my $config = configuration();
+ my $prefix = $ENV{"WebKitInstallationPrefix"};
+
+ push @buildArgs, "OUTPUT_DIR=" . baseProductDir() . "/$config";
+ push @buildArgs, sourceDir() . "/WebKit.pro";
+ if ($config =~ m/debug/i) {
+ push @buildArgs, "CONFIG-=release";
+ push @buildArgs, "CONFIG+=debug";
+ } else {
+ push @buildArgs, "CONFIG+=release";
+ push @buildArgs, "CONFIG-=debug";
+ }
+
+ my $dir = baseProductDir();
+ if (! -d $dir) {
+ system "mkdir", "-p", "$dir";
+ if (! -d $dir) {
+ die "Failed to create product directory " . $dir;
+ }
+ }
+ $dir = $dir . "/$config";
+ if (! -d $dir) {
+ system "mkdir", "-p", "$dir";
+ if (! -d $dir) {
+ die "Failed to create build directory " . $dir;
+ }
+ }
+
+ chdir $dir or die "Failed to cd into " . $dir . "\n";
+
+ print "Calling '$qmakebin @buildArgs' in " . $dir . "\n\n";
+ print "Installation directory: $prefix\n" if(defined($prefix));
+
+ my $result = system $qmakebin, @buildArgs;
+ if ($result ne 0) {
+ die "Failed to setup build environment using $qmakebin!\n";
+ }
+
+ if ($clean) {
+ $result = system "$make distclean";
+ } else {
+ $result = system "$make";
+ }
+
+ chdir ".." or die;
+ return $result;
+}
+
+sub buildQMakeQtProject($$)
+{
+ my ($project, $clean) = @_;
+
+ my @buildArgs = ("CONFIG+=qt-port");
+ return buildQMakeProject($clean, @buildArgs);
+}
+
+sub buildGtkProject($$@)
+{
+ my ($project, $clean, @buildArgs) = @_;
+
+ if ($project ne "WebKit") {
+ die "The Gtk port builds JavaScriptCore, WebCore and WebKit in one shot! Only call it for 'WebKit'.\n";
+ }
+
+ if ($ENV{WEBKITAUTOTOOLS}) {
+ return buildAutotoolsProject($clean, @buildArgs);
+ } else {
+ my @buildArgs = ("CONFIG+=gtk-port", "CONFIG-=qt");
+ return buildQMakeProject($clean, @buildArgs);
+ }
+}
+
+sub setPathForRunningWebKitApp
+{
+ my ($env) = @_;
+
+ return unless isCygwin();
+
+ $env->{PATH} = join(':', productDir(), dirname(installedSafariPath()), $env->{PATH} || "");
+}
+
+sub exitStatus($)
+{
+ my ($returnvalue) = @_;
+ if ($^O eq "MSWin32") {
+ return $returnvalue >> 8;
+ }
+ return WEXITSTATUS($returnvalue);
+}
+
+sub runSafari
+{
+ my ($debugger) = @_;
+
+ if (isOSX()) {
+ return system "$FindBin::Bin/gdb-safari", @ARGV if $debugger;
+
+ my $productDir = productDir();
+ print "Starting Safari with DYLD_FRAMEWORK_PATH set to point to built WebKit in $productDir.\n";
+ $ENV{DYLD_FRAMEWORK_PATH} = $productDir;
+ $ENV{WEBKIT_UNSET_DYLD_FRAMEWORK_PATH} = "YES";
+ return system safariPath(), @ARGV;
+ }
+
+ if (isCygwin()) {
+ my $script = "run-webkit-nightly.cmd";
+ my $result = system "cp", "$FindBin::Bin/$script", productDir();
+ return $result if $result;
+
+ my $cwd = getcwd();
+ chdir productDir();
+
+ my $debuggerFlag = $debugger ? "/debugger" : "";
+ $result = system "cmd", "/c", "call $script $debuggerFlag";
+ chdir $cwd;
+ return $result;
+ }
+
+ return 1;
+}
+
+sub runDrosera
+{
+ my ($debugger) = @_;
+
+ if (isOSX()) {
+ return system "$FindBin::Bin/gdb-drosera", @ARGV if $debugger;
+
+ my $productDir = productDir();
+ print "Starting Drosera with DYLD_FRAMEWORK_PATH set to point to built WebKit in $productDir.\n";
+ $ENV{DYLD_FRAMEWORK_PATH} = $productDir;
+ $ENV{WEBKIT_UNSET_DYLD_FRAMEWORK_PATH} = "YES";
+
+ my $droseraPath = "$productDir/Drosera.app/Contents/MacOS/Drosera";
+ return system $droseraPath, @ARGV;
+ }
+
+ if (isCygwin()) {
+ print "Running Drosera\n";
+ my $script = "run-drosera-nightly.cmd";
+ my $prodDir = productDir();
+ my $result = system "cp", "$FindBin::Bin/$script", $prodDir;
+ return $result if $result;
+
+ my $cwd = getcwd();
+ chdir $prodDir;
+
+ my $debuggerFlag = $debugger ? "/debugger" : "";
+ $result = system "cmd", "/c", "call $script $debuggerFlag";
+ chdir $cwd;
+ return $result;
+ }
+
+ return 1;
+}
+
+1;
diff --git a/WebKitTools/Scripts/wkstyle b/WebKitTools/Scripts/wkstyle
new file mode 100755
index 0000000..690b5fa
--- /dev/null
+++ b/WebKitTools/Scripts/wkstyle
@@ -0,0 +1,66 @@
+
+# Copyright (C) 2006 Michael Emmel<mike.emmel@gmail.com> All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 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.
+
+astyle \
+--style=linux \
+--indent=spaces=4 \
+--convert-tabs \
+$@
+
+#astyle does not support unpadding so we use sed
+for i in $@
+do
+echo $i
+#first print the changes we are making
+sed -n -e '
+/( .*/p
+s/( /(/gp
+/*. )/p
+s/ )/)/gp
+#supress printing this
+#/^namespace WebCore/{
+#N
+#s/\n{/ {/p
+#}
+' $i
+
+#do it for real
+sed -e '
+#unpad leading spaces
+s/( /(/g
+#unpad traling spaces
+s/ )/)/g
+#fixup the namspec decl
+/^namespace WebCore/{
+N
+s/\n{/ {/
+}
+' $i > $i.sed
+mv $i.sed $i
+done
+
+
diff --git a/WebKitTools/WebKitLauncher/Info.plist b/WebKitTools/WebKitLauncher/Info.plist
new file mode 100644
index 0000000..9317bd4
--- /dev/null
+++ b/WebKitTools/WebKitLauncher/Info.plist
@@ -0,0 +1,476 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleDocumentTypes</key>
+ <array>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>css</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>document.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>text/css</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>CSS style sheet</string>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>NSDocumentClass</key>
+ <string>BrowserDocument</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>pdf</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>document.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>application/pdf</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>PDF document</string>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>NSDocumentClass</key>
+ <string>BrowserDocument</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>webarchive</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>webarchive.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>application/x-webarchive</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>Web archive</string>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>NSDocumentClass</key>
+ <string>BrowserDocument</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>syndarticle</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>document.icns</string>
+ <key>CFBundleTypeName</key>
+ <string>RSS article</string>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>NSDocumentClass</key>
+ <string>BrowserDocument</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>webbookmark</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>document.icns</string>
+ <key>CFBundleTypeName</key>
+ <string>Safari bookmark</string>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>NSDocumentClass</key>
+ <string>BrowserDocument</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>webloc</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>document.icns</string>
+ <key>CFBundleTypeName</key>
+ <string>Web internet location</string>
+ <key>CFBundleTypeOSTypes</key>
+ <array>
+ <string>ilht</string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>NSDocumentClass</key>
+ <string>BrowserDocument</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>download</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>download10.icns</string>
+ <key>CFBundleTypeName</key>
+ <string>Safari download</string>
+ <key>CFBundleTypeRole</key>
+ <string>Editor</string>
+ <key>LSTypeIsPackage</key>
+ <true/>
+ <key>NSDocumentClass</key>
+ <string>BrowserDocument</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>gif</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>document.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>image/gif</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>GIF image</string>
+ <key>CFBundleTypeOSTypes</key>
+ <array>
+ <string>GIFf</string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>NSDocumentClass</key>
+ <string>BrowserDocument</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>html</string>
+ <string>htm</string>
+ <string>shtml</string>
+ <string>jhtml</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>document.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>text/html</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>HTML document</string>
+ <key>CFBundleTypeOSTypes</key>
+ <array>
+ <string>HTML</string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>NSDocumentClass</key>
+ <string>BrowserDocument</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>js</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>document.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>application/x-javascript</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>JavaScript script</string>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>NSDocumentClass</key>
+ <string>BrowserDocument</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>jpg</string>
+ <string>jpeg</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>document.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>image/jpeg</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>JPEG image</string>
+ <key>CFBundleTypeOSTypes</key>
+ <array>
+ <string>JPEG</string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>NSDocumentClass</key>
+ <string>BrowserDocument</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>jp2</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>document.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>image/jp2</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>JPEG 2000 image</string>
+ <key>CFBundleTypeOSTypes</key>
+ <array>
+ <string>jp2 </string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>NSDocumentClass</key>
+ <string>BrowserDocument</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>txt</string>
+ <string>text</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>document.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>text/plain</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>Plain text document</string>
+ <key>CFBundleTypeOSTypes</key>
+ <array>
+ <string>TEXT</string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>NSDocumentClass</key>
+ <string>BrowserDocument</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>png</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>document.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>image/png</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>PNG image</string>
+ <key>CFBundleTypeOSTypes</key>
+ <array>
+ <string>PNGf</string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>NSDocumentClass</key>
+ <string>BrowserDocument</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>rtf</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>document.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>application/rtf</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>Rich Text Format (RTF) document</string>
+ <key>CFBundleTypeOSTypes</key>
+ <array>
+ <string>RTF </string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>NSDocumentClass</key>
+ <string>BrowserDocument</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>tiff</string>
+ <string>tif</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>document.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>image/tiff</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>TIFF image</string>
+ <key>CFBundleTypeOSTypes</key>
+ <array>
+ <string>TIFF</string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>NSDocumentClass</key>
+ <string>BrowserDocument</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>url</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>document.icns</string>
+ <key>CFBundleTypeName</key>
+ <string>Web site location</string>
+ <key>CFBundleTypeOSTypes</key>
+ <array>
+ <string>LINK</string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>NSDocumentClass</key>
+ <string>BrowserDocument</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>ico</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>document.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>image/x-icon</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>Windows icon image</string>
+ <key>CFBundleTypeOSTypes</key>
+ <array>
+ <string>ICO </string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>NSDocumentClass</key>
+ <string>BrowserDocument</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>xhtml</string>
+ <string>xhtm</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>document.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>application/xhtml+xml</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>XHTML document</string>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>NSDocumentClass</key>
+ <string>BrowserDocument</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>xml</string>
+ <string>xbl</string>
+ <string>xsl</string>
+ <string>xslt</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>document.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>application/xml</string>
+ <string>text/xml</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>XML document</string>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>NSDocumentClass</key>
+ <string>BrowserDocument</string>
+ </dict>
+ </array>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleGetInfoString</key>
+ <string>rVERSION, Copyright 2005, 2006, 2007 Apple Inc.</string>
+ <key>CFBundleIconFile</key>
+ <string>webkit.icns</string>
+ <key>CFBundleIdentifier</key>
+ <string>org.webkit.nightly.WebKit</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleSignature</key>
+ <string>wbkt</string>
+ <key>CFBundleVersion</key>
+ <string>VERSION</string>
+ <key>CFBundleShortVersionString</key>
+ <string>rVERSION</string>
+ <key>NSPrincipalClass</key>
+ <string>BrowserApplication</string>
+
+ <key>CFBundleHelpBookFolder</key>
+ <string>SafariHelp</string>
+ <key>CFBundleHelpBookName</key>
+ <string>Safari Help</string>
+ <key>CFBundleURLTypes</key>
+ <array>
+ <dict>
+ <key>CFBundleURLName</key>
+ <string>Web site URL</string>
+ <key>CFBundleURLSchemes</key>
+ <array>
+ <string>http</string>
+ <string>https</string>
+ </array>
+ </dict>
+ <dict>
+ <key>CFBundleURLName</key>
+ <string>local file URL</string>
+ <key>CFBundleURLSchemes</key>
+ <array>
+ <string>file</string>
+ </array>
+ </dict>
+ </array>
+ <key>NSAppleScriptEnabled</key>
+ <string>Yes</string>
+ <key>UTExportedTypeDeclarations</key>
+ <array>
+ <dict>
+ <key>UTTypeConformsTo</key>
+ <string>public.data</string>
+ <key>UTTypeDescription</key>
+ <string>Safari bookmark</string>
+ <key>UTTypeIdentifier</key>
+ <string>com.apple.safari.bookmark</string>
+ <key>UTTypeTagSpecification</key>
+ <dict>
+ <key>public.filename-extension</key>
+ <array>
+ <string>webbookmark</string>
+ </array>
+ </dict>
+ </dict>
+ </array>
+
+</dict>
+</plist>
diff --git a/WebKitTools/WebKitLauncher/VERSION b/WebKitTools/WebKitLauncher/VERSION
new file mode 100644
index 0000000..fd85e30
--- /dev/null
+++ b/WebKitTools/WebKitLauncher/VERSION
@@ -0,0 +1 @@
+VERSION
diff --git a/WebKitTools/WebKitLauncher/WebKitLauncher.xcodeproj/project.pbxproj b/WebKitTools/WebKitLauncher/WebKitLauncher.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..fda0581
--- /dev/null
+++ b/WebKitTools/WebKitLauncher/WebKitLauncher.xcodeproj/project.pbxproj
@@ -0,0 +1,359 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 42;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 5D41141C0A50A9DE00C84CF0 /* VERSION in Resources */ = {isa = PBXBuildFile; fileRef = 5D41141B0A50A9DE00C84CF0 /* VERSION */; };
+ 5D4DF982097F89FB0083D5E5 /* start.html in Resources */ = {isa = PBXBuildFile; fileRef = 5D4DF981097F89FB0083D5E5 /* start.html */; };
+ 5D650F3609DB8B370075E9A8 /* WebKitNightlyEnabler.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D650F3509DB8B370075E9A8 /* WebKitNightlyEnabler.m */; };
+ 5D650F3A09DB8B410075E9A8 /* WebKitNightlyEnabler.dylib in Resources */ = {isa = PBXBuildFile; fileRef = 5D650F3409DB8B280075E9A8 /* WebKitNightlyEnabler.dylib */; };
+ 5D877FCD0A5795F200D0C67B /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+ 5DB70525097B94CD009875EC /* webkit.icns in Resources */ = {isa = PBXBuildFile; fileRef = 5DB70524097B94CD009875EC /* webkit.icns */; };
+ 8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
+ 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 5D650F4409DB8B830075E9A8 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 5D650F3309DB8B280075E9A8;
+ remoteInfo = WebKitNightlyEnabler;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
+ 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
+ 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+ 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
+ 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
+ 5D41141B0A50A9DE00C84CF0 /* VERSION */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VERSION; sourceTree = "<group>"; };
+ 5D4DF981097F89FB0083D5E5 /* start.html */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.html; path = start.html; sourceTree = "<group>"; };
+ 5D650F3409DB8B280075E9A8 /* WebKitNightlyEnabler.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = WebKitNightlyEnabler.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
+ 5D650F3509DB8B370075E9A8 /* WebKitNightlyEnabler.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = WebKitNightlyEnabler.m; sourceTree = "<group>"; };
+ 5D650F7509DB8CB40075E9A8 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; };
+ 5DB70524097B94CD009875EC /* webkit.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = webkit.icns; sourceTree = "<group>"; };
+ 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
+ 8D1107320486CEB800E47090 /* WebKit.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WebKit.app; sourceTree = BUILT_PRODUCTS_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 5D650F3209DB8B280075E9A8 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 5D877FCD0A5795F200D0C67B /* Cocoa.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 8D11072E0486CEB800E47090 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 080E96DDFE201D6D7F000001 /* Classes */ = {
+ isa = PBXGroup;
+ children = (
+ );
+ name = Classes;
+ sourceTree = "<group>";
+ };
+ 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */,
+ );
+ name = "Linked Frameworks";
+ sourceTree = "<group>";
+ };
+ 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 5D650F7509DB8CB40075E9A8 /* CoreFoundation.framework */,
+ 29B97324FDCFA39411CA2CEA /* AppKit.framework */,
+ 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */,
+ 29B97325FDCFA39411CA2CEA /* Foundation.framework */,
+ );
+ name = "Other Frameworks";
+ sourceTree = "<group>";
+ };
+ 19C28FACFE9D520D11CA2CBB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 8D1107320486CEB800E47090 /* WebKit.app */,
+ 5D650F3409DB8B280075E9A8 /* WebKitNightlyEnabler.dylib */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 29B97314FDCFA39411CA2CEA /* WebKit */ = {
+ isa = PBXGroup;
+ children = (
+ 080E96DDFE201D6D7F000001 /* Classes */,
+ 29B97315FDCFA39411CA2CEA /* Other Sources */,
+ 29B97317FDCFA39411CA2CEA /* Resources */,
+ 29B97323FDCFA39411CA2CEA /* Frameworks */,
+ 19C28FACFE9D520D11CA2CBB /* Products */,
+ );
+ name = WebKit;
+ sourceTree = "<group>";
+ };
+ 29B97315FDCFA39411CA2CEA /* Other Sources */ = {
+ isa = PBXGroup;
+ children = (
+ 5D650F3509DB8B370075E9A8 /* WebKitNightlyEnabler.m */,
+ 29B97316FDCFA39411CA2CEA /* main.m */,
+ );
+ name = "Other Sources";
+ sourceTree = "<group>";
+ };
+ 29B97317FDCFA39411CA2CEA /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ 5D4DF981097F89FB0083D5E5 /* start.html */,
+ 5DB70524097B94CD009875EC /* webkit.icns */,
+ 8D1107310486CEB800E47090 /* Info.plist */,
+ 5D41141B0A50A9DE00C84CF0 /* VERSION */,
+ );
+ name = Resources;
+ sourceTree = "<group>";
+ };
+ 29B97323FDCFA39411CA2CEA /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */,
+ 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+ 5D650F3009DB8B280075E9A8 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+ 5D650F3309DB8B280075E9A8 /* WebKitNightlyEnabler */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 5D650F3709DB8B370075E9A8 /* Build configuration list for PBXNativeTarget "WebKitNightlyEnabler" */;
+ buildPhases = (
+ 5D650F3009DB8B280075E9A8 /* Headers */,
+ 5D650F3109DB8B280075E9A8 /* Sources */,
+ 5D650F3209DB8B280075E9A8 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = WebKitNightlyEnabler;
+ productName = WebKitNightlyEnabler;
+ productReference = 5D650F3409DB8B280075E9A8 /* WebKitNightlyEnabler.dylib */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ 8D1107260486CEB800E47090 /* WebKit */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "WebKit" */;
+ buildPhases = (
+ 8D1107290486CEB800E47090 /* Resources */,
+ 8D11072C0486CEB800E47090 /* Sources */,
+ 8D11072E0486CEB800E47090 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 5D650F4509DB8B830075E9A8 /* PBXTargetDependency */,
+ );
+ name = WebKit;
+ productInstallPath = "$(HOME)/Applications";
+ productName = WebKit;
+ productReference = 8D1107320486CEB800E47090 /* WebKit.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 29B97313FDCFA39411CA2CEA /* Project object */ = {
+ isa = PBXProject;
+ buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "WebKitLauncher" */;
+ compatibilityVersion = "Xcode 2.4";
+ hasScannedForEncodings = 1;
+ mainGroup = 29B97314FDCFA39411CA2CEA /* WebKit */;
+ projectDirPath = "";
+ projectRoot = "";
+ shouldCheckCompatibility = 1;
+ targets = (
+ 8D1107260486CEB800E47090 /* WebKit */,
+ 5D650F3309DB8B280075E9A8 /* WebKitNightlyEnabler */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 8D1107290486CEB800E47090 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 5D41141C0A50A9DE00C84CF0 /* VERSION in Resources */,
+ 5D650F3A09DB8B410075E9A8 /* WebKitNightlyEnabler.dylib in Resources */,
+ 5D4DF982097F89FB0083D5E5 /* start.html in Resources */,
+ 5DB70525097B94CD009875EC /* webkit.icns in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 5D650F3109DB8B280075E9A8 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 5D650F3609DB8B370075E9A8 /* WebKitNightlyEnabler.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 8D11072C0486CEB800E47090 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8D11072D0486CEB800E47090 /* main.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ 5D650F4509DB8B830075E9A8 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 5D650F3309DB8B280075E9A8 /* WebKitNightlyEnabler */;
+ targetProxy = 5D650F4409DB8B830075E9A8 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+ 5D650F3809DB8B370075E9A8 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ MACOSX_DEPLOYMENT_TARGET_ppc = 10.4;
+ PRODUCT_NAME = WebKitNightlyEnabler;
+ SDKROOT_ppc = /Developer/SDKs/MacOSX10.4u.sdk;
+ };
+ name = Debug;
+ };
+ 5D650F3909DB8B370075E9A8 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ MACOSX_DEPLOYMENT_TARGET_ppc = 10.4;
+ PRODUCT_NAME = WebKitNightlyEnabler;
+ SDKROOT_ppc = /Developer/SDKs/MacOSX10.4u.sdk;
+ };
+ name = Release;
+ };
+ C01FCF4B08A954540054247B /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ GCC_DEBUGGING_SYMBOLS = full;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_MODEL_TUNING = G5;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ INFOPLIST_FILE = Info.plist;
+ INSTALL_PATH = "$(HOME)/Applications";
+ PRODUCT_NAME = WebKit;
+ WRAPPER_EXTENSION = app;
+ };
+ name = Debug;
+ };
+ C01FCF4C08A954540054247B /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ DEAD_CODE_STRIPPING = YES;
+ DEPLOYMENT_POSTPROCESSING = YES;
+ GCC_DEBUGGING_SYMBOLS = full;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+ INFOPLIST_FILE = Info.plist;
+ PRODUCT_NAME = WebKit;
+ WRAPPER_EXTENSION = app;
+ };
+ name = Release;
+ };
+ C01FCF4F08A954540054247B /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.2;
+ MACOSX_DEPLOYMENT_TARGET_i386 = 10.4;
+ MACOSX_DEPLOYMENT_TARGET_ppc = 10.2;
+ PREBINDING = NO;
+ SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
+ };
+ name = Debug;
+ };
+ C01FCF5008A954540054247B /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET_i386 = 10.4;
+ MACOSX_DEPLOYMENT_TARGET_ppc = 10.2;
+ PREBINDING = NO;
+ SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 5D650F3709DB8B370075E9A8 /* Build configuration list for PBXNativeTarget "WebKitNightlyEnabler" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 5D650F3809DB8B370075E9A8 /* Debug */,
+ 5D650F3909DB8B370075E9A8 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "WebKit" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C01FCF4B08A954540054247B /* Debug */,
+ C01FCF4C08A954540054247B /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ C01FCF4E08A954540054247B /* Build configuration list for PBXProject "WebKitLauncher" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C01FCF4F08A954540054247B /* Debug */,
+ C01FCF5008A954540054247B /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
+}
diff --git a/WebKitTools/WebKitLauncher/WebKitNightlyEnabler.m b/WebKitTools/WebKitLauncher/WebKitNightlyEnabler.m
new file mode 100644
index 0000000..8c6eb84
--- /dev/null
+++ b/WebKitTools/WebKitLauncher/WebKitNightlyEnabler.m
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Graham Dennis. 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 <Cocoa/Cocoa.h>
+
+static void enableWebKitNightlyBehaviour() __attribute__ ((constructor));
+
+static NSString *WKNERunState = @"WKNERunState";
+static NSString *WKNEShouldMonitorShutdowns = @"WKNEShouldMonitorShutdowns";
+
+typedef enum {
+ RunStateShutDown,
+ RunStateInitializing,
+ RunStateRunning
+} WKNERunStates;
+
+static bool extensionBundlesWereLoaded = NO;
+static NSSet *extensionPaths = nil;
+
+static void myBundleDidLoad(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
+{
+ // Break out early if we have already detected an extension
+ if (extensionBundlesWereLoaded)
+ return;
+
+ NSBundle *bundle = (NSBundle *)object;
+ NSString *bundlePath = [[bundle bundlePath] stringByAbbreviatingWithTildeInPath];
+ NSString *bundleFileName = [bundlePath lastPathComponent];
+
+ // Explicitly ignore SIMBL.bundle, as its only purpose is to load extensions
+ // on a per-application basis. It's presence indicates a user has application
+ // extensions, but not that any will be loaded into Safari
+ if ([bundleFileName isEqualToString:@"SIMBL.bundle"])
+ return;
+
+ // If the bundle lives inside a known extension path, flag it as an extension
+ NSEnumerator *e = [extensionPaths objectEnumerator];
+ NSString *path = nil;
+ while (path = [e nextObject]) {
+ if ([bundlePath length] < [path length])
+ continue;
+
+ if ([[bundlePath substringToIndex:[path length]] isEqualToString:path]) {
+ extensionBundlesWereLoaded = YES;
+ break;
+ }
+ }
+}
+
+static void myApplicationWillFinishLaunching(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
+{
+ CFNotificationCenterRemoveObserver(CFNotificationCenterGetLocalCenter(), &myApplicationWillFinishLaunching, NULL, NULL);
+ CFNotificationCenterRemoveObserver(CFNotificationCenterGetLocalCenter(), &myBundleDidLoad, NULL, NULL);
+ [extensionPaths release];
+ extensionPaths = nil;
+
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ [userDefaults setInteger:RunStateRunning forKey:WKNERunState];
+ [userDefaults synchronize];
+
+ if (extensionBundlesWereLoaded)
+ NSRunInformationalAlertPanel(@"Safari extensions detected",
+ @"Safari extensions were detected on your system. Extensions are incompatible with nightly builds of WebKit, and may cause crashes or incorrect behavior. Please disable them if you experience such behavior.", @"Continue",
+ nil, nil);
+}
+
+static void myApplicationWillTerminate(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
+{
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ [userDefaults setInteger:RunStateShutDown forKey:WKNERunState];
+ [userDefaults synchronize];
+}
+
+extern char **_CFGetProcessPath() __attribute__((weak));
+
+static void poseAsWebKitApp()
+{
+ char *webKitAppPath = getenv("WebKitAppPath");
+ if (!webKitAppPath || !_CFGetProcessPath)
+ return;
+
+ // Set up the main bundle early so it points at Safari.app
+ CFBundleGetMainBundle();
+
+ // Fiddle with CoreFoundation to have it pick up the executable path as being within WebKit.app
+ char **processPath = _CFGetProcessPath();
+ *processPath = NULL;
+ setenv("CFProcessPath", webKitAppPath, 1);
+ _CFGetProcessPath();
+
+ // Clean up
+ unsetenv("CFProcessPath");
+ unsetenv("WebKitAppPath");
+}
+
+static void enableWebKitNightlyBehaviour()
+{
+ unsetenv("DYLD_INSERT_LIBRARIES");
+ poseAsWebKitApp();
+
+ extensionPaths = [[NSSet alloc] initWithObjects:@"~/Library/InputManagers/", @"/Library/InputManagers/",
+ @"~/Library/Application Support/SIMBL/Plugins/", @"/Library/Application Support/SIMBL/Plugins/",
+ @"~/Library/Application Enhancers/", @"/Library/Application Enhancers/",
+ nil];
+
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ NSDictionary *defaultPrefs = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:RunStateShutDown], WKNERunState,
+ [NSNumber numberWithBool:YES], WKNEShouldMonitorShutdowns, nil];
+ [userDefaults registerDefaults:defaultPrefs];
+ if ([userDefaults boolForKey:WKNEShouldMonitorShutdowns]) {
+ WKNERunStates savedState = (WKNERunStates)[userDefaults integerForKey:WKNERunState];
+ if (savedState == RunStateInitializing) {
+ // Use CoreFoundation here as AppKit hasn't been initialized at this stage of Safari's lifetime
+ CFOptionFlags responseFlags;
+ CFUserNotificationDisplayAlert(0, kCFUserNotificationCautionAlertLevel,
+ NULL, NULL, NULL,
+ CFSTR("WebKit failed to open correctly"),
+ CFSTR("WebKit failed to open correctly on your previous attempt. Please disable any Safari extensions that you may have installed. If the problem continues to occur, please file a bug report at http://webkit.org/quality/reporting.html"),
+ CFSTR("Continue"), NULL, NULL, &responseFlags);
+ }
+ else if (savedState == RunStateRunning) {
+ NSLog(@"WebKit failed to shut down cleanly. Checking for Safari extensions.");
+ CFNotificationCenterAddObserver(CFNotificationCenterGetLocalCenter(), &myBundleDidLoad,
+ myBundleDidLoad, (CFStringRef) NSBundleDidLoadNotification,
+ NULL, CFNotificationSuspensionBehaviorDeliverImmediately);
+ }
+ }
+ [userDefaults setInteger:RunStateInitializing forKey:WKNERunState];
+ [userDefaults synchronize];
+
+ CFNotificationCenterAddObserver(CFNotificationCenterGetLocalCenter(), &myApplicationWillFinishLaunching,
+ myApplicationWillFinishLaunching, (CFStringRef) NSApplicationWillFinishLaunchingNotification,
+ NULL, CFNotificationSuspensionBehaviorDeliverImmediately);
+ CFNotificationCenterAddObserver(CFNotificationCenterGetLocalCenter(), &myApplicationWillTerminate,
+ myApplicationWillTerminate, (CFStringRef) NSApplicationWillTerminateNotification,
+ NULL, CFNotificationSuspensionBehaviorDeliverImmediately);
+ [pool release];
+}
diff --git a/WebKitTools/WebKitLauncher/main.m b/WebKitTools/WebKitLauncher/main.m
new file mode 100644
index 0000000..7c9b9a5
--- /dev/null
+++ b/WebKitTools/WebKitLauncher/main.m
@@ -0,0 +1,175 @@
+/*
+ * 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.
+ */
+
+#import <Cocoa/Cocoa.h>
+#import <CoreFoundation/CoreFoundation.h>
+
+void displayErrorAndQuit(NSString *title, NSString *message)
+{
+ NSApplicationLoad();
+ NSRunCriticalAlertPanel(title, message, @"Quit", nil, nil);
+ exit(0);
+}
+
+void checkMacOSXVersion()
+{
+ long versionNumber = 0;
+ OSErr error = Gestalt(gestaltSystemVersion, &versionNumber);
+ if (error != noErr || versionNumber < 0x1040)
+ displayErrorAndQuit(@"Mac OS X 10.4 is Required", @"Nightly builds of WebKit require Mac OS X 10.4 or newer.");
+}
+
+int getLastVersionShown()
+{
+ [[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithObject:@"-1" forKey:@"StartPageShownInVersion"]];
+ return [[NSUserDefaults standardUserDefaults] integerForKey:@"StartPageShownInVersion"];
+}
+
+void saveLastVersionShown(int lastVersion)
+{
+ [[NSUserDefaults standardUserDefaults] setInteger:lastVersion forKey:@"StartPageShownInVersion"];
+ [[NSUserDefaults standardUserDefaults] synchronize];
+}
+
+NSString *getPathForStartPage()
+{
+ return [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"start.html"];
+}
+
+int getShowStartPageVersion()
+{
+ return getCurrentVersion() + 1;
+}
+
+int getCurrentVersion()
+{
+ return [[[[NSBundle mainBundle] infoDictionary] valueForKey:(NSString *)kCFBundleVersionKey] intValue];
+}
+
+BOOL startPageDisabled()
+{
+ return [[NSUserDefaults standardUserDefaults] boolForKey:@"StartPageDisabled"];
+}
+
+void addStartPageToArgumentsIfNeeded(NSMutableArray *arguments)
+{
+ if (startPageDisabled())
+ return;
+
+ if (getLastVersionShown() < getShowStartPageVersion()) {
+ saveLastVersionShown(getCurrentVersion());
+ NSString *startPagePath = getPathForStartPage();
+ if (startPagePath)
+ [arguments addObject:startPagePath];
+ }
+}
+
+static void myExecve(NSString *executable, NSArray *args, NSDictionary *environment)
+{
+ char **argv = (char **)calloc(sizeof(char *), [args count] + 1);
+ char **env = (char **)calloc(sizeof(char *), [environment count] + 1);
+
+ NSEnumerator *e = [args objectEnumerator];
+ NSString *s;
+ int i = 0;
+ while (s = [e nextObject])
+ argv[i++] = (char *) [s UTF8String];
+
+ e = [environment keyEnumerator];
+ i = 0;
+ while (s = [e nextObject])
+ env[i++] = (char *) [[NSString stringWithFormat:@"%@=%@", s, [environment objectForKey:s]] UTF8String];
+
+ execve([executable fileSystemRepresentation], argv, env);
+}
+
+NSBundle *locateSafariBundle()
+{
+ NSArray *applicationDirectories = NSSearchPathForDirectoriesInDomains(NSApplicationDirectory, NSAllDomainsMask, YES);
+ NSEnumerator *e = [applicationDirectories objectEnumerator];
+ NSString *applicationDirectory;
+ while (applicationDirectory = [e nextObject]) {
+ NSString *possibleSafariPath = [applicationDirectory stringByAppendingPathComponent:@"Safari.app"];
+ NSBundle *possibleSafariBundle = [NSBundle bundleWithPath:possibleSafariPath];
+ if ([[possibleSafariBundle bundleIdentifier] isEqualToString:@"com.apple.Safari"])
+ return possibleSafariBundle;
+ }
+
+ CFURLRef safariURL = nil;
+ OSStatus err = LSFindApplicationForInfo(kLSUnknownCreator, CFSTR("com.apple.Safari"), nil, nil, &safariURL);
+ if (err != noErr)
+ displayErrorAndQuit(@"Unable to locate Safari", @"Nightly builds of WebKit require Safari to run. Please check that it is available and then try again.");
+
+ NSBundle *safariBundle = [NSBundle bundleWithPath:[(NSURL *)safariURL path]];
+ CFRelease(safariURL);
+ return safariBundle;
+}
+
+NSString *currentSystemVersion()
+{
+ long version;
+ if (Gestalt(gestaltSystemVersion, &version) != noErr)
+ return @"10.4";
+
+ return [NSString stringWithFormat:@"%x.%x", (version & 0xFF00) >> 8, (version & 0x00F0) >> 4];
+}
+
+int main(int argc, char *argv[])
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ checkMacOSXVersion();
+
+ NSBundle *safariBundle = locateSafariBundle();
+ NSString *executablePath = [safariBundle executablePath];
+ NSString *frameworkPath = [[[NSBundle mainBundle] privateFrameworksPath] stringByAppendingPathComponent:currentSystemVersion()];
+ NSString *pathToEnablerLib = [[NSBundle mainBundle] pathForResource:@"WebKitNightlyEnabler" ofType:@"dylib"];
+
+ NSLog(@"Using framework path of %@", frameworkPath);
+
+ if ([frameworkPath rangeOfString:@":"].location != NSNotFound ||
+ [pathToEnablerLib rangeOfString:@":"].location != NSNotFound)
+ displayErrorAndQuit(@"Unable to launch Safari",
+ @"WebKit is located at a path containing an unsupported character. Please move WebKit to a different location and try again.");
+
+ NSMutableArray *arguments = [NSMutableArray arrayWithObjects:executablePath, @"-WebKitDeveloperExtras", @"YES", @"-WebKitScriptDebuggerEnabled", @"YES", nil];
+ NSMutableDictionary *environment = [NSDictionary dictionaryWithObjectsAndKeys:frameworkPath, @"DYLD_FRAMEWORK_PATH", @"YES", @"WEBKIT_UNSET_DYLD_FRAMEWORK_PATH",
+ pathToEnablerLib, @"DYLD_INSERT_LIBRARIES", [[NSBundle mainBundle] executablePath], @"WebKitAppPath", nil];
+ addStartPageToArgumentsIfNeeded(arguments);
+
+ while (*++argv)
+ [arguments addObject:[NSString stringWithUTF8String:*argv]];
+
+ myExecve(executablePath, arguments, environment);
+
+ char *error = strerror(errno);
+ NSString *errorMessage = [NSString stringWithFormat:@"Launching Safari at %@ failed with the error '%s' (%d)", [safariBundle bundlePath], error, errno];
+ displayErrorAndQuit(@"Unable to launch Safari", errorMessage);
+
+ [pool release];
+ return 0;
+}
diff --git a/WebKitTools/WebKitLauncher/start.html b/WebKitTools/WebKitLauncher/start.html
new file mode 100644
index 0000000..2c94e79
--- /dev/null
+++ b/WebKitTools/WebKitLauncher/start.html
@@ -0,0 +1,33 @@
+<html>
+ <head>
+ <title>Loading WebKit...</title>
+ <meta http-equiv="refresh" content="1;URL=http://nightly.webkit.org/start/" />
+ <script type="text/javascript">
+ function getWebKitRevision()
+ {
+ var request = new XMLHttpRequest();
+ request.open("GET", "VERSION", false);
+ request.send();
+ var revision = parseInt(request.responseText);
+ if (isNaN(revision))
+ return "";
+
+ return revision;
+ }
+
+ function getWebKitBranch()
+ {
+ var request = new XMLHttpRequest();
+ request.open("GET", "BRANCH", false);
+ request.send();
+ return (request.responseText || "trunk").replace(/\s/g, '')
+ }
+
+ var revision = getWebKitRevision();
+ var branch = getWebKitBranch();
+ document.location = "http://nightly.webkit.org/start/" + branch + "/" + revision;
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/WebKitTools/WebKitLauncher/webkit.icns b/WebKitTools/WebKitLauncher/webkit.icns
new file mode 100644
index 0000000..bf629bf
--- /dev/null
+++ b/WebKitTools/WebKitLauncher/webkit.icns
Binary files differ
diff --git a/WebKitTools/WinLauncher/WinLauncher.cpp b/WebKitTools/WinLauncher/WinLauncher.cpp
new file mode 100644
index 0000000..4d60115
--- /dev/null
+++ b/WebKitTools/WinLauncher/WinLauncher.cpp
@@ -0,0 +1,408 @@
+/*
+ * Copyright (C) 2006, 2008 Apple Computer, 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 "stdafx.h"
+#include "WinLauncher.h"
+#include "WebKit.h"
+
+#include <commctrl.h>
+#include <objbase.h>
+#include <shlwapi.h>
+#include <wininet.h>
+
+#define MAX_LOADSTRING 100
+#define URLBAR_HEIGHT 24
+
+// Global Variables:
+HINSTANCE hInst; // current instance
+HWND hMainWnd;
+HWND hURLBarWnd;
+long DefEditProc;
+IWebView* gWebView = 0;
+HWND gViewWindow = 0;
+WinLauncherWebHost* gWebHost = 0;
+TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
+TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
+
+// Forward declarations of functions included in this code module:
+ATOM MyRegisterClass(HINSTANCE hInstance);
+BOOL InitInstance(HINSTANCE, int);
+LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
+INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
+LRESULT CALLBACK MyEditProc(HWND, UINT, WPARAM, LPARAM);
+
+static void loadURL(BSTR urlBStr);
+
+HRESULT WinLauncherWebHost::updateAddressBar(IWebView* webView)
+{
+ IWebFrame* mainFrame = 0;
+ IWebDataSource* dataSource = 0;
+ IWebMutableURLRequest* request = 0;
+ BSTR frameURL = 0;
+
+ HRESULT hr = S_OK;
+
+ hr = webView->mainFrame(&mainFrame);
+ if (FAILED(hr))
+ goto exit;
+
+ hr = mainFrame->dataSource(&dataSource);
+ if (FAILED(hr) || !dataSource)
+ hr = mainFrame->provisionalDataSource(&dataSource);
+ if (FAILED(hr) || !dataSource)
+ goto exit;
+
+ hr = dataSource->request(&request);
+ if (FAILED(hr) || !request)
+ goto exit;
+
+ hr = request->mainDocumentURL(&frameURL);
+ if (FAILED(hr))
+ goto exit;
+
+ SendMessage(hURLBarWnd, (UINT)WM_SETTEXT, 0, (LPARAM)frameURL);
+
+exit:
+ if (mainFrame)
+ mainFrame->Release();
+ if (dataSource)
+ dataSource->Release();
+ if (request)
+ request->Release();
+ SysFreeString(frameURL);
+ return 0;
+}
+
+HRESULT STDMETHODCALLTYPE WinLauncherWebHost::QueryInterface(REFIID riid, void** ppvObject)
+{
+ *ppvObject = 0;
+ if (IsEqualGUID(riid, IID_IUnknown))
+ *ppvObject = static_cast<IWebFrameLoadDelegate*>(this);
+ else if (IsEqualGUID(riid, IID_IWebFrameLoadDelegate))
+ *ppvObject = static_cast<IWebFrameLoadDelegate*>(this);
+ else
+ return E_NOINTERFACE;
+
+ AddRef();
+ return S_OK;
+}
+
+ULONG STDMETHODCALLTYPE WinLauncherWebHost::AddRef(void)
+{
+ return ++m_refCount;
+}
+
+ULONG STDMETHODCALLTYPE WinLauncherWebHost::Release(void)
+{
+ ULONG newRef = --m_refCount;
+ if (!newRef)
+ delete(this);
+
+ return newRef;
+}
+
+static void resizeSubViews()
+{
+ RECT rcClient;
+ GetClientRect(hMainWnd, &rcClient);
+ MoveWindow(hURLBarWnd, 0, 0, rcClient.right, URLBAR_HEIGHT, TRUE);
+ MoveWindow(gViewWindow, 0, URLBAR_HEIGHT, rcClient.right, rcClient.bottom - URLBAR_HEIGHT, TRUE);
+}
+
+int APIENTRY _tWinMain(HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPTSTR lpCmdLine,
+ int nCmdShow)
+{
+#ifdef _CRTDBG_MAP_ALLOC
+ _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
+ _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
+#endif
+
+ UNREFERENCED_PARAMETER(hPrevInstance);
+ UNREFERENCED_PARAMETER(lpCmdLine);
+
+ // TODO: Place code here.
+ MSG msg;
+ HACCEL hAccelTable;
+
+ INITCOMMONCONTROLSEX InitCtrlEx;
+
+ InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
+ InitCtrlEx.dwICC = 0x00004000; //ICC_STANDARD_CLASSES;
+ InitCommonControlsEx(&InitCtrlEx);
+
+ // Initialize global strings
+ LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
+ LoadString(hInstance, IDC_WINLAUNCHER, szWindowClass, MAX_LOADSTRING);
+ MyRegisterClass(hInstance);
+
+ // Perform application initialization:
+ if (!InitInstance (hInstance, nCmdShow))
+ return FALSE;
+
+ // Init COM
+ OleInitialize(NULL);
+
+ hURLBarWnd = CreateWindow(L"EDIT", 0,
+ WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT | ES_AUTOVSCROLL,
+ 0, 0, 0, 0,
+ hMainWnd,
+ 0,
+ hInstance, 0);
+
+ DefEditProc = GetWindowLong(hURLBarWnd, GWL_WNDPROC);
+ SetWindowLong(hURLBarWnd, GWL_WNDPROC,(long)MyEditProc);
+ SetFocus(hURLBarWnd);
+
+ HRESULT hr = CoCreateInstance(CLSID_WebView, 0, CLSCTX_ALL, IID_IWebView, (void**)&gWebView);
+ if (FAILED(hr))
+ goto exit;
+
+ gWebHost = new WinLauncherWebHost();
+ gWebHost->AddRef();
+ hr = gWebView->setFrameLoadDelegate(gWebHost);
+ if (FAILED(hr))
+ goto exit;
+
+ hr = gWebView->setHostWindow((OLE_HANDLE) hMainWnd);
+ if (FAILED(hr))
+ goto exit;
+
+ RECT clientRect;
+ GetClientRect(hMainWnd, &clientRect);
+ hr = gWebView->initWithFrame(clientRect, 0, 0);
+ if (FAILED(hr))
+ goto exit;
+
+ IWebFrame* frame;
+ hr = gWebView->mainFrame(&frame);
+ if (FAILED(hr))
+ goto exit;
+ static BSTR defaultHTML = 0;
+ if (!defaultHTML)
+ defaultHTML = SysAllocString(TEXT("<p style=\"background-color: #00FF00\">Testing</p><img src=\"http://webkit.org/images/icon-gold.png\" alt=\"Face\"><div style=\"border: solid blue\" contenteditable=\"true\">div with blue border</div><ul><li>foo<li>bar<li>baz</ul>"));
+ frame->loadHTMLString(defaultHTML, 0);
+ frame->Release();
+
+ IWebViewPrivate* viewExt;
+ hr = gWebView->QueryInterface(IID_IWebViewPrivate, (void**)&viewExt);
+ if (FAILED(hr))
+ goto exit;
+ hr = viewExt->viewWindow((OLE_HANDLE*) &gViewWindow);
+ viewExt->Release();
+ if (FAILED(hr) || !gViewWindow)
+ goto exit;
+
+ resizeSubViews();
+
+ ShowWindow(gViewWindow, nCmdShow);
+ UpdateWindow(gViewWindow);
+
+ hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINLAUNCHER));
+
+ // Main message loop:
+ while (GetMessage(&msg, NULL, 0, 0)) {
+ if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+
+exit:
+ delete gWebView;
+#ifdef _CRTDBG_MAP_ALLOC
+ _CrtDumpMemoryLeaks();
+#endif
+
+ // Shut down COM.
+ OleUninitialize();
+
+ return (int) msg.wParam;
+}
+
+ATOM MyRegisterClass(HINSTANCE hInstance)
+{
+ WNDCLASSEX wcex;
+
+ wcex.cbSize = sizeof(WNDCLASSEX);
+
+ wcex.style = CS_HREDRAW | CS_VREDRAW;
+ wcex.lpfnWndProc = WndProc;
+ wcex.cbClsExtra = 0;
+ wcex.cbWndExtra = 0;
+ wcex.hInstance = hInstance;
+ wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINLAUNCHER));
+ wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wcex.hbrBackground = 0;
+ wcex.lpszMenuName = MAKEINTRESOURCE(IDC_WINLAUNCHER);
+ wcex.lpszClassName = szWindowClass;
+ wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
+
+ return RegisterClassEx(&wcex);
+}
+
+BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
+{
+ hInst = hInstance; // Store instance handle in our global variable
+
+ hMainWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
+
+ if (!hMainWnd)
+ return FALSE;
+
+ ShowWindow(hMainWnd, nCmdShow);
+ UpdateWindow(hMainWnd);
+
+ return TRUE;
+}
+
+LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ int wmId, wmEvent;
+ PAINTSTRUCT ps;
+ HDC hdc;
+
+ switch (message) {
+ case WM_COMMAND:
+ wmId = LOWORD(wParam);
+ wmEvent = HIWORD(wParam);
+ // Parse the menu selections:
+ switch (wmId) {
+ case IDM_ABOUT:
+ DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
+ break;
+ case IDM_EXIT:
+ DestroyWindow(hWnd);
+ break;
+ default:
+ return DefWindowProc(hWnd, message, wParam, lParam);
+ }
+ break;
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ break;
+ case WM_SIZE:
+ if (!gWebView)
+ break;
+ resizeSubViews();
+ break;
+ default:
+ return DefWindowProc(hWnd, message, wParam, lParam);
+ }
+ return 0;
+}
+
+
+#define MAX_URL_LENGTH 1024
+
+LRESULT CALLBACK MyEditProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch (message) {
+ case WM_CHAR:
+ if( wParam == 13 ) { // Enter Key
+ wchar_t strPtr[MAX_URL_LENGTH];
+ *((LPWORD)strPtr) = MAX_URL_LENGTH;
+ int strLen = SendMessage(hDlg, EM_GETLINE, 0, (LPARAM)strPtr);
+
+ BSTR bstr = SysAllocStringLen(strPtr, strLen);
+ loadURL(bstr);
+ SysFreeString(bstr);
+
+ return 0;
+ } else
+ return (LRESULT)CallWindowProc((WNDPROC)DefEditProc,hDlg,message,wParam,lParam);
+ break;
+ default:
+ return (LRESULT)CallWindowProc((WNDPROC)DefEditProc,hDlg,message,wParam,lParam);
+ break;
+ }
+ return 0;
+}
+
+
+// Message handler for about box.
+INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ UNREFERENCED_PARAMETER(lParam);
+ switch (message) {
+ case WM_INITDIALOG:
+ return (INT_PTR)TRUE;
+
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) {
+ EndDialog(hDlg, LOWORD(wParam));
+ return (INT_PTR)TRUE;
+ }
+ break;
+ }
+ return (INT_PTR)FALSE;
+}
+
+static void loadURL(BSTR urlBStr)
+{
+ IWebFrame* frame = 0;
+ IWebMutableURLRequest* request = 0;
+ static BSTR methodBStr = 0;
+
+ if (!methodBStr)
+ methodBStr = SysAllocString(TEXT("GET"));
+
+ if (urlBStr && urlBStr[0] && (PathFileExists(urlBStr) || PathIsUNC(urlBStr))) {
+ TCHAR fileURL[INTERNET_MAX_URL_LENGTH];
+ DWORD fileURLLength = sizeof(fileURL)/sizeof(fileURL[0]);
+ if (SUCCEEDED(UrlCreateFromPath(urlBStr, fileURL, &fileURLLength, 0)))
+ urlBStr = fileURL;
+ }
+
+ HRESULT hr = gWebView->mainFrame(&frame);
+ if (FAILED(hr))
+ goto exit;
+
+ hr = CoCreateInstance(CLSID_WebMutableURLRequest, 0, CLSCTX_ALL, IID_IWebMutableURLRequest, (void**)&request);
+ if (FAILED(hr))
+ goto exit;
+
+ hr = request->initWithURL(urlBStr, WebURLRequestUseProtocolCachePolicy, 0);
+ if (FAILED(hr))
+ goto exit;
+
+ hr = request->setHTTPMethod(methodBStr);
+ if (FAILED(hr))
+ goto exit;
+
+ hr = frame->loadRequest(request);
+ if (FAILED(hr))
+ goto exit;
+
+ SetFocus(gViewWindow);
+
+exit:
+ if (frame)
+ frame->Release();
+ if (request)
+ request->Release();
+}
diff --git a/WebKitTools/WinLauncher/WinLauncher.h b/WebKitTools/WinLauncher/WinLauncher.h
new file mode 100644
index 0000000..1f57bff
--- /dev/null
+++ b/WebKitTools/WinLauncher/WinLauncher.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2006 Apple Computer, 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.
+ */
+
+#pragma once
+
+#include "resource.h"
+#include "WebKit.h"
+
+class WinLauncherWebHost : public IWebFrameLoadDelegate
+{
+public:
+ WinLauncherWebHost() : m_refCount(1) {}
+
+ // IUnknown
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
+ virtual ULONG STDMETHODCALLTYPE AddRef(void);
+ virtual ULONG STDMETHODCALLTYPE Release(void);
+
+ // IWebFrameLoadDelegate
+ virtual HRESULT STDMETHODCALLTYPE didStartProvisionalLoadForFrame(
+ /* [in] */ IWebView* webView,
+ /* [in] */ IWebFrame* /*frame*/) { return S_OK; }
+
+ virtual HRESULT STDMETHODCALLTYPE didReceiveServerRedirectForProvisionalLoadForFrame(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebFrame *frame) { return S_OK; }
+
+ virtual HRESULT STDMETHODCALLTYPE didFailProvisionalLoadWithError(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebError *error,
+ /* [in] */ IWebFrame *frame) { return S_OK; }
+
+ virtual HRESULT STDMETHODCALLTYPE didCommitLoadForFrame(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebFrame *frame) { return updateAddressBar(webView); }
+
+ virtual HRESULT STDMETHODCALLTYPE didReceiveTitle(
+ /* [in] */ IWebView *webView,
+ /* [in] */ BSTR title,
+ /* [in] */ IWebFrame *frame) { return S_OK; }
+
+ virtual HRESULT STDMETHODCALLTYPE didReceiveIcon(
+ /* [in] */ IWebView *webView,
+ /* [in] */ OLE_HANDLE hBitmap,
+ /* [in] */ IWebFrame *frame) { return S_OK; }
+
+ virtual HRESULT STDMETHODCALLTYPE didFinishLoadForFrame(
+ /* [in] */ IWebView* webView,
+ /* [in] */ IWebFrame* /*frame*/) { return S_OK; }
+
+ virtual HRESULT STDMETHODCALLTYPE didFailLoadWithError(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebError *error,
+ /* [in] */ IWebFrame *forFrame) { return S_OK; }
+
+ virtual HRESULT STDMETHODCALLTYPE didChangeLocationWithinPageForFrame(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebFrame *frame) { return S_OK; }
+
+ virtual HRESULT STDMETHODCALLTYPE willPerformClientRedirectToURL(
+ /* [in] */ IWebView *webView,
+ /* [in] */ BSTR url,
+ /* [in] */ double delaySeconds,
+ /* [in] */ DATE fireDate,
+ /* [in] */ IWebFrame *frame) { return S_OK; }
+
+ virtual HRESULT STDMETHODCALLTYPE didCancelClientRedirectForFrame(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebFrame *frame) { return S_OK; }
+
+ virtual HRESULT STDMETHODCALLTYPE willCloseFrame(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebFrame *frame) { return S_OK; }
+
+ virtual /* [local] */ HRESULT STDMETHODCALLTYPE windowScriptObjectAvailable(
+ /* [in] */ IWebView *webView,
+ /* [in] */ JSContextRef context,
+ /* [in] */ JSObjectRef windowScriptObject) { return S_OK; }
+
+ // WinLauncherWebHost
+
+protected:
+ HRESULT updateAddressBar(IWebView* webView);
+
+protected:
+ ULONG m_refCount;
+};
diff --git a/WebKitTools/WinLauncher/WinLauncher.ico b/WebKitTools/WinLauncher/WinLauncher.ico
new file mode 100644
index 0000000..d551aa3
--- /dev/null
+++ b/WebKitTools/WinLauncher/WinLauncher.ico
Binary files differ
diff --git a/WebKitTools/WinLauncher/WinLauncher.rc b/WebKitTools/WinLauncher/WinLauncher.rc
new file mode 100644
index 0000000..f4b2cd4
--- /dev/null
+++ b/WebKitTools/WinLauncher/WinLauncher.rc
@@ -0,0 +1,136 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#define APSTUDIO_HIDDEN_SYMBOLS
+#include "windows.h"
+#undef APSTUDIO_HIDDEN_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_WINLAUNCHER ICON "WinLauncher.ico"
+IDI_SMALL ICON "small.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDC_WINLAUNCHER MENU
+BEGIN
+ POPUP "&File"
+ BEGIN
+ MENUITEM "E&xit", IDM_EXIT
+ END
+ POPUP "&Help"
+ BEGIN
+ MENUITEM "&About ...", IDM_ABOUT
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Accelerator
+//
+
+IDC_WINLAUNCHER ACCELERATORS
+BEGIN
+ "?", IDM_ABOUT, ASCII, ALT
+ "/", IDM_ABOUT, ASCII, ALT
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_ABOUTBOX DIALOGEX 22, 17, 230, 75
+STYLE DS_SETFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
+CAPTION "About"
+FONT 8, "System", 0, 0, 0x0
+BEGIN
+ ICON IDI_WINLAUNCHER,IDC_MYICON,14,9,20,20
+ LTEXT "WinLauncher Version 1.1",IDC_STATIC,49,10,119,8,SS_NOPREFIX
+ LTEXT "Copyright (C) 2008",IDC_STATIC,49,20,119,8
+ DEFPUSHBUTTON "OK",IDOK,195,6,30,11,WS_GROUP
+END
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
+ "#include ""windows.h""\r\n"
+ "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ IDS_APP_TITLE "WinLauncher"
+ IDC_WINLAUNCHER "WINLAUNCHER"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/WebKitTools/WinLauncher/WinLauncher.vcproj b/WebKitTools/WinLauncher/WinLauncher.vcproj
new file mode 100644
index 0000000..234df33
--- /dev/null
+++ b/WebKitTools/WinLauncher/WinLauncher.vcproj
@@ -0,0 +1,255 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="WinLauncher"
+ ProjectGUID="{114FCA11-216B-4C8C-957E-30A75AE80443}"
+ RootNamespace="WinLauncher"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(WebKitOutputDir)\bin"
+ IntermediateDirectory="$(WebKitOutputDir)\obj\$(ProjectName)\$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\include\WebKit&quot;;&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(WebKitLibrariesDir)\Include&quot;;&quot;$(WebKitOutputDir)\Include\WebCore&quot;;&quot;$(WebKitLibrariesDir)\Include\WebCore&quot;;&quot;$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\WebCore\ForwardingHeaders&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\Include\JavaScriptCore&quot;;&quot;$(ProjectDir)\..&quot;;&quot;$(ProjectDir)&quot;;&quot;$(IntDir)\Include&quot;;&quot;$(WebKitOutputDir)\obj\WebKit\DerivedSources&quot;"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE"
+ MinimalRebuild="true"
+ ExceptionHandling="0"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="false"
+ UsePrecompiledHeader="2"
+ WarningLevel="1"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkLibraryDependencies="false"
+ AdditionalDependencies="comctl32.lib shlwapi.lib WebKitGUID$(WebKitConfigSuffix).lib WebKit$(WebKitDLLConfigSuffix).lib"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="&quot;$(WebKitOutputDir)\lib&quot;;&quot;$(ProjectDir)\..\..\..\&quot;"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(WebKitOutputDir)\bin"
+ IntermediateDirectory="$(WebKitOutputDir)\obj\$(ProjectName)\$(ConfigurationName)"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\release.vsprops"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\include\WebKit&quot;;&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(WebKitLibrariesDir)\Include&quot;;&quot;$(WebKitOutputDir)\Include\WebCore&quot;;&quot;$(WebKitLibrariesDir)\Include\WebCore&quot;;&quot;$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\WebCore\ForwardingHeaders&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitOutputDir)\Include\icu&quot;;&quot;$(WebKitLibrariesDir)\Include\icu&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;&quot;$(WebKitOutputDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitOutputDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;;&quot;$(ProjectDir)\..&quot;;&quot;$(ProjectDir)&quot;;&quot;$(IntDir)\include&quot;;&quot;$(WebKitOutputDir)\obj\WebKit\DerivedSources&quot;"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_WIN32_WINNT=0x501"
+ ExceptionHandling="0"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="false"
+ UsePrecompiledHeader="2"
+ WarningLevel="1"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkLibraryDependencies="false"
+ AdditionalOptions="&#x0D;&#x0A;"
+ AdditionalDependencies="comctl32.lib shlwapi.lib WebKitGUID$(WebKitConfigSuffix).lib WebKit$(WebKitDLLConfigSuffix).lib"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="&quot;$(WebKitOutputDir)\lib&quot;;&quot;$(ProjectDir)\..\..\..\&quot;"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\stdafx.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\WinLauncher.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\Resource.h"
+ >
+ </File>
+ <File
+ RelativePath=".\stdafx.h"
+ >
+ </File>
+ <File
+ RelativePath=".\WinLauncher.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ <File
+ RelativePath=".\small.ico"
+ >
+ </File>
+ <File
+ RelativePath=".\WinLauncher.ico"
+ >
+ </File>
+ <File
+ RelativePath=".\WinLauncher.rc"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/WebKitTools/WinLauncher/resource.h b/WebKitTools/WinLauncher/resource.h
new file mode 100644
index 0000000..6a21684
--- /dev/null
+++ b/WebKitTools/WinLauncher/resource.h
@@ -0,0 +1,27 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by WinLauncher.rc
+//
+#define IDC_MYICON 2
+#define IDD_WINLAUNCHER_DIALOG 102
+#define IDS_APP_TITLE 103
+#define IDD_ABOUTBOX 103
+#define IDM_ABOUT 104
+#define IDM_EXIT 105
+#define IDI_WINLAUNCHER 107
+#define IDI_SMALL 108
+#define IDC_WINLAUNCHER 109
+#define IDR_MAINFRAME 128
+#define IDC_STATIC -1
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NO_MFC 1
+#define _APS_NEXT_RESOURCE_VALUE 129
+#define _APS_NEXT_COMMAND_VALUE 32771
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 110
+#endif
+#endif
diff --git a/WebKitTools/WinLauncher/small.ico b/WebKitTools/WinLauncher/small.ico
new file mode 100644
index 0000000..d551aa3
--- /dev/null
+++ b/WebKitTools/WinLauncher/small.ico
Binary files differ
diff --git a/WebKitTools/WinLauncher/stdafx.cpp b/WebKitTools/WinLauncher/stdafx.cpp
new file mode 100644
index 0000000..541dcb1
--- /dev/null
+++ b/WebKitTools/WinLauncher/stdafx.cpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2006 Apple Computer, 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.
+ */
+
+// stdafx.cpp : source file that includes just the standard includes
+// Spinneret.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file
diff --git a/WebKitTools/WinLauncher/stdafx.h b/WebKitTools/WinLauncher/stdafx.h
new file mode 100644
index 0000000..86f76cc
--- /dev/null
+++ b/WebKitTools/WinLauncher/stdafx.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2006 Apple Computer, 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.
+ */
+
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#pragma once
+
+// Modify the following defines if you have to target a platform prior to the ones specified below.
+// Refer to MSDN for the latest info on corresponding values for different platforms.
+#ifndef WINVER // Allow use of features specific to Windows XP or later.
+#define WINVER 0x0501 // Change this to the appropriate value to target other versions of Windows.
+#endif
+
+#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later.
+#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
+#endif
+
+#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later.
+#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
+#endif
+
+#ifndef _WIN32_IE // Allow use of features specific to IE 6.0 or later.
+#define _WIN32_IE 0x0600 // Change this to the appropriate value to target other versions of IE.
+#endif
+
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+// Windows Header Files:
+#include <windows.h>
+
+// C RunTime Header Files
+#include <stdlib.h>
+#include <malloc.h>
+#include <memory.h>
+#include <tchar.h>
+
+#if 0
+// Visual Studio Leak Detection
+// <http://msdn2.microsoft.com/en-US/library/e5ewb1h3.aspx>
+#if defined(_MSC_VER) && defined(_DEBUG)
+#define _CRTDBG_MAP_ALLOC
+#include <stdlib.h>
+#include <crtdbg.h>
+#endif
+#endif
diff --git a/WebKitTools/iExploder/CHANGELOG.txt b/WebKitTools/iExploder/CHANGELOG.txt
new file mode 100644
index 0000000..a9d5060
--- /dev/null
+++ b/WebKitTools/iExploder/CHANGELOG.txt
@@ -0,0 +1,328 @@
+------------------------------------------------------------------------
+r618 | thomas | 2006-04-21 09:55:51 -0400 (Fri, 21 Apr 2006) | 1 line
+Changed paths:
+ M /iexploder/README.txt
+ M /iexploder/htdocs/iexploder.cgi
+ M /iexploder/htdocs/iexploder.rb
+ M /iexploder/htdocs/webserver.rb
+
+1.3.2.. minor adjustment to title and where gets set
+------------------------------------------------------------------------
+r617 | thomas | 2006-04-19 17:14:26 -0400 (Wed, 19 Apr 2006) | 1 line
+Changed paths:
+ A /iexploder/testcases/safari/2500_163-Safari-2.0.3_Mac_OS_X-Crash.html
+
+Add h4+pre+cite+nolayer+code crash for Safari 2.0.3
+------------------------------------------------------------------------
+r616 | thomas | 2006-04-19 17:01:48 -0400 (Wed, 19 Apr 2006) | 1 line
+Changed paths:
+ A /iexploder/tools/showtest.rb
+
+showtest.rb: easily download a testcase
+------------------------------------------------------------------------
+r615 | thomas | 2006-04-19 16:07:13 -0400 (Wed, 19 Apr 2006) | 1 line
+Changed paths:
+ M /iexploder/htdocs/iexploder.rb
+
+Remove stopping debug message
+------------------------------------------------------------------------
+r614 | thomas | 2006-04-19 16:02:48 -0400 (Wed, 19 Apr 2006) | 1 line
+Changed paths:
+ M /iexploder/README.txt
+ M /iexploder/htdocs/iexploder.rb
+
+New subtest algorithm: double the tag count each iteration
+------------------------------------------------------------------------
+r613 | thomas | 2006-04-19 15:05:30 -0400 (Wed, 19 Apr 2006) | 1 line
+Changed paths:
+ M /iexploder/htdocs/cssproperties.in
+
+remove IE dupes: text-overflow and word-wrap
+------------------------------------------------------------------------
+r612 | thomas | 2006-04-19 12:48:07 -0400 (Wed, 19 Apr 2006) | 1 line
+Changed paths:
+ M /iexploder/README.txt
+ M /iexploder/htdocs/config.rb
+ M /iexploder/htdocs/iexploder.rb
+
+Add some benchmark/performance info.. set MAX_TAGS default to 96
+------------------------------------------------------------------------
+r611 | thomas | 2006-04-19 10:22:33 -0400 (Wed, 19 Apr 2006) | 1 line
+Changed paths:
+ M /iexploder/htdocs/iexploder.cgi
+ M /iexploder/htdocs/iexploder.rb
+ M /iexploder/htdocs/webserver.rb
+
+Add stop parameter, fix port assignment issue, fix indentation
+------------------------------------------------------------------------
+r610 | thomas | 2006-04-19 10:22:06 -0400 (Wed, 19 Apr 2006) | 1 line
+Changed paths:
+ M /iexploder/README.txt
+
+1.3.0
+------------------------------------------------------------------------
+r609 | thomas | 2006-04-18 22:46:35 -0400 (Tue, 18 Apr 2006) | 1 line
+Changed paths:
+ A /iexploder/testcases/safari/16170_44-Safari-Nightly-420+-2006-r13911-2006-04-18.html
+
+applet+param Hashmap crash in Safari
+------------------------------------------------------------------------
+r608 | thomas | 2006-04-18 22:07:45 -0400 (Tue, 18 Apr 2006) | 1 line
+Changed paths:
+ M /iexploder/htdocs/iexploder.cgi
+ M /iexploder/htdocs/webserver.rb
+
+1.3.0
+------------------------------------------------------------------------
+r607 | thomas | 2006-04-18 22:05:47 -0400 (Tue, 18 Apr 2006) | 1 line
+Changed paths:
+ M /iexploder/README.txt
+ M /iexploder/htdocs/webserver.rb
+ M /iexploder/tools/osx_last_crash.rb
+
+commit osx_last_crash minutes->days change, document that you can pass a new port number to the webserver.rb program
+------------------------------------------------------------------------
+r606 | thomas | 2006-04-18 22:02:16 -0400 (Tue, 18 Apr 2006) | 1 line
+Changed paths:
+ A /iexploder/testcases/safari/2969_421-Safari-2.0.3_Mac_OS_X-Crash.html
+ A /iexploder/testcases/safari/5763_181-Safari-Nightly-420+-2006-r13911-2006-04-18.html
+
+Add more Safari crashes to the testcases list
+------------------------------------------------------------------------
+r605 | thomas | 2006-04-18 19:05:46 -0400 (Tue, 18 Apr 2006) | 1 line
+Changed paths:
+ M /iexploder/README.txt
+ M /iexploder/htdocs/config.rb
+ M /iexploder/htdocs/iexploder.cgi
+ M /iexploder/htdocs/iexploder.rb
+ M /iexploder/htdocs/webserver.rb
+
+Greatly improve subtests. Not only do we iterate around each tag, but we steadily increase the amount of tags we input as well
+------------------------------------------------------------------------
+r604 | thomas | 2006-04-18 17:04:17 -0400 (Tue, 18 Apr 2006) | 1 line
+Changed paths:
+ M /iexploder/README.txt
+ M /iexploder/htdocs/config.rb
+
+1.3b1.. also, raise max tags to 48 now that we have fixed subtest bugs
+------------------------------------------------------------------------
+r603 | thomas | 2006-04-18 16:59:20 -0400 (Tue, 18 Apr 2006) | 1 line
+Changed paths:
+ M /iexploder/htdocs/iexploder.cgi
+ M /iexploder/htdocs/iexploder.rb
+ A /iexploder/htdocs/webserver.rb
+
+New Webrick based option for standalone hosting
+------------------------------------------------------------------------
+r602 | thomas | 2006-04-18 16:18:35 -0400 (Tue, 18 Apr 2006) | 1 line
+Changed paths:
+ A /iexploder/htdocs/config.rb
+ M /iexploder/htdocs/cssproperties.in
+ M /iexploder/htdocs/iexploder.cgi
+ A /iexploder/htdocs/iexploder.rb
+
+Split iexploder.cgi into iexploder.rb and config.rb
+------------------------------------------------------------------------
+r601 | thomas | 2006-04-18 13:36:25 -0400 (Tue, 18 Apr 2006) | 1 line
+Changed paths:
+ M /iexploder/htdocs/cssvalues.in
+
+Add items from WebKit/WebCore/css/CSSValueKeywords.in
+------------------------------------------------------------------------
+r600 | thomas | 2006-04-18 13:32:45 -0400 (Tue, 18 Apr 2006) | 1 line
+Changed paths:
+ A /iexploder/testcases/opera/4750_Opera_8.5.4_Mac_OS_X-Crash.html
+
+Add odd new crash from Opera 8.5.4 for Mac
+------------------------------------------------------------------------
+r599 | thomas | 2006-04-18 13:10:15 -0400 (Tue, 18 Apr 2006) | 1 line
+Changed paths:
+ A /iexploder/testcases/safari/7483_Safari-Nightly-420+-2006-r13911-2006-04-18.html
+
+Add new Safari test case
+------------------------------------------------------------------------
+r598 | thomas | 2006-04-18 12:25:39 -0400 (Tue, 18 Apr 2006) | 1 line
+Changed paths:
+ M /iexploder/LICENSE.txt
+ M /iexploder/README.txt
+ M /iexploder/htdocs/htmlattrs.in
+ M /iexploder/htdocs/htmltags.in
+ M /iexploder/htdocs/iexploder.cgi
+
+iExploder 1.3: sync with modern rendering kits
+------------------------------------------------------------------------
+r597 | thomas | 2006-04-18 12:25:18 -0400 (Tue, 18 Apr 2006) | 1 line
+Changed paths:
+ A /iexploder/testcases/firefox/354_1-Firefox-1.5.0.1_Solaris-Crash.html
+ A /iexploder/testcases/firefox/44_9-Firefox-1.5.0.1_Solaris-Crash.html
+ A /iexploder/testcases/internet_explorer/8386_11-Internet-Explorer-6.0_WinXP-DoS.html (from /iexploder/testcases/safari/8386_11-Internet-Explorer-6.0_WinXP-DoS.html:596)
+ A /iexploder/testcases/safari/218-Safari-2.0.3_Mac_OS_X-Crash.html
+ D /iexploder/testcases/safari/8386_11-Internet-Explorer-6.0_WinXP-DoS.html
+
+New testcases
+------------------------------------------------------------------------
+r596 | thomas | 2006-04-18 12:23:48 -0400 (Tue, 18 Apr 2006) | 1 line
+Changed paths:
+ D /iexploder/testcases/119_4-Safari-Nightly-420+-2005-10-21-Crash.html
+ D /iexploder/testcases/165367_15-FireFox-1.4.1-Crash.html
+ D /iexploder/testcases/2009-iCab-3.0.1-Mac_OS_X-Crash.html
+ D /iexploder/testcases/2289-iCab-3.0.1-Crash.html
+ D /iexploder/testcases/25057-OmniWeb-5.1.1-Crash.html
+ D /iexploder/testcases/2624-Opera-8.5-Mac_OS_X-Crash.html
+ D /iexploder/testcases/502701_7-FireFox-1.4.1-Crash.html
+ D /iexploder/testcases/60253-OmniWeb-5.1.1-Crash.html
+ D /iexploder/testcases/6134_19-Safari-2.0.1-412.5-Crash.html
+ D /iexploder/testcases/8386_11-Internet-Explorer-6.0_WinXP-DoS.html
+ A /iexploder/testcases/firefox
+ A /iexploder/testcases/firefox/165367_15-Firefox-1.4.1-Crash.html (from /iexploder/testcases/165367_15-FireFox-1.4.1-Crash.html:595)
+ A /iexploder/testcases/firefox/502701_7-Firefox-1.4.1-Crash.html (from /iexploder/testcases/502701_7-FireFox-1.4.1-Crash.html:595)
+ A /iexploder/testcases/icab
+ A /iexploder/testcases/icab/2009-iCab-3.0.1-Mac_OS_X-Crash.html (from /iexploder/testcases/2009-iCab-3.0.1-Mac_OS_X-Crash.html:595)
+ A /iexploder/testcases/icab/2289-iCab-3.0.1-Crash.html (from /iexploder/testcases/2289-iCab-3.0.1-Crash.html:595)
+ A /iexploder/testcases/internet_explorer
+ A /iexploder/testcases/omniweb
+ A /iexploder/testcases/omniweb/25057-OmniWeb-5.1.1-Crash.html (from /iexploder/testcases/25057-OmniWeb-5.1.1-Crash.html:595)
+ A /iexploder/testcases/omniweb/60253-OmniWeb-5.1.1-Crash.html (from /iexploder/testcases/60253-OmniWeb-5.1.1-Crash.html:595)
+ A /iexploder/testcases/opera
+ A /iexploder/testcases/opera/2624-Opera-8.5-Mac_OS_X-Crash.html (from /iexploder/testcases/2624-Opera-8.5-Mac_OS_X-Crash.html:595)
+ A /iexploder/testcases/safari
+ A /iexploder/testcases/safari/119_4-Safari-Nightly-420+-2005-10-21-Crash.html (from /iexploder/testcases/119_4-Safari-Nightly-420+-2005-10-21-Crash.html:595)
+ A /iexploder/testcases/safari/6134_19-Safari-2.0.1-412.5-Crash.html (from /iexploder/testcases/6134_19-Safari-2.0.1-412.5-Crash.html:595)
+ A /iexploder/testcases/safari/8386_11-Internet-Explorer-6.0_WinXP-DoS.html (from /iexploder/testcases/8386_11-Internet-Explorer-6.0_WinXP-DoS.html:595)
+
+Reshuffle testcases
+------------------------------------------------------------------------
+r521 | thomas | 2005-11-03 22:01:43 -0500 (Thu, 03 Nov 2005) | 1 line
+Changed paths:
+ A /iexploder/testcases/2289-iCab-3.0.1-Crash.html
+ A /iexploder/testcases/60253-OmniWeb-5.1.1-Crash.html
+
+add some test cases
+------------------------------------------------------------------------
+r520 | thomas | 2005-11-03 22:01:19 -0500 (Thu, 03 Nov 2005) | 1 line
+Changed paths:
+ M /iexploder/htdocs/iexploder.cgi
+
+Add some cute tabs
+------------------------------------------------------------------------
+r508 | thomas | 2005-10-21 15:34:38 -0400 (Fri, 21 Oct 2005) | 1 line
+Changed paths:
+ A /iexploder/testcases/165367_15-FireFox-1.4.1-Crash.html (from /iexploder/testcases/165367_15-FireFox-1.4.1-Mac_OS_X-Crash.html:505)
+ D /iexploder/testcases/165367_15-FireFox-1.4.1-Mac_OS_X-Crash.html
+
+Crash is not OSX specific
+------------------------------------------------------------------------
+r507 | thomas | 2005-10-21 14:59:41 -0400 (Fri, 21 Oct 2005) | 1 line
+Changed paths:
+ M /iexploder/README.txt
+
+Mention the fact that testcases may not be portable across installations
+------------------------------------------------------------------------
+r506 | thomas | 2005-10-21 14:45:48 -0400 (Fri, 21 Oct 2005) | 1 line
+Changed paths:
+ M /iexploder/htdocs/index.html
+
+Fix lookup html code
+------------------------------------------------------------------------
+r505 | thomas | 2005-10-21 14:22:10 -0400 (Fri, 21 Oct 2005) | 1 line
+Changed paths:
+ A /iexploder/testcases/165367_15-FireFox-1.4.1-Mac_OS_X-Crash.html
+
+QuickDraw crash for Mac OS X
+------------------------------------------------------------------------
+r504 | thomas | 2005-10-21 14:14:34 -0400 (Fri, 21 Oct 2005) | 1 line
+Changed paths:
+ A /iexploder/testcases/25057-OmniWeb-5.1.1-Crash.html
+
+New crash
+------------------------------------------------------------------------
+r503 | thomas | 2005-10-21 14:06:45 -0400 (Fri, 21 Oct 2005) | 1 line
+Changed paths:
+ A /iexploder/testcases/8386_11-Internet-Explorer-6.0_WinXP-DoS.html
+
+IE DoS
+------------------------------------------------------------------------
+r502 | thomas | 2005-10-21 13:24:02 -0400 (Fri, 21 Oct 2005) | 1 line
+Changed paths:
+ M /iexploder/README.txt
+ M /iexploder/htdocs/cssvalues.in
+ M /iexploder/htdocs/iexploder.cgi
+ M /iexploder/htdocs/index.html
+ D /iexploder/testcases/100482.html
+ D /iexploder/testcases/103399-nscssvaluelist.html
+ A /iexploder/testcases/119_4-Safari-Nightly-420+-2005-10-21-Crash.html
+ A /iexploder/testcases/2009-iCab-3.0.1-Mac_OS_X-Crash.html
+ A /iexploder/testcases/2624-Opera-8.5-Mac_OS_X-Crash.html
+ A /iexploder/testcases/502701_7-FireFox-1.4.1-Crash.html
+ A /iexploder/testcases/6134_19-Safari-2.0.1-412.5-Crash.html
+ D /iexploder/testcases/firefox-caption-iframe-table-47179.html
+ D /iexploder/testcases/firefox-caption-marquee-27473.html
+ D /iexploder/testcases/firefox-caption-marquee-66937.html
+ D /iexploder/testcases/firefox-isindex-18149.html
+ D /iexploder/testcases/firefox-visibility-caption-111895.html
+
+1.2 Update, mostly documentation and test cases
+------------------------------------------------------------------------
+r501 | thomas | 2005-10-21 11:41:39 -0400 (Fri, 21 Oct 2005) | 1 line
+Changed paths:
+ M /iexploder/tools/osx_last_crash.rb
+
+back to days, filter out synergy
+------------------------------------------------------------------------
+r500 | thomas | 2005-10-21 11:25:28 -0400 (Fri, 21 Oct 2005) | 1 line
+Changed paths:
+ M /iexploder/htdocs/cssvalues.in
+ M /iexploder/htdocs/iexploder.cgi
+ M /iexploder/tools/lasthit.rb
+
+1.2: We now use javascript reloads after 1 second in case the meta breaks (IE)
+------------------------------------------------------------------------
+r499 | thomas | 2005-10-21 08:51:07 -0400 (Fri, 21 Oct 2005) | 1 line
+Changed paths:
+ M /iexploder/htdocs/iexploder.cgi
+
+1.1: Fix up our subtest model
+------------------------------------------------------------------------
+r498 | thomas | 2005-10-20 21:55:59 -0400 (Thu, 20 Oct 2005) | 1 line
+Changed paths:
+ M /iexploder/htdocs/iexploder.cgi
+
+Support for subtests, and compatibility with mod_ruby
+------------------------------------------------------------------------
+r497 | thomas | 2005-10-20 20:48:59 -0400 (Thu, 20 Oct 2005) | 1 line
+Changed paths:
+ M /iexploder/htdocs/cssproperties.in
+ M /iexploder/htdocs/cssvalues.in
+ M /iexploder/htdocs/htmlattrs.in
+ M /iexploder/htdocs/htmlvalues.in
+ M /iexploder/htdocs/iexploder.cgi
+
+update to v1.0
+------------------------------------------------------------------------
+r455 | tstrombe | 2005-02-28 08:13:25 -0500 (Mon, 28 Feb 2005) | 1 line
+Changed paths:
+ A /iexploder
+ A /iexploder/LICENSE.txt
+ A /iexploder/README.txt
+ A /iexploder/htdocs
+ A /iexploder/htdocs/cssproperties.in
+ A /iexploder/htdocs/cssvalues.in
+ A /iexploder/htdocs/htmlattrs.in
+ A /iexploder/htdocs/htmltags.in
+ A /iexploder/htdocs/htmlvalues.in
+ A /iexploder/htdocs/iexploder.cgi
+ A /iexploder/htdocs/index.html
+ A /iexploder/testcases
+ A /iexploder/testcases/100482.html
+ A /iexploder/testcases/103399-nscssvaluelist.html
+ A /iexploder/testcases/firefox-caption-iframe-table-47179.html
+ A /iexploder/testcases/firefox-caption-marquee-27473.html
+ A /iexploder/testcases/firefox-caption-marquee-66937.html
+ A /iexploder/testcases/firefox-isindex-18149.html
+ A /iexploder/testcases/firefox-visibility-caption-111895.html
+ A /iexploder/tools
+ A /iexploder/tools/lasthit.rb
+ A /iexploder/tools/osx_last_crash.rb
+
+iexploder software
+------------------------------------------------------------------------
diff --git a/WebKitTools/iExploder/LICENSE.txt b/WebKitTools/iExploder/LICENSE.txt
new file mode 100644
index 0000000..5199718
--- /dev/null
+++ b/WebKitTools/iExploder/LICENSE.txt
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2005 Thomas Stromberg <thomas%stromberg.org>
+#
+# This software is provided 'as-is', without any express or implied warranty.
+# In no event will the authors be held liable for any damages arising from the
+# use of this software.
+#
+# Permission is granted to anyone to use this software for any purpose,
+# including commercial applications, and to alter it and redistribute it
+# freely, subject to the following restrictions:
+#
+# 1. The origin of this software must not be misrepresented; you must not
+# claim that you wrote the original software. If you use this software in a
+# product, an acknowledgment in the product documentation would be appreciated
+# but is not required.
+#
+# 2. Altered source versions must be plainly marked as such, and must not be
+# misrepresented as being the original software.
+#
+# 3. This notice may not be removed or altered from any source distribution.
diff --git a/WebKitTools/iExploder/README.txt b/WebKitTools/iExploder/README.txt
new file mode 100644
index 0000000..a941697
--- /dev/null
+++ b/WebKitTools/iExploder/README.txt
@@ -0,0 +1,149 @@
+iExploder 1.3.2
+===============
+
+Welcome to iExploder. a highly inefficient, but fairly effective web
+browser tester. The code still has a lot of work to be done, but it's
+definitely usable. Here are some notable features:
+
+* Tests all common HTML and CSS tags and attributes, as parsed from
+the KHTML, WebKit and Mozilla source trees, as well as tags for
+Internet Explorer from MSDN. This also includes a few Javascript hooks.
+* Numeric, and String overflow and formatting tests
+* Sequential and Randomized Test Case Generation
+* Test Case Lookups
+* Subtest generation
+
+
+Installation (Standalone)
+-------------------------
+Make sure you have Ruby installed (comes with Mac OS X, most Linux
+distributions). See http://www.ruby-lang.org/ if you do not.
+
+If you do not already have a webserver setup, you can use the server
+built into iexploder. Simply go into the htdocs directory and type:
+
+% ruby webserver.rb
+
+A webserver will then start on port 2000 with the iexploder form. If
+port 2000 is not preferable, you can pass it another port on the command
+line:
+
+% ruby webserver.rb 2001
+
+Please note that lasthit.rb does not currently work with the logs output
+from this method. I recommend using a seperate instance/port number
+for each browser you test simultaneous using this method.
+
+
+Installation (External Webserver)
+---------------------------------
+If you wish to use an external webserver (required for lasthit.rb use),
+you may do so. IExploder has been tested with apache.
+
+Copy the contents of the htdocs/ folder to any directory served
+by your webserver. Make sure that directory can execute CGI scripts. If
+performance seems to be low, please try using mod_ruby.
+
+
+FAQ:
+----
+1) Are the tests always the same?
+
+ The test cases should always be the same on a single installation, but not
+necessarily on different installations of iExploder. Random generator seeds
+may differ between operating systems and platforms. If you alter the tag and
+property counts in config.rb, it will change the test cases as well.
+
+
+2) How do I look up the last successful test for a client?
+
+Use tools/lasthit.rb. When I get a crash, I usually do something like:
+
+ % tail -15000 /var/log/apache2/access_log | ./lasthit.rb
+
+Letting you know how many tests and what the last test id was for each
+client tested. You can then try to repeat the test, or go through the
+subtests to see if you can repeat the crash.
+
+
+3) How do subtests work?
+
+If you see a crash on a particular test, and would like to determine the exact
+line that is crashing it, you can use subtests. To do so, go back to the test
+submission form, and start the test from the number that a crash was indicated
+on. Instead of leaving the "subtest" field blank, set it to 1. This will rotate
+through each subtest for a particular test.
+
+Each subtest will rotate through a tag offset and a number of tags to
+garble, which should help you isolate the instance. The number of tags
+used doubles each cycle. Here is an idea of how many subtests to expect
+based on your $HTML_MAX_TAGS settings:
+
+tags subtests
+----------------
+32 138
+48 236
+64 332
+96 558
+128 782
+
+Most of the time you will be able to replicate a crash within the first
+$HTML_MAX_TAGS subtests, but sometimes crashes are due to a combination
+of corrupted tags.
+
+
+4) How come I can't seem to repeat the crash?
+
+ Many browser crashes are race conditions that are not easy to repeat. Some
+crashes only happen when going from test 4 -> test 5 -> test 6. If you can't
+repeat the crash through subtests or a lookup of the failing test, try going
+back a few tests.
+
+That said, some crashes are due to race conditions that are very difficult
+to replicate.
+
+
+5) Why did you write this?
+
+ I wanted to make sure that FireFox had as many bugs fixed in it as possible
+before the 1.0 release. After 1.0 came out, I kept improving it.
+
+
+6) Why does Internet Explorer run the tests so slowly?
+
+ <META> refresh tags are very fragile in Internet Explorer, and can be easily
+be rendered useless by other tags on the page. If this happens, a javascript
+refresh will execute after a 1 second delay.
+
+
+
+7) How do I change the number of tags iExploder tests per page?
+
+See config.rb. I personally recommend 32-128 HTML tags per page. While this
+seems to be a lot to go through when designing a test case, that's why the
+subtest engine was made. Different web browsers will have different
+performance characteristics when it comes to the number of tags per page.
+
+Here are the results with Firefox 2.0b1 (Bon Echo) and the iExploder
+built-in webserver running tests 1-250.
+
+tags seconds pages/second tags/second
+-----------------------------------------
+32 60 4.0 131
+48 85 2.9 141
+64 95 2.6 168
+96 120 2.1 200 *DEFAULT*
+128 140 1.8 228
+196 228 1.1 210
+256 308 0.8 207
+
+If you find pages/second to be more important than tags/second, I would
+change $HTML_MAX_TAGS to 32. Do keep in mind that large tag counts mean
+longer subtest generation periods.
+
+
+8) What other performance enhancements can I make?
+
+* Before using iExploder, reset your browser history
+* Minimize your browser while iExploder is running
+* If using Apache, make use of mod_ruby
diff --git a/WebKitTools/iExploder/htdocs/config.rb b/WebKitTools/iExploder/htdocs/config.rb
new file mode 100644
index 0000000..d9e7e1b
--- /dev/null
+++ b/WebKitTools/iExploder/htdocs/config.rb
@@ -0,0 +1,6 @@
+# Configuration for iExploder.. not generally tuned.
+
+$HTML_MAX_TAGS = 96;
+$HTML_MAX_ATTRS = 4;
+$CSS_MAX_PROPS = 5;
+
diff --git a/WebKitTools/iExploder/htdocs/cssproperties.in b/WebKitTools/iExploder/htdocs/cssproperties.in
new file mode 100644
index 0000000..2eb9e7a
--- /dev/null
+++ b/WebKitTools/iExploder/htdocs/cssproperties.in
@@ -0,0 +1,348 @@
+# From WebKit svn r24249 (WebCore/css/CSSPropertyNames.in)
+-webkit-appearance
+-webkit-background-clip
+-webkit-background-composite
+-webkit-background-origin
+-webkit-background-size
+-webkit-binding
+-webkit-border-bottom-left-radius
+-webkit-border-bottom-right-radius
+-webkit-border-fit
+-webkit-border-horizontal-spacing
+-webkit-border-image
+-webkit-border-radius
+-webkit-border-top-left-radius
+-webkit-border-top-right-radius
+-webkit-border-vertical-spacing
+-webkit-box-align
+-webkit-box-direction
+-webkit-box-flex
+-webkit-box-flex-group
+-webkit-box-lines
+-webkit-box-ordinal-group
+-webkit-box-orient
+-webkit-box-pack
+-webkit-box-shadow
+-webkit-box-sizing
+-webkit-column-break-after
+-webkit-column-break-before
+-webkit-column-break-inside
+-webkit-column-count
+-webkit-column-gap
+-webkit-column-rule
+-webkit-column-rule-color
+-webkit-column-rule-style
+-webkit-column-rule-width
+-webkit-column-width
+-webkit-columns
+-webkit-dashboard-region
+-webkit-font-size-delta
+-webkit-highlight
+-webkit-line-break
+-webkit-line-clamp
+-webkit-margin-bottom-collapse
+-webkit-margin-collapse
+-webkit-margin-start
+-webkit-margin-top-collapse
+-webkit-marquee
+-webkit-marquee-direction
+-webkit-marquee-increment
+-webkit-marquee-repetition
+-webkit-marquee-speed
+-webkit-marquee-style
+-webkit-match-nearest-mail-blockquote-color
+-webkit-nbsp-mode
+-webkit-padding-start
+-webkit-rtl-ordering
+-webkit-text-decorations-in-effect
+-webkit-text-fill-color
+-webkit-text-security
+-webkit-text-size-adjust
+-webkit-text-stroke
+-webkit-text-stroke-color
+-webkit-text-stroke-width
+-webkit-user-drag
+-webkit-user-modify
+-webkit-user-select
+background
+background-attachment
+background-color
+background-image
+background-position
+background-position-x
+background-position-y
+background-repeat
+border
+border-bottom
+border-bottom-color
+border-bottom-style
+border-bottom-width
+border-collapse
+border-color
+border-left
+border-left-color
+border-left-style
+border-left-width
+border-right
+border-right-color
+border-right-style
+border-right-width
+border-spacing
+border-style
+border-top
+border-top-color
+border-top-style
+border-top-width
+border-width
+bottom
+caption-side
+clear
+clip
+color
+content
+counter-increment
+counter-reset
+cursor
+direction
+display
+empty-cells
+float
+font
+font-family
+font-size
+font-stretch
+font-style
+font-variant
+font-weight
+height
+left
+letter-spacing
+line-height
+list-style
+list-style-image
+list-style-position
+list-style-type
+margin
+margin-bottom
+margin-left
+margin-right
+margin-top
+max-height
+max-width
+min-height
+min-width
+opacity
+orphans
+outline
+outline-color
+outline-offset
+outline-style
+outline-width
+overflow
+overflow-x
+overflow-y
+padding
+padding-bottom
+padding-left
+padding-right
+padding-top
+page
+page-break-after
+page-break-before
+page-break-inside
+position
+quotes
+resize
+right
+scrollbar-3dlight-color
+scrollbar-arrow-color
+scrollbar-darkshadow-color
+scrollbar-face-color
+scrollbar-highlight-color
+scrollbar-shadow-color
+scrollbar-track-color
+size
+table-layout
+text-align
+text-decoration
+text-indent
+text-line-through
+text-line-through-color
+text-line-through-mode
+text-line-through-style
+text-line-through-width
+text-overflow
+text-overline
+text-overline-color
+text-overline-mode
+text-overline-style
+text-overline-width
+text-shadow
+text-transform
+text-underline
+text-underline-color
+text-underline-mode
+text-underline-style
+text-underline-width
+top
+unicode-bidi
+vertical-align
+visibility
+white-space
+widows
+width
+word-break
+word-spacing
+word-wrap
+z-index
+
+# CSS3 properties - http://www.css3.info/preview/
+background-clip
+background-origin
+border-image
+border-radius
+box-shadow
+box-sizing
+column-count
+column-gap
+column-min-width
+column-rule
+column-rule-color
+column-rule-style
+column-rule-width
+column-space-distribution
+column-span
+column-width
+column-width-policy
+
+# All of the following are from khtml's cssproperties.in as of 19oct2004, but are no longer in WebKit
+-khtml-border-horizontal-spacing
+-khtml-border-vertical-spacing
+-khtml-flow-mode
+-khtml-marquee
+-khtml-marquee-direction
+-khtml-marquee-increment
+-khtml-marquee-repetition
+-khtml-marquee-speed
+-khtml-marquee-style
+-khtml-text-decoration-color
+-khtml-user-input
+scrollbar-base-color
+
+# Internet Explorer 6.0 - http://msdn.microsoft.com/workshop/author/css/reference/attributes.asp
+filter:progid:
+filter:
+ime-mode
+layout-flow
+layout-grid
+layout-grid-char
+layout-grid-line
+layout-grid-mode
+layout-grid-type
+line-break
+overflow-x
+overflow-y
+pagebreakafter
+pagebreakbefore
+ruby-align
+ruby-overhang
+ruby-position
+text-autospace
+text-justify
+text-kashida-space
+text-underline-position
+word-break
+writing-mode
+zoom
+
+# from http://msdn.microsoft.com/library/default.asp?url=/workshop/author/filter/reference/reference.asp
+filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(
+filter:progid:DXImageTransform.Microsoft.Blur(
+filter:progid:DXImageTransform.Microsoft.MotionBlur(
+filter:progid:DXImageTransform.Microsoft.Gradient(
+filter:progid:DXImageTransform.Microsoft.Pixelate(
+
+# From Mozilla Firefox CVS on 2006-04-15 (layout/style/nsCSSPropList.h)
+# grep "^CSS_PROP" nsCSSPropList.h | grep -v "_SVG" |cut -d, -f1 | cut -d\( -f2 | sort
+++ /tmp/moz Tue Apr 18 13:45:30 2006
+-moz-appearance
+-moz-background-clip
+-moz-background-inline-policy
+-moz-background-origin
+-moz-binding
+-moz-border-bottom-colors
+-moz-border-left-colors
+-moz-border-radius
+-moz-border-radius-bottomleft
+-moz-border-radius-bottomright
+-moz-border-radius-topleft
+-moz-border-radius-topright
+-moz-border-right-colors
+-moz-border-top-colors
+-moz-box-align
+-moz-box-direction
+-moz-box-flex
+-moz-box-ordinal-group
+-moz-box-orient
+-moz-box-pack
+-moz-box-sizing
+-moz-column-count
+-moz-column-gap
+-moz-column-width
+-moz-float-edge
+-moz-force-broken-image-icon
+-moz-image-region
+-moz-margin-end
+-moz-margin-start
+-moz-outline-radius
+-moz-outline-radius-bottomleft
+-moz-outline-radius-bottomright
+-moz-outline-radius-topleft
+-moz-outline-radius-topright
+-moz-padding-end
+-moz-padding-start
+-moz-user-focus
+-moz-user-input
+-moz-user-modify
+-moz-user-select
+-x-background-x-position
+-x-background-y-position
+azimuth
+cue
+cue-after
+cue-before
+elevation
+font-size-adjust
+margin-end-value
+margin-left-ltr-source
+margin-left-rtl-source
+margin-left-value
+margin-right-ltr-source
+margin-right-rtl-source
+margin-right-value
+margin-start-value
+marker
+marker-offset
+marks
+padding-end-value
+padding-left-ltr-source
+padding-left-rtl-source
+padding-left-value
+padding-right-ltr-source
+padding-right-rtl-source
+padding-right-value
+padding-start-value
+pause
+pause-after
+pause-before
+pitch
+pitch-range
+richness
+speak
+speak-header
+speak-numeral
+speak-punctuation
+speech-rate
+stress
+voice-family
+volume
diff --git a/WebKitTools/iExploder/htdocs/cssvalues.in b/WebKitTools/iExploder/htdocs/cssvalues.in
new file mode 100644
index 0000000..c19f78f
--- /dev/null
+++ b/WebKitTools/iExploder/htdocs/cssvalues.in
@@ -0,0 +1,339 @@
+"Trebuchet MS",Verdana, Arial, Helvetica, sans-serif
+#339933 !important !important !important
+#9999999999999999999999999999999999999999999
+-5, -5, -5
+-9999%
+-999999999999999999999999999%
+-999999999999999999999999999em
+-999999999999999999999999999px
+-9999em
+-9999px
+-webkit-activelink
+-webkit-auto
+-webkit-baseline-middle
+-webkit-body
+-webkit-box
+-webkit-center
+-webkit-focus-ring-color
+-webkit-inline-box
+-webkit-left
+-webkit-link
+-webkit-marquee
+-webkit-nowrap
+-webkit-overlay
+-webkit-right
+-webkit-text
+-webkit-xxx-large
+0
+0 auto
+0 fixed
+2%
+90000000000000000000000000000000000000000000%
+9999999999999999999999
+99999999999999999999999999999999999999 auto
+99999999999999999999999999999999999999999999px
+999999px solid #fff
+above
+absolute
+activeborder
+activecaption
+after-white-space
+ahead
+alternate
+always
+appworkspace
+aqua
+armenian
+attr("ATTRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
+auto
+avoid
+background
+backwards
+baseline
+below
+bidi-override
+black
+blink
+block
+block clear
+block width
+block-axis
+blue
+bold
+bolder
+border
+border-box
+both
+bottom
+break-word
+button
+button-bevel
+buttonface
+buttonhighlight
+buttonshadow
+buttontext
+capitalize
+caption
+captiontext
+caret
+center
+checkbox
+circle
+cjk-ideographic
+clip
+clip:rect(-0px -2000000px -200000px -0px)
+clip:rect(0px 2000000px 200000px 0px)
+close-quote
+collapse
+compact
+condensed
+content
+content-box
+continuous
+crop
+cross
+crosshair
+cursive
+dashed
+decimal
+decimal-leading-zero
+default
+disc
+discard
+dot-dash
+dot-dot-dash
+dotted
+double
+down
+e-resize
+element
+ellipsis
+embed
+end
+expanded
+extra-condensed
+extra-expanded
+fantasy
+fast
+fixed
+forwards
+fuchsia
+georgian
+gray
+graytext
+green
+grey
+groove
+hand
+hebrew
+help
+helvetica, arial, Courier New, Courier, Mono, Blah, Blah, Blah
+hidden
+hide
+higher
+highlight
+highlighttext
+hiragana
+hiragana-iroha
+horizontal
+icon
+ignore
+inactiveborder
+inactivecaption
+inactivecaptiontext
+infinite
+infobackground
+infotext
+inherit
+initial
+inline
+inline-axis
+inline-block
+inline-table
+inset
+inside
+intrinsic
+invert
+italic
+justify
+katakana
+katakana-iroha
+landscape
+large
+larger
+left
+level
+lighter
+lime
+line-through
+list-item
+listbox
+listitem
+logical
+loud
+lower
+lower-alpha
+lower-greek
+lower-latin
+lower-roman
+lowercase
+ltr
+marker
+maroon
+match
+medium
+menu
+menulist
+menulist-button
+menulist-text
+menulist-textfield
+menutext
+message-box
+middle
+min-intrinsic
+mix
+monospace
+move
+multiple
+n-resize
+narrower
+navy
+ne-resize
+no-close
+no-close-quote
+no-open-quote
+no-repeat
+none
+normal
+normal !important
+nowrap
+nw-resize
+oblique
+olive
+once
+open-quote
+orange
+outset
+outside
+overline
+padding
+pointer
+portrait
+pre
+pre-line
+pre-wrap
+purple
+push-button
+radio
+read-only
+read-write
+read-write-plaintext-only
+red
+relative
+repeat
+repeat-x
+repeat-y
+reverse
+rgb(9999999999, 999999999, 9999999999999)
+ridge
+right
+round
+rtl
+run-in
+s-resize
+sans-serif
+scroll
+scrollbar
+scrollbarbutton-down
+scrollbarbutton-left
+scrollbarbutton-right
+scrollbarbutton-up
+scrollbargripper-horizontal
+scrollbargripper-vertical
+scrollbarthumb-horizontal
+scrollbarthumb-vertical
+scrollbartrack-horizontal
+scrollbartrack-vertical
+se-resize
+searchfield
+searchfield-close
+searchfield-results
+semi-condensed
+semi-expanded
+separate
+serif
+show
+silver
+single
+skip-white-space
+slide
+slider-horizontal
+slider-vertical
+sliderthumb-horizontal
+sliderthumb-vertical
+slow
+small
+small-caps
+small-caption
+smaller
+solid
+space
+square
+square-button
+start
+static
+status-bar
+stretch
+sub
+super
+sw-resize
+table
+table-caption
+table-cell
+table-column
+table-column-group
+table-footer-group
+table-header-group
+table-row
+table-row-group
+teal
+text
+text-bottom
+text-top
+textfield
+thick
+thick dashed yellow
+thick dotted blue
+thin
+threeddarkshadow
+threedface
+threedhighlight
+threedlightshadow
+threedshadow
+top
+transparent
+ultra-condensed
+ultra-expanded
+underline
+unfurl
+up
+upper-alpha
+upper-latin
+upper-roman
+uppercase
+vertical
+visible
+visual
+w-resize
+wait
+wave
+white
+wider
+window
+windowframe
+windowtext
+x-large
+x-small
+xx-large
+xx-small
+yellow
diff --git a/WebKitTools/iExploder/htdocs/htmlattrs.in b/WebKitTools/iExploder/htdocs/htmlattrs.in
new file mode 100644
index 0000000..ad92384
--- /dev/null
+++ b/WebKitTools/iExploder/htdocs/htmlattrs.in
@@ -0,0 +1,259 @@
+# the following come from WebCore 2006-04-15 (WebKit/WebCore/html/HTMLNames.h)
+
+abbr
+accept
+accept_charset
+accesskey
+action
+align
+alink
+alt
+archive
+autocomplete
+autosave
+axis
+background
+behavior
+bgcolor
+bgproperties
+border
+bordercolor
+cellborder
+cellpadding
+cellspacing
+challenge
+char
+charoff
+charset
+checked
+cite
+class
+classid
+clear
+code
+codebase
+codetype
+color
+cols
+colspan
+compact
+composite
+content
+contenteditable
+coords
+data
+datetime
+declare
+defer
+dir
+direction
+disabled
+enctype
+face
+for
+frame
+frameborder
+headers
+height
+hidden
+href
+hreflang
+hspace
+http_equiv
+id
+incremental
+ismap
+keytype
+label
+lang
+language
+left
+leftmargin
+link
+longdesc
+loop
+marginheight
+marginwidth
+max
+maxlength
+mayscript
+media
+method
+min
+multiple
+name
+nohref
+noresize
+noshade
+nowrap
+object
+onabort
+onbeforecopy
+onbeforecut
+onbeforepaste
+onbeforeunload
+onblur
+onchange
+onclick
+oncontextmenu
+oncopy
+oncut
+ondblclick
+ondrag
+ondragend
+ondragenter
+ondragleave
+ondragover
+ondragstart
+ondrop
+onerror
+onfocus
+oninput
+onkeydown
+onkeypress
+onkeyup
+onload
+onmousedown
+onmousemove
+onmouseout
+onmouseover
+onmouseup
+onmousewheel
+onpaste
+onreset
+onresize
+onscroll
+onsearch
+onselect
+onselectstart
+onsubmit
+onunload
+pagex
+pagey
+placeholder
+plain
+pluginpage
+pluginspage
+pluginurl
+precision
+profile
+prompt
+readonly
+rel
+results
+rev
+rows
+rowspan
+rules
+scheme
+scope
+scrollamount
+scrolldelay
+scrolling
+selected
+shape
+size
+span
+src
+standby
+start
+style
+summary
+tabindex
+tableborder
+target
+text
+title
+top
+topmargin
+truespeed
+type
+usemap
+valign
+value
+valuetype
+version
+vlink
+vspace
+width
+wrap
+
+# was in khtml in 2004, but is no longer in WebCore
+accept-charset
+html
+http-equiv
+nosave
+oversrc
+unknown
+visibility
+z-index
+
+# From Mozilla CVS 2006-04-15 (mozilla/layout/style/xbl-marquee)
+bounce
+finish
+onbounce
+onfinish
+onstart
+
+
+# IE specific, from msdn.microsoft.com/workshop/author/dhtml/reference/properties
+acceptcharset
+allowtransparency
+balance
+choff
+datafld
+dataformatas
+datapagesize
+datasrc
+dynsrc
+framespacing
+galleryimg
+hidefocus
+methods
+scroll
+units
+urn
+volume
+
+# From Mozilla CVS 2006-04-15 (mozilla/content/base/src/nsGkAtomList.h)
+# To get these, I used:
+# ggrep -r "Get.*Attr" * | perl -ne 'if (/nsHTMLAtoms::(\w+)/) { \
+# system("grep \\($1, content/base/src/nsGkAtomList.h"); }' \
+# | cut -d\" -f2 | sort -u
+autocheck
+base
+bottommargin
+event
+font-weight
+handler
+layout
+observer
+ping
+point-size
+rightmargin
+variable
+
+# events from Mozilla CVS 2006-04-15 (mozilla/content/base/src/nsGkAtomList.h)
+# cat nsGkAtomList.h | grep GK_ATOM | cut -d\" -f2 | egrep "^on[a-z]+"
+onzoom
+onunderflow
+ontext
+onset
+onpopupshown
+onpopupshowing
+onpopuphiding
+onpopuphidden
+onpaint
+onpageshow
+onpagehide
+onoverflowchanged
+onoverflow
+onget
+ondraggesture
+ondragexit
+ondragdrop
+oncompositionstart
+oncompositionend
+oncommandupdate
+oncommand
+onclose
diff --git a/WebKitTools/iExploder/htdocs/htmltags.in b/WebKitTools/iExploder/htdocs/htmltags.in
new file mode 100644
index 0000000..acac8f3
--- /dev/null
+++ b/WebKitTools/iExploder/htdocs/htmltags.in
@@ -0,0 +1,128 @@
+# The following come from khtml's htmltags.in from 19oct2004
+# From WebCore svn tree, 2006-04-18 (WebKit/WebCore/html/HTMLNames.h)
+
+a
+abbr
+acronym
+address
+applet
+area
+b
+base
+basefont
+bdo
+big
+blockquote
+body
+br
+button
+canvas
+caption
+center
+cite
+code
+col
+colgroup
+dd
+del
+dfn
+dir
+div
+dl
+dt
+em
+embed
+fieldset
+font
+form
+frame
+frameset
+h1
+h2
+h3
+h4
+h5
+h6
+head
+hr
+html
+i
+iframe
+image
+img
+input
+ins
+isindex
+kbd
+keygen
+label
+layer
+legend
+li
+link
+listing
+map
+marquee
+menu
+meta
+nobr
+noembed
+noframes
+nolayer
+noscript
+object
+ol
+optgroup
+option
+p
+param
+plaintext
+pre
+q
+s
+samp
+script
+select
+small
+span
+strike
+strong
+style
+sub
+sup
+table
+tbody
+td
+textarea
+tfoot
+th
+thead
+title
+tr
+tt
+u
+ul
+var
+wbr
+xmp
+
+# This was in khtml in 10-2004
+ilayer
+
+# Additions from Mozilla CVS, 2006-04-18.
+# mozilla/parser/htmlparser/public/nsHTMLTagList.h
+bgsound
+blink
+multicol
+spacer
+
+# The following tags used to be in Mozilla in 10-2004, now removed
+counter
+endnote
+parsererror
+server
+sound
+sourcetext
+
+# From Internet Explorer - http://msdn.microsoft.com/workshop/author/html/reference/elements.asp
+xml
diff --git a/WebKitTools/iExploder/htdocs/htmlvalues.in b/WebKitTools/iExploder/htdocs/htmlvalues.in
new file mode 100644
index 0000000..d54984f
--- /dev/null
+++ b/WebKitTools/iExploder/htdocs/htmlvalues.in
@@ -0,0 +1,35 @@
+# Many of the following are from mangleme.cgi.c's make_up_value() function
+#
+*
+_blank
+_parent
+_self
+_top
+about:
+about:plugins
+file:
+http:
+jar:
+javascript:
+left
+top
+%n%n%n%n%n
+ftp:
+right
+wysiwyg:
+bottom
+none
+ldap:
+%i %i
+999999999,9999999,999999999,9999999,999999999,9999999,999999999,9999999,9
+999999999,9999999,9
+999999999,9999999
+true
+false
+_SEARCH
+javascript
+off
+on
+vbscript
+password
+image
diff --git a/WebKitTools/iExploder/htdocs/iexploder.cgi b/WebKitTools/iExploder/htdocs/iexploder.cgi
new file mode 100755
index 0000000..89e099c
--- /dev/null
+++ b/WebKitTools/iExploder/htdocs/iexploder.cgi
@@ -0,0 +1,45 @@
+#!/usr/bin/ruby
+# iExploder - Generates bad HTML files to perform QA for web browsers.
+# Developed for the Mozilla Foundation.
+#####################
+#
+# Copyright (c) 2006 Thomas Stromberg <thomas%stromberg.org>
+#
+# This software is provided 'as-is', without any express or implied warranty.
+# In no event will the authors be held liable for any damages arising from the
+# use of this software.
+#
+# Permission is granted to anyone to use this software for any purpose,
+# including commercial applications, and to alter it and redistribute it
+# freely, subject to the following restrictions:
+#
+# 1. The origin of this software must not be misrepresented; you must not
+# claim that you wrote the original software. If you use this software in a
+# product, an acknowledgment in the product documentation would be appreciated
+# but is not required.
+#
+# 2. Altered source versions must be plainly marked as such, and must not be
+# misrepresented as being the original software.
+#
+# 3. This notice may not be removed or altered from any source distribution.
+
+require 'cgi';
+require 'iexploder';
+require 'config';
+
+### THE INTERACTION ##################################
+ie = IExploder.new($HTML_MAX_TAGS, $HTML_MAX_ATTRS, $CSS_MAX_PROPS)
+ie.readTagFiles()
+
+cgi = CGI.new("html4");
+ie.url=ENV['SCRIPT_NAME'] || '?'
+ie.test_num = cgi.params['test'][0].to_i
+ie.subtest_num = cgi.params['subtest'][0].to_i || 0
+ie.random_mode = cgi.params['random'][0]
+ie.lookup_mode = cgi.params['lookup'][0]
+ie.stop_num = cgi.params['stop'][0].to_i || 0
+ie.setRandomSeed
+
+cgi.out('type' => 'text/html') do
+ ie.buildPage()
+end
diff --git a/WebKitTools/iExploder/htdocs/iexploder.rb b/WebKitTools/iExploder/htdocs/iexploder.rb
new file mode 100644
index 0000000..eee3e38
--- /dev/null
+++ b/WebKitTools/iExploder/htdocs/iexploder.rb
@@ -0,0 +1,337 @@
+# iExploder - Generates bad HTML files to perform QA for web browsers.
+# Developed for the Mozilla Foundation.
+#####################
+#
+# Copyright (c) 2006 Thomas Stromberg <thomas%stromberg.org>
+#
+# This software is provided 'as-is', without any express or implied warranty.
+# In no event will the authors be held liable for any damages arising from the
+# use of this software.
+#
+# Permission is granted to anyone to use this software for any purpose,
+# including commercial applications, and to alter it and redistribute it
+# freely, subject to the following restrictions:
+#
+# 1. The origin of this software must not be misrepresented; you must not
+# claim that you wrote the original software. If you use this software in a
+# product, an acknowledgment in the product documentation would be appreciated
+# but is not required.
+#
+# 2. Altered source versions must be plainly marked as such, and must not be
+# misrepresented as being the original software.
+#
+# 3. This notice may not be removed or altered from any source distribution.
+
+$VERSION="1.3.2"
+
+class IExploder
+ attr_accessor :test_num, :subtest_num, :lookup_mode, :random_mode, :url
+ attr_accessor :offset, :lines, :stop_num
+
+ def initialize(max_tags, max_attrs, max_props)
+ @htmlMaxTags = max_tags
+ @htmlMaxAttrs = max_attrs
+ @cssMaxProps = max_props
+ @mangledTagTotal = 0
+ @stop_num = 0
+ end
+
+ def setRandomSeed
+ if @test_num > 0
+ srand(@test_num)
+ else
+ srand
+ end
+ end
+
+
+ def readTagFiles
+ # These if statements are so that mod_ruby doesn't have to reload the files
+ # each time
+
+ if (! @cssTags)
+ @cssTags = readTagFile('cssproperties.in');
+ end
+
+ if (! @htmlTags)
+ @htmlTags = readTagFile('htmltags.in');
+ end
+ if (! @htmlAttr)
+ @htmlAttr = readTagFile('htmlattrs.in');
+ end
+
+ if (! @htmlValues)
+ @htmlValues = readTagFile('htmlvalues.in');
+ end
+
+ if (! @cssValues)
+ @cssValues = readTagFile('cssvalues.in');
+ end
+
+ end
+
+
+ def readTagFile(filename)
+ list = Array.new
+ File.new(filename).readlines.each { |line|
+ line.chop!
+
+ # Don't include comments.
+ if (line !~ /^# /) && (line.length > 0)
+ list << line
+ end
+ }
+ return list
+ end
+
+ # based on make_up_value, essentially.
+ def inventValue
+ value = rand(19);
+ case value
+ when 1..3 then return (@htmlValues[rand(@htmlValues.length)])
+ when 4..5 then return (@htmlValues[rand(@htmlValues.length)] + inventValue())
+ when 6 then return (@htmlValues[rand(@htmlValues.length)] + "//" + inventValue())
+ when 7 then return ''
+ # this may return negative argument?
+ when 8..10 then return rand(255).chr * (rand(256)+8)
+ when 11 then return rand(255).chr * (rand(2048)+8)
+ when 12 then return "#" + rand(999999).to_s
+ when 13 then return rand(999999).to_s + "%"
+ when 14..15 then return "&" + rand(999999).to_s + ";"
+ # filters
+ when 16 then
+ return inventValue() + "=" + inventValue()
+
+ # this my return undefined method + for nil:NilClass
+ when 17 then return inventValue() + "," + inventValue()
+ else
+ if rand(5) > 3
+ return "-" + rand(999999).to_s
+ else
+ return rand(999999).to_s
+ end
+ end
+ end
+
+ # based on make_up_value, essentially.
+ def inventCssValue(tag)
+ value = rand(23);
+ case value
+ when 1..10 then return @cssValues[rand(@cssValues.length)]
+ when 11 then return ''
+ when 12 then return rand(255).chr * (rand(8192)+8)
+ when 13
+ length = rand(1024) + 8
+ return (rand(255).chr * length) + " " + (rand(255).chr * length) + " " + (rand(255).chr * length)
+ when 14 then return (rand(255).chr * (rand(1024)+3)) + "px"
+ when 15 then return (rand(255).chr * (rand(1024)+3)) + "em"
+ when 16 then return "url(" + inventValue() + ")"
+ when 17..18 then return "#" + rand(999999999).to_s
+ when 19 then return "-" + rand(99999999).to_s
+ else return rand(99999999).to_s;
+ end
+ end
+
+
+ def mangleTag(tag)
+ @mangledTagTotal += 1
+ out = ''
+
+ # 20% chance of closing a tag instead of opening it. This
+ # still counts against @mangledTagTotal, however.
+ if rand(10) > 8
+ out = "</" + tag + ">"
+ return out
+ end
+
+ # we're opening it.
+ out = "<" + tag
+
+ # forgot the space between the tag and the attributes
+ if rand(15) > 1
+ out << ' '
+ end
+
+ attrNum = rand(@htmlMaxAttrs) + 1
+
+ 1.upto(attrNum) {
+ attr = @htmlAttr[rand(@htmlAttr.length)]
+
+ out << attr
+
+ # 7.5% of the time we skip the = sign. Don't prefix it
+ # if the attribute ends with a ( however.
+
+
+ if rand(15) > 1
+ out << '='
+ end
+
+ # sometimes quote it, sometimes not. I doubt the importance
+ # of this test, but mangleme-1.2 added it, and adding more
+ # random-ness never hurt anything but time. I'll do it less often.
+ quote = rand(2)
+ if (quote > 1)
+ out << "\""
+ end
+
+ out << inventValue()
+
+ # end the quote when you are done
+ if (quote > 1)
+ out << "\" "
+ end
+
+ # 5% chance we skip the space at the end of the name
+ if rand(20) > 1
+ out << ' '
+ end
+
+ }
+
+ # CSS styles!
+ if rand(4) > 1
+ out << " style=\""
+ 1.upto(rand(@cssMaxProps)+1) {
+ out << @cssTags[rand(@cssTags.length)]
+
+ # very small chance we let the tag run on.
+ if rand(50) > 1
+ out << ": "
+ end
+
+ out << inventCssValue(tag)
+ # we almost always put the ; there.
+ if rand(50) > 1
+ out << '; '
+ end
+ }
+ out << "\""
+ end
+
+ out << ">\n"
+
+ # support our local troops!
+ if (@subtest_num > 0) && filterSubTest()
+ if tag =~ /html|body|head/
+ return '<' + tag + '>'
+ else
+ return "<x-#@mangledTagTotal>\n"
+ end
+ else
+ return out
+ end
+ end
+ #end
+
+ def filterSubTest()
+ result = 1
+ if (@mangledTagTotal >= @offset) && (@mangledTagTotal < (@offset + @lines))
+ result = nil
+ end
+ return result
+ end
+
+ def nextTestNum()
+ if random_mode
+ n = rand(99999999)
+ else
+ if @test_num
+ n = @test_num + 1
+ else
+ n = 1
+ end
+ end
+ return n
+ end
+
+ # If we are at line 30 with 8 extra lines, there is no point to try line 31
+ # with 8 lines as well.. skip back to 1 and bump up the line count.
+ def nextSubTestNum()
+ if (@offset + @lines) > @htmlMaxTags
+ nextNum = ((@lines * 2 -1)) * @htmlMaxTags
+ else
+ nextNum = @subtest_num + 1
+ end
+ return nextNum
+ end
+
+
+ def buildPage
+ if (! @test_num) || (@test_num < 1)
+ @test_num = 1
+ end
+ next_num=nextTestNum()
+ @lines = @subtest_num.div(@htmlMaxTags) + 1
+ @offset = @subtest_num.modulo(@htmlMaxTags)
+
+ # building the HTML
+ bodyText = mangleTag('html')
+ bodyText << "\n<head>\n"
+
+ # Only do redirects if lookup=1 has not been specified.
+ if (! @lookup_mode) && (@lines <= @htmlMaxTags) && (@stop_num != @test_num)
+ newpage = @url + "?"
+ if @subtest_num > 0
+ newpage << "test=" << @test_num.to_s << "&subtest=" << nextSubTestNum().to_s
+ else
+ newpage << "test=" << next_num.to_s
+ end
+
+ if @random_mode
+ newpage << "&random=1"
+ end
+
+ if @stop_num > 0
+ newpage << "&stop=" << @stop_num.to_s
+ end
+
+ bodyText << "\t<META HTTP-EQUIV=\"Refresh\" content=\"0;URL=#{newpage}\">\n"
+ # use both techniques, because you never know how you might be corrupting yourself.
+ bodyText << "\t<script language=\"javascript\">setTimeout('window.location=\"#{newpage}\"', 1000);</script>\n"
+ end
+
+ bodyText << "\t" << mangleTag('meta')
+ bodyText << "\t" << mangleTag('meta')
+ bodyText << "\t" << mangleTag('link')
+
+ bodyText << "\t<title>[#@test_num] iExploder #{$VERSION} - #{inventValue()}</title>\n"
+ bodyText << "</head>\n\n"
+
+ # What tags will we be messing with ######################
+ tagList = [ 'body']
+
+ # we already have 5 tags?
+ 1.upto(@htmlMaxTags - 5 ) { tagList << @htmlTags[rand(@htmlTags.length)] }
+
+ tagList.each { |tag|
+ bodyText << mangleTag(tag)
+ bodyText << inventValue() + "\n"
+ }
+ bodyText << "</body>\n</html>"
+ end
+end
+
+
+
+if $0 == __FILE__
+ max=ARGV[0].to_i
+ puts "testing #{max} tags"
+ test = IExploder.new(max, 5, 5)
+ test.readTagFiles()
+ test.test_num=1
+ test.subtest_num=1
+ counter=0
+ test.lines=0
+
+ while test.lines < max
+ test.lines = test.subtest_num.div(max) + 1
+ test.offset = test.subtest_num.modulo(max)
+ test.subtest_num=test.nextSubTestNum
+ counter = counter + 1
+ puts "[#{counter}] subtest #{test.subtest_num} is #{test.lines} lines with #{test.offset} offset"
+ end
+
+ puts "for #{max} tests, you will have #{counter} iterations until #{test.subtest_num}"
+end
+
diff --git a/WebKitTools/iExploder/htdocs/index.html b/WebKitTools/iExploder/htdocs/index.html
new file mode 100644
index 0000000..849bc6b
--- /dev/null
+++ b/WebKitTools/iExploder/htdocs/index.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+ <title>iExploder 1.3.2</title>
+</head>
+<body>
+<h2>iExploder: Web Browser Quality Assurance Tester</h2>
+<small>Written by <a href="http://toadstool.se/">Thomas Str&ouml;mberg</a> for the
+<a href="http://www.mozilla.org/firefox/">Mozilla FireFox</a> project</small>
+
+
+<ul>
+ <li><a href="iexploder.cgi">Start test sequence from the beginning!</a></li>
+ <li><a href="iexploder.cgi?random=1">Start test sequence in random</a></li>
+ <li>Start testing from a test number:
+ <form method="get" action="iexploder.cgi" name="test">
+ Test: <input size="9" name="test" value="1"> Subtest: <input size="2" name="subtest" value="">
+ <input value="Start" type="submit">
+ </form>
+ </li>
+
+ <li>Lookup a single test number:
+ <form method="get" action="iexploder.cgi" name="test">
+ <input type="hidden" name="lookup" value="1">
+ Test: <input size="9" name="test" value="1"> Subtest: <input size="2" name="subtest" value="">
+ <input value="Lookup" type="submit"></form>
+ </li>
+</ul>
+
+If your browser crashes, please contact thomas%stromberg.org!
+
+</body>
+</html>
+
diff --git a/WebKitTools/iExploder/htdocs/webserver.rb b/WebKitTools/iExploder/htdocs/webserver.rb
new file mode 100755
index 0000000..5176172
--- /dev/null
+++ b/WebKitTools/iExploder/htdocs/webserver.rb
@@ -0,0 +1,75 @@
+#!/usr/bin/ruby
+# iExploder - Generates bad HTML files to perform QA for web browsers.
+# Developed for the Mozilla Foundation.
+#####################
+#
+# Copyright (c) 2006 Thomas Stromberg <thomas%stromberg.org>
+#
+# This software is provided 'as-is', without any express or implied warranty.
+# In no event will the authors be held liable for any damages arising from the
+# use of this software.
+#
+# Permission is granted to anyone to use this software for any purpose,
+# including commercial applications, and to alter it and redistribute it
+# freely, subject to the following restrictions:
+#
+# 1. The origin of this software must not be misrepresented; you must not
+# claim that you wrote the original software. If you use this software in a
+# product, an acknowledgment in the product documentation would be appreciated
+# but is not required.
+#
+# 2. Altered source versions must be plainly marked as such, and must not be
+# misrepresented as being the original software.
+#
+# 3. This notice may not be removed or altered from any source distribution.
+
+require 'webrick'
+require 'iexploder';
+require 'config';
+
+include WEBrick
+### THE INTERACTION ##################################
+$ie_preload = IExploder.new($HTML_MAX_TAGS, $HTML_MAX_ATTRS, $CSS_MAX_PROPS)
+$ie_preload.readTagFiles()
+$ie_preload.url='/iexploder.cgi'
+
+if ARGV[0]
+ port = ARGV[0].to_i
+else
+ port = 2000
+end
+
+puts "* iExploder #{$VERSION} will be available at http://localhost:#{port}"
+puts "* Max Tags: #$HTML_MAX_TAGS Max Attrs: #$HTML_MAX_ATTRS Max Props: #$CSS_MAX_PROPS"
+puts
+
+s = HTTPServer.new( :Port => port )
+class IEServlet < HTTPServlet::AbstractServlet
+ def do_GET(req, res)
+ ie = $ie_preload.dup
+ ie.test_num = req.query['test'].to_i
+ ie.subtest_num = req.query['subtest'].to_i || 0
+ ie.random_mode = req.query['random']
+ ie.lookup_mode = req.query['lookup']
+ ie.stop_num = req.query['stop'].to_i
+ ie.setRandomSeed
+
+ res['Content-Type'] = 'text/html'
+ res.body = ie.buildPage()
+ end
+end
+
+class IEForm < HTTPServlet::AbstractServlet
+ def do_GET(req, res)
+ res['Content-Type'] = 'text/html'
+ res.body = File.open("index.html").readlines.join("\n")
+ end
+end
+
+
+
+s.mount("/iexploder.cgi", IEServlet)
+s.mount("/", IEForm)
+trap("INT") { s.shutdown }
+
+s.start
diff --git a/WebKitTools/iExploder/tools/lasthit.rb b/WebKitTools/iExploder/tools/lasthit.rb
new file mode 100755
index 0000000..b569deb
--- /dev/null
+++ b/WebKitTools/iExploder/tools/lasthit.rb
@@ -0,0 +1,53 @@
+#!/usr/bin/ruby
+# lasthit, part of iExploder
+#
+# Shows statistics about recent agents that have tested with iExploder.
+# It takes all or part of an apache logfile via stdin, and outputs a list
+# of all the agents who tested within that section, what their last test
+# was, and how many tests they have done.
+
+# The usefulness is finding out where a browser crashed.
+
+
+hostHash = Hash.new
+
+if (ARGV[0])
+ file = File.open(ARGV[0])
+else
+ file = $stdin
+end
+
+file.readlines.each { |line|
+ if (line =~ /^(.*?) .*iexploder.*?test=(\d+).* HTTP.* \"(.*?)\"$/)
+ host = $1
+ testnum = $2
+ agent = $3
+ if (! hostHash[host])
+ hostHash[host] = Hash.new
+ end
+ if (! hostHash[host][agent])
+ hostHash[host][agent] = Hash.new
+ hostHash[host][agent]['total'] = 0
+ end
+
+ hostHash[host][agent]['last'] = testnum
+ if line =~ /subtest=(\d+)/
+ hostHash[host][agent]['subtest'] = $1
+ else
+ hostHash[host][agent]['subtest'] = ''
+ end
+ hostHash[host][agent]['total'] = hostHash[host][agent]['total'] + 1
+ end
+}
+
+printf("%14.14s | %8.8s | %3.3s | %8.8s | %s\n",
+ "IP", "Test", "SubTest", "Total", "Agent")
+puts "---------------------------------------------------------------------------"
+hostHash.each_key { |host|
+
+ hostHash[host].each_key { |agent|
+ printf("%14.14s | %8.8s | %3.3s | %8.8s | %s\n",
+ host, hostHash[host][agent]['last'], hostHash[host][agent]['subtest'], hostHash[host][agent]['total'], agent);
+ }
+}
+
diff --git a/WebKitTools/iExploder/tools/osx_last_crash.rb b/WebKitTools/iExploder/tools/osx_last_crash.rb
new file mode 100755
index 0000000..5b62c6d
--- /dev/null
+++ b/WebKitTools/iExploder/tools/osx_last_crash.rb
@@ -0,0 +1,48 @@
+#!/usr/bin/ruby
+# Gives you information about the most recent crash for each application
+# that has crashed within the last 2 days
+
+$LogDir=ENV['HOME'] + '/Library/Logs/CrashReporter'
+$Days=1
+$StackCount=5
+
+files=`find #$LogDir -mtime -#$Days -type f | grep -v synergy`
+files.each { |filename|
+ filename.chop!
+ record = 0
+ date=''
+ stackTrace = []
+
+ File.open(filename).readlines.each { |line|
+ #puts line
+
+ if line =~ /^Date.*(200.*)/
+ date = $1
+ end
+
+ if line =~ /^Thread \d+ Crashed/
+ record = 1
+ # reset the stack trace
+ stackTrace = []
+ end
+
+ if record
+ stackTrace << line
+ record = record + 1
+
+ # stop recording after $StackCount lines
+ if record > ($StackCount + 2)
+ record = nil
+ end
+ end
+ }
+
+ puts File.basename(filename) + " - " + date
+ puts "==================================================="
+ stackTrace.each { |line|
+ puts line
+ }
+ puts ""
+}
+
+
diff --git a/WebKitTools/iExploder/tools/showtest.rb b/WebKitTools/iExploder/tools/showtest.rb
new file mode 100755
index 0000000..af6b101
--- /dev/null
+++ b/WebKitTools/iExploder/tools/showtest.rb
@@ -0,0 +1,43 @@
+#!/usr/bin/ruby
+# showtest.rb - simple CLI interface to grab a testcase
+#####################
+#
+# Copyright (c) 2006 Thomas Stromberg <thomas%stromberg.org>
+#
+# This software is provided 'as-is', without any express or implied warranty.
+# In no event will the authors be held liable for any damages arising from the
+# use of this software.
+#
+# Permission is granted to anyone to use this software for any purpose,
+# including commercial applications, and to alter it and redistribute it
+# freely, subject to the following restrictions:
+#
+# 1. The origin of this software must not be misrepresented; you must not
+# claim that you wrote the original software. If you use this software in a
+# product, an acknowledgment in the product documentation would be appreciated
+# but is not required.
+#
+# 2. Altered source versions must be plainly marked as such, and must not be
+# misrepresented as being the original software.
+#
+# 3. This notice may not be removed or altered from any source distribution.
+
+Dir.chdir('../htdocs')
+require 'iexploder';
+require 'config';
+
+### THE INTERACTION ##################################
+ie = IExploder.new($HTML_MAX_TAGS, $HTML_MAX_ATTRS, $CSS_MAX_PROPS)
+ie.readTagFiles()
+
+if ! ARGV[0]
+ puts "syntax: showtest.rb [test#] [subtest#]"
+ exit
+end
+
+ie.test_num = ARGV[0].to_i
+ie.subtest_num = ARGV[1].to_i || 0
+ie.lookup_mode = 1
+ie.setRandomSeed
+
+puts ie.buildPage()
diff --git a/WebKitTools/mangleme/LICENSE b/WebKitTools/mangleme/LICENSE
new file mode 100644
index 0000000..5ab7695
--- /dev/null
+++ b/WebKitTools/mangleme/LICENSE
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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.1 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
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/WebKitTools/mangleme/Makefile b/WebKitTools/mangleme/Makefile
new file mode 100644
index 0000000..90d01e9
--- /dev/null
+++ b/WebKitTools/mangleme/Makefile
@@ -0,0 +1,16 @@
+#
+# HTML manglizer
+# --------------
+# Copyright (C) 2004 by Michal Zalewski <lcamtuf@coredump.cx>
+#
+# Makefile adapted for WebKit project.
+
+CC = gcc
+CFLAGS = -Wall -O3 -fomit-frame-pointer -funroll-loops
+OUTDIR = ../../WebKitBuild/mangleme
+
+all: $(OUTDIR)/mangle.cgi $(OUTDIR)/remangle.cgi
+
+$(OUTDIR)/%.cgi: %.cgi.c
+ if [ ! -d $(OUTDIR) ]; then mkdir -p $(OUTDIR); fi
+ $(CC) $(CFLAGS) $< -o $(OUTDIR)/$*.cgi
diff --git a/WebKitTools/mangleme/README b/WebKitTools/mangleme/README
new file mode 100644
index 0000000..4fe2928
--- /dev/null
+++ b/WebKitTools/mangleme/README
@@ -0,0 +1,20 @@
+
+ HTML manglizer
+ --------------
+
+ Copyright (C) 2004 by Michal Zalewski <lcamtuf@coredump.cx>
+
+ A trivial utility to automatically check for HTML parsing flaws. Generates
+ a basic set of badly mangled tags on request, with auto-refresh back to the
+ script, so that you can point a browser to it once, and let it run until
+ it crashes.
+
+ Put it in your cgi-bin directory or any other Apache folder with ExecCGI option
+ enabled, then visit the URL http://<yourserver>/<cgidir>/mangleme.cgi.
+
+ When the browser crashes, error-log should be examined for the last matching
+ entry generated by mangle.cgi; extract the hexadecimal value, then invoke
+ remangle.cgi?hex_value from the browser again. If it crashes, you've reproduced
+ the problem, and can save the remangle.cgi page using wget or such.
+
+ Check gallery/ for some samples.
diff --git a/WebKitTools/mangleme/mangle.cgi.c b/WebKitTools/mangleme/mangle.cgi.c
new file mode 100644
index 0000000..12ca948
--- /dev/null
+++ b/WebKitTools/mangleme/mangle.cgi.c
@@ -0,0 +1,122 @@
+/*
+
+ HTML manglizer
+ --------------
+ Copyright (C) 2004 by Michal Zalewski <lcamtuf@coredump.cx>
+
+ HTML manglizer library. Logs random seeds to error-log; find the last entry before
+ crash, then pass it to remangle.cgi to reproduce the problem.
+
+ */
+
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "tags.h"
+
+#define R(x) (rand() % (x))
+
+#define MAXTCOUNT 100
+#define MAXPCOUNT 20
+#define MAXSTR2 80
+
+void make_up_value(void) {
+ char c=R(2);
+
+ if (c) putchar('"');
+
+ switch (R(31)) {
+
+ case 0: printf("javascript:"); make_up_value(); break;
+// case 1: printf("jar:"); make_up_value(); break;
+ case 2: printf("mk:"); make_up_value(); break;
+ case 3: printf("file:"); make_up_value(); break;
+ case 4: printf("http:"); make_up_value(); break;
+ case 5: printf("about:"); make_up_value(); break;
+ case 6: printf("_blank"); break;
+ case 7: printf("_self"); break;
+ case 8: printf("top"); break;
+ case 9: printf("left"); break;
+ case 10: putchar('&'); make_up_value(); putchar(';'); break;
+ case 11: make_up_value(); make_up_value(); break;
+
+ case 12 ... 20: {
+ int c = R(10) ? R(10) : (1 + R(MAXSTR2) * R(MAXSTR2));
+ char* x = malloc(c);
+ memset(x,R(256),c);
+ fwrite(x,c,1,stdout);
+ free(x);
+ break;
+ }
+
+ case 21: printf("%s","%n%n%n%n%n%n"); break;
+ case 22: putchar('#'); break;
+ case 23: putchar('*'); break;
+ default: if (R(2)) putchar('-'); printf("%d",rand()); break;
+
+ }
+
+ if (c) putchar('"');
+
+}
+
+
+void random_tag(void) {
+ int tn, tc;
+
+ do tn = R(MAXTAGS); while (!tags[tn][0]);
+ tc = R(MAXPCOUNT) + 1;
+
+ putchar('<');
+
+ switch (R(10)) {
+ case 0: putchar(R(256)); break;
+ case 1: putchar('/');
+ }
+
+ printf("%s", tags[tn][0]);
+
+ while (tc--) {
+ int pn;
+ switch (R(32)) {
+ case 0: putchar(R(256));
+ case 1: break;
+ default: putchar(' ');
+ }
+ do pn = R(MAXPARS-1) + 1; while (!tags[tn][pn]);
+ printf("%s", tags[tn][pn]);
+ switch (R(32)) {
+ case 0: putchar(R(256));
+ case 1: break;
+ default: putchar('=');
+ }
+
+ make_up_value();
+
+ }
+
+ putchar('>');
+
+}
+
+
+int main(int argc,char** argv) {
+ int tc,seed;
+
+ printf("Content-Type: text/html;charset=utf-8\nRefresh: 0;URL=mangle.cgi\n\n");
+ printf("<HTML><HEAD><META HTTP-EQUIV=\"Refresh\" content=\"0;URL=mangle.cgi\">\n");
+ printf("<script language=\"javascript\">setTimeout('window.location=\"mangle.cgi\"', 1000);</script>\n");
+
+ seed = (time(0) ^ (getpid() << 16));
+ fprintf(stderr,"[%u] Mangle attempt 0x%08x (%s) -- %s\n", (int)time(0), seed, getenv("HTTP_USER_AGENT"), getenv("REMOTE_ADDR"));
+ srand(seed);
+
+ tc = R(MAXTCOUNT) + 1;
+ while (tc--) random_tag();
+ fflush(0);
+ return 0;
+}
diff --git a/WebKitTools/mangleme/remangle.cgi.c b/WebKitTools/mangleme/remangle.cgi.c
new file mode 100644
index 0000000..ccc4472
--- /dev/null
+++ b/WebKitTools/mangleme/remangle.cgi.c
@@ -0,0 +1,125 @@
+/*
+
+ HTML manglizer
+ --------------
+ Copyright (C) 2004 by Michal Zalewski <lcamtuf@coredump.cx>
+
+ Fault reproduction utility.
+
+ */
+
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "tags.h"
+
+#define R(x) (rand() % (x))
+
+#define MAXTCOUNT 100
+#define MAXPCOUNT 20
+#define MAXSTR2 80
+
+void make_up_value(void) {
+ char c=R(2);
+
+ if (c) putchar('"');
+
+ switch (R(31)) {
+
+ case 0: printf("javascript:"); make_up_value(); break;
+// case 1: printf("jar:"); make_up_value(); break;
+ case 2: printf("mk:"); make_up_value(); break;
+ case 3: printf("file:"); make_up_value(); break;
+ case 4: printf("http:"); make_up_value(); break;
+ case 5: printf("about:"); make_up_value(); break;
+ case 6: printf("_blank"); break;
+ case 7: printf("_self"); break;
+ case 8: printf("top"); break;
+ case 9: printf("left"); break;
+ case 10: putchar('&'); make_up_value(); putchar(';'); break;
+ case 11: make_up_value(); make_up_value(); break;
+
+ case 12 ... 20: {
+ int c = R(10) ? R(10) : (1 + R(MAXSTR2) * R(MAXSTR2));
+ char* x = malloc(c);
+ memset(x,R(256),c);
+ fwrite(x,c,1,stdout);
+ free(x);
+ break;
+ }
+
+ case 21: printf("%s","%n%n%n%n%n%n"); break;
+ case 22: putchar('#'); break;
+ case 23: putchar('*'); break;
+ default: if (R(2)) putchar('-'); printf("%d",rand()); break;
+
+ }
+
+ if (c) putchar('"');
+
+}
+
+
+void random_tag(void) {
+ int tn, tc;
+
+ do tn = R(MAXTAGS); while (!tags[tn][0]);
+ tc = R(MAXPCOUNT) + 1;
+
+ putchar('<');
+
+ switch (R(10)) {
+ case 0: putchar(R(256)); break;
+ case 1: putchar('/');
+ }
+
+ printf("%s", tags[tn][0]);
+
+ while (tc--) {
+ int pn;
+ switch (R(32)) {
+ case 0: putchar(R(256));
+ case 1: break;
+ default: putchar(' ');
+ }
+ do pn = R(MAXPARS-1) + 1; while (!tags[tn][pn]);
+ printf("%s", tags[tn][pn]);
+ switch (R(32)) {
+ case 0: putchar(R(256));
+ case 1: break;
+ default: putchar('=');
+ }
+
+ make_up_value();
+
+ }
+
+ putchar('>');
+
+}
+
+
+int main(int argc,char** argv) {
+ int tc,seed;
+ char* x = getenv("QUERY_STRING");
+
+ if (!x || sscanf(x,"%x",&seed) != 1) {
+ printf("Content-type: text/plain\n\nMissing or invalid parameter.\n");
+ exit(1);
+ }
+
+ printf("Content-Type: text/html;charset=utf-8\nRefresh: 0;URL=remangle.cgi?0x%08x\n\n", seed);
+ printf("<HTML><HEAD><META HTTP-EQUIV=\"Refresh\" content=\"0;URL=remangle.cgi?0x%08x\">\n", seed);
+ printf("<script language=\"javascript\">setTimeout('window.location=\"remangle.cgi?0x%08x\"', 1000);</script>\n", seed);
+
+ srand(seed);
+
+ tc = R(MAXTCOUNT) + 1;
+ while (tc--) random_tag();
+ fflush(0);
+ return 0;
+}
diff --git a/WebKitTools/mangleme/tags.h b/WebKitTools/mangleme/tags.h
new file mode 100644
index 0000000..5789441
--- /dev/null
+++ b/WebKitTools/mangleme/tags.h
@@ -0,0 +1,76 @@
+/*
+
+ HTML manglizer
+ --------------
+ Copyright (C) 2004 by Michal Zalewski <lcamtuf@coredump.cx>
+
+ Tag and parameter list: guesstimating / reference compilation.
+
+ */
+
+
+#define MAXTAGS 80
+#define MAXPARS 20
+
+static char* tags[MAXTAGS][MAXPARS] = {
+ { "A", "NAME", "HREF", "REF", "REV", "TITLE", "TARGET", "SHAPE", "onLoad", "STYLE", 0 },
+ { "APPLET", "CODEBASE", "CODE", "NAME", "ALIGN", "ALT", "HEIGHT", "WIDTH", "HSPACE", "VSPACE", "DOWNLOAD", "HEIGHT", "NAME", "TITLE", "onLoad", "STYLE", 0 },
+ { "AREA", "SHAPE", "ALT", "CO-ORDS", "HREF", "onLoad", "STYLE", 0 },
+ { "B", "onLoad", "STYLE", 0 },
+ { "BANNER", "onLoad", "STYLE", 0 },
+ { "BASE", "HREF", "TARGET", "onLoad", "STYLE", 0 },
+ { "BASEFONT", "SIZE", "onLoad", "STYLE", 0 },
+ { "BGSOUND", "SRC", "LOOP", "onLoad", "STYLE", 0 },
+ { "BQ", "CLEAR", "NOWRAP", "onLoad", "STYLE", 0 },
+ { "BODY", "BACKGROUND", "BGCOLOR", "TEXT", "LINK", "ALINK", "VLINK", "LEFTMARGIN", "TOPMARGIN", "BGPROPERTIES", "onLoad", "STYLE", 0 },
+ { "CAPTION", "ALIGN", "VALIGN", "onLoad", "STYLE", 0 },
+ { "CENTER", "onLoad", "STYLE", 0 },
+ { "COL", "ALIGN", "SPAN", "onLoad", "STYLE", 0 },
+ { "COLGROUP", "ALIGN", "VALIGN", "HALIGN", "WIDTH", "SPAN", "onLoad", "STYLE", 0 },
+ { "DIV", "ALIGN", "CLASS", "LANG", "onLoad", "STYLE", 0 },
+ { "EMBED", "SRC", "HEIGHT", "WIDTH", "UNITS", "NAME", "PALETTE", "onLoad", "STYLE", 0 },
+ { "FIG", "SRC", "ALIGN", "HEIGHT", "WIDTH", "UNITS", "IMAGEMAP", "onLoad", "STYLE", 0 },
+ { "FN", "ID", "onLoad", "STYLE", 0 },
+ { "FONT", "SIZE", "COLOR", "FACE", "onLoad", "STYLE", 0 },
+ { "FORM", "ACTION", "METHOD", "ENCTYPE", "TARGET", "SCRIPT", "onLoad", "STYLE", 0 },
+ { "FRAME", "SRC", "NAME", "MARGINWIDTH", "MARGINHEIGHT", "SCROLLING", "FRAMESPACING", "onLoad", "STYLE", 0 },
+ { "FRAMESET", "ROWS", "COLS", "onLoad", "STYLE", 0 },
+ { "H1", "SRC", "DINGBAT", "onLoad", "STYLE", 0 },
+ { "HEAD", "onLoad", "STYLE", 0 },
+ { "HR", "SRC", "SIZE", "WIDTH", "ALIGN", "COLOR", "onLoad", "STYLE", 0 },
+ { "HTML", "onLoad", "STYLE", 0 },
+ { "IFRAME", "ALIGN", "FRAMEBORDER", "HEIGHT", "MARGINHEIGHT", "MARGINWIDTH", "NAME", "SCROLLING", "SRC", "ADDRESS", "WIDTH", "onLoad", "STYLE", 0 },
+ { "IMG", "ALIGN", "ALT", "SRC", "BORDER", "DYNSRC", "HEIGHT", "HSPACE", "ISMAP", "LOOP", "LOWSRC", "START", "UNITS", "USEMAP", "WIDTH", "VSPACE", "onLoad", "STYLE", 0 },
+ { "INPUT", "TYPE", "NAME", "VALUE", "onLoad", "STYLE", 0 },
+ { "ISINDEX", "HREF", "PROMPT", "onLoad", "STYLE", 0 },
+ { "LI", "SRC", "DINGBAT", "SKIP", "TYPE", "VALUE", "onLoad", "STYLE", 0 },
+ { "LINK", "REL", "REV", "HREF", "TITLE", "onLoad", "STYLE", 0 },
+ { "MAP", "NAME", "onLoad", "STYLE", 0 },
+ { "MARQUEE", "ALIGN", "BEHAVIOR", "BGCOLOR", "DIRECTION", "HEIGHT", "HSPACE", "LOOP", "SCROLLAMOUNT", "SCROLLDELAY", "WIDTH", "VSPACE", "onLoad", "STYLE", 0 },
+ { "MENU", "onLoad", "STYLE", 0 },
+ { "META", "HTTP-EQUIV", "CONTENT", "NAME", "onLoad", "STYLE", 0 },
+ { "MULTICOL", "COLS", "GUTTER", "WIDTH", "onLoad", "STYLE", 0 },
+ { "NOFRAMES", "onLoad", "STYLE", 0 },
+ { "NOTE", "CLASS", "SRC", "onLoad", "STYLE", 0 },
+ { "OVERLAY", "SRC", "X", "Y", "HEIGHT", "WIDTH", "UNITS", "IMAGEMAP", "onLoad", "STYLE", 0 },
+ { "PARAM", "NAME", "VALUE", "onLoad", "STYLE", 0 },
+ { "RANGE", "FROM", "UNTIL", "onLoad", "STYLE", 0 },
+ { "SCRIPT", "LANGUAGE", "onLoad", "STYLE", 0 },
+ { "SELECT", "NAME", "SIZE", "MULTIPLE", "WIDTH", "HEIGHT", "UNITS", "onLoad", "STYLE", 0 },
+ { "OPTION", "VALUE", "SHAPE", "onLoad", "STYLE", 0 },
+ { "SPACER", "TYPE", "SIZE", "WIDTH", "HEIGHT", "ALIGN", "onLoad", "STYLE", 0 },
+ { "SPOT", "ID", "onLoad", "STYLE", 0 },
+ { "TAB", "INDENT", "TO", "ALIGN", "DP", "onLoad", "STYLE", 0 },
+ { "TABLE", "ALIGN", "WIDTH", "BORDER", "CELLPADDING", "CELLSPACING", "BGCOLOR", "VALIGN", "COLSPEC", "UNITS", "DP", "onLoad", "STYLE", 0 },
+ { "TBODY", "CLASS", "ID", "onLoad", "STYLE", 0 },
+ { "TD", "COLSPAN", "ROWSPAN", "ALIGN", "VALIGN", "BGCOLOR", "onLoad", "STYLE", 0 },
+ { "TEXTAREA", "NAME", "COLS", "ROWS", "onLoad", "STYLE", 0 },
+ { "TEXTFLOW", "CLASS", "ID", "onLoad", "STYLE", 0 },
+ { "TFOOT", "COLSPAN", "ROWSPAN", "ALIGN", "VALIGN", "BGCOLOR", "onLoad", "STYLE", 0 },
+ { "TH", "ALIGN", "CLASS", "ID", "onLoad", "STYLE", 0 },
+ { "TITLE", "onLoad", "STYLE", 0 },
+ { "TR", "ALIGN", "VALIGN", "BGCOLOR", "CLASS", "onLoad", "STYLE", 0 },
+ { "UL", "SRC", "DINGBAT", "WRAP", "TYPE", "PLAIN", "onLoad", "STYLE", 0 },
+ { 0 }
+};
+
diff --git a/WebKitTools/vcbin/cl.exe b/WebKitTools/vcbin/cl.exe
new file mode 100755
index 0000000..2ec78c9
--- /dev/null
+++ b/WebKitTools/vcbin/cl.exe
Binary files differ
diff --git a/WebKitTools/vcbin/midl.exe b/WebKitTools/vcbin/midl.exe
new file mode 100755
index 0000000..55ecd1d
--- /dev/null
+++ b/WebKitTools/vcbin/midl.exe
Binary files differ
diff --git a/WebKitTools/wx/browser/browser.bkl b/WebKitTools/wx/browser/browser.bkl
new file mode 100644
index 0000000..505d740
--- /dev/null
+++ b/WebKitTools/wx/browser/browser.bkl
@@ -0,0 +1,64 @@
+<?xml version="1.0" ?>
+<!--
+Copyright (C) 2007 Kevin Ollivier <kevino@theolliviers.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.
+
+wxWebKit sample application build file
+-->
+
+<makefile>
+ <set var="WX_UNICODE">1</set>
+ <set var="WX_SHARED">1</set>
+
+ <include file="../../../WebKit/wx/wxwk-settings.bkl"/>
+
+ <!-- the WX_PYTHON option was added to presets/wx.bkl in 2.8.5, so define
+ it in case the presets/wx.bkl doesn't define it for us. -->
+ <if cond="not isdefined('WX_PYTHON')">
+ <set var="WX_PYTHON">0</set>
+ </if>
+ <template id="wxwebkit">
+ <lib-path>$(WKOUTPUTDIR)</lib-path>
+ <sys-lib>wxwebkit</sys-lib>
+ </template>
+ <exe id="wxBrowser" template="wxwk,xml2,iconv,xslt,icu,jscore,webcore,wxwebkit,curl,pthreads">
+ <app-type>gui</app-type>
+ <runtime-libs>dynamic</runtime-libs>
+ <set var="BUILDDIR">$(WKOUTPUTDIR)/build/wxbrowser-$(FORMAT)</set>
+
+ <include>$(WK_ROOT)/WebCore/platform/wx</include>
+ <include>$(WK_ROOT)/WebCore/bridge/wx</include>
+ <include>$(WK_ROOT)/WebCore/page/wx</include>
+ <include>$(WK_ROOT)/WebKit/wx</include>
+ <include>$(WK_ROOT)/WebKit/wx/WebKitSupport</include>
+
+ <sources>
+ browser.cpp
+ </sources>
+
+ </exe>
+
+</makefile>
diff --git a/WebKitTools/wx/browser/browser.cpp b/WebKitTools/wx/browser/browser.cpp
new file mode 100644
index 0000000..5993432
--- /dev/null
+++ b/WebKitTools/wx/browser/browser.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2007 Kevin Ollivier <kevino@theolliviers.com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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.
+ */
+
+// webkit includes
+#include "WebView.h"
+#include "WebFrame.h"
+
+#include "wx/wxprec.h"
+#ifndef WX_PRECOMP
+ #include "wx/wx.h"
+#endif
+
+class MyApp : public wxApp
+{
+public:
+
+ virtual bool OnInit();
+};
+
+
+IMPLEMENT_APP(MyApp)
+
+bool MyApp::OnInit()
+{
+ wxInitAllImageHandlers();
+
+ // create the main application window
+ // see WebKit/wx/WebFrame.cpp for how to write a shell around wxWebView.
+ wxWebFrame *frame = new wxWebFrame(_T("wxWebKit Test App"));
+
+#ifndef NDEBUG
+ frame->ShowDebugMenu(true);
+#endif
+ frame->CentreOnScreen();
+ frame->Show(true);
+
+ return true;
+}
diff --git a/WebKitTools/wx/build-wxwebkit b/WebKitTools/wx/build-wxwebkit
new file mode 100755
index 0000000..59907c7
--- /dev/null
+++ b/WebKitTools/wx/build-wxwebkit
@@ -0,0 +1,377 @@
+#!/bin/bash
+
+# Copyright (C) 2007 Robin Dunn, Kevin Ollivier 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.
+#
+# Driver for the wxWebKit build process.
+
+set -o errexit
+#set -o xtrace
+
+#----------------------------------------------------------------------
+# Set up the environment
+
+scriptDir="$(cd $(dirname $0);pwd)"
+WK_ROOT=$scriptDir/../..
+WK_ROOTDIR=$WK_ROOT
+
+cd $scriptDir
+
+if [ -z $WEBKITOUTPUTDIR ]; then
+ WEBKITOUTPUTDIR=`cd $WK_ROOT/WebKitTools/Scripts; perl -e "use webkitdirs; print productDir()"`
+fi
+
+WKWINLIBS=WebKitLibraries/win
+WINDEPS=" $WKWINLIBS/lib/pthreadVC2.dll"
+WINDEPS="$WINDEPS $WKWINLIBS/bin/icuuc34.dll $WKWINLIBS/bin/icudt34.dll $WKWINLIBS/bin/icuin34.dll"
+WINDEPS="$WINDEPS $WKWINLIBS/bin/libcurl.dll $WKWINLIBS/bin/libeay32.dll $WKWINLIBS/bin/ssleay32.dll $WKWINLIBS/bin/zlib1.dll"
+WINDEPS="$WINDEPS $WKWINLIBS/lib/sqlite3.dll"
+WINDEPS="$WINDEPS $WKWINLIBS/bin/libxml2.dll $WKWINLIBS/bin/libxslt.dll"
+WINDEPS="$WINDEPS $WKWINLIBS/bin/iconv.dll"
+
+# TODO: check that we are running from the root of the source tree...
+
+# cygpath will bork if the dir doesn't exist...
+mkdir -p $WEBKITOUTPUTDIR
+
+if [ $OSTYPE == cygwin ]; then
+ EXE=.exe
+ WK_ROOTDIR=`cygpath -d $WK_ROOT`
+ WEBKITOUTPUTDIR=`cygpath -d $WEBKITOUTPUTDIR`
+ export WEBKITOUTPUTDIR
+ if [ -z $WXWIN ]; then
+ echo "Error, you must set WXWIN to your wxWidgets root directory."
+ exit 1
+ fi
+ if [ -z $WX_PREFIX ]; then
+ WX_PREFIX=$WXWIN
+ fi
+ if [ -z $BAKEFILE_PATHS ]; then
+ export BAKEFILE_PATHS=$WXWIN/build/bakefiles/wxpresets
+ fi
+ LINKER=`which link`
+ if [ "$LINKER" = "/usr/bin/link" ]; then
+ echo "WARNING: wxWebKit builds using MSVC on Windows, but it looks like"
+ echo "you have the GCC linker on your path. If /usr/bin/link does NOT point"
+ echo "to the MSVC linker, you need to move it or change your path to pick up"
+ echo "Microsoft's link.exe program first."
+ fi
+
+else
+ export WEBKITOUTPUTDIR
+ WX_PREFIX=`wx-config --prefix`
+ if [ ! -d "$WX_PREFIX" ]; then
+ echo "ERROR: Cannot find your wxWidgets installation."
+ echo "Make sure wx-config is on your PATH and points to a valid wxWidgets installation."
+ exit 1
+ fi
+
+ CONFIG=`wx-config --selected-config`
+ if [ "${CONFIG:0:4}" != "gtk2" -a "${CONFIG:0:3}" != "mac" ]; then
+ echo "ERROR: This configuration '$CONFIG' is not currently supported by wxWebKit. Please use the win, mac, or gtk2 port depending on your platform."
+ exit 1
+ fi
+
+ if [ ! -d "$WX_PREFIX/share/bakefile" ]; then
+ echo "ERROR: wxWidgets installation does not have wxpresets."
+ echo "wx-config is pointing to an installation that does not have Bakefile presets installed. Run `wx-config --version` to ensure your wxWidgets is of version 2.8+."
+ exit 1
+ fi
+
+ if [ -z $BAKEFILE_PATHS ]; then
+ export BAKEFILE_PATHS=$WX_PREFIX/share/bakefile
+ fi
+fi
+
+# after all that, make sure that BAKEFILE_PATHS was either set
+# previously, or by the code above
+if [ -z $BAKEFILE_PATHS ]; then
+ echo "Error, you must set BAKEFILE_PATHS to the directory containing wxpresets."
+ exit 1
+fi
+
+#----------------------------------------------------------------------
+# process command line args
+
+do_bake=0
+do_prep=0
+do_extras=0
+do_build=0
+do_clean=0
+do_install=0
+use_wxgc=0
+wxdebug=0
+wxpython=0
+make_args=''
+other_args=''
+
+for flag in $*; do
+ case $flag in
+ bake) do_bake=1 ;;
+ prep) do_prep=1 ;;
+ build) do_build=1 ;;
+ all) do_extras=1; do_bake=1; do_prep=1; do_build=1 ;;
+ clean) other_args=clean; do_clean=1 ;;
+ wxgc) use_wxgc=1 ;;
+ wxdebug) wxdebug=1 ;;
+ wxpython) wxpython=1 ;;
+ wxpython-install) wxpython_install=1 ;;
+ *) export $flag ;; #other_args='$other_args "$flag"' ;;
+ esac
+done
+
+
+#----------------------------------------------------------------------
+
+# if no arguments were passed, do a full build.
+if [ $do_bake == 0 -a $do_prep == 0 -a $do_build == 0 -a $do_clean == 0 ]; then
+ do_bake=1; do_prep=1; do_build=1
+fi
+
+function do_make {
+ dir=$1
+ cxxflags=$2
+ olddir=$PWD
+ shift
+ shift
+ if [ $OSTYPE == cygwin ]; then
+ cd $dir
+ nmake -f makefile.vc CXXFLAGS="$cxxflags" $@
+ cd $olddir
+ else
+ make -C $dir -f GNUmakefile $MAKE_ARGS CXXFLAGS="$cxxflags" $@
+ fi
+ if [ $? != 0 ]; then
+ exit $?
+ fi
+}
+
+# output the first parameter that is a dir and exists
+function find_existing_dir {
+ for arg in $*; do
+ tester=$arg
+ if [ $OSTYPE == cygwin ]; then
+ tester=`cygpath -u $arg`
+ fi
+ if [ -d $tester ]; then
+ echo $arg
+ return
+ fi
+ done
+}
+
+
+olddir=$PWD
+
+if [ $do_clean == 1 ]; then
+ rm -rf $WK_ROOT/JavaScriptCore/DerivedSources
+ rm -rf $WK_ROOT/WebCore/DerivedSources
+ rm -rf $WK_ROOT/WebCore/include/JavaScriptCore
+else
+
+ mkdir -p $WEBKITOUTPUTDIR/build
+
+ if [ $do_bake == 1 ]; then
+ # bakefile stuff
+ cd $WK_ROOT/WebKit/wx
+ bakefile_gen
+
+ # we need to do this because Bakefile doesn't know which
+ # platform it's running on with GNU format, and so it defaults
+ # to the standard Unix file endings and linker args.
+ if [ "${OSTYPE:0:6}" = "darwin" ]; then
+ sed "s/libwebcore-wx.so/libwebcore-wx.dylib/" < $WK_ROOT/WebCore/GNUmakefile > temp
+ mv temp $WK_ROOT/WebCore/GNUmakefile
+
+ sed "s/\-shared/\-dynamiclib/" < $WK_ROOT/WebCore/GNUmakefile > temp
+ mv temp $WK_ROOT/WebCore/GNUmakefile
+
+ sed "s/libwxwebkit.so/libwxwebkit.dylib/" < $WK_ROOT/WebKit/wx/GNUmakefile > temp
+ mv temp $WK_ROOT/WebKit/wx/GNUmakefile
+
+ sed "s/\-shared/\-dynamiclib/" < $WK_ROOT/WebKit/wx/GNUmakefile > temp
+ mv temp $WK_ROOT/WebKit/wx/GNUmakefile
+ fi
+ fi
+
+ if [ $do_prep == 1 ]; then
+ # Other preparation steps
+
+ # since the buildbot will wipe the build tree clean sometimes, we need to reinstall
+ # the dependencies if they aren't installed.
+ if [ "${OSTYPE:0:6}" == "darwin" ]; then
+ $WK_ROOT/WebKitTools/wx/install-unix-extras
+ fi
+
+ cd $WK_ROOT/JavaScriptCore
+ ./make-generated-sources.sh
+ if [ $? != 0 ]; then
+ exit $?
+ fi
+
+ cd $WK_ROOT/WebCore
+ ./make-generated-sources.sh platform/wx/wx-encodings.txt
+ if [ $? != 0 ]; then
+ exit $?
+ fi
+ fi
+fi
+
+
+if [ $do_build == 1 -o $do_clean == 1 ]; then
+ # Build steps
+ WXGC_DEFINE=""
+ if [ $use_wxgc == 1 ]; then
+ WXGC_DEFINE="-DWTF_USE_WXGC=1"
+ fi
+ WX_EXT=
+ if [ "${OSTYPE:0:6}" == "cygwin" -a $wxdebug == 1 ]; then
+ WX_EXT=d
+ fi
+ if [ "${OSTYPE:0:6}" == "cygwin" -a $wxpython == 1 ]; then
+ other_args=WX_PYTHON=1
+ WX_EXT=h
+ wxdebug=1
+ fi
+
+ if [ "${OSTYPE:0:6}" == "cygwin" ]; then
+ PLATFORM_OS="win"
+ elif [ "${OSTYPE:0:6}" == "darwin" ]; then
+ PLATFORM_OS="mac"
+ else
+ PLATFORM_OS="linux"
+ fi
+
+ WINDEPS="$WINDEPS $WXWIN/lib/vc_dll/wxmsw28u${WX_EXT}_core_vc.dll $WXWIN/lib/vc_dll/wxbase28u${WX_EXT}_vc.dll"
+
+ # NOTE: If we try to do make clean after the Bakefiles were cleaned out, or before they were
+ # first generated, we will get errors about missing files.
+ # FIXME: Make the check more robust.
+ if [ -f $WK_ROOT/JavaScriptCore/GNUmakefile ]; then
+ do_make $WK_ROOT/JavaScriptCore "-DBUILDING_WX__=1 $WXGC_DEFINE" WX_DEBUG=$wxdebug WEBKIT_ROOT=$WK_ROOTDIR PLATFORM_OS=$PLATFORM_OS $other_args
+ do_make $WK_ROOT/WebCore "-DBUILDING_WX__=1 $WXGC_DEFINE" WX_DEBUG=$wxdebug WEBKIT_ROOT=$WK_ROOTDIR PLATFORM_OS=$PLATFORM_OS $other_args
+ do_make $WK_ROOT/WebKit/wx "-DBUILDING_WX__=1 -DWXMAKINGDLL_WEBKIT=1 $WXGC_DEFINE" WX_DEBUG=$wxdebug WEBKIT_ROOT=$WK_ROOTDIR PLATFORM_OS=$PLATFORM_OS $other_args
+ do_make $WK_ROOT/WebKitTools/wx/browser "-DBUILDING_WX__=1 -DWXUSINGDLL_WEBKIT=1 $WXGC_DEFINE" WX_DEBUG=$wxdebug WEBKIT_ROOT=$WK_ROOTDIR PLATFORM_OS=$PLATFORM_OS $other_args
+ fi
+
+ if [ $do_build == 1 ]; then
+ if [ "${OSTYPE:0:6}" = "darwin" ]; then
+ cd $WEBKITOUTPUTDIR
+ mkdir -p wxBrowser.app/Contents/MacOS
+ mkdir -p wxBrowser.app/Contents/Frameworks
+ cp wxBrowser wxBrowser.app/Contents/MacOS
+ install_name_tool -change libwxwebkit.dylib @executable_path/../Frameworks/libwxwebkit.dylib wxBrowser.app/Contents/MacOS/wxBrowser
+ if [ ! -f "$WEBKITOUTPUTDIR/libwxwebkit.dylib" ]; then
+ ln -s $WEBKITOUTPUTDIR/libwxwebkit.dylib wxBrowser.app/Contents/Frameworks
+ fi
+ fi
+
+ if [ $wxpython == 1 ]; then
+ SWIG=`which swig`
+
+ if [ ! -f "$SWIG" ]; then
+ echo "ERROR: Cannot find SWIG. Make sure that SWIG 1.3.29 is located on your path.";
+ exit 1;
+ fi
+
+ cd $WK_ROOT/WebKit/wx/bindings/python
+
+ SWIG_FLAGS=`python -c "import wx.build.config; import string; print string.join(wx.build.config.swig_args, ' ')"`
+ WEBKIT_INCLUDE="-I$WK_ROOT/WebKit/wx"
+ if [ "${OSTYPE:0:6}" == "cygwin" ]; then
+ WEBKIT_INCLUDE="-I`cygpath -d $WK_ROOT/WebKit/wx`"
+ fi
+
+ # Determine which include path to use for wxPython's *.i files
+ # Options are:
+ # wxPython installed on a posix system
+ # the wxPython win32 devel tarball
+ # a wx source tree from a tarball where wxPython is in the wx dir
+ # a wx source tree from SVN where wxPython is a sibling of the wx dir
+ WXPY_INCLUDE=`find_existing_dir \
+ $WX_PREFIX/include/wx-2.8/wx/wxPython/i_files \
+ $WX_PREFIX/include/wx/wxPython/i_files \
+ $WX_PREFIX/wxPython/src \
+ $WX_PREFIX/../wxPython/src`
+ if [ -z $WXPY_INCLUDE ]; then
+ echo "ERROR: Unable to find wxPython's *.i files"
+ exit 1
+ fi
+
+ # Run SWIG
+ $SWIG $SWIG_FLAGS -I$WXPY_INCLUDE $WEBKIT_INCLUDE -o webview.cpp webview.i
+
+ PY_INCLUDE=`python -c "import sys,distutils.sysconfig; sys.stdout.write(distutils.sysconfig.get_python_inc())"`
+ PY_VERSION=`python -c "import sys; sys.stdout.write(str(sys.version_info[0]) + str(sys.version_info[1]))"`
+ PY_LIBDIR=`python -c "import distutils.sysconfig; import sys; sys.stdout.write(distutils.sysconfig.PREFIX)"`
+
+ if [ "${OSTYPE:0:6}" == "cygwin" ]; then
+ PY_LIBDIR="$PY_LIBDIR\\Libs"
+ else
+ PY_LIBDIR="$PY_LIBDIR/lib"
+ fi
+
+ do_make $WK_ROOT/WebKit/wx/bindings/python "-DBUILDING_WX__=1 -DWXUSINGDLL=1 -DWXUSINGDLL_WEBKIT=1 -I$PY_INCLUDE -I$WX_PREFIX/wxPython/include -I$WX_PREFIX/../wxPython/include $WXGC_DEFINE" \
+ WX_DEBUG=$wxdebug WEBKIT_ROOT=$WK_ROOTDIR PLATFORM_OS=$PLATFORM_OS PYTHON_VERSION=$PY_VERSION PYTHON_LIBDIR=$PY_LIBDIR $other_args
+ if [ "${OSTYPE:0:6}" == "cygwin" ]; then
+ if [ -f $WEBKITOUTPUTDIR/_webview.pyd -a -f $WEBKITOUTPUTDIR/_webview.dll ]; then
+ rm $WEBKITOUTPUTDIR/_webview.pyd
+ mv $WEBKITOUTPUTDIR/_webview.dll $WEBKITOUTPUTDIR/_webview.pyd
+ fi
+ fi
+ fi
+
+
+ if [ "$OSTYPE" == "cygwin" ]; then
+ echo "Copying necessary DLLs to run test and sample applications..."
+ cd $WK_ROOT
+ cp $WINDEPS `cygpath -u $WEBKITOUTPUTDIR`
+ chmod +x `cygpath -u $WEBKITOUTPUTDIR/`*.dll
+ fi
+
+ BROWSERAPP="wxBrowser"
+
+ if [ "${OSTYPE:0:6}" == "darwin" ]; then
+ BROWSERAPP="wxBrowser.app/Contents/MacOS/wxBrowser"
+ fi
+
+ echo ""
+ echo ""
+ echo "--- BUILD COMPLETE ---"
+ echo ""
+ echo "Next steps:"
+ echo ""
+ echo "-- Run '$WK_ROOT/WebKitTools/Scripts/run-javascriptcore-tests --wx' to ensure JSCore tests pass."
+ echo ""
+ echo "-- Run $WEBKITOUTPUTDIR/$BROWSERAPP to test your wxWebKit build."
+ echo ""
+ echo ""
+ fi
+fi
+
+if [ $do_clean == 1 ]; then
+ cd $WK_ROOT/WebKit/wx
+ bakefile_gen --clean
+fi
+
+cd $olddir
diff --git a/WebKitTools/wx/install-unix-extras b/WebKitTools/wx/install-unix-extras
new file mode 100755
index 0000000..ec09f85
--- /dev/null
+++ b/WebKitTools/wx/install-unix-extras
@@ -0,0 +1,172 @@
+#!/bin/sh
+
+# Copyright (C) 2005, 2006 Apple Computer, 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.
+
+# A script to download the extra libraries needed to build WebKit on UNIX-based OSes.
+# libxml/libxslt need to be added, but so far I've had them on all the (UNIX) machines
+# I've tested on, so I don't have a machine to test the code on.
+
+DL_CMD="curl -L"
+
+scriptDir="$(cd $(dirname $0);pwd)"
+WK_ROOT=$scriptDir/../..
+WK_ROOTDIR=$WK_ROOT
+
+DL_DIR=/tmp/webkit-deps
+# NOTE: If you change this, make sure the dir is on the path.
+DEPS_PREFIX=$WK_ROOT/WebKitLibraries/unix
+DLLEXT=so
+
+if [ "${OSTYPE:0:6}" == "darwin" ]; then
+ DLLEXT=dylib
+fi
+
+mkdir -p $DL_DIR
+mkdir -p $DEPS_PREFIX
+
+ICU_VERSION="3.4.1"
+ICU_TARBALL="icu-$ICU_VERSION.tgz"
+ICU_URL="ftp://ftp.software.ibm.com/software/globalization/icu/$ICU_VERSION/$ICU_TARBALL"
+
+# dependent app, not lib, what should we do for these?
+
+GPERF_VERSION="3.0.1"
+GPERF_TARBALL="gperf-$GPERF_VERSION.tar.gz"
+GPERF_URL="ftp://mirrors.kernel.org/gnu/gperf/$GPERF_TARBALL"
+
+PKG_CONFIG_VERSION="0.20"
+PKG_CONFIG_TARBALL="pkg-config-$PKG_CONFIG_VERSION.tar.gz"
+PKG_CONFIG_URL="http://pkgconfig.freedesktop.org/releases/$PKG_CONFIG_TARBALL"
+
+ICONV_VERSION="1.9.2"
+ICONV_TARBALL="libiconv-$ICONV_VERSION.tar.gz"
+ICONV_URL="http://ftp.gnu.org/pub/gnu/libiconv/$ICONV_TARBALL"
+
+LIBJPEG_VERSION="6b"
+LIBJPEG_TARBALL="jpegsrc.v$LIBJPEG_VERSION.tar.gz"
+LIBJPEG_URL="http://www.ijg.org/files/$LIBJPEG_TARBALL"
+
+LIBPNG_VERSION="1.2.24"
+LIBPNG_TARBALL="libpng-$LIBPNG_VERSION.tar.gz"
+LIBPNG_URL="ftp://ftp.simplesystems.org/pub/libpng/png/src/$LIBPNG_TARBALL"
+
+cd $DL_DIR
+# build ICU
+if [ `which icu-config >/dev/null 2>&1` ]; then
+ $DL_CMD -o $DL_DIR/$ICU_TARBALL $ICU_URL
+
+ tar xzvf $DL_DIR/$ICU_TARBALL
+ cd $DL_DIR/icu/source
+
+ chmod +x configure install-sh
+
+ if [ "${OSTYPE:0:6}" == "darwin" ]; then
+ ./configure --prefix=$DEPS_PREFIX --disable-dependency-tracking
+ make CFLAGS="-O -g -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386 -arch ppc" \
+ LDFLAGS="-arch i386 -arch ppc"
+ make install
+ else
+ ./configure --prefix=$DEPS_PREFIX
+
+ make
+ #make check
+ make install
+ fi
+ cd $DL_DIR
+ rm -rf icu
+fi
+
+# TODO: What would be a good way to test for this?
+if [ ! -f $DEPS_PREFIX/lib/libiconv.$DLLEXT ]; then
+ $DL_CMD -o $DL_DIR/$ICONV_TARBALL $ICONV_URL
+
+ tar xzvf $DL_DIR/$ICONV_TARBALL
+ cd $DL_DIR/libiconv-$ICONV_VERSION
+
+ if [ "${OSTYPE:0:6}" == "darwin" ]; then
+ ./configure --prefix=$DEPS_PREFIX --disable-dependency-tracking
+ make CFLAGS="-O -g -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386 -arch ppc" \
+ LDFLAGS="-arch i386 -arch ppc"
+ make install
+ else
+ ./configure --prefix=$DEPS_PREFIX
+
+ make
+ make install
+ fi
+ cd $DL_DIR
+ rm -rf $DL_DIR/libiconv-$ICONV_VERSION
+fi
+
+if [ ! -f $DEPS_PREFIX/lib/libjpeg.a ]; then
+ $DL_CMD -o $DL_DIR/$LIBJPEG_TARBALL $LIBJPEG_URL
+
+ tar xzvf $DL_DIR/$LIBJPEG_TARBALL
+ cd $DL_DIR/jpeg-$LIBJPEG_VERSION
+
+ # jpeg install command expects this to exist.
+ mkdir -p $DEPS_PREFIX/man/man1
+
+ if [ "${OSTYPE:0:6}" == "darwin" ]; then
+ ./configure --prefix=$DEPS_PREFIX --disable-dependency-tracking
+ make CFLAGS="-O -g -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386 -arch ppc" \
+ LDFLAGS="-arch i386 -arch ppc"
+ make install
+ else
+ ./configure --prefix=$DEPS_PREFIX
+
+ make
+ fi
+
+ cp libjpeg.a $DEPS_PREFIX/lib
+ cp *.h $DEPS_PREFIX/include
+
+ cd $DL_DIR
+ rm -rf $DL_DIR/jpeg-$LIBJPEG_VERSION
+fi
+
+if [ ! -f $DEPS_PREFIX/lib/libpng.a ]; then
+ $DL_CMD -o $DL_DIR/$LIBPNG_TARBALL $LIBPNG_URL
+
+ tar xzvf $DL_DIR/$LIBPNG_TARBALL
+ cd $DL_DIR/libpng-$LIBPNG_VERSION
+
+ if [ "${OSTYPE:0:6}" == "darwin" ]; then
+ ./configure --prefix=$DEPS_PREFIX --disable-dependency-tracking
+ make CFLAGS="-O -g -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386 -arch ppc" \
+ LDFLAGS="-arch i386 -arch ppc"
+ make install
+ else
+ ./configure --prefix=$DEPS_PREFIX
+
+ make
+ make install
+ fi
+
+ cd $DL_DIR
+ rm -rf $DL_DIR/libpng-$LIBPNG_VERSION
+fi