OSDN Git Service

ab3f13f611a324c51fead38b720d79de79adb505
[hmh/hhml.git] / wiki / wikiattrib.cc
1 #include "wikiattrib.h"
2 #include "wikiformat.h"
3 #include "wikimotor.h"
4 #include "util_check.h"
5 #include "ustring.h"
6
7 bool  WikiAttrib1::readAttrib1 (WikiMotorObjVec* cell, bool& rc) {
8     ustring  key;
9     WikiMotorObjVec  vval;
10     bool  ferr = false;
11
12     if (cell->size () == 0) {
13         if (mode == M_ATTRIB || mode == M_ATTRIB_TEXT)
14             return true;
15         else
16             return false;
17     }
18     if (cell->splitChar_keyword ('=', key, vval)) {
19         if (paramID (key, vval, ferr)) {
20         } else if (paramClass (key, vval, ferr)) {
21 #ifdef BOOTSTRAPHACK
22         } else if (paramDataPrefix (key, vval, ferr)) {
23 #endif
24         } else if (paramOnClickCheck (key)) {
25             if (! checkScript (vval, onclick, ferr)) {
26                 wiki->errorMsg.append (cell->dump ()).append (CharConst (": link script error.\n"));
27                 ferr = true;
28             }
29         } else if (paramOnFocusCheck (key)) {
30             if (! checkScript (vval, onfocus, ferr)) {
31                 wiki->errorMsg.append (cell->dump ()).append (CharConst (": link script error.\n"));
32                 ferr = true;
33             }
34         } else if (paramOnBlurCheck (key)) {
35             if (! checkScript (vval, onblur, ferr)) {
36                 wiki->errorMsg.append (cell->dump ()).append (CharConst (": link script error.\n"));
37                 ferr = true;
38             }
39         } else if (paramOnChangeCheck (key)) {
40             if (! checkScript (vval, onchange, ferr)) {
41                 wiki->errorMsg.append (cell->dump ()).append (CharConst (": link script error.\n"));
42                 ferr = true;
43             }
44         } else if ((selector & SEL_TARGET) && paramTargetCheck (key)) {
45             paramTargetBody (key, vval.textOut (wiki), target, ferr);
46         } else if (readAttribMore (key, vval, ferr)) {
47         } else {
48             if (mode == M_ATTRIB) {
49                 wiki->errorMsg.append (cell->dump ()).append (CharConst (": bad attribute.\n"));
50                 rc = false;
51             }
52             return false;
53         }
54     } else {
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"))) {
61             fmultiple = true;
62         } else if ((selector & SEL_DEFAULT2) && match (key, CharConst ("default"))) {
63             fdefault = true;
64         } else if ((selector & SEL_SCRIPT2) && checkScript (*cell, script, ferr)) {
65         } else if (readAttribMore2 (key, *cell, ferr)) {
66         } else {
67             if (mode == M_ATTRIB) {
68                 wiki->errorMsg.append (cell->dump ()).append (CharConst (": bad attribute.\n"));
69                 rc = false;
70             }
71             return false;
72         }
73     }
74     if (ferr) {
75         rc = false;
76         return false;
77     } else {
78         return true;
79     }
80 }
81
82 bool  WikiAttrib1::shiftAttrib (WikiMotorObjVecPtr& vec) {
83     bool  rc = true;
84     WikiMotorObjVecPtr  v2;
85
86     while (vec->size () > 0) {
87         WikiMotorObjVec  cell;
88
89         v2 = WikiMotorObjVecPtr (new WikiMotorObjVec);
90         if (vec->splitChar (':', cell, *v2) || mode == M_ATTRIB || mode == M_ATTRIB_TEXT) {
91             if (! readAttrib1 (&cell, rc))
92                 return rc;
93             vec = v2;
94         } else {
95             return true;
96         }
97     }
98     return true;
99 }
100
101 void  WikiAttrib1::skipAttrib (WikiMotorObjVecPtr& vec) {
102     WikiMotorObjVecPtr  v2;
103
104     if (vec->size () > 0) {
105         WikiMotorObjVec  cell;
106
107         v2 = WikiMotorObjVecPtr (new WikiMotorObjVec);
108         if (vec->splitChar (':', cell, *v2)) {
109             vec = v2;
110         }
111     }
112 }
113
114 bool  WikiAttrib1::readAttrib (WikiMotorObjVecVec::const_iterator& b, const WikiMotorObjVecVec::const_iterator& e) {
115     bool  rc = true;
116
117     while (b < e) {
118         WikiMotorObjVec*  cell = b->get ();
119         if (! readAttrib1 (cell, rc))
120             return rc;
121         b ++;
122     }
123     return true;
124 }
125
126 bool  WikiAttrib1::checkScript (WikiMotorObjVec& vec, ustring& scr, bool& ferr) {
127     bool  f = false;
128     int  i;
129     ustring  u;
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: 末尾の空白を除去し,セミコロンを確認する。
134         scr.append (u);
135         f = true;
136     }
137     if (f)
138         return true;
139
140     return false;
141 }
142
143 bool  WikiAttrib1::shiftLink (WikiMotorObjVecPtr& vec, ustring& url, bool& fscript) {
144     bool  ferr = false;
145     bool  rc;
146     WikiMotorObjVec  cell;
147     WikiMotorObjVecPtr  v2 (new WikiMotorObjVec);
148
149     rc = vec->splitChar (':', cell, *v2);
150     if (checkScript (cell, url, ferr)) {
151         fscript = true;
152         vec = v2;
153         return true;
154     } else if (rc && cell.match (CharConst ("http"), CharConst ("https"))) {
155         ustring  proto = cell.dump ();
156         vec = v2;
157         cell.clear ();
158         v2 = WikiMotorObjVecPtr (new WikiMotorObjVec);
159         rc = vec->splitChar (':', cell, *v2);
160         if (! cell.splitURL_2 (wiki, proto, url)) {
161             vec = v2;
162             return false;
163         }
164         vec = v2;
165         if (vec->size () > 0) {
166             cell.clear ();
167             v2 = WikiMotorObjVecPtr (new WikiMotorObjVec);
168             rc = vec->splitChar (':', cell, *v2);
169             if (cell.splitURL_3 (wiki, url, url))
170                 vec = v2;
171         }
172         return true;
173     } else if (cell.splitURLPath (wiki, url)) {
174         vec = v2;
175         return true;
176     } else {
177         return false;
178     }
179     return false;
180 }
181
182 bool  WikiAttrib1::readLink (WikiMotorObjVecVec::const_iterator& b, const WikiMotorObjVecVec::const_iterator& e, ustring& url, bool& fscript, bool noscript) {
183     bool  ferr = false;
184     bool  rc;
185     WikiMotorObjVec*  cell;
186     static uregex  re (CharConst ("^[a-z]{3,6}$"));
187
188     if (b == e)
189         return false;
190     cell = b->get ();
191     rc = (b + 1 < e);
192     if (! noscript && checkScript (*cell, url, ferr)) {
193         fscript = true;
194         b ++;
195         return true;
196     } else if (rc && cell->regmatch (re)) {
197         ustring  proto = cell->dump ();
198         b ++;
199         cell = b->get ();
200         if (! cell->splitURL_2 (wiki, proto, url)) {
201             b ++;
202             return false;
203         }
204         b ++;
205         if (b < e) {
206             cell = b->get ();
207             if (cell->splitURL_3 (wiki, url, url))
208                 b ++;
209         }
210         return true;
211     } else if (cell->splitURLPath (wiki, url)) {
212         b ++;
213         return true;
214     } else {
215         return false;
216     }
217     return false;
218 }
219
220 bool  WikiAttrib1::shiftName (WikiMotorObjVecPtr& vec, ustring& name) {
221     if (vec->size () > 0) {
222         WikiMotorObjVec  cell;
223         WikiMotorObjVecPtr  v2 (new WikiMotorObjVec);
224
225         vec->splitChar (':', cell, *v2);
226         name = cell.textOut (wiki);
227         vec = v2;
228         return true;
229     } else {
230         return false;
231     }
232 }
233
234 void  WikiAttrib1::output (MotorOutput* out) {
235     wiki->outputID (out, id);
236     wiki->outputClass (out, classlist);
237 #ifdef BOOTSTRAPHACK
238 //    std::pair<ustring,ustring>::const_iterator  b, e;
239     std::vector<datapre_t>::const_iterator  b, e;
240     b = datapre.begin ();
241     e = datapre.end ();
242     for (; b < e; b ++) {
243         wiki->outputName (out, (*b).first.c_str (), (*b).first.size (), (*b).second);
244     }
245 #endif
246     if (start >= 0)
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);
254     // no fdefault
255     outputMore (out);
256 }
257
258 bool  WikiAttrib1::paramID (const ustring& key, WikiMotorObjVec& vval, bool& ferr) {
259     if (match (key, CharConst ("id"))) {
260         paramIDValue (key, vval, id, ferr);
261         return true;
262     } else {
263         return false;
264     }
265 }
266
267 void  WikiAttrib1::paramIDValue (const ustring& key, WikiMotorObjVec& vval, ustring& var, bool& ferr) {
268     ustring  value (vval.textOut (wiki));
269     if (checkWikiID (value)) {
270         var = value;
271         ferr = false;
272     } else {
273         wiki->errorMsg.append (key).append (uEq).append (value).append (CharConst (": bad value\n"));
274         ferr = true;
275     }
276 }
277
278 bool  WikiAttrib1::paramClass (const ustring& key, WikiMotorObjVec& vval, bool& ferr) {
279     if (match (key, CharConst ("class"))) {
280         paramClassValue (vval, classlist, ferr);
281         return true;
282     } else {
283         return false;
284     }
285 }
286
287 void  WikiAttrib1::paramClassValue (WikiMotorObjVec& vval, std::vector<ustring>& var, bool& ferr) {
288     WikiMotorObjVecVec  args;
289     ferr = false;
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 (checkWikiID (value)) {
295                 var.push_back (value);
296             } else {
297                 wiki->errorMsg.append (value).append (CharConst (": bad class name\n"));
298                 ferr = true;
299             }
300         }
301     }
302 }
303
304 bool  WikiAttrib1::paramWidth (const ustring& key, WikiMotorObjVec& vval, ustring& var, bool& ferr) {
305     if (match (key, CharConst ("width"), CharConst ("w"))) {
306         paramWidthValue (key, vval, var, ferr);
307         return true;
308     } else {
309         return false;
310     }
311 }
312
313 bool  WikiAttrib1::paramHeight (const ustring& key, WikiMotorObjVec& vval, ustring& var, bool& ferr) {
314     if (match (key, CharConst ("height"), CharConst ("h"))) {
315         paramWidthValue (key, vval, var, ferr);
316         return true;
317     } else {
318         return false;
319     }
320 }
321
322 void  WikiAttrib1::paramWidthValue (const ustring& key, WikiMotorObjVec& vval, ustring& var, bool& ferr) {
323     ustring  value (vval.textOut (wiki));
324     if (checkWidth (value)) {
325         var = value;
326         ferr = false;
327     } else {
328         wiki->errorMsg.append (key).append (uEq).append (value).append (CharConst (": bad value\n"));
329         ferr = true;
330     }
331 }
332
333 bool  WikiAttrib1::paramSize (const char* name, size_t namelen, const ustring& key, WikiMotorObjVec& vval, ustring& var, bool& ferr) {
334     if (match (key, name, namelen)) {
335         ustring  value (vval.textOut (wiki));
336         if (checkNum (value)) {
337             var = value;
338             ferr = false;
339         } else {
340             ferr = true;
341         }
342         return true;
343     }
344     return false;
345 }
346
347 void  WikiAttrib1::paramUNum (const ustring& value, int& var, const ustring& name) {
348     if (checkNum (value)) {
349         var = strtoul (value);
350     } else {
351         wiki->errorMsg.append (name).append (uEq).append (value).append (uErrorBadValue).append (uLF);
352     }
353 }
354
355 void  WikiAttrib1::paramColor (const ustring& value, ustring& var, const ustring& name) {
356     if (checkColor (value)) {
357         var = value;
358     } else {
359         wiki->errorMsg.append (name).append (uEq).append (value).append (uErrorBadValue).append (uLF);
360     }
361 }
362
363 bool  WikiAttrib1::paramTargetCheck (const ustring& key) {
364     return match (key, CharConst ("target"));
365 }
366
367 void  WikiAttrib1::paramTargetBody (const ustring& key, const ustring& value, ustring& var, bool& ferr) {
368     if (value.length () == 0 || checkWikiID (value)) {
369         var = value;
370     } else {
371         if (key.length () > 0)
372             wiki->errorMsg.append (key).append (uEq).append (value).append (CharConst (": bad target name.\n"));
373         else
374             wiki->errorMsg.append (value).append (CharConst (": bad target name.\n"));
375         ferr = true;
376     }
377 }
378
379 bool  WikiAttrib1::paramOnClickCheck (const ustring& name) {
380     return match (name, CharConst ("onclick"));
381 }
382
383 bool  WikiAttrib1::paramOnFocusCheck (const ustring& name) {
384     return match (name, CharConst ("onfocus"));
385 }
386
387 bool  WikiAttrib1::paramOnBlurCheck (const ustring& name) {
388     return match (name, CharConst ("onblur"));
389 }
390
391 bool  WikiAttrib1::paramOnChangeCheck (const ustring& name) {
392     return match (name, CharConst ("onchange"));
393 }
394
395 #ifdef BOOTSTRAPHACK
396 bool  WikiAttrib1::paramDataPrefix (const ustring& key, WikiMotorObjVec& vval, bool& ferr) {
397     if (matchHead (key, CharConst ("data-")) && checkWikiID (key)) {
398         ustring  value (vval.textOut (wiki));
399         if (checkWikiID (value)) {
400             datapre.push_back (std::pair<ustring,ustring> (key, value));
401             ferr = false;
402         } else {
403             wiki->errorMsg.append (key).append (uEq).append (value).append (CharConst (": bad value\n"));
404             ferr = true;
405         }
406         return true;
407     } else {
408         return false;
409     }
410 }
411 #endif
412 /* ============================================================ */
413 void  WikiAttribTable::init () {
414     fheader = false;
415     halign = HAlignNone;
416     valign = VAlignNone;
417     fnowrap = false;
418 #ifdef WIKITABLEATTRIB
419     fnoborder = false;
420     cellspacing = -1;
421     cellpadding = -1;
422 #endif
423     fpadding = false;
424 //      halign = HAlignNone;
425     fnowhite = false;
426     fturn = false;
427
428     id.resize (0);
429     while (! classlist.empty ())
430         classlist.pop_back ();
431     width.resize (0);
432     height.resize (0);
433     bgcolor.resize (0);
434     onclick.resize (0);
435 }
436
437 void  WikiAttribTable::copyFrom (WikiAttribTable& b) {
438     int  i;
439
440     id = b.id;
441     for (i = 0; i < b.classlist.size (); i ++)
442         classlist.push_back (b.classlist[i]);
443     onclick = b.onclick;
444     fheader = b.fheader;
445     halign = b.halign;
446     valign = b.valign;
447     width = b.width;
448     height = b.height;
449     bgcolor = b.bgcolor;
450     fnowrap = b.fnowrap;
451 }
452
453 bool  WikiAttribTable::readAttribMore (const ustring& key, WikiMotorObjVec& vval, bool& ferr) {
454     if (paramWidth (key, vval, width, ferr)) {
455     } else if (paramHeight (key, vval, height, ferr)) {
456     } else if (match (key, CharConst ("bgcolor"), CharConst ("bg"))) {
457         paramColor (vval.textOut (wiki), bgcolor, key);
458     } else {
459         switch (selector2) {
460         case SEL_TABLE:
461 #ifdef WIKITABLEATTRIB
462             if (match (key, CharConst ("cellspacing"), CharConst ("spc"))) {
463                 paramUNum (vval.textOut (wiki), cellspacing, key);
464             } else if (match (key, CharConst ("cellpadding"))) {
465                 paramUNum (vval.textOut (wiki), cellpadding, key);
466             } else {
467                 return false;
468             }
469 #else
470             return false;
471 #endif
472             break;
473         case SEL_TR:
474         case SEL_TD:
475             return false;
476         default:
477             assert (0);
478         }
479     }
480     return true;
481 }
482
483 bool  WikiAttribTable::readAttribMore2 (const ustring& key, WikiMotorObjVec& cell, bool& ferr) {
484     if (match (key, CharConst ("left"), CharConst ("l"))) {
485         halign = HAlignLeft;
486     } else if (match (key, CharConst ("right"), CharConst ("r"))) {
487         halign = HAlignRight;
488     } else if (match (key, CharConst ("center"), CharConst ("c"))) {
489         halign = HAlignCenter;
490     } else {
491         switch (selector2) {
492         case SEL_TABLE:
493 #ifdef WIKITABLEATTRIB
494             if (match (key, CharConst ("noborder"), CharConst ("nb"))) {
495                 fnoborder = true;
496             } else
497 #endif
498             if (match (key, CharConst ("padding"), CharConst ("pad"))) {
499                 fpadding = true;
500             } else if (match (key, CharConst ("expanding"), CharConst ("expand"))) {
501                 fpadding = false;
502             } else if (match (key, CharConst ("nowhite"), CharConst ("nw"))) {
503                 fnowhite = true;
504             } else if (match (key, CharConst ("turn"))) {
505                 fturn = true;
506             } else {
507                 return false;
508             }
509             break;
510         case SEL_TR:
511         case SEL_TD:
512             if (match (key, CharConst ("header"), CharConst ("h"))) {
513                 fheader = true;
514             } else if (match (key, CharConst ("top"), CharConst ("t"))) {
515                 valign = VAlignTop;
516             } else if (match (key, CharConst ("middle"), CharConst ("m"))) {
517                 valign = VAlignMiddle;
518             } else if (match (key, CharConst ("bottom"), CharConst ("b"))) {
519                 valign = VAlignBottom;
520             } else if (match (key, CharConst ("nowrap"), CharConst ("nw"))) {
521                 fnowrap = true;
522             } else if (match (key, CharConst ("*"))) {
523                 init ();
524             } else {
525                 return false;
526             }
527             break;
528         default:
529             assert (0);
530         }
531     }
532
533     return true;
534 }
535
536 void  WikiAttribTable::outputMore (MotorOutput* out) {
537     switch (halign) {
538     case HAlignLeft:
539         out->out_raw (CharConst (" align=\"left\""));
540         break;
541     case HAlignCenter:
542         out->out_raw (CharConst (" align=\"center\""));
543         break;
544     case HAlignRight:
545         out->out_raw (CharConst (" align=\"right\""));
546         break;
547     }
548     wiki->outputName (out, CharConst ("width"), width);
549     wiki->outputName (out, CharConst ("height"), height);
550     wiki->outputName (out, CharConst ("bgcolor"), bgcolor);
551
552     switch (selector2) {
553     case SEL_TABLE:
554 #ifdef WIKITABLEATTRIB
555         wiki->outputName (out, CharConst ("border"), fnoborder ? 0 : 1, false);
556         wiki->outputName (out, CharConst ("cellspacing"), cellspacing, false);
557         wiki->outputName (out, CharConst ("cellpadding"), cellpadding, false);
558 #endif
559         break;
560     case SEL_TR:
561     case SEL_TD:
562         switch (valign) {
563         case VAlignTop:
564             out->out_raw (CharConst (" valign=\"top\""));
565             break;
566         case VAlignMiddle:
567             out->out_raw (CharConst (" valign=\"middle\""));
568             break;
569         case VAlignBottom:
570             out->out_raw (CharConst (" valign=\"bottom\""));
571             break;
572         }
573         wiki->outputFlag (out, CharConst ("nowrap"), fnowrap);
574         break;
575     default:
576         assert (0);
577     }
578 }
579
580 /* ============================================================ */
581 bool  WikiAttribImg::readAttribMore (const ustring& key, WikiMotorObjVec& vval, bool& ferr) {
582     if (paramWidth (key, vval, width, ferr)) {
583         if (checkNum (width))
584             width.append (CharConst ("px"));
585     } else if (paramHeight (key, vval, height, ferr)) {
586         if (checkNum (height))
587             height.append (CharConst ("px"));
588     } else if (match (key, CharConst ("alt"))) {
589         alt = vval.textOut (wiki);
590     } else {
591         return false;
592     }
593     return true;
594 }
595
596 void  WikiAttribImg::outputMore (MotorOutput* out) {
597 //    wiki->outputName (out, CharConst ("width"), width);
598 //    wiki->outputName (out, CharConst ("height"), height);
599     if (width.length () > 0 || height.length () > 0) {
600         out->out_raw (CharConst (" style=\""));
601         if (width.length () > 0)
602             out->out_raw (CharConst ("width:"))->out_toHTML_noCtrl (width)->out_raw (CharConst (";"));
603         if (height.length () > 0)
604             out->out_raw (CharConst ("height:"))->out_toHTML_noCtrl (height)->out_raw (CharConst (";"));
605         out->out_raw (CharConst ("\""));
606     }
607     // longdesc
608 }
609
610 /* ============================================================ */
611 bool  WikiAttribInput::readAttribMore (const ustring& key, WikiMotorObjVec& vval, bool& ferr) {
612     if ((selector2 & SEL_INPUT) && paramSize (CharConst ("size"), key, vval, psize, ferr)) {
613     } else if ((selector2 & SEL_ELSIZE) && match (key, CharConst ("size"))) {
614         ustring  v = vval.textOut (wiki);
615         if (match (v, CharConst ("*"))) {
616             elsize = 1;
617         } else if (checkNum (v)) {
618             elsize = to_int32 (v);
619             if (elsize < 0 || elsize > 999) {
620                 elsize = 1;
621             }
622         } else {
623             elsize = 1;
624         }
625     } else if (paramWidth (key, vval, pwidth, ferr)) {
626     } else if ((selector2 & SEL_TEXTAREA) && paramSize (CharConst ("cols"), key, vval, pcols, ferr)) {
627     } else if ((selector2 & SEL_TEXTAREA) && paramSize (CharConst ("rows"), key, vval, prows, ferr)) {
628     } else if ((selector2 & SEL_TEXTAREA) && match (key, CharConst ("wrap"))) {
629         ustring  value (vval.textOut (wiki));
630         if (match (value, CharConst ("off"))) {
631             pwrap = W_OFF;
632         } else if (match (value, CharConst ("soft"))) {
633             pwrap = W_SOFT;
634         } else if (match (value, CharConst ("hard"))) {
635             pwrap = W_HARD;
636         } else {
637             wiki->errorMsg.append (key).append (CharConst ("=")).append (vval.dump ()).append (CharConst (": link script error.\n"));
638             ferr = true;
639             return false;
640         }
641     } else if (match (key, CharConst ("accept"))) {
642         ustring  value (vval.textOut (wiki));
643         if (match (value, CharConst ("camera"))) {
644             paccept.assign (CharConst ("image/*;capture=camera"));
645         } else {
646             static  uregex re ("^"
647                                "(" "[a-z_0-9-]+/[a-z_0-9.+*-]+" ")"
648                                "(" "," "(" "[a-z_0-9-]+/[a-z_0-9.+*-]+" ")" ")*"
649                                "(" ";" "[a-z_0-9-]+=[a-zA-Z_0-9.+*-]+" ")*"
650                                "$");
651             if (checkRe (value, re)) {
652                 paccept = value;
653             } else {
654                 return false;
655             }
656         }
657     } else {
658         return false;
659     }
660     return true;
661 }
662
663 bool  WikiAttribInput::readAttribMore2 (const ustring& key, WikiMotorObjVec& cell, bool& ferr) {
664     if (key == uDefault) {
665         pdefault = true;
666     } else if ((selector2 & SEL_CHECK) && match (key, CharConst ("checked"))) {
667         pchecked = true;
668     } else if ((selector2 & SEL_TEXTAREA) && match (key, CharConst ("tab"))) {
669         ftab = true;
670     } else {
671         return false;
672     }
673     return true;
674 }
675
676 void  WikiAttribInput::outputMore (MotorOutput* out) {
677     wiki->outputName (out, CharConst ("size"), psize);
678     wiki->outputName (out, CharConst ("size"), elsize);
679     if (pwidth.size () > 0) {
680         if (checkNum (pwidth)) {
681             out->out_raw (CharConst (" style=\"width:"))->out_toHTML_noCtrl (pwidth)->out_raw (CharConst ("px;\""));
682         } else {
683             out->out_raw (CharConst (" style=\"width:"))->out_toHTML_noCtrl (pwidth)->out_raw (CharConst (";\""));
684         }
685     }
686     if (selector2 & SEL_CHECK) {
687         wiki->outputFlag (out, CharConst ("checked"), pchecked);
688     }
689     if (selector2 & SEL_TEXTAREA) {
690         wiki->outputName (out, CharConst ("cols"), pcols, false);
691         wiki->outputName (out, CharConst ("rows"), prows);
692         switch (pwrap) {
693         case W_OFF:
694             out->out_raw (CharConst (" wrap=\"off\""));
695             break;
696         case W_SOFT:
697             out->out_raw (CharConst (" wrap=\"soft\""));
698             //  out->out_raw (CharConst (" wrap=\"virtual\""));
699             break;
700         case W_HARD:
701             out->out_raw (CharConst (" wrap=\"hard\""));
702             //  out->out_raw (CharConst (" wrap=\"physical\""));
703             break;
704         }
705         if (ftab) {
706             out->out_raw (uSPC)
707                 ->out_raw (CharConst ("onkeypress"))
708                 ->out_raw (CharConst ("=\""))
709                 ->out_toHTML (ustring (CharConst ("return insertTab(event,this);")))
710                 ->out_raw ("\"");
711             out->out_raw (uSPC)
712                 ->out_raw (CharConst ("onkeydown"))
713                 ->out_raw (CharConst ("=\""))
714                 ->out_toHTML (ustring (CharConst ("return insertTab(event,this);")))
715                 ->out_raw (uQ2);
716             out->out_raw (uSPC)
717                 ->out_raw (CharConst ("onkeyup"))
718                 ->out_raw (CharConst ("=\""))
719                 ->out_toHTML (ustring (CharConst ("return insertTab(event,this);")))
720                 ->out_raw (uQ2);
721         }
722     }
723     if (paccept.length () > 0) {
724         out->out_raw (CharConst (" accept=\""))
725             ->out_toHTML (paccept)
726             ->out_raw (uQ2);
727     }
728 }
729
730 /* ============================================================ */
731 bool  WikiAttribButton::readAttrib (WikiMotorObjVecVec::const_iterator& b, const WikiMotorObjVecVec::const_iterator& e) {
732     bool  rc = true;
733
734     if (b < e) {
735         WikiMotorObjVec*  cell = b->get ();
736         mode_t  bm = mode;
737
738         mode = M_NORMAL;
739         if (! readAttrib1 (cell, rc)) {
740             name = cell->textOut (wiki);
741         }
742         mode = bm;
743         b ++;
744     }
745     while (b < e) {
746         WikiMotorObjVec*  cell = b->get ();
747         if (! readAttrib1 (cell, rc))
748             return rc;
749         b ++;
750     }
751     return true;
752 }
753
754 /* ============================================================ */
755 bool  WikiAttribItem::readAttribMore (const ustring& key, WikiMotorObjVec& vval, bool& ferr) {
756     if (match (key, CharConst ("ulclass"))) {
757         if (owner && owner->parent && owner->parent->attrib.classlist.size () == 0) {
758             paramClassValue (vval, owner->parent->attrib.classlist, ferr);
759         }
760     } else if (match (key, CharConst ("ulid"))) {
761         if (owner && owner->parent && owner->parent->attrib.id.size () == 0) {
762             paramIDValue (key, vval, owner->parent->attrib.id, ferr);
763         }
764     } else if (owner && owner->parent && (owner->parent->attrib.selector & SEL_START) && match (key, CharConst ("start"))) {
765         paramUNum (vval.textOut (wiki), owner->parent->attrib.start, key);
766     } else {
767         return false;
768     }
769     return true;
770 }
771
772 /* ============================================================ */