Add a line gutter to view source mode. The gutter uses counters, and this...
authorhyatt <hyatt@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 18 May 2007 05:07:23 +0000 (05:07 +0000)
committerhyatt <hyatt@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 18 May 2007 05:07:23 +0000 (05:07 +0000)
        that pseudoStyleForElement was not walking all UA rules properly.

        Reviewed by aroben

        * css/cssstyleselector.cpp:
        (WebCore::CSSStyleSelector::pseudoStyleForElement):
        * css/view-source.css:
        * html/HTMLViewSourceDocument.cpp:
        (WebCore::HTMLViewSourceDocument::HTMLViewSourceDocument):
        (WebCore::HTMLViewSourceDocument::addViewSourceToken):
        (WebCore::HTMLViewSourceDocument::addSpanWithClassName):
        (WebCore::HTMLViewSourceDocument::addLine):
        (WebCore::HTMLViewSourceDocument::addText):
        * html/HTMLViewSourceDocument.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@21548 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog
WebCore/css/cssstyleselector.cpp
WebCore/css/view-source.css
WebCore/html/HTMLViewSourceDocument.cpp
WebCore/html/HTMLViewSourceDocument.h

index 66cddb6bb9beb2937e600eee2bdf28b8971dccaa..9545c5a6be496949a151d3bab4fd75590378bfc3 100644 (file)
@@ -1,3 +1,21 @@
+2007-05-17  David Hyatt  <hyatt@apple.com>
+
+        Add a line gutter to view source mode.  The gutter uses counters, and this exposed the fact
+        that pseudoStyleForElement was not walking all UA rules properly.
+
+        Reviewed by aroben
+
+        * css/cssstyleselector.cpp:
+        (WebCore::CSSStyleSelector::pseudoStyleForElement):
+        * css/view-source.css:
+        * html/HTMLViewSourceDocument.cpp:
+        (WebCore::HTMLViewSourceDocument::HTMLViewSourceDocument):
+        (WebCore::HTMLViewSourceDocument::addViewSourceToken):
+        (WebCore::HTMLViewSourceDocument::addSpanWithClassName):
+        (WebCore::HTMLViewSourceDocument::addLine):
+        (WebCore::HTMLViewSourceDocument::addText):
+        * html/HTMLViewSourceDocument.h:
+
 2007-05-17  Justin Garcia  <justin.garcia@apple.com>
 
         Reviewed by ggaren
index 8fa5a1523f0fe2227ee02c94db57468275545a0e..121a83a8f7061493e412ade3c8ad28e86e73c1d4 100644 (file)
@@ -934,7 +934,7 @@ RenderStyle* CSSStyleSelector::pseudoStyleForElement(RenderStyle::PseudoId pseud
     
     // Check UA, user and author rules.
     int firstUARule = -1, lastUARule = -1, firstUserRule = -1, lastUserRule = -1, firstAuthorRule = -1, lastAuthorRule = -1;
-    matchRules(defaultStyle, firstUARule, lastUARule);
+    matchUARules(firstUARule, lastUARule);
     matchRules(m_userStyle, firstUserRule, lastUserRule);
     matchRules(m_authorStyle, firstAuthorRule, lastAuthorRule);
     
index a92fc0b76714f7c81457ce35986727096fcc672f..7177c85f6d64c41c671591d4d3c5cb93e69a67a3 100644 (file)
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
+body {
+    margin: 0
+}
+
+table {
+    border-spacing: 0;
+    counter-reset: lines;
+    white-space: pre-wrap !important;
+    margin: 0;
+    word-break: break-word;
+    font-family: monospace;
+}
+
+td {
+    padding: 0;
+    vertical-align: baseline
+}
+
+.webkit-line-number {
+    padding: 0 2px;
+    min-width: 17px;
+    background-color: rgb(240, 240, 240);
+    border-right: 1px solid rgb(128, 128, 128) !important;
+    -webkit-user-select: none;
+    text-align: right;
+    color: rgb(128, 128, 128);
+    word-break: normal;
+    white-space: nowrap;
+    font-size: 9px;
+    font-family: Helvetica
+}
+
+.webkit-line-number::before {
+    content: counter(lines);
+    counter-increment: lines;
+    -webkit-user-select: none
+}
+
+.webkit-line-content {
+    padding: 0 5px;
+}
+
 .webkit-html-tag {
     color: rgb(136, 18, 128)
 }
index 3bae6819986d51b43c2dbdb286dcb6cebf3dc936..443eff66935d3e4aca4ff8170697f189ad7a0dbf 100644 (file)
 #include "HTMLHtmlElement.h"
 #include "HTMLBodyElement.h"
 #include "HTMLPreElement.h"
+#include "HTMLTableElement.h"
+#include "HTMLTableCellElement.h"
+#include "HTMLTableRowElement.h"
+#include "HTMLTableSectionElement.h"
 #include "Text.h"
 #include "HTMLNames.h"
 
@@ -39,6 +43,8 @@ using namespace HTMLNames;
 HTMLViewSourceDocument::HTMLViewSourceDocument(DOMImplementation* implementation, Frame* frame)
     : HTMLDocument(implementation, frame)
     , m_current(0)
+    , m_tbody(0)
+    , m_td(0)
 {
 }
 
@@ -57,32 +63,29 @@ void HTMLViewSourceDocument::addViewSourceToken(Token* token)
         Element* body = new HTMLBodyElement(this);
         html->addChild(body);
         body->attach();
-        Element* pre = new HTMLPreElement(preTag, this);
-        Attribute* a = new MappedAttribute(styleAttr, "white-space:pre-wrap;margin:0;word-wrap:break-word");
-        NamedMappedAttrMap* attrs = new NamedMappedAttrMap(0);
-        attrs->insertAttribute(a, true);   
-        pre->setAttributeMap(attrs);     
-        body->addChild(pre);
-        pre->attach();
-        m_current = pre;
+        Element* table = new HTMLTableElement(this);
+        body->addChild(table);
+        table->attach();
+        m_tbody = new HTMLTableSectionElement(tbodyTag, this);
+        table->addChild(m_tbody);
+        m_tbody->attach();
+        m_current = m_tbody;
     }
     
