mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-05-29 06:15:29 -04:00
Adjust editor config (#976)
* Adjust editor config Signed-off-by: Tilman Vatteroth <tilman.vatteroth@tu-dortmund.de> Co-authored-by: Erik Michelson <github@erik.michelson.eu>
This commit is contained in:
parent
0180c75e55
commit
e12dc523f8
301 changed files with 4393 additions and 3741 deletions
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import { EditorConfiguration } from 'codemirror'
|
||||
import equal from "fast-deep-equal"
|
||||
import equal from 'fast-deep-equal'
|
||||
import React, { ChangeEvent, useCallback } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useSelector } from 'react-redux'
|
||||
|
@ -30,15 +30,16 @@ export const EditorPreferenceBooleanProperty: React.FC<EditorPreferenceBooleanPr
|
|||
} as EditorConfiguration)
|
||||
}, [property])
|
||||
|
||||
const i18nPrefix = `editor.modal.preferences.${property}`
|
||||
const i18nPrefix = `editor.modal.preferences.${ property }`
|
||||
|
||||
return (
|
||||
<EditorPreferenceInput onChange={selectItem} property={property} type={EditorPreferenceInputType.SELECT} value={preference}>
|
||||
<option value={'true'}>
|
||||
{t(`${i18nPrefix}.on`)}
|
||||
<EditorPreferenceInput onChange={ selectItem } property={ property } type={ EditorPreferenceInputType.SELECT }
|
||||
value={ preference }>
|
||||
<option value={ 'true' }>
|
||||
{ t(`${ i18nPrefix }.on`) }
|
||||
</option>
|
||||
<option value={'false'}>
|
||||
{t(`${i18nPrefix}.off`)}
|
||||
<option value={ 'false' }>
|
||||
{ t(`${ i18nPrefix }.off`) }
|
||||
</option>
|
||||
</EditorPreferenceInput>
|
||||
)
|
||||
|
|
|
@ -23,17 +23,18 @@ export interface EditorPreferenceInputProps {
|
|||
export const EditorPreferenceInput: React.FC<EditorPreferenceInputProps> = ({ property, type, onChange, value, children }) => {
|
||||
useTranslation()
|
||||
return (
|
||||
<Form.Group controlId={`editor-pref-${property}`}>
|
||||
<Form.Group controlId={ `editor-pref-${ property }` }>
|
||||
<Form.Label>
|
||||
<Trans i18nKey={`editor.modal.preferences.${property}${type===EditorPreferenceInputType.NUMBER ? '' : '.label'}`}/>
|
||||
<Trans
|
||||
i18nKey={ `editor.modal.preferences.${ property }${ type === EditorPreferenceInputType.NUMBER ? '' : '.label' }` }/>
|
||||
</Form.Label>
|
||||
<Form.Control
|
||||
as={type === EditorPreferenceInputType.NUMBER ? 'input' : 'select'}
|
||||
as={ type === EditorPreferenceInputType.NUMBER ? 'input' : 'select' }
|
||||
size='sm'
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
type={type === EditorPreferenceInputType.NUMBER ? 'number' : ''}>
|
||||
{children}
|
||||
value={ value }
|
||||
onChange={ onChange }
|
||||
type={ type === EditorPreferenceInputType.NUMBER ? 'number' : '' }>
|
||||
{ children }
|
||||
</Form.Control>
|
||||
</Form.Group>
|
||||
)
|
||||
|
|
|
@ -11,7 +11,8 @@ import { setEditorLigatures } from '../../../../../redux/editor/methods'
|
|||
import { EditorPreferenceInput, EditorPreferenceInputType } from './editor-preference-input'
|
||||
|
||||
export const EditorPreferenceLigaturesSelect: React.FC = () => {
|
||||
const ligaturesEnabled = useSelector((state: ApplicationState) => Boolean(state.editorConfig.ligatures).toString())
|
||||
const ligaturesEnabled = useSelector((state: ApplicationState) => Boolean(state.editorConfig.ligatures)
|
||||
.toString())
|
||||
const saveLigatures = useCallback((event: ChangeEvent<HTMLSelectElement>) => {
|
||||
const ligaturesActivated: boolean = event.target.value === 'true'
|
||||
setEditorLigatures(ligaturesActivated)
|
||||
|
@ -19,10 +20,10 @@ export const EditorPreferenceLigaturesSelect: React.FC = () => {
|
|||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<EditorPreferenceInput onChange={saveLigatures} value={ligaturesEnabled} property={"ligatures"}
|
||||
type={EditorPreferenceInputType.BOOLEAN}>
|
||||
<option value='true'>{t(`common.yes`)}</option>
|
||||
<option value='false'>{t(`common.no`)}</option>
|
||||
<EditorPreferenceInput onChange={ saveLigatures } value={ ligaturesEnabled } property={ 'ligatures' }
|
||||
type={ EditorPreferenceInputType.BOOLEAN }>
|
||||
<option value='true'>{ t(`common.yes`) }</option>
|
||||
<option value='false'>{ t(`common.no`) }</option>
|
||||
</EditorPreferenceInput>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import { EditorConfiguration } from 'codemirror'
|
||||
import equal from "fast-deep-equal"
|
||||
import equal from 'fast-deep-equal'
|
||||
import React, { ChangeEvent, useCallback } from 'react'
|
||||
import { useSelector } from 'react-redux'
|
||||
import { ApplicationState } from '../../../../../redux'
|
||||
|
@ -29,6 +29,7 @@ export const EditorPreferenceNumberProperty: React.FC<EditorPreferenceNumberProp
|
|||
}, [property])
|
||||
|
||||
return (
|
||||
<EditorPreferenceInput onChange={selectItem} property={property} type={EditorPreferenceInputType.NUMBER} value={preference}/>
|
||||
<EditorPreferenceInput onChange={ selectItem } property={ property } type={ EditorPreferenceInputType.NUMBER }
|
||||
value={ preference }/>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import { EditorConfiguration } from 'codemirror'
|
||||
import equal from "fast-deep-equal"
|
||||
import equal from 'fast-deep-equal'
|
||||
import React, { ChangeEvent, useCallback } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useSelector } from 'react-redux'
|
||||
|
@ -32,14 +32,15 @@ export const EditorPreferenceSelectProperty: React.FC<EditorPreferenceSelectProp
|
|||
} as EditorConfiguration)
|
||||
}, [property])
|
||||
|
||||
const i18nPrefix = `editor.modal.preferences.${property}`
|
||||
const i18nPrefix = `editor.modal.preferences.${ property }`
|
||||
|
||||
return (
|
||||
<EditorPreferenceInput onChange={selectItem} property={property} type={EditorPreferenceInputType.SELECT} value={preference}>
|
||||
{selections.map(selection =>
|
||||
<option key={selection} value={selection}>
|
||||
{t(`${i18nPrefix}.${selection}`) }
|
||||
</option>)}
|
||||
<EditorPreferenceInput onChange={ selectItem } property={ property } type={ EditorPreferenceInputType.SELECT }
|
||||
value={ preference }>
|
||||
{ selections.map(selection =>
|
||||
<option key={ selection } value={ selection }>
|
||||
{ t(`${ i18nPrefix }.${ selection }`) }
|
||||
</option>) }
|
||||
</EditorPreferenceInput>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import equal from "fast-deep-equal"
|
||||
import equal from 'fast-deep-equal'
|
||||
import React, { Fragment, useState } from 'react'
|
||||
import { Button, Form, ListGroup } from 'react-bootstrap'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
@ -17,8 +17,8 @@ import { EditorPreferenceBooleanProperty } from './editor-preference-boolean-pro
|
|||
import { EditorPreferenceInput, EditorPreferenceInputType } from './editor-preference-input'
|
||||
import { EditorPreferenceLigaturesSelect } from './editor-preference-ligatures-select'
|
||||
import { EditorPreferenceNumberProperty } from './editor-preference-number-property'
|
||||
import { EditorPreferenceProperty } from "./editor-preference-property"
|
||||
import { EditorPreferenceSelectProperty } from "./editor-preference-select-property"
|
||||
import { EditorPreferenceProperty } from './editor-preference-property'
|
||||
import { EditorPreferenceSelectProperty } from './editor-preference-select-property'
|
||||
|
||||
export const EditorPreferences: React.FC = () => {
|
||||
const { t } = useTranslation()
|
||||
|
@ -27,36 +27,40 @@ export const EditorPreferences: React.FC = () => {
|
|||
|
||||
return (
|
||||
<Fragment>
|
||||
<Button variant='light' onClick={() => setShowModal(true)} title={t('editor.editorToolbar.preferences')}>
|
||||
<Button variant='light' onClick={ () => setShowModal(true) } title={ t('editor.editorToolbar.preferences') }>
|
||||
<ForkAwesomeIcon icon="wrench"/>
|
||||
</Button>
|
||||
<CommonModal
|
||||
show={showModal}
|
||||
onHide={() => setShowModal(false)}
|
||||
titleI18nKey={'editor.modal.preferences.title'}
|
||||
closeButton={true}
|
||||
icon={'wrench'}>
|
||||
show={ showModal }
|
||||
onHide={ () => setShowModal(false) }
|
||||
titleI18nKey={ 'editor.modal.preferences.title' }
|
||||
closeButton={ true }
|
||||
icon={ 'wrench' }>
|
||||
<Form>
|
||||
<ListGroup>
|
||||
<ListGroup.Item>
|
||||
<EditorPreferenceSelectProperty property={EditorPreferenceProperty.THEME} selections={['one-dark', 'neat']}/>
|
||||
<EditorPreferenceSelectProperty property={ EditorPreferenceProperty.THEME }
|
||||
selections={ ['one-dark', 'neat'] }/>
|
||||
</ListGroup.Item>
|
||||
<ListGroup.Item>
|
||||
<EditorPreferenceSelectProperty property={EditorPreferenceProperty.KEYMAP} selections={['sublime', 'emacs', 'vim']}/>
|
||||
<EditorPreferenceSelectProperty property={ EditorPreferenceProperty.KEYMAP }
|
||||
selections={ ['sublime', 'emacs', 'vim'] }/>
|
||||
</ListGroup.Item>
|
||||
<ListGroup.Item>
|
||||
<EditorPreferenceBooleanProperty property={EditorPreferenceProperty.INDENT_WITH_TABS}/>
|
||||
<EditorPreferenceBooleanProperty property={ EditorPreferenceProperty.INDENT_WITH_TABS }/>
|
||||
</ListGroup.Item>
|
||||
<ShowIf condition={!indentWithTabs}>
|
||||
<ShowIf condition={ !indentWithTabs }>
|
||||
<ListGroup.Item>
|
||||
<EditorPreferenceNumberProperty property={EditorPreferenceProperty.INDENT_UNIT}/>
|
||||
<EditorPreferenceNumberProperty property={ EditorPreferenceProperty.INDENT_UNIT }/>
|
||||
</ListGroup.Item>
|
||||
</ShowIf>
|
||||
<ListGroup.Item>
|
||||
<EditorPreferenceLigaturesSelect/>
|
||||
</ListGroup.Item>
|
||||
<ListGroup.Item>
|
||||
<EditorPreferenceInput onChange={() => alert('This feature is not yet implemented.')} property={EditorPreferenceProperty.SPELL_CHECK} type={EditorPreferenceInputType.SELECT}>
|
||||
<EditorPreferenceInput onChange={ () => alert('This feature is not yet implemented.') }
|
||||
property={ EditorPreferenceProperty.SPELL_CHECK }
|
||||
type={ EditorPreferenceInputType.SELECT }>
|
||||
<option value='off'>Off</option>
|
||||
<option value='en'>English</option>
|
||||
</EditorPreferenceInput>
|
||||
|
|
|
@ -23,13 +23,14 @@ export const EmojiPickerButton: React.FC<EmojiPickerButtonProps> = ({ editor })
|
|||
return (
|
||||
<Fragment>
|
||||
<EmojiPicker
|
||||
show={showEmojiPicker}
|
||||
onEmojiSelected={(emoji) => {
|
||||
show={ showEmojiPicker }
|
||||
onEmojiSelected={ (emoji) => {
|
||||
setShowEmojiPicker(false)
|
||||
addEmoji(emoji, editor)
|
||||
}}
|
||||
onDismiss={() => setShowEmojiPicker(false)}/>
|
||||
<Button data-cy={'show-emoji-picker'} variant='light' onClick={() => setShowEmojiPicker(old => !old)} title={t('editor.editorToolbar.emoji')}>
|
||||
} }
|
||||
onDismiss={ () => setShowEmojiPicker(false) }/>
|
||||
<Button data-cy={ 'show-emoji-picker' } variant='light' onClick={ () => setShowEmojiPicker(old => !old) }
|
||||
title={ t('editor.editorToolbar.emoji') }>
|
||||
<ForkAwesomeIcon icon="smile-o"/>
|
||||
</Button>
|
||||
</Fragment>
|
||||
|
|
|
@ -19,12 +19,13 @@ export interface EmojiPickerProps {
|
|||
onDismiss: () => void
|
||||
}
|
||||
|
||||
export const customEmojis: CustomEmoji[] = Object.keys(ForkAwesomeIcons).map((name) => ({
|
||||
name: `fa-${name}`,
|
||||
shortcodes: [`fa-${name.toLowerCase()}`],
|
||||
url: forkawesomeIcon,
|
||||
category: 'ForkAwesome'
|
||||
}))
|
||||
export const customEmojis: CustomEmoji[] = Object.keys(ForkAwesomeIcons)
|
||||
.map((name) => ({
|
||||
name: `fa-${ name }`,
|
||||
shortcodes: [`fa-${ name.toLowerCase() }`],
|
||||
url: forkawesomeIcon,
|
||||
category: 'ForkAwesome'
|
||||
}))
|
||||
|
||||
export const EMOJI_DATA_PATH = '/static/js/emoji-data.json'
|
||||
|
||||
|
@ -92,6 +93,7 @@ export const EmojiPicker: React.FC<EmojiPickerProps> = ({ show, onEmojiSelected,
|
|||
}, [darkModeEnabled])
|
||||
|
||||
return (
|
||||
<div className={`position-absolute emoji-picker-container ${!show ? 'd-none' : ''}`} ref={pickerContainerRef}/>
|
||||
<div className={ `position-absolute emoji-picker-container ${ !show ? 'd-none' : '' }` }
|
||||
ref={ pickerContainerRef }/>
|
||||
)
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -38,42 +38,42 @@ export const CustomTableSizeModal: React.FC<CustomTableSizeModalProps> = ({ show
|
|||
|
||||
return (
|
||||
<CommonModal
|
||||
show={showModal}
|
||||
onHide={() => onDismiss()}
|
||||
titleI18nKey={'editor.editorToolbar.table.customSize'}
|
||||
closeButton={true}
|
||||
icon={'table'}>
|
||||
<div className={'col-lg-10 d-flex flex-row p-3 align-items-center'}>
|
||||
show={ showModal }
|
||||
onHide={ () => onDismiss() }
|
||||
titleI18nKey={ 'editor.editorToolbar.table.customSize' }
|
||||
closeButton={ true }
|
||||
icon={ 'table' }>
|
||||
<div className={ 'col-lg-10 d-flex flex-row p-3 align-items-center' }>
|
||||
<Form.Control
|
||||
type={'number'}
|
||||
min={1}
|
||||
placeholder={t('editor.editorToolbar.table.cols')}
|
||||
isInvalid={tableSize.columns <= 0}
|
||||
onChange={(event) => {
|
||||
type={ 'number' }
|
||||
min={ 1 }
|
||||
placeholder={ t('editor.editorToolbar.table.cols') }
|
||||
isInvalid={ tableSize.columns <= 0 }
|
||||
onChange={ (event) => {
|
||||
const value = Number.parseInt(event.currentTarget.value)
|
||||
setTableSize(old => ({
|
||||
rows: old.rows,
|
||||
columns: isNaN(value) ? 0 : value
|
||||
}))
|
||||
}}
|
||||
} }
|
||||
/>
|
||||
<ForkAwesomeIcon icon='times' className='mx-2' fixedWidth={true}/>
|
||||
<ForkAwesomeIcon icon='times' className='mx-2' fixedWidth={ true }/>
|
||||
<Form.Control
|
||||
type={'number'}
|
||||
min={1}
|
||||
placeholder={t('editor.editorToolbar.table.rows')}
|
||||
isInvalid={tableSize.rows <= 0}
|
||||
onChange={(event) => {
|
||||
type={ 'number' }
|
||||
min={ 1 }
|
||||
placeholder={ t('editor.editorToolbar.table.rows') }
|
||||
isInvalid={ tableSize.rows <= 0 }
|
||||
onChange={ (event) => {
|
||||
const value = Number.parseInt(event.currentTarget.value)
|
||||
setTableSize(old => ({
|
||||
rows: isNaN(value) ? 0 : value,
|
||||
columns: old.columns
|
||||
}))
|
||||
}}/>
|
||||
} }/>
|
||||
</div>
|
||||
<ModalFooter>
|
||||
<Button onClick={onClick} disabled={tableSize.rows <= 0 || tableSize.columns <= 0}>
|
||||
{t('editor.editorToolbar.table.create')}
|
||||
<Button onClick={ onClick } disabled={ tableSize.rows <= 0 || tableSize.columns <= 0 }>
|
||||
{ t('editor.editorToolbar.table.create') }
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</CommonModal>
|
||||
|
|
|
@ -23,14 +23,15 @@ export const TablePickerButton: React.FC<TablePickerButtonProps> = ({ editor })
|
|||
return (
|
||||
<Fragment>
|
||||
<TablePicker
|
||||
show={showTablePicker}
|
||||
onDismiss={() => setShowTablePicker(false)}
|
||||
onTablePicked={(rows, cols) => {
|
||||
show={ showTablePicker }
|
||||
onDismiss={ () => setShowTablePicker(false) }
|
||||
onTablePicked={ (rows, cols) => {
|
||||
setShowTablePicker(false)
|
||||
addTable(editor, rows, cols)
|
||||
}}
|
||||
} }
|
||||
/>
|
||||
<Button data-cy={'show-table-overlay'} variant='light' onClick={() => setShowTablePicker(old => !old)} title={t('editor.editorToolbar.table.title')}>
|
||||
<Button data-cy={ 'show-table-overlay' } variant='light' onClick={ () => setShowTablePicker(old => !old) }
|
||||
title={ t('editor.editorToolbar.table.title') }>
|
||||
<ForkAwesomeIcon icon="table"/>
|
||||
</Button>
|
||||
</Fragment>
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
*/
|
||||
|
||||
|
||||
|
||||
.table-picker-container {
|
||||
z-index: 1111;
|
||||
|
||||
|
|
|
@ -45,40 +45,43 @@ export const TablePicker: React.FC<TablePickerProps> = ({ show, onDismiss, onTab
|
|||
}, [onTablePicked, tableSize])
|
||||
|
||||
return (
|
||||
<div className={`position-absolute table-picker-container p-2 ${!show || showDialog ? 'd-none' : ''} bg-light`} ref={containerRef} role="grid">
|
||||
<p className={'lead'}>
|
||||
<div className={ `position-absolute table-picker-container p-2 ${ !show || showDialog ? 'd-none' : '' } bg-light` }
|
||||
ref={ containerRef } role="grid">
|
||||
<p className={ 'lead' }>
|
||||
{ tableSize
|
||||
? t('editor.editorToolbar.table.size', { cols: tableSize?.columns, rows: tableSize.rows })
|
||||
: t('editor.editorToolbar.table.title')
|
||||
}
|
||||
</p>
|
||||
<div className={'table-container'}>
|
||||
{createNumberRangeArray(8).map((row: number) => (
|
||||
createNumberRangeArray(10).map((col: number) => (
|
||||
<div
|
||||
key={`${row}_${col}`}
|
||||
className={`table-cell ${tableSize && row < tableSize.rows && col < tableSize.columns ? 'bg-primary' : ''}`}
|
||||
onMouseEnter={() => {
|
||||
setTableSize({
|
||||
rows: row + 1,
|
||||
columns: col + 1
|
||||
})
|
||||
}}
|
||||
title={t('editor.editorToolbar.table.size', { cols: col + 1, rows: row + 1 })}
|
||||
onClick={onClick}
|
||||
/>
|
||||
)
|
||||
)
|
||||
))}
|
||||
<div className={ 'table-container' }>
|
||||
{ createNumberRangeArray(8)
|
||||
.map((row: number) => (
|
||||
createNumberRangeArray(10)
|
||||
.map((col: number) => (
|
||||
<div
|
||||
key={ `${ row }_${ col }` }
|
||||
className={ `table-cell ${ tableSize && row < tableSize.rows && col < tableSize.columns ? 'bg-primary' : '' }` }
|
||||
onMouseEnter={ () => {
|
||||
setTableSize({
|
||||
rows: row + 1,
|
||||
columns: col + 1
|
||||
})
|
||||
} }
|
||||
title={ t('editor.editorToolbar.table.size', { cols: col + 1, rows: row + 1 }) }
|
||||
onClick={ onClick }
|
||||
/>
|
||||
)
|
||||
)
|
||||
)) }
|
||||
</div>
|
||||
<div className="d-flex justify-content-center mt-2">
|
||||
<Button data-cy={'show-custom-table-modal'} className={'text-center'} onClick={() => setShowDialog(true)}>
|
||||
<ForkAwesomeIcon icon="table"/> {t('editor.editorToolbar.table.customSize')}
|
||||
<Button data-cy={ 'show-custom-table-modal' } className={ 'text-center' } onClick={ () => setShowDialog(true) }>
|
||||
<ForkAwesomeIcon icon="table"/> { t('editor.editorToolbar.table.customSize') }
|
||||
</Button>
|
||||
<CustomTableSizeModal
|
||||
showModal={showDialog}
|
||||
onDismiss={() => setShowDialog(false)}
|
||||
onTablePicked={onTablePicked}
|
||||
showModal={ showDialog }
|
||||
onDismiss={ () => setShowDialog(false) }
|
||||
onTablePicked={ onTablePicked }
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -47,69 +47,86 @@ export const ToolBar: React.FC<ToolBarProps> = ({ editor }) => {
|
|||
|
||||
return (
|
||||
<ButtonToolbar className='bg-light'>
|
||||
<ButtonGroup className={'mx-1 flex-wrap'}>
|
||||
<Button data-cy={'format-bold'} variant='light' onClick={() => makeSelectionBold(editor)} title={t('editor.editorToolbar.bold')}>
|
||||
<ButtonGroup className={ 'mx-1 flex-wrap' }>
|
||||
<Button data-cy={ 'format-bold' } variant='light' onClick={ () => makeSelectionBold(editor) }
|
||||
title={ t('editor.editorToolbar.bold') }>
|
||||
<ForkAwesomeIcon icon="bold"/>
|
||||
</Button>
|
||||
<Button data-cy={'format-italic'} variant='light' onClick={() => makeSelectionItalic(editor)} title={t('editor.editorToolbar.italic')}>
|
||||
<Button data-cy={ 'format-italic' } variant='light' onClick={ () => makeSelectionItalic(editor) }
|
||||
title={ t('editor.editorToolbar.italic') }>
|
||||
<ForkAwesomeIcon icon="italic"/>
|
||||
</Button>
|
||||
<Button data-cy={'format-underline'} variant='light' onClick={() => underlineSelection(editor)} title={t('editor.editorToolbar.underline')}>
|
||||
<Button data-cy={ 'format-underline' } variant='light' onClick={ () => underlineSelection(editor) }
|
||||
title={ t('editor.editorToolbar.underline') }>
|
||||
<ForkAwesomeIcon icon="underline"/>
|
||||
</Button>
|
||||
<Button data-cy={'format-strikethrough'} variant='light' onClick={() => strikeThroughSelection(editor)} title={t('editor.editorToolbar.strikethrough')}>
|
||||
<Button data-cy={ 'format-strikethrough' } variant='light' onClick={ () => strikeThroughSelection(editor) }
|
||||
title={ t('editor.editorToolbar.strikethrough') }>
|
||||
<ForkAwesomeIcon icon="strikethrough"/>
|
||||
</Button>
|
||||
<Button data-cy={'format-subscript'} variant='light' onClick={() => subscriptSelection(editor)} title={t('editor.editorToolbar.subscript')}>
|
||||
<Button data-cy={ 'format-subscript' } variant='light' onClick={ () => subscriptSelection(editor) }
|
||||
title={ t('editor.editorToolbar.subscript') }>
|
||||
<ForkAwesomeIcon icon="subscript"/>
|
||||
</Button>
|
||||
<Button data-cy={'format-superscript'} variant='light' onClick={() => superscriptSelection(editor)} title={t('editor.editorToolbar.superscript')}>
|
||||
<Button data-cy={ 'format-superscript' } variant='light' onClick={ () => superscriptSelection(editor) }
|
||||
title={ t('editor.editorToolbar.superscript') }>
|
||||
<ForkAwesomeIcon icon="superscript"/>
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
<ButtonGroup className={'mx-1 flex-wrap'}>
|
||||
<Button data-cy={'format-heading'} variant='light' onClick={() => addHeaderLevel(editor)} title={t('editor.editorToolbar.header')}>
|
||||
<ButtonGroup className={ 'mx-1 flex-wrap' }>
|
||||
<Button data-cy={ 'format-heading' } variant='light' onClick={ () => addHeaderLevel(editor) }
|
||||
title={ t('editor.editorToolbar.header') }>
|
||||
<ForkAwesomeIcon icon="header"/>
|
||||
</Button>
|
||||
<Button data-cy={'format-code-block'} variant='light' onClick={() => addCodeFences(editor)} title={t('editor.editorToolbar.code')}>
|
||||
<Button data-cy={ 'format-code-block' } variant='light' onClick={ () => addCodeFences(editor) }
|
||||
title={ t('editor.editorToolbar.code') }>
|
||||
<ForkAwesomeIcon icon="code"/>
|
||||
</Button>
|
||||
<Button data-cy={'format-block-quote'} variant='light' onClick={() => addQuotes(editor)} title={t('editor.editorToolbar.blockquote')}>
|
||||
<Button data-cy={ 'format-block-quote' } variant='light' onClick={ () => addQuotes(editor) }
|
||||
title={ t('editor.editorToolbar.blockquote') }>
|
||||
<ForkAwesomeIcon icon="quote-right"/>
|
||||
</Button>
|
||||
<Button data-cy={'format-unordered-list'} variant='light' onClick={() => addList(editor)} title={t('editor.editorToolbar.unorderedList')}>
|
||||
<Button data-cy={ 'format-unordered-list' } variant='light' onClick={ () => addList(editor) }
|
||||
title={ t('editor.editorToolbar.unorderedList') }>
|
||||
<ForkAwesomeIcon icon="list"/>
|
||||
</Button>
|
||||
<Button data-cy={'format-ordered-list'} variant='light' onClick={() => addOrderedList(editor)} title={t('editor.editorToolbar.orderedList')}>
|
||||
<Button data-cy={ 'format-ordered-list' } variant='light' onClick={ () => addOrderedList(editor) }
|
||||
title={ t('editor.editorToolbar.orderedList') }>
|
||||
<ForkAwesomeIcon icon="list-ol"/>
|
||||
</Button>
|
||||
<Button data-cy={'format-check-list'} variant='light' onClick={() => addTaskList(editor)} title={t('editor.editorToolbar.checkList')}>
|
||||
<Button data-cy={ 'format-check-list' } variant='light' onClick={ () => addTaskList(editor) }
|
||||
title={ t('editor.editorToolbar.checkList') }>
|
||||
<ForkAwesomeIcon icon="check-square"/>
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
<ButtonGroup className={'mx-1 flex-wrap'}>
|
||||
<Button data-cy={'format-link'} variant='light' onClick={() => addLink(editor)} title={t('editor.editorToolbar.link')}>
|
||||
<ButtonGroup className={ 'mx-1 flex-wrap' }>
|
||||
<Button data-cy={ 'format-link' } variant='light' onClick={ () => addLink(editor) }
|
||||
title={ t('editor.editorToolbar.link') }>
|
||||
<ForkAwesomeIcon icon="link"/>
|
||||
</Button>
|
||||
<Button data-cy={'format-image'} variant='light' onClick={() => addImage(editor)} title={t('editor.editorToolbar.image')}>
|
||||
<Button data-cy={ 'format-image' } variant='light' onClick={ () => addImage(editor) }
|
||||
title={ t('editor.editorToolbar.image') }>
|
||||
<ForkAwesomeIcon icon="picture-o"/>
|
||||
</Button>
|
||||
<UploadImageButton editor={editor}/>
|
||||
<UploadImageButton editor={ editor }/>
|
||||
</ButtonGroup>
|
||||
<ButtonGroup className={'mx-1 flex-wrap'}>
|
||||
<TablePickerButton editor={editor}/>
|
||||
<Button data-cy={'format-add-line'} variant='light' onClick={() => addLine(editor)} title={t('editor.editorToolbar.line')}>
|
||||
<ButtonGroup className={ 'mx-1 flex-wrap' }>
|
||||
<TablePickerButton editor={ editor }/>
|
||||
<Button data-cy={ 'format-add-line' } variant='light' onClick={ () => addLine(editor) }
|
||||
title={ t('editor.editorToolbar.line') }>
|
||||
<ForkAwesomeIcon icon="minus"/>
|
||||
</Button>
|
||||
<Button data-cy={'format-collapsable-block'} variant='light' onClick={() => addCollapsableBlock(editor)} title={t('editor.editorToolbar.collapsableBlock')}>
|
||||
<Button data-cy={ 'format-collapsable-block' } variant='light' onClick={ () => addCollapsableBlock(editor) }
|
||||
title={ t('editor.editorToolbar.collapsableBlock') }>
|
||||
<ForkAwesomeIcon icon="caret-square-o-down"/>
|
||||
</Button>
|
||||
<Button data-cy={'format-add-comment'} variant='light' onClick={() => addComment(editor)} title={t('editor.editorToolbar.comment')}>
|
||||
<Button data-cy={ 'format-add-comment' } variant='light' onClick={ () => addComment(editor) }
|
||||
title={ t('editor.editorToolbar.comment') }>
|
||||
<ForkAwesomeIcon icon="comment"/>
|
||||
</Button>
|
||||
<EmojiPickerButton editor={editor}/>
|
||||
<EmojiPickerButton editor={ editor }/>
|
||||
</ButtonGroup>
|
||||
<ButtonGroup className={'mx-1 flex-wrap'}>
|
||||
<ButtonGroup className={ 'mx-1 flex-wrap' }>
|
||||
<EditorPreferences/>
|
||||
</ButtonGroup>
|
||||
</ButtonToolbar>
|
||||
|
|
|
@ -37,10 +37,10 @@ export const UploadImageButton: React.FC<UploadImageButtonProps> = ({ editor })
|
|||
|
||||
return (
|
||||
<Fragment>
|
||||
<Button variant='light' onClick={buttonClick} title={t('editor.editorToolbar.uploadImage')}>
|
||||
<ForkAwesomeIcon icon={'upload'}/>
|
||||
<Button variant='light' onClick={ buttonClick } title={ t('editor.editorToolbar.uploadImage') }>
|
||||
<ForkAwesomeIcon icon={ 'upload' }/>
|
||||
</Button>
|
||||
<UploadInput onLoad={onUploadImage} acceptedFiles={supportedMimeTypesJoined} onClickRef={clickRef}/>
|
||||
<UploadInput onLoad={ onUploadImage } acceptedFiles={ supportedMimeTypesJoined } onClickRef={ clickRef }/>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -12,18 +12,18 @@ export const getEmojiIcon = (emoji: EmojiClickEventDetail): string => {
|
|||
}
|
||||
if (emoji.name) {
|
||||
// noinspection CheckTagEmptyBody
|
||||
return `<i class="fa ${emoji.name}"></i>`
|
||||
return `<i class="fa ${ emoji.name }"></i>`
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
export const getEmojiShortCode = (emoji: EmojiClickEventDetail): string|undefined => {
|
||||
export const getEmojiShortCode = (emoji: EmojiClickEventDetail): string | undefined => {
|
||||
if (!emoji.emoji.shortcodes) {
|
||||
return undefined
|
||||
}
|
||||
let skinToneModifier = ''
|
||||
if ((emoji.emoji as NativeEmoji).skins && emoji.skinTone !== 0) {
|
||||
skinToneModifier = `:skin-tone-${emoji.skinTone as number}:`
|
||||
skinToneModifier = `:skin-tone-${ emoji.skinTone as number }:`
|
||||
}
|
||||
return `:${emoji.emoji.shortcodes[0]}:${skinToneModifier}`
|
||||
return `:${ emoji.emoji.shortcodes[0] }:${ skinToneModifier }`
|
||||
}
|
||||
|
|
|
@ -119,9 +119,12 @@ const mockListSelections = (positions: FromTo, empty: boolean): (() => CodeMirro
|
|||
|
||||
const expectFromToReplacement = (position: FromTo, expectedReplacement: string, done: () => void): ((replacement: string | string[], from: CodeMirror.Position, to?: CodeMirror.Position) => void) => {
|
||||
return (replacement: string | string[], from: CodeMirror.Position, to?: CodeMirror.Position) => {
|
||||
expect(from).toEqual(position.from)
|
||||
expect(to).toEqual(position.to)
|
||||
expect(replacement).toEqual(expectedReplacement)
|
||||
expect(from)
|
||||
.toEqual(position.from)
|
||||
expect(to)
|
||||
.toEqual(position.to)
|
||||
expect(replacement)
|
||||
.toEqual(expectedReplacement)
|
||||
done()
|
||||
}
|
||||
}
|
||||
|
@ -410,18 +413,19 @@ describe('test addHeaderLevel', () => {
|
|||
const { cursor, firstLine, multiline, multilineOffset } = buildRanges()
|
||||
|
||||
const noHeading = testContent.split('\n')[0]
|
||||
const firstHeading = `# ${noHeading}`
|
||||
const secondHeading = `## ${noHeading}`
|
||||
const firstHeading = `# ${ noHeading }`
|
||||
const secondHeading = `## ${ noHeading }`
|
||||
|
||||
const firstLineNoHeading = testContent.split('\n')[1]
|
||||
const firstLineFirstHeading = `# ${firstLineNoHeading}`
|
||||
const firstLineFirstHeading = `# ${ firstLineNoHeading }`
|
||||
|
||||
it('no heading before', done => {
|
||||
const editor = buildEditor({
|
||||
getCursor: () => cursor.from,
|
||||
listSelections: mockListSelections(cursor, true),
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual(firstHeading)
|
||||
expect(replacement)
|
||||
.toEqual(firstHeading)
|
||||
done()
|
||||
},
|
||||
getLine: (): string => (noHeading)
|
||||
|
@ -434,7 +438,8 @@ describe('test addHeaderLevel', () => {
|
|||
getCursor: () => cursor.from,
|
||||
listSelections: mockListSelections(cursor, true),
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual(secondHeading)
|
||||
expect(replacement)
|
||||
.toEqual(secondHeading)
|
||||
done()
|
||||
},
|
||||
getLine: (): string => (firstHeading)
|
||||
|
@ -447,7 +452,8 @@ describe('test addHeaderLevel', () => {
|
|||
getCursor: () => cursor.from,
|
||||
listSelections: mockListSelections(firstLine, false),
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual(firstLineFirstHeading)
|
||||
expect(replacement)
|
||||
.toEqual(firstLineFirstHeading)
|
||||
done()
|
||||
},
|
||||
getLine: (): string => (firstLineNoHeading)
|
||||
|
@ -460,7 +466,8 @@ describe('test addHeaderLevel', () => {
|
|||
getCursor: () => cursor.from,
|
||||
listSelections: mockListSelections(multiline, false),
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual(firstLineFirstHeading)
|
||||
expect(replacement)
|
||||
.toEqual(firstLineFirstHeading)
|
||||
done()
|
||||
},
|
||||
getLine: (): string => (firstLineNoHeading)
|
||||
|
@ -473,7 +480,8 @@ describe('test addHeaderLevel', () => {
|
|||
getCursor: () => cursor.from,
|
||||
listSelections: mockListSelections(multilineOffset, false),
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual(firstLineFirstHeading)
|
||||
expect(replacement)
|
||||
.toEqual(firstLineFirstHeading)
|
||||
done()
|
||||
},
|
||||
getLine: (): string => (firstLineNoHeading)
|
||||
|
@ -492,7 +500,8 @@ describe('test addCodeFences', () => {
|
|||
listSelections: mockListSelections(cursor, true),
|
||||
getLine: (): string => '',
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual('```\n\n```')
|
||||
expect(replacement)
|
||||
.toEqual('```\n\n```')
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
@ -506,7 +515,8 @@ describe('test addCodeFences', () => {
|
|||
listSelections: mockListSelections(cursor, true),
|
||||
getLine: (): string => '1st line',
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual('```\n1st line\n```')
|
||||
expect(replacement)
|
||||
.toEqual('```\n1st line\n```')
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
@ -555,7 +565,8 @@ describe('test addQuotes', () => {
|
|||
listSelections: mockListSelections(cursor, true),
|
||||
getLine: (): string => (textFirstLine),
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual(`> ${textFirstLine}`)
|
||||
expect(replacement)
|
||||
.toEqual(`> ${ textFirstLine }`)
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
@ -568,7 +579,7 @@ describe('test addQuotes', () => {
|
|||
getCursor: () => cursor.from,
|
||||
listSelections: mockListSelections(firstLine, false),
|
||||
getLine: (): string => (textFirstLine),
|
||||
replaceRange: expectFromToReplacement(firstLine, `> ${textFirstLine}`, done)
|
||||
replaceRange: expectFromToReplacement(firstLine, `> ${ textFirstLine }`, done)
|
||||
})
|
||||
addQuotes(editor)
|
||||
})
|
||||
|
@ -602,7 +613,8 @@ describe('test unordered list', () => {
|
|||
listSelections: mockListSelections(cursor, true),
|
||||
getLine: (): string => (textFirstLine),
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual(`- ${textFirstLine}`)
|
||||
expect(replacement)
|
||||
.toEqual(`- ${ textFirstLine }`)
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
@ -614,7 +626,7 @@ describe('test unordered list', () => {
|
|||
getCursor: () => cursor.from,
|
||||
listSelections: mockListSelections(firstLine, false),
|
||||
getLine: (): string => (textFirstLine),
|
||||
replaceRange: expectFromToReplacement(firstLine, `- ${textFirstLine}`, done)
|
||||
replaceRange: expectFromToReplacement(firstLine, `- ${ textFirstLine }`, done)
|
||||
})
|
||||
addList(editor)
|
||||
})
|
||||
|
@ -625,7 +637,8 @@ describe('test unordered list', () => {
|
|||
listSelections: mockListSelections(multiline, false),
|
||||
getLine: (): string => (textFirstLine),
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual('- 2nd line3rd line')
|
||||
expect(replacement)
|
||||
.toEqual('- 2nd line3rd line')
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
@ -638,7 +651,8 @@ describe('test unordered list', () => {
|
|||
listSelections: mockListSelections(multilineOffset, false),
|
||||
getLine: (): string => (textFirstLine),
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual('- line3rd ')
|
||||
expect(replacement)
|
||||
.toEqual('- line3rd ')
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
@ -655,7 +669,8 @@ describe('test ordered list', () => {
|
|||
listSelections: mockListSelections(cursor, true),
|
||||
getLine: (): string => (textFirstLine),
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual(`1. ${textFirstLine}`)
|
||||
expect(replacement)
|
||||
.toEqual(`1. ${ textFirstLine }`)
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
@ -667,7 +682,7 @@ describe('test ordered list', () => {
|
|||
getCursor: () => cursor.from,
|
||||
listSelections: mockListSelections(firstLine, false),
|
||||
getLine: (): string => (textFirstLine),
|
||||
replaceRange: expectFromToReplacement(firstLine, `1. ${textFirstLine}`, done)
|
||||
replaceRange: expectFromToReplacement(firstLine, `1. ${ textFirstLine }`, done)
|
||||
})
|
||||
addOrderedList(editor)
|
||||
})
|
||||
|
@ -678,7 +693,8 @@ describe('test ordered list', () => {
|
|||
listSelections: mockListSelections(multiline, false),
|
||||
getLine: (): string => (textFirstLine),
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual('1. 2nd line3rd line')
|
||||
expect(replacement)
|
||||
.toEqual('1. 2nd line3rd line')
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
@ -691,7 +707,8 @@ describe('test ordered list', () => {
|
|||
listSelections: mockListSelections(multilineOffset, false),
|
||||
getLine: (): string => (textFirstLine),
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual('1. line3rd ')
|
||||
expect(replacement)
|
||||
.toEqual('1. line3rd ')
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
@ -709,7 +726,8 @@ describe('test todo list', () => {
|
|||
listSelections: mockListSelections(cursor, true),
|
||||
getLine: (): string => (textFirstLine),
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual(`- [ ] ${textFirstLine}`)
|
||||
expect(replacement)
|
||||
.toEqual(`- [ ] ${ textFirstLine }`)
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
@ -721,7 +739,7 @@ describe('test todo list', () => {
|
|||
getCursor: () => cursor.from,
|
||||
listSelections: mockListSelections(firstLine, false),
|
||||
getLine: (): string => (textFirstLine),
|
||||
replaceRange: expectFromToReplacement(firstLine, `- [ ] ${textFirstLine}`, done)
|
||||
replaceRange: expectFromToReplacement(firstLine, `- [ ] ${ textFirstLine }`, done)
|
||||
})
|
||||
addTaskList(editor)
|
||||
})
|
||||
|
@ -732,7 +750,8 @@ describe('test todo list', () => {
|
|||
listSelections: mockListSelections(multiline, false),
|
||||
getLine: (): string => (textFirstLine),
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual('- [ ] 2nd line3rd line')
|
||||
expect(replacement)
|
||||
.toEqual('- [ ] 2nd line3rd line')
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
@ -745,7 +764,8 @@ describe('test todo list', () => {
|
|||
listSelections: mockListSelections(multilineOffset, false),
|
||||
getLine: (): string => (textFirstLine),
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual('- [ ] line3rd ')
|
||||
expect(replacement)
|
||||
.toEqual('- [ ] line3rd ')
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
@ -764,7 +784,8 @@ describe('test addLink', () => {
|
|||
listSelections: mockListSelections(cursor, true),
|
||||
getLine: (): string => (textFirstLine),
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual('[](https://)')
|
||||
expect(replacement)
|
||||
.toEqual('[](https://)')
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
@ -776,7 +797,7 @@ describe('test addLink', () => {
|
|||
getCursor: () => cursor.from,
|
||||
listSelections: mockListSelections(firstLine, false),
|
||||
getLine: (): string => (textFirstLine),
|
||||
replaceRange: expectFromToReplacement(firstLine, `[${textFirstLine}](https://)`, done)
|
||||
replaceRange: expectFromToReplacement(firstLine, `[${ textFirstLine }](https://)`, done)
|
||||
})
|
||||
addLink(editor)
|
||||
})
|
||||
|
@ -787,7 +808,8 @@ describe('test addLink', () => {
|
|||
listSelections: mockListSelections(multiline, false),
|
||||
getLine: (): string => (textFirstLine),
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual('[2nd line3rd line](https://)')
|
||||
expect(replacement)
|
||||
.toEqual('[2nd line3rd line](https://)')
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
@ -800,7 +822,8 @@ describe('test addLink', () => {
|
|||
listSelections: mockListSelections(multilineOffset, false),
|
||||
getLine: (): string => (textFirstLine),
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual('[line3rd ](https://)')
|
||||
expect(replacement)
|
||||
.toEqual('[line3rd ](https://)')
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
@ -819,7 +842,8 @@ describe('test addImage', () => {
|
|||
listSelections: mockListSelections(cursor, true),
|
||||
getLine: (): string => (textFirstLine),
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual('')
|
||||
expect(replacement)
|
||||
.toEqual('')
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
@ -831,7 +855,7 @@ describe('test addImage', () => {
|
|||
getCursor: () => cursor.from,
|
||||
listSelections: mockListSelections(firstLine, false),
|
||||
getLine: (): string => (textFirstLine),
|
||||
replaceRange: expectFromToReplacement(firstLine, ``, done)
|
||||
replaceRange: expectFromToReplacement(firstLine, ``, done)
|
||||
})
|
||||
addImage(editor)
|
||||
})
|
||||
|
@ -842,7 +866,8 @@ describe('test addImage', () => {
|
|||
listSelections: mockListSelections(multiline, false),
|
||||
getLine: (): string => (textFirstLine),
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual('')
|
||||
expect(replacement)
|
||||
.toEqual('')
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
@ -855,7 +880,8 @@ describe('test addImage', () => {
|
|||
listSelections: mockListSelections(multilineOffset, false),
|
||||
getLine: (): string => (textFirstLine),
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual('')
|
||||
expect(replacement)
|
||||
.toEqual('')
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
@ -874,7 +900,8 @@ describe('test addLine', () => {
|
|||
listSelections: mockListSelections(cursor, true),
|
||||
getLine: (): string => (textFirstLine),
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual(`${textFirstLine}\n----`)
|
||||
expect(replacement)
|
||||
.toEqual(`${ textFirstLine }\n----`)
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
@ -886,7 +913,7 @@ describe('test addLine', () => {
|
|||
getCursor: () => cursor.from,
|
||||
listSelections: mockListSelections(firstLine, false),
|
||||
getLine: (): string => (textFirstLine),
|
||||
replaceRange: expectFromToReplacement(firstLine, `${textFirstLine}\n----`, done)
|
||||
replaceRange: expectFromToReplacement(firstLine, `${ textFirstLine }\n----`, done)
|
||||
})
|
||||
addLine(editor)
|
||||
})
|
||||
|
@ -897,7 +924,8 @@ describe('test addLine', () => {
|
|||
listSelections: mockListSelections(multiline, false),
|
||||
getLine: (): string => '2nd line',
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual('2nd line\n----')
|
||||
expect(replacement)
|
||||
.toEqual('2nd line\n----')
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
@ -910,7 +938,8 @@ describe('test addLine', () => {
|
|||
listSelections: mockListSelections(multilineOffset, false),
|
||||
getLine: (): string => '2nd line',
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual('2nd line\n----')
|
||||
expect(replacement)
|
||||
.toEqual('2nd line\n----')
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
@ -929,7 +958,8 @@ describe('test collapsable block', () => {
|
|||
listSelections: mockListSelections(cursor, true),
|
||||
getLine: (): string => (textFirstLine),
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual(`${textFirstLine}\n:::spoiler Toggle label\n Toggled content\n:::`)
|
||||
expect(replacement)
|
||||
.toEqual(`${ textFirstLine }\n:::spoiler Toggle label\n Toggled content\n:::`)
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
@ -941,7 +971,7 @@ describe('test collapsable block', () => {
|
|||
getCursor: () => cursor.from,
|
||||
listSelections: mockListSelections(firstLine, false),
|
||||
getLine: (): string => (textFirstLine),
|
||||
replaceRange: expectFromToReplacement(firstLine, `${textFirstLine}\n:::spoiler Toggle label\n Toggled content\n:::`, done)
|
||||
replaceRange: expectFromToReplacement(firstLine, `${ textFirstLine }\n:::spoiler Toggle label\n Toggled content\n:::`, done)
|
||||
})
|
||||
addCollapsableBlock(editor)
|
||||
})
|
||||
|
@ -952,7 +982,8 @@ describe('test collapsable block', () => {
|
|||
listSelections: mockListSelections(multiline, false),
|
||||
getLine: (): string => '2nd line',
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual('2nd line\n:::spoiler Toggle label\n Toggled content\n:::')
|
||||
expect(replacement)
|
||||
.toEqual('2nd line\n:::spoiler Toggle label\n Toggled content\n:::')
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
@ -965,7 +996,8 @@ describe('test collapsable block', () => {
|
|||
listSelections: mockListSelections(multilineOffset, false),
|
||||
getLine: (): string => '2nd line',
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual('2nd line\n:::spoiler Toggle label\n Toggled content\n:::')
|
||||
expect(replacement)
|
||||
.toEqual('2nd line\n:::spoiler Toggle label\n Toggled content\n:::')
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
@ -984,7 +1016,8 @@ describe('test addComment', () => {
|
|||
listSelections: mockListSelections(cursor, true),
|
||||
getLine: (): string => (textFirstLine),
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual(`${textFirstLine}\n> []`)
|
||||
expect(replacement)
|
||||
.toEqual(`${ textFirstLine }\n> []`)
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
@ -996,7 +1029,7 @@ describe('test addComment', () => {
|
|||
getCursor: () => cursor.from,
|
||||
listSelections: mockListSelections(firstLine, false),
|
||||
getLine: (): string => (textFirstLine),
|
||||
replaceRange: expectFromToReplacement(firstLine, `${textFirstLine}\n> []`, done)
|
||||
replaceRange: expectFromToReplacement(firstLine, `${ textFirstLine }\n> []`, done)
|
||||
})
|
||||
addComment(editor)
|
||||
})
|
||||
|
@ -1007,7 +1040,8 @@ describe('test addComment', () => {
|
|||
listSelections: mockListSelections(multiline, false),
|
||||
getLine: (): string => '2nd line',
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual('2nd line\n> []')
|
||||
expect(replacement)
|
||||
.toEqual('2nd line\n> []')
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
@ -1020,7 +1054,8 @@ describe('test addComment', () => {
|
|||
listSelections: mockListSelections(multilineOffset, false),
|
||||
getLine: (): string => '2nd line',
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual('2nd line\n> []')
|
||||
expect(replacement)
|
||||
.toEqual('2nd line\n> []')
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
@ -1039,7 +1074,8 @@ describe('test addTable', () => {
|
|||
listSelections: mockListSelections(cursor, true),
|
||||
getLine: (): string => (textFirstLine),
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual(`${textFirstLine}\n${table}`)
|
||||
expect(replacement)
|
||||
.toEqual(`${ textFirstLine }\n${ table }`)
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
@ -1051,7 +1087,7 @@ describe('test addTable', () => {
|
|||
getCursor: () => cursor.from,
|
||||
listSelections: mockListSelections(firstLine, false),
|
||||
getLine: (): string => (textFirstLine),
|
||||
replaceRange: expectFromToReplacement(firstLine, `${textFirstLine}\n${table}`, done)
|
||||
replaceRange: expectFromToReplacement(firstLine, `${ textFirstLine }\n${ table }`, done)
|
||||
})
|
||||
addTable(editor, 1, 3)
|
||||
})
|
||||
|
@ -1062,7 +1098,8 @@ describe('test addTable', () => {
|
|||
listSelections: mockListSelections(multiline, false),
|
||||
getLine: (): string => '2nd line',
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual(`2nd line\n${table}`)
|
||||
expect(replacement)
|
||||
.toEqual(`2nd line\n${ table }`)
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
@ -1075,7 +1112,8 @@ describe('test addTable', () => {
|
|||
listSelections: mockListSelections(multilineOffset, false),
|
||||
getLine: (): string => '2nd line',
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual(`2nd line\n${table}`)
|
||||
expect(replacement)
|
||||
.toEqual(`2nd line\n${ table }`)
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
@ -1112,7 +1150,8 @@ describe('test addEmoji with native emoji', () => {
|
|||
listSelections: mockListSelections(cursor, true),
|
||||
getLine: (): string => (textFirstLine),
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual(':1234:')
|
||||
expect(replacement)
|
||||
.toEqual(':1234:')
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
@ -1173,7 +1212,8 @@ describe('test addEmoji with native emoji', () => {
|
|||
listSelections: mockListSelections(cursor, true),
|
||||
getLine: (): string => (textFirstLine),
|
||||
replaceRange: (replacement: string | string[]) => {
|
||||
expect(replacement).toEqual(forkAwesomeIcon)
|
||||
expect(replacement)
|
||||
.toEqual(forkAwesomeIcon)
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
|
|
@ -17,27 +17,31 @@ export const subscriptSelection = (editor: Editor): void => wrapTextWith(editor,
|
|||
export const superscriptSelection = (editor: Editor): void => wrapTextWith(editor, '^')
|
||||
export const markSelection = (editor: Editor): void => wrapTextWith(editor, '==')
|
||||
|
||||
export const addHeaderLevel = (editor: Editor): void => changeLines(editor, line => line.startsWith('#') ? `#${line}` : `# ${line}`)
|
||||
export const addHeaderLevel = (editor: Editor): void => changeLines(editor, line => line.startsWith('#') ? `#${ line }` : `# ${ line }`)
|
||||
export const addCodeFences = (editor: Editor): void => wrapTextWithOrJustPut(editor, '```\n', '\n```')
|
||||
export const addQuotes = (editor: Editor): void => insertOnStartOfLines(editor, '> ')
|
||||
|
||||
export const addList = (editor: Editor): void => createList(editor, () => '- ')
|
||||
export const addOrderedList = (editor: Editor): void => createList(editor, j => `${j}. `)
|
||||
export const addOrderedList = (editor: Editor): void => createList(editor, j => `${ j }. `)
|
||||
export const addTaskList = (editor: Editor): void => createList(editor, () => '- [ ] ')
|
||||
|
||||
export const addImage = (editor: Editor): void => addLink(editor, '!')
|
||||
|
||||
export const addLine = (editor: Editor): void => changeLines(editor, line => `${line}\n----`)
|
||||
export const addCollapsableBlock = (editor: Editor): void => changeLines(editor, line => `${line}\n:::spoiler Toggle label\n Toggled content\n:::`)
|
||||
export const addComment = (editor: Editor): void => changeLines(editor, line => `${line}\n> []`)
|
||||
export const addLine = (editor: Editor): void => changeLines(editor, line => `${ line }\n----`)
|
||||
export const addCollapsableBlock = (editor: Editor): void => changeLines(editor, line => `${ line }\n:::spoiler Toggle label\n Toggled content\n:::`)
|
||||
export const addComment = (editor: Editor): void => changeLines(editor, line => `${ line }\n> []`)
|
||||
export const addTable = (editor: Editor, rows: number, columns: number): void => {
|
||||
const rowArray = createNumberRangeArray(rows)
|
||||
const colArray = createNumberRangeArray(columns).map(col => col + 1)
|
||||
const colArray = createNumberRangeArray(columns)
|
||||
.map(col => col + 1)
|
||||
const head = '| # ' + colArray.join(' | # ') + ' |'
|
||||
const divider = '| ' + colArray.map(() => '----').join(' | ') + ' |'
|
||||
const body = rowArray.map(() => '| ' + colArray.map(() => 'Text').join(' | ') + ' |').join('\n')
|
||||
const table = `${head}\n${divider}\n${body}`
|
||||
changeLines(editor, line => `${line}\n${table}`)
|
||||
const divider = '| ' + colArray.map(() => '----')
|
||||
.join(' | ') + ' |'
|
||||
const body = rowArray.map(() => '| ' + colArray.map(() => 'Text')
|
||||
.join(' | ') + ' |')
|
||||
.join('\n')
|
||||
const table = `${ head }\n${ divider }\n${ body }`
|
||||
changeLines(editor, line => `${ line }\n${ table }`)
|
||||
}
|
||||
|
||||
export const addEmoji = (emoji: EmojiClickEventDetail, editor: Editor): void => {
|
||||
|
@ -72,7 +76,7 @@ const wrapTextWithOrJustPut = (editor: Editor, symbol: string, endSymbol?: strin
|
|||
const cursor = editor.getCursor()
|
||||
const lineNumber = cursor.line
|
||||
const line = editor.getLine(lineNumber)
|
||||
const replacement = /\s*\\n/.exec(line) ? `${symbol}${endSymbol ?? ''}` : `${symbol}${line}${endSymbol ?? ''}`
|
||||
const replacement = /\s*\\n/.exec(line) ? `${ symbol }${ endSymbol ?? '' }` : `${ symbol }${ line }${ endSymbol ?? '' }`
|
||||
editor.replaceRange(replacement,
|
||||
{ line: cursor.line, ch: 0 },
|
||||
{ line: cursor.line, ch: line.length },
|
||||
|
@ -89,7 +93,8 @@ export const insertOnStartOfLines = (editor: Editor, symbol: string): void => {
|
|||
const to = range.empty() ? { line: cursor.line, ch: editor.getLine(cursor.line).length } : range.to()
|
||||
const selection = editor.getRange(from, to)
|
||||
const lines = selection.split('\n')
|
||||
editor.replaceRange(lines.map(line => `${symbol}${line}`).join('\n'), from, to, '+input')
|
||||
editor.replaceRange(lines.map(line => `${ symbol }${ line }`)
|
||||
.join('\n'), from, to, '+input')
|
||||
}
|
||||
editor.setSelections(ranges)
|
||||
}
|
||||
|
@ -117,7 +122,8 @@ export const createList = (editor: Editor, listMark: (i: number) => string): voi
|
|||
|
||||
const selection = editor.getRange(from, to)
|
||||
const lines = selection.split('\n')
|
||||
editor.replaceRange(lines.map((line, i) => `${listMark(i + 1)}${line}`).join('\n'), from, to, '+input')
|
||||
editor.replaceRange(lines.map((line, i) => `${ listMark(i + 1) }${ line }`)
|
||||
.join('\n'), from, to, '+input')
|
||||
}
|
||||
editor.setSelections(ranges)
|
||||
}
|
||||
|
@ -131,9 +137,9 @@ export const addLink = (editor: Editor, prefix?: string): void => {
|
|||
const selection = editor.getRange(from, to)
|
||||
const linkRegex = /^(?:https?|ftp|mailto):/
|
||||
if (linkRegex.exec(selection)) {
|
||||
editor.replaceRange(`${prefix || ''}[](${selection})`, from, to, '+input')
|
||||
editor.replaceRange(`${ prefix || '' }[](${ selection })`, from, to, '+input')
|
||||
} else {
|
||||
editor.replaceRange(`${prefix || ''}[${selection}](https://)`, from, to, '+input')
|
||||
editor.replaceRange(`${ prefix || '' }[${ selection }](https://)`, from, to, '+input')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -144,6 +150,6 @@ export const insertAtCursor = (editor: Editor, text: string): void => {
|
|||
for (const range of ranges) {
|
||||
const from = range.empty() ? { line: cursor.line, ch: cursor.ch } : range.from()
|
||||
const to = range.empty() ? { line: cursor.line, ch: cursor.ch } : range.to()
|
||||
editor.replaceRange(`${text}`, from, to, '+input')
|
||||
editor.replaceRange(`${ text }`, from, to, '+input')
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue