Skip to content

Add preference to disable table editor shortcuts and migrate preferences to localStorage #1901

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
218 changes: 149 additions & 69 deletions public/js/lib/editor/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-env browser */
/* global CodeMirror, $, editor, Cookies */
import { options, Alignment, FormatType } from '@susisu/mte-kernel'
import debounce from 'lodash/debounce'
Expand All @@ -11,6 +12,39 @@ import CodeMirrorSpellChecker, { supportLanguages, supportLanguageCodes } from '
import { initTableEditor } from './table-editor'
import { availableThemes } from './constants'

// Storage utility class for localStorage operations
class Storage {
static get (key, defaultValue = null) {
try {
const value = localStorage.getItem(key)
return value !== null ? value : defaultValue
} catch (e) {
console.error('Error getting from localStorage:', e)
return defaultValue
}
}

static set (key, value, options = {}) {
try {
localStorage.setItem(key, value)
return true
} catch (e) {
console.error('Error setting to localStorage:', e)
return false
}
}

static remove (key) {
try {
localStorage.removeItem(key)
return true
} catch (e) {
console.error('Error removing from localStorage:', e)
return false
}
}
}

/* config section */
const isMac = CodeMirror.keyMap.default === CodeMirror.keyMap.macDefault
const defaultEditorMode = 'gfm'
Expand Down Expand Up @@ -183,6 +217,39 @@ export default class Editor {
CodeMirror.defineMode('markmap', function (config, modeConfig) {
return CodeMirror.overlayMode(CodeMirror.getMode(config, 'gfm'), ignoreOverlay)
})

// Migrate preferences from cookies to localStorage
this.migratePreferences()
}

// Migrate preferences from cookies to localStorage
migratePreferences () {
// Only run migration if window and localStorage are available
if (typeof window === 'undefined' || typeof localStorage === 'undefined' || typeof Cookies === 'undefined') {
return
}

const preferencesToMigrate = [
'indent_type',
'tab_size',
'space_units',
'keymap',
'theme',
'spellcheck',
'linter',
'preferences-override-browser-keymap',
'preferences-disable-table-shortcuts'
]

preferencesToMigrate.forEach(key => {
// Check if preference exists in cookies but not in localStorage
const cookieValue = Cookies.get(key)
if (cookieValue !== undefined && Storage.get(key) === null) {
// Migrate the preference to localStorage
Storage.set(key, cookieValue)
console.log(`Migrated preference ${key} from cookies to localStorage`)
}
})
}

