codemirror / codemirror5

In-browser code editor (version 5, legacy)
http://codemirror.net/5/
MIT License
26.82k stars 4.97k forks source link

Cannot read properties of undefined (reading 'length') #6805

Open whereyougo opened 3 years ago

whereyougo commented 3 years ago

environment:

vue3, vue-cli ^4.5 "codemirror": "^5.63.3" chrome browser 93.0.4577.82(x86_64)

problem:

switch cm from small window to fullscreen, then click any where of the fullscreen invoke exception message in the browser console tab: codemirror.js?56b3:2354 Uncaught TypeError: Cannot read properties of undefined (reading 'length') at mapFromLineView (codemirror.js?56b3:2354) at prepareMeasureForLine (codemirror.js?56b3:2407) at cursorCoords (codemirror.js?56b3:2658) at scrollPosIntoView (codemirror.js?56b3:3460) at endOperation_finish (codemirror.js?56b3:3917) at endOperations (codemirror.js?56b3:3836) at eval (codemirror.js?56b3:3819) at finishOperation (codemirror.js?56b3:2058) at endOperation (codemirror.js?56b3:3816) at HTMLDivElement.eval (codemirror.js?56b3:3953)

the vue function to switch cm view mode is: fullScreen(type){ cm.setOption("fullScreen", !cm.getOption("fullScreen")); }

i have debug the code where exception throws, function mapFromLineView(lineView, line, lineN) { if (lineView.line == line) { return {map: lineView.measure.map, cache: lineView.measure.cache} } for (var i = 0; i < lineView.rest.length; i++) { if (lineView.rest[i] == line) { return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]} } } for (var i$1 = 0; i$1 < lineView.rest.length; i$1++) { if (lineNo(lineView.rest[i$1]) > lineN) { return {map: lineView.measure.maps[i$1], cache: lineView.measure.caches[i$1], before: true} } } } when click on the fullscreen cm the method mapFromLineView will execute second for loop(first if not return true),the lineView.rest is undefine, so invoke "Uncaught TypeError: Cannot read properties of undefined (reading 'length')" exception

every click anywhere will throw the same exception

Xnip2021-10-22_01-00-36

marijnh commented 3 years ago

Does 367b5e7b help for this?

whereyougo commented 3 years ago

thanks for your attention,the fix 367b5e7 resolved the "undefined (reading 'length') " problem,but i get a new exception: Uncaught TypeError: Cannot read properties of undefined (reading 'map') at prepareMeasureForLine (codemirror.js?56b3:2412) at cursorCoords (codemirror.js?56b3:2660) at scrollPosIntoView (codemirror.js?56b3:3462) at endOperation_finish (codemirror.js?56b3:3919) at endOperations (codemirror.js?56b3:3838) at eval (codemirror.js?56b3:3821) at finishOperation (codemirror.js?56b3:2058) at endOperation (codemirror.js?56b3:3818) at HTMLDivElement.eval (codemirror.js?56b3:3955) image method mapFromLineView not throw "undefined (reading 'length')" exception,but return undefined result then invoke another "undefined (reading 'map')" exception

the step i used to test 367b5e7 : 1.git checkout 367b5e7 2.fix "version" from "5.63.3" to "5.63.4" of package.json 3.npm pack this cmd will generate a file named codemirror-5.63.4.tgz 4.in my test projetct "codemirror_demo" fix version of package.json to "codemirror": "^5.63.4" then install this npm package by npm install /xx/xx/codemirror-5.63.4.tgz 5.use "npm run serve" to start my codemirror_demo project, view FullScreen page by http://localhost:8080, click fullscreen button then click the area of cm,chrome chonsole will throw new exception undefined (reading 'map') ,illustrate the fixed code has been executed but not resolved problem image

i have try use codemirror without vue and all works fine(can be tested by codemirror_demo project with http://localhost:8080/test.html), but it not ok when use vue. There is another problem when i set initial content for cm then click the area of cm will throw same exception of undefined (reading 'length') but with difference run stack : Uncaught TypeError: Cannot read properties of undefined (reading 'length') at mapFromLineView (codemirror.js?56b3:2354) at prepareMeasureForLine (codemirror.js?56b3:2407) at coordsCharInner (codemirror.js?56b3:2754) at coordsChar (codemirror.js?56b3:2722) at posFromMouse (codemirror.js?56b3:2973) at CodeMirror.onMouseDown (codemirror.js?56b3:7343) at HTMLDivElement.eval (codemirror.js?56b3:3952)

marijnh commented 3 years ago

On closer look, this should never happen, event without the the patch I added. I don't know a lot about vue, but I do know that it adds invasive proxies around objects in some situations. Are you using your CodeMirror instance in such a way that vue will mess with it? That is not supported by this library.

whereyougo commented 3 years ago

All right,I will use codemirror without vue. I forgot paste the codemirror_demo project url last reply.I post it here easy for you test if you're interested.

losetime commented 3 years ago

I also encountered this problem using vue3. It was indeed caused by the intrusion of object proxy. Don't use ref or reactive. You can solve this problem by directly defining an instance.

whereyougo commented 3 years ago

thanks for your feedback. Can you introduce more detail of the way "directly defining an instance" @losetime

losetime commented 3 years ago

define variables directly, do not use responsive, such as: let instances = null const initEditor = () => { instances = CodeMirror.fromTextArea(textarea, options}) } This is currently feasible

whereyougo commented 3 years ago

Thank you.It works. I have add this demo to the codemirror_demo project

lennokiki commented 2 years ago

let instances = null const initEditor = () => { instances = CodeMirror.fromTextArea(textarea, options}) }

Yes, you are right. Should not using vue3 ref to define codeMirror editor instance. God! it's bothering me two days, thank you.