frame.cpp
来自「linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自Web」· C++ 代码 · 共 1,782 行 · 第 1/4 页
CPP
1,782 行
String result = searchForLabelsAboveCell(regExp.get(), startingTableCell); if (!result.isEmpty()) return result; searchedCellAbove = true; } else if (n->isTextNode() && n->renderer() && n->renderer()->style()->visibility() == VISIBLE) { // For each text chunk, run the regexp String nodeString = n->nodeValue(); // add 100 for slop, to make it more likely that we'll search whole nodes if (lengthSearched + nodeString.length() > maxCharsSearched) nodeString = nodeString.right(charsSearchedThreshold - lengthSearched); int pos = regExp->searchRev(nodeString); if (pos >= 0) return nodeString.substring(pos, regExp->matchedLength()); lengthSearched += nodeString.length(); } } // If we started in a cell, but bailed because we found the start of the form or the // previous element, we still might need to search the row above us for a label. if (startingTableCell && !searchedCellAbove) { return searchForLabelsAboveCell(regExp.get(), startingTableCell); } return String();}String Frame::matchLabelsAgainstElement(const Vector<String>& labels, Element* element){ String name = element->getAttribute(nameAttr); if (name.isEmpty()) return String(); // Make numbers and _'s in field names behave like word boundaries, e.g., "address2" replace(name, RegularExpression("\\d", TextCaseSensitive), " "); name.replace('_', ' '); OwnPtr<RegularExpression> regExp(createRegExpForLabels(labels)); // Use the largest match we can find in the whole name string int pos; int length; int bestPos = -1; int bestLength = -1; int start = 0; do { pos = regExp->match(name, start); if (pos != -1) { length = regExp->matchedLength(); if (length >= bestLength) { bestPos = pos; bestLength = length; } start = pos + 1; } } while (pos != -1); if (bestPos != -1) return name.substring(bestPos, bestLength); return String();}const VisibleSelection& Frame::mark() const{ return m_mark;}void Frame::setMark(const VisibleSelection& s){ ASSERT(!s.base().node() || s.base().node()->document() == document()); ASSERT(!s.extent().node() || s.extent().node()->document() == document()); ASSERT(!s.start().node() || s.start().node()->document() == document()); ASSERT(!s.end().node() || s.end().node()->document() == document()); m_mark = s;}void Frame::notifyRendererOfSelectionChange(bool userTriggered){ RenderObject* renderer = 0; if (selection()->rootEditableElement()) renderer = selection()->rootEditableElement()->shadowAncestorNode()->renderer(); // If the current selection is in a textfield or textarea, notify the renderer that the selection has changed if (renderer && renderer->isTextControl()) toRenderTextControl(renderer)->selectionChanged(userTriggered);}void Frame::invalidateSelection(){ selection()->setNeedsLayout(); selectionLayoutChanged();}void Frame::setCaretVisible(bool flag){ if (m_caretVisible == flag) return; clearCaretRectIfNeeded(); m_caretVisible = flag; selectionLayoutChanged();}void Frame::clearCaretRectIfNeeded(){#if ENABLE(TEXT_CARET) if (m_caretPaint) { m_caretPaint = false; selection()->invalidateCaretRect(); }#endif}// Helper function that tells whether a particular node is an element that has an entire// Frame and FrameView, a <frame>, <iframe>, or <object>.static bool isFrameElement(const Node *n){ if (!n) return false; RenderObject *renderer = n->renderer(); if (!renderer || !renderer->isWidget()) return false; Widget* widget = static_cast<RenderWidget*>(renderer)->widget(); return widget && widget->isFrameView();}void Frame::setFocusedNodeIfNeeded(){ if (selection()->isNone() || !selection()->isFocusedAndActive()) return; Node* target = selection()->rootEditableElement(); if (target) { RenderObject* renderer = target->renderer(); // Walk up the render tree to search for a node to focus. // Walking up the DOM tree wouldn't work for shadow trees, like those behind the engine-based text fields. while (renderer) { // We don't want to set focus on a subframe when selecting in a parent frame, // so add the !isFrameElement check here. There's probably a better way to make this // work in the long term, but this is the safest fix at this time. if (target && target->isMouseFocusable() && !isFrameElement(target)) { page()->focusController()->setFocusedNode(target, this); return; } renderer = renderer->parent(); if (renderer) target = renderer->node(); } document()->setFocusedNode(0); }}void Frame::selectionLayoutChanged(){ bool caretRectChanged = selection()->recomputeCaretRect();#if ENABLE(TEXT_CARET) bool shouldBlink = m_caretVisible && selection()->isCaret() && selection()->isContentEditable(); // If the caret moved, stop the blink timer so we can restart with a // black caret in the new location. if (caretRectChanged || !shouldBlink) m_caretBlinkTimer.stop(); // Start blinking with a black caret. Be sure not to restart if we're // already blinking in the right location. if (shouldBlink && !m_caretBlinkTimer.isActive()) { if (double blinkInterval = theme()->caretBlinkInterval()) m_caretBlinkTimer.startRepeating(blinkInterval); if (!m_caretPaint) { m_caretPaint = true; selection()->invalidateCaretRect(); } }#else if (!caretRectChanged) return;#endif RenderView* view = contentRenderer(); if (!view) return; VisibleSelection selection = this->selection()->selection(); if (!selection.isRange()) view->clearSelection(); else { // Use the rightmost candidate for the start of the selection, and the leftmost candidate for the end of the selection. // Example: foo <a>bar</a>. Imagine that a line wrap occurs after 'foo', and that 'bar' is selected. If we pass [foo, 3] // as the start of the selection, the selection painting code will think that content on the line containing 'foo' is selected // and will fill the gap before 'bar'. Position startPos = selection.start(); if (startPos.downstream().isCandidate()) startPos = startPos.downstream(); Position endPos = selection.end(); if (endPos.upstream().isCandidate()) endPos = endPos.upstream(); // We can get into a state where the selection endpoints map to the same VisiblePosition when a selection is deleted // because we don't yet notify the SelectionController of text removal. if (startPos.isNotNull() && endPos.isNotNull() && selection.visibleStart() != selection.visibleEnd()) { RenderObject *startRenderer = startPos.node()->renderer(); RenderObject *endRenderer = endPos.node()->renderer(); view->setSelection(startRenderer, startPos.offset(), endRenderer, endPos.offset()); } }}void Frame::caretBlinkTimerFired(Timer<Frame>*){#if ENABLE(TEXT_CARET) ASSERT(m_caretVisible); ASSERT(selection()->isCaret()); bool caretPaint = m_caretPaint; if (selection()->isCaretBlinkingSuspended() && caretPaint) return; m_caretPaint = !caretPaint; selection()->invalidateCaretRect();#endif}void Frame::paintCaret(GraphicsContext* p, int tx, int ty, const IntRect& clipRect) const{#if ENABLE(TEXT_CARET) if (m_caretPaint && m_caretVisible) selection()->paintCaret(p, tx, ty, clipRect);#endif}void Frame::paintDragCaret(GraphicsContext* p, int tx, int ty, const IntRect& clipRect) const{#if ENABLE(TEXT_CARET) SelectionController* dragCaretController = m_page->dragCaretController(); ASSERT(dragCaretController->selection().isCaret()); if (dragCaretController->selection().start().node()->document()->frame() == this) dragCaretController->paintCaret(p, tx, ty, clipRect);#endif}float Frame::zoomFactor() const{ return m_zoomFactor;}bool Frame::isZoomFactorTextOnly() const{ return m_page->settings()->zoomsTextOnly();}bool Frame::shouldApplyTextZoom() const{ if (m_zoomFactor == 1.0f || !isZoomFactorTextOnly()) return false;#if ENABLE(SVG) if (m_doc->isSVGDocument()) return false;#endif return true;}bool Frame::shouldApplyPageZoom() const{ if (m_zoomFactor == 1.0f || isZoomFactorTextOnly()) return false;#if ENABLE(SVG) if (m_doc->isSVGDocument()) return false;#endif return true;}void Frame::setZoomFactor(float percent, bool isTextOnly){ if (m_zoomFactor == percent && isZoomFactorTextOnly() == isTextOnly) return;#if ENABLE(SVG) // SVG doesn't care if the zoom factor is text only. It will always apply a // zoom to the whole SVG. if (m_doc->isSVGDocument()) { if (!static_cast<SVGDocument*>(m_doc.get())->zoomAndPanEnabled()) return; m_zoomFactor = percent; m_page->settings()->setZoomsTextOnly(true); // We do this to avoid doing any scaling of CSS pixels, since the SVG has its own notion of zoom. if (m_doc->renderer()) m_doc->renderer()->repaint(); return; }#endif m_zoomFactor = percent; m_page->settings()->setZoomsTextOnly(isTextOnly); m_doc->recalcStyle(Node::Force); for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling()) child->setZoomFactor(m_zoomFactor, isTextOnly); if (m_doc->renderer() && m_doc->renderer()->needsLayout() && view()->didFirstLayout()) view()->layout();}void Frame::setPrinting(bool printing, float minPageWidth, float maxPageWidth, bool adjustViewSize){ m_doc->setPrinting(printing); view()->setMediaType(printing ? "print" : "screen"); m_doc->updateStyleSelector(); view()->forceLayoutWithPageWidthRange(minPageWidth, maxPageWidth, adjustViewSize); for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling()) child->setPrinting(printing, minPageWidth, maxPageWidth, adjustViewSize);}void Frame::setJSStatusBarText(const String& text){ m_kjsStatusBarText = text; if (m_page) m_page->chrome()->setStatusbarText(this, m_kjsStatusBarText);}void Frame::setJSDefaultStatusBarText(const String& text){ m_kjsDefaultStatusBarText = text; if (m_page) m_page->chrome()->setStatusbarText(this, m_kjsDefaultStatusBarText);}String Frame::jsStatusBarText() const{ return m_kjsStatusBarText;}String Frame::jsDefaultStatusBarText() const{ return m_kjsDefaultStatusBarText;}void Frame::setNeedsReapplyStyles(){ if (m_needsReapplyStyles) return; m_needsReapplyStyles = true; // FrameView's "layout" timer includes reapplyStyles, so despite its // name, it's what we want to call here. if (view()) view()->scheduleRelayout();}bool Frame::needsReapplyStyles() const{ return m_needsReapplyStyles;}void Frame::reapplyStyles(){ m_needsReapplyStyles = false; // FIXME: This call doesn't really make sense in a method called // "reapplyStyles". We should probably eventually move it into its own // method. m_doc->docLoader()->setAutoLoadImages(m_page && m_page->settings()->loadsImagesAutomatically()); #if FRAME_LOADS_USER_STYLESHEET const KURL userStyleSheetLocation = m_page ? m_page->settings()->userStyleSheetLocation() : KURL(); if (!userStyleSheetLocation.isEmpty()) setUserStyleSheetLocation(userStyleSheetLocation); else setUserStyleSheet(String());#endif // FIXME: It's not entirely clear why the following is needed. // The document automatically does this as required when you set the style sheet. // But we had problems when this code was removed. Details are in // <http://bugs.webkit.org/show_bug.cgi?id=8079>. m_doc->updateStyleSelector();}bool Frame::shouldChangeSelection(const VisibleSelection& newSelection) const{ return shouldChangeSelection(selection()->selection(), newSelection, newSelection.affinity(), false);}bool Frame::shouldChangeSelection(const VisibleSelection& oldSelection, const VisibleSelection& newSelection, EAffinity affinity, bool stillSelecting) const{ return editor()->client()->shouldChangeSelectedRange(oldSelection.toNormalizedRange().get(), newSelection.toNormalizedRange().get(), affinity, stillSelecting);}bool Frame::shouldDeleteSelection(const VisibleSelection& selection) const{ return editor()->client()->shouldDeleteRange(selection.toNormalizedRange().get());}bool Frame::isContentEditable() const { if (m_editor.clientIsEditable()) return true; return m_doc->inDesignMode();}#if !PLATFORM(MAC)void Frame::setUseSecureKeyboardEntry(bool){}#endifvoid Frame::updateSecureKeyboardEntryIfActive(){ if (selection()->isFocusedAndActive()) setUseSecureKeyboardEntry(m_doc->useSecureKeyboardEntryWhenActive());}CSSMutableStyleDeclaration *Frame::typingStyle() const{ return m_typingStyle.get();}void Frame::setTypingStyle(CSSMutableStyleDeclaration *style){ m_typingStyle = style;}void Frame::clearTypingStyle(){ m_typingStyle = 0;}void Frame::computeAndSetTypingStyle(CSSStyleDeclaration *style, EditAction editingAction){ if (!style || style->length() == 0) { clearTypingStyle(); return; } // Calculate the current typing style. RefPtr<CSSMutableStyleDeclaration> mutableStyle = style->makeMutable(); if (typingStyle()) { typingStyle()->merge(mutableStyle.get()); mutableStyle = typingStyle(); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?