switch layout to purecss

pull/7/head 0.9.3
Thorsten von Eicken 10 years ago
parent 8bb8e1124b
commit 7ade39d986
  1. 29
      Makefile
  2. 25
      html/console.tpl
  3. 16
      html/head.tpl
  4. 40
      html/help.tpl
  5. 27
      html/index.tpl
  6. 25
      html/log.tpl
  7. 11
      html/pure-min.css
  8. 233
      html/style.css
  9. 35
      html/ui.js
  10. 60
      html/wifi/wifi.tpl
  11. 52
      user/cgi.c
  12. 1
      user/cgi.h
  13. 5
      user/cgiwifi.c
  14. 6
      user/console.c
  15. 6
      user/log.c

@ -1,30 +1,33 @@
# --------------- esphttpd config options ---------------
# If GZIP_COMPRESSION is set to "yes" then the static css, js, and html files will be compressed with gzip before added to the espfs image
# and will be served with gzip Content-Encoding header.
# This could speed up the downloading of these files, but might break compatibility with older web browsers not supporting gzip encoding
# because Accept-Encoding is simply ignored. Enable this option if you have large static files to serve (for e.g. JQuery, Twitter bootstrap)
# By default only js, css and html files are compressed.
# If you have text based static files with different extensions what you want to serve compressed then you will need to add the extension to the following places:
# If GZIP_COMPRESSION is set to "yes" then the static css, js, and html files will be compressed
# with gzip before added to the espfs image and will be served with gzip Content-Encoding header.
# This could speed up the downloading of these files, but might break compatibility with older
# web browsers not supporting gzip encoding because Accept-Encoding is simply ignored.
# Enable this option if you have large static files to serve (for e.g. JQuery, Twitter bootstrap)
# By default only js, css and html files are compressed using heatshrink.
# If you have text based static files with different extensions what you want to serve compressed
# then you will need to add the extension to the following places:
# - Add the extension to this Makefile at the webpages.espfs target to the find command
# - Add the extension to the gzippedFileTypes array in the user/httpd.c file
#
# Adding JPG or PNG files (and any other compressed formats) is not recommended, because GZIP compression does not works effectively on compressed files.
# Adding JPG or PNG files (and any other compressed formats) is not recommended, because GZIP
# compression does not work effectively on compressed files.
#Static gzipping is disabled by default.
GZIP_COMPRESSION ?= no
GZIP_COMPRESSION ?= yes
# If COMPRESS_W_YUI is set to "yes" then the static css and js files will be compressed with yui-compressor
# This option works only when GZIP_COMPRESSION is set to "yes"
# If COMPRESS_W_YUI is set to "yes" then the static css and js files will be compressed with
# yui-compressor. This option works only when GZIP_COMPRESSION is set to "yes".
# http://yui.github.io/yuicompressor/
#Disabled by default.
COMPRESS_W_YUI ?= no
YUI-COMPRESSOR ?= /usr/bin/yui-compressor
#If USE_HEATSHRINK is set to "yes" then the espfs files will be compressed with Heatshrink and decompressed
#on the fly while reading the file. Because the decompression is done in the esp8266, it does not require
#any support in the browser.
# If USE_HEATSHRINK is set to "yes" then the espfs files will be compressed with Heatshrink and
# decompressed on the fly while reading the file.
# Because the decompression is done in the esp8266, it does not require any support in the browser.
USE_HEATSHRINK ?= yes
# -------------- End of esphttpd config options -------------

@ -1,14 +1,19 @@
<html><head><title>MCU Console - ESP Link</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div id="main">
<div id="topnav">%topnav%</div>
<h1><span class="esp">esp</span> link - Microcontroller Console</h1>
<p>The Microcontroller console shows the last 1024 characters received from UART0, to which
a microcontroller is tpically attached.</p>
<pre class="console">
%head%
<div id="main">
<div class="header">
<h1><span class="esp">esp</span> link - Microcontroller Console</h1>
</div>
<div class="content">
<p>The Microcontroller console shows the last 1024 characters received from UART0, to which
a microcontroller is typically attached.</p>
<pre class="console">
%console%
</pre>
</div>
</div>
</div>
<script src="ui.js"></script>
</body></html>

