Opera 12.15 Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

OpDocumentEditCommand.cpp 34KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150
  1. /* -*- Mode: c++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*-
  2. *
  3. * Copyright (C) 1995-2010 Opera Software AS. All rights reserved.
  4. *
  5. * This file is part of the Opera web browser.
  6. * It may not be distributed under any circumstances.
  7. */
  8. #include "core/pch.h"
  9. #include "modules/documentedit/OpDocumentEdit.h"
  10. #include "modules/documentedit/OpDocumentEditUtils.h"
  11. #include "modules/dom/domutils.h"
  12. #include "modules/logdoc/htm_lex.h"
  13. #include "modules/logdoc/logdoc_util.h"
  14. #include "modules/pi/OpClipboard.h"
  15. #include "modules/util/opstrlst.h"
  16. #include "modules/style/css.h"
  17. #include "modules/style/css_dom.h"
  18. #include "modules/layout/layout_workplace.h"
  19. #include "modules/prefs/prefsmanager/collections/pc_js.h"
  20. #ifdef DOCUMENT_EDIT_SUPPORT
  21. #define REPORT_AND_RETURN_FALSE_IF_ERROR(status) if (OpStatus::IsError(status)) \
  22. { \
  23. if (OpStatus::IsMemoryError(status)) \
  24. ReportOOM(); \
  25. return FALSE; \
  26. }
  27. /* static */
  28. OP_DOCUMENT_EDIT_COMMAND OpDocumentEdit::ConvertCommand(const uni_char* command)
  29. {
  30. // IE also has Refresh, LiveResize, etc...
  31. if (command) switch (command[0])
  32. {
  33. case 'b': case 'B':
  34. if (uni_stricmp(command, UNI_L("BACKCOLOR")) == 0)
  35. return OP_DOCUMENT_EDIT_COMMAND_BACKCOLOR;
  36. else if (uni_stricmp(command, UNI_L("BOLD")) == 0)
  37. return OP_DOCUMENT_EDIT_COMMAND_BOLD;
  38. break;
  39. case 'c': case 'C':
  40. if (uni_stricmp(command, UNI_L("CONTENTREADONLY")) == 0)
  41. return OP_DOCUMENT_EDIT_COMMAND_CONTENTREADONLY;
  42. else if (uni_stricmp(command, UNI_L("COPY")) == 0)
  43. return OP_DOCUMENT_EDIT_COMMAND_COPY;
  44. else if (uni_stricmp(command, UNI_L("CREATELINK")) == 0)
  45. return OP_DOCUMENT_EDIT_COMMAND_CREATELINK;
  46. else if (uni_stricmp(command, UNI_L("CUT")) == 0)
  47. return OP_DOCUMENT_EDIT_COMMAND_CUT;
  48. break;
  49. case 'd': case 'D':
  50. if (uni_stricmp(command, UNI_L("DECREASEFONTSIZE")) == 0)
  51. return OP_DOCUMENT_EDIT_COMMAND_DECREASEFONTSIZE;
  52. else if (uni_stricmp(command, UNI_L("DELETE")) == 0)
  53. return OP_DOCUMENT_EDIT_COMMAND_DELETE;
  54. break;
  55. case 'f': case 'F':
  56. if (uni_stricmp(command, UNI_L("FONTNAME")) == 0)
  57. return OP_DOCUMENT_EDIT_COMMAND_FONTNAME;
  58. else if (uni_stricmp(command, UNI_L("FONTSIZE")) == 0)
  59. return OP_DOCUMENT_EDIT_COMMAND_FONTSIZE;
  60. else if (uni_stricmp(command, UNI_L("FORECOLOR")) == 0)
  61. return OP_DOCUMENT_EDIT_COMMAND_FORECOLOR;
  62. else if (uni_stricmp(command, UNI_L("FORMATBLOCK")) == 0)
  63. return OP_DOCUMENT_EDIT_COMMAND_FORMATBLOCK;
  64. break;
  65. case 'h': case 'H':
  66. if (uni_stricmp(command, UNI_L("HILITECOLOR")) == 0)
  67. return OP_DOCUMENT_EDIT_COMMAND_HILITECOLOR;
  68. break;
  69. case 'i': case 'I':
  70. if (uni_stricmp(command, UNI_L("INCREASEFONTSIZE")) == 0)
  71. return OP_DOCUMENT_EDIT_COMMAND_INCREASEFONTSIZE;
  72. else if (uni_stricmp(command, UNI_L("INDENT")) == 0)
  73. return OP_DOCUMENT_EDIT_COMMAND_INDENT;
  74. // Maybe worth a strincmp pretest on "insert"
  75. else if (uni_stricmp(command, UNI_L("INSERTHORIZONTALRULE")) == 0)
  76. return OP_DOCUMENT_EDIT_COMMAND_INSERTHORIZONTALRULE;
  77. else if (uni_stricmp(command, UNI_L("INSERTHTML")) == 0)
  78. return OP_DOCUMENT_EDIT_COMMAND_INSERTHTML;
  79. else if (uni_stricmp(command, UNI_L("INSERTIMAGE")) == 0)
  80. return OP_DOCUMENT_EDIT_COMMAND_INSERTIMAGE;
  81. else if (uni_stricmp(command, UNI_L("INSERTORDEREDLIST")) == 0)
  82. return OP_DOCUMENT_EDIT_COMMAND_INSERTORDEREDLIST;
  83. else if (uni_stricmp(command, UNI_L("INSERTPARAGRAPH")) == 0)
  84. return OP_DOCUMENT_EDIT_COMMAND_INSERTPARAGRAPH;
  85. else if (uni_stricmp(command, UNI_L("INSERTUNORDEREDLIST")) == 0)
  86. return OP_DOCUMENT_EDIT_COMMAND_INSERTUNORDEREDLIST;
  87. else if (uni_stricmp(command, UNI_L("ITALIC")) == 0)
  88. return OP_DOCUMENT_EDIT_COMMAND_ITALIC;
  89. break;
  90. case 'j': case 'J':
  91. // Maybe worth a strincmp pretest on "justify"
  92. if (uni_stricmp(command, UNI_L("JUSTIFYCENTER")) == 0)
  93. return OP_DOCUMENT_EDIT_COMMAND_JUSTIFYCENTER;
  94. else if (uni_stricmp(command, UNI_L("JUSTIFYFULL")) == 0)
  95. return OP_DOCUMENT_EDIT_COMMAND_JUSTIFYFULL;
  96. else if (uni_stricmp(command, UNI_L("JUSTIFYLEFT")) == 0)
  97. return OP_DOCUMENT_EDIT_COMMAND_JUSTIFYLEFT;
  98. else if (uni_stricmp(command, UNI_L("JUSTIFYRIGHT")) == 0)
  99. return OP_DOCUMENT_EDIT_COMMAND_JUSTIFYRIGHT;
  100. break;
  101. case 'o': case 'O':
  102. if (uni_stricmp(command, UNI_L("OUTDENT")) == 0)
  103. return OP_DOCUMENT_EDIT_COMMAND_OUTDENT;
  104. else if (uni_stricmp(command, UNI_L("OPERA-DEFAULTBLOCK")) == 0)
  105. return OP_DOCUMENT_EDIT_COMMAND_DEFAULT_BLOCK;
  106. break;
  107. case 'p': case 'P':
  108. if (uni_stricmp(command, UNI_L("PASTE")) == 0)
  109. return OP_DOCUMENT_EDIT_COMMAND_PASTE;
  110. break;
  111. case 'r': case 'R':
  112. if (uni_stricmp(command, UNI_L("READONLY")) == 0)
  113. return OP_DOCUMENT_EDIT_COMMAND_READONLY;
  114. else if (uni_stricmp(command, UNI_L("REDO")) == 0)
  115. return OP_DOCUMENT_EDIT_COMMAND_REDO;
  116. else if (uni_stricmp(command, UNI_L("REMOVEFORMAT")) == 0)
  117. return OP_DOCUMENT_EDIT_COMMAND_REMOVEFORMAT;
  118. break;
  119. case 's': case 'S':
  120. if (uni_stricmp(command, UNI_L("SELECTALL")) == 0)
  121. return OP_DOCUMENT_EDIT_COMMAND_SELECTALL;
  122. #ifdef SPELLCHECK_COMMAND_SUPPORT
  123. else if (uni_stricmp(command, UNI_L("SPELLCHECK")) == 0)
  124. return OP_DOCUMENT_EDIT_COMMAND_SPELLCHECK;
  125. else if (uni_stricmp(command, UNI_L("SPELLCHECK_BLOCKING")) == 0)
  126. return OP_DOCUMENT_EDIT_COMMAND_SPELLCHECK_BLOCKING;
  127. else if (uni_stricmp(command, UNI_L("SPELLCHECK_DEBUG")) == 0)
  128. return OP_DOCUMENT_EDIT_COMMAND_SPELLCHECK_DEBUG;
  129. else if (uni_stricmp(command, UNI_L("SPELLCHECK_HAS_MISSPELLING")) == 0)
  130. return OP_DOCUMENT_EDIT_COMMAND_SPELLCHECK_HAS_MISSPELLING;
  131. #endif
  132. else if (uni_stricmp(command, UNI_L("STRIKETHROUGH")) == 0)
  133. return OP_DOCUMENT_EDIT_COMMAND_STRIKETHROUGH;
  134. else if(uni_stricmp(command, UNI_L("STYLEWITHCSS")) == 0)
  135. return OP_DOCUMENT_EDIT_COMMAND_STYLEWITHCSS;
  136. else if (uni_stricmp(command, UNI_L("SUBSCRIPT")) == 0)
  137. return OP_DOCUMENT_EDIT_COMMAND_SUBSCRIPT;
  138. else if (uni_stricmp(command, UNI_L("SUPERSCRIPT")) == 0)
  139. return OP_DOCUMENT_EDIT_COMMAND_SUPERSCRIPT;
  140. break;
  141. case 'u': case 'U':
  142. if (uni_stricmp(command, UNI_L("UNDERLINE")) == 0)
  143. return OP_DOCUMENT_EDIT_COMMAND_UNDERLINE;
  144. else if (uni_stricmp(command, UNI_L("UNDO")) == 0)
  145. return OP_DOCUMENT_EDIT_COMMAND_UNDO;
  146. else if (uni_stricmp(command, UNI_L("UNLINK")) == 0)
  147. return OP_DOCUMENT_EDIT_COMMAND_UNLINK;
  148. else if (uni_stricmp(command, UNI_L("UNSELECT")) == 0)
  149. return OP_DOCUMENT_EDIT_COMMAND_UNSELECT;
  150. else if (uni_stricmp(command, UNI_L("USECSS")) == 0)
  151. return OP_DOCUMENT_EDIT_COMMAND_USECSS;
  152. break;
  153. }
  154. return OP_DOCUMENT_EDIT_COMMAND_UNKNOWN;
  155. }
  156. static HTML_ElementType ConvertFormatBlockValueToType(const uni_char* value)
  157. {
  158. DEBUG_CHECKER_STATIC();
  159. // Fix: escape the string.
  160. if (uni_stristr(value, UNI_L("PRE")))
  161. return HE_PRE;
  162. else if (uni_stristr(value, UNI_L("P")))
  163. return HE_P;
  164. else if (uni_stristr(value, UNI_L("DIV")))
  165. return HE_DIV;
  166. else if (uni_stristr(value, UNI_L("H1")))
  167. return HE_H1;
  168. else if (uni_stristr(value, UNI_L("H2")))
  169. return HE_H2;
  170. else if (uni_stristr(value, UNI_L("H3")))
  171. return HE_H3;
  172. else if (uni_stristr(value, UNI_L("H4")))
  173. return HE_H4;
  174. else if (uni_stristr(value, UNI_L("H5")))
  175. return HE_H5;
  176. else if (uni_stristr(value, UNI_L("H6")))
  177. return HE_H6;
  178. else if (uni_stristr(value, UNI_L("ADDRESS")))
  179. return HE_ADDRESS;
  180. else if (uni_stristr(value, UNI_L("BLOCKQUOTE")))
  181. return HE_BLOCKQUOTE;
  182. return HE_UNKNOWN;
  183. }
  184. static const uni_char* ConvertTypeToFormatBlockValue(HTML_ElementType type)
  185. {
  186. DEBUG_CHECKER_STATIC();
  187. switch(type)
  188. {
  189. // ADS 1.2 can't cope with returning strings directly !
  190. case HE_P: { const uni_char *tmp = UNI_L("P"); return tmp; }
  191. case HE_DIV: { const uni_char *tmp = UNI_L("DIV"); return tmp; }
  192. case HE_H1: { const uni_char *tmp = UNI_L("H1"); return tmp; }
  193. case HE_H2: { const uni_char *tmp = UNI_L("H2"); return tmp; }
  194. case HE_H3: { const uni_char *tmp = UNI_L("H3"); return tmp; }
  195. case HE_H4: { const uni_char *tmp = UNI_L("H4"); return tmp; }
  196. case HE_H5: { const uni_char *tmp = UNI_L("H5"); return tmp; }
  197. case HE_H6: { const uni_char *tmp = UNI_L("H6"); return tmp; }
  198. case HE_ADDRESS: { const uni_char *tmp = UNI_L("ADDRESS"); return tmp; }
  199. case HE_PRE: { const uni_char *tmp = UNI_L("PRE"); return tmp; }
  200. case HE_BLOCKQUOTE: { const uni_char *tmp = UNI_L("BLOCKQUOTE"); return tmp; }
  201. }
  202. const uni_char * tmp = UNI_L("");
  203. return tmp;
  204. }
  205. static HTML_ElementType ConvertCommandToType(OP_DOCUMENT_EDIT_COMMAND command)
  206. {
  207. DEBUG_CHECKER_STATIC();
  208. switch(command)
  209. {
  210. case OP_DOCUMENT_EDIT_COMMAND_BOLD: return HE_STRONG;
  211. case OP_DOCUMENT_EDIT_COMMAND_ITALIC: return HE_EM;
  212. case OP_DOCUMENT_EDIT_COMMAND_UNDERLINE: return HE_U;
  213. case OP_DOCUMENT_EDIT_COMMAND_STRIKETHROUGH: return HE_STRIKE;
  214. case OP_DOCUMENT_EDIT_COMMAND_SUBSCRIPT: return HE_SUB;
  215. case OP_DOCUMENT_EDIT_COMMAND_SUPERSCRIPT: return HE_SUP;
  216. case OP_DOCUMENT_EDIT_COMMAND_DECREASEFONTSIZE: return HE_SMALL;
  217. case OP_DOCUMENT_EDIT_COMMAND_INCREASEFONTSIZE: return HE_BIG;
  218. case OP_DOCUMENT_EDIT_COMMAND_CREATELINK: return HE_A;
  219. case OP_DOCUMENT_EDIT_COMMAND_INSERTORDEREDLIST: return HE_OL;
  220. case OP_DOCUMENT_EDIT_COMMAND_INSERTUNORDEREDLIST: return HE_UL;
  221. case OP_DOCUMENT_EDIT_COMMAND_INSERTPARAGRAPH: return HE_P;
  222. }
  223. return HE_UNKNOWN;
  224. }
  225. static int ConvertCommandToAlign(OP_DOCUMENT_EDIT_COMMAND command)
  226. {
  227. DEBUG_CHECKER_STATIC();
  228. int align = CSS_VALUE_left;
  229. switch(command)
  230. {
  231. case OP_DOCUMENT_EDIT_COMMAND_JUSTIFYCENTER: align = CSS_VALUE_center; break;
  232. case OP_DOCUMENT_EDIT_COMMAND_JUSTIFYFULL: align = CSS_VALUE_justify; break;
  233. case OP_DOCUMENT_EDIT_COMMAND_JUSTIFYRIGHT: align = CSS_VALUE_right; break;
  234. }
  235. return align;
  236. }
  237. static BOOL GetAllowCommandInReadonly(OP_DOCUMENT_EDIT_COMMAND command)
  238. {
  239. DEBUG_CHECKER_STATIC();
  240. switch(command)
  241. {
  242. case OP_DOCUMENT_EDIT_COMMAND_USECSS:
  243. case OP_DOCUMENT_EDIT_COMMAND_STYLEWITHCSS:
  244. case OP_DOCUMENT_EDIT_COMMAND_READONLY:
  245. case OP_DOCUMENT_EDIT_COMMAND_CONTENTREADONLY:
  246. case OP_DOCUMENT_EDIT_COMMAND_COPY:
  247. case OP_DOCUMENT_EDIT_COMMAND_SELECTALL:
  248. return TRUE;
  249. }
  250. return FALSE;
  251. }
  252. /* static */
  253. OP_STATUS OpDocumentEdit::execCommand(const uni_char* command, OpDocumentEdit* document_edit, BOOL showui, const uni_char* value, URL& origin_url, FramesDocument* frm_doc)
  254. {
  255. OP_ASSERT((document_edit || frm_doc) && origin_url.IsValid());
  256. OP_DOCUMENT_EDIT_COMMAND cmd = ConvertCommand(command);
  257. if (document_edit)
  258. {
  259. RETURN_IF_ERROR(document_edit->queryCommandSupported(cmd, origin_url));
  260. return document_edit->execCommand(cmd, showui, value);
  261. }
  262. else
  263. /* Spec allows some commands to be called without existing
  264. "editing host". We are handling a subset as it's not
  265. always clear how specific commands should be handled. */
  266. switch (cmd)
  267. {
  268. #ifdef USE_OP_CLIPBOARD
  269. case OP_DOCUMENT_EDIT_COMMAND_COPY:
  270. case OP_DOCUMENT_EDIT_COMMAND_CUT:
  271. case OP_DOCUMENT_EDIT_COMMAND_PASTE:
  272. {
  273. if (!DOM_Utils::IsClipboardAccessAllowed(origin_url, frm_doc->GetWindow()))
  274. return OpStatus::ERR_NO_ACCESS;
  275. OP_STATUS status;
  276. ClipboardListener *listener = frm_doc->GetClipboardListener();
  277. if (cmd == OP_DOCUMENT_EDIT_COMMAND_COPY)
  278. status = g_clipboard_manager->Copy(listener, frm_doc->GetWindow()->GetUrlContextId(), frm_doc);
  279. else if (cmd == OP_DOCUMENT_EDIT_COMMAND_CUT)
  280. status = g_clipboard_manager->Cut(listener, frm_doc->GetWindow()->GetUrlContextId(), frm_doc);
  281. else
  282. status = g_clipboard_manager->Paste(listener, frm_doc);
  283. return status;
  284. }
  285. #endif // USE_OP_CLIPBOARD
  286. default:
  287. return OpStatus::ERR_NOT_SUPPORTED;
  288. }
  289. }
  290. /* static */
  291. BOOL OpDocumentEdit::queryCommandEnabled(const uni_char* command, OpDocumentEdit* document_edit, URL& origin_url, FramesDocument* frm_doc)
  292. {
  293. OP_ASSERT(document_edit || (origin_url.IsValid() && frm_doc));
  294. if (document_edit)
  295. {
  296. document_edit->CheckLogTreeChanged();
  297. return document_edit->queryCommandEnabled(ConvertCommand(command));
  298. }
  299. else
  300. switch (ConvertCommand(command))
  301. {
  302. #ifdef USE_OP_CLIPBOARD
  303. case OP_DOCUMENT_EDIT_COMMAND_COPY:
  304. case OP_DOCUMENT_EDIT_COMMAND_CUT:
  305. return DOM_Utils::IsClipboardAccessAllowed(origin_url, frm_doc->GetWindow()) && frm_doc->HasSelectedText();
  306. case OP_DOCUMENT_EDIT_COMMAND_PASTE:
  307. return DOM_Utils::IsClipboardAccessAllowed(origin_url, frm_doc->GetWindow()) && g_clipboard_manager->HasText();
  308. #endif // USE_OP_CLIPBOARD
  309. default:
  310. return FALSE;
  311. }
  312. }
  313. BOOL OpDocumentEdit::queryCommandState(const uni_char* command)
  314. {
  315. DEBUG_CHECKER(TRUE);
  316. CheckLogTreeChanged();
  317. return queryCommandState(ConvertCommand(command));
  318. }
  319. /* static */
  320. BOOL OpDocumentEdit::queryCommandSupported(const uni_char* command, OpDocumentEdit* document_edit, URL& origin_url, FramesDocument* frm_doc)
  321. {
  322. OP_ASSERT((document_edit || frm_doc) && origin_url.IsValid());
  323. if (document_edit)
  324. {
  325. document_edit->CheckLogTreeChanged();
  326. return OpStatus::IsSuccess(document_edit->queryCommandSupported(ConvertCommand(command), origin_url));
  327. }
  328. else
  329. switch (ConvertCommand(command))
  330. {
  331. #ifdef USE_OP_CLIPBOARD
  332. case OP_DOCUMENT_EDIT_COMMAND_COPY:
  333. case OP_DOCUMENT_EDIT_COMMAND_CUT:
  334. case OP_DOCUMENT_EDIT_COMMAND_PASTE:
  335. return DOM_Utils::IsClipboardAccessAllowed(origin_url, frm_doc->GetWindow());
  336. #endif // USE_OP_CLIPBOARD
  337. default:
  338. return FALSE;
  339. }
  340. }
  341. OP_STATUS OpDocumentEdit::queryCommandValue(const uni_char* command, TempBuffer& value)
  342. {
  343. DEBUG_CHECKER(TRUE);
  344. CheckLogTreeChanged();
  345. return queryCommandValue(ConvertCommand(command), value);
  346. }
  347. OP_STATUS OpDocumentEdit::execCommand(OP_DOCUMENT_EDIT_COMMAND command, BOOL showui, const uni_char* value)
  348. {
  349. DEBUG_CHECKER(TRUE);
  350. CheckLogTreeChanged();
  351. if (m_readonly && !GetAllowCommandInReadonly(command))
  352. return OpStatus::ERR_NOT_SUPPORTED;
  353. ReflowAndUpdate();
  354. switch(command)
  355. {
  356. case OP_DOCUMENT_EDIT_COMMAND_USECSS:
  357. if (value)
  358. // I think FALSE should be TRUE here. But mozilla and mozillas testsuite seem to have mixed it up??
  359. m_usecss = (uni_stricmp(value, UNI_L("FALSE")) == 0);
  360. break;
  361. case OP_DOCUMENT_EDIT_COMMAND_STYLEWITHCSS:
  362. if (value)
  363. // I think FALSE should be TRUE here. But mozilla and mozillas testsuite seem to have mixed it up??
  364. m_usecss = (uni_stricmp(value, UNI_L("TRUE")) == 0);
  365. break;
  366. #ifdef SPELLCHECK_COMMAND_SUPPORT
  367. case OP_DOCUMENT_EDIT_COMMAND_SPELLCHECK_BLOCKING:
  368. m_blocking_spellcheck = TRUE;
  369. case OP_DOCUMENT_EDIT_COMMAND_SPELLCHECK:
  370. return HandleSpellCheckCommand(showui, value);
  371. #endif
  372. case OP_DOCUMENT_EDIT_COMMAND_READONLY:
  373. if (value) // Depricated command. Replaced by CONTENTREADONLY to fix mozilla bug.
  374. m_readonly = (uni_stricmp(value, UNI_L("FALSE")) == 0);
  375. break;
  376. case OP_DOCUMENT_EDIT_COMMAND_CONTENTREADONLY:
  377. if (value)
  378. m_readonly = (uni_stricmp(value, UNI_L("TRUE")) == 0);
  379. break;
  380. case OP_DOCUMENT_EDIT_COMMAND_HILITECOLOR:
  381. if (value)
  382. {
  383. TempBuffer text;
  384. REPORT_AND_RETURN_FALSE_IF_ERROR(text.Append("background-color: "));
  385. REPORT_AND_RETURN_FALSE_IF_ERROR(text.Append(value));
  386. REPORT_AND_RETURN_FALSE_IF_ERROR(text.Append(";"));
  387. HTML_Element* helm = NewElement(HE_SPAN);
  388. if (!helm)
  389. {
  390. ReportOOM();
  391. return FALSE;
  392. }
  393. REPORT_AND_RETURN_FALSE_IF_ERROR(helm->SetAttribute(GetDoc(), ATTR_STYLE, NULL, NS_IDX_DEFAULT, text.GetStorage(), text.Length(), NULL, FALSE));
  394. REPORT_AND_RETURN_FALSE_IF_ERROR(InsertStyleElement(helm));
  395. }
  396. break;
  397. case OP_DOCUMENT_EDIT_COMMAND_BACKCOLOR:
  398. if (value && m_caret.GetElement())
  399. {
  400. HTML_Element* root = m_doc->GetCaret()->GetContainingElementActual(m_caret.GetElement());
  401. BeginChange(root);
  402. CSS_DOMStyleDeclaration *styledeclaration;
  403. if (OpStatus::IsSuccess(root->DOMGetInlineStyle(styledeclaration, m_doc->GetDOMEnvironment())))
  404. {
  405. OnElementChange(root);
  406. CSS_DOMException exception = CSS_DOMEXCEPTION_NONE;
  407. styledeclaration->SetProperty(CSS_PROPERTY_background_color, value, exception);
  408. OP_DELETE(styledeclaration);
  409. OnElementChanged(root);
  410. }
  411. EndChange(root);
  412. }
  413. break;
  414. case OP_DOCUMENT_EDIT_COMMAND_BOLD:
  415. case OP_DOCUMENT_EDIT_COMMAND_ITALIC:
  416. case OP_DOCUMENT_EDIT_COMMAND_UNDERLINE:
  417. case OP_DOCUMENT_EDIT_COMMAND_STRIKETHROUGH:
  418. case OP_DOCUMENT_EDIT_COMMAND_SUBSCRIPT:
  419. case OP_DOCUMENT_EDIT_COMMAND_SUPERSCRIPT:
  420. {
  421. HTML_ElementType type = ConvertCommandToType(command);
  422. BOOL removed = FALSE;
  423. m_undo_stack.BeginGroup();
  424. if (command == OP_DOCUMENT_EDIT_COMMAND_ITALIC)
  425. {
  426. // Special case since italic need to check 2 types
  427. if (GetHasStyle(HE_I,ATTR_NULL,TRUE))
  428. {
  429. RemoveStyle(HE_I);
  430. removed = TRUE;
  431. }
  432. else if(GetHasStyle(HE_I))
  433. RemoveStyle(HE_I);
  434. if (GetHasStyle(HE_EM,ATTR_NULL,TRUE))
  435. {
  436. RemoveStyle(HE_EM);
  437. removed = TRUE;
  438. }
  439. else if(GetHasStyle(HE_EM))
  440. RemoveStyle(HE_EM);
  441. }
  442. else if (command == OP_DOCUMENT_EDIT_COMMAND_BOLD)
  443. {
  444. // Special case since bold need to check 2 types
  445. if (GetHasStyle(HE_B,ATTR_NULL,TRUE))
  446. {
  447. RemoveStyle(HE_B);
  448. removed = TRUE;
  449. }
  450. else if(GetHasStyle(HE_B))
  451. RemoveStyle(HE_B);
  452. if (GetHasStyle(HE_STRONG,ATTR_NULL,TRUE))
  453. {
  454. RemoveStyle(HE_STRONG);
  455. removed = TRUE;
  456. }
  457. else if(GetHasStyle(HE_STRONG))
  458. RemoveStyle(HE_STRONG);
  459. }
  460. else if (GetHasStyle(type,ATTR_NULL,TRUE))
  461. {
  462. RemoveStyle(type);
  463. removed = TRUE;
  464. }
  465. else if(GetHasStyle(type))
  466. RemoveStyle(type);
  467. if (!removed)
  468. InsertStyle(type);
  469. m_undo_stack.EndGroup();
  470. }
  471. break;
  472. case OP_DOCUMENT_EDIT_COMMAND_DECREASEFONTSIZE:
  473. case OP_DOCUMENT_EDIT_COMMAND_INCREASEFONTSIZE:
  474. {
  475. HTML_ElementType this_type = command == OP_DOCUMENT_EDIT_COMMAND_DECREASEFONTSIZE ? HE_SMALL : HE_BIG;
  476. HTML_ElementType other_type = this_type == HE_SMALL ? HE_BIG : HE_SMALL;
  477. m_undo_stack.BeginGroup();
  478. if(m_selection.HasContent())
  479. {
  480. InsertStyle(this_type,other_type,TRUE,HE_FONT);
  481. if(GetHasStyle(other_type))
  482. RemoveStyle(other_type,ATTR_NULL,TRUE);
  483. }
  484. else
  485. {
  486. if(GetHasStyle(other_type))
  487. RemoveStyle(other_type,ATTR_NULL,TRUE);
  488. else
  489. InsertStyle(this_type,(HTML_ElementType)0,TRUE,HE_FONT);
  490. }
  491. m_undo_stack.EndGroup();
  492. }
  493. break;
  494. case OP_DOCUMENT_EDIT_COMMAND_REMOVEFORMAT:
  495. if (GetHasStyle(HE_ANY))
  496. RemoveStyle(HE_ANY);
  497. break;
  498. case OP_DOCUMENT_EDIT_COMMAND_CREATELINK:
  499. {
  500. SelectionState state = GetSelectionState(FALSE);
  501. if (value && (state.HasEditableContent() || m_layout_modifier.IsActive()))
  502. {
  503. HTML_Element *start = NULL, *stop = NULL;
  504. if(m_layout_modifier.IsActive())
  505. start = stop = m_layout_modifier.m_helm;
  506. else
  507. {
  508. start = state.editable_start_elm;
  509. stop = state.editable_stop_elm;
  510. }
  511. int true_count = 0;
  512. void *args[2];
  513. args[0] = this; args[1] = (void*)value;
  514. REPORT_AND_RETURN_FALSE_IF_ERROR(ApplyFunctionBetween(start,stop,&SetNewHref,args,NULL,&true_count));
  515. if(true_count)
  516. break; // we've changed href on at least ONE anchor in the selection, that's all, don't do any more
  517. HTML_Element *new_elm = NewElement(HE_A);
  518. if (!new_elm)
  519. {
  520. ReportOOM();
  521. return FALSE;
  522. }
  523. new_elm->SetAttribute(m_doc, ATTR_HREF, NULL, NS_IDX_DEFAULT, value, uni_strlen(value), NULL, FALSE);
  524. REPORT_AND_RETURN_FALSE_IF_ERROR(InsertStyleElement(new_elm));
  525. }
  526. }
  527. break;
  528. case OP_DOCUMENT_EDIT_COMMAND_DELETE:
  529. {
  530. OpInputAction action(OpInputAction::ACTION_DELETE);
  531. OnInputAction(&action);
  532. }
  533. break;
  534. case OP_DOCUMENT_EDIT_COMMAND_FONTNAME:
  535. if (value)
  536. InsertFontFace(value);
  537. break;
  538. case OP_DOCUMENT_EDIT_COMMAND_FONTSIZE:
  539. if (value)
  540. {
  541. if(GetHasStyle(HE_BIG))
  542. RemoveStyle(HE_BIG);
  543. if(GetHasStyle(HE_SMALL))
  544. RemoveStyle(HE_SMALL);
  545. InsertFontSize(uni_atoi(value));
  546. }
  547. break;
  548. case OP_DOCUMENT_EDIT_COMMAND_FORECOLOR:
  549. if (value)
  550. {
  551. BOOL do_insert = FALSE;
  552. COLORREF container_color, caret_color;
  553. COLORREF new_color = GetColorVal(value, uni_strlen(value), TRUE);
  554. if(m_caret.GetElement())
  555. {
  556. Head prop_list;
  557. HLDocProfile *hld_profile = m_doc->GetHLDocProfile();
  558. GetSelectionState(FALSE);
  559. HTML_Element* containing_elm = m_doc->GetCaret()->GetContainingElement(m_caret.GetElement());
  560. LayoutProperties* lprops = LayoutProperties::CreateCascade(
  561. containing_elm, prop_list, hld_profile);
  562. if(lprops)
  563. {
  564. container_color = lprops->GetProps()->font_color;
  565. LayoutProperties* child_props = lprops->GetChildProperties(hld_profile, m_caret.GetElement());
  566. if (child_props)
  567. {
  568. caret_color = child_props->GetProps()->font_color;
  569. if (new_color != caret_color)
  570. {
  571. /* If the new color is different from the current one and the one from
  572. * the container element then insert a font tag */
  573. if (new_color != container_color)
  574. do_insert = TRUE;
  575. else if (GetHasStyle(HE_FONT, ATTR_COLOR))
  576. {
  577. /* Otherwise, if we were in a font tag with a different color than
  578. * the containing element, but the new color matches the container
  579. * element's once again, we should continue editing outside of the
  580. * font tag. (a sort of "reset color"). */
  581. RemoveStyle(HE_FONT, ATTR_COLOR);
  582. }
  583. }
  584. }
  585. else
  586. do_insert = TRUE;
  587. prop_list.Clear();
  588. }
  589. }
  590. else
  591. do_insert = TRUE;
  592. if (do_insert)
  593. InsertFontColor(new_color);
  594. }
  595. break;
  596. case OP_DOCUMENT_EDIT_COMMAND_INSERTPARAGRAPH:
  597. // IE's always inserts paragraph if this is called from script. (Even if inside pre)
  598. if(m_caret.GetElement())
  599. InsertBreak(TRUE, TRUE);
  600. break;
  601. case OP_DOCUMENT_EDIT_COMMAND_FORMATBLOCK:
  602. if (value)
  603. {
  604. HTML_ElementType newtype = ConvertFormatBlockValueToType(value);
  605. if (newtype == HE_UNKNOWN)
  606. return FALSE;
  607. // Add the new format to the block
  608. HTML_Element* helm = NewElement(newtype);
  609. if (helm)
  610. {
  611. m_undo_stack.BeginGroup();
  612. HTML_ElementType remove_types[] = { HE_P, HE_DIV, HE_H1, HE_H2, HE_H3, HE_H4, HE_H5, HE_H6, HE_ADDRESS, HE_PRE, HE_UNKNOWN };
  613. if(OpStatus::IsSuccess(InsertBlockElementMultiple(helm,FALSE,FALSE,newtype==HE_DIV,remove_types)))
  614. {
  615. // Remove any existing format from the block
  616. RemoveBlockTypes(remove_types,ATTR_NULL,FALSE,newtype);
  617. }
  618. m_undo_stack.EndGroup();
  619. }
  620. else
  621. ReportOOM();
  622. }
  623. break;
  624. case OP_DOCUMENT_EDIT_COMMAND_INSERTHORIZONTALRULE:
  625. if(m_caret.GetElement())
  626. {
  627. const uni_char* tmp = UNI_L("<hr>");
  628. InsertTextHTML(tmp, uni_strlen(tmp),NULL,NULL,GetHrContainer(m_caret.GetElement()));
  629. }
  630. break;
  631. case OP_DOCUMENT_EDIT_COMMAND_INSERTHTML:
  632. if (value)
  633. {
  634. BOOL is_html = uni_strpbrk(value, UNI_L("<&")) != NULL;
  635. if (!is_html)
  636. InsertPlainText(value, uni_strlen(value));
  637. else
  638. InsertTextHTML(value, uni_strlen(value), NULL, NULL, NULL, TIDY_LEVEL_MINIMAL);
  639. }
  640. break;
  641. case OP_DOCUMENT_EDIT_COMMAND_INSERTIMAGE:
  642. if (value)
  643. {
  644. TempBuffer str;
  645. str.Append(UNI_L("<img src=\""));
  646. str.Append(value);
  647. str.Append(UNI_L("\">"));
  648. InsertTextHTML(str.GetStorage(), str.Length());
  649. }
  650. break;
  651. case OP_DOCUMENT_EDIT_COMMAND_INSERTORDEREDLIST:
  652. case OP_DOCUMENT_EDIT_COMMAND_INSERTUNORDEREDLIST:
  653. ToggleInsertList(command == OP_DOCUMENT_EDIT_COMMAND_INSERTORDEREDLIST);
  654. break;
  655. case OP_DOCUMENT_EDIT_COMMAND_INDENT:
  656. {
  657. OP_STATUS status = OpStatus::OK;
  658. HTML_ElementType list_types[] = {HE_OL,HE_UL,HE_UNKNOWN};
  659. BOOL includes_lists = GetHasBlockTypes(list_types);
  660. m_undo_stack.BeginGroup();
  661. if(m_usecss)
  662. status = IndentSelection(40);
  663. else
  664. {
  665. HTML_Element* helm = NewElement(HE_BLOCKQUOTE);
  666. if (helm)
  667. status = InsertBlockElementMultiple(helm,includes_lists);
  668. else
  669. status = OpStatus::ERR_NO_MEMORY;
  670. }
  671. if(OpStatus::IsSuccess(status) && includes_lists)
  672. status = IncreaseListNestling();
  673. if(OpStatus::IsMemoryError(status))
  674. ReportOOM();
  675. m_undo_stack.EndGroup();
  676. }
  677. break;
  678. case OP_DOCUMENT_EDIT_COMMAND_JUSTIFYCENTER:
  679. case OP_DOCUMENT_EDIT_COMMAND_JUSTIFYFULL:
  680. case OP_DOCUMENT_EDIT_COMMAND_JUSTIFYLEFT:
  681. case OP_DOCUMENT_EDIT_COMMAND_JUSTIFYRIGHT:
  682. JustifySelection((CSSValue)ConvertCommandToAlign(command));
  683. break;
  684. case OP_DOCUMENT_EDIT_COMMAND_OUTDENT:
  685. {
  686. HTML_ElementType types[] = {HE_BLOCKQUOTE, HE_UNKNOWN};
  687. HTML_ElementType list_types[] = {HE_OL,HE_UL,HE_UNKNOWN};
  688. m_undo_stack.BeginGroup();
  689. if(m_usecss)
  690. IndentSelection(-40);
  691. else
  692. RemoveBlockTypes(types,ATTR_NULL,TRUE);
  693. if(GetHasBlockTypes(list_types))
  694. DecreaseListNestling();
  695. m_undo_stack.EndGroup();
  696. }
  697. break;
  698. #ifdef USE_OP_CLIPBOARD
  699. case OP_DOCUMENT_EDIT_COMMAND_CUT:
  700. Cut();
  701. break;
  702. case OP_DOCUMENT_EDIT_COMMAND_COPY:
  703. Copy();
  704. break;
  705. case OP_DOCUMENT_EDIT_COMMAND_PASTE:
  706. {
  707. HTML_Element* target = m_selection.HasContent() ? m_selection.GetStartElement() : m_caret.GetElement();
  708. g_clipboard_manager->Paste(this, m_doc, target);
  709. }
  710. break;
  711. #endif // USE_OP_CLIPBOARD
  712. case OP_DOCUMENT_EDIT_COMMAND_UNDO:
  713. Undo();
  714. break;
  715. case OP_DOCUMENT_EDIT_COMMAND_REDO:
  716. Redo();
  717. break;
  718. case OP_DOCUMENT_EDIT_COMMAND_SELECTALL:
  719. m_selection.SelectAll();
  720. break;
  721. case OP_DOCUMENT_EDIT_COMMAND_UNLINK:
  722. if (GetHasStyle(HE_A))
  723. RemoveStyle(HE_A);
  724. break;
  725. case OP_DOCUMENT_EDIT_COMMAND_UNSELECT:
  726. m_selection.SelectNothing();
  727. break;
  728. case OP_DOCUMENT_EDIT_COMMAND_DEFAULT_BLOCK:
  729. if (uni_stri_eq(value, UNI_L("p")) || uni_stri_eq(value, UNI_L("div")))
  730. m_paragraph_element_type = static_cast<HTML_ElementType>(HTM_Lex::GetTag(value, uni_strlen(value)));
  731. break;
  732. default:
  733. OP_ASSERT(0);
  734. break;
  735. }
  736. if (m_listener)
  737. m_listener->OnTextChanged();
  738. return OpStatus::OK;
  739. }
  740. BOOL OpDocumentEdit::queryCommandEnabled(OP_DOCUMENT_EDIT_COMMAND command)
  741. {
  742. DEBUG_CHECKER(TRUE);
  743. switch(command)
  744. {
  745. case OP_DOCUMENT_EDIT_COMMAND_USECSS:
  746. return !m_usecss;
  747. case OP_DOCUMENT_EDIT_COMMAND_STYLEWITHCSS:
  748. return m_usecss;
  749. case OP_DOCUMENT_EDIT_COMMAND_READONLY:
  750. case OP_DOCUMENT_EDIT_COMMAND_CONTENTREADONLY:
  751. return TRUE;
  752. case OP_DOCUMENT_EDIT_COMMAND_HILITECOLOR:
  753. case OP_DOCUMENT_EDIT_COMMAND_BACKCOLOR:
  754. return TRUE;
  755. case OP_DOCUMENT_EDIT_COMMAND_BOLD:
  756. case OP_DOCUMENT_EDIT_COMMAND_ITALIC:
  757. case OP_DOCUMENT_EDIT_COMMAND_UNDERLINE:
  758. case OP_DOCUMENT_EDIT_COMMAND_STRIKETHROUGH:
  759. case OP_DOCUMENT_EDIT_COMMAND_SUBSCRIPT:
  760. case OP_DOCUMENT_EDIT_COMMAND_SUPERSCRIPT:
  761. return TRUE;
  762. case OP_DOCUMENT_EDIT_COMMAND_DECREASEFONTSIZE:
  763. case OP_DOCUMENT_EDIT_COMMAND_INCREASEFONTSIZE:
  764. return TRUE;
  765. case OP_DOCUMENT_EDIT_COMMAND_REMOVEFORMAT:
  766. return GetHasStyle(HE_ANY);
  767. case OP_DOCUMENT_EDIT_COMMAND_CREATELINK:
  768. return m_selection.HasContent();
  769. case OP_DOCUMENT_EDIT_COMMAND_DELETE:
  770. case OP_DOCUMENT_EDIT_COMMAND_FONTNAME:
  771. case OP_DOCUMENT_EDIT_COMMAND_FONTSIZE:
  772. case OP_DOCUMENT_EDIT_COMMAND_FORECOLOR:
  773. return TRUE;
  774. case OP_DOCUMENT_EDIT_COMMAND_FORMATBLOCK:
  775. case OP_DOCUMENT_EDIT_COMMAND_INDENT:
  776. case OP_DOCUMENT_EDIT_COMMAND_INSERTPARAGRAPH:
  777. return TRUE;
  778. case OP_DOCUMENT_EDIT_COMMAND_INSERTHORIZONTALRULE:
  779. return TRUE;
  780. case OP_DOCUMENT_EDIT_COMMAND_INSERTHTML:
  781. return TRUE;
  782. case OP_DOCUMENT_EDIT_COMMAND_INSERTIMAGE:
  783. return TRUE;
  784. case OP_DOCUMENT_EDIT_COMMAND_INSERTORDEREDLIST:
  785. case OP_DOCUMENT_EDIT_COMMAND_INSERTUNORDEREDLIST:
  786. return TRUE;
  787. case OP_DOCUMENT_EDIT_COMMAND_JUSTIFYCENTER:
  788. case OP_DOCUMENT_EDIT_COMMAND_JUSTIFYFULL:
  789. case OP_DOCUMENT_EDIT_COMMAND_JUSTIFYLEFT:
  790. case OP_DOCUMENT_EDIT_COMMAND_JUSTIFYRIGHT:
  791. return TRUE;
  792. case OP_DOCUMENT_EDIT_COMMAND_OUTDENT:
  793. {
  794. HTML_ElementType types[] = {HE_BLOCKQUOTE,HE_OL,HE_UL,HE_UNKNOWN};
  795. return GetHasBlockTypes(types);
  796. }
  797. #ifdef USE_OP_CLIPBOARD
  798. case OP_DOCUMENT_EDIT_COMMAND_COPY:
  799. return m_selection.HasContent() || m_layout_modifier.IsActive();
  800. case OP_DOCUMENT_EDIT_COMMAND_CUT:
  801. return m_selection.HasContent() || m_layout_modifier.IsActive();
  802. case OP_DOCUMENT_EDIT_COMMAND_PASTE:
  803. return g_clipboard_manager->HasText();
  804. #endif // USE_OP_CLIPBOARD
  805. case OP_DOCUMENT_EDIT_COMMAND_SELECTALL:
  806. return TRUE;
  807. case OP_DOCUMENT_EDIT_COMMAND_UNDO:
  808. return m_undo_stack.CanUndo();
  809. case OP_DOCUMENT_EDIT_COMMAND_REDO:
  810. return m_undo_stack.CanRedo();
  811. case OP_DOCUMENT_EDIT_COMMAND_UNLINK:
  812. return GetHasStyle(HE_A);
  813. case OP_DOCUMENT_EDIT_COMMAND_UNSELECT:
  814. return TRUE;
  815. }
  816. return FALSE;
  817. }
  818. BOOL OpDocumentEdit::queryCommandState(OP_DOCUMENT_EDIT_COMMAND command)
  819. {
  820. DEBUG_CHECKER(TRUE);
  821. HTML_ElementType indent_types[] = {HE_BLOCKQUOTE,HE_OL,HE_UL,HE_UNKNOWN};
  822. switch(command)
  823. {
  824. case OP_DOCUMENT_EDIT_COMMAND_USECSS:
  825. // I think FALSE should be TRUE here. But mozilla and mozillas testsuite seem to have mixed it up??
  826. return !m_usecss;
  827. case OP_DOCUMENT_EDIT_COMMAND_STYLEWITHCSS:
  828. return m_usecss;
  829. case OP_DOCUMENT_EDIT_COMMAND_READONLY:
  830. // Depricated command. Replaced by CONTENTREADONLY to fix mozilla bug.
  831. return !m_readonly;
  832. case OP_DOCUMENT_EDIT_COMMAND_CONTENTREADONLY:
  833. return m_readonly;
  834. case OP_DOCUMENT_EDIT_COMMAND_INDENT:
  835. return GetHasBlockTypes(indent_types);
  836. case OP_DOCUMENT_EDIT_COMMAND_OUTDENT:
  837. return !GetHasBlockTypes(indent_types);
  838. case OP_DOCUMENT_EDIT_COMMAND_CREATELINK:
  839. case OP_DOCUMENT_EDIT_COMMAND_UNLINK:
  840. case OP_DOCUMENT_EDIT_COMMAND_DECREASEFONTSIZE:
  841. case OP_DOCUMENT_EDIT_COMMAND_INCREASEFONTSIZE:
  842. return FALSE;
  843. #ifdef SPELLCHECK_COMMAND_SUPPORT
  844. case OP_DOCUMENT_EDIT_COMMAND_SPELLCHECK_HAS_MISSPELLING:
  845. return m_has_spellchecked;
  846. #endif // SPELLCHECK_COMMAND_SUPPORT
  847. case OP_DOCUMENT_EDIT_COMMAND_FONTNAME:
  848. return GetHasStyle(HE_FONT,ATTR_FACE);
  849. case OP_DOCUMENT_EDIT_COMMAND_FONTSIZE:
  850. return GetHasStyle(HE_FONT,ATTR_SIZE);
  851. case OP_DOCUMENT_EDIT_COMMAND_FORECOLOR:
  852. return GetHasStyle(HE_FONT,ATTR_COLOR);
  853. case OP_DOCUMENT_EDIT_COMMAND_JUSTIFYCENTER:
  854. case OP_DOCUMENT_EDIT_COMMAND_JUSTIFYFULL:
  855. case OP_DOCUMENT_EDIT_COMMAND_JUSTIFYLEFT:
  856. case OP_DOCUMENT_EDIT_COMMAND_JUSTIFYRIGHT:
  857. {
  858. HTML_ElementType check_types[] = { HE_TEXT, HE_BR, HE_UNKNOWN };
  859. int align = ConvertCommandToAlign(command);
  860. if(align == CSS_VALUE_left)
  861. return !GetSelectionMatchesFunction(&IsNonLeftAligned,NULL,NULL,NULL,FALSE,FALSE);
  862. return GetSelectionMatchesFunction(&IsAlignedAs,reinterpret_cast<void*>(align),&StaticIsMatchingType,check_types,TRUE,FALSE);
  863. }
  864. case OP_DOCUMENT_EDIT_COMMAND_FORMATBLOCK:
  865. {
  866. HTML_ElementType types[] = { HE_P, HE_H1, HE_H2, HE_H3, HE_H4, HE_H5, HE_H6, HE_ADDRESS, HE_PRE, HE_UNKNOWN };
  867. return GetHasBlockTypes(types);
  868. }
  869. default:
  870. break;
  871. }
  872. HTML_ElementType type = ConvertCommandToType(command);
  873. if(!(type == HE_UNKNOWN))
  874. {
  875. if(type == HE_STRONG || type == HE_B)
  876. return GetHasStyle(HE_STRONG,ATTR_NULL,TRUE) || GetHasStyle(HE_B,ATTR_NULL,TRUE);
  877. return GetHasStyle(type,ATTR_NULL,TRUE);
  878. }
  879. return FALSE;
  880. }
  881. OP_STATUS OpDocumentEdit::queryCommandSupported(OP_DOCUMENT_EDIT_COMMAND command, URL& origin_url)
  882. {
  883. DEBUG_CHECKER(TRUE);
  884. if (command == OP_DOCUMENT_EDIT_COMMAND_UNKNOWN)
  885. return OpStatus::ERR_NOT_SUPPORTED;
  886. if ((command == OP_DOCUMENT_EDIT_COMMAND_CUT ||
  887. command == OP_DOCUMENT_EDIT_COMMAND_COPY ||
  888. command == OP_DOCUMENT_EDIT_COMMAND_PASTE) && !DOM_Utils::IsClipboardAccessAllowed(origin_url, GetDoc()->GetWindow()))
  889. {
  890. return OpStatus::ERR_NO_ACCESS;
  891. }
  892. return OpStatus::OK;
  893. }
  894. OP_STATUS MakeColor(UINT32 col, TempBuffer& value)
  895. {
  896. DEBUG_CHECKER_STATIC();
  897. col = HTM_Lex::GetColValByIndex(col);
  898. uni_char buf[8]; /* ARRAY OK 2009-05-06 stighal */
  899. RETURN_IF_ERROR(value.Append("rgb("));
  900. uni_itoa(GetRValue(col), buf, 10);
  901. RETURN_IF_ERROR(value.Append(buf));
  902. RETURN_IF_ERROR(value.Append(","));
  903. uni_itoa(GetGValue(col), buf, 10);
  904. RETURN_IF_ERROR(value.Append(buf));
  905. RETURN_IF_ERROR(value.Append(","));
  906. uni_itoa(GetBValue(col), buf, 10);
  907. RETURN_IF_ERROR(value.Append(buf));
  908. RETURN_IF_ERROR(value.Append(")"));
  909. return OpStatus::OK;
  910. }
  911. OP_STATUS OpDocumentEdit::queryCommandValue(OP_DOCUMENT_EDIT_COMMAND command, TempBuffer& value)
  912. {
  913. DEBUG_CHECKER(TRUE);
  914. // FIX: mozilla only returns an empty string instead of the default value
  915. // even though the selection coverse several different values
  916. switch(command)
  917. {
  918. case OP_DOCUMENT_EDIT_COMMAND_FORMATBLOCK:
  919. {
  920. HTML_Element* containing_elm;
  921. if (m_caret.GetElement() && (containing_elm = m_doc->GetCaret()->GetContainingElement(m_caret.GetElement())))
  922. {
  923. HTML_ElementType type = containing_elm->Type();
  924. return value.Append(ConvertTypeToFormatBlockValue(type));
  925. }
  926. else
  927. return value.Append(UNI_L(""));
  928. }
  929. case OP_DOCUMENT_EDIT_COMMAND_FONTNAME:
  930. {
  931. return GetFontFace(value);
  932. }
  933. case OP_DOCUMENT_EDIT_COMMAND_FONTSIZE:
  934. {
  935. return value.AppendLong(GetFontSize());
  936. }
  937. case OP_DOCUMENT_EDIT_COMMAND_FORECOLOR:
  938. {
  939. HTML_Element* root = m_caret.GetElement();
  940. UINT32 color = OP_RGB(0, 0, 0);
  941. if (root)
  942. {
  943. Head prop_list;
  944. HLDocProfile *hld_profile = m_doc->GetHLDocProfile();
  945. LayoutProperties* lprops = LayoutProperties::CreateCascade(root, prop_list, hld_profile);
  946. if (lprops && lprops->GetProps()->font_color != USE_DEFAULT_COLOR)
  947. color = lprops->GetProps()->font_color;
  948. prop_list.Clear();
  949. }
  950. return MakeColor(color, value);
  951. }
  952. break;
  953. #ifdef SPELLCHECK_COMMAND_SUPPORT
  954. case OP_DOCUMENT_EDIT_COMMAND_SPELLCHECK_DEBUG:
  955. {
  956. OpString_list list;
  957. RETURN_IF_ERROR(g_internal_spellcheck->GetInstalledLanguages(list));
  958. for(int i=0;i<(int)list.Count();i++)
  959. {
  960. RETURN_IF_ERROR(value.Append(list.Item(i)));
  961. if(i != (int)(list.Count()-1))
  962. RETURN_IF_ERROR(value.Append(UNI_L(",")));
  963. }
  964. }
  965. break;
  966. #endif // SPELLCHECK_COMMAND_SUPPORT
  967. case OP_DOCUMENT_EDIT_COMMAND_HILITECOLOR:
  968. case OP_DOCUMENT_EDIT_COMMAND_BACKCOLOR:
  969. {
  970. if(!m_caret.GetElement())
  971. return value.Append(UNI_L(""));
  972. HTML_Element* containing_elm = m_doc->GetCaret()->GetContainingElement(m_caret.GetElement());
  973. HTML_Element* root = containing_elm;
  974. if (command == OP_DOCUMENT_EDIT_COMMAND_HILITECOLOR)
  975. {
  976. root = m_caret.GetElement();
  977. while(root && root != containing_elm && root->Type() != HE_SPAN /* || HasBackgroundColor(root) */)
  978. root = root->Parent();
  979. }
  980. UINT32 bg_color = OP_RGB(255,255,255);
  981. if (root)
  982. {
  983. Head prop_list;
  984. HLDocProfile *hld_profile = m_doc->GetHLDocProfile();
  985. LayoutProperties* lprops = LayoutProperties::CreateCascade(root, prop_list, hld_profile);
  986. if (lprops && lprops->GetProps()->bg_color != USE_DEFAULT_COLOR)
  987. bg_color = lprops->GetProps()->bg_color;
  988. prop_list.Clear();
  989. }
  990. return MakeColor(bg_color, value);
  991. }
  992. break;
  993. case OP_DOCUMENT_EDIT_COMMAND_DEFAULT_BLOCK:
  994. value.Append(HTM_Lex::GetTagString(m_paragraph_element_type));
  995. break;
  996. }
  997. return OpStatus::OK;
  998. }
  999. #endif // DOCUMENT_EDIT_SUPPORT