You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							752 lines
						
					
					
						
							23 KiB
						
					
					
				
			
		
		
	
	
							752 lines
						
					
					
						
							23 KiB
						
					
					
				| (function (global, factory) {
 | |
| 	typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@tiptap/core'), require('prosemirror-state'), require('tippy.js')) :
 | |
| 	typeof define === 'function' && define.amd ? define(['exports', '@tiptap/core', 'prosemirror-state', 'tippy.js'], factory) :
 | |
| 	(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["@tiptap/extension-bubble-menu"] = {}, global.core, global.prosemirrorState, global.tippy));
 | |
| })(this, (function (exports, core, prosemirrorState, tippy) { 'use strict';
 | |
| 
 | |
| 	function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
 | |
| 
 | |
| 	var tippy__default = /*#__PURE__*/_interopDefaultLegacy(tippy);
 | |
| 
 | |
| 	var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
 | |
| 
 | |
| 	/**
 | |
| 	 * Checks if `value` is the
 | |
| 	 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
 | |
| 	 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
 | |
| 	 *
 | |
| 	 * @static
 | |
| 	 * @memberOf _
 | |
| 	 * @since 0.1.0
 | |
| 	 * @category Lang
 | |
| 	 * @param {*} value The value to check.
 | |
| 	 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
 | |
| 	 * @example
 | |
| 	 *
 | |
| 	 * _.isObject({});
 | |
| 	 * // => true
 | |
| 	 *
 | |
| 	 * _.isObject([1, 2, 3]);
 | |
| 	 * // => true
 | |
| 	 *
 | |
| 	 * _.isObject(_.noop);
 | |
| 	 * // => true
 | |
| 	 *
 | |
| 	 * _.isObject(null);
 | |
| 	 * // => false
 | |
| 	 */
 | |
| 
 | |
| 	function isObject$2(value) {
 | |
| 	  var type = typeof value;
 | |
| 	  return value != null && (type == 'object' || type == 'function');
 | |
| 	}
 | |
| 
 | |
| 	var isObject_1 = isObject$2;
 | |
| 
 | |
| 	/** Detect free variable `global` from Node.js. */
 | |
| 
 | |
| 	var freeGlobal$1 = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
 | |
| 
 | |
| 	var _freeGlobal = freeGlobal$1;
 | |
| 
 | |
| 	var freeGlobal = _freeGlobal;
 | |
| 
 | |
| 	/** Detect free variable `self`. */
 | |
| 	var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
 | |
| 
 | |
| 	/** Used as a reference to the global object. */
 | |
| 	var root$2 = freeGlobal || freeSelf || Function('return this')();
 | |
| 
 | |
| 	var _root = root$2;
 | |
| 
 | |
| 	var root$1 = _root;
 | |
| 
 | |
| 	/**
 | |
| 	 * Gets the timestamp of the number of milliseconds that have elapsed since
 | |
| 	 * the Unix epoch (1 January 1970 00:00:00 UTC).
 | |
| 	 *
 | |
| 	 * @static
 | |
| 	 * @memberOf _
 | |
| 	 * @since 2.4.0
 | |
| 	 * @category Date
 | |
| 	 * @returns {number} Returns the timestamp.
 | |
| 	 * @example
 | |
| 	 *
 | |
| 	 * _.defer(function(stamp) {
 | |
| 	 *   console.log(_.now() - stamp);
 | |
| 	 * }, _.now());
 | |
| 	 * // => Logs the number of milliseconds it took for the deferred invocation.
 | |
| 	 */
 | |
| 	var now$1 = function() {
 | |
| 	  return root$1.Date.now();
 | |
| 	};
 | |
| 
 | |
| 	var now_1 = now$1;
 | |
| 
 | |
| 	/** Used to match a single whitespace character. */
 | |
| 
 | |
| 	var reWhitespace = /\s/;
 | |
| 
 | |
| 	/**
 | |
| 	 * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace
 | |
| 	 * character of `string`.
 | |
| 	 *
 | |
| 	 * @private
 | |
| 	 * @param {string} string The string to inspect.
 | |
| 	 * @returns {number} Returns the index of the last non-whitespace character.
 | |
| 	 */
 | |
| 	function trimmedEndIndex$1(string) {
 | |
| 	  var index = string.length;
 | |
| 
 | |
| 	  while (index-- && reWhitespace.test(string.charAt(index))) {}
 | |
| 	  return index;
 | |
| 	}
 | |
| 
 | |
| 	var _trimmedEndIndex = trimmedEndIndex$1;
 | |
| 
 | |
| 	var trimmedEndIndex = _trimmedEndIndex;
 | |
| 
 | |
| 	/** Used to match leading whitespace. */
 | |
| 	var reTrimStart = /^\s+/;
 | |
| 
 | |
| 	/**
 | |
| 	 * The base implementation of `_.trim`.
 | |
| 	 *
 | |
| 	 * @private
 | |
| 	 * @param {string} string The string to trim.
 | |
| 	 * @returns {string} Returns the trimmed string.
 | |
| 	 */
 | |
| 	function baseTrim$1(string) {
 | |
| 	  return string
 | |
| 	    ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '')
 | |
| 	    : string;
 | |
| 	}
 | |
| 
 | |
| 	var _baseTrim = baseTrim$1;
 | |
| 
 | |
| 	var root = _root;
 | |
| 
 | |
| 	/** Built-in value references. */
 | |
| 	var Symbol$2 = root.Symbol;
 | |
| 
 | |
| 	var _Symbol = Symbol$2;
 | |
| 
 | |
| 	var Symbol$1 = _Symbol;
 | |
| 
 | |
| 	/** Used for built-in method references. */
 | |
| 	var objectProto$1 = Object.prototype;
 | |
| 
 | |
| 	/** Used to check objects for own properties. */
 | |
| 	var hasOwnProperty = objectProto$1.hasOwnProperty;
 | |
| 
 | |
| 	/**
 | |
| 	 * Used to resolve the
 | |
| 	 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
 | |
| 	 * of values.
 | |
| 	 */
 | |
| 	var nativeObjectToString$1 = objectProto$1.toString;
 | |
| 
 | |
| 	/** Built-in value references. */
 | |
| 	var symToStringTag$1 = Symbol$1 ? Symbol$1.toStringTag : undefined;
 | |
| 
 | |
| 	/**
 | |
| 	 * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
 | |
| 	 *
 | |
| 	 * @private
 | |
| 	 * @param {*} value The value to query.
 | |
| 	 * @returns {string} Returns the raw `toStringTag`.
 | |
| 	 */
 | |
| 	function getRawTag$1(value) {
 | |
| 	  var isOwn = hasOwnProperty.call(value, symToStringTag$1),
 | |
| 	      tag = value[symToStringTag$1];
 | |
| 
 | |
| 	  try {
 | |
| 	    value[symToStringTag$1] = undefined;
 | |
| 	    var unmasked = true;
 | |
| 	  } catch (e) {}
 | |
| 
 | |
| 	  var result = nativeObjectToString$1.call(value);
 | |
| 	  if (unmasked) {
 | |
| 	    if (isOwn) {
 | |
| 	      value[symToStringTag$1] = tag;
 | |
| 	    } else {
 | |
| 	      delete value[symToStringTag$1];
 | |
| 	    }
 | |
| 	  }
 | |
| 	  return result;
 | |
| 	}
 | |
| 
 | |
| 	var _getRawTag = getRawTag$1;
 | |
| 
 | |
| 	/** Used for built-in method references. */
 | |
| 
 | |
| 	var objectProto = Object.prototype;
 | |
| 
 | |
| 	/**
 | |
| 	 * Used to resolve the
 | |
| 	 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
 | |
| 	 * of values.
 | |
| 	 */
 | |
| 	var nativeObjectToString = objectProto.toString;
 | |
| 
 | |
| 	/**
 | |
| 	 * Converts `value` to a string using `Object.prototype.toString`.
 | |
| 	 *
 | |
| 	 * @private
 | |
| 	 * @param {*} value The value to convert.
 | |
| 	 * @returns {string} Returns the converted string.
 | |
| 	 */
 | |
| 	function objectToString$1(value) {
 | |
| 	  return nativeObjectToString.call(value);
 | |
| 	}
 | |
| 
 | |
| 	var _objectToString = objectToString$1;
 | |
| 
 | |
| 	var Symbol = _Symbol,
 | |
| 	    getRawTag = _getRawTag,
 | |
| 	    objectToString = _objectToString;
 | |
| 
 | |
| 	/** `Object#toString` result references. */
 | |
| 	var nullTag = '[object Null]',
 | |
| 	    undefinedTag = '[object Undefined]';
 | |
| 
 | |
| 	/** Built-in value references. */
 | |
| 	var symToStringTag = Symbol ? Symbol.toStringTag : undefined;
 | |
| 
 | |
| 	/**
 | |
| 	 * The base implementation of `getTag` without fallbacks for buggy environments.
 | |
| 	 *
 | |
| 	 * @private
 | |
| 	 * @param {*} value The value to query.
 | |
| 	 * @returns {string} Returns the `toStringTag`.
 | |
| 	 */
 | |
| 	function baseGetTag$1(value) {
 | |
| 	  if (value == null) {
 | |
| 	    return value === undefined ? undefinedTag : nullTag;
 | |
| 	  }
 | |
| 	  return (symToStringTag && symToStringTag in Object(value))
 | |
| 	    ? getRawTag(value)
 | |
| 	    : objectToString(value);
 | |
| 	}
 | |
| 
 | |
| 	var _baseGetTag = baseGetTag$1;
 | |
| 
 | |
| 	/**
 | |
| 	 * Checks if `value` is object-like. A value is object-like if it's not `null`
 | |
| 	 * and has a `typeof` result of "object".
 | |
| 	 *
 | |
| 	 * @static
 | |
| 	 * @memberOf _
 | |
| 	 * @since 4.0.0
 | |
| 	 * @category Lang
 | |
| 	 * @param {*} value The value to check.
 | |
| 	 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
 | |
| 	 * @example
 | |
| 	 *
 | |
| 	 * _.isObjectLike({});
 | |
| 	 * // => true
 | |
| 	 *
 | |
| 	 * _.isObjectLike([1, 2, 3]);
 | |
| 	 * // => true
 | |
| 	 *
 | |
| 	 * _.isObjectLike(_.noop);
 | |
| 	 * // => false
 | |
| 	 *
 | |
| 	 * _.isObjectLike(null);
 | |
| 	 * // => false
 | |
| 	 */
 | |
| 
 | |
| 	function isObjectLike$1(value) {
 | |
| 	  return value != null && typeof value == 'object';
 | |
| 	}
 | |
| 
 | |
| 	var isObjectLike_1 = isObjectLike$1;
 | |
| 
 | |
| 	var baseGetTag = _baseGetTag,
 | |
| 	    isObjectLike = isObjectLike_1;
 | |
| 
 | |
| 	/** `Object#toString` result references. */
 | |
| 	var symbolTag = '[object Symbol]';
 | |
| 
 | |
| 	/**
 | |
| 	 * Checks if `value` is classified as a `Symbol` primitive or object.
 | |
| 	 *
 | |
| 	 * @static
 | |
| 	 * @memberOf _
 | |
| 	 * @since 4.0.0
 | |
| 	 * @category Lang
 | |
| 	 * @param {*} value The value to check.
 | |
| 	 * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
 | |
| 	 * @example
 | |
| 	 *
 | |
| 	 * _.isSymbol(Symbol.iterator);
 | |
| 	 * // => true
 | |
| 	 *
 | |
| 	 * _.isSymbol('abc');
 | |
| 	 * // => false
 | |
| 	 */
 | |
| 	function isSymbol$1(value) {
 | |
| 	  return typeof value == 'symbol' ||
 | |
| 	    (isObjectLike(value) && baseGetTag(value) == symbolTag);
 | |
| 	}
 | |
| 
 | |
| 	var isSymbol_1 = isSymbol$1;
 | |
| 
 | |
| 	var baseTrim = _baseTrim,
 | |
| 	    isObject$1 = isObject_1,
 | |
| 	    isSymbol = isSymbol_1;
 | |
| 
 | |
| 	/** Used as references for various `Number` constants. */
 | |
| 	var NAN = 0 / 0;
 | |
| 
 | |
| 	/** Used to detect bad signed hexadecimal string values. */
 | |
| 	var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
 | |
| 
 | |
| 	/** Used to detect binary string values. */
 | |
| 	var reIsBinary = /^0b[01]+$/i;
 | |
| 
 | |
| 	/** Used to detect octal string values. */
 | |
| 	var reIsOctal = /^0o[0-7]+$/i;
 | |
| 
 | |
| 	/** Built-in method references without a dependency on `root`. */
 | |
| 	var freeParseInt = parseInt;
 | |
| 
 | |
| 	/**
 | |
| 	 * Converts `value` to a number.
 | |
| 	 *
 | |
| 	 * @static
 | |
| 	 * @memberOf _
 | |
| 	 * @since 4.0.0
 | |
| 	 * @category Lang
 | |
| 	 * @param {*} value The value to process.
 | |
| 	 * @returns {number} Returns the number.
 | |
| 	 * @example
 | |
| 	 *
 | |
| 	 * _.toNumber(3.2);
 | |
| 	 * // => 3.2
 | |
| 	 *
 | |
| 	 * _.toNumber(Number.MIN_VALUE);
 | |
| 	 * // => 5e-324
 | |
| 	 *
 | |
| 	 * _.toNumber(Infinity);
 | |
| 	 * // => Infinity
 | |
| 	 *
 | |
| 	 * _.toNumber('3.2');
 | |
| 	 * // => 3.2
 | |
| 	 */
 | |
| 	function toNumber$1(value) {
 | |
| 	  if (typeof value == 'number') {
 | |
| 	    return value;
 | |
| 	  }
 | |
| 	  if (isSymbol(value)) {
 | |
| 	    return NAN;
 | |
| 	  }
 | |
| 	  if (isObject$1(value)) {
 | |
| 	    var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
 | |
| 	    value = isObject$1(other) ? (other + '') : other;
 | |
| 	  }
 | |
| 	  if (typeof value != 'string') {
 | |
| 	    return value === 0 ? value : +value;
 | |
| 	  }
 | |
| 	  value = baseTrim(value);
 | |
| 	  var isBinary = reIsBinary.test(value);
 | |
| 	  return (isBinary || reIsOctal.test(value))
 | |
| 	    ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
 | |
| 	    : (reIsBadHex.test(value) ? NAN : +value);
 | |
| 	}
 | |
| 
 | |
| 	var toNumber_1 = toNumber$1;
 | |
| 
 | |
| 	var isObject = isObject_1,
 | |
| 	    now = now_1,
 | |
| 	    toNumber = toNumber_1;
 | |
| 
 | |
| 	/** Error message constants. */
 | |
| 	var FUNC_ERROR_TEXT = 'Expected a function';
 | |
| 
 | |
| 	/* Built-in method references for those with the same name as other `lodash` methods. */
 | |
| 	var nativeMax = Math.max,
 | |
| 	    nativeMin = Math.min;
 | |
| 
 | |
| 	/**
 | |
| 	 * Creates a debounced function that delays invoking `func` until after `wait`
 | |
| 	 * milliseconds have elapsed since the last time the debounced function was
 | |
| 	 * invoked. The debounced function comes with a `cancel` method to cancel
 | |
| 	 * delayed `func` invocations and a `flush` method to immediately invoke them.
 | |
| 	 * Provide `options` to indicate whether `func` should be invoked on the
 | |
| 	 * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
 | |
| 	 * with the last arguments provided to the debounced function. Subsequent
 | |
| 	 * calls to the debounced function return the result of the last `func`
 | |
| 	 * invocation.
 | |
| 	 *
 | |
| 	 * **Note:** If `leading` and `trailing` options are `true`, `func` is
 | |
| 	 * invoked on the trailing edge of the timeout only if the debounced function
 | |
| 	 * is invoked more than once during the `wait` timeout.
 | |
| 	 *
 | |
| 	 * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
 | |
| 	 * until to the next tick, similar to `setTimeout` with a timeout of `0`.
 | |
| 	 *
 | |
| 	 * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
 | |
| 	 * for details over the differences between `_.debounce` and `_.throttle`.
 | |
| 	 *
 | |
| 	 * @static
 | |
| 	 * @memberOf _
 | |
| 	 * @since 0.1.0
 | |
| 	 * @category Function
 | |
| 	 * @param {Function} func The function to debounce.
 | |
| 	 * @param {number} [wait=0] The number of milliseconds to delay.
 | |
| 	 * @param {Object} [options={}] The options object.
 | |
| 	 * @param {boolean} [options.leading=false]
 | |
| 	 *  Specify invoking on the leading edge of the timeout.
 | |
| 	 * @param {number} [options.maxWait]
 | |
| 	 *  The maximum time `func` is allowed to be delayed before it's invoked.
 | |
| 	 * @param {boolean} [options.trailing=true]
 | |
| 	 *  Specify invoking on the trailing edge of the timeout.
 | |
| 	 * @returns {Function} Returns the new debounced function.
 | |
| 	 * @example
 | |
| 	 *
 | |
| 	 * // Avoid costly calculations while the window size is in flux.
 | |
| 	 * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
 | |
| 	 *
 | |
| 	 * // Invoke `sendMail` when clicked, debouncing subsequent calls.
 | |
| 	 * jQuery(element).on('click', _.debounce(sendMail, 300, {
 | |
| 	 *   'leading': true,
 | |
| 	 *   'trailing': false
 | |
| 	 * }));
 | |
| 	 *
 | |
| 	 * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
 | |
| 	 * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
 | |
| 	 * var source = new EventSource('/stream');
 | |
| 	 * jQuery(source).on('message', debounced);
 | |
| 	 *
 | |
| 	 * // Cancel the trailing debounced invocation.
 | |
| 	 * jQuery(window).on('popstate', debounced.cancel);
 | |
| 	 */
 | |
| 	function debounce(func, wait, options) {
 | |
| 	  var lastArgs,
 | |
| 	      lastThis,
 | |
| 	      maxWait,
 | |
| 	      result,
 | |
| 	      timerId,
 | |
| 	      lastCallTime,
 | |
| 	      lastInvokeTime = 0,
 | |
| 	      leading = false,
 | |
| 	      maxing = false,
 | |
| 	      trailing = true;
 | |
| 
 | |
| 	  if (typeof func != 'function') {
 | |
| 	    throw new TypeError(FUNC_ERROR_TEXT);
 | |
| 	  }
 | |
| 	  wait = toNumber(wait) || 0;
 | |
| 	  if (isObject(options)) {
 | |
| 	    leading = !!options.leading;
 | |
| 	    maxing = 'maxWait' in options;
 | |
| 	    maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
 | |
| 	    trailing = 'trailing' in options ? !!options.trailing : trailing;
 | |
| 	  }
 | |
| 
 | |
| 	  function invokeFunc(time) {
 | |
| 	    var args = lastArgs,
 | |
| 	        thisArg = lastThis;
 | |
| 
 | |
| 	    lastArgs = lastThis = undefined;
 | |
| 	    lastInvokeTime = time;
 | |
| 	    result = func.apply(thisArg, args);
 | |
| 	    return result;
 | |
| 	  }
 | |
| 
 | |
| 	  function leadingEdge(time) {
 | |
| 	    // Reset any `maxWait` timer.
 | |
| 	    lastInvokeTime = time;
 | |
| 	    // Start the timer for the trailing edge.
 | |
| 	    timerId = setTimeout(timerExpired, wait);
 | |
| 	    // Invoke the leading edge.
 | |
| 	    return leading ? invokeFunc(time) : result;
 | |
| 	  }
 | |
| 
 | |
| 	  function remainingWait(time) {
 | |
| 	    var timeSinceLastCall = time - lastCallTime,
 | |
| 	        timeSinceLastInvoke = time - lastInvokeTime,
 | |
| 	        timeWaiting = wait - timeSinceLastCall;
 | |
| 
 | |
| 	    return maxing
 | |
| 	      ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)
 | |
| 	      : timeWaiting;
 | |
| 	  }
 | |
| 
 | |
| 	  function shouldInvoke(time) {
 | |
| 	    var timeSinceLastCall = time - lastCallTime,
 | |
| 	        timeSinceLastInvoke = time - lastInvokeTime;
 | |
| 
 | |
| 	    // Either this is the first call, activity has stopped and we're at the
 | |
| 	    // trailing edge, the system time has gone backwards and we're treating
 | |
| 	    // it as the trailing edge, or we've hit the `maxWait` limit.
 | |
| 	    return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
 | |
| 	      (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
 | |
| 	  }
 | |
| 
 | |
| 	  function timerExpired() {
 | |
| 	    var time = now();
 | |
| 	    if (shouldInvoke(time)) {
 | |
| 	      return trailingEdge(time);
 | |
| 	    }
 | |
| 	    // Restart the timer.
 | |
| 	    timerId = setTimeout(timerExpired, remainingWait(time));
 | |
| 	  }
 | |
| 
 | |
| 	  function trailingEdge(time) {
 | |
| 	    timerId = undefined;
 | |
| 
 | |
| 	    // Only invoke if we have `lastArgs` which means `func` has been
 | |
| 	    // debounced at least once.
 | |
| 	    if (trailing && lastArgs) {
 | |
| 	      return invokeFunc(time);
 | |
| 	    }
 | |
| 	    lastArgs = lastThis = undefined;
 | |
| 	    return result;
 | |
| 	  }
 | |
| 
 | |
| 	  function cancel() {
 | |
| 	    if (timerId !== undefined) {
 | |
| 	      clearTimeout(timerId);
 | |
| 	    }
 | |
| 	    lastInvokeTime = 0;
 | |
| 	    lastArgs = lastCallTime = lastThis = timerId = undefined;
 | |
| 	  }
 | |
| 
 | |
| 	  function flush() {
 | |
| 	    return timerId === undefined ? result : trailingEdge(now());
 | |
| 	  }
 | |
| 
 | |
| 	  function debounced() {
 | |
| 	    var time = now(),
 | |
| 	        isInvoking = shouldInvoke(time);
 | |
| 
 | |
| 	    lastArgs = arguments;
 | |
| 	    lastThis = this;
 | |
| 	    lastCallTime = time;
 | |
| 
 | |
| 	    if (isInvoking) {
 | |
| 	      if (timerId === undefined) {
 | |
| 	        return leadingEdge(lastCallTime);
 | |
| 	      }
 | |
| 	      if (maxing) {
 | |
| 	        // Handle invocations in a tight loop.
 | |
| 	        clearTimeout(timerId);
 | |
| 	        timerId = setTimeout(timerExpired, wait);
 | |
| 	        return invokeFunc(lastCallTime);
 | |
| 	      }
 | |
| 	    }
 | |
| 	    if (timerId === undefined) {
 | |
| 	      timerId = setTimeout(timerExpired, wait);
 | |
| 	    }
 | |
| 	    return result;
 | |
| 	  }
 | |
| 	  debounced.cancel = cancel;
 | |
| 	  debounced.flush = flush;
 | |
| 	  return debounced;
 | |
| 	}
 | |
| 
 | |
| 	var debounce_1 = debounce;
 | |
| 
 | |
| 	class BubbleMenuView {
 | |
| 	    constructor({ editor, element, view, tippyOptions = {}, updateDelay = 250, shouldShow, }) {
 | |
| 	        this.preventHide = false;
 | |
| 	        this.shouldShow = ({ view, state, from, to, }) => {
 | |
| 	            const { doc, selection } = state;
 | |
| 	            const { empty } = selection;
 | |
| 	            // Sometime check for `empty` is not enough.
 | |
| 	            // Doubleclick an empty paragraph returns a node size of 2.
 | |
| 	            // So we check also for an empty text size.
 | |
| 	            const isEmptyTextBlock = !doc.textBetween(from, to).length
 | |
| 	                && core.isTextSelection(state.selection);
 | |
| 	            // When clicking on a element inside the bubble menu the editor "blur" event
 | |
| 	            // is called and the bubble menu item is focussed. In this case we should
 | |
| 	            // consider the menu as part of the editor and keep showing the menu
 | |
| 	            const isChildOfMenu = this.element.contains(document.activeElement);
 | |
| 	            const hasEditorFocus = view.hasFocus() || isChildOfMenu;
 | |
| 	            if (!hasEditorFocus
 | |
| 	                || empty
 | |
| 	                || isEmptyTextBlock
 | |
| 	                || !this.editor.isEditable) {
 | |
| 	                return false;
 | |
| 	            }
 | |
| 	            return true;
 | |
| 	        };
 | |
| 	        this.mousedownHandler = () => {
 | |
| 	            this.preventHide = true;
 | |
| 	        };
 | |
| 	        this.dragstartHandler = () => {
 | |
| 	            this.hide();
 | |
| 	        };
 | |
| 	        this.focusHandler = () => {
 | |
| 	            // we use `setTimeout` to make sure `selection` is already updated
 | |
| 	            setTimeout(() => this.update(this.editor.view));
 | |
| 	        };
 | |
| 	        this.blurHandler = ({ event }) => {
 | |
| 	            var _a;
 | |
| 	            if (this.preventHide) {
 | |
| 	                this.preventHide = false;
 | |
| 	                return;
 | |
| 	            }
 | |
| 	            if ((event === null || event === void 0 ? void 0 : event.relatedTarget)
 | |
| 	                && ((_a = this.element.parentNode) === null || _a === void 0 ? void 0 : _a.contains(event.relatedTarget))) {
 | |
| 	                return;
 | |
| 	            }
 | |
| 	            this.hide();
 | |
| 	        };
 | |
| 	        this.tippyBlurHandler = (event) => {
 | |
| 	            this.blurHandler({ event });
 | |
| 	        };
 | |
| 	        this.updateHandler = (view, oldState) => {
 | |
| 	            var _a, _b, _c;
 | |
| 	            const { state, composing } = view;
 | |
| 	            const { doc, selection } = state;
 | |
| 	            const isSame = oldState && oldState.doc.eq(doc) && oldState.selection.eq(selection);
 | |
| 	            if (composing || isSame) {
 | |
| 	                return;
 | |
| 	            }
 | |
| 	            this.createTooltip();
 | |
| 	            // support for CellSelections
 | |
| 	            const { ranges } = selection;
 | |
| 	            const from = Math.min(...ranges.map(range => range.$from.pos));
 | |
| 	            const to = Math.max(...ranges.map(range => range.$to.pos));
 | |
| 	            const shouldShow = (_a = this.shouldShow) === null || _a === void 0 ? void 0 : _a.call(this, {
 | |
| 	                editor: this.editor,
 | |
| 	                view,
 | |
| 	                state,
 | |
| 	                oldState,
 | |
| 	                from,
 | |
| 	                to,
 | |
| 	            });
 | |
| 	            if (!shouldShow) {
 | |
| 	                this.hide();
 | |
| 	                return;
 | |
| 	            }
 | |
| 	            (_b = this.tippy) === null || _b === void 0 ? void 0 : _b.setProps({
 | |
| 	                getReferenceClientRect: ((_c = this.tippyOptions) === null || _c === void 0 ? void 0 : _c.getReferenceClientRect) || (() => {
 | |
| 	                    if (core.isNodeSelection(state.selection)) {
 | |
| 	                        const node = view.nodeDOM(from);
 | |
| 	                        if (node) {
 | |
| 	                            return node.getBoundingClientRect();
 | |
| 	                        }
 | |
| 	                    }
 | |
| 	                    return core.posToDOMRect(view, from, to);
 | |
| 	                }),
 | |
| 	            });
 | |
| 	            this.show();
 | |
| 	        };
 | |
| 	        this.editor = editor;
 | |
| 	        this.element = element;
 | |
| 	        this.view = view;
 | |
| 	        this.updateDelay = updateDelay;
 | |
| 	        if (shouldShow) {
 | |
| 	            this.shouldShow = shouldShow;
 | |
| 	        }
 | |
| 	        this.element.addEventListener('mousedown', this.mousedownHandler, { capture: true });
 | |
| 	        this.view.dom.addEventListener('dragstart', this.dragstartHandler);
 | |
| 	        this.editor.on('focus', this.focusHandler);
 | |
| 	        this.editor.on('blur', this.blurHandler);
 | |
| 	        this.tippyOptions = tippyOptions;
 | |
| 	        // Detaches menu content from its current parent
 | |
| 	        this.element.remove();
 | |
| 	        this.element.style.visibility = 'visible';
 | |
| 	    }
 | |
| 	    createTooltip() {
 | |
| 	        const { element: editorElement } = this.editor.options;
 | |
| 	        const editorIsAttached = !!editorElement.parentElement;
 | |
| 	        if (this.tippy || !editorIsAttached) {
 | |
| 	            return;
 | |
| 	        }
 | |
| 	        this.tippy = tippy__default["default"](editorElement, {
 | |
| 	            duration: 0,
 | |
| 	            getReferenceClientRect: null,
 | |
| 	            content: this.element,
 | |
| 	            interactive: true,
 | |
| 	            trigger: 'manual',
 | |
| 	            placement: 'top',
 | |
| 	            hideOnClick: 'toggle',
 | |
| 	            ...this.tippyOptions,
 | |
| 	        });
 | |
| 	        // maybe we have to hide tippy on its own blur event as well
 | |
| 	        if (this.tippy.popper.firstChild) {
 | |
| 	            this.tippy.popper.firstChild.addEventListener('blur', this.tippyBlurHandler);
 | |
| 	        }
 | |
| 	    }
 | |
| 	    update(view, oldState) {
 | |
| 	        const { state } = view;
 | |
| 	        const hasValidSelection = state.selection.$from.pos !== state.selection.$to.pos;
 | |
| 	        if (this.updateDelay > 0 && hasValidSelection) {
 | |
| 	            debounce_1(this.updateHandler, this.updateDelay)(view, oldState);
 | |
| 	        }
 | |
| 	        else {
 | |
| 	            this.updateHandler(view, oldState);
 | |
| 	        }
 | |
| 	    }
 | |
| 	    show() {
 | |
| 	        var _a;
 | |
| 	        (_a = this.tippy) === null || _a === void 0 ? void 0 : _a.show();
 | |
| 	    }
 | |
| 	    hide() {
 | |
| 	        var _a;
 | |
| 	        (_a = this.tippy) === null || _a === void 0 ? void 0 : _a.hide();
 | |
| 	    }
 | |
| 	    destroy() {
 | |
| 	        var _a, _b;
 | |
| 	        if ((_a = this.tippy) === null || _a === void 0 ? void 0 : _a.popper.firstChild) {
 | |
| 	            this.tippy.popper.firstChild.removeEventListener('blur', this.tippyBlurHandler);
 | |
| 	        }
 | |
| 	        (_b = this.tippy) === null || _b === void 0 ? void 0 : _b.destroy();
 | |
| 	        this.element.removeEventListener('mousedown', this.mousedownHandler, { capture: true });
 | |
| 	        this.view.dom.removeEventListener('dragstart', this.dragstartHandler);
 | |
| 	        this.editor.off('focus', this.focusHandler);
 | |
| 	        this.editor.off('blur', this.blurHandler);
 | |
| 	    }
 | |
| 	}
 | |
| 	const BubbleMenuPlugin = (options) => {
 | |
| 	    return new prosemirrorState.Plugin({
 | |
| 	        key: typeof options.pluginKey === 'string'
 | |
| 	            ? new prosemirrorState.PluginKey(options.pluginKey)
 | |
| 	            : options.pluginKey,
 | |
| 	        view: view => new BubbleMenuView({ view, ...options }),
 | |
| 	    });
 | |
| 	};
 | |
| 
 | |
| 	const BubbleMenu = core.Extension.create({
 | |
| 	    name: 'bubbleMenu',
 | |
| 	    addOptions() {
 | |
| 	        return {
 | |
| 	            element: null,
 | |
| 	            tippyOptions: {},
 | |
| 	            pluginKey: 'bubbleMenu',
 | |
| 	            updateDelay: undefined,
 | |
| 	            shouldShow: null,
 | |
| 	        };
 | |
| 	    },
 | |
| 	    addProseMirrorPlugins() {
 | |
| 	        if (!this.options.element) {
 | |
| 	            return [];
 | |
| 	        }
 | |
| 	        return [
 | |
| 	            BubbleMenuPlugin({
 | |
| 	                pluginKey: this.options.pluginKey,
 | |
| 	                editor: this.editor,
 | |
| 	                element: this.options.element,
 | |
| 	                tippyOptions: this.options.tippyOptions,
 | |
| 	                updateDelay: this.options.updateDelay,
 | |
| 	                shouldShow: this.options.shouldShow,
 | |
| 	            }),
 | |
| 	        ];
 | |
| 	    },
 | |
| 	});
 | |
| 
 | |
| 	exports.BubbleMenu = BubbleMenu;
 | |
| 	exports.BubbleMenuPlugin = BubbleMenuPlugin;
 | |
| 	exports.BubbleMenuView = BubbleMenuView;
 | |
| 	exports["default"] = BubbleMenu;
 | |
| 
 | |
| 	Object.defineProperty(exports, '__esModule', { value: true });
 | |
| 
 | |
| }));
 | |
| //# sourceMappingURL=tiptap-extension-bubble-menu.umd.js.map
 |