Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Organic Internet WYSIWYG editor module for Magento

  • Loading branch information...
commit 8df1eb8d61947fb742f8e622e242832c73520ce2 1 parent 9d1ad0c
@organicinternet authored
Showing with 34,692 additions and 0 deletions.
  1. +16 −0 app_code_community_OrganicInternet_WysiwygEditor/Block/Pagehead.php
  2. +5 −0 app_code_community_OrganicInternet_WysiwygEditor/Helper/Data.php
  3. +17 −0 app_code_community_OrganicInternet_WysiwygEditor/Model/Source/Editableareas.php
  4. +11 −0 app_code_community_OrganicInternet_WysiwygEditor/Model/Source/Editortype.php
  5. +50 −0 app_code_community_OrganicInternet_WysiwygEditor/etc/config.xml
  6. +50 −0 app_code_community_OrganicInternet_WysiwygEditor/etc/system.xml
  7. +8 −0 app_design_adminhtml_default_default_layout_organicinternet_wysiwygeditor.xml
  8. +54 −0 app_design_adminhtml_default_default_template_organicinternet_wysiwygeditor/page_head.phtml
  9. +9 −0 app_etc_modules_OrganicInternet_WysiwygEditor.xml
  10. +98 −0 js_tiny_mce/classes/AddOnManager.js
  11. +477 −0 js_tiny_mce/classes/ControlManager.js
  12. +91 −0 js_tiny_mce/classes/Developer.js
  13. +2,401 −0 js_tiny_mce/classes/Editor.js
  14. +1,014 −0 js_tiny_mce/classes/EditorCommands.js
  15. +446 −0 js_tiny_mce/classes/EditorManager.js
  16. +561 −0 js_tiny_mce/classes/ForceBlocks.js
  17. +371 −0 js_tiny_mce/classes/Popup.js
  18. +181 −0 js_tiny_mce/classes/UndoManager.js
  19. +169 −0 js_tiny_mce/classes/WindowManager.js
  20. +212 −0 js_tiny_mce/classes/adapter/jquery/adapter.js
  21. +2,992 −0 js_tiny_mce/classes/adapter/jquery/jquery.js
  22. +38 −0 js_tiny_mce/classes/adapter/prototype/adapter.js
  23. +4,152 −0 js_tiny_mce/classes/adapter/prototype/prototype.js
  24. +1,698 −0 js_tiny_mce/classes/dom/DOMUtils.js
  25. +206 −0 js_tiny_mce/classes/dom/Element.js
  26. +295 −0 js_tiny_mce/classes/dom/Event.js
  27. +302 −0 js_tiny_mce/classes/dom/ScriptLoader.js
  28. +666 −0 js_tiny_mce/classes/dom/Selection.js
  29. +959 −0 js_tiny_mce/classes/dom/Serializer.js
  30. +200 −0 js_tiny_mce/classes/dom/StringWriter.js
  31. +151 −0 js_tiny_mce/classes/dom/XMLWriter.js
  32. BIN  js_tiny_mce/classes/firebug/errorIcon.png
  33. +209 −0 js_tiny_mce/classes/firebug/firebug.css
  34. +22 −0 js_tiny_mce/classes/firebug/firebug.html
  35. +681 −0 js_tiny_mce/classes/firebug/firebug.js
  36. BIN  js_tiny_mce/classes/firebug/infoIcon.png
  37. BIN  js_tiny_mce/classes/firebug/warningIcon.png
  38. +546 −0 js_tiny_mce/classes/tinymce.js
  39. +68 −0 js_tiny_mce/classes/ui/Button.js
  40. +212 −0 js_tiny_mce/classes/ui/ColorSplitButton.js
  41. +56 −0 js_tiny_mce/classes/ui/Container.js
  42. +182 −0 js_tiny_mce/classes/ui/Control.js
  43. +392 −0 js_tiny_mce/classes/ui/DropMenu.js
  44. +286 −0 js_tiny_mce/classes/ui/ListBox.js
  45. +175 −0 js_tiny_mce/classes/ui/Menu.js
  46. +128 −0 js_tiny_mce/classes/ui/MenuButton.js
  47. +69 −0 js_tiny_mce/classes/ui/MenuItem.js
  48. +168 −0 js_tiny_mce/classes/ui/NativeListBox.js
  49. +34 −0 js_tiny_mce/classes/ui/Separator.js
  50. +99 −0 js_tiny_mce/classes/ui/SplitButton.js
  51. +86 −0 js_tiny_mce/classes/ui/Toolbar.js
  52. +126 −0 js_tiny_mce/classes/util/Cookie.js
  53. +101 −0 js_tiny_mce/classes/util/Dispatcher.js
  54. +81 −0 js_tiny_mce/classes/util/JSON.js
  55. +87 −0 js_tiny_mce/classes/util/JSONRequest.js
  56. +282 −0 js_tiny_mce/classes/util/URI.js
  57. +424 −0 js_tiny_mce/classes/util/UnitTester.js
  58. +80 −0 js_tiny_mce/classes/util/XHR.js
  59. +126 −0 js_tiny_mce/classes/xml/Parser.js
  60. +154 −0 js_tiny_mce/langs/en.js
  61. +504 −0 js_tiny_mce/license.txt
  62. +5 −0 js_tiny_mce/plugins/advhr/css/advhr.css
  63. +1 −0  js_tiny_mce/plugins/advhr/editor_plugin.js
  64. +54 −0 js_tiny_mce/plugins/advhr/editor_plugin_src.js
  65. +43 −0 js_tiny_mce/plugins/advhr/js/rule.js
  66. +5 −0 js_tiny_mce/plugins/advhr/langs/en_dlg.js
  67. +63 −0 js_tiny_mce/plugins/advhr/rule.htm
  68. +13 −0 js_tiny_mce/plugins/advimage/css/advimage.css
  69. +1 −0  js_tiny_mce/plugins/advimage/editor_plugin.js
  70. +47 −0 js_tiny_mce/plugins/advimage/editor_plugin_src.js
  71. +238 −0 js_tiny_mce/plugins/advimage/image.htm
  72. BIN  js_tiny_mce/plugins/advimage/img/sample.gif
  73. +441 −0 js_tiny_mce/plugins/advimage/js/image.js
  74. +43 −0 js_tiny_mce/plugins/advimage/langs/en_dlg.js
  75. +8 −0 js_tiny_mce/plugins/advlink/css/advlink.css
  76. +1 −0  js_tiny_mce/plugins/advlink/editor_plugin.js
  77. +58 −0 js_tiny_mce/plugins/advlink/editor_plugin_src.js
  78. +528 −0 js_tiny_mce/plugins/advlink/js/advlink.js
  79. +52 −0 js_tiny_mce/plugins/advlink/langs/en_dlg.js
  80. +339 −0 js_tiny_mce/plugins/advlink/link.htm
  81. +1 −0  js_tiny_mce/plugins/autosave/editor_plugin.js
  82. +51 −0 js_tiny_mce/plugins/autosave/editor_plugin_src.js
  83. +1 −0  js_tiny_mce/plugins/bbcode/editor_plugin.js
  84. +117 −0 js_tiny_mce/plugins/bbcode/editor_plugin_src.js
  85. +1 −0  js_tiny_mce/plugins/compat2x/editor_plugin.js
  86. +616 −0 js_tiny_mce/plugins/compat2x/editor_plugin_src.js
  87. +1 −0  js_tiny_mce/plugins/contextmenu/editor_plugin.js
  88. +95 −0 js_tiny_mce/plugins/contextmenu/editor_plugin_src.js
  89. +1 −0  js_tiny_mce/plugins/directionality/editor_plugin.js
  90. +79 −0 js_tiny_mce/plugins/directionality/editor_plugin_src.js
  91. +1 −0  js_tiny_mce/plugins/emotions/editor_plugin.js
  92. +40 −0 js_tiny_mce/plugins/emotions/editor_plugin_src.js
  93. +41 −0 js_tiny_mce/plugins/emotions/emotions.htm
  94. BIN  js_tiny_mce/plugins/emotions/img/smiley-cool.gif
  95. BIN  js_tiny_mce/plugins/emotions/img/smiley-cry.gif
  96. BIN  js_tiny_mce/plugins/emotions/img/smiley-embarassed.gif
  97. BIN  js_tiny_mce/plugins/emotions/img/smiley-foot-in-mouth.gif
  98. BIN  js_tiny_mce/plugins/emotions/img/smiley-frown.gif
  99. BIN  js_tiny_mce/plugins/emotions/img/smiley-innocent.gif
  100. BIN  js_tiny_mce/plugins/emotions/img/smiley-kiss.gif
  101. BIN  js_tiny_mce/plugins/emotions/img/smiley-laughing.gif
  102. BIN  js_tiny_mce/plugins/emotions/img/smiley-money-mouth.gif
  103. BIN  js_tiny_mce/plugins/emotions/img/smiley-sealed.gif
  104. BIN  js_tiny_mce/plugins/emotions/img/smiley-smile.gif
  105. BIN  js_tiny_mce/plugins/emotions/img/smiley-surprised.gif
  106. BIN  js_tiny_mce/plugins/emotions/img/smiley-tongue-out.gif
  107. BIN  js_tiny_mce/plugins/emotions/img/smiley-undecided.gif
  108. BIN  js_tiny_mce/plugins/emotions/img/smiley-wink.gif
  109. BIN  js_tiny_mce/plugins/emotions/img/smiley-yell.gif
  110. +22 −0 js_tiny_mce/plugins/emotions/js/emotions.js
  111. +20 −0 js_tiny_mce/plugins/emotions/langs/en_dlg.js
  112. +27 −0 js_tiny_mce/plugins/example/dialog.htm
  113. +1 −0  js_tiny_mce/plugins/example/editor_plugin.js
  114. +81 −0 js_tiny_mce/plugins/example/editor_plugin_src.js
  115. BIN  js_tiny_mce/plugins/example/img/example.gif
  116. +19 −0 js_tiny_mce/plugins/example/js/dialog.js
  117. +3 −0  js_tiny_mce/plugins/example/langs/en.js
  118. +3 −0  js_tiny_mce/plugins/example/langs/en_dlg.js
  119. +182 −0 js_tiny_mce/plugins/fullpage/css/fullpage.css
  120. +1 −0  js_tiny_mce/plugins/fullpage/editor_plugin.js
  121. +140 −0 js_tiny_mce/plugins/fullpage/editor_plugin_src.js
  122. +577 −0 js_tiny_mce/plugins/fullpage/fullpage.htm
  123. +462 −0 js_tiny_mce/plugins/fullpage/js/fullpage.js
  124. +85 −0 js_tiny_mce/plugins/fullpage/langs/en_dlg.js
  125. +1 −0  js_tiny_mce/plugins/fullscreen/editor_plugin.js
  126. +141 −0 js_tiny_mce/plugins/fullscreen/editor_plugin_src.js
  127. +111 −0 js_tiny_mce/plugins/fullscreen/fullscreen.htm
  128. +1 −0  js_tiny_mce/plugins/iespell/editor_plugin.js
  129. +51 −0 js_tiny_mce/plugins/iespell/editor_plugin_src.js
  130. +1 −0  js_tiny_mce/plugins/inlinepopups/editor_plugin.js
  131. +623 −0 js_tiny_mce/plugins/inlinepopups/editor_plugin_src.js
  132. BIN  js_tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/alert.gif
  133. BIN  js_tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/button.gif
  134. BIN  js_tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/buttons.gif
  135. BIN  js_tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/confirm.gif
  136. BIN  js_tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/corners.gif
  137. BIN  js_tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/horizontal.gif
  138. BIN  js_tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/vertical.gif
  139. +90 −0 js_tiny_mce/plugins/inlinepopups/skins/clearlooks2/window.css
  140. +387 −0 js_tiny_mce/plugins/inlinepopups/template.htm
  141. +1 −0  js_tiny_mce/plugins/insertdatetime/editor_plugin.js
  142. +80 −0 js_tiny_mce/plugins/insertdatetime/editor_plugin_src.js
  143. +1 −0  js_tiny_mce/plugins/layer/editor_plugin.js
  144. +209 −0 js_tiny_mce/plugins/layer/editor_plugin_src.js
  145. +6 −0 js_tiny_mce/plugins/media/css/content.css
  146. +16 −0 js_tiny_mce/plugins/media/css/media.css
  147. +1 −0  js_tiny_mce/plugins/media/editor_plugin.js
  148. +359 −0 js_tiny_mce/plugins/media/editor_plugin_src.js
  149. BIN  js_tiny_mce/plugins/media/img/flash.gif
  150. BIN  js_tiny_mce/plugins/media/img/flv_player.swf
  151. BIN  js_tiny_mce/plugins/media/img/quicktime.gif
  152. BIN  js_tiny_mce/plugins/media/img/realmedia.gif
  153. BIN  js_tiny_mce/plugins/media/img/shockwave.gif
  154. BIN  js_tiny_mce/plugins/media/img/trans.gif
  155. BIN  js_tiny_mce/plugins/media/img/windowsmedia.gif
  156. +73 −0 js_tiny_mce/plugins/media/js/embed.js
  157. +628 −0 js_tiny_mce/plugins/media/js/media.js
  158. +103 −0 js_tiny_mce/plugins/media/langs/en_dlg.js
  159. +824 −0 js_tiny_mce/plugins/media/media.htm
  160. +1 −0  js_tiny_mce/plugins/nonbreaking/editor_plugin.js
  161. +50 −0 js_tiny_mce/plugins/nonbreaking/editor_plugin_src.js
  162. +1 −0  js_tiny_mce/plugins/noneditable/editor_plugin.js
  163. +87 −0 js_tiny_mce/plugins/noneditable/editor_plugin_src.js
  164. +1 −0  js_tiny_mce/plugins/pagebreak/css/content.css
  165. +1 −0  js_tiny_mce/plugins/pagebreak/editor_plugin.js
  166. +74 −0 js_tiny_mce/plugins/pagebreak/editor_plugin_src.js
  167. BIN  js_tiny_mce/plugins/pagebreak/img/pagebreak.gif
  168. BIN  js_tiny_mce/plugins/pagebreak/img/trans.gif
  169. +22 −0 js_tiny_mce/plugins/paste/blank.htm
  170. +14 −0 js_tiny_mce/plugins/paste/css/blank.css
  171. +3 −0  js_tiny_mce/plugins/paste/css/pasteword.css
  172. +1 −0  js_tiny_mce/plugins/paste/editor_plugin.js
  173. +387 −0 js_tiny_mce/plugins/paste/editor_plugin_src.js
  174. +42 −0 js_tiny_mce/plugins/paste/js/pastetext.js
  175. +56 −0 js_tiny_mce/plugins/paste/js/pasteword.js
  176. +5 −0 js_tiny_mce/plugins/paste/langs/en_dlg.js
  177. +34 −0 js_tiny_mce/plugins/paste/pastetext.htm
  178. +29 −0 js_tiny_mce/plugins/paste/pasteword.htm
  179. +1 −0  js_tiny_mce/plugins/preview/editor_plugin.js
  180. +187 −0 js_tiny_mce/plugins/preview/editor_plugin_src.js
  181. +28 −0 js_tiny_mce/plugins/preview/example.html
  182. +73 −0 js_tiny_mce/plugins/preview/jscripts/embed.js
  183. +1 −0  js_tiny_mce/plugins/print/editor_plugin.js
  184. +31 −0 js_tiny_mce/plugins/print/editor_plugin_src.js
  185. +1 −0  js_tiny_mce/plugins/safari/blank.htm
  186. +1 −0  js_tiny_mce/plugins/safari/editor_plugin.js
  187. +460 −0 js_tiny_mce/plugins/safari/editor_plugin_src.js
  188. +1 −0  js_tiny_mce/plugins/save/editor_plugin.js
  189. +98 −0 js_tiny_mce/plugins/save/editor_plugin_src.js
  190. +6 −0 js_tiny_mce/plugins/searchreplace/css/searchreplace.css
  191. +1 −0  js_tiny_mce/plugins/searchreplace/editor_plugin.js
  192. +54 −0 js_tiny_mce/plugins/searchreplace/editor_plugin_src.js
  193. +117 −0 js_tiny_mce/plugins/searchreplace/js/searchreplace.js
  194. +16 −0 js_tiny_mce/plugins/searchreplace/langs/en_dlg.js
  195. +105 −0 js_tiny_mce/plugins/searchreplace/searchreplace.htm
  196. +1 −0  js_tiny_mce/plugins/spellchecker/css/content.css
  197. +1 −0  js_tiny_mce/plugins/spellchecker/editor_plugin.js
  198. +338 −0 js_tiny_mce/plugins/spellchecker/editor_plugin_src.js
  199. BIN  js_tiny_mce/plugins/spellchecker/img/wline.gif
  200. +13 −0 js_tiny_mce/plugins/style/css/props.css
  201. +1 −0  js_tiny_mce/plugins/style/editor_plugin.js
  202. +52 −0 js_tiny_mce/plugins/style/editor_plugin_src.js
  203. +641 −0 js_tiny_mce/plugins/style/js/props.js
  204. +63 −0 js_tiny_mce/plugins/style/langs/en_dlg.js
