1 #include "wikiattrib.h"
2 #include "wikiformat.h"
4 #include "util_check.h"
7 bool WikiAttrib1::readAttrib1 (WikiMotorObjVec* cell, bool& rc) {
12 if (cell->size () == 0) {
13 if (mode == M_ATTRIB || mode == M_ATTRIB_TEXT)
18 if (cell->splitChar_keyword ('=', key, vval)) {
19 if (paramID (key, vval, ferr)) {
20 } else if (paramClass (key, vval, ferr)) {
22 } else if (paramDataPrefix (key, vval, ferr)) {
24 } else if (paramOnClickCheck (key)) {
25 if (! checkScript (vval, onclick, ferr)) {
26 wiki->errorMsg.append (cell->dump ()).append (CharConst (": link script error.\n"));
29 } else if (paramOnFocusCheck (key)) {
30 if (! checkScript (vval, onfocus, ferr)) {
31 wiki->errorMsg.append (cell->dump ()).append (CharConst (": link script error.\n"));
34 } else if (paramOnBlurCheck (key)) {
35 if (! checkScript (vval, onblur, ferr)) {
36 wiki->errorMsg.append (cell->dump ()).append (CharConst (": link script error.\n"));
39 } else if (paramOnChangeCheck (key)) {
40 if (! checkScript (vval, onchange, ferr)) {
41 wiki->errorMsg.append (cell->dump ()).append (CharConst (": link script error.\n"));
44 } else if ((selector & SEL_TARGET) && paramTargetCheck (key)) {
45 paramTargetBody (key, vval.textOut (wiki), target, ferr);
46 } else if (readAttribMore (key, vval, ferr)) {
48 if (mode == M_ATTRIB) {
49 wiki->errorMsg.append (cell->dump ()).append (CharConst (": bad attribute.\n"));
55 if (selector & SEL_CLASS2) {
56 paramClassValue (*cell, classlist, ferr);
57 } else if (selector & SEL_TARGET2) {
58 paramTargetBody (uEmpty, cell->textOut (wiki), target, ferr);
59 } else if ((selector & SEL_ONCLICK2) && checkScript (*cell, onclick, ferr)) {
60 } else if ((selector & SEL_MULTIPLE2) && match (key, CharConst ("multiple"))) {
62 } else if ((selector & SEL_DEFAULT2) && match (key, CharConst ("default"))) {
64 } else if ((selector & SEL_SCRIPT2) && checkScript (*cell, script, ferr)) {
65 } else if (readAttribMore2 (key, *cell, ferr)) {
67 if (mode == M_ATTRIB) {
68 wiki->errorMsg.append (cell->dump ()).append (CharConst (": bad attribute.\n"));
82 bool WikiAttrib1::shiftAttrib (WikiMotorObjVecPtr& vec) {
84 WikiMotorObjVecPtr v2;
86 while (vec->size () > 0) {
89 v2 = WikiMotorObjVecPtr (new WikiMotorObjVec);
90 if (vec->splitChar (':', cell, *v2) || mode == M_ATTRIB || mode == M_ATTRIB_TEXT) {
91 if (! readAttrib1 (&cell, rc))
101 void WikiAttrib1::skipAttrib (WikiMotorObjVecPtr& vec) {
102 WikiMotorObjVecPtr v2;
104 if (vec->size () > 0) {
105 WikiMotorObjVec cell;
107 v2 = WikiMotorObjVecPtr (new WikiMotorObjVec);
108 if (vec->splitChar (':', cell, *v2)) {
114 bool WikiAttrib1::readAttrib (WikiMotorObjVecVec::const_iterator& b, const WikiMotorObjVecVec::const_iterator& e) {
118 WikiMotorObjVec* cell = b->get ();
119 if (! readAttrib1 (cell, rc))
126 bool WikiAttrib1::checkScript (WikiMotorObjVec& vec, ustring& scr, bool& ferr) {
130 for (i = 0; i < vec.size () && vec[i]->type == WikiMotorObj::wiki_funcLink; i ++) {
131 WikiMotorObjFuncLink* fn = WikiMotorObjFuncLink_type (&*vec[i]);
132 u = fn->execDefunArgs (wiki);
133 // XXX: 末尾の空白を除去し,セミコロンを確認する。
143 bool WikiAttrib1::shiftLink (WikiMotorObjVecPtr& vec, ustring& url, bool& fscript) {
146 WikiMotorObjVec cell;
147 WikiMotorObjVecPtr v2 (new WikiMotorObjVec);
149 rc = vec->splitChar (':', cell, *v2);
150 if (checkScript (cell, url, ferr)) {
154 } else if (rc && cell.match (CharConst ("http"), CharConst ("https"))) {
155 ustring proto = cell.dump ();
158 v2 = WikiMotorObjVecPtr (new WikiMotorObjVec);
159 rc = vec->splitChar (':', cell, *v2);
160 if (! cell.splitURL_2 (wiki, proto, url)) {
165 if (vec->size () > 0) {
167 v2 = WikiMotorObjVecPtr (new WikiMotorObjVec);
168 rc = vec->splitChar (':', cell, *v2);
169 if (cell.splitURL_3 (wiki, url, url))
173 } else if (cell.splitURLPath (wiki, url)) {
182 bool WikiAttrib1::readLink (WikiMotorObjVecVec::const_iterator& b, const WikiMotorObjVecVec::const_iterator& e, ustring& url, bool& fscript, bool noscript) {
185 WikiMotorObjVec* cell;
186 static uregex re (CharConst ("^[a-z]{3,6}$"));
192 if (! noscript && checkScript (*cell, url, ferr)) {
196 } else if (rc && cell->regmatch (re)) {
197 ustring proto = cell->dump ();
200 if (! cell->splitURL_2 (wiki, proto, url)) {
207 if (cell->splitURL_3 (wiki, url, url))
211 } else if (cell->splitURLPath (wiki, url)) {
220 bool WikiAttrib1::shiftName (WikiMotorObjVecPtr& vec, ustring& name) {
221 if (vec->size () > 0) {
222 WikiMotorObjVec cell;
223 WikiMotorObjVecPtr v2 (new WikiMotorObjVec);
225 vec->splitChar (':', cell, *v2);
226 name = cell.textOut (wiki);
234 void WikiAttrib1::output (MotorOutput* out) {
235 wiki->outputID (out, id);
236 wiki->outputClass (out, classlist);
238 // std::pair<ustring,ustring>::const_iterator b, e;
239 std::vector<datapre_t>::const_iterator b, e;
240 b = datapre.begin ();
242 for (; b < e; b ++) {
243 wiki->outputName (out, (*b).first.c_str (), (*b).first.size (), (*b).second);
247 wiki->outputNum (out, CharConst ("start"), start);
248 wiki->outputSubmitScript (out, CharConst ("onclick"), onclick, scriptcut);
249 wiki->outputSubmitScript (out, CharConst ("onfocus"), onfocus, scriptcut);
250 wiki->outputSubmitScript (out, CharConst ("onblur"), onblur, scriptcut);
251 wiki->outputSubmitScript (out, CharConst ("onchange"), onchange, scriptcut);
252 wiki->outputName (out, CharConst ("target"), target);
253 wiki->outputFlag (out, CharConst ("multiple"), fmultiple);
258 bool WikiAttrib1::paramID (const ustring& key, WikiMotorObjVec& vval, bool& ferr) {
259 if (match (key, CharConst ("id"))) {
260 paramIDValue (key, vval, id, ferr);
267 void WikiAttrib1::paramIDValue (const ustring& key, WikiMotorObjVec& vval, ustring& var, bool& ferr) {
268 ustring value (vval.textOut (wiki));
269 if (matchWikiID (value)) {
273 wiki->errorMsg.append (key).append (uEq).append (value).append (CharConst (": bad value\n"));
278 bool WikiAttrib1::paramClass (const ustring& key, WikiMotorObjVec& vval, bool& ferr) {
279 if (match (key, CharConst ("class"))) {
280 paramClassValue (vval, classlist, ferr);
287 void WikiAttrib1::paramClassValue (WikiMotorObjVec& vval, std::vector<ustring>& var, bool& ferr) {
288 WikiMotorObjVecVec args;
290 vval.splitCharA (',', args);
291 for (int i = 0; i < args.size (); i ++) {
292 ustring value (args[i]->textOut (wiki));
293 if (value.length () > 0) {
294 if ((selector & SEL_DIRECT) && value[0] == '#' && matchWikiID (ustring (value.begin () + 1, value.end ()))) {
295 directlist.push_back (value); // SEL_DIRECTが指定してある場合のみ有効
296 } else if (matchWikiID (value)) {
297 var.push_back (value);
299 wiki->errorMsg.append (value).append (CharConst (": bad class name\n"));
306 bool WikiAttrib1::paramWidth (const ustring& key, WikiMotorObjVec& vval, ustring& var, bool& ferr) {
307 if (match (key, CharConst ("width"), CharConst ("w"))) {
308 paramWidthValue (key, vval, var, ferr);
315 bool WikiAttrib1::paramHeight (const ustring& key, WikiMotorObjVec& vval, ustring& var, bool& ferr) {
316 if (match (key, CharConst ("height"), CharConst ("h"))) {
317 paramWidthValue (key, vval, var, ferr);
324 void WikiAttrib1::paramWidthValue (const ustring& key, WikiMotorObjVec& vval, ustring& var, bool& ferr) {
325 ustring value (vval.textOut (wiki));
326 if (matchWidth (value)) {
330 wiki->errorMsg.append (key).append (uEq).append (value).append (CharConst (": bad value\n"));
335 bool WikiAttrib1::paramSize (const char* name, size_t namelen, const ustring& key, WikiMotorObjVec& vval, ustring& var, bool& ferr) {
336 if (match (key, name, namelen)) {
337 ustring value (vval.textOut (wiki));
338 if (matchNum (value)) {
349 void WikiAttrib1::paramUNum (const ustring& value, int& var, const ustring& name) {
350 if (matchNum (value)) {
351 var = strtoul (value);
353 wiki->errorMsg.append (name).append (uEq).append (value).append (uErrorBadValue).append (uLF);
357 void WikiAttrib1::paramColor (const ustring& value, ustring& var, const ustring& name) {
358 if (checkColor (value)) {
361 wiki->errorMsg.append (name).append (uEq).append (value).append (uErrorBadValue).append (uLF);
365 bool WikiAttrib1::paramTargetCheck (const ustring& key) {
366 return match (key, CharConst ("target"));
369 void WikiAttrib1::paramTargetBody (const ustring& key, const ustring& value, ustring& var, bool& ferr) {
370 if (value.length () == 0 || matchWikiID (value)) {
373 if (key.length () > 0)
374 wiki->errorMsg.append (key).append (uEq).append (value).append (CharConst (": bad target name.\n"));
376 wiki->errorMsg.append (value).append (CharConst (": bad target name.\n"));
381 bool WikiAttrib1::paramOnClickCheck (const ustring& name) {
382 return match (name, CharConst ("onclick"));
385 bool WikiAttrib1::paramOnFocusCheck (const ustring& name) {
386 return match (name, CharConst ("onfocus"));
389 bool WikiAttrib1::paramOnBlurCheck (const ustring& name) {
390 return match (name, CharConst ("onblur"));
393 bool WikiAttrib1::paramOnChangeCheck (const ustring& name) {
394 return match (name, CharConst ("onchange"));
398 bool WikiAttrib1::paramDataPrefix (const ustring& key, WikiMotorObjVec& vval, bool& ferr) {
399 if (matchHead (key, CharConst ("data-")) && matchWikiID (key)) {
400 ustring value (vval.textOut (wiki));
401 if (matchWikiID (value)) {
402 datapre.push_back (std::pair<ustring,ustring> (key, value));
405 wiki->errorMsg.append (key).append (uEq).append (value).append (CharConst (": bad value\n"));
414 /* ============================================================ */
415 void WikiAttribTable::init () {
420 #ifdef WIKITABLEATTRIB
426 // halign = HAlignNone;
431 while (! classlist.empty ())
432 classlist.pop_back ();
439 void WikiAttribTable::copyFrom (WikiAttribTable& b) {
443 for (i = 0; i < b.classlist.size (); i ++)
444 classlist.push_back (b.classlist[i]);
455 bool WikiAttribTable::readAttribMore (const ustring& key, WikiMotorObjVec& vval, bool& ferr) {
456 if (paramWidth (key, vval, width, ferr)) {
457 } else if (paramHeight (key, vval, height, ferr)) {
458 } else if (match (key, CharConst ("bgcolor"), CharConst ("bg"))) {
459 paramColor (vval.textOut (wiki), bgcolor, key);
463 #ifdef WIKITABLEATTRIB
464 if (match (key, CharConst ("cellspacing"), CharConst ("spc"))) {
465 paramUNum (vval.textOut (wiki), cellspacing, key);
466 } else if (match (key, CharConst ("cellpadding"))) {
467 paramUNum (vval.textOut (wiki), cellpadding, key);
485 bool WikiAttribTable::readAttribMore2 (const ustring& key, WikiMotorObjVec& cell, bool& ferr) {
486 if (match (key, CharConst ("left"), CharConst ("l"))) {
488 } else if (match (key, CharConst ("right"), CharConst ("r"))) {
489 halign = HAlignRight;
490 } else if (match (key, CharConst ("center"), CharConst ("c"))) {
491 halign = HAlignCenter;
495 #ifdef WIKITABLEATTRIB
496 if (match (key, CharConst ("noborder"), CharConst ("nb"))) {
500 if (match (key, CharConst ("padding"), CharConst ("pad"))) {
502 } else if (match (key, CharConst ("expanding"), CharConst ("expand"))) {
504 } else if (match (key, CharConst ("nowhite"), CharConst ("nw"))) {
506 } else if (match (key, CharConst ("turn"))) {
514 if (match (key, CharConst ("header"), CharConst ("h"))) {
516 } else if (match (key, CharConst ("top"), CharConst ("t"))) {
518 } else if (match (key, CharConst ("middle"), CharConst ("m"))) {
519 valign = VAlignMiddle;
520 } else if (match (key, CharConst ("bottom"), CharConst ("b"))) {
521 valign = VAlignBottom;
522 } else if (match (key, CharConst ("nowrap"), CharConst ("nw"))) {
524 } else if (match (key, CharConst ("*"))) {
538 void WikiAttribTable::outputMore (MotorOutput* out, bool foutputwidth) {
541 out->out_raw (CharConst (" align=\"left\""));
544 out->out_raw (CharConst (" align=\"center\""));
547 out->out_raw (CharConst (" align=\"right\""));
552 wiki->outputName (out, CharConst ("width"), width);
553 wiki->outputName (out, CharConst ("height"), height);
554 wiki->outputName (out, CharConst ("bgcolor"), bgcolor);
558 #ifdef WIKITABLEATTRIB
559 wiki->outputName (out, CharConst ("border"), fnoborder ? 0 : 1, false);
560 wiki->outputName (out, CharConst ("cellspacing"), cellspacing, false);
561 wiki->outputName (out, CharConst ("cellpadding"), cellpadding, false);
568 out->out_raw (CharConst (" valign=\"top\""));
571 out->out_raw (CharConst (" valign=\"middle\""));
574 out->out_raw (CharConst (" valign=\"bottom\""));
578 wiki->outputFlag (out, CharConst ("nowrap"), fnowrap);
585 /* ============================================================ */
586 bool WikiAttribImg::readAttribMore (const ustring& key, WikiMotorObjVec& vval, bool& ferr) {
587 if (paramWidth (key, vval, width, ferr)) {
588 if (matchNum (width))
589 width.append (CharConst ("px"));
590 } else if (paramHeight (key, vval, height, ferr)) {
591 if (matchNum (height))
592 height.append (CharConst ("px"));
593 } else if (match (key, CharConst ("alt"))) {
594 alt = vval.textOut (wiki);
601 void WikiAttribImg::outputMore (MotorOutput* out) {
602 // wiki->outputName (out, CharConst ("width"), width);
603 // wiki->outputName (out, CharConst ("height"), height);
604 if (width.length () > 0 || height.length () > 0) {
605 out->out_raw (CharConst (" style=\""));
606 if (width.length () > 0)
607 out->out_raw (CharConst ("width:"))->out_toHTML_noCtrl (width)->out_raw (CharConst (";"));
608 if (height.length () > 0)
609 out->out_raw (CharConst ("height:"))->out_toHTML_noCtrl (height)->out_raw (CharConst (";"));
610 out->out_raw (CharConst ("\""));
615 /* ============================================================ */
616 bool WikiAttribInput::readAttribMore (const ustring& key, WikiMotorObjVec& vval, bool& ferr) {
617 if ((selector2 & SEL_INPUT) && paramSize (CharConst ("size"), key, vval, psize, ferr)) {
618 } else if ((selector2 & SEL_ELSIZE) && match (key, CharConst ("size"))) {
619 ustring v = vval.textOut (wiki);
620 if (match (v, CharConst ("*"))) {
622 } else if (matchNum (v)) {
623 elsize = to_int32 (v);
624 if (elsize < 0 || elsize > 999) {
630 } else if (paramWidth (key, vval, pwidth, ferr)) {
631 } else if ((selector2 & SEL_TEXTAREA) && paramSize (CharConst ("cols"), key, vval, pcols, ferr)) {
632 } else if ((selector2 & SEL_TEXTAREA) && paramSize (CharConst ("rows"), key, vval, prows, ferr)) {
633 } else if ((selector2 & SEL_TEXTAREA) && match (key, CharConst ("wrap"))) {
634 ustring value (vval.textOut (wiki));
635 if (match (value, CharConst ("off"))) {
637 } else if (match (value, CharConst ("soft"))) {
639 } else if (match (value, CharConst ("hard"))) {
642 wiki->errorMsg.append (key).append (CharConst ("=")).append (vval.dump ()).append (CharConst (": link script error.\n"));
646 } else if (match (key, CharConst ("accept"))) {
647 ustring value (vval.textOut (wiki));
648 if (match (value, CharConst ("camera"))) {
649 paccept.assign (CharConst ("image/*;capture=camera"));
651 static uregex re ("^"
652 "(" "[a-z_0-9-]+/[a-z_0-9.+*-]+" ")"
653 "(" "," "(" "[a-z_0-9-]+/[a-z_0-9.+*-]+" ")" ")*"
654 "(" ";" "[a-z_0-9-]+=[a-zA-Z_0-9.+*-]+" ")*"
656 if (checkRe (value, re)) {
668 bool WikiAttribInput::readAttribMore2 (const ustring& key, WikiMotorObjVec& cell, bool& ferr) {
669 if (key == uDefault) {
671 } else if ((selector2 & SEL_CHECK) && match (key, CharConst ("checked"))) {
674 } else if ((selector2 & SEL_TEXTAREA) && match (key, CharConst ("tab"))) {
683 void WikiAttribInput::outputMore (MotorOutput* out) {
684 wiki->outputName (out, CharConst ("size"), psize);
685 wiki->outputName (out, CharConst ("size"), elsize);
686 if (pwidth.size () > 0) {
687 if (matchNum (pwidth)) {
688 out->out_raw (CharConst (" style=\"width:"))->out_toHTML_noCtrl (pwidth)->out_raw (CharConst ("px;\""));
690 out->out_raw (CharConst (" style=\"width:"))->out_toHTML_noCtrl (pwidth)->out_raw (CharConst (";\""));
693 if (selector2 & SEL_CHECK) {
694 wiki->outputFlag (out, CharConst ("checked"), pchecked);
696 if (selector2 & SEL_TEXTAREA) {
697 wiki->outputName (out, CharConst ("cols"), pcols, false);
698 wiki->outputName (out, CharConst ("rows"), prows);
701 out->out_raw (CharConst (" wrap=\"off\""));
704 out->out_raw (CharConst (" wrap=\"soft\""));
705 // out->out_raw (CharConst (" wrap=\"virtual\""));
708 out->out_raw (CharConst (" wrap=\"hard\""));
709 // out->out_raw (CharConst (" wrap=\"physical\""));
715 ->out_raw (CharConst ("onkeypress"))
716 ->out_raw (CharConst ("=\""))
717 ->out_toHTML (ustring (CharConst ("return insertTab(event,this);")))
720 ->out_raw (CharConst ("onkeydown"))
721 ->out_raw (CharConst ("=\""))
722 ->out_toHTML (ustring (CharConst ("return insertTab(event,this);")))
725 ->out_raw (CharConst ("onkeyup"))
726 ->out_raw (CharConst ("=\""))
727 ->out_toHTML (ustring (CharConst ("return insertTab(event,this);")))
732 if (paccept.length () > 0) {
733 out->out_raw (CharConst (" accept=\""))
734 ->out_toHTML (paccept)
739 /* ============================================================ */
740 bool WikiAttribButton::readAttrib (WikiMotorObjVecVec::const_iterator& b, const WikiMotorObjVecVec::const_iterator& e) {
744 WikiMotorObjVec* cell = b->get ();
748 if (! readAttrib1 (cell, rc)) {
749 name = cell->textOut (wiki);
755 WikiMotorObjVec* cell = b->get ();
756 if (! readAttrib1 (cell, rc))
763 /* ============================================================ */
764 bool WikiAttribItem::readAttribMore (const ustring& key, WikiMotorObjVec& vval, bool& ferr) {
765 if (match (key, CharConst ("ulclass"))) {
766 if (owner && owner->parent && owner->parent->attrib.classlist.size () == 0) {
767 paramClassValue (vval, owner->parent->attrib.classlist, ferr);
769 } else if (match (key, CharConst ("ulid"))) {
770 if (owner && owner->parent && owner->parent->attrib.id.size () == 0) {
771 paramIDValue (key, vval, owner->parent->attrib.id, ferr);
773 } else if (owner && owner->parent && (owner->parent->attrib.selector & SEL_START) && match (key, CharConst ("start"))) {
774 paramUNum (vval.textOut (wiki), owner->parent->attrib.start, key);
781 /* ============================================================ */