Update to Drupal 8.0.0-rc3. For more information, see https://www.drupal.org/node/2608078

This commit is contained in:
Pantheon Automation 2015-11-04 11:11:27 -08:00 committed by Greg Anderson
parent 6419a031d7
commit 4afb23bbd3
762 changed files with 20080 additions and 6368 deletions

View file

@ -123,7 +123,7 @@ function template_preprocess_ckeditor_settings_toolbar(&$variables) {
'buttons' => array(),
);
$buttons = array_filter($button_row, function ($button) use ($group_name) {
return $button['group'] === $group_name;
return (string) $button['group'] === $group_name;
});
foreach ($buttons as $button) {
$variables['active_buttons'][$row_number][$group_name]['buttons'][] = $build_button_item($button, $rtl);

View file

@ -34,6 +34,12 @@
margin: 0;
padding: 0;
}
/* This is required to win over specificity of [dir="rtl"] ul */
[dir="rtl"] .ckeditor-toolbar ul,
[dir="rtl"] .ckeditor-toolbar-disabled ul {
margin-right: 0;
}
.ckeditor-row {
padding: 2px 0 3px;
border-radius: 3px;
@ -121,13 +127,19 @@
box-sizing: border-box;
}
.ckeditor-toolbar-disabled .ckeditor-toolbar-available {
float: left;
float: left; /* LTR */
width: 80%;
}
.ckeditor-toolbar-disabled .ckeditor-toolbar-dividers {
[dir="rtl"] .ckeditor-toolbar-disabled .ckeditor-toolbar-available {
float: right;
}
.ckeditor-toolbar-disabled .ckeditor-toolbar-dividers {
float: right; /* LTR */
width: 20%;
}
[dir="rtl"] .ckeditor-toolbar-disabled .ckeditor-toolbar-dividers {
float: left;
}
.ckeditor-toolbar-disabled .ckeditor-buttons li a,
.ckeditor-toolbar .ckeditor-buttons,
.ckeditor-add-new-group button {

View file

@ -29,50 +29,55 @@
return;
}
// Override requiredContent & allowedContent.
widgetDefinition.requiredContent = new CKEDITOR.style({
element: 'img',
styles: {},
attributes: {
'alt': '',
'src': '',
'width': '',
'height': '',
'data-entity-type': '',
'data-entity-uuid': ''
}
});
var allowedContentDefinition = {
element: 'img',
styles: {},
attributes: {
'!data-entity-type': '',
'!data-entity-uuid': ''
// First, convert requiredContent & allowedContent from the string
// format that image2 uses for both to formats that are better suited
// for extending, so that both this basic drupalimage plugin and Drupal
// modules can easily extend it.
// @see http://docs.ckeditor.com/#!/api/CKEDITOR.filter.allowedContentRules
// Mapped from image2's allowedContent. Unlike image2, we don't allow
// <figure>, <figcaption>, <div> or <p> in our downcast, so we omit
// those. For the <img> tag, we list all attributes it lists, but omit
// the classes, because the listed classes are for alignment, and for
// alignment we use the data-align attribute.
widgetDefinition.allowedContent = {
img: {
attributes: {
'!src': true,
'!alt': true,
'width': true,
'height': true
},
classes: {}
}
};
var imgAttributes = widgetDefinition.allowedContent.img.attributes.split(/\s*,\s*/);
for (var i = 0; i < imgAttributes.length; i++) {
allowedContentDefinition.attributes[imgAttributes[i]] = '';
}
if (widgetDefinition.allowedContent.img.classes) {
allowedContentDefinition.attributes['class'] = widgetDefinition.allowedContent.img.classes.split(/\s*,\s*/).join(' ');
}
if (widgetDefinition.allowedContent.img.styles) {
var imgStyles = widgetDefinition.allowedContent.img.styles.split(/\s*,\s*/);
for (var j = 0; j < imgStyles.length; j++) {
allowedContentDefinition.styles[imgStyles[j]] = '';
// Mapped from image2's requiredContent: "img[src,alt]". This does not
// use the object format unlike above, but a CKEDITOR.style instance,
// because requiredContent does not support the object format.
// @see https://www.drupal.org/node/2585173#comment-10456981
widgetDefinition.requiredContent = new CKEDITOR.style({
element: 'img',
attributes: {
src: '',
alt: ''
}
}
widgetDefinition.allowedContent = new CKEDITOR.style(allowedContentDefinition);
});
// Override the 'link' part, to completely disable image2's link
// support: http://dev.ckeditor.com/ticket/11341.
widgetDefinition.parts.link = 'This is a nonsensical selector to disable this functionality completely';
// Extend requiredContent & allowedContent.
// CKEDITOR.style is an immutable object: we cannot modify its
// definition to extend requiredContent. Hence we get the definition,
// modify it, and pass it to a new CKEDITOR.style instance.
var requiredContent = widgetDefinition.requiredContent.getDefinition();
requiredContent.attributes['data-entity-type'] = '';
requiredContent.attributes['data-entity-uuid'] = '';
widgetDefinition.requiredContent = new CKEDITOR.style(requiredContent);
widgetDefinition.allowedContent.img.attributes['!data-entity-type'] = true;
widgetDefinition.allowedContent.img.attributes['!data-entity-uuid'] = true;
// Override downcast(): since we only accept <img> in our upcast method,
// the element is already correct. We only need to update the element's
// data-entity-uuid attribute.
widgetDefinition.downcast = function (element) {
element.attributes['data-entity-type'] = this.data['data-entity-type'];
element.attributes['data-entity-uuid'] = this.data['data-entity-uuid'];
};
@ -176,6 +181,18 @@
return widget;
};
};
var originalInit = widgetDefinition.init;
widgetDefinition.init = function () {
originalInit.call(this);
// Update data.link object with attributes if the link has been
// discovered.
// @see plugins/image2/plugin.js/init() in CKEditor; this is similar.
if (this.parts.link) {
this.setData('link', CKEDITOR.plugins.link.parseLinkAttributes(editor, this.parts.link));
}
};
});
// Add a widget#edit listener to every instance of image2 widget in order
@ -233,25 +250,86 @@
}
},
// Disable image2's integration with the link/drupallink plugins: don't
// allow the widget itself to become a link. Support for that may be added
// by an text filter that adds a data- attribute specifically for that.
afterInit: function (editor) {
if (editor.plugins.drupallink) {
var cmd = editor.getCommand('drupallink');
// Needs to be refreshed on selection changes.
cmd.contextSensitive = 1;
// Disable command and cancel event when the image widget is selected.
cmd.on('refresh', function (evt) {
var widget = editor.widgets.focused;
if (widget && widget.name === 'image') {
this.setState(CKEDITOR.TRISTATE_DISABLED);
evt.cancel();
}
});
}
linkCommandIntegrator(editor);
}
});
/**
* Integrates the drupalimage widget with the drupallink plugin.
*
* Makes images linkable.
*
* @param {CKEDITOR.editor} editor
* A CKEditor instance.
*/
function linkCommandIntegrator(editor) {
// Nothing to integrate with if the drupallink plugin is not loaded.
if (!editor.plugins.drupallink) {
return;
}
// Override default behaviour of 'drupalunlink' command.
editor.getCommand('drupalunlink').on('exec', function (evt) {
var widget = getFocusedWidget(editor);
// Override 'drupalunlink' only when link truly belongs to the widget. If
// wrapped inline widget in a link, let default unlink work.
// @see https://dev.ckeditor.com/ticket/11814
if (!widget || !widget.parts.link) {
return;
}
widget.setData('link', null);
// Selection (which is fake) may not change if unlinked image in focused
// widget, i.e. if captioned image. Let's refresh command state manually
// here.
this.refresh(editor, editor.elementPath());
evt.cancel();
});
// Override default refresh of 'drupalunlink' command.
editor.getCommand('drupalunlink').on('refresh', function (evt) {
var widget = getFocusedWidget(editor);
if (!widget) {
return;
}
// Note that widget may be wrapped in a link, which
// does not belong to that widget (#11814).
this.setState(widget.data.link || widget.wrapper.getAscendant('a') ?
CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED);
evt.cancel();
});
}
/**
* Gets the focused widget, if of the type specific for this plugin.
*
* @param {CKEDITOR.editor} editor
* A CKEditor instance.
*
* @return {?CKEDITOR.plugins.widget}
* The focused image2 widget instance, or null.
*/
function getFocusedWidget(editor) {
var widget = editor.widgets.focused;
if (widget && widget.name === 'image') {
return widget;
}
return null;
}
// Expose an API for other plugins to interact with drupalimage widgets.
CKEDITOR.plugins.drupalimage = {
getFocusedWidget: getFocusedWidget
};
})(jQuery, Drupal, CKEDITOR);

