edit.module | 53 +++-- edit_aloha/edit_aloha.module | 8 +- lib/Drupal/edit/Tests/EditorSelectionTest.php | 224 ++++++++++++++++++++ tests/modules/edit_test.info | 6 + tests/modules/edit_test.module | 6 + .../processed_text_editor/TestProcessedEditor.php | 31 +++ 7 files changed, 304 insertions(+), 24 deletions(-) diff --git a/edit.module b/edit.module index 8740388..91dea8e 100644 --- a/edit.module +++ b/edit.module @@ -118,36 +118,40 @@ function edit_toolbar() { */ function edit_library_info() { $path = drupal_get_path('module', 'edit'); + $options = array( + 'scope' => 'footer', + 'attributes' => array('defer' => TRUE), + ); $libraries['edit'] = array( 'title' => 'Edit: in-place editing', 'website' => 'http://drupal.org/project/edit', 'version' => VERSION, 'js' => array( // Core. - $path . '/js/edit.js' => array('defer' => TRUE), - $path . '/js/app.js' => array('defer' => TRUE), + $path . '/js/edit.js' => $options, + $path . '/js/app.js' => $options, // Routers. - $path . '/js/routers/edit-router.js' => array('defer' => TRUE), + $path . '/js/routers/edit-router.js' => $options, // Models. - $path . '/js/models/edit-app-model.js' => array('defer' => TRUE), + $path . '/js/models/edit-app-model.js' => $options, // Views. - $path . '/js/views/propertyeditordecoration-view.js' => array('defer' => TRUE), - $path . '/js/views/menu-view.js' => array('defer' => TRUE), - $path . '/js/views/modal-view.js' => array('defer' => TRUE), - $path . '/js/views/overlay-view.js' => array('defer' => TRUE), - $path . '/js/views/toolbar-view.js' => array('defer' => TRUE), + $path . '/js/views/propertyeditordecoration-view.js' => $options, + $path . '/js/views/menu-view.js' => $options, + $path . '/js/views/modal-view.js' => $options, + $path . '/js/views/overlay-view.js' => $options, + $path . '/js/views/toolbar-view.js' => $options, // Backbone.sync implementation on top of Drupal forms. - $path . '/js/backbone.drupalform.js' => array('defer' => TRUE), + $path . '/js/backbone.drupalform.js' => $options, // VIE service. - $path . '/js/viejs/EditService.js' => array('defer' => TRUE), + $path . '/js/viejs/EditService.js' => $options, // Create.js subclasses. - $path . '/js/createjs/editable.js' => array('defer' => TRUE), - $path . '/js/createjs/storage.js' => array('defer' => TRUE), - $path . '/js/createjs/editingWidgets/formwidget.js' => array('defer' => TRUE), - $path . '/js/createjs/editingWidgets/drupalcontenteditablewidget.js' => array('defer' => TRUE), + $path . '/js/createjs/editable.js' => $options, + $path . '/js/createjs/storage.js' => $options, + $path . '/js/createjs/editingWidgets/formwidget.js' => $options, + $path . '/js/createjs/editingWidgets/drupalcontenteditablewidget.js' => $options, // Other. - $path . '/js/util.js' => array('defer' => TRUE), - $path . '/js/theme.js' => array('defer' => TRUE), + $path . '/js/util.js' => $options, + $path . '/js/theme.js' => $options, // Basic settings. array( 'data' => array('edit' => array( @@ -159,7 +163,7 @@ function edit_library_info() { ), ), 'css' => array( - $path . '/css/edit.css', + $path . '/css/edit.css' => array(), ), 'dependencies' => array( array('system', 'jquery'), @@ -366,13 +370,18 @@ function _edit_wysiwyg_get_field_editor($format_id = NULL) { // Only load the WYSIWYG editor's JavaScript if it hasn't been already. if ($wysiwyg_plugin->settingsAdded === FALSE) { $definition = $wysiwyg_plugin->getDefinition(); - drupal_add_library($definition['library']['module'], $definition['library']['name']); + if (!empty($definition['library'])) { + drupal_add_library($definition['library']['module'], $definition['library']['name']); + } $wysiwyg_plugin->addJsSettings(); // Let Create.js know which WYSIWYG editor widget it should use. - drupal_add_js(array('edit' => array( - 'wysiwygEditorWidgetName' => $definition['propertyEditorName'], - )), 'setting'); + if (!empty($definition['propertyEditorName'])) { + drupal_add_js(array('edit' => array( + 'wysiwygEditorWidgetName' => $definition['propertyEditorName'], + )), 'setting'); + } + $wysiwyg_plugin->settingsAdded = TRUE; } return 'direct-with-wysiwyg'; diff --git a/edit_aloha/edit_aloha.module b/edit_aloha/edit_aloha.module index 865bcb0..077c3f9 100644 --- a/edit_aloha/edit_aloha.module +++ b/edit_aloha/edit_aloha.module @@ -12,14 +12,18 @@ */ function edit_aloha_library_info() { $module_path = drupal_get_path('module', 'edit_aloha'); + $options = array( + 'scope' => 'footer', + 'attributes' => array('defer' => TRUE), + ); $libraries['aloha.edit'] = array( 'title' => 'Integrate Aloha Editor with the Edit module.', 'version' => ALOHA_VERSION, 'js' => array( - $module_path . '/js/createjs/drupalalohawidget.js' => array('defer' => TRUE), + $module_path . '/js/createjs/drupalalohawidget.js' => $options, ), 'css' => array( - $module_path . '/css/drupal.aloha.edit.css', + $module_path . '/css/drupal.aloha.edit.css' => array(), ), 'dependencies' => array( array('aloha', 'aloha'), diff --git a/lib/Drupal/edit/Tests/EditorSelectionTest.php b/lib/Drupal/edit/Tests/EditorSelectionTest.php new file mode 100644 index 0000000..cb09706 --- /dev/null +++ b/lib/Drupal/edit/Tests/EditorSelectionTest.php @@ -0,0 +1,224 @@ + 'In-place field editor selection', + 'description' => 'Tests in-place field editor selection.', + 'group' => 'Edit', + ); + } + + /** + * Sets the default field storage backend for fields created during tests. + */ + function setUp() { + parent::setUp(); + + $this->installSchema('system', 'variable'); + $this->enableModules(array('field', 'field_sql_storage', 'field_test')); + + // Set default storage backend. + variable_set('field_storage_default', $this->default_storage); + } + + /** + * Creates a field and an instance of it. + * + * @param string $field_name + * The field name. + * @param string $type + * The field type. + * @param int $cardinality + * The field's cardinality. + * @param string $label + * The field's label (used everywhere: widget label, formatter label). + * @param array $instance_settings + * @param string $widget_type + * The widget type. + * @param array $widget_settings + * The widget settings. + * @param string $formatter_type + * The formatter type. + * @param array $formatter_settings + * The formatter settings. + */ + function createFieldWithInstance($field_name, $type, $cardinality, $label, $instance_settings, $widget_type, $widget_settings, $formatter_type, $formatter_settings) { + $field = $field_name . '_field'; + $this->$field = array( + 'field_name' => $field_name, + 'type' => $type, + 'cardinality' => $cardinality, + ); + $this->$field_name = field_create_field($this->$field); + + $instance = $field_name . '_instance'; + $this->$instance = array( + 'field_name' => $field_name, + 'entity_type' => 'test_entity', + 'bundle' => 'test_bundle', + 'label' => $label, + 'description' => $label, + 'weight' => mt_rand(0, 127), + 'settings' => $instance_settings, + 'widget' => array( + 'type' => $widget_type, + 'label' => $label, + 'settings' => $widget_settings, + ), + 'display' => array( + 'default' => array( + 'label' => 'above', + 'type' => $formatter_type, + 'settings' => $formatter_settings + ), + ), + ); + field_create_instance($this->$instance); + } + + /** + * Retrieves the FieldInstance object for the given field and returns the + * editor that Edit selects. + */ + function getSelectedEditor($items, $field_name, $display = 'default') { + $field_instance = field_info_instance('test_entity', $field_name, 'test_bundle'); + return _edit_get_field_editor($items, $field_instance, $field_instance['display'][$display]['type']); + } + + /** + * Tests a textual field, without/with text processing, with cardinality 1 and + * >1, always without a WYSIWYG editor present. + */ + function testText() { + $field_name = 'field_text'; + $this->createFieldWithInstance( + $field_name, 'text', 1, 'Simple text field', + // Instance settings. + array('text_processing' => 0), + // Widget type & settings. + 'text_textfield', + array('size' => 42), + // 'default' formatter type & settings. + 'text_default', + array() + ); + + // Pretend there is an entity with these items for the field. + $items = array(array('value' => 'Hello, world!', 'format' => 'full_html')); + + // Editor selection without text processing, with cardinality 1. + $this->assertEqual('direct', $this->getSelectedEditor($items, $field_name), "Without text processing, cardinality 1, the 'direct' editor is selected."); + + // Editor selection with text processing, cardinality 1. + $this->field_text_instance['settings']['text_processing'] = 1; + field_update_instance($this->field_text_instance); + $this->assertEqual('form', $this->getSelectedEditor($items, $field_name), "With text processing, cardinality 1, the 'form' editor is selected."); + + // Editor selection without text processing, cardinality 1 (again). + $this->field_text_instance['settings']['text_processing'] = 0; + field_update_instance($this->field_text_instance); + $this->assertEqual('direct', $this->getSelectedEditor($items, $field_name), "Without text processing again, cardinality 1, the 'direct' editor is selected."); + + // Editor selection without text processing, cardinality >1 + $this->field_text_field['cardinality'] = 2; + field_update_field($this->field_text_field); + $items[] = array('value' => 'Hallo, wereld!', 'format' => 'full_html'); + $this->assertEqual('form', $this->getSelectedEditor($items, $field_name), "Without text processing, cardinality >1, the 'form' editor is selected."); + + // Editor selection with text processing, cardinality >1 + $this->field_text_instance['settings']['text_processing'] = 1; + field_update_instance($this->field_text_instance); + $this->assertEqual('form', $this->getSelectedEditor($items, $field_name), "With text processing, cardinality >1, the 'form' editor is selected."); + } + + /** + * Tests a textual field, with text processing, with cardinality 1 and >1, + * always with a ProcessedTextEditor plug-in present, but with varying text + * format compatibility. + */ + function testTextWysiwyg() { + $field_name = 'field_textarea'; + $this->createFieldWithInstance( + $field_name, 'text', 1, 'Long text field', + // Instance settings. + array('text_processing' => 1), + // Widget type & settings. + 'text_textarea', + array('size' => 42), + // 'default' formatter type & settings. + 'text_default', + array() + ); + + // ProcessedTextEditor plug-in compatible with the full_html text format. + state()->set('edit_test.compatible_format', 'full_html'); + + // Pretend there is an entity with these items for the field. + $items = array(array('value' => 'Hello, world!', 'format' => 'filtered_html')); + + // Editor selection with cardinality 1, without compatible text format. + $this->assertEqual('form', $this->getSelectedEditor($items, $field_name), "Without cardinality 1, and the filtered_html text format, the 'form' editor is selected."); + + // Editor selection with cardinality 1, with compatible text format. + $items[0]['format'] = 'full_html'; + $this->assertEqual('direct-with-wysiwyg', $this->getSelectedEditor($items, $field_name), "With cardinality 1, and the full_html text format, the 'direct-with-wysiwyg' editor is selected."); + + // Editor selection with text processing, cardinality >1 + $this->field_textarea_field['cardinality'] = 2; + field_update_field($this->field_textarea_field); + $items[] = array('value' => 'Hallo, wereld!', 'format' => 'full_html'); + $this->assertEqual('form', $this->getSelectedEditor($items, $field_name), "With cardinality >1, and both items using the full_html text format, the 'form' editor is selected."); + } + + /** + * Tests a number field, with cardinality 1 and >1. + */ + function testNumber() { + $field_name = 'field_nr'; + $this->createFieldWithInstance( + $field_name, 'number_integer', 1, 'Simple number field', + // Instance settings. + array(), + // Widget type & settings. + 'number', + array(), + // 'default' formatter type & settings. + 'number_integer', + array() + ); + + // Pretend there is an entity with these items for the field. + $items = array(42, 43); + + // Editor selection with cardinality 1. + $this->assertEqual('form', $this->getSelectedEditor($items, $field_name), "With cardinality 1, the 'form' editor is selected."); + + // Editor selection with cardinality >1. + $this->field_nr_field['cardinality'] = 2; + field_update_field($this->field_nr_field); + $this->assertEqual('form', $this->getSelectedEditor($items, $field_name), "With cardinality >1, the 'form' editor is selected."); + } + +} diff --git a/tests/modules/edit_test.info b/tests/modules/edit_test.info new file mode 100644 index 0000000..4df4a3f --- /dev/null +++ b/tests/modules/edit_test.info @@ -0,0 +1,6 @@ +name = Edit test +description = Support module for the Edit module tests. +core = 8.x +package = Testing +version = VERSION +hidden = TRUE diff --git a/tests/modules/edit_test.module b/tests/modules/edit_test.module new file mode 100644 index 0000000..d74528d --- /dev/null +++ b/tests/modules/edit_test.module @@ -0,0 +1,6 @@ +get('edit_test.compatible_format') == $format_id; + } + +}