yui.inc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  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. 'version callback' => 'wysiwyg_yui_version',
  42. 'themes callback' => 'wysiwyg_yui_themes',
  43. 'load callback' => 'wysiwyg_yui_load',
  44. 'settings callback' => 'wysiwyg_yui_settings',
  45. 'plugin callback' => 'wysiwyg_yui_plugins',
  46. 'plugin settings callback' => 'wysiwyg_yui_plugin_settings',
  47. 'proxy plugin' => array(
  48. 'drupal' => array(
  49. 'load' => TRUE,
  50. 'proxy' => TRUE,
  51. ),
  52. ),
  53. 'proxy plugin settings callback' => 'wysiwyg_yui_proxy_plugin_settings',
  54. 'versions' => array(
  55. '2.7.0' => array(
  56. 'js files' => array('yui.js'),
  57. ),
  58. ),
  59. );
  60. return $editor;
  61. }
  62. /**
  63. * Detect editor version.
  64. *
  65. * @param $editor
  66. * An array containing editor properties as returned from hook_editor().
  67. *
  68. * @return
  69. * The installed editor version.
  70. */
  71. function wysiwyg_yui_version($editor) {
  72. $library = $editor['library path'] . '/editor/editor.js';
  73. if (!file_exists($library)) {
  74. return;
  75. }
  76. $library = fopen($library, 'r');
  77. $max_lines = 10;
  78. while ($max_lines && $line = fgets($library, 60)) {
  79. if (preg_match('@version:\s([0-9\.]+)@', $line, $version)) {
  80. fclose($library);
  81. return $version[1];
  82. }
  83. $max_lines--;
  84. }
  85. fclose($library);
  86. }
  87. /**
  88. * Determine available editor themes or check/reset a given one.
  89. *
  90. * @param $editor
  91. * A processed hook_editor() array of editor properties.
  92. * @param $profile
  93. * A wysiwyg editor profile.
  94. *
  95. * @return
  96. * An array of theme names. The first returned name should be the default
  97. * theme name.
  98. */
  99. function wysiwyg_yui_themes($editor, $profile) {
  100. return array('sam');
  101. }
  102. /**
  103. * Perform additional actions upon loading this editor.
  104. *
  105. * @param $editor
  106. * A processed hook_editor() array of editor properties.
  107. * @param $library
  108. * The internal library name (array key) to use.
  109. */
  110. function wysiwyg_yui_load($editor, $library) {
  111. drupal_add_css($editor['library path'] . '/menu/assets/skins/sam/menu.css');
  112. drupal_add_css($editor['library path'] . '/button/assets/skins/sam/button.css');
  113. drupal_add_css($editor['library path'] . '/fonts/fonts-min.css');
  114. drupal_add_css($editor['library path'] . '/container/assets/skins/sam/container.css');
  115. drupal_add_css($editor['library path'] . '/editor/assets/skins/sam/editor.css');
  116. }
  117. /**
  118. * Return runtime editor settings for a given wysiwyg profile.
  119. *
  120. * @param $editor
  121. * A processed hook_editor() array of editor properties.
  122. * @param $config
  123. * An array containing wysiwyg editor profile settings.
  124. * @param $theme
  125. * The name of a theme/GUI/skin to use.
  126. *
  127. * @return
  128. * A settings array to be populated in
  129. * Drupal.settings.wysiwyg.configs.{editor}
  130. */
  131. function wysiwyg_yui_settings($editor, $config, $theme) {
  132. $settings = array(
  133. 'theme' => $theme,
  134. 'animate' => TRUE,
  135. 'handleSubmit' => TRUE,
  136. 'markup' => 'xhtml',
  137. 'ptags' => TRUE,
  138. );
  139. if (isset($config['path_loc']) && $config['path_loc'] != 'none') {
  140. $settings['dompath'] = $config['path_loc'];
  141. }
  142. // Enable auto-height feature when editor should be resizable.
  143. if (!empty($config['resizing'])) {
  144. $settings['autoHeight'] = TRUE;
  145. }
  146. $settings += array(
  147. 'toolbar' => array(
  148. 'collapse' => FALSE,
  149. 'draggable' => TRUE,
  150. 'buttonType' => 'advanced',
  151. 'buttons' => array(),
  152. ),
  153. );
  154. if (!empty($config['buttons'])) {
  155. $buttons = array();
  156. foreach ($config['buttons'] as $plugin => $enabled_buttons) {
  157. foreach ($enabled_buttons as $button => $enabled) {
  158. $extra = array();
  159. if ($button == 'heading') {
  160. $extra = array('menu' => array(
  161. array('text' => 'Normal', 'value' => 'none', 'checked' => TRUE),
  162. ));
  163. if (!empty($config['block_formats'])) {
  164. $headings = array(
  165. 'p' => array('text' => 'Paragraph', 'value' => 'p'),
  166. 'h1' => array('text' => 'Heading 1', 'value' => 'h1'),
  167. 'h2' => array('text' => 'Heading 2', 'value' => 'h2'),
  168. 'h3' => array('text' => 'Heading 3', 'value' => 'h3'),
  169. 'h4' => array('text' => 'Heading 4', 'value' => 'h4'),
  170. 'h5' => array('text' => 'Heading 5', 'value' => 'h5'),
  171. 'h6' => array('text' => 'Heading 6', 'value' => 'h6'),
  172. );
  173. foreach (explode(',', $config['block_formats']) as $tag) {
  174. if (isset($headings[$tag])) {
  175. $extra['menu'][] = $headings[$tag];
  176. }
  177. }
  178. }
  179. }
  180. elseif ($button == 'fontname') {
  181. $extra = array('menu' => array(
  182. array('text' => 'Arial', 'checked' => TRUE),
  183. array('text' => 'Arial Black'),
  184. array('text' => 'Comic Sans MS'),
  185. array('text' => 'Courier New'),
  186. array('text' => 'Lucida Console'),
  187. array('text' => 'Tahoma'),
  188. array('text' => 'Times New Roman'),
  189. array('text' => 'Trebuchet MS'),
  190. array('text' => 'Verdana'),
  191. ));
  192. }
  193. $buttons[] = wysiwyg_yui_button_setting($editor, $plugin, $button, $extra);
  194. }
  195. }
  196. // Group buttons in a dummy group.
  197. $buttons = array('group' => 'default', 'label' => '', 'buttons' => $buttons);
  198. $settings['toolbar']['buttons'] = array($buttons);
  199. }
  200. if (isset($config['css_setting'])) {
  201. if ($config['css_setting'] == 'theme') {
  202. $settings['extracss'] = wysiwyg_get_css();
  203. }
  204. elseif ($config['css_setting'] == 'self' && isset($config['css_path'])) {
  205. $settings['extracss'] = strtr($config['css_path'], array('%b' => base_path(), '%t' => drupal_get_path('theme', variable_get('theme_default', NULL))));
  206. $settings['extracss'] = explode(',', $settings['extracss']);
  207. }
  208. // YUI only supports inline CSS, so we need to use @import directives.
  209. // Syntax: '@import "/base/path/to/theme/style.css"; '
  210. if (!empty($settings['extracss'])) {
  211. $settings['extracss'] = '@import "' . implode('"; @import "', $settings['extracss']) . '";';
  212. }
  213. }
  214. return $settings;
  215. }
  216. /**
  217. * Create the JavaScript structure for a YUI button.
  218. *
  219. * @param $editor
  220. * A processed hook_editor() array of editor properties.
  221. * @param $plugin
  222. * The internal name of a plugin.
  223. * @param $button
  224. * The internal name of a button, defined by $plugin.
  225. * @param $extra
  226. * (optional) An array containing arbitrary other elements to add to the
  227. * resulting button.
  228. */
  229. function wysiwyg_yui_button_setting($editor, $plugin, $button, $extra = array()) {
  230. static $plugins;
  231. if (!isset($plugins)) {
  232. $plugins = wysiwyg_get_plugins($editor['name']);
  233. }
  234. // Return a simple separator.
  235. if ($button === 'separator') {
  236. return array('type' => 'separator');
  237. }
  238. // Setup defaults.
  239. $type = 'push';
  240. $label = $plugins[$plugin]['buttons'][$button];
  241. // Special handling for certain buttons.
  242. if (in_array($button, array('heading', 'fontname'))) {
  243. $type = 'select';
  244. $label = $extra['menu'][0]['text'];
  245. }
  246. elseif (in_array($button, array('fontsize'))) {
  247. $type = 'spin';
  248. }
  249. elseif (in_array($button, array('forecolor', 'backcolor'))) {
  250. $type = 'color';
  251. }
  252. $button = array(
  253. 'type' => $type,
  254. 'label' => $label,
  255. 'value' => $button,
  256. );
  257. // Add arbitrary other elements, if defined.
  258. if (!empty($extra)) {
  259. $button = array_merge($button, $extra);
  260. }
  261. return $button;
  262. }
  263. /**
  264. * Build a JS settings array of native external plugins that need to be loaded separately.
  265. */
  266. function wysiwyg_yui_plugin_settings($editor, $profile, $plugins) {
  267. $settings = array();
  268. foreach ($plugins as $name => $plugin) {
  269. if (!empty($plugin['load'])) {
  270. // Add path for native external plugins; internal ones are loaded
  271. // automatically.
  272. if (empty($plugin['internal']) && isset($plugin['path'])) {
  273. $settings[$name] = base_path() . $plugin['path'];
  274. }
  275. }
  276. }
  277. return $settings;
  278. }
  279. /**
  280. * Build a JS settings array for Drupal plugins loaded via the proxy plugin.
  281. */
  282. function wysiwyg_yui_proxy_plugin_settings($editor, $profile, $plugins) {
  283. $settings = array();
  284. foreach ($plugins as $name => $plugin) {
  285. // Populate required plugin settings.
  286. $settings[$name] = $plugin['dialog settings'] + array(
  287. 'title' => $plugin['title'],
  288. 'icon' => base_path() . $plugin['icon path'] . '/' . $plugin['icon file'],
  289. 'iconTitle' => $plugin['icon title'],
  290. // @todo These should only be set if the plugin defined them.
  291. 'css' => base_path() . $plugin['css path'] . '/' . $plugin['css file'],
  292. );
  293. }
  294. return $settings;
  295. }
  296. /**
  297. * Return internal plugins for this editor; semi-implementation of hook_wysiwyg_plugin().
  298. */
  299. function wysiwyg_yui_plugins($editor) {
  300. return array(
  301. 'default' => array(
  302. 'buttons' => array(
  303. 'bold' => t('Bold'), 'italic' => t('Italic'), 'underline' => t('Underline'),
  304. 'strikethrough' => t('Strike-through'),
  305. 'justifyleft' => t('Align left'), 'justifycenter' => t('Align center'), 'justifyright' => t('Align right'), 'justifyfull' => t('Justify'),
  306. 'insertunorderedlist' => t('Bullet list'), 'insertorderedlist' => t('Numbered list'),
  307. 'outdent' => t('Outdent'), 'indent' => t('Indent'),
  308. 'undo' => t('Undo'), 'redo' => t('Redo'),
  309. 'createlink' => t('Link'),
  310. 'insertimage' => t('Image'),
  311. 'forecolor' => t('Font Color'), 'backcolor' => t('Background Color'),
  312. 'superscript' => t('Sup'), 'subscript' => t('Sub'),
  313. 'hiddenelements' => t('Show/hide hidden elements'),
  314. 'removeformat' => t('Remove format'),
  315. 'heading' => t('HTML block format'), 'fontname' => t('Font'), 'fontsize' => t('Font size'),
  316. ),
  317. 'internal' => TRUE,
  318. ),
  319. );
  320. }