Amélioration de l'interface utilisateur avec Bootstrap
Ce projet est open source et accessible depuis GitHub GL-Browser.
Cet article est le 5ème d'une série d'articles concernant la création d'un navigateur internet incluant par défaut des fonctionnalités que l'on retrouve habituellement sous forme d'extensions dans Chrome ou Firefox.
Exemples de fonctionnalités :
Nous souhaitons :
Nous utilisons Electron qui mixe le navigateur open source Chromium avec la richesse du framework Node.js.
Dans ce 5ème article, nous allons améliorer l'interface utilisateur à l'aide de Bootstrap, notamment en utilisant des onglets pour afficher plusieurs pages internet simultanément.
Article 1 : initialisation du projet avec Electron.
Article 2 : injection du CSS et du JavaScript dans la page de Google.
Article 3 : injection de scripts JavaScript et de styles CSS suivant l'URL.
Article 4 : bloquer les requêtes de suivi/tracking des utilisateurs.
Pour récupérer directement les sources du 4ème article :
git clone https://github.com/emmanuelroecker/GL-Browser
git checkout article4
jQuery est une librairie JavaScript qui facilite la manipulation d'un document HTML.
Bootstrap est une bibliothèque libre de composants visuels CSS et JavaScript qui facilite le développement de l'interface utilisateur d'une page web.
Bootstrap nécessite jQuery.
Ajouter au fichier package.json les nouvelles dépendances :
{
"devDependencies": {
"electron-prebuilt": "^0.36.0",
"js-yaml": "^3.5.0",
"match-pattern": "^0.0.1",
"bootstrap": "^3.3.0",
"jquery": "^1.9.1"
}
}
Pour installer :
npm install
Pour mieux structurer le projet :
Ajouter à index.html le style de Bootstrap et les liens vers les nouveaux fichiers :
<link rel="stylesheet" type="text/css" href="../node_modules/bootstrap/dist/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="css/glbrowser.css">
<script src="./js/glbrowser.js" type="text/javascript"></script>
Ajouter au début de glbrowser.js les déclarations de jQuery et Bootstrap :
window.$ = window.jQuery = require('jquery');
require('bootstrap');
Améliorer le code avec jQuery en remplaçant par exemple les appels du type document.getElementById("main");
par $('#main')
, etc
Les onglets sont gérés à l'aide du composant tab de Bootstrap.
Placer dans le fichier page.html le code HTML du composant qui sera dupliqué dans chaque onglet, c'est à dire la zone de saisie de l'URL, les bouttons de navigation, l'élément webview, ... :
<div class="gl-header input-group">
<div class="input-group-btn">
<a class="gl-goback btn btn-default" role="button"><span class="glyphicon glyphicon-arrow-left"></span></a>
</div>
<input class="gl-urltext form-control" type="text" placeholder="URL">
<span class="gl-indicator input-group-addon"></span>
<div class="input-group-btn">
<a class="gl-refresh btn btn-default" role="button"><span class="glyphicon glyphicon-repeat"></span></a>
<a class="gl-dev btn btn-default" role="button"><span class="glyphicon glyphicon-wrench"></span></a>
</div>
</div>
<webview class="gl-webview">
</webview>
Pour afficher une icône indiquant l'état de chargement d'une page internet, ajouter à glbrowser.js :
let webview = $('.tab-pane.active .gl-webview');
let indicator = $('.tab-pane.active .gl-indicator');
webview.on('did-start-loading', () => {
indicator.toggleClass('glyphicon glyphicon-refresh');
});
webview.on('did-stop-loading', () => {
indicator.toggleClass('glyphicon glyphicon-refresh');
});
Un onglet +
est dédié à l'ajout d'un nouvel onglet, compléter index.html avec :
<ul class="nav nav-tabs">
<li><a role="button" class="add-url" data-toggle="tab">+</a></li>
</ul>
<div class="tab-content">
</div>
Le code correspondant est ajouté à glbrowser.js :
const webComponent = fs.readFileSync('page.html', encoding); //lecture du code html du composant à injecter dans chaque onglet
let elemid = 'url' + $('.nav-tabs').children().length; //générer un identifiant unique suivant le nombre d'onglets déjà présent
$(this).closest('li').before(`<li><a href="#${elemid}" data-toggle="tab">${elemid}</a><span>x</span></li>`); //ajouter le boutton d'accès à l'onglet
$('.tab-content').append(`<div class="tab-pane fade" id="${elemid}">${webComponent}</div>`); //injecter le composant dans le nouvel onglet
Un onglet par défaut est créé au démarrage du navigateur :
window.onload = function () {
$('.add-url').click();
};
Pour cacher un onglet inactif, Bootstrap utilise display: none
mais le webview ne récupère pas les bonnes dimensions de l'onglet lors de son réaffichage.
Pour corriger cela, surcharger le CSS de Bootstrap afin de remplacer display: none
par height: 0; overflow-y: hidden
.
.tab-content > .tab-pane {
display: block;
height: 0;
overflow-y: hidden;
}
.tab-content > .active {
height: auto;
}
Avant | Après |
---|---|
git add -A
git commit -m "article 5"
git push
Le prochain article traitera de l'encapsulation des composants à l'aide de Riot.