init
This commit is contained in:
26
public/tinymce/src/plugins/media/main/ts/ui/Buttons.ts
Normal file
26
public/tinymce/src/plugins/media/main/ts/ui/Buttons.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
|
||||
* Licensed under the LGPL or a commercial license.
|
||||
* For LGPL see License.txt in the project root for license information.
|
||||
* For commercial licenses see https://www.tiny.cloud/
|
||||
*/
|
||||
|
||||
const register = function (editor) {
|
||||
editor.addButton('media', {
|
||||
tooltip: 'Insert/edit media',
|
||||
cmd: 'mceMedia',
|
||||
stateSelector: ['img[data-mce-object]', 'span[data-mce-object]', 'div[data-ephox-embed-iri]']
|
||||
});
|
||||
|
||||
editor.addMenuItem('media', {
|
||||
icon: 'media',
|
||||
text: 'Media',
|
||||
cmd: 'mceMedia',
|
||||
context: 'insert',
|
||||
prependToContext: true
|
||||
});
|
||||
};
|
||||
|
||||
export default {
|
||||
register
|
||||
};
|
||||
234
public/tinymce/src/plugins/media/main/ts/ui/Dialog.ts
Normal file
234
public/tinymce/src/plugins/media/main/ts/ui/Dialog.ts
Normal file
@@ -0,0 +1,234 @@
|
||||
/**
|
||||
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
|
||||
* Licensed under the LGPL or a commercial license.
|
||||
* For LGPL see License.txt in the project root for license information.
|
||||
* For commercial licenses see https://www.tiny.cloud/
|
||||
*/
|
||||
|
||||
import Env from 'tinymce/core/api/Env';
|
||||
import Tools from 'tinymce/core/api/util/Tools';
|
||||
import Settings from '../api/Settings';
|
||||
import HtmlToData from '../core/HtmlToData';
|
||||
import Service from '../core/Service';
|
||||
import Size from '../core/Size';
|
||||
import UpdateHtml from '../core/UpdateHtml';
|
||||
import SizeManager from './SizeManager';
|
||||
|
||||
const embedChange = (Env.ie && Env.ie <= 8) ? 'onChange' : 'onInput';
|
||||
|
||||
const handleError = function (editor) {
|
||||
return function (error) {
|
||||
const errorMessage = error && error.msg ?
|
||||
'Media embed handler error: ' + error.msg :
|
||||
'Media embed handler threw unknown error.';
|
||||
editor.notificationManager.open({ type: 'error', text: errorMessage });
|
||||
};
|
||||
};
|
||||
|
||||
const getData = function (editor) {
|
||||
const element = editor.selection.getNode();
|
||||
const dataEmbed = element.getAttribute('data-ephox-embed-iri');
|
||||
|
||||
if (dataEmbed) {
|
||||
return {
|
||||
'source1': dataEmbed,
|
||||
'data-ephox-embed-iri': dataEmbed,
|
||||
'width': Size.getMaxWidth(element),
|
||||
'height': Size.getMaxHeight(element)
|
||||
};
|
||||
}
|
||||
|
||||
return element.getAttribute('data-mce-object') ?
|
||||
HtmlToData.htmlToData(Settings.getScripts(editor), editor.serializer.serialize(element, { selection: true })) :
|
||||
{};
|
||||
};
|
||||
|
||||
const getSource = function (editor) {
|
||||
const elm = editor.selection.getNode();
|
||||
|
||||
if (elm.getAttribute('data-mce-object') || elm.getAttribute('data-ephox-embed-iri')) {
|
||||
return editor.selection.getContent();
|
||||
}
|
||||
};
|
||||
|
||||
const addEmbedHtml = function (win, editor) {
|
||||
return function (response) {
|
||||
const html = response.html;
|
||||
const embed = win.find('#embed')[0];
|
||||
const data = Tools.extend(HtmlToData.htmlToData(Settings.getScripts(editor), html), { source1: response.url });
|
||||
win.fromJSON(data);
|
||||
|
||||
if (embed) {
|
||||
embed.value(html);
|
||||
SizeManager.updateSize(win);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const selectPlaceholder = function (editor, beforeObjects) {
|
||||
let i;
|
||||
let y;
|
||||
const afterObjects = editor.dom.select('img[data-mce-object]');
|
||||
|
||||
// Find new image placeholder so we can select it
|
||||
for (i = 0; i < beforeObjects.length; i++) {
|
||||
for (y = afterObjects.length - 1; y >= 0; y--) {
|
||||
if (beforeObjects[i] === afterObjects[y]) {
|
||||
afterObjects.splice(y, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
editor.selection.select(afterObjects[0]);
|
||||
};
|
||||
|
||||
const handleInsert = function (editor, html) {
|
||||
const beforeObjects = editor.dom.select('img[data-mce-object]');
|
||||
|
||||
editor.insertContent(html);
|
||||
selectPlaceholder(editor, beforeObjects);
|
||||
editor.nodeChanged();
|
||||
};
|
||||
|
||||
const submitForm = function (win, editor) {
|
||||
const data = win.toJSON();
|
||||
|
||||
data.embed = UpdateHtml.updateHtml(data.embed, data);
|
||||
|
||||
if (data.embed && Service.isCached(data.source1)) {
|
||||
handleInsert(editor, data.embed);
|
||||
} else {
|
||||
Service.getEmbedHtml(editor, data)
|
||||
.then(function (response) {
|
||||
handleInsert(editor, response.html);
|
||||
}).catch(handleError(editor));
|
||||
}
|
||||
};
|
||||
|
||||
const populateMeta = function (win, meta) {
|
||||
Tools.each(meta, function (value, key) {
|
||||
win.find('#' + key).value(value);
|
||||
});
|
||||
};
|
||||
|
||||
const showDialog = function (editor) {
|
||||
let win;
|
||||
let data;
|
||||
|
||||
const generalFormItems: any[] = [
|
||||
{
|
||||
name: 'source1',
|
||||
type: 'filepicker',
|
||||
filetype: 'media',
|
||||
size: 40,
|
||||
autofocus: true,
|
||||
label: 'Source',
|
||||
onpaste () {
|
||||
setTimeout(function () {
|
||||
Service.getEmbedHtml(editor, win.toJSON())
|
||||
.then(
|
||||
addEmbedHtml(win, editor)
|
||||
).catch(handleError(editor));
|
||||
}, 1);
|
||||
},
|
||||
onchange (e) {
|
||||
Service.getEmbedHtml(editor, win.toJSON())
|
||||
.then(
|
||||
addEmbedHtml(win, editor)
|
||||
).catch(handleError(editor));
|
||||
|
||||
populateMeta(win, e.meta);
|
||||
},
|
||||
onbeforecall (e) {
|
||||
e.meta = win.toJSON();
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
const advancedFormItems = [];
|
||||
|
||||
const reserialise = function (update) {
|
||||
update(win);
|
||||
data = win.toJSON();
|
||||
win.find('#embed').value(UpdateHtml.updateHtml(data.embed, data));
|
||||
};
|
||||
|
||||
if (Settings.hasAltSource(editor)) {
|
||||
advancedFormItems.push({ name: 'source2', type: 'filepicker', filetype: 'media', size: 40, label: 'Alternative source' });
|
||||
}
|
||||
|
||||
if (Settings.hasPoster(editor)) {
|
||||
advancedFormItems.push({ name: 'poster', type: 'filepicker', filetype: 'image', size: 40, label: 'Poster' });
|
||||
}
|
||||
|
||||
if (Settings.hasDimensions(editor)) {
|
||||
const control = SizeManager.createUi(reserialise);
|
||||
generalFormItems.push(control);
|
||||
}
|
||||
|
||||
data = getData(editor);
|
||||
|
||||
const embedTextBox = {
|
||||
id: 'mcemediasource',
|
||||
type: 'textbox',
|
||||
flex: 1,
|
||||
name: 'embed',
|
||||
value: getSource(editor),
|
||||
multiline: true,
|
||||
rows: 5,
|
||||
label: 'Source'
|
||||
};
|
||||
|
||||
const updateValueOnChange = function () {
|
||||
data = Tools.extend({}, HtmlToData.htmlToData(Settings.getScripts(editor), this.value()));
|
||||
this.parent().parent().fromJSON(data);
|
||||
};
|
||||
|
||||
embedTextBox[embedChange] = updateValueOnChange;
|
||||
|
||||
const body = [
|
||||
{
|
||||
title: 'General',
|
||||
type: 'form',
|
||||
items: generalFormItems
|
||||
},
|
||||
{
|
||||
title: 'Embed',
|
||||
type: 'container',
|
||||
layout: 'flex',
|
||||
direction: 'column',
|
||||
align: 'stretch',
|
||||
padding: 10,
|
||||
spacing: 10,
|
||||
items: [
|
||||
{
|
||||
type: 'label',
|
||||
text: 'Paste your embed code below:',
|
||||
forId: 'mcemediasource'
|
||||
},
|
||||
embedTextBox
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
if (advancedFormItems.length > 0) {
|
||||
body.push({ title: 'Advanced', type: 'form', items: advancedFormItems });
|
||||
}
|
||||
|
||||
win = editor.windowManager.open({
|
||||
title: 'Insert/edit media',
|
||||
data,
|
||||
bodyType: 'tabpanel',
|
||||
body,
|
||||
onSubmit () {
|
||||
SizeManager.updateSize(win);
|
||||
submitForm(win, editor);
|
||||
}
|
||||
});
|
||||
|
||||
SizeManager.syncSize(win);
|
||||
};
|
||||
|
||||
export default {
|
||||
showDialog
|
||||
};
|
||||
86
public/tinymce/src/plugins/media/main/ts/ui/SizeManager.ts
Normal file
86
public/tinymce/src/plugins/media/main/ts/ui/SizeManager.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
|
||||
* Licensed under the LGPL or a commercial license.
|
||||
* For LGPL see License.txt in the project root for license information.
|
||||
* For commercial licenses see https://www.tiny.cloud/
|
||||
*/
|
||||
|
||||
const doSyncSize = function (widthCtrl, heightCtrl) {
|
||||
widthCtrl.state.set('oldVal', widthCtrl.value());
|
||||
heightCtrl.state.set('oldVal', heightCtrl.value());
|
||||
};
|
||||
const doSizeControls = function (win, f) {
|
||||
const widthCtrl = win.find('#width')[0];
|
||||
const heightCtrl = win.find('#height')[0];
|
||||
const constrained = win.find('#constrain')[0];
|
||||
if (widthCtrl && heightCtrl && constrained) {
|
||||
f(widthCtrl, heightCtrl, constrained.checked());
|
||||
}
|
||||
};
|
||||
|
||||
const doUpdateSize = function (widthCtrl, heightCtrl, isContrained) {
|
||||
const oldWidth = widthCtrl.state.get('oldVal');
|
||||
const oldHeight = heightCtrl.state.get('oldVal');
|
||||
let newWidth = widthCtrl.value();
|
||||
let newHeight = heightCtrl.value();
|
||||
|
||||
if (isContrained && oldWidth && oldHeight && newWidth && newHeight) {
|
||||
if (newWidth !== oldWidth) {
|
||||
newHeight = Math.round((newWidth / oldWidth) * newHeight);
|
||||
|
||||
if (!isNaN(newHeight)) {
|
||||
heightCtrl.value(newHeight);
|
||||
}
|
||||
} else {
|
||||
newWidth = Math.round((newHeight / oldHeight) * newWidth);
|
||||
|
||||
if (!isNaN(newWidth)) {
|
||||
widthCtrl.value(newWidth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
doSyncSize(widthCtrl, heightCtrl);
|
||||
};
|
||||
|
||||
const syncSize = function (win) {
|
||||
doSizeControls(win, doSyncSize);
|
||||
};
|
||||
|
||||
const updateSize = function (win) {
|
||||
doSizeControls(win, doUpdateSize);
|
||||
};
|
||||
|
||||
const createUi = function (onChange) {
|
||||
const recalcSize = function () {
|
||||
onChange(function (win) {
|
||||
updateSize(win);
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
type: 'container',
|
||||
label: 'Dimensions',
|
||||
layout: 'flex',
|
||||
align: 'center',
|
||||
spacing: 5,
|
||||
items: [
|
||||
{
|
||||
name: 'width', type: 'textbox', maxLength: 5, size: 5,
|
||||
onchange: recalcSize, ariaLabel: 'Width'
|
||||
},
|
||||
{ type: 'label', text: 'x' },
|
||||
{
|
||||
name: 'height', type: 'textbox', maxLength: 5, size: 5,
|
||||
onchange: recalcSize, ariaLabel: 'Height'
|
||||
},
|
||||
{ name: 'constrain', type: 'checkbox', checked: true, text: 'Constrain proportions' }
|
||||
]
|
||||
};
|
||||
};
|
||||
|
||||
export default {
|
||||
createUi,
|
||||
syncSize,
|
||||
updateSize
|
||||
};
|
||||
Reference in New Issue
Block a user