Fix for 9538, support syntax highlighted HTML source. Lots of loose
authorhyatt <hyatt@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 26 Jun 2006 23:53:02 +0000 (23:53 +0000)
committerhyatt <hyatt@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 26 Jun 2006 23:53:02 +0000 (23:53 +0000)
        ends still (script/style/comments/doctype/entities/accurate whitespace).

        Reviewed by darin

        * DerivedSources.make:
        * WebCore.xcodeproj/project.pbxproj:
        * bridge/mac/WebCoreFrameBridge.h:
        * bridge/mac/WebCoreFrameBridge.mm:
        (-[WebCoreFrameBridge setInViewSourceMode:]):
        (-[WebCoreFrameBridge inViewSourceMode]):
        * css/cssstyleselector.cpp:
        (WebCore::CSSStyleSelector::loadDefaultStyle):
        (WebCore::CSSStyleSelector::matchUARules):
        * css/cssstyleselector.h:
        * css/view-source.css: Added.
        * dom/Document.cpp:
        (WebCore::Document::implicitClose):
        * dom/xml_tokenizer.h:
        (WebCore::Tokenizer::Tokenizer):
        (WebCore::Tokenizer::~Tokenizer):
        (WebCore::Tokenizer::inViewSourceMode):
        (WebCore::Tokenizer::setInViewSourceMode):
        * html/HTMLAttributeNames.in:
        * html/HTMLFrameElement.cpp:
        (WebCore::HTMLFrameElement::init):
        (WebCore::HTMLFrameElement::parseMappedAttribute):
        (WebCore::HTMLFrameElement::attach):
        * html/HTMLFrameElement.h:
        (WebCore::HTMLFrameElement::viewSourceMode):
        * html/HTMLTokenizer.cpp:
        (WebCore::HTMLTokenizer::HTMLTokenizer):
        (WebCore::HTMLTokenizer::scriptHandler):
        (WebCore::HTMLTokenizer::scriptExecution):
        (WebCore::HTMLTokenizer::parseTag):
        (WebCore::HTMLTokenizer::continueProcessing):
        (WebCore::HTMLTokenizer::write):
        (WebCore::HTMLTokenizer::timerFired):
        (WebCore::HTMLTokenizer::end):
        (WebCore::HTMLTokenizer::processToken):
        (WebCore::HTMLTokenizer::notifyFinished):
        * html/HTMLTokenizer.h:
        * html/HTMLViewSourceDocument.cpp: Added.
        (WebCore::HTMLViewSourceDocument::HTMLViewSourceDocument):
        (WebCore::HTMLViewSourceDocument::createTokenizer):
        (WebCore::HTMLViewSourceDocument::addViewSourceToken):
        (WebCore::HTMLViewSourceDocument::addViewSourceAttribute):
        (WebCore::HTMLViewSourceDocument::addSpanWithClassName):
        * html/HTMLViewSourceDocument.h: Added.
        * page/Frame.cpp:
        (WebCore::Frame::begin):
        (WebCore::Frame::inViewSourceMode):
        (WebCore::Frame::setInViewSourceMode):
        * page/Frame.h:
        * page/FramePrivate.h:
        (WebCore::FramePrivate::FramePrivate):
        * rendering/RenderPartObject.cpp:
        (WebCore::RenderPartObject::updateWidget):

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

21 files changed:
WebCore/ChangeLog
WebCore/DerivedSources.make
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/bridge/mac/WebCoreFrameBridge.h
WebCore/bridge/mac/WebCoreFrameBridge.mm
WebCore/css/cssstyleselector.cpp
WebCore/css/cssstyleselector.h
WebCore/css/view-source.css [new file with mode: 0644]
WebCore/dom/Document.cpp
WebCore/dom/xml_tokenizer.h
WebCore/html/HTMLAttributeNames.in
WebCore/html/HTMLFrameElement.cpp
WebCore/html/HTMLFrameElement.h
WebCore/html/HTMLTokenizer.cpp
WebCore/html/HTMLTokenizer.h
WebCore/html/HTMLViewSourceDocument.cpp [new file with mode: 0644]
WebCore/html/HTMLViewSourceDocument.h [new file with mode: 0644]
WebCore/page/Frame.cpp
WebCore/page/Frame.h
WebCore/page/FramePrivate.h
WebCore/rendering/RenderPartObject.cpp

index 7fce0d3..5382f06 100644 (file)
@@ -1,3 +1,64 @@
+2006-06-26  David Hyatt  <hyatt@apple.com>
+
+        Fix for 9538, support syntax highlighted HTML source.  Lots of loose
+        ends still (script/style/comments/doctype/entities/accurate whitespace).
+
+        Reviewed by darin
+
+        * DerivedSources.make:
+        * WebCore.xcodeproj/project.pbxproj:
+        * bridge/mac/WebCoreFrameBridge.h:
+        * bridge/mac/WebCoreFrameBridge.mm:
+        (-[WebCoreFrameBridge setInViewSourceMode:]):
+        (-[WebCoreFrameBridge inViewSourceMode]):
+        * css/cssstyleselector.cpp:
+        (WebCore::CSSStyleSelector::loadDefaultStyle):
+        (WebCore::CSSStyleSelector::matchUARules):
+        * css/cssstyleselector.h:
+        * css/view-source.css: Added.
+        * dom/Document.cpp:
+        (WebCore::Document::implicitClose):
+        * dom/xml_tokenizer.h:
+        (WebCore::Tokenizer::Tokenizer):
+        (WebCore::Tokenizer::~Tokenizer):
+        (WebCore::Tokenizer::inViewSourceMode):
+        (WebCore::Tokenizer::setInViewSourceMode):
+        * html/HTMLAttributeNames.in:
+        * html/HTMLFrameElement.cpp:
+        (WebCore::HTMLFrameElement::init):
+        (WebCore::HTMLFrameElement::parseMappedAttribute):
+        (WebCore::HTMLFrameElement::attach):
+        * html/HTMLFrameElement.h:
+        (WebCore::HTMLFrameElement::viewSourceMode):
+        * html/HTMLTokenizer.cpp:
+        (WebCore::HTMLTokenizer::HTMLTokenizer):
+        (WebCore::HTMLTokenizer::scriptHandler):
+        (WebCore::HTMLTokenizer::scriptExecution):
+        (WebCore::HTMLTokenizer::parseTag):
+        (WebCore::HTMLTokenizer::continueProcessing):
+        (WebCore::HTMLTokenizer::write):
+        (WebCore::HTMLTokenizer::timerFired):
+        (WebCore::HTMLTokenizer::end):
+        (WebCore::HTMLTokenizer::processToken):
+        (WebCore::HTMLTokenizer::notifyFinished):
+        * html/HTMLTokenizer.h:
+        * html/HTMLViewSourceDocument.cpp: Added.
+        (WebCore::HTMLViewSourceDocument::HTMLViewSourceDocument):
+        (WebCore::HTMLViewSourceDocument::createTokenizer):
+        (WebCore::HTMLViewSourceDocument::addViewSourceToken):
+        (WebCore::HTMLViewSourceDocument::addViewSourceAttribute):
+        (WebCore::HTMLViewSourceDocument::addSpanWithClassName):
+        * html/HTMLViewSourceDocument.h: Added.
+        * page/Frame.cpp:
+        (WebCore::Frame::begin):
+        (WebCore::Frame::inViewSourceMode):
+        (WebCore::Frame::setInViewSourceMode):
+        * page/Frame.h:
+        * page/FramePrivate.h:
+        (WebCore::FramePrivate::FramePrivate):
+        * rendering/RenderPartObject.cpp:
+        (WebCore::RenderPartObject::updateWidget):
+
 2006-06-26  Anders Carlsson  <acarlsson@apple.com>
 
         Reviewed by Darin.
         (WebCore::xmlDocPtrFromNode):
         Pass DocLoader to xmlDocPtrForString
         
