Changeset 5573
- Timestamp:
- 11/18/09 06:27:14 (2 years ago)
- Location:
- trunk/WysiwygPlugin
- Files:
-
- 6 edited
-
data/System/WysiwygPlugin.txt (modified) (3 diffs)
-
lib/Foswiki/Plugins/WysiwygPlugin/HTML2TML/Node.pm (modified) (9 diffs)
-
lib/Foswiki/Plugins/WysiwygPlugin/TML2HTML.pm (modified) (8 diffs)
-
lib/Foswiki/Plugins/WysiwygPlugin/build.pl (modified) (1 diff)
-
test/unit/WysiwygPlugin/ExtendedTranslatorTests.pm (modified) (20 diffs)
-
test/unit/WysiwygPlugin/TranslatorTests.pm (modified) (17 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/WysiwygPlugin/data/System/WysiwygPlugin.txt
r5355 r5573 141 141 142 142 ---+++ Overlapping styles 143 Because Foswiki uses a "best guess" approach to some formatting, it allows overlapping of tags in a way forbidden by HTML, and it is impossible to guarantee 100% that format ing in the original Foswiki document will still be there when the same document is loaded and then saved through the WysiwygPlugin. The most obvious case of this is to do with styles. For example, the sentence143 Because Foswiki uses a "best guess" approach to some formatting, it allows overlapping of tags in a way forbidden by HTML, and it is impossible to guarantee 100% that formatting in the original Foswiki document will still be there when the same document is loaded and then saved through the WysiwygPlugin. The most obvious case of this is to do with styles. For example, the sentence 144 144 <verbatim> 145 145 *bold _bold-italic* italic_ … … 155 155 which is correct by construction, but does not render correctly in Foswiki. This problem is unfortunately unavoidable due to the way TML works. 156 156 157 ---+++ Rowspan processing needs %SYSTEMWEB%.TablePlugin 158 159 WysiwygPlugin is able to convert tables with cells that span rows into TML. This requires syntax provided by the %SYSTEMWEB%.TablePlugin (that is, the =| ^ |= markup). WysiwygPlugin will therefore only perform row-span related conversion if %SYSTEMWEB%.TablePlugin is enabled. %SYSTEMWEB%.TablePlugin is enabled by default and hence WysiwygPlugin converts tables with cells that span rows between TML and HTML by default. 160 161 If %SYSTEMWEB%.TablePlugin is *not* enabled, then TML table cells containing only =^= are not converted to rowspans, and HTML tables containing rowspans are not converted to TML. 162 157 163 ---++ Plugin Info 158 164 … … 170 176 | Release: | %$RELEASE% | 171 177 | Change History: | | 178 | 18 Nov 2009 | Foswikitask:Item2369: Convert tables with cells that span rows | 172 179 | 22 Oct 2009 | Foswikitask:Item2183: Protect div style= by default | 173 180 | 18 Sep 2009 | Foswikitask:Item1980: Prevent dataloss when saving a topic in Wysiwyg where there are a pair of sticky tags inside verbatim tags | -
trunk/WysiwygPlugin/lib/Foswiki/Plugins/WysiwygPlugin/HTML2TML/Node.pm
r3986 r5573 823 823 } 824 824 825 # probe down into a list type to determine if it825 # probe down into a table to determine if it 826 826 # can be converted to TML. 827 827 sub _isConvertableTable { … … 831 831 return 0; 832 832 } 833 834 my $rowspan = undef; 835 $rowspan = [] if Foswiki::Func::getContext()->{'TablePluginEnabled'}; 833 836 834 837 my $kid = $this->{head}; … … 843 846 return 0; 844 847 } 845 my $row = $kid->_isConvertableTableRow( $options);848 my $row = $kid->_isConvertableTableRow( $options, $rowspan ); 846 849 unless ($row) { 847 850 return 0; … … 850 853 } 851 854 $kid = $kid->{next}; 855 } 856 857 if ( $rowspan and grep { $_ } @$rowspan ) { 858 859 # One or more cells span rows past the last row in the table. 860 # This is a defect in the HTML table which TML cannot represent. 861 return 0; 852 862 } 853 863 return 1; … … 865 875 } 866 876 867 # probe down into a list itemto determine if the877 # probe down into a table row to determine if the 868 878 # containing table can be converted to TML. 869 879 sub _isConvertableTableRow { 870 my ( $this, $options ) = @_;880 my ( $this, $options, $rowspan ) = @_; 871 881 872 882 return 0 if ( $this->_isProtectedByAttrs() ); … … 876 886 my $ignoreCols = 0; 877 887 my $kid = $this->{head}; 888 my $colIdx = 0; 889 while ( $rowspan and $rowspan->[$colIdx] ) { 890 push @row, $WC::NBSP . '^' . $WC::NBSP; 891 $rowspan->[$colIdx]--; 892 $colIdx++; 893 } 878 894 while ($kid) { 879 895 if ( $kid->{tag} eq 'th' ) { … … 913 929 } 914 930 if ( $kid->{attrs}->{rowspan} && $kid->{attrs}->{rowspan} > 1 ) { 915 return 0; 931 return 0 unless $rowspan; 932 $rowspan->[$colIdx] = $kid->{attrs}->{rowspan} - 1; 916 933 } 917 934 } … … 937 954 # Pad to allow wikiwords to work 938 955 push( @row, $text ); 956 $colIdx++; 939 957 while ( $ignoreCols > 1 ) { 958 if ( $rowspan and $rowspan->[$colIdx] ) { 959 960 # rowspan and colspan into the same cell 961 return 0; 962 } 940 963 push( @row, '' ); 941 964 $ignoreCols--; 965 $colIdx++; 966 } 967 while ( $rowspan and $rowspan->[$colIdx] ) { 968 push @row, $WC::NBSP . '^' . $WC::NBSP; 969 $rowspan->[$colIdx]--; 970 $colIdx++; 942 971 } 943 972 $kid = $kid->{next}; … … 1565 1594 \@table ); 1566 1595 1567 my $maxrow = 0;1568 my $row;1569 foreach $row (@table) {1570 my $rw = scalar(@$row);1571 $maxrow = $rw if ( $rw > $maxrow );1572 }1573 foreach $row (@table) {1574 while ( scalar(@$row) < $maxrow ) {1575 push( @$row, '' );1576 }1577 }1578 1596 my $text = $WC::CHECKn; 1579 foreach $row (@table) {1597 foreach my $row (@table) { 1580 1598 1581 1599 # isConvertableTableRow has already formatted the cell -
trunk/WysiwygPlugin/lib/Foswiki/Plugins/WysiwygPlugin/TML2HTML.pm
r5503 r5573 115 115 if ($content =~ /[$TT0$TT1$TT2]/o) { 116 116 # There should never be any of these in the text at this point. 117 # If there are, then the conversion failed. 117 # If there are, then the conversion failed. 118 118 die("Invalid characters in HTML after conversion") if $options->{dieOnError}; 119 # Encode the original TML as verbatim-style HTML, 119 120 # Encode the original TML as verbatim-style HTML, 120 121 # so that the user has uncorrupted TML, at least. 121 122 my $originalContent = $_[1]; … … 245 246 246 247 # Lifted straight out of DevelopBranch Render.pm 248 # Then modified to include TablePlugin's approach to table rendering 247 249 sub _getRenderedVersion { 248 250 my ( $this, $text, $refs ) = @_; … … 342 344 my $inList = 0; # True when within a list type 343 345 my $inTable = 0; # True when within a table type 346 my %table = (); 344 347 my $inParagraph = 1; # True when within a P 345 348 my @result = ('<p>'); … … 354 357 $this->_addListItem( \@result, '', '', '' ) if $inList; 355 358 $inList = 0; 356 unless ($inTable) { 357 push( 358 @result, 359 CGI::start_table( 360 { border => 1, cellpadding => 0, cellspacing => 1 } 361 ) 362 ); 363 } 364 push( @result, _emitTR($1) ); 359 push( @result, _processTableRow( $1, $inTable, \%table ) ); 365 360 $inTable = 1; 366 361 next; … … 368 363 369 364 if ($inTable) { 370 push( @result, CGI::end_table() );365 push( @result, _emitTable( \%table ) ); 371 366 $inTable = 0; 372 367 } … … 468 463 469 464 if ($inTable) { 470 push( @result, '</table>');465 push( @result, _emitTable( \%table ) ); 471 466 } 472 467 elsif ($inList) { … … 529 524 530 525 return $text; 526 } 527 528 sub _processTableRow { 529 530 my ( $theRow, $inTable, $state ) = @_; 531 my @result; 532 my $firstRow = 0; 533 if ( !$inTable ) { 534 535 %$state = ( curTable => [], rowspan => [] ); 536 $firstRow = 1; 537 } 538 539 $theRow =~ s/\t/ /go; # change tabs to space 540 $theRow =~ s/\s*$//o; # remove trailing spaces 541 $theRow =~ s/^(\s*)\|//; # Remove leading junk 542 my $pre = $1; 543 544 $theRow =~ 545 s/(\|\|+)/'colspan'.$Foswiki::TranslationToken.length($1)."\|"/geo 546 ; # calc COLSPAN 547 my $colCount = 0; 548 my @row = (); 549 my $span = 0; 550 my $value = ''; 551 552 my $rowspanEnabled = Foswiki::Func::getContext()->{'TablePluginEnabled'}; 553 554 foreach ( split( /\|/, $theRow ) ) { 555 my $attr = {}; 556 $span = 1; 557 if (s/colspan$Foswiki::TranslationToken([0-9]+)//) { 558 $span = $1; 559 $attr->{colspan} = $span; 560 } 561 s/^\s+$/ /o; 562 my ( $left, $right ) = ( 0, 0 ); 563 if (/^(\s*)(.*?)(\s*)$/) { 564 $left = length($1); 565 $_ = $2; 566 $right = length($3); 567 } 568 if ( $left == 1 && $right < 2 ) { 569 570 # Treat left=1 and right=0 like 1 and 1 - Item5220 571 } 572 elsif ( $left > $right ) { 573 $attr->{class} = 'align-right'; 574 $attr->{style} = 'text-align: right'; 575 } 576 elsif ( $left < $right ) { 577 $attr->{class} = 'align-left'; 578 $attr->{style} = 'text-align: left'; 579 } 580 elsif ( $left > 1 ) { 581 $attr->{class} = 'align-center'; 582 $attr->{style} = 'text-align: center'; 583 } 584 585 if ( $rowspanEnabled 586 and !$firstRow 587 and /^(\s|<[^>]*>)*\^(\s|<[^>]*>)*$/ ) 588 { # row span above 589 $state->{rowspan}->[$colCount]++; 590 push @row, { text => $value, type => 'Y' }; 591 } 592 else { 593 for ( my $col = $colCount ; $col < ( $colCount + $span ) ; $col++ ) 594 { 595 if ( defined( $state->{rowspan}->[$col] ) 596 && $state->{rowspan}->[$col] ) 597 { 598 my $nRows = scalar( @{ $state->{curTable} } ); 599 my $rspan = $state->{rowspan}->[$col] + 1; 600 if ( $rspan > 1 ) { 601 $state->{curTable}->[ $nRows - $rspan ][$col]->{attrs} 602 ->{rowspan} = $rspan; 603 } 604 undef( $state->{rowspan}->[$col] ); 605 } 606 } 607 608 my $type = ''; 609 if (/^\s*\*(.*)\*\s*$/) { 610 $value = $1; 611 $type = 'th'; 612 } 613 else { 614 if (/^\s*(.*?)\s*$/) { # strip white spaces 615 $_ = $1; 616 } 617 $value = $_; 618 $type = 'td'; 619 } 620 621 $value = ' ' . $value if $value =~ /^(?:\*|==?|__?)[^\s]/; 622 $value = $value . ' ' if $value =~ /[^\s](?:\*|==?|__?)$/; 623 624 push @row, { text => $value, attrs => $attr, type => $type }; 625 } 626 627 while ( $span > 1 ) { 628 push @row, { text => $value, type => 'X' }; 629 $colCount++; 630 $span--; 631 } 632 $colCount++; 633 } 634 push @{ $state->{curTable} }, \@row; 635 push @{ $state->{pre} }, $pre; 636 return; 637 } 638 639 sub _emitTable { 640 my ($state) = @_; 641 642 my @result; 643 push( @result, 644 CGI::start_table( { border => 1, cellpadding => 0, cellspacing => 1 } ) 645 ); 646 647 #Flush out any remaining rowspans 648 for ( my $i = 0 ; $i < scalar( @{ $state->{rowspan} } ) ; $i++ ) { 649 if ( defined( $state->{rowspan}->[$i] ) && $state->{rowspan}->[$i] ) { 650 my $nRows = scalar( @{ $state->{curTable} } ); 651 my $rspan = $state->{rowspan}->[$i] + 1; 652 my $r = $nRows - $rspan; 653 $state->{curTable}->[$r][$i]->{attrs} ||= {}; 654 if ( $rspan > 1 ) { 655 $state->{curTable}->[$r][$i]->{attrs}->{rowspan} = $rspan; 656 } 657 } 658 } 659 660 my $rowCount = 0; 661 my $numberOfRows = scalar( @{ $state->{curTable} } ); 662 663 my @headerRowList = (); 664 my @bodyRowList = (); 665 666 my $isPastHeaderRows = 0; 667 668 foreach my $row ( @{ $state->{curTable} } ) { 669 my $rowtext = ''; 670 my $colCount = 0; 671 672 # keep track of header cells: if all cells are header cells, 673 # put the row in the thead section 674 my $headerCellCount = 0; 675 my $numberOfCols = scalar(@$row); 676 677 foreach my $fcell (@$row) { 678 679 # check if cell exists 680 next if ( !$fcell || !$fcell->{type} ); 681 682 my $tableAnchor = ''; 683 next 684 if ( $fcell->{type} eq 'X' ) 685 ; # data was there so sort could work with col spanning 686 my $type = $fcell->{type}; 687 my $cell = $fcell->{text}; 688 my $attr = $fcell->{attrs} || {}; 689 690 if ( $type eq 'th' ) { 691 $headerCellCount++; 692 } 693 else { 694 $type = 'td' unless $type eq 'Y'; 695 } ###if( $type eq 'th' ) 696 697 $colCount++; 698 next if ( $type eq 'Y' ); 699 my $fn = 'CGI::' . $type; 700 no strict 'refs'; 701 $rowtext .= &$fn( $attr, " $cell " ); 702 use strict 'refs'; 703 } # foreach my $fcell ( @$row ) 704 705 my $rowHTML = $state->{pre}->[$rowCount] . CGI::Tr($rowtext); 706 707 my $isHeaderRow = ( $headerCellCount == $colCount ); 708 if ( !$isHeaderRow ) { 709 710 # don't include non-adjacent header rows to the top block of header rows 711 $isPastHeaderRows = 1; 712 } 713 714 if ( $isHeaderRow && !$isPastHeaderRows ) { 715 push( @headerRowList, $rowHTML ); 716 } 717 else { 718 push @bodyRowList, $rowHTML; 719 } 720 721 $rowCount++; 722 } # foreach my $row ( @curTable ) 723 724 push @result, @headerRowList, @bodyRowList; 725 726 push @result, CGI::end_table(); 727 return @result; 531 728 } 532 729 … … 561 758 sub _protectVerbatimChars { 562 759 my $text = shift; 563 # $TT0, $TT1 and $TT2 are chr(0), chr(1) and chr(2), respectively. 760 761 # $TT0, $TT1 and $TT2 are chr(0), chr(1) and chr(2), respectively. 564 762 # They are handled specially, elsewhere 565 763 $text =~ s/([\003-\011\013-\037<&>'"])/'&#'.ord($1).';'/ges; -
trunk/WysiwygPlugin/lib/Foswiki/Plugins/WysiwygPlugin/build.pl
r3959 r5573 15 15 16 16 # Build the target on the command line, or the default target 17 $build->build( $build->{target});17 $build->build( $build->{target} ); 18 18 -
trunk/WysiwygPlugin/test/unit/WysiwygPlugin/ExtendedTranslatorTests.pm
r5240 r5573 36 36 # Bits for test type 37 37 # Fields in test records: 38 my $TML2HTML = 1 << 0;# test tml => html39 my $HTML2TML = 1 << 1;# test html => finaltml (default tml)40 my $ROUNDTRIP = 1 << 2;# test tml => => finaltml38 my $TML2HTML = 1 << 0; # test tml => html 39 my $HTML2TML = 1 << 1; # test html => finaltml (default tml) 40 my $ROUNDTRIP = 1 << 2; # test tml => => finaltml 41 41 my $CANNOTWYSIWYG = 1 << 3; # test that notWysiwygEditable returns true 42 42 # and make the ROUNDTRIP test expect failure … … 61 61 # is "WysiwygEditable". 62 62 # 63 # Use CANNOTWYSIWYG without ROUNDTRIP *only* with an appropriate 64 # explanation. For example: 63 # Use CANNOTWYSIWYG without ROUNDTRIP *only* with an appropriate 64 # explanation. For example: 65 65 # Can't ROUNDTRIP this TML because perl on the SMURF platform 66 66 # automagically replaces all instances of 'blue' with 'beautiful'. … … 85 85 # Each testcase is a subhash with fields as follows: 86 86 # exec => $TML2HTML to test TML -> HTML, $HTML2TML to test HTML -> TML, 87 # $ROUNDTRIP to test TML-> ->TML, $CANNOTWYSIWYG to test 87 # $ROUNDTRIP to test TML-> ->TML, $CANNOTWYSIWYG to test 88 88 # notWysiwygEditable, all other bits are ignored. 89 89 # They may be OR'd togoether to perform multiple tests. … … 102 102 my $data = [ 103 103 { 104 exec => $TML2HTML | $ROUNDTRIP, 105 name => 'UnspecifiedCustomXmlTag', 106 setup => sub { 107 $extraTML2HTMLOptions{xmltag} = \%Foswiki::Plugins::WysiwygPlugin::xmltag; 104 exec => $TML2HTML | $ROUNDTRIP, 105 name => 'UnspecifiedCustomXmlTag', 106 setup => sub { 107 $extraTML2HTMLOptions{xmltag} = 108 \%Foswiki::Plugins::WysiwygPlugin::xmltag; 108 109 }, 109 110 html => '<p>' … … 122 123 name => 'DisabledCustomXmlTag', 123 124 setup => sub { 124 $extraTML2HTMLOptions{xmltag} = \%Foswiki::Plugins::WysiwygPlugin::xmltag; 125 $extraTML2HTMLOptions{xmltag} = 126 \%Foswiki::Plugins::WysiwygPlugin::xmltag; 125 127 Foswiki::Plugins::WysiwygPlugin::addXMLTag( 'customtag', 126 128 sub { 0 } ); … … 141 143 name => 'CustomXmlTag', 142 144 setup => sub { 143 $extraTML2HTMLOptions{xmltag} = \%Foswiki::Plugins::WysiwygPlugin::xmltag; 145 $extraTML2HTMLOptions{xmltag} = 146 \%Foswiki::Plugins::WysiwygPlugin::xmltag; 144 147 Foswiki::Plugins::WysiwygPlugin::addXMLTag( 'customtag', 145 148 sub { 1 } ); … … 155 158 name => 'CustomXmlTagCallbackChangesText', 156 159 setup => sub { 157 $extraTML2HTMLOptions{xmltag} = \%Foswiki::Plugins::WysiwygPlugin::xmltag; 160 $extraTML2HTMLOptions{xmltag} = 161 \%Foswiki::Plugins::WysiwygPlugin::xmltag; 158 162 Foswiki::Plugins::WysiwygPlugin::addXMLTag( 'customtag', 159 163 sub { $_[0] =~ s/some/different/; return 1; } ); … … 170 174 name => 'CustomXmlTagDefaultCallback', 171 175 setup => sub { 172 $extraTML2HTMLOptions{xmltag} = \%Foswiki::Plugins::WysiwygPlugin::xmltag; 173 Foswiki::Plugins::WysiwygPlugin::addXMLTag( 'customtag' ); 176 $extraTML2HTMLOptions{xmltag} = 177 \%Foswiki::Plugins::WysiwygPlugin::xmltag; 178 Foswiki::Plugins::WysiwygPlugin::addXMLTag('customtag'); 174 179 }, 175 180 html => '<p>' … … 183 188 name => 'CustomXmlTagWithAttributes', 184 189 setup => sub { 185 $extraTML2HTMLOptions{xmltag} = \%Foswiki::Plugins::WysiwygPlugin::xmltag; 190 $extraTML2HTMLOptions{xmltag} = 191 \%Foswiki::Plugins::WysiwygPlugin::xmltag; 186 192 Foswiki::Plugins::WysiwygPlugin::addXMLTag( 'customtag', 187 193 sub { 1 } ); … … 201 207 name => 'NestedCustomXmlTagWithAttributes', 202 208 setup => sub { 203 $extraTML2HTMLOptions{xmltag} = \%Foswiki::Plugins::WysiwygPlugin::xmltag; 209 $extraTML2HTMLOptions{xmltag} = 210 \%Foswiki::Plugins::WysiwygPlugin::xmltag; 204 211 Foswiki::Plugins::WysiwygPlugin::addXMLTag( 'customtag', 205 212 sub { 1 } ); … … 226 233 { 227 234 exec => $CANNOTWYSIWYG, 235 228 236 # Do not perform ROUNDTRIP on this TML, because ROUNDTRIP passes. 229 # The problem with this TML is that the special handling of 230 # <verbatim> in the conversion to HTML messes up the contents 231 # of this custom XML tag, so that the HTML is not representative 237 # The problem with this TML is that the special handling of 238 # <verbatim> in the conversion to HTML messes up the contents 239 # of this custom XML tag, so that the HTML is not representative 232 240 # of the TML in terms of intellectual content. 233 name => 'VerbatimInsideDot',234 setup => sub { 235 $extraTML2HTMLOptions{xmltag} = \%Foswiki::Plugins::WysiwygPlugin::xmltag;236 Foswiki::Plugins::WysiwygPlugin::addXMLTag( 'dot',237 sub { 1 } );241 name => 'VerbatimInsideDot', 242 setup => sub { 243 $extraTML2HTMLOptions{xmltag} = 244 \%Foswiki::Plugins::WysiwygPlugin::xmltag; 245 Foswiki::Plugins::WysiwygPlugin::addXMLTag( 'dot', sub { 1 } ); 238 246 }, 239 247 tml => <<'DOT', … … 249 257 }, 250 258 { 251 exec => $TML2HTML | $ROUNDTRIP, 252 name => 'CustomtagInsideSticky', 253 setup => sub { 254 $extraTML2HTMLOptions{xmltag} = \%Foswiki::Plugins::WysiwygPlugin::xmltag; 259 exec => $TML2HTML | $ROUNDTRIP, 260 name => 'CustomtagInsideSticky', 261 setup => sub { 262 $extraTML2HTMLOptions{xmltag} = 263 \%Foswiki::Plugins::WysiwygPlugin::xmltag; 255 264 Foswiki::Plugins::WysiwygPlugin::addXMLTag( 'customtag', 256 265 sub { 1 } ); 257 266 }, 258 tml => "<sticky><customtag>this & that\n > the other </customtag></sticky>", 267 tml => 268 "<sticky><customtag>this & that\n > the other </customtag></sticky>", 259 269 html => '<p>' 260 270 . '<div class="WYSIWYG_STICKY">' … … 262 272 . 'this & that<br /> > the other ' 263 273 . '</customtag>' 264 . '</div>' 265 . '</p>'266 },267 {268 exec => $ROUNDTRIP | $CANNOTWYSIWYG, #SMELL: fix this case269 name => 'StickyInsideCustomtag',270 setup => sub {271 $extraTML2HTMLOptions{xmltag} =\%Foswiki::Plugins::WysiwygPlugin::xmltag;274 . '</div>' . '</p>' 275 }, 276 { 277 exec => $ROUNDTRIP | $CANNOTWYSIWYG, #SMELL: fix this case 278 name => 'StickyInsideCustomtag', 279 setup => sub { 280 $extraTML2HTMLOptions{xmltag} = 281 \%Foswiki::Plugins::WysiwygPlugin::xmltag; 272 282 Foswiki::Plugins::WysiwygPlugin::addXMLTag( 'customtag', 273 283 sub { 1 } ); 274 284 }, 275 tml => "<customtag>this <sticky>& that\n > the</sticky> other </customtag>", 285 tml => 286 "<customtag>this <sticky>& that\n > the</sticky> other </customtag>", 276 287 html => '<p>' 277 288 . $protecton … … 283 294 . ' other ' 284 295 . '</customtag>' 285 . $protectoff 286 . '</p>' 287 }, 288 { 289 exec => $TML2HTML | $ROUNDTRIP, 290 name => 'StickyInsideUnspecifiedCustomtag', 291 setup => sub { 292 $extraTML2HTMLOptions{xmltag} = \%Foswiki::Plugins::WysiwygPlugin::xmltag; 293 }, 294 tml => "<customtag>this <sticky>& that\n > the</sticky> other </customtag>", 296 . $protectoff . '</p>' 297 }, 298 { 299 exec => $TML2HTML | $ROUNDTRIP, 300 name => 'StickyInsideUnspecifiedCustomtag', 301 setup => sub { 302 $extraTML2HTMLOptions{xmltag} = 303 \%Foswiki::Plugins::WysiwygPlugin::xmltag; 304 }, 305 tml => 306 "<customtag>this <sticky>& that\n > the</sticky> other </customtag>", 295 307 html => '<p>' 296 308 . $protecton 297 309 . '<customtag>' 298 . $protectoff 299 . 'this' 310 . $protectoff . 'this' 300 311 . '<div class="WYSIWYG_STICKY">' 301 312 . '& that<br /> > the' 302 . '</div>' 303 . 'other' 313 . '</div>' . 'other' 304 314 . $protecton 305 315 . '</customtag>' 306 . $protectoff 307 . '</p>' 308 }, 309 { 310 exec => $ROUNDTRIP, 311 name => 'UnspecifiedCustomtagInsideSticky', 312 setup => sub { 313 $extraTML2HTMLOptions{xmltag} = \%Foswiki::Plugins::WysiwygPlugin::xmltag; 314 }, 315 tml => "<sticky><customtag>this & that\n > the other </customtag></sticky>" 316 }, 317 { 318 exec => $TML2HTML | $ROUNDTRIP, 319 name => 'CustomtagInsideLiteral', 320 setup => sub { 321 $extraTML2HTMLOptions{xmltag} = \%Foswiki::Plugins::WysiwygPlugin::xmltag; 316 . $protectoff . '</p>' 317 }, 318 { 319 exec => $ROUNDTRIP, 320 name => 'UnspecifiedCustomtagInsideSticky', 321 setup => sub { 322 $extraTML2HTMLOptions{xmltag} = 323 \%Foswiki::Plugins::WysiwygPlugin::xmltag; 324 }, 325 tml => 326 "<sticky><customtag>this & that\n > the other </customtag></sticky>" 327 }, 328 { 329 exec => $TML2HTML | $ROUNDTRIP, 330 name => 'CustomtagInsideLiteral', 331 setup => sub { 332 $extraTML2HTMLOptions{xmltag} = 333 \%Foswiki::Plugins::WysiwygPlugin::xmltag; 322 334 Foswiki::Plugins::WysiwygPlugin::addXMLTag( 'customtag', 323 335 sub { 1 } ); 324 336 }, 325 tml => '<literal><customtag>this & that > the other </customtag></literal>', 337 tml => 338 '<literal><customtag>this & that > the other </customtag></literal>', 326 339 html => '<p>' 327 340 . '<div class="WYSIWYG_LITERAL">' 328 341 . '<customtag>this & that > the other </customtag>' 329 . '</div>' 330 . '</p>' 331 }, 332 { 333 exec => $TML2HTML | $ROUNDTRIP, 334 name => 'UnspecifiedCustomtagInsideLiteral', 335 setup => sub { 336 $extraTML2HTMLOptions{xmltag} = \%Foswiki::Plugins::WysiwygPlugin::xmltag; 337 }, 338 tml => '<literal><customtag>this & that > the other </customtag></literal>', 342 . '</div>' . '</p>' 343 }, 344 { 345 exec => $TML2HTML | $ROUNDTRIP, 346 name => 'UnspecifiedCustomtagInsideLiteral', 347 setup => sub { 348 $extraTML2HTMLOptions{xmltag} = 349 \%Foswiki::Plugins::WysiwygPlugin::xmltag; 350 }, 351 tml => 352 '<literal><customtag>this & that > the other </customtag></literal>', 339 353 html => '<p>' 340 354 . '<div class="WYSIWYG_LITERAL">' 341 355 . '<customtag>this & that > the other </customtag>' 342 . '</div>' 343 . '</p>'344 },345 {346 exec => $ROUNDTRIP | $CANNOTWYSIWYG, #SMELL: Fix this case347 name => 'LiteralInsideCustomtag',348 setup => sub {349 $extraTML2HTMLOptions{xmltag} =\%Foswiki::Plugins::WysiwygPlugin::xmltag;356 . '</div>' . '</p>' 357 }, 358 { 359 exec => $ROUNDTRIP | $CANNOTWYSIWYG, #SMELL: Fix this case 360 name => 'LiteralInsideCustomtag', 361 setup => sub { 362 $extraTML2HTMLOptions{xmltag} = 363 \%Foswiki::Plugins::WysiwygPlugin::xmltag; 350 364 Foswiki::Plugins::WysiwygPlugin::addXMLTag( 'customtag', 351 365 sub { 1 } ); 352 366 }, 353 tml => '<customtag>this <literal>& that > the</literal> other </customtag>', 367 tml => 368 '<customtag>this <literal>& that > the</literal> other </customtag>', 354 369 html => '<p>' 355 370 . '<div class="WYSIWYG_LITERAL">' 356 371 . '<customtag>this & that > the other </customtag>' 357 . '</div>' 358 . '</p>' 359 }, 360 { 361 exec => $TML2HTML | $ROUNDTRIP, 362 name => 'LiteralInsideUnspecifiedCustomtag', 363 setup => sub { 364 $extraTML2HTMLOptions{xmltag} = \%Foswiki::Plugins::WysiwygPlugin::xmltag; 365 }, 366 tml => '<customtag>this <literal>& that > the</literal> other </customtag>', 372 . '</div>' . '</p>' 373 }, 374 { 375 exec => $TML2HTML | $ROUNDTRIP, 376 name => 'LiteralInsideUnspecifiedCustomtag', 377 setup => sub { 378 $extraTML2HTMLOptions{xmltag} = 379 \%Foswiki::Plugins::WysiwygPlugin::xmltag; 380 }, 381 tml => 382 '<customtag>this <literal>& that > the</literal> other </customtag>', 367 383 html => '<p>' 368 384 . $protecton 369 385 . '<customtag>' 370 . $protectoff 371 . 'this' 386 . $protectoff . 'this' 372 387 . '<div class="WYSIWYG_LITERAL">' 373 388 . '& that > the' 374 . '</div>' 375 .'other' 389 . '</div>' . 'other' 376 390 . $protecton 377 391 . '</customtag>' 378 . $protectoff 379 . '</p>' 380 }, 381 { 382 # There will probably always be some markup that WysiwygPlugin cannot convert, 383 # but it is not always easy to say what that markup is. 384 # This test case checks the protection of unconvertable text 385 # by using valid markup and forcing the conversion to fail. 392 . $protectoff . '</p>' 393 }, 394 { 395 396 # There will probably always be some markup that WysiwygPlugin cannot convert, 397 # but it is not always easy to say what that markup is. 398 # This test case checks the protection of unconvertable text 399 # by using valid markup and forcing the conversion to fail. 400 exec => $TML2HTML | $ROUNDTRIP, 401 name => 'UnconvertableTextIsProtected', 402 setup => sub { 403 404 # Disable "dieOnError" to test the "protect unconvertable text" behaviour 405 # which can be exercised via the REST handler 406 $extraTML2HTMLOptions{dieOnError} = 0; 407 408 # Override the standard expansion function to hack in an illegal character to force the conversion to fail 409 $extraTML2HTMLOptions{expandVarsInURL} = sub { return "\0"; }; 410 }, 411 tml => '<img src="%PUBURLPATH%">', 412 html => 413 '<div class="WYSIWYG_PROTECTED"><img src="%PUBURLPATH%"></div>' 414 }, 415 { 416 exec => $HTML2TML | $ROUNDTRIP, 417 name => 'TableWithRowSpan_NoTablePlugin', 418 setup => 419 sub { Foswiki::Func::getContext()->{'TablePluginEnabled'} = 0; }, 420 html => <<HTML, 421 <table cellspacing="1" cellpadding="0" border="1"> 422 <tr><td rowspan="2">A</td><td rowspan="3">B</td><td>X</td></tr> 423 <tr><td rowspan="2">C</td></tr> 424 <tr><td>M</td></tr> 425 </table> 426 HTML 427 tml => <<TML, 428 <table cellspacing="1" cellpadding="0" border="1"> <tr><td rowspan="2">A</td><td rowspan="3">B</td><td>X</td></tr> <tr><td rowspan="2">C</td></tr> <tr><td>M</td></tr> </table> 429 TML 430 }, 431 { 386 432 exec => $TML2HTML | $ROUNDTRIP, 387 name => 'UnconvertableTextIsProtected', 388 setup => sub { 389 # Disable "dieOnError" to test the "protect unconvertable text" behaviour 390 # which can be exercised via the REST handler 391 $extraTML2HTMLOptions{dieOnError} = 0; 392 393 # Override the standard expansion function to hack in an illegal character to force the conversion to fail 394 $extraTML2HTMLOptions{expandVarsInURL} = sub { return "\0"; }; 395 }, 396 tml => '<img src="%PUBURLPATH%">', 397 html => '<div class="WYSIWYG_PROTECTED"><img src="%PUBURLPATH%"></div>' 433 name => 'simpleTable_NoTablePlugin', 434 setup => 435 sub { Foswiki::Func::getContext()->{'TablePluginEnabled'} = 0; }, 436 html => <<'HERE', 437 <p> 438 Before 439 </p> 440 <table border="1" cellpadding="0" cellspacing="1"><tr><th>L</th><th>C</th><th>R</th></tr><tr><td> A2</td><td style="text-align: center" class="align-center"> 2</td><td style="text-align: right" class="align-right"> 2</td></tr><tr><td> A3</td><td style="text-align: center" class="align-center"> 3</td><td style="text-align: left" class="align-left"> 3</td></tr><tr><td> A4-6</td><td> four</td><td> four</td></tr><tr><td>^</td><td> five</td><td> five</td></tr></table><p /><table border="1" cellpadding="0" cellspacing="1"><tr><td>^</td><td> six</td><td> six</td></tr></table> 441 After 442 HERE 443 tml => <<'HERE', 444 Before 445 | *L* | *C* | *R* | 446 | A2 | 2 | 2 | 447 | A3 | 3 | 3 | 448 | A4-6 | four | four | 449 |^| five | five | 450 451 |^| six | six | 452 After 453 454 HERE 455 finaltml => <<'HERE', 456 Before 457 | *L* | *C* | *R* | 458 | A2 | 2 | 2 | 459 | A3 | 3 | 3 | 460 | A4-6 | four | four | 461 | ^ | five | five | 462 463 | ^ | six | six | 464 After 465 HERE 466 }, 467 { 468 exec => $HTML2TML, 469 name => 'ttClassInTable_NoTablePlugin', 470 setup => 471 sub { Foswiki::Func::getContext()->{'TablePluginEnabled'} = 0; }, 472 html => '<table><tr><td class="WYSIWYG_TT">Code</td></tr></table>', 473 tml => '| =Code= |' 474 }, 475 { 476 exec => $TML2HTML | $ROUNDTRIP, 477 name => 'tmlInTable_NoTablePlugin', 478 setup => 479 sub { Foswiki::Func::getContext()->{'TablePluginEnabled'} = 0; }, 480 html => <<'BLAH', 481 <table cellspacing="1" cellpadding="0" border="1"> 482 <tr><td> <span class="WYSIWYG_TT">Code</span> </td></tr> 483 <tr><td> <span class="WYSIWYG_TT">code</span> at start</td></tr> 484 <tr><td>ends with <span class="WYSIWYG_TT">code</span> </td></tr> 485 486 <tr><td> <b><span class="WYSIWYG_TT">Code</span></b> </td></tr> 487 <tr><td> <b><span class="WYSIWYG_TT">code</span></b> at start</td></tr> 488 <tr><td>ends with <b><span class="WYSIWYG_TT">code</span></b> </td></tr> 489 490 <tr><td> <i>Emphasis</i> </td></tr> 491 <tr><td> <i>emphasis</i> at start</td></tr> 492 <tr><td>ends with <i>emphasis</i> </td></tr> 493 494 <tr><td> <b><i>Emphasis</i></b> </td></tr> 495 <tr><td> <b><i>emphasis</i></b> at start</td></tr> 496 <tr><td>ends with <b><i>emphasis</i></b> </td></tr> 497 498 <tr><td> <b>bold</b> at start</td></tr> 499 <tr><td>ends with <b>bold</b> </td></tr> 500 </table> 501 BLAH 502 tml => <<'BLAH', 503 | =Code= | 504 | =code= at start | 505 | ends with =code= | 506 | ==Code== | 507 | ==code== at start | 508 | ends with ==code== | 509 | _Emphasis_ | 510 | _emphasis_ at start | 511 | ends with _emphasis_ | 512 | __Emphasis__ | 513 | __emphasis__ at start | 514 | ends with __emphasis__ | 515 | *bold* at start | 516 | ends with *bold* | 517 BLAH 518 }, 519 { 520 exec => $HTML2TML, 521 name => 'kupuTable_NoTablePlugin', 522 setup => 523 sub { Foswiki::Func::getContext()->{'TablePluginEnabled'} = 0; }, 524 html => 525 '<table cellspacing="0" cellpadding="8" border="1" class="plain" _moz_resizing="true"> 526 <tbody> 527 <tr>a0<td>a1</td><td>a2</td><td>a3</td></tr> 528 <tr>b0<td colspan="2">b1</td><td>b3</td></tr> 529 <tr>c0<td>c1</td><td>c2</td><td>c3</td></tr> 530 </tbody> 531 </table>', 532 tml => '| a1 | a2 | a3 | 533 | b1 || b3 | 534 | c1 | c2 | c3 | 535 ', 536 }, 537 { 538 exec => $TML2HTML | $ROUNDTRIP, 539 name => 'tableWithColSpans_NoTablePlugin', 540 setup => 541 sub { Foswiki::Func::getContext()->{'TablePluginEnabled'} = 0; }, 542 html => '<p>abcd 543 </p> 544 <table cellspacing="1" cellpadding="0" border="1"> 545 <tr><td colspan="2">efg</td><td> </td></tr> 546 <tr><td colspan="3"></td></tr></table> 547 hijk', 548 tml => 'abcd 549 | efg || | 550 |||| 551 hijk', 552 finaltml => 'abcd 553 | efg || | 554 | ||| 555 hijk', 556 }, 557 { 558 exec => $ROUNDTRIP, 559 name => 'Item4410_NoTablePlugin', 560 setup => 561 sub { Foswiki::Func::getContext()->{'TablePluginEnabled'} = 0; }, 562 tml => <<'HERE', 563 * x 564 | Y | 565 HERE 566 html => 567 '<ul><li>x</li></ul><table cellspacing="1" cellpadding="0" border="1"><tr><td>Y</td></tr></table>', 568 }, 569 { 570 exec => $HTML2TML, 571 name => 'tableInnaBun_NoTablePlugin', 572 setup => 573 sub { Foswiki::Func::getContext()->{'TablePluginEnabled'} = 0; }, 574 html => <<'JUNK', 575 <ul> 576 <li> List item</li><li><table><tbody><tr><td> 11</td><td> 21</td></tr><tr><td>12 </td><td> 22</td></tr></tbody></table></li><li>crap</li> 577 </ul> 578 JUNK 579 tml => <<JUNX, 580 * List item 581 * <table><tbody><tr><td> 11</td><td> 21</td></tr><tr><td>12 </td><td> 22</td></tr></tbody></table> 582 * crap 583 JUNX 584 }, 585 { 586 exec => $TML2HTML | $HTML2TML, 587 name => 'Item4700_NoTablePlugin', 588 setup => 589 sub { Foswiki::Func::getContext()->{'TablePluginEnabled'} = 0; }, 590 tml => <<EXPT, 591 | ex | per | iment | 592 | exper | iment || 593 | expe || riment | 594 || exper | iment | 595 EXPT 596 finaltml => <<EXPT, 597 | ex | per | iment | 598 | exper | iment || 599 | expe || riment | 600 | | exper | iment | 601 EXPT 602 html => <<HEXPT, 603 <table cellspacing="1" cellpadding="0" border="1"> 604 <tr><td>ex</td><td>per</td><td>iment</td></tr> 605 <tr><td>exper</td><td colspan="2">iment</td></tr> 606 <tr><td colspan="2">expe</td><td>riment</td></tr> 607 <tr><td></td><td>exper</td><td>iment</td></tr> 608 </table> 609 HEXPT 610 }, 611 { 612 exec => $ROUNDTRIP, 613 name => 'Item4700_2_NoTablePlugin', 614 setup => 615 sub { Foswiki::Func::getContext()->{'TablePluginEnabled'} = 0; }, 616 tml => <<EXPT, 617 | ex | per | iment | 618 | exper | iment || 619 | expe || riment | 620 | | exper | iment | 621 EXPT 622 html => <<HEXPT, 623 <table cellspacing="1" cellpadding="0" border="1"> 624 <tr><td>ex</td><td>per</td><td>iment</td></tr> 625 <tr><td>exper</td><td colspan="2">iment</td></tr> 626 <tr><td colspan="2">expe</td><td>riment</td></tr> 627 <tr><td></td><td>exper</td><td>iment</td></tr> 628 </table> 629 HEXPT 630 }, 631 { 632 name => 'Item4855_NoTablePlugin', 633 setup => 634 sub { Foswiki::Func::getContext()->{'TablePluginEnabled'} = 0; }, 635 exec => $TML2HTML, 636 tml => <<HERE, 637 | [[LegacyTopic1]] | Main.SomeGuy | 638 %TABLESEP% 639 %SEARCH{"legacy" nonoise="on" format="| [[\$topic]] | [[\$wikiname]] |"}% 640 HERE 641 html => <<THERE, 642 <table cellspacing="1" cellpadding="0" border="1"> 643 <tr><td><span class="WYSIWYG_LINK">[[LegacyTopic1]]</span></td><td><span class="WYSIWYG_LINK">Main.SomeGuy</span></td></tr> 644 </table> 645 <span class="WYSIWYG_PROTECTED"><br />%TABLESEP%</span> 646 <span class="WYSIWYG_PROTECTED"><br />%SEARCH{"legacy" nonoise="on" format="| [[\$topic]] | [[\$wikiname]] |"}%</span> 647 THERE 648 }, 649 { 650 name => 'Item1798_NoTablePlugin', 651 setup => 652 sub { Foswiki::Func::getContext()->{'TablePluginEnabled'} = 0; }, 653 exec => $ROUNDTRIP | $TML2HTML, 654 tml => <<HERE, 655 | [[LegacyTopic1]] | Main.SomeGuy | 656 %SEARCH{"legacy" nonoise="on" format="| [[\$topic]] | [[\$wikiname]] |"}% 657 HERE 658 html => <<THERE, 659 <table cellspacing="1" cellpadding="0" border="1"> 660 <tr><td><span class="WYSIWYG_LINK">[[LegacyTopic1]]</span></td><td><span class="WYSIWYG_LINK">Main.SomeGuy</span></td></tr> 661 </table> 662 <span class="WYSIWYG_PROTECTED"><br />%SEARCH{"legacy" nonoise="on" format="| [[\$topic]] | [[\$wikiname]] |"}%</span> 663 THERE 664 }, 665 { 666 exec => $HTML2TML | $ROUNDTRIP, 667 name => 'colorClassInTable_NoTablePlugin', 668 setup => 669 sub { Foswiki::Func::getContext()->{'TablePluginEnabled'} = 0; }, 670 html => <<'BLAH', 671 <table> 672 <tr><th class="WYSIWYG_COLOR" style="color:#FF0000;">Red Heading</th></tr> 673 <tr><td class="WYSIWYG_COLOR" style="color:#FF0000;">Red herring</td></tr> 674 </table> 675 BLAH 676 tml => <<'BLAH', 677 | *%RED%Red Heading%ENDCOLOR%* | 678 | %RED%Red herring%ENDCOLOR% | 679 BLAH 680 }, 681 { 682 exec => $HTML2TML | $ROUNDTRIP, 683 name => 'colorAndTtClassInTable_NoTablePlugin', 684 setup => 685 sub { Foswiki::Func::getContext()->{'TablePluginEnabled'} = 0; }, 686 html => <<'BLAH', 687 <table> 688 <tr><th class="WYSIWYG_COLOR WYSIWYG_TT" style="color:#FF0000;">Redder code</th></tr> 689 <tr><td class="WYSIWYG_COLOR WYSIWYG_TT" style="color:#FF0000;">Red code</td></tr> 690 </table> 691 BLAH 692 tml => <<'BLAH', 693 | *%RED% =Redder code= %ENDCOLOR%* | 694 | %RED% =Red code= %ENDCOLOR% | 695 BLAH 696 }, 697 { 698 name => 'Item4969_NoTablePlugin', 699 setup => 700 sub { Foswiki::Func::getContext()->{'TablePluginEnabled'} = 0; }, 701 exec => $HTML2TML, 702 html => <<HERE, 703 <table cellspacing="1" cellpadding="0" border="1"> 704 <tr><td>table element with a <hr /> horizontal rule</td></tr> 705 </table> 706 Mad Fish 707 HERE 708 tml => '| table element with a <hr /> horizontal rule | 709 Mad Fish', 710 }, 711 { 712 name => 'Item5076_NoTablePlugin', 713 setup => 714 sub { Foswiki::Func::getContext()->{'TablePluginEnabled'} = 0; }, 715 exec => $HTML2TML, 716 html => <<HERE, 717 <table border="0"><tbody><tr><td><h2>Argh</h2><ul><li>Ergh </li></ul></td><td> </td></tr><tr><td> </td><td> </td></tr></tbody></table> 718 HERE 719 tml => '<table border="0"><tbody><tr><td> 720 ---++ Argh 721 * Ergh 722 </td><td> </td></tr><tr><td> </td><td> </td></tr></tbody></table>', 398 723 }, 399 724 ]; … … 409 734 my $fn = 'ExtendedTranslatorTests::testTML2HTML_' . $datum->{name}; 410 735 no strict 'refs'; 411 *$fn = sub { 412 my $this = shift; 413 $this->testSpecificSetup($datum); 414 $this->compareTML_HTML($datum); 736 *$fn = sub { 737 my $this = shift; 738 $this->testSpecificSetup($datum); 739 $this->compareTML_HTML($datum); 415 740 $this->testSpecificCleanup($datum); 416 741 }; … … 420 745 my $fn = 'ExtendedTranslatorTests::testHTML2TML_' . $datum->{name}; 421 746 no strict 'refs'; 422 *$fn = sub { 747 *$fn = sub { 423 748 my $this = shift; 424 $this->testSpecificSetup($datum); 749 $this->testSpecificSetup($datum); 425 750 $this->compareHTML_TML($datum); 426 751 $this->testSpecificCleanup($datum); … … 433 758 *$fn = sub { 434 759 my $this = shift; 435 $this->testSpecificSetup($datum); 760 $this->testSpecificSetup($datum); 436 761 $this->compareRoundTrip($datum); 437 762 $this->testSpecificCleanup($datum); … … 442 767 my $fn = 'TranslatorTests::testCANNOTWYSIWYG_' . $datum->{name}; 443 768 no strict 'refs'; 444 *$fn = sub { 769 *$fn = sub { 445 770 my $this = shift; 446 $this->testSpecificSetup($datum); 771 $this->testSpecificSetup($datum); 447 772 $this->compareNotWysiwygEditable($datum); 448 773 $this->testSpecificCleanup($datum); … … 455 780 sub testSpecificSetup { 456 781 my ( $this, $args ) = @_; 782 457 783 # Reset the extendable parts of WysiwygPlugin 458 784 %Foswiki::Plugins::WysiwygPlugin::xmltag = (); … … 474 800 } 475 801 476 sub TML_HTMLconverterOptions 477 { 478 my $this = shift; 802 sub TML_HTMLconverterOptions { 803 my $this = shift; 479 804 my $options = $this->SUPER::TML_HTMLconverterOptions(@_); 480 for my $extraOptionName ( keys %extraTML2HTMLOptions) {805 for my $extraOptionName ( keys %extraTML2HTMLOptions ) { 481 806 $options->{$extraOptionName} = $extraTML2HTMLOptions{$extraOptionName}; 482 807 } -
trunk/WysiwygPlugin/test/unit/WysiwygPlugin/TranslatorTests.pm
r5503 r5573 36 36 # Bits for test type 37 37 # Fields in test records: 38 my $TML2HTML = 1 << 0;# test tml => html39 my $HTML2TML = 1 << 1;# test html => finaltml (default tml)40 my $ROUNDTRIP = 1 << 2;# test tml => => finaltml38 my $TML2HTML = 1 << 0; # test tml => html 39 my $HTML2TML = 1 << 1; # test html => finaltml (default tml) 40 my $ROUNDTRIP = 1 << 2; # test tml => => finaltml 41 41 my $CANNOTWYSIWYG = 1 << 3; # test that notWysiwygEditable returns true 42 42 # and make the ROUNDTRIP test expect failure … … 61 61 # is "WysiwygEditable". 62 62 # 63 # Use CANNOTWYSIWYG without ROUNDTRIP *only* with an appropriate 64 # explanation. For example: 63 # Use CANNOTWYSIWYG without ROUNDTRIP *only* with an appropriate 64 # explanation. For example: 65 65 # Can't ROUNDTRIP this TML because perl on the SMURF platform 66 66 # automagically replaces all instances of 'blue' with 'beautiful'. … … 82 82 # Each testcase is a subhash with fields as follows: 83 83 # exec => $TML2HTML to test TML -> HTML, $HTML2TML to test HTML -> TML, 84 # $ROUNDTRIP to test TML-> ->TML, $CANNOTWYSIWYG to test 84 # $ROUNDTRIP to test TML-> ->TML, $CANNOTWYSIWYG to test 85 85 # notWysiwygEditable, all other bits are ignored. 86 86 # They may be OR'd togoether to perform multiple tests. … … 410 410 <div align="center">TEST Centered text.</div> 411 411 HERE 412 tml => <<'HERE',412 tml => <<'HERE', 413 413 <center>Center Text</center><br /> <div style="text-align:center">TEST Centered text.</div> 414 414 … … 425 425 HERE 426 426 }, 427 428 429 427 430 428 { … … 1623 1621 }, 1624 1622 { 1623 exec => $TML2HTML | $ROUNDTRIP, 1624 name => 'RowSpan1', 1625 tml => <<EXPT, 1626 | A | B | 1627 | C | ^ | 1628 EXPT 1629 html => <<HEXPT, 1630 <table border="1" cellpadding="0" cellspacing="1"> 1631 <tr><td>A</td><td rowspan="2">B</td></tr> 1632 <tr><td>C</td></tr> 1633 </table> 1634 HEXPT 1635 }, 1636 { 1637 exec => $TML2HTML | $ROUNDTRIP, 1638 name => 'RowSpan2', 1639 tml => <<EXPT, 1640 | A | B | 1641 | ^ | C | 1642 EXPT 1643 html => <<HEXPT, 1644 <table border="1" cellpadding="0" cellspacing="1"> 1645 <tr><td rowspan="2">A</td><td>B</td></tr> 1646 <tr><td>C</td></tr> 1647 </table> 1648 HEXPT 1649 }, 1650 { 1651 exec => $TML2HTML | $ROUNDTRIP, 1652 name => 'RowSpan3', 1653 tml => <<EXPT, 1654 | A | B | X | 1655 | ^ | ^ | C | 1656 EXPT 1657 html => <<HEXPT, 1658 <table border="1" cellpadding="0" cellspacing="1"> 1659 <tr><td rowspan="2">A</td><td rowspan="2">B</td><td>X</td></tr> 1660 <tr><td>C</td></tr> 1661 </table> 1662 HEXPT 1663 }, 1664 { 1665 exec => $TML2HTML | $ROUNDTRIP, 1666 name => 'RowSpan4', 1667 tml => <<EXPT, 1668 | A | B | X | 1669 | ^ | ^ | C | 1670 | M | ^ | ^ | 1671 EXPT 1672 html => <<HEXPT, 1673 <table border="1" cellpadding="0" cellspacing="1"> 1674 <tr><td rowspan="2">A</td><td rowspan="3">B</td><td>X</td></tr> 1675 <tr><td rowspan="2">C</td></tr> 1676 <tr><td>M</td></tr> 1677 </table> 1678 HEXPT 1679 }, 1680 { 1681 exec => $TML2HTML | $ROUNDTRIP, 1682 name => 'RowSpan5', 1683 tml => <<EXPT, 1684 | A | B | X | 1685 | ^ | ^ | C | 1686 | M | ^ | 1687 EXPT 1688 html => <<HEXPT, 1689 <table border="1" cellpadding="0" cellspacing="1"> 1690 <tr><td rowspan="2">A</td><td rowspan="3">B</td><td>X</td></tr> 1691 <tr><td>C</td></tr> 1692 <tr><td>M</td></tr> 1693 </table> 1694 HEXPT 1695 DISABLEDfinaltml => <<FEXPT, 1696 | A | B | X | 1697 | ^ | ^ | C | 1698 | M | ^ | | 1699 FEXPT 1700 }, 1701 { 1702 exec => $TML2HTML | $ROUNDTRIP, 1703 name => 'mergedRowsAndColumnsCentre', 1704 tml => <<EXPT, 1705 | A1 | A2 | A3 | A4 | 1706 | B1 | X || B4 | 1707 | C1 | ^ | C4 | 1708 | D1 | D2 | D3 | D4 | 1709 EXPT 1710 html => <<HEXPT, 1711 <table border="1" cellpadding="0" cellspacing="1"> 1712 <tr><td>A1</td><td>A2</td><td>A3</td><td>A4</td></tr> 1713 <tr><td>B1</td><td rowspan="2" colspan="2">X</td><td>B4</td></tr> 1714 <tr><td>C1</td><td>C4</td></tr> 1715 <tr><td>D1</td><td>D2</td><td>D3</td><td>D4</td></tr> 1716 </table> 1717 HEXPT 1718 }, 1719 { 1720 exec => $TML2HTML | $ROUNDTRIP, 1721 name => 'mergedRowsAndColumnsTopLeft', 1722 tml => <<EXPT, 1723 | X || A3 | 1724 | ^ | B3 | 1725 | C1 | C2 | C3 | 1726 EXPT 1727 html => <<HEXPT, 1728 <table border="1" cellpadding="0" cellspacing="1"> 1729 <tr><td rowspan="2" colspan="2">X</td><td>A3</td></tr> 1730 <tr><td>B3</td></tr> 1731 <tr><td>C1</td><td>C2</td><td>C3</td></tr> 1732 </table> 1733 HEXPT 1734 }, 1735 { 1736 exec => $TML2HTML | $ROUNDTRIP, 1737 name => 'mergedRowsAndColumnsTopRight', 1738 tml => <<EXPT, 1739 | A1 | X || 1740 | B1 | ^ | 1741 | C1 | C2 | C3 | 1742 EXPT 1743 html => <<HEXPT, 1744 <table border="1" cellpadding="0" cellspacing="1"> 1745 <tr><td>A1</td><td rowspan="2" colspan="2">X</td></tr> 1746 <tr><td>B1</td></tr> 1747 <tr><td>C1</td><td>C2</td><td>C3</td></tr> 1748 </table> 1749 HEXPT 1750 }, 1751 { 1752 exec => $TML2HTML | $ROUNDTRIP, 1753 name => 'mergedRowsAndColumnsBottomLeft', 1754 tml => <<EXPT, 1755 | A1 | A2 | A3 | 1756 | X || B3 | 1757 | ^ | C3 | 1758 EXPT 1759 html => <<HEXPT, 1760 <table border="1" cellpadding="0" cellspacing="1"> 1761 <tr><td>A1</td><td>A2</td><td>A3</td></tr> 1762 <tr><td rowspan="2" colspan="2">X</td><td>B3</td></tr> 1763 <tr><td>C3</td></tr> 1764 </table> 1765 HEXPT 1766 }, 1767 { 1768 exec => $TML2HTML | $ROUNDTRIP, 1769 name => 'mergedRowsAndColumnsBottomRight', 1770 tml => <<EXPT, 1771 | A1 | A2 | A3 | 1772 | B1 | X || 1773 | C1 | ^ | 1774 EXPT 1775 html => <<HEXPT, 1776 <table border="1" cellpadding="0" cellspacing="1"> 1777 <tr><td>A1</td><td>A2</td><td>A3</td></tr> 1778 <tr><td>B1</td><td rowspan="2" colspan="2">X</td></tr> 1779 <tr><td>C1</td></tr> 1780 </table> 1781 HEXPT 1782 }, 1783 { 1784 exec => $TML2HTML | $ROUNDTRIP, 1785 name => 'notAlwaysRowSpan', 1786 tml => <<EXPT, 1787 | ^ | B | 1788 | ^ | <nop>^ | 1789 EXPT 1790 html => <<HEXPT, 1791 <table border="1" cellpadding="0" cellspacing="1"> 1792 <tr><td rowspan="2">^</td><td>B</td></tr> 1793 <tr><td>$protecton<nop>$protectoff^</td></tr> 1794 </table> 1795 HEXPT 1796 }, 1797 { 1625 1798 exec => $HTML2TML | $ROUNDTRIP, 1626 1799 name => 'collapse', … … 1805 1978 html => <<THERE, 1806 1979 <table cellspacing="1" cellpadding="0" border="1"> 1807 <tr><td><span class="WYSIWYG_LINK">[[LegacyTopic1]]</span></td><td> Main.SomeGuy</td></tr>1980 <tr><td><span class="WYSIWYG_LINK">[[LegacyTopic1]]</span></td><td><span class="WYSIWYG_LINK">Main.SomeGuy</span></td></tr> 1808 1981 </table> 1809 1982 <span class="WYSIWYG_PROTECTED"><br />%TABLESEP%</span> … … 1820 1993 html => <<THERE, 1821 1994 <table cellspacing="1" cellpadding="0" border="1"> 1822 <tr><td><span class="WYSIWYG_LINK">[[LegacyTopic1]]</span></td><td> Main.SomeGuy</td></tr>1995 <tr><td><span class="WYSIWYG_LINK">[[LegacyTopic1]]</span></td><td><span class="WYSIWYG_LINK">Main.SomeGuy</span></td></tr> 1823 1996 </table> 1824 1997 <span class="WYSIWYG_PROTECTED"><br />%SEARCH{"legacy" nonoise="on" format="| [[\$topic]] | [[\$wikiname]] |"}%</span> 1998 THERE 1999 }, 2000 { 2001 name => 'linkInTable', 2002 exec => $ROUNDTRIP | $TML2HTML, 2003 tml => <<HERE, 2004 | Main.SomeGuy | 2005 | - Main.SomeGuy - | 2006 Main.SomeGuy 2007 HERE 2008 html => <<THERE, 2009 <table cellspacing="1" cellpadding="0" border="1"> 2010 <tr><td><span class="WYSIWYG_LINK">Main.SomeGuy</span></td></tr> 2011 <tr><td> - <span class="WYSIWYG_LINK">Main.SomeGuy</span> - </td></tr> 2012 </table> 2013 <span class="WYSIWYG_LINK">Main.SomeGuy</span> 1825 2014 THERE 1826 2015 }, … … 2042 2231 name => "Item2222", 2043 2232 exec => $ROUNDTRIP | $CANNOTWYSIWYG, 2044 tml => '<!-- <sticky></sticky> -->',2233 tml => '<!-- <sticky></sticky> -->', 2045 2234 }, 2046 2235 ]; … … 2074 2263 my $fn = 'TranslatorTests::testCANNOTWYSIWYG_' . $datum->{name}; 2075 2264 no strict 'refs'; 2076 *$fn = sub { my $this = shift; $this->compareNotWysiwygEditable($datum) }; 2265 *$fn = 2266 sub { my $this = shift; $this->compareNotWysiwygEditable($datum) }; 2077 2267 use strict 'refs'; 2078 2268 } … … 2122 2312 } 2123 2313 $query->path_info("/Current/TestTopic"); 2124 $this->{session}->finish() if ( defined($this->{session}));2314 $this->{session}->finish() if ( defined( $this->{session} ) ); 2125 2315 $this->{session} = new Foswiki( undef, $query ); 2126 2316 $Foswiki::Plugins::SESSION = $this->{session}; … … 2135 2325 } 2136 2326 2137 sub TML_HTMLconverterOptions 2138 { 2327 sub TML_HTMLconverterOptions { 2139 2328 my $this = shift; 2140 2329 return { … … 2160 2349 $tml =~ s/%!page!%/$page/g; 2161 2350 2162 my $notEditable = Foswiki::Plugins::WysiwygPlugin::notWysiwygEditable( $tml);2163 $this->assert( !$notEditable, $notEditable);2351 my $notEditable = Foswiki::Plugins::WysiwygPlugin::notWysiwygEditable($tml); 2352 $this->assert( !$notEditable, $notEditable ); 2164 2353 2165 2354 my $txer = new Foswiki::Plugins::WysiwygPlugin::TML2HTML(); 2166 my $tx = $txer->convert( 2167 $tml, 2168 $this->TML_HTMLconverterOptions() 2169 ); 2355 my $tx = $txer->convert( $tml, $this->TML_HTMLconverterOptions() ); 2170 2356 2171 2357 $this->assert_html_equals( $html, $tx ); … … 2185 2371 $tml =~ s/%!page!%/$page/g; 2186 2372 2187 my $notEditable = Foswiki::Plugins::WysiwygPlugin::notWysiwygEditable( $tml, '' ); 2188 $this->assert($notEditable, "This TML should not be wysiwyg-editable: $tml"); 2373 my $notEditable = 2374 Foswiki::Plugins::WysiwygPlugin::notWysiwygEditable( $tml, '' ); 2375 $this->assert( $notEditable, 2376 "This TML should not be wysiwyg-editable: $tml" ); 2189 2377 } 2190 2378 … … 2200 2388 2201 2389 my $txer = new Foswiki::Plugins::WysiwygPlugin::TML2HTML(); 2202 # This conversion can throw an exception. 2390 2391 # This conversion can throw an exception. 2203 2392 # This might be expected if $args->{exec} also has $CANNOTWYSIWYG set 2204 my $html = eval { 2205 $txer->convert( 2206 $tml, 2207 $this->TML_HTMLconverterOptions() 2208 ); 2209 }; 2393 my $html = 2394 eval { $txer->convert( $tml, $this->TML_HTMLconverterOptions() ); }; 2210 2395 $html = $@ if $@; 2211 2396 2212 2397 $txer = new Foswiki::Plugins::WysiwygPlugin::HTML2TML(); 2213 my $tx = $txer->convert( 2214 $html, 2215 $this->HTML_TMLconverterOptions() 2216 ); 2398 my $tx = $txer->convert( $html, $this->HTML_TMLconverterOptions() ); 2217 2399 my $finaltml = $args->{finaltml} || $tml; 2218 2400 $finaltml =~ s/%!page!%/$page/g; 2219 2401 2220 my $notEditable = Foswiki::Plugins::WysiwygPlugin::notWysiwygEditable( $tml, '' ); 2402 my $notEditable = 2403 Foswiki::Plugins::WysiwygPlugin::notWysiwygEditable( $tml, '' ); 2221 2404 if ( ( $mask & $args->{exec} ) & $CANNOTWYSIWYG ) { 2222 $this->assert($notEditable, "This TML should not be wysiwyg-editable: $tml"); 2223 # Expect that roundtrip is not possible if notWysiwygEditable returns true. 2224 # notWysiwygEditable should not return false for anything that *can* be 2225 # roundtripped. 2405 $this->assert( $notEditable, 2406 "This TML should not be wysiwyg-editable: $tml" ); 2407 2408 # Expect that roundtrip is not possible if notWysiwygEditable returns true. 2409 # notWysiwygEditable should not return false for anything that *can* be 2410 # roundtripped. 2226 2411 $this->_assert_tml_not_equals( $finaltml, $tx, $args->{name} ); 2227 2412 } 2228 2413 else { 2229 2414 $this->_assert_tml_equals( $finaltml, $tx, $args->{name} ); 2230 $this->assert(!$notEditable, "$args->{name} TML is wysiwyg-editable, but notWysiwygEditable() reports: $notEditable"); 2415 $this->assert( !$notEditable, 2416 "$args->{name} TML is wysiwyg-editable, but notWysiwygEditable() reports: $notEditable" 2417 ); 2231 2418 } 2232 2419 2233 2420 } 2234 2421 2235 sub HTML_TMLconverterOptions 2236 { 2422 sub HTML_TMLconverterOptions { 2237 2423 my $this = shift; 2238 2424 return { … … 2258 2444 2259 2445 my $txer = new Foswiki::Plugins::WysiwygPlugin::HTML2TML(); 2260 my $tx = $txer->convert( 2261 $html, 2262 $this->HTML_TMLconverterOptions() 2263 ); 2446 my $tx = $txer->convert( $html, $this->HTML_TMLconverterOptions() ); 2264 2447 $this->_assert_tml_equals( $finaltml, $tx, $args->{name} ); 2265 2448 } … … 2310 2493 if ( $expected eq $actual ) { 2311 2494 my $expl = 2312 "==$name== Actual TML unexpectedly correct, remove \$CANNOTWYSIWYG flag:\n"2495 "==$name== Actual TML unexpectedly correct, remove \$CANNOTWYSIWYG flag:\n" 2313 2496 . encode($actual) 2314 2497 . "\n==$name==\n";
Note: See TracChangeset
for help on using the changeset viewer.
