OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 import 'dart:html'; | 5 import 'dart:html'; |
6 import 'dart:convert'; | 6 import 'dart:convert'; |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'package:source_maps/source_maps.dart'; | 8 import 'package:source_maps/source_maps.dart'; |
9 | 9 |
10 Element targetFileName = querySelector("#target_filename"); | 10 Element targetFileName = querySelector("#target_filename"); |
(...skipping 13 matching lines...) Expand all Loading... |
24 generatedOutput.style.height = "${window.innerHeight / 3 - 50}px"; | 24 generatedOutput.style.height = "${window.innerHeight / 3 - 50}px"; |
25 selectedSource.style.height = "${window.innerHeight / 3 - 50}px"; | 25 selectedSource.style.height = "${window.innerHeight / 3 - 50}px"; |
26 decodedMap.style.height = "${window.innerHeight / 3 - 50}px"; | 26 decodedMap.style.height = "${window.innerHeight / 3 - 50}px"; |
27 originalMap.style.height = "${window.innerHeight / 3 - 50}px"; | 27 originalMap.style.height = "${window.innerHeight / 3 - 50}px"; |
28 } | 28 } |
29 | 29 |
30 Future getMap() { | 30 Future getMap() { |
31 Completer c = new Completer(); | 31 Completer c = new Completer(); |
32 HttpRequest httpRequest = new HttpRequest(); | 32 HttpRequest httpRequest = new HttpRequest(); |
33 httpRequest | 33 httpRequest |
34 ..open('GET', '/map') | 34 ..open('GET', '/map') |
35 ..onLoadEnd.listen((_) => c.complete(httpRequest.responseText)) | 35 ..onLoadEnd.listen((_) => c.complete(httpRequest.responseText)) |
36 ..send(''); | 36 ..send(''); |
37 return c.future; | 37 return c.future; |
38 } | 38 } |
39 | 39 |
40 Future fetchFile(String path) { | 40 Future fetchFile(String path) { |
41 Completer c = new Completer(); | 41 Completer c = new Completer(); |
42 HttpRequest httpRequest = new HttpRequest(); | 42 HttpRequest httpRequest = new HttpRequest(); |
43 sourceFileName.text = path; | 43 sourceFileName.text = path; |
44 httpRequest | 44 httpRequest |
45 ..open('GET', path) | 45 ..open('GET', path) |
46 ..onLoadEnd.listen((_) => c.complete(httpRequest.responseText)) | 46 ..onLoadEnd.listen((_) => c.complete(httpRequest.responseText)) |
47 ..send(''); | 47 ..send(''); |
48 return c.future; | 48 return c.future; |
49 } | 49 } |
50 | 50 |
51 displaySource(String filename, List<String> source, TargetEntry entry) { | 51 displaySource(String filename, List<String> source, TargetEntry entry) { |
52 int line = entry.sourceLine; | 52 int line = entry.sourceLine; |
53 int column = entry.sourceColumn; | 53 int column = entry.sourceColumn; |
54 int nameId = entry.sourceNameId; | 54 int nameId = entry.sourceNameId; |
55 String id = nameId == null ? null : sourceMap.names[nameId]; | 55 String id = nameId == null ? null : sourceMap.names[nameId]; |
56 selectedSource.children.clear(); | 56 selectedSource.children.clear(); |
57 SpanElement marker = new SpanElement() | 57 SpanElement marker = new SpanElement() |
58 ..className = "marker" | 58 ..className = "marker" |
59 ..appendText("*"); | 59 ..appendText("*"); |
60 for (int pos = 0; pos < source.length; pos++) { | 60 for (int pos = 0; pos < source.length; pos++) { |
61 String l = source[pos]; | 61 String l = source[pos]; |
62 if (pos != line) { | 62 if (pos != line) { |
63 selectedSource.children.add(l.isEmpty ? new BRElement() : new DivElement() | 63 selectedSource.children.add(l.isEmpty ? new BRElement() : new DivElement() |
64 ..appendText(l)); | 64 ..appendText(l)); |
65 } else { | 65 } else { |
66 selectedSource.children.add(new DivElement() | 66 selectedSource.children.add(new DivElement() |
67 ..appendText(l.substring(0, column)) | 67 ..appendText(l.substring(0, column)) |
68 ..children.add(marker) | 68 ..children.add(marker) |
69 ..appendText(l.substring(column))); | 69 ..appendText(l.substring(column))); |
70 } | 70 } |
71 } | 71 } |
72 sourceFileName.text = filename; | 72 sourceFileName.text = filename; |
73 marker.scrollIntoView(); | 73 marker.scrollIntoView(); |
74 } | 74 } |
75 | 75 |
76 void highlightSelectedSpan(TargetEntry entry, TargetLineEntry lineEntry) { | 76 void highlightSelectedSpan(TargetEntry entry, TargetLineEntry lineEntry) { |
77 selectedOutputSpan.children.clear(); | 77 selectedOutputSpan.children.clear(); |
78 String spanEndCol; | 78 String spanEndCol; |
79 TargetEntry spanEnd; | 79 TargetEntry spanEnd; |
(...skipping 19 matching lines...) Expand all Loading... |
99 if (entry.sourceUrlId == null) { | 99 if (entry.sourceUrlId == null) { |
100 targetSpan += ' Source: unknown'; | 100 targetSpan += ' Source: unknown'; |
101 selectedOutputSpan.children.add(getTextElement(targetSpan)); | 101 selectedOutputSpan.children.add(getTextElement(targetSpan)); |
102 return; | 102 return; |
103 } | 103 } |
104 | 104 |
105 String source = sourceMap.urls[entry.sourceUrlId]; | 105 String source = sourceMap.urls[entry.sourceUrlId]; |
106 String sourceName = source.substring(source.lastIndexOf('/') + 1); | 106 String sourceName = source.substring(source.lastIndexOf('/') + 1); |
107 String sourcePoint = | 107 String sourcePoint = |
108 'Source: Line ${entry.sourceLine} Col. ${entry.sourceColumn}'; | 108 'Source: Line ${entry.sourceLine} Col. ${entry.sourceColumn}'; |
109 sourcePoint += | 109 sourcePoint += entry.sourceNameId == null |
110 entry.sourceNameId == null ? '' | 110 ? '' |
111 : ' (${sourceMap.names[entry.sourceNameId]})'; | 111 : ' (${sourceMap.names[entry.sourceNameId]})'; |
112 sourcePoint += ' in $sourceName'; | 112 sourcePoint += ' in $sourceName'; |
113 selectedOutputSpan.children.add(getTextElement(targetSpan)); | 113 selectedOutputSpan.children.add(getTextElement(targetSpan)); |
114 selectedOutputSpan.children.add(new BRElement()); | 114 selectedOutputSpan.children.add(new BRElement()); |
115 selectedOutputSpan.children.add(getTextElement(sourcePoint)); | 115 selectedOutputSpan.children.add(getTextElement(sourcePoint)); |
116 | 116 |
117 if (highlightedMapEntry != null) { | 117 if (highlightedMapEntry != null) { |
118 highlightedMapEntry[0].style.background = 'white'; | 118 highlightedMapEntry[0].style.background = 'white'; |
119 highlightedMapEntry[1].style.background = 'white'; | 119 highlightedMapEntry[1].style.background = 'white'; |
120 } | 120 } |
121 | 121 |
122 String highlightColor = "#99ff99"; | 122 String highlightColor = "#99ff99"; |
123 highlightedMapEntry = targetEntryMap[entry]; | 123 highlightedMapEntry = targetEntryMap[entry]; |
124 highlightedMapEntry[0] | 124 highlightedMapEntry[0] |
125 ..scrollIntoView() | 125 ..scrollIntoView() |
126 ..style.backgroundColor = highlightColor; | 126 ..style.backgroundColor = highlightColor; |
127 highlightedMapEntry[1] | 127 highlightedMapEntry[1] |
128 ..scrollIntoView() | 128 ..scrollIntoView() |
129 ..style.backgroundColor = highlightColor; | 129 ..style.backgroundColor = highlightColor; |
130 highlightedMapEntry[1].onMouseOver.listen((e) { | 130 highlightedMapEntry[1].onMouseOver.listen((e) { |
131 selectedOutputSpan.style.zIndex = "2"; | 131 selectedOutputSpan.style.zIndex = "2"; |
132 selectedOutputSpan.style.visibility = "visible"; | 132 selectedOutputSpan.style.visibility = "visible"; |
133 selectedOutputSpan.style.top = "${decodedMap.offsetTo(document.body).y + | 133 selectedOutputSpan.style.top = "${decodedMap.offsetTo(document.body).y + |
134 decodedMap.clientHeight - 20}px"; | 134 decodedMap.clientHeight - 20}px"; |
135 selectedOutputSpan.style.left = "${decodedMap.offsetTo(document.body).x}px"; | 135 selectedOutputSpan.style.left = "${decodedMap.offsetTo(document.body).x}px"; |
136 selectedOutputSpan.style.width= "${decodedMap.clientWidth}px"; | 136 selectedOutputSpan.style.width = "${decodedMap.clientWidth}px"; |
137 }); | 137 }); |
138 | 138 |
139 highlightedMapEntry[1].onMouseOut.listen( (e) { | 139 highlightedMapEntry[1].onMouseOut.listen((e) { |
140 selectedOutputSpan.style.visibility = "hidden"; | 140 selectedOutputSpan.style.visibility = "hidden"; |
141 }); | 141 }); |
142 | 142 |
143 adjustDivHeightsToWindow(); | 143 adjustDivHeightsToWindow(); |
144 } | 144 } |
145 | 145 |
146 void loadSource(TargetEntry entry) { | 146 void loadSource(TargetEntry entry) { |
147 if (entry.sourceUrlId == null) { | 147 if (entry.sourceUrlId == null) { |
148 return; | 148 return; |
149 } | 149 } |
150 | 150 |
151 String source = sourceMap.urls[entry.sourceUrlId]; | 151 String source = sourceMap.urls[entry.sourceUrlId]; |
152 fetchFile(new Uri(path: "/file", | 152 fetchFile( |
153 queryParameters: {"path": source}).toString()).then((text) | 153 new Uri(path: "/file", queryParameters: {"path": source}).toString()) |
154 => displaySource(source, text.split("\n"), entry)); | 154 .then((text) => displaySource(source, text.split("\n"), entry)); |
155 selectedSource.text = "loading"; | 155 selectedSource.text = "loading"; |
156 } | 156 } |
157 | 157 |
158 SpanElement createSpan(String content, TargetEntry entry, | 158 SpanElement createSpan( |
159 TargetLineEntry lineEntry) { | 159 String content, TargetEntry entry, TargetLineEntry lineEntry) { |
160 return new SpanElement() | 160 return new SpanElement() |
161 ..addEventListener('click', (e) { | 161 ..addEventListener('click', (e) { |
162 loadSource(entry); | 162 loadSource(entry); |
163 highlightSelectedSpan(entry, lineEntry); | 163 highlightSelectedSpan(entry, lineEntry); |
164 }, false) | 164 }, false) |
165 ..className = "range${entry.sourceUrlId % 4}" | 165 ..className = "range${entry.sourceUrlId % 4}" |
166 ..appendText(content); | 166 ..appendText(content); |
167 } | 167 } |
168 | 168 |
169 Element getLineNumberElement(int line) { | 169 Element getLineNumberElement(int line) { |
170 SpanElement result = new SpanElement(); | 170 SpanElement result = new SpanElement(); |
171 result.style.fontFamily = "Courier"; | 171 result.style.fontFamily = "Courier"; |
172 result.style.fontSize = "10pt"; | 172 result.style.fontSize = "10pt"; |
173 result.appendText("${line} "); | 173 result.appendText("${line} "); |
174 return result; | 174 return result; |
175 } | 175 } |
176 | 176 |
177 Element getTextElement(String text) { | 177 Element getTextElement(String text) { |
178 SpanElement result = new SpanElement(); | 178 SpanElement result = new SpanElement(); |
179 result.text = text; | 179 result.text = text; |
180 return result; | 180 return result; |
181 } | 181 } |
182 | 182 |
183 addTargetLine(int lineNumber, String content, TargetLineEntry lineEntry) { | 183 addTargetLine(int lineNumber, String content, TargetLineEntry lineEntry) { |
184 if (content.isEmpty) { | 184 if (content.isEmpty) { |
185 generatedOutput.children.add(new DivElement() | 185 generatedOutput.children |
186 ..children.add(getLineNumberElement(lineNumber))); | 186 .add(new DivElement()..children.add(getLineNumberElement(lineNumber))); |
187 return; | 187 return; |
188 } | 188 } |
189 if (lineEntry == null) { | 189 if (lineEntry == null) { |
190 generatedOutput.children.add(new DivElement() | 190 generatedOutput.children.add(new DivElement() |
191 ..children.add(getLineNumberElement(lineNumber)) | 191 ..children.add(getLineNumberElement(lineNumber)) |
192 ..children.add(getTextElement(content))); | 192 ..children.add(getTextElement(content))); |
193 return; | 193 return; |
194 } | 194 } |
195 DivElement div = new DivElement(); | 195 DivElement div = new DivElement(); |
196 div.children.add(getLineNumberElement(lineNumber)); | 196 div.children.add(getLineNumberElement(lineNumber)); |
197 | 197 |
198 int pos = 0; | 198 int pos = 0; |
199 TargetEntry previous = null; | 199 TargetEntry previous = null; |
200 for (TargetEntry next in lineEntry.entries) { | 200 for (TargetEntry next in lineEntry.entries) { |
201 if (previous == null) { | 201 if (previous == null) { |
202 if (pos < next.column) { | 202 if (pos < next.column) { |
(...skipping 22 matching lines...) Expand all Loading... |
225 } | 225 } |
226 generatedOutput.children.add(div); | 226 generatedOutput.children.add(div); |
227 } | 227 } |
228 | 228 |
229 // Display the target source in the HTML. | 229 // Display the target source in the HTML. |
230 void displayTargetSource() { | 230 void displayTargetSource() { |
231 List<TargetLineEntry> targetLines = sourceMap.lines; | 231 List<TargetLineEntry> targetLines = sourceMap.lines; |
232 int linesIndex = 0; | 232 int linesIndex = 0; |
233 for (int line = 0; line < target.length; line++) { | 233 for (int line = 0; line < target.length; line++) { |
234 TargetLineEntry entry = null; | 234 TargetLineEntry entry = null; |
235 if (linesIndex < targetLines.length | 235 if (linesIndex < targetLines.length && |
236 && targetLines[linesIndex].line == line) { | 236 targetLines[linesIndex].line == line) { |
237 entry = targetLines[linesIndex]; | 237 entry = targetLines[linesIndex]; |
238 linesIndex++; | 238 linesIndex++; |
239 } | 239 } |
240 if (entry != null) { | 240 if (entry != null) { |
241 addTargetLine(line, target[line], entry); | 241 addTargetLine(line, target[line], entry); |
242 } else { | 242 } else { |
243 addTargetLine(line, target[line], null); | 243 addTargetLine(line, target[line], null); |
244 } | 244 } |
245 } | 245 } |
246 } | 246 } |
247 | 247 |
248 String getMappedData(String mapFileContent) { | 248 String getMappedData(String mapFileContent) { |
249 // Source map contains mapping information in this format: | 249 // Source map contains mapping information in this format: |
250 // "mappings": "A;A,yC;" | 250 // "mappings": "A;A,yC;" |
251 List<String> mapEntry = mapFileContent.split('mappings'); | 251 List<String> mapEntry = mapFileContent.split('mappings'); |
252 return mapEntry[mapEntry.length-1].split('"')[2]; | 252 return mapEntry[mapEntry.length - 1].split('"')[2]; |
253 } | 253 } |
254 | 254 |
255 SpanElement createMapSpan(String segment) { | 255 SpanElement createMapSpan(String segment) { |
256 return new SpanElement()..text = segment; | 256 return new SpanElement()..text = segment; |
257 } | 257 } |
258 | 258 |
259 SpanElement createDecodedMapSpan(TargetEntry entry) { | 259 SpanElement createDecodedMapSpan(TargetEntry entry) { |
260 return new SpanElement()..text = '(${entry.column}, ${entry.sourceUrlId},' | 260 return new SpanElement() |
261 ' ${entry.sourceLine},' | 261 ..text = '(${entry.column}, ${entry.sourceUrlId},' |
262 ' ${entry.sourceColumn})'; | 262 ' ${entry.sourceLine},' |
| 263 ' ${entry.sourceColumn})'; |
263 } | 264 } |
264 | 265 |
265 displayMap(String mapFileContent) { | 266 displayMap(String mapFileContent) { |
266 String mappedData = getMappedData(mapFileContent); | 267 String mappedData = getMappedData(mapFileContent); |
267 int sourceMapLine = 0; | 268 int sourceMapLine = 0; |
268 for (String group in mappedData.split(';')) { | 269 for (String group in mappedData.split(';')) { |
269 if (group.length == 0) continue; | 270 if (group.length == 0) continue; |
270 | 271 |
271 List<String> segments = []; | 272 List<String> segments = []; |
272 if (!group.contains(',')) { | 273 if (!group.contains(',')) { |
(...skipping 22 matching lines...) Expand all Loading... |
295 ++entryNumber; | 296 ++entryNumber; |
296 targetEntryMap.putIfAbsent(entry, () => [orignalMapSpan, decodedMapSpan]); | 297 targetEntryMap.putIfAbsent(entry, () => [orignalMapSpan, decodedMapSpan]); |
297 } | 298 } |
298 originalMap.children.add(new BRElement()); | 299 originalMap.children.add(new BRElement()); |
299 decodedMap.children.add(new BRElement()); | 300 decodedMap.children.add(new BRElement()); |
300 ++sourceMapLine; | 301 ++sourceMapLine; |
301 } | 302 } |
302 } | 303 } |
303 | 304 |
304 void main() { | 305 void main() { |
305 Future load(String q) => fetchFile(new Uri(path: "/file", queryParameters: { | 306 Future load(String q) => fetchFile( |
306 "path": q | 307 new Uri(path: "/file", queryParameters: {"path": q}).toString()); |
307 }).toString()); | |
308 | 308 |
309 getMap().then((mapFileName) { | 309 getMap().then((mapFileName) { |
310 load(mapFileName).then((mapFileContent) { | 310 load(mapFileName).then((mapFileContent) { |
311 sourceMap = new SingleMapping.fromJson(JSON.decode(mapFileContent)); | 311 sourceMap = new SingleMapping.fromJson(JSON.decode(mapFileContent)); |
312 displayMap(mapFileContent); | 312 displayMap(mapFileContent); |
313 targetFileName.text = sourceMap.targetUrl; | 313 targetFileName.text = sourceMap.targetUrl; |
314 load(targetFileName.text).then((targetFileContent) { | 314 load(targetFileName.text).then((targetFileContent) { |
315 target = targetFileContent.split('\n'); | 315 target = targetFileContent.split('\n'); |
316 displayTargetSource(); | 316 displayTargetSource(); |
317 adjustDivHeightsToWindow(); | 317 adjustDivHeightsToWindow(); |
318 }); | 318 }); |
319 }); | 319 }); |
320 }); | 320 }); |
321 | 321 |
322 sourceFileName.text = "<source not selected>"; | 322 sourceFileName.text = "<source not selected>"; |
323 } | 323 } |
OLD | NEW |