← Index
NYTProf Performance Profile   « block view • line view • sub view »
For /usr/local/src/github.com/foswiki/core/bin/view
  Run on Sun Dec 4 17:17:59 2011
Reported on Sun Dec 4 17:26:34 2011

Filename/usr/local/src/github.com/foswiki/core/lib/Foswiki/Plugins/WysiwygPlugin.pm
StatementsExecuted 2309 statements in 13.6ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
11311113.8ms30.1msFoswiki::Plugins::WysiwygPlugin::::beforeCommonTagsHandlerFoswiki::Plugins::WysiwygPlugin::beforeCommonTagsHandler
111139µs583µsFoswiki::Plugins::WysiwygPlugin::::initPluginFoswiki::Plugins::WysiwygPlugin::initPlugin
51140µs40µsFoswiki::Plugins::WysiwygPlugin::::postRenderingHandlerFoswiki::Plugins::WysiwygPlugin::postRenderingHandler
11132µs94µsFoswiki::Plugins::WysiwygPlugin::::modifyHeaderHandlerFoswiki::Plugins::WysiwygPlugin::modifyHeaderHandler
11129µs36µsFoswiki::Plugins::WysiwygPlugin::::BEGIN@25Foswiki::Plugins::WysiwygPlugin::BEGIN@25
11120µs60µsFoswiki::Plugins::WysiwygPlugin::::BEGIN@85Foswiki::Plugins::WysiwygPlugin::BEGIN@85
11118µs60µsFoswiki::Plugins::WysiwygPlugin::::BEGIN@28Foswiki::Plugins::WysiwygPlugin::BEGIN@28
11117µs34µsFoswiki::Plugins::WysiwygPlugin::::BEGIN@26Foswiki::Plugins::WysiwygPlugin::BEGIN@26
11116µs45µ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::::addXMLTagFoswiki::Plugins::WysiwygPlugin::addXMLTag
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
25246µs244µs
# spent 36µs (29+7) within Foswiki::Plugins::WysiwygPlugin::BEGIN@25 which was called: # once (29µs+7µs) by Foswiki::Plugin::BEGIN@2.21 at line 25
use strict;
# spent 36µs making 1 call to Foswiki::Plugins::WysiwygPlugin::BEGIN@25 # spent 7µs making 1 call to strict::import
26245µs252µs
# spent 34µs (17+18) within Foswiki::Plugins::WysiwygPlugin::BEGIN@26 which was called: # once (17µs+18µs) by Foswiki::Plugin::BEGIN@2.21 at line 26
use warnings;
# spent 34µs making 1 call to Foswiki::Plugins::WysiwygPlugin::BEGIN@26 # spent 18µs making 1 call to warnings::import
27
282702µs2102µs
# spent 60µs (18+42) within Foswiki::Plugins::WysiwygPlugin::BEGIN@28 which was called: # once (18µs+42µs) by Foswiki::Plugin::BEGIN@2.21 at line 28
use Assert;
# spent 60µs making 1 call to Foswiki::Plugins::WysiwygPlugin::BEGIN@28 # spent 42µs making 1 call to Assert::import
29
3012µsour $SHORTDESCRIPTION = 'Translator framework for WYSIWYG editors';
3112µsour $NO_PREFS_IN_TOPIC = 1;
3211µsour $VERSION = '$Rev$';
33
3412µsour $RELEASE = '1.1.3';
35
3611µsour %xmltag;
37
38# The following are all used in Handlers, but declared here so we can
39# check them without loading the handlers module
401900nsour $tml2html;
411700nsour $recursionBlock;
4211µsour %FoswikiCompatibility;
43
44# Set to 1 for reasons for rejection
45sub WHY { 0 }
46
47
# spent 583µs (139+444) within Foswiki::Plugins::WysiwygPlugin::initPlugin which was called: # once (139µs+444µs) by Foswiki::Plugin::__ANON__[/usr/local/src/github.com/foswiki/core/lib/Foswiki/Plugin.pm:235] at line 228 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Plugin.pm
sub initPlugin {
4811101µ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',
57148µs sub { _execute( '_OWEBTAG', @_ ) } );
# spent 48µs making 1 call to Foswiki::Func::registerTagHandler
58 Foswiki::Func::registerTagHandler( 'OTOPIC',
59146µs sub { _execute( '_OTOPICTAG', @_ ) } );
# spent 46µs making 1 call to Foswiki::Func::registerTagHandler
60 Foswiki::Func::registerTagHandler( 'WYSIWYG_TEXT',
61145µs sub { _execute( '_WYSIWYG_TEXT', @_ ) } );
# spent 45µs making 1 call to Foswiki::Func::registerTagHandler
62 Foswiki::Func::registerTagHandler( 'JAVASCRIPT_TEXT',
63145µs sub { _execute( '_JAVASCRIPT_TEXT', @_ ) } );
# spent 45µs making 1 call to Foswiki::Func::registerTagHandler
64 Foswiki::Func::registerTagHandler( 'WYSIWYG_SECRET_ID',
65144µs sub { _execute( '_SECRET_ID', @_ ) } );
# spent 44µs making 1 call to Foswiki::Func::registerTagHandler
66
67 Foswiki::Func::registerRESTHandler( 'tml2html',
68171µs sub { _execute( '_restTML2HTML', @_ ) } );
# spent 71µs making 1 call to Foswiki::Func::registerRESTHandler
69 Foswiki::Func::registerRESTHandler( 'html2tml',
70149µs sub { _execute( '_restHTML2TML', @_ ) } );
# spent 49µs making 1 call to Foswiki::Func::registerRESTHandler
71 Foswiki::Func::registerRESTHandler( 'upload',
72151µs sub { _execute( '_restUpload', @_ ) } );
# spent 51µs making 1 call to Foswiki::Func::registerRESTHandler
73 Foswiki::Func::registerRESTHandler( 'attachments',
74145µs sub { _execute( '_restAttachments', @_ ) } );
# spent 45µs making 1 call to Foswiki::Func::registerRESTHandler
75
76 # Plugin correctly initialized
77 return 1;
78}
79
80sub _execute {
81 my $fn = shift;
82
83 require Foswiki::Plugins::WysiwygPlugin::Handlers;
84 $fn = 'Foswiki::Plugins::WysiwygPlugin::Handlers::' . $fn;
85268µs2100µs
# spent 60µs (20+40) within Foswiki::Plugins::WysiwygPlugin::BEGIN@85 which was called: # once (20µs+40µs) by Foswiki::Plugin::BEGIN@2.21 at line 85
no strict 'refs';
# spent 60µs making 1 call to Foswiki::Plugins::WysiwygPlugin::BEGIN@85 # spent 40µs making 1 call to strict::unimport
86 return &$fn(@_);
8721.76ms275µs
# spent 45µs (16+29) within Foswiki::Plugins::WysiwygPlugin::BEGIN@87 which was called: # once (16µs+29µs) by Foswiki::Plugin::BEGIN@2.21 at line 87
use strict 'refs';
# spent 45µs making 1 call to Foswiki::Plugins::WysiwygPlugin::BEGIN@87 # spent 29µ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+)/ )
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/ ) {
159 print STDERR "WYSIWYG_DEBUG: has pre\n"
160 if (WHY);
161 return "Text contains PRE";
162 }
163 }
164
165 # Copy the content.
166 # Then crunch verbatim blocks, because verbatim blocks may
167 # contain *anything*.
168 my $text = $_[0];
169
170 # Look for combinations of sticky and other markup that cause
171 # problems together
172 for my $tag ('literal') {
173 while ( $text =~ /<$tag\b[^>]*>(.*?)<\/$tag>/gsi ) {
174 my $inner = $1;
175 if ( $inner =~ /<sticky\b[^>]*>/i ) {
176 print STDERR "WYSIWYG_DEBUG: <sticky> inside <$tag>\n"
177 if (WHY);
178 return "&lt;sticky&gt; inside &lt;$tag&gt;";
179 }
180 }
181 }
182
183 my $wasAVerbatimTag = "\000verbatim\001";
184 while ( $text =~ s/<verbatim\b[^>]*>(.*?)<\/verbatim>/$wasAVerbatimTag/i ) {
185
186 #my $content = $1;
187 # If there is any content that breaks conversion if it is inside
188 # a verbatim block, check for it here:
189 }
190
191 # Look for combinations of verbatim and other markup that cause
192 # problems together
193 for my $tag ('literal') {
194 while ( $text =~ /<$tag\b[^>]*>(.*?)<\/$tag>/gsi ) {
195 my $inner = $1;
196 if ( $inner =~ /$wasAVerbatimTag/i ) {
197 print STDERR "WYSIWYG_DEBUG: <verbatim> inside <$tag>\n"
198 if (WHY);
199 return "&lt;verbatim&gt; inside &lt;$tag&gt;";
200 }
201 }
202 }
203
204 return 0;
205}
206
207sub wysiwygEditingNotPossibleForThisContent {
208 eval {
209 require Foswiki::Plugins::WysiwygPlugin::Handlers;
210 Foswiki::Plugins::WysiwygPlugin::Handlers::TranslateTML2HTML( $_[0],
211 'Fakewebname', 'FakeTopicName', dieOnError => 1 );
212 };
213 if ($@) {
214 print STDERR
215 "WYSIWYG_DEBUG: TML2HTML conversion threw an exception: $@\n"
216 if (WHY);
217 return "TML2HTML conversion fails";
218 }
219
220 return 0;
221}
222
223sub addXMLTag {
224 require Foswiki::Plugins::WysiwygPlugin::Handlers;
225 Foswiki::Plugins::WysiwygPlugin::Handlers::addXMLTag(@_);
226}
227
228sub postConvertURL {
229 require Foswiki::Plugins::WysiwygPlugin::Handlers;
230 Foswiki::Plugins::WysiwygPlugin::Handlers::postConvertURL(@_);
231}
232
233sub beforeEditHandler {
234 _execute( 'beforeEditHandler', @_ );
235}
236
237sub beforeSaveHandler {
238 _execute( 'beforeSaveHandler', @_ );
239}
240
241sub beforeMergeHandler {
242 _execute( 'beforeMergeHandler', @_ );
243}
244
245sub afterEditHandler {
246 _execute( 'afterEditHandler', @_ );
247}
248
249# The next few handlers have to be executed on topic views, so have to
250# avoid lazy-loading the handlers unless absolutely necessary.
251
25212µs$FoswikiCompatibility{startRenderingHandler} = 2.1;
253
254sub startRenderingHandler {
255 $_[0] =~ s#</?sticky>##g;
256}
257
258
# spent 30.1ms (13.8+16.4) within Foswiki::Plugins::WysiwygPlugin::beforeCommonTagsHandler which was called 1131 times, avg 27µs/call: # 1131 times (13.8ms+16.4ms) by Foswiki::Plugin::invoke at line 287 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Plugin.pm, avg 27µs/call
sub beforeCommonTagsHandler {
259227110.8ms return if $recursionBlock;
260113116.1ms return unless Foswiki::Func::getContext()->{body_text};
# spent 16.1ms making 1131 calls to Foswiki::Func::getContext, avg 14µs/call
261
262378µs my $query = Foswiki::Func::getCgiQuery();
# spent 78µs making 3 calls to Foswiki::Func::getCgiQuery, avg 26µs/call
263
264 return unless $query;
265
2663182µs return unless defined( $query->param('wysiwyg_edit') );
# spent 182µs making 3 calls to Foswiki::Request::param, avg 61µs/call
267 _execute( 'beforeCommonTagsHandler', @_ );
268}
269
270
# spent 40µs within Foswiki::Plugins::WysiwygPlugin::postRenderingHandler which was called 5 times, avg 8µs/call: # 5 times (40µs+0s) by Foswiki::Plugin::invoke at line 287 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Plugin.pm, avg 8µs/call
sub postRenderingHandler {
271533µs return if ( $recursionBlock || !$tml2html );
272 _execute( 'postRenderingHandler', @_ );
273}
274
275
# spent 94µs (32+62) within Foswiki::Plugins::WysiwygPlugin::modifyHeaderHandler which was called: # once (32µs+62µs) by Foswiki::Plugin::invoke at line 287 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Plugin.pm
sub modifyHeaderHandler {
276218µs my ( $headers, $query ) = @_;
277
278162µs if ( $query->param('wysiwyg_edit') ) {
# spent 62µs making 1 call to Foswiki::Request::param
279 _execute( 'modifyHeaderHandler', @_ );
280 }
281}
282
28318µs1;
284__END__