Changeset 5816


Ignore:
Timestamp:
12/18/09 10:38:11 (2 years ago)
Author:
CrawfordCurrie
Message:

Item2511: move code out of the main plugin module into a lazy-loaded handlers module. Reduces load time significantly, important when wysiwyg editing is not even an option (eg when REST handling)#

Location:
trunk/WysiwygPlugin
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/WysiwygPlugin/data/System/WysiwygPlugin.txt

    r5573 r5816  
    77%SHORTDESCRIPTION% 
    88 
    9 Support for the integration of WYSIWYG (What-You-See-Is-What-You-Get) editors. On its own, the only thing this plugin gives you is a stand-alone HTML to TML (topic markup language) translator script. For WYSIWYG editing in Foswiki and Foswiki, you will also need to install a specific editor package such as Foswiki:Extensions.TinyMCEPlugin. 
     9Support for the integration of WYSIWYG (What-You-See-Is-What-You-Get) editors. On its own, the only thing this plugin gives you is a stand-alone HTML to TML (topic markup language) translator script. For WYSIWYG editing you will also need to install a specific editor package such as Foswiki:Extensions.TinyMCEPlugin. 
    1010 
    1111This plugin provides a generic framework that supports editing of topics using any browser-based HTML editor. It works by transforming TML into HTML for the editor, and then transforming HTML back into TML on save. 
     
    176176|  Release: | %$RELEASE% | 
    177177|  Change History: | | 
     178|  18 Dec 2009 | Foswikitask:Item2511: move code out of the plugin module to accelerate loading | 
    178179|  18 Nov 2009 | Foswikitask:Item2369: Convert tables with cells that span rows | 
    179180|  22 Oct 2009 | Foswikitask:Item2183: Protect div style= by default | 
  • trunk/WysiwygPlugin/lib/Foswiki/Plugins/WysiwygPlugin.pm

    r5354 r5816  
    2323package Foswiki::Plugins::WysiwygPlugin; 
    2424 
    25 use CGI qw( :cgi -any ); 
    2625 
    2726use strict; 
    2827 
    2928use Assert; 
    30 use Encode (); 
    31  
    32 use Foswiki::Func                              ();    # The plugins API 
    33 use Foswiki::Plugins                           ();    # For the API version 
    34 use Foswiki::Plugins::WysiwygPlugin::Constants (); 
    35  
    36 use vars qw( $html2tml $tml2html $recursionBlock $imgMap ); 
    37 use vars qw( %FoswikiCompatibility @refs %xmltag %xmltagPlugin); 
    38  
    39 our $SHORTDESCRIPTION  = 'Translator framework for Wysiwyg editors'; 
     29 
     30our $SHORTDESCRIPTION  = 'Translator framework for WYSIWYG editors'; 
    4031our $NO_PREFS_IN_TOPIC = 1; 
    4132our $VERSION           = '$Rev$'; 
    4233 
    43 our $RELEASE = '18 Sep 2009'; 
    44  
    45 our $SECRET_ID = 
    46 'WYSIWYG content - do not remove this comment, and never use this identical text in your topics'; 
    47  
    48 sub WHY { 0 } 
     34our $RELEASE = '18 Dec 2009'; 
     35 
     36our %xmltag; 
     37 
     38# Set to 1 for reasons for rejection 
     39sub WHY { 0 }; 
    4940 
    5041sub initPlugin { 
     
    5344    # %OWEB%.%OTOPIC% is the topic where the initial content should be 
    5445    # grabbed from, as defined in templates/edit.skin.tmpl 
    55     Foswiki::Func::registerTagHandler( 'OWEB',            \&_OWEBTAG ); 
    56     Foswiki::Func::registerTagHandler( 'OTOPIC',          \&_OTOPICTAG ); 
    57     Foswiki::Func::registerTagHandler( 'WYSIWYG_TEXT',    \&_WYSIWYG_TEXT ); 
    58     Foswiki::Func::registerTagHandler( 'JAVASCRIPT_TEXT', \&_JAVASCRIPT_TEXT ); 
    59     Foswiki::Func::registerTagHandler( 'WYSIWYG_SECRET_ID', 
    60         sub { $SECRET_ID } ); 
    61  
    62     Foswiki::Func::registerRESTHandler( 'tml2html',    \&_restTML2HTML ); 
    63     Foswiki::Func::registerRESTHandler( 'html2tml',    \&_restHTML2TML ); 
    64     Foswiki::Func::registerRESTHandler( 'upload',      \&_restUpload ); 
    65     Foswiki::Func::registerRESTHandler( 'attachments', \&_restAttachments ); 
     46    # Note; rather than declaring the handlers in this module, we use 
     47    # the _execute function to hand off execution to 
     48    # Foswiki::Plugins::WysiwygPlugin::Handlers. The goal is to keep this 
     49    # module small and light so it loads fast. 
     50    Foswiki::Func::registerTagHandler( 
     51        'OWEB', sub { _execute('_OWEBTAG', @_) } ); 
     52    Foswiki::Func::registerTagHandler( 
     53        'OTOPIC', sub { _execute('_OTOPICTAG', @_) } ); 
     54    Foswiki::Func::registerTagHandler( 
     55        'WYSIWYG_TEXT', sub { _execute('_WYSIWYG_TEXT', @_) } ); 
     56    Foswiki::Func::registerTagHandler( 
     57        'JAVASCRIPT_TEXT', sub { _execute('_JAVASCRIPT_TEXT', @_) } ); 
     58    Foswiki::Func::registerTagHandler( 
     59        'WYSIWYG_SECRET_ID', sub { _execute('_SECRET_ID', @_) } ); 
     60 
     61    Foswiki::Func::registerRESTHandler( 
     62        'tml2html', sub { _execute('_restTML2HTML', @_) } ); 
     63    Foswiki::Func::registerRESTHandler( 
     64        'html2tml', sub { _execute('_restHTML2TML', @_) } ); 
     65    Foswiki::Func::registerRESTHandler( 
     66        'upload', sub { _execute('_restUpload', @_) } ); 
     67    Foswiki::Func::registerRESTHandler( 
     68        'attachments', sub { _execute('_restAttachments', @_) } ); 
    6669 
    6770    # Plugin correctly initialized 
     
    6972} 
    7073 
    71 sub _OWEBTAG { 
    72     my ( $session, $params, $topic, $web ) = @_; 
    73  
    74     my $query = Foswiki::Func::getCgiQuery(); 
    75  
    76     return $web unless $query; 
    77  
    78     if ( defined( $query->param('templatetopic') ) ) { 
    79         my @split = split( /\./, $query->param('templatetopic') ); 
    80  
    81         if ( $#split == 0 ) { 
    82             return $web; 
    83         } 
    84         else { 
    85             return $split[0]; 
    86         } 
    87     } 
    88  
    89     return $web; 
    90 } 
    91  
    92 sub _OTOPICTAG { 
    93     my ( $session, $params, $topic, $web ) = @_; 
    94  
    95     my $query = Foswiki::Func::getCgiQuery(); 
    96  
    97     return $topic unless $query; 
    98  
    99     if ( defined( $query->param('templatetopic') ) ) { 
    100         my @split = split( /\./, $query->param('templatetopic') ); 
    101  
    102         return $split[$#split]; 
    103     } 
    104  
    105     return $topic; 
    106 } 
    107  
    108 $FoswikiCompatibility{startRenderingHandler} = 2.1; 
    109 sub startRenderingHandler { 
    110     $_[0] =~ s#</?sticky>##g; 
    111 } 
    112  
    113 # This handler is used to determine whether the topic is editable by 
    114 # a WYSIWYG editor or not. The only thing it does is to redirect to a 
    115 # normal edit url if the skin is set to WYSIWYGPLUGIN_WYSIWYGSKIN and 
    116 # nasty content is found. 
    117 sub beforeEditHandler { 
    118  
    119     #my( $text, $topic, $web, $meta ) = @_; 
    120  
    121     my $skin = Foswiki::Func::getPreferencesValue('WYSIWYGPLUGIN_WYSIWYGSKIN'); 
    122  
    123     if ( $skin && Foswiki::Func::getSkin() =~ /\b$skin\b/o ) { 
    124         if ( notWysiwygEditable( $_[0] ) ) { 
    125  
    126             # redirect 
    127             my $query = Foswiki::Func::getCgiQuery(); 
    128             foreach my $p qw( skin cover ) { 
    129                 my $arg = $query->param($p); 
    130                 if ( $arg && $arg =~ s/\b$skin\b// ) { 
    131                     if ( $arg =~ /^[\s,]*$/ ) { 
    132                         $query->delete($p); 
    133                     } 
    134                     else { 
    135                         $query->param( -name => $p, -value => $arg ); 
    136                     } 
    137                 } 
    138             } 
    139             my $url = $query->url( -full => 1, -path => 1, -query => 1 ); 
    140             Foswiki::Func::redirectCgiQuery( $query, $url ); 
    141  
    142             # Bring this session to an untimely end 
    143             exit 0; 
    144         } 
    145     } 
    146 } 
    147  
    148 # This handler is only invoked *after* merging is complete 
    149 sub beforeSaveHandler { 
    150  
    151     #my( $text, $topic, $web ) = @_; 
    152     my $query = Foswiki::Func::getCgiQuery(); 
    153     return unless $query; 
    154  
    155     return unless defined( $query->param('wysiwyg_edit') ); 
    156  
    157     $_[0] = TranslateHTML2TML( $_[0], $_[1], $_[2] ); 
    158 } 
    159  
    160 # This handler is invoked before a merge. Merges are done before the 
    161 # afterEditHandler is called, so we need to translate here. 
    162 sub beforeMergeHandler { 
    163  
    164     #my( $text, $currRev, $currText, $origRev, $origText, $web, $topic ) = @_; 
    165     afterEditHandler( $_[0], $_[6], $_[5] ); 
    166 } 
    167  
    168 # This handler is invoked *after* a merge, and only from the edit 
    169 # script (so it's useless for a REST save) 
    170 sub afterEditHandler { 
    171     my ( $text, $topic, $web ) = @_; 
    172     my $query = Foswiki::Func::getCgiQuery(); 
    173     return unless $query; 
    174  
    175     if (   $Foswiki::cfg{Site}{CharSet} 
    176         && $Foswiki::cfg{Site}{CharSet} =~ /^utf-?8$/i ) 
    177     { 
    178  
    179         # If the site charset is utf-8, then form POSTs (such as the one 
    180         # that got us here) are utf-8 encoded. we have to decode to prevent 
    181         # the HTML parser from going tits up when it sees utf-8 in the data. 
    182         $text = Encode::decode_utf8($text); 
    183     } 
    184  
    185     return 
    186       unless defined( $query->param('wysiwyg_edit') ) 
    187           || $text =~ s/<!--$SECRET_ID-->//go; 
    188  
    189     # Switch off wysiwyg_edit so it doesn't try to transform again in 
    190     # the beforeSaveHandler 
    191     $query->delete('wysiwyg_edit'); 
    192  
    193     $text = TranslateHTML2TML( $text, $_[1], $_[2] ); 
    194  
    195     $_[0] = $text; 
    196 } 
    197  
    198 # Invoked to convert HTML to TML (best efforts) 
    199 sub TranslateHTML2TML { 
    200     my ( $text, $topic, $web ) = @_; 
    201  
    202     unless ($html2tml) { 
    203         require Foswiki::Plugins::WysiwygPlugin::HTML2TML; 
    204  
    205         $html2tml = new Foswiki::Plugins::WysiwygPlugin::HTML2TML(); 
    206     } 
    207  
    208     # SMELL: really, really bad smell; bloody core should NOT pass text 
    209     # with embedded meta to plugins! It is VERY BAD DESIGN!!! 
    210     my $top = ''; 
    211     if ( $text =~ s/^(%META:[A-Z]+{.*?}%\r?\n)//s ) { 
    212         $top = $1; 
    213     } 
    214     my $bottom = ''; 
    215     $text =~ s/^(%META:[A-Z]+{.*?}%\r?\n)/$bottom = "$1$bottom";''/gem; 
    216  
    217     my $opts = { 
    218         web          => $web, 
    219         topic        => $topic, 
    220         convertImage => \&_convertImage, 
    221         rewriteURL   => \&postConvertURL, 
    222         very_clean   => 1,                  # aggressively polish saved HTML 
    223     }; 
    224  
    225     $text = $html2tml->convert( $text, $opts ); 
    226  
    227     $text =~ s/\s+$/\n/s; 
    228  
    229     return $top . $text . $bottom; 
    230 } 
    231  
    232 # Handler used to process text in a =view= URL to generate text/html 
    233 # containing the HTML of the topic to be edited. 
    234 # 
    235 # Invoked when the selected skin is in use to convert the text to HTML 
    236 # We can't use the beforeEditHandler, because the editor loads up and then 
    237 # uses a URL to fetch the text to be edited. This handler is designed to 
    238 # provide the text for that request. It's a real struggle, because the 
    239 # commonTagsHandler is called so many times that getting the right 
    240 # call is hard, and then preventing a repeat call is harder! 
    241 sub beforeCommonTagsHandler { 
    242  
    243     #my ( $text, $topic, $web, $meta ) 
    244     return if $recursionBlock; 
    245     return unless Foswiki::Func::getContext()->{body_text}; 
    246  
    247     my $query = Foswiki::Func::getCgiQuery(); 
    248  
    249     return unless $query; 
    250  
    251     return unless defined( $query->param('wysiwyg_edit') ); 
    252  
    253     # stop it from processing the template without expanded 
    254     # %TEXT% (grr; we need a better way to tell where we 
    255     # are in the processing pipeline) 
    256     return if ( $_[0] =~ /^<!-- WysiwygPlugin Template/ ); 
    257  
    258     # Have to re-read the topic because verbatim blocks have already been 
    259     # lifted out, and we need them. 
    260     my $topic = $_[1]; 
    261     my $web   = $_[2]; 
    262     my ( $meta, $text ); 
    263     my $altText = $query->param('templatetopic'); 
    264     if ( $altText && Foswiki::Func::topicExists( $web, $altText ) ) { 
    265         ( $web, $topic ) = 
    266           Foswiki::Func::normalizeWebTopicName( $web, $altText ); 
    267     } 
    268  
    269     $_[0] = _WYSIWYG_TEXT( $Foswiki::Plugins::SESSION, {}, $topic, $web ); 
    270 } 
    271  
    272 # Handler used by editors that require pre-prepared HTML embedded in the 
    273 # edit template. 
    274 sub _WYSIWYG_TEXT { 
    275     my ( $session, $params, $topic, $web ) = @_; 
    276  
    277     # Have to re-read the topic because content has already been munged 
    278     # by other plugins, or by the extraction of verbatim blocks. 
    279     my ( $meta, $text ) = Foswiki::Func::readTopic( $web, $topic ); 
    280  
    281     $text = TranslateTML2HTML( $text, $web, $topic ); 
    282  
    283     # Lift out the text to protect it from further Foswiki rendering. It will be 
    284     # put back in the postRenderingHandler. 
    285     return _liftOut($text); 
    286 } 
    287  
    288 # Handler used to present the editable text in a javascript constant string 
    289 sub _JAVASCRIPT_TEXT { 
    290     my ( $session, $params, $topic, $web ) = @_; 
    291  
    292     my $html = _dropBack( _WYSIWYG_TEXT(@_) ); 
    293  
    294     $html =~ s/([\\'])/\\$1/sg; 
    295     $html =~ s/\r/\\r/sg; 
    296     $html =~ s/\n/\\n/sg; 
    297     $html =~ s/script/scri'+'pt/g; 
    298  
    299     return _liftOut("'$html'"); 
    300 } 
    301  
    302 sub postRenderingHandler { 
    303     return if ( $recursionBlock || !$tml2html ); 
    304  
    305     # Replace protected content. 
    306     $_[0] = _dropBack( $_[0] ); 
    307 } 
    308  
    309 sub modifyHeaderHandler { 
    310     my ( $headers, $query ) = @_; 
    311  
    312     if ( $query->param('wysiwyg_edit') ) { 
    313         $headers->{Expires} = 0; 
    314         $headers->{'Cache-control'} = 'max-age=0, must-revalidate'; 
    315     } 
    316 } 
    317  
    318 # callback passed to the TML2HTML convertor 
    319 sub getViewUrl { 
    320     my ( $web, $topic ) = @_; 
    321  
    322     # the Cairo documentation says getViewUrl defaults the web. It doesn't. 
    323     unless ( defined $Foswiki::Plugins::SESSION ) { 
    324         $web ||= $Foswiki::webName; 
    325     } 
    326  
    327     return Foswiki::Func::getViewUrl( $web, $topic ); 
    328 } 
    329  
    330 # The subset of vars for which bidirection transformation is supported 
    331 # in URLs only 
    332 use vars qw( @VARS ); 
    333  
    334 # The set of macros that get "special treatment" in URLs 
    335 @VARS = ( 
    336     '%ATTACHURL%', 
    337     '%ATTACHURLPATH%', 
    338     '%PUBURL%', 
    339     '%PUBURLPATH%', 
    340     '%SCRIPTURLPATH{"view"}%', 
    341     '%SCRIPTURLPATH%', 
    342     '%SCRIPTURL{"view"}%', 
    343     '%SCRIPTURL%', 
    344     '%SCRIPTSUFFIX%',    # bit dodgy, this one 
    345 ); 
    346  
    347 # Initialises the mapping from var to URL and back 
    348 sub _populateVars { 
    349     my $opts = shift; 
    350  
    351     return if ( $opts->{exp} ); 
    352  
    353     local $recursionBlock = 1;    # block calls to beforeCommonTagshandler 
    354  
    355     my @exp = split( 
    356         /\0/, 
    357         Foswiki::Func::expandCommonVariables( 
    358             join( "\0", @VARS ), 
    359             $opts->{topic}, $opts->{web} 
    360         ) 
    361     ); 
    362  
    363     for my $i ( 0 .. $#VARS ) { 
    364         my $nvar = $VARS[$i]; 
    365         $opts->{match}[$i] = $nvar; 
    366         $exp[$i] ||= ''; 
    367     } 
    368     $opts->{exp} = \@exp; 
    369 } 
    370  
    371 # callback passed to the TML2HTML convertor on each 
    372 # variable in a URL used in a square bracketed link 
    373 sub expandVarsInURL { 
    374     my ( $url, $opts ) = @_; 
    375  
    376     return '' unless $url; 
    377  
    378     _populateVars($opts); 
    379     for my $i ( 0 .. $#VARS ) { 
    380         $url =~ s/$opts->{match}[$i]/$opts->{exp}->[$i]/g; 
    381     } 
    382     return $url; 
    383 } 
    384  
    385 # callback passed to the HTML2TML convertor 
    386 sub postConvertURL { 
    387     my ( $url, $opts ) = @_; 
    388  
    389     #my $orig = $url; #debug 
    390  
    391     local $recursionBlock = 1;    # block calls to beforeCommonTagshandler 
    392  
    393     my $anchor = ''; 
    394     if ( $url =~ s/(#.*)$// ) { 
    395         $anchor = $1; 
    396     } 
    397     my $parameters = ''; 
    398     if ( $url =~ s/(\?.*)$// ) { 
    399         $parameters = $1; 
    400     } 
    401  
    402     _populateVars($opts); 
    403  
    404     for my $i ( 0 .. $#VARS ) { 
    405         next unless $opts->{exp}->[$i]; 
    406         $url =~ s/^$opts->{exp}->[$i]/$VARS[$i]/; 
    407     } 
    408  
    409     if ( $url =~ m#^%SCRIPTURL(?:PATH)?(?:{"view"}%|%/+view[^/]*)/+([/\w.]+)$# 
    410         && !$parameters ) 
    411     { 
    412         my $orig = $1; 
    413         my ( $web, $topic ) = 
    414           Foswiki::Func::normalizeWebTopicName( $opts->{web}, $orig ); 
    415  
    416         if ( $web && $web ne $opts->{web} ) { 
    417  
    418             #print STDERR "$orig -> $web+$topic$anchor\n";    #debug 
    419             return $web . '.' . $topic . $anchor; 
    420         } 
    421  
    422         #print STDERR "$orig -> $topic$anchor\n"; #debug 
    423         return $topic . $anchor; 
    424     } 
    425  
    426     #print STDERR "$orig -> $url$anchor$parameters\n"; #debug 
    427     return $url . $anchor . $parameters; 
    428 } 
    429  
    430 # Callback used to convert an image reference into a Foswiki variable. 
    431 sub _convertImage { 
    432     my ( $src, $opts ) = @_; 
    433  
    434     return unless $src; 
    435  
    436     local $recursionBlock = 1;    # block calls to beforeCommonTagshandler 
    437  
    438     unless ($imgMap) { 
    439         $imgMap = {}; 
    440         my $imgs = Foswiki::Func::getPreferencesValue('WYSIWYGPLUGIN_ICONS'); 
    441         if ($imgs) { 
    442             while ( $imgs =~ s/src="(.*?)" alt="(.*?)"// ) { 
    443                 my ( $src, $alt ) = ( $1, $2 ); 
    444                 $src = 
    445                   Foswiki::Func::expandCommonVariables( $src, $opts->{topic}, 
    446                     $opts->{web} ); 
    447                 $alt .= '%' if $alt =~ /^%/; 
    448                 $imgMap->{$src} = $alt; 
    449             } 
    450         } 
    451     } 
    452  
    453     return $imgMap->{$src}; 
    454 } 
    455  
    456 # Replace content with a marker to prevent it being munged by Foswiki 
    457 sub _liftOut { 
    458     my ($text) = @_; 
    459     my $n = scalar(@refs); 
    460     push( @refs, $text ); 
    461     return "\05$n\05"; 
    462 } 
    463  
    464 # Substitute marker 
    465 sub _dropBack { 
    466     my ($text) = @_; 
    467  
    468     # Restore everything that was lifted out 
    469     while ( $text =~ s/\05([0-9]+)\05/$refs[$1]/gi ) { 
    470     } 
    471     return $text; 
     74sub _execute { 
     75    my $fn = shift; 
     76 
     77    require Foswiki::Plugins::WysiwygPlugin::Handlers; 
     78    $fn = 'Foswiki::Plugins::WysiwygPlugin::Handlers::'.$fn; 
     79    no strict 'refs'; 
     80    return &$fn(@_); 
     81    use strict 'refs'; 
    47282} 
    47383 
     
    495105    # purely content-related reasons for exclusion 
    496106    if ($exclusions) { 
    497         my $calls_ok = Foswiki::Func::getPreferencesValue('WYSIWYG_EDITABLE_CALLS') 
     107        my $calls_ok = Foswiki::Func::getPreferencesValue( 
     108            'WYSIWYG_EDITABLE_CALLS') 
    498109          || '---'; 
    499110        $calls_ok =~ s/\s//g; 
     
    532143 
    533144    # Copy the content.  
    534     # Then crunch verbatim blocks, because verbatim blocks may contain *anything*. 
     145    # Then crunch verbatim blocks, because verbatim blocks may 
     146    # contain *anything*. 
    535147    my $text = $_[0]; 
    536148 
    537     # Look for combinations of sticky and other markup that cause problems together 
     149    # Look for combinations of sticky and other markup that cause 
     150    # problems together 
    538151    for my $tag ('literal', keys %xmltag) { 
    539152        while ($text =~ /<$tag\b[^>]*>(.*?)<\/$tag>/gsi) { 
     
    550163    while ($text =~ s/<verbatim\b[^>]*>(.*?)<\/verbatim>/$wasAVerbatimTag/i) { 
    551164        #my $content = $1; 
    552         # If there is any content that breaks conversion if it is inside a verbatim block,  
    553         # check for it here: 
    554     } 
    555  
    556     # Look for combinations of verbatim and other markup that cause problems together 
     165        # If there is any content that breaks conversion if it is inside 
     166        # a verbatim block, check for it here: 
     167    } 
     168 
     169    # Look for combinations of verbatim and other markup that cause 
     170    # problems together 
    557171    for my $tag ('literal', keys %xmltag) { 
    558172        while ($text =~ /<$tag\b[^>]*>(.*?)<\/$tag>/gsi) { 
     
    566180    } 
    567181 
    568     # Look for combinations of literal and other markup that cause problems together 
     182    # Look for combinations of literal and other markup that cause 
     183    # problems together 
    569184    for my $tag (keys %xmltag) { 
    570185        while ($text =~ /<$tag\b[^>]*>(.*?)<\/$tag>/gsi) { 
     
    578193    } 
    579194 
    580     # Check that the topic text can be converted to HTML 
     195    # Check that the topic text can be converted to HTML. This is an 
     196    # *expensive* process, to be avoided if possible (hence all the 
     197    # earlier checks) 
    581198    eval { 
    582         TranslateTML2HTML( $_[0], 'Fakewebname', 'FakeTopicName', dieOnError => 1 ); 
     199        require Foswiki::Plugins::WysiwygPlugin::Handlers; 
     200        Foswiki::Plugins::WysiwygPlugin::Handlers::TranslateTML2HTML( 
     201            $_[0], 'Fakewebname', 'FakeTopicName', dieOnError => 1 ); 
    583202    }; 
    584203    if ($@) { 
     
    591210} 
    592211 
    593 =pod 
    594  
    595 ---++ StaticMethod addXMLTag($tag, \&fn) 
    596  
    597 Instruct WysiwygPlugin to "lift out" the named tag  
    598 and pass it to &fn for processing. 
    599 &fn may modify the text of the tag. 
    600 &fn should return 0 if the tag is to be re-embedded immediately, 
    601 or 1 if it is to be re-embedded after all processing is complete. 
    602 The text passed (by reference) to &fn includes the  
    603 =<tag> ... </tag>= brackets. 
    604  
    605 The simplest use of this function is something like this: 
    606 =Foswiki::Plugins::WysiwygPlugin::addXMLTag( 'mytag', sub { 1 } );= 
    607  
    608 A plugin may call this function more than once  
    609 e.g. to change the processing function for a tag. 
    610 However, only the *original plugin* may change the processing 
    611 for a tag. 
    612  
    613 Plugins should call this function from their =initPlugin= 
    614 handlers so that WysiwygPlugin will protect the XML-like tags 
    615 for all conversions, including REST conversions. 
    616 Plugins that are intended to be used with older versions of Foswiki 
    617 (e.g. 1.0.6) should check that this function is defined before calling it, 
    618 so that they degrade gracefully if an older version of WysiwygPlugin 
    619 (e.g. that shipped with 1.0.6) is installed. 
    620  
    621 =cut 
    622  
    623 sub addXMLTag { 
    624     my ( $tag, $fn ) = @_; 
    625  
    626     my $plugin = caller; 
    627     $plugin =~ s/^Foswiki::Plugins:://; 
    628  
    629     return if not defined $tag; 
    630  
    631     if (   ( not exists $xmltag{$tag} and not exists $xmltagPlugin{$tag} ) 
    632         or ( $xmltagPlugin{$tag} eq $plugin ) ) 
    633     { 
    634  
    635         # This is either a plugin adding a new tag 
    636         # or a plugin adding a tag it had previously added before. 
    637         # A plugin is allowed to add a tag that it had added before 
    638         # and the new function replaces the old. 
    639         # 
    640         $fn = sub { 1 } 
    641           unless $fn;    # Default function 
    642  
    643         $xmltag{$tag}       = $fn; 
    644         $xmltagPlugin{$tag} = $plugin; 
    645     } 
    646     else { 
    647  
    648         # DON'T replace the existing processing for this tag 
    649         printf STDERR "WysiwygPlugin::addXMLTag: " 
    650           . "$plugin cannot add XML tag $tag, " 
    651           . "that tag was already registered by $xmltagPlugin{$tag}\n"; 
    652     } 
    653 } 
    654  
    655 sub TranslateTML2HTML { 
    656     my ( $text, $web, $topic, @extraConvertOptions ) = @_; 
    657  
    658     # Translate the topic text to pure HTML. 
    659     unless ($tml2html) { 
    660         require Foswiki::Plugins::WysiwygPlugin::TML2HTML; 
    661         $tml2html = new Foswiki::Plugins::WysiwygPlugin::TML2HTML(); 
    662     } 
    663     return $tml2html->convert( 
    664         $_[0], 
    665         { 
    666             web             => $web, 
    667             topic           => $topic, 
    668             getViewUrl      => \&getViewUrl, 
    669             expandVarsInURL => \&expandVarsInURL, 
    670             xmltag          => \%xmltag, 
    671             @extraConvertOptions, 
    672         } 
    673     ); 
    674 } 
    675  
    676 # PACKAGE PRIVATE 
    677 # Determine if sticky attributes prevent a tag being converted to 
    678 # TML when this attribute is present. 
    679 my @protectedByAttr; 
    680  
    681 sub protectedByAttr { 
    682     my ( $tag, $attr ) = @_; 
    683  
    684     unless ( scalar(@protectedByAttr) ) { 
    685  
    686         # See the WysiwygPluginSettings for information on stickybits 
    687         my $protection = 
    688           Foswiki::Func::getPreferencesValue('WYSIWYGPLUGIN_STICKYBITS') 
    689           || <<'DEFAULT'; 
    690 .*=id,lang,title,dir,on.*; 
    691 a=accesskey,coords,shape,target; 
    692 bdo=dir; 
    693 br=clear; 
    694 col=char,charoff,span,valign,width; 
    695 colgroup=align,char,charoff,span,valign,width; 
    696 dir=compact; 
    697 div=align,style; 
    698 dl=compact; 
    699 font=size,face; 
    700 h\d=align; 
    701 hr=align,noshade,size,width; 
    702 legend=accesskey,align; 
    703 li=value; 
    704 ol=compact,start,type; 
    705 p=align; 
    706 param=name,type,value,valuetype; 
    707 pre=width; 
    708 q=cite; 
    709 table=align,bgcolor,frame,rules,summary,width; 
    710 tbody=align,char,charoff,valign; 
    711 td=abbr,align,axis,bgcolor,char,charoff,headers,height,nowrap,rowspan,scope,valign,width; 
    712 tfoot=align,char,charoff,valign; 
    713 th=abbr,align,axis,bgcolor,char,charoff,height,nowrap,rowspan,scope,valign,width,headers; 
    714 thead=align,char,charoff,valign; 
    715 tr=bgcolor,char,charoff,valign; 
    716 ul=compact,type; 
    717 DEFAULT 
    718         foreach my $def ( split( /;\s*/s, $protection ) ) { 
    719             my ( $re, $ats ) = split( /\s*=\s*/s, $def, 2 ); 
    720             push( 
    721                 @protectedByAttr, 
    722                 { 
    723                     tag   => qr/$re/i, 
    724                     attrs => join( '|', split( /\s*,\s*/, $ats ) ) 
    725                 } 
    726             ); 
    727         } 
    728     } 
    729     foreach my $row (@protectedByAttr) { 
    730         if ( $tag =~ /^$row->{tag}$/i ) { 
    731             if ( $attr =~ /^($row->{attrs})$/i ) { 
    732                 #print STDERR "Protecting  $tag with $attr matches $row->{attrs} \n";    #debug 
    733                 return 1; 
    734             } 
    735         } 
    736     } 
    737     return 0; 
    738 } 
    739  
    740 # Text that is taken from a web page and added to the parameters of an XHR 
    741 # by JavaScript is UTF-8 encoded. This is because UTF-8 is the default encoding 
    742 # for XML, which XHR was designed to transport. 
    743  
    744 # This function is used to decode such parameters to the currently selected 
    745 # Foswiki site character set. 
    746  
    747 # Note that this transform is not as simple as an Encode::from_to, as 
    748 # a number of unicode code points must be remapped for certain encodings. 
    749 sub RESTParameter2SiteCharSet { 
    750     my ($text) = @_; 
    751  
    752     $text = Encode::decode_utf8( $text, Encode::FB_PERLQQ ); 
    753  
    754     WC::mapUnicode2HighBit($text); 
    755  
    756     if ( $Foswiki::cfg{Site}{CharSet} ) { 
    757         $text = Encode::encode( $Foswiki::cfg{Site}{CharSet}, 
    758             $text, Encode::FB_PERLQQ ); 
    759     } 
    760  
    761     return $text; 
    762 } 
    763  
    764 # Text that is taken from a web page and added to the parameters of an XHR 
    765 # by JavaScript is UTF-8 encoded. This is because UTF-8 is the default encoding 
    766 # for XML, which XHR was designed to transport. For usefulness in Javascript 
    767 # the response to an XHR should also be UTF-8 encoded. 
    768 # This function generates such a response. 
    769 sub returnRESTResult { 
    770     my ( $response, $status, $text ) = @_; 
    771  
    772     if ( $Foswiki::cfg{Site}{CharSet} ) { 
    773         $text = Encode::decode( $Foswiki::cfg{Site}{CharSet}, 
    774             $text, Encode::FB_PERLQQ ); 
    775     } 
    776  
    777     WC::mapHighBit2Unicode($text); 
    778  
    779     $text = Encode::encode_utf8($text); 
    780  
    781     # Foswiki 1.0 introduces the Foswiki::Response object, which handles all 
    782     # responses. 
    783     if ( UNIVERSAL::isa( $response, 'Foswiki::Response' ) ) { 
    784         $response->header( 
    785             -status  => $status, 
    786             -type    => 'text/plain', 
    787             -charset => 'UTF-8' 
    788         ); 
    789         $response->print($text); 
    790     } 
    791     else {    # Pre-Foswiki-1.0. 
    792               # Turn off AUTOFLUSH 
    793               # See http://perl.apache.org/docs/2.0/user/coding/coding.html 
    794         local $| = 0; 
    795         my $query = Foswiki::Func::getCgiQuery(); 
    796         if ( defined($query) ) { 
    797             my $len; 
    798             { use bytes; $len = length($text); }; 
    799             print $query->header( 
    800                 -status         => $status, 
    801                 -type           => 'text/plain', 
    802                 -charset        => 'UTF-8', 
    803                 -Content_length => $len 
    804             ); 
    805             print $text; 
    806         } 
    807     } 
    808     print STDERR $text if ( $status >= 400 ); 
    809 } 
    810  
    811 # Rest handler for use from Javascript. The 'text' parameter is used to 
    812 # pass the text for conversion. The text must be URI-encoded (this is 
    813 # to support use of this handler from XMLHttpRequest, which gets it 
    814 # wrong). Example: 
    815 # 
    816 # var req = new XMLHttpRequest(); 
    817 # req.open("POST", url, true); 
    818 # req.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 
    819 # var params = "text=" + encodeURIComponent(escape(text)); 
    820 # request.req.setRequestHeader("Content-length", params.length); 
    821 # request.req.setRequestHeader("Connection", "close"); 
    822 # request.req.onreadystatechange = ...; 
    823 # req.send(params); 
    824 # 
    825 sub _restTML2HTML { 
    826     my ( $session, $plugin, $verb, $response ) = @_; 
    827     my $tml = Foswiki::Func::getCgiQuery()->param('text'); 
    828  
    829     $tml = RESTParameter2SiteCharSet($tml); 
    830  
    831     # if the secret ID is present, don't convert again. We are probably 
    832     # going 'back' to this page (doesn't work on IE :-( ) 
    833     if ( $tml =~ /<!--$SECRET_ID-->/ ) { 
    834         return $tml; 
    835     } 
    836  
    837     my $html = 
    838       TranslateTML2HTML( $tml, $session->{webName}, $session->{topicName} ); 
    839  
    840     # Add the secret id to trigger reconversion. Doesn't work if the 
    841     # editor eats HTML comments, so the editor may need to put it back 
    842     # in during final cleanup. 
    843     $html = '<!--' . $SECRET_ID . '-->' . $html; 
    844  
    845     returnRESTResult( $response, 200, $html ); 
    846  
    847     return;    # to prevent further processing 
    848 } 
    849  
    850 # Rest handler for use from Javascript 
    851 sub _restHTML2TML { 
    852     my ( $session, $plugin, $verb, $response ) = @_; 
    853     unless ($html2tml) { 
    854         require Foswiki::Plugins::WysiwygPlugin::HTML2TML; 
    855  
    856         $html2tml = new Foswiki::Plugins::WysiwygPlugin::HTML2TML(); 
    857     } 
    858     my $html = Foswiki::Func::getCgiQuery()->param('text'); 
    859  
    860     $html = RESTParameter2SiteCharSet($html); 
    861  
    862     $html =~ s/<!--$SECRET_ID-->//go; 
    863     my $tml = $html2tml->convert( 
    864         $html, 
    865         { 
    866             web             => $session->{webName}, 
    867             topic           => $session->{topicName}, 
    868             getViewUrl      => \&getViewUrl, 
    869             expandVarsInURL => \&expandVarsInURL, 
    870             very_clean      => 1, 
    871         } 
    872     ); 
    873  
    874     returnRESTResult( $response, 200, $tml ); 
    875     return;    # to prevent further processing 
    876 } 
    877  
    878 # SMELL: foswiki supports proper REST usage of the upload script, 
    879 # so debatable if this is required any more 
    880 sub _restUpload { 
    881     my ( $session, $plugin, $verb, $response ) = @_; 
    882     my $query = Foswiki::Func::getCgiQuery(); 
    883  
    884     # Item1458 ignore uploads not using POST 
    885     if ( $query && $query->method() && uc( $query->method() ) ne 'POST' ) { 
    886         returnRESTResult( $response, 405, "Method not Allowed" ); 
    887         return; 
    888     } 
    889     my ( $web, $topic ) = 
    890       Foswiki::Func::normalizeWebTopicName( undef, $query->param('topic') ); 
    891     $web = 
    892       Foswiki::Sandbox::untaint( $web, \&Foswiki::Sandbox::validateWebName ); 
    893     $topic = Foswiki::Sandbox::untaint( $topic, 
    894         \&Foswiki::Sandbox::validateTopicName ); 
    895     unless ( defined $web && defined $topic ) { 
    896         returnRESTResult( $response, 401, "Access denied" ); 
    897         return;    # to prevent further processing 
    898     } 
    899     my $hideFile    = $query->param('hidefile')    || ''; 
    900     my $fileComment = $query->param('filecomment') || ''; 
    901     my $createLink  = $query->param('createlink')  || ''; 
    902     my $doPropsOnly = $query->param('changeproperties'); 
    903     my $filePath    = $query->param('filepath')    || ''; 
    904     my $fileName    = $query->param('filename')    || ''; 
    905     if ( $filePath && !$fileName ) { 
    906         $filePath =~ m|([^/\\]*$)|; 
    907         $fileName = $1; 
    908     } 
    909     $fileComment =~ s/\s+/ /go; 
    910     $fileComment =~ s/^\s*//o; 
    911     $fileComment =~ s/\s*$//o; 
    912     $fileName    =~ s/\s*$//o; 
    913     $filePath    =~ s/\s*$//o; 
    914  
    915     unless ( 
    916         Foswiki::Func::checkAccessPermission( 
    917             'CHANGE', Foswiki::Func::getWikiName(), 
    918             undef, $topic, $web 
    919         ) 
    920       ) 
    921     { 
    922         returnRESTResult( $response, 401, "Access denied" ); 
    923         return;    # to prevent further processing 
    924     } 
    925  
    926     my ( $fileSize, $fileDate, $tmpFileName ); 
    927  
    928     my $stream = $query->upload('filepath') unless $doPropsOnly; 
    929     my $origName = $fileName; 
    930  
    931     unless ($doPropsOnly) { 
    932  
    933         # SMELL: call to unpublished function 
    934         ( $fileName, $origName ) = 
    935           Foswiki::Sandbox::sanitizeAttachmentName($fileName); 
    936  
    937         # check if upload has non zero size 
    938         if ($stream) { 
    939             my @stats = stat $stream; 
    940             $fileSize = $stats[7]; 
    941             $fileDate = $stats[9]; 
    942         } 
    943  
    944         unless ( $fileSize && $fileName ) { 
    945             returnRESTResult( $response, 500, "Zero-sized file upload" ); 
    946             return;    # to prevent further processing 
    947         } 
    948  
    949         my $maxSize = Foswiki::Func::getPreferencesValue('ATTACHFILESIZELIMIT'); 
    950         $maxSize = 0 unless ( $maxSize =~ /([0-9]+)/o ); 
    951  
    952         if ( $maxSize && $fileSize > $maxSize * 1024 ) { 
    953             returnRESTResult( $response, 500, "OVERSIZED UPLOAD" ); 
    954             return;    # to prevent further processing 
    955         } 
    956     } 
    957  
    958     # SMELL: use of undocumented CGI::tmpFileName 
    959     my $tfp   = $query->tmpFileName( $query->param('filepath') ); 
    960     my $error = Foswiki::Func::saveAttachment( 
    961         $web, $topic, 
    962         $fileName, 
    963         { 
    964             dontlog     => !$Foswiki::cfg{Log}{upload}, 
    965             comment     => $fileComment, 
    966             hide        => $hideFile, 
    967             createlink  => $createLink, 
    968             stream      => $stream, 
    969             filepath    => $filePath, 
    970             filesize    => $fileSize, 
    971             filedate    => $fileDate, 
    972             tmpFilename => $tfp, 
    973         } 
    974     ); 
    975  
    976     close($stream) if $stream; 
    977  
    978     if ($error) { 
    979         returnRESTResult( $response, 500, $error ); 
    980         return;    # to prevent further processing 
    981     } 
    982  
    983     # Otherwise allow the rest dispatcher to write a 200 
    984     return "$origName attached to $web.$topic" 
    985       . ( $origName ne $fileName ? " as $fileName" : '' ); 
    986 } 
    987  
    988 sub _unquote { 
    989     my $text = shift; 
    990     $text =~ s/\\/\\\\/g; 
    991     $text =~ s/\n/\\n/g; 
    992     $text =~ s/\r/\\r/g; 
    993     $text =~ s/\t/\\t/g; 
    994     $text =~ s/"/\\"/g; 
    995     $text =~ s/'/\\'/g; 
    996     return $text; 
    997 } 
    998  
    999 # Get, and return, a list of attachments using JSON 
    1000 sub _restAttachments { 
    1001     my ( $session, $plugin, $verb, $response ) = @_; 
    1002     my ( $web, $topic ) = 
    1003       Foswiki::Func::normalizeWebTopicName( undef, 
    1004         Foswiki::Func::getCgiQuery()->param('topic') ); 
    1005     $web = 
    1006       Foswiki::Sandbox::untaint( $web, \&Foswiki::Sandbox::validateWebName ); 
    1007     $topic = Foswiki::Sandbox::untaint( $topic, 
    1008         \&Foswiki::Sandbox::validateTopicName ); 
    1009     my ( $meta, $text ) = Foswiki::Func::readTopic( $web, $topic ); 
    1010     unless ( 
    1011         Foswiki::Func::checkAccessPermission( 
    1012             'VIEW', Foswiki::Func::getWikiName(), 
    1013             $text, $topic, $web, $meta 
    1014         ) 
    1015       ) 
    1016     { 
    1017         returnRESTResult( $response, 401, "Access denied" ); 
    1018         return;    # to prevent further processing 
    1019     } 
    1020  
    1021     # Create a JSON list of attachment data, sorted by name 
    1022     my @atts; 
    1023     foreach my $att ( sort { $a->{name} cmp $b->{name} } 
    1024         $meta->find('FILEATTACHMENT') ) 
    1025     { 
    1026         push( 
    1027             @atts, 
    1028             '{' . join( 
    1029                 ',', 
    1030                 map { 
    1031                         '"' 
    1032                       . _unquote($_) . '":"' 
    1033                       . _unquote( $att->{$_} ) . '"' 
    1034                   } keys %$att 
    1035               ) 
    1036               . '}' 
    1037         ); 
    1038  
    1039     } 
    1040     return '[' . join( ',', @atts ) . ']'; 
     212sub postConvertURL { 
     213    require Foswiki::Plugins::WysiwygPlugin::Handlers; 
     214    Foswiki::Plugins::WysiwygPlugin::Handlers::postConvertURL(@_); 
    1041215} 
    1042216 
    10432171; 
    1044218__DATA__ 
    1045 # Module of Foswiki - The Free and Open Source Wiki, http://foswiki.org/ 
    1046 # 
    1047 # Copyright (C) 2008 Foswiki Contributors. Foswiki Contributors 
    1048 # are listed in the AUTHORS file in the root of this distribution. 
    1049 # NOTE: Please extend that file, not this notice. 
    1050 # 
    1051 # Additional copyrights apply to some or all of the code in this file: 
    1052 # 
    1053 # Copyright (C) 2005 ILOG http://www.ilog.fr 
    1054 # and TWiki Contributors. All Rights Reserved. TWiki Contributors 
    1055 # are listed in the AUTHORS file in the root of your Foswiki (or TWiki) 
    1056 # distribution. 
    1057 # 
    1058 # This program is free software; you can redistribute it and/or 
    1059 # modify it under the terms of the GNU General Public License 
    1060 # as published by the Free Software Foundation; either version 2 
    1061 # of the License, or (at your option) any later version. For 
    1062 # more details read LICENSE in the root of the TWiki distribution. 
    1063 # 
    1064 # This program is distributed in the hope that it will be useful, 
    1065 # but WITHOUT ANY WARRANTY; without even the implied warranty of 
    1066 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
    1067 # 
    1068 # As per the GPL, removal of this notice is prohibited. 
     219Module of Foswiki - The Free and Open Source Wiki, http://foswiki.org/ 
     220 
     221Copyright (C) 2008-2009 Foswiki Contributors. Foswiki Contributors 
     222are listed in the AUTHORS file in the root of this distribution. 
     223NOTE: Please extend that file, not this notice. 
     224 
     225Additional copyrights apply to some or all of the code in this file: 
     226 
     227Copyright (C) 2005 ILOG http://www.ilog.fr 
     228and TWiki Contributors. All Rights Reserved. TWiki Contributors 
     229are listed in the AUTHORS file in the root of your Foswiki (or TWiki) 
     230distribution. 
     231 
     232This program is free software; you can redistribute it and/or 
     233modify it under the terms of the GNU General Public License 
     234as published by the Free Software Foundation; either version 2 
     235of the License, or (at your option) any later version. For 
     236more details read LICENSE in the root of the TWiki distribution. 
     237 
     238This program is distributed in the hope that it will be useful, 
     239but WITHOUT ANY WARRANTY; without even the implied warranty of 
     240MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
     241 
     242As per the GPL, removal of this notice is prohibited. 
  • trunk/WysiwygPlugin/lib/Foswiki/Plugins/WysiwygPlugin/HTML2TML/Node.pm

    r5573 r5816  
    656656        next unless length( $this->{attrs}->{$attr} );    # ignore nulls 
    657657        return $attr 
    658           if Foswiki::Plugins::WysiwygPlugin::protectedByAttr( $this->{tag}, 
     658          if Foswiki::Plugins::WysiwygPlugin::Handlers::protectedByAttr( $this->{tag}, 
    659659            $attr ); 
    660660    } 
  • trunk/WysiwygPlugin/test/unit/WysiwygPlugin/ExtendedTranslatorTests.pm

    r5573 r5816  
    125125            $extraTML2HTMLOptions{xmltag} = 
    126126              \%Foswiki::Plugins::WysiwygPlugin::xmltag; 
    127             Foswiki::Plugins::WysiwygPlugin::addXMLTag( 'customtag', 
     127            Foswiki::Plugins::WysiwygPlugin::Handlers::addXMLTag( 'customtag', 
    128128                sub { 0 } ); 
    129129        }, 
     
    145145            $extraTML2HTMLOptions{xmltag} = 
    146146              \%Foswiki::Plugins::WysiwygPlugin::xmltag; 
    147             Foswiki::Plugins::WysiwygPlugin::addXMLTag( 'customtag', 
     147            Foswiki::Plugins::WysiwygPlugin::Handlers::addXMLTag( 'customtag', 
    148148                sub { 1 } ); 
    149149        }, 
     
    160160            $extraTML2HTMLOptions{xmltag} = 
    161161              \%Foswiki::Plugins::WysiwygPlugin::xmltag; 
    162             Foswiki::Plugins::WysiwygPlugin::addXMLTag( 'customtag', 
     162            Foswiki::Plugins::WysiwygPlugin::Handlers::addXMLTag( 'customtag', 
    163163                sub { $_[0] =~ s/some/different/; return 1; } ); 
    164164        }, 
     
    176176            $extraTML2HTMLOptions{xmltag} = 
    177177              \%Foswiki::Plugins::WysiwygPlugin::xmltag; 
    178             Foswiki::Plugins::WysiwygPlugin::addXMLTag('customtag'); 
     178            Foswiki::Plugins::WysiwygPlugin::Handlers::addXMLTag('customtag'); 
    179179        }, 
    180180        html => '<p>' 
     
    190190            $extraTML2HTMLOptions{xmltag} = 
    191191              \%Foswiki::Plugins::WysiwygPlugin::xmltag; 
    192             Foswiki::Plugins::WysiwygPlugin::addXMLTag( 'customtag', 
     192            Foswiki::Plugins::WysiwygPlugin::Handlers::addXMLTag( 'customtag', 
    193193                sub { 1 } ); 
    194194        }, 
     
    209209            $extraTML2HTMLOptions{xmltag} = 
    210210              \%Foswiki::Plugins::WysiwygPlugin::xmltag; 
    211             Foswiki::Plugins::WysiwygPlugin::addXMLTag( 'customtag', 
     211            Foswiki::Plugins::WysiwygPlugin::Handlers::addXMLTag( 'customtag', 
    212212                sub { 1 } ); 
    213213        }, 
     
    243243            $extraTML2HTMLOptions{xmltag} = 
    244244              \%Foswiki::Plugins::WysiwygPlugin::xmltag; 
    245             Foswiki::Plugins::WysiwygPlugin::addXMLTag( 'dot', sub { 1 } ); 
     245            Foswiki::Plugins::WysiwygPlugin::Handlers::addXMLTag( 'dot', sub { 1 } ); 
    246246        }, 
    247247        tml => <<'DOT', 
     
    262262            $extraTML2HTMLOptions{xmltag} = 
    263263              \%Foswiki::Plugins::WysiwygPlugin::xmltag; 
    264             Foswiki::Plugins::WysiwygPlugin::addXMLTag( 'customtag', 
     264            Foswiki::Plugins::WysiwygPlugin::Handlers::addXMLTag( 'customtag', 
    265265                sub { 1 } ); 
    266266        }, 
     
    280280            $extraTML2HTMLOptions{xmltag} = 
    281281              \%Foswiki::Plugins::WysiwygPlugin::xmltag; 
    282             Foswiki::Plugins::WysiwygPlugin::addXMLTag( 'customtag', 
     282            Foswiki::Plugins::WysiwygPlugin::Handlers::addXMLTag( 'customtag', 
    283283                sub { 1 } ); 
    284284        }, 
     
    332332            $extraTML2HTMLOptions{xmltag} = 
    333333              \%Foswiki::Plugins::WysiwygPlugin::xmltag; 
    334             Foswiki::Plugins::WysiwygPlugin::addXMLTag( 'customtag', 
     334            Foswiki::Plugins::WysiwygPlugin::Handlers::addXMLTag( 'customtag', 
    335335                sub { 1 } ); 
    336336        }, 
     
    362362            $extraTML2HTMLOptions{xmltag} = 
    363363              \%Foswiki::Plugins::WysiwygPlugin::xmltag; 
    364             Foswiki::Plugins::WysiwygPlugin::addXMLTag( 'customtag', 
     364            Foswiki::Plugins::WysiwygPlugin::Handlers::addXMLTag( 'customtag', 
    365365                sub { 1 } ); 
    366366        }, 
  • trunk/WysiwygPlugin/test/unit/WysiwygPlugin/WysiwygPluginTests.pm

    r5392 r5816  
    2525use Foswiki; 
    2626use Foswiki::Plugins::WysiwygPlugin; 
    27  
     27use Foswiki::Plugins::WysiwygPlugin::Handlers; 
     28use Encode(); 
    2829use strict; 
    2930use Carp; 
     
    150151        save => sub { 
    151152            my $ok = 
    152               Foswiki::Plugins::WysiwygPlugin::_restTML2HTML( $foswiki, undef, 
     153              Foswiki::Plugins::WysiwygPlugin::Handlers::_restTML2HTML( $foswiki, undef, 
    153154                undef, $foswiki->{response} ); 
    154155            $Foswiki::engine->finalize( $foswiki->{response}, 
     
    167168    $out = Encode::decode_utf8($out); 
    168169 
    169     my $id = "<!--$Foswiki::Plugins::WysiwygPlugin::SECRET_ID-->"; 
     170    my $id = "<!--$Foswiki::Plugins::WysiwygPlugin::Handlers::SECRET_ID-->"; 
    170171    $this->assert( $out =~ s/^\s*$id<p>\s*//s, anal($out) ); 
    171172    $out =~ s/\s*<\/p>\s*$//s; 
     
    205206        save => sub { 
    206207            my $ok = 
    207               Foswiki::Plugins::WysiwygPlugin::_restHTML2TML( $foswiki, undef, 
     208              Foswiki::Plugins::WysiwygPlugin::Handlers::_restHTML2TML( $foswiki, undef, 
    208209                undef, $foswiki->{response} ); 
    209210            $Foswiki::engine->finalize( $foswiki->{response}, 
Note: See TracChangeset for help on using the changeset viewer.