📄 eventsendingcontroller.mm
字号:
[webView performDragOperation:draggingInfo]; else [webView draggingExited:draggingInfo]; [[draggingInfo draggingSource] draggedImage:[draggingInfo draggedImage] endedAt:lastMousePosition operation:dragOperation]; [draggingInfo release]; draggingInfo = nil; }}- (void)mouseMoveToX:(int)x Y:(int)y{ if (dragMode && leftMouseButtonDown && !replayingSavedEvents) { NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[EventSendingController instanceMethodSignatureForSelector:@selector(mouseMoveToX:Y:)]]; [invocation setTarget:self]; [invocation setSelector:@selector(mouseMoveToX:Y:)]; [invocation setArgument:&x atIndex:2]; [invocation setArgument:&y atIndex:3]; [EventSendingController saveEvent:invocation]; return; } NSView *view = [mainFrame webView]; lastMousePosition = [view convertPoint:NSMakePoint(x, [view frame].size.height - y) toView:nil]; NSEvent *event = [NSEvent mouseEventWithType:(leftMouseButtonDown ? NSLeftMouseDragged : NSMouseMoved) location:lastMousePosition modifierFlags:0 timestamp:[self currentEventTime] windowNumber:[[view window] windowNumber] context:[NSGraphicsContext currentContext] eventNumber:++eventNumber clickCount:(leftMouseButtonDown ? clickCount : 0) pressure:0.0]; NSView *subView = [[mainFrame webView] hitTest:[event locationInWindow]]; if (subView) { if (leftMouseButtonDown) { [subView mouseDragged:event]; if (draggingInfo) { [[draggingInfo draggingSource] draggedImage:[draggingInfo draggedImage] movedTo:lastMousePosition]; [[mainFrame webView] draggingUpdated:draggingInfo]; } } else [subView mouseMoved:event]; }}- (void)contextClick{ [[[mainFrame frameView] documentView] layout]; [self updateClickCountForButton:RightMouseButton]; NSEvent *event = [NSEvent mouseEventWithType:NSRightMouseDown location:lastMousePosition modifierFlags:0 timestamp:[self currentEventTime] windowNumber:[[[mainFrame webView] window] windowNumber] context:[NSGraphicsContext currentContext] eventNumber:++eventNumber clickCount:clickCount pressure:0.0]; NSView *subView = [[mainFrame webView] hitTest:[event locationInWindow]]; if (subView) [subView menuForEvent:event];}- (void)scheduleAsynchronousClick{ [self performSelector:@selector(mouseDown:) withObject:nil afterDelay:0]; [self performSelector:@selector(mouseUp:) withObject:nil afterDelay:0];}+ (void)saveEvent:(NSInvocation *)event{ if (!savedMouseEvents) savedMouseEvents = [[NSMutableArray alloc] init]; [savedMouseEvents addObject:event];}+ (void)replaySavedEvents{ replayingSavedEvents = YES; while ([savedMouseEvents count]) { // if a drag is initiated, the remaining saved events will be dispatched from our dragging delegate NSInvocation *invocation = [[[savedMouseEvents objectAtIndex:0] retain] autorelease]; [savedMouseEvents removeObjectAtIndex:0]; [invocation invoke]; } replayingSavedEvents = NO;}+ (void)clearSavedEvents{ [savedMouseEvents release]; savedMouseEvents = nil;}- (void)keyDown:(NSString *)character withModifiers:(WebScriptObject *)modifiers{ NSString *eventCharacter = character; if ([character isEqualToString:@"leftArrow"]) { const unichar ch = NSLeftArrowFunctionKey; eventCharacter = [NSString stringWithCharacters:&ch length:1]; } else if ([character isEqualToString:@"rightArrow"]) { const unichar ch = NSRightArrowFunctionKey; eventCharacter = [NSString stringWithCharacters:&ch length:1]; } else if ([character isEqualToString:@"upArrow"]) { const unichar ch = NSUpArrowFunctionKey; eventCharacter = [NSString stringWithCharacters:&ch length:1]; } else if ([character isEqualToString:@"downArrow"]) { const unichar ch = NSDownArrowFunctionKey; eventCharacter = [NSString stringWithCharacters:&ch length:1]; } else if ([character isEqualToString:@"pageUp"]) { const unichar ch = NSPageUpFunctionKey; eventCharacter = [NSString stringWithCharacters:&ch length:1]; } else if ([character isEqualToString:@"pageDown"]) { const unichar ch = NSPageDownFunctionKey; eventCharacter = [NSString stringWithCharacters:&ch length:1]; } else if ([character isEqualToString:@"home"]) { const unichar ch = NSHomeFunctionKey; eventCharacter = [NSString stringWithCharacters:&ch length:1]; } else if ([character isEqualToString:@"end"]) { const unichar ch = NSEndFunctionKey; eventCharacter = [NSString stringWithCharacters:&ch length:1]; } else if ([character isEqualToString:@"delete"]) { const unichar ch = 0x7f; eventCharacter = [NSString stringWithCharacters:&ch length:1]; } NSString *charactersIgnoringModifiers = eventCharacter; int modifierFlags = 0; if ([character length] == 1 && [character characterAtIndex:0] >= 'A' && [character characterAtIndex:0] <= 'Z') { modifierFlags |= NSShiftKeyMask; charactersIgnoringModifiers = [character lowercaseString]; } if ([modifiers isKindOfClass:[WebScriptObject class]]) for (unsigned i = 0; [[modifiers webScriptValueAtIndex:i] isKindOfClass:[NSString class]]; i++) { NSString *modifier = (NSString *)[modifiers webScriptValueAtIndex:i]; if ([modifier isEqual:@"ctrlKey"]) modifierFlags |= NSControlKeyMask; else if ([modifier isEqual:@"shiftKey"]) modifierFlags |= NSShiftKeyMask; else if ([modifier isEqual:@"altKey"]) modifierFlags |= NSAlternateKeyMask; else if ([modifier isEqual:@"metaKey"]) modifierFlags |= NSCommandKeyMask; } [[[mainFrame frameView] documentView] layout]; NSEvent *event = [NSEvent keyEventWithType:NSKeyDown location:NSMakePoint(5, 5) modifierFlags:modifierFlags timestamp:[self currentEventTime] windowNumber:[[[mainFrame webView] window] windowNumber] context:[NSGraphicsContext currentContext] characters:eventCharacter charactersIgnoringModifiers:charactersIgnoringModifiers isARepeat:NO keyCode:0]; [[[[mainFrame webView] window] firstResponder] keyDown:event]; event = [NSEvent keyEventWithType:NSKeyUp location:NSMakePoint(5, 5) modifierFlags:modifierFlags timestamp:[self currentEventTime] windowNumber:[[[mainFrame webView] window] windowNumber] context:[NSGraphicsContext currentContext] characters:eventCharacter charactersIgnoringModifiers:charactersIgnoringModifiers isARepeat:NO keyCode:0]; [[[[mainFrame webView] window] firstResponder] keyUp:event];}- (void)enableDOMUIEventLogging:(WebScriptObject *)node{ NSEnumerator *eventEnumerator = [webkitDomEventNames objectEnumerator]; id eventName; while ((eventName = [eventEnumerator nextObject])) { [(id<DOMEventTarget>)node addEventListener:eventName listener:self useCapture:NO]; }}- (void)handleEvent:(DOMEvent *)event{ DOMNode *target = [event target]; printf("event type: %s\n", [[event type] UTF8String]); printf(" target: <%s>\n", [[[target nodeName] lowercaseString] UTF8String]); if ([event isKindOfClass:[DOMEvent class]]) { printf(" eventPhase: %d\n", [event eventPhase]); printf(" bubbles: %d\n", [event bubbles] ? 1 : 0); printf(" cancelable: %d\n", [event cancelable] ? 1 : 0); } if ([event isKindOfClass:[DOMUIEvent class]]) { printf(" detail: %d\n", [(DOMUIEvent*)event detail]); DOMAbstractView *view = [(DOMUIEvent*)event view]; if (view) { printf(" view: OK"); if ([view document]) printf(" (document: OK)"); printf("\n"); } } if ([event isKindOfClass:[DOMKeyboardEvent class]]) { printf(" keyIdentifier: %s\n", [[(DOMKeyboardEvent*)event keyIdentifier] UTF8String]); printf(" keyLocation: %d\n", [(DOMKeyboardEvent*)event keyLocation]); printf(" modifier keys: c:%d s:%d a:%d m:%d\n", [(DOMKeyboardEvent*)event ctrlKey] ? 1 : 0, [(DOMKeyboardEvent*)event shiftKey] ? 1 : 0, [(DOMKeyboardEvent*)event altKey] ? 1 : 0, [(DOMKeyboardEvent*)event metaKey] ? 1 : 0); printf(" keyCode: %d\n", [(DOMKeyboardEvent*)event keyCode]); printf(" charCode: %d\n", [(DOMKeyboardEvent*)event charCode]); } if ([event isKindOfClass:[DOMMouseEvent class]]) { printf(" button: %d\n", [(DOMMouseEvent*)event button]); printf(" clientX: %d\n", [(DOMMouseEvent*)event clientX]); printf(" clientY: %d\n", [(DOMMouseEvent*)event clientY]); printf(" screenX: %d\n", [(DOMMouseEvent*)event screenX]); printf(" screenY: %d\n", [(DOMMouseEvent*)event screenY]); printf(" modifier keys: c:%d s:%d a:%d m:%d\n", [(DOMMouseEvent*)event ctrlKey] ? 1 : 0, [(DOMMouseEvent*)event shiftKey] ? 1 : 0, [(DOMMouseEvent*)event altKey] ? 1 : 0, [(DOMMouseEvent*)event metaKey] ? 1 : 0); id relatedTarget = [(DOMMouseEvent*)event relatedTarget]; if (relatedTarget) { printf(" relatedTarget: %s", [[[relatedTarget class] description] UTF8String]); if ([relatedTarget isKindOfClass:[DOMNode class]]) printf(" (nodeName: %s)", [[(DOMNode*)relatedTarget nodeName] UTF8String]); printf("\n"); } } if ([event isKindOfClass:[DOMMutationEvent class]]) { printf(" prevValue: %s\n", [[(DOMMutationEvent*)event prevValue] UTF8String]); printf(" newValue: %s\n", [[(DOMMutationEvent*)event newValue] UTF8String]); printf(" attrName: %s\n", [[(DOMMutationEvent*)event attrName] UTF8String]); printf(" attrChange: %d\n", [(DOMMutationEvent*)event attrChange]); DOMNode *relatedNode = [(DOMMutationEvent*)event relatedNode]; if (relatedNode) { printf(" relatedNode: %s (nodeName: %s)\n", [[[relatedNode class] description] UTF8String], [[relatedNode nodeName] UTF8String]); } } if ([event isKindOfClass:[DOMWheelEvent class]]) { printf(" clientX: %d\n", [(DOMWheelEvent*)event clientX]); printf(" clientY: %d\n", [(DOMWheelEvent*)event clientY]); printf(" screenX: %d\n", [(DOMWheelEvent*)event screenX]); printf(" screenY: %d\n", [(DOMWheelEvent*)event screenY]); printf(" modifier keys: c:%d s:%d a:%d m:%d\n", [(DOMWheelEvent*)event ctrlKey] ? 1 : 0, [(DOMWheelEvent*)event shiftKey] ? 1 : 0, [(DOMWheelEvent*)event altKey] ? 1 : 0, [(DOMWheelEvent*)event metaKey] ? 1 : 0); printf(" isHorizontal: %d\n", [(DOMWheelEvent*)event isHorizontal] ? 1 : 0); printf(" wheelDelta: %d\n", [(DOMWheelEvent*)event wheelDelta]); }}// FIXME: It's not good to have a test hard-wired into this controller like this.// Instead we need to get testing framework based on the Objective-C bindings// to work well enough that we can test that way instead.- (void)fireKeyboardEventsToElement:(WebScriptObject *)element { if (![element isKindOfClass:[DOMHTMLElement class]]) { return; } DOMHTMLElement *target = (DOMHTMLElement*)element; DOMDocument *document = [target ownerDocument]; // Keyboard Event 1 DOMEvent *domEvent = [document createEvent:@"KeyboardEvent"]; [(DOMKeyboardEvent*)domEvent initKeyboardEvent:@"keydown" canBubble:YES cancelable:YES view:[document defaultView] keyIdentifier:@"U+000041" keyLocation:0 ctrlKey:YES altKey:NO shiftKey:NO metaKey:NO]; [target dispatchEvent:domEvent]; // Keyboard Event 2 domEvent = [document createEvent:@"KeyboardEvent"]; [(DOMKeyboardEvent*)domEvent initKeyboardEvent:@"keypress" canBubble:YES cancelable:YES view:[document defaultView] keyIdentifier:@"U+000045" keyLocation:1 ctrlKey:NO altKey:YES shiftKey:NO metaKey:NO]; [target dispatchEvent:domEvent]; // Keyboard Event 3 domEvent = [document createEvent:@"KeyboardEvent"]; [(DOMKeyboardEvent*)domEvent initKeyboardEvent:@"keyup" canBubble:YES cancelable:YES view:[document defaultView] keyIdentifier:@"U+000056" keyLocation:0 ctrlKey:NO altKey:NO shiftKey:NO metaKey:NO]; [target dispatchEvent:domEvent]; }@end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -