← Index
NYTProf Performance Profile   « line view »
For ./view
  Run on Fri Jul 31 19:05:14 2015
Reported on Fri Jul 31 19:08:10 2015

Filename/var/www/foswiki11/lib/Foswiki/Plugins/WysiwygPlugin.pm
StatementsExecuted 65 statements in 1.83ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
4425.73ms14.6msFoswiki::Plugins::WysiwygPlugin::::addXMLTagFoswiki::Plugins::WysiwygPlugin::addXMLTag
71179µs162µsFoswiki::Plugins::WysiwygPlugin::::beforeCommonTagsHandlerFoswiki::Plugins::WysiwygPlugin::beforeCommonTagsHandler
11169µs251µsFoswiki::Plugins::WysiwygPlugin::::initPluginFoswiki::Plugins::WysiwygPlugin::initPlugin
51127µs27µsFoswiki::Plugins::WysiwygPlugin::::postRenderingHandlerFoswiki::Plugins::WysiwygPlugin::postRenderingHandler
11116µs29µsFoswiki::Plugins::WysiwygPlugin::::BEGIN@25Foswiki::Plugins::WysiwygPlugin::BEGIN@25
11113µs27µsFoswiki::Plugins::WysiwygPlugin::::BEGIN@85Foswiki::Plugins::WysiwygPlugin::BEGIN@85
11113µs60µsFoswiki::Plugins::WysiwygPlugin::::modifyHeaderHandlerFoswiki::Plugins::WysiwygPlugin::modifyHeaderHandler
11110µs16µsFoswiki::Plugins::WysiwygPlugin::::BEGIN@26Foswiki::Plugins::WysiwygPlugin::BEGIN@26
11110µs30µsFoswiki::Plugins::WysiwygPlugin::::BEGIN@33Foswiki::Plugins::WysiwygPlugin::BEGIN@33
11110µs24µsFoswiki::Plugins::WysiwygPlugin::::BEGIN@28Foswiki::Plugins::WysiwygPlugin::BEGIN@28
1118µs17µsFoswiki::Plugins::WysiwygPlugin::::BEGIN@87Foswiki::Plugins::WysiwygPlugin::BEGIN@87
0000s0sFoswiki::Plugins::WysiwygPlugin::::WHYFoswiki::Plugins::WysiwygPlugin::WHY
0000s0sFoswiki::Plugins::WysiwygPlugin::::__ANON__[:57]Foswiki::Plugins::WysiwygPlugin::__ANON__[:57]
0000s0sFoswiki::Plugins::WysiwygPlugin::::__ANON__[:59]Foswiki::Plugins::WysiwygPlugin::__ANON__[:59]
0000s0sFoswiki::Plugins::WysiwygPlugin::::__ANON__[:61]Foswiki::Plugins::WysiwygPlugin::__ANON__[:61]
0000s0sFoswiki::Plugins::WysiwygPlugin::::__ANON__[:63]Foswiki::Plugins::WysiwygPlugin::__ANON__[:63]
0000s0sFoswiki::Plugins::WysiwygPlugin::::__ANON__[:65]Foswiki::Plugins::WysiwygPlugin::__ANON__[:65]
0000s0sFoswiki::Plugins::WysiwygPlugin::::__ANON__[:68]Foswiki::Plugins::WysiwygPlugin::__ANON__[:68]
0000s0sFoswiki::Plugins::WysiwygPlugin::::__ANON__[:70]Foswiki::Plugins::WysiwygPlugin::__ANON__[:70]
0000s0sFoswiki::Plugins::WysiwygPlugin::::__ANON__[:72]Foswiki::Plugins::WysiwygPlugin::__ANON__[:72]
0000s0sFoswiki::Plugins::WysiwygPlugin::::__ANON__[:74]Foswiki::Plugins::WysiwygPlugin::__ANON__[:74]
0000s0sFoswiki::Plugins::WysiwygPlugin::::_executeFoswiki::Plugins::WysiwygPlugin::_execute
0000s0sFoswiki::Plugins::WysiwygPlugin::::afterEditHandlerFoswiki::Plugins::WysiwygPlugin::afterEditHandler
0000s0sFoswiki::Plugins::WysiwygPlugin::::beforeEditHandlerFoswiki::Plugins::WysiwygPlugin::beforeEditHandler
0000s0sFoswiki::Plugins::WysiwygPlugin::::beforeMergeHandlerFoswiki::Plugins::WysiwygPlugin::beforeMergeHandler
0000s0sFoswiki::Plugins::WysiwygPlugin::::beforeSaveHandlerFoswiki::Plugins::WysiwygPlugin::beforeSaveHandler
0000s0sFoswiki::Plugins::WysiwygPlugin::::notWysiwygEditableFoswiki::Plugins::WysiwygPlugin::notWysiwygEditable
0000s0sFoswiki::Plugins::WysiwygPlugin::::postConvertURLFoswiki::Plugins::WysiwygPlugin::postConvertURL
0000s0sFoswiki::Plugins::WysiwygPlugin::::startRenderingHandlerFoswiki::Plugins::WysiwygPlugin::startRenderingHandler
0000s0sFoswiki::Plugins::WysiwygPlugin::::wysiwygEditingDisabledForThisContentFoswiki::Plugins::WysiwygPlugin::wysiwygEditingDisabledForThisContent
0000s0sFoswiki::Plugins::WysiwygPlugin::::wysiwygEditingNotPossibleForThisContentFoswiki::Plugins::WysiwygPlugin::wysiwygEditingNotPossibleForThisContent
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1# See bottom of file for license and copyright information
2
3=begin TML
4
5---+ package WysiwygPlugin
6
7This plugin is responsible for translating TML to HTML before an edit starts
8and translating the resultant HTML back into TML.
9
10Note: In the case of a new topic, you might expect to see the "create topic"
11screen in the editor when it goes back to Foswiki for the topic content. This
12doesn't happen because the earliest possible handler is called on the topic
13content and not the template. The template is effectively ignored and a blank
14document is sent to the editor.
15
16Attachment uploads can be handled by URL requests from the editor to the rest
17handler in this plugin. This avoids the need to add any scripts to the bin dir.
18You will have to use a form, though, as XmlHttpRequest does not support file
19uploads.
20
21=cut
22
23package Foswiki::Plugins::WysiwygPlugin;
24
25229µs243µs
# spent 29µs (16+13) within Foswiki::Plugins::WysiwygPlugin::BEGIN@25 which was called: # once (16µs+13µs) by Foswiki::Plugin::BEGIN@2.37 at line 25
use strict;
# spent 29µs making 1 call to Foswiki::Plugins::WysiwygPlugin::BEGIN@25 # spent 13µs making 1 call to strict::import
26225µs221µs
# spent 16µs (10+5) within Foswiki::Plugins::WysiwygPlugin::BEGIN@26 which was called: # once (10µs+5µs) by Foswiki::Plugin::BEGIN@2.37 at line 26
use warnings;
# spent 16µs making 1 call to Foswiki::Plugins::WysiwygPlugin::BEGIN@26 # spent 5µs making 1 call to warnings::import
27
28244µs237µs
# spent 24µs (10+14) within Foswiki::Plugins::WysiwygPlugin::BEGIN@28 which was called: # once (10µs+14µs) by Foswiki::Plugin::BEGIN@2.37 at line 28
use Assert;
# spent 24µs making 1 call to Foswiki::Plugins::WysiwygPlugin::BEGIN@28 # spent 14µs making 1 call to Assert::import
29
301500nsour $SHORTDESCRIPTION = 'Translator framework for WYSIWYG editors';
311200nsour $NO_PREFS_IN_TOPIC = 1;
32
333364µs356µs
# spent 30µs (10+20) within Foswiki::Plugins::WysiwygPlugin::BEGIN@33 which was called: # once (10µs+20µs) by Foswiki::Plugin::BEGIN@2.37 at line 33
use version; our $VERSION = version->declare("v1.1.16");
# spent 30µs making 1 call to Foswiki::Plugins::WysiwygPlugin::BEGIN@33 # spent 20µs making 1 call to version::import # spent 5µs making 1 call to version::vxs::declare
341300nsour $RELEASE = '16 May 2013';
35
361300nsour %xmltag;
37
38# The following are all used in Handlers, but declared here so we can
39# check them without loading the handlers module
401100nsour $tml2html;
4110sour $recursionBlock;
421100nsour %FoswikiCompatibility;
43
44# Set to 1 for reasons for rejection
45sub WHY { 0 }
46
47
# spent 251µs (69+181) within Foswiki::Plugins::WysiwygPlugin::initPlugin which was called: # once (69µs+181µs) by Foswiki::Plugin::__ANON__[/var/www/foswiki11/lib/Foswiki/Plugin.pm:241] at line 234 of /var/www/foswiki11/lib/Foswiki/Plugin.pm
sub initPlugin {
4812µs my ( $topic, $web, $user, $installWeb ) = @_;
49
50 # %OWEB%.%OTOPIC% is the topic where the initial content should be
51 # grabbed from, as defined in templates/edit.skin.tmpl
52 # Note; rather than declaring the handlers in this module, we use
53 # the _execute function to hand off execution to
54 # Foswiki::Plugins::WysiwygPlugin::Handlers. The goal is to keep this
55 # module small and light so it loads fast.
56 Foswiki::Func::registerTagHandler( 'OWEB',
5716µs128µs sub { _execute( '_OWEBTAG', @_ ) } );
# spent 28µs making 1 call to Foswiki::Func::registerTagHandler
58 Foswiki::Func::registerTagHandler( 'OTOPIC',
5916µs120µs sub { _execute( '_OTOPICTAG', @_ ) } );
# spent 20µs making 1 call to Foswiki::Func::registerTagHandler
60 Foswiki::Func::registerTagHandler( 'WYSIWYG_TEXT',
6114µs118µs sub { _execute( '_WYSIWYG_TEXT', @_ ) } );
# spent 18µs making 1 call to Foswiki::Func::registerTagHandler
62 Foswiki::Func::registerTagHandler( 'JAVASCRIPT_TEXT',
6314µs120µs sub { _execute( '_JAVASCRIPT_TEXT', @_ ) } );
# spent 20µs making 1 call to Foswiki::Func::registerTagHandler
64 Foswiki::Func::registerTagHandler( 'WYSIWYG_SECRET_ID',
6514µs118µs sub { _execute( '_SECRET_ID', @_ ) } );
# spent 18µs making 1 call to Foswiki::Func::registerTagHandler
66
67 Foswiki::Func::registerRESTHandler( 'tml2html',
6814µs121µs sub { _execute( '_restTML2HTML', @_ ) } );
# spent 21µs making 1 call to Foswiki::Func::registerRESTHandler
69 Foswiki::Func::registerRESTHandler( 'html2tml',
7016µs118µs sub { _execute( '_restHTML2TML', @_ ) } );
# spent 18µs making 1 call to Foswiki::Func::registerRESTHandler
71 Foswiki::Func::registerRESTHandler( 'upload',
7214µs117µs sub { _execute( '_restUpload', @_ ) } );
# spent 17µs making 1 call to Foswiki::Func::registerRESTHandler
73 Foswiki::Func::registerRESTHandler( 'attachments',
7414µs120µs sub { _execute( '_restAttachments', @_ ) } );
# spent 20µs making 1 call to Foswiki::Func::registerRESTHandler
75
76 # Plugin correctly initialized
7715µs return 1;
78}
79
80sub _execute {
81 my $fn = shift;
82
83 require Foswiki::Plugins::WysiwygPlugin::Handlers;
84 $fn = 'Foswiki::Plugins::WysiwygPlugin::Handlers::' . $fn;
85235µs241µs
# spent 27µs (13+14) within Foswiki::Plugins::WysiwygPlugin::BEGIN@85 which was called: # once (13µs+14µs) by Foswiki::Plugin::BEGIN@2.37 at line 85
no strict 'refs';
# spent 27µs making 1 call to Foswiki::Plugins::WysiwygPlugin::BEGIN@85 # spent 14µs making 1 call to strict::unimport
86 return &$fn(@_);
8721.03ms226µs
# spent 17µs (8+9) within Foswiki::Plugins::WysiwygPlugin::BEGIN@87 which was called: # once (8µs+9µs) by Foswiki::Plugin::BEGIN@2.37 at line 87
use strict 'refs';
# spent 17µs making 1 call to Foswiki::Plugins::WysiwygPlugin::BEGIN@87 # spent 9µs making 1 call to strict::import
88}
89
90=begin TML
91
92---++ StaticMethod notWysiwygEditable($text) -> $boolean
93Determine if the given =$text= is WYSIWYG editable, based on the topic content
94and the value of the Foswiki preferences WYSIWYG_EXCLUDE and
95WYSIWYG_EDITABLE_CALLS. Returns a descriptive string if the text is not
96editable, 0 otherwise.
97
98=cut
99
100sub notWysiwygEditable {
101
102 #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
117 #my ($text, $exclusions) = @_;
118
119 my $exclusions = $_[1];
120 unless ( defined($exclusions) ) {
121 $exclusions = Foswiki::Func::getPreferencesValue('WYSIWYG_EXCLUDE')
122 || '';
123 }
124
125 # Check for explicit exclusions before generic, non-configurable
126 # purely content-related reasons for exclusion
127 if ($exclusions) {
128 my $calls_ok =
129 Foswiki::Func::getPreferencesValue('WYSIWYG_EDITABLE_CALLS')
130 || '---';
131 $calls_ok =~ s/\s//g;
132
133 my $ok = 1;
134 if ( $exclusions =~ /calls/
135 && $_[0] =~ /%((?!($calls_ok){)[A-Z_]+{.*?})%/s )
136 {
137 print STDERR "WYSIWYG_DEBUG: has calls $1 (not in $calls_ok)\n"
138 if (WHY);
139 return "Text contains calls";
140 }
141 if ( $exclusions =~ /(macros|variables)/ && $_[0] =~ /%([A-Z_]+)%/s ) {
142 print STDERR "$exclusions WYSIWYG_DEBUG: has macros $1\n"
143 if (WHY);
144 return "Text contains macros";
145 }
146 if ( $exclusions =~ /html/
147 && $_[0] =~ /<\/?((?!literal|verbatim|noautolink|nop|br)\w+)/i )
148 {
149 print STDERR "WYSIWYG_DEBUG: has html: $1\n"
150 if (WHY);
151 return "Text contains HTML";
152 }
153 if ( $exclusions =~ /comments/ && $_[0] =~ /<[!]--/ ) {
154 print STDERR "WYSIWYG_DEBUG: has comments\n"
155 if (WHY);
156 return "Text contains comments";
157 }
158 if ( $exclusions =~ /pre/ && $_[0] =~ /<pre\w/i ) {
159 print STDERR "WYSIWYG_DEBUG: has pre\n"
160 if (WHY);
161 return "Text contains PRE";
162 }
163 if ( $exclusions =~ /script/ && $_[0] =~ /<script\W/i ) {
164 print STDERR "WYSIWYG_DEBUG: has script\n"
165 if (WHY);
166 return "Text contains script";
167 }
168 if ( $exclusions =~ /style/ && $_[0] =~ /<style\W/i ) {
169 print STDERR "WYSIWYG_DEBUG: has style\n"
170 if (WHY);
171 return "Text contains style";
172 }
173 if ( $exclusions =~ /table/ && $_[0] =~ /<table\W/i ) {
174 print STDERR "WYSIWYG_DEBUG: has table\n"
175 if (WHY);
176 return "Text contains table";
177 }
178 }
179
180 # Copy the content.
181 # Then crunch verbatim blocks, because verbatim blocks may
182 # contain *anything*.
183 my $text = $_[0];
184
185 # Look for combinations of sticky and other markup that cause
186 # problems together
187 for my $tag ('literal') {
188 while ( $text =~ /<$tag\b[^>]*>(.*?)<\/$tag>/gsi ) {
189 my $inner = $1;
190 if ( $inner =~ /<sticky\b[^>]*>/i ) {
191 print STDERR "WYSIWYG_DEBUG: <sticky> inside <$tag>\n"
192 if (WHY);
193 return "&lt;sticky&gt; inside &lt;$tag&gt;";
194 }
195 }
196 }
197
198 my $wasAVerbatimTag = "\000verbatim\001";
199 while ( $text =~ s/<verbatim\b[^>]*>(.*?)<\/verbatim>/$wasAVerbatimTag/i ) {
200
201 #my $content = $1;
202 # If there is any content that breaks conversion if it is inside
203 # a verbatim block, check for it here:
204 }
205
206 # Look for combinations of verbatim and other markup that cause
207 # problems together
208 for my $tag ('literal') {
209 while ( $text =~ /<$tag\b[^>]*>(.*?)<\/$tag>/gsi ) {
210 my $inner = $1;
211 if ( $inner =~ /$wasAVerbatimTag/i ) {
212 print STDERR "WYSIWYG_DEBUG: <verbatim> inside <$tag>\n"
213 if (WHY);
214 return "&lt;verbatim&gt; inside &lt;$tag&gt;";
215 }
216 }
217 }
218
219 return 0;
220}
221
222sub wysiwygEditingNotPossibleForThisContent {
223 eval {
224 require Foswiki::Plugins::WysiwygPlugin::Handlers;
225 Foswiki::Plugins::WysiwygPlugin::Handlers::TranslateTML2HTML( $_[0],
226 'Fakewebname', 'FakeTopicName', dieOnError => 1 );
227 };
228 if ($@) {
229 print STDERR
230 "WYSIWYG_DEBUG: TML2HTML conversion threw an exception: $@\n"
231 if (WHY);
232 return "TML2HTML conversion fails";
233 }
234
235 return 0;
236}
237
238
# spent 14.6ms (5.73+8.88) within Foswiki::Plugins::WysiwygPlugin::addXMLTag which was called 4 times, avg 3.65ms/call: # once (5.72ms+8.85ms) by Foswiki::Plugins::DirectedGraphPlugin::initPlugin at line 323 of /var/www/foswiki11/lib/Foswiki/Plugins/DirectedGraphPlugin.pm # once (6µs+11µs) by Foswiki::Plugins::DirectedGraphPlugin::initPlugin at line 326 of /var/www/foswiki11/lib/Foswiki/Plugins/DirectedGraphPlugin.pm # once (5µs+11µs) by Foswiki::Plugins::PlantUMLPlugin::initPlugin at line 168 of /var/www/foswiki11/lib/Foswiki/Plugins/PlantUMLPlugin.pm # once (4µs+8µs) by Foswiki::Plugins::PlantUMLPlugin::initPlugin at line 171 of /var/www/foswiki11/lib/Foswiki/Plugins/PlantUMLPlugin.pm
sub addXMLTag {
2394134µs require Foswiki::Plugins::WysiwygPlugin::Handlers;
240424µs447µs Foswiki::Plugins::WysiwygPlugin::Handlers::addXMLTag(@_);
# spent 47µs making 4 calls to Foswiki::Plugins::WysiwygPlugin::Handlers::addXMLTag, avg 12µs/call
241}
242
243sub postConvertURL {
244 require Foswiki::Plugins::WysiwygPlugin::Handlers;
245 Foswiki::Plugins::WysiwygPlugin::Handlers::postConvertURL(@_);
246}
247
248sub beforeEditHandler {
249 _execute( 'beforeEditHandler', @_ );
250}
251
252sub beforeSaveHandler {
253 _execute( 'beforeSaveHandler', @_ );
254}
255
256sub beforeMergeHandler {
257 _execute( 'beforeMergeHandler', @_ );
258}
259
260sub afterEditHandler {
261 _execute( 'afterEditHandler', @_ );
262}
263
264# The next few handlers have to be executed on topic views, so have to
265# avoid lazy-loading the handlers unless absolutely necessary.
266
2671700ns$FoswikiCompatibility{startRenderingHandler} = 2.1;
268
269sub startRenderingHandler {
270 $_[0] =~ s#</?sticky>##g;
271}
272
273
# spent 162µs (79+84) within Foswiki::Plugins::WysiwygPlugin::beforeCommonTagsHandler which was called 7 times, avg 23µs/call: # 7 times (79µs+84µs) by Foswiki::Plugin::invoke at line 294 of /var/www/foswiki11/lib/Foswiki/Plugin.pm, avg 23µs/call
sub beforeCommonTagsHandler {
27473µs return if $recursionBlock;
275745µs758µs return unless Foswiki::Func::getContext()->{body_text};
# spent 58µs making 7 calls to Foswiki::Func::getContext, avg 8µs/call
276
27712µs16µs my $query = Foswiki::Func::getCgiQuery();
# spent 6µs making 1 call to Foswiki::Func::getCgiQuery
278
2791400ns return unless $query;
280
28114µs120µs return unless defined( $query->param('wysiwyg_edit') );
# spent 20µs making 1 call to Foswiki::Request::param
282 _execute( 'beforeCommonTagsHandler', @_ );
283}
284
285
# spent 27µs within Foswiki::Plugins::WysiwygPlugin::postRenderingHandler which was called 5 times, avg 5µs/call: # 5 times (27µs+0s) by Foswiki::Plugin::invoke at line 294 of /var/www/foswiki11/lib/Foswiki/Plugin.pm, avg 5µs/call
sub postRenderingHandler {
286522µs return if ( $recursionBlock || !$tml2html );
287 _execute( 'postRenderingHandler', @_ );
288}
289
290
# spent 60µs (13+48) within Foswiki::Plugins::WysiwygPlugin::modifyHeaderHandler which was called: # once (13µs+48µs) by Foswiki::Plugin::invoke at line 294 of /var/www/foswiki11/lib/Foswiki/Plugin.pm
sub modifyHeaderHandler {
2911800ns my ( $headers, $query ) = @_;
292
293112µs148µs if ( $query->param('wysiwyg_edit') ) {
# spent 48µs making 1 call to Foswiki::Request::param
294 _execute( 'modifyHeaderHandler', @_ );
295 }
296}
297
29816µs1;
299__END__