http://www.mediawiki.org/wiki/Special:Code/MediaWiki/95676

Revision: 95676
Author:   neilk
Date:     2011-08-29 16:20:14 +0000 (Mon, 29 Aug 2011)
Log Message:
-----------
re-copied state of UploadWizard in 1.17wmf1 @ 95537. Reverted reverts of 
resources and includes in 95285, necessary to get UploadCampaigns working, 
include mediawiki.uri.js library

Modified Paths:
--------------
    branches/wmf/1.17wmf1/includes/HTMLForm.php
    branches/wmf/1.17wmf1/includes/Message.php
    branches/wmf/1.17wmf1/includes/SpecialPage.php
    branches/wmf/1.17wmf1/resources/Resources.php

Added Paths:
-----------
    branches/wmf/1.17wmf1/extensions/UploadWizard/
    branches/wmf/1.17wmf1/resources/mediawiki/mediawiki.uri.js

Modified: branches/wmf/1.17wmf1/includes/HTMLForm.php
===================================================================
--- branches/wmf/1.17wmf1/includes/HTMLForm.php 2011-08-29 16:12:17 UTC (rev 
95675)
+++ branches/wmf/1.17wmf1/includes/HTMLForm.php 2011-08-29 16:20:14 UTC (rev 
95676)
@@ -369,10 +369,16 @@
         * @return String wrapped HTML.
         */
        function wrapForm( $html ) {
+               global $wgUserLanguage;
 
                # Include a <fieldset> wrapper for style, if requested.
                if ( $this->mWrapperLegend !== false ) {
-                       $html = Xml::fieldset( $this->mWrapperLegend, $html );
+                       if ( is_a( $this->mWrapperLegend, 'Message' ) ) { 
+                               $legend = $this->mWrapperLegend->toString();
+                       } else {
+                               $legend = $this->mWrapperLegend;
+                       }
+                       $html = Xml::fieldset( $legend, $html );
                }
                # Use multipart/form-data
                $encType = $this->mUseMultipart

Modified: branches/wmf/1.17wmf1/includes/Message.php
===================================================================
--- branches/wmf/1.17wmf1/includes/Message.php  2011-08-29 16:12:17 UTC (rev 
95675)
+++ branches/wmf/1.17wmf1/includes/Message.php  2011-08-29 16:20:14 UTC (rev 
95676)
@@ -357,4 +357,4 @@
                return $this->message;
        }
 
-}
\ No newline at end of file
+}

Modified: branches/wmf/1.17wmf1/includes/SpecialPage.php
===================================================================
--- branches/wmf/1.17wmf1/includes/SpecialPage.php      2011-08-29 16:12:17 UTC 
(rev 95675)
+++ branches/wmf/1.17wmf1/includes/SpecialPage.php      2011-08-29 16:20:14 UTC 
(rev 95676)
@@ -937,7 +937,148 @@
        }
 }
 
