README.txt | 77 +++++++++++++++++++++++++ aloha.module | 91 +++++++++++++++++++++--------- aloha/drupal/lib/drupal-plugin.js | 21 ++++--- aloha/drupal/lib/drupalcontenthandler.js | 24 +++++--- js/drupal.aloha.edit.js | 4 +- js/drupal.aloha.js | 38 +++++++++---- js/drupal.aloha.textarea.js | 27 +++------ 7 files changed, 209 insertions(+), 73 deletions(-) diff --git a/README.txt b/README.txt index ad30e45..91f8176 100644 --- a/README.txt +++ b/README.txt @@ -57,6 +57,83 @@ Loading Aloha Editor plug-ins 5) For more details, see the ASCII diagram and aloha_library(). +An example for all of this: the Caption module. + + +Configuring Aloha Editor plug-ins +--------------------------------- + +Aloha Editor plug-in settings/configuration typically live in + + Aloha.settings.plugins.pluginName + +Everything in Drupal.settings.aloha.settings will be copied to Aloha.settings, +this is done by Drupal.aloha.init(), just before Aloha Editor is initialized. + +In PHP, that can be done like this: + + $form['some textarea with processed text']['#attached']['js'][] = array( + 'type' => 'setting', + 'data' => array('aloha' => array('settings' => array('plugins' => array( + 'pluginName' => array( + 'foo' => 'bar' + ), + )))), + ); + + +Activating/configuring Aloha Editor plug-ins based on text format +----------------------------------------------------------------- + +If you need your Aloha Editor plug-in to be disabled entirely for text format X +or to have different settings for text format Y, that is supported as well. + +For Aloha Editor plug-ins that support this, you can then configure them like +this: + + Drupal.settings.aloha.settings.plugins.pluginName.editables['.text-format-filtered-html'] = { + status: true, + }; + Drupal.settings.aloha.settings.plugins.pluginName.editables['.text-format-full-html'] = { + status: false, + }; + +In PHP, that can be done like this: + + $form['some textarea with processed text']['#attached']['js'][] = array( + 'type' => 'setting', + 'data' => array('aloha' => array('settings' => array('plugins' => array( + 'pluginName' => array( + 'editables' => array( + '.text-format-filtered-html' => array( + 'status' => TRUE, + ), + '.text-format-full-html' => array( + 'status' => FALSE, + ), + ), + ), + )))), + ); + +You'll want your Aloha Editor plug-in to consume settings like the common/format +plug-in does: http://aloha-editor.org/guides/plugins.html#configure-plugins. +Examples for all this: Aloha Editor's sanitizeContentHandler.js and the "drupal" +plug-in that is included with the Aloha module. +@todo: This is currently rather painful to implement in Aloha Editor plug-ins, +but we're aiming to make it trivial, please see http://drupal.org/node/1786550. + + +Dynamically overriding Aloha.settings +------------------------------------- + +Every piece of JavaScript also has the opportunity to modify Aloha.settings +dynamically, just do something like this: + + $(document).bind('aloha-before-init', function (e, alohaSettings) { + alohaSettings.foo = 'bar'; + }); + The Aloha Editor dependency chain --------------------------------- diff --git a/aloha.module b/aloha.module index 1c34aa2..e0af787 100644 --- a/aloha.module +++ b/aloha.module @@ -385,37 +385,13 @@ function aloha_pre_render_text_format($element) { $format_field = &$element['format']; $field = &$element['value']; - $settings = array( - 'field' => $field['#id'], - ); - - $format_id = $field['#format']; - - // Gather all necessary metadata for all available formats for this field. - // @todo This needs to be provided by the filter system. - // @see http://drupal.org/node/1782838 - foreach ($format_field['format']['#options'] as $format_id => $format_name) { - $filter_types = filter_get_filter_types_by_format($format_id); - $allowed_tags = filter_get_allowed_tags_by_format($format_id); - $no_disallowed_tags = $allowed_tags === TRUE; - $necessary_tags_allowed = $no_disallowed_tags || (in_array('br', $allowed_tags) && in_array('p', $allowed_tags)); - $settings[$format_id] = array( - // Aloha Editor should only be enabled if no "HTML generator" filters are - // used in this format, and the
and

