frame.cpp

来自「linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自Web」· C++ 代码 · 共 1,782 行 · 第 1/4 页

CPP
1,782
字号
    RefPtr<CSSValue> unicodeBidi;    RefPtr<CSSValue> direction;    if (editingAction == EditActionSetWritingDirection) {        unicodeBidi = mutableStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi);        direction = mutableStyle->getPropertyCSSValue(CSSPropertyDirection);    }    Node* node = selection()->selection().visibleStart().deepEquivalent().node();    computedStyle(node)->diff(mutableStyle.get());    if (editingAction == EditActionSetWritingDirection && unicodeBidi) {        ASSERT(unicodeBidi->isPrimitiveValue());        mutableStyle->setProperty(CSSPropertyUnicodeBidi, static_cast<CSSPrimitiveValue*>(unicodeBidi.get())->getIdent());        if (direction) {            ASSERT(direction->isPrimitiveValue());            mutableStyle->setProperty(CSSPropertyDirection, static_cast<CSSPrimitiveValue*>(direction.get())->getIdent());        }    }    // Handle block styles, substracting these from the typing style.    RefPtr<CSSMutableStyleDeclaration> blockStyle = mutableStyle->copyBlockProperties();    blockStyle->diff(mutableStyle.get());    if (blockStyle->length() > 0)        applyCommand(ApplyStyleCommand::create(document(), blockStyle.get(), editingAction));        // Set the remaining style as the typing style.    m_typingStyle = mutableStyle.release();}String Frame::selectionStartStylePropertyValue(int stylePropertyID) const{    Node *nodeToRemove;    RefPtr<CSSStyleDeclaration> selectionStyle = selectionComputedStyle(nodeToRemove);    if (!selectionStyle)        return String();    String value = selectionStyle->getPropertyValue(stylePropertyID);    if (nodeToRemove) {        ExceptionCode ec = 0;        nodeToRemove->remove(ec);        ASSERT(ec == 0);    }    return value;}PassRefPtr<CSSComputedStyleDeclaration> Frame::selectionComputedStyle(Node*& nodeToRemove) const{    nodeToRemove = 0;    if (selection()->isNone())        return 0;    RefPtr<Range> range(selection()->toNormalizedRange());    Position pos = range->editingStartPosition();    Element *elem = pos.element();    if (!elem)        return 0;        RefPtr<Element> styleElement = elem;    ExceptionCode ec = 0;    if (m_typingStyle) {        styleElement = document()->createElement(spanTag, false);        styleElement->setAttribute(styleAttr, m_typingStyle->cssText().impl(), ec);        ASSERT(ec == 0);                styleElement->appendChild(document()->createEditingTextNode(""), ec);        ASSERT(ec == 0);        if (elem->renderer() && elem->renderer()->canHaveChildren()) {            elem->appendChild(styleElement, ec);        } else {            Node *parent = elem->parent();            Node *next = elem->nextSibling();            if (next) {                parent->insertBefore(styleElement, next, ec);            } else {                parent->appendChild(styleElement, ec);            }        }        ASSERT(ec == 0);        nodeToRemove = styleElement.get();    }    return computedStyle(styleElement.release());}void Frame::textFieldDidBeginEditing(Element* e){    if (editor()->client())        editor()->client()->textFieldDidBeginEditing(e);}void Frame::textFieldDidEndEditing(Element* e){    if (editor()->client())        editor()->client()->textFieldDidEndEditing(e);}void Frame::textDidChangeInTextField(Element* e){    if (editor()->client())        editor()->client()->textDidChangeInTextField(e);}bool Frame::doTextFieldCommandFromEvent(Element* e, KeyboardEvent* ke){    if (editor()->client())        return editor()->client()->doTextFieldCommandFromEvent(e, ke);    return false;}void Frame::textWillBeDeletedInTextField(Element* input){    if (editor()->client())        editor()->client()->textWillBeDeletedInTextField(input);}void Frame::textDidChangeInTextArea(Element* e){    if (editor()->client())        editor()->client()->textDidChangeInTextArea(e);}void Frame::applyEditingStyleToBodyElement() const{    RefPtr<NodeList> list = m_doc->getElementsByTagName("body");    unsigned len = list->length();    for (unsigned i = 0; i < len; i++) {        applyEditingStyleToElement(static_cast<Element*>(list->item(i)));        }}void Frame::removeEditingStyleFromBodyElement() const{    RefPtr<NodeList> list = m_doc->getElementsByTagName("body");    unsigned len = list->length();    for (unsigned i = 0; i < len; i++) {        removeEditingStyleFromElement(static_cast<Element*>(list->item(i)));        }}void Frame::applyEditingStyleToElement(Element* element) const{    if (!element)        return;    CSSStyleDeclaration* style = element->style();    ASSERT(style);    ExceptionCode ec = 0;    style->setProperty(CSSPropertyWordWrap, "break-word", false, ec);    ASSERT(ec == 0);    style->setProperty(CSSPropertyWebkitNbspMode, "space", false, ec);    ASSERT(ec == 0);    style->setProperty(CSSPropertyWebkitLineBreak, "after-white-space", false, ec);    ASSERT(ec == 0);}void Frame::removeEditingStyleFromElement(Element*) const{}#ifndef NDEBUGstatic HashSet<Frame*>& keepAliveSet(){    DEFINE_STATIC_LOCAL(HashSet<Frame*>, staticKeepAliveSet, ());    return staticKeepAliveSet;}#endifvoid Frame::keepAlive(){    if (m_lifeSupportTimer.isActive())        return;#ifndef NDEBUG    keepAliveSet().add(this);#endif    ref();    m_lifeSupportTimer.startOneShot(0);}#ifndef NDEBUGvoid Frame::cancelAllKeepAlive(){    HashSet<Frame*>::iterator end = keepAliveSet().end();    for (HashSet<Frame*>::iterator it = keepAliveSet().begin(); it != end; ++it) {        Frame* frame = *it;        frame->m_lifeSupportTimer.stop();        frame->deref();    }    keepAliveSet().clear();}#endifvoid Frame::lifeSupportTimerFired(Timer<Frame>*){#ifndef NDEBUG    keepAliveSet().remove(this);#endif    deref();}void Frame::clearDOMWindow(){    if (m_domWindow) {        m_liveFormerWindows.add(m_domWindow.get());        m_domWindow->clear();    }    m_domWindow = 0;}RenderView* Frame::contentRenderer() const{    Document* doc = document();    if (!doc)        return 0;    RenderObject* object = doc->renderer();    if (!object)        return 0;    ASSERT(object->isRenderView());    return toRenderView(object);}HTMLFrameOwnerElement* Frame::ownerElement() const{    return m_ownerElement;}RenderPart* Frame::ownerRenderer() const{    HTMLFrameOwnerElement* ownerElement = m_ownerElement;    if (!ownerElement)        return 0;    RenderObject* object = ownerElement->renderer();    if (!object)        return 0;    // FIXME: If <object> is ever fixed to disassociate itself from frames    // that it has started but canceled, then this can turn into an ASSERT    // since m_ownerElement would be 0 when the load is canceled.    // https://bugs.webkit.org/show_bug.cgi?id=18585    if (!object->isRenderPart())        return 0;    return static_cast<RenderPart*>(object);}bool Frame::isDisconnected() const{    return m_isDisconnected;}void Frame::setIsDisconnected(bool isDisconnected){    m_isDisconnected = isDisconnected;}bool Frame::excludeFromTextSearch() const{    return m_excludeFromTextSearch;}void Frame::setExcludeFromTextSearch(bool exclude){    m_excludeFromTextSearch = exclude;}// returns FloatRect because going through IntRect would truncate any floatsFloatRect Frame::selectionBounds(bool clipToVisibleContent) const{    RenderView* root = contentRenderer();    FrameView* view = m_view.get();    if (!root || !view)        return IntRect();        IntRect selectionRect = root->selectionBounds(clipToVisibleContent);    return clipToVisibleContent ? intersection(selectionRect, view->visibleContentRect()) : selectionRect;}void Frame::selectionTextRects(Vector<FloatRect>& rects, bool clipToVisibleContent) const{    RenderView* root = contentRenderer();    if (!root)        return;    RefPtr<Range> selectedRange = selection()->toNormalizedRange();    Vector<IntRect> intRects;    selectedRange->addLineBoxRects(intRects, true);    unsigned size = intRects.size();    FloatRect visibleContentRect = m_view->visibleContentRect();    for (unsigned i = 0; i < size; ++i)        if (clipToVisibleContent)            rects.append(intersection(intRects[i], visibleContentRect));        else            rects.append(intRects[i]);}// Scans logically forward from "start", including any child framesstatic HTMLFormElement *scanForForm(Node *start){    Node *n;    for (n = start; n; n = n->traverseNextNode()) {        if (n->hasTagName(formTag))            return static_cast<HTMLFormElement*>(n);        else if (n->isHTMLElement() && static_cast<Element*>(n)->isFormControlElement())            return static_cast<HTMLFormControlElement*>(n)->form();        else if (n->hasTagName(frameTag) || n->hasTagName(iframeTag)) {            Node *childDoc = static_cast<HTMLFrameElementBase*>(n)->contentDocument();            if (HTMLFormElement *frameResult = scanForForm(childDoc))                return frameResult;        }    }    return 0;}// We look for either the form containing the current focus, or for one immediately after itHTMLFormElement *Frame::currentForm() const{    // start looking either at the active (first responder) node, or where the selection is    Node *start = m_doc ? m_doc->focusedNode() : 0;    if (!start)        start = selection()->start().node();        // try walking up the node tree to find a form element    Node *n;    for (n = start; n; n = n->parentNode()) {        if (n->hasTagName(formTag))            return static_cast<HTMLFormElement*>(n);        else if (n->isHTMLElement() && static_cast<Element*>(n)->isFormControlElement())            return static_cast<HTMLFormControlElement*>(n)->form();    }        // try walking forward in the node tree to find a form element    return start ? scanForForm(start) : 0;}void Frame::revealSelection(const ScrollAlignment& alignment) const{    IntRect rect;    switch (selection()->selectionType()) {        case VisibleSelection::NoSelection:            return;        case VisibleSelection::CaretSelection:            rect = selection()->absoluteCaretBounds();            break;        case VisibleSelection::RangeSelection:            rect = enclosingIntRect(selectionBounds(false));            break;    }    Position start = selection()->start();    ASSERT(start.node());    if (start.node() && start.node()->renderer()) {        // FIXME: This code only handles scrolling the startContainer's layer, but        // the selection rect could intersect more than just that.         // See <rdar://problem/4799899>.        if (RenderLayer* layer = start.node()->renderer()->enclosingLayer())            layer->scrollRectToVisible(rect, false, alignment, alignment);    }}void Frame::revealCaret(const ScrollAlignment& alignment) const{    if (selection()->isNone())        return;    Position extent = selection()->extent();    if (extent.node() && extent.node()->renderer()) {        IntRect extentRect = VisiblePosition(extent).absoluteCaretBounds();        RenderLayer* layer = extent.node()->renderer()->enclosingLayer();        if (layer)            layer->scrollRectToVisible(extentRect, false, alignment, alignment);    }}Frame* Frame::frameForWidget(const Widget* widget){    ASSERT_ARG(widget, widget);    if (RenderWidget* renderer = RenderWidget::find(widget))        if (Node* node = renderer->node())            return node->document()->frame();    // Assume all widgets are either a FrameView or owned by a RenderWidget.    // FIXME: That assumption is not right for scroll bars!    ASSERT(widget->isFrameView());    return static_cast<const FrameView*>(widget)->frame();}void Frame::clearTimers(FrameView *view, Document *document){    if (view) {        view->unscheduleRelayout();        if (view->frame()) {            if (document && document->renderer() && document->renderer()->hasLayer())                document->renderView()->layer()->suspendMarquees();            view->frame()->animation()->suspendAnimations(document);            view->frame()->eventHandler()->stopAutoscrollTimer();        }    }}void Frame::clearTimers(){    clearTimers(m_view.get(), document());}RenderStyle *Frame::styleForSelectionStart(Node *&nodeToRemove) const{    nodeToRemove = 0;        if (selection()->isNone())        return 0;        Position pos = selection()->selection().visibleStart().deepEquivalent();    if (!pos.isCandidate())        return 0;    Node *node = pos.node();    if (!node)        return 0;        if (!m_typingStyle)        return node->renderer()->style();        RefPtr<Element> styleElement = document()->createElement(spanTag, false);        ExceptionCode ec = 0;    String styleText = m_typingStyle->cssText() + " display: inline";    styleElement->setAttribute(styleAttr, styleText.impl(), ec);    ASSERT(ec == 0);        styleElement->appendChild(document()->createEditingTextNode(""), ec);    ASSERT(ec == 0);        node->parentNode()->appendChild(styleElement, ec);    ASSERT(ec == 0);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?