| 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 | 
| 130 | $opt{short_title} ||= 'Struct. Errors'; | $opt{short_title} ||= 'Struct. Errors'; | 
| 131 | $class .= ' errors'; | $class .= ' errors'; | 
| 132 | delete $opt{role}; | 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}; | 
| 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'; | 
| 163 | $opt{short_title} ||= 'Source'; | $opt{short_title} ||= 'Source'; | 
| 164 | $class .= ' source'; | $class .= ' source'; | 
| 165 | delete $opt{role}; | 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>{octets}</var>}{ | 
| 453 | }ge; | if (defined $opt{octets}) { | 
| 454 | $msg =~ s{<var>{local-name}</var>}{ | join ', ', map {sprintf '0x%02X', ord $_} split //, ${$opt{octets}}; | 
| 455 | UNIVERSAL::can ($node, 'manakai_local_name') | } else { | 
| 456 |  | ''; | 
| 457 |  | } | 
| 458 |  | }ge; | 
| 459 |  | $msg =~ s{<var>{char}</var>}{ | 
| 460 |  | defined $opt{char} ? $htescape->(${$opt{char}}) : '' | 
| 461 |  | }ge; | 
| 462 |  | $msg =~ s{<var>{char:hexref}</var>}{ | 
| 463 |  | if (defined $opt{char}) { | 
| 464 |  | join '', map {sprintf '&#x%02X;', ord $_} split //, ${$opt{char}}; | 
| 465 |  | } else { | 
| 466 |  | ''; | 
| 467 |  | } | 
| 468 |  | }ge; | 
| 469 |  | $msg =~ s{<var>{local-name}</var>}{ | 
| 470 |  | UNIVERSAL::can ($node, 'manakai_local_name') | 
| 471 | ? $htescape->($node->manakai_local_name) : '' | ? $htescape->($node->manakai_local_name) : '' | 
| 472 | }ge; | }ge; | 
| 473 | $msg =~ s{<var>{element-local-name}</var>}{ | $msg =~ s{<var>{element-local-name}</var>}{ | 
| 474 | (UNIVERSAL::can ($node, 'owner_element') and | (UNIVERSAL::can ($node, 'owner_element') and $node->owner_element) | 
|  | $node->owner_element) |  | 
| 475 | ? $htescape->($node->owner_element->manakai_local_name) : '' | ? $htescape->($node->owner_element->manakai_local_name) : '' | 
| 476 | }ge; | }ge; | 
|  | } |  | 
|  | $self->html ($msg); |  | 
|  | return; |  | 
|  | } elsif ($type =~ s/:([^:]*)$//) { |  | 
|  | unshift @arg, $1; |  | 
|  | redo; |  | 
| 477 | } | } | 
| 478 |  | $self->html ($msg); | 
| 479 |  | } else { | 
| 480 |  | $self->text ($type); | 
| 481 | } | } | 
|  | $self->text ($type); |  | 
| 482 | } # nl_text | } # nl_text | 
| 483 |  |  | 
| 484 | } | } | 
| 526 | sub generate_input_section ($$) { | sub generate_input_section ($$) { | 
| 527 | my ($out, $cgi) = @_; | my ($out, $cgi) = @_; | 
| 528 |  |  | 
| 529 |  | require Encode; | 
| 530 |  | my $decode = sub ($) { | 
| 531 |  | if (defined $_[0]) { | 
| 532 |  | return Encode::decode ('utf-8', $_[0]); | 
| 533 |  | } else { | 
| 534 |  | return undef; | 
| 535 |  | } | 
| 536 |  | }; # $decode | 
| 537 |  |  | 
| 538 | my $options = sub ($) { | my $options = sub ($) { | 
| 539 | my $context = shift; | my $context = shift; | 
| 540 |  |  | 
| 560 | $out->select ([ | $out->select ([ | 
| 561 | {value => '', label => 'As specified'}, | {value => '', label => 'As specified'}, | 
| 562 | {value => 'application/atom+xml'}, | {value => 'application/atom+xml'}, | 
| 563 |  | {value => 'text/cache-manifest'}, | 
| 564 |  | {value => 'text/css'}, | 
| 565 |  | {value => 'text/x-h2h'}, | 
| 566 |  | {value => 'text/html'}, | 
| 567 |  | {value => 'text/x-webidl'}, | 
| 568 | {value => 'application/xhtml+xml'}, | {value => 'application/xhtml+xml'}, | 
| 569 | {value => 'application/xml'}, | {value => 'application/xml'}, | 
|  | {value => 'text/html'}, |  | 
| 570 | {value => 'text/xml'}, | {value => 'text/xml'}, | 
|  | {value => 'text/css'}, |  | 
|  | {value => 'text/cache-manifest'}, |  | 
|  | {value => 'text/x-webidl'}, |  | 
| 571 | ], name => 'i', selected => scalar $cgi->get_parameter ('i')); | ], name => 'i', selected => scalar $cgi->get_parameter ('i')); | 
| 572 | $out->end_tag ('label'); | $out->end_tag ('label'); | 
| 573 |  |  | 
| 581 | {label => 'Japanese charsets', options => [ | {label => 'Japanese charsets', options => [ | 
| 582 | {value => 'Windows-31J'}, | {value => 'Windows-31J'}, | 
| 583 | {value => 'Shift_JIS'}, | {value => 'Shift_JIS'}, | 
| 584 |  | {value => 'x-sjis'}, | 
| 585 | {value => 'EUC-JP'}, | {value => 'EUC-JP'}, | 
| 586 |  | {value => 'x-euc-jp'}, | 
| 587 | {value => 'ISO-2022-JP'}, | {value => 'ISO-2022-JP'}, | 
| 588 |  | {value => 'ISO-2022-JP-1'}, | 
| 589 |  | {value => 'ISO-2022-JP-2'}, | 
| 590 | ]}, | ]}, | 
| 591 | {label => 'European charsets', options => [ | {label => 'Latin charsets', options => [ | 
| 592 |  | {value => 'Windows-1250'}, | 
| 593 | {value => 'Windows-1252'}, | {value => 'Windows-1252'}, | 
| 594 |  | {value => 'Windows-1254'}, | 
| 595 |  | {value => 'Windows-1257'}, | 
| 596 |  | {value => 'Windows-1258'}, | 
| 597 | {value => 'ISO-8859-1'}, | {value => 'ISO-8859-1'}, | 
| 598 |  | {value => 'ISO-8859-2'}, | 
| 599 |  | {value => 'ISO-8859-3'}, | 
| 600 |  | {value => 'ISO-8859-4'}, | 
| 601 |  | {value => 'ISO-8859-9'}, | 
| 602 |  | {value => 'ISO-8859-10'}, | 
| 603 |  | {value => 'ISO-8859-13'}, | 
| 604 |  | {value => 'ISO-8859-14'}, | 
| 605 |  | {value => 'ISO-8859-15'}, | 
| 606 |  | {value => 'ISO-8859-16'}, | 
| 607 | {value => 'US-ASCII'}, | {value => 'US-ASCII'}, | 
| 608 | ]}, | ]}, | 
| 609 | {label => 'Asian charsets', options => [ | {label => 'Greek charsets', options => [ | 
| 610 |  | {value => 'Windows-1253'}, | 
| 611 |  | {value => 'ISO-8859-7'}, | 
| 612 |  | ]}, | 
| 613 |  | {label => 'Cyrillic charsets', options => [ | 
| 614 |  | {value => 'Windows-1251'}, | 
| 615 |  | {value => 'ISO-8859-5'}, | 
| 616 |  | ]}, | 
| 617 |  | {label => 'Arabic charsets', options => [ | 
| 618 |  | {value => 'Windows-1256'}, | 
| 619 |  | {value => 'ISO-8859-6'}, | 
| 620 |  | ]}, | 
| 621 |  | {label => 'Hebrew charsets', options => [ | 
| 622 |  | {value => 'Windows-1255'}, | 
| 623 |  | {value => 'ISO-8859-8'}, | 
| 624 |  | ]}, | 
| 625 |  | {label => 'Thai charsets', options => [ | 
| 626 | {value => 'Windows-874'}, | {value => 'Windows-874'}, | 
| 627 | {value => 'ISO-8859-11'}, | {value => 'ISO-8859-11'}, | 
| 628 | {value => 'TIS-620'}, | {value => 'TIS-620'}, | 
| 629 | ]}, | ]}, | 
| 630 |  | {label => 'Chinese charsets', options => [ | 
| 631 |  | {value => 'Big5'}, | 
| 632 |  | {value => 'x-x-big5'}, | 
| 633 |  | {value => 'Big5-HKSCS'}, | 
| 634 |  | {value => 'GBK'}, | 
| 635 |  | {value => 'GB2312'}, | 
| 636 |  | {value => 'GB_2312-80'}, | 
| 637 |  | {value => 'ISO-2022-CN'}, | 
| 638 |  | {value => 'ISO-2022-CN-EXT'}, | 
| 639 |  | ]}, | 
| 640 |  | {label => 'Korean charsets', options => [ | 
| 641 |  | {value => 'Windows-949'}, | 
| 642 |  | {value => 'EUC-KR'}, | 
| 643 |  | {value => 'KS_C_5601-1987'}, | 
| 644 |  | {value => 'ISO-2022-KR'}, | 
| 645 |  | ]}, | 
| 646 | {label => 'Unicode charsets', options => [ | {label => 'Unicode charsets', options => [ | 
| 647 | {value => 'UTF-8'}, | {value => 'UTF-8'}, | 
| 648 | {value => 'UTF-8n'}, | {value => 'UTF-8n'}, | 
| 649 | ]}, | {value => 'UTF-16'}, | 
| 650 |  | {value => 'UTF-16BE'}, | 
| 651 |  | {value => 'UTF-16LE'}, | 
| 652 |  | ]}, | 
| 653 | ], name => 'charset', | ], name => 'charset', | 
| 654 | selected => scalar $cgi->get_parameter ('charset')); | selected => scalar $cgi->get_parameter ('charset')); | 
| 655 | $out->end_tag ('label'); | $out->end_tag ('label'); | 
| 661 | $out->nl_text ('Setting innerHTML'); | $out->nl_text ('Setting innerHTML'); | 
| 662 | $out->text (': '); | $out->text (': '); | 
| 663 | $out->start_tag ('input', name => 'e', | $out->start_tag ('input', name => 'e', | 
| 664 | value => scalar $cgi->get_parameter ('e')); | value => $decode->(scalar $cgi->get_parameter ('e'))); | 
| 665 | $out->end_tag ('label'); | $out->end_tag ('label'); | 
| 666 | } | } | 
| 667 |  |  | 
| 685 | $out->start_tag ('input', | $out->start_tag ('input', | 
| 686 | name => 'uri', | name => 'uri', | 
| 687 | type => 'url', | type => 'url', | 
| 688 | value => $cgi->get_parameter ('uri')); | value => $decode->(scalar $cgi->get_parameter ('uri'))); | 
| 689 | $out->end_tag ('label'); | $out->end_tag ('label'); | 
| 690 |  |  | 
| 691 | $out->start_tag ('p'); | $out->start_tag ('p'); | 
| 698 | $out->end_tag ('form'); | $out->end_tag ('form'); | 
| 699 | $out->end_section; | $out->end_section; | 
| 700 |  |  | 
|  | $out->end_tag ('fieldset'); |  | 
|  |  |  | 
| 701 | ## TODO: File upload | ## TODO: File upload | 
| 702 |  |  | 
| 703 | $out->start_section (id => 'input-text', title => 'By direct input', | $out->start_section (id => 'input-text', title => 'By direct input', | 
| 714 | $out->start_tag ('br'); | $out->start_tag ('br'); | 
| 715 | $out->start_tag ('textarea', | $out->start_tag ('textarea', | 
| 716 | name => 's'); | name => 's'); | 
| 717 | my $s = $cgi->get_parameter ('s'); | my $s = $decode->($cgi->get_parameter ('s')); | 
| 718 | $out->html ($htescape_value->($s)) if defined $s; | $out->html ($htescape_value->($s)) if defined $s; | 
| 719 | $out->end_tag ('textarea'); | $out->end_tag ('textarea'); | 
| 720 | $out->end_tag ('label'); | $out->end_tag ('label'); |