Beginning rewrite of dart and scss code, no more infojs for org

New look for the website, rewrite and optimization of dart code.

Infojs has been removed entirely.
This commit is contained in:
2020-04-24 18:14:52 +02:00
parent 79a6001b11
commit 37d735cfdd
16 changed files with 337 additions and 1921 deletions

View File

@@ -1,11 +0,0 @@
@JS()
library cookie;
import 'package:js/js.dart';
@JS()
class Cookies {
// external factory Cookie();
external static String get(String name);
external static void set(String name, String value);
}

View File

@@ -1,66 +1,5 @@
@JS()
library main;
import 'dart:html';
import 'package:js/js.dart';
import './cookie.dart';
import './reorganize_html.dart' show reorganizeHtml;
void main() {
reorganizeHtml();
createThemeSwitcher();
themeSwitch(isThemeDark());
querySelector('.themeBtn').onClick.listen(themeSwitchMouse);
}
String cookieThemeName = 'theme';
void createThemeSwitcher() {
// set the correct CSS depending on the cookie, dark is enabled by default
var isDark = isThemeDark();
// Set the correct symbol in the theme switcher button
querySelector('body').append(DivElement()..className = 'themeBtn');
querySelector('.themeBtn')
.children
.add(Element.tag('i')..className = 'fas fa-' + (isDark ? 'sun' : 'moon'));
}
bool isThemeDark() {
if (Cookies.get(cookieThemeName) == 'light') {
return false;
}
Cookies.set(cookieThemeName, 'dark');
return true;
}
void reorganizeHtml() {
// Add a <hr> element after the content div
querySelector('#content').appendHtml('<hr>');
// Move the postamble in the content div
querySelector('#content').append(querySelector('#postamble'));
for (var table in querySelectorAll('table')) {
var largetable = DivElement();
largetable.className = 'largetable';
table.before(largetable);
largetable.children.add(table);
}
}
bool setTheme(bool dark) {
Cookies.set(cookieThemeName, (dark ? 'dark' : 'light'));
return !dark;
}
void themeSwitch(bool isDark) {
querySelector('.fas').className = 'fas fa-' + (isDark ? 'sun' : 'moon');
querySelector('#theme').attributes['href'] =
'https://langue.phundrak.com/css/' + (isDark ? 'dark' : 'light') + '.css';
}
void themeSwitchMouse(MouseEvent event) {
bool isDark = setTheme(!isThemeDark());
themeSwitch(isDark);
}

View File

@@ -0,0 +1,38 @@
import 'dart:html' show HttpRequest;
import 'package:html/parser.dart' show parse;
// Get the sitemap content
Future<String> getSitemap() async {
const path = 'sitemap.html';
try {
return await HttpRequest.getString(path);
} catch (e) {
print('Couldnt open $path');
}
return 'Error';
}
// This function returns a Map which contains all links to languages detected
// from the sitemap.
Future<Map<String, String>> parseSitemap() async {
var links = <String, String>{};
await getSitemap().then((String content) {
final sitemap = parse(content).getElementsByClassName('org-ul')[0].children;
for (var elem in sitemap) {
// TODO: make this recursive so prefixes in nested folders can be added to
// each other
if (elem.innerHtml.startsWith('<a')) {
elem = elem.firstChild;
final text = elem.firstChild.text;
final url = elem.attributes['href'];
if (!url.contains('index')) {
links[url] = text;
}
} else {
print('Sitemap folder:\n${elem.innerHtml}');
}
}
});
return links;
}

View File

