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:
Tilman Vatteroth 2021-02-03 22:13:04 +01:00 committed by GitHub
parent 0180c75e55
commit e12dc523f8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
301 changed files with 4393 additions and 3741 deletions

View file

@ -57,6 +57,14 @@ ij_scss_space_before_opening_brace = true
ij_scss_use_double_quotes = true
ij_scss_value_alignment = 0
[.editorconfig]
ij_editorconfig_align_group_field_declarations = false
ij_editorconfig_space_after_colon = false
ij_editorconfig_space_after_comma = true
ij_editorconfig_space_before_colon = false
ij_editorconfig_space_before_comma = false
ij_editorconfig_spaces_around_assignment_operators = true
[{*.ats, *.ts, *.tsx}]
indent_size = 2
tab_width = 2
@ -64,18 +72,18 @@ ij_continuation_indent_size = 2
ij_typescript_align_imports = false
ij_typescript_align_multiline_array_initializer_expression = false
ij_typescript_align_multiline_binary_operation = false
ij_typescript_align_multiline_chained_methods = false
ij_typescript_align_multiline_chained_methods = true
ij_typescript_align_multiline_extends_list = false
ij_typescript_align_multiline_for = true
ij_typescript_align_multiline_parameters = true
ij_typescript_align_multiline_parameters = false
ij_typescript_align_multiline_parameters_in_calls = false
ij_typescript_align_multiline_ternary_operation = false
ij_typescript_align_object_properties = 0
ij_typescript_align_union_types = false
ij_typescript_align_union_types = true
ij_typescript_align_var_statements = 0
ij_typescript_array_initializer_new_line_after_left_brace = false
ij_typescript_array_initializer_right_brace_on_new_line = false
ij_typescript_array_initializer_wrap = off
ij_typescript_array_initializer_wrap = normal
ij_typescript_assignment_wrap = off
ij_typescript_binary_operation_sign_on_next_line = false
ij_typescript_binary_operation_wrap = off
@ -95,26 +103,26 @@ ij_typescript_catch_on_new_line = false
ij_typescript_chained_call_dot_on_new_line = true
ij_typescript_class_brace_style = end_of_line
ij_typescript_comma_on_new_line = false
ij_typescript_do_while_brace_force = never
ij_typescript_do_while_brace_force = always
ij_typescript_else_on_new_line = false
ij_typescript_enforce_trailing_comma = keep
ij_typescript_enforce_trailing_comma = remove
ij_typescript_extends_keyword_wrap = off
ij_typescript_extends_list_wrap = off
ij_typescript_field_prefix = _
ij_typescript_file_name_style = relaxed
ij_typescript_finally_on_new_line = false
ij_typescript_for_brace_force = never
ij_typescript_for_brace_force = always
ij_typescript_for_statement_new_line_after_left_paren = false
ij_typescript_for_statement_right_paren_on_new_line = false
ij_typescript_for_statement_wrap = off
ij_typescript_force_quote_style = false
ij_typescript_force_quote_style = true
ij_typescript_force_semicolon_style = true
ij_typescript_function_expression_brace_style = end_of_line
ij_typescript_if_brace_force = never
ij_typescript_if_brace_force = always
ij_typescript_import_merge_members = global
ij_typescript_import_prefer_absolute_path = global
ij_typescript_import_sort_members = true
ij_typescript_import_sort_module_name = true
ij_typescript_import_sort_module_name = false
ij_typescript_import_use_node_resolution = true
ij_typescript_imports_wrap = on_every_item
ij_typescript_indent_case_from_switch = true
@ -122,7 +130,7 @@ ij_typescript_indent_chained_calls = true
ij_typescript_indent_package_children = 0
ij_typescript_jsdoc_include_types = false
ij_typescript_jsx_attribute_value = braces
ij_typescript_keep_blank_lines_in_code = 1
ij_typescript_keep_blank_lines_in_code = 2
ij_typescript_keep_first_column_comment = true
ij_typescript_keep_indents_on_empty_lines = false
ij_typescript_keep_line_breaks = true
@ -131,11 +139,11 @@ ij_typescript_keep_simple_methods_in_one_line = false
ij_typescript_line_comment_add_space = true
ij_typescript_line_comment_at_first_column = false
ij_typescript_method_brace_style = end_of_line
ij_typescript_method_call_chain_wrap = off
ij_typescript_method_call_chain_wrap = split_into_lines
ij_typescript_method_parameters_new_line_after_left_paren = false
ij_typescript_method_parameters_right_paren_on_new_line = false
ij_typescript_method_parameters_wrap = off
ij_typescript_object_literal_wrap = on_every_item
ij_typescript_object_literal_wrap = off
ij_typescript_parentheses_expression_new_line_after_left_paren = false
ij_typescript_parentheses_expression_right_paren_on_new_line = false
ij_typescript_place_assignment_sign_on_next_line = false
@ -144,7 +152,7 @@ ij_typescript_prefer_explicit_types_function_expression_returns = false
ij_typescript_prefer_explicit_types_function_returns = false
ij_typescript_prefer_explicit_types_vars_fields = false
ij_typescript_prefer_parameters_wrap = false
ij_typescript_reformat_c_style_comments = false
ij_typescript_reformat_c_style_comments = true
ij_typescript_space_after_colon = true
ij_typescript_space_after_comma = true
ij_typescript_space_after_dots_in_rest_parameter = false
@ -175,7 +183,7 @@ ij_typescript_space_before_if_left_brace = true
ij_typescript_space_before_if_parentheses = true
ij_typescript_space_before_method_call_parentheses = false
ij_typescript_space_before_method_left_brace = true
ij_typescript_space_before_method_parentheses = true
ij_typescript_space_before_method_parentheses = false
ij_typescript_space_before_property_colon = false
ij_typescript_space_before_quest = true
ij_typescript_space_before_switch_left_brace = true
@ -202,7 +210,7 @@ ij_typescript_spaces_within_catch_parentheses = false
ij_typescript_spaces_within_for_parentheses = false
ij_typescript_spaces_within_if_parentheses = false
ij_typescript_spaces_within_imports = true
ij_typescript_spaces_within_interpolation_expressions = false
ij_typescript_spaces_within_interpolation_expressions = true
ij_typescript_spaces_within_method_call_parentheses = false
ij_typescript_spaces_within_method_parentheses = false
ij_typescript_spaces_within_object_literal_braces = true
@ -215,15 +223,15 @@ ij_typescript_spaces_within_while_parentheses = false
ij_typescript_special_else_if_treatment = true
ij_typescript_ternary_operation_signs_on_next_line = false
ij_typescript_ternary_operation_wrap = off
ij_typescript_union_types_wrap = on_every_item
ij_typescript_union_types_wrap = normal
ij_typescript_use_chained_calls_group_indents = false
ij_typescript_use_double_quotes = false
ij_typescript_use_explicit_js_extension = global
ij_typescript_use_path_mapping = always
ij_typescript_use_public_modifier = false
ij_typescript_use_semicolon_after_statement = false
ij_typescript_var_declaration_wrap = normal
ij_typescript_while_brace_force = never
ij_typescript_var_declaration_wrap = on_every_item
ij_typescript_while_brace_force = always
ij_typescript_while_on_new_line = false
ij_typescript_wrap_comments = false
@ -275,8 +283,8 @@ ij_javascript_for_brace_force = never
ij_javascript_for_statement_new_line_after_left_paren = false
ij_javascript_for_statement_right_paren_on_new_line = false
ij_javascript_for_statement_wrap = off
ij_javascript_force_quote_style = true
ij_javascript_force_semicolon_style = true
ij_javascript_force_quote_style = false
ij_javascript_force_semicolon_style = false
ij_javascript_function_expression_brace_style = end_of_line
ij_javascript_if_brace_force = never
ij_javascript_import_merge_members = global
@ -289,12 +297,12 @@ ij_javascript_indent_case_from_switch = true
ij_javascript_indent_chained_calls = true
ij_javascript_indent_package_children = 0
ij_javascript_jsx_attribute_value = braces
ij_javascript_keep_blank_lines_in_code = 1
ij_javascript_keep_blank_lines_in_code = 2
ij_javascript_keep_first_column_comment = true
ij_javascript_keep_indents_on_empty_lines = false
ij_javascript_keep_line_breaks = true
ij_javascript_keep_simple_blocks_in_one_line = true
ij_javascript_keep_simple_methods_in_one_line = true
ij_javascript_keep_simple_blocks_in_one_line = false
ij_javascript_keep_simple_methods_in_one_line = false
ij_javascript_line_comment_add_space = true
ij_javascript_line_comment_at_first_column = false
ij_javascript_method_brace_style = end_of_line
@ -337,12 +345,12 @@ ij_javascript_space_before_for_left_brace = true
ij_javascript_space_before_for_parentheses = true
ij_javascript_space_before_for_semicolon = false
ij_javascript_space_before_function_left_parenth = true
ij_javascript_space_before_generator_mult = true
ij_javascript_space_before_generator_mult = false
ij_javascript_space_before_if_left_brace = true
ij_javascript_space_before_if_parentheses = true
ij_javascript_space_before_method_call_parentheses = false
ij_javascript_space_before_method_left_brace = true
ij_javascript_space_before_method_parentheses = true
ij_javascript_space_before_method_parentheses = false
ij_javascript_space_before_property_colon = false
ij_javascript_space_before_quest = true
ij_javascript_space_before_switch_left_brace = true
@ -368,11 +376,11 @@ ij_javascript_spaces_within_brackets = false
ij_javascript_spaces_within_catch_parentheses = false
ij_javascript_spaces_within_for_parentheses = false
ij_javascript_spaces_within_if_parentheses = false
ij_javascript_spaces_within_imports = true
ij_javascript_spaces_within_imports = false
ij_javascript_spaces_within_interpolation_expressions = false
ij_javascript_spaces_within_method_call_parentheses = false
ij_javascript_spaces_within_method_parentheses = false
ij_javascript_spaces_within_object_literal_braces = true
ij_javascript_spaces_within_object_literal_braces = false
ij_javascript_spaces_within_object_type_braces = true
ij_javascript_spaces_within_parentheses = false
ij_javascript_spaces_within_switch_parentheses = false
@ -380,22 +388,22 @@ ij_javascript_spaces_within_type_assertion = false
ij_javascript_spaces_within_union_types = true
ij_javascript_spaces_within_while_parentheses = false
ij_javascript_special_else_if_treatment = true
ij_javascript_ternary_operation_signs_on_next_line = true
ij_javascript_ternary_operation_signs_on_next_line = false
ij_javascript_ternary_operation_wrap = off
ij_javascript_union_types_wrap = on_every_item
ij_javascript_use_chained_calls_group_indents = false
ij_javascript_use_double_quotes = false
ij_javascript_use_double_quotes = true
ij_javascript_use_explicit_js_extension = global
ij_javascript_use_path_mapping = always
ij_javascript_use_public_modifier = false
ij_javascript_use_semicolon_after_statement = false
ij_javascript_use_semicolon_after_statement = true
ij_javascript_var_declaration_wrap = normal
ij_javascript_while_brace_force = never
ij_javascript_while_on_new_line = false
ij_javascript_wrap_comments = false
[{*.har,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.prettierrc,.stylelintrc,bowerrc,jest.config}]
indent_size = 4
indent_size = 2
ij_json_keep_blank_lines_in_code = 0
ij_json_keep_indents_on_empty_lines = false
ij_json_keep_line_breaks = true
@ -433,9 +441,30 @@ ij_html_space_after_tag_name = false
ij_html_space_around_equality_in_attribute = false
ij_html_space_inside_empty_tag = false
ij_html_text_wrap = normal
ij_html_uniform_ident = false
[{*.markdown, *.md}]
ij_markdown_force_one_space_after_blockquote_symbol = true
ij_markdown_force_one_space_after_header_symbol = true
ij_markdown_force_one_space_after_list_bullet = true
ij_markdown_force_one_space_between_words = true
ij_markdown_keep_indents_on_empty_lines = false
ij_markdown_max_lines_around_block_elements = 1
ij_markdown_max_lines_around_header = 1
ij_markdown_max_lines_between_paragraphs = 1
ij_markdown_min_lines_around_block_elements = 1
ij_markdown_min_lines_around_header = 1
ij_markdown_min_lines_between_paragraphs = 1
[{*.yaml, *.yml}]
indent_size = 2
ij_yaml_align_values_properties = do_not_align
ij_yaml_autoinsert_sequence_marker = true
ij_yaml_block_mapping_on_new_line = false
ij_yaml_indent_sequence_value = true
ij_yaml_keep_indents_on_empty_lines = false
ij_yaml_keep_line_breaks = true
ij_yaml_sequence_on_new_line = false
ij_yaml_space_before_colon = false
ij_yaml_spaces_within_braces = true
ij_yaml_spaces_within_brackets = true

View file