+>>>>>>> .r15049
 2006-06-21  David Hyatt  <hyatt@apple.com>
 
         Back out -webkit-overlay and just rename it back to overlay.
index fb65212..adb30db 100644 (file)
@@ -210,7 +210,7 @@ XPathGrammar.cpp : xpath/impl/XPathGrammar.y $(PROJECT_FILE)
 
 # user agent style sheets
 
-USER_AGENT_STYLE_SHEETS = $(WebCore)/css/html4.css $(WebCore)/css/quirks.css $(WebCore)/css/svg.css 
+USER_AGENT_STYLE_SHEETS = $(WebCore)/css/html4.css $(WebCore)/css/quirks.css $(WebCore)/css/view-source.css $(WebCore)/css/svg.css 
 UserAgentStyleSheets.h : css/make-css-file-arrays.pl $(USER_AGENT_STYLE_SHEETS)
        perl $< $@ UserAgentStyleSheetsData.cpp $(USER_AGENT_STYLE_SHEETS)
 
index 66cb0fa..b017c64 100644 (file)
                BC1A37C0097C715F0019F3D8 /* DOMViews.h in Headers */ = {isa = PBXBuildFile; fileRef = BC1A37AA097C715F0019F3D8 /* DOMViews.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BC1A37C1097C715F0019F3D8 /* DOMViews.mm in Sources */ = {isa = PBXBuildFile; fileRef = BC1A37AB097C715F0019F3D8 /* DOMViews.mm */; };
                BC1A37C2097C715F0019F3D8 /* DOMViewsInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = BC1A37AC097C715F0019F3D8 /* DOMViewsInternal.h */; };
+               BC5EC1770A507E3E006007F5 /* view-source.css in Resources */ = {isa = PBXBuildFile; fileRef = BC5EC1760A507E3E006007F5 /* view-source.css */; };
                BC6B7BAF0993603C0052867B /* Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC6B7BAE0993603C0052867B /* Image.cpp */; };
                BC6B7ECF0998AC7F0052867B /* ImageSource.h in Headers */ = {isa = PBXBuildFile; fileRef = BC6B7ECE0998AC7F0052867B /* ImageSource.h */; };
                BC6D6DD209AF906600F59759 /* Font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC6D6DD009AF906600F59759 /* Font.cpp */; };
                BCC8CFCC0986CD2400140BF2 /* Color.h in Headers */ = {isa = PBXBuildFile; fileRef = BCC8CFC90986CD2400140BF2 /* Color.h */; };
                BCC8D1730988301200140BF2 /* Pen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCC8D1710988301200140BF2 /* Pen.cpp */; };
                BCC8D1740988301200140BF2 /* Pen.h in Headers */ = {isa = PBXBuildFile; fileRef = BCC8D1720988301200140BF2 /* Pen.h */; };
