AndyRussG has uploaded a new change for review. (
https://gerrit.wikimedia.org/r/344988 )
Change subject: [WIP] Banner sequence campaign mixin
......................................................................
[WIP] Banner sequence campaign mixin
Change-Id: I6cfb31b07c56097fd3d0007a3f051d7511ed5017
---
M README
M extension.json
M i18n/en.json
M i18n/qqq.json
M resources/infrastructure/campaignManager.js
A resources/subscribing/ext.centralNotice.bannerSequence.js
6 files changed, 230 insertions(+), 5 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/CentralNotice
refs/changes/88/344988/1
diff --git a/README b/README
index e02bee5..ca93123 100644
--- a/README
+++ b/README
@@ -201,6 +201,7 @@
- legacySupport
- impressionDiet
- largeBannerLimit
+ - bannerSequence
* $wgNoticeTabifyPages: Declare all pages that should be tabified as CN pages
diff --git a/extension.json b/extension.json
index 79cee50..37d1ace 100644
--- a/extension.json
+++ b/extension.json
@@ -222,7 +222,11 @@
"centralnotice-large-banner-limit-randomize",
"centralnotice-large-banner-limit-randomize-help",
"centralnotice-large-banner-limit-identifier",
-
"centralnotice-large-banner-limit-identifier-help"
+
"centralnotice-large-banner-limit-identifier-help",
+ "centralnotice-banner-sequence",
+ "centralnotice-banner-sequence-help",
+ "centralnotice-banner-sequence-bucket-seq",
+ "centralnotice-banner-sequence-bucket-add-step"
]
},
"ext.centralNotice.startUp": {
@@ -325,6 +329,17 @@
"scripts":
"subscribing/ext.centralNotice.legacySupport.js",
"dependencies": [
"ext.centralNotice.display"
+ ],
+ "targets": [
+ "desktop",
+ "mobile"
+ ]
+ },
+ "ext.centralNotice.bannerSequence": {
+ "scripts":
"subscribing/ext.centralNotice.bannerSequence.js",
+ "dependencies": [
+ "ext.centralNotice.display",
+ "ext.centralNotice.kvStore"
],
"targets": [
"desktop",
@@ -563,6 +578,17 @@
"defaultValue":
"centralnotice-frbanner-seen-fullscreen"
}
}
+ },
+ "bannerSequence": {
+ "module": "ext.centralNotice.bannerSequence",
+ "nameMsg": "centralnotice-banner-sequence",
+ "helpMsg": "centralnotice-banner-sequence-help",
+ "customAdminUIControls": true,
+ "parameters": {
+ "sequence": {
+ "type": "json"
+ }
+ }
}
},
"NoticeTabifyPages": {
diff --git a/i18n/en.json b/i18n/en.json
index 1a842fd..879784c 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -291,5 +291,9 @@
"centralnotice-large-banner-limit-randomize": "Randomize bucket
transition",
"centralnotice-large-banner-limit-randomize-help": "Normal bucket
transition is A to C, B to D. When checked, readers will randomly move to
buckets C or D.",
"centralnotice-large-banner-limit-identifier": "Identifier for
client-side storage",
- "centralnotice-large-banner-limit-identifier-help": "Large banner
display is suppressed across campaigns with the same identifier. Default value
'centralnotice-frbanner-seen-fullscreen' may be used to migrate legacy cookies."
+ "centralnotice-large-banner-limit-identifier-help": "Large banner
display is suppressed across campaigns with the same identifier. Default value
'centralnotice-frbanner-seen-fullscreen' may be used to migrate legacy
cookies.",
+ "centralnotice-banner-sequence": "Banner sequence",
+ "centralnotice-banner-sequence-help": "Set multiple banners to display
in specific order.",
+ "centralnotice-banner-sequence-bucket-seq": "Sequence for bucket $1",
+ "centralnotice-banner-sequence-bucket-add-step": "Add a step"
}
diff --git a/i18n/qqq.json b/i18n/qqq.json
index a6ac33a..7dd351f 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -315,5 +315,9 @@
"centralnotice-large-banner-limit-randomize": "Label for the form
control to randomize bucket transition",
"centralnotice-large-banner-limit-randomize-help": "Help text for the
form control to randomize bucket transition",
"centralnotice-large-banner-limit-identifier": "Label for the form
control to set a large banner identifier/cookie name",
- "centralnotice-large-banner-limit-identifier-help": "Help text for the
form control to set large banner identifier/cookie name"
+ "centralnotice-large-banner-limit-identifier-help": "Help text for the
form control to set large banner identifier/cookie name",
+ "centralnotice-banner-sequence": "Label for the banner sequence mixin",
+ "centralnotice-banner-sequence-help": "Help text for banner sequence
mixin",
+ "centralnotice-banner-sequence-bucket-seq": "Label for sequence for a
given bucket",
+ "centralnotice-banner-sequence-bucket-add-step": "Label for button to
add step to a banner sequence"
}
diff --git a/resources/infrastructure/campaignManager.js
b/resources/infrastructure/campaignManager.js
index df62287..2b9ec92 100644
--- a/resources/infrastructure/campaignManager.js
+++ b/resources/infrastructure/campaignManager.js
@@ -30,7 +30,10 @@
$mixinCheckboxes = $( 'input.noticeMixinCheck' ),
$submitBtn = $( '#noticeDetailSubmit' ),
mixinControlGroupFactory = new OO.Factory(),
- MixinControlGroup;
+ MixinControlGroup,
+ BannerSequenceControlGroup, BucketSequenceContainer,
BucketSequence, SequenceStep,
+ bucketChangeHandlers = [],
+ bucketLabels = [ 'A', 'B', 'C', 'D' ];
// Note: the following code uses two completely distinct meanings of
// "mixin". One is "campaign mixin", bits of JS code that can be run on
the
@@ -159,6 +162,152 @@
return $input;
};
+ /* BannerSequenceControlGroup */
+
+ BannerSequenceControlGroup = function ( config ) {
+
+ var numBuckets = parseInt( getCampaignBuckets(), 10 );
+
+ // Configuration initialization
+ config = config || {};
+ config.data = config.data || {};
+ config.data.sequence = config.data.sequence || [];
+
+ // Call parent constructor
+ BannerSequenceControlGroup.parent.call( this, config );
+
+ // Call the bucket change handler to ensure the right number of
buckets
+ // in data and create widgets.
+ this.onBucketChange( numBuckets );
+
+ // Subscribe the bucket change handler
+ bucketChangeHandlers.push( { callback: this.onBucketChange,
context: this } );
+ };
+
+ OO.inheritClass( BannerSequenceControlGroup, MixinControlGroup );
+
+ BannerSequenceControlGroup.static.name = 'bannerSequence';
+
+ BannerSequenceControlGroup.prototype.onBucketChange = function (
numBuckets ) {
+
+ var b,
+ sequence = this.getData().sequence,
+ bucketSeqContainers = this.getItems();
+
+ // Sequence has too many buckets?
+ if ( sequence.length > numBuckets ) {
+
+ // Check there are too many bucketSequenceContainer
widgets, too. If
+ // there are, prune.
+ if ( bucketSeqContainers.length > numBuckets ) {
+ for ( b = numBuckets; b < sequence.length; b++
) {
+ this.removeItems( [
this.getItemFromData( b ) ] );
+ }
+ }
+
+ sequence = sequence.slice( 0, numBuckets );
+
+ // Sequence has not enough buckets?
+ } else if ( sequence.length < numBuckets ) {
+
+ for ( b = sequence.length; b < numBuckets; b++ ) {
+ sequence[ b ] = [];
+ }
+ }
+
+ // Ensure bucketSequenceContainer widgets for all the buckets
+ for ( b = 0; b < numBuckets; b++ ) {
+ if ( !this.getItemFromData( b ) ) {
+ this.addItems(
+ [ new BucketSequenceContainer( {
+ data: b,
+ bucketSequence: sequence[ b ]
+ } ) ],
+ b
+ );
+ }
+ }
+
+ this.setParam( 'sequence', sequence, true );
+ };
+
+ mixinControlGroupFactory.register( BannerSequenceControlGroup );
+
+ /* BucketSequenceContainer */
+
+ BucketSequenceContainer = function ( config ) {
+
+ var bucketSequence, addStepBtn;
+
+ config.bucketSequence = this.bucketSequence;
+
+ bucketSequence = new BucketSequence( {
+ bucketSequence: this.bucketSequence
+ } );
+
+ addStepBtn = new OO.ui.ButtonWidget( {
+ label: mw.message(
'centralnotice-banner-sequence-bucket-add-step' ).text()
+ } );
+
+ config.text = mw.message(
+ 'centralnotice-banner-sequence-bucket-seq',
+ bucketLabels[ config.data ]
+ ).text();
+
+ // Call parent constructor
+ BucketSequenceContainer.parent.call( this, config );
+
+ // Call mixin constructor
+ OO.ui.mixin.GroupElement.call(
+ this, $.extend( {}, config, { $group: this.$element } )
);
+
+ this.addItems( [ bucketSequence, addStepBtn ] );
+
+ addStepBtn.on( 'click', function () {
+ bucketSequence.addItems( [ new SequenceStep() ] );
+ } );
+ };
+
+ OO.inheritClass( BucketSequenceContainer, OO.ui.Widget );
+ OO.mixinClass( BucketSequenceContainer, OO.ui.mixin.GroupElement );
+
+ /* BucketSequence */
+
+ BucketSequence = function ( config ) {
+ // Configuration initialization
+ config = config || {};
+
+ // Call parent constructor
+ BucketSequence.parent.call( this, config );
+
+ // Call mixin constructor
+ OO.ui.mixin.DraggableGroupElement.call(
+ this, $.extend( {}, config, { $group: this.$element } )
);
+ };
+
+ OO.inheritClass( BucketSequence, OO.ui.Widget );
+ OO.mixinClass( BucketSequence, OO.ui.mixin.DraggableGroupElement );
+
+ /* SequenceStep */
+
+ SequenceStep = function ( config ) {
+ // Configuration initialization
+ config = config || {};
+ config.text = 'This is a step ' + Math.random();
+
+ // Call parent constructor
+ SequenceStep.parent.call( this, config );
+
+ // Call mixin constructors
+ OO.ui.mixin.GroupElement.call( this, config );
+ OO.ui.mixin.DraggableElement.call(
+ this, $.extend( {}, config, { $handle: this.$element }
) );
+ };
+
+ OO.inheritClass( SequenceStep, OO.ui.Widget );
+ OO.mixinClass( SequenceStep, OO.ui.mixin.GroupElement );
+ OO.mixinClass( SequenceStep, OO.ui.mixin.DraggableElement );
+
$( '#centralnotice-throttle-amount' ).slider( {
range: 'min',
min: 0,
@@ -193,8 +342,9 @@
$( '#balanced' ).click( updateWeightColumn );
+ // FIXME Additional bucket-change handling is in centralnotice.js
function updateBuckets() {
- var numCampaignBuckets = $( 'select#buckets :checked' ).val(),
+ var numCampaignBuckets = getCampaignBuckets(),
i,
isBucketDisabled;
@@ -205,6 +355,20 @@
$( 'select.bucketSelector option[value=' + i +
']' ).prop( 'disabled', isBucketDisabled );
}
}
+
+ // Provisional hack: bucket change handlers register themselves
via
+ // bucketChangeHandlers.
+ for ( i = 0; i < bucketChangeHandlers.length; i++ ) {
+
+ bucketChangeHandlers[ i ].callback.call(
+ bucketChangeHandlers[ i ].context,
+ parseInt( numCampaignBuckets, 10 )
+ );
+ }
+ }
+
+ function getCampaignBuckets() {
+ return $( 'select#buckets :selected' ).val();
}
$( 'select#buckets' ).change( updateBuckets );
diff --git a/resources/subscribing/ext.centralNotice.bannerSequence.js
b/resources/subscribing/ext.centralNotice.bannerSequence.js
new file mode 100644
index 0000000..cd237ec
--- /dev/null
+++ b/resources/subscribing/ext.centralNotice.bannerSequence.js
@@ -0,0 +1,26 @@
+/**
+ * Large banner limit mixin. Shows readers a large banner once, then switches
+ * to small banners for a configurable number of days.
+ *
+ * Requires a campaign with four buckets. Buckets A and B are assumed to
contain
+ * large banners, and buckets C and D small banners.
+ *
+ * Replaces the following scripts:
+ *
https://meta.wikimedia.org/wiki/MediaWiki:FR2014/Resources/ShowHideCheckFullscreen.js
+ *
https://meta.wikimedia.org/wiki/MediaWiki:FR2014/Resources/ChangeBucket-AtoC-BtoD.js
+ */
+// jshint unused:false
+( function ( mw ) {
+ 'use strict';
+
+ var cn = mw.centralNotice,
+ mixin = new cn.Mixin( 'bannerSequence' ),
+ STORAGE_KEY = 'banner_sequence';
+
+ mixin.setPreBannerHandler( function ( mixinParams ) {
+ } );
+
+ // Register the mixin
+ cn.registerCampaignMixin( mixin );
+
+} )( mediaWiki );
--
To view, visit https://gerrit.wikimedia.org/r/344988
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I6cfb31b07c56097fd3d0007a3f051d7511ed5017
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/CentralNotice
Gerrit-Branch: master
Gerrit-Owner: AndyRussG <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits