← Index
NYTProf Performance Profile   « line view »
For ./view
  Run on Fri Jul 31 18:42:36 2015
Reported on Fri Jul 31 18:48:14 2015

Filename/var/www/foswikidev/core/lib/Foswiki/Plugins/TwistyPlugin.pm
StatementsExecuted 34 statements in 2.08ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
1111.47ms1.63msFoswiki::Plugins::TwistyPlugin::::BEGIN@12Foswiki::Plugins::TwistyPlugin::BEGIN@12
11146µs146µsFoswiki::Plugins::TwistyPlugin::::initPluginFoswiki::Plugins::TwistyPlugin::initPlugin
1119µs65µsFoswiki::Plugins::TwistyPlugin::::BEGIN@17Foswiki::Plugins::TwistyPlugin::BEGIN@17
1119µs13µsFoswiki::Plugins::TwistyPlugin::::BEGIN@15Foswiki::Plugins::TwistyPlugin::BEGIN@15
1119µs9µsFoswiki::Plugins::TwistyPlugin::::BEGIN@11Foswiki::Plugins::TwistyPlugin::BEGIN@11
1118µs21µsFoswiki::Plugins::TwistyPlugin::::BEGIN@14Foswiki::Plugins::TwistyPlugin::BEGIN@14
1114µs4µsFoswiki::Plugins::TwistyPlugin::::BEGIN@13Foswiki::Plugins::TwistyPlugin::BEGIN@13
0000s0sFoswiki::Plugins::TwistyPlugin::::_ENDTWISTYTOGGLEFoswiki::Plugins::TwistyPlugin::_ENDTWISTYTOGGLE
0000s0sFoswiki::Plugins::TwistyPlugin::::_TWISTYFoswiki::Plugins::TwistyPlugin::_TWISTY
0000s0sFoswiki::Plugins::TwistyPlugin::::_TWISTYBUTTONFoswiki::Plugins::TwistyPlugin::_TWISTYBUTTON
0000s0sFoswiki::Plugins::TwistyPlugin::::_TWISTYHIDEFoswiki::Plugins::TwistyPlugin::_TWISTYHIDE
0000s0sFoswiki::Plugins::TwistyPlugin::::_TWISTYSHOWFoswiki::Plugins::TwistyPlugin::_TWISTYSHOW
0000s0sFoswiki::Plugins::TwistyPlugin::::_TWISTYTOGGLEFoswiki::Plugins::TwistyPlugin::_TWISTYTOGGLE
0000s0sFoswiki::Plugins::TwistyPlugin::::_addHeaderFoswiki::Plugins::TwistyPlugin::_addHeader
0000s0sFoswiki::Plugins::TwistyPlugin::::_createHtmlPropertiesFoswiki::Plugins::TwistyPlugin::_createHtmlProperties
0000s0sFoswiki::Plugins::TwistyPlugin::::_createIdFoswiki::Plugins::TwistyPlugin::_createId
0000s0sFoswiki::Plugins::TwistyPlugin::::_readCookieFoswiki::Plugins::TwistyPlugin::_readCookie
0000s0sFoswiki::Plugins::TwistyPlugin::::_setDefaultsFoswiki::Plugins::TwistyPlugin::_setDefaults
0000s0sFoswiki::Plugins::TwistyPlugin::::_twistyBtnFoswiki::Plugins::TwistyPlugin::_twistyBtn
0000s0sFoswiki::Plugins::TwistyPlugin::::_wrapInButtonHtmlFoswiki::Plugins::TwistyPlugin::_wrapInButtonHtml
0000s0sFoswiki::Plugins::TwistyPlugin::::_wrapInContainerDivIfNoJavascripCloseFoswiki::Plugins::TwistyPlugin::_wrapInContainerDivIfNoJavascripClose
0000s0sFoswiki::Plugins::TwistyPlugin::::_wrapInContainerHideIfNoJavascripOpenFoswiki::Plugins::TwistyPlugin::_wrapInContainerHideIfNoJavascripOpen
0000s0sFoswiki::Plugins::TwistyPlugin::::_wrapInContentHtmlCloseFoswiki::Plugins::TwistyPlugin::_wrapInContentHtmlClose
0000s0sFoswiki::Plugins::TwistyPlugin::::_wrapInContentHtmlOpenFoswiki::Plugins::TwistyPlugin::_wrapInContentHtmlOpen
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 TwistyPlugin
6
7=cut
8
9package Foswiki::Plugins::TwistyPlugin;
10
11227µs19µs
# spent 9µs within Foswiki::Plugins::TwistyPlugin::BEGIN@11 which was called: # once (9µs+0s) by Foswiki::Plugin::BEGIN@2.40 at line 11
use Foswiki::Func ();
# spent 9µs making 1 call to Foswiki::Plugins::TwistyPlugin::BEGIN@11
122100µs11.63ms
# spent 1.63ms (1.47+162µs) within Foswiki::Plugins::TwistyPlugin::BEGIN@12 which was called: # once (1.47ms+162µs) by Foswiki::Plugin::BEGIN@2.40 at line 12
use CGI::Cookie ();
# spent 1.63ms making 1 call to Foswiki::Plugins::TwistyPlugin::BEGIN@12
13230µs14µs
# spent 4µs within Foswiki::Plugins::TwistyPlugin::BEGIN@13 which was called: # once (4µs+0s) by Foswiki::Plugin::BEGIN@2.40 at line 13
use CGI ();
# spent 4µs making 1 call to Foswiki::Plugins::TwistyPlugin::BEGIN@13
14225µs233µs
# spent 21µs (8+12) within Foswiki::Plugins::TwistyPlugin::BEGIN@14 which was called: # once (8µs+12µs) by Foswiki::Plugin::BEGIN@2.40 at line 14
use strict;
# spent 21µs making 1 call to Foswiki::Plugins::TwistyPlugin::BEGIN@14 # spent 12µs making 1 call to strict::import
15230µs217µs
# spent 13µs (9+4) within Foswiki::Plugins::TwistyPlugin::BEGIN@15 which was called: # once (9µs+4µs) by Foswiki::Plugin::BEGIN@2.40 at line 15
use warnings;
# spent 13µs making 1 call to Foswiki::Plugins::TwistyPlugin::BEGIN@15 # spent 4µs making 1 call to warnings::import
16
1718µs156µs
# spent 65µs (9+56) within Foswiki::Plugins::TwistyPlugin::BEGIN@17 which was called: # once (9µs+56µs) by Foswiki::Plugin::BEGIN@2.40 at line 18
use vars qw( @twistystack $doneHeader $doneDefaults $twistyCount
# spent 56µs making 1 call to vars::import
1811.81ms165µs $prefMode $prefShowLink $prefHideLink $prefRemember);
# spent 65µs making 1 call to Foswiki::Plugins::TwistyPlugin::BEGIN@17
19
201900nsour $VERSION = '1.62';
211200nsour $RELEASE = '1.62';
221200nsour $SHORTDESCRIPTION =
23 'Twisty section Javascript library to open/close content dynamically';
241200nsour $NO_PREFS_IN_TOPIC = 1;
25
261400nsmy $TWISTYPLUGIN_COOKIE_PREFIX = "TwistyPlugin_";
271200nsmy $TWISTYPLUGIN_CONTENT_HIDDEN = 0;
281100nsmy $TWISTYPLUGIN_CONTENT_SHOWN = 1;
29
30#there is no need to document this.
31
# spent 146µs (46+100) within Foswiki::Plugins::TwistyPlugin::initPlugin which was called: # once (46µs+100µs) by Foswiki::Plugin::__ANON__[/var/www/foswikidev/core/lib/Foswiki/Plugin.pm:257] at line 250 of /var/www/foswikidev/core/lib/Foswiki/Plugin.pm
sub initPlugin {
3212µs my ( $topic, $web, $user, $installWeb ) = @_;
33
34 # check for Plugins.pm versions
35113µs18µs if ( $Foswiki::Plugins::VERSION < 1.1 ) {
# spent 8µs making 1 call to version::vxs::VCMP
36 Foswiki::Func::writeWarning(
37 "Version mismatch between TwistyPlugin and Plugins.pm");
38 return 0;
39 }
40
411700ns $doneDefaults = 0;
421500ns $doneHeader = 0;
431400ns $twistyCount = 0;
44
4512µs113µs Foswiki::Plugins::JQueryPlugin::registerPlugin( 'twisty',
# spent 13µs making 1 call to Foswiki::Plugins::JQueryPlugin::registerPlugin
46 'Foswiki::Plugins::TwistyPlugin::TWISTY' );
4712µs115µs Foswiki::Func::registerTagHandler( 'TWISTYSHOW', \&_TWISTYSHOW );
# spent 15µs making 1 call to Foswiki::Func::registerTagHandler
4812µs111µs Foswiki::Func::registerTagHandler( 'TWISTYHIDE', \&_TWISTYHIDE );
# spent 11µs making 1 call to Foswiki::Func::registerTagHandler
4912µs111µs Foswiki::Func::registerTagHandler( 'TWISTYBUTTON', \&_TWISTYBUTTON );
# spent 11µs making 1 call to Foswiki::Func::registerTagHandler
5012µs111µs Foswiki::Func::registerTagHandler( 'TWISTY', \&_TWISTY );
# spent 11µs making 1 call to Foswiki::Func::registerTagHandler
5113µs111µs Foswiki::Func::registerTagHandler( 'ENDTWISTY', \&_ENDTWISTYTOGGLE );
# spent 11µs making 1 call to Foswiki::Func::registerTagHandler
5212µs110µs Foswiki::Func::registerTagHandler( 'TWISTYTOGGLE', \&_TWISTYTOGGLE );
# spent 10µs making 1 call to Foswiki::Func::registerTagHandler
5312µs111µs Foswiki::Func::registerTagHandler( 'ENDTWISTYTOGGLE', \&_ENDTWISTYTOGGLE );
# spent 11µs making 1 call to Foswiki::Func::registerTagHandler
54
5514µs return 1;
56}
57
58sub _setDefaults {
59 return if $doneDefaults;
60 $doneDefaults = 1;
61
62 $prefMode =
63 Foswiki::Func::getPreferencesValue('TWISTYMODE')
64 || Foswiki::Func::getPluginPreferencesValue('TWISTYMODE')
65 || 'div';
66 $prefShowLink =
67 Foswiki::Func::getPreferencesValue('TWISTYSHOWLINK')
68 || Foswiki::Func::getPluginPreferencesValue('TWISTYSHOWLINK')
69 || '%MAKETEXT{"More..."}%';
70 $prefHideLink =
71 Foswiki::Func::getPreferencesValue('TWISTYHIDELINK')
72 || Foswiki::Func::getPluginPreferencesValue('TWISTYHIDELINK')
73 || '%MAKETEXT{"Close"}%';
74 $prefRemember =
75 Foswiki::Func::getPreferencesValue('TWISTYREMEMBER')
76 || Foswiki::Func::getPluginPreferencesValue('TWISTYREMEMBER')
77 || '';
78
79 return;
80}
81
82sub _addHeader {
83 return if $doneHeader;
84 $doneHeader = 1;
85
86 if ( Foswiki::Func::getContext()->{JQueryPluginEnabled} ) {
87 Foswiki::Plugins::JQueryPlugin::createPlugin('twisty');
88 }
89 else {
90 my $header;
91 Foswiki::Func::loadTemplate('twistyplugin');
92
93 $header =
94 Foswiki::Func::expandTemplate("TwistyPlugin/twisty")
95 . Foswiki::Func::expandTemplate("TwistyPlugin/twisty.css");
96 Foswiki::Func::expandCommonVariables($header);
97 }
98
99 return;
100}
101
102sub _TWISTYSHOW {
103 my ( $session, $params, $theTopic, $theWeb ) = @_;
104 _setDefaults();
105
106 my $mode = $params->{'mode'} || $prefMode;
107 my $btn = _twistyBtn( 'show', $session, $params, $theTopic, $theWeb );
108 return Foswiki::Func::decodeFormatTokens(
109 _wrapInButtonHtml( $btn, $mode ) );
110}
111
112sub _TWISTYHIDE {
113 my ( $session, $params, $theTopic, $theWeb ) = @_;
114 _setDefaults();
115 my $mode = $params->{'mode'} || $prefMode;
116 my $btn = _twistyBtn( 'hide', $session, $params, $theTopic, $theWeb );
117 return Foswiki::Func::decodeFormatTokens(
118 _wrapInButtonHtml( $btn, $mode ) );
119}
120
121sub _TWISTYBUTTON {
122 my ( $session, $params, $theTopic, $theWeb ) = @_;
123 _setDefaults();
124
125 my $mode = $params->{'mode'} || $prefMode;
126 my $btnShow = _twistyBtn( 'show', $session, $params, $theTopic, $theWeb );
127 my $btnHide = _twistyBtn( 'hide', $session, $params, $theTopic, $theWeb );
128 my $prefix = $params->{'prefix'} || '';
129 my $suffix = $params->{'suffix'} || '';
130 my $btn = $prefix . $btnShow . $btnHide . $suffix;
131 return Foswiki::Func::decodeFormatTokens(
132 _wrapInButtonHtml( $btn, $mode ) );
133}
134
135=pod
136
137If no ID is passed, creates a new unique id based on web and topic.
138
139=cut
140
141sub _TWISTY {
142 my ( $session, $params, $theTopic, $theWeb ) = @_;
143
144 _addHeader();
145 $params->{'id'} = _createId( $params, $theWeb, $theTopic );
146 return _TWISTYBUTTON( $session, $params, $theTopic, $theWeb )
147 . _TWISTYTOGGLE( $session, $params, $theTopic, $theWeb );
148}
149
150sub _TWISTYTOGGLE {
151 my ( $session, $params, $theTopic, $theWeb ) = @_;
152 my $id = $params->{'id'};
153 if ( !defined $id || $id eq '' ) {
154 return '';
155 }
156 _setDefaults();
157 my $idTag = $id . 'toggle';
158 my $mode = $params->{'mode'} || $prefMode;
159 push( @twistystack, { mode => $mode, id => $idTag } );
160
161 my $isTrigger = 0;
162 my $cookieState = _readCookie( $session, $idTag );
163 my @propList =
164 _createHtmlProperties( undef, $idTag, $mode, $params, $isTrigger,
165 $cookieState );
166 my $props = @propList ? " " . join( " ", @propList ) : '';
167 my $modeTag = '<' . $mode . $props . '>';
168 return Foswiki::Func::decodeFormatTokens(
169 _wrapInContentHtmlOpen($mode) . $modeTag );
170}
171
172sub _ENDTWISTYTOGGLE {
173 my ( $session, $params, $theTopic, $theWeb ) = @_;
174 my $twisty = pop @twistystack;
175
176 return
177"<div class='foswikiAlert'>woops, ordering error: got an ENDTWISTY before seeing a TWISTY</div>"
178 unless $twisty->{mode};
179
180 my $modeTag = ( $twisty->{mode} ) ? '</' . $twisty->{mode} . '>' : '';
181 return $modeTag . _wrapInContentHtmlClose($twisty);
182}
183
184sub _createId {
185 my ( $params, $inWeb, $inTopic ) = @_;
186
187 my $id = $params->{'id'} || "twistyId$inWeb$inTopic";
188 $id =~ s/\//subweb/g;
189
190 # Ensure uniqueness, or at least try to
191 my $remember = $params->{'remember'} || $prefRemember;
192 if ( Foswiki::Func::isTrue($remember) ) {
193 $id .= ++$twistyCount; # For remember
194 }
195 else { # 100 is the number of remembered cookies to avoid clashes
196 $id .= int( rand(10000) ) + 100; # For AJAX
197 }
198 return $id;
199}
200
201sub _twistyBtn {
202 my ( $twistyControlState, $session, $params, $theTopic, $theWeb ) = @_;
203
204 _addHeader();
205
206 # not used yet:
207 #my $triangle_right = '&#9658;';
208 #my $triangle_down = '&#9660;';
209
210 my $id = $params->{'id'};
211 if ( !defined $id || $id eq '' ) {
212 return '';
213 }
214 my $idTag;
215 if ($twistyControlState) {
216 $idTag = $id . $twistyControlState;
217 }
218 else {
219 $idTag = '';
220 }
221
222 my $defaultLink =
223 ( $twistyControlState eq 'show' ) ? $prefShowLink : $prefHideLink;
224
225 # link="" takes precedence over showlink="" and hidelink=""
226 my $link = $params->{'link'};
227
228 if ( !defined $link ) {
229
230 # if 'link' is not set, try 'showlink' / 'hidelink'
231 $link = $params->{ $twistyControlState . 'link' };
232 }
233 if ( !defined $link ) {
234 $link = $defaultLink || '';
235 }
236 my $img =
237 $params->{ $twistyControlState . 'img' }
238 || $params->{'img'}
239 || '';
240 my $imgright =
241 $params->{ $twistyControlState . 'imgright' }
242 || $params->{'imgright'}
243 || '';
244 my $imgleft =
245 $params->{ $twistyControlState . 'imgleft' }
246 || $params->{'imgleft'}
247 || '';
248 $img =~ s/['\"]//g;
249 $imgright =~ s/['\"]//g;
250 $imgleft =~ s/['\"]//g;
251 my $imgTag =
252 ( $img ne '' ) ? '<img src="' . $img . '" border="0" alt="" />' : '';
253 my $imgRightTag =
254 ( $imgright ne '' )
255 ? '<img src="' . $imgright . '" border="0" alt="" />'
256 : '';
257 my $imgLeftTag =
258 ( $imgleft ne '' )
259 ? '<img src="' . $imgleft . '" border="0" alt="" />'
260 : '';
261
262 my @linkClasses;
263 push( @linkClasses, $params->{'linkclass'} ) if $params->{'linkclass'};
264
265 my $imgLinkTag = CGI::a(
266 {
267 href => '#',
268 class => join( ' ', @linkClasses )
269 },
270 $imgLeftTag
271 . CGI::span( { class => 'foswikiLinkLabel foswikiUnvisited' }, $link )
272 . $imgTag
273 . $imgRightTag
274 );
275
276 my $isTrigger = 1;
277 my $props = '';
278
279 if ( $idTag && $params ) {
280 my $cookieState = _readCookie( $session, $idTag );
281 my @propList =
282 _createHtmlProperties( $twistyControlState, $idTag, undef, $params,
283 $isTrigger, $cookieState );
284 $props = @propList ? " " . join( " ", @propList ) : '';
285 }
286 my $triggerTag = '<span' . $props . '>' . $imgLinkTag . '</span>';
287 return $triggerTag;
288}
289
290sub _createHtmlProperties {
291 my ( $twistyControlState, $idTag, $mode, $params, $isTrigger, $cookie ) =
292 @_;
293 my $class = $params->{'class'} || '';
294 my $firststart = $params->{'firststart'} || '';
295 my $firstStartHidden;
296 $firstStartHidden = 1 if ( $firststart eq 'hide' );
297 my $firstStartShown;
298 $firstStartShown = 1 if ( $firststart eq 'show' );
299 my $cookieShow;
300 $cookieShow = 1 if defined $cookie && $cookie == 1;
301 my $cookieHide;
302 $cookieHide = 1 if defined $cookie && $cookie == 0;
303 my $start = $params->{start} || '';
304 my $startHidden;
305 $startHidden = 1 if ( $start eq 'hide' );
306 my $startShown;
307 $startShown = 1 if ( $start eq 'show' );
308 my @propList = ();
309
310 _setDefaults();
311 my $remember = $params->{'remember'} || $prefRemember;
312 my $noscript = $params->{'noscript'} || '';
313 my $noscriptHide = ( $noscript eq 'hide' ) ? 1 : 0;
314 $mode ||= $prefMode;
315
316 my @classList = ();
317 my @styleList = ();
318 push( @classList, $class ) if $class && !$isTrigger;
319 push( @classList, 'twistyRememberSetting' )
320 if Foswiki::Func::isTrue($remember);
321 push( @classList, 'twistyForgetSetting' ) if $remember eq 'off';
322 push( @classList, 'twistyStartHide' ) if $startHidden;
323 push( @classList, 'twistyStartShow' ) if $startShown;
324 push( @classList, 'twistyFirstStartHide' ) if $firstStartHidden;
325 push( @classList, 'twistyFirstStartShow' ) if $firstStartShown;
326
327 # Mimic the rules in twist.js, function _update()
328 my $state = '';
329 $state = $TWISTYPLUGIN_CONTENT_HIDDEN if $firstStartHidden;
330 $state = $TWISTYPLUGIN_CONTENT_SHOWN if $firstStartShown;
331
332 # cookie setting may override firstStartHidden and firstStartShown
333 $state = $TWISTYPLUGIN_CONTENT_HIDDEN if $cookieHide;
334 $state = $TWISTYPLUGIN_CONTENT_SHOWN if $cookieShow;
335
336 # startHidden and startShown may override cookie
337 $state = $TWISTYPLUGIN_CONTENT_HIDDEN if $startHidden;
338 $state = $TWISTYPLUGIN_CONTENT_SHOWN if $startShown;
339
340 # assume trigger should be hidden
341 # unless explicitly said otherwise
342 my $shouldHideTrigger = 1;
343 if ($isTrigger) {
344 push( @classList, 'twistyTrigger foswikiUnvisited' );
345
346 if ( $state eq $TWISTYPLUGIN_CONTENT_SHOWN
347 && $twistyControlState eq 'hide' )
348 {
349 $shouldHideTrigger = 0;
350 }
351 if ( $state eq $TWISTYPLUGIN_CONTENT_HIDDEN
352 && $twistyControlState eq 'show' )
353 {
354 $shouldHideTrigger = 0;
355 }
356 push( @styleList, 'display:none' ) if $shouldHideTrigger;
357 }
358
359 # assume content should be hidden
360 # unless explicitly said otherwise
361 if ( !$isTrigger ) {
362 push( @classList, 'twistyContent' );
363 }
364
365 # deprecated
366 # should be done by Foswiki template scripts instead
367 if ( !$isTrigger && $noscriptHide ) {
368 push( @classList, 'foswikiMakeVisible' );
369 }
370
371 # let javascript know we have set the state already
372 push( @classList, 'twistyInited' . $state );
373
374 push( @propList, 'id="' . $idTag . '"' );
375
376 my $styleListString = join( ", ", @styleList );
377 push( @propList, 'style="' . $styleListString . '"' );
378
379 my $classListString = join( " ", @classList );
380 push( @propList, 'class="' . $classListString . '"' );
381
382 return @propList;
383}
384
385=begin TML
386
387Reads a setting from the FOSWIKIPREF cookie.
388Returns:
389 * 1 if the cookie has been set (meaning: show content)
390 * 0 if the cookie is '0' (meaning: hide content)
391 * undef if no cookie has been set
392
393=cut
394
395sub _readCookie {
396 my ( $session, $idTag ) = @_;
397
398 return '' if !$idTag;
399
400 # which state do we use?
401 my $cgi = CGI->new();
402 my $cookie = $cgi->cookie('FOSWIKIPREF');
403 my $tag = $idTag;
404 $tag =~ s/^(.*)(hide|show|toggle)$/$1/g;
405 my $key = $TWISTYPLUGIN_COOKIE_PREFIX . $tag;
406
407 return unless ( defined($key) && defined($cookie) );
408
409 my $value = '';
410 if ( $cookie =~ m/\b\Q$key=\E(.+?)\b/gi ) {
411 $value = $1;
412 }
413
414 return if $value eq '';
415 return ( $value eq '1' ) ? 1 : 0;
416}
417
418sub _wrapInButtonHtml {
419 my ( $text, $mode ) = @_;
420 return _wrapInContainerHideIfNoJavascripOpen($mode) . $text
421 . _wrapInContainerDivIfNoJavascripClose($mode);
422}
423
424sub _wrapInContentHtmlOpen {
425 my ($mode) = @_;
426 return "<$mode class=\"twistyPlugin\">";
427}
428
429sub _wrapInContentHtmlClose {
430 my ($twisty) = @_;
431 my $closeTag = "</$twisty->{mode}>";
432
433 return $closeTag;
434}
435
436sub _wrapInContainerHideIfNoJavascripOpen {
437 my ($mode) = @_;
438
439 return '<' . $mode . ' class="twistyPlugin foswikiMakeVisible">';
440}
441
442sub _wrapInContainerDivIfNoJavascripClose {
443 my ($mode) = @_;
444
445 return '</' . $mode . '>';
446}
447
44814µs1;
449__END__