From 659b68d3ffc09cae68f0a0e53369aa4bf751ab55 Mon Sep 17 00:00:00 2001 From: Hieromon Ikasamo Date: Wed, 23 Jan 2019 21:22:30 +0900 Subject: [PATCH 1/4] Under the work of v0.9.7 documentation --- mkdocs/acelements.md | 6 +- mkdocs/achandling.md | 106 +++++++++++++++++++++++- mkdocs/acintro.md | 10 +-- mkdocs/acjson.md | 189 +++++++++++++++++++++++++++++++++---------- mkdocs/apiaux.md | 42 ++++++++-- 5 files changed, 294 insertions(+), 59 deletions(-) diff --git a/mkdocs/acelements.md b/mkdocs/acelements.md index f09db26..308c02e 100644 --- a/mkdocs/acelements.md +++ b/mkdocs/acelements.md @@ -115,7 +115,7 @@ It becomes a value of the `value` attribute of an HTML button tag. ### action -**action** is String data type and is an onclick attribute fire on a mouse click on the element. it is mostly used with a JavaScript to activate a script.[^1] For example, the following code defines a custom Web page that copies a content of `Text1` to `Text2` by clicking `Button`. +**action** is String data type and is an onclick attribute fire on a mouse click on the element. It is mostly used with a JavaScript to activate a script.[^1] For example, the following code defines a custom Web page that copies a content of `Text1` to `Text2` by clicking `Button`. [^1]:JavaScript can be inserted into a custom Web page using AutoConnectElement. @@ -225,7 +225,7 @@ A label is an optional string. A label will be arranged in the left or top of th ### order -A `order` specifies the orientation of the radio buttons. It is a value of type `ACArrange_t` and accepts one of the following: +A `order` specifies the direction to arrange the radio buttons. It is a value of type `ACArrange_t` and accepts one of the following: - **`AC_Horizontal`** : Horizontal arrangement. - **`AC_Vertical`** : Vertical arrangement. @@ -284,7 +284,7 @@ It is the `name` of the AutoConnectSubmit element and matches the name attribute ### value -It becomes a string of the `value` attribute of an HTML `` tag. The `value` is displayed as a label of the button. +It becomes a string of the `value` attribute of an HTML `` tag. The `value` will be displayed as a label of the button. ### uri diff --git a/mkdocs/achandling.md b/mkdocs/achandling.md index 2415678..d8033eb 100644 --- a/mkdocs/achandling.md +++ b/mkdocs/achandling.md @@ -1,6 +1,108 @@ -## Handing AutoConnectElements in the sketches +## Handing AutoConnectElements with the sketches -## Loading AutoConnectElements +AutoConnectElements (ie. they are the elements displayed on the custom Web page) must be contained in AutoConnectAux object. AutoConnectElements declared in sketch must be programmed to add to AutoConnectAux one after another. Elements are automatically included in AutoConnectAux by AutoConnect if you load it from the JSON description. In either method, it is common to use the function of AutoConnectAux to access an element with a sketch. + +The AutoConnectAux class has several functions to manipulate AutoConnectElements. The functions can add, delete, retrieve elements, and get and set values. + +### Add AutoConnectElements to the AutoConnectAux object + +To add AutoConnectElment(s) to an AutoConnectAux object, use the add function. + +```cpp +void AutoConnectAux::add(AutoConenctElement& addon) +``` +```cpp +void AutoConnectAux::add(AutoConenctElementVT addons) +``` + +The add function adds specified AutoConnectElement to the AutoConnectAux. If speficied the collection of AutoConnectElements as a `std::vector` of the references to each element, these elements added in bulk. + +The AutoConnectElements contained in the AutoConnectAux object are uniquely identified by the name. When adding an AutoConnectElement, if an element with the same name already exists in the AutoConnectAux, checking the type, and if it is the same, the value will be replaced. If another type of AutoConnectElement exists with the same name, that add operation will be invalid.[^1] In the following example, an AutoConnectButton as `button` addition is invalid. + +[^1]: The valid scope of the name is within an AutoConnectAux. + +```cpp hl_lines="3" +AutoConnectAux aux; +AutoConnectText text("hello", "hello, world"); +AutoConnectButton button("hello", "hello, world", "alert('Hello world!')"); // This is invalid. +aux.add({ text, button }); +``` + +Similarly this, the uniqueness of the name is also necessary within the JSON document + +```json hl_lines="12" +{ + "name" : "aux", + "uri" : "/aux", + "menu" : true, + "element" : [ + { + "name": "hello", + "type": "ACText", + "value": "hello, world" + }, + { + "name": "hello", + "type": "ACButton", + "value": "hello, world", + "action": "alert('Hello world!')" + } + ] +} +``` + +!!! note "Load all elements from JSON document" + If you load all AutoConnectElements from JSON document into AutoConnect, you do not need to sketch the population process of the AutoConnectElements. It is managed by the AutoConnect library automatically. + +### Get AutoConnectElement from the AutoConnectAux + +To retrieve an element from AutoConnectAux, use the getElement or getElements function. Normally, the getElement is needed when accessing the value of AutoConnectElement in the sketch. + +```cpp +AutoConnectElement* AutoConnectAux::getElement(const String& name); +``` + +```cpp +template T& AutoConnectAux::getElement(const String& name); +``` + +```cpp +AutoConnectElementVT* AutoConnectAux::getElements(void); +``` + +The [**getElement**](apiaux.md#getelement) function returns an AutoConnectElement with the specified name as a key. When you use this function, you need to know the type of AutoConnectElement in advance. To retrieve an AutoConnectElement by specifying its type, use the following method. + +```cpp +AutoConnectAux aux; +aux.load("SOME_JSON_DOCUMENT"); + +// Retrieve the pointer of the AutoConnectText +AutoConnectText* text = reinterpret_cast(aux.getElement("TEXT_ELEMENT_NAME")); + +// Retrieve the reference of the AutoConnectText +AutoConnectText& text = aux.getElement("TEXT_ELEMENT_NAME"); +``` + +The AutoConnectElement type behaves as a variant of other element types. Therefore use cast or template to convert to actual type as above. In the sketch, you access the real type of AutoConnectElement after casting it and storing into the variable. + +```cpp +const String auxJson = String("{\"title\":\"Page 1 title\",\"uri\":\"/page1\",\"menu\":true,\"element\":[{\"name\":\"caption\",\"type\":\"ACText\",\"value\":\"hello, world\"}]}"); +AutoConenct portal; +portal.load(auxJson); +AutoConnectAux* aux = portal.aux("/page1"); // Identify the AutoConnectAux instance with uri +AutoConenctText& text = aux->getElement("caption"); // Cast to real type and access members +Serial.println(text.value); +``` + +To get all the AutoConnectElements of an AutoConnectAux object use the [**getElements**](apiaux.md#getelements) function. This function returns the vector of the reference wrapper as *AutoConnectElementVT* to all AutoConnectElements registered in the AutoConnectAux. + +```cpp +AutoConnectElementVT& getElements(void) +``` + +*AutoConnectElementVT* is a predefined type for it and can use methods of [std::vector](https://en.cppreference.com/w/cpp/container/vector)<[std::reference_wrapper](https://en.cppreference.com/w/cpp/utility/functional/reference_wrapper)>. + +## Loading & saving AutoConnectElements ## Saving AutoConnectElements diff --git a/mkdocs/acintro.md b/mkdocs/acintro.md index 1ac3974..53f7fa8 100644 --- a/mkdocs/acintro.md +++ b/mkdocs/acintro.md @@ -63,10 +63,6 @@ In the sketch below, it shows the sequence of codes to integrate three custom We } ``` -## Passing parameters with sketches and custom Web pages - -A sketch can access variables of [AutoConnectElements](acelements.md) in the custom Web page. The value entered into the AutoConnectElements on the page is stored to the [member variables](acelements.md#form-and-autoconnectelements) of the element by AutoConnect whenever GET / POST transmission occurs. Your sketches can get these values with the GET / POST request handler. If you assign a value to an element before a request to the page occurs, its value will appear as the initial value when the page is displayed. - ## Basic steps to use custom Web pages So, the basic procedure for handling of the custom Web pages is as follows: @@ -163,7 +159,11 @@ void loop() { } ``` -[^3]: Installation of the [ArduinoJson](https://github.com/bblanchon/ArduinoJson) v.5.13.4 library is required. +[^3]: Installation of the [ArduinoJson](https://github.com/bblanchon/ArduinoJson) as the latest release of version 5 series is required. + +## Passing parameters with sketches and custom Web pages + +A sketch can access variables of [AutoConnectElements](acelements.md) in the custom Web page. The value entered into the AutoConnectElements on the page is stored to the [member variables](acelements.md#form-and-autoconnectelements) of the element by AutoConnect whenever GET / POST transmission occurs. Your sketches can get these values with the GET / POST request handler. If you assign a value to an element before a request to the page occurs, its value will appear as the initial value when the page is displayed. Details are explained in the [Parameter handling](achandling.md#parameter-handling). " + "" + "" + "
" + "{{MENU_PRE}}" + "{{MENU_POST}}" + "
" + "
{{CUR_SSID}}
" + "
" + "
" + "" + "" +}; + /**< A page announcing that a connection has been established. */ const char AutoConnect::_PAGE_SUCCESS[] PROGMEM = { "{{HEAD}}" @@ -802,6 +870,7 @@ String AutoConnect::_token_CSS_ICON_LOCK(PageArgument& args) { AC_UNUSED(args); return String(FPSTR(_CSS_ICON_LOCK)); } + String AutoConnect::_token_CSS_INPUT_BUTTON(PageArgument& args) { AC_UNUSED(args); return String(FPSTR(_CSS_INPUT_BUTTON)); @@ -817,6 +886,11 @@ String AutoConnect::_token_CSS_TABLE(PageArgument& args) { return String(FPSTR(_CSS_TABLE)); } +String AutoConnect::_token_CSS_SPINNER(PageArgument& args) { + AC_UNUSED(args); + return String(FPSTR(_CSS_SPINNER)); +} + String AutoConnect::_token_HEAD(PageArgument& args) { AC_UNUSED(args); return String(FPSTR(_ELM_HTML_HEAD)); @@ -1093,6 +1167,15 @@ String AutoConnect::_token_BOOTURI(PageArgument& args) { return String(""); } +String AutoConnect::_token_CURRENT_SSID(PageArgument& args) { + AC_UNUSED(args); + return String(reinterpret_cast(_credential.ssid)); +} + +String AutoConnect::_token_RESULT_URI(PageArgument& args) { + AC_UNUSED(args); + return _webServer->client().localIP().toString() + String(AUTOCONNECT_URI_RESULT); +} /** * This function dynamically build up the response pages that conform to @@ -1156,9 +1239,17 @@ PageElement* AutoConnect::_setupPage(String uri) { else if (uri == String(AUTOCONNECT_URI_CONNECT)) { // Setup /auto/connect - elm->setMold("{{REQ}}"); + elm->setMold(_PAGE_CONNECTING); elm->addToken(String(FPSTR("REQ")), std::bind(&AutoConnect::_induceConnect, this, std::placeholders::_1)); - } + elm->addToken(String(FPSTR("HEAD")), std::bind(&AutoConnect::_token_HEAD, this, std::placeholders::_1)); + elm->addToken(String(FPSTR("URI_RESULT")), std::bind(&AutoConnect::_token_RESULT_URI, this, std::placeholders::_1)); + elm->addToken(String(FPSTR("CSS_BASE")), std::bind(&AutoConnect::_token_CSS_BASE, this, std::placeholders::_1)); + elm->addToken(String(FPSTR("CSS_SPINNER")), std::bind(&AutoConnect::_token_CSS_SPINNER, this, std::placeholders::_1)); + elm->addToken(String(FPSTR("CSS_LUXBAR")), std::bind(&AutoConnect::_token_CSS_LUXBAR, this, std::placeholders::_1)); + elm->addToken(String(FPSTR("MENU_PRE")), std::bind(&AutoConnect::_token_MENU_PRE, this, std::placeholders::_1)); + elm->addToken(String(FPSTR("MENU_POST")), std::bind(&AutoConnect::_token_MENU_POST, this, std::placeholders::_1)); + elm->addToken(String(FPSTR("CUR_SSID")), std::bind(&AutoConnect::_token_CURRENT_SSID, this, std::placeholders::_1)); + } else if (uri == String(AUTOCONNECT_URI_OPEN)) { // Setup /auto/open From 48c6ea8b4ee7709f313d2c6f57b523268bd4547d Mon Sep 17 00:00:00 2001 From: Hieromon Ikasamo Date: Wed, 23 Jan 2019 21:39:43 +0900 Subject: [PATCH 3/4] Update String allocation --- src/AutoConnect.cpp | 16 ++++++++-------- src/AutoConnectDefs.h | 5 +++++ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/AutoConnect.cpp b/src/AutoConnect.cpp index d05d8cf..fe2aca6 100644 --- a/src/AutoConnect.cpp +++ b/src/AutoConnect.cpp @@ -51,7 +51,7 @@ void AutoConnect::_initialize() { _rfReset = false; _responsePage = nullptr; _currentPageElement = nullptr; - _menuTitle = String(AUTOCONNECT_MENU_TITLE); + _menuTitle = String(F(AUTOCONNECT_MENU_TITLE)); _connectTimeout = AUTOCONNECT_TIMEOUT; memset(&_credential, 0x00, sizeof(struct station_config)); #ifdef ARDUINO_ARCH_ESP32 @@ -450,7 +450,7 @@ void AutoConnect::handleRequest() { if (WiFi.BSSID() != NULL) { memcpy(_credential.bssid, WiFi.BSSID(), sizeof(station_config::bssid)); _currentHostIP = WiFi.localIP(); - _redirectURI = String(AUTOCONNECT_URI_SUCCESS); + _redirectURI = String(F(AUTOCONNECT_URI_SUCCESS)); // Save current credential if (_apConfig.autoSave == AC_SAVECREDENTIAL_AUTO) { @@ -467,7 +467,7 @@ void AutoConnect::handleRequest() { } else { _currentHostIP = WiFi.softAPIP(); - _redirectURI = String(AUTOCONNECT_URI_FAIL); + _redirectURI = String(F(AUTOCONNECT_URI_FAIL)); _rsConnect = WiFi.status(); _disconnectWiFi(false); while (WiFi.status() != WL_IDLE_STATUS && WiFi.status() != WL_DISCONNECTED) { @@ -598,9 +598,9 @@ void AutoConnect::_stopPortal() { bool AutoConnect::_captivePortal() { String hostHeader = _webServer->hostHeader(); if (!_isIP(hostHeader) && (hostHeader != WiFi.localIP().toString())) { - String location = String("http://") + _webServer->client().localIP().toString() + String(AUTOCONNECT_URI); - _webServer->sendHeader("Location", location, true); - _webServer->send(302, "text/plain", ""); + String location = String(F("http://")) + _webServer->client().localIP().toString() + String(AUTOCONNECT_URI); + _webServer->sendHeader(F("Location"), location, true); + _webServer->send(302, F("text/plain"), ""); _webServer->client().flush(); _webServer->client().stop(); return true; @@ -666,7 +666,7 @@ void AutoConnect::_handleNotFound() { */ String AutoConnect::_induceReset(PageArgument& args) { _rfReset = true; - return String("Reset in progress..."); + return String(F("Reset in progress...")); } /** @@ -706,7 +706,7 @@ String AutoConnect::_induceConnect(PageArgument& args) { // Turn on the trigger to start WiFi.begin(). _rfConnect = true; - _menuTitle = String("Connecting"); + _menuTitle = String(F(AUTOCONNECT_CONNECTING_TITLE)); // Since v0.9.7, the redirect method changed from a 302 response to the // meta tag with refresh attribute. diff --git a/src/AutoConnectDefs.h b/src/AutoConnectDefs.h index ad69bc8..16778f2 100644 --- a/src/AutoConnectDefs.h +++ b/src/AutoConnectDefs.h @@ -76,6 +76,11 @@ #define AUTOCONNECT_MENU_TITLE "AutoConnect" #endif // !AUTOCONNECT_MENU_TITLE +// AutoConnect title for during a connection attempting +#ifndef AUTOCONNECT_CONNECTING_TITLE +#define AUTOCONNECT_CONNECTING_TITLE "Connecting" +#endif // !AUTOCONNECT_CONNECTING_TITLE + // URIs of AutoConnect menu collection #define AUTOCONNECT_URI_CONFIG AUTOCONNECT_URI "/config" #define AUTOCONNECT_URI_CONNECT AUTOCONNECT_URI "/connect" From c428a33aa9f298bdf4baab011f7aeb1eecf428d9 Mon Sep 17 00:00:00 2001 From: Hieromon Ikasamo Date: Wed, 23 Jan 2019 23:58:09 +0900 Subject: [PATCH 4/4] Improved code readability --- src/AutoConnect.cpp | 1 - src/AutoConnect.h | 1 - src/AutoConnectDefs.h | 5 - src/AutoConnectPage.cpp | 761 ++++++++++++++++++++-------------------- 4 files changed, 379 insertions(+), 389 deletions(-) diff --git a/src/AutoConnect.cpp b/src/AutoConnect.cpp index fe2aca6..de76fda 100644 --- a/src/AutoConnect.cpp +++ b/src/AutoConnect.cpp @@ -706,7 +706,6 @@ String AutoConnect::_induceConnect(PageArgument& args) { // Turn on the trigger to start WiFi.begin(). _rfConnect = true; - _menuTitle = String(F(AUTOCONNECT_CONNECTING_TITLE)); // Since v0.9.7, the redirect method changed from a 302 response to the // meta tag with refresh attribute. diff --git a/src/AutoConnect.h b/src/AutoConnect.h index 530a84d..a54b81f 100644 --- a/src/AutoConnect.h +++ b/src/AutoConnect.h @@ -336,7 +336,6 @@ class AutoConnect { String _token_UPTIME(PageArgument& args); String _token_BOOTURI(PageArgument& args); String _token_CURRENT_SSID(PageArgument& args); - String _token_RESULT_URI(PageArgument& args); #if defined(ARDUINO_ARCH_ESP8266) friend class ESP8266WebServer; diff --git a/src/AutoConnectDefs.h b/src/AutoConnectDefs.h index 16778f2..ad69bc8 100644 --- a/src/AutoConnectDefs.h +++ b/src/AutoConnectDefs.h @@ -76,11 +76,6 @@ #define AUTOCONNECT_MENU_TITLE "AutoConnect" #endif // !AUTOCONNECT_MENU_TITLE -// AutoConnect title for during a connection attempting -#ifndef AUTOCONNECT_CONNECTING_TITLE -#define AUTOCONNECT_CONNECTING_TITLE "Connecting" -#endif // !AUTOCONNECT_CONNECTING_TITLE - // URIs of AutoConnect menu collection #define AUTOCONNECT_URI_CONFIG AUTOCONNECT_URI "/config" #define AUTOCONNECT_URI_CONNECT AUTOCONNECT_URI "/connect" diff --git a/src/AutoConnectPage.cpp b/src/AutoConnectPage.cpp index 98e4bbd..01b509c 100644 --- a/src/AutoConnectPage.cpp +++ b/src/AutoConnectPage.cpp @@ -3,7 +3,7 @@ * @file AutoConnectPage.h * @author hieromon@gmail.com * @version 0.9.7 - * @date 2018-11-17 + * @date 2019-01-23 * @copyright MIT license. */ @@ -24,192 +24,192 @@ extern "C" { /**< Basic CSS common to all pages */ const char AutoConnect::_CSS_BASE[] PROGMEM = { "html{" - "font-family:Helvetica,Arial,sans-serif;" - "font-size:16px;" - "-ms-text-size-adjust:100%;" - "-webkit-text-size-adjust:100%;" - "-moz-osx-font-smoothing:grayscale;" - "-webkit-font-smoothing:antialiased;" + "font-family:Helvetica,Arial,sans-serif;" + "font-size:16px;" + "-ms-text-size-adjust:100%;" + "-webkit-text-size-adjust:100%;" + "-moz-osx-font-smoothing:grayscale;" + "-webkit-font-smoothing:antialiased;" "}" "body{" - "margin:0;" - "padding:0;" + "margin:0;" + "padding:0;" "}" ".base-panel{" - "margin:0 22px 0 22px;" + "margin:0 22px 0 22px;" "}" ".base-panel>*>label{" - "display:inline-block;" - "width:3.0em;" - "text-align:right;" + "display:inline-block;" + "width:3.0em;" + "text-align:right;" "}" "input{" - "-moz-appearance:none;" - "-webkit-appearance:none;" - "font-size:0.9em;" - "margin:8px 0 auto;" + "-moz-appearance:none;" + "-webkit-appearance:none;" + "font-size:0.9em;" + "margin:8px 0 auto;" "}" ".lap{" - "visibility:collapse;" + "visibility:collapse;" "}" ".lap:target{" - "visibility:visible;" + "visibility:visible;" "}" ".lap:target .overlap{" - "opacity:0.7;" - "transition:0.3s;" + "opacity:0.7;" + "transition:0.3s;" "}" ".lap:target .modal_button{" - "opacity:1;" - "transition:0.3s;" + "opacity:1;" + "transition:0.3s;" "}" ".overlap{" - "top:0;" - "left:0;" - "width:100%;" - "height:100%;" - "position:fixed;" - "opacity:0;" - "background:#000;" - "z-index:1000;" + "top:0;" + "left:0;" + "width:100%;" + "height:100%;" + "position:fixed;" + "opacity:0;" + "background:#000;" + "z-index:1000;" "}" ".modal_button{" - "border-radius:13px;" - "background:#660033;" - "color:#ffffcc;" - "padding:20px 30px;" - "text-align:center;" - "text-decoration:none;" - "letter-spacing:1px;" - "font-weight:bold;" - "display:inline-block;" - "top:40%;" - "left:40%;" - "width:20%;" - "position:fixed;" - "opacity:0;" - "z-index:1001;" + "border-radius:13px;" + "background:#660033;" + "color:#ffffcc;" + "padding:20px 30px;" + "text-align:center;" + "text-decoration:none;" + "letter-spacing:1px;" + "font-weight:bold;" + "display:inline-block;" + "top:40%;" + "left:40%;" + "width:20%;" + "position:fixed;" + "opacity:0;" + "z-index:1001;" "}" }; /**< non-marked list for UL */ const char AutoConnect::_CSS_UL[] PROGMEM = { "ul.noorder{" - "padding:0;" - "list-style:none;" + "padding:0;" + "list-style:none;" "}" "ul.noorder>*>label{" - "display:inline-block;" - "width:86px;" - "margin-right:10px;" - "text-align:right;" + "display:inline-block;" + "width:86px;" + "margin-right:10px;" + "text-align:right;" "}" "ul.noorder>input[type=\"checkbox\"]{" - "-moz-appearance:checkbox;" - "-webkit-appearance:checkbox;" + "-moz-appearance:checkbox;" + "-webkit-appearance:checkbox;" "}" "ul.noorder>input[type=\"radio\"]{" - "margin-right:0.5em;" - "-moz-appearance:radio;" - "-webkit-appearance:radio;" + "margin-right:0.5em;" + "-moz-appearance:radio;" + "-webkit-appearance:radio;" "}" }; /**< Image icon for inline expansion, the lock mark. */ const char AutoConnect::_CSS_ICON_LOCK[] PROGMEM = { ".img-lock{" - "display:inline-block;" - "width:24px;" - "height:24px;" - "margin-left:12px;" - "vertical-align:middle;" - "background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsTAAALEwEAmpwYAAAB1ElEQVRIibWVu0scURTGf3d2drBQFAWbbRQVCwuVLIZdi2gnWIiF/4GtKyuJGAJh8mgTcU0T8T8ICC6kiIVu44gvtFEQQWwsbExQJGHXmZtiZsOyzCN3Vz+4cDjfvec7j7l3QAF95onRZ54YKmdE1IbnS0c9mnAyAjkBxDy3LRHrjtRyu7OD52HntTAyvbw/HxP2hkCearrRb2WSCSuTTGi60S+QpzFhbwznDl/VVMHw0sF7hEjFbW2qkB38lfp8nNDipWcATil+uDM3cDWyeNRSijnfkHJnezb5Vkkgvbg3IOXD2e1ts93S+icnkZOAVaalZK3YQMa4L+pC6L1WduhYSeCf0PLBdxzOjZ93Lwvm6APAiLmlF1ubPiHotmaS41ExQjH0ZbfNM1NAFpgD0lVcICIrANqAVaAd+AFIYAy4BqaBG+Wsq5AH3vgk8xpYrzf4KLAZwhe8PYEIvQe4vc6H8Hnc2dQs0AFchvAXQGdEDF8s4A5TZS34BQqqQNaS1WMI3KD4WUbNoBJfce9CO7BSr4BfBe8A21vmUwh0VdjdTyHwscL+UK+AHxoD7FDoAX6/Cnpxn4ay/egCjcCL/w1chkqLakLQ/6ABhT57uAd+Vzv/Ara3iY6fK4WxAAAAAElFTkSuQmCC) no-repeat;" + "display:inline-block;" + "width:24px;" + "height:24px;" + "margin-left:12px;" + "vertical-align:middle;" + "background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsTAAALEwEAmpwYAAAB1ElEQVRIibWVu0scURTGf3d2drBQFAWbbRQVCwuVLIZdi2gnWIiF/4GtKyuJGAJh8mgTcU0T8T8ICC6kiIVu44gvtFEQQWwsbExQJGHXmZtiZsOyzCN3Vz+4cDjfvec7j7l3QAF95onRZ54YKmdE1IbnS0c9mnAyAjkBxDy3LRHrjtRyu7OD52HntTAyvbw/HxP2hkCearrRb2WSCSuTTGi60S+QpzFhbwznDl/VVMHw0sF7hEjFbW2qkB38lfp8nNDipWcATil+uDM3cDWyeNRSijnfkHJnezb5Vkkgvbg3IOXD2e1ts93S+icnkZOAVaalZK3YQMa4L+pC6L1WduhYSeCf0PLBdxzOjZ93Lwvm6APAiLmlF1ubPiHotmaS41ExQjH0ZbfNM1NAFpgD0lVcICIrANqAVaAd+AFIYAy4BqaBG+Wsq5AH3vgk8xpYrzf4KLAZwhe8PYEIvQe4vc6H8Hnc2dQs0AFchvAXQGdEDF8s4A5TZS34BQqqQNaS1WMI3KD4WUbNoBJfce9CO7BSr4BfBe8A21vmUwh0VdjdTyHwscL+UK+AHxoD7FDoAX6/Cnpxn4ay/egCjcCL/w1chkqLakLQ/6ABhT57uAd+Vzv/Ara3iY6fK4WxAAAAAElFTkSuQmCC) no-repeat;" "}" }; /**< INPUT button and submit style */ const char AutoConnect::_CSS_INPUT_BUTTON[] PROGMEM = { "input[type=\"button\"],input[type=\"submit\"]{" - "padding:8px 30px;" - "font-weight:bold;" - "letter-spacing:0.8px;" - "color:#fff;" - "border:1px solid;" - "border-radius:2px;" - "margin-top:12px;" + "padding:8px 30px;" + "font-weight:bold;" + "letter-spacing:0.8px;" + "color:#fff;" + "border:1px solid;" + "border-radius:2px;" + "margin-top:12px;" "}" "input[type=\"button\"]{" - "background-color:#1b5e20;" - "border-color:#1b5e20;" - "width:16em;" + "background-color:#1b5e20;" + "border-color:#1b5e20;" + "width:16em;" "}" ".aux-page input[type=\"button\"]{" - "font-weight:normal;" - "padding:8px 14px;" - "margin:12px;" - "width:auto;" + "font-weight:normal;" + "padding:8px 14px;" + "margin:12px;" + "width:auto;" "}" "input#sb[type=\"submit\"]{" - "width:16em;" + "width:16em;" "}" "input[type=\"submit\"]{" - "background-color:#006064;" - "border-color:#006064;" + "background-color:#006064;" + "border-color:#006064;" "}" "input[type=\"button\"], input[type=\"submit\"]:focus," "input[type=\"button\"], input[type=\"submit\"]:active{" - "outline:none;" - "text-decoration:none;" + "outline:none;" + "text-decoration:none;" "}" }; /**< INPUT text style */ const char AutoConnect::_CSS_INPUT_TEXT[] PROGMEM = { "input[type=\"text\"], input[type=\"password\"], .aux-page select{" - "background-color:#fff;" - "border:1px solid #ccc;" - "border-radius:2px;" - "color:#444;" - "margin:8px 0 8px 0;" - "padding:10px;" + "background-color:#fff;" + "border:1px solid #ccc;" + "border-radius:2px;" + "color:#444;" + "margin:8px 0 8px 0;" + "padding:10px;" "}" "input[type=\"text\"], input[type=\"password\"]{" - "font-weight:300;" - "width:calc(100% - 124px);" - "-webkit-transition:all 0.20s ease-in;" - "-moz-transition:all 0.20s ease-in;" - "-o-transition:all 0.20s ease-in;" - "-ms-transition:all 0.20s ease-in;" - "transition:all 0.20s ease-in;" + "font-weight:300;" + "width:calc(100% - 124px);" + "-webkit-transition:all 0.20s ease-in;" + "-moz-transition:all 0.20s ease-in;" + "-o-transition:all 0.20s ease-in;" + "-ms-transition:all 0.20s ease-in;" + "transition:all 0.20s ease-in;" "}" "input[type=\"text\"]:focus,input[type=\"password\"]:focus{" - "outline:none;" - "border-color:#5C9DED;" - "box-shadow:0 0 3px #4B8CDC;" + "outline:none;" + "border-color:#5C9DED;" + "box-shadow:0 0 3px #4B8CDC;" "}" "input.error, input.error:focus{" - "border-color:#ED5564;" - "color:#D9434E;" - "box-shadow:0 0 3px #D9434E;" + "border-color:#ED5564;" + "color:#D9434E;" + "box-shadow:0 0 3px #D9434E;" "}" "input:disabled{" - "opacity:0.6;" - "background-color:#f7f7f7;" + "opacity:0.6;" + "background-color:#f7f7f7;" "}" "input:disabled:hover{" - "cursor:not-allowed;" + "cursor:not-allowed;" "}" - "input.error::-webkit-input-placeholder{" - "color:#D9434E;" + "input.error::-webkit-input-placeholder{" + "color:#D9434E;" "}" "input.error:-moz-placeholder{" - "color:#D9434E;" + "color:#D9434E;" "}" "input.error::-moz-placeholder{" - "color:#D9434E;" + "color:#D9434E;" "}" "input.error:-ms-input-placeholder{" - "color:#D9434E;" + "color:#D9434E;" "}" ".aux-page label{" "padding:10px 0.5em;" @@ -219,54 +219,54 @@ const char AutoConnect::_CSS_INPUT_TEXT[] PROGMEM = { /**< TABLE style */ const char AutoConnect::_CSS_TABLE[] PROGMEM = { "table{" - "border-collapse:collapse;" - "border-spacing:0;" - "border:1px solid #ddd;" - "color:#444;" - "background-color:#fff;" - "margin-bottom:20px;" + "border-collapse:collapse;" + "border-spacing:0;" + "border:1px solid #ddd;" + "color:#444;" + "background-color:#fff;" + "margin-bottom:20px;" "}" "table.info," "table.info>tfoot," "table.info>thead{" - "width:100%;" - "border-color:#5C9DED;" + "width:100%;" + "border-color:#5C9DED;" "}" "table.info>thead{" - "background-color:#5C9DED;" + "background-color:#5C9DED;" "}" "table.info>thead>tr>th{" - "color:#fff;" + "color:#fff;" "}" "td," "th{" - "padding:10px 22px;" + "padding:10px 22px;" "}" "thead{" - "background-color:#f3f3f3;" - "border-bottom:1px solid #ddd;" + "background-color:#f3f3f3;" + "border-bottom:1px solid #ddd;" "}" "thead>tr>th{" - "font-weight:400;" - "text-align:left;" + "font-weight:400;" + "text-align:left;" "}" "tfoot{" - "border-top:1px solid #ddd;" + "border-top:1px solid #ddd;" "}" "tbody," "tbody>tr:nth-child(odd){" - "background-color:#fff;" + "background-color:#fff;" "}" "tbody>tr>td," "tfoot>tr>td{" - "font-weight:300;" - "font-size:.88em;" + "font-weight:300;" + "font-size:.88em;" "}" "tbody>tr:nth-child(even){" - "background-color:#f7f7f7;" + "background-color:#f7f7f7;" "}" - "table.info tbody>tr:nth-child(even){" - "background-color:#EFF5FD;" + "table.info tbody>tr:nth-child(even){" + "background-color:#EFF5FD;" "}" }; @@ -291,18 +291,18 @@ const char AutoConnect::_CSS_SPINNER[] PROGMEM = { "animation:sk-bounce 2.0s infinite ease-in-out;" "}" ".double-bounce2{" - "-webkit-animation-delay: -1.0s;" - "animation-delay: -1.0s;" + "-webkit-animation-delay:-1.0s;" + "animation-delay:-1.0s;" "}" "@-webkit-keyframes sk-bounce{" - "0%, 100% {-webkit-transform:scale(0.0)}" - "50% {-webkit-transform:scale(1.0)}" + "0%, 100%{-webkit-transform:scale(0.0)}" + "50%{-webkit-transform:scale(1.0)}" "}" "@keyframes sk-bounce{" - "0%, 100% {" + "0%,100%{" "transform:scale(0.0);" "-webkit-transform:scale(0.0);" - "} 50% {" + "}50%{" "transform:scale(1.0);" "-webkit-transform:scale(1.0);" "}" @@ -503,46 +503,46 @@ const char AutoConnect::_ELM_HTML_HEAD[] PROGMEM = { "" "" "" - "" + "" }; /**< LuxBar menu element. */ const char AutoConnect::_ELM_MENU_PRE[] PROGMEM = { "
" - "" - "
" - "" + "
" + "
" + "" + "
" "
" }; /**< The 404 page content. */ const char AutoConnect::_PAGE_404[] PROGMEM = { "{{HEAD}}" - "Page not found" + "Page not found" "" "" - "404 Not found" + "404 Not found" "" "" }; @@ -550,11 +550,11 @@ const char AutoConnect::_PAGE_404[] PROGMEM = { /**< The page that started the reset. */ const char AutoConnect::_PAGE_RESETTING[] PROGMEM = { "{{HEAD}}" - "" - "AutoConnect resetting" + "" + "AutoConnect resetting" "" "" - "

