patch to add support for designMode and contentEditable attributes

Ken Kocienda kocienda at apple.com
Tue Oct 14 14:08:48 CEST 2003


This patch adds support for designMode and contentEditable attributes. 
This patch probably has an amount of overlap with some work Leo 
Savernik has done recently with caret navigation and tracking inherited 
attributes that have to do with editing. At this time, I did not 
attempt to resolve these differences.

-------------- next part --------------
Index: khtml/khtml_part.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/khtml_part.cpp,v
retrieving revision 1.156
diff -u -r1.156 khtml/khtml_part.cpp
--- khtml/khtml_part.cpp	2003/10/08 01:49:31	1.156
+++ khtml/khtml_part.cpp	2003/10/14 15:22:39
@@ -2092,6 +2092,30 @@
   d->m_onlyLocalReferences = enable;
 }
 
+void KHTMLPart::setEditMode(TristateFlag flag)
+{
+    d->m_inEditMode = flag;
+}
+
+TristateFlag KHTMLPart::editMode() const
+{ 
+    if (d->m_inEditMode != FlagNone)
+        return d->m_inEditMode == FlagEnabled ? FlagEnabled : FlagDisabled;
+    
+    KHTMLPart *part = parentPart();
+    while (part) {
+        if (part->d->m_inEditMode != FlagNone)
+            return part->d->m_inEditMode == FlagEnabled ? FlagEnabled : FlagDisabled;
+        part = part->parentPart();
+    }
+    return FlagNone;
+}
+
+bool KHTMLPart::inEditMode() const
+{
+    return editMode() == FlagEnabled;
+}
+
 void KHTMLPart::findTextBegin(NodeImpl *startNode, int startPos)
 {
     d->m_findPos = startPos;
@@ -3708,7 +3732,7 @@
   return (!(*it).m_frame.isNull());
 }
 
-KHTMLPart *KHTMLPart::parentPart()
+KHTMLPart *KHTMLPart::parentPart() const
 {
   if ( !parent() || !parent()->inherits( "KHTMLPart" ) )
     return 0L;
Index: khtml/khtml_part.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/khtml_part.h,v
retrieving revision 1.50
diff -u -r1.50 khtml/khtml_part.h
--- khtml/khtml_part.h	2003/10/07 00:01:43	1.50
+++ khtml/khtml_part.h	2003/10/14 15:22:39
@@ -29,6 +29,7 @@
 
 #include "dom/html_document.h"
 #include "dom/dom2_range.h"
+#include "dom/dom_misc.h"
 
 #include <kparts/part.h>
 #include <kparts/browserextension.h>
@@ -61,6 +62,8 @@
   class EventListener;
 };
 
