mirror of
https://github.com/marktext/marktext.git
synced 2025-05-15 08:20:24 +08:00
update: remove some unused code (#607)
This commit is contained in:
parent
2ce05829d7
commit
dbe8d28a2f
@ -5,7 +5,7 @@ export default function highlight (h, block, rStart, rEnd, token) {
|
||||
const { text } = block
|
||||
const { highlights } = token
|
||||
let result = []
|
||||
let unions = []
|
||||
const unions = []
|
||||
let pos = rStart
|
||||
|
||||
if (highlights) {
|
||||
|
@ -89,37 +89,6 @@ export const getFirstSelectableLeafNode = element => {
|
||||
return element
|
||||
}
|
||||
|
||||
export const isElementAtBeginningOfBlock = node => {
|
||||
let textVal
|
||||
let sibling
|
||||
while (!isBlockContainer(node) && !isAganippeEditorElement(node)) {
|
||||
sibling = node.previousSibling
|
||||
while (sibling) {
|
||||
textVal = sibling.nodeType === 3 ? sibling.nodeValue : sibling.textContent
|
||||
if (textVal.length > 0) {
|
||||
return false
|
||||
}
|
||||
sibling = sibling.previousSibling
|
||||
}
|
||||
node = node.parentNode
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
export const findPreviousSibling = node => {
|
||||
if (!node || isAganippeEditorElement(node)) {
|
||||
return false
|
||||
}
|
||||
|
||||
let previousSibling = node.previousSibling
|
||||
while (!previousSibling && !isAganippeEditorElement(node.parentNode)) {
|
||||
node = node.parentNode
|
||||
previousSibling = node.previousSibling
|
||||
}
|
||||
|
||||
return previousSibling
|
||||
}
|
||||
|
||||
export const getClosestBlockContainer = node => {
|
||||
return traverseUp(node, node => {
|
||||
return isBlockContainer(node) || isAganippeEditorElement(node)
|
||||
|
@ -5,10 +5,7 @@
|
||||
import {
|
||||
isBlockContainer,
|
||||
traverseUp,
|
||||
isAganippeEditorElement,
|
||||
getFirstSelectableLeafNode,
|
||||
isElementAtBeginningOfBlock,
|
||||
findPreviousSibling,
|
||||
getClosestBlockContainer,
|
||||
getCursorPositionWithinMarkedText,
|
||||
compareParagraphsOrder,
|
||||
@ -42,60 +39,6 @@ class Selection {
|
||||
return traverseUp(current, testElementFunction)
|
||||
}
|
||||
|
||||
getSelectionElement (contentWindow) {
|
||||
return this.findMatchingSelectionParent(el => {
|
||||
return isAganippeEditorElement(el)
|
||||
}, contentWindow)
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/17678843/cant-restore-selection-after-html-modify-even-if-its-the-same-html
|
||||
// Tim Down
|
||||
exportSelection (root) {
|
||||
if (!root) {
|
||||
return null
|
||||
}
|
||||
|
||||
let selectionState = null
|
||||
const selection = this.doc.getSelection()
|
||||
|
||||
if (selection.rangeCount > 0) {
|
||||
const range = selection.getRangeAt(0)
|
||||
const preSelectionRange = range.cloneRange()
|
||||
|
||||
preSelectionRange.selectNodeContents(root)
|
||||
preSelectionRange.setEnd(range.startContainer, range.startOffset)
|
||||
|
||||
const start = preSelectionRange.toString().length
|
||||
selectionState = {
|
||||
start,
|
||||
end: start + range.toString().length
|
||||
}
|
||||
|
||||
// Check to see if the selection starts with any images
|
||||
// if so we need to make sure the the beginning of the selection is
|
||||
// set correctly when importing selection
|
||||
if (this.doesRangeStartWithImages(range)) {
|
||||
selectionState.startsWithImage = true
|
||||
}
|
||||
|
||||
// Check to see if the selection has any trailing images
|
||||
// if so, this this means we need to look for them when we import selection
|
||||
const trailingImageCount = this.getTrailingImageCount(root, selectionState, range.endContainer, range.endOffset)
|
||||
if (trailingImageCount) {
|
||||
selectionState.trailingImageCount = trailingImageCount
|
||||
}
|
||||
|
||||
// If start = 0 there may still be an empty paragraph before it, but we don't care.
|
||||
if (start !== 0) {
|
||||
const emptyBlocksIndex = this.getIndexRelativeToAdjacentEmptyBlocks(root, range.startContainer, range.startOffset)
|
||||
if (emptyBlocksIndex !== -1) {
|
||||
selectionState.emptyBlocksIndex = emptyBlocksIndex
|
||||
}
|
||||
}
|
||||
}
|
||||
return selectionState
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/17678843/cant-restore-selection-after-html-modify-even-if-its-the-same-html
|
||||
// Tim Down
|
||||
//
|
||||
@ -314,207 +257,6 @@ class Selection {
|
||||
return range
|
||||
}
|
||||
|
||||
// Returns -1 unless the cursor is at the beginning of a paragraph/block
|
||||
// If the paragraph/block is preceded by empty paragraphs/block (with no text)
|
||||
// it will return the number of empty paragraphs before the cursor.
|
||||
// Otherwise, it will return 0, which indicates the cursor is at the beginning
|
||||
// of a paragraph/block, and not at the end of the paragraph/block before it
|
||||
getIndexRelativeToAdjacentEmptyBlocks (root, cursorContainer, cursorOffset) {
|
||||
// If there is text in front of the cursor, that means there isn't only empty blocks before it
|
||||
if (cursorContainer.textContent.length > 0 && cursorOffset > 0) {
|
||||
return -1
|
||||
}
|
||||
|
||||
// Check if the block that contains the cursor has any other text in front of the cursor
|
||||
let node = cursorContainer
|
||||
if (node.nodeType !== 3) {
|
||||
node = cursorContainer.childNodes[cursorOffset]
|
||||
}
|
||||
if (node) {
|
||||
// The element isn't at the beginning of a block, so it has content before it
|
||||
if (!isElementAtBeginningOfBlock(node)) {
|
||||
return -1
|
||||
}
|
||||
|
||||
const previousSibling = findPreviousSibling(node)
|
||||
// If there is no previous sibling, this is the first text element in the editor
|
||||
if (!previousSibling) {
|
||||
return -1
|
||||
} else if (previousSibling.nodeValue) {
|
||||
// If the previous sibling has text, then there are no empty blocks before this
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
// Walk over block elements, counting number of empty blocks between last piece of text
|
||||
// and the block the cursor is in
|
||||
const closestBlock = getClosestBlockContainer(cursorContainer)
|
||||
const treeWalker = this.doc.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, filterOnlyParentElements, false)
|
||||
let emptyBlocksCount = 0
|
||||
while (treeWalker.nextNode()) {
|
||||
const blockIsEmpty = treeWalker.currentNode.textContent === ''
|
||||
if (blockIsEmpty || emptyBlocksCount > 0) {
|
||||
emptyBlocksCount += 1
|
||||
}
|
||||
if (treeWalker.currentNode === closestBlock) {
|
||||
return emptyBlocksCount
|
||||
}
|
||||
if (!blockIsEmpty) {
|
||||
emptyBlocksCount = 0
|
||||
}
|
||||
}
|
||||
|
||||
return emptyBlocksCount
|
||||
}
|
||||
|
||||
// Returns true if the selection range begins with an image tag
|
||||
// Returns false if the range starts with any non empty text nodes
|
||||
doesRangeStartWithImages (range) {
|
||||
if (range.startOffset !== 0 || range.startContainer.nodeType !== 1) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (range.startContainer.nodeName.toLowerCase() === 'img') {
|
||||
return true
|
||||
}
|
||||
|
||||
const img = range.startContainer.querySelector('img')
|
||||
if (!img) {
|
||||
return false
|
||||
}
|
||||
|
||||
const treeWalker = this.doc.createTreeWalker(range.startContainer, NodeFilter.SHOW_ALL, null, false)
|
||||
while (treeWalker.nextNode()) {
|
||||
const next = treeWalker.currentNode
|
||||
// If we hit the image, then there isn't any text before the image so
|
||||
// the image is at the beginning of the range
|
||||
if (next === img) {
|
||||
break
|
||||
}
|
||||
// If we haven't hit the iamge, but found text that contains content
|
||||
// then the range doesn't start with an image
|
||||
if (next.nodeValue) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
getTrailingImageCount (root, selectionState, endContainer, endOffset) {
|
||||
// If the endOffset of a range is 0, the endContainer doesn't contain images
|
||||
// If the endContainer is a text node, there are no trailing images
|
||||
if (endOffset === 0 || endContainer.nodeType !== 1) {
|
||||
return 0
|
||||
}
|
||||
|
||||
// If the endContainer isn't an image, and doesn't have an image descendants
|
||||
// there are no trailing images
|
||||
if (endContainer.nodeName.toLowerCase() !== 'img' && !endContainer.querySelector('img')) {
|
||||
return 0
|
||||
}
|
||||
|
||||
let lastNode = endContainer.childNodes[endOffset - 1]
|
||||
while (lastNode.hasChildNodes()) {
|
||||
lastNode = lastNode.lastChild
|
||||
}
|
||||
|
||||
let node = root
|
||||
const nodeStack = []
|
||||
let charIndex = 0
|
||||
let foundStart = false
|
||||
let foundEnd = false
|
||||
let stop = false
|
||||
let nextCharIndex
|
||||
let trailingImages = 0
|
||||
|
||||
while (!stop && node) {
|
||||
// Only iterate over elements and text nodes
|
||||
if (node.nodeType > 3) {
|
||||
node = nodeStack.pop()
|
||||
continue
|
||||
}
|
||||
|
||||
if (node.nodeType === 3 && !foundEnd) {
|
||||
trailingImages = 0
|
||||
nextCharIndex = charIndex + node.length
|
||||
if (!foundStart && selectionState.start >= charIndex && selectionState.start <= nextCharIndex) {
|
||||
foundStart = true
|
||||
}
|
||||
if (foundStart && selectionState.end >= charIndex && selectionState.end <= nextCharIndex) {
|
||||
foundEnd = true
|
||||
}
|
||||
charIndex = nextCharIndex
|
||||
} else {
|
||||
if (node.nodeName.toLowerCase() === 'img') {
|
||||
trailingImages++
|
||||
}
|
||||
|
||||
if (node === lastNode) {
|
||||
stop = true
|
||||
} else if (node.nodeType === 1) {
|
||||
// this is an element
|
||||
// add all its children to the stack
|
||||
let i = node.childNodes.length - 1
|
||||
while (i >= 0) {
|
||||
nodeStack.push(node.childNodes[i])
|
||||
i -= 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!stop) {
|
||||
node = nodeStack.pop()
|
||||
}
|
||||
}
|
||||
|
||||
return trailingImages
|
||||
}
|
||||
|
||||
// determine if the current selection contains any 'content'
|
||||
// content being any non-white space text or an image
|
||||
selectionContainsContent () {
|
||||
const sel = this.doc.getSelection()
|
||||
|
||||
// collapsed selection or selection withour range doesn't contain content
|
||||
if (!sel || sel.isCollapsed || !sel.rangeCount) {
|
||||
return false
|
||||
}
|
||||
|
||||
// if toString() contains any text, the selection contains some content
|
||||
if (sel.toString().trim() !== '') {
|
||||
return true
|
||||
}
|
||||
|
||||
// if selection contains only image(s), it will return empty for toString()
|
||||
// so check for an image manually
|
||||
const selectionNode = this.getSelectedParentElement(sel.getRangeAt(0))
|
||||
if (selectionNode) {
|
||||
if (selectionNode.nodeName.toLowerCase() === 'img' ||
|
||||
(selectionNode.nodeType === 1 && selectionNode.querySelector('img'))) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
selectionInContentEditableFalse (contentWindow) {
|
||||
// determine if the current selection is exclusively inside
|
||||
// a contenteditable="false", though treat the case of an
|
||||
// explicit contenteditable="true" inside a "false" as false.
|
||||
let sawtrue
|
||||
const sawfalse = this.findMatchingSelectionParent(function (el) {
|
||||
const ce = el && el.getAttribute('contenteditable')
|
||||
if (ce === 'true') {
|
||||
sawtrue = true
|
||||
}
|
||||
return el.nodeName !== '#text' && ce === 'false'
|
||||
}, contentWindow)
|
||||
|
||||
return !sawtrue && sawfalse
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/4176923/html-of-selected-text
|
||||
// by Tim Down
|
||||
getSelectionHtml () {
|
||||
@ -593,61 +335,6 @@ class Selection {
|
||||
}
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/15867542/range-object-get-selection-parent-node-chrome-vs-firefox
|
||||
rangeSelectsSingleNode (range) {
|
||||
const startNode = range.startContainer
|
||||
return startNode === range.endContainer &&
|
||||
startNode.hasChildNodes() &&
|
||||
range.endOffset === range.startOffset + 1
|
||||
}
|
||||
|
||||
getSelectedParentElement (range) {
|
||||
if (!range) {
|
||||
return null
|
||||
}
|
||||
|
||||
// Selection encompasses a single element
|
||||
if (this.rangeSelectsSingleNode(range) && range.startContainer.childNodes[range.startOffset].nodeType !== 3) {
|
||||
return range.startContainer.childNodes[range.startOffset]
|
||||
}
|
||||
|
||||
// Selection range starts inside a text node, so get its parent
|
||||
if (range.startContainer.nodeType === 3) {
|
||||
return range.startContainer.parentNode
|
||||
}
|
||||
|
||||
// Selection starts inside an element
|
||||
return range.startContainer
|
||||
}
|
||||
|
||||
getSelectedElements () {
|
||||
const selection = this.doc.getSelection()
|
||||
let range
|
||||
let toRet
|
||||
let currNode
|
||||
|
||||
if (!selection.rangeCount || selection.isCollapsed || !selection.getRangeAt(0).commonAncestorContainer) {
|
||||
return []
|
||||
}
|
||||
|
||||
range = selection.getRangeAt(0)
|
||||
|
||||
if (range.commonAncestorContainer.nodeType === 3) {
|
||||
toRet = []
|
||||
currNode = range.commonAncestorContainer
|
||||
while (currNode.parentNode && currNode.parentNode.childNodes.length === 1) {
|
||||
toRet.push(currNode.parentNode)
|
||||
currNode = currNode.parentNode
|
||||
}
|
||||
|
||||
return toRet
|
||||
}
|
||||
|
||||
return [].filter.call(range.commonAncestorContainer.getElementsByTagName('*'), function (el) {
|
||||
return (typeof selection.containsNode === 'function') ? selection.containsNode(el, true) : true
|
||||
})
|
||||
}
|
||||
|
||||
selectNode (node) {
|
||||
const range = this.doc.createRange()
|
||||
range.selectNodeContents(node)
|
||||
|
Loading…
Reference in New Issue
Block a user