EditorClientEfl.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. /*
  2. * Copyright (C) 2007 Alp Toker <alp@atoker.com>
  3. * Copyright (C) 2008 Nuanti Ltd.
  4. * Copyright (C) 2008 INdT - Instituto Nokia de Tecnologia
  5. * Copyright (C) 2009-2010 ProFUSION embedded systems
  6. * Copyright (C) 2009-2010 Samsung Electronics
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2 of the License, or (at your option) any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with this library; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. */
  22. #include "config.h"
  23. #include "EditorClientEfl.h"
  24. #include "Document.h"
  25. #include "DumpRenderTreeSupportEfl.h"
  26. #include "Editor.h"
  27. #include "EflKeyboardUtilities.h"
  28. #include "EventNames.h"
  29. #include "FocusController.h"
  30. #include "Frame.h"
  31. #include "KeyboardEvent.h"
  32. #include "NotImplemented.h"
  33. #include "Page.h"
  34. #include "PlatformKeyboardEvent.h"
  35. #include "Settings.h"
  36. #include "UndoStep.h"
  37. #include "WindowsKeyboardCodes.h"
  38. #include "ewk_frame_private.h"
  39. #include "ewk_private.h"
  40. #include "ewk_view_private.h"
  41. using namespace WebCore;
  42. namespace WebCore {
  43. void EditorClientEfl::willSetInputMethodState()
  44. {
  45. notImplemented();
  46. }
  47. void EditorClientEfl::setInputMethodState(bool active)
  48. {
  49. ewk_view_input_method_state_set(m_view, active);
  50. }
  51. bool EditorClientEfl::shouldDeleteRange(Range* range)
  52. {
  53. evas_object_smart_callback_call(m_view, "editorclient,range,delete", range);
  54. return true;
  55. }
  56. bool EditorClientEfl::isContinuousSpellCheckingEnabled()
  57. {
  58. notImplemented();
  59. return false;
  60. }
  61. bool EditorClientEfl::isGrammarCheckingEnabled()
  62. {
  63. notImplemented();
  64. return false;
  65. }
  66. int EditorClientEfl::spellCheckerDocumentTag()
  67. {
  68. notImplemented();
  69. return 0;
  70. }
  71. bool EditorClientEfl::shouldBeginEditing(Range* range)
  72. {
  73. evas_object_smart_callback_call(m_view, "editorclient,editing,begin", range);
  74. return true;
  75. }
  76. bool EditorClientEfl::shouldEndEditing(Range* range)
  77. {
  78. evas_object_smart_callback_call(m_view, "editorclient,editing,end", range);
  79. return true;
  80. }
  81. bool EditorClientEfl::shouldInsertText(const String& text, Range* range, EditorInsertAction action)
  82. {
  83. CString protectedText = text.utf8();
  84. Ewk_Should_Insert_Text_Event shouldInsertTextEvent = { protectedText.data(), range, action };
  85. evas_object_smart_callback_call(m_view, "editorclient,text,insert", &shouldInsertTextEvent);
  86. return true;
  87. }
  88. bool EditorClientEfl::shouldChangeSelectedRange(Range* fromRange, Range* toRange, EAffinity affinity, bool stillSelecting)
  89. {
  90. Ewk_Should_Change_Selected_Range_Event shouldChangeSelectedRangeEvent = { fromRange, toRange, affinity, stillSelecting };
  91. evas_object_smart_callback_call(m_view, "editorclient,selected,range,change", &shouldChangeSelectedRangeEvent);
  92. return true;
  93. }
  94. bool EditorClientEfl::shouldApplyStyle(StylePropertySet* style, Range* range)
  95. {
  96. Ewk_Should_Apply_Style_Event shouldApplyStyleEvent = { style, range };
  97. evas_object_smart_callback_call(m_view, "editorclient,style,apply", &shouldApplyStyleEvent);
  98. return true;
  99. }
  100. bool EditorClientEfl::shouldMoveRangeAfterDelete(Range*, Range*)
  101. {
  102. notImplemented();
  103. return true;
  104. }
  105. void EditorClientEfl::didBeginEditing()
  106. {
  107. evas_object_smart_callback_call(m_view, "editorclient,editing,began", 0);
  108. }
  109. void EditorClientEfl::respondToChangedContents()
  110. {
  111. Evas_Object* frame = ewk_view_frame_focused_get(m_view);
  112. if (!frame)
  113. frame = ewk_view_frame_main_get(m_view);
  114. if (!frame)
  115. return;
  116. ewk_frame_editor_client_contents_changed(frame);
  117. }
  118. void EditorClientEfl::respondToChangedSelection(Frame* coreFrame)
  119. {
  120. if (!coreFrame)
  121. return;
  122. if (coreFrame->editor().ignoreCompositionSelectionChange())
  123. return;
  124. Evas_Object* webFrame = EWKPrivate::kitFrame(coreFrame);
  125. ewk_frame_editor_client_selection_changed(webFrame);
  126. coreFrame->editor().cancelCompositionIfSelectionIsInvalid();
  127. }
  128. void EditorClientEfl::didEndEditing()
  129. {
  130. evas_object_smart_callback_call(m_view, "editorclient,editing,ended", 0);
  131. }
  132. void EditorClientEfl::didWriteSelectionToPasteboard()
  133. {
  134. notImplemented();
  135. }
  136. void EditorClientEfl::willWriteSelectionToPasteboard(WebCore::Range*)
  137. {
  138. }
  139. void EditorClientEfl::getClientPasteboardDataForRange(WebCore::Range*, Vector<String>&, Vector<RefPtr<WebCore::SharedBuffer> >&)
  140. {
  141. }
  142. void EditorClientEfl::didSetSelectionTypesForPasteboard()
  143. {
  144. notImplemented();
  145. }
  146. void EditorClientEfl::registerUndoStep(WTF::PassRefPtr<UndoStep> step)
  147. {
  148. if (!m_isInRedo)
  149. redoStack.clear();
  150. undoStack.prepend(step);
  151. }
  152. void EditorClientEfl::registerRedoStep(WTF::PassRefPtr<UndoStep> step)
  153. {
  154. redoStack.prepend(step);
  155. }
  156. void EditorClientEfl::clearUndoRedoOperations()
  157. {
  158. undoStack.clear();
  159. redoStack.clear();
  160. }
  161. bool EditorClientEfl::canCopyCut(Frame*, bool defaultValue) const
  162. {
  163. return defaultValue;
  164. }
  165. bool EditorClientEfl::canPaste(Frame*, bool defaultValue) const
  166. {
  167. return defaultValue;
  168. }
  169. bool EditorClientEfl::canUndo() const
  170. {
  171. return !undoStack.isEmpty();
  172. }
  173. bool EditorClientEfl::canRedo() const
  174. {
  175. return !redoStack.isEmpty();
  176. }
  177. void EditorClientEfl::undo()
  178. {
  179. if (canUndo()) {
  180. RefPtr<WebCore::UndoStep> step = undoStack.takeFirst();
  181. step->unapply();
  182. }
  183. }
  184. void EditorClientEfl::redo()
  185. {
  186. if (canRedo()) {
  187. RefPtr<WebCore::UndoStep> step = redoStack.takeFirst();
  188. ASSERT(!m_isInRedo);
  189. m_isInRedo = true;
  190. step->reapply();
  191. m_isInRedo = false;
  192. }
  193. }
  194. bool EditorClientEfl::shouldInsertNode(Node* node, Range* range, EditorInsertAction action)
  195. {
  196. Ewk_Should_Insert_Node_Event insertNodeEvent = { node, range, action };
  197. evas_object_smart_callback_call(m_view, "editorclient,node,insert", &insertNodeEvent);
  198. return true;
  199. }
  200. void EditorClientEfl::pageDestroyed()
  201. {
  202. delete this;
  203. }
  204. bool EditorClientEfl::smartInsertDeleteEnabled()
  205. {
  206. WebCore::Page* corePage = EWKPrivate::corePage(m_view);
  207. if (!corePage)
  208. return false;
  209. return corePage->settings()->smartInsertDeleteEnabled();
  210. }
  211. bool EditorClientEfl::isSelectTrailingWhitespaceEnabled()
  212. {
  213. WebCore::Page* corePage = EWKPrivate::corePage(m_view);
  214. if (!corePage)
  215. return false;
  216. return corePage->settings()->selectTrailingWhitespaceEnabled();
  217. }
  218. void EditorClientEfl::toggleContinuousSpellChecking()
  219. {
  220. notImplemented();
  221. }
  222. void EditorClientEfl::toggleGrammarChecking()
  223. {
  224. notImplemented();
  225. }
  226. const char* EditorClientEfl::interpretKeyEvent(const KeyboardEvent* event)
  227. {
  228. ASSERT(event->type() == eventNames().keydownEvent || event->type() == eventNames().keypressEvent);
  229. if (event->type() == eventNames().keydownEvent)
  230. return getKeyDownCommandName(event);
  231. return getKeyPressCommandName(event);
  232. }
  233. bool EditorClientEfl::handleEditingKeyboardEvent(KeyboardEvent* event)
  234. {
  235. Node* node = event->target()->toNode();
  236. ASSERT(node);
  237. Frame* frame = node->document()->frame();
  238. ASSERT(frame);
  239. const PlatformKeyboardEvent* keyEvent = event->keyEvent();
  240. if (!keyEvent)
  241. return false;
  242. if (!frame->settings())
  243. return false;
  244. bool caretBrowsing = frame->settings()->caretBrowsingEnabled();
  245. if (caretBrowsing) {
  246. switch (keyEvent->windowsVirtualKeyCode()) {
  247. case VK_LEFT:
  248. frame->selection()->modify(keyEvent->shiftKey() ? FrameSelection::AlterationExtend : FrameSelection::AlterationMove,
  249. DirectionLeft,
  250. keyEvent->ctrlKey() ? WordGranularity : CharacterGranularity,
  251. UserTriggered);
  252. return true;
  253. case VK_RIGHT:
  254. frame->selection()->modify(keyEvent->shiftKey() ? FrameSelection::AlterationExtend : FrameSelection::AlterationMove,
  255. DirectionRight,
  256. keyEvent->ctrlKey() ? WordGranularity : CharacterGranularity,
  257. UserTriggered);
  258. return true;
  259. case VK_UP:
  260. frame->selection()->modify(keyEvent->shiftKey() ? FrameSelection::AlterationExtend : FrameSelection::AlterationMove,
  261. DirectionBackward,
  262. keyEvent->ctrlKey() ? ParagraphGranularity : LineGranularity,
  263. UserTriggered);
  264. return true;
  265. case VK_DOWN:
  266. frame->selection()->modify(keyEvent->shiftKey() ? FrameSelection::AlterationExtend : FrameSelection::AlterationMove,
  267. DirectionForward,
  268. keyEvent->ctrlKey() ? ParagraphGranularity : LineGranularity,
  269. UserTriggered);
  270. return true;
  271. }
  272. }
  273. Editor::Command command = frame->editor().command(interpretKeyEvent(event));
  274. if (keyEvent->type() == PlatformEvent::RawKeyDown) {
  275. // WebKit doesn't have enough information about mode to decide how commands that just insert text if executed via Editor should be treated,
  276. // so we leave it upon WebCore to either handle them immediately (e.g. Tab that changes focus) or let a keypress event be generated
  277. // (e.g. Tab that inserts a Tab character, or Enter).
  278. return !command.isTextInsertion() && command.execute(event);
  279. }
  280. if (command.execute(event))
  281. return true;
  282. // Don't allow text insertion for nodes that cannot edit.
  283. if (!frame->editor().canEdit())
  284. return false;
  285. // Don't insert null or control characters as they can result in unexpected behaviour
  286. if (event->charCode() < ' ')
  287. return false;
  288. // Don't insert anything if a modifier is pressed
  289. if (keyEvent->ctrlKey() || keyEvent->altKey())
  290. return false;
  291. return frame->editor().insertText(event->keyEvent()->text(), event);
  292. }
  293. void EditorClientEfl::handleKeyboardEvent(KeyboardEvent* event)
  294. {
  295. if (handleEditingKeyboardEvent(event))
  296. event->setDefaultHandled();
  297. }
  298. void EditorClientEfl::handleInputMethodKeydown(KeyboardEvent*)
  299. {
  300. }
  301. EditorClientEfl::EditorClientEfl(Evas_Object* view)
  302. : m_isInRedo(false)
  303. , m_view(view)
  304. {
  305. notImplemented();
  306. }
  307. EditorClientEfl::~EditorClientEfl()
  308. {
  309. notImplemented();
  310. }
  311. void EditorClientEfl::textFieldDidBeginEditing(Element*)
  312. {
  313. }
  314. void EditorClientEfl::textFieldDidEndEditing(Element*)
  315. {
  316. notImplemented();
  317. }
  318. void EditorClientEfl::textDidChangeInTextField(Element*)
  319. {
  320. notImplemented();
  321. }
  322. bool EditorClientEfl::doTextFieldCommandFromEvent(Element*, KeyboardEvent*)
  323. {
  324. return false;
  325. }
  326. void EditorClientEfl::textWillBeDeletedInTextField(Element*)
  327. {
  328. notImplemented();
  329. }
  330. void EditorClientEfl::textDidChangeInTextArea(Element*)
  331. {
  332. notImplemented();
  333. }
  334. bool EditorClientEfl::shouldEraseMarkersAfterChangeSelection(TextCheckingType) const
  335. {
  336. return true;
  337. }
  338. void EditorClientEfl::ignoreWordInSpellDocument(const String&)
  339. {
  340. notImplemented();
  341. }
  342. void EditorClientEfl::learnWord(const String&)
  343. {
  344. notImplemented();
  345. }
  346. void EditorClientEfl::checkSpellingOfString(const UChar*, int, int*, int*)
  347. {
  348. notImplemented();
  349. }
  350. String EditorClientEfl::getAutoCorrectSuggestionForMisspelledWord(const String&)
  351. {
  352. notImplemented();
  353. return String();
  354. }
  355. void EditorClientEfl::checkGrammarOfString(const UChar*, int, Vector<GrammarDetail>&, int*, int*)
  356. {
  357. notImplemented();
  358. }
  359. void EditorClientEfl::updateSpellingUIWithGrammarString(const String&, const GrammarDetail&)
  360. {
  361. notImplemented();
  362. }
  363. void EditorClientEfl::updateSpellingUIWithMisspelledWord(const String&)
  364. {
  365. notImplemented();
  366. }
  367. void EditorClientEfl::showSpellingUI(bool)
  368. {
  369. notImplemented();
  370. }
  371. bool EditorClientEfl::spellingUIIsShowing()
  372. {
  373. notImplemented();
  374. return false;
  375. }
  376. void EditorClientEfl::getGuessesForWord(const String& /*word*/, const String& /*context*/, Vector<String>& /*guesses*/)
  377. {
  378. notImplemented();
  379. }
  380. }