tags are allowed. - 'status' => !in_array(FILTER_TYPE_HTML_GENERATOR, $filter_types) - && $necessary_tags_allowed, - // Let Aloha Editor know which tags are allowed; it will reconfigure its - // UI to match that. - 'allowedTags' => implode(',', $no_disallowed_tags ? array() : $allowed_tags), - ); - } // Use a hidden element for a single text format. if (!$format_field['format']['#access']) { $format_field['aloha'] = array( '#type' => 'hidden', '#name' => $format_field['format']['#name'], - '#value' => $format_id, + '#value' => $field['#format'], '#attributes' => array( 'id' => $format_field['format']['#id'], 'class' => array('aloha-formatselector-for-textarea'), @@ -428,10 +404,13 @@ function aloha_pre_render_text_format($element) { array( 'type' => 'setting', 'data' => array('aloha' => array('textareas' => array( - $format_field['format']['#id'] => $settings + $format_field['format']['#id'] => $field['#id'], ))), ), ), + 'aloha_add_format_settings' => array( + array() + ), ), ); } @@ -442,15 +421,73 @@ function aloha_pre_render_text_format($element) { $format_field['format']['#attached']['js'][] = array( 'type' => 'setting', 'data' => array('aloha' => array('textareas' => array( - $format_field['format']['#id'] => $settings + $format_field['format']['#id'] => $field['#id'], ))), ); + $format_field['format']['#attached']['aloha_add_format_settings'][] = array(); } return $element; } /** + * Adds Drupal.settings.aloha.formats and Aloha.settings.plugins.drupal. Ensures + * Aloha Editor has the metadata to deal with formats. + */ +function aloha_add_format_settings() { + $format_settings_added = &drupal_static(__FUNCTION__, FALSE); + + if (!$format_settings_added) { + global $user; + $formats = filter_formats($user); + + $settings['formats'] = array(); + $settings['settings']['plugins']['drupal'] = array(); + + // Gather all necessary metadata for each format available to the current + // user. + // @todo filter_get_filter_types_by_format() and filter_get_allowed_tags_by_format() + // are provided by http://drupal.org/node/1782838 + foreach (array_keys($formats) as $format_id) { + $filter_types = filter_get_filter_types_by_format($format_id); + $allowed_tags = filter_get_allowed_tags_by_format($format_id); + $no_disallowed_tags = $allowed_tags === TRUE; + $necessary_tags_allowed = $no_disallowed_tags || (in_array('br', $allowed_tags) && in_array('p', $allowed_tags)); + $class = 'text-format-' . drupal_html_class($format_id); + $settings['formats'][$format_id] = array( + 'id' => $format_id, + // Aloha Editor should only be enabled if no "HTML generator" filters + // are used in this format, and the
and