@ -0,0 +1,16 @@
<html><head>
<title>ESP Link</title>
<link rel="stylesheet" href="/pure-min.css">
<link rel="stylesheet" href="/style.css">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div id="layout">
<a href="#menu" id="menuLink" class="menu-link"><span></span></a>
<div id="menu">
<div class="pure-menu">
<a class="pure-menu-heading" href="/">esp-link</a>
<ul class="pure-menu-list">%topnav%</ul>
</div>
</div>

@ -1,13 +1,16 @@
<html>
<head><title>Help - ESP Link</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div id="main">
<div id="topnav">%topnav%</div>
<h1><span class="esp">esp</span> link - Help</h1>
%head%
The ESP Link functions in two wifi modes: Station+AccessPoint (STA+AP) and Station (STA).
<div id="main">
<div class="header">
<h1><span class="esp">esp</span> link - Help</h1>
</div>
<div class="content">
<p>This text is somewhat out of date, please refer to
<a href="https://github.com/jeelabs/esp-link/blob/master/README.md">the online README</a>
for the time being.</p>
<p>The ESP Link functions in two wifi modes: Station+AccessPoint (STA+AP) and Station (STA).
In the STA+AP mode it presents a network called esp8266 that you can connect to using the
password jeelabs8266. This mode is intended for initial configuration, but it is
fully functional. Typically the easiest way to connect to the esp8266 network is using a phone,
@ -27,23 +30,25 @@ fresh IP the next time it starts up. On many Wifi routers you can enter a fixed
the ESP Link's hardware MAC address to a static IP address so it always gets the same IP
address. This is the recommended method of operation.</p>
<h1>Using your ESP Serial Programmer</h1>
The ESP Programmer can used in several distinct ways:
<h2 class="content-subhead">Using your esp-link</h2>
<p>
The esp-link can used in several distinct ways:
<ul>
<li>as a transparent bridge between TCP port 23 and the serial port</li>
<li>as a web console to see input from the serial port</li>
<li>as an Arduino, AVR, or ARM processor programmer using serial-over-TCP</li>
<li>as an Arduino, AVR, or ARM processor programmer by uploading HEX files (not yet functional)</li>
</ul>
</p>
<h2>Transparent bridge</h2>
<h2 class="content-subhead">Transparent bridge</h2>
<p>The ESP accepts TCP connections to port 23 and "connects" through to the serial port.
Up to 5 simultaneous TCP connections are supported and characters coming in on the serial
port get passed through to all connections. Characters coming in on a connection get copied
through to the serial port.</p>
<p>When using Linux a simple way to use this is <tt>nc esp8266 23</tt></p>
<h2>Programmer using serial-over-TCP</h2>
<h2 class="content-subhead">Programmer using serial-over-TCP</h2>
<p>By hooking up the ESP's GPIO lines to the reset line of an Arduino (or AVR in general) that is
preloaded with the Optiboot bootloader/flasher it is possible to reprogram these processors over
Wifi. The way is works is that the ESP toggles the reset line each time a connection is established
@ -55,16 +60,21 @@ Serial Programmer (an IP address could have been used instead).</p>
ARM's reset and ISP lines. The ESP Serial Programmer issues the correct reset/isp pulses to put
the ARM chip into firmware programming mode.</p>
<h2>Web Console</h2>
<h2 class="content-subhead">Web Console</h2>
<p>The output of an attached Arduino/AVR/ARM can also be monitored via the console web page.
When connecting, it shows the most recent 10KB of characters received on the serial port and
then continues to print everything that comes in on the serial port. Eventually the page refreshes
when it gets very long. (Yes, this could be improved with some javascript...)</p>
<h2>Programmer using HEX upload</h2>
<h2 class="content-subhead">Programmer using HEX upload</h2>
<p><i>(Not yet functional)</i> Instead of using the wifi-to-serial bridge to program
microcontrollers it is often faster to upload the HEX file to the ESP Serial Programmer and
have it perform the actual programming protocol.</p>
</div>
</div>
</div>
<script src="ui.js"></script>
</body></html>