+               BCCD74DC0A4C8D35005FDA6D /* HTMLViewSourceDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = BCCD74DB0A4C8D35005FDA6D /* HTMLViewSourceDocument.h */; };
+               BCCD74E50A4C8DDF005FDA6D /* HTMLViewSourceDocument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCCD74E40A4C8DDF005FDA6D /* HTMLViewSourceDocument.cpp */; };
                BCD75ABC0989A446003E28DF /* Image.h in Headers */ = {isa = PBXBuildFile; fileRef = BCD75ABB0989A446003E28DF /* Image.h */; };
                BCEA478F097CAAC80094C9E4 /* CSSComputedStyleDeclaration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCEA477C097CAAC80094C9E4 /* CSSComputedStyleDeclaration.cpp */; };
                BCEA4790097CAAC80094C9E4 /* CSSComputedStyleDeclaration.h in Headers */ = {isa = PBXBuildFile; fileRef = BCEA477D097CAAC80094C9E4 /* CSSComputedStyleDeclaration.h */; };
                BC1A37AB097C715F0019F3D8 /* DOMViews.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMViews.mm; sourceTree = "<group>"; };
                BC1A37AC097C715F0019F3D8 /* DOMViewsInternal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DOMViewsInternal.h; sourceTree = "<group>"; };
                BC3B364705C9D5E200E42902 /* AtomicStringList.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = AtomicStringList.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
+               BC5EC1760A507E3E006007F5 /* view-source.css */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "view-source.css"; sourceTree = "<group>"; };
                BC6B7BAE0993603C0052867B /* Image.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Image.cpp; sourceTree = "<group>"; };
                BC6B7ECE0998AC7F0052867B /* ImageSource.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ImageSource.h; sourceTree = "<group>"; };
                BC6D6DD009AF906600F59759 /* Font.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Font.cpp; sourceTree = "<group>"; };
                BCC8CFCA0986CD2400140BF2 /* ColorData.gperf */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = ColorData.gperf; sourceTree = "<group>"; };
                BCC8D1710988301200140BF2 /* Pen.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Pen.cpp; sourceTree = "<group>"; };
                BCC8D1720988301200140BF2 /* Pen.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Pen.h; sourceTree = "<group>"; };
+               BCCD74DB0A4C8D35005FDA6D /* HTMLViewSourceDocument.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = HTMLViewSourceDocument.h; sourceTree = "<group>"; };
+               BCCD74E40A4C8DDF005FDA6D /* HTMLViewSourceDocument.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLViewSourceDocument.cpp; sourceTree = "<group>"; };
                BCD75ABB0989A446003E28DF /* Image.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Image.h; sourceTree = "<group>"; };
                BCEA477C097CAAC80094C9E4 /* CSSComputedStyleDeclaration.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSSComputedStyleDeclaration.cpp; sourceTree = "<group>"; };
                BCEA477D097CAAC80094C9E4 /* CSSComputedStyleDeclaration.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSSComputedStyleDeclaration.h; sourceTree = "<group>"; };
                93EEC1EC09C2877700C515D1 /* html */ = {
                        isa = PBXGroup;
                        children = (
+                               BCCD74DB0A4C8D35005FDA6D /* HTMLViewSourceDocument.h */,
                                93EEC1F009C2877700C515D1 /* CanvasGradient.cpp */,
                                93EEC1F109C2877700C515D1 /* CanvasGradient.h */,
                                930CAB8809C49EFA00229C04 /* CanvasGradient.idl */,
                                A8EA79E70A1916DF00A8EF5F /* HTMLUListElement.cpp */,
                                A8EA79E60A1916DF00A8EF5F /* HTMLUListElement.h */,
                                1A85B1D50A1B236C00D8C87C /* HTMLUListElement.idl */,
+                               BCCD74E40A4C8DDF005FDA6D /* HTMLViewSourceDocument.cpp */,
                        );
                        path = html;
                        sourceTree = "<group>";
                                A8EA80020A19516E00A8EF5F /* StyleSheetList.h */,
                                93CA4CA209DF93FA00DF8677 /* svg.css */,
                                93CA4CA309DF93FA00DF8677 /* tokenizer.flex */,
+                               BC5EC1760A507E3E006007F5 /* view-source.css */,
                        );
                        path = css;
                        sourceTree = "<group>";
                                85031B4F0A44EFC700F992E0 /* UIEventWithKeyState.h in Headers */,
                                85031B510A44EFC700F992E0 /* WheelEvent.h in Headers */,
                                ABE7B5240A489F830031881C /* DeprecatedRenderSelect.h in Headers */,
+                               BCCD74DC0A4C8D35005FDA6D /* HTMLViewSourceDocument.h in Headers */,
                                1A8086CC0A4D097600DFB6A7 /* DOMCSSInternal.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                                A7B97B850979C3A1000E8EB1 /* WKTableTransferFilter.cikernel in Resources */,
                                A7638A92099592C30007E14F /* WKDisplacementMapFilter.cikernel in Resources */,
                                AB4261D80A2F6C9700BDD17D /* missingImage.tiff in Resources */,
+                               BC5EC1770A507E3E006007F5 /* view-source.css in Resources */,
                                1CD4418D0A4CE76F00A007AB /* eastWestResizeCursor.tiff in Resources */,
                                1CD4418E0A4CE76F00A007AB /* northEastSouthWestResizeCursor.tiff in Resources */,
                                1CD4418F0A4CE76F00A007AB /* northSouthResizeCursor.tiff in Resources */,
                                85031B500A44EFC700F992E0 /* WheelEvent.cpp in Sources */,
                                ABE7B5230A489F830031881C /* DeprecatedRenderSelect.cpp in Sources */,
                                51F11E150A48C2920034A24E /* SQLTransaction.cpp in Sources */,
