mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-06-23 22:21:54 +08:00
- Allowed re-editing of existing embed HTML code. - Handled "src" form field when video is using child source tags.
This commit is contained in:
@ -14,7 +14,6 @@ import {
|
|||||||
setCommonBlockPropsFromElement,
|
setCommonBlockPropsFromElement,
|
||||||
updateElementWithCommonBlockProps
|
updateElementWithCommonBlockProps
|
||||||
} from "lexical/nodes/common";
|
} from "lexical/nodes/common";
|
||||||
import {$selectSingleNode} from "../../utils/selection";
|
|
||||||
import {SerializedCommonBlockNode} from "lexical/nodes/CommonBlockNode";
|
import {SerializedCommonBlockNode} from "lexical/nodes/CommonBlockNode";
|
||||||
|
|
||||||
export type MediaNodeTag = 'iframe' | 'embed' | 'object' | 'video' | 'audio';
|
export type MediaNodeTag = 'iframe' | 'embed' | 'object' | 'video' | 'audio';
|
||||||
@ -141,16 +140,26 @@ export class MediaNode extends ElementNode {
|
|||||||
|
|
||||||
getSources(): MediaNodeSource[] {
|
getSources(): MediaNodeSource[] {
|
||||||
const self = this.getLatest();
|
const self = this.getLatest();
|
||||||
return self.__sources;
|
return self.__sources.map(s => Object.assign({}, s))
|
||||||
}
|
}
|
||||||
|
|
||||||
setSrc(src: string): void {
|
setSrc(src: string): void {
|
||||||
const attrs = this.getAttributes();
|
const attrs = this.getAttributes();
|
||||||
|
const sources = this.getSources();
|
||||||
|
|
||||||
if (this.__tag ==='object') {
|
if (this.__tag ==='object') {
|
||||||
attrs.data = src;
|
attrs.data = src;
|
||||||
|
} if (this.__tag === 'video' && sources.length > 0) {
|
||||||
|
sources[0].src = src;
|
||||||
|
delete attrs.src;
|
||||||
|
if (sources.length > 1) {
|
||||||
|
sources.splice(1, sources.length - 1);
|
||||||
|
}
|
||||||
|
this.setSources(sources);
|
||||||
} else {
|
} else {
|
||||||
attrs.src = src;
|
attrs.src = src;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setAttributes(attrs);
|
this.setAttributes(attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,4 +28,19 @@ describe('LexicalMediaNode', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('setSrc on video uses sources if existing', () => {
|
||||||
|
const {editor} = createTestContext();
|
||||||
|
editor.updateAndCommit(() => {
|
||||||
|
const mediaMode = $createMediaNode('video');
|
||||||
|
mediaMode.setAttributes({src: 'z'});
|
||||||
|
mediaMode.setSources([{src: 'a', type: 'video'}, {src: 'b', type: 'video'}]);
|
||||||
|
|
||||||
|
mediaMode.setSrc('c');
|
||||||
|
|
||||||
|
expect(mediaMode.getAttributes().src).toBeUndefined();
|
||||||
|
expect(mediaMode.getSources()).toHaveLength(1);
|
||||||
|
expect(mediaMode.getSources()[0].src).toBe('c');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
@ -192,11 +192,17 @@ export function $showMediaForm(media: MediaNode|null, context: EditorUiContext):
|
|||||||
let formDefaults = {};
|
let formDefaults = {};
|
||||||
if (media) {
|
if (media) {
|
||||||
const nodeAttrs = media.getAttributes();
|
const nodeAttrs = media.getAttributes();
|
||||||
|
const nodeDOM = media.exportDOM(context.editor).element;
|
||||||
|
const nodeHtml = (nodeDOM instanceof HTMLElement) ? nodeDOM.outerHTML : '';
|
||||||
|
|
||||||
formDefaults = {
|
formDefaults = {
|
||||||
src: nodeAttrs.src || nodeAttrs.data || '',
|
src: nodeAttrs.src || nodeAttrs.data || media.getSources()[0]?.src || '',
|
||||||
width: nodeAttrs.width,
|
width: nodeAttrs.width,
|
||||||
height: nodeAttrs.height,
|
height: nodeAttrs.height,
|
||||||
embed: '',
|
embed: nodeHtml,
|
||||||
|
|
||||||
|
// This is used so we can check for edits against the embed field on submit
|
||||||
|
embed_check: nodeHtml,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,7 +220,8 @@ export const media: EditorFormDefinition = {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
const embedCode = (formData.get('embed') || '').toString().trim();
|
const embedCode = (formData.get('embed') || '').toString().trim();
|
||||||
if (embedCode) {
|
const embedCheck = (formData.get('embed_check') || '').toString().trim();
|
||||||
|
if (embedCode && embedCode !== embedCheck) {
|
||||||
context.editor.update(() => {
|
context.editor.update(() => {
|
||||||
const node = $createMediaNodeFromHtml(embedCode);
|
const node = $createMediaNodeFromHtml(embedCode);
|
||||||
if (selectedNode && node) {
|
if (selectedNode && node) {
|
||||||
@ -236,6 +243,7 @@ export const media: EditorFormDefinition = {
|
|||||||
if (selectedNode) {
|
if (selectedNode) {
|
||||||
selectedNode.setSrc(src);
|
selectedNode.setSrc(src);
|
||||||
selectedNode.setWidthAndHeight(width, height);
|
selectedNode.setWidthAndHeight(width, height);
|
||||||
|
context.manager.triggerFutureStateRefresh();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,6 +289,11 @@ export const media: EditorFormDefinition = {
|
|||||||
name: 'embed',
|
name: 'embed',
|
||||||
type: 'textarea',
|
type: 'textarea',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: '',
|
||||||
|
name: 'embed_check',
|
||||||
|
type: 'hidden',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
@ -11,7 +11,7 @@ import {el} from "../../utils/dom";
|
|||||||
export interface EditorFormFieldDefinition {
|
export interface EditorFormFieldDefinition {
|
||||||
label: string;
|
label: string;
|
||||||
name: string;
|
name: string;
|
||||||
type: 'text' | 'select' | 'textarea' | 'checkbox';
|
type: 'text' | 'select' | 'textarea' | 'checkbox' | 'hidden';
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EditorSelectFormFieldDefinition extends EditorFormFieldDefinition {
|
export interface EditorSelectFormFieldDefinition extends EditorFormFieldDefinition {
|
||||||
@ -67,6 +67,9 @@ export class EditorFormField extends EditorUiElement {
|
|||||||
input = el('textarea', {id, name: this.definition.name, class: 'editor-form-field-input'});
|
input = el('textarea', {id, name: this.definition.name, class: 'editor-form-field-input'});
|
||||||
} else if (this.definition.type === 'checkbox') {
|
} else if (this.definition.type === 'checkbox') {
|
||||||
input = el('input', {id, name: this.definition.name, type: 'checkbox', class: 'editor-form-field-input-checkbox', value: 'true'});
|
input = el('input', {id, name: this.definition.name, type: 'checkbox', class: 'editor-form-field-input-checkbox', value: 'true'});
|
||||||
|
} else if (this.definition.type === 'hidden') {
|
||||||
|
input = el('input', {id, name: this.definition.name, type: 'hidden'});
|
||||||
|
return el('div', {hidden: 'true'}, [input]);
|
||||||
} else {
|
} else {
|
||||||
input = el('input', {id, name: this.definition.name, class: 'editor-form-field-input'});
|
input = el('input', {id, name: this.definition.name, class: 'editor-form-field-input'});
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user