@ -1,14 +1,17 @@
<html>
<head><title>ESP Link</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div id="main">
<div id="topnav">%topnav%</div>
<h1><span class="esp">esp</span> link</h1>
<p>
The ESP Link connects the ESP's serial port to Wifi and it can
program microcontrollers over the serial port, in particular Arduinos, AVRs, and
NXP's LPC800-series ARM processors.</p>
%head%
<div id="main">
<div class="header">
<h1><span class="esp">esp</span> link</h1>
</div>
<div class="content">
<p>The ESP Link connects the ESP's serial port to Wifi and it can
program microcontrollers over the serial port, in particular Arduinos, AVRs, and
NXP's LPC800-series ARM processors.</p>
</div>
</div>
</div>
<script src="ui.js"></script>
</body></html>

@ -1,14 +1,19 @@
<html><head><title>Log - ESP Link</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div id="main">
<div id="topnav">%topnav%</div>
<h1><span class="esp">esp</span> link - Debug Log</h1>
<p>The debug log shows the 1024 last characters printed by the esp-link software itself to
its own debug log.</p>
<pre class="console">
%head%
<div id="main">
<div class="header">
<h1><span class="esp">esp</span> link - Debug Log</h1>
</div>
<div class="content">
<p>The debug log shows the 1024 last characters printed by the esp-link software itself to
its own debug log.</p>
<pre class="console">
%log%
</pre>
</div>
</div>
</div>
<script src="ui.js"></script>
</body></html>

11
html/pure-min.css vendored

File diff suppressed because one or more lines are too long