{{RESET}}

" + "

{{RESET}}

" "" "" }; @@ -562,81 +562,81 @@ const char AutoConnect::_PAGE_RESETTING[] PROGMEM = { /**< AutoConnect portal page. */ const char AutoConnect::_PAGE_STAT[] PROGMEM = { "{{HEAD}}" - "AutoConnect statistics" - "" + "AutoConnect statistics" + "" "" "" - "
" - "{{MENU_PRE}}" - "{{MENU_AUX}}" - "{{MENU_POST}}" - "
" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "
Established connection{{ESTAB_SSID}}
Mode{{WIFI_MODE}}({{WIFI_STATUS}})
IP{{LOCAL_IP}}
GW{{GATEWAY}}
Subnet mask{{NETMASK}}
SoftAP IP{{SOFTAP_IP}}
AP MAC{{AP_MAC}}
STA MAC{{STA_MAC}}
Channel{{CHANNEL}}
dBm{{DBM}}
Chip ID{{CHIP_ID}}
CPU Freq.{{CPU_FREQ}}MHz
Flash size{{FLASH_SIZE}}
Free memory{{FREE_HEAP}}
" - "
" - "
" + "
" + "{{MENU_PRE}}" + "{{MENU_AUX}}" + "{{MENU_POST}}" + "
" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "
Established connection{{ESTAB_SSID}}
Mode{{WIFI_MODE}}({{WIFI_STATUS}})
IP{{LOCAL_IP}}
GW{{GATEWAY}}
Subnet mask{{NETMASK}}
SoftAP IP{{SOFTAP_IP}}
AP MAC{{AP_MAC}}
STA MAC{{STA_MAC}}
Channel{{CHANNEL}}
dBm{{DBM}}
Chip ID{{CHIP_ID}}
CPU Freq.{{CPU_FREQ}}MHz
Flash size{{FLASH_SIZE}}
Free memory{{FREE_HEAP}}
" + "
" + "
" "" "" }; @@ -644,39 +644,39 @@ const char AutoConnect::_PAGE_STAT[] PROGMEM = { /**< A page that specifies the new configuration. */ const char AutoConnect::_PAGE_CONFIGNEW[] PROGMEM = { "{{HEAD}}" - "AutoConnect config" - "" + "AutoConnect config" + "" "" "" - "
" - "{{MENU_PRE}}" - "{{MENU_AUX}}" - "{{MENU_POST}}" - "
" - "
" - "{{LIST_SSID}}" - "
Hidden:{{HIDDEN_COUNT}}
" - "
    " - "
  • " - "" - "" - "
  • " - "
  • " - "" - "" - "
  • " - "
  • " - "
" - "
" - "
" - "
" + "
" + "{{MENU_PRE}}" + "{{MENU_AUX}}" + "{{MENU_POST}}" + "
" + "
" + "{{LIST_SSID}}" + "
Hidden:{{HIDDEN_COUNT}}
" + "
    " + "
  • " + "" + "" + "
  • " + "
  • " + "" + "" + "
  • " + "
  • " + "
" + "
" + "
" + "
" "" "" }; @@ -684,25 +684,25 @@ const char AutoConnect::_PAGE_CONFIGNEW[] PROGMEM = { /**< A page that reads stored authentication information and starts connection. */ const char AutoConnect::_PAGE_OPENCREDT[] PROGMEM = { "{{HEAD}}" - "AutoConnect credentials" - "" + "AutoConnect credentials" + "" "" "" - "
" - "{{MENU_PRE}}" - "{{MENU_AUX}}" - "{{MENU_POST}}" - "
" - "
" - "{{OPEN_SSID}}" - "
" - "
" - "
" + "
" + "{{MENU_PRE}}" + "{{MENU_AUX}}" + "{{MENU_POST}}" + "
" + "
" + "{{OPEN_SSID}}" + "
" + "
" + "
" "" "" }; @@ -711,27 +711,29 @@ const char AutoConnect::_PAGE_OPENCREDT[] PROGMEM = { const char AutoConnect::_PAGE_CONNECTING[] PROGMEM = { "{{REQ}}" "{{HEAD}}" - "" - "AutoConnect connecting" - "" - "" + "" + "AutoConnect connecting" + "" + "" "" "" - "
" - "{{MENU_PRE}}" - "{{MENU_POST}}" - "
" - "
{{CUR_SSID}}
" - "
" - "
" + "
" + "{{MENU_PRE}}" + "{{MENU_POST}}" + "
" + "
{{CUR_SSID}}
" + "
" + "
" + "
" + "
" "" "" }; @@ -739,52 +741,52 @@ const char AutoConnect::_PAGE_CONNECTING[] PROGMEM = { /**< A page announcing that a connection has been established. */ const char AutoConnect::_PAGE_SUCCESS[] PROGMEM = { "{{HEAD}}" - "AutoConnect statistics" - "" + "AutoConnect statistics" + "" "" "" - "
" - "{{MENU_PRE}}" - "{{MENU_AUX}}" - "{{MENU_POST}}" - "
" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "
Established connection{{ESTAB_SSID}}
Mode{{WIFI_MODE}}({{WIFI_STATUS}})
IP{{LOCAL_IP}}
GW{{GATEWAY}}
Subnet mask{{NETMASK}}
Channel{{CHANNEL}}
dBm{{DBM}}
" - "
" - "
" + "
" + "{{MENU_PRE}}" + "{{MENU_AUX}}" + "{{MENU_POST}}" + "
" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "
Established connection{{ESTAB_SSID}}
Mode{{WIFI_MODE}}({{WIFI_STATUS}})
IP{{LOCAL_IP}}
GW{{GATEWAY}}
Subnet mask{{NETMASK}}
Channel{{CHANNEL}}
dBm{{DBM}}
" + "
" + "
" "" "" }; @@ -792,29 +794,29 @@ const char AutoConnect::_PAGE_SUCCESS[] PROGMEM = { /**< A response page for connection failed. */ const char AutoConnect::_PAGE_FAIL[] PROGMEM = { "{{HEAD}}" - "AutoConnect statistics" - "" + "AutoConnect statistics" + "" "" "" - "
" - "{{MENU_PRE}}" - "{{MENU_AUX}}" - "{{MENU_POST}}" - "
" - "" - "" - "" - "" - "" - "" - "" - "
Connection Failed{{STATION_STATUS}}
" - "
" - "
" + "
" + "{{MENU_PRE}}" + "{{MENU_AUX}}" + "{{MENU_POST}}" + "
" + "" + "" + "" + "" + "" + "" + "" + "
Connection Failed{{STATION_STATUS}}
" + "
" + "
" "" "" }; @@ -823,17 +825,17 @@ const char AutoConnect::_PAGE_FAIL[] PROGMEM = { const char AutoConnect::_PAGE_DISCONN[] PROGMEM = { "{{DISCONNECT}}" "{{HEAD}}" - "AutoConnect disconnected" - "" + "AutoConnect disconnected" + "" "" "" - "
" - "{{MENU_PRE}}" - "{{MENU_AUX}}" - "{{MENU_POST}}" + "
" + "{{MENU_PRE}}" + "{{MENU_POST}}" + "
" "" "" }; @@ -1172,11 +1174,6 @@ String AutoConnect::_token_CURRENT_SSID(PageArgument& args) { return String(reinterpret_cast(_credential.ssid)); } -String AutoConnect::_token_RESULT_URI(PageArgument& args) { - AC_UNUSED(args); - return _webServer->client().localIP().toString() + String(AUTOCONNECT_URI_RESULT); -} - /** * This function dynamically build up the response pages that conform to * the requested URI. A PageBuilder instance is stored in _rensponsePage @@ -1239,10 +1236,10 @@ PageElement* AutoConnect::_setupPage(String uri) { else if (uri == String(AUTOCONNECT_URI_CONNECT)) { // Setup /auto/connect + _menuTitle = FPSTR("Connecting"); elm->setMold(_PAGE_CONNECTING); elm->addToken(String(FPSTR("REQ")), std::bind(&AutoConnect::_induceConnect, this, std::placeholders::_1)); elm->addToken(String(FPSTR("HEAD")), std::bind(&AutoConnect::_token_HEAD, this, std::placeholders::_1)); - elm->addToken(String(FPSTR("URI_RESULT")), std::bind(&AutoConnect::_token_RESULT_URI, this, std::placeholders::_1)); elm->addToken(String(FPSTR("CSS_BASE")), std::bind(&AutoConnect::_token_CSS_BASE, this, std::placeholders::_1)); elm->addToken(String(FPSTR("CSS_SPINNER")), std::bind(&AutoConnect::_token_CSS_SPINNER, this, std::placeholders::_1)); elm->addToken(String(FPSTR("CSS_LUXBAR")), std::bind(&AutoConnect::_token_CSS_LUXBAR, this, std::placeholders::_1)); @@ -1274,7 +1271,6 @@ PageElement* AutoConnect::_setupPage(String uri) { elm->addToken(String(FPSTR("CSS_BASE")), std::bind(&AutoConnect::_token_CSS_BASE, this, std::placeholders::_1)); elm->addToken(String(FPSTR("CSS_LUXBAR")), std::bind(&AutoConnect::_token_CSS_LUXBAR, this, std::placeholders::_1)); elm->addToken(String(FPSTR("MENU_PRE")), std::bind(&AutoConnect::_token_MENU_PRE, this, std::placeholders::_1)); - elm->addToken(String(FPSTR("MENU_AUX")), std::bind(&AutoConnect::_token_MENU_AUX, this, std::placeholders::_1)); elm->addToken(String(FPSTR("MENU_POST")), std::bind(&AutoConnect::_token_MENU_POST, this, std::placeholders::_1)); } else if (uri == String(AUTOCONNECT_URI_RESET)) { @@ -1315,6 +1311,7 @@ PageElement* AutoConnect::_setupPage(String uri) { else if (uri == String(AUTOCONNECT_URI_FAIL)) { // Setup /auto/fail + _menuTitle = FPSTR("Failed"); elm->setMold(_PAGE_FAIL); elm->addToken(String(FPSTR("HEAD")), std::bind(&AutoConnect::_token_HEAD, this, std::placeholders::_1)); elm->addToken(String(FPSTR("CSS_BASE")), std::bind(&AutoConnect::_token_CSS_BASE, this, std::placeholders::_1));