mirror of
https://github.com/marktext/marktext.git
synced 2025-05-02 07:31:18 +08:00
A task checked should update related task (#1737)
* A task checked should update related task * Improve code quality * feat: add a option for autoCheck * refactor: put autoCheck in Editor part * refactor: refactor some functions and methods 1. fix autoCheck was not passed to the editor 2. put getParentCheckBox and cumputeChecboxStatus functions in utils folder. 3. put setCheckBoxState, updateParentsCheckBoxState, updateChildrenCheckBoxState and listItemCheckBoxClick methods in clickCtrl.js file.
This commit is contained in:
parent
862324387c
commit
3103aee8ed
@ -40,6 +40,7 @@ Preferences can be controlled and modified in the settings window or via the `pr
|
||||
| autoGuessEncoding | Boolean | true | Try to automatically guess the file encoding when opening files |
|
||||
| trimTrailingNewline | Enum | `2` | Ensure a single trailing newline or whether trailing newlines should be removed: `0`: trim all trailing newlines, `1`: ensure single newline, `2`: auto detect, `3`: disabled. |
|
||||
| hideLinkPopup | Boolean | false | It will not show the link popup when hover over the link if set `hideLinkPopup` to true |
|
||||
| autoCheck | Boolean | false | Whether to automatically check related task. Optional value: true, false |
|
||||
|
||||
#### Markdown
|
||||
|
||||
|
@ -200,6 +200,11 @@
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"autoCheck": {
|
||||
"description": "Editor--Whether to automatically check related task.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"preferLooseListItem": {
|
||||
"description": "Markdown--The preferred list type",
|
||||
"type": "boolean"
|
||||
|
@ -264,6 +264,7 @@ export const MUYA_DEFAULT_OPTION = {
|
||||
vegaTheme: 'latimes', // excel / ggplot2 / quartz / vox / fivethirtyeight / dark / latimes
|
||||
hideQuickInsertHint: false,
|
||||
hideLinkPopup: false,
|
||||
autoCheck: false,
|
||||
// Whether we should set spellcheck attribute on our container to highlight misspelled words.
|
||||
// NOTE: The browser is not able to correct misspelled words words without a custom
|
||||
// implementation like in Mark Text.
|
||||
|
@ -1,6 +1,8 @@
|
||||
import selection from '../selection'
|
||||
import { isMuyaEditorElement } from '../selection/dom'
|
||||
import { HAS_TEXT_BLOCK_REG, CLASS_OR_ID } from '../config'
|
||||
import { getParentCheckBox } from '../utils/getParentCheckBox'
|
||||
import { cumputeCheckboxStatus } from '../utils/cumputeCheckBoxStatus'
|
||||
|
||||
const clickCtrl = ContentState => {
|
||||
ContentState.prototype.clickHandler = function (event) {
|
||||
@ -193,6 +195,50 @@ const clickCtrl = ContentState => {
|
||||
this.cursor = { start, end }
|
||||
}
|
||||
}
|
||||
|
||||
ContentState.prototype.setCheckBoxState = function (checkbox, checked) {
|
||||
checkbox.checked = checked
|
||||
const block = this.getBlock(checkbox.id)
|
||||
block.checked = checked
|
||||
checkbox.classList.toggle(CLASS_OR_ID.AG_CHECKBOX_CHECKED)
|
||||
}
|
||||
|
||||
ContentState.prototype.updateParentsCheckBoxState = function (checkbox) {
|
||||
let parent = getParentCheckBox(checkbox)
|
||||
while (parent !== null) {
|
||||
const checked = cumputeCheckboxStatus(parent)
|
||||
if (parent.checked !== checked) {
|
||||
this.setCheckBoxState(parent, checked)
|
||||
parent = getParentCheckBox(parent)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ContentState.prototype.updateChildrenCheckBoxState = function (checkbox, checked) {
|
||||
const checkboxes = checkbox.parentElement.querySelectorAll(`input ~ ul .${CLASS_OR_ID.AG_TASK_LIST_ITEM_CHECKBOX}`)
|
||||
const len = checkboxes.length
|
||||
for (let i = 0; i < len; i++) {
|
||||
const checkbox = checkboxes[i]
|
||||
if (checkbox.checked !== checked) {
|
||||
this.setCheckBoxState(checkbox, checked)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// handle task list item checkbox click
|
||||
ContentState.prototype.listItemCheckBoxClick = function (checkbox) {
|
||||
const { checked } = checkbox
|
||||
this.setCheckBoxState(checkbox, checked)
|
||||
|
||||
// A task checked, then related task should be update
|
||||
const { autoCheck } = this.muya.options
|
||||
if (autoCheck) {
|
||||
this.updateChildrenCheckBoxState(checkbox, checked)
|
||||
this.updateParentsCheckBoxState(checkbox)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default clickCtrl
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { tokenizer } from '../parser/'
|
||||
import { conflict } from '../utils'
|
||||
import { CLASS_OR_ID } from '../config'
|
||||
|
||||
const INLINE_UPDATE_FRAGMENTS = [
|
||||
'(?:^|\n) {0,3}([*+-] {1,4})', // Bullet list
|
||||
@ -17,14 +16,6 @@ const INLINE_UPDATE_FRAGMENTS = [
|
||||
const INLINE_UPDATE_REG = new RegExp(INLINE_UPDATE_FRAGMENTS.join('|'), 'i')
|
||||
|
||||
const updateCtrl = ContentState => {
|
||||
// handle task list item checkbox click
|
||||
ContentState.prototype.listItemCheckBoxClick = function (checkbox) {
|
||||
const { checked, id } = checkbox
|
||||
const block = this.getBlock(id)
|
||||
block.checked = checked
|
||||
checkbox.classList.toggle(CLASS_OR_ID.AG_CHECKBOX_CHECKED)
|
||||
}
|
||||
|
||||
ContentState.prototype.checkSameMarkerOrDelimiter = function (list, markerOrDelimiter) {
|
||||
if (!/ol|ul/.test(list.type)) return false
|
||||
return list.children[0].bulletMarkerOrDelimiter === markerOrDelimiter
|
||||
@ -303,7 +294,7 @@ const updateCtrl = ContentState => {
|
||||
}
|
||||
}
|
||||
if (TASK_LIST_REG.test(listItemText)) {
|
||||
const [,, tasklist,,,,] = listItemText.match(INLINE_UPDATE_REG) || [] // eslint-disable-line comma-spacing
|
||||
const [, , tasklist, , , ,] = listItemText.match(INLINE_UPDATE_REG) || [] // eslint-disable-line comma-spacing
|
||||
return this.updateTaskListItem(block, 'tasklist', tasklist)
|
||||
} else {
|
||||
return block
|
||||
|
11
src/muya/lib/utils/cumputeCheckBoxStatus.js
Normal file
11
src/muya/lib/utils/cumputeCheckBoxStatus.js
Normal file
@ -0,0 +1,11 @@
|
||||
export const cumputeCheckboxStatus = function (parentCheckbox) {
|
||||
const children = parentCheckbox.parentElement.lastElementChild.children
|
||||
const len = children.length
|
||||
for (let i = 0; i < len; i++) {
|
||||
const checkbox = children[i].firstElementChild
|
||||
if (checkbox.checked === false) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
10
src/muya/lib/utils/getParentCheckBox.js
Normal file
10
src/muya/lib/utils/getParentCheckBox.js
Normal file
@ -0,0 +1,10 @@
|
||||
import { CLASS_OR_ID } from '../config'
|
||||
|
||||
export const getParentCheckBox = function (checkbox) {
|
||||
const parent = checkbox.parentElement.parentElement.parentElement
|
||||
if (parent.id !== CLASS_OR_ID.AG_EDITOR_ID) {
|
||||
return parent.firstElementChild
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
@ -147,6 +147,7 @@ export default {
|
||||
editorFontFamily: state => state.preferences.editorFontFamily,
|
||||
hideQuickInsertHint: state => state.preferences.hideQuickInsertHint,
|
||||
hideLinkPopup: state => state.preferences.hideLinkPopup,
|
||||
autoCheck: state => state.preferences.autoCheck,
|
||||
editorLineWidth: state => state.preferences.editorLineWidth,
|
||||
imageInsertAction: state => state.preferences.imageInsertAction,
|
||||
imageFolderPath: state => state.preferences.imageFolderPath,
|
||||
@ -319,6 +320,12 @@ export default {
|
||||
editor.setOptions({ hideLinkPopup: value })
|
||||
}
|
||||
},
|
||||
autoCheck: function (value, oldValue) {
|
||||
const { editor } = this
|
||||
if (value !== oldValue && editor) {
|
||||
editor.setOptions({ autoCheck: value })
|
||||
}
|
||||
},
|
||||
codeFontSize: function (value, oldValue) {
|
||||
if (value !== oldValue) {
|
||||
addCommonStyle({
|
||||
@ -477,7 +484,8 @@ export default {
|
||||
theme,
|
||||
sequenceTheme,
|
||||
spellcheckerEnabled,
|
||||
hideLinkPopup
|
||||
hideLinkPopup,
|
||||
autoCheck
|
||||
} = this
|
||||
|
||||
// use muya UI plugins
|
||||
@ -520,6 +528,7 @@ export default {
|
||||
footnote,
|
||||
hideQuickInsertHint,
|
||||
hideLinkPopup,
|
||||
autoCheck,
|
||||
sequenceTheme,
|
||||
spellcheckEnabled: spellcheckerEnabled,
|
||||
imageAction: this.imageAction.bind(this),
|
||||
|
@ -109,6 +109,11 @@
|
||||
:bool="hideLinkPopup"
|
||||
:onChange="value => onSelectChange('hideLinkPopup', value)"
|
||||
></bool>
|
||||
<bool
|
||||
description="Whether to automatically check related task."
|
||||
:bool="autoCheck"
|
||||
:onChange="value => onSelectChange('autoCheck', value)"
|
||||
></bool>
|
||||
<separator></separator>
|
||||
<text-box
|
||||
description="Defines the maximum editor area width. An empty string or suffixes of ch (characters), px (pixels) or % (percentage) are allowed."
|
||||
@ -167,6 +172,7 @@ export default {
|
||||
trimUnnecessaryCodeBlockEmptyLines: state => state.preferences.trimUnnecessaryCodeBlockEmptyLines,
|
||||
hideQuickInsertHint: state => state.preferences.hideQuickInsertHint,
|
||||
hideLinkPopup: state => state.preferences.hideLinkPopup,
|
||||
autoCheck: state => state.preferences.autoCheck,
|
||||
editorLineWidth: state => state.preferences.editorLineWidth,
|
||||
defaultEncoding: state => state.preferences.defaultEncoding,
|
||||
autoGuessEncoding: state => state.preferences.autoGuessEncoding,
|
||||
|
@ -36,6 +36,7 @@ const state = {
|
||||
hideQuickInsertHint: false,
|
||||
imageInsertAction: 'folder',
|
||||
hideLinkPopup: false,
|
||||
autoCheck: false,
|
||||
|
||||
preferLooseListItem: true,
|
||||
bulletListMarker: '-',
|
||||
|
@ -32,6 +32,7 @@
|
||||
"hideQuickInsertHint": false,
|
||||
"imageInsertAction": "path",
|
||||
"hideLinkPopup": false,
|
||||
"autoCheck": false,
|
||||
|
||||
"preferLooseListItem": true,
|
||||
"bulletListMarker": "-",
|
||||
|
Loading…
Reference in New Issue
Block a user