@ -1,46 +1,74 @@
/* All fonts */
html, button, input, select, textarea, .pure-g [class *= "pure-u"] {
font-family: sans-serif;
}
body {
background-color: #404040;
font-family: sans-serif;
font-color: #663300;
color: #777;
}
#main {
background-color: #FFFFCC;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
border: 2px solid #000000;
width: 800px;
margin: 0 auto;
padding: 20px
/* make images size-up */
.xx-pure-img-responsive {
max-width: 100%;
height: auto;
}
h1 {
margin-top: 0;
font-size: 36pt;
/* Add transition to containers so they can push in and out */
#layout, #menu, .menu-link {
-webkit-transition: all 0.2s ease-out;
-moz-transition: all 0.2s ease-out;
-ms-transition: all 0.2s ease-out;
-o-transition: all 0.2s ease-out;
transition: all 0.2s ease-out;
}
h1 .esp {
font-size: 48pt;
/* This is the parent `<div>` that contains the menu and the content area */
#layout {
position: relative;
padding-left: 0;
}
#layout.active #menu {
left: 150px;
width: 150px;
}
#topnav {
background-color: #CC9966;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
border: 0px solid #000000;
padding: 10px;
margin-left: auto;
margin-right: auto;
color: #ffff99;
#layout.active .menu-link {
left: 150px;
}
#topnav a {
color: #ffff99;
font-weight: bold;
font-stretch: expanded;
/* The content `<div>` */
.content {
margin: 0 auto;
padding: 0 2em;
max-width: 800px;
margin-bottom: 50px;
line-height: 1.6em;
}
.header {
margin: 0;
color: #333;
text-align: center;
padding: 2.5em 2em 0;
border-bottom: 1px solid #eee;
background-color: #fc0;
}
.header h1 {
margin: 0.2em 0;
font-size: 3em;
font-weight: 300;
}
.header h1 .esp {
font-size: 1.25em;
}
.content-subhead {
margin: 50px 0 20px 0;
font-weight: 300;
color: #888;
}
/* Text console */
pre.console {
background-color: #663300;
-moz-border-radius: 5px;
@ -62,3 +90,146 @@ pre.console a {
height: 32px;
display: inline-block;
}
/* The `#menu` `<div>` is the parent `<div>` that contains the `.pure-menu` that
* appears on the left side of the page */
#menu {
margin-left: -150px; /* "#menu" width */
width: 150px;
position: fixed;
top: 0;
left: 0;
bottom: 0;
z-index: 1000; /* so the menu or its navicon stays above all content */
background: #191818;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}
/* All anchors inside the menu should be styled like this */
#menu a {
color: #999;
border: none;
padding: 0.6em 0 0.6em 0.6em;
}
/* Remove all background/borders, since we are applying them to #menu */
#menu .pure-menu, #menu .pure-menu ul {
border: none;
background: transparent;
}
/* Add that light border to separate items into groups */
#menu .pure-menu ul, #menu .pure-menu .menu-item-divided {
border-top: 1px solid #333;
}
/* Change color of the anchor links on hover/focus */
#menu .pure-menu li a:hover, #menu .pure-menu li a:focus {
background: #333;
}
/* This styles the selected menu item `<li>` */
#menu .pure-menu-selected, #menu .pure-menu-heading {
background: #c60;
}
/* This styles a link within a selected menu item `<li>` */
#menu .pure-menu-selected a {
color: #fff;
}
/* This styles the menu heading */
#menu .pure-menu-heading {
font-size: 110%;
color: #fff;
margin: 0;
}
#menu .pure-menu-item {
height:2em;
}
/* -- Dynamic Button For Responsive Menu -------------------------------------*/
/* `.menu-link` represents the responsive menu toggle that shows/hides on small screens */
.menu-link {
position: fixed;
display: block; /* show this only on small screens */
top: 0;
left: 0; /* "#menu width" */
background: #000;
background: rgba(0,0,0,0.7);
font-size: 10px; /* change this value to increase/decrease button size */
z-index: 10;
width: 2em;
height: auto;
padding: 2.1em 1.6em;
}
.menu-link:hover, .menu-link:focus {
background: #000;
}
.menu-link span {
position: relative;
display: block;
}
.menu-link span, .menu-link span:before, .menu-link span:after {
background-color: #fff;
width: 100%;
height: 0.2em;
}
.menu-link span:before, .menu-link span:after {
position: absolute;
margin-top: -0.6em;
content: " ";
}
.menu-link span:after {
margin-top: 0.6em;
}
/* -- Responsive Styles (Media Queries) ------------------------------------- */
/* Hides the menu at `48em`, but modify this based on your app's needs */
@media (min-width: 48em) {
.header, .content {
padding-left: 2em;
padding-right: 2em;
}
#layout {
padding-left: 150px; /* left col width "#menu" */
left: 0;
}
#menu {
left: 150px;
}
.menu-link {
position: fixed;
left: 150px;
display: none;
}
#layout.active .menu-link {
left: 150px;
}
}
@media (max-width: 48em) {
/* Only apply this when the window is small. Otherwise, the following
case results in extra padding on the left:
* Make the window small.
* Tap the menu to trigger the active state.
* Make the window large again.
*/
#layout.active {
position: relative;
left: 150px;
}
}

@ -0,0 +1,35 @@
(function (window, document) {
var layout = document.getElementById('layout'),
menu = document.getElementById('menu'),
menuLink = document.getElementById('menuLink');
function toggleClass(element, className) {
var classes = element.className.split(/\s+/),
length = classes.length,
i = 0;
for(; i < length; i++) {
if (classes[i] === className) {
classes.splice(i, 1);
break;
}
}
// The className is not found
if (length === classes.length) {
classes.push(className);
}
element.className = classes.join(' ');
}
menuLink.onclick = function (e) {
var active = 'active';
e.preventDefault();
toggleClass(layout, active);
toggleClass(menu, active);
toggleClass(menuLink, active);
};
}(this, this.document));