+using DOM::TristateFlag;
+
 namespace khtml
 {
   class DocLoader;
@@ -94,7 +97,7 @@
  * This class is khtml's main class. It features an almost complete
  * web browser, and html renderer.
  *
- * The easiest way to use this class (if you just want to display a an HTML
+ * The easiest way to use this class (if you just want to display an HTML
  * page at some URL) is the following:
  *
  * <pre>
@@ -345,10 +348,14 @@
   void setOnlyLocalReferences(bool enable);
 
   /**
-   * Returnd whether references should be loaded ( default false )
+   * Returns whether references should be loaded ( default false )
    **/
   bool onlyLocalReferences() const;
 
+  void setEditMode(TristateFlag enable);
+  TristateFlag editMode() const;
+  bool inEditMode() const;
+
 #ifndef KDE_NO_COMPAT
   void enableJScript(bool e) { setJScriptEnabled(e); }
   void enableJava(bool e) { setJavaEnabled(e); }
@@ -639,7 +646,7 @@
    *
    *  Returns 0L otherwise.
    */
-  KHTMLPart *parentPart();
+  KHTMLPart *parentPart() const;
 
   /**
    * Returns a list of names of all frame (including iframe) objects of
Index: khtml/khtmlpart_p.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/khtmlpart_p.h,v
retrieving revision 1.26
diff -u -r1.26 khtml/khtmlpart_p.h
--- khtml/khtmlpart_p.h	2003/09/13 02:11:34	1.26
+++ khtml/khtmlpart_p.h	2003/10/14 15:22:39
@@ -42,6 +42,7 @@
 #include "misc/decoder.h"
 #include "java/kjavaappletcontext.h"
 #include "ecma/kjs_proxy.h"
+#include "dom/dom_misc.h"
 
 namespace KIO
 {
@@ -151,6 +152,8 @@
     m_bPluginsOverride = false;
     m_onlyLocalReferences = false;
 
+    m_inEditMode = DOM::FlagNone;
+
     m_metaRefreshEnabled = true;
     m_bHTTPRefresh = false;
 
@@ -181,6 +184,7 @@
             m_ssl_in_use = part->d->m_ssl_in_use;
 #endif
             m_onlyLocalReferences = part->d->m_onlyLocalReferences;
+            m_inEditMode = part->d->m_inEditMode;
             m_zoomFactor = part->d->m_zoomFactor;
         }
     }
@@ -359,6 +363,8 @@
   bool m_bCleared:1;
   bool m_bSecurityInQuestion:1;
   bool m_focusNodeRestored:1;
+
+  TristateFlag m_inEditMode;
 
   int m_focusNodeNumber;
 
Index: khtml/dom/dom_misc.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/dom/dom_misc.h,v
retrieving revision 1.6
diff -u -r1.6 khtml/dom/dom_misc.h
--- khtml/dom/dom_misc.h	2002/06/04 00:18:58	1.6
+++ khtml/dom/dom_misc.h	2003/10/14 15:22:39
@@ -53,6 +53,8 @@
     unsigned int _ref;
 };
 
+enum TristateFlag { FlagNone, FlagEnabled, FlagDisabled };
+
 }; // namespace
 
 #endif
Index: khtml/dom/html_document.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/dom/html_document.cpp,v
retrieving revision 1.15
diff -u -r1.15 khtml/dom/html_document.cpp
--- khtml/dom/html_document.cpp	2003/10/03 21:49:11	1.15
+++ khtml/dom/html_document.cpp	2003/10/14 15:22:39
@@ -237,3 +237,15 @@
     return new NameNodeListImpl(impl, elementName);
 }
 
+DOMString HTMLDocument::designMode() const
+{
+    if(!impl) return "inherit";
+    return ((HTMLDocumentImpl *)impl)->designMode();
+}
+
+void HTMLDocument::setDesignMode(const DOMString &s)
+{
+    if(impl)
+        ((HTMLDocumentImpl *)impl)->setDesignMode(s);
+}
+
Index: khtml/dom/html_document.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/dom/html_document.h,v
retrieving revision 1.4
diff -u -r1.4 khtml/dom/html_document.h
--- khtml/dom/html_document.h	2002/09/27 03:06:08	1.4
+++ khtml/dom/html_document.h	2003/10/14 15:22:39
@@ -292,6 +292,10 @@
      * a document.
      */
     HTMLCollection all() const;
+
+    DOMString designMode() const;
+    void setDesignMode(const DOMString &);
+
 };
 
 }; //namespace
Index: khtml/dom/html_element.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/dom/html_element.cpp,v
retrieving revision 1.8
diff -u -r1.8 khtml/dom/html_element.cpp
--- khtml/dom/html_element.cpp	2003/02/25 20:00:15	1.8
+++ khtml/dom/html_element.cpp	2003/10/14 15:22:39
@@ -175,3 +175,26 @@
 	Node::operator = (other);
     }   
 }
+
+bool HTMLElement::isContentEditable() const
+{
+    if(!impl) return false;
+    return static_cast<HTMLElementImpl *>(impl)->isContentEditable();
+}
+
+DOMString HTMLElement::contentEditable() const {
+    if(!impl) return "inherit";
+    return static_cast<HTMLElementImpl *>(impl)->contentEditable();
+}
+
+void HTMLElement::setContentEditable(const DOMString &enabled) {
+    if(!impl)
+        throw DOMException(DOMException::INVALID_STATE_ERR);
+    if (enabled == "inherit") {
+        int exceptionCode;
+        static_cast<HTMLElementImpl *>(impl)->removeAttribute(ATTR_CONTENTEDITABLE, exceptionCode);
+    }
+    else
+        static_cast<HTMLElementImpl *>(impl)->setAttribute(ATTR_CONTENTEDITABLE, enabled.isEmpty() ? "true" : enabled);
+}
+
Index: khtml/dom/html_element.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/dom/html_element.h,v
retrieving revision 1.4
diff -u -r1.4 khtml/dom/html_element.h
--- khtml/dom/html_element.h	2002/06/10 20:07:35	1.4
+++ khtml/dom/html_element.h	2003/10/14 15:22:39
@@ -200,6 +200,10 @@
      */
     void addCSSProperty( const DOMString &property, const DOMString &value );
 