tags are allowed. + 'status' => !in_array(FILTER_TYPE_HTML_GENERATOR, $filter_types) + && $necessary_tags_allowed, + // The class that will be set on the editable whenever this text format + // is active. + 'className' => $class, + ); + + // For Aloha Editor to make sense in a Drupal context, we need to make + // sure that Aloha Editor works as well as possible with Drupal's filter + // system. Hence we developed the 'drupal' plug-in for Aloha Editor, which + // is able to adjust the UI and filter pasting based on the allowed tags + // of the current text format of the current editable. + // Whenever we use Aloha Editor within Drupal, it's in + // e.g. if the tag is disallowed, it won't show the "I" button and + // pasted italic text will automatically be unitalicized. + // @todo: make this plug-in obsolete: http://drupal.org/node/1806492 + if ($settings['formats'][$format_id]['status']) { + $settings['settings']['plugins']['drupal']['editables'][".$class"] = array( + 'allowedTags' => $no_disallowed_tags ? array() : $allowed_tags, + ); + } + } + + drupal_add_js(array('aloha' => $settings), array('type' => 'setting')); + + $format_settings_added = TRUE; + } +} + +/** * Helper function to create Aloha.settings entries for Aloha Editor plug-ins * that are defined in hook_library() as libraries. * diff --git a/aloha/drupal/lib/drupal-plugin.js b/aloha/drupal/lib/drupal-plugin.js index 9ee8eab..b712006 100644 --- a/aloha/drupal/lib/drupal-plugin.js +++ b/aloha/drupal/lib/drupal-plugin.js @@ -56,14 +56,21 @@ define([ ContentHandlerManager.register('drupal', DrupalContentHandler); Aloha.bind('aloha-editable-activated', function ($event, params) { - var element; - var allowedTagsList = Aloha.activeEditable.originalObj - .closest('[data-allowed-tags]') - .attr('data-allowed-tags'); + var config, element, i; + var drupalConfig = Aloha.settings.plugins.drupal.editables; + var classes = Aloha.activeEditable.originalObj.attr('class').split(' '); + for (i = 0; i < classes.length; i++) { + if (typeof drupalConfig['.' + classes[i]] !== 'undefined') { + config = drupalConfig['.' + classes[i]]; + } + } - if (allowedTagsList) { - allowedTags = allowedTagsList.split(','); + if (typeof config === 'undefined') { + config = { allowedTags: [] }; + } + var allowedTags = config.allowedTags; + if (allowedTags.length) { for (element in elementMapping) { if (elementMapping.hasOwnProperty(element) && $.inArray(element, allowedTags) === -1) { $('span.ui-button-icon-primary[data-html-tag="' + elementMapping[element] + '"]') @@ -74,7 +81,7 @@ define([ } // Always hide the elements that are not allowed. - for (var i = 0; i < neverAllowedElements.length; i++) { + for (i = 0; i < neverAllowedElements.length; i++) { element = neverAllowedElements[i]; var tag = elementMapping[element]; $('span.ui-button-icon-primary[data-html-tag="' + tag + '"]') diff --git a/aloha/drupal/lib/drupalcontenthandler.js b/aloha/drupal/lib/drupalcontenthandler.js index 5f7c2f8..84be24f 100644 --- a/aloha/drupal/lib/drupalcontenthandler.js +++ b/aloha/drupal/lib/drupalcontenthandler.js @@ -44,20 +44,28 @@ define([ * @param content */ handleContent: function (content) { - var config; + var config, i; // sanitize does not work in IE7. It tries to set the style attribute via setAttributeNode() and this is know to not work in IE7 // (see http://www.it-blogger.com/2007-06-22/microsofts-internetexplorer-und-mitglied-nicht-gefunden/ as a reference) if ($.browser.msie && $.browser.version <= 7) { return content; } - // dynamic allowed tags drupal sprint - var allowedTags = Aloha.activeEditable.originalObj - .closest('[data-allowed-tags]') - .attr('data-allowed-tags'); - if (allowedTags) { - var allows = allowedTags.split(','); - sanitize = new Sanitize({elements: allows}); + var drupalConfig = Aloha.settings.plugins.drupal.editables; + var classes = Aloha.activeEditable.originalObj.attr('class').split(' '); + for (i = 0; i < classes.length; i++) { + if (typeof drupalConfig['.' + classes[i]] !== 'undefined') { + config = drupalConfig['.' + classes[i]]; + } + } + + if (typeof config === 'undefined') { + config = { allowedTags: [] }; + } + + var allowedTags = config.allowedTags; + if (allowedTags.length) { + sanitize = new Sanitize({elements: allowedTags}); } else if (typeof sanitize === 'undefined') { config = this.setting.basic; diff --git a/js/drupal.aloha.edit.js b/js/drupal.aloha.edit.js index 9033131..880aa1a 100644 --- a/js/drupal.aloha.edit.js +++ b/js/drupal.aloha.edit.js @@ -17,8 +17,8 @@ Drupal.edit.wysiwyg.aloha = { }); }, - attach: function ($editable) { - Drupal.aloha.attach($editable, false); + attach: function ($editable, format) { + Drupal.aloha.attach($editable, format); $editable.bind('aloha-content-changed', function() { $editable.trigger('edit-wysiwyg-content-changed'); }); diff --git a/js/drupal.aloha.js b/js/drupal.aloha.js index 27c7dd1..c159ae3 100644 --- a/js/drupal.aloha.js +++ b/js/drupal.aloha.js @@ -80,23 +80,19 @@ Drupal.aloha = { * The editable to which Aloha Editor should be applied. Can be a