#?SuikaWikiConfig/2.0 Plugin: @Name: StyleSheet @Description: @@@: Stylesheet support @@lang:en @License: %%Perl%% @Author: @@Name: @@@@: Wakaba @@@lang:ja @@@script:Latn @@Mail[list]: w@suika.fam.cx @Date.RCS: $Date: 2005/03/15 08:50:05 $ @RequiredPlugin[list]: Error HTML @RequiredModule[list]: URI @Use: use URI; use Message::Util::Error; my $WIKIRESOURCE; @Namespace: @@ss: http://suika.fam.cx/~wakaba/archive/2004/05/sw-stylesheet# @@media-type: http://suika.fam.cx/~wakaba/-temp/2004/04/24/mt# @@edit: http://suika.fam.cx/~wakaba/-temp/2004/7/25/sw-edit# PluginConst: @NS_XHTML1: http://www.w3.org/1999/xhtml @WIKIRESOURCE: {($WIKIRESOURCE ||= SuikaWiki::Plugin->module_package ('WikiResource'))} Format: @ModuleName: StyleSheet::CSS @Name: CSS @Type: text/css @Description: @@@: Cascading Style Sheets (CSS) @@lang: en @Use: use Message::Markup::XML::QName qw(NS_xml_URI); @Converter: @@Type: text/css @@Description: @@@: CSS -> CSS (no convertion) @@lang: en @@ToString: return $$source; ## BUG: Insecure specification MUST be removed @Converter: @@Type: text/html @@IsFragment: 1 @@Description: @@@: CSS with some decoration, marked-up in HTML @@lang: en @@Main: my $node = $opt->{-parent}->append_new_node (type => '#element', namespace_uri => $NS_XHTML1, local_name => 'pre'); $node->set_attribute (class => 'text-css'); $node->set_attribute (space => 'preserve', namespace_uri => NS_xml_URI); $node->append_text ($$source); return $node; @content_written: @@Main: if ($opt{wiki}->{config}->{}) { $opt{wiki}->{db}->set (static__css => $opt{page} => ${$opt{new_content}}); } @content_removed: @@Main: if ($opt{wiki}->{config}->{}) { $opt{wiki}->{db}->delete (static__css => $opt{page}); } @content_type_changed_from: @@Main: if ($opt{wiki}->{config}->{}) { $opt{wiki}->{db}->delete (static__css => $opt{page}); } @Prop: @@edit:new-mode--edit: edit @@edit:new-mode--adminedit: adminedit ViewDefinition: @Mode: css @Condition: @@http-method[list]: GET HEAD POST @Description: @@@: CSS Style Sheet @@lang: en @template: @@http-status-code: 200 @@media-type: text/css @@use-media-type-charset: 1 @@expires: %%stylesheet%% @@body: %read (Type => {text/css}, return-type => {ToString}, when-no-converter => 406); FormattingRule: @Category[list]: view view-resource @Name: styles-wiki-html @Description: @@@: Stylesheet list as HTML (link element) @@lang: en @Paramater: @@Name: page @@Type: WikiName @@Default: (auto) @@Description: @@@@: WikiPage in which stylesheet list is defined @@@lang: en @Formatting: my $list = __FUNCPACK__->_get_stylelist_definition_page (page => $o->{wiki}->name ($p->{page} || $o->{wiki}->{config}->{page} ->{'StyleSheetList(text/html)'} || [qw!Wiki Style List text/html!]), o => $o, wiki => $o->{wiki}); return unless $list; my $parent = $p->{-parent}; my $ua_apply; my $dg = $o->{wiki}->{var}->{client}->{downgrade}; if ($dg->{stylesheet_non_standard}) { $ua_apply = $dg->{ua_netscape4} ? 'Netscape4' : $dg->{ua_winie60} ? 'WinIE6.0' : $dg->{ua_winie55} ? 'WinIE5.5' : $dg->{ua_winie50} ? 'WinIE5.0' : $dg->{ua_winie40} ? 'WinIE4.0' : $dg->{ua_winie30} ? 'WinIE3.0' : 1; } my $mkuri = $o->{wiki}->{config}->{} || \ \&__FUNCPACK__::generate_uri; for my $set (@{$list->child_nodes}) { if ($set->local_name eq 'StyleSet') { my $apply = $set->get_attribute_value ('Apply', default => ['alternate'], as_array => 1); my $type = { map {$_ => 1} \ @$apply }; next if $ua_apply and not $type->{$ua_apply}; my $rel = $type->{alternate} ? 'alternate stylesheet' : 'stylesheet'; my $title = __FUNCPACK__->_get_styleset_title (StyleSet => $set, o => $o, type => $type); for my $sheet (@{$set->child_nodes}) { if ($sheet->local_name eq 'StyleSheet') { my $stype = { map {$_ => 1} \ @{$sheet->get_attribute_value ('Apply', default => $apply, as_array => 1)} }; next if $ua_apply and not $stype->{$ua_apply}; next if not $ua_apply and (not $stype->{alternate} and not $stype->{preferred} and not $stype->{persistent}); my $link = $parent->append_new_node (type => '#element', namespace_uri => $NS_XHTML1, local_name => 'link'); $link->option (use_EmptyElemTag => 1); $link->set_attribute (rel => $rel); $link->set_attribute (title => $title) unless $type->{persistent}; my $media_type = $sheet->get_attribute_value ('Type', default => 'text/css'); ## TODO: parameter $link->set_attribute (type => $media_type); unless ($dg->{html_link_no_media}) { my $media_descriptor = $sheet->get_attribute_value ('Media'); $link->set_attribute (media => $media_descriptor || 'all'); } my $uri = $mkuri->(undef, o => $o, wiki => $o->{wiki}, wikiname => $o->{wiki}->name ($sheet->get_attribute_value ('WikiPage', default => '')), mode => 'css'); ## ISSUE: Make this media-type independent! $link->set_attribute (href => $uri); $parent->append_text ("\n"); } } } } FormattingRule: @Category[list]: view view-resource @Name: styles-wiki-xml @Description: @@@: Stylesheet list in xml-stylesheet processing instructions @@lang: en @Parameter: @@Name: downgrade-html @@Type: boolean @@Default: "0" @@Description: @@@@: HTML downgrade mode. PIs are not outputed if User-Agent does not support PIs (eg. Classic Mozilla). @@lang: en @Paramater: @@Name: page @@Type: WikiName @@Default: (auto) @@Description: @@@@: WikiPage in which stylesheet list is defined @@@lang: en @Formatting: __ATTRTEXT:%downgrade_html__; if ($p->{downgrade_html}) { return if $o->{wiki}->{var}->{client}->{downgrade}->{html_no_pi}; } my $list = __FUNCPACK__->_get_stylelist_definition_page (page => $o->{wiki}->name ($p->{page} || $o->{wiki}->{config}->{page} ->{'StyleSheetList(text/html)'} || [qw!Wiki Style List text/html!]), o => $o, wiki => $o->{wiki}); return unless $list; my $parent = $p->{-parent}; my $mkuri = $o->{wiki}->{config}->{} || \ \&__FUNCPACK__::generate_uri; for my $set (@{$list->child_nodes}) { if ($set->local_name eq 'StyleSet') { my $apply = $set->get_attribute_value ('Apply', default => ['alternate'], as_array => 1); my $type = {map {$_ => 1} @$apply}; my $rel = $type->{alternate} ? 'alternate stylesheet' : 'stylesheet'; my $title = __FUNCPACK__->_get_styleset_title (StyleSet => $set, o => $o, type => $type); for my $sheet (@{$set->child_nodes}) { if ($sheet->local_name eq 'StyleSheet') { my $stype = { map {$_ => 1} \ @{$sheet->get_attribute_value ('Apply', default => $apply, as_array => 1)} }; next if (not $stype->{alternate} and not $stype->{preferred} and not $stype->{persistent}); my $link = $parent->append_new_node (type => '#pi', local_name => 'xml-stylesheet'); $link->set_attribute (alternate => $type->{preferred} ? 'no' : 'yes') unless $type->{persistent}; $link->set_attribute (title => $title) unless $type->{persistent}; my $media_type = $sheet->get_attribute_value ('Type', default => 'text/css'); ## TODO: parameter $link->set_attribute (type => $media_type); unless ($o->{wiki}->{var}->{client}->{downgrade} ->{html_link_no_media}) { my $media_descriptor = $sheet->get_attribute_value ('Media'); $link->set_attribute (media => $media_descriptor || 'all'); } my $uri = $mkuri->(undef, o => $o, wiki => $o->{wiki}, wikiname => $o->{wiki}->name ($sheet->get_attribute_value ('WikiPage', default => '')), lm => time, ## TODO: Should be last-modified mode => 'css'); ## ISSUE: Make this media-type independent! $link->set_attribute (href => $uri); $parent->append_text ("\n"); } } } } Function: @Name: generate_uri @Description: @@@: Default generator for stylesheet URI @@lang: en @Main: my (undef, %opt) = @_; return $opt{wiki}->uri_reference (page => $opt{wikiname}, mode => $opt{mode}, with_lm => 1, base => 1); ViewDefinition: @Mode: ss--no-static @Condition: @@http-method[list]: GET HEAD POST @Description: @@@: Generate static version @@lang: en @method: @@Name: main @@@: require SuikaWiki::Output::HTTP; my $wiki = $self->{view}->{wiki}; $wiki->init_db; GENSTATIC: { last GENSTATIC unless ref $wiki->{config}->{} and $wiki->{config}->{} and $wiki->{db} and $wiki->{input}; my $uri = $wiki->{input}->meta_variable ('REDIRECT_URL'); last GENSTATIC unless $uri; my $wn = $wiki->{config}->{} ->(undef, wiki => $wiki, uri => URI->new ($uri)); my $prop = $wiki->{db}->get (content_prop => $wn); my $mt = $prop->get_attribute_value (, default => '--'); last GENSTATIC unless $mt eq 'IMT:text/css##'; $wiki->{db}->set (static__css => $wn => $wiki->{db}->get (content => $wn)); $uri = $wiki->{config}->{} ->(undef, wiki => $wiki, wikiname => $wn); $uri = $uri->abs ($wiki->uri_reference); $uri->query (time); my $output = new SuikaWiki::Output::HTTP (wiki => $wiki); $output->set_redirect (uri => $uri, status_code => 303, status_phrase => 'Created'); $output->output (output => 'http-cgi'); return; } my $output = new SuikaWiki::Output::HTTP (wiki => $wiki); $output->{status_code} = 404; $output->{entity}->{media_type} = 'text/plain'; $output->{entity}->{body} = '404'; $output->output (output => 'http-cgi'); FormattingRule: @Category[list]: view view-resource form-input @Name: select-user-preferred-style @Description: @@@: Select user preferred style @@lang: en @Paramater: @@Name: page @@Type: WikiName @@Default: (auto) @@Description: @@@@: WikiPage in which stylesheet list is defined @@@lang: en @Formatting: __ATTRTEXT:%page__; my $list = __FUNCPACK__->_get_stylelist_definition_page (page => $o->{wiki}->name ($p->{page} || $o->{wiki}->{config}->{page} ->{'StyleSheetList(text/html)'} || [qw!Wiki Style List text/html!]), o => $o, wiki => $o->{wiki}); return unless $list; my $form = $p->{-parent}->append_new_node (type => '#element', namespace_uri => $NS_XHTML1, local_name => 'form'); my $id = SuikaWiki::Plugin->module_package ('WikiFormCore') ->control_id ($o, local_id => 'style-selector', require_local_id => 1); $form->set_attribute (id => $id->{global_id}); my $div = $form->append_new_node (type => '#element', namespace_uri => $NS_XHTML1, local_name => 'div'); my $parent = $div->append_new_node (type => '#element', namespace_uri => $NS_XHTML1, local_name => 'select'); $parent->set_attribute (id => $id->{global_id}.'-list'); my $default = $parent->append_new_node (type => '#element', namespace_uri => $NS_XHTML1, local_name => 'option'); $default->set_attribute (value => 'no-style'); $default->append_text ($WIKIRESOURCE->get (name => 'Style:Default', o => $o, wiki => $o->{wiki})); my $selected = 0; for my $set (@{$list->child_nodes}) { if ($set->local_name eq 'StyleSet') { my $type = {map {$_ => 1} @{ $set->get_attribute_value ('Apply', default => ['alternate']) }}; next unless $type->{preferred} or $type->{alternate}; my $title = __FUNCPACK__->_get_styleset_title (StyleSet => $set, o => $o, type => $type); my $link = $parent->append_new_node (type => '#element', namespace_uri => $NS_XHTML1, local_name => 'option'); $link->set_attribute (selected => 'selected'), $selected = 1 if $type->{preferred}; $link->set_attribute (value => $title); $link->append_text ($title); $parent->append_text ("\n"); } } $default->set_attribute (selected => 'selected') unless $selected; for ($div->append_new_node (type => '#element', namespace_uri => $NS_XHTML1, local_name => 'input')) { $_->set_attribute (type => 'button'); $_->set_attribute (id => $id->{global_id}.'-save'); $_->set_attribute (value => $WIKIRESOURCE->get (name => 'Style:Save', o => $o, wiki => $o->{wiki})); $_->set_attribute (class => 'save'); $_->option (use_EmptyElemTag => 1); } for ($div->append_new_node (type => '#element', namespace_uri => $NS_XHTML1, local_name => 'input')) { $_->set_attribute (type => 'reset'); $_->set_attribute (id => $id->{global_id}.'-reset'); $_->set_attribute (value => $WIKIRESOURCE->get (name => 'Style:Reset', o => $o, wiki => $o->{wiki})); $_->set_attribute (class => 'reset'); $_->option (use_EmptyElemTag => 1); } return if $o->{wiki}->{var}->{client}->{downgrade}->{js_no_regex}; __ATTRTEXT:%expires__; my $cookie_path = $o->{wiki}->uri_reference->path; for ($div->append_new_node (type => '#element', namespace_uri => $NS_XHTML1, local_name => 'script')) { $_->set_attribute (type => $o->{wiki}->{var}->{client}->{downgrade} ->{media_type_no_app_js} ? 'text/javascript' : 'application/x-javascript'); $_->set_attribute (defer => 'defer'); ## Gecko assumes