Reviewed by Ken.
authordarin <darin@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 14 Dec 2004 00:10:19 +0000 (00:10 +0000)
committerdarin <darin@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 14 Dec 2004 00:10:19 +0000 (00:10 +0000)
        - moved markup-related functions into new sources files in the editing directory
        - removed all of the uses of dynamic_cast, preparing to turn off RTTI to make our code smaller and slightly faster

        * ForwardingHeaders/editing/markup.h: Added.
        * khtml/editing/markup.h: Added.
        * khtml/editing/markup.cpp: Added.

        * WebCore.pbproj/project.pbxproj: Added markup.h/cpp.

        * khtml/dom/dom_node.cpp: (Node::toHTML): Call createMarkup since there's no toHTML in NodeImpl any more.
        * khtml/html/html_elementimpl.cpp:
        (HTMLElementImpl::innerHTML): Changed to call createMarkup.
        (HTMLElementImpl::outerHTML): Ditto.

        * khtml/ecma/kjs_window.cpp:
        (Window::retrieveWindow): Comment out assert that uses dynamic_cast.
        (Window::retrieveActive): Ditto.

        * khtml/editing/htmlediting.h: Added forward class declaration needed now that I removed one elsewhere.
        * khtml/xml/dom_docimpl.h: Ditto.

        * khtml/khtml_part.cpp:
        (KHTMLPart::slotDebugDOMTree): Use createMarkup instead of toHTML.
        (KHTMLPart::processObjectRequest): Use inherits instead of dynamic_cast.

        * khtml/rendering/render_image.cpp: (RenderImage::paint): Add an explicit QChar conversion so this code
        still works even with the additional replace overloads added to QString.
        * kwq/KWQTextCodec.mm: (QTextCodec::fromUnicode): Ditto.

        * khtml/rendering/render_object.h: Removed the version of arenaDelete that does not take an object
        base pointer, because it used dynamic_cast in its implementation. Made the other version public.
        * khtml/rendering/render_object.cpp: Ditto.
        * khtml/rendering/render_replaced.cpp: (RenderWidget::deref): Pass object base pointer to arenaDelete.

        * khtml/xml/dom2_rangeimpl.h: Removed extra parameters from toHTML, and unneeded includes and declarations.
        * khtml/xml/dom2_rangeimpl.cpp: (DOM::RangeImpl::toHTML): Changed to call createMarkup, and moved all
        the support code into markup.cpp.

        * khtml/xml/dom_nodeimpl.h: Moved toHTML and related functions into markup.cpp.
        * khtml/xml/dom_nodeimpl.cpp: Ditto.

        * khtml/xml/dom_position.cpp:
        (DOM::startPosition): Implemented the version of this that takes a RangeImpl. Also added null checks
        so these return null positions rather than raising exceptions.
        (DOM::endPosition): Ditto.

        * khtml/khtmlview.h: Added an APPLE_CHANGES function so inherits can detect this class without dynamic_cast.
        * kwq/KWQFrame.h: Ditto.
        * kwq/KWQFrame.mm: (QFrame::isQFrame): Ditto.
        * kwq/KWQKPartsPart.h: Ditto.
        * kwq/KWQKPartsPart.mm: (KParts::ReadOnlyPart::isKPartsReadOnlyPart): Ditto.
        * kwq/KWQScrollView.h: Ditto.
        * kwq/KWQScrollView.mm: (QScrollView::isQScrollView): Ditto.
        * kwq/KWQKHTMLPart.h: Ditto.
        * kwq/KWQKHTMLPart.mm:
        (KHTMLView::isKHTMLView): Ditto.
        (KWQKHTMLPart::setTitle): Added an explicit QChar conversion so this code still works even with the additional
        replace overloads added to QString.
        (KWQKHTMLPart::setStatusBarText): Ditto.
        (KWQKHTMLPart::runJavaScriptAlert): Ditto.
        (KWQKHTMLPart::runJavaScriptConfirm): Ditto.
        (KWQKHTMLPart::runJavaScriptPrompt): Ditto.
        (KWQKHTMLPart::attributedString): Ditto.
        (KWQKHTMLPart::isCharacterSmartReplaceExempt): Ditto.
        (KWQKHTMLPart::isKHTMLPart): That dynamic_cast thing (see above).

        * kwq/KWQObject.h: Added virtual methods for the few cases where we need dynamic_cast-like behavior.
        * kwq/KWQObject.mm:
        (QObject::inherits): Changed to not use dynamic cast.
        (QObject::isKHTMLPart): Added. Returns false.
        (QObject::isKHTMLView): Ditto.
        (QObject::isKPartsReadOnlyPart): Ditto.
        (QObject::isQFrame): Ditto.
        (QObject::isQScrollView): Ditto.

        * kwq/KWQRenderTreeDebug.cpp:
        (write): Changed to use inherits rather than dynamic_cast.
        (writeSelection): Ditto.

        * kwq/KWQSlot.mm: (KWQSlot::call): Call through to the version with just a job pointer parameter rather
        than going straight on to the "no parameters at all" version.

        * kwq/KWQString.h:
        * kwq/KWQString.mm: (QString::replace): Added overloads.
        * kwq/WebCoreBridge.mm:
        (-[WebCoreBridge markupStringFromNode:nodes:]): Changed to call functions in markup.h.
        (-[WebCoreBridge markupStringFromRange:nodes:]): Ditto.
        (-[WebCoreBridge selectedString]): Added an explicit QChar conversion so this code still works even with
        the additional replace overloads added to QString.
        (-[WebCoreBridge stringForRange:]): Ditto.
        (-[WebCoreBridge copyDOMNode:copier:]): Changed to call functions in markup.h.
        (-[WebCoreBridge elementAtPoint:]): QChar conversion.
        (-[WebCoreBridge documentFragmentWithMarkupString:baseURLString:]): Changed to call functions in markup.h.
        (-[WebCoreBridge documentFragmentWithText:]): Changed to call functions in markup.h.

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

37 files changed:
WebCore/ChangeLog-2005-08-23
WebCore/ForwardingHeaders/editing/markup.h [new file with mode: 0644]
WebCore/WebCore.pbproj/project.pbxproj
WebCore/khtml/dom/dom_node.cpp
WebCore/khtml/ecma/kjs_window.cpp
WebCore/khtml/editing/htmlediting.h
WebCore/khtml/editing/markup.cpp [new file with mode: 0644]
WebCore/khtml/editing/markup.h [new file with mode: 0644]
WebCore/khtml/html/html_elementimpl.cpp
WebCore/khtml/khtml_part.cpp
WebCore/khtml/khtmlview.h
WebCore/khtml/rendering/render_image.cpp
WebCore/khtml/rendering/render_object.cpp
WebCore/khtml/rendering/render_object.h
WebCore/khtml/rendering/render_replaced.cpp
WebCore/khtml/xml/dom2_rangeimpl.cpp
WebCore/khtml/xml/dom2_rangeimpl.h
WebCore/khtml/xml/dom_docimpl.h
WebCore/khtml/xml/dom_nodeimpl.cpp
WebCore/khtml/xml/dom_nodeimpl.h
WebCore/khtml/xml/dom_position.cpp
WebCore/kwq/KWQFrame.h
WebCore/kwq/KWQFrame.mm
WebCore/kwq/KWQKHTMLPart.h
WebCore/kwq/KWQKHTMLPart.mm
WebCore/kwq/KWQKPartsPart.h
WebCore/kwq/KWQKPartsPart.mm
WebCore/kwq/KWQObject.h
WebCore/kwq/KWQObject.mm
WebCore/kwq/KWQRenderTreeDebug.cpp
WebCore/kwq/KWQScrollView.h
WebCore/kwq/KWQScrollView.mm
WebCore/kwq/KWQSlot.mm
WebCore/kwq/KWQString.h
WebCore/kwq/KWQString.mm
WebCore/kwq/KWQTextCodec.mm
WebCore/kwq/WebCoreBridge.mm

