Index: trunk/extensions/QPoll/qp_user.php |
— | — | @@ -37,9 +37,7 @@ |
38 | 38 | die( "This file is part of the QPoll extension. It is not a valid entry point.\n" ); |
39 | 39 | } |
40 | 40 | |
41 | | -define( 'QP_CSS_ERROR_COLOR1' , "LightYellow" ); |
42 | 41 | define( 'QP_CSS_ERROR_COLOR2', "#D700D7" ); |
43 | | -define( 'QP_CSS_ERROR_STYLE', 'background-color: ' . QP_CSS_ERROR_COLOR1 . ';' ); |
44 | 42 | |
45 | 43 | define( 'QP_ERROR_MISSED_TITLE', 1 ); |
46 | 44 | define( 'QP_ERROR_INVALID_ADDRESS', 2 ); |
— | — | @@ -144,9 +142,9 @@ |
145 | 143 | self::$ScriptPath = $wgScriptPath . '/extensions' . ( ( $top_dir == 'extensions' ) ? '' : '/' . $top_dir ); |
146 | 144 | $wgExtensionMessagesFiles['QPoll'] = self::$ExtDir . '/qp_i18n.php'; |
147 | 145 | $wgAutoloadClasses['PollResults'] = self::$ExtDir . '/qp_results.php'; |
148 | | - $wgAutoloadClasses['qp_Question'] = self::$ExtDir . '/qp_question.php'; |
| 146 | + $wgAutoloadClasses['qp_Question'] = |
149 | 147 | $wgAutoloadClasses['qp_QuestionStats'] = self::$ExtDir . '/qp_question.php'; |
150 | | - $wgAutoloadClasses['qp_PollStore'] = self::$ExtDir . '/qp_pollstore.php'; |
| 148 | + $wgAutoloadClasses['qp_PollStore'] = |
151 | 149 | $wgAutoloadClasses['qp_QuestionData'] = self::$ExtDir . '/qp_pollstore.php'; |
152 | 150 | $wgAutoloadClasses['qp_QueryPage'] = self::$ExtDir . '/qp_results.php'; |
153 | 151 | // TODO: Use the new technique for i18n of special page aliases |
— | — | @@ -154,10 +152,11 @@ |
155 | 153 | // TODO: Use the new technique for i18n of magic words |
156 | 154 | // instantiating fake instance for PHP < 5.2.3, which does not support 'Class::method' type of callbacks |
157 | 155 | $qp_Setup = new qp_Setup; |
158 | | - $wgHooks['LanguageGetMagic'][] = $qp_Setup; |
159 | | - $wgHooks['MediaWikiPerformAction'][] = $qp_Setup; |
160 | | - $wgHooks['ParserFirstCallInit'][] = $qp_Setup; |
161 | | - $wgHooks['LoadAllMessages'][] = $qp_Setup; |
| 156 | + $wgHooks['LanguageGetMagic'][] = |
| 157 | + $wgHooks['MediaWikiPerformAction'][] = |
| 158 | + $wgHooks['ParserFirstCallInit'][] = |
| 159 | + $wgHooks['LoadAllMessages'][] = |
| 160 | + $wgHooks['ResourceLoaderRegisterModules'][] = $qp_Setup; |
162 | 161 | } |
163 | 162 | |
164 | 163 | static function onLoadAllMessages() { |
— | — | @@ -236,21 +235,24 @@ |
237 | 236 | * Register the extension with the WikiText parser. |
238 | 237 | */ |
239 | 238 | static function onParserFirstCallInit() { |
| 239 | + global $wgOut; |
| 240 | + if ( class_exists( 'ResourceLoader' ) ) { |
| 241 | + # MW 1.17+ |
| 242 | + // $wgOut->addModules( 'jquery' ); |
| 243 | + $wgOut->addModules( 'ext.qpoll' ); |
| 244 | + } else { |
| 245 | + # MW < 1.17 |
| 246 | + global $wgJsMimeType, $wgContLang; |
| 247 | + # Ouput the style and the script to the header once for all. |
| 248 | + $head = '<script type="' . $wgJsMimeType . '" src="' . self::$ScriptPath . '/qp_user.js"></script>' . "\n"; |
| 249 | + $wgOut->addScript( $head ); |
| 250 | + $wgOut->addExtensionStyle( self::$ScriptPath . '/qp_user.css' ); |
| 251 | + if ( $wgContLang->isRTL() ) { |
| 252 | + $wgOut->addExtensionStyle( self::$ScriptPath . '/qp_user_rtl.css' ); |
| 253 | + } |
| 254 | + } |
240 | 255 | global $wgParser; |
241 | | - global $wgExtensionCredits; |
242 | 256 | global $wgQPollFunctionsHook; |
243 | | - global $wgContLang; |
244 | | - global $wgJsMimeType, $wgOut; |
245 | | - # Ouput the style and the script to the header once for all. |
246 | | - $head = '<style type="text/css">' . "\n"; |
247 | | - $head .= '.qpoll .fatalerror { border: 1px solid gray; padding: 4px; ' . QP_CSS_ERROR_STYLE . ' }' . "\n"; |
248 | | - $head .= '</style>' . "\n"; |
249 | | - $head .= '<script type="' . $wgJsMimeType . '" src="' . self::$ScriptPath . '/qp_user.js"></script>' . "\n"; |
250 | | - $wgOut->addScript( $head ); |
251 | | - $wgOut->addExtensionStyle( self::$ScriptPath . '/qp_user.css' ); |
252 | | - if ( $wgContLang->isRTL() ) { |
253 | | - $wgOut->addExtensionStyle( self::$ScriptPath . '/qp_user_rtl.css' ); |
254 | | - } |
255 | 257 | # setup tag hook |
256 | 258 | $wgParser->setHook( 'qpoll', array( 'qp_Setup', 'renderPoll' ) ); |
257 | 259 | $wgQPollFunctionsHook = new qp_FunctionsHook(); |
— | — | @@ -260,6 +262,28 @@ |
261 | 263 | } |
262 | 264 | |
263 | 265 | /** |
| 266 | + * MW 1.17+ ResourceLoader module hook (JS,CSS) |
| 267 | + */ |
| 268 | + static function onResourceLoaderRegisterModules( $resourceLoader ) { |
| 269 | + global $wgExtensionAssetsPath; |
| 270 | + $localpath = dirname( __FILE__ ); |
| 271 | + $remotepath = "$wgExtensionAssetsPath/QPoll"; |
| 272 | + $resourceLoader->register( |
| 273 | + array( |
| 274 | + 'ext.qpoll' => new ResourceLoaderFileModule( |
| 275 | + array( |
| 276 | + 'scripts' => 'qp_user.js', |
| 277 | + 'styles' => 'qp_user.css' |
| 278 | + ), |
| 279 | + $localpath, |
| 280 | + $remotepath |
| 281 | + ) |
| 282 | + ) |
| 283 | + ); |
| 284 | + return true; |
| 285 | + } |
| 286 | + |
| 287 | + /** |
264 | 288 | * Call the poll parser on an input text. |
265 | 289 | * |
266 | 290 | * @param $input Text between <qpoll> and </qpoll> tags, in QPoll syntax. |
— | — | @@ -1121,6 +1145,19 @@ |
1122 | 1146 | return $tag_open . $tag_val . $tag_close; |
1123 | 1147 | } |
1124 | 1148 | |
| 1149 | + /** |
| 1150 | + * add one or more of CSS class names to tag class attribute |
| 1151 | + */ |
| 1152 | + static function addClass( &$tag, $className ) { |
| 1153 | + if ( !isset( $tag['class'] ) ) { |
| 1154 | + $tag['class'] = $className; |
| 1155 | + return; |
| 1156 | + } |
| 1157 | + if ( array_search( $className, explode( ' ', $tag['class'] ) ) === false ) { |
| 1158 | + $tag['class'] .= " $className"; |
| 1159 | + } |
| 1160 | + } |
| 1161 | + |
1125 | 1162 | # creates one "htmlobject" row of the table |
1126 | 1163 | # elements of $row can be either a string/number value of cell or an array( "count"=>colspannum, "attribute"=>value, 0=>html_inside_tag ) |
1127 | 1164 | # attribute maps can be like this: ("name"=>0, "count"=>colspan" ) |
Index: trunk/extensions/QPoll/qp_user.css |
— | — | @@ -1,3 +1,5 @@ |
| 2 | +.qpoll .error { background-color: LightYellow; } |
| 3 | +.qpoll .fatalerror { border: 1px solid gray; padding: 4px; background-color: LightYellow; } |
2 | 4 | .qpoll .settings input.numerical { width:2em; } |
3 | 5 | .qpoll .header {font-weight: bold;} |
4 | 6 | *>.qpoll .header .questionId {text-indent: -1.5em; } /* *> prevent ie6 to interprate it. */ |
Index: trunk/extensions/QPoll/qp_question.php |
— | — | @@ -180,7 +180,7 @@ |
181 | 181 | $spanState->cellsLeft = $this->mCategorySpans[ $spanState->id ]['count']; |
182 | 182 | if ( $spanState->cellsLeft < 2 ) { |
183 | 183 | $text = $this->bodyErrorMessage( wfMsg( 'qp_error_too_few_spans' ), 'error' ) . $text; |
184 | | - $row[ $catId ][ 'style' ] = QP_CSS_ERROR_STYLE; |
| 184 | + QP_Renderer::addClass( $row[ $catId ], 'error' ); |
185 | 185 | } |
186 | 186 | $spanState->isDrawing = $spanState->cellsLeft != 1 && $spanState->cellsLeft != count( $this->mCategories ); |
187 | 187 | # hightlight only spans of count != 1 and count != count(categories) |
— | — | @@ -301,12 +301,12 @@ |
302 | 302 | if ( $this->categoriesStyle != '' ) { |
303 | 303 | qp_Renderer::applyAttrsToRow( $spansRow, array( 'style'=>$this->categoriesStyle ) ); |
304 | 304 | } |
305 | | - $this->addRow( $spansRow, array( 'class'=>'spans'), 'th', array( 'count'=>$this->spanType, 'name'=>0 ) ); |
| 305 | + $this->addRow( $spansRow, array( 'class'=>'spans' ), 'th', array( 'count'=>$this->spanType, 'name'=>0 ) ); |
306 | 306 | } |
307 | 307 | if ( $this->categoriesStyle != '' ) { |
308 | 308 | qp_Renderer::applyAttrsToRow( $catRow, array( 'style'=>$this->categoriesStyle ) ); |
309 | 309 | } |
310 | | - $this->addRow( $catRow, array( 'class'=>'categories'), 'th', array( 'name'=>0 ) ); |
| 310 | + $this->addRow( $catRow, array( 'class'=>'categories' ), 'th', array( 'name'=>0 ) ); |
311 | 311 | foreach ( $this->mProposalText as $proposalId => $text ) { |
312 | 312 | $row = Array(); |
313 | 313 | $rawClass = 'proposal'; |
— | — | @@ -320,7 +320,7 @@ |
321 | 321 | $this->renderSpan( $name, $catDesc, $text, $rawClass, $spanState ); |
322 | 322 | break; |
323 | 323 | } |
324 | | - $row[ $catId ][ 'class' ] = $spanState->className; |
| 324 | + QP_Renderer::addClass( $row[ $catId ], $spanState->className ); |
325 | 325 | if ( $this->showResults['type'] != 0 ) { |
326 | 326 | # there ars some stat in row (not necessarily all cells, because size of question table changes dynamically) |
327 | 327 | $row[ $catId ][ 0 ] = $this->{'addShowResults' . $this->showResults['type']}( $proposalId, $catId ); |
— | — | @@ -576,12 +576,12 @@ |
577 | 577 | if ( $this->categoriesStyle != '' ) { |
578 | 578 | qp_Renderer::applyAttrsToRow( $spansRow, array( 'style'=>$this->categoriesStyle ) ); |
579 | 579 | } |
580 | | - $this->addRow( $spansRow, array( 'class'=>'spans'), 'th', array( 'count'=>$this->spanType, 'name'=>0 ) ); |
| 580 | + $this->addRow( $spansRow, array( 'class'=>'spans' ), 'th', array( 'count'=>$this->spanType, 'name'=>0 ) ); |
581 | 581 | } |
582 | 582 | if ( $this->categoriesStyle != '' ) { |
583 | 583 | qp_Renderer::applyAttrsToRow( $catRow, array( 'style'=>$this->categoriesStyle ) ); |
584 | 584 | } |
585 | | - $this->addRow( $catRow, array( 'class'=>'categories'), 'th', array( 'name'=>0 ) ); |
| 585 | + $this->addRow( $catRow, array( 'class'=>'categories' ), 'th', array( 'name'=>0 ) ); |
586 | 586 | } |
587 | 587 | |
588 | 588 | function singleChoiceParseBody() { |
— | — | @@ -633,7 +633,7 @@ |
634 | 634 | $text = $this->bodyErrorMessage( wfMsg( 'qp_error_unanswered_span' ), 'NA' ) . $text; |
635 | 635 | # highlight current span to indicate an error |
636 | 636 | for ( $i = $catId, $j = $this->mCategorySpans[ $spanState->id ]['count']; $j > 0; $i--, $j-- ) { |
637 | | - $row[$i][ 'style' ] = QP_CSS_ERROR_STYLE; |
| 637 | + QP_Renderer::addClass( $row[$i], 'error' ); |
638 | 638 | } |
639 | 639 | $rawClass = 'proposalerror'; |
640 | 640 | } |
— | — | @@ -653,7 +653,7 @@ |
654 | 654 | $text = $this->bodyErrorMessage( wfMsg( 'qp_error_non_unique_choice' ), 'NA' ) . $text; |
655 | 655 | $rawClass = 'proposalerror'; |
656 | 656 | unset( $inp[ 'checked' ] ); |
657 | | - $row[ $catId ][ 'style' ] = QP_CSS_ERROR_STYLE; |
| 657 | + QP_Renderer::addClass( $row[ $catId ], 'error' ); |
658 | 658 | } |
659 | 659 | } else { |
660 | 660 | $spanState->wasChecked = true; |
— | — | @@ -664,7 +664,7 @@ |
665 | 665 | $this->mProposalCategoryId[ $proposalId ][] = $catId; |
666 | 666 | $this->mProposalCategoryText[ $proposalId ][] = ''; |
667 | 667 | } |
668 | | - $row[ $catId ][ 'class' ] = $spanState->className; |
| 668 | + QP_Renderer::addClass( $row[ $catId ], $spanState->className ); |
669 | 669 | if ( $this->mSubType == 'unique' ) { |
670 | 670 | # unique (question,category,proposal) "coordinate" for javascript |
671 | 671 | $inp[ 'id' ] = 'uq' . $this->mQuestionId . 'c' . $catId . 'p' . $proposalId; |
— | — | @@ -673,7 +673,7 @@ |
674 | 674 | # if there was no previous errors, hightlight the whole row |
675 | 675 | if ( $this->getState() == '' ) { |
676 | 676 | foreach( $row as &$cell ) { |
677 | | - $cell[ 'style' ] = QP_CSS_ERROR_STYLE; |
| 677 | + QP_Renderer::addClass( $cell, 'error' ); |
678 | 678 | } |
679 | 679 | } |
680 | 680 | $text = $this->bodyErrorMessage( wfMsg( 'qp_error_unique' ), 'error' ) . $text; |
— | — | @@ -695,7 +695,7 @@ |
696 | 696 | if( trim( $text ) == '' ) { |
697 | 697 | $text = $this->bodyErrorMessage( wfMsg( 'qp_error_proposal_text_empty' ), 'error' ); |
698 | 698 | foreach( $row as &$cell ) { |
699 | | - $cell[ 'style' ] = QP_CSS_ERROR_STYLE; |
| 699 | + QP_Renderer::addClass( $cell, 'error' ); |
700 | 700 | } |
701 | 701 | $rawClass = 'proposalerror'; |
702 | 702 | } |
— | — | @@ -704,7 +704,7 @@ |
705 | 705 | # if there was no previous errors, hightlight the whole row |
706 | 706 | if ( $this->getState() == '' ) { |
707 | 707 | foreach( $row as &$cell ) { |
708 | | - $cell[ 'style' ] = QP_CSS_ERROR_STYLE; |
| 708 | + QP_Renderer::addClass( $cell, 'error' ); |
709 | 709 | } |
710 | 710 | } |
711 | 711 | $text = $this->bodyErrorMessage( wfMsg( 'qp_error_no_answer' ), 'NA' ) . $text; |
— | — | @@ -851,7 +851,7 @@ |
852 | 852 | } catch( Exception $e ) { |
853 | 853 | if ( $e->getMessage() == 'qp_error' ) { |
854 | 854 | foreach( $row as &$cell ) { |
855 | | - $cell[ 'style' ] = QP_CSS_ERROR_STYLE; |
| 855 | + QP_Renderer::addClass( $cell, 'error' ); |
856 | 856 | } |
857 | 857 | $rawClass = 'proposalerror'; |
858 | 858 | } else { |