📄 webhtmlview.mm
字号:
|| [event type] == NSFlagsChanged); } if (!captureHitsOnSubviews) return [super hitTest:point]; if ([[self superview] mouse:point inRect:[self frame]]) return self; return nil;}- (void)_clearLastHitViewIfSelf{ if (lastHitView == self) lastHitView = nil;}- (NSTrackingRectTag)addTrackingRect:(NSRect)rect owner:(id)owner userData:(void *)data assumeInside:(BOOL)assumeInside{ ASSERT(_private->trackingRectOwner == nil); _private->trackingRectOwner = owner; _private->trackingRectUserData = data; return TRACKING_RECT_TAG;}- (NSTrackingRectTag)_addTrackingRect:(NSRect)rect owner:(id)owner userData:(void *)data assumeInside:(BOOL)assumeInside useTrackingNum:(int)tag{ ASSERT(tag == 0 || tag == TRACKING_RECT_TAG); ASSERT(_private->trackingRectOwner == nil); _private->trackingRectOwner = owner; _private->trackingRectUserData = data; return TRACKING_RECT_TAG;}- (void)_addTrackingRects:(NSRect *)rects owner:(id)owner userDataList:(void **)userDataList assumeInsideList:(BOOL *)assumeInsideList trackingNums:(NSTrackingRectTag *)trackingNums count:(int)count{ ASSERT(count == 1); ASSERT(trackingNums[0] == 0 || trackingNums[0] == TRACKING_RECT_TAG); ASSERT(_private->trackingRectOwner == nil); _private->trackingRectOwner = owner; _private->trackingRectUserData = userDataList[0]; trackingNums[0] = TRACKING_RECT_TAG;}- (void)removeTrackingRect:(NSTrackingRectTag)tag{ if (tag == 0) return; if (_private && (tag == TRACKING_RECT_TAG)) { _private->trackingRectOwner = nil; return; } if (_private && (tag == _private->lastToolTipTag)) { [super removeTrackingRect:tag]; _private->lastToolTipTag = 0; return; } // If any other tracking rect is being removed, we don't know how it was created // and it's possible there's a leak involved (see 3500217) ASSERT_NOT_REACHED();}- (void)_removeTrackingRects:(NSTrackingRectTag *)tags count:(int)count{ int i; for (i = 0; i < count; ++i) { int tag = tags[i]; if (tag == 0) continue; ASSERT(tag == TRACKING_RECT_TAG); if (_private != nil) { _private->trackingRectOwner = nil; } }}- (void)_sendToolTipMouseExited{ // Nothing matters except window, trackingNumber, and userData. NSEvent *fakeEvent = [NSEvent enterExitEventWithType:NSMouseExited location:NSMakePoint(0, 0) modifierFlags:0 timestamp:0 windowNumber:[[self window] windowNumber] context:NULL eventNumber:0 trackingNumber:TRACKING_RECT_TAG userData:_private->trackingRectUserData]; [_private->trackingRectOwner mouseExited:fakeEvent];}- (void)_sendToolTipMouseEntered{ // Nothing matters except window, trackingNumber, and userData. NSEvent *fakeEvent = [NSEvent enterExitEventWithType:NSMouseEntered location:NSMakePoint(0, 0) modifierFlags:0 timestamp:0 windowNumber:[[self window] windowNumber] context:NULL eventNumber:0 trackingNumber:TRACKING_RECT_TAG userData:_private->trackingRectUserData]; [_private->trackingRectOwner mouseEntered:fakeEvent];}- (void)_setToolTip:(NSString *)string{ NSString *toolTip = [string length] == 0 ? nil : string; NSString *oldToolTip = _private->toolTip; if ((toolTip == nil || oldToolTip == nil) ? toolTip == oldToolTip : [toolTip isEqualToString:oldToolTip]) { return; } if (oldToolTip) { [self _sendToolTipMouseExited]; [oldToolTip release]; } _private->toolTip = [toolTip copy]; if (toolTip) { // See radar 3500217 for why we remove all tooltips rather than just the single one we created. [self removeAllToolTips]; NSRect wideOpenRect = NSMakeRect(-100000, -100000, 200000, 200000); _private->lastToolTipTag = [self addToolTipRect:wideOpenRect owner:self userData:NULL]; [self _sendToolTipMouseEntered]; }}- (NSString *)view:(NSView *)view stringForToolTip:(NSToolTipTag)tag point:(NSPoint)point userData:(void *)data{ return [[_private->toolTip copy] autorelease];}- (void)_updateMouseoverWithEvent:(NSEvent *)event{ if (_private->closed) return; NSView *contentView = [[event window] contentView]; NSPoint locationForHitTest = [[contentView superview] convertPoint:[event locationInWindow] fromView:nil]; forceWebHTMLViewHitTest = YES; NSView *hitView = [contentView hitTest:locationForHitTest]; forceWebHTMLViewHitTest = NO; WebHTMLView *view = nil; if ([hitView isKindOfClass:[WebHTMLView class]] && ![[(WebHTMLView *)hitView _webView] isHoverFeedbackSuspended]) view = (WebHTMLView *)hitView; if (view) [view retain]; if (lastHitView != view && lastHitView && [lastHitView _frame]) { // If we are moving out of a view (or frame), let's pretend the mouse moved // all the way out of that view. But we have to account for scrolling, because // khtml doesn't understand our clipping. NSRect visibleRect = [[[[lastHitView _frame] frameView] _scrollView] documentVisibleRect]; float yScroll = visibleRect.origin.y; float xScroll = visibleRect.origin.x; event = [NSEvent mouseEventWithType:NSMouseMoved location:NSMakePoint(-1 - xScroll, -1 - yScroll ) modifierFlags:[[NSApp currentEvent] modifierFlags] timestamp:[NSDate timeIntervalSinceReferenceDate] windowNumber:[[view window] windowNumber] context:[[NSApp currentEvent] context] eventNumber:0 clickCount:0 pressure:0]; if (Frame* lastHitCoreFrame = core([lastHitView _frame])) lastHitCoreFrame->eventHandler()->mouseMoved(event); } lastHitView = view; if (view) { if (Frame* coreFrame = core([view _frame])) coreFrame->eventHandler()->mouseMoved(event); [view release]; }}// keep in sync with WebPasteboardHelper::insertablePasteboardTypes+ (NSArray *)_insertablePasteboardTypes{ static NSArray *types = nil; if (!types) { types = [[NSArray alloc] initWithObjects:WebArchivePboardType, NSHTMLPboardType, NSFilenamesPboardType, NSTIFFPboardType,#if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD) NSPICTPboardType,#endif NSURLPboardType, NSRTFDPboardType, NSRTFPboardType, NSStringPboardType, NSColorPboardType, kUTTypePNG, nil]; CFRetain(types); } return types;}+ (NSArray *)_selectionPasteboardTypes{ // FIXME: We should put data for NSHTMLPboardType on the pasteboard but Microsoft Excel doesn't like our format of HTML (3640423). return [NSArray arrayWithObjects:WebArchivePboardType, NSRTFDPboardType, NSRTFPboardType, NSStringPboardType, nil];}- (NSImage *)_dragImageForURL:(NSString*)urlString withLabel:(NSString*)label{ BOOL drawURLString = YES; BOOL clipURLString = NO, clipLabelString = NO; if (!label) { drawURLString = NO; label = urlString; } NSFont *labelFont = [[NSFontManager sharedFontManager] convertFont:[NSFont systemFontOfSize:DRAG_LINK_LABEL_FONT_SIZE] toHaveTrait:NSBoldFontMask]; NSFont *urlFont = [NSFont systemFontOfSize: DRAG_LINK_URL_FONT_SIZE]; NSSize labelSize; labelSize.width = [label _web_widthWithFont: labelFont]; labelSize.height = [labelFont ascender] - [labelFont descender]; if (labelSize.width > MAX_DRAG_LABEL_WIDTH){ labelSize.width = MAX_DRAG_LABEL_WIDTH; clipLabelString = YES; } NSSize imageSize, urlStringSize; imageSize.width = labelSize.width + DRAG_LABEL_BORDER_X * 2.0f; imageSize.height = labelSize.height + DRAG_LABEL_BORDER_Y * 2.0f; if (drawURLString) { urlStringSize.width = [urlString _web_widthWithFont: urlFont]; urlStringSize.height = [urlFont ascender] - [urlFont descender]; imageSize.height += urlStringSize.height; if (urlStringSize.width > MAX_DRAG_LABEL_WIDTH) { imageSize.width = MAX(MAX_DRAG_LABEL_WIDTH + DRAG_LABEL_BORDER_X * 2.0f, MIN_DRAG_LABEL_WIDTH_BEFORE_CLIP); clipURLString = YES; } else { imageSize.width = MAX(labelSize.width + DRAG_LABEL_BORDER_X * 2.0f, urlStringSize.width + DRAG_LABEL_BORDER_X * 2.0f); } } NSImage *dragImage = [[[NSImage alloc] initWithSize: imageSize] autorelease]; [dragImage lockFocus]; [[NSColor colorWithDeviceRed: 0.7f green: 0.7f blue: 0.7f alpha: 0.8f] set]; // Drag a rectangle with rounded corners/ NSBezierPath *path = [NSBezierPath bezierPath]; [path appendBezierPathWithOvalInRect: NSMakeRect(0.0f, 0.0f, DRAG_LABEL_RADIUS * 2.0f, DRAG_LABEL_RADIUS * 2.0f)]; [path appendBezierPathWithOvalInRect: NSMakeRect(0, imageSize.height - DRAG_LABEL_RADIUS * 2.0f, DRAG_LABEL_RADIUS * 2.0f, DRAG_LABEL_RADIUS * 2.0f)]; [path appendBezierPathWithOvalInRect: NSMakeRect(imageSize.width - DRAG_LABEL_RADIUS * 2.0f, imageSize.height - DRAG_LABEL_RADIUS * 2.0f, DRAG_LABEL_RADIUS * 2.0f, DRAG_LABEL_RADIUS * 2.0f)]; [path appendBezierPathWithOvalInRect: NSMakeRect(imageSize.width - DRAG_LABEL_RADIUS * 2.0f, 0.0f, DRAG_LABEL_RADIUS * 2.0f, DRAG_LABEL_RADIUS * 2.0f)]; [path appendBezierPathWithRect: NSMakeRect(DRAG_LABEL_RADIUS, 0.0f, imageSize.width - DRAG_LABEL_RADIUS * 2.0f, imageSize.height)]; [path appendBezierPathWithRect: NSMakeRect(0.0f, DRAG_LABEL_RADIUS, DRAG_LABEL_RADIUS + 10.0f, imageSize.height - 2.0f * DRAG_LABEL_RADIUS)]; [path appendBezierPathWithRect: NSMakeRect(imageSize.width - DRAG_LABEL_RADIUS - 20.0f, DRAG_LABEL_RADIUS, DRAG_LABEL_RADIUS + 20.0f, imageSize.height - 2.0f * DRAG_LABEL_RADIUS)]; [path fill]; NSColor *topColor = [NSColor colorWithDeviceWhite:0.0f alpha:0.75f]; NSColor *bottomColor = [NSColor colorWithDeviceWhite:1.0f alpha:0.5f]; if (drawURLString) { if (clipURLString) urlString = [WebStringTruncator centerTruncateString: urlString toWidth:imageSize.width - (DRAG_LABEL_BORDER_X * 2.0f) withFont:urlFont]; [urlString _web_drawDoubledAtPoint:NSMakePoint(DRAG_LABEL_BORDER_X, DRAG_LABEL_BORDER_Y - [urlFont descender]) withTopColor:topColor bottomColor:bottomColor font:urlFont]; } if (clipLabelString) label = [WebStringTruncator rightTruncateString: label toWidth:imageSize.width - (DRAG_LABEL_BORDER_X * 2.0f) withFont:labelFont]; [label _web_drawDoubledAtPoint:NSMakePoint (DRAG_LABEL_BORDER_X, imageSize.height - DRAG_LABEL_BORDER_Y_OFFSET - [labelFont pointSize]) withTopColor:topColor bottomColor:bottomColor font:labelFont]; [dragImage unlockFocus]; return dragImage;}- (NSImage *)_dragImageForLinkElement:(NSDictionary *)element{ NSURL *linkURL = [element objectForKey: WebElementLinkURLKey]; NSString *label = [element objectForKey: WebElementLinkLabelKey]; NSString *urlString = [linkURL _web_userVisibleString]; return [self _dragImageForURL:urlString withLabel:label];}- (void)pasteboardChangedOwner:(NSPasteboard *)pasteboard{ [self setPromisedDragTIFFDataSource:0];}- (void)pasteboard:(NSPasteboard *)pasteboard provideDataForType:(NSString *)type{ if ([type isEqual:NSRTFDPboardType] && [[pasteboard types] containsObject:WebArchivePboardType]) { WebArchive *archive = [[WebArchive alloc] initWithData:[pasteboard dataForType:WebArchivePboardType]]; [pasteboard _web_writePromisedRTFDFromArchive:archive containsImage:[[pasteboard types] containsObject:NSTIFFPboardType]]; [archive release]; } else if ([type isEqual:NSTIFFPboardType] && [self promisedDragTIFFDataSource]) { if (Image* image = [self promisedDragTIFFDataSource]->image()) [pasteboard setData:(NSData *)image->getTIFFRepresentation() forType:NSTIFFPboardType]; [self setPromisedDragTIFFDataSource:0]; }}- (void)_handleAutoscrollForMouseDragged:(NSEvent *)event { [self autoscroll:event]; [self _startAutoscrollTimer:event]; } - (WebPluginController *)_pluginController{ return _private->pluginController;}- (void)_layoutForPrinting{ // Set printing mode temporarily so we can adjust the size of the view. This will allow // AppKit's pagination code to use the correct height for the page content. Leaving printing // mode on indefinitely would interfere with Mail's printing mechanism (at least), so we just // turn it off again after adjusting the size. [self _web_setPrintingModeRecursiveAndAdjustViewSize]; [self _web_clearPrintingModeRecursive];}- (void)_smartInsertForString:(NSString *)pasteString replacingRange:(DOMRange *)rangeToReplace beforeString:(NSString **)beforeString afterString:(NSString **)afterString{ if (!pasteString || !rangeToReplace || ![[self _webView] smartInsertDeleteEnabled]) { if (beforeString) *beforeString = nil; if (afterString) *afterString = nil; return; } [[self _frame] _smartInsertForString:pasteString replacingRange:rangeToReplace beforeString:beforeString afterString:afterString];}- (BOOL)_canSmartReplaceWithPasteboard:(NSPasteboard *)pasteboard{ return [[self _webView] smartInsertDeleteEnabled] && [[pasteboard types] containsObject:WebSmartPastePboardType];}- (void)_startAutoscrollTimer: (NSEvent *)triggerEvent{ if (_private->autoscrollTimer == nil) { _private->autoscro
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -