📄 webframe.mm
字号:
if (!self) return nil; _private = [[WebFramePrivate alloc] init]; if (fv) { [_private setWebFrameView:fv]; [fv _setWebFrame:self]; } _private->shouldCreateRenderers = YES; ++WebFrameCount; return self;}- (void)_clearCoreFrame{ _private->coreFrame = 0;}- (void)_updateBackgroundAndUpdatesWhileOffscreen{ WebView *webView = getWebView(self); BOOL drawsBackground = [webView drawsBackground]; NSColor *backgroundColor = [webView backgroundColor]; Frame* coreFrame = _private->coreFrame; for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) { WebFrame *webFrame = kit(frame); // Don't call setDrawsBackground:YES here because it may be NO because of a load // in progress; WebFrameLoaderClient keeps it set to NO during the load process. if (!drawsBackground) [[[webFrame frameView] _scrollView] setDrawsBackground:NO]; [[[webFrame frameView] _scrollView] setBackgroundColor:backgroundColor]; id documentView = [[webFrame frameView] documentView]; if ([documentView respondsToSelector:@selector(setDrawsBackground:)]) [documentView setDrawsBackground:drawsBackground]; if ([documentView respondsToSelector:@selector(setBackgroundColor:)]) [documentView setBackgroundColor:backgroundColor]; if (frame && frame->view()) { frame->view()->setTransparent(!drawsBackground); Color color = colorFromNSColor([backgroundColor colorUsingColorSpaceName:NSDeviceRGBColorSpace]); frame->view()->setBaseBackgroundColor(color); frame->view()->setShouldUpdateWhileOffscreen([webView shouldUpdateWhileOffscreen]); } }}- (void)_setInternalLoadDelegate:(id)internalLoadDelegate{ _private->internalLoadDelegate = internalLoadDelegate;}- (id)_internalLoadDelegate{ return _private->internalLoadDelegate;}#ifndef BUILDING_ON_TIGER- (void)_unmarkAllBadGrammar{ Frame* coreFrame = _private->coreFrame; for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) { if (Document* document = frame->document()) document->removeMarkers(DocumentMarker::Grammar); }}#endif- (void)_unmarkAllMisspellings{ Frame* coreFrame = _private->coreFrame; for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) { if (Document* document = frame->document()) document->removeMarkers(DocumentMarker::Spelling); }}- (BOOL)_hasSelection{ id documentView = [_private->webFrameView documentView]; // optimization for common case to avoid creating potentially large selection string if ([documentView isKindOfClass:[WebHTMLView class]]) if (Frame* coreFrame = _private->coreFrame) return coreFrame->selection()->isRange(); if ([documentView conformsToProtocol:@protocol(WebDocumentText)]) return [[documentView selectedString] length] > 0; return NO;}- (void)_clearSelection{ id documentView = [_private->webFrameView documentView]; if ([documentView conformsToProtocol:@protocol(WebDocumentText)]) [documentView deselectAll];}#if !ASSERT_DISABLED- (BOOL)_atMostOneFrameHasSelection{ // FIXME: 4186050 is one known case that makes this debug check fail. BOOL found = NO; Frame* coreFrame = _private->coreFrame; for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) if ([kit(frame) _hasSelection]) { if (found) return NO; found = YES; } return YES;}#endif- (WebFrame *)_findFrameWithSelection{ Frame* coreFrame = _private->coreFrame; for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) { WebFrame *webFrame = kit(frame); if ([webFrame _hasSelection]) return webFrame; } return nil;}- (void)_clearSelectionInOtherFrames{ // We rely on WebDocumentSelection protocol implementors to call this method when they become first // responder. It would be nicer to just notice first responder changes here instead, but there's no // notification sent when the first responder changes in general (Radar 2573089). WebFrame *frameWithSelection = [[getWebView(self) mainFrame] _findFrameWithSelection]; if (frameWithSelection != self) [frameWithSelection _clearSelection]; // While we're in the general area of selection and frames, check that there is only one now. ASSERT([[getWebView(self) mainFrame] _atMostOneFrameHasSelection]);}static inline WebDataSource *dataSource(DocumentLoader* loader){ return loader ? static_cast<WebDocumentLoaderMac*>(loader)->dataSource() : nil;}- (WebDataSource *)_dataSource{ return dataSource(_private->coreFrame->loader()->documentLoader());}- (void)_addData:(NSData *)data{ Document* document = _private->coreFrame->document(); // Document may be nil if the part is about to redirect // as a result of JS executing during load, i.e. one frame // changing another's location before the frame's document // has been created. if (!document) return; document->setShouldCreateRenderers(_private->shouldCreateRenderers); _private->coreFrame->loader()->addData((const char *)[data bytes], [data length]);}- (NSString *)_stringWithDocumentTypeStringAndMarkupString:(NSString *)markupString{ return _private->coreFrame->documentTypeString() + markupString;}- (NSArray *)_nodesFromList:(Vector<Node*> *)nodesVector{ size_t size = nodesVector->size(); NSMutableArray *nodes = [NSMutableArray arrayWithCapacity:size]; for (size_t i = 0; i < size; ++i) [nodes addObject:[DOMNode _wrapNode:(*nodesVector)[i]]]; return nodes;}- (NSString *)_markupStringFromRange:(DOMRange *)range nodes:(NSArray **)nodes{ // FIXME: This is always "for interchange". Is that right? See the previous method. Vector<Node*> nodeList; NSString *markupString = createMarkup([range _range], nodes ? &nodeList : 0, AnnotateForInterchange); if (nodes) *nodes = [self _nodesFromList:&nodeList]; return [self _stringWithDocumentTypeStringAndMarkupString:markupString];}- (NSString *)_selectedString{ return _private->coreFrame->displayStringModifiedByEncoding(_private->coreFrame->selectedText());}- (NSString *)_stringForRange:(DOMRange *)range{ // This will give a system malloc'd buffer that can be turned directly into an NSString unsigned length; UChar* buf = plainTextToMallocAllocatedBuffer([range _range], length, true); if (!buf) return [NSString string]; // Transfer buffer ownership to NSString return [[[NSString alloc] initWithCharactersNoCopy:buf length:length freeWhenDone:YES] autorelease];}- (void)_drawRect:(NSRect)rect contentsOnly:(BOOL)contentsOnly{ PlatformGraphicsContext* platformContext = static_cast<PlatformGraphicsContext*>([[NSGraphicsContext currentContext] graphicsPort]); ASSERT([[NSGraphicsContext currentContext] isFlipped]); GraphicsContext context(platformContext); if (contentsOnly) _private->coreFrame->view()->paintContents(&context, enclosingIntRect(rect)); else _private->coreFrame->view()->paint(&context, enclosingIntRect(rect));}// Used by pagination code called from AppKit when a standalone web page is printed.- (NSArray*)_computePageRectsWithPrintWidthScaleFactor:(float)printWidthScaleFactor printHeight:(float)printHeight{ NSMutableArray* pages = [NSMutableArray arrayWithCapacity:5]; if (printWidthScaleFactor <= 0) { LOG_ERROR("printWidthScaleFactor has bad value %.2f", printWidthScaleFactor); return pages; } if (printHeight <= 0) { LOG_ERROR("printHeight has bad value %.2f", printHeight); return pages; } if (!_private->coreFrame || !_private->coreFrame->document() || !_private->coreFrame->view()) return pages; RenderView* root = static_cast<RenderView *>(_private->coreFrame->document()->renderer()); if (!root) return pages; FrameView* view = _private->coreFrame->view(); if (!view) return pages; NSView* documentView = view->documentView(); if (!documentView) return pages; float currPageHeight = printHeight; float docHeight = root->layer()->height(); float docWidth = root->layer()->width(); float printWidth = docWidth/printWidthScaleFactor; // We need to give the part the opportunity to adjust the page height at each step. for (float i = 0; i < docHeight; i += currPageHeight) { float proposedBottom = min(docHeight, i + printHeight); view->adjustPageHeight(&proposedBottom, i, proposedBottom, i); currPageHeight = max(1.0f, proposedBottom - i); for (float j = 0; j < docWidth; j += printWidth) { NSValue* val = [NSValue valueWithRect: NSMakeRect(j, i, printWidth, currPageHeight)]; [pages addObject: val]; } } return pages;}- (BOOL)_getVisibleRect:(NSRect*)rect{ ASSERT_ARG(rect, rect); if (RenderPart* ownerRenderer = _private->coreFrame->ownerRenderer()) { if (ownerRenderer->needsLayout()) return NO; *rect = ownerRenderer->absoluteClippedOverflowRect(); return YES; } return NO;}- (NSString *)_stringByEvaluatingJavaScriptFromString:(NSString *)string{ return [self _stringByEvaluatingJavaScriptFromString:string forceUserGesture:true];}- (NSString *)_stringByEvaluatingJavaScriptFromString:(NSString *)string forceUserGesture:(BOOL)forceUserGesture{ ASSERT(_private->coreFrame->document()); JSValuePtr result = _private->coreFrame->loader()->executeScript(string, forceUserGesture).jsValue(); if (!_private->coreFrame) // In case the script removed our frame from the page. return @""; // This bizarre set of rules matches behavior from WebKit for Safari 2.0. // If you don't like it, use -[WebScriptObject evaluateWebScript:] or // JSEvaluateScript instead, since they have less surprising semantics. if (!result || !result.isBoolean() && !result.isString() && !result.isNumber()) return @""; JSLock lock(false); return String(result.toString(_private->coreFrame->script()->globalObject()->globalExec()));}- (NSRect)_caretRectAtNode:(DOMNode *)node offset:(int)offset affinity:(NSSelectionAffinity)affinity{ VisiblePosition visiblePosition([node _node], offset, static_cast<EAffinity>(affinity)); return visiblePosition.absoluteCaretBounds();}- (NSRect)_firstRectForDOMRange:(DOMRange *)range{ return _private->coreFrame->firstRectForRange([range _range]);}- (void)_scrollDOMRangeToVisible:(DOMRange *)range{ NSRect rangeRect = [self _firstRectForDOMRange:range]; Node *startNode = [[range startContainer] _node]; if (startNode && startNode->renderer()) { RenderLayer *layer = startNode->renderer()->enclosingLayer(); if (layer) layer->scrollRectToVisible(enclosingIntRect(rangeRect), false, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded); }}- (BOOL)_needsLayout{ return _private->coreFrame->view() ? _private->coreFrame->view()->needsLayout() : false;}- (id)_accessibilityTree{#if HAVE(ACCESSIBILITY) if (!AXObjectCache::accessibilityEnabled()) { AXObjectCache::enableAccessibility(); if ([[NSApp accessibilityAttributeValue:NSAccessibilityEnhancedUserInterfaceAttribute] boolValue]) AXObjectCache::enableEnhancedUserInterfaceAccessibility(); } if (!_private->coreFrame || !_private->coreFrame->document()) return nil; RenderView* root = static_cast<RenderView *>(_private->coreFrame->document()->renderer()); if (!root) return nil; return _private->coreFrame->document()->axObjectCache()->getOrCreate(root)->wrapper();#else return nil;#endif}- (DOMRange *)_rangeByAlteringCurrentSelection:(SelectionController::EAlteration)alteration direction:(SelectionController::EDirection)direction granularity:(TextGranularity)granularity{ if (_private->coreFrame->selection()->isNone()) return nil;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -