Chunter: Add button for link formatting (#2063)

Signed-off-by: Denis Bunakalya <denis.bunakalya@xored.com>
This commit is contained in:
Denis Bunakalya 2022-06-14 17:48:40 +03:00 committed by GitHub
parent 89b1a570a5
commit 5d33062176
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 115 additions and 3 deletions

View File

@ -63,7 +63,9 @@
{:else if node.nodeName === 'DIV'}
<div><svelte:self nodes={node.childNodes} /></div>
{:else if node.nodeName === 'A'}
<a href={node.getAttribute('href')}><svelte:self nodes={node.childNodes} /></a>
<a href={node.getAttribute('href')} target={node.getAttribute('target')}
><svelte:self nodes={node.childNodes} /></a
>
{:else if node.nodeName === 'LABEL'}
<svelte:self nodes={node.childNodes} />
{:else if node.nodeName === 'INPUT'}

View File

@ -7,6 +7,8 @@
"Bold": "Bold",
"Italic": "Italic",
"Strikethrough": "Strikethrough",
"Link": "Link",
"Save": "Save",
"OrderedList": "Ordered list",
"BulletedList": "Bulleted list",
"Blockquote": "Blockquote",

View File

@ -7,6 +7,8 @@
"Bold": "Жирный",
"Italic": "Курсив",
"Strikethrough": "Зачеркнутый",
"Link": "Ссылка",
"Save": "Сохранить",
"OrderedList": "Упорядоченный список",
"BulletedList": "Маркированный список",
"Blockquote": "Цитата",

View File

@ -0,0 +1,44 @@
<!--
// Copyright © 2022 Anticrm Platform Contributors.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
-->
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import { Card } from '@anticrm/presentation'
import { EditBox } from '@anticrm/ui'
import type { IntlString } from '@anticrm/platform'
import textEditorPlugin from '../plugin'
export let link = ''
const dispatch = createEventDispatcher()
const linkPlaceholder = 'http://my.link.net' as IntlString
function save () {
dispatch('update', link)
}
</script>
<Card
label={textEditorPlugin.string.Link}
okLabel={textEditorPlugin.string.Save}
okAction={save}
canSave
on:close={() => {
dispatch('close')
}}
>
<EditBox placeholder={linkPlaceholder} bind:value={link} maxWidth={'16rem'} focus />
</Card>

View File

@ -15,7 +15,7 @@
<script lang="ts">
import { Asset, getResource, IntlString } from '@anticrm/platform'
import presentation, { getClient, ObjectSearchCategory } from '@anticrm/presentation'
import { AnySvelteComponent, Icon, Button, Tooltip } from '@anticrm/ui'
import { AnySvelteComponent, Icon, Button, Tooltip, showPopup } from '@anticrm/ui'
import { AnyExtension } from '@tiptap/core'
import { createEventDispatcher } from 'svelte'
import { Completion } from '../Completion'
@ -25,6 +25,7 @@
import Bold from './icons/Bold.svelte'
import Italic from './icons/Italic.svelte'
import Strikethrough from './icons/Strikethrough.svelte'
import Link from './icons/Link.svelte'
import ListNumber from './icons/ListNumber.svelte'
import ListBullet from './icons/ListBullet.svelte'
import Quote from './icons/Quote.svelte'
@ -37,6 +38,7 @@
import MentionList from './MentionList.svelte'
import { SvelteRenderer } from './SvelteRenderer'
import TextEditor from './TextEditor.svelte'
import LinkPopup from './LinkPopup.svelte'
const dispatch = createEventDispatcher()
export let content: string = ''
@ -47,6 +49,7 @@
let textEditor: TextEditor
let isFormatting = false
let activeModes = new Set<FormatMode>()
let isSelectionEmpty = true
export let categories: ObjectSearchCategory[] = []
@ -172,6 +175,7 @@
function updateFormattingState () {
activeModes = new Set(FORMAT_MODES.filter(textEditor.checkIsActive))
isSelectionEmpty = textEditor.checkIsSelectionEmpty()
}
function getToggler (toggle: () => void) {
@ -181,6 +185,18 @@
updateFormattingState()
}
}
async function formatLink (): Promise<void> {
const link = textEditor.getLink()
showPopup(LinkPopup, { link }, undefined, undefined, (newLink) => {
if (newLink === '') {
textEditor.unsetLink()
} else {
textEditor.setLink(newLink)
}
})
}
</script>
<div class="ref-container">
@ -213,6 +229,16 @@
on:click={getToggler(textEditor.toggleStrike)}
/>
</Tooltip>
<Tooltip label={textEditorPlugin.string.Link}>
<Button
icon={Link}
kind={'transparent'}
size={'small'}
selected={activeModes.has('link')}
disabled={isSelectionEmpty && !activeModes.has('link')}
on:click={formatLink}
/>
</Tooltip>
<div class="buttons-divider" />
<Tooltip label={textEditorPlugin.string.OrderedList}>
<Button

