create link without autocomplete
This commit is contained in:
@@ -13,10 +13,7 @@ export default class ContextedLinkEditing extends Plugin {
|
|||||||
const twoStepCaretMovementPlugin = this.editor.plugins.get(TwoStepCaretMovement)
|
const twoStepCaretMovementPlugin = this.editor.plugins.get(TwoStepCaretMovement)
|
||||||
twoStepCaretMovementPlugin.registerAttribute('contextedLink')
|
twoStepCaretMovementPlugin.registerAttribute('contextedLink')
|
||||||
inlineHighlight(this.editor, 'contextedLink', 'a', HIGHLIGHT_CLASS)
|
inlineHighlight(this.editor, 'contextedLink', 'a', HIGHLIGHT_CLASS)
|
||||||
this.editor.commands.add(
|
this.editor.commands.add('autocomplete', new AttributeCommand(this.editor, 'autocomplete'))
|
||||||
'autocomplete',
|
|
||||||
new AttributeCommand(this.editor, 'autocomplete')
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
afterInit() {
|
afterInit() {
|
||||||
this._addAutocomplete()
|
this._addAutocomplete()
|
||||||
@@ -27,7 +24,7 @@ export default class ContextedLinkEditing extends Plugin {
|
|||||||
|
|
||||||
// Extend the text node's schema to accept the abbreviation attribute.
|
// Extend the text node's schema to accept the abbreviation attribute.
|
||||||
schema.extend('$text', {
|
schema.extend('$text', {
|
||||||
allowAttributes: ['contextedLink', 'autocomplete'],
|
allowAttributes: ['contextedLink', 'autocomplete']
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
_defineConverters() {
|
_defineConverters() {
|
||||||
@@ -43,19 +40,19 @@ export default class ContextedLinkEditing extends Plugin {
|
|||||||
const { writer } = conversionApi
|
const { writer } = conversionApi
|
||||||
|
|
||||||
return writer.createAttributeElement('a', {
|
return writer.createAttributeElement('a', {
|
||||||
'data-contexted-link': modelAttributeValue,
|
'data-contexted-link': modelAttributeValue
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
})
|
})
|
||||||
conversion.for('upcast').elementToAttribute({
|
conversion.for('upcast').elementToAttribute({
|
||||||
view: {
|
view: {
|
||||||
name: 'a',
|
name: 'a',
|
||||||
key: 'data-contexted-link',
|
key: 'data-contexted-link'
|
||||||
},
|
},
|
||||||
model: {
|
model: {
|
||||||
key: 'contextedLink',
|
key: 'contextedLink'
|
||||||
},
|
},
|
||||||
converterPriority: 'high',
|
converterPriority: 'high'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
_addAutocomplete() {
|
_addAutocomplete() {
|
||||||
@@ -83,7 +80,7 @@ export default class ContextedLinkEditing extends Plugin {
|
|||||||
const focus = selection.focus
|
const focus = selection.focus
|
||||||
const block = focus?.parent
|
const block = focus?.parent
|
||||||
if (!block || !focus) return
|
if (!block || !focus) return
|
||||||
const { text } = getTextAfterCode(
|
const { text, range } = getTextAfterCode(
|
||||||
model.createRange(model.createPositionAt(block, 0), focus),
|
model.createRange(model.createPositionAt(block, 0), focus),
|
||||||
model
|
model
|
||||||
)
|
)
|
||||||
@@ -91,9 +88,7 @@ export default class ContextedLinkEditing extends Plugin {
|
|||||||
const autocompleteText = (inputText as string).match(/(?<=\[\[).*/g)
|
const autocompleteText = (inputText as string).match(/(?<=\[\[).*/g)
|
||||||
const cursorNodes = [focus.textNode, focus.nodeBefore, focus.nodeAfter]
|
const cursorNodes = [focus.textNode, focus.nodeBefore, focus.nodeAfter]
|
||||||
const autocompleteNode: any = cursorNodes.find((node) =>
|
const autocompleteNode: any = cursorNodes.find((node) =>
|
||||||
['contextedLink', 'autocomplete'].some((attribute) =>
|
['contextedLink', 'autocomplete'].some((attribute) => node?.hasAttribute(attribute))
|
||||||
node?.hasAttribute(attribute)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if (Boolean(autocompleteText) !== Boolean(autocompleteNode)) {
|
if (Boolean(autocompleteText) !== Boolean(autocompleteNode)) {
|
||||||
@@ -104,6 +99,35 @@ export default class ContextedLinkEditing extends Plugin {
|
|||||||
})
|
})
|
||||||
showAutocomplete = autocompleteActive
|
showAutocomplete = autocompleteActive
|
||||||
fireAutocompleteEvent(editor, showAutocomplete, autocompleteNode)
|
fireAutocompleteEvent(editor, showAutocomplete, autocompleteNode)
|
||||||
|
|
||||||
|
const regexFormat = /(\[\[)([^[]+?)(\]\])$/g
|
||||||
|
let result
|
||||||
|
const format: Array<number>[] = []
|
||||||
|
while ((result = regexFormat.exec(text as string)) !== null) {
|
||||||
|
if (result && result.length < 4) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
let index = result.index
|
||||||
|
const { '1': leftDel, '2': content, '3': rightDel } = result
|
||||||
|
// Real matched string - there might be some non-capturing groups so we need to recalculate starting index.
|
||||||
|
const found = leftDel + content + rightDel
|
||||||
|
index += result[0].length - found.length
|
||||||
|
format.push([index + leftDel.length, index + leftDel.length + content.length])
|
||||||
|
}
|
||||||
|
model.enqueueChange((writer) => {
|
||||||
|
const rangesToFormat = format.map((array) =>
|
||||||
|
model.createRange(range.start.getShiftedBy(array[0]), range.start.getShiftedBy(array[1]))
|
||||||
|
)
|
||||||
|
|
||||||
|
const validRanges = editor.model.schema.getValidRanges(rangesToFormat, 'contextedLink')
|
||||||
|
for (const range of validRanges) {
|
||||||
|
for (const item of range.getItems()) {
|
||||||
|
if ((item as any).data) {
|
||||||
|
writer.setAttribute('contextedLink', true, range)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
_addContextedKeyHandler() {
|
_addContextedKeyHandler() {
|
||||||
@@ -121,15 +145,15 @@ export default class ContextedLinkEditing extends Plugin {
|
|||||||
}
|
}
|
||||||
const keyCodes = [...keyCodesConfirm, ...keyCodesCycle]
|
const keyCodes = [...keyCodesConfirm, ...keyCodesCycle]
|
||||||
const selection = editor.model.document.selection
|
const selection = editor.model.document.selection
|
||||||
const selectionInContextedLink = ['contextedLink', 'autocomplete'].some(
|
const selectionInContextedLink = ['contextedLink', 'autocomplete'].some((attribute) =>
|
||||||
(attribute) => selection.hasAttribute(attribute)
|
selection.hasAttribute(attribute)
|
||||||
)
|
)
|
||||||
if (selectionInContextedLink && keyCodes.includes(keyCode)) {
|
if (selectionInContextedLink && keyCodes.includes(keyCode)) {
|
||||||
if (selection.hasAttribute('contextedLink')) {
|
if (selection.hasAttribute('contextedLink')) {
|
||||||
const autocompleteNode = [
|
const autocompleteNode = [
|
||||||
selection.focus?.nodeBefore,
|
selection.focus?.nodeBefore,
|
||||||
selection.focus?.textNode,
|
selection.focus?.textNode,
|
||||||
selection.focus?.nodeAfter,
|
selection.focus?.nodeAfter
|
||||||
].find((node) => Boolean(node))
|
].find((node) => Boolean(node))
|
||||||
fireAutocompleteEvent(editor, true, autocompleteNode)
|
fireAutocompleteEvent(editor, true, autocompleteNode)
|
||||||
}
|
}
|
||||||
@@ -149,9 +173,7 @@ function getNodePosition(editor: any, modelPosition: any) {
|
|||||||
const viewPosition = mapper.toViewPosition(modelPosition)
|
const viewPosition = mapper.toViewPosition(modelPosition)
|
||||||
const viewRange = editor.editing.view.createRange(viewPosition)
|
const viewRange = editor.editing.view.createRange(viewPosition)
|
||||||
const domConverter = editor.editing.view.domConverter
|
const domConverter = editor.editing.view.domConverter
|
||||||
const rangeRects = Rect.getDomRangeRects(
|
const rangeRects = Rect.getDomRangeRects(domConverter.viewRangeToDom(viewRange)).pop()
|
||||||
domConverter.viewRangeToDom(viewRange)
|
|
||||||
).pop()
|
|
||||||
return rangeRects
|
return rangeRects
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e)
|
console.log(e)
|
||||||
@@ -194,18 +216,15 @@ function fireAutocompleteEvent(editor: any, show: boolean, autocompleteNode?: an
|
|||||||
event = {
|
event = {
|
||||||
position: getNodePosition(
|
position: getNodePosition(
|
||||||
editor,
|
editor,
|
||||||
editor.model.createPositionFromPath(
|
editor.model.createPositionFromPath(autocompleteNode.root, autocompleteNode.getPath())
|
||||||
autocompleteNode.root,
|
|
||||||
autocompleteNode.getPath()
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
autocompleteText: autocompleteNode.data,
|
autocompleteText: autocompleteNode.data,
|
||||||
domElement,
|
domElement,
|
||||||
show: true,
|
show: true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
event = {
|
event = {
|
||||||
show: false,
|
show: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
editor.model.document.fire('contextedLinkAutocomplete', event)
|
editor.model.document.fire('contextedLinkAutocomplete', event)
|
||||||
|
|||||||
Reference in New Issue
Block a user