summaryrefslogtreecommitdiffstats
path: root/WebKitTools/DumpRenderTree/mac
diff options
context:
space:
mode:
Diffstat (limited to 'WebKitTools/DumpRenderTree/mac')
-rw-r--r--WebKitTools/DumpRenderTree/mac/AccessibilityControllerMac.mm54
-rw-r--r--WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm425
-rw-r--r--WebKitTools/DumpRenderTree/mac/Configurations/Base.xcconfig4
-rw-r--r--WebKitTools/DumpRenderTree/mac/Configurations/DebugRelease.xcconfig2
-rw-r--r--WebKitTools/DumpRenderTree/mac/Configurations/DumpRenderTree.xcconfig2
-rw-r--r--WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm383
-rw-r--r--WebKitTools/DumpRenderTree/mac/DumpRenderTreeMac.h8
-rw-r--r--WebKitTools/DumpRenderTree/mac/DumpRenderTreePasteboard.h3
-rw-r--r--WebKitTools/DumpRenderTree/mac/DumpRenderTreePasteboard.m13
-rw-r--r--WebKitTools/DumpRenderTree/mac/DumpRenderTreeWindow.mm5
-rw-r--r--WebKitTools/DumpRenderTree/mac/EditingDelegate.mm26
-rw-r--r--WebKitTools/DumpRenderTree/mac/EventSendingController.h2
-rw-r--r--WebKitTools/DumpRenderTree/mac/EventSendingController.mm128
-rw-r--r--WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.h2
-rw-r--r--WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.mm62
-rw-r--r--WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm47
-rw-r--r--WebKitTools/DumpRenderTree/mac/ObjCController.m42
-rw-r--r--WebKitTools/DumpRenderTree/mac/ObjCPlugin.m2
-rw-r--r--WebKitTools/DumpRenderTree/mac/PixelDumpSupportMac.mm267
-rw-r--r--WebKitTools/DumpRenderTree/mac/ResourceLoadDelegate.mm63
-rw-r--r--WebKitTools/DumpRenderTree/mac/UIDelegate.mm37
21 files changed, 1264 insertions, 313 deletions
diff --git a/WebKitTools/DumpRenderTree/mac/AccessibilityControllerMac.mm b/WebKitTools/DumpRenderTree/mac/AccessibilityControllerMac.mm
new file mode 100644
index 0000000..482c4f3
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/AccessibilityControllerMac.mm
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "DumpRenderTree.h"
+#import "AccessibilityController.h"
+
+#import "AccessibilityUIElement.h"
+#import <Foundation/Foundation.h>
+#import <WebKit/WebFrame.h>
+#import <WebKit/WebHTMLView.h>
+
+AccessibilityController::AccessibilityController()
+{
+}
+
+AccessibilityController::~AccessibilityController()
+{
+}
+
+AccessibilityUIElement AccessibilityController::focusedElement()
+{
+ // FIXME: we could do some caching here.
+ id accessibilityObject = [[[mainFrame frameView] documentView] accessibilityFocusedUIElement];
+ return AccessibilityUIElement(accessibilityObject);
+}
+
+AccessibilityUIElement AccessibilityController::rootElement()
+{
+ // FIXME: we could do some caching here.
+ id accessibilityObject = [[mainFrame frameView] documentView];
+ return AccessibilityUIElement(accessibilityObject);
+}
diff --git a/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm b/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm
new file mode 100644
index 0000000..81edd99
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm
@@ -0,0 +1,425 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "DumpRenderTree.h"
+#import "AccessibilityUIElement.h"
+
+#import <Foundation/Foundation.h>
+#import <JavaScriptCore/JSStringRef.h>
+#import <JavaScriptCore/JSStringRefCF.h>
+#import <WebKit/WebFrame.h>
+#import <WebKit/WebHTMLView.h>
+#import <WebKit/WebTypesInternal.h>
+#import <wtf/RetainPtr.h>
+#import <wtf/Vector.h>
+
+AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement element)
+ : m_element(element)
+{
+ [m_element retain];
+}
+
+AccessibilityUIElement::AccessibilityUIElement(const AccessibilityUIElement& other)
+ : m_element(other.m_element)
+{
+ [m_element retain];
+}
+
+AccessibilityUIElement::~AccessibilityUIElement()
+{
+ [m_element release];
+}
+
+@interface NSString (JSStringRefAdditions)
+- (JSStringRef)createJSStringRef;
+@end
+
+@implementation NSString (JSStringRefAdditions)
+
+- (JSStringRef)createJSStringRef
+{
+ return JSStringCreateWithCFString((CFStringRef)self);
+}
+
+@end
+
+static NSString* descriptionOfValue(id valueObject, id focusedAccessibilityObject)
+{
+ if (!valueObject)
+ return NULL;
+
+ if ([valueObject isKindOfClass:[NSArray class]])
+ return [NSString stringWithFormat:@"<array of size %d>", [(NSArray*)valueObject count]];
+
+ if ([valueObject isKindOfClass:[NSNumber class]])
+ return [(NSNumber*)valueObject stringValue];
+
+ if ([valueObject isKindOfClass:[NSValue class]]) {
+ NSString* type = [NSString stringWithCString:[valueObject objCType] encoding:NSASCIIStringEncoding];
+ NSValue* value = (NSValue*)valueObject;
+ if ([type rangeOfString:@"NSRect"].length > 0)
+ return [NSString stringWithFormat:@"NSRect: %@", NSStringFromRect([value rectValue])];
+ if ([type rangeOfString:@"NSPoint"].length > 0)
+ return [NSString stringWithFormat:@"NSPoint: %@", NSStringFromPoint([value pointValue])];
+ if ([type rangeOfString:@"NSSize"].length > 0)
+ return [NSString stringWithFormat:@"NSSize: %@", NSStringFromSize([value sizeValue])];
+ if ([type rangeOfString:@"NSRange"].length > 0)
+ return [NSString stringWithFormat:@"NSRange: %@", NSStringFromRange([value rangeValue])];
+ }
+
+ // Strip absolute URL paths
+ NSString* description = [valueObject description];
+ NSRange range = [description rangeOfString:@"LayoutTests"];
+ if (range.length)
+ return [description substringFromIndex:range.location];
+
+ // Strip pointer locations
+ if ([description rangeOfString:@"0x"].length) {
+ NSString* role = [focusedAccessibilityObject accessibilityAttributeValue:@"AXRole"];
+ NSString* title = [focusedAccessibilityObject accessibilityAttributeValue:@"AXTitle"];
+ if ([title length])
+ return [NSString stringWithFormat:@"<%@: '%@'>", role, title];
+ return [NSString stringWithFormat:@"<%@>", role];
+ }
+
+ return [valueObject description];
+}
+
+static NSString* attributesOfElement(id accessibilityObject)
+{
+ NSArray* supportedAttributes = [accessibilityObject accessibilityAttributeNames];
+
+ NSMutableString* attributesString = [NSMutableString string];
+ for (NSUInteger i = 0; i < [supportedAttributes count]; ++i) {
+ NSString* attribute = [supportedAttributes objectAtIndex:i];
+
+ // Right now, position provides useless and screen-specific information, so we do not
+ // want to include it for the sake of universally passing tests.
+ if ([attribute isEqualToString:@"AXPosition"])
+ continue;
+
+ id valueObject = [accessibilityObject accessibilityAttributeValue:attribute];
+ NSString* value = descriptionOfValue(valueObject, accessibilityObject);
+ [attributesString appendFormat:@"%@: %@\n", attribute, value];
+ }
+
+ return attributesString;
+}
+
+static JSStringRef concatenateAttributeAndValue(NSString* attribute, NSString* value)
+{
+ Vector<UniChar> buffer([attribute length]);
+ [attribute getCharacters:buffer.data()];
+ buffer.append(':');
+ buffer.append(' ');
+
+ Vector<UniChar> valueBuffer([value length]);
+ [value getCharacters:valueBuffer.data()];
+ buffer.append(valueBuffer);
+
+ return JSStringCreateWithCharacters(buffer.data(), buffer.size());
+}
+
+static void convertNSArrayToVector(NSArray* array, Vector<AccessibilityUIElement>& elementVector)
+{
+ NSUInteger count = [array count];
+ for (NSUInteger i = 0; i < count; ++i)
+ elementVector.append(AccessibilityUIElement([array objectAtIndex:i]));
+}
+
+static JSStringRef descriptionOfElements(Vector<AccessibilityUIElement>& elementVector)
+{
+ NSMutableString* allElementString = [NSMutableString string];
+ size_t size = elementVector.size();
+ for (size_t i = 0; i < size; ++i) {
+ NSString* attributes = attributesOfElement(elementVector[i].platformUIElement());
+ [allElementString appendFormat:@"%@\n------------\n", attributes];
+ }
+
+ return [allElementString createJSStringRef];
+}
+
+void AccessibilityUIElement::getLinkedUIElements(Vector<AccessibilityUIElement>& elementVector)
+{
+ NSArray* linkedElements = [m_element accessibilityAttributeValue:NSAccessibilityLinkedUIElementsAttribute];
+ convertNSArrayToVector(linkedElements, elementVector);
+}
+
+void AccessibilityUIElement::getDocumentLinks(Vector<AccessibilityUIElement>& elementVector)
+{
+ NSArray* linkElements = [m_element accessibilityAttributeValue:@"AXLinkUIElements"];
+ convertNSArrayToVector(linkElements, elementVector);
+}
+
+void AccessibilityUIElement::getChildren(Vector<AccessibilityUIElement>& elementVector)
+{
+ NSArray* children = [m_element accessibilityAttributeValue:NSAccessibilityChildrenAttribute];
+ convertNSArrayToVector(children, elementVector);
+}
+
+AccessibilityUIElement AccessibilityUIElement::getChildAtIndex(unsigned index)
+{
+ Vector<AccessibilityUIElement> children;
+ getChildren(children);
+
+ if (index < children.size())
+ return children[index];
+ return nil;
+}
+
+AccessibilityUIElement AccessibilityUIElement::titleUIElement()
+{
+ id accessibilityObject = [m_element accessibilityAttributeValue:NSAccessibilityTitleUIElementAttribute];
+ if (accessibilityObject)
+ return AccessibilityUIElement(accessibilityObject);
+
+ return nil;
+}
+
+JSStringRef AccessibilityUIElement::attributesOfLinkedUIElements()
+{
+ Vector<AccessibilityUIElement> linkedElements;
+ getLinkedUIElements(linkedElements);
+ return descriptionOfElements(linkedElements);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfDocumentLinks()
+{
+ Vector<AccessibilityUIElement> linkElements;
+ getDocumentLinks(linkElements);
+ return descriptionOfElements(linkElements);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfChildren()
+{
+ Vector<AccessibilityUIElement> children;
+ getChildren(children);
+ return descriptionOfElements(children);
+}
+
+JSStringRef AccessibilityUIElement::allAttributes()
+{
+ NSString* attributes = attributesOfElement(m_element);
+ return [attributes createJSStringRef];
+}
+
+JSStringRef AccessibilityUIElement::parameterizedAttributeNames()
+{
+ NSArray* supportedParameterizedAttributes = [m_element accessibilityParameterizedAttributeNames];
+
+ NSMutableString* attributesString = [NSMutableString string];
+ for (NSUInteger i = 0; i < [supportedParameterizedAttributes count]; ++i) {
+ [attributesString appendFormat:@"%@\n", [supportedParameterizedAttributes objectAtIndex:i]];
+ }
+
+ return [attributesString createJSStringRef];
+}
+
+JSStringRef AccessibilityUIElement::role()
+{
+ NSString* role = descriptionOfValue([m_element accessibilityAttributeValue:@"AXRole"], m_element);
+ return concatenateAttributeAndValue(@"AXRole", role);
+}
+
+JSStringRef AccessibilityUIElement::title()
+{
+ NSString* title = descriptionOfValue([m_element accessibilityAttributeValue:@"AXTitle"], m_element);
+ return concatenateAttributeAndValue(@"AXTitle", title);
+}
+
+JSStringRef AccessibilityUIElement::description()
+{
+ id description = descriptionOfValue([m_element accessibilityAttributeValue:@"AXDescription"], m_element);
+ return concatenateAttributeAndValue(@"AXDescription", description);
+}
+
+double AccessibilityUIElement::width()
+{
+ NSValue* sizeValue = [m_element accessibilityAttributeValue:@"AXSize"];
+ return static_cast<double>([sizeValue sizeValue].width);
+}
+
+double AccessibilityUIElement::height()
+{
+ NSValue* sizeValue = [m_element accessibilityAttributeValue:@"AXSize"];
+ return static_cast<double>([sizeValue sizeValue].height);
+}
+
+double AccessibilityUIElement::intValue()
+{
+ id value = [m_element accessibilityAttributeValue:@"AXValue"];
+ if ([value isKindOfClass:[NSNumber class]])
+ return [(NSNumber*)value doubleValue];
+ return 0.0f;
+}
+
+double AccessibilityUIElement::minValue()
+{
+ id value = [m_element accessibilityAttributeValue:@"AXMinValue"];
+ if ([value isKindOfClass:[NSNumber class]])
+ return [(NSNumber*)value doubleValue];
+ return 0.0f;
+}
+
+double AccessibilityUIElement::maxValue()
+{
+ id value = [m_element accessibilityAttributeValue:@"AXMaxValue"];
+ if ([value isKindOfClass:[NSNumber class]])
+ return [(NSNumber*)value doubleValue];
+ return 0.0;
+}
+
+int AccessibilityUIElement::insertionPointLineNumber()
+{
+ id value = [m_element accessibilityAttributeValue:@"AXInsertionPointLineNumber"];
+ if ([value isKindOfClass:[NSNumber class]])
+ return [(NSNumber *)value intValue];
+ return -1;
+}
+
+bool AccessibilityUIElement::supportsPressAction()
+{
+ NSArray* actions = [m_element accessibilityActionNames];
+ return [actions containsObject:@"AXPress"];
+}
+
+// parameterized attributes
+int AccessibilityUIElement::lineForIndex(int index)
+{
+ id value = [m_element accessibilityAttributeValue:@"AXLineForIndex" forParameter:[NSNumber numberWithInt:index]];
+ if ([value isKindOfClass:[NSNumber class]])
+ return [(NSNumber *)value intValue];
+ return -1;
+}
+
+JSStringRef AccessibilityUIElement::boundsForRange(unsigned location, unsigned length)
+{
+ NSRange range = NSMakeRange(location, length);
+ id value = [m_element accessibilityAttributeValue:NSAccessibilityBoundsForRangeParameterizedAttribute forParameter:[NSValue valueWithRange:range]];
+ NSRect rect = NSMakeRect(0,0,0,0);
+ if ([value isKindOfClass:[NSValue class]])
+ rect = [value rectValue];
+
+ // don't return position information because it is platform dependent
+ NSMutableString* boundsDescription = [NSMutableString stringWithFormat:@"{{%f, %f}, {%f, %f}}",-1.0f,-1.0f,rect.size.width,rect.size.height];
+ return [boundsDescription createJSStringRef];
+}
+
+JSStringRef AccessibilityUIElement::attributesOfColumnHeaders()
+{
+ // not yet defined in AppKit... odd
+ NSArray* columnHeadersArray = [m_element accessibilityAttributeValue:@"AXColumnHeaderUIElements"];
+ Vector<AccessibilityUIElement> columnHeadersVector;
+ convertNSArrayToVector(columnHeadersArray, columnHeadersVector);
+ return descriptionOfElements(columnHeadersVector);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfRowHeaders()
+{
+ NSArray* rowHeadersArray = [m_element accessibilityAttributeValue:@"AXRowHeaderUIElements"];
+ Vector<AccessibilityUIElement> rowHeadersVector;
+ convertNSArrayToVector(rowHeadersArray, rowHeadersVector);
+ return descriptionOfElements(rowHeadersVector);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfColumns()
+{
+ NSArray* columnsArray = [m_element accessibilityAttributeValue:NSAccessibilityColumnsAttribute];
+ Vector<AccessibilityUIElement> columnsVector;
+ convertNSArrayToVector(columnsArray, columnsVector);
+ return descriptionOfElements(columnsVector);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfRows()
+{
+ NSArray* rowsArray = [m_element accessibilityAttributeValue:NSAccessibilityRowsAttribute];
+ Vector<AccessibilityUIElement> rowsVector;
+ convertNSArrayToVector(rowsArray, rowsVector);
+ return descriptionOfElements(rowsVector);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfVisibleCells()
+{
+ NSArray* cellsArray = [m_element accessibilityAttributeValue:@"AXVisibleCells"];
+ Vector<AccessibilityUIElement> cellsVector;
+ convertNSArrayToVector(cellsArray, cellsVector);
+ return descriptionOfElements(cellsVector);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfHeader()
+{
+ id headerObject = [m_element accessibilityAttributeValue:NSAccessibilityHeaderAttribute];
+ if (!headerObject)
+ return [@"" createJSStringRef];
+
+ Vector<AccessibilityUIElement> headerVector;
+ headerVector.append(headerObject);
+ return descriptionOfElements(headerVector);
+}
+
+int AccessibilityUIElement::indexInTable()
+{
+ NSNumber* indexNumber = [m_element accessibilityAttributeValue:NSAccessibilityIndexAttribute];
+ if (!indexNumber)
+ return -1;
+ return [indexNumber intValue];
+}
+
+JSStringRef AccessibilityUIElement::rowIndexRange()
+{
+ NSValue* indexRange = [m_element accessibilityAttributeValue:@"AXRowIndexRange"];
+ NSRange range = indexRange ? [indexRange rangeValue] : NSMakeRange(0,0);
+ NSMutableString* rangeDescription = [NSMutableString stringWithFormat:@"{%d, %d}",range.location, range.length];
+ return [rangeDescription createJSStringRef];
+}
+
+JSStringRef AccessibilityUIElement::columnIndexRange()
+{
+ NSNumber* indexRange = [m_element accessibilityAttributeValue:@"AXColumnIndexRange"];
+ NSRange range = indexRange ? [indexRange rangeValue] : NSMakeRange(0,0);
+ NSMutableString* rangeDescription = [NSMutableString stringWithFormat:@"{%d, %d}",range.location, range.length];
+ return [rangeDescription createJSStringRef];
+}
+
+AccessibilityUIElement AccessibilityUIElement::cellForColumnAndRow(unsigned col, unsigned row)
+{
+ NSArray *colRowArray = [NSArray arrayWithObjects:[NSNumber numberWithUnsignedInt:col], [NSNumber numberWithUnsignedInt:row], nil];
+ return [m_element accessibilityAttributeValue:@"AXCellForColumnAndRow" forParameter:colRowArray];
+}
+
+JSStringRef AccessibilityUIElement::selectedTextRange()
+{
+ NSNumber *indexRange = [m_element accessibilityAttributeValue:NSAccessibilitySelectedTextRangeAttribute];
+ NSRange range = indexRange ? [indexRange rangeValue] : NSMakeRange(0,0);
+ NSMutableString *rangeDescription = [NSMutableString stringWithFormat:@"{%d, %d}",range.location, range.length];
+ return [rangeDescription createJSStringRef];
+}
+
+void AccessibilityUIElement::setSelectedTextRange(unsigned location, unsigned length)
+{
+ NSRange textRange = NSMakeRange(location, length);
+ NSValue *textRangeValue = [NSValue valueWithRange:textRange];
+ [m_element accessibilitySetValue:textRangeValue forAttribute:NSAccessibilitySelectedTextRangeAttribute];
+}
diff --git a/WebKitTools/DumpRenderTree/mac/Configurations/Base.xcconfig b/WebKitTools/DumpRenderTree/mac/Configurations/Base.xcconfig
index bd5b1e0..de9d67f 100644
--- a/WebKitTools/DumpRenderTree/mac/Configurations/Base.xcconfig
+++ b/WebKitTools/DumpRenderTree/mac/Configurations/Base.xcconfig
@@ -3,6 +3,8 @@ FRAMEWORK_SEARCH_PATHS = $(FRAMEWORK_SEARCH_PATHS_$(MAC_OS_X_VERSION_MAJOR));
FRAMEWORK_SEARCH_PATHS_ = $(SYSTEM_LIBRARY_DIR)/Frameworks/Quartz.framework/Frameworks $(SYSTEM_LIBRARY_DIR)/Frameworks/ApplicationServices.framework/Frameworks
FRAMEWORK_SEARCH_PATHS_1040 = $(SYSTEM_LIBRARY_DIR)/Frameworks/Quartz.framework/Frameworks $(SYSTEM_LIBRARY_DIR)/Frameworks/ApplicationServices.framework/Frameworks
FRAMEWORK_SEARCH_PATHS_1050 = $(SYSTEM_LIBRARY_DIR)/Frameworks/Quartz.framework/Frameworks $(SYSTEM_LIBRARY_DIR)/Frameworks/ApplicationServices.framework/Frameworks $(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks
+FRAMEWORK_SEARCH_PATHS_1060 = $(SYSTEM_LIBRARY_DIR)/Frameworks/Quartz.framework/Frameworks $(SYSTEM_LIBRARY_DIR)/Frameworks/ApplicationServices.framework/Frameworks $(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks
+GCC_PREPROCESSOR_DEFINITIONS = ENABLE_DASHBOARD_SUPPORT;
DEBUG_INFORMATION_FORMAT = dwarf
PREBINDING = NO
GCC_C_LANGUAGE_STANDARD = gnu99
@@ -12,4 +14,4 @@ GCC_WARN_UNUSED_FUNCTION = YES
GCC_WARN_UNUSED_VARIABLE = YES
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO
WARNING_CFLAGS = -Wall -W -Wno-unused-parameter
-VALID_ARCHS = ppc7400 ppc970 i386 ppc
+LINKER_DISPLAYS_MANGLED_NAMES = YES;
diff --git a/WebKitTools/DumpRenderTree/mac/Configurations/DebugRelease.xcconfig b/WebKitTools/DumpRenderTree/mac/Configurations/DebugRelease.xcconfig
index e17439e..e272da2 100644
--- a/WebKitTools/DumpRenderTree/mac/Configurations/DebugRelease.xcconfig
+++ b/WebKitTools/DumpRenderTree/mac/Configurations/DebugRelease.xcconfig
@@ -1,4 +1,6 @@
#include "Base.xcconfig"
+ARCHS = $(NATIVE_ARCH);
+
MACOSX_DEPLOYMENT_TARGET = $(MACOSX_DEPLOYMENT_TARGET_$(MAC_OS_X_VERSION_MAJOR))
MACOSX_DEPLOYMENT_TARGET_ = 10.4
MACOSX_DEPLOYMENT_TARGET_1040 = 10.4
diff --git a/WebKitTools/DumpRenderTree/mac/Configurations/DumpRenderTree.xcconfig b/WebKitTools/DumpRenderTree/mac/Configurations/DumpRenderTree.xcconfig
index c8a7bdc..b977225 100644
--- a/WebKitTools/DumpRenderTree/mac/Configurations/DumpRenderTree.xcconfig
+++ b/WebKitTools/DumpRenderTree/mac/Configurations/DumpRenderTree.xcconfig
@@ -1,4 +1,4 @@
-OTHER_LDFLAGS = -sectcreate __DATA Ahem qt/fonts/AHEM____.TTF
+OTHER_LDFLAGS = -sectcreate __DATA Ahem qt/fonts/AHEM____.TTF -sectcreate __DATA WeightWatcher100 fonts/WebKitWeightWatcher100.ttf -sectcreate __DATA WeightWatcher200 fonts/WebKitWeightWatcher200.ttf -sectcreate __DATA WeightWatcher300 fonts/WebKitWeightWatcher300.ttf -sectcreate __DATA WeightWatcher400 fonts/WebKitWeightWatcher400.ttf -sectcreate __DATA WeightWatcher500 fonts/WebKitWeightWatcher500.ttf -sectcreate __DATA WeightWatcher600 fonts/WebKitWeightWatcher600.ttf -sectcreate __DATA WeightWatcher700 fonts/WebKitWeightWatcher700.ttf -sectcreate __DATA WeightWatcher800 fonts/WebKitWeightWatcher800.ttf -sectcreate __DATA WeightWatcher900 fonts/WebKitWeightWatcher900.ttf
PRODUCT_NAME = DumpRenderTree
GCC_ENABLE_OBJC_EXCEPTIONS = YES
GCC_PREFIX_HEADER = DumpRenderTreePrefix.h
diff --git a/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm b/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm
index 6df150d..203c6b2 100644
--- a/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm
+++ b/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm
@@ -29,6 +29,7 @@
#import "DumpRenderTree.h"
+#import "AccessibilityController.h"
#import "CheckedMalloc.h"
#import "DumpRenderTreePasteboard.h"
#import "DumpRenderTreeWindow.h"
@@ -46,34 +47,42 @@
#import "UIDelegate.h"
#import "WorkQueue.h"
#import "WorkQueueItem.h"
+#import <Carbon/Carbon.h>
#import <CoreFoundation/CoreFoundation.h>
#import <WebKit/DOMElementPrivate.h>
#import <WebKit/DOMExtensions.h>
#import <WebKit/DOMRange.h>
#import <WebKit/WebBackForwardList.h>
+#import <WebKit/WebCache.h>
#import <WebKit/WebCoreStatistics.h>
-#import <WebKit/WebDatabaseManagerPrivate.h>
#import <WebKit/WebDataSourcePrivate.h>
+#import <WebKit/WebDatabaseManagerPrivate.h>
#import <WebKit/WebDocumentPrivate.h>
#import <WebKit/WebEditingDelegate.h>
#import <WebKit/WebFrameView.h>
+#import <WebKit/WebHTMLRepresentationInternal.h>
#import <WebKit/WebHistory.h>
#import <WebKit/WebHistoryItemPrivate.h>
+#import <WebKit/WebInspector.h>
#import <WebKit/WebPluginDatabase.h>
#import <WebKit/WebPreferences.h>
#import <WebKit/WebPreferencesPrivate.h>
#import <WebKit/WebResourceLoadDelegate.h>
+#import <WebKit/WebTypesInternal.h>
#import <WebKit/WebViewPrivate.h>
#import <getopt.h>
#import <mach-o/getsect.h>
#import <objc/objc-runtime.h>
#import <wtf/Assertions.h>
#import <wtf/RetainPtr.h>
+#import <wtf/OwnPtr.h>
+
+using namespace std;
@interface DumpRenderTreeEvent : NSEvent
@end
-static void runTest(const char *pathOrURL);
+static void runTest(const string& testPathOrURL);
// Deciding when it's OK to dump out the state is a bit tricky. All these must be true:
// - There is no load in progress
@@ -84,8 +93,8 @@ static void runTest(const char *pathOrURL);
volatile bool done;
-NavigationController* navigationController = 0;
-LayoutTestController* layoutTestController = 0;
+NavigationController* gNavigationController = 0;
+LayoutTestController* gLayoutTestController = 0;
WebFrame *mainFrame = 0;
// This is the topmost frame that is loading, during a given load, or nil when no load is
@@ -106,13 +115,10 @@ static ResourceLoadDelegate *resourceLoadDelegate;
PolicyDelegate *policyDelegate;
static int dumpPixels;
-static int dumpAllPixels;
static int threaded;
-static int testRepaintDefault;
-static int repaintSweepHorizontallyDefault;
static int dumpTree = YES;
+static int forceComplexText;
static BOOL printSeparators;
-static NSString *currentTest = nil;
static RetainPtr<CFStringRef> persistentUserStyleSheetLocation;
static WebHistoryItem *prevTestBFItem = nil; // current b/f item at the end of the previous test
@@ -120,43 +126,109 @@ static WebHistoryItem *prevTestBFItem = nil; // current b/f item at the end of
const unsigned maxViewHeight = 600;
const unsigned maxViewWidth = 800;
+#if __OBJC2__
+static void swizzleAllMethods(Class imposter, Class original)
+{
+ unsigned int imposterMethodCount;
+ Method* imposterMethods = class_copyMethodList(imposter, &imposterMethodCount);
+
+ unsigned int originalMethodCount;
+ Method* originalMethods = class_copyMethodList(original, &originalMethodCount);
+
+ for (unsigned int i = 0; i < imposterMethodCount; i++) {
+ SEL imposterMethodName = method_getName(imposterMethods[i]);
+
+ // Attempt to add the method to the original class. If it fails, the method already exists and we should
+ // instead exchange the implementations.
+ if (class_addMethod(original, imposterMethodName, method_getImplementation(originalMethods[i]), method_getTypeEncoding(originalMethods[i])))
+ continue;
+
+ unsigned int j = 0;
+ for (; j < originalMethodCount; j++) {
+ SEL originalMethodName = method_getName(originalMethods[j]);
+ if (sel_isEqual(imposterMethodName, originalMethodName))
+ break;
+ }
+
+ // If class_addMethod failed above then the method must exist on the original class.
+ ASSERT(j < originalMethodCount);
+ method_exchangeImplementations(imposterMethods[i], originalMethods[j]);
+ }
+
+ free(imposterMethods);
+ free(originalMethods);
+}
+#endif
+
+static void poseAsClass(const char* imposter, const char* original)
+{
+ Class imposterClass = objc_getClass(imposter);
+ Class originalClass = objc_getClass(original);
+
+#if !__OBJC2__
+ class_poseAs(imposterClass, originalClass);
+#else
+
+ // Swizzle instance methods
+ swizzleAllMethods(imposterClass, originalClass);
+ // and then class methods
+ swizzleAllMethods(object_getClass(imposterClass), object_getClass(originalClass));
+#endif
+}
+
void setPersistentUserStyleSheetLocation(CFStringRef url)
{
persistentUserStyleSheetLocation = url;
}
-static BOOL shouldIgnoreWebCoreNodeLeaks(CFStringRef URLString)
+static bool shouldIgnoreWebCoreNodeLeaks(const string& URLString)
{
- static CFStringRef const ignoreSet[] = {
+ static char* const ignoreSet[] = {
// Keeping this infrastructure around in case we ever need it again.
};
- static const int ignoreSetCount = sizeof(ignoreSet) / sizeof(CFStringRef);
+ static const int ignoreSetCount = sizeof(ignoreSet) / sizeof(char*);
for (int i = 0; i < ignoreSetCount; i++) {
- CFStringRef ignoreString = ignoreSet[i];
- CFRange range = CFRangeMake(0, CFStringGetLength(URLString));
- CFOptionFlags flags = kCFCompareAnchored | kCFCompareBackwards | kCFCompareCaseInsensitive;
- if (CFStringFindWithOptions(URLString, ignoreString, range, flags, NULL))
- return YES;
+ // FIXME: ignore case
+ string curIgnore(ignoreSet[i]);
+ // Match at the end of the URLString
+ if (!URLString.compare(URLString.length() - curIgnore.length(), curIgnore.length(), curIgnore))
+ return true;
}
- return NO;
+ return false;
}
-static void activateAhemFont()
-{
- unsigned long fontDataLength;
- char* fontData = getsectdata("__DATA", "Ahem", &fontDataLength);
- if (!fontData) {
- fprintf(stderr, "Failed to locate the Ahem font.\n");
- exit(1);
- }
+static void activateFonts()
+{
+ static const char* fontSectionNames[] = {
+ "Ahem",
+ "WeightWatcher100",
+ "WeightWatcher200",
+ "WeightWatcher300",
+ "WeightWatcher400",
+ "WeightWatcher500",
+ "WeightWatcher600",
+ "WeightWatcher700",
+ "WeightWatcher800",
+ "WeightWatcher900",
+ 0
+ };
+
+ for (unsigned i = 0; fontSectionNames[i]; ++i) {
+ unsigned long fontDataLength;
+ char* fontData = getsectdata("__DATA", fontSectionNames[i], &fontDataLength);
+ if (!fontData) {
+ fprintf(stderr, "Failed to locate the %s font.\n", fontSectionNames[i]);
+ exit(1);
+ }
- ATSFontContainerRef fontContainer;
- OSStatus status = ATSFontActivateFromMemory(fontData, fontDataLength, kATSFontContextLocal, kATSFontFormatUnspecified, NULL, kATSOptionFlagsDefault, &fontContainer);
+ ATSFontContainerRef fontContainer;
+ OSStatus status = ATSFontActivateFromMemory(fontData, fontDataLength, kATSFontContextLocal, kATSFontFormatUnspecified, NULL, kATSOptionFlagsDefault, &fontContainer);
- if (status != noErr) {
- fprintf(stderr, "Failed to activate the Ahem font.\n");
- exit(1);
+ if (status != noErr) {
+ fprintf(stderr, "Failed to activate the %s font.\n", fontSectionNames[i]);
+ exit(1);
+ }
}
}
@@ -235,18 +307,26 @@ void testStringByEvaluatingJavaScriptFromString()
static void setDefaultsToConsistentValuesForTesting()
{
// Give some clear to undocumented defaults values
- static const int MediumFontSmoothing = 2;
+ static const int NoFontSmoothing = 0;
static const int BlueTintedAppearance = 1;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
- [defaults setObject:@"DoubleMax" forKey:@"AppleScrollBarVariant"];
[defaults setInteger:4 forKey:@"AppleAntiAliasingThreshold"]; // smallest font size to CG should perform antialiasing on
- [defaults setInteger:MediumFontSmoothing forKey:@"AppleFontSmoothing"];
+ [defaults setInteger:NoFontSmoothing forKey:@"AppleFontSmoothing"];
[defaults setInteger:BlueTintedAppearance forKey:@"AppleAquaColorVariant"];
[defaults setObject:@"0.709800 0.835300 1.000000" forKey:@"AppleHighlightColor"];
[defaults setObject:@"0.500000 0.500000 0.500000" forKey:@"AppleOtherHighlightColor"];
[defaults setObject:[NSArray arrayWithObject:@"en"] forKey:@"AppleLanguages"];
+ // Scrollbars are drawn either using AppKit (which uses NSUserDefaults) or using HIToolbox (which uses CFPreferences / kCFPreferencesAnyApplication / kCFPreferencesCurrentUser / kCFPreferencesAnyHost)
+ [defaults setObject:@"DoubleMax" forKey:@"AppleScrollBarVariant"];
+ RetainPtr<CFTypeRef> initialValue = CFPreferencesCopyValue(CFSTR("AppleScrollBarVariant"), kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
+ CFPreferencesSetValue(CFSTR("AppleScrollBarVariant"), CFSTR("DoubleMax"), kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
+ ThemeScrollBarArrowStyle style;
+ GetThemeScrollBarArrowStyle(&style); // Force HIToolbox to read from CFPreferences
+ if (initialValue)
+ CFPreferencesSetValue(CFSTR("AppleScrollBarVariant"), initialValue.get(), kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
+
NSString *libraryPath = [@"~/Library/Application Support/DumpRenderTree" stringByExpandingTildeInPath];
[defaults setObject:[libraryPath stringByAppendingPathComponent:@"Databases"] forKey:WebDatabaseDirectoryDefaultsKey];
@@ -265,6 +345,8 @@ static void setDefaultsToConsistentValuesForTesting()
[preferences setEditableLinkBehavior:WebKitEditableLinkOnlyLiveWithShiftKey];
[preferences setTabsToLinks:NO];
[preferences setDOMPasteAllowed:YES];
+ [preferences setFullDocumentTeardownEnabled:YES];
+ [preferences setShouldPrintBackgrounds:YES];
// The back/forward cache is causing problems due to layouts during transition from one page to another.
// So, turn it off for now, but we might want to turn it back on some day.
@@ -273,8 +355,10 @@ static void setDefaultsToConsistentValuesForTesting()
static void crashHandler(int sig)
{
- fprintf(stderr, "%s\n", strsignal(sig));
- restoreColorSpace(0);
+ char *signalName = strsignal(sig);
+ write(STDERR_FILENO, signalName, strlen(signalName));
+ write(STDERR_FILENO, "\n", 1);
+ restoreMainDisplayColorProfile(0);
exit(128 + sig);
}
@@ -295,7 +379,7 @@ static void installSignalHandlers()
static void allocateGlobalControllers()
{
// FIXME: We should remove these and move to the ObjC standard [Foo sharedInstance] model
- navigationController = [[NavigationController alloc] init];
+ gNavigationController = [[NavigationController alloc] init];
frameLoadDelegate = [[FrameLoadDelegate alloc] init];
uiDelegate = [[UIDelegate alloc] init];
editingDelegate = [[EditingDelegate alloc] init];
@@ -312,7 +396,7 @@ static inline void releaseAndZero(NSObject** object)
static void releaseGlobalControllers()
{
- releaseAndZero(&navigationController);
+ releaseAndZero(&gNavigationController);
releaseAndZero(&frameLoadDelegate);
releaseAndZero(&editingDelegate);
releaseAndZero(&resourceLoadDelegate);
@@ -323,13 +407,11 @@ static void releaseGlobalControllers()
static void initializeGlobalsFromCommandLineOptions(int argc, const char *argv[])
{
struct option options[] = {
- {"dump-all-pixels", no_argument, &dumpAllPixels, YES},
- {"horizontal-sweep", no_argument, &repaintSweepHorizontallyDefault, YES},
{"notree", no_argument, &dumpTree, NO},
{"pixel-tests", no_argument, &dumpPixels, YES},
- {"repaint", no_argument, &testRepaintDefault, YES},
{"tree", no_argument, &dumpTree, YES},
{"threaded", no_argument, &threaded, YES},
+ {"complex-text", no_argument, &forceComplexText, YES},
{NULL, 0, NULL, 0}
};
@@ -376,14 +458,14 @@ static void runTestingServerLoop()
static void prepareConsistentTestingEnvironment()
{
- class_poseAs(objc_getClass("DumpRenderTreePasteboard"), objc_getClass("NSPasteboard"));
- class_poseAs(objc_getClass("DumpRenderTreeEvent"), objc_getClass("NSEvent"));
+ poseAsClass("DumpRenderTreePasteboard", "NSPasteboard");
+ poseAsClass("DumpRenderTreeEvent", "NSEvent");
setDefaultsToConsistentValuesForTesting();
- activateAhemFont();
+ activateFonts();
if (dumpPixels)
- initializeColorSpaceAndScreeBufferForPixelTests();
+ setupMainDisplayColorProfile();
allocateGlobalControllers();
makeLargeMallocFailSilently();
@@ -396,12 +478,17 @@ void dumpRenderTree(int argc, const char *argv[])
addTestPluginsToPluginSearchPath(argv[0]);
if (dumpPixels)
installSignalHandlers();
-
+
+ if (forceComplexText)
+ [WebView _setAlwaysUsesComplexTextCodePath:YES];
+
WebView *webView = createWebViewAndOffscreenWindow();
mainFrame = [webView mainFrame];
[[NSURLCache sharedURLCache] removeAllCachedResponses];
+ [WebCache empty];
+
// <rdar://problem/5222911>
testStringByEvaluatingJavaScriptFromString();
@@ -420,7 +507,6 @@ void dumpRenderTree(int argc, const char *argv[])
if (threaded)
stopJavaScriptThreads();
- [WebCoreStatistics emptyCache]; // Otherwise SVGImages trigger false positives for Frame/Node counts
[webView close];
mainFrame = nil;
@@ -445,7 +531,7 @@ void dumpRenderTree(int argc, const char *argv[])
}
if (dumpPixels)
- restoreColorSpace(0);
+ restoreMainDisplayColorProfile(0);
}
int main(int argc, const char *argv[])
@@ -454,11 +540,12 @@ int main(int argc, const char *argv[])
[NSApplication sharedApplication]; // Force AppKit to init itself
dumpRenderTree(argc, argv);
[WebCoreStatistics garbageCollectJavaScriptObjects];
+ [WebCoreStatistics emptyCache]; // Otherwise SVGImages trigger false positives for Frame/Node counts
[pool release];
return 0;
}
-static int compareHistoryItems(id item1, id item2, void *context)
+static NSInteger compareHistoryItems(id item1, id item2, void *context)
{
return [[item1 target] caseInsensitiveCompare:[item2 target]];
}
@@ -497,7 +584,7 @@ static void dumpFrameScrollPosition(WebFrame *f)
printf("scrolled to %.f,%.f\n", scrollPosition.x, scrollPosition.y);
}
- if (layoutTestController->dumpChildFrameScrollPositions()) {
+ if (gLayoutTestController->dumpChildFrameScrollPositions()) {
NSArray *kids = [f childFrames];
if (kids)
for (unsigned i = 0; i < [kids count]; i++)
@@ -521,7 +608,7 @@ static NSString *dumpFramesAsText(WebFrame *frame)
[result appendFormat:@"%@\n", [documentElement innerText]];
- if (layoutTestController->dumpChildFramesAsText()) {
+ if (gLayoutTestController->dumpChildFramesAsText()) {
NSArray *kids = [frame childFrames];
if (kids) {
for (unsigned i = 0; i < [kids count]; i++)
@@ -532,8 +619,47 @@ static NSString *dumpFramesAsText(WebFrame *frame)
return result;
}
+static NSData *dumpFrameAsPDF(WebFrame *frame)
+{
+ if (!frame)
+ return nil;
+
+ // Sadly we have to dump to a file and then read from that file again
+ // +[NSPrintOperation PDFOperationWithView:insideRect:] requires a rect and prints to a single page
+ // likewise +[NSView dataWithPDFInsideRect:] also prints to a single continuous page
+ // The goal of this function is to test "real" printing across multiple pages.
+ // FIXME: It's possible there might be printing SPI to let us print a multi-page PDF to an NSData object
+ NSString *path = @"/tmp/test.pdf";
+
+ NSMutableDictionary *printInfoDict = [NSMutableDictionary dictionaryWithDictionary:[[NSPrintInfo sharedPrintInfo] dictionary]];
+ [printInfoDict setObject:NSPrintSaveJob forKey:NSPrintJobDisposition];
+ [printInfoDict setObject:path forKey:NSPrintSavePath];
+
+ NSPrintInfo *printInfo = [[NSPrintInfo alloc] initWithDictionary:printInfoDict];
+ [printInfo setHorizontalPagination:NSAutoPagination];
+ [printInfo setVerticalPagination:NSAutoPagination];
+ [printInfo setVerticallyCentered:NO];
+
+ NSPrintOperation *printOperation = [NSPrintOperation printOperationWithView:[frame frameView] printInfo:printInfo];
+ [printOperation setShowPanels:NO];
+ [printOperation runOperation];
+
+ [printInfo release];
+
+ NSData *pdfData = [NSData dataWithContentsOfFile:path];
+ [[NSFileManager defaultManager] removeFileAtPath:path handler:nil];
+
+ return pdfData;
+}
+
static void convertMIMEType(NSMutableString *mimeType)
{
+#ifdef BUILDING_ON_LEOPARD
+ // Workaround for <rdar://problem/5539824> on Leopard
+ if ([mimeType isEqualToString:@"text/xml"])
+ [mimeType setString:@"application/xml"];
+#endif
+ // Workaround for <rdar://problem/6234318> with Dashcode 2.0
if ([mimeType isEqualToString:@"application/x-javascript"])
[mimeType setString:@"text/javascript"];
}
@@ -543,22 +669,24 @@ static void convertWebResourceDataToString(NSMutableDictionary *resource)
NSMutableString *mimeType = [resource objectForKey:@"WebResourceMIMEType"];
convertMIMEType(mimeType);
- if ([mimeType hasPrefix:@"text/"]) {
+ if ([mimeType hasPrefix:@"text/"] || [[WebHTMLRepresentation supportedNonImageMIMETypes] containsObject:mimeType]) {
NSData *data = [resource objectForKey:@"WebResourceData"];
NSString *dataAsString = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
[resource setObject:dataAsString forKey:@"WebResourceData"];
}
}
-static void normalizeWebResourceURL(NSMutableString *webResourceURL, NSString *oldURLBase)
+static void normalizeWebResourceURL(NSMutableString *webResourceURL)
{
- [webResourceURL replaceOccurrencesOfString:oldURLBase
- withString:@"file://"
- options:NSLiteralSearch
- range:NSMakeRange(0, [webResourceURL length])];
+ static int fileUrlLength = [(NSString *)@"file://" length];
+ NSRange layoutTestsWebArchivePathRange = [webResourceURL rangeOfString:@"/LayoutTests/" options:NSBackwardsSearch];
+ if (layoutTestsWebArchivePathRange.location == NSNotFound)
+ return;
+ NSRange currentWorkingDirectoryRange = NSMakeRange(fileUrlLength, layoutTestsWebArchivePathRange.location - fileUrlLength);
+ [webResourceURL replaceCharactersInRange:currentWorkingDirectoryRange withString:@""];
}
-static void convertWebResourceResponseToDictionary(NSMutableDictionary *propertyList, NSString *oldURLBase)
+static void convertWebResourceResponseToDictionary(NSMutableDictionary *propertyList)
{
NSURLResponse *response = nil;
NSData *responseData = [propertyList objectForKey:@"WebResourceResponse"]; // WebResourceResponseKey in WebResource.m
@@ -573,7 +701,7 @@ static void convertWebResourceResponseToDictionary(NSMutableDictionary *property
NSMutableDictionary *responseDictionary = [[NSMutableDictionary alloc] init];
NSMutableString *urlString = [[[response URL] description] mutableCopy];
- normalizeWebResourceURL(urlString, oldURLBase);
+ normalizeWebResourceURL(urlString);
[responseDictionary setObject:urlString forKey:@"URL"];
[urlString release];
@@ -598,6 +726,14 @@ static void convertWebResourceResponseToDictionary(NSMutableDictionary *property
[responseDictionary release];
}
+static NSInteger compareResourceURLs(id resource1, id resource2, void *context)
+{
+ NSString *url1 = [resource1 objectForKey:@"WebResourceURL"];
+ NSString *url2 = [resource2 objectForKey:@"WebResourceURL"];
+
+ return [url1 compare:url2];
+}
+
static NSString *serializeWebArchiveToXML(WebArchive *webArchive)
{
NSString *errorString;
@@ -608,9 +744,6 @@ static NSString *serializeWebArchiveToXML(WebArchive *webArchive)
if (!propertyList)
return errorString;
- // Normalize WebResourceResponse and WebResourceURL values in plist for testing
- NSString *cwdURL = [@"file://" stringByAppendingString:[[[NSFileManager defaultManager] currentDirectoryPath] stringByExpandingTildeInPath]];
-
NSMutableArray *resources = [NSMutableArray arrayWithCapacity:1];
[resources addObject:propertyList];
@@ -619,7 +752,7 @@ static NSString *serializeWebArchiveToXML(WebArchive *webArchive)
[resources removeObjectAtIndex:0];
NSMutableDictionary *mainResource = [resourcePropertyList objectForKey:@"WebMainResource"];
- normalizeWebResourceURL([mainResource objectForKey:@"WebResourceURL"], cwdURL);
+ normalizeWebResourceURL([mainResource objectForKey:@"WebResourceURL"]);
convertWebResourceDataToString(mainResource);
// Add subframeArchives to list for processing
@@ -631,10 +764,14 @@ static NSString *serializeWebArchiveToXML(WebArchive *webArchive)
NSEnumerator *enumerator = [subresources objectEnumerator];
NSMutableDictionary *subresourcePropertyList;
while ((subresourcePropertyList = [enumerator nextObject])) {
- normalizeWebResourceURL([subresourcePropertyList objectForKey:@"WebResourceURL"], cwdURL);
- convertWebResourceResponseToDictionary(subresourcePropertyList, cwdURL);
+ normalizeWebResourceURL([subresourcePropertyList objectForKey:@"WebResourceURL"]);
+ convertWebResourceResponseToDictionary(subresourcePropertyList);
convertWebResourceDataToString(subresourcePropertyList);
}
+
+ // Sort the subresources so they're always in a predictable order for the dump
+ if (NSArray *sortedSubresources = [subresources sortedArrayUsingFunction:compareResourceURLs context:nil])
+ [resourcePropertyList setObject:sortedSubresources forKey:@"WebSubresources"];
}
NSData *xmlData = [NSPropertyListSerialization dataFromPropertyList:propertyList
@@ -689,7 +826,7 @@ static void dumpBackForwardListForWebView(WebView *view)
static void sizeWebViewForCurrentTest()
{
// W3C SVG tests expect to be 480x360
- bool isSVGW3CTest = ([currentTest rangeOfString:@"svg/W3C-SVG-1.1"].length);
+ bool isSVGW3CTest = (gLayoutTestController->testPathOrURL().find("svg/W3C-SVG-1.1") != string::npos);
if (isSVGW3CTest)
[[mainFrame webView] setFrameSize:NSMakeSize(480, 360)];
else
@@ -699,11 +836,11 @@ static void sizeWebViewForCurrentTest()
static const char *methodNameStringForFailedTest()
{
const char *errorMessage;
- if (layoutTestController->dumpAsText())
+ if (gLayoutTestController->dumpAsText())
errorMessage = "[documentElement innerText]";
- else if (layoutTestController->dumpDOMAsWebArchive())
+ else if (gLayoutTestController->dumpDOMAsWebArchive())
errorMessage = "[[mainFrame DOMDocument] webArchive]";
- else if (layoutTestController->dumpSourceAsWebArchive())
+ else if (gLayoutTestController->dumpSourceAsWebArchive())
errorMessage = "[[mainFrame dataSource] webArchive]";
else
errorMessage = "[mainFrame renderTreeAsExternalRepresentation]";
@@ -735,21 +872,27 @@ void dump()
{
invalidateAnyPreviousWaitToDumpWatchdog();
+ bool dumpAsText = gLayoutTestController->dumpAsText();
if (dumpTree) {
NSString *resultString = nil;
NSData *resultData = nil;
+ NSString *resultMimeType = @"text/plain";
- bool dumpAsText = layoutTestController->dumpAsText();
dumpAsText |= [[[mainFrame dataSource] _responseMIMEType] isEqualToString:@"text/plain"];
- layoutTestController->setDumpAsText(dumpAsText);
- if (layoutTestController->dumpAsText()) {
+ gLayoutTestController->setDumpAsText(dumpAsText);
+ if (gLayoutTestController->dumpAsText()) {
resultString = dumpFramesAsText(mainFrame);
- } else if (layoutTestController->dumpDOMAsWebArchive()) {
+ } else if (gLayoutTestController->dumpAsPDF()) {
+ resultData = dumpFrameAsPDF(mainFrame);
+ resultMimeType = @"application/pdf";
+ } else if (gLayoutTestController->dumpDOMAsWebArchive()) {
WebArchive *webArchive = [[mainFrame DOMDocument] webArchive];
resultString = serializeWebArchiveToXML(webArchive);
- } else if (layoutTestController->dumpSourceAsWebArchive()) {
+ resultMimeType = @"application/x-webarchive";
+ } else if (gLayoutTestController->dumpSourceAsWebArchive()) {
WebArchive *webArchive = [[mainFrame dataSource] webArchive];
resultString = serializeWebArchiveToXML(webArchive);
+ resultMimeType = @"application/x-webarchive";
} else {
sizeWebViewForCurrentTest();
resultString = [mainFrame renderTreeAsExternalRepresentation];
@@ -758,25 +901,32 @@ void dump()
if (resultString && !resultData)
resultData = [resultString dataUsingEncoding:NSUTF8StringEncoding];
+ printf("Content-Type: %s\n", [resultMimeType UTF8String]);
+
if (resultData) {
fwrite([resultData bytes], 1, [resultData length], stdout);
- if (!layoutTestController->dumpAsText() && !layoutTestController->dumpDOMAsWebArchive() && !layoutTestController->dumpSourceAsWebArchive())
+ if (!gLayoutTestController->dumpAsText() && !gLayoutTestController->dumpDOMAsWebArchive() && !gLayoutTestController->dumpSourceAsWebArchive())
dumpFrameScrollPosition(mainFrame);
- if (layoutTestController->dumpBackForwardList())
+ if (gLayoutTestController->dumpBackForwardList())
dumpBackForwardListForAllWindows();
} else
printf("ERROR: nil result from %s", methodNameStringForFailedTest());
- if (printSeparators)
- puts("#EOF");
+ if (printSeparators) {
+ puts("#EOF"); // terminate the content block
+ fputs("#EOF\n", stderr);
+ }
}
- if (dumpPixels)
- dumpWebViewAsPixelsAndCompareWithExpected([currentTest UTF8String], dumpAllPixels);
+ if (dumpPixels && !dumpAsText)
+ dumpWebViewAsPixelsAndCompareWithExpected(gLayoutTestController->expectedPixelHash());
+
+ puts("#EOF"); // terminate the (possibly empty) pixels block
fflush(stdout);
+ fflush(stderr);
done = YES;
}
@@ -786,29 +936,24 @@ static bool shouldLogFrameLoadDelegates(const char *pathOrURL)
return strstr(pathOrURL, "loading/");
}
-static CFURLRef createCFURLFromPathOrURL(CFStringRef pathOrURLString)
-{
- CFURLRef URL;
- if (CFStringHasPrefix(pathOrURLString, CFSTR("http://")) || CFStringHasPrefix(pathOrURLString, CFSTR("https://")))
- URL = CFURLCreateWithString(NULL, pathOrURLString, NULL);
- else
- URL = CFURLCreateWithFileSystemPath(NULL, pathOrURLString, kCFURLPOSIXPathStyle, FALSE);
- return URL;
-}
-
static void resetWebViewToConsistentStateBeforeTesting()
{
WebView *webView = [mainFrame webView];
[(EditingDelegate *)[webView editingDelegate] setAcceptsEditing:YES];
[webView makeTextStandardSize:nil];
- [webView setTabKeyCyclesThroughElements: YES];
+ [webView resetPageZoom:nil];
+ [webView setTabKeyCyclesThroughElements:YES];
[webView setPolicyDelegate:nil];
[webView _setDashboardBehavior:WebDashboardBehaviorUseBackwardCompatibilityMode to:NO];
+ [webView _clearMainFrameName];
WebPreferences *preferences = [webView preferences];
[preferences setPrivateBrowsingEnabled:NO];
[preferences setAuthorAndUserStylesEnabled:YES];
[preferences setJavaScriptCanOpenWindowsAutomatically:YES];
+ [preferences setOfflineWebApplicationCacheEnabled:YES];
+ [preferences setFullDocumentTeardownEnabled:YES];
+ [preferences setDeveloperExtrasEnabled:NO];
if (persistentUserStyleSheetLocation) {
[preferences setUserStyleSheetLocation:[NSURL URLWithString:(NSString *)(persistentUserStyleSheetLocation.get())]];
@@ -816,56 +961,72 @@ static void resetWebViewToConsistentStateBeforeTesting()
} else
[preferences setUserStyleSheetEnabled:NO];
+ [[mainFrame webView] setSmartInsertDeleteEnabled:YES];
+ [[[mainFrame webView] inspector] setJavaScriptProfilingEnabled:NO];
+
[WebView _setUsesTestModeFocusRingColor:YES];
}
-static void runTest(const char *pathOrURL)
+static void runTest(const string& testPathOrURL)
{
- CFStringRef pathOrURLString = CFStringCreateWithCString(NULL, pathOrURL, kCFStringEncodingUTF8);
+ ASSERT(!testPathOrURL.empty());
+
+ // Look for "'" as a separator between the path or URL, and the pixel dump hash that follows.
+ string pathOrURL(testPathOrURL);
+ string expectedPixelHash;
+
+ size_t separatorPos = pathOrURL.find("'");
+ if (separatorPos != string::npos) {
+ pathOrURL = string(testPathOrURL, 0, separatorPos);
+ expectedPixelHash = string(testPathOrURL, separatorPos + 1);
+ }
+
+ NSString *pathOrURLString = [NSString stringWithUTF8String:pathOrURL.c_str()];
if (!pathOrURLString) {
- fprintf(stderr, "Failed to parse filename as UTF-8: %s\n", pathOrURL);
+ fprintf(stderr, "Failed to parse \"%s\" as UTF-8\n", pathOrURL.c_str());
return;
}
- CFURLRef URL = createCFURLFromPathOrURL(pathOrURLString);
- if (!URL) {
- CFRelease(pathOrURLString);
- fprintf(stderr, "Can't turn %s into a CFURL\n", pathOrURL);
+ NSURL *url;
+ if ([pathOrURLString hasPrefix:@"http://"] || [pathOrURLString hasPrefix:@"https://"])
+ url = [NSURL URLWithString:pathOrURLString];
+ else
+ url = [NSURL fileURLWithPath:pathOrURLString];
+ if (!url) {
+ fprintf(stderr, "Failed to parse \"%s\" as a URL\n", pathOrURL.c_str());
return;
}
+ const string testURL([[url absoluteString] UTF8String]);
+
resetWebViewToConsistentStateBeforeTesting();
- layoutTestController = new LayoutTestController(testRepaintDefault, repaintSweepHorizontallyDefault);
+ gLayoutTestController = new LayoutTestController(testURL, expectedPixelHash);
topLoadingFrame = nil;
done = NO;
if (disallowedURLs)
CFSetRemoveAllValues(disallowedURLs);
- if (shouldLogFrameLoadDelegates(pathOrURL))
- layoutTestController->setDumpFrameLoadCallbacks(true);
+ if (shouldLogFrameLoadDelegates(pathOrURL.c_str()))
+ gLayoutTestController->setDumpFrameLoadCallbacks(true);
if ([WebHistory optionalSharedHistory])
[WebHistory setOptionalSharedHistory:nil];
lastMousePosition = NSZeroPoint;
lastClickPosition = NSZeroPoint;
- if (currentTest != nil)
- CFRelease(currentTest);
- currentTest = (NSString *)pathOrURLString;
[prevTestBFItem release];
prevTestBFItem = [[[[mainFrame webView] backForwardList] currentItem] retain];
WorkQueue::shared()->clear();
WorkQueue::shared()->setFrozen(false);
- BOOL _shouldIgnoreWebCoreNodeLeaks = shouldIgnoreWebCoreNodeLeaks(CFURLGetString(URL));
- if (_shouldIgnoreWebCoreNodeLeaks)
+ bool ignoreWebCoreNodeLeaks = shouldIgnoreWebCoreNodeLeaks(testURL);
+ if (ignoreWebCoreNodeLeaks)
[WebCoreStatistics startIgnoringWebCoreNodeLeaks];
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [mainFrame loadRequest:[NSURLRequest requestWithURL:(NSURL *)URL]];
- CFRelease(URL);
+ [mainFrame loadRequest:[NSURLRequest requestWithURL:url]];
[pool release];
while (!done) {
pool = [[NSAutoreleasePool alloc] init];
@@ -878,7 +1039,7 @@ static void runTest(const char *pathOrURL)
WorkQueue::shared()->clear();
- if (layoutTestController->closeRemainingWindowsWhenComplete()) {
+ if (gLayoutTestController->closeRemainingWindowsWhenComplete()) {
NSArray* array = [DumpRenderTreeWindow openWindows];
unsigned count = [array count];
@@ -905,10 +1066,10 @@ static void runTest(const char *pathOrURL)
ASSERT(CFArrayGetCount(openWindowsRef) == 1);
ASSERT(CFArrayGetValueAtIndex(openWindowsRef, 0) == [[mainFrame webView] window]);
- delete layoutTestController;
- layoutTestController = 0;
+ gLayoutTestController->deref();
+ gLayoutTestController = 0;
- if (_shouldIgnoreWebCoreNodeLeaks)
+ if (ignoreWebCoreNodeLeaks)
[WebCoreStatistics stopIgnoringWebCoreNodeLeaks];
}
diff --git a/WebKitTools/DumpRenderTree/mac/DumpRenderTreeMac.h b/WebKitTools/DumpRenderTree/mac/DumpRenderTreeMac.h
index c4c7573..03d354d 100644
--- a/WebKitTools/DumpRenderTree/mac/DumpRenderTreeMac.h
+++ b/WebKitTools/DumpRenderTree/mac/DumpRenderTreeMac.h
@@ -32,6 +32,12 @@
// FIXME: we should add a config.h file for DumpRenderTree.
#define WTF_PLATFORM_CF 1
+#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4
+#define BUILDING_ON_TIGER 1
+#elif MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5
+#define BUILDING_ON_LEOPARD 1
+#endif
+
@class DumpRenderTreeDraggingInfo;
@class NavigationController;
@class PolicyDelegate;
@@ -45,7 +51,7 @@ extern CFMutableSetRef disallowedURLs;
extern WebFrame* mainFrame;
extern WebFrame* topLoadingFrame;
extern DumpRenderTreeDraggingInfo *draggingInfo;
-extern NavigationController* navigationController;
+extern NavigationController* gNavigationController;
extern PolicyDelegate* policyDelegate;
extern const unsigned maxViewHeight;
diff --git a/WebKitTools/DumpRenderTree/mac/DumpRenderTreePasteboard.h b/WebKitTools/DumpRenderTree/mac/DumpRenderTreePasteboard.h
index 6a01a42..ba2754b 100644
--- a/WebKitTools/DumpRenderTree/mac/DumpRenderTreePasteboard.h
+++ b/WebKitTools/DumpRenderTree/mac/DumpRenderTreePasteboard.h
@@ -29,9 +29,10 @@
*/
#import <AppKit/AppKit.h>
+#import <WebKit/WebTypesInternal.h>
@interface DumpRenderTreePasteboard : NSPasteboard
-- (int)declareType:(NSString *)type owner:(id)newOwner;
+- (NSInteger)declareType:(NSString *)type owner:(id)newOwner;
+ (void)releaseLocalPasteboards;
@end
diff --git a/WebKitTools/DumpRenderTree/mac/DumpRenderTreePasteboard.m b/WebKitTools/DumpRenderTree/mac/DumpRenderTreePasteboard.m
index b5a9b7a..a797b5c 100644
--- a/WebKitTools/DumpRenderTree/mac/DumpRenderTreePasteboard.m
+++ b/WebKitTools/DumpRenderTree/mac/DumpRenderTreePasteboard.m
@@ -28,14 +28,17 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#import "DumpRenderTreeMac.h"
#import "DumpRenderTreePasteboard.h"
+#import <WebKit/WebTypesInternal.h>
+
@interface LocalPasteboard : NSPasteboard
{
NSMutableArray *typesArray;
NSMutableSet *typesSet;
NSMutableDictionary *dataByType;
- int changeCount;
+ NSInteger changeCount;
}
@end
@@ -68,7 +71,7 @@ static NSMutableDictionary *localPasteboards;
// Convenience method for JS so that it doesn't have to try and create a NSArray on the objc side instead
// of the usual WebScriptObject that is passed around
-- (int)declareType:(NSString *)type owner:(id)newOwner
+- (NSInteger)declareType:(NSString *)type owner:(id)newOwner
{
return [self declareTypes:[NSArray arrayWithObject:type] owner:newOwner];
}
@@ -107,7 +110,7 @@ static NSMutableDictionary *localPasteboards;
{
}
-- (int)declareTypes:(NSArray *)newTypes owner:(id)newOwner
+- (NSInteger)declareTypes:(NSArray *)newTypes owner:(id)newOwner
{
[typesArray removeAllObjects];
[typesSet removeAllObjects];
@@ -115,7 +118,7 @@ static NSMutableDictionary *localPasteboards;
return [self addTypes:newTypes owner:newOwner];
}
-- (int)addTypes:(NSArray *)newTypes owner:(id)newOwner
+- (NSInteger)addTypes:(NSArray *)newTypes owner:(id)newOwner
{
unsigned count = [newTypes count];
unsigned i;
@@ -134,7 +137,7 @@ static NSMutableDictionary *localPasteboards;
return ++changeCount;
}
-- (int)changeCount
+- (NSInteger)changeCount
{
return changeCount;
}
diff --git a/WebKitTools/DumpRenderTree/mac/DumpRenderTreeWindow.mm b/WebKitTools/DumpRenderTree/mac/DumpRenderTreeWindow.mm
index 9e5e104..b3fc5a7 100644
--- a/WebKitTools/DumpRenderTree/mac/DumpRenderTreeWindow.mm
+++ b/WebKitTools/DumpRenderTree/mac/DumpRenderTreeWindow.mm
@@ -34,6 +34,7 @@
// FIXME: This file is ObjC++ only because of this include. :(
#import "LayoutTestController.h"
+#import <WebKit/WebTypesInternal.h>
CFMutableArrayRef openWindowsRef = 0;
@@ -52,7 +53,7 @@ static CFArrayCallBacks NonRetainingArrayCallbacks = {
return [[(NSArray *)openWindowsRef copy] autorelease];
}
-- (id)initWithContentRect:(NSRect)contentRect styleMask:(unsigned int)styleMask backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation
+- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation
{
if (!openWindowsRef)
openWindowsRef = CFArrayCreateMutable(NULL, 0, &NonRetainingArrayCallbacks);
@@ -73,7 +74,7 @@ static CFArrayCallBacks NonRetainingArrayCallbacks = {
- (BOOL)isKeyWindow
{
- return layoutTestController ? layoutTestController->windowIsKey() : YES;
+ return gLayoutTestController ? gLayoutTestController->windowIsKey() : YES;
}
- (void)keyDown:(id)sender
diff --git a/WebKitTools/DumpRenderTree/mac/EditingDelegate.mm b/WebKitTools/DumpRenderTree/mac/EditingDelegate.mm
index a8f0815..cf4026b 100644
--- a/WebKitTools/DumpRenderTree/mac/EditingDelegate.mm
+++ b/WebKitTools/DumpRenderTree/mac/EditingDelegate.mm
@@ -73,14 +73,14 @@
- (BOOL)webView:(WebView *)webView shouldBeginEditingInDOMRange:(DOMRange *)range
{
- if (!done && layoutTestController->dumpEditingCallbacks())
+ if (!done && gLayoutTestController->dumpEditingCallbacks())
printf("EDITING DELEGATE: shouldBeginEditingInDOMRange:%s\n", [[range dump] UTF8String]);
return acceptsEditing;
}
- (BOOL)webView:(WebView *)webView shouldEndEditingInDOMRange:(DOMRange *)range
{
- if (!done && layoutTestController->dumpEditingCallbacks())
+ if (!done && gLayoutTestController->dumpEditingCallbacks())
printf("EDITING DELEGATE: shouldEndEditingInDOMRange:%s\n", [[range dump] UTF8String]);
return acceptsEditing;
}
@@ -93,7 +93,7 @@
"WebViewInsertActionDropped",
};
- if (!done && layoutTestController->dumpEditingCallbacks())
+ if (!done && gLayoutTestController->dumpEditingCallbacks())
printf("EDITING DELEGATE: shouldInsertNode:%s replacingDOMRange:%s givenAction:%s\n", [[node dumpPath] UTF8String], [[range dump] UTF8String], insertactionstring[action]);
return acceptsEditing;
}
@@ -106,14 +106,14 @@
"WebViewInsertActionDropped",
};
- if (!done && layoutTestController->dumpEditingCallbacks())
+ if (!done && gLayoutTestController->dumpEditingCallbacks())
printf("EDITING DELEGATE: shouldInsertText:%s replacingDOMRange:%s givenAction:%s\n", [[text description] UTF8String], [[range dump] UTF8String], insertactionstring[action]);
return acceptsEditing;
}
- (BOOL)webView:(WebView *)webView shouldDeleteDOMRange:(DOMRange *)range
{
- if (!done && layoutTestController->dumpEditingCallbacks())
+ if (!done && gLayoutTestController->dumpEditingCallbacks())
printf("EDITING DELEGATE: shouldDeleteDOMRange:%s\n", [[range dump] UTF8String]);
return acceptsEditing;
}
@@ -134,52 +134,52 @@
"TRUE"
};
- if (!done && layoutTestController->dumpEditingCallbacks())
+ if (!done && gLayoutTestController->dumpEditingCallbacks())
printf("EDITING DELEGATE: shouldChangeSelectedDOMRange:%s toDOMRange:%s affinity:%s stillSelecting:%s\n", [[currentRange dump] UTF8String], [[proposedRange dump] UTF8String], affinitystring[selectionAffinity], boolstring[flag]);
return acceptsEditing;
}
- (BOOL)webView:(WebView *)webView shouldApplyStyle:(DOMCSSStyleDeclaration *)style toElementsInDOMRange:(DOMRange *)range
{
- if (!done && layoutTestController->dumpEditingCallbacks())
+ if (!done && gLayoutTestController->dumpEditingCallbacks())
printf("EDITING DELEGATE: shouldApplyStyle:%s toElementsInDOMRange:%s\n", [[style description] UTF8String], [[range dump] UTF8String]);
return acceptsEditing;
}
- (BOOL)webView:(WebView *)webView shouldChangeTypingStyle:(DOMCSSStyleDeclaration *)currentStyle toStyle:(DOMCSSStyleDeclaration *)proposedStyle
{
- if (!done && layoutTestController->dumpEditingCallbacks())
+ if (!done && gLayoutTestController->dumpEditingCallbacks())
printf("EDITING DELEGATE: shouldChangeTypingStyle:%s toStyle:%s\n", [[currentStyle description] UTF8String], [[proposedStyle description] UTF8String]);
return acceptsEditing;
}
- (void)webViewDidBeginEditing:(NSNotification *)notification
{
- if (!done && layoutTestController->dumpEditingCallbacks())
+ if (!done && gLayoutTestController->dumpEditingCallbacks())
printf("EDITING DELEGATE: webViewDidBeginEditing:%s\n", [[notification name] UTF8String]);
}
- (void)webViewDidChange:(NSNotification *)notification
{
- if (!done && layoutTestController->dumpEditingCallbacks())
+ if (!done && gLayoutTestController->dumpEditingCallbacks())
printf("EDITING DELEGATE: webViewDidChange:%s\n", [[notification name] UTF8String]);
}
- (void)webViewDidEndEditing:(NSNotification *)notification
{
- if (!done && layoutTestController->dumpEditingCallbacks())
+ if (!done && gLayoutTestController->dumpEditingCallbacks())
printf("EDITING DELEGATE: webViewDidEndEditing:%s\n", [[notification name] UTF8String]);
}
- (void)webViewDidChangeTypingStyle:(NSNotification *)notification
{
- if (!done && layoutTestController->dumpEditingCallbacks())
+ if (!done && gLayoutTestController->dumpEditingCallbacks())
printf("EDITING DELEGATE: webViewDidChangeTypingStyle:%s\n", [[notification name] UTF8String]);
}
- (void)webViewDidChangeSelection:(NSNotification *)notification
{
- if (!done && layoutTestController->dumpEditingCallbacks())
+ if (!done && gLayoutTestController->dumpEditingCallbacks())
printf("EDITING DELEGATE: webViewDidChangeSelection:%s\n", [[notification name] UTF8String]);
}
diff --git a/WebKitTools/DumpRenderTree/mac/EventSendingController.h b/WebKitTools/DumpRenderTree/mac/EventSendingController.h
index 28d0385..deee848 100644
--- a/WebKitTools/DumpRenderTree/mac/EventSendingController.h
+++ b/WebKitTools/DumpRenderTree/mac/EventSendingController.h
@@ -31,7 +31,7 @@
@interface EventSendingController : NSObject <DOMEventListener>
{
- BOOL down;
+ BOOL leftMouseButtonDown;
BOOL dragMode;
int clickCount;
NSTimeInterval lastClick;
diff --git a/WebKitTools/DumpRenderTree/mac/EventSendingController.mm b/WebKitTools/DumpRenderTree/mac/EventSendingController.mm
index 8e9be38..8be05e7 100644
--- a/WebKitTools/DumpRenderTree/mac/EventSendingController.mm
+++ b/WebKitTools/DumpRenderTree/mac/EventSendingController.mm
@@ -35,13 +35,29 @@
#import "DumpRenderTreeDraggingInfo.h"
#import <Carbon/Carbon.h> // for GetCurrentEventTime()
-#import <WebKit/WebKit.h>
#import <WebKit/DOMPrivate.h>
+#import <WebKit/WebKit.h>
+#import <WebKit/WebViewPrivate.h>
extern "C" void _NSNewKillRingSequence();
+enum MouseAction {
+ MouseDown,
+ MouseUp,
+ MouseDragged
+};
+
+// Match the DOM spec (sadly the DOM spec does not provide an enum)
+enum MouseButton {
+ LeftMouseButton = 0,
+ MiddleMouseButton = 1,
+ RightMouseButton = 2,
+ NoMouseButton = -1
+};
+
NSPoint lastMousePosition;
NSPoint lastClickPosition;
+int lastClickButton = NoMouseButton;
NSArray *webkitDomEventNames;
NSMutableArray *savedMouseEvents; // mouse events sent between mouseDown and mouseUp are stored here, and then executed at once.
BOOL replayingSavedEvents;
@@ -102,8 +118,8 @@ BOOL replayingSavedEvents;
+ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
{
- if (aSelector == @selector(mouseDown)
- || aSelector == @selector(mouseUp)
+ if (aSelector == @selector(mouseDown:)
+ || aSelector == @selector(mouseUp:)
|| aSelector == @selector(contextClick)
|| aSelector == @selector(mouseMoveToX:Y:)
|| aSelector == @selector(leapForward:)
@@ -112,7 +128,9 @@ BOOL replayingSavedEvents;
|| aSelector == @selector(fireKeyboardEventsToElement:)
|| aSelector == @selector(clearKillRing)
|| aSelector == @selector(textZoomIn)
- || aSelector == @selector(textZoomOut))
+ || aSelector == @selector(textZoomOut)
+ || aSelector == @selector(zoomPageIn)
+ || aSelector == @selector(zoomPageOut))
return NO;
return YES;
}
@@ -126,6 +144,10 @@ BOOL replayingSavedEvents;
+ (NSString *)webScriptNameForSelector:(SEL)aSelector
{
+ if (aSelector == @selector(mouseDown:))
+ return @"mouseDown";
+ if (aSelector == @selector(mouseUp:))
+ return @"mouseUp";
if (aSelector == @selector(mouseMoveToX:Y:))
return @"mouseMoveTo";
if (aSelector == @selector(leapForward:))
@@ -161,7 +183,7 @@ BOOL replayingSavedEvents;
- (void)leapForward:(int)milliseconds
{
- if (dragMode && down && !replayingSavedEvents) {
+ if (dragMode && leftMouseButtonDown && !replayingSavedEvents) {
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[EventSendingController instanceMethodSignatureForSelector:@selector(leapForward:)]];
[invocation setTarget:self];
[invocation setSelector:@selector(leapForward:)];
@@ -180,15 +202,59 @@ BOOL replayingSavedEvents;
_NSNewKillRingSequence();
}
-- (void)mouseDown
+static NSEventType eventTypeForMouseButtonAndAction(int button, MouseAction action)
+{
+ switch (button) {
+ case LeftMouseButton:
+ switch (action) {
+ case MouseDown:
+ return NSLeftMouseDown;
+ case MouseUp:
+ return NSLeftMouseUp;
+ case MouseDragged:
+ return NSLeftMouseDragged;
+ }
+ case RightMouseButton:
+ switch (action) {
+ case MouseDown:
+ return NSRightMouseDown;
+ case MouseUp:
+ return NSRightMouseUp;
+ case MouseDragged:
+ return NSRightMouseDragged;
+ }
+ default:
+ switch (action) {
+ case MouseDown:
+ return NSOtherMouseDown;
+ case MouseUp:
+ return NSOtherMouseUp;
+ case MouseDragged:
+ return NSOtherMouseDragged;
+ }
+ }
+ assert(0);
+ return static_cast<NSEventType>(0);
+}
+
+- (void)updateClickCountForButton:(int)buttonNumber
{
- [[[mainFrame frameView] documentView] layout];
if (([self currentEventTime] - lastClick >= 1) ||
- !NSEqualPoints(lastMousePosition, lastClickPosition))
+ !NSEqualPoints(lastMousePosition, lastClickPosition) ||
+ lastClickButton != buttonNumber) {
clickCount = 1;
- else
+ lastClickButton = buttonNumber;
+ } else
clickCount++;
- NSEvent *event = [NSEvent mouseEventWithType:NSLeftMouseDown
+}
+
+- (void)mouseDown:(int)buttonNumber
+{
+ [[[mainFrame frameView] documentView] layout];
+ [self updateClickCountForButton:buttonNumber];
+
+ NSEventType eventType = eventTypeForMouseButtonAndAction(buttonNumber, MouseDown);
+ NSEvent *event = [NSEvent mouseEventWithType:eventType
location:lastMousePosition
modifierFlags:0
timestamp:[self currentEventTime]
@@ -201,7 +267,8 @@ BOOL replayingSavedEvents;
NSView *subView = [[mainFrame webView] hitTest:[event locationInWindow]];
if (subView) {
[subView mouseDown:event];
- down = YES;
+ if (buttonNumber == LeftMouseButton)
+ leftMouseButtonDown = YES;
}
}
@@ -215,12 +282,23 @@ BOOL replayingSavedEvents;
[[mainFrame webView] makeTextSmaller:self];
}
-- (void)mouseUp
+- (void)zoomPageIn
+{
+ [[mainFrame webView] zoomPageIn:self];
+}
+
+- (void)zoomPageOut
+{
+ [[mainFrame webView] zoomPageOut:self];
+}
+
+- (void)mouseUp:(int)buttonNumber
{
if (dragMode && !replayingSavedEvents) {
- NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[EventSendingController instanceMethodSignatureForSelector:@selector(mouseUp)]];
+ NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[EventSendingController instanceMethodSignatureForSelector:@selector(mouseUp:)]];
[invocation setTarget:self];
- [invocation setSelector:@selector(mouseUp)];
+ [invocation setSelector:@selector(mouseUp:)];
+ [invocation setArgument:&buttonNumber atIndex:2];
[EventSendingController saveEvent:invocation];
[EventSendingController replaySavedEvents];
@@ -229,7 +307,8 @@ BOOL replayingSavedEvents;
}
[[[mainFrame frameView] documentView] layout];
- NSEvent *event = [NSEvent mouseEventWithType:NSLeftMouseUp
+ NSEventType eventType = eventTypeForMouseButtonAndAction(buttonNumber, MouseUp);
+ NSEvent *event = [NSEvent mouseEventWithType:eventType
location:lastMousePosition
modifierFlags:0
timestamp:[self currentEventTime]
@@ -246,7 +325,8 @@ BOOL replayingSavedEvents;
targetView = targetView ? targetView : [[mainFrame frameView] documentView];
assert(targetView);
[targetView mouseUp:event];
- down = NO;
+ if (buttonNumber == LeftMouseButton)
+ leftMouseButtonDown = NO;
lastClick = [event timestamp];
lastClickPosition = lastMousePosition;
if (draggingInfo) {
@@ -266,7 +346,7 @@ BOOL replayingSavedEvents;
- (void)mouseMoveToX:(int)x Y:(int)y
{
- if (dragMode && down && !replayingSavedEvents) {
+ if (dragMode && leftMouseButtonDown && !replayingSavedEvents) {
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[EventSendingController instanceMethodSignatureForSelector:@selector(mouseMoveToX:Y:)]];
[invocation setTarget:self];
[invocation setSelector:@selector(mouseMoveToX:Y:)];
@@ -280,19 +360,19 @@ BOOL replayingSavedEvents;
NSView *view = [mainFrame webView];
lastMousePosition = [view convertPoint:NSMakePoint(x, [view frame].size.height - y) toView:nil];
- NSEvent *event = [NSEvent mouseEventWithType:(down ? NSLeftMouseDragged : NSMouseMoved)
+ NSEvent *event = [NSEvent mouseEventWithType:(leftMouseButtonDown ? NSLeftMouseDragged : NSMouseMoved)
location:lastMousePosition
modifierFlags:0
timestamp:[self currentEventTime]
windowNumber:[[view window] windowNumber]
context:[NSGraphicsContext currentContext]
eventNumber:++eventNumber
- clickCount:(down ? clickCount : 0)
+ clickCount:(leftMouseButtonDown ? clickCount : 0)
pressure:0.0];
NSView *subView = [[mainFrame webView] hitTest:[event locationInWindow]];
if (subView) {
- if (down) {
+ if (leftMouseButtonDown) {
[subView mouseDragged:event];
if (draggingInfo) {
[[draggingInfo draggingSource] draggedImage:[draggingInfo draggedImage] movedTo:lastMousePosition];
@@ -306,11 +386,9 @@ BOOL replayingSavedEvents;
- (void)contextClick
{
[[[mainFrame frameView] documentView] layout];
- if ([self currentEventTime] - lastClick >= 1)
- clickCount = 1;
- else
- clickCount++;
- NSEvent *event = [NSEvent mouseEventWithType:NSRightMouseDown
+ [self updateClickCountForButton:RightMouseButton];
+
+ NSEvent *event = [NSEvent mouseEventWithType:NSRightMouseDown
location:lastMousePosition
modifierFlags:0
timestamp:[self currentEventTime]
diff --git a/WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.h b/WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.h
index 3b86fdf..6c3cbdb 100644
--- a/WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.h
+++ b/WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.h
@@ -28,10 +28,12 @@
#import <Foundation/Foundation.h>
+class AccessibilityController;
class GCController;
@interface FrameLoadDelegate : NSObject
{
+ AccessibilityController* accessibilityController;
GCController* gcController;
}
@end
diff --git a/WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.mm b/WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.mm
index 98b6bac..3d7f8b4 100644
--- a/WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.mm
+++ b/WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.mm
@@ -29,6 +29,7 @@
#import "DumpRenderTree.h"
#import "FrameLoadDelegate.h"
+#import "AccessibilityController.h"
#import "AppleScriptController.h"
#import "EventSendingController.h"
#import "GCController.h"
@@ -94,8 +95,10 @@
- (id)init
{
- if ((self = [super init]))
+ if ((self = [super init])) {
gcController = new GCController;
+ accessibilityController = new AccessibilityController;
+ }
return self;
}
@@ -117,7 +120,7 @@
}
// if we didn't start a new load, then we finished all the commands, so we're ready to dump state
- if (!topLoadingFrame && !layoutTestController->waitToDump())
+ if (!topLoadingFrame && !gLayoutTestController->waitToDump())
dump();
}
@@ -126,7 +129,7 @@
if ([dataSource webFrame] == topLoadingFrame) {
topLoadingFrame = nil;
WorkQueue::shared()->setFrozen(true); // first complete load freezes the queue for the rest of this test
- if (!layoutTestController->waitToDump()) {
+ if (!gLayoutTestController->waitToDump()) {
if (WorkQueue::shared()->count())
[self performSelector:@selector(processWork:) withObject:nil afterDelay:0];
else
@@ -137,7 +140,7 @@
- (void)webView:(WebView *)sender didStartProvisionalLoadForFrame:(WebFrame *)frame
{
- if (!done && layoutTestController->dumpFrameLoadCallbacks()) {
+ if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
NSString *string = [NSString stringWithFormat:@"%@ - didStartProvisionalLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
printf ("%s\n", [string UTF8String]);
}
@@ -147,11 +150,17 @@
// end up doing two dumps for one test.
if (!topLoadingFrame && !done)
topLoadingFrame = frame;
+
+ if (!done && gLayoutTestController->stopProvisionalFrameLoads()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - stopping load in didStartProvisionalLoadForFrame callback", [frame _drt_descriptionSuitableForTestResult]];
+ printf ("%s\n", [string UTF8String]);
+ [frame stopLoading];
+ }
}
- (void)webView:(WebView *)sender didCommitLoadForFrame:(WebFrame *)frame
{
- if (!done && layoutTestController->dumpFrameLoadCallbacks()) {
+ if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
NSString *string = [NSString stringWithFormat:@"%@ - didCommitLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
printf ("%s\n", [string UTF8String]);
}
@@ -159,7 +168,7 @@
ASSERT(![frame provisionalDataSource]);
ASSERT([frame dataSource]);
- layoutTestController->setWindowIsKey(true);
+ gLayoutTestController->setWindowIsKey(true);
NSView *documentView = [[mainFrame frameView] documentView];
[[[mainFrame webView] window] makeFirstResponder:documentView];
if ([documentView isKindOfClass:[WebHTMLView class]])
@@ -168,7 +177,7 @@
- (void)webView:(WebView *)sender didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame
{
- if (!done && layoutTestController->dumpFrameLoadCallbacks()) {
+ if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
NSString *string = [NSString stringWithFormat:@"%@ - didFailProvisionalLoadWithError", [frame _drt_descriptionSuitableForTestResult]];
printf ("%s\n", [string UTF8String]);
}
@@ -189,7 +198,7 @@
ASSERT([frame dataSource]);
ASSERT(frame == [[frame dataSource] webFrame]);
- if (!done && layoutTestController->dumpFrameLoadCallbacks()) {
+ if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
NSString *string = [NSString stringWithFormat:@"%@ - didFinishLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
printf ("%s\n", [string UTF8String]);
}
@@ -200,12 +209,12 @@
if ([[sender mainFrame] isEqual:frame])
[sender displayIfNeeded];
[self webView:sender locationChangeDone:nil forDataSource:[frame dataSource]];
- [navigationController webView:sender didFinishLoadForFrame:frame];
+ [gNavigationController webView:sender didFinishLoadForFrame:frame];
}
- (void)webView:(WebView *)sender didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame;
{
- if (!done && layoutTestController->dumpFrameLoadCallbacks()) {
+ if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
NSString *string = [NSString stringWithFormat:@"%@ - didFailLoadWithError", [frame _drt_descriptionSuitableForTestResult]];
printf ("%s\n", [string UTF8String]);
}
@@ -218,7 +227,7 @@
- (void)webView:(WebView *)webView windowScriptObjectAvailable:(WebScriptObject *)windowScriptObject;
{
- if (!done && layoutTestController->dumpFrameLoadCallbacks()) {
+ if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
NSString *string = [NSString stringWithFormat:@"?? - windowScriptObjectAvailable"];
printf ("%s\n", [string UTF8String]);
}
@@ -236,13 +245,16 @@
JSObjectRef globalObject = JSContextGetGlobalObject(context);
JSValueRef exception = 0;
- ASSERT(layoutTestController);
- layoutTestController->makeWindowObject(context, globalObject, &exception);
+ ASSERT(gLayoutTestController);
+ gLayoutTestController->makeWindowObject(context, globalObject, &exception);
ASSERT(!exception);
gcController->makeWindowObject(context, globalObject, &exception);
ASSERT(!exception);
+ accessibilityController->makeWindowObject(context, globalObject, &exception);
+ ASSERT(!exception);
+
// Make Old-Style controllers
EventSendingController *esc = [[EventSendingController alloc] init];
[obj setValue:esc forKey:@"eventSender"];
@@ -260,7 +272,7 @@
[obj setValue:occ forKey:@"objCController"];
[occ release];
- [obj setValue:navigationController forKey:@"navigationController"];
+ [obj setValue:gNavigationController forKey:@"navigationController"];
ObjCPlugin *plugin = [[ObjCPlugin alloc] init];
[obj setValue:plugin forKey:@"objCPlugin"];
@@ -273,18 +285,18 @@
- (void)webView:(WebView *)sender didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame
{
- if (!done && layoutTestController->dumpFrameLoadCallbacks()) {
+ if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
NSString *string = [NSString stringWithFormat:@"%@ - didReceiveTitle: %@", [frame _drt_descriptionSuitableForTestResult], title];
printf ("%s\n", [string UTF8String]);
}
- if (layoutTestController->dumpTitleChanges())
+ if (gLayoutTestController->dumpTitleChanges())
printf("TITLE CHANGED: %s\n", [title UTF8String]);
}
- (void)webView:(WebView *)sender didReceiveServerRedirectForProvisionalLoadForFrame:(WebFrame *)frame
{
- if (!done && layoutTestController->dumpFrameLoadCallbacks()) {
+ if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
NSString *string = [NSString stringWithFormat:@"%@ - didReceiveServerRedirectForProvisionalLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
printf ("%s\n", [string UTF8String]);
}
@@ -292,7 +304,7 @@
- (void)webView:(WebView *)sender didChangeLocationWithinPageForFrame:(WebFrame *)frame
{
- if (!done && layoutTestController->dumpFrameLoadCallbacks()) {
+ if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
NSString *string = [NSString stringWithFormat:@"%@ - didChangeLocationWithinPageForFrame", [frame _drt_descriptionSuitableForTestResult]];
printf ("%s\n", [string UTF8String]);
}
@@ -300,7 +312,7 @@
- (void)webView:(WebView *)sender willPerformClientRedirectToURL:(NSURL *)URL delay:(NSTimeInterval)seconds fireDate:(NSDate *)date forFrame:(WebFrame *)frame
{
- if (!done && layoutTestController->dumpFrameLoadCallbacks()) {
+ if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
NSString *string = [NSString stringWithFormat:@"%@ - willPerformClientRedirectToURL: %@ ", [frame _drt_descriptionSuitableForTestResult], [URL _drt_descriptionSuitableForTestResult]];
printf ("%s\n", [string UTF8String]);
}
@@ -308,7 +320,7 @@
- (void)webView:(WebView *)sender didCancelClientRedirectForFrame:(WebFrame *)frame
{
- if (!done && layoutTestController->dumpFrameLoadCallbacks()) {
+ if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
NSString *string = [NSString stringWithFormat:@"%@ - didCancelClientRedirectForFrame", [frame _drt_descriptionSuitableForTestResult]];
printf ("%s\n", [string UTF8String]);
}
@@ -316,15 +328,21 @@
- (void)webView:(WebView *)sender didFinishDocumentLoadForFrame:(WebFrame *)frame;
{
- if (!done && layoutTestController->dumpFrameLoadCallbacks()) {
+ if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
NSString *string = [NSString stringWithFormat:@"%@ - didFinishDocumentLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
printf ("%s\n", [string UTF8String]);
+ } else if (!done) {
+ unsigned pendingFrameUnloadEvents = [frame _pendingFrameUnloadEventCount];
+ if (pendingFrameUnloadEvents) {
+ NSString *string = [NSString stringWithFormat:@"%@ - has %u onunload handler(s)", [frame _drt_descriptionSuitableForTestResult], pendingFrameUnloadEvents];
+ printf ("%s\n", [string UTF8String]);
+ }
}
}
- (void)webView:(WebView *)sender didHandleOnloadEventsForFrame:(WebFrame *)frame;
{
- if (!done && layoutTestController->dumpFrameLoadCallbacks()) {
+ if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
NSString *string = [NSString stringWithFormat:@"%@ - didHandleOnloadEventsForFrame", [frame _drt_descriptionSuitableForTestResult]];
printf ("%s\n", [string UTF8String]);
}
diff --git a/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm b/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm
index b321319..2200c27 100644
--- a/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm
+++ b/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm
@@ -36,13 +36,19 @@
#import <JavaScriptCore/JSRetainPtr.h>
#import <JavaScriptCore/JSStringRef.h>
#import <JavaScriptCore/JSStringRefCF.h>
+#import <WebKit/DOMDocument.h>
#import <WebKit/WebBackForwardList.h>
+#import <WebKit/WebDatabaseManagerPrivate.h>
+#import <WebKit/WebDataSource.h>
#import <WebKit/WebFrame.h>
+#import <WebKit/WebHTMLRepresentation.h>
#import <WebKit/WebHTMLViewPrivate.h>
#import <WebKit/WebHistory.h>
+#import <WebKit/WebInspector.h>
#import <WebKit/WebNSURLExtras.h>
#import <WebKit/WebPreferences.h>
#import <WebKit/WebPreferencesPrivate.h>
+#import <WebKit/WebSecurityOriginPrivate.h>
#import <WebKit/WebView.h>
#import <WebKit/WebViewPrivate.h>
#import <wtf/RetainPtr.h>
@@ -65,6 +71,11 @@ void LayoutTestController::addDisallowedURL(JSStringRef url)
CFSetAddValue(disallowedURLs, [request URL]);
}
+void LayoutTestController::clearAllDatabases()
+{
+ [[WebDatabaseManager sharedWebDatabaseManager] deleteAllDatabases];
+}
+
void LayoutTestController::clearBackForwardList()
{
WebBackForwardList *backForwardList = [[mainFrame webView] backForwardList];
@@ -170,6 +181,13 @@ void LayoutTestController::setCustomPolicyDelegate(bool setDelegate)
[[mainFrame webView] setPolicyDelegate:nil];
}
+void LayoutTestController::setDatabaseQuota(unsigned long long quota)
+{
+ WebSecurityOrigin *origin = [[WebSecurityOrigin alloc] initWithURL:[NSURL URLWithString:@"file:///"]];
+ [origin setQuota:quota];
+ [origin release];
+}
+
void LayoutTestController::setMainFrameIsFirstResponder(bool flag)
{
NSView *documentView = [[mainFrame frameView] documentView];
@@ -232,13 +250,24 @@ void LayoutTestController::setWindowIsKey(bool windowIsKey)
[(WebHTMLView *)documentView _updateFocusedAndActiveState];
}
+void LayoutTestController::setSmartInsertDeleteEnabled(bool flag)
+{
+ [[mainFrame webView] setSmartInsertDeleteEnabled:flag];
+}
+
+void LayoutTestController::setJavaScriptProfilingEnabled(bool profilingEnabled)
+{
+ [[[mainFrame webView] preferences] setDeveloperExtrasEnabled:profilingEnabled];
+ [[[mainFrame webView] inspector] setJavaScriptProfilingEnabled:profilingEnabled];
+}
+
static const CFTimeInterval waitToDumpWatchdogInterval = 10.0;
static void waitUntilDoneWatchdogFired(CFRunLoopTimerRef timer, void* info)
{
const char* message = "FAIL: Timed out waiting for notifyDone to be called\n";
- fprintf(stderr, message);
- fprintf(stdout, message);
+ fprintf(stderr, "%s", message);
+ fprintf(stdout, "%s", message);
dump();
}
@@ -256,6 +285,20 @@ int LayoutTestController::windowCount()
return CFArrayGetCount(openWindowsRef);
}
+bool LayoutTestController::elementDoesAutoCompleteForElementWithId(JSStringRef id)
+{
+ RetainPtr<CFStringRef> idCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, id));
+ NSString *idNS = (NSString *)idCF.get();
+
+ DOMElement *element = [[mainFrame DOMDocument] getElementById:idNS];
+ id rep = [[mainFrame dataSource] representation];
+
+ if ([rep class] == [WebHTMLRepresentation class])
+ return [(WebHTMLRepresentation *)rep elementDoesAutoComplete:element];
+
+ return false;
+}
+
void LayoutTestController::execCommand(JSStringRef name, JSStringRef value)
{
RetainPtr<CFStringRef> nameCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, name));
diff --git a/WebKitTools/DumpRenderTree/mac/ObjCController.m b/WebKitTools/DumpRenderTree/mac/ObjCController.m
index 1b9abb7..ec1ed38 100644
--- a/WebKitTools/DumpRenderTree/mac/ObjCController.m
+++ b/WebKitTools/DumpRenderTree/mac/ObjCController.m
@@ -28,11 +28,28 @@
#import "ObjCController.h"
+#import <JavaScriptCore/JavaScriptCore.h>
#import <WebKit/DOMAbstractView.h>
#import <WebKit/WebScriptObject.h>
#import <WebKit/WebView.h>
+#import <pthread.h>
#import <wtf/Assertions.h>
+static void* runJavaScriptThread(void* arg)
+{
+ JSGlobalContextRef ctx = JSGlobalContextCreate(0);
+ JSStringRef scriptRef = JSStringCreateWithUTF8CString("'Hello World!'");
+
+ JSValueRef exception = 0;
+ JSEvaluateScript(ctx, scriptRef, 0, 0, 1, &exception);
+ ASSERT(!exception);
+
+ JSGlobalContextRelease(ctx);
+ JSStringRelease(scriptRef);
+
+ return 0;
+}
+
@implementation ObjCController
+ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
@@ -46,6 +63,8 @@
|| aSelector == @selector(testWrapperRoundTripping:)
|| aSelector == @selector(accessStoredWebScriptObject)
|| aSelector == @selector(storeWebScriptObject:)
+ || aSelector == @selector(testValueForKey)
+ || aSelector == @selector(testArray)
)
return NO;
return YES;
@@ -67,6 +86,10 @@
return @"testWrapperRoundTripping";
if (aSelector == @selector(storeWebScriptObject:))
return @"storeWebScriptObject";
+ if (aSelector == @selector(testValueForKey))
+ return @"testValueForKey";
+ if (aSelector == @selector(testArray))
+ return @"testArray";
return nil;
}
@@ -115,6 +138,20 @@
return num;
}
+- (void)testValueForKey
+{
+ ASSERT(storedWebScriptObject);
+
+ @try {
+ [storedWebScriptObject valueForKey:@"ThisKeyDoesNotExist"];
+ } @catch (NSException *e) {
+ }
+
+ pthread_t pthread;
+ pthread_create(&pthread, 0, &runJavaScriptThread, 0);
+ pthread_join(pthread, 0);
+}
+
- (BOOL)testWrapperRoundTripping:(WebScriptObject *)webScriptObject
{
JSObjectRef jsObject = [webScriptObject JSObject];
@@ -182,6 +219,11 @@
storedWebScriptObject = [webScriptObject retain];
}
+- (NSArray *)testArray
+{
+ return [NSArray array];
+}
+
- (void)dealloc
{
[storedWebScriptObject release];
diff --git a/WebKitTools/DumpRenderTree/mac/ObjCPlugin.m b/WebKitTools/DumpRenderTree/mac/ObjCPlugin.m
index 18b174c..3ec3e74 100644
--- a/WebKitTools/DumpRenderTree/mac/ObjCPlugin.m
+++ b/WebKitTools/DumpRenderTree/mac/ObjCPlugin.m
@@ -110,7 +110,7 @@ static BOOL _allowsScriptsFullAccess = NO;
- (void)log:(NSString *)message
{
- NSLog(message);
+ NSLog(@"%@", message);
}
- (id)retainObject:(id)obj
diff --git a/WebKitTools/DumpRenderTree/mac/PixelDumpSupportMac.mm b/WebKitTools/DumpRenderTree/mac/PixelDumpSupportMac.mm
index 5a19164..f4191e5 100644
--- a/WebKitTools/DumpRenderTree/mac/PixelDumpSupportMac.mm
+++ b/WebKitTools/DumpRenderTree/mac/PixelDumpSupportMac.mm
@@ -34,129 +34,208 @@
#include "LayoutTestController.h"
#include <CoreGraphics/CGBitmapContext.h>
+#ifndef BUILDING_ON_LEOPARD
+#include <OpenGL/OpenGL.h>
+#include <OpenGL/CGLMacro.h>
+#endif
#include <wtf/Assertions.h>
-#include <wtf/RetainPtr.h>
+#include <wtf/RefPtr.h>
#import <WebKit/WebDocumentPrivate.h>
#import <WebKit/WebKit.h>
-static unsigned char* screenCaptureBuffer;
+// To ensure pixel tests consistency, we need to always render in the same colorspace.
+// Unfortunately, because of AppKit / WebKit constraints, we can't render directly in the colorspace of our choice.
+// This implies we have to temporarily change the profile of the main display to the colorspace we want to render into.
+// We also need to make sure the CGBitmapContext we return is in that same colorspace.
-static CMProfileRef currentColorProfile = 0;
-static CGColorSpaceRef sharedColorSpace;
+#define PROFILE_PATH "/System/Library/ColorSync/Profiles/Generic RGB Profile.icc" // FIXME: This cannot be more than CS_MAX_PATH (256 characters)
-void restoreColorSpace(int ignored)
+static CMProfileLocation sInitialProfileLocation; // The locType field is initialized to 0 which is the same as cmNoProfileBase
+
+void restoreMainDisplayColorProfile(int ignored)
{
// This is used as a signal handler, and thus the calls into ColorSync are unsafe
// But we might as well try to restore the user's color profile, we're going down anyway...
- if (currentColorProfile) {
- // This call is deprecated in Leopard, but there appears to be no replacement.
- int error = CMSetDefaultProfileByUse(cmDisplayUse, currentColorProfile);
+ if (sInitialProfileLocation.locType != cmNoProfileBase) {
+ const CMDeviceScope scope = { kCFPreferencesCurrentUser, kCFPreferencesCurrentHost };
+ int error = CMSetDeviceProfile(cmDisplayDeviceClass, (CMDeviceID)kCGDirectMainDisplay, &scope, cmDefaultProfileID, &sInitialProfileLocation);
if (error)
- fprintf(stderr, "Failed to retore previous color profile! You may need to open System Preferences : Displays : Color and manually restore your color settings. (Error: %i)", error);
- currentColorProfile = 0;
+ fprintf(stderr, "Failed to restore initial color profile for main display! Open System Preferences > Displays > Color and manually re-select the profile. (Error: %i)", error);
+ sInitialProfileLocation.locType = cmNoProfileBase;
}
}
-static void setDefaultColorProfileToRGB()
+void setupMainDisplayColorProfile()
{
- CMProfileRef genericProfile = (CMProfileRef)[[NSColorSpace genericRGBColorSpace] colorSyncProfile];
- CMProfileRef previousProfile;
- int error = CMGetDefaultProfileByUse(cmDisplayUse, &previousProfile);
+ const CMDeviceScope scope = { kCFPreferencesCurrentUser, kCFPreferencesCurrentHost };
+ int error;
+
+ CMProfileRef profile = 0;
+ error = CMGetProfileByAVID((CMDisplayIDType)kCGDirectMainDisplay, &profile);
+ if (!error) {
+ UInt32 size = sizeof(CMProfileLocation);
+ error = NCMGetProfileLocation(profile, &sInitialProfileLocation, &size);
+ CMCloseProfile(profile);
+ }
if (error) {
- fprintf(stderr, "Failed to get current color profile. I will not be able to restore your current profile, thus I'm not changing it. Many pixel tests may fail as a result. (Error: %i)\n", error);
+ fprintf(stderr, "Failed to retrieve current color profile for main display, thus it won't be changed. Many pixel tests may fail as a result. (Error: %i)", error);
+ sInitialProfileLocation.locType = cmNoProfileBase;
return;
}
- if (previousProfile == genericProfile)
- return;
- CFStringRef previousProfileName;
- CFStringRef genericProfileName;
- char previousProfileNameString[1024];
- char genericProfileNameString[1024];
- CMCopyProfileDescriptionString(previousProfile, &previousProfileName);
- CMCopyProfileDescriptionString(genericProfile, &genericProfileName);
- CFStringGetCString(previousProfileName, previousProfileNameString, sizeof(previousProfileNameString), kCFStringEncodingUTF8);
- CFStringGetCString(genericProfileName, genericProfileNameString, sizeof(previousProfileNameString), kCFStringEncodingUTF8);
- CFRelease(previousProfileName);
- CFRelease(genericProfileName);
-
- fprintf(stderr, "\n\nWARNING: Temporarily changing your system color profile from \"%s\" to \"%s\".\n", previousProfileNameString, genericProfileNameString);
- fprintf(stderr, "This allows the WebKit pixel-based regression tests to have consistent color values across all machines.\n");
- fprintf(stderr, "The colors on your screen will change for the duration of the testing.\n\n");
- if ((error = CMSetDefaultProfileByUse(cmDisplayUse, genericProfile))) {
- fprintf(stderr, "Failed to set color profile to \"%s\"! Many pixel tests will fail as a result. (Error: %i)",
- genericProfileNameString, error);
- } else {
- currentColorProfile = previousProfile;
- signal(SIGINT, restoreColorSpace);
- signal(SIGHUP, restoreColorSpace);
- signal(SIGTERM, restoreColorSpace);
+ CMProfileLocation location;
+ location.locType = cmPathBasedProfile;
+ strcpy(location.u.pathLoc.path, PROFILE_PATH);
+ error = CMSetDeviceProfile(cmDisplayDeviceClass, (CMDeviceID)kCGDirectMainDisplay, &scope, cmDefaultProfileID, &location);
+ if (error) {
+ fprintf(stderr, "Failed to set color profile for main display! Many pixel tests may fail as a result. (Error: %i)", error);
+ sInitialProfileLocation.locType = cmNoProfileBase;
+ return;
}
+
+ // Other signals are handled in installSignalHandlers() which also calls restoreMainDisplayColorProfile()
+ signal(SIGINT, restoreMainDisplayColorProfile);
+ signal(SIGHUP, restoreMainDisplayColorProfile);
+ signal(SIGTERM, restoreMainDisplayColorProfile);
+
+ fprintf(stderr, "\n\nWARNING: Temporarily changing the main display color profile to \"%s\": the colors on your screen will change for the duration of the testing.\n", PROFILE_PATH);
+ fprintf(stderr, "This allows the WebKit pixel-based regression tests to have consistent color values across all machines.\n");
}
-void initializeColorSpaceAndScreeBufferForPixelTests()
-{
- setDefaultColorProfileToRGB();
- screenCaptureBuffer = (unsigned char *)malloc(maxViewHeight * maxViewWidth * 4);
- sharedColorSpace = CGColorSpaceCreateDeviceRGB();
-}
-
-// Declared in PixelDumpSupportCG.h
-
-RetainPtr<CGContextRef> getBitmapContextFromWebView()
-{
- NSSize webViewSize = [[mainFrame webView] frame].size;
- return RetainPtr<CGContextRef>(AdoptCF, CGBitmapContextCreate(screenCaptureBuffer, static_cast<size_t>(webViewSize.width), static_cast<size_t>(webViewSize.height), 8, static_cast<size_t>(webViewSize.width) * 4, sharedColorSpace, kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedLast));
-}
-
-void paintWebView(CGContextRef context)
+PassRefPtr<BitmapContext> createBitmapContextFromWebView(bool onscreen, bool incrementalRepaint, bool sweepHorizontally, bool drawSelectionRect)
{
- RetainPtr<NSGraphicsContext> savedContext = [NSGraphicsContext currentContext];
-
- NSGraphicsContext* nsContext = [NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:NO];
- [NSGraphicsContext setCurrentContext:nsContext];
-
WebView* view = [mainFrame webView];
- [view displayIfNeeded];
- [view lockFocus];
- NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:[view frame]];
- [view unlockFocus];
- [imageRep draw];
- [imageRep release];
-
- [NSGraphicsContext setCurrentContext:savedContext.get()];
-}
-
-void repaintWebView(CGContextRef context, bool horizontal)
-{
- RetainPtr<NSGraphicsContext> savedContext = [NSGraphicsContext currentContext];
-
- NSGraphicsContext* nsContext = [NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:NO];
- [NSGraphicsContext setCurrentContext:nsContext];
-
- WebView *view = [mainFrame webView];
NSSize webViewSize = [view frame].size;
+ size_t pixelsWide = static_cast<size_t>(webViewSize.width);
+ size_t pixelsHigh = static_cast<size_t>(webViewSize.height);
+ size_t rowBytes = (4 * pixelsWide + 63) & ~63; // Use a multiple of 64 bytes to improve CG performance
- if (horizontal) {
- for (NSRect column = NSMakeRect(0, 0, 1, webViewSize.height); column.origin.x < webViewSize.width; column.origin.x++)
- [view displayRectIgnoringOpacity:column inContext:nsContext];
- } else {
- for (NSRect line = NSMakeRect(0, 0, webViewSize.width, 1); line.origin.y < webViewSize.height; line.origin.y++)
- [view displayRectIgnoringOpacity:line inContext:nsContext];
+ void *buffer = calloc(pixelsHigh, rowBytes);
+ if (!buffer)
+ return 0;
+
+ static CGColorSpaceRef colorSpace = 0;
+ if (!colorSpace) {
+ CMProfileLocation location;
+ location.locType = cmPathBasedProfile;
+ strcpy(location.u.pathLoc.path, PROFILE_PATH);
+ CMProfileRef profile;
+ if (CMOpenProfile(&profile, &location) == noErr) {
+ colorSpace = CGColorSpaceCreateWithPlatformColorSpace(profile);
+ CMCloseProfile(profile);
+ }
+ }
+
+ CGContextRef context = CGBitmapContextCreate(buffer, pixelsWide, pixelsHigh, 8, rowBytes, colorSpace, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host); // Use ARGB8 on PPC or BGRA8 on X86 to improve CG performance
+ if (!context) {
+ free(buffer);
+ return 0;
}
- [NSGraphicsContext setCurrentContext:savedContext.get()];
-}
+ // The BitmapContext keeps the CGContextRef and the pixel buffer alive
+ RefPtr<BitmapContext> bitmapContext = BitmapContext::createByAdoptingBitmapAndContext(buffer, context);
+
+ NSGraphicsContext *nsContext = [NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:NO];
+ ASSERT(nsContext);
+
+ if (incrementalRepaint) {
+ if (sweepHorizontally) {
+ for (NSRect column = NSMakeRect(0, 0, 1, webViewSize.height); column.origin.x < webViewSize.width; column.origin.x++)
+ [view displayRectIgnoringOpacity:column inContext:nsContext];
+ } else {
+ for (NSRect line = NSMakeRect(0, 0, webViewSize.width, 1); line.origin.y < webViewSize.height; line.origin.y++)
+ [view displayRectIgnoringOpacity:line inContext:nsContext];
+ }
+ } else {
+ if (onscreen) {
+#ifdef BUILDING_ON_LEOPARD
+ // Ask the window server to provide us a composited version of the *real* window content including surfaces (i.e. OpenGL content)
+ // Note that the returned image might differ very slightly from the window backing because of dithering artifacts in the window server compositor
+
+ CGImageRef image = CGWindowListCreateImage(CGRectNull, kCGWindowListOptionIncludingWindow, [[view window] windowNumber], kCGWindowImageBoundsIgnoreFraming | kCGWindowImageShouldBeOpaque);
+ CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)), image);
+ CGImageRelease(image);
+#else
+ // On 10.4 and earlier, we have to move the window temporarily "onscreen" and read directly from the display framebuffer using OpenGL
+ // In this code path, we need to ensure the window is above any other window or captured result will be corrupted
+
+ NSWindow *window = [view window];
+ int oldLevel = [window level];
+ NSRect oldFrame = [window frame];
+
+ NSRect newFrame = [[[NSScreen screens] objectAtIndex:0] frame];
+ newFrame = NSMakeRect(newFrame.origin.x + (newFrame.size.width - oldFrame.size.width) / 2, newFrame.origin.y + (newFrame.size.height - oldFrame.size.height) / 2, oldFrame.size.width, oldFrame.size.height);
+ [window setLevel:NSScreenSaverWindowLevel];
+ [window setFrame:newFrame display:NO animate:NO];
+
+ CGRect rect = CGRectMake(newFrame.origin.x, newFrame.origin.y, webViewSize.width, webViewSize.height);
+ CGDirectDisplayID displayID;
+ CGDisplayCount count;
+ if (CGGetDisplaysWithRect(rect, 1, &displayID, &count) == kCGErrorSuccess) {
+ CGRect bounds = CGDisplayBounds(displayID);
+ rect.origin.x -= bounds.origin.x;
+ rect.origin.y -= bounds.origin.y;
+
+ CGLPixelFormatAttribute attributes[] = {kCGLPFAAccelerated, kCGLPFANoRecovery, kCGLPFAFullScreen, kCGLPFADisplayMask, (CGLPixelFormatAttribute)CGDisplayIDToOpenGLDisplayMask(displayID), (CGLPixelFormatAttribute)0};
+ CGLPixelFormatObj pixelFormat;
+ GLint num;
+ if (CGLChoosePixelFormat(attributes, &pixelFormat, &num) == kCGLNoError) {
+ CGLContextObj cgl_ctx;
+ if (CGLCreateContext(pixelFormat, 0, &cgl_ctx) == kCGLNoError) {
+ if (CGLSetFullScreen(cgl_ctx) == kCGLNoError) {
+ void *flipBuffer = calloc(pixelsHigh, rowBytes);
+ if (flipBuffer) {
+ glPixelStorei(GL_PACK_ROW_LENGTH, rowBytes / 4);
+ glPixelStorei(GL_PACK_ALIGNMENT, 4);
+#if __BIG_ENDIAN__
+ glReadPixels(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, flipBuffer);
+#else
+ glReadPixels(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, flipBuffer);
+#endif
+ if (!glGetError()) {
+ for(size_t i = 0; i < pixelsHigh; ++i)
+ bcopy((char*)flipBuffer + rowBytes * i, (char*)buffer + rowBytes * (pixelsHigh - i - 1), pixelsWide * 4);
+ }
+
+ free(flipBuffer);
+ }
+ }
+ CGLDestroyContext(cgl_ctx);
+ }
+ CGLDestroyPixelFormat(pixelFormat);
+ }
+ }
+
+ [window setFrame:oldFrame display:NO animate:NO];
+ [window setLevel:oldLevel];
+#endif
+ } else {
+ // Grab directly the contents of the window backing buffer (this ignores any surfaces on the window)
+ // FIXME: This path is suboptimal: data is read from window backing store, converted to RGB8 then drawn again into an RGBA8 bitmap
+
+ [view displayIfNeeded];
+ [view lockFocus];
+ NSBitmapImageRep *imageRep = [[[NSBitmapImageRep alloc] initWithFocusedViewRect:[view frame]] autorelease];
+ [view unlockFocus];
+
+ RetainPtr<NSGraphicsContext> savedContext = [NSGraphicsContext currentContext];
+ [NSGraphicsContext setCurrentContext:nsContext];
+ [imageRep draw];
+ [NSGraphicsContext setCurrentContext:savedContext.get()];
+ }
+ }
-CGRect getSelectionRect()
-{
- NSView *documentView = [[mainFrame frameView] documentView];
- if ([documentView conformsToProtocol:@protocol(WebDocumentSelection)]) {
+ if (drawSelectionRect) {
+ NSView *documentView = [[mainFrame frameView] documentView];
+ ASSERT([documentView conformsToProtocol:@protocol(WebDocumentSelection)]);
NSRect rect = [documentView convertRect:[(id <WebDocumentSelection>)documentView selectionRect] fromView:nil];
- return CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
+ CGContextSaveGState(context);
+ CGContextSetLineWidth(context, 1.0);
+ CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0);
+ CGContextStrokeRect(context, CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height));
+ CGContextRestoreGState(context);
}
-
- ASSERT_NOT_REACHED();
- return CGRectZero;
+
+ return bitmapContext.release();
}
diff --git a/WebKitTools/DumpRenderTree/mac/ResourceLoadDelegate.mm b/WebKitTools/DumpRenderTree/mac/ResourceLoadDelegate.mm
index cc0eb4a..5d2e2b4 100644
--- a/WebKitTools/DumpRenderTree/mac/ResourceLoadDelegate.mm
+++ b/WebKitTools/DumpRenderTree/mac/ResourceLoadDelegate.mm
@@ -31,6 +31,7 @@
#import "DumpRenderTree.h"
#import "LayoutTestController.h"
#import <WebKit/WebKit.h>
+#import <WebKit/WebTypesInternal.h>
#import <wtf/Assertions.h>
@interface NSURL (DRTExtras)
@@ -54,12 +55,12 @@
{
NSString *str = [NSString stringWithFormat:@"<NSError domain %@, code %d", [self domain], [self code]];
NSURL *failingURL;
-
+
if ((failingURL = [[self userInfo] objectForKey:@"NSErrorFailingURLKey"]))
str = [str stringByAppendingFormat:@", failing URL \"%@\"", [failingURL _drt_descriptionSuitableForTestResult]];
-
+
str = [str stringByAppendingFormat:@">"];
-
+
return str;
}
@@ -75,9 +76,9 @@
WebDataSource *dataSource = [mainFrame dataSource];
if (!dataSource)
dataSource = [mainFrame provisionalDataSource];
-
+
NSString *basePath = [[[[dataSource request] URL] path] stringByDeletingLastPathComponent];
-
+
return [[self path] substringFromIndex:[basePath length] + 1];
}
@@ -106,24 +107,35 @@
- webView: (WebView *)wv identifierForInitialRequest: (NSURLRequest *)request fromDataSource: (WebDataSource *)dataSource
{
ASSERT([[dataSource webFrame] dataSource] || [[dataSource webFrame] provisionalDataSource]);
-
- if (!done && layoutTestController->dumpResourceLoadCallbacks())
+
+ if (!done && gLayoutTestController->dumpResourceLoadCallbacks())
return [[request URL] _drt_descriptionSuitableForTestResult];
-
+
return @"<unknown>";
}
-(NSURLRequest *)webView: (WebView *)wv resource:identifier willSendRequest: (NSURLRequest *)newRequest redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)dataSource
{
- if (!done && layoutTestController->dumpResourceLoadCallbacks()) {
+ if (!done && gLayoutTestController->dumpResourceLoadCallbacks()) {
NSString *string = [NSString stringWithFormat:@"%@ - willSendRequest %@ redirectResponse %@", identifier, [newRequest _drt_descriptionSuitableForTestResult],
[redirectResponse _drt_descriptionSuitableForTestResult]];
- printf ("%s\n", [string UTF8String]);
- }
-
- if (disallowedURLs && CFSetContainsValue(disallowedURLs, [newRequest URL]))
+ printf("%s\n", [string UTF8String]);
+ }
+
+ NSURL *url = [newRequest URL];
+ NSString *host = [url host];
+ if (host
+ && (NSOrderedSame == [[url scheme] caseInsensitiveCompare:@"http"] || NSOrderedSame == [[url scheme] caseInsensitiveCompare:@"https"])
+ && NSOrderedSame != [host compare:@"127.0.0.1"]
+ && NSOrderedSame != [host compare:@"255.255.255.255"] // used in some tests that expect to get back an error
+ && NSOrderedSame != [host caseInsensitiveCompare:@"localhost"]) {
+ printf("Blocked access to external URL %s\n", [[url absoluteString] cStringUsingEncoding:NSUTF8StringEncoding]);
return nil;
-
+ }
+
+ if (disallowedURLs && CFSetContainsValue(disallowedURLs, url))
+ return nil;
+
return newRequest;
}
@@ -137,41 +149,44 @@
-(void)webView: (WebView *)wv resource:identifier didReceiveResponse: (NSURLResponse *)response fromDataSource:(WebDataSource *)dataSource
{
- if (!done && layoutTestController->dumpResourceLoadCallbacks()) {
+ if (!done && gLayoutTestController->dumpResourceLoadCallbacks()) {
NSString *string = [NSString stringWithFormat:@"%@ - didReceiveResponse %@", identifier, [response _drt_descriptionSuitableForTestResult]];
- printf ("%s\n", [string UTF8String]);
- }
+ printf("%s\n", [string UTF8String]);
+ }
}
--(void)webView: (WebView *)wv resource:identifier didReceiveContentLength: (unsigned)length fromDataSource:(WebDataSource *)dataSource
+-(void)webView: (WebView *)wv resource:identifier didReceiveContentLength: (NSInteger)length fromDataSource:(WebDataSource *)dataSource
{
}
-(void)webView: (WebView *)wv resource:identifier didFinishLoadingFromDataSource:(WebDataSource *)dataSource
{
- if (!done && layoutTestController->dumpResourceLoadCallbacks()) {
+ if (!done && gLayoutTestController->dumpResourceLoadCallbacks()) {
NSString *string = [NSString stringWithFormat:@"%@ - didFinishLoading", identifier];
- printf ("%s\n", [string UTF8String]);
+ printf("%s\n", [string UTF8String]);
}
}
-(void)webView: (WebView *)wv resource:identifier didFailLoadingWithError:(NSError *)error fromDataSource:(WebDataSource *)dataSource
{
- if (!done && layoutTestController->dumpResourceLoadCallbacks()) {
+ if (!done && gLayoutTestController->dumpResourceLoadCallbacks()) {
NSString *string = [NSString stringWithFormat:@"%@ - didFailLoadingWithError: %@", identifier, [error _drt_descriptionSuitableForTestResult]];
- printf ("%s\n", [string UTF8String]);
+ printf("%s\n", [string UTF8String]);
}
}
- (void)webView: (WebView *)wv plugInFailedWithError:(NSError *)error dataSource:(WebDataSource *)dataSource
{
+ // The call to -display here simulates the "Plug-in not found" sheet that Safari shows.
+ // It is used for platform/mac/plugins/update-widget-from-style-recalc.html
+ [wv display];
}
-(NSCachedURLResponse *) webView: (WebView *)wv resource:(id)identifier willCacheResponse:(NSCachedURLResponse *)response fromDataSource:(WebDataSource *)dataSource
{
- if (!done && layoutTestController->dumpResourceLoadCallbacks()) {
+ if (!done && gLayoutTestController->dumpResourceLoadCallbacks()) {
NSString *string = [NSString stringWithFormat:@"%@ - willCacheResponse: called", identifier];
- printf ("%s\n", [string UTF8String]);
+ printf("%s\n", [string UTF8String]);
}
return response;
}
diff --git a/WebKitTools/DumpRenderTree/mac/UIDelegate.mm b/WebKitTools/DumpRenderTree/mac/UIDelegate.mm
index 29f3ddd..0c5a93c 100644
--- a/WebKitTools/DumpRenderTree/mac/UIDelegate.mm
+++ b/WebKitTools/DumpRenderTree/mac/UIDelegate.mm
@@ -84,10 +84,18 @@ DumpRenderTreeDraggingInfo *draggingInfo = nil;
return defaultText;
}
+- (BOOL)webView:(WebView *)c runBeforeUnloadConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame
+{
+ if (!done)
+ printf("CONFIRM NAVIGATION: %s\n", [message UTF8String]);
+ return YES;
+}
+
+
- (void)webView:(WebView *)sender dragImage:(NSImage *)anImage at:(NSPoint)viewLocation offset:(NSSize)initialOffset event:(NSEvent *)event pasteboard:(NSPasteboard *)pboard source:(id)sourceObj slideBack:(BOOL)slideFlag forView:(NSView *)view
{
assert(!draggingInfo);
- if (layoutTestController->addFileToPasteboardOnDrag()) {
+ if (gLayoutTestController->addFileToPasteboardOnDrag()) {
[pboard declareTypes:[NSArray arrayWithObject:NSFilenamesPboardType] owner:nil];
[pboard setPropertyList:[NSArray arrayWithObject:@"DRTFakeFile"] forType:NSFilenamesPboardType];
}
@@ -97,19 +105,21 @@ DumpRenderTreeDraggingInfo *draggingInfo = nil;
- (void)webViewFocus:(WebView *)webView
{
- layoutTestController->setWindowIsKey(true);
- NSView *documentView = [[mainFrame frameView] documentView];
- if ([documentView isKindOfClass:[WebHTMLView class]])
- [(WebHTMLView *)documentView _updateFocusedAndActiveState];
+ gLayoutTestController->setWindowIsKey(true);
+}
+
+- (void)webViewUnfocus:(WebView *)webView
+{
+ gLayoutTestController->setWindowIsKey(false);
}
- (WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request
{
- if (!layoutTestController->canOpenWindows())
+ if (!gLayoutTestController->canOpenWindows())
return nil;
// Make sure that waitUntilDone has been called.
- ASSERT(layoutTestController->waitToDump());
+ ASSERT(gLayoutTestController->waitToDump());
WebView *webView = createWebViewAndOffscreenWindow();
@@ -120,7 +130,7 @@ DumpRenderTreeDraggingInfo *draggingInfo = nil;
{
NSWindow* window = [sender window];
- if (layoutTestController->callCloseOnWebViews())
+ if (gLayoutTestController->callCloseOnWebViews())
[sender close];
[window close];
@@ -128,10 +138,19 @@ DumpRenderTreeDraggingInfo *draggingInfo = nil;
- (void)webView:(WebView *)sender frame:(WebFrame *)frame exceededDatabaseQuotaForSecurityOrigin:(WebSecurityOrigin *)origin database:(NSString *)databaseIdentifier
{
- static const unsigned long long defaultQuota = 5 * 1024 * 1024;
+ if (!done && gLayoutTestController->dumpDatabaseCallbacks())
+ printf("UI DELEGATE DATABASE CALLBACK: exceededDatabaseQuotaForSecurityOrigin:{%s, %s, %i} database:%s\n", [[origin protocol] UTF8String], [[origin host] UTF8String],
+ [origin port], [databaseIdentifier UTF8String]);
+
+ static const unsigned long long defaultQuota = 5 * 1024 * 1024;
[origin setQuota:defaultQuota];
}
+- (void)webView:(WebView *)sender setStatusText:(NSString *)text
+{
+ if (gLayoutTestController->dumpStatusCallbacks())
+ printf("UI DELEGATE STATUS CALLBACK: setStatusText:%s\n", [text UTF8String]);
+}
- (void)dealloc
{