diff options
Diffstat (limited to 'WebKitTools')
129 files changed, 12043 insertions, 1561 deletions
diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/config.json b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/config.json index b650b4c..2b8faf6 100644 --- a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/config.json +++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/config.json @@ -7,8 +7,15 @@ { "name": "apple-xserve-2", "platform": "mac-leopard" }, { "name": "apple-xserve-3", "platform": "mac-leopard" }, + { "name": "apple-xserve-4", "platform": "mac-snowleopard" }, + { "name": "apple-xserve-5", "platform": "mac-snowleopard" }, + { "name": "apple-xserve-6", "platform": "mac-snowleopard" }, + { "name": "apple-pixel-1", "platform": "mac-leopard" }, + { "name": "apple-macpro-1", "platform": "mac-snowleopard" }, + { "name": "apple-macpro-2", "platform": "mac-snowleopard" }, + { "name": "apple-windows-1", "platform": "win"}, { "name": "apple-windows-2", "platform": "win"}, { "name": "apple-windows-3", "platform": "win"}, @@ -16,7 +23,9 @@ { "name": "gtk-linux-slave-1", "platform": "gtk"}, - { "name": "szeged-linux-1", "platform": "qt"} + { "name": "szeged-linux-1", "platform": "qt"}, + + { "name": "google-slave-1", "platform": "chromium-win" } ], "builders": [ { "name": "Tiger Intel Release", "type": "BuildAndTest", "builddir": "tiger-intel-release", @@ -43,6 +52,19 @@ "platform": "mac-leopard", "configuration": "debug", "architectures": ["i386"], "slavenames": ["apple-xserve-3", "test-slave"] }, + { "name": "SnowLeopard Intel Release (Build)", "type": "Build", "builddir": "snowleopard-intel-release", + "platform": "mac-snowleopard", "configuration": "release", "architectures": ["x86_64"], + "triggers": ["snowleopard-intel-release-tests"], + "slavenames": ["apple-xserve-4", "test-slave"] + }, + { "name": "SnowLeopard Intel Release (Tests)", "type": "Test", "builddir": "snowleopard-intel-release-tests", + "platform": "mac-snowleopard", "configuration": "release", "architectures": ["x86_64"], + "slavenames": ["apple-xserve-5", "apple-xserve-6", "test-slave"] + }, + { "name": "SnowLeopard Intel Leaks", "type": "BuildAndTestLeaks", "builddir": "snowleopard-intel-leaks", + "platform": "mac-snowleopard", "configuration": "debug", "architectures": ["x86_64"], + "slavenames": ["apple-macpro-1", "test-slave"] + }, { "name": "Windows Release (Build)", "type": "Build", "builddir": "win-release", "platform": "win", "configuration": "release", "architectures": ["i386"], @@ -74,13 +96,20 @@ "name": "Qt Linux Release", "type": "BuildAndTest", "builddir": "qt-linux-release", "platform": "qt", "configuration": "release", "architectures": ["i386"], "slavenames": ["szeged-linux-1"] + }, + { + "name": "Chromium Win Release", "type": "ChromiumBuild", "builddir": "chromium-win-release", + "platform": "chromium-win", "configuration": "release", "architectures": ["i386"], + "slavenames": ["google-slave-1"] } ], "schedulers": [ { "type": "AnyBranchScheduler", "name": "trunk", "branches": ["trunk"], "treeStableTimer": 45.0, "builderNames": ["Tiger Intel Release", "Leopard Intel Release (Build)", "Leopard Intel Debug (Build)", + "SnowLeopard Intel Release (Build)", "SnowLeopard Intel Leaks", "Windows Release (Build)", "Windows Debug (Build)", - "GTK Linux Release", "Qt Linux Release"] + "GTK Linux Release", "Qt Linux Release", + "Chromium Win Release"] }, { "type": "Triggerable", "name": "leopard-intel-release-tests", "builderNames": ["Leopard Intel Release (Tests)"] @@ -88,6 +117,9 @@ { "type": "Triggerable", "name": "leopard-intel-debug-tests", "builderNames": ["Leopard Intel Debug (Tests)"] }, + { "type": "Triggerable", "name": "snowleopard-intel-release-tests", + "builderNames": ["SnowLeopard Intel Release (Tests)"] + }, { "type": "Triggerable", "name": "win-release-tests", "builderNames": ["Windows Release (Tests)"] }, diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg index 4d92436..6219b0d 100644 --- a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg +++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg @@ -13,6 +13,7 @@ from buildbot.status.builder import SUCCESS, FAILURE, WARNINGS, SKIPPED from twisted.internet import defer +import re import simplejson WithProperties = properties.WithProperties @@ -47,6 +48,55 @@ class CheckOutSource(source.SVN): source.SVN.__init__(self, baseURL=self.baseURL, defaultBranch="trunk", mode=self.mode, *args, **kwargs) +# FIXME: Remove this step once Chromium WebKit port build system is decoupled from +# Chromium (https://bugs.webkit.org/show_bug.cgi?id=28396) +class UpdateChromiumSource(shell.ShellCommand): + command = ["gclient", "sync"] + name = "update-chromium" + description = ["updating chromium source"] + descriptionDone = ["updated"] + haltOnFailure = True + + def createSummary(self, log): + scraper = re.compile(r"^________ running '[^\n]+third_party[/\\]WebKit[^\n]+$\n(?:^[UA]\W+[^\n]+$\n)*^(?:Updated to|At) revision (\d+)", re.DOTALL | re.MULTILINE) + revisions = scraper.findall(log.getText()) + gotRevision = "??" # This matches SVN unknown revision response. + if len(revisions): + gotRevision = "r%s" % revisions[-1] + self.descriptionDone = ["updated", gotRevision] + + def start(self): + os = self.getProperty("fullPlatform").split('-')[1] + if os == "win": + self.setCommand(["gclient.bat", "sync"]) + revision = self.getProperty("revision") + if revision: + command = self.command[:] + command.append("--revision=src/third_party/WebKit@%d" % revision) + self.setCommand(command) + return shell.ShellCommand.start(self) + + +# FIXME: Remove this step once Chromium WebKit port build system is decoupled from +# Chromium (https://bugs.webkit.org/show_bug.cgi?id=28396) +class CompileChromiumWebKit(shell.ShellCommand): + command = ["python", "../../../scripts/slave/compile.py"] + name = "build-chromium" + description = ["compiling"] + descriptionDone = ["compiled"] + haltOnFailure = True + + def start(self): + os = self.getProperty("fullPlatform").split('-')[1] + command = self.command[:] + if os == "win": + command.extend(["--solution=webkit.sln", "--build-dir=src\\webkit", "--", "/project", "webcore"]) + elif os == "mac": + command.extend(["--solution=__solution__", "--build-dir=src/build", "--", "-project", "../webkit/webkit.xcodeproj", "-target", "webcore"]) + self.setCommand(command) + return shell.ShellCommand.start(self) + + class InstallWin32Dependencies(shell.Compile): description = ["installing dependencies"] descriptionDone = ["installed dependencies"] @@ -188,13 +238,19 @@ class RunWebKitTests(shell.Test): incorrectLayoutLines.append(line) elif line.find('test case') >= 0 and (line.find(' crashed') >= 0 or line.find(' timed out') >= 0): incorrectLayoutLines.append(line) + elif line.startswith("WARNING:") and line.find(' leak') >= 0: + incorrectLayoutLines.append(line.replace('WARNING: ', '')) + + # FIXME: Detect and summarize leaks of RefCounted objects self.incorrectLayoutLines = incorrectLayoutLines def evaluateCommand(self, cmd): if self.incorrectLayoutLines: - if len(self.incorrectLayoutLines) == 1 and (self.incorrectLayoutLines[0].find('were new') >= 0 or self.incorrectLayoutLines[0].find('was new') >= 0): - return WARNINGS + if len(self.incorrectLayoutLines) == 1: + line = self.incorrectLayoutLines[0] + if line.find('were new') >= 0 or line.find('was new') >= 0 or line.find(' leak') >= 0: + return WARNINGS return FAILURE @@ -213,6 +269,12 @@ class RunWebKitTests(shell.Test): return [self.name] +class RunWebKitLeakTests(RunWebKitTests): + def start(self): + self.setCommand(self.command + ["--leaks"]) + return RunWebKitTests.start(self) + + class ArchiveTestResults(shell.ShellCommand): command = ["python", "./WebKitTools/BuildSlaveSupport/test-result-archive", WithProperties("--platform=%(platform)s"), WithProperties("--%(configuration)s"), "archive"] @@ -257,6 +319,15 @@ class Factory(factory.BuildFactory): if platform == "win": self.addStep(InstallWin32Dependencies) +# FIXME: Remove this factory once Chromium WebKit port build system is decoupled from +# Chromium (https://bugs.webkit.org/show_bug.cgi?id=28396) +class ChromiumBuildFactory(factory.BuildFactory): + def __init__(self, platform, configuration, architectures): + factory.BuildFactory.__init__(self) + self.addStep(ConfigureBuild, platform=platform, configuration=configuration, architecture=" ".join(architectures), buildOnly=True) + self.addStep(UpdateChromiumSource) + self.addStep(CompileChromiumWebKit) + class BuildFactory(Factory): def __init__(self, platform, configuration, architectures, triggers): Factory.__init__(self, platform, configuration, architectures, True) @@ -277,15 +348,19 @@ class TestFactory(Factory): self.addStep(ExtractTestResults) class BuildAndTestFactory(Factory): + TestClass = RunWebKitTests def __init__(self, platform, configuration, architectures): Factory.__init__(self, platform, configuration, architectures, False) self.addStep(CompileWebKit) self.addStep(RunJavaScriptCoreTests) - self.addStep(RunWebKitTests) + self.addStep(self.TestClass) self.addStep(ArchiveTestResults) self.addStep(UploadTestResults) self.addStep(ExtractTestResults) +class BuildAndTestLeaksFactory(BuildAndTestFactory): + TestClass = RunWebKitLeakTests + def loadBuilderConfig(c): passwords = simplejson.load(open('passwords.json')) diff --git a/WebKitTools/ChangeLog b/WebKitTools/ChangeLog index 93d94cd..6a8a912 100644 --- a/WebKitTools/ChangeLog +++ b/WebKitTools/ChangeLog @@ -1,3 +1,3639 @@ +2009-10-08 Adam Roben <aroben@apple.com> + + Use QueryInterface to get IWebInspectorPrivate + + Fixes <http://webkit.org/b/30215> Make IWebInspectorPrivate be + accessed in a more standard way + + Reviewed by John Sullivan and Tim Hatcher. + + * DumpRenderTree/win/LayoutTestControllerWin.cpp: + (LayoutTestController::evaluateInWebInspector): Get the IWebInspector + by calling IWebViewPrivate::inspector, then use QueryInterface to get + to the IWebInspectorPrivate interface. + +2009-10-07 Adam Roben <aroben@apple.com> + + Implement DRT support for origin whitelisting + + Fixes <http://webkit.org/b/30185>. + + Reviewed by Eric Seidel. + + * DumpRenderTree/win/DumpRenderTree.cpp: + (resetWebViewToConsistentStateBeforeTesting): Reset any origin + whitelist, to match Mac DRT. + * DumpRenderTree/win/LayoutTestControllerWin.cpp: + (LayoutTestController::whiteListAccessFromOrigin): Call through to + IWebViewPrivate::whiteListAccessFromOrigin. + +2009-10-07 Brady Eidson <beidson@apple.com> + + Reviewed by Darin Adler. + + Send title changes to the global history delegate. + <rdar://problem/7285293> and https://webkit.org/b/29904 + + * DumpRenderTree/mac/HistoryDelegate.mm: + (-[HistoryDelegate webView:updateHistoryTitle:forURL:]): + +2009-10-07 Adam Barth <abarth@webkit.org> + + Unreviewed. Remove some folks from committers.py who were listed on + the WebKit Team wiki page but who weren't actually listed as commit+. + At some point, we should coorelate this list with the committers + mailing list. + + * Scripts/modules/committers.py: + +2009-10-07 Adam Barth <abarth@webkit.org> + + Unreviewed. Import a bunch of committers from the WebKit Team page on + the wiki into committers.py. + + * Scripts/modules/committers.py: + +2009-10-07 Adam Barth <abarth@webkit.org> + + Unreviewed. Added Aaron Boodman to committers.py. + + * Scripts/modules/committers.py: + +2009-10-07 Evan Martin <evan@chromium.org> + + Reviewed by Darin Adler. + + Add API to LayoutTestController for re/setting the system locale. + https://bugs.webkit.org/show_bug.cgi?id=18994 + + * DumpRenderTree/LayoutTestController.cpp: + (setLocaleCallback): + (LayoutTestController::staticFunctions): + (LayoutTestController::setLocale): + * DumpRenderTree/LayoutTestController.h: + +2009-10-06 Shinichiro Hamaji <hamaji@chromium.org> + + Reviewed by Jan Alonzo. + + [Layout tests] [Gtk] Gtk DumpRenderTree should use WebKit test fonts + https://bugs.webkit.org/show_bug.cgi?id=29689 + + Build fix by adding -lfontconfig for DumpRenderTree. + + * GNUmakefile.am: + +2009-10-07 Csaba Osztrogonac <oszi@inf.u-szeged.hu> + + Reviewed by Simon Hausmann. + + Re-enable use-remote-links-to-tests for Qt. Disabled in r46416. + + * Scripts/run-webkit-tests: + +2009-10-07 Xan Lopez <xlopez@igalia.com> + + Reviewed by Gustavo Noronha. + + "delete" in EventSender is the backspace key, not the delete one. + + * DumpRenderTree/gtk/EventSender.cpp: + (keyDownCallback): + +2009-10-07 Xan Lopez <xlopez@igalia.com> + + Reviewed by Gustavo Noronha. + + getChildrenWithRange expects as last parameter the end index, not + the length of the range. Correct this and clarify the variable + names to reflect how the code works. + + * DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp: + (AccessibilityUIElement::getChildrenWithRange): + (AccessibilityUIElement::getChildAtIndex): + +2009-10-06 Mark Rowe <mrowe@apple.com> + + Reviewed by Simon Fraser. + + <http://webkit.org/b/30138> update-webkit-localizable-strings assumes that WebKitTools/Scripts is in the PATH + + * Scripts/update-webkit-localizable-strings: Use an explicit path to extract-localizable-strings based on the + the fact we have already changed the working directory to the top of the open source tree. + +2009-10-06 Julie Parent <jparent@chromium.org> + + Unreviewed. Fixing the entry for myself in committers.py to use my bugzilla email, + rather than my committer email. + + * Scripts/modules/committers.py: + +2009-10-06 Jakub Wieczorek <faw217@gmail.com> + + Reviewed by Eric Seidel. + + [Qt] LayoutTestController: Reset m_dumpStatusCallbacks to false in reset(). + + r49189 added support for the 'dumpStatusCallbacks' setting but didn't reset + it after each layout test as it should do, making the DRT dump additional output + for all of the subsequent layout tests. + + * DumpRenderTree/qt/jsobjects.cpp: + (LayoutTestController::reset): + +2009-10-06 Jakub Wieczorek <faw217@gmail.com> + + Reviewed by Simon Hausmann. + + [Qt] Implement layoutTestController.dumpStatusCallbacks() and unskip the + fast/dom/assign-to-window-status.html test, which is passing as a result. + + https://bugs.webkit.org/show_bug.cgi?id=30127 + + * DumpRenderTree/qt/DumpRenderTree.cpp: + (WebCore::DumpRenderTree::DumpRenderTree): + (WebCore::DumpRenderTree::statusBarMessage): + * DumpRenderTree/qt/DumpRenderTree.h: + * DumpRenderTree/qt/jsobjects.h: + (LayoutTestController::shouldDumpStatusCallbacks): + (LayoutTestController::dumpStatusCallbacks): + +2009-10-06 Jakub Wieczorek <faw217@gmail.com> + + Reviewed by Simon Hausmann. + + [Qt] The implementation of EventSender::mouseUp() and EventSender::mouseDown() + ignores the argument indicating which mouse button to trigger. + https://bugs.webkit.org/show_bug.cgi?id=30048 + + This affects the fast/events/mouse-click-events.html layout test. + + * DumpRenderTree/qt/jsobjects.cpp: + (EventSender::mouseDown): + (EventSender::mouseUp): + * DumpRenderTree/qt/jsobjects.h: + +2009-10-06 Jakub Wieczorek <faw217@gmail.com> + + Reviewed by Simon Hausmann. + + [Qt] Fix the EventSender::keyDown() implementation + https://bugs.webkit.org/show_bug.cgi?id=30043 + + It should post both a key press event and a key release event, + just like other ports do. + + * DumpRenderTree/qt/jsobjects.cpp: + (EventSender::keyDown): + +2009-10-05 Kevin Ollivier <kevino@theolliviers.com> + + wx build fix. Add jpeg to the list of libs to link against. + + * wx/build/settings.py: + +2009-10-05 Jakub Wieczorek <faw217@gmail.com> + + Reviewed by Simon Hausmann. + + [Qt] EventSender::keyDown() cannot send function-key events. + https://bugs.webkit.org/show_bug.cgi?id=30044 + + This affects the fast/events/keydown-function-keys.html layout test. + + * DumpRenderTree/qt/jsobjects.cpp: + (EventSender::keyDown): + +2009-10-05 Vadim Zeitlin <vadim@wxwidgets.org> + + Added --wx-compiler-prefix waf option to allow building wxWebKit with + wxWidgets built using "nmake COMPILER_PREFIX=something-non-default". + + * wx/build/settings.py: + * wx/build/wxpresets.py: + +2009-10-05 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Timothy Hatcher. + + Web Inspector: add testing harness for Web Inspector. + + https://bugs.webkit.org/show_bug.cgi?id=30010 + + * DumpRenderTree/LayoutTestController.cpp: + (showWebInspectorCallback): + (closeWebInspectorCallback): + (evaluateInWebInspectorCallback): + (LayoutTestController::staticFunctions): + * DumpRenderTree/LayoutTestController.h: + * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp: + (LayoutTestController::showWebInspector): + (LayoutTestController::closeWebInspector): + (LayoutTestController::evaluateInWebInspector): + * DumpRenderTree/mac/LayoutTestControllerMac.mm: + (LayoutTestController::showWebInspector): + (LayoutTestController::closeWebInspector): + (LayoutTestController::evaluateInWebInspector): + * DumpRenderTree/win/LayoutTestControllerWin.cpp: + (LayoutTestController::showWebInspector): + (LayoutTestController::closeWebInspector): + (LayoutTestController::evaluateInWebInspector): + * DumpRenderTree/wx/LayoutTestControllerWx.cpp: + (LayoutTestController::showWebInspector): + (LayoutTestController::closeWebInspector): + (LayoutTestController::evaluateInWebInspector): + +2009-10-05 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + Reviewed by Ariyha Hidayat. + + Pass arguments to system() as a string instead of array + + When passed as an array entries with a space fail to translate + to two arguments to the child process, so instead of manually + splitting all the entries in @buildArgs we pass the whole thing + as a string instead. + + * Scripts/webkitdirs.pm: + +2009-10-04 Carol Szabo <carol.szabo@nokia.com> + + Reviewed by David Levin. + + check-webkit-style misses whitespace errors for operators: + <<, >>, <<=, >>=, &=, |=, +=, -=, *=, /=, /, |, &&, ||. + https://bugs.webkit.org/show_bug.cgi?id=30021 + + * Scripts/modules/cpp_style.py: + Added the operators mentioned above to the same list as == and !=. + +2009-10-02 Julie Parent <jparent@chromium.org> + + Unreviewed. + + Adding myself and Ojan Vafai as committers, because we are committers. + + * Scripts/modules/committers.py: + +2009-10-02 Brian Weinstein <bweinstein@apple.com> + + Reviewed by Adam Roben. + + svn-create-patch should have an --ignore-changelogs to not add ChangeLogs to the diff, + this will help the patch merging process when TryBots are used. + + * Scripts/svn-create-patch: + +2009-10-02 Jakub Wieczorek <faw217@gmail.com> + + Reviewed by Simon Hausmann. + + [Qt] Implement layoutTestController.overridePreference(). + https://bugs.webkit.org/show_bug.cgi?id=29970 + + * DumpRenderTree/qt/DumpRenderTree.cpp: + (WebCore::WebPage::WebPage): + (WebCore::WebPage::resetSettings): + (WebCore::DumpRenderTree::resetToConsistentStateBeforeTesting): + * DumpRenderTree/qt/jsobjects.cpp: + (LayoutTestController::reset): + (LayoutTestController::setPrivateBrowsingEnabled): + (LayoutTestController::setPopupBlockingEnabled): + (LayoutTestController::overridePreference): + * DumpRenderTree/qt/jsobjects.h: + +2009-10-01 Chris Marrin <cmarrin@apple.com> + + Reviewed by Oliver Hunt. + + Turn on ENABLE_3D_CANVAS in TOT + https://bugs.webkit.org/show_bug.cgi?id=29906 + + * Scripts/build-webkit: + +2009-10-01 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Rubberstamped by Simon Hausmann. + + Enable HTTP tests for Qt + + * Scripts/run-webkit-tests: + +2009-10-01 Yaar Schnitman <yaar@chromium.org> + + Reviewed by Dimitri Glazkov. + + build-webkit --chromium now also works on cygwin. + + https://bugs.webkit.org/show_bug.cgi?id=29973 + + * Scripts/webkitdirs.pm: + +2009-10-01 Zoltan Horvath <zoltan@webkit.org> + + Reviewed by Simon Hausmann. + + [Qt] Don't use TCmalloc in DumpRenderTree + https://bugs.webkit.org/show_bug.cgi?id=27029 + + Add USE_SYSTEM_MALLOC macro to the DRT's profile to avoid using TCmalloc in Qt's DRT. + + * DumpRenderTree/qt/DumpRenderTree.pro: + +2009-10-01 Jakub Wieczorek <faw217@gmail.com> + + Reviewed by Simon Hausmann. + + [Qt] Implement eventSender.scheduleAsynchronousClick(). + + https://bugs.webkit.org/show_bug.cgi?id=29931 + + * DumpRenderTree/qt/jsobjects.cpp: + (EventSender::scheduleAsynchronousClick): + * DumpRenderTree/qt/jsobjects.h: + +2009-10-01 Jakub Wieczorek <faw217@gmail.com> + + Reviewed by Simon Hausmann. + + [Qt] Implement setPopupBlockingEnabled() in the LayoutTestController and remove + fast/events/open-window-from-another-frame.html from the Skipped list. + + https://bugs.webkit.org/show_bug.cgi?id=29930 + + * DumpRenderTree/qt/jsobjects.cpp: + (LayoutTestController::setPopupBlockingEnabled): + * DumpRenderTree/qt/jsobjects.h: + +2009-09-30 Cameron McCormack <cam@mcc.id.au> + + Unreviewed. + + Added myself to the list of committers. + + * Scripts/modules/committers.py: + +2009-09-30 Eric Seidel <eric@webkit.org> + + No review, just adding Geoff to the list of reviewers. + + * Scripts/modules/committers.py: + +2009-09-30 Dan Bernstein <mitz@apple.com> + + Reviewed by Sam Weinig. + + Added the WebKit Layout Tests fonts that are referenced in + LayoutTests/platform/win/css2.1/resources/Mac-compatible-font-fallback.css + + * DumpRenderTree/fonts/WebKit Layout Tests 2.ttf: Added. + * DumpRenderTree/fonts/WebKit Layout Tests.ttf: Added. + +2009-09-30 Csaba Osztrogonac <oszi@inf.u-szeged.hu> + + Reviewed by David Kilzer. + + Make sunspider scripts work on Windows platform. + https://bugs.webkit.org/show_bug.cgi?id=29656 + + * Scripts/run-sunspider: Perl scripts invoked with same Perl interpreter. + * Scripts/sunspider-compare-results: Perl scripts invoked with same Perl interpreter. + * Scripts/webkitdirs.pm: currentPerlPath() added. + +2009-09-29 Brady Eidson <beidson@apple.com> + + Rubberstamped by Dan Bernstein. + + Fix license and some sorting in new files. + + * DumpRenderTree/mac/HistoryDelegate.h: + * DumpRenderTree/mac/HistoryDelegate.mm: + +2009-09-29 Yaar Schnitman <yaar@chromium.org> + + Reviewed by David Kilzer. + + Fixed how error codes are handled. + https://bugs.webkit.org/show_bug.cgi?id=29898 + + * Scripts/update-webkit: + * Scripts/update-webkit-chromium: + +2009-09-29 Brady Eidson <beidson@apple.com> + + Reviewed by John Sullivan. + + Updated way-out-of-date sorting throughout the dump methods/flags. + + * DumpRenderTree/LayoutTestController.cpp: + (LayoutTestController::LayoutTestController): + (dumpAsPDFCallback): + (dumpAsTextCallback): + (dumpFrameLoadCallbacksCallback): + (dumpResourceLoadCallbacksCallback): + (LayoutTestController::staticFunctions): + + * DumpRenderTree/LayoutTestController.h: + (LayoutTestController::dumpAsText): + (LayoutTestController::setDumpAsText): + (LayoutTestController::dumpFrameLoadCallbacks): + (LayoutTestController::setDumpFrameLoadCallbacks): + (LayoutTestController::dumpSelectionRect): + (LayoutTestController::setDumpSelectionRect): + (LayoutTestController::dumpSourceAsWebArchive): + (LayoutTestController::setDumpSourceAsWebArchive): + (LayoutTestController::dumpStatusCallbacks): + (LayoutTestController::setDumpStatusCallbacks): + (LayoutTestController::dumpTitleChanges): + (LayoutTestController::setDumpTitleChanges): + (LayoutTestController::dumpWillCacheResponse): + (LayoutTestController::setDumpWillCacheResponse): + +2009-09-29 Brady Eidson <beidson@apple.com> + + Reviewed by John Sullivan. + + WebKit Mac API should provide a delegate interface for global history. + <rdar://problem/7042773> and https://webkit.org/b/29904 + + Adding the dumping of global history delegate callbacks. + + * DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj: + + Automatically dump history delegate callbacks for tests with "globalhistory/" in their URL: + * DumpRenderTree/mac/DumpRenderTree.mm: + (createWebViewAndOffscreenWindow): + (allocateGlobalControllers): + (shouldLogFrameLoadDelegates): + (shouldLogHistoryDelegates): + (runTest): + + Dump history delegate callbacks: + * DumpRenderTree/mac/HistoryDelegate.h: Added. + * DumpRenderTree/mac/HistoryDelegate.mm: Added. + (-[HistoryDelegate webView:didNavigateWithNavigationData:inFrame:]): + (-[HistoryDelegate webView:didPerformClientRedirectFromURL:toURL:inFrame:]): + (-[HistoryDelegate webView:didPerformServerRedirectFromURL:toURL:inFrame:]): + +2009-09-29 Daniel Bates <dbates@webkit.org> + + Reviewed by Adam Roben. + + https://bugs.webkit.org/show_bug.cgi?id=28902 + + Fixes an issue where the drop effect returned by Window Dump Render Tree + was always DROPEFFECT_NONE (since it was hard coded to do so). + + This patch corrects this issue by determining the actual drop effect + performed by the corresponding drag-and-drop operation so that we can + return it. + + * DumpRenderTree/win/DraggingInfo.h: Added field m_dropEffect to store performed drop effect. + (DraggingInfo::DraggingInfo): + (DraggingInfo::performedDropEffect): Added method. + (DraggingInfo::setPerformedDropEffect): Added method. + * DumpRenderTree/win/EventSender.cpp: + (doMouseUp): Calls method DraggingInfo::setPerformedDropEffect with performed drop effect. + Moved delete draggingInfo to UIDelegate::doDragDrop. + * DumpRenderTree/win/UIDelegate.cpp: + (UIDelegate::doDragDrop): Sets performedDropEffect to DraggingInfo::performedDropEffect(). + +2009-09-29 Dan Bernstein <mitz@apple.com> + + Reviewed by Adam Roben. + + Remove copying of unnecessary or nonexistent files from the ImageDiff + post-build event. + + * DumpRenderTree/win/ImageDiff.vcproj: + +2009-09-29 Csaba Osztrogonac <oszi@inf.u-szeged.hu> + + Reviewed by David Kilzer. + + [Qt] Make build-webkit script work on Windows + https://bugs.webkit.org/show_bug.cgi?id=29802 + + * Scripts/run-webkit-tests: + * Scripts/webkitdirs.pm: + - Removed unnecessary -p switch for mkdir on Windows. + - Use canonical path, which uses slashes or backslashes depends on platform. + - isWindows() only test for Windows and not for Cyqwin. + +2009-09-29 Andras Becsi <becsi.andras@stud.u-szeged.hu> + + Reviewed by Simon Hausmann. + + Fix time measurement in build-webkit after refactoring done in r48853. + + * Scripts/build-webkit: + +2009-09-29 Andras Becsi <becsi.andras@stud.u-szeged.hu> + + Reviewed by Tor Arne Vestbø. + + [Qt] Default font size reconciliation to 16px/13px to match other platform's de-facto standard. + This fixes https://bugs.webkit.org/show_bug.cgi?id=19674. + + * DumpRenderTree/qt/DumpRenderTree.cpp: + (WebCore::WebPage::WebPage): + +2009-09-29 Jakub Wieczorek <faw217@gmail.com> + + Reviewed by Simon Hausmann. + + [Qt] Implement eventSender.contextClick(). + https://bugs.webkit.org/show_bug.cgi?id=29821 + + * DumpRenderTree/qt/jsobjects.cpp: + (EventSender::contextClick): + * DumpRenderTree/qt/jsobjects.h: + +2009-09-28 Fumitoshi Ukai <ukai@chromium.org> + + Reviewed by Eric Seidel. + + Add experimentalWebSocketsEnabled in WebPreferences. + https://bugs.webkit.org/show_bug.cgi?id=28941 + + * DumpRenderTree/mac/DumpRenderTree.mm: + (resetDefaultsToConsistentValues): + * DumpRenderTree/win/DumpRenderTree.cpp: + (resetDefaultsToConsistentValues): + +2009-09-28 Yaar Schnitman <yaar@chromium.org> + + Reviewed by David Kilzer. + + Integrated chromium port building into webkit tools update-webkit and + build-webkit. + + https://bugs.webkit.org/show_bug.cgi?id=29749 + + * Scripts/build-webkit: When --chromium is specified, will build + the chromium port (currently only Mac is supported). + * Scripts/update-webkit: When --chromium is specified, delegates to + update-webkit-chromium. + * Scripts/webkitdirs.pm: Added chromium specific defs. + * Scripts/update-webkit-chromium: Uses gclient and gyp to fetch + chromium port's dependencies and update its project files. + +2009-09-28 Fumitoshi Ukai <ukai@chromium.org> + + Unreviewed. + + Add myself to list of committers. + + * Scripts/modules/committers.py: + +2009-09-27 Jakub Wieczorek <faw217@gmail.com> + + Reviewed by Darin Adler. + + run-webkit-tests: Do not strip the metrics when there is no expected result for a test. + https://bugs.webkit.org/show_bug.cgi?id=29771 + + * Scripts/run-webkit-tests: + +2009-09-27 Jakub Wieczorek <faw217@gmail.com> + + Reviewed by Simon Hausmann. + + [Qt] Implement layoutTestController.waitForPolicyDelegate. + https://bugs.webkit.org/show_bug.cgi?id=25037 + + * DumpRenderTree/qt/DumpRenderTree.cpp: + (WebCore::WebPage::acceptNavigationRequest): + * DumpRenderTree/qt/DumpRenderTree.pro: + * DumpRenderTree/qt/jsobjects.cpp: + (LayoutTestController::reset): + (LayoutTestController::notifyDone): + (LayoutTestController::waitForPolicyDelegate): + * DumpRenderTree/qt/jsobjects.h: + (LayoutTestController::waitForPolicy): + +2009-09-26 David Kilzer <ddkilzer@apple.com> + + <http://webkit.org/b/29764> mark-bug-fixed: add -o|--open switch + + Reviewed by Eric Seidel. + + The -o|--open switch uses the open(1) command on Mac OS X to + open the bug URL in the default web browser. If there are + similar mechanisms on other platforms, they may be added later. + + * Scripts/mark-bug-fixed: + (MarkBugFixed.__init__): Added -o|--open switch to list of parse + options. + (MarkBugFixed._determine_bug_id_and_svn_revision): Moved logging + code into main() and extracted prompting code into + _prompt_user_for_correctness(). + (MarkBugFixed._open_bug_in_web_browser): Added. + (MarkBugFixed._prompt_user_for_correctness): Added. + (MarkBugFixed.main): Added logging code from + _determine_bug_id_and_svn_revision(). Added code to call + _open_bug_in_web_browser() if the switch is set. Added code to + call _prompt_user_for_correctness() when needed. + * Scripts/modules/bugzilla.py: + (Bugzilla.short_bug_url_for_bug_id): Added. + +2009-09-26 David Kilzer <ddkilzer@apple.com> + + svn-unapply and svn-apply don't work when used outside multiple svn working directories + + <http://webkit.org/b/29744> + <rdar://problem/7252905> + + Reviewed by Eric Seidel. + + Some users have a workflow where svn-create-patch, svn-apply and + svn-unapply are used outside of multiple svn working + directories. Instead of aborting the scripts in these cases, + print a warning and assume that Subversion is being used. + + * Scripts/VCSUtils.pm: + (determineVCSRoot): Call warn() instead of die() if both isGit() + and isSVN() initially return false. Set $VCSUtils::isSVN to 1 + to enforce the assumption about Subversion, then return + determineSVNRoot(). + * Scripts/svn-apply: Switch to using isGit() and isSVN() from + VCSUtils.pm. They both already cache their values and checking + here is redundant since determineVCSRoot() is called later. + +2009-09-26 Zan Dobersek <zandobersek@gmail.com> + + Reviewed by Gustavo Noronha. + + [Layout tests] [Gtk] Gtk DumpRenderTree should use WebKit test fonts + https://bugs.webkit.org/show_bug.cgi?id=29689 + + Load test fonts through FontConfig before each test. + This ensures a more proper rendering of the tests. + + * DumpRenderTree/gtk/DumpRenderTree.cpp: + (initializeFonts): + (runTest): + (main): + * DumpRenderTree/gtk/fonts.conf: Copied from WebKitTools/DumpRenderTree/qt/fonts.conf. + * GNUmakefile.am: + +2009-09-25 David Kilzer <ddkilzer@apple.com> + + <http://webkit.org/b/29718> mark-bug-fixed: add -u|--update-only switch + + Reviewed by Eric Seidel. + + * Scripts/mark-bug-fixed: + (MarkBugFixed.__init__): Added -u|--update-only switch to list + of parse options. + (MarkBugFixed.main): When -u|--update-only is specified, add a + comment to the bug without marking it Resolved/Fixed. + +2009-09-25 Darin Adler <darin@apple.com> + + Reviewed by Geoffrey Garen. + + * Scripts/prepare-ChangeLog: Leave files from the script-tests directory + out, just as we do for the resources directory. + +2009-09-25 Adam Barth <abarth@webkit.org> + + Unreviewed. Added Tony to committers.py because he's a + committer now. + + * Scripts/modules/committers.py: + +2009-09-25 Eric Seidel <eric@webkit.org> + + Reviewed by Simon Fraser. + + REGRESSION: media/video-pause-empty-events.html is occasionally timing out on bots + https://bugs.webkit.org/show_bug.cgi?id=28624 + + Disable hardware compositing on Leopard for versions of QuickTime 7.6.4 and older. + + * DumpRenderTree/mac/DumpRenderTree.mm: + (resetDefaultsToConsistentValues): + +2009-09-25 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + commit-queue should auto-retry patches which fail to commit due to out of date files + https://bugs.webkit.org/show_bug.cgi?id=28316 + + * Scripts/bugzilla-tool: + - Handle new CheckoutNeedsUpdate exception. + * Scripts/modules/logging_unittest.py: + - Call the ScriptError constructor correctly (this test had regressed). + * Scripts/modules/scm.py: + - Added the ability to define custom error handlers for run_command + and added a commit_error_handler which throws CheckoutNeedsUpdate + instead of ScriptError. + - Re-ordered ScriptError constructor arguments to make ScriptError("message text") usage possible. + * Scripts/modules/scm_unittest.py: + - Added tests of new error handlers. + +2009-09-25 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + commit-queue should give better feedback when failing a patch + https://bugs.webkit.org/show_bug.cgi?id=29316 + + * Scripts/bugzilla-tool: + - Update ScriptError uses to the new constructor format. + - Move CommitQueue._run_command to WebKitLandingScripts.run_command_with_teed_output + so that we can print to both stdout as well as an output buffer for error reporting. + - Update run_and_throw_if_fail to use teed output so that it can report the "output" as part of ScriptError. + - Use e.message_with_output() when failing a patch (this is the real fix here). + I also removed use of "This patch will require manual commit." as that's not always true. + - Add missing word "bug" from log message. + * Scripts/modules/scm.py: + - Make ScriptError save a bunch more data so that error messages can be nicer. + - Update ScriptError callers. + +2009-09-24 John Gregg <johnnyg@google.com> + + Reviewed by Eric Seidel. + + Enable switch for notifications (experimental) in Page Settings + https://bugs.webkit.org/show_bug.cgi?id=28930 + + Now that desktop notifications are controlled by run-time switch, + set that switch to true for DumpRenderTree. + + * DumpRenderTree/mac/DumpRenderTree.mm: + (resetDefaultsToConsistentValues): + * DumpRenderTree/win/DumpRenderTree.cpp: + (resetDefaultsToConsistentValues): + * DumpRenderTree/win/UIDelegate.cpp: + (UIDelegate::QueryInterface): + +2009-09-24 Kevin Ollivier <kevino@theolliviers.com> + + wx build fix. SnowLeopard fixes for Mac dependencies. + + * wx/build/build_utils.py: + * wx/build/settings.py: + * wx/install-unix-extras: + +2009-09-24 Gustavo Noronha Silva <gustavo.noronha@collabora.co.uk> + + Reviewed by Oliver Hunt. + + Add support for DRT to send mouse wheel events. + + https://bugs.webkit.org/show_bug.cgi?id=29348 + [Gtk] Scrollwheel on horizontal scrollbars should slide horizontally + + * DumpRenderTree/gtk/EventSender.cpp: + (mouseWheelToCallback): + +2009-09-17 Eric Seidel <eric@webkit.org> + + Reviewed by David Levin. + + commit-queue needs web-based status reporting + https://bugs.webkit.org/show_bug.cgi?id=29307 + + Add a first-pass web-based status for the commit-queue. + The bot is currently reachable at: + http://webkit-commit-queue.appspot.com/ + + * CommitQueueStatus/app.yaml: Added. + - Application description file required by App Engine. + * CommitQueueStatus/filters/__init__.py: Added. + - Required by python to treat 'filters' as a module. + * CommitQueueStatus/filters/webkit_extras.py: Added. + - Support for turning 'bug 123' and 'patch 123' into links. + This lets us use plain text strings in our logs yet display nice HTML (help prevent XSS attacks on the page). + * CommitQueueStatus/index.html: Added. + * CommitQueueStatus/index.yaml: Added. + - Some auto-generated file from app engine. + * CommitQueueStatus/queue_status.py: Added. + - The core logic of this bot. We could eventually split this file out into pieces. + * CommitQueueStatus/stylesheets/main.css: Added. + - Some basic lame-o CSS to make the page look less awful. + * CommitQueueStatus/update_status.html: Added. + - The form that the commit-queue (or a human) can use to update the status. + * Scripts/bugzilla-tool: + - Add some very basic update_status calls. + * Scripts/modules/statusbot.py: Added. + - Knows how to post to the CommitQueueStatus web application. + +2009-09-24 David Kilzer <ddkilzer@apple.com> + + <http://webkit.org/b/29712> mark-bug-fixed: add -m|--comment switch + + Reviewed by Adam Roben. + + * Scripts/mark-bug-fixed: + (MarkBugFixed.__init__): Added -m|--comment switch to list of + parse options. + (MarkBugFixed.main): When specified, prepend comment from + -m|--comment command-line switch to the bug comment. + +2009-09-24 Gustavo Noronha Silva <gustavo.noronha@collabora.co.uk> + + Reviewed by Jan Alonzo. + + [GTK] DRT must display window instead of just realizing, to enable synthesizing events correctly + https://bugs.webkit.org/show_bug.cgi?id=29693 + + Show the window, to be able to synthesize events correctly. + + * DumpRenderTree/gtk/DumpRenderTree.cpp: + (runTest): + (main): + +2009-09-24 Oliver Hunt <oliver@apple.com> + + Reviewed by NOBODY(rollout) + + Roll out r48712 as it is incorrect. + + * DumpRenderTree/mac/ObjCController.m: + (+[ObjCController isSelectorExcludedFromWebScript:]): + (+[ObjCController webScriptNameForSelector:]): + +2009-09-24 Benjamin Poulain <benjamin.poulain@nokia.com> + + Reviewed by Eric Seidel. + + https://bugs.webkit.org/show_bug.cgi?id=29005 + The indices of RuntimeArray should be enumerated like for a regular array. + + * DumpRenderTree/mac/ObjCController.m: + (+[ObjCController isSelectorExcludedFromWebScript:]): + (+[ObjCController webScriptNameForSelector:]): + (-[ObjCController arrayOfString]): + +2009-09-23 David Kilzer <ddkilzer@apple.com> + + <http://webkit.org/b/28910> Move bugzilla-tool mark-fixed to standalone mark-bug-fixed tool + + Reviewed by Darin Adler. + + Also fixed a bug where specifying a revision on the command-line + as 'r12345' would fail. See <http://webkit.org/b/29699>. + + * Scripts/bugzilla-tool: Updated module import statements. + (parse_bug_id): Removed. Moved to bugzilla.py. + (bug_comment_from_svn_revision): Removed. Moved to comments.py. + (bug_comment_from_commit_text): Removed. Moved to comments.py. + (MarkBugFixed): Removed. Code moved to mark-bug-fixed. + (BugzillaTool.__init__): Removed mark-fixed subcommand. + * Scripts/mark-bug-fixed: Added. + * Scripts/modules/bugzilla.py: + (parse_bug_id): Added. Moved from bugzilla-tool. + * Scripts/modules/comments.py: Added. + (bug_comment_from_svn_revision): Added. Moved from bugzilla-tool. + (bug_comment_from_commit_text): Added. Moved from bugzilla-tool. + +2009-09-23 Marshall Culpepper <mculpepper@appcelerator.com> + + Reviewed by Eric Seidel. + + jpeg.lib is now libjpeg.lib in DRT Cairo dependencies. return + "false" in non-implemented stub for setAlwaysAcceptCookies. + https://bugs.webkit.org/show_bug.cgi?id=29661 + + * DumpRenderTree/win/DumpRenderTree.vcproj: + * DumpRenderTree/win/DumpRenderTree.cpp: + +2009-09-23 Gustavo Noronha Silva <gustavo.noronha@collabora.co.uk> + + Reviewed by Xan Lopez. + + [GTK] need to dump number of pending unload handlers + https://bugs.webkit.org/show_bug.cgi?id=29685 + + Implement dumping of the number of pending unload handlers. + + The following tests will pass: + + fast/loader/unload-form-about-blank.html + fast/loader/unload-form-post-about-blank.html + fast/loader/unload-form-post.html + fast/loader/unload-form.html + fast/loader/unload-hyperlink.html + fast/loader/unload-javascript-url.html + fast/loader/unload-reload.html + fast/loader/unload-window-location.html + + * DumpRenderTree/gtk/DumpRenderTree.cpp: + (getFrameNameSuitableForTestResult): + (webViewLoadFinished): + +2009-09-22 Shinichiro Hamaji <hamaji@chromium.org> + + Reviewed by Eric Seidel. + + js tests should move into jstests subdirectory instead of resources/ + https://bugs.webkit.org/show_bug.cgi?id=25880 + + Remove support of resources directory. + + * Scripts/make-script-test-wrappers: + +2009-09-22 Eric Seidel <eric@webkit.org> + + No review, only fixing typo (missing space character). + + Fix typo from https://bugs.webkit.org/show_bug.cgi?id=29220 + + * Scripts/run-webkit-tests: + +2009-09-22 Eric Seidel <eric@webkit.org> + + Reviewed by Darin Adler. + + run-webkit-tests needs a --repeat-each=N option (AAABBBCCC instead of ABCABCABC) + https://bugs.webkit.org/show_bug.cgi?id=29220 + + * Scripts/run-webkit-tests: + +2009-09-22 Eric Seidel <eric@webkit.org> + + Reviewed by David Kilzer. + + svn-apply can't handle single-line binary file additions + https://bugs.webkit.org/show_bug.cgi?id=29100 + + Fixed the regexp and added a unit test. + + * Scripts/modules/scm_unittest.py: + * Scripts/svn-apply: + +2009-09-11 Eric Seidel <eric@webkit.org> + + Reviewed by David Kilzer. + + post-diff and post-commits should be able to find bug urls in ChangeLogs. + https://bugs.webkit.org/show_bug.cgi?id=29206 + + * Scripts/bugzilla-tool: + - Share common options by adding a PostDiffAsPatchToBug.posting_options() method. + - Rename --no-comment to --add-log-as-comment and reverse behavior. + Comments tend to just be noise. I'll eventually remove this argument if no one uses it. + - Split out code into helper functions to try and make execute() more legible. + - Make post-diff find the bug url in the ChangeLogs if not passed as an argument. + - Fallback to bug urls in commit diffs, instead of just in commit messages, + meaning post-commits will now find bug urls in ChangeLogs. + +2009-09-21 Csaba Osztrogonac <oszi@inf.u-szeged.hu> + + Reviewed by Maciej Stachowiak. + + --parse-only parameter wasn't passed to SunSpider/sunspider script. + https://bugs.webkit.org/show_bug.cgi?id=29611 + + * Scripts/run-sunspider: Missing parameter passing added. + +2009-09-20 David Kilzer <ddkilzer@apple.com> + + <http://webkit.org/b/29521> run-webkit-tests: use require instead eval to load DumpRenderTreeSupport module + + Reviewed by Mark Rowe. + + The require statement is like the use statement, except that it + is run during script execution instead of during the 'BEGIN' + phase. This makes it possible to change @INC before the require + statement is run. See 'require' and 'use' in the perlfunc(1) + manpage and 'BEGIN' in perlmod(1) manpage. + + * Scripts/run-webkit-tests: Replace eval statement with require + statement. + +2009-09-18 Kevin Ollivier <kevino@theolliviers.com> + + wx build fixes. Fix the config name under git and allow users to specify + their own waf install for experimenting with new versions. + + * Scripts/webkitdirs.pm: + * wx/build/settings.py: + +2009-09-18 Alex Milowski <alex@milowski.com> + + Reviewed by Maciej Stachowiak. + + Added checkWebCoreMathMLSupport and hasMathMLSupport to support + checking for whether MathML tests should be run + + * Scripts/run-webkit-tests: + * Scripts/webkitdirs.pm: + +2009-08-28 Darin Adler <darin@apple.com> + + Reviewed by Mark Rowe. + + Break more of run-webkit-tests into separate functions + https://bugs.webkit.org/show_bug.cgi?id=29497 + + Some small steps toward improving run-webkit-tests. My goal is to + refactor much more of the script into functions. Later we can add + parallel test running to the tool. But better structure may help + even if someone decides to translate this into another scripting + language instead. + + * Scripts/run-webkit-tests: Break more pieces of the script into + seprate functions. Added readSkippedFiles, findTestsToRun, and + printResults functions. Removed custom code to skip results.html + and instead just put it into the ignoredFiles hash. Fixed some + indentation. Sorted function declarations, global variables, + and options at the top of the file alphabetically so they're not + in a semi-random order. + +2009-09-17 Kevin Ollivier <kevino@theolliviers.com> + + wx build fix, add missing dependency. + + * wx/browser/wscript: + +2009-09-16 Mark Rowe <mrowe@apple.com> + + Split the SnowLeopard build across a few machines. + + * BuildSlaveSupport/build.webkit.org-config/config.json: + +2009-09-16 Kevin Ollivier <kevino@theolliviers.com> + + wx build fix to support monolithic builds on Windows. + + * wx/build/wxpresets.py: + +2009-09-16 Kevin Ollivier <kevino@theolliviers.com> + + wx build fix, improve debug support and 2.9 support on MSW. + + * wx/build/settings.py: + * wx/build/wxpresets.py: + +2009-09-16 Gustavo Noronha Silva <gustavo.noronha@collabora.co.uk> + + Blind try at fixing new test failure on Windows. + + * DumpRenderTree/win/FrameLoadDelegate.cpp: + (FrameLoadDelegate::didReceiveTitle): + +2009-09-15 Alex Milowski <alex@milowski.com> + + Reviewed by Tor Arne Vestbø. + + Added mathml toggle + + * Scripts/build-webkit: + +2009-09-15 Kevin Ollivier <kevino@theolliviers.com> + + wx build fix. Allow waf build to support Python < 2.6. + + * wx/build/waf_extensions.py: + +2009-09-14 Chris Marrin <cmarrin@apple.com> + + Reviewed by Oliver Hunt. + + Add LayoutTests infrastructure to enable and disable webgl tests. + https://bugs.webkit.org/show_bug.cgi?id=29254 + + * Scripts/run-webkit-tests: + * Scripts/webkitdirs.pm: + +2009-09-14 Simon Fraser <simon.fraser@apple.com> + + Reviewed by Darin Adler. + + Add --iterations option to run-webkit-tests to repeat the tests N times + https://bugs.webkit.org/show_bug.cgi?id=29263 + + When run with --iterations N, run-webkit-tests will repeat the tests N times. + + * Scripts/run-webkit-tests: + +2009-09-14 Brady Eidson <beidson@apple.com> + + Not reviewed, maybe should've been: + + Cleaning up more Windows-specific fallout from the fix for: + <rdar://problem/7174050> and https://bugs.webkit.org/show_bug.cgi?id=29160 + + * DumpRenderTree/win/ResourceLoadDelegate.cpp: + (ResourceLoadDelegate::didReceiveAuthenticationChallenge): Correct printf() formatter, + and call the correct method to get the Sender. + +2009-09-14 Jon Honeycutt <jhoneycutt@apple.com> + + GTK build fix. + + Unreviewed. + + * DumpRenderTree/gtk/AccessibilityControllerGtk.cpp: + (AccessibilityController::setLogScrollingStartEvents): + +2009-09-11 Jon Honeycutt <jhoneycutt@apple.com> + + DRT/test part of + <rdar://problem/7197644> WebKit should broadcast an MSAA event when + jumping to a named anchor + + https://bugs.webkit.org/show_bug.cgi?id=28899 + + Reviewed by Adam Roben. + + * DumpRenderTree/AccessibilityController.cpp: + (logScrollingStartEventsCallback): + Turn on logging of scrolling start events. + (AccessibilityController::getJSClass): + Add a "logScrollingStartEvents" to the AccessibilityController's JS + class definition. + (AccessibilityController::resetToConsistentState): + Turn off logging of scrolling start events. + + * DumpRenderTree/AccessibilityController.h: + Declare setLogScrollingStartEvents(). Add a member for the scrolling + start event hook. + + * DumpRenderTree/mac/AccessibilityControllerMac.cpp: + (AccessibilityController::setLogScrollingStartEvents): + Stubbed. + + * DumpRenderTree/win/AccessibilityControllerWin.cpp: + (AccessibilityController::AccessibilityController): + Initialize the handle to 0. + (logEventProc): + Renamed from logFocusEventProc; now logs scrolling start events, too. + Removed the assertion that the event is a focus event. Added a switch + to print a message for focus, scrolling start, and other, unknown + events. + (AccessibilityController::setLogFocusEvents): + Changed to use logEventProc. + (AccessibilityController::setLogScrollingStartEvents): + If turning logging off, unhook the scrolling start event hook, and clear + the member holding the handle. If turning on, query for the root + accessible, so that accessibility is enabled for the WebView, and call + SetWinEventHook to setup an event hook using logEventProc as the + callback function. + +2009-09-14 Brady Eidson <beidson@apple.com> + + Windows build fix. + + * DumpRenderTree/LayoutTestController.cpp: + (setAuthenticationPasswordCallback): + (setAuthenticationUsernameCallback): + + * DumpRenderTree/win/ResourceLoadDelegate.cpp: + (ResourceLoadDelegate::didReceiveAuthenticationChallenge): + +2009-09-14 Brady Eidson <beidson@apple.com> + + Reviewed by Alexey Proskuryakov. + + Safari 4 cannot be used to update firmware on Linksys routers. + <rdar://problem/7174050> and https://bugs.webkit.org/show_bug.cgi?id=29160 + + Add the ability for DRT to handle authentication challenges. + + * DumpRenderTree/LayoutTestController.cpp: + (setAuthenticationPasswordCallback): + (setAuthenticationUsernameCallback): + (setHandlesAuthenticationChallengesCallback): + (LayoutTestController::staticFunctions): + + * DumpRenderTree/LayoutTestController.h: + (LayoutTestController::handlesAuthenticationChallenges): + (LayoutTestController::setHandlesAuthenticationChallenges): + (LayoutTestController::authenticationUsername): + (LayoutTestController::setAuthenticationUsername): + (LayoutTestController::authenticationPassword): + (LayoutTestController::setAuthenticationPassword): + + * DumpRenderTree/mac/ResourceLoadDelegate.mm: + (-[ResourceLoadDelegate webView:resource:didReceiveAuthenticationChallenge:fromDataSource:]): + + * DumpRenderTree/win/ResourceLoadDelegate.cpp: + (ResourceLoadDelegate::didReceiveAuthenticationChallenge): + * DumpRenderTree/win/ResourceLoadDelegate.h: + +2009-09-12 Mark Rowe <mrowe@apple.com> + + Reviewed by Dan Bernstein. + + Test for <rdar://problem/6954546> and <rdar://problem/7090444>. + + Add a flag on the test plug-in that asks it to clear the document during the call to NPP_New. + This is the trigger for both <rdar://problem/6954546> and <rdar://problem/7090444>. + + * DumpRenderTree/TestNetscapePlugIn.subproj/main.cpp: + (NPP_New): + +2009-09-14 Kevin Ollivier <kevino@theolliviers.com> + + wx build fix for non-wxPython builds and a fix for errors when updating swig.py. + + * wx/build/build_utils.py: + * wx/build/settings.py: + +2009-09-14 Csaba Osztrogonac <oszi@inf.u-szeged.hu> + + Reviewed by Tor Arne Vestbø. + + [Qt] Build fix for windows build. + + * Scripts/bisect-builds: Add missing paranthesis for tmpdir function. + +2009-09-13 Kevin Ollivier <kevino@theolliviers.com> + + Fix typo accidently landed in last commit. + + * wx/build/settings.py: + +2009-09-13 Kevin Ollivier <kevino@theolliviers.com> + + wx build fix, error out if using the wrong Python. + + * wx/build/settings.py: + +2009-09-13 Xan Lopez <xlopez@igalia.com> + + Build fix for GTK+ < 2.14. + + Do not use gtk_widget_get_window, access the window directly + through the struct. + + * DumpRenderTree/gtk/EventSender.cpp: + (contextClickCallback): + (mouseDownCallback): + (mouseUpCallback): + (mouseMoveToCallback): + (keyDownCallback): + +2009-09-13 Martin Robinson <martin.james.robinson@gmail.com> + + Reviewed by Xan Lopez and Jan Alonzo. + + [GTK] EventSender does not set 'window' property on synthesized GDK events + https://bugs.webkit.org/show_bug.cgi?id=29169 + + Set the window property on synthesized GDK events in the GTK+ EventSender. + + * DumpRenderTree/gtk/EventSender.cpp: + (contextClickCallback): + (mouseDownCallback): + (mouseUpCallback): + (mouseMoveToCallback): + (keyDownCallback): + +2009-09-12 Drew Wilson <atwilson@google.com> + + Reviewed by Mark Rowe. + + run-webkit-tests has a timeout value that is too low + https://bugs.webkit.org/show_bug.cgi?id=29223 + + * Scripts/run-webkit-tests: + Changed timeout value to 20 seconds to avoid timing out too early. + +2009-09-11 Kevin Ollivier <kevino@theolliviers.com> + + wx build fix. Mark dependencies as mandatory and declare which MSVC versions and + architectures are supported for building wxWebKit. + + * wx/build/settings.py: + +2009-09-11 Eric Seidel <eric@webkit.org> + + Reviewed by David Levin. + + bugzilla-tool rollout threw exception under svn + https://bugs.webkit.org/show_bug.cgi?id=29211 + + * Scripts/modules/scm.py: add missing return, and convert number arguments to strings. + * Scripts/modules/scm_unittest.py: add testing for this fix. + +2009-09-11 Brian Weinstein <bweinstein@apple.com> + + Add myself to the committers list. + + * Scripts/modules/committers.py: + +2009-09-11 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + bugzilla-tool land-patches should only fail-fast in --commit-queue mode + https://bugs.webkit.org/show_bug.cgi?id=29201 + + * Scripts/bugzilla-tool: + +2009-09-11 Adam Roben <aroben@apple.com> + + Make commit-log-editor move common prefixes to the top of the log + + Fies <http://webkit.org/b/29190> commit-log-editor should move common + prefixes to the top of the commit log + + Reviewed by Darin Adler. + + * Scripts/commit-log-editor: Find and remove the longest common prefix + ending in a double newline from each ChangeLog entry, then put that + common prefix at the top of the commit log. + (removeLongestCommonPrefixEndingInDoubleNewline): Added. Finds, + removes, and returns the longest common prefix ending in a double + newline from a hash of strings + +2009-09-11 Eric Seidel <eric@webkit.org> + + Fix obvious typo in previous commit, no review. + + bugzilla-tool should automate rollouts + https://bugs.webkit.org/show_bug.cgi?id=26715 + + * Scripts/bugzilla-tool: add back missing "scm" argument. + +2009-09-11 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + bugzilla-tool should automate rollouts + https://bugs.webkit.org/show_bug.cgi?id=26715 + + bugzilla-tool rollout will do the rollout locally and leave the diff for you to verify and commit. + The --complete-rollout option will automatically land and update the bug. + Eventually --complete-rollout will be default, but that will require more testing. + + This first pass is good enough for others to try and file bugs about. + + * Scripts/bugzilla-tool: + - Move modified_changelogs into scm.py. + - Move svn_revision_from_commit_text logic into scm.py. + - Add RolloutCommit command. + * Scripts/modules/bugzilla.py: + - Add reopen_bug command used by RolloutCommit. + * Scripts/modules/scm.py: + - Add functions to support RolloutCommit. + - Abstract find_uuid into value_from_svn_info so it can be re-used for _repository_url (needed by svn merge). + - Add a str() call so that svn_commit_log can take a numeric argument. + - Remove a bunch of very slow code from last_svn_commit_log and used the built-in 'BASE' alias instead. + - Made dry_run commits return something that svn_revision_from_commit_text can parse. + * Scripts/modules/scm_unittest.py: + - Add read_from_path for easy file reading. + - Put test4 on a new line to make reverts work w/o conflict. + - Add an "svn update" call so that the checkout revision matches the server revision. + - Add tests for svn_revision_from_commit_text. + - Add a simple test for apply_reverse_diff. + - Add a new self.scm member and use it in the new tests (eventually other tests can use it too). + - Add test for svn_commit_log to make sure my 'BASE' change above worked as expected. + +2009-09-11 Adam Roben <aroben@apple.com> + + Get user script/stylesheet tests running on Windows + + Fixes <http://webkit.org/b/29181> User script/stylesheet tests are + skipped on Windows + + Reviewed by John Sullivan. + + * DumpRenderTree/win/DumpRenderTree.vcproj: Link all configurations + against comsuppw.lib so we can use _bstr_t. + + * DumpRenderTree/win/LayoutTestControllerWin.cpp: Fixed #include + order, added #include of comutil.h for _bstr_t. + + (bstrT): Helper function to convert a JSStringRef to a _bstr_t. + (LayoutTestController::addUserScript): + (LayoutTestController::addUserStyleSheet): + Implemented. Implementations were based on those in + LayoutTestControllerMac.mm. + +2009-09-10 David Kilzer <ddkilzer@apple.com> + + <http://webkit.org/b/29147> run-webkit-tests: make -h show help + + Reviewed by Mark Rowe. + + * Scripts/run-webkit-tests: Updated to make -h switch show help. + +2009-09-10 Fumitoshi Ukai <ukai@chromium.org> + + Reviewed by Alexey Proskuryakov. + + Add WebCore/websockets directory in wx build system. + https://bugs.webkit.org/show_bug.cgi?id=28038 + + * wx/build/settings.py: + +2009-09-10 Martin Robinson <martin.james.robinson@gmail.com> + + [GTK] EventSender does not properly convert some keyDown strings + https://bugs.webkit.org/show_bug.cgi?id=29119 + + Add more keyDown string to character code conversions for GTK+ EventSender. + + * DumpRenderTree/gtk/EventSender.cpp: + (keyDownCallback): + +2009-09-09 Steve Block <steveblock@google.com> + + Reviewed by Maciej Stachowiak. + + Geolocation Coordinates::toString() prints bogus values for unspecified properties. + https://bugs.webkit.org/show_bug.cgi?id=29080 + + * Scripts/make-script-test-wrappers: Modified. Adds asynchronous Geolocation tests to exclusion list. + +2009-09-09 Eric Seidel <eric@webkit.org> + + Reviewed by Eric Carlson. + + reviewer/committer lookups are backwards + https://bugs.webkit.org/show_bug.cgi?id=29113 + + I also moved Eric Carlson from the committer list to the reviewer list now that he is one. + + * Scripts/modules/bugzilla.py: + * Scripts/modules/committers.py: + +2009-09-09 Cameron McCormack <cam@mcc.id.au> + + Reviewed by Eric Seidel. + + svn-unapply doesn't revert directories correctly + https://bugs.webkit.org/show_bug.cgi?id=29065 + + * Scripts/svn-unapply: Make svnStatus consistently return status + lines including a newline. + * Scripts/svn-apply: Keep svnStatus in sync with the one in + svn-unapply, in lieu of moving it to a common file. + +2009-09-09 Cameron McCormack <cam@mcc.id.au> + + Reviewed by Eric Seidel. + + svn-apply doesn't handle changes to files copied to new directories properly + https://bugs.webkit.org/show_bug.cgi?id=29059 + + * Scripts/svn-apply: Don't treat "--- revision 0" patches as being + additions if we know that we've just copied a file to this name. + +2009-09-09 Eric Seidel <eric@webkit.org> + + Reviewed by David Levin. + + commit-queue hangs if a builder has never built + https://bugs.webkit.org/show_bug.cgi?id=29091 + + * Scripts/modules/buildbot.py: + * Scripts/modules/buildbot_unittest.py: + +2009-09-09 Zan Dobersek <zandobersek@gmail.com> + + Reviewed by Gustavo Noronha. + + [GTK] DumpRenderTree needs eventSender object and implementation + https://bugs.webkit.org/show_bug.cgi?id=25990 + + Implements most of the EventSender object's functionality for + the DumpRenderTree tool. Implementation still lacks support + for drag and drop tests and forward leaps. + + Based on work by Holger Hans Peter Freyther. + + * DumpRenderTree/gtk/DumpRenderTree.cpp: + (runTest): Focus on the view before loading a new test. + (webViewWindowObjectCleared): + * DumpRenderTree/gtk/EventSender.cpp: Added. + (getDragModeCallback): + (setDragModeCallback): + (leapForwardCallback): + (contextClickCallback): + (updateClickCount): + (mouseDownCallback): + (mouseUpCallback): + (mouseMoveToCallback): + (beginDragWithFilesCallback): + (replaySavedEvents): + (keyDownCallback): + (textZoomInCallback): + (textZoomOutCallback): + (zoomPageInCallback): + (zoomPageOutCallback): + (getClass): + (makeEventSender): + * DumpRenderTree/gtk/EventSender.h: Added. + * GNUmakefile.am: Add build rules for EventSender. + +2009-09-09 Daniel Bates <dbates@webkit.org> + + Reviewed by Adam Roben. + + https://bugs.webkit.org/show_bug.cgi?id=28953 + + Added pre- and post- build events so that on build failure, the file + buildfailed is written to the directory $(WebKitOutputDir). + + * WinLauncher/WinLauncher.vcproj: + +2009-09-09 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Unreviewed. + + Add myself to list of committers. + + * Scripts/modules/committers.py: + +2009-09-08 Eric Seidel <eric@webkit.org> + + Reviewed by David Levin. + + commit-queue gets stuck if a non-committer sets commit-queue+ or review+ + https://bugs.webkit.org/show_bug.cgi?id=28605 + https://bugs.webkit.org/show_bug.cgi?id=28916 + + * Scripts/bugzilla-tool: + - Fix comment and adjust reject_patch_from_commit_queue call to pass "manual commit" + comment now that it's used for rejecting patches for invalid committers too. + - Pass reject_invalid_patches=True for commit-queue calls, normally we just ignore patches with invalid reviewers, the commit-queue rejects them. + - Make the commit queue print patches count instead of bugs count, this also fixes https://bugs.webkit.org/show_bug.cgi?id=28916. + * Scripts/modules/bugzilla.py: + - Make _parse_attachment_element not validate reviewer/committer. + - Share flag parsing code in _parse_attachment_flag. + - Add _validate* methods for validating reviewers and committers and updating bugs when validation fails. + - Add reject_invalid_patches argument so the commit-queue can update bugs on failed validation and other "read only" commands will not. + - Add reject_patch_from_review_queue using a new _set_flag_on_attachment abstraction. + * Scripts/modules/bugzilla_unittest.py: + - Update this test to no longer expect committer/reviewer validation. + * Scripts/modules/committers.py: + - Return None on failed lookups instead of raising Exceptions. + * Scripts/modules/committers_unittest.py: + - Update tests to expect None returns instead of exceptions. + +2009-09-09 David Kilzer <ddkilzer@apple.com> + + <http://webkit.org/b/29061> Fix obvious copy-paste error in AccessibilityUIElement::clickPointY() + + Reviewed by Mark Rowe. + + No change to layout test results. + + * DumpRenderTree/mac/AccessibilityUIElementMac.mm: + (AccessibilityUIElement::clickPointY): Changed to return y value + instead of x value. + +2009-09-08 Dimitri Glazkov <dglazkov@chromium.org> + + Reviewed by Mark Rowe. + + Reduce dglazkov's boboiness by properly concatenating revision value. + + * BuildSlaveSupport/build.webkit.org-config/master.cfg: Used substitution + rather than "+". + +2009-09-08 Kevin Ollivier <kevino@theolliviers.com> + + wxWebKit Python extension build fix - get swig.py if it doesn't exist. + + * wx/build/build_utils.py: + +2009-09-08 Mark Rowe <mrowe@apple.com> + + Fix an incorrect variable name in UpdateChromiumSource. + + * BuildSlaveSupport/build.webkit.org-config/master.cfg: + +2009-09-08 Mark Rowe <mrowe@apple.com> + + Don't check for leaks on the release SnowLeopard builder. + + * BuildSlaveSupport/build.webkit.org-config/config.json: + +2009-09-08 Mark Rowe <mrowe@apple.com> + + Add a SnowLeopard release builder. + + * BuildSlaveSupport/build.webkit.org-config/config.json: + +2009-09-08 David Levin <levin@chromium.org> + + Reviewed by Darin Adler. + + Remove end of line whitespace check from check-webkit-style. + https://bugs.webkit.org/show_bug.cgi?id=29053 + + * Scripts/modules/cpp_style.py: + +2009-09-08 Cameron McCormack <cam@mcc.id.au> + + Reviewed by Darin Adler. + + Fix DumpRenderTree build from clean tree on Tiger + https://bugs.webkit.org/show_bug.cgi?id=28927 + + * DumpRenderTree/mac/PerlSupport/Makefile: Ensure the + DerivedSources/DumpRenderTree directory exists when + building on Tiger. + +2009-09-08 Kevin Ollivier <kevino@theolliviers.com> + + wx build fix after introduction of platform/mock directory. + + * wx/build/settings.py: + +2009-09-08 Yael Aharon <yael.aharon@nokia.com> + + Unreviewed. + + Add myself to list of committers. + + * Scripts/modules/committers.py: + +2009-09-08 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Unreviewed. + + Add myself to list of committers. + + * Scripts/modules/committers.py: + +2009-09-08 Cameron McCormack <cam@mcc.id.au> + + Reviewed by Darin Adler. + + prepare-ChangeLog too chatty on file additions + https://bugs.webkit.org/show_bug.cgi?id=29019 + + * Scripts/prepare-ChangeLog: Omit description of added properties + on newly added files. + +2009-09-08 Steve Block <steveblock@google.com> + + Reviewed by Adam Barth. + + Adds a LayoutTestController method to set the permission state for Geolocation. + This is required to use the mock Geolocation service for testing. + https://bugs.webkit.org/show_bug.cgi?id=29027 + + * DumpRenderTree/LayoutTestController.cpp: Modified. + (setDatabaseQuotaCallback): Modified. Style fix. + (setGeolocationPermissionCallback): Added. Sets the Geolocation permission state. + (LayoutTestController::staticFunctions): Modified. Registers the above function on the LayoutTestController. + * DumpRenderTree/LayoutTestController.h: Modified. + (LayoutTestController::setGeolocationPermission): Added. Sets the Geolocation permission state. + (LayoutTestController::isGeolocationPermissionSet): Added. Returns whether the Geolocation permission has been set. + (LayoutTestController::geolocationPermission): Added. Returns the Geolocation permission state. + * DumpRenderTree/mac/UIDelegate.mm: Modified. + (-[UIDelegate webView:frame:requestGeolocationPermission:securityOrigin:]): Added. Implement chrome method to respond to request for Geolocation permission state. Response is made using above methods to access permission state. + +2009-09-08 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] QtWebKit single API to enable persistency + https://bugs.webkit.org/show_bug.cgi?id=28682 + + Use the new enablePersistentStorage API instead + of enabling all persistent features one-by-one. + + * DumpRenderTree/qt/DumpRenderTree.cpp: + (WebCore::WebPage::WebPage): + (WebCore::DumpRenderTree::DumpRenderTree): + +2009-09-07 Andras Becsi <becsi.andras@stud.u-szeged.hu> + + Reviewed by Tor Arne Vestbø. + + Refactor --strict switch to --ignore-metrics and correct the + implementation to make the feature usable on all platforms. + https://bugs.webkit.org/show_bug.cgi?id=28907 + + run-webkit-tests --ignore-metrics strips the font related metrics from + the actual and expected data before comparing them. + In this way the render trees can be checked for obvious differences but + a successful test implies by no means that the layout is actually correct. + + * Scripts/run-webkit-tests: + +2009-09-07 Steve Block <steveblock@google.com> + + Reviewed by Adam Barth. + + Adds a mock Geolocation service. This will be used to provide predictable behavior of the + Geolocation API for use in LayoutTests. Later changes will integrate the the mock + Geolocation service with DumpRenderTree. + https://bugs.webkit.org/show_bug.cgi?id=28264 + + * DumpRenderTree/LayoutTestController.cpp: Modified. + (setMockGeolocationPositionCallback): Added. Configures the mock Geolocation service. + (setMockGeolocationErrorCallback): Added. Configures the mock Geolocation service. + (LayoutTestController::staticFunctions): Added. Registers the above functions on the LayoutTestController. + * DumpRenderTree/LayoutTestController.h: Modified. + * DumpRenderTree/mac/LayoutTestControllerMac.mm: Modified. + (LayoutTestController::setMockGeolocationPosition): Added. Configures the mock Geolocation service. + (LayoutTestController::setMockGeolocationError): Added. Configures the mock Geolocation service. + +2009-09-07 Drew Wilson <atwilson@google.com> + + Reviewed by David Levin. + + Enable SHARED_WORKERS by default + https://bugs.webkit.org/show_bug.cgi?id=28959 + + * Scripts/build-webkit: + +2009-09-07 Kevin Ollivier <kevino@theolliviers.com> + + wx build fixes for wx SVN trunk. + + * wx/build/settings.py: + +2009-09-04 Kevin Ollivier <kevino@theolliviers.com> + + wx build fix. Switch USE_ defines over to the compiler so that they can be + checked by files not including config.h (like WebCorePrefix.h). + + * wx/build/settings.py: + +2009-09-04 Adam Barth <abarth@webkit.org> + + Unreviewed build fix. + + Update declaration of FrameLoadDelegate to reflect that + IWebFrameLoadDelegatePrivate2 inherits from + IWebFrameLoadDelegatePrivate. + + * DumpRenderTree/win/FrameLoadDelegate.h: + +2009-09-04 Adam Barth <abarth@webkit.org> + + Reviewed by Eric Seidel. + + https://bugs.webkit.org/show_bug.cgi?id=24696 + + Add testing instrumentation for mixed content. + + * DumpRenderTree/mac/FrameLoadDelegate.mm: + (-[FrameLoadDelegate webView:]): + (-[FrameLoadDelegate webView:didRunInsecureContent:]): + * DumpRenderTree/win/FrameLoadDelegate.cpp: + (descriptionSuitableForTestResult): + (FrameLoadDelegate::QueryInterface): + (FrameLoadDelegate::didDisplayInsecureContent): + (FrameLoadDelegate::didRunInsecureContent): + * DumpRenderTree/win/FrameLoadDelegate.h: + +2009-09-03 Kevin Watters <kevinwatters@gmail.com> + + Reviewed by Kevin Ollivier. + + [wx] Frames support + https://bugs.webkit.org/show_bug.cgi?id=19041 + + * wx/build-wxwebkit: + +2009-09-02 David Kilzer <ddkilzer@apple.com> + + <http://webkit.org/b/28880> svn-apply --force doesn't actually work + + Reviewed by Eric Seidel. + + This fixes "svn-apply --force" and adds unit tests for the + scm.apply_patch() method which uses this script. + + * Scripts/svn-apply: Created $globalExitCode variable that + defaults to 0. Exit with a value of $globalExitCode when the + script is finished. + (applyPatch): Ignore a non-zero $exitCode if $force is true, but + set $globalExitCode to $exitCode so that svn-apply exits with a + non-zero status if any patches did not apply cleanly. Also + print out the actual patch command if $force was not true. + + * Scripts/modules/scm.py: + (scripts_directory): Added. Extracted from script_path(). + (script_path): Extracted scripts_directory(). + * Scripts/modules/scm_unittest.py: Import urllib. + (SVNTestRepository.setup): Save the original working directory + in test_object since this represents the WebKit repository from + where the unit tests are run. + (SCMTest): Created new super class to hold utility methods. + (SCMTest._create_patch): Creates a patch file on disk and a + dictionary for use with scm.svn_apply(). + (SCMTest._setup_webkittools_scripts_symlink): Sets up a symlink + back to WebKitTools/Scripts in the test repository so that + scm.apply_patch() is able to find the svn-apply script. + (SVNTest): Inherit from SCMTest instead of unittest.TestCase. + (SVNTest.tearDown): Make sure to change directories back to the + original_path before the next test. + (SVNTest.test_apply_svn_patch): New test case for applying an + svn patch with scm.apply_patch(). + (SVNTest.test_apply_svn_patch_force): New test case for applying + an svn patch with scm.apply_patch() that conflicts. + (GitTest): Inherit from SCMTest instead of unittest.TestCase. + (GitTest.tearDown): Make sure to change directories back to the + original_path before the next test. + (GitTest.test_apply_git_patch): New test case for applying a git + patch with scm.apply_patch(). + (GitTest.test_apply_git_patch_force): New test case for applying + a git patch with scm.apply_patch() that conflicts. + +2009-09-02 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + Reviewed by Mark Rowe. + + [Qt] Add support for platform-spesific layout-test results + + For the Qt port we use the qt-[mac|linux|win] directories and then fall + back to the generic qt directory for both test results and skipped list. + + * Scripts/run-webkit-tests: + * Scripts/webkitdirs.pm: + +2009-09-02 Laurent Cerveau <lcerveau@me.com> + + Reviewed by David Kilzer. + + <http://webkit.org/b/25517> build-webkit script should print build time at end + + * Scripts/build-webkit: + Added startTime and endTime variable so that the build time is computed and printed as + part of the build message; display formatting has been separated in a dedicated subroutine. + +2009-09-02 David Kilzer <ddkilzer@apple.com> + + <http://webkit.org/b/28881> svn-create-patch should check if the repo path is the same when trying to find the root + + Reviewed by Eric Seidel. + + * Scripts/VCSUtils.pm: + (determineSvnRoot): Added back check for repository root that + was removed in r46134 when this code lived in svn-create-patch. + It's necessary to check both the repository root and the + repository UUID in case two different working directories are + checked out from the same repository. + +2009-09-02 Timothy Hatcher <timothy@apple.com> + + Use new 512x512 icons for nightly builds. + + Rubber-stamped by Mark Rowe. + + * WebKitLauncher/webkit.icns: + +2009-09-02 Kevin Ollivier <kevino@theolliviers.com> + + waf build fix. Remove local variable shadowing global. + + * wx/build/settings.py: + +2009-09-02 Zan Dobersek <zandobersek@gmail.com> + + Reviewed by David Kilzer. + + Calls exitStatus function from the main package where it is also defined. + + * Scripts/VCSUtils.pm: + +2009-09-02 Kevin Ollivier <kevino@theolliviers.com> + + waf build fixes for Windows/MSVC and Mac/Snow Leopard. + + * wx/browser/wscript: + * wx/build/build_utils.py: + * wx/build/settings.py: + +2009-08-10 Kevin Ollivier <kevino@theolliviers.com> + + Reviewed by Eric Seidel. + + Changes needed for build-webkit to support the waf build system for the wx port. + + https://bugs.webkit.org/show_bug.cgi?id=27619 + + * Scripts/build-webkit: + * Scripts/run-launcher: + * Scripts/webkitdirs.pm: + +2009-09-02 David Kilzer <ddkilzer@apple.com> + + <http://webkit.org/b/27168> With Subversion 1.6, update-webkit prompts on conflicts + + Reviewed by Eric Seidel. + + * Scripts/update-webkit: Added "--accept postpone" to + @svnOptions when running with svn-1.6 or newer. + +2009-09-02 David Kilzer <ddkilzer@apple.com> + + Moved svn 1.6 version check into VCSUtils::isSVNVersion16OrNewer() + + Reviewed by Eric Seidel. + + * Scripts/VCSUtils.pm: + (@EXPORT): Added &isSVNVersion16OrNewer. + (svnVersion): Added. Internal method that gets the SVN version + and caches it. + (isSVNVersion16OrNewer): Added. Method that does the SVN 1.6 + version check. + * Scripts/prepare-ChangeLog: Switched to use new + isSVNVersion16OrNewer() method. + * Scripts/resolve-ChangeLogs: Ditto. + * Scripts/svn-create-patch: Ditto. + +2009-09-02 David Kilzer <ddkilzer@apple.com> + + Clean up VCSUtils.pm + + Reviewed by Eric Seidel. + + * Scripts/VCSUtils.pm: Added proper package statement. Fixed + indentation of BEGIN block. Listed each exported method on a + line by itself. Added methods to the export list after adding + the package statement. Sorted module variables. Moved + definiton of $gitRoot next to other module variables. + +2009-09-01 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + Rubber-stamped by Simon Hausmann. + + [Qt] Fix layout-test plugins/plugin-javascript-access.html + + * DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro: + +2009-09-02 Shinichiro Hamaji <hamaji@chromium.org> + + Reviewed by Eric Seidel. + + js tests should move into jstests subdirectory instead of resources/ + https://bugs.webkit.org/show_bug.cgi?id=25880 + + make-script-wrappers supports both resources and script-tests directories. + run-webkit-tests ignores files in script-tests. + Move script tests of animations to check the new script is working. + + * Scripts/make-script-test-wrappers: + * Scripts/run-webkit-tests: + +2009-09-02 Szabo Carol <carol.szabo@nokia.com> + + Reviewed by David Levin. + + check-webkit-style uses python from /usr/bin instead of the PATH + https://bugs.webkit.org/show_bug.cgi?id=28225 + + * Scripts/bugzilla-tool: + * Scripts/check-webkit-style: + * Scripts/run-webkit-unittests: + * Scripts/update-sources-list.py: + Changed the first line from + #!/usr/bin/python + to + #!/usr/bin/env python + which causes python to be invoked from the path location returned + by "which python" when any of these scripts are launched. + these are currently all the python scripts in WebKitTools/Scripts. + +2009-09-01 David Kilzer <ddkilzer@apple.com> + + <http://webkit.org/b/28601> bugzilla-tool post-commits posts commits backwards + + Reviewed by Adam Barth. + + * Scripts/modules/scm.py: + (Git.commit_ids_from_commitish_arguments): Reverse the list of + commits returned from git-rev-list since we always want to post + the oldest patches first to bugs.webkit.org. + * Scripts/modules/scm_unittest.py: + (run): Added return statement to return the output now that we + want it sometimes. + (SVNTestRepository._setup_test_commits): Added a fourth commit + so the GitTest.test_commitish_order() test has more commits to + work with. + (GitTest.test_commitish_order): Added unit test for change to + Git.commit_ids_from_commitish_arguments() in scm.py. + +2009-09-01 David Kilzer <ddkilzer@apple.com> + + <http://webkit.org/b/28877> Implement bugzilla-tool mark-fixed + + Reviewed by David Levin. + + The mark-fixed subcommand is for those times when you don't use + bugzilla-tool to commit a patch, but you want to use it to close + the bug with a committed-revision message. + + * Scripts/bugzilla-tool: + (bug_comment_from_svn_revision): Added. Extracted from + bug_comment_from_commit_text(). + (bug_comment_from_commit_text): Extracted + bug_comment_from_svn_revision() from this method. + (MarkBugFixed.__init__): Added. + (MarkBugFixed._fetch_commit_log): Added. Retrieves the commit + log from the last commit if no svn revision is specified, else + the commit log for the specified svn revision. + (MarkBugFixed._determine_bug_id_and_svn_revision): Added. + Attempts to determine the bug id and svn revision if one or both + were not defined on the command line. + (MarkBugFixed.execute): Added. Adds a comment about the + revision that fixed the bug and closes the bug. + (BugzillaTool.__init__): Added mark-fixed subcommand. + * Scripts/modules/bugzilla.py: + (Bugzilla.fetch_title_from_bug): Added. Returns the title of a + bug given a bug id. + * Scripts/modules/scm.py: + (SCM.strip_r_from_svn_revision): Added. Utility method to strip + the leading 'r' from an svn revision. + (SCM.svn_commit_log): Added. Subclasses must override. + (SCM.last_svn_commit_log): Added. Subclasses must override. + (SVN.svn_commit_log): Added. Returns svn log for a given + revision. + (SVN.last_svn_commit_log): Added. Uses svnversion to find the + last commit in an svn working directory and then runs svn log. + (Git.svn_commit_log): Added. Returns svn log for a given + revision. + (Git.last_svn_commit_log): Added. Runs git-svn-log with a limit + of one log message. + +2009-09-01 David Kilzer <ddkilzer@apple.com> + + <http://webkit.org/b/28880> svn-apply --force doesn't actually work + + Reviewed by Brady Eidson. + + * Scripts/svn-apply: + (applyPatch): Add "--force" to $options arrayref if $force is + set. + +2009-09-01 David Kilzer <ddkilzer@apple.com> + + <http://webkit.org/b/28725> resolve-ChangeLogs: determineVCSRoot() returns incorrect repository root during git filter-branch + + Reviewed by Adam Roben. + + When git-filter-branch has been invoked to rewrite ChangeLog + files on series of git commits, it changes directories into + .git-rewrite/t before re-running resolve-ChangeLogs. This + causes determineVCSRoot() in VCSUtils.pm to return + ".git-rewrite/t", which causes that path to be prepended to all + ChangeLog paths, which results in an error like this: + + error: pathspec '.git-rewrite/t/ChangeLog' did not match any file(s) known to git. + Died at WebKitTools/Scripts/resolve-ChangeLogs line 376. + + The correct way to fix this is not to try to find the repository + root when invoked by git-filter-branch. + + * Scripts/resolve-ChangeLogs: If isInGitFilterBranch() is true, + set $relativePath to '.' instead of calling + chdirReturningRelativePath(determineVCSRoot()). + (isInGitFilterBranch): Added. Checks for the existence of the + MAPPED_PREVIOUS_COMMIT environment variable. + +2009-09-01 Xan Lopez <xlopez@igalia.com> + + Reviewed by Gustavo Noronha. + + Add support for Fedora distros in the http tests + https://bugs.webkit.org/show_bug.cgi?id=28263 + + Add detection code for Fedora distribution, and use the proper + httpd conf file when needed. + + * Scripts/run-webkit-httpd: + * Scripts/run-webkit-tests: + * Scripts/webkitdirs.pm: + +2009-09-01 Jan Michael Alonzo <jmalonzo@webkit.org> + + Reviewed by Eric Seidel. + + [Gtk] DRT needs implementation of overridePreference + https://bugs.webkit.org/show_bug.cgi?id=28830 + + Implement overridePreference. + + * DumpRenderTree/gtk/DumpRenderTree.cpp: + (resetDefaultsToConsistentValues): + (setDefaultsToConsistentStateValuesForTesting): + (runTest): + * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp: + (toWebSettingKey): + (LayoutTestController::overridePreference): + +2009-09-01 Joseph Pecoraro <joepeck@webkit.org> + + <http://webkit.org/b/28623> svn-[un]apply should change directories to the repository root before [un]applying + + Reviewed by Eric Seidel. + + Jump back and forth between the repository root directory (to apply) and the + directory the script was run from (to find the patch). + + * Scripts/svn-apply: + * Scripts/svn-unapply: + +2009-08-31 Adam Roben <aroben@apple.com> + + Fall back to a Release version of Safari if a Debug one doesn't exist + + <http://webkit.org/b/28849> + + Reviewed by Sam Weinig. + + * Scripts/webkitdirs.pm: + (safariPath): If the user is working with a Debug build, but there's + no Debug version of Safari present, fall back to using a Release + version of Safari. + +2009-08-31 Adam Roben <aroben@apple.com> + + Make safariPath() work for Debug builds of Safari on Windows + + <http://webkit.org/b/28849> + + Reviewed by Sam Weinig. + + * Scripts/webkitdirs.pm: + (safariPath): If the user is working with a Debug build, add the + _debug suffix to Safari.exe. + +2009-08-28 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + commit-queue needs a master process + https://bugs.webkit.org/show_bug.cgi?id=28040 + + Add a bugzilla-tool commit-queue command + Keeps per-bug logs, but doesn't yet upload them anywhere. + + * Scripts/bugzilla-tool: Add LandPatchesFromCommitQueue to handle 'commit-queue' + * Scripts/modules/buildbot.py: remove noisy log message + * Scripts/modules/logging.py: add a 'tee()' call for splitting outputs in python + +2009-08-28 Jan Michael Alonzo <jmalonzo@webkit.org> + + Reviewed by Gustavo Noronha. + + [GTK] Geolocation needs permission API before being enabled by default + + Build the Gtk port with geolocation enabled. This option is only + enabled for the buildbot. The autotools option will be enabled by + default once the permissions API is implemented. + + * Scripts/build-webkit: + +2009-08-26 Cameron McCormack <cam@mcc.id.au> + + Reviewed by David Kilzer. + + Make prepare-ChangeLog notice property changes + https://bugs.webkit.org/show_bug.cgi?id=28675 + + Make the generated ChangeLog entry include a short description of + property changes if there were such changes. Also make + prepare-ChangeLog not bail if the only changes are property changes. + + * Scripts/prepare-ChangeLog: + +2009-08-26 Adam Barth <abarth@webkit.org> + + Reviewed by Oliver Hunt. + + Don't let local files access web URLs + https://bugs.webkit.org/show_bug.cgi?id=28480 + + A bunch of our LayoutTests rely on our old behavior, so we explicitly + grant local files universal access during testing. Mainly, these tests + involve making XMLHttpRequests for data URLs. + + * DumpRenderTree/mac/DumpRenderTree.mm: + (resetDefaultsToConsistentValues): + * DumpRenderTree/qt/DumpRenderTree.cpp: + (WebCore::WebPage::WebPage): + * DumpRenderTree/win/DumpRenderTree.cpp: + (resetDefaultsToConsistentValues): + +2009-08-26 John Gregg <johnnyg@google.com> + + Reviewed by David Levin. + + Minor style correction and include fix for notifications + https://bugs.webkit.org/show_bug.cgi?id=28745 + + * DumpRenderTree/win/DRTDesktopNotificationPresenter.cpp: + change to correct EnumStyle + (DRTDesktopNotificationPresenter::checkNotificationPermission): + +2009-08-26 David Levin <levin@chromium.org> + + Reviewed by Alexey Proskuryakov. + + XMLHttpRequest.withCredentials=false shouldn't save cookies. + https://bugs.webkit.org/show_bug.cgi?id=28743 + + Added the support to the layout test controller on OSX and + Windows (for CFNETWORK) to allow for changing the accept cookie + policy. + + * DumpRenderTree/LayoutTestController.cpp: + (LayoutTestController::LayoutTestController): Added a bool + to track the state of accepting cookies. + (setAlwaysAcceptCookiesCallback): Standard wrapper method + to go from js to a C++ method. + (LayoutTestController::staticFunctions): Added the + setAlwaysAcceptCookies method to the js layoutTestController. + * DumpRenderTree/LayoutTestController.h: + (LayoutTestController::alwaysAcceptCookies): Returns the value. + * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp: + (LayoutTestController::setAlwaysAcceptCookies): Stub out method. + * DumpRenderTree/mac/DumpRenderTree.mm: + (resetDefaultsToConsistentValues): Reset the accept cookie to + its default. + * DumpRenderTree/mac/LayoutTestControllerMac.mm: + (LayoutTestController::setAlwaysAcceptCookies): Does the work for + OSX to change the cookie accept policy. + * DumpRenderTree/win/DumpRenderTree.cpp: + (setAlwaysAcceptCookies): Method to handle all the calls necessary + to change the accept cookie policy on Windows. + (resetDefaultsToConsistentValues): Reset the accept cookie to + its default. + * DumpRenderTree/win/DumpRenderTreeWin.h: + * DumpRenderTree/win/LayoutTestControllerWin.cpp: + (LayoutTestController::setAlwaysAcceptCookies): Stub out method. + * DumpRenderTree/wx/LayoutTestControllerWx.cpp: + (LayoutTestController::setAlwaysAcceptCookies): Stub out method. + +2009-08-26 Dimitri Glazkov <dglazkov@chromium.org> + + Unreviewed. + + Remove accidentally left in clobber option. + https://bugs.webkit.org/show_bug.cgi?id=28400 + + * BuildSlaveSupport/build.webkit.org-config/master.cfg: Removed clobber option. + +2009-08-26 Dimitri Glazkov <dglazkov@chromium.org> + + Reviewed by Mark Rowe. + + Add canary-style Chromium WebKit build slave to the waterfall. + https://bugs.webkit.org/show_bug.cgi?id=28400 + + * BuildSlaveSupport/build.webkit.org-config/config.json: Added one Chromium/Windows slave + * BuildSlaveSupport/build.webkit.org-config/master.cfg: Added support for Chromium slave commands. + +2009-08-25 Cameron McCormack <cam@mcc.id.au> + + Reviewed by Darin Adler. + + make-script-test-wrappers should be executable + https://bugs.webkit.org/show_bug.cgi?id=28669 + + Make make-script-test-wrappers and update-sources-list.py both be + executable. + + * Scripts/update-sources-list.py: + * Scripts/make-script-test-wrappers: + +2009-08-25 Brent Fulgham <bfulgham@webkit.org> + + Build fix + + Revise Debug_Cairo targets to point inherit from the + debug_wincairo.vsprops property sheet so that they link + against the proper libraries in Debug build. + + * DumpRenderTree/win/DumpRenderTree.vcproj: + * DumpRenderTree/win/TestNetscapePlugin/TestNetscapePlugin.vcproj: + * WinLauncher/WinLauncher.vcproj: + +2009-08-25 David Levin <levin@chromium.org> + + Reviewed by Adam Roben. + + PLATFORM(CFNETWORK) should be USE(CFNETWORK). + https://bugs.webkit.org/show_bug.cgi?id=28713 + + * DumpRenderTree/win/DumpRenderTree.cpp: + (main): + +2009-08-25 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + Reviewed by Ariya Hidayat. + + [Qt/Mac] Use CONFIG+=build_all only when building libraries + + If no configuration is specified when building WebKit we pass the + debug_and_release option to QMake which results in Makefiles for + both configurations being generated. + + Previously we built both of these configurations by default, for + all targets (both the QtWebKit framework/dyldlib and the various + executables such as QtLauncher and tests). This makes sense for + the libraries, which get the _debug suffix and can be loaded on + demand by setting the DYLD_IMAGE_SUFFIX, but for executables we + ended up building the same executable twice. + + We now only build one instance of each executable, and since this + is a developer build we build the debug-version. Passing either + --debug or --release to build-webkit will override this, and + even in the default case the release version can still be built + by running 'make release' in the the build directory of each + target. + + * DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro: + * Scripts/webkitdirs.pm: + +2009-08-24 Hironori Bono <hbono@chromium.org> + + Reviewed by Adam Barth. + + Fix Bug 27827 "[Chromium] Functions Keys don't work in google spreadsheet". + <https://bugs.webkit.org/show_bug.cgi?id=27827>. + + Because of the lack of mappings from GDK key-codes to WebKit key-codes, + Chromium cannot send valid key-codes to JavaScript when a user types + function keys. This change just copies the mappings from 'KeyEventGtk.cpp'. + + To write layout tests for this issue, added mappings from function-key + names to platform-specific key-codes to EventSendingController objects + so that eventSender.keyDown() can send function-key events without using + platform-specific key codes. (Unfortunately, this eventSender.keyDown() change + is only for Mac. So this change adds this new test to Skipped tests for other + platforms to prevent this change from crashing the build trees.) + + * DumpRenderTree/mac/EventSendingController.mm: + (-[EventSendingController keyDown:withModifiers:]): + +2009-08-23 Jan Michael Alonzo <jmalonzo@webkit.org> + + Reviewed by Xan Lopez. + + [Gtk] API for disabling local file access to web URLs + https://bugs.webkit.org/show_bug.cgi?id=28663 + + Enable this setting for DRT. + + * DumpRenderTree/gtk/DumpRenderTree.cpp: + (resetWebViewToConsistentStateBeforeTesting): + +2009-08-22 Adam Barth <abarth@webkit.org> + + Revert 47684. We're going to do this later once clients have had a + chance to opt into the setting they like. + + * DumpRenderTree/mac/DumpRenderTree.mm: + (resetDefaultsToConsistentValues): + * DumpRenderTree/qt/DumpRenderTree.cpp: + (WebCore::WebPage::WebPage): + * DumpRenderTree/win/DumpRenderTree.cpp: + (resetDefaultsToConsistentValues): + +2009-08-22 Adam Barth <abarth@webkit.org> + + Reviewed by Eric Seidel. + + Don't let local files access web URLs + https://bugs.webkit.org/show_bug.cgi?id=28480 + + A bunch of our LayoutTests rely on our old behavior, so we explicitly + grant local files universal access during testing. Mainly, these tests + involve making XMLHttpRequests for data URLs. + + * DumpRenderTree/mac/DumpRenderTree.mm: + (resetDefaultsToConsistentValues): + * DumpRenderTree/qt/DumpRenderTree.cpp: + (WebCore::WebPage::WebPage): + * DumpRenderTree/win/DumpRenderTree.cpp: + (resetDefaultsToConsistentValues): + +2009-08-22 Mark Rowe <mrowe@apple.com> + + Rubber-stamped by Anders Carlsson. + + Bring signed updates to the Mac nightly builds. + + * WebKitLauncher/Info.plist: + * WebKitLauncher/WebKitLauncher.xcodeproj/project.pbxproj: + * WebKitLauncher/WebKitNightlyEnablerSparkle.m: + (initializeSparkle): + * WebKitLauncher/nightly.webkit.org.public.pem: Added. + +2009-08-21 Jan Michael Alonzo <jmalonzo@webkit.org> + + Rubberstamped by Simon Fraser. + + Remove GNOME keyring support in build-webkit. This dependency's + already been removed in the Gtk port. + + * Scripts/build-webkit: + +2009-08-20 Brian Weinstein <bweinstein@apple.com> + + Reviewed by Adam Roben. + Based on original patch by Stephanie Lewis. + + Added support of the Windows malloc history format to parse-malloc history, so we can + read and parse it. + + * Scripts/parse-malloc-history: + +2009-08-20 Chris Fleizach <cfleizach@apple.com> + + Reviewed by Darin Adler. + + Enable various "grouping" ARIA roles + https://bugs.webkit.org/show_bug.cgi?id=28486 + + Expose the ability to retrieve the subrole through accessibility for DRT. + + * DumpRenderTree/AccessibilityUIElement.cpp: + * DumpRenderTree/AccessibilityUIElement.h: + * DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp: + * DumpRenderTree/mac/AccessibilityUIElementMac.mm: + * DumpRenderTree/win/AccessibilityUIElementWin.cpp: + +2009-08-20 Joseph Pecoraro <joepeck@webkit.org> + + Unreviewed. + + Added myself as a committer. + + * Scripts/modules/committers.py: + +2009-08-20 Xan Lopez <xlopez@igalia.com> + + Reviewed by Gustavo Noronha. + + Fix memory leaks. + + * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp: + (LayoutTestController::whiteListAccessFromOrigin): + (LayoutTestController::pauseAnimationAtTimeOnElementWithId): + (LayoutTestController::pauseTransitionAtTimeOnElementWithId): + +2009-08-20 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + bugzilla-tool post-diff can post partial diffs from SVN checkouts. + https://bugs.webkit.org/show_bug.cgi?id=28445 + + Pass the checkout root as the cwd. Also wrote a test to ensure this. + + * Scripts/modules/scm.py: + * Scripts/modules/scm_unittest.py: + +2009-08-20 Mark Rowe <mrowe@apple.com> + + Reviewed by Adele Peterson. + + Don't leak the JSStringRef returned by AccessibilityUIElement::attributeValue. + + * DumpRenderTree/AccessibilityUIElement.cpp: + (attributeValueCallback): + +2009-08-20 Ariya Hidayat <ariya.hidayat@nokia.com> + + Unreviewed, build fix. + + [Qt] The template-based qMax() compares two qreals. + + * DumpRenderTree/qt/ImageDiff.cpp: + (main): + +2009-08-20 David Levin <levin@chromium.org> + + Reviewed by David Kilzer. + + bugzilla-tool patch retrieval should handle 302 redirects. + https://bugs.webkit.org/show_bug.cgi?id=28485 + + * Scripts/modules/scm.py: Pass the --location parameter to curl + so that 302's are followed. + +2009-08-20 Aaron Boodman <aa@chromium.org> + + One more speculative build for gtk. + + * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp: + +2009-08-20 Aaron Boodman <aa@chromium.org> + + Speculative build for gtk. + + * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp: + (LayoutTestController::whiteListAccessFromOrigin): + +2009-08-20 Mark Rowe <mrowe@apple.com> + + Ignore some leaks that are known to originate from ImageIO. + + * Scripts/run-webkit-tests: + +2009-08-20 Aaron Boodman <aa@chromium.org> + + With David Levin. + + Speculative build fix for qt. + + * DumpRenderTree/qt/jsobjects.cpp: + (LayoutTestController::whiteListAccessFromOrigin): + * DumpRenderTree/qt/jsobjects.h: + +2009-08-19 Mark Rowe <mrowe@apple.com> + + Reviewed by Dan Bernstein. + + Fix <http://webkit.org/b/28484> Plug-in-related leaks seen on the build bot + + Update check-for-global-initializers to accommodate the new uses of RefCountedLeakCounter in WebKit. + + * Scripts/check-for-global-initializers: + +2009-08-19 Aaron Boodman <aa@chromium.org> + + Reviewed by David Levin. + + https://bugs.webkit.org/show_bug.cgi?id=24853: Provide a way for WebKit clients to + specify a more granular policy for cross-origin XHR access. + + * DumpRenderTree/LayoutTestController.cpp: Expose whiteListAccessFromOrigin() to layout tests. + (whiteListAccessFromOriginCallback): Ditto. + (LayoutTestController::staticFunctions): Ditto. + * DumpRenderTree/LayoutTestController.h: Ditto. + * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp: Ditto. + (LayoutTestController::whiteListAccessToOrigin): Ditto. + * DumpRenderTree/mac/LayoutTestControllerMac.mm: Ditto. + (LayoutTestController::whiteListAccessFromOrigin): Ditto. + * DumpRenderTree/qt/jsobjects.cpp: Ditto. + (LayoutTestController::whiteListAccessFromOrigin): Ditto. + * DumpRenderTree/win/LayoutTestControllerWin.cpp: Stub out whiteListAccessFromOrigin(). + (LayoutTestController::whiteListAccessFromOrigin): Ditto. + * DumpRenderTree/gtk/DumpRenderTree.cpp: Reset origin access lists before each test. + (resetWebViewToConsistentStateBeforeTesting): Ditto. + * DumpRenderTree/mac/DumpRenderTree.mm: Ditto. + (resetWebViewToConsistentStateBeforeTesting): Ditto. + * DumpRenderTree/qt/DumpRenderTree.cpp: Ditto. + (WebCore::DumpRenderTree::resetToConsistentStateBeforeTesting): Ditto. + +2009-08-19 Mark Rowe <mrowe@apple.com> + + Rubber-stamped by Dan Bernstein. + + Ignore some leaks that are known to originate from QTKit. + + * Scripts/run-webkit-tests: + +2009-08-19 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + commit-queue/bugzilla-tool can get wedged if git is mid-rebase + https://bugs.webkit.org/show_bug.cgi?id=28436 + + Make clean_working_directory cancel rebases too (even though that's a bit of a hack). + This code will only ever be run when --force-clean is passed. + + I also added a new unit test to make sure this code actually works. :) + + * Scripts/modules/scm.py: + * Scripts/modules/scm_unittest.py: + +2009-08-19 Eric Seidel <eric@webkit.org> + + Reviewed by David Levin. + + WebKit needs a changelogs.py to hold changelog-related code + https://bugs.webkit.org/show_bug.cgi?id=28477 + + This is moving code and adding tests. There was only one functional + change (which was removing a trailing newline from the last_entry() result). + + * Scripts/bugzilla-tool: + * Scripts/modules/changelogs.py: Added. + * Scripts/modules/changelogs_unittest.py: Added. + * Scripts/run-webkit-unittests: + +2009-08-20 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + bugzilla-tool needs a way to ask build.webkit.org if the bots are passing + https://bugs.webkit.org/show_bug.cgi?id=28222 + + Basic support for now. This has been in testing for 24 hours now and worked great! + + * Scripts/bugzilla-tool: + * Scripts/modules/buildbot.py: Added. + * Scripts/modules/buildbot_unittest.py: Added. + * Scripts/run-webkit-unittests: + +2009-08-19 Jan Michael Alonzo <jmalonzo@webkit.org> + + Reviewed by Gustavo Noronha. + + [Gtk] Bump waitToDumpWatchdog interval to 15 seconds to match the + default timeout used by run-webkit-tests. Mac and Win ports were + recently bumped in http://trac.webkit.org/changeset/r47465. + + * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp: + (LayoutTestController::setWaitToDump): + +2009-08-19 David D. Kilzer <ddkilzer@webkit.org> + + DumpRenderTreeSupport.pm: provide pre-generated swig source for Tiger + + Reviewed by Mark Rowe. + + Provide pre-generated swig source files for Tiger so it may + benefit from the faster run-webkit-tests. + + * DumpRenderTree/mac/PerlSupport/DumpRenderTreeSupportTiger.pm: + Generated by swig. + * DumpRenderTree/mac/PerlSupport/DumpRenderTreeSupport_wrapTiger.c: Added. + Generated by swig. + (swig_type_info::SWIG_TypeNameComp): + (swig_type_info::SWIG_TypeEquiv): + (swig_type_info::SWIG_TypeRegisterTL): + (swig_type_info::SWIG_TypeCheck): + (swig_type_info::SWIG_TypeCast): + (swig_type_info::SWIG_TypeDynamicCast): + (swig_type_info::SWIG_TypeName): + (swig_type_info::SWIG_TypePrettyName): + (swig_type_info::SWIG_TypeQueryTL): + (swig_type_info::SWIG_TypeClientDataTL): + (swig_type_info::SWIG_PackData): + (swig_type_info::SWIG_UnpackData): + (swig_type_info::SWIG_PropagateClientDataTL): + (swig_type_info::SWIG_PackVoidPtr): + (swig_type_info::SWIG_UnpackVoidPtr): + (swig_type_info::SWIG_PackDataName): + (swig_type_info::SWIG_UnpackDataName): + * DumpRenderTree/mac/PerlSupport/Makefile: Updated to build on + Tiger using pre-generated files. + +2009-08-18 Shinichiro Hamaji <hamaji@chromium.org> + + Reviewed by David Kilzer. + + run-webkit-tests hangs when WebCore tries to log too much + https://bugs.webkit.org/show_bug.cgi?id=15743 + + Read stdout and stderr in parallel. + + * Scripts/run-webkit-tests: + +2009-08-18 Mark Rowe <mrowe@apple.com> + + Rubber-stamped by Oliver Hunt. + + Add a new build configuration that checks for leaks during the layout tests, + and hook a new machine up to it. + + * BuildSlaveSupport/build.webkit.org-config/config.json: + * BuildSlaveSupport/build.webkit.org-config/master.cfg: + +2009-08-18 Aaron Boodman <aa@chromium.org> + + Reviewed by Maciej Stachowiak. + + https://bugs.webkit.org/show_bug.cgi?id=28412: Leak of WebCore::XMLHttpRequest object during layout tests. + + No new tests: Already covered by existing tests. + + * Scripts/check-for-global-initializers: Allow global initialization of WTF::RefCountedLeakCounter for XMLHttpRequest. + +2009-08-18 Mark Rowe <mrowe@apple.com> + + Rubber-stamped by Geoff Garen. + + Bump waitToDumpWatchdogInterval to 15 seconds to match the time-out used by run-webkit-tests. + + * DumpRenderTree/mac/LayoutTestControllerMac.mm: + * DumpRenderTree/win/LayoutTestControllerWin.cpp: + +2009-08-18 Brian Weinstein <bweinstein@apple.com> + + Rubber-stamped by Adam Roben. + + Changed use of CComBSTR in exceededDatabaseQuota to BSTRs, and free them, + and removed include to fix building on VC++ Express. + + * DumpRenderTree/win/UIDelegate.cpp: + (UIDelegate::exceededDatabaseQuota): + +2009-08-18 Brian Weinstein <bweinstein@apple.com> + + Reviewed by Oliver Hunt. + + Fix of <https://bugs.webkit.org/show_bug.cgi?id=28326> DRT on Windows doesn't support + LayoutTestController::setQuota or print a callback on UIDelegate::exceededDatabaseQuota. + + Implemenent setDatabaseQuota and added a new function to the IWebDatabaseManager interface. + Also added a console output on UIDelegate::exceededDatabaseQuota to match the mac. + + * DumpRenderTree/win/LayoutTestControllerWin.cpp: + (LayoutTestController::setDatabaseQuota): + * DumpRenderTree/win/UIDelegate.cpp: + (UIDelegate::exceededDatabaseQuota): + +2009-08-18 Peter Kasting <pkasting@google.com> + + Reviewed by Eric Seidel. + + https://bugs.webkit.org/show_bug.cgi?id=28415 + Set svn:eol-style CRLF on all .sln and .vcproj files that don't already + have it. + + * record-memory-win/record-memory-win.vcproj: + * WinLauncher/WinLauncher.vcproj: + * WebKitLauncherWin/WebKitLauncherWin.vcproj: + * DumpRenderTree/win/ImageDiff.vcproj: + * FindSafari/FindSafari.vcproj: + +2009-08-18 Drew Wilson <atwilson@google.com> + + Reviewed by Eric Seidel. + + Need to extend DumpRenderTree to expose number of worker threads + https://bugs.webkit.org/show_bug.cgi?id=28292 + + Added layoutTestController.workerThreadCount, and implementations on various platforms that call into WebKit. + + * DumpRenderTree/LayoutTestController.cpp: + (getWorkerThreadCountCallback): + (LayoutTestController::staticValues): + * DumpRenderTree/LayoutTestController.h: + * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp: + (LayoutTestController::workerThreadCount): + * DumpRenderTree/mac/LayoutTestControllerMac.mm: + (LayoutTestController::workerThreadCount): + * DumpRenderTree/win/LayoutTestControllerWin.cpp: + (LayoutTestController::workerThreadCount): + * DumpRenderTree/wx/LayoutTestControllerWx.cpp: + (LayoutTestController::workerThreadCount): + +2009-08-18 Xan Lopez <xlopez@igalia.com> + + Reviewed by Jan Alonzo. + + Initialize x and y in the GtkAllocation structure to shut up + valgrind. + + * DumpRenderTree/gtk/DumpRenderTree.cpp: + (runTest): + +2009-08-17 Shinichiro Hamaji <hamaji@chromium.org> + + Reviewed by Darin Adler. + + Some HTMLs are modified by make-script-test-wrappers + https://bugs.webkit.org/show_bug.cgi?id=28213 + + Add fast/js/const.js and fast/canvas/canvas-2d-imageData-create-nonfinite.js into + the exclude list, modified fast/dom/Geolocation/resources/TEMPLATE.html, and + re-generated wml/* and Geolocation/* . + + * Scripts/make-script-test-wrappers: + +2009-08-17 Shinichiro Hamaji <hamaji@chromium.org> + + Reviewed by Eric Seidel. + + -webkit-box-orient:horizontal doesn't work on <button> tag + https://bugs.webkit.org/show_bug.cgi?id=34445 + + Make a flexible button's anonymous child flexible and pass the + parent's box-orient to the anonymous child. + + Also, added a renderName for anonymous flexible boxes. + + * Scripts/make-script-test-wrappers: + +2009-08-17 Eric Seidel <eric@webkit.org> + + Reviewed by Darin Adler. + + Can no longer --reset-results of a layout test directory + https://bugs.webkit.org/show_bug.cgi?id=28336 + + --reset-results and --exit-after-n-failures are incompatible. + + * Scripts/run-webkit-tests: + +2009-08-17 David Kilzer <ddkilzer@apple.com> + + <http://webkit.org/b/26920> bugzilla-tool dumps too much junk the the commit comment from git + + Reviewed by Adam Roben. + + New commit message: + Committed r12345: <http://trac.webkit.org/changeset/12345> + + * Scripts/bugzilla-tool: + (bug_comment_from_commit_text): Print out a compact, + standardized commit message for both git and svn. + +2009-08-17 Peter Kasting <pkasting@google.com> + + Reviewed by Steve Falkenburg. + + https://bugs.webkit.org/show_bug.cgi?id=27323 + Only add Cygwin to the path when it isn't already there. This avoids + causing problems for people who purposefully have non-Cygwin versions of + executables like svn in front of the Cygwin ones in their paths. + + * DumpRenderTree/win/DumpRenderTree.vcproj: + * DumpRenderTree/win/ImageDiff.vcproj: + * DumpRenderTree/win/TestNetscapePlugin/TestNetscapePlugin.vcproj: + +2009-08-17 David Kilzer <ddkilzer@apple.com> + + <http://webkit.org/b/28393> check-webkit-style: add check for use of std::max()/std::min() instead of MAX()/MIN() + + Reviewed by David Levin. + + * Scripts/modules/cpp_style.py: + (_ERROR_CATEGORIES): Added 'runtime/max_min_macros'. + (check_max_min_macros): Added. Returns level 4 error when MAX() + and MIN() macros are used in header files and C++ source files. + (check_style): Added call to check_max_min_macros(). + * Scripts/modules/cpp_style_unittest.py: Added unit tests. + (test_max_macro): Added. + (test_min_macro): Added. + +2009-08-13 Mike Fenton <mike.fenton@torchmobile.com> + + Reviewed by Eric Seidel. + + Move adjustLineToPixelBoundaries overlapping function to GraphicsContext.cpp + and remove from GraphicsContextCairo.cpp and GraphicsContextQt.cpp. + + https://bugs.webkit.org/show_bug.cgi?id=28268 + + * platform/graphics/GraphicsContext.cpp: + (WebCore::GraphicsContext::adjustLineToPixelBoundaries): + * platform/graphics/GraphicsContext.h: + * platform/graphics/cairo/GraphicsContextCairo.cpp: + * platform/graphics/qt/GraphicsContextQt.cpp: + +2009-08-10 Mike Fenton <mike.fenton@torchmobile.com> + + Reviewed by Adam Treat. + + Style fixes for DumpRenderTree/qt/jsobjects.cpp based on cpp_style.py and + WebKit style guide. + + https://bugs.webkit.org/show_bug.cgi?id=28161 + + * DumpRenderTree/qt/jsobjects.cpp: + (findFrameNamed): + (LoadItem::invoke): + (LayoutTestController::provisionalLoad): + (LayoutTestController::timerEvent): + (LayoutTestController::pauseAnimationAtTimeOnElementWithId): + (LayoutTestController::pauseTransitionAtTimeOnElementWithId): + (LayoutTestController::numberOfActiveAnimations): + (EventSender::keyDown): + (EventSender::frameUnderMouse): + (TextInputController::doCommand): + +2009-08-16 David Kilzer <ddkilzer@apple.com> + + <http://webkit.org/b/28370> check-webkit-style: add check for 'using std::foo;' statements + + Reviewed by David Levin. + + In <http://webkit.org/b/28355#c1>, it was noted that new source + files use 'using namespace std;' instead of individual + 'using std::foo;' statements. This adds a level 4 check for + such statements. + + * Scripts/modules/cpp_style.py: + (_ERROR_CATEGORIES): Added 'build/using_std'. + (check_using_std): Added. + (check_style): Added call to check_using_std(). + * Scripts/modules/cpp_style_unittest.py: + (WebKitStyleTest.test_using_std): Added unit test. + +2009-08-16 David Kilzer <ddkilzer@apple.com> + + Backed out r47343 which was mistakenly committed + + * Scripts/bugzilla-tool: + * Scripts/modules/scm.py: + +2009-08-16 David Kilzer <ddkilzer@apple.com> + + <http://webkit.org/b/28367> bugzilla.py: replace ScriptError class with BugzillaError class + + Reviewed by David Levin. + + The ScriptError class doesn't exist in bugzilla.py, so any + errors print error messages about ScriptError instead of the + actual error: + + NameError: global name 'ScriptError' is not defined + + * Scripts/modules/bugzilla.py: + (BugzillaError): Added class. Modeled after ScriptError class + in scm.py. + (Bugzilla.authenticate): Changed to use BugzillaError instead of + ScriptError. + (Bugzilla._check_create_bug_response): Ditto. + +2009-08-14 Adam Bergkvist <adam.bergkvist@ericsson.com> + + Reviewed by Sam Weinig. + + Added EventSource to the build script (default on). + https://bugs.webkit.org/show_bug.cgi?id=14997 + + * Scripts/build-webkit: + +2009-08-15 Ryosuke Niwa <rniwa@webkit.org> + + Unreviewed. + + Add myself to list of committers. + + * Scripts/modules/committers.py: + +2009-08-15 Jon Honeycutt <jhoneycutt@apple.com> + + Fix layout test failures after r47312. + + Reviewed by Cameron Zwarich. + + * DumpRenderTree/AccessibilityController.h: + Replaced logFocusEvents() with setLogFocusEvents(), which takes a + boolean argument to turn logging of focus events on or off. + Added a function to reset the AccessibilityController to a consistent + state. + + * DumpRenderTree/AccessibilityController.cpp: + (logFocusEventsCallback): + Call setLogFocusEvents() to enable logging. + (AccessibilityController::resetToConsistentState): + Call setLogFocusEvents() to disable logging. + + * DumpRenderTree/gtk/AccessibilityControllerGtk.cpp: + (AccessibilityController::setLogFocusEvents): + Update stub. + + * DumpRenderTree/mac/AccessibilityControllerMac.mm: + (AccessibilityController::setLogFocusEvents): + Update stub. + + * DumpRenderTree/mac/DumpRenderTree.mm: + (resetWebViewToConsistentStateBeforeTesting): + Call the FrameLoadDelegate's resetToConsistentState method. + + * DumpRenderTree/mac/FrameLoadDelegate.h: + Declare the resetToConsistentState method. + + * DumpRenderTree/mac/FrameLoadDelegate.mm: + (-[FrameLoadDelegate resetToConsistentState]): + Call the AccessibilityController's resetToConsistentState() function. + + * DumpRenderTree/win/AccessibilityControllerWin.cpp: + (AccessibilityController::~AccessibilityController): + Turn off focus event logging when the controller is destroyed. + (AccessibilityController::setLogFocusEvents): + If the caller passes false, unhook the focus event, and clear + m_focusEventHook. + + * DumpRenderTree/win/DumpRenderTree.cpp: + (resetWebViewToConsistentStateBeforeTesting): + Call the FrameLoadDelegate's resetToConsistentState function. + + * DumpRenderTree/win/FrameLoadDelegate.h: + Declare the resetToConsistentState() function. + + * DumpRenderTree/win/FrameLoadDelegate.cpp: + (FrameLoadDelegate::resetToConsistentState): + Call the AccessibilityController's resetToConsistentState() function. + + +2009-08-14 Jon Honeycutt <jhoneycutt@apple.com> + + Add a mechanism for logging MSAA focus events. + + Part of <rdar://problem/6218721> No MSAA focus events fired for Webkit + nightly (20866) + + https://bugs.webkit.org/show_bug.cgi?id=20866 + + Reviewed by Oliver Hunt. + + * DumpRenderTree/AccessibilityController.cpp: + (logFocusEventsCallback): + Call the AccessibilityController's logFocusEvents() function. + (AccessibilityController::getJSClass): + Add a "logFocusEvents" function to the AccessibilityController's JS + class definition. + + * DumpRenderTree/AccessibilityController.h: + On Windows, include windows.h, and add a member variable to hold the + handle to the event hook for focus events. Add a declaration for a + function that enables logging of focus events. + + * DumpRenderTree/gtk/AccessibilityControllerGtk.cpp: + (AccessibilityController::logFocusEvents): + Stubbed. + + * DumpRenderTree/mac/AccessibilityControllerMac.mm: + (AccessibilityController::logFocusEvents): + Stubbed. + + * DumpRenderTree/win/AccessibilityControllerWin.cpp: + (AccessibilityController::AccessibilityController): + (AccessibilityController::~AccessibilityController): + If we hooked the focus event, unhook it. + (logFocusEventProc): + When we receive a focus event, get the accessible object for the event, + and log its name to stdout. + (AccessibilityController::logFocusEvents): + Setup the focus event hook to listen for events in the current process. + +2009-08-14 Eric Seidel <eric@webkit.org> + + No review. Fix 5-space indent to be 4-spaces. + + * Scripts/bugzilla-tool: + +2009-08-14 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Public API to configure the storage path for HTML5 localStorage + https://bugs.webkit.org/show_bug.cgi?id=28036 + + Turn on LocalStorage support for Qt DumpRenderTree since + LocalStorage is now disabled by defult for QtWebkit. + + * DumpRenderTree/qt/DumpRenderTree.cpp: + (WebCore::WebPage::WebPage): + +2009-08-14 Xan Lopez <xlopez@igalia.com> + + Reviewed by Jan Alonzo. + + Do not unref the main webview, it's owned by its parent + container. Instead destroy the container, which should take care + of everything (not terribly important since we exit right after + that, but still). + + * DumpRenderTree/gtk/DumpRenderTree.cpp: + (main): + +2009-08-13 Eric Seidel <eric@webkit.org> + + No review, correcting obvious python error seen in the commit queue. + + args can be a string or an array. Assuming args is always an array results in + double-spaced text in error logs. + + * Scripts/bugzilla-tool: + +2009-08-13 Gustavo Noronha Silva <gustavo.noronha@collabora.co.uk> + + Unreviewed build fix. Include stdio.h for using stdout, stderr, + and fprintf. + + * DumpRenderTree/LayoutTestController.cpp: + +2009-08-13 Shinichiro Hamaji <hamaji@chromium.org> + + Reviewed by Eric Seidel. + + rename make-js-test-wrappers to make-script-test-wrappers + https://bugs.webkit.org/show_bug.cgi?id=28212 + + * Scripts/make-script-test-wrappers: Renamed from WebKitTools/Scripts/make-js-test-wrappers. + +2009-08-13 Drew Wilson <atwilson@chromium.org> + + Unreviewed. + + Add myself to list of committers. + + * Scripts/modules/committers.py: + +2009-08-13 John Sullivan <sullivan@apple.com> + + Unreviewed. + + Add myself to list of committers. + + * Scripts/modules/committers.py: + +2009-08-13 Eric Seidel <eric@webkit.org> + + Correct spelling error in file name. No review. + + * Scripts/modules/committers_unittest.py: Renamed from WebKitTools/Scripts/modules/commiters_unittest.py. + * Scripts/run-webkit-unittests: + +2009-08-13 Eric Seidel <eric@webkit.org> + + Reviewed by Simon Fraser. + + REGRESSION(r47175): error running run-webkit-tests + https://bugs.webkit.org/show_bug.cgi?id=28261 + + Fix "Use of uninitialized value in concatenation (.) or string at + WebKitTools/Scripts/run-webkit-tests line 191." by setting + $testsPerDumpTool to 1000 by default. + + * Scripts/run-webkit-tests: + +2009-08-13 Nate Chapin <japhet@chromium.org> + + Unreviewed. + + Add myself to list of committers. + + * Scripts/modules/committers.py: + +2009-08-13 Brent Fulgham <bfulgham@webkit.org> + + Unreviewed. + + Add 'Brent Fulgham' to the committers list. + + * Scripts/modules/committers.py: + +2009-08-13 Adam Langley <agl@chromium.org> + + Review not required. + + * Scripts/modules/committers.py: + Adding myself to this list because Eric told me to. + +2009-08-13 Greg Bolsinga <bolsinga@apple.com> + + Unreviewed. + + Add 'Greg Bolsinga' to the committers list. + + * Scripts/modules/committers.py: + +2009-08-13 Adam Roben <aroben@apple.com> + + Fix off-by-one result comparisons in media tests on Windows Debug + builds + + media/video-played.html seems always to time out in Windows Debug + builds. A race condition between media/video-test.js's "hang" timer and + DumpRenderTree's built-in "watchdog" timer was causing results for + media/video-played.html to be printed twice, causing all future media + tests to be compared to the previous test's results. + + The fix is to make the watchdog timer got through the same code path + as calling notifyDone manually, so that the results will only get + printed once. A subsequent patch will remove video-test.js's hang + timer entirely, since it is redundant. + + Fixes <http://webkit.org/b/28265>. + + Reviewed by Mark Rowe. + + * DumpRenderTree/LayoutTestController.cpp: + (LayoutTestController::waitToDumpWatchdogTimerFired): Added. Code came + from Gtk/Mac/Win's watchdog timer handlers, but we now call + notifyDone() instead of dump() so that a subsequent call to + notifyDone() won't print the results out again. + + * DumpRenderTree/LayoutTestController.h: Added + waitToDumpWatchdogTimerFired. + + * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp: + (waitToDumpWatchdogFired): + * DumpRenderTree/mac/LayoutTestControllerMac.mm: + (waitUntilDoneWatchdogFired): + * DumpRenderTree/win/LayoutTestControllerWin.cpp: + (waitUntilDoneWatchdogFired): + Changed to call waitToDumpWatchdogTimerFired. + +2009-08-13 Eric Carlson <eric.carlson@apple.com> + + Unreviewed. + + Added 'Eric Carlson' to the committers list. + + * Scripts/modules/committers.py: + +2009-08-13 Dirk Schulze <krit@webkit.org> + + Unreviewed. + Added 'Dirk Schulze' to the committers list. + + * Scripts/modules/committers.py: + +2009-08-13 Adam Roben <aroben@apple.com> + + Enable running testapi in run-javascriptcore-tests on Windows + + Fixes <http://webkit.org/b/24856> run-javascriptcore-tests should run + testapi on Windows + + Reviewed by Mark Rowe. + + * Scripts/run-javascriptcore-tests: Allow testapi to run if we're in + the AppleWinWebKit configuration. + +2009-08-13 Adam Roben <aroben@apple.com> + + Re-enable testapi in run-javascriptcore-tests on Mac + + This seems to have been mistakenly disabled in r47089. + + Rubber-stamped by Mark Rowe. + + * Scripts/run-javascriptcore-tests: Removed comment markers that were + preventing running testapi. + +2009-08-12 George Staikos <george.staikos@torchmobile.com> + + Reviewed by Adam Treat. + + Enable WCSS and XHTML-MP flags for build-webkit. + + * Scripts/build-webkit: + +2009-08-12 David Kilzer <ddkilzer@apple.com> + + run-webkit-tests: document --nthly flag in help message + + Reviewed by Simon Fraser. + + * Scripts/run-webkit-tests: Added --nthly flag to $usage string. + Also noted that -1|--singly implies --nthly 1. + +2009-08-12 Eric Seidel <eric@webkit.org> + + No review, just fixing mismerged ChangeLogs. + +2009-08-12 Eric Seidel <eric@webkit.org> + + Reviewed by Mark Rowe. + + run-webkit-tests needs a --exit-after-failures=N option + https://bugs.webkit.org/show_bug.cgi?id=28192 + + Added the option and deployed it to bugzilla-tool. + + * Scripts/bugzilla-tool: + * Scripts/run-webkit-tests: + +2009-08-11 Eric Seidel <eric@webkit.org> + + Reviewed by Mark Rowe. + + bugzilla-tool : various improvements for running the commit-queue + https://bugs.webkit.org/show_bug.cgi?id=28199 + + Make run_and_throw_if_fail silence STDERR as well as STDIN. + I also changed run_and_throw_if_fail to use the /dev/null trick instead of .communicate() to avoid ever buffering the output (per abarth's suggestion). + Change a few "print" statements to "log" so they appear in the output. + Changed all string + uses to use string formatting instead (this is less error prone as it will automatically convert non-string objects). + Added a little more logging so that --quiet mode is easier to understand. + Changed clear_attachment_review_flag to clear_attachment_flags and made it clear the commit-queue flag as well. + Added the ability for bugzilla-tool to reject patches from the commit-queue when they fail to compile/apply/etc. + Added _find_select_element_for_flag to make the code for finding flag <select> elements clearer. + Made curl call (downloading patch files) quieter. + + * Scripts/bugzilla-tool: + * Scripts/modules/bugzilla.py: + * Scripts/modules/scm.py: + +2009-08-12 Peter Kasting <pkasting@google.com> + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=27323 + Change pattern that strips all trailing whitespace to just remove EOL + chars (\r, \n), to make it clear that varying EOL chars is the primary + problem being solved. + + * Scripts/prepare-ChangeLog: + * Scripts/resolve-ChangeLogs: + * Scripts/svn-create-patch: + * Scripts/update-webkit: + +2009-08-12 Kevin Ollivier <kevino@theolliviers.com> + + wx waf build fix, add new directories to the build. + + * wx/build/settings.py: + +2009-08-11 Adam Roben <aroben@apple.com> + + Update DumpRenderTree for IWebUIDelegatePrivate changes + + Reviewed by Dave Hyatt. + + * DumpRenderTree/win/UIDelegate.h: Updated to match + IWebUIDelegatePrivate. + +2009-08-12 Adam Roben <aroben@apple.com> + + Don't try to seek to the end of stdin on Cygwin + + Doing so seems to always cause an exception (for unknown reasons). + + Fixes <http://webkit.org/b/28159> create-bug throws an exception in + Cygwin + + Reviewed by Dave Kilzer. + + * Scripts/bugzilla-tool: + (CreateBug.prompt_for_bug_title_and_comments): Ignore IOErrors + generated by calling sys.stdin.seek, since these seem to be generated + for no good reason on Cygwin. + +2009-08-12 Adam Roben <aroben@apple.com> + + Don't raise an exception when --cc is not passed to create-bug + + Fixes <http://webkit.org/b/28158> create-bug throws an exception if + --cc is not specified + + Reviewed by Dave Kilzer. + + * Scripts/modules/bugzilla.py: + (Bugzilla.create_bug_with_patch): Only set the "cc" field if a CC + string was specified. Otherwise we'll generate an exception about the + "cc" variable not being a string. + +2009-08-11 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + bugzilla-tool : various improvements for running the commit-queue + https://bugs.webkit.org/show_bug.cgi?id=28199 + + Make run_and_throw_if_fail silence STDERR as well as STDIN. + I also changed run_and_throw_if_fail to use the /dev/null trick instead of .communicate() to avoid ever buffering the out + Change a few "print" statements to "log" so they appear in the output. + Changed all string + uses to use string formatting instead (this is less error prone as it will automatically convert non + Added a little more logging so that --quiet mode is easier to understand. + Changed clear_attachment_review_flag to clear_attachment_flags and made it clear the commit-queue flag as well. + Added the ability for bugzilla-tool to reject patches from the commit-queue when they fail to compile/apply/etc. + Added _find_select_element_for_flag to make the code for finding flag <select> elements clearer. + Made curl call (downloading patch files) quieter. + + * Scripts/bugzilla-tool: + * Scripts/modules/bugzilla.py: + * Scripts/modules/scm.py: + +2009-08-11 Eric Seidel <eric@webkit.org> + + No review, script regression fix only. + + run-webkit-tests --quiet hangs + https://bugs.webkit.org/show_bug.cgi?id=28202 + + Do a huge dance to get open3 to pipe to /dev/null w/o blocking. + This was what I came up with after discussions in #perl. + + * Scripts/run-webkit-tests: + +2009-08-11 John Gregg <johnnyg@google.com> + + Reviewed by Maciej Stachowiak. + + Switch DumpRenderTree to contain a WebUIDelegate2, which extends + WebUIDelegate, so that the notifications tests will still work. + https://bugs.webkit.org/show_bug.cgi?id=28198 + + * DumpRenderTree/win/UIDelegate.h: + +2009-08-11 Darin Adler <darin@apple.com> + + Try to fix GTK build. + + * DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp: + (AccessibilityUIElement::stringForRange): Added. + +2009-08-10 Mike Fenton <mike.fenton@torchmobile.com> + + Reviewed by Adam Treat. + + Add processing for string constants used by the tests to trigger + common actions like up, down, left, right, etc. for the Qt + implementation of DumpRenderTree. + + Note this allows fast/forms/textarea-arrow-navigation.html to pass + correctly. + + https://bugs.webkit.org/show_bug.cgi?id=28161 + + * DumpRenderTree/qt/jsobjects.cpp: + (EventSender::keyDown): + +2009-08-11 Chris Fleizach <cfleizach@apple.com> + + Reviewed by Darin Adler. + + Bug 28200 - ListMarker should be included as part of the text value to parse + https://bugs.webkit.org/show_bug.cgi?id=28200 + + Add the ability to retrieve a string given a plain NSRange. + + * DumpRenderTree/AccessibilityUIElement.cpp: + (stringForRangeCallback): + (AccessibilityUIElement::getJSClass): + * DumpRenderTree/AccessibilityUIElement.h: + * DumpRenderTree/mac/AccessibilityUIElementMac.mm: + (AccessibilityUIElement::valueDescription): + (AccessibilityUIElement::stringForRange): + * DumpRenderTree/win/AccessibilityUIElementWin.cpp: + (AccessibilityUIElement::stringForRange): + +2009-08-11 Dmitry Titov <dimich@chromium.org> + + Reviewed by NOBODY (Speculative fix for the layout test failure). + + Fix fast/dom/prototype-inheritance.html + and fast/dom/prototype-inheritance-2.html + broken on Windows by http://trac.webkit.org/changeset/47018 + + * DumpRenderTree/win/DumpRenderTree.cpp: + (resetDefaultsToConsistentValues): enable app cache in Windows DRT. + +2009-08-11 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + bugzilla-tool: Re-factor shared landing logic into helper class to share more code + https://bugs.webkit.org/show_bug.cgi?id=28193 + + Added new WebKitLandingScripts class to hold this shared logic. + Also added a view_source_url function to move more webkit-specific urls out of bugzilla-tool core. + + * Scripts/bugzilla-tool: + +2009-08-11 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Adam Treat. + + Fix the current failures on the buildbot. + + As Qt hooks up the maybeDump to loadFinished, we need to make + sure that calling dump() will not call maybeDump on loadFinished. + + As dump is called my emitting done() which calls dump() and then + setting m_isLoading to false. So in the case m_isLoading is false, + do not dump again. + + The current code is confusing, and should be made more clear + in another commit. + + * DumpRenderTree/qt/jsobjects.cpp: + (LayoutTestController::maybeDump): + (LayoutTestController::notifyDone): + +2009-08-11 John Gregg <johnnyg@google.com> + + Reviewed by Maciej Stachowiak. + + Add support for desktop notifications API to DumpRenderTree, + and support for ENABLE_NOTIFICATIONS flag to build-webkit. + + * DumpRenderTree/LayoutTestController.cpp: + (grantDesktopNotificationPermissionCallback): + (LayoutTestController::staticFunctions): + (LayoutTestController::grantDesktopNotificationPermission): + (LayoutTestController::checkDesktopNotificationPermission): + * DumpRenderTree/LayoutTestController.h: + * DumpRenderTree/win/DRTDesktopNotificationPresenter.cpp: Added. + (DRTDesktopNotificationPresenter::DRTDesktopNotificationPresenter): + (DRTDesktopNotificationPresenter::QueryInterface): + (DRTDesktopNotificationPresenter::AddRef): + (DRTDesktopNotificationPresenter::Release): + (DRTDesktopNotificationPresenter::showDesktopNotification): + (DRTDesktopNotificationPresenter::cancelDesktopNotification): + (DRTDesktopNotificationPresenter::notificationDestroyed): + (DRTDesktopNotificationPresenter::checkNotificationPermission): + (DRTDesktopNotificationPresenter::requestNotificationPermission): + * DumpRenderTree/win/DRTDesktopNotificationPresenter.h: Added. + * DumpRenderTree/win/DumpRenderTree.vcproj: + * DumpRenderTree/win/UIDelegate.cpp: + (UIDelegate::UIDelegate): + (UIDelegate::desktopNotificationsDelegate): + * DumpRenderTree/win/UIDelegate.h: + * Scripts/build-webkit: + +2009-08-11 Peter Kasting <pkasting@google.com> + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=27323 + Handle arbitrary line endings when manufacturing patches for additions + with history. + + * Scripts/svn-create-patch: + +2009-08-11 Peter Kasting <pkasting@google.com> + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=28183 + Support VS2008 as well as VS2005 in a few scripts. + + * Scripts/pdevenv: Check both $VS80COMNTOOLS and $VS90COMNTOOLS. + * Scripts/webkitdirs.pm: Use $VSINSTALLDIR if available instead of hardcoding the VS2005 dir. + +2009-08-11 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + run-webkit-tests --quiet should not output build-dumprendertree output + https://bugs.webkit.org/show_bug.cgi?id=28189 + + * Scripts/run-webkit-tests: + +2009-08-11 Eric Seidel <eric@webkit.org> + + Reviewed by Darin Adler. + + Exception in land-patches + https://bugs.webkit.org/show_bug.cgi?id=27962 + + Use ("%s" % object) instead of ("" + object). + Added unit tests for logging.py. + + * Scripts/modules/logging.py: + * Scripts/modules/logging_unittest.py: Added. + * Scripts/run-webkit-unittests: + +2009-08-11 Dmitry Titov <dimich@chromium.org> + + Reviewed by NOBODY (Windows layout tests fix). + + Fix for layout tests failures. Need to initialize some preferences early + because WebView on Windows uses them during create time. + + * DumpRenderTree/win/DumpRenderTree.cpp: + (main): + +2009-08-11 Dmitry Titov <dimich@chromium.org> + + Reviewed by Adam Roben. + + Originally implemented by Glenn Wilson <gwilson@chromium.org>. + + Added support for overriding default preferences per-test. + See https://bugs.webkit.org/show_bug.cgi?id=20534 + + * DumpRenderTree/LayoutTestController.cpp: + (overridePreferenceCallback): add wiring for layoutTestController.overridePreference. + (LayoutTestController::staticFunctions): same. + * DumpRenderTree/LayoutTestController.h: same. + * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp: + (LayoutTestController::overridePreference): added empty overridePreference method. + * DumpRenderTree/mac/DumpRenderTree.mm: implemented preference override. + (resetDefaultsToConsistentValues): new method, resets preferences to same set of value before every test. + (setDefaultsToConsistentValuesForTesting): new method, sets other details of testing environment, every time DRT starts. + (resetWebViewToConsistentStateBeforeTesting): move some preference setting from here to new resetDefaultsToConsistentValues(). + * DumpRenderTree/mac/LayoutTestControllerMac.mm: + (LayoutTestController::overridePreference): + * DumpRenderTree/win/DumpRenderTree.cpp: + (resetDefaultsToConsistentValues): new method, resets preferences to same set of value before every test. + (resetWebViewToConsistentStateBeforeTesting): move some preference setting from here to new resetDefaultsToConsistentValues(). + (createWebViewAndOffscreenWindow): same. + (main): same. + * DumpRenderTree/win/LayoutTestControllerWin.cpp: + (LayoutTestController::overridePreference): + * DumpRenderTree/wx/LayoutTestControllerWx.cpp: + (LayoutTestController::overridePreference): + +2009-08-11 Brian Weinstein <bweinstein@apple.com> + + Reviewed by Sam Weinig. + + Added support for DRT to support arguments for eventSender.mouseDown and eventSender.mouseUp for Windows. + https://bugs.webkit.org/show_bug.cgi?id=28166. + + This is a step towards fixing fast/events/mouse-click-events.html on Windows. + + * DumpRenderTree/win/EventSender.cpp: + (mouseDownCallback): + (mouseUpCallback): + (replaySavedEvents): + +2009-08-11 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + Reviewed by Simon Hausmann. + + Build the TestNetscapePlugin on Qt/Mac + + * DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro: + 2009-08-11 Dmitry Titov <dimich@chromium.org> Reviewed by NOBODY (build fix). @@ -61,6 +3697,15 @@ 2009-08-10 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + Reviewed by Simon Hausmann. + + Fix a bunch of build warnings in TestNetscapePlugin + + * DumpRenderTree/TestNetscapePlugIn.subproj/TestObject.cpp: + * DumpRenderTree/gtk/TestNetscapePlugin/TestNetscapePlugin.cpp: + +2009-08-10 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + Reviewed by Adam Roben. Allow TestNetscapePlugIn to fall back to the Carbon event model diff --git a/WebKitTools/CommitQueueStatus/app.yaml b/WebKitTools/CommitQueueStatus/app.yaml new file mode 100644 index 0000000..2756112 --- /dev/null +++ b/WebKitTools/CommitQueueStatus/app.yaml @@ -0,0 +1,11 @@ +application: webkit-commit-queue +version: 1 +runtime: python +api_version: 1 + +handlers: +- url: /stylesheets + static_dir: stylesheets + +- url: /.* + script: queue_status.py diff --git a/WebKitTools/CommitQueueStatus/filters/__init__.py b/WebKitTools/CommitQueueStatus/filters/__init__.py new file mode 100644 index 0000000..ef65bee --- /dev/null +++ b/WebKitTools/CommitQueueStatus/filters/__init__.py @@ -0,0 +1 @@ +# Required for Python to search this directory for module files diff --git a/WebKitTools/CommitQueueStatus/filters/webkit_extras.py b/WebKitTools/CommitQueueStatus/filters/webkit_extras.py new file mode 100644 index 0000000..6a08727 --- /dev/null +++ b/WebKitTools/CommitQueueStatus/filters/webkit_extras.py @@ -0,0 +1,44 @@ +# Copyright (C) 2009 Google 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: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from django.template.defaultfilters import stringfilter +from google.appengine.ext import webapp + +import re + +bug_regexp = re.compile(r"bug (?P<bug_id>\d+)") +patch_regexp = re.compile(r"patch (?P<patch_id>\d+)") + +@stringfilter +def webkit_linkify(value): + value = bug_regexp.sub(r'<a href="http://webkit.org/b/\g<bug_id>">bug \g<bug_id></a>', value) + value = patch_regexp.sub(r'<a href="https://bugs.webkit.org/attachment.cgi?id=\g<patch_id>&action=prettypatch">patch \g<patch_id></a>', value) + return value + +register = webapp.template.create_template_register() +register.filter(webkit_linkify) diff --git a/WebKitTools/CommitQueueStatus/index.html b/WebKitTools/CommitQueueStatus/index.html new file mode 100644 index 0000000..2b5aced --- /dev/null +++ b/WebKitTools/CommitQueueStatus/index.html @@ -0,0 +1,28 @@ +<html> +<head> + <title>WebKit Commit Queue Status</title> + <link type="text/css" rel="stylesheet" href="/stylesheets/main.css" /> +</head> +<body> + <center> + <div id="current_status"> + {{ last_status.message|force_escape|urlize|webkit_linkify|safe }} + <div id="last_status_date">As of {{ last_status.date|timesince }} ago</div> + </div> + + <table id="recent_status_table"> + <tr> + <th colspan=2>Recent Status</th> + </tr> + {% for recent_status in recent_statuses %} + <tr> + <td class='status_date'>{{ recent_status.date|timesince }} ago</td> + <td class="recent_status">{{ recent_status.message|force_escape|urlize|webkit_linkify|safe }}</td> + </tr> + {% endfor %} + </table> + + <div id="footer"><a href="https://bugs.webkit.org/buglist.cgi?query_format=advanced&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&field0-0-0=flagtypes.name&type0-0-0=equals&value0-0-0=commit-queue%2B">queued bugs</a> | <a href="http://trac.webkit.org/wiki/CommitQueue">documentation</a> | <a href="http://webkit.org/">webkit.org</a></div> + </center> +</body> +</html> diff --git a/WebKitTools/CommitQueueStatus/index.yaml b/WebKitTools/CommitQueueStatus/index.yaml new file mode 100644 index 0000000..a3b9e05 --- /dev/null +++ b/WebKitTools/CommitQueueStatus/index.yaml @@ -0,0 +1,11 @@ +indexes: + +# AUTOGENERATED + +# This index.yaml is automatically updated whenever the dev_appserver +# detects that a new type of query is run. If you want to manage the +# index.yaml file manually, remove the above marker line (the line +# saying "# AUTOGENERATED"). If you want to manage some indexes +# manually, move them above the marker line. The index.yaml file is +# automatically uploaded to the admin console when you next deploy +# your application using appcfg.py. diff --git a/WebKitTools/CommitQueueStatus/queue_status.py b/WebKitTools/CommitQueueStatus/queue_status.py new file mode 100644 index 0000000..30d2494 --- /dev/null +++ b/WebKitTools/CommitQueueStatus/queue_status.py @@ -0,0 +1,96 @@ +# Copyright (C) 2009 Google 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: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import cgi +import os + +# Request a modern Django +from google.appengine.dist import use_library +use_library('django', '1.1') + +from google.appengine.ext.webapp import template +from google.appengine.api import users +from google.appengine.ext import webapp +from google.appengine.ext.webapp.util import run_wsgi_app +from google.appengine.ext import db + +webapp.template.register_template_library('filters.webkit_extras') + +class QueueStatus(db.Model): + author = db.UserProperty() + active_bug_id = db.IntegerProperty() + active_patch_id = db.IntegerProperty() + message = db.StringProperty(multiline=True) + date = db.DateTimeProperty(auto_now_add=True) + +class MainPage(webapp.RequestHandler): + def get(self): + statuses_query = QueueStatus.all().order('-date') + statuses = statuses_query.fetch(6) + template_values = { + 'last_status' : statuses[0], + 'recent_statuses' : statuses[1:], + } + self.response.out.write(template.render('index.html', template_values)) + +class UpdateStatus(webapp.RequestHandler): + def get(self): + self.response.out.write(template.render('update_status.html', None)) + + def _int_from_request(self, name): + string_value = self.request.get(name) + try: + int_value = int(string_value) + except ValueError, TypeError: + pass + return None + + def post(self): + queue_status = QueueStatus() + + if users.get_current_user(): + queue_status.author = users.get_current_user() + + queue_status.active_bug_id = self._int_from_request('bug_id') + queue_status.active_patch_id = self._int_from_request('patch_id') + queue_status.message = self.request.get('status') + queue_status.put() + self.redirect('/') + +routes = [ + ('/', MainPage), + ('/update_status', UpdateStatus) +] + +application = webapp.WSGIApplication(routes, debug=True) + +def main(): + run_wsgi_app(application) + +if __name__ == "__main__": + main() diff --git a/WebKitTools/CommitQueueStatus/stylesheets/main.css b/WebKitTools/CommitQueueStatus/stylesheets/main.css new file mode 100644 index 0000000..55d3694 --- /dev/null +++ b/WebKitTools/CommitQueueStatus/stylesheets/main.css @@ -0,0 +1,26 @@ +body { + font-family: Verdana, Helvetica, sans-serif; +} + +#current_status { + padding: 5px; + font-size: larger; +} + +#last_status_date { + font-size: small; +} + +.recent_status { + padding-left: 10px; +} + +#recent_status_table { + font-size: small; + margin: 10px; +} + +#footer { + font-size: small; + padding-top: 10px; +} diff --git a/WebKitTools/CommitQueueStatus/update_status.html b/WebKitTools/CommitQueueStatus/update_status.html new file mode 100644 index 0000000..edafba4 --- /dev/null +++ b/WebKitTools/CommitQueueStatus/update_status.html @@ -0,0 +1,19 @@ +Update the current status of the commit-queue: +<form name="update_status" method="post"> + <div> + Active Bug Id: + <input name="bug_id"> + </div> + <div> + Active Patch Id: + <input name="patch_id"> + </div> + <div> + Space separated list of other bugs in queue: + <input name="bugs_in_queue"> + </div> + <div> + <textarea name="status" rows="3" cols="60"></textarea> + </div> + <div><input type="submit" value="Add Status"></div> +</form> diff --git a/WebKitTools/DumpRenderTree/AccessibilityController.cpp b/WebKitTools/DumpRenderTree/AccessibilityController.cpp index 6556f91..af1daf6 100644 --- a/WebKitTools/DumpRenderTree/AccessibilityController.cpp +++ b/WebKitTools/DumpRenderTree/AccessibilityController.cpp @@ -52,8 +52,28 @@ void AccessibilityController::makeWindowObject(JSContextRef context, JSObjectRef JSObjectSetProperty(context, windowObject, accessibilityControllerStr.get(), accessibilityControllerObject, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, exception); } +static JSValueRef logFocusEventsCallback(JSContextRef ctx, JSObjectRef, JSObjectRef thisObject, size_t, const JSValueRef[], JSValueRef*) +{ + AccessibilityController* controller = static_cast<AccessibilityController*>(JSObjectGetPrivate(thisObject)); + controller->setLogFocusEvents(true); + return JSValueMakeUndefined(ctx); +} + +static JSValueRef logScrollingStartEventsCallback(JSContextRef ctx, JSObjectRef, JSObjectRef thisObject, size_t, const JSValueRef[], JSValueRef*) +{ + AccessibilityController* controller = static_cast<AccessibilityController*>(JSObjectGetPrivate(thisObject)); + controller->setLogScrollingStartEvents(true); + return JSValueMakeUndefined(ctx); +} + JSClassRef AccessibilityController::getJSClass() { + static JSStaticFunction staticFunctions[] = { + { "logFocusEvents", logFocusEventsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "logScrollingStartEvents", logScrollingStartEventsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { 0, 0, 0 } + }; + static JSStaticValue staticValues[] = { { "focusedElement", getFocusedElementCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "rootElement", getRootElementCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, @@ -61,10 +81,16 @@ JSClassRef AccessibilityController::getJSClass() }; static JSClassDefinition classDefinition = { - 0, kJSClassAttributeNone, "AccessibilityController", 0, staticValues, 0, + 0, kJSClassAttributeNone, "AccessibilityController", 0, staticValues, staticFunctions, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; static JSClassRef accessibilityControllerClass = JSClassCreate(&classDefinition); return accessibilityControllerClass; } + +void AccessibilityController::resetToConsistentState() +{ + setLogFocusEvents(false); + setLogScrollingStartEvents(false); +} diff --git a/WebKitTools/DumpRenderTree/AccessibilityController.h b/WebKitTools/DumpRenderTree/AccessibilityController.h index 0af6613..a10e8be 100644 --- a/WebKitTools/DumpRenderTree/AccessibilityController.h +++ b/WebKitTools/DumpRenderTree/AccessibilityController.h @@ -27,6 +27,9 @@ #define AccessibilityController_h #include <JavaScriptCore/JSObjectRef.h> +#if PLATFORM(WIN) +#include <windows.h> +#endif class AccessibilityUIElement; @@ -41,8 +44,18 @@ public: AccessibilityUIElement rootElement(); AccessibilityUIElement focusedElement(); + void setLogFocusEvents(bool); + void setLogScrollingStartEvents(bool); + + void resetToConsistentState(); + private: static JSClassRef getJSClass(); + +#if PLATFORM(WIN) + HWINEVENTHOOK m_focusEventHook; + HWINEVENTHOOK m_scrollingStartEventHook; +#endif }; #endif // AccessibilityController_h diff --git a/WebKitTools/DumpRenderTree/AccessibilityUIElement.cpp b/WebKitTools/DumpRenderTree/AccessibilityUIElement.cpp index 8a92766..5958ccb 100644 --- a/WebKitTools/DumpRenderTree/AccessibilityUIElement.cpp +++ b/WebKitTools/DumpRenderTree/AccessibilityUIElement.cpp @@ -140,6 +140,18 @@ static JSValueRef boundsForRangeCallback(JSContextRef context, JSObjectRef funct return JSValueMakeString(context, boundsDescription.get()); } +static JSValueRef stringForRangeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + unsigned location = UINT_MAX, length = 0; + if (argumentCount == 2) { + location = JSValueToNumber(context, arguments[0], exception); + length = JSValueToNumber(context, arguments[1], exception); + } + + JSRetainPtr<JSStringRef> stringDescription(Adopt, toAXElement(thisObject)->stringForRange(location, length)); + return JSValueMakeString(context, stringDescription.get()); +} + static JSValueRef childAtIndexCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { int indexNumber = -1; @@ -190,7 +202,8 @@ static JSValueRef attributeValueCallback(JSContextRef context, JSObjectRef funct JSStringRef attribute = NULL; if (argumentCount == 1) attribute = JSValueToStringCopy(context, arguments[0], exception); - JSValueRef result = JSValueMakeString(context, toAXElement(thisObject)->attributeValue(attribute)); + JSRetainPtr<JSStringRef> attributeValue(Adopt, toAXElement(thisObject)->attributeValue(attribute)); + JSValueRef result = JSValueMakeString(context, attributeValue.get()); if (attribute) JSStringRelease(attribute); return result; @@ -250,6 +263,12 @@ static JSValueRef getRoleCallback(JSContextRef context, JSObjectRef thisObject, return JSValueMakeString(context, role.get()); } +static JSValueRef getSubroleCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + JSRetainPtr<JSStringRef> role(Adopt, toAXElement(thisObject)->subrole()); + return JSValueMakeString(context, role.get()); +} + static JSValueRef getTitleCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) { JSRetainPtr<JSStringRef> title(Adopt, toAXElement(thisObject)->title()); @@ -363,6 +382,7 @@ JSClassRef AccessibilityUIElement::getJSClass() { static JSStaticValue staticValues[] = { { "role", getRoleCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "subrole", getSubroleCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "title", getTitleCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "description", getDescriptionCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "language", getLanguageCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, @@ -392,6 +412,7 @@ JSClassRef AccessibilityUIElement::getJSClass() { "parameterizedAttributeNames", parameterizedAttributeNamesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "lineForIndex", lineForIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "boundsForRange", boundsForRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "stringForRange", stringForRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "childAtIndex", childAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "elementAtPoint", elementAtPointCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "attributesOfColumnHeaders", attributesOfColumnHeadersCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, diff --git a/WebKitTools/DumpRenderTree/AccessibilityUIElement.h b/WebKitTools/DumpRenderTree/AccessibilityUIElement.h index d0b63c3..fffdad8 100644 --- a/WebKitTools/DumpRenderTree/AccessibilityUIElement.h +++ b/WebKitTools/DumpRenderTree/AccessibilityUIElement.h @@ -86,6 +86,7 @@ public: bool isAttributeSettable(JSStringRef attribute); bool isActionSupported(JSStringRef action); JSStringRef role(); + JSStringRef subrole(); JSStringRef title(); JSStringRef description(); JSStringRef language(); @@ -119,6 +120,7 @@ public: int lineForIndex(int); JSStringRef boundsForRange(unsigned location, unsigned length); void setSelectedTextRange(unsigned location, unsigned length); + JSStringRef stringForRange(unsigned location, unsigned length); // Table-specific AccessibilityUIElement cellForColumnAndRow(unsigned column, unsigned row); diff --git a/WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj b/WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj index fd2c0d9..06f0599 100644 --- a/WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj +++ b/WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj @@ -35,6 +35,8 @@ 1AC6C84A0D07638600CD3161 /* PluginObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AC6C7800D07589B00CD3161 /* PluginObject.cpp */; }; 1AC6C84B0D07638600CD3161 /* TestObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AC6C7810D07589B00CD3161 /* TestObject.cpp */; }; 23BCB8900EA57623003C6289 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 23BCB88F0EA57623003C6289 /* OpenGL.framework */; }; + 5185F6B210714E07007AA393 /* HistoryDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5185F69F10714A57007AA393 /* HistoryDelegate.mm */; }; + 5185F6B310714E12007AA393 /* HistoryDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 5185F69E10714A57007AA393 /* HistoryDelegate.h */; }; 5DB9AC970F722C3600684641 /* AHEM____.TTF in Copy Font Files */ = {isa = PBXBuildFile; fileRef = AA7F10C20CB3C1030003BDC9 /* AHEM____.TTF */; }; 5DB9AC980F722C3600684641 /* WebKitWeightWatcher100.ttf in Copy Font Files */ = {isa = PBXBuildFile; fileRef = 375F09710DAC3CB600C8B4E5 /* WebKitWeightWatcher100.ttf */; }; 5DB9AC990F722C3600684641 /* WebKitWeightWatcher200.ttf in Copy Font Files */ = {isa = PBXBuildFile; fileRef = 375F09720DAC3CB600C8B4E5 /* WebKitWeightWatcher200.ttf */; }; @@ -189,6 +191,8 @@ 375F09770DAC3CB600C8B4E5 /* WebKitWeightWatcher700.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = WebKitWeightWatcher700.ttf; path = fonts/WebKitWeightWatcher700.ttf; sourceTree = "<group>"; }; 375F09780DAC3CB600C8B4E5 /* WebKitWeightWatcher800.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = WebKitWeightWatcher800.ttf; path = fonts/WebKitWeightWatcher800.ttf; sourceTree = "<group>"; }; 375F09790DAC3CB600C8B4E5 /* WebKitWeightWatcher900.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = WebKitWeightWatcher900.ttf; path = fonts/WebKitWeightWatcher900.ttf; sourceTree = "<group>"; }; + 5185F69E10714A57007AA393 /* HistoryDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HistoryDelegate.h; path = mac/HistoryDelegate.h; sourceTree = "<group>"; }; + 5185F69F10714A57007AA393 /* HistoryDelegate.mm */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; name = HistoryDelegate.mm; path = mac/HistoryDelegate.mm; sourceTree = "<group>"; }; 8465E2C60FFA8DF2003B8342 /* PixelDumpSupport.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 30; path = PixelDumpSupport.cpp; sourceTree = "<group>"; }; 9335435F03D75502008635CE /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = WebKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 933BF5A90F93FA5C000F0441 /* PlainTextController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PlainTextController.h; path = mac/PlainTextController.h; sourceTree = "<group>"; }; @@ -388,6 +392,8 @@ BCA18B580C9B08C200114369 /* EditingDelegate.mm */, BCA18B590C9B08C200114369 /* FrameLoadDelegate.h */, BCA18B5A0C9B08C200114369 /* FrameLoadDelegate.mm */, + 5185F69E10714A57007AA393 /* HistoryDelegate.h */, + 5185F69F10714A57007AA393 /* HistoryDelegate.mm */, BCA18B5B0C9B08C200114369 /* PolicyDelegate.h */, BCA18B5C0C9B08C200114369 /* PolicyDelegate.mm */, BCA18B5D0C9B08C200114369 /* ResourceLoadDelegate.h */, @@ -531,6 +537,7 @@ BCA18B690C9B08C200114369 /* UIDelegate.h in Headers */, BC9D90250C97472E0099A4A3 /* WorkQueue.h in Headers */, BC9D90260C97472E0099A4A3 /* WorkQueueItem.h in Headers */, + 5185F6B310714E12007AA393 /* HistoryDelegate.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -696,6 +703,7 @@ BCA18B6A0C9B08C200114369 /* UIDelegate.mm in Sources */, BC9D90240C97472E0099A4A3 /* WorkQueue.cpp in Sources */, BCA18B260C9B015C00114369 /* WorkQueueItemMac.mm in Sources */, + 5185F6B210714E07007AA393 /* HistoryDelegate.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/WebKitTools/DumpRenderTree/LayoutTestController.cpp b/WebKitTools/DumpRenderTree/LayoutTestController.cpp index 2a0871f..1f34325 100644 --- a/WebKitTools/DumpRenderTree/LayoutTestController.cpp +++ b/WebKitTools/DumpRenderTree/LayoutTestController.cpp @@ -33,26 +33,28 @@ #include "WorkQueueItem.h" #include <JavaScriptCore/JSObjectRef.h> #include <JavaScriptCore/JSRetainPtr.h> +#include <stdio.h> #include <wtf/Assertions.h> #include <wtf/MathExtras.h> +#include <wtf/RefPtr.h> LayoutTestController::LayoutTestController(const std::string& testPathOrURL, const std::string& expectedPixelHash) - : m_dumpAsText(false) - , m_dumpAsPDF(false) + : m_dumpAsPDF(false) + , m_dumpAsText(false) , m_dumpBackForwardList(false) , m_dumpChildFrameScrollPositions(false) , m_dumpChildFramesAsText(false) - , m_dumpDatabaseCallbacks(false) , m_dumpDOMAsWebArchive(false) + , m_dumpDatabaseCallbacks(false) + , m_dumpEditingCallbacks(false) + , m_dumpFrameLoadCallbacks(false) + , m_dumpResourceLoadCallbacks(false) + , m_dumpResourceResponseMIMETypes(false) , m_dumpSelectionRect(false) , m_dumpSourceAsWebArchive(false) , m_dumpStatusCallbacks(false) , m_dumpTitleChanges(false) - , m_dumpEditingCallbacks(false) - , m_dumpResourceLoadCallbacks(false) - , m_dumpResourceResponseMIMETypes(false) , m_dumpWillCacheResponse(false) - , m_dumpFrameLoadCallbacks(false) , m_callCloseOnWebViews(true) , m_canOpenWindows(false) , m_closeRemainingWindowsWhenComplete(true) @@ -63,7 +65,10 @@ LayoutTestController::LayoutTestController(const std::string& testPathOrURL, con , m_waitToDump(false) , m_willSendRequestReturnsNullOnRedirect(false) , m_windowIsKey(true) + , m_alwaysAcceptCookies(false) , m_globalFlag(false) + , m_isGeolocationPermissionSet(false) + , m_geolocationPermission(false) , m_testPathOrURL(testPathOrURL) , m_expectedPixelHash(expectedPixelHash) { @@ -71,17 +76,17 @@ LayoutTestController::LayoutTestController(const std::string& testPathOrURL, con // Static Functions -static JSValueRef dumpAsTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +static JSValueRef dumpAsPDFCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); - controller->setDumpAsText(true); + controller->setDumpAsPDF(true); return JSValueMakeUndefined(context); } -static JSValueRef dumpAsPDFCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +static JSValueRef dumpAsTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); - controller->setDumpAsPDF(true); + controller->setDumpAsText(true); return JSValueMakeUndefined(context); } @@ -127,6 +132,13 @@ static JSValueRef dumpEditingCallbacksCallback(JSContextRef context, JSObjectRef return JSValueMakeUndefined(context); } +static JSValueRef dumpFrameLoadCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + LayoutTestController* controller = static_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 = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); @@ -362,6 +374,19 @@ static JSValueRef execCommandCallback(JSContextRef context, JSObjectRef function return JSValueMakeUndefined(context); } +static JSValueRef grantDesktopNotificationPermissionCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + // Has Windows implementation + if (argumentCount < 1) + return JSValueMakeUndefined(context); + + LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); + + controller->grantDesktopNotificationPermission(JSValueToStringCopy(context, arguments[0], NULL)); + + return JSValueMakeUndefined(context); +} + static JSValueRef isCommandEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { // Has Mac implementation. @@ -377,6 +402,22 @@ static JSValueRef isCommandEnabledCallback(JSContextRef context, JSObjectRef fun return JSValueMakeBoolean(context, controller->isCommandEnabled(name.get())); } +static JSValueRef overridePreferenceCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + if (argumentCount < 2) + return JSValueMakeUndefined(context); + + JSRetainPtr<JSStringRef> key(Adopt, JSValueToStringCopy(context, arguments[0], exception)); + ASSERT(!*exception); + JSRetainPtr<JSStringRef> value(Adopt, JSValueToStringCopy(context, arguments[1], exception)); + ASSERT(!*exception); + + LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); + controller->overridePreference(key.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 @@ -505,6 +546,18 @@ static JSValueRef setAcceptsEditingCallback(JSContextRef context, JSObjectRef fu return JSValueMakeUndefined(context); } +static JSValueRef setAlwaysAcceptCookiesCallback(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 = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); + controller->setAlwaysAcceptCookies(JSValueToBoolean(context, arguments[0])); + + return JSValueMakeUndefined(context); +} + static JSValueRef setAppCacheMaximumSizeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { // Has mac implementation @@ -521,6 +574,46 @@ static JSValueRef setAppCacheMaximumSizeCallback(JSContextRef context, JSObjectR } +static JSValueRef setAuthenticationPasswordCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + // Has mac & windows implementation + if (argumentCount < 1) + return JSValueMakeUndefined(context); + + JSRetainPtr<JSStringRef> password(Adopt, JSValueToStringCopy(context, arguments[0], exception)); + ASSERT(!*exception); + + size_t maxLength = JSStringGetMaximumUTF8CStringSize(password.get()); + char* passwordBuffer = new char[maxLength + 1]; + JSStringGetUTF8CString(password.get(), passwordBuffer, maxLength + 1); + + LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); + controller->setAuthenticationPassword(passwordBuffer); + delete[] passwordBuffer; + + return JSValueMakeUndefined(context); +} + +static JSValueRef setAuthenticationUsernameCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + // Has mac & windows implementation + if (argumentCount < 1) + return JSValueMakeUndefined(context); + + JSRetainPtr<JSStringRef> username(Adopt, JSValueToStringCopy(context, arguments[0], exception)); + ASSERT(!*exception); + + size_t maxLength = JSStringGetMaximumUTF8CStringSize(username.get()); + char* usernameBuffer = new char[maxLength + 1]; + JSStringGetUTF8CString(username.get(), usernameBuffer, maxLength + 1); + + LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); + controller->setAuthenticationUsername(usernameBuffer); + delete[] usernameBuffer; + + return JSValueMakeUndefined(context); +} + static JSValueRef setAuthorAndUserStylesEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { // Has mac & windows implementation @@ -577,7 +670,71 @@ static JSValueRef setDatabaseQuotaCallback(JSContextRef context, JSObjectRef fun controller->setDatabaseQuota(static_cast<unsigned long long>(quota)); return JSValueMakeUndefined(context); +} + +static JSValueRef setMockGeolocationPositionCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + if (argumentCount < 3) + return JSValueMakeUndefined(context); + + LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); + controller->setMockGeolocationPosition(JSValueToNumber(context, arguments[0], NULL), // latitude + JSValueToNumber(context, arguments[1], NULL), // longitude + JSValueToNumber(context, arguments[2], NULL)); // accuracy + + return JSValueMakeUndefined(context); +} + +static JSValueRef setMockGeolocationErrorCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + if (argumentCount < 2) + return JSValueMakeUndefined(context); + + int code = JSValueToNumber(context, arguments[0], NULL); + JSRetainPtr<JSStringRef> message(Adopt, JSValueToStringCopy(context, arguments[1], exception)); + ASSERT(!*exception); + + LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); + controller->setMockGeolocationError(code, message.get()); + + return JSValueMakeUndefined(context); +} + +static JSValueRef setGeolocationPermissionCallback(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 = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); + controller->setGeolocationPermission(JSValueToBoolean(context, arguments[0])); + + return JSValueMakeUndefined(context); +} + +static JSValueRef setHandlesAuthenticationChallengesCallback(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 = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); + controller->setHandlesAuthenticationChallenges(JSValueToBoolean(context, arguments[0])); + + return JSValueMakeUndefined(context); +} + +static JSValueRef setPOSIXLocaleCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + if (argumentCount < 1) + return JSValueMakeUndefined(context); + + LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); + JSRetainPtr<JSStringRef> locale(Adopt, JSValueToStringCopy(context, arguments[0], exception)); + ASSERT(!*exception); + controller->setPOSIXLocale(locale.get()); + return JSValueMakeUndefined(context); } static JSValueRef setIconDatabaseEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) @@ -785,6 +942,32 @@ static JSValueRef setStopProvisionalFrameLoadsCallback(JSContextRef context, JSO return JSValueMakeUndefined(context); } +static JSValueRef showWebInspectorCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); + controller->showWebInspector(); + return JSValueMakeUndefined(context); +} + +static JSValueRef closeWebInspectorCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); + controller->closeWebInspector(); + return JSValueMakeUndefined(context); +} + +static JSValueRef evaluateInWebInspectorCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); + double callId = JSValueToNumber(context, arguments[0], exception); + ASSERT(!*exception); + JSRetainPtr<JSStringRef> script(Adopt, JSValueToStringCopy(context, arguments[1], exception)); + ASSERT(!*exception); + + controller->evaluateInWebInspector(static_cast<long>(callId), script.get()); + return JSValueMakeUndefined(context); +} + static JSValueRef elementDoesAutoCompleteForElementWithIdCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); @@ -844,6 +1027,51 @@ static JSValueRef waitForPolicyDelegateCallback(JSContextRef context, JSObjectRe return JSValueMakeUndefined(context); } +static JSValueRef whiteListAccessFromOriginCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + if (argumentCount != 4) + return JSValueMakeUndefined(context); + + JSRetainPtr<JSStringRef> sourceOrigin(Adopt, JSValueToStringCopy(context, arguments[0], exception)); + ASSERT(!*exception); + JSRetainPtr<JSStringRef> destinationProtocol(Adopt, JSValueToStringCopy(context, arguments[1], exception)); + ASSERT(!*exception); + JSRetainPtr<JSStringRef> destinationHost(Adopt, JSValueToStringCopy(context, arguments[2], exception)); + ASSERT(!*exception); + bool allowDestinationSubdomains = JSValueToBoolean(context, arguments[3]); + + LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); + controller->whiteListAccessFromOrigin(sourceOrigin.get(), destinationProtocol.get(), destinationHost.get(), allowDestinationSubdomains); + return JSValueMakeUndefined(context); +} + +static JSValueRef addUserScriptCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + if (argumentCount != 2) + return JSValueMakeUndefined(context); + + JSRetainPtr<JSStringRef> source(Adopt, JSValueToStringCopy(context, arguments[0], exception)); + ASSERT(!*exception); + bool runAtStart = JSValueToBoolean(context, arguments[1]); + + LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); + controller->addUserScript(source.get(), runAtStart); + return JSValueMakeUndefined(context); +} + +static JSValueRef addUserStyleSheetCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + if (argumentCount != 1) + return JSValueMakeUndefined(context); + + JSRetainPtr<JSStringRef> source(Adopt, JSValueToStringCopy(context, arguments[0], exception)); + ASSERT(!*exception); + + LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); + controller->addUserStyleSheet(source.get()); + return JSValueMakeUndefined(context); +} + // Static Values static JSValueRef getGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) @@ -858,6 +1086,12 @@ static JSValueRef getWebHistoryItemCountCallback(JSContextRef context, JSObjectR return JSValueMakeNumber(context, controller->webHistoryItemCount()); } +static JSValueRef getWorkerThreadCountCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); + return JSValueMakeNumber(context, controller->workerThreadCount()); +} + static bool setGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) { LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); @@ -904,6 +1138,7 @@ JSStaticValue* LayoutTestController::staticValues() static JSStaticValue staticValues[] = { { "globalFlag", getGlobalFlagCallback, setGlobalFlagCallback, kJSPropertyAttributeNone }, { "webHistoryItemCount", getWebHistoryItemCountCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "workerThreadCount", getWorkerThreadCountCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { 0, 0, 0, 0 } }; return staticValues; @@ -913,9 +1148,12 @@ JSStaticFunction* LayoutTestController::staticFunctions() { static JSStaticFunction staticFunctions[] = { { "addDisallowedURL", addDisallowedURLCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "addUserScript", addUserScriptCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "addUserStyleSheet", addUserStyleSheetCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "clearAllDatabases", clearAllDatabasesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "clearBackForwardList", clearBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "clearPersistentUserStyleSheet", clearPersistentUserStyleSheetCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "closeWebInspector", closeWebInspectorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "decodeHostName", decodeHostNameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "disableImageLoading", disableImageLoadingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "dispatchPendingLoadRequests", dispatchPendingLoadRequestsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, @@ -927,6 +1165,7 @@ JSStaticFunction* LayoutTestController::staticFunctions() { "dumpDOMAsWebArchive", dumpDOMAsWebArchiveCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "dumpDatabaseCallbacks", dumpDatabaseCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "dumpEditingCallbacks", dumpEditingCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "dumpFrameLoadCallbacks", dumpFrameLoadCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "dumpResourceLoadCallbacks", dumpResourceLoadCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "dumpResourceResponseMIMETypes", dumpResourceResponseMIMETypesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "dumpSelectionRect", dumpSelectionRectCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, @@ -936,11 +1175,14 @@ JSStaticFunction* LayoutTestController::staticFunctions() { "dumpWillCacheResponse", dumpWillCacheResponseCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "elementDoesAutoCompleteForElementWithId", elementDoesAutoCompleteForElementWithIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "encodeHostName", encodeHostNameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "evaluateInWebInspector", evaluateInWebInspectorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "execCommand", execCommandCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "grantDesktopNotificationPermission", grantDesktopNotificationPermissionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "isCommandEnabled", isCommandEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "keepWebHistory", keepWebHistoryCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "notifyDone", notifyDoneCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "numberOfActiveAnimations", numberOfActiveAnimationsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "overridePreference", overridePreferenceCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "pathToLocalResource", pathToLocalResourceCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "pauseAnimationAtTimeOnElementWithId", pauseAnimationAtTimeOnElementWithIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "pauseTransitionAtTimeOnElementWithId", pauseTransitionAtTimeOnElementWithIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, @@ -953,17 +1195,25 @@ JSStaticFunction* LayoutTestController::staticFunctions() { "queueReload", queueReloadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "repaintSweepHorizontally", repaintSweepHorizontallyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setAcceptsEditing", setAcceptsEditingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "setAuthorAndUserStylesEnabled", setAuthorAndUserStylesEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "setAlwaysAcceptCookies", setAlwaysAcceptCookiesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setAppCacheMaximumSize", setAppCacheMaximumSizeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "setAuthenticationPassword", setAuthenticationPasswordCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "setAuthenticationUsername", setAuthenticationUsernameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "setAuthorAndUserStylesEnabled", setAuthorAndUserStylesEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setCallCloseOnWebViews", setCallCloseOnWebViewsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setCanOpenWindows", setCanOpenWindowsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setCacheModel", setCacheModelCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setCloseRemainingWindowsWhenComplete", setCloseRemainingWindowsWhenCompleteCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setCustomPolicyDelegate", setCustomPolicyDelegateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setDatabaseQuota", setDatabaseQuotaCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "setGeolocationPermission", setGeolocationPermissionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "setHandlesAuthenticationChallenges", setHandlesAuthenticationChallengesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "setPOSIXLocale", setPOSIXLocaleCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setIconDatabaseEnabled", setIconDatabaseEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setJavaScriptProfilingEnabled", setJavaScriptProfilingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setMainFrameIsFirstResponder", setMainFrameIsFirstResponderCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "setMockGeolocationPosition", setMockGeolocationPositionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "setMockGeolocationError", setMockGeolocationErrorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setPersistentUserStyleSheetLocation", setPersistentUserStyleSheetLocationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setPopupBlockingEnabled", setPopupBlockingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setPrivateBrowsingEnabled", setPrivateBrowsingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, @@ -977,11 +1227,13 @@ JSStaticFunction* LayoutTestController::staticFunctions() { "setUserStyleSheetLocation", setUserStyleSheetLocationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setWillSendRequestReturnsNullOnRedirect", setWillSendRequestReturnsNullOnRedirectCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setWindowIsKey", setWindowIsKeyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "showWebInspector", showWebInspectorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "testOnscreen", testOnscreenCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "testRepaint", testRepaintCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "waitForPolicyDelegate", waitForPolicyDelegateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "waitUntilDone", waitUntilDoneCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "windowCount", windowCountCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "whiteListAccessFromOrigin", whiteListAccessFromOriginCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { 0, 0, 0 } }; @@ -1012,3 +1264,41 @@ void LayoutTestController::queueReload() { WorkQueue::shared()->queue(new ReloadItem); } + +void LayoutTestController::grantDesktopNotificationPermission(JSStringRef origin) +{ + m_desktopNotificationAllowedOrigins.push_back(JSStringRetain(origin)); +} + +bool LayoutTestController::checkDesktopNotificationPermission(JSStringRef origin) +{ + std::vector<JSStringRef>::iterator i; + for (i = m_desktopNotificationAllowedOrigins.begin(); + i != m_desktopNotificationAllowedOrigins.end(); + ++i) { + if (JSStringIsEqual(*i, origin)) + return true; + } + return false; +} + +void LayoutTestController::waitToDumpWatchdogTimerFired() +{ + const char* message = "FAIL: Timed out waiting for notifyDone to be called\n"; + fprintf(stderr, "%s", message); + fprintf(stdout, "%s", message); + notifyDone(); +} + +void LayoutTestController::setGeolocationPermission(bool allow) +{ + m_isGeolocationPermissionSet = true; + m_geolocationPermission = allow; +} + +void LayoutTestController::setPOSIXLocale(JSStringRef locale) +{ + char localeBuf[32]; + JSStringGetUTF8CString(locale, localeBuf, sizeof(localeBuf)); + setlocale(LC_ALL, localeBuf); +} diff --git a/WebKitTools/DumpRenderTree/LayoutTestController.h b/WebKitTools/DumpRenderTree/LayoutTestController.h index 5bc9d61..7c829ef 100644 --- a/WebKitTools/DumpRenderTree/LayoutTestController.h +++ b/WebKitTools/DumpRenderTree/LayoutTestController.h @@ -32,6 +32,7 @@ #include <JavaScriptCore/JSObjectRef.h> #include <wtf/RefCounted.h> #include <string> +#include <vector> class LayoutTestController : public RefCounted<LayoutTestController> { public: @@ -53,6 +54,7 @@ public: bool isCommandEnabled(JSStringRef name); void keepWebHistory(); void notifyDone(); + void overridePreference(JSStringRef key, JSStringRef value); JSStringRef pathToLocalResource(JSContextRef, JSStringRef url); void queueBackNavigation(int howFarBackward); void queueForwardNavigation(int howFarForward); @@ -66,6 +68,8 @@ public: void setCacheModel(int); void setCustomPolicyDelegate(bool setDelegate, bool permissive); void setDatabaseQuota(unsigned long long quota); + void setMockGeolocationPosition(double latitude, double longitude, double accuracy); + void setMockGeolocationError(int code, JSStringRef message); void setIconDatabaseEnabled(bool iconDatabaseEnabled); void setJavaScriptProfilingEnabled(bool profilingEnabled); void setMainFrameIsFirstResponder(bool flag); @@ -81,15 +85,19 @@ public: void setUserStyleSheetLocation(JSStringRef path); void waitForPolicyDelegate(); size_t webHistoryItemCount(); + unsigned workerThreadCount() const; int windowCount(); - bool elementDoesAutoCompleteForElementWithId(JSStringRef id); + void grantDesktopNotificationPermission(JSStringRef origin); + bool checkDesktopNotificationPermission(JSStringRef origin); - bool dumpAsText() const { return m_dumpAsText; } - void setDumpAsText(bool dumpAsText) { m_dumpAsText = dumpAsText; } + bool elementDoesAutoCompleteForElementWithId(JSStringRef id); bool dumpAsPDF() const { return m_dumpAsPDF; } void setDumpAsPDF(bool dumpAsPDF) { m_dumpAsPDF = dumpAsPDF; } + + 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; } @@ -103,36 +111,36 @@ public: 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 dumpFrameLoadCallbacks() const { return m_dumpFrameLoadCallbacks; } + void setDumpFrameLoadCallbacks(bool dumpFrameLoadCallbacks) { m_dumpFrameLoadCallbacks = dumpFrameLoadCallbacks; } + bool dumpResourceLoadCallbacks() const { return m_dumpResourceLoadCallbacks; } void setDumpResourceLoadCallbacks(bool dumpResourceLoadCallbacks) { m_dumpResourceLoadCallbacks = dumpResourceLoadCallbacks; } bool dumpResourceResponseMIMETypes() const { return m_dumpResourceResponseMIMETypes; } void setDumpResourceResponseMIMETypes(bool dumpResourceResponseMIMETypes) { m_dumpResourceResponseMIMETypes = dumpResourceResponseMIMETypes; } - bool dumpWillCacheResponse() const { return m_dumpWillCacheResponse; } - void setDumpWillCacheResponse(bool dumpWillCacheResponse) { m_dumpWillCacheResponse = dumpWillCacheResponse; } + bool dumpSelectionRect() const { return m_dumpSelectionRect; } + void setDumpSelectionRect(bool dumpSelectionRect) { m_dumpSelectionRect = dumpSelectionRect; } - bool dumpFrameLoadCallbacks() const { return m_dumpFrameLoadCallbacks; } - void setDumpFrameLoadCallbacks(bool dumpFrameLoadCallbacks) { m_dumpFrameLoadCallbacks = dumpFrameLoadCallbacks; } + bool dumpSourceAsWebArchive() const { return m_dumpSourceAsWebArchive; } + void setDumpSourceAsWebArchive(bool dumpSourceAsWebArchive) { m_dumpSourceAsWebArchive = dumpSourceAsWebArchive; } + + bool dumpStatusCallbacks() const { return m_dumpStatusCallbacks; } + void setDumpStatusCallbacks(bool dumpStatusCallbacks) { m_dumpStatusCallbacks = dumpStatusCallbacks; } + bool dumpTitleChanges() const { return m_dumpTitleChanges; } + void setDumpTitleChanges(bool dumpTitleChanges) { m_dumpTitleChanges = dumpTitleChanges; } + + bool dumpWillCacheResponse() const { return m_dumpWillCacheResponse; } + void setDumpWillCacheResponse(bool dumpWillCacheResponse) { m_dumpWillCacheResponse = dumpWillCacheResponse; } + bool callCloseOnWebViews() const { return m_callCloseOnWebViews; } void setCallCloseOnWebViews(bool callCloseOnWebViews) { m_callCloseOnWebViews = callCloseOnWebViews; } @@ -156,6 +164,7 @@ public: bool waitToDump() const { return m_waitToDump; } void setWaitToDump(bool waitToDump); + void waitToDumpWatchdogTimerFired(); bool willSendRequestReturnsNullOnRedirect() const { return m_willSendRequestReturnsNullOnRedirect; } void setWillSendRequestReturnsNullOnRedirect(bool returnsNull) { m_willSendRequestReturnsNullOnRedirect = returnsNull; } @@ -163,6 +172,18 @@ public: bool windowIsKey() const { return m_windowIsKey; } void setWindowIsKey(bool windowIsKey); + bool alwaysAcceptCookies() const { return m_alwaysAcceptCookies; } + void setAlwaysAcceptCookies(bool alwaysAcceptCookies); + + bool handlesAuthenticationChallenges() const { return m_handlesAuthenticationChallenges; } + void setHandlesAuthenticationChallenges(bool handlesAuthenticationChallenges) { m_handlesAuthenticationChallenges = handlesAuthenticationChallenges; } + + const std::string& authenticationUsername() const { return m_authenticationUsername; } + void setAuthenticationUsername(std::string username) { m_authenticationUsername = username; } + + const std::string& authenticationPassword() const { return m_authenticationPassword; } + void setAuthenticationPassword(std::string password) { m_authenticationPassword = password; } + bool globalFlag() const { return m_globalFlag; } void setGlobalFlag(bool globalFlag) { m_globalFlag = globalFlag; } @@ -172,24 +193,39 @@ public: bool pauseAnimationAtTimeOnElementWithId(JSStringRef animationName, double time, JSStringRef elementId); bool pauseTransitionAtTimeOnElementWithId(JSStringRef propertyName, double time, JSStringRef elementId); unsigned numberOfActiveAnimations() const; - + + void whiteListAccessFromOrigin(JSStringRef sourceOrigin, JSStringRef destinationProtocol, JSStringRef destinationHost, bool allowDestinationSubdomains); + + void addUserScript(JSStringRef source, bool runAtStart); + void addUserStyleSheet(JSStringRef source); + + void setGeolocationPermission(bool allow); + bool isGeolocationPermissionSet() const { return m_isGeolocationPermissionSet; } + bool geolocationPermission() const { return m_geolocationPermission; } + + void showWebInspector(); + void closeWebInspector(); + void evaluateInWebInspector(long callId, JSStringRef script); + + void setPOSIXLocale(JSStringRef locale); + private: - bool m_dumpAsText; bool m_dumpAsPDF; + bool m_dumpAsText; bool m_dumpBackForwardList; bool m_dumpChildFrameScrollPositions; bool m_dumpChildFramesAsText; - bool m_dumpDatabaseCallbacks; bool m_dumpDOMAsWebArchive; + bool m_dumpDatabaseCallbacks; + bool m_dumpEditingCallbacks; + bool m_dumpFrameLoadCallbacks; + bool m_dumpResourceLoadCallbacks; + bool m_dumpResourceResponseMIMETypes; bool m_dumpSelectionRect; bool m_dumpSourceAsWebArchive; bool m_dumpStatusCallbacks; bool m_dumpTitleChanges; - bool m_dumpEditingCallbacks; - bool m_dumpResourceLoadCallbacks; - bool m_dumpResourceResponseMIMETypes; bool m_dumpWillCacheResponse; - bool m_dumpFrameLoadCallbacks; bool m_callCloseOnWebViews; bool m_canOpenWindows; bool m_closeRemainingWindowsWhenComplete; @@ -200,12 +236,20 @@ private: bool m_waitToDump; // True if waitUntilDone() has been called, but notifyDone() has not yet been called. bool m_willSendRequestReturnsNullOnRedirect; bool m_windowIsKey; - + bool m_alwaysAcceptCookies; bool m_globalFlag; + bool m_isGeolocationPermissionSet; + bool m_geolocationPermission; + bool m_handlesAuthenticationChallenges; + std::string m_authenticationUsername; + std::string m_authenticationPassword; std::string m_testPathOrURL; std::string m_expectedPixelHash; // empty string if no hash + // origins which have been granted desktop notification access + std::vector<JSStringRef> m_desktopNotificationAllowedOrigins; + static JSClassRef getJSClass(); static JSStaticValue* staticValues(); static JSStaticFunction* staticFunctions(); diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/TestObject.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/TestObject.cpp index af60df4..0b32191 100644 --- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/TestObject.cpp +++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/TestObject.cpp @@ -87,7 +87,7 @@ static void initializeIdentifiers(void) browser->getstringidentifiers(testMethodIdentifierNames, NUM_METHOD_IDENTIFIERS, testMethodIdentifiers); } -static NPObject *testAllocate(NPP npp, NPClass *theClass) +static NPObject *testAllocate(NPP /*npp*/, NPClass* /*theClass*/) { NPObject *newInstance = static_cast<NPObject*>(malloc(sizeof(NPObject))); @@ -113,7 +113,7 @@ static bool testHasMethod(NPObject*, NPIdentifier name) return false; } -static bool testInvoke(NPObject* header, NPIdentifier name, const NPVariant* args, uint32_t argCount, NPVariant* result) +static bool testInvoke(NPObject* header, NPIdentifier name, const NPVariant* /*args*/, uint32_t /*argCount*/, NPVariant* /*result*/) { if (name == testMethodIdentifiers[ID_THROW_EXCEPTION_METHOD]) { browser->setexception(header, "test object throwException SUCCESS"); @@ -145,7 +145,7 @@ static bool testGetProperty(NPObject* npobj, NPIdentifier name, NPVariant* resul } -static bool testEnumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count) +static bool testEnumerate(NPObject* /*npobj*/, NPIdentifier **value, uint32_t *count) { *count = NUM_ENUMERATABLE_TEST_IDENTIFIERS; @@ -155,7 +155,7 @@ static bool testEnumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count return true; } -static bool testConstruct(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result) +static bool testConstruct(NPObject* npobj, const NPVariant* /*args*/, uint32_t /*argCount*/, NPVariant* result) { browser->retainobject(npobj); diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/main.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/main.cpp index 704ba09..88618c3 100644 --- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/main.cpp +++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/main.cpp @@ -64,6 +64,8 @@ void NP_Shutdown(void) { } +static void executeScript(const PluginObject* obj, const char* script); + NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char *argn[], char *argv[], NPSavedData *saved) { bool forceCarbon = false; @@ -101,7 +103,8 @@ NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, ch for (int i = 0; i < argc; i++) if (strcasecmp(argn[i], "src") == 0) pluginLog(instance, "src: %s", argv[i]); - } + } else if (strcasecmp(argn[i], "cleardocumentduringnew") == 0) + executeScript(obj, "document.body.innerHTML = ''"); } #ifndef NP_NO_CARBON diff --git a/WebKitTools/DumpRenderTree/fonts/WebKit Layout Tests 2.ttf b/WebKitTools/DumpRenderTree/fonts/WebKit Layout Tests 2.ttf Binary files differnew file mode 100644 index 0000000..e732fbc --- /dev/null +++ b/WebKitTools/DumpRenderTree/fonts/WebKit Layout Tests 2.ttf diff --git a/WebKitTools/DumpRenderTree/fonts/WebKit Layout Tests.ttf b/WebKitTools/DumpRenderTree/fonts/WebKit Layout Tests.ttf Binary files differnew file mode 100644 index 0000000..f9f997e --- /dev/null +++ b/WebKitTools/DumpRenderTree/fonts/WebKit Layout Tests.ttf diff --git a/WebKitTools/DumpRenderTree/gtk/AccessibilityControllerGtk.cpp b/WebKitTools/DumpRenderTree/gtk/AccessibilityControllerGtk.cpp index ab92e1d..593f2eb 100644 --- a/WebKitTools/DumpRenderTree/gtk/AccessibilityControllerGtk.cpp +++ b/WebKitTools/DumpRenderTree/gtk/AccessibilityControllerGtk.cpp @@ -61,3 +61,11 @@ AccessibilityUIElement AccessibilityController::rootElement() AtkObject* axObject = gtk_widget_get_accessible(GTK_WIDGET(view)); return AccessibilityUIElement(axObject); } + +void AccessibilityController::setLogFocusEvents(bool) +{ +} + +void AccessibilityController::setLogScrollingStartEvents(bool) +{ +} diff --git a/WebKitTools/DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp b/WebKitTools/DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp index be1bbed..9aa31a8 100644 --- a/WebKitTools/DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp +++ b/WebKitTools/DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp @@ -67,9 +67,9 @@ void AccessibilityUIElement::getChildren(Vector<AccessibilityUIElement>& childre } } -void AccessibilityUIElement::getChildrenWithRange(Vector<AccessibilityUIElement>& elementVector, unsigned location, unsigned length) +void AccessibilityUIElement::getChildrenWithRange(Vector<AccessibilityUIElement>& elementVector, unsigned start, unsigned end) { - for (unsigned i = location; i < length; i++) { + for (unsigned i = start; i < end; i++) { AtkObject* child = atk_object_ref_accessible_child(ATK_OBJECT(m_element), i); elementVector.append(AccessibilityUIElement(child)); } @@ -94,7 +94,7 @@ AccessibilityUIElement AccessibilityUIElement::elementAtPoint(int x, int y) AccessibilityUIElement AccessibilityUIElement::getChildAtIndex(unsigned index) { Vector<AccessibilityUIElement> children; - getChildrenWithRange(children, index, 1); + getChildrenWithRange(children, index, index + 1); if (children.size() == 1) return children.at(0); @@ -156,6 +156,11 @@ JSStringRef AccessibilityUIElement::role() return JSStringCreateWithUTF8CString(atk_role_get_name(role)); } +JSStringRef AccessibilityUIElement::subrole() +{ + return 0; +} + JSStringRef AccessibilityUIElement::title() { const gchar* name = atk_object_get_name(ATK_OBJECT(m_element)); @@ -377,6 +382,12 @@ JSStringRef AccessibilityUIElement::boundsForRange(unsigned location, unsigned l return JSStringCreateWithCharacters(0, 0); } +JSStringRef AccessibilityUIElement::stringForRange(unsigned, unsigned) +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + AccessibilityUIElement AccessibilityUIElement::cellForColumnAndRow(unsigned column, unsigned row) { // FIXME: implement diff --git a/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp b/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp index ac82dd8..6ecd774 100644 --- a/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp +++ b/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp @@ -32,6 +32,7 @@ #include "DumpRenderTree.h" #include "AccessibilityController.h" +#include "EventSender.h" #include "GCController.h" #include "LayoutTestController.h" #include "WorkQueue.h" @@ -43,6 +44,10 @@ #include <wtf/Assertions.h> +#if PLATFORM(X11) +#include <fontconfig/fontconfig.h> +#endif + #include <cassert> #include <getopt.h> #include <stdlib.h> @@ -58,10 +63,12 @@ extern GList* webkit_web_history_item_get_children(WebKitWebHistoryItem*); extern GSList* webkit_web_frame_get_children(WebKitWebFrame* frame); extern gchar* webkit_web_frame_get_inner_text(WebKitWebFrame* frame); extern gchar* webkit_web_frame_dump_render_tree(WebKitWebFrame* frame); +extern guint webkit_web_frame_get_pending_unload_event_count(WebKitWebFrame* frame); extern void webkit_web_settings_add_extra_plugin_directory(WebKitWebView* view, const gchar* directory); extern gchar* webkit_web_frame_get_response_mime_type(WebKitWebFrame* frame); extern void webkit_web_frame_clear_main_frame_name(WebKitWebFrame* frame); extern void webkit_web_view_set_group_name(WebKitWebView* view, const gchar* groupName); +extern void webkit_reset_origin_access_white_lists(); } volatile bool done; @@ -73,6 +80,7 @@ AccessibilityController* axController = 0; LayoutTestController* gLayoutTestController = 0; static GCController* gcController = 0; static WebKitWebView* webView; +static GtkWidget* window; static GtkWidget* container; WebKitWebFrame* mainFrame = 0; WebKitWebFrame* topLoadingFrame = 0; @@ -122,6 +130,41 @@ static void appendString(gchar*& target, gchar* string) g_free(oldString); } +#if PLATFORM(X11) +static void initializeFonts() +{ + static int numFonts = -1; + + // Some tests may add or remove fonts via the @font-face rule. + // If that happens, font config should be re-created to suppress any unwanted change. + FcFontSet* appFontSet = FcConfigGetFonts(0, FcSetApplication); + if (appFontSet && numFonts >= 0 && appFontSet->nfont == numFonts) + return; + + const char* fontDirEnv = g_getenv("WEBKIT_TESTFONTS"); + if (!fontDirEnv) + g_error("WEBKIT_TESTFONTS environment variable is not set, but it should point to the directory " + "containing the fonts you can clone from git://gitorious.org/qtwebkit/testfonts.git\n"); + + GFile* fontDir = g_file_new_for_path(fontDirEnv); + if (!fontDir || !g_file_query_exists(fontDir, NULL)) + g_error("WEBKIT_TESTFONTS environment variable is not set correctly - it should point to the directory " + "containing the fonts you can clone from git://gitorious.org/qtwebkit/testfonts.git\n"); + + FcConfig *config = FcConfigCreate(); + if (!FcConfigParseAndLoad (config, (FcChar8*) FONTS_CONF_FILE, true)) + g_error("Couldn't load font configuration file"); + if (!FcConfigAppFontAddDir (config, (FcChar8*) g_file_get_path(fontDir))) + g_error("Couldn't add font dir!"); + FcConfigSetCurrent(config); + + g_object_unref(fontDir); + + appFontSet = FcConfigGetFonts(config, FcSetApplication); + numFonts = appFontSet->nfont; +} +#endif + static gchar* dumpFramesAsText(WebKitWebFrame* frame) { gchar* result = 0; @@ -262,7 +305,7 @@ static void invalidateAnyPreviousWaitToDumpWatchdog() waitForPolicy = false; } -static void resetWebViewToConsistentStateBeforeTesting() +static void resetDefaultsToConsistentValues() { WebKitWebSettings* settings = webkit_web_view_get_settings(webView); g_object_set(G_OBJECT(settings), @@ -274,12 +317,25 @@ static void resetWebViewToConsistentStateBeforeTesting() "enable-xss-auditor", FALSE, "javascript-can-open-windows-automatically", TRUE, "enable-offline-web-application-cache", TRUE, + "enable-universal-access-from-file-uris", TRUE, + "enable-scripts", TRUE, + "default-font-family", "Times", + "monospace-font-family", "Courier", + "serif-font-family", "Times", + "sans-serif-font-family", "Helvetica", + "default-font-size", 16, + "default-monospace-font-size", 13, + "minimum-font-size", 1, NULL); webkit_web_frame_clear_main_frame_name(mainFrame); WebKitWebInspector* inspector = webkit_web_view_get_inspector(webView); g_object_set(G_OBJECT(inspector), "javascript-profiling-enabled", FALSE, NULL); + + webkit_reset_origin_access_white_lists(); + + setlocale(LC_ALL, ""); } void dump() @@ -354,16 +410,7 @@ static void setDefaultsToConsistentStateValuesForTesting() { gdk_screen_set_resolution(gdk_screen_get_default(), 72.0); - WebKitWebSettings* settings = webkit_web_view_get_settings(webView); - g_object_set(G_OBJECT(settings), - "default-font-family", "Times", - "monospace-font-family", "Courier", - "serif-font-family", "Times", - "sans-serif-font-family", "Helvetica", - "default-font-size", 16, - "default-monospace-font-size", 13, - "minimum-font-size", 1, - NULL); + resetDefaultsToConsistentValues(); /* Disable the default auth dialog for testing */ SoupSession* session = webkit_get_default_session(); @@ -372,6 +419,10 @@ static void setDefaultsToConsistentStateValuesForTesting() #if PLATFORM(X11) webkit_web_settings_add_extra_plugin_directory(webView, TEST_PLUGIN_DIR); #endif + + gchar* databaseDirectory = g_build_filename(g_get_user_data_dir(), "gtkwebkitdrt", "databases", NULL); + webkit_set_web_database_directory_path(databaseDirectory); + g_free(databaseDirectory); } static void runTest(const string& testPathOrURL) @@ -391,7 +442,7 @@ static void runTest(const string& testPathOrURL) gchar* url = autocorrectURL(pathOrURL.c_str()); const string testURL(url); - resetWebViewToConsistentStateBeforeTesting(); + resetDefaultsToConsistentValues(); gLayoutTestController = new LayoutTestController(testURL, expectedPixelHash); topLoadingFrame = 0; @@ -407,8 +458,10 @@ static void runTest(const string& testPathOrURL) bool isSVGW3CTest = (gLayoutTestController->testPathOrURL().find("svg/W3C-SVG-1.1") != string::npos); GtkAllocation size; + size.x = size.y = 0; size.width = isSVGW3CTest ? 480 : maxViewWidth; size.height = isSVGW3CTest ? 360 : maxViewHeight; + gtk_window_resize(GTK_WINDOW(window), size.width, size.height); gtk_widget_size_allocate(container, &size); if (prevTestBFItem) @@ -418,7 +471,12 @@ static void runTest(const string& testPathOrURL) if (prevTestBFItem) g_object_ref(prevTestBFItem); +#if PLATFORM(X11) + initializeFonts(); +#endif + // Focus the web view before loading the test to avoid focusing problems + gtk_widget_grab_focus(GTK_WIDGET(webView)); webkit_web_view_open(webView, url); g_free(url); @@ -462,8 +520,39 @@ static gboolean processWork(void* data) return FALSE; } +static char* getFrameNameSuitableForTestResult(WebKitWebView* view, WebKitWebFrame* frame) +{ + char* frameName = g_strdup(webkit_web_frame_get_name(frame)); + + if (frame == webkit_web_view_get_main_frame(view)) { + // This is a bit strange. Shouldn't web_frame_get_name return NULL? + if (frameName && (frameName[0] != '\0')) { + char* tmp = g_strdup_printf("main frame \"%s\"", frameName); + g_free (frameName); + frameName = tmp; + } else { + g_free(frameName); + frameName = g_strdup("main frame"); + } + } else if (!frameName || (frameName[0] == '\0')) { + g_free(frameName); + frameName = g_strdup("frame (anonymous)"); + } + + return frameName; +} + static void webViewLoadFinished(WebKitWebView* view, WebKitWebFrame* frame, void*) { + if (!done && !gLayoutTestController->dumpFrameLoadCallbacks()) { + guint pendingFrameUnloadEvents = webkit_web_frame_get_pending_unload_event_count(frame); + if (pendingFrameUnloadEvents) { + char* frameName = getFrameNameSuitableForTestResult(view, frame); + printf("%s - has %u onunload handler(s)\n", frameName, pendingFrameUnloadEvents); + g_free(frameName); + } + } + if (frame != topLoadingFrame) return; @@ -492,6 +581,10 @@ static void webViewWindowObjectCleared(WebKitWebView* view, WebKitWebFrame* fram axController->makeWindowObject(context, windowObject, &exception); ASSERT(!exception); + JSStringRef eventSenderStr = JSStringCreateWithUTF8CString("eventSender"); + JSValueRef eventSender = makeEventSender(context); + JSObjectSetProperty(context, windowObject, eventSenderStr, eventSender, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, 0); + JSStringRelease(eventSenderStr); } static gboolean webViewConsoleMessage(WebKitWebView* view, const gchar* message, unsigned int line, const gchar* sourceId, gpointer data) @@ -593,6 +686,23 @@ static gboolean webViewClose(WebKitWebView* view) return TRUE; } +static void databaseQuotaExceeded(WebKitWebView* view, WebKitWebFrame* frame, WebKitWebDatabase *database) +{ + ASSERT(view); + ASSERT(frame); + ASSERT(database); + + WebKitSecurityOrigin* origin = webkit_web_database_get_security_origin(database); + if (gLayoutTestController->dumpDatabaseCallbacks()) { + printf("UI DELEGATE DATABASE CALLBACK: exceededDatabaseQuotaForSecurityOrigin:{%s, %s, %i} database:%s\n", + webkit_security_origin_get_protocol(origin), + webkit_security_origin_get_host(origin), + webkit_security_origin_get_port(origin), + webkit_web_database_get_name(database)); + } + webkit_security_origin_set_web_database_quota(origin, 5 * 1024 * 1024); +} + static WebKitWebView* webViewCreate(WebKitWebView*, WebKitWebFrame*); @@ -617,6 +727,7 @@ static WebKitWebView* createWebView() "signal::status-bar-text-changed", webViewStatusBarTextChanged, 0, "signal::create-web-view", webViewCreate, 0, "signal::close-web-view", webViewClose, 0, + "signal::database-quota-exceeded", databaseQuotaExceeded, 0, NULL); return view; @@ -641,6 +752,11 @@ int main(int argc, char* argv[]) g_thread_init(NULL); gtk_init(&argc, &argv); +#if PLATFORM(X11) + FcInit(); + initializeFonts(); +#endif + struct option options[] = { {"notree", no_argument, &dumpTree, false}, {"pixel-tests", no_argument, &dumpPixels, true}, @@ -657,11 +773,11 @@ int main(int argc, char* argv[]) break; } - GtkWidget* window = gtk_window_new(GTK_WINDOW_POPUP); + window = gtk_window_new(GTK_WINDOW_POPUP); container = GTK_WIDGET(gtk_scrolled_window_new(NULL, NULL)); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(container), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_add(GTK_CONTAINER(window), container); - gtk_widget_realize(window); + gtk_widget_show_all(window); webView = createWebView(); gtk_container_add(GTK_CONTAINER(container), GTK_WIDGET(webView)); @@ -699,7 +815,7 @@ int main(int argc, char* argv[]) delete axController; axController = 0; - g_object_unref(webView); + gtk_widget_destroy(window); return 0; } diff --git a/WebKitTools/DumpRenderTree/gtk/EventSender.cpp b/WebKitTools/DumpRenderTree/gtk/EventSender.cpp new file mode 100644 index 0000000..c3c72c1 --- /dev/null +++ b/WebKitTools/DumpRenderTree/gtk/EventSender.cpp @@ -0,0 +1,545 @@ +/* + * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2009 Zan Dobersek <zandobersek@gmail.com> + * Copyright (C) 2009 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. + */ + +#include "config.h" +#include "EventSender.h" + +#include "DumpRenderTree.h" + +#include <JavaScriptCore/JSObjectRef.h> +#include <JavaScriptCore/JSRetainPtr.h> +#include <JavaScriptCore/JSStringRef.h> +#include <webkit/webkitwebframe.h> +#include <webkit/webkitwebview.h> +#include <wtf/ASCIICType.h> +#include <wtf/Platform.h> + +#include <gdk/gdk.h> +#include <gdk/gdkkeysyms.h> +#include <string.h> + +// TODO: Currently drag and drop related code is left out and +// should be merged once we have drag and drop support in WebCore. + +extern "C" { + extern void webkit_web_frame_layout(WebKitWebFrame* frame); +} + +static bool down = false; +static bool dragMode = true; +static bool replayingSavedEvents = false; +static int lastMousePositionX; +static int lastMousePositionY; + +static int lastClickPositionX; +static int lastClickPositionY; +static int clickCount = 0; + +struct DelayedMessage { + GdkEvent event; + gulong delay; + gboolean isDragEvent; +}; + +static DelayedMessage msgQueue[1024]; + +static unsigned endOfQueue; +static unsigned startOfQueue; + +static const float zoomMultiplierRatio = 1.2f; + +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 leapForwardCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + // FIXME: Add proper support for forward leaps + return JSValueMakeUndefined(context); +} + +static JSValueRef contextClickCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + webkit_web_frame_layout(mainFrame); + + WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); + if (!view) + return JSValueMakeUndefined(context); + + GdkEvent event; + memset(&event, 0, sizeof(event)); + event.button.button = 3; + event.button.x = lastMousePositionX; + event.button.y = lastMousePositionY; + event.button.window = GTK_WIDGET(view)->window; + + gboolean return_val; + down = true; + event.type = GDK_BUTTON_PRESS; + g_signal_emit_by_name(view, "button_press_event", &event, &return_val); + + down = false; + event.type = GDK_BUTTON_RELEASE; + g_signal_emit_by_name(view, "button_release_event", &event, &return_val); + + return JSValueMakeUndefined(context); +} + +static void updateClickCount(int /* button */) +{ + // FIXME: take the last clicked button number and the time of last click into account. + if (lastClickPositionX != lastMousePositionX && lastClickPositionY != lastMousePositionY) + clickCount = 1; + else + clickCount++; +} + +static JSValueRef mouseDownCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); + if (!view) + return JSValueMakeUndefined(context); + + down = true; + + GdkEvent event; + memset(&event, 0, sizeof(event)); + event.type = GDK_BUTTON_PRESS; + event.button.button = 1; + event.button.x = lastMousePositionX; + event.button.y = lastMousePositionY; + event.button.window = GTK_WIDGET(view)->window; + + updateClickCount(1); + + if (!msgQueue[endOfQueue].delay) { + webkit_web_frame_layout(mainFrame); + + gboolean return_val; + g_signal_emit_by_name(view, "button_press_event", &event, &return_val); + if (clickCount == 2) { + event.type = GDK_2BUTTON_PRESS; + g_signal_emit_by_name(view, "button_press_event", &event, &return_val); + } + } else { + // replaySavedEvents should have the required logic to make leapForward delays work + msgQueue[endOfQueue++].event = event; + replaySavedEvents(); + } + + return JSValueMakeUndefined(context); +} + +static JSValueRef mouseUpCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + + WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); + if (!view) + return JSValueMakeUndefined(context); + + down = false; + + GdkEvent event; + memset(&event, 0, sizeof(event)); + event.type = GDK_BUTTON_RELEASE; + event.button.button = 1; + event.button.x = lastMousePositionX; + event.button.y = lastMousePositionY; + event.button.window = GTK_WIDGET(view)->window; + + if ((dragMode && !replayingSavedEvents) || msgQueue[endOfQueue].delay) { + msgQueue[endOfQueue].event = event; + msgQueue[endOfQueue++].isDragEvent = true; + replaySavedEvents(); + } else { + webkit_web_frame_layout(mainFrame); + + gboolean return_val; + g_signal_emit_by_name(view, "button_release_event", &event, &return_val); + } + + lastClickPositionX = lastMousePositionX; + lastClickPositionY = lastMousePositionY; + + return JSValueMakeUndefined(context); +} + +static JSValueRef mouseMoveToCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); + if (!view) + return JSValueMakeUndefined(context); + + if (argumentCount < 2) + return JSValueMakeUndefined(context); + + lastMousePositionX = (int)JSValueToNumber(context, arguments[0], exception); + g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context)); + lastMousePositionY = (int)JSValueToNumber(context, arguments[1], exception); + g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context)); + + GdkEvent event; + event.type = GDK_MOTION_NOTIFY; + event.motion.x = lastMousePositionX; + event.motion.y = lastMousePositionY; + event.motion.time = GDK_CURRENT_TIME; + event.motion.window = GTK_WIDGET(view)->window; + + if (dragMode && down && !replayingSavedEvents) { + msgQueue[endOfQueue].event = event; + msgQueue[endOfQueue++].isDragEvent = true; + } else { + webkit_web_frame_layout(mainFrame); + + gboolean return_val; + g_signal_emit_by_name(view, "motion_notify_event", &event, &return_val); + } + + return JSValueMakeUndefined(context); +} + +static JSValueRef mouseWheelToCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); + if (!view) + return JSValueMakeUndefined(context); + + if (argumentCount < 2) + return JSValueMakeUndefined(context); + + int horizontal = (int)JSValueToNumber(context, arguments[0], exception); + g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context)); + int vertical = (int)JSValueToNumber(context, arguments[1], exception); + g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context)); + + // GTK+ doesn't support multiple direction scrolls in the same event! + g_return_val_if_fail((!vertical || !horizontal), JSValueMakeUndefined(context)); + + GdkEvent event; + event.type = GDK_SCROLL; + event.scroll.x = lastMousePositionX; + event.scroll.y = lastMousePositionY; + event.scroll.time = GDK_CURRENT_TIME; + event.scroll.window = GTK_WIDGET(view)->window; + + if (horizontal < 0) + event.scroll.direction = GDK_SCROLL_LEFT; + else if (horizontal > 0) + event.scroll.direction = GDK_SCROLL_RIGHT; + else if (vertical < 0) + event.scroll.direction = GDK_SCROLL_UP; + else if (vertical > 0) + event.scroll.direction = GDK_SCROLL_DOWN; + else + g_assert_not_reached(); + + if (dragMode && down && !replayingSavedEvents) { + msgQueue[endOfQueue].event = event; + msgQueue[endOfQueue++].isDragEvent = true; + } else { + webkit_web_frame_layout(mainFrame); + gtk_main_do_event(&event); + } + + return JSValueMakeUndefined(context); +} + +static JSValueRef beginDragWithFilesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + if (argumentCount < 1) + return JSValueMakeUndefined(context); + + // FIXME: Implement this completely once WebCore has complete drag and drop support + return JSValueMakeUndefined(context); +} + +void replaySavedEvents() +{ + // FIXME: This doesn't deal with forward leaps, but it should. + + WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); + if (!view) + return; + + replayingSavedEvents = true; + + for (unsigned queuePos = 0; queuePos < endOfQueue; queuePos++) { + GdkEvent event = msgQueue[queuePos].event; + gboolean return_val; + + switch (event.type) { + case GDK_BUTTON_RELEASE: + g_signal_emit_by_name(view, "button_release_event", &event, &return_val); + break; + case GDK_BUTTON_PRESS: + g_signal_emit_by_name(view, "button_press_event", &event, &return_val); + break; + case GDK_MOTION_NOTIFY: + g_signal_emit_by_name(view, "motion_notify_event", &event, &return_val); + break; + default: + continue; + } + + startOfQueue++; + } + + int numQueuedMessages = endOfQueue - startOfQueue; + if (!numQueuedMessages) { + startOfQueue = 0; + endOfQueue = 0; + replayingSavedEvents = false; + return; + } + + 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"); + + webkit_web_frame_layout(mainFrame); + + // handle modifier keys. + int state = 0; + if (argumentCount > 1) { + JSObjectRef modifiersArray = JSValueToObject(context, arguments[1], exception); + if (modifiersArray) { + for (int i = 0; i < JSValueToNumber(context, JSObjectGetProperty(context, modifiersArray, lengthProperty, 0), 0); ++i) { + JSValueRef value = JSObjectGetPropertyAtIndex(context, modifiersArray, i, 0); + JSStringRef string = JSValueToStringCopy(context, value, 0); + if (JSStringIsEqualToUTF8CString(string, "ctrlKey")) + state |= GDK_CONTROL_MASK; + else if (JSStringIsEqualToUTF8CString(string, "shiftKey")) + state |= GDK_SHIFT_MASK; + else if (JSStringIsEqualToUTF8CString(string, "altKey")) + state |= GDK_MOD1_MASK; + + JSStringRelease(string); + } + } + } + + JSStringRef character = JSValueToStringCopy(context, arguments[0], exception); + g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context)); + int gdkKeySym; + if (JSStringIsEqualToUTF8CString(character, "leftArrow")) + gdkKeySym = GDK_Left; + else if (JSStringIsEqualToUTF8CString(character, "rightArrow")) + gdkKeySym = GDK_Right; + else if (JSStringIsEqualToUTF8CString(character, "upArrow")) + gdkKeySym = GDK_Up; + else if (JSStringIsEqualToUTF8CString(character, "downArrow")) + gdkKeySym = GDK_Down; + else if (JSStringIsEqualToUTF8CString(character, "pageUp")) + gdkKeySym = GDK_Page_Up; + else if (JSStringIsEqualToUTF8CString(character, "pageDown")) + gdkKeySym = GDK_Page_Down; + else if (JSStringIsEqualToUTF8CString(character, "home")) + gdkKeySym = GDK_Home; + else if (JSStringIsEqualToUTF8CString(character, "end")) + gdkKeySym = GDK_End; + else if (JSStringIsEqualToUTF8CString(character, "delete")) + gdkKeySym = GDK_BackSpace; + else if (JSStringIsEqualToUTF8CString(character, "F1")) + gdkKeySym = GDK_F1; + else if (JSStringIsEqualToUTF8CString(character, "F2")) + gdkKeySym = GDK_F2; + else if (JSStringIsEqualToUTF8CString(character, "F3")) + gdkKeySym = GDK_F3; + else if (JSStringIsEqualToUTF8CString(character, "F4")) + gdkKeySym = GDK_F4; + else if (JSStringIsEqualToUTF8CString(character, "F5")) + gdkKeySym = GDK_F5; + else if (JSStringIsEqualToUTF8CString(character, "F6")) + gdkKeySym = GDK_F6; + else if (JSStringIsEqualToUTF8CString(character, "F7")) + gdkKeySym = GDK_F7; + else if (JSStringIsEqualToUTF8CString(character, "F8")) + gdkKeySym = GDK_F8; + else if (JSStringIsEqualToUTF8CString(character, "F9")) + gdkKeySym = GDK_F9; + else if (JSStringIsEqualToUTF8CString(character, "F10")) + gdkKeySym = GDK_F10; + else if (JSStringIsEqualToUTF8CString(character, "F11")) + gdkKeySym = GDK_F11; + else if (JSStringIsEqualToUTF8CString(character, "F12")) + gdkKeySym = GDK_F12; + else { + int charCode = JSStringGetCharactersPtr(character)[0]; + if (charCode == '\n' || charCode == '\r') + gdkKeySym = GDK_Return; + else if (charCode == '\t') + gdkKeySym = GDK_Tab; + else if (charCode == '\x8') + gdkKeySym = GDK_BackSpace; + else { + gdkKeySym = gdk_unicode_to_keyval(charCode); + if (WTF::isASCIIUpper(charCode)) + state |= GDK_SHIFT_MASK; + } + } + + JSStringRelease(character); + + WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); + if (!view) + return JSValueMakeUndefined(context); + + // create and send the event + GdkEvent event; + memset(&event, 0, sizeof(event)); + event.key.keyval = gdkKeySym; + event.key.state = state; + event.key.window = GTK_WIDGET(view)->window; + + gboolean return_val; + event.key.type = GDK_KEY_PRESS; + g_signal_emit_by_name(view, "key-press-event", &event.key, &return_val); + + event.key.type = GDK_KEY_RELEASE; + g_signal_emit_by_name(view, "key-release-event", &event.key, &return_val); + + return JSValueMakeUndefined(context); +} + +static JSValueRef textZoomInCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); + if (!view) + return JSValueMakeUndefined(context); + + gfloat currentZoom = webkit_web_view_get_zoom_level(view); + webkit_web_view_set_zoom_level(view, currentZoom * zoomMultiplierRatio); + + return JSValueMakeUndefined(context); +} + +static JSValueRef textZoomOutCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); + if (!view) + return JSValueMakeUndefined(context); + + gfloat currentZoom = webkit_web_view_get_zoom_level(view); + webkit_web_view_set_zoom_level(view, currentZoom / zoomMultiplierRatio); + + return JSValueMakeUndefined(context); +} + +static JSValueRef zoomPageInCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); + if (!view) + return JSValueMakeUndefined(context); + + webkit_web_view_zoom_in(view); + return JSValueMakeUndefined(context); +} + +static JSValueRef zoomPageOutCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); + if (!view) + return JSValueMakeUndefined(context); + + webkit_web_view_zoom_out(view); + return JSValueMakeUndefined(context); +} + +static JSStaticFunction staticFunctions[] = { + { "mouseWheelTo", mouseWheelToCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "contextClick", contextClickCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "mouseDown", mouseDownCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "mouseUp", mouseUpCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "mouseMoveTo", mouseMoveToCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "beginDragWithFiles", beginDragWithFilesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "leapForward", leapForwardCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "keyDown", keyDownCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "textZoomIn", textZoomInCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "textZoomOut", textZoomOutCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "zoomPageIn", zoomPageInCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "zoomPageOut", zoomPageOutCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { 0, 0, 0 } +}; + +static JSStaticValue staticValues[] = { + { "dragMode", getDragModeCallback, setDragModeCallback, kJSPropertyAttributeNone }, + { 0, 0, 0, 0 } +}; + +static JSClassRef getClass(JSContextRef context) +{ + static JSClassRef eventSenderClass = 0; + + if (!eventSenderClass) { + JSClassDefinition classDefinition = { + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + classDefinition.staticFunctions = staticFunctions; + classDefinition.staticValues = staticValues; + + eventSenderClass = JSClassCreate(&classDefinition); + } + + return eventSenderClass; +} + +JSObjectRef makeEventSender(JSContextRef context) +{ + down = false; + dragMode = true; + lastMousePositionX = lastMousePositionY = 0; + lastClickPositionX = lastClickPositionY = 0; + + if (!replayingSavedEvents) { + // This function can be called in the middle of a test, even + // while replaying saved events. Resetting these while doing that + // can break things. + endOfQueue = 0; + startOfQueue = 0; + } + + return JSObjectMake(context, getClass(context), 0); +} diff --git a/WebKitTools/DumpRenderTree/gtk/EventSender.h b/WebKitTools/DumpRenderTree/gtk/EventSender.h new file mode 100644 index 0000000..272e8a9 --- /dev/null +++ b/WebKitTools/DumpRenderTree/gtk/EventSender.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2009 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. + */ + +#ifndef EventSender_h +#define EventSender_h + +typedef const struct OpaqueJSContext* JSContextRef; +typedef struct OpaqueJSValue* JSObjectRef; + +JSObjectRef makeEventSender(JSContextRef context); +void replaySavedEvents(); + +#endif diff --git a/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp b/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp index 009cb97..0b4a38f 100644 --- a/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp +++ b/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp @@ -38,6 +38,8 @@ #include <JavaScriptCore/JSRetainPtr.h> #include <JavaScriptCore/JSStringRef.h> +#include <iostream> +#include <sstream> #include <stdio.h> #include <glib.h> #include <libsoup/soup.h> @@ -48,6 +50,23 @@ bool webkit_web_frame_pause_animation(WebKitWebFrame* frame, const gchar* name, bool webkit_web_frame_pause_transition(WebKitWebFrame* frame, const gchar* name, double time, const gchar* element); unsigned int webkit_web_frame_number_of_active_animations(WebKitWebFrame* frame); void webkit_application_cache_set_maximum_size(unsigned long long size); +unsigned int webkit_worker_thread_count(void); +void webkit_white_list_access_from_origin(const gchar* sourceOrigin, const gchar* destinationProtocol, const gchar* destinationHost, bool allowDestinationSubdomains); +} + +static gchar* copyWebSettingKey(gchar* preferenceKey) +{ + static GHashTable* keyTable; + + if (!keyTable) { + // If you add a pref here, make sure you reset the value in + // DumpRenderTree::resetWebViewToConsistentStateBeforeTesting. + keyTable = g_hash_table_new(g_str_hash, g_str_equal); + g_hash_table_insert(keyTable, g_strdup("WebKitJavaScriptEnabled"), g_strdup("enable-scripts")); + g_hash_table_insert(keyTable, g_strdup("WebKitDefaultFontSize"), g_strdup("default-font-size")); + } + + return g_strdup(static_cast<gchar*>(g_hash_table_lookup(keyTable, preferenceKey))); } LayoutTestController::~LayoutTestController() @@ -110,6 +129,11 @@ size_t LayoutTestController::webHistoryItemCount() return 0; } +unsigned LayoutTestController::workerThreadCount() const +{ + return webkit_worker_thread_count(); +} + void LayoutTestController::notifyDone() { if (m_waitToDump && !topLoadingFrame && !WorkQueue::shared()->count()) @@ -152,6 +176,11 @@ void LayoutTestController::setAcceptsEditing(bool acceptsEditing) webkit_web_view_set_editable(webView, acceptsEditing); } +void LayoutTestController::setAlwaysAcceptCookies(bool alwaysAcceptCookies) +{ + // FIXME: Implement this (and restore the default value before running each test in DumpRenderTree.cpp). +} + void LayoutTestController::setCustomPolicyDelegate(bool setDelegate, bool permissive) { // FIXME: implement @@ -163,6 +192,17 @@ void LayoutTestController::waitForPolicyDelegate() setWaitToDump(true); } +void LayoutTestController::whiteListAccessFromOrigin(JSStringRef sourceOrigin, JSStringRef protocol, JSStringRef host, bool includeSubdomains) +{ + gchar* sourceOriginGChar = JSStringCopyUTF8CString(sourceOrigin); + gchar* protocolGChar = JSStringCopyUTF8CString(protocol); + gchar* hostGChar = JSStringCopyUTF8CString(host); + webkit_white_list_access_from_origin(sourceOriginGChar, protocolGChar, hostGChar, includeSubdomains); + g_free(sourceOriginGChar); + g_free(protocolGChar); + g_free(hostGChar); +} + void LayoutTestController::setMainFrameIsFirstResponder(bool flag) { // FIXME: implement @@ -213,17 +253,14 @@ void LayoutTestController::setSmartInsertDeleteEnabled(bool flag) 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); waitToDumpWatchdog = 0; - dump(); + gLayoutTestController->waitToDumpWatchdogTimerFired(); return FALSE; } void LayoutTestController::setWaitToDump(bool waitUntilDone) { - static const int timeoutSeconds = 10; + static const int timeoutSeconds = 15; m_waitToDump = waitUntilDone; if (m_waitToDump && !waitToDumpWatchdog) @@ -265,6 +302,18 @@ void LayoutTestController::disableImageLoading() // Also need to make sure image loading is re-enabled for each new test. } +void LayoutTestController::setMockGeolocationPosition(double latitude, double longitude, double accuracy) +{ + // FIXME: Implement for Geolocation layout tests. + // See https://bugs.webkit.org/show_bug.cgi?id=28264. +} + +void LayoutTestController::setMockGeolocationError(int code, JSStringRef message) +{ + // FIXME: Implement for Geolocation layout tests. + // See https://bugs.webkit.org/show_bug.cgi?id=28264. +} + void LayoutTestController::setIconDatabaseEnabled(bool flag) { // FIXME: implement @@ -331,12 +380,13 @@ void LayoutTestController::clearPersistentUserStyleSheet() void LayoutTestController::clearAllDatabases() { - // FIXME: implement + webkit_remove_all_web_databases(); } void LayoutTestController::setDatabaseQuota(unsigned long long quota) -{ - // FIXME: implement +{ + WebKitSecurityOrigin* origin = webkit_web_frame_get_security_origin(mainFrame); + webkit_security_origin_set_web_database_quota(origin, quota); } void LayoutTestController::setAppCacheMaximumSize(unsigned long long size) @@ -348,17 +398,91 @@ bool LayoutTestController::pauseAnimationAtTimeOnElementWithId(JSStringRef anima { gchar* name = JSStringCopyUTF8CString(animationName); gchar* element = JSStringCopyUTF8CString(elementId); - return webkit_web_frame_pause_animation(mainFrame, name, time, element); + bool returnValue = webkit_web_frame_pause_animation(mainFrame, name, time, element); + g_free(name); + g_free(element); + return returnValue; } bool LayoutTestController::pauseTransitionAtTimeOnElementWithId(JSStringRef propertyName, double time, JSStringRef elementId) { gchar* name = JSStringCopyUTF8CString(propertyName); gchar* element = JSStringCopyUTF8CString(elementId); - return webkit_web_frame_pause_transition(mainFrame, name, time, element); + bool returnValue = webkit_web_frame_pause_transition(mainFrame, name, time, element); + g_free(name); + g_free(element); + return returnValue; } unsigned LayoutTestController::numberOfActiveAnimations() const { return webkit_web_frame_number_of_active_animations(mainFrame); } + +void LayoutTestController::overridePreference(JSStringRef key, JSStringRef value) +{ + gchar* name = JSStringCopyUTF8CString(key); + gchar* strValue = JSStringCopyUTF8CString(value); + + WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); + ASSERT(view); + + WebKitWebSettings* settings = webkit_web_view_get_settings(view); + gchar* webSettingKey = copyWebSettingKey(name); + + if (webSettingKey) { + GValue stringValue = { 0, { { 0 } } }; + g_value_init(&stringValue, G_TYPE_STRING); + g_value_set_string(&stringValue, const_cast<gchar*>(strValue)); + + WebKitWebSettingsClass* klass = WEBKIT_WEB_SETTINGS_GET_CLASS(settings); + GParamSpec* pspec = g_object_class_find_property(G_OBJECT_CLASS(klass), webSettingKey); + GValue propValue = { 0, { { 0 } } }; + g_value_init(&propValue, pspec->value_type); + + if (g_value_type_transformable(G_TYPE_STRING, pspec->value_type)) { + g_value_transform(const_cast<GValue*>(&stringValue), &propValue); + g_object_set_property(G_OBJECT(settings), webSettingKey, const_cast<GValue*>(&propValue)); + } else if (G_VALUE_HOLDS_BOOLEAN(&propValue)) { + g_object_set(G_OBJECT(settings), webSettingKey, + g_str_equal(g_utf8_strdown(strValue, -1), "true"), + NULL); + } else if (G_VALUE_HOLDS_INT(&propValue)) { + std::string str(strValue); + std::stringstream ss(str); + int val = 0; + if (!(ss >> val).fail()) + g_object_set(G_OBJECT(settings), webSettingKey, val, NULL); + } else + printf("LayoutTestController::overridePreference failed to override preference '%s'.\n", name); + } + + g_free(webSettingKey); + g_free(name); + g_free(strValue); +} + +void LayoutTestController::addUserScript(JSStringRef source, bool runAtStart) +{ + printf("LayoutTestController::addUserScript not implemented.\n"); +} + +void LayoutTestController::addUserStyleSheet(JSStringRef source) +{ + printf("LayoutTestController::addUserStyleSheet not implemented.\n"); +} + +void LayoutTestController::showWebInspector() +{ + // FIXME: Implement this. +} + +void LayoutTestController::closeWebInspector() +{ + // FIXME: Implement this. +} + +void LayoutTestController::evaluateInWebInspector(long callId, JSStringRef script) +{ + // FIXME: Implement this. +} diff --git a/WebKitTools/DumpRenderTree/gtk/TestNetscapePlugin/TestNetscapePlugin.cpp b/WebKitTools/DumpRenderTree/gtk/TestNetscapePlugin/TestNetscapePlugin.cpp index b7d14eb..6c62a7c 100644 --- a/WebKitTools/DumpRenderTree/gtk/TestNetscapePlugin/TestNetscapePlugin.cpp +++ b/WebKitTools/DumpRenderTree/gtk/TestNetscapePlugin/TestNetscapePlugin.cpp @@ -46,13 +46,13 @@ extern "C" { } static NPError -webkit_test_plugin_new_instance(NPMIMEType mimetype, +webkit_test_plugin_new_instance(NPMIMEType /*mimetype*/, NPP instance, - uint16_t mode, + uint16_t /*mode*/, int16_t argc, char *argn[], char *argv[], - NPSavedData *savedData) + NPSavedData* /*savedData*/) { if (browser->version >= 14) { PluginObject* obj = (PluginObject*)browser->createobject(instance, getPluginClass()); @@ -85,7 +85,7 @@ webkit_test_plugin_new_instance(NPMIMEType mimetype, } static NPError -webkit_test_plugin_destroy_instance(NPP instance, NPSavedData **save) +webkit_test_plugin_destroy_instance(NPP instance, NPSavedData** /*save*/) { PluginObject* obj = static_cast<PluginObject*>(instance->pdata); if (obj) { @@ -138,9 +138,9 @@ static void executeScript(const PluginObject* obj, const char* script) static NPError webkit_test_plugin_new_stream(NPP instance, - NPMIMEType type, + NPMIMEType /*type*/, NPStream *stream, - NPBool seekable, + NPBool /*seekable*/, uint16* stype) { PluginObject* obj = static_cast<PluginObject*>(instance->pdata); @@ -160,7 +160,7 @@ webkit_test_plugin_new_stream(NPP instance, } static NPError -webkit_test_plugin_destroy_stream(NPP instance, NPStream *stream, NPError reason) +webkit_test_plugin_destroy_stream(NPP instance, NPStream* /*stream*/, NPError /*reason*/) { PluginObject* obj = (PluginObject*)instance->pdata; @@ -171,28 +171,28 @@ webkit_test_plugin_destroy_stream(NPP instance, NPStream *stream, NPError reason } static void -webkit_test_plugin_stream_as_file(NPP instance, NPStream *stream, const char* fname) +webkit_test_plugin_stream_as_file(NPP /*instance*/, NPStream* /*stream*/, const char* /*fname*/) { } static int32 -webkit_test_plugin_write_ready(NPP instance, NPStream *stream) +webkit_test_plugin_write_ready(NPP /*instance*/, NPStream* /*stream*/) { return 0; } static int32 -webkit_test_plugin_write(NPP instance, - NPStream *stream, - int32_t offset, - int32_t len, - void *buffer) +webkit_test_plugin_write(NPP /*instance*/, + NPStream* /*stream*/, + int32_t /*offset*/, + int32_t /*len*/, + void* /*buffer*/) { return 0; } static void -webkit_test_plugin_print(NPP instance, NPPrint* platformPrint) +webkit_test_plugin_print(NPP /*instance*/, NPPrint* /*platformPrint*/) { } @@ -258,7 +258,7 @@ webkit_test_plugin_get_value(NPP instance, NPPVariable variable, void *value) } static NPError -webkit_test_plugin_set_value(NPP instance, NPNVariable variable, void *value) +webkit_test_plugin_set_value(NPP /*instance*/, NPNVariable /*variable*/, void* /*value*/) { return NPERR_NO_ERROR; } @@ -310,7 +310,7 @@ NP_Shutdown(void) } NPError -NP_GetValue(void *future, NPPVariable variable, void *value) +NP_GetValue(void* /*future*/, NPPVariable variable, void *value) { return webkit_test_plugin_get_value(NULL, variable, value); } diff --git a/WebKitTools/DumpRenderTree/gtk/fonts.conf b/WebKitTools/DumpRenderTree/gtk/fonts.conf new file mode 100644 index 0000000..3540c47 --- /dev/null +++ b/WebKitTools/DumpRenderTree/gtk/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/mac/AccessibilityControllerMac.mm b/WebKitTools/DumpRenderTree/mac/AccessibilityControllerMac.mm index a191495..67e0fa4 100644 --- a/WebKitTools/DumpRenderTree/mac/AccessibilityControllerMac.mm +++ b/WebKitTools/DumpRenderTree/mac/AccessibilityControllerMac.mm @@ -53,3 +53,12 @@ AccessibilityUIElement AccessibilityController::rootElement() id accessibilityObject = [[mainFrame frameView] documentView]; return AccessibilityUIElement(accessibilityObject); } + +void AccessibilityController::setLogFocusEvents(bool) +{ +} + +void AccessibilityController::setLogScrollingStartEvents(bool) +{ +} + diff --git a/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm b/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm index b2cbb34..375dbad 100644 --- a/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm +++ b/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm @@ -311,6 +311,12 @@ JSStringRef AccessibilityUIElement::role() return concatenateAttributeAndValue(@"AXRole", role); } +JSStringRef AccessibilityUIElement::subrole() +{ + NSString* role = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilitySubroleAttribute], m_element); + return concatenateAttributeAndValue(@"AXSubrole", role); +} + JSStringRef AccessibilityUIElement::title() { NSString* title = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityTitleAttribute], m_element); @@ -362,7 +368,7 @@ double AccessibilityUIElement::clickPointX() double AccessibilityUIElement::clickPointY() { NSValue* positionValue = [m_element accessibilityAttributeValue:@"AXClickPoint"]; - return static_cast<double>([positionValue pointValue].x); + return static_cast<double>([positionValue pointValue].y); } double AccessibilityUIElement::intValue() @@ -392,7 +398,7 @@ double AccessibilityUIElement::maxValue() JSStringRef AccessibilityUIElement::valueDescription() { NSString* valueDescription = [m_element accessibilityAttributeValue:NSAccessibilityValueDescriptionAttribute]; - if ([valueDescription isKindOfClass:[NSString class]]) + if ([valueDescription isKindOfClass:[NSString class]]) return [valueDescription createJSStringRef]; return 0; } @@ -449,6 +455,16 @@ JSStringRef AccessibilityUIElement::boundsForRange(unsigned location, unsigned l return [boundsDescription createJSStringRef]; } +JSStringRef AccessibilityUIElement::stringForRange(unsigned location, unsigned length) +{ + NSRange range = NSMakeRange(location, length); + id string = [m_element accessibilityAttributeValue:NSAccessibilityStringForRangeParameterizedAttribute forParameter:[NSValue valueWithRange:range]]; + if (![string isKindOfClass:[NSString class]]) + return 0; + + return [string createJSStringRef]; +} + JSStringRef AccessibilityUIElement::attributesOfColumnHeaders() { // not yet defined in AppKit... odd diff --git a/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm b/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm index d49248b..0c33381 100644 --- a/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm +++ b/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm @@ -38,6 +38,7 @@ #import "EditingDelegate.h" #import "EventSendingController.h" #import "FrameLoadDelegate.h" +#import "HistoryDelegate.h" #import "JavaScriptThreading.h" #import "LayoutTestController.h" #import "NavigationController.h" @@ -116,6 +117,7 @@ static FrameLoadDelegate *frameLoadDelegate; static UIDelegate *uiDelegate; static EditingDelegate *editingDelegate; static ResourceLoadDelegate *resourceLoadDelegate; +static HistoryDelegate *historyDelegate; PolicyDelegate *policyDelegate; static int dumpPixels; @@ -354,7 +356,8 @@ static NSString *libraryPathForDumpRenderTree() return [@"~/Library/Application Support/DumpRenderTree" stringByExpandingTildeInPath]; } -static void setDefaultsToConsistentValuesForTesting() +// Called before each test. +static void resetDefaultsToConsistentValues() { // Give some clear to undocumented defaults values static const int NoFontSmoothing = 0; @@ -384,15 +387,10 @@ static void setDefaultsToConsistentValuesForTesting() NSString *path = libraryPathForDumpRenderTree(); [defaults setObject:[path stringByAppendingPathComponent:@"Databases"] forKey:WebDatabaseDirectoryDefaultsKey]; [defaults setObject:[path stringByAppendingPathComponent:@"LocalCache"] forKey:WebKitLocalCacheDefaultsKey]; - NSURLCache *sharedCache = - [[NSURLCache alloc] initWithMemoryCapacity:1024 * 1024 - diskCapacity:0 - diskPath:[path stringByAppendingPathComponent:@"URLCache"]]; - [NSURLCache setSharedURLCache:sharedCache]; - [sharedCache release]; WebPreferences *preferences = [WebPreferences standardPreferences]; + [preferences setAllowUniversalAccessFromFileURLs:YES]; [preferences setStandardFontFamily:@"Times"]; [preferences setFixedFontFamily:@"Courier"]; [preferences setSerifFontFamily:@"Times"]; @@ -410,10 +408,58 @@ static void setDefaultsToConsistentValuesForTesting() [preferences setShouldPrintBackgrounds:YES]; [preferences setCacheModel:WebCacheModelDocumentBrowser]; [preferences setXSSAuditorEnabled:NO]; + [preferences setExperimentalNotificationsEnabled:NO]; + [preferences setExperimentalWebSocketsEnabled:NO]; + + [preferences setPrivateBrowsingEnabled:NO]; + [preferences setAuthorAndUserStylesEnabled:YES]; + [preferences setJavaScriptCanOpenWindowsAutomatically:YES]; + [preferences setOfflineWebApplicationCacheEnabled:YES]; + [preferences setDeveloperExtrasEnabled:NO]; + [preferences setXSSAuditorEnabled:NO]; + [preferences setLoadsImagesAutomatically:YES]; + if (persistentUserStyleSheetLocation) { + [preferences setUserStyleSheetLocation:[NSURL URLWithString:(NSString *)(persistentUserStyleSheetLocation.get())]]; + [preferences setUserStyleSheetEnabled:YES]; + } else + [preferences setUserStyleSheetEnabled:NO]; // 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]; + +#if defined(BUILDING_ON_LEOPARD) + // Disable hardware composititing to avoid timeouts and crashes from buggy CoreVideo teardown code. + // https://bugs.webkit.org/show_bug.cgi?id=28845 and rdar://problem/7228836 + SInt32 qtVersion; + OSErr err = Gestalt(gestaltQuickTimeVersion, &qtVersion); + assert(err == noErr); + // Bug 7228836 exists in at least 7.6.3 and 7.6.4, hopefully it will be fixed in 7.6.5. + // FIXME: Once we know the exact versions of QuickTime affected, we can update this check. + if (qtVersion <= 0x07640000) + [preferences setAcceleratedCompositingEnabled:NO]; + else +#endif + [preferences setAcceleratedCompositingEnabled:YES]; + + [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain]; + + setlocale(LC_ALL, ""); +} + +// Called once on DumpRenderTree startup. +static void setDefaultsToConsistentValuesForTesting() +{ + resetDefaultsToConsistentValues(); + + NSString *path = libraryPathForDumpRenderTree(); + NSURLCache *sharedCache = + [[NSURLCache alloc] initWithMemoryCapacity:1024 * 1024 + diskCapacity:0 + diskPath:[path stringByAppendingPathComponent:@"URLCache"]]; + [NSURLCache setSharedURLCache:sharedCache]; + [sharedCache release]; + } static void crashHandler(int sig) @@ -448,6 +494,7 @@ static void allocateGlobalControllers() editingDelegate = [[EditingDelegate alloc] init]; resourceLoadDelegate = [[ResourceLoadDelegate alloc] init]; policyDelegate = [[PolicyDelegate alloc] init]; + historyDelegate = [[HistoryDelegate alloc] init]; } // ObjC++ doens't seem to let me pass NSObject*& sadly. @@ -1033,11 +1080,16 @@ void dump() done = YES; } -static bool shouldLogFrameLoadDelegates(const char *pathOrURL) +static bool shouldLogFrameLoadDelegates(const char* pathOrURL) { return strstr(pathOrURL, "loading/"); } +static bool shouldLogHistoryDelegates(const char* pathOrURL) +{ + return strstr(pathOrURL, "globalhistory/"); +} + static void resetWebViewToConsistentStateBeforeTesting() { WebView *webView = [mainFrame webView]; @@ -1048,29 +1100,19 @@ static void resetWebViewToConsistentStateBeforeTesting() [webView setPolicyDelegate:nil]; [policyDelegate setPermissive:NO]; [policyDelegate setControllerToNotifyDone:0]; + [frameLoadDelegate resetToConsistentState]; [webView _setDashboardBehavior:WebDashboardBehaviorUseBackwardCompatibilityMode to:NO]; [webView _clearMainFrameName]; [[webView undoManager] removeAllActions]; + [WebView _removeAllUserContentFromGroup:[webView groupName]]; - WebPreferences *preferences = [webView preferences]; - [preferences setPrivateBrowsingEnabled:NO]; - [preferences setAuthorAndUserStylesEnabled:YES]; - [preferences setJavaScriptCanOpenWindowsAutomatically:YES]; - [preferences setOfflineWebApplicationCacheEnabled:YES]; - [preferences setDeveloperExtrasEnabled:NO]; - [preferences setXSSAuditorEnabled:NO]; - [preferences setLoadsImagesAutomatically:YES]; - - if (persistentUserStyleSheetLocation) { - [preferences setUserStyleSheetLocation:[NSURL URLWithString:(NSString *)(persistentUserStyleSheetLocation.get())]]; - [preferences setUserStyleSheetEnabled:YES]; - } else - [preferences setUserStyleSheetEnabled:NO]; + resetDefaultsToConsistentValues(); [[mainFrame webView] setSmartInsertDeleteEnabled:YES]; [[[mainFrame webView] inspector] setJavaScriptProfilingEnabled:NO]; [WebView _setUsesTestModeFocusRingColor:YES]; + [WebView _resetOriginAccessWhiteLists]; } static void runTest(const string& testPathOrURL) @@ -1120,6 +1162,11 @@ static void runTest(const string& testPathOrURL) if (shouldLogFrameLoadDelegates(pathOrURL.c_str())) gLayoutTestController->setDumpFrameLoadCallbacks(true); + if (shouldLogHistoryDelegates(pathOrURL.c_str())) + [[mainFrame webView] setHistoryDelegate:historyDelegate]; + else + [[mainFrame webView] setHistoryDelegate:nil]; + if ([WebHistory optionalSharedHistory]) [WebHistory setOptionalSharedHistory:nil]; lastMousePosition = NSZeroPoint; diff --git a/WebKitTools/DumpRenderTree/mac/EventSendingController.mm b/WebKitTools/DumpRenderTree/mac/EventSendingController.mm index 8c7c1c4..1cba53b 100644 --- a/WebKitTools/DumpRenderTree/mac/EventSendingController.mm +++ b/WebKitTools/DumpRenderTree/mac/EventSendingController.mm @@ -506,6 +506,15 @@ static NSEventType eventTypeForMouseButtonAndAction(int button, MouseAction acti eventCharacter = [NSString stringWithCharacters:&ch length:1]; } + // Compare the input string with the function-key names defined by the DOM spec (i.e. "F1",...,"F24"). + // If the input string is a function-key name, set its key code. + for (unsigned i = 1; i <= 24; i++) { + if ([character isEqualToString:[NSString stringWithFormat:@"F%u", i]]) { + const unichar ch = NSF1FunctionKey + (i - 1); + eventCharacter = [NSString stringWithCharacters:&ch length:1]; + } + } + NSString *charactersIgnoringModifiers = eventCharacter; int modifierFlags = 0; diff --git a/WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.h b/WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.h index 6c3cbdb..390a881 100644 --- a/WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.h +++ b/WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.h @@ -36,4 +36,7 @@ class GCController; AccessibilityController* accessibilityController; GCController* gcController; } + +- (void)resetToConsistentState; + @end diff --git a/WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.mm b/WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.mm index 4bf02ed..2838d2e 100644 --- a/WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.mm +++ b/WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.mm @@ -48,6 +48,7 @@ #import <WebKit/WebHTMLViewPrivate.h> #import <WebKit/WebKit.h> #import <WebKit/WebNSURLExtras.h> +#import <WebKit/WebSecurityOriginPrivate.h> #import <wtf/Assertions.h> @interface NSURLRequest (PrivateThingsWeShouldntReallyUse) @@ -123,6 +124,11 @@ dump(); } +- (void)resetToConsistentState +{ + accessibilityController->resetToConsistentState(); +} + - (void)webView:(WebView *)c locationChangeDone:(NSError *)error forDataSource:(WebDataSource *)dataSource { if ([dataSource webFrame] == topLoadingFrame) { @@ -348,4 +354,16 @@ } } +- (void)webViewDidDisplayInsecureContent:(WebView *)sender +{ + if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) + printf ("didDisplayInsecureContent\n"); +} + +- (void)webView:(WebView *)sender didRunInsecureContent:(WebSecurityOrigin *)origin +{ + if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) + printf ("didRunInsecureContent\n"); +} + @end diff --git a/WebKitTools/DumpRenderTree/mac/HistoryDelegate.h b/WebKitTools/DumpRenderTree/mac/HistoryDelegate.h new file mode 100644 index 0000000..c56d203 --- /dev/null +++ b/WebKitTools/DumpRenderTree/mac/HistoryDelegate.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2009 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 <Cocoa/Cocoa.h> + +@interface HistoryDelegate : NSObject +{ +} + +@end diff --git a/WebKitTools/DumpRenderTree/mac/HistoryDelegate.mm b/WebKitTools/DumpRenderTree/mac/HistoryDelegate.mm new file mode 100644 index 0000000..9e2b836 --- /dev/null +++ b/WebKitTools/DumpRenderTree/mac/HistoryDelegate.mm @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2009 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 "config.h" +#import "HistoryDelegate.h" + +#import "DumpRenderTree.h" +#import "LayoutTestController.h" + +#import <WebKit/WebNavigationData.h> + +@interface NSURL (DRTExtras) +- (NSString *)_drt_descriptionSuitableForTestResult; +@end + +@implementation HistoryDelegate + +- (void)webView:(WebView *)webView didNavigateWithNavigationData:(WebNavigationData *)navigationData inFrame:(WebFrame *)webFrame +{ + NSURL *url = [navigationData url] ? [NSURL URLWithString:[navigationData url]] : nil; + bool hasClientRedirect = [[navigationData clientRedirectSource] length]; + NSHTTPURLResponse *httpResponse = [[navigationData response] isKindOfClass:[NSHTTPURLResponse class]] ? (NSHTTPURLResponse *)[navigationData response] : nil; + bool wasFailure = [navigationData hasSubstituteData] || (httpResponse && [httpResponse statusCode] >= 400); + + printf("WebView navigated to url \"%s\" with title \"%s\" with HTTP equivalent method \"%s\". The navigation was %s and was %s%s.\n", + url ? [[url _drt_descriptionSuitableForTestResult] UTF8String] : "<none>", + [navigationData title] ? [[navigationData title] UTF8String] : "", + [navigationData originalRequest] ? [[[navigationData originalRequest] HTTPMethod] UTF8String] : "", + wasFailure ? "a failure" : "successful", + hasClientRedirect ? "a client redirect from " : "not a client redirect", + hasClientRedirect ? [[navigationData clientRedirectSource] UTF8String] : ""); +} + +- (void)webView:(WebView *)webView didPerformClientRedirectFromURL:(NSString *)sourceURL toURL:(NSString *)destinationURL inFrame:(WebFrame *)webFrame +{ + NSURL *source = [NSURL URLWithString:sourceURL]; + NSURL *dest = [NSURL URLWithString:destinationURL]; + printf("WebView performed a client redirect from \"%s\" to \"%s\".\n", [[source _drt_descriptionSuitableForTestResult] UTF8String], [[dest _drt_descriptionSuitableForTestResult] UTF8String]); +} + +- (void)webView:(WebView *)webView didPerformServerRedirectFromURL:(NSString *)sourceURL toURL:(NSString *)destinationURL inFrame:(WebFrame *)webFrame +{ + NSURL *source = [NSURL URLWithString:sourceURL]; + NSURL *dest = [NSURL URLWithString:destinationURL]; + printf("WebView performed a server redirect from \"%s\" to \"%s\".\n", [[source _drt_descriptionSuitableForTestResult] UTF8String], [[dest _drt_descriptionSuitableForTestResult] UTF8String]); +} + +- (void)webView:(WebView *)webView updateHistoryTitle:(NSString *)title forURL:(NSString *)url +{ + printf("WebView updated the title for history URL \"%s\" to \"%s\".\n", [[[NSURL URLWithString:url]_drt_descriptionSuitableForTestResult] UTF8String], [title UTF8String]); +} + +@end diff --git a/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm b/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm index 591bb81..233c5fd 100644 --- a/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm +++ b/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm @@ -51,7 +51,8 @@ #import <WebKit/WebHTMLViewPrivate.h> #import <WebKit/WebHistory.h> #import <WebKit/WebHistoryPrivate.h> -#import <WebKit/WebInspector.h> +#import <WebKit/WebInspectorPrivate.h> +#import <WebKit/WebGeolocationMockPrivate.h> #import <WebKit/WebNSURLExtras.h> #import <WebKit/WebPreferences.h> #import <WebKit/WebPreferencesPrivate.h> @@ -59,6 +60,7 @@ #import <WebKit/WebTypesInternal.h> #import <WebKit/WebView.h> #import <WebKit/WebViewPrivate.h> +#import <WebKit/WebWorkersPrivate.h> #import <wtf/RetainPtr.h> @interface CommandValidationTarget : NSObject <NSValidatedUserInterfaceItem> @@ -163,6 +165,11 @@ size_t LayoutTestController::webHistoryItemCount() return [[[WebHistory optionalSharedHistory] allItems] count]; } +unsigned LayoutTestController::workerThreadCount() const +{ + return [WebWorkersPrivate workerThreadCount]; +} + void LayoutTestController::notifyDone() { if (m_waitToDump && !topLoadingFrame && !WorkQueue::shared()->count()) @@ -192,6 +199,16 @@ void LayoutTestController::setAcceptsEditing(bool newAcceptsEditing) [(EditingDelegate *)[[mainFrame webView] editingDelegate] setAcceptsEditing:newAcceptsEditing]; } +void LayoutTestController::setAlwaysAcceptCookies(bool alwaysAcceptCookies) +{ + if (alwaysAcceptCookies == m_alwaysAcceptCookies) + return; + + m_alwaysAcceptCookies = alwaysAcceptCookies; + NSHTTPCookieAcceptPolicy cookieAcceptPolicy = alwaysAcceptCookies ? NSHTTPCookieAcceptPolicyAlways : NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain; + [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookieAcceptPolicy:cookieAcceptPolicy]; +} + void LayoutTestController::setAppCacheMaximumSize(unsigned long long size) { [WebApplicationCache setMaximumSize:size]; @@ -218,6 +235,18 @@ void LayoutTestController::setDatabaseQuota(unsigned long long quota) [origin release]; } +void LayoutTestController::setMockGeolocationPosition(double latitude, double longitude, double accuracy) +{ + [WebGeolocationMock setPosition:latitude:longitude:accuracy]; +} + +void LayoutTestController::setMockGeolocationError(int code, JSStringRef message) +{ + RetainPtr<CFStringRef> messageCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, message)); + NSString *messageNS = (NSString *)messageCF.get(); + [WebGeolocationMock setError:code:messageNS]; +} + void LayoutTestController::setIconDatabaseEnabled(bool iconDatabaseEnabled) { // FIXME: Workaround <rdar://problem/6480108> @@ -293,6 +322,17 @@ void LayoutTestController::dispatchPendingLoadRequests() [[mainFrame webView] _dispatchPendingLoadRequests]; } +void LayoutTestController::overridePreference(JSStringRef key, JSStringRef value) +{ + RetainPtr<CFStringRef> keyCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, key)); + NSString *keyNS = (NSString *)keyCF.get(); + + RetainPtr<CFStringRef> valueCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, value)); + NSString *valueNS = (NSString *)valueCF.get(); + + [[WebPreferences standardPreferences] _setPreferenceForTestWithValue:valueNS forKey:keyNS]; +} + void LayoutTestController::setPersistentUserStyleSheetLocation(JSStringRef jsURL) { RetainPtr<CFStringRef> urlString(AdoptCF, JSStringCopyCFString(0, jsURL)); @@ -320,14 +360,11 @@ void LayoutTestController::setSelectTrailingWhitespaceEnabled(bool flag) [[mainFrame webView] setSelectTrailingWhitespaceEnabled:flag]; } -static const CFTimeInterval waitToDumpWatchdogInterval = 10.0; +static const CFTimeInterval waitToDumpWatchdogInterval = 15.0; static void waitUntilDoneWatchdogFired(CFRunLoopTimerRef timer, void* info) { - const char* message = "FAIL: Timed out waiting for notifyDone to be called\n"; - fprintf(stderr, "%s", message); - fprintf(stdout, "%s", message); - dump(); + gLayoutTestController->waitToDumpWatchdogTimerFired(); } void LayoutTestController::setWaitToDump(bool waitUntilDone) @@ -429,3 +466,45 @@ void LayoutTestController::waitForPolicyDelegate() [policyDelegate setControllerToNotifyDone:this]; [[mainFrame webView] setPolicyDelegate:policyDelegate]; } + +void LayoutTestController::whiteListAccessFromOrigin(JSStringRef sourceOrigin, JSStringRef destinationProtocol, JSStringRef destinationHost, bool allowDestinationSubdomains) +{ + RetainPtr<CFStringRef> sourceOriginCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, sourceOrigin)); + NSString *sourceOriginNS = (NSString *)sourceOriginCF.get(); + RetainPtr<CFStringRef> protocolCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, destinationProtocol)); + NSString *destinationProtocolNS = (NSString *)protocolCF.get(); + RetainPtr<CFStringRef> hostCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, destinationHost)); + NSString *destinationHostNS = (NSString *)hostCF.get(); + [WebView _whiteListAccessFromOrigin:sourceOriginNS destinationProtocol:destinationProtocolNS destinationHost:destinationHostNS allowDestinationSubdomains:allowDestinationSubdomains]; +} + +void LayoutTestController::addUserScript(JSStringRef source, bool runAtStart) +{ + RetainPtr<CFStringRef> sourceCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, source)); + NSString *sourceNS = (NSString *)sourceCF.get(); + [WebView _addUserScriptToGroup:@"org.webkit.DumpRenderTree" source:sourceNS url:nil worldID:1 whitelist:nil blacklist:nil injectionTime:(runAtStart ? WebInjectAtDocumentStart : WebInjectAtDocumentEnd)]; +} + +void LayoutTestController::addUserStyleSheet(JSStringRef source) +{ + RetainPtr<CFStringRef> sourceCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, source)); + NSString *sourceNS = (NSString *)sourceCF.get(); + [WebView _addUserStyleSheetToGroup:@"org.webkit.DumpRenderTree" source:sourceNS url:nil worldID:1 whitelist:nil blacklist:nil]; +} + +void LayoutTestController::showWebInspector() +{ + [[[mainFrame webView] inspector] show:nil]; +} + +void LayoutTestController::closeWebInspector() +{ + [[[mainFrame webView] inspector] close:nil]; +} + +void LayoutTestController::evaluateInWebInspector(long callId, JSStringRef script) +{ + RetainPtr<CFStringRef> scriptCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, script)); + NSString *scriptNS = (NSString *)scriptCF.get(); + [[[mainFrame webView] inspector] evaluateInFrontend:nil callId:callId script:scriptNS]; +} diff --git a/WebKitTools/DumpRenderTree/mac/PerlSupport/DumpRenderTreeSupportTiger.pm b/WebKitTools/DumpRenderTree/mac/PerlSupport/DumpRenderTreeSupportTiger.pm index f0697fc..7b4ea34 100644 --- a/WebKitTools/DumpRenderTree/mac/PerlSupport/DumpRenderTreeSupportTiger.pm +++ b/WebKitTools/DumpRenderTree/mac/PerlSupport/DumpRenderTreeSupportTiger.pm @@ -1,52 +1,54 @@ -# Copyright (C) 2009 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. - -use strict; -use warnings; +# This file was automatically generated by SWIG +package DumpRenderTreeSupport; +require Exporter; +require DynaLoader; +@ISA = qw(Exporter DynaLoader); +package DumpRenderTreeSupportc; +bootstrap DumpRenderTreeSupport; +package DumpRenderTreeSupport; +@EXPORT = qw( ); + +# ---------- BASE METHODS ------------- package DumpRenderTreeSupport; -BEGIN { - use Exporter (); - our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS); - $VERSION = 1.00; - @ISA = qw(Exporter); - @EXPORT = qw(&processIsCrashing); - %EXPORT_TAGS = ( ); - @EXPORT_OK = (); +sub TIEHASH { + my ($classname,$obj) = @_; + return bless $obj, $classname; +} + +sub CLEAR { } + +sub FIRSTKEY { } + +sub NEXTKEY { } + +sub FETCH { + my ($self,$field) = @_; + my $member_func = "swig_${field}_get"; + $self->$member_func(); +} + +sub STORE { + my ($self,$field,$newval) = @_; + my $member_func = "swig_${field}_set"; + $self->$member_func($newval); } -our @EXPORT_OK; - -sub processIsCrashing -{ - my $pid = shift; - my $tryingToExit = 0; - open PS, "ps -o state -p $pid |"; - <PS>; # skip header - $tryingToExit = 1 if <PS> =~ /E/; - close PS; - return $tryingToExit; +sub this { + my $ptr = shift; + return tied(%$ptr); } + +# ------- FUNCTION WRAPPERS -------- + +package DumpRenderTreeSupport; + +*processIsCrashing = *DumpRenderTreeSupportc::processIsCrashing; + +# ------- VARIABLE STUBS -------- + +package DumpRenderTreeSupport; + 1; diff --git a/WebKitTools/DumpRenderTree/mac/PerlSupport/DumpRenderTreeSupport_wrapTiger.c b/WebKitTools/DumpRenderTree/mac/PerlSupport/DumpRenderTreeSupport_wrapTiger.c new file mode 100644 index 0000000..f734989 --- /dev/null +++ b/WebKitTools/DumpRenderTree/mac/PerlSupport/DumpRenderTreeSupport_wrapTiger.c @@ -0,0 +1,1167 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.24 + * + * This file is not intended to be easily readable and contains a number of + * coding conventions designed to improve portability and efficiency. Do not make + * changes to this file unless you know what you are doing--modify the SWIG + * interface file instead. + * ----------------------------------------------------------------------------- */ + + +#ifndef SWIG_TEMPLATE_DISAMBIGUATOR +# if defined(__SUNPRO_CC) +# define SWIG_TEMPLATE_DISAMBIGUATOR template +# else +# define SWIG_TEMPLATE_DISAMBIGUATOR +# endif +#endif + +/*********************************************************************** + * swigrun.swg + * + * This file contains generic CAPI SWIG runtime support for pointer + * type checking. + * + ************************************************************************/ + +/* This should only be incremented when either the layout of swig_type_info changes, + or for whatever reason, the runtime changes incompatibly */ +#define SWIG_RUNTIME_VERSION "1" + +/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */ +#ifdef SWIG_TYPE_TABLE +#define SWIG_QUOTE_STRING(x) #x +#define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x) +#define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE) +#else +#define SWIG_TYPE_TABLE_NAME +#endif + +#include <string.h> + +#ifndef SWIGINLINE +#if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) +# define SWIGINLINE inline +#else +# define SWIGINLINE +#endif +#endif + +/* + You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for + creating a static or dynamic library from the swig runtime code. + In 99.9% of the cases, swig just needs to declare them as 'static'. + + But only do this if is strictly necessary, ie, if you have problems + with your compiler or so. +*/ +#ifndef SWIGRUNTIME +#define SWIGRUNTIME static +#endif +#ifndef SWIGRUNTIMEINLINE +#define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *(*swig_converter_func)(void *); +typedef struct swig_type_info *(*swig_dycast_func)(void **); + +typedef struct swig_type_info { + const char *name; + swig_converter_func converter; + const char *str; + void *clientdata; + swig_dycast_func dcast; + struct swig_type_info *next; + struct swig_type_info *prev; +} swig_type_info; + +/* + Compare two type names skipping the space characters, therefore + "char*" == "char *" and "Class<int>" == "Class<int >", etc. + + Return 0 when the two name types are equivalent, as in + strncmp, but skipping ' '. +*/ +SWIGRUNTIME int +SWIG_TypeNameComp(const char *f1, const char *l1, + const char *f2, const char *l2) { + for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) { + while ((*f1 == ' ') && (f1 != l1)) ++f1; + while ((*f2 == ' ') && (f2 != l2)) ++f2; + if (*f1 != *f2) return *f1 - *f2; + } + return (l1 - f1) - (l2 - f2); +} + +/* + Check type equivalence in a name list like <name1>|<name2>|... +*/ +SWIGRUNTIME int +SWIG_TypeEquiv(const char *nb, const char *tb) { + int equiv = 0; + const char* te = tb + strlen(tb); + const char* ne = nb; + while (!equiv && *ne) { + for (nb = ne; *ne; ++ne) { + if (*ne == '|') break; + } + equiv = SWIG_TypeNameComp(nb, ne, tb, te) == 0; + if (*ne) ++ne; + } + return equiv; +} + +/* + Register a type mapping with the type-checking +*/ +SWIGRUNTIME swig_type_info * +SWIG_TypeRegisterTL(swig_type_info **tl, swig_type_info *ti) { + swig_type_info *tc, *head, *ret, *next; + /* Check to see if this type has already been registered */ + tc = *tl; + while (tc) { + /* check simple type equivalence */ + int typeequiv = (strcmp(tc->name, ti->name) == 0); + /* check full type equivalence, resolving typedefs */ + if (!typeequiv) { + /* only if tc is not a typedef (no '|' on it) */ + if (tc->str && ti->str && !strstr(tc->str,"|")) { + typeequiv = SWIG_TypeEquiv(ti->str,tc->str); + } + } + if (typeequiv) { + /* Already exists in the table. Just add additional types to the list */ + if (ti->clientdata) tc->clientdata = ti->clientdata; + head = tc; + next = tc->next; + goto l1; + } + tc = tc->prev; + } + head = ti; + next = 0; + + /* Place in list */ + ti->prev = *tl; + *tl = ti; + + /* Build linked lists */ + l1: + ret = head; + tc = ti + 1; + /* Patch up the rest of the links */ + while (tc->name) { + head->next = tc; + tc->prev = head; + head = tc; + tc++; + } + if (next) next->prev = head; + head->next = next; + + return ret; +} + +/* + Check the typename +*/ +SWIGRUNTIME swig_type_info * +SWIG_TypeCheck(const char *c, swig_type_info *ty) { + swig_type_info *s; + if (!ty) return 0; /* Void pointer */ + s = ty->next; /* First element always just a name */ + do { + if (strcmp(s->name,c) == 0) { + if (s == ty->next) return s; + /* Move s to the top of the linked list */ + s->prev->next = s->next; + if (s->next) { + s->next->prev = s->prev; + } + /* Insert s as second element in the list */ + s->next = ty->next; + if (ty->next) ty->next->prev = s; + ty->next = s; + s->prev = ty; + return s; + } + s = s->next; + } while (s && (s != ty->next)); + return 0; +} + +/* + Cast a pointer up an inheritance hierarchy +*/ +SWIGRUNTIMEINLINE void * +SWIG_TypeCast(swig_type_info *ty, void *ptr) { + return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr); +} + +/* + Dynamic pointer casting. Down an inheritance hierarchy +*/ +SWIGRUNTIME swig_type_info * +SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) { + swig_type_info *lastty = ty; + if (!ty || !ty->dcast) return ty; + while (ty && (ty->dcast)) { + ty = (*ty->dcast)(ptr); + if (ty) lastty = ty; + } + return lastty; +} + +/* + Return the name associated with this type +*/ +SWIGRUNTIMEINLINE const char * +SWIG_TypeName(const swig_type_info *ty) { + return ty->name; +} + +/* + Return the pretty name associated with this type, + that is an unmangled type name in a form presentable to the user. +*/ +SWIGRUNTIME const char * +SWIG_TypePrettyName(const swig_type_info *type) { + /* The "str" field contains the equivalent pretty names of the + type, separated by vertical-bar characters. We choose + to print the last name, as it is often (?) the most + specific. */ + if (type->str != NULL) { + const char *last_name = type->str; + const char *s; + for (s = type->str; *s; s++) + if (*s == '|') last_name = s+1; + return last_name; + } + else + return type->name; +} + +/* + Search for a swig_type_info structure +*/ +SWIGRUNTIME swig_type_info * +SWIG_TypeQueryTL(swig_type_info *tl, const char *name) { + swig_type_info *ty = tl; + while (ty) { + if (ty->str && (SWIG_TypeEquiv(ty->str,name))) return ty; + if (ty->name && (strcmp(name,ty->name) == 0)) return ty; + ty = ty->prev; + } + return 0; +} + +/* + Set the clientdata field for a type +*/ +SWIGRUNTIME void +SWIG_TypeClientDataTL(swig_type_info *tl, swig_type_info *ti, void *clientdata) { + swig_type_info *tc, *equiv; + if (ti->clientdata) return; + /* if (ti->clientdata == clientdata) return; */ + ti->clientdata = clientdata; + equiv = ti->next; + while (equiv) { + if (!equiv->converter) { + tc = tl; + while (tc) { + if ((strcmp(tc->name, equiv->name) == 0)) + SWIG_TypeClientDataTL(tl,tc,clientdata); + tc = tc->prev; + } + } + equiv = equiv->next; + } +} + +/* + Pack binary data into a string +*/ +SWIGRUNTIME char * +SWIG_PackData(char *c, void *ptr, size_t sz) { + static char hex[17] = "0123456789abcdef"; + unsigned char *u = (unsigned char *) ptr; + const unsigned char *eu = u + sz; + register unsigned char uu; + for (; u != eu; ++u) { + uu = *u; + *(c++) = hex[(uu & 0xf0) >> 4]; + *(c++) = hex[uu & 0xf]; + } + return c; +} + +/* + Unpack binary data from a string +*/ +SWIGRUNTIME const char * +SWIG_UnpackData(const char *c, void *ptr, size_t sz) { + register unsigned char *u = (unsigned char *) ptr; + register const unsigned char *eu = u + sz; + for (; u != eu; ++u) { + register int d = *(c++); + register unsigned char uu = 0; + if ((d >= '0') && (d <= '9')) + uu = ((d - '0') << 4); + else if ((d >= 'a') && (d <= 'f')) + uu = ((d - ('a'-10)) << 4); + else + return (char *) 0; + d = *(c++); + if ((d >= '0') && (d <= '9')) + uu |= (d - '0'); + else if ((d >= 'a') && (d <= 'f')) + uu |= (d - ('a'-10)); + else + return (char *) 0; + *u = uu; + } + return c; +} + +/* + This function will propagate the clientdata field of type to any new + swig_type_info structures that have been added into the list of + equivalent types. It is like calling SWIG_TypeClientData(type, + clientdata) a second time. +*/ +SWIGRUNTIME void +SWIG_PropagateClientDataTL(swig_type_info *tl, swig_type_info *type) { + swig_type_info *equiv = type->next; + swig_type_info *tc; + if (!type->clientdata) return; + while (equiv) { + if (!equiv->converter) { + tc = tl; + while (tc) { + if ((strcmp(tc->name, equiv->name) == 0) && !tc->clientdata) + SWIG_TypeClientDataTL(tl,tc, type->clientdata); + tc = tc->prev; + } + } + equiv = equiv->next; + } +} + +/* + Pack 'void *' into a string buffer. +*/ +SWIGRUNTIME char * +SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) { + char *r = buff; + if ((2*sizeof(void *) + 2) > bsz) return 0; + *(r++) = '_'; + r = SWIG_PackData(r,&ptr,sizeof(void *)); + if (strlen(name) + 1 > (bsz - (r - buff))) return 0; + strcpy(r,name); + return buff; +} + +SWIGRUNTIME const char * +SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) { + if (*c != '_') { + if (strcmp(c,"NULL") == 0) { + *ptr = (void *) 0; + return name; + } else { + return 0; + } + } + return SWIG_UnpackData(++c,ptr,sizeof(void *)); +} + +SWIGRUNTIME char * +SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) { + char *r = buff; + size_t lname = (name ? strlen(name) : 0); + if ((2*sz + 2 + lname) > bsz) return 0; + *(r++) = '_'; + r = SWIG_PackData(r,ptr,sz); + if (lname) { + strncpy(r,name,lname+1); + } else { + *r = 0; + } + return buff; +} + +SWIGRUNTIME const char * +SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) { + if (*c != '_') { + if (strcmp(c,"NULL") == 0) { + memset(ptr,0,sz); + return name; + } else { + return 0; + } + } + return SWIG_UnpackData(++c,ptr,sz); +} + +#ifdef __cplusplus +} +#endif + +/*********************************************************************** + * common.swg + * + * This file contains generic SWIG runtime support for pointer + * type checking as well as a few commonly used macros to control + * external linkage. + * + * Author : David Beazley (beazley@cs.uchicago.edu) + * + * Copyright (c) 1999-2000, The University of Chicago + * + * This file may be freely redistributed without license or fee provided + * this copyright message remains intact. + ************************************************************************/ + + +#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# if !defined(STATIC_LINKED) +# define SWIGEXPORT(a) __declspec(dllexport) a +# else +# define SWIGEXPORT(a) a +# endif +#else +# define SWIGEXPORT(a) a +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +/*************************************************************************/ + + +/* The static type info list */ + +static swig_type_info *swig_type_list = 0; +static swig_type_info **swig_type_list_handle = &swig_type_list; + + +/* Register a type mapping with the type-checking */ +static swig_type_info * +SWIG_TypeRegister(swig_type_info *ti) { + return SWIG_TypeRegisterTL(swig_type_list_handle, ti); +} + +/* Search for a swig_type_info structure */ +static swig_type_info * +SWIG_TypeQuery(const char *name) { + return SWIG_TypeQueryTL(*swig_type_list_handle, name); +} + +/* Set the clientdata field for a type */ +static void +SWIG_TypeClientData(swig_type_info *ti, void *clientdata) { + SWIG_TypeClientDataTL(*swig_type_list_handle, ti, clientdata); +} + +/* This function will propagate the clientdata field of type to +* any new swig_type_info structures that have been added into the list +* of equivalent types. It is like calling +* SWIG_TypeClientData(type, clientdata) a second time. +*/ +static void +SWIG_PropagateClientData(swig_type_info *type) { + SWIG_PropagateClientDataTL(*swig_type_list_handle, type); +} + +#ifdef __cplusplus +} +#endif + +/* ---------------------------------------------------------------------- -*- c -*- + * perl5.swg + * + * Perl5 runtime library + * $Header: /cvsroot/swig/SWIG/Lib/perl5/perlrun.swg,v 1.20 2004/11/29 23:13:57 wuzzeb Exp $ + * ----------------------------------------------------------------------------- */ + +#define SWIGPERL +#define SWIGPERL5 +#ifdef __cplusplus +/* Needed on some windows machines---since MS plays funny games with the header files under C++ */ +#include <math.h> +#include <stdlib.h> +extern "C" { +#endif +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" + +/* Get rid of free and malloc defined by perl */ +#undef free +#undef malloc + +#ifndef pTHX_ +#define pTHX_ +#endif + +#include <string.h> +#ifdef __cplusplus +} +#endif + +/* Macro to call an XS function */ + +#ifdef PERL_OBJECT +# define SWIG_CALLXS(_name) _name(cv,pPerl) +#else +# ifndef MULTIPLICITY +# define SWIG_CALLXS(_name) _name(cv) +# else +# define SWIG_CALLXS(_name) _name(PERL_GET_THX, cv) +# endif +#endif + +/* Contract support */ + +#define SWIG_contract_assert(expr,msg) if (!(expr)) { SWIG_croak(msg); } else + +/* Note: SwigMagicFuncHack is a typedef used to get the C++ compiler to just shut up already */ + +#ifdef PERL_OBJECT +#define MAGIC_PPERL CPerlObj *pPerl = (CPerlObj *) this; +typedef int (CPerlObj::*SwigMagicFunc)(SV *, MAGIC *); + +#ifdef __cplusplus +extern "C" { +#endif +typedef int (CPerlObj::*SwigMagicFuncHack)(SV *, MAGIC *); +#ifdef __cplusplus +} +#endif + +#define SWIG_MAGIC(a,b) (SV *a, MAGIC *b) +#define SWIGCLASS_STATIC +#else +#define MAGIC_PPERL +#define SWIGCLASS_STATIC static +#ifndef MULTIPLICITY +#define SWIG_MAGIC(a,b) (SV *a, MAGIC *b) +typedef int (*SwigMagicFunc)(SV *, MAGIC *); + +#ifdef __cplusplus +extern "C" { +#endif +typedef int (*SwigMagicFuncHack)(SV *, MAGIC *); +#ifdef __cplusplus +} +#endif + + +#else +#define SWIG_MAGIC(a,b) (struct interpreter *interp, SV *a, MAGIC *b) +typedef int (*SwigMagicFunc)(struct interpreter *, SV *, MAGIC *); +#ifdef __cplusplus +extern "C" { +#endif +typedef int (*SwigMagicFuncHack)(struct interpreter *, SV *, MAGIC *); +#ifdef __cplusplus +} +#endif + +#endif +#endif + +#if defined(WIN32) && defined(PERL_OBJECT) && !defined(PerlIO_exportFILE) +#define PerlIO_exportFILE(fh,fl) (FILE*)(fh) +#endif + +/* Modifications for newer Perl 5.005 releases */ + +#if !defined(PERL_REVISION) || ((PERL_REVISION >= 5) && ((PERL_VERSION < 5) || ((PERL_VERSION == 5) && (PERL_SUBVERSION < 50)))) +# ifndef PL_sv_yes +# define PL_sv_yes sv_yes +# endif +# ifndef PL_sv_undef +# define PL_sv_undef sv_undef +# endif +# ifndef PL_na +# define PL_na na +# endif +#endif + +#include <stdlib.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define SWIG_OWNER 1 +#define SWIG_SHADOW 2 + +/* Common SWIG API */ + +#ifdef PERL_OBJECT +# define SWIG_ConvertPtr(obj, pp, type, flags) \ + SWIG_Perl_ConvertPtr(pPerl, obj, pp, type, flags) +# define SWIG_NewPointerObj(p, type, flags) \ + SWIG_Perl_NewPointerObj(pPerl, p, type, flags) +# define SWIG_MakePackedObj(sv, p, s, type) \ + SWIG_Perl_MakePackedObj(pPerl, sv, p, s, type) +# define SWIG_ConvertPacked(obj, p, s, type, flags) \ + SWIG_Perl_ConvertPacked(pPerl, obj, p, s, type, flags) + +#else +# define SWIG_ConvertPtr(obj, pp, type, flags) \ + SWIG_Perl_ConvertPtr(obj, pp, type, flags) +# define SWIG_NewPointerObj(p, type, flags) \ + SWIG_Perl_NewPointerObj(p, type, flags) +# define SWIG_MakePackedObj(sv, p, s, type) \ + SWIG_Perl_MakePackedObj(sv, p, s, type ) +# define SWIG_ConvertPacked(obj, p, s, type, flags) \ + SWIG_Perl_ConvertPacked(obj, p, s, type, flags) +#endif + +/* Perl-specific API */ +#ifdef PERL_OBJECT +# define SWIG_MakePtr(sv, ptr, type, flags) \ + SWIG_Perl_MakePtr(pPerl, sv, ptr, type, flags) +# define SWIG_SetError(str) \ + SWIG_Perl_SetError(pPerl, str) +#else +# define SWIG_MakePtr(sv, ptr, type, flags) \ + SWIG_Perl_MakePtr(sv, ptr, type, flags) +# define SWIG_SetError(str) \ + SWIG_Perl_SetError(str) +# define SWIG_SetErrorSV(str) \ + SWIG_Perl_SetErrorSV(str) +#endif + +#define SWIG_SetErrorf SWIG_Perl_SetErrorf + + +#ifdef PERL_OBJECT +# define SWIG_MAYBE_PERL_OBJECT CPerlObj *pPerl, +#else +# define SWIG_MAYBE_PERL_OBJECT +#endif + +static swig_type_info ** +SWIG_Perl_GetTypeListHandle() { + static void *type_pointer = (void *)0; + SV *pointer; + + /* first check if pointer already created */ + if (!type_pointer) { + pointer = get_sv("swig_runtime_data::type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME, FALSE); + if (pointer && SvOK(pointer)) { + type_pointer = INT2PTR(swig_type_info **, SvIV(pointer)); + } + } + + return (swig_type_info **) type_pointer; +} + +/* + Search for a swig_type_info structure + */ +SWIGRUNTIMEINLINE swig_type_info * +SWIG_Perl_GetTypeList() { + swig_type_info **tlh = SWIG_Perl_GetTypeListHandle(); + return tlh ? *tlh : (swig_type_info*)0; +} + +#define SWIG_Runtime_GetTypeList SWIG_Perl_GetTypeList + +static swig_type_info * +SWIG_Perl_TypeCheckRV(SWIG_MAYBE_PERL_OBJECT SV *rv, swig_type_info *ty) { + swig_type_info *s; + if (!ty) return 0; /* Void pointer */ + s = ty->next; /* First element always just a name */ + do { + if (sv_derived_from(rv, (char *) s->name)) { + if (s == ty->next) return s; + /* Move s to the top of the linked list */ + s->prev->next = s->next; + if (s->next) { + s->next->prev = s->prev; + } + /* Insert s as second element in the list */ + s->next = ty->next; + if (ty->next) ty->next->prev = s; + ty->next = s; + s->prev = ty; + return s; + } + s = s->next; + } while (s && (s != ty->next)); + return 0; +} + +/* Function for getting a pointer value */ + +static int +SWIG_Perl_ConvertPtr(SWIG_MAYBE_PERL_OBJECT SV *sv, void **ptr, swig_type_info *_t, int flags) { + swig_type_info *tc; + void *voidptr = (void *)0; + + /* If magical, apply more magic */ + if (SvGMAGICAL(sv)) + mg_get(sv); + + /* Check to see if this is an object */ + if (sv_isobject(sv)) { + SV *tsv = (SV*) SvRV(sv); + IV tmp = 0; + if ((SvTYPE(tsv) == SVt_PVHV)) { + MAGIC *mg; + if (SvMAGICAL(tsv)) { + mg = mg_find(tsv,'P'); + if (mg) { + sv = mg->mg_obj; + if (sv_isobject(sv)) { + tmp = SvIV((SV*)SvRV(sv)); + } + } + } else { + return -1; + } + } else { + tmp = SvIV((SV*)SvRV(sv)); + } + voidptr = (void *)tmp; + if (!_t) { + *(ptr) = voidptr; + return 0; + } + } else if (! SvOK(sv)) { /* Check for undef */ + *(ptr) = (void *) 0; + return 0; + } else if (SvTYPE(sv) == SVt_RV) { /* Check for NULL pointer */ + *(ptr) = (void *) 0; + if (!SvROK(sv)) + return 0; + else + return -1; + } else { /* Don't know what it is */ + *(ptr) = (void *) 0; + return -1; + } + if (_t) { + /* Now see if the types match */ + char *_c = HvNAME(SvSTASH(SvRV(sv))); + tc = SWIG_TypeCheck(_c,_t); + if (!tc) { + *ptr = voidptr; + return -1; + } + *ptr = SWIG_TypeCast(tc,voidptr); + return 0; + } + *ptr = voidptr; + return 0; +} + +static void +SWIG_Perl_MakePtr(SWIG_MAYBE_PERL_OBJECT SV *sv, void *ptr, swig_type_info *t, int flags) { + if (ptr && (flags & SWIG_SHADOW)) { + SV *self; + SV *obj=newSV(0); + HV *hash=newHV(); + HV *stash; + sv_setref_pv(obj, (char *) t->name, ptr); + stash=SvSTASH(SvRV(obj)); + if (flags & SWIG_OWNER) { + HV *hv; + GV *gv=*(GV**)hv_fetch(stash, "OWNER", 5, TRUE); + if (!isGV(gv)) + gv_init(gv, stash, "OWNER", 5, FALSE); + hv=GvHVn(gv); + hv_store_ent(hv, obj, newSViv(1), 0); + } + sv_magic((SV *)hash, (SV *)obj, 'P', Nullch, 0); + SvREFCNT_dec(obj); + self=newRV_noinc((SV *)hash); + sv_setsv(sv, self); + SvREFCNT_dec((SV *)self); + sv_bless(sv, stash); + } + else { + sv_setref_pv(sv, (char *) t->name, ptr); + } +} + +static SWIGINLINE SV * +SWIG_Perl_NewPointerObj(SWIG_MAYBE_PERL_OBJECT void *ptr, swig_type_info *t, int flags) { + SV *result = sv_newmortal(); + SWIG_MakePtr(result, ptr, t, flags); + return result; +} + +static void + SWIG_Perl_MakePackedObj(SWIG_MAYBE_PERL_OBJECT SV *sv, void *ptr, int sz, swig_type_info *type) { + char result[1024]; + char *r = result; + if ((2*sz + 1 + strlen(type->name)) > 1000) return; + *(r++) = '_'; + r = SWIG_PackData(r,ptr,sz); + strcpy(r,type->name); + sv_setpv(sv, result); +} + +/* Convert a packed value value */ +static int +SWIG_Perl_ConvertPacked(SWIG_MAYBE_PERL_OBJECT SV *obj, void *ptr, int sz, swig_type_info *ty, int flags) { + swig_type_info *tc; + const char *c = 0; + + if ((!obj) || (!SvOK(obj))) return -1; + c = SvPV(obj, PL_na); + /* Pointer values must start with leading underscore */ + if (*c != '_') return -1; + c++; + c = SWIG_UnpackData(c,ptr,sz); + if (ty) { + tc = SWIG_TypeCheck(c,ty); + if (!tc) return -1; + } + return 0; +} + +static SWIGINLINE void +SWIG_Perl_SetError(SWIG_MAYBE_PERL_OBJECT const char *error) { + if (error) sv_setpv(perl_get_sv("@", TRUE), error); +} + +static SWIGINLINE void +SWIG_Perl_SetErrorSV(SWIG_MAYBE_PERL_OBJECT SV *error) { + if (error) sv_setsv(perl_get_sv("@", TRUE), error); +} + +static void +SWIG_Perl_SetErrorf(const char *fmt, ...) { + va_list args; + va_start(args, fmt); + sv_vsetpvfn(perl_get_sv("@", TRUE), fmt, strlen(fmt), &args, Null(SV**), 0, Null(bool*)); + va_end(args); +} + +/* Macros for low-level exception handling */ +#define SWIG_fail goto fail +#define SWIG_croak(x) { SWIG_SetError(x); goto fail; } +#define SWIG_croakSV(x) { SWIG_SetErrorSV(x); goto fail; } +/* most preprocessors do not support vararg macros :-( */ +/* #define SWIG_croakf(x...) { SWIG_SetErrorf(x); goto fail; } */ + + +typedef XS(SwigPerlWrapper); +typedef SwigPerlWrapper *SwigPerlWrapperPtr; + +/* Structure for command table */ +typedef struct { + const char *name; + SwigPerlWrapperPtr wrapper; +} swig_command_info; + +/* Information for constant table */ + +#define SWIG_INT 1 +#define SWIG_FLOAT 2 +#define SWIG_STRING 3 +#define SWIG_POINTER 4 +#define SWIG_BINARY 5 + +/* Constant information structure */ +typedef struct swig_constant_info { + int type; + const char *name; + long lvalue; + double dvalue; + void *pvalue; + swig_type_info **ptype; +} swig_constant_info; + +#ifdef __cplusplus +} +#endif + +/* Structure for variable table */ +typedef struct { + const char *name; + SwigMagicFunc set; + SwigMagicFunc get; + swig_type_info **type; +} swig_variable_info; + +/* Magic variable code */ +#ifndef PERL_OBJECT +#define swig_create_magic(s,a,b,c) _swig_create_magic(s,a,b,c) + #ifndef MULTIPLICITY + static void _swig_create_magic(SV *sv, char *name, int (*set)(SV *, MAGIC *), int (*get)(SV *,MAGIC *)) { + #else + static void _swig_create_magic(SV *sv, char *name, int (*set)(struct interpreter*, SV *, MAGIC *), int (*get)(struct interpreter*, SV *,MAGIC *)) { + #endif +#else +# define swig_create_magic(s,a,b,c) _swig_create_magic(pPerl,s,a,b,c) +static void _swig_create_magic(CPerlObj *pPerl, SV *sv, const char *name, int (CPerlObj::*set)(SV *, MAGIC *), int (CPerlObj::*get)(SV *, MAGIC *)) { +#endif + MAGIC *mg; + sv_magic(sv,sv,'U',(char *) name,strlen(name)); + mg = mg_find(sv,'U'); + mg->mg_virtual = (MGVTBL *) malloc(sizeof(MGVTBL)); + mg->mg_virtual->svt_get = (SwigMagicFuncHack) get; + mg->mg_virtual->svt_set = (SwigMagicFuncHack) set; + mg->mg_virtual->svt_len = 0; + mg->mg_virtual->svt_clear = 0; + mg->mg_virtual->svt_free = 0; +} + + + + + + +#ifdef do_open + #undef do_open +#endif +#ifdef do_close + #undef do_close +#endif +#ifdef scalar + #undef scalar +#endif +#ifdef list + #undef list +#endif +#ifdef apply + #undef apply +#endif +#ifdef convert + #undef convert +#endif +#ifdef Error + #undef Error +#endif +#ifdef form + #undef form +#endif +#ifdef vform + #undef vform +#endif +#ifdef LABEL + #undef LABEL +#endif +#ifdef METHOD + #undef METHOD +#endif +#ifdef Move + #undef Move +#endif +#ifdef yylex + #undef yylex +#endif +#ifdef yyparse + #undef yyparse +#endif +#ifdef yyerror + #undef yyerror +#endif +#ifdef invert + #undef invert +#endif +#ifdef ref + #undef ref +#endif +#ifdef ENTER + #undef ENTER +#endif + + +/* -------- TYPES TABLE (BEGIN) -------- */ + +static swig_type_info *swig_types[1]; + +/* -------- TYPES TABLE (END) -------- */ + +#define SWIG_init boot_DumpRenderTreeSupport + +#define SWIG_name "DumpRenderTreeSupportc::boot_DumpRenderTreeSupport" +#define SWIG_prefix "DumpRenderTreeSupportc::" + +#ifdef __cplusplus +extern "C" +#endif +#ifndef PERL_OBJECT +#ifndef MULTIPLICITY +SWIGEXPORT(void) SWIG_init (CV* cv); +#else +SWIGEXPORT(void) SWIG_init (pTHXo_ CV* cv); +#endif +#else +SWIGEXPORT(void) SWIG_init (CV *cv, CPerlObj *); +#endif + +int processIsCrashing(int); +#ifdef PERL_OBJECT +#define MAGIC_CLASS _wrap_DumpRenderTreeSupport_var:: +class _wrap_DumpRenderTreeSupport_var : public CPerlObj { +public: +#else +#define MAGIC_CLASS +#endif +SWIGCLASS_STATIC int swig_magic_readonly(pTHX_ SV *sv, MAGIC *mg) { + MAGIC_PPERL + sv = sv; mg = mg; + croak("Value is read-only."); + return 0; +} + + +#ifdef PERL_OBJECT +}; +#endif + +#ifdef __cplusplus +extern "C" { +#endif +XS(_wrap_processIsCrashing) { + { + int arg1 ; + int result; + int argvi = 0; + dXSARGS; + + if ((items < 1) || (items > 1)) { + SWIG_croak("Usage: processIsCrashing(pid);"); + } + arg1 = (int) SvIV(ST(0)); + result = (int)processIsCrashing(arg1); + + ST(argvi) = sv_newmortal(); + sv_setiv(ST(argvi++), (IV) result); + XSRETURN(argvi); + fail: + ; + } + croak(Nullch); +} + + + +/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */ + + +static swig_type_info *swig_types_initial[] = { +0 +}; + + +/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */ + +static swig_constant_info swig_constants[] = { +{0,0,0,0,0,0} +}; +#ifdef __cplusplus +} +#endif +static swig_variable_info swig_variables[] = { +{0,0,0,0} +}; +static swig_command_info swig_commands[] = { +{"DumpRenderTreeSupportc::processIsCrashing", _wrap_processIsCrashing}, +{0,0} +}; + + +static void SWIG_Perl_SetTypeListHandle(swig_type_info **handle) { + SV *pointer; + + /* create a new pointer */ + pointer = get_sv("swig_runtime_data::type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME, TRUE); + sv_setiv(pointer, PTR2IV(swig_type_list_handle)); +} + +static swig_type_info ** +SWIG_Perl_LookupTypePointer(swig_type_info **type_list_handle) { + swig_type_info **type_pointer; + + /* first check if module already created */ + type_pointer = SWIG_Perl_GetTypeListHandle(); + if (type_pointer) { + return type_pointer; + } else { + /* create a new module and variable */ + SWIG_Perl_SetTypeListHandle(type_list_handle); + return type_list_handle; + } +} + + +#ifdef __cplusplus +extern "C" +#endif + +XS(SWIG_init) { + dXSARGS; + int i; + static int _init = 0; + if (!_init) { + swig_type_list_handle = SWIG_Perl_LookupTypePointer(swig_type_list_handle); + for (i = 0; swig_types_initial[i]; i++) { + swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]); + } + _init = 1; + } + + /* Install commands */ + for (i = 0; swig_commands[i].name; i++) { + newXS((char*) swig_commands[i].name,swig_commands[i].wrapper, (char*)__FILE__); + } + + /* Install variables */ + for (i = 0; swig_variables[i].name; i++) { + SV *sv; + sv = perl_get_sv((char*) swig_variables[i].name, TRUE | 0x2); + if (swig_variables[i].type) { + SWIG_MakePtr(sv,(void *)1, *swig_variables[i].type,0); + } else { + sv_setiv(sv,(IV) 0); + } + swig_create_magic(sv, (char *) swig_variables[i].name, swig_variables[i].set, swig_variables[i].get); + } + + /* Install constant */ + for (i = 0; swig_constants[i].type; i++) { + SV *sv; + sv = perl_get_sv((char*)swig_constants[i].name, TRUE | 0x2); + switch(swig_constants[i].type) { + case SWIG_INT: + sv_setiv(sv, (IV) swig_constants[i].lvalue); + break; + case SWIG_FLOAT: + sv_setnv(sv, (double) swig_constants[i].dvalue); + break; + case SWIG_STRING: + sv_setpv(sv, (char *) swig_constants[i].pvalue); + break; + case SWIG_POINTER: + SWIG_MakePtr(sv, swig_constants[i].pvalue, *(swig_constants[i].ptype),0); + break; + case SWIG_BINARY: + SWIG_MakePackedObj(sv, swig_constants[i].pvalue, swig_constants[i].lvalue, *(swig_constants[i].ptype)); + break; + default: + break; + } + SvREADONLY_on(sv); + } + + ST(0) = &PL_sv_yes; + XSRETURN(1); +} + diff --git a/WebKitTools/DumpRenderTree/mac/PerlSupport/Makefile b/WebKitTools/DumpRenderTree/mac/PerlSupport/Makefile index 6c97877..56b2ed2 100644 --- a/WebKitTools/DumpRenderTree/mac/PerlSupport/Makefile +++ b/WebKitTools/DumpRenderTree/mac/PerlSupport/Makefile @@ -24,39 +24,45 @@ CONFIGURATION_BUILD_DIR ?= . OUTPUT_DIR=$(CONFIGURATION_BUILD_DIR) -WRAPPER=$(OUTPUT_DIR)/DerivedSources/DumpRenderTree/DumpRenderTreeSupport_wrap.c +WRAPPER_DIR=$(OUTPUT_DIR)/DerivedSources/DumpRenderTree +WRAPPER=$(WRAPPER_DIR)/DumpRenderTreeSupport_wrap.c PERL_MODULE=$(OUTPUT_DIR)/DumpRenderTreeSupport.pm DYLIB=$(OUTPUT_DIR)/DumpRenderTreeSupport.dylib DUMPRENDERTREE=$(OUTPUT_DIR)/DumpRenderTree +PERL=/usr/bin/perl OSX_VERSION=$(shell sw_vers -productVersion | cut -d. -f 2) ifneq "$(OSX_VERSION)" "4" -PERL=/usr/bin/perl + SWIG=/usr/bin/swig all: $(DYLIB) $(PERL_MODULE) $(WRAPPER) $(PERL_MODULE): DumpRenderTreeSupport.c $(DUMPRENDERTREE) - mkdir -p $$(dirname $(WRAPPER)) + mkdir -p $(WRAPPER_DIR) $(SWIG) -o $(WRAPPER) -outdir $(OUTPUT_DIR) -perl -module DumpRenderTreeSupport $< -$(DYLIB): DumpRenderTreeSupport.c $(WRAPPER) - gcc -g -dynamiclib -o $(DYLIB) `$(PERL) -MExtUtils::Embed -eperl_inc` `$(PERL) -MExtUtils::Embed -eldopts` $^ - else -all: $(PERL_MODULE) +all: $(DYLIB) $(PERL_MODULE) + +$(WRAPPER): DumpRenderTreeSupport_wrapTiger.c $(DUMPRENDERTREE) + mkdir -p $(WRAPPER_DIR) + cp DumpRenderTreeSupport_wrapTiger.c $(WRAPPER) -$(PERL_MODULE): DumpRenderTreeSupportTiger.pm - cp $^ $(PERL_MODULE) +$(PERL_MODULE): DumpRenderTreeSupportTiger.pm $(DUMPRENDERTREE) + cp DumpRenderTreeSupportTiger.pm $(PERL_MODULE) endif +$(DYLIB): DumpRenderTreeSupport.c $(WRAPPER) + gcc -g -dynamiclib -o $(DYLIB) `$(PERL) -MExtUtils::Embed -eperl_inc` `$(PERL) -MExtUtils::Embed -eldopts` $^ + clean: rm -f $(WRAPPER) $(PERL_MODULE) $(DYLIB) diff --git a/WebKitTools/DumpRenderTree/mac/ResourceLoadDelegate.mm b/WebKitTools/DumpRenderTree/mac/ResourceLoadDelegate.mm index 0089f7f..3aaba59 100644 --- a/WebKitTools/DumpRenderTree/mac/ResourceLoadDelegate.mm +++ b/WebKitTools/DumpRenderTree/mac/ResourceLoadDelegate.mm @@ -153,6 +153,20 @@ - (void)webView:(WebView *)wv resource:(id)identifier didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge fromDataSource:(WebDataSource *)dataSource { + if (!gLayoutTestController->handlesAuthenticationChallenges()) + return; + + const char* user = gLayoutTestController->authenticationUsername().c_str(); + NSString *nsUser = [NSString stringWithFormat:@"%s", user ? user : ""]; + + const char* password = gLayoutTestController->authenticationPassword().c_str(); + NSString *nsPassword = [NSString stringWithFormat:@"%s", password ? password : ""]; + + NSString *string = [NSString stringWithFormat:@"%@ - didReceiveAuthenticationChallenge - Responding with %@:%@", identifier, nsUser, nsPassword]; + printf("%s\n", [string UTF8String]); + + [[challenge sender] useCredential:[NSURLCredential credentialWithUser:nsUser password:nsPassword persistence:NSURLCredentialPersistenceForSession] + forAuthenticationChallenge:challenge]; } - (void)webView:(WebView *)wv resource:(id)identifier didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge fromDataSource:(WebDataSource *)dataSource diff --git a/WebKitTools/DumpRenderTree/mac/UIDelegate.mm b/WebKitTools/DumpRenderTree/mac/UIDelegate.mm index 807ea08..a52d5be 100644 --- a/WebKitTools/DumpRenderTree/mac/UIDelegate.mm +++ b/WebKitTools/DumpRenderTree/mac/UIDelegate.mm @@ -34,6 +34,7 @@ #import "EventSendingController.h" #import "LayoutTestController.h" #import <WebKit/WebFramePrivate.h> +#import <WebKit/WebGeolocationPrivate.h> #import <WebKit/WebHTMLViewPrivate.h> #import <WebKit/WebSecurityOriginPrivate.h> #import <WebKit/WebView.h> @@ -150,6 +151,12 @@ DumpRenderTreeDraggingInfo *draggingInfo = nil; printf("UI DELEGATE STATUS CALLBACK: setStatusText:%s\n", [text UTF8String]); } +- (void)webView:(WebView *)sender frame:(WebFrame *)frame requestGeolocationPermission:(WebGeolocation *)geolocation securityOrigin:(WebSecurityOrigin *)origin +{ + if (gLayoutTestController->isGeolocationPermissionSet()) + [geolocation setIsAllowed:gLayoutTestController->geolocationPermission()]; +} + - (void)dealloc { [draggingInfo release]; diff --git a/WebKitTools/DumpRenderTree/qt/DumpRenderTree.cpp b/WebKitTools/DumpRenderTree/qt/DumpRenderTree.cpp index 1afb761..83626ac 100644 --- a/WebKitTools/DumpRenderTree/qt/DumpRenderTree.cpp +++ b/WebKitTools/DumpRenderTree/qt/DumpRenderTree.cpp @@ -45,6 +45,7 @@ #include <QUrl> #include <QFocusEvent> #include <QFontDatabase> +#include <QNetworkRequest> #include <qwebpage.h> #include <qwebframe.h> @@ -83,9 +84,14 @@ public: bool javaScriptConfirm(QWebFrame *frame, const QString& msg); bool javaScriptPrompt(QWebFrame *frame, const QString& msg, const QString& defaultValue, QString* result); + void resetSettings(); + public slots: bool shouldInterruptJavaScript() { return false; } +protected: + bool acceptNavigationRequest(QWebFrame* frame, const QNetworkRequest& request, NavigationType type); + private slots: void setViewGeometry(const QRect &r) { @@ -100,21 +106,42 @@ private: WebPage::WebPage(QWidget *parent, DumpRenderTree *drt) : QWebPage(parent), m_drt(drt) { - settings()->setFontSize(QWebSettings::MinimumFontSize, 5); - settings()->setFontSize(QWebSettings::MinimumLogicalFontSize, 5); - // To get DRT compliant to some layout tests lets set the default fontsize to 13. - settings()->setFontSize(QWebSettings::DefaultFontSize, 13); - settings()->setFontSize(QWebSettings::DefaultFixedFontSize, 13); - settings()->setAttribute(QWebSettings::JavascriptCanOpenWindows, true); - settings()->setAttribute(QWebSettings::JavascriptCanAccessClipboard, true); - settings()->setAttribute(QWebSettings::LinksIncludedInFocusChain, false); - settings()->setAttribute(QWebSettings::PluginsEnabled, true); + QWebSettings* globalSettings = QWebSettings::globalSettings(); + + globalSettings->setFontSize(QWebSettings::MinimumFontSize, 5); + globalSettings->setFontSize(QWebSettings::MinimumLogicalFontSize, 5); + globalSettings->setFontSize(QWebSettings::DefaultFontSize, 16); + globalSettings->setFontSize(QWebSettings::DefaultFixedFontSize, 13); + + globalSettings->setAttribute(QWebSettings::JavascriptCanOpenWindows, true); + globalSettings->setAttribute(QWebSettings::JavascriptCanAccessClipboard, true); + globalSettings->setAttribute(QWebSettings::LinksIncludedInFocusChain, false); + globalSettings->setAttribute(QWebSettings::PluginsEnabled, true); + globalSettings->setAttribute(QWebSettings::LocalContentCanAccessRemoteUrls, true); + globalSettings->setAttribute(QWebSettings::JavascriptEnabled, true); + globalSettings->setAttribute(QWebSettings::PrivateBrowsingEnabled, false); + globalSettings->setAttribute(QWebSettings::OfflineWebApplicationCacheEnabled, false); + connect(this, SIGNAL(geometryChangeRequested(const QRect &)), this, SLOT(setViewGeometry(const QRect & ))); setPluginFactory(new TestPlugin(this)); } +void WebPage::resetSettings() +{ + // After each layout test, reset the settings that may have been changed by + // layoutTestController.overridePreference() or similar. + + settings()->resetFontSize(QWebSettings::DefaultFontSize); + + settings()->resetAttribute(QWebSettings::JavascriptCanOpenWindows); + settings()->resetAttribute(QWebSettings::JavascriptEnabled); + settings()->resetAttribute(QWebSettings::PrivateBrowsingEnabled); + settings()->resetAttribute(QWebSettings::LinksIncludedInFocusChain); + settings()->resetAttribute(QWebSettings::OfflineWebApplicationCacheEnabled); +} + QWebPage *WebPage::createWindow(QWebPage::WebWindowType) { return m_drt->createWindow(); @@ -143,12 +170,49 @@ bool WebPage::javaScriptPrompt(QWebFrame*, const QString& msg, const QString& de return true; } +bool WebPage::acceptNavigationRequest(QWebFrame* frame, const QNetworkRequest& request, NavigationType type) +{ + if (m_drt->layoutTestController()->waitForPolicy()) { + QString url = QString::fromUtf8(request.url().toEncoded()); + QString typeDescription; + + switch (type) { + case NavigationTypeLinkClicked: + typeDescription = "link clicked"; + break; + case NavigationTypeFormSubmitted: + typeDescription = "form submitted"; + break; + case NavigationTypeBackOrForward: + typeDescription = "back/forward"; + break; + case NavigationTypeReload: + typeDescription = "reload"; + break; + case NavigationTypeFormResubmitted: + typeDescription = "form resubmitted"; + break; + case NavigationTypeOther: + typeDescription = "other"; + break; + default: + typeDescription = "illegal value"; + } + + fprintf(stdout, "Policy delegate: attempt to load %s with navigation type '%s'\n", + url.toUtf8().constData(), typeDescription.toUtf8().constData()); + m_drt->layoutTestController()->notifyDone(); + } + return QWebPage::acceptNavigationRequest(frame, request, type); +} + DumpRenderTree::DumpRenderTree() : m_dumpPixels(false) , m_stdin(0) , m_notifier(0) { qt_drt_overwritePluginDirectories(); + QWebSettings::enablePersistentStorage(); m_controller = new LayoutTestController(this); connect(m_controller, SIGNAL(done()), this, SLOT(dump())); @@ -168,6 +232,8 @@ DumpRenderTree::DumpRenderTree() SLOT(titleChanged(const QString&))); connect(m_page, SIGNAL(databaseQuotaExceeded(QWebFrame*,QString)), this, SLOT(dumpDatabaseQuota(QWebFrame*,QString))); + connect(m_page, SIGNAL(statusBarMessage(const QString&)), + this, SLOT(statusBarMessage(const QString&))); m_eventSender = new EventSender(m_page); m_textInputController = new TextInputController(m_page); @@ -210,6 +276,8 @@ void DumpRenderTree::resetToConsistentStateBeforeTesting() m_page->blockSignals(false); m_page->mainFrame()->setZoomFactor(1.0); + + static_cast<WebPage*>(m_page)->resetSettings(); qt_drt_clearFrameName(m_page->mainFrame()); WorkQueue::shared()->clear(); @@ -217,6 +285,9 @@ void DumpRenderTree::resetToConsistentStateBeforeTesting() //WorkQueue::shared()->setFrozen(false); m_controller->reset(); + QWebSecurityOrigin::resetOriginAccessWhiteLists(); + + setlocale(LC_ALL, ""); } void DumpRenderTree::open(const QUrl& aurl) @@ -463,6 +534,14 @@ void DumpRenderTree::dumpDatabaseQuota(QWebFrame* frame, const QString& dbName) origin.setDatabaseQuota(5 * 1024 * 1024); } +void DumpRenderTree::statusBarMessage(const QString& message) +{ + if (!m_controller->shouldDumpStatusCallbacks()) + return; + + printf("UI DELEGATE STATUS CALLBACK: setStatusText:%s\n", message.toUtf8().constData()); +} + QWebPage *DumpRenderTree::createWindow() { if (!m_controller->canOpenWindows()) diff --git a/WebKitTools/DumpRenderTree/qt/DumpRenderTree.h b/WebKitTools/DumpRenderTree/qt/DumpRenderTree.h index 28ae1b6..c5b4801 100644 --- a/WebKitTools/DumpRenderTree/qt/DumpRenderTree.h +++ b/WebKitTools/DumpRenderTree/qt/DumpRenderTree.h @@ -88,6 +88,7 @@ public Q_SLOTS: void titleChanged(const QString &s); void connectFrame(QWebFrame *frame); void dumpDatabaseQuota(QWebFrame* frame, const QString& dbName); + void statusBarMessage(const QString& message); Q_SIGNALS: void quit(); diff --git a/WebKitTools/DumpRenderTree/qt/DumpRenderTree.pro b/WebKitTools/DumpRenderTree/qt/DumpRenderTree.pro index ca97ed5..0daf8bd 100644 --- a/WebKitTools/DumpRenderTree/qt/DumpRenderTree.pro +++ b/WebKitTools/DumpRenderTree/qt/DumpRenderTree.pro @@ -9,8 +9,8 @@ DESTDIR = ../../../bin CONFIG += link_pkgconfig PKGCONFIG += fontconfig -QT = core gui -macx: QT += xml network +QT = core gui network +macx: QT += xml HEADERS = WorkQueue.h WorkQueueItem.h DumpRenderTree.h jsobjects.h testplugin.h SOURCES = WorkQueue.cpp DumpRenderTree.cpp main.cpp jsobjects.cpp testplugin.cpp @@ -22,3 +22,5 @@ unix:!mac { lessThan(QT_MINOR_VERSION, 4) { DEFINES += QT_BEGIN_NAMESPACE="" QT_END_NAMESPACE="" } + +DEFINES+=USE_SYSTEM_MALLOC diff --git a/WebKitTools/DumpRenderTree/qt/ImageDiff.cpp b/WebKitTools/DumpRenderTree/qt/ImageDiff.cpp index 6aebced..704ca13 100644 --- a/WebKitTools/DumpRenderTree/qt/ImageDiff.cpp +++ b/WebKitTools/DumpRenderTree/qt/ImageDiff.cpp @@ -119,7 +119,7 @@ int main(int argc, char* argv[]) difference = 0; } else { difference = round(difference * 100) / 100; - difference = qMax(difference, 0.01); + difference = qMax(difference, qreal(0.01)); } if (!count) { diff --git a/WebKitTools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro b/WebKitTools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro index 686fbc1..7f502f8 100644 --- a/WebKitTools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro +++ b/WebKitTools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro @@ -1,14 +1,35 @@ TEMPLATE = lib -TARGET = TestNetscapePlugin +TARGET = TestNetscapePlugIn + VPATH = ../../gtk/TestNetscapePlugin ../../TestNetscapePlugIn.subproj include(../../../../WebKit.pri) + DESTDIR = $$OUTPUT_DIR/lib/plugins + +mac { + CONFIG += plugin + CONFIG += plugin_bundle + QMAKE_INFO_PLIST = ../../TestNetscapePlugIn.subproj/Info.plist + QMAKE_PLUGIN_BUNDLE_NAME = $$TARGET + QMAKE_BUNDLE_LOCATION += "Contents/MacOS" + + !build_pass:CONFIG += build_all + debug_and_release:TARGET = $$qtLibraryTarget($$TARGET) +} + INCLUDEPATH += ../../../../JavaScriptCore \ ../../gtk/TestNetscapePlugin/ForwardingHeaders \ ../../gtk/TestNetscapePlugin/ForwardingHeaders/WebKit \ ../../../../WebCore \ ../../../../WebCore/bridge \ ../../TestNetscapePlugIn.subproj -SOURCES = TestNetscapePlugin.cpp \ - PluginObject.cpp \ - TestObject.cpp \ + +SOURCES = PluginObject.cpp \ + TestObject.cpp + +mac { + SOURCES += ../../TestNetscapePlugIn.subproj/main.cpp + LIBS += -framework Carbon +} else { + SOURCES += ../../gtk/TestNetscapePlugin/TestNetscapePlugin.cpp +} diff --git a/WebKitTools/DumpRenderTree/qt/jsobjects.cpp b/WebKitTools/DumpRenderTree/qt/jsobjects.cpp index 7e5e168..b2d8528 100644 --- a/WebKitTools/DumpRenderTree/qt/jsobjects.cpp +++ b/WebKitTools/DumpRenderTree/qt/jsobjects.cpp @@ -27,19 +27,20 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include <jsobjects.h> -#include <qwebpage.h> -#include <qwebhistory.h> -#include <qwebframe.h> -#include <qwebsecurityorigin.h> -#include <qwebdatabase.h> -#include <qevent.h> + +#include "DumpRenderTree.h" +#include "WorkQueue.h" +#include "WorkQueueItem.h" + #include <qapplication.h> #include <qevent.h> #include <qtimer.h> +#include <qwebdatabase.h> +#include <qwebframe.h> +#include <qwebhistory.h> +#include <qwebpage.h> +#include <qwebsecurityorigin.h> -#include "DumpRenderTree.h" -#include "WorkQueueItem.h" -#include "WorkQueue.h" extern void qt_dump_editing_callbacks(bool b); extern void qt_dump_resource_load_callbacks(bool b); extern void qt_drt_setJavaScriptProfilingEnabled(QWebFrame*, bool enabled); @@ -47,7 +48,7 @@ extern bool qt_drt_pauseAnimation(QWebFrame*, const QString &name, double time, extern bool qt_drt_pauseTransitionOfProperty(QWebFrame*, const QString &name, double time, const QString &elementId); extern int qt_drt_numberOfActiveAnimations(QWebFrame*); -QWebFrame *findFrameNamed(const QString &frameName, QWebFrame *frame) +QWebFrame* findFrameNamed(const QString &frameName, QWebFrame* frame) { if (frame->frameName() == frameName) return frame; @@ -64,7 +65,7 @@ bool LoadItem::invoke() const //qDebug() << ">>>LoadItem::invoke"; Q_ASSERT(m_webPage); - QWebFrame *frame = 0; + QWebFrame* frame = 0; const QString t = target(); if (t.isEmpty()) frame = m_webPage->mainFrame(); @@ -128,11 +129,12 @@ void LayoutTestController::reset() m_waitForDone = false; m_dumpTitleChanges = false; m_dumpDatabaseCallbacks = false; + m_dumpStatusCallbacks = false; m_timeoutTimer.stop(); m_topLoadingFrame = 0; + m_waitForPolicy = false; qt_dump_editing_callbacks(false); qt_dump_resource_load_callbacks(false); - QWebSettings::globalSettings()->setAttribute(QWebSettings::PrivateBrowsingEnabled, false); } void LayoutTestController::processWork() @@ -151,6 +153,12 @@ void LayoutTestController::maybeDump(bool success) { Q_ASSERT(sender() == m_topLoadingFrame); + // as the function is called on loadFinished, the test might + // already have dumped and thus no longer be active, thus + // bail out here. + if (!m_isLoading) + return; + m_topLoadingFrame = 0; WorkQueue::shared()->setFrozen(true); // first complete load freezes the queue for the rest of this test @@ -180,6 +188,8 @@ void LayoutTestController::notifyDone() m_timeoutTimer.stop(); emit done(); m_isLoading = false; + m_waitForDone = false; + m_waitForPolicy = false; } int LayoutTestController::windowCount() @@ -237,7 +247,7 @@ void LayoutTestController::queueScript(const QString &url) void LayoutTestController::provisionalLoad() { - QWebFrame *frame = qobject_cast<QWebFrame*>(sender()); + QWebFrame* frame = qobject_cast<QWebFrame*>(sender()); if (!m_topLoadingFrame && m_isLoading) m_topLoadingFrame = frame; } @@ -247,9 +257,8 @@ void LayoutTestController::timerEvent(QTimerEvent *ev) if (ev->timerId() == m_timeoutTimer.timerId()) { qDebug() << ">>>>>>>>>>>>> timeout"; notifyDone(); - } else { + } else QObject::timerEvent(ev); - } } QString LayoutTestController::encodeHostName(const QString &host) @@ -279,14 +288,19 @@ void LayoutTestController::setFixedContentsSize(int width, int height) void LayoutTestController::setPrivateBrowsingEnabled(bool enable) { - QWebSettings::globalSettings()->setAttribute(QWebSettings::PrivateBrowsingEnabled, enable); + m_drt->webPage()->settings()->setAttribute(QWebSettings::PrivateBrowsingEnabled, enable); +} + +void LayoutTestController::setPopupBlockingEnabled(bool enable) +{ + m_drt->webPage()->settings()->setAttribute(QWebSettings::JavascriptCanOpenWindows, !enable); } bool LayoutTestController::pauseAnimationAtTimeOnElementWithId(const QString &animationName, double time, const QString &elementId) { - QWebFrame *frame = m_drt->webPage()->mainFrame(); + QWebFrame* frame = m_drt->webPage()->mainFrame(); Q_ASSERT(frame); return qt_drt_pauseAnimation(frame, animationName, time, elementId); } @@ -295,14 +309,14 @@ bool LayoutTestController::pauseTransitionAtTimeOnElementWithId(const QString &p double time, const QString &elementId) { - QWebFrame *frame = m_drt->webPage()->mainFrame(); + QWebFrame* frame = m_drt->webPage()->mainFrame(); Q_ASSERT(frame); return qt_drt_pauseTransitionOfProperty(frame, propertyName, time, elementId); } unsigned LayoutTestController::numberOfActiveAnimations() const { - QWebFrame *frame = m_drt->webPage()->mainFrame(); + QWebFrame* frame = m_drt->webPage()->mainFrame(); Q_ASSERT(frame); return qt_drt_numberOfActiveAnimations(frame); } @@ -330,23 +344,88 @@ void LayoutTestController::clearAllDatabases() QWebDatabase::removeAllDatabases(); } +void LayoutTestController::whiteListAccessFromOrigin(const QString& sourceOrigin, const QString& destinationProtocol, const QString& destinationHost, bool allowDestinationSubdomains) +{ + QWebSecurityOrigin::whiteListAccessFromOrigin(sourceOrigin, destinationProtocol, destinationHost, allowDestinationSubdomains); +} + +void LayoutTestController::waitForPolicyDelegate() +{ + m_waitForPolicy = true; + waitUntilDone(); +} + +void LayoutTestController::overridePreference(const QString& name, const QVariant& value) +{ + QWebSettings* settings = m_topLoadingFrame->page()->settings(); + + if (name == "WebKitJavaScriptEnabled") + settings->setAttribute(QWebSettings::JavascriptEnabled, value.toBool()); + else if (name == "WebKitTabToLinksPreferenceKey") + settings->setAttribute(QWebSettings::LinksIncludedInFocusChain, value.toBool()); + else if (name == "WebKitOfflineWebApplicationCacheEnabled") + settings->setAttribute(QWebSettings::OfflineWebApplicationCacheEnabled, value.toBool()); + else if (name == "WebKitDefaultFontSize") + settings->setFontSize(QWebSettings::DefaultFontSize, value.toInt()); +} + EventSender::EventSender(QWebPage *parent) : QObject(parent) { m_page = parent; } -void EventSender::mouseDown() -{ +void EventSender::mouseDown(int button) +{ + Qt::MouseButton mouseButton; + switch (button) { + case 0: + mouseButton = Qt::LeftButton; + break; + case 1: + mouseButton = Qt::MidButton; + break; + case 2: + mouseButton = Qt::RightButton; + break; + case 3: + // fast/events/mouse-click-events expects the 4th button to be treated as the middle button + mouseButton = Qt::MidButton; + break; + default: + mouseButton = Qt::LeftButton; + break; + } + // qDebug() << "EventSender::mouseDown" << frame; - QMouseEvent event(QEvent::MouseButtonPress, m_mousePos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + QMouseEvent event(QEvent::MouseButtonPress, m_mousePos, mouseButton, mouseButton, Qt::NoModifier); QApplication::sendEvent(m_page, &event); } -void EventSender::mouseUp() -{ +void EventSender::mouseUp(int button) +{ + Qt::MouseButton mouseButton; + switch (button) { + case 0: + mouseButton = Qt::LeftButton; + break; + case 1: + mouseButton = Qt::MidButton; + break; + case 2: + mouseButton = Qt::RightButton; + break; + case 3: + // fast/events/mouse-click-events expects the 4th button to be treated as the middle button + mouseButton = Qt::MidButton; + break; + default: + mouseButton = Qt::LeftButton; + break; + } + // qDebug() << "EventSender::mouseUp" << frame; - QMouseEvent event(QEvent::MouseButtonRelease, m_mousePos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + QMouseEvent event(QEvent::MouseButtonRelease, m_mousePos, mouseButton, mouseButton, Qt::NoModifier); QApplication::sendEvent(m_page, &event); } @@ -440,17 +519,71 @@ void EventSender::keyDown(const QString &string, const QStringList &modifiers) s = QString(); code = Qt::Key_Home; modifs = 0; - } else { + } else code = string.unicode()->toUpper().unicode(); + } else { + qDebug() << ">>>>>>>>> keyDown" << string; + + if (string.startsWith(QLatin1Char('F')) && string.count() <= 3) { + s = s.mid(1); + int functionKey = s.toInt(); + Q_ASSERT(functionKey >= 1 && functionKey <= 35); + code = Qt::Key_F1 + (functionKey - 1); + // map special keycode strings used by the tests to something that works for Qt/X11 + } else if (string == QLatin1String("leftArrow")) { + s = QString(); + code = Qt::Key_Left; + } else if (string == QLatin1String("rightArrow")) { + s = QString(); + code = Qt::Key_Right; + } else if (string == QLatin1String("upArrow")) { + s = QString(); + code = Qt::Key_Up; + } else if (string == QLatin1String("downArrow")) { + s = QString(); + code = Qt::Key_Down; + } else if (string == QLatin1String("pageUp")) { + s = QString(); + code = Qt::Key_PageUp; + } else if (string == QLatin1String("pageDown")) { + s = QString(); + code = Qt::Key_PageDown; + } else if (string == QLatin1String("home")) { + s = QString(); + code = Qt::Key_Home; + } else if (string == QLatin1String("end")) { + s = QString(); + code = Qt::Key_End; + } else if (string == QLatin1String("delete")) { + s = QString(); + code = Qt::Key_Delete; } } QKeyEvent event(QEvent::KeyPress, code, modifs, s); QApplication::sendEvent(m_page, &event); + QKeyEvent event2(QEvent::KeyRelease, code, modifs, s); + QApplication::sendEvent(m_page, &event2); +} + +void EventSender::contextClick() +{ + QMouseEvent event(QEvent::MouseButtonPress, m_mousePos, Qt::RightButton, Qt::RightButton, Qt::NoModifier); + QApplication::sendEvent(m_page, &event); + QMouseEvent event2(QEvent::MouseButtonRelease, m_mousePos, Qt::RightButton, Qt::RightButton, Qt::NoModifier); + QApplication::sendEvent(m_page, &event2); +} + +void EventSender::scheduleAsynchronousClick() +{ + QMouseEvent* event = new QMouseEvent(QEvent::MouseButtonPress, m_mousePos, Qt::LeftButton, Qt::RightButton, Qt::NoModifier); + QApplication::postEvent(m_page, event); + QMouseEvent* event2 = new QMouseEvent(QEvent::MouseButtonRelease, m_mousePos, Qt::LeftButton, Qt::RightButton, Qt::NoModifier); + QApplication::postEvent(m_page, event2); } -QWebFrame *EventSender::frameUnderMouse() const +QWebFrame* EventSender::frameUnderMouse() const { - QWebFrame *frame = m_page->mainFrame(); + QWebFrame* frame = m_page->mainFrame(); redo: QList<QWebFrame*> children = frame->childFrames(); @@ -478,81 +611,81 @@ void TextInputController::doCommand(const QString &command) if (command == "moveBackwardAndModifySelection:") { modifiers |= Qt::ShiftModifier; keycode = Qt::Key_Left; - } else if(command =="moveDown:") { + } else if (command =="moveDown:") { keycode = Qt::Key_Down; - } else if(command =="moveDownAndModifySelection:") { + } else if (command =="moveDownAndModifySelection:") { modifiers |= Qt::ShiftModifier; keycode = Qt::Key_Down; - } else if(command =="moveForward:") { + } else if (command =="moveForward:") { keycode = Qt::Key_Right; - } else if(command =="moveForwardAndModifySelection:") { + } else if (command =="moveForwardAndModifySelection:") { modifiers |= Qt::ShiftModifier; keycode = Qt::Key_Right; - } else if(command =="moveLeft:") { + } else if (command =="moveLeft:") { keycode = Qt::Key_Left; - } else if(command =="moveLeftAndModifySelection:") { + } else if (command =="moveLeftAndModifySelection:") { modifiers |= Qt::ShiftModifier; keycode = Qt::Key_Left; - } else if(command =="moveRight:") { + } else if (command =="moveRight:") { keycode = Qt::Key_Right; - } else if(command =="moveRightAndModifySelection:") { + } else if (command =="moveRightAndModifySelection:") { modifiers |= Qt::ShiftModifier; keycode = Qt::Key_Right; - } else if(command =="moveToBeginningOfDocument:") { + } else if (command =="moveToBeginningOfDocument:") { modifiers |= Qt::ControlModifier; keycode = Qt::Key_Home; - } else if(command =="moveToBeginningOfLine:") { + } else if (command =="moveToBeginningOfLine:") { keycode = Qt::Key_Home; -// } else if(command =="moveToBeginningOfParagraph:") { - } else if(command =="moveToEndOfDocument:") { +// } else if (command =="moveToBeginningOfParagraph:") { + } else if (command =="moveToEndOfDocument:") { modifiers |= Qt::ControlModifier; keycode = Qt::Key_End; - } else if(command =="moveToEndOfLine:") { + } else if (command =="moveToEndOfLine:") { keycode = Qt::Key_End; -// } else if(command =="moveToEndOfParagraph:") { - } else if(command =="moveUp:") { +// } else if (command =="moveToEndOfParagraph:") { + } else if (command =="moveUp:") { keycode = Qt::Key_Up; - } else if(command =="moveUpAndModifySelection:") { + } else if (command =="moveUpAndModifySelection:") { modifiers |= Qt::ShiftModifier; keycode = Qt::Key_Up; - } else if(command =="moveWordBackward:") { + } else if (command =="moveWordBackward:") { modifiers |= Qt::ControlModifier; keycode = Qt::Key_Up; - } else if(command =="moveWordBackwardAndModifySelection:") { + } else if (command =="moveWordBackwardAndModifySelection:") { modifiers |= Qt::ShiftModifier; modifiers |= Qt::ControlModifier; keycode = Qt::Key_Left; - } else if(command =="moveWordForward:") { + } else if (command =="moveWordForward:") { modifiers |= Qt::ControlModifier; keycode = Qt::Key_Right; - } else if(command =="moveWordForwardAndModifySelection:") { + } else if (command =="moveWordForwardAndModifySelection:") { modifiers |= Qt::ControlModifier; modifiers |= Qt::ShiftModifier; keycode = Qt::Key_Right; - } else if(command =="moveWordLeft:") { + } else if (command =="moveWordLeft:") { modifiers |= Qt::ControlModifier; keycode = Qt::Key_Left; - } else if(command =="moveWordRight:") { + } else if (command =="moveWordRight:") { modifiers |= Qt::ControlModifier; keycode = Qt::Key_Left; - } else if(command =="moveWordRightAndModifySelection:") { + } else if (command =="moveWordRightAndModifySelection:") { modifiers |= Qt::ShiftModifier; modifiers |= Qt::ControlModifier; keycode = Qt::Key_Right; - } else if(command =="moveWordLeftAndModifySelection:") { + } 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:") { + } 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:") { + } else if (command == "deleteBackward:") { keycode = Qt::Key_Backspace; - } else if(command == "deleteForward:") { + } else if (command == "deleteForward:") { keycode = Qt::Key_Delete; } QKeyEvent event(QEvent::KeyPress, keycode, modifiers); diff --git a/WebKitTools/DumpRenderTree/qt/jsobjects.h b/WebKitTools/DumpRenderTree/qt/jsobjects.h index 8e6dd20..c076bb9 100644 --- a/WebKitTools/DumpRenderTree/qt/jsobjects.h +++ b/WebKitTools/DumpRenderTree/qt/jsobjects.h @@ -53,9 +53,11 @@ public: bool shouldDumpBackForwardList() const { return m_dumpBackForwardList; } bool shouldDumpChildrenAsText() const { return m_dumpChildrenAsText; } bool shouldDumpDatabaseCallbacks() const { return m_dumpDatabaseCallbacks; } + bool shouldDumpStatusCallbacks() const { return m_dumpStatusCallbacks; } bool shouldWaitUntilDone() const { return m_waitForDone; } bool canOpenWindows() const { return m_canOpenWindows; } bool shouldDumpTitleChanges() const { return m_dumpTitleChanges; } + bool waitForPolicy() const { return m_waitForPolicy; } void reset(); @@ -70,6 +72,7 @@ public slots: void dumpAsText() { m_textDump = true; } void dumpChildFramesAsText() { m_dumpChildrenAsText = true; } void dumpDatabaseCallbacks() { m_dumpDatabaseCallbacks = true; } + void dumpStatusCallbacks() { m_dumpStatusCallbacks = true; } void setCanOpenWindows() { m_canOpenWindows = true; } void waitUntilDone(); void notifyDone(); @@ -93,16 +96,23 @@ public slots: void setJavaScriptProfilingEnabled(bool enable); void setFixedContentsSize(int width, int height); void setPrivateBrowsingEnabled(bool enable); + void setPopupBlockingEnabled(bool enable); bool pauseAnimationAtTimeOnElementWithId(const QString &animationName, double time, const QString &elementId); bool pauseTransitionAtTimeOnElementWithId(const QString &propertyName, double time, const QString &elementId); unsigned numberOfActiveAnimations() const; + + void whiteListAccessFromOrigin(const QString& sourceOrigin, const QString& destinationProtocol, const QString& destinationHost, bool allowDestinationSubdomains); + void dispatchPendingLoadRequests(); void disableImageLoading(); void setDatabaseQuota(int size); void clearAllDatabases(); + void waitForPolicyDelegate(); + void overridePreference(const QString& name, const QVariant& value); + private slots: void processWork(); @@ -115,6 +125,9 @@ private: bool m_waitForDone; bool m_dumpTitleChanges; bool m_dumpDatabaseCallbacks; + bool m_dumpStatusCallbacks; + bool m_waitForPolicy; + QBasicTimer m_timeoutTimer; QWebFrame *m_topLoadingFrame; WebCore::DumpRenderTree *m_drt; @@ -130,12 +143,14 @@ public: EventSender(QWebPage *parent); public slots: - void mouseDown(); - void mouseUp(); + void mouseDown(int button = 0); + void mouseUp(int button = 0); void mouseMoveTo(int x, int y); void leapForward(int ms); void keyDown(const QString &string, const QStringList &modifiers=QStringList()); void clearKillRing() {} + void contextClick(); + void scheduleAsynchronousClick(); private: QPoint m_mousePos; diff --git a/WebKitTools/DumpRenderTree/win/AccessibilityControllerWin.cpp b/WebKitTools/DumpRenderTree/win/AccessibilityControllerWin.cpp index b6e45f2..ac64efb 100644 --- a/WebKitTools/DumpRenderTree/win/AccessibilityControllerWin.cpp +++ b/WebKitTools/DumpRenderTree/win/AccessibilityControllerWin.cpp @@ -32,13 +32,19 @@ #include <WebCore/COMPtr.h> #include <WebKit/WebKit.h> #include <oleacc.h> +#include <string> + +using namespace std; AccessibilityController::AccessibilityController() + : m_focusEventHook(0) + , m_scrollingStartEventHook(0) { } AccessibilityController::~AccessibilityController() { + setLogFocusEvents(false); } AccessibilityUIElement AccessibilityController::focusedElement() @@ -82,3 +88,76 @@ AccessibilityUIElement AccessibilityController::rootElement() return rootAccessible; } + +static void CALLBACK logEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD, DWORD) +{ + // Get the accessible object for this event. + COMPtr<IAccessible> parentObject; + + VARIANT vChild; + VariantInit(&vChild); + + HRESULT hr = AccessibleObjectFromEvent(hwnd, idObject, idChild, &parentObject, &vChild); + ASSERT(SUCCEEDED(hr)); + + // Get the name of the focused element, and log it to stdout. + BSTR nameBSTR; + hr = parentObject->get_accName(vChild, &nameBSTR); + ASSERT(SUCCEEDED(hr)); + wstring name(nameBSTR, ::SysStringLen(nameBSTR)); + SysFreeString(nameBSTR); + + switch (event) { + case EVENT_OBJECT_FOCUS: + printf("Received focus event for object '%S'.\n", name.c_str()); + break; + + case EVENT_SYSTEM_SCROLLINGSTART: + printf("Received scrolling start event for object '%S'.\n", name.c_str()); + break; + + default: + printf("Received unknown event for object '%S'.\n", name.c_str()); + break; + } +} + +void AccessibilityController::setLogFocusEvents(bool logFocusEvents) +{ + if (!!m_focusEventHook == logFocusEvents) + return; + + if (!logFocusEvents) { + UnhookWinEvent(m_focusEventHook); + m_focusEventHook = 0; + return; + } + + // Ensure that accessibility is initialized for the WebView by querying for + // the root accessible object. + rootElement(); + + m_focusEventHook = SetWinEventHook(EVENT_OBJECT_FOCUS, EVENT_OBJECT_FOCUS, GetModuleHandle(0), logEventProc, GetCurrentProcessId(), 0, WINEVENT_INCONTEXT); + + ASSERT(m_focusEventHook); +} + +void AccessibilityController::setLogScrollingStartEvents(bool logScrollingStartEvents) +{ + if (!!m_scrollingStartEventHook == logScrollingStartEvents) + return; + + if (!logScrollingStartEvents) { + UnhookWinEvent(m_scrollingStartEventHook); + m_scrollingStartEventHook = 0; + return; + } + + // Ensure that accessibility is initialized for the WebView by querying for + // the root accessible object. + rootElement(); + + m_scrollingStartEventHook = SetWinEventHook(EVENT_SYSTEM_SCROLLINGSTART, EVENT_SYSTEM_SCROLLINGSTART, GetModuleHandle(0), logEventProc, GetCurrentProcessId(), 0, WINEVENT_INCONTEXT); + + ASSERT(m_scrollingStartEventHook); +} diff --git a/WebKitTools/DumpRenderTree/win/AccessibilityUIElementWin.cpp b/WebKitTools/DumpRenderTree/win/AccessibilityUIElementWin.cpp index cfcfc54..de3d9ff 100644 --- a/WebKitTools/DumpRenderTree/win/AccessibilityUIElementWin.cpp +++ b/WebKitTools/DumpRenderTree/win/AccessibilityUIElementWin.cpp @@ -157,6 +157,11 @@ JSStringRef AccessibilityUIElement::role() return JSStringCreateWithCharacters(roleText, _tcslen(roleText)); } +JSStringRef AccessibilityUIElement::subrole() +{ + return 0; +} + JSStringRef AccessibilityUIElement::title() { BSTR titleBSTR; @@ -325,6 +330,11 @@ JSStringRef AccessibilityUIElement::boundsForRange(unsigned location, unsigned l return JSStringCreateWithCharacters(0, 0); } +JSStringRef AccessibilityUIElement::stringForRange(unsigned, unsigned) +{ + return JSStringCreateWithCharacters(0, 0); +} + AccessibilityUIElement AccessibilityUIElement::cellForColumnAndRow(unsigned column, unsigned row) { return 0; diff --git a/WebKitTools/DumpRenderTree/win/DRTDesktopNotificationPresenter.cpp b/WebKitTools/DumpRenderTree/win/DRTDesktopNotificationPresenter.cpp new file mode 100644 index 0000000..b18b724 --- /dev/null +++ b/WebKitTools/DumpRenderTree/win/DRTDesktopNotificationPresenter.cpp @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2009 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "DRTDesktopNotificationPresenter.h" + +#include "DumpRenderTree.h" +#include "LayoutTestController.h" +#include <JavaScriptCore/JSStringRef.h> +#include <JavaScriptCore/JSStringRefBSTR.h> +#include <WebCore/NotificationPresenter.h> + +DRTDesktopNotificationPresenter::DRTDesktopNotificationPresenter() + : m_refCount(1) {} + +HRESULT STDMETHODCALLTYPE DRTDesktopNotificationPresenter::QueryInterface(REFIID riid, void** ppvObject) +{ + *ppvObject = 0; + if (IsEqualGUID(riid, IID_IUnknown)) + *ppvObject = static_cast<DRTDesktopNotificationPresenter*>(this); + else if (IsEqualGUID(riid, IID_IWebDesktopNotificationsDelegate)) + *ppvObject = static_cast<DRTDesktopNotificationPresenter*>(this); + else + return E_NOINTERFACE; + + AddRef(); + return S_OK; +} + +ULONG STDMETHODCALLTYPE DRTDesktopNotificationPresenter::AddRef() +{ + return ++m_refCount; +} + +ULONG STDMETHODCALLTYPE DRTDesktopNotificationPresenter::Release() +{ + ULONG newRef = --m_refCount; + if (!newRef) + delete(this); + + return newRef; +} + +HRESULT STDMETHODCALLTYPE DRTDesktopNotificationPresenter::showDesktopNotification( + /* [in] */ IWebDesktopNotification* notification) +{ + BSTR title, text, url; + BOOL html; + + if (!notification->isHTML(&html) && html) { + notification->contentsURL(&url); + printf("DESKTOP NOTIFICATION: contents at %S\n", url ? url : L""); + } else { + notification->iconURL(&url); + notification->title(&title); + notification->text(&text); + printf("DESKTOP NOTIFICATION: icon %S, title %S, text %S\n", + url ? url : L"", + title ? title : L"", + text ? text : L""); + } + + // In this stub implementation, the notification is displayed immediately; + // we dispatch the display event to mimic that. + notification->notifyDisplay(); + + return S_OK; +} + +HRESULT STDMETHODCALLTYPE DRTDesktopNotificationPresenter::cancelDesktopNotification( + /* [in] */ IWebDesktopNotification* notification) +{ + BSTR identifier; + BOOL html; + notification->isHTML(&html); + if (html) + notification->contentsURL(&identifier); + else + notification->title(&identifier); + + printf("DESKTOP NOTIFICATION CLOSED: %S\n", identifier ? identifier : L""); + notification->notifyClose(false); + + return S_OK; +} + +HRESULT STDMETHODCALLTYPE DRTDesktopNotificationPresenter::notificationDestroyed( + /* [in] */ IWebDesktopNotification* notification) +{ + // Since in these tests events happen immediately, we don't hold on to + // Notification pointers. So there's no cleanup to do. + return S_OK; +} + +HRESULT STDMETHODCALLTYPE DRTDesktopNotificationPresenter::checkNotificationPermission( + /* [in] */ BSTR origin, + /* [out, retval] */ int* result) +{ +#if ENABLE(NOTIFICATIONS) + JSStringRef jsOrigin = JSStringCreateWithBSTR(origin); + bool allowed = ::gLayoutTestController->checkDesktopNotificationPermission(jsOrigin); + + if (allowed) + *result = WebCore::NotificationPresenter::PermissionAllowed; + else + *result = WebCore::NotificationPresenter::PermissionDenied; + + JSStringRelease(jsOrigin); +#endif + return S_OK; +} + +HRESULT STDMETHODCALLTYPE DRTDesktopNotificationPresenter::requestNotificationPermission( + /* [in] */ BSTR origin) +{ + printf("DESKTOP NOTIFICATION PERMISSION REQUESTED: %S\n", origin ? origin : L""); + return S_OK; +} diff --git a/WebKitTools/DumpRenderTree/win/DRTDesktopNotificationPresenter.h b/WebKitTools/DumpRenderTree/win/DRTDesktopNotificationPresenter.h new file mode 100644 index 0000000..5679845 --- /dev/null +++ b/WebKitTools/DumpRenderTree/win/DRTDesktopNotificationPresenter.h @@ -0,0 +1,66 @@ +/* + * 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 DRTDesktopNotificationPresenter_h +#define DRTDesktopNotificationPresenter_h + +#include <WebKit/WebKit.h> +#include <wtf/OwnPtr.h> +#include <windef.h> + +class DRTDesktopNotificationPresenter : public IWebDesktopNotificationsDelegate { +public: + DRTDesktopNotificationPresenter(); + + // IUnknown + virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject); + virtual ULONG STDMETHODCALLTYPE AddRef(void); + virtual ULONG STDMETHODCALLTYPE Release(void); + + // IWebDesktopNotificationsDelegate + virtual HRESULT STDMETHODCALLTYPE showDesktopNotification( + /* [in] */ IWebDesktopNotification* notification); + + virtual HRESULT STDMETHODCALLTYPE cancelDesktopNotification( + /* [in] */ IWebDesktopNotification* notification); + + virtual HRESULT STDMETHODCALLTYPE notificationDestroyed( + /* [in] */ IWebDesktopNotification* notification); + + virtual HRESULT STDMETHODCALLTYPE checkNotificationPermission( + /* [in] */ BSTR origin, + /* [out, retval] */ int* result); + + virtual HRESULT STDMETHODCALLTYPE requestNotificationPermission( + /* [in] */ BSTR origin); + +private: + ULONG m_refCount; +}; + +#endif diff --git a/WebKitTools/DumpRenderTree/win/DraggingInfo.h b/WebKitTools/DumpRenderTree/win/DraggingInfo.h index 2ead457..98982bc 100644 --- a/WebKitTools/DumpRenderTree/win/DraggingInfo.h +++ b/WebKitTools/DumpRenderTree/win/DraggingInfo.h @@ -36,6 +36,7 @@ public: DraggingInfo(IDataObject* object, IDropSource* source) : m_object(object) , m_source(source) + , m_performedDropEffect(DROPEFFECT_NONE) { m_object->AddRef(); m_source->AddRef(); @@ -54,9 +55,13 @@ public: IDataObject* dataObject() const { return m_object; } IDropSource* dropSource() const { return m_source; } + DWORD performedDropEffect() const { return m_performedDropEffect; } + void setPerformedDropEffect(DWORD effect) { m_performedDropEffect = effect; } + private: IDataObject* m_object; IDropSource* m_source; + DWORD m_performedDropEffect; }; #endif // !defined(DraggingInfo_h) diff --git a/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp b/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp index d262826..7e013a7 100644 --- a/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp +++ b/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp @@ -50,14 +50,19 @@ #include <wtf/RetainPtr.h> #include <wtf/Vector.h> #include <windows.h> -#if PLATFORM(CFNETWORK) -#include <CFNetwork/CFURLCachePriv.h> -#endif #include <CoreFoundation/CoreFoundation.h> #include <JavaScriptCore/JavaScriptCore.h> #include <WebKit/WebKit.h> #include <WebKit/WebKitCOMAPI.h> +#if USE(CFNETWORK) +#include <CFNetwork/CFURLCachePriv.h> +#endif + +#if USE(CFNETWORK) +#include <CFNetwork/CFHTTPCookiesPriv.h> +#endif + using namespace std; #ifndef NDEBUG @@ -108,6 +113,25 @@ void setPersistentUserStyleSheetLocation(CFStringRef url) persistentUserStyleSheetLocation = url; } +bool setAlwaysAcceptCookies(bool alwaysAcceptCookies) +{ +#if USE(CFNETWORK) + COMPtr<IWebCookieManager> cookieManager; + if (FAILED(WebKitCreateInstance(CLSID_WebCookieManager, 0, IID_IWebCookieManager, reinterpret_cast<void**>(&cookieManager)))) + return false; + CFHTTPCookieStorageRef cookieStorage = 0; + if (FAILED(cookieManager->cookieStorage(&cookieStorage)) || !cookieStorage) + return false; + + WebKitCookieStorageAcceptPolicy cookieAcceptPolicy = alwaysAcceptCookies ? WebKitCookieStorageAcceptPolicyAlways : WebKitCookieStorageAcceptPolicyOnlyFromMainDocumentDomain; + CFHTTPCookieStorageSetCookieAcceptPolicy(cookieStorage, cookieAcceptPolicy); + return true; +#else + // FIXME: Implement! + return false; +#endif +} + wstring urlSuitableForTestResult(const wstring& url) { if (!url.c_str() || url.find(L"file://") == wstring::npos) @@ -657,6 +681,72 @@ static bool shouldLogFrameLoadDelegates(const char* pathOrURL) return strstr(pathOrURL, "/loading/") || strstr(pathOrURL, "\\loading\\"); } +static void resetDefaultsToConsistentValues(IWebPreferences* preferences) +{ +#ifdef USE_MAC_FONTS + static BSTR standardFamily = SysAllocString(TEXT("Times")); + static BSTR fixedFamily = SysAllocString(TEXT("Courier")); + static BSTR sansSerifFamily = SysAllocString(TEXT("Helvetica")); + static BSTR cursiveFamily = SysAllocString(TEXT("Apple Chancery")); + static BSTR fantasyFamily = SysAllocString(TEXT("Papyrus")); +#else + static BSTR standardFamily = SysAllocString(TEXT("Times New Roman")); + static BSTR fixedFamily = SysAllocString(TEXT("Courier New")); + static BSTR sansSerifFamily = SysAllocString(TEXT("Arial")); + static BSTR cursiveFamily = SysAllocString(TEXT("Comic Sans MS")); // Not actually cursive, but it's what IE and Firefox use. + static 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->setDefaultFontSize(16); + preferences->setDefaultFixedFontSize(13); + preferences->setMinimumFontSize(1); + preferences->setJavaEnabled(FALSE); + preferences->setPlugInsEnabled(TRUE); + preferences->setDOMPasteAllowed(TRUE); + preferences->setEditableLinkBehavior(WebKitEditableLinkOnlyLiveWithShiftKey); + preferences->setFontSmoothing(FontSmoothingTypeStandard); + preferences->setUsesPageCache(FALSE); + preferences->setPrivateBrowsingEnabled(FALSE); + preferences->setJavaScriptCanOpenWindowsAutomatically(TRUE); + preferences->setJavaScriptEnabled(TRUE); + preferences->setTabsToLinks(FALSE); + preferences->setShouldPrintBackgrounds(TRUE); + preferences->setLoadsImagesAutomatically(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->setAllowUniversalAccessFromFileURLs(TRUE); + prefsPrivate->setAuthorAndUserStylesEnabled(TRUE); + prefsPrivate->setDeveloperExtrasEnabled(FALSE); + prefsPrivate->setExperimentalNotificationsEnabled(TRUE); + prefsPrivate->setExperimentalWebSocketsEnabled(FALSE); + prefsPrivate->setShouldPaintNativeControls(FALSE); // FIXME - need to make DRT pass with Windows native controls <http://bugs.webkit.org/show_bug.cgi?id=25592> + prefsPrivate->setXSSAuditorEnabled(FALSE); + prefsPrivate->setOfflineWebApplicationCacheEnabled(TRUE); + } + setAlwaysAcceptCookies(false); + + setlocale(LC_ALL, ""); +} + static void resetWebViewToConsistentStateBeforeTesting() { COMPtr<IWebView> webView; @@ -673,30 +763,10 @@ static void resetWebViewToConsistentStateBeforeTesting() webIBActions->resetPageZoom(0); } + COMPtr<IWebPreferences> preferences; - if (SUCCEEDED(webView->preferences(&preferences))) { - preferences->setPrivateBrowsingEnabled(FALSE); - preferences->setJavaScriptCanOpenWindowsAutomatically(TRUE); - preferences->setLoadsImagesAutomatically(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); - prefsPrivate->setDeveloperExtrasEnabled(FALSE); - prefsPrivate->setShouldPaintNativeControls(FALSE); // FIXME - need to make DRT pass with Windows native controls <http://bugs.webkit.org/show_bug.cgi?id=25592> - prefsPrivate->setXSSAuditorEnabled(FALSE); - } - } + if (SUCCEEDED(webView->preferences(&preferences))) + resetDefaultsToConsistentValues(preferences.get()); COMPtr<IWebViewEditing> viewEditing; if (SUCCEEDED(webView->QueryInterface(&viewEditing))) @@ -715,8 +785,11 @@ static void resetWebViewToConsistentStateBeforeTesting() SetFocus(viewWindow); webViewPrivate->clearMainFrameName(); + webViewPrivate->resetOriginAccessWhiteLists(); sharedUIDelegate->resetUndoManager(); + + sharedFrameLoadDelegate->resetToConsistentState(); } static void runTest(const string& testPathOrURL) @@ -830,44 +903,6 @@ exit: 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); @@ -1052,18 +1087,12 @@ IWebView* createWebViewAndOffscreenWindow(HWND* webViewWindow) 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; } -#if PLATFORM(CFNETWORK) +#if USE(CFNETWORK) RetainPtr<CFURLCacheRef> sharedCFURLCache() { HMODULE module = GetModuleHandle(TEXT("CFNetwork_debug.dll")); @@ -1138,7 +1167,7 @@ int main(int argc, char* argv[]) standardPreferencesPrivate->setShouldPaintNativeControls(FALSE); standardPreferences->setJavaScriptEnabled(TRUE); standardPreferences->setDefaultFontSize(16); - + COMPtr<IWebView> webView(AdoptCOM, createWebViewAndOffscreenWindow(&webViewWindow)); if (!webView) return -1; @@ -1153,7 +1182,7 @@ int main(int argc, char* argv[]) if (FAILED(webView->mainFrame(&frame))) return -1; -#if PLATFORM(CFNETWORK) +#if USE(CFNETWORK) RetainPtr<CFURLCacheRef> urlCache = sharedCFURLCache(); CFURLCacheRemoveAllCachedResponses(urlCache.get()); #endif diff --git a/WebKitTools/DumpRenderTree/win/DumpRenderTree.vcproj b/WebKitTools/DumpRenderTree/win/DumpRenderTree.vcproj index b1bd3ab..dea2467 100644 --- a/WebKitTools/DumpRenderTree/win/DumpRenderTree.vcproj +++ b/WebKitTools/DumpRenderTree/win/DumpRenderTree.vcproj @@ -23,7 +23,7 @@ >
<Tool
Name="VCPreBuildEventTool"
- CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%
if exist "$(WebKitOutputDir)\buildfailed" grep XX$(ProjectName)XX "$(WebKitOutputDir)\buildfailed"
if errorlevel 1 exit 1
echo XX$(ProjectName)XX > "$(WebKitOutputDir)\buildfailed"

mkdir 2>NUL "$(WebKitOutputDir)\include\DumpRenderTree"
mkdir 2>NUL "$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders"
mkdir 2>NUL "$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf"

xcopy /y /d "$(ProjectDir)\..\ForwardingHeaders\wtf\*.h" "$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf"
"
+ CommandLine="%SystemDrive%\cygwin\bin\which.exe bash
if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%
cmd /c
if exist "$(WebKitOutputDir)\buildfailed" grep XX$(ProjectName)XX "$(WebKitOutputDir)\buildfailed"
if errorlevel 1 exit 1
echo XX$(ProjectName)XX > "$(WebKitOutputDir)\buildfailed"

mkdir 2>NUL "$(WebKitOutputDir)\include\DumpRenderTree"
mkdir 2>NUL "$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders"
mkdir 2>NUL "$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf"

xcopy /y /d "$(ProjectDir)\..\ForwardingHeaders\wtf\*.h" "$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf"
"
/>
<Tool
Name="VCCustomBuildTool"
@@ -55,7 +55,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="JavaScriptCore$(WebKitDLLConfigSuffix).lib WebKitGUID$(WebKitConfigSuffix).lib WebKit$(WebKitDLLConfigSuffix).lib CoreGraphics$(LibraryConfigSuffix).lib CoreFoundation$(LibraryConfigSuffix).lib CFNetwork$(LibraryConfigSuffix).lib pthreadVC2$(LibraryConfigSuffix).lib gdi32.lib ole32.lib oleaut32.lib user32.lib shlwapi.lib oleacc.lib"
+ AdditionalDependencies="JavaScriptCore$(WebKitDLLConfigSuffix).lib WebKitGUID$(WebKitConfigSuffix).lib WebKit$(WebKitDLLConfigSuffix).lib CoreGraphics$(LibraryConfigSuffix).lib CoreFoundation$(LibraryConfigSuffix).lib CFNetwork$(LibraryConfigSuffix).lib pthreadVC2$(LibraryConfigSuffix).lib gdi32.lib ole32.lib oleaut32.lib user32.lib shlwapi.lib oleacc.lib comsuppw.lib"
AdditionalLibraryDirectories=""
DelayLoadDLLs=""
SubSystem="1"
@@ -96,7 +96,7 @@ >
<Tool
Name="VCPreBuildEventTool"
- CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%
if exist "$(WebKitOutputDir)\buildfailed" grep XX$(ProjectName)XX "$(WebKitOutputDir)\buildfailed"
if errorlevel 1 exit 1
echo XX$(ProjectName)XX > "$(WebKitOutputDir)\buildfailed"

mkdir 2>NUL "$(WebKitOutputDir)\include\DumpRenderTree"
mkdir 2>NUL "$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders"
mkdir 2>NUL "$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf"

xcopy /y /d "$(ProjectDir)\..\ForwardingHeaders\wtf\*.h" "$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf"
"
+ CommandLine="%SystemDrive%\cygwin\bin\which.exe bash
if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%
cmd /c
if exist "$(WebKitOutputDir)\buildfailed" grep XX$(ProjectName)XX "$(WebKitOutputDir)\buildfailed"
if errorlevel 1 exit 1
echo XX$(ProjectName)XX > "$(WebKitOutputDir)\buildfailed"

mkdir 2>NUL "$(WebKitOutputDir)\include\DumpRenderTree"
mkdir 2>NUL "$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders"
mkdir 2>NUL "$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf"

xcopy /y /d "$(ProjectDir)\..\ForwardingHeaders\wtf\*.h" "$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf"
"
/>
<Tool
Name="VCCustomBuildTool"
@@ -128,7 +128,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="JavaScriptCore$(WebKitDLLConfigSuffix).lib WebKitGUID$(WebKitConfigSuffix).lib WebKit$(WebKitDLLConfigSuffix).lib CoreGraphics$(LibraryConfigSuffix).lib CoreFoundation$(LibraryConfigSuffix).lib CFNetwork$(LibraryConfigSuffix).lib pthreadVC2$(LibraryConfigSuffix).lib gdi32.lib ole32.lib oleaut32.lib user32.lib shlwapi.lib oleacc.lib"
+ AdditionalDependencies="JavaScriptCore$(WebKitDLLConfigSuffix).lib WebKitGUID$(WebKitConfigSuffix).lib WebKit$(WebKitDLLConfigSuffix).lib CoreGraphics$(LibraryConfigSuffix).lib CoreFoundation$(LibraryConfigSuffix).lib CFNetwork$(LibraryConfigSuffix).lib pthreadVC2$(LibraryConfigSuffix).lib gdi32.lib ole32.lib oleaut32.lib user32.lib shlwapi.lib oleacc.lib comsuppw.lib"
AdditionalLibraryDirectories=""
DelayLoadDLLs=""
SubSystem="1"
@@ -168,7 +168,7 @@ >
<Tool
Name="VCPreBuildEventTool"
- CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%
if exist "$(WebKitOutputDir)\buildfailed" grep XX$(ProjectName)XX "$(WebKitOutputDir)\buildfailed"
if errorlevel 1 exit 1
echo XX$(ProjectName)XX > "$(WebKitOutputDir)\buildfailed"

mkdir 2>NUL "$(WebKitOutputDir)\include\DumpRenderTree"
mkdir 2>NUL "$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders"
mkdir 2>NUL "$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf"

xcopy /y /d "$(ProjectDir)\..\ForwardingHeaders\wtf\*.h" "$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf"
"
+ CommandLine="%SystemDrive%\cygwin\bin\which.exe bash
if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%
cmd /c
if exist "$(WebKitOutputDir)\buildfailed" grep XX$(ProjectName)XX "$(WebKitOutputDir)\buildfailed"
if errorlevel 1 exit 1
echo XX$(ProjectName)XX > "$(WebKitOutputDir)\buildfailed"

mkdir 2>NUL "$(WebKitOutputDir)\include\DumpRenderTree"
mkdir 2>NUL "$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders"
mkdir 2>NUL "$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf"

xcopy /y /d "$(ProjectDir)\..\ForwardingHeaders\wtf\*.h" "$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf"
"
/>
<Tool
Name="VCCustomBuildTool"
@@ -200,7 +200,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="JavaScriptCore$(WebKitDLLConfigSuffix).lib WebKitGUID$(WebKitConfigSuffix).lib WebKit$(WebKitDLLConfigSuffix).lib CoreGraphics$(LibraryConfigSuffix).lib CoreFoundation$(LibraryConfigSuffix).lib CFNetwork$(LibraryConfigSuffix).lib pthreadVC2$(LibraryConfigSuffix).lib gdi32.lib ole32.lib oleaut32.lib user32.lib shlwapi.lib oleacc.lib"
+ AdditionalDependencies="JavaScriptCore$(WebKitDLLConfigSuffix).lib WebKitGUID$(WebKitConfigSuffix).lib WebKit$(WebKitDLLConfigSuffix).lib CoreGraphics$(LibraryConfigSuffix).lib CoreFoundation$(LibraryConfigSuffix).lib CFNetwork$(LibraryConfigSuffix).lib pthreadVC2$(LibraryConfigSuffix).lib gdi32.lib ole32.lib oleaut32.lib user32.lib shlwapi.lib oleacc.lib comsuppw.lib"
AdditionalLibraryDirectories=""
DelayLoadDLLs=""
SubSystem="1"
@@ -234,12 +234,12 @@ <Configuration
Name="Debug_Cairo|Win32"
ConfigurationType="1"
- InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;$(WebKitLibrariesDir)\tools\vsprops\WinCairo.vsprops"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_wincairo.vsprops;$(WebKitLibrariesDir)\tools\vsprops\WinCairo.vsprops"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
- CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%
if exist "$(WebKitOutputDir)\buildfailed" grep XX$(ProjectName)XX "$(WebKitOutputDir)\buildfailed"
if errorlevel 1 exit 1
echo XX$(ProjectName)XX > "$(WebKitOutputDir)\buildfailed"

mkdir 2>NUL "$(WebKitOutputDir)\include\DumpRenderTree"
mkdir 2>NUL "$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders"
mkdir 2>NUL "$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf"

xcopy /y /d "$(ProjectDir)\..\ForwardingHeaders\wtf\*.h" "$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf"
"
+ CommandLine="%SystemDrive%\cygwin\bin\which.exe bash
if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%
cmd /c
if exist "$(WebKitOutputDir)\buildfailed" grep XX$(ProjectName)XX "$(WebKitOutputDir)\buildfailed"
if errorlevel 1 exit 1
echo XX$(ProjectName)XX > "$(WebKitOutputDir)\buildfailed"

mkdir 2>NUL "$(WebKitOutputDir)\include\DumpRenderTree"
mkdir 2>NUL "$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders"
mkdir 2>NUL "$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf"

xcopy /y /d "$(ProjectDir)\..\ForwardingHeaders\wtf\*.h" "$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf"
"
/>
<Tool
Name="VCCustomBuildTool"
@@ -271,7 +271,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="JavaScriptCore$(WebKitDLLConfigSuffix).lib WebKitGUID$(WebKitConfigSuffix).lib WebKit$(WebKitDLLConfigSuffix).lib CFLite_Debug.lib cairo.lib jpeg.lib libpng.lib libcurl_imp.lib pthreadVC2$(LibraryConfigSuffix).lib gdi32.lib ole32.lib oleaut32.lib user32.lib shlwapi.lib oleacc.lib"
+ AdditionalDependencies="JavaScriptCore$(WebKitDLLConfigSuffix).lib WebKitGUID$(WebKitConfigSuffix).lib WebKit$(WebKitDLLConfigSuffix).lib CFLite_Debug.lib cairo.lib libjpeg.lib libpng.lib libcurl_imp.lib pthreadVC2$(LibraryConfigSuffix).lib gdi32.lib ole32.lib oleaut32.lib user32.lib shlwapi.lib oleacc.lib comsuppw.lib"
AdditionalLibraryDirectories=""
DelayLoadDLLs=""
SubSystem="1"
@@ -312,7 +312,7 @@ >
<Tool
Name="VCPreBuildEventTool"
- CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%
if exist "$(WebKitOutputDir)\buildfailed" grep XX$(ProjectName)XX "$(WebKitOutputDir)\buildfailed"
if errorlevel 1 exit 1
echo XX$(ProjectName)XX > "$(WebKitOutputDir)\buildfailed"

mkdir 2>NUL "$(WebKitOutputDir)\include\DumpRenderTree"
mkdir 2>NUL "$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders"
mkdir 2>NUL "$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf"

xcopy /y /d "$(ProjectDir)\..\ForwardingHeaders\wtf\*.h" "$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf"
"
+ CommandLine="%SystemDrive%\cygwin\bin\which.exe bash
if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%
cmd /c
if exist "$(WebKitOutputDir)\buildfailed" grep XX$(ProjectName)XX "$(WebKitOutputDir)\buildfailed"
if errorlevel 1 exit 1
echo XX$(ProjectName)XX > "$(WebKitOutputDir)\buildfailed"

mkdir 2>NUL "$(WebKitOutputDir)\include\DumpRenderTree"
mkdir 2>NUL "$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders"
mkdir 2>NUL "$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf"

xcopy /y /d "$(ProjectDir)\..\ForwardingHeaders\wtf\*.h" "$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf"
"
/>
<Tool
Name="VCCustomBuildTool"
@@ -344,7 +344,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="JavaScriptCore$(WebKitDLLConfigSuffix).lib WebKitGUID$(WebKitConfigSuffix).lib WebKit$(WebKitDLLConfigSuffix).lib CFLite.lib cairo.lib jpeg.lib libpng.lib libcurl_imp.lib pthreadVC2$(LibraryConfigSuffix).lib gdi32.lib ole32.lib oleaut32.lib user32.lib shlwapi.lib oleacc.lib"
+ AdditionalDependencies="JavaScriptCore$(WebKitDLLConfigSuffix).lib WebKitGUID$(WebKitConfigSuffix).lib WebKit$(WebKitDLLConfigSuffix).lib CFLite.lib cairo.lib libjpeg.lib libpng.lib libcurl_imp.lib pthreadVC2$(LibraryConfigSuffix).lib gdi32.lib ole32.lib oleaut32.lib user32.lib shlwapi.lib oleacc.lib comsuppw.lib"
AdditionalLibraryDirectories=""
DelayLoadDLLs=""
SubSystem="1"
@@ -432,6 +432,14 @@ Name="Delegates"
>
<File
+ RelativePath=".\DRTDesktopNotificationPresenter.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\DRTDesktopNotificationPresenter.h"
+ >
+ </File>
+ <File
RelativePath=".\EditingDelegate.cpp"
>
</File>
diff --git a/WebKitTools/DumpRenderTree/win/DumpRenderTreeWin.h b/WebKitTools/DumpRenderTree/win/DumpRenderTreeWin.h index bf9b123..6eb468d 100644 --- a/WebKitTools/DumpRenderTree/win/DumpRenderTreeWin.h +++ b/WebKitTools/DumpRenderTree/win/DumpRenderTreeWin.h @@ -53,6 +53,7 @@ typedef HashMap<HWND, COMPtr<IWebView> > WindowToWebViewMap; WindowToWebViewMap& windowToWebViewMap(); void setPersistentUserStyleSheetLocation(CFStringRef); +bool setAlwaysAcceptCookies(bool alwaysAcceptCookies); extern UINT_PTR waitToDumpWatchdog; diff --git a/WebKitTools/DumpRenderTree/win/EventSender.cpp b/WebKitTools/DumpRenderTree/win/EventSender.cpp index ca897fb..721b238 100644 --- a/WebKitTools/DumpRenderTree/win/EventSender.cpp +++ b/WebKitTools/DumpRenderTree/win/EventSender.cpp @@ -151,7 +151,30 @@ static JSValueRef mouseDownCallback(JSContextRef context, JSObjectRef function, framePrivate->layout(); down = true; - MSG msg = makeMsg(webViewWindow, WM_LBUTTONDOWN, 0, MAKELPARAM(lastMousePosition.x, lastMousePosition.y)); + int mouseType = WM_LBUTTONDOWN; + if (argumentCount == 1) { + int mouseNumber = JSValueToNumber(context, arguments[0], exception); + switch (mouseNumber) { + case 0: + mouseType = WM_LBUTTONDOWN; + break; + case 1: + mouseType = WM_MBUTTONDOWN; + break; + case 2: + mouseType = WM_RBUTTONDOWN; + break; + case 3: + // fast/events/mouse-click-events expects the 4th button has event.button = 1, so send an WM_BUTTONDOWN + mouseType = WM_MBUTTONDOWN; + break; + default: + mouseType = WM_LBUTTONDOWN; + break; + } + } + + MSG msg = makeMsg(webViewWindow, mouseType, 0, MAKELPARAM(lastMousePosition.x, lastMousePosition.y)); if (!msgQueue[endOfQueue].delay) dispatchMessage(&msg); else { @@ -196,18 +219,42 @@ static void doMouseUp(MSG msg) if (hr == DRAGDROP_S_DROP && effect != DROPEFFECT_NONE) { DWORD effect = 0; webViewDropTarget->Drop(draggingInfo->dataObject(), 0, pointl(screenPoint), &effect); + draggingInfo->setPerformedDropEffect(effect); } else webViewDropTarget->DragLeave(); - delete draggingInfo; - draggingInfo = 0; + // Reset didDragEnter so that another drag started within the same frame works properly. + didDragEnter = false; } } } 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)); + int mouseType = WM_LBUTTONUP; + if (argumentCount == 1) { + int mouseNumber = JSValueToNumber(context, arguments[0], exception); + switch (mouseNumber) { + case 0: + mouseType = WM_LBUTTONUP; + break; + case 1: + mouseType = WM_MBUTTONUP; + break; + case 2: + mouseType = WM_RBUTTONUP; + break; + case 3: + // fast/events/mouse-click-events expects the 4th button has event.button = 1, so send an WM_MBUTTONUP + mouseType = WM_MBUTTONUP; + break; + default: + mouseType = WM_LBUTTONUP; + break; + } + } + + MSG msg = makeMsg(webViewWindow, mouseType, 0, MAKELPARAM(lastMousePosition.x, lastMousePosition.y)); if ((dragMode && !replayingSavedEvents) || msgQueue[endOfQueue].delay) { msgQueue[endOfQueue++].msg = msg; @@ -277,12 +324,16 @@ void replaySavedEvents() msg = msgQueue[startOfQueue++].msg; switch (msg.message) { case WM_LBUTTONUP: + case WM_RBUTTONUP: + case WM_MBUTTONUP: doMouseUp(msg); break; case WM_MOUSEMOVE: doMouseMove(msg); break; case WM_LBUTTONDOWN: + case WM_RBUTTONDOWN: + case WM_MBUTTONDOWN: dispatchMessage(&msg); break; default: @@ -317,12 +368,16 @@ void replaySavedEvents() msg = msgQueue[startOfQueue++].msg; switch (msg.message) { case WM_LBUTTONUP: + case WM_RBUTTONUP: + case WM_MBUTTONUP: doMouseUp(msg); break; case WM_MOUSEMOVE: doMouseMove(msg); break; case WM_LBUTTONDOWN: + case WM_RBUTTONDOWN: + case WM_MBUTTONDOWN: dispatchMessage(&msg); break; default: diff --git a/WebKitTools/DumpRenderTree/win/FrameLoadDelegate.cpp b/WebKitTools/DumpRenderTree/win/FrameLoadDelegate.cpp index 5f0e02b..939090a 100644 --- a/WebKitTools/DumpRenderTree/win/FrameLoadDelegate.cpp +++ b/WebKitTools/DumpRenderTree/win/FrameLoadDelegate.cpp @@ -76,8 +76,7 @@ string descriptionSuitableForTestResult(IWebFrame* webFrame) string frameName = (webFrame == mainFrame) ? "main frame" : "frame"; frameName += " \"" + BSTRtoString(frameNameBSTR) + "\""; - SysFreeString(frameNameBSTR); - + SysFreeString(frameNameBSTR); return frameName; } @@ -101,6 +100,8 @@ HRESULT STDMETHODCALLTYPE FrameLoadDelegate::QueryInterface(REFIID riid, void** *ppvObject = static_cast<IWebFrameLoadDelegate*>(this); else if (IsEqualGUID(riid, IID_IWebFrameLoadDelegatePrivate)) *ppvObject = static_cast<IWebFrameLoadDelegatePrivate*>(this); + else if (IsEqualGUID(riid, IID_IWebFrameLoadDelegatePrivate2)) + *ppvObject = static_cast<IWebFrameLoadDelegatePrivate2*>(this); else return E_NOINTERFACE; @@ -180,6 +181,9 @@ HRESULT STDMETHODCALLTYPE FrameLoadDelegate::didReceiveTitle( /* [in] */ BSTR title, /* [in] */ IWebFrame *frame) { + if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) + printf("%s - didReceiveTitle: %S\n", descriptionSuitableForTestResult(frame).c_str(), title); + if (::gLayoutTestController->dumpTitleChanges() && !done) printf("TITLE CHANGED: %S\n", title ? title : L""); return S_OK; @@ -196,6 +200,11 @@ void FrameLoadDelegate::processWork() dump(); } +void FrameLoadDelegate::resetToConsistentState() +{ + m_accessibilityController->resetToConsistentState(); +} + static void CALLBACK processWorkTimer(HWND, UINT, UINT_PTR id, DWORD) { ::KillTimer(0, id); @@ -346,3 +355,23 @@ HRESULT STDMETHODCALLTYPE FrameLoadDelegate::didFirstVisuallyNonEmptyLayoutInFra { return S_OK; } + +HRESULT STDMETHODCALLTYPE FrameLoadDelegate::didDisplayInsecureContent( + /* [in] */ IWebView *sender) +{ + if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) + printf("didDisplayInsecureContent\n"); + + return S_OK; +} + +HRESULT STDMETHODCALLTYPE FrameLoadDelegate::didRunInsecureContent( + /* [in] */ IWebView *sender, + /* [in] */ IWebSecurityOrigin *origin) +{ + if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) + printf("didRunInsecureContent\n"); + + return S_OK; +} + diff --git a/WebKitTools/DumpRenderTree/win/FrameLoadDelegate.h b/WebKitTools/DumpRenderTree/win/FrameLoadDelegate.h index 526e1b4..56325e2 100644 --- a/WebKitTools/DumpRenderTree/win/FrameLoadDelegate.h +++ b/WebKitTools/DumpRenderTree/win/FrameLoadDelegate.h @@ -35,13 +35,15 @@ class AccessibilityController; class GCController; -class FrameLoadDelegate : public IWebFrameLoadDelegate, public IWebFrameLoadDelegatePrivate { +class FrameLoadDelegate : public IWebFrameLoadDelegate, public IWebFrameLoadDelegatePrivate2 { public: FrameLoadDelegate(); virtual ~FrameLoadDelegate(); void processWork(); + void resetToConsistentState(); + // IUnknown virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject); virtual ULONG STDMETHODCALLTYPE AddRef(void); @@ -131,6 +133,14 @@ public: /* [in] */ IWebView *sender, /* [in] */ IWebFrame *frame); + // IWebFrameLoadDelegatePrivate2 + virtual HRESULT STDMETHODCALLTYPE didDisplayInsecureContent( + /* [in] */ IWebView *sender); + + virtual HRESULT STDMETHODCALLTYPE didRunInsecureContent( + /* [in] */ IWebView *sender, + /* [in] */ IWebSecurityOrigin *origin); + protected: void locationChangeDone(IWebError*, IWebFrame*); diff --git a/WebKitTools/DumpRenderTree/win/ImageDiff.vcproj b/WebKitTools/DumpRenderTree/win/ImageDiff.vcproj index 8d79717..37bddeb 100644 --- a/WebKitTools/DumpRenderTree/win/ImageDiff.vcproj +++ b/WebKitTools/DumpRenderTree/win/ImageDiff.vcproj @@ -1,230 +1,230 @@ -<?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" - CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%
if exist "$(WebKitOutputDir)\buildfailed" grep XX$(ProjectName)XX "$(WebKitOutputDir)\buildfailed"
if errorlevel 1 exit 1
echo XX$(ProjectName)XX > "$(WebKitOutputDir)\buildfailed"
" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - /> - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories=""$(WebKitOutputDir)\include";"$(WebKitOutputDir)\include\private";"$(WebKitOutputDir)\include\WebCore\ForwardingHeaders";"$(WebKitLibrariesDir)\include";"$(WebKitLibrariesDir)\include\private";"$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders";"$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility"" - /> - <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" - CommandLine="if exist "$(WebKitOutputDir)\buildfailed" del "$(WebKitOutputDir)\buildfailed"

mkdir 2>NUL "$(WebKitOutputDir)\bin"

if not defined ARCHIVE_BUILD (if defined PRODUCTION exit /b)

if not exist "$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll" exit /b

xcopy /y /d "$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).pdb" "$(WebKitOutputDir)\bin"
xcopy /y /d /e /i "$(WebKitLibrariesDir)\bin\CoreFoundation.resources" "$(WebKitOutputDir)\bin\CoreFoundation.resources"
xcopy /y /d /e /i "$(WebKitLibrariesDir)\bin\CharacterSets" "$(WebKitOutputDir)\bin\CharacterSets"
xcopy /y /d "$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).dll" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).pdb" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\icudt38.dll" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\icudt38$(LibraryConfigSuffix).dll" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\icuin38$(LibraryConfigSuffix).dll" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\icuin38$(LibraryConfigSuffix).pdb" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\icuuc38$(LibraryConfigSuffix).dll" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\icuuc38$(LibraryConfigSuffix).pdb" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).dll" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).pdb" "$(WebKitOutputDir)\bin"
" - /> - </Configuration> - <Configuration - Name="Release|Win32" - ConfigurationType="1" - InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\release.vsprops" - CharacterSet="2" - WholeProgramOptimization="1" - > - <Tool - Name="VCPreBuildEventTool" - CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%
if exist "$(WebKitOutputDir)\buildfailed" grep XX$(ProjectName)XX "$(WebKitOutputDir)\buildfailed"
if errorlevel 1 exit 1
echo XX$(ProjectName)XX > "$(WebKitOutputDir)\buildfailed"
" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - /> - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories=""$(WebKitOutputDir)\include";"$(WebKitOutputDir)\include\private";"$(WebKitOutputDir)\include\WebCore\ForwardingHeaders";"$(WebKitLibrariesDir)\include";"$(WebKitLibrariesDir)\include\private";"$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders";"$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility"" - /> - <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" - CommandLine="if exist "$(WebKitOutputDir)\buildfailed" del "$(WebKitOutputDir)\buildfailed"

mkdir 2>NUL "$(WebKitOutputDir)\bin"

if not defined ARCHIVE_BUILD (if defined PRODUCTION exit /b)

if not exist "$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll" exit /b

xcopy /y /d "$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).pdb" "$(WebKitOutputDir)\bin"
xcopy /y /d /e /i "$(WebKitLibrariesDir)\bin\CoreFoundation.resources" "$(WebKitOutputDir)\bin\CoreFoundation.resources"
xcopy /y /d /e /i "$(WebKitLibrariesDir)\bin\CharacterSets" "$(WebKitOutputDir)\bin\CharacterSets"
xcopy /y /d "$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).dll" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).pdb" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\icudt38.dll" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\icudt38$(LibraryConfigSuffix).dll" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\icuin38$(LibraryConfigSuffix).dll" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\icuin38$(LibraryConfigSuffix).pdb" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\icuuc38$(LibraryConfigSuffix).dll" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\icuuc38$(LibraryConfigSuffix).pdb" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).dll" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).pdb" "$(WebKitOutputDir)\bin"
" - /> - </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="2" - > - <Tool - Name="VCPreBuildEventTool" - CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%
if exist "$(WebKitOutputDir)\buildfailed" grep XX$(ProjectName)XX "$(WebKitOutputDir)\buildfailed"
if errorlevel 1 exit 1
echo XX$(ProjectName)XX > "$(WebKitOutputDir)\buildfailed"
" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - /> - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories=""$(WebKitOutputDir)\include";"$(WebKitOutputDir)\include\private";"$(WebKitOutputDir)\include\WebCore\ForwardingHeaders";"$(WebKitLibrariesDir)\include";"$(WebKitLibrariesDir)\include\private";"$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders";"$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility"" - /> - <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" - CommandLine="if exist "$(WebKitOutputDir)\buildfailed" del "$(WebKitOutputDir)\buildfailed"

mkdir 2>NUL "$(WebKitOutputDir)\bin"

if not defined ARCHIVE_BUILD (if defined PRODUCTION exit /b)

if not exist "$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll" exit /b

xcopy /y /d "$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).pdb" "$(WebKitOutputDir)\bin"
xcopy /y /d /e /i "$(WebKitLibrariesDir)\bin\CoreFoundation.resources" "$(WebKitOutputDir)\bin\CoreFoundation.resources"
xcopy /y /d /e /i "$(WebKitLibrariesDir)\bin\CharacterSets" "$(WebKitOutputDir)\bin\CharacterSets"
xcopy /y /d "$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).dll" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).pdb" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\icudt38.dll" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\icudt38$(LibraryConfigSuffix).dll" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\icuin38$(LibraryConfigSuffix).dll" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\icuin38$(LibraryConfigSuffix).pdb" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\icuuc38$(LibraryConfigSuffix).dll" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\icuuc38$(LibraryConfigSuffix).pdb" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).dll" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).pdb" "$(WebKitOutputDir)\bin"
" - /> - </Configuration> - </Configurations> - <References> - </References> - <Files> - <File - RelativePath="..\cg\ImageDiffCG.cpp" - > - </File> - </Files> - <Globals> - </Globals> -</VisualStudioProject> +<?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"
+ CommandLine="%SystemDrive%\cygwin\bin\which.exe bash
if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%
cmd /c
if exist "$(WebKitOutputDir)\buildfailed" grep XX$(ProjectName)XX "$(WebKitOutputDir)\buildfailed"
if errorlevel 1 exit 1
echo XX$(ProjectName)XX > "$(WebKitOutputDir)\buildfailed"
"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""$(WebKitOutputDir)\include";"$(WebKitOutputDir)\include\private";"$(WebKitOutputDir)\include\WebCore\ForwardingHeaders";"$(WebKitLibrariesDir)\include";"$(WebKitLibrariesDir)\include\private";"$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders";"$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility""
+ />
+ <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"
+ CommandLine="if exist "$(WebKitOutputDir)\buildfailed" del "$(WebKitOutputDir)\buildfailed"

mkdir 2>NUL "$(WebKitOutputDir)\bin"

if not defined ARCHIVE_BUILD (if defined PRODUCTION exit /b)

if not exist "$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll" exit /b

xcopy /y /d "$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).pdb" "$(WebKitOutputDir)\bin"
xcopy /y /d /e /i "$(WebKitLibrariesDir)\bin\CoreFoundation.resources" "$(WebKitOutputDir)\bin\CoreFoundation.resources"
xcopy /y /d "$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).dll" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).pdb" "$(WebKitOutputDir)\bin"
"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\release.vsprops"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine="%SystemDrive%\cygwin\bin\which.exe bash
if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%
cmd /c
if exist "$(WebKitOutputDir)\buildfailed" grep XX$(ProjectName)XX "$(WebKitOutputDir)\buildfailed"
if errorlevel 1 exit 1
echo XX$(ProjectName)XX > "$(WebKitOutputDir)\buildfailed"
"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""$(WebKitOutputDir)\include";"$(WebKitOutputDir)\include\private";"$(WebKitOutputDir)\include\WebCore\ForwardingHeaders";"$(WebKitLibrariesDir)\include";"$(WebKitLibrariesDir)\include\private";"$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders";"$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility""
+ />
+ <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"
+ CommandLine="if exist "$(WebKitOutputDir)\buildfailed" del "$(WebKitOutputDir)\buildfailed"

mkdir 2>NUL "$(WebKitOutputDir)\bin"

if not defined ARCHIVE_BUILD (if defined PRODUCTION exit /b)

if not exist "$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll" exit /b

xcopy /y /d "$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).pdb" "$(WebKitOutputDir)\bin"
xcopy /y /d /e /i "$(WebKitLibrariesDir)\bin\CoreFoundation.resources" "$(WebKitOutputDir)\bin\CoreFoundation.resources"
xcopy /y /d "$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).dll" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).pdb" "$(WebKitOutputDir)\bin"
"
+ />
+ </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="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine="%SystemDrive%\cygwin\bin\which.exe bash
if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%
cmd /c
if exist "$(WebKitOutputDir)\buildfailed" grep XX$(ProjectName)XX "$(WebKitOutputDir)\buildfailed"
if errorlevel 1 exit 1
echo XX$(ProjectName)XX > "$(WebKitOutputDir)\buildfailed"
"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""$(WebKitOutputDir)\include";"$(WebKitOutputDir)\include\private";"$(WebKitOutputDir)\include\WebCore\ForwardingHeaders";"$(WebKitLibrariesDir)\include";"$(WebKitLibrariesDir)\include\private";"$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders";"$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility""
+ />
+ <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"
+ CommandLine="if exist "$(WebKitOutputDir)\buildfailed" del "$(WebKitOutputDir)\buildfailed"

mkdir 2>NUL "$(WebKitOutputDir)\bin"

if not defined ARCHIVE_BUILD (if defined PRODUCTION exit /b)

if not exist "$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll" exit /b

xcopy /y /d "$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).pdb" "$(WebKitOutputDir)\bin"
xcopy /y /d /e /i "$(WebKitLibrariesDir)\bin\CoreFoundation.resources" "$(WebKitOutputDir)\bin\CoreFoundation.resources"
xcopy /y /d "$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).dll" "$(WebKitOutputDir)\bin"
xcopy /y /d "$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).pdb" "$(WebKitOutputDir)\bin"
"
+ />
+ </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 index 7a80bab..cf3ac85 100644 --- a/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp +++ b/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp @@ -34,21 +34,22 @@ #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 <CoreFoundation/CoreFoundation.h> #include <JavaScriptCore/Assertions.h> -#include <JavaScriptCore/JavaScriptCore.h> #include <JavaScriptCore/JSRetainPtr.h> #include <JavaScriptCore/JSStringRefBSTR.h> +#include <JavaScriptCore/JavaScriptCore.h> +#include <WebCore/COMPtr.h> #include <WebKit/WebKit.h> #include <WebKit/WebKitCOMAPI.h> -#include <string> -#include <CoreFoundation/CoreFoundation.h> +#include <comutil.h> #include <shlwapi.h> #include <shlguid.h> #include <shobjidl.h> +#include <string> +#include <wtf/Platform.h> +#include <wtf/RetainPtr.h> +#include <wtf/Vector.h> using std::string; using std::wstring; @@ -183,6 +184,17 @@ size_t LayoutTestController::webHistoryItemCount() return count; } +unsigned LayoutTestController::workerThreadCount() const +{ + COMPtr<IWebWorkersPrivate> workers; + if (FAILED(WebKitCreateInstance(CLSID_WebWorkersPrivate, 0, __uuidof(workers), reinterpret_cast<void**>(&workers)))) + return 0; + unsigned count; + if (FAILED(workers->workerThreadCount(&count))) + return 0; + return count; +} + void LayoutTestController::notifyDone() { // Same as on mac. This can be shared. @@ -260,6 +272,16 @@ void LayoutTestController::setAcceptsEditing(bool acceptsEditing) editingDelegate->setAcceptsEditing(acceptsEditing); } +void LayoutTestController::setAlwaysAcceptCookies(bool alwaysAcceptCookies) +{ + if (alwaysAcceptCookies == m_alwaysAcceptCookies) + return; + + if (!::setAlwaysAcceptCookies(alwaysAcceptCookies)) + return; + m_alwaysAcceptCookies = alwaysAcceptCookies; +} + void LayoutTestController::setAuthorAndUserStylesEnabled(bool flag) { COMPtr<IWebView> webView; @@ -290,6 +312,18 @@ void LayoutTestController::setCustomPolicyDelegate(bool setDelegate, bool permis webView->setPolicyDelegate(0); } +void LayoutTestController::setMockGeolocationPosition(double latitude, double longitude, double accuracy) +{ + // FIXME: Implement for Geolocation layout tests. + // See https://bugs.webkit.org/show_bug.cgi?id=28264. +} + +void LayoutTestController::setMockGeolocationError(int code, JSStringRef message) +{ + // FIXME: Implement for Geolocation layout tests. + // See https://bugs.webkit.org/show_bug.cgi?id=28264. +} + void LayoutTestController::setIconDatabaseEnabled(bool iconDatabaseEnabled) { // See also <rdar://problem/6480108> @@ -615,14 +649,11 @@ void LayoutTestController::setSelectTrailingWhitespaceEnabled(bool flag) viewEditing->setSelectTrailingWhitespaceEnabled(flag ? TRUE : FALSE); } -static const CFTimeInterval waitToDumpWatchdogInterval = 10.0; +static const CFTimeInterval waitToDumpWatchdogInterval = 15.0; static void CALLBACK waitUntilDoneWatchdogFired(HWND, UINT, UINT_PTR, DWORD) { - const char* message = "FAIL: Timed out waiting for notifyDone to be called\n"; - fprintf(stderr, message); - fprintf(stdout, message); - dump(); + gLayoutTestController->waitToDumpWatchdogTimerFired(); } void LayoutTestController::setWaitToDump(bool waitUntilDone) @@ -707,9 +738,38 @@ void LayoutTestController::clearAllDatabases() databaseManager->deleteAllDatabases(); } +void LayoutTestController::overridePreference(JSStringRef key, JSStringRef value) +{ + 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; + + BSTR keyBSTR = JSStringCopyBSTR(key); + BSTR valueBSTR = JSStringCopyBSTR(value); + prefsPrivate->setPreferenceForTest(keyBSTR, valueBSTR); + SysFreeString(keyBSTR); + SysFreeString(valueBSTR); +} + void LayoutTestController::setDatabaseQuota(unsigned long long quota) { - printf("ERROR: LayoutTestController::setDatabaseQuota() not implemented\n"); + COMPtr<IWebDatabaseManager> databaseManager; + COMPtr<IWebDatabaseManager> tmpDatabaseManager; + + if (FAILED(WebKitCreateInstance(CLSID_WebDatabaseManager, 0, IID_IWebDatabaseManager, (void**)&tmpDatabaseManager))) + return; + if (FAILED(tmpDatabaseManager->sharedWebDatabaseManager(&databaseManager))) + return; + + databaseManager->setQuota(TEXT("file:///"), quota); } void LayoutTestController::setAppCacheMaximumSize(unsigned long long size) @@ -779,3 +839,76 @@ unsigned LayoutTestController::numberOfActiveAnimations() const return number; } + +static _bstr_t bstrT(JSStringRef jsString) +{ + // The false parameter tells the _bstr_t constructor to adopt the BSTR we pass it. + return _bstr_t(JSStringCopyBSTR(jsString), false); +} + +void LayoutTestController::whiteListAccessFromOrigin(JSStringRef sourceOrigin, JSStringRef destinationProtocol, JSStringRef destinationHost, bool allowDestinationSubdomains) +{ + COMPtr<IWebViewPrivate> webView; + if (FAILED(WebKitCreateInstance(__uuidof(WebView), 0, __uuidof(webView), reinterpret_cast<void**>(&webView)))) + return; + + webView->whiteListAccessFromOrigin(bstrT(sourceOrigin).GetBSTR(), bstrT(destinationProtocol).GetBSTR(), bstrT(destinationHost).GetBSTR(), allowDestinationSubdomains); +} + +void LayoutTestController::addUserScript(JSStringRef source, bool runAtStart) +{ + COMPtr<IWebViewPrivate> webView; + if (FAILED(WebKitCreateInstance(__uuidof(WebView), 0, __uuidof(webView), reinterpret_cast<void**>(&webView)))) + return; + + webView->addUserScriptToGroup(_bstr_t(L"org.webkit.DumpRenderTree").GetBSTR(), 1, bstrT(source).GetBSTR(), 0, 0, 0, 0, 0, runAtStart ? WebInjectAtDocumentStart : WebInjectAtDocumentEnd); +} + + +void LayoutTestController::addUserStyleSheet(JSStringRef source) +{ + COMPtr<IWebViewPrivate> webView; + if (FAILED(WebKitCreateInstance(__uuidof(WebView), 0, __uuidof(webView), reinterpret_cast<void**>(&webView)))) + return; + + webView->addUserStyleSheetToGroup(_bstr_t(L"org.webkit.DumpRenderTree").GetBSTR(), 1, bstrT(source).GetBSTR(), 0, 0, 0, 0, 0); +} + +void LayoutTestController::showWebInspector() +{ + COMPtr<IWebViewPrivate> webView; + if (FAILED(WebKitCreateInstance(__uuidof(WebView), 0, __uuidof(webView), reinterpret_cast<void**>(&webView)))) + return; + + COMPtr<IWebInspector> inspector; + if (SUCCEEDED(webView->inspector(&inspector))) + inspector->show(); +} + +void LayoutTestController::closeWebInspector() +{ + COMPtr<IWebViewPrivate> webView; + if (FAILED(WebKitCreateInstance(__uuidof(WebView), 0, __uuidof(webView), reinterpret_cast<void**>(&webView)))) + return; + + COMPtr<IWebInspector> inspector; + if (SUCCEEDED(webView->inspector(&inspector))) + inspector->close(); +} + +void LayoutTestController::evaluateInWebInspector(long callId, JSStringRef script) +{ + COMPtr<IWebViewPrivate> webView; + if (FAILED(WebKitCreateInstance(__uuidof(WebView), 0, __uuidof(webView), reinterpret_cast<void**>(&webView)))) + return; + + COMPtr<IWebInspector> inspector; + if (FAILED(webView->inspector(&inspector))) + return; + + COMPtr<IWebInspectorPrivate> inspectorPrivate(Query, inspector); + if (!inspectorPrivate) + return; + + inspectorPrivate->evaluateInFrontend(callId, bstrT(script).GetBSTR()); +} diff --git a/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.cpp b/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.cpp index 06476e7..0edf69b 100644 --- a/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.cpp +++ b/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.cpp @@ -31,10 +31,13 @@ #include "DumpRenderTree.h" #include "LayoutTestController.h" +#include <comutil.h> +#include <WebKit/WebKitCOMAPI.h> #include <wtf/HashMap.h> #include <wtf/Vector.h> #include <sstream> + using std::wstring; using std::wiostream; @@ -251,6 +254,33 @@ HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::willSendRequest( return S_OK; } +HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::didReceiveAuthenticationChallenge( + /* [in] */ IWebView *webView, + /* [in] */ unsigned long identifier, + /* [in] */ IWebURLAuthenticationChallenge *challenge, + /* [in] */ IWebDataSource *dataSource) +{ + if (!gLayoutTestController->handlesAuthenticationChallenges()) + return E_FAIL; + + const char* user = gLayoutTestController->authenticationUsername().c_str(); + const char* password = gLayoutTestController->authenticationPassword().c_str(); + + printf("%S - didReceiveAuthenticationChallenge - Responding with %s:%s\n", descriptionSuitableForTestResult(identifier).c_str(), user, password); + + COMPtr<IWebURLAuthenticationChallengeSender> sender; + if (!challenge || FAILED(challenge->sender(&sender))) + return E_FAIL; + + COMPtr<IWebURLCredential> credential; + if (FAILED(WebKitCreateInstance(CLSID_WebURLCredential, 0, IID_IWebURLCredential, (void**)&credential))) + return E_FAIL; + credential->initWithUser(_bstr_t(user), _bstr_t(password), WebURLCredentialPersistenceForSession); + + sender->useCredential(credential.get(), challenge); + return S_OK; +} + HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::didReceiveResponse( /* [in] */ IWebView* webView, /* [in] */ unsigned long identifier, diff --git a/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.h b/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.h index c708147..924727b 100644 --- a/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.h +++ b/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.h @@ -60,7 +60,7 @@ public: /* [in] */ IWebView *webView, /* [in] */ unsigned long identifier, /* [in] */ IWebURLAuthenticationChallenge *challenge, - /* [in] */ IWebDataSource *dataSource) { return E_NOTIMPL; } + /* [in] */ IWebDataSource *dataSource); virtual HRESULT STDMETHODCALLTYPE didCancelAuthenticationChallenge( /* [in] */ IWebView *webView, diff --git a/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/TestNetscapePlugin.vcproj b/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/TestNetscapePlugin.vcproj index 5ccd6ce..0e0918d 100644 --- a/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/TestNetscapePlugin.vcproj +++ b/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/TestNetscapePlugin.vcproj @@ -23,7 +23,7 @@ >
<Tool
Name="VCPreBuildEventTool"
- CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%
if exist "$(WebKitOutputDir)\buildfailed" grep XX$(ProjectName)XX "$(WebKitOutputDir)\buildfailed"
if errorlevel 1 exit 1
echo XX$(ProjectName)XX > "$(WebKitOutputDir)\buildfailed"
"
+ CommandLine="%SystemDrive%\cygwin\bin\which.exe bash
if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%
cmd /c
if exist "$(WebKitOutputDir)\buildfailed" grep XX$(ProjectName)XX "$(WebKitOutputDir)\buildfailed"
if errorlevel 1 exit 1
echo XX$(ProjectName)XX > "$(WebKitOutputDir)\buildfailed"
"
/>
<Tool
Name="VCCustomBuildTool"
@@ -93,7 +93,7 @@ >
<Tool
Name="VCPreBuildEventTool"
- CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%
if exist "$(WebKitOutputDir)\buildfailed" grep XX$(ProjectName)XX "$(WebKitOutputDir)\buildfailed"
if errorlevel 1 exit 1
echo XX$(ProjectName)XX > "$(WebKitOutputDir)\buildfailed"
"
+ CommandLine="%SystemDrive%\cygwin\bin\which.exe bash
if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%
cmd /c
if exist "$(WebKitOutputDir)\buildfailed" grep XX$(ProjectName)XX "$(WebKitOutputDir)\buildfailed"
if errorlevel 1 exit 1
echo XX$(ProjectName)XX > "$(WebKitOutputDir)\buildfailed"
"
/>
<Tool
Name="VCCustomBuildTool"
@@ -162,7 +162,7 @@ >
<Tool
Name="VCPreBuildEventTool"
- CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%
if exist "$(WebKitOutputDir)\buildfailed" grep XX$(ProjectName)XX "$(WebKitOutputDir)\buildfailed"
if errorlevel 1 exit 1
echo XX$(ProjectName)XX > "$(WebKitOutputDir)\buildfailed"
"
+ CommandLine="%SystemDrive%\cygwin\bin\which.exe bash
if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%
cmd /c
if exist "$(WebKitOutputDir)\buildfailed" grep XX$(ProjectName)XX "$(WebKitOutputDir)\buildfailed"
if errorlevel 1 exit 1
echo XX$(ProjectName)XX > "$(WebKitOutputDir)\buildfailed"
"
/>
<Tool
Name="VCCustomBuildTool"
@@ -224,6 +224,75 @@ CommandLine="if exist "$(WebKitOutputDir)\buildfailed" del "$(WebKitOutputDir)\buildfailed""
/>
</Configuration>
+ <Configuration
+ Name="Debug_Cairo|Win32"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_wincairo.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine="%SystemDrive%\cygwin\bin\which.exe bash
if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%
cmd /c
if exist "$(WebKitOutputDir)\buildfailed" grep XX$(ProjectName)XX "$(WebKitOutputDir)\buildfailed"
if errorlevel 1 exit 1
echo XX$(ProjectName)XX > "$(WebKitOutputDir)\buildfailed"
"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""$(WebKitOutputDir)\Include";"$(WebKitOutputDir)\Include\JavaScriptCore";"$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders";"$(ProjectDir)..\..\TestNetscapePlugin.subproj";"$(WebKitLibrariesDir)\include";"$(WebKitLibrariesDir)\include\CoreFoundation\OSXCompatibilityHeaders";"$(WebKitLibrariesDir)\include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility""
+ PreprocessorDefinitions="_USRDLL;TESTNETSCAPEPLUGIN_EXPORTS;snprintf=_snprintf"
+ DisableSpecificWarnings="4819"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories=""
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\$(ProjectName)$(WebKitConfigSuffix)\np$(ProjectName)$(WebKitConfigSuffix).dll"
+ ModuleDefinitionFile="TestNetscapePlugin$(WebKitConfigSuffix).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"
+ CommandLine="if exist "$(WebKitOutputDir)\buildfailed" del "$(WebKitOutputDir)\buildfailed""
+ />
+ </Configuration>
</Configurations>
<References>
</References>
diff --git a/WebKitTools/DumpRenderTree/win/UIDelegate.cpp b/WebKitTools/DumpRenderTree/win/UIDelegate.cpp index 63f5441..b78fd3e 100755 --- a/WebKitTools/DumpRenderTree/win/UIDelegate.cpp +++ b/WebKitTools/DumpRenderTree/win/UIDelegate.cpp @@ -33,6 +33,7 @@ #include "DraggingInfo.h" #include "EventSender.h" #include "LayoutTestController.h" +#include "DRTDesktopNotificationPresenter.h" #include <WebCore/COMPtr.h> #include <wtf/Platform.h> @@ -155,6 +156,7 @@ void DRTUndoManager::undo() UIDelegate::UIDelegate() : m_refCount(1) , m_undoManager(new DRTUndoManager) + , m_desktopNotifications(new DRTDesktopNotificationPresenter) { m_frame.bottom = 0; m_frame.top = 0; @@ -174,6 +176,8 @@ HRESULT STDMETHODCALLTYPE UIDelegate::QueryInterface(REFIID riid, void** ppvObje *ppvObject = static_cast<IWebUIDelegate*>(this); else if (IsEqualGUID(riid, IID_IWebUIDelegate)) *ppvObject = static_cast<IWebUIDelegate*>(this); + else if (IsEqualGUID(riid, IID_IWebUIDelegate2)) + *ppvObject = static_cast<IWebUIDelegate2*>(this); else if (IsEqualGUID(riid, IID_IWebUIDelegatePrivate)) *ppvObject = static_cast<IWebUIDelegatePrivate*>(this); else @@ -499,6 +503,11 @@ HRESULT STDMETHODCALLTYPE UIDelegate::doDragDrop( draggingInfo = new DraggingInfo(object, source); replaySavedEvents(); + if (draggingInfo) { + *performedEffect = draggingInfo->performedDropEffect(); + delete draggingInfo; + draggingInfo = 0; + } return S_OK; } @@ -561,6 +570,20 @@ HRESULT STDMETHODCALLTYPE UIDelegate::exceededDatabaseQuota( /* [in] */ IWebSecurityOrigin *origin, /* [in] */ BSTR databaseIdentifier) { + BSTR protocol; + BSTR host; + unsigned short port; + + origin->protocol(&protocol); + origin->host(&host); + origin->port(&port); + + if (!done && gLayoutTestController->dumpDatabaseCallbacks()) + printf("UI DELEGATE DATABASE CALLBACK: exceededDatabaseQuotaForSecurityOrigin:{%S, %S, %i} database:%S\n", protocol, host, port, databaseIdentifier); + + SysFreeString(protocol); + SysFreeString(host); + static const unsigned long long defaultQuota = 5 * 1024 * 1024; origin->setQuota(defaultQuota); @@ -604,3 +627,9 @@ HRESULT STDMETHODCALLTYPE UIDelegate::setStatusText(IWebView*, BSTR text) printf("UI DELEGATE STATUS CALLBACK: setStatusText:%S\n", text ? text : L""); return S_OK; } + +HRESULT STDMETHODCALLTYPE UIDelegate::desktopNotificationsDelegate(IWebDesktopNotificationsDelegate** result) +{ + m_desktopNotifications.copyRefTo(result); + return S_OK; +} diff --git a/WebKitTools/DumpRenderTree/win/UIDelegate.h b/WebKitTools/DumpRenderTree/win/UIDelegate.h index 853031f..436e31a 100755 --- a/WebKitTools/DumpRenderTree/win/UIDelegate.h +++ b/WebKitTools/DumpRenderTree/win/UIDelegate.h @@ -29,13 +29,15 @@ #ifndef UIDelegate_h #define UIDelegate_h +#include <WebCore/COMPtr.h> #include <WebKit/WebKit.h> #include <wtf/OwnPtr.h> #include <windef.h> class DRTUndoManager; +class DRTDesktopNotificationPresenter; -class UIDelegate : public IWebUIDelegate, IWebUIDelegatePrivate { +class UIDelegate : public IWebUIDelegate2, IWebUIDelegatePrivate { public: UIDelegate(); @@ -326,20 +328,11 @@ public: protected: // IWebUIDelegatePrivate - virtual HRESULT STDMETHODCALLTYPE webViewResizerRect( - /* [in] */ IWebView *sender, - /* [retval][out] */ RECT *rect) { return E_NOTIMPL; } + virtual HRESULT STDMETHODCALLTYPE unused1() { return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE webViewSendResizeMessage( - /* [in] */ UINT uMsg, - /* [in] */ WPARAM wParam, - /* [in] */ LPARAM lParam) { return E_NOTIMPL; } + virtual HRESULT STDMETHODCALLTYPE unused2() { 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 unused3() { return E_NOTIMPL; } virtual HRESULT STDMETHODCALLTYPE webViewScrolled( /* [in] */ IWebView *sender) { return E_NOTIMPL; } @@ -399,11 +392,16 @@ protected: virtual HRESULT STDMETHODCALLTYPE webViewDidInvalidate( /* [in] */ IWebView *sender); + virtual HRESULT STDMETHODCALLTYPE desktopNotificationsDelegate( + /* [out] */ IWebDesktopNotificationsDelegate** result); + ULONG m_refCount; private: RECT m_frame; OwnPtr<DRTUndoManager> m_undoManager; + + COMPtr<IWebDesktopNotificationsDelegate> m_desktopNotifications; }; #endif diff --git a/WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp b/WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp index fa7e541..bfe1d99 100644 --- a/WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp +++ b/WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp @@ -100,6 +100,11 @@ void LayoutTestController::setAcceptsEditing(bool acceptsEditing) { } +void LayoutTestController::setAlwaysAcceptCookies(bool alwaysAcceptCookies) +{ + // FIXME: Implement this (and restore the default value before running each test in DumpRenderTree.cpp). +} + void LayoutTestController::setCustomPolicyDelegate(bool, bool) { // FIXME: implement @@ -217,6 +222,12 @@ unsigned LayoutTestController::numberOfActiveAnimations() const return 0; } +unsigned LayoutTestController::workerThreadCount() const +{ + // FIXME: implement + return 0; +} + void LayoutTestController::setSelectTrailingWhitespaceEnabled(bool flag) { // FIXME: implement @@ -228,6 +239,18 @@ bool LayoutTestController::pauseTransitionAtTimeOnElementWithId(JSStringRef prop return false; } +void LayoutTestController::setMockGeolocationPosition(double latitude, double longitude, double accuracy) +{ + // FIXME: Implement for Geolocation layout tests. + // See https://bugs.webkit.org/show_bug.cgi?id=28264. +} + +void LayoutTestController::setMockGeolocationError(int code, JSStringRef message) +{ + // FIXME: Implement for Geolocation layout tests. + // See https://bugs.webkit.org/show_bug.cgi?id=28264. +} + void LayoutTestController::setIconDatabaseEnabled(bool iconDatabaseEnabled) { // FIXME: implement @@ -260,3 +283,33 @@ void LayoutTestController::waitForPolicyDelegate() { // FIXME: Implement this. } + +void LayoutTestController::overridePreference(JSStringRef /* key */, JSStringRef /* value */) +{ + // FIXME: implement +} + +void LayoutTestController::addUserScript(JSStringRef source, bool runAtStart) +{ + printf("LayoutTestController::addUserScript not implemented.\n"); +} + +void LayoutTestController::addUserStyleSheet(JSStringRef source) +{ + printf("LayoutTestController::addUserStyleSheet not implemented.\n"); +} + +void LayoutTestController::showWebInspector() +{ + // FIXME: Implement this. +} + +void LayoutTestController::closeWebInspector() +{ + // FIXME: Implement this. +} + +void LayoutTestController::evaluateInWebInspector(long callId, JSStringRef script) +{ + // FIXME: Implement this. +} diff --git a/WebKitTools/GNUmakefile.am b/WebKitTools/GNUmakefile.am index 487a479..c2029f3 100644 --- a/WebKitTools/GNUmakefile.am +++ b/WebKitTools/GNUmakefile.am @@ -60,6 +60,8 @@ Programs_DumpRenderTree_SOURCES = \ WebKitTools/DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp \ WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp \ WebKitTools/DumpRenderTree/gtk/DumpRenderTreeGtk.h \ + WebKitTools/DumpRenderTree/gtk/EventSender.h \ + WebKitTools/DumpRenderTree/gtk/EventSender.cpp \ WebKitTools/DumpRenderTree/gtk/GCControllerGtk.cpp \ WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp \ WebKitTools/DumpRenderTree/gtk/WorkQueueItemGtk.cpp @@ -85,7 +87,8 @@ Programs_DumpRenderTree_LDADD = \ $(CAIRO_LIBS) \ $(GTK_LIBS) \ $(GLIB_LIBS) \ - $(LIBSOUP_LIBS) + $(LIBSOUP_LIBS) \ + $(FREETYPE_LIBS) Programs_DumpRenderTree_LDFLAGS = \ -no-fast-install \ @@ -105,7 +108,8 @@ noinst_LTLIBRARIES += \ TestNetscapePlugin/libtestnetscapeplugin.la dumprendertree_cppflags += \ - -DTEST_PLUGIN_DIR=\"${shell pwd}/${top_builddir}/TestNetscapePlugin/.libs\" + -DTEST_PLUGIN_DIR=\"${shell pwd}/${top_builddir}/TestNetscapePlugin/.libs\" \ + -DFONTS_CONF_FILE=\"${shell pwd}/${srcdir}/WebKitTools/DumpRenderTree/gtk/fonts.conf\" TestNetscapePlugin_libtestnetscapeplugin_la_CPPFLAGS = \ -I$(srcdir)/WebKitTools/DumpRenderTree \ diff --git a/WebKitTools/Scripts/VCSUtils.pm b/WebKitTools/Scripts/VCSUtils.pm index 571487d..6ec12c9 100644 --- a/WebKitTools/Scripts/VCSUtils.pm +++ b/WebKitTools/Scripts/VCSUtils.pm @@ -25,6 +25,7 @@ # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # Module to share code to work with various version control systems. +package VCSUtils; use strict; use warnings; @@ -34,21 +35,37 @@ use File::Basename; use File::Spec; BEGIN { - use Exporter (); - our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS); - $VERSION = 1.00; - @ISA = qw(Exporter); - @EXPORT = qw(&chdirReturningRelativePath &determineSVNRoot &determineVCSRoot &isGit &isGitDirectory &isSVN &isSVNDirectory &makeFilePathRelative); - %EXPORT_TAGS = ( ); - @EXPORT_OK = (); + use Exporter (); + our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS); + $VERSION = 1.00; + @ISA = qw(Exporter); + @EXPORT = qw( + &chdirReturningRelativePath + &determineSVNRoot + &determineVCSRoot + &gitBranch + &isGit + &isGitBranchBuild + &isGitDirectory + &isSVN + &isSVNDirectory + &isSVNVersion16OrNewer + &makeFilePathRelative + &pathRelativeToSVNRepositoryRootForPath + &svnRevisionForDirectory + ); + %EXPORT_TAGS = ( ); + @EXPORT_OK = (); } our @EXPORT_OK; -my $isGit; -my $isSVN; my $gitBranch; +my $gitRoot; +my $isGit; my $isGitBranchBuild; +my $isSVN; +my $svnVersion; sub isGitDirectory($) { @@ -68,7 +85,7 @@ sub gitBranch() { unless (defined $gitBranch) { chomp($gitBranch = `git symbolic-ref -q HEAD`); - $gitBranch = "" if exitStatus($?); + $gitBranch = "" if main::exitStatus($?); # FIXME: exitStatus is defined in webkitdirs.pm $gitBranch =~ s#^refs/heads/##; $gitBranch = "" if $gitBranch eq "master"; } @@ -106,6 +123,24 @@ sub isSVN() return $isSVN; } +sub svnVersion() +{ + return $svnVersion if defined $svnVersion; + + if (!isSVN()) { + $svnVersion = 0; + } else { + chomp($svnVersion = `svn --version --quiet`); + } + return $svnVersion; +} + +sub isSVNVersion16OrNewer() +{ + my $version = svnVersion(); + return eval "v$version" ge v1.6; +} + sub chdirReturningRelativePath($) { my ($directory) = @_; @@ -128,28 +163,38 @@ sub determineSVNRoot() my $last = ''; my $path = '.'; my $parent = '..'; + my $repositoryRoot; my $repositoryUUID; while (1) { + my $thisRoot; my $thisUUID; # Ignore error messages in case we've run past the root of the checkout. open INFO, "svn info '$path' 2> $devNull |" or die; while (<INFO>) { + if (/^Repository Root: (.+)/) { + $thisRoot = $1; + } if (/^Repository UUID: (.+)/) { $thisUUID = $1; - { local $/ = undef; <INFO>; } # Consume the rest of the input. + } + if ($thisRoot && $thisUUID) { + local $/ = undef; + <INFO>; # Consume the rest of the input. } } close INFO; # It's possible (e.g. for developers of some ports) to have a WebKit # checkout in a subdirectory of another checkout. So abort if the - # repository UUID suddenly changes. + # repository root or the repository UUID suddenly changes. last if !$thisUUID; - if (!$repositoryUUID) { - $repositoryUUID = $thisUUID; - } + $repositoryUUID = $thisUUID if !$repositoryUUID; last if $thisUUID ne $repositoryUUID; + last if !$thisRoot; + $repositoryRoot = $thisRoot if !$repositoryRoot; + last if $thisRoot ne $repositoryRoot; + $last = $path; $path = File::Spec->catdir($parent, $path); } @@ -162,10 +207,16 @@ sub determineVCSRoot() if (isGit()) { return determineGitRoot(); } - if (isSVN()) { - return determineSVNRoot(); + + if (!isSVN()) { + # Some users have a workflow where svn-create-patch, svn-apply and + # svn-unapply are used outside of multiple svn working directores, + # so warn the user and assume Subversion is being used in this case. + warn "Unable to determine VCS root; assuming Subversion"; + $isSVN = 1; } - die "Unable to determine VCS root"; + + return determineSVNRoot(); } sub svnRevisionForDirectory($) @@ -206,8 +257,6 @@ sub pathRelativeToSVNRepositoryRootForPath($) return $svnURL; } - -my $gitRoot; sub makeFilePathRelative($) { my ($path) = @_; diff --git a/WebKitTools/Scripts/bisect-builds b/WebKitTools/Scripts/bisect-builds index 34230a9..93e9223 100755 --- a/WebKitTools/Scripts/bisect-builds +++ b/WebKitTools/Scripts/bisect-builds @@ -209,7 +209,7 @@ sub createTempFile($) my ($fh, $tempFile) = tempfile( basename($0) . "-XXXXXXXX", - DIR => File::Spec->tmpdir, + DIR => File::Spec->tmpdir(), SUFFIX => ".html", UNLINK => 0, ); diff --git a/WebKitTools/Scripts/bugzilla-tool b/WebKitTools/Scripts/bugzilla-tool index b3c0d67..ec5aa0d 100755 --- a/WebKitTools/Scripts/bugzilla-tool +++ b/WebKitTools/Scripts/bugzilla-tool @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # Copyright (c) 2009, Google Inc. All rights reserved. # Copyright (c) 2009 Apple Inc. All rights reserved. # @@ -30,19 +30,24 @@ # # A tool for automating dealing with bugzilla, posting patches, committing patches, etc. -import fileinput # inplace file editing for set_reviewer_in_changelog import os import re import StringIO # for add_patch_to_bug file wrappers import subprocess import sys +import time +from datetime import datetime, timedelta from optparse import OptionParser, IndentedHelpFormatter, SUPPRESS_USAGE, make_option # Import WebKit-specific modules. -from modules.bugzilla import Bugzilla -from modules.logging import error, log -from modules.scm import CommitMessage, detect_scm_system, ScriptError +from modules.bugzilla import Bugzilla, parse_bug_id +from modules.changelogs import ChangeLog +from modules.comments import bug_comment_from_commit_text +from modules.logging import error, log, tee +from modules.scm import CommitMessage, detect_scm_system, ScriptError, CheckoutNeedsUpdate +from modules.buildbot import BuildBot +from modules.statusbot import StatusBot def plural(noun): # This is a dumb plural() implementation which was just enough for our uses. @@ -56,70 +61,21 @@ def pluralize(noun, count): noun = plural(noun) return "%d %s" % (count, noun) -# These could be put in some sort of changelogs.py. -def latest_changelog_entry(changelog_path): - # e.g. 2009-06-03 Eric Seidel <eric@webkit.org> - changelog_date_line_regexp = re.compile('^(\d{4}-\d{2}-\d{2})' # Consume the date. - + '\s+(.+)\s+' # Consume the name. - + '<([^<>]+)>$') # And finally the email address. - - entry_lines = [] - changelog = open(changelog_path) - try: - log("Parsing ChangeLog: " + changelog_path) - # The first line should be a date line. - first_line = changelog.readline() - if not changelog_date_line_regexp.match(first_line): - return None - entry_lines.append(first_line) - - for line in changelog: - # If we've hit the next entry, return. - if changelog_date_line_regexp.match(line): - return ''.join(entry_lines) - entry_lines.append(line) - finally: - changelog.close() - # We never found a date line! - return None - -def set_reviewer_in_changelog(changelog_path, reviewer): - # inplace=1 creates a backup file and re-directs stdout to the file - for line in fileinput.FileInput(changelog_path, inplace=1): - print line.replace("NOBODY (OOPS!)", reviewer.encode("utf-8")), # Trailing comma suppresses printing newline - -def modified_changelogs(scm): - changelog_paths = [] - paths = scm.changed_files() - for path in paths: - if os.path.basename(path) == "ChangeLog": - changelog_paths.append(path) - return changelog_paths - -def parse_bug_id(commit_message): - message = commit_message.message() - match = re.search("http\://webkit\.org/b/(?P<bug_id>\d+)", message) - if match: - return match.group('bug_id') - match = re.search(Bugzilla.bug_server_regex + "show_bug\.cgi\?id=(?P<bug_id>\d+)", message) - if match: - return match.group('bug_id') - return None - def commit_message_for_this_commit(scm): - changelog_paths = modified_changelogs(scm) + changelog_paths = scm.modified_changelogs() if not len(changelog_paths): - raise ScriptError("Found no modified ChangeLogs, cannot create a commit message.\n" + raise ScriptError(message="Found no modified ChangeLogs, cannot create a commit message.\n" "All changes require a ChangeLog. See:\n" "http://webkit.org/coding/contributing.html") changelog_messages = [] - for path in changelog_paths: - changelog_entry = latest_changelog_entry(path) + for changelog_path in changelog_paths: + log("Parsing ChangeLog: %s" % changelog_path) + changelog_entry = ChangeLog(changelog_path).latest_entry() if not changelog_entry: - error("Failed to parse ChangeLog: " + os.path.abspath(path)) + error("Failed to parse ChangeLog: " + os.path.abspath(changelog_path)) changelog_messages.append(changelog_entry) - + # FIXME: We should sort and label the ChangeLog messages like commit-log-editor does. return CommitMessage(''.join(changelog_messages).splitlines()) @@ -183,10 +139,9 @@ class ApplyPatchesFromBug(Command): def __init__(self): options = [ make_option("--no-update", action="store_false", dest="update", default=True, help="Don't update the working directory before applying patches"), - make_option("--force-clean", action="store_true", dest="force_clean", default=False, help="Clean working directory before applying patches (removes local changes and commits)"), - make_option("--no-clean", action="store_false", dest="clean", default=True, help="Don't check if the working directory is clean before applying patches"), make_option("--local-commit", action="store_true", dest="local_commit", default=False, help="Make a local commit for each applied patch"), ] + options += WebKitLandingScripts.cleaning_options() Command.__init__(self, 'Applies all patches on a bug to the local working directory without committing.', 'BUGID', options=options) @staticmethod @@ -212,23 +167,110 @@ class ApplyPatchesFromBug(Command): self.apply_patches(patches, tool.scm(), options.local_commit) -def bug_comment_from_commit_text(scm, commit_text): - match = re.search(scm.commit_success_regexp(), commit_text, re.MULTILINE) - svn_revision = match.group('svn_revision') - commit_text += ("\nhttp://trac.webkit.org/changeset/%s" % svn_revision) - return commit_text - +class WebKitLandingScripts: + @staticmethod + def cleaning_options(): + return [ + make_option("--force-clean", action="store_true", dest="force_clean", default=False, help="Clean working directory before applying patches (removes local changes and commits)"), + make_option("--no-clean", action="store_false", dest="clean", default=True, help="Don't check if the working directory is clean before applying patches"), + ] -class LandAndUpdateBug(Command): - def __init__(self): - options = [ - make_option("-r", "--reviewer", action="store", type="string", dest="reviewer", help="Update ChangeLogs to say Reviewed by REVIEWER."), + @staticmethod + def land_options(): + return [ + make_option("--ignore-builders", action="store_false", dest="check_builders", default=True, help="Don't check to see if the build.webkit.org builders are green before landing."), make_option("--no-close", action="store_false", dest="close_bug", default=True, help="Leave bug open after landing."), make_option("--no-build", action="store_false", dest="build", default=True, help="Commit without building first, implies --no-test."), make_option("--no-test", action="store_false", dest="test", default=True, help="Commit without running run-webkit-tests."), make_option("--quiet", action="store_true", dest="quiet", default=False, help="Produce less console output."), make_option("--commit-queue", action="store_true", dest="commit_queue", default=False, help="Run in commit queue mode (no user interaction)."), ] + + @staticmethod + def run_command_with_teed_output(args, teed_output): + child_process = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + + # Use our own custom wait loop because Popen ignores a tee'd stderr/stdout. + # FIXME: This could be improved not to flatten output to stdout. + while True: + output_line = child_process.stdout.readline() + if output_line == '' and child_process.poll() != None: + return child_process.poll() + teed_output.write(output_line) + + @staticmethod + def run_and_throw_if_fail(args, quiet=False): + # Cache the child's output locally so it can be used for error reports. + child_out_file = StringIO.StringIO() + if quiet: + dev_null = open(os.devnull, "w") + child_stdout = tee(child_out_file, dev_null if quiet else sys.stdout) + exit_code = WebKitLandingScripts.run_command_with_teed_output(args, child_stdout) + if quiet: + dev_null.close() + + child_output = child_out_file.getvalue() + child_out_file.close() + + if exit_code: + raise ScriptError(script_args=args, exit_code=exit_code, output=child_output) + + # We might need to pass scm into this function for scm.checkout_root + @staticmethod + def webkit_script_path(script_name): + return os.path.join("WebKitTools", "Scripts", script_name) + + @classmethod + def run_webkit_script(cls, script_name, quiet=False): + log("Running %s" % script_name) + cls.run_and_throw_if_fail(cls.webkit_script_path(script_name), quiet) + + @classmethod + def build_webkit(cls, quiet=False): + cls.run_webkit_script("build-webkit", quiet) + + @staticmethod + def ensure_builders_are_green(buildbot, options): + if not options.check_builders or buildbot.core_builders_are_green(): + return + error("Builders at %s are red, please do not commit. Pass --ignore-builders to bypass this check." % (buildbot.buildbot_host)) + + @classmethod + def run_webkit_tests(cls, launch_safari, fail_fast=False, quiet=False): + args = [cls.webkit_script_path("run-webkit-tests")] + if not launch_safari: + args.append("--no-launch-safari") + if quiet: + args.append("--quiet") + if fail_fast: + args.append("--exit-after-n-failures=1") + cls.run_and_throw_if_fail(args) + + @staticmethod + def setup_for_landing(scm, options): + os.chdir(scm.checkout_root) + scm.ensure_no_local_commits(options.force_clean) + if options.clean: + scm.ensure_clean_working_directory(options.force_clean) + + @classmethod + def build_and_commit(cls, scm, options): + if options.build: + cls.build_webkit(quiet=options.quiet) + if options.test: + # When running the commit-queue we don't want to launch Safari and we want to exit after the first failure. + cls.run_webkit_tests(launch_safari=not options.commit_queue, fail_fast=options.commit_queue, quiet=options.quiet) + commit_message = commit_message_for_this_commit(scm) + commit_log = scm.commit_with_message(commit_message.message()) + return bug_comment_from_commit_text(scm, commit_log) + + +class LandAndUpdateBug(Command): + def __init__(self): + options = [ + make_option("-r", "--reviewer", action="store", type="string", dest="reviewer", help="Update ChangeLogs to say Reviewed by REVIEWER."), + ] + options += WebKitLandingScripts.land_options() Command.__init__(self, 'Lands the current working directory diff and updates the bug if provided.', '[BUGID]', options=options) def guess_reviewer_from_bug(self, bugs, bug_id): @@ -252,17 +294,18 @@ class LandAndUpdateBug(Command): log("Failed to guess reviewer from bug %s and --reviewer= not provided. Not updating ChangeLogs with reviewer." % bug_id) return - changelogs = modified_changelogs(tool.scm()) - for changelog in changelogs: - set_reviewer_in_changelog(changelog, reviewer) + for changelog_path in tool.scm().modified_changelogs(): + ChangeLog(changelog_path).set_reviewer(reviewer) def execute(self, options, args, tool): bug_id = args[0] if len(args) else None os.chdir(tool.scm().checkout_root) + WebKitLandingScripts.ensure_builders_are_green(tool.buildbot, options) + self.update_changelogs_with_reviewer(options.reviewer, bug_id, tool) - comment_text = LandPatchesFromBugs.build_and_commit(tool.scm(), options) + comment_text = WebKitLandingScripts.build_and_commit(tool.scm(), options) if bug_id: log("Updating bug %s" % bug_id) if options.close_bug: @@ -278,104 +321,66 @@ class LandAndUpdateBug(Command): class LandPatchesFromBugs(Command): def __init__(self): - options = [ - make_option("--force-clean", action="store_true", dest="force_clean", default=False, help="Clean working directory before applying patches (removes local changes and commits)"), - make_option("--no-clean", action="store_false", dest="clean", default=True, help="Don't check if the working directory is clean before applying patches"), - make_option("--no-close", action="store_false", dest="close_bug", default=True, help="Leave bug open after landing."), - make_option("--no-build", action="store_false", dest="build", default=True, help="Commit without building first, implies --no-test."), - make_option("--no-test", action="store_false", dest="test", default=True, help="Commit without running run-webkit-tests."), - make_option("--quiet", action="store_true", dest="quiet", default=False, help="Produce less console output."), - make_option("--commit-queue", action="store_true", dest="commit_queue", default=False, help="Run in commit queue mode (no user interaction)."), - ] + options = WebKitLandingScripts.cleaning_options() + options += WebKitLandingScripts.land_options() Command.__init__(self, 'Lands all patches on a bug optionally testing them first', 'BUGID', options=options) - @staticmethod - def run_and_throw_if_fail(args, quiet=False): - child_stdout = subprocess.PIPE if quiet else None - child_process = subprocess.Popen(args, stdout=child_stdout) - if child_process.stdout: - child_process.communicate() - return_code = child_process.wait() - if return_code: - raise ScriptError("%s failed with exit code %d" % (" ".join(args), return_code)) - - # We might need to pass scm into this function for scm.checkout_root - @staticmethod - def webkit_script_path(script_name): - return os.path.join("WebKitTools", "Scripts", script_name) - - @classmethod - def run_webkit_script(cls, script_name, quiet=False): - print "Running WebKit Script " + script_name - cls.run_and_throw_if_fail(cls.webkit_script_path(script_name), quiet) - - @classmethod - def build_webkit(cls, quiet=False): - cls.run_webkit_script("build-webkit", quiet) - - @classmethod - def run_webkit_tests(cls, launch_safari, quiet=False): - args = [cls.webkit_script_path("run-webkit-tests")] - if not launch_safari: - args.append("--no-launch-safari") - if quiet: - args.append("--quiet") - cls.run_and_throw_if_fail(args) - - @staticmethod - def setup_for_landing(scm, options): - os.chdir(scm.checkout_root) - scm.ensure_no_local_commits(options.force_clean) - if options.clean: - scm.ensure_clean_working_directory(options.force_clean) - - @classmethod - def build_and_commit(cls, scm, options): - if options.build: - cls.build_webkit(quiet=options.quiet) - if options.test: - cls.run_webkit_tests(launch_safari=not options.commit_queue, quiet=options.quiet) - commit_message = commit_message_for_this_commit(scm) - commit_log = scm.commit_with_message(commit_message.message()) - return bug_comment_from_commit_text(scm, commit_log) - @classmethod def land_patches(cls, bug_id, patches, options, tool): try: comment_text = "" for patch in patches: tool.scm().update_webkit() # Update before every patch in case the tree has changed + log("Applying %s from bug %s." % (patch['id'], bug_id)) tool.scm().apply_patch(patch, force=options.commit_queue) - comment_text = cls.build_and_commit(tool.scm(), options) - tool.bugs.clear_attachment_review_flag(patch['id'], comment_text) + # Make sure the tree is still green after updating, before building this patch. + # The first patch ends up checking tree status twice, but that's OK. + WebKitLandingScripts.ensure_builders_are_green(tool.buildbot, options) + comment_text = WebKitLandingScripts.build_and_commit(tool.scm(), options) + tool.bugs.clear_attachment_flags(patch['id'], comment_text) if options.close_bug: tool.bugs.close_bug_as_fixed(bug_id, "All reviewed patches have been landed. Closing bug.") + except CheckoutNeedsUpdate, e: + log("Commit was rejected because the checkout is out of date. Please update and try again.") + log("You can pass --no-build to skip building/testing after update if you believe the new commits did not affect the results.") + error(e) except ScriptError, e: - # We should add a comment to the bug, and r- the patch on failure + # Mark the patch as commit-queue- and comment in the bug. + tool.bugs.reject_patch_from_commit_queue(patch['id'], e.message_with_output()) error(e) - def execute(self, options, args, tool): - if not len(args): - error("bug-id(s) required") - + @staticmethod + def _fetch_list_of_patches_to_land(options, args, tool): bugs_to_patches = {} patch_count = 0 for bug_id in args: patches = [] if options.commit_queue: - patches = tool.bugs.fetch_commit_queue_patches_from_bug(bug_id) + patches = tool.bugs.fetch_commit_queue_patches_from_bug(bug_id, reject_invalid_patches=True) else: patches = tool.bugs.fetch_reviewed_patches_from_bug(bug_id) - if not len(patches): - log("No reviewed patches found on %s." % bug_id) - continue - patch_count += len(patches) - bugs_to_patches[bug_id] = patches + + patches_found = len(patches) + log("%s found on bug %s." % (pluralize("reviewed patch", patches_found), bug_id)) + + patch_count += patches_found + if patches_found: + bugs_to_patches[bug_id] = patches log("Landing %s from %s." % (pluralize("patch", patch_count), pluralize("bug", len(args)))) + return bugs_to_patches + + def execute(self, options, args, tool): + if not len(args): + error("bug-id(s) required") - self.setup_for_landing(tool.scm(), options) + # Check the tree status here so we can fail early + WebKitLandingScripts.ensure_builders_are_green(tool.buildbot, options) + + bugs_to_patches = self._fetch_list_of_patches_to_land(options, args, tool) + + WebKitLandingScripts.setup_for_landing(tool.scm(), options) for bug_id in bugs_to_patches.keys(): self.land_patches(bug_id, bugs_to_patches[bug_id], options, tool) @@ -405,11 +410,17 @@ class ObsoleteAttachmentsOnBug(Command): class PostDiffAsPatchToBug(Command): def __init__(self): options = [ + make_option("-m", "--description", action="store", type="string", dest="description", help="Description string for the attachment (default: 'patch')"), + ] + options += self.posting_options() + Command.__init__(self, 'Attaches the current working directory diff to a bug as a patch file.', '[BUGID]', options=options) + + @staticmethod + def posting_options(): + return [ make_option("--no-obsolete", action="store_false", dest="obsolete_patches", default=True, help="Do not obsolete old patches before posting this one."), make_option("--no-review", action="store_false", dest="review", default=True, help="Do not mark the patch for review."), - make_option("-m", "--description", action="store", type="string", dest="description", help="Description string for the attachment (default: 'patch')"), ] - Command.__init__(self, 'Attaches the current working directory diff to a bug as a patch file.', 'BUGID', options=options) @staticmethod def obsolete_patches_on_bug(bug_id, bugs): @@ -420,7 +431,10 @@ class PostDiffAsPatchToBug(Command): bugs.obsolete_attachment(patch['id']) def execute(self, options, args, tool): - bug_id = args[0] + # Perfer a bug id passed as an argument over a bug url in the diff (i.e. ChangeLogs). + bug_id = (args and args[0]) or parse_bug_id(tool.scm().create_patch()) + if not bug_id: + error("No bug id passed and no bug url found in diff, can't post.") if options.obsolete_patches: self.obsolete_patches_on_bug(bug_id, tool.bugs) @@ -436,49 +450,109 @@ class PostCommitsAsPatchesToBug(Command): def __init__(self): options = [ make_option("-b", "--bug-id", action="store", type="string", dest="bug_id", help="Specify bug id if no URL is provided in the commit log."), - make_option("--no-comment", action="store_false", dest="comment", default=True, help="Do not use commit log message as a comment for the patch."), - make_option("--no-obsolete", action="store_false", dest="obsolete_patches", default=True, help="Do not obsolete old patches before posting new ones."), - make_option("--no-review", action="store_false", dest="review", default=True, help="Do not mark the patch for review."), - make_option("-m", "--description", action="store", type="string", dest="description", help="Description string for the attachment (default: 'patch')"), + make_option("--add-log-as-comment", action="store_true", dest="add_log_as_comment", default=False, help="Add commit log message as a comment when uploading the patch."), + make_option("-m", "--description", action="store", type="string", dest="description", help="Description string for the attachment (default: description from commit message)"), ] + options += PostDiffAsPatchToBug.posting_options() Command.__init__(self, 'Attaches a range of local commits to bugs as patch files.', 'COMMITISH', options=options, requires_local_commits=True) + def _comment_text_for_commit(self, options, commit_message, tool, commit_id): + comment_text = None + if (options.add_log_as_comment): + comment_text = commit_message.body(lstrip=True) + comment_text += "---\n" + comment_text += tool.scm().files_changed_summary_for_commit(commit_id) + return comment_text + + def _diff_file_for_commit(self, tool, commit_id): + diff = tool.scm().create_patch_from_local_commit(commit_id) + return StringIO.StringIO(diff) # add_patch_to_bug expects a file-like object + def execute(self, options, args, tool): if not args: error("%s argument is required" % self.argument_names) commit_ids = tool.scm().commit_ids_from_commitish_arguments(args) - if len(commit_ids) > 10: - error("Are you sure you want to attach %s patches?" % (pluralize('patch', len(commit_ids)))) - # Could add a --patches-limit option. + if len(commit_ids) > 10: # We could lower this limit, 10 is too many for one bug as-is. + error("bugzilla-tool does not support attaching %s at once. Are you sure you passed the right commit range?" % (pluralize('patch', len(commit_ids)))) have_obsoleted_patches = set() for commit_id in commit_ids: - # FIXME: commit_message is the wrong place to look for the bug_id - # the ChangeLogs should have the bug id, but the local commit message might not. commit_message = tool.scm().commit_message_for_local_commit(commit_id) - bug_id = options.bug_id or parse_bug_id(commit_message) + # Prefer --bug-id=, then a bug url in the commit message, then a bug url in the entire commit diff (i.e. ChangeLogs). + bug_id = options.bug_id or parse_bug_id(commit_message.message()) or parse_bug_id(tool.scm().create_patch_from_local_commit(commit_id)) if not bug_id: - log("Skipping %s: No bug id found in commit log or specified with --bug-id." % commit_id) + log("Skipping %s: No bug id found in commit or specified with --bug-id." % commit_id) continue if options.obsolete_patches and bug_id not in have_obsoleted_patches: PostDiffAsPatchToBug.obsolete_patches_on_bug(bug_id, tool.bugs) have_obsoleted_patches.add(bug_id) + diff_file = self._diff_file_for_commit(tool, commit_id) description = options.description or commit_message.description(lstrip=True, strip_url=True) - comment_text = None - if (options.comment): - comment_text = commit_message.body(lstrip=True) - comment_text += "---\n" - comment_text += tool.scm().files_changed_summary_for_commit(commit_id) - - diff = tool.scm().create_patch_from_local_commit(commit_id) - diff_file = StringIO.StringIO(diff) # add_patch_to_bug expects a file-like object + comment_text = self._comment_text_for_commit(options, commit_message, tool, commit_id) tool.bugs.add_patch_to_bug(bug_id, diff_file, description, comment_text, mark_for_review=options.review) +class RolloutCommit(Command): + def __init__(self): + options = WebKitLandingScripts.land_options() + options += WebKitLandingScripts.cleaning_options() + options.append(make_option("--complete-rollout", action="store_true", dest="complete_rollout", help="Experimental support for complete unsupervised rollouts, including re-opening the bug. Not recommended.")) + Command.__init__(self, 'Reverts the given revision and commits the revert and re-opens the original bug.', 'REVISION [BUGID]', options=options) + + @staticmethod + def _create_changelogs_for_revert(scm, revision): + # First, discard the ChangeLog changes from the rollout. + changelog_paths = scm.modified_changelogs() + scm.revert_files(changelog_paths) + + # Second, make new ChangeLog entries for this rollout. + # This could move to prepare-ChangeLog by adding a --revert= option. + WebKitLandingScripts.run_webkit_script("prepare-ChangeLog") + for changelog_path in changelog_paths: + ChangeLog(changelog_path).update_for_revert(revision) + + @staticmethod + def _parse_bug_id_from_revision_diff(tool, revision): + original_diff = tool.scm().diff_for_revision(revision) + return parse_bug_id(original_diff) + + @staticmethod + def _reopen_bug_after_rollout(tool, bug_id, comment_text): + if bug_id: + tool.bugs.reopen_bug(bug_id, comment_text) + else: + log(comment_text) + log("No bugs were updated or re-opened to reflect this rollout.") + + def execute(self, options, args, tool): + if not args: + error("REVISION is required, see --help.") + revision = args[0] + bug_id = self._parse_bug_id_from_revision_diff(tool, revision) + if options.complete_rollout: + if bug_id: + log("Will re-open bug %s after rollout." % bug_id) + else: + log("Failed to parse bug number from diff. No bugs will be updated/reopened after the rollout.") + + WebKitLandingScripts.setup_for_landing(tool.scm(), options) + tool.scm().update_webkit() + tool.scm().apply_reverse_diff(revision) + self._create_changelogs_for_revert(tool.scm(), revision) + + # FIXME: Fully automated rollout is not 100% idiot-proof yet, so for now just log with instructions on how to complete the rollout. + # Once we trust rollout we will remove this option. + if not options.complete_rollout: + log("\nNOTE: Rollout support is experimental.\nPlease verify the rollout diff and use 'bugzilla-tool land-diff %s' to commit the rollout." % bug_id) + else: + comment_text = WebKitLandingScripts.build_and_commit(tool.scm(), options) + self._reopen_bug_after_rollout(tool, bug_id, comment_text) + + class CreateBug(Command): def __init__(self): options = [ @@ -533,9 +607,18 @@ class CreateBug(Command): def prompt_for_bug_title_and_comment(self): bug_title = raw_input("Bug title: ") - print("Bug comment (hit ^D on blank line to end):") + print "Bug comment (hit ^D on blank line to end):" lines = sys.stdin.readlines() - sys.stdin.seek(0, os.SEEK_END) + try: + sys.stdin.seek(0, os.SEEK_END) + except IOError: + # Cygwin raises an Illegal Seek (errno 29) exception when the above + # seek() call is made. Ignoring it seems to cause no harm. + # FIXME: Figure out a way to get avoid the exception in the first + # place. + pass + else: + raise comment_text = ''.join(lines) return (bug_title, comment_text) @@ -548,6 +631,126 @@ class CreateBug(Command): self.create_bug_from_patch(options, args, tool) +class CheckTreeStatus(Command): + def __init__(self): + Command.__init__(self, 'Print out the status of the webkit builders.') + + def execute(self, options, args, tool): + for builder in tool.buildbot.builder_statuses(): + status_string = "ok" if builder['is_green'] else 'FAIL' + print "%s : %s" % (status_string.ljust(4), builder['name']) + + +class LandPatchesFromCommitQueue(Command): + def __init__(self): + options = [ + make_option("--no-confirm", action="store_false", dest="confirm", default=True, help="Do not ask the user for confirmation before running the queue. Dangerous!"), + make_option("--status-host", action="store", type="string", dest="status_host", default=StatusBot.default_host, help="Do not ask the user for confirmation before running the queue. Dangerous!"), + ] + Command.__init__(self, 'Run the commit queue.', options=options) + self._original_stdout = None + self._original_stderr = None + self._files_for_output = [] + + queue_log_path = 'commit_queue.log' + bug_logs_directory = 'commit_queue_logs' + + log_date_format = "%Y-%m-%d %H:%M:%S" + sleep_duration_text = "5 mins" + seconds_to_sleep = 300 + + def _tee_outputs_to_files(self, files): + if not self._original_stdout: + self._original_stdout = sys.stdout + self._original_stderr = sys.stderr + if files and len(files): + sys.stdout = tee(self._original_stdout, *files) + sys.stderr = tee(self._original_stderr, *files) + else: + sys.stdout = self._original_stdout + sys.stderr = self._original_stderr + + @classmethod + def _sleep_message(cls, message): + wake_time = datetime.now() + timedelta(seconds=cls.seconds_to_sleep) + return "%s Sleeping until %s (%s)." % (message, wake_time.strftime(cls.log_date_format), cls.sleep_duration_text) + + @classmethod + def _sleep(cls, message): + log(cls._sleep_message(message)) + time.sleep(cls.seconds_to_sleep) + + def _update_status_and_sleep(self, message): + status_message = self._sleep_message(message) + self.status_bot.update_status(status_message) + log(status_message) + time.sleep(self.seconds_to_sleep) + + @staticmethod + def _open_log_file(log_path): + (log_directory, log_name) = os.path.split(log_path) + if log_directory and not os.path.exists(log_directory): + os.makedirs(log_directory) + return open(log_path, 'a+') + + def _add_log_to_output_tee(self, path): + log_file = self._open_log_file(path) + self._files_for_output.append(log_file) + self._tee_outputs_to_files(self._files_for_output) + return log_file + + def _remove_log_from_output_tee(self, log_file): + self._files_for_output.remove(log_file) + self._tee_outputs_to_files(self._files_for_output) + log_file.close() + + def execute(self, options, args, tool): + log("CAUTION: commit-queue will discard all local changes in %s" % tool.scm().checkout_root) + if options.confirm: + response = raw_input("Are you sure? Type 'yes' to continue: ") + if (response != 'yes'): + error("User declined.") + + queue_log = self._add_log_to_output_tee(self.queue_log_path) + log("Running WebKit Commit Queue. %s" % datetime.now().strftime(self.log_date_format)) + + self.status_bot = StatusBot(host=options.status_host) + + while (True): + # Either of these calls could throw URLError which shouldn't stop the queue. + # We catch all exceptions just in case. + try: + # Fetch patches instead of just bug ids to that we validate reviewer/committer flags on every patch. + patches = tool.bugs.fetch_patches_from_commit_queue(reject_invalid_patches=True) + if not len(patches): + self._update_status_and_sleep("Empty queue.") + continue + patch_ids = map(lambda patch: patch['id'], patches) + first_bug_id = patches[0]['bug_id'] + log("%s in commit queue [%s]" % (pluralize('patch', len(patches)), ", ".join(patch_ids))) + + if not tool.buildbot.core_builders_are_green(): + self._update_status_and_sleep("Builders (http://build.webkit.org) are red.") + continue + + self.status_bot.update_status("Landing patches from bug %s." % first_bug_id, bug_id=first_bug_id) + except Exception, e: + # Don't try tell the status bot, in case telling it causes an exception. + self._sleep("Exception while checking queue and bots: %s." % e) + continue + + # Try to land patches on the first bug in the queue before looping + bug_log_path = os.path.join(self.bug_logs_directory, "%s.log" % first_bug_id) + bug_log = self._add_log_to_output_tee(bug_log_path) + bugzilla_tool_path = __file__ # re-execute this script + bugzilla_tool_args = [bugzilla_tool_path, 'land-patches', '--force-clean', '--commit-queue', '--quiet', first_bug_id] + WebKitLandingScripts.run_command_with_teed_output(bugzilla_tool_args, sys.stdout) + self._remove_log_from_output_tee(bug_log) + + log("Finished WebKit Commit Queue. %s" % datetime.now().strftime(self.log_date_format)) + self._remove_log_from_output_tee(queue_log) + + class NonWrappingEpilogIndentedHelpFormatter(IndentedHelpFormatter): def __init__(self): IndentedHelpFormatter.__init__(self) @@ -571,6 +774,7 @@ class BugzillaTool: def __init__(self): self.cached_scm = None self.bugs = Bugzilla() + self.buildbot = BuildBot() self.commands = [ { 'name' : 'bugs-to-commit', 'object' : BugsInCommitQueue() }, { 'name' : 'patches-to-commit', 'object' : PatchesInCommitQueue() }, @@ -583,6 +787,9 @@ class BugzillaTool: { 'name' : 'obsolete-attachments', 'object' : ObsoleteAttachmentsOnBug() }, { 'name' : 'post-diff', 'object' : PostDiffAsPatchToBug() }, { 'name' : 'post-commits', 'object' : PostCommitsAsPatchesToBug() }, + { 'name' : 'tree-status', 'object' : CheckTreeStatus() }, + { 'name' : 'commit-queue', 'object' : LandPatchesFromCommitQueue() }, + { 'name' : 'rollout', 'object' : RolloutCommit() }, ] self.global_option_parser = HelpPrintingOptionParser(usage=self.usage_line(), formatter=NonWrappingEpilogIndentedHelpFormatter(), epilog=self.commands_usage()) diff --git a/WebKitTools/Scripts/build-webkit b/WebKitTools/Scripts/build-webkit index fe6d3c7..4f78eef 100755 --- a/WebKitTools/Scripts/build-webkit +++ b/WebKitTools/Scripts/build-webkit @@ -1,6 +1,7 @@ #!/usr/bin/perl -w -# Copyright (C) 2005, 2006 Apple Computer, Inc. All rights reserved. +# Copyright (C) 2005, 2006 Apple Inc. All rights reserved. +# Copyright (C) 2009 Google Inc. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -37,6 +38,9 @@ use lib $FindBin::Bin; use webkitdirs; use POSIX; +sub formatBuildTime($); +sub writeCongrats(); + my $originalWorkingDirectory = getcwd(); chdirWebKit(); @@ -44,17 +48,18 @@ my $showHelp = 0; my $clean = 0; my $minimal = 0; my $makeArgs; +my $startTime = time(); my ($threeDCanvasSupport, $threeDRenderingSupport, $channelMessagingSupport, $databaseSupport, $datagridSupport, $domStorageSupport, - $filtersSupport, $geolocationSupport, $gnomeKeyringSupport, $iconDatabaseSupport, - $javaScriptDebuggerSupport, $offlineWebApplicationSupport, $rubySupport, $sharedWorkersSupport, + $eventsourceSupport, $filtersSupport, $geolocationSupport, $iconDatabaseSupport, + $javaScriptDebuggerSupport, $mathmlSupport, $offlineWebApplicationSupport, $rubySupport, $sharedWorkersSupport, $svgSupport, $svgAnimationSupport, $svgAsImageSupport, $svgDOMObjCBindingsSupport, $svgFontsSupport, - $svgForeignObjectSupport, $svgUseSupport, $videoSupport, $webSocketsSupport, $wmlSupport, $workersSupport, - $xpathSupport, $xsltSupport, $coverageSupport); + $svgForeignObjectSupport, $svgUseSupport, $videoSupport, $webSocketsSupport, $wmlSupport, $wcssSupport, $xhtmlmpSupport, $workersSupport, + $xpathSupport, $xsltSupport, $coverageSupport, $notificationsSupport); my @features = ( { option => "3d-canvas", desc => "Toggle 3D canvas support", - define => "ENABLE_3D_CANVAS", default => 0, value => \$threeDCanvasSupport }, + define => "ENABLE_3D_CANVAS", default => (isAppleMacWebKit() && !isTiger()), value => \$threeDCanvasSupport }, { option => "3d-rendering", desc => "Toggle 3D rendering support", define => "ENABLE_3D_RENDERING", default => (isAppleMacWebKit() && !isTiger()), value => \$threeDRenderingSupport }, @@ -74,14 +79,14 @@ my @features = ( { option => "dom-storage", desc => "Toggle DOM Storage Support", define => "ENABLE_DOM_STORAGE", default => 1, value => \$domStorageSupport }, + { option => "eventsource", desc => "Toggle server-sent events support", + define => "ENABLE_EVENTSOURCE", default => 1, value => \$eventsourceSupport }, + { option => "filters", desc => "Toggle Filters support", define => "ENABLE_FILTERS", default => 0, value => \$filtersSupport }, { option => "geolocation", desc => "Toggle Geolocation support", - define => "ENABLE_GEOLOCATION", default => 0, value => \$geolocationSupport }, - - { option => "gnomekeyring", desc => "Toggle GNOME Keyring Support (GTK+ port only)", - define => "WTF_USE_GNOMEKEYRING", default => 0, value => \$gnomeKeyringSupport }, + define => "ENABLE_GEOLOCATION", default => isGtk(), value => \$geolocationSupport }, { option => "icon-database", desc => "Toggle Icon database support", define => "ENABLE_ICONDATABASE", default => 1, value => \$iconDatabaseSupport }, @@ -89,6 +94,12 @@ my @features = ( { option => "javascript-debugger", desc => "Toggle JavaScript Debugger/Profiler support", define => "ENABLE_JAVASCRIPT_DEBUGGER", default => 1, value => \$javaScriptDebuggerSupport }, + { option => "mathml", desc => "Toggle MathML support", + define => "ENABLE_MATHML", default => 0, value => \$mathmlSupport }, + + { option => "notifications", desc => "Toggle Desktop Notifications Support", + define => "ENABLE_NOTIFICATIONS", default => 0, value => \$notificationsSupport }, + { option => "offline-web-applications", desc => "Toggle Offline Web Application Support", define => "ENABLE_OFFLINE_WEB_APPLICATIONS", default => 1, value => \$offlineWebApplicationSupport }, @@ -96,7 +107,7 @@ my @features = ( define => "ENABLE_RUBY", default => 1, value => \$rubySupport }, { option => "shared-workers", desc => "Toggle SharedWorkers support", - define => "ENABLE_SHARED_WORKERS", default => 0, value => \$sharedWorkersSupport }, + define => "ENABLE_SHARED_WORKERS", default => (isAppleWebKit() || isGtk()), value => \$sharedWorkersSupport }, { option => "svg", desc => "Toggle SVG support", define => "ENABLE_SVG", default => 1, value => \$svgSupport }, @@ -128,6 +139,12 @@ my @features = ( { option => "wml", desc => "Toggle WML support", define => "ENABLE_WML", default => 0, value => \$wmlSupport }, + { option => "xhtmlmp", desc => "Toggle XHTML-MP support", + define => "ENABLE_XHTMLMP", default => 0, value => \$xhtmlmpSupport }, + + { option => "wcss", desc => "Toggle WCSS support", + define => "ENABLE_WCSS", default => 0, value => \$wcssSupport }, + { option => "workers", desc => "Toggle Web Workers support", define => "ENABLE_WORKERS", default => (isAppleWebKit() || isGtk()), value => \$workersSupport }, @@ -205,18 +222,6 @@ if ($showHelp) { checkRequiredSystemConfig(); setConfiguration(); -if (isWx()) { - $ENV{"WEBKITOUTPUTDIR"} = productDir(); - - my @opts = getWxArgs(); - - if ($clean) { - push(@opts, "clean"); - } - system "WebKitTools/wx/build-wxwebkit @opts"; - exit exitStatus($?); -} - my $productDir = productDir(); # Check that all the project directories are there. @@ -306,6 +311,19 @@ if (isGtk()) { # Force re-link of existing libraries if different than expected removeLibraryDependingOnSVG("WebCore", $svgSupport); +if (isWx()) { + downloadWafIfNeeded(); + push @projects, 'WebKitTools/wx/browser'; + push @projects, 'WebKit/wx/bindings/python'; +} + +if (isChromium()) { + # Chromium doesn't build by project directories. + @projects = (); + my $result = buildChromium($clean, @options); + exit $result if $result; +} + # Build, and abort if the build fails. for my $dir (@projects) { chdir $dir or die; @@ -327,6 +345,16 @@ for my $dir (@projects) { if ($dir eq "WebKit") { $result = buildVisualStudioProject("win/WebKit.vcproj/WebKit.sln", $clean); } + } elsif (isWx()) { + @options = (); + if (defined($makeArgs)) { + @options = split(/ /, $makeArgs); + } + if ($dir eq "WebKit" && isWx()) { + chdir 'wx' or die; + } + + $result = buildWafProject($dir, $clean, @options); } if (exitStatus($result)) { @@ -339,21 +367,44 @@ for my $dir (@projects) { } exit exitStatus($result); } - chdir ".." or die; + chdirWebKit(); } # Don't report the "WebKit is now built" message after a clean operation. exit if $clean; # Write out congratulations message. +writeCongrats(); + +exit 0; -my $launcherPath = launcherPath(); -my $launcherName = launcherName(); +sub formatBuildTime($) +{ + my ($buildTime) = @_; -print "\n"; -print "===========================================================\n"; -print " WebKit is now built. To run $launcherName with this newly-built\n"; -print " code, use the \"$launcherPath\" script.\n"; -print "===========================================================\n"; + my $buildHours = int($buildTime / 3600); + my $buildMins = int(($buildTime - $buildHours * 3600) / 60); + my $buildSecs = $buildTime - $buildHours * 3600 - $buildMins * 60; -exit 0; + if ($buildHours) { + return sprintf("%dh:%02dm:%02ds", $buildHours, $buildMins, $buildSecs); + } + return sprintf("%02dm:%02ds", $buildMins, $buildSecs); +} + +sub writeCongrats() +{ + my $launcherPath = launcherPath(); + my $launcherName = launcherName(); + my $endTime = time(); + my $buildTime = formatBuildTime($endTime - $startTime); + + print "\n"; + print "===========================================================\n"; + print " WebKit is now built ($buildTime). \n"; + if (!isChromium()) { + print " To run $launcherName with this newly-built code, use the\n"; + print " \"$launcherPath\" script.\n"; + } + print "===========================================================\n"; +} diff --git a/WebKitTools/Scripts/check-for-global-initializers b/WebKitTools/Scripts/check-for-global-initializers index e6c1a69..a74f57d 100755 --- a/WebKitTools/Scripts/check-for-global-initializers +++ b/WebKitTools/Scripts/check-for-global-initializers @@ -111,6 +111,11 @@ for my $file (sort @files) { next if $shortName eq "RenderObject.o"; next if $shortName eq "SubresourceLoader.o"; next if $shortName eq "SVGElementInstance.o"; + next if $shortName eq "XMLHttpRequest.o"; + } + if ($target eq "WebKit") { + next if $shortName eq "HostedNetscapePluginStream.o"; + next if $shortName eq "NetscapePluginInstanceProxy.o"; } } diff --git a/WebKitTools/Scripts/check-webkit-style b/WebKitTools/Scripts/check-webkit-style index 14812a7..5709cf0 100755 --- a/WebKitTools/Scripts/check-webkit-style +++ b/WebKitTools/Scripts/check-webkit-style @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # # Copyright (C) 2009 Google Inc. All rights reserved. # diff --git a/WebKitTools/Scripts/commit-log-editor b/WebKitTools/Scripts/commit-log-editor index e2fc92d..e58b181 100755 --- a/WebKitTools/Scripts/commit-log-editor +++ b/WebKitTools/Scripts/commit-log-editor @@ -39,6 +39,7 @@ use VCSUtils; use webkitdirs; sub normalizeLineEndings($$); +sub removeLongestCommonPrefixEndingInDoubleNewline(\%); sub usage { @@ -216,6 +217,8 @@ for my $changeLog (@changeLogs) { $changeLogContents{$label} = $contents; } +my $commonPrefix = removeLongestCommonPrefixEndingInDoubleNewline(%changeLogContents); + my $first = 1; open NEWLOG, ">$log.edit" or die; if (isGit() && scalar keys %changeLogSort == 0) { @@ -233,6 +236,7 @@ if (isGit() && scalar keys %changeLogSort == 0) { close CHANGELOG_ENTRIES; } } else { + print NEWLOG normalizeLineEndings($commonPrefix, $endl); for my $sortKey (sort keys %changeLogSort) { my $label = $changeLogSort{$sortKey}; if (keys %changeLogSort > 1) { @@ -273,3 +277,32 @@ sub normalizeLineEndings($$) $string =~ s/\r?\n/$endl/g; return $string; } + +sub removeLongestCommonPrefixEndingInDoubleNewline(\%) +{ + my ($hashOfStrings) = @_; + + my @strings = values %{$hashOfStrings}; + return "" unless @strings > 1; + + my $prefix = shift @strings; + my $prefixLength = length $prefix; + foreach my $string (@strings) { + while ($prefixLength) { + last if substr($string, 0, $prefixLength) eq $prefix; + --$prefixLength; + $prefix = substr($prefix, 0, -1); + } + last unless $prefixLength; + } + + return "" unless $prefixLength; + + my $lastDoubleNewline = rindex($prefix, "\n\n"); + return "" unless $lastDoubleNewline > 0; + + foreach my $key (keys %{$hashOfStrings}) { + $hashOfStrings->{$key} = substr($hashOfStrings->{$key}, $lastDoubleNewline); + } + return substr($prefix, 0, $lastDoubleNewline + 2); +} diff --git a/WebKitTools/Scripts/make-js-test-wrappers b/WebKitTools/Scripts/make-script-test-wrappers index a030d3b..133476c 100755 --- a/WebKitTools/Scripts/make-js-test-wrappers +++ b/WebKitTools/Scripts/make-script-test-wrappers @@ -62,7 +62,15 @@ my @templates = findTemplateFiles(@ARGV); for my $tfile (@templates) { my $tpath = $tfile; - $tpath =~ s:/resources/TEMPLATE.html$::; + my $templateDirectory; + my $templateRelativePath; + if ($tpath =~ s:/(script-tests)/TEMPLATE.html$::) { + $templateDirectory = $1; + $templateRelativePath = $1 . "/TEMPLATE.html"; + } else { + print "Inappropriate position of a template: ${tpath}\n"; + next; + } print "${tpath}\n"; @@ -73,64 +81,22 @@ for my $tfile (@templates) { my $fileFilter = sub { push @files, $File::Find::name if substr($_, -3) eq ".js"; }; - find({ preprocess => \&directoryFilter, wanted => $fileFilter }, "resources"); + find({ preprocess => \&directoryFilter, wanted => $fileFilter }, $templateDirectory); - open TEMPLATE, "<resources/TEMPLATE.html"; + open TEMPLATE, "<${templateRelativePath}"; my $template = do { local $/; <TEMPLATE> }; close TEMPLATE; my $templateNegative = $template; - if (-e "resources/TEMPLATE-n.html") { - open TEMPLATE, "<resources/TEMPLATE-n.html"; + if (-e "${templateDirectory}/TEMPLATE-n.html") { + open TEMPLATE, "<${templateDirectory}/TEMPLATE-n.html"; $templateNegative = do { local $/; <TEMPLATE> }; close TEMPLATE; } for my $file (@files) { - next if $file =~ /js-test-.*\.js$/; - next if $file =~ /cookies-test-(post|pre)\.js$/; - next if $file =~ /standalone-.*\.js$/; - next if $file =~ /SVGTestCase\.js/; - next if $file =~ /WMLTestCase\.js/; - - next if $file =~ m:resources/bom-in-file-retains-correct-offset\.js$:; # has a custom template - next if $file =~ m:resources/NSResolver-exceptions\.js$:; - next if $file =~ m:resources/WindowProperties\.js$:; - next if $file =~ m:resources/altGlyph-dom\.js$:; - next if $file =~ m:resources/attr-case-sensitivity\.js$:; - next if $file =~ m:resources/box-shadow-overflow-scroll\.js$:; - next if $file =~ m:resources/codegen-temporaries-multiple-global-blocks-1\.js$:; - next if $file =~ m:resources/codegen-temporaries-multiple-global-blocks-2\.js$:; - next if $file =~ m:resources/constructors-cached-navigate\.js$:; - next if $file =~ m:resources/frame-loading-via-document-write\.js$:; - next if $file =~ m:resources/id-fastpath-almost-strict\.js$:; - next if $file =~ m:resources/id-fastpath-strict\.js$:; - next if $file =~ m:resources/intersectsNode\.js$:; - next if $file =~ m:resources/p-in-scope\.js$:; - next if $file =~ m:resources/paste-blockquote-before-blockquote\.js$:; - next if $file =~ m:resources/reflection-overflow-scroll\.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/scripted-random\.js$:; - next if $file =~ m:resources/select-options-remove\.js$:; - next if $file =~ m:resources/shadow-offset\.js$:; - next if $file =~ m:resources/tabindex-focus-blur-all\.js$:; - next if $file =~ m:resources/use-instanceRoot-event-bubbling\.js$:; - next if $file =~ m:resources/use-instanceRoot-event-listeners\.js$:; - next if $file =~ m:resources/window-properties\.js$:; - next if $file =~ m:resources/wrapper-identity-base\.js$:; - next if $file =~ m:resources/xhtml-scripts\.js$:; - next if $file =~ m:resources/instanceof-operator-dummy-worker\.js$:; - next if $file =~ m:resources/json2-es5-compat\.js$:; - next if $file =~ m:resources/JSON-stringify\.js$:; - next if $file =~ m:resources/JSON-parse\.js$:; - next if $file =~ m:resources/textarea-input-event\.js$:; - my $html = $file; - $html =~ s:resources/(.*)\.js:$1.html:; + $html =~ s:${templateDirectory}/(.*)\.js:$1.html:; next if -f "$html-disabled"; system("grep -q 'successfullyParsed =' $file"); diff --git a/WebKitTools/Scripts/mark-bug-fixed b/WebKitTools/Scripts/mark-bug-fixed new file mode 100755 index 0000000..c7086c2 --- /dev/null +++ b/WebKitTools/Scripts/mark-bug-fixed @@ -0,0 +1,141 @@ +#!/usr/bin/env python + +# Copyright (C) 2009 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 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. + +# Mark a bug as fixed on bugs.webkit.org. + +import os +import re +import sys + +from optparse import OptionParser + +from modules.bugzilla import Bugzilla, parse_bug_id +from modules.comments import bug_comment_from_svn_revision +from modules.logging import error, log +from modules.scm import SCM, detect_scm_system + + +class MarkBugFixedTool: + def __init__(self): + self.bugs = Bugzilla() + self.cached_scm = None + self.option_parser = OptionParser(usage="usage: %prog [options] [rNNNNN]") + self.option_parser.add_option("-b", "--bug-id", action="store", type="string", dest="bug_id", help="Specify bug id if no URL is provided in the commit log.") + self.option_parser.add_option("-m", "--comment", action="store", type="string", dest="comment", help="Text to include in bug comment.") + self.option_parser.add_option("-o", "--open", action="store_true", default=False, dest="open_bug", help="Open bug in default web browser (Mac only).") + self.option_parser.add_option("-u", "--update-only", action="store_true", default=False, dest="update_only", help="Add comment to the bug, but do not close it.") + + def scm(self): + # Lazily initialize SCM to not error-out before command line parsing (or when running non-scm commands). + if not self.cached_scm: + original_cwd = os.path.abspath('.') + self.cached_scm = detect_scm_system(original_cwd) + return self.cached_scm + + def _fetch_commit_log(self, scm, svn_revision): + if not svn_revision: + return scm.last_svn_commit_log() + return scm.svn_commit_log(svn_revision) + + def _determine_bug_id_and_svn_revision(self, bug_id, svn_revision): + commit_log = self._fetch_commit_log(self.scm(), svn_revision) + + if not bug_id: + bug_id = parse_bug_id(commit_log) + + if not svn_revision: + match = re.search("^r(?P<svn_revision>\d+) \|", commit_log, re.MULTILINE) + if match: + svn_revision = match.group('svn_revision') + + if not bug_id or not svn_revision: + not_found = [] + if not bug_id: + not_found.append("bug id") + if not svn_revision: + not_found.append("svn revision") + error("Could not find %s on command-line or in %s." + % (" or ".join(not_found), "r%s" % svn_revision if svn_revision else "last commit")) + + return (bug_id, svn_revision) + + def _open_bug_in_web_browser(self, bug_id): + if sys.platform == "darwin": + SCM.run_command(["open", self.bugs.short_bug_url_for_bug_id(bug_id)]) + return + log("WARNING: -o|--open is only supported on Mac OS X.") + + def _prompt_user_for_correctness(self, bug_id, svn_revision): + answer = raw_input("Is this correct (y/N)? ") + if not re.match("^\s*y(es)?", answer, re.IGNORECASE): + exit(1) + + def main(self): + (options, args) = self.option_parser.parse_args(sys.argv[1:]) + + if len(args) > 1: + error("Only one revision may be specified.") + + bug_id = options.bug_id + + svn_revision = args[0] if len(args) == 1 else None + if svn_revision: + if re.match("^r[0-9]+$", svn_revision, re.IGNORECASE): + svn_revision = svn_revision[1:] + if not re.match("^[0-9]+$", svn_revision): + error("Invalid svn revision: '%s'" % svn_revision) + + needs_prompt = False + if not bug_id or not svn_revision: + needs_prompt = True + (bug_id, svn_revision) = self._determine_bug_id_and_svn_revision(bug_id, svn_revision) + + log("Bug: <%s> %s" % (self.bugs.short_bug_url_for_bug_id(bug_id), self.bugs.fetch_title_from_bug(bug_id))) + log("Revision: %s" % svn_revision) + + if options.open_bug: + self._open_bug_in_web_browser(bug_id) + + if needs_prompt: + self._prompt_user_for_correctness(bug_id, svn_revision) + + bug_comment = bug_comment_from_svn_revision(svn_revision) + if options.comment: + bug_comment = "%s\n\n%s" % (options.comment, bug_comment) + + if options.update_only: + log("Adding comment to Bug %s." % bug_id) + self.bugs.post_comment_to_bug(bug_id, bug_comment) + else: + log("Adding comment to Bug %s and marking as Resolved/Fixed." % bug_id) + self.bugs.close_bug_as_fixed(bug_id, bug_comment) + + +def main(): + tool = MarkBugFixedTool() + return tool.main() + +if __name__ == "__main__": + main() diff --git a/WebKitTools/Scripts/modules/bugzilla.py b/WebKitTools/Scripts/modules/bugzilla.py index 1eebe9d..daf3f19 100644 --- a/WebKitTools/Scripts/modules/bugzilla.py +++ b/WebKitTools/Scripts/modules/bugzilla.py @@ -92,10 +92,19 @@ def credentials_from_keychain(username=None): def is_mac_os_x(): return platform.mac_ver()[0] +def parse_bug_id(message): + match = re.search("http\://webkit\.org/b/(?P<bug_id>\d+)", message) + if match: + return match.group('bug_id') + match = re.search(Bugzilla.bug_server_regex + "show_bug\.cgi\?id=(?P<bug_id>\d+)", message) + if match: + return match.group('bug_id') + return None + # FIXME: This should not depend on git for config storage def read_config(key): # Need a way to read from svn too - config_process = subprocess.Popen("git config --get bugzilla." + key, stdout=subprocess.PIPE, shell=True) + config_process = subprocess.Popen("git config --get bugzilla.%s" % key, stdout=subprocess.PIPE, shell=True) value = config_process.communicate()[0] return_code = config_process.wait() @@ -119,6 +128,11 @@ def read_credentials(): def timestamp(): return datetime.now().strftime("%Y%m%d%H%M%S") + +class BugzillaError(Exception): + pass + + class Bugzilla: def __init__(self, dryrun=False, committers=CommitterList()): self.dryrun = dryrun @@ -137,13 +151,21 @@ class Bugzilla: def bug_url_for_bug_id(self, bug_id, xml=False): content_type = "&ctype=xml" if xml else "" return "%sshow_bug.cgi?id=%s%s" % (self.bug_server_url, bug_id, content_type) - + + def short_bug_url_for_bug_id(self, bug_id): + return "http://webkit.org/b/%s" % bug_id + def attachment_url_for_id(self, attachment_id, action="view"): action_param = "" if action and action != "view": - action_param = "&action=" + action + action_param = "&action=%s" % action return "%sattachment.cgi?id=%s%s" % (self.bug_server_url, attachment_id, action_param) + def _parse_attachment_flag(self, element, flag_name, attachment, result_key): + flag = element.find('flag', attrs={'name' : flag_name}) + if flag and flag['status'] == '+': + attachment[result_key] = flag['setter'] + def _parse_attachment_element(self, element, bug_id): attachment = {} attachment['bug_id'] = bug_id @@ -153,24 +175,13 @@ class Bugzilla: attachment['url'] = self.attachment_url_for_id(attachment['id']) attachment['name'] = unicode(element.find('desc').string) attachment['type'] = str(element.find('type').string) - - review_flag = element.find('flag', attrs={"name" : "review"}) - if review_flag and review_flag['status'] == '+': - reviewer_email = review_flag['setter'] - reviewer = self.committers.reviewer_by_bugzilla_email(reviewer_email) - attachment['reviewer'] = reviewer.full_name - - commit_queue_flag = element.find('flag', attrs={"name" : "commit-queue"}) - if commit_queue_flag and commit_queue_flag['status'] == '+': - committer_email = commit_queue_flag['setter'] - committer = self.committers.committer_by_bugzilla_email(committer_email) - attachment['commit-queue'] = committer.full_name - + self._parse_attachment_flag(element, 'review', attachment, 'reviewer_email') + self._parse_attachment_flag(element, 'commit-queue', attachment, 'committer_email') return attachment def fetch_attachments_from_bug(self, bug_id): bug_url = self.bug_url_for_bug_id(bug_id, xml=True) - log("Fetching: " + bug_url) + log("Fetching: %s" % bug_url) page = urllib2.urlopen(bug_url) soup = BeautifulSoup(page) @@ -181,6 +192,12 @@ class Bugzilla: attachments.append(attachment) return attachments + def fetch_title_from_bug(self, bug_id): + bug_url = self.bug_url_for_bug_id(bug_id, xml=True) + page = urllib2.urlopen(bug_url) + soup = BeautifulSoup(page) + return soup.find('short_desc').string + def fetch_patches_from_bug(self, bug_id): patches = [] for attachment in self.fetch_attachments_from_bug(bug_id): @@ -188,17 +205,45 @@ class Bugzilla: patches.append(attachment) return patches - def fetch_reviewed_patches_from_bug(self, bug_id): + # _view_source_link belongs in some sort of webkit_config.py module. + def _view_source_link(self, local_path): + return "http://trac.webkit.org/browser/trunk/%s" % local_path + + def _validate_setter_email(self, patch, result_key, lookup_function, rejection_function, reject_invalid_patches): + setter_email = patch.get(result_key + '_email') + if not setter_email: + return None + + committer = lookup_function(setter_email) + if committer: + patch[result_key] = committer.full_name + return patch[result_key] + + if reject_invalid_patches: + committer_list = "WebKitTools/Scripts/modules/committers.py" + failure_message = "%s does not have %s permissions according to %s." % (setter_email, result_key, self._view_source_link(committer_list)) + rejection_function(patch['id'], failure_message) + else: + log("Warning, attachment %s on bug %s has invalid %s (%s)", (patch['id'], patch['bug_id'], result_key, setter_email)) + return None + + def _validate_reviewer(self, patch, reject_invalid_patches): + return self._validate_setter_email(patch, 'reviewer', self.committers.reviewer_by_bugzilla_email, self.reject_patch_from_review_queue, reject_invalid_patches) + + def _validate_committer(self, patch, reject_invalid_patches): + return self._validate_setter_email(patch, 'committer', self.committers.committer_by_bugzilla_email, self.reject_patch_from_commit_queue, reject_invalid_patches) + + def fetch_reviewed_patches_from_bug(self, bug_id, reject_invalid_patches=False): reviewed_patches = [] for attachment in self.fetch_attachments_from_bug(bug_id): - if 'reviewer' in attachment and not attachment['is_obsolete']: + if self._validate_reviewer(attachment, reject_invalid_patches) and not attachment['is_obsolete']: reviewed_patches.append(attachment) return reviewed_patches - def fetch_commit_queue_patches_from_bug(self, bug_id): + def fetch_commit_queue_patches_from_bug(self, bug_id, reject_invalid_patches=False): commit_queue_patches = [] - for attachment in self.fetch_reviewed_patches_from_bug(bug_id): - if 'commit-queue' in attachment and not attachment['is_obsolete']: + for attachment in self.fetch_reviewed_patches_from_bug(bug_id, reject_invalid_patches): + if self._validate_committer(attachment, reject_invalid_patches) and not attachment['is_obsolete']: commit_queue_patches.append(attachment) return commit_queue_patches @@ -216,10 +261,10 @@ class Bugzilla: return bug_ids - def fetch_patches_from_commit_queue(self): + def fetch_patches_from_commit_queue(self, reject_invalid_patches=False): patches_to_land = [] for bug_id in self.fetch_bug_ids_from_commit_queue(): - patches = self.fetch_commit_queue_patches_from_bug(bug_id) + patches = self.fetch_commit_queue_patches_from_bug(bug_id, reject_invalid_patches) patches_to_land += patches return patches_to_land @@ -245,7 +290,7 @@ class Bugzilla: # If the resulting page has a title, and it contains the word "invalid" assume it's the login failure page. if match and re.search("Invalid", match.group(1), re.IGNORECASE): # FIXME: We could add the ability to try again on failure. - raise ScriptError("Bugzilla login failed: %s" % match.group(1)) + raise BugzillaError("Bugzilla login failed: %s" % match.group(1)) self.authenticated = True @@ -257,7 +302,7 @@ class Bugzilla: log(comment_text) return - self.browser.open(self.bug_server_url + "attachment.cgi?action=enter&bugid=" + bug_id) + self.browser.open("%sattachment.cgi?action=enter&bugid=%s" % (self.bug_server_url, bug_id)) self.browser.select_form(name="entryform") self.browser['description'] = description self.browser['ispatch'] = ("1",) @@ -287,7 +332,7 @@ class Bugzilla: if match: text_lines = BeautifulSoup(match.group('error_message')).findAll(text=True) error_message = "\n" + '\n'.join([" " + line.strip() for line in text_lines if line.strip()]) - raise ScriptError("Bug not created: %s" % error_message) + raise BugzillaError("Bug not created: %s" % error_message) def create_bug_with_patch(self, bug_title, bug_description, component, patch_file_object, patch_description, cc, mark_for_review=False): self.authenticate() @@ -304,7 +349,8 @@ class Bugzilla: if not component or component not in component_names: component = self.prompt_for_component(component_names) self.browser['component'] = [component] - self.browser['cc'] = cc + if cc: + self.browser['cc'] = cc self.browser['short_desc'] = bug_title if bug_description: log(bug_description) @@ -317,15 +363,23 @@ class Bugzilla: bug_id = self._check_create_bug_response(response.read()) log("Bug %s created." % bug_id) - log(self.bug_server_url + "show_bug.cgi?id=" + bug_id) + log("%sshow_bug.cgi?id=%s" % (self.bug_server_url, bug_id)) return bug_id - def clear_attachment_review_flag(self, attachment_id, additional_comment_text=None): + def _find_select_element_for_flag(self, flag_name): + # FIXME: This will break if we ever re-order attachment flags + if flag_name == "review": + return self.browser.find_control(type='select', nr=0) + if flag_name == "commit-queue": + return self.browser.find_control(type='select', nr=1) + raise Exception("Don't know how to find flag named \"%s\"" % flag_name) + + def clear_attachment_flags(self, attachment_id, additional_comment_text=None): self.authenticate() - comment_text = "Clearing review flag on attachment: %s" % attachment_id + comment_text = "Clearing flags on attachment: %s" % attachment_id if additional_comment_text: - comment_text += "\n\n" + additional_comment_text + comment_text += "\n\n%s" % additional_comment_text log(comment_text) if self.dryrun: @@ -334,9 +388,35 @@ class Bugzilla: self.browser.open(self.attachment_url_for_id(attachment_id, 'edit')) self.browser.select_form(nr=1) self.browser.set_value(comment_text, name='comment', nr=0) - self.browser.find_control(type='select', nr=0).value = ("X",) + self._find_select_element_for_flag('review').value = ("X",) + self._find_select_element_for_flag('commit-queue').value = ("X",) self.browser.submit() + # FIXME: We need a way to test this on a live bugzilla instance. + def _set_flag_on_attachment(self, attachment_id, flag_name, flag_value, comment_text, additional_comment_text): + self.authenticate() + + if additional_comment_text: + comment_text += "\n\n%s" % additional_comment_text + log(comment_text) + + if self.dryrun: + return + + self.browser.open(self.attachment_url_for_id(attachment_id, 'edit')) + self.browser.select_form(nr=1) + self.browser.set_value(comment_text, name='comment', nr=0) + self._find_select_element_for_flag(flag_name).value = (flag_value,) + self.browser.submit() + + def reject_patch_from_commit_queue(self, attachment_id, additional_comment_text=None): + comment_text = "Rejecting patch %s from commit-queue." % attachment_id + self._set_flag_on_attachment(attachment_id, 'commit-queue', '-', comment_text, additional_comment_text) + + def reject_patch_from_review_queue(self, attachment_id, additional_comment_text=None): + comment_text = "Rejecting patch %s from review queue." % attachment_id + self._set_flag_on_attachment(attachment_id, 'review', '-', comment_text, additional_comment_text) + def obsolete_attachment(self, attachment_id, comment_text = None): self.authenticate() @@ -349,7 +429,8 @@ class Bugzilla: self.browser.select_form(nr=1) self.browser.find_control('isobsolete').items[0].selected = True # Also clear any review flag (to remove it from review/commit queues) - self.browser.find_control(type='select', nr=0).value = ("X",) + self._find_select_element_for_flag('review').value = ("X",) + self._find_select_element_for_flag('commit-queue').value = ("X",) if comment_text: log(comment_text) # Bugzilla has two textareas named 'comment', one is somehow hidden. We want the first. @@ -385,3 +466,17 @@ class Bugzilla: self.browser['bug_status'] = ['RESOLVED'] self.browser['resolution'] = ['FIXED'] self.browser.submit() + + def reopen_bug(self, bug_id, comment_text): + self.authenticate() + + log("Re-opening bug %s" % bug_id) + log(comment_text) # Bugzilla requires a comment when re-opening a bug, so we know it will never be None. + if self.dryrun: + return + + self.browser.open(self.bug_url_for_bug_id(bug_id)) + self.browser.select_form(name="changeform") + self.browser['bug_status'] = ['REOPENED'] + self.browser['comment'] = comment_text + self.browser.submit() diff --git a/WebKitTools/Scripts/modules/bugzilla_unittest.py b/WebKitTools/Scripts/modules/bugzilla_unittest.py index 1e52140..f08031e 100644 --- a/WebKitTools/Scripts/modules/bugzilla_unittest.py +++ b/WebKitTools/Scripts/modules/bugzilla_unittest.py @@ -68,21 +68,21 @@ class BugzillaTest(unittest.TestCase): 'url' : "https://bugs.webkit.org/attachment.cgi?id=33721", 'name' : "Fixed whitespace issue", 'type' : "text/plain", - 'reviewer' : 'Test One', - 'commit-queue' : 'Test Two' + 'reviewer_email' : 'one@test.com', + 'committer_email' : 'two@test.com' } def test_attachment_parsing(self): - reviewer = Reviewer('Test One', 'one@test.com') - committer = Committer('Test Two', 'two@test.com') - committer_list = CommitterList(committers=[committer], reviewers=[reviewer]) - bugzilla = Bugzilla(committers=committer_list) + bugzilla = Bugzilla() soup = BeautifulSoup(self._example_attachment) attachment_element = soup.find("attachment") attachment = bugzilla._parse_attachment_element(attachment_element, self._expected_example_attachment_parsing['bug_id']) self.assertTrue(attachment) + # Make sure we aren't parsing more or less than we expect + self.assertEquals(attachment.keys(), self._expected_example_attachment_parsing.keys()) + for key, expected_value in self._expected_example_attachment_parsing.items(): self.assertEquals(attachment[key], expected_value, ("Failure for key: %s: Actual='%s' Expected='%s'" % (key, attachment[key], expected_value))) diff --git a/WebKitTools/Scripts/modules/buildbot.py b/WebKitTools/Scripts/modules/buildbot.py new file mode 100644 index 0000000..4478429 --- /dev/null +++ b/WebKitTools/Scripts/modules/buildbot.py @@ -0,0 +1,102 @@ +# Copyright (c) 2009, Google 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: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# WebKit's Python module for interacting with WebKit's buildbot + +import re +import urllib2 + +# Import WebKit-specific modules. +from modules.logging import log + +# WebKit includes a built copy of BeautifulSoup in Scripts/modules +# so this import should always succeed. +from .BeautifulSoup import BeautifulSoup + +class BuildBot: + def __init__(self, host="build.webkit.org"): + self.buildbot_host = host + self.buildbot_server_url = "http://%s/" % self.buildbot_host + + # If any of the Leopard build/test bots or the Windows builders are red we should not be landing patches. + # Other builders should be added to this list once they're known to be stable. + self.core_builder_names_regexps = [ 'Leopard', "Windows.*Build" ] + + # If WebKit's buildbot has an XMLRPC interface we could use, we could do something more sophisticated here. + # For now we just parse out the basics, enough to support basic questions like "is the tree green?" + def _parse_builder_status_from_row(self, status_row): + status_cells = status_row.findAll('td') + builder = {} + + name_link = status_cells[0].find('a') + builder['name'] = name_link.string + # We could generate the builder_url from the name in a future version of this code. + builder['builder_url'] = self.buildbot_server_url + name_link['href'] + + status_link = status_cells[1].find('a') + if not status_link: + # We failed to find a link in the first cell, just give up. + # This can happen if a builder is just-added, the first cell will just be "no build" + builder['is_green'] = False # Other parts of the code depend on is_green being present. + return builder + revision_string = status_link.string # Will be either a revision number or a build number + # If revision_string has non-digits assume it's not a revision number. + builder['built_revision'] = int(revision_string) if not re.match('\D', revision_string) else None + builder['is_green'] = not re.search('fail', status_cells[1].renderContents()) + # We could parse out the build number instead, but for now just store the URL. + builder['build_url'] = self.buildbot_server_url + status_link['href'] + + # We could parse out the current activity too. + + return builder + + def _builder_statuses_with_names_matching_regexps(self, builder_statuses, name_regexps): + builders = [] + for builder in builder_statuses: + for name_regexp in name_regexps: + if re.match(name_regexp, builder['name']): + builders.append(builder) + return builders + + def core_builders_are_green(self): + for builder in self._builder_statuses_with_names_matching_regexps(self.builder_statuses(), self.core_builder_names_regexps): + if not builder['is_green']: + return False + return True + + def builder_statuses(self): + build_status_url = self.buildbot_server_url + 'one_box_per_builder' + page = urllib2.urlopen(build_status_url) + soup = BeautifulSoup(page) + + builders = [] + status_table = soup.find('table') + for status_row in status_table.findAll('tr'): + builder = self._parse_builder_status_from_row(status_row) + builders.append(builder) + return builders diff --git a/WebKitTools/Scripts/modules/buildbot_unittest.py b/WebKitTools/Scripts/modules/buildbot_unittest.py new file mode 100644 index 0000000..461e5a2 --- /dev/null +++ b/WebKitTools/Scripts/modules/buildbot_unittest.py @@ -0,0 +1,118 @@ +# Copyright (C) 2009 Google 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: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import unittest + +from modules.buildbot import BuildBot + +from modules.BeautifulSoup import BeautifulSoup + +class BuildBotTest(unittest.TestCase): + + _example_one_box_status = ''' + <table> + <tr> + <td class="box"><a href="builders/Windows%20Debug%20%28Tests%29">Windows Debug (Tests)</a></td> + <td align="center" class="LastBuild box success"><a href="builders/Windows%20Debug%20%28Tests%29/builds/3693">47380</a><br />build<br />successful</td> + <td align="center" class="Activity building">building<br />ETA in<br />~ 14 mins<br />at 13:40</td> + <tr> + <td class="box"><a href="builders/SnowLeopard%20Intel%20Release">SnowLeopard Intel Release</a></td> + <td class="LastBuild box" >no build</td> + <td align="center" class="Activity building">building<br />< 1 min</td> + <tr> + <td class="box"><a href="builders/Qt%20Linux%20Release">Qt Linux Release</a></td> + <td align="center" class="LastBuild box failure"><a href="builders/Qt%20Linux%20Release/builds/654">47383</a><br />failed<br />compile-webkit</td> + <td align="center" class="Activity idle">idle</td> + </table> +''' + _expected_example_one_box_parsings = [ + { + 'builder_url': u'http://build.webkit.org/builders/Windows%20Debug%20%28Tests%29', + 'build_url': u'http://build.webkit.org/builders/Windows%20Debug%20%28Tests%29/builds/3693', + 'is_green': True, + 'name': u'Windows Debug (Tests)', + 'built_revision': 47380 + }, + { + 'builder_url': u'http://build.webkit.org/builders/SnowLeopard%20Intel%20Release', + 'is_green': False, + 'name': u'SnowLeopard Intel Release', + }, + { + 'builder_url': u'http://build.webkit.org/builders/Qt%20Linux%20Release', + 'build_url': u'http://build.webkit.org/builders/Qt%20Linux%20Release/builds/654', + 'is_green': False, + 'name': u'Qt Linux Release', + 'built_revision': 47383 + }, + ] + + def test_status_parsing(self): + buildbot = BuildBot() + + soup = BeautifulSoup(self._example_one_box_status) + status_table = soup.find("table") + input_rows = status_table.findAll('tr') + + for x in range(len(input_rows)): + status_row = input_rows[x] + expected_parsing = self._expected_example_one_box_parsings[x] + + builder = buildbot._parse_builder_status_from_row(status_row) + + # Make sure we aren't parsing more or less than we expect + self.assertEquals(builder.keys(), expected_parsing.keys()) + + for key, expected_value in expected_parsing.items(): + self.assertEquals(builder[key], expected_value, ("Builder %d parse failure for key: %s: Actual='%s' Expected='%s'" % (x, key, builder[key], expected_value))) + + def test_builder_name_regexps(self): + buildbot = BuildBot() + + example_builders = [ + { 'name': u'Leopard Debug (Build)', }, + { 'name': u'Leopard Debug (Tests)', }, + { 'name': u'Windows Release (Build)', }, + { 'name': u'Windows Debug (Tests)', }, + { 'name': u'Qt Linux Release', }, + ] + name_regexps = [ 'Leopard', "Windows.*Build" ] + expected_builders = [ + { 'name': u'Leopard Debug (Build)', }, + { 'name': u'Leopard Debug (Tests)', }, + { 'name': u'Windows Release (Build)', }, + ] + + # This test should probably be updated if the default regexp list changes + self.assertEquals(buildbot.core_builder_names_regexps, name_regexps) + + builders = buildbot._builder_statuses_with_names_matching_regexps(example_builders, name_regexps) + self.assertEquals(builders, expected_builders) + +if __name__ == '__main__': + unittest.main() diff --git a/WebKitTools/Scripts/modules/changelogs.py b/WebKitTools/Scripts/modules/changelogs.py new file mode 100644 index 0000000..a407d23 --- /dev/null +++ b/WebKitTools/Scripts/modules/changelogs.py @@ -0,0 +1,92 @@ +# Copyright (C) 2009, Google 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: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# WebKit's Python module for parsing and modifying ChangeLog files + +import fileinput # inplace file editing for set_reviewer_in_changelog +import re + +# FIMXE: This doesn't really belong in this file, but we don't have a better home for it yet. +# Maybe eventually a webkit_config.py? +def view_source_url(revision_number): + return "http://trac.webkit.org/changeset/%s" % revision_number + + +class ChangeLog: + def __init__(self, path): + self.path = path + + # e.g. 2009-06-03 Eric Seidel <eric@webkit.org> + date_line_regexp = re.compile('^(\d{4}-\d{2}-\d{2})' # Consume the date. + + '\s+(.+)\s+' # Consume the name. + + '<([^<>]+)>$') # And finally the email address. + + @staticmethod + def _parse_latest_entry_from_file(changelog_file): + entry_lines = [] + # The first line should be a date line. + first_line = changelog_file.readline() + if not ChangeLog.date_line_regexp.match(first_line): + return None + entry_lines.append(first_line) + + for line in changelog_file: + # If we've hit the next entry, return. + if ChangeLog.date_line_regexp.match(line): + return ''.join(entry_lines[:-1]) # Remove the extra newline at the end + entry_lines.append(line) + return None # We never found a date line! + + def latest_entry(self): + changelog_file = open(self.path) + try: + return self._parse_latest_entry_from_file(changelog_file) + finally: + changelog_file.close() + + def update_for_revert(self, revision): + reviewed_by_regexp = re.compile('Reviewed by NOBODY \(OOPS!\)\.') + removing_boilerplate = False + # inplace=1 creates a backup file and re-directs stdout to the file + for line in fileinput.FileInput(self.path, inplace=1): + if reviewed_by_regexp.search(line): + print reviewed_by_regexp.sub("No review, rolling out r%s." % revision, line), + print " %s\n" % view_source_url(revision) + # Remove all the ChangeLog boilerplate between the Reviewed by line and the first changed file. + removing_boilerplate = True + elif removing_boilerplate: + if line.find('*') >= 0 : # each changed file is preceded by a * + removing_boilerplate = False + + if not removing_boilerplate: + print line, + + def set_reviewer(self, reviewer): + # inplace=1 creates a backup file and re-directs stdout to the file + for line in fileinput.FileInput(self.path, inplace=1): + print line.replace("NOBODY (OOPS!)", reviewer.encode("utf-8")), # Trailing comma suppresses printing newline diff --git a/WebKitTools/Scripts/modules/changelogs_unittest.py b/WebKitTools/Scripts/modules/changelogs_unittest.py new file mode 100644 index 0000000..dd14cb7 --- /dev/null +++ b/WebKitTools/Scripts/modules/changelogs_unittest.py @@ -0,0 +1,145 @@ +# Copyright (C) 2009 Google 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: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import unittest +from changelogs import * + +import os +import tempfile +from StringIO import StringIO + +class ChangeLogsTest(unittest.TestCase): + + _example_entry = '''2009-08-17 Peter Kasting <pkasting@google.com> + + Reviewed by Steve Falkenburg. + + https://bugs.webkit.org/show_bug.cgi?id=27323 + Only add Cygwin to the path when it isn't already there. This avoids + causing problems for people who purposefully have non-Cygwin versions of + executables like svn in front of the Cygwin ones in their paths. + + * DumpRenderTree/win/DumpRenderTree.vcproj: + * DumpRenderTree/win/ImageDiff.vcproj: + * DumpRenderTree/win/TestNetscapePlugin/TestNetscapePlugin.vcproj: +''' + + # More example text than we need. Eventually we need to support parsing this all and write tests for the parsing. + _example_changelog = '''2009-08-17 David Kilzer <ddkilzer@apple.com> + + <http://webkit.org/b/28393> check-webkit-style: add check for use of std::max()/std::min() instead of MAX()/MIN() + + Reviewed by David Levin. + + * Scripts/modules/cpp_style.py: + (_ERROR_CATEGORIES): Added 'runtime/max_min_macros'. + (check_max_min_macros): Added. Returns level 4 error when MAX() + and MIN() macros are used in header files and C++ source files. + (check_style): Added call to check_max_min_macros(). + * Scripts/modules/cpp_style_unittest.py: Added unit tests. + (test_max_macro): Added. + (test_min_macro): Added. + +2009-08-16 David Kilzer <ddkilzer@apple.com> + + Backed out r47343 which was mistakenly committed + + * Scripts/bugzilla-tool: + * Scripts/modules/scm.py: + +2009-06-18 Darin Adler <darin@apple.com> + + Rubber stamped by Mark Rowe. + + * DumpRenderTree/mac/DumpRenderTreeWindow.mm: + (-[DumpRenderTreeWindow close]): Resolved crashes seen during regression + tests. The close method can be called on a window that's already closed + so we can't assert here. + +== Rolled over to ChangeLog-2009-06-16 == +''' + + def test_latest_entry_parse(self): + changelog_contents = "%s\n%s" % (self._example_entry, self._example_changelog) + changelog_file = StringIO(changelog_contents) + latest_entry = ChangeLog._parse_latest_entry_from_file(changelog_file) + self.assertEquals(self._example_entry, latest_entry) + + @staticmethod + def _write_tmp_file_with_contents(contents): + (file_descriptor, file_path) = tempfile.mkstemp() # NamedTemporaryFile always deletes the file on close in python < 2.6 + file = os.fdopen(file_descriptor, 'w') + file.write(contents) + file.close() + return file_path + + @staticmethod + def _read_file_contents(file_path): + file = open(file_path) + contents = file.read() + file.close() + return contents + + _new_entry_boilerplate = '''2009-08-19 Eric Seidel <eric@webkit.org> + + Reviewed by NOBODY (OOPS!). + + Need a short description and bug URL (OOPS!) + + * Scripts/bugzilla-tool: +''' + + def test_set_reviewer(self): + changelog_contents = "%s\n%s" % (self._new_entry_boilerplate, self._example_changelog) + changelog_path = self._write_tmp_file_with_contents(changelog_contents) + reviewer_name = 'Test Reviewer' + ChangeLog(changelog_path).set_reviewer(reviewer_name) + actual_contents = self._read_file_contents(changelog_path) + expected_contents = changelog_contents.replace('NOBODY (OOPS!)', reviewer_name) + os.remove(changelog_path) + self.assertEquals(actual_contents, expected_contents) + + _expected_revert_entry = '''2009-08-19 Eric Seidel <eric@webkit.org> + + No review, rolling out r12345. + http://trac.webkit.org/changeset/12345 + + * Scripts/bugzilla-tool: +''' + + def test_update_for_revert(self): + changelog_contents = "%s\n%s" % (self._new_entry_boilerplate, self._example_changelog) + changelog_path = self._write_tmp_file_with_contents(changelog_contents) + changelog = ChangeLog(changelog_path) + changelog.update_for_revert(12345) + actual_entry = changelog.latest_entry() + os.remove(changelog_path) + self.assertEquals(actual_entry, self._expected_revert_entry) + +if __name__ == '__main__': + unittest.main() diff --git a/WebKitTools/Scripts/modules/comments.py b/WebKitTools/Scripts/modules/comments.py new file mode 100755 index 0000000..eeee655 --- /dev/null +++ b/WebKitTools/Scripts/modules/comments.py @@ -0,0 +1,39 @@ +# Copyright (c) 2009, Google Inc. All rights reserved. +# Copyright (c) 2009 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: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# A tool for automating dealing with bugzilla, posting patches, committing patches, etc. + +from modules.changelogs import view_source_url + +def bug_comment_from_svn_revision(svn_revision): + return "Committed r%s: <%s>" % (svn_revision, view_source_url(svn_revision)) + +def bug_comment_from_commit_text(scm, commit_text): + svn_revision = scm.svn_revision_from_commit_text(commit_text) + return bug_comment_from_svn_revision(svn_revision) diff --git a/WebKitTools/Scripts/modules/committers.py b/WebKitTools/Scripts/modules/committers.py index 6a7f436..e157fb4 100644 --- a/WebKitTools/Scripts/modules/committers.py +++ b/WebKitTools/Scripts/modules/committers.py @@ -45,13 +45,43 @@ class Reviewer(Committer): # All reviewers are committers, so this list is only of committers # who are not reviewers. committers_unable_to_review = [ + Committer("Aaron Boodman", "aa@chromium.org"), + Committer("Adam Langley", "agl@chromium.org"), Committer("Albert J. Wong", "ajwong@chromium.org"), + Committer("Antonio Gomes", "tonikitoo@webkit.org"), + Committer("Anthony Ricaud", "rik@webkit.org"), Committer("Ben Murdoch", "benm@google.com"), + Committer("Brent Fulgham", "bfulgham@webkit.org"), + Committer("Brian Weinstein", "bweinstein@apple.com"), + Committer("Cameron McCormack", "cam@webkit.org"), + Committer("Daniel Bates", "dbates@webkit.org"), + Committer("Drew Wilson", "atwilson@chromium.org"), + Committer("Dirk Schulze", "krit@webkit.org"), + Committer("Dmitry Titov", "dimich@chromium.org"), + Committer("Eli Fidler", "eli@staikos.net"), + Committer("Eric Roman", "eroman@chromium.org"), + Committer("Fumitoshi Ukai", "ukai@chromium.org"), + Committer("Greg Bolsinga", "bolsinga@apple.com"), + Committer("Jeremy Moskovich", "playmobil@google.com"), Committer("Jeremy Orlow", "jorlow@chromium.org"), + Committer("Jian Li", "jianli@chromium.org"), + Committer("John Abd-El-Malek", "jam@chromium.org"), + Committer("Joseph Pecoraro", "joepeck@webkit.org"), + Committer("Julie Parent", "jparent@google.com"), + Committer("Kenneth Rohde Christiansen", "kenneth@webkit.org"), + Committer("Laszlo Gombos", "laszlo.1.gombos@nokia.com"), + Committer("Nate Chapin", "japhet@chromium.org"), + Committer("Ojan Vafai", "ojan@chromium.org"), + Committer("Pam Greene", "pam@chromium.org"), Committer("Peter Kasting", "pkasting@google.com"), Committer("Pierre d'Herbemont", "pdherbemont@free.fr"), - Committer("Shinichiro Hamaji", "hamaji@google.com"), - Committer("Zoltan Horvath", "hzoltan@inf.u-szeged.hu"), + Committer("Ryosuke Niwa", "rniwa@webkit.org"), + Committer("Scott Violet", "sky@chromium.org"), + Committer("Shinichiro Hamaji", "hamaji@chromium.org"), + Committer("Tony Chang", "tony@chromium.org"), + Committer("Yael Aharon", "yael.aharon@nokia.com"), + Committer("Yong Li", "yong.li@torchmobile.com"), + Committer("Zoltan Horvath", "zoltan@webkit.org"), ] reviewers_list = [ @@ -71,12 +101,15 @@ reviewers_list = [ Reviewer("David Kilzer", "ddkilzer@webkit.org"), Reviewer("David Levin", "levin@chromium.org"), Reviewer("Dimitri Glazkov", "dglazkov@chromium.org"), + Reviewer("Eric Carlson", "eric.carlson@apple.com"), Reviewer("Eric Seidel", "eric@webkit.org"), Reviewer("Gavin Barraclough", "barraclough@apple.com"), + Reviewer("Geoffrey Garen", "ggaren@apple.com"), Reviewer("George Staikos", "staikos@kde.org"), Reviewer("Gustavo Noronha", "gns@gnome.org"), Reviewer("Holger Freyther", "zecke@selfish.org"), Reviewer("Jan Alonzo", "jmalonzo@gmail.com"), + Reviewer("John Sullivan", "sullivan@apple.com"), Reviewer("Justin Garcia", "justin.garcia@apple.com"), Reviewer("Kevin McCullough", "kmccullough@apple.com"), Reviewer("Kevin Ollivier", "kevino@theolliviers.com"), @@ -111,13 +144,10 @@ class CommitterList: return self._committers_by_email def committer_by_bugzilla_email(self, bugzilla_email): - committer = self._email_to_committer_map().get(bugzilla_email) - if not committer: - raise Exception("Unknown committer: %s" % bugzilla_email) - return committer + return self._email_to_committer_map().get(bugzilla_email) def reviewer_by_bugzilla_email(self, bugzilla_email): committer = self.committer_by_bugzilla_email(bugzilla_email) - if not committer.can_review: - raise Exception("Committer %s does not have review rights." % committer) + if committer and not committer.can_review: + return None return committer diff --git a/WebKitTools/Scripts/modules/commiters_unittest.py b/WebKitTools/Scripts/modules/committers_unittest.py index d221c8b..045e20e 100644 --- a/WebKitTools/Scripts/modules/commiters_unittest.py +++ b/WebKitTools/Scripts/modules/committers_unittest.py @@ -42,11 +42,11 @@ class CommittersTest(unittest.TestCase): self.assertEqual(committer_list.committer_by_bugzilla_email('two@test.com'), reviewer) # Test that a known committer is not returned during reviewer lookup - self.assertRaises(Exception, committer_list.reviewer_by_bugzilla_email, 'one@test.com') + self.assertEqual(committer_list.reviewer_by_bugzilla_email('one@test.com'), None) # Test that unknown email address fail both committer and reviewer lookup - self.assertRaises(Exception, committer_list.committer_by_bugzilla_email, 'bar@bar.com') - self.assertRaises(Exception, committer_list.reviewer_by_bugzilla_email, 'bar@bar.com') + self.assertEqual(committer_list.committer_by_bugzilla_email('bar@bar.com'), None) + self.assertEqual(committer_list.reviewer_by_bugzilla_email('bar@bar.com'), None) if __name__ == '__main__': unittest.main() diff --git a/WebKitTools/Scripts/modules/cpp_style.py b/WebKitTools/Scripts/modules/cpp_style.py index 86c0401..0c9dfa0 100644 --- a/WebKitTools/Scripts/modules/cpp_style.py +++ b/WebKitTools/Scripts/modules/cpp_style.py @@ -3,6 +3,7 @@ # # Copyright (C) 2009 Google Inc. All rights reserved. # Copyright (C) 2009 Torch Mobile Inc. +# Copyright (C) 2009 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 @@ -117,6 +118,7 @@ _ERROR_CATEGORIES = '''\ build/namespaces build/printf_format build/storage_class + build/using_std legal/copyright readability/braces readability/casting @@ -138,6 +140,7 @@ _ERROR_CATEGORIES = '''\ runtime/int runtime/init runtime/invalid_increment + runtime/max_min_macros runtime/memset runtime/printf runtime/printf_format @@ -1545,7 +1548,7 @@ def check_spacing(filename, clean_lines, line_number, error): # Alas, we can't test < or > because they're legitimately used sans spaces # (a->b, vector<int> a). The only time we can tell is a < with no >, and # only if it's not template params list spilling into the next line. - matched = search(r'[^<>=!\s](==|!=|<=|>=)[^<>=!\s]', line) + matched = search(r'[^<>=!\s](==|!=|\+=|-=|\*=|/=|/|\|=|&=|<<=|>>=|<=|>=|\|\||\||&&|>>|<<)[^<>=!\s]', line) if not matched: # Note that while it seems that the '<[^<]*' term in the following # regexp could be simplified to '<.*', which would indeed match @@ -1558,7 +1561,7 @@ def check_spacing(filename, clean_lines, line_number, error): 'Missing spaces around %s' % matched.group(1)) # We allow no-spaces around << and >> when used like this: 10<<20, but # not otherwise (particularly, not when used as streams) - matched = search(r'[^0-9\s](<<|>>)[^0-9\s]', line) + matched = search(r'[^0-9\s](<<|>>)[^0-9\s=]', line) if matched: error(filename, line_number, 'whitespace/operators', 3, 'Missing spaces around %s' % matched.group(1)) @@ -1741,6 +1744,58 @@ def check_namespace_indentation(filename, clean_lines, line_number, file_extensi break +def check_using_std(filename, clean_lines, line_number, error): + """Looks for 'using std::foo;' statements which should be replaced with 'using namespace std;'. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + line_number: The number of the line to check. + error: The function to call with any errors found. + """ + + # This check doesn't apply to C or Objective-C implementation files. + if filename.endswith('.c') or filename.endswith('.m'): + return + + line = clean_lines.elided[line_number] # Get rid of comments and strings. + + using_std_match = match(r'\s*using\s+std::(?P<method_name>\S+)\s*;\s*$', line) + if not using_std_match: + return + + method_name = using_std_match.group('method_name') + error(filename, line_number, 'build/using_std', 4, + "Use 'using namespace std;' instead of 'using std::%s;'." % method_name) + + +def check_max_min_macros(filename, clean_lines, line_number, error): + """Looks use of MAX() and MIN() macros that should be replaced with std::max() and std::min(). + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + line_number: The number of the line to check. + error: The function to call with any errors found. + """ + + # This check doesn't apply to C or Objective-C implementation files. + if filename.endswith('.c') or filename.endswith('.m'): + return + + line = clean_lines.elided[line_number] # Get rid of comments and strings. + + max_min_macros_search = search(r'\b(?P<max_min_macro>(MAX|MIN))\s*\(', line) + if not max_min_macros_search: + return + + max_min_macro = max_min_macros_search.group('max_min_macro') + max_min_macro_lower = max_min_macro.lower() + error(filename, line_number, 'runtime/max_min_macros', 4, + 'Use std::%s() or std::%s<type>() instead of the %s() macro.' + % (max_min_macro_lower, max_min_macro_lower, max_min_macro)) + + def check_switch_indentation(filename, clean_lines, line_number, error): """Looks for indentation errors inside of switch statements. @@ -2174,6 +2229,8 @@ def check_style(filename, clean_lines, line_number, file_extension, error): # Some more style checks check_namespace_indentation(filename, clean_lines, line_number, file_extension, error) + check_using_std(filename, clean_lines, line_number, error) + check_max_min_macros(filename, clean_lines, line_number, error) check_switch_indentation(filename, clean_lines, line_number, error) check_braces(filename, clean_lines, line_number, error) check_exit_statement_simplifications(filename, clean_lines, line_number, error) @@ -3087,6 +3144,7 @@ def use_webkit_styles(): # modify the implementation and enable them. global _DEFAULT_FILTERS _DEFAULT_FILTERS = [ + '-whitespace/end_of_line', '-whitespace/comments', '-whitespace/blank_line', '-runtime/explicit', # explicit diff --git a/WebKitTools/Scripts/modules/cpp_style_unittest.py b/WebKitTools/Scripts/modules/cpp_style_unittest.py index ad01fc3..322356e 100644 --- a/WebKitTools/Scripts/modules/cpp_style_unittest.py +++ b/WebKitTools/Scripts/modules/cpp_style_unittest.py @@ -3,6 +3,7 @@ # # Copyright (C) 2009 Google Inc. All rights reserved. # Copyright (C) 2009 Torch Mobile Inc. +# Copyright (C) 2009 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 @@ -950,7 +951,7 @@ class CppStyleTest(CppStyleTestBase): self.assert_lint('int a[sizeof(struct Foo)];', '') self.assert_lint('int a[128 - sizeof(const bar)];', '') self.assert_lint('int a[(sizeof(foo) * 4)];', '') - self.assert_lint('int a[(arraysize(fixed_size_array)/2) << 1];', '') + self.assert_lint('int a[(arraysize(fixed_size_array)/2) << 1];', 'Missing spaces around / [whitespace/operators] [3]') self.assert_lint('delete a[some_var];', '') self.assert_lint('return a[some_var];', '') @@ -1208,6 +1209,62 @@ class CppStyleTest(CppStyleTestBase): self.assert_lint('typedef hash_map<Foo, Bar', 'Missing spaces around <' ' [whitespace/operators] [3]') self.assert_lint('typedef hash_map<FoooooType, BaaaaarType,', '') + self.assert_lint('a<Foo> t+=b;', 'Missing spaces around +=' + ' [whitespace/operators] [3]') + self.assert_lint('a<Foo> t-=b;', 'Missing spaces around -=' + ' [whitespace/operators] [3]') + self.assert_lint('a<Foo*> t*=b;', 'Missing spaces around *=' + ' [whitespace/operators] [3]') + self.assert_lint('a<Foo*> t/=b;', 'Missing spaces around /=' + ' [whitespace/operators] [3]') + self.assert_lint('a<Foo*> t|=b;', 'Missing spaces around |=' + ' [whitespace/operators] [3]') + self.assert_lint('a<Foo*> t&=b;', 'Missing spaces around &=' + ' [whitespace/operators] [3]') + self.assert_lint('a<Foo*> t<<=b;', 'Missing spaces around <<=' + ' [whitespace/operators] [3]') + self.assert_lint('a<Foo*> t>>=b;', 'Missing spaces around >>=' + ' [whitespace/operators] [3]') + self.assert_lint('a<Foo*> t>>=&b|c;', 'Missing spaces around >>=' + ' [whitespace/operators] [3]') + self.assert_lint('a<Foo*> t<<=*b/c;', 'Missing spaces around <<=' + ' [whitespace/operators] [3]') + self.assert_lint('a<Foo> t -= b;', '') + self.assert_lint('a<Foo> t += b;', '') + self.assert_lint('a<Foo*> t *= b;', '') + self.assert_lint('a<Foo*> t /= b;', '') + self.assert_lint('a<Foo*> t |= b;', '') + self.assert_lint('a<Foo*> t &= b;', '') + self.assert_lint('a<Foo*> t <<= b;', '') + self.assert_lint('a<Foo*> t >>= b;', '') + self.assert_lint('a<Foo*> t >>= &b|c;', 'Missing spaces around |' + ' [whitespace/operators] [3]') + self.assert_lint('a<Foo*> t <<= *b/c;', 'Missing spaces around /' + ' [whitespace/operators] [3]') + self.assert_lint('a<Foo*> t <<= b/c; //Test', ['At least two spaces' + ' is best between code and comments [whitespace/' + 'comments] [2]', 'Should have a space between // ' + 'and comment [whitespace/comments] [4]', 'Missing' + ' spaces around / [whitespace/operators] [3]']) + self.assert_lint('a<Foo*> t <<= b||c; //Test', ['Should have a space' + ' between // and comment [whitespace/comments] [4]', + 'Missing spaces around || [whitespace/operators] [3]']) + self.assert_lint('a<Foo*> t <<= b&&c; // Test', 'Missing spaces around' + ' && [whitespace/operators] [3]') + self.assert_lint('a<Foo*> t <<= b&&&c; // Test', 'Missing spaces around' + ' && [whitespace/operators] [3]') + self.assert_lint('a<Foo*> t <<= b&&*c; // Test', 'Missing spaces around' + ' && [whitespace/operators] [3]') + self.assert_lint('a<Foo*> t <<= b && *c; // Test', '') + self.assert_lint('a<Foo*> t <<= b && &c; // Test', '') + self.assert_lint('a<Foo*> t <<= b || &c; /*Test', 'Complex multi-line ' + '/*...*/-style comment found. Lint may give bogus ' + 'warnings. Consider replacing these with //-style' + ' comments, with #if 0...#endif, or with more clearly' + ' structured multi-line comments. [readability/multiline_comment] [5]') + self.assert_lint('a<Foo&> t <<= &b | &c;', '') + self.assert_lint('a<Foo*> t <<= &b & &c; // Test', '') + self.assert_lint('a<Foo*> t <<= *b / &c; // Test', '') def test_spacing_before_last_semicolon(self): self.assert_lint('call_function() ;', @@ -2959,7 +3016,7 @@ class WebKitStyleTest(CppStyleTestBase): 'Missing space after , [whitespace/comma] [3]') self.assert_multi_line_lint( 'c = a|b;', - '') + 'Missing spaces around | [whitespace/operators] [3]') # FIXME: We cannot catch this lint error. # self.assert_multi_line_lint( # 'return condition ? 1:0;', @@ -3425,6 +3482,49 @@ class WebKitStyleTest(CppStyleTestBase): 'if (othertrue == fontType)', '') + def test_using_std(self): + self.assert_lint( + 'using std::min;', + "Use 'using namespace std;' instead of 'using std::min;'." + " [build/using_std] [4]", + 'foo.cpp') + + def test_max_macro(self): + self.assert_lint( + 'int i = MAX(0, 1);', + '', + 'foo.c') + + self.assert_lint( + 'int i = MAX(0, 1);', + 'Use std::max() or std::max<type>() instead of the MAX() macro.' + ' [runtime/max_min_macros] [4]', + 'foo.cpp') + + self.assert_lint( + 'inline int foo() { return MAX(0, 1); }', + 'Use std::max() or std::max<type>() instead of the MAX() macro.' + ' [runtime/max_min_macros] [4]', + 'foo.h') + + def test_min_macro(self): + self.assert_lint( + 'int i = MIN(0, 1);', + '', + 'foo.c') + + self.assert_lint( + 'int i = MIN(0, 1);', + 'Use std::min() or std::min<type>() instead of the MIN() macro.' + ' [runtime/max_min_macros] [4]', + 'foo.cpp') + + self.assert_lint( + 'inline int foo() { return MIN(0, 1); }', + 'Use std::min() or std::min<type>() instead of the MIN() macro.' + ' [runtime/max_min_macros] [4]', + 'foo.h') + def test_names(self): # FIXME: Implement this. pass diff --git a/WebKitTools/Scripts/modules/logging.py b/WebKitTools/Scripts/modules/logging.py index ea03a48..cbccacf 100644 --- a/WebKitTools/Scripts/modules/logging.py +++ b/WebKitTools/Scripts/modules/logging.py @@ -35,5 +35,14 @@ def log(string): print >> sys.stderr, string def error(string): - log("ERROR: " + string) + log("ERROR: %s" % string) exit(1) + +# Simple class to split output between multiple destinations +class tee: + def __init__(self, *files): + self.files = files + + def write(self, string): + for file in self.files: + file.write(string) diff --git a/WebKitTools/Scripts/modules/logging_unittest.py b/WebKitTools/Scripts/modules/logging_unittest.py new file mode 100644 index 0000000..7d41e56 --- /dev/null +++ b/WebKitTools/Scripts/modules/logging_unittest.py @@ -0,0 +1,61 @@ +# Copyright (C) 2009 Google 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: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import os +import subprocess +import StringIO +import tempfile +import unittest + +from modules.logging import * +from modules.scm import ScriptError + +class LoggingTest(unittest.TestCase): + + def assert_log_equals(self, log_input, expected_output): + original_stderr = sys.stderr + test_stderr = StringIO.StringIO() + sys.stderr = test_stderr + + try: + log(log_input) + actual_output = test_stderr.getvalue() + finally: + original_stderr = original_stderr + + self.assertEquals(actual_output, expected_output, "log(\"%s\") expected: %s actual: %s" % (log_input, expected_output, actual_output)) + + def test_log(self): + self.assert_log_equals("test", "test\n") + + # Test that log() does not throw an exception when passed an object instead of a string. + self.assert_log_equals(ScriptError(message="ScriptError"), "ScriptError\n") + + +if __name__ == '__main__': + unittest.main() diff --git a/WebKitTools/Scripts/modules/scm.py b/WebKitTools/Scripts/modules/scm.py index ec1f362..3daecbc 100644 --- a/WebKitTools/Scripts/modules/scm.py +++ b/WebKitTools/Scripts/modules/scm.py @@ -78,8 +78,43 @@ class CommitMessage: class ScriptError(Exception): - pass + def __init__(self, message=None, script_args=None, exit_code=None, output=None, cwd=None): + if not message: + message = 'Failed to run "%s"' % script_args + if exit_code: + message += " exit_code: %d" % exit_code + if cwd: + message += " cwd: %s" % cwd + + Exception.__init__(self, message) + self.script_args = script_args # 'args' is already used by Exception + self.exit_code = exit_code + self.output = output + self.cwd = cwd + + def message_with_output(self, output_limit=500): + if self.output: + if len(self.output) > output_limit: + return "%s\nLast %s characters of output:\n%s" % (self, output_limit, self.output[-output_limit:]) + return "%s\n%s" % (self, self.output) + return str(self) + +class CheckoutNeedsUpdate(ScriptError): + def __init__(self, script_args, exit_code, output, cwd): + ScriptError.__init__(self, script_args=script_args, exit_code=exit_code, output=output, cwd=cwd) + + +def default_error_handler(error): + raise error + +def commit_error_handler(error): + if re.search("resource out of date", error.output): + raise CheckoutNeedsUpdate(script_args=error.script_args, exit_code=error.exit_code, output=error.output, cwd=error.cwd) + default_error_handler(error) + +def ignore_error(error): + pass class SCM: def __init__(self, cwd, dryrun=False): @@ -88,24 +123,28 @@ class SCM: self.dryrun = dryrun @staticmethod - def run_command(args, cwd=None, input=None, raise_on_failure=True, return_exit_code=False): + def run_command(args, cwd=None, input=None, error_handler=default_error_handler, return_exit_code=False): stdin = subprocess.PIPE if input else None - process = subprocess.Popen(args, stdout=subprocess.PIPE, stdin=stdin, cwd=cwd) + process = subprocess.Popen(args, stdin=stdin, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=cwd) output = process.communicate(input)[0].rstrip() exit_code = process.wait() - if raise_on_failure and exit_code: - raise ScriptError('Failed to run "%s" exit_code: %d cwd: %s' % (args, exit_code, cwd)) + if exit_code: + script_error = ScriptError(script_args=args, exit_code=exit_code, output=output, cwd=cwd) + error_handler(script_error) if return_exit_code: return exit_code return output + def scripts_directory(self): + return os.path.join(self.checkout_root, "WebKitTools", "Scripts") + def script_path(self, script_name): - return os.path.join(self.checkout_root, "WebKitTools", "Scripts", script_name) + return os.path.join(self.scripts_directory(), script_name) def ensure_clean_working_directory(self, force): if not force and not self.working_directory_is_clean(): - print self.run_command(self.status_command(), raise_on_failure=False) - raise ScriptError("Working directory has modifications, pass --force-clean or --no-clean to continue.") + print self.run_command(self.status_command(), error_handler=ignore_error) + raise ScriptError(message="Working directory has modifications, pass --force-clean or --no-clean to continue.") log("Cleaning working directory") self.clean_working_directory() @@ -123,7 +162,7 @@ class SCM: def apply_patch(self, patch, force=False): # It's possible that the patch was not made from the root directory. # We should detect and handle that case. - curl_process = subprocess.Popen(['curl', patch['url']], stdout=subprocess.PIPE) + curl_process = subprocess.Popen(['curl', '--location', '--silent', '--show-error', patch['url']], stdout=subprocess.PIPE) args = [self.script_path('svn-apply'), '--reviewer', patch['reviewer']] if force: args.append('--force') @@ -131,7 +170,7 @@ class SCM: return_code = patch_apply_process.wait() if return_code: - raise ScriptError("Patch %s from bug %s failed to download and apply." % (patch['url'], patch['bug_id'])) + raise ScriptError(message="Patch %s from bug %s failed to download and apply." % (patch['url'], patch['bug_id'])) def run_status_and_extract_filenames(self, status_command, status_regexp): filenames = [] @@ -144,6 +183,25 @@ class SCM: filenames.append(filename) return filenames + def strip_r_from_svn_revision(self, svn_revision): + match = re.match("^r(?P<svn_revision>\d+)", svn_revision) + if (match): + return match.group('svn_revision') + return svn_revision + + def svn_revision_from_commit_text(self, commit_text): + match = re.search(self.commit_success_regexp(), commit_text, re.MULTILINE) + return match.group('svn_revision') + + # ChangeLog-specific code doesn't really belong in scm.py, but this function is very useful. + def modified_changelogs(self): + changelog_paths = [] + paths = self.changed_files() + for path in paths: + if os.path.basename(path) == "ChangeLog": + changelog_paths.append(path) + return changelog_paths + @staticmethod def in_working_directory(path): raise NotImplementedError, "subclasses must implement" @@ -177,9 +235,24 @@ class SCM: def create_patch(self): raise NotImplementedError, "subclasses must implement" + def diff_for_revision(self, revision): + raise NotImplementedError, "subclasses must implement" + + def apply_reverse_diff(self, revision): + raise NotImplementedError, "subclasses must implement" + + def revert_files(self, file_paths): + raise NotImplementedError, "subclasses must implement" + def commit_with_message(self, message): raise NotImplementedError, "subclasses must implement" - + + def svn_commit_log(self, svn_revision): + raise NotImplementedError, "subclasses must implement" + + def last_svn_commit_log(self): + raise NotImplementedError, "subclasses must implement" + # Subclasses must indicate if they support local commits, # but the SCM baseclass will only call local_commits methods when this is true. @staticmethod @@ -211,16 +284,21 @@ class SVN(SCM): def in_working_directory(path): return os.path.isdir(os.path.join(path, '.svn')) - @staticmethod - def find_uuid(path): - if not SVN.in_working_directory(path): + @classmethod + def find_uuid(cls, path): + if not cls.in_working_directory(path): return None - info = SVN.run_command(['svn', 'info', path]) - match = re.search("^Repository UUID: (?P<uuid>.+)$", info, re.MULTILINE) + return cls.value_from_svn_info(path, 'Repository UUID') + + @classmethod + def value_from_svn_info(cls, path, field_name): + svn_info_args = ['svn', 'info', path] + info_output = cls.run_command(svn_info_args) + match = re.search("^%s: (?P<value>.+)$" % field_name, info_output, re.MULTILINE) if not match: - raise ScriptError('svn info did not contain a UUID.') - return match.group('uuid') - + raise ScriptError(script_args=svn_info_args, message='svn info did not contain a %s.' % field_name) + return match.group('value') + @staticmethod def find_checkout_root(path): uuid = SVN.find_uuid(path) @@ -236,11 +314,11 @@ class SVN(SCM): (path, last_component) = os.path.split(path) if last_path == path: return None - + @staticmethod def commit_success_regexp(): return "^Committed revision (?P<svn_revision>\d+)\.$" - + def svn_version(self): if not self.cached_version: self.cached_version = self.run_command(['svn', '--version', '--quiet']) @@ -274,19 +352,44 @@ class SVN(SCM): return "svn" def create_patch(self): - return self.run_command(self.script_path("svn-create-patch")) + return self.run_command(self.script_path("svn-create-patch"), cwd=self.checkout_root) + + def diff_for_revision(self, revision): + return self.run_command(['svn', 'diff', '-c', str(revision)]) + + def _repository_url(self): + return self.value_from_svn_info(self.checkout_root, 'URL') + + def apply_reverse_diff(self, revision): + # '-c -revision' applies the inverse diff of 'revision' + svn_merge_args = ['svn', 'merge', '--non-interactive', '-c', '-%s' % revision, self._repository_url()] + log("WARNING: svn merge has been known to take more than 10 minutes to complete. It is recommended you use git for rollouts.") + log("Running '%s'" % " ".join(svn_merge_args)) + self.run_command(svn_merge_args) + + def revert_files(self, file_paths): + self.run_command(['svn', 'revert'] + file_paths) def commit_with_message(self, message): if self.dryrun: - return "Dry run, no remote commit." - return self.run_command(['svn', 'commit', '-m', message]) + # Return a string which looks like a commit so that things which parse this output will succeed. + return "Dry run, no commit.\nCommitted revision 0." + return self.run_command(['svn', 'commit', '-m', message], error_handler=commit_error_handler) + + def svn_commit_log(self, svn_revision): + svn_revision = self.strip_r_from_svn_revision(str(svn_revision)) + return self.run_command(['svn', 'log', '--non-interactive', '--revision', svn_revision]); + def last_svn_commit_log(self): + # BASE is the checkout revision, HEAD is the remote repository revision + # http://svnbook.red-bean.com/en/1.0/ch03s03.html + return self.svn_commit_log('BASE') # All git-specific logic should go here. class Git(SCM): def __init__(self, cwd, dryrun=False): SCM.__init__(self, cwd, dryrun) - + @classmethod def in_working_directory(cls, path): return cls.run_command(['git', 'rev-parse', '--is-inside-work-tree'], cwd=path) == "true" @@ -303,22 +406,29 @@ class Git(SCM): @staticmethod def commit_success_regexp(): return "^Committed r(?P<svn_revision>\d+)$" - + + def discard_local_commits(self): self.run_command(['git', 'reset', '--hard', 'trunk']) def local_commits(self): return self.run_command(['git', 'log', '--pretty=oneline', 'HEAD...trunk']).splitlines() + def rebase_in_progress(self): + return os.path.exists(os.path.join(self.checkout_root, '.git/rebase-apply')) + def working_directory_is_clean(self): return self.run_command(['git', 'diff-index', 'HEAD']) == "" - + def clean_working_directory(self): # Could run git clean here too, but that wouldn't match working_directory_is_clean self.run_command(['git', 'reset', '--hard', 'HEAD']) - + # Aborting rebase even though this does not match working_directory_is_clean + if self.rebase_in_progress(): + self.run_command(['git', 'rebase', '--abort']) + def update_webkit(self): - # FIXME: Should probably call update-webkit, no? + # FIXME: Call update-webkit once https://bugs.webkit.org/show_bug.cgi?id=27162 is fixed. log("Updating working directory") self.run_command(['git', 'svn', 'rebase']) @@ -340,10 +450,44 @@ class Git(SCM): def create_patch(self): return self.run_command(['git', 'diff', 'HEAD']) + @classmethod + def git_commit_from_svn_revision(cls, revision): + # git svn find-rev always exits 0, even when the revision is not found. + return cls.run_command(['git', 'svn', 'find-rev', 'r%s' % revision]) + + def diff_for_revision(self, revision): + git_commit = self.git_commit_from_svn_revision(revision) + return self.create_patch_from_local_commit(git_commit) + + def apply_reverse_diff(self, revision): + # Assume the revision is an svn revision. + git_commit = self.git_commit_from_svn_revision(revision) + if not git_commit: + raise ScriptError(message='Failed to find git commit for revision %s, git svn log output: "%s"' % (revision, git_commit)) + + # I think this will always fail due to ChangeLogs. + # FIXME: We need to detec specific failure conditions and handle them. + self.run_command(['git', 'revert', '--no-commit', git_commit], error_handler=ignore_error) + + # Fix any ChangeLogs if necessary. + changelog_paths = self.modified_changelogs() + if len(changelog_paths): + self.run_command([self.script_path('resolve-ChangeLogs')] + changelog_paths) + + def revert_files(self, file_paths): + self.run_command(['git', 'checkout', 'HEAD'] + file_paths) + def commit_with_message(self, message): self.commit_locally_with_message(message) return self.push_local_commits_to_server() + def svn_commit_log(self, svn_revision): + svn_revision = self.strip_r_from_svn_revision(svn_revision) + return self.run_command(['git', 'svn', 'log', '-r', svn_revision]) + + def last_svn_commit_log(self): + return self.run_command(['git', 'svn', 'log', '--limit=1']) + # Git-specific methods: def create_patch_from_local_commit(self, commit_id): @@ -357,8 +501,9 @@ class Git(SCM): def push_local_commits_to_server(self): if self.dryrun: - return "Dry run, no remote commit." - return self.run_command(['git', 'svn', 'dcommit']) + # Return a string which looks like a commit so that things which parse this output will succeed. + return "Dry run, no remote commit.\nCommitted r0" + return self.run_command(['git', 'svn', 'dcommit'], error_handler=commit_error_handler) # This function supports the following argument formats: # no args : rev-list trunk..HEAD @@ -373,9 +518,9 @@ class Git(SCM): commit_ids = [] for commitish in args: if '...' in commitish: - raise ScriptError("'...' is not supported (found in '%s'). Did you mean '..'?" % commitish) + raise ScriptError(message="'...' is not supported (found in '%s'). Did you mean '..'?" % commitish) elif '..' in commitish: - commit_ids += self.run_command(['git', 'rev-list', commitish]).splitlines() + commit_ids += reversed(self.run_command(['git', 'rev-list', commitish]).splitlines()) else: # Turn single commits or branch or tag names into commit ids. commit_ids += self.run_command(['git', 'rev-parse', '--revs-only', commitish]).splitlines() diff --git a/WebKitTools/Scripts/modules/scm_unittest.py b/WebKitTools/Scripts/modules/scm_unittest.py index 5bf2726..58494a0 100644 --- a/WebKitTools/Scripts/modules/scm_unittest.py +++ b/WebKitTools/Scripts/modules/scm_unittest.py @@ -1,4 +1,5 @@ # Copyright (C) 2009 Google Inc. All rights reserved. +# Copyright (C) 2009 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 @@ -26,18 +27,40 @@ # (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 base64 import os +import re +import stat import subprocess import tempfile import unittest -from modules.scm import detect_scm_system, SCM, ScriptError +import urllib +from modules.scm import detect_scm_system, SCM, ScriptError, CheckoutNeedsUpdate, ignore_error, commit_error_handler # Eventually we will want to write tests which work for both scms. (like update_webkit, changed_files, etc.) # Perhaps through some SCMTest base-class which both SVNTest and GitTest inherit from. -def run(args): - SCM.run_command(args) +def run(args, cwd=None): + return SCM.run_command(args, cwd=cwd) + +def run_silent(args, cwd=None): + process = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd) + process.communicate() # ignore output + exit_code = process.wait() + if exit_code: + raise ScriptError('Failed to run "%s" exit_code: %d cwd: %s' % (args, exit_code, cwd)) + +def write_into_file_at_path(file_path, contents): + file = open(file_path, 'w') + file.write(contents) + file.close() + +def read_from_path(file_path): + file = open(file_path, 'r') + contents = file.read() + file.close() + return contents # Exists to share svn repository creation code between the git and svn tests class SVNTestRepository: @@ -57,13 +80,23 @@ class SVNTestRepository: run(['svn', 'commit', '--quiet', '--message', 'second commit']) - test_file.write("test3") - test_file.close() + test_file.write("test3\n") + test_file.flush() run(['svn', 'commit', '--quiet', '--message', 'third commit']) + test_file.write("test4\n") + test_file.close() + + run(['svn', 'commit', '--quiet', '--message', 'fourth commit']) + + # svn does not seem to update after commit as I would expect. + run(['svn', 'update']) + @classmethod def setup(cls, test_object): + test_object.original_path = os.path.abspath('.') + # Create an test SVN repository test_object.svn_repo_path = tempfile.mkdtemp(suffix="svn_test_repo") test_object.svn_repo_url = "file://%s" % test_object.svn_repo_path # Not sure this will work on windows @@ -83,29 +116,161 @@ class SVNTestRepository: run(['rm', '-rf', test_object.svn_checkout_path]) -class SVNTest(unittest.TestCase): +class SCMTest(unittest.TestCase): + def _create_patch(self, patch_contents): + patch_path = os.path.join(self.svn_checkout_path, 'patch.diff') + write_into_file_at_path(patch_path, patch_contents) + patch = {} + patch['reviewer'] = 'Joe Cool' + patch['bug_id'] = '12345' + patch['url'] = 'file://%s' % urllib.pathname2url(patch_path) + return patch + + def _setup_webkittools_scripts_symlink(self, local_scm): + webkit_scm = detect_scm_system(self.original_path) + webkit_scripts_directory = webkit_scm.scripts_directory() + local_scripts_directory = local_scm.scripts_directory() + os.mkdir(os.path.dirname(local_scripts_directory)) + os.symlink(webkit_scripts_directory, local_scripts_directory) + + def test_error_handlers(self): + git_failure_message="Merge conflict during commit: Your file or directory 'WebCore/ChangeLog' is probably out-of-date: resource out of date; try updating at /usr/local/libexec/git-core//git-svn line 469" + svn_failure_message="""svn: Commit failed (details follow): +svn: File or directory 'ChangeLog' is out of date; try updating +svn: resource out of date; try updating +""" + command_does_not_exist = ['does_not_exist', 'invalid_option'] + self.assertRaises(OSError, SCM.run_command, command_does_not_exist) + self.assertRaises(OSError, SCM.run_command, command_does_not_exist, error_handler=ignore_error) + + command_returns_non_zero = ['/bin/sh', '--invalid-option'] + self.assertRaises(ScriptError, SCM.run_command, command_returns_non_zero) + self.assertTrue(SCM.run_command(command_returns_non_zero, error_handler=ignore_error)) + + self.assertRaises(CheckoutNeedsUpdate, commit_error_handler, ScriptError(output=git_failure_message)) + self.assertRaises(CheckoutNeedsUpdate, commit_error_handler, ScriptError(output=svn_failure_message)) + self.assertRaises(ScriptError, commit_error_handler, ScriptError(output='blah blah blah')) + + + # Tests which both GitTest and SVNTest should run. + # FIXME: There must be a simpler way to add these w/o adding a wrapper method to both subclasses + def _shared_test_commit_with_message(self): + write_into_file_at_path('test_file', 'more test content') + commit_text = self.scm.commit_with_message('another test commit') + self.assertEqual(self.scm.svn_revision_from_commit_text(commit_text), '5') + + self.scm.dryrun = True + write_into_file_at_path('test_file', 'still more test content') + commit_text = self.scm.commit_with_message('yet another test commit') + self.assertEqual(self.scm.svn_revision_from_commit_text(commit_text), '0') + + def _shared_test_reverse_diff(self): + self._setup_webkittools_scripts_symlink(self.scm) # Git's apply_reverse_diff uses resolve-ChangeLogs + # Only test the simple case, as any other will end up with conflict markers. + self.scm.apply_reverse_diff('4') + self.assertEqual(read_from_path('test_file'), "test1test2test3\n") + + def _shared_test_diff_for_revision(self): + # Patch formats are slightly different between svn and git, so just regexp for things we know should be there. + r3_patch = self.scm.diff_for_revision(3) + self.assertTrue(re.search('test3', r3_patch)) + self.assertFalse(re.search('test4', r3_patch)) + self.assertTrue(re.search('test2', r3_patch)) + self.assertTrue(re.search('test2', self.scm.diff_for_revision(2))) + + +class SVNTest(SCMTest): def setUp(self): SVNTestRepository.setup(self) os.chdir(self.svn_checkout_path) + self.scm = detect_scm_system(self.svn_checkout_path) def tearDown(self): SVNTestRepository.tear_down(self) + os.chdir(self.original_path) + + def test_create_patch_is_full_patch(self): + test_dir_path = os.path.join(self.svn_checkout_path, 'test_dir') + os.mkdir(test_dir_path) + test_file_path = os.path.join(test_dir_path, 'test_file2') + write_into_file_at_path(test_file_path, 'test content') + run(['svn', 'add', 'test_dir']) + + # create_patch depends on 'svn-create-patch', so make a dummy version. + scripts_path = os.path.join(self.svn_checkout_path, 'WebKitTools', 'Scripts') + os.makedirs(scripts_path) + create_patch_path = os.path.join(scripts_path, 'svn-create-patch') + write_into_file_at_path(create_patch_path, '#!/bin/sh\necho $PWD') + os.chmod(create_patch_path, stat.S_IXUSR | stat.S_IRUSR) + + # Change into our test directory and run the create_patch command. + os.chdir(test_dir_path) + scm = detect_scm_system(test_dir_path) + self.assertEqual(scm.checkout_root, self.svn_checkout_path) # Sanity check that detection worked right. + patch_contents = scm.create_patch() + # Our fake 'svn-create-patch' returns $PWD instead of a patch, check that it was executed from the root of the repo. + self.assertEqual(os.path.realpath(scm.checkout_root), patch_contents) def test_detection(self): scm = detect_scm_system(self.svn_checkout_path) self.assertEqual(scm.display_name(), "svn") self.assertEqual(scm.supports_local_commits(), False) -class GitTest(unittest.TestCase): + def test_apply_small_binary_patch(self): + patch_contents = """Index: test_file.swf +=================================================================== +Cannot display: file marked as a binary type. +svn:mime-type = application/octet-stream + +Property changes on: test_file.swf +___________________________________________________________________ +Name: svn:mime-type + + application/octet-stream + + +Q1dTBx0AAAB42itg4GlgYJjGwMDDyODMxMDw34GBgQEAJPQDJA== +""" + expected_contents = base64.b64decode("Q1dTBx0AAAB42itg4GlgYJjGwMDDyODMxMDw34GBgQEAJPQDJA==") + self._setup_webkittools_scripts_symlink(self.scm) + patch_file = self._create_patch(patch_contents) + self.scm.apply_patch(patch_file) + actual_contents = read_from_path("test_file.swf") + self.assertEqual(actual_contents, expected_contents) + + def test_apply_svn_patch(self): + scm = detect_scm_system(self.svn_checkout_path) + patch = self._create_patch(run(['svn', 'diff', '-r4:3'])) + self._setup_webkittools_scripts_symlink(scm) + scm.apply_patch(patch) + + def test_apply_svn_patch_force(self): + scm = detect_scm_system(self.svn_checkout_path) + patch = self._create_patch(run(['svn', 'diff', '-r2:4'])) + self._setup_webkittools_scripts_symlink(scm) + self.assertRaises(ScriptError, scm.apply_patch, patch, force=True) + + def test_commit_logs(self): + # Commits have dates and usernames in them, so we can't just direct compare. + self.assertTrue(re.search('fourth commit', self.scm.last_svn_commit_log())) + self.assertTrue(re.search('second commit', self.scm.svn_commit_log(2))) + + def test_commit_text_parsing(self): + self._shared_test_commit_with_message() + + def test_reverse_diff(self): + self._shared_test_reverse_diff() + + def test_diff_for_revision(self): + self._shared_test_diff_for_revision() + + +class GitTest(SCMTest): def _setup_git_clone_of_svn_repository(self): self.git_checkout_path = tempfile.mkdtemp(suffix="git_test_checkout") - # --quiet doesn't make git svn silent, so we redirect output - args = ['git', 'svn', '--quiet', 'clone', self.svn_repo_url, self.git_checkout_path] - git_svn_clone = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - git_svn_clone.communicate() # ignore output - git_svn_clone.wait() + # --quiet doesn't make git svn silent, so we use run_silent to redirect output + run_silent(['git', 'svn', '--quiet', 'clone', self.svn_repo_url, self.git_checkout_path]) def _tear_down_git_clone_of_svn_repository(self): run(['rm', '-rf', self.git_checkout_path]) @@ -114,26 +279,81 @@ class GitTest(unittest.TestCase): SVNTestRepository.setup(self) self._setup_git_clone_of_svn_repository() os.chdir(self.git_checkout_path) + self.scm = detect_scm_system(self.git_checkout_path) def tearDown(self): SVNTestRepository.tear_down(self) self._tear_down_git_clone_of_svn_repository() + os.chdir(self.original_path) def test_detection(self): scm = detect_scm_system(self.git_checkout_path) self.assertEqual(scm.display_name(), "git") self.assertEqual(scm.supports_local_commits(), True) - def test_commitish_parsing(self): + def test_rebase_in_progress(self): + svn_test_file = os.path.join(self.svn_checkout_path, 'test_file') + write_into_file_at_path(svn_test_file, "svn_checkout") + run(['svn', 'commit', '--message', 'commit to conflict with git commit'], cwd=self.svn_checkout_path) + + git_test_file = os.path.join(self.git_checkout_path, 'test_file') + write_into_file_at_path(git_test_file, "git_checkout") + run(['git', 'commit', '-a', '-m', 'commit to be thrown away by rebase abort']) + + # --quiet doesn't make git svn silent, so use run_silent to redirect output + self.assertRaises(ScriptError, run_silent, ['git', 'svn', '--quiet', 'rebase']) # Will fail due to a conflict leaving us mid-rebase. + scm = detect_scm_system(self.git_checkout_path) + self.assertTrue(scm.rebase_in_progress()) + + # Make sure our cleanup works. + scm.clean_working_directory() + self.assertFalse(scm.rebase_in_progress()) + + # Make sure cleanup doesn't throw when no rebase is in progress. + scm.clean_working_directory() + def test_commitish_parsing(self): + scm = detect_scm_system(self.git_checkout_path) + # Multiple revisions are cherry-picked. self.assertEqual(len(scm.commit_ids_from_commitish_arguments(['HEAD~2'])), 1) self.assertEqual(len(scm.commit_ids_from_commitish_arguments(['HEAD', 'HEAD~2'])), 2) - + # ... is an invalid range specifier self.assertRaises(ScriptError, scm.commit_ids_from_commitish_arguments, ['trunk...HEAD']) + def test_commitish_order(self): + scm = detect_scm_system(self.git_checkout_path) + + commit_range = 'HEAD~3..HEAD' + + actual_commits = scm.commit_ids_from_commitish_arguments([commit_range]) + expected_commits = [] + expected_commits += reversed(run(['git', 'rev-list', commit_range]).splitlines()) + + self.assertEqual(actual_commits, expected_commits) + + def test_apply_git_patch(self): + scm = detect_scm_system(self.git_checkout_path) + patch = self._create_patch(run(['git', 'diff', 'HEAD..HEAD^'])) + self._setup_webkittools_scripts_symlink(scm) + scm.apply_patch(patch) + + def test_apply_git_patch_force(self): + scm = detect_scm_system(self.git_checkout_path) + patch = self._create_patch(run(['git', 'diff', 'HEAD~2..HEAD'])) + self._setup_webkittools_scripts_symlink(scm) + self.assertRaises(ScriptError, scm.apply_patch, patch, force=True) + + def test_commit_text_parsing(self): + self._shared_test_commit_with_message() + + def test_reverse_diff(self): + self._shared_test_reverse_diff() + + def test_diff_for_revision(self): + self._shared_test_diff_for_revision() if __name__ == '__main__': unittest.main() diff --git a/WebKitTools/Scripts/modules/statusbot.py b/WebKitTools/Scripts/modules/statusbot.py new file mode 100644 index 0000000..9c9ba04 --- /dev/null +++ b/WebKitTools/Scripts/modules/statusbot.py @@ -0,0 +1,66 @@ +# Copyright (C) 2009 Google 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: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# WebKit's Python module for interacting with the Commit Queue status page. + +# WebKit includes a built copy of BeautifulSoup in Scripts/modules +# so this import should always succeed. +from .BeautifulSoup import BeautifulSoup + +try: + from mechanize import Browser +except ImportError, e: + print """ +mechanize is required. + +To install: +sudo easy_install mechanize + +Or from the web: +http://wwwsearch.sourceforge.net/mechanize/ +""" + exit(1) + +class StatusBot: + default_host = "webkit-commit-queue.appspot.com" + + def __init__(self, host=default_host): + self.statusbot_host = host + self.statusbot_server_url = "http://%s" % self.statusbot_host + self.update_status_url = "%s/update_status" % self.statusbot_server_url + self.browser = Browser() + + def update_status(self, status, bug_id=None, patch_id=None): + self.browser.open(self.update_status_url) + self.browser.select_form(name="update_status") + if bug_id: + self.browser['bug_id'] = str(bug_id) + if patch_id: + self.browser['patch_id'] = str(patch_id) + self.browser['status'] = status + self.browser.submit() diff --git a/WebKitTools/Scripts/parse-malloc-history b/WebKitTools/Scripts/parse-malloc-history index 76ca74b..177de1c 100755 --- a/WebKitTools/Scripts/parse-malloc-history +++ b/WebKitTools/Scripts/parse-malloc-history @@ -70,8 +70,6 @@ sub main() 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 @@ -93,6 +91,28 @@ sub main() } } + # Then try LeakFinder format + # --------------- Key: 213813, 84 bytes --------- + # c:\cygwin\home\buildbot\webkit\opensource\webcore\rendering\renderarena.cpp(78): WebCore::RenderArena::allocate + # c:\cygwin\home\buildbot\webkit\opensource\webcore\rendering\renderobject.cpp(82): WebCore::RenderObject::operator new + if (!$callCount || !$byteCount) { + $callCount = 1; + ($byteCount) = ($line =~ /Key: (?:\d+), (\d+) bytes/); + if ($byteCount) { + $line = $file[++$i]; + my @tempStack; + while ($file[$i+1] !~ /^(?:-|\d)/) { + if ($line =~ /\): (.*)$/) { + my $call = $1; + $call =~ s/\r$//; + unshift(@tempStack, $call); + } + $line = $file[++$i]; + } + $line = join(" | ", @tempStack); + } + } + # Then give up next if (!$callCount || !$byteCount); diff --git a/WebKitTools/Scripts/pdevenv b/WebKitTools/Scripts/pdevenv index 9128912..818e4ee 100755 --- a/WebKitTools/Scripts/pdevenv +++ b/WebKitTools/Scripts/pdevenv @@ -11,8 +11,22 @@ my ($fh, $path) = tempfile(UNLINK => 0, SUFFIX => '.cmd') or die; chomp(my $vcBin = `cygpath -w "$FindBin::Bin/../vcbin"`); chomp(my $scriptsPath = `cygpath -w "$FindBin::Bin"`); +my $vsToolsVar; +if ($ENV{'VS80COMNTOOLS'}) { + $vsToolsVar = "VS80COMNTOOLS"; +} elsif ($ENV{'VS90COMNTOOLS'}) { + $vsToolsVar = "VS90COMNTOOLS"; +} else { + print "*************************************************************\n"; + print "Cannot find Visual Studio tools dir.\n"; + print "Please ensure that \$VS80COMNTOOLS or \$VS90COMNTOOLS\n"; + print "is set to a valid location.\n"; + print "*************************************************************\n"; + die; +} + print $fh "\@echo off\n\n"; -print $fh "call \"\%VS80COMNTOOLS\%\\vsvars32.bat\"\n\n"; +print $fh "call \"\%" . $vsToolsVar . "\%\\vsvars32.bat\"\n\n"; print $fh "set PATH=$vcBin;$scriptsPath;\%PATH\%\n\n"; print $fh "IF EXIST \"\%VSINSTALLDIR\%\\Common7\\IDE\\devenv.com\" (devenv.com /useenv " . join(" ", @ARGV) . ") ELSE "; print $fh "VCExpress.exe /useenv " . join(" ", @ARGV) . "\n"; diff --git a/WebKitTools/Scripts/prepare-ChangeLog b/WebKitTools/Scripts/prepare-ChangeLog index c3e2cef..ed31005 100755 --- a/WebKitTools/Scripts/prepare-ChangeLog +++ b/WebKitTools/Scripts/prepare-ChangeLog @@ -5,6 +5,7 @@ # Copyright (C) 2000, 2001 Eazel, Inc. # Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. # Copyright (C) 2009 Torch Mobile, Inc. +# Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au> # # prepare-ChangeLog is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public @@ -73,12 +74,16 @@ sub statusCommand(@); sub createPatchCommand($); sub diffHeaderFormat(); sub findOriginalFileFromSvn($); +sub determinePropertyChanges($$$); +sub pluralizeAndList($$@); sub generateFileList(\@\@\%); sub gitConfig($); +sub isUnmodifiedStatus($); sub isModifiedStatus($); sub isAddedStatus($); sub isConflictStatus($); -sub statusDescription($$); +sub statusDescription($$$$); +sub propertyChangeDescription($); sub extractLineRange($); sub canonicalizePath($); sub testListForChangeLog(@); @@ -146,8 +151,6 @@ $isSVN || $isGit || die "Couldn't determine your version control system."; my $SVN = "svn"; my $GIT = "git"; -my $svnVersion = `svn --version --quiet` if $isSVN; - # Find the list of modified files my @changed_files; my $changed_files_string; @@ -326,7 +329,7 @@ if (@logs && $updateChangeLogs && $isSVN) { my @conflictedChangeLogs; while (my $line = <ERRORS>) { print STDERR " ", $line; - push @conflictedChangeLogs, $1 if $line =~ m/^C\s+(.*\S+)\s*$/; + push @conflictedChangeLogs, $1 if $line =~ m/^C\s+(.+?)[\r\n]*$/; } close ERRORS; @@ -1323,7 +1326,7 @@ sub createPatchCommand($) sub diffHeaderFormat() { - return qr/^Index: (\S+)\s*$/ if $isSVN; + return qr/^Index: (\S+)[\r\n]*$/ if $isSVN; return qr/^diff --git a\/.+ b\/(.+)$/ if $isGit; } @@ -1333,7 +1336,7 @@ sub findOriginalFileFromSvn($) my $baseUrl; open INFO, "$SVN info . |" or die; while (<INFO>) { - if (/^URL: (.*\S+)\s*$/) { + if (/^URL: (.+?)[\r\n]*$/) { $baseUrl = $1; } } @@ -1341,7 +1344,7 @@ sub findOriginalFileFromSvn($) my $sourceFile; open INFO, "$SVN info '$file' |" or die; while (<INFO>) { - if (/^Copied From URL: (.*\S+)\s*$/) { + if (/^Copied From URL: (.+?)[\r\n]*$/) { $sourceFile = File::Spec->abs2rel($1, $baseUrl); } } @@ -1349,6 +1352,76 @@ sub findOriginalFileFromSvn($) return $sourceFile; } +sub determinePropertyChanges($$$) +{ + my ($file, $isAdd, $original) = @_; + + my %changes; + if ($isAdd) { + my %addedProperties; + my %removedProperties; + open PROPLIST, "$SVN proplist '$file' |" or die; + while (<PROPLIST>) { + $addedProperties{$1} = 1 if /^ (.+?)[\r\n]*$/ && $1 ne 'svn:mergeinfo'; + } + close PROPLIST; + if ($original) { + open PROPLIST, "$SVN proplist '$original' |" or die; + while (<PROPLIST>) { + next unless /^ (.+?)[\r\n]*$/; + my $property = $1; + if (exists $addedProperties{$property}) { + delete $addedProperties{$1}; + } else { + $removedProperties{$1} = 1; + } + } + } + $changes{"A"} = [sort keys %addedProperties] if %addedProperties; + $changes{"D"} = [sort keys %removedProperties] if %removedProperties; + } else { + open DIFF, "$SVN diff '$file' |" or die; + while (<DIFF>) { + if (/^Property changes on:/) { + while (<DIFF>) { + my $operation; + my $property; + if (/^Added: (\S*)/) { + $operation = "A"; + $property = $1; + } elsif (/^Modified: (\S*)/) { + $operation = "M"; + $property = $1; + } elsif (/^Deleted: (\S*)/) { + $operation = "D"; + $property = $1; + } elsif (/^Name: (\S*)/) { + # Older versions of svn just say "Name" instead of the type + # of property change. + $operation = "C"; + $property = $1; + } + if ($operation) { + $changes{$operation} = [] unless exists $changes{$operation}; + push @{$changes{$operation}}, $property; + } + } + } + } + close DIFF; + } + return \%changes; +} + +sub pluralizeAndList($$@) +{ + my ($singular, $plural, @items) = @_; + + return if @items == 0; + return "$singular $items[0]" if @items == 1; + return "$plural " . join(", ", @items[0 .. $#items - 1]) . " and " . $items[-1]; +} + sub generateFileList(\@\@\%) { my ($changedFiles, $conflictFiles, $functionLists) = @_; @@ -1356,32 +1429,40 @@ sub generateFileList(\@\@\%) open STAT, "-|", statusCommand(keys %paths) or die "The status failed: $!.\n"; while (<STAT>) { my $status; + my $propertyStatus; + my $propertyChanges; my $original; my $file; if ($isSVN) { my $matches; - if (eval "v$svnVersion" ge v1.6) { - $matches = /^([ACDMR]).{6} (.*\S+)\s*$/; + if (isSVNVersion16OrNewer()) { + $matches = /^([ ACDMR])([ CM]).{5} (.+?)[\r\n]*$/; $status = $1; - $file = $2; + $propertyStatus = $2; + $file = $3; } else { - $matches = /^([ACDMR]).{5} (.*\S+)\s*$/; + $matches = /^([ ACDMR])([ CM]).{4} (.+?)[\r\n]*$/; $status = $1; - $file = $2; + $propertyStatus = $2; + $file = $3; } if ($matches) { $file = normalizePath($file); $original = findOriginalFileFromSvn($file) if substr($_, 3, 1) eq "+"; + my $isAdd = isAddedStatus($status); + $propertyChanges = determinePropertyChanges($file, $isAdd, $original) if isModifiedStatus($propertyStatus) || $isAdd; } else { print; # error output from svn stat } } elsif ($isGit) { if (/^([ADM])\t(.+)$/) { $status = $1; + $propertyStatus = " "; # git doesn't have properties $file = normalizePath($2); } elsif (/^([CR])[0-9]{1,3}\t([^\t]+)\t([^\t\n]+)$/) { # for example: R90% newfile oldfile $status = $1; + $propertyStatus = " "; $original = normalizePath($2); $file = normalizePath($3); } else { @@ -1389,11 +1470,11 @@ sub generateFileList(\@\@\%) } } - next unless $status; + next if !$status || isUnmodifiedStatus($status) && isUnmodifiedStatus($propertyStatus); $file = makeFilePathRelative($file); - if (isModifiedStatus($status) || isAddedStatus($status)) { + if (isModifiedStatus($status) || isAddedStatus($status) || isModifiedStatus($propertyStatus)) { my @components = File::Spec->splitdir($file); if ($components[0] eq "LayoutTests") { $didChangeRegressionTests = 1; @@ -1401,14 +1482,15 @@ sub generateFileList(\@\@\%) if isAddedStatus($status) && $file =~ /\.([a-zA-Z]+)$/ && $supportedTestExtensions{lc($1)} - && !scalar(grep(/^resources$/i, @components)); + && !scalar(grep(/^resources$/i, @components)) + && !scalar(grep(/^script-tests$/i, @components)); } push @{$changedFiles}, $file if $components[$#components] ne "ChangeLog"; - } elsif (isConflictStatus($status)) { + } elsif (isConflictStatus($status) || isConflictStatus($propertyStatus)) { push @{$conflictFiles}, $file; } if (basename($file) ne "ChangeLog") { - my $description = statusDescription($status, $original); + my $description = statusDescription($status, $propertyStatus, $original, $propertyChanges); $functionLists->{$file} = $description if defined $description; } } @@ -1429,6 +1511,17 @@ sub gitConfig($) return $result; } +sub isUnmodifiedStatus($) +{ + my ($status) = @_; + + my %statusCodes = ( + " " => 1, + ); + + return $statusCodes{$status}; +} + sub isModifiedStatus($) { my ($status) = @_; @@ -1470,15 +1563,18 @@ sub isConflictStatus($) return $git{$status} if $isGit; } -sub statusDescription($$) +sub statusDescription($$$$) { - my ($status, $original) = @_; + my ($status, $propertyStatus, $original, $propertyChanges) = @_; + + my $propertyDescription = defined $propertyChanges ? propertyChangeDescription($propertyChanges) : ""; my %svn = ( "A" => defined $original ? " Copied from \%s." : " Added.", "D" => " Removed.", "M" => "", "R" => defined $original ? " Replaced with \%s." : " Replaced.", + " " => "", ); my %git = %svn; @@ -1486,9 +1582,33 @@ sub statusDescription($$) $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; + my $description; + $description = sprintf($svn{$status}, $original) if $isSVN && exists $svn{$status}; + $description = sprintf($git{$status}, $original) if $isGit && exists $git{$status}; + return unless defined $description; + + $description .= $propertyDescription unless isAddedStatus($status); + return $description; +} + +sub propertyChangeDescription($) +{ + my ($propertyChanges) = @_; + + my %operations = ( + "A" => "Added", + "M" => "Modified", + "D" => "Removed", + "C" => "Changed", + ); + + my $description = ""; + while (my ($operation, $properties) = each %$propertyChanges) { + my $word = $operations{$operation}; + my $list = pluralizeAndList("property", "properties", @$properties); + $description .= " $word $list."; + } + return $description; } sub extractLineRange($) diff --git a/WebKitTools/Scripts/resolve-ChangeLogs b/WebKitTools/Scripts/resolve-ChangeLogs index 9107fd2..db497f9 100755 --- a/WebKitTools/Scripts/resolve-ChangeLogs +++ b/WebKitTools/Scripts/resolve-ChangeLogs @@ -48,6 +48,7 @@ sub fixChangeLogPatch($); sub fixMergedChangeLogs($;@); sub fixOneMergedChangeLog($); sub hasGitUnmergedFiles(); +sub isInGitFilterBranch(); sub mergeChanges($$$); sub parseFixMerged($$;$); sub removeChangeLogArguments($); @@ -63,8 +64,6 @@ my $isSVN = isSVN(); my $SVN = "svn"; my $GIT = "git"; -my $svnVersion = `svn --version --quiet` if $isSVN; - my $fixMerged; my $gitRebaseContinue = 0; my $printWarnings = 1; @@ -77,7 +76,7 @@ my $getOptionsResult = GetOptions( 'w|warnings!' => \$printWarnings, ); -my $relativePath = chdirReturningRelativePath(determineVCSRoot()); +my $relativePath = isInGitFilterBranch() ? '.' : chdirReturningRelativePath(determineVCSRoot()); my @changeLogFiles = removeChangeLogArguments($relativePath); @@ -255,11 +254,11 @@ sub findUnmergedChangeLogs() if ($isSVN) { my $matches; my $file; - if (eval "v$svnVersion" ge v1.6) { - $matches = /^([C]).{6} (.*\S+)\s*$/; + if (isSVNVersion16OrNewer()) { + $matches = /^([C]).{6} (.+?)[\r\n]*$/; $file = $2; } else { - $matches = /^([C]).{5} (.*\S+)\s*$/; + $matches = /^([C]).{5} (.+?)[\r\n]*$/; $file = $2; } if ($matches) { @@ -432,6 +431,11 @@ sub hasGitUnmergedFiles() return $output ne ""; } +sub isInGitFilterBranch() +{ + return exists $ENV{MAPPED_PREVIOUS_COMMIT} && $ENV{MAPPED_PREVIOUS_COMMIT}; +} + sub mergeChanges($$$) { my ($fileMine, $fileOlder, $fileNewer) = @_; diff --git a/WebKitTools/Scripts/run-javascriptcore-tests b/WebKitTools/Scripts/run-javascriptcore-tests index 21d63c2..865ae1d 100755 --- a/WebKitTools/Scripts/run-javascriptcore-tests +++ b/WebKitTools/Scripts/run-javascriptcore-tests @@ -124,7 +124,7 @@ sub testapiPath($) } #run api tests -if (isAppleMacWebKit()) { +if (isAppleMacWebKit() || isAppleWinWebKit()) { chdirWebKit(); chdir($productDir) or die; my $testapiResult = system testapiPath($productDir); diff --git a/WebKitTools/Scripts/run-launcher b/WebKitTools/Scripts/run-launcher index 24a4c32..ee462ba 100755 --- a/WebKitTools/Scripts/run-launcher +++ b/WebKitTools/Scripts/run-launcher @@ -61,6 +61,15 @@ if (isQt()) { if (isGtk()) { $launcherPath = catdir($launcherPath, "Programs", "GtkLauncher"); } + + if (isWx()) { + if (isDarwin()) { + $launcherPath = catdir($launcherPath, 'wxBrowser.app', 'Contents', 'MacOS', 'wxBrowser'); + } else { + $ENV{LD_LIBRARY_PATH} = $ENV{LD_LIBRARY_PATH} ? "$productDir:$ENV{LD_LIBRARY_PATH}" : $productDir; + $launcherPath = catdir($launcherPath, 'wxBrowser'); + } + } print "Starting webkit launcher.\n"; } diff --git a/WebKitTools/Scripts/run-sunspider b/WebKitTools/Scripts/run-sunspider index 154c9fa..367fd06 100755 --- a/WebKitTools/Scripts/run-sunspider +++ b/WebKitTools/Scripts/run-sunspider @@ -43,6 +43,7 @@ my $runShark20 = 0; my $runSharkCache = 0; my $ubench = 0; my $v8 = 0; +my $parseonly = 0; my $setBaseline = 0; my $showHelp = 0; my $testsPattern; @@ -60,6 +61,7 @@ Usage: $programName [options] [options to pass to build system] --shark-cache Like --shark, but performs a L2 cache-miss sample instead of time sample --ubench Use microbenchmark suite instead of regular tests (to check for core execution regressions) --v8 Use the V8 benchmark suite. + --parse-only Use the parse-only benchmark suite EOF GetOptions('root=s' => sub { my ($x, $value) = @_; $root = $value; setConfigurationProductDir(Cwd::abs_path($root)); }, @@ -70,6 +72,7 @@ GetOptions('root=s' => sub { my ($x, $value) = @_; $root = $value; setConfigurat 'shark-cache' => \$runSharkCache, 'ubench' => \$ubench, 'v8' => \$v8, + 'parse-only' => \$parseonly, 'tests=s' => \$testsPattern, 'help' => \$showHelp); @@ -84,7 +87,7 @@ sub buildJSC push(@ARGV, "--" . $configuration); chdirWebKit(); - my $buildResult = system "WebKitTools/Scripts/build-jsc", @ARGV; + my $buildResult = system currentPerlPath(), "WebKitTools/Scripts/build-jsc", @ARGV; if ($buildResult) { print STDERR "Compiling jsc failed!\n"; exit exitStatus($buildResult); @@ -127,6 +130,7 @@ push @args, "--shark20" if $runShark20; push @args, "--shark-cache" if $runSharkCache; push @args, "--ubench" if $ubench; push @args, "--v8" if $v8; +push @args, "--parse-only" if $parseonly; push @args, "--tests", $testsPattern if $testsPattern; -exec "./sunspider", @args; +exec currentPerlPath(), "./sunspider", @args; diff --git a/WebKitTools/Scripts/run-webkit-httpd b/WebKitTools/Scripts/run-webkit-httpd index 62eae14..9a97190 100755 --- a/WebKitTools/Scripts/run-webkit-httpd +++ b/WebKitTools/Scripts/run-webkit-httpd @@ -90,6 +90,7 @@ 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(); +$httpdConfig = "$testDirectory/http/conf/fedora-httpd.conf" if isFedoraBased(); my $documentRoot = "$testDirectory/http/tests"; my $typesConfig = "$testDirectory/http/conf/mime.types"; my $sslCertificate = "$testDirectory/http/conf/webkit-httpd.pem"; diff --git a/WebKitTools/Scripts/run-webkit-tests b/WebKitTools/Scripts/run-webkit-tests index f51cf53..a08a53c 100755 --- a/WebKitTools/Scripts/run-webkit-tests +++ b/WebKitTools/Scripts/run-webkit-tests @@ -5,6 +5,7 @@ # Copyright (C) 2007 Matt Lilek (pewtermoose@gmail.com) # Copyright (C) 2007 Eric Seidel <eric@webkit.org> # Copyright (C) 2009 Google Inc. All rights reserved. +# Copyright (C) 2009 Andras Becsi (becsi.andras@stud.u-szeged.hu), University of Szeged # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -70,80 +71,86 @@ use webkitdirs; use VCSUtils; use POSIX; -sub launchWithCurrentEnv(@); -sub openDiffTool(); -sub openDumpTool(); +sub buildPlatformResultHierarchy(); +sub buildPlatformTestHierarchy(@); +sub closeCygpaths(); sub closeDumpTool(); -sub dumpToolDidCrash(); sub closeHTTPD(); sub countAndPrintLeaks($$$); +sub countFinishedTest($$$$); +sub deleteExpectedAndActualResults($); +sub dumpToolDidCrash(); +sub epiloguesAndPrologues($$); +sub expectedDirectoryForTest($;$;$); sub fileNameWithNumber($$); +sub htmlForResultsSection(\@$&); +sub isTextOnlyTest($); +sub launchWithCurrentEnv(@); sub numericcmp($$); +sub openDiffTool(); +sub openDumpTool(); sub openHTTPDIfNeeded(); +sub parseLeaksandPrintUniqueLeaks(); sub pathcmp($$); +sub printFailureMessageForTest($$); sub processIgnoreTests($$); +sub readFromDumpToolWithTimer(**); +sub recordActualResultsAndDiff($$); +sub sampleDumpTool(); +sub setFileHandleNonBlocking(*$); sub slowestcmp($$); sub splitpath($); sub stripExtension($); -sub isTextOnlyTest($); -sub expectedDirectoryForTest($;$;$); -sub countFinishedTest($$$$); +sub stripMetrics($$); sub testCrashedOrTimedOut($$$$$); -sub sampleDumpTool(); -sub printFailureMessageForTest($$); sub toURL($); sub toWindowsPath($); -sub closeCygpaths(); sub validateSkippedArg($$;$); -sub htmlForResultsSection(\@$&); -sub deleteExpectedAndActualResults($); -sub recordActualResultsAndDiff($$); -sub buildPlatformResultHierarchy(); -sub buildPlatformTestHierarchy(@); -sub epiloguesAndPrologues($$); -sub parseLeaksandPrintUniqueLeaks(); -sub readFromDumpToolWithTimer(*;$); -sub setFileHandleNonBlocking(*$); sub writeToFile($$); # Argument handling my $addPlatformExceptions = 0; my $complexText = 0; +my $exitAfterNFailures = 0; +my $generateNewResults = isAppleMacWebKit() ? 1 : 0; my $guardMalloc = ''; my $httpdPort = 8000; my $httpdSSLPort = 8443; +my $ignoreMetrics = 0; my $ignoreTests = ''; +my $iterations = 1; my $launchSafari = 1; -my $platform; +my $mergeDepth; my $pixelTests = ''; +my $platform; my $quiet = ''; +my $randomizeTests = 0; +my $repeatEach = 1; my $report10Slowest = 0; my $resetResults = 0; +my $reverseTests = 0; +my $root; +my $runSample = 1; my $shouldCheckLeaks = 0; my $showHelp = 0; -my $testsPerDumpTool; +my $stripEditingCallbacks = isCygwin(); my $testHTTP = 1; my $testMedia = 1; my $testResultsDirectory = "/tmp/layout-test-results"; +my $testsPerDumpTool = 1000; my $threaded = 0; +# DumpRenderTree has an internal timeout of 15 seconds, so this must be > 15. +my $timeoutSeconds = 20; my $tolerance = 0; my $treatSkipped = "default"; -my $verbose = 0; -my $useValgrind = 0; -my $strictTesting = 0; -my $generateNewResults = isAppleMacWebKit() ? 1 : 0; -my $stripEditingCallbacks = isCygwin(); -my $runSample = 1; -my $root; -my $reverseTests = 0; -my $randomizeTests = 0; -my $mergeDepth; -my $timeoutSeconds = 15; my $useRemoteLinksToTests = 0; +my $useValgrind = 0; +my $verbose = 0; + my @leaksFilenames; -# Default to --no-http for Qt, and wx for now. -$testHTTP = 0 if (isQt() || isWx()); +# Default to --no-http for wx for now. +$testHTTP = 0 if (isWx()); my $expectedTag = "expected"; my $actualTag = "actual"; @@ -167,7 +174,15 @@ if (isAppleMacWebKit()) { $platform = "mac"; } } elsif (isQt()) { - $platform = "qt"; + if (isDarwin()) { + $platform = "qt-mac"; + } elsif (isLinux()) { + $platform = "qt-linux"; + } elsif (isWindows() || isCygwin()) { + $platform = "qt-win"; + } else { + $platform = "qt"; + } } elsif (isGtk()) { $platform = "gtk"; } elsif (isWx()) { @@ -186,19 +201,21 @@ my $launchSafariDefault = $launchSafari ? "launch" : "do not launch"; my $httpDefault = $testHTTP ? "run" : "do not run"; my $sampleDefault = $runSample ? "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 --complex-text Use the complex text code path for all text (Mac OS X and Windows only) -c|--configuration config Set DumpRenderTree build configuration -g|--guard-malloc Enable malloc guard - --help Show this help message + --exit-after-n-failures N Exit after the first N failures instead of running all tests + -h|--help Show this help message --[no-]http Run (or do not run) http tests (default: $httpDefault) -i|--ignore-tests Comma-separated list of directories or tests to ignore + --iterations n Number of times to run the set of tests (e.g. ABCABCABC) --[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 + --nthly n Restart DumpRenderTree every n tests (default: $testsPerDumpTool) -p|--pixel-tests Enable pixel tests --tolerance t Ignore image differences less than this percentage (default: $tolerance) --platform Override the detected platform to use for tests and results (default: $platform) @@ -207,16 +224,17 @@ Usage: $programName [options] [testdir|testpath ...] --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 + --repeat-each n Number of times to run each test (e.g. AAABBBCCC) --reverse Run the tests in reverse alphabetical order --root Path to root tools build --[no-]sample-on-timeout Run sample on timeout (default: $sampleDefault) (Mac OS X only) - -1|--singly Isolate each test case run (implies --verbose) + -1|--singly Isolate each test case run (implies --nthly 1 --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) + --ignore-metrics Ignore metrics in tests --[no-]strip-editing-callbacks Remove editing callbacks from expected results -t|--threaded Run a concurrent JavaScript thead with each test --timeout t Sets the number of seconds before a test times out (default: $timeoutSeconds) @@ -229,38 +247,41 @@ EOF setConfiguration(); my $getOptionsResult = GetOptions( + 'add-platform-exceptions' => \$addPlatformExceptions, 'complex-text' => \$complexText, + 'exit-after-n-failures=i' => \$exitAfterNFailures, 'guard-malloc|g' => \$guardMalloc, - 'help' => \$showHelp, + 'help|h' => \$showHelp, 'http!' => \$testHTTP, + 'ignore-metrics!' => \$ignoreMetrics, 'ignore-tests|i=s' => \$ignoreTests, + 'iterations=i' => \$iterations, 'launch-safari!' => \$launchSafari, 'leaks|l' => \$shouldCheckLeaks, + 'merge-leak-depth|m:5' => \$mergeDepth, + 'new-test-results!' => \$generateNewResults, + 'nthly=i' => \$testsPerDumpTool, 'pixel-tests|p' => \$pixelTests, 'platform=s' => \$platform, 'port=i' => \$httpdPort, 'quiet|q' => \$quiet, + 'random' => \$randomizeTests, + 'repeat-each=i' => \$repeatEach, 'reset-results' => \$resetResults, - 'new-test-results!' => \$generateNewResults, 'results-directory|o=s' => \$testResultsDirectory, + 'reverse' => \$reverseTests, + 'root=s' => \$root, + 'sample-on-timeout!' => \$runSample, 'singly|1' => sub { $testsPerDumpTool = 1; }, - 'nthly=i' => \$testsPerDumpTool, 'skipped=s' => \&validateSkippedArg, 'slowest' => \$report10Slowest, - 'threaded|t' => \$threaded, - 'tolerance=f' => \$tolerance, - 'verbose|v' => \$verbose, - 'valgrind' => \$useValgrind, - 'sample-on-timeout!' => \$runSample, - 'strict' => \$strictTesting, 'strip-editing-callbacks!' => \$stripEditingCallbacks, - 'random' => \$randomizeTests, - 'reverse' => \$reverseTests, - 'root=s' => \$root, - 'add-platform-exceptions' => \$addPlatformExceptions, - 'merge-leak-depth|m:5' => \$mergeDepth, + 'threaded|t' => \$threaded, 'timeout=i' => \$timeoutSeconds, + 'tolerance=f' => \$tolerance, 'use-remote-links-to-tests' => \$useRemoteLinksToTests, + 'valgrind' => \$useValgrind, + 'verbose|v' => \$verbose, ); if (!$getOptionsResult || $showHelp) { @@ -275,8 +296,6 @@ my $skippedOnly = $treatSkipped eq "only"; my $configuration = configuration(); -$testsPerDumpTool = 1000 if !$testsPerDumpTool; - $verbose = 1 if $testsPerDumpTool == 1; if ($shouldCheckLeaks && $testsPerDumpTool > 1000) { @@ -286,8 +305,8 @@ if ($shouldCheckLeaks && $testsPerDumpTool > 1000) { # Stack logging does not play well with QuickTime on Tiger (rdar://problem/5537157) $testMedia = 0 if $shouldCheckLeaks && isTiger(); -# Generating remote links causes a lot of unnecessary spew on GTK and Qt build bot -$useRemoteLinksToTests = 0 if (isGtk() || isQt()); +# Generating remote links causes a lot of unnecessary spew on GTK build bot +$useRemoteLinksToTests = 0 if isGtk(); setConfigurationProductDir(Cwd::abs_path($root)) if (defined($root)); my $productDir = productDir(); @@ -297,10 +316,30 @@ $productDir .= "/Programs" if isGtk(); chdirWebKit(); if (!defined($root)) { - # Push the parameters to build-dumprendertree as an array + print STDERR "Running build-dumprendertree\n"; + + local *DEVNULL; + my ($childIn, $childOut, $childErr); + if ($quiet) { + open(DEVNULL, ">", File::Spec->devnull) or die "Failed to open /dev/null"; + $childOut = ">&DEVNULL"; + $childErr = ">&DEVNULL"; + } else { + # When not quiet, let the child use our stdout/stderr. + $childOut = ">&STDOUT"; + $childErr = ">&STDERR"; + } + my @args = argumentsForConfiguration(); + my $buildProcess = open3($childIn, $childOut, $childErr, "WebKitTools/Scripts/build-dumprendertree", @args) or die "Failed to run build-dumprendertree"; + close($childIn); + waitpid $buildProcess, 0; + my $buildResult = $?; + close($childOut); + close($childErr); + + close DEVNULL if ($quiet); - my $buildResult = system "WebKitTools/Scripts/build-dumprendertree", @args; if ($buildResult) { print STDERR "Compiling DumpRenderTree failed!\n"; exit exitStatus($buildResult); @@ -320,7 +359,7 @@ checkFrameworks() unless isCygwin(); if (isAppleMacWebKit()) { push @INC, $productDir; - eval 'use DumpRenderTreeSupport;'; + require DumpRenderTreeSupport; } my $layoutTestsName = "LayoutTests"; @@ -351,16 +390,17 @@ if ($pixelTests) { } } -my @tests = (); -my %testType = (); - system "ln", "-s", $testDirectory, "/tmp/LayoutTests" unless -x "/tmp/LayoutTests"; -my %ignoredFiles = (); +my %ignoredFiles = ( "results.html" => 1 ); my %ignoredDirectories = map { $_ => 1 } qw(platform); -my %ignoredLocalDirectories = map { $_ => 1 } qw(.svn _svn resources); +my %ignoredLocalDirectories = map { $_ => 1 } qw(.svn _svn resources script-tests); my %supportedFileExtensions = map { $_ => 1 } qw(html shtml xml xhtml pl php); +if (!checkWebCoreMathMLSupport(0)) { + $ignoredDirectories{'mathml'} = 1; +} + # FIXME: We should fix webkitdirs.pm:hasSVG/WMLSupport() to do the correct feature detection for Cygwin. if (checkWebCoreSVGSupport(0)) { $supportedFileExtensions{'svg'} = 1; @@ -388,6 +428,10 @@ if (!checkWebCore3DRenderingSupport(0)) { $ignoredDirectories{'transforms/3d'} = 1; } +if (!checkWebCore3DCanvasSupport(0)) { + $ignoredDirectories{'fast/canvas/webgl'} = 1; +} + if (checkWebCoreWMLSupport(0)) { $supportedFileExtensions{'wml'} = 1; } else { @@ -404,105 +448,13 @@ if (!checkWebCoreWCSSSupport(0)) { $ignoredDirectories{'fast/wcss'} = 1; } -if ($ignoreTests) { - processIgnoreTests($ignoreTests, "ignore-tests"); -} - -sub fileShouldBeIgnored { - my($filePath) = @_; - foreach my $ignoredDir (keys %ignoredDirectories) { - if ($filePath =~ m/^$ignoredDir/) { - return 1; - } - } - return 0; -} - -if (!$ignoreSkipped) { - foreach my $level (@platformTestHierarchy) { - if (open SKIPPED, "<", "$level/Skipped") { - if ($verbose) { - 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) { - if (!&fileShouldBeIgnored($skipped)) { - push(@ARGV, $skipped); - } elsif ($verbose) { - print " $skipped\n"; - } - } else { - if ($verbose) { - print " $skipped\n"; - } - processIgnoreTests($skipped, "Skipped"); - } - } - } - close SKIPPED; - } - } -} - +processIgnoreTests($ignoreTests, "ignore-tests") if $ignoreTests; +readSkippedFiles() unless $ignoreSkipped; -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 (@platformTestHierarchy) { - 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 (@platformTestHierarchy) { - find({ preprocess => $directoryFilter, wanted => $fileFilter }, $level); - } -} +my @tests = findTestsToRun(); die "no tests to run\n" if !@tests; -@tests = sort pathcmp @tests; - my %counts; my %tests; my %imagesPresent; @@ -537,20 +489,31 @@ my $isHttpdOpen = 0; sub catch_pipe { $dumpToolCrashed = 1; } $SIG{"PIPE"} = "catch_pipe"; -print "Testing ", scalar @tests, " test cases.\n"; +print "Testing ", scalar @tests, " test cases"; +print " $iterations times" if ($iterations > 1); +print ", repeating each test $repeatEach times" if ($repeatEach > 1); +print ".\n"; + my $overallStartTime = time; my %expectedResultPaths; -# Reverse the tests -@tests = reverse @tests if $reverseTests; - -# Shuffle the array -@tests = shuffle(@tests) if $randomizeTests; +my @originalTests = @tests; +# Add individual test repetitions +if ($repeatEach > 1) { + @tests = (); + foreach my $test (@originalTests) { + for (my $i = 0; $i < $repeatEach; $i++) { + push(@tests, $test); + } + } +} +# Add test set repetitions +for (my $i = 1; $i < $iterations; $i++) { + push(@tests, @originalTests); +} for my $test (@tests) { - next if $test eq 'results.html'; - my $newDumpTool = not $isDumpToolOpen; openDumpTool(); @@ -648,14 +611,12 @@ for my $test (@tests) { # The first block is the output of the test (in text, RenderTree or other formats). # The second block is for optional pixel data in PNG format, and may be empty if # pixel tests are not being run, or the test does not dump pixels (e.g. text tests). - - my $actualRead = readFromDumpToolWithTimer(IN); - my $errorRead = readFromDumpToolWithTimer(ERROR, $actualRead->{status} eq "timedOut"); + my $readResults = readFromDumpToolWithTimer(IN, ERROR); - my $actual = $actualRead->{output}; - my $error = $errorRead->{output}; + my $actual = $readResults->{output}; + my $error = $readResults->{error}; - $expectedExtension = $actualRead->{extension}; + $expectedExtension = $readResults->{extension}; my $expectedFileName = "$base-$expectedTag.$expectedExtension"; my $isText = isTextOnlyTest($actual); @@ -663,12 +624,12 @@ for my $test (@tests) { my $expectedDir = expectedDirectoryForTest($base, $isText, $expectedExtension); $expectedResultPaths{$base} = "$expectedDir/$expectedFileName"; - unless ($actualRead->{status} eq "success" && $errorRead->{status} eq "success") { - my $crashed = $actualRead->{status} eq "crashed" || $errorRead->{status} eq "crashed"; + unless ($readResults->{status} eq "success") { + my $crashed = $readResults->{status} eq "crashed"; testCrashedOrTimedOut($test, $base, $crashed, $actual, $error); countFinishedTest($test, $base, $crashed ? "crash" : "timedout", 0); next; - } + } $durations{$test} = time - $startTime if $report10Slowest; @@ -682,15 +643,9 @@ for my $test (@tests) { } close EXPECTED; } - my $expectedMac; - if (!isAppleMacWebKit() && $strictTesting && !$isText) { - if (!$resetResults && open EXPECTED, "<", "$testDirectory/platform/mac/$expectedFileName") { - $expectedMac = ""; - while (<EXPECTED>) { - $expectedMac .= $_; - } - close EXPECTED; - } + + if ($ignoreMetrics && !$isText && defined $expected) { + ($actual, $expected) = stripMetrics($actual, $expected); } if ($shouldCheckLeaks && $testsPerDumpTool == 1) { @@ -776,57 +731,6 @@ for my $test (@tests) { } } - if (!isAppleMacWebKit() && $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) { - writeToFile("/tmp/actual.txt", $simplified_actual); - writeToFile("/tmp/expected.txt", $expectedMac); - 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"; testCrashedOrTimedOut($test, $base, 1, $actual, $error); @@ -971,6 +875,17 @@ for my $test (@tests) { } countFinishedTest($test, $base, $result, $isText); + + # --reset-results does not check pass vs. fail, so exitAfterNFailures makes no sense with --reset-results. + if ($exitAfterNFailures && !$resetResults) { + my $passCount = $counts{match} || 0; # $counts{match} will be undefined if we've not yet passed a test (e.g. the first test fails). + my $failureCount = $count - $passCount; # "Failure" here includes new tests, timeouts, crashes, etc. + if ($failureCount >= $exitAfterNFailures) { + print "\nExiting early after $failureCount failures. $count tests run."; + closeDumpTool(); + last; + } + } } printf "\n%0.2fs total testing time\n", (time - $overallStartTime) . ""; @@ -990,8 +905,7 @@ if ($isDiffToolOpen && $shouldCheckLeaks) { if ($totalLeaks) { if ($mergeDepth) { parseLeaksandPrintUniqueLeaks(); - } - else { + } else { print "\nWARNING: $totalLeaks total leaks found!\n"; print "See above for individual leaks results.\n" if ($leaksOutputFileNumber > 2); } @@ -1025,31 +939,7 @@ if ($resetResults || ($counts{match} && $counts{match} == $count)) { exit; } - -my %text = ( - match => "succeeded", - mismatch => "had incorrect layout", - new => "were new", - timedout => "timed out", - crash => "crashed", - error => "had stderr output" -); - -for my $type ("match", "mismatch", "new", "timedout", "crash", "error") { - 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; - } -} +printResults(); mkpath $testResultsDirectory; @@ -1060,6 +950,10 @@ print HTML "<title>Layout Test Results</title>\n"; print HTML "</head>\n"; print HTML "<body>\n"; +if ($ignoreMetrics) { + print HTML "<h4>Tested with metrics ignored.</h4>"; +} + print HTML htmlForResultsSection(@{$tests{mismatch}}, "Tests where results did not match expected results", \&linksForMismatchTest); print HTML htmlForResultsSection(@{$tests{timedout}}, "Tests that timed out", \&linksForErrorTest); print HTML htmlForResultsSection(@{$tests{crash}}, "Tests that caused the DumpRenderTree tool to crash", \&linksForErrorTest); @@ -1143,6 +1037,13 @@ sub countAndPrintLeaks($$$) ); } + if (isSnowLeopard()) { + push @callStacksToExclude, ( + "readMakerNoteProps", # <rdar://problem/7156432> leak in ImageIO + "QTKitMovieControllerView completeUISetup", # <rdar://problem/7155156> leak in QTKit + ); + } + my $leaksTool = sourceDir() . "/WebKitTools/Scripts/run-leaks"; my $excludeString = "--exclude-callstack '" . (join "' --exclude-callstack '", @callStacksToExclude) . "'"; $excludeString .= " --exclude-type '" . (join "' --exclude-type '", @typesToExclude) . "'" if @typesToExclude; @@ -1172,7 +1073,7 @@ sub countAndPrintLeaks($$$) writeToFile($leaksFilePath, $leaksOutput); - push( @leaksFilenames, $leaksFilePath ); + push @leaksFilenames, $leaksFilePath; } return $adjustedCount; @@ -1414,6 +1315,9 @@ sub openHTTPDIfNeeded() } elsif (isDebianBased()) { $httpdPath = "/usr/sbin/apache2"; $httpdConfig = "$testDirectory/http/conf/apache2-debian-httpd.conf"; + } elsif (isFedoraBased()) { + $httpdPath = "/usr/sbin/httpd"; + $httpdConfig = "$testDirectory/http/conf/fedora-httpd.conf"; } else { $httpdConfig = "$testDirectory/http/conf/httpd.conf"; $httpdConfig = "$testDirectory/http/conf/apache2-httpd.conf" if `$httpdPath -v` =~ m|Apache/2|; @@ -1476,7 +1380,8 @@ sub fileNameWithNumber($$) return $base; } -sub processIgnoreTests($$) { +sub processIgnoreTests($$) +{ my @ignoreList = split(/\s*,\s*/, shift); my $listName = shift; @@ -1541,7 +1446,8 @@ sub expectedDirectoryForTest($;$;$) return $isText ? $expectedDirectory : $platformResultHierarchy[$#platformResultHierarchy]; } -sub countFinishedTest($$$$) { +sub countFinishedTest($$$$) +{ my ($test, $base, $result, $isText) = @_; if (($count + 1) % $testsPerDumpTool == 0 || $count == $#tests) { @@ -1563,7 +1469,6 @@ sub countFinishedTest($$$$) { $count++; $counts{$result}++; push @{$tests{$result}}, $test; - $testType{$test} = $isText; } sub testCrashedOrTimedOut($$$$$) @@ -1833,6 +1738,9 @@ sub buildPlatformResultHierarchy() for (; $i < @macPlatforms; $i++) { push @platforms, $macPlatforms[$i]; } + } elsif ($platform =~ /^qt-/) { + push @platforms, $platform; + push @platforms, "qt"; } else { @platforms = $platform; } @@ -1854,7 +1762,8 @@ sub buildPlatformTestHierarchy(@) return ($platformHierarchy[0], $platformHierarchy[$#platformHierarchy]); } -sub epiloguesAndPrologues($$) { +sub epiloguesAndPrologues($$) +{ my ($lastDirectory, $directory) = @_; my @lastComponents = split('/', $lastDirectory); my @components = split('/', $directory); @@ -1890,7 +1799,8 @@ sub epiloguesAndPrologues($$) { return @result; } -sub parseLeaksandPrintUniqueLeaks() { +sub parseLeaksandPrintUniqueLeaks() +{ return unless @leaksFilenames; my $mergedFilenames = join " ", @leaksFilenames; @@ -1926,11 +1836,12 @@ sub extensionForMimeType($) } # Read up to the first #EOF (the content block of the test), or until detecting crashes or timeouts. -sub readFromDumpToolWithTimer(*;$) +sub readFromDumpToolWithTimer(**) { - my ($fh, $dontWaitForTimeOut) = @_; + my ($fhIn, $fhError) = @_; - setFileHandleNonBlocking($fh, 1); + setFileHandleNonBlocking($fhIn, 1); + setFileHandleNonBlocking($fhError, 1); my $maximumSecondsWithoutOutput = $timeoutSeconds; $maximumSecondsWithoutOutput *= 10 if $guardMalloc; @@ -1939,11 +1850,14 @@ sub readFromDumpToolWithTimer(*;$) my $timeOfLastSuccessfulRead = time; my @output = (); + my @error = (); my $status = "success"; my $mimeType = "text/plain"; # We don't have a very good way to know when the "headers" stop # and the content starts, so we use this as a hack: my $haveSeenContentType = 0; + my $haveSeenEofIn = 0; + my $haveSeenEofError = 0; while (1) { if (time - $timeOfLastSuccessfulRead > $maximumSecondsWithoutOutput) { @@ -1951,37 +1865,48 @@ sub readFromDumpToolWithTimer(*;$) last; } - my $line = readline($fh); - if (!defined($line)) { + # Once we've seen the EOF, we must not read anymore. + my $lineIn = readline($fhIn) unless $haveSeenEofIn; + my $lineError = readline($fhError) unless $haveSeenEofError; + if (!defined($lineIn) && !defined($lineError)) { + last if ($haveSeenEofIn && $haveSeenEofError); + if ($! != EAGAIN) { $status = "crashed"; last; } - if ($dontWaitForTimeOut) { - last; - } - # No data ready usleep($microsecondsToWaitBeforeReadingAgain); next; } $timeOfLastSuccessfulRead = time; - - if (!$haveSeenContentType && $line =~ /^Content-Type: (\S+)$/) { - $mimeType = $1; - $haveSeenContentType = 1; - next; + + if (defined($lineIn)) { + if (!$haveSeenContentType && $lineIn =~ /^Content-Type: (\S+)$/) { + $mimeType = $1; + $haveSeenContentType = 1; + } elsif ($lineIn =~ /#EOF/) { + $haveSeenEofIn = 1; + } else { + push @output, $lineIn; + } + } + if (defined($lineError)) { + if ($lineError =~ /#EOF/) { + $haveSeenEofError = 1; + } else { + push @error, $lineError; + } } - last if ($line =~ /#EOF/); - - push @output, $line; } - setFileHandleNonBlocking($fh, 0); + setFileHandleNonBlocking($fhIn, 0); + setFileHandleNonBlocking($fhError, 0); return { output => join("", @output), + error => join("", @error), status => $status, mimeType => $mimeType, extension => extensionForMimeType($mimeType) @@ -2016,3 +1941,167 @@ sub sampleDumpTool() my $outputFile = "$outputDirectory/HangReport.txt"; system "/usr/bin/sample", $dumpToolPID, qw(10 10 -file), $outputFile; } + +sub stripMetrics($$) +{ + my ($actual, $expected) = @_; + + foreach my $result ($actual, $expected) { + $result =~ s/at \(-?[0-9]+,-?[0-9]+\) *//g; + $result =~ s/size -?[0-9]+x-?[0-9]+ *//g; + $result =~ s/text run width -?[0-9]+: //g; + $result =~ s/text run width -?[0-9]+ [a-zA-Z ]+: //g; + $result =~ s/RenderButton {BUTTON} .*/RenderButton {BUTTON}/g; + $result =~ s/RenderImage {INPUT} .*/RenderImage {INPUT}/g; + $result =~ s/RenderBlock {INPUT} .*/RenderBlock {INPUT}/g; + $result =~ s/RenderTextControl {INPUT} .*/RenderTextControl {INPUT}/g; + $result =~ s/\([0-9]+px/px/g; + $result =~ s/ *" *\n +" */ /g; + $result =~ s/" +$/"/g; + + $result =~ s/- /-/g; + $result =~ s/\n( *)"\s+/\n$1"/g; + $result =~ s/\s+"\n/"\n/g; + $result =~ s/scrollWidth [0-9]+/scrollWidth/g; + $result =~ s/scrollHeight [0-9]+/scrollHeight/g; + } + + return ($actual, $expected); +} + +sub fileShouldBeIgnored +{ + my ($filePath) = @_; + foreach my $ignoredDir (keys %ignoredDirectories) { + if ($filePath =~ m/^$ignoredDir/) { + return 1; + } + } + return 0; +} + +sub readSkippedFiles +{ + foreach my $level (@platformTestHierarchy) { + if (open SKIPPED, "<", "$level/Skipped") { + if ($verbose) { + 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) { + if (!&fileShouldBeIgnored($skipped)) { + push(@ARGV, $skipped); + } elsif ($verbose) { + print " $skipped\n"; + } + } else { + if ($verbose) { + print " $skipped\n"; + } + processIgnoreTests($skipped, "Skipped"); + } + } + } + close SKIPPED; + } + } +} + +my @testsToRun; + +sub directoryFilter +{ + return () if exists $ignoredLocalDirectories{basename($File::Find::dir)}; + return () if exists $ignoredDirectories{File::Spec->abs2rel($File::Find::dir, $testDirectory)}; + return @_; +} + +sub fileFilter +{ + my $filename = $_; + if ($filename =~ /\.([^.]+)$/) { + if (exists $supportedFileExtensions{$1}) { + my $path = File::Spec->abs2rel(catfile($File::Find::dir, $filename), $testDirectory); + push @testsToRun, $path if !exists $ignoredFiles{$path}; + } + } +} + +sub findTestsToRun +{ + @testsToRun = (); + + 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 @testsToRun, $test; + } + } elsif (-d $fullPath) { + find({ preprocess => \&directoryFilter, wanted => \&fileFilter }, $fullPath); + for my $level (@platformTestHierarchy) { + 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 (@platformTestHierarchy) { + find({ preprocess => \&directoryFilter, wanted => \&fileFilter }, $level); + } + } + + @testsToRun = sort pathcmp @testsToRun; + + # Reverse the tests + @testsToRun = reverse @testsToRun if $reverseTests; + + # Shuffle the array + @testsToRun = shuffle(@testsToRun) if $randomizeTests; + + return @testsToRun; +} + +sub printResults +{ + my %text = ( + match => "succeeded", + mismatch => "had incorrect layout", + new => "were new", + timedout => "timed out", + crash => "crashed", + error => "had stderr output" + ); + + for my $type ("match", "mismatch", "new", "timedout", "crash", "error") { + my $typeCount = $counts{$type}; + next unless $typeCount; + my $typeText = $text{$type}; + my $message; + if ($typeCount == 1) { + $typeText =~ s/were/was/; + $message = sprintf "1 test case (%d%%) %s\n", 1 * 100 / $count, $typeText; + } else { + $message = sprintf "%d test cases (%d%%) %s\n", $typeCount, $typeCount * 100 / $count, $typeText; + } + $message =~ s-\(0%\)-(<1%)-; + print $message; + } +} diff --git a/WebKitTools/Scripts/run-webkit-unittests b/WebKitTools/Scripts/run-webkit-unittests index 83aaea9..8d0ef1d 100755 --- a/WebKitTools/Scripts/run-webkit-unittests +++ b/WebKitTools/Scripts/run-webkit-unittests @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # Copyright (c) 2009 Google Inc. All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -30,9 +30,12 @@ import unittest from modules.bugzilla_unittest import * -from modules.commiters_unittest import * +from modules.buildbot_unittest import * +from modules.changelogs_unittest import * +from modules.committers_unittest import * from modules.cpp_style_unittest import * from modules.diff_parser_unittest import * +from modules.logging_unittest import * from modules.scm_unittest import * if __name__ == "__main__": diff --git a/WebKitTools/Scripts/sunspider-compare-results b/WebKitTools/Scripts/sunspider-compare-results index d219896..ce87a23 100755 --- a/WebKitTools/Scripts/sunspider-compare-results +++ b/WebKitTools/Scripts/sunspider-compare-results @@ -67,7 +67,7 @@ sub buildJSC { if (!defined($root)){ chdirWebKit(); - my $buildResult = system "WebKitTools/Scripts/build-jsc", "--" . $configuration; + my $buildResult = system currentPerlPath(), "WebKitTools/Scripts/build-jsc", "--" . $configuration; if ($buildResult) { print STDERR "Compiling jsc failed!\n"; exit WEXITSTATUS($buildResult); @@ -124,4 +124,4 @@ my @args = ("--shell", $jscPath); push @args, "--ubench" if $ubench; push @args, "--v8" if $v8; -exec "./sunspider-compare-results", @args, @ARGV; +exec currentPerlPath(), "./sunspider-compare-results", @args, @ARGV; diff --git a/WebKitTools/Scripts/svn-apply b/WebKitTools/Scripts/svn-apply index 4b88a37..19c8c56 100755 --- a/WebKitTools/Scripts/svn-apply +++ b/WebKitTools/Scripts/svn-apply @@ -1,6 +1,7 @@ #!/usr/bin/perl -w # Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved. +# Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au> # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -80,6 +81,7 @@ sub isDirectoryEmptyForRemoval($); sub patch($); sub removeDirectoriesIfNeeded(); sub setChangeLogDateAndReviewer($$); +sub removeEOL($); sub svnStatus($); # These should be replaced by an scm class/module: @@ -109,10 +111,6 @@ if (!$optionParseSuccess || $showHelp) { exit 1; } -my $isGit = isGitDirectory("."); -my $isSVN = isSVNDirectory("."); -$isSVN || $isGit || die "Couldn't determine your version control system."; - my %removeDirectoryIgnoreList = ( '.' => 1, '..' => 1, @@ -121,6 +119,11 @@ my %removeDirectoryIgnoreList = ( '_svn' => 1, ); +my $globalExitCode = 0; + +my $pathScriptWasRunFrom = Cwd::getcwd(); +my $pathForRepositoryRoot = determineVCSRoot(); + my %checkedDirectories; my %copiedFiles; my @patches; @@ -172,7 +175,7 @@ if ($patch && !$copiedFromPath) { } if ($merge) { - die "--merge is currently only supported for SVN" unless $isSVN; + die "--merge is currently only supported for SVN" unless isSVN(); # How do we handle Git patches applied to an SVN checkout here? for my $file (sort keys %versions) { print "Getting version $versions{$file} of $file\n"; @@ -192,7 +195,7 @@ for $patch (@patches) { removeDirectoriesIfNeeded(); -exit 0; +exit $globalExitCode; sub addDirectoriesIfNeeded($) { @@ -226,16 +229,22 @@ sub addDirectoriesIfNeeded($) sub applyPatch($$;$) { my ($patch, $fullPath, $options) = @_; + chdir $pathForRepositoryRoot; $options = [] if (! $options); + push @{$options}, "--force" if $force; my $command = "patch " . join(" ", "-p0", @{$options}); open PATCH, "| $command" or die "Failed to patch $fullPath\n"; print PATCH $patch; close PATCH; + chdir $pathScriptWasRunFrom; my $exitCode = $? >> 8; - if ($exitCode != 0) { - print "patch -p0 \"$fullPath\" returned $exitCode. Pass --force to ignore patch failures.\n"; - exit($exitCode); + if ($exitCode) { + if (!$force) { + print "$command \"$fullPath\" returned $exitCode. Pass --force to ignore patch failures.\n"; + exit $exitCode; + } + $globalExitCode = $exitCode; } } @@ -320,7 +329,10 @@ sub gitdiff2svndiff($) sub handleBinaryChange($$) { my ($fullPath, $contents) = @_; - if ($contents =~ m#((\n[A-Za-z0-9+/]{76})+\n[A-Za-z0-9+/=]{4,76}\n)#) { + # [A-Za-z0-9+/] is the class of allowed base64 characters. + # One or more lines, at most 76 characters in length. + # The last line is allowed to have up to two '=' characters at the end (to signify padding). + if ($contents =~ m#((\n[A-Za-z0-9+/]{76})*\n[A-Za-z0-9+/]{2,74}?[A-Za-z0-9+/=]{2}\n)#) { # Addition or Modification open FILE, ">", $fullPath or die; print FILE decode_base64($1); @@ -369,7 +381,7 @@ sub patch($) my $addition = 0; my $isBinary = 0; - $addition = 1 if ($patch =~ /\n--- .+\(revision 0\)\r?\n/ || $patch =~ /\n@@ -0,0 .* @@/); + $addition = 1 if ($patch =~ /\n--- .+\(revision 0\)\r?\n/ || $patch =~ /\n@@ -0,0 .* @@/) && !exists($copiedFiles{$fullPath}); $deletion = 1 if $patch =~ /\n@@ .* \+0,0 @@/; $isBinary = 1 if $patch =~ /\nCannot display: file marked as a binary type\./; @@ -401,7 +413,7 @@ sub patch($) unlink("$fullPath.orig") if -e "$fullPath.orig" && checksum($fullPath) eq checksum("$fullPath.orig"); scmAdd($fullPath); # What is this for? - system "svn", "stat", "$fullPath.orig" if $isSVN && -e "$fullPath.orig"; + system "svn", "stat", "$fullPath.orig" if isSVN() && -e "$fullPath.orig"; } } } @@ -435,6 +447,14 @@ sub setChangeLogDateAndReviewer($$) return $patch; } +sub removeEOL($) +{ + my ($line) = @_; + + $line =~ s/[\r\n]+$//g; + return $line; +} + sub svnStatus($) { my ($fullPath) = @_; @@ -448,10 +468,10 @@ sub svnStatus($) my $normalizedFullPath = File::Spec->catdir(File::Spec->splitdir($fullPath)); while (<SVN>) { # Input may use a different EOL sequence than $/, so avoid chomp. - $_ =~ s/[\r\n]+$//g; + $_ = removeEOL($_); my $normalizedStatPath = File::Spec->catdir(File::Spec->splitdir(substr($_, 7))); if ($normalizedFullPath eq $normalizedStatPath) { - $svnStatus = $_; + $svnStatus = "$_\n"; last; } } @@ -461,7 +481,7 @@ sub svnStatus($) } else { # Files will have only one status returned. - $svnStatus = <SVN>; + $svnStatus = removeEOL(<SVN>) . "\n"; } close SVN; return $svnStatus; @@ -472,10 +492,10 @@ sub svnStatus($) sub scmWillDeleteFile($) { my ($path) = @_; - if ($isSVN) { + if (isSVN()) { my $svnOutput = svnStatus($path); return 1 if $svnOutput && substr($svnOutput, 0, 1) eq "D"; - } elsif ($isGit) { + } elsif (isGit()) { my $gitOutput = `git diff-index --name-status HEAD -- $path`; return 1 if $gitOutput && substr($gitOutput, 0, 1) eq "D"; } @@ -485,7 +505,7 @@ sub scmWillDeleteFile($) sub scmKnowsOfFile($) { my ($path) = @_; - if ($isSVN) { + if (isSVN()) { my $svnOutput = svnStatus($path); # This will match more than intended. ? might not be the first field in the status if ($svnOutput && $svnOutput =~ m#\?\s+$path\n#) { @@ -493,7 +513,7 @@ sub scmKnowsOfFile($) } # This does not handle errors well. return 1; - } elsif ($isGit) { + } elsif (isGit()) { `git ls-files --error-unmatch -- $path`; my $exitCode = $? >> 8; return $exitCode == 0; @@ -503,9 +523,9 @@ sub scmKnowsOfFile($) sub scmCopy($$) { my ($source, $destination) = @_; - if ($isSVN) { + if (isSVN()) { system "svn", "copy", $source, $destination; - } elsif ($isGit) { + } elsif (isGit()) { system "cp", $source, $destination; system "git", "add", $destination; } @@ -514,9 +534,9 @@ sub scmCopy($$) sub scmAdd($) { my ($path) = @_; - if ($isSVN) { + if (isSVN()) { system "svn", "add", $path; - } elsif ($isGit) { + } elsif (isGit()) { system "git", "add", $path; } } @@ -524,7 +544,7 @@ sub scmAdd($) sub scmRemove($) { my ($path) = @_; - if ($isSVN) { + if (isSVN()) { # SVN is very verbose when removing directories. Squelch all output except the last line. my $svnOutput; open SVN, "svn rm --force '$path' |" or die "svn rm --force '$path' failed!"; @@ -534,7 +554,7 @@ sub scmRemove($) } close SVN; print $svnOutput if $svnOutput; - } elsif ($isGit) { + } elsif (isGit()) { system "git", "rm", "--force", $path; } } diff --git a/WebKitTools/Scripts/svn-create-patch b/WebKitTools/Scripts/svn-create-patch index 75c82bc..3f40783 100755 --- a/WebKitTools/Scripts/svn-create-patch +++ b/WebKitTools/Scripts/svn-create-patch @@ -77,14 +77,15 @@ sub testfilecmp($$); $ENV{'LC_ALL'} = 'C'; my $showHelp; -my $svnVersion = `svn --version --quiet`; +my $ignoreChangelogs = 0; my $devNull = File::Spec->devnull(); my $result = GetOptions( "help" => \$showHelp, + "ignore-changelogs" => \$ignoreChangelogs ); if (!$result || $showHelp) { - print STDERR basename($0) . " [-h|--help] [svndir1 [svndir2 ...]]\n"; + print STDERR basename($0) . " [-h|--help] [--ignore-changelogs] [svndir1 [svndir2 ...]]\n"; exit 1; } @@ -156,7 +157,7 @@ sub findBaseUrl($) my $baseUrl; open INFO, "svn info '$infoPath' |" or die; while (<INFO>) { - if (/^URL: (.+)/) { + if (/^URL: (.+?)[\r\n]*$/) { $baseUrl = $1; } } @@ -200,7 +201,7 @@ sub findSourceFileAndRevision($) my $sourceRevision; open INFO, "svn info '$file' |" or die; while (<INFO>) { - if (/^Copied From URL: (.+)/) { + if (/^Copied From URL: (.+?)[\r\n]*$/) { $sourceFile = File::Spec->abs2rel($1, $baseUrl); } elsif (/^Copied From Rev: ([0-9]+)/) { $sourceRevision = $1; @@ -265,6 +266,11 @@ sub generateDiff($$) { my ($fileData, $prefix) = @_; my $file = File::Spec->catdir($prefix, $fileData->{path}); + + if ($ignoreChangelogs && basename($file) eq "ChangeLog") { + return; + } + my $patch; if ($fileData->{modificationType} eq "additionWithHistory") { manufacturePatchForAdditionWithHistory($fileData); @@ -292,7 +298,7 @@ sub generateFileList($\%) $line =~ s/[\r\n]+$//g; my $stat; my $path; - if (eval "v$svnVersion" ge v1.6) { + if (isSVNVersion16OrNewer()) { $stat = substr($line, 0, 8); $path = substr($line, 8); } else { diff --git a/WebKitTools/Scripts/svn-unapply b/WebKitTools/Scripts/svn-unapply index 964b51e..a4cec9a 100755 --- a/WebKitTools/Scripts/svn-unapply +++ b/WebKitTools/Scripts/svn-unapply @@ -1,6 +1,7 @@ #!/usr/bin/perl -w # Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved. +# Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au> # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -65,11 +66,16 @@ use File::Spec; use File::Temp qw(tempfile); use Getopt::Long; +use FindBin; +use lib $FindBin::Bin; +use VCSUtils; + sub checksum($); sub fixChangeLogPatch($); sub gitdiff2svndiff($); sub patch($); sub revertDirectories(); +sub removeEOL($); sub svnStatus($); sub unapplyPatch($$;$); sub unsetChangeLogDate($$); @@ -80,6 +86,9 @@ if (!GetOptions("help!" => \$showHelp) || $showHelp) { exit 1; } +my $pathScriptWasRunFrom = Cwd::getcwd(); +my $pathForRepositoryRoot = determineVCSRoot(); + my @copiedFiles; my %directoriesToCheck; @@ -133,7 +142,9 @@ for $patch (@copiedFiles) { patch($patch); } -revertDirectories(); +if (isSVN()) { + revertDirectories(); +} exit 0; @@ -289,6 +300,7 @@ sub patch($) sub revertDirectories() { + chdir $pathForRepositoryRoot; my %checkedDirectories; foreach my $path (reverse sort keys %directoriesToCheck) { my @dirs = File::Spec->splitdir($path); @@ -318,6 +330,14 @@ sub revertDirectories() } } +sub removeEOL($) +{ + my ($line) = @_; + + $line =~ s/[\r\n]+$//g; + return $line; +} + sub svnStatus($) { my ($fullPath) = @_; @@ -331,10 +351,10 @@ sub svnStatus($) my $normalizedFullPath = File::Spec->catdir(File::Spec->splitdir($fullPath)); while (<SVN>) { # Input may use a different EOL sequence than $/, so avoid chomp. - $_ =~ s/[\r\n]+$//g; + $_ = removeEOL($_); my $normalizedStatPath = File::Spec->catdir(File::Spec->splitdir(substr($_, 7))); if ($normalizedFullPath eq $normalizedStatPath) { - $svnStatus = $_; + $svnStatus = "$_\n"; last; } } @@ -344,7 +364,7 @@ sub svnStatus($) } else { # Files will have only one status returned. - $svnStatus = <SVN>; + $svnStatus = removeEOL(<SVN>) . "\n"; } close SVN; return $svnStatus; @@ -353,11 +373,13 @@ sub svnStatus($) sub unapplyPatch($$;$) { my ($patch, $fullPath, $options) = @_; + chdir $pathForRepositoryRoot; $options = [] if (! $options); my $command = "patch " . join(" ", "-p0", "-R", @{$options}); open PATCH, "| $command" or die "Failed to patch $fullPath: $!"; print PATCH $patch; close PATCH; + chdir $pathScriptWasRunFrom; } sub unsetChangeLogDate($$) diff --git a/WebKitTools/Scripts/update-sources-list.py b/WebKitTools/Scripts/update-sources-list.py index e565059..433d04a 100644..100755 --- a/WebKitTools/Scripts/update-sources-list.py +++ b/WebKitTools/Scripts/update-sources-list.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # Copyright (C) 2007 Kevin Ollivier All rights reserved. # diff --git a/WebKitTools/Scripts/update-webkit b/WebKitTools/Scripts/update-webkit index 5f72869..e562cc0 100755 --- a/WebKitTools/Scripts/update-webkit +++ b/WebKitTools/Scripts/update-webkit @@ -1,6 +1,7 @@ #!/usr/bin/perl -w -# Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. +# Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. +# Copyright (C) 2009 Google Inc. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -34,6 +35,7 @@ use lib $FindBin::Bin; use File::Basename; use File::Spec; use Getopt::Long; +use VCSUtils; use webkitdirs; sub runSvnUpdate(); @@ -43,6 +45,8 @@ sub normalizePath($); my $quiet = ''; my $showHelp; +determineIsChromium(); + my $getOptionsResult = GetOptions( 'h|help' => \$showHelp, 'q|quiet' => \$quiet, @@ -51,6 +55,7 @@ my $getOptionsResult = GetOptions( if (!$getOptionsResult || $showHelp) { print STDERR <<__END__; Usage: @{[ basename($0) ]} [options] + --chromium also update dependencies of the chromium port -h|--help show the help message -q|--quiet pass -q to svn update for quiet updates __END__ @@ -60,6 +65,9 @@ __END__ my @svnOptions = (); push @svnOptions, '-q' if $quiet; +# Don't prompt when using svn-1.6 or newer. +push @svnOptions, qw(--accept postpone) if isSVNVersion16OrNewer(); + chdirWebKit(); print "Updating OpenSource\n" unless $quiet; runSvnUpdate(); @@ -68,6 +76,8 @@ if (-d "../Internal") { chdir("../Internal"); print "Updating Internal\n" unless $quiet; runSvnUpdate(); +} elsif (isChromium()) { + system("perl", "WebKitTools/Scripts/update-webkit-chromium") == 0 or die $!; } elsif (isAppleWinWebKit()) { system("perl", "WebKitTools/Scripts/update-webkit-auxiliary-libs") == 0 or die; } @@ -80,7 +90,7 @@ sub runSvnUpdate() my @conflictedChangeLogs; while (my $line = <UPDATE>) { print $line; - $line =~ m/^C\s+(.*\S+)\s*$/; + $line =~ m/^C\s+(.+?)[\r\n]*$/; if ($1) { my $filename = normalizePath($1); push @conflictedChangeLogs, $filename if basename($filename) eq "ChangeLog"; diff --git a/WebKitTools/Scripts/update-webkit-chromium b/WebKitTools/Scripts/update-webkit-chromium new file mode 100644 index 0000000..a0cc19a --- /dev/null +++ b/WebKitTools/Scripts/update-webkit-chromium @@ -0,0 +1,51 @@ +#!/usr/bin/perl -w + +# Copyright (C) 2009 Google 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 the WebKit Chromium Port. + +# Check if gclient is installed. +if (not `gclient --version`) { + print STDERR "gclient is required for updating chromium dependencies.\n"; + print STDERR "Install depot_tools and add gclient to the environment\n"; + print STDERR "path. For more information, refer to:\n"; + print STDERR "http://dev.chromium.org/developers/how-tos/install-gclient\n"; + die; +} + +chdir("WebKit/chromium") or die $!; +if (! -e ".gclient") { + # If .gclient configuration file doesn't exist, create it. + print "Configuring gclient...\n"; + system("gclient", + "config", + "--spec=solutions=[{'name':'./','url':None}]") == 0 or die $!; +} + +# Execute gclient sync. +print "Updating chromium port dependencies using gclient...\n"; +system("gclient", "sync") == 0 or die $!; diff --git a/WebKitTools/Scripts/update-webkit-localizable-strings b/WebKitTools/Scripts/update-webkit-localizable-strings index 350bf21..1d1f413 100755 --- a/WebKitTools/Scripts/update-webkit-localizable-strings +++ b/WebKitTools/Scripts/update-webkit-localizable-strings @@ -43,4 +43,4 @@ my $exceptionsFile = "WebKit/StringsNotToBeLocalized.txt"; chdirWebKit(); system "sort -u $exceptionsFile -o $exceptionsFile"; -exec "extract-localizable-strings", $exceptionsFile, $fileToUpdate, @directoriesToScan; +exec "./WebKitTools/Scripts/extract-localizable-strings", $exceptionsFile, $fileToUpdate, @directoriesToScan; diff --git a/WebKitTools/Scripts/webkitdirs.pm b/WebKitTools/Scripts/webkitdirs.pm index d8ccd3a..d5177dd 100644 --- a/WebKitTools/Scripts/webkitdirs.pm +++ b/WebKitTools/Scripts/webkitdirs.pm @@ -1,4 +1,5 @@ # Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved. +# Copyright (C) 2009 Google Inc. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -28,8 +29,10 @@ use strict; use warnings; +use Config; use FindBin; use File::Basename; +use File::Spec; use POSIX; use VCSUtils; @@ -83,6 +86,15 @@ sub determineSourceDir $sourceDir = "$sourceDir/OpenSource" if -d "$sourceDir/OpenSource"; } +sub currentPerlPath() +{ + my $thisPerl = $^X; + if ($^O ne 'VMS') { + $thisPerl .= $Config{_exe} unless $thisPerl =~ m/$Config{_exe}$/i; + } + return $thisPerl; +} + # used for scripts which are stored in a non-standard location sub setSourceDir($) { @@ -468,9 +480,17 @@ sub safariPath # Use Safari.app in product directory if present (good for Safari development team). if (isAppleMacWebKit() && -d "$configurationProductDir/Safari.app") { $safariBundle = "$configurationProductDir/Safari.app"; - } elsif (isAppleWinWebKit() && -x "$configurationProductDir/bin/Safari.exe") { - $safariBundle = "$configurationProductDir/bin/Safari.exe"; - } else { + } elsif (isAppleWinWebKit()) { + my $path = "$configurationProductDir/Safari.exe"; + my $debugPath = "$configurationProductDir/Safari_debug.exe"; + + if (configurationForVisualStudio() =~ /Debug/ && -x $debugPath) { + $safariBundle = $debugPath; + } elsif (-x $path) { + $safariBundle = $path; + } + } + if (!$safariBundle) { return installedSafariPath(); } } @@ -539,6 +559,25 @@ sub libraryContainsSymbol return $foundSymbol; } +sub hasMathMLSupport +{ + my $path = shift; + + return libraryContainsSymbol($path, "MathMLElement"); +} + +sub checkWebCoreMathMLSupport +{ + my $required = shift; + my $framework = "WebCore"; + my $path = builtDylibPathForName($framework); + my $hasMathML = hasMathMLSupport($path); + if ($required && !$hasMathML) { + die "$framework at \"$path\" does not include MathML Support, please run build-webkit --mathml\n"; + } + return $hasMathML; +} + sub hasSVGSupport { my $path = shift; @@ -618,6 +657,26 @@ sub checkWebCore3DRenderingSupport return $has3DRendering; } +sub has3DCanvasSupport +{ + return 0 if isQt(); + + my $path = shift; + return libraryContainsSymbol($path, "CanvasShader"); +} + +sub checkWebCore3DCanvasSupport +{ + my $required = shift; + my $framework = "WebCore"; + my $path = builtDylibPathForName($framework); + my $has3DCanvas = has3DCanvasSupport($path); + if ($required && !$has3DCanvas) { + die "$framework at \"$path\" does not include 3D Canvas Support, please run build-webkit --3d-canvas\n"; + } + return $has3DCanvas; +} + sub hasWMLSupport { my $path = shift; @@ -788,6 +847,11 @@ sub isDebianBased() return -e "/etc/debian_version"; } +sub isFedoraBased() +{ + return -e "/etc/fedora-release"; +} + sub isChromium() { determineIsChromium(); @@ -810,6 +874,16 @@ sub isDarwin() return ($^O eq "darwin") || 0; } +sub isWindows() +{ + return ($^O eq "MSWin32") || 0; +} + +sub isLinux() +{ + return ($^O eq "linux") || 0; +} + sub isAppleWebKit() { return !(isQt() or isGtk() or isWx() or isChromium()); @@ -894,7 +968,7 @@ sub relativeScriptsDir() sub launcherPath() { my $relativeScriptsPath = relativeScriptsDir(); - if (isGtk() || isQt()) { + if (isGtk() || isQt() || isWx()) { return "$relativeScriptsPath/run-launcher"; } elsif (isAppleWebKit()) { return "$relativeScriptsPath/run-safari"; @@ -907,6 +981,8 @@ sub launcherName() return "GtkLauncher"; } elsif (isQt()) { return "QtLauncher"; + } elsif (isWx()) { + return "wxBrowser"; } elsif (isAppleWebKit()) { return "Safari"; } @@ -931,7 +1007,7 @@ sub checkRequiredSystemConfig print "http://developer.apple.com/tools/xcode\n"; print "*************************************************************\n"; } - } elsif (isGtk() or isQt() or isWx()) { + } elsif (isGtk() or isQt() or isWx() or isChromium()) { my @cmds = qw(flex bison gperf); my @missing = (); foreach my $cmd (@cmds) { @@ -952,23 +1028,21 @@ 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"; + my $vsInstallDir; + my $programFilesPath = $ENV{'PROGRAMFILES'} || "C:\\Program Files"; + if ($ENV{'VSINSTALLDIR'}) { + $vsInstallDir = $ENV{'VSINSTALLDIR'}; + } else { + $vsInstallDir = "$programFilesPath/Microsoft Visual Studio 8"; + } + $vsInstallDir = `cygpath "$vsInstallDir"`; + chomp $vsInstallDir; + $vcBuildPath = "$vsInstallDir/Common7/IDE/devenv.com"; if (-e $vcBuildPath) { # Visual Studio is installed; we can use pdevenv to build. $vcBuildPath = File::Spec->catfile(sourceDir(), qw(WebKitTools Scripts pdevenv)); } else { # Visual Studio 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"; @@ -1032,6 +1106,50 @@ sub buildVisualStudioProject return system @command; } +sub downloadWafIfNeeded +{ + # get / update waf if needed + my $waf = "$sourceDir/WebKitTools/wx/waf"; + my $wafURL = 'http://wxwebkit.wxcommunity.com/downloads/deps/waf'; + if (!-f $waf) { + my $result = system "curl -o $waf $wafURL"; + chmod 0755, $waf; + } +} + +sub buildWafProject +{ + my ($project, $shouldClean, @options) = @_; + + # set the PYTHONPATH for waf + my $pythonPath = $ENV{'PYTHONPATH'}; + if (!defined($pythonPath)) { + $pythonPath = ''; + } + my $sourceDir = sourceDir(); + my $newPythonPath = "$sourceDir/WebKitTools/wx/build:$pythonPath"; + if (isCygwin()) { + $newPythonPath = `cygpath --mixed --path $newPythonPath`; + } + $ENV{'PYTHONPATH'} = $newPythonPath; + + print "Building $project\n"; + + my $wafCommand = "$sourceDir/WebKitTools/wx/waf"; + if ($ENV{'WXWEBKIT_WAF'}) { + $wafCommand = $ENV{'WXWEBKIT_WAF'}; + } + if (isCygwin()) { + $wafCommand = `cygpath --windows "$wafCommand"`; + chomp($wafCommand); + } + if ($shouldClean) { + return system $wafCommand, "clean", "distclean"; + } + + return system $wafCommand, 'configure', 'build', 'install', @options; +} + sub retrieveQMakespecVar { my $mkspec = $_[0]; @@ -1187,26 +1305,28 @@ sub buildQMakeProject($@) push @buildArgs, "CONFIG-=release"; push @buildArgs, "CONFIG+=debug"; } else { - push @buildArgs, "CONFIG+=release"; my $passedConfig = passedConfiguration() || ""; if (!isDarwin() || $passedConfig =~ m/release/i) { + push @buildArgs, "CONFIG+=release"; push @buildArgs, "CONFIG-=debug"; } else { + push @buildArgs, "CONFIG+=debug"; push @buildArgs, "CONFIG+=debug_and_release"; - push @buildArgs, "CONFIG+=build_all"; } } - my $dir = baseProductDir(); + my $dir = File::Spec->canonpath(baseProductDir()); + my @mkdirArgs; + push @mkdirArgs, "-p" if !isWindows(); if (! -d $dir) { - system "mkdir", "-p", "$dir"; + system "mkdir", @mkdirArgs, "$dir"; if (! -d $dir) { die "Failed to create product directory " . $dir; } } - $dir = $dir . "/$config"; + $dir = File::Spec->catfile($dir, $config); if (! -d $dir) { - system "mkdir", "-p", "$dir"; + system "mkdir", @mkdirArgs, "$dir"; if (! -d $dir) { die "Failed to create build directory " . $dir; } @@ -1217,7 +1337,7 @@ sub buildQMakeProject($@) print "Calling '$qmakebin @buildArgs' in " . $dir . "\n\n"; print "Installation directory: $prefix\n" if(defined($prefix)); - my $result = system $qmakebin, @buildArgs; + my $result = system "$qmakebin @buildArgs"; if ($result ne 0) { die "Failed to setup build environment using $qmakebin!\n"; } @@ -1250,6 +1370,30 @@ sub buildGtkProject($$@) return buildAutotoolsProject($clean, @buildArgs); } +sub buildChromium($@) +{ + my ($clean, @options) = @_; + + my $result = 1; + if (isDarwin()) { + # Mac build - builds the root xcode project. + $result = buildXCodeProject("WebKit/chromium/webkit", + $clean, + (@options)); + } elsif (isCygwin()) { + # Windows build - builds the root visual studio solution. + $result = buildVisualStudioProject("WebKit/chromium/webkit.sln", + $clean); + } elsif (isLinux()) { + # Linux build + # FIXME support linux. + print STDERR "Linux build is not supported. Yet."; + } else { + print STDERR "This platform is not supported by chromium."; + } + return $result; +} + sub setPathForRunningWebKitApp { my ($env) = @_; diff --git a/WebKitTools/WebKitLauncher/Info.plist b/WebKitTools/WebKitLauncher/Info.plist index 1eba038..83564a7 100644 --- a/WebKitTools/WebKitLauncher/Info.plist +++ b/WebKitTools/WebKitLauncher/Info.plist @@ -441,6 +441,8 @@ <false/> <key>SUAllowsAutomaticUpdates</key> <false/> + <key>SUPublicDSAKeyFile</key> + <string>nightly.webkit.org.public.pem</string> <key>NSPrincipalClass</key> <string>BrowserApplication</string> <key>CFBundleHelpBookFolder</key> diff --git a/WebKitTools/WebKitLauncher/WebKitLauncher.xcodeproj/project.pbxproj b/WebKitTools/WebKitLauncher/WebKitLauncher.xcodeproj/project.pbxproj index b8d7a6d..36eacc5 100644 --- a/WebKitTools/WebKitLauncher/WebKitLauncher.xcodeproj/project.pbxproj +++ b/WebKitTools/WebKitLauncher/WebKitLauncher.xcodeproj/project.pbxproj @@ -23,6 +23,7 @@ /* Begin PBXBuildFile section */ 5D1067640FE63758002A2868 /* WebKitLauncherURLProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D1067620FE63758002A2868 /* WebKitLauncherURLProtocol.h */; }; 5D1067650FE63758002A2868 /* WebKitLauncherURLProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D1067630FE63758002A2868 /* WebKitLauncherURLProtocol.m */; }; + 5D18A1FF103FE255006CA7C7 /* nightly.webkit.org.public.pem in Resources */ = {isa = PBXBuildFile; fileRef = 5D18A1FE103FE255006CA7C7 /* nightly.webkit.org.public.pem */; }; 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 */; }; @@ -65,6 +66,7 @@ 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; }; 5D1067620FE63758002A2868 /* WebKitLauncherURLProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebKitLauncherURLProtocol.h; sourceTree = "<group>"; }; 5D1067630FE63758002A2868 /* WebKitLauncherURLProtocol.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebKitLauncherURLProtocol.m; sourceTree = "<group>"; }; + 5D18A1FE103FE255006CA7C7 /* nightly.webkit.org.public.pem */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = nightly.webkit.org.public.pem; sourceTree = "<group>"; }; 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; }; @@ -148,9 +150,10 @@ 29B97317FDCFA39411CA2CEA /* Resources */ = { isa = PBXGroup; children = ( - 5D41141B0A50A9DE00C84CF0 /* VERSION */, 8D1107310486CEB800E47090 /* Info.plist */, + 5D18A1FE103FE255006CA7C7 /* nightly.webkit.org.public.pem */, 5D4DF981097F89FB0083D5E5 /* start.html */, + 5D41141B0A50A9DE00C84CF0 /* VERSION */, 5DB70524097B94CD009875EC /* webkit.icns */, ); name = Resources; @@ -257,6 +260,7 @@ 5D41141C0A50A9DE00C84CF0 /* VERSION in Resources */, 5DB70525097B94CD009875EC /* webkit.icns in Resources */, 5D650F3A09DB8B410075E9A8 /* WebKitNightlyEnabler.dylib in Resources */, + 5D18A1FF103FE255006CA7C7 /* nightly.webkit.org.public.pem in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/WebKitTools/WebKitLauncher/WebKitNightlyEnablerSparkle.m b/WebKitTools/WebKitLauncher/WebKitNightlyEnablerSparkle.m index 3927131..8b13ab8 100644 --- a/WebKitTools/WebKitLauncher/WebKitNightlyEnablerSparkle.m +++ b/WebKitTools/WebKitLauncher/WebKitNightlyEnablerSparkle.m @@ -43,13 +43,6 @@ static NSString* updatePermissionPromptDescription(id self, SEL _cmd) return @"Should WebKit automatically check for updates? You can always check for updates manually from the Safari menu."; } -// -[SUBasicUpdateDriver downloadDidFinish:] requires that the download be served over SSL or signed -// using a public key. We're not interested in dealing with that hassle just at the moment. -static void skipSignatureVerificationInDownloadDidFinish(id self, SEL _cmd, id download) -{ - objc_msgSend(self, @selector(extractUpdate)); -} - static NSPanel *updateAlertPanel(id updateItem, id host) { NSString *hostName = objc_msgSend(host, @selector(name)); @@ -139,9 +132,6 @@ void initializeSparkle() Method methodToPatch = class_getInstanceMethod(objc_getRequiredClass("SUUpdatePermissionPrompt"), @selector(promptDescription)); setMethodImplementation(methodToPatch, (IMP)updatePermissionPromptDescription); - methodToPatch = class_getInstanceMethod(objc_getRequiredClass("SUBasicUpdateDriver"), @selector(downloadDidFinish:)); - setMethodImplementation(methodToPatch, (IMP)skipSignatureVerificationInDownloadDidFinish); - methodToPatch = class_getInstanceMethod(objc_getRequiredClass("SUUpdateAlert"), @selector(initWithAppcastItem:host:)); setMethodImplementation(methodToPatch, (IMP)updateAlertInitForAlertPanel); diff --git a/WebKitTools/WebKitLauncher/nightly.webkit.org.public.pem b/WebKitTools/WebKitLauncher/nightly.webkit.org.public.pem new file mode 100644 index 0000000..174c1e4 --- /dev/null +++ b/WebKitTools/WebKitLauncher/nightly.webkit.org.public.pem @@ -0,0 +1,20 @@ +-----BEGIN PUBLIC KEY----- +MIIDOjCCAi0GByqGSM44BAEwggIgAoIBAQCkQLoVjuu3dPn1dO8N6xIFf4riPVuJ +XOVpx+QlFMno+qzqGJcJxqhfqZhIRwLq62eHpeuYKIuuPG8fqXY/hquHQIjrtEFZ +euCW8cxqC7iBg3PlX6RsKUXHD+WY82HJ5Hdkd+5G3jD9qO+Ka7RXgOnL7fTRcbkW +rtBjL7lVAlMBSVG54+zvti/h1CmdfpO83JAnoGl8c+WGgKlwt5nR7jxp4PgBdAw2 +aJt+UqrMkZOr4Npik1a8IzW+KTlBn96DbF5M6PP6Uh9TblnYtt0ic/Vnr6MKS60X +WNCb/2/HFjQYaINYtJfXpBaGUMZ0dsAyMxn/Sf1vApmVWh2t0TRMgI4JAhUAtL7E +pauM+spqaZnAxcMNMP0uFaECggEAe1lF6yZHJh89QdPQvmwROKFHOXYvEX5/IFRw +pFJDdJJdw53nS/yXWKy8o/wBqESzeVCbktYRqQE84ApO/KJs4KdwiL2LU32FiMD0 +c4UCkRf/RxSLxE4/FGKQzTaBB5TGMfuNLn6C/4aoNXnxcB399QxKF2slBp1GQgsC +6/4KZZYN+kxGxqAfA1UqrleVtv9OwmaCJwMYYqq20zxYhryuBjTSAD+VN6ncerUf +IxUceX83mWriBMtXHHR0x12WUDfnFQZg583MeMguFc8qESqZX7mWtzSnblsGmez3 +pD028APHFWJSdruT2YI1NJf08S7A9GLdkLRaUNQTABygANviQwOCAQUAAoIBAGDn +SFRJ3o/wKBm1PwQyaMfE8dtFt1NVOqTA2/VL3CVfqPV6tizRSvto45HSBn96R6nC +cxZCi3knJy/9V9ITtlCw1UtqeYOW7sp0PRAgct93XuzlMpOFQr5Q8jydvqMEymOD +c55QE2vbSgHYbQH362uNXsyMWN1xRVSlT13MBi+fmZ86Z5CkRWvIPWg2NRO16bnx +jK6l0LGvBKiU79HIrH7DlEfX0zVJBYi6NnJqvFSDeoKyiOMWaCAquWDgu00k3NOl +gndPnl+mVzEEgNvvN0H6KGVTf55H7KR1LqtWFWCw0VXy5oFgRB359hrLvxe91U4M +iN3jD7YxuENTOTefu9c= +-----END PUBLIC KEY----- diff --git a/WebKitTools/WebKitLauncher/webkit.icns b/WebKitTools/WebKitLauncher/webkit.icns Binary files differindex bf629bf..b1e1017 100644 --- a/WebKitTools/WebKitLauncher/webkit.icns +++ b/WebKitTools/WebKitLauncher/webkit.icns diff --git a/WebKitTools/WebKitLauncherWin/WebKitLauncherWin.vcproj b/WebKitTools/WebKitLauncherWin/WebKitLauncherWin.vcproj index ee007ca..bf99228 100644 --- a/WebKitTools/WebKitLauncherWin/WebKitLauncherWin.vcproj +++ b/WebKitTools/WebKitLauncherWin/WebKitLauncherWin.vcproj @@ -1,123 +1,123 @@ -<?xml version="1.0" encoding="Windows-1252"?> -<VisualStudioProject - ProjectType="Visual C++" - Version="8.00" - Name="WebKitLauncherWin" - ProjectGUID="{D09806DB-E58B-4646-8C9B-61101906C1E2}" - RootNamespace="WebKitLauncherWin" - Keyword="Win32Proj" - > - <Platforms> - <Platform - Name="Win32" - /> - </Platforms> - <ToolFiles> - </ToolFiles> - <Configurations> - <Configuration - Name="Release|Win32" - 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" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLinkerTool" - AdditionalDependencies="shlwapi.lib" - OutputFile="$(OutDir)\WebKit$(WebKitConfigSuffix).exe" - /> - <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=".\WebKitLauncherWin.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> - </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=".\webkit.ico" - > - </File> - <File - RelativePath=".\WebKitLauncherWin.rc" - > - </File> - </Filter> - </Files> - <Globals> - </Globals> -</VisualStudioProject> +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="WebKitLauncherWin"
+ ProjectGUID="{D09806DB-E58B-4646-8C9B-61101906C1E2}"
+ RootNamespace="WebKitLauncherWin"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Release|Win32"
+ 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"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="shlwapi.lib"
+ OutputFile="$(OutDir)\WebKit$(WebKitConfigSuffix).exe"
+ />
+ <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=".\WebKitLauncherWin.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>
+ </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=".\webkit.ico"
+ >
+ </File>
+ <File
+ RelativePath=".\WebKitLauncherWin.rc"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/WebKitTools/WinLauncher/WinLauncher.vcproj b/WebKitTools/WinLauncher/WinLauncher.vcproj index 7e3c761..5fddb48 100644 --- a/WebKitTools/WinLauncher/WinLauncher.vcproj +++ b/WebKitTools/WinLauncher/WinLauncher.vcproj @@ -23,6 +23,7 @@ >
<Tool
Name="VCPreBuildEventTool"
+ CommandLine="%SystemDrive%\cygwin\bin\which.exe bash
if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%
cmd /c
if exist "$(WebKitOutputDir)\buildfailed" grep XX$(ProjectName)XX "$(WebKitOutputDir)\buildfailed"
if errorlevel 1 exit 1
echo XX$(ProjectName)XX > "$(WebKitOutputDir)\buildfailed"
"
/>
<Tool
Name="VCCustomBuildTool"
@@ -94,6 +95,7 @@ />
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="if exist "$(WebKitOutputDir)\buildfailed" del "$(WebKitOutputDir)\buildfailed""
/>
</Configuration>
<Configuration
@@ -105,6 +107,7 @@ >
<Tool
Name="VCPreBuildEventTool"
+ CommandLine="%SystemDrive%\cygwin\bin\which.exe bash
if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%
cmd /c
if exist "$(WebKitOutputDir)\buildfailed" grep XX$(ProjectName)XX "$(WebKitOutputDir)\buildfailed"
if errorlevel 1 exit 1
echo XX$(ProjectName)XX > "$(WebKitOutputDir)\buildfailed"
"
/>
<Tool
Name="VCCustomBuildTool"
@@ -176,6 +179,7 @@ />
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="if exist "$(WebKitOutputDir)\buildfailed" del "$(WebKitOutputDir)\buildfailed""
/>
</Configuration>
<Configuration
@@ -186,6 +190,7 @@ >
<Tool
Name="VCPreBuildEventTool"
+ CommandLine="%SystemDrive%\cygwin\bin\which.exe bash
if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%
cmd /c
if exist "$(WebKitOutputDir)\buildfailed" grep XX$(ProjectName)XX "$(WebKitOutputDir)\buildfailed"
if errorlevel 1 exit 1
echo XX$(ProjectName)XX > "$(WebKitOutputDir)\buildfailed"
"
/>
<Tool
Name="VCCustomBuildTool"
@@ -257,6 +262,90 @@ />
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="if exist "$(WebKitOutputDir)\buildfailed" del "$(WebKitOutputDir)\buildfailed""
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug_Cairo|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_wincairo.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine="%SystemDrive%\cygwin\bin\which.exe bash
if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%
cmd /c
if exist "$(WebKitOutputDir)\buildfailed" grep XX$(ProjectName)XX "$(WebKitOutputDir)\buildfailed"
if errorlevel 1 exit 1
echo XX$(ProjectName)XX > "$(WebKitOutputDir)\buildfailed"
"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""$(WebKitOutputDir)\include\WebKit";"$(WebKitOutputDir)\Include";"$(WebKitLibrariesDir)\Include";"$(WebKitOutputDir)\Include\WebCore";"$(WebKitLibrariesDir)\Include\WebCore";"$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders";"$(WebKitLibrariesDir)\Include\WebCore\ForwardingHeaders";"$(WebKitOutputDir)\Include\JavaScriptCore";"$(WebKitLibrariesDir)\Include\JavaScriptCore";"$(ProjectDir)\..";"$(ProjectDir)";"$(IntDir)\Include";"$(WebKitOutputDir)\obj\WebKit\DerivedSources""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE"
+ MinimalRebuild="true"
+ ExceptionHandling="0"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="false"
+ UsePrecompiledHeader="2"
+ WarningLevel="1"
+ Detect64BitPortabilityProblems="false"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkLibraryDependencies="false"
+ AdditionalDependencies="comctl32.lib shlwapi.lib user32.lib ole32.lib oleaut32.lib WebKitGUID$(WebKitConfigSuffix).lib WebKit$(WebKitDLLConfigSuffix).lib"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories=""$(WebKitOutputDir)\lib";"$(ProjectDir)\..\..\..\""
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ TypeLibraryFile=""
+ ComponentFileName=""
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="if exist "$(WebKitOutputDir)\buildfailed" del "$(WebKitOutputDir)\buildfailed""
/>
</Configuration>
</Configurations>
@@ -295,6 +384,14 @@ UsePrecompiledHeader="1"
/>
</FileConfiguration>
+ <FileConfiguration
+ Name="Debug_Cairo|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
</File>
<File
RelativePath=".\WinLauncher.cpp"
diff --git a/WebKitTools/wx/browser/wscript b/WebKitTools/wx/browser/wscript index fb8d81f..530cd75 100644 --- a/WebKitTools/wx/browser/wscript +++ b/WebKitTools/wx/browser/wscript @@ -45,7 +45,7 @@ def build(bld): includes = ' '.join(include_paths), source = 'browser.cpp', target = 'wxBrowser', - uselib = 'WX CURL ICU XSLT XML WXWEBKIT ' + waf_configname, + uselib = 'WX CURL ICU SQLITE3 XSLT XML WXWEBKIT ' + get_config(), libpath = [output_dir], uselib_local = '', install_path = output_dir) diff --git a/WebKitTools/wx/build-wxwebkit b/WebKitTools/wx/build-wxwebkit index db03251..3e4c414 100755 --- a/WebKitTools/wx/build-wxwebkit +++ b/WebKitTools/wx/build-wxwebkit @@ -368,7 +368,7 @@ if [ $do_build == 1 -o $do_clean == 1 ]; then PY_LIBDIR=`python -c "import distutils.sysconfig; import sys; sys.stdout.write(distutils.sysconfig.PREFIX)"` PY_LIBDIR="$PY_LIBDIR\\Libs" PY_LIB=`python -c "import sys; sys.stdout.write('python' + sys.version[:3])"` - PY_LIB=`python -c "sys.stdout.write('$PY_LIB'.replace('.', ''))"` + PY_LIB=`python -c "import sys; sys.stdout.write('$PY_LIB'.replace('.', ''))"` else PY_LIB=`python-config --libs` PY_LIBDIR=`python-config --ldflags` diff --git a/WebKitTools/wx/build/build_utils.py b/WebKitTools/wx/build/build_utils.py index f6daf3a..0a795a8 100644 --- a/WebKitTools/wx/build/build_utils.py +++ b/WebKitTools/wx/build/build_utils.py @@ -23,8 +23,11 @@ # # Helper functions for the WebKit build. +import commands import glob import os +import platform +import shutil import sys import urllib import urlparse @@ -35,8 +38,11 @@ def get_output(command): """ Windows-compatible function for getting output from a command. """ - f = os.popen(command) - return f.read().strip() + if sys.platform.startswith('win'): + f = os.popen(command) + return f.read().strip() + else: + return commands.getoutput(command) def get_excludes(root, patterns): """ @@ -100,7 +106,7 @@ def download_if_newer(url, destdir): return None -def update_wx_deps(wk_root, msvc_version='msvc2008'): +def update_wx_deps(conf, wk_root, msvc_version='msvc2008'): """ Download and update tools needed to build the wx port. """ @@ -114,7 +120,10 @@ def update_wx_deps(wk_root, msvc_version='msvc2008'): sys.exit(1) # since this module is still experimental - #swig_module = download_if_newer('http://wxwebkit.wxcommunity.com/downloads/deps/swig.py', os.path.join(wk_root, 'WebKit', 'wx', 'bindings', 'python')) + wxpy_dir = os.path.join(wk_root, 'WebKit', 'wx', 'bindings', 'python') + swig_module = download_if_newer('http://wxwebkit.wxcommunity.com/downloads/deps/swig.py.txt', wxpy_dir) + if swig_module: + shutil.copy(os.path.join(wxpy_dir, 'swig.py.txt'), os.path.join(wxpy_dir, 'swig.py')) if sys.platform.startswith('win'): Logs.info('downloading deps package') @@ -123,6 +132,10 @@ def update_wx_deps(wk_root, msvc_version='msvc2008'): os.system('unzip -o %s -d %s' % (archive, os.path.join(wklibs_dir, msvc_version))) elif sys.platform.startswith('darwin'): + # export the right compiler for building the dependencies + if platform.release().startswith('10'): # Snow Leopard + os.environ['CC'] = conf.env['CC'][0] + os.environ['CXX'] = conf.env['CXX'][0] os.system('%s/WebKitTools/wx/install-unix-extras' % wk_root) def includeDirsForSources(sources): diff --git a/WebKitTools/wx/build/settings.py b/WebKitTools/wx/build/settings.py index b09f0bc..4019273 100644 --- a/WebKitTools/wx/build/settings.py +++ b/WebKitTools/wx/build/settings.py @@ -26,8 +26,11 @@ import commands import os import platform +import re import sys +import Options + from build_utils import * from waf_extensions import * @@ -56,6 +59,24 @@ common_libs = [] common_libpaths = [] common_frameworks = [] +ports = [ + 'CF', + 'Chromium', + 'Gtk', + 'Haiku', + 'Mac', + 'None', + 'Qt', + 'Safari', + 'Win', + 'Wince', + 'wx', +] + +port_uses = { + 'wx': ['CURL','PTHREADS', 'WXGC'], +} + jscore_dirs = [ 'API', 'bytecode', @@ -84,13 +105,15 @@ webcore_dirs = [ 'dom/default', 'editing', 'history', - 'html', + 'html', + 'html/canvas', 'inspector', 'loader', 'loader/appcache', 'loader/archive', - 'loader/icon', - 'page', + 'loader/icon', + 'notifications', + 'page', 'page/animation', 'platform', 'platform/animation', @@ -103,7 +126,8 @@ webcore_dirs = [ 'platform/image-decoders/jpeg', 'platform/image-decoders/png', 'platform/image-decoders/xbm', - 'platform/image-decoders/zlib', + 'platform/image-decoders/zlib', + 'platform/mock', 'platform/network', 'platform/sql', 'platform/text', @@ -111,6 +135,7 @@ webcore_dirs = [ 'rendering', 'rendering/style', 'storage', + 'websockets', 'xml' ] @@ -120,18 +145,35 @@ config = 'Debug' if os.path.exists(config_file): config = open(config_file).read() -output_dir = os.path.join(wk_root, 'WebKitBuild', config) +config_dir = config -waf_configname = config.upper() +try: + branches = commands.getoutput("git branch --no-color") + match = re.search('^\* (.*)', branches, re.MULTILINE) + if match: + config_dir += ".%s" % match.group(1) +except: + pass + +output_dir = os.path.join(wk_root, 'WebKitBuild', config_dir) build_port = "wx" building_on_win32 = sys.platform.startswith('win') -if building_on_win32: - if config == 'Release': - waf_configname = waf_configname + ' CRT_MULTITHREADED_DLL' - else: - waf_configname = waf_configname + ' CRT_MULTITHREADED_DLL_DBG' +def get_config(): + waf_configname = config.upper().strip() + if building_on_win32: + isReleaseCRT = (config == 'Release') + if build_port == 'wx': + if Options.options.wxpython: + isReleaseCRT = True + + if isReleaseCRT: + waf_configname = waf_configname + ' CRT_MULTITHREADED_DLL' + else: + waf_configname = waf_configname + ' CRT_MULTITHREADED_DLL_DBG' + + return waf_configname create_hash_table = wk_root + "/JavaScriptCore/create_hash_table" if building_on_win32: @@ -140,6 +182,16 @@ os.environ['CREATE_HASH_TABLE'] = create_hash_table feature_defines = ['ENABLE_DATABASE', 'ENABLE_XSLT', 'ENABLE_JAVASCRIPT_DEBUGGER'] +msvc_version = 'msvc2008' + +msvclibs_dir = os.path.join(wklibs_dir, msvc_version, 'win') + +def get_path_to_wxconfig(): + if 'WX_CONFIG' in os.environ: + return os.environ['WX_CONFIG'] + else: + return 'wx-config' + def common_set_options(opt): """ Initialize common options provided to the user. @@ -149,38 +201,66 @@ def common_set_options(opt): opt.tool_options('python') opt.add_option('--wxpython', action='store_true', default=False, help='Create the wxPython bindings.') + opt.add_option('--wx-compiler-prefix', action='store', default='vc', + help='Specify a different compiler prefix (do this if you used COMPILER_PREFIX when building wx itself)') def common_configure(conf): """ Configuration used by all targets, called from the target's configure() step. """ + + conf.env['MSVC_VERSIONS'] = ['msvc 9.0', 'msvc 8.0'] + conf.env['MSVC_TARGETS'] = ['x86'] + + if sys.platform.startswith('cygwin'): + print "ERROR: You must use the Win32 Python from python.org, not Cygwin Python, when building on Windows." + sys.exit(1) + + if sys.platform.startswith('darwin') and build_port == 'wx': + import platform + if platform.release().startswith('10'): # Snow Leopard + # wx currently only supports 32-bit compilation, so we want gcc-4.0 instead of 4.2 on Snow Leopard + # unless the user has explicitly set a different compiler. + if not "CC" in os.environ: + conf.env['CC'] = 'gcc-4.0' + if not "CXX" in os.environ: + conf.env['CXX'] = 'g++-4.0' conf.check_tool('compiler_cxx') conf.check_tool('compiler_cc') - conf.check_tool('python') - conf.check_python_headers() + if Options.options.wxpython: + conf.check_tool('python') + conf.check_python_headers() if sys.platform.startswith('darwin'): conf.check_tool('osx') - msvc_version = 'msvc2008' + global msvc_version + global msvclibs_dir + if building_on_win32: found_versions = conf.get_msvc_versions() if found_versions[0][0] == 'msvc 9.0': msvc_version = 'msvc2008' elif found_versions[0][0] == 'msvc 8.0': msvc_version = 'msvc2005' - - msvclibs_dir = '' - if build_port == "wx": - update_wx_deps(wk_root, msvc_version) + msvclibs_dir = os.path.join(wklibs_dir, msvc_version, 'win') + conf.env.append_value('CXXFLAGS', ['/wd4291','/wd4344','/wd4396','/wd4800']) + + for use in port_uses[build_port]: + conf.env.append_value('CXXDEFINES', ['WTF_USE_%s' % use]) - conf.env.append_value('CXXDEFINES', ['BUILDING_WX__=1', 'WTF_USE_WXGC=1']) + if build_port == "wx": + update_wx_deps(conf, wk_root, msvc_version) + + conf.env.append_value('CXXDEFINES', ['BUILDING_WX__=1']) if building_on_win32: conf.env.append_value('LIBPATH', os.path.join(msvclibs_dir, 'lib')) # wx settings - wxdefines, wxincludes, wxlibs, wxlibpaths = get_wxmsw_settings(wx_root, shared=True, unicode=True, wxPython=True) + global config + is_debug = (config == 'Debug') + wxdefines, wxincludes, wxlibs, wxlibpaths = get_wxmsw_settings(wx_root, shared=True, unicode=True, debug=is_debug, wxPython=Options.options.wxpython) conf.env['CXXDEFINES_WX'] = wxdefines conf.env['CPPPATH_WX'] = wxincludes conf.env['LIB_WX'] = wxlibs @@ -193,6 +273,14 @@ def common_configure(conf): conf.env.append_value('CPPPATH', wklibs_dir) conf.env.append_value('LIBPATH', wklibs_dir) + + # WebKit only supports 10.4+ + mac_target = 'MACOSX_DEPLOYMENT_TARGET' + if mac_target in os.environ and os.environ[mac_target] == '10.3': + os.environ[mac_target] = '10.4' + + if mac_target in conf.env and conf.env[mac_target] == '10.3': + conf.env[mac_target] = '10.4' #conf.env['PREFIX'] = output_dir @@ -240,26 +328,22 @@ def common_configure(conf): conf.env['LIB_XSLT'] = ['libxslt'] else: if build_port == 'wx': - conf.env.append_value('LIB', ['png', 'pthread']) + conf.env.append_value('LIB', ['jpeg', 'png', 'pthread']) conf.env.append_value('LIBPATH', os.path.join(wklibs_dir, 'unix', 'lib')) conf.env.append_value('CPPPATH', os.path.join(wklibs_dir, 'unix', 'include')) conf.env.append_value('CXXFLAGS', ['-fPIC', '-DPIC']) - conf.check_cfg(path='wx-config', args='--cxxflags --libs', package='', uselib_store='WX') + conf.check_cfg(path=get_path_to_wxconfig(), args='--cxxflags --libs', package='', uselib_store='WX', mandatory=True) - conf.check_cfg(path='xslt-config', args='--cflags --libs', package='', uselib_store='XSLT') - conf.check_cfg(path='xml2-config', args='--cflags --libs', package='', uselib_store='XML') - conf.check_cfg(path='curl-config', args='--cflags --libs', package='', uselib_store='CURL') + conf.check_cfg(msg='Checking for libxslt', path='xslt-config', args='--cflags --libs', package='', uselib_store='XSLT', mandatory=True) + conf.check_cfg(path='xml2-config', args='--cflags --libs', package='', uselib_store='XML', mandatory=True) + conf.check_cfg(path='curl-config', args='--cflags --libs', package='', uselib_store='CURL', mandatory=True) if sys.platform.startswith('darwin'): conf.env.append_value('LIB', ['WebCoreSQLite3']) if not sys.platform.startswith('darwin'): - conf.check_cfg(package='cairo', args='--cflags --libs', uselib_store='WX') - conf.check_cfg(package='pango', args='--cflags --libs', uselib_store='WX') - conf.check_cfg(package='gtk+-2.0', args='--cflags --libs', uselib_store='WX') - conf.check_cfg(package='sqlite3', args='--cflags --libs', uselib_store='SQLITE3') - conf.check_cfg(path='icu-config', args='--cflags --ldflags', package='', uselib_store='ICU') - - - - + conf.check_cfg(package='cairo', args='--cflags --libs', uselib_store='WX', mandatory=True) + conf.check_cfg(package='pango', args='--cflags --libs', uselib_store='WX', mandatory=True) + conf.check_cfg(package='gtk+-2.0', args='--cflags --libs', uselib_store='WX', mandatory=True) + conf.check_cfg(package='sqlite3', args='--cflags --libs', uselib_store='SQLITE3', mandatory=True) + conf.check_cfg(path='icu-config', args='--cflags --ldflags', package='', uselib_store='ICU', mandatory=True) diff --git a/WebKitTools/wx/build/waf_extensions.py b/WebKitTools/wx/build/waf_extensions.py index fcf34df..6816441 100644 --- a/WebKitTools/wx/build/waf_extensions.py +++ b/WebKitTools/wx/build/waf_extensions.py @@ -34,10 +34,9 @@ def exec_command(s, **kw): filename = '' if sys.platform.startswith('win') and len(' '.join(s)) > 32000: import tempfile - file = tempfile.NamedTemporaryFile(delete=False) - filename = file.name - file.write(' '.join(s[1:])) - file.close() + (fd, filename) = tempfile.mkstemp() + os.write(fd, ' '.join(s[1:])) + os.close(fd) s = [s[0], '@' + filename] diff --git a/WebKitTools/wx/build/wxpresets.py b/WebKitTools/wx/build/wxpresets.py index 677720c..3d6b693 100644 --- a/WebKitTools/wx/build/wxpresets.py +++ b/WebKitTools/wx/build/wxpresets.py @@ -24,6 +24,37 @@ # Library for functions to determine wx settings based on configuration import os +import re + +import Options + +def parse_build_cfg(filename): + cfg_file = open(filename, 'r') + cfg = {} + for cfg_line in cfg_file.readlines(): + key = None + value = None + parts = cfg_line.split('=') + if len(parts) >= 1: + key = parts[0].strip() + + if len(parts) >= 2: + value = parts[1].strip() + if value.isdigit(): + value = int(value) + + if key: + cfg[key] = value + + return cfg + +def get_wx_version(wx_root): + versionText = open(os.path.join(wx_root, "include", "wx", "version.h"), "r").read() + + majorVersion = re.search("#define\swxMAJOR_VERSION\s+(\d+)", versionText).group(1) + minorVersion = re.search("#define\swxMINOR_VERSION\s+(\d+)", versionText).group(1) + + return (majorVersion, minorVersion) def get_wxmsw_settings(wx_root, shared = False, unicode = False, debug = False, wxPython=False): if not os.path.exists(wx_root): @@ -40,11 +71,13 @@ def get_wxmsw_settings(wx_root, shared = False, unicode = False, debug = False, ext = '' postfix = 'vc' + version_str_nodot = ''.join(get_wx_version(wx_root)) + if shared: defines.append('WXUSINGDLL') - libdir = os.path.join(libdir, 'vc_dll') + libdir = os.path.join(libdir, Options.options.wx_compiler_prefix + '_dll') else: - libdir = os.path.join(libdir, 'vc_lib') + libdir = os.path.join(libdir, Options.options.wx_compiler_prefix + '_lib') if unicode: defines.append('_UNICODE') @@ -59,18 +92,27 @@ def get_wxmsw_settings(wx_root, shared = False, unicode = False, debug = False, depext += 'd' configdir = os.path.join(libdir, 'msw' + ext) + + monolithic = False + cfg_file = os.path.join(configdir, 'build.cfg') + if os.path.exists(cfg_file): + cfg = parse_build_cfg(cfg_file) + if "MONOLITHIC" in cfg: + monolithic = cfg["MONOLITHIC"] libpaths.append(libdir) includes.append(configdir) def get_wxlib_name(name): - prefix = 'wxmsw' if name == 'base': - return 'wxbase28%s' % (ext) + return 'wxbase%s%s' % (version_str_nodot, ext) - return "wxmsw28%s_%s" % (ext, name) + return "wxmsw%s%s_%s" % (version_str_nodot, ext, name) libs.extend(['wxzlib' + depext, 'wxjpeg' + depext, 'wxpng' + depext, 'wxexpat' + depext]) - libs.extend([get_wxlib_name('base'), get_wxlib_name('core')]) + if monolithic: + libs.extend(["wxmsw%s%s" % (version_str_nodot, ext)]) + else: + libs.extend([get_wxlib_name('base'), get_wxlib_name('core')]) if wxPython or debug: defines.append('__WXDEBUG__') diff --git a/WebKitTools/wx/install-unix-extras b/WebKitTools/wx/install-unix-extras index b3088c0..68d81e4 100755 --- a/WebKitTools/wx/install-unix-extras +++ b/WebKitTools/wx/install-unix-extras @@ -68,7 +68,7 @@ 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" +LIBJPEG_URL="http://wxwebkit.wxcommunity.com/downloads/deps/$LIBJPEG_TARBALL" LIBPNG_VERSION="1.2.33" LIBPNG_TARBALL="libpng-$LIBPNG_VERSION.tar.gz" |