Beispiel #1
0
 static fromNode(renderTree, node, offset) {
   if (isTextNode(node)) {
     return Position.fromTextNode(renderTree, node, offset);
   } else {
     return Position.fromElementNode(renderTree, node, offset);
   }
 }
function constrainNodeTo(node, parentNode, existingOffset) {
  let compare = parentNode.compareDocumentPosition(node);
  if (compare & Node.DOCUMENT_POSITION_CONTAINED_BY) {
    // the node is inside parentNode, do nothing
    return { node, offset: existingOffset};
  } else if (compare & Node.DOCUMENT_POSITION_CONTAINS) {
    // the node contains parentNode. This shouldn't happen.
    return { node, offset: existingOffset};
  } else if (compare & Node.DOCUMENT_POSITION_PRECEDING) {
    // node is before parentNode. return start of deepest first child
    let child = parentNode.firstChild;
    while (child.firstChild) {
      child = child.firstChild;
    }
    return { node: child, offset: 0};
  } else if (compare & Node.DOCUMENT_POSITION_FOLLOWING) {
    // node is after parentNode. return end of deepest last child
    let child = parentNode.lastChild;
    while (child.lastChild) {
      child = child.lastChild;
    }

    let offset = isTextNode(child) ? child.textContent.length : 1;
    return {node: child, offset};
  } else {
    return { node, offset: existingOffset};
  }
}
Beispiel #3
0
  _getSectionDetails(element) {
    let sectionType,
        tagName,
        inferredTagName = false;
    if (isTextNode(element)) {
      tagName = DEFAULT_TAG_NAME;
      sectionType = MARKUP_SECTION_TYPE;
      inferredTagName = true;
    } else {
      tagName = normalizeTagName(element.tagName);

      if (contains(VALID_LIST_SECTION_TAGNAMES, tagName)) {
        sectionType = LIST_SECTION_TYPE;
      } else if (contains(VALID_LIST_ITEM_TAGNAMES, tagName)) {
        sectionType = LIST_ITEM_TYPE;
      } else if (contains(VALID_MARKUP_SECTION_TAGNAMES, tagName)) {
        sectionType = MARKUP_SECTION_TYPE;
      } else {
        sectionType = MARKUP_SECTION_TYPE;
        tagName = DEFAULT_TAG_NAME;
        inferredTagName = true;
      }
    }

    return {sectionType, tagName, inferredTagName};
  }
/*
 * @param {Object} coords with `top` and `left`
 * @see https://github.com/ProseMirror/prosemirror/blob/4c22e3fe97d87a355a0534e25d65aaf0c0d83e57/src/edit/dompos.js
 * @return {Object} {node, offset}
 */
/* eslint-disable complexity */
function findOffsetInNode(node, coords) {
  let closest, dyClosest = 1e8, coordsClosest, offset = 0;
  for (let child = node.firstChild; child; child = child.nextSibling) {
    let rects;
    if (isElementNode(child)) {
      rects = child.getClientRects();
    } else if (isTextNode(child)) {
      rects = textNodeRects(child);
    } else {
      continue;
    }

    for (let i = 0; i < rects.length; i++) {
      let rect = rects[i];
      if (rect.left <= coords.left && rect.right >= coords.left) {
        let dy = rect.top > coords.top ? rect.top - coords.top
            : rect.bottom < coords.top ? coords.top - rect.bottom : 0;
        if (dy < dyClosest) {
          closest = child;
          dyClosest = dy;
          coordsClosest = dy ? {left: coords.left, top: rect.top} : coords;
          if (isElementNode(child) && !child.firstChild) {
            offset = i + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0);
          }
          continue;
        }
      }
      if (!closest &&
          (coords.top >= rect.bottom || coords.top >= rect.top && coords.left >= rect.right)) {
        offset = i + 1;
      }
    }
  }
  if (!closest) {
    return {node, offset};
  }
  if (isTextNode(closest)) {
    return findOffsetInTextNode(closest, coordsClosest);
  }
  if (closest.firstChild) {
    return findOffsetInNode(closest, coordsClosest);
  }
  return {node, offset};
}
Beispiel #5
0
  _markupsFromElement(element) {
    let { builder } = this;
    let markups = [];
    if (isTextNode(element)) {
      return markups;
    }

    const tagName = normalizeTagName(element.tagName);
    if (this._isValidMarkupForElement(tagName, element)) {
      markups.push(builder.createMarkup(tagName, getAttributes(element)));
    }

    this._markupsFromElementStyle(element).forEach(
      markup => markups.push(markup)
    );

    return markups;
  }
Beispiel #6
0
  parse(element) {
    if (this._isSkippable(element)) {
      return [];
    }
    this.sections = [];
    this.state = {};

    this._updateStateFromElement(element);

    let childNodes = isTextNode(element) ? [element] : element.childNodes;

    if (this.state.section.isListSection) {
      this.parseListItems(childNodes);
    } else {
      forEach(childNodes, el => {
        this.parseNode(el);
      });
    }

    this._closeCurrentSection();

    return this.sections;
  }
Beispiel #7
0
 return walkDOMUntil(parentElement, node => {
   return isTextNode(node) && node.textContent.indexOf(text) !== -1;
 });