View file

@ -50,15 +50,16 @@
}
}, true);
// Override requiredContent & allowedContent.
// Extend requiredContent & allowedContent.
// CKEDITOR.style is an immutable object: we cannot modify its
// definition to extend requiredContent. Hence we get the definition,
// modify it, and pass it to a new CKEDITOR.style instance.
var requiredContent = widgetDefinition.requiredContent.getDefinition();
requiredContent.attributes['data-align'] = '';
requiredContent.attributes['data-caption'] = '';
widgetDefinition.requiredContent = new CKEDITOR.style(requiredContent);
var allowedContent = widgetDefinition.allowedContent.getDefinition();
allowedContent.attributes['!data-align'] = '';
allowedContent.attributes['!data-caption'] = '';
widgetDefinition.allowedContent = new CKEDITOR.style(allowedContent);
widgetDefinition.allowedContent.img.attributes['!data-align'] = true;
widgetDefinition.allowedContent.img.attributes['!data-caption'] = true;
// Override allowedContent setting for the 'caption' nested editable.
// This must match what caption_filter enforces.
@ -71,10 +72,9 @@
// data-caption attributes.
var originalDowncast = widgetDefinition.downcast;
widgetDefinition.downcast = function (element) {
var img = originalDowncast.call(this, element);
if (!img) {
img = findElementByName(element, 'img');
}
var img = findElementByName(element, 'img');
originalDowncast.call(this, img);
var caption = this.editables.caption;
var captionHtml = caption && caption.getData();
var attrs = img.attributes;
@ -91,10 +91,14 @@
attrs['data-align'] = this.data.align;
}
}
attrs['data-entity-type'] = this.data['data-entity-type'];
attrs['data-entity-uuid'] = this.data['data-entity-uuid'];
return img;
// If img is wrapped with a link, we want to return that link.
if (img.parent.name === 'a') {
return img.parent;
}
else {
return img;
}
};
// We want to upcast <img> elements to a DOM structure required by the
@ -115,6 +119,11 @@
element = originalUpcast.call(this, element, data);
var attrs = element.attributes;
if (element.parent.name === 'a') {
element = element.parent;
}
var retElement = element;
var caption;