on (event, cb) {
Expand Down Expand Up @@ -423,24 +490,24 @@ export default class Editor {
}

setIndent () {
var cookieIndentType = Cookies.get('indent_type')
var cookieTabSize = parseInt(Cookies.get('tab_size'))
var cookieSpaceUnits = parseInt(Cookies.get('space_units'))
if (cookieIndentType) {
if (cookieIndentType === 'tab') {
var storedIndentType = Storage.get('indent_type')
var storedTabSize = parseInt(Storage.get('tab_size'))
var storedSpaceUnits = parseInt(Storage.get('space_units'))
if (storedIndentType) {
if (storedIndentType === 'tab') {
this.editor.setOption('indentWithTabs', true)
if (cookieTabSize) {
this.editor.setOption('indentUnit', cookieTabSize)
if (storedTabSize) {
this.editor.setOption('indentUnit', storedTabSize)
}
} else if (cookieIndentType === 'space') {
} else if (storedIndentType === 'space') {
this.editor.setOption('indentWithTabs', false)
if (cookieSpaceUnits) {
this.editor.setOption('indentUnit', cookieSpaceUnits)
if (storedSpaceUnits) {
this.editor.setOption('indentUnit', storedSpaceUnits)
}
}
}
if (cookieTabSize) {
this.editor.setOption('tabSize', cookieTabSize)
if (storedTabSize) {
this.editor.setOption('tabSize', storedTabSize)
}

var type = this.statusIndicators.find('.indent-type')
Expand All @@ -449,14 +516,10 @@ export default class Editor {

const setType = () => {
if (this.editor.getOption('indentWithTabs')) {
Cookies.set('indent_type', 'tab', {
expires: 365
})
Storage.set('indent_type', 'tab')
type.text('Tab Size:')
} else {
Cookies.set('indent_type', 'space', {
expires: 365
})
Storage.set('indent_type', 'space')
type.text('Spaces:')
}
}
Expand All @@ -465,13 +528,9 @@ export default class Editor {
const setUnit = () => {
var unit = this.editor.getOption('indentUnit')
if (this.editor.getOption('indentWithTabs')) {
Cookies.set('tab_size', unit, {
expires: 365
})
Storage.set('tab_size', unit)
} else {
Cookies.set('space_units', unit, {
expires: 365
})
Storage.set('space_units', unit)
}
widthLabel.text(unit)
}
Expand All @@ -480,16 +539,16 @@ export default class Editor {
type.click(() => {
if (this.editor.getOption('indentWithTabs')) {
this.editor.setOption('indentWithTabs', false)
cookieSpaceUnits = parseInt(Cookies.get('space_units'))
if (cookieSpaceUnits) {
this.editor.setOption('indentUnit', cookieSpaceUnits)
storedSpaceUnits = parseInt(Storage.get('space_units'))
if (storedSpaceUnits) {
this.editor.setOption('indentUnit', storedSpaceUnits)
}
} else {
this.editor.setOption('indentWithTabs', true)
cookieTabSize = parseInt(Cookies.get('tab_size'))
if (cookieTabSize) {
this.editor.setOption('indentUnit', cookieTabSize)
this.editor.setOption('tabSize', cookieTabSize)
storedTabSize = parseInt(Storage.get('tab_size'))
if (storedTabSize) {
this.editor.setOption('indentUnit', storedTabSize)
this.editor.setOption('tabSize', storedTabSize)
}
}
setType()
Expand Down Expand Up @@ -525,9 +584,9 @@ export default class Editor {
}

setKeymap () {
var cookieKeymap = Cookies.get('keymap')
if (cookieKeymap) {
this.editor.setOption('keyMap', cookieKeymap)
var storedKeymap = Storage.get('keymap')
if (storedKeymap) {
this.editor.setOption('keyMap', storedKeymap)
}

var label = this.statusIndicators.find('.ui-keymap-label')
Expand All @@ -537,9 +596,7 @@ export default class Editor {

const setKeymapLabel = () => {
var keymap = this.editor.getOption('keyMap')
Cookies.set('keymap', keymap, {
expires: 365
})
Storage.set('keymap', keymap)
label.text(keymap)
this.restoreOverrideEditorKeymap()
this.setOverrideBrowserKeymap()
Expand Down Expand Up @@ -572,17 +629,15 @@ export default class Editor {

const setTheme = theme => {
this.editor.setOption('theme', theme)
Cookies.set('theme', theme, {
expires: 365
})
Storage.set('theme', theme)
this.statusIndicators.find('.status-theme li').removeClass('active')
this.statusIndicators.find(`.status-theme li[value="${theme}"]`).addClass('active')
}

const cookieTheme = Cookies.get('theme')
if (cookieTheme && availableThemes.find(theme => cookieTheme === theme.value)) {
setTheme(cookieTheme)
activateThemeListItem(cookieTheme)
const storedTheme = Storage.get('theme')
if (storedTheme && availableThemes.find(theme => storedTheme === theme.value)) {
setTheme(storedTheme)
activateThemeListItem(storedTheme)
} else {
activateThemeListItem(this.editor.getOption('theme'))
}
Expand Down Expand Up @@ -613,10 +668,10 @@ export default class Editor {
}

getExistingSpellcheckLang () {
const cookieSpellcheck = Cookies.get('spellcheck')
const storedSpellcheck = Storage.get('spellcheck')

if (cookieSpellcheck) {
return cookieSpellcheck === 'false' ? undefined : cookieSpellcheck
if (storedSpellcheck) {
return storedSpellcheck === 'false' ? undefined : storedSpellcheck
} else {
return undefined
}
Expand All @@ -637,18 +692,18 @@ export default class Editor {
return $(`<li value="${lang.value}"><a>${lang.name}</a></li>`)
}))

const cookieSpellcheck = Cookies.get('spellcheck')
if (cookieSpellcheck) {
const storedSpellcheck = Storage.get('spellcheck')
if (storedSpellcheck) {
let mode = null
let lang = 'en_US'

if (cookieSpellcheck === 'false' || !cookieSpellcheck) {
if (storedSpellcheck === 'false' || !storedSpellcheck) {
mode = defaultEditorMode
this.activateSpellcheckListItem(false)
} else {
mode = 'spell-checker'
if (supportLanguageCodes.includes(cookieSpellcheck)) {
lang = cookieSpellcheck
if (supportLanguageCodes.includes(storedSpellcheck)) {
lang = storedSpellcheck
}
this.setSpellcheckLang(lang)
}
Expand All @@ -674,17 +729,13 @@ export default class Editor {
if (lang === 'disabled') {
spellcheckToggle.removeClass('active')

Cookies.set('spellcheck', false, {
expires: 365
})
Storage.set('spellcheck', 'false')

self.editor.setOption('mode', defaultEditorMode)
} else {
spellcheckToggle.addClass('active')

Cookies.set('spellcheck', lang, {
expires: 365
})
Storage.set('spellcheck', lang)

self.editor.setOption('mode', 'spell-checker')
}
Expand All @@ -703,12 +754,10 @@ export default class Editor {
if (!gutters.includes(lintGutter)) {
this.editor.setOption('gutters', [lintGutter, ...gutters])
}
Cookies.set('linter', true, {
expires: 365
})
Storage.set('linter', 'true')
} else {
this.editor.setOption('gutters', gutters.filter(g => g !== lintGutter))
Cookies.remove('linter')
Storage.remove('linter')
}
this.editor.setOption('lint', enable ? linterOptions : false)
}
Expand All @@ -726,7 +775,7 @@ export default class Editor {
updateLinterStatus(!lintEnable)
})

const enable = !!Cookies.get('linter')
const enable = Storage.get('linter') === 'true'
this.toggleLinter.bind(this)(enable)
updateLinterStatus(enable)
}
Expand All @@ -752,12 +801,10 @@ export default class Editor {
'.ui-preferences-override-browser-keymap label > input[type="checkbox"]'
)
if (overrideBrowserKeymap.is(':checked')) {
Cookies.set('preferences-override-browser-keymap', true, {
expires: 365
})
Storage.set('preferences-override-browser-keymap', 'true')
this.restoreOverrideEditorKeymap()
} else {
Cookies.remove('preferences-override-browser-keymap')
Storage.remove('preferences-override-browser-keymap')
this.resetEditorKeymapToBrowserKeymap()
}
}
Expand All @@ -766,10 +813,10 @@ export default class Editor {
var overrideBrowserKeymap = $(
'.ui-preferences-override-browser-keymap label > input[type="checkbox"]'
)
var cookieOverrideBrowserKeymap = Cookies.get(
var storedOverrideBrowserKeymap = Storage.get(
'preferences-override-browser-keymap'
)
if (cookieOverrideBrowserKeymap && cookieOverrideBrowserKeymap === 'true') {
if (storedOverrideBrowserKeymap && storedOverrideBrowserKeymap === 'true') {
overrideBrowserKeymap.prop('checked', true)
} else {
overrideBrowserKeymap.prop('checked', false)
Expand All @@ -779,6 +826,39 @@ export default class Editor {
overrideBrowserKeymap.change(() => {
this.setOverrideBrowserKeymap()
})

// Handle table editor shortcuts preference
var disableTableShortcuts = $(
'.ui-preferences-disable-table-shortcuts label > input[type="checkbox"]'
)
var storedDisableTableShortcuts = Storage.get(
'preferences-disable-table-shortcuts'
)
if (storedDisableTableShortcuts && storedDisableTableShortcuts === 'true') {
disableTableShortcuts.prop('checked', true)
} else {
disableTableShortcuts.prop('checked', false)
}
this.setTableShortcutsPreference()

disableTableShortcuts.change(() => {
this.setTableShortcutsPreference()
})
}

setTableShortcutsPreference () {
var disableTableShortcuts = $(
'.ui-preferences-disable-table-shortcuts label > input[type="checkbox"]'
)
if (disableTableShortcuts.is(':checked')) {
Storage.set('preferences-disable-table-shortcuts', 'true')
} else {
Storage.remove('preferences-disable-table-shortcuts')
}
// Notify table editor about the preference change
if (this.tableEditor) {
this.tableEditor.setShortcutsEnabled(!disableTableShortcuts.is(':checked'))
}
}

init (textit) {
Expand Down
1 change: 1 addition & 0 deletions public/js/lib/editor/statusbar.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
</a>
<ul class="dropdown-menu" aria-labelledby="preferencesLabel">
<li class="ui-preferences-override-browser-keymap"><a><label>Allow override browser keymap&nbsp;&nbsp;<input type="checkbox"></label></a></li>
<li class="ui-preferences-disable-table-shortcuts"><a><label>Disable table editor shortcuts&nbsp;&nbsp;<input type="checkbox"></label></a></li>
</ul>
</div>
<div class="status-keymap dropup pull-right">
Expand Down
Loading