2010-06-24  Eric Seidel  <eric@webkit.org>

        Reviewed by Adam Barth.

        Add RawDataDocumentParser to get rid of a bunch of copy/paste code in DocumentParser subclasses
        https://bugs.webkit.org/show_bug.cgi?id=41136

        I think this is likely far from the final design,
        however this is almost entirely minus lines which is a
        good thing.

        The original authors of these DocumentParser subclasses
        seem to have just copied the files whole, as they all
        had the same includes, many of which were unnecessary for
        some of the files.

        I think eventually the FrameLoader will call a virtual
        DocumentParser::appendData which will in turn decode
        and call another write/appendData call.  In the case
        of these RawDataDocumentParsers, they will just override
        the low-level appendData call instead of needing
        DocumentWriter to have a special if based on
        DocumentParser::wantsRawData.

        No functional change, thus no tests.

        * GNUmakefile.am:
        * WebCore.gypi:
        * WebCore.pro:
        * WebCore.xcodeproj/project.pbxproj:
        * dom/DocumentParser.h:
        (WebCore::DocumentParser::writeRawData):
        * loader/ImageDocument.cpp:
        (WebCore::ImageDocumentParser::ImageDocumentParser):
        (WebCore::ImageDocumentParser::finish):
        * loader/MediaDocument.cpp:
        (WebCore::MediaDocumentParser::MediaDocumentParser):
        (WebCore::MediaDocumentParser::writeRawData):
        * loader/PluginDocument.cpp:
        (WebCore::PluginDocumentParser::PluginDocumentParser):
        * loader/SinkDocument.cpp:
        (WebCore::SinkDocument::createParser):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@61789 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 1233c35..9c7bc41 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,46 @@
+2010-06-24  Eric Seidel  <eric@webkit.org>
+
+        Reviewed by Adam Barth.
+
+        Add RawDataDocumentParser to get rid of a bunch of copy/paste code in DocumentParser subclasses
+        https://bugs.webkit.org/show_bug.cgi?id=41136
+
+        I think this is likely far from the final design,
+        however this is almost entirely minus lines which is a
+        good thing.
+
+        The original authors of these DocumentParser subclasses
+        seem to have just copied the files whole, as they all
+        had the same includes, many of which were unnecessary for
+        some of the files.
+
+        I think eventually the FrameLoader will call a virtual
+        DocumentParser::appendData which will in turn decode
+        and call another write/appendData call.  In the case
+        of these RawDataDocumentParsers, they will just override
+        the low-level appendData call instead of needing
+        DocumentWriter to have a special if based on
+        DocumentParser::wantsRawData.
+
+        No functional change, thus no tests.
+
+        * GNUmakefile.am:
+        * WebCore.gypi:
+        * WebCore.pro:
+        * WebCore.xcodeproj/project.pbxproj:
+        * dom/DocumentParser.h:
+        (WebCore::DocumentParser::writeRawData):
+        * loader/ImageDocument.cpp:
+        (WebCore::ImageDocumentParser::ImageDocumentParser):
+        (WebCore::ImageDocumentParser::finish):
+        * loader/MediaDocument.cpp:
+        (WebCore::MediaDocumentParser::MediaDocumentParser):
+        (WebCore::MediaDocumentParser::writeRawData):
+        * loader/PluginDocument.cpp:
+        (WebCore::PluginDocumentParser::PluginDocumentParser):
+        * loader/SinkDocument.cpp:
+        (WebCore::SinkDocument::createParser):
+
 2010-06-23  Peter Kasting  <pkasting@google.com>
 
         Reviewed by Adam Barth.
diff --git a/WebCore/GNUmakefile.am b/WebCore/GNUmakefile.am
index e48b037..847bd58 100644
--- a/WebCore/GNUmakefile.am
+++ b/WebCore/GNUmakefile.am
@@ -872,6 +872,7 @@
 	WebCore/dom/Range.h \
 	WebCore/dom/RangeBoundaryPoint.h \
 	WebCore/dom/RangeException.h \
+	WebCore/dom/RawDataDocumentParser.h \
 	WebCore/dom/RegisteredEventListener.cpp \
 	WebCore/dom/RegisteredEventListener.h \
 	WebCore/dom/ScriptElement.cpp \