index f3625ec..884b65f 100644 (file)
@@ -1,3 +1,102 @@
+2004-12-13  Darin Adler  <darin@apple.com>
+
+        Reviewed by Ken.
+
+        - moved markup-related functions into new sources files in the editing directory
+        - removed all of the uses of dynamic_cast, preparing to turn off RTTI to make our code smaller and slightly faster
+
+        * ForwardingHeaders/editing/markup.h: Added.
+        * khtml/editing/markup.h: Added.
+        * khtml/editing/markup.cpp: Added.
+
+        * WebCore.pbproj/project.pbxproj: Added markup.h/cpp.
+
+        * khtml/dom/dom_node.cpp: (Node::toHTML): Call createMarkup since there's no toHTML in NodeImpl any more.
+        * khtml/html/html_elementimpl.cpp:
+        (HTMLElementImpl::innerHTML): Changed to call createMarkup.
+        (HTMLElementImpl::outerHTML): Ditto.
+
+        * khtml/ecma/kjs_window.cpp:
+        (Window::retrieveWindow): Comment out assert that uses dynamic_cast.
+        (Window::retrieveActive): Ditto.
+
+        * khtml/editing/htmlediting.h: Added forward class declaration needed now that I removed one elsewhere.
+        * khtml/xml/dom_docimpl.h: Ditto.
+
+        * khtml/khtml_part.cpp:
+        (KHTMLPart::slotDebugDOMTree): Use createMarkup instead of toHTML.
+        (KHTMLPart::processObjectRequest): Use inherits instead of dynamic_cast.
+
+        * khtml/rendering/render_image.cpp: (RenderImage::paint): Add an explicit QChar conversion so this code
+        still works even with the additional replace overloads added to QString.
+        * kwq/KWQTextCodec.mm: (QTextCodec::fromUnicode): Ditto.
+
+        * khtml/rendering/render_object.h: Removed the version of arenaDelete that does not take an object
+        base pointer, because it used dynamic_cast in its implementation. Made the other version public.
+        * khtml/rendering/render_object.cpp: Ditto.
+        * khtml/rendering/render_replaced.cpp: (RenderWidget::deref): Pass object base pointer to arenaDelete.
+
+        * khtml/xml/dom2_rangeimpl.h: Removed extra parameters from toHTML, and unneeded includes and declarations.
+        * khtml/xml/dom2_rangeimpl.cpp: (DOM::RangeImpl::toHTML): Changed to call createMarkup, and moved all
+        the support code into markup.cpp.
+
+        * khtml/xml/dom_nodeimpl.h: Moved toHTML and related functions into markup.cpp.
+        * khtml/xml/dom_nodeimpl.cpp: Ditto.
+
+        * khtml/xml/dom_position.cpp:
+        (DOM::startPosition): Implemented the version of this that takes a RangeImpl. Also added null checks
+        so these return null positions rather than raising exceptions.
+        (DOM::endPosition): Ditto.
+
+        * khtml/khtmlview.h: Added an APPLE_CHANGES function so inherits can detect this class without dynamic_cast.
+        * kwq/KWQFrame.h: Ditto.
+        * kwq/KWQFrame.mm: (QFrame::isQFrame): Ditto.
+        * kwq/KWQKPartsPart.h: Ditto.
+        * kwq/KWQKPartsPart.mm: (KParts::ReadOnlyPart::isKPartsReadOnlyPart): Ditto.
+        * kwq/KWQScrollView.h: Ditto.
+        * kwq/KWQScrollView.mm: (QScrollView::isQScrollView): Ditto.
+        * kwq/KWQKHTMLPart.h: Ditto.
+        * kwq/KWQKHTMLPart.mm:
+        (KHTMLView::isKHTMLView): Ditto.
+        (KWQKHTMLPart::setTitle): Added an explicit QChar conversion so this code still works even with the additional
+        replace overloads added to QString.
+        (KWQKHTMLPart::setStatusBarText): Ditto.
+        (KWQKHTMLPart::runJavaScriptAlert): Ditto.
+        (KWQKHTMLPart::runJavaScriptConfirm): Ditto.
+        (KWQKHTMLPart::runJavaScriptPrompt): Ditto.
+        (KWQKHTMLPart::attributedString): Ditto.
+        (KWQKHTMLPart::isCharacterSmartReplaceExempt): Ditto.
+        (KWQKHTMLPart::isKHTMLPart): That dynamic_cast thing (see above).
+
+        * kwq/KWQObject.h: Added virtual methods for the few cases where we need dynamic_cast-like behavior.
+        * kwq/KWQObject.mm:
+        (QObject::inherits): Changed to not use dynamic cast.
+        (QObject::isKHTMLPart): Added. Returns false.
+        (QObject::isKHTMLView): Ditto.
+        (QObject::isKPartsReadOnlyPart): Ditto.
+        (QObject::isQFrame): Ditto.
+        (QObject::isQScrollView): Ditto.
+
+        * kwq/KWQRenderTreeDebug.cpp:
+        (write): Changed to use inherits rather than dynamic_cast.
+        (writeSelection): Ditto.
+
+        * kwq/KWQSlot.mm: (KWQSlot::call): Call through to the version with just a job pointer parameter rather
+        than going straight on to the "no parameters at all" version.
+
+        * kwq/KWQString.h:
+        * kwq/KWQString.mm: (QString::replace): Added overloads.
+        * kwq/WebCoreBridge.mm:
+        (-[WebCoreBridge markupStringFromNode:nodes:]): Changed to call functions in markup.h.
+        (-[WebCoreBridge markupStringFromRange:nodes:]): Ditto.
+        (-[WebCoreBridge selectedString]): Added an explicit QChar conversion so this code still works even with
+        the additional replace overloads added to QString.
+        (-[WebCoreBridge stringForRange:]): Ditto.
+        (-[WebCoreBridge copyDOMNode:copier:]): Changed to call functions in markup.h.
+        (-[WebCoreBridge elementAtPoint:]): QChar conversion.
+        (-[WebCoreBridge documentFragmentWithMarkupString:baseURLString:]): Changed to call functions in markup.h.
+        (-[WebCoreBridge documentFragmentWithText:]): Changed to call functions in markup.h.
+
 2004-12-13  Ken Kocienda  <kocienda@apple.com>
 
         Reviewed by John
diff --git a/WebCore/ForwardingHeaders/editing/markup.h b/WebCore/ForwardingHeaders/editing/markup.h
new file mode 100644 (file)
index 0000000..af3d53b
--- /dev/null
@@ -0,0 +1 @@
+#import <markup.h>
index 6780b2e..ab0842b 100644 (file)
                                939FF8EF0702B1B100979E5E,
                                BECE67BE07087B250007C14B,
                                BEA5E01E075CEDAC0098A432,
+                               9378D9FC07640A46004B97BF,
                        );
                        isa = PBXHeadersBuildPhase;
                        runOnlyForDeploymentPostprocessing = 0;
                                93ABE074070285F600BD91F9,
                                939FF8EE0702B1B100979E5E,
                                BEA5DBDB075CEDA00098A432,
+                               9378D9FB07640A46004B97BF,
                        );
                        isa = PBXSourcesBuildPhase;
                        runOnlyForDeploymentPostprocessing = 0;
                        settings = {
                        };
                };
