gdpr audit implemented, email log, vollmachten, pdf delete cancel data privacy and vollmachten, removed message no id card in engergy car, and other contracts that are not telecom contracts, added insert counter for engery
This commit is contained in:
+21
@@ -0,0 +1,21 @@
|
||||
This is a plugin that adds a type of selection for focusing places
|
||||
that don't allow regular selection (such as positions that have a leaf
|
||||
block node, table, or the end of the document both before and after
|
||||
them). By default, leaf blocks and isolating nodes will allow gap
|
||||
cursors to appear next to them. You can add a `creatGapCursor: true`
|
||||
property to a block node's spec to make them appear next to other
|
||||
nodes as well.
|
||||
|
||||
You'll probably want to load `style/gapcursor.css`, which contains
|
||||
basic styling for the simulated cursor (as a short, blinking
|
||||
horizontal stripe).
|
||||
|
||||
By default, gap cursor are only allowed in places where the default
|
||||
content node (in the schema content constraints) is a textblock node.
|
||||
You can customize this by adding an `allowGapCursor` property to your
|
||||
node specs—if it's true, gap cursor are allowed everywhere in that
|
||||
node, if it's `false` they are never allowed.
|
||||
|
||||
@gapCursor
|
||||
|
||||
@GapCursor
|
||||
+141
@@ -0,0 +1,141 @@
|
||||
import {Selection, NodeSelection} from "prosemirror-state"
|
||||
import {Slice, ResolvedPos, Node, NodeType} from "prosemirror-model"
|
||||
import {Mappable} from "prosemirror-transform"
|
||||
|
||||
/// Gap cursor selections are represented using this class. Its
|
||||
/// `$anchor` and `$head` properties both point at the cursor position.
|
||||
export class GapCursor extends Selection {
|
||||
/// Create a gap cursor.
|
||||
constructor($pos: ResolvedPos) {
|
||||
super($pos, $pos)
|
||||
}
|
||||
|
||||
map(doc: Node, mapping: Mappable): Selection {
|
||||
let $pos = doc.resolve(mapping.map(this.head))
|
||||
return GapCursor.valid($pos) ? new GapCursor($pos) : Selection.near($pos)
|
||||
}
|
||||
|
||||
content() { return Slice.empty }
|
||||
|
||||
eq(other: Selection): boolean {
|
||||
return other instanceof GapCursor && other.head == this.head
|
||||
}
|
||||
|
||||
toJSON(): any {
|
||||
return {type: "gapcursor", pos: this.head}
|
||||
}
|
||||
|
||||
/// @internal
|
||||
static fromJSON(doc: Node, json: any): GapCursor {
|
||||
if (typeof json.pos != "number") throw new RangeError("Invalid input for GapCursor.fromJSON")
|
||||
return new GapCursor(doc.resolve(json.pos))
|
||||
}
|
||||
|
||||
/// @internal
|
||||
getBookmark() { return new GapBookmark(this.anchor) }
|
||||
|
||||
/// @internal
|
||||
static valid($pos: ResolvedPos) {
|
||||
let parent = $pos.parent
|
||||
if (parent.isTextblock || !closedBefore($pos) || !closedAfter($pos)) return false
|
||||
let override = parent.type.spec.allowGapCursor
|
||||
if (override != null) return override
|
||||
let deflt = parent.contentMatchAt($pos.index()).defaultType
|
||||
return deflt && deflt.isTextblock
|
||||
}
|
||||
|
||||
/// @internal
|
||||
static findGapCursorFrom($pos: ResolvedPos, dir: number, mustMove = false) {
|
||||
search: for (;;) {
|
||||
if (!mustMove && GapCursor.valid($pos)) return $pos
|
||||
let pos = $pos.pos, next = null
|
||||
// Scan up from this position
|
||||
for (let d = $pos.depth;; d--) {
|
||||
let parent = $pos.node(d)
|
||||
if (dir > 0 ? $pos.indexAfter(d) < parent.childCount : $pos.index(d) > 0) {
|
||||
next = parent.child(dir > 0 ? $pos.indexAfter(d) : $pos.index(d) - 1)
|
||||
break
|
||||
} else if (d == 0) {
|
||||
return null
|
||||
}
|
||||
pos += dir
|
||||
let $cur = $pos.doc.resolve(pos)
|
||||
if (GapCursor.valid($cur)) return $cur
|
||||
}
|
||||
|
||||
// And then down into the next node
|
||||
for (;;) {
|
||||
let inside: Node | null = dir > 0 ? next.firstChild : next.lastChild
|
||||
if (!inside) {
|
||||
if (next.isAtom && !next.isText && !NodeSelection.isSelectable(next)) {
|
||||
$pos = $pos.doc.resolve(pos + next.nodeSize * dir)
|
||||
mustMove = false
|
||||
continue search
|
||||
}
|
||||
break
|
||||
}
|
||||
next = inside
|
||||
pos += dir
|
||||
let $cur = $pos.doc.resolve(pos)
|
||||
if (GapCursor.valid($cur)) return $cur
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GapCursor.prototype.visible = false
|
||||
|
||||
;(GapCursor as any).findFrom = GapCursor.findGapCursorFrom
|
||||
|
||||
Selection.jsonID("gapcursor", GapCursor)
|
||||
|
||||
class GapBookmark {
|
||||
constructor(readonly pos: number) {}
|
||||
|
||||
map(mapping: Mappable) {
|
||||
return new GapBookmark(mapping.map(this.pos))
|
||||
}
|
||||
resolve(doc: Node) {
|
||||
let $pos = doc.resolve(this.pos)
|
||||
return GapCursor.valid($pos) ? new GapCursor($pos) : Selection.near($pos)
|
||||
}
|
||||
}
|
||||
|
||||
function needsGap(type: NodeType) {
|
||||
return type.isAtom || type.spec.isolating || type.spec.createGapCursor
|
||||
}
|
||||
|
||||
function closedBefore($pos: ResolvedPos) {
|
||||
for (let d = $pos.depth; d >= 0; d--) {
|
||||
let index = $pos.index(d), parent = $pos.node(d)
|
||||
// At the start of this parent, look at next one
|
||||
if (index == 0) {
|
||||
if (parent.type.spec.isolating) return true
|
||||
continue
|
||||
}
|
||||
// See if the node before (or its first ancestor) is closed
|
||||
for (let before = parent.child(index - 1);; before = before.lastChild!) {
|
||||
if ((before.childCount == 0 && !before.inlineContent) || needsGap(before.type)) return true
|
||||
if (before.inlineContent) return false
|
||||
}
|
||||
}
|
||||
// Hit start of document
|
||||
return true
|
||||
}
|
||||
|
||||
function closedAfter($pos: ResolvedPos) {
|
||||
for (let d = $pos.depth; d >= 0; d--) {
|
||||
let index = $pos.indexAfter(d), parent = $pos.node(d)
|
||||
if (index == parent.childCount) {
|
||||
if (parent.type.spec.isolating) return true
|
||||
continue
|
||||
}
|
||||
for (let after = parent.child(index);; after = after.firstChild!) {
|
||||
if ((after.childCount == 0 && !after.inlineContent) || needsGap(after.type)) return true
|
||||
if (after.inlineContent) return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
import {keydownHandler} from "prosemirror-keymap"
|
||||
import {TextSelection, NodeSelection, Plugin, Command, EditorState} from "prosemirror-state"
|
||||
import {Fragment, Slice} from "prosemirror-model"
|
||||
import {Decoration, DecorationSet, EditorView} from "prosemirror-view"
|
||||
|
||||
import {GapCursor} from "./gapcursor"
|
||||
|
||||
/// Create a gap cursor plugin. When enabled, this will capture clicks
|
||||
/// near and arrow-key-motion past places that don't have a normally
|
||||
/// selectable position nearby, and create a gap cursor selection for
|
||||
/// them. The cursor is drawn as an element with class
|
||||
/// `ProseMirror-gapcursor`. You can either include
|
||||
/// `style/gapcursor.css` from the package's directory or add your own
|
||||
/// styles to make it visible.
|
||||
export function gapCursor(): Plugin {
|
||||
return new Plugin({
|
||||
props: {
|
||||
decorations: drawGapCursor,
|
||||
|
||||
createSelectionBetween(_view, $anchor, $head) {
|
||||
return $anchor.pos == $head.pos && GapCursor.valid($head) ? new GapCursor($head) : null
|
||||
},
|
||||
|
||||
handleClick,
|
||||
handleKeyDown,
|
||||
handleDOMEvents: {beforeinput: beforeinput as any}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export {GapCursor}
|
||||
|
||||
const handleKeyDown = keydownHandler({
|
||||
"ArrowLeft": arrow("horiz", -1),
|
||||
"ArrowRight": arrow("horiz", 1),
|
||||
"ArrowUp": arrow("vert", -1),
|
||||
"ArrowDown": arrow("vert", 1)
|
||||
})
|
||||
|
||||
function arrow(axis: "vert" | "horiz", dir: number): Command {
|
||||
const dirStr = axis == "vert" ? (dir > 0 ? "down" : "up") : (dir > 0 ? "right" : "left")
|
||||
return function(state, dispatch, view) {
|
||||
let sel = state.selection
|
||||
let $start = dir > 0 ? sel.$to : sel.$from, mustMove = sel.empty
|
||||
if (sel instanceof TextSelection) {
|
||||
if (!view!.endOfTextblock(dirStr) || $start.depth == 0) return false
|
||||
mustMove = false
|
||||
$start = state.doc.resolve(dir > 0 ? $start.after() : $start.before())
|
||||
}
|
||||
let $found = GapCursor.findGapCursorFrom($start, dir, mustMove)
|
||||
if (!$found) return false
|
||||
if (dispatch) dispatch(state.tr.setSelection(new GapCursor($found)))
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
function handleClick(view: EditorView, pos: number, event: MouseEvent) {
|
||||
if (!view || !view.editable) return false
|
||||
let $pos = view.state.doc.resolve(pos)
|
||||
if (!GapCursor.valid($pos)) return false
|
||||
let clickPos = view.posAtCoords({left: event.clientX, top: event.clientY})
|
||||
if (clickPos && clickPos.inside > -1 && NodeSelection.isSelectable(view.state.doc.nodeAt(clickPos.inside)!)) return false
|
||||
view.dispatch(view.state.tr.setSelection(new GapCursor($pos)))
|
||||
return true
|
||||
}
|
||||
|
||||
// This is a hack that, when a composition starts while a gap cursor
|
||||
// is active, quickly creates an inline context for the composition to
|
||||
// happen in, to avoid it being aborted by the DOM selection being
|
||||
// moved into a valid position.
|
||||
function beforeinput(view: EditorView, event: InputEvent) {
|
||||
if (event.inputType != "insertCompositionText" || !(view.state.selection instanceof GapCursor)) return false
|
||||
|
||||
let {$from} = view.state.selection
|
||||
let insert = $from.parent.contentMatchAt($from.index()).findWrapping(view.state.schema.nodes.text)
|
||||
if (!insert) return false
|
||||
|
||||
let frag = Fragment.empty
|
||||
for (let i = insert.length - 1; i >= 0; i--) frag = Fragment.from(insert[i].createAndFill(null, frag))
|
||||
let tr = view.state.tr.replace($from.pos, $from.pos, new Slice(frag, 0, 0))
|
||||
tr.setSelection(TextSelection.near(tr.doc.resolve($from.pos + 1)))
|
||||
view.dispatch(tr)
|
||||
return false
|
||||
}
|
||||
|
||||
function drawGapCursor(state: EditorState) {
|
||||
if (!(state.selection instanceof GapCursor)) return null
|
||||
let node = document.createElement("div")
|
||||
node.className = "ProseMirror-gapcursor"
|
||||
return DecorationSet.create(state.doc, [Decoration.widget(state.selection.head, node, {key: "gapcursor"})])
|
||||
}
|
||||
Reference in New Issue
Block a user