"name": "Interfaces",
"classes": [
"mw.Feedback*",
- "mw.Upload*"
+ "mw.Upload*",
+ "mw.ForeignUpload",
+ "mw.ForeignStructuredUpload"
]
},
{
'mediawiki.api.upload',
),
),
+ 'mediawiki.ForeignUpload' => array(
+ 'scripts' => 'resources/src/mediawiki/mediawiki.ForeignUpload.js',
+ 'dependencies' => array(
+ 'mediawiki.ForeignApi',
+ 'mediawiki.Upload',
+ 'oojs',
+ ),
+ ),
+ 'mediawiki.ForeignStructuredUpload' => array(
+ 'scripts' => 'resources/src/mediawiki/mediawiki.ForeignStructuredUpload.js',
+ 'dependencies' => array(
+ 'mediawiki.ForeignUpload',
+ ),
+ ),
'mediawiki.Upload.Dialog' => array(
'scripts' => 'resources/src/mediawiki/mediawiki.Upload.Dialog.js',
'dependencies' => array(
--- /dev/null
+( function ( mw, OO ) {
+ /**
+ * @class mw.ForeignStructuredUpload
+ * @extends mw.ForeignUpload
+ *
+ * Used to represent an upload in progress on the frontend.
+ *
+ * This subclass will upload to a wiki using a structured metadata
+ * system similar to (or identical to) the one on Wikimedia Commons.
+ *
+ * See <https://commons.wikimedia.org/wiki/Commons:Structured_data> for
+ * a more detailed description of how that system works.
+ *
+ * TODO this currently only supports uploads under CC-BY-SA 4.0,
+ * and should really have support for more licenses.
+ *
+ * @inheritdoc
+ */
+ function ForeignStructuredUpload( targetHost, apiconfig ) {
+ this.date = undefined;
+ this.descriptions = [];
+ this.categories = [];
+
+ mw.ForeignUpload.call( this, targetHost, apiconfig );
+ }
+
+ OO.inheritClass( ForeignStructuredUpload, mw.ForeignUpload );
+
+ /**
+ * Add categories to the upload.
+ * @param {string[]} categories Array of categories to which this upload will be added.
+ */
+ ForeignStructuredUpload.prototype.addCategories = function ( categories ) {
+ var i, category;
+
+ for ( i = 0; i < categories.length; i++ ) {
+ category = categories[i];
+ this.categories.push( category );
+ }
+ };
+
+ /**
+ * Add a description to the upload.
+ * @param {string} language The language code for the description's language. Must have a template on the target wiki to work properly.
+ * @param {string} description The description of the file.
+ */
+ ForeignStructuredUpload.prototype.addDescription = function ( language, description ) {
+ this.descriptions.push( {
+ language: language,
+ text: description
+ } );
+ };
+
+ /**
+ * Set the date of creation for the upload.
+ * @param {Date} date
+ */
+ ForeignStructuredUpload.prototype.setDate = function ( date ) {
+ this.date = date;
+ };
+
+ /**
+ * Get the text of the file page, to be created on upload. Brings together
+ * several different pieces of information to create useful text.
+ * @return {string}
+ */
+ ForeignStructuredUpload.prototype.getText = function () {
+ return (
+ '{{' +
+ this.getTemplateName() +
+ '\n|description=' +
+ this.getDescriptions() +
+ '\n|date=' +
+ this.getDate() +
+ '\n|source=' +
+ this.getUser() +
+ '\n|author=' +
+ this.getUser() +
+ '\n}}\n\n' +
+ this.getLicense() +
+ '\n\n' +
+ this.getCategories()
+ );
+ };
+
+ /**
+ * Gets the wikitext for the creation date of this upload.
+ * @private
+ * @return {string}
+ */
+ ForeignStructuredUpload.prototype.getDate = function () {
+ if ( !this.date ) {
+ return '';
+ }
+
+ return this.date.toString();
+ };
+
+ /**
+ * Gets the name of the template to use for creating the file metadata.
+ * Override in subclasses for other templates.
+ * @private
+ * @return {string}
+ */
+ ForeignStructuredUpload.prototype.getTemplateName = function () {
+ return 'Information';
+ };
+
+ /**
+ * Fetches the wikitext for any descriptions that have been added
+ * to the upload.
+ * @private
+ * @return {string}
+ */
+ ForeignStructuredUpload.prototype.getDescriptions = function () {
+ var i, desc, templateCalls = [];
+
+ for ( i = 0; i < this.descriptions.length; i++ ) {
+ desc = this.descriptions[i];
+ templateCalls.push( '{{' + desc.language + '|' + desc.text + '}}' );
+ }
+
+ return templateCalls.join( '\n' );
+ };
+
+ /**
+ * Fetches the wikitext for the categories to which the upload will
+ * be added.
+ * @private
+ * @return {string}
+ */
+ ForeignStructuredUpload.prototype.getCategories = function () {
+ var i, cat, categoryLinks = [];
+
+ for ( i = 0; i < this.categories.length; i++ ) {
+ cat = this.categories[i];
+ categoryLinks.push( '[[Category:' + cat + ']]' );
+ }
+
+ return categoryLinks.join( '\n' );
+ };
+
+ /**
+ * Gets the wikitext for the license of the upload. Abstract for now.
+ * @private
+ * @return {string}
+ */
+ ForeignStructuredUpload.prototype.getLicense = function () {
+ return '';
+ };
+
+ /**
+ * Get the username.
+ * @private
+ * @return {string}
+ */
+ ForeignStructuredUpload.prototype.getUser = function () {
+ return mw.config.get( 'wgUserName' );
+ };
+
+ mw.ForeignStructuredUpload = ForeignStructuredUpload;
+}( mediaWiki, OO ) );
--- /dev/null
+( function ( mw, OO ) {
+ /**
+ * @class mw.ForeignUpload
+ * @extends mw.Upload
+ *
+ * Used to represent an upload in progress on the frontend.
+ *
+ * Subclassed to upload to a foreign API, with no other goodies. Use
+ * this for a generic foreign image repository on your wiki farm.
+ *
+ * Note you can provide the {@link #targetHost targetHost} or not - if the first argument is
+ * an object, we assume you want the default, and treat it as apiconfig
+ * instead.
+ *
+ * @constructor
+ * @param {string} [targetHost="commons.wikimedia.org"] Used to set up the target
+ * wiki. If not remote, this class behaves identically to mw.Upload (unless further subclassed)
+ * @param {Object} [apiconfig] Passed to the constructor of mw.ForeignApi or mw.Api, as needed.
+ */
+ function ForeignUpload( targetHost, apiconfig ) {
+ var api;
+
+ if ( typeof targetHost === 'object' ) {
+ // targetHost probably wasn't passed in, it must
+ // be apiconfig
+ apiconfig = targetHost;
+ } else {
+ // targetHost is a useful string, set it here
+ this.targetHost = targetHost || this.targetHost;
+ }
+
+ if ( location.host !== this.targetHost ) {
+ api = new mw.ForeignApi(
+ location.protocol + '//' + this.targetHost + '/w/api.php',
+ apiconfig
+ );
+ } else {
+ // We'll ignore the CORS and centralauth stuff if we're on Commons already
+ api = new mw.Api( apiconfig );
+ }
+
+ mw.Upload.call( this, api );
+ }
+
+ OO.inheritClass( ForeignUpload, mw.Upload );
+
+ /**
+ * @property targetHost
+ * Used to specify the target repository of the upload.
+ *
+ * You could override this to point at something that isn't Commons,
+ * but be sure it has the correct templates and is CORS and CentralAuth
+ * ready.
+ */
+ ForeignUpload.prototype.targetHost = 'commons.wikimedia.org';
+
+ mw.ForeignUpload = ForeignUpload;
+}( mediaWiki, OO ) );
'tests/qunit/suites/resources/mediawiki/mediawiki.storage.test.js',
'tests/qunit/suites/resources/mediawiki/mediawiki.template.test.js',
'tests/qunit/suites/resources/mediawiki/mediawiki.test.js',
+ 'tests/qunit/suites/resources/mediawiki/mediawiki.ForeignUpload.test.js',
+ 'tests/qunit/suites/resources/mediawiki/mediawiki.ForeignStructuredUpload.test.js',
'tests/qunit/suites/resources/mediawiki/mediawiki.Title.test.js',
'tests/qunit/suites/resources/mediawiki/mediawiki.toc.test.js',
'tests/qunit/suites/resources/mediawiki/mediawiki.track.test.js',
'mediawiki.api.upload',
'mediawiki.api.watch',
'mediawiki.ForeignApi.core',
+ 'mediawiki.ForeignUpload',
+ 'mediawiki.ForeignStructuredUpload',
'mediawiki.jqueryMsg',
'mediawiki.messagePoster',
'mediawiki.RegExp',
--- /dev/null
+( function ( mw ) {
+ QUnit.module( 'mediawiki.ForeignStructuredUpload', QUnit.newMwEnvironment( {} ) );
+
+ QUnit.test( 'Constructor check', function ( assert ) {
+ QUnit.expect( 3 );
+ var upload = new mw.ForeignStructuredUpload();
+
+ assert.ok( upload, 'The ForeignUpload constructor is working.' );
+ assert.ok( upload.descriptions, 'The descriptions array was initialized properly' );
+ assert.ok( upload.categories, 'The categories array was initialized properly' );
+ } );
+
+ QUnit.test( 'getText', function ( assert ) {
+ QUnit.expect( 1 );
+
+ var upload = new mw.ForeignStructuredUpload();
+
+ // Set basic information
+ upload.addDescription( 'en', 'Test description one two three' );
+ upload.addDescription( 'en-x-piglatin', 'Esttay escriptionday unway ootay eethray' );
+ upload.setDate( '1776-07-04' );
+ upload.addCategories( [ 'Test 1', 'Test 2' ] );
+ upload.addCategories( [ 'Test 3' ] );
+
+ // Fake the user
+ this.sandbox.stub( upload, 'getUser' ).returns( 'Test user' );
+
+ assert.strictEqual( upload.getText().trim(), '{{Information\n|description={{en|Test description one two three}}\n{{en-x-piglatin|Esttay escriptionday unway ootay eethray}}\n|date=1776-07-04\n|source=Test user\n|author=Test user\n}}\n\n\n\n[[Category:Test 1]]\n[[Category:Test 2]]\n[[Category:Test 3]]' );
+ } );
+}( mediaWiki ) );
--- /dev/null
+( function ( mw ) {
+ QUnit.module( 'mediawiki.ForeignUpload', QUnit.newMwEnvironment( {} ) );
+
+ QUnit.test( 'Constructor check', function ( assert ) {
+ QUnit.expect( 3 );
+ var upload = new mw.ForeignUpload();
+
+ assert.ok( upload, 'The ForeignUpload constructor is working.' );
+ assert.strictEqual( upload.targetHost, 'commons.wikimedia.org', 'Default target host is correct' );
+ assert.ok( upload.api instanceof mw.ForeignApi, 'API is correctly configured to point at a foreign wiki.' );
+ } );
+}( mediaWiki ) );