Changeset 8111


Ignore:
Timestamp:
07/10/10 14:53:09 (23 months ago)
Author:
MichaelTempest
Message:

Item2074: Some TML is simply not editable in the WYSIWYG editor at present, such as <sticky> inside a <literal> block. There is also the WYSIWYG_EXCLUDE preference that disables the WYSIWYG editor when the topic contains certain TML.

However, nothing stops the user from opening a topic in the WYSIWYG editor, clicking WikiText, entering some TML that would have prevented the use of the WYSIWYG editor in the first place, and then clicking WYSIWYG. This can corrupt the topic.

To guard against that, the TML2HTML rest handler now detects TML that is not WYSIWYG-editable and protects all of the TML. To explain why, it adds a warning at the top of the HTML. This warning is automatically removed when converting back to TML.

Location:
trunk/WysiwygPlugin
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/WysiwygPlugin/lib/Foswiki/Plugins/WysiwygPlugin.pm

    r7948 r8111  
    101101 
    102102    #my ($text, $exclusions) = @_; 
     103    my $disabled = wysiwygEditingDisabledForThisContent($_[0], $_[1]); 
     104    return $disabled if $disabled; 
     105 
     106    # Check that the topic text can be converted to HTML. This is an 
     107    # *expensive* process, to be avoided if possible (hence all the 
     108    # earlier checks) 
     109    my $impossible = wysiwygEditingNotPossibleForThisContent( $_[0] ); 
     110    return $impossible if $impossible; 
     111 
     112    return 0; 
     113} 
     114 
     115sub wysiwygEditingDisabledForThisContent { 
     116    #my ($text, $exclusions) = @_; 
    103117 
    104118    my $exclusions = $_[1]; 
     
    161175                print STDERR "WYSIWYG_DEBUG: <sticky> inside <$tag>\n" 
    162176                  if (WHY); 
    163                 return "<sticky> inside <$tag>"; 
     177                return "&lt;sticky&gt; inside &lt;$tag&gt;"; 
    164178            } 
    165179        } 
     
    182196                print STDERR "WYSIWYG_DEBUG: <verbatim> inside <$tag>\n" 
    183197                  if (WHY); 
    184                 return "<verbatim> inside <$tag>"; 
     198                return "&lt;verbatim&gt; inside &lt;$tag&gt;"; 
    185199            } 
    186200        } 
    187201    } 
    188202 
    189     # Look for combinations of literal and other markup that cause 
    190     # problems together 
    191     for my $tag ( keys %xmltag ) { 
    192         while ( $text =~ /<$tag\b[^>]*>(.*?)<\/$tag>/gsi ) { 
    193             my $inner = $1; 
    194             if ( $inner =~ /<literal\b[^>]*>/i ) { 
    195                 print STDERR "WYSIWYG_DEBUG: <literal> inside <$tag>\n" 
    196                   if (WHY); 
    197                 return "<literal> inside <$tag>"; 
    198             } 
    199         } 
    200     } 
    201  
    202     # Check that the topic text can be converted to HTML. This is an 
    203     # *expensive* process, to be avoided if possible (hence all the 
    204     # earlier checks) 
     203    return 0; 
     204} 
     205 
     206sub wysiwygEditingNotPossibleForThisContent { 
    205207    eval { 
    206208        require Foswiki::Plugins::WysiwygPlugin::Handlers; 
  • trunk/WysiwygPlugin/lib/Foswiki/Plugins/WysiwygPlugin/HTML2TML/Node.pm

    r7928 r8111  
    15571557    my ( $this, $options ) = @_; 
    15581558 
     1559    if ( $this->hasClass('WYSIWYG_WARNING') ) { 
     1560        return ( 0, '' ); 
     1561    } 
     1562 
    15591563    if ( $this->hasClass('TMLverbatim') ) { 
    15601564        return $this->_verbatim( 'verbatim', $options ); 
  • trunk/WysiwygPlugin/lib/Foswiki/Plugins/WysiwygPlugin/TML2HTML.pm

    r8110 r8111  
    100100    return '' unless $content; 
    101101 
    102     $content =~ s/[$TT0$TT1$TT2]/?/go; 
    103  
    104     # Render TML constructs to tagged HTML 
    105     $content = $this->_getRenderedVersion($content); 
    106  
    107     # Substitute back in protected elements 
    108     $content = $this->_dropBack($content); 
    109  
    110     if ( $content =~ /[$TT0$TT1$TT2]/o ) { 
    111  
    112         # There should never be any of these in the text at this point. 
    113         # If there are, then the conversion failed. 
    114         die("Invalid characters in HTML after conversion") 
    115           if $options->{dieOnError}; 
    116  
    117         # Encode the original TML as verbatim-style HTML, 
    118         # so that the user has uncorrupted TML, at least. 
    119         my $originalContent = $_[1]; 
    120         $originalContent =~ s/[$TT0$TT1$TT2]/?/go; 
    121         $originalContent = _protectVerbatimChars($originalContent); 
    122         $content = 
    123           CGI::div( { class => 'WYSIWYG_PROTECTED' }, $originalContent ); 
     102    my $disabled = 
     103      Foswiki::Plugins::WysiwygPlugin::wysiwygEditingDisabledForThisContent( 
     104        $content); 
     105    if ($disabled) { 
     106 
     107      # encode the content verbatim-style, so that the user has uncorrupted HTML 
     108        $content =~ s/[$TT0$TT1$TT2]/?/go; 
     109        $content = CGI::div( 
     110            { class => 'WYSIWYG_WARNING foswikiBroadcastMessage' }, 
     111            Foswiki::Func::renderText( 
     112                Foswiki::Func::expandCommonVariables( <<"WARNING" ) ) ) 
     113*%MAKETEXT{"Conversion to HTML for WYSIWYG editing is disabled because of the topic content."}%* 
     114 
     115%MAKETEXT{"This is why the conversion is disabled:"}% $disabled 
     116 
     117%MAKETEXT{"(This message will be removed automatically)"}% 
     118WARNING 
     119          . CGI::div( { class => 'WYSIWYG_PROTECTED' }, 
     120            _protectVerbatimChars($content) ); 
     121    } 
     122    else { 
     123 
     124        # Convert TML to HTML for wysiwyg editing 
     125 
     126        $content =~ s/[$TT0$TT1$TT2]/?/go; 
     127 
     128        # Render TML constructs to tagged HTML 
     129        $content = $this->_getRenderedVersion($content); 
     130 
     131        # Substitute back in protected elements 
     132        $content = $this->_dropBack($content); 
     133 
     134        if ( $content =~ /[$TT0$TT1$TT2]/o ) { 
     135 
     136            # There should never be any of these in the text at this point. 
     137            # If there are, then the conversion failed. 
     138            die("Invalid characters in HTML after conversion") 
     139              if $options->{dieOnError}; 
     140 
     141            # Encode the original TML as verbatim-style HTML, 
     142            # so that the user has uncorrupted TML, at least. 
     143            my $originalContent = $_[1]; 
     144            $originalContent =~ s/[$TT0$TT1$TT2]/?/go; 
     145            $originalContent = _protectVerbatimChars($originalContent); 
     146            $content = 
     147              CGI::div( { class => 'WYSIWYG_PROTECTED' }, $originalContent ); 
     148        } 
    124149    } 
    125150 
  • trunk/WysiwygPlugin/test/unit/WysiwygPlugin/TranslatorTests.pm

    r7928 r8111  
    20172017    }, 
    20182018    { 
    2019         exec => $ROUNDTRIP | $CANNOTWYSIWYG, 
     2019        exec => $ROUNDTRIP, 
    20202020        name => 'verbatimInsideLiteralItem1980', 
    20212021        tml  => <<'GLUED', 
     
    20482048    }, 
    20492049    { 
    2050         exec => $ROUNDTRIP | $CANNOTWYSIWYG, 
     2050        exec => $ROUNDTRIP, 
    20512051        name => 'stickyInsideLiteral', 
    20522052        tml  => <<'GLUED', 
     
    26192619    else { 
    26202620        $this->assert_tml_equals( $finaltml, $tx, $args->{name} ); 
    2621         $this->assert( !$notEditable, 
     2621        if ($html =~ /WYSIWYG_WARNING/) { 
     2622            # The HTML contains a warning message saying that this TML  
     2623            # cannot be edited as HTML, and all of the TML is protected 
     2624            # as if the whole topic were in a <sticky> block 
     2625        } 
     2626        else { 
     2627            # This TML really is editable in the WYSIWYG editor 
     2628            $this->assert( !$notEditable, 
    26222629"$args->{name} TML is wysiwyg-editable, but notWysiwygEditable() reports: $notEditable" 
    2623         ); 
     2630            ); 
     2631        } 
    26242632    } 
    26252633 
Note: See TracChangeset for help on using the changeset viewer.