File indexing completed on 2024-04-28 15:23:23
0001 /* 0002 * Copyright (C) 2004 Apple Computer, Inc. All rights reserved. 0003 * 0004 * Redistribution and use in source and binary forms, with or without 0005 * modification, are permitted provided that the following conditions 0006 * are met: 0007 * 1. Redistributions of source code must retain the above copyright 0008 * notice, this list of conditions and the following disclaimer. 0009 * 2. Redistributions in binary form must reproduce the above copyright 0010 * notice, this list of conditions and the following disclaimer in the 0011 * documentation and/or other materials provided with the distribution. 0012 * 0013 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 0014 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 0015 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 0016 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 0017 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 0018 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 0019 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 0020 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 0021 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0022 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 0023 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0024 */ 0025 0026 #include "jsediting.h" 0027 #include "editing/htmlediting_impl.h" 0028 #include "editor.h" 0029 0030 #include "css/cssproperties.h" 0031 #include "css/cssvalues.h" 0032 #include "css/css_valueimpl.h" 0033 #include "xml/dom_selection.h" 0034 #include "xml/dom_docimpl.h" 0035 #include "dom/dom_string.h" 0036 0037 #include "misc/khtml_partaccessor.h" 0038 0039 #include <QHash> 0040 #include <QString> 0041 0042 using khtml::TypingCommandImpl; 0043 using khtml::InsertListCommandImpl; 0044 // 0045 #define KPAC khtml::KHTMLPartAccessor 0046 0047 #define DEBUG_COMMANDS 0048 0049 namespace DOM 0050 { 0051 0052 class DocumentImpl; 0053 0054 struct CommandImp { 0055 bool (*execFn)(KHTMLPart *part, bool userInterface, const DOMString &value); 0056 bool (*enabledFn)(KHTMLPart *part); 0057 Editor::TriState(*stateFn)(KHTMLPart *part); 0058 DOMString(*valueFn)(KHTMLPart *part); 0059 }; 0060 0061 typedef QHash<QString, const CommandImp *> CommandDict; 0062 static CommandDict createCommandDictionary(); 0063 0064 bool JSEditor::execCommand(const CommandImp *cmd, bool userInterface, const DOMString &value) 0065 { 0066 if (!cmd || !cmd->enabledFn) { 0067 return false; 0068 } 0069 KHTMLPart *part = m_doc->part(); 0070 if (!part) { 0071 return false; 0072 } 0073 m_doc->updateLayout(); 0074 return cmd->enabledFn(part) && cmd->execFn(part, userInterface, value); 0075 } 0076 0077 bool JSEditor::queryCommandEnabled(const CommandImp *cmd) 0078 { 0079 if (!cmd || !cmd->enabledFn) { 0080 return false; 0081 } 0082 KHTMLPart *part = m_doc->part(); 0083 if (!part) { 0084 return false; 0085 } 0086 m_doc->updateLayout(); 0087 return cmd->enabledFn(part); 0088 } 0089 0090 bool JSEditor::queryCommandIndeterm(const CommandImp *cmd) 0091 { 0092 if (!cmd || !cmd->enabledFn) { 0093 return false; 0094 } 0095 KHTMLPart *part = m_doc->part(); 0096 if (!part) { 0097 return false; 0098 } 0099 m_doc->updateLayout(); 0100 return cmd->stateFn(part) == Editor::MixedTriState; 0101 } 0102 0103 bool JSEditor::queryCommandState(const CommandImp *cmd) 0104 { 0105 if (!cmd || !cmd->enabledFn) { 0106 return false; 0107 } 0108 KHTMLPart *part = m_doc->part(); 0109 if (!part) { 0110 return false; 0111 } 0112 m_doc->updateLayout(); 0113 return cmd->stateFn(part) != Editor::FalseTriState; 0114 } 0115 0116 bool JSEditor::queryCommandSupported(const CommandImp *cmd) 0117 { 0118 return cmd != nullptr; 0119 } 0120 0121 DOMString JSEditor::queryCommandValue(const CommandImp *cmd) 0122 { 0123 if (!cmd || !cmd->enabledFn) { 0124 return DOMString(); 0125 } 0126 KHTMLPart *part = m_doc->part(); 0127 if (!part) { 0128 return DOMString(); 0129 } 0130 m_doc->updateLayout(); 0131 return cmd->valueFn(part); 0132 } 0133 0134 // ============================================================================================= 0135 0136 // Private stuff 0137 0138 static bool execStyleChange(KHTMLPart *part, int propertyID, const DOMString &propertyValue) 0139 { 0140 CSSStyleDeclarationImpl *style = new CSSStyleDeclarationImpl(nullptr); 0141 style->setProperty(propertyID, propertyValue); 0142 style->ref(); 0143 part->editor()->applyStyle(style); 0144 style->deref(); 0145 return true; 0146 } 0147 0148 static bool execStyleChange(KHTMLPart *part, int propertyID, int propertyEnum) 0149 { 0150 CSSStyleDeclarationImpl *style = new CSSStyleDeclarationImpl(nullptr); 0151 style->setProperty(propertyID, propertyEnum); 0152 style->ref(); 0153 part->editor()->applyStyle(style); 0154 style->deref(); 0155 return true; 0156 } 0157 0158 static bool execStyleChange(KHTMLPart *part, int propertyID, const char *propertyValue) 0159 { 0160 return execStyleChange(part, propertyID, DOMString(propertyValue)); 0161 } 0162 0163 static Editor::TriState stateStyle(KHTMLPart *part, int propertyID, const char *desiredValue) 0164 { 0165 CSSStyleDeclarationImpl *style = new CSSStyleDeclarationImpl(nullptr); 0166 style->setProperty(propertyID, desiredValue); 0167 style->ref(); 0168 Editor::TriState state = part->editor()->selectionHasStyle(style); 0169 style->deref(); 0170 return state; 0171 } 0172 0173 static bool selectionStartHasStyle(KHTMLPart *part, int propertyID, const char *desiredValue) 0174 { 0175 CSSStyleDeclarationImpl *style = new CSSStyleDeclarationImpl(nullptr); 0176 style->setProperty(propertyID, desiredValue); 0177 style->ref(); 0178 bool hasStyle = part->editor()->selectionStartHasStyle(style); 0179 style->deref(); 0180 return hasStyle; 0181 } 0182 0183 static DOMString valueStyle(KHTMLPart *part, int propertyID) 0184 { 0185 return part->editor()->selectionStartStylePropertyValue(propertyID); 0186 } 0187 0188 // ============================================================================================= 0189 // 0190 // execCommand implementations 0191 // 0192 0193 static bool execBackColor(KHTMLPart *part, bool /*userInterface*/, const DOMString &value) 0194 { 0195 return execStyleChange(part, CSS_PROP_BACKGROUND_COLOR, value); 0196 } 0197 0198 static bool execBold(KHTMLPart *part, bool /*userInterface*/, const DOMString &/*value*/) 0199 { 0200 bool isBold = selectionStartHasStyle(part, CSS_PROP_FONT_WEIGHT, "bold"); 0201 return execStyleChange(part, CSS_PROP_FONT_WEIGHT, isBold ? "normal" : "bold"); 0202 } 0203 0204 static bool execCopy(KHTMLPart *part, bool /*userInterface*/, const DOMString &/*value*/) 0205 { 0206 part->editor()->copy(); 0207 return true; 0208 } 0209 0210 static bool execCut(KHTMLPart *part, bool /*userInterface*/, const DOMString &/*value*/) 0211 { 0212 part->editor()->cut(); 0213 return true; 0214 } 0215 0216 static bool execDelete(KHTMLPart *part, bool /*userInterface*/, const DOMString &/*value*/) 0217 { 0218 TypingCommandImpl::deleteKeyPressed0(KPAC::xmlDocImpl(part)); 0219 return true; 0220 } 0221 0222 static bool execFontName(KHTMLPart *part, bool /*userInterface*/, const DOMString &value) 0223 { 0224 return execStyleChange(part, CSS_PROP_FONT_FAMILY, value); 0225 } 0226 0227 static bool execFontSize(KHTMLPart *part, bool /*userInterface*/, const DOMString &value) 0228 { 0229 // This should handle sizes 1-7 like <font> does. Who the heck designed this interface? (Rhetorical question) 0230 bool ok; 0231 int val = value.string().toInt(&ok); 0232 if (ok && val >= 1 && val <= 7) { 0233 int size; 0234 switch (val) { 0235 case 1: size = CSS_VAL_XX_SMALL; break; 0236 case 2: size = CSS_VAL_SMALL; break; 0237 case 3: size = CSS_VAL_MEDIUM; break; 0238 case 4: size = CSS_VAL_LARGE; break; 0239 case 5: size = CSS_VAL_X_LARGE; break; 0240 case 6: size = CSS_VAL_XX_LARGE; break; 0241 default: size = CSS_VAL__KHTML_XXX_LARGE; 0242 } 0243 return execStyleChange(part, CSS_PROP_FONT_SIZE, size); 0244 } 0245 0246 return execStyleChange(part, CSS_PROP_FONT_SIZE, value); 0247 } 0248 0249 static bool execForeColor(KHTMLPart *part, bool /*userInterface*/, const DOMString &value) 0250 { 0251 return execStyleChange(part, CSS_PROP_COLOR, value); 0252 } 0253 0254 static bool execIndent(KHTMLPart *part, bool /*userInterface*/, const DOMString &/*value*/) 0255 { 0256 part->editor()->indent(); 0257 return true; 0258 } 0259 0260 static bool execInsertNewline(KHTMLPart *part, bool /*userInterface*/, const DOMString &/*value*/) 0261 { 0262 TypingCommandImpl::insertNewline0(KPAC::xmlDocImpl(part)); 0263 return true; 0264 } 0265 0266 static bool execInsertParagraph(KHTMLPart * /*part*/, bool /*userInterface*/, const DOMString &/*value*/) 0267 { 0268 // FIXME: Implement. 0269 return false; 0270 } 0271 0272 static bool execInsertText(KHTMLPart *part, bool /*userInterface*/, const DOMString &value) 0273 { 0274 TypingCommandImpl::insertText0(KPAC::xmlDocImpl(part), value); 0275 return true; 0276 } 0277 0278 static bool execInsertOrderedList(KHTMLPart *part, bool /*userInterface*/, const DOMString &/*value*/) 0279 { 0280 InsertListCommandImpl::insertList(KPAC::xmlDocImpl(part), InsertListCommandImpl::OrderedList); 0281 return true; 0282 } 0283 0284 static bool execInsertUnorderedList(KHTMLPart *part, bool /*userInterface*/, const DOMString &/*value*/) 0285 { 0286 InsertListCommandImpl::insertList(KPAC::xmlDocImpl(part), InsertListCommandImpl::UnorderedList); 0287 return true; 0288 } 0289 0290 static bool execItalic(KHTMLPart *part, bool /*userInterface*/, const DOMString &/*value*/) 0291 { 0292 bool isItalic = selectionStartHasStyle(part, CSS_PROP_FONT_STYLE, "italic"); 0293 return execStyleChange(part, CSS_PROP_FONT_STYLE, isItalic ? "normal" : "italic"); 0294 } 0295 0296 static bool execJustifyCenter(KHTMLPart *part, bool /*userInterface*/, const DOMString &/*value*/) 0297 { 0298 return execStyleChange(part, CSS_PROP_TEXT_ALIGN, "center"); 0299 } 0300 0301 static bool execJustifyFull(KHTMLPart *part, bool /*userInterface*/, const DOMString &/*value*/) 0302 { 0303 return execStyleChange(part, CSS_PROP_TEXT_ALIGN, "justify"); 0304 } 0305 0306 static bool execJustifyLeft(KHTMLPart *part, bool /*userInterface*/, const DOMString &/*value*/) 0307 { 0308 return execStyleChange(part, CSS_PROP_TEXT_ALIGN, "left"); 0309 } 0310 0311 static bool execJustifyRight(KHTMLPart *part, bool /*userInterface*/, const DOMString &/*value*/) 0312 { 0313 return execStyleChange(part, CSS_PROP_TEXT_ALIGN, "right"); 0314 } 0315 0316 static bool execOutdent(KHTMLPart *part, bool /*userInterface*/, const DOMString &/*value*/) 0317 { 0318 part->editor()->outdent(); 0319 return true; 0320 } 0321 0322 #ifndef NO_SUPPORT_PASTE 0323 0324 static bool execPaste(KHTMLPart *part, bool /*userInterface*/, const DOMString &/*value*/) 0325 { 0326 part->editor()->paste(); 0327 return true; 0328 } 0329 0330 #endif 0331 0332 static bool execPrint(KHTMLPart *part, bool /*userInterface*/, const DOMString &/*value*/) 0333 { 0334 part->editor()->print(); 0335 return true; 0336 } 0337 0338 static bool execRedo(KHTMLPart *part, bool /*userInterface*/, const DOMString &/*value*/) 0339 { 0340 part->editor()->redo(); 0341 return true; 0342 } 0343 0344 static bool execSelectAll(KHTMLPart *part, bool /*userInterface*/, const DOMString &/*value*/) 0345 { 0346 part->selectAll(); 0347 return true; 0348 } 0349 0350 static bool execStrikeThrough(KHTMLPart *part, bool /*userInterface*/, const DOMString &/*value*/) 0351 { 0352 bool isStriked = selectionStartHasStyle(part, CSS_PROP_TEXT_DECORATION, "line-through"); 0353 return execStyleChange(part, CSS_PROP_TEXT_DECORATION, isStriked ? "none" : "line-through"); 0354 } 0355 0356 static bool execSubscript(KHTMLPart *part, bool /*userInterface*/, const DOMString &/*value*/) 0357 { 0358 return execStyleChange(part, CSS_PROP_VERTICAL_ALIGN, "sub"); 0359 } 0360 0361 static bool execSuperscript(KHTMLPart *part, bool /*userInterface*/, const DOMString &/*value*/) 0362 { 0363 return execStyleChange(part, CSS_PROP_VERTICAL_ALIGN, "super"); 0364 } 0365 0366 static bool execUndo(KHTMLPart *part, bool /*userInterface*/, const DOMString &/*value*/) 0367 { 0368 part->editor()->undo(); 0369 return true; 0370 } 0371 0372 static bool execUnderline(KHTMLPart *part, bool /*userInterface*/, const DOMString &/*value*/) 0373 { 0374 bool isUnderline = selectionStartHasStyle(part, CSS_PROP_TEXT_DECORATION, "underline"); 0375 return execStyleChange(part, CSS_PROP_TEXT_DECORATION, isUnderline ? "none" : "underline"); 0376 } 0377 0378 static bool execUnselect(KHTMLPart *part, bool /*userInterface*/, const DOMString &/*value*/) 0379 { 0380 KPAC::clearSelection(part); 0381 return true; 0382 } 0383 0384 // ============================================================================================= 0385 // 0386 // queryCommandEnabled implementations 0387 // 0388 // It's a bit difficult to get a clear notion of the difference between 0389 // "supported" and "enabled" from reading the Microsoft documentation, but 0390 // what little I could glean from that seems to make some sense. 0391 // Supported = The command is supported by this object. 0392 // Enabled = The command is available and enabled. 0393 0394 static bool enabled(KHTMLPart * /*part*/) 0395 { 0396 return true; 0397 } 0398 0399 static bool enabledAnySelection(KHTMLPart *part) 0400 { 0401 return KPAC::caret(part).notEmpty(); 0402 } 0403 0404 #ifndef NO_SUPPORT_PASTE 0405 0406 static bool enabledPaste(KHTMLPart *part) 0407 { 0408 return part->editor()->canPaste(); 0409 } 0410 0411 #endif 0412 0413 static bool enabledRangeSelection(KHTMLPart *part) 0414 { 0415 return KPAC::caret(part).state() == Selection::RANGE; 0416 } 0417 0418 static bool enabledRedo(KHTMLPart *part) 0419 { 0420 return part->editor()->canRedo(); 0421 } 0422 0423 static bool enabledUndo(KHTMLPart *part) 0424 { 0425 return part->editor()->canUndo(); 0426 } 0427 0428 // ============================================================================================= 0429 // 0430 // queryCommandIndeterm/State implementations 0431 // 0432 // It's a bit difficult to get a clear notion of what these methods are supposed 0433 // to do from reading the Microsoft documentation, but my current guess is this: 0434 // 0435 // queryCommandState and queryCommandIndeterm work in concert to return 0436 // the two bits of information that are needed to tell, for instance, 0437 // if the text of a selection is bold. The answer can be "yes", "no", or 0438 // "partially". 0439 // 0440 // If this is so, then queryCommandState should return "yes" in the case where 0441 // all the text is bold and "no" for non-bold or partially-bold text. 0442 // Then, queryCommandIndeterm should return "no" in the case where 0443 // all the text is either all bold or not-bold and and "yes" for partially-bold text. 0444 0445 static Editor::TriState stateNone(KHTMLPart * /*part*/) 0446 { 0447 return Editor::FalseTriState; 0448 } 0449 0450 static Editor::TriState stateBold(KHTMLPart *part) 0451 { 0452 return stateStyle(part, CSS_PROP_FONT_WEIGHT, "bold"); 0453 } 0454 0455 static Editor::TriState stateItalic(KHTMLPart *part) 0456 { 0457 return stateStyle(part, CSS_PROP_FONT_STYLE, "italic"); 0458 } 0459 0460 static Editor::TriState stateStrike(KHTMLPart *part) 0461 { 0462 return stateStyle(part, CSS_PROP_TEXT_DECORATION, "line-through"); 0463 } 0464 0465 static Editor::TriState stateSubscript(KHTMLPart *part) 0466 { 0467 return stateStyle(part, CSS_PROP_VERTICAL_ALIGN, "sub"); 0468 } 0469 0470 static Editor::TriState stateSuperscript(KHTMLPart *part) 0471 { 0472 return stateStyle(part, CSS_PROP_VERTICAL_ALIGN, "super"); 0473 } 0474 0475 static Editor::TriState stateUnderline(KHTMLPart *part) 0476 { 0477 return stateStyle(part, CSS_PROP_TEXT_DECORATION, "underline"); 0478 } 0479 0480 // ============================================================================================= 0481 // 0482 // queryCommandValue implementations 0483 // 0484 0485 static DOMString valueNull(KHTMLPart * /*part*/) 0486 { 0487 return DOMString(); 0488 } 0489 0490 static DOMString valueBackColor(KHTMLPart *part) 0491 { 0492 return valueStyle(part, CSS_PROP_BACKGROUND_COLOR); 0493 } 0494 0495 static DOMString valueFontName(KHTMLPart *part) 0496 { 0497 return valueStyle(part, CSS_PROP_FONT_FAMILY); 0498 } 0499 0500 static DOMString valueFontSize(KHTMLPart *part) 0501 { 0502 return valueStyle(part, CSS_PROP_FONT_SIZE); 0503 } 0504 0505 static DOMString valueForeColor(KHTMLPart *part) 0506 { 0507 return valueStyle(part, CSS_PROP_COLOR); 0508 } 0509 0510 // ============================================================================================= 0511 0512 struct EditorCommandInfo { 0513 const char *name; 0514 CommandImp imp; 0515 }; 0516 0517 // NOTE: strictly keep in sync with EditorCommand in editor_command.h 0518 static const EditorCommandInfo commands[] = { 0519 0520 { "backColor", { execBackColor, enabled, stateNone, valueBackColor } }, 0521 { "bold", { execBold, enabledAnySelection, stateBold, valueNull } }, 0522 { "copy", { execCopy, enabledRangeSelection, stateNone, valueNull } }, 0523 { "cut", { execCut, enabledRangeSelection, stateNone, valueNull } }, 0524 { "delete", { execDelete, enabledAnySelection, stateNone, valueNull } }, 0525 { "fontName", { execFontName, enabledAnySelection, stateNone, valueFontName } }, 0526 { "fontSize", { execFontSize, enabledAnySelection, stateNone, valueFontSize } }, 0527 { "foreColor", { execForeColor, enabledAnySelection, stateNone, valueForeColor } }, 0528 { "indent", { execIndent, enabledAnySelection, stateNone, valueNull } }, 0529 { "insertNewline", { execInsertNewline, enabledAnySelection, stateNone, valueNull } }, 0530 { "insertOrderedList", { execInsertOrderedList, enabledAnySelection, stateNone, valueNull } }, 0531 { "insertParagraph", { execInsertParagraph, enabledAnySelection, stateNone, valueNull } }, 0532 { "insertText", { execInsertText, enabledAnySelection, stateNone, valueNull } }, 0533 { "insertUnorderedList", { execInsertUnorderedList, enabledAnySelection, stateNone, valueNull } }, 0534 { "italic", { execItalic, enabledAnySelection, stateItalic, valueNull } }, 0535 { "justifyCenter", { execJustifyCenter, enabledAnySelection, stateNone, valueNull } }, 0536 { "justifyFull", { execJustifyFull, enabledAnySelection, stateNone, valueNull } }, 0537 { "justifyLeft", { execJustifyLeft, enabledAnySelection, stateNone, valueNull } }, 0538 { "justifyNone", { execJustifyLeft, enabledAnySelection, stateNone, valueNull } }, 0539 { "justifyRight", { execJustifyRight, enabledAnySelection, stateNone, valueNull } }, 0540 { "outdent", { execOutdent, enabledAnySelection, stateNone, valueNull } }, 0541 #ifndef NO_SUPPORT_PASTE 0542 { "paste", { execPaste, enabledPaste, stateNone, valueNull } }, 0543 #else 0544 { 0, { 0, 0, 0, 0 } }, 0545 #endif 0546 { "print", { execPrint, enabled, stateNone, valueNull } }, 0547 { "redo", { execRedo, enabledRedo, stateNone, valueNull } }, 0548 { "selectAll", { execSelectAll, enabled, stateNone, valueNull } }, 0549 { "StrikeThrough", {execStrikeThrough, enabled, stateStrike, valueNull } }, 0550 { "subscript", { execSubscript, enabledAnySelection, stateSubscript, valueNull } }, 0551 { "superscript", { execSuperscript, enabledAnySelection, stateSuperscript, valueNull } }, 0552 { "underline", { execUnderline, enabledAnySelection, stateUnderline, valueNull } }, 0553 { "undo", { execUndo, enabledUndo, stateNone, valueNull } }, 0554 { "unselect", { execUnselect, enabledAnySelection, stateNone, valueNull } } 0555 0556 // 0557 // The "unsupported" commands are listed here since they appear in the Microsoft 0558 // documentation used as the basis for the list. 0559 // 0560 0561 // 2d-position (not supported) 0562 // absolutePosition (not supported) 0563 // blockDirLTR (not supported) 0564 // blockDirRTL (not supported) 0565 // browseMode (not supported) 0566 // clearAuthenticationCache (not supported) 0567 // createBookmark (not supported) 0568 // createLink (not supported) 0569 // dirLTR (not supported) 0570 // dirRTL (not supported) 0571 // editMode (not supported) 0572 // formatBlock (not supported) 0573 // inlineDirLTR (not supported) 0574 // inlineDirRTL (not supported) 0575 // insertButton (not supported) 0576 // insertFieldSet (not supported) 0577 // insertHorizontalRule (not supported) 0578 // insertIFrame (not supported) 0579 // insertImage (not supported) 0580 // insertInputButton (not supported) 0581 // insertInputCheckbox (not supported) 0582 // insertInputFileUpload (not supported) 0583 // insertInputHidden (not supported) 0584 // insertInputImage (not supported) 0585 // insertInputPassword (not supported) 0586 // insertInputRadio (not supported) 0587 // insertInputReset (not supported) 0588 // insertInputSubmit (not supported) 0589 // insertInputText (not supported) 0590 // insertMarquee (not supported) 0591 // insertOrderedList (not supported) 0592 // insertSelectDropDown (not supported) 0593 // insertSelectListBox (not supported) 0594 // insertTextArea (not supported) 0595 // insertUnorderedList (not supported) 0596 // liveResize (not supported) 0597 // multipleSelection (not supported) 0598 // open (not supported) 0599 // overwrite (not supported) 0600 // playImage (not supported) 0601 // refresh (not supported) 0602 // removeFormat (not supported) 0603 // removeParaFormat (not supported) 0604 // saveAs (not supported) 0605 // sizeToControl (not supported) 0606 // sizeToControlHeight (not supported) 0607 // sizeToControlWidth (not supported) 0608 // stop (not supported) 0609 // stopimage (not supported) 0610 // strikethrough (not supported) 0611 // unbookmark (not supported) 0612 // underline (not supported) 0613 // unlink (not supported) 0614 }; 0615 0616 static CommandDict createCommandDictionary() 0617 { 0618 const int numCommands = sizeof(commands) / sizeof(commands[0]); 0619 CommandDict commandDictionary; // case-insensitive dictionary 0620 for (int i = 0; i < numCommands; ++i) { 0621 if (commands[i].name) { 0622 commandDictionary.insert(QString(commands[i].name).toLower(), &commands[i].imp); 0623 } 0624 } 0625 return commandDictionary; 0626 } 0627 0628 const CommandImp *JSEditor::commandImp(const DOMString &command) 0629 { 0630 static CommandDict commandDictionary = createCommandDictionary(); 0631 const CommandImp *result = commandDictionary.value(command.string().toLower()); 0632 #ifdef DEBUG_COMMANDS 0633 if (!result) { 0634 qCDebug(KHTML_LOG) << "[Command is not supported yet]" << command; 0635 } 0636 #endif 0637 return result; 0638 } 0639 0640 const CommandImp *JSEditor::commandImp(int command) 0641 { 0642 if (command < 0 || command >= int(sizeof commands / sizeof commands[0])) { 0643 return nullptr; 0644 } 0645 return &commands[command].imp; 0646 } 0647 0648 } // namespace DOM 0649 0650 #undef KPAC