+
 /**
+ * Special page which uses an HTMLForm to handle processing.  This is mostly a
+ * clone of FormAction.  More special pages should be built this way; maybe 
this could be
+ * a new structure for SpecialPages
+ */
+abstract class FormSpecialPage extends SpecialPage {
+
+       /**
+        * Get an HTMLForm descriptor array
+        * @return Array
+        */
+       protected abstract function getFormFields();
+
+       /**
+        * Add pre- or post-text to the form
+        * @return String HTML which will be sent to $form->addPreText()
+        */
+       protected function preText() { return ''; }
+       protected function postText() { return ''; }
+
+       /**
+        * Play with the HTMLForm if you need to more substantially
+        * @param $form HTMLForm
+        */
+       protected function alterForm( HTMLForm $form ) {}
+
+       /**
+        * Get the HTMLForm to control behaviour
+        * @return HTMLForm|null
+        */
+       protected function getForm() {
+               global $wgRequest;
+               $this->fields = $this->getFormFields();
+
+               $form = new HTMLForm( $this->fields );
+               $form->setTitle( $this->getTitle() );
+
+               $form->setSubmitCallback( array( $this, 'onSubmit' ) );
+               $form->setWrapperLegend( wfMessage( strtolower( 
$this->getName() ) . '-legend' ) );
+               $form->addHeaderText(
+                       wfMessage( strtolower( $this->getName() ) . '-text' 
)->parseAsBlock() );
+
+               // Retain query parameters (uselang etc)
+               $params = array_diff_key( $_GET, array( 'title' => null ) );
+               $form->addHiddenField( 'redirectparams', wfArrayToCGI( $params 
) );
+
+               $form->addPreText( $this->preText() );
+               $form->addPostText( $this->postText() );
+               $this->alterForm( $form );
+
+               // Give hooks a chance to alter the form, adding extra fields 
or text etc
+               wfRunHooks( "Special{$this->getName()}BeforeFormDisplay", 
array( &$form ) );
+
+               return $form;
+       }
+
+       /**
+        * Process the form on POST submission.
+        * @param  $data Array
+        * @return Bool|Array true for success, false for didn't-try, array of 
errors on failure
+        */
+       public abstract function onSubmit( array $data );
+
+       /**
+        * Do something exciting on successful processing of the form, most 
likely to show a
+        * confirmation message
+        */
+       public abstract function onSuccess();
+
+       /**
+        * Basic SpecialPage workflow: get a form, send it to the user; get 
some data back,
+        *
+        * @param $par String Subpage string if one was specified
+        */
+       public function execute( $par ) {
+               global $wgUser;
+               $this->setParameter( $par );
+               $this->setHeaders();
+
+               // This will throw exceptions if there's a problem
+               $this->userCanExecute( $wgUser );
+
+               $form = $this->getForm();
+               if ( $form->show() ) {
+                       $this->onSuccess();
+               }
+       }
+
+       /**
+        * Maybe do something interesting with the subpage parameter
+        * @param $par String
+        */
+       protected function setParameter( $par ){}
+
+       /**
+        * Checks if the given user (identified by an object) can perform this 
action.  Can be
+        * overridden by sub-classes with more complicated permissions schemes. 
 Failures here
+        * must throw subclasses of ErrorPageError
+        *
+        * @param $user User: the user to check, or null to use the context user
+        * @return Bool true
+        * @throws ErrorPageError
+        */
+       public function userCanExecute( $user ) {
+               if ( $this->requiresWrite() && wfReadOnly() ) {
+                       throw new ReadOnlyError();
+               }
+
+               if ( $this->getRestriction() !== null && !$user->isAllowed( 
$this->getRestriction() ) ) {
+                       throw new PermissionsError( $this->getRestriction() );
+               }
+
+               if ( $this->requiresUnblock() && $user->isBlocked() ) {
+                       $block = $user->mBlock;
+                       throw new UserBlockedError( $block );
+               }
+
+               return true;
+       }
+
+       /**
+        * Whether this action requires the wiki not to be locked
+        * @return Bool
+        */
+       public function requiresWrite() {
+               return true;
+       }
+
+       /**
+        * Whether this action cannot be executed by a blocked user
+        * @return Bool
+        */
+       public function requiresUnblock() {
+               return true;
+       }
+}
+
+
+
+
+/**
  * Shortcut to construct a special page which is unlisted by default
  * @ingroup SpecialPage
  */

Modified: branches/wmf/1.17wmf1/resources/Resources.php
===================================================================
--- branches/wmf/1.17wmf1/resources/Resources.php       2011-08-29 16:12:17 UTC 
(rev 95675)
+++ branches/wmf/1.17wmf1/resources/Resources.php       2011-08-29 16:20:14 UTC 
(rev 95676)
@@ -342,6 +342,9 @@
                'dependencies' => array( 'jquery.checkboxShiftClick', 
'jquery.client', 'jquery.placeholder' ),
                'debugScripts' => 
'resources/mediawiki.util/mediawiki.util.test.js',
        ),
