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 + -
显示快捷键?