@@ -0,0 +1,174 @@
import 'dart:html';
import './parse_sitemap.dart' show parseSitemap;
// Returns the title of the current webpage
String getPageTitle() {
return querySelector('title').text;
}
class Navbar {
Navbar() {
navbar = Element.ul()..classes.add('navbar-nav');
}
// Inserts the element in a <li class='nav-item'></li>
void addElement(final Element elem, [List<String> classes, String id]) {
var wrapper = Element.li()
..classes.add('nav-item')
..append(elem);
if (classes != null) {
for (var c in classes) {
wrapper.classes.add(c);
}
}
if (id != null) () => wrapper.attributes['id'] = id;
navbar.append(wrapper);
}
Future<Element> makeNavbar() async {
addElement(Element.a()
..attributes['href']
..innerText = 'Accueil');
}
Future<void> addLanguages() async {
var languages = Element.ul()..classes.add('dropdown');
await parseSitemap().then((final sitemap) => {
sitemap.forEach((url, name) {
final link = Element.a()
..attributes['href'] = url
..innerText = name;
final linkLi = Element.li()
..classes.add('dropdown-item')
..insertAdjacentElement('afterBegin', link);
languages.insertAdjacentElement('beforeEnd', linkLi);
})
});
final langLink = Element.a()
..attributes['href'] = '#'
..innerText = 'Langues';
addElement(langLink, ['has-dropdown'], 'langList');
querySelector('#langList').insertAdjacentElement('beforeEnd', languages);
}
Element navbar;
}
Future<Element> addLanguages(Element navbar) async {
// Languages
var languages = Element.ul()..classes.add('dropdown');
await parseSitemap().then((final sitemap) => {
sitemap.forEach((url, name) {
final link = Element.a()
..attributes['href'] = url
..innerText = name;
final linkLi = Element.li()
..classes.add('dropdown-item')
..insertAdjacentElement('afterBegin', link);
languages.insertAdjacentElement('beforeEnd', linkLi);
})
});
navbar.append(Element.li()
..append(Element.a()
..attributes['href'] = '#'
..innerText = 'Langues')
..classes.add('nav-item')
..classes.add('has-dropdown')
..insertAdjacentElement('beforeEnd', languages));
return navbar;
}
// Add a navbar atop of the HTML body, containing two buttons:
// - One back to home
// - A dropdown to each language detected in the sitemap
Future<Element> makeNavbar() async {
var _navbar = Navbar();
// Home
var navbar_content = Element.ul()..classes.add('navbar-nav');
navbar_content.append(Element.li()
..classes.add('nav-item')
..insertAdjacentElement(
'afterBegin',
Element.a()
..attributes['href'] = '/'
..innerText = 'Accueil'));
// Add languages
// navbar_content.append(Element.html('''
// '''));
navbar_content = await addLanguages(navbar_content);
// Page title
navbar_content.append(Element.li()
..classes.add('nav-item')
..innerText = getPageTitle());
// Share icon
// Add dropdown for sharing on multiple platforms
navbar_content = addIcon(navbar_content, ['fas', 'fa-share-alt'], 'shareBtn');
// Theme changer
// Add dropdown for theming
// navbar_content = addIcon(navbar_content, ['fas', 'fa-sun'], 'themeBtn');
navbar_content.append(Element.html('''
<li class="nav-item has-dropdown">
<a href="#"><i class="fas fa-sun" id="themeBtn"></i></a>
<ul class="dropdown" id="theme-dropdown">
<li class="dropdown-item"><i class="fas fa-sun"></i> Clair</li>
<li class="dropdown-item"><i class="fas fa-moon"></i> Sombre</li>
</ul>
</li>'''));
// Navbar content added to navbar
final navbar = Element.nav()
..classes.add('navbar')
..append(navbar_content);
return navbar;
}
Element addIcon(Element navbar, List<String> classes, String id) {
var elem = Element.tag('i')..attributes['id'] = id;
for (var c in classes) {
elem.classes.add(c);
}
navbar.append(Element.li()..append(elem));
return navbar;
}
Future<void> wrapTables() async {
for (var table in querySelectorAll('table')) {
var largetable = DivElement()..className = 'largetable';
table.before(largetable);
largetable.children.add(table);
}
}
Future<void> makeHeader() async {
querySelector('body')
.insertAdjacentElement('afterBegin', Element.tag('header'));
querySelector('header').append(querySelector('h1'));
querySelector('header').append(querySelector('.subtitle'));
}
Future<void> reorganizeHtml() async {
await makeHeader();
await wrapTables();
await makeNavbar().then((navbar) {
querySelector('body').insertAdjacentElement('afterBegin', navbar);
});
querySelector('body')
..classes.add('light')
// Add a <hr> element after the content div
..appendHtml('<hr>')
// Move the postamble in the content div
..append(querySelector('#postamble'));
}