24
24
25
25
#include " EmbAJAX.h"
26
26
27
- #include < cstdarg> // For va_args in printContentF .
27
+ #include < cstdarg> // For va_args in _printContentF .
28
28
29
29
#define ITOA_BUFLEN 8
30
30
@@ -77,7 +77,7 @@ void EmbAJAXOutputDriverBase::_printContent(const char* value) {
77
77
}
78
78
}
79
79
80
- void EmbAJAXOutputDriverBase::printContentF (const char * fmt, ...) {
80
+ void EmbAJAXOutputDriverBase::_printContentF (const char * fmt, ...) {
81
81
va_list args;
82
82
va_start (args, fmt);
83
83
const char *pos = fmt;
@@ -104,24 +104,23 @@ void EmbAJAXOutputDriverBase::printContentF(const char* fmt, ...) {
104
104
}
105
105
106
106
void EmbAJAXOutputDriverBase::printAttribute (const char * name, const char * value) {
107
- printContentF (" " PLAIN_STRING_ARG " =" HTML_QUOTED_STRING_ARG, name, value);
107
+ _printContentF (" " PLAIN_STRING_ARG " =" HTML_QUOTED_STRING_ARG, name, value);
108
108
}
109
109
110
110
void EmbAJAXOutputDriverBase::printAttribute (const char * name, const int32_t value) {
111
- printContentF (" " PLAIN_STRING_ARG " =" INTEGER_VALUE_ARG, name, value);
111
+ _printContentF (" " PLAIN_STRING_ARG " =" INTEGER_VALUE_ARG, name, value);
112
112
}
113
113
114
114
// ////////////////////// EmbAJAXConnectionIndicator ///////////////////////
115
115
116
116
void EmbAJAXConnectionIndicator::print () const {
117
- _driver->printContentF (" <div class=\" EmbAJAXStatus\" ><span>" PLAIN_STRING_ARG " </span><span>" PLAIN_STRING_ARG " </span><script>\n "
117
+ _driver->printFormatted (" <div class=\" EmbAJAXStatus\" ><span>" , PLAIN_STRING (_content_ok), " </span><span>" , PLAIN_STRING (_content_fail), " </span><script>\n "
118
118
" window.ardujaxsh = { 'div': document.scripts[document.scripts.length-1].parentNode,\n "
119
119
" 'good': 0,\n "
120
120
" 'tid': null,\n "
121
121
" 'toggle': function(on) { this.div.children[on].style.display = 'none'; this.div.children[1-on].style.display = 'inline'; this.good = on; },\n "
122
122
" 'in': function() { clearTimeout(this.tid); this.tid = window.setTimeout(this.toggle.bind(this, 0), 5000); if(!this.good) {this.toggle(1);} }\n "
123
- " };\n window.ardujaxsh.in();\n </script></div>" ,
124
- _content_ok, _content_fail);
123
+ " };\n window.ardujaxsh.in();\n </script></div>" );
125
124
}
126
125
127
126
// //////////////////////////// EmbAJAXElement /////////////////////////////
@@ -136,15 +135,15 @@ EmbAJAXElement::EmbAJAXElement(const char* id) : EmbAJAXBase() {
136
135
bool EmbAJAXElement::sendUpdates (uint16_t since, bool first) {
137
136
if (!changed (since)) return false ;
138
137
if (!first) _driver->printContent (" ,\n " );
139
- _driver->printContentF (" {\n\" id\" : " JS_QUOTED_STRING_ARG " ,\n\" changes\" : [" , _id );
138
+ _driver->printFormatted (" {\n\" id\" : " , JS_QUOTED_STRING (_id), " ,\n\" changes\" : [" );
140
139
uint8_t i = 0 ;
141
140
while (true ) {
142
141
const char * pid = valueProperty (i);
143
142
const char * pval = value (i);
144
143
if (!pid || !pval) break ;
145
144
146
145
if (i != 0 ) _driver->printContent (" ," );
147
- _driver->printContentF (" [" JS_QUOTED_STRING_ARG " , " , pid );
146
+ _driver->printFormatted (" [" , JS_QUOTED_STRING (pid) , " , " );
148
147
_driver->printFiltered (pval, EmbAJAXOutputDriverBase::JSQuoted, valueNeedsEscaping (i));
149
148
_driver->printContent (" ]" );
150
149
@@ -172,10 +171,9 @@ bool EmbAJAXElement::changed(uint16_t since) {
172
171
}
173
172
174
173
void EmbAJAXElement::printTextInput (size_t SIZE, const char * _value) const {
175
- _driver->printContentF (" <input type=\" text\" id=" HTML_QUOTED_STRING_ARG " maxLength=" INTEGER_VALUE_ARG " size=" INTEGER_VALUE_ARG
176
- " value=" HTML_QUOTED_STRING_ARG " onInput=\" doRequest(this.id, this.value);\" />" ,
177
- _id, SIZE-1 , min (max ((size_t ) SIZE, (size_t ) 11 ), (size_t ) 41 ) - 1 , // Arbitray limit for rendered width of text fields: 10..40 chars
178
- _value);
174
+ _driver->printFormatted (" <input type=\" text\" id=" , HTML_QUOTED_STRING (_id), " maxLength=" , INTEGER_VALUE (SIZE-1 ),
175
+ " size=" , INTEGER_VALUE (min (max ((size_t ) SIZE, (size_t ) 11 ), (size_t ) 41 ) - 1 ), // Arbitray limit for rendered width of text fields: 10..40 chars
176
+ " value=" , HTML_QUOTED_STRING (_value), " onInput=\" doRequest(this.id, this.value);\" />" );
179
177
}
180
178
181
179
// ////////////////////// EmbAJAXContainer ////////////////////////////////////
@@ -209,7 +207,7 @@ EmbAJAXElement* EmbAJAXBase::findChild(EmbAJAXBase** _children, size_t NUM, cons
209
207
// ////////////////////// EmbAJAXMutableSpan /////////////////////////////
210
208
211
209
void EmbAJAXMutableSpan::print () const {
212
- _driver->printContentF (" <span id=" HTML_QUOTED_STRING_ARG " >" , _id );
210
+ _driver->printFormatted (" <span id=" , HTML_QUOTED_STRING (_id), " >" );
213
211
if (_value) _driver->printFiltered (_value, EmbAJAXOutputDriverBase::NotQuoted, valueNeedsEscaping ());
214
212
_driver->printContent (" </span>\n " );
215
213
}
@@ -246,8 +244,8 @@ EmbAJAXSlider::EmbAJAXSlider(const char* id, int16_t min, int16_t max, int16_t i
246
244
}
247
245
248
246
void EmbAJAXSlider::print () const {
249
- _driver->printContentF (" <input type=\" range\" id=" HTML_QUOTED_STRING_ARG " min=" INTEGER_VALUE_ARG " max=" INTEGER_VALUE_ARG " value=" INTEGER_VALUE_ARG
250
- " oninput=\" doRequest(this.id, this.value);\" onchange=\" oninput();\" />" , _id, _min, _max, _value );
247
+ _driver->printFormatted (" <input type=\" range\" id=" , HTML_QUOTED_STRING (_id), " min=" , INTEGER_VALUE (_min), " max=" , INTEGER_VALUE (_max), " value=" , INTEGER_VALUE (_value),
248
+ " oninput=\" doRequest(this.id, this.value);\" onchange=\" oninput();\" />" );
251
249
}
252
250
253
251
const char * EmbAJAXSlider::value (uint8_t which) const {
@@ -280,8 +278,8 @@ EmbAJAXColorPicker::EmbAJAXColorPicker(const char* id, uint8_t r, uint8_t g, uin
280
278
}
281
279
282
280
void EmbAJAXColorPicker::print () const {
283
- _driver->printContentF (" <input type=\" color\" id=" HTML_QUOTED_STRING_ARG " value=" HTML_QUOTED_STRING_ARG
284
- " oninput=\" doRequest(this.id, this.value);\" onchange=\" oninput();\" />" , _id, value () );
281
+ _driver->printFormatted (" <input type=\" color\" id=" , HTML_QUOTED_STRING (_id), " value=" , HTML_QUOTED_STRING ( value ()),
282
+ " oninput=\" doRequest(this.id, this.value);\" onchange=\" oninput();\" />" );
285
283
}
286
284
287
285
// helper to make sure we get exactly two hex digits for any input
@@ -353,8 +351,8 @@ EmbAJAXPushButton::EmbAJAXPushButton(const char* id, const char* label, void (*c
353
351
}
354
352
355
353
void EmbAJAXPushButton::print () const {
356
- _driver->printContentF (" <button type=\" button\" id=" HTML_QUOTED_STRING_ARG
357
- " onClick=\" doRequest(this.id, 'p', 2);\" >" , _id ); // 2 -> not mergeable -> so we can count individual presses, even if they happen fast
354
+ _driver->printFormatted (" <button type=\" button\" id=" , HTML_QUOTED_STRING (_id),
355
+ " onClick=\" doRequest(this.id, 'p', 2);\" >" ); // 2 -> not mergeable -> so we can count individual presses, even if they happen fast
358
356
_driver->printFiltered (_label, EmbAJAXOutputDriverBase::NotQuoted, valueNeedsEscaping ());
359
357
_driver->printContent (" </button>" );
360
358
}
@@ -392,14 +390,14 @@ EmbAJAXMomentaryButton::EmbAJAXMomentaryButton(const char* id, const char* label
392
390
}
393
391
394
392
void EmbAJAXMomentaryButton::print () const {
395
- _driver->printContentF (" <button type=\" button\" id=" HTML_QUOTED_STRING_ARG " >" , _id );
393
+ _driver->printFormatted (" <button type=\" button\" id=" , HTML_QUOTED_STRING (_id), " >" );
396
394
_driver->printFiltered (_label, EmbAJAXOutputDriverBase::NotQuoted, valueNeedsEscaping ());
397
- _driver->printContentF (" </button>"
395
+ _driver->printFormatted (" </button>"
398
396
" <script>\n "
399
- " {let btn=document.getElementById(" JS_QUOTED_STRING_ARG " );\n "
400
- " btn.onmousedown = btn.ontouchstart = function() { clearInterval(this.pinger); this.pinger=setInterval(function() {doRequest(this.id, 'p');}.bind(this)," INTEGER_VALUE_ARG " ); doRequest(this.id, 'p'); return false; };\n "
397
+ " {let btn=document.getElementById(" , JS_QUOTED_STRING (_id), " );\n "
398
+ " btn.onmousedown = btn.ontouchstart = function() { clearInterval(this.pinger); this.pinger=setInterval(function() {doRequest(this.id, 'p');}.bind(this)," , INTEGER_VALUE (( int ) (_timeout / 1.5 )), " ); doRequest(this.id, 'p'); return false; };\n "
401
399
" btn.onmouseup = btn.ontouchend = btn.onmouseleave = function() { clearInterval(this.pinger); doRequest(this.id, 'r'); return false;};}\n "
402
- " </script>" , _id, ( int ) (_timeout / 1.5 ) );
400
+ " </script>" );
403
401
}
404
402
405
403
EmbAJAXMomentaryButton::Status EmbAJAXMomentaryButton::status () const {
@@ -429,16 +427,15 @@ EmbAJAXCheckButton::EmbAJAXCheckButton(const char* id, const char* label, bool c
429
427
}
430
428
431
429
void EmbAJAXCheckButton::print () const {
432
- _driver->printContentF (" <span class=" HTML_QUOTED_STRING_ARG " >" // <input> and <label> inside a common span to support hiding, better.
433
- // Also, assign a class to the surrounding span to ease styling via CSS.
434
- " <input id=" HTML_QUOTED_STRING_ARG " type=" HTML_QUOTED_STRING_ARG
435
- " value=\" t\" onChange=\" doRequest(this.id, this.checked ? 't' : 'f');\" " ,
436
- radiogroup ? " radio" : " checkbox" , _id, radiogroup ? " radio" : " checkbox" );
430
+ _driver->printFormatted (" <span class=" , HTML_QUOTED_STRING (radiogroup ? " radio" : " checkbox" ), " >" // <input> and <label> inside a common span to support hiding, better.
431
+ // Also, assign a class to the surrounding span to ease styling via CSS.
432
+ " <input id=" , HTML_QUOTED_STRING (_id), " type=" , HTML_QUOTED_STRING (radiogroup ? " radio" : " checkbox" ),
433
+ " value=\" t\" onChange=\" doRequest(this.id, this.checked ? 't' : 'f');\" " );
437
434
if (radiogroup) _driver->printAttribute (" name" , radiogroup->_name );
438
435
if (_checked) _driver->printContent (" checked=\" true\" " );
439
436
// Note: Internal <span> element for more flexbility in styling the control
440
- _driver->printContentF (" /><label for=" HTML_QUOTED_STRING_ARG " >" PLAIN_STRING_ARG // NOTE: Not escaping _label, so user can insert HTML.
441
- " </label></span>" , _id, _label );
437
+ _driver->printFormatted (" /><label for=" , HTML_QUOTED_STRING (_id), " >" , PLAIN_STRING (_label), // NOTE: Not escaping _label, so user can insert HTML.
438
+ " </label></span>" );
442
439
}
443
440
444
441
const char * EmbAJAXCheckButton::value (uint8_t which) const {
@@ -469,9 +466,9 @@ void EmbAJAXCheckButton::setChecked(bool checked) {
469
466
// ////////////////////// EmbAJAXOptionSelect(Base) ///////////////
470
467
471
468
void EmbAJAXOptionSelectBase::print (const char * const * _labels, uint8_t NUM) const {
472
- _driver->printContentF (" <select id=" HTML_QUOTED_STRING_ARG " onChange=\" doRequest(this.id, this.value)\" >\n " , _id );
469
+ _driver->printFormatted (" <select id=" , HTML_QUOTED_STRING (_id), " onChange=\" doRequest(this.id, this.value)\" >\n " );
473
470
for (uint8_t i = 0 ; i < NUM; ++i) {
474
- _driver->printContentF (" <option value=" INTEGER_VALUE_ARG " >" HTML_QUOTED_STRING_ARG " </option>\n " , i, _labels[i] );
471
+ _driver->printFormatted (" <option value=" , INTEGER_VALUE (i), " >" , HTML_QUOTED_STRING (_labels[i]), " </option>\n " );
475
472
}
476
473
_driver->printContent (" </select>" );
477
474
}
@@ -506,7 +503,7 @@ void EmbAJAXBase::printPage(EmbAJAXBase** _children, size_t NUM, const char* _ti
506
503
time_t start = millis ();
507
504
#endif
508
505
_driver->printHeader (true );
509
- _driver->printContentF (" <!DOCTYPE html>\n <HTML><HEAD><TITLE>" PLAIN_STRING_ARG " </TITLE>\n <SCRIPT>\n "
506
+ _driver->printFormatted (" <!DOCTYPE html>\n <HTML><HEAD><TITLE>" , PLAIN_STRING (_title), " </TITLE>\n <SCRIPT>\n "
510
507
511
508
" var serverrevision = 0;\n "
512
509
" var request_queue = [];\n " // requests waiting to be sent
@@ -525,7 +522,7 @@ void EmbAJAXBase::printPage(EmbAJAXBase** _children, size_t NUM, const char* _ti
525
522
" var prev_request = 0;\n "
526
523
" function sendQueued() {\n "
527
524
" var now = new Date().getTime();\n "
528
- " if (num_waiting > 0 || (now - prev_request < " INTEGER_VALUE_ARG " )) return;\n "
525
+ " if (num_waiting > 0 || (now - prev_request < " , INTEGER_VALUE (_min_interval), " )) return;\n "
529
526
" var e = request_queue.shift();\n "
530
527
" if (!e && (now - prev_request < 1000)) return;\n "
531
528
" if (!e) e = {id: '', value: ''};\n " // Nothing in queue, but last request more than 1000 ms ago? Send a ping to query for updates
@@ -545,7 +542,7 @@ void EmbAJAXBase::printPage(EmbAJAXBase** _children, size_t NUM, const char* _ti
545
542
" req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');\n "
546
543
" req.send('id=' + e.id + '&value=' + encodeURIComponent(e.value) + '&revision=' + serverrevision);\n "
547
544
" }\n "
548
- " window.setInterval(sendQueued, " INTEGER_VALUE_ARG " );\n "
545
+ " window.setInterval(sendQueued, " , INTEGER_VALUE (_min_interval/ 2 + 1 ), " );\n "
549
546
550
547
" function doUpdates(response) {\n "
551
548
" serverrevision = response.revision;\n "
@@ -567,18 +564,18 @@ void EmbAJAXBase::printPage(EmbAJAXBase** _children, size_t NUM, const char* _ti
567
564
" }\n "
568
565
" }\n "
569
566
570
- " </SCRIPT>\n " PLAIN_STRING_ARG
571
- " </HEAD>\n <BODY><FORM autocomplete=\" off\" onSubmit=\" return false;\" >\n " // NOTE: The nasty thing about autocomplete is that it does not trigger
572
- // onChange() functions, but also the "restore latest settings after client
573
- // reload" is questionable in our use-case.
574
- , _title, _min_interval, _min_interval/2 +1 , _header_add);
567
+ " </SCRIPT>\n " , PLAIN_STRING (_header_add),
568
+ " </HEAD>\n <BODY><FORM autocomplete=\" off\" onSubmit=\" return false;\" >\n " );
569
+ // NOTE: The nasty thing about autocomplete is that it does not trigger onChange() functions, but also the
570
+ // "restore latest settings after client reload" is questionable in our use-case.
575
571
576
572
printChildren (_children, NUM);
577
573
578
574
_driver->printContent (" \n </FORM></BODY></HTML>\n " );
579
575
#if EMBAJAX_DEBUG > 2
576
+ auto diff = millis () - start;
580
577
Serial.print (" Page rendered in " );
581
- Serial.print (millis () - start );
578
+ Serial.print (diff );
582
579
Serial.println (" ms" );
583
580
#endif
584
581
}
@@ -628,7 +625,7 @@ void EmbAJAXBase::handleRequest(EmbAJAXBase** _children, size_t NUM, void (*chan
628
625
629
626
// then relay value changes that have occured in the server (possibly in response to those sent)
630
627
_driver->printHeader (false );
631
- _driver->printContentF (" {\" revision\" : " INTEGER_VALUE_ARG " ,\n\" updates\" : [\n " , _driver-> revision () );
628
+ _driver->printFormatted (" {\" revision\" : " , INTEGER_VALUE (_driver-> revision ()), " ,\n\" updates\" : [\n " );
632
629
sendUpdates (_children, NUM, client_revision, true );
633
630
_driver->printContent (" \n ]}\n " );
634
631
0 commit comments