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

📄 rendertreeastext.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#include "config.h"#include "RenderTreeAsText.h"#include "CharacterNames.h"#include "Document.h"#include "Frame.h"#include "FrameView.h"#include "HTMLElement.h"#include "HTMLNames.h"#include "InlineTextBox.h"#include "RenderBR.h"#include "RenderInline.h"#include "RenderListMarker.h"#include "RenderTableCell.h"#include "RenderView.h"#include "RenderWidget.h"#include "SelectionController.h"#include "TextStream.h"#include <wtf/Vector.h>#if ENABLE(SVG)#include "RenderSVGRoot.h"#include "RenderSVGContainer.h"#include "RenderSVGInlineText.h"#include "RenderSVGText.h"#include "SVGRenderTreeAsText.h"#endifnamespace WebCore {using namespace HTMLNames;static void writeLayers(TextStream&, const RenderLayer* rootLayer, RenderLayer*, const IntRect& paintDirtyRect, int indent = 0);#if !ENABLE(SVG)static TextStream &operator<<(TextStream& ts, const IntRect& r){    return ts << "at (" << r.x() << "," << r.y() << ") size " << r.width() << "x" << r.height();}#endifstatic void writeIndent(TextStream& ts, int indent){    for (int i = 0; i != indent; ++i)        ts << "  ";}static void printBorderStyle(TextStream& ts, const EBorderStyle borderStyle){    switch (borderStyle) {        case BNONE:            ts << "none";            break;        case BHIDDEN:            ts << "hidden";            break;        case INSET:            ts << "inset";            break;        case GROOVE:            ts << "groove";            break;        case RIDGE:            ts << "ridge";            break;        case OUTSET:            ts << "outset";            break;        case DOTTED:            ts << "dotted";            break;        case DASHED:            ts << "dashed";            break;        case SOLID:            ts << "solid";            break;        case DOUBLE:            ts << "double";            break;    }    ts << " ";}static String getTagName(Node* n){    if (n->isDocumentNode())        return "";    if (n->isCommentNode())        return "COMMENT";    return n->nodeName();}static bool isEmptyOrUnstyledAppleStyleSpan(const Node* node){    if (!node || !node->isHTMLElement() || !node->hasTagName(spanTag))        return false;    const HTMLElement* elem = static_cast<const HTMLElement*>(node);    if (elem->getAttribute(classAttr) != "Apple-style-span")        return false;    if (!node->hasChildNodes())        return true;    CSSMutableStyleDeclaration* inlineStyleDecl = elem->inlineStyleDecl();    return (!inlineStyleDecl || inlineStyleDecl->length() == 0);}String quoteAndEscapeNonPrintables(const String& s){    Vector<UChar> result;    result.append('"');    for (unsigned i = 0; i != s.length(); ++i) {        UChar c = s[i];        if (c == '\\') {            result.append('\\');            result.append('\\');        } else if (c == '"') {            result.append('\\');            result.append('"');        } else if (c == '\n' || c == noBreakSpace)            result.append(' ');        else {            if (c >= 0x20 && c < 0x7F)                result.append(c);            else {                unsigned u = c;                String hex = String::format("\\x{%X}", u);                unsigned len = hex.length();                for (unsigned i = 0; i < len; ++i)                    result.append(hex[i]);            }        }    }    result.append('"');    return String::adopt(result);}static TextStream &operator<<(TextStream& ts, const RenderObject& o){    ts << o.renderName();    if (o.style() && o.style()->zIndex())        ts << " zI: " << o.style()->zIndex();    if (o.node()) {        String tagName = getTagName(o.node());        if (!tagName.isEmpty()) {            ts << " {" << tagName << "}";            // flag empty or unstyled AppleStyleSpan because we never            // want to leave them in the DOM            if (isEmptyOrUnstyledAppleStyleSpan(o.node()))                ts << " *empty or unstyled AppleStyleSpan*";        }    }    bool adjustForTableCells = o.containingBlock()->isTableCell();    IntRect r;    if (o.isText()) {        // FIXME: Would be better to dump the bounding box x and y rather than the first run's x and y, but that would involve updating        // many test results.        const RenderText& text = *toRenderText(&o);        IntRect linesBox = text.linesBoundingBox();        r = IntRect(text.firstRunX(), text.firstRunY(), linesBox.width(), linesBox.height());        if (adjustForTableCells && !text.firstTextBox())            adjustForTableCells = false;    } else if (o.isRenderInline()) {        // FIXME: Would be better not to just dump 0, 0 as the x and y here.        const RenderInline& inlineFlow = *toRenderInline(&o);        r = IntRect(0, 0, inlineFlow.linesBoundingBox().width(), inlineFlow.linesBoundingBox().height());        adjustForTableCells = false;    } else if (o.isTableCell()) {        // FIXME: Deliberately dump the "inner" box of table cells, since that is what current results reflect.  We'd like        // to clean up the results to dump both the outer box and the intrinsic padding so that both bits of information are        // captured by the results.        const RenderTableCell& cell = static_cast<const RenderTableCell&>(o);        r = IntRect(cell.x(), cell.y() + cell.intrinsicPaddingTop(), cell.width(), cell.height() - cell.intrinsicPaddingTop() - cell.intrinsicPaddingBottom());    } else if (o.isBox())        r = toRenderBox(&o)->frameRect();    // FIXME: Temporary in order to ensure compatibility with existing layout test results.    if (adjustForTableCells)        r.move(0, -static_cast<RenderTableCell*>(o.containingBlock())->intrinsicPaddingTop());    ts << " " << r;    if (!(o.isText() && !o.isBR())) {        if (o.parent() && (o.parent()->style()->color() != o.style()->color()))            ts << " [color=" << o.style()->color().name() << "]";        if (o.parent() && (o.parent()->style()->backgroundColor() != o.style()->backgroundColor()) &&            o.style()->backgroundColor().isValid() && o.style()->backgroundColor().rgb())            // Do not dump invalid or transparent backgrounds, since that is the default.            ts << " [bgcolor=" << o.style()->backgroundColor().name() << "]";                if (o.parent() && (o.parent()->style()->textFillColor() != o.style()->textFillColor()) &&            o.style()->textFillColor().isValid() && o.style()->textFillColor() != o.style()->color() &&            o.style()->textFillColor().rgb())            ts << " [textFillColor=" << o.style()->textFillColor().name() << "]";        if (o.parent() && (o.parent()->style()->textStrokeColor() != o.style()->textStrokeColor()) &&            o.style()->textStrokeColor().isValid() && o.style()->textStrokeColor() != o.style()->color() &&            o.style()->textStrokeColor().rgb())            ts << " [textStrokeColor=" << o.style()->textStrokeColor().name() << "]";        if (o.parent() && (o.parent()->style()->textStrokeWidth() != o.style()->textStrokeWidth()) &&            o.style()->textStrokeWidth() > 0)            ts << " [textStrokeWidth=" << o.style()->textStrokeWidth() << "]";        if (!o.isBoxModelObject())            return ts;        const RenderBoxModelObject& box = *toRenderBoxModelObject(&o);        if (box.borderTop() || box.borderRight() || box.borderBottom() || box.borderLeft()) {            ts << " [border:";            BorderValue prevBorder;            if (o.style()->borderTop() != prevBorder) {                prevBorder = o.style()->borderTop();                if (!box.borderTop())                    ts << " none";                else {                    ts << " (" << box.borderTop() << "px ";                    printBorderStyle(ts, o.style()->borderTopStyle());                    Color col = o.style()->borderTopColor();                    if (!col.isValid())                        col = o.style()->color();                    ts << col.name() << ")";                }            }            if (o.style()->borderRight() != prevBorder) {                prevBorder = o.style()->borderRight();                if (!box.borderRight())                    ts << " none";                else {                    ts << " (" << box.borderRight() << "px ";                    printBorderStyle(ts, o.style()->borderRightStyle());                    Color col = o.style()->borderRightColor();                    if (!col.isValid())                        col = o.style()->color();                    ts << col.name() << ")";                }            }            if (o.style()->borderBottom() != prevBorder) {                prevBorder = box.style()->borderBottom();

⌨️ 快捷键说明

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