Supports AutoConnectAux

pull/41/head
Hieromon Ikasamo 6 years ago
parent cfa63c531e
commit 8652dadfaf
  1. 7
      keywords.txt
  2. 23
      src/AutoConnect.cpp
  3. 9
      src/AutoConnect.h
  4. 252
      src/AutoConnectAux.cpp
  5. 15
      src/AutoConnectAux.h
  6. 4
      src/AutoConnectElement.h
  7. 3
      src/AutoConnectElementBasis.h
  8. 8
      src/AutoConnectElementBasisImpl.h
  9. 4
      src/AutoConnectElementJson.h
  10. 1
      src/AutoConnectElementJsonImpl.h

@ -23,12 +23,14 @@ begin KEYWORD2
del KEYWORD2
end KEYWORD2
entries KEYWORD2
getElement KEYWORD2
handleClient KEYWORD2
handleRequest KEYWORD2
home KEYWORD2
host KEYWORD2
join KEYWORD2
load KEYWORD2
loadElement KEYWORD2
menu KEYWORD2
name KEYWORD2
on KEYWORD2
@ -47,6 +49,11 @@ AC_WEBSERVER_PARASITIC LITERAL1
AC_WEBSERVER_HOSTED LITERAL1
AC_SAVECREDENTIAL_NEVER LITERAL1
AC_SAVECREDENTIAL_AUTO LITERAL1
AC_URIONBOOT_ROOT LITERAL1
AC_URIONBOOT_HOME LITERAL1
AC_EXIT_AHEAD LITERAL1
AC_EXIT_LATER LITERAL1
AC_EXIT_BOTH LITERAL1
#######################################
# PREPROCESSOR (KEYWORD3)

@ -424,6 +424,29 @@ void AutoConnect::handleRequest() {
}
}
/**
* Register the exit routine for AutoConnectAux.
* @param uri Specify the URI of the AutoConnectAux page that
* registers the exit routine.
* @param handler A handler function of the exit routine.
* @param order Specify an enumeration type of
* AutoConnectExitOrder_t for the call timing of the exit routine.
* @return true An exit routine registered.
* @return false AutoConnectAux page for the specified URI is not
* registered.
*/
bool AutoConnect::on(const char* uri, const AuxHandlerFunctionT handler, AutoConnectExitOrder_t order) {
AutoConnectAux* aux = _aux.get();
while (aux) {
if (!strcmp(uri, aux->uri())) {
aux->on(handler, order);
return true;
}
aux = aux->_next.get();
}
return false;
}
/**
* Register the exit routine for the starting captive portal.
* @param fn A function of the exit routine.

@ -165,14 +165,15 @@ class AutoConnect {
WebServerClass& host();
bool join(AutoConnectAux& aux);
bool join(std::vector<std::reference_wrapper<AutoConnectAux>> aux);
bool on(const char* uri, const AuxHandlerFunctionT handler, AutoConnectExitOrder_t order = AC_EXIT_AHEAD);
/** For AutoConnectAux described in JSON */
#ifdef AUTOCONNECT_USE_JSON
bool join(const char* aux);
bool join(const __FlashStringHelper* aux);
bool join(Stream& aux, size_t bufferSize = AUTOCONNECT_JSON_BUFFER_SIZE);
bool load(const char* aux);
bool load(const __FlashStringHelper* aux);
bool load(Stream& aux, size_t bufferSize = AUTOCONNECT_JSON_BUFFER_SIZE);
bool _load(JsonVariant& aux);
#endif
#endif // !AUTOCONNECT_USE_JSON
typedef std::function<bool(IPAddress)> DetectExit_ft;
void onDetect(DetectExit_ft fn);

