Filename | /usr/local/src/github.com/foswiki/core/lib/Foswiki/UI/View.pm |
Statements | Executed 147 statements in 7.32ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
54 | 2 | 1 | 1.54ms | 1.54ms | CORE:substcont (opcode) | Foswiki::UI::View::
1 | 1 | 1 | 1.00ms | 184s | view | Foswiki::UI::View::
7 | 5 | 1 | 526µs | 526µs | CORE:subst (opcode) | Foswiki::UI::View::
3 | 3 | 1 | 369µs | 183s | _prepare | Foswiki::UI::View::
1 | 1 | 1 | 246µs | 252µs | BEGIN@15 | Foswiki::UI::View::
1 | 1 | 1 | 117µs | 313ms | revisionsAround | Foswiki::UI::View::
6 | 5 | 1 | 91µs | 91µs | CORE:match (opcode) | Foswiki::UI::View::
1 | 1 | 1 | 26µs | 67µs | BEGIN@14 | Foswiki::UI::View::
1 | 1 | 1 | 25µs | 33µs | BEGIN@13 | Foswiki::UI::View::
1 | 1 | 1 | 19µs | 63µs | BEGIN@17 | Foswiki::UI::View::
1 | 1 | 1 | 10µs | 10µs | BEGIN@16 | Foswiki::UI::View::
1 | 1 | 1 | 9µs | 9µs | BEGIN@19 | Foswiki::UI::View::
1 | 1 | 1 | 9µs | 9µs | BEGIN@20 | Foswiki::UI::View::
1 | 1 | 1 | 9µs | 9µs | BEGIN@21 | Foswiki::UI::View::
1 | 1 | 1 | 8µs | 8µs | BEGIN@22 | Foswiki::UI::View::
1 | 1 | 1 | 8µs | 8µs | BEGIN@23 | Foswiki::UI::View::
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 Foswiki::UI::View | ||||
6 | |||||
7 | UI delegate for view function | ||||
8 | |||||
9 | =cut | ||||
10 | |||||
11 | package Foswiki::UI::View; | ||||
12 | |||||
13 | 2 | 59µs | 2 | 41µs | # spent 33µs (25+8) within Foswiki::UI::View::BEGIN@13 which was called:
# once (25µs+8µs) by Foswiki::UI::BEGIN@2 at line 13 # spent 33µs making 1 call to Foswiki::UI::View::BEGIN@13
# spent 8µs making 1 call to strict::import |
14 | 2 | 65µs | 2 | 107µs | # spent 67µs (26+41) within Foswiki::UI::View::BEGIN@14 which was called:
# once (26µs+41µs) by Foswiki::UI::BEGIN@2 at line 14 # spent 67µs making 1 call to Foswiki::UI::View::BEGIN@14
# spent 41µs making 1 call to warnings::import |
15 | 2 | 263µs | 2 | 258µs | # spent 252µs (246+6) within Foswiki::UI::View::BEGIN@15 which was called:
# once (246µs+6µs) by Foswiki::UI::BEGIN@2 at line 15 # spent 252µs making 1 call to Foswiki::UI::View::BEGIN@15
# spent 6µs making 1 call to integer::import |
16 | 2 | 40µs | 1 | 10µs | # spent 10µs within Foswiki::UI::View::BEGIN@16 which was called:
# once (10µs+0s) by Foswiki::UI::BEGIN@2 at line 16 # spent 10µs making 1 call to Foswiki::UI::View::BEGIN@16 |
17 | 2 | 47µs | 2 | 107µs | # spent 63µs (19+44) within Foswiki::UI::View::BEGIN@17 which was called:
# once (19µs+44µs) by Foswiki::UI::BEGIN@2 at line 17 # spent 63µs making 1 call to Foswiki::UI::View::BEGIN@17
# spent 44µs making 1 call to Assert::import |
18 | |||||
19 | 2 | 37µs | 1 | 9µs | # spent 9µs within Foswiki::UI::View::BEGIN@19 which was called:
# once (9µs+0s) by Foswiki::UI::BEGIN@2 at line 19 # spent 9µs making 1 call to Foswiki::UI::View::BEGIN@19 |
20 | 2 | 37µs | 1 | 9µs | # spent 9µs within Foswiki::UI::View::BEGIN@20 which was called:
# once (9µs+0s) by Foswiki::UI::BEGIN@2 at line 20 # spent 9µs making 1 call to Foswiki::UI::View::BEGIN@20 |
21 | 2 | 36µs | 1 | 9µs | # spent 9µs within Foswiki::UI::View::BEGIN@21 which was called:
# once (9µs+0s) by Foswiki::UI::BEGIN@2 at line 21 # spent 9µs making 1 call to Foswiki::UI::View::BEGIN@21 |
22 | 2 | 36µs | 1 | 8µs | # spent 8µs within Foswiki::UI::View::BEGIN@22 which was called:
# once (8µs+0s) by Foswiki::UI::BEGIN@2 at line 22 # spent 8µs making 1 call to Foswiki::UI::View::BEGIN@22 |
23 | 2 | 3.20ms | 1 | 8µs | # spent 8µs within Foswiki::UI::View::BEGIN@23 which was called:
# once (8µs+0s) by Foswiki::UI::BEGIN@2 at line 23 # spent 8µs making 1 call to Foswiki::UI::View::BEGIN@23 |
24 | |||||
25 | =begin TML | ||||
26 | |||||
27 | ---++ StaticMethod view( $session ) | ||||
28 | |||||
29 | =view= command handler. | ||||
30 | This method is designed to be | ||||
31 | invoked via the =UI::run= method. | ||||
32 | |||||
33 | Generate a complete HTML page that represents the viewed topics. | ||||
34 | The view is controlled by CGI parameters as follows: | ||||
35 | |||||
36 | | =rev= | topic revision to view | | ||||
37 | | =section= | restrict view to a named section | | ||||
38 | | =raw= | no format body text if set | | ||||
39 | | =skin= | comma-separated list of skin(s) to use | | ||||
40 | | =contenttype= | Allows you to specify an alternate content type | | ||||
41 | |||||
42 | =cut | ||||
43 | |||||
44 | # spent 184s (1.00ms+184) within Foswiki::UI::View::view which was called:
# once (1.00ms+184s) by Foswiki::UI::__ANON__[/usr/local/src/github.com/foswiki/core/lib/Foswiki/UI.pm:318] at line 316 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/UI.pm | ||||
45 | 1 | 2µs | my $session = shift; | ||
46 | |||||
47 | 1 | 2µs | my $query = $session->{request}; | ||
48 | 1 | 2µs | my $web = $session->{webName}; | ||
49 | 1 | 2µs | my $topic = $session->{topicName}; | ||
50 | |||||
51 | 1 | 2µs | my $cache = $session->{cache}; | ||
52 | 1 | 1µs | my $cachedPage; | ||
53 | 1 | 1µs | $cachedPage = $cache->getPage( $web, $topic ) if $cache; | ||
54 | 1 | 1µs | if ($cachedPage) { | ||
55 | print STDERR "found $web.$topic in cache\n" | ||||
56 | if $Foswiki::cfg{Cache}{Debug}; | ||||
57 | Monitor::MARK("found page in cache"); | ||||
58 | |||||
59 | # render uncacheable areas | ||||
60 | my $text = $cachedPage->{text}; | ||||
61 | $cache->renderDirtyAreas( \$text ) if $cachedPage->{isDirty}; | ||||
62 | |||||
63 | # set status | ||||
64 | my $status = $cachedPage->{status}; | ||||
65 | if ( $status == 302 ) { | ||||
66 | $session->{response}->redirect( $cachedPage->{location} ); | ||||
67 | } | ||||
68 | else { | ||||
69 | |||||
70 | # See Item9941 to understand why do not set status when 200 | ||||
71 | $session->{response}->status($status) unless $status eq 200; | ||||
72 | } | ||||
73 | |||||
74 | # set headers | ||||
75 | $session->generateHTTPHeaders( 'view', $cachedPage->{contentType}, | ||||
76 | $text, $cachedPage ); | ||||
77 | |||||
78 | # send it out | ||||
79 | $session->{response}->print($text); | ||||
80 | |||||
81 | Monitor::MARK('Wrote HTML'); | ||||
82 | $session->logEvent( 'view', $web . '.' . $topic, '(cached)' ); | ||||
83 | |||||
84 | return; | ||||
85 | } | ||||
86 | |||||
87 | 1 | 4µs | print STDERR "computing page for $web.$topic\n" | ||
88 | if $Foswiki::cfg{Cache}{Debug}; | ||||
89 | |||||
90 | 1 | 13µs | 1 | 75µs | my $raw = $query->param('raw') || ''; # spent 75µs making 1 call to Foswiki::Request::param |
91 | 1 | 6µs | 1 | 44µs | my $contentType = $query->param('contenttype'); # spent 44µs making 1 call to Foswiki::Request::param |
92 | |||||
93 | 1 | 4µs | my $logEntry = ''; | ||
94 | |||||
95 | # is this view indexable by search engines? Default yes. | ||||
96 | 1 | 2µs | my $indexableView = 1; | ||
97 | 1 | 1µs | my $viewTemplate; | ||
98 | |||||
99 | 1 | 10µs | 1 | 254µs | Foswiki::UI::checkWebExists( $session, $web, 'view' ); # spent 254µs making 1 call to Foswiki::UI::checkWebExists |
100 | |||||
101 | 1 | 15µs | 2 | 62µs | my $requestedRev = Foswiki::Store::cleanUpRevID( $query->param('rev') ); # spent 48µs making 1 call to Foswiki::Request::param
# spent 13µs making 1 call to Foswiki::Store::cleanUpRevID |
102 | 1 | 2µs | my $showLatest = !$requestedRev; | ||
103 | 1 | 1µs | my $showRev; | ||
104 | |||||
105 | 1 | 1µs | my $topicObject; # the stub of the topic we are to display | ||
106 | 1 | 1µs | my $text; # the text to display, *not* necessarily | ||
107 | # the same as $topicObject->text | ||||
108 | 1 | 1µs | my $revIt; # Iterator over the range of available revs | ||
109 | 1 | 1µs | my $maxRev; | ||
110 | |||||
111 | 1 | 8µs | 1 | 134µs | if ( $session->topicExists( $web, $topic ) ) { # spent 134µs making 1 call to Foswiki::topicExists |
112 | |||||
113 | # Load the most recent rev. This *should* be maxRev, but may | ||||
114 | # not say it is because the TOPICINFO could be up the spout | ||||
115 | 1 | 12µs | 1 | 6.11ms | $topicObject = Foswiki::Meta->load( $session, $web, $topic ); # spent 6.11ms making 1 call to Foswiki::Meta::load |
116 | 1 | 10µs | 1 | 2.31ms | Foswiki::UI::checkAccess( $session, 'VIEW', $topicObject ); # spent 2.31ms making 1 call to Foswiki::UI::checkAccess |
117 | |||||
118 | 1 | 12µs | 1 | 308ms | $revIt = $topicObject->getRevisionHistory(); # spent 308ms making 1 call to Foswiki::Meta::getRevisionHistory |
119 | |||||
120 | # The topic exists; it must have at least one rev | ||||
121 | 1 | 13µs | 1 | 12µs | ASSERT( $revIt->hasNext() ) if DEBUG; # spent 12µs making 1 call to Assert::ASSERTS_OFF |
122 | 1 | 7µs | 1 | 11µs | $maxRev = $revIt->next(); # spent 11µs making 1 call to Foswiki::Iterator::NumberRangeIterator::next |
123 | |||||
124 | 1 | 3µs | if ( defined $requestedRev ) { | ||
125 | |||||
126 | # Is the requested rev id known? | ||||
127 | 1 | 6µs | 1 | 7µs | $revIt->reset(); # spent 7µs making 1 call to Foswiki::Iterator::NumberRangeIterator::reset |
128 | 1 | 8µs | 1 | 10µs | while ( $revIt->hasNext() ) { # spent 10µs making 1 call to Foswiki::Iterator::NumberRangeIterator::hasNext |
129 | 1 | 15µs | 2 | 17µs | if ( $requestedRev eq $revIt->next() ) { # spent 9µs making 1 call to Foswiki::Iterator::NumberRangeIterator::next
# spent 8µs making 1 call to Foswiki::Iterator::NumberRangeIterator::hasNext |
130 | $showRev = $requestedRev; | ||||
131 | last; | ||||
132 | } | ||||
133 | } | ||||
134 | |||||
135 | # if rev was not found; show max rev | ||||
136 | 1 | 2µs | $showRev = $maxRev unless ( defined $showRev ); | ||
137 | |||||
138 | 1 | 2µs | if ( $showRev ne $maxRev ) { | ||
139 | |||||
140 | # Load the old revision instead | ||||
141 | $topicObject = | ||||
142 | Foswiki::Meta->load( $session, $web, $topic, $showRev ); | ||||
143 | if ( !$topicObject->haveAccess('VIEW') ) { | ||||
144 | throw Foswiki::AccessControlException( 'VIEW', | ||||
145 | $session->{user}, $web, $topic, | ||||
146 | $Foswiki::Meta::reason ); | ||||
147 | } | ||||
148 | $logEntry .= 'r' . $requestedRev; | ||||
149 | } | ||||
150 | } | ||||
151 | else { | ||||
152 | $showRev = $maxRev; | ||||
153 | } | ||||
154 | |||||
155 | 1 | 20µs | 1 | 102µs | if ( my $section = $query->param('section') ) { # spent 102µs making 1 call to Foswiki::Request::param |
156 | |||||
157 | # Apply the 'section' selection (and maybe others in the | ||||
158 | # future as well). $text is cleared unless a named section | ||||
159 | # matching the 'section' URL parameter is found. | ||||
160 | my ( $ntext, $sections ) = | ||||
161 | Foswiki::parseSections( $topicObject->text() ); | ||||
162 | $text = ''; # in the beginning, there was ... NO section | ||||
163 | FINDSECTION: | ||||
164 | for my $s (@$sections) { | ||||
165 | if ( $s->{type} eq 'section' && $s->{name} eq $section ) { | ||||
166 | $text = | ||||
167 | substr( $ntext, $s->{start}, $s->{end} - $s->{start} ); | ||||
168 | last FINDSECTION; | ||||
169 | } | ||||
170 | } | ||||
171 | } | ||||
172 | else { | ||||
173 | |||||
174 | # Otherwise take the full topic text | ||||
175 | 1 | 14µs | 1 | 40µs | $text = $topicObject->text(); # spent 40µs making 1 call to Foswiki::Meta::text |
176 | } | ||||
177 | } | ||||
178 | else { # Topic does not exist yet | ||||
179 | $topicObject = Foswiki::Meta->new( $session, $web, $topic ); | ||||
180 | $indexableView = 0; | ||||
181 | $session->enterContext('new_topic'); | ||||
182 | $session->{response}->status(404); | ||||
183 | $showRev = 1; | ||||
184 | $maxRev = 0; | ||||
185 | $viewTemplate = 'TopicDoesNotExistView'; | ||||
186 | $logEntry .= ' (not exist)'; | ||||
187 | $raw = ''; # There is no raw view of a topic that doesn't exist | ||||
188 | $revIt = new Foswiki::ListIterator( [1] ); | ||||
189 | } | ||||
190 | |||||
191 | 1 | 2µs | if ($raw) { | ||
192 | $indexableView = 0; | ||||
193 | $logEntry .= ' raw=' . $raw; | ||||
194 | if ( $raw eq 'debug' || $raw eq 'all' ) { | ||||
195 | |||||
196 | # We want to see the embedded store form | ||||
197 | $text = $topicObject->getEmbeddedStoreForm(); | ||||
198 | } | ||||
199 | } | ||||
200 | |||||
201 | 1 | 2µs | $text = '' unless defined $text; | ||
202 | |||||
203 | 1 | 35µs | 3 | 8.68ms | $session->logEvent( 'view', $topicObject->web . '.' . $topicObject->topic, # spent 8.65ms making 1 call to Foswiki::logEvent
# spent 14µs making 1 call to Foswiki::Meta::web
# spent 11µs making 1 call to Foswiki::Meta::topic |
204 | $logEntry ); | ||||
205 | |||||
206 | # Note; must enter all contexts before the template is read, as | ||||
207 | # TMPL:P is expanded on the fly in the template reader. :-( | ||||
208 | 1 | 4µs | my ( $revTitle, $revArg ) = ( '', '' ); | ||
209 | 1 | 7µs | 1 | 8µs | $revIt->reset(); # spent 8µs making 1 call to Foswiki::Iterator::NumberRangeIterator::reset |
210 | 1 | 6µs | 1 | 10µs | if ( $showRev && $showRev != $revIt->next() ) { # spent 10µs making 1 call to Foswiki::Iterator::NumberRangeIterator::next |
211 | $session->enterContext('inactive'); | ||||
212 | |||||
213 | # disable edit of previous revisions | ||||
214 | $revTitle = '(r' . $showRev . ')'; | ||||
215 | $revArg = '&rev=' . $showRev; | ||||
216 | } | ||||
217 | |||||
218 | 1 | 23µs | 2 | 246µs | my $template = # spent 188µs making 1 call to Foswiki::Prefs::getPreference
# spent 58µs making 1 call to Foswiki::Request::param |
219 | $viewTemplate | ||||
220 | || $query->param('template') | ||||
221 | || $session->{prefs}->getPreference('VIEW_TEMPLATE') | ||||
222 | || 'view'; | ||||
223 | |||||
224 | # Always use default view template for raw=debug, raw=all and raw=on | ||||
225 | 1 | 14µs | 1 | 4µs | if ( $raw =~ /^(debug|all|on)$/ ) { # spent 4µs making 1 call to Foswiki::UI::View::CORE:match |
226 | $template = 'view'; | ||||
227 | } | ||||
228 | |||||
229 | 1 | 15µs | 2 | 122ms | my $tmpl = $session->templates->readTemplate( $template, no_oops => 1 ); # spent 111ms making 1 call to Foswiki::Templates::readTemplate
# spent 10.9ms making 1 call to Foswiki::templates |
230 | |||||
231 | # If the VIEW_TEMPLATE (or other) doesn't exist, default to view. | ||||
232 | 1 | 2µs | $tmpl = $session->templates->readTemplate('view') unless defined($tmpl); | ||
233 | |||||
234 | 1 | 32µs | 1 | 19µs | $tmpl =~ s/%REVTITLE%/$revTitle/g; # spent 19µs making 1 call to Foswiki::UI::View::CORE:subst |
235 | 1 | 27µs | 1 | 18µs | $tmpl =~ s/%REVARG%/$revArg/g; # spent 18µs making 1 call to Foswiki::UI::View::CORE:subst |
236 | |||||
237 | 1 | 18µs | 1 | 62µs | if ( $indexableView # spent 62µs making 1 call to Foswiki::Request::param |
238 | && $Foswiki::cfg{AntiSpam}{RobotsAreWelcome} | ||||
239 | && !$query->param() ) | ||||
240 | { | ||||
241 | |||||
242 | # it's an indexable view type, there are no parameters | ||||
243 | # on the url, and robots are welcome. Remove the NOINDEX meta tag | ||||
244 | 1 | 51µs | 1 | 44µs | $tmpl =~ s/<meta name="robots"[^>]*>//goi; # spent 44µs making 1 call to Foswiki::UI::View::CORE:subst |
245 | } | ||||
246 | |||||
247 | # Show revisions around the one being displayed. | ||||
248 | 1 | 82µs | 3 | 58µs | $tmpl =~ s/%REVISIONS%/ # spent 43µs making 2 calls to Foswiki::UI::View::CORE:substcont, avg 21µs/call
# spent 15µs making 1 call to Foswiki::UI::View::CORE:subst |
249 | 1 | 11µs | 1 | 313ms | revisionsAround( # spent 313ms making 1 call to Foswiki::UI::View::revisionsAround |
250 | $session, $topicObject, $requestedRev, $showRev, $maxRev)/e; | ||||
251 | |||||
252 | ## SMELL: This is also used in Foswiki::_TOC. Could insert a tag in | ||||
253 | ## TOC and remove all those here, finding the parameters only once | ||||
254 | 1 | 3µs | my @qparams = (); | ||
255 | 1 | 22µs | 1 | 81µs | foreach my $name ( $query->param ) { # spent 81µs making 1 call to Foswiki::Request::param |
256 | next if ( $name eq 'keywords' ); | ||||
257 | next if ( $name eq 'topic' ); | ||||
258 | push @qparams, $name => $query->param($name); | ||||
259 | } | ||||
260 | |||||
261 | # SMELL: %QUERYPARAMSTRING% isn't a documented macro, and is no longer used in core | ||||
262 | # or core extensions. Maintained for legacy only. | ||||
263 | 1 | 20µs | 1 | 9µs | if ( $tmpl =~ /%QUERYPARAMSTRING%/ ) { # spent 9µs making 1 call to Foswiki::UI::View::CORE:match |
264 | my $qps = Foswiki::make_params(@qparams); | ||||
265 | $qps =~ s/^.*\?/;/; # remove any anchor (there should be none) and the ? | ||||
266 | $tmpl =~ s/%QUERYPARAMSTRING%/$qps/g; | ||||
267 | } | ||||
268 | |||||
269 | # extract header and footer from the template, if there is a | ||||
270 | # %TEXT% tag marking the split point. The topic text is inserted | ||||
271 | # in place of the %TEXT% tag. The text before this tag is inserted | ||||
272 | # as header, the text after is inserted as footer. If there is a | ||||
273 | # %STARTTEXT% tag present, the header text between %STARTTEXT% and | ||||
274 | # %TEXT is rendered together, as is the footer text between %TEXT% | ||||
275 | # and %ENDTEXT%, if present. This allows correct handling of Foswiki | ||||
276 | # markup in header or footer if those do require examination of the | ||||
277 | # topic text to work correctly (e.g., %TOC%). | ||||
278 | # Note: This feature is experimental and may be replaced by an | ||||
279 | # alternative solution not requiring additional tags. | ||||
280 | 1 | 2µs | my ( $start, $end ); | ||
281 | |||||
282 | # SMELL: unchecked implicit untaint of data that *may* be coming from | ||||
283 | # a topic (topics can be templates) | ||||
284 | 1 | 82µs | 1 | 71µs | if ( $tmpl =~ m/^(.*)%TEXT%(.*)$/s ) { # spent 71µs making 1 call to Foswiki::UI::View::CORE:match |
285 | 1 | 27µs | my @starts = split( /%STARTTEXT%/, $1 ); | ||
286 | 1 | 4µs | if ( $#starts > 0 ) { | ||
287 | |||||
288 | # we know that there is something before %STARTTEXT% | ||||
289 | $start = $starts[0]; | ||||
290 | $text = $starts[1] . $text; | ||||
291 | } | ||||
292 | else { | ||||
293 | 1 | 10µs | $start = $1; | ||
294 | } | ||||
295 | 1 | 21µs | my @ends = split( /%ENDTEXT%/, $2 ); | ||
296 | 1 | 4µs | if ( $#ends > 0 ) { | ||
297 | |||||
298 | # we know that there is something after %ENDTEXT% | ||||
299 | $text .= $ends[0]; | ||||
300 | $end = $ends[1]; | ||||
301 | } | ||||
302 | else { | ||||
303 | 1 | 9µs | $end = $2; | ||
304 | } | ||||
305 | } | ||||
306 | else { | ||||
307 | my @starts = split( /%STARTTEXT%/, $tmpl ); | ||||
308 | if ( $#starts > 0 ) { | ||||
309 | |||||
310 | # we know that there is something before %STARTTEXT% | ||||
311 | $start = $starts[0]; | ||||
312 | $text = $starts[1]; | ||||
313 | } | ||||
314 | else { | ||||
315 | $start = $tmpl; | ||||
316 | $text = ''; | ||||
317 | } | ||||
318 | $end = ''; | ||||
319 | } | ||||
320 | |||||
321 | # If minimalist is set, images and anchors will be stripped from text | ||||
322 | 1 | 3µs | my $minimalist = 0; | ||
323 | 1 | 37µs | 4 | 867µs | if ($contentType) { # spent 861µs making 2 calls to Foswiki::getSkin, avg 430µs/call
# spent 6µs making 2 calls to Foswiki::UI::View::CORE:match, avg 3µs/call |
324 | $minimalist = ( $session->getSkin() =~ /\brss/ ); | ||||
325 | } | ||||
326 | elsif ( $session->getSkin() =~ /\brss/ ) { | ||||
327 | $contentType = 'text/xml'; | ||||
328 | $minimalist = 1; | ||||
329 | } | ||||
330 | elsif ( $session->getSkin() =~ /\bxml/ ) { | ||||
331 | $contentType = 'text/xml'; | ||||
332 | $minimalist = 1; | ||||
333 | } | ||||
334 | elsif ( $raw eq 'text' || $raw eq 'all' ) { | ||||
335 | $contentType = 'text/plain'; | ||||
336 | } | ||||
337 | else { | ||||
338 | 1 | 4µs | $contentType = 'text/html'; | ||
339 | } | ||||
340 | 1 | 11µs | 1 | 254µs | $session->{prefs}->setSessionPreferences( # spent 254µs making 1 call to Foswiki::Prefs::setSessionPreferences |
341 | MAXREV => $maxRev, | ||||
342 | CURRREV => $showRev | ||||
343 | ); | ||||
344 | |||||
345 | # Set page generation mode to RSS if using an RSS skin | ||||
346 | 1 | 12µs | 2 | 322µs | $session->enterContext('rss') if $session->getSkin() =~ /\brss/; # spent 320µs making 1 call to Foswiki::getSkin
# spent 2µs making 1 call to Foswiki::UI::View::CORE:match |
347 | |||||
348 | 1 | 2µs | my $page; | ||
349 | |||||
350 | # Legacy: If the _only_ skin is 'text' it is used like this: | ||||
351 | # http://.../view/Codev/MyTopic?skin=text&contenttype=text/plain&raw=on | ||||
352 | # which shows the topic as plain text; useful for those who want | ||||
353 | # to download plain text for the topic. So when the skin is 'text' | ||||
354 | # we do _not_ want to create a textarea. | ||||
355 | # raw=on&skin=text is deprecated; use raw=text instead. | ||||
356 | 1 | 13µs | 1 | 11µs | Monitor::MARK('Ready to render'); # spent 11µs making 1 call to Monitor::__ANON__[/usr/local/src/github.com/foswiki/core/lib/Monitor.pm:119] |
357 | 1 | 4µs | if ( $raw eq 'text' | ||
358 | || $raw eq 'all' | ||||
359 | || ( $raw && $session->getSkin() eq 'text' ) ) | ||||
360 | { | ||||
361 | |||||
362 | # use raw text | ||||
363 | $page = $text; | ||||
364 | } | ||||
365 | else { | ||||
366 | 1 | 4µs | my @args = ( $topicObject, $minimalist ); | ||
367 | |||||
368 | 1 | 12µs | 1 | 22µs | $session->enterContext('header_text'); # spent 22µs making 1 call to Foswiki::enterContext |
369 | 1 | 10µs | 1 | 93.4s | $page = _prepare( $start, @args ); # spent 93.4s making 1 call to Foswiki::UI::View::_prepare |
370 | 1 | 12µs | 1 | 22µs | $session->leaveContext('header_text'); # spent 22µs making 1 call to Foswiki::leaveContext |
371 | 1 | 11µs | 1 | 10µs | Monitor::MARK('Rendered header'); # spent 10µs making 1 call to Monitor::__ANON__[/usr/local/src/github.com/foswiki/core/lib/Monitor.pm:119] |
372 | |||||
373 | 1 | 3µs | if ($raw) { | ||
374 | if ($text) { | ||||
375 | my $p = $session->{prefs}; | ||||
376 | $page .= CGI::textarea( | ||||
377 | -readonly => 'readonly', | ||||
378 | -rows => $p->getPreference('EDITBOXHEIGHT'), | ||||
379 | -cols => $p->getPreference('EDITBOXWIDTH'), | ||||
380 | -style => $p->getPreference('EDITBOXSTYLE'), | ||||
381 | -class => 'foswikiTextarea foswikiTextareaRawView', | ||||
382 | -id => 'topic', | ||||
383 | -default => $text | ||||
384 | ); | ||||
385 | } | ||||
386 | } | ||||
387 | else { | ||||
388 | 1 | 8µs | 1 | 14µs | $session->enterContext('body_text'); # spent 14µs making 1 call to Foswiki::enterContext |
389 | 1 | 37µs | 1 | 475ms | $page .= _prepare( $text, @args ); # spent 475ms making 1 call to Foswiki::UI::View::_prepare |
390 | 1 | 13µs | 1 | 21µs | $session->leaveContext('body_text'); # spent 21µs making 1 call to Foswiki::leaveContext |
391 | } | ||||
392 | |||||
393 | 1 | 12µs | 1 | 10µs | Monitor::MARK('Rendered body'); # spent 10µs making 1 call to Monitor::__ANON__[/usr/local/src/github.com/foswiki/core/lib/Monitor.pm:119] |
394 | 1 | 8µs | 1 | 13µs | $session->enterContext('footer_text'); # spent 13µs making 1 call to Foswiki::enterContext |
395 | 1 | 37µs | 1 | 88.9s | $page .= _prepare( $end, @args ); # spent 88.9s making 1 call to Foswiki::UI::View::_prepare |
396 | 1 | 13µs | 1 | 26µs | $session->leaveContext('footer_text'); # spent 26µs making 1 call to Foswiki::leaveContext |
397 | 1 | 14µs | 1 | 10µs | Monitor::MARK('Rendered footer'); # spent 10µs making 1 call to Monitor::__ANON__[/usr/local/src/github.com/foswiki/core/lib/Monitor.pm:119] |
398 | } | ||||
399 | |||||
400 | # Output has to be done in one go, because if we generate the header and | ||||
401 | # then redirect because of some later constraint, some browsers fall over | ||||
402 | 1 | 15µs | 1 | 70.7ms | $session->writeCompletePage( $page, 'view', $contentType ); # spent 70.7ms making 1 call to Foswiki::writeCompletePage |
403 | 1 | 51µs | 1 | 5µs | Monitor::MARK('Wrote HTML'); # spent 5µs making 1 call to Monitor::__ANON__[/usr/local/src/github.com/foswiki/core/lib/Monitor.pm:119] |
404 | } | ||||
405 | |||||
406 | sub _prepare { | ||||
407 | 3 | 14µs | my ( $text, $topicObject, $minimalist ) = @_; | ||
408 | |||||
409 | 3 | 53µs | 3 | 183s | $text = $topicObject->expandMacros($text); # spent 183s making 3 calls to Foswiki::Meta::expandMacros, avg 60.9s/call |
410 | 3 | 46µs | 3 | 168ms | $text = $topicObject->renderTML($text); # spent 168ms making 3 calls to Foswiki::Meta::renderTML, avg 55.9ms/call |
411 | 3 | 2.11ms | 55 | 1.93ms | $text =~ s/( ?) *<\/?(nop|noautolink)\/?>\n?/$1/gois; # spent 1.50ms making 52 calls to Foswiki::UI::View::CORE:substcont, avg 29µs/call
# spent 429µs making 3 calls to Foswiki::UI::View::CORE:subst, avg 143µs/call |
412 | |||||
413 | 3 | 4µs | if ($minimalist) { | ||
414 | $text =~ s/<img [^>]*>//gi; # remove image tags | ||||
415 | $text =~ s/<a [^>]*>//gi; # remove anchor tags | ||||
416 | $text =~ s/<\/a>//gi; # remove anchor tags | ||||
417 | } | ||||
418 | |||||
419 | 3 | 67µs | return $text; | ||
420 | } | ||||
421 | |||||
422 | =begin TML | ||||
423 | |||||
424 | ---++ StaticMethod revisionsAround($session, $topicObject, $requestedRev, $showRev, $maxRev) -> $output | ||||
425 | |||||
426 | Calculate the revisions spanning the current one for display in the bottom | ||||
427 | bar. | ||||
428 | |||||
429 | =cut | ||||
430 | |||||
431 | # spent 313ms (117µs+313) within Foswiki::UI::View::revisionsAround which was called:
# once (117µs+313ms) by Foswiki::UI::View::view at line 249 | ||||
432 | 1 | 6µs | my ( $session, $topicObject, $requestedRev, $showRev, $maxRev ) = @_; | ||
433 | |||||
434 | 1 | 5µs | my $revsToShow = $Foswiki::cfg{NumberOfRevisions} + 1; | ||
435 | |||||
436 | # Soak up the revision iterator | ||||
437 | 1 | 10µs | 1 | 312ms | my $revIt = $topicObject->getRevisionHistory(); # spent 312ms making 1 call to Foswiki::Meta::getRevisionHistory |
438 | 1 | 25µs | 1 | 81µs | my @revs = $revIt->all(); # spent 81µs making 1 call to Foswiki::Iterator::all |
439 | 1 | 2µs | my $maxRevDisjoint = 0; | ||
440 | |||||
441 | 1 | 4µs | if ( $Foswiki::cfg{NumberOfRevisions} ) { | ||
442 | |||||
443 | # Locate the preferred rev in the array | ||||
444 | 1 | 2µs | my $showIndex = $#revs; | ||
445 | 1 | 1µs | my $left = 0; | ||
446 | 1 | 4µs | my $right = $Foswiki::cfg{NumberOfRevisions}; | ||
447 | 1 | 2µs | if ($requestedRev) { | ||
448 | while ( $showIndex && $revs[$showIndex] != $showRev ) { | ||||
449 | $showIndex--; | ||||
450 | } | ||||
451 | $right = $showIndex + $Foswiki::cfg{NumberOfRevisions} - 1; | ||||
452 | $right = scalar(@revs) if $right > scalar(@revs); | ||||
453 | $left = $right - $Foswiki::cfg{NumberOfRevisions}; | ||||
454 | if ( $left < 0 ) { | ||||
455 | $left = 0; | ||||
456 | $right = $Foswiki::cfg{NumberOfRevisions}; | ||||
457 | } | ||||
458 | } | ||||
459 | 1 | 2µs | splice( @revs, $right ) if ( $right < scalar(@revs) ); | ||
460 | 1 | 2µs | splice( @revs, 0, $left ); | ||
461 | 1 | 2µs | if ( $left > 0 ) { | ||
462 | |||||
463 | # Put the max rev back in at the front, and flag | ||||
464 | # special treatment | ||||
465 | $maxRevDisjoint = 1; | ||||
466 | unshift( @revs, $maxRev ); | ||||
467 | } | ||||
468 | } | ||||
469 | |||||
470 | 1 | 2µs | my $output = ''; | ||
471 | 1 | 1µs | my $r = 0; | ||
472 | 1 | 3µs | while ( $r < scalar(@revs) ) { | ||
473 | 1 | 3µs | if ( $revs[$r] == $showRev ) { | ||
474 | 1 | 3µs | $output .= 'r' . $showRev; | ||
475 | } | ||||
476 | else { | ||||
477 | $output .= CGI::a( | ||||
478 | { | ||||
479 | href => $session->getScriptUrl( | ||||
480 | 0, 'view', | ||||
481 | $topicObject->web, $topicObject->topic, | ||||
482 | rev => $revs[$r] | ||||
483 | ), | ||||
484 | rel => 'nofollow' | ||||
485 | }, | ||||
486 | 'r' . $revs[$r] | ||||
487 | ); | ||||
488 | } | ||||
489 | 1 | 2µs | if ( $r == 0 && $maxRevDisjoint ) { | ||
490 | $output .= ' | '; | ||||
491 | } | ||||
492 | elsif ( $r < $#revs ) { | ||||
493 | $output .= ' ' | ||||
494 | . CGI::a( | ||||
495 | { | ||||
496 | href => $session->getScriptUrl( | ||||
497 | 0, 'rdiff', $topicObject->web, $topicObject->topic, | ||||
498 | rev1 => $revs[ $r + 1 ], | ||||
499 | rev2 => $revs[$r] | ||||
500 | ), | ||||
501 | rel => 'nofollow' | ||||
502 | }, | ||||
503 | '<' | ||||
504 | ) . ' '; | ||||
505 | } | ||||
506 | 1 | 3µs | $r++; | ||
507 | } | ||||
508 | 1 | 26µs | return $output; | ||
509 | } | ||||
510 | |||||
511 | 1 | 5µs | 1; | ||
512 | __END__ | ||||
# spent 91µs within Foswiki::UI::View::CORE:match which was called 6 times, avg 15µs/call:
# 2 times (6µs+0s) by Foswiki::UI::View::view at line 323, avg 3µs/call
# once (71µs+0s) by Foswiki::UI::View::view at line 284
# once (9µs+0s) by Foswiki::UI::View::view at line 263
# once (4µs+0s) by Foswiki::UI::View::view at line 225
# once (2µs+0s) by Foswiki::UI::View::view at line 346 | |||||
# spent 526µs within Foswiki::UI::View::CORE:subst which was called 7 times, avg 75µs/call:
# 3 times (429µs+0s) by Foswiki::UI::View::_prepare at line 411, avg 143µs/call
# once (44µs+0s) by Foswiki::UI::View::view at line 244
# once (19µs+0s) by Foswiki::UI::View::view at line 234
# once (18µs+0s) by Foswiki::UI::View::view at line 235
# once (15µs+0s) by Foswiki::UI::View::view at line 248 | |||||
sub Foswiki::UI::View::CORE:substcont; # opcode |