blob: 6ddf95e6bcb7e4649aeb61baff1aebd5006502ce [file] [log] [blame]
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library sourcemap.html_parts;
import 'sourcemap_html_helper.dart';
class HtmlPrintContext {
final int lineNoWidth;
final bool usePre;
HtmlPrintContext({
this.lineNoWidth,
this.usePre: true});
}
enum HtmlPartKind {
CODE,
LINE,
CONST,
NEWLINE,
TEXT,
ANCHOR,
}
abstract class HtmlPart {
void printHtmlOn(StringBuffer buffer, HtmlPrintContext context) {}
toJson();
static HtmlPart fromJson(json) {
if (json is String) {
return new ConstHtmlPart(json);
} else {
switch (HtmlPartKind.values[json['kind']]) {
case HtmlPartKind.LINE:
return HtmlLine.fromJson(json);
case HtmlPartKind.CODE:
return CodeLine.fromJson(json);
case HtmlPartKind.CONST:
return ConstHtmlPart.fromJson(json);
case HtmlPartKind.NEWLINE:
return const NewLine();
case HtmlPartKind.TEXT:
return HtmlText.fromJson(json);
case HtmlPartKind.ANCHOR:
return AnchorHtmlPart.fromJson(json);
}
}
}
}
class ConstHtmlPart implements HtmlPart {
final String html;
const ConstHtmlPart(this.html);
@override
void printHtmlOn(StringBuffer buffer, HtmlPrintContext context) {
buffer.write(html);
}
toJson() {
return {'kind': HtmlPartKind.CONST.index, 'html': html};
}
static ConstHtmlPart fromJson(Map json) {
return new ConstHtmlPart(json['html']);
}
}
class NewLine implements HtmlPart {
const NewLine();
void printHtmlOn(StringBuffer buffer, HtmlPrintContext context) {
if (context.usePre) {
buffer.write('\n');
} else {
buffer.write('<br/>');
}
}
toJson() {
return {'kind': HtmlPartKind.NEWLINE.index};
}
}
class HtmlText implements HtmlPart {
final String text;
const HtmlText(this.text);
void printHtmlOn(StringBuffer buffer, HtmlPrintContext context) {
String escaped = escape(text);
buffer.write(escaped);
}
toJson() {
return {'kind': HtmlPartKind.TEXT.index, 'text': text};
}
static HtmlText fromJson(Map json) {
return new HtmlText(json['text']);
}
}
class AnchorHtmlPart implements HtmlPart {
final String color;
final String name;
final String href;
final String title;
final String onclick;
final String onmouseover;
final String onmouseout;
AnchorHtmlPart({
this.color,
this.name,
this.href,
this.title,
this.onclick,
this.onmouseover,
this.onmouseout});
@override
void printHtmlOn(StringBuffer buffer, HtmlPrintContext context) {
buffer.write('<a');
if (href != null) {
buffer.write(' href="${href}"');
}
if (name != null) {
buffer.write(' name="${name}"');
}
if (title != null) {
buffer.write(' title="${escape(title)}"');
}
buffer.write(' style="${color}"');
if (onclick != null) {
buffer.write(' onclick="${onclick}"');
}
if (onmouseover != null) {
buffer.write(' onmouseover="${onmouseover}"');
}
if (onmouseout != null) {
buffer.write(' onmouseout="${onmouseout}"');
}
buffer.write('>');
}
toJson() {
return {
'kind': HtmlPartKind.ANCHOR.index,
'color': color,
'name': name,
'href': href,
'title': title,
'onclick': onclick,
'onmouseover': onmouseover,
'onmouseout': onmouseout};
}
static AnchorHtmlPart fromJson(Map json) {
return new AnchorHtmlPart(
color: json['color'],
name: json['name'],
href: json['href'],
title: json['title'],
onclick: json['onclick'],
onmouseover: json['onmouseover'],
onmouseout: json['onmouseout']);
}
}
class HtmlLine implements HtmlPart {
final List<HtmlPart> htmlParts = <HtmlPart>[];
@override
void printHtmlOn(StringBuffer htmlBuffer, HtmlPrintContext context) {
for (HtmlPart part in htmlParts) {
part.printHtmlOn(htmlBuffer, context);
}
}
Map toJson() {
return {
'kind': HtmlPartKind.LINE.index,
'html': htmlParts.map((p) => p.toJson()).toList(),
};
}
static CodeLine fromJson(Map json) {
HtmlLine line = new HtmlLine();
json['html'].forEach((part) => line.htmlParts.add(HtmlPart.fromJson(part)));
return line;
}
}
class CodeLine extends HtmlLine {
final int lineNo;
final int offset;
final StringBuffer codeBuffer = new StringBuffer();
final List<HtmlPart> htmlParts = <HtmlPart>[];
// TODO(johnniwinther): Make annotations serializable.
final List<Annotation> annotations = <Annotation>[];
String _code;
CodeLine(this.lineNo, this.offset);
String get code {
if (_code == null) {
_code = codeBuffer.toString();
}
return _code;
}
@override
void printHtmlOn(StringBuffer htmlBuffer, HtmlPrintContext context) {
htmlBuffer.write(lineNumber(
lineNo, width: context.lineNoWidth, useNbsp: !context.usePre));
for (HtmlPart part in htmlParts) {
part.printHtmlOn(htmlBuffer, context);
}
}
Map toJson() {
return {
'kind': HtmlPartKind.CODE.index,
'lineNo': lineNo,
'offset': offset,
'code': code,
'html': htmlParts.map((p) => p.toJson()).toList(),
};
}
static CodeLine fromJson(Map json) {
CodeLine line = new CodeLine(json['lineNo'], json['offset']);
line.codeBuffer.write(json['code']);
json['html'].forEach((part) => line.htmlParts.add(HtmlPart.fromJson(part)));
return line;
}
}