@ -1,6 +1,35 @@
<html><head><title>WiFi connection - ESP Link</title>
<link rel="stylesheet" type="text/css" href="/style.css">
<script type="text/javascript" src="140medley.min.js"></script>
%head%
<div id="main">
<div class="header">
<h1><span class="esp">esp</span> link - Wifi Configuration</h1>
</div>
<div class="content">
<h2 class="content-subhead">Current Wifi State</h2>
<p>
WiFi mode: %WiFiMode%<br>
Configured network: %currSsid% Status: %currStatus% Phy:%currPhy%
</p>
<p>%WiFiapwarn%</p>
<h2 class="content-subhead">Change Wifi association</h2>
<form name="wifiform" action="connect.cgi" method="post">
<p>To connect to a WiFi network, please select one of the detected networks,
enter the password, and hit the connect button...<p>
<div id="aps">Scanning...</div>
<p>WiFi password, if applicable: <br />
<input type="text" name="passwd" val="%WiFiPasswd%">
<input type="submit" name="connect" value="Connect!">
</p>
</form>
</div>
</div>
</div>
<script src="ui.js"></script>
<script src="140medley.min.js"></script>
<script type="text/javascript">
var xhr=j();
@ -71,27 +100,4 @@ window.onload=function(e) {
scanAPs();
};
</script>
</head>
<body>
<div id="main">
<div id="topnav">%topnav%</div>
<h1><span class="esp">esp</span> link - Wifi Configuration</h1>
<p>
Current WiFi mode: %WiFiMode%<br>
Current network: %currSsid% Status: %currStatus% Phy:%currPhy%
</p>
<p>
Note: %WiFiapwarn%
</p>
<form name="wifiform" action="connect.cgi" method="post">
<p>
To connect to a WiFi network, please select one of the detected networks...<br>
<div id="aps">Scanning...</div>
<br>
WiFi password, if applicable: <br />
<input type="text" name="passwd" val="%WiFiPasswd%"> <br />
<input type="submit" name="connect" value="Connect!">
</p>
</div>
</body>
</html>
</body></html>

