Fix for r56924: don't do any mouseover/mouseout effects while the spinner is being...
[lhc/web/wiklou.git] / skins / Vector.php
1 <?php
2 /**
3 * Vector - Branch of MonoBook which has many usability improvements and
4 * somewhat cleaner code.
5 *
6 * @todo document
7 * @file
8 * @ingroup Skins
9 */
10
11 if( !defined( 'MEDIAWIKI' ) )
12 die( -1 );
13
14 /**
15 * SkinTemplate class for Vector skin
16 * @ingroup Skins
17 */
18 class SkinVector extends SkinTemplate {
19
20 /* Functions */
21 var $skinname = 'vector', $stylename = 'vector',
22 $template = 'VectorTemplate', $useHeadElement = true;
23
24 /**
25 * Initializes output page and sets up skin-specific parameters
26 * @param object $out Output page object to initialize
27 */
28 public function initPage( OutputPage $out ) {
29 global $wgStylePath, $wgJsMimeType, $wgStyleVersion;
30
31 parent::initPage( $out );
32
33 // Append skin-specific styles
34 $out->addStyle( 'vector/main-rtl.css', 'screen', '', 'rtl' );
35 $out->addStyle( 'vector/main-ltr.css', 'screen', '', 'ltr' );
36 // Append CSS which includes IE only behavior fixes for hover support -
37 // this is better than including this in a CSS fille since it doesn't
38 // wait for the CSS file to load before fetching the HTC file.
39 $out->addScript(
40 '<!--[if lt IE 7]><style type="text/css">body{behavior:url("' .
41 $wgStylePath .
42 '/vector/csshover.htc")}</style><![endif]-->'
43 );
44 // Append common IE fixes, which perhaps should be included in all
45 // skins, but for now it seems each skin needs to include them
46 // explicitly
47 $out->addScript(
48 '<!--[if lt IE 7]><script type="' . $wgJsMimeType . '" src="' .
49 $wgStylePath .
50 '/common/IEFixes.js?' .
51 $wgStyleVersion .
52 '"></script>' .
53 '<meta http-equiv="imagetoolbar" content="no" /><![endif]-->'
54 );
55 }
56 /**
57 * Builds a structured array of links used for tabs and menus
58 * @return array
59 * @private
60 */
61 function buildNavigationUrls() {
62 global $wgContLang, $wgLang, $wgOut, $wgUser, $wgRequest, $wgArticle, $wgStylePath;
63 global $wgDisableLangConversion;
64
65 wfProfileIn( __METHOD__ );
66
67 $links = array(
68 'namespaces' => array(),
69 'views' => array(),
70 'actions' => array(),
71 'variants' => array()
72 );
73
74 // Detects parameters
75 $action = $wgRequest->getVal( 'action', 'view' );
76 $section = $wgRequest->getVal( 'section' );
77
78 // Checks if page is some kind of content
79 if( $this->iscontent ) {
80
81 // Gets page objects for the related namespaces
82 $subjectPage = $this->mTitle->getSubjectPage();
83 $talkPage = $this->mTitle->getTalkPage();
84
85 // Determines if this is a talk page
86 $isTalk = $this->mTitle->isTalkPage();
87
88 // Generates XML IDs from namespace names
89 $subjectId = $this->mTitle->getNamespaceKey( '' );
90
91 if ( $subjectId == 'main' ) {
92 $talkId = 'talk';
93 } else {
94 $talkId = "{$subjectId}_talk";
95 }
96 $currentId = $isTalk ? $talkId : $subjectId;
97
98 // Adds namespace links
99 $links['namespaces'][$subjectId] = $this->tabAction(
100 $subjectPage, 'vector-namespace-' . $subjectId, !$isTalk, '', true
101 );
102 $links['namespaces'][$subjectId]['context'] = 'subject';
103 $links['namespaces'][$talkId] = $this->tabAction(
104 $talkPage, 'vector-namespace-talk', $isTalk, '', true
105 );
106 $links['namespaces'][$talkId]['context'] = 'talk';
107
108 // Adds view view link
109 if ( $this->mTitle->exists() ) {
110 $links['views']['view'] = $this->tabAction(
111 $isTalk ? $talkPage : $subjectPage,
112 'vector-view-view', ( $action == 'view' ), '', true
113 );
114 }
115
116 wfProfileIn( __METHOD__ . '-edit' );
117
118 // Checks if user can...
119 if (
120 // edit the current page
121 $this->mTitle->quickUserCan( 'edit' ) &&
122 (
123 // if it exists
124 $this->mTitle->exists() ||
125 // or they can create one here
126 $this->mTitle->quickUserCan( 'create' )
127 )
128 ) {
129 // Builds CSS class for talk page links
130 $isTalkClass = $isTalk ? ' istalk' : '';
131
132 // Determines if we're in edit mode
133 $selected = (
134 ( $action == 'edit' || $action == 'submit' ) &&
135 ( $section != 'new' )
136 );
137 $links['views']['edit'] = array(
138 'class' => ( $selected ? 'selected' : '' ) . $isTalkClass,
139 'text' => $this->mTitle->exists()
140 ? wfMsg( 'vector-view-edit' )
141 : wfMsg( 'vector-view-create' ),
142 'href' =>
143 $this->mTitle->getLocalUrl( $this->editUrlOptions() )
144 );
145 // Checks if this is a current rev of talk page and we should show a new
146 // section link
147 if ( ( $isTalk && $wgArticle->isCurrent() ) || ( $wgOut->showNewSectionLink() ) ) {
148 // Checks if we should ever show a new section link
149 if ( !$wgOut->forceHideNewSectionLink() ) {
150 // Adds new section link
151 //$links['actions']['addsection']
152 $links['views']['addsection'] = array(
153 'class' => $section == 'new' ? 'selected' : false,
154 'text' => wfMsg( 'vector-action-addsection' ),
155 'href' => $this->mTitle->getLocalUrl(
156 'action=edit&section=new'
157 )
158 );
159 }
160 }
161 // Checks if the page is known (some kind of viewable content)
162 } elseif ( $this->mTitle->isKnown() ) {
163 // Adds view source view link
164 $links['views']['viewsource'] = array(
165 'class' => ( $action == 'edit' ) ? 'selected' : false,
166 'text' => wfMsg( 'vector-view-viewsource' ),
167 'href' =>
168 $this->mTitle->getLocalUrl( $this->editUrlOptions() )
169 );
170 }
171 wfProfileOut( __METHOD__ . '-edit' );
172
173 wfProfileIn( __METHOD__ . '-live' );
174
175 // Checks if the page exists
176 if ( $this->mTitle->exists() ) {
177 // Adds history view link
178 $links['views']['history'] = array(
179 'class' => ($action == 'history') ? 'selected' : false,
180 'text' => wfMsg( 'vector-view-history' ),
181 'href' => $this->mTitle->getLocalUrl( 'action=history' ),
182 'rel' => 'archives',
183 );
184
185 if( $wgUser->isAllowed( 'delete' ) ) {
186 $links['actions']['delete'] = array(
187 'class' => ($action == 'delete') ? 'selected' : false,
188 'text' => wfMsg( 'vector-action-delete' ),
189 'href' => $this->mTitle->getLocalUrl( 'action=delete' )
190 );
191 }
192 if ( $this->mTitle->quickUserCan( 'move' ) ) {
193 $moveTitle = SpecialPage::getTitleFor(
194 'Movepage', $this->thispage
195 );
196 $links['actions']['move'] = array(
197 'class' => $this->mTitle->isSpecial( 'Movepage' ) ?
198 'selected' : false,
199 'text' => wfMsg( 'vector-action-move' ),
200 'href' => $moveTitle->getLocalUrl()
201 );
202 }
203
204 if (
205 $this->mTitle->getNamespace() !== NS_MEDIAWIKI &&
206 $wgUser->isAllowed( 'protect' )
207 ) {
208 if ( !$this->mTitle->isProtected() ){
209 $links['actions']['protect'] = array(
210 'class' => ($action == 'protect') ?
211 'selected' : false,
212 'text' => wfMsg( 'vector-action-protect' ),
213 'href' =>
214 $this->mTitle->getLocalUrl( 'action=protect' )
215 );
216
217 } else {
218 $links['actions']['unprotect'] = array(
219 'class' => ($action == 'unprotect') ?
220 'selected' : false,
221 'text' => wfMsg( 'vector-action-unprotect' ),
222 'href' =>
223 $this->mTitle->getLocalUrl( 'action=unprotect' )
224 );
225 }
226 }
227 } else {
228 // article doesn't exist or is deleted
229 if (
230 $wgUser->isAllowed( 'deletedhistory' ) &&
231 $wgUser->isAllowed( 'undelete' )
232 ) {
233 if( $n = $this->mTitle->isDeleted() ) {
234 $undelTitle = SpecialPage::getTitleFor( 'Undelete' );
235 $links['actions']['undelete'] = array(
236 'class' => false,
237 'text' => wfMsgExt(
238 'vector-action-undelete',
239 array( 'parsemag' ),
240 $wgLang->formatNum( $n )
241 ),
242 'href' => $undelTitle->getLocalUrl(
243 'target=' . urlencode( $this->thispage )
244 )
245 );
246 }
247 }
248
249 if (
250 $this->mTitle->getNamespace() !== NS_MEDIAWIKI &&
251 $wgUser->isAllowed( 'protect' )
252 ) {
253 if ( !$this->mTitle->getRestrictions( 'create' ) ) {
254 $links['actions']['protect'] = array(
255 'class' => ($action == 'protect') ?
256 'selected' : false,
257 'text' => wfMsg( 'vector-action-protect' ),
258 'href' =>
259 $this->mTitle->getLocalUrl( 'action=protect' )
260 );
261
262 } else {
263 $links['actions']['unprotect'] = array(
264 'class' => ($action == 'unprotect') ?
265 'selected' : false,
266 'text' => wfMsg( 'vector-action-unprotect' ),
267 'href' =>
268 $this->mTitle->getLocalUrl( 'action=unprotect' )
269 );
270 }
271 }
272 }
273 wfProfileOut( __METHOD__ . '-live' );
274
275 /**
276 * The following actions use messages which, if made particular to
277 * the Vector skin, would break the Ajax code which makes this
278 * action happen entirely inline. Skin::makeGlobalVariablesScript
279 * defines a set of messages in a javascript object - and these
280 * messages are assumed to be global for all skins. Without making
281 * a change to that procedure these messages will have to remain as
282 * the global versions.
283 */
284 // Checks if the user is logged in
285 if( $this->loggedin ) {
286 // Checks if the user is watching this page
287 if( !$this->mTitle->userIsWatching() ) {
288 // Adds watch view link
289 $links['views']['watch'] = array(
290 'class' =>
291 ( $action == 'watch' or $action == 'unwatch' ) ?
292 'selected' : false,
293 'text' => wfMsg( 'watch' ),
294 'img' => "{$wgStylePath}/vector/images/watch_off.gif",
295 'href' => $this->mTitle->getLocalUrl( 'action=watch' )
296 );
297 } else {
298 // Adds unwatch view link
299 $links['views']['unwatch'] = array(
300 'class' =>
301 ($action == 'unwatch' or $action == 'watch') ?
302 'selected' : false,
303 'text' => wfMsg( 'unwatch' ),
304 'img' => "{$wgStylePath}/vector/images/watch_on.gif",
305 'href' => $this->mTitle->getLocalUrl( 'action=unwatch' )
306 );
307 }
308 }
309
310 // This is instead of SkinTemplateTabs - which uses a flat array
311 wfRunHooks( 'SkinTemplateNavigation', array( &$this, &$links ) );
312
313 // If it's not content, it's got to be a special page
314 } else {
315 $links['namespaces']['special'] = array(
316 'class' => 'selected',
317 'text' => wfMsg( 'vector-namespace-special' ),
318 'href' => $wgRequest->getRequestURL()
319 );
320 }
321
322 // Gets list of language variants
323 $variants = $wgContLang->getVariants();
324 // Checks that language conversion is enabled and variants exist
325 if( !$wgDisableLangConversion && count( $variants ) > 1 ) {
326 // Gets preferred variant
327 $preferred = $wgContLang->getPreferredVariant();
328 // Loops over each variant
329 foreach( $variants as $code ) {
330 // Gets variant name from language code
331 $varname = $wgContLang->getVariantname( $code );
332 // Checks if the variant is marked as disabled
333 if( $varname == 'disable' ) {
334 // Skips this variant
335 continue;
336 }
337 // Appends variant link
338 $links['variants'][] = array(
339 'class' => ( $code == $preferred ) ? 'selected' : false,
340 'text' => $varname,
341 'href' => $this->mTitle->getLocalURL( '', $code )
342 );
343 }
344 }
345
346 wfProfileOut( __METHOD__ );
347
348 return $links;
349 }
350 }
351
352 /**
353 * QuickTemplate class for Vector skin
354 * @ingroup Skins
355 */
356 class VectorTemplate extends QuickTemplate {
357
358 /* Members */
359
360 /**
361 * @var Cached skin object
362 */
363 var $skin;
364
365 /* Functions */
366
367 /**
368 * Outputs the entire contents of the XHTML page
369 */
370 public function execute() {
371 global $wgRequest, $wgOut, $wgContLang;
372
373 $this->skin = $this->data['skin'];
374 $action = $wgRequest->getText( 'action' );
375
376 // Build additional attributes for navigation urls
377 $nav = $this->skin->buildNavigationUrls();
378 foreach ( $nav as $section => $links ) {
379 foreach ( $links as $key => $link ) {
380 $xmlID = $key;
381 if ( isset( $link['context'] ) && $link['context'] == 'subject' ) {
382 $xmlID = 'ca-nstab-' . $xmlID;
383 } else if ( isset( $link['context'] ) && $link['context'] == 'talk' ) {
384 $xmlID = 'ca-talk';
385 } else {
386 $xmlID = 'ca-' . $xmlID;
387 }
388 $nav[$section][$key]['attributes'] =
389 ' id="' . Sanitizer::escapeId( $xmlID ) . '"';
390 if ( $nav[$section][$key]['class'] ) {
391 $nav[$section][$key]['attributes'] .=
392 ' class="' . htmlspecialchars( $link['class'] ) . '"';
393 unset( $nav[$section][$key]['class'] );
394 }
395 // We don't want to give the watch tab an accesskey if the page
396 // is being edited, because that conflicts with the accesskey on
397 // the watch checkbox. We also don't want to give the edit tab
398 // an accesskey, because that's fairly superfluous and conflicts
399 // with an accesskey (Ctrl-E) often used for editing in Safari.
400 if (
401 in_array( $action, array( 'edit', 'submit' ) ) &&
402 in_array( $key, array( 'edit', 'watch', 'unwatch' ) )
403 ) {
404 $nav[$section][$key]['key'] =
405 $this->skin->tooltip( $xmlID );
406 } else {
407 $nav[$section][$key]['key'] =
408 $this->skin->tooltipAndAccesskey( $xmlID );
409 }
410 }
411 }
412 $this->data['namespace_urls'] = $nav['namespaces'];
413 $this->data['view_urls'] = $nav['views'];
414 $this->data['action_urls'] = $nav['actions'];
415 $this->data['variant_urls'] = $nav['variants'];
416 // Build additional attributes for personal_urls
417 foreach ( $this->data['personal_urls'] as $key => $item) {
418 $this->data['personal_urls'][$key]['attributes'] =
419 ' id="' . Sanitizer::escapeId( "pt-$key" ) . '"';
420 if ( isset( $item['active'] ) && $item['active'] ) {
421 $this->data['personal_urls'][$key]['attributes'] .=
422 ' class="active"';
423 }
424 $this->data['personal_urls'][$key]['key'] =
425 $this->skin->tooltipAndAccesskey('pt-'.$key);
426 }
427
428 // Generate additional footer links
429 $footerlinks = array(
430 'info' => array(
431 'lastmod',
432 'viewcount',
433 'numberofwatchingusers',
434 'credits',
435 'copyright',
436 'tagline',
437 ),
438 'places' => array(
439 'privacy',
440 'about',
441 'disclaimer',
442 ),
443 );
444 // Reduce footer links down to only those which are being used
445 $validFooterLinks = array();
446 foreach( $footerlinks as $category => $links ) {
447 $validFooterLinks[$category] = array();
448 foreach( $links as $link ) {
449 if( isset( $this->data[$link] ) && $this->data[$link] ) {
450 $validFooterLinks[$category][] = $link;
451 }
452 }
453 }
454 // Reverse horizontally rendered navigation elements
455 if ( $wgContLang->isRTL() ) {
456 $this->data['view_urls'] =
457 array_reverse( $this->data['view_urls'] );
458 $this->data['namespace_urls'] =
459 array_reverse( $this->data['namespace_urls'] );
460 $this->data['personal_urls'] =
461 array_reverse( $this->data['personal_urls'] );
462 }
463 // Output HTML Page
464 $this->html( 'headelement' );
465 ?>
466 <body<?php if ( $this->data['body_ondblclick'] ): ?> ondblclick="<?php $this->text( 'body_ondblclick' ) ?>"<?php endif; ?> <?php if ( $this->data['body_onload'] ): ?> onload="<?php $this->text( 'body_onload' ) ?>"<?php endif; ?> class="mediawiki <?php $this->text( 'dir' ) ?> <?php $this->text( 'pageclass' ) ?> <?php $this->text( 'skinnameclass' ) ?>" dir="<?php $this->text( 'dir' ) ?>">
467 <div id="page-base" class="noprint"></div>
468 <div id="head-base" class="noprint"></div>
469 <!-- content -->
470 <div id="content">
471 <a id="top"></a>
472 <div id="mw-js-message" style="display:none;"></div>
473 <?php if ( $this->data['sitenotice'] ): ?>
474 <!-- sitenotice -->
475 <div id="siteNotice"><?php $this->html( 'sitenotice' ) ?></div>
476 <!-- /sitenotice -->
477 <?php endif; ?>
478 <!-- firstHeading -->
479 <h1 id="firstHeading" class="firstHeading"><?php $this->html( 'title' ) ?></h1>
480 <!-- /firstHeading -->
481 <!-- bodyContent -->
482 <div id="bodyContent">
483 <!-- tagline -->
484 <h3 id="siteSub"><?php $this->msg( 'tagline' ) ?></h3>
485 <!-- /tagline -->
486 <!-- subtitle -->
487 <div id="contentSub"><?php $this->html( 'subtitle' ) ?></div>
488 <!-- /subtitle -->
489 <?php if ( $this->data['undelete'] ): ?>
490 <!-- undelete -->
491 <div id="contentSub2"><?php $this->html( 'undelete' ) ?></div>
492 <!-- /undelete -->
493 <?php endif; ?>
494 <?php if($this->data['newtalk'] ): ?>
495 <!-- newtalk -->
496 <div class="usermessage"><?php $this->html( 'newtalk' ) ?></div>
497 <!-- /newtalk -->
498 <?php endif; ?>
499 <?php if ( $this->data['showjumplinks'] ): ?>
500 <!-- jumpto -->
501 <div id="jump-to-nav">
502 <?php $this->msg( 'jumpto' ) ?><a href="#head"><?php $this->msg( 'jumptonavigation' ) ?></a>,
503 <a href="#p-search"><?php $this->msg( 'jumptosearch' ) ?></a>
504 </div>
505 <!-- /jumpto -->
506 <?php endif; ?>
507 <!-- bodytext -->
508 <?php $this->html( 'bodytext' ) ?>
509 <!-- /bodytext -->
510 <?php if ( $this->data['catlinks'] ): ?>
511 <!-- catlinks -->
512 <?php $this->html( 'catlinks' ); ?>
513 <!-- /catlinks -->
514 <?php endif; ?>
515 <?php if ( $this->data['dataAfterContent'] ): ?>
516 <!-- dataAfterContent -->
517 <?php $this->html( 'dataAfterContent' ); ?>
518 <!-- /dataAfterContent -->
519 <?php endif; ?>
520 <div class="visualClear"></div>
521 </div>
522 <!-- /bodyContent -->
523 </div>
524 <!-- /content -->
525 <!-- header -->
526 <div id="head" class="noprint">
527 <?php $this->renderNavigation( 'PERSONAL' ); ?>
528 <div id="left-navigation">
529 <?php $this->renderNavigation( array( 'NAMESPACES', 'VARIANTS' ) ); ?>
530 </div>
531 <div id="right-navigation">
532 <?php $this->renderNavigation( array( 'VIEWS', 'ACTIONS', 'SEARCH' ) ); ?>
533 </div>
534 </div>
535 <!-- /header -->
536 <!-- panel -->
537 <div id="panel" class="noprint">
538 <!-- logo -->
539 <div id="p-logo"><a style="background-image: url(<?php $this->text( 'logopath' ) ?>);" href="<?php echo htmlspecialchars( $this->data['nav_urls']['mainpage']['href'] ) ?>" <?php echo $this->skin->tooltipAndAccesskey( 'p-logo' ) ?>></a></div>
540 <!-- /logo -->
541 <?php $this->renderPortals( $this->data['sidebar'] ); ?>
542 </div>
543 <!-- /panel -->
544 <!-- footer -->
545 <div id="footer">
546 <?php foreach( $validFooterLinks as $category => $links ): ?>
547 <?php if ( count( $links ) > 0 ): ?>
548 <ul id="footer-<?php echo $category ?>">
549 <?php foreach( $links as $link ): ?>
550 <?php if( isset( $this->data[$link] ) && $this->data[$link] ): ?>
551 <li id="footer-<?php echo $category ?>-<?php echo $link ?>"><?php $this->html( $link ) ?></li>
552 <?php endif; ?>
553 <?php endforeach; ?>
554 </ul>
555 <?php endif; ?>
556 <?php endforeach; ?>
557 <ul id="footer-icons" class="noprint">
558 <?php if ( $this->data['poweredbyico'] ): ?>
559 <li id="footer-icon-poweredby"><?php $this->html( 'poweredbyico' ) ?></li>
560 <?php endif; ?>
561 <?php if ( $this->data['copyrightico'] ): ?>
562 <li id="footer-icon-copyright"><?php $this->html( 'copyrightico' ) ?></li>
563 <?php endif; ?>
564 </ul>
565 <div style="clear:both"></div>
566 </div>
567 <!-- /footer -->
568 <!-- fixalpha -->
569 <script type="<?php $this->text('jsmimetype') ?>"> if ( window.isMSIE55 ) fixalpha(); </script>
570 <!-- /fixalpha -->
571 <?php $this->html( 'bottomscripts' ); /* JS call to runBodyOnloadHook */ ?>
572 <?php $this->html( 'reporttime' ) ?>
573 <?php if ( $this->data['debug'] ): ?>
574 <!-- Debug output: <?php $this->text( 'debug' ); ?> -->
575 <?php endif; ?>
576 </body>
577 </html>
578 <?php
579 }
580
581 /**
582 * Render a series of portals
583 */
584 private function renderPortals( $portals ) {
585 // Force the rendering of the following portals
586 if ( !isset( $portals['SEARCH'] ) ) $portals['SEARCH'] = true;
587 if ( !isset( $portals['TOOLBOX'] ) ) $portals['TOOLBOX'] = true;
588 if ( !isset( $portals['LANGUAGES'] ) ) $portals['LANGUAGES'] = true;
589 // Render portals
590 foreach ( $portals as $name => $content ) {
591 echo "\n<!-- {$name} -->\n";
592 switch( $name ) {
593 case 'SEARCH':
594 break;
595 case 'TOOLBOX':
596 ?>
597 <div class="portal" id="p-tb">
598 <h5 <?php $this->html('userlangattributes') ?>><?php $this->msg( 'toolbox' ) ?></h5>
599 <div class="body">
600 <ul>
601 <?php if( $this->data['notspecialpage'] ): ?>
602 <li id="t-whatlinkshere"><a href="<?php echo htmlspecialchars( $this->data['nav_urls']['whatlinkshere']['href'] ) ?>"<?php echo $this->skin->tooltipAndAccesskey( 't-whatlinkshere' ) ?>><?php $this->msg( 'whatlinkshere' ) ?></a></li>
603 <?php if( $this->data['nav_urls']['recentchangeslinked'] ): ?>
604 <li id="t-recentchangeslinked"><a href="<?php echo htmlspecialchars( $this->data['nav_urls']['recentchangeslinked']['href'] ) ?>"<?php echo $this->skin->tooltipAndAccesskey( 't-recentchangeslinked' ) ?>><?php $this->msg( 'recentchangeslinked-toolbox' ) ?></a></li>
605 <?php endif; ?>
606 <?php endif; ?>
607 <?php if( isset( $this->data['nav_urls']['trackbacklink'] ) ): ?>
608 <li id="t-trackbacklink"><a href="<?php echo htmlspecialchars( $this->data['nav_urls']['trackbacklink']['href'] ) ?>"<?php echo $this->skin->tooltipAndAccesskey( 't-trackbacklink' ) ?>><?php $this->msg( 'trackbacklink' ) ?></a></li>
609 <?php endif; ?>
610 <?php if( $this->data['feeds']): ?>
611 <li id="feedlinks">
612 <?php foreach( $this->data['feeds'] as $key => $feed ): ?>
613 <a id="<?php echo Sanitizer::escapeId( "feed-$key" ) ?>" href="<?php echo htmlspecialchars( $feed['href'] ) ?>" rel="alternate" type="application/<?php echo $key ?>+xml" class="feedlink"<?php echo $this->skin->tooltipAndAccesskey( 'feed-' . $key ) ?>><?php echo htmlspecialchars( $feed['text'] ) ?></a>
614 <?php endforeach; ?>
615 </li>
616 <?php endif; ?>
617 <?php foreach( array( 'contributions', 'log', 'blockip', 'emailuser', 'upload', 'specialpages' ) as $special ): ?>
618 <?php if( $this->data['nav_urls'][$special]): ?>
619 <li id="t-<?php echo $special ?>"><a href="<?php echo htmlspecialchars( $this->data['nav_urls'][$special]['href'] ) ?>"<?php echo $this->skin->tooltipAndAccesskey( 't-' . $special ) ?>><?php $this->msg( $special ) ?></a></li>
620 <?php endif; ?>
621 <?php endforeach; ?>
622 <?php if( !empty( $this->data['nav_urls']['print']['href'] ) ): ?>
623 <li id="t-print"><a href="<?php echo htmlspecialchars( $this->data['nav_urls']['print']['href'] ) ?>" rel="alternate"<?php echo $this->skin->tooltipAndAccesskey( 't-print' ) ?>><?php $this->msg( 'printableversion' ) ?></a></li>
624 <?php endif; ?>
625 <?php if ( !empty( $this->data['nav_urls']['permalink']['href'] ) ): ?>
626 <li id="t-permalink"><a href="<?php echo htmlspecialchars( $this->data['nav_urls']['permalink']['href'] ) ?>"<?php echo $this->skin->tooltipAndAccesskey( 't-permalink' ) ?>><?php $this->msg( 'permalink' ) ?></a></li>
627 <?php elseif ( $this->data['nav_urls']['permalink']['href'] === '' ): ?>
628 <li id="t-ispermalink"<?php echo $this->skin->tooltip( 't-ispermalink' ) ?>><?php $this->msg( 'permalink' ) ?></li>
629 <?php endif; ?>
630 <?php wfRunHooks( 'VectorTemplateToolboxEnd', array( &$this ) ); ?>
631 <?php wfRunHooks( 'SkinTemplateToolboxEnd', array( &$this ) ); ?>
632 </ul>
633 </div>
634 </div>
635 <?php
636 break;
637 case 'LANGUAGES':
638 if ( $this->data['language_urls'] ) {
639 ?>
640 <div class="portal" id="p-lang">
641 <h5 <?php $this->html('userlangattributes') ?>><?php $this->msg( 'otherlanguages' ) ?></h5>
642 <div class="body">
643 <ul>
644 <?php foreach ( $this->data['language_urls'] as $langlink ): ?>
645 <li class="<?php echo htmlspecialchars( $langlink['class'] ) ?>"><a href="<?php echo htmlspecialchars( $langlink['href'] ) ?>"><?php echo $langlink['text'] ?></a></li>
646 <?php endforeach; ?>
647 </ul>
648 </div>
649 </div>
650 <?php
651 }
652 break;
653 default:
654 ?>
655 <div class="portal" id='<?php echo Sanitizer::escapeId( "p-$name" ) ?>'<?php echo $this->skin->tooltip( 'p-' . $name ) ?>>
656 <h5 <?php $this->html('userlangattributes') ?>><?php $out = wfMsg( $name ); if ( wfEmptyMsg( $name, $out ) ) echo htmlspecialchars( $name ); else echo htmlspecialchars( $out ); ?></h5>
657 <div class="body">
658 <?php if ( is_array( $content ) ): ?>
659 <ul>
660 <?php foreach( $content as $key => $val ): ?>
661 <li id="<?php echo Sanitizer::escapeId( $val['id'] ) ?>"<?php if ( $val['active'] ): ?> class="active" <?php endif; ?>><a href="<?php echo htmlspecialchars( $val['href'] ) ?>"<?php echo $this->skin->tooltipAndAccesskey( $val['id'] ) ?>><?php echo htmlspecialchars( $val['text'] ) ?></a></li>
662 <?php endforeach; ?>
663 </ul>
664 <?php else: ?>
665 <?php echo $content; /* Allow raw HTML block to be defined by extensions */ ?>
666 <?php endif; ?>
667 </div>
668 </div>
669 <?php
670 break;
671 }
672 echo "\n<!-- /{$name} -->\n";
673 }
674 }
675
676 /**
677 * Render one or more navigations elements by name, automatically reveresed
678 * when UI is in RTL mode
679 */
680 private function renderNavigation( $elements ) {
681 global $wgContLang, $wgVectorUseSimpleSearch, $wgStylePath;
682
683 // If only one element was given, wrap it in an array, allowing more
684 // flexible arguments
685 if ( !is_array( $elements ) ) {
686 $elements = array( $elements );
687 // If there's a series of elements, reverse them when in RTL mode
688 } else if ( $wgContLang->isRTL() ) {
689 $elements = array_reverse( $elements );
690 }
691 // Render elements
692 foreach ( $elements as $name => $element ) {
693 echo "\n<!-- {$name} -->\n";
694 switch ( $element ) {
695 case 'NAMESPACES':
696 ?>
697 <div id="p-namespaces" class="vectorTabs<?php if ( count( $this->data['namespace_urls'] ) == 0 ) echo ' emptyPortlet'; ?>">
698 <h5><?php $this->msg('namespaces') ?></h5>
699 <ul <?php $this->html('userlangattributes') ?>>
700 <?php foreach ($this->data['namespace_urls'] as $key => $link ): ?>
701 <li <?php echo $link['attributes'] ?>><a href="<?php echo htmlspecialchars( $link['href'] ) ?>" <?php echo $link['key'] ?>><span><?php echo htmlspecialchars( $link['text'] ) ?></span></a></li>
702 <?php endforeach; ?>
703 </ul>
704 </div>
705 <?php
706 break;
707 case 'VARIANTS':
708 ?>
709 <div id="p-variants" class="vectorMenu<?php if ( count( $this->data['variant_urls'] ) == 0 ) echo ' emptyPortlet'; ?>">
710 <h5><span><?php $this->msg('variants') ?></span><a href="#"></a></h5>
711 <div class="menu">
712 <ul <?php $this->html('userlangattributes') ?>>
713 <?php foreach ($this->data['variant_urls'] as $key => $link ): ?>
714 <li<?php echo $link['attributes'] ?>><a href="<?php echo htmlspecialchars( $link['href'] ) ?>" <?php echo $link['key'] ?>><?php echo htmlspecialchars( $link['text'] ) ?></a></li>
715 <?php endforeach; ?>
716 </ul>
717 </div>
718 </div>
719 <?php
720 break;
721 case 'VIEWS':
722 ?>
723 <div id="p-views" class="vectorTabs<?php if ( count( $this->data['view_urls'] ) == 0 ) echo ' emptyPortlet'; ?>">
724 <h5><?php $this->msg('views') ?></h5>
725 <ul <?php $this->html('userlangattributes') ?>>
726 <?php foreach ($this->data['view_urls'] as $key => $link ): ?>
727 <li<?php echo $link['attributes'] ?>><a href="<?php echo htmlspecialchars( $link['href'] ) ?>" <?php echo $link['key'] ?>><?php echo (array_key_exists('img',$link) ? '<img src="'.$link['img'].'" alt="'.$link['text'].'" />' : '<span>'.htmlspecialchars( $link['text'] ).'</span>') ?></a></li>
728 <?php endforeach; ?>
729 </ul>
730 </div>
731 <?php
732 break;
733 case 'ACTIONS':
734 ?>
735 <div id="p-cactions" class="vectorMenu<?php if ( count( $this->data['action_urls'] ) == 0 ) echo ' emptyPortlet'; ?>">
736 <h5><span><?php $this->msg('actions') ?></span><a href="#"></a></h5>
737 <div class="menu">
738 <ul <?php $this->html('userlangattributes') ?>>
739 <?php foreach ($this->data['action_urls'] as $key => $link ): ?>
740 <li<?php echo $link['attributes'] ?>><a href="<?php echo htmlspecialchars( $link['href'] ) ?>" <?php echo $link['key'] ?>><?php echo htmlspecialchars( $link['text'] ) ?></a></li>
741 <?php endforeach; ?>
742 </ul>
743 </div>
744 </div>
745 <?php
746 break;
747 case 'PERSONAL':
748 ?>
749 <div id="p-personal" class="<?php if ( count( $this->data['personal_urls'] ) == 0 ) echo ' emptyPortlet'; ?>">
750 <h5><?php $this->msg('personaltools') ?></h5>
751 <ul <?php $this->html('userlangattributes') ?>>
752 <?php foreach($this->data['personal_urls'] as $key => $item): ?>
753 <li <?php echo $item['attributes'] ?>><a href="<?php echo htmlspecialchars($item['href']) ?>"<?php echo $item['key'] ?><?php if(!empty($item['class'])): ?> class="<?php echo htmlspecialchars($item['class']) ?>"<?php endif; ?>><?php echo htmlspecialchars($item['text']) ?></a></li>
754 <?php endforeach; ?>
755 </ul>
756 </div>
757 <?php
758 break;
759 case 'SEARCH':
760 ?>
761 <div id="p-search">
762 <h5 <?php $this->html('userlangattributes') ?>><label for="searchInput"><?php $this->msg( 'search' ) ?></label></h5>
763 <form action="<?php $this->text( 'wgScript' ) ?>" id="searchform">
764 <input type='hidden' name="title" value="<?php $this->text( 'searchtitle' ) ?>"/>
765 <?php if ( $wgVectorUseSimpleSearch ): ?>
766 <div id="simpleSearch">
767 <input id="searchInput" name="search" type="text" <?php echo $this->skin->tooltipAndAccesskey( 'search' ); ?> <?php if( isset( $this->data['search'] ) ): ?> value="<?php $this->text( 'search' ) ?>"<?php endif; ?> />
768 <button id="searchButton" type='submit' name='button' <?php echo $this->skin->tooltipAndAccesskey( 'search-fulltext' ); ?>>&nbsp;</button>
769 </div>
770 <?php else: ?>
771 <input id="searchInput" name="search" type="text" <?php echo $this->skin->tooltipAndAccesskey( 'search' ); ?> <?php if( isset( $this->data['search'] ) ): ?> value="<?php $this->text( 'search' ) ?>"<?php endif; ?> />
772 <input type='submit' name="go" class="searchButton" id="searchGoButton" value="<?php $this->msg( 'searcharticle' ) ?>"<?php echo $this->skin->tooltipAndAccesskey( 'search-go' ); ?> />
773 <input type="submit" name="fulltext" class="searchButton" id="mw-searchButton" value="<?php $this->msg( 'searchbutton' ) ?>"<?php echo $this->skin->tooltipAndAccesskey( 'search-fulltext' ); ?> />
774 <?php endif; ?>
775 </form>
776 </div>
777 <?php
778
779 break;
780 }
781 echo "\n<!-- /{$name} -->\n";
782 }
783 }
784 }