* @ignore
*/
-(function ($, Drupal, drupalSettings, CKEDITOR) {
+(function($, Drupal, drupalSettings, CKEDITOR) {
function parseAttributes(editor, element) {
const parsedAttributes = {};
const domElement = element.$;
let attribute;
let attributeName;
- for (let attrIndex = 0; attrIndex < domElement.attributes.length; attrIndex++) {
+ for (
+ let attrIndex = 0;
+ attrIndex < domElement.attributes.length;
+ attrIndex++
+ ) {
attribute = domElement.attributes.item(attrIndex);
attributeName = attribute.nodeName.toLowerCase();
// Ignore data-cke-* attributes; they're CKEditor internals.
}
// Store the value for this attribute, unless there's a data-cke-saved-
// alternative for it, which will contain the quirk-free, original value.
- parsedAttributes[attributeName] = element.data(`cke-saved-${attributeName}`) || attribute.nodeValue;
+ parsedAttributes[attributeName] =
+ element.data(`cke-saved-${attributeName}`) || attribute.nodeValue;
}
// Remove any cke_* classes.
if (parsedAttributes.class) {
- parsedAttributes.class = CKEDITOR.tools.trim(parsedAttributes.class.replace(/cke_\S+/, ''));
+ parsedAttributes.class = CKEDITOR.tools.trim(
+ parsedAttributes.class.replace(/cke_\S+/, ''),
+ );
}
return parsedAttributes;
function getAttributes(editor, data) {
const set = {};
- Object.keys(data || {}).forEach((attributeName) => {
+ Object.keys(data || {}).forEach(attributeName => {
set[attributeName] = data[attributeName];
});
// Remove all attributes which are not currently set.
const removed = {};
- Object.keys(set).forEach((s) => {
+ Object.keys(set).forEach(s => {
delete removed[s];
});
};
}
+ /**
+ * Get the surrounding link element of current selection.
+ *
+ * The following selection will all return the link element.
+ *
+ * @example
+ * <a href="#">li^nk</a>
+ * <a href="#">[link]</a>
+ * text[<a href="#">link]</a>
+ * <a href="#">li[nk</a>]
+ * [<b><a href="#">li]nk</a></b>]
+ * [<a href="#"><b>li]nk</b></a>
+ *
+ * @param {CKEDITOR.editor} editor
+ * The CKEditor editor object
+ *
+ * @return {?HTMLElement}
+ * The selected link element, or null.
+ *
+ */
+ function getSelectedLink(editor) {
+ const selection = editor.getSelection();
+ const selectedElement = selection.getSelectedElement();
+ if (selectedElement && selectedElement.is('a')) {
+ return selectedElement;
+ }
+
+ const range = selection.getRanges(true)[0];
+
+ if (range) {
+ range.shrink(CKEDITOR.SHRINK_TEXT);
+ return editor.elementPath(range.getCommonAncestor()).contains('a', 1);
+ }
+ return null;
+ }
+
CKEDITOR.plugins.add('drupallink', {
icons: 'drupallink,drupalunlink',
hidpi: true,
canUndo: true,
exec(editor) {
const drupalImageUtils = CKEDITOR.plugins.drupalimage;
- const focusedImageWidget = drupalImageUtils && drupalImageUtils.getFocusedWidget(editor);
+ const focusedImageWidget =
+ drupalImageUtils && drupalImageUtils.getFocusedWidget(editor);
let linkElement = getSelectedLink(editor);
// Set existing values based on selected element.
}
// Prepare a save callback to be used upon saving the dialog.
- const saveCallback = function (returnValues) {
+ const 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) {
- focusedImageWidget.setData('link', CKEDITOR.tools.extend(returnValues.attributes, focusedImageWidget.data.link));
+ focusedImageWidget.setData(
+ 'link',
+ CKEDITOR.tools.extend(
+ returnValues.attributes,
+ focusedImageWidget.data.link,
+ ),
+ );
editor.fire('saveSnapshot');
return;
}
// Use link URL as text with a collapsed cursor.
if (range.collapsed) {
// Shorten mailto URLs to just the email address.
- const text = new CKEDITOR.dom.text(returnValues.attributes.href.replace(/^mailto:/, ''), editor.document);
+ const text = new CKEDITOR.dom.text(
+ returnValues.attributes.href.replace(/^mailto:/, ''),
+ editor.document,
+ );
range.insertNode(text);
range.selectNodeContents(text);
}
// Create the new link by applying a style to the new text.
- const style = new CKEDITOR.style({ element: 'a', attributes: returnValues.attributes });
+ const style = new CKEDITOR.style({
+ element: 'a',
+ attributes: returnValues.attributes,
+ });
style.type = CKEDITOR.STYLE_INLINE;
style.applyToRange(range);
range.select();
}
// Update the link properties.
else if (linkElement) {
- Object.keys(returnValues.attributes || {}).forEach((attrName) => {
+ Object.keys(returnValues.attributes || {}).forEach(attrName => {
// Update the property if a value is specified.
if (returnValues.attributes[attrName].length > 0) {
const value = returnValues.attributes[attrName];
// loads the JavaScript file instead of Drupal. Pull translated
// strings from the plugin settings that are translated server-side.
const dialogSettings = {
- title: linkElement ? editor.config.drupalLink_dialogTitleEdit : editor.config.drupalLink_dialogTitleAdd,
+ title: linkElement
+ ? editor.config.drupalLink_dialogTitleEdit
+ : editor.config.drupalLink_dialogTitleAdd,
dialogClass: 'editor-link-dialog',
};
// Open the dialog for the edit form.
- Drupal.ckeditor.openDialog(editor, Drupal.url(`editor/dialog/link/${editor.config.drupal.format}`), existingValues, saveCallback, dialogSettings);
+ Drupal.ckeditor.openDialog(
+ editor,
+ Drupal.url(`editor/dialog/link/${editor.config.drupal.format}`),
+ existingValues,
+ saveCallback,
+ dialogSettings,
+ );
},
});
editor.addCommand('drupalunlink', {
},
}),
exec(editor) {
- const style = new CKEDITOR.style({ element: 'a', type: CKEDITOR.STYLE_INLINE, alwaysRemoveElement: 1 });
+ const style = new CKEDITOR.style({
+ element: 'a',
+ type: CKEDITOR.STYLE_INLINE,
+ alwaysRemoveElement: 1,
+ });
editor.removeStyle(style);
},
refresh(editor, path) {
- const element = path.lastElement && path.lastElement.getAscendant('a', true);
- if (element && element.getName() === 'a' && element.getAttribute('href') && element.getChildCount()) {
+ const element =
+ path.lastElement && path.lastElement.getAscendant('a', true);
+ if (
+ element &&
+ element.getName() === 'a' &&
+ element.getAttribute('href') &&
+ element.getChildCount()
+ ) {
this.setState(CKEDITOR.TRISTATE_OFF);
- }
- else {
+ } else {
this.setState(CKEDITOR.TRISTATE_DISABLED);
}
},
});
}
- editor.on('doubleclick', (evt) => {
+ editor.on('doubleclick', evt => {
const element = getSelectedLink(editor) || evt.data.element;
if (!element.isReadOnly()) {
let menu = {};
if (anchor.getAttribute('href') && anchor.getChildCount()) {
- menu = { link: CKEDITOR.TRISTATE_OFF, unlink: CKEDITOR.TRISTATE_OFF };
+ menu = {
+ link: CKEDITOR.TRISTATE_OFF,
+ unlink: CKEDITOR.TRISTATE_OFF,
+ };
}
return menu;
});
},
});
- /**
- * Get the surrounding link element of current selection.
- *
- * The following selection will all return the link element.
- *
- * @example
- * <a href="#">li^nk</a>
- * <a href="#">[link]</a>
- * text[<a href="#">link]</a>
- * <a href="#">li[nk</a>]
- * [<b><a href="#">li]nk</a></b>]
- * [<a href="#"><b>li]nk</b></a>
- *
- * @param {CKEDITOR.editor} editor
- * The CKEditor editor object
- *
- * @return {?HTMLElement}
- * The selected link element, or null.
- *
- */
- function getSelectedLink(editor) {
- const selection = editor.getSelection();
- const selectedElement = selection.getSelectedElement();
- if (selectedElement && selectedElement.is('a')) {
- return selectedElement;
- }
-
- const range = selection.getRanges(true)[0];
-
- if (range) {
- range.shrink(CKEDITOR.SHRINK_TEXT);
- return editor.elementPath(range.getCommonAncestor()).contains('a', 1);
- }
- return null;
- }
-
// Expose an API for other plugins to interact with drupallink widgets.
// (Compatible with the official CKEditor link plugin's API:
// http://dev.ckeditor.com/ticket/13885.)
parseLinkAttributes: parseAttributes,
getLinkAttributes: getAttributes,
};
-}(jQuery, Drupal, drupalSettings, CKEDITOR));
+})(jQuery, Drupal, drupalSettings, CKEDITOR);