Add firefox compability for autocomplete
This commit is contained in:
@@ -38,7 +38,7 @@
|
|||||||
hideAutoComplete()
|
hideAutoComplete()
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{#if !highlight || !CSS.highlights || isFirefox}
|
{#if !highlight}
|
||||||
<textarea
|
<textarea
|
||||||
class="w-full h-full bg-transparent focus-within:outline-none resize-none absolute top-0 left-0 z-10 overflow-y-auto"
|
class="w-full h-full bg-transparent focus-within:outline-none resize-none absolute top-0 left-0 z-10 overflow-y-auto"
|
||||||
class:px-4={padding}
|
class:px-4={padding}
|
||||||
@@ -67,6 +67,28 @@
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
{:else if isFirefox}
|
||||||
|
<div
|
||||||
|
class="w-full h-full bg-transparent focus-within:outline-none resize-none absolute top-0 left-0 z-10 overflow-y-auto px-4 py-2 break-words whitespace-pre-wrap"
|
||||||
|
contenteditable="true"
|
||||||
|
bind:innerText={value}
|
||||||
|
on:keydown={(e) => {
|
||||||
|
handleKeyDown(e)
|
||||||
|
onInput()
|
||||||
|
}}
|
||||||
|
on:input={(e) => {
|
||||||
|
autoComplete()
|
||||||
|
}}
|
||||||
|
on:paste={(e) => {
|
||||||
|
e.preventDefault()
|
||||||
|
const text = e.clipboardData.getData('text/plain')
|
||||||
|
if(text){
|
||||||
|
insertContent(text, 'paste')
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
bind:this={inputDom}
|
||||||
|
translate="no"
|
||||||
|
>{value ?? ''}</div>
|
||||||
{:else}
|
{:else}
|
||||||
<div
|
<div
|
||||||
class="w-full h-full bg-transparent focus-within:outline-none resize-none absolute top-0 left-0 z-10 overflow-y-auto px-4 py-2 break-words whitespace-pre-wrap"
|
class="w-full h-full bg-transparent focus-within:outline-none resize-none absolute top-0 left-0 z-10 overflow-y-auto px-4 py-2 break-words whitespace-pre-wrap"
|
||||||
@@ -79,13 +101,14 @@
|
|||||||
on:input={(e) => {
|
on:input={(e) => {
|
||||||
autoComplete()
|
autoComplete()
|
||||||
}}
|
}}
|
||||||
|
bind:this={inputDom}
|
||||||
translate="no"
|
translate="no"
|
||||||
>{value ?? ''}</div>
|
>{value ?? ''}</div>
|
||||||
{/if}
|
{/if}
|
||||||
<div class="hidden absolute z-100 bg-bgcolor border border-darkborderc p-2 flex-col" bind:this={autoCompleteDom}>
|
<div class="hidden absolute z-100 bg-bgcolor border border-darkborderc p-2 flex-col" bind:this={autoCompleteDom}>
|
||||||
{#each autocompleteContents as content, i}
|
{#each autocompleteContents as content, i}
|
||||||
<button class="w-full text-left py-1 px-2 bg-bgcolor" class:text-blue-500={selectingAutoComplete === i} on:click={() => {
|
<button class="w-full text-left py-1 px-2 bg-bgcolor" class:text-blue-500={selectingAutoComplete === i} on:click={() => {
|
||||||
insertAutoComplete(content)
|
insertContent(content)
|
||||||
}}>{content}</button>
|
}}>{content}</button>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
@@ -116,6 +139,7 @@
|
|||||||
let optiValue = value
|
let optiValue = value
|
||||||
let autoCompleteDom: HTMLDivElement
|
let autoCompleteDom: HTMLDivElement
|
||||||
let autocompleteContents:string[] = []
|
let autocompleteContents:string[] = []
|
||||||
|
let inputDom: HTMLDivElement
|
||||||
|
|
||||||
const autoComplete = () => {
|
const autoComplete = () => {
|
||||||
if(isMobile){
|
if(isMobile){
|
||||||
@@ -160,27 +184,38 @@
|
|||||||
autoCompleteDom.style.display = 'flex'
|
autoCompleteDom.style.display = 'flex'
|
||||||
}
|
}
|
||||||
|
|
||||||
const insertAutoComplete = (insertContent:string) => {
|
const insertContent = (insertContent:string, type:'autoComplete'|'paste' = 'autoComplete') => {
|
||||||
const sel = window.getSelection()
|
const sel = window.getSelection()
|
||||||
if(sel){
|
if(sel){
|
||||||
const range = sel.getRangeAt(0)
|
const range = sel.getRangeAt(0)
|
||||||
let content = (range.startContainer).textContent
|
let content = (range.startContainer).textContent
|
||||||
let contentStart = content.substring(0, range.startOffset)
|
let contentStart = content.substring(0, range.startOffset)
|
||||||
let contentEnd = content.substring(range.startOffset)
|
let contentEnd = content.substring(range.startOffset)
|
||||||
contentStart = contentStart.substring(0, contentStart.lastIndexOf('{{'))
|
if(type === 'autoComplete'){
|
||||||
|
contentStart = contentStart.substring(0, contentStart.lastIndexOf('{{'))
|
||||||
if(insertContent.endsWith(':')){
|
if(insertContent.endsWith(':')){
|
||||||
insertContent = `{{${insertContent}:`
|
insertContent = `{{${insertContent}:`
|
||||||
}
|
}
|
||||||
else{
|
else if(insertContent.startsWith('#')){
|
||||||
insertContent = `{{${insertContent}}}`
|
insertContent = `{{${insertContent} `
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
insertContent = `{{${insertContent}}}`
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const cons = contentStart + insertContent + contentEnd
|
const cons = contentStart + insertContent + contentEnd
|
||||||
range.startContainer.textContent = cons
|
range.startContainer.textContent = cons
|
||||||
|
|
||||||
sel.collapse(range.startContainer, contentStart.length + insertContent.length)
|
|
||||||
hideAutoComplete()
|
hideAutoComplete()
|
||||||
|
|
||||||
|
try {
|
||||||
|
sel.collapse(range.startContainer, contentStart.length + insertContent.length)
|
||||||
|
} catch (error) {
|
||||||
|
inputDom.dispatchEvent(new Event('input'))
|
||||||
|
inputDom.dispatchEvent(new Event('change'))
|
||||||
|
}
|
||||||
|
//invoke onInput
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,7 +253,7 @@
|
|||||||
case 'Tab':
|
case 'Tab':
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
if(selectingAutoComplete !== -1){
|
if(selectingAutoComplete !== -1){
|
||||||
insertAutoComplete(autocompleteContents[selectingAutoComplete])
|
insertContent(autocompleteContents[selectingAutoComplete])
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 'Escape':
|
case 'Escape':
|
||||||
|
|||||||
Reference in New Issue
Block a user