/[pub]/suikawiki/script/misc/plugins/view/stylesheet.wp2
Suika

Contents of /suikawiki/script/misc/plugins/view/stylesheet.wp2

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.10 - (hide annotations) (download)
Tue Mar 15 08:50:05 2005 UTC (19 years, 7 months ago) by wakaba
Branch: MAIN
CVS Tags: suikawiki3-redirect, HEAD
Branch point for: helowiki, helowiki-2005
Changes since 1.9: +4 -1 lines
No JavaScript regex literal for old User Agents

1 wakaba 1.1 #?SuikaWikiConfig/2.0
2    
3     Plugin:
4     @Name: StyleSheet
5     @Description:
6     @@@: Stylesheet support
7     @@lang:en
8 wakaba 1.2 @License: %%Perl%%
9 wakaba 1.1 @Author:
10     @@Name:
11     @@@@: Wakaba
12     @@@lang:ja
13     @@@script:Latn
14     @@Mail[list]: w@suika.fam.cx
15 wakaba 1.2 @Date.RCS:
16 wakaba 1.10 $Date: 2005/03/15 08:50:05 $
17 wakaba 1.1 @RequiredPlugin[list]:
18     Error
19     HTML
20 wakaba 1.5 @RequiredModule[list]:
21     URI
22 wakaba 1.1 @Use:
23 wakaba 1.5 use URI;
24 wakaba 1.1 use Message::Util::Error;
25     my $WIKIRESOURCE;
26 wakaba 1.5 @Namespace:
27     @@ss:
28     http://suika.fam.cx/~wakaba/archive/2004/05/sw-stylesheet#
29     @@media-type:
30     http://suika.fam.cx/~wakaba/-temp/2004/04/24/mt#
31 wakaba 1.6 @@edit:
32     http://suika.fam.cx/~wakaba/-temp/2004/7/25/sw-edit#
33 wakaba 1.1
34     PluginConst:
35     @NS_XHTML1:
36     http://www.w3.org/1999/xhtml
37     @WIKIRESOURCE:
38     {($WIKIRESOURCE ||= SuikaWiki::Plugin->module_package ('WikiResource'))}
39    
40     Format:
41     @ModuleName:
42     StyleSheet::CSS
43    
44     @Name: CSS
45     @Type: text/css
46     @Description:
47     @@@: Cascading Style Sheets (CSS)
48     @@lang: en
49    
50     @Use:
51     use Message::Markup::XML::QName qw(NS_xml_URI);
52    
53     @Converter:
54     @@Type: text/css
55     @@Description:
56     @@@: CSS -> CSS (no convertion)
57     @@lang: en
58     @@ToString:
59     return $$source;
60     ## BUG: Insecure specification MUST be removed
61    
62     @Converter:
63     @@Type: text/html
64     @@IsFragment: 1
65     @@Description:
66     @@@: CSS with some decoration, marked-up in HTML
67     @@lang: en
68     @@Main:
69     my $node = $opt->{-parent}->append_new_node
70     (type => '#element',
71     namespace_uri => $NS_XHTML1,
72     local_name => 'pre');
73     $node->set_attribute (class => 'text-css');
74     $node->set_attribute (space => 'preserve', namespace_uri => NS_xml_URI);
75     $node->append_text ($$source);
76     return $node;
77    
78 wakaba 1.5 @content_written:
79     @@Main:
80     if ($opt{wiki}->{config}->{<Q:ss:use-static>}) {
81     $opt{wiki}->{db}->set (static__css => $opt{page} => ${$opt{new_content}});
82     }
83    
84     @content_removed:
85     @@Main:
86     if ($opt{wiki}->{config}->{<Q:ss:use-static>}) {
87     $opt{wiki}->{db}->delete (static__css => $opt{page});
88     }
89    
90     @content_type_changed_from:
91     @@Main:
92     if ($opt{wiki}->{config}->{<Q:ss:use-static>}) {
93     $opt{wiki}->{db}->delete (static__css => $opt{page});
94     }
95 wakaba 1.6
96     @Prop:
97     @@edit:new-mode--edit: edit
98     @@edit:new-mode--adminedit: adminedit
99 wakaba 1.5
100 wakaba 1.1 ViewDefinition:
101     @Mode: css
102     @Condition:
103     @@http-method[list]:
104     GET
105     HEAD
106     POST
107     @Description:
108     @@@: CSS Style Sheet
109     @@lang: en
110     @template:
111     @@http-status-code: 200
112     @@media-type: text/css
113     @@use-media-type-charset: 1
114     @@expires: %%stylesheet%%
115     @@body:
116     %read (Type => {text/css}, return-type => {ToString},
117     when-no-converter => 406);
118    
119     FormattingRule:
120     @Category[list]:
121     view
122     view-resource
123     @Name: styles-wiki-html
124     @Description:
125     @@@:
126     Stylesheet list as HTML (link element)
127     @@lang: en
128     @Paramater:
129     @@Name: page
130     @@Type: WikiName
131     @@Default: (auto)
132     @@Description:
133     @@@@: WikiPage in which stylesheet list is defined
134     @@@lang: en
135     @Formatting:
136     my $list = __FUNCPACK__->_get_stylelist_definition_page
137     (page => $o->{wiki}->name
138     ($p->{page} ||
139     $o->{wiki}->{config}->{page}
140     ->{'StyleSheetList(text/html)'} ||
141     [qw!Wiki Style List text/html!]),
142     o => $o, wiki => $o->{wiki});
143     return unless $list;
144     my $parent = $p->{-parent};
145    
146     my $ua_apply;
147     my $dg = $o->{wiki}->{var}->{client}->{downgrade};
148     if ($dg->{stylesheet_non_standard}) {
149     $ua_apply = $dg->{ua_netscape4} ? 'Netscape4'
150     : $dg->{ua_winie60} ? 'WinIE6.0'
151     : $dg->{ua_winie55} ? 'WinIE5.5'
152     : $dg->{ua_winie50} ? 'WinIE5.0'
153     : $dg->{ua_winie40} ? 'WinIE4.0'
154     : $dg->{ua_winie30} ? 'WinIE3.0'
155     : 1;
156     }
157 wakaba 1.5
158     my $mkuri = $o->{wiki}->{config}->{<Q:ss:wikiname-to-uri>} ||
159     \ \&__FUNCPACK__::generate_uri;
160 wakaba 1.1
161     for my $set (@{$list->child_nodes}) {
162     if ($set->local_name eq 'StyleSet') {
163 wakaba 1.8 my $apply = $set->get_attribute_value ('Apply',
164 wakaba 1.9 default => ['alternate'],
165     as_array => 1);
166 wakaba 1.1 my $type = {
167 wakaba 1.8 map {$_ => 1}
168 wakaba 1.9 \ @$apply
169 wakaba 1.1 };
170     next if $ua_apply and not $type->{$ua_apply};
171     my $rel = $type->{alternate} ? 'alternate stylesheet' : 'stylesheet';
172     my $title = __FUNCPACK__->_get_styleset_title
173     (StyleSet => $set, o => $o,
174     type => $type);
175     for my $sheet (@{$set->child_nodes}) {
176     if ($sheet->local_name eq 'StyleSheet') {
177 wakaba 1.8 my $stype = {
178     map {$_ => 1}
179 wakaba 1.9 \ @{$sheet->get_attribute_value ('Apply', default => $apply,
180     as_array => 1)}
181 wakaba 1.8 };
182     next if $ua_apply and not $stype->{$ua_apply};
183     next if not $ua_apply and (not $stype->{alternate} and
184     not $stype->{preferred} and
185     not $stype->{persistent});
186 wakaba 1.1 my $link = $parent->append_new_node
187     (type => '#element',
188     namespace_uri => $NS_XHTML1,
189     local_name => 'link');
190     $link->option (use_EmptyElemTag => 1);
191     $link->set_attribute (rel => $rel);
192     $link->set_attribute (title => $title) unless $type->{persistent};
193     my $media_type = $sheet->get_attribute_value
194     ('Type', default => 'text/css');
195     ## TODO: parameter
196     $link->set_attribute (type => $media_type);
197     unless ($dg->{html_link_no_media}) {
198     my $media_descriptor = $sheet->get_attribute_value ('Media');
199     $link->set_attribute (media => $media_descriptor || 'all');
200     }
201 wakaba 1.5 my $uri = $mkuri->(undef, o => $o, wiki => $o->{wiki},
202     wikiname => $o->{wiki}->name
203     ($sheet->get_attribute_value
204 wakaba 1.1 ('WikiPage', default => '')),
205 wakaba 1.5 mode => 'css'); ## ISSUE: Make this media-type independent!
206     $link->set_attribute (href => $uri);
207 wakaba 1.1 $parent->append_text ("\n");
208     }
209     }
210    
211     }
212     }
213    
214     FormattingRule:
215     @Category[list]:
216     view
217     view-resource
218     @Name: styles-wiki-xml
219     @Description:
220     @@@:
221     Stylesheet list in xml-stylesheet processing instructions
222     @@lang: en
223     @Parameter:
224     @@Name: downgrade-html
225     @@Type: boolean
226     @@Default: "0"
227     @@Description:
228     @@@@:
229     HTML downgrade mode. PIs are not outputed if User-Agent does not
230     support PIs (eg. Classic Mozilla).
231     @@lang: en
232     @Paramater:
233     @@Name: page
234     @@Type: WikiName
235     @@Default: (auto)
236     @@Description:
237     @@@@: WikiPage in which stylesheet list is defined
238     @@@lang: en
239     @Formatting:
240     __ATTRTEXT:%downgrade_html__;
241     if ($p->{downgrade_html}) {
242     return if $o->{wiki}->{var}->{client}->{downgrade}->{html_no_pi};
243     }
244     my $list = __FUNCPACK__->_get_stylelist_definition_page
245     (page => $o->{wiki}->name
246     ($p->{page} ||
247     $o->{wiki}->{config}->{page}
248     ->{'StyleSheetList(text/html)'} ||
249     [qw!Wiki Style List text/html!]),
250     o => $o, wiki => $o->{wiki});
251     return unless $list;
252     my $parent = $p->{-parent};
253    
254 wakaba 1.5 my $mkuri = $o->{wiki}->{config}->{<Q:ss:wikiname-to-uri>} ||
255     \ \&__FUNCPACK__::generate_uri;
256    
257 wakaba 1.1 for my $set (@{$list->child_nodes}) {
258     if ($set->local_name eq 'StyleSet') {
259 wakaba 1.9 my $apply = $set->get_attribute_value
260     ('Apply', default => ['alternate'],
261     as_array => 1);
262     my $type = {map {$_ => 1} @$apply};
263 wakaba 1.1 my $rel = $type->{alternate} ? 'alternate stylesheet' : 'stylesheet';
264     my $title = __FUNCPACK__->_get_styleset_title
265     (StyleSet => $set, o => $o,
266     type => $type);
267     for my $sheet (@{$set->child_nodes}) {
268     if ($sheet->local_name eq 'StyleSheet') {
269 wakaba 1.9 my $stype = {
270     map {$_ => 1}
271     \ @{$sheet->get_attribute_value ('Apply', default => $apply,
272     as_array => 1)}
273     };
274     next if (not $stype->{alternate} and
275     not $stype->{preferred} and
276     not $stype->{persistent});
277 wakaba 1.1 my $link = $parent->append_new_node
278     (type => '#pi',
279     local_name => 'xml-stylesheet');
280     $link->set_attribute (alternate => $type->{preferred} ? 'no'
281     : 'yes')
282     unless $type->{persistent};
283     $link->set_attribute (title => $title) unless $type->{persistent};
284     my $media_type = $sheet->get_attribute_value
285     ('Type', default => 'text/css');
286     ## TODO: parameter
287     $link->set_attribute (type => $media_type);
288     unless ($o->{wiki}->{var}->{client}->{downgrade}
289     ->{html_link_no_media}) {
290     my $media_descriptor = $sheet->get_attribute_value ('Media');
291     $link->set_attribute (media => $media_descriptor || 'all');
292     }
293 wakaba 1.5 my $uri = $mkuri->(undef, o => $o, wiki => $o->{wiki},
294     wikiname => $o->{wiki}->name
295     ($sheet->get_attribute_value
296 wakaba 1.1 ('WikiPage', default => '')),
297 wakaba 1.7 lm => time, ## TODO: Should be last-modified
298 wakaba 1.5 mode => 'css'); ## ISSUE: Make this media-type independent!
299     $link->set_attribute (href => $uri);
300 wakaba 1.1 $parent->append_text ("\n");
301     }
302     }
303     }
304     }
305 wakaba 1.5
306     Function:
307     @Name: generate_uri
308     @Description:
309     @@@: Default generator for stylesheet URI
310     @@lang: en
311     @Main:
312     my (undef, %opt) = @_;
313     return $opt{wiki}->uri_reference
314     (page => $opt{wikiname},
315     mode => $opt{mode},
316     with_lm => 1, base => 1);
317    
318     ViewDefinition:
319     @Mode: ss--no-static
320     @Condition:
321     @@http-method[list]:
322     GET
323     HEAD
324     POST
325     @Description:
326     @@@: Generate static version
327     @@lang: en
328     @method:
329     @@Name: main
330     @@@:
331     require SuikaWiki::Output::HTTP;
332     my $wiki = $self->{view}->{wiki};
333     $wiki->init_db;
334    
335     GENSTATIC: {
336     last GENSTATIC unless ref $wiki->{config}->{<Q:ss:uri-to-wikiname>} and
337     $wiki->{config}->{<Q:ss:use-static>} and
338     $wiki->{db} and $wiki->{input};
339     my $uri = $wiki->{input}->meta_variable ('REDIRECT_URL');
340     last GENSTATIC unless $uri;
341     my $wn = $wiki->{config}->{<Q:ss:uri-to-wikiname>}
342     ->(undef, wiki => $wiki,
343     uri => URI->new ($uri));
344    
345     my $prop = $wiki->{db}->get (content_prop => $wn);
346     my $mt = $prop->get_attribute_value (<Q:media-type:media-type>,
347     default => '--');
348     last GENSTATIC unless $mt eq 'IMT:text/css##';
349    
350     $wiki->{db}->set (static__css => $wn =>
351     $wiki->{db}->get (content => $wn));
352    
353     $uri = $wiki->{config}->{<Q:ss:wikiname-to-uri>}
354     ->(undef, wiki => $wiki,
355     wikiname => $wn);
356     $uri = $uri->abs ($wiki->uri_reference);
357     $uri->query (time);
358    
359     my $output = new SuikaWiki::Output::HTTP (wiki => $wiki);
360     $output->set_redirect (uri => $uri, status_code => 303,
361     status_phrase => 'Created');
362     $output->output (output => 'http-cgi');
363    
364     return;
365     }
366     my $output = new SuikaWiki::Output::HTTP (wiki => $wiki);
367     $output->{status_code} = 404;
368     $output->{entity}->{media_type} = 'text/plain';
369     $output->{entity}->{body} = '404';
370     $output->output (output => 'http-cgi');
371 wakaba 1.1
372     FormattingRule:
373     @Category[list]:
374     view
375     view-resource
376     form-input
377     @Name: select-user-preferred-style
378     @Description:
379     @@@:
380     Select user preferred style
381     @@lang: en
382     @Paramater:
383     @@Name: page
384     @@Type: WikiName
385     @@Default: (auto)
386     @@Description:
387     @@@@: WikiPage in which stylesheet list is defined
388     @@@lang: en
389     @Formatting:
390     __ATTRTEXT:%page__;
391     my $list = __FUNCPACK__->_get_stylelist_definition_page
392     (page => $o->{wiki}->name
393     ($p->{page} ||
394     $o->{wiki}->{config}->{page}
395     ->{'StyleSheetList(text/html)'} ||
396     [qw!Wiki Style List text/html!]),
397     o => $o, wiki => $o->{wiki});
398     return unless $list;
399     my $form = $p->{-parent}->append_new_node
400     (type => '#element',
401     namespace_uri => $NS_XHTML1,
402     local_name => 'form');
403     my $id = SuikaWiki::Plugin->module_package ('WikiFormCore')
404     ->control_id ($o,
405     local_id => 'style-selector',
406     require_local_id => 1);
407     $form->set_attribute (id => $id->{global_id});
408     my $div = $form->append_new_node
409     (type => '#element',
410     namespace_uri => $NS_XHTML1,
411     local_name => 'div');
412     my $parent = $div->append_new_node
413     (type => '#element',
414     namespace_uri => $NS_XHTML1,
415     local_name => 'select');
416     $parent->set_attribute (id => $id->{global_id}.'-list');
417    
418     my $default = $parent->append_new_node
419     (type => '#element',
420     namespace_uri => $NS_XHTML1,
421     local_name => 'option');
422     $default->set_attribute (value => 'no-style');
423     $default->append_text ($WIKIRESOURCE->get (name => 'Style:Default',
424     o => $o, wiki => $o->{wiki}));
425     my $selected = 0;
426    
427     for my $set (@{$list->child_nodes}) {
428     if ($set->local_name eq 'StyleSet') {
429     my $type = {map {$_ => 1}
430     @{
431     $set->get_attribute_value ('Apply', default => ['alternate'])
432     }};
433     next unless $type->{preferred} or $type->{alternate};
434     my $title = __FUNCPACK__->_get_styleset_title
435     (StyleSet => $set, o => $o,
436     type => $type);
437     my $link = $parent->append_new_node
438     (type => '#element',
439     namespace_uri => $NS_XHTML1,
440     local_name => 'option');
441     $link->set_attribute (selected => 'selected'), $selected = 1
442     if $type->{preferred};
443     $link->set_attribute (value => $title);
444     $link->append_text ($title);
445     $parent->append_text ("\n");
446     }
447     }
448    
449     $default->set_attribute (selected => 'selected') unless $selected;
450    
451     for ($div->append_new_node (type => '#element',
452     namespace_uri => $NS_XHTML1,
453     local_name => 'input')) {
454     $_->set_attribute (type => 'button');
455     $_->set_attribute (id => $id->{global_id}.'-save');
456     $_->set_attribute (value => $WIKIRESOURCE->get
457     (name => 'Style:Save',
458     o => $o, wiki => $o->{wiki}));
459     $_->set_attribute (class => 'save');
460     $_->option (use_EmptyElemTag => 1);
461     }
462     for ($div->append_new_node (type => '#element',
463     namespace_uri => $NS_XHTML1,
464     local_name => 'input')) {
465     $_->set_attribute (type => 'reset');
466     $_->set_attribute (id => $id->{global_id}.'-reset');
467     $_->set_attribute (value => $WIKIRESOURCE->get
468     (name => 'Style:Reset',
469     o => $o, wiki => $o->{wiki}));
470     $_->set_attribute (class => 'reset');
471     $_->option (use_EmptyElemTag => 1);
472     }
473    
474 wakaba 1.10 return if $o->{wiki}->{var}->{client}->{downgrade}->{js_no_regex};
475 wakaba 1.1 __ATTRTEXT:%expires__;
476 wakaba 1.2 my $cookie_path = $o->{wiki}->uri_reference->path;
477 wakaba 1.1 for ($div->append_new_node (type => '#element',
478     namespace_uri => $NS_XHTML1,
479     local_name => 'script')) {
480     $_->set_attribute (type => $o->{wiki}->{var}->{client}->{downgrade}
481     ->{media_type_no_app_js}
482     ? 'text/javascript'
483     : 'application/x-javascript');
484     $_->set_attribute (defer => 'defer');
485     ## Gecko assumes <script> content as CDATA even if it is XHTML,
486     ## when it is labeled as text/html. (Pseudo) comment declaration
487     ## nor CDATA marked section can be used to keep compatibility and
488     ## well-formedness. Use #xml type, instead of #text, not to escape
489     ## GREATER-THAN SIGN.
490     $_->append_new_node (type => '#xml', value => <<EOH);
491    
492     function getCookieValue (name) {
493     var c = document.cookie.split(';');
494     for (var i = 0; c.length > i; i++) {
495     var v = c[i].split('=');
496     if (v[0].replace(/^\\s+/,'').replace(/\\s+\$/,'') == name) {
497     return decodeURIComponent (v[1].replace(/^\\s+/,'')
498     .replace(/\\s+\$/,''));
499     }
500     }
501     return '';
502     }
503     var selectList = document.getElementById('$id->{global_id}-list');
504     selectList.value = getCookieValue('Selected');
505     selectList.onchange = function () {
506     var selectList = document.getElementById('$id->{global_id}-list');
507     for (var i = 0; document.styleSheets.length > i; i++) {
508     var s = document.styleSheets.item(i);
509     if (s.href != document.URL) {
510     if (s.title)
511     s.disabled = (s.title != selectList.value);
512     }
513     }
514     }
515     document.getElementById('$id->{global_id}-save').onclick = function () {
516     var selectList = document.getElementById('$id->{global_id}-list');
517     var expires = new Date();
518     expires.setTime (expires.getTime()
519     + 1000*3600*24*@{[$p->{expires}||365]});
520     document.cookie = 'Selected=' + encodeURIComponent(selectList.value)
521     + ';path=$cookie_path;expires='+expires.toGMTString();
522     }
523     document.getElementById('$id->{global_id}-reset').onclick = function () {
524     var expires = new Date();
525     expires.setTime (expires.getTime() - 3600);
526     document.cookie = 'Selected=;path=$cookie_path;expires='
527     + expires.toGMTString();
528     }
529    
530     EOH
531     }
532    
533     FormattingRule:
534     @Category[list]:
535     view
536     view-resource
537     form-input
538     @Name: apply-user-preferred-style
539     @Description:
540     @@@:
541     Applying user preferred style
542     @@lang: en
543     @Formatting:
544 wakaba 1.10 return if $o->{wiki}->{var}->{client}->{downgrade}->{js_no_regex};
545 wakaba 1.1 for ($p->{-parent}->append_new_node
546     (type => '#element',
547     namespace_uri => $NS_XHTML1,
548     local_name => 'script')) {
549     $_->set_attribute (type => $o->{wiki}->{var}->{client}->{downgrade}
550     ->{media_type_no_app_js}
551     ? 'text/javascript'
552     : 'application/x-javascript');
553     $_->set_attribute (defer => 'defer');
554     ## TODO: Some mechanism to prevent multiple outputing of same functions
555     ## required.
556     $_->append_new_node (type => '#xml', value => <<EOH);
557    
558     function getCookieValue (name) {
559     var c = document.cookie.split(';');
560     for (var i = 0; c.length > i; i++) {
561     var v = c[i].split('=');
562     if (v[0].replace(/^\\s+/,'').replace(/\\s+\$/,'') == name) {
563     return decodeURIComponent (v[1].replace(/^\\s+/,'')
564     .replace(/\\s+\$/,''));
565     }
566     }
567     return '';
568     }
569    
570     var styleName = getCookieValue('Selected');
571     if (styleName) {
572     for (var i = 0; document.styleSheets.length > i; i++) {
573     var s = document.styleSheets.item(i);
574     if (s.href != document.URL) {
575     if (s.title)
576     s.disabled = (s.title != styleName) ? true : false;
577     }
578     }
579     }
580    
581     EOH
582     }
583    
584     Function:
585     @Name: _get_stylelist_definition_page
586     @Main:
587     my (undef, %opt) = @_;
588     my $content;
589 wakaba 1.4 my $content_prop;
590 wakaba 1.1 if ($opt{wiki}->{db}) {
591     try {
592     $content = $opt{wiki}->{db}->get (content => $opt{page});
593 wakaba 1.4 $content_prop = $opt{wiki}->{db}->get (content_prop => $opt{page});
594 wakaba 1.1 } catch SuikaWiki::DB::Util::Error with {
595 wakaba 1.3 my $err = shift;
596     $err->throw if $err->{-type} eq 'ERROR_REPORTED';
597 wakaba 1.1 $content = undef;
598     };
599     }
600     my $format = SuikaWiki::Plugin->module_package ('WikiFormat')
601     ->handler (\$content,
602 wakaba 1.4 content_prop => $content_prop,
603 wakaba 1.1 o => $opt{o},
604     wiki => $opt{o}->{wiki});
605     my $cfg;
606     try {
607     $cfg = $format->convert (\$content,
608     Type => 'application/x.suikawiki.config',
609     Type_param => {version => '2.0'},
610     o => $opt{o}, page => $opt{page});
611     } catch SuikaWiki::Format::Definition::error with {
612     my $err = shift;
613     if ($err->{-type} eq 'CONVERTER_NOT_FOUND') {
614     SuikaWiki::Plugin->module_package ('Error')
615     ->report_error_simple
616     ($opt{o}->{wiki},
617     'Condition' => $err->stringify);
618     } else {
619     $err->throw;
620     }
621     };
622     $cfg;
623    
624     Function:
625     @Name: _get_styleset_title
626     @Description:
627     @@@: Get "title" of the styleset
628     @@lang: en
629     @Main:
630     my (undef, %opt) = @_;
631     my $title;
632     if (not $opt{type}->{persistent}) {
633     $title = $opt{StyleSet}->get_attribute_value
634     ('DisplayName', default => '');
635     if (length $title) {
636     try {
637     $title = SuikaWiki::Plugin->formatter ('view_resource')
638     ->replace ($title,
639     param => $opt{o})
640     ->inner_text;
641     } catch Message::Util::Formatter::error with {
642     my $err = shift;
643     if ($err->{-object}->{-category_name} eq 'view_resource') {
644     my $wiki = $err->{option}->{param}->{wiki};
645     SuikaWiki::Plugin->module_package ('Error')
646     ->reporting_formatting_template_error
647     ($err, $wiki,
648     template => $title);
649     } else {
650     $err->throw;
651     }
652     $title ||= $opt{StyleSet}->get_attribute_value
653     ('Name', default => '');
654     };
655     } else {
656     $title = $opt{StyleSet}->get_attribute_value ('Name', default => '');
657     }
658     }
659     return $title;
660    
661     FormattingRule:
662     @Category[list]:
663     view
664     view-resource
665     form-input
666     @Name: select-user-preferred-mode
667     @Description:
668     @@@:
669     Select user preferred mode
670     @@lang: en
671     @Formatting:
672     my $list = [grep /^[0-9A-Za-z_]/, keys %{$o->{wiki}->{view}->{definition}}];
673     my $form = $p->{-parent}->append_new_node
674     (type => '#element',
675     namespace_uri => $NS_XHTML1,
676     local_name => 'form');
677     my $id = SuikaWiki::Plugin->module_package ('WikiFormCore')
678     ->control_id ($o,
679     local_id => 'spss--mode-selector',
680     require_local_id => 1);
681     $form->set_attribute (id => $id->{global_id});
682     my $div = $form->append_new_node
683     (type => '#element',
684     namespace_uri => $NS_XHTML1,
685     local_name => 'div');
686     my $parent = $div->append_new_node
687     (type => '#element',
688     namespace_uri => $NS_XHTML1,
689     local_name => 'select');
690     $parent->set_attribute (id => $id->{global_id}.'-list');
691    
692     my $default = $parent->append_new_node
693     (type => '#element',
694     namespace_uri => $NS_XHTML1,
695     local_name => 'option');
696     $default->set_attribute (value => 'default');
697     $default->append_text ($WIKIRESOURCE->get (name => 'Mode:Default',
698     o => $o, wiki => $o->{wiki}));
699     $default->set_attribute (selected => 'selected');
700    
701     for my $set (@$list) {
702     my $title = $WIKIRESOURCE->get (name => 'Mode:'.$set,
703     o => $o, wiki => $o->{wiki});
704     my $link = $parent->append_new_node
705     (type => '#element',
706     namespace_uri => $NS_XHTML1,
707     local_name => 'option');
708     $link->set_attribute (value => $set);
709     $link->append_text ($title);
710     $parent->append_text ("\n");
711     }
712    
713     for ($div->append_new_node (type => '#element',
714     namespace_uri => $NS_XHTML1,
715     local_name => 'input')) {
716     $_->set_attribute (type => 'button');
717     $_->set_attribute (id => $id->{global_id}.'-save');
718     $_->set_attribute (value => $WIKIRESOURCE->get
719     (name => 'Mode:Save',
720     o => $o, wiki => $o->{wiki}));
721     $_->set_attribute (class => 'save');
722     $_->option (use_EmptyElemTag => 1);
723     }
724     for ($div->append_new_node (type => '#element',
725     namespace_uri => $NS_XHTML1,
726     local_name => 'input')) {
727     $_->set_attribute (type => 'reset');
728     $_->set_attribute (id => $id->{global_id}.'-reset');
729     $_->set_attribute (value => $WIKIRESOURCE->get
730     (name => 'Mode:Reset',
731     o => $o, wiki => $o->{wiki}));
732     $_->set_attribute (class => 'reset');
733     $_->option (use_EmptyElemTag => 1);
734     }
735    
736 wakaba 1.10 return if $o->{wiki}->{var}->{client}->{downgrade}->{js_no_regex};
737 wakaba 1.1 __ATTRTEXT:%expires__;
738 wakaba 1.2 my $cookie_path = $o->{wiki}->uri_reference->path;
739 wakaba 1.1 for ($div->append_new_node (type => '#element',
740     namespace_uri => $NS_XHTML1,
741     local_name => 'script')) {
742     $_->set_attribute (type => $o->{wiki}->{var}->{client}->{downgrade}
743     ->{media_type_no_app_js}
744     ? 'text/javascript'
745     : 'application/x-javascript');
746     $_->set_attribute (defer => 'defer');
747     $_->append_new_node (type => '#xml', value => <<EOH);
748    
749     function getCookieValue (name) {
750     var c = document.cookie.split(';');
751     for (var i = 0; c.length > i; i++) {
752     var v = c[i].split('=');
753     if (v[0].replace(/^\\s+/,'').replace(/\\s+\$/,'') == name) {
754     return decodeURIComponent (v[1].replace(/^\\s+/,'')
755     .replace(/\\s+\$/,''));
756     }
757     }
758     return '';
759     }
760    
761     document.getElementById ('$id->{global_id}-list').value
762     = getCookieValue('SelectedMode');
763     document.getElementById ('$id->{global_id}-save').onclick = function () {
764     var expires = new Date ();
765     expires.setTime (expires.getTime ()
766     + 1000*3600*24*@{[$p->{expires}||365]});
767     document.cookie = 'SelectedMode='
768     + encodeURIComponent
769     (document.getElementById('$id->{global_id}-list')
770     .value)
771     + ';path=$cookie_path;expires='
772     + expires.toGMTString ();
773     }
774     document.getElementById('$id->{global_id}-reset').onclick = function () {
775     var expires = new Date();
776     expires.setTime (expires.getTime() - 3600);
777     document.cookie = 'SelectedMode=;path=$cookie_path;expires='
778     + expires.toGMTString();
779     }
780    
781     EOH
782     }
783    
784     ViewFragment:
785     @Name: ht--stylesheets-html
786     @Order: 0
787     @Description:
788     @@@: Default stylesheets links
789     @@lang: en
790     @Formatting:
791     %styles-wiki-html;
792    
793     ViewFragment:
794     @Name: ht--pre-element-content
795     @Order: 0
796     @Description:
797     @@@: Default stylesheets links (as xml-stylesheet PIs)
798     @@lang: en
799     @Formatting:
800     %styles-wiki-xml (downgrade-html);
801    
802     ViewFragment:
803     @Name: ws--footer
804     @Order: 100000
805     @Description:
806     @@@: Apply user selected stylesheets
807     @@lang: en
808     @Formatting:
809     %apply-user-preferred-style;
810    
811     Resource:
812     @Mode:css:
813     @@@: Cascading Style Sheet output
814     @@lang: en
815     @Mode:Default:
816     @@@:
817     Default
818     @@lang: en
819     @Mode:Reset:
820     @@@: Reset default mode selection
821     @@lang: en
822     @Mode:Save:
823     @@@: Save default mode selection
824     @@lang: en
825     @Style:Default:
826     @@@:
827     Basic Page Style
828     @@: lang: en
829     @Style:Reset:
830     @@@:
831     Reset style selection
832     @@lang: en
833     @Style:Save:
834     @@@:
835     Save style selection
836 wakaba 1.4 @@lang: en
837     @WikiFormat:MediaType:Description:IMT:text/css##:
838     @@@: CSS (Cascading Style Sheets)
839     @@lang: en
840     @WikiFormat:MediaType:Label:IMT:text/css##:
841     @@@: CSS
842 wakaba 1.1 @@lang: en
843    
844    

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24