3
3
// BSD-style license that can be found in the LICENSE file.
4
4
5
5
import 'dart:async' ;
6
- import 'dart:html ' ;
6
+ import 'dart:js_interop ' ;
7
7
8
8
import 'package:markdown/markdown.dart' as md;
9
+ import 'package:web/web.dart' ;
9
10
10
11
import 'highlight.dart' ;
11
12
12
- final markdownInput = querySelector ('#markdown' ) as TextAreaElement ;
13
- final htmlDiv = querySelector ('#html' ) as DivElement ;
14
- final versionSpan = querySelector ('.version' ) as SpanElement ;
13
+ final markdownInput =
14
+ document.querySelector ('#markdown' ) as HTMLTextAreaElement ;
15
+ final htmlDiv = document.querySelector ('#html' ) as HTMLDivElement ;
16
+ final versionSpan = document.querySelector ('.version' ) as HTMLSpanElement ;
15
17
16
- final nullSanitizer = NullTreeSanitizer ();
17
18
const typing = Duration (milliseconds: 150 );
18
19
const introText = '''Markdown is the **best**!
19
20
@@ -26,9 +27,10 @@ const introText = '''Markdown is the **best**!
26
27
* ...and _so much more_...''' ;
27
28
28
29
// Flavor support.
29
- final basicRadio = querySelector ('#basic-radio' ) as HtmlElement ;
30
- final commonmarkRadio = querySelector ('#commonmark-radio' ) as HtmlElement ;
31
- final gfmRadio = querySelector ('#gfm-radio' ) as HtmlElement ;
30
+ final basicRadio = document.querySelector ('#basic-radio' ) as HTMLElement ;
31
+ final commonmarkRadio =
32
+ document.querySelector ('#commonmark-radio' ) as HTMLElement ;
33
+ final gfmRadio = document.querySelector ('#gfm-radio' ) as HTMLElement ;
32
34
md.ExtensionSet ? extensionSet;
33
35
34
36
final extensionSets = {
@@ -54,7 +56,7 @@ void main() {
54
56
}
55
57
56
58
// GitHub is the default extension set.
57
- gfmRadio.attributes[ 'checked' ] = '' ;
59
+ gfmRadio.attributes. getNamedItem ( 'checked' ) ? .value = '' ;
58
60
gfmRadio.querySelector ('.glyph' )! .text = 'radio_button_checked' ;
59
61
extensionSet = extensionSets[gfmRadio.id];
60
62
_renderMarkdown ();
@@ -65,19 +67,16 @@ void main() {
65
67
}
66
68
67
69
void _renderMarkdown ([Event ? event]) {
68
- final markdown = markdownInput.value! ;
70
+ final markdown = markdownInput.value;
69
71
70
- htmlDiv.setInnerHtml (
71
- md.markdownToHtml (markdown, extensionSet: extensionSet),
72
- treeSanitizer: nullSanitizer,
73
- );
72
+ htmlDiv.innerHTML = md.markdownToHtml (markdown, extensionSet: extensionSet);
74
73
75
- for (final block in htmlDiv.querySelectorAll ('pre code' )) {
74
+ for (final block in htmlDiv.querySelectorAll ('pre code' ).items ) {
76
75
try {
77
76
highlightElement (block);
78
77
} catch (e) {
79
- window. console.error ('Error highlighting markdown:' );
80
- window. console.error (e);
78
+ console.error ('Error highlighting markdown:' .toJS );
79
+ console.error (e. toString ().toJS );
81
80
}
82
81
}
83
82
@@ -107,29 +106,36 @@ void _typeItOut(String msg, int pos) {
107
106
}
108
107
109
108
void _switchFlavor (Event e) {
110
- final target = e.currentTarget as HtmlElement ;
111
- if (! target.attributes.containsKey ('checked' )) {
109
+ final target = e.currentTarget as HTMLElement ;
110
+ if (target.attributes.getNamedItem ('checked' ) == null ) {
112
111
if (basicRadio != target) {
113
- basicRadio.attributes.remove ('checked' );
112
+ basicRadio.attributes.safeRemove ('checked' );
114
113
basicRadio.querySelector ('.glyph' )! .text = 'radio_button_unchecked' ;
115
114
}
116
115
if (commonmarkRadio != target) {
117
- commonmarkRadio.attributes.remove ('checked' );
116
+ commonmarkRadio.attributes.safeRemove ('checked' );
118
117
commonmarkRadio.querySelector ('.glyph' )! .text = 'radio_button_unchecked' ;
119
118
}
120
119
if (gfmRadio != target) {
121
- gfmRadio.attributes.remove ('checked' );
120
+ gfmRadio.attributes.safeRemove ('checked' );
122
121
gfmRadio.querySelector ('.glyph' )! .text = 'radio_button_unchecked' ;
123
122
}
124
123
125
- target.attributes[ 'checked' ] = '' ;
124
+ target.attributes. getNamedItem ( 'checked' ) ? .value = '' ;
126
125
target.querySelector ('.glyph' )! .text = 'radio_button_checked' ;
127
126
extensionSet = extensionSets[target.id];
128
127
_renderMarkdown ();
129
128
}
130
129
}
131
130
132
- class NullTreeSanitizer implements NodeTreeSanitizer {
133
- @override
134
- void sanitizeTree (Node node) {}
131
+ extension on NodeList {
132
+ List <Node > get items => [
133
+ for (var i = 0 ; i < length; i++ ) item (i)! ,
134
+ ];
135
+ }
136
+
137
+ extension on NamedNodeMap {
138
+ void safeRemove (String qualifiedName) {
139
+ if (getNamedItem (qualifiedName) != null ) removeNamedItem (qualifiedName);
140
+ }
135
141
}
0 commit comments