[dart] Upgrade to Dart 2.12 and its null-safety features
This commit is contained in:
		
							parent
							
								
									0e8e894056
								
							
						
					
					
						commit
						291fc9111b
					
				| @ -5,7 +5,7 @@ homepage: https://labs.phundrak.com/phundrak/org-website-backend | ||||
| author: Lucien Cartier-Tilet <lucien@phundrak.com> | ||||
| 
 | ||||
| environment: | ||||
|   sdk: '>=2.7.0 <3.0.0' | ||||
|   sdk: '>=2.12.0 <3.0.0' | ||||
| 
 | ||||
| dependencies: | ||||
| 
 | ||||
|  | ||||
| @ -35,7 +35,7 @@ final icons = { | ||||
| }; | ||||
| 
 | ||||
| // Get the current page’s title | ||||
| String getPageTitle() => querySelector('title').text; | ||||
| String getPageTitle() => querySelector('title')!.text!; | ||||
| 
 | ||||
| // Create the home button | ||||
| Future<Element> makeHome() async { | ||||
| @ -45,7 +45,7 @@ Future<Element> makeHome() async { | ||||
|         'afterBegin', | ||||
|         Element.a() | ||||
|           ..attributes['href'] = '/' | ||||
|           ..append(makeIcon(icons['home']))); | ||||
|           ..append(makeIcon(icons['home']!))); | ||||
| } | ||||
| 
 | ||||
| // Create a clickable icon | ||||
| @ -61,7 +61,7 @@ Future<Element> makePages() async { | ||||
|     ..append(Element.a() | ||||
|       ..attributes['tabindex'] = '-1' | ||||
|       ..attributes['href'] = 'javascript:void(0)' | ||||
|       ..append(makeIcon(icons['pages']))) | ||||
|       ..append(makeIcon(icons['pages']!))) | ||||
|     ..classes.addAll(['nav-item', 'has-dropdown']) | ||||
|     ..append(Element.ul() | ||||
|       ..attributes['id'] = 'drop-page' | ||||
| @ -87,23 +87,23 @@ Future<Element> makeShare() async { | ||||
|     ..append(Element.a() | ||||
|       ..attributes['href'] = 'javascript:void(0)' | ||||
|       ..attributes['tabindex'] = '-1' | ||||
|       ..append(makeIcon(icons['share']))) | ||||
|       ..append(makeIcon(icons['share']!))) | ||||
|     ..append(Element.ul() | ||||
|       ..classes.add('dropdown') | ||||
|       ..attributes['id'] = 'drop-share' | ||||
|       ..append(makeShareLink( | ||||
|           makeIcon(icons['twitter']), | ||||
|           makeIcon(icons['twitter']!), | ||||
|           'https://twitter.com/share?text=${getPageTitle()}' | ||||
|           '&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}')) | ||||
|       ..append(makeShareLink(makeIcon(icons['email']), | ||||
|           'mailto:?subject=${getPageTitle}&body=${window.location.href}')) | ||||
|       ..append(makeShareLink(makeIcon(icons['email']!), | ||||
|           'mailto:?subject=$getPageTitle&body=${window.location.href}')) | ||||
|       ..append(makeShareLink( | ||||
|           makeIcon(icons['linkedin']), | ||||
|           makeIcon(icons['linkedin']!), | ||||
|           'https://www.linkedin.com/shareArticle?mini=true&url=${window.location.href}' | ||||
|           '&title=${getPageTitle()}')) | ||||
|       ..append(makeShareLink(makeIcon(icons['facebook']), | ||||
|       ..append(makeShareLink(makeIcon(icons['facebook']!), | ||||
|           'https://www.facebook.com/sharer/sharer.php?u=${window.location.href}'))); | ||||
| } | ||||
| 
 | ||||
| @ -125,7 +125,7 @@ Future<Element> makeThemeChanger() async { | ||||
|       ..attributes['tabindex'] = '-1' | ||||
|       ..append(Element.span() | ||||
|         ..style.verticalAlign = 'top' | ||||
|         ..append(makeIcon(icons['theme'])))) | ||||
|         ..append(makeIcon(icons['theme']!)))) | ||||
|     ..append(Element.ul() | ||||
|       ..classes.add('dropdown') | ||||
|       ..attributes['id'] = 'theme-dropdown' | ||||
| @ -144,7 +144,7 @@ Future<Element> makeToc() async { | ||||
|     ..append(Element.a() | ||||
|       ..attributes['tabindex'] = '-1' | ||||
|       ..attributes['href'] = 'javascript:void(0)' | ||||
|       ..append(makeIcon(icons['toc']))); | ||||
|       ..append(makeIcon(icons['toc']!))); | ||||
| } | ||||
| 
 | ||||
