MOON
Server: Apache
System: Linux nserver.cafsindia.com 4.18.0-553.104.1.lve.el8.x86_64 #1 SMP Tue Feb 10 20:07:30 UTC 2026 x86_64
User: cafsindia (1002)
PHP: 8.2.30
Disabled: NONE
Upload Files
File: /home/cafsindia/snap.cafsinfotech.in/node_modules/caret-pos/src/editable.js
/**
 * Create an Editable Caret
 * @param {Element} element The editable element
 * @param {object|null} ctx The context
 *
 * @return {EditableCaret}
 */
const createEditableCaret = (element, ctx) => {

  /**
   * Set the caret position
   *
   * @param {int} pos The position to se
   *
   * @return {Element} The element
   */
  const setPos = (pos) => {
    const sel = ctx.window.getSelection();
    if (sel) {
      let offset = 0;
      let found = false;
      const find = (position, parent) => {
        for (let i = 0; i < parent.childNodes.length; i++) {
          const node = parent.childNodes[i];
          if (found) {
            break;
          }
          if (node.nodeType === 3) {
            if (offset + node.length >= position) {
              found = true;
              const range = ctx.document.createRange();
              range.setStart(node, position - offset);
              sel.removeAllRanges();
              sel.addRange(range);
              break;
            } else {
              offset += node.length;
            }
          } else {
            find(pos, node);
          }
        }
      };
      find(pos, element);
    }

    return element;
  };

  /**
   * Get the offset
   *
   * @return {object} The offset
   */
  const getOffset = () => {
    const range = getRange();
    let offset = {
      height: 0,
      left: 0,
      right: 0,
    };

    if (!range) {
      return offset;
    }

    const hasCustomPos = ctx.customPos || ctx.customPos === 0;

    // endContainer in Firefox would be the element at the start of
    // the line
    if ((range.endOffset - 1 > 0 && range.endContainer !== element) || hasCustomPos) {
      const clonedRange = range.cloneRange();
      const fixedPosition = hasCustomPos ? ctx.customPos : range.endOffset;
      clonedRange.setStart(range.endContainer, fixedPosition - 1 < 0 ? 0 : fixedPosition - 1);
      clonedRange.setEnd(range.endContainer, fixedPosition);
      const rect = clonedRange.getBoundingClientRect();
      offset = {
        height: rect.height,
        left: rect.left + rect.width,
        top: rect.top,
      };
      clonedRange.detach();
    }

    if ((!offset || (offset && offset.height === 0)) && !ctx.noShadowCaret) {
      const clonedRange = range.cloneRange();
      const shadowCaret = ctx.document.createTextNode('|');
      clonedRange.insertNode(shadowCaret);
      clonedRange.selectNode(shadowCaret);
      const rect = clonedRange.getBoundingClientRect();
      offset = {
        height: rect.height,
        left: rect.left,
        top: rect.top,
      };
      shadowCaret.parentNode.removeChild(shadowCaret);
      clonedRange.detach();
    }

    if (offset) {
      const doc = ctx.document.documentElement;
      offset.top += ctx.window.pageYOffset - (doc.clientTop || 0);
      offset.left += ctx.window.pageXOffset - (doc.clientLeft || 0);
    }

    return offset;
  };

  /**
   * Get the position
   *
   * @return {object} The position
   */
  const getPosition = () => {
    const offset = getOffset();
    const pos = getPos();
    const rect = element.getBoundingClientRect();
    const inputOffset = {
      top: rect.top + ctx.document.body.scrollTop,
      left: rect.left + ctx.document.body.scrollLeft
    };
    offset.left -= inputOffset.left;
    offset.top -= inputOffset.top;
    offset.pos = pos;

    return offset;
  };

  /**
   * Get the range
   *
   * @return {Range|null}
   */
  const getRange = () => {
    if (!ctx.window.getSelection) {
      return;
    }
    const sel = ctx.window.getSelection();

    return sel.rangeCount > 0 ? sel.getRangeAt(0) : null;
  };

  /**
   * Get the caret position
   *
   * @return {int} The position
   */
  const getPos = () => {
    const range = getRange();
    const clonedRange = range.cloneRange();
    clonedRange.selectNodeContents(element);
    clonedRange.setEnd(range.endContainer, range.endOffset);
    const pos = clonedRange.toString().length;
    clonedRange.detach();

    return pos;
  };

  return {
    getPos,
    setPos,
    getPosition,
    getOffset,
    getRange,
  };
};

export default createEditableCaret;