View File

@ -68,6 +68,18 @@
export function toggleStrike () {
editor.commands.toggleStrike()
}
export function getLink () {
return editor.getAttributes('link').href
}
export function unsetLink () {
editor.chain().focus().extendMarkRange('link').unsetLink().run()
}
export function setLink (link: string) {
editor.chain().focus().extendMarkRange('link').setLink({ href: link }).run()
}
export function checkIsSelectionEmpty () {
return editor.view.state.selection.empty
}
export function toggleOrderedList () {
editor.commands.toggleOrderedList()
}
@ -111,6 +123,12 @@
Enter: () => {
submit()
return true
},
Space: () => {
if (editor.isActive('link')) {
this.editor.commands.toggleMark('link')
}
return false
}
}
}
@ -124,7 +142,7 @@
extensions: [
StarterKit,
Highlight,
Link,
Link.configure({ openOnClick: false }),
...(supportSubmit ? [Handle] : []), // order important
// Typography, // we need to disable 1/2 -> ½ rule (https://github.com/hcengineering/anticrm/issues/345)
Placeholder.configure({ placeholder: placeHolderStr }),

View File

@ -0,0 +1,15 @@
<script lang="ts">
export let size: 'small' | 'medium' | 'large'
const fill: string = 'currentColor'
</script>
<svg class="svg-{size}" {fill} viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path
d="M4.1,8c-1-1-1-2.7,0.1-3.8C5.3,3.1,7,3.1,8,4.1l4.6,4.6c0,0,0,0,0,0c1,1,1,2.7-0.1,3.8c-0.3,0.3-0.3,0.8,0,1.1 s0.8,0.3,1.1,0c1.6-1.6,1.7-4.3,0.1-5.9l0,0l0,0L9.1,3.1C7.4,1.4,4.8,1.5,3.1,3.2C1.5,4.8,1.4,7.5,3.1,9.1l4,4 c0.3,0.3,0.8,0.3,1.1,0s0.3-0.8,0-1.1L4.1,8z"
/>
<path
d="M20.9,14.9l-4-4c-0.3-0.3-0.8-0.3-1.1,0c-0.3,0.3-0.3,0.8,0,1.1l4,4c1,1,1,2.7-0.1,3.8 c-1.1,1.1-2.8,1.1-3.8,0.1l-4.6-4.6c0,0,0,0,0,0c0,0,0,0,0,0c-1-1-1-2.7,0.1-3.8c0.3-0.3,0.3-0.8,0-1.1c-0.3-0.3-0.8-0.3-1.1,0 c-1.6,1.6-1.7,4.3-0.1,5.9c0,0,0,0,0,0c0,0,0,0,0,0l4.6,4.6c1.6,1.6,4.3,1.6,5.9-0.1C22.5,19.2,22.6,16.6,20.9,14.9z"
/>
</svg>

View File

@ -39,6 +39,8 @@ export default plugin(textEditorId, {
Bold: '' as IntlString,
Italic: '' as IntlString,
Strikethrough: '' as IntlString,
Link: '' as IntlString,
Save: '' as IntlString,
OrderedList: '' as IntlString,
BulletedList: '' as IntlString,
Blockquote: '' as IntlString,

View File

@ -29,6 +29,7 @@ export const FORMAT_MODES = [
'bold',
'italic',
'strike',
'link',
'orderedList',
'bulletList',
'blockquote',