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