zhangjian
2023-06-05 0976d2d0f90cff460cedfdc8bd74e98c2c31a58c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import FormatBlot from './abstract/format';
import LeafBlot from './abstract/leaf';
import ShadowBlot from './abstract/shadow';
import * as Registry from '../registry';
 
// Shallow object comparison
function isEqual(obj1: Object, obj2: Object): boolean {
  if (Object.keys(obj1).length !== Object.keys(obj2).length) return false;
  // @ts-ignore
  for (let prop in obj1) {
    // @ts-ignore
    if (obj1[prop] !== obj2[prop]) return false;
  }
  return true;
}
 
class InlineBlot extends FormatBlot {
  static blotName = 'inline';
  static scope = Registry.Scope.INLINE_BLOT;
  static tagName = 'SPAN';
 
  static formats(domNode: HTMLElement): any {
    if (domNode.tagName === InlineBlot.tagName) return undefined;
    return super.formats(domNode);
  }
 
  format(name: string, value: any) {
    if (name === this.statics.blotName && !value) {
      this.children.forEach(child => {
        if (!(child instanceof FormatBlot)) {
          child = child.wrap(InlineBlot.blotName, true);
        }
        this.attributes.copy(<FormatBlot>child);
      });
      this.unwrap();
    } else {
      super.format(name, value);
    }
  }
 
  formatAt(index: number, length: number, name: string, value: any): void {
    if (this.formats()[name] != null || Registry.query(name, Registry.Scope.ATTRIBUTE)) {
      let blot = <InlineBlot>this.isolate(index, length);
      blot.format(name, value);
    } else {
      super.formatAt(index, length, name, value);
    }
  }
 
  optimize(context: { [key: string]: any }): void {
    super.optimize(context);
    let formats = this.formats();
    if (Object.keys(formats).length === 0) {
      return this.unwrap(); // unformatted span
    }
    let next = this.next;
    if (next instanceof InlineBlot && next.prev === this && isEqual(formats, next.formats())) {
      next.moveChildren(this);
      next.remove();
    }
  }
}
 
export default InlineBlot;