diff --git a/WebCore/WebCore.gypi b/WebCore/WebCore.gypi
index 5ea5a5e..4887033 100644
--- a/WebCore/WebCore.gypi
+++ b/WebCore/WebCore.gypi
@@ -1199,6 +1199,7 @@
             'dom/Range.h',
             'dom/RangeBoundaryPoint.h',
             'dom/RangeException.h',
+            'dom/RawDataDocumentParser.h',
             'dom/RegisteredEventListener.cpp',
             'dom/RegisteredEventListener.h',
             'dom/ScriptElement.cpp',
diff --git a/WebCore/WebCore.pro b/WebCore/WebCore.pro
index 39965c5..7de03e1 100644
--- a/WebCore/WebCore.pro
+++ b/WebCore/WebCore.pro
@@ -516,6 +516,7 @@
     dom/ProgressEvent.cpp \
     dom/QualifiedName.cpp \
     dom/Range.cpp \
+    dom/RawDataDocumentParser.h \
     dom/RegisteredEventListener.cpp \
     dom/ScriptElement.cpp \
     dom/ScriptExecutionContext.cpp \
diff --git a/WebCore/WebCore.xcodeproj/project.pbxproj b/WebCore/WebCore.xcodeproj/project.pbxproj
index 0d09478..89e5c15 100644
--- a/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -2966,6 +2966,7 @@
 		A83B79560CCB0125000B0825 /* DOMSVGFontFaceElement.mm in Sources */ = {isa = PBXBuildFile; fileRef = A83B79470CCB0125000B0825 /* DOMSVGFontFaceElement.mm */; };
 		A83B79570CCB0125000B0825 /* DOMSVGFontFaceElement.h in Headers */ = {isa = PBXBuildFile; fileRef = A83B79480CCB0125000B0825 /* DOMSVGFontFaceElement.h */; };
 		A83E1C740E49042C00140B9C /* ScriptControllerMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = A83E1C720E49042B00140B9C /* ScriptControllerMac.mm */; };
+		A84D827C11D333ED00972990 /* RawDataDocumentParser.h in Headers */ = {isa = PBXBuildFile; fileRef = A84D827B11D333ED00972990 /* RawDataDocumentParser.h */; };
 		A84EBD780CB8C89200079609 /* JSStyleSheetListCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A84EBD770CB8C89200079609 /* JSStyleSheetListCustom.cpp */; };
 		A84EBD830CB8C97700079609 /* JSStyleSheetList.h in Headers */ = {isa = PBXBuildFile; fileRef = A84EBD810CB8C97700079609 /* JSStyleSheetList.h */; };
 		A84EBD840CB8C97700079609 /* JSStyleSheetList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A84EBD820CB8C97700079609 /* JSStyleSheetList.cpp */; };
