PageSourceSearch

https://pip.pipanz.com/assets/template_editor/richtext/lexical-editor/image-node-q4T7WDB.js

js pipanz.com collected 2026-10-07 02:29:35 UTC 4,475 bytes, 165 lines download raw bytes

1// JavaScript
2import {
3    DecoratorNode,
4    createCommand,
5} from 'lexical';
6
7// Command to insert an image
8export const INSERT_IMAGE_COMMAND = createCommand('INSERT_IMAGE_COMMAND');
9
10const CLASS_FLOAT_LEFT = 'float-left';
11const CLASS_FLOAT_RIGHT = 'float-right';
12
13const isFloating = (elm) => {
14    elm.classList.contains(CLASS_FLOAT_LEFT) || elm.classList.contains(CLASS_FLOAT_RIGHT);
15}
16
17export class ImageNode extends DecoratorNode {
18    // data needed for the image
19    __src;
20    __alt;
21    __width;
22    __height;
23    __className;
24
25    static getType() {
26        return 'image';
27    }
28
29    static clone(node) {
30        const newNode = new ImageNode(node.__src, node.__alt, node.__width, node.__height, node.__key);
31        newNode.__className = node.__className;
32        // noinspection JSValidateTypes
33        return newNode;
34    }
35
36    constructor(src, alt = '', width = null, height = null, key) {
37        super(key);
38        this.__src = src;
39        this.__alt = alt;
40        this.__width = width;
41        this.__height = height;
42        this.__className = '';
43    }
44
45    createDOM() {
46        // Not used for DecoratorNode rendering when decorate() returns React
47        const img = document.createElement('img');
48        img.src = this.__src;
49        if (this.__alt) img.alt = this.__alt;
50        if (this.__width) img.width = this.__width;
51        if (this.__height) img.height = this.__height;
52        img.className = this.__className || '';
53        // noinspection JSValidateTypes
54        return img;
55    }
56
57    decorate() {
58        const img = document.createElement('img');
59        img.src = this.__src;
60        img.alt = this.__alt || '';
61        if (this.__width) img.width = this.__width;
62        if (this.__height) img.height = this.__height;
63        img.className = this.__className || '';
64        return img;
65    }
66
67    updateDOM(prevNode, dom, config) {
68        // Keep class in sync if it changed
69        if (!prevNode.__className && isFloating(dom)
70            || !dom.classList.contains(prevNode.__className)
71        ) {
72            dom.classList = this.__className || '';
73            return true;
74        }
75        if (dom.src !== this.__src) {
76            dom.src = this.__src;
77            return true;
78        }
79        return false;
80    }
81
82    static importDOM() {
83        return {
84            'img': () => ({
85                conversion: $convertImageElement,
86                priority: 1
87            })
88        };
89    }
90
91    // Serialization (for persistence / copy paste)
92    exportJSON() {
93        return {
94            type: 'image',
95            version: 1,
96            src: this.__src,
97            alt: this.__alt,
98            width: this.__width,
99            height: this.__height,
100            className: this.__className,
101        };
102    }
103
104    static importJSON(serializedNode) {
105        const {src, alt, width, height, className} = serializedNode;
106        const node = new ImageNode(src, alt, width, height);
107        node.__className = className;
108        // noinspection JSValidateTypes
109        return node;
110    }
111
112    // Convenience getters/setters if needed
113
114    // noinspection JSUnusedGlobalSymbols
115    getSrc() {
116        return this.__src;
117    }
118    // noinspection JSUnusedGlobalSymbols
119    setSrc(src) {
120        this.__src = src;
121        this.markDirty();
122    }
123    // noinspection JSUnusedGlobalSymbols
124    getAlt() {
125        return this.__alt;
126    }
127    // noinspection JSUnusedGlobalSymbols
128    setAlt(alt) {
129        this.__alt = alt;
130        this.markDirty();
131    }
132
133    // Required: indicate if the node is inline or block. Images are usually inline or block depending on your needs.
134    isInline() {
135        return false; // false -> treat as block element (paragraph-level)
136    }
137
138    setFloat(value) {
139        if (!value || value === 'none') {
140            this.__className = '';
141        } else if (['left', 'right'].indexOf(value) !== -1) {
142            this.__className = `float-${value}`;
143        }
144        this.markDirty();
145    }
146
147    getClass() {
148        return this.__className;
149    }
150}
151
152function $convertImageElement(element) {
153    const node = $createImageNode(element.src, element.alt, element.width, element.height);
154    node.__className = element.className || '';
155    return {node};
156}
157
158// Create helper
159export function $createImageNode(src, alt = '', width = null, height = null) {
160    return new ImageNode(src, alt, width, height);
161}
162
163export function $isImageNode(node) {
164    return node instanceof ImageNode;
165}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.