(packed:any[], attributes:{[id:string]: any|undefined})
| 805 | |
| 806 | // This is an update to an existing document, so we need to figure out what got added and removed. |
| 807 | updateDocument(packed:any[], attributes:{[id:string]: any|undefined}) { |
| 808 | if(packed.length % 4 !== 0) throw new Error("Invalid span packing, unable to load."); |
| 809 | |
| 810 | let addedDebug = []; |
| 811 | let removedDebug = []; |
| 812 | |
| 813 | this.cm.operation(() => { |
| 814 | this.reloading = true; |
| 815 | let doc = this.cm.getDoc(); |
| 816 | |
| 817 | let cursorLine = doc.getCursor().line; |
| 818 | |
| 819 | // Find all runtime-controlled spans (e.g. syntax highlighting, errors) that are unchanged and mark them as such. |
| 820 | // Unmarked spans will be swept afterwards. |
| 821 | // Set editor-controlled spans aside. We'll match them up to maintain id stability afterwards |
| 822 | let controlledOffsets = {}; |
| 823 | let touchedIds = {}; |
| 824 | for(let i = 0; i < packed.length; i += 4) { |
| 825 | // if(isEditorControlled(packed[i + 2])) |
| 826 | // console.info(packed[i + 2], debugTokenWithContext(doc.getValue(), packed[i], packed[i + 1])); |
| 827 | |
| 828 | |
| 829 | let start = packed[i]; |
| 830 | let type = packed[i + 2]; |
| 831 | if(isEditorControlled(type)) { |
| 832 | if(!controlledOffsets[type]) controlledOffsets[type] = [i]; |
| 833 | else controlledOffsets[type].push(i); |
| 834 | } else { |
| 835 | let from = doc.posFromIndex(packed[i]); |
| 836 | let to = doc.posFromIndex(packed[i + 1]); |
| 837 | let type = packed[i + 2]; |
| 838 | let id = packed[i + 3]; |
| 839 | |
| 840 | let source = attributes[id] || {}; |
| 841 | source.type = type; |
| 842 | source.id = id; |
| 843 | if(type === "document_comment") { |
| 844 | source.delay = 1000; |
| 845 | } |
| 846 | |
| 847 | let spans = this.findSpansAt(from, type); |
| 848 | let unchanged = false; |
| 849 | for(let span of spans) { |
| 850 | let loc = span.find(); |
| 851 | if(loc && samePosition(to, loc.to) && span.sourceEquals(source)) { |
| 852 | span.source = source; |
| 853 | if(span.refresh) span.refresh(); |
| 854 | if(type === "document_comment") { |
| 855 | (span as any).updateWidget(); |
| 856 | } |
| 857 | touchedIds[span.id] = true; |
| 858 | unchanged = true; |
| 859 | break; |
| 860 | } |
| 861 | } |
| 862 | |
| 863 | if(!unchanged) { |
| 864 | let span = this.markSpan(from, to, source); |
no test coverage detected