Index: khtmlview.cpp =================================================================== RCS file: /home/kde/kdelibs/khtml/khtmlview.cpp,v retrieving revision 1.664 diff -u -3 -p -r1.664 khtmlview.cpp --- khtmlview.cpp 28 Aug 2004 13:58:54 -0000 1.664 +++ khtmlview.cpp 12 Sep 2004 19:23:27 -0000 @@ -3295,7 +3295,14 @@ void KHTMLView::caretKeyPressEvent(QKeyE else moveCaretToLineEnd(); break; - + default: { + DOM::DocumentImpl *doc = m_part->xmlDocImpl(); + if (doc && doc->isHTMLDocument() && static_cast(doc)->designMode()) { + static_cast(doc)->designModeKeyEvent(m_part->d->caretNode().handle(), m_part->d->caretOffset(), _ke); + if (_ke->isAccepted()) + return; + } + } }/*end switch*/ if ((m_part->d->caretNode().handle() != oldCaretNode Index: ecma/kjs_html.h =================================================================== RCS file: /home/kde/kdelibs/khtml/ecma/kjs_html.h,v retrieving revision 1.80 diff -u -3 -p -r1.80 kjs_html.h --- ecma/kjs_html.h 24 Aug 2004 11:00:20 -0000 1.80 +++ ecma/kjs_html.h 12 Sep 2004 19:23:27 -0000 @@ -49,7 +49,8 @@ namespace KJS { Images, Applets, Links, Forms, Anchors, Scripts, All, Clear, Open, Close, Write, WriteLn, GetElementsByName, GetSelection, CaptureEvents, ReleaseEvents, BgColor, FgColor, AlinkColor, LinkColor, VlinkColor, LastModified, - Height, Width, Dir, Frames, CompatMode }; + Height, Width, Dir, Frames, CompatMode, + DesignMode, ExecCommand, QueryCommandEnabled, QueryCommandState, QueryCommandValue }; DOM::Document toDocument() const { return static_cast( node ); } }; Index: ecma/kjs_html.cpp =================================================================== RCS file: /home/kde/kdelibs/khtml/ecma/kjs_html.cpp,v retrieving revision 1.269 diff -u -3 -p -r1.269 kjs_html.cpp --- ecma/kjs_html.cpp 24 Aug 2004 11:00:20 -0000 1.269 +++ ecma/kjs_html.cpp 12 Sep 2004 19:23:27 -0000 @@ -63,6 +63,77 @@ using namespace KJS; +// ------------------------------------------------------------------------- + +// execCommand for design mode document + +enum ExecCommandType { + ExecBackcolor, ExecBold, ExecCopy, ExecCreatelink, ExecCut, ExecDelete, + ExecFontname, ExecFontsize, ExecForecolor, ExecFormatblock, ExecHeading, + ExecIndent, ExecInserthorizontalrule, ExecInsertimage, + ExecInsertorderedlist, ExecInsertunorderedlist, ExecItalic, + ExecJustifycenter, ExecJustifyfull, ExecJustifyleft, ExecJustifyright, + ExecOutdent, ExecPaste, ExecRedo, ExecRemoveformat, ExecSelectall, + ExecStrikethrough, ExecSubscript, ExecSuperscript, ExecUnderline, + ExecUndo, ExecUnlink +}; + +static struct ExecCommandEntry { + const char *command; + ExecCommandType type; +} exec_commands[] = { + { "backcolor", ExecBackcolor }, + { "bold", ExecBold }, + { "copy", ExecCopy }, + { "createlink", ExecCreatelink }, + { "cut", ExecCut }, + { "delete", ExecDelete }, + { "fontname", ExecFontname }, + { "fontsize", ExecFontsize }, + { "forecolor", ExecForecolor }, + { "formatblock", ExecFormatblock }, + { "heading", ExecHeading }, + { "indent", ExecIndent }, + { "inserthorizontalrule", ExecInserthorizontalrule }, + { "insertimage", ExecInsertimage }, + { "insertorderedlist", ExecInsertorderedlist }, + { "insertunorderedlist", ExecInsertunorderedlist }, + { "italic", ExecItalic }, + { "justifycenter", ExecJustifycenter }, + { "justifyfull", ExecJustifyfull }, + { "justifyleft", ExecJustifyleft }, + { "justifyright", ExecJustifyright }, + { "outdent", ExecOutdent }, + { "paste", ExecPaste }, + { "redo", ExecRedo }, + { "removeformat", ExecRemoveformat }, + { "selectall", ExecSelectall }, + { "strikethrough", ExecStrikethrough }, + { "subscript", ExecSubscript }, + { "superscript", ExecSuperscript }, + { "underline", ExecUnderline }, + { "undo", ExecUndo }, + { "unlink", ExecUnlink } +}; + +static ExecCommandEntry *execCommandType( const char *cmd, int b=0, int e=sizeof(exec_commands)/sizeof(ExecCommandEntry) ) +{ + if (e - b < 2) { + if (b != e && !strcmp(exec_commands[b].command, cmd)) + return exec_commands + b; + return 0L; + } + int mid = (b + e) / 2; + int cmp = strcmp(exec_commands[mid].command, cmd); + if (cmp < 0) + return execCommandType(cmd, mid + 1, e); + if (cmp > 0) + return execCommandType(cmd, b, mid); + return exec_commands + mid; +} + +// ------------------------------------------------------------------------- + IMPLEMENT_PROTOFUNC_DOM(HTMLDocFunction) Value KJS::HTMLDocFunction::tryCall(ExecState *exec, Object &thisObj, const List &args) @@ -123,6 +194,62 @@ Value KJS::HTMLDocFunction::tryCall(Exec case HTMLDocument::ReleaseEvents: // Do nothing for now. These are NS-specific legacy calls. break; + case HTMLDocument::ExecCommand: + if (args.size() > 0) { + QString cmd = args[0].toString(exec).qstring(); + bool showUI = false; + QString param; + if (args.size() > 1) { + showUI = args[1].toBoolean(exec); + if (args.size() > 2) + param = args[2].toString(exec).qstring(); + } + ExecCommandEntry *entry = execCommandType(cmd.ascii()); + if (entry) { + switch (entry->type) { + case ExecBackcolor: + case ExecBold: + case ExecCopy: + case ExecCreatelink: + case ExecCut: + case ExecDelete: + case ExecFontname: + case ExecFontsize: + case ExecForecolor: + case ExecFormatblock: + case ExecHeading: + case ExecIndent: + case ExecInserthorizontalrule: + case ExecInsertimage: + case ExecInsertorderedlist: + case ExecInsertunorderedlist: + case ExecItalic: + case ExecJustifycenter: + case ExecJustifyfull: + case ExecJustifyleft: + case ExecJustifyright: + case ExecOutdent: + case ExecPaste: + case ExecRedo: + case ExecRemoveformat: + case ExecSelectall: + case ExecStrikethrough: + case ExecSubscript: + case ExecSuperscript: + case ExecUnderline: + case ExecUndo: + case ExecUnlink: + break; + } + } + } + break; + case HTMLDocument::QueryCommandEnabled: + break; + case HTMLDocument::QueryCommandState: + break; + case HTMLDocument::QueryCommandValue: + break; } return Undefined(); @@ -167,6 +294,12 @@ const ClassInfo KJS::HTMLDocument::info compatMode HTMLDocument::CompatMode DontDelete|ReadOnly #IE extension frames HTMLDocument::Frames DontDelete|ReadOnly +#Midas http://www.mozilla.org/editor/midas-spec.html + designMode HTMLDocument::DesignMode DontDelete + execCommand HTMLDocument::ExecCommand DontDelete|Function 1 + queryCommandEnabled HTMLDocument::QueryCommandEnabled DontDelete|Function 1 + queryCommandState HTMLDocument::QueryCommandState DontDelete|Function 1 + queryCommandValue HTMLDocument::QueryCommandValue DontDelete|Function 1 #potentially obsolete array properties # layers # plugins @@ -327,10 +460,16 @@ Value KJS::HTMLDocument::tryGet(ExecStat case GetSelection: case CaptureEvents: case ReleaseEvents: + case ExecCommand: + case QueryCommandEnabled: + case QueryCommandState: + case QueryCommandValue: return lookupOrCreateFunction( exec, propertyName, this, entry->value, entry->params, entry->attr ); case CompatMode: return getString(static_cast(doc.handle())->parseMode() == DocumentImpl::Compat ? "BackCompat" : "CSS1Compat"); + case DesignMode: + return String(static_cast(doc.handle())->designMode() ? "on" : "off"); } } // Look for overrides @@ -449,6 +588,9 @@ void KJS::HTMLDocument::putValueProperty case Dir: body.setDir(val); break; + case DesignMode: + static_cast(doc.handle())->setDesignMode(val=="on"); + break; default: kdDebug(6070) << "WARNING: HTMLDocument::putValueProperty unhandled token " << token << endl; } Index: html/html_documentimpl.h =================================================================== RCS file: /home/kde/kdelibs/khtml/html/html_documentimpl.h,v retrieving revision 1.73 diff -u -3 -p -r1.73 html_documentimpl.h --- html/html_documentimpl.h 9 Sep 2004 09:08:18 -0000 1.73 +++ html/html_documentimpl.h 12 Sep 2004 19:23:28 -0000 @@ -78,6 +78,9 @@ public: HTMLCollectionImpl::CollectionInfo *collectionInfo(int type) { return m_collection_info+type; } + void setDesignMode(bool enable=true); + bool designMode() const { return m_designMode; } + void designModeKeyEvent(DOM::NodeImpl *node, int pos, QKeyEvent *ke); protected: HTMLElementImpl *bodyElement; HTMLElementImpl *htmlElement; @@ -94,6 +97,7 @@ protected slots: private: HTMLCollectionImpl::CollectionInfo m_collection_info[HTMLCollectionImpl::LAST_TYPE]; mutable DOMString m_domain; + bool m_designMode; }; } //namespace Index: html/html_documentimpl.cpp =================================================================== RCS file: /home/kde/kdelibs/khtml/html/html_documentimpl.cpp,v retrieving revision 1.162 diff -u -3 -p -r1.162 html_documentimpl.cpp --- html/html_documentimpl.cpp 9 Sep 2004 09:08:18 -0000 1.162 +++ html/html_documentimpl.cpp 12 Sep 2004 19:23:28 -0000 @@ -64,7 +64,7 @@ using namespace khtml; HTMLDocumentImpl::HTMLDocumentImpl(DOMImplementationImpl *_implementation, KHTMLView *v) - : DocumentImpl(_implementation, v) + : DocumentImpl(_implementation, v), m_designMode(false) { // kdDebug( 6090 ) << "HTMLDocumentImpl constructor this = " << this << endl; bodyElement = 0; @@ -434,4 +434,51 @@ void HTMLDocumentImpl::determineParseMod recalcStyleSelector(); } +void HTMLDocumentImpl::setDesignMode(bool enable) { + m_designMode = enable; + m_view->part()->setCaretMode(enable); +} + +void HTMLDocumentImpl::designModeKeyEvent(DOM::NodeImpl *node, int pos, QKeyEvent *ke) { + if (!node) return; + int exceptioncode; + switch (ke->key()) { + case Qt::Key_Backspace: + if (node->nodeType() == DOM::Node::TEXT_NODE && pos > 0) { + DOM::DOMString textNode = node->nodeValue(); + DOM::DOMString endText = textNode.split(pos); + textNode.truncate(pos-1); + node->setNodeValue(textNode + endText, exceptioncode); + ke->accept(); + m_view->part()->setCaretPosition(node, pos-1); + } + break; + case Qt::Key_Delete: + if (node->nodeType() == DOM::Node::TEXT_NODE && pos < node->nodeValue().length()) { + DOM::DOMString textNode = node->nodeValue(); + DOM::DOMString endText = textNode.split(pos); + node->setNodeValue(textNode + endText.split(1), exceptioncode); + ke->accept(); + } + break; + case Qt::Key_Return: + case Qt::Key_Enter: + break; + default: + if (ke->text().isNull()) { + kdDebug() << "null key" << endl; + } else if (node->nodeType() == DOM::Node::TEXT_NODE) { + DOM::DOMString textNode = node->nodeValue(); + DOM::DOMString textSplitted = textNode.split(pos); + node->setNodeValue(textNode + ke->text() + textSplitted, exceptioncode); + ke->accept(); + m_view->part()->setCaretPosition(node, pos+1); + } else if (node->parentNode()) { + node->parentNode()->insertBefore(createTextNode(ke->text()), node, exceptioncode); + ke->accept(); + } + } + +} + #include "html_documentimpl.moc"