jenkins-bot has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/386413 )
Change subject: Add patent license agreement ...................................................................... Add patent license agreement Bug: T178513 Change-Id: I5194beef2378c636f06f0a61cc3daf9a7cec99bd --- M UploadWizard.config.php M extension.json M i18n/en.json M i18n/qqq.json M resources/controller/uw.controller.Details.js A resources/deed/dialog/uw.deed.dialog.PatentDialog.js A resources/deed/dialog/uw.deed.dialog.base.js M resources/deed/uw.deed.Abstract.js M resources/deed/uw.deed.OwnWork.js M resources/deed/uw.deed.ThirdParty.js A resources/images/no-weapons.svg M resources/ui/steps/uw.ui.Details.js M resources/uploadWizard.css M tests/qunit/controller/uw.controller.Deed.test.js 14 files changed, 582 insertions(+), 47 deletions(-) Approvals: MarkTraceur: Looks good to me, approved jenkins-bot: Verified diff --git a/UploadWizard.config.php b/UploadWizard.config.php index 06148ba..35371bf 100644 --- a/UploadWizard.config.php +++ b/UploadWizard.config.php @@ -523,6 +523,16 @@ ] ], + 'patents' => [ + 'extensions' => [ 'stl' ], + 'url' => [ + 'legalcode' => '//wikimediafoundation.org/wiki/Wikimedia_3D_file_patent_license', + 'warranty' => '//meta.wikimedia.org/wiki/Wikilegal/3D_files_and_3D_printing', + 'license' => '//meta.wikimedia.org/wiki/Wikilegal/3D_files_and_3D_printing', + 'weapons' => '//meta.wikimedia.org/wiki/Wikilegal/3D_files_and_3D_printing#Weapons', + ], + ], + // Max author string length 'maxAuthorLength' => 10000, diff --git a/extension.json b/extension.json index 12a8366..85d4017 100644 --- a/extension.json +++ b/extension.json @@ -675,7 +675,9 @@ ], "messages": [ "mwe-upwiz-file-some-failed", - "mwe-upwiz-file-all-failed" + "mwe-upwiz-file-all-failed", + "mwe-upwiz-patent-weapon-policy", + "mwe-upwiz-patent-weapon-policy-link" ], "targets": [ "desktop", "mobile" ], "group": "ext.uploadWizard" @@ -761,6 +763,9 @@ "dependencies": [ "uw.deed.base" ], + "messages": [ + "mwe-upwiz-patent-dialog-title-filename" + ], "targets": [ "desktop", "mobile" ], "group": "ext.uploadWizard" }, @@ -770,7 +775,8 @@ ], "dependencies": [ "oojs", - "uw.deed.Abstract" + "uw.deed.Abstract", + "uw.deed.dialog.PatentDialog" ], "messages": [ "mwe-upwiz-tooltip-sign", @@ -810,6 +816,8 @@ "mwe-upwiz-source-ownwork-cc-zero-explain", "mwe-upwiz-source-ownwork-assert-generic", "mwe-upwiz-source-ownwork-generic-explain", + "mwe-upwiz-patent", + "mwe-upwiz-error-patent-disagree", "mwe-upwiz-error-signature-blank", "mwe-upwiz-error-signature-too-long", "mwe-upwiz-error-signature-too-short", @@ -865,6 +873,42 @@ "targets": [ "desktop", "mobile" ], "group": "ext.uploadWizard" }, + "uw.deed.dialog.base": { + "scripts": [ + "resources/deed/dialog/uw.deed.dialog.base.js" + ], + "dependencies": [ + "uw.deed.base" + ], + "targets": [ "desktop", "mobile" ], + "group": "ext.uploadWizard" + }, + "uw.deed.dialog.PatentDialog": { + "scripts": [ + "resources/deed/dialog/uw.deed.dialog.PatentDialog.js" + ], + "dependencies": [ + "mediawiki.language", + "oojs", + "oojs-ui-core", + "oojs-ui-windows", + "uw.deed.dialog.base" + ], + "messages": [ + "mwe-upwiz-patent-dialog-title", + "mwe-upwiz-patent-dialog-button-back", + "mwe-upwiz-patent-dialog-button-next", + "mwe-upwiz-patent-dialog-title-warranty", + "mwe-upwiz-patent-dialog-text-warranty", + "mwe-upwiz-patent-dialog-link-warranty", + "mwe-upwiz-patent-dialog-title-license", + "mwe-upwiz-patent-dialog-text-license", + "mwe-upwiz-patent-dialog-link-license", + "mwe-upwiz-patent-dialog-checkbox-label" + ], + "targets": [ "desktop", "mobile" ], + "group": "ext.uploadWizard" + }, "uw.units": { "scripts": [ "resources/uw.units.js" diff --git a/i18n/en.json b/i18n/en.json index 80bbba3..e4720d9 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -121,6 +121,20 @@ "mwe-upwiz-source-thirdparty-cases": "Now tell us why you are sure you have the right to publish {{PLURAL:$1|this work|these works}}:", "mwe-upwiz-source-thirdparty-accept": "OK", "mwe-upwiz-source-custom": "Provide copyright information for each file individually on the next page.", + "mwe-upwiz-patent": "I, $2, would like to grant a permanent patent license to any users of {{PLURAL:$1|the file|the files}} and related 3D objects ([$3 legal code]).", + "mwe-upwiz-patent-dialog-title": "Patent rights", + "mwe-upwiz-patent-dialog-title-filename": "Legal rights for: $1", + "mwe-upwiz-patent-dialog-button-back": "Back", + "mwe-upwiz-patent-dialog-button-next": "Next", + "mwe-upwiz-patent-dialog-title-warranty": "Warranty about Patents", + "mwe-upwiz-patent-dialog-text-warranty": "Use of {{PLURAL:$1|this file|these files}} and any objects depicted in {{PLURAL:$1|the file|the files}} will not knowingly or recklessly infringe any patents.", + "mwe-upwiz-patent-dialog-link-warranty": "Learn more", + "mwe-upwiz-patent-dialog-title-license": "Patent License", + "mwe-upwiz-patent-dialog-text-license": "Any 3D objects depicted in {{PLURAL:$1|the file|the files}} are my own work.", + "mwe-upwiz-patent-dialog-link-license": "Learn more", + "mwe-upwiz-patent-dialog-checkbox-label": "I agree with these terms", + "mwe-upwiz-patent-weapon-policy": "Users should avoid uploading any 3D models that could be viewed as a weapon or \"defense article\".\nThe Commons community might remove such items upon moderation.", + "mwe-upwiz-patent-weapon-policy-link": "Read policy details", "mwe-upwiz-more-options": "Add location and more information …", "mwe-upwiz-copy-metadata": "Copy information to all uploads following …", "mwe-upwiz-copy-metadata-button": "Copy", @@ -220,6 +234,7 @@ "mwe-upwiz-error-license-wikitext-too-short": "The wikitext here is too short to be a license", "mwe-upwiz-error-license-wikitext-too-long": "The wikitext you entered is too long.", "mwe-upwiz-error-license-wikitext-missing-template": "The wikitext you entered doesn't contain a valid license template.", + "mwe-upwiz-error-patent-disagree": "You need to agree with the terms.", "mwe-upwiz-warning-categories-missing": "It is recommended that you fill in some categories for your uploads.", "mwe-upwiz-warning-postdate": "The date that you selected is in the future.", "mwe-upwiz-details-error-count": "There {{PLURAL:$1|is one error|are $1 errors}} with the {{PLURAL:$2|form|forms}} above. Correct the {{PLURAL:$1|error|errors}}, and try submitting again.", diff --git a/i18n/qqq.json b/i18n/qqq.json index 7086a39..90d2bf3 100644 --- a/i18n/qqq.json +++ b/i18n/qqq.json @@ -148,6 +148,20 @@ "mwe-upwiz-source-thirdparty-cases": "This message is followed by the License form. Parameters:\n* $1 - number of works. i.e. number of uploads", "mwe-upwiz-source-thirdparty-accept": "{{Identical|OK}}", "mwe-upwiz-source-custom": "Prompts the user for the copyright information for each file.", + "mwe-upwiz-patent": "Parameters:\n* $1 - number of works (number of 3D uploads)\n* $2 - author name\n* $3 - full URL\n* $4 - a user object, which can be used for GENDER", + "mwe-upwiz-patent-dialog-title": "Title for the dialog to confirm agreement with patent rights.", + "mwe-upwiz-patent-dialog-title-filename": "Title for the dialog to confirm agreement with patent rights for a single file. Parameters:\n$ $1 - the upload filename", + "mwe-upwiz-patent-dialog-button-back": "Title text for the \"back\" button in the patent rights dialog.", + "mwe-upwiz-patent-dialog-button-next": "Text for the \"next\" button in the patent rights dialog.", + "mwe-upwiz-patent-dialog-title-warranty": "Title for the patent rights dialog paragraph about patents warranty.", + "mwe-upwiz-patent-dialog-text-warranty": "Text for the patent rights dialog paragraph about patents warranty.\n\nParameters:\n* $1 - the number of uploads for PLURAL", + "mwe-upwiz-patent-dialog-link-warranty": "Link text for the patent rights dialog paragraph about patents warranty.", + "mwe-upwiz-patent-dialog-title-license": "Title for the patent rights dialog paragraph about patents license.", + "mwe-upwiz-patent-dialog-text-license": "Text for the patent rights dialog paragraph about patents license.\n\nParameters:\n* $1 - the number of uploads for PLURAL", + "mwe-upwiz-patent-dialog-link-license": "Link text for the patent rights dialog paragraph about patents license.", + "mwe-upwiz-patent-dialog-checkbox-label": "Label for the checbox to agree with the patent terms.", + "mwe-upwiz-patent-weapon-policy": "Text to instruct users not to upload 3D models that could be viewed as a weapon or \"defense article\".", + "mwe-upwiz-patent-weapon-policy-link": "Link text to the policy details", "mwe-upwiz-more-options": "Text for a 'more options' toggle that opens more of a form so a user can make more detailed descriptions/add more properties for uploaded images.", "mwe-upwiz-copy-metadata": "Toggler which expands/collapses a selection of checkboxes vertically which allow the user to selectively copy metadata from the first upload to other uploads.", "mwe-upwiz-copy-metadata-button": "Label of the button which copies the selected metadata from the first upload to all other uploads.\n{{Identical|Copy}}", @@ -247,6 +261,7 @@ "mwe-upwiz-error-license-wikitext-too-short": "Message for a failed minimum length validation on the license form.", "mwe-upwiz-error-license-wikitext-too-long": "Message for a failed maximum length validation on the license form.", "mwe-upwiz-error-license-wikitext-missing-template": "Message for when the wikitext doesn't contain a valid license template.", + "mwe-upwiz-error-patent-disagree": "Error message for when the uploader doesn't agree with the patent terms.", "mwe-upwiz-warning-categories-missing": "Warning message displayed when the user has not selected any categories.", "mwe-upwiz-warning-postdate": "Warning message displayed when the user selects a file creation date that is in the future.", "mwe-upwiz-details-error-count": "Used as error message. Parameters:\n* $1 - number of errors\n* $2 - number of forms. i.e. number of uploads", diff --git a/resources/controller/uw.controller.Details.js b/resources/controller/uw.controller.Details.js index eac65f8..f64b4ca 100644 --- a/resources/controller/uw.controller.Details.js +++ b/resources/controller/uw.controller.Details.js @@ -314,7 +314,6 @@ // Disable edit interface this.ui.disableEdits(); - this.ui.previousButton.$element.hide(); this.removeCopyMetadataFeature(); return this.transitionAll().then( function () { @@ -331,7 +330,7 @@ * See UI class for more. */ uw.controller.Details.prototype.showErrors = function () { - this.ui.previousButton.$element.show(); + this.ui.enableEdits(); this.removeCopyMetadataFeature(); this.addCopyMetadataFeature(); diff --git a/resources/deed/dialog/uw.deed.dialog.PatentDialog.js b/resources/deed/dialog/uw.deed.dialog.PatentDialog.js new file mode 100644 index 0000000..60439b9 --- /dev/null +++ b/resources/deed/dialog/uw.deed.dialog.PatentDialog.js @@ -0,0 +1,172 @@ +/* + * This file is part of the MediaWiki extension UploadWizard. + * + * UploadWizard is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * UploadWizard is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with UploadWizard. If not, see <http://www.gnu.org/licenses/>. + */ + +( function ( mw, uw, $, OO ) { + /** + * @param {Object} config Dialog config + * @param {Object} uwConfig UploadWizard config + * @param {mw.UploadWizardUpload[]} uploads + * @constructor + */ + uw.PatentDialog = function PatentDialog( config, uwConfig, uploads ) { + uw.PatentDialog.super.call( this, config ); + this.config = uwConfig; + this.panels = config.panels || []; + this.uploads = uploads; + }; + + OO.inheritClass( uw.PatentDialog, OO.ui.ProcessDialog ); + OO.mixinClass( uw.PatentDialog, OO.EventEmitter ); + + uw.PatentDialog.static.name = 'uwPatentDialog'; + uw.PatentDialog.static.title = mw.msg( 'mwe-upwiz-patent-dialog-title' ); + uw.PatentDialog.static.actions = [ + { + flags: [ 'primary', 'progressive' ], + indicator: 'next', + action: 'confirm', + label: OO.ui.deferMsg( 'mwe-upwiz-patent-dialog-button-next' ), + disabled: true + }, + { + flags: [ 'safe', 'back' ], + icon: 'previous', + title: OO.ui.deferMsg( 'mwe-upwiz-patent-dialog-button-back' ), + framed: false + } + ]; + + uw.PatentDialog.prototype.initialize = function () { + var filenames = [], + label = new OO.ui.LabelWidget(), + panels = new OO.ui.PanelLayout( { padded: true, expanded: false } ); + + uw.PatentDialog.super.prototype.initialize.apply( this, arguments ); + + $.each( this.uploads, function ( i, upload ) { + filenames.push( + // use given title (if available already) or fall back to filename + upload.details ? upload.details.getTitle().getMainText() : upload.title.getMainText() + ); + } ); + + this.content = new OO.ui.PanelLayout( { padded: false, expanded: false } ); + this.content.$element.addClass( 'mwe-upwiz-patent-rights' ); + + if ( $.inArray( 'filelist', this.panels ) >= 0 ) { + label.setLabel( mw.msg( 'mwe-upwiz-patent-dialog-title-filename', mw.language.listToText( filenames ) ) ); + label.$element.addClass( 'oo-ui-processDialog-title mwe-upwiz-patent-rights-filelist' ); + this.content.$element.append( label.$element ); + } + + if ( $.inArray( 'warranty', this.panels ) >= 0 ) { + panels.$element.append( this.getWarrantyLayout().$element ); + } + + if ( $.inArray( 'license', this.panels ) >= 0 ) { + panels.$element.append( this.getLicenseLayout().$element ); + } + + this.checkbox = new OO.ui.CheckboxInputWidget(); + this.checkbox.connect( this, { change: 'onCheckboxChange' } ); + panels.$element.append( this.getCheckboxLayout().$element ); + + this.content.$element.append( panels.$element ); + this.$body.append( this.content.$element ); + }; + + /** + * @return {OO.ui.PanelLayout} + */ + uw.PatentDialog.prototype.getWarrantyLayout = function () { + var layout = new OO.ui.PanelLayout( { padded: true, expanded: false } ); + + layout.$element.append( + $( '<strong>' ).text( mw.msg( 'mwe-upwiz-patent-dialog-title-warranty' ) ), + $( '<p>' ).text( mw.msg( 'mwe-upwiz-patent-dialog-text-warranty', this.uploads.length ) ), + $( '<a>' ) + .text( mw.msg( 'mwe-upwiz-patent-dialog-link-warranty' ) ) + .attr( { target: '_blank', href: this.config.patents.url.warranty } ) + ); + + return layout; + }; + + /** + * @return {OO.ui.PanelLayout} + */ + uw.PatentDialog.prototype.getLicenseLayout = function () { + var layout = new OO.ui.PanelLayout( { padded: true, expanded: false } ); + + layout.$element.append( + $( '<strong>' ).text( mw.msg( 'mwe-upwiz-patent-dialog-title-license' ) ), + $( '<p>' ).text( mw.msg( 'mwe-upwiz-patent-dialog-text-license', this.uploads.length ) ), + $( '<a>' ) + .text( mw.msg( 'mwe-upwiz-patent-dialog-link-license' ) ) + .attr( { target: '_blank', href: this.config.patents.url.license } ) + ); + + return layout; + }; + + /** + * @return {OO.ui.PanelLayout} + */ + uw.PatentDialog.prototype.getCheckboxLayout = function () { + var checkbox = new OO.ui.FieldLayout( this.checkbox, { + label: mw.msg( 'mwe-upwiz-patent-dialog-checkbox-label' ), + align: 'inline' + } ); + + return new OO.ui.PanelLayout( { + padded: true, + expanded: false, + $content: checkbox.$element + } ); + }; + + /** + * @param {boolean} checked + */ + uw.PatentDialog.prototype.onCheckboxChange = function ( checked ) { + var button = this.actions.get( { flags: 'primary' } )[ 0 ]; + button.setDisabled( !checked ); + }; + + /** + * @param {string} action + * @return {OO.ui.Process} Action process + */ + uw.PatentDialog.prototype.getActionProcess = function ( action ) { + var dialog = this; + + if ( action === '' ) { + this.emit( 'disagree' ); + } else if ( action === 'confirm' ) { + return new OO.ui.Process( function () { + dialog.emit( 'agree' ); + dialog.close( { action: action } ); + } ); + } + + return uw.PatentDialog.super.prototype.getActionProcess.call( this, action ); + }; + + uw.PatentDialog.prototype.getBodyHeight = function () { + return this.content.$element.outerHeight( true ); + }; +}( mediaWiki, mediaWiki.uploadWizard, jQuery, OO ) ); diff --git a/resources/deed/dialog/uw.deed.dialog.base.js b/resources/deed/dialog/uw.deed.dialog.base.js new file mode 100644 index 0000000..43b9e8c --- /dev/null +++ b/resources/deed/dialog/uw.deed.dialog.base.js @@ -0,0 +1,21 @@ +/* + * This file is part of the MediaWiki extension UploadWizard. + * + * UploadWizard is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * UploadWizard is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with UploadWizard. If not, see <http://www.gnu.org/licenses/>. + */ + +( function ( uw ) { + // create UploadWizard deed.dialog namespace + uw.deed.dialog = {}; +}( mediaWiki.uploadWizard ) ); diff --git a/resources/deed/uw.deed.Abstract.js b/resources/deed/uw.deed.Abstract.js index 05fdcaf..10dced8 100644 --- a/resources/deed/uw.deed.Abstract.js +++ b/resources/deed/uw.deed.Abstract.js @@ -37,7 +37,7 @@ uw.deed.Abstract.prototype.instanceCount = 0; /** - * @returns {number} + * @return {number} */ uw.deed.Abstract.prototype.getInstanceCount = function () { return this.instanceCount; @@ -103,4 +103,86 @@ this.name = serialized.name; } }; + + /** + * @param {mw.UploadWizardUpload[]} uploads Array of uploads + * @return {number} + */ + uw.deed.Abstract.prototype.get3DCount = function ( uploads ) { + var extensions = this.config.patents ? this.config.patents.extensions : [], + threeDCount = 0; + + $.each( uploads, function ( i, upload ) { + if ( $.inArray( upload.title.getExtension().toLowerCase(), extensions ) >= 0 ) { + threeDCount++; + } + } ); + + return threeDCount; + }; + + /** + * @param {mw.UploadWizardUpload[]} uploads + * @return {uw.FieldLayout} + */ + uw.deed.Abstract.prototype.getPatentAgreementField = function ( uploads ) { + var field = new OO.ui.HiddenInputWidget(); + field.getErrors = this.getPatentAgreementErrors.bind( this, field, uploads ); + field.getWarnings = $.Deferred().resolve( [] ).promise.bind(); + + return new uw.FieldLayout( field ); + }; + + /** + * @param {mw.UploadWizardUpload[]} uploads + * @return {uw.PatentDialog} + */ + uw.deed.Abstract.prototype.getPatentDialog = function ( uploads ) { + var config = { panels: [ 'warranty' ] }; + + // Only show filename list when in "details" step & we're showing the dialog for individual files + if ( uploads[ 0 ] && uploads[ 0 ].state === 'details' ) { + config.panels.unshift( 'filelist' ); + } + + return new uw.PatentDialog( config, this.config, uploads ); + }; + + /** + * @param {OO.ui.InputWidget} input + * @param {mw.UploadWizardUpload[]} uploads + * @param {boolean} thorough + * @return {jQuery.Promise} + */ + uw.deed.Abstract.prototype.getPatentAgreementErrors = function ( input, uploads, thorough ) { + var deed = this, + windowManager, dialog, deferred; + + // We only want to test this on submit + if ( !thorough ) { + return $.Deferred().resolve( [] ).promise(); + } + + if ( this.patentAgreed !== true ) { + deferred = $.Deferred(); + windowManager = new OO.ui.WindowManager(); + dialog = this.getPatentDialog( uploads ); + + $( 'body' ).append( windowManager.$element ); + windowManager.addWindows( [ dialog ] ); + windowManager.openWindow( dialog ); + + dialog.on( 'disagree', function () { + deferred.resolve( [ mw.message( 'mwe-upwiz-error-patent-disagree' ) ] ); + } ); + dialog.on( 'agree', function () { + deed.patentAgreed = true; + deferred.resolve( [] ); + } ); + + return deferred.promise(); + } else { + return $.Deferred().resolve( [] ).promise(); + } + }; }( mediaWiki, mediaWiki.uploadWizard ) ); diff --git a/resources/deed/uw.deed.OwnWork.js b/resources/deed/uw.deed.OwnWork.js index f5f008a..e046800 100644 --- a/resources/deed/uw.deed.OwnWork.js +++ b/resources/deed/uw.deed.OwnWork.js @@ -32,6 +32,7 @@ uw.deed.Abstract.call( this, 'ownwork', config ); this.uploadCount = uploads.length; + this.threeDCount = this.get3DCount( uploads ); if ( !prefAuthName ) { prefAuthName = mw.config.get( 'wgUserName' ); @@ -65,6 +66,26 @@ this.licenseInput.$element.addClass( 'mwe-upwiz-deed-license' ); this.licenseInputField = new uw.FieldLayout( this.licenseInput ); } + + // grant patent license + if ( this.threeDCount > 0 ) { + this.patentAuthorInput = new OO.ui.TextInputWidget( { + name: 'patent-author', + title: mw.message( 'mwe-upwiz-tooltip-sign' ).text(), + value: prefAuthName, + classes: [ 'mwe-upwiz-sign' ] + } ); + // keep authors in sync! + this.patentAuthorInput.on( 'change', function () { + deed.authorInput.setValue( deed.patentAuthorInput.getValue() ); + deed.fakeAuthorInput.setValue( deed.patentAuthorInput.getValue() ); + } ); + this.authorInput.on( 'change', function () { + deed.patentAuthorInput.setValue( deed.authorInput.getValue() ); + } ); + + this.patentAgreementField = this.getPatentAgreementField( uploads ); + } }; OO.inheritClass( uw.deed.OwnWork, uw.deed.Abstract ); @@ -77,13 +98,18 @@ if ( this.showCustomDiv ) { fields.push( this.licenseInputField ); } + if ( this.threeDCount > 0 ) { + fields.push( this.patentAuthorInputField ); + fields.push( this.patentAgreementField ); + } return fields; }; uw.deed.OwnWork.prototype.setFormFields = function ( $selector ) { var $customDiv, $formFields, $toggler, crossfaderWidget, defaultLicense, defaultLicenseURL, defaultLicenseMsg, defaultLicenseExplainMsg, - defaultLicenseLink, $standardDiv, $crossfader, deed, languageCode; + defaultLicenseLink, $standardDiv, $crossfader, deed, languageCode, + patentMsg, patentLink, $patentDiv, patentWidget; this.$selector = $selector; deed = this; @@ -128,27 +154,9 @@ crossfaderWidget = new OO.ui.Widget(); crossfaderWidget.$element.append( $crossfader ); // See uw.DetailsWidget - crossfaderWidget.getErrors = function () { - var - errors = [], - minLength = deed.config.minAuthorLength, - maxLength = deed.config.maxAuthorLength, - text = deed.authorInput.getValue().trim(); + crossfaderWidget.getErrors = this.getAuthorErrors.bind( this, this.authorInput ); + crossfaderWidget.getWarnings = this.getAuthorWarnings.bind( this, this.authorInput ); - if ( text === '' ) { - errors.push( mw.message( 'mwe-upwiz-error-signature-blank' ) ); - } else if ( text.length < minLength ) { - errors.push( mw.message( 'mwe-upwiz-error-signature-too-short', minLength ) ); - } else if ( text.length > maxLength ) { - errors.push( mw.message( 'mwe-upwiz-error-signature-too-long', maxLength ) ); - } - - return $.Deferred().resolve( errors ).promise(); - }; - // See uw.DetailsWidget - crossfaderWidget.getWarnings = function () { - return $.Deferred().resolve( [] ).promise(); - }; this.authorInputField = new uw.FieldLayout( crossfaderWidget ); // Aggregate 'change' event this.authorInput.on( 'change', OO.ui.debounce( function () { @@ -156,24 +164,51 @@ }, 500 ) ); $formFields = $( '<div class="mwe-upwiz-deed-form-internal" />' ) - .append( - this.authorInputField.$element, - this.showCustomDiv ? this.licenseInputField.$element.hide() : '' - ); - - $toggler = $( '<p class="mwe-more-options" style="text-align: right"></p>' ) - .append( $( '<a />' ) - .msg( 'mwe-upwiz-license-show-all' ) - .click( function () { - if ( $crossfader.data( 'crossfadeDisplay' ).get( 0 ) === $customDiv.get( 0 ) ) { - deed.standardLicense(); - } else { - deed.customLicense(); - } - } ) ); + .append( this.authorInputField.$element ); if ( this.showCustomDiv ) { - $formFields.append( $toggler ); + $toggler = $( '<p class="mwe-more-options" style="text-align: right"></p>' ) + .append( $( '<a />' ) + .msg( 'mwe-upwiz-license-show-all' ) + .click( function () { + if ( $crossfader.data( 'crossfadeDisplay' ).get( 0 ) === $customDiv.get( 0 ) ) { + deed.standardLicense(); + } else { + deed.customLicense(); + } + } ) ); + + $formFields.append( this.licenseInputField.$element.hide(), $toggler ); + } + + if ( this.threeDCount > 0 ) { + patentMsg = 'mwe-upwiz-patent'; + patentLink = $( '<a>' ).attr( { target: '_blank', href: this.config.patents.url.legalcode } ); + + $patentDiv = $( '<div class="mwe-upwiz-patent" />' ).append( + $( '<p>' ).msg( + patentMsg, + this.threeDCount, + this.patentAuthorInput.$element, + patentLink, + mw.user + ) + ); + + patentWidget = new OO.ui.Widget(); + patentWidget.$element.append( $patentDiv ); + + // See uw.DetailsWidget + patentWidget.getErrors = this.getAuthorErrors.bind( this, this.patentAuthorInput ); + patentWidget.getWarnings = this.getAuthorWarnings.bind( this, this.patentAuthorInput ); + + this.patentAuthorInputField = new uw.FieldLayout( patentWidget ); + deed.patentAuthorInput.on( 'change', OO.ui.debounce( function () { + patentWidget.emit( 'change' ); + }, 500 ) ); + + $formFields.append( this.patentAuthorInputField.$element ); + $formFields.append( this.patentAgreementField.$element ); } this.$form.append( $formFields ).appendTo( $selector ); @@ -234,6 +269,10 @@ serialized.license = this.licenseInput.getSerialized(); } + if ( this.threeDCount > 0 ) { + serialized.patentAuthor = this.patentAuthorInput.getValue(); + } + return serialized; }; @@ -254,6 +293,10 @@ this.customLicense(); this.licenseInput.setSerialized( serialized.license ); } + } + + if ( this.threeDCount > 0 && serialized.patentAuthor ) { + this.patentAuthorInput.setValue( serialized.patentAuthor ); } }; @@ -315,4 +358,48 @@ $toggler.msg( 'mwe-upwiz-license-show-recommended' ); }; + + /** + * @param {OO.ui.InputWidget} input + * @return {jQuery.Promise} + */ + uw.deed.OwnWork.prototype.getAuthorErrors = function ( input ) { + var + errors = [], + minLength = this.config.minAuthorLength, + maxLength = this.config.maxAuthorLength, + text = input.getValue().trim(); + + if ( text === '' ) { + errors.push( mw.message( 'mwe-upwiz-error-signature-blank' ) ); + } else if ( text.length < minLength ) { + errors.push( mw.message( 'mwe-upwiz-error-signature-too-short', minLength ) ); + } else if ( text.length > maxLength ) { + errors.push( mw.message( 'mwe-upwiz-error-signature-too-long', maxLength ) ); + } + + return $.Deferred().resolve( errors ).promise(); + }; + + /** + * @return {jQuery.Promise} + */ + uw.deed.OwnWork.prototype.getAuthorWarnings = function () { + return $.Deferred().resolve( [] ).promise(); + }; + + /** + * @param {mw.UploadWizardUpload[]} uploads + * @return {uw.PatentDialog} + */ + uw.deed.OwnWork.prototype.getPatentDialog = function ( uploads ) { + var config = { panels: [ 'warranty', 'license' ] }; + + // Only show filename list when in "details" step & we're showing the dialog for individual files + if ( uploads[ 0 ] && uploads[ 0 ].state === 'details' ) { + config.panels.unshift( 'filelist' ); + } + + return new uw.PatentDialog( config, this.config, uploads ); + }; }( mediaWiki, mediaWiki.uploadWizard, jQuery, OO ) ); diff --git a/resources/deed/uw.deed.ThirdParty.js b/resources/deed/uw.deed.ThirdParty.js index ec8ed59..09b3b66 100644 --- a/resources/deed/uw.deed.ThirdParty.js +++ b/resources/deed/uw.deed.ThirdParty.js @@ -31,6 +31,7 @@ uw.deed.Abstract.call( this, 'thirdparty', config ); this.uploadCount = uploads.length; + this.threeDCount = this.get3DCount( uploads ); this.sourceInput = new OO.ui.MultilineTextInputWidget( { autosize: true, @@ -111,6 +112,10 @@ this.licenseInputField = new uw.FieldLayout( this.licenseInput, { label: mw.message( 'mwe-upwiz-source-thirdparty-cases', this.uploadCount ).text() } ); + + if ( this.threeDCount > 0 ) { + this.patentAgreementField = this.getPatentAgreementField( uploads ); + } }; OO.inheritClass( uw.deed.ThirdParty, uw.deed.Abstract ); @@ -119,7 +124,11 @@ * @return {uw.FieldLayout[]} Fields that need validation */ uw.deed.ThirdParty.prototype.getFields = function () { - return [ this.authorInputField, this.sourceInputField, this.licenseInputField ]; + var fields = [ this.authorInputField, this.sourceInputField, this.licenseInputField ]; + if ( this.threeDCount > 0 ) { + fields.push( this.patentAgreementField ); + } + return fields; }; uw.deed.ThirdParty.prototype.setFormFields = function ( $selector ) { @@ -144,6 +153,10 @@ .append( this.licenseInputField.$element ) ); + if ( this.threeDCount > 0 ) { + $formFields.append( this.patentAgreementField.$element ); + } + this.$form.append( $formFields ); $selector.append( this.$form ); diff --git a/resources/images/no-weapons.svg b/resources/images/no-weapons.svg new file mode 100644 index 0000000..c7c0db7 --- /dev/null +++ b/resources/images/no-weapons.svg @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg version="1.1" viewBox="0 0 26 26" xmlns="http://www.w3.org/2000/svg"> +<title>Group 5</title> +<desc>Created with Sketch.</desc> +<g fill="none" fill-rule="evenodd"> +<g transform="translate(-237 -711)"> +<g transform="translate(238 712)"> +<circle cx="12" cy="12" r="12" stroke="#000" stroke-width="2"/> +<path d="m6.7059 1.7647l10.684 20.7" stroke="#000" stroke-linecap="square" stroke-width="2"/> +<path d="m19.951 7.0363h-0.68282l-0.47409 0.47289h-11.527l-0.27797-0.42606h-0.4985l-0.38043 0.88374h-0.85812v1.3294c0 0.057435-0.29478 0.30018-0.33841 0.36863-0.093657 0.14689-0.20392 0.44527-0.027217 0.55774 0.11787 0.072444 0.36122 0.044627 0.4971 0.08105 0.10707 0.027817 0.20392 0.064039 0.29738 0.11967 0 0 0.63639 0.25376 0.63639 1.1571 0 0 0 0.94878-0.6482 2.1291-0.3234 0.59016-1.9186 2.6824-1.9186 4.3 0 0.67101 0.74005 0.57855 0.74005 0.57855h3.7677s0.51071-0.1629 0.51071-0.87874l1.4683-4.0591s0.24755-0.8247 0.89134-0.38063c0.36262 0.25095 2.1451 0.12187 2.7011 0.12187 0.56214 0 1.1273-0.47329 1.23-0.97119l0.13868-1.1401s0.093857-0.34621 1.2027-0.34621h4.0713s0.64179-0.024215 0.64179-0.76447v-1.3294l-0.68862-1.331-0.47449-0.47289zm-6.2332 5.7485h-1.8507s-0.88994 0.044627-0.88994-0.92817c0-0.79168 0.59837-0.9834 0.92477-0.9834-0.14529 1.4279 0.99701 1.6154 0.70703 0.92036-0.29038-0.69663 0.45308-1.017 0.45308-1.017l0.79469 0.0078048s0.67081 0.03262 0.67081 0.99121c-2.001e-4 0.66-0.3234 1.0092-0.80969 1.0092z" fill="#000" fill-rule="nonzero"/> +</g> +</g> +</g> +</svg> diff --git a/resources/ui/steps/uw.ui.Details.js b/resources/ui/steps/uw.ui.Details.js index 5e1a041..582ef80 100644 --- a/resources/ui/steps/uw.ui.Details.js +++ b/resources/ui/steps/uw.ui.Details.js @@ -72,6 +72,21 @@ uw.ui.Details.prototype.load = function ( uploads ) { uw.ui.Step.prototype.load.call( this, uploads ); + if ( this.get3DCount( uploads ) > 0 ) { + this.$div.prepend( + $( '<div>' ) + .addClass( 'mwe-upwiz-patent-weapon-policy ui-corner-all' ) + .append( + $( '<p>' ).append( mw.msg( 'mwe-upwiz-patent-weapon-policy' ) ), + $( '<p>' ).append( + $( '<a>' ) + .text( mw.msg( 'mwe-upwiz-patent-weapon-policy-link' ) ) + .attr( { target: '_blank', href: mw.UploadWizard.config.patents.url.weapons } ) + ) + ) + ); + } + this.$div.prepend( $( '<div>' ) .attr( 'id', 'mwe-upwiz-macro-files' ) @@ -145,6 +160,17 @@ this.$div .find( '.mwe-upwiz-data' ) .morphCrossfade( '.mwe-upwiz-submitting' ); + + this.previousButton.$element.hide(); + this.$div.find( '.mwe-upwiz-patent-weapon-policy' ).hide(); + }; + + /** + * Re-enabled edits to the details. + */ + uw.ui.Details.prototype.enableEdits = function () { + this.previousButton.$element.show(); + this.$div.find( '.mwe-upwiz-patent-weapon-policy' ).show(); }; /** @@ -213,4 +239,21 @@ } }; + /** + * @param {mw.UploadWizardUpload[]} uploads Array of uploads + * @return {number} + */ + uw.ui.Details.prototype.get3DCount = function ( uploads ) { + var extensions = mw.UploadWizard.config.patents.extensions, + threeDCount = 0; + + $.each( uploads, function ( i, upload ) { + if ( $.inArray( upload.title.getExtension().toLowerCase(), extensions ) >= 0 ) { + threeDCount++; + } + } ); + + return threeDCount; + }; + }( mediaWiki, jQuery, mediaWiki.uploadWizard, OO ) ); diff --git a/resources/uploadWizard.css b/resources/uploadWizard.css index 6c30f3c..fa7bd62 100644 --- a/resources/uploadWizard.css +++ b/resources/uploadWizard.css @@ -186,6 +186,26 @@ width: 300px; } +.mwe-upwiz-patent-rights .oo-ui-panelLayout .oo-ui-panelLayout:not(:last-child) { + box-shadow: 0 1em 1px -1em #bbb; +} + +.mwe-upwiz-patent-rights-filelist { + display: block; + text-align: center; + box-shadow: 0 0 1px 0 #bbb; +} + +.mwe-upwiz-patent-weapon-policy { + margin-top: 1em; + padding: 0 1em 0 calc( 32px + 2em ); + border: 1px solid #c8ccd1; + white-space: pre-wrap; + /* @embed */ + background: #f2f4f7 url( images/no-weapons.svg ) no-repeat 1em 1em; + background-size: 32px 32px; +} + /* Flickr Interface CSS*/ #mwe-upwiz-upload-ctr-divide { diff --git a/tests/qunit/controller/uw.controller.Deed.test.js b/tests/qunit/controller/uw.controller.Deed.test.js index 526f57a..5235665 100644 --- a/tests/qunit/controller/uw.controller.Deed.test.js +++ b/tests/qunit/controller/uw.controller.Deed.test.js @@ -32,10 +32,10 @@ ), ststub = this.sandbox.stub().returns( $.Deferred().promise() ), uploads = [ - { file: { fromURL: true }, getThumbnail: ststub, on: $.noop }, - { file: {}, getThumbnail: ststub, on: $.noop }, - { file: { fromURL: true }, getThumbnail: ststub, on: $.noop }, - { file: {}, getThumbnail: ststub, on: $.noop } + { file: { fromURL: true }, getThumbnail: ststub, on: $.noop, title: mw.Title.newFromText( 'Test1.jpg', 6 ) }, + { file: {}, getThumbnail: ststub, on: $.noop, title: mw.Title.newFromText( 'Test2.jpg', 6 ) }, + { file: { fromURL: true }, getThumbnail: ststub, on: $.noop, title: mw.Title.newFromText( 'Test3.jpg', 6 ) }, + { file: {}, getThumbnail: ststub, on: $.noop, title: mw.Title.newFromText( 'Test4.jpg', 6 ) } ]; this.sandbox.stub( step.ui, 'load' ); -- To view, visit https://gerrit.wikimedia.org/r/386413 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I5194beef2378c636f06f0a61cc3daf9a7cec99bd Gerrit-PatchSet: 17 Gerrit-Project: mediawiki/extensions/UploadWizard Gerrit-Branch: master Gerrit-Owner: Matthias Mullie <mmul...@wikimedia.org> Gerrit-Reviewer: MarkTraceur <mholmqu...@wikimedia.org> Gerrit-Reviewer: Matthias Mullie <mmul...@wikimedia.org> Gerrit-Reviewer: Siebrand <siebr...@kitano.nl> Gerrit-Reviewer: jenkins-bot <> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits