Filename | /var/www/foswikidev/core/lib/Foswiki/Plugins/TablePlugin/Core.pm |
Statements | Executed 619 statements in 9.23ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
5 | 1 | 1 | 658µs | 1.54ms | handler | Foswiki::Plugins::TablePlugin::Core::
1 | 1 | 1 | 152µs | 248µs | _parseAttributes | Foswiki::Plugins::TablePlugin::Core::
6 | 2 | 1 | 139µs | 139µs | _mergeHashes | Foswiki::Plugins::TablePlugin::Core::
5 | 1 | 1 | 63µs | 213µs | _resetReusedVariables | Foswiki::Plugins::TablePlugin::Core::
1 | 1 | 1 | 57µs | 821µs | _init | Foswiki::Plugins::TablePlugin::Core::
13 | 5 | 1 | 53µs | 78µs | _debug | Foswiki::Plugins::TablePlugin::Core::
21 | 21 | 1 | 36µs | 36µs | _storeAttribute | Foswiki::Plugins::TablePlugin::Core::
1 | 1 | 1 | 17µs | 305µs | _initDefaults | Foswiki::Plugins::TablePlugin::Core::
1 | 1 | 1 | 16µs | 29µs | BEGIN@3 | Foswiki::Plugins::TablePlugin::
1 | 1 | 1 | 15µs | 267µs | _parseDefaultAttributes | Foswiki::Plugins::TablePlugin::Core::
1 | 1 | 1 | 12µs | 26µs | BEGIN@1760 | Foswiki::Plugins::TablePlugin::Core::
6 | 6 | 1 | 12µs | 12µs | _arrayRefFromParam | Foswiki::Plugins::TablePlugin::Core::
1 | 1 | 1 | 10µs | 13µs | BEGIN@10 | Foswiki::Plugins::TablePlugin::Core::
1 | 1 | 1 | 10µs | 146µs | BEGIN@11 | Foswiki::Plugins::TablePlugin::Core::
1 | 1 | 1 | 9µs | 19µs | BEGIN@1762 | Foswiki::Plugins::TablePlugin::Core::
1 | 1 | 1 | 9µs | 13µs | BEGIN@4 | Foswiki::Plugins::TablePlugin::
2 | 2 | 1 | 8µs | 15µs | _debugData | Foswiki::Plugins::TablePlugin::Core::
1 | 1 | 1 | 7µs | 7µs | BEGIN@8 | Foswiki::Plugins::TablePlugin::Core::
1 | 1 | 1 | 5µs | 5µs | BEGIN@13 | Foswiki::Plugins::TablePlugin::Core::
1 | 1 | 1 | 4µs | 4µs | BEGIN@9 | Foswiki::Plugins::TablePlugin::Core::
2 | 2 | 1 | 3µs | 3µs | _cleanParamValue | Foswiki::Plugins::TablePlugin::Core::
0 | 0 | 0 | 0s | 0s | __ANON__[:1044] | Foswiki::Plugins::TablePlugin::Core::
0 | 0 | 0 | 0s | 0s | __ANON__[:497] | Foswiki::Plugins::TablePlugin::Core::
0 | 0 | 0 | 0s | 0s | __ANON__[:502] | Foswiki::Plugins::TablePlugin::Core::
0 | 0 | 0 | 0s | 0s | _addDefaultStyles | Foswiki::Plugins::TablePlugin::Core::
0 | 0 | 0 | 0s | 0s | _addHeadStyles | Foswiki::Plugins::TablePlugin::Core::
0 | 0 | 0 | 0s | 0s | _appendColNumberCssClass | Foswiki::Plugins::TablePlugin::Core::
0 | 0 | 0 | 0s | 0s | _appendFirstColumnCssClass | Foswiki::Plugins::TablePlugin::Core::
0 | 0 | 0 | 0s | 0s | _appendLastColumnCssClass | Foswiki::Plugins::TablePlugin::Core::
0 | 0 | 0 | 0s | 0s | _appendLastRowCssClass | Foswiki::Plugins::TablePlugin::Core::
0 | 0 | 0 | 0s | 0s | _appendRowNumberCssClass | Foswiki::Plugins::TablePlugin::Core::
0 | 0 | 0 | 0s | 0s | _appendSortedAscendingCssClass | Foswiki::Plugins::TablePlugin::Core::
0 | 0 | 0 | 0s | 0s | _appendSortedCssClass | Foswiki::Plugins::TablePlugin::Core::
0 | 0 | 0 | 0s | 0s | _appendSortedDescendingCssClass | Foswiki::Plugins::TablePlugin::Core::
0 | 0 | 0 | 0s | 0s | _appendToClassList | Foswiki::Plugins::TablePlugin::Core::
0 | 0 | 0 | 0s | 0s | _convertStringToDate | Foswiki::Plugins::TablePlugin::Core::
0 | 0 | 0 | 0s | 0s | _convertStringToNumber | Foswiki::Plugins::TablePlugin::Core::
0 | 0 | 0 | 0s | 0s | _createCssStyles | Foswiki::Plugins::TablePlugin::Core::
0 | 0 | 0 | 0s | 0s | _getCurrentSortDirection | Foswiki::Plugins::TablePlugin::Core::
0 | 0 | 0 | 0s | 0s | _getDefaultSortDirection | Foswiki::Plugins::TablePlugin::Core::
0 | 0 | 0 | 0s | 0s | _getImageTextForSorting | Foswiki::Plugins::TablePlugin::Core::
0 | 0 | 0 | 0s | 0s | _getIncludeParams | Foswiki::Plugins::TablePlugin::Core::
0 | 0 | 0 | 0s | 0s | _getNewSortDirection | Foswiki::Plugins::TablePlugin::Core::
0 | 0 | 0 | 0s | 0s | _headerRowCount | Foswiki::Plugins::TablePlugin::Core::
0 | 0 | 0 | 0s | 0s | _parseTableSpecificTableAttributes | Foswiki::Plugins::TablePlugin::Core::
0 | 0 | 0 | 0s | 0s | _processTableRow | Foswiki::Plugins::TablePlugin::Core::
0 | 0 | 0 | 0s | 0s | _setSortTypeForCells | Foswiki::Plugins::TablePlugin::Core::
0 | 0 | 0 | 0s | 0s | _stripHtml | Foswiki::Plugins::TablePlugin::Core::
0 | 0 | 0 | 0s | 0s | _writeStyleToHead | Foswiki::Plugins::TablePlugin::Core::
0 | 0 | 0 | 0s | 0s | addDefaultSizeUnit | Foswiki::Plugins::TablePlugin::Core::
0 | 0 | 0 | 0s | 0s | emitTable | Foswiki::Plugins::TablePlugin::Core::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | # See bottom of file for license and copyright information | ||||
2 | |||||
3 | 2 | 29µs | 2 | 42µs | # spent 29µs (16+13) within Foswiki::Plugins::TablePlugin::BEGIN@3 which was called:
# once (16µs+13µs) by Foswiki::Plugins::TablePlugin::preRenderingHandler at line 3 # spent 29µs making 1 call to Foswiki::Plugins::TablePlugin::BEGIN@3
# spent 13µs making 1 call to strict::import |
4 | 2 | 32µs | 2 | 18µs | # spent 13µs (9+4) within Foswiki::Plugins::TablePlugin::BEGIN@4 which was called:
# once (9µs+4µs) by Foswiki::Plugins::TablePlugin::preRenderingHandler at line 4 # spent 13µs making 1 call to Foswiki::Plugins::TablePlugin::BEGIN@4
# spent 4µs making 1 call to warnings::import |
5 | |||||
6 | package Foswiki::Plugins::TablePlugin::Core; | ||||
7 | |||||
8 | 2 | 24µs | 1 | 7µs | # spent 7µs within Foswiki::Plugins::TablePlugin::Core::BEGIN@8 which was called:
# once (7µs+0s) by Foswiki::Plugins::TablePlugin::preRenderingHandler at line 8 # spent 7µs making 1 call to Foswiki::Plugins::TablePlugin::Core::BEGIN@8 |
9 | 2 | 21µs | 1 | 4µs | # spent 4µs within Foswiki::Plugins::TablePlugin::Core::BEGIN@9 which was called:
# once (4µs+0s) by Foswiki::Plugins::TablePlugin::preRenderingHandler at line 9 # spent 4µs making 1 call to Foswiki::Plugins::TablePlugin::Core::BEGIN@9 |
10 | 2 | 28µs | 2 | 17µs | # spent 13µs (10+4) within Foswiki::Plugins::TablePlugin::Core::BEGIN@10 which was called:
# once (10µs+4µs) by Foswiki::Plugins::TablePlugin::preRenderingHandler at line 10 # spent 13µs making 1 call to Foswiki::Plugins::TablePlugin::Core::BEGIN@10
# spent 4µs making 1 call to Foswiki::Time::import |
11 | 2 | 57µs | 2 | 283µs | # spent 146µs (10+137) within Foswiki::Plugins::TablePlugin::Core::BEGIN@11 which was called:
# once (10µs+137µs) by Foswiki::Plugins::TablePlugin::preRenderingHandler at line 11 # spent 146µs making 1 call to Foswiki::Plugins::TablePlugin::Core::BEGIN@11
# spent 137µs making 1 call to Error::import |
12 | |||||
13 | # spent 5µs within Foswiki::Plugins::TablePlugin::Core::BEGIN@13 which was called:
# once (5µs+0s) by Foswiki::Plugins::TablePlugin::preRenderingHandler at line 18 | ||||
14 | 1 | 6µs | if ( $Foswiki::cfg{UseLocale} ) { | ||
15 | require locale; | ||||
16 | import locale(); | ||||
17 | } | ||||
18 | 1 | 6.57ms | 1 | 5µs | } # spent 5µs making 1 call to Foswiki::Plugins::TablePlugin::Core::BEGIN@13 |
19 | |||||
20 | 1 | 200ns | my @curTable; | ||
21 | 1 | 100ns | my $translationToken; | ||
22 | 1 | 0s | my $insideTABLE; | ||
23 | 1 | 0s | my $currTablePre; | ||
24 | 1 | 0s | my $didWriteDefaultStyle; | ||
25 | 1 | 0s | my $defaultAttrs; # to write generic table CSS | ||
26 | 1 | 100ns | my $tableSpecificAttrs; # to write table specific table CSS | ||
27 | 1 | 100ns | my $combinedTableAttrs; # default and specific table attributes | ||
28 | 1 | 800ns | my $styles = {}; # hash of default and specific styles | ||
29 | 1 | 600ns | my @messages = (); | ||
30 | |||||
31 | # not yet refactored: | ||||
32 | 1 | 100ns | my $tableCount; | ||
33 | 1 | 100ns | my $sortCol; | ||
34 | 1 | 100ns | my $MAX_SORT_COLS; | ||
35 | 1 | 100ns | my $requestedTable; | ||
36 | 1 | 100ns | my $up; | ||
37 | 1 | 100ns | my $sortTablesInText; | ||
38 | 1 | 0s | my $sortAttachments; | ||
39 | 1 | 100ns | my $sortColFromUrl; | ||
40 | 1 | 0s | my $url; | ||
41 | 1 | 0s | my $currentSortDirection; | ||
42 | 1 | 0s | my @rowspan; | ||
43 | |||||
44 | 1 | 400ns | my $HEAD_ID_DEFAULT_STYLE = | ||
45 | 'TABLEPLUGIN_default'; # this name is part of the API, do not change | ||||
46 | 1 | 200ns | my $HEAD_ID_SPECIFIC_STYLE = | ||
47 | 'TABLEPLUGIN_specific'; # this name is part of the API, do not change | ||||
48 | |||||
49 | 1 | 2µs | my $PATTERN_TABLE = qr/%TABLE(?:{(.*?)})?%/; | ||
50 | 1 | 0s | my $URL_ICON; | ||
51 | 1 | 0s | my $GIF_TABLE_SORT_ASCENDING; | ||
52 | 1 | 0s | my $GIF_TABLE_SORT_DESCENDING; | ||
53 | 1 | 0s | my $GIF_TABLE_SORT_BOTH; | ||
54 | 1 | 0s | my $CHAR_SORT_ASCENDING; | ||
55 | 1 | 0s | my $CHAR_SORT_DESCENDING; | ||
56 | 1 | 0s | my $CHAR_SORT_BOTH; | ||
57 | |||||
58 | 1 | 0s | my $SORT_DIRECTION; | ||
59 | |||||
60 | 1 | 800ns | my $PATTERN_ATTRIBUTE_SIZE = qr'([0-9]+)(px|%)*'o; | ||
61 | |||||
62 | 1 | 2µs | my $TABLE_RULES = {}; | ||
63 | 1 | 3µs | $TABLE_RULES->{all}->{TD} = $TABLE_RULES->{all}->{TH} = | ||
64 | $TABLE_RULES->{data_all}->{TD} = $TABLE_RULES->{header_all}->{TH} = | ||||
65 | 'border-style:solid'; | ||||
66 | 1 | 2µs | $TABLE_RULES->{none}->{TD} = $TABLE_RULES->{none}->{TH} = | ||
67 | $TABLE_RULES->{data_none}->{TD} = $TABLE_RULES->{header_none}->{TH} = | ||||
68 | 'border-style:none'; | ||||
69 | 1 | 2µs | $TABLE_RULES->{cols}->{TD} = $TABLE_RULES->{cols}->{TH} = | ||
70 | $TABLE_RULES->{data_cols}->{TD} = $TABLE_RULES->{header_cols}->{TH} = | ||||
71 | 'border-style:none solid'; | ||||
72 | 1 | 1µs | $TABLE_RULES->{rows}->{TD} = $TABLE_RULES->{rows}->{TH} = | ||
73 | $TABLE_RULES->{data_rows}->{TD} = $TABLE_RULES->{header_rows}->{TH} = | ||||
74 | 'border-style:solid none'; | ||||
75 | 1 | 500ns | $TABLE_RULES->{groups}->{TD} = 'border-style:none'; | ||
76 | 1 | 400ns | $TABLE_RULES->{groups}->{TH} = 'border-style:solid none'; | ||
77 | |||||
78 | 1 | 200ns | my $TABLE_FRAME = {}; | ||
79 | 1 | 400ns | $TABLE_FRAME->{void} = 'border-style:none'; | ||
80 | 1 | 400ns | $TABLE_FRAME->{above} = 'border-style:solid none none none'; | ||
81 | 1 | 300ns | $TABLE_FRAME->{below} = 'border-style:none none solid none'; | ||
82 | 1 | 300ns | $TABLE_FRAME->{lhs} = 'border-style:none none none solid'; | ||
83 | 1 | 300ns | $TABLE_FRAME->{rhs} = 'border-style:none solid none none'; | ||
84 | 1 | 300ns | $TABLE_FRAME->{hsides} = 'border-style:solid none solid none'; | ||
85 | 1 | 300ns | $TABLE_FRAME->{vsides} = 'border-style:none solid none solid'; | ||
86 | 1 | 700ns | $TABLE_FRAME->{box} = 'border-style:solid'; | ||
87 | 1 | 300ns | $TABLE_FRAME->{border} = 'border-style:solid'; | ||
88 | |||||
89 | # spent 821µs (57+764) within Foswiki::Plugins::TablePlugin::Core::_init which was called:
# once (57µs+764µs) by Foswiki::Plugins::TablePlugin::preRenderingHandler at line 80 of /var/www/foswikidev/core/lib/Foswiki/Plugins/TablePlugin.pm | ||||
90 | 1 | 1µs | 1 | 9µs | _debug("_init"); # spent 9µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_debug |
91 | 1 | 400ns | $translationToken = "\0"; | ||
92 | |||||
93 | # the maximum number of columns we will handle | ||||
94 | 1 | 200ns | $MAX_SORT_COLS = 10000; | ||
95 | 1 | 100ns | $didWriteDefaultStyle = 0; | ||
96 | 1 | 100ns | $tableCount = 0; | ||
97 | 1 | 200ns | $currTablePre = ''; | ||
98 | 1 | 400ns | $combinedTableAttrs = {}; | ||
99 | 1 | 200ns | $tableSpecificAttrs = {}; | ||
100 | 1 | 800ns | $styles = {}; | ||
101 | 1 | 4µs | 1 | 32µs | $URL_ICON = # spent 32µs making 1 call to Foswiki::Func::getPubUrlPath |
102 | Foswiki::Func::getPubUrlPath() . '/' | ||||
103 | . $Foswiki::cfg{SystemWebName} | ||||
104 | . '/DocumentGraphics/'; | ||||
105 | 1 | 10µs | 1 | 232µs | $GIF_TABLE_SORT_ASCENDING = CGI::img( # spent 232µs making 1 call to CGI::AUTOLOAD |
106 | { | ||||
107 | src => $URL_ICON . 'tablesortup.gif', | ||||
108 | border => 0, | ||||
109 | width => 11, | ||||
110 | height => 13, | ||||
111 | alt => 'Sorted ascending', | ||||
112 | title => 'Sorted ascending' | ||||
113 | } | ||||
114 | ); | ||||
115 | |||||
116 | 1 | 4µs | 1 | 56µs | $GIF_TABLE_SORT_DESCENDING = CGI::img( # spent 56µs making 1 call to CGI::img |
117 | { | ||||
118 | src => $URL_ICON . 'tablesortdown.gif', | ||||
119 | border => 0, | ||||
120 | width => 11, | ||||
121 | height => 13, | ||||
122 | alt => 'Sorted descending', | ||||
123 | title => 'Sorted descending' | ||||
124 | } | ||||
125 | ); | ||||
126 | |||||
127 | 1 | 4µs | 1 | 55µs | $GIF_TABLE_SORT_BOTH = CGI::img( # spent 55µs making 1 call to CGI::img |
128 | { | ||||
129 | src => $URL_ICON . 'tablesortdiamond.gif', | ||||
130 | border => 0, | ||||
131 | width => 11, | ||||
132 | height => 13, | ||||
133 | alt => 'Sort', | ||||
134 | title => 'Sort' | ||||
135 | } | ||||
136 | ); | ||||
137 | 1 | 4µs | 1 | 202µs | $CHAR_SORT_ASCENDING = CGI::span( { class => 'tableSortIcon tableSortUp' }, # spent 202µs making 1 call to CGI::AUTOLOAD |
138 | $GIF_TABLE_SORT_ASCENDING ); | ||||
139 | 1 | 2µs | 1 | 28µs | $CHAR_SORT_DESCENDING = # spent 28µs making 1 call to CGI::span |
140 | CGI::span( { class => 'tableSortIcon tableSortDown' }, | ||||
141 | $GIF_TABLE_SORT_DESCENDING ); | ||||
142 | 1 | 2µs | 1 | 26µs | $CHAR_SORT_BOTH = CGI::span( { class => 'tableSortIcon tableSortUp' }, # spent 26µs making 1 call to CGI::span |
143 | $GIF_TABLE_SORT_BOTH ); | ||||
144 | |||||
145 | 1 | 5µs | $SORT_DIRECTION = { | ||
146 | 'ASCENDING' => 0, | ||||
147 | 'DESCENDING' => 1, | ||||
148 | 'NONE' => 2, | ||||
149 | }; | ||||
150 | } | ||||
151 | |||||
152 | # called one time | ||||
153 | # spent 305µs (17+289) within Foswiki::Plugins::TablePlugin::Core::_initDefaults which was called:
# once (17µs+289µs) by Foswiki::Plugins::TablePlugin::Core::handler at line 1930 | ||||
154 | 1 | 900ns | 1 | 5µs | _debug('_initDefaults'); # spent 5µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_debug |
155 | 1 | 2µs | $defaultAttrs = { | ||
156 | headerrows => 0, | ||||
157 | footerrows => 0, | ||||
158 | sort => 1, | ||||
159 | class => 'foswikiTable', | ||||
160 | sortAllTables => $sortTablesInText, | ||||
161 | }; | ||||
162 | 1 | 5µs | 1 | 267µs | _parseDefaultAttributes( # spent 267µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_parseDefaultAttributes |
163 | %{Foswiki::Plugins::TablePlugin::pluginAttributes} ); | ||||
164 | |||||
165 | 1 | 5µs | 1 | 16µs | $combinedTableAttrs = _mergeHashes( {}, $defaultAttrs ); # spent 16µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_mergeHashes |
166 | } | ||||
167 | |||||
168 | sub _addDefaultStyles { | ||||
169 | return if $Foswiki::Plugins::TablePlugin::writtenToHead; | ||||
170 | $Foswiki::Plugins::TablePlugin::writtenToHead = 1; | ||||
171 | |||||
172 | # create CSS styles tables in general | ||||
173 | my ( $id, @styles ) = _createCssStyles( 1, $defaultAttrs ); | ||||
174 | _addHeadStyles( $HEAD_ID_DEFAULT_STYLE, @styles ) if scalar(@styles); | ||||
175 | } | ||||
176 | |||||
177 | # spent 213µs (63+150) within Foswiki::Plugins::TablePlugin::Core::_resetReusedVariables which was called 5 times, avg 43µs/call:
# 5 times (63µs+150µs) by Foswiki::Plugins::TablePlugin::Core::handler at line 1968, avg 43µs/call | ||||
178 | 5 | 5µs | 5 | 27µs | _debug('_resetReusedVariables'); # spent 27µs making 5 calls to Foswiki::Plugins::TablePlugin::Core::_debug, avg 5µs/call |
179 | 5 | 2µs | $currTablePre = ''; | ||
180 | 5 | 24µs | 5 | 122µs | $combinedTableAttrs = _mergeHashes( {}, $defaultAttrs ); # spent 122µs making 5 calls to Foswiki::Plugins::TablePlugin::Core::_mergeHashes, avg 24µs/call |
181 | 5 | 3µs | $tableSpecificAttrs = {}; | ||
182 | 5 | 1µs | $sortCol = 0; | ||
183 | 5 | 17µs | @messages = (); | ||
184 | } | ||||
185 | |||||
186 | =pod | ||||
187 | |||||
188 | =cut | ||||
189 | |||||
190 | # spent 36µs within Foswiki::Plugins::TablePlugin::Core::_storeAttribute which was called 21 times, avg 2µs/call:
# once (3µs+0s) by Foswiki::Plugins::TablePlugin::Core::_parseAttributes at line 335
# once (3µs+0s) by Foswiki::Plugins::TablePlugin::Core::_parseAttributes at line 375
# once (2µs+0s) by Foswiki::Plugins::TablePlugin::Core::_parseAttributes at line 380
# once (2µs+0s) by Foswiki::Plugins::TablePlugin::Core::_parseAttributes at line 398
# once (2µs+0s) by Foswiki::Plugins::TablePlugin::Core::_parseAttributes at line 392
# once (2µs+0s) by Foswiki::Plugins::TablePlugin::Core::_parseAttributes at line 400
# once (2µs+0s) by Foswiki::Plugins::TablePlugin::Core::_parseAttributes at line 381
# once (2µs+0s) by Foswiki::Plugins::TablePlugin::Core::_parseAttributes at line 395
# once (2µs+0s) by Foswiki::Plugins::TablePlugin::Core::_parseAttributes at line 336
# once (2µs+0s) by Foswiki::Plugins::TablePlugin::Core::_parseAttributes at line 377
# once (2µs+0s) by Foswiki::Plugins::TablePlugin::Core::_parseAttributes at line 393
# once (2µs+0s) by Foswiki::Plugins::TablePlugin::Core::_parseAttributes at line 394
# once (2µs+0s) by Foswiki::Plugins::TablePlugin::Core::_parseAttributes at line 338
# once (2µs+0s) by Foswiki::Plugins::TablePlugin::Core::_parseAttributes at line 340
# once (1µs+0s) by Foswiki::Plugins::TablePlugin::Core::_parseAttributes at line 382
# once (1µs+0s) by Foswiki::Plugins::TablePlugin::Core::_parseAttributes at line 386
# once (1µs+0s) by Foswiki::Plugins::TablePlugin::Core::_parseAttributes at line 383
# once (1µs+0s) by Foswiki::Plugins::TablePlugin::Core::_parseAttributes at line 339
# once (1µs+0s) by Foswiki::Plugins::TablePlugin::Core::_parseAttributes at line 408
# once (1µs+0s) by Foswiki::Plugins::TablePlugin::Core::_parseAttributes at line 405
# once (1µs+0s) by Foswiki::Plugins::TablePlugin::Core::_parseAttributes at line 389 | ||||
191 | 21 | 11µs | my ( $inAttrName, $inValue, $inCollection ) = @_; | ||
192 | |||||
193 | 21 | 3µs | if ( !$inCollection ) { | ||
194 | _debug('_storeAttribute -- missing inCollection!'); | ||||
195 | return; | ||||
196 | } | ||||
197 | 21 | 38µs | return if !defined $inValue; | ||
198 | 8 | 2µs | return if !defined $inAttrName || $inAttrName eq ''; | ||
199 | 8 | 29µs | $inCollection->{$inAttrName} = $inValue; | ||
200 | } | ||||
201 | |||||
202 | =pod | ||||
203 | |||||
204 | =cut | ||||
205 | |||||
206 | # spent 267µs (15+252) within Foswiki::Plugins::TablePlugin::Core::_parseDefaultAttributes which was called:
# once (15µs+252µs) by Foswiki::Plugins::TablePlugin::Core::_initDefaults at line 162 | ||||
207 | 1 | 7µs | my (%params) = @_; | ||
208 | |||||
209 | 1 | 1µs | 1 | 4µs | _debug('_parseDefaultAttributes'); # spent 4µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_debug |
210 | |||||
211 | 1 | 4µs | 1 | 248µs | _parseAttributes( 0, $defaultAttrs, \%params ); # spent 248µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_parseAttributes |
212 | } | ||||
213 | |||||
214 | =pod | ||||
215 | |||||
216 | =cut | ||||
217 | |||||
218 | sub _parseTableSpecificTableAttributes { | ||||
219 | my (%params) = @_; | ||||
220 | |||||
221 | _debug('_parseTableSpecificTableAttributes'); | ||||
222 | |||||
223 | _parseAttributes( 1, $tableSpecificAttrs, \%params ); | ||||
224 | |||||
225 | # remove default values from hash | ||||
226 | while ( my ( $key, $value ) = each %{$tableSpecificAttrs} ) { | ||||
227 | delete $tableSpecificAttrs->{$key} | ||||
228 | if $defaultAttrs->{$key} && $value eq $defaultAttrs->{$key}; | ||||
229 | } | ||||
230 | $combinedTableAttrs = | ||||
231 | _mergeHashes( $combinedTableAttrs, $tableSpecificAttrs ); | ||||
232 | _debugData( 'combinedTableAttrs', $combinedTableAttrs ); | ||||
233 | |||||
234 | # create CSS styles for this table only | ||||
235 | my ( $id, @styles ) = _createCssStyles( 0, $tableSpecificAttrs ); | ||||
236 | _debugData( "after _createCssStyles, id=$id; styles", \@styles ); | ||||
237 | |||||
238 | _addHeadStyles( $id, @styles ) if scalar(@styles); | ||||
239 | |||||
240 | return $currTablePre . '<nop>'; | ||||
241 | } | ||||
242 | |||||
243 | =pod | ||||
244 | |||||
245 | =cut | ||||
246 | |||||
247 | # spent 248µs (152+96) within Foswiki::Plugins::TablePlugin::Core::_parseAttributes which was called:
# once (152µs+96µs) by Foswiki::Plugins::TablePlugin::Core::_parseDefaultAttributes at line 211 | ||||
248 | 1 | 500ns | my ( $isTableSpecific, $inCollection, $inParams ) = @_; | ||
249 | |||||
250 | 1 | 2µs | 1 | 9µs | _debugData( "isTableSpecific=$isTableSpecific; _parseAttributes=", # spent 9µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_debugData |
251 | $inParams ); | ||||
252 | |||||
253 | # include topic to read definitions | ||||
254 | 1 | 300ns | if ( $inParams->{include} ) { | ||
255 | my ( $includeParams, $message ) = | ||||
256 | _getIncludeParams( $inParams->{include} ); | ||||
257 | |||||
258 | if ($includeParams) { | ||||
259 | $inParams = $includeParams; | ||||
260 | } | ||||
261 | if ($message) { | ||||
262 | push( @messages, $message ); | ||||
263 | } | ||||
264 | } | ||||
265 | |||||
266 | # table attributes | ||||
267 | # some will be used for css styling as well | ||||
268 | |||||
269 | 1 | 200ns | _storeAttribute( 'generateInlineMarkup', | ||
270 | Foswiki::Func::isTrue( $inParams->{inlinemarkup} ), | ||||
271 | $inCollection ) | ||||
272 | if defined $inParams->{inlinemarkup}; | ||||
273 | |||||
274 | # sort attributes | ||||
275 | 1 | 300ns | if ( defined $inParams->{sort} ) { | ||
276 | my $sort = Foswiki::Func::isTrue( $inParams->{sort} ); | ||||
277 | _storeAttribute( 'sort', $sort, $inCollection ); | ||||
278 | _storeAttribute( 'sortAllTables', $sort, $inCollection ); | ||||
279 | } | ||||
280 | 1 | 200ns | if ( defined( $inParams->{initsort} ) | ||
281 | and int( $inParams->{initsort} ) > 0 ) | ||||
282 | { | ||||
283 | _storeAttribute( 'initSort', $inParams->{initsort}, $inCollection ); | ||||
284 | |||||
285 | # override sort attribute: we are sorting after all | ||||
286 | _storeAttribute( 'sort', 1, $inCollection ); | ||||
287 | } | ||||
288 | |||||
289 | 1 | 200ns | if ( $inParams->{initdirection} ) { | ||
290 | _storeAttribute( 'initDirection', $SORT_DIRECTION->{'ASCENDING'}, | ||||
291 | $inCollection ) | ||||
292 | if $inParams->{initdirection} =~ /^down$/i; | ||||
293 | _storeAttribute( 'initDirection', $SORT_DIRECTION->{'DESCENDING'}, | ||||
294 | $inCollection ) | ||||
295 | if $inParams->{initdirection} =~ /^up$/i; | ||||
296 | } | ||||
297 | |||||
298 | # Don't allow sort requests when rendering for static use. | ||||
299 | # Force sort=off but allow initsort / initdirection | ||||
300 | 1 | 1µs | 1 | 1µs | my $context = Foswiki::Func::getContext(); # spent 1µs making 1 call to Foswiki::Func::getContext |
301 | 1 | 400ns | if ( $context->{static} ) { | ||
302 | delete $inCollection->{sortAllTables}; | ||||
303 | } | ||||
304 | |||||
305 | # If EditTablePlugin is installed and we are editing a table, | ||||
306 | # the CGI parameter 'sort' is defined as "off" to disable all | ||||
307 | # header sorting ((Item5135) | ||||
308 | 1 | 1µs | 1 | 4µs | my $cgi = Foswiki::Func::getCgiQuery(); # spent 4µs making 1 call to Foswiki::Func::getCgiQuery |
309 | 1 | 2µs | 1 | 18µs | my $urlParamSort = $cgi->param('sort'); # spent 18µs making 1 call to Foswiki::Request::param |
310 | 1 | 200ns | if ( $urlParamSort && $urlParamSort =~ /^off$/oi ) { | ||
311 | delete $inCollection->{sortAllTables}; | ||||
312 | } | ||||
313 | |||||
314 | # If EditTablePlugin is installed and we are editing a table, the | ||||
315 | # 'disableallsort' TABLE parameter is added to disable initsort and header | ||||
316 | # sorting in the table that is being edited. (Item5135) | ||||
317 | 1 | 3µs | 1 | 5µs | if ( Foswiki::Func::isTrue( $inParams->{disableallsort} ) ) { # spent 5µs making 1 call to Foswiki::Func::isTrue |
318 | $inCollection->{sortAllTables} = 0; | ||||
319 | delete $inCollection->{initSort}; | ||||
320 | } | ||||
321 | |||||
322 | 1 | 200ns | if ($isTableSpecific) { | ||
323 | |||||
324 | _storeAttribute( 'summary', $inParams->{summary}, $inCollection ); | ||||
325 | my $id = | ||||
326 | defined $inParams->{id} | ||||
327 | ? $inParams->{id} | ||||
328 | : 'table' | ||||
329 | . $Foswiki::Plugins::TablePlugin::topic | ||||
330 | . ( $tableCount + 1 ); | ||||
331 | _storeAttribute( 'id', $id, $inCollection ); | ||||
332 | _storeAttribute( 'headerrows', $inParams->{headerrows}, $inCollection ); | ||||
333 | _storeAttribute( 'footerrows', $inParams->{footerrows}, $inCollection ); | ||||
334 | } | ||||
335 | 1 | 1µs | 1 | 3µs | _storeAttribute( 'border', $inParams->{tableborder}, $inCollection ); # spent 3µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_storeAttribute |
336 | 1 | 2µs | 1 | 2µs | _storeAttribute( 'tableBorderColor', $inParams->{tablebordercolor}, # spent 2µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_storeAttribute |
337 | $inCollection ); | ||||
338 | 1 | 1µs | 1 | 2µs | _storeAttribute( 'cellpadding', $inParams->{cellpadding}, $inCollection ); # spent 2µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_storeAttribute |
339 | 1 | 1µs | 1 | 1µs | _storeAttribute( 'cellspacing', $inParams->{cellspacing}, $inCollection ); # spent 1µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_storeAttribute |
340 | 1 | 2µs | 1 | 2µs | _storeAttribute( 'frame', $inParams->{tableframe}, $inCollection ); # spent 2µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_storeAttribute |
341 | |||||
342 | # tablerules css settings | ||||
343 | 1 | 400ns | my @tableRulesList = (); | ||
344 | 1 | 500ns | if ( $inParams->{tablerules} ) { | ||
345 | |||||
346 | # store tablerules as array, so that headerrules and datarules | ||||
347 | # can be appended to that list | ||||
348 | 1 | 1µs | 1 | 2µs | my $param = _cleanParamValue( $inParams->{tablerules} ); # spent 2µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_cleanParamValue |
349 | 1 | 700ns | if ($param) { | ||
350 | push( @tableRulesList, $param ); | ||||
351 | } | ||||
352 | } | ||||
353 | 1 | 400ns | if ( $inParams->{headerrules} ) { | ||
354 | 1 | 1µs | 1 | 1µs | my $param = _cleanParamValue( $inParams->{headerrules} ); # spent 1µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_cleanParamValue |
355 | 1 | 300ns | if ($param) { | ||
356 | 1 | 600ns | $param = "header_$param"; | ||
357 | 1 | 400ns | push( @tableRulesList, $param ); | ||
358 | } | ||||
359 | } | ||||
360 | 1 | 300ns | if ( $inParams->{datarules} ) { | ||
361 | my $param = _cleanParamValue( $inParams->{datarules} ); | ||||
362 | if ($param) { | ||||
363 | $param = "data_$param"; | ||||
364 | push( @tableRulesList, $param ); | ||||
365 | } | ||||
366 | } | ||||
367 | 1 | 700ns | $inCollection->{tableRules} = \@tableRulesList if scalar(@tableRulesList); | ||
368 | |||||
369 | # use 'rules' as table attribute only (not to define css styles) | ||||
370 | # but set to | ||||
371 | 1 | 500ns | my $rules = | ||
372 | ( defined $inParams->{headerrules} || defined $inParams->{datarules} ) | ||||
373 | ? 'none' | ||||
374 | : $inParams->{tablerules}; | ||||
375 | 1 | 900ns | 1 | 3µs | _storeAttribute( 'rules', $rules, $inCollection ); # spent 3µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_storeAttribute |
376 | |||||
377 | 1 | 2µs | 1 | 2µs | _storeAttribute( 'width', $inParams->{tablewidth}, $inCollection ); # spent 2µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_storeAttribute |
378 | |||||
379 | # css attributes | ||||
380 | 1 | 1µs | 1 | 2µs | _storeAttribute( 'headerColor', $inParams->{headercolor}, $inCollection ); # spent 2µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_storeAttribute |
381 | 1 | 900ns | 1 | 2µs | _storeAttribute( 'headerBg', $inParams->{headerbg}, $inCollection ); # spent 2µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_storeAttribute |
382 | 1 | 1µs | 1 | 1µs | _storeAttribute( 'cellBorder', $inParams->{cellborder}, $inCollection ); # spent 1µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_storeAttribute |
383 | 1 | 2µs | 2 | 3µs | _storeAttribute( 'headerAlignListRef', # spent 2µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_arrayRefFromParam
# spent 1µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_storeAttribute |
384 | _arrayRefFromParam( $inParams->{headeralign} ), | ||||
385 | $inCollection ); | ||||
386 | 1 | 2µs | 2 | 3µs | _storeAttribute( 'dataAlignListRef', # spent 1µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_arrayRefFromParam
# spent 1µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_storeAttribute |
387 | _arrayRefFromParam( $inParams->{dataalign} ), | ||||
388 | $inCollection ); | ||||
389 | 1 | 2µs | 2 | 2µs | _storeAttribute( 'columnWidthsListRef', # spent 1µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_arrayRefFromParam
# spent 1µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_storeAttribute |
390 | _arrayRefFromParam( $inParams->{columnwidths} ), | ||||
391 | $inCollection ); | ||||
392 | 1 | 1µs | 1 | 2µs | _storeAttribute( 'vAlign', $inParams->{valign} || 'top', $inCollection ); # spent 2µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_storeAttribute |
393 | 1 | 2µs | 1 | 2µs | _storeAttribute( 'dataVAlign', $inParams->{datavalign}, $inCollection ); # spent 2µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_storeAttribute |
394 | 1 | 2µs | 1 | 2µs | _storeAttribute( 'headerVAlign', $inParams->{headervalign}, $inCollection ); # spent 2µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_storeAttribute |
395 | 1 | 1µs | 1 | 2µs | _storeAttribute( 'headerBgSorted', # spent 2µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_storeAttribute |
396 | $inParams->{headerbgsorted} || $inParams->{headerbg}, | ||||
397 | $inCollection ); | ||||
398 | 1 | 2µs | 2 | 6µs | _storeAttribute( 'dataBgListRef', _arrayRefFromParam( $inParams->{databg} ), # spent 4µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_arrayRefFromParam
# spent 2µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_storeAttribute |
399 | $inCollection ); | ||||
400 | 1 | 2µs | 2 | 5µs | _storeAttribute( # spent 3µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_arrayRefFromParam
# spent 2µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_storeAttribute |
401 | 'dataBgSortedListRef', | ||||
402 | _arrayRefFromParam( $inParams->{databgsorted} || $inParams->{databg} ), | ||||
403 | $inCollection | ||||
404 | ); | ||||
405 | 1 | 2µs | 2 | 3µs | _storeAttribute( 'dataColorListRef', # spent 2µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_arrayRefFromParam
# spent 1µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_storeAttribute |
406 | _arrayRefFromParam( $inParams->{datacolor} ), | ||||
407 | $inCollection ); | ||||
408 | 1 | 1µs | 1 | 1µs | _storeAttribute( 'tableCaption', $inParams->{caption}, $inCollection ); # spent 1µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_storeAttribute |
409 | |||||
410 | # remove empty attributes | ||||
411 | 1 | 19µs | while ( my ( $key, $value ) = each %{$inCollection} ) { | ||
412 | delete $inCollection->{$key} if !defined $value || $value eq ''; | ||||
413 | } | ||||
414 | |||||
415 | 1 | 6µs | 1 | 6µs | _debugData( '_parseAttributes result:', $inCollection ); # spent 6µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_debugData |
416 | } | ||||
417 | |||||
418 | =pod | ||||
419 | |||||
420 | _getIncludeParams( $includeTopic ) -> \%params | ||||
421 | |||||
422 | From $includeTopic read the first TABLE tag and return its parameters. | ||||
423 | |||||
424 | =cut | ||||
425 | |||||
426 | sub _getIncludeParams { | ||||
427 | my ($inIncludeTopic) = @_; | ||||
428 | |||||
429 | my ( $includeWeb, $includeTopic ) = | ||||
430 | Foswiki::Func::normalizeWebTopicName( $Foswiki::Plugins::TablePlugin::web, | ||||
431 | $inIncludeTopic ); | ||||
432 | |||||
433 | _debug("_getIncludeParams:$inIncludeTopic"); | ||||
434 | _debug("\t includeTopic=$includeTopic") if $includeTopic; | ||||
435 | |||||
436 | if ( !Foswiki::Func::topicExists( $includeWeb, $includeTopic ) ) { | ||||
437 | _debug("TablePlugin: included topic $inIncludeTopic does not exist."); | ||||
438 | return ( undef, | ||||
439 | '%MAKETEXT{"Warning: \'include\' topic <nop>[_1] does not exist!" args="' | ||||
440 | . "$includeWeb.$includeTopic" | ||||
441 | . '"}%' ); | ||||
442 | } | ||||
443 | else { | ||||
444 | |||||
445 | my $text = Foswiki::Func::readTopicText( $includeWeb, $includeTopic ); | ||||
446 | |||||
447 | if ( $text =~ m/$PATTERN_TABLE/s ) { | ||||
448 | _debug("\t PATTERN_TABLE=$PATTERN_TABLE; 1=$1"); | ||||
449 | my $paramString = $1; | ||||
450 | |||||
451 | if ( $includeWeb ne $Foswiki::Plugins::TablePlugin::web | ||||
452 | || $includeTopic ne $Foswiki::Plugins::TablePlugin::topic ) | ||||
453 | { | ||||
454 | |||||
455 | # expand common vars, except oneself to prevent recursion | ||||
456 | $paramString = | ||||
457 | Foswiki::Func::expandCommonVariables( $paramString, | ||||
458 | $includeTopic, $includeWeb ); | ||||
459 | } | ||||
460 | my %params = Foswiki::Func::extractParameters($paramString); | ||||
461 | return ( \%params, undef ); | ||||
462 | } | ||||
463 | else { | ||||
464 | return ( undef, | ||||
465 | '%MAKETEXT{"Warning: table definition in \'include\' topic [_1] does not exist!" args="' | ||||
466 | . "$includeWeb.$includeTopic" | ||||
467 | . '"}%' ); | ||||
468 | } | ||||
469 | } | ||||
470 | } | ||||
471 | |||||
472 | =pod | ||||
473 | |||||
474 | _convertStringToDate ( $text ) -> $number | ||||
475 | |||||
476 | Convert text to number if syntactically possible, otherwise return undef. | ||||
477 | Assumes that the text has been stripped from HTML markup. | ||||
478 | |||||
479 | =cut | ||||
480 | |||||
481 | sub _convertStringToDate { | ||||
482 | my ($text) = @_; | ||||
483 | |||||
484 | return undef if !defined $text; | ||||
485 | return undef if $text eq ''; | ||||
486 | return undef if ( $text =~ /^\s*$/ ); | ||||
487 | |||||
488 | my $date = undef; | ||||
489 | |||||
490 | if ( $text =~ /^\s*-?[0-9]+(\.[0-9])*\s*$/ ) { | ||||
491 | _debug("\t this is a number"); | ||||
492 | } | ||||
493 | else { | ||||
494 | try { | ||||
495 | $date = Foswiki::Time::parseTime($text); | ||||
496 | _debug("\t is a date"); | ||||
497 | } | ||||
498 | catch Error::Simple with { | ||||
499 | |||||
500 | # nope, wasn't a date | ||||
501 | _debug("\t $text is not a date"); | ||||
502 | }; | ||||
503 | } | ||||
504 | |||||
505 | return $date; | ||||
506 | } | ||||
507 | |||||
508 | =pod | ||||
509 | |||||
510 | _convertStringToNumber ( $text ) -> $number | ||||
511 | |||||
512 | Convert text to number if syntactically possible, otherwise return undef. | ||||
513 | Assumes that the text has been stripped from HTML markup. | ||||
514 | |||||
515 | =cut | ||||
516 | |||||
517 | sub _convertStringToNumber { | ||||
518 | my ($text) = @_; | ||||
519 | |||||
520 | return undef if !defined $text; | ||||
521 | return undef if $text eq ''; | ||||
522 | return undef if ( $text =~ /^\s*$/ ); | ||||
523 | |||||
524 | # very course testing on IP (could in fact be anything with n.n. syntax | ||||
525 | if ( | ||||
526 | $text =~ m/ | ||||
527 | ^ | ||||
528 | \s* # any space | ||||
529 | (?: # don't need to capture | ||||
530 | [0-9]+ # digits | ||||
531 | \. # dot | ||||
532 | ) # | ||||
533 | {2,} # repeat more than once: exclude decimal numbers | ||||
534 | .*? # any string | ||||
535 | $ | ||||
536 | /x | ||||
537 | ) | ||||
538 | { | ||||
539 | _debug("\t $text looks like an IP address, or something similar"); | ||||
540 | |||||
541 | # should be sorted by text | ||||
542 | return undef; | ||||
543 | } | ||||
544 | |||||
545 | if ( | ||||
546 | $text =~ m/ | ||||
547 | ^ | ||||
548 | \s* # any space | ||||
549 | ( # | ||||
550 | -* # possible minus | ||||
551 | [0-9]+ # digits | ||||
552 | \.* # possible decimal | ||||
553 | [0-9]* # possible fracture digits | ||||
554 | ) # end capture of number | ||||
555 | .*$ # any string | ||||
556 | /x | ||||
557 | ) | ||||
558 | { | ||||
559 | |||||
560 | _debug("\t $1 is a number"); | ||||
561 | |||||
562 | # make sure to return a number, not a string | ||||
563 | return $1 * 1.0; | ||||
564 | } | ||||
565 | return undef; | ||||
566 | } | ||||
567 | |||||
568 | sub _processTableRow { | ||||
569 | my ( $thePre, $theRow ) = @_; | ||||
570 | |||||
571 | $currTablePre = $thePre || ''; | ||||
572 | my $span = 0; | ||||
573 | my $l1 = 0; | ||||
574 | my $l2 = 0; | ||||
575 | |||||
576 | if ( !$insideTABLE ) { | ||||
577 | @curTable = (); | ||||
578 | @rowspan = (); | ||||
579 | |||||
580 | $tableCount++; | ||||
581 | $currentSortDirection = $SORT_DIRECTION->{'NONE'}; | ||||
582 | |||||
583 | if ( defined $requestedTable | ||||
584 | && $requestedTable == $tableCount | ||||
585 | && defined $sortColFromUrl ) | ||||
586 | { | ||||
587 | $sortCol = $sortColFromUrl; | ||||
588 | $sortCol = 0 unless ( $sortCol =~ m/^[0-9]+$/ ); | ||||
589 | $sortCol = $MAX_SORT_COLS if ( $sortCol > $MAX_SORT_COLS ); | ||||
590 | $currentSortDirection = _getCurrentSortDirection($up); | ||||
591 | } | ||||
592 | elsif ( defined $combinedTableAttrs->{initSort} ) { | ||||
593 | $sortCol = $combinedTableAttrs->{initSort} - 1; | ||||
594 | $sortCol = $MAX_SORT_COLS if ( $sortCol > $MAX_SORT_COLS ); | ||||
595 | $currentSortDirection = | ||||
596 | _getCurrentSortDirection( $combinedTableAttrs->{initDirection} ); | ||||
597 | } | ||||
598 | } | ||||
599 | |||||
600 | $theRow =~ s/\t/ /go; # change tabs to space | ||||
601 | $theRow =~ s/\s*$//o; # remove trailing spaces | ||||
602 | $theRow =~ | ||||
603 | s/(\|\|+)/'colspan'.$translationToken.length($1)."\|"/geo; # calc COLSPAN | ||||
604 | my $colCount = 0; | ||||
605 | my @row = (); | ||||
606 | $span = 0; | ||||
607 | my $value = ''; | ||||
608 | |||||
609 | foreach ( split( /\|/, $theRow ) ) { | ||||
610 | my $attr = {}; | ||||
611 | $span = 1; | ||||
612 | |||||
613 | # Item13309: adjust for ERP empty column | ||||
614 | if ( !$tableSpecificAttrs->{sort_adjusted} | ||||
615 | && $colCount == 0 | ||||
616 | && /erpJS_willDiscard/ ) | ||||
617 | { | ||||
618 | if ( $combinedTableAttrs->{initSort} ) { | ||||
619 | $combinedTableAttrs->{initSort}++; | ||||
620 | $sortCol++; | ||||
621 | } | ||||
622 | |||||
623 | $tableSpecificAttrs->{sort_adjusted} = 1; | ||||
624 | } | ||||
625 | |||||
626 | #AS 25-5-01 Fix to avoid matching also single columns | ||||
627 | if (s/colspan$translationToken([0-9]+)//) { | ||||
628 | $span = $1; | ||||
629 | $attr->{colspan} = $span; | ||||
630 | } | ||||
631 | s/^\s+$/ /o; | ||||
632 | ( $l1, $l2 ) = ( 0, 0 ); | ||||
633 | if (/^(\s*).*?(\s*)$/) { | ||||
634 | $l1 = length($1); | ||||
635 | $l2 = length($2); | ||||
636 | } | ||||
637 | if ( $l1 >= 2 ) { | ||||
638 | if ( $l2 <= 1 ) { | ||||
639 | $attr->{style} = 'text-align:right'; | ||||
640 | } | ||||
641 | else { | ||||
642 | $attr->{style} = 'text-align:center'; | ||||
643 | } | ||||
644 | } | ||||
645 | if ( $span <= 2 ) { | ||||
646 | $attr->{class} = | ||||
647 | _appendColNumberCssClass( $attr->{class}, $colCount ); | ||||
648 | } | ||||
649 | |||||
650 | # html attribute: (column) width | ||||
651 | if ( $combinedTableAttrs->{generateInlineMarkup} | ||||
652 | && defined $combinedTableAttrs->{columnWidthsListRef} ) | ||||
653 | { | ||||
654 | my @columnWidths = @{ $combinedTableAttrs->{columnWidthsListRef} }; | ||||
655 | if ( defined $columnWidths[$colCount] | ||||
656 | && $columnWidths[$colCount] | ||||
657 | && $span <= 2 ) | ||||
658 | { | ||||
659 | $attr->{width} = $columnWidths[$colCount]; | ||||
660 | } | ||||
661 | } | ||||
662 | |||||
663 | # END html attribute | ||||
664 | |||||
665 | if (/^(\s|<[^>]*>)*\^(\s|<[^>]*>)*$/) { # row span above | ||||
666 | $rowspan[$colCount]++; | ||||
667 | push @row, { text => $value, type => 'Y' }; | ||||
668 | } | ||||
669 | else { | ||||
670 | for ( my $col = $colCount ; $col < ( $colCount + $span ) ; $col++ ) | ||||
671 | { | ||||
672 | if ( defined( $rowspan[$col] ) && $rowspan[$col] ) { | ||||
673 | my $nRows = scalar(@curTable); | ||||
674 | my $rspan = $rowspan[$col] + 1; | ||||
675 | if ( $rspan > 1 ) { | ||||
676 | $curTable[ $nRows - $rspan ][$col]->{attrs}->{rowspan} = | ||||
677 | $rspan; | ||||
678 | } | ||||
679 | undef( $rowspan[$col] ); | ||||
680 | } | ||||
681 | } | ||||
682 | |||||
683 | if ( | ||||
684 | ( | ||||
685 | ( | ||||
686 | defined $requestedTable | ||||
687 | && $requestedTable == $tableCount | ||||
688 | ) | ||||
689 | || defined $combinedTableAttrs->{initSort} | ||||
690 | ) | ||||
691 | && defined $sortCol | ||||
692 | && $colCount == $sortCol | ||||
693 | ) | ||||
694 | { | ||||
695 | |||||
696 | # CSS class name | ||||
697 | if ( $currentSortDirection == $SORT_DIRECTION->{'ASCENDING'} ) { | ||||
698 | $attr->{class} = | ||||
699 | _appendSortedAscendingCssClass( $attr->{class} ); | ||||
700 | } | ||||
701 | if ( $currentSortDirection == $SORT_DIRECTION->{'DESCENDING'} ) | ||||
702 | { | ||||
703 | $attr->{class} = | ||||
704 | _appendSortedDescendingCssClass( $attr->{class} ); | ||||
705 | } | ||||
706 | } | ||||
707 | my $type = ''; | ||||
708 | |||||
709 | # Fixup for EditRowPlugin - add ** if erpJS_sort | ||||
710 | s/(.*)/*$1*/ if /erpJS_sort \{headrows: \d/; | ||||
711 | |||||
712 | if (/^\s*\*(.*)\*\s*$/) { | ||||
713 | $value = $1; | ||||
714 | $type = 'th'; | ||||
715 | |||||
716 | # html attribute: align | ||||
717 | if ( $combinedTableAttrs->{generateInlineMarkup} | ||||
718 | && defined $combinedTableAttrs->{headerAlignListRef} ) | ||||
719 | { | ||||
720 | my @headerAlign = | ||||
721 | @{ $combinedTableAttrs->{headerAlignListRef} }; | ||||
722 | if (@headerAlign) { | ||||
723 | my $align = | ||||
724 | @headerAlign[ $colCount % ( $#headerAlign + 1 ) ]; | ||||
725 | $attr->{style} = "text-align:$align"; | ||||
726 | } | ||||
727 | } | ||||
728 | |||||
729 | # END html attribute | ||||
730 | |||||
731 | # html attribute: valign | ||||
732 | if ( $combinedTableAttrs->{generateInlineMarkup} ) { | ||||
733 | if ( defined $combinedTableAttrs->{headerVAlign} ) { | ||||
734 | $attr->{valign} = $combinedTableAttrs->{headerVAlign}; | ||||
735 | } | ||||
736 | elsif ( defined $combinedTableAttrs->{vAlign} ) { | ||||
737 | $attr->{valign} = $combinedTableAttrs->{vAlign}; | ||||
738 | } | ||||
739 | } | ||||
740 | |||||
741 | # END html attribute | ||||
742 | } | ||||
743 | else { | ||||
744 | if (/^\s*(.*?)\s*$/) { # strip white spaces | ||||
745 | $_ = $1; | ||||
746 | } | ||||
747 | $value = $_; | ||||
748 | $type = 'td'; | ||||
749 | |||||
750 | # html attribute: align | ||||
751 | if ( $combinedTableAttrs->{generateInlineMarkup} | ||||
752 | && defined $combinedTableAttrs->{dataAlignListRef} ) | ||||
753 | { | ||||
754 | my @dataAlign = | ||||
755 | @{ $combinedTableAttrs->{dataAlignListRef} }; | ||||
756 | if (@dataAlign) { | ||||
757 | my $align = | ||||
758 | @dataAlign[ $colCount % ( $#dataAlign + 1 ) ]; | ||||
759 | $attr->{style} = "text-align:$align"; | ||||
760 | } | ||||
761 | } | ||||
762 | |||||
763 | # END html attribute | ||||
764 | |||||
765 | # html attribute: valign | ||||
766 | if ( $combinedTableAttrs->{generateInlineMarkup} ) { | ||||
767 | if ( defined $combinedTableAttrs->{dataVAlign} ) { | ||||
768 | $attr->{valign} = $combinedTableAttrs->{dataVAlign}; | ||||
769 | } | ||||
770 | elsif ( defined $combinedTableAttrs->{vAlign} ) { | ||||
771 | $attr->{valign} = $combinedTableAttrs->{vAlign}; | ||||
772 | } | ||||
773 | } | ||||
774 | |||||
775 | # END html attribute | ||||
776 | } | ||||
777 | |||||
778 | push @row, { text => $value, attrs => $attr, type => $type }; | ||||
779 | } | ||||
780 | while ( $span > 1 ) { | ||||
781 | push @row, { text => $value, type => 'X' }; | ||||
782 | $colCount++; | ||||
783 | $span--; | ||||
784 | } | ||||
785 | $colCount++; | ||||
786 | } | ||||
787 | push @curTable, \@row; | ||||
788 | return $currTablePre | ||||
789 | . '<nop>'; # Avoid Foswiki converting empty lines to new paras | ||||
790 | } | ||||
791 | |||||
792 | sub _headerRowCount { | ||||
793 | my ($table) = @_; | ||||
794 | |||||
795 | my $headerCount = 0; | ||||
796 | my $footerCount = 0; | ||||
797 | my $endheader = 0; | ||||
798 | |||||
799 | # All cells in header are headings? | ||||
800 | foreach my $row (@$table) { | ||||
801 | my $isHeader = 1; | ||||
802 | foreach my $cell (@$row) { | ||||
803 | if ( $cell->{type} ne 'th' ) { | ||||
804 | $isHeader = 0; | ||||
805 | $endheader = 1; | ||||
806 | $footerCount = 0 if $footerCount; | ||||
807 | } | ||||
808 | } | ||||
809 | unless ($endheader) { | ||||
810 | $headerCount++ if $isHeader; | ||||
811 | } | ||||
812 | else { | ||||
813 | $footerCount++ if $isHeader; | ||||
814 | } | ||||
815 | } | ||||
816 | |||||
817 | # Some cells came after the footer - so there isn't one. | ||||
818 | $footerCount = 0 if ( $endheader > 1 ); | ||||
819 | |||||
820 | return ( $headerCount, $footerCount ); | ||||
821 | } | ||||
822 | |||||
823 | =pod | ||||
824 | |||||
825 | _setSortTypeForCells ( $col, \@table ) | ||||
826 | |||||
827 | Sets a sort key for each cell. | ||||
828 | |||||
829 | =cut | ||||
830 | |||||
831 | sub _setSortTypeForCells { | ||||
832 | my ( $col, $table ) = @_; | ||||
833 | |||||
834 | foreach my $row ( @{$table} ) { | ||||
835 | |||||
836 | my $rowText = _stripHtml( $row->[$col]->{text} ); | ||||
837 | |||||
838 | my $num = _convertStringToNumber($rowText); | ||||
839 | my $date = _convertStringToDate($rowText); | ||||
840 | |||||
841 | $row->[$col]->{sortText} = ''; | ||||
842 | $row->[$col]->{number} = 0; | ||||
843 | $row->[$col]->{dateString} = ''; | ||||
844 | |||||
845 | if ( defined $date ) { | ||||
846 | |||||
847 | # date has just converted to a number | ||||
848 | $row->[$col]->{number} = $date; | ||||
849 | |||||
850 | # add dateString value in case dates are equal | ||||
851 | $row->[$col]->{dateString} = $rowText; | ||||
852 | } | ||||
853 | elsif ( defined $num ) { | ||||
854 | $row->[$col]->{number} = $num; | ||||
855 | |||||
856 | # when sorting mixed numbers and text, make the text sort value as low as possible | ||||
857 | $row->[$col]->{sortText} = ' '; | ||||
858 | } | ||||
859 | else { | ||||
860 | $row->[$col]->{sortText} = lc $rowText; | ||||
861 | } | ||||
862 | |||||
863 | } | ||||
864 | } | ||||
865 | |||||
866 | # Remove HTML from text so it can be sorted | ||||
867 | sub _stripHtml { | ||||
868 | my ($text) = @_; | ||||
869 | |||||
870 | return undef if !defined $text; | ||||
871 | $text =~ | ||||
872 | s/\[\[[^\]]+\]\[([^\]]+)\]\]/$1/go; # extract label from [[...][...]] link | ||||
873 | |||||
874 | my $orgtext = | ||||
875 | $text; # in case we will have removed all contents with stripping html | ||||
876 | $text =~ s/<[^>]+>//go; # strip HTML | ||||
877 | $text =~ s/\ / /go; | ||||
878 | $text = _getImageTextForSorting($orgtext) if ( $text eq '' ); | ||||
879 | $text =~ s/[\[\]\*\|=_\&\<\>]/ /g; # remove Wiki formatting chars | ||||
880 | $text =~ s/^ *//go; # strip leading space space | ||||
881 | |||||
882 | return $text; | ||||
883 | } | ||||
884 | |||||
885 | =pod | ||||
886 | |||||
887 | Retrieve text data from an image html tag to be used for sorting. | ||||
888 | First try the alt tag string. If not available, return the url string. | ||||
889 | If not available, return the original string. | ||||
890 | |||||
891 | =cut | ||||
892 | |||||
893 | sub _getImageTextForSorting { | ||||
894 | my ($text) = @_; | ||||
895 | |||||
896 | # try to see _if_ there is any img data for sorting | ||||
897 | my $hasImageTag = ( $text =~ m/\<\s*img([^>]+)>/ ); | ||||
898 | return $text if ( !$hasImageTag ); | ||||
899 | |||||
900 | # first try to get the alt text | ||||
901 | my $key = 'alt'; | ||||
902 | $text =~ m/$key=\s*[\"\']([^\"\']*)/; | ||||
903 | return $1 if ( $1 ne '' ); | ||||
904 | |||||
905 | # else | ||||
906 | |||||
907 | # no alt text; use the url | ||||
908 | $key = 'url'; | ||||
909 | $text =~ m/$key=\s*[\"\']([^\"\']*)/; | ||||
910 | return $1 if ( $1 ne '' ); | ||||
911 | |||||
912 | # else | ||||
913 | |||||
914 | return $text; | ||||
915 | } | ||||
916 | |||||
917 | =pod | ||||
918 | |||||
919 | Appends $className to $classList, separated by a space. | ||||
920 | |||||
921 | =cut | ||||
922 | |||||
923 | sub _appendToClassList { | ||||
924 | my ( $classList, $className ) = @_; | ||||
925 | $classList = $classList ? $classList .= ' ' : ''; | ||||
926 | $classList .= $className; | ||||
927 | return $classList; | ||||
928 | } | ||||
929 | |||||
930 | sub _appendSortedCssClass { | ||||
931 | my ($classList) = @_; | ||||
932 | |||||
933 | return _appendToClassList( $classList, 'foswikiSortedCol' ); | ||||
934 | } | ||||
935 | |||||
936 | sub _appendRowNumberCssClass { | ||||
937 | my ( $classList, $colListName, $rowNum ) = @_; | ||||
938 | |||||
939 | my $rowClassName = 'foswikiTableRow' . $colListName . $rowNum; | ||||
940 | return _appendToClassList( $classList, $rowClassName ); | ||||
941 | } | ||||
942 | |||||
943 | sub _appendColNumberCssClass { | ||||
944 | my ( $classList, $colNum ) = @_; | ||||
945 | |||||
946 | my $colClassName = 'foswikiTableCol' . $colNum; | ||||
947 | return _appendToClassList( $classList, $colClassName ); | ||||
948 | } | ||||
949 | |||||
950 | sub _appendFirstColumnCssClass { | ||||
951 | my ($classList) = @_; | ||||
952 | |||||
953 | return _appendToClassList( $classList, 'foswikiFirstCol' ); | ||||
954 | } | ||||
955 | |||||
956 | sub _appendLastColumnCssClass { | ||||
957 | my ($classList) = @_; | ||||
958 | |||||
959 | return _appendToClassList( $classList, 'foswikiLastCol' ); | ||||
960 | } | ||||
961 | |||||
962 | sub _appendLastRowCssClass { | ||||
963 | my ($classList) = @_; | ||||
964 | |||||
965 | return _appendToClassList( $classList, 'foswikiLast' ); | ||||
966 | } | ||||
967 | |||||
968 | sub _appendSortedAscendingCssClass { | ||||
969 | my ($classList) = @_; | ||||
970 | |||||
971 | return _appendToClassList( $classList, 'foswikiSortedAscendingCol' ); | ||||
972 | } | ||||
973 | |||||
974 | sub _appendSortedDescendingCssClass { | ||||
975 | my ($classList) = @_; | ||||
976 | |||||
977 | return _appendToClassList( $classList, 'foswikiSortedDescendingCol' ); | ||||
978 | } | ||||
979 | |||||
980 | # The default sort direction. | ||||
981 | sub _getDefaultSortDirection { | ||||
982 | return $SORT_DIRECTION->{'ASCENDING'}; | ||||
983 | } | ||||
984 | |||||
985 | # Gets the current sort direction. | ||||
986 | sub _getCurrentSortDirection { | ||||
987 | my ($currentDirection) = @_; | ||||
988 | $currentDirection = $SORT_DIRECTION->{'ASCENDING'} | ||||
989 | unless defined $currentDirection && $currentDirection =~ m/[0-2]+/; | ||||
990 | $currentDirection ||= _getDefaultSortDirection(); | ||||
991 | return $currentDirection; | ||||
992 | } | ||||
993 | |||||
994 | # Gets the new sort direction (needed for sort button) based on the current sort | ||||
995 | # direction. | ||||
996 | sub _getNewSortDirection { | ||||
997 | my ($currentDirection) = @_; | ||||
998 | if ( !defined $currentDirection ) { | ||||
999 | return _getDefaultSortDirection(); | ||||
1000 | } | ||||
1001 | my $newDirection; | ||||
1002 | if ( $currentDirection == $SORT_DIRECTION->{'ASCENDING'} ) { | ||||
1003 | $newDirection = $SORT_DIRECTION->{'DESCENDING'}; | ||||
1004 | } | ||||
1005 | elsif ( $currentDirection == $SORT_DIRECTION->{'DESCENDING'} ) { | ||||
1006 | $newDirection = $SORT_DIRECTION->{'NONE'}; | ||||
1007 | } | ||||
1008 | elsif ( $currentDirection == $SORT_DIRECTION->{'NONE'} ) { | ||||
1009 | $newDirection = $SORT_DIRECTION->{'ASCENDING'}; | ||||
1010 | } | ||||
1011 | else { | ||||
1012 | $newDirection = _getDefaultSortDirection(); | ||||
1013 | } | ||||
1014 | |||||
1015 | return $newDirection; | ||||
1016 | } | ||||
1017 | |||||
1018 | =pod | ||||
1019 | |||||
1020 | _createCssStyles( $writeDefaults, $inAttrs ) -> ($id, @styles) | ||||
1021 | |||||
1022 | Explicitly set styles override html styling (in this file marked with comment '# html attribute'). | ||||
1023 | |||||
1024 | =cut | ||||
1025 | |||||
1026 | sub _createCssStyles { | ||||
1027 | my ( $writeDefaults, $inAttrs ) = @_; | ||||
1028 | |||||
1029 | _debug("_createCssStyles; writeDefaults=$writeDefaults"); | ||||
1030 | |||||
1031 | my $_styles = {}; | ||||
1032 | my $setAttribute = sub { | ||||
1033 | my ( $tableSelector, $type, $rule ) = @_; | ||||
1034 | |||||
1035 | return if !$rule; | ||||
1036 | $type ||= '#'; # for table selector only, if no type | ||||
1037 | my $storedType = $_styles->{$tableSelector}->{$type} || ''; | ||||
1038 | if ( !defined $storedType ) { | ||||
1039 | @{ $_styles->{$tableSelector}->{$type} } = (); | ||||
1040 | } | ||||
1041 | if ( $rule ne $storedType ) { | ||||
1042 | push @{ $_styles->{$tableSelector}->{$type} }, $rule; | ||||
1043 | } | ||||
1044 | }; | ||||
1045 | |||||
1046 | if ( $writeDefaults && !$didWriteDefaultStyle ) { | ||||
1047 | my $tableSelector = '.foswikiTable'; | ||||
1048 | my $attr = 'padding-left:.3em; vertical-align:text-bottom'; | ||||
1049 | &$setAttribute( $tableSelector, '.tableSortIcon img', $attr ); | ||||
1050 | |||||
1051 | if ( $inAttrs->{cellpadding} ) { | ||||
1052 | my $attr = | ||||
1053 | 'padding:' . addDefaultSizeUnit( $inAttrs->{cellpadding} ); | ||||
1054 | &$setAttribute( $tableSelector, 'td', $attr ); | ||||
1055 | &$setAttribute( $tableSelector, 'th', $attr ); | ||||
1056 | } | ||||
1057 | } | ||||
1058 | |||||
1059 | my $tableSelector; | ||||
1060 | my $id; | ||||
1061 | if ($writeDefaults) { | ||||
1062 | $id = 'default'; | ||||
1063 | $tableSelector = ".foswikiTable"; | ||||
1064 | } | ||||
1065 | else { | ||||
1066 | $id = $inAttrs->{id}; | ||||
1067 | $tableSelector = ".foswikiTable#$id"; | ||||
1068 | } | ||||
1069 | |||||
1070 | # tablerules | ||||
1071 | if ( $inAttrs->{tableRules} ) { | ||||
1072 | my @rules = @{ $inAttrs->{tableRules} }; | ||||
1073 | |||||
1074 | my $attr_td; | ||||
1075 | my $attr_th; | ||||
1076 | foreach my $rule (@rules) { | ||||
1077 | $attr_td = $TABLE_RULES->{$rule}->{TD} | ||||
1078 | if $TABLE_RULES->{$rule}->{TD}; | ||||
1079 | $attr_th = $TABLE_RULES->{$rule}->{TH} | ||||
1080 | if $TABLE_RULES->{$rule}->{TH}; | ||||
1081 | } | ||||
1082 | &$setAttribute( $tableSelector, 'th', $attr_th ); | ||||
1083 | &$setAttribute( $tableSelector, 'td', $attr_td ); | ||||
1084 | } | ||||
1085 | |||||
1086 | # tableframe | ||||
1087 | if ( $inAttrs->{frame} ) { | ||||
1088 | my $attr = $TABLE_FRAME->{ $inAttrs->{frame} }; | ||||
1089 | &$setAttribute( $tableSelector, '', $attr ); | ||||
1090 | } | ||||
1091 | |||||
1092 | # tableborder | ||||
1093 | if ( defined $inAttrs->{border} ) { | ||||
1094 | my $tableBorderWidth = $inAttrs->{border} || 0; | ||||
1095 | my $attr = 'border-width:' . addDefaultSizeUnit($tableBorderWidth); | ||||
1096 | &$setAttribute( $tableSelector, '', $attr ); | ||||
1097 | } | ||||
1098 | |||||
1099 | # tableBorderColor | ||||
1100 | if ( defined $inAttrs->{tableBorderColor} ) { | ||||
1101 | my $attr; | ||||
1102 | $attr = 'border-color:' . $inAttrs->{tableBorderColor}; | ||||
1103 | &$setAttribute( $tableSelector, '', $attr ); | ||||
1104 | $attr = 'border-top-color:' . $inAttrs->{tableBorderColor}; | ||||
1105 | &$setAttribute( $tableSelector, '', $attr ); | ||||
1106 | $attr = 'border-bottom-color:' . $inAttrs->{tableBorderColor}; | ||||
1107 | &$setAttribute( $tableSelector, '', $attr ); | ||||
1108 | $attr = 'border-left-color:' . $inAttrs->{tableBorderColor}; | ||||
1109 | &$setAttribute( $tableSelector, '', $attr ); | ||||
1110 | $attr = 'border-right-color:' . $inAttrs->{tableBorderColor}; | ||||
1111 | &$setAttribute( $tableSelector, '', $attr ); | ||||
1112 | } | ||||
1113 | |||||
1114 | # cellSpacing | ||||
1115 | if ( defined $inAttrs->{cellspacing} ) { | ||||
1116 | |||||
1117 | # do not use border-collapse:collapse | ||||
1118 | my $attr = 'border-collapse:separate'; | ||||
1119 | &$setAttribute( $tableSelector, '', $attr ); | ||||
1120 | } | ||||
1121 | |||||
1122 | # cellpadding | ||||
1123 | if ( defined $inAttrs->{cellpadding} ) { | ||||
1124 | my $attr = 'padding:' . addDefaultSizeUnit( $inAttrs->{cellpadding} ); | ||||
1125 | &$setAttribute( $tableSelector, 'td', $attr ); | ||||
1126 | &$setAttribute( $tableSelector, 'th', $attr ); | ||||
1127 | } | ||||
1128 | |||||
1129 | # cellborder | ||||
1130 | if ( defined $inAttrs->{cellBorder} ) { | ||||
1131 | my $cellBorderWidth = $inAttrs->{cellBorder} || 0; | ||||
1132 | my $attr = 'border-width:' . addDefaultSizeUnit($cellBorderWidth); | ||||
1133 | &$setAttribute( $tableSelector, 'td', $attr ); | ||||
1134 | &$setAttribute( $tableSelector, 'th', $attr ); | ||||
1135 | } | ||||
1136 | |||||
1137 | # tablewidth | ||||
1138 | if ( defined $inAttrs->{width} ) { | ||||
1139 | my $width = addDefaultSizeUnit( $inAttrs->{width} ); | ||||
1140 | my $attr = 'width:' . $width; | ||||
1141 | &$setAttribute( $tableSelector, '', $attr ); | ||||
1142 | } | ||||
1143 | |||||
1144 | # valign | ||||
1145 | if ( defined $inAttrs->{vAlign} ) { | ||||
1146 | my $attr = 'vertical-align:' . $inAttrs->{vAlign}; | ||||
1147 | &$setAttribute( $tableSelector, 'td', $attr ); | ||||
1148 | &$setAttribute( $tableSelector, 'th', $attr ); | ||||
1149 | } | ||||
1150 | |||||
1151 | # headerVAlign | ||||
1152 | if ( defined $inAttrs->{headerVAlign} ) { | ||||
1153 | my $attr = 'vertical-align:' . $inAttrs->{headerVAlign}; | ||||
1154 | &$setAttribute( $tableSelector, 'th', $attr ); | ||||
1155 | } | ||||
1156 | |||||
1157 | # dataVAlign | ||||
1158 | if ( defined $inAttrs->{dataVAlign} ) { | ||||
1159 | my $attr = 'vertical-align:' . $inAttrs->{dataVAlign}; | ||||
1160 | &$setAttribute( $tableSelector, 'td', $attr ); | ||||
1161 | } | ||||
1162 | |||||
1163 | # headerbg | ||||
1164 | if ( defined $inAttrs->{headerBg} ) { | ||||
1165 | my $color = | ||||
1166 | ( $inAttrs->{headerBg} =~ /none/i ) | ||||
1167 | ? 'transparent' | ||||
1168 | : $inAttrs->{headerBg}; | ||||
1169 | my $attr = 'background-color:' . $color; | ||||
1170 | &$setAttribute( $tableSelector, 'th', $attr ); | ||||
1171 | } | ||||
1172 | |||||
1173 | # headerbgsorted | ||||
1174 | if ( defined $inAttrs->{headerBgSorted} ) { | ||||
1175 | my $color = | ||||
1176 | ( $inAttrs->{headerBgSorted} =~ /none/i ) | ||||
1177 | ? 'transparent' | ||||
1178 | : $inAttrs->{headerBgSorted}; | ||||
1179 | my $attr = 'background-color:' . $color; | ||||
1180 | &$setAttribute( $tableSelector, 'th.foswikiSortedCol', $attr ); | ||||
1181 | } | ||||
1182 | |||||
1183 | # headercolor | ||||
1184 | if ( defined $inAttrs->{headerColor} ) { | ||||
1185 | my $attr = 'color:' . $inAttrs->{headerColor}; | ||||
1186 | &$setAttribute( $tableSelector, 'th', $attr ); | ||||
1187 | &$setAttribute( $tableSelector, 'th a:link', $attr ); | ||||
1188 | &$setAttribute( $tableSelector, 'th a:visited', $attr ); | ||||
1189 | &$setAttribute( $tableSelector, 'th a:xhover', $attr ) | ||||
1190 | ; # just to make sorting work: hover should be last. below we will remove the x again. | ||||
1191 | if ( defined $inAttrs->{headerBg} ) { | ||||
1192 | my $hoverBackgroundColor = $inAttrs->{headerBg}; | ||||
1193 | $attr = 'background-color:' . $hoverBackgroundColor; | ||||
1194 | &$setAttribute( $tableSelector, 'th a:xhover', $attr ); | ||||
1195 | } | ||||
1196 | } | ||||
1197 | |||||
1198 | # databg (array) | ||||
1199 | if ( defined $inAttrs->{dataBgListRef} ) { | ||||
1200 | my @dataBg = @{ $inAttrs->{dataBgListRef} }; | ||||
1201 | my $noneColor = ( $dataBg[0] =~ /none/i ) ? 'transparent' : ''; | ||||
1202 | my $count = 0; | ||||
1203 | foreach my $color (@dataBg) { | ||||
1204 | $color = $noneColor if $noneColor; | ||||
1205 | next if !$color; | ||||
1206 | my $rowSelector = 'foswikiTableRow' . 'dataBg' . $count; | ||||
1207 | my $attr = "background-color:$color"; | ||||
1208 | &$setAttribute( $tableSelector, "tr.$rowSelector td", $attr ); | ||||
1209 | $count++; | ||||
1210 | } | ||||
1211 | } | ||||
1212 | |||||
1213 | # databgsorted (array) | ||||
1214 | if ( defined $inAttrs->{dataBgSortedListRef} ) { | ||||
1215 | my @dataBgSorted = @{ $inAttrs->{dataBgSortedListRef} }; | ||||
1216 | my $noneColor = ( $dataBgSorted[0] =~ /none/i ) ? 'transparent' : ''; | ||||
1217 | my $count = 0; | ||||
1218 | foreach my $color (@dataBgSorted) { | ||||
1219 | $color = $noneColor if $noneColor; | ||||
1220 | next if !$color; | ||||
1221 | my $rowSelector = 'foswikiTableRow' . 'dataBg' . $count; | ||||
1222 | my $attr = "background-color:$color"; | ||||
1223 | &$setAttribute( $tableSelector, | ||||
1224 | "tr.$rowSelector td.foswikiSortedCol", $attr ); | ||||
1225 | $count++; | ||||
1226 | } | ||||
1227 | } | ||||
1228 | |||||
1229 | # datacolor (array) | ||||
1230 | if ( defined $inAttrs->{dataColorListRef} ) { | ||||
1231 | my @dataColor = @{ $inAttrs->{dataColorListRef} }; | ||||
1232 | unless ( $dataColor[0] =~ /none/i ) { | ||||
1233 | my $count = 0; | ||||
1234 | foreach my $color (@dataColor) { | ||||
1235 | next if !$color; | ||||
1236 | my $rowSelector = 'foswikiTableRow' . 'dataColor' . $count; | ||||
1237 | my $attr = "color:$color"; | ||||
1238 | &$setAttribute( $tableSelector, "tr.$rowSelector td", $attr ); | ||||
1239 | $count++; | ||||
1240 | } | ||||
1241 | } | ||||
1242 | } | ||||
1243 | |||||
1244 | # columnwidths | ||||
1245 | if ( defined $inAttrs->{columnWidthsListRef} ) { | ||||
1246 | my @columnWidths = @{ $inAttrs->{columnWidthsListRef} }; | ||||
1247 | my $count = 0; | ||||
1248 | foreach my $width (@columnWidths) { | ||||
1249 | next if !$width; | ||||
1250 | $width = addDefaultSizeUnit($width); | ||||
1251 | my $colSelector = 'foswikiTableCol'; | ||||
1252 | $colSelector .= $count; | ||||
1253 | my $attr = 'width:' . $width; | ||||
1254 | &$setAttribute( $tableSelector, "td.$colSelector", $attr ); | ||||
1255 | &$setAttribute( $tableSelector, "th.$colSelector", $attr ); | ||||
1256 | $count++; | ||||
1257 | } | ||||
1258 | } | ||||
1259 | |||||
1260 | # headeralign | ||||
1261 | if ( defined $inAttrs->{headerAlignListRef} ) { | ||||
1262 | my @headerAlign = @{ $inAttrs->{headerAlignListRef} }; | ||||
1263 | if ( scalar(@headerAlign) == 1 ) { | ||||
1264 | my $align = $headerAlign[0]; | ||||
1265 | my $attr = 'text-align:' . $align; | ||||
1266 | &$setAttribute( $tableSelector, 'th', $attr ); | ||||
1267 | } | ||||
1268 | else { | ||||
1269 | my $count = 0; | ||||
1270 | foreach my $align (@headerAlign) { | ||||
1271 | next if !$align; | ||||
1272 | my $colSelector = 'foswikiTableCol'; | ||||
1273 | $colSelector .= $count; | ||||
1274 | my $attr = 'text-align:' . $align; | ||||
1275 | &$setAttribute( $tableSelector, "th.$colSelector", $attr ); | ||||
1276 | $count++; | ||||
1277 | } | ||||
1278 | } | ||||
1279 | } | ||||
1280 | |||||
1281 | # dataAlign | ||||
1282 | if ( defined $inAttrs->{dataAlignListRef} ) { | ||||
1283 | my @dataAlign = @{ $inAttrs->{dataAlignListRef} }; | ||||
1284 | if ( scalar(@dataAlign) == 1 ) { | ||||
1285 | my $align = $dataAlign[0]; | ||||
1286 | my $attr = 'text-align:' . $align; | ||||
1287 | &$setAttribute( $tableSelector, 'td', $attr ); | ||||
1288 | } | ||||
1289 | else { | ||||
1290 | my $count = 0; | ||||
1291 | foreach my $align (@dataAlign) { | ||||
1292 | next if !$align; | ||||
1293 | my $colSelector = 'foswikiTableCol'; | ||||
1294 | $colSelector .= $count; | ||||
1295 | my $attr = 'text-align:' . $align; | ||||
1296 | &$setAttribute( $tableSelector, "td.$colSelector", $attr ); | ||||
1297 | $count++; | ||||
1298 | } | ||||
1299 | } | ||||
1300 | } | ||||
1301 | |||||
1302 | my @styles = (); | ||||
1303 | foreach my $tableSelector ( sort keys %{$_styles} ) { | ||||
1304 | foreach my $selector ( sort keys %{ $_styles->{$tableSelector} } ) { | ||||
1305 | my $selectors = | ||||
1306 | join( '; ', @{ $_styles->{$tableSelector}->{$selector} } ); | ||||
1307 | $selector =~ s/xhover/hover/go; # remove sorting hack | ||||
1308 | # TODO: optimize by combining identical rules | ||||
1309 | if ( $selector eq '#' ) { | ||||
1310 | push @styles, "$tableSelector {$selectors}"; | ||||
1311 | } | ||||
1312 | else { | ||||
1313 | push @styles, "$tableSelector $selector {$selectors}"; | ||||
1314 | } | ||||
1315 | } | ||||
1316 | } | ||||
1317 | |||||
1318 | return ( $id, @styles ); | ||||
1319 | } | ||||
1320 | |||||
1321 | sub _addHeadStyles { | ||||
1322 | my ( $inId, @inStyles ) = @_; | ||||
1323 | |||||
1324 | return if !scalar(@inStyles); | ||||
1325 | |||||
1326 | $styles->{seendIds}->{$inId} = 1; | ||||
1327 | if ( $inId eq $HEAD_ID_DEFAULT_STYLE ) { | ||||
1328 | $styles->{$HEAD_ID_DEFAULT_STYLE}->{'default'} = \@inStyles; | ||||
1329 | _writeStyleToHead( $HEAD_ID_DEFAULT_STYLE, | ||||
1330 | $styles->{$HEAD_ID_DEFAULT_STYLE} ); | ||||
1331 | } | ||||
1332 | else { | ||||
1333 | $styles->{$HEAD_ID_SPECIFIC_STYLE}->{$inId} = \@inStyles; | ||||
1334 | _writeStyleToHead( $HEAD_ID_SPECIFIC_STYLE, | ||||
1335 | $styles->{$HEAD_ID_SPECIFIC_STYLE} ); | ||||
1336 | } | ||||
1337 | } | ||||
1338 | |||||
1339 | sub _writeStyleToHead { | ||||
1340 | my ( $inId, $inStyles ) = @_; | ||||
1341 | |||||
1342 | my @allStyles = (); | ||||
1343 | foreach my $id ( sort keys %{$inStyles} ) { | ||||
1344 | push @allStyles, @{ $inStyles->{$id} }; | ||||
1345 | } | ||||
1346 | my $styleText = join( "\n", @allStyles ); | ||||
1347 | |||||
1348 | my $header = <<EOS; | ||||
1349 | <style type="text/css" media="all"> | ||||
1350 | $styleText | ||||
1351 | </style> | ||||
1352 | EOS | ||||
1353 | Foswiki::Func::addToZone( "head", $inId, $header, $HEAD_ID_DEFAULT_STYLE ); | ||||
1354 | } | ||||
1355 | |||||
1356 | =pod | ||||
1357 | |||||
1358 | StaticMethod addDefaultSizeUnit ($text) -> $text | ||||
1359 | |||||
1360 | Adds size unit 'px' if this is missing from the size text. | ||||
1361 | |||||
1362 | =cut | ||||
1363 | |||||
1364 | sub addDefaultSizeUnit { | ||||
1365 | my ($inSize) = @_; | ||||
1366 | |||||
1367 | my $unit = ''; | ||||
1368 | if ( $inSize =~ m/$PATTERN_ATTRIBUTE_SIZE/ ) { | ||||
1369 | $unit = 'px' if !$2; | ||||
1370 | } | ||||
1371 | return "$inSize$unit"; | ||||
1372 | } | ||||
1373 | |||||
1374 | sub emitTable { | ||||
1375 | |||||
1376 | _addDefaultStyles(); | ||||
1377 | |||||
1378 | _debug('emitTable'); | ||||
1379 | |||||
1380 | #Validate headerrows/footerrows and modify if out of range | ||||
1381 | if ( $combinedTableAttrs->{headerrows} > scalar(@curTable) ) { | ||||
1382 | $combinedTableAttrs->{headerrows} = | ||||
1383 | scalar(@curTable); # limit header to size of table! | ||||
1384 | } | ||||
1385 | if ( $combinedTableAttrs->{headerrows} + $combinedTableAttrs->{footerrows} > | ||||
1386 | @curTable ) | ||||
1387 | { | ||||
1388 | $combinedTableAttrs->{footerrows} = | ||||
1389 | scalar(@curTable) - | ||||
1390 | $combinedTableAttrs->{headerrows}; # and footer to whatever is left | ||||
1391 | } | ||||
1392 | |||||
1393 | my $sortThisTable = | ||||
1394 | ( !defined $combinedTableAttrs->{sortAllTables} | ||||
1395 | || $combinedTableAttrs->{sortAllTables} == 0 ) | ||||
1396 | ? 0 | ||||
1397 | : $combinedTableAttrs->{sort}; | ||||
1398 | |||||
1399 | if ( $combinedTableAttrs->{headerrows} == 0 ) { | ||||
1400 | my ( $headerRowCount, $footerRowCount ) = _headerRowCount( \@curTable ); | ||||
1401 | |||||
1402 | # override default setting with calculated header count | ||||
1403 | $combinedTableAttrs->{headerrows} = $headerRowCount; | ||||
1404 | $combinedTableAttrs->{footerrows} = $footerRowCount; | ||||
1405 | } | ||||
1406 | |||||
1407 | my $tableTagAttributes = {}; | ||||
1408 | $tableTagAttributes->{class} = $combinedTableAttrs->{class}; | ||||
1409 | $tableTagAttributes->{border} = $combinedTableAttrs->{border}; | ||||
1410 | $tableTagAttributes->{cellspacing} = $combinedTableAttrs->{cellspacing}; | ||||
1411 | $tableTagAttributes->{cellpadding} = $combinedTableAttrs->{cellpadding}; | ||||
1412 | $tableTagAttributes->{id} = $combinedTableAttrs->{id} | ||||
1413 | || undef; | ||||
1414 | $tableTagAttributes->{summary} = $combinedTableAttrs->{summary}; | ||||
1415 | $tableTagAttributes->{frame} = $combinedTableAttrs->{frame}; | ||||
1416 | $tableTagAttributes->{rules} = $combinedTableAttrs->{rules}; | ||||
1417 | $tableTagAttributes->{width} = $combinedTableAttrs->{width}; | ||||
1418 | |||||
1419 | # remove empty attributes | ||||
1420 | while ( my ( $key, $value ) = each %{$tableTagAttributes} ) { | ||||
1421 | delete $tableTagAttributes->{$key} if !defined $value || $value eq ''; | ||||
1422 | } | ||||
1423 | |||||
1424 | my $text = $currTablePre . CGI::start_table($tableTagAttributes); | ||||
1425 | $text .= $currTablePre . CGI::caption( $combinedTableAttrs->{tableCaption} ) | ||||
1426 | if $combinedTableAttrs->{tableCaption}; | ||||
1427 | |||||
1428 | # count the number of cols to prevent looping over non-existing columns | ||||
1429 | my $maxCols = 0; | ||||
1430 | |||||
1431 | # Flush out any remaining rowspans | ||||
1432 | for ( my $i = 0 ; $i < @rowspan ; $i++ ) { | ||||
1433 | if ( defined( $rowspan[$i] ) && $rowspan[$i] ) { | ||||
1434 | my $nRows = scalar(@curTable); | ||||
1435 | my $rspan = $rowspan[$i] + 1; | ||||
1436 | my $r = $nRows - $rspan; | ||||
1437 | $curTable[$r][$i]->{attrs} ||= {}; | ||||
1438 | if ( $rspan > 1 ) { | ||||
1439 | $curTable[$r][$i]->{attrs}->{rowspan} = $rspan; | ||||
1440 | } | ||||
1441 | } | ||||
1442 | } | ||||
1443 | |||||
1444 | if ( | ||||
1445 | ( | ||||
1446 | $sortThisTable | ||||
1447 | && defined $sortCol | ||||
1448 | && defined $requestedTable | ||||
1449 | && $requestedTable == $tableCount | ||||
1450 | ) | ||||
1451 | || defined $combinedTableAttrs->{initSort} | ||||
1452 | ) | ||||
1453 | { | ||||
1454 | |||||
1455 | # DG 08 Aug 2002: Allow multi-line headers | ||||
1456 | my @header = splice( @curTable, 0, $combinedTableAttrs->{headerrows} ); | ||||
1457 | |||||
1458 | # DG 08 Aug 2002: Skip sorting any trailers as well | ||||
1459 | my @trailer = (); | ||||
1460 | if ( $combinedTableAttrs->{footerrows} | ||||
1461 | && scalar(@curTable) > $combinedTableAttrs->{footerrows} ) | ||||
1462 | { | ||||
1463 | @trailer = splice( @curTable, -$combinedTableAttrs->{footerrows} ); | ||||
1464 | } | ||||
1465 | |||||
1466 | # Count the maximum number of columns of this table | ||||
1467 | for my $row ( 0 .. $#curTable ) { | ||||
1468 | my $thisRowMaxColCount = 0; | ||||
1469 | for my $col ( 0 .. $#{ $curTable[$row] } ) { | ||||
1470 | $thisRowMaxColCount++; | ||||
1471 | } | ||||
1472 | $maxCols = $thisRowMaxColCount | ||||
1473 | if ( $thisRowMaxColCount > $maxCols ); | ||||
1474 | } | ||||
1475 | |||||
1476 | # Handle multi-row labels by killing rowspans in sorted tables | ||||
1477 | for my $row ( 0 .. $#curTable ) { | ||||
1478 | for my $col ( 0 .. $#{ $curTable[$row] } ) { | ||||
1479 | |||||
1480 | # SMELL: why do we need to specify a rowspan of 1? | ||||
1481 | $curTable[$row][$col]->{attrs}->{rowspan} = 1; | ||||
1482 | if ( $curTable[$row][$col]->{type} eq 'Y' ) { | ||||
1483 | $curTable[$row][$col]->{text} = | ||||
1484 | $curTable[ $row - 1 ][$col]->{text}; | ||||
1485 | $curTable[$row][$col]->{type} = 'td'; | ||||
1486 | } | ||||
1487 | } | ||||
1488 | } | ||||
1489 | |||||
1490 | # url requested sort on column beyond end of table. Force to last column | ||||
1491 | $sortCol = 0 unless ( $sortCol =~ m/^[0-9]+$/ ); | ||||
1492 | $sortCol = $maxCols - 1 if ( $sortCol >= $maxCols ); | ||||
1493 | |||||
1494 | # only get the column type if within bounds | ||||
1495 | if ( $sortCol < $maxCols ) { | ||||
1496 | _setSortTypeForCells( $sortCol, \@curTable ); | ||||
1497 | } | ||||
1498 | |||||
1499 | _debug("currentSortDirection:$currentSortDirection"); | ||||
1500 | |||||
1501 | if ( $combinedTableAttrs->{sort} | ||||
1502 | && $currentSortDirection == $SORT_DIRECTION->{'ASCENDING'} ) | ||||
1503 | { | ||||
1504 | @curTable = sort { | ||||
1505 | $a->[$sortCol]->{sortText} cmp $b->[$sortCol]->{sortText} | ||||
1506 | || $a->[$sortCol]->{number} <=> $b->[$sortCol]->{number} | ||||
1507 | || $a->[$sortCol]->{dateString} | ||||
1508 | cmp $b->[$sortCol]->{dateString} | ||||
1509 | } @curTable; | ||||
1510 | } | ||||
1511 | elsif ($combinedTableAttrs->{sort} | ||||
1512 | && $currentSortDirection == $SORT_DIRECTION->{'DESCENDING'} ) | ||||
1513 | { | ||||
1514 | @curTable = sort { | ||||
1515 | $b->[$sortCol]->{sortText} cmp $a->[$sortCol]->{sortText} | ||||
1516 | || $b->[$sortCol]->{number} <=> $a->[$sortCol]->{number} | ||||
1517 | || $b->[$sortCol]->{dateString} | ||||
1518 | cmp $a->[$sortCol]->{dateString} | ||||
1519 | } @curTable; | ||||
1520 | } | ||||
1521 | |||||
1522 | # DG 08 Aug 2002: Cleanup after the header/trailer splicing | ||||
1523 | # this is probably awfully inefficient - but how big is a table? | ||||
1524 | @curTable = ( @header, @curTable, @trailer ); | ||||
1525 | } # if defined $sortCol ... | ||||
1526 | |||||
1527 | my $rowCount = 0; | ||||
1528 | my $numberOfRows = scalar(@curTable); | ||||
1529 | my $dataColorCount = 0; | ||||
1530 | |||||
1531 | my @headerRowList = (); | ||||
1532 | my @bodyRowList = (); | ||||
1533 | my @footerRowList = (); | ||||
1534 | |||||
1535 | my $isPastHeaderRows = 0; | ||||
1536 | my $singleIndent = "\n\t"; | ||||
1537 | my $doubleIndent = "\n\t\t"; | ||||
1538 | my $tripleIndent = "\n\t\t\t"; | ||||
1539 | |||||
1540 | # Only *one* row of the table has sort links, and it will either | ||||
1541 | # be the last row in the header or the first row in the footer. | ||||
1542 | my $sortLinksWritten = 0; | ||||
1543 | |||||
1544 | foreach my $row (@curTable) { | ||||
1545 | my $rowtext = ''; | ||||
1546 | my $colCount = 0; | ||||
1547 | |||||
1548 | # keep track of header cells: if all cells are header cells, do not | ||||
1549 | # update the data color count | ||||
1550 | my $headerCellCount = 0; | ||||
1551 | my $numberOfCols = scalar(@$row); | ||||
1552 | my $writingSortLinks = 0; | ||||
1553 | |||||
1554 | foreach my $fcell (@$row) { | ||||
1555 | |||||
1556 | # check if cell exists | ||||
1557 | next if ( !$fcell || !$fcell->{type} ); | ||||
1558 | |||||
1559 | my $tableAnchor = ''; | ||||
1560 | next | ||||
1561 | if ( $fcell->{type} eq 'X' ) | ||||
1562 | ; # data was there so sort could work with col spanning | ||||
1563 | my $type = $fcell->{type}; | ||||
1564 | my $cell = $fcell->{text}; | ||||
1565 | my $attr = $fcell->{attrs} || {}; | ||||
1566 | |||||
1567 | my $newDirection; | ||||
1568 | my $isSorted = 0; | ||||
1569 | |||||
1570 | if ( | ||||
1571 | $currentSortDirection != $SORT_DIRECTION->{'NONE'} | ||||
1572 | && defined $sortCol | ||||
1573 | && $colCount == $sortCol | ||||
1574 | |||||
1575 | # Removing the line below hides the marking of sorted columns | ||||
1576 | # until the user clicks on a header (KJL) | ||||
1577 | # && defined $requestedTable && $requestedTable == $tableCount | ||||
1578 | # && $sortType ne '' | ||||
1579 | ) | ||||
1580 | { | ||||
1581 | $isSorted = 1; | ||||
1582 | $newDirection = _getNewSortDirection($currentSortDirection); | ||||
1583 | } | ||||
1584 | else { | ||||
1585 | $newDirection = _getDefaultSortDirection(); | ||||
1586 | } | ||||
1587 | |||||
1588 | if ( $type eq 'th' ) { | ||||
1589 | $headerCellCount++; | ||||
1590 | |||||
1591 | # html attribute: bgcolor | ||||
1592 | if ( $combinedTableAttrs->{generateInlineMarkup} | ||||
1593 | && defined $combinedTableAttrs->{headerBg} ) | ||||
1594 | { | ||||
1595 | $attr->{bgcolor} = $combinedTableAttrs->{headerBg} | ||||
1596 | unless ( $combinedTableAttrs->{headerBg} =~ /none/i ); | ||||
1597 | } | ||||
1598 | |||||
1599 | # END html attribute | ||||
1600 | |||||
1601 | if ($isSorted) { | ||||
1602 | if ( $currentSortDirection == | ||||
1603 | $SORT_DIRECTION->{'ASCENDING'} ) | ||||
1604 | { | ||||
1605 | $tableAnchor = $CHAR_SORT_ASCENDING; | ||||
1606 | } | ||||
1607 | if ( $currentSortDirection == | ||||
1608 | $SORT_DIRECTION->{'DESCENDING'} ) | ||||
1609 | { | ||||
1610 | $tableAnchor = $CHAR_SORT_DESCENDING; | ||||
1611 | } | ||||
1612 | |||||
1613 | # html attribute: (sorted header cell) bgcolor | ||||
1614 | # overrides earlier set bgcolor | ||||
1615 | if ( $combinedTableAttrs->{generateInlineMarkup} | ||||
1616 | && defined $combinedTableAttrs->{headerBgSorted} ) | ||||
1617 | { | ||||
1618 | $attr->{bgcolor} = $combinedTableAttrs->{headerBgSorted} | ||||
1619 | unless ( | ||||
1620 | $combinedTableAttrs->{headerBgSorted} =~ /none/i ); | ||||
1621 | } | ||||
1622 | |||||
1623 | # END html attribute | ||||
1624 | } | ||||
1625 | |||||
1626 | if ( | ||||
1627 | defined $sortCol | ||||
1628 | && $colCount == $sortCol | ||||
1629 | && defined $requestedTable | ||||
1630 | && $requestedTable == $tableCount | ||||
1631 | && ( $combinedTableAttrs->{headerrows} | ||||
1632 | || $combinedTableAttrs->{footerrows} ) | ||||
1633 | ) | ||||
1634 | { | ||||
1635 | |||||
1636 | $tableAnchor = | ||||
1637 | CGI::a( { name => 'sorted_table' }, '<!-- -->' ) | ||||
1638 | . $tableAnchor; | ||||
1639 | } | ||||
1640 | |||||
1641 | # html attribute: headercolor (font style) | ||||
1642 | if ( $combinedTableAttrs->{generateInlineMarkup} | ||||
1643 | && defined $combinedTableAttrs->{headerColor} ) | ||||
1644 | { | ||||
1645 | my $fontStyle = | ||||
1646 | { color => $combinedTableAttrs->{headerColor} }; | ||||
1647 | $cell = CGI::font( $fontStyle, $cell ); | ||||
1648 | } | ||||
1649 | |||||
1650 | # END html attribute | ||||
1651 | |||||
1652 | if ( | ||||
1653 | $sortThisTable | ||||
1654 | && ( | ||||
1655 | ( $rowCount == $combinedTableAttrs->{headerrows} - 1 ) | ||||
1656 | || ( !$combinedTableAttrs->{headerrows} | ||||
1657 | && $rowCount == | ||||
1658 | $numberOfRows - $combinedTableAttrs->{footerrows} ) | ||||
1659 | ) | ||||
1660 | && ( $writingSortLinks || !$sortLinksWritten ) | ||||
1661 | ) | ||||
1662 | { | ||||
1663 | $writingSortLinks = 1; | ||||
1664 | my $linkAttributes = { | ||||
1665 | href => $url | ||||
1666 | . 'sortcol=' | ||||
1667 | . $colCount | ||||
1668 | . ';table=' | ||||
1669 | . $tableCount . ';up=' | ||||
1670 | . $newDirection | ||||
1671 | . '#sorted_table', | ||||
1672 | rel => 'nofollow', | ||||
1673 | title => 'Sort by this column' | ||||
1674 | }; | ||||
1675 | |||||
1676 | if ( $cell =~ /\[\[|href/o ) { | ||||
1677 | $cell .= CGI::a( $linkAttributes, $CHAR_SORT_BOTH ) | ||||
1678 | . $tableAnchor; | ||||
1679 | } | ||||
1680 | else { | ||||
1681 | $cell = CGI::a( $linkAttributes, $cell ) . $tableAnchor; | ||||
1682 | } | ||||
1683 | } | ||||
1684 | |||||
1685 | } | ||||
1686 | else { | ||||
1687 | |||||
1688 | $type = 'td' unless $type eq 'Y'; | ||||
1689 | |||||
1690 | # html attribute: bgcolor | ||||
1691 | if ( $combinedTableAttrs->{generateInlineMarkup} ) { | ||||
1692 | if ( $isSorted | ||||
1693 | && defined $combinedTableAttrs->{dataBgSortedListRef} ) | ||||
1694 | { | ||||
1695 | my @dataBg = | ||||
1696 | @{ $combinedTableAttrs->{dataBgSortedListRef} }; | ||||
1697 | |||||
1698 | unless ( $dataBg[0] =~ /none/ ) { | ||||
1699 | $attr->{bgcolor} = | ||||
1700 | $dataBg[ $dataColorCount % ( $#dataBg + 1 ) ]; | ||||
1701 | } | ||||
1702 | } | ||||
1703 | elsif ( defined $combinedTableAttrs->{dataBgListRef} ) { | ||||
1704 | my @dataBg = @{ $combinedTableAttrs->{dataBgListRef} }; | ||||
1705 | unless ( $dataBg[0] =~ /none/i ) { | ||||
1706 | $attr->{bgcolor} = | ||||
1707 | $dataBg[ $dataColorCount % ( $#dataBg + 1 ) ]; | ||||
1708 | } | ||||
1709 | } | ||||
1710 | } | ||||
1711 | |||||
1712 | # END html attribute | ||||
1713 | |||||
1714 | # html attribute: datacolor (font style) | ||||
1715 | if ( $combinedTableAttrs->{generateInlineMarkup} | ||||
1716 | && defined $combinedTableAttrs->{dataColorListRef} ) | ||||
1717 | { | ||||
1718 | my @dataColor = | ||||
1719 | @{ $combinedTableAttrs->{dataColorListRef} }; | ||||
1720 | my $color = | ||||
1721 | $dataColor[ $dataColorCount % ( $#dataColor + 1 ) ]; | ||||
1722 | unless ( $color =~ /^(none)$/i ) { | ||||
1723 | my $cellAttrs = { color => $color }; | ||||
1724 | $cell = CGI::font( $cellAttrs, ' ' . $cell . ' ' ); | ||||
1725 | } | ||||
1726 | } | ||||
1727 | |||||
1728 | # END html attribute | ||||
1729 | |||||
1730 | } ###if( $type eq 'th' ) | ||||
1731 | |||||
1732 | if ($isSorted) { | ||||
1733 | $attr->{class} = _appendSortedCssClass( $attr->{class} ); | ||||
1734 | } | ||||
1735 | |||||
1736 | if ($writingSortLinks) { | ||||
1737 | $sortLinksWritten = 1; | ||||
1738 | } | ||||
1739 | |||||
1740 | my $isLastRow = ( $rowCount == $numberOfRows - 1 ); | ||||
1741 | if ( $attr->{rowspan} ) { | ||||
1742 | $isLastRow = | ||||
1743 | ( ( $rowCount + ( $attr->{rowspan} - 1 ) ) == | ||||
1744 | $numberOfRows - 1 ); | ||||
1745 | } | ||||
1746 | |||||
1747 | # CSS class name | ||||
1748 | $attr->{class} = _appendFirstColumnCssClass( $attr->{class} ) | ||||
1749 | if $colCount == 0; | ||||
1750 | my $isLastCol = ( $colCount == $numberOfCols - 1 ); | ||||
1751 | $attr->{class} = _appendLastColumnCssClass( $attr->{class} ) | ||||
1752 | if $isLastCol; | ||||
1753 | |||||
1754 | $attr->{class} = _appendLastRowCssClass( $attr->{class} ) | ||||
1755 | if $isLastRow; | ||||
1756 | |||||
1757 | $colCount++; | ||||
1758 | next if ( $type eq 'Y' ); | ||||
1759 | my $fn = 'CGI::' . $type; | ||||
1760 | 2 | 49µs | 2 | 40µs | # spent 26µs (12+14) within Foswiki::Plugins::TablePlugin::Core::BEGIN@1760 which was called:
# once (12µs+14µs) by Foswiki::Plugins::TablePlugin::preRenderingHandler at line 1760 # spent 26µs making 1 call to Foswiki::Plugins::TablePlugin::Core::BEGIN@1760
# spent 14µs making 1 call to strict::unimport |
1761 | $rowtext .= "$tripleIndent" . &$fn( $attr, " $cell " ); | ||||
1762 | 2 | 1.25ms | 2 | 28µs | # spent 19µs (9+9) within Foswiki::Plugins::TablePlugin::Core::BEGIN@1762 which was called:
# once (9µs+9µs) by Foswiki::Plugins::TablePlugin::preRenderingHandler at line 1762 # spent 19µs making 1 call to Foswiki::Plugins::TablePlugin::Core::BEGIN@1762
# spent 9µs making 1 call to strict::import |
1763 | } # foreach my $fcell ( @$row ) | ||||
1764 | |||||
1765 | # assign css class names to tr | ||||
1766 | # based on settings: dataBg, dataBgSorted | ||||
1767 | my $trClassName = ''; | ||||
1768 | |||||
1769 | # just 2 css names is too limited, but we will keep it for compatibility | ||||
1770 | # with existing style sheets | ||||
1771 | my $rowTypeName = | ||||
1772 | ( $rowCount % 2 ) ? 'foswikiTableEven' : 'foswikiTableOdd'; | ||||
1773 | $trClassName = _appendToClassList( $trClassName, $rowTypeName ); | ||||
1774 | |||||
1775 | if ( $combinedTableAttrs->{dataBgSortedListRef} ) { | ||||
1776 | my @dataBgSorted = @{ $combinedTableAttrs->{dataBgSortedListRef} }; | ||||
1777 | my $modRowNum = $dataColorCount % ( $#dataBgSorted + 1 ); | ||||
1778 | $trClassName = | ||||
1779 | _appendRowNumberCssClass( $trClassName, 'dataBgSorted', | ||||
1780 | $modRowNum ); | ||||
1781 | } | ||||
1782 | if ( $combinedTableAttrs->{dataBgListRef} ) { | ||||
1783 | my @dataBg = @{ $combinedTableAttrs->{dataBgListRef} }; | ||||
1784 | my $modRowNum = $dataColorCount % ( $#dataBg + 1 ); | ||||
1785 | $trClassName = | ||||
1786 | _appendRowNumberCssClass( $trClassName, 'dataBg', $modRowNum ); | ||||
1787 | } | ||||
1788 | if ( $combinedTableAttrs->{dataColorListRef} ) { | ||||
1789 | my @dataColor = @{ $combinedTableAttrs->{dataColorListRef} }; | ||||
1790 | my $modRowNum = $dataColorCount % ( $#dataColor + 1 ); | ||||
1791 | $trClassName = | ||||
1792 | _appendRowNumberCssClass( $trClassName, 'dataColor', $modRowNum ); | ||||
1793 | } | ||||
1794 | $rowtext .= $doubleIndent; | ||||
1795 | my $rowHTML = | ||||
1796 | $doubleIndent . CGI::Tr( { class => $trClassName }, $rowtext ); | ||||
1797 | |||||
1798 | my $isHeaderRow = | ||||
1799 | $rowCount < | ||||
1800 | $combinedTableAttrs->{headerrows}; #( $headerCellCount == $colCount ); | ||||
1801 | my $isFooterRow = | ||||
1802 | ( ( $numberOfRows - $rowCount ) <= | ||||
1803 | $combinedTableAttrs->{footerrows} ); | ||||
1804 | |||||
1805 | if ( !$isHeaderRow && !$isFooterRow ) { | ||||
1806 | |||||
1807 | # don't include non-adjacent header rows to the top block of header rows | ||||
1808 | $isPastHeaderRows = 1; | ||||
1809 | } | ||||
1810 | |||||
1811 | if ($isFooterRow) { | ||||
1812 | push @footerRowList, $rowHTML; | ||||
1813 | } | ||||
1814 | elsif ( $isHeaderRow && !$isPastHeaderRows ) { | ||||
1815 | push( @headerRowList, $rowHTML ); | ||||
1816 | } | ||||
1817 | else { | ||||
1818 | push @bodyRowList, $rowHTML; | ||||
1819 | $dataColorCount++; | ||||
1820 | } | ||||
1821 | |||||
1822 | if ($isHeaderRow) { | ||||
1823 | |||||
1824 | # reset data color count to start with first color after | ||||
1825 | # each table heading | ||||
1826 | $dataColorCount = 0; | ||||
1827 | } | ||||
1828 | |||||
1829 | $rowCount++; | ||||
1830 | } # foreach my $row ( @curTable ) | ||||
1831 | |||||
1832 | my $thead = | ||||
1833 | "$singleIndent<thead>" | ||||
1834 | . join( "", @headerRowList ) | ||||
1835 | . "$singleIndent</thead>"; | ||||
1836 | $text .= $currTablePre . $thead if scalar(@headerRowList); | ||||
1837 | |||||
1838 | my $tfoot = | ||||
1839 | "$singleIndent<tfoot>" | ||||
1840 | . join( "", @footerRowList ) | ||||
1841 | . "$singleIndent</tfoot>"; | ||||
1842 | $text .= $currTablePre . $tfoot if scalar(@footerRowList); | ||||
1843 | |||||
1844 | my $tbody; | ||||
1845 | if ( scalar(@bodyRowList) ) { | ||||
1846 | $tbody = | ||||
1847 | "$singleIndent<tbody>" | ||||
1848 | . join( "", @bodyRowList ) | ||||
1849 | . "$singleIndent</tbody>"; | ||||
1850 | } | ||||
1851 | else { | ||||
1852 | |||||
1853 | # A HTML table requires a body, which cannot be empty (Item8991). | ||||
1854 | # So we provide one, but prevent it from being displayed. | ||||
1855 | $tbody = | ||||
1856 | "$singleIndent<tbody>$doubleIndent<tr style=\"display:none;\">$tripleIndent<td></td>$doubleIndent</tr>$singleIndent</tbody>\n"; | ||||
1857 | } | ||||
1858 | |||||
1859 | if ( scalar(@messages) ) { | ||||
1860 | $text = | ||||
1861 | '<span class="foswikiAlert">' | ||||
1862 | . Foswiki::Func::expandCommonVariables( join( "\n", @messages ) ) | ||||
1863 | . '</span>' . "\n" | ||||
1864 | . $text; | ||||
1865 | } | ||||
1866 | |||||
1867 | $text .= $currTablePre . $tbody; | ||||
1868 | $text .= $currTablePre . CGI::end_table() . "\n"; | ||||
1869 | |||||
1870 | return $text; | ||||
1871 | } | ||||
1872 | |||||
1873 | # spent 1.54ms (658µs+881µs) within Foswiki::Plugins::TablePlugin::Core::handler which was called 5 times, avg 308µs/call:
# 5 times (658µs+881µs) by Foswiki::Plugins::TablePlugin::preRenderingHandler at line 83 of /var/www/foswikidev/core/lib/Foswiki/Plugins/TablePlugin.pm, avg 308µs/call | ||||
1874 | ### my ( $text, $removed ) = @_; | ||||
1875 | |||||
1876 | 5 | 9µs | 5 | 32µs | _debug('handler'); # spent 32µs making 5 calls to Foswiki::Plugins::TablePlugin::Core::_debug, avg 6µs/call |
1877 | |||||
1878 | 5 | 1µs | unless ($Foswiki::Plugins::TablePlugin::initialised) { | ||
1879 | 1 | 200ns | $insideTABLE = 0; | ||
1880 | |||||
1881 | # Even if $tableCount is initialized already at plugin init | ||||
1882 | # we need to reset it again each time preRenderingHandler | ||||
1883 | # calls this handler sub. Important for initialiseWhenRender API | ||||
1884 | 1 | 100ns | $tableCount = 0; | ||
1885 | |||||
1886 | 1 | 1µs | 1 | 4µs | my $cgi = Foswiki::Func::getCgiQuery(); # spent 4µs making 1 call to Foswiki::Func::getCgiQuery |
1887 | 1 | 200ns | return unless $cgi; | ||
1888 | |||||
1889 | # Copy existing values | ||||
1890 | 1 | 300ns | my ( @origSort, @origTable, @origUp ); | ||
1891 | 1 | 3µs | 1 | 23µs | @origSort = $cgi->multi_param('sortcol'); # spent 23µs making 1 call to Foswiki::Request::multi_param |
1892 | 1 | 2µs | 1 | 15µs | @origTable = $cgi->multi_param('table'); # spent 15µs making 1 call to Foswiki::Request::multi_param |
1893 | 1 | 1µs | 1 | 14µs | @origUp = $cgi->multi_param('up'); # NOTE: internal parameter # spent 14µs making 1 call to Foswiki::Request::multi_param |
1894 | 1 | 3µs | 1 | 7µs | $cgi->delete( 'sortcol', 'table', 'up' ); # spent 7µs making 1 call to Foswiki::Request::delete |
1895 | 1 | 3µs | 1 | 133µs | $url = $cgi->url( -absolute => 1, -path => 1 ) . '?'; # spent 133µs making 1 call to Foswiki::Request::url |
1896 | 1 | 2µs | 1 | 75µs | my $queryString = $cgi->query_string(); # spent 75µs making 1 call to Foswiki::Request::queryString |
1897 | 1 | 700ns | if ($queryString) { | ||
1898 | $url .= $queryString . ';'; | ||||
1899 | } | ||||
1900 | |||||
1901 | # Restore parameters, so we don't interfere on the remaining execution | ||||
1902 | 1 | 300ns | $cgi->param( -name => 'sortcol', -value => \@origSort ) if @origSort; | ||
1903 | 1 | 200ns | $cgi->param( -name => 'table', -value => \@origTable ) if @origTable; | ||
1904 | 1 | 100ns | $cgi->param( -name => 'up', -value => \@origUp ) if @origUp; | ||
1905 | |||||
1906 | 1 | 1µs | 1 | 12µs | $sortColFromUrl = # spent 12µs making 1 call to Foswiki::Request::param |
1907 | $cgi->param('sortcol'); # zero based: 0 is first column | ||||
1908 | 1 | 200ns | if ( defined $sortColFromUrl && $sortColFromUrl !~ m/^[0-9]+$/ ) { | ||
1909 | $sortColFromUrl = 0; | ||||
1910 | } | ||||
1911 | |||||
1912 | 1 | 1µs | 1 | 12µs | $requestedTable = $cgi->param('table'); # spent 12µs making 1 call to Foswiki::Request::param |
1913 | 1 | 400ns | $requestedTable = 0 | ||
1914 | unless ( defined $requestedTable && $requestedTable =~ m/^[0-9]+$/ ); | ||||
1915 | |||||
1916 | 1 | 1µs | 1 | 12µs | $up = $cgi->param('up'); # spent 12µs making 1 call to Foswiki::Request::param |
1917 | |||||
1918 | 1 | 200ns | $sortTablesInText = 0; | ||
1919 | 1 | 100ns | $sortAttachments = 0; | ||
1920 | 1 | 2µs | 1 | 24µs | my $tmp = Foswiki::Func::getPreferencesValue('TABLEPLUGIN_SORT') # spent 24µs making 1 call to Foswiki::Func::getPreferencesValue |
1921 | || 'all'; | ||||
1922 | 1 | 2µs | if ( !$tmp || $tmp =~ /^all$/oi ) { | ||
1923 | 1 | 200ns | $sortTablesInText = 1; | ||
1924 | 1 | 300ns | $sortAttachments = 1; | ||
1925 | } | ||||
1926 | elsif ( $tmp =~ /^attachments$/oi ) { | ||||
1927 | $sortAttachments = 1; | ||||
1928 | } | ||||
1929 | |||||
1930 | 1 | 2µs | 1 | 305µs | _initDefaults(); # first time # spent 305µs making 1 call to Foswiki::Plugins::TablePlugin::Core::_initDefaults |
1931 | 1 | 1µs | $Foswiki::Plugins::TablePlugin::initialised = 1; | ||
1932 | } | ||||
1933 | |||||
1934 | 5 | 2µs | $insideTABLE = 0; | ||
1935 | |||||
1936 | 5 | 5µs | my $defaultSort = $combinedTableAttrs->{sortAllTables}; | ||
1937 | |||||
1938 | 5 | 1µs | my $acceptable = $combinedTableAttrs->{sortAllTables}; | ||
1939 | 5 | 188µs | my @lines = split( /\r?\n/, $_[0] ); | ||
1940 | 5 | 7µs | for (@lines) { | ||
1941 | 220 | 315µs | if ( | ||
1942 | s/$PATTERN_TABLE/_parseTableSpecificTableAttributes(Foswiki::Func::extractParameters($1))/se | ||||
1943 | ) | ||||
1944 | { | ||||
1945 | $acceptable = 1; | ||||
1946 | } | ||||
1947 | elsif (s/^(\s*)\|(.*\|\s*)$/_processTableRow($1,$2)/eo) { | ||||
1948 | $insideTABLE = 1; | ||||
1949 | } | ||||
1950 | elsif ($insideTABLE) { | ||||
1951 | $_ = emitTable() . $_; | ||||
1952 | $insideTABLE = 0; | ||||
1953 | |||||
1954 | $combinedTableAttrs->{sortAllTables} = $defaultSort; | ||||
1955 | $acceptable = $defaultSort; | ||||
1956 | |||||
1957 | # prepare for next table | ||||
1958 | _resetReusedVariables(); | ||||
1959 | } | ||||
1960 | } | ||||
1961 | 5 | 30µs | $_[0] = join( "\n", @lines ); | ||
1962 | |||||
1963 | 5 | 1µs | if ($insideTABLE) { | ||
1964 | $_[0] .= emitTable(); | ||||
1965 | } | ||||
1966 | |||||
1967 | # prepare for next table | ||||
1968 | 5 | 33µs | 5 | 213µs | _resetReusedVariables(); # spent 213µs making 5 calls to Foswiki::Plugins::TablePlugin::Core::_resetReusedVariables, avg 43µs/call |
1969 | } | ||||
1970 | |||||
1971 | =pod | ||||
1972 | |||||
1973 | _mergeHashes (\%a, \%b ) -> \%merged | ||||
1974 | |||||
1975 | Merges 2 hash references. | ||||
1976 | |||||
1977 | =cut | ||||
1978 | |||||
1979 | # spent 139µs within Foswiki::Plugins::TablePlugin::Core::_mergeHashes which was called 6 times, avg 23µs/call:
# 5 times (122µs+0s) by Foswiki::Plugins::TablePlugin::Core::_resetReusedVariables at line 180, avg 24µs/call
# once (16µs+0s) by Foswiki::Plugins::TablePlugin::Core::_initDefaults at line 165 | ||||
1980 | 6 | 3µs | my ( $A, $B ) = @_; | ||
1981 | |||||
1982 | 6 | 8µs | my %merged = (); | ||
1983 | 6 | 10µs | while ( my ( $k, $v ) = each(%$A) ) { | ||
1984 | $merged{$k} = $v; | ||||
1985 | } | ||||
1986 | 6 | 107µs | while ( my ( $k, $v ) = each(%$B) ) { | ||
1987 | $merged{$k} = $v; | ||||
1988 | } | ||||
1989 | 6 | 19µs | return \%merged; | ||
1990 | } | ||||
1991 | |||||
1992 | =pod | ||||
1993 | |||||
1994 | =cut | ||||
1995 | |||||
1996 | sub _cleanParamValue { | ||||
1997 | 2 | 600ns | my ($inValue) = @_; | ||
1998 | |||||
1999 | 2 | 300ns | return undef if !$inValue; | ||
2000 | |||||
2001 | 2 | 700ns | $inValue =~ s/ //go; # remove spaces | ||
2002 | 2 | 7µs | return $inValue; | ||
2003 | } | ||||
2004 | |||||
2005 | =pod | ||||
2006 | |||||
2007 | =cut | ||||
2008 | |||||
2009 | # spent 12µs within Foswiki::Plugins::TablePlugin::Core::_arrayRefFromParam which was called 6 times, avg 2µs/call:
# once (4µs+0s) by Foswiki::Plugins::TablePlugin::Core::_parseAttributes at line 398
# once (3µs+0s) by Foswiki::Plugins::TablePlugin::Core::_parseAttributes at line 400
# once (2µs+0s) by Foswiki::Plugins::TablePlugin::Core::_parseAttributes at line 383
# once (2µs+0s) by Foswiki::Plugins::TablePlugin::Core::_parseAttributes at line 405
# once (1µs+0s) by Foswiki::Plugins::TablePlugin::Core::_parseAttributes at line 386
# once (1µs+0s) by Foswiki::Plugins::TablePlugin::Core::_parseAttributes at line 389 | ||||
2010 | 6 | 3µs | my ($inValue) = @_; | ||
2011 | |||||
2012 | 6 | 13µs | return undef if !$inValue; | ||
2013 | |||||
2014 | 2 | 700ns | $inValue =~ s/ //go; # remove spaces | ||
2015 | 2 | 3µs | my @list = split( /,/, $inValue ); | ||
2016 | 2 | 6µs | return \@list; | ||
2017 | } | ||||
2018 | |||||
2019 | =pod | ||||
2020 | |||||
2021 | Shorthand debugging call. | ||||
2022 | |||||
2023 | =cut | ||||
2024 | |||||
2025 | # spent 78µs (53+26) within Foswiki::Plugins::TablePlugin::Core::_debug which was called 13 times, avg 6µs/call:
# 5 times (23µs+9µs) by Foswiki::Plugins::TablePlugin::Core::handler at line 1876, avg 6µs/call
# 5 times (17µs+10µs) by Foswiki::Plugins::TablePlugin::Core::_resetReusedVariables at line 178, avg 5µs/call
# once (6µs+3µs) by Foswiki::Plugins::TablePlugin::Core::_init at line 90
# once (3µs+2µs) by Foswiki::Plugins::TablePlugin::Core::_initDefaults at line 154
# once (3µs+1µs) by Foswiki::Plugins::TablePlugin::Core::_parseDefaultAttributes at line 209 | ||||
2026 | 13 | 45µs | 13 | 26µs | return Foswiki::Plugins::TablePlugin::debug( 'TablePlugin::Core', @_ ); # spent 26µs making 13 calls to Foswiki::Plugins::TablePlugin::debug, avg 2µs/call |
2027 | } | ||||
2028 | |||||
2029 | sub _debugData { | ||||
2030 | 2 | 9µs | 2 | 7µs | return Foswiki::Plugins::TablePlugin::debugData( 'TablePlugin::Core', @_ ); # spent 7µs making 2 calls to Foswiki::Plugins::TablePlugin::debugData, avg 3µs/call |
2031 | } | ||||
2032 | |||||
2033 | 1 | 17µs | 1; | ||
2034 | __END__ |