Bläddra i källkod

refactoring nav menu

Benoît Hubert 8 år sedan
förälder
incheckning
b93b040929
5 ändrade filer med 162 tillägg och 80 borttagningar
  1. 19 6
      css/styles.css
  2. 12 1
      index.html
  3. 71 0
      lib/ExampleStore.js
  4. 24 0
      lib/scandir.js
  5. 36 73
      sandboxApp.js

+ 19 - 6
css/styles.css

@@ -50,6 +50,7 @@
  */
 body {
   font-size: 130%;
+  font-family: Arial, Helvetica;
 }
 
 /**
@@ -126,18 +127,18 @@ body {
 .panel-inner {
   padding: 10px;
 }
-.panel-left nav,
+#site-menu{ position: fixed;top:0;right:0; }
+/*.panel-left nav,
 #add-example-form {
-  /*display: inline-block;*/
+  display: inline-block;
 }
-#site-menu{ position: fixed;top:0;right:0; }
 .panel-left nav ul {
   padding-left: 0;
   margin: 0;
 }
 .panel-left nav ul li {
-  /*display: inline-block;*/
-}
+  display: inline-block;
+}*/
 #notification {
   color: black;
   position: absolute;
@@ -193,10 +194,22 @@ button:hover {
 #editor {
   font-size: 90%;
   position: absolute;
-  top: 90px;
+  top: 390px;
   right: 500px;
   bottom: 0;
   left: 0;
   border-top: 1px solid #aaa;
   border-bottom: 1px solid #aaa;
 }
+
+/* Menus de nav */
+.nav-menu {
+  background: #eee;
+  padding: 10px;
+}
+.nav-menu a {
+  color: #000;
+}
+.nav-menu a:hover {
+  color: #555;
+}

+ 12 - 1
index.html

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html lang="en">
 <head>
-<title>Formation jQuery</title>
+<title>{{title}} - Web sandbox</title>
     <link rel="stylesheet" href="css/normalize.css">
     <link rel="stylesheet" href="css/main.css">
 <!--     <link rel="stylesheet" href="css/qunit-2.4.1.css"> -->
@@ -18,6 +18,17 @@
     <div class="panel-left">
         <div id="notification"></div>
         <div class="panel-inner">