@ -15,6 +15,7 @@ flash as a binary. Also handles the hit counter on the main page.
#include <esp8266.h>
#include "cgi.h"
#include "espfs.h"
//cause I can't be bothered to write an ioGetLed()
@ -44,7 +45,7 @@ int ICACHE_FLASH_ATTR cgiLed(HttpdConnData *connData) {
//Template code for the led page.
int ICACHE_FLASH_ATTR tplLed(HttpdConnData *connData, char *token, void **arg) {
char buff[128];
char buff[512];
if (token==NULL) return HTTPD_CGI_DONE;
os_strcpy(buff, "Unknown");
@ -65,13 +66,14 @@ static long hitCounter=0;
//Template code for the counter on the index page.
int ICACHE_FLASH_ATTR tplCounter(HttpdConnData *connData, char *token, void **arg) {
char buff[256];
char buff[64];
if (token==NULL) return HTTPD_CGI_DONE;
if (printSysInfo(buff, token) > 0) {
// awesome...
} else if (os_strcmp(token, "topnav")==0) {
printNav(buff);
} else if (os_strcmp(token, "head")==0) {
printHead(connData);
buff[0] = 0;
} else if (os_strcmp(token, "counter")==0) {
hitCounter++;
os_sprintf(buff, "%ld", hitCounter);
@ -82,7 +84,7 @@ int ICACHE_FLASH_ATTR tplCounter(HttpdConnData *connData, char *token, void **ar
static char *navLinks[][2] = {
{ "Home", "/index.tpl" }, { "Wifi", "/wifi/wifi.tpl" }, { "\xC2\xB5""C Console", "/console.tpl" },
{ "Esp log", "/log.tpl" }, { "Help", "/help.tpl" },
{ "Debug log", "/log.tpl" }, { "Help", "/help.tpl" },
{ 0, 0 },
};
@ -90,14 +92,48 @@ static char *navLinks[][2] = {
int ICACHE_FLASH_ATTR printNav(char *buff) {
int len = 0;
for (uint8_t i=0; navLinks[i][0] != NULL; i++) {
if (i > 0) buff[len++] = '|';
//os_printf("nav %d: %s -> %s\n", i, navLinks[i][0], navLinks[i][1]);
len += os_sprintf(buff+len, " <a href=\"%s\">%s</a> ", navLinks[i][1], navLinks[i][0]);
len += os_sprintf(buff+len,
" <li class=\"pure-menu-item\"><a href=\"%s\" class=\"pure-menu-link\">%s</a></li>",
navLinks[i][1], navLinks[i][0]);
}
//os_printf("nav: %s\n", buff);
//os_printf("nav(%d): %s\n", len, buff);
return len;
}
void ICACHE_FLASH_ATTR printHead(HttpdConnData *connData) {
char buff[1024];
struct EspFsFile *file = espFsOpen("/head.tpl");
if (file == NULL) {
espFsClose(file);
os_printf("Header file 'head.tpl' not found\n");
return;
}
int len = espFsRead(file, buff, 1024);
if (len == 1024) {
os_printf("Header file 'head.tpl' too large!\n");
buff[1023] = 0;
} else {
buff[len] = 0; // ensure null termination
}
if (len > 0) {
char *p = os_strstr(buff, "%topnav%");
if (p != NULL) {
char navBuf[512];
int n = p - buff;
httpdSend(connData, buff, n);
printNav(navBuf);
httpdSend(connData, navBuf, -1);
httpdSend(connData, buff+n+8, len-n-8);
} else {
httpdSend(connData, buff, len);
}
}
}
#define TOKEN(x) (os_strcmp(token, x) == 0)
// Handle system information variables and print their value, returns the number of

@ -7,6 +7,7 @@ int cgiLed(HttpdConnData *connData);
int tplLed(HttpdConnData *connData, char *token, void **arg);
int tplCounter(HttpdConnData *connData, char *token, void **arg);
int printNav(char *buff);
void ICACHE_FLASH_ATTR printHead(HttpdConnData *connData);
int ICACHE_FLASH_ATTR printSysInfo(char *buff, char *token);
#endif

@ -406,8 +406,9 @@ int ICACHE_FLASH_ATTR tplWlan(HttpdConnData *connData, char *token, void **arg)
os_strcpy(buff, "Click <a href=\"setmode.cgi?mode=1\">here</a> to go to STA mode.");
break;
}
} else if (os_strcmp(token, "topnav")==0) {
printNav(buff);
} else if (os_strcmp(token, "head")==0) {
printHead(connData);
buff[0] = 0;
}
httpdSend(connData, buff, -1);
return HTTPD_CGI_DONE;

@ -39,7 +39,6 @@ console_write_char(char c) {
int ICACHE_FLASH_ATTR
tplConsole(HttpdConnData *connData, char *token, void **arg) {
if (token==NULL) return HTTPD_CGI_DONE;
char buff[256];
if (os_strcmp(token, "console") == 0) {
if (console_wr > console_rd) {
@ -48,9 +47,8 @@ tplConsole(HttpdConnData *connData, char *token, void **arg) {
httpdSend(connData, console_buf+console_rd, BUF_MAX-console_rd);
httpdSend(connData, console_buf, console_wr);
}
} else if (os_strcmp(token, "topnav")==0) {
printNav(buff);
httpdSend(connData, buff, -1);
} else if (os_strcmp(token, "head")==0) {
printHead(connData);
} else {
httpdSend(connData, "Unknown\n", -1);
}

@ -67,7 +67,6 @@ log_write_char(char c) {
int ICACHE_FLASH_ATTR
tplLog(HttpdConnData *connData, char *token, void **arg) {
if (token==NULL) return HTTPD_CGI_DONE;
char buff[256];
if (os_strcmp(token, "log") == 0) {
if (log_wr > log_rd) {
@ -76,9 +75,8 @@ tplLog(HttpdConnData *connData, char *token, void **arg) {
httpdSend(connData, log_buf+log_rd, BUF_MAX-log_rd);
httpdSend(connData, log_buf, log_wr);
}
} else if (os_strcmp(token, "topnav")==0) {
printNav(buff);
httpdSend(connData, buff, -1);
} else if (os_strcmp(token, "head")==0) {
printHead(connData);
} else {
httpdSend(connData, "Unknown\n", -1);
}

Loading…
Cancel
Save