+                               BCCD74E50A4C8DDF005FDA6D /* HTMLViewSourceDocument.cpp in Sources */,
                                E1052C320A4D70010072D99B /* DOMEventsNonstandard.mm in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
index 9f6ac2f..68fd5a4 100644 (file)
@@ -493,6 +493,10 @@ typedef enum {
 - (BOOL)canProvideDocumentSource;
 - (BOOL)canSaveAsWebArchive;
 - (BOOL)containsPlugins;
+
+- (void)setInViewSourceMode:(BOOL)flag;
+- (BOOL)inViewSourceMode;
+
 @end
 
 // The WebCoreFrameBridge protocol contains methods for use by the WebCore side of the bridge.
index d42233f..36dde1f 100644 (file)
@@ -2584,6 +2584,16 @@ static NSCharacterSet *_getPostSmartSet(void)
     return m_frame->containsPlugins();
 }
 
+- (void)setInViewSourceMode:(BOOL)flag
+{
+    m_frame->setInViewSourceMode(flag);
+}
+
+- (BOOL)inViewSourceMode
+{
+    return m_frame->inViewSourceMode();
+}
+
 @end
 
 @implementation WebCoreFrameBridge (WebCoreBridgeInternal)
index 073bac9..7533004 100644 (file)
@@ -194,12 +194,16 @@ public:
     unsigned m_ruleCount;
 };
 
-CSSRuleSet *CSSStyleSelector::defaultStyle = 0;
-CSSRuleSet *CSSStyleSelector::defaultQuirksStyle = 0;
-CSSRuleSet *CSSStyleSelector::defaultPrintStyle = 0;
-CSSStyleSheet *CSSStyleSelector::defaultSheet = 0;
+CSSRuleSet* CSSStyleSelector::defaultStyle = 0;
+CSSRuleSet* CSSStyleSelector::defaultQuirksStyle = 0;
+CSSRuleSet* CSSStyleSelector::defaultPrintStyle = 0;
+CSSRuleSet* CSSStyleSelector::defaultViewSourceStyle = 0;
+
+CSSStyleSheet* CSSStyleSelector::defaultSheet = 0;
 RenderStyle* CSSStyleSelector::styleNotYetAvailable = 0;
-CSSStyleSheet *CSSStyleSelector::quirksSheet = 0;
+CSSStyleSheet* CSSStyleSelector::quirksSheet = 0;
+CSSStyleSheet* CSSStyleSelector::viewSourceSheet = 0;
+
 #if SVG_SUPPORT
 CSSStyleSheet *CSSStyleSelector::svgSheet = 0;
 #endif
@@ -348,6 +352,7 @@ void CSSStyleSelector::loadDefaultStyle()
     defaultStyle = new CSSRuleSet;
     defaultPrintStyle = new CSSRuleSet;
     defaultQuirksStyle = new CSSRuleSet;
+    defaultViewSourceStyle = new CSSRuleSet;
 
     MediaQueryEvaluator screenEval("screen");
     MediaQueryEvaluator printEval("print");
@@ -367,6 +372,10 @@ void CSSStyleSelector::loadDefaultStyle()
     // Quirks-mode rules.
     quirksSheet = parseUASheet(quirksUserAgentStyleSheet);
     defaultQuirksStyle->addRulesFromSheet(quirksSheet, &screenEval);
+    
+    // View source rules.
+    viewSourceSheet = parseUASheet(sourceUserAgentStyleSheet);
+    defaultViewSourceStyle->addRulesFromSheet(viewSourceSheet, &screenEval);
 }
 
 void CSSStyleSelector::matchRules(CSSRuleSet* rules, int& firstRuleIndex, int& lastRuleIndex)
@@ -747,6 +756,10 @@ void CSSStyleSelector::matchUARules(int& firstUARule, int& lastUARule)
     // 3. If our medium is print, then we match rules from the print sheet.
     if (m_medium->mediaTypeMatch("print"))
         matchRules(defaultPrintStyle, firstUARule, lastUARule);
+        
+    // 4. If we're in view source mode, then we match rules from the view source style sheet.
+    if (view && view->frame() && view->frame()->inViewSourceMode())
+        matchRules(defaultViewSourceStyle, firstUARule, lastUARule);
 }
 
 // If resolveForRootDefault is true, style based on user agent style sheet only. This is used in media queries, where
index f72959d..17b9146 100644 (file)
@@ -158,14 +158,18 @@ class StyledElement;
 
         void applyDeclarations(bool firstPass, bool important, int startIndex, int endIndex);
         
-        static CSSStyleSheet *defaultSheet;
-        static CSSStyleSheet *quirksSheet;
+        static CSSStyleSheet* defaultSheet;
+        static CSSStyleSheet* quirksSheet;
+        static CSSStyleSheet* viewSourceSheet;
 #if SVG_SUPPORT
-        static CSSStyleSheet *svgSheet;
+        static CSSStyleSheetsvgSheet;
 #endif
+
         static CSSRuleSet* defaultStyle;
         static CSSRuleSet* defaultQuirksStyle;
         static CSSRuleSet* defaultPrintStyle;
+        static CSSRuleSet* defaultViewSourceStyle;
+
         CSSRuleSet* m_authorStyle;
         CSSRuleSet* m_userStyle;
         CSSStyleSheet* m_userSheet;
diff --git a/WebCore/css/view-source.css b/WebCore/css/view-source.css
new file mode 100644 (file)
index 0000000..a92fc0b
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2006 Apple Computer, 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,
+ * 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. 
+ */
+
+.webkit-html-tag {
+    color: rgb(136, 18, 128)
+}
+
+.webkit-html-attribute-name {
+    color: rgb(153, 69, 0)
+}
+
+.webkit-html-attribute-value {
+    color: rgb(26, 26, 166)
+}
+
+.webkit-html-comment {
+    color: rgb(35, 110, 37);
+}
+
+.webkit-html-doctype {
+    color: rgb(192, 192, 192);
+}
+
+.webkit-html-entity {
+    rgb(136, 18, 128);
+}
index 0538047..ab8f6ca 100644 (file)
@@ -1231,7 +1231,7 @@ void Document::implicitClose()
 #endif
 
 #if SVG_SUPPORT
-    // FIXME: Officially, time 0 is when the outermost <svg> recieves its
+    // FIXME: Officially, time 0 is when the outermost <svg> receives its
     // SVGLoad event, but we don't implement those yet.  This is close enough
     // for now.  In some cases we should have fired earlier.
     if (svgExtensions())
index 80283c7..2a1b13d 100644 (file)
@@ -39,8 +39,12 @@ class SegmentedString;
 class Tokenizer
 {
 public:
-    Tokenizer() : m_parserStopped(false) { }
-    virtual ~Tokenizer() { }
+    Tokenizer(bool viewSourceMode = false) 
+    : m_parserStopped(false)
+    , m_inViewSourceMode(viewSourceMode)
+    {}
+    
+    virtual ~Tokenizer() {}
 
     // Script output must be prepended, while new data
     // received during executing a script must be appended, hence the
@@ -56,11 +60,16 @@ public:
     virtual bool wantsRawData() const { return false; }
     virtual bool writeRawData(const char* data, int len) { return false; }
     
+    bool inViewSourceMode() const { return m_inViewSourceMode; }
+    void setInViewSourceMode(bool mode) { m_inViewSourceMode = mode; }
+
 protected:
     // The tokenizer has buffers, so parsing may continue even after
     // it stops receiving data. We use m_parserStopped to stop the tokenizer
     // even when it has buffered data.
     bool m_parserStopped;
+    
+    bool m_inViewSourceMode;
 };
 
 Tokenizer* newXMLTokenizer(Document*, FrameView* = 0);
index 43664d2..7db17c7 100644 (file)
@@ -171,6 +171,7 @@ valign
 value
 valuetype
 version
+viewsource
 vlink
 vspace
 width
index 5cc2894..6c78399 100644 (file)
@@ -61,6 +61,7 @@ void HTMLFrameElement::init()
     m_marginHeight = -1;
     m_scrolling = ScrollBarAuto;
     m_noResize = false;
