| 55 | return $_[0]->{handle}; | return $_[0]->{handle}; | 
| 56 | } # handle | } # handle | 
| 57 |  |  | 
| 58 |  | sub has_error ($;$) { | 
| 59 |  | if (@_ > 1) { | 
| 60 |  | if (defined $_[1]) { | 
| 61 |  | $_[0]->{has_error} = 1; | 
| 62 |  | } else { | 
| 63 |  | delete $_[0]->{has_error}; | 
| 64 |  | } | 
| 65 |  | } | 
| 66 |  |  | 
| 67 |  | return $_[0]->{has_error}; | 
| 68 |  | } # has_error | 
| 69 |  |  | 
| 70 | sub set_utf8 ($) { | sub set_utf8 ($) { | 
| 71 | binmode shift->{handle}, ':utf8'; | binmode shift->{handle}, ':utf8'; | 
| 72 | } # set_utf8 | } # set_utf8 | 
| 122 | $opt{id} ||= 'parse-errors'; | $opt{id} ||= 'parse-errors'; | 
| 123 | $opt{title} ||= 'Parse Errors Section'; | $opt{title} ||= 'Parse Errors Section'; | 
| 124 | $opt{short_title} ||= 'Parse Errors'; | $opt{short_title} ||= 'Parse Errors'; | 
| 125 |  | $class .= ' errors'; | 
| 126 | delete $opt{role}; | delete $opt{role}; | 
| 127 | } elsif ($opt{role} eq 'structure-errors') { | } elsif ($opt{role} eq 'structure-errors') { | 
| 128 | $opt{id} ||= 'document-errors'; | $opt{id} ||= 'document-errors'; | 
| 129 | $opt{title} ||= 'Structural Errors'; | $opt{title} ||= 'Structural Errors'; | 
| 130 | $opt{short_title} ||= 'Struct. Errors'; | $opt{short_title} ||= 'Struct. Errors'; | 
| 131 |  | $class .= ' errors'; | 
| 132 |  | delete $opt{role}; | 
| 133 |  | } elsif ($opt{role} eq 'transfer-errors') { | 
| 134 |  | $opt{id} ||= 'transfer-errors'; | 
| 135 |  | $opt{title} ||= 'Transfer Errors'; | 
| 136 |  | $opt{short_title} ||= 'Trans. Errors'; | 
| 137 |  | $class .= ' errors'; | 
| 138 | delete $opt{role}; | delete $opt{role}; | 
| 139 | } elsif ($opt{role} eq 'reformatted') { | } elsif ($opt{role} eq 'reformatted') { | 
| 140 | $opt{id} ||= 'document-tree'; | $opt{id} ||= 'document-tree'; | 
| 141 | $opt{title} ||= 'Reformatted Document Source'; | $opt{title} ||= 'Reformatted Document Source'; | 
| 142 | $opt{short_title} ||= 'Reformatted'; | $opt{short_title} ||= 'Reformatted'; | 
| 143 |  | $class .= ' dump'; | 
| 144 | delete $opt{role} | delete $opt{role} | 
| 145 | } elsif ($opt{role} eq 'tree') { | } elsif ($opt{role} eq 'tree') { | 
| 146 | $opt{id} ||= 'document-tree'; | $opt{id} ||= 'document-tree'; | 
| 147 | $opt{title} ||= 'Document Tree'; | $opt{title} ||= 'Document Tree'; | 
| 148 | $opt{short_title} ||= 'Tree'; | $opt{short_title} ||= 'Tree'; | 
| 149 |  | $class .= ' dump'; | 
| 150 | delete $opt{role}; | delete $opt{role}; | 
| 151 | } elsif ($opt{role} eq 'structure') { | } elsif ($opt{role} eq 'structure') { | 
| 152 | $opt{id} ||= 'document-structure'; | $opt{id} ||= 'document-structure'; | 
| 153 | $opt{title} ||= 'Document Structure'; | $opt{title} ||= 'Document Structure'; | 
| 154 | $opt{short_title} ||= 'Structure'; | $opt{short_title} ||= 'Structure'; | 
| 155 |  | $class .= ' dump'; | 
| 156 | delete $opt{role}; | delete $opt{role}; | 
| 157 | } elsif ($opt{role} eq 'subdoc') { | } elsif ($opt{role} eq 'subdoc') { | 
| 158 | $class .= ' subdoc'; | $class .= ' subdoc'; | 
| 159 | delete $opt{role}; | delete $opt{role}; | 
| 160 |  | } elsif ($opt{role} eq 'source') { | 
| 161 |  | $opt{id} ||= 'source-string'; | 
| 162 |  | $opt{title} ||= 'Document Source'; | 
| 163 |  | $opt{short_title} ||= 'Source'; | 
| 164 |  | $class .= ' source'; | 
| 165 |  | delete $opt{role}; | 
| 166 |  | } elsif ($opt{role} eq 'result') { | 
| 167 |  | $opt{id} ||= 'result-summary'; | 
| 168 |  | $opt{title} ||= 'Result'; | 
| 169 |  | $class .= ' result'; | 
| 170 |  | delete $opt{role}; | 
| 171 | } | } | 
| 172 | } | } | 
| 173 |  |  | 
| 181 | if ($self->{section_rank} == 2 or length $opt{parent_id}) { | if ($self->{section_rank} == 2 or length $opt{parent_id}) { | 
| 182 | my $st = $opt{short_title} || $opt{title}; | my $st = $opt{short_title} || $opt{title}; | 
| 183 | push @{$self->{nav}}, | push @{$self->{nav}}, | 
| 184 | [$id => $st => $opt{text}]; | [$id => $st => $opt{text}] if $self->{section_rank} == 2; | 
| 185 |  |  | 
| 186 | $self->start_tag ('script'); | $self->start_tag ('script'); | 
| 187 | $self->html (qq[ addSectionLink ('$id', ']); | $self->html (qq[ addSectionLink ('$id', ']); | 
| 219 | } elsif ($opt{role} eq 'structure-errors') { | } elsif ($opt{role} eq 'structure-errors') { | 
| 220 | $opt{id} ||= 'document-errors-list'; | $opt{id} ||= 'document-errors-list'; | 
| 221 | delete $opt{role}; | delete $opt{role}; | 
| 222 |  | } elsif ($opt{role} eq 'transfer-errors') { | 
| 223 |  | $opt{id} ||= 'transfer-errors-list'; | 
| 224 |  | delete $opt{role}; | 
| 225 | } | } | 
| 226 | } | } | 
| 227 |  |  | 
| 228 | $self->start_tag ('dl', %opt); | $self->start_tag ('dl', %opt); | 
| 229 |  |  | 
| 230 |  | delete $self->{has_error}; # reset | 
| 231 | } # start_error_list | } # start_error_list | 
| 232 |  |  | 
| 233 | sub end_error_list ($%) { | sub end_error_list ($%) { | 
| 234 | my ($self, %opt) = @_; | my ($self, %opt) = @_; | 
| 235 |  |  | 
| 236 |  | my $no_error_message = 'No error found.'; | 
| 237 |  |  | 
| 238 | if (defined $opt{role}) { | if (defined $opt{role}) { | 
| 239 | if ($opt{role} eq 'parse-errors') { | if ($opt{role} eq 'parse-errors') { | 
|  | delete $opt{role}; |  | 
| 240 | $self->end_tag ('dl'); | $self->end_tag ('dl'); | 
| 241 | ## NOTE: For parse error list, the |add_source_to_parse_error_list| | ## NOTE: For parse error list, the |add_source_to_parse_error_list| | 
| 242 | ## method is invoked at the end of |generate_source_string_section|, | ## method is invoked at the end of |generate_source_string_section|, | 
| 243 | ## since that generation method is invoked after the error list | ## since that generation method is invoked after the error list | 
| 244 | ## is generated. | ## is generated. | 
| 245 |  | $no_error_message = 'No parse error found.'; | 
| 246 | } elsif ($opt{role} eq 'structure-errors') { | } elsif ($opt{role} eq 'structure-errors') { | 
|  | delete $opt{role}; |  | 
| 247 | $self->end_tag ('dl'); | $self->end_tag ('dl'); | 
| 248 | $self->add_source_to_parse_error_list ('document-errors-list'); | $self->add_source_to_parse_error_list ('document-errors-list'); | 
| 249 |  | $no_error_message = 'No structural error found.'; | 
| 250 |  | } elsif ($opt{role} eq 'transfer-errors') { | 
| 251 |  | $self->end_tag ('dl'); | 
| 252 |  | $no_error_message = 'No transfer error found.'; | 
| 253 | } else { | } else { | 
| 254 | $self->end_tag ('dl'); | $self->end_tag ('dl'); | 
| 255 | } | } | 
| 256 | } else { | } else { | 
| 257 | $self->end_tag ('dl'); | $self->end_tag ('dl'); | 
| 258 | } | } | 
| 259 |  |  | 
| 260 |  | unless ($self->{has_error}) { | 
| 261 |  | $self->start_tag ('p', class => 'no-errors'); | 
| 262 |  | $self->nl_text ($no_error_message); | 
| 263 |  | } | 
| 264 | } # end_error_list | } # end_error_list | 
| 265 |  |  | 
| 266 | sub add_source_to_parse_error_list ($$) { | sub add_source_to_parse_error_list ($$) { | 
| 341 | $self->html ('</a>'); | $self->html ('</a>'); | 
| 342 | } # xref | } # xref | 
| 343 |  |  | 
| 344 |  | sub xref_text ($$%) { | 
| 345 |  | my ($self, $content, %opt) = @_; | 
| 346 |  | $self->html ('<a href="#' . $htescape->($self->input->id_prefix . $opt{target}) . '">'); | 
| 347 |  | $self->text ($content); | 
| 348 |  | $self->html ('</a>'); | 
| 349 |  | } # xref | 
| 350 |  |  | 
| 351 | sub link_to_webhacc ($$%) { | sub link_to_webhacc ($$%) { | 
| 352 | my ($self, $content, %opt) = @_; | my ($self, $content, %opt) = @_; | 
| 353 | $opt{url} = './?uri=' . $self->encode_url_component ($opt{url}); | $opt{url} = './?uri=' . $self->encode_url_component ($opt{url}); | 
| 401 | sub node_link ($$) { | sub node_link ($$) { | 
| 402 | my ($self, $node) = @_; | my ($self, $node) = @_; | 
| 403 | if ($node->isa ('Message::IF::Node')) { | if ($node->isa ('Message::IF::Node')) { | 
| 404 | $self->xref ($get_node_path->($node), target => 'node-' . refaddr $node); | $self->xref_text ($get_node_path->($node), | 
| 405 |  | target => 'node-' . refaddr $node); | 
| 406 | } else { | } else { | 
| 407 | $self->html ($get_object_path->($node)); | $self->html ($get_object_path->($node)); | 
| 408 | } | } | 
| 433 | my ($self, $type, %opt) = @_; | my ($self, $type, %opt) = @_; | 
| 434 | my $node = $opt{node}; | my $node = $opt{node}; | 
| 435 |  |  | 
| 436 | my @arg; | if (defined $Msg->{$type}) { | 
| 437 | { | my $msg = $Msg->{$type}->[1]; | 
| 438 | if (defined $Msg->{$type}) { | if ($msg =~ /<var>/) { | 
| 439 | my $msg = $Msg->{$type}->[1]; | $msg =~ s{<var>{\@([A-Za-z0-9:_.-]+)}</var>}{ | 
| 440 | if ($msg =~ /<var>/) { | UNIVERSAL::can ($node, 'get_attribute_ns') | 
| 441 | $msg =~ s{<var>\$([0-9]+)</var>}{ | ? $htescape->($node->get_attribute_ns (undef, $1)) : '' | 
| 442 | defined $arg[$1] ? $htescape->($arg[$1]) : '(undef)'; | }ge; | 
| 443 | }ge; | $msg =~ s{<var>{\@}</var>}{ | 
| 444 | $msg =~ s{<var>{\@([A-Za-z0-9:_.-]+)}</var>}{ | UNIVERSAL::can ($node, 'value') ? $htescape->($node->value) : '' | 
| 445 | UNIVERSAL::can ($node, 'get_attribute_ns') | }ge; | 
| 446 | ? $htescape->($node->get_attribute_ns (undef, $1)) : '' | $msg =~ s{<var>{text}</var>}{ | 
| 447 | }ge; | defined $opt{text} ? $htescape->($opt{text}) : '' | 
| 448 | $msg =~ s{<var>{\@}</var>}{ | }ge; | 
| 449 | UNIVERSAL::can ($node, 'value') ? $htescape->($node->value) : '' | $msg =~ s{<var>{value}</var>}{ | 
| 450 | }ge; | defined $opt{value} ? $htescape->($opt{value}) : '' | 
| 451 | $msg =~ s{<var>{text}</var>}{ | }ge; | 
| 452 | defined $opt{text} ? $htescape->($opt{text}) : '' | $msg =~ s{<var>{local-name}</var>}{ | 
| 453 | }ge; | UNIVERSAL::can ($node, 'manakai_local_name') | 
|  | $msg =~ s{<var>{local-name}</var>}{ |  | 
|  | UNIVERSAL::can ($node, 'manakai_local_name') |  | 
| 454 | ? $htescape->($node->manakai_local_name) : '' | ? $htescape->($node->manakai_local_name) : '' | 
| 455 | }ge; | }ge; | 
| 456 | $msg =~ s{<var>{element-local-name}</var>}{ | $msg =~ s{<var>{element-local-name}</var>}{ | 
| 457 | (UNIVERSAL::can ($node, 'owner_element') and | (UNIVERSAL::can ($node, 'owner_element') and $node->owner_element) | 
|  | $node->owner_element) |  | 
| 458 | ? $htescape->($node->owner_element->manakai_local_name) : '' | ? $htescape->($node->owner_element->manakai_local_name) : '' | 
| 459 | }ge; | }ge; | 
|  | } |  | 
|  | $self->html ($msg); |  | 
|  | return; |  | 
|  | } elsif ($type =~ s/:([^:]*)$//) { |  | 
|  | unshift @arg, $1; |  | 
|  | redo; |  | 
| 460 | } | } | 
| 461 |  | $self->html ($msg); | 
| 462 |  | } else { | 
| 463 |  | $self->text ($type); | 
| 464 | } | } | 
|  | $self->text ($type); |  | 
| 465 | } # nl_text | } # nl_text | 
| 466 |  |  | 
| 467 | } | } | 
| 509 | sub generate_input_section ($$) { | sub generate_input_section ($$) { | 
| 510 | my ($out, $cgi) = @_; | my ($out, $cgi) = @_; | 
| 511 |  |  | 
| 512 |  | require Encode; | 
| 513 |  | my $decode = sub ($) { | 
| 514 |  | if (defined $_[0]) { | 
| 515 |  | return Encode::decode ('utf-8', $_[0]); | 
| 516 |  | } else { | 
| 517 |  | return undef; | 
| 518 |  | } | 
| 519 |  | }; # $decode | 
| 520 |  |  | 
| 521 | my $options = sub ($) { | my $options = sub ($) { | 
| 522 | my $context = shift; | my $context = shift; | 
| 523 |  |  | 
| 543 | $out->select ([ | $out->select ([ | 
| 544 | {value => '', label => 'As specified'}, | {value => '', label => 'As specified'}, | 
| 545 | {value => 'application/atom+xml'}, | {value => 'application/atom+xml'}, | 
| 546 |  | {value => 'text/cache-manifest'}, | 
| 547 |  | {value => 'text/css'}, | 
| 548 |  | {value => 'text/x-h2h'}, | 
| 549 |  | {value => 'text/html'}, | 
| 550 |  | {value => 'text/x-webidl'}, | 
| 551 | {value => 'application/xhtml+xml'}, | {value => 'application/xhtml+xml'}, | 
| 552 | {value => 'application/xml'}, | {value => 'application/xml'}, | 
|  | {value => 'text/html'}, |  | 
| 553 | {value => 'text/xml'}, | {value => 'text/xml'}, | 
|  | {value => 'text/css'}, |  | 
|  | {value => 'text/cache-manifest'}, |  | 
|  | {value => 'text/x-webidl'}, |  | 
| 554 | ], name => 'i', selected => scalar $cgi->get_parameter ('i')); | ], name => 'i', selected => scalar $cgi->get_parameter ('i')); | 
| 555 | $out->end_tag ('label'); | $out->end_tag ('label'); | 
| 556 |  |  | 
| 592 | $out->nl_text ('Setting innerHTML'); | $out->nl_text ('Setting innerHTML'); | 
| 593 | $out->text (': '); | $out->text (': '); | 
| 594 | $out->start_tag ('input', name => 'e', | $out->start_tag ('input', name => 'e', | 
| 595 | value => scalar $cgi->get_parameter ('e')); | value => $decode->(scalar $cgi->get_parameter ('e'))); | 
| 596 | $out->end_tag ('label'); | $out->end_tag ('label'); | 
| 597 | } | } | 
| 598 |  |  | 
| 616 | $out->start_tag ('input', | $out->start_tag ('input', | 
| 617 | name => 'uri', | name => 'uri', | 
| 618 | type => 'url', | type => 'url', | 
| 619 | value => $cgi->get_parameter ('uri')); | value => $decode->(scalar $cgi->get_parameter ('uri'))); | 
| 620 | $out->end_tag ('label'); | $out->end_tag ('label'); | 
| 621 |  |  | 
| 622 | $out->start_tag ('p'); | $out->start_tag ('p'); | 
| 629 | $out->end_tag ('form'); | $out->end_tag ('form'); | 
| 630 | $out->end_section; | $out->end_section; | 
| 631 |  |  | 
|  | $out->end_tag ('fieldset'); |  | 
|  |  |  | 
| 632 | ## TODO: File upload | ## TODO: File upload | 
| 633 |  |  | 
| 634 | $out->start_section (id => 'input-text', title => 'By direct input', | $out->start_section (id => 'input-text', title => 'By direct input', | 
| 645 | $out->start_tag ('br'); | $out->start_tag ('br'); | 
| 646 | $out->start_tag ('textarea', | $out->start_tag ('textarea', | 
| 647 | name => 's'); | name => 's'); | 
| 648 | my $s = $cgi->get_parameter ('s'); | my $s = $decode->($cgi->get_parameter ('s')); | 
| 649 | $out->html ($htescape_value->($s)) if defined $s; | $out->html ($htescape_value->($s)) if defined $s; | 
| 650 | $out->end_tag ('textarea'); | $out->end_tag ('textarea'); | 
| 651 | $out->end_tag ('label'); | $out->end_tag ('label'); |