/** * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state, FilterFormat $filter_format = NULL) { // Add AJAX support. $form['#prefix'] = '<div id="video-embed-dialog-form">'; $form['#suffix'] = '</div>'; // Ensure relevant dialog libraries are attached. $form['#attached']['library'][] = 'editor/drupal.editor.dialog'; // Simple URL field and submit button for video URL. $form['video_url'] = ['#type' => 'textfield', '#title' => $this->t('Video URL'), '#required' => TRUE, '#default_value' => $this->getUserInput($form_state, 'video_url')]; // If no settings are found, use the defaults configured in the filter // formats interface. $settings = $this->getUserInput($form_state, 'settings'); if (empty($settings) && ($editor = Editor::load($filter_format->id()))) { $editor_settings = $editor->getSettings(); $plugin_settings = NestedArray::getValue($editor_settings, ['plugins', 'video_embed', 'defaults', 'children']); $settings = $plugin_settings ? $plugin_settings : []; } // Create a settings form from the existing video formatter. $form['settings'] = Video::mockInstance($settings)->settingsForm([], new FormState()); $form['settings']['#type'] = 'fieldset'; $form['settings']['#title'] = $this->t('Settings'); $form['actions'] = ['#type' => 'actions']; $form['actions']['save_modal'] = ['#type' => 'submit', '#value' => $this->t('Save'), '#submit' => [], '#ajax' => ['callback' => '::ajaxSubmit', 'event' => 'click', 'wrapper' => 'video-embed-dialog-form']]; return $form; }
/** * Tests StylesCombo settings for an existing text format. */ function testExistingFormat() { $ckeditor = $this->container->get('plugin.manager.editor')->createInstance('ckeditor'); $default_settings = $ckeditor->getDefaultSettings(); $this->drupalLogin($this->adminUser); $this->drupalGet('admin/config/content/formats/manage/' . $this->format); // Ensure an Editor config entity exists, with the proper settings. $expected_settings = $default_settings; $editor = Editor::load($this->format); $this->assertEqual($expected_settings, $editor->getSettings(), 'The Editor config entity has the correct settings.'); // Case 1: Configure the Styles plugin with different labels for each style, // and ensure the updated settings are saved. $this->drupalGet('admin/config/content/formats/manage/' . $this->format); $edit = ['editor[settings][plugins][stylescombo][styles]' => "h1.title|Title\np.callout|Callout\n\n"]; $this->drupalPostForm(NULL, $edit, t('Save configuration')); $expected_settings['plugins']['stylescombo']['styles'] = "h1.title|Title\np.callout|Callout\n\n"; $editor = Editor::load($this->format); $this->assertEqual($expected_settings, $editor->getSettings(), 'The Editor config entity has the correct settings.'); // Case 2: Configure the Styles plugin with same labels for each style, and // ensure that an error is displayed and that the updated settings are not // saved. $this->drupalGet('admin/config/content/formats/manage/' . $this->format); $edit = ['editor[settings][plugins][stylescombo][styles]' => "h1.title|Title\np.callout|Title\n\n"]; $this->drupalPostForm(NULL, $edit, t('Save configuration')); $this->assertRaw(t('Each style must have a unique label.')); $expected_settings['plugins']['stylescombo']['styles'] = "h1.title|Title\np.callout|Callout\n\n"; $editor = Editor::load($this->format); $this->assertEqual($expected_settings, $editor->getSettings(), 'The Editor config entity has the correct settings.'); }
/** * Tests text format removal or disabling. */ public function testTextFormatIntegration() { // Create an arbitrary text format. $format = FilterFormat::create(['format' => Unicode::strtolower($this->randomMachineName()), 'name' => $this->randomString()]); $format->save(); // Create a paired editor. Editor::create(['format' => $format->id(), 'editor' => 'unicorn'])->save(); // Disable the text format. $format->disable()->save(); // The paired editor should be disabled too. $this->assertFalse(Editor::load($format->id())->status()); // Re-enable the text format. $format->enable()->save(); // The paired editor should be enabled too. $this->assertTrue(Editor::load($format->id())->status()); // Completely remove the text format. Usually this cannot occur via UI, but // can be triggered from API. $format->delete(); // The paired editor should be removed. $this->assertNull(Editor::load($format->id())); }
/** * Tests presence of essential configuration even without Internal's buttons. */ protected function testLoadingWithoutInternalButtons() { // Change the CKEditor text editor configuration to only have link buttons. // This means: // - 0 buttons are from \Drupal\ckeditor\Plugin\CKEditorPlugin\Internal // - 2 buttons are from \Drupal\ckeditor\Plugin\CKEditorPlugin\DrupalLink $filtered_html_editor = Editor::load('filtered_html'); $settings = $filtered_html_editor->getSettings(); $settings['toolbar']['rows'] = [0 => [0 => ['name' => 'Links', 'items' => ['DrupalLink', 'DrupalUnlink']]]]; $filtered_html_editor->setSettings($settings)->save(); // Even when no buttons of \Drupal\ckeditor\Plugin\CKEditorPlugin\Internal // are in use, its configuration (Internal::getConfig()) is still essential: // this is configuration that is associated with the (custom, optimized) // build of CKEditor that Drupal core ships with. For example, it configures // CKEditor to not perform its default action of loading a config.js file, // to not convert special characters into HTML entities, and the allowedContent // setting to configure CKEditor's Advanced Content Filter. $this->drupalLogin($this->normalUser); $this->drupalGet('node/add/article'); $editor_settings = $this->getDrupalSettings()['editor']['formats']['filtered_html']['editorSettings']; $this->assertTrue(isset($editor_settings['customConfig'])); $this->assertTrue(isset($editor_settings['entities'])); $this->assertTrue(isset($editor_settings['allowedContent'])); $this->assertTrue(isset($editor_settings['disallowedContent'])); }
/** * Assert that CKEditor picks the expected language when French is default. * * @param string $langcode * Language code to assert for. Defaults to French. That is the default * language set in this assertion. */ protected function assertCKEditorLanguage($langcode = 'fr') { // Set French as the site default language. ConfigurableLanguage::createFromLangcode('fr')->save(); $this->config('system.site')->set('default_langcode', 'fr')->save(); // Reset the language manager so new negotiations attempts will fall back on // French. Reinject the language manager CKEditor to use the current one. $this->container->get('language_manager')->reset(); $this->ckeditor = $this->container->get('plugin.manager.editor')->createInstance('ckeditor'); // Test that we now get the expected language. $editor = Editor::load('filtered_html'); $settings = $this->ckeditor->getJSSettings($editor); $this->assertEqual($settings['language'], $langcode); }
/** * Tests the iframe instance CSS files of plugins. */ function testCssFiles() { $this->manager = $this->container->get('plugin.manager.ckeditor.plugin'); $editor = Editor::load('filtered_html'); // Case 1: no CKEditor iframe instance CSS file. $this->assertIdentical(array(), $this->manager->getCssFiles($editor), 'No iframe instance CSS file found.'); // Enable the CKEditor Test module, which has the LlamaCss plugin and // clear the editor manager's cache so it is picked up. $this->enableModules(array('ckeditor_test')); $this->manager = $this->container->get('plugin.manager.ckeditor.plugin'); $settings = $editor->getSettings(); // LlamaCss: automatically enabled by adding its 'LlamaCSS' button. $settings['toolbar']['rows'][0][0]['items'][] = 'LlamaCSS'; $editor->setSettings($settings); $editor->save(); // Case 2: CKEditor iframe instance CSS file. $expected = array('llama_css' => array(drupal_get_path('module', 'ckeditor_test') . '/css/llama.css')); $this->assertIdentical($expected, $this->manager->getCssFiles($editor), 'Iframe instance CSS file found.'); }
/** * Asserts whether the saved maximum dimensions equal the ones provided. * * @param string $width * The expected width of the uploaded image. * @param string $height * The expected height of the uploaded image. * * @return bool */ protected function assertSavedMaxDimensions($width, $height) { $image_upload_settings = Editor::load('basic_html')->getImageUploadSettings(); $expected = ['width' => $image_upload_settings['max_dimensions']['width'], 'height' => $image_upload_settings['max_dimensions']['height']]; $same_width = $this->assertEqual($width, $expected['width'], 'Actual width of "' . $width . '" equals the expected width of "' . $expected['width'] . '"'); $same_height = $this->assertEqual($height, $expected['height'], 'Actual height of "' . $height . '" equals the expected width of "' . $expected['height'] . '"'); return $same_width && $same_height; }
/** * Tests configuring a text editor for a new text format. * * This test only needs to ensure that the basics of the CKEditor * configuration form work; details are tested in testExistingFormat(). */ function testNewFormat() { $this->drupalLogin($this->adminUser); $this->drupalGet('admin/config/content/formats/add'); // Verify the "Text Editor" <select> when a text editor is available. $select = $this->xpath('//select[@name="editor[editor]"]'); $select_is_disabled = $this->xpath('//select[@name="editor[editor]" and @disabled="disabled"]'); $options = $this->xpath('//select[@name="editor[editor]"]/option'); $this->assertTrue(count($select) === 1, 'The Text Editor select exists.'); $this->assertTrue(count($select_is_disabled) === 0, 'The Text Editor select is not disabled.'); $this->assertTrue(count($options) === 2, 'The Text Editor select has two options.'); $this->assertTrue((string) $options[0] === 'None', 'Option 1 in the Text Editor select is "None".'); $this->assertTrue((string) $options[1] === 'CKEditor', 'Option 2 in the Text Editor select is "CKEditor".'); $this->assertTrue((string) $options[0]['selected'] === 'selected', 'Option 1 ("None") is selected.'); // Name our fancy new text format, select the "CKEditor" editor and click // the "Configure" button. $edit = array('name' => 'My amazing text format', 'format' => 'amazing_format', 'editor[editor]' => 'ckeditor'); $this->drupalPostAjaxForm(NULL, $edit, 'editor_configure'); $filter_format = FilterFormat::load('amazing_format'); $this->assertFalse($filter_format, 'No FilterFormat config entity exists yet.'); $editor = Editor::load('amazing_format'); $this->assertFalse($editor, 'No Editor config entity exists yet.'); // Ensure the toolbar buttons configuration value is initialized to the // default value. $ckeditor = $this->container->get('plugin.manager.editor')->createInstance('ckeditor'); $default_settings = $ckeditor->getDefaultSettings(); $expected_buttons_value = json_encode($default_settings['toolbar']['rows']); $this->assertFieldByName('editor[settings][toolbar][button_groups]', $expected_buttons_value); // Regression test for https://www.drupal.org/node/2606460. $this->assertTrue(strpos($this->drupalSettings['ckeditor']['toolbarAdmin'], '<li data-drupal-ckeditor-button-name="Bold" class="ckeditor-button"><a href="#" class="cke-icon-only cke_ltr" role="button" title="bold" aria-label="bold"><span class="cke_button_icon cke_button__bold_icon">bold</span></a></li>') !== FALSE); // Ensure the styles textarea exists and is initialized empty. $styles_textarea = $this->xpath('//textarea[@name="editor[settings][plugins][stylescombo][styles]"]'); $this->assertFieldByXPath('//textarea[@name="editor[settings][plugins][stylescombo][styles]"]', '', 'The styles textarea exists and is empty.'); $this->assertTrue(count($styles_textarea) === 1, 'The "styles" textarea exists.'); // Submit the form to create both a new text format and an associated text // editor. $this->drupalPostForm(NULL, $edit, t('Save configuration')); // Ensure a FilterFormat object exists now. $filter_format = FilterFormat::load('amazing_format'); $this->assertTrue($filter_format instanceof FilterFormatInterface, 'A FilterFormat config entity exists now.'); // Ensure an Editor object exists now, with the proper settings. $expected_settings = $default_settings; $expected_settings['plugins']['stylescombo']['styles'] = ''; $editor = Editor::load('amazing_format'); $this->assertTrue($editor instanceof Editor, 'An Editor config entity exists now.'); $this->assertEqual($this->castSafeStrings($expected_settings), $this->castSafeStrings($editor->getSettings()), 'The Editor config entity has the correct settings.'); }
/** * Sets the maximum dimensions and saves the configuration. * * @param string|int $width * The width of the image. * @param string|int $height * The height of the image. */ protected function setMaxDimensions($width, $height) { $editor = Editor::load('basic_html'); $image_upload_settings = $editor->getImageUploadSettings(); $image_upload_settings['max_dimensions']['width'] = $width; $image_upload_settings['max_dimensions']['height'] = $height; $editor->setImageUploadSettings($image_upload_settings); $editor->save(); }