+    m_viewSource = false;
 }
 
 HTMLFrameElement::~HTMLFrameElement()
@@ -157,6 +158,10 @@ void HTMLFrameElement::parseMappedAttribute(MappedAttribute *attr)
         else if (equalIgnoringCase(attr->value(), "no"))
             m_scrolling = ScrollBarAlwaysOff;
         // FIXME: If we are already attached, this has no effect.
+    } else if (attr->name() == viewsourceAttr) {
+        m_viewSource = !attr->isNull();
+        if (contentFrame())
+            contentFrame()->setInViewSourceMode(viewSourceMode());
     } else if (attr->name() == onloadAttr) {
         setHTMLEventListener(loadEvent, attr);
     } else if (attr->name() == onbeforeunloadAttr) {
@@ -216,6 +221,9 @@ void HTMLFrameElement::attach()
 
     // load the frame contents
     frame->requestFrame(static_cast<RenderFrame*>(renderer()), relativeURL, m_name);
+    
+    if (contentFrame())
+        contentFrame()->setInViewSourceMode(viewSourceMode());
 }
 
 void HTMLFrameElement::close()
index 143e71a..3b59993 100644 (file)
@@ -98,6 +98,8 @@ public:
     int frameWidth() const;
     int frameHeight() const;
 
+    bool viewSourceMode() const { return m_viewSource; }
+
 protected:
     bool isURLAllowed(const AtomicString&) const;
     virtual void openURL();
@@ -112,6 +114,7 @@ protected:
     bool m_frameBorder : 1;
     bool m_frameBorderSet : 1;
     bool m_noResize : 1;
+    bool m_viewSource : 1;
 };
 
 } //namespace
index 72b1988..49e422f 100644 (file)
@@ -34,6 +34,7 @@
 #include "DocumentFragment.h"
 #include "EventNames.h"
 #include "Frame.h"
+#include "HTMLViewSourceDocument.h"
 #include "HTMLElement.h"
 #include "SystemTime.h"
 #include "csshelper.h"
