all files / ui/ AnnotatedTextComponent.js

68.97% Statements 20/29
51.72% Branches 15/29
40% Functions 4/10
68.97% Lines 20/29
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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110                                                                  1032×                   1032× 1032× 1032× 1032× 103×         103×   929×   1032×       315× 315×         117× 117× 117×   117×       117×           117× 117×             117× 117×                                        
import { Fragmenter } from '../model'
import Component from './Component'
import AnnotationComponent from './AnnotationComponent'
import InlineNodeComponent from './InlineNodeComponent'
 
/**
  Renders an anotated text. Used internally by {@link ui/TextPropertyComponent}.
 
  @class
  @component
  @extends ui/Component
 
  @prop {String[]} path The property to be rendered.
*/
 
class AnnotatedTextComponent extends Component {
 
  render($$) {
    let el = this._renderContent($$)
      .addClass('sc-annotated-text')
      .css({ whiteSpace: "pre-wrap" })
    return el
  }
 
  getText() {
    return this.getDocument().get(this.props.path) || ''
  }
 
  getAnnotations() {
    return this.getDocument().getIndex('annotations').get(this.props.path)
  }
 
  _getTagName() {
    return this.props.tagName
  }
 
  _onDocumentChange(update) {
    if (update.change && update.change.updated[this.getPath()]) {
      this.rerender()
    }
  }
 
  _renderContent($$) {
    let text = this.getText();
    let annotations = this.getAnnotations()
    let el = $$(this._getTagName() || 'span')
    if (annotations && annotations.length > 0) {
      let fragmenter = new Fragmenter({
        onText: this._renderTextNode.bind(this),
        onEnter: this._renderFragment.bind(this, $$),
        onExit: this._finishFragment.bind(this)
      });
      fragmenter.start(el, text, annotations)
    } else {
      el.append(text)
    }
    return el
  }
 
  _renderTextNode(context, text) {
    Eif (text && text.length > 0) {
      context.append(text)
    }
  }
 
  _renderFragment($$, fragment) {
    let doc = this.getDocument()
    let componentRegistry = this.getComponentRegistry()
    let node = fragment.node
    // TODO: fix support for container annotations
    Iif (node.type === "container-annotation-fragment") {
      // return $$(AnnotationComponent, { doc: doc, node: node })
      //   .addClass("se-annotation-fragment")
      //   .addClass(node.anno.getTypeNames().join(' ').replace(/_/g, "-"));
    } else Iif (node.type === "container-annotation-anchor") {
      // return $$(AnnotationComponent, { doc: doc, node: node })
      //   .addClass("se-anchor")
      //   .addClass(node.anno.getTypeNames().join(' ').replace(/_/g, "-"))
      //   .addClass(node.isStart?"start-anchor":"end-anchor")
    } else {
      let ComponentClass = componentRegistry.get(node.type) || AnnotationComponent
      Iif (node.constructor.isInline &&
          // also no extra wrapping if the node is already an inline node
          !ComponentClass.prototype._isInlineNodeComponent &&
          // opt-out for custom implementations
          !ComponentClass.isCustom) {
        ComponentClass = InlineNodeComponent
      }
      let el = $$(ComponentClass, { doc: doc, node: node })
      return el
    }
  }
 
  _finishFragment(fragment, context, parentContext) {
    parentContext.append(context)
  }
 
  /**
    Gets document instance.
 
    @return {Document} The document instance
   */
  getDocument() {
    return this.props.doc || this.context.doc
  }
 
}
 
export default AnnotatedTextComponent