[dart] Upgrade to Dart 2.12 and its null-safety features

This commit is contained in:
Lucien Cartier-Tilet 2021-03-30 18:54:31 +02:00
parent 0e8e894056
commit 291fc9111b
Signed by: phundrak
GPG Key ID: BD7789E705CB8DCA
5 changed files with 39 additions and 42 deletions

View File

@ -5,7 +5,7 @@ homepage: https://labs.phundrak.com/phundrak/org-website-backend
author: Lucien Cartier-Tilet <lucien@phundrak.com> author: Lucien Cartier-Tilet <lucien@phundrak.com>
environment: environment:
sdk: '>=2.7.0 <3.0.0' sdk: '>=2.12.0 <3.0.0'
dependencies: dependencies:

View File

@ -35,7 +35,7 @@ final icons = {
}; };
// Get the current pages title // Get the current pages title
String getPageTitle() => querySelector('title').text; String getPageTitle() => querySelector('title')!.text!;
// Create the home button // Create the home button
Future<Element> makeHome() async { Future<Element> makeHome() async {
@ -45,7 +45,7 @@ Future<Element> makeHome() async {
'afterBegin', 'afterBegin',
Element.a() Element.a()
..attributes['href'] = '/' ..attributes['href'] = '/'
..append(makeIcon(icons['home']))); ..append(makeIcon(icons['home']!)));
} }
// Create a clickable icon // Create a clickable icon
@ -61,7 +61,7 @@ Future<Element> makePages() async {
..append(Element.a() ..append(Element.a()
..attributes['tabindex'] = '-1' ..attributes['tabindex'] = '-1'
..attributes['href'] = 'javascript:void(0)' ..attributes['href'] = 'javascript:void(0)'
..append(makeIcon(icons['pages']))) ..append(makeIcon(icons['pages']!)))
..classes.addAll(['nav-item', 'has-dropdown']) ..classes.addAll(['nav-item', 'has-dropdown'])
..append(Element.ul() ..append(Element.ul()
..attributes['id'] = 'drop-page' ..attributes['id'] = 'drop-page'
@ -87,23 +87,23 @@ Future<Element> makeShare() async {
..append(Element.a() ..append(Element.a()
..attributes['href'] = 'javascript:void(0)' ..attributes['href'] = 'javascript:void(0)'
..attributes['tabindex'] = '-1' ..attributes['tabindex'] = '-1'
..append(makeIcon(icons['share']))) ..append(makeIcon(icons['share']!)))
..append(Element.ul() ..append(Element.ul()
..classes.add('dropdown') ..classes.add('dropdown')
..attributes['id'] = 'drop-share' ..attributes['id'] = 'drop-share'
..append(makeShareLink( ..append(makeShareLink(
makeIcon(icons['twitter']), makeIcon(icons['twitter']!),
'https://twitter.com/share?text=${getPageTitle()}' 'https://twitter.com/share?text=${getPageTitle()}'
'&url=${window.location.href}')) '&url=${window.location.href}'))
..append(makeShareLink(makeIcon(icons['reddit']), ..append(makeShareLink(makeIcon(icons['reddit']!),
'https://www.reddit.com/submit?title=${getPageTitle()}s&url=${window.location.href}')) 'https://www.reddit.com/submit?title=${getPageTitle()}s&url=${window.location.href}'))
..append(makeShareLink(makeIcon(icons['email']), ..append(makeShareLink(makeIcon(icons['email']!),
'mailto:?subject=${getPageTitle}&body=${window.location.href}')) 'mailto:?subject=$getPageTitle&body=${window.location.href}'))
..append(makeShareLink( ..append(makeShareLink(
makeIcon(icons['linkedin']), makeIcon(icons['linkedin']!),
'https://www.linkedin.com/shareArticle?mini=true&url=${window.location.href}' 'https://www.linkedin.com/shareArticle?mini=true&url=${window.location.href}'
'&title=${getPageTitle()}')) '&title=${getPageTitle()}'))
..append(makeShareLink(makeIcon(icons['facebook']), ..append(makeShareLink(makeIcon(icons['facebook']!),
'https://www.facebook.com/sharer/sharer.php?u=${window.location.href}'))); 'https://www.facebook.com/sharer/sharer.php?u=${window.location.href}')));
} }
@ -125,7 +125,7 @@ Future<Element> makeThemeChanger() async {
..attributes['tabindex'] = '-1' ..attributes['tabindex'] = '-1'
..append(Element.span() ..append(Element.span()
..style.verticalAlign = 'top' ..style.verticalAlign = 'top'
..append(makeIcon(icons['theme'])))) ..append(makeIcon(icons['theme']!))))
..append(Element.ul() ..append(Element.ul()
..classes.add('dropdown') ..classes.add('dropdown')
..attributes['id'] = 'theme-dropdown' ..attributes['id'] = 'theme-dropdown'
@ -144,7 +144,7 @@ Future<Element> makeToc() async {
..append(Element.a() ..append(Element.a()
..attributes['tabindex'] = '-1' ..attributes['tabindex'] = '-1'
..attributes['href'] = 'javascript:void(0)' ..attributes['href'] = 'javascript:void(0)'
..append(makeIcon(icons['toc']))); ..append(makeIcon(icons['toc']!)));
} }
// Add a navbar atop of the HTML body, containing: // Add a navbar atop of the HTML body, containing:

View File

@ -15,29 +15,29 @@ Future<String> fetchRemoteSitemap() async {
// Parse the list of elements and detect pages from this list // Parse the list of elements and detect pages from this list
Map<String, String> detectPages(List<Element> t_sitemap, Map<String, String> detectPages(List<Element> t_sitemap,
[String t_prefix, Map<String, String> t_links]) { [String? t_prefix, Map<String, String>? t_links]) {
t_links ??= <String, String>{}; t_links ??= <String, String>{};
// parse each element in sitemap // parse each element in sitemap
for (var elem in t_sitemap) { for (var elem in t_sitemap) {
// if its a link // if its a link
if (elem.innerHtml.startsWith('<a')) { if (elem.innerHtml!.startsWith('<a')) {
elem = elem.firstChild; elem = elem.children[0];
final url = elem.attributes['href']; final url = elem.attributes['href']!;
final text = elem.firstChild.text; final text = elem.children[0].text;
if (excluded_keywords.contains(text) || if (excluded_keywords.contains(text) ||
excluded_keywords.contains(url.substring(0, url.length - 5))) { excluded_keywords.contains(url.substring(0, url.length - 5))) {
continue; continue;
} }
t_links['/$url'] = (t_prefix == null) ? text : '$text ($t_prefix)'; t_links!['/$url'] = ((t_prefix == null) ? text : '$text ($t_prefix)')!;
} else { } else {
final prefix = (t_prefix == null) final prefix = (t_prefix == null)
? elem.firstChild.text.replaceAll('\n', '') ? elem.firstChild!.text!.replaceAll('\n', '')
: '$t_prefix / ${elem.firstChild.text}'.replaceAll('\n', ''); : '$t_prefix / ${elem.firstChild!.text}'.replaceAll('\n', '');
t_links = detectPages(elem.children[0].children, prefix, t_links); t_links = detectPages(elem.children[0].children, prefix, t_links);
} }
} }
return t_links; return t_links!;
} }
// This function returns a Map which contains all links to languages detected // This function returns a Map which contains all links to languages detected
@ -45,13 +45,13 @@ Map<String, String> detectPages(List<Element> t_sitemap,
Future<Map<String, String>> parseSitemap() async { Future<Map<String, String>> parseSitemap() async {
final content = await fetchRemoteSitemap(); final content = await fetchRemoteSitemap();
final sitemap = Element.ul()..innerHtml = content; final sitemap = Element.ul()..innerHtml = content;
final sitemapNodes = sitemap.querySelector('ul').children; final sitemapNodes = sitemap.querySelector('ul')!.children;
return detectPages(sitemapNodes); return detectPages(sitemapNodes);
} }
Future<void> createSitemap() async { Future<void> createSitemap() async {
final sitemap = await parseSitemap(); final sitemap = await parseSitemap();
final pages = querySelector('#drop-page'); final pages = querySelector('#drop-page')!;
sitemap.forEach((url, name) { sitemap.forEach((url, name) {
final link = Element.li() final link = Element.li()
..classes.add('dropdown-item') ..classes.add('dropdown-item')

View File

@ -13,7 +13,7 @@ Future<Element> makeHeader() async {
..attributes['alt'] = 'Logo' ..attributes['alt'] = 'Logo'
..attributes['height'] = '150px' ..attributes['height'] = '150px'
..attributes['width'] = '150px') ..attributes['width'] = '150px')
..append(querySelector('h1')); ..append(querySelector('h1')!);
final subt = header.querySelector('.subtitle'); final subt = header.querySelector('.subtitle');
if (subt != null) { if (subt != null) {
header.append(subt); header.append(subt);
@ -32,8 +32,8 @@ Future<void> wrapTables() async {
// All images that are not nested inside a link will be linkified to themselves. // All images that are not nested inside a link will be linkified to themselves.
Future<void> linkifyImg() async { Future<void> linkifyImg() async {
querySelectorAll('img').forEach((img) { querySelectorAll('img').forEach((img) {
if (img.parent.tagName == 'P') { if (img.parent!.tagName == 'P') {
final link = Element.a()..attributes['href'] = img.attributes['src']; final link = Element.a()..attributes['href'] = img.attributes['src']!;
img.insertAdjacentElement('beforeBegin', link); img.insertAdjacentElement('beforeBegin', link);
link.append(img); link.append(img);
} }
@ -61,10 +61,10 @@ Future<void> reorganizeHtml() async {
await linkifyImg(); await linkifyImg();
// Add navbar to page // Add navbar to page
querySelector('body').insertAdjacentElement('afterBegin', navbar); querySelector('body')!.insertAdjacentElement('afterBegin', navbar);
// Add headet to page // Add headet to page
querySelector('#content').insertAdjacentElement('beforeBegin', header); querySelector('#content')!.insertAdjacentElement('beforeBegin', header);
// Add correct class to TOC // Add correct class to TOC
final toc = (querySelector('#table-of-contents') ?? final toc = (querySelector('#table-of-contents') ??
@ -72,7 +72,7 @@ Future<void> reorganizeHtml() async {
..attributes['id'] = 'table-of-contents' ..attributes['id'] = 'table-of-contents'
..innerText = 'Table of Contents Unavailable')) ..innerText = 'Table of Contents Unavailable'))
..classes.add('dropdown'); ..classes.add('dropdown');
navbar.querySelector('#toc-drop').append(toc); navbar.querySelector('#toc-drop')!.append(toc);
// Remove all <br> tags from HTML // Remove all <br> tags from HTML
querySelectorAll('br').forEach((br) => br.remove()); querySelectorAll('br').forEach((br) => br.remove());

View File

@ -2,22 +2,19 @@ import 'dart:html' show window, querySelector;
final localStorage = window.localStorage; final localStorage = window.localStorage;
Future<void> setTheme([String theme]) async { Future<void> setTheme([String? theme]) async {
final currentTheme = theme ?? localStorage['theme'] ?? theme ??= localStorage['theem'] ??
() { (window.matchMedia('(prefers-color-scheme: dark)').matches
final devicePrefersDark = ? 'dark'
window.matchMedia('(prefers-color-scheme: dark)').matches; : 'light');
return devicePrefersDark ? 'nord' : 'light'; localStorage['theme'] = theme;
}(); querySelector('body')!
localStorage['theme'] = currentTheme;
querySelector('body')
..classes.clear() ..classes.clear()
..classes.add(currentTheme); ..classes.add(theme);
} }
void enableThemeChanger() { void enableThemeChanger() {
final themes = <String>['light', 'dark', 'nord', 'black']; final themes = <String>['light', 'dark', 'nord', 'black'];
themes.forEach((theme) => themes.forEach((theme) =>
querySelector('#${theme}Btn').onClick.listen((_) => setTheme(theme)) querySelector('#${theme}Btn')!.onClick.listen((_) => setTheme(theme)));
);
} }