⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 markup.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 4 页
字号:
            } else {                preMarkups.append(getStartMarkup(ancestor, updatedRange.get(), annotate, convertBlocksToInlines));                markups.append(getEndMarkup(ancestor));            }            if (nodes)                nodes->append(ancestor);                        lastClosed = ancestor;                        if (ancestor == specialCommonAncestor)                break;        }    }        DEFINE_STATIC_LOCAL(const String, styleSpanOpen, ("<span class=\"" AppleStyleSpanClass "\" style=\""));    DEFINE_STATIC_LOCAL(const String, styleSpanClose, ("</span>"));        // Add a wrapper span with the styles that all of the nodes in the markup inherit.    Node* parentOfLastClosed = lastClosed ? lastClosed->parentNode() : 0;    if (parentOfLastClosed && parentOfLastClosed->renderer()) {        RefPtr<CSSMutableStyleDeclaration> style = computedStyle(parentOfLastClosed)->copyInheritableProperties();        // Styles that Mail blockquotes contribute should only be placed on the Mail blockquote, to help        // us differentiate those styles from ones that the user has applied.  This helps us        // get the color of content pasted into blockquotes right.        removeEnclosingMailBlockquoteStyle(style.get(), parentOfLastClosed);                // Document default styles will be added on another wrapper span.        removeDefaultStyles(style.get(), document);                // Since we are converting blocks to inlines, remove any inherited block properties that are in the style.        // This cuts out meaningless properties and prevents properties from magically affecting blocks later        // if the style is cloned for a new block element during a future editing operation.        if (convertBlocksToInlines)            style->removeBlockProperties();        if (style->length() > 0) {            Vector<UChar> openTag;            append(openTag, styleSpanOpen);            appendAttributeValue(openTag, style->cssText(), documentIsHTML);            openTag.append('\"');            openTag.append('>');            preMarkups.append(String::adopt(openTag));                        markups.append(styleSpanClose);        }    }        if (lastClosed && lastClosed != document->documentElement()) {        // Add a style span with the document's default styles.  We add these in a separate        // span so that at paste time we can differentiate between document defaults and user        // applied styles.        RefPtr<CSSMutableStyleDeclaration> defaultStyle = computedStyle(document->documentElement())->copyInheritableProperties();                if (defaultStyle->length() > 0) {            Vector<UChar> openTag;            append(openTag, styleSpanOpen);            appendAttributeValue(openTag, defaultStyle->cssText(), documentIsHTML);            openTag.append('\"');            openTag.append('>');            preMarkups.append(String::adopt(openTag));            markups.append(styleSpanClose);        }    }    // FIXME: The interchange newline should be placed in the block that it's in, not after all of the content, unconditionally.    if (annotate && needInterchangeNewlineAfter(visibleEnd.previous()))        markups.append(interchangeNewlineString);        if (deleteButton)        deleteButton->enable();    return joinMarkups(preMarkups, markups);}PassRefPtr<DocumentFragment> createFragmentFromMarkup(Document* document, const String& markup, const String& baseURL){    ASSERT(document->documentElement()->isHTMLElement());    // FIXME: What if the document element is not an HTML element?    HTMLElement *element = static_cast<HTMLElement*>(document->documentElement());    RefPtr<DocumentFragment> fragment = element->createContextualFragment(markup);    if (fragment && !baseURL.isEmpty() && baseURL != blankURL() && baseURL != document->baseURL())        completeURLs(fragment.get(), baseURL);    return fragment.release();}String createMarkup(const Node* node, EChildrenOnly includeChildren, Vector<Node*>* nodes){    Vector<UChar> result;    if (!node)        return "";    Document* document = node->document();    Frame* frame = document->frame();    DeleteButtonController* deleteButton = frame ? frame->editor()->deleteButtonController() : 0;    // disable the delete button so it's elements are not serialized into the markup    if (deleteButton) {        if (node->isDescendantOf(deleteButton->containerElement()))            return "";        deleteButton->disable();    }    appendMarkup(result, const_cast<Node*>(node), includeChildren, nodes);    if (deleteButton)        deleteButton->enable();    return String::adopt(result);}static void fillContainerFromString(ContainerNode* paragraph, const String& string){    Document* document = paragraph->document();    ExceptionCode ec = 0;    if (string.isEmpty()) {        paragraph->appendChild(createBlockPlaceholderElement(document), ec);        ASSERT(ec == 0);        return;    }    ASSERT(string.find('\n') == -1);    Vector<String> tabList;    string.split('\t', true, tabList);    String tabText = "";    bool first = true;    size_t numEntries = tabList.size();    for (size_t i = 0; i < numEntries; ++i) {        const String& s = tabList[i];        // append the non-tab textual part        if (!s.isEmpty()) {            if (!tabText.isEmpty()) {                paragraph->appendChild(createTabSpanElement(document, tabText), ec);                ASSERT(ec == 0);                tabText = "";            }            RefPtr<Node> textNode = document->createTextNode(stringWithRebalancedWhitespace(s, first, i + 1 == numEntries));            paragraph->appendChild(textNode.release(), ec);            ASSERT(ec == 0);        }        // there is a tab after every entry, except the last entry        // (if the last character is a tab, the list gets an extra empty entry)        if (i + 1 != numEntries)            tabText.append('\t');        else if (!tabText.isEmpty()) {            paragraph->appendChild(createTabSpanElement(document, tabText), ec);            ASSERT(ec == 0);        }                first = false;    }}PassRefPtr<DocumentFragment> createFragmentFromText(Range* context, const String& text){    if (!context)        return 0;    Node* styleNode = context->firstNode();    if (!styleNode) {        styleNode = context->startPosition().node();        if (!styleNode)            return 0;    }    Document* document = styleNode->document();    RefPtr<DocumentFragment> fragment = document->createDocumentFragment();        if (text.isEmpty())        return fragment.release();    String string = text;    string.replace("\r\n", "\n");    string.replace('\r', '\n');    ExceptionCode ec = 0;    RenderObject* renderer = styleNode->renderer();    if (renderer && renderer->style()->preserveNewline()) {        fragment->appendChild(document->createTextNode(string), ec);        ASSERT(ec == 0);        if (string.endsWith("\n")) {            RefPtr<Element> element = createBreakElement(document);            element->setAttribute(classAttr, AppleInterchangeNewline);                        fragment->appendChild(element.release(), ec);            ASSERT(ec == 0);        }        return fragment.release();    }    // A string with no newlines gets added inline, rather than being put into a paragraph.    if (string.find('\n') == -1) {        fillContainerFromString(fragment.get(), string);        return fragment.release();    }    // Break string into paragraphs. Extra line breaks turn into empty paragraphs.    Node* blockNode = enclosingBlock(context->firstNode());    Element* block = static_cast<Element*>(blockNode);    bool useClonesOfEnclosingBlock = blockNode        && blockNode->isElementNode()        && !block->hasTagName(bodyTag)        && !block->hasTagName(htmlTag)        && block != editableRootForPosition(context->startPosition());        Vector<String> list;    string.split('\n', true, list); // true gets us empty strings in the list    size_t numLines = list.size();    for (size_t i = 0; i < numLines; ++i) {        const String& s = list[i];        RefPtr<Element> element;        if (s.isEmpty() && i + 1 == numLines) {            // For last line, use the "magic BR" rather than a P.            element = createBreakElement(document);            element->setAttribute(classAttr, AppleInterchangeNewline);                    } else {            if (useClonesOfEnclosingBlock)                element = block->cloneElement();            else                element = createDefaultParagraphElement(document);            fillContainerFromString(element.get(), s);        }        fragment->appendChild(element.release(), ec);        ASSERT(ec == 0);    }    return fragment.release();}PassRefPtr<DocumentFragment> createFragmentFromNodes(Document *document, const Vector<Node*>& nodes){    if (!document)        return 0;    // disable the delete button so it's elements are not serialized into the markup    if (document->frame())        document->frame()->editor()->deleteButtonController()->disable();    RefPtr<DocumentFragment> fragment = document->createDocumentFragment();    ExceptionCode ec = 0;    size_t size = nodes.size();    for (size_t i = 0; i < size; ++i) {        RefPtr<Element> element = createDefaultParagraphElement(document);        element->appendChild(nodes[i], ec);        ASSERT(ec == 0);        fragment->appendChild(element.release(), ec);        ASSERT(ec == 0);    }    if (document->frame())        document->frame()->editor()->deleteButtonController()->enable();    return fragment.release();}String createFullMarkup(const Node* node){    if (!node)        return String();            Document* document = node->document();    if (!document)        return String();            Frame* frame = document->frame();    if (!frame)        return String();    // FIXME: This is never "for interchange". Is that right?        String markupString = createMarkup(node, IncludeNode, 0);    Node::NodeType nodeType = node->nodeType();    if (nodeType != Node::DOCUMENT_NODE && nodeType != Node::DOCUMENT_TYPE_NODE)        markupString = frame->documentTypeString() + markupString;    return markupString;}String createFullMarkup(const Range* range){    if (!range)        return String();    Node* node = range->startContainer();    if (!node)        return String();            Document* document = node->document();    if (!document)        return String();            Frame* frame = document->frame();    if (!frame)        return String();    // FIXME: This is always "for interchange". Is that right? See the previous method.    return frame->documentTypeString() + createMarkup(range, 0, AnnotateForInterchange);        }}

⌨️ 快捷键说明

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