Index: trunk/extensions/ThemeDesigner/ThemeDesigner.alias.php |
— | — | @@ -0,0 +1,17 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * Aliases for Special:ThemeDesigner |
| 5 | + * |
| 6 | + * @file |
| 7 | + * @ingroup Extensions |
| 8 | + */ |
| 9 | + |
| 10 | +$specialPageAliases = array(); |
| 11 | + |
| 12 | +/** English |
| 13 | + * @author Daniel Friesen |
| 14 | + */ |
| 15 | +$specialPageAliases['en'] = array( |
| 16 | + 'ThemeDesigner' => array( 'ThemeDesigner' ), |
| 17 | +); |
| 18 | + |
Property changes on: trunk/extensions/ThemeDesigner/ThemeDesigner.alias.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 19 | + native |
Index: trunk/extensions/ThemeDesigner/ThemeDesigner.i18n.php |
— | — | @@ -0,0 +1,25 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * Internationalisation file for extension ThemeDesigner. |
| 5 | + * |
| 6 | + * @file |
| 7 | + * @ingroup Extensions |
| 8 | + */ |
| 9 | + |
| 10 | +$messages = array(); |
| 11 | + |
| 12 | +/** English |
| 13 | + * @author Daniel Friesen |
| 14 | + */ |
| 15 | +$messages['en'] = array( |
| 16 | + 'themedesigner-desc' => "Gives users [[Special:ThemeDesigner|a special page]] they can use to preview and build site styles with.", |
| 17 | + |
| 18 | + 'themedesigner' => "Theme Designer", |
| 19 | + 'themedesigner-start' => "Start designer", |
| 20 | + 'themedesigner-interface-skinlabel' => "For skin:", |
| 21 | + 'themedesigner-noscript' => "We're sorry but to function at all the skin designer requires JavaScript to function. Please enable javascript or switch to a browser you can use javascript in if you need to use the skin designer.", |
| 22 | + 'themedesigner-wrongskin' => "Whoops, it looks like the skin currently showing in the preview is not the skin you are currently working on. Perhaps you navigated to this page before the preview's js load event was called, or used a link or form we couldn't intercept. Try navigating to another page on the wiki, that should bring you back to the skin you are working on.", |
| 23 | + |
| 24 | + 'themedesigner-leavewarning' => "You cannot leave the wiki inside skin preview mode. This link's action has been canceled.", |
| 25 | + 'themedesigner-resizertext' => "«|»", |
| 26 | +); |
Property changes on: trunk/extensions/ThemeDesigner/ThemeDesigner.i18n.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 27 | + native |
Index: trunk/extensions/ThemeDesigner/ThemeDesigner.php |
— | — | @@ -0,0 +1,36 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * @author Daniel Friesen (http://mediawiki.org/wiki/User:Dantman) <mediawiki@danielfriesen.name> |
| 5 | + * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later |
| 6 | + * |
| 7 | + * This program is free software; you can redistribute it and/or |
| 8 | + * modify it under the terms of the GNU General Public License |
| 9 | + * as published by the Free Software Foundation; either version 2 |
| 10 | + * of the License, or (at your option) any later version. |
| 11 | + * |
| 12 | + * This program is distributed in the hope that it will be useful, |
| 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 15 | + * GNU General Public License for more details. |
| 16 | + * |
| 17 | + * You should have received a copy of the GNU General Public License |
| 18 | + * along with this program; if not, write to the Free Software |
| 19 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| 20 | + */ |
| 21 | + |
| 22 | +if( !defined( 'MEDIAWIKI' ) ) die( "This is an extension to the MediaWiki package and cannot be run standalone." ); |
| 23 | + |
| 24 | +$wgExtensionCredits['special'][] = array ( |
| 25 | + 'name' => 'Theme Designer', |
| 26 | + 'url' => 'http://mediawiki.org/wiki/Extension:ThemeDesigner', |
| 27 | + 'author' => "[http://mediawiki.org/wiki/User:Dantman Daniel Friesen] [mailto:Daniel%20Friesen%20%3Cmediawiki@danielfriesen.name%3E <mediawiki@danielfriesen.name>]", |
| 28 | + 'descriptionmsg' => 'themedesigner-desc', |
| 29 | +); |
| 30 | + |
| 31 | +$dir = dirname( __FILE__ ) . '/'; |
| 32 | +$wgExtensionMessagesFiles['ThemeDesigner'] = $dir . 'ThemeDesigner.i18n.php'; |
| 33 | +$wgExtensionAliasesFiles['ThemeDesigner'] = $dir . 'ThemeDesigner.alias.php'; |
| 34 | +$wgAutoloadClasses['SpecialThemeDesigner'] = $dir . 'SpecialThemeDesigner.php'; |
| 35 | +$wgSpecialPages['ThemeDesigner'] = 'SpecialThemeDesigner'; |
| 36 | +$wgSpecialPageGroups['ThemeDesigner'] = 'wiki'; |
| 37 | + |
Property changes on: trunk/extensions/ThemeDesigner/ThemeDesigner.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 38 | + native |
Index: trunk/extensions/ThemeDesigner/SpecialThemeDesigner.php |
— | — | @@ -0,0 +1,107 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * Special:ThemeDesigner implementation for extension ThemeDesigner |
| 5 | + * |
| 6 | + * @file |
| 7 | + * @ingroup Extensions |
| 8 | + */ |
| 9 | + |
| 10 | +if( !defined( 'MEDIAWIKI' ) ) { |
| 11 | + die( 'This is an extension to the MediaWiki package and cannot be run standalone.' ); |
| 12 | +} |
| 13 | + |
| 14 | +class SpecialThemeDesigner extends SpecialPage { |
| 15 | + |
| 16 | + public function __construct() { |
| 17 | + parent::__construct( 'ThemeDesigner' ); |
| 18 | + wfLoadExtensionMessages( 'ThemeDesigner' ); |
| 19 | + } |
| 20 | + |
| 21 | + /** |
| 22 | + * Show the special page |
| 23 | + * |
| 24 | + * @param $par String: name of the user to sudo into |
| 25 | + */ |
| 26 | + public function execute( $par ) { |
| 27 | + global $wgOut, $wgExtensionAssetsPath; |
| 28 | + |
| 29 | + $this->mSkin = Skin::newFromKey( 'simple' ); |
| 30 | + |
| 31 | + $this->setHeaders(); |
| 32 | + |
| 33 | + if ( function_exists("OutputPage::includeJQuery") ) { |
| 34 | + $wgOut->includeJQuery(); |
| 35 | + } |
| 36 | + |
| 37 | + $wgOut->addExtensionStyle("$wgExtensionAssetsPath/ThemeDesigner/frame/style/main.css"); |
| 38 | + // Yes, the following is ugly... though I still haven't decided if I want to become completely ResourceLoader dependant |
| 39 | + // While 1.16 is still stable. |
| 40 | + $varScript = array(); |
| 41 | + foreach ( array('leavewarning', 'resizertext') as $msgName ) { |
| 42 | + $varScript[] = 'msg'.ucfirst($msgName).' = '.Xml::encodeJsVar((string)wfMsg("themedesigner-{$msgName}")); |
| 43 | + } |
| 44 | + $varScript = 'var '.implode(", ", $varScript).';'; |
| 45 | + $wgOut->addInlineScript($varScript); |
| 46 | + $wgOut->addScriptFile("$wgExtensionAssetsPath/ThemeDesigner/frame/designer.js"); |
| 47 | + |
| 48 | + $this->printHtmlHead(); |
| 49 | + |
| 50 | + // We've collected our html building into a separate file for readability |
| 51 | + require(dirname(__FILE__).'/frame/layout.php'); |
| 52 | + |
| 53 | + echo $this->mSkin->bottomScripts( $wgOut ); |
| 54 | + echo Html::closeElement('body'); |
| 55 | + echo Html::closeElement('html'); |
| 56 | + |
| 57 | + } |
| 58 | + |
| 59 | + /** |
| 60 | + * Prints a raw html header for our page complete takeover specialpage |
| 61 | + * Note that this matches most of the functionality of OutputPage::headElement |
| 62 | + * however that method ads extra we can't have in our head so we have to reimplement |
| 63 | + */ |
| 64 | + function printHtmlHead() { |
| 65 | + global $wgOut, $wgHtml5, $wgMimeType, $wgOutputEncoding; |
| 66 | + echo Html::htmlHeader( array( 'lang' => wfUILang()->getCode() ) ); |
| 67 | + if ( $wgOut->getHTMLTitle() == '' ) { |
| 68 | + $wgOut->setHTMLTitle( wfMsg( 'pagetitle', $wgOut->getPageTitle() ) ); |
| 69 | + } |
| 70 | + $openHead = Html::openElement( 'head' ); |
| 71 | + if ( $openHead ) { |
| 72 | + echo "$openHead\n"; |
| 73 | + } |
| 74 | + |
| 75 | + if ( $wgHtml5 ) { |
| 76 | + # More succinct than <meta http-equiv=Content-Type>, has the |
| 77 | + # same effect |
| 78 | + echo Html::element( 'meta', array( 'charset' => $wgOutputEncoding ) ) . "\n"; |
| 79 | + } else { |
| 80 | + $wgOut->addMeta( 'http:Content-Type', "$wgMimeType; charset=$wgOutputEncoding" ); |
| 81 | + } |
| 82 | + |
| 83 | + echo Html::element( 'title', null, $wgOut->getHTMLTitle() ) . "\n"; |
| 84 | + |
| 85 | + foreach ( $wgOut->mExtStyles as $extstyle ) { |
| 86 | + $wgOut->styles[$extstyle] = array(); |
| 87 | + } |
| 88 | + |
| 89 | + echo implode( "\n", array( |
| 90 | + $wgOut->getHeadLinks( $this->mSkin ), |
| 91 | + $wgOut->buildCssLinks(), |
| 92 | + $wgOut->getHeadItems() |
| 93 | + ) ); |
| 94 | + |
| 95 | + $closeHead = Html::closeElement( 'head' ); |
| 96 | + if ( $closeHead ) { |
| 97 | + echo "$closeHead\n"; |
| 98 | + } |
| 99 | + |
| 100 | + $bodyAttrs = array(); |
| 101 | + |
| 102 | + echo Html::openElement( 'body', $bodyAttrs ) . "\n"; |
| 103 | + |
| 104 | + $wgOut->sendCacheControl(); |
| 105 | + $wgOut->disable(); |
| 106 | + } |
| 107 | + |
| 108 | +} |
Property changes on: trunk/extensions/ThemeDesigner/SpecialThemeDesigner.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 109 | + native |
Index: trunk/extensions/ThemeDesigner/frame/style/main.css |
— | — | @@ -0,0 +1,196 @@ |
| 2 | + |
| 3 | +html, |
| 4 | +body { |
| 5 | + height: 100%; |
| 6 | + margin: 0; |
| 7 | + padding: 0; |
| 8 | + font-family: sans-serif; |
| 9 | + font-size: 1em; |
| 10 | + |
| 11 | + background-color: #222; |
| 12 | + color: #fff; |
| 13 | +} |
| 14 | + |
| 15 | +section { display: block } |
| 16 | + |
| 17 | +#designer-nav, |
| 18 | +#designer-interface, |
| 19 | +#designer-viewer { |
| 20 | + position: relative; |
| 21 | + font-size: .8em; |
| 22 | +} |
| 23 | + |
| 24 | +#designer-nav { |
| 25 | + display: block; |
| 26 | + background: #444 url(nav-bg.gif) center bottom repeat-x; |
| 27 | + border-bottom: 1px solid #666; |
| 28 | + height: 40px; |
| 29 | + line-height: 40px; |
| 30 | + letter-spacing: 1px; |
| 31 | + margin: 0; |
| 32 | + padding: 0; |
| 33 | + color: #fff; |
| 34 | +} |
| 35 | +#designer-nav ul { |
| 36 | + display: block; |
| 37 | + position: relative; |
| 38 | + list-style: none; |
| 39 | + margin: 0; |
| 40 | + padding: 0; |
| 41 | +} |
| 42 | +#designer-nav ul li { |
| 43 | + display: block; |
| 44 | + position: relative; |
| 45 | + float: left; |
| 46 | + margin: 0; |
| 47 | + padding: 0; |
| 48 | +} |
| 49 | +#designer-nav ul li a, |
| 50 | +#designer-nav ul li span { |
| 51 | + display: block; |
| 52 | + color: #fff; |
| 53 | + padding: 0 14px; |
| 54 | + text-decoration: none; |
| 55 | + text-shadow: 1px 1px 3px #000; |
| 56 | +} |
| 57 | +#designer-nav ul li.active a, |
| 58 | +#designer-nav ul li a:active, |
| 59 | +#designer-nav ul li:hover a { |
| 60 | + background-color: #333; |
| 61 | +} |
| 62 | + |
| 63 | +.secondary-bar { |
| 64 | + display: block; |
| 65 | + background: #555; |
| 66 | + border-bottom: 1px solid #666; |
| 67 | + height: 42px; |
| 68 | + line-height: 42px; |
| 69 | + letter-spacing: 1px; |
| 70 | + font-weight: bold; |
| 71 | + margin: 0; |
| 72 | + padding: 0; |
| 73 | + color: #fff; |
| 74 | + padding: 0 5px; |
| 75 | +} |
| 76 | + |
| 77 | +#designer-interface { |
| 78 | + position: absolute; |
| 79 | + top: 41px; |
| 80 | + left: 0; |
| 81 | + width: 250px; |
| 82 | + bottom: 0; |
| 83 | + overflow: auto; |
| 84 | + border-right: 1px solid #666; |
| 85 | +} |
| 86 | +#designer-interface section { |
| 87 | + overflow: auto; |
| 88 | +} |
| 89 | +#designer-interface h2 { |
| 90 | + display: block; |
| 91 | + background: #333; |
| 92 | + border-bottom: 1px solid #666; |
| 93 | + height: 25px; |
| 94 | + line-height: 25px; |
| 95 | + letter-spacing: 1px; |
| 96 | + font-size: 1em; |
| 97 | + font-weight: bold; |
| 98 | + margin: 0; |
| 99 | + padding: 0; |
| 100 | + color: #fff; |
| 101 | + padding: 0 5px; |
| 102 | + cursor: pointer; |
| 103 | +} |
| 104 | +#designer-interface section ~ h2 { |
| 105 | + border-top: 1px solid #666; |
| 106 | +} |
| 107 | +#designer-interface section > div { |
| 108 | + |
| 109 | +} |
| 110 | + |
| 111 | +#designer-interface textarea { |
| 112 | + width: 100%; |
| 113 | + border: 1px solid #333; |
| 114 | + -moz-box-sizing: border-box; -khtml-box-sizing: border-box; -webkit-box-sizing: border-box; -ms-box-sizing: border-box; box-sizing: border-box; |
| 115 | +} |
| 116 | + |
| 117 | +#designer-viewer { |
| 118 | + position: absolute; |
| 119 | + top: 41px; |
| 120 | + left: 251px; |
| 121 | + right: 0; |
| 122 | + bottom: 0; |
| 123 | + overflow: auto; |
| 124 | +} |
| 125 | +#designer-viewer-path { |
| 126 | + overflow: hidden; |
| 127 | + white-space: nowrap; |
| 128 | +} |
| 129 | +#designer-wrongskinmessage { |
| 130 | + position: absolute; |
| 131 | + z-index: 3; |
| 132 | + top: 43px; |
| 133 | + left: 50px; right: 50px; |
| 134 | + padding: 0 1em; |
| 135 | + background: #555; |
| 136 | + color: #fff; |
| 137 | + border: 1px solid #666; |
| 138 | + border-top-width: 0; |
| 139 | + -moz-border-radius-bottomleft: 5px; -khtml-border-bottom-left-radius: 5px; -webkit-border-bottom-left-radius: 5px; border-bottom-left-radius: 5px; |
| 140 | + -moz-border-radius-bottomright: 5px; -khtml-border-bottom-right-radius: 5px; -webkit-border-bottom-right-radius: 5px; border-bottom-right-radius: 5px; |
| 141 | + display: none; |
| 142 | +} |
| 143 | + |
| 144 | +#designer-viewer-framewrapper { |
| 145 | + position: absolute; |
| 146 | + top: 43px; bottom: 0; |
| 147 | + left: 0; right: 0; |
| 148 | + -moz-box-sizing: border-box; -khtml-box-sizing: border-box; -webkit-box-sizing: border-box; -ms-box-sizing: border-box; box-sizing: border-box; |
| 149 | +} |
| 150 | +#designer-iframe { |
| 151 | + display: block; |
| 152 | + position: absolute; |
| 153 | + top: 0; bottom: 0; |
| 154 | + left: 0; right: 0; |
| 155 | + width: 100%; height: 100%; |
| 156 | + border: none; |
| 157 | + -moz-box-sizing: border-box; -khtml-box-sizing: border-box; -webkit-box-sizing: border-box; -ms-box-sizing: border-box; box-sizing: border-box; |
| 158 | + background: white; |
| 159 | +} |
| 160 | + |
| 161 | +#safewrapper { |
| 162 | + position: absolute; |
| 163 | + width: 100%; height: 100%; |
| 164 | + top: 0; right: 0; bottom: 0; left: 0; |
| 165 | + background: white; |
| 166 | + opacity: 0.1; |
| 167 | + z-index: 5; |
| 168 | +} |
| 169 | +.horizontal-resizer { |
| 170 | + display: block; |
| 171 | + position: absolute; |
| 172 | + background: #555; |
| 173 | + text-align: center; |
| 174 | + vertical-align: middle; |
| 175 | + padding: 0 5px; |
| 176 | + -moz-border-radius: 3px; -khtml-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; |
| 177 | + font-size: 12px; |
| 178 | + height: 20px; |
| 179 | + line-height: 20px; |
| 180 | + cursor: ew-resize; |
| 181 | + z-index: 10; |
| 182 | +} |
| 183 | + |
| 184 | +#designer-interface { |
| 185 | + display: -webkit-box; |
| 186 | + -webkit-box-orient: vertical; |
| 187 | + -webkit-box-align: stretch; |
| 188 | +} |
| 189 | +#designer-interface > * { |
| 190 | + -webkit-box-flex: 0; |
| 191 | +} |
| 192 | +#designer-interface > section { |
| 193 | + position: relative; |
| 194 | + -webkit-box-flex: 1; |
| 195 | +} |
| 196 | + |
| 197 | + |
Property changes on: trunk/extensions/ThemeDesigner/frame/style/main.css |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 198 | + native |
Index: trunk/extensions/ThemeDesigner/frame/style/nav-bg.gif |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/extensions/ThemeDesigner/frame/style/nav-bg.gif |
___________________________________________________________________ |
Added: svn:mime-type |
2 | 199 | + application/octet-stream |
Index: trunk/extensions/ThemeDesigner/frame/layout.php |
— | — | @@ -0,0 +1,45 @@ |
| 2 | +<nav id="designer-nav"> |
| 3 | + <ul> |
| 4 | + <li><span><?php echo htmlspecialchars(wfMsg('themedesigner')); ?></span></li> |
| 5 | + <li><a href="<?php echo Title::newMainPage()->escapeLocalURL(); ?>"><?php echo htmlspecialchars(wfMsg('mainpage-description')); ?></a></li> |
| 6 | + <li><a href="<?php echo SpecialPage::getTitleFor('RecentChanges')->escapeLocalURL(); ?>"><?php echo htmlspecialchars(wfMsg('recentchanges')); ?></a></li> |
| 7 | + <li><a href="<?php echo SpecialPage::getTitleFor('SpecialPages')->escapeLocalURL(); ?>"><?php echo htmlspecialchars(wfMsg('specialpages')); ?></a></li> |
| 8 | + </ul> |
| 9 | +</nav> |
| 10 | +<div id=designer-interface> |
| 11 | + <div id=designer-interface-bar class=secondary-bar> |
| 12 | + <?php echo htmlspecialchars(wfMsg('themedesigner-interface-skinlabel')) ?> |
| 13 | +<?php |
| 14 | + $validSkinNames = Skin::getUsableSkins(); |
| 15 | + foreach ( $validSkinNames as $skinkey => &$skinname ) { |
| 16 | + $msgName = "skinname-{$skinkey}"; |
| 17 | + $localisedSkinName = wfMsg( $msgName ); |
| 18 | + if ( !wfEmptyMsg( $msgName, $localisedSkinName ) ) { |
| 19 | + $skinname = htmlspecialchars( $localisedSkinName ); |
| 20 | + } |
| 21 | + } |
| 22 | + asort( $validSkinNames ); |
| 23 | + /* if ( empty($par) || !isset($validSkinNames[strtolower($par)]) ) { |
| 24 | + $par = $GLOBALS["wgUser"]->getSkin()->skinname; |
| 25 | + } |
| 26 | + $skinSelect = new XmlSelect( 'skin', false, strtolower($par) );*/ |
| 27 | + $skinSelect = new XmlSelect( 'skin', false, $GLOBALS["wgUser"]->getSkin()->skinname ); |
| 28 | + $skinSelect->addOptions( array_combine( array_values($validSkinNames), array_keys($validSkinNames) ) ); |
| 29 | + echo $skinSelect->getHTML(); ?> |
| 30 | + </div> |
| 31 | + <h2>Basic</h2> |
| 32 | + <section> |
| 33 | + ... |
| 34 | + </section> |
| 35 | + <h2>Advanced</h2> |
| 36 | + <section> |
| 37 | + <textarea rows=15 id=advanced-css></textarea> |
| 38 | + </section> |
| 39 | +</div> |
| 40 | +<div id=designer-viewer> |
| 41 | + <noscript><?php echo wfMsgWikiHtml('themedesigner-noscript'); ?></noscript> |
| 42 | + <div id=designer-viewer-bar class=secondary-bar> |
| 43 | + </div> |
| 44 | + <div id=designer-wrongskinmessage><?php echo wfMsgWikiHtml('themedesigner-wrongskin'); ?></div> |
| 45 | + <div id=designer-viewer-framewrapper></div> |
| 46 | +</div> |
Property changes on: trunk/extensions/ThemeDesigner/frame/layout.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 47 | + native |
Index: trunk/extensions/ThemeDesigner/frame/designer.js |
— | — | @@ -0,0 +1,235 @@ |
| 2 | +jQuery.fn.cssText = function(style) { |
| 3 | + return this.each(function() { |
| 4 | + if ( !jQuery.nodeName(this, "style") ) |
| 5 | + return; |
| 6 | + if ( this.styleSheet ) { |
| 7 | + this.styleSheet.cssText = style; // IE |
| 8 | + } else { |
| 9 | + while ( this.firstChild ) |
| 10 | + this.removeChild(this.firstChild); |
| 11 | + this.appendChild(document.createTextNode(style)); // Everyone else |
| 12 | + } |
| 13 | + }); |
| 14 | +}; |
| 15 | + |
| 16 | +jQuery(function($) { |
| 17 | + |
| 18 | + var skin = $('select[name="skin"]').val(); |
| 19 | + function makeFirstUrl() { return wgScript+"?useskin="+encodeURIComponent(skin) } |
| 20 | + |
| 21 | + var $hoverPath = $('<div id=designer-viewer-path />').appendTo('#designer-viewer-bar'); |
| 22 | + |
| 23 | + var $wrongSkin = $('#designer-wrongskinmessage'); |
| 24 | + |
| 25 | + var $iframe = $('<iframe id=designer-iframe />') |
| 26 | + .attr({ src: makeFirstUrl() }) |
| 27 | + .bind("load", function(e) { |
| 28 | + var iDocument = $iframe[0].contentDocument; |
| 29 | + |
| 30 | + $wrongSkin.animate({ height: skin != $iframe[0].contentWindow.skin ? "show" : "hide" }, "fast"); |
| 31 | + |
| 32 | + pageStyleRefresh(false); |
| 33 | + |
| 34 | + $("body", iDocument) |
| 35 | + .delegate("a[href]", "click", function(e) { |
| 36 | + var href = this.href; |
| 37 | + |
| 38 | + if ( /^[a-z0-9]+:/i.test(href) ) { |
| 39 | + if ( href.substr(0, wgServer.length).toLowerCase() != wgServer.toLowerCase() ) { |
| 40 | + alert(msgLeavewarning); |
| 41 | + return false; |
| 42 | + } |
| 43 | + } |
| 44 | + |
| 45 | + href += /\?/.test(href) ? '&' : '?'; |
| 46 | + href += "useskin="+encodeURIComponent(skin); |
| 47 | + |
| 48 | + $iframe.attr({ src: href }); |
| 49 | + |
| 50 | + return false; |
| 51 | + }) |
| 52 | + .submit(function(e) { |
| 53 | + $('<input type=hidden name=useskin />', iDocument).val(skin).prependTo(e.target); |
| 54 | + }) |
| 55 | + .mouseover(function(e) { |
| 56 | + var path = $(e.target, iDocument).parents().andSelf().map(function() { |
| 57 | + var text = (this.tagName||"").toLowerCase(); |
| 58 | + if ( this.id ) |
| 59 | + text += '#' + this.id; |
| 60 | + if ( this.className ) |
| 61 | + text += '.' + this.className.split(/\s+/).join('.'); |
| 62 | + return text; |
| 63 | + }).toArray().join(' > '); |
| 64 | + $hoverPath.text(path); |
| 65 | + $hoverPath.scrollLeft($hoverPath[0].scrollWidth); |
| 66 | + }); |
| 67 | + }) |
| 68 | + .mouseleave(function(e) { |
| 69 | + $hoverPath.empty(); |
| 70 | + }) |
| 71 | + .appendTo('#designer-viewer-framewrapper'); |
| 72 | + |
| 73 | + $('select[name="skin"]').change(function(e) { |
| 74 | + skin = $(this).val(); |
| 75 | + $iframe.attr({ src: makeFirstUrl() }); |
| 76 | + refreshSkin(); |
| 77 | + return false; |
| 78 | + }); |
| 79 | + |
| 80 | + var $resizer = $('<span class=horizontal-resizer />').text(msgResizertext) |
| 81 | + .css({ |
| 82 | + top: $('#designer-nav').outerHeight(true) + $('.secondary-bar:first').outerHeight(true) + 10, |
| 83 | + left: $('#designer-interface').outerWidth(true) |
| 84 | + }) |
| 85 | + .appendTo('body'); |
| 86 | + $resizer.css({ marginLeft: -$resizer.outerWidth(true) / 2 }); |
| 87 | + |
| 88 | + var $designerInterface = $('#designer-interface'); |
| 89 | + var $designerViewer = $('#designer-viewer'); |
| 90 | + (function() { |
| 91 | + var lastX, $safewrapper; |
| 92 | + function moveEvent(e) { |
| 93 | + var moveX = e.clientX - lastX; |
| 94 | + |
| 95 | + var w = $designerInterface.width(); |
| 96 | + w += moveX; |
| 97 | + |
| 98 | + $designerInterface.width(w); |
| 99 | + $designerViewer.css({ left: w+1 }); |
| 100 | + $resizer.css({ left: w }); |
| 101 | + lastX = e.clientX; |
| 102 | + } |
| 103 | + function upEvent(e) { |
| 104 | + $safewrapper.remove(); |
| 105 | + delete $safewrapper; |
| 106 | + $(window).unbind("mousemove", moveEvent).unbind("mouseup", upEvent); |
| 107 | + } |
| 108 | + |
| 109 | + $resizer.mousedown(function(e) { |
| 110 | + lastX = e.clientX; |
| 111 | + $safewrapper = $('<div id=safewrapper />').appendTo('body'); |
| 112 | + $(window).mousemove(moveEvent).mouseup(upEvent); |
| 113 | + return false; |
| 114 | + }); |
| 115 | + })(); |
| 116 | + |
| 117 | + $designerInterface.delegate('h2', "click", function(e) { |
| 118 | + $designerInterface.find('section').slideUp("slow"); |
| 119 | + $(this).next("section").stop().slideDown("slow"); |
| 120 | + return false; |
| 121 | + }); |
| 122 | + $designerInterface.find('section:not(:first)').hide(); |
| 123 | + |
| 124 | + // With the new resource loader Common.css, Print.css, and the Skinname.css |
| 125 | + // Are all combined into a single file. As a result of that because we want |
| 126 | + // To properly preview css as if we were editing the Skinname.css message |
| 127 | + // We have to eliminate the shared css file including all 3 into the page |
| 128 | + // To avoid breaking styles we have to reintroduce Print.css and Common.css |
| 129 | + // Ourselves, hence we need to preload them... |
| 130 | + // |
| 131 | + // Oh... wait... @_@ Maybe I could just add links to the css files themselves instead... heh |
| 132 | + // *sigh* scrap it all... |
| 133 | + /*var printStyles, commonStyles; |
| 134 | + $.ajax({ |
| 135 | + url: wgScriptPath+'/api.php', |
| 136 | + data: { |
| 137 | + action: query, |
| 138 | + prop: revisions, |
| 139 | + titles: "MediaWiki:Print.css|MediaWiki:Common.css" |
| 140 | + rvprop: content, |
| 141 | + format: "json" |
| 142 | + }, |
| 143 | + success: function(json) { |
| 144 | + console.log(json); |
| 145 | + } |
| 146 | + }); |
| 147 | + */ |
| 148 | + |
| 149 | + var $advancedCSS = $("#advanced-css") |
| 150 | + .bind("input change", function(e) { |
| 151 | + pageStyleRefresh(true); |
| 152 | + }); |
| 153 | + |
| 154 | + function pageStyleRefresh(emptyOk) { |
| 155 | + if ( skin != $iframe[0].contentWindow.skin ) { |
| 156 | + // Don't screw up styles when we're inside the wrong skin |
| 157 | + return; |
| 158 | + } |
| 159 | + if ( !emptyOk && !$advancedCSS.val() ) { |
| 160 | + // We were called by an event such as an onload which does not control the style directly but wants to refresh it |
| 161 | + // And the custom css box is empty. Under these circumstances it's most probable that we just got a page load |
| 162 | + // event after switching skins but the ajax has not loaded this skin's css into the custom area yet |
| 163 | + // Because we don't want to erase the styles that would be ending up inside that custom area, we'll skip |
| 164 | + // This style refresh call. It's very likely that the ajax which is fetching this skin's custom css is going |
| 165 | + // to finish soon, and when it does it will call a style refresh on it's own and the styles will be properly refreshed |
| 166 | + return; |
| 167 | + } |
| 168 | + |
| 169 | + var iDocument = $iframe[0].contentDocument; |
| 170 | + var $$ = $('#designer-css-preview', iDocument); |
| 171 | + if ( !$$.length ) { |
| 172 | + // Preview styles not in place, replace build in styles |
| 173 | + |
| 174 | + // Erase the real stylesheets so we can inject our preview styles instead |
| 175 | + $('head link[rel="stylesheet"]', iDocument).each(function() { |
| 176 | + if ( /[?&]modules=site(&|$)/.test(this.href) && /[?&]only=styles(&|$)/.test(this.href) ) { |
| 177 | + // This link includes Common.css, Print.css, and Skinname.css, we don't want the real Skinname.css |
| 178 | + // Affecting the page while we preview our own version of it, we'll just have to kill the stylesheet |
| 179 | + $(this).remove(); |
| 180 | + } |
| 181 | + }); |
| 182 | + |
| 183 | + var $iHead = $('head', iDocument); |
| 184 | + |
| 185 | + // While we have to kill Skinname.css unfortunately it is bundled with Common.css and Print.css, to avoid |
| 186 | + // Screwing up styles we have to include a replacement for Common.css and Print.css ourselves |
| 187 | + $('<link rel=stylesheet />', iDocument) |
| 188 | + .attr({ href: wgScript+'?title=MediaWiki:Common.css&action=raw&ctype=text/css' }) |
| 189 | + .appendTo($iHead); |
| 190 | + |
| 191 | + // Now lets insert the preview stylesheet node. |
| 192 | + $$ = $('<link rel=stylesheet id=designer-css-preview type="text/css" />', iDocument).appendTo($iHead); |
| 193 | + //$$ = $('<style id=designer-css-preview type="text/css" />', iDocument).appendTo($('head', iDocument)); |
| 194 | + |
| 195 | + // Here's the Print.css, we insert it now because the order inside of the original file went Common.css, Skinname.css, and finally Print.css |
| 196 | + $('<link rel=stylesheet media=print />', iDocument) |
| 197 | + .attr({ href: wgScript+'?title=MediaWiki:Print.css&action=raw&ctype=text/css' }) |
| 198 | + .appendTo($iHead); |
| 199 | + |
| 200 | + } |
| 201 | + |
| 202 | + // Now we insert the real styles into our preview stylesheet |
| 203 | + // Note that if we were to use a <style> node with inline styles then it |
| 204 | + // would have differentcascading behavior than it would when it came to actually saving |
| 205 | + // the styles into the Skinname.css file. So we make use of a data: url and base64 encode |
| 206 | + // our stylesheet into it. The result is a preview stylesheet that works 99% the same as the |
| 207 | + // real stylesheet (relative url()s do behave slightly differently, but those are already unreliable enough people don't use them in site styles) |
| 208 | + // Right now we're using window.btoa which apparently is present in most browsers other than IE. |
| 209 | + // If you want that last bit of compatibility we should probably bundle a base64 library to fallback to. |
| 210 | + // Although, to be honnest... IE's support for data: urls isn't that great anyways. |
| 211 | + // IE7 and before don't support them. And IE8 has size limitations. |
| 212 | + var data = "data:text/css;base64,"+window.btoa($advancedCSS.val()); |
| 213 | + |
| 214 | + $$.attr({ href: data }); |
| 215 | + |
| 216 | + //$$.cssText(this.value); |
| 217 | + } |
| 218 | + |
| 219 | + function refreshSkin() { |
| 220 | + $advancedCSS.cssText(''); |
| 221 | + $.ajax({ |
| 222 | + url: wgScript, |
| 223 | + data: { |
| 224 | + title: "MediaWiki:Skinname.css".replace("Skinname", skin.charAt(0).toUpperCase() + skin.substr(1)), |
| 225 | + action: "raw", |
| 226 | + ctype: "text/css" |
| 227 | + }, |
| 228 | + success: function(style) { |
| 229 | + $advancedCSS.val(style); |
| 230 | + pageStyleRefresh(true); |
| 231 | + } |
| 232 | + }); |
| 233 | + } |
| 234 | + refreshSkin(); |
| 235 | + |
| 236 | +}); |
Property changes on: trunk/extensions/ThemeDesigner/frame/designer.js |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 237 | + native |