Initial
This commit is contained in:
100
resources/app/node_modules/prosemirror-dropcursor/CONTRIBUTING.md
generated
vendored
Normal file
100
resources/app/node_modules/prosemirror-dropcursor/CONTRIBUTING.md
generated
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
# How to contribute
|
||||
|
||||
- [Getting help](#getting-help)
|
||||
- [Submitting bug reports](#submitting-bug-reports)
|
||||
- [Contributing code](#contributing-code)
|
||||
|
||||
## Getting help
|
||||
|
||||
Community discussion, questions, and informal bug reporting is done on the
|
||||
[discuss.ProseMirror forum](http://discuss.prosemirror.net).
|
||||
|
||||
## Submitting bug reports
|
||||
|
||||
Report bugs on the
|
||||
[GitHub issue tracker](http://github.com/prosemirror/prosemirror/issues).
|
||||
Before reporting a bug, please read these pointers.
|
||||
|
||||
- The issue tracker is for *bugs*, not requests for help. Questions
|
||||
should be asked on the [forum](http://discuss.prosemirror.net).
|
||||
|
||||
- Include information about the version of the code that exhibits the
|
||||
problem. For browser-related issues, include the browser and browser
|
||||
version on which the problem occurred.
|
||||
|
||||
- Mention very precisely what went wrong. "X is broken" is not a good
|
||||
bug report. What did you expect to happen? What happened instead?
|
||||
Describe the exact steps a maintainer has to take to make the
|
||||
problem occur. A screencast can be useful, but is no substitute for
|
||||
a textual description.
|
||||
|
||||
- A great way to make it easy to reproduce your problem, if it can not
|
||||
be trivially reproduced on the website demos, is to submit a script
|
||||
that triggers the issue.
|
||||
|
||||
## Contributing code
|
||||
|
||||
- Make sure you have a [GitHub Account](https://github.com/signup/free)
|
||||
|
||||
- Fork the relevant repository
|
||||
([how to fork a repo](https://help.github.com/articles/fork-a-repo))
|
||||
|
||||
- Create a local checkout of the code. You can use the
|
||||
[main repository](https://github.com/prosemirror/prosemirror) to
|
||||
easily check out all core modules.
|
||||
|
||||
- Make your changes, and commit them
|
||||
|
||||
- Follow the code style of the rest of the project (see below). Run
|
||||
`npm run lint` (in the main repository checkout) to make sure that
|
||||
the linter is happy.
|
||||
|
||||
- If your changes are easy to test or likely to regress, add tests in
|
||||
the relevant `test/` directory. Either put them in an existing
|
||||
`test-*.js` file, if they fit there, or add a new file.
|
||||
|
||||
- Make sure all tests pass. Run `npm run test` to verify tests pass
|
||||
(you will need Node.js v6+).
|
||||
|
||||
- Submit a pull request ([how to create a pull request](https://help.github.com/articles/fork-a-repo)).
|
||||
Don't put more than one feature/fix in a single pull request.
|
||||
|
||||
By contributing code to ProseMirror you
|
||||
|
||||
- Agree to license the contributed code under the project's [MIT
|
||||
license](https://github.com/ProseMirror/prosemirror/blob/master/LICENSE).
|
||||
|
||||
- Confirm that you have the right to contribute and license the code
|
||||
in question. (Either you hold all rights on the code, or the rights
|
||||
holder has explicitly granted the right to use it like this,
|
||||
through a compatible open source license or through a direct
|
||||
agreement with you.)
|
||||
|
||||
### Coding standards
|
||||
|
||||
- ES6 syntax, targeting an ES5 runtime (i.e. don't use library
|
||||
elements added by ES6, don't use ES7/ES.next syntax).
|
||||
|
||||
- 2 spaces per indentation level, no tabs.
|
||||
|
||||
- No semicolons except when necessary.
|
||||
|
||||
- Follow the surrounding code when it comes to spacing, brace
|
||||
placement, etc.
|
||||
|
||||
- Brace-less single-statement bodies are encouraged (whenever they
|
||||
don't impact readability).
|
||||
|
||||
- [getdocs](https://github.com/marijnh/getdocs)-style doc comments
|
||||
above items that are part of the public API.
|
||||
|
||||
- When documenting non-public items, you can put the type after a
|
||||
single colon, so that getdocs doesn't pick it up and add it to the
|
||||
API reference.
|
||||
|
||||
- The linter (`npm run lint`) complains about unused variables and
|
||||
functions. Prefix their names with an underscore to muffle it.
|
||||
|
||||
- ProseMirror does *not* follow JSHint or JSLint prescribed style.
|
||||
Patches that try to 'fix' code to pass one of these linters will not
|
||||
be accepted.
|
||||
19
resources/app/node_modules/prosemirror-dropcursor/LICENSE
generated
vendored
Normal file
19
resources/app/node_modules/prosemirror-dropcursor/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (C) 2015-2017 by Marijn Haverbeke <marijn@haverbeke.berlin> and others
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
208
resources/app/node_modules/prosemirror-dropcursor/dist/index.cjs
generated
vendored
Normal file
208
resources/app/node_modules/prosemirror-dropcursor/dist/index.cjs
generated
vendored
Normal file
@@ -0,0 +1,208 @@
|
||||
'use strict';
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
||||
|
||||
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
||||
|
||||
Object.defineProperty(exports, '__esModule', {
|
||||
value: true
|
||||
});
|
||||
|
||||
var prosemirrorState = require('prosemirror-state');
|
||||
|
||||
var prosemirrorTransform = require('prosemirror-transform');
|
||||
|
||||
function dropCursor() {
|
||||
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
||||
return new prosemirrorState.Plugin({
|
||||
view: function view(editorView) {
|
||||
return new DropCursorView(editorView, options);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var DropCursorView = function () {
|
||||
function DropCursorView(editorView, options) {
|
||||
var _this = this;
|
||||
|
||||
_classCallCheck(this, DropCursorView);
|
||||
|
||||
var _a;
|
||||
|
||||
this.editorView = editorView;
|
||||
this.cursorPos = null;
|
||||
this.element = null;
|
||||
this.timeout = -1;
|
||||
this.width = (_a = options.width) !== null && _a !== void 0 ? _a : 1;
|
||||
this.color = options.color === false ? undefined : options.color || "black";
|
||||
this["class"] = options["class"];
|
||||
this.handlers = ["dragover", "dragend", "drop", "dragleave"].map(function (name) {
|
||||
var handler = function handler(e) {
|
||||
_this[name](e);
|
||||
};
|
||||
|
||||
editorView.dom.addEventListener(name, handler);
|
||||
return {
|
||||
name: name,
|
||||
handler: handler
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
_createClass(DropCursorView, [{
|
||||
key: "destroy",
|
||||
value: function destroy() {
|
||||
var _this2 = this;
|
||||
|
||||
this.handlers.forEach(function (_ref) {
|
||||
var name = _ref.name,
|
||||
handler = _ref.handler;
|
||||
return _this2.editorView.dom.removeEventListener(name, handler);
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: "update",
|
||||
value: function update(editorView, prevState) {
|
||||
if (this.cursorPos != null && prevState.doc != editorView.state.doc) {
|
||||
if (this.cursorPos > editorView.state.doc.content.size) this.setCursor(null);else this.updateOverlay();
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: "setCursor",
|
||||
value: function setCursor(pos) {
|
||||
if (pos == this.cursorPos) return;
|
||||
this.cursorPos = pos;
|
||||
|
||||
if (pos == null) {
|
||||
this.element.parentNode.removeChild(this.element);
|
||||
this.element = null;
|
||||
} else {
|
||||
this.updateOverlay();
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: "updateOverlay",
|
||||
value: function updateOverlay() {
|
||||
var $pos = this.editorView.state.doc.resolve(this.cursorPos);
|
||||
var isBlock = !$pos.parent.inlineContent,
|
||||
rect;
|
||||
|
||||
if (isBlock) {
|
||||
var before = $pos.nodeBefore,
|
||||
after = $pos.nodeAfter;
|
||||
|
||||
if (before || after) {
|
||||
var node = this.editorView.nodeDOM(this.cursorPos - (before ? before.nodeSize : 0));
|
||||
|
||||
if (node) {
|
||||
var nodeRect = node.getBoundingClientRect();
|
||||
var top = before ? nodeRect.bottom : nodeRect.top;
|
||||
if (before && after) top = (top + this.editorView.nodeDOM(this.cursorPos).getBoundingClientRect().top) / 2;
|
||||
rect = {
|
||||
left: nodeRect.left,
|
||||
right: nodeRect.right,
|
||||
top: top - this.width / 2,
|
||||
bottom: top + this.width / 2
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!rect) {
|
||||
var coords = this.editorView.coordsAtPos(this.cursorPos);
|
||||
rect = {
|
||||
left: coords.left - this.width / 2,
|
||||
right: coords.left + this.width / 2,
|
||||
top: coords.top,
|
||||
bottom: coords.bottom
|
||||
};
|
||||
}
|
||||
|
||||
var parent = this.editorView.dom.offsetParent;
|
||||
|
||||
if (!this.element) {
|
||||
this.element = parent.appendChild(document.createElement("div"));
|
||||
if (this["class"]) this.element.className = this["class"];
|
||||
this.element.style.cssText = "position: absolute; z-index: 50; pointer-events: none;";
|
||||
|
||||
if (this.color) {
|
||||
this.element.style.backgroundColor = this.color;
|
||||
}
|
||||
}
|
||||
|
||||
this.element.classList.toggle("prosemirror-dropcursor-block", isBlock);
|
||||
this.element.classList.toggle("prosemirror-dropcursor-inline", !isBlock);
|
||||
var parentLeft, parentTop;
|
||||
|
||||
if (!parent || parent == document.body && getComputedStyle(parent).position == "static") {
|
||||
parentLeft = -pageXOffset;
|
||||
parentTop = -pageYOffset;
|
||||
} else {
|
||||
var _rect = parent.getBoundingClientRect();
|
||||
|
||||
parentLeft = _rect.left - parent.scrollLeft;
|
||||
parentTop = _rect.top - parent.scrollTop;
|
||||
}
|
||||
|
||||
this.element.style.left = rect.left - parentLeft + "px";
|
||||
this.element.style.top = rect.top - parentTop + "px";
|
||||
this.element.style.width = rect.right - rect.left + "px";
|
||||
this.element.style.height = rect.bottom - rect.top + "px";
|
||||
}
|
||||
}, {
|
||||
key: "scheduleRemoval",
|
||||
value: function scheduleRemoval(timeout) {
|
||||
var _this3 = this;
|
||||
|
||||
clearTimeout(this.timeout);
|
||||
this.timeout = setTimeout(function () {
|
||||
return _this3.setCursor(null);
|
||||
}, timeout);
|
||||
}
|
||||
}, {
|
||||
key: "dragover",
|
||||
value: function dragover(event) {
|
||||
if (!this.editorView.editable) return;
|
||||
var pos = this.editorView.posAtCoords({
|
||||
left: event.clientX,
|
||||
top: event.clientY
|
||||
});
|
||||
var node = pos && pos.inside >= 0 && this.editorView.state.doc.nodeAt(pos.inside);
|
||||
var disableDropCursor = node && node.type.spec.disableDropCursor;
|
||||
var disabled = typeof disableDropCursor == "function" ? disableDropCursor(this.editorView, pos, event) : disableDropCursor;
|
||||
|
||||
if (pos && !disabled) {
|
||||
var target = pos.pos;
|
||||
|
||||
if (this.editorView.dragging && this.editorView.dragging.slice) {
|
||||
var point = prosemirrorTransform.dropPoint(this.editorView.state.doc, target, this.editorView.dragging.slice);
|
||||
if (point != null) target = point;
|
||||
}
|
||||
|
||||
this.setCursor(target);
|
||||
this.scheduleRemoval(5000);
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: "dragend",
|
||||
value: function dragend() {
|
||||
this.scheduleRemoval(20);
|
||||
}
|
||||
}, {
|
||||
key: "drop",
|
||||
value: function drop() {
|
||||
this.scheduleRemoval(20);
|
||||
}
|
||||
}, {
|
||||
key: "dragleave",
|
||||
value: function dragleave(event) {
|
||||
if (event.target == this.editorView.dom || !this.editorView.dom.contains(event.relatedTarget)) this.setCursor(null);
|
||||
}
|
||||
}]);
|
||||
|
||||
return DropCursorView;
|
||||
}();
|
||||
|
||||
exports.dropCursor = dropCursor;
|
||||
29
resources/app/node_modules/prosemirror-dropcursor/dist/index.d.cts
generated
vendored
Normal file
29
resources/app/node_modules/prosemirror-dropcursor/dist/index.d.cts
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
import { Plugin } from 'prosemirror-state';
|
||||
|
||||
interface DropCursorOptions {
|
||||
/**
|
||||
The color of the cursor. Defaults to `black`. Use `false` to apply no color and rely only on class.
|
||||
*/
|
||||
color?: string | false;
|
||||
/**
|
||||
The precise width of the cursor in pixels. Defaults to 1.
|
||||
*/
|
||||
width?: number;
|
||||
/**
|
||||
A CSS class name to add to the cursor element.
|
||||
*/
|
||||
class?: string;
|
||||
}
|
||||
/**
|
||||
Create a plugin that, when added to a ProseMirror instance,
|
||||
causes a decoration to show up at the drop position when something
|
||||
is dragged over the editor.
|
||||
|
||||
Nodes may add a `disableDropCursor` property to their spec to
|
||||
control the showing of a drop cursor inside them. This may be a
|
||||
boolean or a function, which will be called with a view and a
|
||||
position, and should return a boolean.
|
||||
*/
|
||||
declare function dropCursor(options?: DropCursorOptions): Plugin;
|
||||
|
||||
export { dropCursor };
|
||||
139
resources/app/node_modules/prosemirror-dropcursor/dist/index.js
generated
vendored
Normal file
139
resources/app/node_modules/prosemirror-dropcursor/dist/index.js
generated
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
import { Plugin } from 'prosemirror-state';
|
||||
import { dropPoint } from 'prosemirror-transform';
|
||||
|
||||
/**
|
||||
Create a plugin that, when added to a ProseMirror instance,
|
||||
causes a decoration to show up at the drop position when something
|
||||
is dragged over the editor.
|
||||
|
||||
Nodes may add a `disableDropCursor` property to their spec to
|
||||
control the showing of a drop cursor inside them. This may be a
|
||||
boolean or a function, which will be called with a view and a
|
||||
position, and should return a boolean.
|
||||
*/
|
||||
function dropCursor(options = {}) {
|
||||
return new Plugin({
|
||||
view(editorView) { return new DropCursorView(editorView, options); }
|
||||
});
|
||||
}
|
||||
class DropCursorView {
|
||||
constructor(editorView, options) {
|
||||
var _a;
|
||||
this.editorView = editorView;
|
||||
this.cursorPos = null;
|
||||
this.element = null;
|
||||
this.timeout = -1;
|
||||
this.width = (_a = options.width) !== null && _a !== void 0 ? _a : 1;
|
||||
this.color = options.color === false ? undefined : (options.color || "black");
|
||||
this.class = options.class;
|
||||
this.handlers = ["dragover", "dragend", "drop", "dragleave"].map(name => {
|
||||
let handler = (e) => { this[name](e); };
|
||||
editorView.dom.addEventListener(name, handler);
|
||||
return { name, handler };
|
||||
});
|
||||
}
|
||||
destroy() {
|
||||
this.handlers.forEach(({ name, handler }) => this.editorView.dom.removeEventListener(name, handler));
|
||||
}
|
||||
update(editorView, prevState) {
|
||||
if (this.cursorPos != null && prevState.doc != editorView.state.doc) {
|
||||
if (this.cursorPos > editorView.state.doc.content.size)
|
||||
this.setCursor(null);
|
||||
else
|
||||
this.updateOverlay();
|
||||
}
|
||||
}
|
||||
setCursor(pos) {
|
||||
if (pos == this.cursorPos)
|
||||
return;
|
||||
this.cursorPos = pos;
|
||||
if (pos == null) {
|
||||
this.element.parentNode.removeChild(this.element);
|
||||
this.element = null;
|
||||
}
|
||||
else {
|
||||
this.updateOverlay();
|
||||
}
|
||||
}
|
||||
updateOverlay() {
|
||||
let $pos = this.editorView.state.doc.resolve(this.cursorPos);
|
||||
let isBlock = !$pos.parent.inlineContent, rect;
|
||||
if (isBlock) {
|
||||
let before = $pos.nodeBefore, after = $pos.nodeAfter;
|
||||
if (before || after) {
|
||||
let node = this.editorView.nodeDOM(this.cursorPos - (before ? before.nodeSize : 0));
|
||||
if (node) {
|
||||
let nodeRect = node.getBoundingClientRect();
|
||||
let top = before ? nodeRect.bottom : nodeRect.top;
|
||||
if (before && after)
|
||||
top = (top + this.editorView.nodeDOM(this.cursorPos).getBoundingClientRect().top) / 2;
|
||||
rect = { left: nodeRect.left, right: nodeRect.right, top: top - this.width / 2, bottom: top + this.width / 2 };
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!rect) {
|
||||
let coords = this.editorView.coordsAtPos(this.cursorPos);
|
||||
rect = { left: coords.left - this.width / 2, right: coords.left + this.width / 2, top: coords.top, bottom: coords.bottom };
|
||||
}
|
||||
let parent = this.editorView.dom.offsetParent;
|
||||
if (!this.element) {
|
||||
this.element = parent.appendChild(document.createElement("div"));
|
||||
if (this.class)
|
||||
this.element.className = this.class;
|
||||
this.element.style.cssText = "position: absolute; z-index: 50; pointer-events: none;";
|
||||
if (this.color) {
|
||||
this.element.style.backgroundColor = this.color;
|
||||
}
|
||||
}
|
||||
this.element.classList.toggle("prosemirror-dropcursor-block", isBlock);
|
||||
this.element.classList.toggle("prosemirror-dropcursor-inline", !isBlock);
|
||||
let parentLeft, parentTop;
|
||||
if (!parent || parent == document.body && getComputedStyle(parent).position == "static") {
|
||||
parentLeft = -pageXOffset;
|
||||
parentTop = -pageYOffset;
|
||||
}
|
||||
else {
|
||||
let rect = parent.getBoundingClientRect();
|
||||
parentLeft = rect.left - parent.scrollLeft;
|
||||
parentTop = rect.top - parent.scrollTop;
|
||||
}
|
||||
this.element.style.left = (rect.left - parentLeft) + "px";
|
||||
this.element.style.top = (rect.top - parentTop) + "px";
|
||||
this.element.style.width = (rect.right - rect.left) + "px";
|
||||
this.element.style.height = (rect.bottom - rect.top) + "px";
|
||||
}
|
||||
scheduleRemoval(timeout) {
|
||||
clearTimeout(this.timeout);
|
||||
this.timeout = setTimeout(() => this.setCursor(null), timeout);
|
||||
}
|
||||
dragover(event) {
|
||||
if (!this.editorView.editable)
|
||||
return;
|
||||
let pos = this.editorView.posAtCoords({ left: event.clientX, top: event.clientY });
|
||||
let node = pos && pos.inside >= 0 && this.editorView.state.doc.nodeAt(pos.inside);
|
||||
let disableDropCursor = node && node.type.spec.disableDropCursor;
|
||||
let disabled = typeof disableDropCursor == "function" ? disableDropCursor(this.editorView, pos, event) : disableDropCursor;
|
||||
if (pos && !disabled) {
|
||||
let target = pos.pos;
|
||||
if (this.editorView.dragging && this.editorView.dragging.slice) {
|
||||
let point = dropPoint(this.editorView.state.doc, target, this.editorView.dragging.slice);
|
||||
if (point != null)
|
||||
target = point;
|
||||
}
|
||||
this.setCursor(target);
|
||||
this.scheduleRemoval(5000);
|
||||
}
|
||||
}
|
||||
dragend() {
|
||||
this.scheduleRemoval(20);
|
||||
}
|
||||
drop() {
|
||||
this.scheduleRemoval(20);
|
||||
}
|
||||
dragleave(event) {
|
||||
if (event.target == this.editorView.dom || !this.editorView.dom.contains(event.relatedTarget))
|
||||
this.setCursor(null);
|
||||
}
|
||||
}
|
||||
|
||||
export { dropCursor };
|
||||
34
resources/app/node_modules/prosemirror-dropcursor/package.json
generated
vendored
Normal file
34
resources/app/node_modules/prosemirror-dropcursor/package.json
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"name": "prosemirror-dropcursor",
|
||||
"version": "1.8.1",
|
||||
"description": "Drop cursor plugin for ProseMirror",
|
||||
"type": "module",
|
||||
"main": "dist/index.cjs",
|
||||
"module": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"exports": {
|
||||
"import": "./dist/index.js",
|
||||
"require": "./dist/index.cjs"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"license": "MIT",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "Marijn Haverbeke",
|
||||
"email": "marijn@haverbeke.berlin",
|
||||
"web": "http://marijnhaverbeke.nl"
|
||||
}
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/prosemirror/prosemirror-dropcursor.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"prosemirror-view": "^1.1.0",
|
||||
"prosemirror-transform": "^1.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@prosemirror/buildhelper": "^0.1.5"
|
||||
}
|
||||
}
|
||||
156
resources/app/node_modules/prosemirror-dropcursor/src/dropcursor.ts
generated
vendored
Normal file
156
resources/app/node_modules/prosemirror-dropcursor/src/dropcursor.ts
generated
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
import {Plugin, EditorState} from "prosemirror-state"
|
||||
import {EditorView} from "prosemirror-view"
|
||||
import {dropPoint} from "prosemirror-transform"
|
||||
|
||||
interface DropCursorOptions {
|
||||
/// The color of the cursor. Defaults to `black`. Use `false` to apply no color and rely only on class.
|
||||
color?: string | false
|
||||
|
||||
/// The precise width of the cursor in pixels. Defaults to 1.
|
||||
width?: number
|
||||
|
||||
/// A CSS class name to add to the cursor element.
|
||||
class?: string
|
||||
}
|
||||
|
||||
/// Create a plugin that, when added to a ProseMirror instance,
|
||||
/// causes a decoration to show up at the drop position when something
|
||||
/// is dragged over the editor.
|
||||
///
|
||||
/// Nodes may add a `disableDropCursor` property to their spec to
|
||||
/// control the showing of a drop cursor inside them. This may be a
|
||||
/// boolean or a function, which will be called with a view and a
|
||||
/// position, and should return a boolean.
|
||||
export function dropCursor(options: DropCursorOptions = {}): Plugin {
|
||||
return new Plugin({
|
||||
view(editorView) { return new DropCursorView(editorView, options) }
|
||||
})
|
||||
}
|
||||
|
||||
class DropCursorView {
|
||||
width: number
|
||||
color: string | undefined
|
||||
class: string | undefined
|
||||
cursorPos: number | null = null
|
||||
element: HTMLElement | null = null
|
||||
timeout: number = -1
|
||||
handlers: {name: string, handler: (event: Event) => void}[]
|
||||
|
||||
constructor(readonly editorView: EditorView, options: DropCursorOptions) {
|
||||
this.width = options.width ?? 1
|
||||
this.color = options.color === false ? undefined : (options.color || "black")
|
||||
this.class = options.class
|
||||
|
||||
this.handlers = ["dragover", "dragend", "drop", "dragleave"].map(name => {
|
||||
let handler = (e: Event) => { (this as any)[name](e) }
|
||||
editorView.dom.addEventListener(name, handler)
|
||||
return {name, handler}
|
||||
})
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.handlers.forEach(({name, handler}) => this.editorView.dom.removeEventListener(name, handler))
|
||||
}
|
||||
|
||||
update(editorView: EditorView, prevState: EditorState) {
|
||||
if (this.cursorPos != null && prevState.doc != editorView.state.doc) {
|
||||
if (this.cursorPos > editorView.state.doc.content.size) this.setCursor(null)
|
||||
else this.updateOverlay()
|
||||
}
|
||||
}
|
||||
|
||||
setCursor(pos: number | null) {
|
||||
if (pos == this.cursorPos) return
|
||||
this.cursorPos = pos
|
||||
if (pos == null) {
|
||||
this.element!.parentNode!.removeChild(this.element!)
|
||||
this.element = null
|
||||
} else {
|
||||
this.updateOverlay()
|
||||
}
|
||||
}
|
||||
|
||||
updateOverlay() {
|
||||
let $pos = this.editorView.state.doc.resolve(this.cursorPos!)
|
||||
let isBlock = !$pos.parent.inlineContent, rect
|
||||
if (isBlock) {
|
||||
let before = $pos.nodeBefore, after = $pos.nodeAfter
|
||||
if (before || after) {
|
||||
let node = this.editorView.nodeDOM(this.cursorPos! - (before ? before.nodeSize : 0))
|
||||
if (node) {
|
||||
let nodeRect = (node as HTMLElement).getBoundingClientRect()
|
||||
let top = before ? nodeRect.bottom : nodeRect.top
|
||||
if (before && after)
|
||||
top = (top + (this.editorView.nodeDOM(this.cursorPos!) as HTMLElement).getBoundingClientRect().top) / 2
|
||||
rect = {left: nodeRect.left, right: nodeRect.right, top: top - this.width / 2, bottom: top + this.width / 2}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!rect) {
|
||||
let coords = this.editorView.coordsAtPos(this.cursorPos!)
|
||||
rect = {left: coords.left - this.width / 2, right: coords.left + this.width / 2, top: coords.top, bottom: coords.bottom}
|
||||
}
|
||||
|
||||
let parent = this.editorView.dom.offsetParent!
|
||||
if (!this.element) {
|
||||
this.element = parent.appendChild(document.createElement("div"))
|
||||
if (this.class) this.element.className = this.class
|
||||
this.element.style.cssText = "position: absolute; z-index: 50; pointer-events: none;"
|
||||
if (this.color) {
|
||||
this.element.style.backgroundColor = this.color
|
||||
}
|
||||
}
|
||||
this.element.classList.toggle("prosemirror-dropcursor-block", isBlock)
|
||||
this.element.classList.toggle("prosemirror-dropcursor-inline", !isBlock)
|
||||
let parentLeft, parentTop
|
||||
if (!parent || parent == document.body && getComputedStyle(parent).position == "static") {
|
||||
parentLeft = -pageXOffset
|
||||
parentTop = -pageYOffset
|
||||
} else {
|
||||
let rect = parent.getBoundingClientRect()
|
||||
parentLeft = rect.left - parent.scrollLeft
|
||||
parentTop = rect.top - parent.scrollTop
|
||||
}
|
||||
this.element.style.left = (rect.left - parentLeft) + "px"
|
||||
this.element.style.top = (rect.top - parentTop) + "px"
|
||||
this.element.style.width = (rect.right - rect.left) + "px"
|
||||
this.element.style.height = (rect.bottom - rect.top) + "px"
|
||||
}
|
||||
|
||||
scheduleRemoval(timeout: number) {
|
||||
clearTimeout(this.timeout)
|
||||
this.timeout = setTimeout(() => this.setCursor(null), timeout)
|
||||
}
|
||||
|
||||
dragover(event: DragEvent) {
|
||||
if (!this.editorView.editable) return
|
||||
let pos = this.editorView.posAtCoords({left: event.clientX, top: event.clientY})
|
||||
|
||||
let node = pos && pos.inside >= 0 && this.editorView.state.doc.nodeAt(pos.inside)
|
||||
let disableDropCursor = node && node.type.spec.disableDropCursor
|
||||
let disabled = typeof disableDropCursor == "function" ? disableDropCursor(this.editorView, pos, event) : disableDropCursor
|
||||
|
||||
if (pos && !disabled) {
|
||||
let target: number | null = pos.pos
|
||||
if (this.editorView.dragging && this.editorView.dragging.slice) {
|
||||
let point = dropPoint(this.editorView.state.doc, target, this.editorView.dragging.slice)
|
||||
if (point != null) target = point
|
||||
}
|
||||
this.setCursor(target)
|
||||
this.scheduleRemoval(5000)
|
||||
}
|
||||
}
|
||||
|
||||
dragend() {
|
||||
this.scheduleRemoval(20)
|
||||
}
|
||||
|
||||
drop() {
|
||||
this.scheduleRemoval(20)
|
||||
}
|
||||
|
||||
dragleave(event: DragEvent) {
|
||||
if (event.target == this.editorView.dom || !this.editorView.dom.contains((event as any).relatedTarget))
|
||||
this.setCursor(null)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user