📄 webhtmlview.mm
字号:
inContext:context subresources:0])) return fragment;#if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD) if ([types containsObject:NSPICTPboardType] && (fragment = [self _documentFragmentFromPasteboard:pasteboard forType:NSPICTPboardType inContext:context subresources:0])) return fragment;#endif // Only 10.5 and higher support setting and retrieving pasteboard types with UTIs, but we don't believe // that any applications on Tiger put types for which we only have a UTI, like PNG, on the pasteboard. if ([types containsObject:(NSString*)kUTTypePNG] && (fragment = [self _documentFragmentFromPasteboard:pasteboard forType:(NSString*)kUTTypePNG inContext:context subresources:0])) return fragment; if ([types containsObject:NSURLPboardType] && (fragment = [self _documentFragmentFromPasteboard:pasteboard forType:NSURLPboardType inContext:context subresources:0])) return fragment; if (allowPlainText && [types containsObject:NSStringPboardType] && (fragment = [self _documentFragmentFromPasteboard:pasteboard forType:NSStringPboardType inContext:context subresources:0])) { return fragment; } return nil;}- (NSString *)_plainTextFromPasteboard:(NSPasteboard *)pasteboard{ NSArray *types = [pasteboard types]; if ([types containsObject:NSStringPboardType]) return [pasteboard stringForType:NSStringPboardType]; NSAttributedString *attributedString = nil; NSString *string; if ([types containsObject:NSRTFDPboardType]) attributedString = [[NSAttributedString alloc] initWithRTFD:[pasteboard dataForType:NSRTFDPboardType] documentAttributes:NULL]; if (attributedString == nil && [types containsObject:NSRTFPboardType]) attributedString = [[NSAttributedString alloc] initWithRTF:[pasteboard dataForType:NSRTFPboardType] documentAttributes:NULL]; if (attributedString != nil) { string = [[attributedString string] copy]; [attributedString release]; return [string autorelease]; } if ([types containsObject:NSFilenamesPboardType]) { string = [[pasteboard propertyListForType:NSFilenamesPboardType] componentsJoinedByString:@"\n"]; if (string != nil) return string; } NSURL *URL; if ((URL = [NSURL URLFromPasteboard:pasteboard])) { string = [URL _web_userVisibleString]; if ([string length] > 0) return string; } return nil;}- (void)_pasteWithPasteboard:(NSPasteboard *)pasteboard allowPlainText:(BOOL)allowPlainText{ DOMRange *range = [self _selectedRange]; DOMDocumentFragment *fragment = [self _documentFragmentFromPasteboard:pasteboard inContext:range allowPlainText:allowPlainText]; WebFrame *frame = [self _frame]; if (fragment && [self _shouldInsertFragment:fragment replacingDOMRange:[self _selectedRange] givenAction:WebViewInsertActionPasted]) { [frame _replaceSelectionWithFragment:fragment selectReplacement:NO smartReplace:[self _canSmartReplaceWithPasteboard:pasteboard] matchStyle:NO]; }}- (void)_pasteAsPlainTextWithPasteboard:(NSPasteboard *)pasteboard{ NSString *text = [self _plainTextFromPasteboard:pasteboard]; if ([self _shouldReplaceSelectionWithText:text givenAction:WebViewInsertActionPasted]) [[self _frame] _replaceSelectionWithText:text selectReplacement:NO smartReplace:[self _canSmartReplaceWithPasteboard:pasteboard]];}- (void)_removeMouseMovedObserverUnconditionally{ if (!_private || !_private->observingMouseMovedNotifications) return; [[NSNotificationCenter defaultCenter] removeObserver:self name:WKMouseMovedNotification() object:nil]; _private->observingMouseMovedNotifications = false;}- (void)_removeSuperviewObservers{ if (!_private || !_private->observingSuperviewNotifications) return; NSView *superview = [self superview]; if (!superview || ![self window]) return; NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; [notificationCenter removeObserver:self name:NSViewFrameDidChangeNotification object:superview]; [notificationCenter removeObserver:self name:NSViewBoundsDidChangeNotification object:superview]; _private->observingSuperviewNotifications = false;}- (void)_removeWindowObservers{ if (!_private->observingWindowNotifications) return; NSWindow *window = [self window]; if (!window) return; NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; [notificationCenter removeObserver:self name:NSWindowDidBecomeKeyNotification object:nil]; [notificationCenter removeObserver:self name:NSWindowDidResignKeyNotification object:nil]; [notificationCenter removeObserver:self name:NSWindowWillCloseNotification object:window]; [notificationCenter removeObserver:self name:WKWindowWillOrderOnScreenNotification() object:window]; _private->observingWindowNotifications = false;}- (BOOL)_shouldInsertFragment:(DOMDocumentFragment *)fragment replacingDOMRange:(DOMRange *)range givenAction:(WebViewInsertAction)action{ WebView *webView = [self _webView]; DOMNode *child = [fragment firstChild]; if ([fragment lastChild] == child && [child isKindOfClass:[DOMCharacterData class]]) return [[webView _editingDelegateForwarder] webView:webView shouldInsertText:[(DOMCharacterData *)child data] replacingDOMRange:range givenAction:action]; return [[webView _editingDelegateForwarder] webView:webView shouldInsertNode:fragment replacingDOMRange:range givenAction:action];}- (BOOL)_shouldInsertText:(NSString *)text replacingDOMRange:(DOMRange *)range givenAction:(WebViewInsertAction)action{ WebView *webView = [self _webView]; return [[webView _editingDelegateForwarder] webView:webView shouldInsertText:text replacingDOMRange:range givenAction:action];}- (BOOL)_shouldReplaceSelectionWithText:(NSString *)text givenAction:(WebViewInsertAction)action{ return [self _shouldInsertText:text replacingDOMRange:[self _selectedRange] givenAction:action];}// Calculate the vertical size of the view that fits on a single page- (float)_calculatePrintHeight{ // Obtain the print info object for the current operation NSPrintInfo *pi = [[NSPrintOperation currentOperation] printInfo]; // Calculate the page height in points NSSize paperSize = [pi paperSize]; return paperSize.height - [pi topMargin] - [pi bottomMargin];}- (DOMRange *)_selectedRange{ Frame* coreFrame = core([self _frame]); return coreFrame ? kit(coreFrame->selection()->toNormalizedRange().get()) : nil;}- (BOOL)_shouldDeleteRange:(DOMRange *)range{ Frame* coreFrame = core([self _frame]); return coreFrame && coreFrame->editor()->shouldDeleteRange(core(range));}- (NSView *)_hitViewForEvent:(NSEvent *)event{ // Usually, we hack AK's hitTest method to catch all events at the topmost WebHTMLView. // Callers of this method, however, want to query the deepest view instead. forceNSViewHitTest = YES; NSView *hitView = [[[self window] contentView] hitTest:[event locationInWindow]]; forceNSViewHitTest = NO; return hitView;}- (void)_writeSelectionWithPasteboardTypes:(NSArray *)types toPasteboard:(NSPasteboard *)pasteboard cachedAttributedString:(NSAttributedString *)attributedString{ // Put HTML on the pasteboard. if ([types containsObject:WebArchivePboardType]) { if (RefPtr<LegacyWebArchive> coreArchive = LegacyWebArchive::createFromSelection(core([self _frame]))) { if (RetainPtr<CFDataRef> data = coreArchive ? coreArchive->rawDataRepresentation() : 0) [pasteboard setData:(NSData *)data.get() forType:WebArchivePboardType]; } } // Put the attributed string on the pasteboard (RTF/RTFD format). if ([types containsObject:NSRTFDPboardType]) { if (attributedString == nil) { attributedString = [self selectedAttributedString]; } NSData *RTFDData = [attributedString RTFDFromRange:NSMakeRange(0, [attributedString length]) documentAttributes:nil]; [pasteboard setData:RTFDData forType:NSRTFDPboardType]; } if ([types containsObject:NSRTFPboardType]) { if (attributedString == nil) { attributedString = [self selectedAttributedString]; } if ([attributedString containsAttachments]) { attributedString = [attributedString _web_attributedStringByStrippingAttachmentCharacters]; } NSData *RTFData = [attributedString RTFFromRange:NSMakeRange(0, [attributedString length]) documentAttributes:nil]; [pasteboard setData:RTFData forType:NSRTFPboardType]; } // Put plain string on the pasteboard. if ([types containsObject:NSStringPboardType]) { // Map to a plain old space because this is better for source code, other browsers do it, // and because HTML forces you to do this any time you want two spaces in a row. NSMutableString *s = [[self selectedString] mutableCopy]; const unichar NonBreakingSpaceCharacter = 0xA0; NSString *NonBreakingSpaceString = [NSString stringWithCharacters:&NonBreakingSpaceCharacter length:1]; [s replaceOccurrencesOfString:NonBreakingSpaceString withString:@" " options:0 range:NSMakeRange(0, [s length])]; [pasteboard setString:s forType:NSStringPboardType]; [s release]; } if ([self _canSmartCopyOrDelete] && [types containsObject:WebSmartPastePboardType]) { [pasteboard setData:nil forType:WebSmartPastePboardType]; }}- (void)_setMouseDownEvent:(NSEvent *)event{ ASSERT(!event || [event type] == NSLeftMouseDown || [event type] == NSRightMouseDown || [event type] == NSOtherMouseDown); if (event == _private->mouseDownEvent) return; [event retain]; [_private->mouseDownEvent release]; _private->mouseDownEvent = event;}- (void)_cancelUpdateFocusedAndActiveStateTimer{ if (_private->updateFocusedAndActiveStateTimer) { CFRunLoopTimerInvalidate(_private->updateFocusedAndActiveStateTimer); CFRelease(_private->updateFocusedAndActiveStateTimer); _private->updateFocusedAndActiveStateTimer = NULL; }}- (void)_cancelUpdateMouseoverTimer{ if (_private->updateMouseoverTimer) { CFRunLoopTimerInvalidate(_private->updateMouseoverTimer); CFRelease(_private->updateMouseoverTimer); _private->updateMouseoverTimer = NULL; }}- (WebHTMLView *)_topHTMLView{ // FIXME: this can fail if the dataSource is nil, which happens when the WebView is tearing down from the window closing. WebHTMLView *view = (WebHTMLView *)[[[[_private->dataSource _webView] mainFrame] frameView] documentView]; ASSERT(view); ASSERT([view isKindOfClass:[WebHTMLView class]]); return view;}- (BOOL)_isTopHTMLView{ // FIXME: this should be a cached boolean that doesn't rely on _topHTMLView since that can fail (see _topHTMLView). return self == [self _topHTMLView];}- (void)_web_setPrintingModeRecursive{ [self _setPrinting:YES minimumPageWidth:0.0f maximumPageWidth:0.0f adjustViewSize:NO];#ifndef NDEBUG _private->enumeratingSubviews = YES;#endif NSMutableArray *descendantWebHTMLViews = [[NSMutableArray alloc] init]; [self _web_addDescendantWebHTMLViewsToArray:descendantWebHTMLViews]; unsigned count = [descendantWebHTMLViews count]; for (unsigned i = 0; i < count; ++i) [[descendantWebHTMLViews objectAtIndex:i] _setPrinting:YES minimumPageWidth:0.0f maximumPageWidth:0.0f adjustViewSize:NO]; [descendantWebHTMLViews release];#ifndef NDEBUG _private->enumeratingSubviews = NO;#endif}- (void)_web_clearPrintingModeRecursive{ [self _setPrinting:NO minimumPageWidth:0.0f maximumPageWidth:0.0f adjustViewSize:NO];#ifndef NDEBUG _private->enumeratingSubviews = YES;#endif NSMutableArray *descendantWebHTMLViews = [[NSMutableArray alloc] init]; [self _web_addDescendantWebHTMLViewsToArray:descendantWebHTMLViews]; unsigned count = [descendantWebHTMLViews count]; for (unsigned i = 0; i < count; ++i) [[descendantWebHTMLViews objectAtIndex:i] _setPrinting:NO minimumPageWidth:0.0f maximumPageWidth:0.0f adjustViewSize:NO]; [descendantWebHTMLViews release];#ifndef NDEBUG _private->enumeratingSubviews = NO;#endif}- (void)_web_setPrintingModeRecursiveAndAdjustViewSize{ [self _setPrinting:YES minimumPageWidth:0.0f maximumPageWidth:0.0f adjustViewSize:YES];#ifndef NDEBUG _private->enumeratingSubviews = YES;#endif NSMutableArray *descendantWebHTMLViews = [[NSMutableArray alloc] init]; [self _web_addDescendantWebHTMLViewsToArray:descendantWebHTMLViews]; unsigned count = [descendantWebHTMLViews count]; for (unsigned i = 0; i < count; ++i) [[descendantWebHTMLViews objectAtIndex:i] _setPrinting:YES minimumPageWidth:0.0f maximumPageWidth:0.0f adjustViewSize:YES]; [descendantWebHTMLViews release];#ifndef NDEBUG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -