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