Fix bug where checker could be opened twice and delete nodes (#138)

* Fix bug where checker could be opened twice and delete nodes

Prevents opening the checker while it is already open, which could cause nodes to be deleted

closes MAT-1106

Test Plan:
- Open an RCE and create content that causes an a11y violation
- Click the a11y checker icon to open the a11y checker
- Check the box to apply formatting changes
- Click the a11y checker icon to Open the a11y checker again (without closing it)
- Verify RCE content is not changed, RCE can be edited and used as normal
- Verify a11y checker can be opened again, used as normal

* Update version and changelog

* Update CHANGELOG for real
This commit is contained in:
Jacob DeWar 2023-02-13 17:19:50 -05:00 committed by Ed Schiebel
parent 01aedf4c3f
commit 9da682a35f
4 changed files with 37 additions and 23 deletions

View File

@ -7,7 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
## [4.2.3] - 2023-01-30 ## [4.1.4] - 2023-02-14
- Fixed a bug where the a11y checker could be opened twice and cause
content to become deleted
## [4.1.3] - 2023-01-30
- Change the violation highlight from an absolutely positioned blue box - Change the violation highlight from an absolutely positioned blue box
to an outline created with just CSS to an outline created with just CSS

View File

@ -1,6 +1,6 @@
{ {
"name": "tinymce-a11y-checker", "name": "tinymce-a11y-checker",
"version": "4.1.3", "version": "4.1.4",
"description": "An accessibility checker plugin for TinyMCE.", "description": "An accessibility checker plugin for TinyMCE.",
"main": "lib/plugin.js", "main": "lib/plugin.js",
"module": "es/plugin.js", "module": "es/plugin.js",

View File

@ -53,7 +53,9 @@ export default class Checker extends React.Component {
componentDidMount() { componentDidMount() {
this.props.editor.on("Remove", (editor) => { this.props.editor.on("Remove", (editor) => {
this.setState({ open: false }) this.setState({ open: false }, () => {
this.props.onClose()
})
}) })
} }
@ -282,7 +284,9 @@ export default class Checker extends React.Component {
handleClose() { handleClose() {
this.onLeaveError() this.onLeaveError()
clearIndicators(this.props.editor.dom.doc) clearIndicators(this.props.editor.dom.doc)
this.setState({ open: false }) this.setState({ open: false }, () => {
this.props.onClose()
})
} }
render() { render() {

View File

@ -4,6 +4,7 @@ import Checker from "./components/checker"
import formatMessage from "./format-message" import formatMessage from "./format-message"
import checkNode from "./node-checker" import checkNode from "./node-checker"
let isCheckerOpen = false
let instance let instance
const pendingInstanceCallbacks = [] const pendingInstanceCallbacks = []
const container = document.createElement("div") const container = document.createElement("div")
@ -16,25 +17,29 @@ tinymce.create("tinymce.plugins.AccessibilityChecker", {
ui, ui,
{ done, config, additionalRules, mountNode } { done, config, additionalRules, mountNode }
) { ) {
ReactDOM.render( if (!isCheckerOpen) {
<Checker ReactDOM.render(
getBody={ed.getBody.bind(ed)} <Checker
editor={ed} getBody={ed.getBody.bind(ed)}
additionalRules={additionalRules} editor={ed}
mountNode={mountNode} additionalRules={additionalRules}
/>, mountNode={mountNode}
container, onClose={() => isCheckerOpen = false}
function () { />,
// this is a workaround for react 16 since ReactDOM.render is not container,
// guaranteed to return the instance synchronously (especially if called function () {
// within another component's lifecycle method eg: componentDidMount). see: // this is a workaround for react 16 since ReactDOM.render is not
// https://github.com/facebook/react/issues/10309#issuecomment-318434635 // guaranteed to return the instance synchronously (especially if called
instance = this // within another component's lifecycle method eg: componentDidMount). see:
if (config) getInstance(instance => instance.setConfig(config)) // https://github.com/facebook/react/issues/10309#issuecomment-318434635
pendingInstanceCallbacks.forEach(cb => cb(instance)) instance = this
instance.check(done) if (config) getInstance(instance => instance.setConfig(config))
} pendingInstanceCallbacks.forEach(cb => cb(instance))
) instance.check(done)
}
)
isCheckerOpen = true
}
}) })
ed.addCommand("checkAccessibility", function ( ed.addCommand("checkAccessibility", function (