How can I update my inline video/audio/image via `cm.markText` after I have updated the token?

I have already solved the problem where when the user either puts the cursor in or clicks on a image/video/audio then the marker is removed.

The problem is that when I change the marker token from something like ![[video.mp4]] to [[yet_another_video.mp4]] I’ll keep the “old” video.mp4 dom element.

How can I use the “changes” event(or other mechanism) to know when my token has changed and then update those changes by removing the old marker and putting the new one( with the updated version ).

This is the same thing as with GitHub - laobubu/HyperMD: A WYSIWYG Markdown Editor for browsers. Break the Wall between writing and previewing.. Where when you click an image it will collapse/fold and if you change anything it will reflect on the image.



After( on click )

What should my function body should look like?

to deterct the changes to my token?
cm.on("changes", (cm, changes) => { /*What should go in here??? */ })

Do I understand correctly that you’re replacing the ![]() syntax with a widget, and want to move back to text when you click it, and then back to the widget when the selection moves out of it? The general approach would be to keep a set of markers and, after every "changes" event, to synchronize those with the document and new selection, optionally using the information in the changes array to avoid scanning the entire document. That kind of thing is a bit of a pain in version 5.x, because computing the extent of changes is so awkward.

Yes(ty for the anwer).
My question is … how. how do I use the “changes” array to modify that specific token, since we might have two equal links and clear the wrong mark like [[example]] and [[example]].

Does codemirror encourages any sort of design pattern for this type of thing or I’ll just have to hack myself.
also keep this thread open I’ll past my solution here to people can use site: and find this thread.

The easiest way is to just check where the first of the changes is and re-scan lines around that. It is also in principle possible to construct a precise changed range from an array of changes, but since the change representation is really bad in this version, that is much more tricky than it should be. (CodeMirror 6 is a lot better about things like this.)

What’s the easiest way of detecting when the cursor is inside a textMark while inside cursorActivity?

Resolve the mark position with its find method, and compare that to the cursor position. Or, if you don’t have the mark object, find marks at a given position with findMarks.

Thank you.
I could do using the find method on the embed, now how do I make the token as in [[this is the video title.mp4]] not appear while I render the embed, like the token text, is there a way of hiding it, and only showing the video/image/audio instead of its token too?
I’ll post the final code here if someone wants the solution.

markText with the replaceWith option can replace a bit of text with a widget. That what you are looking for?

Yes but the text is not removed.

                        let token_cursor        = cm.getCursor(token.token)

                        let token_line          = token_cursor.line
                        let token_ch            =

                        let video_name          = token.token.replace( "![[", "" ).replace( "]]", "" )
                        printf( "video_name -> ", video_name )

                        let dom                 = document.createElement("video")
                            dom.src             = `${ilse.backend_url}/assets/${video_name}`
                            dom.controls        = true
                            dom.className       = "inline-video"

                        let options             = {
                            clearOnEnter: true,
                            collapsed: false,
                            className: "inline-video",
                            replacedWith: dom,
                            clearWhenEmpty: true,
                            // inclusiveRight: true,
                            // inclusiveLeft: true,
                            // css: "display: none;"

                        let is_on               = true
                        let line_widget         = cm.markText( {line: token_line}, {line: token_line + 1 }, options )

                        cm.on('cursorActivity',  editor => {

                            let cursor          = cm.getCursor();
                            let widget_marks    = cm.findMarks(cursor, { line: cursor.line +1, ch: })
                            let pos             = line_widget.find()
                            let marks           = cm.findMarks(
                                    line:  cursor.line,
                                    ch:  0,
                                    line: cursor.line,


                            let is_cursor_inside_token = marks && marks.length && marks[0].className && marks[0].className === 'inline-video'
                            if( is_cursor_inside_token ) {
                                printf( "Found our stuff" )

                                if( is_on ) {
                                    is_on = false // toggle

                            } else {

                                let is_off = !is_on
                                if( is_off ) {
                                    line_widget.changed() // cheap, instead of re-adding it calling line_widget.changed() is very cheap
                                    // line_widget  = cm.markText( {line: token_line}, {line: token_line+1}, options )
                                    is_on = true // toggle



                        return line_widget