+
+            <div id="nav-menus">
+                <ul id="menu-repo" class="nav-menu">{{#menuRepo}}
+                  <li><a href="{{slug}}">{{title}}</a></li>{{/menuRepo}}
+                </ul>
+
+                <ul id="menu-repo" class="nav-menu">{{#menuRepo}}
+                  <li><a href="{{slug}}">{{title}}</a></li>{{/menuRepo}}
+                </ul>
+            </div>
+
             <button id="add-example-btn" class="icon-plus rounded blue"></button>
             <form id="add-example-form" style="display: none;">
                 <input type="text" name="title" class="input-sm" value="" />

+ 71 - 0
lib/ExampleStore.js

@@ -0,0 +1,71 @@
+const scandir = require('./scandir');
+var Promise   = require('bluebird');
+var _         = require('lodash');
+function ExampleStore(path) {
+  this.rootPath = path;
+  this.repos = [];
+}
+
+ExampleStore.prototype.init = function() {
+  const loadRepository = this.loadRepository.bind(this);
+  return scandir(this.rootPath, ['.gitkeep'])
+  .then(repositories => Promise.map(
+    repositories, loadRepository
+  ));
+};
+
+ExampleStore.prototype.loadRepository = function(repoPath) {
+  const loadExample    = this.loadExample.bind(this);
+  const fullPath       = this.rootPath + '/' + repoPath;
+  const repoConfig     = require(fullPath + '/repo-config.json');
+  const repoDescriptor = {
+    title: repoConfig.title,
+    path: repoPath,
+    fullPath,
+    examples: []
+  };
+  this.repos.push(repoDescriptor);
+  return scandir(fullPath, ['.gitkeep', 'repo-config.json'])
+  .then(examples => Promise.map(
+    examples, example => loadExample(repoDescriptor, example)
+  ))
+  .then(() => console.log(this.repos[0]))
+};
+
+ExampleStore.prototype.loadExample = function(repo, slug) {
+  const exampleConfig = require(repo.fullPath + '/' + slug + '/config.json');
+  repo.examples.push(Object.assign({ slug }, exampleConfig));
+  return exampleConfig;
+};
+
+ExampleStore.prototype.getList = function(path) {
+  return _.find(this.repos, { path });
+}
+
+ExampleStore.prototype.getRepoMenu = function(path) {
+  return this.repos.map(
+    ({ title, path }) => ({ title, slug: path }) 
+  )
+};
+
+ExampleStore.prototype.getExampleMenu = function(path) {
+  const repo = _.find(this.repos, { path });
+  return repo.examples.map(
+    ({ title, slug }) => ({ title, href: repo.path + '/' + slug }) 
+  );
+};
+
+ExampleStore.prototype.getMenu = function(path) {
+  const self = this;
+  return '<ul>' + self.repos.reduce((menu, repo) => {
+    return menu + '<li>'+ repo.title + '<ul>' + repo.examples.reduce((submenu, example) =>
+      (submenu + '<li><a href="#' + repo.path + '/' + example.slug  + '">' + example.title + '</a></li>'),
+    '') + '</ul></li>';
+  }, '') + '</ul>';
+}
+
+ExampleStore.prototype.repoExists = function(path) {
+  return _.find(this.repos, { path }) !== undefined;
+}
+
+module.exports = ExampleStore;

+ 24 - 0
lib/scandir.js

@@ -0,0 +1,24 @@
+/**
+ * This has to be required *after* using Bluebird's promisifyAll() on fs
+ */
+var fs = require('fs');
+
+if(typeof fs.readdirAsync !== 'function') {
+  console.error("scandir module requires promisifying fs with Bluebird's Promise.promisifyAll()");
+}
+
+function scandir(path, excludes) {
+  excludes = excludes || [];
+  return fs.readdirAsync(path)
+  .then(dirContent => {
+    excludes.forEach(file => {
+      var idxInContent = dirContent.indexOf(file);
+      if(idxInContent !== -1) {
+        dirContent.splice(idxInContent, 1);
+      }
+    });
+    return dirContent;
+  })
+}
+
+module.exports = scandir;

+ 36 - 73
sandboxApp.js

@@ -10,85 +10,19 @@ var fs           = require('fs');
 var Promise      = require('bluebird');
 var Mustache     = require('mustache');
 var app          = express();
-// var examplesJSON = __dirname + '/exemples/liste.json';
+var ExampleStore = require('./lib/ExampleStore');
+var indexTpml    = fs.readFileSync(__dirname + '/html/index.mustache.html').toString();
 var sandboxTpml  = fs.readFileSync(__dirname + '/html/template.mustache.html').toString();
-// var examples     = require(examplesJSON);
 Promise.promisifyAll(fs);
+var exStore     = new ExampleStore(__dirname + '/exemples');
+exStore.init()
+.then(() => console.log(exStore.getMenu()));
 
 // Initialize Express app: root folder as static, body parsers
 app.use(express.static(__dirname));
 app.use(bodyParser.json());
 app.use(bodyParser.urlencoded({ extended: true }));
 
-function scandir(path, excludes) {
-  excludes = excludes || [];
-  return fs.readdirAsync(path)
-  .then(dirContent => {
-    excludes.forEach(file => {
-      var idxInContent = dirContent.indexOf(file);
-      if(idxInContent !== -1) {
-        dirContent.splice(idxInContent, 1);
-      }
-    });
-    return dirContent;
-  })
-}
-
-function ExampleStore(path) {
-  this.rootPath = path;
-  this.repos = [];
-}
-
-ExampleStore.prototype.init = function() {
-  const loadRepository = this.loadRepository.bind(this);
-  return scandir(this.rootPath, ['.gitkeep'])
-  .then(repositories => Promise.map(
-    repositories, loadRepository
-  ));
-};
-
-ExampleStore.prototype.loadRepository = function(repoPath) {
-  const loadExample    = this.loadExample.bind(this);
-  const fullPath       = this.rootPath + '/' + repoPath;
-  const repoConfig     = require(fullPath + '/repo-config.json');
-  const repoDescriptor = {
-    title: repoConfig.title,
-    path: repoPath,
-    fullPath,
-    examples: []
-  };
-  this.repos.push(repoDescriptor);
-  return scandir(fullPath, ['.gitkeep', 'repo-config.json'])
-  .then(examples => Promise.map(
-    examples, example => loadExample(repoDescriptor, example)
-  ))
-  .then(() => console.log(this.repos[0]))
-};
-
-ExampleStore.prototype.loadExample = function(repo, slug) {
-  const exampleConfig = require(repo.fullPath + '/' + slug + '/config.json');
-  repo.examples.push(Object.assign({ slug }, exampleConfig));
-  return exampleConfig;
-};
-
-ExampleStore.prototype.getList = function(path) {
-  return _.find(this.repos, { path });
-}
-
-ExampleStore.prototype.getMenu = function(path) {
-  const self = this;
-  return '<ul>' + self.repos.reduce((menu, repo) => {
-    return '<li>'+ repo.title + '<ul>' + repo.examples.reduce((submenu, example) =>
-      (submenu + '<li><a href="#' + repo.path + '/' + example.slug  + '">' + example.title + '</a></li>'),
-    '') + '</ul></li>';
-  }, '') + '</ul>';
-}
-
-
-var es = new ExampleStore(__dirname + '/exemples');
-es.init()
-.then(() => console.log(es.getMenu()));
-
 
 function addExample(slug, title) {
   examples.push({ slug: slug, title: title });
@@ -126,6 +60,35 @@ function readFileAsync(file) {
 //   ]);
 // }
 
+app.get('/', function(req, res) {
+  const menuRepo = exStore.getRepoMenu();
+  // const title    = 'Home';
+  console.log(menuRepo);
+  res.send(Mustache.render(indexTpml, {
+    title,
+    menuRepo
+  }));
+});
+
+app.get('/:repoSlug',
+  function(req, res, next) {
+    if(! exStore.repoExists(req.params.repoSlug)) {
+      return res.status(404).send('Repo ' + req.params.repoSlug + ' not found');
+    }
+    next();
+  },
+  function(req, res) {
+    const menuRepo = exStore.getRepoMenu();
+    const menuRepo = exStore.getRepoMenu();
+    // const title    = 'Home';
+    console.log(menuRepo);
+    res.send(Mustache.render(indexTpml, {
+      title,
+      menuRepo,
+    menuRepo
+    }));
+});
+
 app.post('/examples', function(req, res) {
   var title = req.body.title;
   if(! req.body.title) {
@@ -158,12 +121,12 @@ app.get('/examples/:slug', function(req, res) {
 });
 
 app.get('/menu', (rea, res) => {
-  res.send(es.getMenu());
+  res.send(exStore.getMenu());
 });
 
 app.get('/list/:repoPath', function(req, res) {
   const { repoPath } = req.params;
-  const repo = es.getList(repoPath);
+  const repo = exStore.getList(repoPath);
   if(! repo) {
     return res.status(404).send('Repo ' + repoPath + ' not found');
   }