@ckeditor/ckeditor5-html-embed 30.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +17 -0
- package/README.md +20 -0
- package/build/html-embed.js +5 -0
- package/build/translations/cs.js +1 -0
- package/build/translations/de-ch.js +1 -0
- package/build/translations/de.js +1 -0
- package/build/translations/en-au.js +1 -0
- package/build/translations/es.js +1 -0
- package/build/translations/fr.js +1 -0
- package/build/translations/gl.js +1 -0
- package/build/translations/hr.js +1 -0
- package/build/translations/hu.js +1 -0
- package/build/translations/id.js +1 -0
- package/build/translations/it.js +1 -0
- package/build/translations/nl.js +1 -0
- package/build/translations/pl.js +1 -0
- package/build/translations/pt-br.js +1 -0
- package/build/translations/ro.js +1 -0
- package/build/translations/ru.js +1 -0
- package/build/translations/sk.js +1 -0
- package/build/translations/sl.js +1 -0
- package/build/translations/sr-latn.js +1 -0
- package/build/translations/sr.js +1 -0
- package/build/translations/uk.js +1 -0
- package/build/translations/vi.js +1 -0
- package/build/translations/zh-cn.js +1 -0
- package/ckeditor5-metadata.json +30 -0
- package/lang/contexts.json +9 -0
- package/lang/translations/cs.po +45 -0
- package/lang/translations/de-ch.po +45 -0
- package/lang/translations/de.po +45 -0
- package/lang/translations/en-au.po +45 -0
- package/lang/translations/en.po +45 -0
- package/lang/translations/es.po +45 -0
- package/lang/translations/fr.po +45 -0
- package/lang/translations/gl.po +45 -0
- package/lang/translations/hr.po +45 -0
- package/lang/translations/hu.po +45 -0
- package/lang/translations/id.po +45 -0
- package/lang/translations/it.po +45 -0
- package/lang/translations/nl.po +45 -0
- package/lang/translations/pl.po +45 -0
- package/lang/translations/pt-br.po +45 -0
- package/lang/translations/ro.po +45 -0
- package/lang/translations/ru.po +45 -0
- package/lang/translations/sk.po +45 -0
- package/lang/translations/sl.po +45 -0
- package/lang/translations/sr-latn.po +45 -0
- package/lang/translations/sr.po +45 -0
- package/lang/translations/uk.po +45 -0
- package/lang/translations/vi.po +45 -0
- package/lang/translations/zh-cn.po +45 -0
- package/package.json +58 -0
- package/src/htmlembed.js +124 -0
- package/src/htmlembedediting.js +400 -0
- package/src/htmlembedui.js +61 -0
- package/src/index.js +12 -0
- package/src/inserthtmlembedcommand.js +79 -0
- package/src/updatehtmlembedcommand.js +64 -0
- package/theme/htmlembed.css +68 -0
- package/theme/icons/html.svg +1 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @module html-embed/htmlembedui
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { Plugin } from 'ckeditor5/src/core';
|
|
11
|
+
import { ButtonView } from 'ckeditor5/src/ui';
|
|
12
|
+
|
|
13
|
+
import htmlEmbedIcon from '../theme/icons/html.svg';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The HTML embed UI plugin.
|
|
17
|
+
*
|
|
18
|
+
* @extends module:core/plugin~Plugin
|
|
19
|
+
*/
|
|
20
|
+
export default class HtmlEmbedUI extends Plugin {
|
|
21
|
+
/**
|
|
22
|
+
* @inheritDoc
|
|
23
|
+
*/
|
|
24
|
+
static get pluginName() {
|
|
25
|
+
return 'HtmlEmbedUI';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @inheritDoc
|
|
30
|
+
*/
|
|
31
|
+
init() {
|
|
32
|
+
const editor = this.editor;
|
|
33
|
+
const t = editor.t;
|
|
34
|
+
|
|
35
|
+
// Add the `htmlEmbed` button to feature components.
|
|
36
|
+
editor.ui.componentFactory.add( 'htmlEmbed', locale => {
|
|
37
|
+
const command = editor.commands.get( 'insertHtmlEmbed' );
|
|
38
|
+
const view = new ButtonView( locale );
|
|
39
|
+
|
|
40
|
+
view.set( {
|
|
41
|
+
label: t( 'Insert HTML' ),
|
|
42
|
+
icon: htmlEmbedIcon,
|
|
43
|
+
tooltip: true
|
|
44
|
+
} );
|
|
45
|
+
|
|
46
|
+
view.bind( 'isEnabled' ).to( command, 'isEnabled' );
|
|
47
|
+
|
|
48
|
+
// Execute the command.
|
|
49
|
+
this.listenTo( view, 'execute', () => {
|
|
50
|
+
editor.execute( 'insertHtmlEmbed' );
|
|
51
|
+
editor.editing.view.focus();
|
|
52
|
+
|
|
53
|
+
const widgetWrapper = editor.editing.view.document.selection.getSelectedElement();
|
|
54
|
+
|
|
55
|
+
widgetWrapper.getCustomProperty( 'rawHtmlApi' ).makeEditable();
|
|
56
|
+
} );
|
|
57
|
+
|
|
58
|
+
return view;
|
|
59
|
+
} );
|
|
60
|
+
}
|
|
61
|
+
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @module html-embed
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export { default as HtmlEmbed } from './htmlembed';
|
|
11
|
+
export { default as HtmlEmbedEditing } from './htmlembedediting';
|
|
12
|
+
export { default as HtmlEmbedUI } from './htmlembedui';
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @module html-embed/inserthtmlembedcommand
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { Command } from 'ckeditor5/src/core';
|
|
11
|
+
import { findOptimalInsertionRange } from 'ckeditor5/src/widget';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The insert HTML embed element command.
|
|
15
|
+
*
|
|
16
|
+
* The command is registered by {@link module:html-embed/htmlembedediting~HtmlEmbedEditing} as `'insertHtmlEmbed'`.
|
|
17
|
+
*
|
|
18
|
+
* To insert the HTML embed element at the current selection, execute the command:
|
|
19
|
+
*
|
|
20
|
+
* editor.execute( 'insertHtmlEmbed' );
|
|
21
|
+
*
|
|
22
|
+
* @extends module:core/command~Command
|
|
23
|
+
*/
|
|
24
|
+
export default class InsertHtmlEmbedCommand extends Command {
|
|
25
|
+
/**
|
|
26
|
+
* @inheritDoc
|
|
27
|
+
*/
|
|
28
|
+
refresh() {
|
|
29
|
+
const model = this.editor.model;
|
|
30
|
+
const schema = model.schema;
|
|
31
|
+
const selection = model.document.selection;
|
|
32
|
+
|
|
33
|
+
this.isEnabled = isHtmlEmbedAllowedInParent( selection, schema, model );
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Executes the command, which creates and inserts a new HTML embed element.
|
|
38
|
+
*
|
|
39
|
+
* @fires execute
|
|
40
|
+
*/
|
|
41
|
+
execute() {
|
|
42
|
+
const model = this.editor.model;
|
|
43
|
+
|
|
44
|
+
model.change( writer => {
|
|
45
|
+
const rawHtmlElement = writer.createElement( 'rawHtml' );
|
|
46
|
+
|
|
47
|
+
model.insertContent( rawHtmlElement );
|
|
48
|
+
writer.setSelection( rawHtmlElement, 'on' );
|
|
49
|
+
} );
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Checks if an HTML embed is allowed by the schema in the optimal insertion parent.
|
|
54
|
+
//
|
|
55
|
+
// @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection
|
|
56
|
+
// @param {module:engine/model/schema~Schema} schema
|
|
57
|
+
// @param {module:engine/model/model~Model} model Model instance.
|
|
58
|
+
// @returns {Boolean}
|
|
59
|
+
function isHtmlEmbedAllowedInParent( selection, schema, model ) {
|
|
60
|
+
const parent = getInsertHtmlEmbedParent( selection, model );
|
|
61
|
+
|
|
62
|
+
return schema.checkChild( parent, 'rawHtml' );
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Returns a node that will be used to insert a html embed with `model.insertContent` to check if a html embed element can be placed there.
|
|
66
|
+
//
|
|
67
|
+
// @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection
|
|
68
|
+
// @param {module:engine/model/model~Model} model Model instance.
|
|
69
|
+
// @returns {module:engine/model/element~Element}
|
|
70
|
+
function getInsertHtmlEmbedParent( selection, model ) {
|
|
71
|
+
const insertionRange = findOptimalInsertionRange( selection, model );
|
|
72
|
+
const parent = insertionRange.start.parent;
|
|
73
|
+
|
|
74
|
+
if ( parent.isEmpty && !parent.is( 'element', '$root' ) ) {
|
|
75
|
+
return parent.parent;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return parent;
|
|
79
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @module html-embed/updatehtmlembedcommand
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { Command } from 'ckeditor5/src/core';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The update HTML embed value command.
|
|
14
|
+
*
|
|
15
|
+
* The command is registered by {@link module:html-embed/htmlembedediting~HtmlEmbedEditing} as `'updateHtmlEmbed'`.
|
|
16
|
+
*
|
|
17
|
+
* To update the value of the HTML embed element at the current selection, execute the command:
|
|
18
|
+
*
|
|
19
|
+
* editor.execute( 'updateHtmlEmbed', '<b>HTML.</b>' );
|
|
20
|
+
*
|
|
21
|
+
* @extends module:core/command~Command
|
|
22
|
+
*/
|
|
23
|
+
export default class UpdateHtmlEmbedCommand extends Command {
|
|
24
|
+
/**
|
|
25
|
+
* @inheritDoc
|
|
26
|
+
*/
|
|
27
|
+
refresh() {
|
|
28
|
+
const model = this.editor.model;
|
|
29
|
+
const selection = model.document.selection;
|
|
30
|
+
const rawHtmlElement = getSelectedRawHtmlModelWidget( selection );
|
|
31
|
+
|
|
32
|
+
this.isEnabled = !!rawHtmlElement;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Executes the command, which updates the `value` attribute of the embedded HTML element:
|
|
37
|
+
*
|
|
38
|
+
* @fires execute
|
|
39
|
+
* @param {String} value HTML as a string.
|
|
40
|
+
*/
|
|
41
|
+
execute( value ) {
|
|
42
|
+
const model = this.editor.model;
|
|
43
|
+
const selection = model.document.selection;
|
|
44
|
+
const selectedRawHtmlElement = getSelectedRawHtmlModelWidget( selection );
|
|
45
|
+
|
|
46
|
+
model.change( writer => {
|
|
47
|
+
writer.setAttribute( 'value', value, selectedRawHtmlElement );
|
|
48
|
+
} );
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Returns the selected HTML embed element in the model, if any.
|
|
53
|
+
//
|
|
54
|
+
// @param {module:engine/model/selection~Selection} selection
|
|
55
|
+
// @returns {module:engine/model/element~Element|null}
|
|
56
|
+
function getSelectedRawHtmlModelWidget( selection ) {
|
|
57
|
+
const selectedElement = selection.getSelectedElement();
|
|
58
|
+
|
|
59
|
+
if ( selectedElement && selectedElement.is( 'element', 'rawHtml' ) ) {
|
|
60
|
+
return selectedElement;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/* The feature container. */
|
|
7
|
+
.ck-widget.raw-html-embed {
|
|
8
|
+
/* Give the embed some air. */
|
|
9
|
+
/* The first value should be equal to --ck-spacing-large variable if used in the editor context
|
|
10
|
+
to avoid the content jumping (See https://github.com/ckeditor/ckeditor5/issues/9825). */
|
|
11
|
+
margin: 0.9em auto;
|
|
12
|
+
position: relative;
|
|
13
|
+
display: flow-root;
|
|
14
|
+
|
|
15
|
+
/* Give the html embed some minimal width in the content to prevent them
|
|
16
|
+
from being "squashed" in tight spaces, e.g. in table cells (https://github.com/ckeditor/ckeditor5/issues/8331) */
|
|
17
|
+
min-width: 15em;
|
|
18
|
+
|
|
19
|
+
/* Don't inherit the style, e.g. when in a block quote. */
|
|
20
|
+
font-style: normal;
|
|
21
|
+
|
|
22
|
+
/* ----- Emebed label in the upper left corner ----------------------------------------------- */
|
|
23
|
+
|
|
24
|
+
&::before {
|
|
25
|
+
position: absolute;
|
|
26
|
+
|
|
27
|
+
/* Make sure the content does not cover the label. */
|
|
28
|
+
z-index: 1;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/* ----- Emebed internals --------------------------------------------------------------------- */
|
|
32
|
+
|
|
33
|
+
/* The switch mode button wrapper. */
|
|
34
|
+
& .raw-html-embed__buttons-wrapper {
|
|
35
|
+
position: absolute;
|
|
36
|
+
display: flex;
|
|
37
|
+
flex-direction: column;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
& .raw-html-embed__preview {
|
|
41
|
+
position: relative;
|
|
42
|
+
overflow: hidden;
|
|
43
|
+
display: flex;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
& .raw-html-embed__preview-content {
|
|
47
|
+
width: 100%;
|
|
48
|
+
position: relative;
|
|
49
|
+
margin: auto;
|
|
50
|
+
|
|
51
|
+
/* Gives spacing to the small renderable elements, so they always cover the placeholder. */
|
|
52
|
+
display: table;
|
|
53
|
+
border-collapse: separate;
|
|
54
|
+
border-spacing: 7px;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
& .raw-html-embed__preview-placeholder {
|
|
58
|
+
position: absolute;
|
|
59
|
+
left: 0;
|
|
60
|
+
top: 0;
|
|
61
|
+
right: 0;
|
|
62
|
+
bottom: 0;
|
|
63
|
+
|
|
64
|
+
display: flex;
|
|
65
|
+
align-items: center;
|
|
66
|
+
justify-content: center;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M17 0a2 2 0 0 1 2 2v7a1 1 0 0 1 1 1v5a1 1 0 0 1-.883.993l-.118.006L19 17a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2l-.001-1.001-.116-.006A1 1 0 0 1 0 15v-5a1 1 0 0 1 .999-1L1 2a2 2 0 0 1 2-2h14zm.499 15.999h-15L2.5 17a.5.5 0 0 0 .5.5h14a.5.5 0 0 0 .5-.5l-.001-1.001zm-3.478-6.013-.014.014H14v.007l-1.525 1.525-1.46-1.46-.015.013V10h-1v5h1v-3.53l1.428 1.43.048.043.131-.129L14 11.421V15h1v-5h-.965l-.014-.014zM2 10H1v5h1v-2h2v2h1v-5H4v2H2v-2zm7 0H6v1h1v4h1v-4h1v-1zm8 0h-1v5h3v-1h-2v-4zm0-8.5H3a.5.5 0 0 0-.5.5l-.001 6.999h15L17.5 2a.5.5 0 0 0-.5-.5zM10 7v1H4V7h6zm3-2v1H4V5h9zm-3-2v1H4V3h6z"/></svg>
|