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:
He Linming 2020-02-11 21:46:24 +08:00 committed by GitHub
parent 862324387c
commit 3103aee8ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 94 additions and 12 deletions

View File

@ -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

View File

@ -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"

View File

@ -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.

View File

@ -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

View File

@ -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

View 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
}

View 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
}
}

View File

@ -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),

View File

@ -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,

View File

@ -36,6 +36,7 @@ const state = {
hideQuickInsertHint: false,
imageInsertAction: 'folder',
hideLinkPopup: false,
autoCheck: false,
preferLooseListItem: true,
bulletListMarker: '-',

View File

@ -32,6 +32,7 @@
"hideQuickInsertHint": false,
"imageInsertAction": "path",
"hideLinkPopup": false,
"autoCheck": false,
"preferLooseListItem": true,
"bulletListMarker": "-",