Changeset 21526 in webkit


Ignore:
Timestamp:
May 16, 2007 11:27:28 PM (17 years ago)
Author:
hyatt
Message:

Improve the syntax-highlighted view source mode. It now preserves all whitespace properly
and highlights doctypes and comments (in addition to all the stuff it could highlight before).

Reviewed by aroben

  • html/HTMLTokenizer.cpp: (WebCore::Token::addAttribute): (WebCore::HTMLTokenizer::parseTag):
  • html/HTMLTokenizer.h: (WebCore::Token::Token): (WebCore::Token::~Token): (WebCore::Token::reset): (WebCore::Token::addViewSourceChar):
  • html/HTMLViewSourceDocument.cpp: (WebCore::HTMLViewSourceDocument::addViewSourceToken):
  • html/HTMLViewSourceDocument.h:
Location:
trunk/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r21524 r21526  
     12007-05-16  David Hyatt  <hyatt@apple.com>
     2
     3        Improve the syntax-highlighted view source mode.  It now preserves all whitespace properly
     4        and highlights doctypes and comments (in addition to all the stuff it could highlight before).
     5
     6        Reviewed by aroben
     7
     8        * html/HTMLTokenizer.cpp:
     9        (WebCore::Token::addAttribute):
     10        (WebCore::HTMLTokenizer::parseTag):
     11        * html/HTMLTokenizer.h:
     12        (WebCore::Token::Token):
     13        (WebCore::Token::~Token):
     14        (WebCore::Token::reset):
     15        (WebCore::Token::addViewSourceChar):
     16        * html/HTMLViewSourceDocument.cpp:
     17        (WebCore::HTMLViewSourceDocument::addViewSourceToken):
     18        * html/HTMLViewSourceDocument.h:
     19
    1202007-05-16  Maciej Stachowiak  <mjs@apple.com>
    221
  • trunk/WebCore/html/HTMLTokenizer.cpp

    r21009 r21526  
    126126}
    127127
    128 inline void Token::addAttribute(Document* doc, const AtomicString& attrName, const AtomicString& v)
    129 {
    130     if (!attrName.isEmpty() && attrName != "/") {
     128inline void Token::addAttribute(Document* doc, AtomicString& attrName, const AtomicString& v, bool viewSourceMode)
     129{
     130    if (!attrName.isEmpty() && (viewSourceMode || attrName != "/")) {
    131131        Attribute* a = new MappedAttribute(attrName, v);
    132132        if (!attrs)
     
    134134        attrs->insertAttribute(a);
    135135    }
     136   
     137    attrName = emptyAtom;
    136138}
    137139
     
    918920                // Now that we've shaved off any invalid / that might have followed the name), make the tag.
    919921                // FIXME: FireFox and WinIE turn !foo nodes into comments, we ignore comments. (fast/parser/tag-with-exclamation-point.html)
    920                 if (ptr[0] != '!') {
     922                if (ptr[0] != '!' || inViewSourceMode()) {
    921923                    currToken.tagName = AtomicString(ptr);
    922924                    currToken.beginTag = beginTag;
     
    944946                    break;
    945947                }
     948                if (inViewSourceMode())
     949                    currToken.addViewSourceChar(curchar);
    946950                ++src;
    947951            }
     
    971975                    if (currToken.tagName == scriptTag && curchar == '>' && attrName == "/")
    972976                        currToken.flat = true;
     977                    if (inViewSourceMode())
     978                        currToken.addViewSourceChar('a');
    973979                    break;
    974980                }
    975981               
    976982                // tolower() shows up on profiles. This is faster!
    977                 if (curchar >= 'A' && curchar <= 'Z')
     983                if (curchar >= 'A' && curchar <= 'Z' && !inViewSourceMode())
    978984                    cBuffer[cBufferPos++] = curchar + ('a' - 'A');
    979985                else
    980986                    cBuffer[cBufferPos++] = curchar;
     987                   
    981988                ++src;
    982989            }
     
    987994                *dest++ = 0;
    988995                state.setTagState(SearchEqual);
     996                if (inViewSourceMode())
     997                    currToken.addViewSourceChar('a');
    989998            }
    990999            break;
     
    10031012#endif
    10041013                        state.setTagState(SearchValue);
     1014                        if (inViewSourceMode())
     1015                            currToken.addViewSourceChar(curchar);
    10051016                        ++src;
    10061017                    }
    10071018                    else {
    1008                         currToken.addAttribute(m_doc, attrName, emptyAtom);
     1019                        currToken.addAttribute(m_doc, attrName, emptyAtom, inViewSourceMode());
    10091020                        dest = buffer;
    10101021                        state.setTagState(SearchAttribute);
     
    10121023                    break;
    10131024                }
     1025                if (inViewSourceMode())
     1026                    currToken.addViewSourceChar(curchar);
    10141027                ++src;
    10151028            }
     
    10221035                        tquote = curchar == '\"' ? DoubleQuote : SingleQuote;
    10231036                        state.setTagState(QuotedValue);
     1037                        if (inViewSourceMode())
     1038                            currToken.addViewSourceChar(curchar);
    10241039                        ++src;
    10251040                    } else
     
    10281043                    break;
    10291044                }
     1045                if (inViewSourceMode())
     1046                    currToken.addViewSourceChar(curchar);
    10301047                ++src;
    10311048            }
     
    10511068                    AtomicString v(buffer+1, dest-buffer-1);
    10521069                    attrName = v; // Just make the name/value match. (FIXME: Is this some WinIE quirk?)
    1053                     currToken.addAttribute(m_doc, attrName, v);
     1070                    currToken.addAttribute(m_doc, attrName, v, inViewSourceMode());
     1071                    if (inViewSourceMode())
     1072                        currToken.addViewSourceChar('x');
    10541073                    state.setTagState(SearchAttribute);
    10551074                    dest = buffer;
     
    10731092                            dest--; // remove trailing newlines
    10741093                        AtomicString v(buffer+1, dest-buffer-1);
    1075                         if (attrName.isEmpty())
     1094                        if (attrName.isEmpty()) {
    10761095                            attrName = v; // Make the name match the value. (FIXME: Is this a WinIE quirk?)
    1077                         currToken.addAttribute(m_doc, attrName, v);
    1078 
     1096                            if (inViewSourceMode())
     1097                                currToken.addViewSourceChar('x');
     1098                        } else if (inViewSourceMode())
     1099                            currToken.addViewSourceChar('v');
     1100                        currToken.addAttribute(m_doc, attrName, v, inViewSourceMode());
    10791101                        dest = buffer;
    10801102                        state.setTagState(SearchAttribute);
    10811103                        tquote = NoQuote;
     1104                        if (inViewSourceMode())
     1105                            currToken.addViewSourceChar(curchar);
    10821106                        ++src;
    10831107                        break;
     
    11081132                    {
    11091133                        AtomicString v(buffer+1, dest-buffer-1);
    1110                         currToken.addAttribute(m_doc, attrName, v);
     1134                        currToken.addAttribute(m_doc, attrName, v, inViewSourceMode());
     1135                        if (inViewSourceMode())
     1136                            currToken.addViewSourceChar('v');
    11111137                        dest = buffer;
    11121138                        state.setTagState(SearchAttribute);
     
    11311157                    currToken.flat = true;
    11321158
     1159                if (inViewSourceMode())
     1160                    currToken.addViewSourceChar(*src);
    11331161                ++src;
    11341162            }
     
    11561184            bool isSelfClosingScript = currToken.flat && currToken.beginTag && currToken.tagName == scriptTag;
    11571185            bool beginTag = !currToken.flat && currToken.beginTag;
    1158             if (currToken.beginTag && currToken.tagName == scriptTag && !parser->skipMode()) {
     1186            if (currToken.beginTag && currToken.tagName == scriptTag && !inViewSourceMode() && !parser->skipMode()) {
    11591187                Attribute* a = 0;
    11601188                scriptSrc = String();
  • trunk/WebCore/html/HTMLTokenizer.h

    r21511 r21526  
    3131#include "Tokenizer.h"
    3232#include "CachedResourceClient.h"
     33#include <wtf/Vector.h>
     34#include <wtf/OwnPtr.h>
    3335
    3436namespace WebCore {
     
    5153class Token {
    5254public:
    53     Token() : beginTag(true), flat(false) { }
    54 
    55     void addAttribute(Document*, const AtomicString& attrName, const AtomicString& v);
     55    Token() : beginTag(true), flat(false), m_sourceInfo(0) { }
     56    ~Token() { }
     57
     58    void addAttribute(Document*, AtomicString& attrName, const AtomicString& v, bool viewSourceMode);
    5659
    5760    bool isOpenTag(const QualifiedName& fullName) const { return beginTag && fullName.localName() == tagName; }
     
    6568        beginTag = true;
    6669        flat = false;
     70        if (m_sourceInfo)
     71            m_sourceInfo->clear();
    6772    }
     73
     74    void addViewSourceChar(UChar c) { if (!m_sourceInfo.get()) m_sourceInfo.set(new Vector<UChar>); m_sourceInfo->append(c); }
    6875
    6976    RefPtr<NamedMappedAttrMap> attrs;
     
    7279    bool beginTag;
    7380    bool flat;
     81    OwnPtr<Vector<UChar> > m_sourceInfo;
    7482};
    7583
  • trunk/WebCore/html/HTMLViewSourceDocument.cpp

    r21179 r21526  
    5959        body->attach();
    6060        Element* pre = new HTMLPreElement(preTag, this);
     61        Attribute* a = new MappedAttribute(styleAttr, "white-space:pre-wrap;margin:0;word-wrap:break-word");
     62        NamedMappedAttrMap* attrs = new NamedMappedAttrMap(0);
     63        attrs->insertAttribute(a);   
     64        pre->setAttributeMap(attrs);     
    6165        body->addChild(pre);
    6266        pre->attach();
     
    6973        t->attach();
    7074    } else if (token->tagName == commentAtom) {
    71    
     75        if (token->beginTag) {
     76            Element* span = addSpanWithClassName("webkit-html-comment");
     77            Text* t = new Text(this, String("<!--") + token->text.get() + "-->"); // FIXME: If the comment was degenerate, would be good to show the original here.
     78            span->addChild(t);
     79            t->attach();
     80        }
    7281    } else {
    7382        // Handle the tag.
    74         Element* span = addSpanWithClassName("webkit-html-tag");
     83        bool doctype = token->tagName.startsWith("!DOCTYPE", true);
     84       
     85        Element* span = addSpanWithClassName(doctype ? "webkit-html-doctype" : "webkit-html-tag");
    7586        String text = "<";
    7687        if (!token->beginTag)
    7788            text += "/";
    7889        text += token->tagName;
    79         if (!token->attrs)
     90        Vector<UChar>* guide = token->m_sourceInfo.get();
     91        if (!guide || !guide->size())
    8092            text += ">";
     93
    8194        Text* t = new Text(this, text);
    8295        span->addChild(t);
    8396        t->attach();
    84        
    85         // Now handle attributes.
    86         if (token->attrs) {
    87             unsigned length = token->attrs->length();
    88             for (unsigned i = 0; i < length; i++)
    89                 addViewSourceAttribute(token->attrs->attributeItem(i));
    90        
    91             span = addSpanWithClassName("webkit-html-tag");
    92             t = new Text(this, ">");
     97           
     98        // Walk our guide string that tells us where attribute names/values should go.
     99        if (guide && guide->size()) {
     100            unsigned size = guide->size();
     101            unsigned begin = 0;
     102            unsigned currAttr = 0;
     103            m_current = span;
     104            for (unsigned i = 0; i < size; i++) {
     105                if (guide->at(i) == 'a' || guide->at(i) == 'x' || guide->at(i) == 'v') {
     106                    // Add in the string.
     107                    Text* t = new Text(this, String((UChar*)(guide->data()) + begin, i - begin));
     108                    span->addChild(t);
     109                    t->attach();
     110                   
     111                    begin = i + 1;
     112
     113                    if (token->attrs && currAttr < token->attrs->length()) {
     114                        if (guide->at(i) == 'a') {
     115                            Attribute* attr = token->attrs->attributeItem(currAttr);
     116                            String name = attr->name().toString();
     117                            Element* attrSpan = doctype || name == "/" ? span : addSpanWithClassName("webkit-html-attribute-name");
     118                            t = new Text(this, name);
     119                            attrSpan->addChild(t);
     120                            t->attach();
     121                            if (attr->value().isNull() || attr->value().isEmpty())
     122                                currAttr++;
     123                        } else {
     124                            Attribute* attr = token->attrs->attributeItem(currAttr);
     125                            String value = attr->value().domString();
     126                            Element* attrSpan = doctype ? span : addSpanWithClassName("webkit-html-attribute-value");
     127                            t = new Text(this, value);
     128                            attrSpan->addChild(t);
     129                            t->attach();
     130                            currAttr++;
     131                        }
     132                    }
     133                }
     134            }
     135           
     136            // Add in any string that might be left.
     137            if (begin < size) {
     138                Text* t = new Text(this, String((UChar*)(guide->data()) + begin, size - begin));
     139                span->addChild(t);
     140                t->attach();
     141            }
     142
     143            // Add in the end tag.
     144            Text* t = new Text(this, ">");
    93145            span->addChild(t);
    94146            t->attach();
     147           
     148            m_current = span->parentNode();
    95149        }
    96        
    97     }
    98 }
    99 
    100 void HTMLViewSourceDocument::addViewSourceAttribute(Attribute* attr)
    101 {
    102     // FIXME: Don't just hard-code the whitespace between attribute values.
    103     Text* t = new Text(this, " ");
    104     m_current->addChild(t);
    105     t->attach();
    106    
    107     // Attribute name.
    108     // FIXME: Losing whitespace between the name and the = sign and between the = sign and the value.
    109     Element* span = addSpanWithClassName("webkit-html-attribute-name");
    110     String name = attr->name().toString();
    111     if (!attr->value().isNull())
    112         name += "=";
    113     t = new Text(this, name);
    114     span->addChild(t);
    115     t->attach();
    116    
    117     // Attribute value.
    118     if (!attr->value().isNull()) {
    119         Element* span = addSpanWithClassName("webkit-html-attribute-value");
    120         String text = "\""; // FIXME: Don't assume the attr is quoted.
    121         text += attr->value();
    122         text += "\"";
    123         t = new Text(this, text);
    124         span->addChild(t);
    125         t->attach();
    126150    }
    127151}
  • trunk/WebCore/html/HTMLViewSourceDocument.h

    r21179 r21526  
    3939   
    4040    void addViewSourceToken(Token*);
    41     void addViewSourceAttribute(Attribute*);
    4241   
    4342private:
Note: See TracChangeset for help on using the changeset viewer.