OSDN Git Service

disable the textarea hack by default.
[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 (matchWikiID (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 ((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);
298             } else {
299                 wiki->errorMsg.append (value).append (CharConst (": bad class name\n"));
300                 ferr = true;
301             }
302         }
303     }
304 }
305
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);
309         return true;
310     } else {
311         return false;
312     }
313 }
314
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);
318         return true;
319     } else {
320         return false;
321     }
322 }
323
324 void  WikiAttrib1::paramWidthValue (const ustring& key, WikiMotorObjVec& vval, ustring& var, bool& ferr) {
325     ustring  value (vval.textOut (wiki));
326     if (matchWidth (value)) {
327         var = value;
328         ferr = false;
329     } else {
330         wiki->errorMsg.append (key).append (uEq).append (value).append (CharConst (": bad value\n"));
331         ferr = true;
332     }
333 }
334
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)) {
339             var = value;
340             ferr = false;
341         } else {
342             ferr = true;
343         }
344         return true;
345     }
346     return false;
347 }
348
349 void  WikiAttrib1::paramUNum (const ustring& value, int& var, const ustring& name) {
350     if (matchNum (value)) {
351         var = strtoul (value);
352     } else {
353         wiki->errorMsg.append (name).append (uEq).append (value).append (uErrorBadValue).append (uLF);
354     }
355 }
356
357 void  WikiAttrib1::paramColor (const ustring& value, ustring& var, const ustring& name) {
358     if (checkColor (value)) {
359         var = value;
360     } else {
361         wiki->errorMsg.append (name).append (uEq).append (value).append (uErrorBadValue).append (uLF);
362     }
363 }
364
365 bool  WikiAttrib1::paramTargetCheck (const ustring& key) {
366     return match (key, CharConst ("target"));
367 }
368
369 void  WikiAttrib1::paramTargetBody (const ustring& key, const ustring& value, ustring& var, bool& ferr) {
370     if (value.length () == 0 || matchWikiID (value)) {
371         var = value;
372     } else {
373         if (key.length () > 0)
374             wiki->errorMsg.append (key).append (uEq).append (value).append (CharConst (": bad target name.\n"));
375         else
376             wiki->errorMsg.append (value).append (CharConst (": bad target name.\n"));
377         ferr = true;
378     }
379 }
380
381 bool  WikiAttrib1::paramOnClickCheck (const ustring& name) {
382     return match (name, CharConst ("onclick"));
383 }
384
385 bool  WikiAttrib1::paramOnFocusCheck (const ustring& name) {
386     return match (name, CharConst ("onfocus"));
387 }
388
389 bool  WikiAttrib1::paramOnBlurCheck (const ustring& name) {
390     return match (name, CharConst ("onblur"));
391 }
392
393 bool  WikiAttrib1::paramOnChangeCheck (const ustring& name) {
394     return match (name, CharConst ("onchange"));
395 }
396
397 #ifdef BOOTSTRAPHACK
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));
403             ferr = false;
404         } else {
405             wiki->errorMsg.append (key).append (uEq).append (value).append (CharConst (": bad value\n"));
406             ferr = true;
407         }
408         return true;
409     } else {
410         return false;
411     }
412 }
413 #endif
414 /* ============================================================ */
415 void  WikiAttribTable::init () {
416     fheader = false;
417     halign = HAlignNone;
418     valign = VAlignNone;
419     fnowrap = false;
420 #ifdef WIKITABLEATTRIB
421     fnoborder = false;
422     cellspacing = -1;
423     cellpadding = -1;
424 #endif
425     fpadding = false;
426 //      halign = HAlignNone;
427     fnowhite = false;
428     fturn = false;
429
430     id.resize (0);
431     while (! classlist.empty ())
432         classlist.pop_back ();
433     width.resize (0);
434     height.resize (0);
435     bgcolor.resize (0);
436     onclick.resize (0);
437 }
438
439 void  WikiAttribTable::copyFrom (WikiAttribTable& b) {
440     int  i;
441
442     id = b.id;
443     for (i = 0; i < b.classlist.size (); i ++)
444         classlist.push_back (b.classlist[i]);
445     onclick = b.onclick;
446     fheader = b.fheader;
447     halign = b.halign;
448     valign = b.valign;
449     width = b.width;
450     height = b.height;
451     bgcolor = b.bgcolor;
452     fnowrap = b.fnowrap;
453 }
454
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);
460     } else {
461         switch (selector2) {
462         case SEL_TABLE:
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);
468             } else {
469                 return false;
470             }
471 #else
472             return false;
473 #endif
474             break;
475         case SEL_TR:
476         case SEL_TD:
477             return false;
478         default:
479             assert (0);
480         }
481     }
482     return true;
483 }
484
485 bool  WikiAttribTable::readAttribMore2 (const ustring& key, WikiMotorObjVec& cell, bool& ferr) {
486     if (match (key, CharConst ("left"), CharConst ("l"))) {
487         halign = HAlignLeft;
488     } else if (match (key, CharConst ("right"), CharConst ("r"))) {
489         halign = HAlignRight;
490     } else if (match (key, CharConst ("center"), CharConst ("c"))) {
491         halign = HAlignCenter;
492     } else {
493         switch (selector2) {
494         case SEL_TABLE:
495 #ifdef WIKITABLEATTRIB
496             if (match (key, CharConst ("noborder"), CharConst ("nb"))) {
497                 fnoborder = true;
498             } else
499 #endif
500             if (match (key, CharConst ("padding"), CharConst ("pad"))) {
501                 fpadding = true;
502             } else if (match (key, CharConst ("expanding"), CharConst ("expand"))) {
503                 fpadding = false;
504             } else if (match (key, CharConst ("nowhite"), CharConst ("nw"))) {
505                 fnowhite = true;
506             } else if (match (key, CharConst ("turn"))) {
507                 fturn = true;
508             } else {
509                 return false;
510             }
511             break;
512         case SEL_TR:
513         case SEL_TD:
514             if (match (key, CharConst ("header"), CharConst ("h"))) {
515                 fheader = true;
516             } else if (match (key, CharConst ("top"), CharConst ("t"))) {
517                 valign = VAlignTop;
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"))) {
523                 fnowrap = true;
524             } else if (match (key, CharConst ("*"))) {
525                 init ();
526             } else {
527                 return false;
528             }
529             break;
530         default:
531             assert (0);
532         }
533     }
534
535     return true;
536 }
537
538 void  WikiAttribTable::outputMore (MotorOutput* out) {
539     switch (halign) {
540     case HAlignLeft:
541         out->out_raw (CharConst (" align=\"left\""));
542         break;
543     case HAlignCenter:
544         out->out_raw (CharConst (" align=\"center\""));
545         break;
546     case HAlignRight:
547         out->out_raw (CharConst (" align=\"right\""));
548         break;
549     default:;
550     }
551     wiki->outputName (out, CharConst ("width"), width);
552     wiki->outputName (out, CharConst ("height"), height);
553     wiki->outputName (out, CharConst ("bgcolor"), bgcolor);
554
555     switch (selector2) {
556     case SEL_TABLE:
557 #ifdef WIKITABLEATTRIB
558         wiki->outputName (out, CharConst ("border"), fnoborder ? 0 : 1, false);
559         wiki->outputName (out, CharConst ("cellspacing"), cellspacing, false);
560         wiki->outputName (out, CharConst ("cellpadding"), cellpadding, false);
561 #endif
562         break;
563     case SEL_TR:
564     case SEL_TD:
565         switch (valign) {
566         case VAlignTop:
567             out->out_raw (CharConst (" valign=\"top\""));
568             break;
569         case VAlignMiddle:
570             out->out_raw (CharConst (" valign=\"middle\""));
571             break;
572         case VAlignBottom:
573             out->out_raw (CharConst (" valign=\"bottom\""));
574             break;
575         default:;
576         }
577         wiki->outputFlag (out, CharConst ("nowrap"), fnowrap);
578         break;
579     default:
580         assert (0);
581     }
582 }
583
584 /* ============================================================ */
585 bool  WikiAttribImg::readAttribMore (const ustring& key, WikiMotorObjVec& vval, bool& ferr) {
586     if (paramWidth (key, vval, width, ferr)) {
587         if (matchNum (width))
588             width.append (CharConst ("px"));
589     } else if (paramHeight (key, vval, height, ferr)) {
590         if (matchNum (height))
591             height.append (CharConst ("px"));
592     } else if (match (key, CharConst ("alt"))) {
593         alt = vval.textOut (wiki);
594     } else {
595         return false;
596     }
597     return true;
598 }
599
600 void  WikiAttribImg::outputMore (MotorOutput* out) {
601 //    wiki->outputName (out, CharConst ("width"), width);
602 //    wiki->outputName (out, CharConst ("height"), height);
603     if (width.length () > 0 || height.length () > 0) {
604         out->out_raw (CharConst (" style=\""));
605         if (width.length () > 0)
606             out->out_raw (CharConst ("width:"))->out_toHTML_noCtrl (width)->out_raw (CharConst (";"));
607         if (height.length () > 0)
608             out->out_raw (CharConst ("height:"))->out_toHTML_noCtrl (height)->out_raw (CharConst (";"));
609         out->out_raw (CharConst ("\""));
610     }
611     // longdesc
612 }
613
614 /* ============================================================ */
615 bool  WikiAttribInput::readAttribMore (const ustring& key, WikiMotorObjVec& vval, bool& ferr) {
616     if ((selector2 & SEL_INPUT) && paramSize (CharConst ("size"), key, vval, psize, ferr)) {
617     } else if ((selector2 & SEL_ELSIZE) && match (key, CharConst ("size"))) {
618         ustring  v = vval.textOut (wiki);
619         if (match (v, CharConst ("*"))) {
620             elsize = 1;
621         } else if (matchNum (v)) {
622             elsize = to_int32 (v);
623             if (elsize < 0 || elsize > 999) {
624                 elsize = 1;
625             }
626         } else {
627             elsize = 1;
628         }
629     } else if (paramWidth (key, vval, pwidth, ferr)) {
630     } else if ((selector2 & SEL_TEXTAREA) && paramSize (CharConst ("cols"), key, vval, pcols, ferr)) {
631     } else if ((selector2 & SEL_TEXTAREA) && paramSize (CharConst ("rows"), key, vval, prows, ferr)) {
632     } else if ((selector2 & SEL_TEXTAREA) && match (key, CharConst ("wrap"))) {
633         ustring  value (vval.textOut (wiki));
634         if (match (value, CharConst ("off"))) {
635             pwrap = W_OFF;
636         } else if (match (value, CharConst ("soft"))) {
637             pwrap = W_SOFT;
638         } else if (match (value, CharConst ("hard"))) {
639             pwrap = W_HARD;
640         } else {
641             wiki->errorMsg.append (key).append (CharConst ("=")).append (vval.dump ()).append (CharConst (": link script error.\n"));
642             ferr = true;
643             return false;
644         }
645     } else if (match (key, CharConst ("accept"))) {
646         ustring  value (vval.textOut (wiki));
647         if (match (value, CharConst ("camera"))) {
648             paccept.assign (CharConst ("image/*;capture=camera"));
649         } else {
650             static  uregex re ("^"
651                                "(" "[a-z_0-9-]+/[a-z_0-9.+*-]+" ")"
652                                "(" "," "(" "[a-z_0-9-]+/[a-z_0-9.+*-]+" ")" ")*"
653                                "(" ";" "[a-z_0-9-]+=[a-zA-Z_0-9.+*-]+" ")*"
654                                "$");
655             if (checkRe (value, re)) {
656                 paccept = value;
657             } else {
658                 return false;
659             }
660         }
661     } else {
662         return false;
663     }
664     return true;
665 }
666
667 bool  WikiAttribInput::readAttribMore2 (const ustring& key, WikiMotorObjVec& cell, bool& ferr) {
668     if (key == uDefault) {
669         pdefault = true;
670     } else if ((selector2 & SEL_CHECK) && match (key, CharConst ("checked"))) {
671         pchecked = true;
672 #ifdef INSERTTABHACK
673     } else if ((selector2 & SEL_TEXTAREA) && match (key, CharConst ("tab"))) {
674         ftab = true;
675 #endif
676     } else {
677         return false;
678     }
679     return true;
680 }
681
682 void  WikiAttribInput::outputMore (MotorOutput* out) {
683     wiki->outputName (out, CharConst ("size"), psize);
684     wiki->outputName (out, CharConst ("size"), elsize);
685     if (pwidth.size () > 0) {
686         if (matchNum (pwidth)) {
687             out->out_raw (CharConst (" style=\"width:"))->out_toHTML_noCtrl (pwidth)->out_raw (CharConst ("px;\""));
688         } else {
689             out->out_raw (CharConst (" style=\"width:"))->out_toHTML_noCtrl (pwidth)->out_raw (CharConst (";\""));
690         }
691     }
692     if (selector2 & SEL_CHECK) {
693         wiki->outputFlag (out, CharConst ("checked"), pchecked);
694     }
695     if (selector2 & SEL_TEXTAREA) {
696         wiki->outputName (out, CharConst ("cols"), pcols, false);
697         wiki->outputName (out, CharConst ("rows"), prows);
698         switch (pwrap) {
699         case W_OFF:
700             out->out_raw (CharConst (" wrap=\"off\""));
701             break;
702         case W_SOFT:
703             out->out_raw (CharConst (" wrap=\"soft\""));
704             //  out->out_raw (CharConst (" wrap=\"virtual\""));
705             break;
706         case W_HARD:
707             out->out_raw (CharConst (" wrap=\"hard\""));
708             //  out->out_raw (CharConst (" wrap=\"physical\""));
709             break;
710         }
711 #ifdef INSERTTABHACK
712         if (ftab) {
713             out->out_raw (uSPC)
714                 ->out_raw (CharConst ("onkeypress"))
715                 ->out_raw (CharConst ("=\""))
716                 ->out_toHTML (ustring (CharConst ("return insertTab(event,this);")))
717                 ->out_raw ("\"");
718             out->out_raw (uSPC)
719                 ->out_raw (CharConst ("onkeydown"))
720                 ->out_raw (CharConst ("=\""))
721                 ->out_toHTML (ustring (CharConst ("return insertTab(event,this);")))
722                 ->out_raw (uQ2);
723             out->out_raw (uSPC)
724                 ->out_raw (CharConst ("onkeyup"))
725                 ->out_raw (CharConst ("=\""))
726                 ->out_toHTML (ustring (CharConst ("return insertTab(event,this);")))
727                 ->out_raw (uQ2);
728         }
729 #endif
730     }
731     if (paccept.length () > 0) {
732         out->out_raw (CharConst (" accept=\""))
733             ->out_toHTML (paccept)
734             ->out_raw (uQ2);
735     }
736 }
737
738 /* ============================================================ */
739 bool  WikiAttribButton::readAttrib (WikiMotorObjVecVec::const_iterator& b, const WikiMotorObjVecVec::const_iterator& e) {
740     bool  rc = true;
741
742     if (b < e) {
743         WikiMotorObjVec*  cell = b->get ();
744         mode_t  bm = mode;
745
746         mode = M_NORMAL;
747         if (! readAttrib1 (cell, rc)) {
748             name = cell->textOut (wiki);
749         }
750         mode = bm;
751         b ++;
752     }
753     while (b < e) {
754         WikiMotorObjVec*  cell = b->get ();
755         if (! readAttrib1 (cell, rc))
756             return rc;
757         b ++;
758     }
759     return true;
760 }
761
762 /* ============================================================ */
763 bool  WikiAttribItem::readAttribMore (const ustring& key, WikiMotorObjVec& vval, bool& ferr) {
764     if (match (key, CharConst ("ulclass"))) {
765         if (owner && owner->parent && owner->parent->attrib.classlist.size () == 0) {
766             paramClassValue (vval, owner->parent->attrib.classlist, ferr);
767         }
768     } else if (match (key, CharConst ("ulid"))) {
769         if (owner && owner->parent && owner->parent->attrib.id.size () == 0) {
770             paramIDValue (key, vval, owner->parent->attrib.id, ferr);
771         }
772     } else if (owner && owner->parent && (owner->parent->attrib.selector & SEL_START) && match (key, CharConst ("start"))) {
773         paramUNum (vval.textOut (wiki), owner->parent->attrib.start, key);
774     } else {
775         return false;
776     }
777     return true;
778 }
779
780 /* ============================================================ */