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

Reply via email to