@ -88,6 +88,18 @@ void AutoConnectAux::add(AutoConnectElementVT addons) {
add(addons[n]);
}
/**
* Get already registered AutoConnectElement.
* @param name Element name
* @return A pointer to the registered AutoConnectElement.
*/
AutoConnectElement* AutoConnectAux::getElement(const String name) {
for (std::size_t n = 0; n < _addonElm.size(); n++)
if (_addonElm[n].get().name == name)
return &(_addonElm[n].get());
return nullptr;
}
/**
* Releases the AutoConnectElements with the specified name from
* the AutoConnectAux page. Releases all AutoConnectElements with
@ -153,7 +165,7 @@ const String AutoConnectAux::_insertElement(PageArgument& args) {
if (_handler) {
if (_order & AC_EXIT_AHEAD) {
AC_DBG("CB %s\n", uri());
body += _handler(args);
body += _handler(*this, args);
}
}
@ -165,7 +177,7 @@ const String AutoConnectAux::_insertElement(PageArgument& args) {
if (_handler) {
if (_order & AC_EXIT_LATER) {
AC_DBG("CB %s\n", uri());
body += _handler(args);
body += _handler(*this, args);
}
}
@ -232,7 +244,114 @@ const String AutoConnectAux::_injectMenu(PageArgument& args) {
return menuItem;
}
#ifdef AUTOCONNECT_USE_JSON
#ifndef AUTOCONNECT_USE_JSON
/**
* Get AutoConnectButtonBasis element.
* @param name An element name.
* @return A reference of AutoConnectButton class.
*/
template<>
AutoConnectButtonBasis& AutoConnectAux::getElement(const String name) {
AutoConnectElement* elm = getElement(name);
if (elm) {
if (elm->typeOf() == AC_Button)
return *(reinterpret_cast<AutoConnectButtonBasis*>(elm));
}
return reinterpret_cast<AutoConnectButtonBasis&>(_nullElement());
}
/**
* Get AutoConnectCheckboxBasis element.
* @param name An element name.
* @return A reference of AutoConnectCheckbox class.
*/
template<>
AutoConnectCheckboxBasis& AutoConnectAux::getElement(const String name) {
AutoConnectElement* elm = getElement(name);
if (elm) {
if (elm->typeOf() == AC_Checkbox)
return *(reinterpret_cast<AutoConnectCheckboxBasis*>(elm));
}
return reinterpret_cast<AutoConnectCheckboxBasis&>(_nullElement());
}
/**
* Get AutoConnectInputBasis element.
* @param name An element name.
* @return A reference of AutoConnectInput class.
*/
template<>
AutoConnectInputBasis& AutoConnectAux::getElement(const String name) {
AutoConnectElement* elm = getElement(name);
if (elm) {
if (elm->typeOf() == AC_Input)
return *(reinterpret_cast<AutoConnectInputBasis*>(elm));
}
return reinterpret_cast<AutoConnectInputBasis&>(_nullElement());
}
/**
* Get AutoConnectRadioBasis element.
* @param name An element name.
* @return A reference of AutoConnectRadio class.
*/
template<>
AutoConnectRadioBasis& AutoConnectAux::getElement(const String name) {
AutoConnectElement* elm = getElement(name);
if (elm) {
if (elm->typeOf() == AC_Radio)
return *(reinterpret_cast<AutoConnectRadioBasis*>(elm));
}
return reinterpret_cast<AutoConnectRadioBasis&>(_nullElement());
}
/**
* Get AutoConnectSelectBasis element.
* @param name An element name.
* @return A reference of AutoConnectSelect class.
*/
template<>
AutoConnectSelectBasis& AutoConnectAux::getElement(const String name) {
AutoConnectElement* elm = getElement(name);
if (elm) {
if (elm->typeOf() == AC_Select)
return *(reinterpret_cast<AutoConnectSelectBasis*>(elm));
}
return reinterpret_cast<AutoConnectSelectBasis&>(_nullElement());
}
/**
* Get AutoConnectSubmitBasis element.
* @param name An element name.
* @return A reference of AutoConnectSubmit class.
*/
template<>
AutoConnectSubmitBasis& AutoConnectAux::getElement(const String name) {
AutoConnectElement* elm = getElement(name);
if (elm) {
if (elm->typeOf() == AC_Submit)
return *(reinterpret_cast<AutoConnectSubmitBasis*>(elm));
}
return reinterpret_cast<AutoConnectSubmitBasis&>(_nullElement());
}
/**
* Get AutoConnectTextBasis element.
* @param name An element name.
* @return A reference of AutoConnectText class.
*/
template<>
AutoConnectTextBasis& AutoConnectAux::getElement(const String name) {
AutoConnectElement* elm = getElement(name);
if (elm) {
if (elm->typeOf() == AC_Text)
return *(reinterpret_cast<AutoConnectTextBasis*>(elm));
}
return reinterpret_cast<AutoConnectTextBasis&>(_nullElement());
}
#else
/**
* Static storage for JSON buffer size calculation.
@ -249,6 +368,111 @@ int8_t AutoConnectAux::_np; /**< Stack pointer for JSON object counter
bool AutoConnectAux::_jbOpen; /**< JSON object paring status */
bool AutoConnectAux::_jbLiteral; /**< JSON object lexical status */
/**
* Get AutoConnectButtonJson element.
* @param name An element name.
* @return A reference of AutoConnectButton class.
*/
template<>
AutoConnectButtonJson& AutoConnectAux::getElement(const String name) {
AutoConnectElement* elm = getElement(name);
if (elm) {
if (elm->typeOf() == AC_Button)
return *(reinterpret_cast<AutoConnectButtonJson*>(elm));
}
return reinterpret_cast<AutoConnectButtonJson&>(_nullElement());
}
/**
* Get AutoConnectCheckboxJson element.
* @param name An element name.
* @return A reference of AutoConnectCheckbox class.
*/
template<>
AutoConnectCheckboxJson& AutoConnectAux::getElement(const String name) {
AutoConnectElement* elm = getElement(name);
if (elm) {
if (elm->typeOf() == AC_Checkbox)
return *(reinterpret_cast<AutoConnectCheckboxJson*>(elm));
}
return reinterpret_cast<AutoConnectCheckboxJson&>(_nullElement());
}
/**
* Get AutoConnectInputJson element.
* @param name An element name.
* @return A reference of AutoConnectInput class.
*/
template<>
AutoConnectInputJson& AutoConnectAux::getElement(const String name) {
AutoConnectElement* elm = getElement(name);
if (elm) {
if (elm->typeOf() == AC_Input)
return *(reinterpret_cast<AutoConnectInputJson*>(elm));
}
return reinterpret_cast<AutoConnectInputJson&>(_nullElement());
}
/**
* Get AutoConnectRadioJson element.
* @param name An element name.
* @return A reference of AutoConnectRadio class.
*/
template<>
AutoConnectRadioJson& AutoConnectAux::getElement(const String name) {
AutoConnectElement* elm = getElement(name);
if (elm) {
if (elm->typeOf() == AC_Radio)
return *(reinterpret_cast<AutoConnectRadioJson*>(elm));
}
return reinterpret_cast<AutoConnectRadioJson&>(_nullElement());
}
/**
* Get AutoConnectSelectJson element.
* @param name An element name.
* @return A reference of AutoConnectSelect class.
*/
template<>
AutoConnectSelectJson& AutoConnectAux::getElement(const String name) {
AutoConnectElement* elm = getElement(name);
if (elm) {
if (elm->typeOf() == AC_Select)
return *(reinterpret_cast<AutoConnectSelectJson*>(elm));
}
return reinterpret_cast<AutoConnectSelectJson&>(_nullElement());
}
/**
* Get AutoConnectSubmitJson element.
* @param name An element name.
* @return A reference of AutoConnectSubmit class.
*/
template<>
AutoConnectSubmitJson& AutoConnectAux::getElement(const String name) {
AutoConnectElement* elm = getElement(name);
if (elm) {
if (elm->typeOf() == AC_Submit)
return *(reinterpret_cast<AutoConnectSubmitJson*>(elm));
}
return reinterpret_cast<AutoConnectSubmitJson&>(_nullElement());
}
/**
* Get AutoConnectTextJson element.
* @param name An element name.
* @return A reference of AutoConnectText class.
*/
template<>
AutoConnectTextJson& AutoConnectAux::getElement(const String name) {
AutoConnectElement* elm = getElement(name);
if (elm) {
if (elm->typeOf() == AC_Text)
return *(reinterpret_cast<AutoConnectTextJson*>(elm));
}
return reinterpret_cast<AutoConnectTextJson&>(_nullElement());
}
/**
* Load AutoConnectAux page from JSON description stored in the sketch.
* This function can load AutoConnectAux for multiple AUX pages written
@ -256,7 +480,7 @@ bool AutoConnectAux::_jbLiteral; /**< JSON object lexical status */
* @param aux JSON description to be load.
* @return true Successfully loaded.
*/
bool AutoConnect::join(const char* aux) {
bool AutoConnect::load(const char* aux) {
const size_t bufferSize = AutoConnectAux::_calcJsonBufferSize(aux);
DynamicJsonBuffer jsonBuffer(bufferSize);
JsonVariant jv = jsonBuffer.parse(aux);
@ -270,7 +494,7 @@ bool AutoConnect::join(const char* aux) {
* @param aux JSON description to be load.
* @return true Successfully loaded.
*/
bool AutoConnect::join(const __FlashStringHelper* aux) {
bool AutoConnect::load(const __FlashStringHelper* aux) {
const size_t bufferSize = AutoConnectAux::_calcJsonBufferSize(aux);
DynamicJsonBuffer jsonBuffer(bufferSize);
JsonVariant jv = jsonBuffer.parse(aux);
@ -284,7 +508,7 @@ bool AutoConnect::join(const __FlashStringHelper* aux) {
* @param aux Stream for read AutoConnectAux elements.
* @return true Successfully loaded.
*/
bool AutoConnect::join(Stream& aux, size_t bufferSize) {
bool AutoConnect::load(Stream& aux, size_t bufferSize) {
DynamicJsonBuffer jsonBuffer(bufferSize);
JsonVariant jv = jsonBuffer.parse(aux);
return _load(jv);
@ -480,7 +704,7 @@ AutoConnectElement& AutoConnectAux::_loadElement(JsonObject& jb, const String na
if (wc || name.equalsIgnoreCase(elmName)) {
// The specified element is defined in the JSON stream.
// Loads from JSON object.
auxElm = _getElement(elmName);
auxElm = getElement(elmName);
// The element is not created yet, create new one.
if (!auxElm) {
if ((auxElm = _createElement(element))) {
@ -535,18 +759,6 @@ size_t AutoConnectAux::saveElement(Stream& out, const AutoConnectElement& elemen
return 0;
}
/**
* Get already registered AutoConnectElement.
* @param name Element name
* @return A pointer to the registered AutoConnectElement.
*/
AutoConnectElement* AutoConnectAux::_getElement(const String name) {
for (std::size_t n = 0; n < _addonElm.size(); n++)
if (_addonElm[n].get().name == name)
return &(_addonElm[n].get());
return nullptr;
}
/**
* Convert element type from type as String.
* @param type An element type as String
@ -723,4 +935,4 @@ size_t AutoConnectAux::_resultJsonBufferSize() {
}
}
#endif
#endif // AUTOCONNECT_USE_JSON

@ -16,20 +16,21 @@
#include <functional>
#ifdef AUTOCONNECT_USE_JSON
#include <Stream.h>
#endif
#endif // !AUTOCONNECT_USE_JSON
#include <PageBuilder.h>
#include "AutoConnectElement.h"
#define AUTOCONENCT_JSONOBJECTTREE_MAXDEPTH 3
class AutoConnect; // Reference to avoid circular
class AutoConnectAux; // Reference to avoid circular
// Manage placed AutoConnectElement with a vector
typedef std::vector<std::reference_wrapper<AutoConnectElement>> AutoConnectElementVT;
// A type of callback function when AutoConnectAux page requested.
//typedef std::function<void(AutoConnectAux&, PageArgument&)> AuxHandleFuncT;
typedef std::function<String(PageArgument&)> AuxHandlerFunctionT;
typedef std::function<String(AutoConnectAux&, PageArgument&)> AuxHandlerFunctionT;
// A type for the order in which callback functions are called.
typedef enum {
@ -53,6 +54,9 @@ class AutoConnectAux : public PageBuilder {
~AutoConnectAux();
void add(AutoConnectElement& addon); /**< Add an element to the auxiliary page. */
void add(AutoConnectElementVT addons); /**< Add the element set to the auxiliary page. */
template<typename T>
T& getElement(const String name); /**< Get AutoConnect element */
AutoConnectElement* getElement(const String name); /**< Get registered AutoConnectElement as specified name */
bool release(const char* name) { return release(String(name)); } /**< Release an AutoConnectElement */
bool release(const String name); /**< Release an AutoConnectElement */
void setTitle(const char* title) { _title = String(title); } /**< Set a title of the auxiliary page. */
@ -67,7 +71,7 @@ class AutoConnectAux : public PageBuilder {
AutoConnectElement& loadElement(const __FlashStringHelper* in, const String name = "*"); /**< Load specified element */
AutoConnectElement& loadElement(Stream& in, const String name = "*", const size_t bufferSize = AUTOCONNECT_JSON_BUFFER_SIZE); /**< Load specified element */
size_t saveElement(Stream& out, const AutoConnectElement& element); /**< Load specified element */
#endif
#endif // !AUTOCONNECT_USE_JSON
protected:
void _concat(AutoConnectAux& aux); /**< Make up chain of AutoConnectAux */
@ -81,10 +85,9 @@ class AutoConnectAux : public PageBuilder {
bool _load(JsonObject& in); /**< Load all elements from JSON object */
AutoConnectElement& _loadElement(JsonObject& in, const String name); /**< Load an element as specified name from JSON object */
AutoConnectElement* _createElement(const JsonObject& json); /**< Create an AutoConnectElement instance from JSON object */
AutoConnectElement* _getElement(const String name); /**< Get registered AutoConnectElement as specified name */
static const ACElement_t _asElementType(const String type); /**< Convert a string of element type to the enumeration value */
static AutoConnectElement& _nullElement(void); /**< A static returning value as invalid */
#endif
#endif // !AUTOCONNECT_USE_JSON
String _title; /**< A title of the page */
bool _menu; /**< Switch for menu displaying */
@ -120,4 +123,4 @@ class AutoConnectAux : public PageBuilder {
static bool _jbLiteral; /**< JSON object lexical status */
};
#endif // _AUTOCONNECTAUX_H_
#endif // _AUTOCONNECTAUX_H_

@ -32,7 +32,7 @@ using AutoConnectRadio = AutoConnectRadioBasis;
using AutoConnectSelect = AutoConnectSelectBasis;
using AutoConnectSubmit = AutoConnectSubmitBasis;
using AutoConnectText = AutoConnectTextBasis;
#endif
#endif // !AUTOCONNECT_USE_JSON
/**
* Support declare the AutoConnectElement variable with reducing the
@ -48,4 +48,4 @@ using AutoConnectText = AutoConnectTextBasis;
#define ACSubmit(n, ...) AutoConnectSubmit n(#n, ##__VA_ARGS__)
#define ACText(n, ...) AutoConnectText n(#n, ##__VA_ARGS__)
#endif // _AUTOCONNECTELEMENT_H_
#endif // _AUTOCONNECTELEMENT_H_

@ -100,12 +100,13 @@ class AutoConnectCheckboxBasis : virtual public AutoConnectElementBasis {
*/
class AutoConnectInputBasis : virtual public AutoConnectElementBasis {
public:
explicit AutoConnectInputBasis(const char* name = "", const char* value = "", const char* label = "") : AutoConnectElementBasis(name, value), label(String(label)) {
explicit AutoConnectInputBasis(const char* name = "", const char* value = "", const char* placeholder = "", const char* label = "") : AutoConnectElementBasis(name, value), placeholder(String(placeholder)), label(String(label)) {
_type = AC_Input;
}
virtual ~AutoConnectInputBasis() {}
const String toHTML(void) const;
String placeholder;
String label; /**< A label for a subsequent input box */
};

@ -54,10 +54,12 @@ const String AutoConnectInputBasis::toHTML(void) const {
if (label.length())
html = String(FPSTR("<label for=\"")) + name + String("\">") + label + String(FPSTR("</label>"));
html += String(FPSTR("<input type=\"text\" id=\"")) + name + String(FPSTR("\" name=\"")) + name;
html += String(FPSTR("<input type=\"text\" id=\"")) + name + String(FPSTR("\" name=\"")) + name + String("\"");
if (placeholder.length())
html += String(FPSTR(" placeholder=\"")) + placeholder + String("\"");
if (value.length())
html += String(FPSTR("\" placeholder=\"")) + value;
html += String(FPSTR("\"><br>"));
html += String(FPSTR(" value=\"")) + value + String("\"");
html += String(FPSTR("><br>"));
return html;
}

@ -22,6 +22,7 @@
#define AUTOCONNECT_JSON_KEY_MENU "menu"
#define AUTOCONNECT_JSON_KEY_NAME "name"
#define AUTOCONNECT_JSON_KEY_OPTION "option"
#define AUTOCONNECT_JSON_KEY_PLACEHOLDER "placeholder"
#define AUTOCONNECT_JSON_KEY_STYLE "style"
#define AUTOCONNECT_JSON_KEY_TITLE "title"
#define AUTOCONNECT_JSON_KEY_TYPE "type"
@ -107,9 +108,10 @@ class AutoConnectCheckboxJson : public AutoConnectElementJson, public AutoConnec
*/
class AutoConnectInputJson : public AutoConnectElementJson, public AutoConnectInputBasis {
public:
explicit AutoConnectInputJson(const char* name = "", const char* value = "", const char* label = "") {
explicit AutoConnectInputJson(const char* name = "", const char* value = "", const char* placeholder = "", const char* label = "") {
AutoConnectInputBasis::name = name;
AutoConnectInputBasis::value = value;
AutoConnectInputBasis::placeholder = placeholder;
AutoConnectInputBasis::label = label;
}
~AutoConnectInputJson() {}

@ -79,6 +79,7 @@ bool AutoConnectInputJson::loadElement(const JsonObject& json) {
String type = json.get<String>(F(AUTOCONNECT_JSON_KEY_TYPE));
if (type.equalsIgnoreCase(F(AUTOCONNECT_JSON_TYPE_ACINPUT))) {
_setElement(json);
placeholder = json.get<String>(F(AUTOCONNECT_JSON_KEY_PLACEHOLDER));
label = json.get<String>(F(AUTOCONNECT_JSON_KEY_LABEL));
return true;
}

Loading…
Cancel
Save