@@ -119,8 +120,9 @@ inline void Token::addAttribute(Document* doc, const AtomicString& attrName, con
 
 // ----------------------------------------------------------------------------
 
-HTMLTokenizer::HTMLTokenizer(Document* doc)
-    : buffer(0)
+HTMLTokenizer::HTMLTokenizer(HTMLDocument* doc)
+    : Tokenizer()
+    , buffer(0)
     , scriptCode(0)
     , scriptCodeSize(0)
     , scriptCodeMaxSize(0)
@@ -128,10 +130,27 @@ HTMLTokenizer::HTMLTokenizer(Document* doc)
     , m_executingScript(0)
     , m_timer(this, &HTMLTokenizer::timerFired)
     , m_doc(doc)
+    , parser(new HTMLParser(doc))
+    , inWrite(false)
+    , m_fragment(false)
+{
+    begin();
+}
+
+HTMLTokenizer::HTMLTokenizer(HTMLViewSourceDocument* doc)
+    : Tokenizer(true)
+    , buffer(0)
+    , scriptCode(0)
+    , scriptCodeSize(0)
+    , scriptCodeMaxSize(0)
+    , scriptCodeResync(0)
+    , m_executingScript(0)
+    , m_timer(this, &HTMLTokenizer::timerFired)
+    , m_doc(doc)
+    , parser(0)
     , inWrite(false)
     , m_fragment(false)
 {
-    parser = new HTMLParser(doc);
     begin();
 }
 
@@ -332,18 +351,18 @@ HTMLTokenizer::State HTMLTokenizer::scriptHandler(State state)
 
     // (Bugzilla 3837) Scripts following a frameset element should not execute or, 
     // in the case of extern scripts, even load.
-    bool followingFrameset = (parser->doc()->body() && parser->doc()->body()->hasTagName(framesetTag));
+    bool followingFrameset = (m_doc->body() && m_doc->body()->hasTagName(framesetTag));
   
     CachedScript* cs = 0;
     // don't load external scripts for standalone documents (for now)
-    if (!scriptSrc.isEmpty() && parser->doc()->frame()) {
+    if (!scriptSrc.isEmpty() && m_doc->frame()) {
         // forget what we just got; load from src url instead
         if (!parser->skipMode() && !followingFrameset) {
 #if INSTRUMENT_LAYOUT_SCHEDULING
-            if (!parser->doc()->ownerElement())
-                printf("Requesting script at time %d\n", parser->doc()->elapsedTime());
+            if (!m_doc->ownerElement())
+                printf("Requesting script at time %d\n", m_doc->elapsedTime());
 #endif
-            if ( (cs = parser->doc()->docLoader()->requestScript(scriptSrc, scriptSrcCharset) ))
+            if ( (cs = m_doc->docLoader()->requestScript(scriptSrc, scriptSrcCharset) ))
                 pendingScripts.enqueue(cs);
             else
                 scriptNode = 0;
@@ -446,8 +465,8 @@ HTMLTokenizer::State HTMLTokenizer::scriptExecution(const DeprecatedString& str,
     currentPrependingSrc = &prependingSrc;
 
 #if INSTRUMENT_LAYOUT_SCHEDULING
-    if (!parser->doc()->ownerElement())
-        printf("beginning script execution at %d\n", parser->doc()->elapsedTime());
+    if (!m_doc->ownerElement())
+        printf("beginning script execution at %d\n", m_doc->elapsedTime());
 #endif
 
     m_state = state;
@@ -457,8 +476,8 @@ HTMLTokenizer::State HTMLTokenizer::scriptExecution(const DeprecatedString& str,
     state.setAllowYield(true);
 
 #if INSTRUMENT_LAYOUT_SCHEDULING
-    if (!parser->doc()->ownerElement())
-        printf("ending script execution at %d\n", parser->doc()->elapsedTime());
+    if (!m_doc->ownerElement())
+        printf("ending script execution at %d\n", m_doc->elapsedTime());
 #endif
     
     m_executingScript--;
@@ -788,7 +807,7 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
                         // Fix bug 34302 at kde.bugs.org.  Go ahead and treat
                         // <!--> as a valid comment, since both mozilla and IE on windows
                         // can handle this case.  Only do this in quirks mode. -dwh
-                        if (!src.isEmpty() && *src == '>' && parser->doc()->inCompatMode()) {
+                        if (!src.isEmpty() && *src == '>' && m_doc->inCompatMode()) {
                           state.setInComment(false);
                           ++src;
                           if (!src.isEmpty())
@@ -820,7 +839,7 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
                 }
                 
                 // tolower() shows up on profiles. This is faster!
-                if (curchar >= 'A' && curchar <= 'Z')
+                if (curchar >= 'A' && curchar <= 'Z' && !inViewSourceMode())
                     cBuffer[cBufferPos++] = curchar + ('a' - 'A');
                 else
                     cBuffer[cBufferPos++] = curchar;
@@ -845,7 +864,7 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
                     beginTag = true;
 
                 // Ignore the / in fake xml tags like <br/>.  We trim off the "/" so that we'll get "br" as the tag name and not "br/".
-                if (len > 1 && ptr[len-1] == '/')
+                if (len > 1 && ptr[len-1] == '/' && !inViewSourceMode())
                     ptr[--len] = '\0';
 
                 // Now that we've shaved off any invalid / that might have followed the name), make the tag.
@@ -935,7 +954,7 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
                         ++src;
                     }
                     else {
-                        currToken.addAttribute(parser->doc(), attrName, emptyAtom);
+                        currToken.addAttribute(m_doc, attrName, emptyAtom);
                         dest = buffer;
                         state.setTagState(SearchAttribute);
                     }
@@ -980,7 +999,7 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
                         dest--; // remove trailing newlines
                     AtomicString v(buffer+1, dest-buffer-1);
                     attrName = v; // Just make the name/value match. (FIXME: Is this some WinIE quirk?)
-                    currToken.addAttribute(parser->doc(), attrName, v);
+                    currToken.addAttribute(m_doc, attrName, v);
                     state.setTagState(SearchAttribute);
                     dest = buffer;
                     tquote = NoQuote;
@@ -1004,7 +1023,7 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
                         AtomicString v(buffer+1, dest-buffer-1);
                         if (attrName.isEmpty())
                             attrName = v; // Make the name match the value. (FIXME: Is this a WinIE quirk?)
-                        currToken.addAttribute(parser->doc(), attrName, v);
+                        currToken.addAttribute(m_doc, attrName, v);
 
                         dest = buffer;
                         state.setTagState(SearchAttribute);
@@ -1037,7 +1056,7 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
                     if ( curchar <= ' ' || curchar == '>' )
                     {
                         AtomicString v(buffer+1, dest-buffer-1);
-                        currToken.addAttribute(parser->doc(), attrName, v);
+                        currToken.addAttribute(m_doc, attrName, v);
                         dest = buffer;
                         state.setTagState(SearchAttribute);
                         break;
@@ -1091,16 +1110,16 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
                 scriptSrc = DeprecatedString::null;
                 scriptSrcCharset = DeprecatedString::null;
                 if ( currToken.attrs && /* potentially have a ATTR_SRC ? */
-                     parser->doc()->frame() &&
-                     parser->doc()->frame()->jScriptEnabled() && /* jscript allowed at all? */
+                     m_doc->frame() &&
+                     m_doc->frame()->jScriptEnabled() && /* jscript allowed at all? */
                      !m_fragment /* are we a regular tokenizer or just for innerHTML ? */
                     ) {
                     if ((a = currToken.attrs->getAttributeItem(srcAttr)))
-                        scriptSrc = parser->doc()->completeURL(parseURL(a->value()).deprecatedString());
+                        scriptSrc = m_doc->completeURL(parseURL(a->value()).deprecatedString());
                     if ((a = currToken.attrs->getAttributeItem(charsetAttr)))
                         scriptSrcCharset = a->value().deprecatedString().stripWhiteSpace();
                     if ( scriptSrcCharset.isEmpty() )
-                        scriptSrcCharset = parser->doc()->frame()->encoding();
+                        scriptSrcCharset = m_doc->frame()->encoding();
                     /* Check type before language, since language is deprecated */
                     if ((a = currToken.attrs->getAttributeItem(typeAttr)) != 0 && !a->value().isEmpty())
                         foundTypeAttribute = true;
@@ -1159,7 +1178,7 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
 
             RefPtr<Node> n = processToken();
 
-            if (tagName == preTag || tagName == listingTag) {
+            if ((tagName == preTag || tagName == listingTag) && !inViewSourceMode()) {
                 if (beginTag)
                     state.setDiscardLF(true); // Discard the first LF after we open a pre.
             } else if (tagName == scriptTag) {
@@ -1243,8 +1262,8 @@ inline bool HTMLTokenizer::continueProcessing(int& processedCount, double startT
             /* FIXME: We'd like to yield aggressively to give stylesheets the opportunity to
                load, but this hurts overall performance on slower machines.  For now turn this
                off.
-            || (!parser->doc()->haveStylesheetsLoaded() && 
-                (parser->doc()->documentElement()->id() != ID_HTML || parser->doc()->body()))) {*/
+            || (!m_doc->haveStylesheetsLoaded() && 
+                (m_doc->documentElement()->id() != ID_HTML || m_doc->body()))) {*/
             // Schedule the timer to keep processing as soon as possible.
             m_timer.startOneShot(0);
 #if INSTRUMENT_LAYOUT_SCHEDULING
@@ -1294,14 +1313,14 @@ bool HTMLTokenizer::write(const SegmentedString &str, bool appendData)
     inWrite = true;
     
 #if INSTRUMENT_LAYOUT_SCHEDULING
-    if (!parser->doc()->ownerElement())
-        printf("Beginning write at time %d\n", parser->doc()->elapsedTime());
+    if (!m_doc->ownerElement())
+        printf("Beginning write at time %d\n", m_doc->elapsedTime());
 #endif
     
     int processedCount = 0;
     double startTime = currentTime();
 
-    Frame *frame = parser->doc()->frame();
+    Frame *frame = m_doc->frame();
 
     State state = m_state;
 
@@ -1412,8 +1431,8 @@ bool HTMLTokenizer::write(const SegmentedString &str, bool appendData)
     }
     
 #if INSTRUMENT_LAYOUT_SCHEDULING
-    if (!parser->doc()->ownerElement())
-        printf("Ending write at time %d\n", parser->doc()->elapsedTime());
+    if (!m_doc->ownerElement())
+        printf("Ending write at time %d\n", m_doc->elapsedTime());
 #endif
     
     inWrite = wasInWrite;
@@ -1446,11 +1465,11 @@ bool HTMLTokenizer::processingData() const
 void HTMLTokenizer::timerFired(Timer<HTMLTokenizer>*)
 {
 #if INSTRUMENT_LAYOUT_SCHEDULING
-    if (!parser->doc()->ownerElement())
-        printf("Beginning timer write at time %d\n", parser->doc()->elapsedTime());
+    if (!m_doc->ownerElement())
+        printf("Beginning timer write at time %d\n", m_doc->elapsedTime());
 #endif
 
-    if (parser->doc()->view() && parser->doc()->view()->layoutPending() && !parser->doc()->minimumLayoutDelay()) {
+    if (m_doc->view() && m_doc->view()->layoutPending() && !m_doc->minimumLayoutDelay()) {
         // Restart the timer and let layout win.  This is basically a way of ensuring that the layout
         // timer has higher priority than our timer.
         m_timer.startOneShot(0);
@@ -1485,7 +1504,10 @@ void HTMLTokenizer::end()
         buffer = 0;
     }
 
-    parser->finished();
+    if (!inViewSourceMode())
+        parser->finished();
+    else
+        m_doc->finishedParsing();
 }
 
 void HTMLTokenizer::finish()
@@ -1576,10 +1598,13 @@ PassRefPtr<Node> HTMLTokenizer::processToken()
 
     RefPtr<Node> n;
     
-    if (!m_parserStopped)
-        // pass the token over to the parser, the parser DOES NOT delete the token
-        n = parser->parseToken(&currToken);
-    
+    if (!m_parserStopped) {
+        if (inViewSourceMode())
+            static_cast<HTMLViewSourceDocument*>(m_doc)->addViewSourceToken(&currToken);
+        else
+            // pass the token over to the parser, the parser DOES NOT delete the token
+            n = parser->parseToken(&currToken);
+    }
     currToken.reset();
     if (jsProxy)
         jsProxy->setEventHandlerLineno(0);
@@ -1614,8 +1639,8 @@ void HTMLTokenizer::enlargeScriptBuffer(int len)
 void HTMLTokenizer::notifyFinished(CachedObject*)
 {
 #if INSTRUMENT_LAYOUT_SCHEDULING
-    if (!parser->doc()->ownerElement())
-        printf("script loaded at %d\n", parser->doc()->elapsedTime());
+    if (!m_doc->ownerElement())
+        printf("script loaded at %d\n", m_doc->elapsedTime());
 #endif
 
     ASSERT(!pendingScripts.isEmpty());
@@ -1642,8 +1667,8 @@ void HTMLTokenizer::notifyFinished(CachedObject*)
         scriptNode = 0;
 
 #if INSTRUMENT_LAYOUT_SCHEDULING
-        if (!parser->doc()->ownerElement())
-            printf("external script beginning execution at %d\n", parser->doc()->elapsedTime());
+        if (!m_doc->ownerElement())
+            printf("external script beginning execution at %d\n", m_doc->elapsedTime());
 #endif
 
         if (errorOccurred)
@@ -1659,8 +1684,8 @@ void HTMLTokenizer::notifyFinished(CachedObject*)
         if (finished) {
             m_state.setLoadingExtScript(false);
 #if INSTRUMENT_LAYOUT_SCHEDULING
-            if (!parser->doc()->ownerElement())
-                printf("external script finished execution at %d\n", parser->doc()->elapsedTime());
+            if (!m_doc->ownerElement())
+                printf("external script finished execution at %d\n", m_doc->elapsedTime());
 #endif
         }
 
index 79bdd40..4f1214e 100644 (file)
@@ -38,6 +38,8 @@ namespace WebCore {
 class CachedScript;
 class DocumentFragment;
 class Document;
+class HTMLDocument;
+class HTMLViewSourceDocument;
 class FrameView;
 class HTMLParser;
 class Node;
@@ -79,7 +81,8 @@ public:
 class HTMLTokenizer : public Tokenizer, public CachedObjectClient
 {
 public:
-    HTMLTokenizer(Document*);
+    HTMLTokenizer(HTMLDocument*);
+    HTMLTokenizer(HTMLViewSourceDocument*);
     HTMLTokenizer(DocumentFragment*);
     virtual ~HTMLTokenizer();
 
diff --git a/WebCore/html/HTMLViewSourceDocument.cpp b/WebCore/html/HTMLViewSourceDocument.cpp
new file mode 100644 (file)
index 0000000..ba282e7
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2006 Apple Computer, 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,
+ * 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 "HTMLViewSourceDocument.h"
+#include "HTMLTokenizer.h"
+#include "HTMLHtmlElement.h"
+#include "HTMLBodyElement.h"
+#include "HTMLPreElement.h"
+#include "Text.h"
+#include "HTMLNames.h"
+
+namespace WebCore
+{
+
+using namespace HTMLNames;
+
+HTMLViewSourceDocument::HTMLViewSourceDocument(DOMImplementation* implementation, FrameView* v)
+    : HTMLDocument(implementation, v), m_current(0)
+{
+}
+
+Tokenizer* HTMLViewSourceDocument::createTokenizer()
+{
+    return new HTMLTokenizer(this);
+}
+
+void HTMLViewSourceDocument::addViewSourceToken(Token* token)
+{
+    if (!m_current) {
+        // Go ahead and create our <html> and <body>
+        Element* html = new HTMLHtmlElement(this);
+        addChild(html);
+        html->attach();
+        Element* body = new HTMLBodyElement(this);
+        html->addChild(body);
+        body->attach();
+        Element* pre = new HTMLPreElement(preTag, this);
+        body->addChild(pre);
+        pre->attach();
+        m_current = pre;
+    }
+    
+    if (token->tagName == textAtom) {
+        Text* t = new Text(this, token->text.get());
+        m_current->addChild(t);
+        t->attach();
+    } else if (token->tagName == commentAtom) {
+    
+    } else {
+        // Handle the tag.
+        Element* span = addSpanWithClassName("webkit-html-tag");
+        String text = "<";
+        if (!token->beginTag)
+            text += "/";
+        text += token->tagName;
+        if (!token->attrs)
+            text += ">";
+        Text* t = new Text(this, text);
+        span->addChild(t);
+        t->attach();
+        
+        // Now handle attributes.
+        if (token->attrs) {
+            unsigned length = token->attrs->length();
+            for (unsigned i = 0; i < length; i++)
+                addViewSourceAttribute(token->attrs->attributeItem(i));
+        
+            span = addSpanWithClassName("webkit-html-tag");
+            t = new Text(this, ">");
+            span->addChild(t);
+            t->attach();
+        }
+        
+    }
+}
+
+void HTMLViewSourceDocument::addViewSourceAttribute(Attribute* attr)
+{
+    // FIXME: Don't just hard-code the whitespace between attribute values.
+    Text* t = new Text(this, " ");
+    m_current->addChild(t);
+    t->attach();
+    
+    // Attribute name.
+    // FIXME: Losing whitespace between the name and the = sign and between the = sign and the value.
+    Element* span = addSpanWithClassName("webkit-html-attribute-name");
+    String name = attr->name().toString();
+    if (!attr->value().isNull())
+        name += "=";
+    t = new Text(this, name);
+    span->addChild(t);
+    t->attach();
+    
+    // Attribute value.
+    if (!attr->value().isNull()) {
+        Element* span = addSpanWithClassName("webkit-html-attribute-value");
+        String text = "\""; // FIXME: Don't assume the attr is quoted.
+        text += attr->value();
+        text += "\"";
+        t = new Text(this, text);
+        span->addChild(t);
+        t->attach();
+    }
+}
+
+Element* HTMLViewSourceDocument::addSpanWithClassName(const String& className)
+{
+    Element* span = new HTMLElement(spanTag, this);
+    Attribute* a = new MappedAttribute(classAttr, className);
+    NamedMappedAttrMap* attrs = new NamedMappedAttrMap(0);
+    attrs->insertAttribute(a);   
+    span->setAttributeMap(attrs);     
+    m_current->addChild(span);
+    span->attach();
+    return span;
+}
+
+}
diff --git a/WebCore/html/HTMLViewSourceDocument.h b/WebCore/html/HTMLViewSourceDocument.h
new file mode 100644 (file)
index 0000000..6822d86
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2006 Apple Computer, 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,
+ * 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. 
+ */
+#ifndef HTMLViewSourceDocument_h
+#define HTMLViewSourceDocument_h
+
+#include "HTMLDocument.h"
+
+namespace WebCore {
+
+class DOMImplementation;
+class FrameView;
+class Token;
+class Attribute;
+
+class HTMLViewSourceDocument : public HTMLDocument
+{
+public:
+    HTMLViewSourceDocument(DOMImplementation*, FrameView* = 0);
+    
+    virtual Tokenizer* createTokenizer();
+    
+    void addViewSourceToken(Token*);
+    void addViewSourceAttribute(Attribute*);
+    
+private:
+    Element* addSpanWithClassName(const String&);
+
+private:
+    RefPtr<Node> m_current;
+};
+
+}
+
+#endif // HTMLViewSourceDocument_h
index e6bf8d4..3ba6206 100644 (file)
@@ -46,7 +46,7 @@
 #include "FloatRect.h"
 #include "Frame.h"
 #include "GraphicsContext.h"
-#include "HTMLDocument.h"
+#include "HTMLViewSourceDocument.h"
 #include "HTMLFormElement.h"
 #include "HTMLFrameElement.h"
 #include "HTMLGenericFormElement.h"
@@ -590,6 +590,8 @@ void Frame::begin(const KURL& url)
     d->m_doc = new ImageDocument(DOMImplementation::instance(), d->m_view.get());
   else if (PlugInInfoStore::supportsMIMEType(d->m_request.m_responseMIMEType))
     d->m_doc = new PluginDocument(DOMImplementation::instance(), d->m_view.get());
+  else if (inViewSourceMode())
+    d->m_doc = new HTMLViewSourceDocument(DOMImplementation::instance(), d->m_view.get());
   else
     d->m_doc = DOMImplementation::instance()->createHTMLDocument(d->m_view.get());
 
@@ -3346,6 +3348,16 @@ void Frame::setWindowHasFocus(bool flag)
         doc->dispatchWindowEvent(flag ? focusEvent : blurEvent, false, false);
 }
 
+bool Frame::inViewSourceMode() const
+{
+    return d->m_inViewSourceMode;
+}
+
+void Frame::setInViewSourceMode(bool mode) const
+{
+    d->m_inViewSourceMode = mode;
+}
+  
 UChar Frame::backslashAsCurrencySymbol() const
 {
     Document *doc = document();
index 454281a..c7de7e1 100644 (file)
@@ -453,6 +453,9 @@ public:
 
   virtual void tokenizerProcessedData() {}
 
+  bool inViewSourceMode() const;
+  void setInViewSourceMode(bool = true) const;
+
   const KHTMLSettings* settings() const;
 
   void setJSStatusBarText(const String&);
index 8c87f97..92e2773 100644 (file)
@@ -101,6 +101,7 @@ namespace WebCore {
             , m_markedTextUsesUnderlines(false)
             , m_highlightTextMatches(false)
             , m_windowHasFocus(false)
+            , m_inViewSourceMode(false)
             , frameCount(0)
         {
         }
@@ -225,6 +226,8 @@ namespace WebCore {
         bool m_highlightTextMatches;
         bool m_windowHasFocus;
         
+        bool m_inViewSourceMode;
+
         unsigned frameCount;
     };
 }
index cfd384b..711d957 100644 (file)
@@ -245,6 +245,8 @@ void RenderPartObject::updateWidget()
           url = "about:blank";
       FrameView* v = static_cast<FrameView*>(m_view);
       v->frame()->requestFrame(this, url, o->m_name);
+      if (o->contentFrame())
+          o->contentFrame()->setInViewSourceMode(o->viewSourceMode());
   }
 }