r78270 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r78269‎ | r78270 | r78271 >
Date:19:02, 12 December 2010
Author:dantman
Status:deferred (Comments)
Tags:
Comment:
Commit experimental ThemeDesigner extension.
Modified paths:
  • /trunk/extensions/ThemeDesigner (added) (history)
  • /trunk/extensions/ThemeDesigner/SpecialThemeDesigner.php (added) (history)
  • /trunk/extensions/ThemeDesigner/ThemeDesigner.alias.php (added) (history)
  • /trunk/extensions/ThemeDesigner/ThemeDesigner.i18n.php (added) (history)
  • /trunk/extensions/ThemeDesigner/ThemeDesigner.php (added) (history)
  • /trunk/extensions/ThemeDesigner/frame (added) (history)
  • /trunk/extensions/ThemeDesigner/frame/designer.js (added) (history)
  • /trunk/extensions/ThemeDesigner/frame/layout.php (added) (history)
  • /trunk/extensions/ThemeDesigner/frame/style (added) (history)
  • /trunk/extensions/ThemeDesigner/frame/style/main.css (added) (history)
  • /trunk/extensions/ThemeDesigner/frame/style/nav-bg.gif (added) (history)

Diff [purge]

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
119 + 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
127 + 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
138 + 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
1109 + 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
1198 + 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
2199 + 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
147 + 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
1237 + native

Follow-up revisions

RevisionCommit summaryAuthorDate
r78302Followup r78270 comments, fixing notices.dantman14:31, 13 December 2010

Comments

#Comment by Reedy (talk | contribs)   19:16, 12 December 2010
+		echo Html::element( 'title', null, $wgOut->getHTMLTitle() ) . "\n";

Yum...

#Comment by Dantman (talk | contribs)   19:18, 12 December 2010

That's basically duplicated from OutputPage::headElement. I partially duplicated it because headElement itself goes on to include stuff that didn't belong in the theme designer ui.

#Comment by Raymond (talk | contribs)   10:38, 13 December 2010

Notice: Use of wfLoadExtensionMessages is deprecated. [Called from SpecialThemeDesigner::__construct in \extensions\ThemeDesigner\SpecialThemeDesigner.php at line 17] in \includes\GlobalFunctions.php on line 3334

Notice: Did not find alias for special page 'ThemeDesigner'. Perhaps no aliases are defined for it? [Called from SpecialPage::getLocalName in \includes\SpecialPage.php at line 787] in \includes\GlobalFunctions.php on line 3334

Notice: Did not find alias for special page 'ThemeDesigner'. Perhaps no aliases are defined for it? [Called from SpecialPage::getTitleFor in \includes\SpecialPage.php at line 652] in \includes\GlobalFunctions.php on line 3334

Warning: Missing argument 1 for OutputPage::buildCssLinks(), called in \extensions\ThemeDesigner\SpecialThemeDesigner.php on line 90 and defined in \includes\OutputPage.php on line 2631

Notice: Undefined variable: sk in \includes\OutputPage.php on line 2645

Catchable fatal error: Argument 1 passed to OutputPage::makeResourceLoaderLink() must be an instance of Skin, null given, called in \includes\OutputPage.php on line 2646 and defined in \includes\OutputPage.php on line 2293

#Comment by Dantman (talk | contribs)   14:33, 13 December 2010

Fixed the wfLoadExtensionMessages one, fixed the buildCssLinks one. I cannot reproduce the rest. A $wgExtensionAliasesFiles is properly defined and contains the aliases in it.

#Comment by Dantman (talk | contribs)   15:49, 13 December 2010

FWIW, those buildCssLinks related bugs were caused by r78023 which went and changed which method inside headElement gets a skin passed to it. My code was correct for the revision of trunk I had checked out when I started the extension.

Status & tagging log