-    if (token->tagName == textAtom) {
-        Text* t = new Text(this, token->text.get());
-        m_current->addChild(t);
-        t->attach();
-    } else if (token->tagName == commentAtom) {
+    if (token->tagName == textAtom)
+        addText(token->text.get(), "");
+    else if (token->tagName == commentAtom) {
         if (token->beginTag) {
-            Element* span = addSpanWithClassName("webkit-html-comment");
-            Text* t = new Text(this, String("<!--") + token->text.get() + "-->"); // FIXME: If the comment was degenerate, would be good to show the original here.
-            span->addChild(t);
-            t->attach();
+            m_current = addSpanWithClassName("webkit-html-comment");
+            addText(String("<!--") + token->text.get() + "-->", "webkit-html-comment");
         }
     } else {
         // Handle the tag.
         bool doctype = token->tagName.startsWith("!DOCTYPE", true);
         
-        Element* span = addSpanWithClassName(doctype ? "webkit-html-doctype" : "webkit-html-tag");
+        String classNameStr = doctype ? "webkit-html-doctype" : "webkit-html-tag";
+        m_current = addSpanWithClassName(classNameStr);
+
         String text = "<";
         if (!token->beginTag)
             text += "/";
@@ -91,42 +94,39 @@ void HTMLViewSourceDocument::addViewSourceToken(Token* token)
         if (!guide || !guide->size())
             text += ">";
 
-        Text* t = new Text(this, text);
-        span->addChild(t);
-        t->attach();
-            
+        addText(text, classNameStr);
+
         // Walk our guide string that tells us where attribute names/values should go.
         if (guide && guide->size()) {
             unsigned size = guide->size();
             unsigned begin = 0;
             unsigned currAttr = 0;
-            m_current = span;
             for (unsigned i = 0; i < size; i++) {
                 if (guide->at(i) == 'a' || guide->at(i) == 'x' || guide->at(i) == 'v') {
                     // Add in the string.
-                    Text* t = new Text(this, String((UChar*)(guide->data()) + begin, i - begin));
-                    span->addChild(t);
-                    t->attach();
-                    
+                    addText(String((UChar*)(guide->data()) + begin, i - begin), classNameStr);
+                     
                     begin = i + 1;
 
                     if (token->attrs && currAttr < token->attrs->length()) {
                         if (guide->at(i) == 'a') {
                             Attribute* attr = token->attrs->attributeItem(currAttr);
                             String name = attr->name().toString();
-                            Element* attrSpan = doctype || name == "/" ? span : addSpanWithClassName("webkit-html-attribute-name");
-                            t = new Text(this, name);
-                            attrSpan->addChild(t);
-                            t->attach();
+                            String nameClassStr = doctype ? "webkit-html-doctype" : (name == "/" ? "webkit-html-tag" : "webkit-html-attribute-name");
+                            addText(name, nameClassStr);
                             if (attr->value().isNull() || attr->value().isEmpty())
                                 currAttr++;
                         } else {
                             Attribute* attr = token->attrs->attributeItem(currAttr);
                             String value = attr->value().domString();
-                            Element* attrSpan = doctype ? span : addSpanWithClassName("webkit-html-attribute-value");
-                            t = new Text(this, value);
-                            attrSpan->addChild(t);
-                            t->attach();
+                            if (doctype)
+                                addText(value, "webkit-html-doctype");
+                            else {
+                                m_current = addSpanWithClassName("webkit-html-attribute-value");
+                                addText(value, "webkit-html-attribute-value");
+                                if (m_current != m_tbody)
+                                    m_current = m_current->parent();
+                            }
                             currAttr++;
                         }
                     }
@@ -134,24 +134,21 @@ void HTMLViewSourceDocument::addViewSourceToken(Token* token)
             }
             
             // Add in any string that might be left.
-            if (begin < size) {
-                Text* t = new Text(this, String((UChar*)(guide->data()) + begin, size - begin));
-                span->addChild(t);
-                t->attach();
-            }
+            if (begin < size)
+                addText(String((UChar*)(guide->data()) + begin, size - begin), classNameStr);
 
             // Add in the end tag.
-            Text* t = new Text(this, ">");
-            span->addChild(t);
-            t->attach();
-            
-            m_current = span->parentNode();
+            addText(">", classNameStr);
         }
+        
+        m_current = m_td;
     }
 }
 
 Element* HTMLViewSourceDocument::addSpanWithClassName(const String& className)
 {
+    if (m_current == m_tbody)
+        addLine(className);
     Element* span = new HTMLElement(spanTag, this);
     Attribute* a = new MappedAttribute(classAttr, className);
     NamedMappedAttrMap* attrs = new NamedMappedAttrMap(0);
@@ -162,4 +159,68 @@ Element* HTMLViewSourceDocument::addSpanWithClassName(const String& className)
     return span;
 }
 
+void HTMLViewSourceDocument::addLine(const String& className)
+{
+    // Create a table row.
+    Element* trow = new HTMLTableRowElement(this);
+    m_tbody->addChild(trow);
+    trow->attach();
+    
+    // Create a cell that will hold the line number (it is generated in the stylesheet using counters).
+    Element* td = new HTMLTableCellElement(tdTag, this);
+    Attribute* classNameAttr = new MappedAttribute(classAttr, "webkit-line-number");
+    NamedMappedAttrMap* attrs = new NamedMappedAttrMap(0);
+    attrs->insertAttribute(classNameAttr, true);
+
+    td->setAttributeMap(attrs);     
+    trow->addChild(td);
+    td->attach();
+
+    // Create a second cell for the line contents
+    td = new HTMLTableCellElement(tdTag, this);
+    classNameAttr = new MappedAttribute(classAttr, "webkit-line-content");
+    attrs = new NamedMappedAttrMap(0);
+    attrs->insertAttribute(classNameAttr, true);
+    td->setAttributeMap(attrs);     
+    trow->addChild(td);
+    td->attach();
+    m_current = m_td = td;
+
+    // Open up the needed spans.
+    if (!className.isEmpty()) {
+        if (className == "webkit-html-attribute-name" || className == "webkit-html-attribute-value")
+            m_current = addSpanWithClassName("webkit-html-tag");
+        m_current = addSpanWithClassName(className);
+    }
+}
+
+void HTMLViewSourceDocument::addText(const String& text, const String& className)
+{
+    if (text.isEmpty())
+        return;
+
+    // Add in the content, splitting on newlines.
+    Vector<String> lines = text.split('\n', true);
+    unsigned size = lines.size();
+    for (unsigned i = 0; i < size; i++) {
+        String substring = lines[i];
+        if (substring.isEmpty()) {
+            if (i == size - 1)
+                break;
+            substring = " ";
+        }
+        if (m_current == m_tbody)
+            addLine(className);
+        Text* t = new Text(this, substring);
+        m_current->addChild(t);
+        t->attach();
+        if (i < size - 1)
+            m_current = m_tbody;
+    }
+    
+    // Set current to m_tbody if the last character was a newline.
+    if (text[text.length() - 1] == '\n')
+        m_current = m_tbody;
+}
+
 }
index 6f5328420ac901217c67d2feef6a5b5923b03c74..774d65acb1e7557b0efbe4ed65b5c38d2ceee251 100644 (file)
@@ -41,9 +41,13 @@ public:
     
 private:
     Element* addSpanWithClassName(const String&);
+    void addLine(const String& className);
+    void addText(const String& text, const String& className);
 
 private:
     Node* m_current;
+    Node* m_tbody;
+    Node* m_td;
 };
 
 }