OSDN Git Service

tab option of wiki textarea.
[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 (fwhole)
14         if (mode == M_ATTRIB || mode == M_ATTRIB_TEXT)
15             return true;
16         else
17             return false;
18     }
19     if (cell->splitChar_keyword ('=', key, vval)) {
20         if (wiki->paramID (key, vval, id, ferr)) {
21         } else if (wiki->paramClass (key, vval, classlist, ferr)) {
22         } else if (wiki->paramOnClickCheck (key)) {
23             if (! checkScript (vval, onclick, ferr)) {
24                 wiki->errorMsg.append (cell->dump ()).append (CharConst (": link script error.\n"));
25                 ferr = true;
26             }
27         } else if (wiki->paramOnFocusCheck (key)) {
28             if (! checkScript (vval, onfocus, ferr)) {
29                 wiki->errorMsg.append (cell->dump ()).append (CharConst (": link script error.\n"));
30                 ferr = true;
31             }
32         } else if (wiki->paramOnBlurCheck (key)) {
33             if (! checkScript (vval, onblur, ferr)) {
34                 wiki->errorMsg.append (cell->dump ()).append (CharConst (": link script error.\n"));
35                 ferr = true;
36             }
37         } else if (wiki->paramOnChangeCheck (key)) {
38             if (! checkScript (vval, onchange, ferr)) {
39                 wiki->errorMsg.append (cell->dump ()).append (CharConst (": link script error.\n"));
40                 ferr = true;
41             }
42         } else if ((selector & SEL_TARGET) && wiki->paramTargetCheck (key)) {
43             wiki->paramTargetBody (key, vval.textOut (wiki), target, ferr);
44         } else if (readAttribMore (key, vval, ferr)) {
45         } else {
46 //          if (fwhole) {
47             if (mode == M_ATTRIB) {
48                 wiki->errorMsg.append (cell->dump ()).append (CharConst (": bad attribute.\n"));
49                 rc = false;
50             }
51             return false;
52         }
53     } else {
54         if (selector & SEL_CLASS2) {
55             wiki->paramClassValue (*cell, classlist, ferr);
56         } else if (selector & SEL_TARGET2) {
57             wiki->paramTargetBody (uEmpty, cell->textOut (wiki), target, ferr);
58         } else if ((selector & SEL_ONCLICK2) && checkScript (*cell, onclick, ferr)) {
59         } else if ((selector & SEL_MULTIPLE2) && match (key, CharConst ("multiple"))) {
60             fmultiple = true;
61         } else if ((selector & SEL_DEFAULT2) && match (key, CharConst ("default"))) {
62             fdefault = true;
63         } else if ((selector & SEL_SCRIPT2) && checkScript (*cell, script, ferr)) {
64         } else if (readAttribMore2 (key, *cell, ferr)) {
65         } else {
66 //          if (fwhole) {
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) || fwhole) {
91         if (vec->splitChar (':', cell, *v2) || mode == M_ATTRIB || mode == M_ATTRIB_TEXT) {
92             if (! readAttrib1 (&cell, rc))
93                 return rc;
94             vec = v2;
95         } else {
96             return true;
97         }
98     }
99     return true;
100 }
101
102 void  WikiAttrib1::skipAttrib (WikiMotorObjVecPtr& vec) {
103     WikiMotorObjVecPtr  v2;
104
105     if (vec->size () > 0) {
106         WikiMotorObjVec  cell;
107
108         v2 = WikiMotorObjVecPtr (new WikiMotorObjVec);
109         if (vec->splitChar (':', cell, *v2)) {
110             vec = v2;
111         }
112     }
113 }
114
115 bool  WikiAttrib1::readAttrib (WikiMotorObjVecVec::const_iterator& b, const WikiMotorObjVecVec::const_iterator& e) {
116     bool  rc = true;
117
118     while (b < e) {
119         WikiMotorObjVec*  cell = b->get ();
120         if (! readAttrib1 (cell, rc))
121             return rc;
122         b ++;
123     }
124     return true;
125 }
126
127 bool  WikiAttrib1::checkScript (WikiMotorObjVec& vec, ustring& scr, bool& ferr) {
128     bool  f = false;
129     int  i;
130     ustring  u;
131     for (i = 0; i < vec.size () && vec[i]->type == WikiMotorObj::wiki_funcLink; i ++) {
132         WikiMotorObjFuncLink*  fn = WikiMotorObjFuncLink_type (&*vec[i]);
133         u = fn->execDefunArgs (wiki);
134         // XXX: 末尾の空白を除去し,セミコロンを確認する。
135         scr.append (u);
136         f = true;
137     }
138     if (f)
139         return true;
140
141     return false;
142 }
143
144 bool  WikiAttrib1::shiftLink (WikiMotorObjVecPtr& vec, ustring& url, bool& fscript) {
145     bool  ferr = false;
146     bool  rc;
147     WikiMotorObjVec  cell;
148     WikiMotorObjVecPtr  v2 (new WikiMotorObjVec);
149
150     rc = vec->splitChar (':', cell, *v2);
151     if (checkScript (cell, url, ferr)) {
152         fscript = true;
153         vec = v2;
154         return true;
155     } else if (rc && cell.match (CharConst ("http"), CharConst ("https"))) {
156         ustring  proto = cell.dump ();
157         vec = v2;
158         cell.clear ();
159         v2 = WikiMotorObjVecPtr (new WikiMotorObjVec);
160         rc = vec->splitChar (':', cell, *v2);
161         if (! cell.splitURL_2 (wiki, proto, url)) {
162             vec = v2;
163             return false;
164         }
165         vec = v2;
166         if (vec->size () > 0) {
167             cell.clear ();
168             v2 = WikiMotorObjVecPtr (new WikiMotorObjVec);
169             rc = vec->splitChar (':', cell, *v2);
170             if (cell.splitURL_3 (wiki, url, url))
171                 vec = v2;
172         }
173         return true;
174     } else if (cell.splitURLPath (wiki, url)) {
175         vec = v2;
176         return true;
177     } else {
178         return false;
179     }
180     return false;
181 }
182
183 bool  WikiAttrib1::readLink (WikiMotorObjVecVec::const_iterator& b, const WikiMotorObjVecVec::const_iterator& e, ustring& url, bool& fscript, bool noscript) {
184     bool  ferr = false;
185     bool  rc;
186     WikiMotorObjVec*  cell;
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->match (CharConst ("http"), CharConst ("https"))) {
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     wiki->outputSubmitScript (out, CharConst ("onclick"), onclick);
238     wiki->outputSubmitScript (out, CharConst ("onfocus"), onfocus);
239     wiki->outputSubmitScript (out, CharConst ("onblur"), onblur);
240     wiki->outputSubmitScript (out, CharConst ("onchange"), onchange);
241     wiki->outputName (out, CharConst ("target"), target);
242 //    wiki->outputName (out, CharConst ("size"), elsize);
243     wiki->outputFlag (out, CharConst ("multiple"), fmultiple);
244     // no fdefault
245     outputMore (out);
246 }
247
248 /* ============================================================ */
249 void  WikiAttribTable::init () {
250     fheader = false;
251     halign = HAlignNone;
252     valign = VAlignNone;
253     fnowrap = false;
254     fnoborder = false;
255     cellspacing = -1;
256     cellpadding = -1;
257     fpadding = false;
258 //      halign = HAlignNone;
259     fnowhite = false;
260     fturn = false;
261
262     id.resize (0);
263     while (! classlist.empty ())
264         classlist.pop_back ();
265     width.resize (0);
266     height.resize (0);
267     bgcolor.resize (0);
268     onclick.resize (0);
269 }
270
271 void  WikiAttribTable::copyFrom (WikiAttribTable& b) {
272     int  i;
273
274     id = b.id;
275     for (i = 0; i < b.classlist.size (); i ++)
276         classlist.push_back (b.classlist[i]);
277     onclick = b.onclick;
278     fheader = b.fheader;
279     halign = b.halign;
280     valign = b.valign;
281     width = b.width;
282     height = b.height;
283     bgcolor = b.bgcolor;
284     fnowrap = b.fnowrap;
285 }
286
287 bool  WikiAttribTable::readAttribMore (const ustring& key, WikiMotorObjVec& vval, bool& ferr) {
288     if (wiki->paramWidth (key, vval, width, ferr)) {
289     } else if (wiki->paramHeight (key, vval, height, ferr)) {
290     } else if (match (key, CharConst ("bgcolor"), CharConst ("bg"))) {
291         wiki->paramColor (vval.textOut (wiki), bgcolor, key);
292     } else {
293         switch (selector2) {
294         case SEL_TABLE:
295             if (match (key, CharConst ("cellspacing"), CharConst ("spc"))) {
296                 wiki->paramUNum (vval.textOut (wiki), cellspacing, key);
297             } else if (match (key, CharConst ("cellpadding"))) {
298                 wiki->paramUNum (vval.textOut (wiki), cellpadding, key);
299             } else {
300                 return false;
301             }
302             break;
303         case SEL_TR:
304         case SEL_TD:
305             return false;
306         default:
307             assert (0);
308         }
309     }
310     return true;
311 }
312
313 bool  WikiAttribTable::readAttribMore2 (const ustring& key, WikiMotorObjVec& cell, bool& ferr) {
314     if (match (key, CharConst ("left"), CharConst ("l"))) {
315         halign = HAlignLeft;
316     } else if (match (key, CharConst ("right"), CharConst ("r"))) {
317         halign = HAlignRight;
318     } else if (match (key, CharConst ("center"), CharConst ("c"))) {
319         halign = HAlignCenter;
320     } else {
321         switch (selector2) {
322         case SEL_TABLE:
323             if (match (key, CharConst ("noborder"), CharConst ("nb"))) {
324                 fnoborder = true;
325             } else if (match (key, CharConst ("padding"), CharConst ("pad"))) {
326                 fpadding = true;
327             } else if (match (key, CharConst ("expanding"), CharConst ("expand"))) {
328                 fpadding = false;
329             } else if (match (key, CharConst ("nowhite"), CharConst ("nw"))) {
330                 fnowhite = true;
331             } else if (match (key, CharConst ("turn"))) {
332                 fturn = true;
333             } else {
334                 return false;
335             }
336             break;
337         case SEL_TR:
338         case SEL_TD:
339             if (match (key, CharConst ("header"), CharConst ("h"))) {
340                 fheader = true;
341             } else if (match (key, CharConst ("top"), CharConst ("t"))) {
342                 valign = VAlignTop;
343             } else if (match (key, CharConst ("middle"), CharConst ("m"))) {
344                 valign = VAlignMiddle;
345             } else if (match (key, CharConst ("bottom"), CharConst ("b"))) {
346                 valign = VAlignBottom;
347             } else if (match (key, CharConst ("nowrap"), CharConst ("nw"))) {
348                 fnowrap = true;
349             } else if (match (key, CharConst ("*"))) {
350                 init ();
351             } else {
352                 return false;
353             }
354             break;
355         default:
356             assert (0);
357         }
358     }
359
360     return true;
361 }
362
363 void  WikiAttribTable::outputMore (MotorOutput* out) {
364     switch (halign) {
365     case HAlignLeft:
366         out->out_raw (CharConst (" align=\"left\""));
367         break;
368     case HAlignCenter:
369         out->out_raw (CharConst (" align=\"center\""));
370         break;
371     case HAlignRight:
372         out->out_raw (CharConst (" align=\"right\""));
373         break;
374     }
375     wiki->outputName (out, CharConst ("width"), width);
376     wiki->outputName (out, CharConst ("height"), height);
377     wiki->outputName (out, CharConst ("bgcolor"), bgcolor);
378
379     switch (selector2) {
380     case SEL_TABLE:
381         wiki->outputName (out, CharConst ("border"), fnoborder ? 0 : 1, false);
382         wiki->outputName (out, CharConst ("cellspacing"), cellspacing, false);
383         wiki->outputName (out, CharConst ("cellpadding"), cellpadding, false);
384         break;
385     case SEL_TR:
386     case SEL_TD:
387         switch (valign) {
388         case VAlignTop:
389             out->out_raw (CharConst (" valign=\"top\""));
390             break;
391         case VAlignMiddle:
392             out->out_raw (CharConst (" valign=\"middle\""));
393             break;
394         case VAlignBottom:
395             out->out_raw (CharConst (" valign=\"bottom\""));
396             break;
397         }
398         wiki->outputFlag (out, CharConst ("nowrap"), fnowrap);
399         break;
400     default:
401         assert (0);
402     }
403 }
404
405 /* ============================================================ */
406 bool  WikiAttribImg::readAttribMore (const ustring& key, WikiMotorObjVec& vval, bool& ferr) {
407     if (wiki->paramWidth (key, vval, width, ferr)) {
408     } else if (wiki->paramHeight (key, vval, height, ferr)) {
409     } else if (match (key, CharConst ("alt"))) {
410         alt = vval.textOut (wiki);
411     } else {
412         return false;
413     }
414     return true;
415 }
416
417 void  WikiAttribImg::outputMore (MotorOutput* out) {
418     wiki->outputName (out, CharConst ("width"), width);
419     wiki->outputName (out, CharConst ("height"), height);
420     // longdesc
421 }
422
423 /* ============================================================ */
424 bool  WikiAttribInput::readAttribMore (const ustring& key, WikiMotorObjVec& vval, bool& ferr) {
425     if ((selector2 & SEL_INPUT) && wiki->paramSize (CharConst ("size"), key, vval, psize, ferr)) {
426     } else if ((selector2 & SEL_ELSIZE) && match (key, CharConst ("size"))) {
427         ustring  v = vval.textOut (wiki);
428         if (match (v, CharConst ("*"))) {
429             elsize = 1;
430         } else if (checkNum (v)) {
431             elsize = to_int32 (v);
432             if (elsize < 0 || elsize > 999) {
433                 elsize = 1;
434             }
435         } else {
436             elsize = 1;
437         }
438     } else if (wiki->paramWidth (key, vval, pwidth, ferr)) {
439     } else if ((selector2 & SEL_TEXTAREA) && wiki->paramSize (CharConst ("cols"), key, vval, pcols, ferr)) {
440     } else if ((selector2 & SEL_TEXTAREA) && wiki->paramSize (CharConst ("rows"), key, vval, prows, ferr)) {
441     } else if ((selector2 & SEL_TEXTAREA) && match (key, CharConst ("wrap"))) {
442         ustring  value (vval.textOut (wiki));
443         if (match (value, CharConst ("off"))) {
444             pwrap = W_OFF;
445         } else if (match (value, CharConst ("soft"))) {
446             pwrap = W_SOFT;
447         } else if (match (value, CharConst ("hard"))) {
448             pwrap = W_HARD;
449         } else if (wiki->paramWidth (key, vval, pwidth, ferr)) {
450         } else {
451             wiki->errorMsg.append (key).append (CharConst ("=")).append (vval.dump ()).append (CharConst (": link script error.\n"));
452             ferr = true;
453             return false;
454         }
455     } else {
456         return false;
457     }
458     return true;
459 }
460
461 bool  WikiAttribInput::readAttribMore2 (const ustring& key, WikiMotorObjVec& cell, bool& ferr) {
462     if (key == uDefault) {
463         pdefault = true;
464     } else if ((selector2 & SEL_CHECK) && match (key, CharConst ("checked"))) {
465         pchecked = true;
466     } else if ((selector2 & SEL_TEXTAREA) && match (key, CharConst ("tab"))) {
467         ftab = true;
468     } else {
469         return false;
470     }
471     return true;
472 }
473
474 void  WikiAttribInput::outputMore (MotorOutput* out) {
475     wiki->outputName (out, CharConst ("size"), psize);
476     wiki->outputName (out, CharConst ("size"), elsize);
477     if (pwidth.size () > 0) {
478         if (checkNum (pwidth)) {
479             out->out_raw (CharConst (" style=\"width:"))->out_toHTML_noCtrl (pwidth)->out_raw (CharConst ("px;\""));
480         } else {
481             out->out_raw (CharConst (" style=\"width:"))->out_toHTML_noCtrl (pwidth)->out_raw (CharConst (";\""));
482         }
483     }
484     if (selector2 & SEL_CHECK) {
485         wiki->outputFlag (out, CharConst ("checked"), pchecked);
486     }
487     if (selector2 & SEL_TEXTAREA) {
488         wiki->outputName (out, CharConst ("cols"), pcols, false);
489         wiki->outputName (out, CharConst ("rows"), prows);
490         switch (pwrap) {
491         case W_OFF:
492             out->out_raw (CharConst (" wrap=\"off\""));
493             break;
494         case W_SOFT:
495             out->out_raw (CharConst (" wrap=\"soft\""));
496             //  out->out_raw (CharConst (" wrap=\"virtual\""));
497             break;
498         case W_HARD:
499             out->out_raw (CharConst (" wrap=\"hard\""));
500             //  out->out_raw (CharConst (" wrap=\"physical\""));
501             break;
502         }
503         if (ftab) {
504             out->out_raw (uSPC)
505                 ->out_raw (CharConst ("onkeypress"))
506                 ->out_raw (CharConst ("=\""))
507                 ->out_toHTML (ustring (CharConst ("return insertTab(event,this);")))
508                 ->out_raw ("\"");
509             out->out_raw (uSPC)
510                 ->out_raw (CharConst ("onkeydown"))
511                 ->out_raw (CharConst ("=\""))
512                 ->out_toHTML (ustring (CharConst ("return insertTab(event,this);")))
513                 ->out_raw ("\"");
514             out->out_raw (uSPC)
515                 ->out_raw (CharConst ("onkeyup"))
516                 ->out_raw (CharConst ("=\""))
517                 ->out_toHTML (ustring (CharConst ("return insertTab(event,this);")))
518                 ->out_raw ("\"");
519         }
520     }
521 }
522
523 /* ============================================================ */
524 bool  WikiAttribButton::readAttrib (WikiMotorObjVecVec::const_iterator& b, const WikiMotorObjVecVec::const_iterator& e) {
525     bool  rc = true;
526
527     if (b < e) {
528         WikiMotorObjVec*  cell = b->get ();
529 //      bool  bf = fwhole;
530 //      fwhole = false;
531         mode_t  bm = mode;
532
533         mode = M_NORMAL;
534         if (! readAttrib1 (cell, rc)) {
535             name = cell->textOut (wiki);
536         }
537 //      fwhole = bf;
538         mode = bm;
539         b ++;
540     }
541     while (b < e) {
542         WikiMotorObjVec*  cell = b->get ();
543         if (! readAttrib1 (cell, rc))
544             return rc;
545         b ++;
546     }
547     return true;
548 }
549
550 /* ============================================================ */