Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
F
footnotes-3486079
Manage
Activity
Members
Labels
Plan
Custom issue tracker
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Model registry
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Issue forks
footnotes-3486079
Commits
d2cc40df
Commit
d2cc40df
authored
4 months ago
by
Scott Euser
Browse files
Options
Downloads
Patches
Plain Diff
Issue
#3484654
by scott_euser, andreastkdf: Pasting content nests everything in an extra paragraph
parent
a58a47bc
Branches
4.0.x
Branches containing commit
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
assets/js/build/footnotes.js
+1
-1
1 addition, 1 deletion
assets/js/build/footnotes.js
assets/js/ckeditor5_plugins/footnotes/src/footnotesediting.js
+2
-3
2 additions, 3 deletions
...ts/js/ckeditor5_plugins/footnotes/src/footnotesediting.js
with
3 additions
and
4 deletions
assets/js/build/footnotes.js
+
1
−
1
View file @
d2cc40df
!
function
(
e
,
n
){
"
object
"
==
typeof
exports
&&
"
object
"
==
typeof
module
?
module
.
exports
=
n
():
"
function
"
==
typeof
define
&&
define
.
amd
?
define
([],
n
):
"
object
"
==
typeof
exports
?
exports
.
CKEditor5
=
n
():(
e
.
CKEditor5
=
e
.
CKEditor5
||
{},
e
.
CKEditor5
.
footnotes
=
n
())}(
self
,(()
=>
(()
=>
{
var
__webpack_modules__
=
{
"
./assets/js/ckeditor5_plugins/footnotes/src/footnotes.js
"
:(
__unused_webpack_module
,
__webpack_exports__
,
__webpack_require__
)
=>
{
"
use strict
"
;
eval
(
'
__webpack_require__.r(__webpack_exports__);
\n
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
\n
/* harmony export */ "default": () => (/* binding */ Footnotes)
\n
/* harmony export */ });
\n
/* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "ckeditor5/src/core.js");
\n
/* harmony import */ var _footnotesediting__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./footnotesediting */ "./assets/js/ckeditor5_plugins/footnotes/src/footnotesediting.js");
\n
/* harmony import */ var _footnotesui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./footnotesui */ "./assets/js/ckeditor5_plugins/footnotes/src/footnotesui.js");
\n
// eslint-disable-next-line import/no-unresolved
\n\n\n\n\n
/**
\n
* Main entry point to the footnotes.
\n
*/
\n
class Footnotes extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.Plugin {
\n
/**
\n
* @inheritdoc
\n
*/
\n
static get requires() {
\n
return [_footnotesediting__WEBPACK_IMPORTED_MODULE_1__["default"], _footnotesui__WEBPACK_IMPORTED_MODULE_2__["default"]];
\n
}
\n\n
/**
\n
* @inheritdoc
\n
*/
\n
static get pluginName() {
\n
return
\'
footnotes
\'
;
\n
}
\n
}
\n\n\n
//# sourceURL=webpack://CKEditor5.footnotes/./assets/js/ckeditor5_plugins/footnotes/src/footnotes.js?
'
)},
"
./assets/js/ckeditor5_plugins/footnotes/src/footnotescommand.js
"
:(
__unused_webpack_module
,
__webpack_exports__
,
__webpack_require__
)
=>
{
"
use strict
"
;
eval
(
"
__webpack_require__.r(__webpack_exports__);
\n
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
\n
/* harmony export */
\"
default
\"
: () => (/* binding */ Footnotescommand)
\n
/* harmony export */ });
\n
/* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */
\"
ckeditor5/src/core.js
\"
);
\n
// eslint-disable-next-line import/no-unresolved
\n\n\n
/**
\n
* Creates a <footnotes> element using the provided writer and attributes.
\n
*
\n
* @param {Object} writer - The CKEditor writer instance.
\n
* @param {Object} attributes - Attributes to be applied to the <footnotes> element.
\n
* @return {Object} The created <footnotes> element.
\n
*/
\n
function createFootnotes(writer, attributes) {
\n
return writer.createElement('footnotes', attributes);
\n
}
\n\n
/**
\n
* Command for inserting <footnotes> tag into ckeditor.
\n
*/
\n
class Footnotescommand extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.Command {
\n
execute(attributes) {
\n
const footnotesEditing = this.editor.plugins.get('footnotesEditing');
\n\n
// Create object that contains supported data-attributes in view data by
\n
// flipping `DrupalMediaEditing.attrs` object (i.e. keys from object become
\n
// values and values from object become keys).
\n
const dataAttributeMapping = Object.entries(footnotesEditing.attrs).reduce(
\n
(result, [key, value]) => {
\n
result[value] = key;
\n
return result;
\n
},
\n
{},
\n
);
\n\n
//
\\
Drupal
\\
media
\\
Form
\\
EditorMediaDialog returns data in keyed by
\n
// data-attributes used in view data. This converts data-attribute keys to
\n
// keys used in model.
\n
const modelAttributes = Object.keys(attributes).reduce(
\n
(result, attribute) => {
\n
if (dataAttributeMapping[attribute]) {
\n
if (typeof attributes[attribute].value !== 'undefined') {
\n
result[dataAttributeMapping[attribute]] =
\n
attributes[attribute].value;
\n
} else {
\n
result[dataAttributeMapping[attribute]] = attributes[attribute];
\n
}
\n
}
\n
return result;
\n
},
\n
{},
\n
);
\n\n
this.editor.model.change((writer) => {
\n
this.editor.model.insertContent(createFootnotes(writer, modelAttributes));
\n
});
\n
}
\n\n
refresh() {
\n
const { model } = this.editor;
\n
const { selection } = model.document;
\n
const allowedIn = model.schema.findAllowedParent(
\n
selection.getFirstPosition(),
\n
'footnotes',
\n
);
\n
this.isEnabled = allowedIn !== null;
\n
}
\n
}
\n\n\n
//# sourceURL=webpack://CKEditor5.footnotes/./assets/js/ckeditor5_plugins/footnotes/src/footnotescommand.js?
"
)},
"
./assets/js/ckeditor5_plugins/footnotes/src/footnotesdoubleclick.js
"
:(
__unused_webpack_module
,
__webpack_exports__
,
__webpack_require__
)
=>
{
"
use strict
"
;
eval
(
'
__webpack_require__.r(__webpack_exports__);
\n
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
\n
/* harmony export */ "default": () => (/* binding */ DoubleClickObserver)
\n
/* harmony export */ });
\n
/* harmony import */ var ckeditor5_src_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/engine */ "ckeditor5/src/engine.js");
\n
// eslint-disable-next-line import/no-unresolved
\n\n\n
/**
\n
* Ckeditor5 doesn
\'
t support double click out of the box.
\n
* Register it here so we can use it.
\n
*/
\n
class DoubleClickObserver extends ckeditor5_src_engine__WEBPACK_IMPORTED_MODULE_0__.DomEventObserver {
\n
constructor(view) {
\n
super(view);
\n
this.domEventType =
\'
dblclick
\'
;
\n
}
\n\n
onDomEvent(domEvent) {
\n
this.fire(domEvent.type, domEvent);
\n
}
\n
}
\n\n\n
//# sourceURL=webpack://CKEditor5.footnotes/./assets/js/ckeditor5_plugins/footnotes/src/footnotesdoubleclick.js?
'
)},
"
./assets/js/ckeditor5_plugins/footnotes/src/footnotesediting.js
"
:(
__unused_webpack_module
,
__webpack_exports__
,
__webpack_require__
)
=>
{
"
use strict
"
;
eval
(
"
__webpack_require__.r(__webpack_exports__);
\n
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
\n
/* harmony export */
\"
default
\"
: () => (/* binding */ Footnotesediting)
\n
/* harmony export */ });
\n
/* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */
\"
ckeditor5/src/core.js
\"
);
\n
/* harmony import */ var ckeditor5_src_widget__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ckeditor5/src/widget */
\"
ckeditor5/src/widget.js
\"
);
\n
/* harmony import */ var _footnotescommand__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./footnotescommand */
\"
./assets/js/ckeditor5_plugins/footnotes/src/footnotescommand.js
\"
);
\n
/* eslint-disable import/no-unresolved */
\n\n\n\n\n
// Function to determine if we should output console logs.
\n
function isDebugMode() {
\n
const params = new URLSearchParams(window.location.search);
\n
return params.has('debug');
\n
}
\n\n
function transformClipboardContent(documentFragment) {
\n
// Function to create a new <footnotes> element
\n
function createFootnotesElement(value, reference) {
\n
const footnotesElement = document.createElement('footnotes');
\n\n
footnotesElement.setAttribute('data-value', value);
\n
footnotesElement.setAttribute('data-text', reference);
\n
footnotesElement.innerHTML = ' '; // or any other content you wish to add
\n\n
return footnotesElement;
\n
}
\n\n
// Function to extract the reference html from the selected footnote.
\n
function extractFootnoteReference(htmlString) {
\n
// Ensure htmlString is actually a string (not an HTML element)
\n
if (typeof htmlString !== 'string') {
\n
throw new Error(`Expected a string as input, got: ${typeof htmlString}`);
\n
}
\n\n
// Create a DOM parser to parse the string
\n
const parser = new DOMParser();
\n
const doc = parser.parseFromString(htmlString, 'text/html');
\n\n
// Create a document fragment to hold the cleaned content
\n
const fragment = document.createDocumentFragment();
\n\n
// Function to traverse and extract only the relevant elements, namely
\n
// bold, italics, and links.
\n
function processNode(node) {
\n
if (node.nodeType === Node.ELEMENT_NODE) {
\n
const tagName = node.tagName.toLowerCase();
\n\n
if (tagName === 'b' || tagName === 'strong') {
\n
const bold = document.createElement('b');
\n
bold.innerHTML = node.innerHTML;
\n
fragment.appendChild(bold);
\n
} else if (tagName === 'i' || tagName === 'em') {
\n
const italic = document.createElement('i');
\n
italic.innerHTML = node.innerHTML;
\n
fragment.appendChild(italic);
\n
} else if (tagName === 'a') {
\n
const hrefFragment = node.href.split('#')[1] || '';
\n
// Exclude if the fragment starts with
\"
sdfootnote
\"
,
\"
ftn
\"
, or
\"
_ftn
\"\n
if (
\n
!hrefFragment.startsWith('sdfootnote') &&
\n
!hrefFragment.startsWith('ftn') &&
\n
!hrefFragment.startsWith('_ftn')
\n
) {
\n
const link = document.createElement('a');
\n
link.href = node.href;
\n
link.innerHTML = node.innerHTML;
\n
fragment.appendChild(link);
\n
}
\n
} else if (tagName === 'span') {
\n
// Unwrap the <span> element by processing its children
\n
Array.from(node.childNodes).forEach(processNode);
\n
} else {
\n
// Recursively extract from child nodes.
\n
Array.from(node.childNodes).forEach(processNode);
\n
}
\n
} else if (node.nodeType === Node.TEXT_NODE) {
\n
fragment.appendChild(document.createTextNode(node.textContent));
\n
}
\n
}
\n\n
// Start processing the body of the parsed document.
\n
Array.from(doc.body.childNodes).forEach(processNode);
\n\n
// Convert the document fragment back to HTML
\n
const container = document.createElement('div');
\n
container.appendChild(fragment);
\n\n
// Return the inner HTML of the cleaned content
\n
return container.innerHTML.trim();
\n
}
\n\n
if (isDebugMode()) {
\n
console.log('Content received from paste pipeline:');
\n
console.log(documentFragment);
\n
}
\n\n
// Find all the footnotes
\n
const footnotes = documentFragment.querySelectorAll(
\n
'.sdfootnote, [id*=
\"
ftn
\"
] > p, [id*=
\"
sdfootnote
\"
] > p',
\n
);
\n\n
footnotes.forEach((footnote) => {
\n
let footnoteText = extractFootnoteReference(footnote.innerHTML);
\n\n
// Find the anchor element
\n
const anchor = footnote.querySelector('.sdfootnotesym, [ href*=
\"
_ftnref
\"
]');
\n
if (anchor) {
\n
// Get the link, ensure that it only contains the fragment.
\n
let footnoteId = anchor.getAttribute('href').replace(/anc|ref|_/g, '');
\n
footnoteId = `#${footnoteId.split('#').pop()}`;
\n\n
// Find the corresponding anchor element and div
\n
const anchorSup = documentFragment.querySelector(
\n
`.sdfootnoteanc[href*=
\"
${footnoteId}sym
\"
], [href*=
\"
_ftn
\"
]`,
\n
);
\n
const anchorDiv = documentFragment.querySelector(`div${footnoteId}`);
\n
const supValue = '';
\n\n
if (anchorSup) {
\n
// Attempt to get footnote text from the anchor div
\n
// if not found yet.
\n
if (!footnoteText && anchorDiv.querySelector(`.MsoFootnoteReference`)) {
\n
// Find the reference number like [1] and remove it so the html
\n
// remaining is only the reference text itself.
\n
const anchorReferenceNumber = anchorDiv.querySelector(
\n
`.MsoFootnoteReference`,
\n
).parentNode;
\n\n
// If there is a reference number, remove it.
\n
if (typeof anchorReferenceNumber !== 'undefined') {
\n
anchorReferenceNumber.parentNode.removeChild(anchorReferenceNumber);
\n
}
\n
const anchorDivText = anchorDiv.querySelector('.MsoFootnoteText');
\n
if (anchorDivText) {
\n
footnoteText = anchorDivText.innerHTML;
\n
}
\n
}
\n\n
// If we ultimately have text.
\n
if (footnoteText) {
\n
// Create the new drupal footnotes element
\n
const footnotesElement = createFootnotesElement(
\n
supValue,
\n
footnoteText,
\n
);
\n\n
if (isDebugMode()) {
\n
console.log('Created footnotes element:');
\n
console.log(footnotesElement);
\n\n
console.log('Replacing citation element:');
\n
console.log(anchorSup);
\n\n
console.log('Removing anchor div:');
\n
console.log(anchorDiv);
\n
}
\n\n
// Remove unwanted remaining html.
\n
anchorSup.parentNode.replaceChild(footnotesElement, anchorSup);
\n
anchorDiv.parentNode.removeChild(anchorDiv);
\n
}
\n
}
\n
}
\n
});
\n\n
// Remove any lingering elements.
\n
const remainingElements = documentFragment.querySelectorAll(
\n
'div[style*=
\"
mso-element:footnote-list;
\"
]',
\n
);
\n
if (remainingElements && remainingElements.length > 0) {
\n
remainingElements.forEach((div) => {
\n
div.parentNode.removeChild(div);
\n
});
\n
}
\n\n
// Find all remaining/existing footnotes
\n
const drupalFootnotes = documentFragment.querySelectorAll('footnotes');
\n\n
// Reset the data value for automatic numbering
\n
drupalFootnotes.forEach((drupalFootnote) => {
\n
drupalFootnote.setAttribute('data-value', '');
\n
});
\n\n
if (isDebugMode()) {
\n
console.log('Returning document fragment:');
\n
console.log(documentFragment);
\n
}
\n
return documentFragment;
\n
}
\n\n
/**
\n
* Footnotes editing functionality.
\n
*/
\n
class Footnotesediting extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.Plugin {
\n
/**
\n
* @inheritdoc
\n
*/
\n
static get requires() {
\n
return [ckeditor5_src_widget__WEBPACK_IMPORTED_MODULE_1__.Widget];
\n
}
\n\n
/**
\n
* @inheritdoc
\n
*/
\n
static get pluginName() {
\n
return 'footnotesEditing';
\n
}
\n\n
/**
\n
* @inheritdoc
\n
*/
\n
init() {
\n
this.attrs = {
\n
footnotesText: 'data-text',
\n
footnotesValue: 'data-value',
\n
};
\n
const options = this.editor.config.get('footnotes');
\n
if (!options) {
\n
return;
\n
}
\n
const { previewURL, themeError } = options;
\n
this.previewUrl = previewURL;
\n
this.themeError =
\n
themeError ||
\n
`
\n
<p>${Drupal.t(
\n
'An error occurred while trying to preview the embedded content. Please save your work and reload this page.',
\n
)}<p>
\n
`;
\n\n
this._defineSchema();
\n
this._defineConverters();
\n\n
this.editor.commands.add('footnotes', new _footnotescommand__WEBPACK_IMPORTED_MODULE_2__[
\"
default
\"
](this.editor));
\n\n
// Automatically convert pasted content from Word/LibreOffice to
\n
// Footnotes format.
\n
this.editor.plugins.get('ClipboardPipeline').on(
\n
'inputTransformation',
\n
(evt, data) => {
\n
// Convert the view document fragment to a DOM document fragment.
\n
const viewFragment = data.content;
\n
const domFragment = this.editor.editing.view.domConverter.viewToDom(viewFragment);
\n\n
// Apply the footnotes changes and transform it back to a view document fragment.
\n
const transformedDomFragment = transformClipboardContent(domFragment);
\n
const transformedViewFragment = this.editor.editing.view.domConverter.domToView(transformedDomFragment);
\n\n
if (isDebugMode()) {
\n
console.log('Transformed view fragment:');
\n
console.log(transformedViewFragment);
\n
}
\n\n
// Convert the transformed view fragment to a model fragment.
\n
const modelFragment = this.editor.data.toModel(transformedViewFragment);
\n\n
this.editor.model.change(writer => {
\n
const selection = this.editor.model.document.selection;
\n\n
// If there is a selection, replace the selected content.
\n
if (selection && !selection.isCollapsed) {
\n
writer.remove(selection.getFirstRange());
\n
}
\n\n
// Insert the transformed content at the selection position (or cursor if collapsed).
\n
writer.insert(modelFragment, selection.getFirstPosition());
\n
});
\n\n
// Prevent default content handling, as we've already updated the model.
\n
evt.stop();
\n
},
\n
{ priority: 'highest' },
\n
);
\n
}
\n\n
/**
\n
* Fetches the preview for the given model element.
\n
*
\n
* @param {Element} modelElement - The CKEditor model element representing footnotes.
\n
*/
\n
async _fetchPreview(modelElement) {
\n
const query = {
\n
text: modelElement.getAttribute('footnotesText'),
\n
value: modelElement.getAttribute('footnotesValue'),
\n
};
\n
const response = await fetch(
\n
`${this.previewUrl}?${new URLSearchParams(query)}`,
\n
);
\n
if (response.ok) {
\n
return response.text();
\n
}
\n\n
return this.themeError;
\n
}
\n\n
/**
\n
* Registers footnotes as a block element in the DOM converter.
\n
*/
\n
_defineSchema() {
\n
const { schema } = this.editor.model;
\n
schema.register('footnotes', {
\n
allowWhere: '$inlineObject',
\n
blockObject: false,
\n
isObject: true,
\n
isContent: true,
\n
isBlock: false,
\n
isInline: true,
\n
inlineObject: true,
\n
allowAttributes: Object.keys(this.attrs),
\n
});
\n
this.editor.editing.view.domConverter.blockElements.push('footnotes');
\n
}
\n\n
/**
\n
* Defines handling of drupal media element in the content lifecycle.
\n
*
\n
* @private
\n
*/
\n
_defineConverters() {
\n
const { conversion } = this.editor;
\n\n
conversion.for('upcast').elementToElement({
\n
view: {
\n
name: 'footnotes',
\n
},
\n
model: 'footnotes',
\n
});
\n\n
conversion.for('dataDowncast').elementToElement({
\n
model: 'footnotes',
\n
view: {
\n
name: 'footnotes',
\n
},
\n
});
\n
conversion
\n
.for('editingDowncast')
\n
.elementToElement({
\n
model: 'footnotes',
\n
view: (modelElement, { writer }) => {
\n
const container = writer.createContainerElement('span');
\n
return (0,ckeditor5_src_widget__WEBPACK_IMPORTED_MODULE_1__.toWidget)(container, writer, {
\n
label: Drupal.t('Footnotes'),
\n
});
\n
},
\n
})
\n
.add((dispatcher) => {
\n
const converter = (event, data, conversionApi) => {
\n
const viewWriter = conversionApi.writer;
\n
const modelElement = data.item;
\n
const container = conversionApi.mapper.toViewElement(data.item);
\n
const footnotes = viewWriter.createRawElement('span', {
\n
'data-footnotes-preview': 'loading',
\n
class: 'footnotes-preview',
\n
});
\n
viewWriter.insert(
\n
viewWriter.createPositionAt(container, 0),
\n
footnotes,
\n
);
\n
this._fetchPreview(modelElement).then((preview) => {
\n
if (!footnotes) {
\n
return;
\n
}
\n
this.editor.editing.view.change((writer) => {
\n
const footnotesPreview = writer.createRawElement(
\n
'span',
\n
{
\n
class: 'footnotes-preview',
\n
'data-footnotes-preview': 'ready',
\n
},
\n
// eslint-disable-next-line max-nested-callbacks
\n
(domElement) => {
\n
domElement.innerHTML = preview;
\n
},
\n
);
\n
writer.insert(
\n
writer.createPositionBefore(footnotes),
\n
footnotesPreview,
\n
);
\n
writer.remove(footnotes);
\n
});
\n
});
\n
};
\n
dispatcher.on('attribute:footnotesValue:footnotes', converter);
\n
return dispatcher;
\n
});
\n\n
Object.keys(this.attrs).forEach((modelKey) => {
\n
const attributeMapping = {
\n
model: {
\n
key: modelKey,
\n
name: 'footnotes',
\n
},
\n
view: {
\n
name: 'footnotes',
\n
key: this.attrs[modelKey],
\n
},
\n
};
\n
conversion.for('dataDowncast').attributeToAttribute(attributeMapping);
\n
conversion.for('upcast').attributeToAttribute(attributeMapping);
\n
});
\n
}
\n
}
\n\n\n
//# sourceURL=webpack://CKEditor5.footnotes/./assets/js/ckeditor5_plugins/footnotes/src/footnotesediting.js?
"
)},
"
./assets/js/ckeditor5_plugins/footnotes/src/footnotesui.js
"
:(
__unused_webpack_module
,
__webpack_exports__
,
__webpack_require__
)
=>
{
"
use strict
"
;
eval
(
"
__webpack_require__.r(__webpack_exports__);
\n
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
\n
/* harmony export */
\"
default
\"
: () => (/* binding */ Footnotesui)
\n
/* harmony export */ });
\n
/* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */
\"
ckeditor5/src/core.js
\"
);
\n
/* harmony import */ var ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ckeditor5/src/ui */
\"
ckeditor5/src/ui.js
\"
);
\n
/* harmony import */ var _footnotesdoubleclick__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./footnotesdoubleclick */
\"
./assets/js/ckeditor5_plugins/footnotes/src/footnotesdoubleclick.js
\"
);
\n
/* harmony import */ var _icons_footnotes_svg__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../icons/footnotes.svg */
\"
./assets/js/ckeditor5_plugins/footnotes/icons/footnotes.svg
\"
);
\n
/* eslint-disable import/no-unresolved */
\n\n\n\n\n\n
/**
\n
* Provides the embedded content button and editing.
\n
*/
\n
class Footnotesui extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.Plugin {
\n
init() {
\n
const { editor } = this;
\n
const options = this.editor.config.get('footnotes');
\n
if (!options) {
\n
return;
\n
}
\n\n
const { dialogURL, openDialog, dialogSettings = {} } = options;
\n
if (!dialogURL || typeof openDialog !== 'function') {
\n
return;
\n
}
\n
editor.ui.componentFactory.add('footnotes', (locale) => {
\n
const command = editor.commands.get('footnotes');
\n
const buttonView = new ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__.ButtonView(locale);
\n
buttonView.set({
\n
label: Drupal.t('Footnotes'),
\n
icon: _icons_footnotes_svg__WEBPACK_IMPORTED_MODULE_3__[
\"
default
\"
],
\n
tooltip: true,
\n
});
\n\n
// Bind the state of the button to the command.
\n
buttonView.bind('isOn', 'isEnabled').to(command, 'value', 'isEnabled');
\n\n
this.listenTo(buttonView, 'execute', () => {
\n
const modelElement =
\n
editor.model.document.selection.getSelectedElement();
\n
const url = new URL(dialogURL, document.baseURI);
\n
if (
\n
modelElement &&
\n
typeof modelElement.name !== 'undefined' &&
\n
modelElement.name === 'footnotes'
\n
) {
\n
url.searchParams.append(
\n
'text',
\n
modelElement.getAttribute('footnotesText'),
\n
);
\n
url.searchParams.append(
\n
'value',
\n
modelElement.getAttribute('footnotesValue'),
\n
);
\n
}
\n
openDialog(
\n
url.toString(),
\n
({ attributes }) => {
\n
editor.execute('footnotes', attributes);
\n
},
\n
dialogSettings,
\n
);
\n
});
\n\n
return buttonView;
\n
});
\n\n
const { view } = editor.editing;
\n
const viewDocument = view.document;
\n\n
view.addObserver(_footnotesdoubleclick__WEBPACK_IMPORTED_MODULE_2__[
\"
default
\"
]);
\n\n
editor.listenTo(viewDocument, 'dblclick', (evt, data) => {
\n
const modelElement = editor.editing.mapper.toModelElement(
\n
data.target.parent,
\n
);
\n
if (
\n
modelElement &&
\n
typeof modelElement.name !== 'undefined' &&
\n
modelElement.name === 'footnotes'
\n
) {
\n
const query = {
\n
text: modelElement.getAttribute('footnotesText'),
\n
value: modelElement.getAttribute('footnotesValue'),
\n
};
\n
openDialog(
\n
`${dialogURL}?${new URLSearchParams(query)}`,
\n
({ attributes }) => {
\n
editor.execute('footnotes', attributes);
\n
},
\n
dialogSettings,
\n
);
\n
}
\n
});
\n
}
\n
}
\n\n\n
//# sourceURL=webpack://CKEditor5.footnotes/./assets/js/ckeditor5_plugins/footnotes/src/footnotesui.js?
"
)},
"
./assets/js/ckeditor5_plugins/footnotes/src/index.js
"
:(
__unused_webpack_module
,
__webpack_exports__
,
__webpack_require__
)
=>
{
"
use strict
"
;
eval
(
'
__webpack_require__.r(__webpack_exports__);
\n
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
\n
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
\n
/* harmony export */ });
\n
/* harmony import */ var _footnotes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./footnotes */ "./assets/js/ckeditor5_plugins/footnotes/src/footnotes.js");
\n\n\n
/**
\n
* @private
\n
*/
\n
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
\n
Footnotes: _footnotes__WEBPACK_IMPORTED_MODULE_0__["default"],
\n
});
\n\n\n
//# sourceURL=webpack://CKEditor5.footnotes/./assets/js/ckeditor5_plugins/footnotes/src/index.js?
'
)},
"
./assets/js/ckeditor5_plugins/footnotes/icons/footnotes.svg
"
:(
__unused_webpack_module
,
__webpack_exports__
,
__webpack_require__
)
=>
{
"
use strict
"
;
eval
(
'
__webpack_require__.r(__webpack_exports__);
\n
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
\n
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
\n
/* harmony export */ });
\n
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ("<?xml version=
\\
"1.0
\\
" standalone=
\\
"no
\\
"?>
\\
n<!DOCTYPE svg PUBLIC
\\
"-//W3C//DTD SVG 20010904//EN
\\
"
\\
n
\\
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd
\\
">
\\
n<svg version=
\\
"1.0
\\
" xmlns=
\\
"http://www.w3.org/2000/svg
\\
"
\\
n width=
\\
"16.000000pt
\\
" height=
\\
"16.000000pt
\\
" viewBox=
\\
"0 0 16.000000 16.000000
\\
"
\\
n preserveAspectRatio=
\\
"xMidYMid meet
\\
">
\\
n
\\
n<g transform=
\\
"translate(0.000000,16.000000) scale(0.100000,-0.100000)
\\
"
\\
nfill=
\\
"#000000
\\
" stroke=
\\
"none
\\
">
\\
n<path d=
\\
"M115 115 c0 -14 5 -25 11 -25 7 0 9 10 6 25 -2 14 -7 25 -11 25 -3 0
\\
n-6 -11 -6 -25z
\\
"/>
\\
n<path d=
\\
"M35 110 c-4 -6 5 -10 19 -10 14 0 26 -4 26 -10 0 -5 -8 -10 -19 -10
\\
n-24 0 -45 -25 -38 -45 4 -9 19 -14 42 -13 33 1 35 3 35 38 0 20 -5 41 -12 48
\\
n-15 15 -45 16 -53 2z m45 -60 c0 -5 -9 -10 -20 -10 -11 0 -20 5 -20 10 0 6 9
\\
n10 20 10 11 0 20 -4 20 -10z
\\
"/>
\\
n</g>
\\
n</svg>
\\
n");
\n\n
//# sourceURL=webpack://CKEditor5.footnotes/./assets/js/ckeditor5_plugins/footnotes/icons/footnotes.svg?
'
)},
"
ckeditor5/src/core.js
"
:(
module
,
__unused_webpack_exports
,
__webpack_require__
)
=>
{
eval
(
'
module.exports = (__webpack_require__(/*! dll-reference CKEditor5.dll */ "dll-reference CKEditor5.dll"))("./src/core.js");
\n\n
//# sourceURL=webpack://CKEditor5.footnotes/delegated_./core.js_from_dll-reference_CKEditor5.dll?
'
)},
"
ckeditor5/src/engine.js
"
:(
module
,
__unused_webpack_exports
,
__webpack_require__
)
=>
{
eval
(
'
module.exports = (__webpack_require__(/*! dll-reference CKEditor5.dll */ "dll-reference CKEditor5.dll"))("./src/engine.js");
\n\n
//# sourceURL=webpack://CKEditor5.footnotes/delegated_./engine.js_from_dll-reference_CKEditor5.dll?
'
)},
"
ckeditor5/src/ui.js
"
:(
module
,
__unused_webpack_exports
,
__webpack_require__
)
=>
{
eval
(
'
module.exports = (__webpack_require__(/*! dll-reference CKEditor5.dll */ "dll-reference CKEditor5.dll"))("./src/ui.js");
\n\n
//# sourceURL=webpack://CKEditor5.footnotes/delegated_./ui.js_from_dll-reference_CKEditor5.dll?
'
)},
"
ckeditor5/src/widget.js
"
:(
module
,
__unused_webpack_exports
,
__webpack_require__
)
=>
{
eval
(
'
module.exports = (__webpack_require__(/*! dll-reference CKEditor5.dll */ "dll-reference CKEditor5.dll"))("./src/widget.js");
\n\n
//# sourceURL=webpack://CKEditor5.footnotes/delegated_./widget.js_from_dll-reference_CKEditor5.dll?
'
)},
"
dll-reference CKEditor5.dll
"
:
e
=>
{
"
use strict
"
;
e
.
exports
=
CKEditor5
.
dll
}},
__webpack_module_cache__
=
{};
function
__webpack_require__
(
e
){
var
n
=
__webpack_module_cache__
[
e
];
if
(
void
0
!==
n
)
return
n
.
exports
;
var
t
=
__webpack_module_cache__
[
e
]
=
{
exports
:{}};
return
__webpack_modules__
[
e
](
t
,
t
.
exports
,
__webpack_require__
),
t
.
exports
}
__webpack_require__
.
d
=
(
e
,
n
)
=>
{
for
(
var
t
in
n
)
__webpack_require__
.
o
(
n
,
t
)
&&!
__webpack_require__
.
o
(
e
,
t
)
&&
Object
.
defineProperty
(
e
,
t
,{
enumerable
:
!
0
,
get
:
n
[
t
]})},
__webpack_require__
.
o
=
(
e
,
n
)
=>
Object
.
prototype
.
hasOwnProperty
.
call
(
e
,
n
),
__webpack_require__
.
r
=
e
=>
{
"
undefined
"
!=
typeof
Symbol
&&
Symbol
.
toStringTag
&&
Object
.
defineProperty
(
e
,
Symbol
.
toStringTag
,{
value
:
"
Module
"
}),
Object
.
defineProperty
(
e
,
"
__esModule
"
,{
value
:
!
0
})};
var
__webpack_exports__
=
__webpack_require__
(
"
./assets/js/ckeditor5_plugins/footnotes/src/index.js
"
);
return
__webpack_exports__
=
__webpack_exports__
.
default
,
__webpack_exports__
})()));
\ No newline at end of file
!
function
(
e
,
t
){
"
object
"
==
typeof
exports
&&
"
object
"
==
typeof
module
?
module
.
exports
=
t
():
"
function
"
==
typeof
define
&&
define
.
amd
?
define
([],
t
):
"
object
"
==
typeof
exports
?
exports
.
CKEditor5
=
t
():(
e
.
CKEditor5
=
e
.
CKEditor5
||
{},
e
.
CKEditor5
.
footnotes
=
t
())}(
self
,(()
=>
(()
=>
{
var
e
=
{
"
ckeditor5/src/core.js
"
:(
e
,
t
,
o
)
=>
{
e
.
exports
=
o
(
"
dll-reference CKEditor5.dll
"
)(
"
./src/core.js
"
)},
"
ckeditor5/src/engine.js
"
:(
e
,
t
,
o
)
=>
{
e
.
exports
=
o
(
"
dll-reference CKEditor5.dll
"
)(
"
./src/engine.js
"
)},
"
ckeditor5/src/ui.js
"
:(
e
,
t
,
o
)
=>
{
e
.
exports
=
o
(
"
dll-reference CKEditor5.dll
"
)(
"
./src/ui.js
"
)},
"
ckeditor5/src/widget.js
"
:(
e
,
t
,
o
)
=>
{
e
.
exports
=
o
(
"
dll-reference CKEditor5.dll
"
)(
"
./src/widget.js
"
)},
"
dll-reference CKEditor5.dll
"
:
e
=>
{
"
use strict
"
;
e
.
exports
=
CKEditor5
.
dll
}},
t
=
{};
function
o
(
n
){
var
r
=
t
[
n
];
if
(
void
0
!==
r
)
return
r
.
exports
;
var
s
=
t
[
n
]
=
{
exports
:{}};
return
e
[
n
](
s
,
s
.
exports
,
o
),
s
.
exports
}
o
.
d
=
(
e
,
t
)
=>
{
for
(
var
n
in
t
)
o
.
o
(
t
,
n
)
&&!
o
.
o
(
e
,
n
)
&&
Object
.
defineProperty
(
e
,
n
,{
enumerable
:
!
0
,
get
:
t
[
n
]})},
o
.
o
=
(
e
,
t
)
=>
Object
.
prototype
.
hasOwnProperty
.
call
(
e
,
t
);
var
n
=
{};
return
(()
=>
{
"
use strict
"
;
o
.
d
(
n
,{
default
:()
=>
m
});
var
e
=
o
(
"
ckeditor5/src/core.js
"
),
t
=
o
(
"
ckeditor5/src/widget.js
"
);
class
r
extends
e
.
Command
{
execute
(
e
){
const
t
=
this
.
editor
.
plugins
.
get
(
"
footnotesEditing
"
),
o
=
Object
.
entries
(
t
.
attrs
).
reduce
(((
e
,[
t
,
o
])
=>
(
e
[
o
]
=
t
,
e
)),{}),
n
=
Object
.
keys
(
e
).
reduce
(((
t
,
n
)
=>
(
o
[
n
]
&&
(
void
0
!==
e
[
n
].
value
?
t
[
o
[
n
]]
=
e
[
n
].
value
:
t
[
o
[
n
]]
=
e
[
n
]),
t
)),{});
this
.
editor
.
model
.
change
((
e
=>
{
this
.
editor
.
model
.
insertContent
(
function
(
e
,
t
){
return
e
.
createElement
(
"
footnotes
"
,
t
)}(
e
,
n
))}))}
refresh
(){
const
{
model
:
e
}
=
this
.
editor
,{
selection
:
t
}
=
e
.
document
,
o
=
e
.
schema
.
findAllowedParent
(
t
.
getFirstPosition
(),
"
footnotes
"
);
this
.
isEnabled
=
null
!==
o
}}
function
s
(){
return
new
URLSearchParams
(
window
.
location
.
search
).
has
(
"
debug
"
)}
function
i
(
e
){
s
()
&&
(
console
.
log
(
"
Content received from paste pipeline:
"
),
console
.
log
(
e
));
e
.
querySelectorAll
(
'
.sdfootnote, [id*="ftn"] > p, [id*="sdfootnote"] > p
'
).
forEach
((
t
=>
{
let
o
=
function
(
e
){
if
(
"
string
"
!=
typeof
e
)
throw
new
Error
(
"
Expected a string as input, got:
"
+
typeof
e
);
const
t
=
(
new
DOMParser
).
parseFromString
(
e
,
"
text/html
"
),
o
=
document
.
createDocumentFragment
();
Array
.
from
(
t
.
body
.
childNodes
).
forEach
((
function
e
(
t
){
if
(
t
.
nodeType
===
Node
.
ELEMENT_NODE
){
const
n
=
t
.
tagName
.
toLowerCase
();
if
(
"
b
"
===
n
||
"
strong
"
===
n
){
const
e
=
document
.
createElement
(
"
b
"
);
e
.
innerHTML
=
t
.
innerHTML
,
o
.
appendChild
(
e
)}
else
if
(
"
i
"
===
n
||
"
em
"
===
n
){
const
e
=
document
.
createElement
(
"
i
"
);
e
.
innerHTML
=
t
.
innerHTML
,
o
.
appendChild
(
e
)}
else
if
(
"
a
"
===
n
){
const
e
=
t
.
href
.
split
(
"
#
"
)[
1
]
||
""
;
if
(
!
e
.
startsWith
(
"
sdfootnote
"
)
&&!
e
.
startsWith
(
"
ftn
"
)
&&!
e
.
startsWith
(
"
_ftn
"
)){
const
e
=
document
.
createElement
(
"
a
"
);
e
.
href
=
t
.
href
,
e
.
innerHTML
=
t
.
innerHTML
,
o
.
appendChild
(
e
)}}
else
Array
.
from
(
t
.
childNodes
).
forEach
(
e
)}
else
t
.
nodeType
===
Node
.
TEXT_NODE
&&
o
.
appendChild
(
document
.
createTextNode
(
t
.
textContent
))}));
const
n
=
document
.
createElement
(
"
div
"
);
return
n
.
appendChild
(
o
),
n
.
innerHTML
.
trim
()}(
t
.
innerHTML
);
const
n
=
t
.
querySelector
(
'
.sdfootnotesym, [ href*="_ftnref"]
'
);
if
(
n
){
let
t
=
n
.
getAttribute
(
"
href
"
).
replace
(
/anc|ref|_/g
,
""
);
t
=
`#
${
t
.
split
(
"
#
"
).
pop
()}
`
;
const
r
=
e
.
querySelector
(
`.sdfootnoteanc[href*="
${
t
}
sym"], [href*="_ftn"]`
),
i
=
e
.
querySelector
(
`div
${
t
}
`
),
c
=
""
;
if
(
r
){
if
(
!
o
&&
i
.
querySelector
(
"
.MsoFootnoteReference
"
)){
const
e
=
i
.
querySelector
(
"
.MsoFootnoteReference
"
).
parentNode
;
void
0
!==
e
&&
e
.
parentNode
.
removeChild
(
e
);
const
t
=
i
.
querySelector
(
"
.MsoFootnoteText
"
);
t
&&
(
o
=
t
.
innerHTML
)}
if
(
o
){
const
e
=
function
(
e
,
t
){
const
o
=
document
.
createElement
(
"
footnotes
"
);
return
o
.
setAttribute
(
"
data-value
"
,
e
),
o
.
setAttribute
(
"
data-text
"
,
t
),
o
.
innerHTML
=
"
"
,
o
}(
c
,
o
);
s
()
&&
(
console
.
log
(
"
Created footnotes element:
"
),
console
.
log
(
e
),
console
.
log
(
"
Replacing citation element:
"
),
console
.
log
(
r
),
console
.
log
(
"
Removing anchor div:
"
),
console
.
log
(
i
)),
r
.
parentNode
.
replaceChild
(
e
,
r
),
i
.
parentNode
.
removeChild
(
i
)}}}}));
const
t
=
e
.
querySelectorAll
(
'
div[style*="mso-element:footnote-list;"]
'
);
t
&&
t
.
length
>
0
&&
t
.
forEach
((
e
=>
{
e
.
parentNode
.
removeChild
(
e
)}));
return
e
.
querySelectorAll
(
"
footnotes
"
).
forEach
((
e
=>
{
e
.
setAttribute
(
"
data-value
"
,
""
)})),
s
()
&&
(
console
.
log
(
"
Returning document fragment:
"
),
console
.
log
(
e
)),
e
}
class
c
extends
e
.
Plugin
{
static
get
requires
(){
return
[
t
.
Widget
]}
static
get
pluginName
(){
return
"
footnotesEditing
"
}
init
(){
this
.
attrs
=
{
footnotesText
:
"
data-text
"
,
footnotesValue
:
"
data-value
"
};
const
e
=
this
.
editor
.
config
.
get
(
"
footnotes
"
);
if
(
!
e
)
return
;
const
{
previewURL
:
t
,
themeError
:
o
}
=
e
;
this
.
previewUrl
=
t
,
this
.
themeError
=
o
||
`\n <p>
${
Drupal
.
t
(
"
An error occurred while trying to preview the embedded content. Please save your work and reload this page.
"
)}
<p>\n `
,
this
.
_defineSchema
(),
this
.
_defineConverters
(),
this
.
editor
.
commands
.
add
(
"
footnotes
"
,
new
r
(
this
.
editor
)),
this
.
editor
.
plugins
.
get
(
"
ClipboardPipeline
"
).
on
(
"
inputTransformation
"
,((
e
,
t
)
=>
{
const
o
=
t
.
content
,
n
=
i
(
this
.
editor
.
editing
.
view
.
domConverter
.
viewToDom
(
o
)),
r
=
this
.
editor
.
editing
.
view
.
domConverter
.
domToView
(
n
);
s
()
&&
(
console
.
log
(
"
Transformed view fragment:
"
),
console
.
log
(
r
));
const
c
=
this
.
editor
.
data
.
toModel
(
r
);
this
.
editor
.
model
.
change
((
e
=>
{
const
t
=
this
.
editor
.
model
.
document
.
selection
;
t
&&!
t
.
isCollapsed
&&
e
.
remove
(
t
.
getFirstRange
()),
this
.
editor
.
model
.
insertContent
(
c
,
t
)})),
e
.
stop
()}),{
priority
:
"
highest
"
})}
async
_fetchPreview
(
e
){
const
t
=
{
text
:
e
.
getAttribute
(
"
footnotesText
"
),
value
:
e
.
getAttribute
(
"
footnotesValue
"
)},
o
=
await
fetch
(
`
${
this
.
previewUrl
}
?
${
new
URLSearchParams
(
t
)}
`
);
return
o
.
ok
?
o
.
text
():
this
.
themeError
}
_defineSchema
(){
const
{
schema
:
e
}
=
this
.
editor
.
model
;
e
.
register
(
"
footnotes
"
,{
allowWhere
:
"
$inlineObject
"
,
blockObject
:
!
1
,
isObject
:
!
0
,
isContent
:
!
0
,
isBlock
:
!
1
,
isInline
:
!
0
,
inlineObject
:
!
0
,
allowAttributes
:
Object
.
keys
(
this
.
attrs
)}),
this
.
editor
.
editing
.
view
.
domConverter
.
blockElements
.
push
(
"
footnotes
"
)}
_defineConverters
(){
const
{
conversion
:
e
}
=
this
.
editor
;
e
.
for
(
"
upcast
"
).
elementToElement
({
view
:{
name
:
"
footnotes
"
},
model
:
"
footnotes
"
}),
e
.
for
(
"
dataDowncast
"
).
elementToElement
({
model
:
"
footnotes
"
,
view
:{
name
:
"
footnotes
"
}}),
e
.
for
(
"
editingDowncast
"
).
elementToElement
({
model
:
"
footnotes
"
,
view
:(
e
,{
writer
:
o
})
=>
{
const
n
=
o
.
createContainerElement
(
"
span
"
);
return
(
0
,
t
.
toWidget
)(
n
,
o
,{
label
:
Drupal
.
t
(
"
Footnotes
"
)})}}).
add
((
e
=>
(
e
.
on
(
"
attribute:footnotesValue:footnotes
"
,((
e
,
t
,
o
)
=>
{
const
n
=
o
.
writer
,
r
=
t
.
item
,
s
=
o
.
mapper
.
toViewElement
(
t
.
item
),
i
=
n
.
createRawElement
(
"
span
"
,{
"
data-footnotes-preview
"
:
"
loading
"
,
class
:
"
footnotes-preview
"
});
n
.
insert
(
n
.
createPositionAt
(
s
,
0
),
i
),
this
.
_fetchPreview
(
r
).
then
((
e
=>
{
i
&&
this
.
editor
.
editing
.
view
.
change
((
t
=>
{
const
o
=
t
.
createRawElement
(
"
span
"
,{
class
:
"
footnotes-preview
"
,
"
data-footnotes-preview
"
:
"
ready
"
},(
t
=>
{
t
.
innerHTML
=
e
}));
t
.
insert
(
t
.
createPositionBefore
(
i
),
o
),
t
.
remove
(
i
)}))}))})),
e
))),
Object
.
keys
(
this
.
attrs
).
forEach
((
t
=>
{
const
o
=
{
model
:{
key
:
t
,
name
:
"
footnotes
"
},
view
:{
name
:
"
footnotes
"
,
key
:
this
.
attrs
[
t
]}};
e
.
for
(
"
dataDowncast
"
).
attributeToAttribute
(
o
),
e
.
for
(
"
upcast
"
).
attributeToAttribute
(
o
)}))}}
var
a
=
o
(
"
ckeditor5/src/ui.js
"
),
d
=
o
(
"
ckeditor5/src/engine.js
"
);
class
l
extends
d
.
DomEventObserver
{
constructor
(
e
){
super
(
e
),
this
.
domEventType
=
"
dblclick
"
}
onDomEvent
(
e
){
this
.
fire
(
e
.
type
,
e
)}}
class
f
extends
e
.
Plugin
{
init
(){
const
{
editor
:
e
}
=
this
,
t
=
this
.
editor
.
config
.
get
(
"
footnotes
"
);
if
(
!
t
)
return
;
const
{
dialogURL
:
o
,
openDialog
:
n
,
dialogSettings
:
r
=
{}}
=
t
;
if
(
!
o
||
"
function
"
!=
typeof
n
)
return
;
e
.
ui
.
componentFactory
.
add
(
"
footnotes
"
,(
t
=>
{
const
s
=
e
.
commands
.
get
(
"
footnotes
"
),
i
=
new
a
.
ButtonView
(
t
);
return
i
.
set
({
label
:
Drupal
.
t
(
"
Footnotes
"
),
icon
:
'
<?xml version="1.0" standalone="no"?>
\n
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
\n
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
\n
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
\n
width="16.000000pt" height="16.000000pt" viewBox="0 0 16.000000 16.000000"
\n
preserveAspectRatio="xMidYMid meet">
\n\n
<g transform="translate(0.000000,16.000000) scale(0.100000,-0.100000)"
\n
fill="#000000" stroke="none">
\n
<path d="M115 115 c0 -14 5 -25 11 -25 7 0 9 10 6 25 -2 14 -7 25 -11 25 -3 0
\n
-6 -11 -6 -25z"/>
\n
<path d="M35 110 c-4 -6 5 -10 19 -10 14 0 26 -4 26 -10 0 -5 -8 -10 -19 -10
\n
-24 0 -45 -25 -38 -45 4 -9 19 -14 42 -13 33 1 35 3 35 38 0 20 -5 41 -12 48
\n
-15 15 -45 16 -53 2z m45 -60 c0 -5 -9 -10 -20 -10 -11 0 -20 5 -20 10 0 6 9
\n
10 20 10 11 0 20 -4 20 -10z"/>
\n
</g>
\n
</svg>
\n
'
,
tooltip
:
!
0
}),
i
.
bind
(
"
isOn
"
,
"
isEnabled
"
).
to
(
s
,
"
value
"
,
"
isEnabled
"
),
this
.
listenTo
(
i
,
"
execute
"
,(()
=>
{
const
t
=
e
.
model
.
document
.
selection
.
getSelectedElement
(),
s
=
new
URL
(
o
,
document
.
baseURI
);
t
&&
void
0
!==
t
.
name
&&
"
footnotes
"
===
t
.
name
&&
(
s
.
searchParams
.
append
(
"
text
"
,
t
.
getAttribute
(
"
footnotesText
"
)),
s
.
searchParams
.
append
(
"
value
"
,
t
.
getAttribute
(
"
footnotesValue
"
))),
n
(
s
.
toString
(),(({
attributes
:
t
})
=>
{
e
.
execute
(
"
footnotes
"
,
t
)}),
r
)})),
i
}));
const
{
view
:
s
}
=
e
.
editing
,
i
=
s
.
document
;
s
.
addObserver
(
l
),
e
.
listenTo
(
i
,
"
dblclick
"
,((
t
,
s
)
=>
{
const
i
=
e
.
editing
.
mapper
.
toModelElement
(
s
.
target
.
parent
);
if
(
i
&&
void
0
!==
i
.
name
&&
"
footnotes
"
===
i
.
name
){
const
t
=
{
text
:
i
.
getAttribute
(
"
footnotesText
"
),
value
:
i
.
getAttribute
(
"
footnotesValue
"
)};
n
(
`
${
o
}
?
${
new
URLSearchParams
(
t
)}
`
,(({
attributes
:
t
})
=>
{
e
.
execute
(
"
footnotes
"
,
t
)}),
r
)}}))}}
class
u
extends
e
.
Plugin
{
static
get
requires
(){
return
[
c
,
f
]}
static
get
pluginName
(){
return
"
footnotes
"
}}
const
m
=
{
Footnotes
:
u
}})(),
n
=
n
.
default
})()));
\ No newline at end of file
This diff is collapsed.
Click to expand it.
assets/js/ckeditor5_plugins/footnotes/src/footnotesediting.js
+
2
−
3
View file @
d2cc40df
...
...
@@ -40,7 +40,6 @@ function transformClipboardContent(documentFragment) {
function
processNode
(
node
)
{
if
(
node
.
nodeType
===
Node
.
ELEMENT_NODE
)
{
const
tagName
=
node
.
tagName
.
toLowerCase
();
if
(
tagName
===
'
b
'
||
tagName
===
'
strong
'
)
{
const
bold
=
document
.
createElement
(
'
b
'
);
bold
.
innerHTML
=
node
.
innerHTML
;
...
...
@@ -262,8 +261,8 @@ export default class Footnotesediting extends Plugin {
writer
.
remove
(
selection
.
getFirstRange
());
}
// Insert the transformed content at the selection position
(or cursor if collapsed)
.
wr
it
e
r
.
inser
t
(
modelFragment
,
selection
.
getFirstPosition
()
);
// Insert the transformed content at the selection position.
this
.
ed
it
o
r
.
model
.
insertConten
t
(
modelFragment
,
selection
);
});
// Prevent default content handling, as we've already updated the model.
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment