ElementNode,
LexicalEditor,
LexicalNode,
- SerializedElementNode, Spread
+ Spread
} from 'lexical';
import type {EditorConfig} from "lexical/LexicalEditor";
-import {el, sizeToPixels} from "../utils/dom";
+import {el, setOrRemoveAttribute, sizeToPixels} from "../utils/dom";
import {
- CommonBlockAlignment,
+ CommonBlockAlignment, deserializeCommonBlockNode,
SerializedCommonBlockNode,
setCommonBlockPropsFromElement,
updateElementWithCommonBlockProps
} from "./_common";
-import {elem} from "../../services/dom";
import {$selectSingleNode} from "../utils/selection";
export type MediaNodeTag = 'iframe' | 'embed' | 'object' | 'video' | 'audio';
__tag: MediaNodeTag;
__attributes: Record<string, string> = {};
__sources: MediaNodeSource[] = [];
+ __inset: number = 0;
static getType() {
return 'media';
newNode.__sources = node.__sources.map(s => Object.assign({}, s));
newNode.__id = node.__id;
newNode.__alignment = node.__alignment;
+ newNode.__inset = node.__inset;
return newNode;
}
return self.__alignment;
}
+ setInset(size: number) {
+ const self = this.getWritable();
+ self.__inset = size;
+ }
+
+ getInset(): number {
+ const self = this.getLatest();
+ return self.__inset;
+ }
+
setHeight(height: number): void {
if (!height) {
return;
return true;
}
+ isParentRequired(): boolean {
+ return true;
+ }
+
createInnerDOM() {
const sources = (this.__tag === 'video' || this.__tag === 'audio') ? this.__sources : [];
const sourceEls = sources.map(source => el('source', source));
return wrap;
}
- updateDOM(prevNode: unknown, dom: HTMLElement) {
- return true;
+ updateDOM(prevNode: MediaNode, dom: HTMLElement): boolean {
+ if (prevNode.__tag !== this.__tag) {
+ return true;
+ }
+
+ if (JSON.stringify(prevNode.__sources) !== JSON.stringify(this.__sources)) {
+ return true;
+ }
+
+ if (JSON.stringify(prevNode.__attributes) !== JSON.stringify(this.__attributes)) {
+ return true;
+ }
+
+ const mediaEl = dom.firstElementChild as HTMLElement;
+
+ if (prevNode.__id !== this.__id) {
+ setOrRemoveAttribute(mediaEl, 'id', this.__id);
+ }
+
+ if (prevNode.__alignment !== this.__alignment) {
+ if (prevNode.__alignment) {
+ dom.classList.remove(`align-${prevNode.__alignment}`);
+ mediaEl.classList.remove(`align-${prevNode.__alignment}`);
+ }
+ if (this.__alignment) {
+ dom.classList.add(`align-${this.__alignment}`);
+ mediaEl.classList.add(`align-${this.__alignment}`);
+ }
+ }
+
+ if (prevNode.__inset !== this.__inset) {
+ dom.style.paddingLeft = `${this.__inset}px`;
+ }
+
+ return false;
}
static importDOM(): DOMConversionMap|null {
version: 1,
id: this.__id,
alignment: this.__alignment,
+ inset: this.__inset,
tag: this.__tag,
attributes: this.__attributes,
sources: this.__sources,
static importJSON(serializedNode: SerializedMediaNode): MediaNode {
const node = $createMediaNode(serializedNode.tag);
- node.setId(serializedNode.id);
- node.setAlignment(serializedNode.alignment);
+ deserializeCommonBlockNode(serializedNode, node);
return node;
}
const videoExtensions = ['mp4', 'mpeg', 'm4v', 'm4p', 'mov'];
const audioExtensions = ['3gp', 'aac', 'flac', 'mp3', 'm4a', 'ogg', 'wav', 'webm'];
-const iframeExtensions = ['html', 'htm', 'php', 'asp', 'aspx'];
+const iframeExtensions = ['html', 'htm', 'php', 'asp', 'aspx', ''];
export function $createMediaNodeFromSrc(src: string): MediaNode {
let nodeTag: MediaNodeTag = 'iframe';
const srcEnd = src.split('?')[0].split('/').pop() || '';
- const extension = (srcEnd.split('.').pop() || '').toLowerCase();
+ const srcEndSplit = srcEnd.split('.');
+ const extension = (srcEndSplit.length > 1 ? srcEndSplit[srcEndSplit.length - 1] : '').toLowerCase();
if (videoExtensions.includes(extension)) {
nodeTag = 'video';
} else if (audioExtensions.includes(extension)) {