+       'mediawiki.Uri' => array( 
+               'scripts' => 'resources/mediawiki/mediawiki.uri.js',
+       ),
        'mediawiki.action.history' => array(
                'scripts' => 
'resources/mediawiki.action/mediawiki.action.history.js',
                'dependencies' => 'mediawiki.legacy.history',

Copied: branches/wmf/1.17wmf1/resources/mediawiki/mediawiki.uri.js (from rev 
95284, branches/wmf/1.17wmf1/resources/mediawiki/mediawiki.uri.js)
===================================================================
--- branches/wmf/1.17wmf1/resources/mediawiki/mediawiki.uri.js                  
        (rev 0)
+++ branches/wmf/1.17wmf1/resources/mediawiki/mediawiki.uri.js  2011-08-29 
16:20:14 UTC (rev 95676)
@@ -0,0 +1,260 @@
+/**
+ * Library for simple URI parsing and manipulation.  Requires jQuery.
+ *
+ * Do not expect full RFC 3986 compliance. Intended to be minimal, but 
featureful.
+ * The use cases we have in mind are constructing 'next page' or 'previous 
page' URLs,
+ * detecting whether we need to use cross-domain proxies for an API, 
constructing
+ * simple URL-based API calls, etc.
+ *
+ * Intended to compress very well if you use a JS-parsing minifier.
+ *
+ * Dependencies: mw, jQuery
+ *
+ * Example:
+ *
+ *     var uri = new mw.Uri( 'http://foo.com/mysite/mypage.php?quux=2' );
+ *
+ *     if ( uri.host == 'foo.com' ) {
+ *         uri.host = 'www.foo.com';
+ *         uri.extend( { bar: 1 } );
+ *
+ *         $( 'a#id1' ).attr( 'href', uri );
+ *         // anchor with id 'id1' now links to 
http://foo.com/mysite/mypage.php?bar=1&quux=2
+ *
+ *         $( 'a#id2' ).attr( 'href', uri.clone().extend( { bar: 3, pif: 'paf' 
} ) );
+ *         // anchor with id 'id2' now links to 
http://foo.com/mysite/mypage.php?bar=3&quux=2&pif=paf
+ *     }
+ *
+ * Parsing here is regex based, so may not work on all URIs, but is good 
enough for most.
+ *
+ * Given a URI like
+ * 
'http://usr:[email protected]:81/dir/dir.2/index.htm?q1=0&&test1&test2=&test3=value+%28escaped%29&r=1&r=2#top':
+ * The returned object will have the following properties:
+ *
+ *    protocol  'http'
+ *    user      'usr'
+ *    password  'pwd'
+ *    host      'www.test.com'
+ *    port      '81'
+ *    path      '/dir/dir.2/index.htm'
+ *    query     {
+ *                  q1: 0,
+ *                  test1: null,
+ *                  test2: '',
+ *                  test3: 'value (escaped)'
+ *                  r: [1, 2]
+ *              }
+ *    fragment  'top'
+ *
+ * n.b. 'password' is not technically allowed for HTTP URIs, but it is 
possible with other
+ * sorts of URIs.
+ * You can modify the properties directly. Then use the toString() method to 
extract the
+ * full URI string again.
+ *
+ * Parsing based on parseUri 1.2.2 (c) Steven Levithan <stevenlevithan.com> 
MIT License
+ * http://stevenlevithan.com/demo/parseuri/js/
+ *
+ */
+
+( function( $ ) {
+
+       /**
+        * Function that's useful when constructing the URI string -- we 
frequently encounter the pattern of
+        * having to add something to the URI as we go, but only if it's 
present, and to include a character before or after if so.
+        * @param {String} to prepend, if value not empty
+        * @param {String} value to include, if not empty
+        * @param {String} to append, if value not empty
+        * @param {Boolean} raw -- if true, do not URI encode
+        * @return {String}
+        */
+       function cat( pre, val, post, raw ) {
+               if ( val === undefined || val === null || val === '' ) {
+                       return '';
+               } else {
+                       return pre + ( raw ? val : mw.Uri.encode( val ) ) + 
post;
+               }
+       }
+
+       // Regular expressions to parse many common URIs.
+       var parser = {
+               strict: 
/^(?:([^:\/?#]+):)?(?:\/\/(?:(?:([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)?((?:[^?#\/]*\/)*[^?#]*)(?:\?([^#]*))?(?:#(.*))?/,
+               loose:  
/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?(?:(?:([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?((?:\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?[^?#\/]*)(?:\?([^#]*))?(?:#(.*))?/
+       },
+
+       // The order here matches the order of captured matches in the above 
parser regexes.
+       properties = [
+               'protocol',  // http
+               'user',      // usr
+               'password',  // pwd
+               'host',      // www.test.com
+               'port',      // 81
+               'path',      // /dir/dir.2/index.htm
+               'query',     // q1=0&&test1&test2=value (will become { q1: 0, 
test1: '', test2: 'value' } )
+               'fragment'   // top
+       ];
+
+       /**
+        * Constructs URI object. Throws error if arguments are 
illegal/impossible, or otherwise don't parse.
+        * @constructor
+        * @param {!Object|String} URI string, or an Object with appropriate 
properties (especially another URI object to clone). Object must have non-blank 
'protocol', 'host', and 'path' properties.
+        * @param {Boolean} strict mode (when parsing a string)
+        */
+       mw.Uri = function( uri, strictMode ) {
+               strictMode = !!strictMode;
+               if ( uri !== undefined && uri !== null || uri !== '' ) {
+                       if ( typeof uri === 'string' ) {
+                               this._parse( uri, strictMode );
+                       } else if ( typeof uri === 'object' ) {
+                               var _this = this;
+                               $.each( properties, function( i, property ) {
+                                       _this[property] = uri[property];
+                               } );
+                               if ( this.query === undefined ) {
+                                       this.query = {};
+                               }
+                       }
+               }
+               if ( !( this.protocol && this.host && this.path ) ) {
+                       throw new Error( 'Bad constructor arguments' );
+               }
+       };
+
+       /**
+        * Standard encodeURIComponent, with extra stuff to make all browsers 
work similarly and more compliant with RFC 3986
+        * Similar to rawurlencode from PHP and our JS library 
mw.util.rawurlencode, but we also replace space with a +
+        * @param {String} string
+        * @return {String} encoded for URI
+        */
+       mw.Uri.encode = function( s ) {
+               return encodeURIComponent( s )
+                       .replace( /!/g, '%21').replace( /'/g, '%27').replace( 
/\(/g, '%28')
+                       .replace( /\)/g, '%29').replace( /\*/g, '%2A')
+                       .replace( /%20/g, '+' );
+       };
+
+       /**
+        * Standard decodeURIComponent, with '+' to space
+        * @param {String} string encoded for URI
+        * @return {String} decoded string
+        */
+       mw.Uri.decode = function( s ) {
+               return decodeURIComponent( s ).replace( /\+/g, ' ' );
+       };
+
+       mw.Uri.prototype = {
+
+               /**
+                * Parse a string and set our properties accordingly.
+                * @param {String} URI
+                * @param {Boolean} strictness
+                * @return {Boolean} success
+                */
+               _parse: function( str, strictMode ) {
+                       var matches = parser[ strictMode ? 'strict' : 'loose' 
].exec( str );
+                       var uri = this;
+                       $.each( properties, function( i, property ) {
+                               uri[ property ] = matches[ i+1 ];
+                       } );
+
+                       // uri.query starts out as the query string; we will 
parse it into key-val pairs then make
+                       // that object the "query" property.
+                       // we overwrite query in uri way to make cloning 
easier, it can use the same list of properties.
+                       var q = {};
+                       // using replace to iterate over a string
+                       if ( uri.query ) {
+                               uri.query.replace( 
/(?:^|&)([^&=]*)(?:(=)([^&]*))?/g, function ($0, $1, $2, $3) {
+                                       if ( $1 ) {
+                                               var k = mw.Uri.decode( $1 );
+                                               var v = ( $2 === '' || $2 === 
undefined ) ? null : mw.Uri.decode( $3 );
+                                               if ( typeof q[ k ] === 'string' 
) {
+                                                       q[ k ] = [ q[ k ] ];
+                                               }
+                                               if ( typeof q[ k ] === 'object' 
) {
+                                                       q[ k ].push( v );
+                                               } else {
+                                                       q[ k ] = v;
+                                               }
+                                       }
+                               } );
+                       }
+                       this.query = q;
+               },
+
+               /**
+                * Returns user and password portion of a URI.
+                * @return {String}
+                */
+               getUserInfo: function() {
+                       return cat( '', this.user, cat( ':', this.password, '' 
) );
+               },
+
+               /**
+                * Gets host and port portion of a URI.
+                * @return {String}
+                */
+               getHostPort: function() {
+                       return this.host + cat( ':', this.port, '' );
+               },
+
+               /**
+                * Returns the userInfo and host and port portion of the URI.
+                * In most real-world URLs, this is simply the hostname, but it 
is more general.
+                * @return {String}
+                */
+               getAuthority: function() {
+                       return cat( '', this.getUserInfo(), '@' ) + 
this.getHostPort();
+               },
+
+               /**
+                * Returns the query arguments of the URL, encoded into a string
+                * Does not preserve the order of arguments passed into the 
URI. Does handle escaping.
+                * @return {String}
+                */
+               getQueryString: function() {
+                       var args = [];
+                       $.each( this.query, function( key, val ) {
+                               var k = mw.Uri.encode( key );
+                               var vals = val === null ? [ null ] : 
$.makeArray( val );
+                               $.each( vals, function( i, v ) {
+                                       args.push( k + ( v === null ? '' : '=' 
+ mw.Uri.encode( v ) ) );
+                               } );
+                       } );
+                       return args.join( '&' );
+               },
+
+               /**
+                * Returns everything after the authority section of the URI
+                * @return {String}
+                */
+               getRelativePath: function() {
+                       return this.path + cat( '?', this.getQueryString(), '', 
true ) + cat( '#', this.fragment, '' );
+               },
+
+               /**
+                * Gets the entire URI string. May not be precisely the same as 
input due to order of query arguments.
+                * @return {String} the URI string
+                */
+               toString: function() {
+                       return this.protocol + '://' + this.getAuthority() + 
this.getRelativePath();
+               },
+
+               /**
+                * Clone this URI
+                * @return {Object} new URI object with same properties
+                */
+               clone: function() {
+                       return new mw.Uri( this );
+               },
+
+               /**
+                * Extend the query -- supply query parameters to override or 
add to ours
+                * @param {Object} query parameters in key-val form to override 
or add
+                * @return {Object} this URI object
+                */
+               extend: function( parameters ) {
+                       $.extend( this.query, parameters );
+                       return this;
+               }
+       };
+
+} )( jQuery );


_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to