| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 library sourcemap.html_parts; | 5 library sourcemap.html_parts; |
| 6 | 6 |
| 7 import 'sourcemap_html_helper.dart'; | 7 import 'sourcemap_html_helper.dart'; |
| 8 | 8 |
| 9 class Annotation { | 9 class Annotation { |
| 10 final id; | 10 final id; |
| 11 final int codeOffset; | 11 final int codeOffset; |
| 12 final String title; | 12 final String title; |
| 13 final data; | 13 final data; |
| 14 | 14 |
| 15 Annotation(this.id, this.codeOffset, this.title, {this.data}); | 15 Annotation(this.id, this.codeOffset, this.title, {this.data}); |
| 16 } | 16 } |
| 17 | 17 |
| 18 typedef bool AnnotationFilter(Annotation annotation); | 18 typedef bool AnnotationFilter(Annotation annotation); |
| 19 typedef AnnotationData AnnotationDataFunction( | 19 typedef AnnotationData AnnotationDataFunction(Iterable<Annotation> annotations, |
| 20 Iterable<Annotation> annotations, | |
| 21 {bool forSpan}); | 20 {bool forSpan}); |
| 22 typedef LineData LineDataFunction(lineAnnotation); | 21 typedef LineData LineDataFunction(lineAnnotation); |
| 23 | 22 |
| 24 bool includeAllAnnotation(Annotation annotation) => true; | 23 bool includeAllAnnotation(Annotation annotation) => true; |
| 25 | 24 |
| 26 class LineData { | 25 class LineData { |
| 27 final String lineClass; | 26 final String lineClass; |
| 28 final String lineNumberClass; | 27 final String lineNumberClass; |
| 29 | 28 |
| 30 const LineData({ | 29 const LineData({this.lineClass: 'line', this.lineNumberClass: 'lineNumber'}); |
| 31 this.lineClass: 'line', | |
| 32 this.lineNumberClass: 'lineNumber'}); | |
| 33 } | 30 } |
| 34 | 31 |
| 35 class AnnotationData { | 32 class AnnotationData { |
| 36 final String tag; | 33 final String tag; |
| 37 final Map<String, String> properties; | 34 final Map<String, String> properties; |
| 38 | 35 |
| 39 const AnnotationData({ | 36 const AnnotationData( |
| 40 this.tag: 'a', | 37 {this.tag: 'a', this.properties: const <String, String>{}}); |
| 41 this.properties: const <String, String>{}}); | |
| 42 | 38 |
| 43 int get hashCode => tag.hashCode * 13 + properties.hashCode * 19; | 39 int get hashCode => tag.hashCode * 13 + properties.hashCode * 19; |
| 44 | 40 |
| 45 bool operator ==(other) { | 41 bool operator ==(other) { |
| 46 if (identical(this, other)) return true; | 42 if (identical(this, other)) return true; |
| 47 if (other is! AnnotationData) return false; | 43 if (other is! AnnotationData) return false; |
| 48 return tag == other.tag && | 44 return tag == other.tag && |
| 49 properties.length == other.properties.length && | 45 properties.length == other.properties.length && |
| 50 properties.keys.every((k) => properties[k] == other.properties[k]); | 46 properties.keys.every((k) => properties[k] == other.properties[k]); |
| 51 } | 47 } |
| 52 } | 48 } |
| 53 | 49 |
| 54 AnnotationDataFunction createAnnotationDataFunction( | 50 AnnotationDataFunction createAnnotationDataFunction( |
| 55 {CssColorScheme colorScheme: const SingleColorScheme(), | 51 {CssColorScheme colorScheme: const SingleColorScheme(), |
| 56 ElementScheme elementScheme: const ElementScheme()}) { | 52 ElementScheme elementScheme: const ElementScheme()}) { |
| 57 return (Iterable<Annotation> annotations, {bool forSpan}) { | 53 return (Iterable<Annotation> annotations, {bool forSpan}) { |
| 58 return getAnnotationDataFromSchemes( | 54 return getAnnotationDataFromSchemes(annotations, |
| 59 annotations, | |
| 60 forSpan: forSpan, | 55 forSpan: forSpan, |
| 61 colorScheme: colorScheme, | 56 colorScheme: colorScheme, |
| 62 elementScheme: elementScheme); | 57 elementScheme: elementScheme); |
| 63 }; | 58 }; |
| 64 } | 59 } |
| 65 | 60 |
| 66 LineData getDefaultLineData(data) => const LineData(); | 61 LineData getDefaultLineData(data) => const LineData(); |
| 67 | 62 |
| 68 AnnotationData getAnnotationDataFromSchemes( | 63 AnnotationData getAnnotationDataFromSchemes(Iterable<Annotation> annotations, |
| 69 Iterable<Annotation> annotations, | |
| 70 {bool forSpan, | 64 {bool forSpan, |
| 71 CssColorScheme colorScheme: const SingleColorScheme(), | 65 CssColorScheme colorScheme: const SingleColorScheme(), |
| 72 ElementScheme elementScheme: const ElementScheme()}) { | 66 ElementScheme elementScheme: const ElementScheme()}) { |
| 73 if (colorScheme.showLocationAsSpan != forSpan) return null; | 67 if (colorScheme.showLocationAsSpan != forSpan) return null; |
| 74 Map<String, String> data = <String, String>{}; | 68 Map<String, String> data = <String, String>{}; |
| 75 var id; | 69 var id; |
| 76 if (annotations.length == 1) { | 70 if (annotations.length == 1) { |
| 77 Annotation annotation = annotations.single; | 71 Annotation annotation = annotations.single; |
| 78 if (annotation != null) { | 72 if (annotation != null) { |
| 79 id = annotation.id; | 73 id = annotation.id; |
| 80 data['style'] = colorScheme.singleLocationToCssColor(id); | 74 data['style'] = colorScheme.singleLocationToCssColor(id); |
| 81 data['title'] = annotation.title; | 75 data['title'] = annotation.title; |
| 82 } | 76 } |
| 83 } else { | 77 } else { |
| 84 id = annotations.first.id; | 78 id = annotations.first.id; |
| 85 List ids = []; | 79 List ids = []; |
| 86 for (Annotation annotation in annotations) { | 80 for (Annotation annotation in annotations) { |
| 87 ids.add(annotation.id); | 81 ids.add(annotation.id); |
| 88 } | 82 } |
| 89 data['style'] = colorScheme.multiLocationToCssColor(ids); | 83 data['style'] = colorScheme.multiLocationToCssColor(ids); |
| 90 data['title'] = annotations.map((l) => l.title).join(','); | 84 data['title'] = annotations.map((l) => l.title).join(','); |
| 91 } | 85 } |
| 92 if (id != null) { | 86 if (id != null) { |
| 93 Set ids = annotations.map((l) => l.id).toSet(); | 87 Set ids = annotations.map((l) => l.id).toSet(); |
| 94 data['tag'] = 'a'; | 88 data['tag'] = 'a'; |
| 95 data['name'] = elementScheme.getName(id, ids); | 89 data['name'] = elementScheme.getName(id, ids); |
| 96 data['href'] = elementScheme.getHref(id, ids); | 90 data['href'] = elementScheme.getHref(id, ids); |
| 97 data['onclick'] = elementScheme.onClick(id, ids); | 91 data['onclick'] = elementScheme.onClick(id, ids); |
| 98 data['onmouseover'] = elementScheme.onMouseOver(id, ids); | 92 data['onmouseover'] = elementScheme.onMouseOver(id, ids); |
| 99 data['onmouseout'] = elementScheme.onMouseOut(id, ids); | 93 data['onmouseout'] = elementScheme.onMouseOut(id, ids); |
| 100 return new AnnotationData( | 94 return new AnnotationData(properties: data); |
| 101 properties: data); | |
| 102 } | 95 } |
| 103 return null; | 96 return null; |
| 104 } | 97 } |
| 105 | 98 |
| 106 class HtmlPrintContext { | 99 class HtmlPrintContext { |
| 107 final int lineNoWidth; | 100 final int lineNoWidth; |
| 108 final bool usePre; | 101 final bool usePre; |
| 109 final AnnotationFilter includeAnnotation; | 102 final AnnotationFilter includeAnnotation; |
| 110 final AnnotationDataFunction getAnnotationData; | 103 final AnnotationDataFunction getAnnotationData; |
| 111 final LineDataFunction getLineData; | 104 final LineDataFunction getLineData; |
| 112 | 105 |
| 113 HtmlPrintContext({ | 106 HtmlPrintContext( |
| 114 this.lineNoWidth, | 107 {this.lineNoWidth, |
| 115 this.usePre: true, | 108 this.usePre: true, |
| 116 this.includeAnnotation: includeAllAnnotation, | 109 this.includeAnnotation: includeAllAnnotation, |
| 117 this.getAnnotationData: getAnnotationDataFromSchemes, | 110 this.getAnnotationData: getAnnotationDataFromSchemes, |
| 118 this.getLineData: getDefaultLineData}); | 111 this.getLineData: getDefaultLineData}); |
| 119 | 112 |
| 120 HtmlPrintContext from({ | 113 HtmlPrintContext from( |
| 121 int lineNoWidth, | 114 {int lineNoWidth, |
| 122 bool usePre, | 115 bool usePre, |
| 123 AnnotationFilter includeAnnotation, | 116 AnnotationFilter includeAnnotation, |
| 124 AnnotationDataFunction getAnnotationData, | 117 AnnotationDataFunction getAnnotationData, |
| 125 LineDataFunction getLineData}) { | 118 LineDataFunction getLineData}) { |
| 126 return new HtmlPrintContext( | 119 return new HtmlPrintContext( |
| 127 lineNoWidth: lineNoWidth ?? this.lineNoWidth, | 120 lineNoWidth: lineNoWidth ?? this.lineNoWidth, |
| 128 usePre: usePre ?? this.usePre, | 121 usePre: usePre ?? this.usePre, |
| 129 includeAnnotation: includeAnnotation ?? this.includeAnnotation, | 122 includeAnnotation: includeAnnotation ?? this.includeAnnotation, |
| 130 getAnnotationData: getAnnotationData ?? this.getAnnotationData, | 123 getAnnotationData: getAnnotationData ?? this.getAnnotationData, |
| 131 getLineData: getLineData ?? this.getLineData); | 124 getLineData: getLineData ?? this.getLineData); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 static HtmlText fromJson(Map json, JsonStrategy strategy) { | 224 static HtmlText fromJson(Map json, JsonStrategy strategy) { |
| 232 return new HtmlText(json['text']); | 225 return new HtmlText(json['text']); |
| 233 } | 226 } |
| 234 } | 227 } |
| 235 | 228 |
| 236 class TagPart implements HtmlPart { | 229 class TagPart implements HtmlPart { |
| 237 final String tag; | 230 final String tag; |
| 238 final Map<String, String> properties; | 231 final Map<String, String> properties; |
| 239 final List<HtmlPart> content; | 232 final List<HtmlPart> content; |
| 240 | 233 |
| 241 TagPart( | 234 TagPart(this.tag, |
| 242 this.tag, | 235 {this.properties: const <String, String>{}, |
| 243 {this.properties: const <String, String>{}, | 236 this.content: const <HtmlPart>[]}); |
| 244 this.content: const <HtmlPart>[]}); | |
| 245 | 237 |
| 246 HtmlPartKind get kind => HtmlPartKind.TAG; | 238 HtmlPartKind get kind => HtmlPartKind.TAG; |
| 247 | 239 |
| 248 @override | 240 @override |
| 249 void printHtmlOn(StringBuffer buffer, HtmlPrintContext context) { | 241 void printHtmlOn(StringBuffer buffer, HtmlPrintContext context) { |
| 250 buffer.write('<$tag'); | 242 buffer.write('<$tag'); |
| 251 properties.forEach((String key, String value) { | 243 properties.forEach((String key, String value) { |
| 252 if (value != null) { | 244 if (value != null) { |
| 253 buffer.write(' $key="${value}"'); | 245 buffer.write(' $key="${value}"'); |
| 254 } | 246 } |
| 255 }); | 247 }); |
| 256 buffer.write('>'); | 248 buffer.write('>'); |
| 257 for (HtmlPart child in content) { | 249 for (HtmlPart child in content) { |
| 258 child.printHtmlOn(buffer, context); | 250 child.printHtmlOn(buffer, context); |
| 259 } | 251 } |
| 260 buffer.write('</$tag>'); | 252 buffer.write('</$tag>'); |
| 261 } | 253 } |
| 262 | 254 |
| 263 toJson(JsonStrategy strategy) { | 255 toJson(JsonStrategy strategy) { |
| 264 return { | 256 return { |
| 265 'kind': kind.index, | 257 'kind': kind.index, |
| 266 'tag': tag, | 258 'tag': tag, |
| 267 'properties': properties, | 259 'properties': properties, |
| 268 'content': content.map((p) => p.toJson(strategy)).toList()}; | 260 'content': content.map((p) => p.toJson(strategy)).toList() |
| 261 }; |
| 269 } | 262 } |
| 270 | 263 |
| 271 static TagPart fromJson(Map json, JsonStrategy strategy) { | 264 static TagPart fromJson(Map json, JsonStrategy strategy) { |
| 272 return new TagPart( | 265 return new TagPart(json['tag'], |
| 273 json['tag'], | |
| 274 properties: json['properties'], | 266 properties: json['properties'], |
| 275 content: json['content'].map(HtmlPart.fromJson).toList()); | 267 content: json['content'].map(HtmlPart.fromJson).toList()); |
| 276 } | 268 } |
| 277 } | 269 } |
| 278 | 270 |
| 279 class HtmlLine implements HtmlPart { | 271 class HtmlLine implements HtmlPart { |
| 280 final List<HtmlPart> htmlParts = <HtmlPart>[]; | 272 final List<HtmlPart> htmlParts = <HtmlPart>[]; |
| 281 | 273 |
| 282 HtmlPartKind get kind => HtmlPartKind.LINE; | 274 HtmlPartKind get kind => HtmlPartKind.LINE; |
| 283 | 275 |
| 284 @override | 276 @override |
| 285 void printHtmlOn(StringBuffer htmlBuffer, HtmlPrintContext context) { | 277 void printHtmlOn(StringBuffer htmlBuffer, HtmlPrintContext context) { |
| 286 for (HtmlPart part in htmlParts) { | 278 for (HtmlPart part in htmlParts) { |
| 287 part.printHtmlOn(htmlBuffer, context); | 279 part.printHtmlOn(htmlBuffer, context); |
| 288 } | 280 } |
| 289 } | 281 } |
| 290 | 282 |
| 291 Map toJson(JsonStrategy strategy) { | 283 Map toJson(JsonStrategy strategy) { |
| 292 return { | 284 return { |
| 293 'kind': kind.index, | 285 'kind': kind.index, |
| 294 'html': htmlParts.map((p) => p.toJson(strategy)).toList(), | 286 'html': htmlParts.map((p) => p.toJson(strategy)).toList(), |
| 295 }; | 287 }; |
| 296 } | 288 } |
| 297 | 289 |
| 298 static HtmlLine fromJson(Map json, JsonStrategy strategy) { | 290 static HtmlLine fromJson(Map json, JsonStrategy strategy) { |
| 299 HtmlLine line = new HtmlLine(); | 291 HtmlLine line = new HtmlLine(); |
| 300 json['html'] | 292 json['html'].forEach( |
| 301 .forEach((part) => line.htmlParts | 293 (part) => line.htmlParts.add(HtmlPart.fromJson(part, strategy))); |
| 302 .add(HtmlPart.fromJson(part, strategy))); | |
| 303 return line; | 294 return line; |
| 304 } | 295 } |
| 305 } | 296 } |
| 306 | 297 |
| 307 class CodePart { | 298 class CodePart { |
| 308 final List<Annotation> annotations; | 299 final List<Annotation> annotations; |
| 309 final String subsequentCode; | 300 final String subsequentCode; |
| 310 | 301 |
| 311 CodePart(this.annotations, this.subsequentCode); | 302 CodePart(this.annotations, this.subsequentCode); |
| 312 | 303 |
| 313 void printHtmlOn(StringBuffer buffer, HtmlPrintContext context) { | 304 void printHtmlOn(StringBuffer buffer, HtmlPrintContext context) { |
| 314 Iterable<Annotation> included = | 305 Iterable<Annotation> included = |
| 315 annotations.where(context.includeAnnotation); | 306 annotations.where(context.includeAnnotation); |
| 316 | 307 |
| 317 List<HtmlPart> htmlParts = <HtmlPart>[]; | 308 List<HtmlPart> htmlParts = <HtmlPart>[]; |
| 318 if (included.isNotEmpty) { | 309 if (included.isNotEmpty) { |
| 319 AnnotationData annotationData = | 310 AnnotationData annotationData = |
| 320 context.getAnnotationData(included, forSpan: false); | 311 context.getAnnotationData(included, forSpan: false); |
| 321 AnnotationData annotationDataForSpan = | 312 AnnotationData annotationDataForSpan = |
| 322 context.getAnnotationData(included, forSpan: true); | 313 context.getAnnotationData(included, forSpan: true); |
| 323 | 314 |
| 324 String head = subsequentCode; | 315 String head = subsequentCode; |
| 325 String tail = ''; | 316 String tail = ''; |
| 326 if (subsequentCode.length > 1) { | 317 if (subsequentCode.length > 1) { |
| 327 head = subsequentCode.substring(0, 1); | 318 head = subsequentCode.substring(0, 1); |
| 328 tail = subsequentCode.substring(1); | 319 tail = subsequentCode.substring(1); |
| 329 } | 320 } |
| 330 | 321 |
| 331 void addForSpan(AnnotationData data) { | 322 void addForSpan(AnnotationData data) { |
| 332 htmlParts.add(new TagPart( | 323 htmlParts.add(new TagPart(data.tag, |
| 333 data.tag, | |
| 334 properties: data.properties, | 324 properties: data.properties, |
| 335 content: [new HtmlText(subsequentCode)])); | 325 content: [new HtmlText(subsequentCode)])); |
| 336 } | 326 } |
| 337 | 327 |
| 338 if (annotationData != null && | 328 if (annotationData != null && annotationDataForSpan != null) { |
| 339 annotationDataForSpan != null) { | 329 htmlParts.add(new TagPart(annotationDataForSpan.tag, |
| 340 htmlParts.add(new TagPart( | |
| 341 annotationDataForSpan.tag, | |
| 342 properties: annotationDataForSpan.properties, | 330 properties: annotationDataForSpan.properties, |
| 343 content: [ | 331 content: [ |
| 344 new TagPart( | 332 new TagPart(annotationData.tag, |
| 345 annotationData.tag, | |
| 346 properties: annotationData.properties, | 333 properties: annotationData.properties, |
| 347 content: [new HtmlText(head)]), | 334 content: [new HtmlText(head)]), |
| 348 new HtmlText(tail)])); | 335 new HtmlText(tail) |
| 336 ])); |
| 349 } else if (annotationDataForSpan != null) { | 337 } else if (annotationDataForSpan != null) { |
| 350 htmlParts.add(new TagPart( | 338 htmlParts.add(new TagPart(annotationDataForSpan.tag, |
| 351 annotationDataForSpan.tag, | |
| 352 properties: annotationDataForSpan.properties, | 339 properties: annotationDataForSpan.properties, |
| 353 content: [new HtmlText(subsequentCode)])); | 340 content: [new HtmlText(subsequentCode)])); |
| 354 } else if (annotationData != null) { | 341 } else if (annotationData != null) { |
| 355 htmlParts.add(new TagPart( | 342 htmlParts.add(new TagPart(annotationData.tag, |
| 356 annotationData.tag, | |
| 357 properties: annotationData.properties, | 343 properties: annotationData.properties, |
| 358 content: [new HtmlText(head)])); | 344 content: [new HtmlText(head)])); |
| 359 htmlParts.add(new HtmlText(tail)); | 345 htmlParts.add(new HtmlText(tail)); |
| 360 } else { | 346 } else { |
| 361 htmlParts.add(new HtmlText(subsequentCode)); | 347 htmlParts.add(new HtmlText(subsequentCode)); |
| 362 } | 348 } |
| 363 } else { | 349 } else { |
| 364 htmlParts.add(new HtmlText(subsequentCode)); | 350 htmlParts.add(new HtmlText(subsequentCode)); |
| 365 } | 351 } |
| 366 | 352 |
| 367 for (HtmlPart part in htmlParts) { | 353 for (HtmlPart part in htmlParts) { |
| 368 part.printHtmlOn(buffer, context); | 354 part.printHtmlOn(buffer, context); |
| 369 } | 355 } |
| 370 } | 356 } |
| 371 | 357 |
| 372 Map toJson(JsonStrategy strategy) { | 358 Map toJson(JsonStrategy strategy) { |
| 373 return { | 359 return { |
| 374 'annotations': | 360 'annotations': |
| 375 annotations.map((a) => strategy.encodeAnnotation(a)).toList(), | 361 annotations.map((a) => strategy.encodeAnnotation(a)).toList(), |
| 376 'subsequentCode': subsequentCode, | 362 'subsequentCode': subsequentCode, |
| 377 }; | 363 }; |
| 378 } | 364 } |
| 379 | 365 |
| 380 static CodePart fromJson(Map json, JsonStrategy strategy) { | 366 static CodePart fromJson(Map json, JsonStrategy strategy) { |
| 381 return new CodePart( | 367 return new CodePart( |
| 382 json['annotations'].map((j) => strategy.decodeAnnotation(j)).toList(), | 368 json['annotations'].map((j) => strategy.decodeAnnotation(j)).toList(), |
| 383 json['subsequentCode']); | 369 json['subsequentCode']); |
| 384 } | 370 } |
| 385 } | 371 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 396 toJson(JsonStrategy strategy) { | 382 toJson(JsonStrategy strategy) { |
| 397 return { | 383 return { |
| 398 'kind': kind.index, | 384 'kind': kind.index, |
| 399 'lineNo': lineNo, | 385 'lineNo': lineNo, |
| 400 'lineAnnotation': strategy.encodeLineAnnotation(lineAnnotation), | 386 'lineAnnotation': strategy.encodeLineAnnotation(lineAnnotation), |
| 401 }; | 387 }; |
| 402 } | 388 } |
| 403 | 389 |
| 404 static LineNumber fromJson(Map json, JsonStrategy strategy) { | 390 static LineNumber fromJson(Map json, JsonStrategy strategy) { |
| 405 return new LineNumber( | 391 return new LineNumber( |
| 406 json['lineNo'], | 392 json['lineNo'], strategy.decodeLineAnnotation(json['lineAnnotation'])); |
| 407 strategy.decodeLineAnnotation(json['lineAnnotation'])); | |
| 408 } | 393 } |
| 409 | 394 |
| 410 @override | 395 @override |
| 411 void printHtmlOn(StringBuffer buffer, HtmlPrintContext context) { | 396 void printHtmlOn(StringBuffer buffer, HtmlPrintContext context) { |
| 412 buffer.write(lineNumber( | 397 buffer.write(lineNumber(lineNo, |
| 413 lineNo, | |
| 414 width: context.lineNoWidth, | 398 width: context.lineNoWidth, |
| 415 useNbsp: !context.usePre, | 399 useNbsp: !context.usePre, |
| 416 className: context.getLineData(lineAnnotation).lineNumberClass)); | 400 className: context.getLineData(lineAnnotation).lineNumberClass)); |
| 417 } | 401 } |
| 418 } | 402 } |
| 419 | 403 |
| 420 class CodeLine extends HtmlPart { | 404 class CodeLine extends HtmlPart { |
| 421 final Uri uri; | 405 final Uri uri; |
| 422 final int lineNo; | 406 final int lineNo; |
| 423 final int offset; | 407 final int offset; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 455 } | 439 } |
| 456 | 440 |
| 457 Map toJson(JsonStrategy strategy) { | 441 Map toJson(JsonStrategy strategy) { |
| 458 return { | 442 return { |
| 459 'kind': kind.index, | 443 'kind': kind.index, |
| 460 'lineNo': lineNo, | 444 'lineNo': lineNo, |
| 461 'offset': offset, | 445 'offset': offset, |
| 462 'code': code, | 446 'code': code, |
| 463 'parts': codeParts.map((p) => p.toJson(strategy)).toList(), | 447 'parts': codeParts.map((p) => p.toJson(strategy)).toList(), |
| 464 'annotations': | 448 'annotations': |
| 465 annotations.map((a) => strategy.encodeAnnotation(a)).toList(), | 449 annotations.map((a) => strategy.encodeAnnotation(a)).toList(), |
| 466 'lineAnnotation': lineAnnotation != null | 450 'lineAnnotation': lineAnnotation != null |
| 467 ? strategy.encodeLineAnnotation(lineAnnotation) : null, | 451 ? strategy.encodeLineAnnotation(lineAnnotation) |
| 452 : null, |
| 468 }; | 453 }; |
| 469 } | 454 } |
| 470 | 455 |
| 471 static CodeLine fromJson(Map json, JsonStrategy strategy) { | 456 static CodeLine fromJson(Map json, JsonStrategy strategy) { |
| 472 CodeLine line = new CodeLine( | 457 CodeLine line = new CodeLine(json['lineNo'], json['offset'], |
| 473 json['lineNo'], | |
| 474 json['offset'], | |
| 475 uri: json['uri'] != null ? Uri.parse(json['uri']) : null); | 458 uri: json['uri'] != null ? Uri.parse(json['uri']) : null); |
| 476 line.codeBuffer.write(json['code']); | 459 line.codeBuffer.write(json['code']); |
| 477 json['parts'] | 460 json['parts'].forEach( |
| 478 .forEach((part) => line.codeParts | 461 (part) => line.codeParts.add(CodePart.fromJson(part, strategy))); |
| 479 .add(CodePart.fromJson(part, strategy))); | |
| 480 json['annotations'] | 462 json['annotations'] |
| 481 .forEach((a) => line.annotations | 463 .forEach((a) => line.annotations.add(strategy.decodeAnnotation(a))); |
| 482 .add(strategy.decodeAnnotation(a))); | |
| 483 line.lineAnnotation = json['lineAnnotation'] != null | 464 line.lineAnnotation = json['lineAnnotation'] != null |
| 484 ? strategy.decodeLineAnnotation(json['lineAnnotation']) : null; | 465 ? strategy.decodeLineAnnotation(json['lineAnnotation']) |
| 466 : null; |
| 485 return line; | 467 return line; |
| 486 } | 468 } |
| 487 } | 469 } |
| 488 | 470 |
| 489 class JsonStrategy { | 471 class JsonStrategy { |
| 490 const JsonStrategy(); | 472 const JsonStrategy(); |
| 491 | 473 |
| 492 Map encodeAnnotation(Annotation annotation) { | 474 Map encodeAnnotation(Annotation annotation) { |
| 493 return { | 475 return { |
| 494 'id': annotation.id, | 476 'id': annotation.id, |
| 495 'codeOffset': annotation.codeOffset, | 477 'codeOffset': annotation.codeOffset, |
| 496 'title': annotation.title, | 478 'title': annotation.title, |
| 497 'data': annotation.data, | 479 'data': annotation.data, |
| 498 }; | 480 }; |
| 499 } | 481 } |
| 500 | 482 |
| 501 Annotation decodeAnnotation(Map json) { | 483 Annotation decodeAnnotation(Map json) { |
| 502 return new Annotation( | 484 return new Annotation(json['id'], json['codeOffset'], json['title'], |
| 503 json['id'], | |
| 504 json['codeOffset'], | |
| 505 json['title'], | |
| 506 data: json['data']); | 485 data: json['data']); |
| 507 } | 486 } |
| 508 | 487 |
| 509 | |
| 510 encodeLineAnnotation(lineAnnotation) => lineAnnotation; | 488 encodeLineAnnotation(lineAnnotation) => lineAnnotation; |
| 511 | 489 |
| 512 decodeLineAnnotation(json) => json; | 490 decodeLineAnnotation(json) => json; |
| 513 } | 491 } |
| OLD | NEW |