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:
2026-03-21 11:59:53 +01:00
parent 09e87c951b
commit c3edb8ad2e
1491 changed files with 265550 additions and 1292 deletions
+29
View File
@@ -0,0 +1,29 @@
This module exports list-related schema elements and commands. The
commands assume lists to be nestable, with the restriction that the
first child of a list item is a plain paragraph.
These are the node specs:
@orderedList
@bulletList
@listItem
@addListNodes
Using this would look something like this:
```javascript
const mySchema = new Schema({
nodes: addListNodes(baseSchema.spec.nodes, "paragraph block*", "block"),
marks: baseSchema.spec.marks
})
```
The following functions are [commands](/docs/guide/#commands) and utilities:
@wrapInList
@wrapRangeInList
@splitListItem
@splitListItemKeepMarks
@liftListItem
@sinkListItem
+267
View File
@@ -0,0 +1,267 @@
import {findWrapping, liftTarget, canSplit, ReplaceAroundStep, canJoin} from "prosemirror-transform"
import {Slice, Fragment, NodeSpec, DOMOutputSpec, NodeType, Attrs, NodeRange} from "prosemirror-model"
import OrderedMap from "orderedmap"
import {Command, EditorState, Transaction, NodeSelection, Selection} from "prosemirror-state"
const olDOM: DOMOutputSpec = ["ol", 0], ulDOM: DOMOutputSpec = ["ul", 0], liDOM: DOMOutputSpec = ["li", 0]
/// An ordered list [node spec](#model.NodeSpec). Has a single
/// attribute, `order`, which determines the number at which the list
/// starts counting, and defaults to 1. Represented as an `<ol>`
/// element.
export const orderedList = {
attrs: {order: {default: 1, validate: "number"}},
parseDOM: [{tag: "ol", getAttrs(dom: HTMLElement) {
return {order: dom.hasAttribute("start") ? +dom.getAttribute("start")! : 1}
}}],
toDOM(node) {
return node.attrs.order == 1 ? olDOM : ["ol", {start: node.attrs.order}, 0]
}
} as NodeSpec
/// A bullet list node spec, represented in the DOM as `<ul>`.
export const bulletList: NodeSpec = {
parseDOM: [{tag: "ul"}],
toDOM() { return ulDOM }
}
/// A list item (`<li>`) spec.
export const listItem: NodeSpec = {
parseDOM: [{tag: "li"}],
toDOM() { return liDOM },
defining: true
}
function add(obj: {[prop: string]: any}, props: {[prop: string]: any}) {
let copy: {[prop: string]: any} = {}
for (let prop in obj) copy[prop] = obj[prop]
for (let prop in props) copy[prop] = props[prop]
return copy
}
/// Convenience function for adding list-related node types to a map
/// specifying the nodes for a schema. Adds
/// [`orderedList`](#schema-list.orderedList) as `"ordered_list"`,
/// [`bulletList`](#schema-list.bulletList) as `"bullet_list"`, and
/// [`listItem`](#schema-list.listItem) as `"list_item"`.
///
/// `itemContent` determines the content expression for the list items.
/// If you want the commands defined in this module to apply to your
/// list structure, it should have a shape like `"paragraph block*"` or
/// `"paragraph (ordered_list | bullet_list)*"`. `listGroup` can be
/// given to assign a group name to the list node types, for example
/// `"block"`.
export function addListNodes(nodes: OrderedMap<NodeSpec>, itemContent: string, listGroup?: string): OrderedMap<NodeSpec> {
return nodes.append({
ordered_list: add(orderedList, {content: "list_item+", group: listGroup}),
bullet_list: add(bulletList, {content: "list_item+", group: listGroup}),
list_item: add(listItem, {content: itemContent})
})
}
/// Returns a command function that wraps the selection in a list with
/// the given type an attributes. If `dispatch` is null, only return a
/// value to indicate whether this is possible, but don't actually
/// perform the change.
export function wrapInList(listType: NodeType, attrs: Attrs | null = null): Command {
return function(state: EditorState, dispatch?: (tr: Transaction) => void) {
let {$from, $to} = state.selection
let range = $from.blockRange($to)
if (!range) return false
let tr = dispatch ? state.tr : null
if (!wrapRangeInList(tr, range, listType, attrs)) return false
if (dispatch) dispatch(tr!.scrollIntoView())
return true
}
}
/// Try to wrap the given node range in a list of the given type.
/// Return `true` when this is possible, `false` otherwise. When `tr`
/// is non-null, the wrapping is added to that transaction. When it is
/// `null`, the function only queries whether the wrapping is
/// possible.
export function wrapRangeInList(tr: Transaction | null, range: NodeRange, listType: NodeType, attrs: Attrs | null = null) {
let doJoin = false, outerRange = range, doc = range.$from.doc
// This is at the top of an existing list item
if (range.depth >= 2 && range.$from.node(range.depth - 1).type.compatibleContent(listType) && range.startIndex == 0) {
// Don't do anything if this is the top of the list
if (range.$from.index(range.depth - 1) == 0) return false
let $insert = doc.resolve(range.start - 2)
outerRange = new NodeRange($insert, $insert, range.depth)
if (range.endIndex < range.parent.childCount)
range = new NodeRange(range.$from, doc.resolve(range.$to.end(range.depth)), range.depth)
doJoin = true
}
let wrap = findWrapping(outerRange, listType, attrs, range)
if (!wrap) return false
if (tr) doWrapInList(tr, range, wrap, doJoin, listType)
return true
}
function doWrapInList(tr: Transaction, range: NodeRange, wrappers: {type: NodeType, attrs?: Attrs | null}[],
joinBefore: boolean, listType: NodeType) {
let content = Fragment.empty
for (let i = wrappers.length - 1; i >= 0; i--)
content = Fragment.from(wrappers[i].type.create(wrappers[i].attrs, content))
tr.step(new ReplaceAroundStep(range.start - (joinBefore ? 2 : 0), range.end, range.start, range.end,
new Slice(content, 0, 0), wrappers.length, true))
let found = 0
for (let i = 0; i < wrappers.length; i++) if (wrappers[i].type == listType) found = i + 1
let splitDepth = wrappers.length - found
let splitPos = range.start + wrappers.length - (joinBefore ? 2 : 0), parent = range.parent
for (let i = range.startIndex, e = range.endIndex, first = true; i < e; i++, first = false) {
if (!first && canSplit(tr.doc, splitPos, splitDepth)) {
tr.split(splitPos, splitDepth)
splitPos += 2 * splitDepth
}
splitPos += parent.child(i).nodeSize
}
return tr
}
/// Build a command that splits a non-empty textblock at the top level
/// of a list item by also splitting that list item.
export function splitListItem(itemType: NodeType, itemAttrs?: Attrs): Command {
return function(state: EditorState, dispatch?: (tr: Transaction) => void) {
let {$from, $to, node} = state.selection as NodeSelection
if ((node && node.isBlock) || $from.depth < 2 || !$from.sameParent($to)) return false
let grandParent = $from.node(-1)
if (grandParent.type != itemType) return false
if ($from.parent.content.size == 0 && $from.node(-1).childCount == $from.indexAfter(-1)) {
// In an empty block. If this is a nested list, the wrapping
// list item should be split. Otherwise, bail out and let next
// command handle lifting.
if ($from.depth == 3 || $from.node(-3).type != itemType ||
$from.index(-2) != $from.node(-2).childCount - 1) return false
if (dispatch) {
let wrap = Fragment.empty
let depthBefore = $from.index(-1) ? 1 : $from.index(-2) ? 2 : 3
// Build a fragment containing empty versions of the structure
// from the outer list item to the parent node of the cursor
for (let d = $from.depth - depthBefore; d >= $from.depth - 3; d--)
wrap = Fragment.from($from.node(d).copy(wrap))
let depthAfter = $from.indexAfter(-1) < $from.node(-2).childCount ? 1
: $from.indexAfter(-2) < $from.node(-3).childCount ? 2 : 3
// Add a second list item with an empty default start node
wrap = wrap.append(Fragment.from(itemType.createAndFill()))
let start = $from.before($from.depth - (depthBefore - 1))
let tr = state.tr.replace(start, $from.after(-depthAfter), new Slice(wrap, 4 - depthBefore, 0))
let sel = -1
tr.doc.nodesBetween(start, tr.doc.content.size, (node, pos) => {
if (sel > -1) return false
if (node.isTextblock && node.content.size == 0) sel = pos + 1
})
if (sel > -1) tr.setSelection(Selection.near(tr.doc.resolve(sel)))
dispatch(tr.scrollIntoView())
}
return true
}
let nextType = $to.pos == $from.end() ? grandParent.contentMatchAt(0).defaultType : null
let tr = state.tr.delete($from.pos, $to.pos)
let types = nextType ? [itemAttrs ? {type: itemType, attrs: itemAttrs} : null, {type: nextType}] : undefined
if (!canSplit(tr.doc, $from.pos, 2, types)) return false
if (dispatch) dispatch(tr.split($from.pos, 2, types).scrollIntoView())
return true
}
}
/// Acts like [`splitListItem`](#schema-list.splitListItem), but
/// without resetting the set of active marks at the cursor.
export function splitListItemKeepMarks(itemType: NodeType, itemAttrs?: Attrs): Command {
let split = splitListItem(itemType, itemAttrs)
return (state, dispatch) => {
return split(state, dispatch && (tr => {
let marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks())
if (marks) tr.ensureMarks(marks)
dispatch(tr)
}))
}
}
/// Create a command to lift the list item around the selection up into
/// a wrapping list.
export function liftListItem(itemType: NodeType): Command {
return function(state: EditorState, dispatch?: (tr: Transaction) => void) {
let {$from, $to} = state.selection
let range = $from.blockRange($to, node => node.childCount > 0 && node.firstChild!.type == itemType)
if (!range) return false
if (!dispatch) return true
if ($from.node(range.depth - 1).type == itemType) // Inside a parent list
return liftToOuterList(state, dispatch, itemType, range)
else // Outer list node
return liftOutOfList(state, dispatch, range)
}
}
function liftToOuterList(state: EditorState, dispatch: (tr: Transaction) => void, itemType: NodeType, range: NodeRange) {
let tr = state.tr, end = range.end, endOfList = range.$to.end(range.depth)
if (end < endOfList) {
// There are siblings after the lifted items, which must become
// children of the last item
tr.step(new ReplaceAroundStep(end - 1, endOfList, end, endOfList,
new Slice(Fragment.from(itemType.create(null, range.parent.copy())), 1, 0), 1, true))
range = new NodeRange(tr.doc.resolve(range.$from.pos), tr.doc.resolve(endOfList), range.depth)
}
const target = liftTarget(range)
if (target == null) return false
tr.lift(range, target)
let $after = tr.doc.resolve(tr.mapping.map(end, -1) - 1)
if (canJoin(tr.doc, $after.pos) && $after.nodeBefore!.type == $after.nodeAfter!.type) tr.join($after.pos)
dispatch(tr.scrollIntoView())
return true
}
function liftOutOfList(state: EditorState, dispatch: (tr: Transaction) => void, range: NodeRange) {
let tr = state.tr, list = range.parent
// Merge the list items into a single big item
for (let pos = range.end, i = range.endIndex - 1, e = range.startIndex; i > e; i--) {
pos -= list.child(i).nodeSize
tr.delete(pos - 1, pos + 1)
}
let $start = tr.doc.resolve(range.start), item = $start.nodeAfter!
if (tr.mapping.map(range.end) != range.start + $start.nodeAfter!.nodeSize) return false
let atStart = range.startIndex == 0, atEnd = range.endIndex == list.childCount
let parent = $start.node(-1), indexBefore = $start.index(-1)
if (!parent.canReplace(indexBefore + (atStart ? 0 : 1), indexBefore + 1,
item.content.append(atEnd ? Fragment.empty : Fragment.from(list))))
return false
let start = $start.pos, end = start + item.nodeSize
// Strip off the surrounding list. At the sides where we're not at
// the end of the list, the existing list is closed. At sides where
// this is the end, it is overwritten to its end.
tr.step(new ReplaceAroundStep(start - (atStart ? 1 : 0), end + (atEnd ? 1 : 0), start + 1, end - 1,
new Slice((atStart ? Fragment.empty : Fragment.from(list.copy(Fragment.empty)))
.append(atEnd ? Fragment.empty : Fragment.from(list.copy(Fragment.empty))),
atStart ? 0 : 1, atEnd ? 0 : 1), atStart ? 0 : 1))
dispatch(tr.scrollIntoView())
return true
}
/// Create a command to sink the list item around the selection down
/// into an inner list.
export function sinkListItem(itemType: NodeType): Command {
return function(state, dispatch) {
let {$from, $to} = state.selection
let range = $from.blockRange($to, node => node.childCount > 0 && node.firstChild!.type == itemType)
if (!range) return false
let startIndex = range.startIndex
if (startIndex == 0) return false
let parent = range.parent, nodeBefore = parent.child(startIndex - 1)
if (nodeBefore.type != itemType) return false
if (dispatch) {
let nestedBefore = nodeBefore.lastChild && nodeBefore.lastChild.type == parent.type
let inner = Fragment.from(nestedBefore ? itemType.create() : null)
let slice = new Slice(Fragment.from(itemType.create(null, Fragment.from(parent.type.create(null, inner)))),
nestedBefore ? 3 : 1, 0)
let before = range.start, after = range.end
dispatch(state.tr.step(new ReplaceAroundStep(before - (nestedBefore ? 3 : 1), after,
before, after, slice, 1, true))
.scrollIntoView())
}
return true
}
}