@ -24,7 +24,9 @@ describe('Banner', () => {
.find('.fa-times')
.click()
.then(() => {
expect(localStorage.getItem('bannerTimeStamp')).to.equal(banner.timestamp)
expect(localStorage.getItem('bannerTimeStamp'))
.to
.equal(banner.timestamp)
})
cy.get('.alert-primary.show')
.should('not.exist')

View file

@ -49,28 +49,33 @@ describe('File upload', () => {
})
it('via paste', () => {
cy.fixture('acme.png').then((image: string) => {
cy.fixture('acme.png')
.then((image: string) => {
const pasteEvent = {
clipboardData: {
files: [Cypress.Blob.base64StringToBlob(image, 'image/png')]
}
}
cy.get('.CodeMirror-scroll').trigger('paste', pasteEvent)
cy.get('.CodeMirror-scroll')
.trigger('paste', pasteEvent)
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
.should('have.text', `![](${ imageUrl })`)
})
})
it('via drag and drop', () => {
cy.fixture('acme.png').then((image: string) => {
cy.fixture('acme.png')
.then((image: string) => {
const dropEvent = {
dataTransfer: {
files: [Cypress.Blob.base64StringToBlob(image, 'image/png')],
effectAllowed: 'uninitialized'
}
}
cy.get('.CodeMirror-scroll').trigger('dragenter', dropEvent)
cy.get('.CodeMirror-scroll').trigger('drop', dropEvent)
cy.get('.CodeMirror-scroll')
.trigger('dragenter', dropEvent)
cy.get('.CodeMirror-scroll')
.trigger('drop', dropEvent)
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
.should('have.text', `![](${ imageUrl })`)
})
@ -86,7 +91,8 @@ describe('File upload', () => {
})
cy.get('.fa-upload')
.click()
cy.fixture('acme.png').then(() => {
cy.fixture('acme.png')
.then(() => {
cy.get('input[type=file]')
.attachFile({ filePath: 'acme.png', mimeType: 'image/png' })
})
@ -101,7 +107,8 @@ describe('File upload', () => {
getData: (type = 'text') => testText
}
}
cy.get('.CodeMirror-scroll').trigger('paste', pasteEvent)
cy.get('.CodeMirror-scroll')
.trigger('paste', pasteEvent)
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
.should('have.text', `${ testText }`)
})

View file

@ -160,14 +160,15 @@ describe('Code', () => {
return cy.wrap(null)
}
cy.spy(frame.contentWindow.navigator.clipboard, 'writeText').as("copy")
cy.spy(frame.contentWindow.navigator.clipboard, 'writeText')
.as('copy')
})
cy.getMarkdownRenderer()
.find('[data-cy="copy-code-button"]')
.click()
cy.get("@copy")
cy.get('@copy')
.should('be.calledWithExactly', 'let x = 0\n')
})
})

View file

@ -17,7 +17,8 @@ describe('Languages', () => {
cy.get('@languages')
.should('have.length', 28)
languages.forEach(language => {
cy.get('@languages').contains(language)
cy.get('@languages')
.contains(language)
})
})

View file

@ -64,14 +64,16 @@ describe('Links Intro', () => {
describe('Menu Buttons logged in', () => {
it('New note', () => {
cy.get('.d-inline-flex.btn-primary').click()
cy.get('.d-inline-flex.btn-primary')
.click()
cy.url()
.should('include', '/new')
})
describe('User Menu', () => {
beforeEach(() => {
cy.get('#dropdown-user').click()
cy.get('#dropdown-user')
.click()
})
it('Features', () => {

View file

@ -12,7 +12,7 @@ describe('profile page', () => {
}, {
body: [
{
label: "cypress-App",
label: 'cypress-App',
created: 1601991518
}
]

View file

@ -21,7 +21,7 @@ describe('Toolbar Buttons', () => {
beforeEach(() => {
cy.codemirrorFill(testText)
cy.get('.CodeMirror-line > span')
.should("exist")
.should('exist')
.should('have.text', testText)
})
@ -184,7 +184,7 @@ describe('Toolbar Buttons', () => {
beforeEach(() => {
cy.codemirrorFill(testLink)
cy.get('.CodeMirror-line > span')
.should("exist")
.should('exist')
.should('have.text', testLink)
cy.get('@codeinput')
.type('{ctrl}a')

View file

@ -16,6 +16,7 @@ declare namespace Cypress {
}
Cypress.Commands.add('checkExternalLink', { prevSubject: 'element' }, ($element: JQuery, url: string) => {
cy.wrap($element).should('have.attr', 'href', url)
cy.wrap($element)
.should('have.attr', 'href', url)
.should('have.attr', 'target', '_blank')
})

View file

@ -50,9 +50,9 @@ beforeEach(() => {
sourceCodeUrl: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
issueTrackerUrl: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'
},
"iframeCommunication": {
"editorOrigin": "http://127.0.0.1:3001",
"rendererOrigin": "http://127.0.0.1:3001"
'iframeCommunication': {
'editorOrigin': 'http://127.0.0.1:3001',
'rendererOrigin': 'http://127.0.0.1:3001'
}
}
})

View file

@ -12,6 +12,7 @@ declare namespace Cypress {
* @example cy.get(input).fill('content')
*/
fill(value: string): Chainable<Element>
codemirrorFill(value: string): Chainable<Element>
}
}
@ -25,7 +26,8 @@ Cypress.Commands.add('fill', {
})
Cypress.Commands.add('codemirrorFill', (content: string) => {
const line = content.split("\n").find(value => value !== '');
const line = content.split('\n')
.find(value => value !== '')
cy.get('.CodeMirror')
.click()
.get('textarea')

View file

@ -16,6 +16,8 @@ declare namespace Cypress {
}
Cypress.Commands.add('logout', () => {
cy.get('#dropdown-user').click()
cy.get('.fa-sign-out').click()
cy.get('#dropdown-user')
.click()
cy.get('.fa-sign-out')
.click()
})

View file

@ -18,16 +18,16 @@ Cypress.Commands.add('visitTestEditor', (query?: string) => {
beforeEach(() => {
cy.intercept(`/api/v2/notes/${ testNoteId }-get`, {
"id": "ABC123",
"alias": "banner",
"lastChange": {
"userId": "test",
"timestamp": 1600033920
'id': 'ABC123',
'alias': 'banner',
'lastChange': {
'userId': 'test',
'timestamp': 1600033920
},
"viewCount": 0,
"createTime": 1600033920,
"content": "",
"authorship": [],
"preVersionTwoNote": true
'viewCount': 0,
'createTime': 1600033920,
'content': '',
'authorship': [],
'preVersionTwoNote': true
})
})

View file

@ -3,8 +3,15 @@
"strict": true,
"baseUrl": "../node_modules",
"target": "es6",
"lib": ["es6", "dom"],
"types": ["cypress" ,"cypress-commands", "cypress-file-upload"]
"lib": [
"es6",
"dom"
],
"types": [
"cypress",
"cypress-commands",
"cypress-file-upload"
]
},
"include": [
"**/*.ts"

View file

@ -6,32 +6,72 @@
.loader {
@keyframes animation-roll {
0% { transform: translateX(calc(-100vw / 2 - 100%)) rotateZ(0deg); }
100% { transform: translateX(calc(100vw / 2 + 100%)) rotateZ(720deg); }
0% {
transform: translateX(calc(-100vw / 2 - 100%)) rotateZ(0deg);
}
100% {
transform: translateX(calc(100vw / 2 + 100%)) rotateZ(720deg);
}
}
@keyframes animation-jump {
0% { transform: scale(1,1) translateY(0); }
10% { transform: scale(1.1,.9) translateY(0); }
30% { transform: scale(.9,1.1) translateY(-100px); }
50% { transform: scale(1.05,.95) translateY(0); }
57% { transform: scale(1,1) translateY(-7px); }
64% { transform: scale(1,1) translateY(0); }
100% { transform: scale(1,1) translateY(0); }
0% {
transform: scale(1, 1) translateY(0);
}
10% {
transform: scale(1.1, .9) translateY(0);
}
30% {
transform: scale(.9, 1.1) translateY(-100px);
}
50% {
transform: scale(1.05, .95) translateY(0);
}
57% {
transform: scale(1, 1) translateY(-7px);
}
64% {
transform: scale(1, 1) translateY(0);
}
100% {
transform: scale(1, 1) translateY(0);
}
}
@keyframes animation-shake {
0% { transform: translate(1px, 1px) rotate(0deg); }
10% { transform: translate(-1px, -2px) rotate(-1deg); }
20% { transform: translate(-3px, 0px) rotate(1deg); }
30% { transform: translate(3px, 2px) rotate(0deg); }
40% { transform: translate(1px, -1px) rotate(1deg); }
50% { transform: translate(-1px, 2px) rotate(-1deg); }
60% { transform: translate(-3px, 1px) rotate(0deg); }
70% { transform: translate(3px, 1px) rotate(-1deg); }
80% { transform: translate(-1px, -1px) rotate(1deg); }
90% { transform: translate(1px, 2px) rotate(0deg); }
100% { transform: translate(1px, -2px) rotate(-1deg); }
0% {
transform: translate(1px, 1px) rotate(0deg);
}
10% {
transform: translate(-1px, -2px) rotate(-1deg);
}
20% {
transform: translate(-3px, 0px) rotate(1deg);
}
30% {
transform: translate(3px, 2px) rotate(0deg);
}
40% {
transform: translate(1px, -1px) rotate(1deg);
}
50% {
transform: translate(-1px, 2px) rotate(-1deg);
}
60% {
transform: translate(-3px, 1px) rotate(0deg);
}
70% {
transform: translate(3px, 1px) rotate(-1deg);
}
80% {
transform: translate(-1px, -1px) rotate(1deg);
}
90% {
transform: translate(1px, 2px) rotate(0deg);
}
100% {
transform: translate(1px, -2px) rotate(-1deg);
}
}
.animation-roll {

View file

@ -30,7 +30,8 @@ export const ApplicationLoader: React.FC = ({ children }) => {
useEffect(() => {
for (const task of initTasks) {
runTask(task.task).catch((reason: Error) => {
runTask(task.task)
.catch((reason: Error) => {
console.error(reason)
setFailedTitle(task.name)
})

View file

@ -16,68 +16,88 @@ describe('Test caching functionality', () => {
it('initialize with right lifetime, no entry limit', () => {
const lifetime = 1000
const lifetimedCache = new Cache<string, string>(lifetime)
expect(lifetimedCache.entryLifetime).toEqual(lifetime)
expect(lifetimedCache.maxEntries).toEqual(0)
expect(lifetimedCache.entryLifetime)
.toEqual(lifetime)
expect(lifetimedCache.maxEntries)
.toEqual(0)
})
it('initialize with right lifetime, given entry limit', () => {
const lifetime = 1000
const maxEntries = 10
const limitedCache = new Cache<string, string>(lifetime, maxEntries)
expect(limitedCache.entryLifetime).toEqual(lifetime)
expect(limitedCache.maxEntries).toEqual(maxEntries)
expect(limitedCache.entryLifetime)
.toEqual(lifetime)
expect(limitedCache.maxEntries)
.toEqual(maxEntries)
})
it('entry exists after inserting', () => {
testCache.put('test', 123)
expect(testCache.has('test')).toBe(true)
expect(testCache.has('test'))
.toBe(true)
})
it('entry does not exist prior inserting', () => {
expect(testCache.has('test')).toBe(false)
expect(testCache.has('test'))
.toBe(false)
})
it('entry does expire', () => {
const shortLivingCache = new Cache<string, number>(2)
shortLivingCache.put('test', 123)
expect(shortLivingCache.has('test')).toBe(true)
expect(shortLivingCache.has('test'))
.toBe(true)
setTimeout(() => {
expect(shortLivingCache.has('test')).toBe(false)
expect(shortLivingCache.has('test'))
.toBe(false)
}, 2000)
})
it('entry value does not change', () => {
const testValue = Date.now()
testCache.put('test', testValue)
expect(testCache.get('test')).toEqual(testValue)
expect(testCache.get('test'))
.toEqual(testValue)
})
it('error is thrown on non-existent entry', () => {
const accessNonExistentEntry = () => {
testCache.get('test')
}
expect(accessNonExistentEntry).toThrow(Error)
expect(accessNonExistentEntry)
.toThrow(Error)
})
it('newer item replaces older item', () => {
testCache.put('test', 123)
testCache.put('test', 456)
expect(testCache.get('test')).toEqual(456)
expect(testCache.get('test'))
.toEqual(456)
})
it('entry limit is respected', () => {
const limitedCache = new Cache<string, number>(1000, 2)
limitedCache.put('first', 1)
expect(limitedCache.has('first')).toBe(true)
expect(limitedCache.has('second')).toBe(false)
expect(limitedCache.has('third')).toBe(false)
expect(limitedCache.has('first'))
.toBe(true)
expect(limitedCache.has('second'))
.toBe(false)
expect(limitedCache.has('third'))
.toBe(false)
limitedCache.put('second', 2)
expect(limitedCache.has('first')).toBe(true)
expect(limitedCache.has('second')).toBe(true)
expect(limitedCache.has('third')).toBe(false)
expect(limitedCache.has('first'))
.toBe(true)
expect(limitedCache.has('second'))
.toBe(true)
expect(limitedCache.has('third'))
.toBe(false)
limitedCache.put('third', 3)
expect(limitedCache.has('first')).toBe(false)
expect(limitedCache.has('second')).toBe(true)
expect(limitedCache.has('third')).toBe(true)
expect(limitedCache.has('first'))
.toBe(false)
expect(limitedCache.has('second'))
.toBe(true)
expect(limitedCache.has('third'))
.toBe(true)
})
})

View file

@ -10,10 +10,9 @@ export interface CacheEntry<T> {
}
export class Cache<K, V> {
private store = new Map<K, CacheEntry<V>>()
readonly entryLifetime: number
readonly maxEntries: number
private store = new Map<K, CacheEntry<V>>()
constructor(lifetime: number, maxEntries = 0) {
if (lifetime < 0) {
@ -41,7 +40,8 @@ export class Cache<K, V> {
put(key: K, value: V): void {
if (this.maxEntries > 0 && this.store.size === this.maxEntries) {
this.store.delete(this.store.keys().next().value)
this.store.delete(this.store.keys()
.next().value)
}
this.store.set(key, {
entryCreated: Date.now(),

View file

@ -22,14 +22,19 @@ export const CopyOverlay: React.FC<CopyOverlayProps> = ({ content, clickComponen
const [tooltipId] = useState<string>(() => uuid())
const copyToClipboard = useCallback((content: string) => {
navigator.clipboard.writeText(content).then(() => {
navigator.clipboard.writeText(content)
.then(() => {
setError(false)
}).catch(() => {
})
.catch(() => {
setError(true)
console.error("couldn't copy")
}).finally(() => {
console.error('couldn\'t copy')
})
.finally(() => {
setShowCopiedTooltip(true)
setTimeout(() => { setShowCopiedTooltip(false) }, 2000)
setTimeout(() => {
setShowCopiedTooltip(false)
}, 2000)
})
}, [])

View file

@ -15,7 +15,7 @@ export interface CopyToClipboardButtonProps {
content: string
size?: 'sm' | 'lg'
variant?: Variant
"data-cy"?: string
'data-cy'?: string
}
export const CopyToClipboardButton: React.FC<CopyToClipboardButtonProps> = ({
@ -30,7 +30,7 @@ export const CopyToClipboardButton: React.FC<CopyToClipboardButtonProps> = ({
return (
<Fragment>
<Button ref={ button } size={ size } variant={ variant } title={ t('renderer.highlightCode.copyCode') }
data-cy={props["data-cy"]}>
data-cy={ props['data-cy'] }>
<ForkAwesomeIcon icon='files-o'/>
</Button>
<CopyOverlay content={ content } clickComponent={ button }/>

View file

@ -25,7 +25,8 @@ export const CopyableField: React.FC<CopyableFieldProps> = ({ content, nativeSha
navigator.share({
text: content,
url: url
}).catch(err => {
})
.catch(err => {
console.error('Native sharing failed: ', err)
})
}, [content, url])

File diff suppressed because one or more lines are too long

View file

@ -1 +1,29 @@
<svg clip-rule="evenodd" fill-rule="evenodd" height="1486" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 1486 1486" width="1486" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientTransform="matrix(200 -420 420 200 660 1340)" gradientUnits="userSpaceOnUse" x1="0" x2="1" y1="0" y2="0"><stop offset="0" stop-color="#fcca8c"/><stop offset="1" stop-color="#dca055"/></linearGradient><g fill-rule="nonzero" transform="translate(-142.756 -142.754)"><path d="m1553.66 961.083 75.25-75.258-75.25-75.246 56.61-90.096-90.1-56.616 35.15-100.446-100.44-35.142 11.91-105.746-105.74-11.912-11.92-105.75-105.74 11.912-35.15-100.445-100.43 35.145-56.63-90.1-90.107 56.617-75.242-75.246-75.242 75.25-90.104-56.612-56.612 90.096-100.442-35.15-35.142 100.441-105.75-11.916-11.912 105.741-105.742 11.913 11.917 105.741-100.454 35.15 35.145 100.438-90.1 56.612 56.621 90.117-75.258 75.25 75.25 75.258-56.613 90.107 90.1 56.61-35.145 100.44 100.45 35.15-11.913 105.73 105.742 11.92 11.912 105.74 105.75-11.91 35.142 100.43 100.437-35.13 56.617 90.1 90.096-56.62 75.25 74.55 75.25-74.53 90.099 56.61 56.61-90.11 100.45 35.15 35.14-100.44 105.75 11.91 11.91-105.75 105.75-11.91-11.92-105.74 100.45-35.15-35.15-100.45 90.1-56.61z" fill="#b51f08"/><path d="m1401.3 1004.78c0-145.437-117.9-263.341-263.34-263.341-72.24 0-137.68 29.112-185.252 76.225l-.033-.034-67.096 67.1-54.862-54.862c-48.267-55.067-119.071-89.879-198.042-89.879-145.442 0-263.342 117.904-263.342 263.341 0 76 32.23 144.43 83.721 192.49l432.779 432.55 423.217-423.49c52.88-49.77 92.25-120 92.25-200.1" fill="#fcca8c"/><path d="m885.579 884.73-54.862-54.862c-48.267-55.067-119.071-89.879-198.042-89.879-145.442 0-263.342 117.904-263.342 263.341 0 76 32.23 144.43 83.721 192.49l432.779 432.55" fill="url(#a)"/></g><path d="m743.077 1485.616-.254-743.64" fill="none"/><g fill-rule="nonzero" transform="translate(-142.756 -142.754)"><path d="m961.011 1553.59c-19.279-19.35-45.917-31.31-75.325-31.31-29.417 0-56.046 11.96-75.329 31.31.308 41.34 33.908 74.76 75.325 74.76 41.416 0 75.02-33.43 75.329-74.76" fill="#010007"/><path d="m797.707 1098.22c0 31.8-25.767 57.57-57.571 57.57-31.787 0-57.558-25.77-57.558-57.57s25.771-57.57 57.558-57.57c31.804 0 57.571 25.77 57.571 57.57" fill="#010007"/><path d="m777.962 1089.59c0 8.82-7.146 15.94-15.95 15.94-8.808 0-15.958-7.12-15.958-15.94 0-8.81 7.15-15.96 15.958-15.96 8.804 0 15.95 7.15 15.95 15.96" fill="#fffffa"/><path d="m1089.65 1098.22c0 31.8-25.77 57.57-57.57 57.57-31.79 0-57.567-25.77-57.567-57.57s25.777-57.57 57.567-57.57c31.8 0 57.57 25.77 57.57 57.57" fill="#010007"/><path d="m1069.9 1089.59c0 8.82-7.15 15.94-15.95 15.94-8.81 0-15.96-7.12-15.96-15.94 0-8.81 7.15-15.96 15.96-15.96 8.8 0 15.95 7.15 15.95 15.96" fill="#fffffa"/></g></svg>
<svg clip-rule="evenodd" fill-rule="evenodd" height="1486" stroke-linejoin="round" stroke-miterlimit="2"
viewBox="0 0 1486 1486" width="1486" xmlns="http://www.w3.org/2000/svg">
<linearGradient id="a" gradientTransform="matrix(200 -420 420 200 660 1340)" gradientUnits="userSpaceOnUse" x1="0"
x2="1" y1="0" y2="0">
<stop offset="0" stop-color="#fcca8c"/>
<stop offset="1" stop-color="#dca055"/>
</linearGradient>
<g fill-rule="nonzero" transform="translate(-142.756 -142.754)">
<path d="m1553.66 961.083 75.25-75.258-75.25-75.246 56.61-90.096-90.1-56.616 35.15-100.446-100.44-35.142 11.91-105.746-105.74-11.912-11.92-105.75-105.74 11.912-35.15-100.445-100.43 35.145-56.63-90.1-90.107 56.617-75.242-75.246-75.242 75.25-90.104-56.612-56.612 90.096-100.442-35.15-35.142 100.441-105.75-11.916-11.912 105.741-105.742 11.913 11.917 105.741-100.454 35.15 35.145 100.438-90.1 56.612 56.621 90.117-75.258 75.25 75.25 75.258-56.613 90.107 90.1 56.61-35.145 100.44 100.45 35.15-11.913 105.73 105.742 11.92 11.912 105.74 105.75-11.91 35.142 100.43 100.437-35.13 56.617 90.1 90.096-56.62 75.25 74.55 75.25-74.53 90.099 56.61 56.61-90.11 100.45 35.15 35.14-100.44 105.75 11.91 11.91-105.75 105.75-11.91-11.92-105.74 100.45-35.15-35.15-100.45 90.1-56.61z"
fill="#b51f08"/>
<path d="m1401.3 1004.78c0-145.437-117.9-263.341-263.34-263.341-72.24 0-137.68 29.112-185.252 76.225l-.033-.034-67.096 67.1-54.862-54.862c-48.267-55.067-119.071-89.879-198.042-89.879-145.442 0-263.342 117.904-263.342 263.341 0 76 32.23 144.43 83.721 192.49l432.779 432.55 423.217-423.49c52.88-49.77 92.25-120 92.25-200.1"
fill="#fcca8c"/>
<path d="m885.579 884.73-54.862-54.862c-48.267-55.067-119.071-89.879-198.042-89.879-145.442 0-263.342 117.904-263.342 263.341 0 76 32.23 144.43 83.721 192.49l432.779 432.55"
fill="url(#a)"/>
</g>
<path d="m743.077 1485.616-.254-743.64" fill="none"/>
<g fill-rule="nonzero" transform="translate(-142.756 -142.754)">
<path d="m961.011 1553.59c-19.279-19.35-45.917-31.31-75.325-31.31-29.417 0-56.046 11.96-75.329 31.31.308 41.34 33.908 74.76 75.325 74.76 41.416 0 75.02-33.43 75.329-74.76"
fill="#010007"/>
<path d="m797.707 1098.22c0 31.8-25.767 57.57-57.571 57.57-31.787 0-57.558-25.77-57.558-57.57s25.771-57.57 57.558-57.57c31.804 0 57.571 25.77 57.571 57.57"
fill="#010007"/>
<path d="m777.962 1089.59c0 8.82-7.146 15.94-15.95 15.94-8.808 0-15.958-7.12-15.958-15.94 0-8.81 7.15-15.96 15.958-15.96 8.804 0 15.95 7.15 15.95 15.96"
fill="#fffffa"/>
<path d="m1089.65 1098.22c0 31.8-25.77 57.57-57.57 57.57-31.79 0-57.567-25.77-57.567-57.57s25.777-57.57 57.567-57.57c31.8 0 57.57 25.77 57.57 57.57"
fill="#010007"/>
<path d="m1069.9 1089.59c0 8.82-7.15 15.94-15.95 15.94-8.81 0-15.96-7.12-15.96-15.94 0-8.81 7.15-15.96 15.96-15.96 8.8 0 15.95 7.15 15.95 15.96"
fill="#fffffa"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 3 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

View file

@ -3,7 +3,7 @@ SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
SPDX-License-Identifier: AGPL-3.0-only
*/
import hljs from 'highlight.js/lib/core';
import hljs from 'highlight.js/lib/core'
import abnf from 'highlight.js/lib/languages/abnf'
import accesslog from 'highlight.js/lib/languages/accesslog'
import actionscript from 'highlight.js/lib/languages/actionscript'
@ -194,196 +194,196 @@ import xl from 'highlight.js/lib/languages/xl'
import xquery from 'highlight.js/lib/languages/xquery'
import zephir from 'highlight.js/lib/languages/zephir'
hljs.registerLanguage('abnf', abnf);
hljs.registerLanguage('accesslog', accesslog);
hljs.registerLanguage('actionscript', actionscript);
hljs.registerLanguage('ada', ada);
hljs.registerLanguage('angelscript', angelscript);
hljs.registerLanguage('apache', apache);
hljs.registerLanguage('applescript', applescript);
hljs.registerLanguage('arcade', arcade);
hljs.registerLanguage('arduino', arduino);
hljs.registerLanguage('armasm', armasm);
hljs.registerLanguage('xml', xml);
hljs.registerLanguage('asciidoc', asciidoc);
hljs.registerLanguage('aspectj', aspectj);
hljs.registerLanguage('autohotkey', autohotkey);
hljs.registerLanguage('autoit', autoit);
hljs.registerLanguage('avrasm', avrasm);
hljs.registerLanguage('awk', awk);
hljs.registerLanguage('axapta', axapta);
hljs.registerLanguage('bash', bash);
hljs.registerLanguage('basic', basic);
hljs.registerLanguage('bnf', bnf);
hljs.registerLanguage('brainfuck', brainfuck);
hljs.registerLanguage('c-like', c_like);
hljs.registerLanguage('c', c);
hljs.registerLanguage('cal', cal);
hljs.registerLanguage('capnproto', capnproto);
hljs.registerLanguage('ceylon', ceylon);
hljs.registerLanguage('clean', clean);
hljs.registerLanguage('clojure', clojure);
hljs.registerLanguage('clojure-repl', clojure_repl);
hljs.registerLanguage('cmake', cmake);
hljs.registerLanguage('coffeescript', coffeescript);
hljs.registerLanguage('coq', coq);
hljs.registerLanguage('cos', cos);
hljs.registerLanguage('cpp', cpp);
hljs.registerLanguage('crmsh', crmsh);
hljs.registerLanguage('crystal', crystal);
hljs.registerLanguage('csharp', csharp);
hljs.registerLanguage('csp', csp);
hljs.registerLanguage('css', css);
hljs.registerLanguage('d', d);
hljs.registerLanguage('markdown', markdown);
hljs.registerLanguage('dart', dart);
hljs.registerLanguage('delphi', delphi);
hljs.registerLanguage('diff', diff);
hljs.registerLanguage('django', django);
hljs.registerLanguage('dns', dns);
hljs.registerLanguage('dockerfile', dockerfile);
hljs.registerLanguage('dos', dos);
hljs.registerLanguage('dsconfig', dsconfig);
hljs.registerLanguage('dts', dts);
hljs.registerLanguage('dust', dust);
hljs.registerLanguage('ebnf', ebnf);
hljs.registerLanguage('elixir', elixir);
hljs.registerLanguage('elm', elm);
hljs.registerLanguage('ruby', ruby);
hljs.registerLanguage('erb', erb);
hljs.registerLanguage('erlang-repl', erlang_repl);
hljs.registerLanguage('erlang', erlang);
hljs.registerLanguage('excel', excel);
hljs.registerLanguage('fix', fix);
hljs.registerLanguage('flix', flix);
hljs.registerLanguage('fortran', fortran);
hljs.registerLanguage('fsharp', fsharp);
hljs.registerLanguage('gams', gams);
hljs.registerLanguage('gauss', gauss);
hljs.registerLanguage('gcode', gcode);
hljs.registerLanguage('gherkin', gherkin);
hljs.registerLanguage('glsl', glsl);
hljs.registerLanguage('gml', gml);
hljs.registerLanguage('go', go);
hljs.registerLanguage('golo', golo);
hljs.registerLanguage('gradle', gradle);
hljs.registerLanguage('groovy', groovy);
hljs.registerLanguage('haml', haml);
hljs.registerLanguage('handlebars', handlebars);
hljs.registerLanguage('haskell', haskell);
hljs.registerLanguage('haxe', haxe);
hljs.registerLanguage('hsp', hsp);
hljs.registerLanguage('html', xml);
hljs.registerLanguage('htmlbars', htmlbars);
hljs.registerLanguage('http', http);
hljs.registerLanguage('hy', hy);
hljs.registerLanguage('inform7', inform7);
hljs.registerLanguage('ini', ini);
hljs.registerLanguage('irpf90', irpf90);
hljs.registerLanguage('isbl', isbl);
hljs.registerLanguage('java', java);
hljs.registerLanguage('javascript', javascript);
hljs.registerLanguage('jboss-cli', jboss_cli);
hljs.registerLanguage('js', javascript);
hljs.registerLanguage('json', json);
hljs.registerLanguage('julia', julia);
hljs.registerLanguage('julia-repl', julia_repl);
hljs.registerLanguage('kotlin', kotlin);
hljs.registerLanguage('lasso', lasso);
hljs.registerLanguage('latex', latex);
hljs.registerLanguage('ldif', ldif);
hljs.registerLanguage('leaf', leaf);
hljs.registerLanguage('less', less);
hljs.registerLanguage('lisp', lisp);
hljs.registerLanguage('livecodeserver', livecodeserver);
hljs.registerLanguage('livescript', livescript);
hljs.registerLanguage('llvm', llvm);
hljs.registerLanguage('lsl', lsl);
hljs.registerLanguage('lua', lua);
hljs.registerLanguage('makefile', makefile);
hljs.registerLanguage('mathematica', mathematica);
hljs.registerLanguage('matlab', matlab);
hljs.registerLanguage('maxima', maxima);
hljs.registerLanguage('mel', mel);
hljs.registerLanguage('mercury', mercury);
hljs.registerLanguage('mipsasm', mipsasm);
hljs.registerLanguage('mizar', mizar);
hljs.registerLanguage('perl', perl);
hljs.registerLanguage('mojolicious', mojolicious);
hljs.registerLanguage('monkey', monkey);
hljs.registerLanguage('moonscript', moonscript);
hljs.registerLanguage('n1ql', n1ql);
hljs.registerLanguage('nginx', nginx);
hljs.registerLanguage('nim', nim);
hljs.registerLanguage('nix', nix);
hljs.registerLanguage('node-repl', node_repl);
hljs.registerLanguage('nsis', nsis);
hljs.registerLanguage('objectivec', objectivec);
hljs.registerLanguage('ocaml', ocaml);
hljs.registerLanguage('openscad', openscad);
hljs.registerLanguage('oxygene', oxygene);
hljs.registerLanguage('parser3', parser3);
hljs.registerLanguage('pf', pf);
hljs.registerLanguage('pgsql', pgsql);
hljs.registerLanguage('php', php);
hljs.registerLanguage('php-template', php_template);
hljs.registerLanguage('plaintext', plaintext);
hljs.registerLanguage('pony', pony);
hljs.registerLanguage('powershell', powershell);
hljs.registerLanguage('processing', processing);
hljs.registerLanguage('profile', profile);
hljs.registerLanguage('prolog', prolog);
hljs.registerLanguage('properties', properties);
hljs.registerLanguage('protobuf', protobuf);
hljs.registerLanguage('puppet', puppet);
hljs.registerLanguage('purebasic', purebasic);
hljs.registerLanguage('python', python);
hljs.registerLanguage('python-repl', python_repl);
hljs.registerLanguage('q', q);
hljs.registerLanguage('qml', qml);
hljs.registerLanguage('r', r);
hljs.registerLanguage('reasonml', reasonml);
hljs.registerLanguage('rib', rib);
hljs.registerLanguage('roboconf', roboconf);
hljs.registerLanguage('routeros', routeros);
hljs.registerLanguage('rsl', rsl);
hljs.registerLanguage('ruleslanguage', ruleslanguage);
hljs.registerLanguage('rust', rust);
hljs.registerLanguage('sas', sas);
hljs.registerLanguage('scala', scala);
hljs.registerLanguage('scheme', scheme);
hljs.registerLanguage('scilab', scilab);
hljs.registerLanguage('scss', scss);
hljs.registerLanguage('shell', shell);
hljs.registerLanguage('smali', smali);
hljs.registerLanguage('smalltalk', smalltalk);
hljs.registerLanguage('sml', sml);
hljs.registerLanguage('sqf', sqf);
hljs.registerLanguage('sql', sql);
hljs.registerLanguage('stan', stan);
hljs.registerLanguage('stata', stata);
hljs.registerLanguage('step21', step21);
hljs.registerLanguage('stylus', stylus);
hljs.registerLanguage('subunit', subunit);
hljs.registerLanguage('swift', swift);
hljs.registerLanguage('taggerscript', taggerscript);
hljs.registerLanguage('yaml', yaml);
hljs.registerLanguage('tap', tap);
hljs.registerLanguage('tcl', tcl);
hljs.registerLanguage('thrift', thrift);
hljs.registerLanguage('tp', tp);
hljs.registerLanguage('twig', twig);
hljs.registerLanguage('typescript', typescript);
hljs.registerLanguage('vala', vala);
hljs.registerLanguage('vbnet', vbnet);
hljs.registerLanguage('vbscript', vbscript);
hljs.registerLanguage('vbscript-html', vbscript_html);
hljs.registerLanguage('verilog', verilog);
hljs.registerLanguage('vhdl', vhdl);
hljs.registerLanguage('vim', vim);
hljs.registerLanguage('x86asm', x86asm);
hljs.registerLanguage('xl', xl);
hljs.registerLanguage('xquery', xquery);
hljs.registerLanguage('zephir', zephir);
hljs.registerLanguage('abnf', abnf)
hljs.registerLanguage('accesslog', accesslog)
hljs.registerLanguage('actionscript', actionscript)
hljs.registerLanguage('ada', ada)
hljs.registerLanguage('angelscript', angelscript)
hljs.registerLanguage('apache', apache)
hljs.registerLanguage('applescript', applescript)
hljs.registerLanguage('arcade', arcade)
hljs.registerLanguage('arduino', arduino)
hljs.registerLanguage('armasm', armasm)
hljs.registerLanguage('xml', xml)
hljs.registerLanguage('asciidoc', asciidoc)
hljs.registerLanguage('aspectj', aspectj)
hljs.registerLanguage('autohotkey', autohotkey)
hljs.registerLanguage('autoit', autoit)
hljs.registerLanguage('avrasm', avrasm)
hljs.registerLanguage('awk', awk)
hljs.registerLanguage('axapta', axapta)
hljs.registerLanguage('bash', bash)
hljs.registerLanguage('basic', basic)
hljs.registerLanguage('bnf', bnf)
hljs.registerLanguage('brainfuck', brainfuck)
hljs.registerLanguage('c-like', c_like)
hljs.registerLanguage('c', c)
hljs.registerLanguage('cal', cal)
hljs.registerLanguage('capnproto', capnproto)
hljs.registerLanguage('ceylon', ceylon)
hljs.registerLanguage('clean', clean)
hljs.registerLanguage('clojure', clojure)
hljs.registerLanguage('clojure-repl', clojure_repl)
hljs.registerLanguage('cmake', cmake)
hljs.registerLanguage('coffeescript', coffeescript)
hljs.registerLanguage('coq', coq)
hljs.registerLanguage('cos', cos)
hljs.registerLanguage('cpp', cpp)
hljs.registerLanguage('crmsh', crmsh)
hljs.registerLanguage('crystal', crystal)
hljs.registerLanguage('csharp', csharp)
hljs.registerLanguage('csp', csp)
hljs.registerLanguage('css', css)
hljs.registerLanguage('d', d)
hljs.registerLanguage('markdown', markdown)
hljs.registerLanguage('dart', dart)
hljs.registerLanguage('delphi', delphi)
hljs.registerLanguage('diff', diff)
hljs.registerLanguage('django', django)
hljs.registerLanguage('dns', dns)
hljs.registerLanguage('dockerfile', dockerfile)
hljs.registerLanguage('dos', dos)
hljs.registerLanguage('dsconfig', dsconfig)
hljs.registerLanguage('dts', dts)
hljs.registerLanguage('dust', dust)
hljs.registerLanguage('ebnf', ebnf)
hljs.registerLanguage('elixir', elixir)
hljs.registerLanguage('elm', elm)
hljs.registerLanguage('ruby', ruby)
hljs.registerLanguage('erb', erb)
hljs.registerLanguage('erlang-repl', erlang_repl)
hljs.registerLanguage('erlang', erlang)
hljs.registerLanguage('excel', excel)
hljs.registerLanguage('fix', fix)
hljs.registerLanguage('flix', flix)
hljs.registerLanguage('fortran', fortran)
hljs.registerLanguage('fsharp', fsharp)
hljs.registerLanguage('gams', gams)
hljs.registerLanguage('gauss', gauss)
hljs.registerLanguage('gcode', gcode)
hljs.registerLanguage('gherkin', gherkin)
hljs.registerLanguage('glsl', glsl)
hljs.registerLanguage('gml', gml)
hljs.registerLanguage('go', go)
hljs.registerLanguage('golo', golo)
hljs.registerLanguage('gradle', gradle)
hljs.registerLanguage('groovy', groovy)
hljs.registerLanguage('haml', haml)
hljs.registerLanguage('handlebars', handlebars)
hljs.registerLanguage('haskell', haskell)
hljs.registerLanguage('haxe', haxe)
hljs.registerLanguage('hsp', hsp)
hljs.registerLanguage('html', xml)
hljs.registerLanguage('htmlbars', htmlbars)
hljs.registerLanguage('http', http)
hljs.registerLanguage('hy', hy)
hljs.registerLanguage('inform7', inform7)
hljs.registerLanguage('ini', ini)
hljs.registerLanguage('irpf90', irpf90)
hljs.registerLanguage('isbl', isbl)
hljs.registerLanguage('java', java)
hljs.registerLanguage('javascript', javascript)
hljs.registerLanguage('jboss-cli', jboss_cli)
hljs.registerLanguage('js', javascript)
hljs.registerLanguage('json', json)
hljs.registerLanguage('julia', julia)
hljs.registerLanguage('julia-repl', julia_repl)
hljs.registerLanguage('kotlin', kotlin)
hljs.registerLanguage('lasso', lasso)
hljs.registerLanguage('latex', latex)
hljs.registerLanguage('ldif', ldif)
hljs.registerLanguage('leaf', leaf)
hljs.registerLanguage('less', less)
hljs.registerLanguage('lisp', lisp)
hljs.registerLanguage('livecodeserver', livecodeserver)
hljs.registerLanguage('livescript', livescript)
hljs.registerLanguage('llvm', llvm)
hljs.registerLanguage('lsl', lsl)
hljs.registerLanguage('lua', lua)
hljs.registerLanguage('makefile', makefile)
hljs.registerLanguage('mathematica', mathematica)
hljs.registerLanguage('matlab', matlab)
hljs.registerLanguage('maxima', maxima)
hljs.registerLanguage('mel', mel)
hljs.registerLanguage('mercury', mercury)
hljs.registerLanguage('mipsasm', mipsasm)
hljs.registerLanguage('mizar', mizar)
hljs.registerLanguage('perl', perl)
hljs.registerLanguage('mojolicious', mojolicious)
hljs.registerLanguage('monkey', monkey)
hljs.registerLanguage('moonscript', moonscript)
hljs.registerLanguage('n1ql', n1ql)
hljs.registerLanguage('nginx', nginx)
hljs.registerLanguage('nim', nim)
hljs.registerLanguage('nix', nix)
hljs.registerLanguage('node-repl', node_repl)
hljs.registerLanguage('nsis', nsis)
hljs.registerLanguage('objectivec', objectivec)
hljs.registerLanguage('ocaml', ocaml)
hljs.registerLanguage('openscad', openscad)
hljs.registerLanguage('oxygene', oxygene)
hljs.registerLanguage('parser3', parser3)
hljs.registerLanguage('pf', pf)
hljs.registerLanguage('pgsql', pgsql)
hljs.registerLanguage('php', php)
hljs.registerLanguage('php-template', php_template)
hljs.registerLanguage('plaintext', plaintext)
hljs.registerLanguage('pony', pony)
hljs.registerLanguage('powershell', powershell)
hljs.registerLanguage('processing', processing)
hljs.registerLanguage('profile', profile)
hljs.registerLanguage('prolog', prolog)
hljs.registerLanguage('properties', properties)
hljs.registerLanguage('protobuf', protobuf)
hljs.registerLanguage('puppet', puppet)
hljs.registerLanguage('purebasic', purebasic)
hljs.registerLanguage('python', python)
hljs.registerLanguage('python-repl', python_repl)
hljs.registerLanguage('q', q)
hljs.registerLanguage('qml', qml)
hljs.registerLanguage('r', r)
hljs.registerLanguage('reasonml', reasonml)
hljs.registerLanguage('rib', rib)
hljs.registerLanguage('roboconf', roboconf)
hljs.registerLanguage('routeros', routeros)
hljs.registerLanguage('rsl', rsl)
hljs.registerLanguage('ruleslanguage', ruleslanguage)
hljs.registerLanguage('rust', rust)
hljs.registerLanguage('sas', sas)
hljs.registerLanguage('scala', scala)
hljs.registerLanguage('scheme', scheme)
hljs.registerLanguage('scilab', scilab)
hljs.registerLanguage('scss', scss)
hljs.registerLanguage('shell', shell)
hljs.registerLanguage('smali', smali)
hljs.registerLanguage('smalltalk', smalltalk)
hljs.registerLanguage('sml', sml)
hljs.registerLanguage('sqf', sqf)
hljs.registerLanguage('sql', sql)
hljs.registerLanguage('stan', stan)
hljs.registerLanguage('stata', stata)
hljs.registerLanguage('step21', step21)
hljs.registerLanguage('stylus', stylus)
hljs.registerLanguage('subunit', subunit)
hljs.registerLanguage('swift', swift)
hljs.registerLanguage('taggerscript', taggerscript)
hljs.registerLanguage('yaml', yaml)
hljs.registerLanguage('tap', tap)
hljs.registerLanguage('tcl', tcl)
hljs.registerLanguage('thrift', thrift)
hljs.registerLanguage('tp', tp)
hljs.registerLanguage('twig', twig)
hljs.registerLanguage('typescript', typescript)
hljs.registerLanguage('vala', vala)
hljs.registerLanguage('vbnet', vbnet)
hljs.registerLanguage('vbscript', vbscript)
hljs.registerLanguage('vbscript-html', vbscript_html)
hljs.registerLanguage('verilog', verilog)
hljs.registerLanguage('vhdl', vhdl)
hljs.registerLanguage('vim', vim)
hljs.registerLanguage('x86asm', x86asm)
hljs.registerLanguage('xl', xl)
hljs.registerLanguage('xquery', xquery)
hljs.registerLanguage('zephir', zephir)
export default hljs;
export default hljs

View file

@ -19,7 +19,8 @@ export interface IconButtonProps extends ButtonProps {
export const IconButton: React.FC<IconButtonProps> = ({ icon, children, border = false, ...props }) => {
return (
<Button {...props} className={`btn-icon p-0 d-inline-flex align-items-stretch ${border ? 'with-border' : ''}`}>
<Button { ...props }
className={ `btn-icon p-0 d-inline-flex align-items-stretch ${ border ? 'with-border' : '' }` }>
<span className="icon-part d-flex align-items-center">
<ForkAwesomeIcon icon={ icon } className={ 'icon' }/>
</span>

View file

@ -26,7 +26,8 @@ export const CommonModal: React.FC<CommonModalProps> = ({ show, onHide, titleI18
useTranslation()
return (
<Modal data-cy={'limitReachedModal'} show={show} onHide={onHide} animation={true} dialogClassName={`text-dark ${additionalClasses ?? ''}`} size={size}>
<Modal data-cy={ 'limitReachedModal' } show={ show } onHide={ onHide } animation={ true }
dialogClassName={ `text-dark ${ additionalClasses ?? '' }` } size={ size }>
<Modal.Header closeButton={ !!closeButton }>
<Modal.Title>
<ShowIf condition={ !!icon }>

View file

@ -5,5 +5,6 @@
*/
export const createNumberRangeArray = (length: number): number[] => {
return Array.from(Array(length).keys())
return Array.from(Array(length)
.keys())
}

View file

@ -53,12 +53,15 @@ export const PagerPagination: React.FC<PaginationProps> = ({ numberOfPageButtons
0
)
const paginationItemsBefore = Array.from(new Array(correctedPageIndex - correctedLowerPageIndex)).map((k, index) => {
const paginationItemsBefore = Array.from(new Array(correctedPageIndex - correctedLowerPageIndex))
.map((k, index) => {
const itemIndex = correctedLowerPageIndex + index
return <PagerItem key={itemIndex} index={itemIndex} onClick={setPageIndex}/>
return <PagerItem key={ itemIndex } index={ itemIndex }
onClick={ setPageIndex }/>
})
const paginationItemsAfter = Array.from(new Array(correctedUpperPageIndex - correctedPageIndex)).map((k, index) => {
const paginationItemsAfter = Array.from(new Array(correctedUpperPageIndex - correctedPageIndex))
.map((k, index) => {
const itemIndex = correctedPageIndex + index + 1
return <PagerItem key={ itemIndex } index={ itemIndex } onClick={ setPageIndex }/>
})

View file

@ -22,7 +22,8 @@ export const Pager: React.FC<PagerPageProps> = ({ children, numberOfElementsPerP
return <Fragment>
{
React.Children.toArray(children).filter((value, index) => {
React.Children.toArray(children)
.filter((value, index) => {
const pageOfElement = Math.floor((index) / numberOfElementsPerPage)
return (pageOfElement === correctedPageIndex)
})

View file

@ -56,7 +56,9 @@ export const DocumentInfobar: React.FC<DocumentInfobarProps> = ({
<span className={ 'ml-auto' }>
{ viewCount } <Trans i18nKey={ 'views.readOnly.viewCount' }/>
<ShowIf condition={ editable }>
<InternalLink text={''} href={`/n/${noteId}`} icon={'pencil'} className={'text-primary text-decoration-none mx-1'} title={t('views.readOnly.editNote')}/>
<InternalLink text={ '' } href={ `/n/${ noteId }` } icon={ 'pencil' }
className={ 'text-primary text-decoration-none mx-1' }
title={ t('views.readOnly.editNote') }/>
</ShowIf>
</span>
</div>

View file

@ -55,7 +55,7 @@ export const DocumentReadOnlyPage: React.FC = () => {
noteId={ id }
viewCount={ noteDetails.viewCount }
/>
<RenderIframe extraClasses={"flex-fill"}
<RenderIframe extraClasses={ 'flex-fill' }
markdownContent={ markdownContent }
onFirstHeadingChange={ onFirstHeadingChange }
onFrontmatterChange={ onFrontmatterChange }/>

View file

@ -46,7 +46,8 @@ export const AppBar: React.FC<AppBarProps> = ({ mode }) => {
</ShowIf>
<DarkModeButton/>
<Link to={ `/p/${ id }` } target='_blank'>
<Button title={t('editor.documentBar.slideMode')} className="ml-2 text-secondary" size="sm" variant="outline-light">
<Button title={ t('editor.documentBar.slideMode') } className="ml-2 text-secondary" size="sm"
variant="outline-light">
<ForkAwesomeIcon icon="television"/>
</Button>
</Link>

View file

@ -43,22 +43,26 @@ export const HelpButton: React.FC = () => {
<Modal show={ show } onHide={ () => setShow(false) } animation={ true } className='text-dark' size='lg'>
<Modal.Header closeButton>
<Modal.Title>
<ForkAwesomeIcon icon='question-circle'/> <Trans i18nKey={'editor.documentBar.help'}/> <Trans i18nKey={`editor.help.${tab}`}/>
<ForkAwesomeIcon icon='question-circle'/> <Trans i18nKey={ 'editor.documentBar.help' }/> <Trans
i18nKey={ `editor.help.${ tab }` }/>
</Modal.Title>
</Modal.Header>
<Modal.Body>
<nav className='nav nav-tabs'>
<Button variant={'light'} className={`nav-link nav-item ${tab === HelpTabStatus.Cheatsheet ? 'active' : ''}`}
<Button variant={ 'light' }
className={ `nav-link nav-item ${ tab === HelpTabStatus.Cheatsheet ? 'active' : '' }` }
onClick={ () => setTab(HelpTabStatus.Cheatsheet) }
>
<Trans i18nKey={ 'editor.help.cheatsheet.title' }/>
</Button>
<Button variant={'light'} className={`nav-link nav-item ${tab === HelpTabStatus.Shortcuts ? 'active' : ''}`}
<Button variant={ 'light' }
className={ `nav-link nav-item ${ tab === HelpTabStatus.Shortcuts ? 'active' : '' }` }
onClick={ () => setTab(HelpTabStatus.Shortcuts) }
>
<Trans i18nKey={ 'editor.help.shortcuts.title' }/>
</Button>
<Button variant={'light'} className={`nav-link nav-item ${tab === HelpTabStatus.Links ? 'active' : ''}`}
<Button variant={ 'light' }
className={ `nav-link nav-item ${ tab === HelpTabStatus.Links ? 'active' : '' }` }
onClick={ () => setTab(HelpTabStatus.Links) }
>
<Trans i18nKey={ 'editor.help.links.title' }/>

View file

@ -30,12 +30,14 @@ export const Shortcut: React.FC = () => {
}
return (
<Row className={ 'justify-content-center pt-4' }>
{Object.keys(shortcutMap).map(category => {
{ Object.keys(shortcutMap)
.map(category => {
return (
<Card key={ category } className={ 'm-2 w-50' }>
<Card.Header>{ category }</Card.Header>
<ListGroup variant="flush">
{Object.entries(shortcutMap[category]).map(([functionName, shortcuts]) => {
{ Object.entries(shortcutMap[category])
.map(([functionName, shortcuts]) => {
return (
<ListGroup.Item key={ functionName } className={ 'd-flex justify-content-between' }>
<span><Trans i18nKey={ functionName }/></span>

View file

@ -3,9 +3,9 @@
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns="http://www.w3.org/2000/svg"
width="512"
height="512"
viewBox="0 0 135.46666 135.46666"

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

View file

@ -9,6 +9,7 @@
width: 20px;
height: 20px;
}
.btn {
svg g {
@import "../../../../style/variables.light";

View file

@ -31,7 +31,8 @@ export const DocumentInfoModal: React.FC<DocumentInfoModalProps> = ({show, onHid
<DocumentInfoTimeLine
size={ '2x' }
mode={ DocumentInfoLineWithTimeMode.CREATED }
time={DateTime.local().minus({ days: 11 })}
time={ DateTime.local()
.minus({ days: 11 }) }
userName={ 'Tilman' }
profileImageSrc={ '/img/avatar.png' }/>
</ListGroup.Item>
@ -39,7 +40,8 @@ export const DocumentInfoModal: React.FC<DocumentInfoModalProps> = ({show, onHid
<DocumentInfoTimeLine
size={ '2x' }
mode={ DocumentInfoLineWithTimeMode.EDITED }
time={DateTime.local().minus({ minutes: 3 })}
time={ DateTime.local()
.minus({ minutes: 3 }) }
userName={ 'Philip' }
profileImageSrc={ '/img/avatar.png' }/>
</ListGroup.Item>
@ -60,5 +62,5 @@ export const DocumentInfoModal: React.FC<DocumentInfoModalProps> = ({show, onHid
</ListGroup>
</Modal.Body>
</CommonModal>
);
)
}

View file

@ -34,7 +34,8 @@ export const DocumentInfoTimeLine: React.FC<DocumentInfoLineWithTimeProps> = ({
return (
<DocumentInfoLine icon={ icon } size={ size }>
<Trans i18nKey={ i18nKey }>
<UserAvatar photo={profileImageSrc} additionalClasses={'font-style-normal bold font-weight-bold'} name={userName} size={size ? 'lg' : undefined}/>
<UserAvatar photo={ profileImageSrc } additionalClasses={ 'font-style-normal bold font-weight-bold' }
name={ userName } size={ size ? 'lg' : undefined }/>
<TimeFromNow time={ time }/>
</Trans>
</DocumentInfoLine>

View file

@ -14,6 +14,7 @@ export interface TimeFromNowProps {
export const TimeFromNow: React.FC<TimeFromNowProps> = ({ time }) => {
return (
<time className={'mx-1'} title={time.toFormat('DDDD T')} dateTime={time.toString()}>{time.toRelative()}</time>
<time className={ 'mx-1' } title={ time.toFormat('DDDD T') }
dateTime={ time.toString() }>{ time.toRelative() }</time>
)
}

View file

@ -69,22 +69,26 @@ export const PermissionModal: React.FC<PermissionsModalProps> = ({ show, onHide
useEffect(() => {
// set owner
getUserById(permissionsApiResponse.owner).then(response => {
getUserById(permissionsApiResponse.owner)
.then(response => {
setOwner({
name: response.name,
photo: response.photo
})
}).catch(() => setError(true))
})
.catch(() => setError(true))
// set user List
permissionsApiResponse.sharedTo.forEach(shareUser => {
getUserById(shareUser.username).then(response => {
getUserById(shareUser.username)
.then(response => {
setUserList(list => list.concat([{
id: response.id,
name: response.name,
photo: response.photo,
canEdit: shareUser.canEdit
}]))
}).catch(() => setError(true))
})
.catch(() => setError(true))
})
// set group List
permissionsApiResponse.sharedToGroup.forEach(sharedGroup => {

View file

@ -29,7 +29,8 @@ export const RevisionModalListEntry: React.FC<RevisionModalListEntryProps> = ({
>
<span>
<ForkAwesomeIcon icon={ 'clock-o' } className='mx-2'/>
{DateTime.fromMillis(revision.timestamp * 1000).toFormat('DDDD T')}
{ DateTime.fromMillis(revision.timestamp * 1000)
.toFormat('DDDD T') }
</span>
<span>
<ForkAwesomeIcon icon={ 'file-text-o' } className='mx-2'/>
@ -38,9 +39,11 @@ export const RevisionModalListEntry: React.FC<RevisionModalListEntryProps> = ({
<span className={ 'd-flex flex-row my-1 align-items-center' }>
<ForkAwesomeIcon icon={ 'user-o' } className={ 'mx-2' }/>
{
revisionAuthorListMap.get(revision.timestamp)?.map((user, index) => {
revisionAuthorListMap.get(revision.timestamp)
?.map((user, index) => {
return (
<UserAvatar name={user.name} photo={user.photo} showName={false} additionalClasses={'mx-1'} key={index}/>
<UserAvatar name={ user.name } photo={ user.photo } showName={ false }
additionalClasses={ 'mx-1' } key={ index }/>
)
})
}

View file

@ -36,7 +36,8 @@ export const RevisionModal: React.FC<PermissionsModalProps> = ({ show, onHide })
const { id } = useParams<{ id: string }>()
useEffect(() => {
getAllRevisions(id).then(fetchedRevisions => {
getAllRevisions(id)
.then(fetchedRevisions => {
fetchedRevisions.forEach(revision => {
const authorData = getUserDataForRevision(revision.authors)
revisionAuthorListMap.current.set(revision.timestamp, authorData)
@ -45,22 +46,26 @@ export const RevisionModal: React.FC<PermissionsModalProps> = ({ show, onHide })
if (fetchedRevisions.length >= 1) {
setSelectedRevisionTimestamp(fetchedRevisions[0].timestamp)
}
}).catch(() => setError(true))
})
.catch(() => setError(true))
}, [setRevisions, setError, id])
useEffect(() => {
if (selectedRevisionTimestamp === null) {
return
}
getRevision(id, selectedRevisionTimestamp).then(fetchedRevision => {
getRevision(id, selectedRevisionTimestamp)
.then(fetchedRevision => {
setSelectedRevision(fetchedRevision)
}).catch(() => setError(true))
})
.catch(() => setError(true))
}, [selectedRevisionTimestamp, id])
const markdownContent = useNoteMarkdownContent()
return (
<CommonModal show={show} onHide={onHide} titleI18nKey={'editor.modal.revision.title'} icon={'history'} closeButton={true} size={'xl'} additionalClasses='revision-modal'>
<CommonModal show={ show } onHide={ onHide } titleI18nKey={ 'editor.modal.revision.title' } icon={ 'history' }
closeButton={ true } size={ 'xl' } additionalClasses='revision-modal'>
<Modal.Body>
<Row>
<Col lg={ 4 } className={ 'scroll-col' }>

View file

@ -41,11 +41,13 @@ export const ShareModal: React.FC<ShareModalProps> = ({ show, onHide }) => {
url={ `${ baseUrl }/n/${ id }?${ editorMode }` }/>
<ShowIf condition={ noteFrontmatter.type === 'slide' }>
<Trans i18nKey={ 'editor.modal.shareLink.slidesDescription' }/>
<CopyableField content={`${baseUrl}/p/${id}`} nativeShareButton={true} url={`${baseUrl}/p/${id}`}/>
<CopyableField content={ `${ baseUrl }/p/${ id }` } nativeShareButton={ true }
url={ `${ baseUrl }/p/${ id }` }/>
</ShowIf>
<ShowIf condition={ noteFrontmatter.type === '' }>
<Trans i18nKey={ 'editor.modal.shareLink.viewOnlyDescription' }/>
<CopyableField content={`${baseUrl}/s/${id}`} nativeShareButton={true} url={`${baseUrl}/s/${id}`}/>
<CopyableField content={ `${ baseUrl }/s/${ id }` } nativeShareButton={ true }
url={ `${ baseUrl }/s/${ id }` }/>
</ShowIf>
</Modal.Body>
</CommonModal>

View file

@ -24,7 +24,7 @@ export const useOnIframeLoad = (frameReference: RefObject<HTMLIFrameElement>, if
return
} else {
onNavigateAway()
console.error("Navigated away from unknown URL")
console.error('Navigated away from unknown URL')
frame.src = renderPageUrl
sendToRenderPage.current = true
}

View file

@ -19,7 +19,8 @@ export const MaxLengthWarningModal: React.FC<MaxLengthWarningModalProps> = ({ sh
useTranslation()
return (
<CommonModal data-cy={'limitReachedModal'} show={show} onHide={onHide} titleI18nKey={'editor.error.limitReached.title'} closeButton={true}>
<CommonModal data-cy={ 'limitReachedModal' } show={ show } onHide={ onHide }
titleI18nKey={ 'editor.error.limitReached.title' } closeButton={ true }>
<Modal.Body>
<Trans i18nKey={ 'editor.error.limitReached.description' } values={ { maxLength } }/>
<strong className='mt-2 d-block'><Trans i18nKey={ 'editor.error.limitReached.advice' }/></strong>

View file

@ -58,7 +58,8 @@ export const EditorPage: React.FC = () => {
useEffect(() => {
const requestedMode = search.substr(1)
const mode = Object.values(EditorMode).find(mode => mode === requestedMode)
const mode = Object.values(EditorMode)
.find(mode => mode === requestedMode)
if (mode) {
setEditorMode(mode)
}
@ -100,7 +101,7 @@ export const EditorPage: React.FC = () => {
<LoadingNoteAlert show={ loading }/>
</div>
<ShowIf condition={ !error && !loading }>
<div className={"flex-fill d-flex h-100 w-100 overflow-hidden flex-row"}>
<div className={ 'flex-fill d-flex h-100 w-100 overflow-hidden flex-row' }>
<Splitter
showLeft={ editorMode === EditorMode.EDITOR || editorMode === EditorMode.BOTH }
left={

View file

@ -21,7 +21,8 @@ const codeBlockHint = (editor: Editor): Promise< Hints| null > => {
}
const term = searchResult[1]
if (allSupportedLanguages.length === 0) {
allSupportedLanguages = hljs.default.listLanguages().concat('csv', 'flow', 'html', 'js', 'markmap', 'abc', 'graphviz', 'mermaid', 'vega-lite')
allSupportedLanguages = hljs.default.listLanguages()
.concat('csv', 'flow', 'html', 'js', 'markmap', 'abc', 'graphviz', 'mermaid', 'vega-lite')
}
const suggestions = search(term, allSupportedLanguages)
const cursor = editor.getCursor()

View file

@ -16,7 +16,8 @@ const spoilerSuggestion: Hint = {
const suggestions = validAlertLevels.map((suggestion: string): Hint => ({
text: ':::' + suggestion + '\n\n::: \n',
displayText: suggestion
})).concat(spoilerSuggestion)
}))
.concat(spoilerSuggestion)
const containerHint = (editor: Editor): Promise<Hints | null> => {
return new Promise((resolve) => {

View file

@ -40,7 +40,8 @@ export const findWordAtCursor = (editor: Editor): findWordAtCursorResponse => {
}
return {
text: line.slice(start, end).toLowerCase(),
text: line.slice(start, end)
.toLowerCase(),
start: start,
end: end
}
@ -49,7 +50,8 @@ export const findWordAtCursor = (editor: Editor): findWordAtCursorResponse => {
export const search = (term: string, list: string[]): string[] => {
const suggestions: string[] = []
list.forEach(item => {
if (item.toLowerCase().startsWith(term.toLowerCase())) {
if (item.toLowerCase()
.startsWith(term.toLowerCase())) {
suggestions.push(item)
}
})
@ -64,5 +66,5 @@ export const allHinters: Hinter[] = [
ImageHinter,
LinkAndExtraTagHinter,
PDFHinter,
CollapsableBlockHinter,
CollapsableBlockHinter
]

View file

@ -51,7 +51,8 @@ const linkAndExtraTagHint = (editor: Editor): Promise< Hints| null > => {
case 'time':
// show the current time when the autocompletion is opened and not when the function is loaded
return {
text: `[time=${DateTime.local().toFormat('DDDD T')}]`
text: `[time=${ DateTime.local()
.toFormat('DDDD T') }]`
}
default:
return {

View file

@ -30,6 +30,7 @@
.CodeMirror-line, .CodeMirror-line-like {
font-feature-settings: inherit;
}
.CodeMirror-line, .CodeMirror-line-like {
font-variant-ligatures: none;
}

View file

@ -30,7 +30,8 @@ const tab = (editor: Editor) => {
const tab = '\t'
// contruct x length spaces
const spaces = Array((editor.getOption('indentUnit') ?? 0) + 1).join(' ')
const spaces = Array((editor.getOption('indentUnit') ?? 0) + 1)
.join(' ')
// auto indent whole line when in list or blockquote
const cursor = editor.getCursor()
@ -43,7 +44,8 @@ const tab = (editor: Editor) => {
const regex = /^(\s*)(>[> ]*|[*+-]\s|(\d+)([.)]))/
let match
const multiple = editor.getSelection().split('\n').length > 1 ||
const multiple = editor.getSelection()
.split('\n').length > 1 ||
editor.getSelections().length > 1
if (multiple) {

View file

@ -17,32 +17,39 @@ borrow some color from tomorrow-night-eighties
.dark #main-toolbar {
background: #1d222a;
}
.dark #working-set-list-container,
.dark #editor-holder .pane-header {
background: #15181e;
}
.dark .working-set-header,
.dark #project-files-header .btn-alt-quiet {
background: rgba(204, 217, 255, 0.05);
}
.dark .working-set-header > span {
background: transparent;
}
.dark .sidebar-selection,
.dark .filetree-selection,
.dark .sidebar-selection-extension,
.dark .filetree-selection-extension {
background: #282c34;
}
.dark #status-bar,
.dark #status-indicators {
background: #15181e;
border-top-color: #1d222a;
}
.dark a,
.dark .open-files-container li.selected a {
color: #528bff;
}
/* Code Styling */
.cm-s-one-dark.CodeMirror,
.cm-s-one-dark .CodeMirror-scroll {
@ -50,26 +57,33 @@ borrow some color from tomorrow-night-eighties
background-color: #1e2126;
color: #abb2bf;
}
.cm-s-one-dark .CodeMirror-activeline-background {
background: transparent;
}
.cm-s-one-dark.CodeMirror-focused .CodeMirror-activeline-background {
background: rgba(204, 217, 255, 0.05);
}
.show-line-padding .cm-s-one-dark.CodeMirror-focused .CodeMirror-activeline-background {
box-shadow: inset 15px 0 0 0 #000;
}
.cm-s-one-dark.CodeMirror-focused .CodeMirror-activeline .CodeMirror-gutter-elt {
background: transparent;
color: #5c6370;
}
.cm-s-one-dark.CodeMirror-focused .CodeMirror-activeline .inline-widget .CodeMirror-gutter-elt {
color: red;
}
.cm-s-one-dark .cm-string-2,
.cm-s-one-dark .cm-hr {
color: #56b6c2;
}
.cm-s-one-dark .cm-number,
.cm-s-one-dark .cm-attribute,
.cm-s-one-dark .cm-qualifier,
@ -77,9 +91,11 @@ borrow some color from tomorrow-night-eighties
.cm-s-one-dark .cm-atom {
color: #eda35e;
}
.cm-s-one-dark .cm-def {
color: #c678dd;
}
.cm-s-one-dark .cm-property,
.cm-s-one-dark .cm-variable,
.cm-s-one-dark .cm-variable-2,
@ -89,10 +105,12 @@ borrow some color from tomorrow-night-eighties
.cm-s-one-dark .cm-bracket {
color: #f76e79;
}
/*borrow from tomorrow-night-eighties*/
.cm-s-one-dark .cm-variable {
color: #99cc99;
}
.cm-s-one-dark .cm-variable-2 {
color: #6699cc;
}
@ -101,34 +119,42 @@ borrow some color from tomorrow-night-eighties
color: #5c6370;
font-style: italic;
}
.cm-s-one-dark .cm-error,
.cm-s-one-dark .cm-minus {
color: #be5046;
}
.cm-s-one-dark .cm-header {
color: #eda35e;
}
.cm-s-one-dark .cm-link {
color: #98c379;
text-decoration: none;
}
.cm-s-one-dark .cm-rangeinfo {
color: #c678dd;
}
.cm-s-one-dark .cm-keyword,
.cm-s-one-dark .cm-builtin,
.cm-s-one-dark .cm-tag {
color: #e06c75;
}
.cm-s-one-dark .cm-m-markdown.cm-keyword,
.cm-s-one-dark .cm-m-markdown.cm-builtin,
.cm-s-one-dark .cm-m-markdown.cm-tag {
color: #98c379;
}
.cm-s-one-dark .cm-string {
/* color: #98c379;*/
color: #6699cc;
}
/* Extra CSS */
.cm-s-one-dark .CodeMirror-searching {
color: #fff !important;
@ -137,32 +163,40 @@ borrow some color from tomorrow-night-eighties
background-color: rgba(204, 217, 255, 0.09);
box-shadow: 0px 0px 6px rgba(66, 133, 244, 0.4);
}
.cm-s-one-dark .CodeMirror-searching.searching-current-match {
color: #fff;
background-color: #528bff;
box-shadow: 0px 0px 6px rgba(66, 133, 244, 0.8);
}
.cm-s-one-dark .CodeMirror-cursor {
border-left: 2px solid #528bff !important;
}
.cm-fat-cursor .CodeMirror-cursor {
border-left: 2px solid #3C5B9E !important;
background: #3C5B9E;
}
.cm-s-one-dark .CodeMirror-gutters {
/* background-color: #282c34;*/
background-color: #1e2126;
border-right: 1px solid rgba(204, 217, 255, 0.05);
}
.cm-s-one-dark .CodeMirror-linenumber {
color: #393e46;
}
.cm-s-one-dark.CodeMirror .CodeMirror-selected {
background: rgba(204, 217, 255, 0.05);
}
.cm-s-one-dark.CodeMirror-focused .CodeMirror-selected {
background: rgba(204, 217, 255, 0.09);
}
.cm-s-one-dark .CodeMirror-matchingbracket,
.cm-s-one-dark .CodeMirror-matchingtag {
/* Ensure visibility against gray inline editor background */
@ -170,52 +204,65 @@ borrow some color from tomorrow-night-eighties
color: #abb2bf !important;
border-bottom: 1px solid #528bff;
}
.cm-s-one-dark .CodeMirror-overwrite .CodeMirror-cursor {
border-left: none !important;
border-bottom: 1px solid #fff;
width: 0.5em;
}
.cm-s-one-dark.CodeMirror .CodeMirror {
background: transparent;
}
.cm-s-one-dark.CodeMirror .CodeMirror .CodeMirror-gutters {
background: transparent;
border-right: none;
}
.cm-s-one-dark.CodeMirror .CodeMirror .CodeMirror-activeline-background {
background: transparent;
}
.cm-s-one-dark.CodeMirror .CodeMirror .CodeMirror-activeline .CodeMirror-gutter-elt {
background: transparent;
color: #5c6370;
}
.cm-s-one-dark.CodeMirror .CodeMirror-focused .CodeMirror-activeline-background {
background: #000;
}
.cm-s-one-dark.CodeMirror .CodeMirror-focused .CodeMirror-activeline .CodeMirror-gutter-elt {
background: rgba(204, 217, 255, 0.05);
color: #fff;
}
.cm-s-one-dark .CodeMirror-foldgutter-open:after {
color: #393e46;
}
.cm-s-one-dark .CodeMirror-foldgutter-folded:after {
color: #5c6370;
}
.cm-s-one-dark .CodeMirror.over-gutter .CodeMirror-foldgutter-open:after,
.cm-s-one-dark.CodeMirror-focused .CodeMirror-activeline .CodeMirror-foldgutter-open:after {
color: #5c6370;
}
.cm-s-one-dark .CodeMirror-foldmarker {
border-color: #393e46;
color: #abb2bf;
background: rgba(204, 217, 255, 0.05);
}
/* Non-editor styling */
.image-view,
.not-editor {
background-color: #282c34;
}
.view-pane .image-view {
color: #abb2bf;
}

View file

@ -34,7 +34,8 @@ export const createStatusInfo = (editor: Editor, maxDocumentLength: number): Sta
remainingCharacters: maxDocumentLength - editor.getValue().length,
linesInDocument: editor.lineCount(),
selectedColumns: editor.getSelection().length,
selectedLines: editor.getSelection().split('\n').length
selectedLines: editor.getSelection()
.split('\n').length
})
export const StatusBar: React.FC<StatusBarInfo> = ({ position, selectedColumns, selectedLines, charactersInDocument, linesInDocument, remainingCharacters }) => {

View file

@ -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'
@ -33,7 +33,8 @@ export const EditorPreferenceBooleanProperty: React.FC<EditorPreferenceBooleanPr
const i18nPrefix = `editor.modal.preferences.${ property }`
return (
<EditorPreferenceInput onChange={selectItem} property={property} type={EditorPreferenceInputType.SELECT} value={preference}>
<EditorPreferenceInput onChange={ selectItem } property={ property } type={ EditorPreferenceInputType.SELECT }
value={ preference }>
<option value={ 'true' }>
{ t(`${ i18nPrefix }.on`) }
</option>

View file

@ -25,7 +25,8 @@ export const EditorPreferenceInput: React.FC<EditorPreferenceInputProps> = ({ pr
return (
<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' }

View file

@ -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,7 +20,7 @@ export const EditorPreferenceLigaturesSelect: React.FC = () => {
const { t } = useTranslation()
return (
<EditorPreferenceInput onChange={saveLigatures} value={ligaturesEnabled} property={"ligatures"}
<EditorPreferenceInput onChange={ saveLigatures } value={ ligaturesEnabled } property={ 'ligatures' }
type={ EditorPreferenceInputType.BOOLEAN }>
<option value='true'>{ t(`common.yes`) }</option>
<option value='false'>{ t(`common.no`) }</option>

View file

@ -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 }/>
)
}

View file

@ -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'
@ -35,7 +35,8 @@ export const EditorPreferenceSelectProperty: React.FC<EditorPreferenceSelectProp
const i18nPrefix = `editor.modal.preferences.${ property }`
return (
<EditorPreferenceInput onChange={selectItem} property={property} type={EditorPreferenceInputType.SELECT} value={preference}>
<EditorPreferenceInput onChange={ selectItem } property={ property } type={ EditorPreferenceInputType.SELECT }
value={ preference }>
{ selections.map(selection =>
<option key={ selection } value={ selection }>
{ t(`${ i18nPrefix }.${ selection }`) }

View file

@ -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()
@ -39,10 +39,12 @@ export const EditorPreferences: React.FC = () => {
<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 }/>
@ -56,7 +58,9 @@ export const EditorPreferences: React.FC = () => {
<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>

View file

@ -29,7 +29,8 @@ export const EmojiPickerButton: React.FC<EmojiPickerButtonProps> = ({ editor })
addEmoji(emoji, editor)
} }
onDismiss={ () => setShowEmojiPicker(false) }/>
<Button data-cy={'show-emoji-picker'} variant='light' onClick={() => setShowEmojiPicker(old => !old)} title={t('editor.editorToolbar.emoji')}>
<Button data-cy={ 'show-emoji-picker' } variant='light' onClick={ () => setShowEmojiPicker(old => !old) }
title={ t('editor.editorToolbar.emoji') }>
<ForkAwesomeIcon icon="smile-o"/>
</Button>
</Fragment>

View file

@ -19,7 +19,8 @@ export interface EmojiPickerProps {
onDismiss: () => void
}
export const customEmojis: CustomEmoji[] = Object.keys(ForkAwesomeIcons).map((name) => ({
export const customEmojis: CustomEmoji[] = Object.keys(ForkAwesomeIcons)
.map((name) => ({
name: `fa-${ name }`,
shortcodes: [`fa-${ name.toLowerCase() }`],
url: forkawesomeIcon,
@ -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 }/>
)
}

View file

@ -30,7 +30,8 @@ export const TablePickerButton: React.FC<TablePickerButtonProps> = ({ editor })
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>

View file

@ -5,7 +5,6 @@
*/
.table-picker-container {
z-index: 1111;

View file

@ -45,7 +45,8 @@ 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">
<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 })
@ -53,8 +54,10 @@ export const TablePicker: React.FC<TablePickerProps> = ({ show, onDismiss, onTab
}
</p>
<div className={ 'table-container' }>
{createNumberRangeArray(8).map((row: number) => (
createNumberRangeArray(10).map((col: number) => (
{ 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' : '' }` }

View file

@ -48,63 +48,80 @@ 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')}>
<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')}>
<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')}>
<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 }/>
</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')}>
<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 }/>

View file

@ -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()
}
}
@ -421,7 +424,8 @@ describe('test addHeaderLevel', () => {
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()
}
})
@ -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()
}
})
@ -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()
}
})
@ -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()
}
})
@ -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()
}
})
@ -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('![](https://)')
expect(replacement)
.toEqual('![](https://)')
done()
}
})
@ -842,7 +866,8 @@ describe('test addImage', () => {
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()
}
})
@ -855,7 +880,8 @@ describe('test addImage', () => {
listSelections: mockListSelections(multilineOffset, false),
getLine: (): string => (textFirstLine),
replaceRange: (replacement: string | string[]) => {
expect(replacement).toEqual('![line3rd ](https://)')
expect(replacement)
.toEqual('![line3rd ](https://)')
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()
}
})
@ -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()
}
})
@ -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()
}
})
@ -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()
}
})
@ -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()
}
})

View file

@ -32,10 +32,14 @@ export const addCollapsableBlock = (editor: Editor): void => changeLines(editor,
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 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 }`)
}
@ -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)
}

View file

@ -29,10 +29,16 @@ describe('yaml frontmatter tests', () => {
const testFrontmatter = (input: string, expectedRaw: Partial<RawNoteFrontmatter>, expectedFinished: Partial<NoteFrontmatter>) => {
md.render(input)
expect(raw).not.toBe(undefined)
expect(raw).toEqual(expectedRaw)
expect(finished).not.toBe(undefined)
expect(finished).toEqual({
expect(raw)
.not
.toBe(undefined)
expect(raw)
.toEqual(expectedRaw)
expect(finished)
.not
.toBe(undefined)
expect(finished)
.toEqual({
...defaultYAML,
...expectedFinished
})

View file

@ -257,7 +257,8 @@ export class NoteFrontmatter {
theme: 'white'
} */
if (typeof rawData?.tags === 'string') {
this.tags = rawData?.tags?.split(',').map(entry => entry.trim()) ?? []
this.tags = rawData?.tags?.split(',')
.map(entry => entry.trim()) ?? []
this.deprecatedTagsSyntax = true
} else if (typeof rawData?.tags === 'object') {
this.tags = rawData?.tags?.filter(tag => tag !== null) ?? []

View file

@ -24,7 +24,7 @@ export const useOnIframeLoad = (frameReference: RefObject<HTMLIFrameElement>, if
return
} else {
onNavigateAway()
console.error("Navigated away from unknown URL")
console.error('Navigated away from unknown URL')
frame.src = renderPageUrl
sendToRenderPage.current = true
}

View file

@ -39,13 +39,18 @@ export const RenderIframe: React.FC<MarkdownDocumentProps> = (
const onIframeLoad = useOnIframeLoad(frameReference, iframeCommunicator, rendererOrigin, renderPageUrl, resetRendererReady)
useEffect(() => () => iframeCommunicator.unregisterEventListener(), [iframeCommunicator])
useEffect(() => iframeCommunicator.onFirstHeadingChange(onFirstHeadingChange), [iframeCommunicator, onFirstHeadingChange])
useEffect(() => iframeCommunicator.onFrontmatterChange(onFrontmatterChange), [iframeCommunicator, onFrontmatterChange])
useEffect(() => iframeCommunicator.onFirstHeadingChange(onFirstHeadingChange), [iframeCommunicator,
onFirstHeadingChange])
useEffect(() => iframeCommunicator.onFrontmatterChange(onFrontmatterChange), [iframeCommunicator,
onFrontmatterChange])
useEffect(() => iframeCommunicator.onSetScrollState(onScroll), [iframeCommunicator, onScroll])
useEffect(() => iframeCommunicator.onSetScrollSourceToRenderer(onMakeScrollSource), [iframeCommunicator, onMakeScrollSource])
useEffect(() => iframeCommunicator.onTaskCheckboxChange(onTaskCheckedChange), [iframeCommunicator, onTaskCheckedChange])
useEffect(() => iframeCommunicator.onSetScrollSourceToRenderer(onMakeScrollSource), [iframeCommunicator,
onMakeScrollSource])
useEffect(() => iframeCommunicator.onTaskCheckboxChange(onTaskCheckedChange), [iframeCommunicator,
onTaskCheckedChange])
useEffect(() => iframeCommunicator.onImageClicked(setLightboxDetails), [iframeCommunicator])
useEffect(() => iframeCommunicator.onRendererReady(() => setRendererReady(true)), [darkMode, iframeCommunicator, scrollState])
useEffect(() => iframeCommunicator.onRendererReady(() => setRendererReady(true)), [darkMode, iframeCommunicator,
scrollState])
useEffect(() => {
if (rendererReady) {
iframeCommunicator.sendSetDarkmode(darkMode)

View file

@ -16,7 +16,7 @@ export const DeleteNoteSidebarEntry: React.FC<SpecificSidebarEntryProps> = ({ hi
return (
<Fragment>
<SidebarButton icon={"trash"} className={className} hide={hide} onClick={() => setShowDialog(true)}>
<SidebarButton icon={ 'trash' } className={ className } hide={ hide } onClick={ () => setShowDialog(true) }>
<Trans i18nKey={ 'landing.history.menu.deleteNote' }/>
</SidebarButton>
<DeletionModal

View file

@ -16,7 +16,7 @@ export const DocumentInfoSidebarEntry: React.FC<SpecificSidebarEntryProps> = ({c
return (
<Fragment>
<SidebarButton hide={hide} className={className} icon={"line-chart"} onClick={() => setShowModal(true)}>
<SidebarButton hide={ hide } className={ className } icon={ 'line-chart' } onClick={ () => setShowModal(true) }>
<Trans i18nKey={ 'editor.modal.documentInfo.title' }/>
</SidebarButton>
<DocumentInfoModal show={ showModal } onHide={ () => setShowModal(false) }/>

View file

@ -19,7 +19,7 @@ export const ExportMarkdownSidebarEntry: React.FC = () => {
}, [markdownContent])
return (
<SidebarButton data-cy={"menu-export-markdown"} onClick={onClick} icon={'file-text'}>
<SidebarButton data-cy={ 'menu-export-markdown' } onClick={ onClick } icon={ 'file-text' }>
<Trans i18nKey={ 'editor.export.markdown-file' }/>
</SidebarButton>
)

View file

@ -29,28 +29,29 @@ export const ExportMenuSidebarMenu: React.FC<SpecificSidebarMenuProps> = (
return (
<Fragment>
<SidebarButton data-cy={"menu-export"} hide={hide} icon={expand ? "arrow-left" : "cloud-download"}
<SidebarButton data-cy={ 'menu-export' } hide={ hide } icon={ expand ? 'arrow-left' : 'cloud-download' }
className={ className } onClick={ onClickHandler }>
<Trans i18nKey={ 'editor.documentBar.export' }/>
</SidebarButton>
<SidebarMenu expand={ expand }>
<SidebarButton icon={"github"}>
<SidebarButton icon={ 'github' }>
Gist
</SidebarButton>
<SidebarButton icon={"gitlab"}>
<SidebarButton icon={ 'gitlab' }>
Gitlab Snippet
</SidebarButton>
<ExportMarkdownSidebarEntry/>
<SidebarButton icon={"file-code-o"}>
<SidebarButton icon={ 'file-code-o' }>
HTML
</SidebarButton>
<SidebarButton icon={"file-code-o"}>
<SidebarButton icon={ 'file-code-o' }>
<Trans i18nKey='editor.export.rawHtml'/>
</SidebarButton>
<SidebarButton icon={"file-pdf-o"}>
<a className='small text-muted' dir={'auto'} href={links.faq} target={'_blank'} rel='noopener noreferrer'>
<SidebarButton icon={ 'file-pdf-o' }>
<a className='small text-muted' dir={ 'auto' } href={ links.faq } target={ '_blank' }
rel='noopener noreferrer'>
<Trans i18nKey={ 'editor.export.pdf' }/>
&nbsp;
<span className={ 'text-primary' }>

View file

@ -39,10 +39,10 @@ export const ImportMarkdownSidebarEntry: React.FC = () => {
return (
<Fragment>
<SidebarButton data-cy={"menu-import-markdown"} icon={"file-text-o"} onClick={buttonClick}>
<SidebarButton data-cy={ 'menu-import-markdown' } icon={ 'file-text-o' } onClick={ buttonClick }>
<Trans i18nKey={ 'editor.import.file' }/>
</SidebarButton>
<UploadInput onLoad={onImportMarkdown} data-cy={"menu-import-markdown-input"}
<UploadInput onLoad={ onImportMarkdown } data-cy={ 'menu-import-markdown-input' }
acceptedFiles={ '.md, text/markdown, text/plain' } onClickRef={ clickRef }/>
</Fragment>
)

View file

@ -29,18 +29,18 @@ export const ImportMenuSidebarMenu: React.FC<SpecificSidebarMenuProps> = (
return (
<Fragment>
<SidebarButton data-cy={"menu-import"} hide={hide} icon={expand ? "arrow-left" : "cloud-upload"}
<SidebarButton data-cy={ 'menu-import' } hide={ hide } icon={ expand ? 'arrow-left' : 'cloud-upload' }
className={ className } onClick={ onClickHandler }>
<Trans i18nKey={ 'editor.documentBar.import' }/>
</SidebarButton>
<SidebarMenu expand={ expand }>
<SidebarButton icon={"github"}>
<SidebarButton icon={ 'github' }>
Gist
</SidebarButton>
<SidebarButton icon={"gitlab"}>
<SidebarButton icon={ 'gitlab' }>
Gitlab Snippet
</SidebarButton>
<SidebarButton icon={"clipboard"}>
<SidebarButton icon={ 'clipboard' }>
<Trans i18nKey={ 'editor.import.clipboard' }/>
</SidebarButton>
<ImportMarkdownSidebarEntry/>

View file

@ -16,7 +16,7 @@ export const PermissionsSidebarEntry: React.FC<SpecificSidebarEntryProps> = ({cl
return (
<Fragment>
<SidebarButton hide={hide} className={className} icon={"lock"} onClick={() => setShowModal(true)}>
<SidebarButton hide={ hide } className={ className } icon={ 'lock' } onClick={ () => setShowModal(true) }>
<Trans i18nKey={ 'editor.modal.permissions.title' }/>
</SidebarButton>
<PermissionModal show={ showModal } onHide={ () => setShowModal(false) }/>

View file

@ -15,7 +15,7 @@ export const RevisionSidebarEntry: React.FC<SpecificSidebarEntryProps> = ({class
return (
<Fragment>
<SidebarButton hide={hide} className={className} icon={"history"} onClick={() => setShowModal(true)}>
<SidebarButton hide={ hide } className={ className } icon={ 'history' } onClick={ () => setShowModal(true) }>
<Trans i18nKey={ 'editor.modal.revision.title' }/>
</SidebarButton>
<RevisionModal show={ showModal } onHide={ () => setShowModal(false) }/>

View file

@ -16,7 +16,7 @@ export const ShareSidebarEntry: React.FC<SpecificSidebarEntryProps> = ({classNam
return (
<Fragment>
<SidebarButton hide={hide} className={className} icon={"share"} onClick={() => setShowModal(true)}>
<SidebarButton hide={ hide } className={ className } icon={ 'share' } onClick={ () => setShowModal(true) }>
<Trans i18nKey={ 'editor.modal.shareLink.title' }/>
</SidebarButton>
<ShareModal show={ showModal } onHide={ () => setShowModal(false) }/>

View file

@ -10,7 +10,7 @@ import { IconName } from '../../common/fork-awesome/types'
import { ShowIf } from '../../common/show-if/show-if'
import { SidebarEntryProps } from './types'
export type SidebarEntryVariant = "primary"
export type SidebarEntryVariant = 'primary'
export const SidebarButton: React.FC<SidebarEntryProps> = ({ children, icon, className, variant, buttonRef, hide, ...props }) => {
return (

View file

@ -14,5 +14,5 @@ export const SidebarMenu: React.FC<SidebarMenuProps> = ({children, expand}) => {
{ children }
</div>
</div>
);
)
}

View file

@ -14,7 +14,7 @@ import { PermissionsSidebarEntry } from './permissions-sidebar-entry'
import { PinNoteSidebarEntry } from './pin-note-sidebar-entry'
import { RevisionSidebarEntry } from './revision-sidebar-entry'
import { ShareSidebarEntry } from './share-sidebar-entry'
import "./style/theme.scss"
import './style/theme.scss'
import { DocumentSidebarMenuSelection } from './types'
import { UsersOnlineSidebarMenu } from './users-online-sidebar-menu/users-online-sidebar-menu'

View file

@ -21,7 +21,7 @@ export interface SidebarEntryProps {
hide?: boolean
className?: string
onClick?: () => void
"data-cy"?: string
'data-cy'?: string
}
export interface SidebarMenuProps {

View file

@ -10,7 +10,7 @@ export interface UploadInputProps {
onLoad: (file: File) => Promise<void>
acceptedFiles: string
onClickRef: MutableRefObject<(() => void) | undefined>
"data-cy"?: string
'data-cy'?: string
}
export const UploadInput: React.FC<UploadInputProps> = ({ onLoad, acceptedFiles, onClickRef, ...props }) => {
@ -25,9 +25,11 @@ export const UploadInput: React.FC<UploadInputProps> = ({ onLoad, acceptedFiles,
return
}
const file = fileInput.files[0]
onLoad(file).then(() => {
onLoad(file)
.then(() => {
fileInput.value = ''
}).catch((error) => {
})
.catch((error) => {
console.error(error)
})
})
@ -39,6 +41,7 @@ export const UploadInput: React.FC<UploadInputProps> = ({ onLoad, acceptedFiles,
})
return (
<input data-cy={props["data-cy"]} type='file' ref={fileInputReference} className='d-none' accept={acceptedFiles}/>
<input data-cy={ props['data-cy'] } type='file' ref={ fileInputReference } className='d-none'
accept={ acceptedFiles }/>
)
}

View file

@ -20,8 +20,9 @@ export const UserLine: React.FC<UserLineProps> = ({ name, photo, color, status }
return (
<div className={ 'd-flex align-items-center h-100 w-100' }>
<div className='d-inline-flex align-items-bottom user-line-color-indicator' style={ { borderLeftColor: color } }/>
<UserAvatar photo={photo} name={name} additionalClasses={'flex-fill overflow-hidden px-2 text-nowrap w-100'}/>
<div className={"active-indicator-container"}>
<UserAvatar photo={ photo } name={ name }
additionalClasses={ 'flex-fill overflow-hidden px-2 text-nowrap w-100' }/>
<div className={ 'active-indicator-container' }>
<ActiveIndicator status={ status }/>
</div>
</div>

View file

@ -36,16 +36,19 @@ export const UsersOnlineSidebarMenu: React.FC<SpecificSidebarMenuProps> = ({
return (
<Fragment>
<SidebarButton hide={hide} buttonRef={buttonRef} onClick={onClickHandler} icon={expand ? "arrow-left" : "users"}
<SidebarButton hide={ hide } buttonRef={ buttonRef } onClick={ onClickHandler }
icon={ expand ? 'arrow-left' : 'users' }
variant={ 'primary' } className={ `online-entry ${ className ?? '' }` }>
<Trans i18nKey={ 'editor.onlineStatus.online' }/>
</SidebarButton>
<SidebarMenu expand={ expand }>
<SidebarButton>
<UserLine name="Philip Molares" photo="/img/avatar.png" color="red" status={ActiveIndicatorStatus.INACTIVE}/>
<UserLine name="Philip Molares" photo="/img/avatar.png" color="red"
status={ ActiveIndicatorStatus.INACTIVE }/>
</SidebarButton>
<SidebarButton>
<UserLine name="Tilman Vatteroth" photo="/img/avatar.png" color="blue" status={ActiveIndicatorStatus.ACTIVE}/>
<UserLine name="Tilman Vatteroth" photo="/img/avatar.png" color="blue"
status={ ActiveIndicatorStatus.ACTIVE }/>
</SidebarButton>
</SidebarMenu>
</Fragment>

View file

@ -56,7 +56,8 @@ export const Splitter: React.FC<SplitterProps> = ({ containerClassName, left, ri
return (
<div ref={ splitContainer } className={ `flex-fill flex-row d-flex ${ containerClassName || '' }` }
onMouseUp={ stopResizing } onTouchEnd={ stopResizing } onMouseMove={ onMouseMove } onTouchMove={ onTouchMove }>
<div className={`splitter left ${!showLeft ? 'd-none' : ''}`} style={{ flexBasis: `calc(${realSplit}% - 5px)` }}>
<div className={ `splitter left ${ !showLeft ? 'd-none' : '' }` }
style={ { flexBasis: `calc(${ realSplit }% - 5px)` } }>
{ left }
</div>
<ShowIf condition={ showLeft && showRight }>

View file

@ -19,7 +19,9 @@ export interface TableOfContentsProps {
}
export const slugify = (content: string): string => {
return encodeURIComponent(content.trim().toLowerCase().replace(/\s+/g, '-'))
return encodeURIComponent(content.trim()
.toLowerCase()
.replace(/\s+/g, '-'))
}
const convertLevel = (toc: TocAst, levelsToShowUnderThis: number, headerCounts: Map<string, number>,
@ -38,7 +40,8 @@ const convertLevel = (toc: TocAst, levelsToShowUnderThis: number, headerCounts:
const content = (
<Fragment>
<ShowIf condition={ toc.l > 0 }>
<a href={headlineUrl} title={rawName} onClick={createJumpToMarkClickEventHandler(slug.substr(1))}>{rawName}</a>
<a href={ headlineUrl } title={ rawName }
onClick={ createJumpToMarkClickEventHandler(slug.substr(1)) }>{ rawName }</a>
</ShowIf>
<ShowIf condition={ toc.c.length > 0 }>
<ul>
@ -69,7 +72,8 @@ export const TableOfContents: React.FC<TableOfContentsProps> = ({
baseUrl
}) => {
useTranslation()
const tocTree = useMemo(() => convertLevel(ast, maxDepth, new Map<string, number>(), false, baseUrl), [ast, maxDepth, baseUrl])
const tocTree = useMemo(() => convertLevel(ast, maxDepth, new Map<string, number>(), false, baseUrl), [ast, maxDepth,
baseUrl])
return (
<div className={ `markdown-toc ${ className ?? '' }` }>

View file

@ -4,4 +4,5 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
export const isMac = navigator.platform.toLowerCase().includes('mac')
export const isMac = navigator.platform.toLowerCase()
.includes('mac')

View file

@ -41,9 +41,11 @@ export class ErrorBoundary extends Component {
<Container className="text-light d-flex flex-column mvh-100">
<div className='text-light d-flex flex-column align-items-center justify-content-center my-5'>
<h1>An unknown error occurred</h1>
<p>Don't worry, this happens sometimes. If this is the first time you see this page then try reloading the app.</p>
<p>Don't worry, this happens sometimes. If this is the first time you see this page then try reloading the
app.</p>
If you can reproduce this error, then we would be glad if you&#32;
<ExternalLink text={'open an issue on github'} href={frontendVersion.issueTrackerUrl} className={'text-primary'}/>&#32;
<ExternalLink text={ 'open an issue on github' } href={ frontendVersion.issueTrackerUrl }
className={ 'text-primary' }/>&#32;
or <ExternalLink text={ 'contact us on matrix.' } href={ links.chat } className={ 'text-primary' }/>
<Button onClick={ () => this.refreshPage() } title={ 'Reload App' } className={ 'mt-4' }>
<ForkAwesomeIcon icon={ 'refresh' }/>&nbsp;Reload App

View file

@ -29,7 +29,8 @@ export const EntryMenu: React.FC<EntryMenuProps> = ({ id, title, location, isDar
return (
<Dropdown className={ `d-inline-flex ${ className || '' }` }>
<Dropdown.Toggle variant={isDark ? 'secondary' : 'light'} id={`dropdown-card-${id}`} className='no-arrow history-menu d-inline-flex align-items-center'>
<Dropdown.Toggle variant={ isDark ? 'secondary' : 'light' } id={ `dropdown-card-${ id }` }
className='no-arrow history-menu d-inline-flex align-items-center'>
<ForkAwesomeIcon icon="ellipsis-v" fixedWidth={ true }/>
</Dropdown.Toggle>

View file

@ -21,19 +21,22 @@ export const HistoryCard: React.FC<HistoryEntryProps> = ({ entry, onPinClick, on
<Card className="card-min-height" text={ 'dark' } bg={ 'light' }>
<Card.Body className="p-2 d-flex flex-row justify-content-between">
<div className={ 'd-flex flex-column' }>
<PinButton isDark={false} isPinned={entry.pinned} onPinClick={() => onPinClick(entry.id, entry.location)}/>
<PinButton isDark={ false } isPinned={ entry.pinned }
onPinClick={ () => onPinClick(entry.id, entry.location) }/>
</div>
<Link to={ `/n/${ entry.id }` } className="text-decoration-none flex-fill text-dark">
<div className={ 'd-flex flex-column justify-content-between' }>
<Card.Title className="m-0 mt-1dot5">{ entry.title }</Card.Title>
<div>
<div className="text-black-50 mt-2">
<ForkAwesomeIcon icon="clock-o"/> {DateTime.fromISO(entry.lastVisited).toRelative()}<br/>
<ForkAwesomeIcon icon="clock-o"/> { DateTime.fromISO(entry.lastVisited)
.toRelative() }<br/>
{ formatHistoryDate(entry.lastVisited) }
</div>
<div className={ 'card-footer-min-height p-0' }>
{
entry.tags.map((tag) => <Badge variant={'dark'} className={'mr-1 mb-1'} key={tag}>{tag}</Badge>)
entry.tags.map((tag) => <Badge variant={ 'dark' } className={ 'mr-1 mb-1' }
key={ tag }>{ tag }</Badge>)
}
</div>
</div>

View file

@ -28,7 +28,8 @@ export const HistoryTableRow: React.FC<HistoryEntryProps> = ({ entry, onPinClick
}
</td>
<td>
<PinButton isDark={true} isPinned={entry.pinned} onPinClick={() => onPinClick(entry.id, entry.location)} className={'mb-1 mr-1'}/>
<PinButton isDark={ true } isPinned={ entry.pinned } onPinClick={ () => onPinClick(entry.id, entry.location) }
className={ 'mb-1 mr-1' }/>
<EntryMenu
id={ entry.id }
title={ entry.title }

View file

@ -92,7 +92,8 @@ export const HistoryToolbar: React.FC<HistoryToolbarProps> = ({ onSettingsChange
return (
<Form inline={ true }>
<InputGroup className={ 'mr-1 mb-1' }>
<Typeahead id={'tagsSelection'} options={tags} multiple={true} placeholder={t('landing.history.toolbar.selectTags')}
<Typeahead id={ 'tagsSelection' } options={ tags } multiple={ true }
placeholder={ t('landing.history.toolbar.selectTags') }
onChange={ selectedTagsChanged }/>
</InputGroup>
<InputGroup className={ 'mr-1 mb-1' }>
@ -103,7 +104,8 @@ export const HistoryToolbar: React.FC<HistoryToolbarProps> = ({ onSettingsChange
/>
</InputGroup>
<InputGroup className={ 'mr-1 mb-1' }>
<SortButton onDirectionChange={titleSortChanged} direction={state.titleSortDirection} variant={'light'}><Trans
<SortButton onDirectionChange={ titleSortChanged } direction={ state.titleSortDirection }
variant={ 'light' }><Trans
i18nKey={ 'landing.history.toolbar.sortByTitle' }/></SortButton>
</InputGroup>
<InputGroup className={ 'mr-1 mb-1' }>
@ -136,10 +138,12 @@ export const HistoryToolbar: React.FC<HistoryToolbarProps> = ({ onSettingsChange
onChange={ (newViewState: ViewStateEnum) => {
toggleViewChanged(newViewState)
} }>
<ToggleButton className={'btn-light'} value={ViewStateEnum.CARD} title={t('landing.history.toolbar.cards')}>
<ToggleButton className={ 'btn-light' } value={ ViewStateEnum.CARD }
title={ t('landing.history.toolbar.cards') }>
<ForkAwesomeIcon icon={ 'sticky-note' } className={ 'fa-fix-line-height' }/>
</ToggleButton>
<ToggleButton className={'btn-light'} value={ViewStateEnum.TABLE} title={t('landing.history.toolbar.table')}>
<ToggleButton className={ 'btn-light' } value={ ViewStateEnum.TABLE }
title={ t('landing.history.toolbar.table') }>
<ForkAwesomeIcon icon={ 'table' } className={ 'fa-fix-line-height' }/>
</ToggleButton>
</ToggleButtonGroup>

View file

@ -50,5 +50,6 @@ export const SortButton: React.FC<SortButtonProps> = ({ children, variant, onDir
onDirectionChange(toggleDirection(direction))
}
return <IconButton onClick={toggleSort} variant={variant} icon={getIcon(direction)} border={true}>{children}</IconButton>
return <IconButton onClick={ toggleSort } variant={ variant } icon={ getIcon(direction) }
border={ true }>{ children }</IconButton>
}

Some files were not shown because too many files have changed in this diff Show more