yui.inc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. <?php
  2. /**
  3. * @file
  4. * Editor integration functions for YUI editor.
  5. */
  6. /**
  7. * Plugin implementation of hook_editor().
  8. */
  9. function wysiwyg_yui_editor() {
  10. $editor['yui'] = array(
  11. 'title' => 'YUI editor',
  12. 'vendor url' => 'http://developer.yahoo.com/yui/editor/',
  13. 'download url' => 'http://developer.yahoo.com/yui/download/',
  14. 'library path' => wysiwyg_get_path('yui') . '/build',
  15. 'libraries' => array(
  16. 'min' => array(
  17. 'title' => 'Minified',
  18. 'files' => array(
  19. 'yahoo-dom-event/yahoo-dom-event.js',
  20. 'animation/animation-min.js',
  21. 'element/element-min.js',
  22. 'container/container-min.js',
  23. 'menu/menu-min.js',
  24. 'button/button-min.js',
  25. 'editor/editor-min.js',
  26. ),
  27. ),
  28. 'src' => array(
  29. 'title' => 'Source',
  30. 'files' => array(
  31. 'yahoo-dom-event/yahoo-dom-event.js',
  32. 'animation/animation.js',
  33. 'element/element.js',
  34. 'container/container.js',
  35. 'menu/menu.js',
  36. 'button/button.js',
  37. 'editor/editor.js',
  38. ),
  39. ),
  40. ),
  41. 'install note callback' => 'wysiwyg_yui_install_note',
  42. 'verified version range' => array('2.7.0', '2.9.0'),
  43. 'version callback' => 'wysiwyg_yui_version',
  44. 'themes callback' => 'wysiwyg_yui_themes',
  45. 'settings form callback' => 'wysiwyg_yui_settings_form',
  46. 'load callback' => 'wysiwyg_yui_load',
  47. 'settings callback' => 'wysiwyg_yui_settings',
  48. 'plugin callback' => '_wysiwyg_yui_plugins',
  49. 'plugin meta callback' => '_wysiwyg_yui_plugin_meta',
  50. 'proxy plugin' => array(
  51. 'drupal' => array(
  52. 'load' => TRUE,
  53. 'proxy' => TRUE,
  54. ),
  55. ),
  56. 'proxy plugin settings callback' => '_wysiwyg_yui_proxy_plugin_settings',
  57. 'versions' => array(
  58. '2.7.0' => array(
  59. 'js files' => array('yui.js'),
  60. ),
  61. ),
  62. );
  63. return $editor;
  64. }
  65. /**
  66. * Return an install note.
  67. */
  68. function wysiwyg_yui_install_note() {
  69. $output = '<p class="warning">' . t('YUI 3 is not supported because it does not contain a complete editor.') . '</p>';
  70. return $output;
  71. }
  72. /**
  73. * Detect editor version.
  74. *
  75. * @param $editor
  76. * An array containing editor properties as returned from hook_editor().
  77. *
  78. * @return
  79. * The installed editor version.
  80. */
  81. function wysiwyg_yui_version($editor) {
  82. $library = $editor['library path'] . '/editor/editor.js';
  83. if (!file_exists($library)) {
  84. return;
  85. }
  86. $library = fopen($library, 'r');
  87. $max_lines = 10;
  88. while ($max_lines && $line = fgets($library, 60)) {
  89. if (preg_match('@version:\s([0-9\.]+)@', $line, $version)) {
  90. fclose($library);
  91. return $version[1];
  92. }
  93. $max_lines--;
  94. }
  95. fclose($library);
  96. }
  97. /**
  98. * Determine available editor themes or check/reset a given one.
  99. *
  100. * @param $editor
  101. * A processed hook_editor() array of editor properties.
  102. * @param $profile
  103. * A wysiwyg editor profile.
  104. *
  105. * @return
  106. * An array of theme names. The first returned name should be the default
  107. * theme name.
  108. */
  109. function wysiwyg_yui_themes($editor, $profile) {
  110. return array('sam');
  111. }
  112. /**
  113. * Enhances the editor profile settings form for YUI.
  114. *
  115. * @see http://developer.yahoo.com/yui/docs/YAHOO.widget.Editor.html
  116. */
  117. function wysiwyg_yui_settings_form(&$form, &$form_state) {
  118. $profile = $form_state['wysiwyg_profile'];
  119. $settings = $profile->settings;
  120. $settings += array(
  121. 'autoHeight' => FALSE,
  122. 'block_formats' => 'p,h1,h2,h3,h4,h5,h6',
  123. );
  124. $form['basic']['language']['#access'] = FALSE;
  125. $form['appearance']['autoHeight'] = array(
  126. '#type' => 'checkbox',
  127. '#title' => t('Enable automatic height'),
  128. '#default_value' => $settings['autoHeight'],
  129. '#return_value' => 1,
  130. '#description' => t('When enabled, removes the scrollbars from the edit area and resizes it to fit the content.') . ' ' . t('Uses the <a href="@url">@setting</a> setting internally.', array('@setting' => 'autoHeight', '@url' => url('http://developer.yahoo.com/yui/docs/YAHOO.widget.SimpleEditor.html#config_autoHeight'))),
  131. );
  132. $form['css']['block_formats'] = array(
  133. '#type' => 'textfield',
  134. '#title' => t('Block formats'),
  135. '#default_value' => $settings['block_formats'],
  136. '#size' => 40,
  137. '#maxlength' => 250,
  138. '#description' => t('Comma separated list of HTML block formats. Possible values: <code>@format-list</code>.', array('@format-list' => 'p,h1,h2,h3,h4,h5,h6,')),
  139. );
  140. }
  141. /**
  142. * Perform additional actions upon loading this editor.
  143. *
  144. * @param $editor
  145. * A processed hook_editor() array of editor properties.
  146. * @param $library
  147. * The internal library name (array key) to use.
  148. */
  149. function wysiwyg_yui_load($editor, $library) {
  150. drupal_add_css($editor['library path'] . '/menu/assets/skins/sam/menu.css');
  151. drupal_add_css($editor['library path'] . '/button/assets/skins/sam/button.css');
  152. drupal_add_css($editor['library path'] . '/fonts/fonts-min.css');
  153. drupal_add_css($editor['library path'] . '/container/assets/skins/sam/container.css');
  154. drupal_add_css($editor['library path'] . '/editor/assets/skins/sam/editor.css');
  155. }
  156. /**
  157. * Return runtime editor settings for a given wysiwyg profile.
  158. *
  159. * @param $editor
  160. * A processed hook_editor() array of editor properties.
  161. * @param $config
  162. * An array containing wysiwyg editor profile settings.
  163. * @param $theme
  164. * The name of a theme/GUI/skin to use.
  165. *
  166. * @return
  167. * A settings array to be populated in
  168. * Drupal.settings.wysiwyg.configs.{editor}
  169. */
  170. function wysiwyg_yui_settings($editor, $config, $theme) {
  171. $settings = array(
  172. 'theme' => $theme,
  173. 'animate' => TRUE,
  174. 'handleSubmit' => TRUE,
  175. 'markup' => 'xhtml',
  176. 'ptags' => TRUE,
  177. );
  178. if (!empty($config['autoHeight'])) {
  179. $settings['autoHeight'] = TRUE;
  180. }
  181. $settings += array(
  182. 'toolbar' => array(
  183. 'collapse' => FALSE,
  184. 'draggable' => TRUE,
  185. 'buttonType' => 'advanced',
  186. 'buttons' => array(),
  187. ),
  188. );
  189. if (!empty($config['buttons'])) {
  190. $buttons = array();
  191. foreach ($config['buttons'] as $plugin => $enabled_buttons) {
  192. foreach ($enabled_buttons as $button => $enabled) {
  193. $extra = array();
  194. if ($button == 'heading') {
  195. $extra = array('menu' => array(
  196. array('text' => 'Normal', 'value' => 'none', 'checked' => TRUE),
  197. ));
  198. if (!empty($config['block_formats'])) {
  199. $headings = array(
  200. 'p' => array('text' => 'Paragraph', 'value' => 'p'),
  201. 'h1' => array('text' => 'Heading 1', 'value' => 'h1'),
  202. 'h2' => array('text' => 'Heading 2', 'value' => 'h2'),
  203. 'h3' => array('text' => 'Heading 3', 'value' => 'h3'),
  204. 'h4' => array('text' => 'Heading 4', 'value' => 'h4'),
  205. 'h5' => array('text' => 'Heading 5', 'value' => 'h5'),
  206. 'h6' => array('text' => 'Heading 6', 'value' => 'h6'),
  207. );
  208. foreach (explode(',', preg_replace('@\s+@', '', $config['block_formats'])) as $tag) {
  209. if (isset($headings[$tag])) {
  210. $extra['menu'][] = $headings[$tag];
  211. }
  212. }
  213. }
  214. }
  215. elseif ($button == 'fontname') {
  216. $extra = array('menu' => array(
  217. array('text' => 'Arial', 'checked' => TRUE),
  218. array('text' => 'Arial Black'),
  219. array('text' => 'Comic Sans MS'),
  220. array('text' => 'Courier New'),
  221. array('text' => 'Lucida Console'),
  222. array('text' => 'Tahoma'),
  223. array('text' => 'Times New Roman'),
  224. array('text' => 'Trebuchet MS'),
  225. array('text' => 'Verdana'),
  226. ));
  227. }
  228. $buttons[] = wysiwyg_yui_button_setting($editor, $plugin, $button, $extra);
  229. }
  230. }
  231. // Group buttons in a dummy group.
  232. $buttons = array('group' => 'default', 'label' => '', 'buttons' => $buttons);
  233. $settings['toolbar']['buttons'] = array($buttons);
  234. }
  235. if (isset($config['css_setting'])) {
  236. if ($config['css_setting'] == 'theme') {
  237. $settings['extracss'] = wysiwyg_get_css(isset($config['css_theme']) ? $config['css_theme'] : '');
  238. }
  239. elseif ($config['css_setting'] == 'self' && isset($config['css_path'])) {
  240. $settings['extracss'] = strtr($config['css_path'], array(
  241. '%b' => base_path(),
  242. '%t' => drupal_get_path('theme', variable_get('theme_default', NULL)),
  243. '%q' => variable_get('css_js_query_string', ''),
  244. ));
  245. $settings['extracss'] = explode(',', $settings['extracss']);
  246. }
  247. // YUI only supports inline CSS, so we need to use @import directives.
  248. // Syntax: '@import "/base/path/to/theme/style.css"; '
  249. if (!empty($settings['extracss'])) {
  250. $settings['extracss'] = '@import "' . implode('"; @import "', $settings['extracss']) . '";';
  251. }
  252. }
  253. return $settings;
  254. }
  255. /**
  256. * Create the JavaScript structure for a YUI button.
  257. *
  258. * @param $editor
  259. * A processed hook_editor() array of editor properties.
  260. * @param $plugin
  261. * The internal name of a plugin.
  262. * @param $button
  263. * The internal name of a button, defined by $plugin.
  264. * @param $extra
  265. * (optional) An array containing arbitrary other elements to add to the
  266. * resulting button.
  267. */
  268. function wysiwyg_yui_button_setting($editor, $plugin, $button, $extra = array()) {
  269. static $plugins;
  270. if (!isset($plugins)) {
  271. $plugins = wysiwyg_get_plugins($editor['name']);
  272. }
  273. // Return a simple separator.
  274. if ($button === 'separator') {
  275. return array('type' => 'separator');
  276. }
  277. // Setup defaults.
  278. $type = 'push';
  279. $label = $plugins[$plugin]['buttons'][$button];
  280. // Special handling for certain buttons.
  281. if (in_array($button, array('heading', 'fontname'))) {
  282. $type = 'select';
  283. $label = $extra['menu'][0]['text'];
  284. }
  285. elseif (in_array($button, array('fontsize'))) {
  286. $type = 'spin';
  287. }
  288. elseif (in_array($button, array('forecolor', 'backcolor'))) {
  289. $type = 'color';
  290. }
  291. $button = array(
  292. 'type' => $type,
  293. 'label' => $label,
  294. 'value' => $button,
  295. );
  296. // Add arbitrary other elements, if defined.
  297. if (!empty($extra)) {
  298. $button = array_merge($button, $extra);
  299. }
  300. return $button;
  301. }
  302. /**
  303. * Build a JS settings array with global metadata for native external plugins.
  304. */
  305. function _wysiwyg_yui_plugin_meta($editor, $plugin) {
  306. $meta = NULL;
  307. if (!empty($plugin['load'])) {
  308. // Add path for native external plugins; internal ones are loaded
  309. // automatically.
  310. if (empty($plugin['internal']) && isset($plugin['path'])) {
  311. $meta = base_path() . $plugin['path'];
  312. }
  313. }
  314. return $meta;
  315. }
  316. /**
  317. * Build a JS settings array for Drupal plugins loaded via the proxy plugin.
  318. */
  319. function _wysiwyg_yui_proxy_plugin_settings($editor, $profile, $plugins) {
  320. $settings = array();
  321. foreach ($plugins as $name => $plugin) {
  322. $settings[$name] = array();
  323. }
  324. return $settings;
  325. }
  326. /**
  327. * Return internal plugins for this editor; semi-implementation of hook_wysiwyg_plugin().
  328. */
  329. function _wysiwyg_yui_plugins($editor) {
  330. return array(
  331. 'default' => array(
  332. 'buttons' => array(
  333. 'bold' => t('Bold'), 'italic' => t('Italic'), 'underline' => t('Underline'),
  334. 'strikethrough' => t('Strike-through'),
  335. 'justifyleft' => t('Align left'), 'justifycenter' => t('Align center'), 'justifyright' => t('Align right'), 'justifyfull' => t('Justify'),
  336. 'insertunorderedlist' => t('Bullet list'), 'insertorderedlist' => t('Numbered list'),
  337. 'outdent' => t('Outdent'), 'indent' => t('Indent'),
  338. 'undo' => t('Undo'), 'redo' => t('Redo'),
  339. 'createlink' => t('Link'),
  340. 'insertimage' => t('Image'),
  341. 'forecolor' => t('Font Color'), 'backcolor' => t('Background Color'),
  342. 'superscript' => t('Sup'), 'subscript' => t('Sub'),
  343. 'hiddenelements' => t('Show/hide hidden elements'),
  344. 'removeformat' => t('Remove format'),
  345. 'heading' => t('HTML block format'), 'fontname' => t('Font'), 'fontsize' => t('Font size'),
  346. ),
  347. 'internal' => TRUE,
  348. ),
  349. );
  350. }