Index: wysiwyg.init.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wysiwyg/wysiwyg.init.js,v
retrieving revision 1.1
diff -u -p -r1.1 wysiwyg.init.js
--- wysiwyg.init.js 11 Oct 2008 19:54:24 -0000 1.1
+++ wysiwyg.init.js 12 Oct 2008 02:58:19 -0000
@@ -1,8 +1,8 @@
// $Id: wysiwyg.init.js,v 1.1 2008/10/11 19:54:24 sun Exp $
-Drupal.wysiwyg = Drupal.wysiwyg || {};
+Drupal.wysiwyg = Drupal.wysiwyg || { 'invoke': {} };
-Drupal.wysiwyg.editor = Drupal.wysiwyg.editor || { 'init': {}, 'attach': {}, 'detach': {} };
+Drupal.wysiwyg.editor = Drupal.wysiwyg.editor || { 'init': {}, 'attach': {}, 'detach': {}, 'invoke': {} };
Drupal.wysiwyg.plugins = Drupal.wysiwyg.plugins || {};
Index: wysiwyg_editor.admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wysiwyg/wysiwyg_editor.admin.inc,v
retrieving revision 1.18
diff -u -p -r1.18 wysiwyg_editor.admin.inc
--- wysiwyg_editor.admin.inc 10 Oct 2008 21:57:09 -0000 1.18
+++ wysiwyg_editor.admin.inc 12 Oct 2008 17:56:43 -0000
@@ -180,14 +180,16 @@ function wysiwyg_editor_profile_form($fo
foreach ($plugins as $name => $meta) {
if (isset($meta['buttons']) && is_array($meta['buttons'])) {
foreach ($meta['buttons'] as $button => $title) {
- // @todo Button icon locations are different in editors, editor versions,
- // and contrib/custom plugins (like Image Assist, f.e.).
- $img_src = $meta['path'] ."/images/$name.gif";
- // Handle plugins that have more than one button.
- if (!file_exists($img_src)) {
- $img_src = $meta['path'] ."/images/$button.gif";
+ if (!empty($meta['path'])) {
+ // @todo Button icon locations are different in editors, editor versions,
+ // and contrib/custom plugins (like Image Assist, f.e.).
+ $img_src = $meta['path'] ."/images/$name.gif";
+ // Handle plugins that have more than one button.
+ if (!file_exists($img_src)) {
+ $img_src = $meta['path'] ."/images/$button.gif";
+ }
+ $icon = file_exists($img_src) ? '' : '';
}
- $icon = file_exists($img_src) ? '
' : '';
$title = (isset($meta['url']) ? l($title, $meta['url'], array('target' => '_blank')) : $title);
$title = (!empty($icon) ? $icon .' '. $title : $title);
$form['buttons'][$name][$button] = array(
Index: wysiwyg_editor.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wysiwyg/wysiwyg_editor.js,v
retrieving revision 1.9
diff -u -p -r1.9 wysiwyg_editor.js
--- wysiwyg_editor.js 11 Oct 2008 19:54:24 -0000 1.9
+++ wysiwyg_editor.js 12 Oct 2008 17:42:00 -0000
@@ -81,6 +81,13 @@ Drupal.wysiwygAttach = function(context,
if (typeof Drupal.wysiwyg.editor.attach[params.editor] == 'function') {
// Attach editor.
Drupal.wysiwyg.editor.attach[params.editor](context, params, Drupal.wysiwyg.clone(Drupal.settings.wysiwygEditor.configs[params.editor]));
+ // Provide editor callbacks for plugins.
+ Drupal.wysiwyg.invoke = {};
+ if (typeof Drupal.wysiwyg.editor.invoke[params.editor] == 'object') {
+ Drupal.wysiwyg.invoke = Drupal.wysiwyg.editor.invoke[params.editor];
+ }
+ // Store this editor id, so (external) plugins can use it.
+ Drupal.wysiwyg.activeId = params.field;
// Display toggle link.
$('#wysiwyg-toggle-' + params.field).show();
}
@@ -125,6 +132,7 @@ Drupal.wysiwygEditorAttachToggleLink = f
$('#wysiwyg-toggle-' + params.field).html(Drupal.settings.wysiwygEditor.enable).blur();
// After disabling the editor, re-attach default behaviors.
Drupal.wysiwyg.editor.attach.none(context, params);
+ Drupal.wysiwyg.invoke = Drupal.wysiwyg.editor.invoke.none;
},
function() {
// Before enabling the editor, detach default behaviors.
Index: wysiwyg_editor.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wysiwyg/wysiwyg_editor.module,v
retrieving revision 1.29
diff -u -p -r1.29 wysiwyg_editor.module
--- wysiwyg_editor.module 11 Oct 2008 19:54:24 -0000 1.29
+++ wysiwyg_editor.module 12 Oct 2008 02:58:19 -0000
@@ -160,10 +160,10 @@ function wysiwyg_process_form(&$form) {
// Check editor theme (and reset it if not/no longer available).
$theme = wysiwyg_editor_get_themes($profile, $field['#wysiwyg_style']);
+ // Add plugin settings (first) for this input format.
+ wysiwyg_editor_add_plugin_settings($profile);
// Add profile settings for this input format.
wysiwyg_editor_add_settings($profile, $theme);
- // Add plugin settings for this input format.
- wysiwyg_editor_add_plugin_settings($profile);
$theme = ' wysiwyg-theme-'. $theme;
}
@@ -362,6 +362,13 @@ function wysiwyg_editor_add_plugin_setti
$plugins = array();
$editor = wysiwyg_get_editor($profile->settings['editor']);
$info = module_invoke_all('wysiwyg_plugin', $editor['name'], $editor['installed version']);
+ if (isset($editor['proxy plugin'])) {
+ $info += $editor['proxy plugin'];
+ $contrib_plugins = wysiwyg_get_all_plugins();
+ foreach ($contrib_plugins as $plugin_name => $meta) {
+ $info['drupal']['buttons'][$plugin_name] = $meta;
+ }
+ }
// Only keep enabled plugins in this profile.
foreach ($info as $plugin => $meta) {
if (!isset($profile->settings['buttons'][$plugin])) {
@@ -436,9 +443,16 @@ function wysiwyg_editor_get_plugins($edi
$plugins = $editor['plugin callback']($editor);
}
// Load our own plugins.
- include_once drupal_get_path('module', 'wysiwyg_editor') .'/wysiwyg_editor.plugins.inc';
+ #include_once drupal_get_path('module', 'wysiwyg_editor') .'/wysiwyg_editor.plugins.inc';
- $plugins = array_merge($plugins, module_invoke_all('wysiwyg_plugin', $editor['name'], $editor['installed version']));
+ #$plugins = array_merge($plugins, module_invoke_all('wysiwyg_plugin', $editor['name'], $editor['installed version']));
+ if (isset($editor['proxy plugin'])) {
+ $plugins += $editor['proxy plugin'];
+ $contrib_plugins = wysiwyg_get_all_plugins();
+ foreach ($contrib_plugins as $plugin_name => $info) {
+ $plugins['drupal']['buttons'][$plugin_name] = $info['title'];
+ }
+ }
}
return $plugins;
}
@@ -640,6 +654,42 @@ function wysiwyg_get_all_editors() {
}
/**
+ * Invoke hook_wysiwyg_plugin() in all modules.
+ */
+function wysiwyg_get_all_plugins() {
+ static $plugins;
+
+ if (isset($plugins)) {
+ return $plugins;
+ }
+
+ $plugins = wysiwyg_load_includes('plugins', 'plugin');
+ foreach ($plugins as $name => $properties) {
+ $plugin = &$plugins[$name];
+ // Fill in required properties.
+ $plugin += array(
+ 'title' => $plugin['name'],
+ 'vendor url' => '',
+ 'js path' => $plugin['path'] . '/' . $plugin['name'],
+ 'js file' => $plugin['name'] . '.js',
+ 'css path' => $plugin['path'] . '/' . $plugin['name'],
+ 'css file' => $plugin['name'] . '.css',
+ 'icon path' => $plugin['path'] . '/' . $plugin['name'] . '/images',
+ 'icon file' => $plugin['name'] . '.png',
+ 'dialog path' => $plugin['name'],
+ 'dialog settings' => array(),
+ 'settings callback' => NULL,
+ 'settings form callback' => NULL,
+ );
+ // Check whether library is present.
+ if (!($plugin['installed'] = file_exists($plugin['js path'] . '/' . $plugin['js file']))) {
+ continue;
+ }
+ }
+ return $plugins;
+}
+
+/**
* Load include files for wysiwyg implemented by all modules.
*
* @param $type
Index: editors/tinymce.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wysiwyg/editors/tinymce.inc,v
retrieving revision 1.5
diff -u -p -r1.5 tinymce.inc
--- editors/tinymce.inc 11 Oct 2008 22:48:00 -0000 1.5
+++ editors/tinymce.inc 12 Oct 2008 19:53:57 -0000
@@ -38,6 +38,12 @@ function wysiwyg_tinymce_editor() {
// 'include files' => array('tinymce-2.inc'),
'js files' => array('tinymce-2.js'),
'download url' => 'http://sourceforge.net/project/showfiles.php?group_id=103281&package_id=111430&release_id=557383',
+ 'proxy plugin' => array(
+ 'drupal' => array(
+ 'load' => TRUE,
+ 'internal' => TRUE,
+ ),
+ ),
),
'3.2' => array(
// 'include files' => array('tinymce-3.inc'),
@@ -57,6 +63,12 @@ function wysiwyg_tinymce_editor() {
'files' => array('tiny_mce_src.js'),
),
),
+ 'proxy plugin' => array(
+ 'drupal' => array(
+ 'load' => TRUE,
+ 'internal' => TRUE,
+ ),
+ ),
),
),
// Optional properties
@@ -172,7 +184,12 @@ function wysiwyg_tinymce_settings($edito
}
// Add internal buttons that also need to be loaded as extension.
else if ($type == 'buttons' && isset($plugins[$plugin]['load'])) {
- $init['extensions'][$plugin] = 1;
+ if ($plugin == 'drupal') {
+ $init['extensions'][$button] = 1;
+ }
+ else {
+ $init['extensions'][$plugin] = 1;
+ }
}
// Add plain extensions.
else if ($type == 'extensions') {
@@ -266,7 +283,21 @@ function wysiwyg_tinymce_themes($editor,
function wysiwyg_tinymce_plugin_settings($editor, $profile, $info) {
$plugins = array();
foreach ($info as $name => $plugin) {
- if (!isset($plugin['internal'])) {
+ // New API plugins.
+ if ($name == 'drupal') {
+ foreach ($plugin['buttons'] as $plugin_name => $meta) {
+ drupal_add_js($meta['js path'] .'/'. $meta['js file']);
+ $plugins[$plugin_name] = $meta['dialog settings'] + array(
+ 'title' => $meta['title'],
+ 'path' => base_path() . $meta['js path'],
+ 'dialogPath' => base_path() . $meta['dialog path'],
+ 'icon' => base_path() . $meta['icon path'] .'/'. $meta['icon file'],
+ 'iconTitle' => $meta['icon title'],
+ 'css' => base_path() . $meta['css path'] .'/'. $meta['css file'],
+ );
+ }
+ }
+ else if (!isset($plugin['internal'])) {
$plugins[$name] = base_path() . $plugin['path'];
}
}
Index: editors/js/none.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wysiwyg/editors/js/none.js,v
retrieving revision 1.2
diff -u -p -r1.2 none.js
--- editors/js/none.js 11 Oct 2008 19:54:24 -0000 1.2
+++ editors/js/none.js 12 Oct 2008 03:12:53 -0000
@@ -42,3 +42,30 @@ Drupal.wysiwyg.editor.detach.none = func
}
};
+/**
+ * Simple invoke methods for plain text areas.
+ */
+Drupal.wysiwyg.editor.invoke.none = {
+ insert: function(instanceId, content) {
+ var editor = document.getElementById(instanceId);
+
+ // IE support.
+ if (document.selection) {
+ editor.focus();
+ sel = document.selection.createRange();
+ sel.text = content;
+ }
+
+ // Mozilla/Firefox/Netscape 7+ support.
+ else if (editor.selectionStart || editor.selectionStart == '0') {
+ var startPos = editor.selectionStart;
+ var endPos = editor.selectionEnd;
+ editor.value = editor.value.substring(0, startPos) + content + editor.value.substring(endPos, editor.value.length);
+ }
+
+ // Fallback, just add to the end of the content.
+ else {
+ editor.value += content;
+ }
+ }
+};
Index: editors/js/tinymce-2.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wysiwyg/editors/js/tinymce-2.js,v
retrieving revision 1.3
diff -u -p -r1.3 tinymce-2.js
--- editors/js/tinymce-2.js 11 Oct 2008 19:54:24 -0000 1.3
+++ editors/js/tinymce-2.js 12 Oct 2008 21:35:35 -0000
@@ -25,7 +25,12 @@ Drupal.wysiwyg.editor.init.tinymce = fun
}
// @todo Move into global library settings.
for (var plugin in Drupal.settings.wysiwygEditor.plugins.tinymce) {
- tinyMCE.loadPlugin(plugin, Drupal.settings.wysiwygEditor.plugins.tinymce[plugin]);
+ if (typeof Drupal.settings.wysiwygEditor.plugins.tinymce[plugin] == 'string') {
+ tinyMCE.loadPlugin(plugin, Drupal.settings.wysiwygEditor.plugins.tinymce[plugin]);
+ }
+ else if (plugin != 'drupal') {
+ Drupal.wysiwyg.editor.invoke.tinymce.addPlugin(plugin);
+ }
}
};
@@ -61,3 +66,125 @@ Drupal.wysiwyg.editor.detach.tinymce = f
// }
};
+Drupal.wysiwyg.editor.invoke.tinymce = {
+ addPlugin: function(plugin) {
+ var settings = Drupal.settings.wysiwygEditor.plugins.tinymce[plugin];
+
+ // Register plugin.
+ tinyMCE.addPlugin(plugin, {
+
+ // Register an editor command for this plugin, invoked by the plugin's button.
+ execCommand: function(editor_id, element, command, user_interface, value) {
+ switch (command) {
+ case plugin:
+ if (typeof Drupal.wysiwyg.plugins[plugin].invoke == 'function') {
+ var ed = tinyMCE.getInstanceById(editor_id);
+ var data = { format: 'html', node: ed.getFocusElement(), content: ed.getFocusElement() };
+ Drupal.wysiwyg.plugins[plugin].invoke(data, settings, editor_id);
+ return true;
+ }
+ }
+ // Pass to next handler in chain.
+ return false;
+ },
+
+ // Register the plugin button.
+ getControlHTML: function(control_name) {
+ switch (control_name) {
+ case plugin:
+ return tinyMCE.getButtonHTML(control_name, settings.iconTitle, settings.icon, plugin);
+ }
+ return '';
+ },
+
+ // Load custom CSS for editor contents on startup.
+ initInstance: function(ed) {
+ if (settings.css) {
+ tinyMCE.importCSS(ed.getDoc(), settings.css);
+ }
+ },
+
+ cleanup: function(type, content) {
+ switch (type) {
+ case 'insert_to_editor':
+ // Attach: Replace plain text with HTML representations.
+ if (typeof Drupal.wysiwyg.plugins[plugin].attach == 'function') {
+ content = Drupal.wysiwyg.plugins[plugin].attach(content, settings, tinyMCE.selectedInstance.editorId);
+ content = Drupal.wysiwyg.editor.invoke.tinymce.prepareContent(content);
+ }
+ break;
+
+ case 'get_from_editor':
+ // Detach: Replace HTML representations with plain text.
+ if (typeof Drupal.wysiwyg.plugins[plugin].detach == 'function') {
+ content = Drupal.wysiwyg.plugins[plugin].detach(content, settings, tinyMCE.selectedInstance.editorId);
+ }
+ break;
+ }
+ // Pass through to next handler in chain
+ return content;
+ },
+
+ // isNode: Return whether the plugin button should be enabled for the
+ // current selection.
+ handleNodeChange: function(editor_id, node, undo_index, undo_levels, visual_aid, any_selection) {
+ if (node == null) {
+ return;
+ }
+ if (typeof Drupal.wysiwyg.plugins[plugin].isNode == 'function') {
+ if (Drupal.wysiwyg.plugins[plugin].isNode(node)) {
+ tinyMCE.switchClass(editor_id + '_' + plugin, 'mceButtonSelected');
+ return true;
+ }
+ }
+ tinyMCE.switchClass(editor_id + '_' + plugin, 'mceButtonNormal');
+ return true;
+ },
+
+ /**
+ * Return information about the plugin as a name/value array.
+ */
+ getInfo: function() {
+ return { longname: settings.title };
+ }
+ });
+ },
+
+ openDialog: function() {
+ },
+
+ closeDialog: function() {
+ tinyMCEPopup.close();
+ },
+
+ prepareContent: function(content) {
+ // Certain content elements need to have additional DOM properties applied
+ // to prevent this editor from highlighting an internal button in addition
+ // to the button of a Drupal plugin.
+ var specialProperties = {
+ img: { name: 'mce_drupal' }
+ };
+ $content = $('
';
+ }
+};