Index: trunk/phase3/skins/Simple.php |
— | — | @@ -18,17 +18,20 @@ |
19 | 19 | * @ingroup Skins |
20 | 20 | */ |
21 | 21 | class SkinSimple extends SkinTemplate { |
22 | | - function initPage( &$out ) { |
| 22 | + function initPage( OutputPage $out ) { |
23 | 23 | SkinTemplate::initPage( $out ); |
24 | 24 | $this->skinname = 'simple'; |
25 | 25 | $this->stylename = 'simple'; |
26 | 26 | $this->template = 'MonoBookTemplate'; |
27 | | - $this->addStyle( 'simple/main.css', 'screen' ); |
28 | | - $this->addStyle( 'simple/rtl.css', '', '', 'rtl' ); |
| 27 | + } |
29 | 28 | |
| 29 | + function setupSkinUserCss( OutputPage $out ){ |
| 30 | + $out->addStyle( 'simple/main.css', 'screen' ); |
| 31 | + $out->addStyle( 'simple/rtl.css', '', '', 'rtl' ); |
| 32 | + |
30 | 33 | } |
31 | 34 | |
32 | | - function reallyDoGetUserStyles() { |
| 35 | + function reallyGenerateUserStylesheet() { |
33 | 36 | global $wgUser; |
34 | 37 | $s = ''; |
35 | 38 | if (($undopt = $wgUser->getOption("underline")) != 2) { |
Index: trunk/phase3/skins/CologneBlue.php |
— | — | @@ -96,9 +96,8 @@ |
97 | 97 | return $s; |
98 | 98 | } |
99 | 99 | |
100 | | - function doGetUserStyles() { |
101 | | - global $wgOut; |
102 | | - $s = parent::doGetUserStyles(); |
| 100 | + function reallyGenerateUserStylesheet() { |
| 101 | + $s = parent::reallyGenerateUserStylesheet(); |
103 | 102 | $qb = $this->qbSetting(); |
104 | 103 | |
105 | 104 | if ( 2 == $qb ) { # Right |
Index: trunk/phase3/skins/Standard.php |
— | — | @@ -33,27 +33,20 @@ |
34 | 34 | /** |
35 | 35 | * |
36 | 36 | */ |
37 | | - function getUserStyles() { |
38 | | - global $wgStylePath, $wgStyleVersion; |
39 | | - $s = ''; |
| 37 | + function setupSkinUserCss( OutputPage $out ){ |
40 | 38 | if ( 3 == $this->qbSetting() ) { # Floating left |
41 | | - $s .= "<style type='text/css'>\n" . |
42 | | - "@import '{$wgStylePath}/common/quickbar.css?$wgStyleVersion';\n</style>\n"; |
| 39 | + $out->addStyle( 'common/quickbar.css' ); |
43 | 40 | } else if ( 4 == $this->qbSetting() ) { # Floating right |
44 | | - $s .= "<style type='text/css'>\n" . |
45 | | - "@import '{$wgStylePath}/common/quickbar-right.css?$wgStyleVersion';\n</style>\n"; |
| 41 | + $out->addStyle( 'common/quickbar-right.css' ); |
46 | 42 | } |
47 | | - $s .= parent::getUserStyles(); |
48 | | - return $s; |
| 43 | + parent::setupSkinUserCss( $out ); |
49 | 44 | } |
50 | 45 | |
51 | 46 | /** |
52 | 47 | * |
53 | 48 | */ |
54 | | - function doGetUserStyles() { |
55 | | - global $wgStylePath; |
56 | | - |
57 | | - $s = parent::doGetUserStyles(); |
| 49 | + function reallyGenerateUserStylesheet() { |
| 50 | + $s = parent::reallyGenerateUserStylesheet(); |
58 | 51 | $qb = $this->qbSetting(); |
59 | 52 | |
60 | 53 | if ( 2 == $qb ) { # Right |
— | — | @@ -273,7 +266,7 @@ |
274 | 267 | $id=User::idFromName($wgTitle->getText()); |
275 | 268 | $ip=User::isIP($wgTitle->getText()); |
276 | 269 | |
277 | | - if($id||$ip) { |
| 270 | + if( $id || $ip ){ |
278 | 271 | $s .= $sep . $this->userContribsLink(); |
279 | 272 | } |
280 | 273 | if( $this->showEmailUser( $id ) ) { |
— | — | @@ -302,5 +295,3 @@ |
303 | 296 | |
304 | 297 | |
305 | 298 | } |
306 | | - |
307 | | - |
Index: trunk/phase3/skins/MySkin.php |
— | — | @@ -10,20 +10,15 @@ |
11 | 11 | if( !defined( 'MEDIAWIKI' ) ) |
12 | 12 | die( -1 ); |
13 | 13 | |
14 | | -/** */ |
15 | | -require_once( dirname(__FILE__) . '/MonoBook.php' ); |
16 | | - |
17 | 14 | /** |
18 | 15 | * @todo document |
19 | 16 | * @ingroup Skins |
20 | 17 | */ |
21 | 18 | class SkinMySkin extends SkinTemplate { |
22 | | - function initPage( &$out ) { |
23 | | - SkinTemplate::initPage( $out ); |
| 19 | + function initPage( OutputPage $out ) { |
| 20 | + parent::initPage( $out ); |
24 | 21 | $this->skinname = 'myskin'; |
25 | 22 | $this->stylename = 'myskin'; |
26 | 23 | $this->template = 'MonoBookTemplate'; |
27 | 24 | } |
28 | 25 | } |
29 | | - |
30 | | - |
Index: trunk/phase3/skins/Chick.php |
— | — | @@ -18,17 +18,20 @@ |
19 | 19 | * @ingroup Skins |
20 | 20 | */ |
21 | 21 | class SkinChick extends SkinTemplate { |
22 | | - function initPage( &$out ) { |
| 22 | + function initPage( OutputPage $out ) { |
23 | 23 | SkinTemplate::initPage( $out ); |
24 | 24 | $this->skinname = 'chick'; |
25 | 25 | $this->stylename = 'chick'; |
26 | 26 | $this->template = 'MonoBookTemplate'; |
| 27 | + } |
27 | 28 | |
| 29 | + function setupSkinUserCss( OutputPage $out ){ |
| 30 | + parent::setupSkinUserCss( $out ); |
28 | 31 | // Append to the default screen common & print styles... |
29 | | - $this->addStyle( 'chick/main.css', 'screen,handheld' ); |
30 | | - $this->addStyle( 'chick/IE50Fixes.css', 'screen,handheld', 'lt IE 5.5000' ); |
31 | | - $this->addStyle( 'chick/IE55Fixes.css', 'screen,handheld', 'IE 5.5000' ); |
32 | | - $this->addStyle( 'chick/IE60Fixes.css', 'screen,handheld', 'IE 6' ); |
| 32 | + $out->addStyle( 'chick/main.css', 'screen,handheld' ); |
| 33 | + $out->addStyle( 'chick/IE50Fixes.css', 'screen,handheld', 'lt IE 5.5000' ); |
| 34 | + $out->addStyle( 'chick/IE55Fixes.css', 'screen,handheld', 'IE 5.5000' ); |
| 35 | + $out->addStyle( 'chick/IE60Fixes.css', 'screen,handheld', 'IE 6' ); |
33 | 36 | } |
34 | 37 | } |
35 | 38 | |
Index: trunk/phase3/skins/MonoBook.php |
— | — | @@ -20,27 +20,32 @@ |
21 | 21 | */ |
22 | 22 | class SkinMonoBook extends SkinTemplate { |
23 | 23 | /** Using monobook. */ |
24 | | - function initPage( &$out ) { |
25 | | - global $wgHandheldStyle; |
26 | | - |
27 | | - SkinTemplate::initPage( $out ); |
| 24 | + function initPage( OutputPage $out ) { |
| 25 | + parent::initPage( $out ); |
28 | 26 | $this->skinname = 'monobook'; |
29 | 27 | $this->stylename = 'monobook'; |
30 | 28 | $this->template = 'MonoBookTemplate'; |
31 | 29 | |
| 30 | + } |
| 31 | + |
| 32 | + function setupSkinUserCss( OutputPage $out ) { |
| 33 | + global $wgHandheldStyle; |
| 34 | + |
| 35 | + parent::setupSkinUserCss( $out ); |
| 36 | + |
32 | 37 | // Append to the default screen common & print styles... |
33 | | - $this->addStyle( 'monobook/main.css', 'screen' ); |
| 38 | + $out->addStyle( 'monobook/main.css', 'screen' ); |
34 | 39 | if( $wgHandheldStyle ) { |
35 | 40 | // Currently in testing... try 'chick/main.css' |
36 | | - $this->addStyle( $wgHandheldStyle, 'handheld' ); |
| 41 | + $out->addStyle( $wgHandheldStyle, 'handheld' ); |
37 | 42 | } |
38 | 43 | |
39 | | - $this->addStyle( 'monobook/IE50Fixes.css', 'screen', 'lt IE 5.5000' ); |
40 | | - $this->addStyle( 'monobook/IE55Fixes.css', 'screen', 'IE 5.5000' ); |
41 | | - $this->addStyle( 'monobook/IE60Fixes.css', 'screen', 'IE 6' ); |
42 | | - $this->addStyle( 'monobook/IE70Fixes.css', 'screen', 'IE 7' ); |
| 44 | + $out->addStyle( 'monobook/IE50Fixes.css', 'screen', 'lt IE 5.5000' ); |
| 45 | + $out->addStyle( 'monobook/IE55Fixes.css', 'screen', 'IE 5.5000' ); |
| 46 | + $out->addStyle( 'monobook/IE60Fixes.css', 'screen', 'IE 6' ); |
| 47 | + $out->addStyle( 'monobook/IE70Fixes.css', 'screen', 'IE 7' ); |
43 | 48 | |
44 | | - $this->addStyle( 'monobook/rtl.css', 'screen', '', 'rtl' ); |
| 49 | + $out->addStyle( 'monobook/rtl.css', 'screen', '', 'rtl' ); |
45 | 50 | } |
46 | 51 | } |
47 | 52 | |
Index: trunk/phase3/skins/Modern.php |
— | — | @@ -25,16 +25,19 @@ |
26 | 26 | return "<div class='mw_poweredby'>Powered by MediaWiki $wgVersion</div>"; |
27 | 27 | } |
28 | 28 | |
29 | | - function initPage( &$out ) { |
30 | | - Skin::initPage( $out ); |
| 29 | + function initPage( OutputPage $out ) { |
| 30 | + parent::initPage( $out ); |
31 | 31 | $this->skinname = 'modern'; |
32 | 32 | $this->stylename = 'modern'; |
33 | 33 | $this->template = 'ModernTemplate'; |
34 | | - |
35 | | - $this->addStyle( 'common/shared.css', 'screen' ); |
36 | | - $this->addStyle( 'modern/main.css', 'screen' ); |
37 | | - $this->addStyle( 'modern/print.css', 'print' ); |
38 | 34 | } |
| 35 | + |
| 36 | + function setupSkinUserCss( OutputPage $out ){ |
| 37 | + // Do not call parent::setupSkinUserCss(), we have our own print style |
| 38 | + $out->addStyle( 'common/shared.css', 'screen' ); |
| 39 | + $out->addStyle( 'modern/main.css', 'screen' ); |
| 40 | + $out->addStyle( 'modern/print.css', 'print' ); |
| 41 | + } |
39 | 42 | } |
40 | 43 | |
41 | 44 | /** |
Index: trunk/phase3/includes/OutputPage.php |
— | — | @@ -35,6 +35,13 @@ |
36 | 36 | var $mSquidMaxage = 0; |
37 | 37 | var $mRevisionId = null; |
38 | 38 | |
| 39 | + /** |
| 40 | + * An array of stylesheet filenames (relative from skins path), with options |
| 41 | + * for CSS media, IE conditions, and RTL/LTR direction. |
| 42 | + * For internal use; add settings in the skin via $this->addStyle() |
| 43 | + */ |
| 44 | + var $styles = array(); |
| 45 | + |
39 | 46 | private $mIndexPolicy = 'index'; |
40 | 47 | private $mFollowPolicy = 'follow'; |
41 | 48 | |
— | — | @@ -65,18 +72,19 @@ |
66 | 73 | */ |
67 | 74 | function setStatusCode( $statusCode ) { $this->mStatusCode = $statusCode; } |
68 | 75 | |
69 | | - # To add an http-equiv meta tag, precede the name with "http:" |
70 | | - function addMeta( $name, $val ) { array_push( $this->mMetatags, array( $name, $val ) ); } |
| 76 | + /** |
| 77 | + * Add a new <meta> tag |
| 78 | + * To add an http-equiv meta tag, precede the name with "http:" |
| 79 | + * |
| 80 | + * @param $name tag name |
| 81 | + * @param $val tag value |
| 82 | + */ |
| 83 | + function addMeta( $name, $val ) { |
| 84 | + array_push( $this->mMetatags, array( $name, $val ) ); |
| 85 | + } |
| 86 | + |
71 | 87 | function addKeyword( $text ) { array_push( $this->mKeywords, $text ); } |
72 | 88 | function addScript( $script ) { $this->mScripts .= "\t\t".$script; } |
73 | | - function addStyle( $style ) { |
74 | | - global $wgStylePath, $wgStyleVersion; |
75 | | - $this->addLink( |
76 | | - array( |
77 | | - 'rel' => 'stylesheet', |
78 | | - 'href' => $wgStylePath . '/' . $style . '?' . $wgStyleVersion, |
79 | | - 'type' => 'text/css' ) ); |
80 | | - } |
81 | 89 | |
82 | 90 | function addExtensionStyle( $url ) { |
83 | 91 | $linkarr = array( 'rel' => 'stylesheet', 'href' => $url, 'type' => 'text/css' ); |
— | — | @@ -1382,15 +1390,19 @@ |
1383 | 1391 | /** |
1384 | 1392 | * @return string The doctype, opening <html>, and head element. |
1385 | 1393 | */ |
1386 | | - public function headElement() { |
| 1394 | + public function headElement( Skin $sk ) { |
1387 | 1395 | global $wgDocType, $wgDTD, $wgContLanguageCode, $wgOutputEncoding, $wgMimeType; |
1388 | 1396 | global $wgXhtmlDefaultNamespace, $wgXhtmlNamespaces; |
1389 | 1397 | global $wgUser, $wgContLang, $wgUseTrackbacks, $wgTitle, $wgStyleVersion; |
1390 | 1398 | |
| 1399 | + $this->addMeta( "http:Content-type", "$wgMimeType; charset={$wgOutputEncoding}" ); |
| 1400 | + $this->addStyle( 'common/wikiprintable.css', 'print' ); |
| 1401 | + $sk->setupUserCss( $this ); |
| 1402 | + |
| 1403 | + $ret = ''; |
| 1404 | + |
1391 | 1405 | if( $wgMimeType == 'text/xml' || $wgMimeType == 'application/xhtml+xml' || $wgMimeType == 'application/xml' ) { |
1392 | | - $ret = "<?xml version=\"1.0\" encoding=\"$wgOutputEncoding\" ?>\n"; |
1393 | | - } else { |
1394 | | - $ret = ''; |
| 1406 | + $ret .= "<?xml version=\"1.0\" encoding=\"$wgOutputEncoding\" ?>\n"; |
1395 | 1407 | } |
1396 | 1408 | |
1397 | 1409 | $ret .= "<!DOCTYPE html PUBLIC \"$wgDocType\"\n \"$wgDTD\">\n"; |
— | — | @@ -1405,30 +1417,18 @@ |
1406 | 1418 | $ret .= "xmlns:{$tag}=\"{$ns}\" "; |
1407 | 1419 | } |
1408 | 1420 | $ret .= "xml:lang=\"$wgContLanguageCode\" lang=\"$wgContLanguageCode\" $rtl>\n"; |
1409 | | - $ret .= "<head>\n<title>" . htmlspecialchars( $this->getHTMLTitle() ) . "</title>\n"; |
1410 | | - $this->addMeta( "http:Content-type", "$wgMimeType; charset={$wgOutputEncoding}" ); |
1411 | | - |
1412 | | - $ret .= $this->getHeadLinks(); |
1413 | | - global $wgStylePath; |
1414 | | - if( $this->isPrintable() ) { |
1415 | | - $media = ''; |
1416 | | - } else { |
1417 | | - $media = "media='print'"; |
| 1421 | + $ret .= "<head>\n<title>" . htmlspecialchars( $this->getHTMLTitle() ) . "</title>\n\t\t"; |
| 1422 | + $ret .= implode( "\t\t", array( |
| 1423 | + $this->getHeadLinks(), |
| 1424 | + $this->buildCssLinks(), |
| 1425 | + $sk->getHeadScripts( $this->mAllowUserJs ), |
| 1426 | + $this->mScripts, |
| 1427 | + $this->getHeadItems(), |
| 1428 | + )); |
| 1429 | + if( $sk->usercss ){ |
| 1430 | + $ret .= "<style type='text/css'>{$sk->usercss}</style>"; |
1418 | 1431 | } |
1419 | | - $printsheet = htmlspecialchars( "$wgStylePath/common/wikiprintable.css?$wgStyleVersion" ); |
1420 | | - $ret .= "<link rel='stylesheet' type='text/css' $media href='$printsheet' />\n"; |
1421 | 1432 | |
1422 | | - $sk = $wgUser->getSkin(); |
1423 | | - // Load order here is key |
1424 | | - $ret .= $sk->getHeadScripts( $this->mAllowUserJs ); |
1425 | | - $ret .= $this->mScripts; |
1426 | | - $ret .= $sk->getSiteStyles(); |
1427 | | - foreach( $this->mExtStyles as $tag ) { |
1428 | | - $ret .= Xml::element( 'link', $tag ) . "\n"; |
1429 | | - } |
1430 | | - $ret .= $sk->getUserStyles(); |
1431 | | - $ret .= $this->getHeadItems(); |
1432 | | - |
1433 | 1433 | if ($wgUseTrackbacks && $this->isArticleRelated()) |
1434 | 1434 | $ret .= $wgTitle->trackbackRDF(); |
1435 | 1435 | |
— | — | @@ -1565,6 +1565,118 @@ |
1566 | 1566 | } |
1567 | 1567 | |
1568 | 1568 | /** |
| 1569 | + * Add a local or specified stylesheet, with the given media options. |
| 1570 | + * Meant primarily for internal use... |
| 1571 | + * |
| 1572 | + * @param $media -- to specify a media type, 'screen', 'printable', 'handheld' or any. |
| 1573 | + * @param $conditional -- for IE conditional comments, specifying an IE version |
| 1574 | + * @param $dir -- set to 'rtl' or 'ltr' for direction-specific sheets |
| 1575 | + */ |
| 1576 | + public function addStyle( $style, $media='', $condition='', $dir='' ) { |
| 1577 | + $options = array(); |
| 1578 | + if( $media ) |
| 1579 | + $options['media'] = $media; |
| 1580 | + if( $condition ) |
| 1581 | + $options['condition'] = $condition; |
| 1582 | + if( $dir ) |
| 1583 | + $options['dir'] = $dir; |
| 1584 | + $this->styles[$style] = $options; |
| 1585 | + } |
| 1586 | + |
| 1587 | + /** |
| 1588 | + * Build a set of <link>s for the stylesheets specified in the $this->styles array. |
| 1589 | + * These will be applied to various media & IE conditionals. |
| 1590 | + */ |
| 1591 | + public function buildCssLinks() { |
| 1592 | + $links = array(); |
| 1593 | + foreach( $this->styles as $file => $options ) { |
| 1594 | + $link = $this->styleLink( $file, $options ); |
| 1595 | + if( $link ) |
| 1596 | + $links[] = $link; |
| 1597 | + } |
| 1598 | + |
| 1599 | + return implode( "\n\t\t", $links ); |
| 1600 | + } |
| 1601 | + |
| 1602 | + protected function styleLink( $style, $options ) { |
| 1603 | + global $wgRequest; |
| 1604 | + |
| 1605 | + if( isset( $options['dir'] ) ) { |
| 1606 | + global $wgContLang; |
| 1607 | + $siteDir = $wgContLang->isRTL() ? 'rtl' : 'ltr'; |
| 1608 | + if( $siteDir != $options['dir'] ) |
| 1609 | + return ''; |
| 1610 | + } |
| 1611 | + |
| 1612 | + if( isset( $options['media'] ) ) { |
| 1613 | + $media = $this->transformCssMedia( $options['media'] ); |
| 1614 | + if( is_null( $media ) ) { |
| 1615 | + return ''; |
| 1616 | + } |
| 1617 | + } else { |
| 1618 | + $media = ''; |
| 1619 | + } |
| 1620 | + |
| 1621 | + if( substr( $style, 0, 1 ) == '/' || |
| 1622 | + substr( $style, 0, 5 ) == 'http:' || |
| 1623 | + substr( $style, 0, 6 ) == 'https:' ) { |
| 1624 | + $url = $style; |
| 1625 | + } else { |
| 1626 | + global $wgStylePath, $wgStyleVersion; |
| 1627 | + $url = $wgStylePath . '/' . $style . '?' . $wgStyleVersion; |
| 1628 | + } |
| 1629 | + |
| 1630 | + $attribs = array( |
| 1631 | + 'rel' => 'stylesheet', |
| 1632 | + 'href' => $url, |
| 1633 | + 'type' => 'text/css' ); |
| 1634 | + if( $media ) { |
| 1635 | + $attribs['media'] = $media; |
| 1636 | + } |
| 1637 | + |
| 1638 | + $link = Xml::element( 'link', $attribs ); |
| 1639 | + |
| 1640 | + if( isset( $options['condition'] ) ) { |
| 1641 | + $condition = htmlspecialchars( $options['condition'] ); |
| 1642 | + $link = "<!--[if $condition]>$link<![endif]-->"; |
| 1643 | + } |
| 1644 | + return $link; |
| 1645 | + } |
| 1646 | + |
| 1647 | + function transformCssMedia( $media ) { |
| 1648 | + global $wgRequest, $wgHandheldForIPhone; |
| 1649 | + |
| 1650 | + // Switch in on-screen display for media testing |
| 1651 | + $switches = array( |
| 1652 | + 'printable' => 'print', |
| 1653 | + 'handheld' => 'handheld', |
| 1654 | + ); |
| 1655 | + foreach( $switches as $switch => $targetMedia ) { |
| 1656 | + if( $wgRequest->getBool( $switch ) ) { |
| 1657 | + if( $media == $targetMedia ) { |
| 1658 | + $media = ''; |
| 1659 | + } elseif( $media == 'screen' ) { |
| 1660 | + return null; |
| 1661 | + } |
| 1662 | + } |
| 1663 | + } |
| 1664 | + |
| 1665 | + // Expand longer media queries as iPhone doesn't grok 'handheld' |
| 1666 | + if( $wgHandheldForIPhone ) { |
| 1667 | + $mediaAliases = array( |
| 1668 | + 'screen' => 'screen and (min-device-width: 481px)', |
| 1669 | + 'handheld' => 'handheld, only screen and (max-device-width: 480px)', |
| 1670 | + ); |
| 1671 | + |
| 1672 | + if( isset( $mediaAliases[$media] ) ) { |
| 1673 | + $media = $mediaAliases[$media]; |
| 1674 | + } |
| 1675 | + } |
| 1676 | + |
| 1677 | + return $media; |
| 1678 | + } |
| 1679 | + |
| 1680 | + /** |
1569 | 1681 | * Turn off regular page output and return an error reponse |
1570 | 1682 | * for when rate limiting has triggered. |
1571 | 1683 | */ |
Index: trunk/phase3/includes/RawPage.php |
— | — | @@ -163,11 +163,13 @@ |
164 | 164 | global $wgUser, $wgOut, $wgRequest; |
165 | 165 | if($this->mGen) { |
166 | 166 | $sk = $wgUser->getSkin(); |
167 | | - $sk->initPage($wgOut); |
| 167 | + if( !StubObject::isRealObject( $wgOut ) ) |
| 168 | + $wgOut->_unstub( 2 ); |
| 169 | + $sk->initPage( $wgOut ); |
168 | 170 | if($this->mGen == 'css') { |
169 | | - return $sk->getUserStylesheet(); |
| 171 | + return $sk->generateUserStylesheet(); |
170 | 172 | } else if($this->mGen == 'js') { |
171 | | - return $sk->getUserJs(); |
| 173 | + return $sk->generateUserJs(); |
172 | 174 | } |
173 | 175 | } else { |
174 | 176 | return $this->getArticleText(); |
Index: trunk/phase3/includes/SkinTemplate.php |
— | — | @@ -87,13 +87,6 @@ |
88 | 88 | */ |
89 | 89 | var $template; |
90 | 90 | |
91 | | - /** |
92 | | - * An array of stylesheet filenames (relative from skins path), with options |
93 | | - * for CSS media, IE conditions, and RTL/LTR direction. |
94 | | - * For internal use; add settings in the skin via $this->addStyle() |
95 | | - */ |
96 | | - var $styles = array(); |
97 | | - |
98 | 91 | /**#@-*/ |
99 | 92 | |
100 | 93 | /** |
— | — | @@ -101,16 +94,23 @@ |
102 | 95 | * Child classes should override this to set the name, |
103 | 96 | * style subdirectory, and template filler callback. |
104 | 97 | * |
105 | | - * @param OutputPage $out |
| 98 | + * @param $out OutputPage |
106 | 99 | */ |
107 | | - function initPage( &$out ) { |
| 100 | + function initPage( OutputPage $out ) { |
108 | 101 | parent::initPage( $out ); |
109 | 102 | $this->skinname = 'monobook'; |
110 | 103 | $this->stylename = 'monobook'; |
111 | 104 | $this->template = 'QuickTemplate'; |
| 105 | + } |
112 | 106 | |
113 | | - $this->addStyle( 'common/shared.css', 'screen' ); |
114 | | - $this->addStyle( 'common/commonPrint.css', 'print' ); |
| 107 | + /** |
| 108 | + * Add specific styles for this skin |
| 109 | + * |
| 110 | + * @param $out OutputPage |
| 111 | + */ |
| 112 | + function setupSkinUserCss( OutputPage $out ){ |
| 113 | + $out->addStyle( 'common/shared.css', 'screen' ); |
| 114 | + $out->addStyle( 'common/commonPrint.css', 'print' ); |
115 | 115 | } |
116 | 116 | |
117 | 117 | /** |
— | — | @@ -118,9 +118,9 @@ |
119 | 119 | * and eventually it spits out some HTML. Should have interface |
120 | 120 | * roughly equivalent to PHPTAL 0.7. |
121 | 121 | * |
122 | | - * @param string $callback (or file) |
123 | | - * @param string $repository subdirectory where we keep template files |
124 | | - * @param string $cache_dir |
| 122 | + * @param $callback string (or file) |
| 123 | + * @param $repository string: subdirectory where we keep template files |
| 124 | + * @param $cache_dir string |
125 | 125 | * @return object |
126 | 126 | * @private |
127 | 127 | */ |
— | — | @@ -131,11 +131,10 @@ |
132 | 132 | /** |
133 | 133 | * initialize various variables and generate the template |
134 | 134 | * |
135 | | - * @param OutputPage $out |
136 | | - * @public |
| 135 | + * @param $out OutputPage |
137 | 136 | */ |
138 | | - function outputPage( &$out ) { |
139 | | - global $wgTitle, $wgArticle, $wgUser, $wgLang, $wgContLang, $wgOut; |
| 137 | + function outputPage( OutputPage $out ) { |
| 138 | + global $wgTitle, $wgArticle, $wgUser, $wgLang, $wgContLang; |
140 | 139 | global $wgScript, $wgStylePath, $wgContLanguageCode; |
141 | 140 | global $wgMimeType, $wgJsMimeType, $wgOutputEncoding, $wgRequest; |
142 | 141 | global $wgXhtmlDefaultNamespace, $wgXhtmlNamespaces; |
— | — | @@ -153,9 +152,7 @@ |
154 | 153 | wfProfileIn( __METHOD__."-init" ); |
155 | 154 | $this->initPage( $out ); |
156 | 155 | |
157 | | - $this->mTitle =& $wgTitle; |
158 | | - $this->mUser =& $wgUser; |
159 | | - |
| 156 | + $this->setMembers(); |
160 | 157 | $tpl = $this->setupTemplate( $this->template, 'skins' ); |
161 | 158 | |
162 | 159 | #if ( $wgUseDatabaseMessages ) { // uncomment this to fall back to GetText |
— | — | @@ -170,8 +167,6 @@ |
171 | 168 | $this->iscontent = ($this->mTitle->getNamespace() != NS_SPECIAL ); |
172 | 169 | $this->iseditable = ($this->iscontent and !($action == 'edit' or $action == 'submit')); |
173 | 170 | $this->username = $wgUser->getName(); |
174 | | - $userPage = $wgUser->getUserPage(); |
175 | | - $this->userpage = $userPage->getPrefixedText(); |
176 | 171 | |
177 | 172 | if ( $wgUser->isLoggedIn() || $this->showIPinHeader() ) { |
178 | 173 | $this->userpageUrlDetails = self::makeUrlDetails( $this->userpage ); |
— | — | @@ -181,16 +176,16 @@ |
182 | 177 | $this->userpageUrlDetails = self::makeKnownUrlDetails( $this->userpage ); |
183 | 178 | } |
184 | 179 | |
185 | | - $this->usercss = $this->userjs = $this->userjsprev = false; |
186 | | - $this->setupUserCss( $out->getExtStyle() ); |
| 180 | + $this->userjs = $this->userjsprev = false; |
| 181 | + $this->setupUserCss( $out ); |
187 | 182 | $this->setupUserJs( $out->isUserJsAllowed() ); |
188 | 183 | $this->titletxt = $this->mTitle->getPrefixedText(); |
189 | 184 | wfProfileOut( __METHOD__."-stuff" ); |
190 | 185 | |
191 | 186 | wfProfileIn( __METHOD__."-stuff2" ); |
192 | | - $tpl->set( 'title', $wgOut->getPageTitle() ); |
193 | | - $tpl->set( 'pagetitle', $wgOut->getHTMLTitle() ); |
194 | | - $tpl->set( 'displaytitle', $wgOut->mPageLinkTitle ); |
| 187 | + $tpl->set( 'title', $out->getPageTitle() ); |
| 188 | + $tpl->set( 'pagetitle', $out->getHTMLTitle() ); |
| 189 | + $tpl->set( 'displaytitle', $out->mPageLinkTitle ); |
195 | 190 | $tpl->set( 'pageclass', $this->getPageClasses( $this->mTitle ) ); |
196 | 191 | $tpl->set( 'skinnameclass', ( "skin-" . Sanitizer::escapeClass( $this->getSkinName ( ) ) ) ); |
197 | 192 | |
— | — | @@ -205,7 +200,7 @@ |
206 | 201 | $tpl->set( 'articleid', $this->mTitle->getArticleId() ); |
207 | 202 | $tpl->set( 'currevisionid', isset( $wgArticle ) ? $wgArticle->getLatest() : 0 ); |
208 | 203 | |
209 | | - $tpl->set( 'isarticle', $wgOut->isArticle() ); |
| 204 | + $tpl->set( 'isarticle', $out->isArticle() ); |
210 | 205 | |
211 | 206 | $tpl->setRef( "thispage", $this->thispage ); |
212 | 207 | $subpagestr = $this->subPageSubtitle(); |
— | — | @@ -222,9 +217,9 @@ |
223 | 218 | ); |
224 | 219 | |
225 | 220 | $tpl->set( 'catlinks', $this->getCategories()); |
226 | | - if( $wgOut->isSyndicated() ) { |
| 221 | + if( $out->isSyndicated() ) { |
227 | 222 | $feeds = array(); |
228 | | - foreach( $wgOut->getSyndicationLinks() as $format => $link ) { |
| 223 | + foreach( $out->getSyndicationLinks() as $format => $link ) { |
229 | 224 | $feeds[$format] = array( |
230 | 225 | 'text' => wfMsg( "feed-$format" ), |
231 | 226 | 'href' => $link ); |
— | — | @@ -245,14 +240,14 @@ |
246 | 241 | $tpl->setRef( 'jsmimetype', $wgJsMimeType ); |
247 | 242 | $tpl->setRef( 'charset', $wgOutputEncoding ); |
248 | 243 | $tpl->set( 'headlinks', $out->getHeadLinks() ); |
249 | | - $tpl->set('headscripts', $out->getScript() ); |
| 244 | + $tpl->set( 'headscripts', $out->getScript() ); |
| 245 | + $tpl->set( 'csslinks', $out->buildCssLinks() ); |
250 | 246 | $tpl->setRef( 'wgScript', $wgScript ); |
251 | 247 | $tpl->setRef( 'skinname', $this->skinname ); |
252 | 248 | $tpl->set( 'skinclass', get_class( $this ) ); |
253 | 249 | $tpl->setRef( 'stylename', $this->stylename ); |
254 | 250 | $tpl->set( 'printable', $wgRequest->getBool( 'printable' ) ); |
255 | 251 | $tpl->set( 'handheld', $wgRequest->getBool( 'handheld' ) ); |
256 | | - $tpl->set( 'csslinks', $this->buildCssLinks() ); |
257 | 252 | $tpl->setRef( 'loggedin', $this->loggedin ); |
258 | 253 | $tpl->set('notspecialpage', $this->mTitle->getNamespace() != NS_SPECIAL); |
259 | 254 | /* XXX currently unused, might get useful later |
— | — | @@ -310,7 +305,7 @@ |
311 | 306 | ) |
312 | 307 | ); |
313 | 308 | # Disable Cache |
314 | | - $wgOut->setSquidMaxage(0); |
| 309 | + $out->setSquidMaxage(0); |
315 | 310 | } |
316 | 311 | } else if (count($newtalks)) { |
317 | 312 | $sep = str_replace("_", " ", wfMsgHtml("newtalkseperator")); |
— | — | @@ -321,7 +316,7 @@ |
322 | 317 | } |
323 | 318 | $parts = implode($sep, $msgs); |
324 | 319 | $ntl = wfMsgHtml('youhavenewmessagesmulti', $parts); |
325 | | - $wgOut->setSquidMaxage(0); |
| 320 | + $out->setSquidMaxage(0); |
326 | 321 | } else { |
327 | 322 | $ntl = ''; |
328 | 323 | } |
— | — | @@ -331,7 +326,7 @@ |
332 | 327 | $tpl->setRef( 'newtalk', $ntl ); |
333 | 328 | $tpl->setRef( 'skin', $this ); |
334 | 329 | $tpl->set( 'logo', $this->logoText() ); |
335 | | - if ( $wgOut->isArticle() and (!isset( $oldid ) or isset( $diff )) and |
| 330 | + if ( $out->isArticle() and (!isset( $oldid ) or isset( $diff )) and |
336 | 331 | $wgArticle and 0 != $wgArticle->getID() ) |
337 | 332 | { |
338 | 333 | if ( !$wgDisableCounters ) { |
— | — | @@ -413,7 +408,7 @@ |
414 | 409 | $language_urls = array(); |
415 | 410 | |
416 | 411 | if ( !$wgHideInterlanguageLinks ) { |
417 | | - foreach( $wgOut->getLanguageLinks() as $l ) { |
| 412 | + foreach( $out->getLanguageLinks() as $l ) { |
418 | 413 | $tmp = explode( ':', $l, 2 ); |
419 | 414 | $class = 'interwiki-' . $tmp[0]; |
420 | 415 | unset($tmp); |
— | — | @@ -650,7 +645,7 @@ |
651 | 646 | * @return array |
652 | 647 | * @private |
653 | 648 | */ |
654 | | - function buildContentActionUrls () { |
| 649 | + function buildContentActionUrls() { |
655 | 650 | global $wgContLang, $wgLang, $wgOut; |
656 | 651 | wfProfileIn( __METHOD__ ); |
657 | 652 | |
— | — | @@ -846,7 +841,7 @@ |
847 | 842 | * @return array |
848 | 843 | * @private |
849 | 844 | */ |
850 | | - function buildNavUrls () { |
| 845 | + function buildNavUrls() { |
851 | 846 | global $wgUseTrackbacks, $wgTitle, $wgUser, $wgRequest; |
852 | 847 | global $wgEnableUploads, $wgUploadNavigationUrl; |
853 | 848 | |
— | — | @@ -961,77 +956,13 @@ |
962 | 957 | * @return string |
963 | 958 | * @private |
964 | 959 | */ |
965 | | - function getNameSpaceKey () { |
| 960 | + function getNameSpaceKey() { |
966 | 961 | return $this->mTitle->getNamespaceKey(); |
967 | 962 | } |
968 | 963 | |
969 | 964 | /** |
970 | 965 | * @private |
971 | 966 | */ |
972 | | - function setupUserCss( $extCSS = array() ) { |
973 | | - global $wgRequest, $wgAllowUserCss, $wgUseSiteCss, $wgContLang, $wgSquidMaxage, $wgStylePath, $wgUser; |
974 | | - |
975 | | - wfProfileIn( __METHOD__ ); |
976 | | - |
977 | | - $siteargs = array( |
978 | | - 'action' => 'raw', |
979 | | - 'maxage' => $wgSquidMaxage, |
980 | | - ); |
981 | | - if( $this->loggedin ) { |
982 | | - // Ensure that logged-in users' generated CSS isn't clobbered |
983 | | - // by anons' publicly cacheable generated CSS. |
984 | | - $siteargs['smaxage'] = '0'; |
985 | | - $siteargs['ts'] = $wgUser->mTouched; |
986 | | - } |
987 | | - |
988 | | - // Add any extension CSS |
989 | | - foreach( $extCSS as $tag ) { |
990 | | - $this->addStyle( $tag['href'] ); |
991 | | - } |
992 | | - |
993 | | - // If we use the site's dynamic CSS, throw that in, too |
994 | | - // Per-site custom styles |
995 | | - if ( $wgUseSiteCss ) { |
996 | | - $query = wfArrayToCGI( array( |
997 | | - 'usemsgcache' => 'yes', |
998 | | - 'ctype' => 'text/css', |
999 | | - 'smaxage' => $wgSquidMaxage |
1000 | | - ) + $siteargs ); |
1001 | | - $this->addStyle( self::makeNSUrl( 'Common.css', $query, NS_MEDIAWIKI ) ); |
1002 | | - $this->addStyle( self::makeNSUrl( ucfirst( $this->skinname ) . '.css', $query, NS_MEDIAWIKI ), |
1003 | | - 'screen' ); |
1004 | | - } |
1005 | | - |
1006 | | - // Per-user styles based on preferences |
1007 | | - $siteargs['gen'] = 'css'; |
1008 | | - if( ( $us = $wgRequest->getVal( 'useskin', '' ) ) !== '' ) |
1009 | | - $siteargs['useskin'] = $us; |
1010 | | - $this->addStyle( self::makeUrl( '-', wfArrayToCGI( $siteargs ) ), 'screen' ); |
1011 | | - |
1012 | | - // Per-user custom style pages |
1013 | | - if ( $wgAllowUserCss && $this->loggedin ) { |
1014 | | - $action = $wgRequest->getVal('action'); |
1015 | | - |
1016 | | - # if we're previewing the CSS page, use it |
1017 | | - if( $this->mTitle->isCssSubpage() && $this->userCanPreview( $action ) ) { |
1018 | | - $previewCss = $wgRequest->getText('wpTextbox1'); |
1019 | | - |
1020 | | - /// @fixme properly escape the cdata! |
1021 | | - $this->usercss = "/*<![CDATA[*/\n" . |
1022 | | - $previewCss . |
1023 | | - "/*]]>*/"; |
1024 | | - } else { |
1025 | | - $this->addStyle( self::makeUrl($this->userpage . '/'.$this->skinname.'.css', |
1026 | | - 'action=raw&ctype=text/css'), 'screen' ); |
1027 | | - } |
1028 | | - } |
1029 | | - |
1030 | | - wfProfileOut( __METHOD__ ); |
1031 | | - } |
1032 | | - |
1033 | | - /** |
1034 | | - * @private |
1035 | | - */ |
1036 | 967 | function setupUserJs( $allowUserJs ) { |
1037 | 968 | wfProfileIn( __METHOD__ ); |
1038 | 969 | |
— | — | @@ -1059,165 +990,9 @@ |
1060 | 991 | wfProfileIn( __METHOD__ ); |
1061 | 992 | $out = false; |
1062 | 993 | wfRunHooks( 'SkinTemplateSetupPageCss', array( &$out ) ); |
1063 | | - |
1064 | 994 | wfProfileOut( __METHOD__ ); |
1065 | 995 | return $out; |
1066 | 996 | } |
1067 | | - |
1068 | | - /** |
1069 | | - * returns css with user-specific options |
1070 | | - */ |
1071 | | - public function getUserStylesheet() { |
1072 | | - wfProfileIn( __METHOD__ ); |
1073 | | - |
1074 | | - $s = "/* generated user stylesheet */\n"; |
1075 | | - $s .= $this->reallyDoGetUserStyles(); |
1076 | | - wfProfileOut( __METHOD__ ); |
1077 | | - return $s; |
1078 | | - } |
1079 | | - |
1080 | | - /** |
1081 | | - * This returns MediaWiki:Common.js and MediaWiki:[Skinname].js concate- |
1082 | | - * nated together. For some bizarre reason, it does *not* return any |
1083 | | - * custom user JS from subpages. Huh? |
1084 | | - * |
1085 | | - * There's absolutely no reason to have separate Monobook/Common JSes. |
1086 | | - * Any JS that cares can just check the skin variable generated at the |
1087 | | - * top. For now Monobook.js will be maintained, but it should be consi- |
1088 | | - * dered deprecated. |
1089 | | - * |
1090 | | - * @return string |
1091 | | - */ |
1092 | | - public function getUserJs() { |
1093 | | - wfProfileIn( __METHOD__ ); |
1094 | | - |
1095 | | - $s = parent::getUserJs(); |
1096 | | - $s .= "\n\n/* MediaWiki:".ucfirst($this->skinname).".js */\n"; |
1097 | | - |
1098 | | - // avoid inclusion of non defined user JavaScript (with custom skins only) |
1099 | | - // by checking for default message content |
1100 | | - $msgKey = ucfirst($this->skinname).'.js'; |
1101 | | - $userJS = wfMsgForContent($msgKey); |
1102 | | - if ( !wfEmptyMsg( $msgKey, $userJS ) ) { |
1103 | | - $s .= $userJS; |
1104 | | - } |
1105 | | - |
1106 | | - wfProfileOut( __METHOD__ ); |
1107 | | - return $s; |
1108 | | - } |
1109 | | - |
1110 | | - /** |
1111 | | - * Add a local or specified stylesheet, with the given media options. |
1112 | | - * Meant primarily for internal use... |
1113 | | - * |
1114 | | - * @param $media -- to specify a media type, 'screen', 'printable', 'handheld' or any. |
1115 | | - * @param $conditional -- for IE conditional comments, specifying an IE version |
1116 | | - * @param $dir -- set to 'rtl' or 'ltr' for direction-specific sheets |
1117 | | - */ |
1118 | | - public function addStyle( $style, $media='', $condition='', $dir='' ) { |
1119 | | - $options = array(); |
1120 | | - if( $media ) |
1121 | | - $options['media'] = $media; |
1122 | | - if( $condition ) |
1123 | | - $options['condition'] = $condition; |
1124 | | - if( $dir ) |
1125 | | - $options['dir'] = $dir; |
1126 | | - $this->styles[$style] = $options; |
1127 | | - } |
1128 | | - |
1129 | | - /** |
1130 | | - * Build a set of <link>s for the stylesheets specified in the $this->styles array. |
1131 | | - * These will be applied to various media & IE conditionals. |
1132 | | - */ |
1133 | | - protected function buildCssLinks() { |
1134 | | - $links = array(); |
1135 | | - foreach( $this->styles as $file => $options ) { |
1136 | | - $link = $this->styleLink( $file, $options ); |
1137 | | - if( $link ) |
1138 | | - $links[] = $link; |
1139 | | - } |
1140 | | - |
1141 | | - return implode( "\n\t\t", $links ); |
1142 | | - } |
1143 | | - |
1144 | | - protected function styleLink( $style, $options ) { |
1145 | | - global $wgRequest; |
1146 | | - |
1147 | | - if( isset( $options['dir'] ) ) { |
1148 | | - global $wgContLang; |
1149 | | - $siteDir = $wgContLang->isRTL() ? 'rtl' : 'ltr'; |
1150 | | - if( $siteDir != $options['dir'] ) |
1151 | | - return ''; |
1152 | | - } |
1153 | | - |
1154 | | - if( isset( $options['media'] ) ) { |
1155 | | - $media = $this->transformCssMedia( $options['media'] ); |
1156 | | - if( is_null( $media ) ) { |
1157 | | - return ''; |
1158 | | - } |
1159 | | - } else { |
1160 | | - $media = ''; |
1161 | | - } |
1162 | | - |
1163 | | - if( substr( $style, 0, 1 ) == '/' || |
1164 | | - substr( $style, 0, 5 ) == 'http:' || |
1165 | | - substr( $style, 0, 6 ) == 'https:' ) { |
1166 | | - $url = $style; |
1167 | | - } else { |
1168 | | - global $wgStylePath, $wgStyleVersion; |
1169 | | - $url = $wgStylePath . '/' . $style . '?' . $wgStyleVersion; |
1170 | | - } |
1171 | | - |
1172 | | - $attribs = array( |
1173 | | - 'rel' => 'stylesheet', |
1174 | | - 'href' => $url, |
1175 | | - 'type' => 'text/css' ); |
1176 | | - if( $media ) { |
1177 | | - $attribs['media'] = $media; |
1178 | | - } |
1179 | | - |
1180 | | - $link = Xml::element( 'link', $attribs ); |
1181 | | - |
1182 | | - if( isset( $options['condition'] ) ) { |
1183 | | - $condition = htmlspecialchars( $options['condition'] ); |
1184 | | - $link = "<!--[if $condition]>$link<![endif]-->"; |
1185 | | - } |
1186 | | - return $link; |
1187 | | - } |
1188 | | - |
1189 | | - function transformCssMedia( $media ) { |
1190 | | - global $wgRequest, $wgHandheldForIPhone; |
1191 | | - |
1192 | | - // Switch in on-screen display for media testing |
1193 | | - $switches = array( |
1194 | | - 'printable' => 'print', |
1195 | | - 'handheld' => 'handheld', |
1196 | | - ); |
1197 | | - foreach( $switches as $switch => $targetMedia ) { |
1198 | | - if( $wgRequest->getBool( $switch ) ) { |
1199 | | - if( $media == $targetMedia ) { |
1200 | | - $media = ''; |
1201 | | - } elseif( $media == 'screen' ) { |
1202 | | - return null; |
1203 | | - } |
1204 | | - } |
1205 | | - } |
1206 | | - |
1207 | | - // Expand longer media queries as iPhone doesn't grok 'handheld' |
1208 | | - if( $wgHandheldForIPhone ) { |
1209 | | - $mediaAliases = array( |
1210 | | - 'screen' => 'screen and (min-device-width: 481px)', |
1211 | | - 'handheld' => 'handheld, only screen and (max-device-width: 480px)', |
1212 | | - ); |
1213 | | - |
1214 | | - if( isset( $mediaAliases[$media] ) ) { |
1215 | | - $media = $mediaAliases[$media]; |
1216 | | - } |
1217 | | - } |
1218 | | - |
1219 | | - return $media; |
1220 | | - } |
1221 | | - |
1222 | 997 | } |
1223 | 998 | |
1224 | 999 | /** |
Index: trunk/phase3/includes/Skin.php |
— | — | @@ -171,7 +171,7 @@ |
172 | 172 | return $q; |
173 | 173 | } |
174 | 174 | |
175 | | - function initPage( &$out ) { |
| 175 | + function initPage( OutputPage $out ) { |
176 | 176 | global $wgFavicon, $wgAppleTouchIcon; |
177 | 177 | |
178 | 178 | wfProfileIn( __METHOD__ ); |
— | — | @@ -223,7 +223,7 @@ |
224 | 224 | $lb->execute(); |
225 | 225 | } |
226 | 226 | |
227 | | - function addMetadataLinks( &$out ) { |
| 227 | + function addMetadataLinks( OutputPage $out ) { |
228 | 228 | global $wgTitle, $wgEnableDublinCoreRdf, $wgEnableCreativeCommonsRdf; |
229 | 229 | global $wgRightsPage, $wgRightsUrl; |
230 | 230 | |
— | — | @@ -259,16 +259,25 @@ |
260 | 260 | } |
261 | 261 | } |
262 | 262 | |
263 | | - function outputPage( &$out ) { |
| 263 | + function setMembers(){ |
| 264 | + global $wgTitle, $wgUser; |
| 265 | + $this->mTitle = $wgTitle; |
| 266 | + $this->mUser = $wgUser; |
| 267 | + $this->userpage = $wgUser->getUserPage()->getPrefixedText(); |
| 268 | + $this->usercss = false; |
| 269 | + } |
| 270 | + |
| 271 | + function outputPage( OutputPage $out ) { |
264 | 272 | global $wgDebugComments; |
| 273 | + wfProfileIn( __METHOD__ ); |
265 | 274 | |
266 | | - wfProfileIn( __METHOD__ ); |
| 275 | + $this->setMembers(); |
267 | 276 | $this->initPage( $out ); |
268 | 277 | |
269 | 278 | // See self::afterContentHook() for documentation |
270 | 279 | $afterContent = $this->afterContentHook(); |
271 | 280 | |
272 | | - $out->out( $out->headElement() ); |
| 281 | + $out->out( $out->headElement( $this ) ); |
273 | 282 | |
274 | 283 | $out->out( "\n<body" ); |
275 | 284 | $ops = $this->getBodyOptions(); |
— | — | @@ -336,7 +345,7 @@ |
337 | 346 | 'wgScriptPath' => $wgScriptPath, |
338 | 347 | 'wgScript' => $wgScript, |
339 | 348 | 'wgVariantArticlePath' => $wgVariantArticlePath, |
340 | | - 'wgActionPaths' => $wgActionPaths, |
| 349 | + 'wgActionPaths' => (object)$wgActionPaths, |
341 | 350 | 'wgServer' => $wgServer, |
342 | 351 | 'wgCanonicalNamespace' => $nsname, |
343 | 352 | 'wgCanonicalSpecialPageName' => SpecialPage::resolveAlias( $wgTitle->getDBkey() ), |
— | — | @@ -390,26 +399,26 @@ |
391 | 400 | function getHeadScripts( $allowUserJs ) { |
392 | 401 | global $wgStylePath, $wgUser, $wgJsMimeType, $wgStyleVersion; |
393 | 402 | |
394 | | - $r = self::makeGlobalVariablesScript( array( 'skinname' => $this->getSkinName() ) ); |
| 403 | + $vars = self::makeGlobalVariablesScript( array( 'skinname' => $this->getSkinName() ) ); |
395 | 404 | |
396 | | - $r .= "<script type=\"{$wgJsMimeType}\" src=\"{$wgStylePath}/common/wikibits.js?$wgStyleVersion\"></script>\n"; |
| 405 | + $r = array( "<script type=\"{$wgJsMimeType}\" src=\"{$wgStylePath}/common/wikibits.js?$wgStyleVersion\"></script>" ); |
397 | 406 | global $wgUseSiteJs; |
398 | 407 | if ($wgUseSiteJs) { |
399 | 408 | $jsCache = $wgUser->isLoggedIn() ? '&smaxage=0' : ''; |
400 | | - $r .= "<script type=\"$wgJsMimeType\" src=\"". |
| 409 | + $r[] = "<script type=\"$wgJsMimeType\" src=\"". |
401 | 410 | htmlspecialchars(self::makeUrl('-', |
402 | 411 | "action=raw$jsCache&gen=js&useskin=" . |
403 | 412 | urlencode( $this->getSkinName() ) ) ) . |
404 | | - "\"><!-- site js --></script>\n"; |
| 413 | + "\"><!-- site js --></script>"; |
405 | 414 | } |
406 | 415 | if( $allowUserJs && $wgUser->isLoggedIn() ) { |
407 | 416 | $userpage = $wgUser->getUserPage(); |
408 | 417 | $userjs = htmlspecialchars( self::makeUrl( |
409 | 418 | $userpage->getPrefixedText().'/'.$this->getSkinName().'.js', |
410 | 419 | 'action=raw&ctype='.$wgJsMimeType)); |
411 | | - $r .= '<script type="'.$wgJsMimeType.'" src="'.$userjs."\"></script>\n"; |
| 420 | + $r[] = '<script type="'.$wgJsMimeType.'" src="'.$userjs."\"></script>"; |
412 | 421 | } |
413 | | - return $r; |
| 422 | + return $vars . "\t\t" . implode ( "\n\t\t", $r ); |
414 | 423 | } |
415 | 424 | |
416 | 425 | /** |
— | — | @@ -437,46 +446,23 @@ |
438 | 447 | } |
439 | 448 | |
440 | 449 | /** |
441 | | - * Get the site-specific stylesheet, SkinTemplate loads via RawPage.php (settings are cached that way) |
| 450 | + * generated JavaScript action=raw&gen=js |
| 451 | + * This returns MediaWiki:Common.js and MediaWiki:[Skinname].js concate- |
| 452 | + * nated together. For some bizarre reason, it does *not* return any |
| 453 | + * custom user JS from subpages. Huh? |
| 454 | + * |
| 455 | + * There's absolutely no reason to have separate Monobook/Common JSes. |
| 456 | + * Any JS that cares can just check the skin variable generated at the |
| 457 | + * top. For now Monobook.js will be maintained, but it should be consi- |
| 458 | + * dered deprecated. |
| 459 | + * |
| 460 | + * @return string |
442 | 461 | */ |
443 | | - function getSiteStylesheet() { |
444 | | - global $wgStylePath, $wgContLang, $wgStyleVersion; |
445 | | - $sheet = $this->getStylesheet(); |
446 | | - $s = "@import \"$wgStylePath/common/shared.css?$wgStyleVersion\";\n"; |
447 | | - $s .= "@import \"$wgStylePath/common/oldshared.css?$wgStyleVersion\";\n"; |
448 | | - $s .= "@import \"$wgStylePath/$sheet?$wgStyleVersion\";\n"; |
449 | | - if( $wgContLang->isRTL() ) |
450 | | - $s .= "@import \"$wgStylePath/common/common_rtl.css?$wgStyleVersion\";\n"; |
451 | | - return "$s\n"; |
452 | | - } |
| 462 | + public function generateUserJs() { |
| 463 | + global $wgStylePath; |
453 | 464 | |
454 | | - /** |
455 | | - * Get the user-specific stylesheet, SkinTemplate loads via RawPage.php (settings are cached that way) |
456 | | - */ |
457 | | - function getUserStylesheet() { |
458 | | - global $wgContLang, $wgSquidMaxage, $wgStyleVersion; |
459 | | - $query = "usemsgcache=yes&action=raw&ctype=text/css&smaxage=$wgSquidMaxage"; |
460 | | - $s = '@import "' . self::makeNSUrl( 'Common.css', $query, NS_MEDIAWIKI ) . "\";\n"; |
461 | | - $s .= '@import "' . self::makeNSUrl( ucfirst( $this->getSkinName() . '.css' ), $query, NS_MEDIAWIKI ) . "\";\n"; |
462 | | - $s .= $this->doGetUserStyles(); |
463 | | - return "$s\n"; |
464 | | - } |
465 | | - |
466 | | - /** |
467 | | - * This returns MediaWiki:Common.js, and derived classes may add other JS. |
468 | | - * Despite its name, it does *not* return any custom user JS from user |
469 | | - * subpages. The returned script is sitewide and publicly cacheable and |
470 | | - * therefore must not include anything that varies according to user, |
471 | | - * interface language, etc. (although it may vary by skin). See |
472 | | - * makeGlobalVariablesScript for things that can vary per page view and are |
473 | | - * not cacheable. |
474 | | - * |
475 | | - * @return string Raw JavaScript to be returned |
476 | | - */ |
477 | | - public function getUserJs() { |
478 | 465 | wfProfileIn( __METHOD__ ); |
479 | 466 | |
480 | | - global $wgStylePath; |
481 | 467 | $s = "/* generated javascript */\n"; |
482 | 468 | $s .= "var skin = '" . Xml::escapeJsString( $this->getSkinName() ) . "';\n"; |
483 | 469 | $s .= "var stylepath = '" . Xml::escapeJsString( $wgStylePath ) . "';"; |
— | — | @@ -485,57 +471,35 @@ |
486 | 472 | if ( !wfEmptyMsg ( 'common.js', $commonJs ) ) { |
487 | 473 | $s .= $commonJs; |
488 | 474 | } |
| 475 | + |
| 476 | + $s .= "\n\n/* MediaWiki:".ucfirst( $this->getSkinName() ).".js */\n"; |
| 477 | + // avoid inclusion of non defined user JavaScript (with custom skins only) |
| 478 | + // by checking for default message content |
| 479 | + $msgKey = ucfirst( $this->getSkinName() ).'.js'; |
| 480 | + $userJS = wfMsgForContent($msgKey); |
| 481 | + if ( !wfEmptyMsg( $msgKey, $userJS ) ) { |
| 482 | + $s .= $userJS; |
| 483 | + } |
| 484 | + |
489 | 485 | wfProfileOut( __METHOD__ ); |
490 | 486 | return $s; |
491 | 487 | } |
492 | 488 | |
493 | 489 | /** |
494 | | - * Return html code that include site stylesheets |
| 490 | + * generate user stylesheet for action=raw&gen=css |
495 | 491 | */ |
496 | | - function getSiteStyles() { |
497 | | - $s = "<style type='text/css'>\n"; |
498 | | - $s .= "/*/*/ /*<![CDATA[*/\n"; # <-- Hide the styles from Netscape 4 without hiding them from IE/Mac |
499 | | - $s .= $this->getSiteStylesheet(); |
500 | | - $s .= "/*]]>*/ /* */\n"; |
501 | | - $s .= "</style>\n"; |
| 492 | + public function generateUserStylesheet() { |
| 493 | + wfProfileIn( __METHOD__ ); |
| 494 | + $s = "/* generated user stylesheet */\n" . |
| 495 | + $this->reallyGenerateUserStylesheet(); |
| 496 | + wfProfileOut( __METHOD__ ); |
502 | 497 | return $s; |
503 | 498 | } |
504 | 499 | |
505 | 500 | /** |
506 | | - * Return html code that include User stylesheets |
| 501 | + * Split for easier subclassing in SkinSimple, SkinStandard and SkinCologneBlue |
507 | 502 | */ |
508 | | - function getUserStyles() { |
509 | | - $s = "<style type='text/css'>\n"; |
510 | | - $s .= "/*/*/ /*<![CDATA[*/\n"; # <-- Hide the styles from Netscape 4 without hiding them from IE/Mac |
511 | | - $s .= $this->getUserStylesheet(); |
512 | | - $s .= "/*]]>*/ /* */\n"; |
513 | | - $s .= "</style>\n"; |
514 | | - return $s; |
515 | | - } |
516 | | - |
517 | | - /** |
518 | | - * Some styles that are set by user through the user settings interface. |
519 | | - */ |
520 | | - function doGetUserStyles() { |
521 | | - global $wgUser, $wgUser, $wgRequest, $wgTitle, $wgAllowUserCss; |
522 | | - |
523 | | - $s = ''; |
524 | | - |
525 | | - if( $wgAllowUserCss && $wgUser->isLoggedIn() ) { # logged in |
526 | | - if($wgTitle->isCssSubpage() && $this->userCanPreview( $wgRequest->getText( 'action' ) ) ) { |
527 | | - $s .= $wgRequest->getText('wpTextbox1'); |
528 | | - } else { |
529 | | - $userpage = $wgUser->getUserPage(); |
530 | | - $s.= '@import "'.self::makeUrl( |
531 | | - $userpage->getPrefixedText().'/'.$this->getSkinName().'.css', |
532 | | - 'action=raw&ctype=text/css').'";'."\n"; |
533 | | - } |
534 | | - } |
535 | | - |
536 | | - return $s . $this->reallyDoGetUserStyles(); |
537 | | - } |
538 | | - |
539 | | - function reallyDoGetUserStyles() { |
| 503 | + protected function reallyGenerateUserStylesheet(){ |
540 | 504 | global $wgUser; |
541 | 505 | $s = ''; |
542 | 506 | if (($undopt = $wgUser->getOption("underline")) < 2) { |
— | — | @@ -572,6 +536,81 @@ |
573 | 537 | return $s; |
574 | 538 | } |
575 | 539 | |
| 540 | + /** |
| 541 | + * @private |
| 542 | + */ |
| 543 | + function setupUserCss( OutputPage $out ) { |
| 544 | + global $wgRequest, $wgContLang, $wgUser; |
| 545 | + global $wgAllowUserCss, $wgUseSiteCss, $wgSquidMaxage, $wgStylePath; |
| 546 | + |
| 547 | + wfProfileIn( __METHOD__ ); |
| 548 | + |
| 549 | + $this->setupSkinUserCss( $out ); |
| 550 | + |
| 551 | + $siteargs = array( |
| 552 | + 'action' => 'raw', |
| 553 | + 'maxage' => $wgSquidMaxage, |
| 554 | + ); |
| 555 | + if( $wgUser->isLoggedIn() ) { |
| 556 | + // Ensure that logged-in users' generated CSS isn't clobbered |
| 557 | + // by anons' publicly cacheable generated CSS. |
| 558 | + $siteargs['smaxage'] = '0'; |
| 559 | + $siteargs['ts'] = $wgUser->mTouched; |
| 560 | + } |
| 561 | + |
| 562 | + // Add any extension CSS |
| 563 | + foreach( $out->getExtStyle() as $tag ) { |
| 564 | + $out->addStyle( $tag['href'] ); |
| 565 | + } |
| 566 | + |
| 567 | + // If we use the site's dynamic CSS, throw that in, too |
| 568 | + // Per-site custom styles |
| 569 | + if( $wgUseSiteCss ) { |
| 570 | + $query = wfArrayToCGI( array( |
| 571 | + 'usemsgcache' => 'yes', |
| 572 | + 'ctype' => 'text/css', |
| 573 | + 'smaxage' => $wgSquidMaxage |
| 574 | + ) + $siteargs ); |
| 575 | + # Site settings must override extension css! (bug 15025) |
| 576 | + $out->addStyle( self::makeNSUrl( 'Common.css', $query, NS_MEDIAWIKI) ); |
| 577 | + $out->addStyle( self::makeNSUrl( $this->getSkinName() . '.css', $query, NS_MEDIAWIKI ) ); |
| 578 | + } |
| 579 | + |
| 580 | + // Per-user styles based on preferences |
| 581 | + $siteargs['gen'] = 'css'; |
| 582 | + if( ( $us = $wgRequest->getVal( 'useskin', '' ) ) !== '' ) { |
| 583 | + $siteargs['useskin'] = $us; |
| 584 | + } |
| 585 | + $out->addStyle( self::makeUrl( '-', wfArrayToCGI( $siteargs ) ) ); |
| 586 | + |
| 587 | + // Per-user custom style pages |
| 588 | + if( $wgAllowUserCss && $wgUser->isLoggedIn() ) { |
| 589 | + $action = $wgRequest->getVal('action'); |
| 590 | + # If we're previewing the CSS page, use it |
| 591 | + if( $this->mTitle->isCssSubpage() && $this->userCanPreview( $action ) ) { |
| 592 | + $previewCss = $wgRequest->getText('wpTextbox1'); |
| 593 | + // @FIXME: properly escape the cdata! |
| 594 | + $this->usercss = "/*<![CDATA[*/\n" . $previewCss . "/*]]>*/"; |
| 595 | + } else { |
| 596 | + $out->addStyle( self::makeUrl($this->userpage .'/'.$this->getSkinName() .'.css', |
| 597 | + 'action=raw&ctype=text/css') ); |
| 598 | + } |
| 599 | + } |
| 600 | + |
| 601 | + wfProfileOut( __METHOD__ ); |
| 602 | + } |
| 603 | + |
| 604 | + /** |
| 605 | + * Add skin specific stylesheets |
| 606 | + * @param $out OutputPage |
| 607 | + */ |
| 608 | + function setupSkinUserCss( OutputPage $out ) { |
| 609 | + $out->addStyle( 'common/shared.css' ); |
| 610 | + $out->addStyle( 'common/oldshared.css' ); |
| 611 | + $out->addStyle( $this->getStylesheet() ); |
| 612 | + $out->addStyle( 'common/common_rtl.css', '', '', 'rtl' ); |
| 613 | + } |
| 614 | + |
576 | 615 | function getBodyOptions() { |
577 | 616 | global $wgUser, $wgTitle, $wgOut, $wgRequest, $wgContLang; |
578 | 617 | |
— | — | @@ -646,11 +685,11 @@ |
647 | 686 | $s .= "\n<div id='content'>\n<div id='topbar'>\n" . |
648 | 687 | "<table border='0' cellspacing='0' width='98%'>\n<tr>\n"; |
649 | 688 | |
650 | | - $shove = ($qb != 0); |
651 | | - $left = ($qb == 1 || $qb == 3); |
652 | | - if($wgContLang->isRTL()) $left = !$left; |
| 689 | + $shove = ( $qb != 0 ); |
| 690 | + $left = ( $qb == 1 || $qb == 3 ); |
| 691 | + if( $wgContLang->isRTL() ) $left = !$left; |
653 | 692 | |
654 | | - if ( !$shove ) { |
| 693 | + if( !$shove ) { |
655 | 694 | $s .= "<td class='top' align='left' valign='top' rowspan='{$rows}'>\n" . |
656 | 695 | $this->logoText() . '</td>'; |
657 | 696 | } elseif( $left ) { |
— | — | @@ -733,7 +772,7 @@ |
734 | 773 | |
735 | 774 | # optional 'dmoz-like' category browser. Will be shown under the list |
736 | 775 | # of categories an article belong to |
737 | | - if($wgUseCategoryBrowser) { |
| 776 | + if( $wgUseCategoryBrowser ){ |
738 | 777 | $s .= '<br /><hr />'; |
739 | 778 | |
740 | 779 | # get a big array of the parents tree |
— | — | @@ -756,7 +795,7 @@ |
757 | 796 | * @param &skin Object: skin passed by reference |
758 | 797 | * @return String separated by >, terminate with "\n" |
759 | 798 | */ |
760 | | - function drawCategoryBrowser($tree, &$skin) { |
| 799 | + function drawCategoryBrowser( $tree, &$skin ){ |
761 | 800 | $return = ''; |
762 | 801 | foreach ($tree as $element => $parent) { |
763 | 802 | if (empty($parent)) { |
— | — | @@ -806,13 +845,13 @@ |
807 | 846 | * |
808 | 847 | * Returns an empty string by default, if not changed by any hook function. |
809 | 848 | */ |
810 | | - protected function afterContentHook () { |
| 849 | + protected function afterContentHook() { |
811 | 850 | $data = ""; |
812 | 851 | |
813 | | - if (wfRunHooks ('SkinAfterContent', array (&$data))) { |
| 852 | + if( wfRunHooks( 'SkinAfterContent', array( &$data ) ) ){ |
814 | 853 | // adding just some spaces shouldn't toggle the output |
815 | 854 | // of the whole <div/>, so we use trim() here |
816 | | - if (trim ($data) != "") { |
| 855 | + if( trim( $data ) != '' ){ |
817 | 856 | // Doing this here instead of in the skins to |
818 | 857 | // ensure that the div has the same ID in all |
819 | 858 | // skins |
— | — | @@ -821,15 +860,15 @@ |
822 | 861 | "</div>\n"; |
823 | 862 | } |
824 | 863 | } else { |
825 | | - wfDebug ('Hook SkinAfterContent changed output processing.'); |
| 864 | + wfDebug( "Hook SkinAfterContent changed output processing.\n" ); |
826 | 865 | } |
827 | 866 | |
828 | 867 | return $data; |
829 | 868 | } |
830 | 869 | |
831 | 870 | /** |
832 | | - * This gets called shortly before the \</body\> tag. |
833 | | - * @return String HTML to be put before \</body\> |
| 871 | + * This gets called shortly before the </body> tag. |
| 872 | + * @return String HTML to be put before </body> |
834 | 873 | */ |
835 | 874 | function afterContent() { |
836 | 875 | $printfooter = "<div class=\"printfooter\">\n" . $this->printFooter() . "</div>\n"; |
— | — | @@ -837,8 +876,8 @@ |
838 | 877 | } |
839 | 878 | |
840 | 879 | /** |
841 | | - * This gets called shortly before the \</body\> tag. |
842 | | - * @return String HTML-wrapped JS code to be put before \</body\> |
| 880 | + * This gets called shortly before the </body> tag. |
| 881 | + * @return String HTML-wrapped JS code to be put before </body> |
843 | 882 | */ |
844 | 883 | function bottomScripts() { |
845 | 884 | global $wgJsMimeType; |
— | — | @@ -860,7 +899,7 @@ |
861 | 900 | } |
862 | 901 | |
863 | 902 | /** overloaded by derived classes */ |
864 | | - function doAfterContent() { } |
| 903 | + function doAfterContent() { return "</div></div>"; } |
865 | 904 | |
866 | 905 | function pageTitleLinks() { |
867 | 906 | global $wgOut, $wgTitle, $wgUser, $wgRequest; |