# Plugin for TWiki Collaboration Platform, http://TWiki.org/ # # Copyright (C) 2007-2018 Peter Thoeny and TWiki Contributors. # Copyright (C) 2008-2012 Foswiki Contributors. # All Rights Reserved. TWiki Contributors are listed in the # AUTHORS file in the root of this distribution. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details, published at # http://www.gnu.org/copyleft/gpl.html package TWiki::Plugins::TinyMCEPlugin; use strict; use warnings; use Assert; our $VERSION = '$Rev: 30541 (2018-07-16) $'; our $RELEASE = '2018-07-10'; our $SHORTDESCRIPTION = 'Integration of the Tiny MCE WYSIWYG Editor'; our $NO_PREFS_IN_TOPIC = 1; use TWiki::Func (); our %defaultINIT_BROWSER = ( MSIE => '', OPERA => '', GECKO => '"gecko_spellcheck" : true', SAFARI => '', CHROME => '', ); my $query; # Info about browser type my %browserInfo; sub initPlugin { $query = TWiki::Func::getCgiQuery(); return 0 unless $query; unless ( $TWiki::cfg{Plugins}{WysiwygPlugin}{Enabled} ) { TWiki::Func::writeWarning( "TinyMCEPlugin is enabled but WysiwygPlugin is not. Both must be installed and enabled for TinyMCE." ); return 0; } unless ( $TWiki::cfg{Plugins}{JQueryPlugin}{Enabled} ) { TWiki::Func::writeWarning( "TinyMCEPlugin is enabled but JQueryPlugin is not. Both must be installed and enabled for TinyMCE." ); return 0; } # Identify the browser from the user agent string my $ua = $query->user_agent(); if ($ua) { $browserInfo{isMSIE} = $ua =~ /MSIE/; $browserInfo{isMSIE5} = $browserInfo{isMSIE} && ( $ua =~ /MSIE 5/ ); $browserInfo{isMSIE5_0} = $browserInfo{isMSIE} && ( $ua =~ /MSIE 5.0/ ); $browserInfo{isMSIE6} = $browserInfo{isMSIE} && $ua =~ /MSIE 6/; $browserInfo{isMSIE7} = $browserInfo{isMSIE} && $ua =~ /MSIE 7/; $browserInfo{isMSIE8} = $browserInfo{isMSIE} && $ua =~ /MSIE 8/; $browserInfo{isGecko} = $ua =~ /Gecko/; # Will also be true on Safari $browserInfo{isSafari} = $ua =~ /Safari/; # Will also be true on Chrome $browserInfo{isOpera} = $ua =~ /Opera/; $browserInfo{isChrome} = $ua =~ /Chrome/; $browserInfo{isMac} = $ua =~ /Mac/; $browserInfo{isNS7} = $ua =~ /Netscape\/7/; $browserInfo{isNS71} = $ua =~ /Netscape\/7.1/; } my $disable = TWiki::Func::getPreferencesValue('TINYMCEPLUGIN_DISABLE'); my $available = 1; if ( $disable ) { if ( $disable =~ /%/ ) { $disable = TWiki::Func::expandCommonVariables($disable); } if ( TWiki::Func::isTrue($disable) ) { $available = 0; } } TWiki::Func::getContext()->{TinyMCEPluginAvailable} = $available; return 1; } sub _notAvailable { for my $c (qw(TINYMCEPLUGIN_DISABLE NOWYSIWYG)) { return "Disabled by * Set $c = " . TWiki::Func::getPreferencesValue($c) if TWiki::Func::getPreferencesFlag($c); } # Disable TinyMCE if we are on a specialised edit skin my $skin = TWiki::Func::getPreferencesValue('WYSIWYGPLUGIN_WYSIWYGSKIN'); return "$skin is active" if ( $skin && TWiki::Func::getSkin() =~ /\b$skin\b/o ); return "No browser" unless $query; return "Disabled by URL parameter" if $query->param('nowysiwyg'); # Check the client browser to see if it is blacklisted my $ua = TWiki::Func::getPreferencesValue('TINYMCEPLUGIN_BAD_BROWSERS') || '(?i-xsm:Konqueror)'; return 'Unsupported browser: ' . $query->user_agent() if $ua && $query->user_agent() && $query->user_agent() =~ /$ua/; return 0; } sub beforeEditHandler { my ( $text, $topic, $web ) = @_; my $mess = _notAvailable(); if ($mess) { if ( ( $mess !~ /^Disabled/ || DEBUG ) && defined &TWiki::Func::setPreferencesValue ) { TWiki::Func::setPreferencesValue( 'EDITOR_MESSAGE', 'WYSIWYG could not be started: ' . $mess ); } return; } if ( defined &TWiki::Func::setPreferencesValue ) { TWiki::Func::setPreferencesValue( 'EDITOR_HELP', 'TinyMCEQuickHelp' ); } my $initTopic = TWiki::Func::getPreferencesValue('TINYMCEPLUGIN_INIT_TOPIC') || $TWiki::cfg{SystemWebName} . '.TinyMCEPlugin'; my $init = TWiki::Func::getPreferencesValue('TINYMCEPLUGIN_INIT') || TWiki::Func::expandCommonVariables( '%INCLUDE{"' . $initTopic . '" section="TINYMCEPLUGIN_INIT" warn="off"}%', $topic, $web ); my $browser = ''; # The order of these conditions is important, because browsers # spoof eachother if ( $browserInfo{isChrome} ) { $browser = 'CHROME'; } elsif ( $browserInfo{isSafari} ) { $browser = 'SAFARI'; } elsif ( $browserInfo{isOpera} ) { $browser = 'OPERA'; } elsif ( $browserInfo{isGecko} ) { $browser = 'GECKO'; } elsif ( $browserInfo{isMSIE} ) { $browser = 'MSIE'; } if ($browser) { my $settings = TWiki::Func::getPreferencesValue( 'TINYMCEPLUGIN_INIT_' . $browser ) || $defaultINIT_BROWSER{$browser}; if ($settings) { $init = join( ',', ( split( ',', $init ), split( ',', $settings ) ) ); } } require TWiki::Plugins::WysiwygPlugin; $mess = TWiki::Plugins::WysiwygPlugin::notWysiwygEditable($text); if ($mess) { if ( defined &TWiki::Func::setPreferencesValue ) { TWiki::Func::setPreferencesValue( 'EDITOR_MESSAGE', 'WYSIWYG could not be started: ' . $mess ); TWiki::Func::setPreferencesValue( 'EDITOR_HELP', undef ); } return; } my $USE_SRC = ''; if ( TWiki::Func::getPreferencesValue('TINYMCEPLUGIN_DEBUG') ) { $USE_SRC = '_src'; } # Add the Javascript for the editor. When it starts up the editor will # use a REST call to the WysiwygPlugin tml2html REST handler to convert # the textarea content from TML to HTML. my $pluginURL = '%PUBURLPATH%/%SYSTEMWEB%/TinyMCEPlugin'; my $tmceURL = $pluginURL . '/tinymce/jscripts/tiny_mce'; # URL-encode the version number to include in the .js URLs, so that # the browser re-fetches the .js when this plugin is upgraded. my $encodedVersion = $VERSION; # SMELL: This regex (and the one applied to $metainit, above) # duplicates TWiki::urlEncode(), but TWiki::Func.pm does not # expose that function, so plugins may not use it $encodedVersion =~ s/([^0-9a-zA-Z-_.:~!*'\/%])/'%'.sprintf('%02x',ord($1))/ge; # Inline JS to set config? Heresy! Well, we were encoding into SCRIPT TWiki::Func::addToHEAD( 'TinyMCEPlugin', $scripts ); # See %SYSTEMWEB%.IfStatements for a description of this context id. TWiki::Func::getContext()->{textareas_hijacked} = 1; return; } 1;