core/modules/edit/edit.module | 1 - core/modules/edit/edit.routing.yml | 8 --- core/modules/edit/js/util.js | 35 ------------- .../edit/lib/Drupal/edit/EditController.php | 28 ---------- core/modules/editor/editor.module | 24 ++++++++- core/modules/editor/editor.routing.yml | 7 +++ core/modules/editor/js/editor.createjs.js | 54 ++++++++++++++++---- ...RenderedWithoutTransformationFiltersCommand.php | 7 +-- .../editor/lib/Drupal/editor/EditorController.php | 47 +++++++++++++++++ .../Drupal/editor/Tests/EditIntegrationTest.php | 25 +++++++++ 10 files changed, 151 insertions(+), 85 deletions(-) diff --git a/core/modules/edit/edit.module b/core/modules/edit/edit.module index dc1eec7..902d423 100644 --- a/core/modules/edit/edit.module +++ b/core/modules/edit/edit.module @@ -119,7 +119,6 @@ function edit_library_info() { 'data' => array('edit' => array( 'metadataURL' => url('edit/metadata'), 'fieldFormURL' => url('edit/form/!entity_type/!id/!field_name/!langcode/!view_mode'), - 'rerenderProcessedTextURL' => url('edit/text/!entity_type/!id/!field_name/!langcode/!view_mode'), 'context' => 'body', )), 'type' => 'setting', diff --git a/core/modules/edit/edit.routing.yml b/core/modules/edit/edit.routing.yml index f63dc82..d66881d 100644 --- a/core/modules/edit/edit.routing.yml +++ b/core/modules/edit/edit.routing.yml @@ -12,11 +12,3 @@ edit_field_form: requirements: _permission: 'access in-place editing' _access_edit_entity_field: 'TRUE' - -edit_text: - pattern: '/edit/text/{entity_type}/{entity}/{field_name}/{langcode}/{view_mode}' - defaults: - _controller: '\Drupal\edit\EditController::getUntransformedText' - requirements: - _permission: 'access in-place editing' - _access_edit_entity_field: 'TRUE' diff --git a/core/modules/edit/js/util.js b/core/modules/edit/js/util.js index 6633859..e0aa490 100644 --- a/core/modules/edit/js/util.js +++ b/core/modules/edit/js/util.js @@ -54,41 +54,6 @@ Drupal.edit.util.buildUrl = function(id, urlFormat) { }); }; -/** - * Loads rerendered processed text for a given property. - * - * Leverages Drupal.ajax' ability to have scoped (per-instance) command - * implementations to be able to call a callback. - * - * @param options - * An object with the following keys: - * - $editorElement (required): the PredicateEditor DOM element. - * - propertyID (required): the property ID that uniquely identifies the - * property for which this form will be loaded. - * - callback (required: A callback function that will receive the rerendered - * processed text. - */ -Drupal.edit.util.loadRerenderedProcessedText = function(options) { - // Create a Drupal.ajax instance to load the form. - Drupal.ajax[options.propertyID] = new Drupal.ajax(options.propertyID, options.$editorElement, { - url: Drupal.edit.util.buildUrl(options.propertyID, drupalSettings.edit.rerenderProcessedTextURL), - event: 'edit-internal.edit', - submit: { nocssjs : true }, - progress: { type : null } // No progress indicator. - }); - // Implement a scoped editFieldRenderedWithoutTransformationFilters AJAX - // command: calls the callback. - Drupal.ajax[options.propertyID].commands.editFieldRenderedWithoutTransformationFilters = function(ajax, response, status) { - options.callback(response.data); - // Delete the Drupal.ajax instance that called this very function. - delete Drupal.ajax[options.propertyID]; - options.$editorElement.off('edit-internal.edit'); - }; - // This will ensure our scoped editFieldRenderedWithoutTransformationFilters - // AJAX command gets called. - options.$editorElement.trigger('edit-internal.edit'); -}; - Drupal.edit.util.form = { /** * Loads a form, calls a callback to inserts. diff --git a/core/modules/edit/lib/Drupal/edit/EditController.php b/core/modules/edit/lib/Drupal/edit/EditController.php index 16644ab..aaf2c95 100644 --- a/core/modules/edit/lib/Drupal/edit/EditController.php +++ b/core/modules/edit/lib/Drupal/edit/EditController.php @@ -16,7 +16,6 @@ use Drupal\edit\Ajax\FieldFormCommand; use Drupal\edit\Ajax\FieldFormSavedCommand; use Drupal\edit\Ajax\FieldFormValidationErrorsCommand; -use Drupal\edit\Ajax\FieldRenderedWithoutTransformationFiltersCommand; /** * Returns responses for Edit module routes. @@ -117,31 +116,4 @@ public function fieldForm(EntityInterface $entity, $field_name, $langcode, $view return $response; } - /** - * Returns an Ajax response to render a text field without transformation filters. - * - * @param int $entity - * The entity of which a processed text field is being rerendered. - * @param string $field_name - * The name of the (processed text) field that that is being rerendered - * @param string $langcode - * The name of the language for which the processed text field is being - * rererendered. - * @param string $view_mode - * The view mode the processed text field should be rerendered in. - * @return \Drupal\Core\Ajax\AjaxResponse - * The Ajax response. - */ - public function getUntransformedText(EntityInterface $entity, $field_name, $langcode, $view_mode) { - $response = new AjaxResponse(); - - $output = field_view_field($entity, $field_name, $view_mode, $langcode); - $langcode = $output['#language']; - // Direct text editing is only supported for single-valued fields. - $editable_text = check_markup($output['#items'][0]['value'], $output['#items'][0]['format'], $langcode, FALSE, array(FILTER_TYPE_TRANSFORM_REVERSIBLE, FILTER_TYPE_TRANSFORM_IRREVERSIBLE)); - $response->addCommand(new FieldRenderedWithoutTransformationFiltersCommand($editable_text)); - - return $response; - } - } diff --git a/core/modules/editor/editor.module b/core/modules/editor/editor.module index 4061f48..6cdc777 100644 --- a/core/modules/editor/editor.module +++ b/core/modules/editor/editor.module @@ -86,11 +86,21 @@ function editor_library_info() { $path . '/js/editor.createjs.js' => array( 'scope' => 'footer', 'attributes' => array('defer' => TRUE), - ) + ), + array( + 'type' => 'setting', + 'data' => array( + 'editor' => array( + 'rerenderProcessedTextURL' => url('editor/!entity_type/!id/!field_name/!langcode/!view_mode'), + ) + ) + ), ), 'dependencies' => array( array('edit', 'edit'), array('editor', 'drupal.editor'), + array('system', 'drupal.ajax'), + array('system', 'drupalSettings'), ), ); @@ -98,6 +108,18 @@ function editor_library_info() { } /** + * Implements hook_custom_theme(). + * + * @todo Add an event subscriber to the Ajax system to automatically set the + * base page theme for all Ajax requests, and then remove this one off. + */ +function editor_custom_theme() { + if (substr(current_path(), 0, 7) === 'editor/') { + return ajax_base_page_theme(); + } +} + +/** * Implements hook_form_FORM_ID_alter(). */ function editor_form_filter_admin_overview_alter(&$form, $form_state) { diff --git a/core/modules/editor/editor.routing.yml b/core/modules/editor/editor.routing.yml new file mode 100644 index 0000000..0bb56cf --- /dev/null +++ b/core/modules/editor/editor.routing.yml @@ -0,0 +1,7 @@ +editor_field_untransformed_text: + pattern: '/editor/{entity_type}/{entity}/{field_name}/{langcode}/{view_mode}' + defaults: + _controller: '\Drupal\editor\EditorController::getUntransformedText' + requirements: + _permission: 'access in-place editing' + _access_edit_entity_field: 'TRUE' diff --git a/core/modules/editor/js/editor.createjs.js b/core/modules/editor/js/editor.createjs.js index 56780dd..c7b1fdc 100644 --- a/core/modules/editor/js/editor.createjs.js +++ b/core/modules/editor/js/editor.createjs.js @@ -18,7 +18,7 @@ /** * Implements getEditUISettings() method. */ - getEditUISettings: function() { + getEditUISettings: function () { return { padding: true, unifiedToolbar: true, fullWidthToolbar: true }; }, @@ -28,12 +28,12 @@ * @todo: POSTPONED_ON(Create.js, https://github.com/bergie/create/issues/142) * Get rid of this once that issue is solved. */ - _init: function() {}, + _init: function () {}, /** * Implements Create's _initialize() method. */ - _initialize: function() { + _initialize: function () { var propertyID = Drupal.edit.util.calcPropertyID(this.options.entity, this.options.property); var metadata = Drupal.edit.metadataCache[propertyID].custom; @@ -47,11 +47,11 @@ /** * Binds to events. */ - _bindEvents: function() { + _bindEvents: function () { var that = this; // Sets the state to 'activated' upon clicking the element. - this.element.on('click.edit', function(event) { + this.element.on('click.edit', function (event) { event.stopPropagation(); event.preventDefault(); that.options.activating(); @@ -61,7 +61,7 @@ /** * Makes this PropertyEditor widget react to state changes. */ - stateChange: function(from, to) { + stateChange: function (from, to) { var that = this; switch (to) { case 'inactive': @@ -85,7 +85,7 @@ // text of this field, then we'll need to load a re-rendered version of // it without the transformation filters. if (this.textFormatHasTransformations) { - Drupal.edit.util.loadRerenderedProcessedText({ + this._loadRerenderedProcessedText({ $editorElement: this.element, propertyID: Drupal.edit.util.calcPropertyID(this.options.entity, this.options.property), callback: function (rerendered) { @@ -131,7 +131,7 @@ * * @todo: this should not be necessary, will be obviated by edit.module. */ - _removeValidationErrors: function() { + _removeValidationErrors: function () { this.element .removeClass('edit-validation-error') .next('.edit-validation-errors').remove(); @@ -142,10 +142,46 @@ * * @todo: this should not be necessary, will be obviated by edit.module. */ - _cleanUp: function() { + _cleanUp: function () { Drupal.edit.util.form.unajaxifySaving(jQuery('#edit_backstage form .edit-form-submit')); jQuery('#edit_backstage form').remove(); + }, + + /** + * Loads rerendered processed text for a given property. + * + * Leverages Drupal.ajax' ability to have scoped (per-instance) command + * implementations to be able to call a callback. + * + * @param options + * An object with the following keys: + * - $editorElement (required): the PredicateEditor DOM element. + * - propertyID (required): the property ID that uniquely identifies the + * property for which this form will be loaded. + * - callback (required: A callback function that will receive the + * rerendered processed text. + */ + _loadRerenderedProcessedText: function (options) { + // Create a Drupal.ajax instance to load the form. + Drupal.ajax[options.propertyID] = new Drupal.ajax(options.propertyID, options.$editorElement, { + url: Drupal.edit.util.buildUrl(options.propertyID, drupalSettings.editor.rerenderProcessedTextURL), + event: 'editor-internal.editor', + submit: { nocssjs : true }, + progress: { type : null } // No progress indicator. + }); + // Implement a scoped editFieldRenderedWithoutTransformationFilters AJAX + // command: calls the callback. + Drupal.ajax[options.propertyID].commands.editorFieldRenderedWithoutTransformationFilters = function(ajax, response, status) { + options.callback(response.data); + // Delete the Drupal.ajax instance that called this very function. + delete Drupal.ajax[options.propertyID]; + options.$editorElement.off('editor-internal.editor'); + }; + // This will ensure our scoped editFieldRenderedWithoutTransformationFilters + // AJAX command gets called. + options.$editorElement.trigger('editor-internal.editor'); } + }); })(jQuery, Drupal, drupalSettings); diff --git a/core/modules/edit/lib/Drupal/edit/Ajax/FieldRenderedWithoutTransformationFiltersCommand.php b/core/modules/editor/lib/Drupal/editor/Ajax/FieldRenderedWithoutTransformationFiltersCommand.php similarity index 65% rename from core/modules/edit/lib/Drupal/edit/Ajax/FieldRenderedWithoutTransformationFiltersCommand.php rename to core/modules/editor/lib/Drupal/editor/Ajax/FieldRenderedWithoutTransformationFiltersCommand.php index 53a8826..77100a7 100644 --- a/core/modules/edit/lib/Drupal/edit/Ajax/FieldRenderedWithoutTransformationFiltersCommand.php +++ b/core/modules/editor/lib/Drupal/editor/Ajax/FieldRenderedWithoutTransformationFiltersCommand.php @@ -2,12 +2,13 @@ /** * @file - * Definition of Drupal\edit\Ajax\FieldRenderedWithoutTransformationFiltersCommand. + * Definition of Drupal\editor\Ajax\FieldRenderedWithoutTransformationFiltersCommand. */ -namespace Drupal\edit\Ajax; +namespace Drupal\editor\Ajax; use Drupal\Core\Ajax\CommandInterface; +use Drupal\edit\Ajax\BaseCommand; /** * AJAX command to rerender a processed text field without any transformation @@ -22,7 +23,7 @@ class FieldRenderedWithoutTransformationFiltersCommand extends BaseCommand { * The data to pass on to the client side. */ public function __construct($data) { - parent::__construct('editFieldRenderedWithoutTransformationFilters', $data); + parent::__construct('editorFieldRenderedWithoutTransformationFilters', $data); } } diff --git a/core/modules/editor/lib/Drupal/editor/EditorController.php b/core/modules/editor/lib/Drupal/editor/EditorController.php new file mode 100644 index 0000000..2f774fd --- /dev/null +++ b/core/modules/editor/lib/Drupal/editor/EditorController.php @@ -0,0 +1,47 @@ +addCommand(new FieldRenderedWithoutTransformationFiltersCommand($editable_text)); + + return $response; + } + +} diff --git a/core/modules/editor/lib/Drupal/editor/Tests/EditIntegrationTest.php b/core/modules/editor/lib/Drupal/editor/Tests/EditIntegrationTest.php index 875f1ef..3dfd688 100644 --- a/core/modules/editor/lib/Drupal/editor/Tests/EditIntegrationTest.php +++ b/core/modules/editor/lib/Drupal/editor/Tests/EditIntegrationTest.php @@ -12,6 +12,8 @@ use Drupal\edit\Plugin\EditorManager; use Drupal\edit\Tests\EditTestBase; use Drupal\edit_test\MockEditEntityFieldAccessCheck; +use Drupal\editor\EditorController; +use Symfony\Component\HttpFoundation\Request; /** * Tests Edit module integration (Editor module's inline editing support). @@ -172,4 +174,27 @@ function testMetadata() { $this->assertEqual($expected, $metadata, 'The correct metadata (including custom metadata) is generated.'); } + /** + * Tests FieldRenderedWithoutTransformationFiltersCommand AJAX command. + */ + function testFieldRenderedWithoutTransformationFiltersCommand() { + // Create an entity with values for the field. + $this->entity = field_test_create_entity(); + $this->is_new = TRUE; + $this->entity->{$this->field_name}[LANGUAGE_NOT_SPECIFIED] = array(array('value' => 'Test', 'format' => 'full_html')); + field_test_entity_save($this->entity); + $entity = entity_load('test_entity', $this->entity->ftid); + + // Verify AJAX response. + $controller = new EditorController(); + $request = new Request(); + $response = $controller->getUntransformedText($entity, $this->field_name, LANGUAGE_NOT_SPECIFIED, 'default'); + $expected = array( + array( + 'command' => 'editorFieldRenderedWithoutTransformationFilters', + 'data' => 'Test', + ) + ); + $this->assertEqual(drupal_json_encode($expected), $response->prepare($request)->getContent(), 'The FieldRenderedWithoutTransformationFiltersCommand AJAX command works correctly.'); + } }