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 89cf92eaf5
commit f2876f877e
1491 changed files with 265550 additions and 1292 deletions
+263
View File
@@ -0,0 +1,263 @@
import {Slice, Fragment, DOMParser, DOMSerializer, ResolvedPos, NodeType, Node} from "prosemirror-model"
import * as browser from "./browser"
import {EditorView} from "./index"
export function serializeForClipboard(view: EditorView, slice: Slice) {
view.someProp("transformCopied", f => { slice = f(slice!, view) })
let context = [], {content, openStart, openEnd} = slice
while (openStart > 1 && openEnd > 1 && content.childCount == 1 && content.firstChild!.childCount == 1) {
openStart--
openEnd--
let node = content.firstChild!
context.push(node.type.name, node.attrs != node.type.defaultAttrs ? node.attrs : null)
content = node.content
}
let serializer = view.someProp("clipboardSerializer") || DOMSerializer.fromSchema(view.state.schema)
let doc = detachedDoc(), wrap = doc.createElement("div")
wrap.appendChild(serializer.serializeFragment(content, {document: doc}))
let firstChild = wrap.firstChild, needsWrap, wrappers = 0
while (firstChild && firstChild.nodeType == 1 && (needsWrap = wrapMap[firstChild.nodeName.toLowerCase()])) {
for (let i = needsWrap.length - 1; i >= 0; i--) {
let wrapper = doc.createElement(needsWrap[i])
while (wrap.firstChild) wrapper.appendChild(wrap.firstChild)
wrap.appendChild(wrapper)
wrappers++
}
firstChild = wrap.firstChild
}
if (firstChild && firstChild.nodeType == 1)
(firstChild as HTMLElement).setAttribute(
"data-pm-slice", `${openStart} ${openEnd}${wrappers ? ` -${wrappers}` : ""} ${JSON.stringify(context)}`)
let text = view.someProp("clipboardTextSerializer", f => f(slice, view)) ||
slice.content.textBetween(0, slice.content.size, "\n\n")
return {dom: wrap, text, slice}
}
// Read a slice of content from the clipboard (or drop data).
export function parseFromClipboard(view: EditorView, text: string, html: string | null, plainText: boolean, $context: ResolvedPos) {
let inCode = $context.parent.type.spec.code
let dom: HTMLElement | undefined, slice: Slice | undefined
if (!html && !text) return null
let asText = !!text && (plainText || inCode || !html)
if (asText) {
view.someProp("transformPastedText", f => { text = f(text, inCode || plainText, view) })
if (inCode) {
slice = new Slice(Fragment.from(view.state.schema.text(text.replace(/\r\n?/g, "\n"))), 0, 0)
view.someProp("transformPasted", f => { slice = f(slice!, view, true) })
return slice
}
let parsed = view.someProp("clipboardTextParser", f => f(text, $context, plainText, view))
if (parsed) {
slice = parsed
} else {
let marks = $context.marks()
let {schema} = view.state, serializer = DOMSerializer.fromSchema(schema)
dom = document.createElement("div")
text.split(/(?:\r\n?|\n)+/).forEach(block => {
let p = dom!.appendChild(document.createElement("p"))
if (block) p.appendChild(serializer.serializeNode(schema.text(block, marks)))
})
}
} else {
view.someProp("transformPastedHTML", f => { html = f(html!, view) })
dom = readHTML(html!)
if (browser.webkit) restoreReplacedSpaces(dom)
}
let contextNode = dom && dom.querySelector("[data-pm-slice]")
let sliceData = contextNode && /^(\d+) (\d+)(?: -(\d+))? (.*)/.exec(contextNode.getAttribute("data-pm-slice") || "")
if (sliceData && sliceData[3]) for (let i = +sliceData[3]; i > 0; i--) {
let child = dom!.firstChild
while (child && child.nodeType != 1) child = child.nextSibling
if (!child) break
dom = child as HTMLElement
}
if (!slice) {
let parser = view.someProp("clipboardParser") || view.someProp("domParser") || DOMParser.fromSchema(view.state.schema)
slice = parser.parseSlice(dom!, {
preserveWhitespace: !!(asText || sliceData),
context: $context,
ruleFromNode(dom) {
if (dom.nodeName == "BR" && !dom.nextSibling &&
dom.parentNode && !inlineParents.test(dom.parentNode.nodeName)) return {ignore: true}
return null
}
})
}
if (sliceData) {
slice = addContext(closeSlice(slice, +sliceData[1], +sliceData[2]), sliceData[4])
} else { // HTML wasn't created by ProseMirror. Make sure top-level siblings are coherent
slice = Slice.maxOpen(normalizeSiblings(slice.content, $context), true)
if (slice.openStart || slice.openEnd) {
let openStart = 0, openEnd = 0
for (let node = slice.content.firstChild; openStart < slice.openStart && !node!.type.spec.isolating;
openStart++, node = node!.firstChild) {}
for (let node = slice.content.lastChild; openEnd < slice.openEnd && !node!.type.spec.isolating;
openEnd++, node = node!.lastChild) {}
slice = closeSlice(slice, openStart, openEnd)
}
}
view.someProp("transformPasted", f => { slice = f(slice!, view, asText) })
return slice
}
const inlineParents = /^(a|abbr|acronym|b|cite|code|del|em|i|ins|kbd|label|output|q|ruby|s|samp|span|strong|sub|sup|time|u|tt|var)$/i
// Takes a slice parsed with parseSlice, which means there hasn't been
// any content-expression checking done on the top nodes, tries to
// find a parent node in the current context that might fit the nodes,
// and if successful, rebuilds the slice so that it fits into that parent.
//
// This addresses the problem that Transform.replace expects a
// coherent slice, and will fail to place a set of siblings that don't
// fit anywhere in the schema.
function normalizeSiblings(fragment: Fragment, $context: ResolvedPos) {
if (fragment.childCount < 2) return fragment
for (let d = $context.depth; d >= 0; d--) {
let parent = $context.node(d)
let match = parent.contentMatchAt($context.index(d))
let lastWrap: readonly NodeType[] | undefined, result: Node[] | null = []
fragment.forEach(node => {
if (!result) return
let wrap = match.findWrapping(node.type), inLast
if (!wrap) return result = null
if (inLast = result.length && lastWrap!.length && addToSibling(wrap, lastWrap!, node, result[result.length - 1], 0)) {
result[result.length - 1] = inLast
} else {
if (result.length) result[result.length - 1] = closeRight(result[result.length - 1], lastWrap!.length)
let wrapped = withWrappers(node, wrap)
result.push(wrapped)
match = match.matchType(wrapped.type)!
lastWrap = wrap
}
})
if (result) return Fragment.from(result)
}
return fragment
}
function withWrappers(node: Node, wrap: readonly NodeType[], from = 0) {
for (let i = wrap.length - 1; i >= from; i--)
node = wrap[i].create(null, Fragment.from(node))
return node
}
// Used to group adjacent nodes wrapped in similar parents by
// normalizeSiblings into the same parent node
function addToSibling(wrap: readonly NodeType[], lastWrap: readonly NodeType[],
node: Node, sibling: Node, depth: number): Node | undefined {
if (depth < wrap.length && depth < lastWrap.length && wrap[depth] == lastWrap[depth]) {
let inner = addToSibling(wrap, lastWrap, node, sibling.lastChild!, depth + 1)
if (inner) return sibling.copy(sibling.content.replaceChild(sibling.childCount - 1, inner))
let match = sibling.contentMatchAt(sibling.childCount)
if (match.matchType(depth == wrap.length - 1 ? node.type : wrap[depth + 1]))
return sibling.copy(sibling.content.append(Fragment.from(withWrappers(node, wrap, depth + 1))))
}
}
function closeRight(node: Node, depth: number) {
if (depth == 0) return node
let fragment = node.content.replaceChild(node.childCount - 1, closeRight(node.lastChild!, depth - 1))
let fill = node.contentMatchAt(node.childCount).fillBefore(Fragment.empty, true)!
return node.copy(fragment.append(fill))
}
function closeRange(fragment: Fragment, side: number, from: number, to: number, depth: number, openEnd: number) {
let node = side < 0 ? fragment.firstChild! : fragment.lastChild!, inner = node.content
if (fragment.childCount > 1) openEnd = 0
if (depth < to - 1) inner = closeRange(inner, side, from, to, depth + 1, openEnd)
if (depth >= from)
inner = side < 0 ? node.contentMatchAt(0)!.fillBefore(inner, openEnd <= depth)!.append(inner)
: inner.append(node.contentMatchAt(node.childCount)!.fillBefore(Fragment.empty, true)!)
return fragment.replaceChild(side < 0 ? 0 : fragment.childCount - 1, node.copy(inner))
}
function closeSlice(slice: Slice, openStart: number, openEnd: number) {
if (openStart < slice.openStart)
slice = new Slice(closeRange(slice.content, -1, openStart, slice.openStart, 0, slice.openEnd), openStart, slice.openEnd)
if (openEnd < slice.openEnd)
slice = new Slice(closeRange(slice.content, 1, openEnd, slice.openEnd, 0, 0), slice.openStart, openEnd)
return slice
}
// Trick from jQuery -- some elements must be wrapped in other
// elements for innerHTML to work. I.e. if you do `div.innerHTML =
// "<td>..</td>"` the table cells are ignored.
const wrapMap: {[node: string]: string[]} = {
thead: ["table"],
tbody: ["table"],
tfoot: ["table"],
caption: ["table"],
colgroup: ["table"],
col: ["table", "colgroup"],
tr: ["table", "tbody"],
td: ["table", "tbody", "tr"],
th: ["table", "tbody", "tr"]
}
let _detachedDoc: Document | null = null
function detachedDoc() {
return _detachedDoc || (_detachedDoc = document.implementation.createHTMLDocument("title"))
}
let _policy: any = null
function maybeWrapTrusted(html: string): string {
let trustedTypes = (window as any).trustedTypes
if (!trustedTypes) return html
// With the require-trusted-types-for CSP, Chrome will block
// innerHTML, even on a detached document. This wraps the string in
// a way that makes the browser allow us to use its parser again.
if (!_policy)
_policy = trustedTypes.defaultPolicy || trustedTypes.createPolicy("ProseMirrorClipboard", {createHTML: (s: string) => s})
return _policy.createHTML(html)
}
function readHTML(html: string) {
let metas = /^(\s*<meta [^>]*>)*/.exec(html)
if (metas) html = html.slice(metas[0].length)
let elt = detachedDoc().createElement("div")
let firstTag = /<([a-z][^>\s]+)/i.exec(html), wrap
if (wrap = firstTag && wrapMap[firstTag[1].toLowerCase()])
html = wrap.map(n => "<" + n + ">").join("") + html + wrap.map(n => "</" + n + ">").reverse().join("")
elt.innerHTML = maybeWrapTrusted(html)
if (wrap) for (let i = 0; i < wrap.length; i++) elt = elt.querySelector(wrap[i]) || elt
return elt
}
// Webkit browsers do some hard-to-predict replacement of regular
// spaces with non-breaking spaces when putting content on the
// clipboard. This tries to convert such non-breaking spaces (which
// will be wrapped in a plain span on Chrome, a span with class
// Apple-converted-space on Safari) back to regular spaces.
function restoreReplacedSpaces(dom: HTMLElement) {
let nodes = dom.querySelectorAll(browser.chrome ? "span:not([class]):not([style])" : "span.Apple-converted-space")
for (let i = 0; i < nodes.length; i++) {
let node = nodes[i]
if (node.childNodes.length == 1 && node.textContent == "\u00a0" && node.parentNode)
node.parentNode.replaceChild(dom.ownerDocument.createTextNode(" "), node)
}
}
function addContext(slice: Slice, context: string) {
if (!slice.size) return slice
let schema = slice.content.firstChild!.type.schema, array
try { array = JSON.parse(context) }
catch(e) { return slice }
let {content, openStart, openEnd} = slice
for (let i = array.length - 2; i >= 0; i -= 2) {
let type = schema.nodes[array[i]]
if (!type || type.hasRequiredAttrs()) break
content = Fragment.from(type.create(array[i + 1], content))
openStart++; openEnd++
}
return new Slice(content, openStart, openEnd)
}