View file

@ -13,17 +13,17 @@
init: function (editor) {
// Add the commands for link and unlink.
editor.addCommand('drupallink', {
allowedContent: new CKEDITOR.style({
element: 'a',
styles: {},
attributes: {
'!href': '',
'target': ''
allowedContent: {
a: {
attributes: {
'!href': true,
'target': true
},
classes: {}
}
}),
},
requiredContent: new CKEDITOR.style({
element: 'a',
styles: {},
attributes: {
href: ''
}
@ -31,6 +31,8 @@
modes: {wysiwyg: 1},
canUndo: true,
exec: function (editor) {
var drupalImageUtils = CKEDITOR.plugins.drupalimage;
var focusedImageWidget = drupalImageUtils && drupalImageUtils.getFocusedWidget(editor);
var linkElement = getSelectedLink(editor);
var linkDOMElement = null;
@ -56,9 +58,30 @@
existingValues[attributeName] = linkElement.data('cke-saved-' + attributeName) || attribute.nodeValue;
}
}
// Or, if an image widget is focused, we're editing a link wrapping
// an image widget.
else if (focusedImageWidget && focusedImageWidget.data.link) {
var url = focusedImageWidget.data.link.url;
existingValues.href = url.protocol + url.url;
}
// Prepare a save callback to be used upon saving the dialog.
var saveCallback = function (returnValues) {
// If an image widget is focused, we're not editing an independent
// link, but we're wrapping an image widget in a link.
if (focusedImageWidget) {
var urlMatch = returnValues.attributes.href.match(urlRegex);
focusedImageWidget.setData('link', {
type: 'url',
url: {
protocol: urlMatch[1],
url: urlMatch[2]
}
});
editor.fire('saveSnapshot');
return;
}
editor.fire('saveSnapshot');
// Create a new link element if needed.
@ -124,13 +147,14 @@
editor.addCommand('drupalunlink', {
contextSensitive: 1,
startDisabled: 1,
allowedContent: new CKEDITOR.style({
element: 'a',
attributes: {
'!href': '',
'target': ''
allowedContent: {
a: {
attributes: {
'!href': true,
'target': true
}
}
}),
},
requiredContent: new CKEDITOR.style({
element: 'a',
attributes: {
@ -256,4 +280,57 @@
return null;
}
var urlRegex = /^((?:http|https):\/\/)?(.*)$/;
/**
* The image2 plugin is currently tightly coupled to the link plugin: it
* calls CKEDITOR.plugins.link.parseLinkAttributes().
*
* Drupal 8's CKEditor build doesn't include the 'link' plugin. Because it
* includes its own link plugin that integrates with Drupal's dialog system.
* So, to allow images to be linked, we need to duplicate the necessary subset
* of the logic.
*
* @todo Remove once we update to CKEditor 4.5.5.
* @see https://dev.ckeditor.com/ticket/13885
*/
CKEDITOR.plugins.link = CKEDITOR.plugins.link || {
parseLinkAttributes: function (editor, element) {
var href = (element && (element.data('cke-saved-href') || element.getAttribute('href'))) || '';
var urlMatch = href.match(urlRegex);
return {
type: 'url',
url: {
protocol: urlMatch[1],
url: urlMatch[2]
}
};
},
getLinkAttributes: function (editor, data) {
var set = {};
var protocol = (data.url && typeof data.url.protocol !== 'undefined') ? data.url.protocol : 'http://';
var url = (data.url && CKEDITOR.tools.trim(data.url.url)) || '';
set['data-cke-saved-href'] = (url.indexOf('/') === 0) ? url : protocol + url;
// Browser need the "href" fro copy/paste link to work. (#6641)
if (set['data-cke-saved-href']) {
set.href = set['data-cke-saved-href'];
}
// Remove all attributes which are not currently set.
var removed = {};
for (var s in set) {
if (set.hasOwnProperty(s)) {
delete removed[s];
}
}
return {
set: set,
removed: CKEDITOR.tools.objectKeys(removed)
};
}
};
})(jQuery, Drupal, drupalSettings, CKEDITOR);

View file

@ -75,14 +75,14 @@ class Internal extends CKEditorPluginBase implements ContainerFactoryPluginInter
}
/**
* Implements \Drupal\ckeditor\Plugin\CKEditorPluginInterface::isInternal().
* {@inheritdoc}
*/
public function isInternal() {
return TRUE;
}
/**
* Implements \Drupal\ckeditor\Plugin\CKEditorPluginInterface::getFile().
* {@inheritdoc}
*/
public function getFile() {
// This plugin is already part of Drupal core's CKEditor build.
@ -90,7 +90,7 @@ class Internal extends CKEditorPluginBase implements ContainerFactoryPluginInter
}
/**
* Implements \Drupal\ckeditor\Plugin\CKEditorPluginInterface::getConfig().
* {@inheritdoc}
*/
public function getConfig(Editor $editor) {
// Reasonable defaults that provide expected basic behavior.
@ -123,7 +123,7 @@ class Internal extends CKEditorPluginBase implements ContainerFactoryPluginInter
}
/**
* Implements \Drupal\ckeditor\Plugin\CKEditorPluginButtonsInterface::getButtons().
* {@inheritdoc}
*/
public function getButtons() {
$button = function($name, $direction = 'ltr') {
@ -538,16 +538,26 @@ class Internal extends CKEditorPluginBase implements ContainerFactoryPluginInter
if (count($allowed_attributes)) {
$allowed[$tag]['attributes'] = implode(',', array_keys($allowed_attributes));
}
if (isset($allowed_attributes['style']) && is_array($allowed_attributes['style'])) {
$allowed_styles = $get_attribute_values($allowed_attributes['style'], TRUE);
if (isset($allowed_styles)) {
$allowed[$tag]['styles'] = $allowed_styles;
if (isset($allowed_attributes['style'])) {
if (is_bool($allowed_attributes['style'])) {
$allowed[$tag]['styles'] = $allowed_attributes['style'];
}
elseif (is_array($allowed_attributes['style'])) {
$allowed_classes = $get_attribute_values($allowed_attributes['style'], TRUE);
if (isset($allowed_classes)) {
$allowed[$tag]['styles'] = $allowed_classes;
}
}
}
if (isset($allowed_attributes['class']) && is_array($allowed_attributes['class'])) {
$allowed_classes = $get_attribute_values($allowed_attributes['class'], TRUE);
if (isset($allowed_classes)) {
$allowed[$tag]['classes'] = $allowed_classes;
if (isset($allowed_attributes['class'])) {
if (is_bool($allowed_attributes['class'])) {
$allowed[$tag]['classes'] = $allowed_attributes['class'];
}
elseif (is_array($allowed_attributes['class'])) {
$allowed_classes = $get_attribute_values($allowed_attributes['class'], TRUE);
if (isset($allowed_classes)) {
$allowed[$tag]['classes'] = $allowed_classes;
}
}
}

View file

@ -23,14 +23,14 @@ use Drupal\editor\Entity\Editor;
class StylesCombo extends CKEditorPluginBase implements CKEditorPluginConfigurableInterface {
/**
* Implements \Drupal\ckeditor\Plugin\CKEditorPluginInterface::isInternal().
* {@inheritdoc}
*/
public function isInternal() {
return TRUE;
}
/**
* Implements \Drupal\ckeditor\Plugin\CKEditorPluginInterface::getFile().
* {@inheritdoc}
*/
public function getFile() {
// This plugin is already part of Drupal core's CKEditor build.
@ -38,7 +38,7 @@ class StylesCombo extends CKEditorPluginBase implements CKEditorPluginConfigurab
}
/**
* Implements \Drupal\ckeditor\Plugin\CKEditorPluginInterface::getConfig().
* {@inheritdoc}
*/
public function getConfig(Editor $editor) {
$config = array();
@ -52,7 +52,7 @@ class StylesCombo extends CKEditorPluginBase implements CKEditorPluginConfigurab
}
/**
* Implements \Drupal\ckeditor\Plugin\CKEditorPluginButtonsInterface::getButtons().
* {@inheritdoc}
*/
public function getButtons() {
return array(
@ -70,7 +70,7 @@ class StylesCombo extends CKEditorPluginBase implements CKEditorPluginConfigurab
}
/**
* Implements \Drupal\ckeditor\Plugin\CKEditorPluginConfigurableInterface::settingsForm().
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state, Editor $editor) {
// Defaults.
@ -85,7 +85,7 @@ class StylesCombo extends CKEditorPluginBase implements CKEditorPluginConfigurab
'#title_display' => 'invisible',
'#type' => 'textarea',
'#default_value' => $config['styles'],
'#description' => t('A list of classes that will be provided in the "Styles" dropdown. Enter one class on each line in the format: element.class|Label. Example: h1.title|Title.<br />These styles should be available in your theme\'s CSS file.'),
'#description' => t('A list of classes that will be provided in the "Styles" dropdown. Enter one or more classes on each line in the format: element.classA.classB|Label. Example: h1.title|Title. Advanced example: h1.fancy.title|Fancy title.<br />These styles should be available in your theme\'s CSS file.'),
'#attached' => array(
'library' => array('ckeditor/drupal.ckeditor.stylescombo.admin'),
),

View file

@ -261,6 +261,9 @@ class CKEditorAdminTest extends WebTestBase {
$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.');

View file

@ -123,11 +123,13 @@ class CKEditorTest extends KernelTestBase {
// Change the allowed HTML tags; the "allowedContent" and "format_tags"
// settings for CKEditor should automatically be updated as well.
$format = $editor->getFilterFormat();
$format->filters('filter_html')->settings['allowed_html'] .= '<pre> <h1>';
$format->filters('filter_html')->settings['allowed_html'] .= '<pre class> <h1> <blockquote class="*"> <address class="foo bar-* *">';
$format->save();
$expected_config['allowedContent']['pre'] = array('attributes' => FALSE, 'styles' => FALSE, 'classes' => FALSE);
$expected_config['allowedContent']['pre'] = array('attributes' => 'class', 'styles' => FALSE, 'classes' => TRUE);
$expected_config['allowedContent']['h1'] = array('attributes' => FALSE, 'styles' => FALSE, 'classes' => FALSE);
$expected_config['allowedContent']['blockquote'] = array('attributes' => 'class', 'styles' => FALSE, 'classes' => TRUE);
$expected_config['allowedContent']['address'] = array('attributes' => 'class', 'styles' => FALSE, 'classes' => 'foo,bar-*');
$expected_config['format_tags'] = 'p;h1;h2;h3;h4;h5;h6;pre';
ksort($expected_config['allowedContent']);
$this->assertIdentical($expected_config, $this->castSafeStrings($this->ckeditor->getJSSettings($editor)), 'Generated JS settings are correct for customized configuration.');

View file

@ -31,35 +31,35 @@ use Drupal\editor\Entity\Editor;
class Llama extends PluginBase implements CKEditorPluginInterface {
/**
* Implements \Drupal\ckeditor\Plugin\CKEditorPluginInterface::getDependencies().
* {@inheritdoc}
*/
function getDependencies(Editor $editor) {
return array();
}
/**
* Implements \Drupal\ckeditor\Plugin\CKEditorPluginInterface::getLibraries().
* {@inheritdoc}
*/
function getLibraries(Editor $editor) {
return array();
}
/**
* Implements \Drupal\ckeditor\Plugin\CKEditorPluginInterface::isInternal().
* {@inheritdoc}
*/
function isInternal() {
return FALSE;
}
/**
* Implements \Drupal\ckeditor\Plugin\CKEditorPluginInterface::getFile().
* {@inheritdoc}
*/
function getFile() {
return drupal_get_path('module', 'ckeditor_test') . '/js/llama.js';
}
/**
* Implements \Drupal\ckeditor\Plugin\CKEditorPluginInterface::getConfig().
* {@inheritdoc}
*/
public function getConfig(Editor $editor) {
return array();

View file

@ -20,7 +20,7 @@ use Drupal\ckeditor\CKEditorPluginButtonsInterface;
class LlamaButton extends Llama implements CKEditorPluginButtonsInterface {
/**
* Implements \Drupal\ckeditor\Plugin\CKEditorPluginButtonsInterface::getButtons().
* {@inheritdoc}
*/
function getButtons() {
return array(
@ -31,7 +31,7 @@ class LlamaButton extends Llama implements CKEditorPluginButtonsInterface {
}
/**
* Implements \Drupal\ckeditor\Plugin\CKEditorPluginInterface::getFile().
* {@inheritdoc}
*/
function getFile() {
return drupal_get_path('module', 'ckeditor_test') . '/js/llama_button.js';

View file

@ -21,7 +21,7 @@ use Drupal\editor\Entity\Editor;
class LlamaContextual extends Llama implements CKEditorPluginContextualInterface {
/**
* Implements \Drupal\ckeditor\Plugin\CKEditorPluginContextualInterface::isEnabled().
* {@inheritdoc}
*/
function isEnabled(Editor $editor) {
// Automatically enable this plugin if the Underline button is enabled.
@ -37,7 +37,7 @@ class LlamaContextual extends Llama implements CKEditorPluginContextualInterface
}
/**
* Implements \Drupal\ckeditor\Plugin\CKEditorPluginInterface::getFile().
* {@inheritdoc}
*/
function getFile() {
return drupal_get_path('module', 'ckeditor_test') . '/js/llama_contextual.js';

View file

@ -25,7 +25,7 @@ use Drupal\editor\Entity\Editor;
class LlamaContextualAndButton extends Llama implements CKEditorPluginContextualInterface, CKEditorPluginButtonsInterface, CKEditorPluginConfigurableInterface {
/**
* Implements \Drupal\ckeditor\Plugin\CKEditorPluginContextualInterface::isEnabled().
* {@inheritdoc}
*/
function isEnabled(Editor $editor) {
// Automatically enable this plugin if the Strike button is enabled.
@ -41,7 +41,7 @@ class LlamaContextualAndButton extends Llama implements CKEditorPluginContextual
}
/**
* Implements \Drupal\ckeditor\Plugin\CKEditorPluginButtonsInterface::getButtons().
* {@inheritdoc}
*/
function getButtons() {
return array(
@ -52,14 +52,14 @@ class LlamaContextualAndButton extends Llama implements CKEditorPluginContextual
}
/**
* Implements \Drupal\ckeditor\Plugin\CKEditorPluginInterface::getFile().
* {@inheritdoc}
*/
function getFile() {
return drupal_get_path('module', 'ckeditor_test') . '/js/llama_contextual_and_button.js';
}
/**
* Implements \Drupal\ckeditor\Plugin\CKEditorPluginConfigurableInterface::settingsForm().
* {@inheritdoc}
*/
function settingsForm(array $form, FormStateInterface $form_state, Editor $editor) {
// Defaults.