3 // A collaborative project by Matt Westgate <drupal at asitis dot org>
4 // and Richard Bennett <richard.b@gritechnologies.com>
8 * Integrate the TinyMCE editor (http://tinymce.moxiecode.com/) into Drupal.
12 * Implementation of hook_menu().
14 * Add the JavaScript file to the page head. Doing this in a menu hook is a
15 * little less expensive that in *_init since we don't need to load the head for
16 * Drupal-cached pages.
19 function tinymce_menu($may_cache) {
22 drupal_set_html_head('<script language="javascript" type="text/javascript" src="'.
drupal_get_path('module', 'tinymce') .
'/tinymce/jscripts/tiny_mce/tiny_mce.js"></script>');
23 //We may need this so TinyMCE has the right path to Drupal to invoke drupal tinymce plugins.
24 //drupal_set_html_head('<script language="javascript" type="text/javascript"> var baseUrl = "'. $base_url .'"; </script>');
25 // We have to do this becuase of some unfocused CSS in certain themes. See http://drupal.org/node/18879 for details
26 drupal_set_html_head('<style type="text/css" media="all">.mceEditor img { display: inline; }</style>');
31 * Implementation of hook_help().
33 function tinymce_help($section) {
35 case
'admin/modules#description':
36 return t('The TinyMCE Javascript HTML WYSIWYG editor.');
38 case
'admin/settings/tinymce#pages':
39 return "node/*\nuser/*\ncomment/*";
44 * Implementation of hook_perm().
46 function tinymce_perm() {
47 return array('access tinymce', 'choose own tinymce theme');
51 * Implementation of hook_img_assist_head().
53 function tinymce_img_assist_head() {
54 $popup_path = drupal_get_path('module', 'tinymce').
'/tinymce/jscripts/tiny_mce';
57 <script language
="javascript" src
="$popup_path/tiny_mce_popup.js"></script
>
58 <script language
="javascript">
59 function insertImage(form
) {
61 var thumb
= (form
['edit-thumb'].checked
) ?
1 : 0;
64 var src
= form
['edit[thumbpath]'].value
;
65 var width
= form
['edit[thumbWidth]'].value
;
66 var height
= form
['edit[thumbHeight]'].value
;
69 var src
= form
['edit[filepath]'].value
;
70 var width
= form
['edit[width]'].value
!= '' ? form
['edit[width]'].value
: form
['edit[origWidth]'].value
;
71 var height
= form
['edit[height]'].value
!= '' ? form
['edit[height]'].value
: form
['edit[origHeight]'].value
;
73 var alt
= form
['edit[alt]'].value
;
75 window.opener.tinyMCE.
insertImage(src
, alt
, '', '', '', width
, height
);
85 * Implementation of hook_img_assist_on_submit().
87 function tinymce_img_assist_on_submit() {
88 return 'parent.insertImage(this.form);';
92 * Implementation of hook_settings().
94 function tinymce_settings() {
95 drupal_set_title(t('TinyMCE settings'));
97 //Check if TinyMCE is installed.
98 $tinymce_loc = drupal_get_path('module', 'tinymce') .
'/tinymce/';
99 if (!is_dir($tinymce_loc)) {
100 drupal_set_message(t('Could not find the TinyMCE engine installed at <strong>%tinymce-directory</strong>. Please <a href="http://tinymce.moxiecode.com/">download TinyMCE</a>, uncompress it and copy the folder into %tinymce-path.', array('%tinymce-path' => drupal_get_path('module', 'tinymce'), '%tinymce-directory' => drupal_get_path('module', 'tinymce').
'/tinymce/')), 'error');
103 $group = form_radios(t('Default theme'), 'tinymce_theme', variable_get('tinymce_theme', 'simple'), _tinymce_get_themes());
104 $output = form_group(t('Themes'), $group);
106 $group = form_radios(t('access tinymce'), 'tinymce_all', variable_get('tinymce_all', 1), array(t('on specific pages'), t('on all textareas')));
107 if (!variable_get('tinymce_all', 1)) {
108 $group .
= form_textarea(t('Pages'), 'tinymce_pages', variable_get('tinymce_pages', tinymce_help('admin/settings/tinymce#pages')), 40, 5, t("Enter one page per line as Drupal paths. The '*' character is a wildcard. Example paths are '<em>blog</em>' for the blog page and '<em>blog/*</em>' for every personal blog. '<em><front></em>' is the front page."));
110 $output .
= form_group('', $group);
115 * Implementation of hook_textarea().
117 function tinymce_textarea($op, $name) {
118 static
$is_running = FALSE
;
119 if (!user_access('access tinymce')) return NULL
;
122 $theme_name = $user->tinymce_theme ?
$user->tinymce_theme
: variable_get('tinymce_theme', 'simple');
123 $user_status = $user->tinymce_status
!= NULL ?
$user->tinymce_status
: TRUE
;
125 if ($op == 'pre' && _tinymce_page_match() && $user_status) {
128 // Build a default list of TinyMCE settings.
129 $init['mode'] = 'textareas';
130 $init['theme'] = $theme_name;
131 $init['document_base_url'] = "$base_url/";
133 // Merge and overrivide user-defined TinyMCE settings.
134 $init = array_merge($init, (array) theme('tinymce_theme', $init, $textarea_name, $theme_name, $is_running));
135 foreach ($init as
$k => $v) {
136 $settings[] = $k.
' : "'.
$v.
'"';
138 $tinymce_settings = implode(",\n", $settings);
141 <script language
="javascript" type
="text/javascript">
148 // We only invoke TinyMCE once per request, not once per textarea. We could
149 // do this check earlier in the conditional, but it's probably wise to let
150 // the themed functions know what's going on.
159 * Implementation of hook_user().
161 function tinymce_user($type, &$edit, &$user, $category = NULL
) {
162 if ($type == 'form' && $category == 'account' && user_access('access tinymce')) {
163 $user_status = $edit['tinymce_status'] != NULL ?
$edit['tinymce_status'] : ($user->tinymce_status
!= NULL ?
$user->tinymce_status
: 1);
164 $form = form_radios(t('Status'), 'tinymce_status', $user_status, array(t('Disabled'), t('Enabled')), t('Would you like to enable rich-text editing of your content?'));
165 if ($user_status && user_access('choose own tinymce theme')) {
166 $form .
= form_radios(t('Default theme'), 'tinymce_theme', $edit['tinymce_theme'] ?
$edit['tinymce_theme'] : variable_get('tinymce_theme', 'simple'), _tinymce_get_themes());
168 return array(array('title' => t('TinyMCE settings'), 'data' => $form));
170 if ($type == 'validate') {
171 return array('tinymce_theme' => $edit['tinymce_theme'], 'tinymce_status' => $edit['tinymce_status']);
176 * @addtogroup themeable
181 * Customize a TinyMCE theme.
184 * An array of settings TinyMCE should invoke a theme. You may override any
185 * of the TinyMCE settings. Details here:
187 * http://tinymce.moxiecode.com/wrapper.php?url=tinymce/docs/using.htm
189 * @param textarea_name
190 * The name of the textarea TinyMCE wants to enable.
193 * The default theme name to be enabled for this textarea. The sitewide
194 * default is 'simple', but the user may also override this.
197 * A boolean flag that identifies id TinyMCE is currently running for this
198 * request life cycle. If it's already running then anything returned by this
199 * will be ignored. This is necessary since TinyMCE works by being invoked
200 * once per request and not once per textarea.
202 function theme_tinymce_theme($init, $textarea_name, $theme_name, $is_running) {
203 switch ($theme_name) {
205 $init['extended_valid_elements'] = 'a[href|target|name]';
206 $init['theme_advanced_buttons3_add_before'] = 'tablecontrols,separator';
207 $init['plugins'] = 'drupalimage,table,emotions,iespell,print';
208 $init['theme_advanced_buttons3_add'] = 'emotions,iespell,separator,print';
213 /** @} End of addtogroup themeable */
216 * Grab the themes available to TinyMCE.
218 * TinyMCE themes control the functionality and buttons that are available to a
219 * user. Themes are only looked for within the default TinyMCE theme directory.
222 * An array of theme names.
224 function _tinymce_get_themes() {
225 static
$themes = array();
228 $theme_loc = drupal_get_path('module', 'tinymce') .
'/tinymce/jscripts/tiny_mce/themes/';
229 if (is_dir($theme_loc) && $dh = opendir($theme_loc)) {
230 while (($file = readdir($dh)) !== false
) {
231 if (!in_array($file, array('.', '..', 'CVS')) && is_dir($theme_loc .
$file)) {
232 $themes[$file] = $file;
244 * Determine if TinyMCE can render the current page.
247 * TRUE if can render, FALSE if not allowed.
249 function _tinymce_page_match() {
250 $edit = $_POST['edit'];
252 //Kill TinyMCE if we're editing a textarea with PHP in it!
254 if ($edit['format'] == 2) {
259 // PHP input formats are #2 in the filters table.
260 preg_match("|^node/(\d+)(/edit)$|", $_GET['q'], $match);
261 if (intval($match[1]) > 0) {
262 if (db_result(db_query('SELECT format FROM {node} WHERE nid = %d AND format = 2', $match[1]))) {
268 if (variable_get('tinymce_all', 1)) {
273 $pages = variable_get('tinymce_pages', tinymce_help('admin/settings/tinymce#pages'));
275 $path = drupal_get_path_alias($_GET['q']);
276 $regexp = '/^('.
preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/', '/(^|\|)\\\\<front\\\\>($|\|)/'), array('|', '.*', '\1'.
variable_get('site_frontpage', 'node') .
'\2'), preg_quote($pages, '/')) .
')$/';
277 $page_match = preg_match($regexp, $path);