+    bool isContentEditable() const;
+    DOMString contentEditable() const;
+    void setContentEditable(const DOMString &enabled);
+
 protected:
     /*
      * @internal
Index: khtml/ecma/kjs_html.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/ecma/kjs_html.cpp,v
retrieving revision 1.40
diff -u -r1.40 khtml/ecma/kjs_html.cpp
--- khtml/ecma/kjs_html.cpp	2003/08/06 22:15:13	1.40
+++ khtml/ecma/kjs_html.cpp	2003/10/14 15:22:39
@@ -122,7 +122,7 @@
 const ClassInfo KJS::HTMLDocument::info =
   { "HTMLDocument", &DOMDocument::info, &HTMLDocumentTable, 0 };
 /* Source for HTMLDocumentTable. Use "make hashtables" to regenerate.
- at begin HTMLDocumentTable 31
+ at begin HTMLDocumentTable 32
   title			HTMLDocument::Title		DontDelete
   referrer		HTMLDocument::Referrer		DontDelete|ReadOnly
   domain		HTMLDocument::Domain		DontDelete
@@ -154,6 +154,7 @@
   height		HTMLDocument::Height		DontDelete|ReadOnly
   width			HTMLDocument::Width		DontDelete|ReadOnly
   dir			HTMLDocument::Dir		DontDelete
+  designMode            HTMLDocument::DesignMode        DontDelete
 #potentially obsolete array properties
 # layers
 # plugins
@@ -244,6 +245,8 @@
     case CaptureEvents:
     case ReleaseEvents:
       return lookupOrCreateFunction<HTMLDocFunction>( exec, propertyName, this, entry->value, entry->params, entry->attr );
+    case DesignMode:
+        return String(doc.designMode());
     }
   }
   // Look for overrides
@@ -414,6 +417,9 @@
   case Dir:
     body.setDir(value.toString(exec).string());
     break;
+  case DesignMode:
+    doc.setDesignMode(value.toString(exec).string());
+    break;
   default:
     kdWarning() << "HTMLDocument::putValue unhandled token " << token << endl;
   }
@@ -603,7 +609,7 @@
   }
 }
 /*
- at begin HTMLElementTable 8
+ at begin HTMLElementTable 11
   id		KJS::HTMLElement::ElementId	DontDelete
   title		KJS::HTMLElement::ElementTitle	DontDelete
   lang		KJS::HTMLElement::ElementLang	DontDelete
@@ -615,6 +621,8 @@
   document	KJS::HTMLElement::ElementDocument  DontDelete|ReadOnly
 # IE extension
   children	KJS::HTMLElement::ElementChildren  DontDelete|ReadOnly
+  contentEditable   KJS::HTMLElement::ElementContentEditable  DontDelete
+  isContentEditable KJS::HTMLElement::ElementIsContentEditable  DontDelete|ReadOnly
 @end
 @begin HTMLHtmlElementTable 1
   version	KJS::HTMLElement::HtmlVersion	DontDelete
@@ -1794,6 +1802,10 @@
     return getDOMNode(exec,element.ownerDocument());
   case ElementChildren:
     return getHTMLCollection(exec,element.children());
+  case ElementContentEditable:
+    return String(element.contentEditable());
+  case ElementIsContentEditable:
+    return Boolean(element.isContentEditable());
   // ### what about style? or is this used instead for DOM2 stylesheets?
   }
   kdWarning() << "HTMLElement::getValueProperty unhandled token " << token << endl;
@@ -2806,6 +2818,9 @@
     return;
   case ElementInnerText:
     element.setInnerText(str);
+    return;
+  case ElementContentEditable:
+    element.setContentEditable(str);
     return;
   default:
     kdWarning() << "KJS::HTMLElement::putValue unhandled token " << token << " thisTag=" << element.tagName().string() << " str=" << str.string() << endl;
Index: khtml/ecma/kjs_html.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/ecma/kjs_html.h,v
retrieving revision 1.16
diff -u -r1.16 khtml/ecma/kjs_html.h
--- khtml/ecma/kjs_html.h	2003/06/12 18:00:34	1.16
+++ khtml/ecma/kjs_html.h	2003/10/14 15:22:39
@@ -49,7 +49,7 @@
     enum { Title, Referrer, Domain, URL, Body, Location, Cookie,
            Images, Applets, Links, Forms, Anchors, Scripts, All, Clear, Open, Close,
            Write, WriteLn, GetElementsByName, CaptureEvents, ReleaseEvents,
-           BgColor, FgColor, AlinkColor, LinkColor, VlinkColor, LastModified, Height, Width, Dir };
+           BgColor, FgColor, AlinkColor, LinkColor, VlinkColor, LastModified, Height, Width, Dir, DesignMode };
     DOM::Document toDocument() const { return static_cast<DOM::Document>( node ); }
   };
 
@@ -146,7 +146,8 @@
            IFrameFrameBorder, IFrameSrc, IFrameName, IFrameHeight,
            IFrameMarginHeight, IFrameMarginWidth, IFrameScrolling, IFrameWidth, IFrameContentDocument,
            ElementInnerHTML, ElementTitle, ElementId, ElementDir, ElementLang,
-           ElementClassName, ElementInnerText, ElementDocument, ElementChildren };
+           ElementClassName, ElementInnerText, ElementDocument, ElementChildren, ElementContentEditable,
+           ElementIsContentEditable};
 
     DOM::HTMLElement toElement() const { return static_cast<DOM::HTMLElement>(node); }
   };
Index: khtml/html/html_documentimpl.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/html/html_documentimpl.cpp,v
retrieving revision 1.47
diff -u -r1.47 khtml/html/html_documentimpl.cpp
--- khtml/html/html_documentimpl.cpp	2003/10/03 21:49:11	1.47
+++ khtml/html/html_documentimpl.cpp	2003/10/14 15:22:39
@@ -262,6 +262,34 @@
 // not part of the DOM
 // --------------------------------------------------------------------------
 
+DOMString HTMLDocumentImpl::designMode() const
+{
+    TristateFlag editMode = KWQ(view()->part())->editMode();
+    // Note: case for return values intentionally matches WinIE
+    switch (editMode) {
+        default:
+        case FlagNone:
+            return "Inherit";
+        case FlagEnabled:
+            return "On";
+        case FlagDisabled:
+            return "Off";
+    }
+}
+
+void HTMLDocumentImpl::setDesignMode(const DOMString &s)
+{
+    if ( strcasecmp( s, "on" ) == 0 ) {
+        KWQ(view()->part())->setEditMode(FlagEnabled);
+    }
+    else if (strcasecmp(s, "off") == 0) {
+        KWQ(view()->part())->setEditMode(FlagDisabled);
+    }
+    else if (strcasecmp(s, "inherit") == 0 || s.isNull()) {
+        KWQ(view()->part())->setEditMode(FlagNone);
+    }
+}
+
 bool HTMLDocumentImpl::childAllowed( NodeImpl *newChild )
 {
     // ### support comments. etc as a child
Index: khtml/html/html_documentimpl.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/html/html_documentimpl.h,v
retrieving revision 1.16
diff -u -r1.16 khtml/html/html_documentimpl.h
--- khtml/html/html_documentimpl.h	2003/10/03 21:49:11	1.16
+++ khtml/html/html_documentimpl.h	2003/10/14 15:22:39
@@ -65,6 +65,9 @@
     void setPolicyBaseURL(const DOMString &s) { m_policyBaseURL = s; }
 #endif
 
+    DOMString designMode() const;
+    void setDesignMode(const DOMString &);
+
     HTMLElementImpl *body();
     void setBody(HTMLElementImpl *_body, int& exceptioncode);
 
Index: khtml/html/html_elementimpl.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/html/html_elementimpl.cpp,v
retrieving revision 1.19
diff -u -r1.19 khtml/html/html_elementimpl.cpp
--- khtml/html/html_elementimpl.cpp	2003/10/06 20:28:50	1.19
+++ khtml/html/html_elementimpl.cpp	2003/10/14 15:22:39
@@ -53,7 +53,8 @@
 using namespace khtml;
 
 HTMLElementImpl::HTMLElementImpl(DocumentPtr *doc)
-    : ElementImpl(doc)
+    : ElementImpl(doc),
+      m_contentEditable(FlagNone)
 {
 }
 
@@ -129,6 +130,12 @@
         setHasClass(attr->val());
         setChanged();
         break;
+    case ATTR_CONTENTEDITABLE:
+    {
+        setContentEditable(attr->value());
+        setChanged();
+        break;
+    }
     case ATTR_STYLE:
         // ### we need to remove old style info in case there was any!
         // ### the inline sheet ay contain more than 1 property!
@@ -564,6 +571,43 @@
 	addCSSProperty( CSS_PROP_VERTICAL_ALIGN, propvalign );
 }
 
+bool HTMLElementImpl::isContentEditable() const {
+    if (m_contentEditable == FlagEnabled)
+        return true;
+    if (m_contentEditable == FlagDisabled)
+        return false;
+
+    NodeImpl *node = parentNode();
+    while (node && node->isHTMLElement()) {
+        HTMLElementImpl *element = static_cast<HTMLElementImpl *>(node);
+        if (element->m_contentEditable == FlagEnabled)
+            return true;
+        if (element->m_contentEditable == FlagDisabled)
+            return false;
+        node = node->parentNode();
+    }
+    return false;
+}
+
+DOMString HTMLElementImpl::contentEditable() const {
+    if (m_contentEditable == FlagEnabled)
+        return "true";
+    if (m_contentEditable == FlagDisabled)
+        return "false";
+    return "inherit";
+}
+
+void HTMLElementImpl::setContentEditable(const DOMString &enabled) {
+    if ( strcasecmp ( enabled, "true" ) == 0 )
+        m_contentEditable = FlagEnabled;
+    else if ( enabled.isEmpty() ) // we want the "true" attribute
+        setAttribute(ATTR_CONTENTEDITABLE, "true");
+    else if ( strcasecmp ( enabled, "false" ) == 0 )
+        m_contentEditable = FlagDisabled;
+    else if ( strcasecmp ( enabled, "inherit" ) == 0 ) {
+        m_contentEditable = FlagNone;
+    }
+}
 
 // -------------------------------------------------------------------------
 HTMLGenericElementImpl::HTMLGenericElementImpl(DocumentPtr *doc, ushort i)
Index: khtml/html/html_elementimpl.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/html/html_elementimpl.h,v
retrieving revision 1.9
diff -u -r1.9 khtml/html/html_elementimpl.h
--- khtml/html/html_elementimpl.h	2003/10/06 20:28:50	1.9
+++ khtml/html/html_elementimpl.h	2003/10/14 15:22:39
@@ -60,6 +60,10 @@
     bool setInnerText( const DOMString &text );
 
     virtual DOMString namespaceURI() const;
+    
+    virtual bool isContentEditable() const;
+    virtual DOMString contentEditable() const;
+    virtual void setContentEditable(const DOMString &enabled);
 
 #if APPLE_CHANGES
     virtual bool isGenericFormElement() const { return false; }
@@ -68,6 +72,11 @@
 protected:
     // for IMG, OBJECT and APPLET
     void addHTMLAlignment( DOMString alignment );
+
+private:
+    // FIXME: When the property for editing has been determined in CSS3, use that 
+    // instead of this member variable.
+    TristateFlag m_contentEditable;
 };
 
 class HTMLGenericElementImpl : public HTMLElementImpl
Index: khtml/misc/htmlattrs.in
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/misc/htmlattrs.in,v
retrieving revision 1.3
diff -u -r1.3 khtml/misc/htmlattrs.in
--- khtml/misc/htmlattrs.in	2003/08/18 21:12:40	1.3
+++ khtml/misc/htmlattrs.in	2003/10/14 15:22:39
@@ -33,6 +33,7 @@
 colspan
 compact
 content
+contenteditable
 coords
 data
 datetime
-------------- next part --------------


- Ken


More information about the Khtml-devel mailing list