+               9378D9F907640A46004B97BF = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.cpp.cpp;
+                       name = markup.cpp;
+                       path = editing/markup.cpp;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               9378D9FA07640A46004B97BF = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = markup.h;
+                       path = editing/markup.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               9378D9FB07640A46004B97BF = {
+                       fileRef = 9378D9F907640A46004B97BF;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9378D9FC07640A46004B97BF = {
+                       fileRef = 9378D9FA07640A46004B97BF;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
                93859E32065FCAD300CF54EE = {
                        fileEncoding = 4;
                        isa = PBXFileReference;
                                BEA5E01D075CEDAC0098A432,
                                BE02D4E6066F908A0076809F,
                                BE02D4E7066F908A0076809F,
+                               9378D9FA07640A46004B97BF,
+                               9378D9F907640A46004B97BF,
                                93ABE067070285F600BD91F9,
                                93ABE066070285F600BD91F9,
                                BECE67BD07087B250007C14B,
index 9e4d34f..820593c 100644 (file)
 #include "xml/dom_docimpl.h"
 #include "xml/dom_elementimpl.h"
 #include "xml/dom2_eventsimpl.h"
+#include "editing/markup.h"
 
 #include <qrect.h>
 
 using namespace DOM;
 
+using khtml::createMarkup;
+
 NamedNodeMap::NamedNodeMap()
 {
     impl = 0;
@@ -394,8 +397,7 @@ unsigned long Node::index() const
 
 QString Node::toHTML()
 {
-    if (!impl) return QString::null;
-    return impl->toHTML();
+    return createMarkup(impl);
 }
 
 void Node::applyChanges()
index 0d28087..134cf9a 100644 (file)
@@ -328,7 +328,7 @@ Window *Window::retrieveWindow(KHTMLPart *p)
   {
     assert( !obj.isNull() );
 #ifndef QWS
-    assert( dynamic_cast<KJS::Window*>(obj.imp()) ); // type checking
+    //assert( dynamic_cast<KJS::Window*>(obj.imp()) ); // type checking
 #endif
   }
 #endif
@@ -342,7 +342,7 @@ Window *Window::retrieveActive(ExecState *exec)
   ValueImp *imp = exec->dynamicInterpreter()->globalObject().imp();
   assert( imp );
 #ifndef QWS
-  assert( dynamic_cast<KJS::Window*>(imp) );
+  //assert( dynamic_cast<KJS::Window*>(imp) );
 #endif
   return static_cast<KJS::Window*>(imp);
 }
index c59ae77..ac265cc 100644 (file)
@@ -35,6 +35,7 @@
 namespace DOM {
     class CSSMutableStyleDeclarationImpl;
     class CSSProperty;
+    class CSSStyleDeclarationImpl;
     class DocumentFragmentImpl;
     class HTMLElementImpl;
     class TextImpl;
diff --git a/WebCore/khtml/editing/markup.cpp b/WebCore/khtml/editing/markup.cpp
new file mode 100644 (file)
index 0000000..6cb1aaa
--- /dev/null
@@ -0,0 +1,441 @@
+/*
+ * Copyright (C) 2004 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,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "markup.h"
+
+#include "html/html_elementimpl.h"
+#include "xml/dom_position.h"
+#include "xml/dom2_rangeimpl.h"
+#include "rendering/render_text.h"
+#include "misc/htmltags.h"
+#include "html/dtd.h"
+
+using DOM::AttributeImpl;
+using DOM::CommentImpl;
+using DOM::DocumentFragmentImpl;
+using DOM::DocumentImpl;
+using DOM::DOMString;
+using DOM::ElementImpl;
+using DOM::endTag;
+using DOM::FORBIDDEN;
+using DOM::HTMLElementImpl;
+using DOM::NamedAttrMapImpl;
+using DOM::Node;
+using DOM::NodeImpl;
+using DOM::Position;
+using DOM::RangeImpl;
+using DOM::TextImpl;
+
+namespace khtml {
+
+static QString escapeHTML(const QString &in)
+{
+    QString s = "";
+
+    unsigned len = in.length();
+    for (unsigned i = 0; i < len; ++i) {
+        switch (in[i].latin1()) {
+            case '&':
+                s += "&amp;";
+                break;
+            case '<':
+                s += "&lt;";
+                break;
+            case '>':
+                s += "&gt;";
+                break;
+            default:
+                s += in[i];
+        }
+    }
+
+    return s;
+}
+
+static QString stringValueForRange(const NodeImpl *node, const RangeImpl *range)
+{
+    DOMString str = node->nodeValue().copy();
+    if (range) {
+        int exceptionCode;
+        if (node == range->endContainer(exceptionCode)) {
+            str.truncate(range->endOffset(exceptionCode));
+        }
+        if (node == range->startContainer(exceptionCode)) {
+            str.remove(0, range->startOffset(exceptionCode));
+        }
+    }
+    return str.string();
+}
+
+static QString renderedText(const NodeImpl *node, const RangeImpl *range)
+{
+    RenderObject *r = node->renderer();
+    if (!r)
+        return QString();
+    
+    if (!node->isTextNode())
+        return QString();
+
+    QString result = "";
+
+    int exceptionCode;
+    const TextImpl *textNode = static_cast<const TextImpl *>(node);
+    unsigned startOffset = 0;
+    unsigned endOffset = textNode->length();
+
+    if (range && node == range->startContainer(exceptionCode))
+        startOffset = range->startOffset(exceptionCode);
+    if (range && node == range->endContainer(exceptionCode))
+        endOffset = range->endOffset(exceptionCode);
+    
+    RenderText *textRenderer = static_cast<RenderText *>(r);
+    QString str = node->nodeValue().string();
+    for (InlineTextBox *box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
+        unsigned start = box->m_start;
+        unsigned end = box->m_start + box->m_len;
+        if (endOffset < start)
+            break;
+        if (startOffset <= end) {
+            unsigned s = kMax(start, startOffset);
+            unsigned e = kMin(end, endOffset);
+            result.append(str.mid(s, e-s));
+            // now add in collapsed-away spaces if at the end of the line
+            InlineTextBox *nextBox = box->nextTextBox();
+            if (nextBox && box->root() != nextBox->root()) {
+                const char nonBreakingSpace = '\xa0';
+                // count the number of characters between the end of the
+                // current box and the start of the next box.
+                int collapsedStart = e;
+                int collapsedPastEnd = kMin((unsigned)nextBox->m_start, endOffset + 1);
+                bool addNextNonNBSP = true;
+                for (int i = collapsedStart; i < collapsedPastEnd; i++) {
+                    if (str[i] == nonBreakingSpace) {
+                        result.append(str[i]);
+                        addNextNonNBSP = true;
+                    }
+                    else if (addNextNonNBSP) {
+                        result.append(str[i]);
+                        addNextNonNBSP = false;
+                    }
+                }
+            }
+        }
+
+    }
+    
+    return result;
+}
+
+static QString startMarkup(const NodeImpl *node, const RangeImpl *range, EAnnotateForInterchange annotate)
+{
+    unsigned short type = node->nodeType();
+    switch (type) {
+        case Node::TEXT_NODE: {
+            if (node->parentNode()) {
+                switch (node->parentNode()->id()) {
+                    case ID_SCRIPT:
+                    case ID_STYLE:
+                    case ID_TEXTAREA:
+                        return stringValueForRange(node, range);
+                }
+            }
+            if (annotate)
+                return convertHTMLTextToInterchangeFormat(escapeHTML(renderedText(node, range))); 
+            return escapeHTML(stringValueForRange(node, range));
+        }
+        case Node::COMMENT_NODE:
+            return static_cast<const CommentImpl *>(node)->toString().string();
+        case Node::DOCUMENT_NODE:
+            return "";
+        default: {
+            QString markup = QChar('<') + node->nodeName().string();
+            if (type == Node::ELEMENT_NODE) {
+                const ElementImpl *el = static_cast<const ElementImpl *>(node);
+                NamedAttrMapImpl *attrs = el->attributes();
+                unsigned long length = attrs->length();
+                for (unsigned int i=0; i<length; i++) {
+                    AttributeImpl *attr = attrs->attributeItem(i);
+                    markup += " " + node->getDocument()->attrName(attr->id()).string() + "=\"" + attr->value().string() + "\"";
+                }
+            }
+            markup += node->isHTMLElement() ? ">" : "/>";
+            return markup;
+        }
+    }
+}
+
+static QString endMarkup(const NodeImpl *node)
+{
+    if ((!node->isHTMLElement() || endTag[node->id()] != FORBIDDEN) && node->nodeType() != Node::TEXT_NODE && node->nodeType() != Node::DOCUMENT_NODE) {
+        return "</" + node->nodeName().string() + ">";
+    }
+    return "";
+}
+
+static QString markup(const NodeImpl *startNode, bool onlyIncludeChildren, bool includeSiblings, QPtrList<NodeImpl> *nodes)
+{
+    // Doesn't make sense to only include children and include siblings.
+    assert(!(onlyIncludeChildren && includeSiblings));
+    QString me = "";
+    for (const NodeImpl *current = startNode; current != NULL; current = includeSiblings ? current->nextSibling() : NULL) {
+        if (!onlyIncludeChildren) {
+            if (nodes) {
+                nodes->append(current);
+            }
+            me += startMarkup(current, 0, DoNotAnnotateForInterchange);
+        }        
+        if (!current->isHTMLElement() || endTag[current->id()] != FORBIDDEN) {
+            // print children
+            if (NodeImpl *n = current->firstChild()) {
+                me += markup(n, false, true, nodes);
+            }
+            // Print my ending tag
+            if (!onlyIncludeChildren) {
+                me += endMarkup(current);
+            }
+        }
+    }
+    return me;
+}
+
+static void completeURLs(NodeImpl *node, const QString &baseURL)
+{
+    NodeImpl *end = node->traverseNextSibling();
+    for (NodeImpl *n = node; n != end; n = n->traverseNextNode()) {
+        if (n->nodeType() == Node::ELEMENT_NODE) {
+            ElementImpl *e = static_cast<ElementImpl *>(n);
+            NamedAttrMapImpl *attrs = e->attributes();
+            unsigned long length = attrs->length();
+            for (unsigned long i = 0; i < length; i++) {
+                AttributeImpl *attr = attrs->attributeItem(i);
+                if (e->isURLAttribute(attr)) {
+                    e->setAttribute(attr->id(), KURL(baseURL, attr->value().string()).url());
+                }
+            }
+        }
+    }
+}
+
+QString createMarkup(const RangeImpl *range, QPtrList<NodeImpl> *nodes, EAnnotateForInterchange annotate)
+{
+    if (!range || range->isDetached())
+        return QString();
+
+    int exceptionCode;
+    NodeImpl *commonAncestor = range->commonAncestorContainer(exceptionCode);
+    NodeImpl *commonAncestorBlock = 0;
+    if (commonAncestor != 0) {
+        commonAncestorBlock = commonAncestor->enclosingBlockFlowElement();
+    }
+    if (commonAncestorBlock == 0) {
+        return "";    
+    }
+
+    QStringList markups;
+    NodeImpl *pastEnd = range->pastEndNode();
+    NodeImpl *lastClosed = 0;
+    QPtrList<NodeImpl> ancestorsToClose;
+    
+    // Iterate through the nodes of the range.
+    NodeImpl *next;
+    for (NodeImpl *n = range->startNode(); n != pastEnd; n = next) {
+        next = n->traverseNextNode();
+        if (!n->renderer())
+            continue;
+
+        if (n->isBlockFlow() && next == pastEnd) {
+            // Don't write out an empty block.
+            continue;
+        }
+        
+        // Add the node to the markup.
+        markups.append(startMarkup(n, range, annotate));
+        if (nodes) {
+            nodes->append(n);
+        }
+        
+        if (n->firstChild() == 0) {
+            // Node has no children, add its close tag now.
+            markups.append(endMarkup(n));
+            lastClosed = n;
+            
+            // Check if the node is the last leaf of a tree.
+            if (n->nextSibling() == 0 || next == pastEnd) {
+                if (!ancestorsToClose.isEmpty()) {
+                    // Close up the ancestors.
+                    while (NodeImpl *ancestor = ancestorsToClose.last()) {
+                        if (next != pastEnd && ancestor == next->parentNode()) {
+                            break;
+                        }
+                        // Not at the end of the range, close ancestors up to sibling of next node.
+                        markups.append(endMarkup(ancestor));
+                        lastClosed = ancestor;
+                        ancestorsToClose.removeLast();
+                    }
+                } else {
+                    // No ancestors to close, but need to add ancestors not in range since next node is in another tree. 
+                    if (next != pastEnd) {
+                        NodeImpl *nextParent = next->parentNode();
+                        if (n != nextParent) {
+                            for (NodeImpl *parent = n->parent(); parent != 0 && parent != nextParent; parent = parent->parentNode()) {
+                                markups.prepend(startMarkup(parent, range, annotate));
+                                markups.append(endMarkup(parent));
+                                if (nodes) {
+                                    nodes->append(parent);
+                                }                            
+                                lastClosed = parent;
+                            }
+                        }
+                    }
+                }
+            }
+        } else {
+            // Node is an ancestor, set it to close eventually.
+            ancestorsToClose.append(n);
+        }
+    }
+    
+    // Add ancestors up to the common ancestor block so inline ancestors such as FONT and B are part of the markup.
+    for (NodeImpl *ancestor = lastClosed->parentNode(); ancestor; ancestor = ancestor->parentNode()) {
+        bool breakAtEnd = false;
+        if (commonAncestorBlock == ancestor) {
+            NodeImpl::Id id = ancestor->id();
+            // Tables and lists must be part of the markup to avoid broken structures. 
+            if (id == ID_TABLE || id == ID_OL || id == ID_UL) {
+                breakAtEnd = true;
+            } else {
+                break;
+            }
+        }
+        markups.prepend(startMarkup(ancestor, range, annotate));
+        markups.append(endMarkup(ancestor));
+        if (nodes) {
+            nodes->append(ancestor);
+        }        
+        if (breakAtEnd) {
+            break;
+        }
+    }
+
+    if (annotate) {
+        Position pos(endPosition(range));
+        NodeImpl *block = pos.node()->enclosingBlockFlowElement();
+        NodeImpl *upstreamBlock = pos.upstream().node()->enclosingBlockFlowElement();
+        if (block != upstreamBlock) {
+            static const QString interchangeNewlineString = QString("<br class=\"") + AppleInterchangeNewline + "\">";
+            markups.append(interchangeNewlineString);
+        }
+    }
+
+    return markups.join("");
+}
+
+DocumentFragmentImpl *createFragmentFromMarkup(DocumentImpl *document, const QString &markup, const QString &baseURL)
+{
+    // FIXME: What if the document element is not an HTML element?
+    HTMLElementImpl *element = static_cast<HTMLElementImpl *>(document->documentElement());
+
+    DocumentFragmentImpl *fragment = element->createContextualFragment(markup);
+    assert(fragment);
+
+    if (!baseURL.isEmpty() && baseURL != document->baseURL())
+        completeURLs(fragment, baseURL);
+
+    return fragment;
+}
+
+QString createMarkup(const DOM::NodeImpl *node, EChildrenOnly includeChildren,
+    QPtrList<DOM::NodeImpl> *nodes, EAnnotateForInterchange annotate)
+{
+    assert(annotate == DoNotAnnotateForInterchange); // annotation not yet implemented for this code path
+    return markup(node, includeChildren, false, nodes);
+}
+
+DOM::DocumentFragmentImpl *createFragmentFromText(DOM::DocumentImpl *document, const QString &text)
+{
+    if (!document)
+        return 0;
+
+    DocumentFragmentImpl *fragment = document->createDocumentFragment();
+    QString string = text;
+
+    // Replace tabs with four plain spaces.
+    // These spaces will get converted along with the other existing spaces below.
+    string.replace('\t', "    ");
+
+    int offset = 0;
+    int stringLength = string.length();
+    while (1) {
+        // FIXME: This only converts plain old spaces, and does not
+        // deal with more exotic whitespace. Note that we want to 
+        // leave newlines and returns alone at this point anyway, 
+        // since those are handled specially later.
+        int spacesPos = string.find("  ", offset);
+        if (spacesPos < 0)
+            break;
+            
+        // Found two adjoining spaces.
+        // Now, lookahead to see if these two spaces are followed by:
+        //   1. another space and then a non-space
+        //   2. another space and then the end of the string
+        // If either 1 or 2 is true, replace the three spaces found with nbsp+nbsp+space, 
+        // otherwise, replace the first two spaces with nbsp+space.
+        if ((spacesPos + 3 < stringLength && string[spacesPos + 2] == ' ' && string[spacesPos + 3] != ' ')
+                || (spacesPos + 3 == stringLength && string[spacesPos + 2] == ' ')) {
+            string.replace(spacesPos, 3, "\xA0\xA0 ");
+        } else {
+            string.replace(spacesPos, 2, "\xA0 ");
+        }
+        offset = spacesPos + 2;
+    }
+    
+    // Handle line endings, replacing them with BR elements.
+    string.replace(QString("\r\n"), "\n");
+    string.replace('\r', '\n');
+    QStringList list = QStringList::split('\n', string, true); // true gets us empty strings in the list
+    bool firstNode = true;
+    while (!list.isEmpty()) {
+        int exceptionCode = 0;
+        if (firstNode) {
+            firstNode = false;
+        } else {
+            ElementImpl *breakNode = document->createHTMLElement("br", exceptionCode);
+            assert(exceptionCode == 0);
+            fragment->appendChild(breakNode, exceptionCode);
+            assert(exceptionCode == 0);
+        }
+        QString s = list.first();
+        list.pop_front();
+        if (!s.isEmpty()) {
+            NodeImpl *textNode = document->createTextNode(s);
+            fragment->appendChild(textNode, exceptionCode);
+            assert(exceptionCode == 0);
+        }
+    }
+    
+    return fragment;
+}
+
+}
diff --git a/WebCore/khtml/editing/markup.h b/WebCore/khtml/editing/markup.h
new file mode 100644 (file)
index 0000000..1ae6756
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2004 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,
+ * 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 KHTML_EDITING_MARKUP_H
+#define KHTML_EDITING_MARKUP_H
+
+#include <xml/dom_docimpl.h>
+#include "html_interchange.h"
+
+namespace khtml {
+
+enum EChildrenOnly { IncludeNode, ChildrenOnly };
+
+DOM::DocumentFragmentImpl *createFragmentFromText(DOM::DocumentImpl *document, const QString &text);
+DOM::DocumentFragmentImpl *createFragmentFromMarkup(DOM::DocumentImpl *document, const QString &markup, const QString &baseURL);
+
+QString createMarkup(const DOM::RangeImpl *range,
+    QPtrList<DOM::NodeImpl> *nodes = 0, EAnnotateForInterchange = DoNotAnnotateForInterchange);
+QString createMarkup(const DOM::NodeImpl *node, EChildrenOnly = IncludeNode,
+    QPtrList<DOM::NodeImpl> *nodes = 0, EAnnotateForInterchange = DoNotAnnotateForInterchange);
+
+}
+
+#endif // KHTML_EDITING_MARKUP_H
index 3e51e1a..e1bdd19 100644 (file)
@@ -48,6 +48,7 @@
 #include "css/css_ruleimpl.h"
 #include "xml/dom_textimpl.h"
 #include "xml/dom2_eventsimpl.h"
+#include "editing/markup.h"
 
 #include <kdebug.h>
 
@@ -701,12 +702,12 @@ void HTMLElementImpl::createMappedDecl(HTMLAttributeImpl* attr)
 
 DOMString HTMLElementImpl::innerHTML() const
 {
-    return toHTML();
+    return createMarkup(this, ChildrenOnly);
 }
 
 DOMString HTMLElementImpl::outerHTML() const
 {
-    return recursive_toHTML();
+    return createMarkup(this);
 }
 
 DOMString HTMLElementImpl::innerText() const
index ad28f1b..ccf337b 100644 (file)
@@ -44,6 +44,7 @@
 #include "dom/dom_string.h"
 #include "dom/dom_element.h"
 #include "dom/html_document.h"
+#include "editing/markup.h"
 #include "editing/selection.h"
 #include "editing/visible_position.h"
 #include "editing/visible_text.h"
@@ -921,7 +922,7 @@ void KHTMLPart::slotShowDocument( const QString &url, const QString &target )
 void KHTMLPart::slotDebugDOMTree()
 {
   if ( d->m_doc && d->m_doc->firstChild() )
-    qDebug("%s", d->m_doc->firstChild()->toHTML().latin1());
+    qDebug("%s", createMarkup(d->m_doc->firstChild()).latin1());
 }
 
 void KHTMLPart::slotDebugRenderTree()
@@ -3173,15 +3174,15 @@ bool KHTMLPart::processObjectRequest( khtml::ChildFrame *child, const KURL &_url
 #if APPLE_CHANGES
   if ( child->m_part )
   {
-    KHTMLPart *part = dynamic_cast<KHTMLPart *>(&*child->m_part);
-    if (part)
+    KHTMLPart *part = static_cast<KHTMLPart *>(&*child->m_part);
+    if (part && part->inherits("KHTMLPart"))
       part->openURL(url);
   }
   else
   {
     KParts::ReadOnlyPart *part = KWQ(this)->createPart(*child, url, mimetype);
-    KHTMLPart *khtml_part = dynamic_cast<KHTMLPart *>(part);
-    if (khtml_part)
+    KHTMLPart *khtml_part = static_cast<KHTMLPart *>(part);
+    if (khtml_part && khtml_part->inherits("KHTMLPart"))
       khtml_part->childBegin();
 #else
   if ( !child->m_services.contains( mimetype ) )
@@ -3293,8 +3294,8 @@ bool KHTMLPart::processObjectRequest( khtml::ChildFrame *child, const KURL &_url
     // completed() signal for the child by hand:
     if (url.isEmpty() || url.url() == "about:blank") {
       ReadOnlyPart *readOnlyPart = child->m_part;
-      KHTMLPart *part = dynamic_cast<KHTMLPart *>(readOnlyPart);
-      if (part) {
+      KHTMLPart *part = static_cast<KHTMLPart *>(readOnlyPart);
+      if (part && part->inherits("KHTMLPart")) {
         part->completed();
       }
     }
index 31aa9eb..5c21496 100644 (file)
@@ -290,6 +290,10 @@ private:
 
     void applyBodyScrollQuirk(khtml::RenderObject* o, ScrollBarMode& hMode, ScrollBarMode& vMode);
 
+#if APPLE_CHANGES
+    virtual bool isKHTMLView() const;
+#endif
+
     // ------------------------------------- member variables ------------------------------------
  private:
     unsigned _refCount;
index 2ce7ec5..fc05f75 100644 (file)
@@ -289,7 +289,7 @@ void RenderImage::paint(PaintInfo& i, int _tx, int _ty)
             
             if (!alt.isEmpty()) {
                 QString text = alt.string();
-                text.replace('\\', backslashAsCurrencySymbol());
+                text.replace(QChar('\\'), backslashAsCurrencySymbol());
                 p->setFont (style()->font());
                 p->setPen (style()->color());
                 int ax = _tx + leftBorder + leftPad;
index ea1448f..74ba9be 100644 (file)
@@ -1848,11 +1848,6 @@ void RenderObject::arenaDelete(RenderArena *arena, void *base)
     arena->free(*(size_t *)base, base);
 }
 
-void RenderObject::arenaDelete(RenderArena *arena)
-{
-    arenaDelete(arena, dynamic_cast<void *>(this));
-}
-
 Position RenderObject::positionForCoordinates(int x, int y, EAffinity *affinity)
 {
     if (affinity)
index 39596b5..b24c1c4 100644 (file)
@@ -860,7 +860,7 @@ protected:
 
     virtual void removeLeftoverAnonymousBoxes();
     
-    void arenaDelete(RenderArena *arena);
+    void arenaDelete(RenderArena *arena, void *objectBase);
 
 private:
     RenderStyle* m_style;
@@ -894,8 +894,6 @@ private:
     
     bool m_hasOverflowClip           : 1;
 
-    void arenaDelete(RenderArena *arena, void *objectBase);
-
     // note: do not add unnecessary bitflags, we have 32 bit already!
     friend class RenderListItem;
     friend class RenderContainer;
index 6e94d7c..9520cc2 100644 (file)
@@ -570,7 +570,7 @@ void RenderWidget::deref(RenderArena *arena)
 {
     if (_ref) _ref--; 
     if (!_ref)
-        arenaDelete(arena);
+        arenaDelete(arena, this);
 }
 
 #if APPLE_CHANGES
index 5ba38cb..18e2db1 100644 (file)
 #include "dom_xmlimpl.h"
 #include "html/html_elementimpl.h"
 #include "misc/htmltags.h"
+#include "editing/markup.h"
 #include "editing/visible_position.h"
 #include "editing/visible_text.h"
 #include "xml/dom_position.h"
 
 #include "render_block.h"
 
+using khtml::createMarkup;
 using khtml::RenderBlock;
 using khtml::RenderObject;
 
@@ -834,127 +836,11 @@ DOMString RangeImpl::toString( int &exceptioncode ) const
     return text;
 }
 
-static QString interchangeNewlineMarkupString()
+DOMString RangeImpl::toHTML() const
 {
-    static QString interchangeNewlineString;
-    if (interchangeNewlineString.length() == 0) {
-        interchangeNewlineString = "<br class=\"";
-        interchangeNewlineString += AppleInterchangeNewline;
-        interchangeNewlineString += "\">";
-    }
-    return interchangeNewlineString;
-}
-
-DOMString RangeImpl::toHTML(QPtrList<NodeImpl> *nodes, EAnnotateForInterchange annotate) const
-{
-    int exceptionCode;
-    NodeImpl *commonAncestor = commonAncestorContainer(exceptionCode);
-    NodeImpl *commonAncestorBlock = 0;
-    if (commonAncestor != 0) {
-        commonAncestorBlock = commonAncestor->enclosingBlockFlowElement();
-    }
-    if (commonAncestorBlock == 0) {
-        return "";    
-    }
-        
-    QStringList markups;
-    NodeImpl *pastEnd = pastEndNode();
-    NodeImpl *lastClosed = 0;
-    QPtrList<NodeImpl> ancestorsToClose;
-    
-    // Iterate through the nodes of the range.
-    NodeImpl *next;
-    for (NodeImpl *n = startNode(); n != pastEnd; n = next) {
-        next = n->traverseNextNode();
-        if (!n->renderer())
-            continue;
-
-        if (n->isBlockFlow() && next == pastEnd) {
-            // Don't write out an empty block.
-            continue;
-        }
-        
-        // Add the node to the markup.
-        markups.append(n->startMarkup(this, annotate));
-        if (nodes) {
-            nodes->append(n);
-        }
-        
-        if (n->firstChild() == 0) {
-            // Node has no children, add its close tag now.
-            markups.append(n->endMarkup());
-            lastClosed = n;
-            
-            // Check if the node is the last leaf of a tree.
-            if (n->nextSibling() == 0 || next == pastEnd) {
-                if (!ancestorsToClose.isEmpty()) {
-                    // Close up the ancestors.
-                    while (NodeImpl *ancestor = ancestorsToClose.last()) {
-                        if (next != pastEnd && ancestor == next->parentNode()) {
-                            break;
-                        }
-                        // Not at the end of the range, close ancestors up to sibling of next node.
-                        markups.append(ancestor->endMarkup());
-                        lastClosed = ancestor;
-                        ancestorsToClose.removeLast();
-                    }
-                } else {
-                    // No ancestors to close, but need to add ancestors not in range since next node is in another tree. 
-                    if (next != pastEnd) {
-                        NodeImpl *nextParent = next->parentNode();
-                        if (n != nextParent) {
-                            for (NodeImpl *parent = n->parent(); parent != 0 && parent != nextParent; parent = parent->parentNode()) {
-                                markups.prepend(parent->startMarkup(this, annotate));
-                                markups.append(parent->endMarkup());
-                                if (nodes) {
-                                    nodes->append(parent);
-                                }                            
-                                lastClosed = parent;
-                            }
-                        }
-                    }
-                }
-            }
-        } else {
-            // Node is an ancestor, set it to close eventually.
-            ancestorsToClose.append(n);
-        }
-    }
-    
-    // Add ancestors up to the common ancestor block so inline ancestors such as FONT and B are part of the markup.
-    for (NodeImpl *ancestor = lastClosed->parentNode(); ancestor; ancestor = ancestor->parentNode()) {
-        bool breakAtEnd = false;
-        if (commonAncestorBlock == ancestor) {
-            NodeImpl::Id id = ancestor->id();
-            // Tables and lists must be part of the markup to avoid broken structures. 
-            if (id == ID_TABLE || id == ID_OL || id == ID_UL) {
-                breakAtEnd = true;
-            } else {
-                break;
-            }
-        }
-        markups.prepend(ancestor->startMarkup(this, annotate));
-        markups.append(ancestor->endMarkup());
-        if (nodes) {
-            nodes->append(ancestor);
-        }        
-        if (breakAtEnd) {
-            break;
-        }
-    }
-    
-    if (annotate) {
-        Position pos(m_endContainer, m_endOffset);
-        NodeImpl *block = pos.node()->enclosingBlockFlowElement();
-        NodeImpl *upstreamBlock = pos.upstream().node()->enclosingBlockFlowElement();
-        if (block != upstreamBlock)
-            markups.append(interchangeNewlineMarkupString());
-    }
-    
-    return markups.join("");
+    return createMarkup(this);
 }
 
-
 DOMString RangeImpl::text() const
 {
     if (m_detached)
index b464193..62bbc6a 100644 (file)
 
 #include <qptrlist.h>
 #include "dom/dom2_range.h"
-#include "editing/html_interchange.h"
 #include "misc/shared.h"
 
-class QStringList;
-
 namespace DOM {
 
 class DocumentPtr;
@@ -72,7 +69,7 @@ public:
     DocumentFragmentImpl *cloneContents ( int &exceptioncode );
     void insertNode( NodeImpl *newNode, int &exceptioncode );
     DOMString toString ( int &exceptioncode ) const;
-    DOMString toHTML(QPtrList<NodeImpl> *nodes=NULL, EAnnotateForInterchange annotate=DoNotAnnotateForInterchange) const;
+    DOMString toHTML() const;
     DOMString text() const;
 
     DocumentFragmentImpl *createContextualFragment ( DOMString &html, int &exceptioncode ) const;
@@ -127,4 +124,3 @@ private:
 } // namespace
 
 #endif
-
index 5a26e24..2df10b6 100644 (file)
@@ -101,6 +101,7 @@ namespace DOM {
     class NodeIteratorImpl;
     class NodeListImpl;
     class ProcessingInstructionImpl;
+    class Range;
     class RangeImpl;
     class RegisteredEventListener;
     class StyleSheetImpl;
index 41ec9a3..78d6cbb 100644 (file)
@@ -270,201 +270,6 @@ NodeImpl *NodeImpl::addChild(NodeImpl *)
   return 0;
 }
 
-QString NodeImpl::toHTML() const
-{
-    return recursive_toHTML(true);
-}
-
-static QString escapeHTML( const QString& in )
-{
-    QString s;
-    for ( unsigned int i = 0; i < in.length(); ++i ) {
-        switch( in[i].latin1() ) {
-        case '&':
-            s += "&amp;";
-            break;
-        case '<':
-            s += "&lt;";
-            break;
-        case '>':
-            s += "&gt;";
-            break;
-        default:
-            s += in[i];
-        }
-    }
-
-    return s;
-}
-
-QString NodeImpl::stringValueForRange(const RangeImpl *range) const
-{
-    DOMString str = nodeValue().copy();
-    if (range) {
-        int exceptionCode;
-        if (this == range->endContainer(exceptionCode)) {
-            str.truncate(range->endOffset(exceptionCode));
-        }
-        if (this == range->startContainer(exceptionCode)) {
-            str.remove(0, range->startOffset(exceptionCode));
-        }
-    }
-    return str.string();
-}
-
-QString NodeImpl::renderedText(const RangeImpl *range) const
-{
-    QString result;
-
-    RenderObject *r = renderer();
-    if (!r)
-        return result;
-    
-    if (!isTextNode())
-        return result;
-
-    int exceptionCode;
-    const TextImpl *textNode = static_cast<const TextImpl *>(this);
-    unsigned startOffset = 0;
-    unsigned endOffset = textNode->length();
-
-    if (range && this == range->startContainer(exceptionCode))
-        startOffset = range->startOffset(exceptionCode);
-    if (range && this == range->endContainer(exceptionCode))
-        endOffset = range->endOffset(exceptionCode);
-    
-    RenderText *textRenderer = static_cast<RenderText *>(r);
-    QString str = nodeValue().string();
-    for (InlineTextBox *box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
-        unsigned start = box->m_start;
-        unsigned end = box->m_start + box->m_len;
-        if (endOffset < start)
-            break;
-        if (startOffset <= end) {
-            unsigned s = kMax(start, startOffset);
-            unsigned e = kMin(end, endOffset);
-            result.append(str.mid(s, e-s));
-
-            // now add in collapsed-away spaces if at the end of the line
-            InlineTextBox *nextBox = box->nextTextBox();
-            if (nextBox && box->root() != nextBox->root()) {
-                static QChar nbsp('0xa0');
-                static QChar space(' ');
-                // count the number of characters between the end of the
-                // current box and the start of the next box.
-                int collapsedStart = e;
-                int collapsedPastEnd = kMin((unsigned)nextBox->m_start, endOffset + 1);
-                bool addNextNonNBSP = true;
-                for (int i = collapsedStart; i < collapsedPastEnd; i++) {
-                    if (str[i] == nbsp) {
-                        result.append(str[i]);
-                        addNextNonNBSP = true;
-                    }
-                    else if (addNextNonNBSP) {
-                        result.append(str[i]);
-                        addNextNonNBSP = false;
-                    }
-                }
-            }
-        }
-    }
-    
-    return result;
-}
-
-QString NodeImpl::startMarkup(const RangeImpl *range, EAnnotateForInterchange annotate) const
-{
-    unsigned short type = nodeType();
-    if (type == Node::TEXT_NODE) {
-        DOMString str = nodeValue().copy();
-        Id parentID = parentNode()->id();
-        bool dontEscape = (parentID == ID_SCRIPT || parentID == ID_TEXTAREA || parentID == ID_STYLE);
-        if (dontEscape)
-            return stringValueForRange(range);
-        if (annotate)
-            return convertHTMLTextToInterchangeFormat(escapeHTML(renderedText(range))); 
-        return escapeHTML(stringValueForRange(range));
-    } else if (type == Node::COMMENT_NODE) {
-        return static_cast<const CommentImpl *>(this)->toString().string();
-    } else if (type != Node::DOCUMENT_NODE) {
-        QString markup = QChar('<') + nodeName().string();
-        if (type == Node::ELEMENT_NODE) {
-            const ElementImpl *el = static_cast<const ElementImpl *>(this);
-            NamedAttrMapImpl *attrs = el->attributes();
-            unsigned long length = attrs->length();
-            for (unsigned int i=0; i<length; i++) {
-                AttributeImpl *attr = attrs->attributeItem(i);
-                markup += " " + getDocument()->attrName(attr->id()).string() + "=\"" + attr->value().string() + "\"";
-            }
-        }
-        markup += isHTMLElement() ? ">" : "/>";
-        return markup;
-    }
-    return "";
-}
-
-QString NodeImpl::endMarkup(void) const
-{
-    if ((!isHTMLElement() || endTag[id()] != FORBIDDEN) && nodeType() != Node::TEXT_NODE && nodeType() != Node::DOCUMENT_NODE) {
-        return "</" + nodeName().string() + ">";
-    }
-    return "";
-}
-
-QString NodeImpl::recursive_toString(const NodeImpl *startNode, bool onlyIncludeChildren, bool includeSiblings, QPtrList<NodeImpl> *nodes)
-{
-    // Doesn't make sense to only include children and include siblings.
-    assert(!(onlyIncludeChildren && includeSiblings));
-    QString me = "";
-    for (const NodeImpl *current = startNode; current != NULL; current = includeSiblings ? current->nextSibling() : NULL) {
-        if (!onlyIncludeChildren) {
-            if (nodes) {
-                nodes->append(current);
-            }
-            me += current->startMarkup(0);
-        }        
-        if (!current->isHTMLElement() || endTag[current->id()] != FORBIDDEN) {
-            // print children
-            if (NodeImpl *n = current->firstChild()) {
-                me += recursive_toString(n, false, true, nodes);
-            }
-            // Print my ending tag
-            if (!onlyIncludeChildren) {
-                me += current->endMarkup();
-            }
-        }
-    }
-    return me;
-}
-
-QString NodeImpl::recursive_toHTML(bool onlyIncludeChildren, QPtrList<NodeImpl> *nodes) const
-{      
-    return NodeImpl::recursive_toString(this, onlyIncludeChildren, false, nodes);
-}
-
-void NodeImpl::recursive_completeURLs(QString baseURL)
-{
-    if (nodeType() == Node::ELEMENT_NODE) {
-        ElementImpl *el = static_cast<ElementImpl *>(this);
-        NamedAttrMapImpl *attrs = el->attributes();
-        unsigned long length = attrs->length();
-        for (unsigned int i=0; i<length; i++) {
-            AttributeImpl *attr = attrs->attributeItem(i);
-            if (el->isURLAttribute(attr)) {
-                el->setAttribute(attr->id(), KURL(baseURL, attr->value().string()).url());
-            }
-        }
-    }
-    
-    NodeImpl *n;
-    if ((n = firstChild())) {
-        n->recursive_completeURLs(baseURL);
-    }
-    if ((n = nextSibling())) {
-        n->recursive_completeURLs(baseURL);
-    }
-}
-
 bool NodeImpl::isContentEditable() const
 {
     return m_parent ? m_parent->isContentEditable() : false;
index f6f69a4..39d932b 100644 (file)
@@ -28,7 +28,6 @@
 #include "dom/dom_misc.h"
 #include "dom/dom_string.h"
 #include "dom/dom_node.h"
-#include "editing/html_interchange.h"
 #include "misc/helper.h"
 #include "misc/shared.h"
 #include "dom_atomicstring.h"
@@ -51,15 +50,10 @@ namespace khtml {
 
 namespace DOM {
 
-class CSSStyleDeclarationImpl;
 class DocumentImpl;
 class ElementImpl;
 class EventImpl;
-class NamedNodeMapImpl;
 class NodeListImpl;
-class Position;
-class Range;
-class RangeImpl;
 class RegisteredEventListener;
 
 // The namespace used for XHTML elements
@@ -261,14 +255,6 @@ public:
     virtual bool isMouseFocusable() const;
     
     virtual bool isInline() const;
-    QString stringValueForRange(const RangeImpl *range) const;
-    QString renderedText(const RangeImpl *range) const;
-    QString startMarkup(const RangeImpl *range, EAnnotateForInterchange annotate=DoNotAnnotateForInterchange) const;
-    QString endMarkup(void) const;
-    virtual QString toHTML() const;
-    QString recursive_toHTML(bool onlyIncludeChildren=false, QPtrList<NodeImpl> *nodes=NULL) const;
-    static QString recursive_toString(const NodeImpl *startNode, bool onlyIncludeChildren, bool includeSiblings, QPtrList<NodeImpl> *nodes);
-    void recursive_completeURLs(QString baseURL);
     
     virtual bool isContentEditable() const;
     virtual QRect getRect() const;
index 6530bb8..e062ba1 100644 (file)
@@ -33,6 +33,7 @@
 #include "dom_nodeimpl.h"
 #include "dom_positioniterator.h"
 #include "dom2_range.h"
+#include "dom2_rangeimpl.h"
 #include "dom2_viewsimpl.h"
 #include "helper.h"
 #include "htmltags.h"
@@ -808,12 +809,32 @@ void Position::formatForDebugger(char *buffer, unsigned length) const
 
 Position startPosition(const Range &r)
 {
+    if (r.isNull() || r.isDetached())
+        return Position();
     return Position(r.startContainer().handle(), r.startOffset());
 }
 
+Position startPosition(const RangeImpl *r)
+{
+    if (!r || r->isDetached())
+        return Position();
+    int exceptionCode;
+    return Position(r->startContainer(exceptionCode), r->startOffset(exceptionCode));
+}
+
 Position endPosition(const Range &r)
 {
+    if (r.isNull() || r.isDetached())
+        return Position();
     return Position(r.endContainer().handle(), r.endOffset());
 }
 
+Position endPosition(const RangeImpl *r)
+{
+    if (!r || r->isDetached())
+        return Position();
+    int exceptionCode;
+    return Position(r->endContainer(exceptionCode), r->endOffset(exceptionCode));
+}
+
 } // namespace DOM
index 5b47ca7..c40dd32 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2004 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
@@ -40,6 +40,8 @@ public:
     int frameWidth() const;
 
 private:
+    virtual bool isQFrame() const;
+
     int _frameStyle;
 };
 
index 24ae6a3..e151234 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2004 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
@@ -57,3 +57,8 @@ int QFrame::frameWidth() const
         return 3;
     return 0;
 }
+
+bool QFrame::isQFrame() const
+{
+    return true;
+}
index f88d1ab..ddc62f4 100644 (file)
@@ -318,13 +318,11 @@ public:
     void didTellBridgeAboutLoad(const QString &urlString);
     bool haveToldBridgeAboutLoad(const QString &urlString);
 
-    KJS::Bindings::Instance *getEmbedInstanceForView (NSView *aView);
-    KJS::Bindings::Instance *getAppletInstanceForView (NSView *aView);
+    KJS::Bindings::Instance *getEmbedInstanceForView(NSView *aView);
+    KJS::Bindings::Instance *getAppletInstanceForView(NSView *aView);
     void addPluginRootObject(const KJS::Bindings::RootObject *root);
     void cleanupPluginRootObjects();
     
-    DOM::DocumentFragmentImpl *documentFragmentWithText(NSString *text);
-    
     void registerCommandForUndo(const khtml::EditCommandPtr &);
     void registerCommandForRedo(const khtml::EditCommandPtr &);
     void clearUndoRedoOperations();
@@ -393,6 +391,8 @@ private:
 
     khtml::RenderStyle *styleForSelectionStart(DOM::NodeImpl *&nodeToRemove) const;
 
+    virtual bool isKHTMLPart() const;
+
     WebCoreBridge *_bridge;
     
     KWQSignal _started;
index 78bc0df..10f9c58 100644 (file)
@@ -195,6 +195,11 @@ void KHTMLPart::started(Job *j)
     KWQ(this)->_started.call(j);
 }
 
+bool KHTMLView::isKHTMLView() const
+{
+    return true;
+}
+
 static void redirectionTimerMonitor(void *context)
 {
     KWQKHTMLPart *kwq = static_cast<KWQKHTMLPart *>(context);
@@ -839,7 +844,7 @@ KHTMLView *KWQKHTMLPart::view() const
 void KWQKHTMLPart::setTitle(const DOMString &title)
 {
     QString text = title.string();
-    text.replace('\\', backslashAsCurrencySymbol());
+    text.replace(QChar('\\'), backslashAsCurrencySymbol());
 
     KWQ_BLOCK_EXCEPTIONS;
     [_bridge setTitle:text.getNSString()];
@@ -849,7 +854,7 @@ void KWQKHTMLPart::setTitle(const DOMString &title)
 void KWQKHTMLPart::setStatusBarText(const QString &status)
 {
     QString text = status;
-    text.replace('\\', backslashAsCurrencySymbol());
+    text.replace(QChar('\\'), backslashAsCurrencySymbol());
 
     KWQ_BLOCK_EXCEPTIONS;
     [_bridge setStatusText:text.getNSString()];
@@ -1767,7 +1772,7 @@ void KWQKHTMLPart::sendScrollEvent()
 void KWQKHTMLPart::runJavaScriptAlert(const QString &message)
 {
     QString text = message;
-    text.replace('\\', backslashAsCurrencySymbol());
+    text.replace(QChar('\\'), backslashAsCurrencySymbol());
     KWQ_BLOCK_EXCEPTIONS;
     [_bridge runJavaScriptAlertPanelWithMessage:text.getNSString()];
     KWQ_UNBLOCK_EXCEPTIONS;
@@ -1776,7 +1781,7 @@ void KWQKHTMLPart::runJavaScriptAlert(const QString &message)
 bool KWQKHTMLPart::runJavaScriptConfirm(const QString &message)
 {
     QString text = message;
-    text.replace('\\', backslashAsCurrencySymbol());
+    text.replace(QChar('\\'), backslashAsCurrencySymbol());
 
     KWQ_BLOCK_EXCEPTIONS;
     return [_bridge runJavaScriptConfirmPanelWithMessage:text.getNSString()];
@@ -1788,9 +1793,9 @@ bool KWQKHTMLPart::runJavaScriptConfirm(const QString &message)
 bool KWQKHTMLPart::runJavaScriptPrompt(const QString &prompt, const QString &defaultValue, QString &result)
 {
     QString promptText = prompt;
-    promptText.replace('\\', backslashAsCurrencySymbol());
+    promptText.replace(QChar('\\'), backslashAsCurrencySymbol());
     QString defaultValueText = defaultValue;
-    defaultValueText.replace('\\', backslashAsCurrencySymbol());
+    defaultValueText.replace(QChar('\\'), backslashAsCurrencySymbol());
 
     KWQ_BLOCK_EXCEPTIONS;
     NSString *returnedText = nil;
@@ -1800,7 +1805,7 @@ bool KWQKHTMLPart::runJavaScriptPrompt(const QString &prompt, const QString &def
 
     if (ok) {
         result = QString::fromNSString(returnedText);
-        result.replace(backslashAsCurrencySymbol(), '\\');
+        result.replace(backslashAsCurrencySymbol(), QChar('\\'));
     }
 
     return ok;
@@ -2966,7 +2971,7 @@ NSAttributedString *KWQKHTMLPart::attributedString(NodeImpl *_start, int startOf
                     }
                 }
                 
-                text.replace('\\', renderer->backslashAsCurrencySymbol());
+                text.replace(QChar('\\'), renderer->backslashAsCurrencySymbol());
     
                 if (text.length() > 0 || needSpace) {
                     NSMutableDictionary *attrs = [[NSMutableDictionary alloc] init];
@@ -3817,87 +3822,6 @@ void KWQKHTMLPart::cleanupPluginRootObjects()
     }
 }
 
-static NSString *nbspSpaceString = 0;
-static NSString *nbspNBSPSpaceString = 0;
-
-DocumentFragmentImpl *KWQKHTMLPart::documentFragmentWithText(NSString *text)
-{
-    if (!xmlDocImpl())
-        return 0;
-
-    DocumentFragmentImpl *fragment = xmlDocImpl()->createDocumentFragment();
-    NSMutableString *string = [text mutableCopy];
-
-    // Replace tabs with four plain spaces.
-    // These spaces will get converted along with the other existing spaces below.
-    [string replaceOccurrencesOfString:@"\t" withString:@"    " options:0 range:NSMakeRange(0, [string length])];
-
-    if (!nbspSpaceString) {
-        unichar nbspSpace[] = { 0xa0, ' ' };
-        nbspSpaceString = [[NSString alloc] initWithCharacters:nbspSpace length:2];
-    }
-    
-    if (!nbspNBSPSpaceString) {
-        unichar nbspNBSPSpace[] = { 0xa0, 0xa0, ' ' };
-        nbspNBSPSpaceString = [[NSString alloc] initWithCharacters:nbspNBSPSpace length:3];
-    }
-
-    unsigned stringLength = [string length];
-    NSRange range = NSMakeRange(0, stringLength);
-    while (1) {
-        // FIXME: This only converts plain old spaces, and does not
-        // deal with more exotic whitespace. Note that we want to 
-        // leave newlines and returns alone at this point anyway, 
-        // since those are handled specially later.
-        NSRange replaceRange = [string rangeOfString:@"  " options:NSLiteralSearch range:range];
-        if (replaceRange.location == NSNotFound)
-            break;
-            
-        // Found two adjoining spaces.
-        // Now, lookahead to see if these two spaces are followed by:
-        //   1. another space and then a non-space
-        //   2. another space and then the end of the string
-        // If either 1 or 2 is true, replace the three spaces found with nbsp+nbsp+space, 
-        // otherwise, replace the first two spaces with nbsp+space.
-        unsigned lookahead = replaceRange.location + 2;
-        if ((lookahead + 2 < stringLength && [string characterAtIndex:lookahead] == ' ' && [string characterAtIndex:lookahead + 1] != ' ') ||
-            (lookahead + 1 == stringLength && [string characterAtIndex:lookahead] == ' ')) {
-            replaceRange.length = 3;
-            [string replaceCharactersInRange:replaceRange withString:nbspNBSPSpaceString];
-        }
-        else {
-            [string replaceCharactersInRange:replaceRange withString:nbspSpaceString];
-        }
-        range.location = replaceRange.location + 2;
-        range.length = stringLength - range.location;
-    }
-    
-    // Handle line endings, replacing them with BR elements.
-    [string replaceOccurrencesOfString:@"\r\n" withString:@"\n" options:0 range:NSMakeRange(0, [string length])];
-    [string replaceOccurrencesOfString:@"\r" withString:@"\n" options:0 range:NSMakeRange(0, [string length])];
-    NSArray *array = [string componentsSeparatedByString:@"\n"];
-    [string release];
-    int count = [array count];
-    int i;
-    for (i = 0; i < count; i++) {
-        int exceptionCode = 0;
-        if (i != 0) {
-            ElementImpl *breakNode = xmlDocImpl()->createHTMLElement("br", exceptionCode);
-            ASSERT(exceptionCode == 0);
-            fragment->appendChild(breakNode, exceptionCode);
-            ASSERT(exceptionCode == 0);
-        }
-        NSString *component = (NSString *)[array objectAtIndex:i];
-        if ([component length] > 0) {
-            NodeImpl *textNode = xmlDocImpl()->createTextNode(component);
-            fragment->appendChild(textNode, exceptionCode);
-        }
-    }
-    
-
-    return fragment;
-}
-
 void KWQKHTMLPart::registerCommandForUndo(const EditCommandPtr &cmd)
 {
     ASSERT(cmd.get());
@@ -4183,3 +4107,8 @@ bool KWQKHTMLPart::isCharacterSmartReplaceExempt(const QChar &c, bool isPrevious
 {
     return [_bridge isCharacterSmartReplaceExempt:c.unicode() isPreviousCharacter:isPreviousChar];
 }
+
+bool KWQKHTMLPart::isKHTMLPart() const
+{
+    return true;
+}
index 0acf4bf..098f0cc 100644 (file)
@@ -81,6 +81,8 @@ public:
     virtual bool closeURL() = 0;
 
 private:
+    virtual bool isKPartsReadOnlyPart() const;
+
     QObject *_parent;
     QString _name;
 };
index 9402e0a..4a41ff8 100644 (file)
@@ -36,4 +36,9 @@ void ReadOnlyPart::setName(const QString &name)
     _name = name; 
 }
 
-};
+bool ReadOnlyPart::isKPartsReadOnlyPart() const
+{
+    return true;
+}
+
+}
index ff64dcc..e785d27 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2004 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
@@ -130,6 +130,12 @@ private:
     
     static bool _defersTimers;
 
+    virtual bool isKHTMLPart() const;
+    virtual bool isKHTMLView() const;
+    virtual bool isKPartsReadOnlyPart() const;
+    virtual bool isQFrame() const;
+    virtual bool isQScrollView() const;
+
     friend class KWQGuardedPtrBase;
     friend class KWQSignal;
     friend class KWQObjectSenderScope;
index 3cdeb71..0df2322 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2004 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
@@ -358,31 +358,51 @@ void QObject::setDefersTimers(bool defers)
 
 @end
 
-// special includes only for inherits
-
-#import "khtml_part.h"
-#import "khtmlview.h"
-
 bool QObject::inherits(const char *className) const
 {
     if (strcmp(className, "KHTMLPart") == 0) {
-        return dynamic_cast<const KHTMLPart *>(this);
+        return isKHTMLPart();
     }
     if (strcmp(className, "KHTMLView") == 0) {
-        return dynamic_cast<const KHTMLView *>(this);
+        return isKHTMLView();
     }
     if (strcmp(className, "KParts::Factory") == 0) {
         return false;
     }
     if (strcmp(className, "KParts::ReadOnlyPart") == 0) {
-        return dynamic_cast<const KParts::ReadOnlyPart *>(this);
+        return isKPartsReadOnlyPart();
     }
     if (strcmp(className, "QFrame") == 0) {
-        return dynamic_cast<const QFrame *>(this);
+        return isQFrame();
     }
     if (strcmp(className, "QScrollView") == 0) {
-        return dynamic_cast<const QScrollView *>(this);
+        return isQScrollView();
     }
     ERROR("class name %s not recognized", className);
     return false;
 }
+
+bool QObject::isKHTMLPart() const
+{
+    return false;
+}
+
+bool QObject::isKHTMLView() const
+{
+    return false;
+}
+
+bool QObject::isKPartsReadOnlyPart() const
+{
+    return false;
+}
+
+bool QObject::isQFrame() const
+{
+    return false;
+}
+
+bool QObject::isQScrollView() const
+{
+    return false;
+}
index c5bb9d7..02cb0b0 100644 (file)
@@ -269,8 +269,9 @@ static void write(QTextStream &ts, const RenderObject &o, int indent = 0)
     }
     
     if (o.isWidget()) {
-        KHTMLView *view = dynamic_cast<KHTMLView *>(static_cast<const RenderWidget &>(o).widget());
-        if (view) {
+        QWidget *widget = static_cast<const RenderWidget &>(o).widget();
+        if (widget && widget->inherits("KHTMLView")) {
+            KHTMLView *view = static_cast<KHTMLView *>(widget);
             RenderObject *root = KWQ(view->part())->renderer();
             if (root) {
                 view->layout();
@@ -373,8 +374,12 @@ static QString nodePositionRelativeToRoot(NodeImpl *node, NodeImpl *root)
 
 static void writeSelection(QTextStream &ts, const RenderObject *o)
 {
-    DocumentImpl *doc = dynamic_cast<DocumentImpl *>(o->element());
-    if (!doc || !doc->part())
+    NodeImpl *n = o->element();
+    if (!n || !n->isDocumentNode())
+        return;
+
+    DocumentImpl *doc = static_cast<DocumentImpl *>(n);
+    if (!doc->part())
         return;
     
     Selection selection = doc->part()->selection();
index 06ac4f8..dfee243 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2004 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
@@ -94,6 +94,9 @@ public:
     void ensureRectVisibleCentered(const QRect &r, bool forceCentering=false);
         
     NSView *getDocumentView() const;
+
+private:
+    virtual bool isQScrollView() const;
 };
 
 #endif
index 222a4a2..568b6d5 100644 (file)
@@ -491,3 +491,8 @@ NSView *QScrollView::getDocumentView() const
     
     return nil;
 }
+
+bool QScrollView::isQScrollView() const
+{
+    return true;
+}
index d89bed8..1b3f754 100644 (file)
@@ -329,7 +329,7 @@ void KWQSlot::call(KIO::Job *job, NSData *allData) const
             return;
     }
     
-    call();
+    call(job);
 }
 
 void KWQSlot::call(KIO::Job *job, NSURLResponse *response) const
index b7d958d..93579c4 100644 (file)
@@ -517,6 +517,9 @@ public:
     QString &prepend(const QString &);
     QString &remove(uint, uint);
     QString &replace(uint index, uint len, const QString &s);
+    QString &replace(char, const QString &);
+    QString &replace(QChar, const QString &);
+    QString &replace(const QString &, const QString &);
     QString &replace(const QRegExp &, const QString &);
     QString &replace(QChar, QChar);
 
index 6aacfb4..0fc2adb 100644 (file)
@@ -2488,6 +2488,45 @@ QString &QString::replace( uint index, uint len, const QString &str )
     return remove(index, len).insert(index, str);
 }
 
+QString &QString::replace(char pattern, const QString &str)
+{
+    int slen = str.dataHandle[0]->_length;
+    int index = 0;
+    while ((index = find(pattern, index)) >= 0) {
+        replace(index, 1, str);
+        index += slen;
+    }
+    return *this;
+}
+
+
+QString &QString::replace(QChar pattern, const QString &str)
+{
+    int slen = str.dataHandle[0]->_length;
+    int index = 0;
+    while ((index = find(pattern, index)) >= 0) {
+        replace(index, 1, str);
+        index += slen;
+    }
+    return *this;
+}
+
+
+QString &QString::replace(const QString &pattern, const QString &str)
+{
+    if (pattern.isEmpty())
+        return *this;
+    int plen = pattern.dataHandle[0]->_length;
+    int slen = str.dataHandle[0]->_length;
+    int index = 0;
+    while ((index = find(pattern, index)) >= 0) {
+        replace(index, plen, str);
+        index += slen;
+    }
+    return *this;
+}
+
+
 QString &QString::replace(const QRegExp &qre, const QString &str)
 {
     if ( isEmpty() )
index 480a2ee..f8f67e2 100644 (file)
@@ -147,7 +147,7 @@ QCString QTextCodec::fromUnicode(const QString &qcs) const
     // FIXME: Since there's no "force ASCII range" mode in CFString, we change the backslash into a yen sign.
     // Encoding will change the yen sign back into a backslash.
     QString copy = qcs;
-    copy.replace('\\', backslashAsCurrencySymbol());
+    copy.replace(QChar('\\'), backslashAsCurrencySymbol());
     CFStringRef cfs = copy.getCFString();
 
     CFRange range = CFRangeMake(0, CFStringGetLength(cfs));
index 338e53e..2a5027e 100644 (file)
@@ -44,6 +44,7 @@
 #import "kjs_proxy.h"
 #import "kjs_window.h"
 #import "loader.h"
+#import "markup.h"
 #import "render_canvas.h"
 #import "render_frames.h"
 #import "render_image.h"
@@ -102,11 +103,14 @@ using DOM::NodeImpl;
 using DOM::Position;
 using DOM::Range;
 
+using khtml::ChildrenOnly;
+using khtml::createMarkup;
 using khtml::Decoder;
 using khtml::DeleteSelectionCommand;
 using khtml::EAffinity;
 using khtml::EditCommandPtr;
 using khtml::ETextGranularity;
+using khtml::IncludeNode;
 using khtml::MoveSelectionCommand;
 using khtml::parseURL;
 using khtml::RenderCanvas;
@@ -148,7 +152,7 @@ NSString *WebCoreElementTitleKey =              @"WebCoreElementTitle"; // not i
 
 NSString *WebCorePageCacheStateKey =            @"WebCorePageCacheState";
 
-@interface WebCoreBridge (WebCoreBridgePrivate)
+@interface WebCoreBridge (WebCoreBridgeInternal)
 - (RootObject *)executionContextForView:(NSView *)aView;
 @end
 
@@ -538,28 +542,22 @@ static bool initializedKJS = FALSE;
 
 - (NSString *)markupStringFromNode:(DOMNode *)node nodes:(NSArray **)nodes
 {
-    QPtrList<NodeImpl> *nodeList = NULL;
+    // FIXME: This is never "for interchange". Is that right? See the next method.
+    QPtrList<NodeImpl> nodeList;
+    NSString *markupString = createMarkup([node _nodeImpl], IncludeNode, nodes ? &nodeList : 0).getNSString();
     if (nodes) {
-        nodeList = new QPtrList<NodeImpl>;
-    }
-    NSString *markupString = [node _nodeImpl]->recursive_toHTML(false, nodeList).getNSString();
-    if (nodes) {
-        *nodes = [self nodesFromList:nodeList];
-        delete nodeList;
+        *nodes = [self nodesFromList:&nodeList];
     }
     return [self _stringWithDocumentTypeStringAndMarkupString:markupString];
 }
 
 - (NSString *)markupStringFromRange:(DOMRange *)range nodes:(NSArray **)nodes
 {
-    QPtrList<NodeImpl> *nodeList = NULL;
-    if (nodes) {
-        nodeList = new QPtrList<NodeImpl>;
-    }
-    NSString *markupString = [range _rangeImpl]->toHTML(nodeList, AnnotateForInterchange).string().getNSString();
+    // FIXME: This is always "for interchange". Is that right? See the previous method.
+    QPtrList<NodeImpl> nodeList;
+    NSString *markupString = createMarkup([range _rangeImpl], nodes ? &nodeList : 0, AnnotateForInterchange).getNSString();
     if (nodes) {
-        *nodes = [self nodesFromList:nodeList];
-        delete nodeList;
+        *nodes = [self nodesFromList:&nodeList];
     }
     return [self _stringWithDocumentTypeStringAndMarkupString:markupString];
 }
@@ -567,14 +565,14 @@ static bool initializedKJS = FALSE;
 - (NSString *)selectedString
 {
     QString text = _part->selectedText();
-    text.replace('\\', _part->backslashAsCurrencySymbol());
+    text.replace(QChar('\\'), _part->backslashAsCurrencySymbol());
     return [[text.getNSString() copy] autorelease];
 }
 
 - (NSString *)stringForRange:(DOMRange *)range
 {
     QString text = _part->text([range _rangeImpl]);
-    text.replace('\\', _part->backslashAsCurrencySymbol());
+    text.replace(QChar('\\'), _part->backslashAsCurrencySymbol());
     return [[text.getNSString() copy] autorelease];
 }
 
@@ -741,7 +739,7 @@ static BOOL nowPrinting(WebCoreBridge *self)
     }
     NSObject *copiedNode = [copier nodeWithName:node->nodeName().string().getNSString()
                                           value:node->nodeValue().string().getNSString()
-                                         source:node->recursive_toHTML(true).getNSString()
+                                         source:createMarkup(node, ChildrenOnly).getNSString()
                                        children:children];
     [children release];
     return copiedNode;
@@ -990,7 +988,7 @@ static HTMLFormElementImpl *formElementFromDOMElement(DOMElement *element)
             if (!title.isNull()) {
                 // We found a node with a title.
                 QString titleText = title.string();
-                titleText.replace('\\', _part->backslashAsCurrencySymbol());
+                titleText.replace(QChar('\\'), _part->backslashAsCurrencySymbol());
                 [element setObject:titleText.getNSString() forKey:WebCoreElementTitleKey];
                 break;
             }
@@ -1004,7 +1002,7 @@ static HTMLFormElementImpl *formElementFromDOMElement(DOMElement *element)
         const AtomicString& title = e->getAttribute(ATTR_TITLE);
         if (!title.isEmpty()) {
             QString titleText = title.string();
-            titleText.replace('\\', _part->backslashAsCurrencySymbol());
+            titleText.replace(QChar('\\'), _part->backslashAsCurrencySymbol());
             [element setObject:titleText.getNSString() forKey:WebCoreElementLinkTitleKey];
         }
         
@@ -1072,7 +1070,7 @@ static HTMLFormElementImpl *formElementFromDOMElement(DOMElement *element)
                 alt = static_cast<HTMLImageElementImpl *>(i)->altText();
             if (!alt.isNull()) {
                 QString altText = alt.string();
-                altText.replace('\\', _part->backslashAsCurrencySymbol());
+                altText.replace(QChar('\\'), _part->backslashAsCurrencySymbol());
                 [element setObject:altText.getNSString() forKey:WebCoreElementImageAltStringKey];
             }
         }
@@ -1550,17 +1548,10 @@ static HTMLFormElementImpl *formElementFromDOMElement(DOMElement *element)
 
 - (DOMDocumentFragment *)documentFragmentWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString 
 {
-    DocumentImpl *document = _part->xmlDocImpl();
-    HTMLElementImpl *element = static_cast<HTMLElementImpl *>(document->documentElement());
-    DocumentFragmentImpl *fragment = element->createContextualFragment(markupString);
-    ASSERT(fragment);
-    
-    if ([baseURLString length] > 0) {
-        DOM::DOMString baseURL = baseURLString;
-        if (baseURL != document->baseURL()) {
-            fragment->recursive_completeURLs(baseURL.string());
-        }
-    }
+    if (!_part || !_part->xmlDocImpl())
+        return 0;
+
+    DocumentFragmentImpl *fragment = createFragmentFromMarkup(_part->xmlDocImpl(), QString::fromNSString(markupString), QString::fromNSString(baseURLString));
     return [DOMDocumentFragment _documentFragmentWithImpl:fragment];
 }
 
@@ -1569,7 +1560,7 @@ static HTMLFormElementImpl *formElementFromDOMElement(DOMElement *element)
     if (!_part || !_part->xmlDocImpl() || !text)
         return 0;
 
-    return [DOMDocumentFragment _documentFragmentWithImpl:_part->documentFragmentWithText(text)];
+    return [DOMDocumentFragment _documentFragmentWithImpl:createFragmentFromText(_part->xmlDocImpl(), QString::fromNSString(text))];
 }
 
 - (void)replaceSelectionWithFragment:(DOMDocumentFragment *)fragment selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace
@@ -1963,7 +1954,7 @@ static HTMLFormElementImpl *formElementFromDOMElement(DOMElement *element)
 
 @end
 
-@implementation WebCoreBridge (WebCoreBridgePrivate)
+@implementation WebCoreBridge (WebCoreBridgeInternal)
 
 - (RootObject *)executionContextForView:(NSView *)aView
 {
@@ -1974,4 +1965,5 @@ static HTMLFormElementImpl *formElementFromDOMElement(DOMElement *element)
     part->addPluginRootObject(root);
     return root;
 }
+
 @end