| // Add a navbar atop of the HTML body, containing: | ||||
|  | ||||
| @ -15,29 +15,29 @@ Future<String> fetchRemoteSitemap() async { | ||||
| 
 | ||||
| // Parse the list of elements and detect pages from this list | ||||
| 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>{}; | ||||
| 
 | ||||
|   // parse each element in sitemap | ||||
|   for (var elem in t_sitemap) { | ||||
|     // if it’s a link | ||||
|     if (elem.innerHtml.startsWith('<a')) { | ||||
|       elem = elem.firstChild; | ||||
|       final url = elem.attributes['href']; | ||||
|       final text = elem.firstChild.text; | ||||
|     if (elem.innerHtml!.startsWith('<a')) { | ||||
|       elem = elem.children[0]; | ||||
|       final url = elem.attributes['href']!; | ||||
|       final text = elem.children[0].text; | ||||
|       if (excluded_keywords.contains(text) || | ||||
|           excluded_keywords.contains(url.substring(0, url.length - 5))) { | ||||
|         continue; | ||||
|       } | ||||
|       t_links['/$url'] = (t_prefix == null) ? text : '$text ($t_prefix)'; | ||||
|       t_links!['/$url'] = ((t_prefix == null) ? text : '$text ($t_prefix)')!; | ||||
|     } else { | ||||
|       final prefix = (t_prefix == null) | ||||
|           ? elem.firstChild.text.replaceAll('\n', '') | ||||
|           : '$t_prefix / ${elem.firstChild.text}'.replaceAll('\n', ''); | ||||
|           ? elem.firstChild!.text!.replaceAll('\n', '') | ||||
|           : '$t_prefix / ${elem.firstChild!.text}'.replaceAll('\n', ''); | ||||
|       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 | ||||
| @ -45,13 +45,13 @@ Map<String, String> detectPages(List<Element> t_sitemap, | ||||
| Future<Map<String, String>> parseSitemap() async { | ||||
|   final content = await fetchRemoteSitemap(); | ||||
|   final sitemap = Element.ul()..innerHtml = content; | ||||
|   final sitemapNodes = sitemap.querySelector('ul').children; | ||||
|   final sitemapNodes = sitemap.querySelector('ul')!.children; | ||||
|   return detectPages(sitemapNodes); | ||||
| } | ||||
| 
 | ||||
| Future<void> createSitemap() async { | ||||
|   final sitemap = await parseSitemap(); | ||||
|   final pages = querySelector('#drop-page'); | ||||
|   final pages = querySelector('#drop-page')!; | ||||
|   sitemap.forEach((url, name) { | ||||
|     final link = Element.li() | ||||
|       ..classes.add('dropdown-item') | ||||
|  | ||||
| @ -13,7 +13,7 @@ Future<Element> makeHeader() async { | ||||
|       ..attributes['alt'] = 'Logo' | ||||
|       ..attributes['height'] = '150px' | ||||
|       ..attributes['width'] = '150px') | ||||
|     ..append(querySelector('h1')); | ||||
|     ..append(querySelector('h1')!); | ||||
|   final subt = header.querySelector('.subtitle'); | ||||
|   if (subt != null) { | ||||
|     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. | ||||
| Future<void> linkifyImg() async { | ||||
|   querySelectorAll('img').forEach((img) { | ||||
|     if (img.parent.tagName == 'P') { | ||||
|       final link = Element.a()..attributes['href'] = img.attributes['src']; | ||||
|     if (img.parent!.tagName == 'P') { | ||||
|       final link = Element.a()..attributes['href'] = img.attributes['src']!; | ||||
|       img.insertAdjacentElement('beforeBegin', link); | ||||
|       link.append(img); | ||||
|     } | ||||
| @ -61,10 +61,10 @@ Future<void> reorganizeHtml() async { | ||||
|   await linkifyImg(); | ||||
| 
 | ||||
|   // Add navbar to page | ||||
|   querySelector('body').insertAdjacentElement('afterBegin', navbar); | ||||
|   querySelector('body')!.insertAdjacentElement('afterBegin', navbar); | ||||
| 
 | ||||
|   // Add headet to page | ||||
|   querySelector('#content').insertAdjacentElement('beforeBegin', header); | ||||
|   querySelector('#content')!.insertAdjacentElement('beforeBegin', header); | ||||
| 
 | ||||
|   // Add correct class to TOC | ||||
|   final toc = (querySelector('#table-of-contents') ?? | ||||
| @ -72,7 +72,7 @@ Future<void> reorganizeHtml() async { | ||||
|         ..attributes['id'] = 'table-of-contents' | ||||
|         ..innerText = 'Table of Contents Unavailable')) | ||||
|     ..classes.add('dropdown'); | ||||
|   navbar.querySelector('#toc-drop').append(toc); | ||||
|   navbar.querySelector('#toc-drop')!.append(toc); | ||||
| 
 | ||||
|   // Remove all <br> tags from HTML | ||||
|   querySelectorAll('br').forEach((br) => br.remove()); | ||||
|  | ||||
| @ -2,22 +2,19 @@ import 'dart:html' show window, querySelector; | ||||
| 
 | ||||
| final localStorage = window.localStorage; | ||||
| 
 | ||||
| Future<void> setTheme([String theme]) async { | ||||
|   final currentTheme = theme ?? localStorage['theme'] ?? | ||||
|   () { | ||||
|     final devicePrefersDark = | ||||
|     window.matchMedia('(prefers-color-scheme: dark)').matches; | ||||
|     return devicePrefersDark ? 'nord' : 'light'; | ||||
|   }(); | ||||
|   localStorage['theme'] = currentTheme; | ||||
|   querySelector('body') | ||||
| Future<void> setTheme([String? theme]) async { | ||||
|   theme ??= localStorage['theem'] ?? | ||||
|       (window.matchMedia('(prefers-color-scheme: dark)').matches | ||||
|           ? 'dark' | ||||
|           : 'light'); | ||||
|   localStorage['theme'] = theme; | ||||
|   querySelector('body')! | ||||
|     ..classes.clear() | ||||
|     ..classes.add(currentTheme); | ||||
|     ..classes.add(theme); | ||||
| } | ||||
| 
 | ||||
| void enableThemeChanger() { | ||||
|   final themes = <String>['light', 'dark', 'nord', 'black']; | ||||
|   themes.forEach((theme) => | ||||
|     querySelector('#${theme}Btn').onClick.listen((_) => setTheme(theme)) | ||||
|   ); | ||||
|       querySelector('#${theme}Btn')!.onClick.listen((_) => setTheme(theme))); | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user