@@ -8445,6 +8446,7 @@
 		A83B79470CCB0125000B0825 /* DOMSVGFontFaceElement.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMSVGFontFaceElement.mm; sourceTree = "<group>"; };
 		A83B79480CCB0125000B0825 /* DOMSVGFontFaceElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMSVGFontFaceElement.h; sourceTree = "<group>"; };
 		A83E1C720E49042B00140B9C /* ScriptControllerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ScriptControllerMac.mm; sourceTree = "<group>"; };
+		A84D827B11D333ED00972990 /* RawDataDocumentParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RawDataDocumentParser.h; sourceTree = "<group>"; };
 		A84EBD770CB8C89200079609 /* JSStyleSheetListCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSStyleSheetListCustom.cpp; sourceTree = "<group>"; };
 		A84EBD810CB8C97700079609 /* JSStyleSheetList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStyleSheetList.h; sourceTree = "<group>"; };
 		A84EBD820CB8C97700079609 /* JSStyleSheetList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSStyleSheetList.cpp; sourceTree = "<group>"; };
@@ -16617,6 +16619,7 @@
 		F523D32402DE4478018635CA /* dom */ = {
 			isa = PBXGroup;
 			children = (
+				A84D827B11D333ED00972990 /* RawDataDocumentParser.h */,
 				E1C4DE6D0EA75C650023CCD6 /* ActiveDOMObject.cpp */,
 				E1C4DE680EA75C1E0023CCD6 /* ActiveDOMObject.h */,
 				A8C4A7FC09D563270003AC8D /* Attr.cpp */,
@@ -19526,6 +19529,7 @@
 				9719AF0011D09F2C00D45831 /* HTMLInputStream.h in Headers */,
 				A853123D11D0471B00D4D077 /* FragmentScriptingPermission.h in Headers */,
 				A8E6A78111D1661B00311F4A /* HTMLParserScheduler.h in Headers */,
+				A84D827C11D333ED00972990 /* RawDataDocumentParser.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
diff --git a/WebCore/dom/DocumentParser.h b/WebCore/dom/DocumentParser.h
index ae90794..881136c 100644
--- a/WebCore/dom/DocumentParser.h
+++ b/WebCore/dom/DocumentParser.h
@@ -55,7 +55,11 @@
     virtual bool processingData() const { return false; }
 
     virtual bool wantsRawData() const { return false; }
-    virtual bool writeRawData(const char* /*data*/, int /*length*/) { return false; }
+    virtual bool writeRawData(const char* /*data*/, int /*length*/)
+    {
+        ASSERT_NOT_REACHED();
+        return false;
+    }
 
     virtual bool wellFormed() const { return true; }
 
diff --git a/WebCore/dom/RawDataDocumentParser.h b/WebCore/dom/RawDataDocumentParser.h
new file mode 100644
index 0000000..77d148d
--- /dev/null
+++ b/WebCore/dom/RawDataDocumentParser.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2010 Google, 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 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 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.
+ */
+
+#ifndef RawDataDocumentParser_h
+#define RawDataDocumentParser_h
+
+#include "DocumentParser.h"
+
+namespace WebCore {
+
+// FIXME: It seems wrong that RawDataDocumentParser is a subclass of
+// DocumentParser.  RawDataDocumentParser, just wants to override an earlier
+// version of write() before the data is decoded.  Seems the decoding could
+// move into the base-class DocumentParser, and then RawDataDocumentParser
+// would just be short-circuting.  That could simplify some of the
+// DocumentWriter logic.
+class RawDataDocumentParser : public DocumentParser {
+public:
+    RawDataDocumentParser(Document* document)
+        : DocumentParser(document)
+    {
+    }
+
+protected:
+    virtual void finish()
+    {
+        if (!m_parserStopped)
+            m_document->finishedParsing();
+    }
+
+private:
+    virtual void write(const SegmentedString&, bool)
+    {
+        // <https://bugs.webkit.org/show_bug.cgi?id=25397>: JS code can always call document.write, we need to handle it.
+        ASSERT_NOT_REACHED();
+    }
+
+    virtual bool finishWasCalled()
+    {
+        // finish() always calls document()->finishedParsing() so we will be
+        // deleted after finish().
+        return false;
+    }
+
+    virtual bool isWaitingForScripts() const { return false; }
+
+    virtual bool wantsRawData() const { return true; }
+    virtual bool writeRawData(const char*, int) { return false; }
+};
+
+};
+
+#endif // RawDataDocumentParser_h
diff --git a/WebCore/loader/ImageDocument.cpp b/WebCore/loader/ImageDocument.cpp
index 5075fdd..e3e84e3 100644
--- a/WebCore/loader/ImageDocument.cpp
+++ b/WebCore/loader/ImageDocument.cpp
@@ -25,14 +25,11 @@
 #include "config.h"
 #include "ImageDocument.h"
 
-#include "CSSStyleDeclaration.h"
 #include "CachedImage.h"
 #include "DocumentLoader.h"
-#include "Element.h"
 #include "EventListener.h"
 #include "EventNames.h"
 #include "Frame.h"
-#include "FrameLoader.h"
 #include "FrameLoaderClient.h"
 #include "FrameView.h"
 #include "HTMLImageElement.h"
@@ -41,10 +38,8 @@
 #include "MouseEvent.h"
 #include "NotImplemented.h"
 #include "Page.h"
-#include "SegmentedString.h"
+#include "RawDataDocumentParser.h"
 #include "Settings.h"
-#include "Text.h"
-#include "XMLDocumentParser.h"
 
 using std::min;
 
@@ -76,25 +71,21 @@
     ImageDocument* m_doc;
 };
     
