initialize () { let article = this._getArticle() let editorState = this._getEditorState() forEach(article.getNodes(), node => { CheckRequiredFields.onCreate(this, node) }) // TODO: or should we bind to editorState updates? editorState.addObserver(['document'], this._onDocumentChange, this, { stage: 'update' }) }
_onDocumentChange(change) { let needsUpdate = false const sheet = this.sheet const N = sheet.getRowCount() // TODO we need to detect all relevant changes // for scheduling checks let cells = {} let cols = {} for (let i = 0; i < change.ops.length; i++) { let op = change.ops[i] let nodeId = op.path[0] let node = this._doc.get(nodeId) if (!node) continue // revalidate on all cell changes if (node.type === 'cell') { cells[node.id] = node needsUpdate = true } else if (node.type === 'col') { if (op.path[2] === 'type') { cols[node.id] = node needsUpdate = true } } } // extract all cell ids for changed columns forEach(cols, (column) => { let colIdx = sheet.getColumnIndex(column) for (let i = 0; i < N; i++) { let cell = sheet.getCell(i, colIdx) cells[cell.id] = cell } }) if (needsUpdate) { let newChecks = map(cells) // revalidate existing let revalidations = [] let issues = this.issueManager.getIssues('linter') issues.forEach((issue) => { if (issue.isCellIssue() && !cells[issue.cellId]) { let cell = this._doc.get(issue.cellId) cells[issue.cellId] = cell revalidations.push(cell) } }) this.queue = newChecks.concat(revalidations).concat(this.queue) this.issueManager.clear('linter') if(this.firstShot) { this.restart() } else { this.start() } } }
_initialize() { forEach(this.doc.getNodes(), (node) => { this._onCreate(node) }) }