Sorry, we could not display the entire diff because too many files (302) changed.
View
16 app_code_community_OrganicInternet_WysiwygEditor/Block/Pagehead.php
@@ -0,0 +1,16 @@
+<?php
+
+if (!class_exists('OrganicInternet_Wysiwyg_Block_PageHead')) {
+class OrganicInternet_Wysiwyg_Block_PageHead extends Mage_Adminhtml_Block_Page_Head
+{
+ protected function getWysiwygActive()
+ {
+ return true;#$this->getConfigData('organicinternet_wysiwyg/active');
+ }
+
+ protected function getEditableAreas()
+ {
+ return 'description,short_description';#$this->getConfigData('organicinternet_wysiwyg/editable_areas');
+ }
+}
+}
View
5 app_code_community_OrganicInternet_WysiwygEditor/Helper/Data.php
@@ -0,0 +1,5 @@
+<?php
+
+class OrganicInternet_WysiwygEditor_Helper_Data extends Mage_Core_Helper_Abstract {
+
+}
View
17 app_code_community_OrganicInternet_WysiwygEditor/Model/Source/Editableareas.php
@@ -0,0 +1,17 @@
+<?php
+
+class OrganicInternet_WysiwygEditor_Model_Source_EditableAreas
+{
+ public function toOptionArray()
+ {
+ return array(
+ array('value' => 'description', 'label' => Mage::helper('organicinternet_wysiwygeditor')->__('Product Description')),
+ array('value' => 'short_description', 'label' => Mage::helper('organicinternet_wysiwygeditor')->__('Product Short Description')),
+ array('value' => '_generaldescription', 'label' => Mage::helper('organicinternet_wysiwygeditor')->__('Category Description')),
+ array('value' => 'text', 'label' => Mage::helper('organicinternet_wysiwygeditor')->__('Newsletter Template')),
+ array('value' => 'page_content', 'label' => Mage::helper('organicinternet_wysiwygeditor')->__('CMS Page Content')),
+ array('value' => 'block_content', 'label' => Mage::helper('organicinternet_wysiwygeditor')->__('Static Block Content')),
+ );
+ }
+}
+
View
11 app_code_community_OrganicInternet_WysiwygEditor/Model/Source/Editortype.php
@@ -0,0 +1,11 @@
+<?php
+
+class OrganicInternet_WysiwygEditor_Model_Source_Editortype
+{
+ public function toOptionArray()
+ {
+ return array(
+ array('value' => 'tinymce', 'label' => 'Tiny MCE'),
+ );
+ }
+}
View
50 app_code_community_OrganicInternet_WysiwygEditor/etc/config.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+<config>
+ <modules>
+ <OrganicInternet_WysiwygEditor>
+ <version>0.0.1</version>
+ </OrganicInternet_WysiwygEditor>
+ </modules>
+ <global>
+ <helpers>
+ <organicinternet_wysiwygeditor>
+ <class>OrganicInternet_WysiwygEditor_Helper</class>
+ </organicinternet_wysiwygeditor>
+ </helpers>
+ <blocks>
+ <organicinternet_wysiwygeditor>
+ <class>OrganicInternet_WysiwygEditor_Block</class>
+ </organicinternet_wysiwygeditor>
+ <!--
+ <adminhtml>
+ <rewrite>
+ <page_head>OrganicInternet_WysiwygEditor_Block_PageHead</page_head>
+ </rewrite>
+ </adminhtml>
+ -->
+ </blocks>
+ <models>
+ <organicinternet_wysiwygeditor>
+ <class>OrganicInternet_WysiwygEditor_Model</class>
+ </organicinternet_wysiwygeditor>
+ </models>
+ </global>
+ <adminhtml>
+ <layout>
+ <updates>
+ <organicinternet_wysiwygeditor>
+ <file>organicinternet_wysiwygeditor.xml</file>
+ </organicinternet_wysiwygeditor>
+ </updates>
+ </layout>
+ </adminhtml>
+ <default>
+ <advanced>
+ <organicinternet_wysiwygeditor>
+ <active>0</active>
+ <editor_type>tinymce</editor_type>
+ <editable_areas>description,short_description</editable_areas>
+ </organicinternet_wysiwygeditor>
+ </advanced>
+ </default>
+</config>
View
50 app_code_community_OrganicInternet_WysiwygEditor/etc/system.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+<config>
+ <sections>
+<!-- payment tab -->
+ <advanced>
+ <groups>
+<!-- newmodule fieldset -->
+ <organicinternet_wysiwygeditor translate="label" module="organicinternet_wysiwygeditor">
+<!-- will have title 'New Module' -->
+ <label>WYSIWYG Editor</label>
+<!-- position between other payment methods -->
+ <sort_order>500</sort_order>
+<!-- do not show this configuration options in store scope -->
+ <show_in_default>1</show_in_default>
+ <show_in_website>1</show_in_website>
+ <show_in_store>0</show_in_store>
+ <fields>
+ <active translate="label">
+ <label>Enabled</label>
+ <frontend_type>select</frontend_type>
+ <source_model>adminhtml/system_config_source_yesno</source_model>
+ <sort_order>1</sort_order>
+ <show_in_default>1</show_in_default>
+ <show_in_website>1</show_in_website>
+ <show_in_store>0</show_in_store>
+ </active>
+ <editor_type translate="label">
+ <label>Editor Type</label>
+ <frontend_type>select</frontend_type>
+ <source_model>organicinternet_wysiwygeditor/source_editortype</source_model>
+ <sort_order>2</sort_order>
+ <show_in_default>1</show_in_default>
+ <show_in_website>1</show_in_website>
+ <show_in_store>0</show_in_store>
+ </editor_type>
+ <editable_areas translate="label">
+ <label>Editable Areas</label>
+ <frontend_type>multiselect</frontend_type>
+ <source_model>organicinternet_wysiwygeditor/source_editableareas</source_model>
+ <sort_order>6</sort_order>
+ <show_in_default>1</show_in_default>
+ <show_in_website>1</show_in_website>
+ <show_in_store>0</show_in_store>
+ </editable_areas>
+ </fields>
+ </organicinternet_wysiwygeditor>
+ </groups>
+ </advanced>
+ </sections>
+</config>
View
8 app_design_adminhtml_default_default_layout_organicinternet_wysiwygeditor.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<layout version="0.0.1">
+ <default>
+ <reference name="head">
+ <action method="setTemplate"><template>organicinternet_wysiwygeditor/page_head.phtml</template></action>
+ </reference>
+ </default>
+</layout>
View
54 app_design_adminhtml_default_default_template_organicinternet_wysiwygeditor/page_head.phtml
@@ -0,0 +1,54 @@
+<title><?php echo htmlspecialchars(html_entity_decode($this->getTitle())) ?></title>
+<meta http-equiv="Content-Type" content="<?php echo $this->getContentType() ?>"/>
+
+<link rel="icon" href="<?php echo $this->getSkinUrl('favicon.ico') ?>" type="image/x-icon"/>
+<link rel="shortcut icon" href="<?php echo $this->getSkinUrl('favicon.ico') ?>" type="image/x-icon"/>
+
+<script type="text/javascript">
+ var BLANK_URL = '<?php echo $this->getJsUrl() ?>blank.html';
+ var BLANK_IMG = '<?php echo $this->getJsUrl() ?>spacer.gif';
+ var BASE_URL = '<?php echo $this->getUrl('*') ?>';
+ var SKIN_URL = '<?php echo $this->getSkinUrl() ?>';
+</script>
+
+<?php echo $this->getCssJsHtml() ?>
+
+<?php if($this->getCanLoadExtJs()): ?>
+<script type="text/javascript">
+ Ext.BLANK_IMAGE_URL = BLANK_IMG;
+ Ext.UpdateManager.defaults.loadScripts = false;
+ Ext.UpdateManager.defaults.disableCaching = true;
+</script>
+<?php endif; ?>
+
+<script type="text/javascript">
+ Fieldset.addToPrefix(<?php echo Mage::helper('adminhtml')->getCurrentUserId() ?>);
+</script>
+
+<?php echo $this->helper('core/js')->getTranslatorScript() ?>
+
+<?php if (true || $this->getWysiwygActive()) { ?>
+<script type="text/javascript" src="/js/tiny_mce/tiny_mce.js"></script>
+<script type="text/javascript">
+Event.observe(window, 'load', function() {
+ 'description,short_description,_generaldescription,text,page_content,block_content'.split(',').each(function(dom_id) {
+ if ($(dom_id)) {
+ $(dom_id).removeClassName('required-entry');
+ }
+ });
+ tinyMCE.init({
+ mode : "exact",
+ elements : "<?php echo $this->getEditableAreas() ? $this->getEditableAreas() : 'description,short_description,_generaldescription,text,page_content,block_content' ?>",
+ theme : "advanced",
+ strict_loading_mode : true,
+ width: "640",
+ height: "350",
+ content_css: "<?php echo $this->getSkinUrl() ?>tinymce_content.css",
+ theme_advanced_toolbar_location : "top",
+ theme_advanced_toolbar_align : "left",
+ theme_advanced_statusbar_location : "bottom",
+ relative_urls : false
+ });
+});
+</script>
+<?php } ?>
View
9 app_etc_modules_OrganicInternet_WysiwygEditor.xml
@@ -0,0 +1,9 @@
+<config>
+ <modules>
+ <OrganicInternet_WysiwygEditor>
+ <active>true</active>
+ <codePool>community</codePool>
+ <version>0.0.1</version>
+ </OrganicInternet_WysiwygEditor>
+ </modules>
+</config>
View
98 js_tiny_mce/classes/AddOnManager.js
@@ -0,0 +1,98 @@
+/**
+ * $Id: PluginManager.js 352 2007-11-05 17:03:49Z spocke $
+ *
+ * @author Moxiecode
+ * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
+ */
+
+(function() {
+ var Dispatcher = tinymce.util.Dispatcher, each = tinymce.each;
+
+ /**#@+
+ * @class This class handles the loading of themes/plugins or other add-ons and their language packs.
+ * @member tinymce.AddOnManager
+ */
+ tinymce.create('tinymce.AddOnManager', {
+ items : [],
+ urls : {},
+ lookup : {},
+ onAdd : new Dispatcher(this),
+
+ /**#@+
+ * @method
+ */
+
+ /**
+ * Returns the specified add on by the short name.
+ *
+ * @param {String} n Add-on to look for.
+ * @return {tinymce.Theme/tinymce.Plugin} Theme or plugin add-on instance or undefined.
+ */
+ get : function(n) {
+ return this.lookup[n];
+ },
+
+ /**
+ * Loads a language pack for the specified add-on.
+ *
+ * @param {String} n Short name of the add-on.
+ */
+ requireLangPack : function(n) {
+ var u, s;
+
+ if (tinymce.EditorManager.settings) {
+ u = this.urls[n] + '/langs/' + tinymce.EditorManager.settings.language + '.js';
+ s = tinymce.EditorManager.settings;
+
+ if (s) {
+ if (!tinymce.dom.Event.domLoaded && !s.strict_mode)
+ tinymce.ScriptLoader.load(u);
+ else
+ tinymce.ScriptLoader.add(u);
+ }
+ }
+ },
+
+ /**
+ * Adds a instance of the add-on by it's short name.
+ *
+ * @param {String} id Short name/id for the add-on.
+ * @param {tinymce.Theme/tinymce.Plugin} o Theme or plugin to add.
+ * @return {tinymce.Theme/tinymce.Plugin} The same theme or plugin instance that got passed in.
+ */
+ add : function(id, o) {
+ this.items.push(o);
+ this.lookup[id] = o;
+ this.onAdd.dispatch(this, id, o);
+
+ return o;
+ },
+
+ /**
+ * Loads an add-on from a specific url.
+ *
+ * @param {String} n Short name of the add-on that gets loaded.
+ * @param {String} u URL to the add-on that will get loaded.
+ * @param {function} cb Optional callback to execute ones the add-on is loaded.
+ * @param {Object} s Optional scope to execute the callback in.
+ */
+ load : function(n, u, cb, s) {
+ var t = this;
+
+ if (t.urls[n])
+ return;
+
+ if (u.indexOf('/') != 0 && u.indexOf('://') == -1)
+ u = tinymce.baseURL + '/' + u;
+
+ t.urls[n] = u.substring(0, u.lastIndexOf('/'));
+ tinymce.ScriptLoader.add(u, cb, s);
+ }
+
+ /**#@-*/
+ });
+
+ // Create plugin and theme managers
+ tinymce.PluginManager = new tinymce.AddOnManager();
+ tinymce.ThemeManager = new tinymce.AddOnManager();
+}());
View
477 js_tiny_mce/classes/ControlManager.js
@@ -0,0 +1,477 @@
+/**
+ * $Id: ControlManager.js 842 2008-05-07 15:56:39Z spocke $
+ *
+ * @author Moxiecode
+ * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
+ */
+
+(function() {
+ // Shorten names
+ var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, extend = tinymce.extend;
+
+ /**#@+
+ * @class This class is responsible for managing UI control instances. It's both a factory and a collection for the controls.
+ * @member tinymce.ControlManager
+ */
+ tinymce.create('tinymce.ControlManager', {
+ /**
+ * Constructs a new control manager instance.
+ * Consult the Wiki for more details on this class.
+ *
+ * @constructor
+ * @param {tinymce.Editor} ed TinyMCE editor instance to add the control to.
+ * @param {Object} s Optional settings object for the control manager.
+ */
+ ControlManager : function(ed, s) {
+ var t = this, i;
+
+ s = s || {};
+ t.editor = ed;
+ t.controls = {};
+ t.onAdd = new tinymce.util.Dispatcher(t);
+ t.onPostRender = new tinymce.util.Dispatcher(t);
+ t.prefix = s.prefix || ed.id + '_';
+ t._cls = {};
+
+ t.onPostRender.add(function() {
+ each(t.controls, function(c) {
+ c.postRender();
+ });
+ });
+ },
+
+ /**#@+
+ * @method
+ */
+
+ /**
+ * Returns a control by id or undefined it it wasn't found.
+ *
+ * @param {String} id Control instance name.
+ * @return {tinymce.ui.Control} Control instance or undefined.
+ */
+ get : function(id) {
+ return this.controls[this.prefix + id] || this.controls[id];
+ },
+
+ /**
+ * Sets the active state of a control by id.
+ *
+ * @param {String} id Control id to set state on.
+ * @param {bool} s Active state true/false.
+ * @return {tinymce.ui.Control} Control instance that got activated or null if it wasn't found.
+ */
+ setActive : function(id, s) {
+ var c = null;
+
+ if (c = this.get(id))
+ c.setActive(s);
+
+ return c;
+ },
+
+ /**
+ * Sets the dsiabled state of a control by id.
+ *
+ * @param {String} id Control id to set state on.
+ * @param {bool} s Active state true/false.
+ * @return {tinymce.ui.Control} Control instance that got disabled or null if it wasn't found.
+ */
+ setDisabled : function(id, s) {
+ var c = null;
+
+ if (c = this.get(id))
+ c.setDisabled(s);
+
+ return c;
+ },
+
+ /**
+ * Adds a control to the control collection inside the manager.
+ *
+ * @param {tinymce.ui.Control} Control instance to add to collection.
+ * @return {tinymce.ui.Control} Control instance that got passed in.
+ */
+ add : function(c) {
+ var t = this;
+
+ if (c) {
+ t.controls[c.id] = c;
+ t.onAdd.dispatch(c, t);
+ }
+
+ return c;
+ },
+
+ /**
+ * Creates a control by name, when a control is created it will automatically add it to the control collection.
+ * It first ask all plugins for the specified control if the plugins didn't return a control then the default behavior
+ * will be used.
+ *
+ * @param {String} n Control name to create for example "separator".
+ * @return {tinymce.ui.Control} Control instance that got created and added.
+ */
+ createControl : function(n) {
+ var c, t = this, ed = t.editor;
+
+ each(ed.plugins, function(p) {
+ if (p.createControl) {
+ c = p.createControl(n, t);
+
+ if (c)
+ return false;
+ }
+ });
+
+ switch (n) {
+ case "|":
+ case "separator":
+ return t.createSeparator();
+ }
+
+ if (!c && ed.buttons && (c = ed.buttons[n]))
+ return t.createButton(n, c);
+
+ return t.add(c);
+ },
+
+ /**
+ * Creates a drop menu control instance by id.
+ *
+ * @param {String} id Unique id for the new dropdown instance. For example "some menu".
+ * @param {Object} s Optional settings object for the control.
+ * @param {Object} cc Optional control class to use instead of the default one.
+ * @return {tinymce.ui.Control} Control instance that got created and added.
+ */
+ createDropMenu : function(id, s, cc) {
+ var t = this, ed = t.editor, c, bm, v, cls;
+
+ s = extend({
+ 'class' : 'mceDropDown',
+ constrain : ed.settings.constrain_menus
+ }, s);
+
+ s['class'] = s['class'] + ' ' + ed.getParam('skin') + 'Skin';
+ if (v = ed.getParam('skin_variant'))
+ s['class'] += ' ' + ed.getParam('skin') + 'Skin' + v.substring(0, 1).toUpperCase() + v.substring(1);
+
+ id = t.prefix + id;
+ cls = cc || t._cls.dropmenu || tinymce.ui.DropMenu;
+ c = t.controls[id] = new cls(id, s);
+ c.onAddItem.add(function(c, o) {
+ var s = o.settings;
+
+ s.title = ed.getLang(s.title, s.title);
+
+ if (!s.onclick) {
+ s.onclick = function(v) {
+ ed.execCommand(s.cmd, s.ui || false, s.value);
+ };
+ }
+ });
+
+ ed.onRemove.add(function() {
+ c.destroy();
+ });
+
+ // Fix for bug #1897785, #1898007
+ if (tinymce.isIE) {
+ c.onShowMenu.add(function() {
+ bm = ed.selection.getBookmark(1);
+ });
+
+ c.onHideMenu.add(function() {
+ if (bm)
+ ed.selection.moveToBookmark(bm);
+ });
+ }
+
+ return t.add(c);
+ },
+
+ /**
+ * Creates a list box control instance by id. A list box is either a native select element or a DOM/JS based list box control. This
+ * depends on the use_native_selects settings state.
+ *
+ * @param {String} id Unique id for the new listbox instance. For example "styles".
+ * @param {Object} s Optional settings object for the control.
+ * @param {Object} cc Optional control class to use instead of the default one.
+ * @return {tinymce.ui.Control} Control instance that got created and added.
+ */
+ createListBox : function(id, s, cc) {
+ var t = this, ed = t.editor, cmd, c, cls;
+
+ if (t.get(id))
+ return null;
+
+ s.title = ed.translate(s.title);
+ s.scope = s.scope || ed;
+
+ if (!s.onselect) {
+ s.onselect = function(v) {
+ ed.execCommand(s.cmd, s.ui || false, v || s.value);
+ };
+ }
+
+ s = extend({
+ title : s.title,
+ 'class' : 'mce_' + id,
+ scope : s.scope,
+ control_manager : t
+ }, s);
+
+ id = t.prefix + id;
+
+ if (ed.settings.use_native_selects)
+ c = new tinymce.ui.NativeListBox(id, s);
+ else {
+ cls = cc || t._cls.listbox || tinymce.ui.ListBox;
+ c = new cls(id, s);
+ }
+
+ t.controls[id] = c;
+
+ // Fix focus problem in Safari
+ if (tinymce.isWebKit) {
+ c.onPostRender.add(function(c, n) {
+ // Store bookmark on mousedown
+ Event.add(n, 'mousedown', function() {
+ ed.bookmark = ed.selection.getBookmark('simple');
+ });
+
+ // Restore on focus, since it might be lost
+ Event.add(n, 'focus', function() {
+ ed.selection.moveToBookmark(ed.bookmark);
+ ed.bookmark = null;
+ });
+ });
+ }
+
+ if (c.hideMenu)
+ ed.onMouseDown.add(c.hideMenu, c);
+
+ return t.add(c);
+ },
+
+ /**
+ * Creates a button control instance by id.
+ *
+ * @param {String} id Unique id for the new button instance. For example "bold".
+ * @param {Object} s Optional settings object for the control.
+ * @param {Object} cc Optional control class to use instead of the default one.
+ * @return {tinymce.ui.Control} Control instance that got created and added.
+ */
+ createButton : function(id, s, cc) {
+ var t = this, ed = t.editor, o, c, cls;
+
+ if (t.get(id))
+ return null;
+
+ s.title = ed.translate(s.title);
+ s.label = ed.translate(s.label);
+ s.scope = s.scope || ed;
+
+ if (!s.onclick && !s.menu_button) {
+ s.onclick = function() {
+ ed.execCommand(s.cmd, s.ui || false, s.value);
+ };
+ }
+
+ s = extend({
+ title : s.title,
+ 'class' : 'mce_' + id,
+ unavailable_prefix : ed.getLang('unavailable', ''),
+ scope : s.scope,
+ control_manager : t
+ }, s);
+
+ id = t.prefix + id;
+
+ if (s.menu_button) {
+ cls = cc || t._cls.menubutton || tinymce.ui.MenuButton;
+ c = new cls(id, s);
+ ed.onMouseDown.add(c.hideMenu, c);
+ } else {
+ cls = t._cls.button || tinymce.ui.Button;
+ c = new cls(id, s);
+ }
+
+ return t.add(c);
+ },
+
+ /**
+ * Creates a menu button control instance by id.
+ *
+ * @param {String} id Unique id for the new menu button instance. For example "menu1".
+ * @param {Object} s Optional settings object for the control.
+ * @param {Object} cc Optional control class to use instead of the default one.
+ * @return {tinymce.ui.Control} Control instance that got created and added.
+ */
+ createMenuButton : function(id, s) {
+ s = s || {};
+ s.menu_button = 1;
+
+ return this.createButton(id, s);
+ },
+
+ /**
+ * Creates a split button control instance by id.
+ *
+ * @param {String} id Unique id for the new split button instance. For example "spellchecker".
+ * @param {Object} s Optional settings object for the control.
+ * @param {Object} cc Optional control class to use instead of the default one.
+ * @return {tinymce.ui.Control} Control instance that got created and added.
+ */
+ createSplitButton : function(id, s, cc) {
+ var t = this, ed = t.editor, cmd, c, cls;
+
+ if (t.get(id))
+ return null;
+
+ s.title = ed.translate(s.title);
+ s.scope = s.scope || ed;
+
+ if (!s.onclick) {
+ s.onclick = function(v) {
+ ed.execCommand(s.cmd, s.ui || false, v || s.value);
+ };
+ }
+
+ if (!s.onselect) {
+ s.onselect = function(v) {
+ ed.execCommand(s.cmd, s.ui || false, v || s.value);
+ };
+ }
+
+ s = extend({
+ title : s.title,
+ 'class' : 'mce_' + id,
+ scope : s.scope,
+ control_manager : t
+ }, s);
+
+ id = t.prefix + id;
+ cls = cc || t._cls.splitbutton || tinymce.ui.SplitButton;
+ c = t.add(new cls(id, s));
+ ed.onMouseDown.add(c.hideMenu, c);
+
+ return c;
+ },
+
+ /**
+ * Creates a color split button control instance by id.
+ *
+ * @param {String} id Unique id for the new color split button instance. For example "forecolor".
+ * @param {Object} s Optional settings object for the control.
+ * @param {Object} cc Optional control class to use instead of the default one.
+ * @return {tinymce.ui.Control} Control instance that got created and added.
+ */
+ createColorSplitButton : function(id, s, cc) {
+ var t = this, ed = t.editor, cmd, c, cls, bm;
+
+ if (t.get(id))
+ return null;
+
+ s.title = ed.translate(s.title);
+ s.scope = s.scope || ed;
+
+ if (!s.onclick) {
+ s.onclick = function(v) {
+ ed.execCommand(s.cmd, s.ui || false, v || s.value);
+ };
+ }
+
+ if (!s.onselect) {
+ s.onselect = function(v) {
+ ed.execCommand(s.cmd, s.ui || false, v || s.value);
+ };
+ }
+
+ s = extend({
+ title : s.title,
+ 'class' : 'mce_' + id,
+ 'menu_class' : ed.getParam('skin') + 'Skin',
+ scope : s.scope,
+ more_colors_title : ed.getLang('more_colors')
+ }, s);
+
+ id = t.prefix + id;
+ cls = cc || t._cls.colorsplitbutton || tinymce.ui.ColorSplitButton;
+ c = new cls(id, s);
+ ed.onMouseDown.add(c.hideMenu, c);
+
+ // Remove the menu element when the editor is removed
+ ed.onRemove.add(function() {
+ c.destroy();
+ });
+
+ // Fix for bug #1897785, #1898007
+ if (tinymce.isIE) {
+ c.onShowMenu.add(function() {
+ bm = ed.selection.getBookmark(1);
+ });
+
+ c.onHideMenu.add(function() {
+ if (bm)
+ ed.selection.moveToBookmark(bm);
+ });
+ }
+
+ return t.add(c);
+ },
+
+ /**
+ * Creates a toolbar container control instance by id.
+ *
+ * @param {String} id Unique id for the new toolbar container control instance. For example "toolbar1".
+ * @param {Object} s Optional settings object for the control.
+ * @param {Object} cc Optional control class to use instead of the default one.
+ * @return {tinymce.ui.Control} Control instance that got created and added.
+ */
+ createToolbar : function(id, s, cc) {
+ var c, t = this, cls;
+
+ id = t.prefix + id;
+ cls = cc || t._cls.toolbar || tinymce.ui.Toolbar;
+ c = new cls(id, s);
+
+ if (t.get(id))
+ return null;
+
+ return t.add(c);
+ },
+
+ /**
+ * Creates a separator control instance.
+ *
+ * @param {Object} cc Optional control class to use instead of the default one.
+ * @return {tinymce.ui.Control} Control instance that got created and added.
+ */
+ createSeparator : function(cc) {
+ var cls = cc || this._cls.separator || tinymce.ui.Separator;
+
+ return new cls();
+ },
+
+ /**
+ * Overrides a specific control type with a custom class.
+ *
+ * @param {string} n Name of the control to override for example button or dropmenu.
+ * @param {function} c Class reference to use instead of the default one.
+ * @return {function} Same as the class reference.
+ */
+ setControlType : function(n, c) {
+ return this._cls[n.toLowerCase()] = c;
+ },
+
+ destroy : function() {
+ each(this.controls, function(c) {
+ c.destroy();
+ });
+
+ this.controls = null;
+ }
+
+ /**#@-*/
+ });
+})();
View
91 js_tiny_mce/classes/Developer.js
@@ -0,0 +1,91 @@
+/**
+ * $Id: Developer.js 520 2008-01-07 16:30:32Z spocke $
+ *
+ * @author Moxiecode
+ * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
+ */
+
+(function() {
+ var EditorManager = tinymce.EditorManager, each = tinymce.each, DOM = tinymce.DOM;
+
+ /**
+ * This class patches in various development features. This class is only available for the dev version of TinyMCE.
+ */
+ tinymce.create('static tinymce.Developer', {
+ _piggyBack : function() {
+ var t = this, em = tinymce.EditorManager, lo = false;
+
+ // Makes sure that XML language pack is used instead of JS files
+ t._runBefore(em, 'init', function(s) {
+ var par = new tinymce.xml.Parser({async : false}), lng = s.language || "en", i18n = tinymce.EditorManager.i18n, sl = tinymce.ScriptLoader;
+
+ if (!s.translate_mode)
+ return;
+
+ if (lo)
+ return;
+
+ lo = true;
+
+ // Common language loaded
+ sl.markDone(tinymce.baseURL + '/langs/' + lng + '.js');
+
+ // Theme languages loaded
+ sl.markDone(tinymce.baseURL + '/themes/simple/langs/' + lng + '.js');
+ sl.markDone(tinymce.baseURL + '/themes/advanced/langs/' + lng + '.js');
+
+ // All plugin packs loaded
+ each(s.plugins.split(','), function(p) {
+ sl.markDone(tinymce.baseURL + '/plugins/' + p + '/langs/' + lng + '.js');
+ });
+
+ // Load XML language pack
+ par.load(tinymce.baseURL + '/langs/' + lng + '.xml', function(doc, ex) {
+ var c;
+
+ if (!doc) {
+ alert(ex.message);
+ return;
+ }
+
+ if (doc.documentElement.nodeName == 'parsererror') {
+ alert('Parse error!!');
+ return;
+ }
+
+ c = doc.getElementsByTagName('language')[0].getAttribute("code");
+
+ each(doc.getElementsByTagName('group'), function(g) {
+ var gn = g.getAttribute("target"), o = {};
+
+ // Build object from XML items
+ each(g.getElementsByTagName('item'), function(it) {
+ var itn = it.getAttribute("name");
+
+ if (gn == "common")
+ i18n[c + '.' + itn] = par.getText(it);
+ else
+ i18n[c + '.' + gn + "." + itn] = par.getText(it);
+ });
+ });
+ }, {
+ async : false
+ });
+ });
+ },
+
+ _runBefore : function(o, n, f) {
+ var e = o[n];
+
+ o[n] = function() {
+ var s = f.apply(o, arguments);
+
+ if (s !== false)
+ return e.apply(o, arguments);
+ };
+ }
+ });
+
+ tinymce.Developer._piggyBack();
+})();
+
View
2,401 js_tiny_mce/classes/Editor.js
@@ -0,0 +1,2401 @@
+/**
+ * $Id: Editor.js 858 2008-06-02 10:24:28Z spocke $
+ *
+ * @author Moxiecode
+ * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
+ */
+
+(function() {
+ var DOM = tinymce.DOM, Event = tinymce.dom.Event, extend = tinymce.extend, Dispatcher = tinymce.util.Dispatcher;
+ var each = tinymce.each, isGecko = tinymce.isGecko, isIE = tinymce.isIE, isWebKit = tinymce.isWebKit;
+ var is = tinymce.is, ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager, EditorManager = tinymce.EditorManager;
+ var inArray = tinymce.inArray, grep = tinymce.grep, explode = tinymce.explode;
+
+ /**#@+
+ * @class This class contains the core logic for a TinyMCE editor.
+ * @member tinymce.Editor
+ */
+ tinymce.create('tinymce.Editor', {
+ /**
+ * Constructs a editor instance by id.
+ *
+ * @constructor
+ * @member tinymce.Editor
+ * @param {String} id Unique id for the editor.
+ * @param {Object} s Optional settings string for the editor.
+ */
+ Editor : function(id, s) {
+ var t = this;
+
+ t.id = t.editorId = id;
+ t.execCommands = {};
+ t.queryStateCommands = {};
+ t.queryValueCommands = {};
+ t.plugins = {};
+
+ // Add events to the editor
+ each([
+ 'onPreInit',
+ 'onBeforeRenderUI',
+ 'onPostRender',
+ 'onInit',
+ 'onRemove',
+ 'onActivate',
+ 'onDeactivate',
+ 'onClick',
+ 'onEvent',
+ 'onMouseUp',
+ 'onMouseDown',
+ 'onDblClick',
+ 'onKeyDown',
+ 'onKeyUp',
+ 'onKeyPress',
+ 'onContextMenu',
+ 'onSubmit',
+ 'onReset',
+ 'onPaste',
+ 'onPreProcess',
+ 'onPostProcess',
+ 'onBeforeSetContent',
+ 'onBeforeGetContent',
+ 'onSetContent',
+ 'onGetContent',
+ 'onLoadContent',
+ 'onSaveContent',
+ 'onNodeChange',
+ 'onChange',
+ 'onBeforeExecCommand',
+ 'onExecCommand',
+ 'onUndo',
+ 'onRedo',
+ 'onVisualAid',
+ 'onSetProgressState'
+ ], function(e) {
+ t[e] = new Dispatcher(t);
+ });
+
+ // Default editor config
+ t.settings = s = extend({
+ id : id,
+ language : 'en',
+ docs_language : 'en',
+ theme : 'simple',
+ skin : 'default',
+ delta_width : 0,
+ delta_height : 0,
+ popup_css : '',
+ plugins : '',
+ document_base_url : tinymce.documentBaseURL,
+ add_form_submit_trigger : 1,
+ submit_patch : 1,
+ add_unload_trigger : 1,
+ convert_urls : 1,
+ relative_urls : 1,
+ remove_script_host : 1,
+ table_inline_editing : 0,
+ object_resizing : 1,
+ cleanup : 1,
+ accessibility_focus : 1,
+ custom_shortcuts : 1,
+ custom_undo_redo_keyboard_shortcuts : 1,
+ custom_undo_redo_restore_selection : 1,
+ custom_undo_redo : 1,
+ doctype : '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">',
+ visual_table_class : 'mceItemTable',
+ visual : 1,
+ inline_styles : true,
+ convert_fonts_to_spans : true,
+ font_size_style_values : 'xx-small,x-small,small,medium,large,x-large,xx-large',
+ apply_source_formatting : 1,
+ directionality : 'ltr',
+ forced_root_block : 'p',
+ valid_elements : '@[id|class|style|title|dir<ltr?rtl|lang|xml::lang|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],a[rel|rev|charset|hreflang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur],strong/b,em/i,strike,u,#p[align],-ol[type|compact],-ul[type|compact],-li,br,img[longdesc|usemap|src|border|alt=|title|hspace|vspace|width|height|align],-sub,-sup,-blockquote[cite],-table[border=0|cellspacing|cellpadding|width|frame|rules|height|align|summary|bgcolor|background|bordercolor],-tr[rowspan|width|height|align|valign|bgcolor|background|bordercolor],tbody,thead,tfoot,#td[colspan|rowspan|width|height|align|valign|bgcolor|background|bordercolor|scope],#th[colspan|rowspan|width|height|align|valign|scope],caption,-div,-span,-code,-pre,address,-h1,-h2,-h3,-h4,-h5,-h6,hr[size|noshade],-font[face|size|color],dd,dl,dt,cite,abbr,acronym,del[datetime|cite],ins[datetime|cite],object[classid|width|height|codebase|*],param[name|value|_value],embed[type|width|height|src|*],script[src|type],map[name],area[shape|coords|href|alt|target],bdo,button,col[align|char|charoff|span|valign|width],colgroup[align|char|charoff|span|valign|width],dfn,fieldset,form[action|accept|accept-charset|enctype|method],input[accept|alt|checked|disabled|maxlength|name|readonly|size|src|type|value],kbd,label[for],legend,noscript,optgroup[label|disabled],option[disabled|label|selected|value],q[cite],samp,select[disabled|multiple|name|size],small,textarea[cols|rows|disabled|name|readonly],tt,var,big',
+ hidden_input : 1,
+ padd_empty_editor : 1,
+ render_ui : 1,
+ init_theme : 1,
+ force_p_newlines : 1,
+ indentation : '30px'
+ }, s);
+
+ // Setup URIs
+ t.documentBaseURI = new tinymce.util.URI(s.document_base_url || tinymce.documentBaseURL, {
+ base_uri : tinyMCE.baseURI
+ });
+ t.baseURI = EditorManager.baseURI;
+
+ // Call setup
+ t.execCallback('setup', t);
+ },
+
+ /**#@+
+ * @method
+ */
+
+ /**
+ * Renderes the editor/adds it to the page.
+ */
+ render : function(nst) {
+ var t = this, s = t.settings, id = t.id, sl = tinymce.ScriptLoader;
+
+ // Page is not loaded yet, wait for it
+ if (!Event.domLoaded) {
+ Event.add(document, 'init', function() {
+ t.render();
+ });
+ return;
+ }
+
+ // Force strict loading mode if render us called by user and not internally
+ if (!nst) {
+ s.strict_loading_mode = 1;
+ tinyMCE.settings = s;
+ }
+
+ // Element not found, then skip initialization
+ if (!t.getElement())
+ return;
+
+ if (s.strict_loading_mode) {
+ sl.settings.strict_mode = s.strict_loading_mode;
+ tinymce.DOM.settings.strict = 1;
+ }
+
+ // Add hidden input for non input elements inside form elements
+ if (!/TEXTAREA|INPUT/i.test(t.getElement().nodeName) && s.hidden_input && DOM.getParent(id, 'form'))
+ DOM.insertAfter(DOM.create('input', {type : 'hidden', name : id}), id);
+
+ t.windowManager = new tinymce.WindowManager(t);
+
+ if (s.encoding == 'xml') {
+ t.onGetContent.add(function(ed, o) {
+ if (o.save)
+ o.content = DOM.encode(o.content);
+ });
+ }
+
+ if (s.add_form_submit_trigger) {
+ t.onSubmit.addToTop(function() {
+ if (t.initialized) {
+ t.save();
+ t.isNotDirty = 1;
+ }
+ });
+ }
+
+ if (s.add_unload_trigger && !s.ask) {
+ t._beforeUnload = tinyMCE.onBeforeUnload.add(function() {
+ if (t.initialized && !t.destroyed && !t.isHidden())
+ t.save({format : 'raw', no_events : true});
+ });
+ }
+
+ tinymce.addUnload(t.destroy, t);
+
+ if (s.submit_patch) {
+ t.onBeforeRenderUI.add(function() {
+ var n = t.getElement().form;
+
+ if (!n)
+ return;
+
+ // Already patched
+ if (n._mceOldSubmit)
+ return;
+
+ // Check page uses id="submit" or name="submit" for it's submit button
+ if (!n.submit.nodeType && !n.submit.length) {
+ t.formElement = n;
+ n._mceOldSubmit = n.submit;
+ n.submit = function() {
+ // Save all instances
+ EditorManager.triggerSave();
+ t.isNotDirty = 1;
+
+ return this._mceOldSubmit(this);
+ };
+ }
+
+ n = null;
+ });
+ }
+
+ // Load scripts
+ function loadScripts() {
+ if (s.language)
+ sl.add(tinymce.baseURL + '/langs/' + s.language + '.js');
+
+ if (s.theme.charAt(0) != '-' && !ThemeManager.urls[s.theme])
+ ThemeManager.load(s.theme, 'themes/' + s.theme + '/editor_template' + tinymce.suffix + '.js');
+
+ each(explode(s.plugins), function(p) {
+ if (p && p.charAt(0) != '-' && !PluginManager.urls[p]) {
+ // Skip safari plugin for other browsers
+ if (!isWebKit && p == 'safari')
+ return;
+
+ PluginManager.load(p, 'plugins/' + p + '/editor_plugin' + tinymce.suffix + '.js');
+ }
+ });
+
+ // Init when que is loaded
+ sl.loadQueue(function() {
+ if (s.ask) {
+ function ask() {
+ // Yield for awhile to avoid focus bug on FF 3 when cancel is pressed
+ window.setTimeout(function() {
+ Event.remove(t.id, 'focus', ask);
+
+ t.windowManager.confirm(t.getLang('edit_confirm'), function(s) {
+ if (s)
+ t.init();
+ });
+ }, 0);
+ };
+
+ Event.add(t.id, 'focus', ask);
+ return;
+ }
+
+ if (!t.removed)
+ t.init();
+ });
+ };
+
+ // Load compat2x first
+ if (s.plugins.indexOf('compat2x') != -1) {
+ PluginManager.load('compat2x', 'plugins/compat2x/editor_plugin' + tinymce.suffix + '.js');
+ sl.loadQueue(loadScripts);
+ } else
+ loadScripts();
+ },
+
+ /**
+ * Initializes the editor this will be called automatically when
+ * all plugins/themes and language packs are loaded by the rendered method.
+ * This method will setup the iframe and create the theme and plugin instances.
+ */
+ init : function() {
+ var n, t = this, s = t.settings, w, h, e = t.getElement(), o, ti, u, bi, bc, re;
+
+ EditorManager.add(t);
+
+ // Create theme
+ s.theme = s.theme.replace(/-/, '');
+ o = ThemeManager.get(s.theme);
+ t.theme = new o();
+
+ if (t.theme.init && s.init_theme)
+ t.theme.init(t, ThemeManager.urls[s.theme] || tinymce.documentBaseURL.replace(/\/$/, ''));
+
+ // Create all plugins
+ each(explode(s.plugins.replace(/\-/g, '')), function(p) {
+ var c = PluginManager.get(p), u = PluginManager.urls[p] || tinymce.documentBaseURL.replace(/\/$/, ''), po;
+
+ if (c) {
+ po = new c(t, u);
+
+ t.plugins[p] = po;
+
+ if (po.init)
+ po.init(t, u);
+ }
+ });
+
+ // Setup popup CSS path(s)
+ if (s.popup_css)
+ s.popup_css = t.documentBaseURI.toAbsolute(s.popup_css);
+ else
+ s.popup_css = t.baseURI.toAbsolute("themes/" + s.theme + "/skins/" + s.skin + "/dialog.css");
+
+ if (s.popup_css_add)
+ s.popup_css += ',' + t.documentBaseURI.toAbsolute(s.popup_css_add);
+
+ // Setup control factory
+ t.controlManager = new tinymce.ControlManager(t);
+ t.undoManager = new tinymce.UndoManager(t);
+
+ // Pass through
+ t.undoManager.onAdd.add(function(um, l) {
+ if (!l.initial)
+ return t.onChange.dispatch(t, l, um);
+ });
+
+ t.undoManager.onUndo.add(function(um, l) {
+ return t.onUndo.dispatch(t, l, um);
+ });
+
+ t.undoManager.onRedo.add(function(um, l) {
+ return t.onRedo.dispatch(t, l, um);
+ });
+
+ if (s.custom_undo_redo) {
+ t.onExecCommand.add(function(ed, cmd, ui, val, a) {
+ if (cmd != 'Undo' && cmd != 'Redo' && cmd != 'mceRepaint' && (!a || !a.skip_undo))
+ t.undoManager.add();
+ });
+ }
+
+ t.onExecCommand.add(function(ed, c) {
+ // Don't refresh the select lists until caret move
+ if (!/^(FontName|FontSize)$/.test(c))
+ t.nodeChanged();
+ });
+
+ // Remove ghost selections on images and tables in Gecko
+ if (isGecko) {
+ function repaint(a, o) {
+ if (!o || !o.initial)
+ t.execCommand('mceRepaint');
+ };
+
+ t.onUndo.add(repaint);
+ t.onRedo.add(repaint);
+ t.onSetContent.add(repaint);
+ }
+
+ // Enables users to override the control factory
+ t.onBeforeRenderUI.dispatch(t, t.controlManager);
+
+ // Measure box
+ if (s.render_ui) {
+ w = s.width || e.style.width || e.offsetWidth;
+ h = s.height || e.style.height || e.offsetHeight;
+ t.orgDisplay = e.style.display;
+ re = /^[0-9\.]+(|px)$/i;
+
+ if (re.test('' + w))
+ w = Math.max(parseInt(w) + (o.deltaWidth || 0), 100);
+
+ if (re.test('' + h))
+ h = Math.max(parseInt(h) + (o.deltaHeight || 0), 100);
+
+ // Render UI
+ o = t.theme.renderUI({
+ targetNode : e,
+ width : w,
+ height : h,
+ deltaWidth : s.delta_width,
+ deltaHeight : s.delta_height
+ });
+
+ t.editorContainer = o.editorContainer;
+ }
+
+ // #if contentEditable
+
+ // Content editable mode ends here
+ if (s.content_editable) {
+ e = n = o = null; // Fix IE leak
+ return t.setupContentEditable();
+ }
+
+ // #endif
+
+ // Resize editor
+ DOM.setStyles(o.sizeContainer || o.editorContainer, {
+ width : w,
+ height : h
+ });
+
+ h = (o.iframeHeight || h) + ((h + '').indexOf('%') == -1 ? (o.deltaHeight || 0) : '');
+ if (h < 100)
+ h = 100;
+
+ t.iframeHTML = s.doctype + '<html><head xmlns="http://www.w3.org/1999/xhtml"><base href="' + t.documentBaseURI.getURI() + '"></base>';
+ t.iframeHTML += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />';
+
+ if (tinymce.relaxedDomain)
+ t.iframeHTML += '<script type="text/javascript">document.domain = "' + tinymce.relaxedDomain + '";</script>';
+
+ bi = s.body_id || 'tinymce';
+ if (bi.indexOf('=') != -1) {
+ bi = t.getParam('body_id', '', 'hash');
+ bi = bi[t.id] || bi;
+ }
+
+ bc = s.body_class || '';
+ if (bc.indexOf('=') != -1) {
+ bc = t.getParam('body_class', '', 'hash');
+ bc = bc[t.id] || '';
+ }
+
+ t.iframeHTML += '</head><body id="' + bi + '" class="mceContentBody ' + bc + '"></body></html>';
+
+ // Domain relaxing enabled, then set document domain
+ if (tinymce.relaxedDomain) {
+ // We need to write the contents here in IE since multiple writes messes up refresh button and back button
+ if (isIE)
+ u = 'javascript:(function(){document.open();document.domain="' + document.domain + '";var ed = window.parent.tinyMCE.get("' + t.id + '");document.write(ed.iframeHTML);document.close();ed.setupIframe();})()';
+ else if (tinymce.isOpera)
+ u = 'javascript:(function(){document.open();document.domain="' + document.domain + '";document.close();ed.setupIframe();})()';
+ }
+
+ // Create iframe
+ n = DOM.add(o.iframeContainer, 'iframe', {
+ id : t.id + "_ifr",
+ src : u || 'javascript:""', // Workaround for HTTPS warning in IE6/7
+ frameBorder : '0',
+ style : {
+ width : '100%',
+ height : h
+ }
+ });
+
+ t.contentAreaContainer = o.iframeContainer;
+ DOM.get(o.editorContainer).style.display = t.orgDisplay;
+ DOM.get(t.id).style.display = 'none';
+
+ // Safari 2.x requires us to wait for the load event and load a real HTML doc
+ if (tinymce.isOldWebKit) {
+ Event.add(n, 'load', t.setupIframe, t);
+ n.src = tinymce.baseURL + '/plugins/safari/blank.htm';
+ } else {
+ if (!isIE || !tinymce.relaxedDomain)
+ t.setupIframe();
+
+ e = n = o = null; // Cleanup
+ }
+ },
+
+ /**
+ * This method get called by the init method ones the iframe is loaded.
+ * It will fill the iframe with contents, setups DOM and selection objects for the iframe.
+ * This method should not be called directly.
+ */
+ setupIframe : function() {
+ var t = this, s = t.settings, e = DOM.get(t.id), d = t.getDoc(), h, b;
+
+ // Setup iframe body
+ if (!isIE || !tinymce.relaxedDomain) {
+ d.open();
+ d.write(t.iframeHTML);
+ d.close();
+ }
+
+ // Design mode needs to be added here Ctrl+A will fail otherwise
+ if (!isIE) {
+ try {
+ d.designMode = 'On';
+ } catch (ex) {
+ // Will fail on Gecko if the editor is placed in an hidden container element
+ // The design mode will be set ones the editor is focused
+ }
+ }
+
+ // IE needs to use contentEditable or it will display non secure items for HTTPS
+ if (isIE) {
+ // It will not steal focus if we hide it while setting contentEditable
+ b = t.getBody();
+ DOM.hide(b);
+ b.contentEditable = true;
+ DOM.show(b);
+ }
+
+ // Setup objects
+ t.dom = new tinymce.DOM.DOMUtils(t.getDoc(), {
+ keep_values : true,
+ url_converter : t.convertURL,
+ url_converter_scope : t,
+ hex_colors : s.force_hex_style_colors,
+ class_filter : s.class_filter,
+ update_styles : 1,
+ fix_ie_paragraphs : 1
+ });
+
+ t.serializer = new tinymce.dom.Serializer({
+ entity_encoding : s.entity_encoding,
+ entities : s.entities,
+ valid_elements : s.verify_html === false ? '*[*]' : s.valid_elements,
+ extended_valid_elements : s.extended_valid_elements,
+ valid_child_elements : s.valid_child_elements,
+ invalid_elements : s.invalid_elements,
+ fix_table_elements : s.fix_table_elements,
+ fix_list_elements : s.fix_list_elements,
+ fix_content_duplication : s.fix_content_duplication,
+ convert_fonts_to_spans : s.convert_fonts_to_spans,
+ font_size_classes : s.font_size_classes,
+ font_size_style_values : s.font_size_style_values,
+ apply_source_formatting : s.apply_source_formatting,
+ remove_linebreaks : s.remove_linebreaks,
+ dom : t.dom
+ });
+
+ t.selection = new tinymce.dom.Selection(t.dom, t.getWin(), t.serializer);
+ t.forceBlocks = new tinymce.ForceBlocks(t, {
+ forced_root_block : s.forced_root_block
+ });
+ t.editorCommands = new tinymce.EditorCommands(t);
+
+ // Pass through
+ t.serializer.onPreProcess.add(function(se, o) {
+ return t.onPreProcess.dispatch(t, o, se);
+ });
+
+ t.serializer.onPostProcess.add(function(se, o) {
+ return t.onPostProcess.dispatch(t, o, se);
+ });
+
+ t.onPreInit.dispatch(t);
+
+ if (!s.gecko_spellcheck)
+ t.getBody().spellcheck = 0;
+
+ t._addEvents();
+
+ t.controlManager.onPostRender.dispatch(t, t.controlManager);
+ t.onPostRender.dispatch(t);
+
+ if (s.directionality)
+ t.getBody().dir = s.directionality;
+
+ if (s.nowrap)
+ t.getBody().style.whiteSpace = "nowrap";
+
+ if (s.auto_resize)
+ t.onNodeChange.add(t.resizeToContent, t);
+
+ if (s.custom_elements) {
+ function handleCustom(ed, o) {
+ each(explode(s.custom_elements), function(v) {
+ var n;
+
+ if (v.indexOf('~') === 0) {
+ v = v.substring(1);
+ n = 'span';
+ } else
+ n = 'div';
+
+ o.content = o.content.replace(new RegExp('<(' + v + ')([^>]*)>', 'g'), '<' + n + ' mce_name="$1"$2>');
+ o.content = o.content.replace(new RegExp('</(' + v + ')>', 'g'), '</' + n + '>');
+ });
+ };
+
+ t.onBeforeSetContent.add(handleCustom);
+ t.onPostProcess.add(function(ed, o) {
+ if (o.set)
+ handleCustom(ed, o)
+ });
+ }
+
+ if (s.handle_node_change_callback) {
+ t.onNodeChange.add(function(ed, cm, n) {
+ t.execCallback('handle_node_change_callback', t.id, n, -1, -1, true, t.selection.isCollapsed());
+ });
+ }
+
+ if (s.save_callback) {
+ t.onSaveContent.add(function(ed, o) {
+ var h = t.execCallback('save_callback', t.id, o.content, t.getBody());
+
+ if (h)
+ o.content = h;
+ });
+ }
+
+ if (s.onchange_callback) {
+ t.onChange.add(function(ed, l) {
+ t.execCallback('onchange_callback', t, l);
+ });
+ }
+
+ if (s.convert_newlines_to_brs) {
+ t.onBeforeSetContent.add(function(ed, o) {
+ if (o.initial)
+ o.content = o.content.replace(/\r?\n/g, '<br />');
+ });
+ }
+
+ if (s.fix_nesting && isIE) {
+ t.onBeforeSetContent.add(function(ed, o) {
+ o.content = t._fixNesting(o.content);
+ });
+ }
+
+ if (s.preformatted) {
+ t.onPostProcess.add(function(ed, o) {
+ o.content = o.content.replace(/^\s*<pre.*?>/, '');
+ o.content = o.content.replace(/<\/pre>\s*$/, '');
+
+ if (o.set)
+ o.content = '<pre class="mceItemHidden">' + o.content + '</pre>';
+ });
+ }
+
+ if (s.verify_css_classes) {
+ t.serializer.attribValueFilter = function(n, v) {
+ var s, cl;
+
+ if (n == 'class') {
+ // Build regexp for classes
+ if (!t.classesRE) {
+ cl = t.dom.getClasses();
+
+ if (cl.length > 0) {
+ s = '';
+
+ each (cl, function(o) {
+ s += (s ? '|' : '') + o['class'];
+ });
+
+ t.classesRE = new RegExp('(' + s + ')', 'gi');
+ }
+ }
+
+ return !t.classesRE || /(\bmceItem\w+\b|\bmceTemp\w+\b)/g.test(v) || t.classesRE.test(v) ? v : '';
+ }
+
+ return v;
+ };
+ }
+
+ if (s.convert_fonts_to_spans)
+ t._convertFonts();
+
+ if (s.inline_styles)
+ t._convertInlineElements();
+
+ if (s.cleanup_callback) {
+ t.onBeforeSetContent.add(function(ed, o) {
+ o.content = t.execCallback('cleanup_callback', 'insert_to_editor', o.content, o);
+ });
+
+ t.onPreProcess.add(function(ed, o) {
+ if (o.set)
+ t.execCallback('cleanup_callback', 'insert_to_editor_dom', o.node, o);
+
+ if (o.get)
+ t.execCallback('cleanup_callback', 'get_from_editor_dom', o.node, o);
+ });
+
+ t.onPostProcess.add(function(ed, o) {
+ if (o.set)
+ o.content = t.execCallback('cleanup_callback', 'insert_to_editor', o.content, o);
+
+ if (o.get)
+ o.content = t.execCallback('cleanup_callback', 'get_from_editor', o.content, o);
+ });
+ }
+
+ if (s.save_callback) {
+ t.onGetContent.add(function(ed, o) {
+ if (o.save)
+ o.content = t.execCallback('save_callback', t.id, o.content, t.getBody());
+ });
+ }
+
+ if (s.handle_event_callback) {
+ t.onEvent.add(function(ed, e, o) {
+ if (t.execCallback('handle_event_callback', e, ed, o) === false)
+ Event.cancel(e);
+ });
+ }
+
+ t.onSetContent.add(function() {
+ // Safari needs some time, it will crash the browser when a link is created otherwise
+ // I think this crash issue is resolved in the latest 3.0.4
+ //window.setTimeout(function() {
+ t.addVisual(t.getBody());
+ //}, 1);
+ });
+
+ // Remove empty contents
+ if (s.padd_empty_editor) {
+ t.onPostProcess.add(function(ed, o) {
+ o.content = o.content.replace(/^(<p>(&nbsp;|&#160;|\s|\u00a0|)<\/p>[\r\n]*|<br \/>[\r\n]*)$/, '');
+ });
+ }
+
+ if (isGecko) {
+ try {
+ // Design mode must be set here once again to fix a bug where
+ // Ctrl+A/Delete/Backspace didn't work if the editor was added using mceAddControl then removed then added again
+ d.designMode = 'Off';
+ d.designMode = 'On';
+ } catch (ex) {
+ // Will fail on Gecko if the editor is placed in an hidden container element
+ // The design mode will be set ones the editor is focused
+ }
+ }
+
+ // A small timeout was needed since firefox will remove. Bug: #1838304
+ setTimeout(function () {
+ if (t.removed)
+ return;
+
+ t.load({initial : true, format : (s.cleanup_on_startup ? 'html' : 'raw')});
+ t.startContent = t.getContent({format : 'raw'});
+ t.undoManager.add({initial : true});
+ t.initialized = true;
+
+ t.onInit.dispatch(t);
+ t.execCallback('setupcontent_callback', t.id, t.getBody(), t.getDoc());
+ t.execCallback('init_instance_callback', t);
+ t.focus(true);
+ t.nodeChanged({initial : 1});
+
+ // Load specified content CSS last
+ if (s.content_css) {
+ tinymce.each(explode(s.content_css), function(u) {
+ t.dom.loadCSS(t.documentBaseURI.toAbsolute(u));
+ });
+ }
+
+ // Handle auto focus
+ if (s.auto_focus) {
+ setTimeout(function () {
+ var ed = EditorManager.get(s.auto_focus);
+
+ ed.selection.select(ed.getBody(), 1);
+ ed.selection.collapse(1);
+ ed.getWin().focus();
+ }, 100);
+ }
+ }, 1);
+
+ e = null;
+ },
+
+ // #if contentEditable
+
+ /**
+ * Sets up the contentEditable mode.
+ */
+ setupContentEditable : function() {
+ var t = this, s = t.settings, e = t.getElement();
+
+ t.contentDocument = s.content_document || document;
+ t.contentWindow = s.content_window || window;
+ t.bodyElement = e;
+
+ // Prevent leak in IE
+ s.content_document = s.content_window = null;
+
+ DOM.hide(e);
+ e.contentEditable = true;
+ DOM.show(e);
+
+ if (!s.gecko_spellcheck)
+ t.getDoc().body.spellcheck = 0;
+
+ // Setup objects
+ t.dom = new tinymce.DOM.DOMUtils(t.getDoc(), {
+ keep_values : true,
+ url_converter : t.convertURL,
+ url_converter_scope : t,
+ hex_colors : s.force_hex_style_colors,
+ class_filter : s.class_filter,
+ root_element : t.id,
+ strict_root : 1,
+ fix_ie_paragraphs : 1,
+ update_styles : 1
+ });
+
+ t.serializer = new tinymce.dom.Serializer({
+ entity_encoding : s.entity_encoding,
+ entities : s.entities,
+ valid_elements : s.verify_html === false ? '*[*]' : s.valid_elements,
+ extended_valid_elements : s.extended_valid_elements,
+ valid_child_elements : s.valid_child_elements,
+ invalid_elements : s.invalid_elements,
+ fix_table_elements : s.fix_table_elements,
+ fix_list_elements : s.fix_list_elements,
+ fix_content_duplication : s.fix_content_duplication,
+ convert_fonts_to_spans : s.convert_fonts_to_spans,
+ font_size_classes : s.font_size_classes,
+ font_size_style_values : s.font_size_style_values,
+ apply_source_formatting : s.apply_source_formatting,
+ dom : t.dom
+ });
+
+ t.selection = new tinymce.dom.Selection(t.dom, t.getWin(), t.serializer);
+ t.forceBlocks = new tinymce.ForceBlocks(t, {
+ forced_root_block : s.forced_root_block
+ });
+ t.editorCommands = new tinymce.EditorCommands(t);
+
+ // Pass through
+ t.serializer.onPreProcess.add(function(se, o) {
+ return t.onPreProcess.dispatch(t, o, se);
+ });
+
+ t.serializer.onPostProcess.add(function(se, o) {
+ return t.onPostProcess.dispatch(t, o, se);
+ });
+
+ t.onPreInit.dispatch(t);
+ t._addEvents();
+
+ t.controlManager.onPostRender.dispatch(t, t.controlManager);
+ t.onPostRender.dispatch(t);
+
+ if (s.convert_fonts_to_spans)
+ t._convertFonts();
+
+ if (s.inline_styles)
+ t._convertInlineElements();
+
+ t.onSetContent.add(function() {
+ t.addVisual(t.getBody());
+ });
+
+ t.load({initial : true, format : (s.cleanup_on_startup ? 'html' : 'raw')});
+ t.startContent = t.getContent({format : 'raw'});
+ t.undoManager.add({initial : true});
+ t.initialized = true;
+
+ t.onInit.dispatch(t);
+ t.focus(true);
+ t.nodeChanged({initial : 1});
+
+ // Load specified content CSS last
+ if (s.content_css) {
+ each(explode(s.content_css), function(u) {
+ t.dom.loadCSS(t.documentBaseURI.toAbsolute(u));
+ });
+ }
+
+ if (isIE) {
+ t.onBeforeExecCommand.add(function(ed, cmd, ui, val, o) {
+ if (!DOM.getParent(ed.selection.getStart(), function(n) {return n == ed.getBody();}))
+ o.terminate = 1;
+
+ if (!DOM.getParent(ed.selection.getEnd(), function(n) {return n == ed.getBody();}))
+ o.terminate = 1;
+ });
+ }
+
+ e = null; // Cleanup
+ },
+
+ // #endif
+
+ /**
+ * Focuses/activates the editor. This will set this editor as the activeEditor in the EditorManager
+ * it will also place DOM focus inside the editor.
+ *
+ * @param {bool} sf Skip DOM focus. Just set is as the active editor.
+ */
+ focus : function(sf) {
+ var oed, t = this, ce = t.settings.content_editable;
+
+ if (!sf) {
+ if (!ce)
+ t.getWin().focus();
+
+ // #if contentEditable
+
+ // Content editable mode ends here
+ if (tinymce.isIE && ce)
+ t.getElement().focus();
+
+ // #endif
+ }
+
+ if (EditorManager.activeEditor != t) {
+ if ((oed = EditorManager.activeEditor) != null)
+ oed.onDeactivate.dispatch(oed, t);
+
+ t.onActivate.dispatch(t, oed);
+ }
+
+ EditorManager._setActive(t);
+ },
+
+ /**
+ * Executes a legacy callback. This method is useful to call old 2.x option callbacks.
+ * There new event model is a better way to add callback so this method might be removed in the future.
+ *
+ * @param {String} n Name of the callback to execute.
+ * @return {Object} Return value passed from callback function.
+ */
+ execCallback : function(n) {
+ var t = this, f = t.settings[n], s;
+
+ if (!f)
+ return;
+
+ // Look through lookup
+ if (t.callbackLookup && (s = t.callbackLookup[n])) {
+ f = s.func;
+ s = s.scope;
+ }
+
+ if (is(f, 'string')) {
+ s = f.replace(/\.\w+$/, '');
+ s = s ? tinymce.resolve(s) : 0;
+ f = tinymce.resolve(f);
+ t.callbackLookup = t.callbackLookup || {};
+ t.callbackLookup[n] = {func : f, scope : s};
+ }
+
+ return f.apply(s || t, Array.prototype.slice.call(arguments, 1));
+ },
+
+ /**
+ * Translates the specified string by replacing variables with language pack items it will also check if there is
+ * a key mathcin the input.
+ *
+ * @param {String} s String to translate by the language pack data.
+ * @return {String} Translated string.
+ */
+ translate : function(s) {
+ var c = this.settings.language, i18n = EditorManager.i18n;
+
+ if (!s)
+ return '';
+
+ return i18n[c + '.' + s] || s.replace(/{\#([^}]+)\}/g, function(a, b) {
+ return i18n[c + '.' + b] || '{#' + b + '}';
+ });
+ },
+
+ /**
+ * Returns a language pack item by name/key.
+ *
+ * @param {String} n Name/key to get from the language pack.
+ * @param {String} dv Optional default value to retrive.
+ */
+ getLang : function(n, dv) {
+ return EditorManager.i18n[this.settings.language + '.' + n] || (is(dv) ? dv : '{#' + n + '}');
+ },
+
+ /**
+ * Returns a configuration parameter by name.
+ *
+ * @param {String} n Configruation parameter to retrive.
+ * @param {String} dv Optional default value to return.
+ * @param {String} ty Optional type parameter.
+ * @return {String} Configuration parameter value or default value.
+ */
+ getParam : function(n, dv, ty) {
+ var tr = tinymce.trim, v = is(this.settings[n]) ? this.settings[n] : dv, o;
+
+ if (ty === 'hash') {
+ o = {};
+
+ if (is(v, 'string')) {
+ each(v.indexOf('=') > 0 ? v.split(/[;,](?![^=;,]*(?:[;,]|$))/) : v.split(','), function(v) {
+ v = v.split('=');
+
+ if (v.length > 1)
+ o[tr(v[0])] = tr(v[1]);
+ else
+ o[tr(v[0])] = tr(v);
+ });
+ } else
+ o = v;
+
+ return o;
+ }
+
+ return v;
+ },
+
+ /**
+ * Distpaches out a onNodeChange event to all observers. This method should be called when you
+ * need to update the UI states or element path etc.
+ *
+ * @param {Object} o Optional object to pass along for the node changed event.
+ */
+ nodeChanged : function(o) {
+ var t = this, s = t.selection, n = s.getNode() || t.getBody();
+
+ // Fix for bug #1896577 it seems that this can not be fired while the editor is loading
+ if (t.initialized) {
+ t.onNodeChange.dispatch(
+ t,
+ o ? o.controlManager || t.controlManager : t.controlManager,
+ isIE && n.ownerDocument != t.getDoc() ? t.getBody() : n, // Fix for IE initial state
+ s.isCollapsed(),
+ o
+ );
+ }
+ },
+
+ /**
+ * Adds a button that later gets created by the ControlManager. This is a shorter and easier method
+ * of adding buttons without the need to deal with the ControlManager directly. But it's also less
+ * powerfull if you need more control use the ControlManagers factory methods instead.
+ *
+ * @param {String} n Button name to add.
+ * @param {Object} s Settings object with title, cmd etc.
+ */
+ addButton : function(n, s) {
+ var t = this;
+
+ t.buttons = t.buttons || {};
+ t.buttons[n] = s;
+ },
+
+ /**
+ * Adds a custom command to the editor, you can also override existing commands with this method.
+ * The command that you add can be executed with execCommand.
+ *
+ * @param {String} n Command name to add/override.
+ * @param {function} f Function to execute when the command occurs.
+ * @param {Object} s Optional scope to execute the function in.
+ */
+ addCommand : function(n, f, s) {
+ this.execCommands[n] = {func : f, scope : s || this};
+ },
+
+ /**
+ * Adds a custom query state command to the editor, you can also override existing commands with this method.
+ * The command that you add can be executed with queryCommandState function.
+ *
+ * @param {String} n Command name to add/override.
+ * @param {function} f Function to execute when the command state retrival occurs.
+ * @param {Object} s Optional scope to execute the function in.
+ */
+ addQueryStateHandler : function(n, f, s) {
+ this.queryStateCommands[n] = {func : f, scope : s || this};
+ },
+
+ /**
+ * Adds a custom query value command to the editor, you can also override existing commands with this method.
+ * The command that you add can be executed with queryCommandValue function.
+ *
+ * @param {String} n Command name to add/override.
+ * @param {function} f Function to execute when the command value retrival occurs.
+ * @param {Object} s Optional scope to execute the function in.
+ */
+ addQueryValueHandler : function(n, f, s) {
+ this.queryValueCommands[n] = {func : f, scope : s || this};
+ },
+
+ /**
+ * Adds a keyboard shortcut for some command or function.
+ *
+ * @param {String} pa Shortcut pattern. Like for example: ctrl+alt+o.
+ * @param {String} desc Text description for the command.
+ * @param {String/Function} cmd_func Command name string or function to execute when the key is pressed.
+ * @param {Object} sc Optional scope to execute the function in.
+ * @return {bool} true/false state if the shortcut was added or not.
+ */
+ addShortcut : function(pa, desc, cmd_func, sc) {
+ var t = this, c;
+
+ if (!t.settings.custom_shortcuts)
+ return false;
+
+ t.shortcuts = t.shortcuts || {};
+
+ if (is(cmd_func, 'string')) {
+ c = cmd_func;
+
+ cmd_func = function() {
+ t.execCommand(c, false, null);
+ };
+ }
+
+ if (is(cmd_func, 'object')) {
+ c = cmd_func;
+
+ cmd_func = function() {
+ t.execCommand(c[0], c[1], c[2]);
+ };
+ }
+
+ each(explode(pa), function(pa) {
+ var o = {
+ func : cmd_func,
+ scope : sc || this,
+ desc : desc,
+ alt : false,
+ ctrl : false,
+ shift : false
+ };
+
+ each(explode(pa, '+'), function(v) {
+ switch (v) {
+ case 'alt':
+ case 'ctrl':
+ case 'shift':
+ o[v] = true;
+ break;
+
+ default:
+ o.charCode = v.charCodeAt(0);
+ o.keyCode = v.toUpperCase().charCodeAt(0);
+ }
+ });
+
+ t.shortcuts[(o.ctrl ? 'ctrl' : '') + ',' + (o.alt ? 'alt' : '') + ',' + (o.shift ? 'shift' : '') + ',' + o.keyCode] = o;
+ });
+
+ return true;
+ },
+
+ /**
+ * Executes a command on the current instance. These commands can be TinyMCE internal commands prefixed with "mce" or
+ * they can be build in browser commands such as "Bold". A compleate list of browser commands is available on MSDN or Mozilla.org.
+ * This function will dispatch the execCommand function on each plugin, theme or the execcommand_callback option if none of these
+ * return true it will handle the command as a internal browser command.
+ *
+ * @param {String} cmd Command name to execute, for example mceLink or Bold.
+ * @param {bool} ui True/false state if a UI (dialog) should be presented or not.
+ * @param {mixed} val Optional command value, this can be anything.
+ * @param {Object} a Optional arguments object.
+ * @return {bool} True/false if the command was executed or not.
+ */
+ execCommand : function(cmd, ui, val, a) {
+ var t = this, s = 0, o, st;
+
+ if (!/^(mceAddUndoLevel|mceEndUndoLevel|mceBeginUndoLevel|mceRepaint|SelectAll)$/.test(cmd) && (!a || !a.skip_focus))
+ t.focus();
+
+ o