-class ImageDocumentParser : public DocumentParser {
+class ImageDocumentParser : public RawDataDocumentParser {
 public:
     ImageDocumentParser(ImageDocument* document)
-        : DocumentParser(document)
+        : RawDataDocumentParser(document)
     {
     }
 
-    virtual void write(const SegmentedString&, bool appendData);
-    virtual void finish();
-    virtual bool finishWasCalled();
-    virtual bool isWaitingForScripts() const;
-    
-    virtual bool wantsRawData() const { return true; }
-    virtual bool writeRawData(const char* data, int len);
-
     ImageDocument* document() const
     {
         return static_cast<ImageDocument*>(m_document);
     }
+
+private:
+    virtual bool writeRawData(const char* data, int len);
+    virtual void finish();
 };
 
 class ImageDocumentElement : public HTMLImageElement {
@@ -127,12 +118,6 @@
     return view ? view->pageZoomFactor() : 1;
 }
 
-void ImageDocumentParser::write(const SegmentedString&, bool)
-{
-    // <https://bugs.webkit.org/show_bug.cgi?id=25397>: JS code can always call document.write, we need to handle it.
-    notImplemented();
-}
-
 bool ImageDocumentParser::writeRawData(const char*, int)
 {
     Frame* frame = document()->frame();
@@ -179,19 +164,6 @@
 
     document()->finishedParsing();
 }
-
-bool ImageDocumentParser::finishWasCalled()
-{
-    // finish() always calls document()->finishedParsing() so we'll be deleted
-    // after finish().
-    return false;
-}
-
-bool ImageDocumentParser::isWaitingForScripts() const
-{
-    // An image document is never waiting for scripts
-    return false;
-}
     
 // --------
 
diff --git a/WebCore/loader/MediaDocument.cpp b/WebCore/loader/MediaDocument.cpp
index b9a3d4e..cf72ced 100644
--- a/WebCore/loader/MediaDocument.cpp
+++ b/WebCore/loader/MediaDocument.cpp
@@ -29,11 +29,8 @@
 #include "MediaDocument.h"
 
 #include "DocumentLoader.h"
-#include "Element.h"
-#include "Event.h"
 #include "EventNames.h"
 #include "Frame.h"
-#include "FrameLoader.h"
 #include "FrameLoaderClient.h"
 #include "HTMLEmbedElement.h"
 #include "HTMLNames.h"
@@ -41,42 +38,28 @@
 #include "KeyboardEvent.h"
 #include "MainResourceLoader.h"
 #include "NodeList.h"
-#include "Page.h"
-#include "SegmentedString.h"
-#include "Settings.h"
-#include "Text.h"
-#include "XMLDocumentParser.h"
+#include "RawDataDocumentParser.h"
 
 namespace WebCore {
 
 using namespace HTMLNames;
 
-class MediaDocumentParser : public DocumentParser {
+// FIXME: Share more code with PluginDocumentParser.
+class MediaDocumentParser : public RawDataDocumentParser {
 public:
     MediaDocumentParser(Document* document)
-        : DocumentParser(document)
+        : RawDataDocumentParser(document)
         , m_mediaElement(0)
     {
     }
 
 private:
-    virtual void write(const SegmentedString&, bool appendData);
-    virtual void finish();
-    virtual bool finishWasCalled();
-    virtual bool isWaitingForScripts() const;
-        
-    virtual bool wantsRawData() const { return true; }
     virtual bool writeRawData(const char* data, int len);
-        
+
     void createDocumentStructure();
 
     HTMLMediaElement* m_mediaElement;
 };
-
-void MediaDocumentParser::write(const SegmentedString&, bool)
-{
-    ASSERT_NOT_REACHED();
-}
     
 void MediaDocumentParser::createDocumentStructure()
 {
@@ -118,25 +101,6 @@
     finish();
     return false;
 }
-
-void MediaDocumentParser::finish()
-{
-    if (!m_parserStopped) 
-        document()->finishedParsing();
-}
-
-bool MediaDocumentParser::finishWasCalled()
-{
-    // finish() always calls document()->finishedParsing() so we'll be deleted
-    // after finish().
-    return false;
-}
-
-bool MediaDocumentParser::isWaitingForScripts() const
-{
-    // A media document is never waiting for scripts
-    return false;
-}
     
 MediaDocument::MediaDocument(Frame* frame)
     : HTMLDocument(frame)
diff --git a/WebCore/loader/PluginDocument.cpp b/WebCore/loader/PluginDocument.cpp
index 66df8ea..1b989e8 100644
--- a/WebCore/loader/PluginDocument.cpp
+++ b/WebCore/loader/PluginDocument.cpp
@@ -26,44 +26,34 @@
 #include "PluginDocument.h"
 
 #include "DocumentLoader.h"
-#include "Element.h"
 #include "Frame.h"
-#include "FrameLoader.h"
 #include "FrameLoaderClient.h"
 #include "HTMLEmbedElement.h"
 #include "HTMLNames.h"
 #include "MainResourceLoader.h"
 #include "Page.h"
+#include "RawDataDocumentParser.h"
 #include "RenderEmbeddedObject.h"
-#include "RenderWidget.h"
-#include "SegmentedString.h"
 #include "Settings.h"
-#include "Text.h"
-#include "XMLDocumentParser.h"
 
 namespace WebCore {
     
 using namespace HTMLNames;
-    
-class PluginDocumentParser : public DocumentParser {
+
+// FIXME: Share more code with MediaDocumentParser.
+class PluginDocumentParser : public RawDataDocumentParser {
 public:
     PluginDocumentParser(Document* document)
-        : DocumentParser(document)
+        : RawDataDocumentParser(document)
         , m_embedElement(0)
     {
     }
 
     static Widget* pluginWidgetFromDocument(Document*);
-        
+
 private:
-    virtual void write(const SegmentedString&, bool appendData);
-    virtual void finish();
-    virtual bool finishWasCalled();
-    virtual bool isWaitingForScripts() const;
-        
-    virtual bool wantsRawData() const { return true; }
     virtual bool writeRawData(const char* data, int len);
-        
+
     void createDocumentStructure();
 
     HTMLEmbedElement* m_embedElement;
@@ -83,11 +73,6 @@
     return 0;
 }
 
-void PluginDocumentParser::write(const SegmentedString&, bool)
-{
-    ASSERT_NOT_REACHED();
-}
-    
 void PluginDocumentParser::createDocumentStructure()
 {
     ExceptionCode ec;
@@ -139,25 +124,6 @@
     return false;
 }
 
-void PluginDocumentParser::finish()
-{
-    if (!m_parserStopped) 
-        document()->finishedParsing();            
-}
-
-bool PluginDocumentParser::finishWasCalled()
-{
-    // finish() always calls document()->finishedParsing() so we'll be deleted
-    // after finish().
-    return false;
-}
-
-bool PluginDocumentParser::isWaitingForScripts() const
-{
-    // A plugin document is never waiting for scripts
-    return false;
-}
-    
 PluginDocument::PluginDocument(Frame* frame)
     : HTMLDocument(frame)
 {
diff --git a/WebCore/loader/SinkDocument.cpp b/WebCore/loader/SinkDocument.cpp
index 00ab8dd..1e056ee 100644
--- a/WebCore/loader/SinkDocument.cpp
+++ b/WebCore/loader/SinkDocument.cpp
@@ -26,49 +26,21 @@
 #include "config.h"
 #include "SinkDocument.h"
 
-#include "DocumentParser.h"
+#include "RawDataDocumentParser.h"
 
 namespace WebCore {
 
-class SinkDocumentParser : public DocumentParser {
-public:
-    SinkDocumentParser(Document* document)
-        : DocumentParser(document)
-    {
-    }
-
-private:
-    virtual void write(const SegmentedString&, bool) { ASSERT_NOT_REACHED(); }
-    virtual void finish();
-    virtual bool finishWasCalled();
-    virtual bool isWaitingForScripts() const { return false; }
-        
-    virtual bool wantsRawData() const { return true; }
-    virtual bool writeRawData(const char*, int) { return false; }
-};
-
-void SinkDocumentParser::finish()
-{
-    if (!m_parserStopped) 
-        m_document->finishedParsing();    
-}
-
-bool SinkDocumentParser::finishWasCalled()
-{
-    // finish() always calls m_doc->finishedParsing() so we'll be deleted
-    // after finish().
-    return false;
-}
-
 SinkDocument::SinkDocument(Frame* frame)
     : HTMLDocument(frame)
 {
     setParseMode(Compat);
 }
-    
+
 DocumentParser* SinkDocument::createParser()
 {
-    return new SinkDocumentParser(this);
+    // The basic RawDataDocumentParser does nothing with the data
+    // which is sufficient for our purposes here.
+    return new RawDataDocumentParser(this);
 }
 
 } // namespace WebCore