jenkins-bot has submitted this change and it was merged.
Change subject: Load a quick survey on desktop and mobile
......................................................................
Load a quick survey on desktop and mobile
Writes it in a MobileFrontend like way, making use of templates
to generate $content and using similar named variables that
MobileFrontend developers will be used to.
Note:
* This currently pulls in both Hogan and Mustache on mobile.
* Results are not stored.
* A survey can only be shown by including quicksurvey in your query string
These will be fixed in follow ups.
Dependency: Idb37352acecd745beb53aa8d77ea050851448e0d
Change-Id: Id5c32bb7a662dda8d153490f7c47e972cabc1efd
---
M extension.json
M i18n/en.json
M i18n/qqq.json
M includes/QuickSurveys.hooks.php
A resources/ext.quicksurveys.init/init.js
A resources/ext.quicksurveys.init/styles.less
A resources/ext.quicksurveys.views/QuickSurvey.js
A resources/ext.quicksurveys.views/finalPanel.mustache
A resources/ext.quicksurveys.views/heart.svg
A resources/ext.quicksurveys.views/initialPanel.mustache
A resources/ext.quicksurveys.views/styles.less
11 files changed, 343 insertions(+), 2 deletions(-)
Approvals:
Phuedx: Looks good to me, approved
jenkins-bot: Verified
diff --git a/extension.json b/extension.json
index 7e1a91c..1cd4b50 100644
--- a/extension.json
+++ b/extension.json
@@ -19,6 +19,56 @@
"ConfigRegistry": {
"quicksurveys": "GlobalVarConfig::newInstance"
},
+ "ResourceFileModulePaths": {
+ "localBasePath": "",
+ "remoteExtPath": "QuickSurveys"
+ },
+ "ResourceModules": {
+ "ext.quicksurveys.views": {
+ "dependencies": [
+ "oojs-ui",
+ "mediawiki.user"
+ ],
+ "targets": [
+ "mobile",
+ "desktop"
+ ],
+ "templates": {
+ "finalPanel.mustache":
"resources/ext.quicksurveys.views/finalPanel.mustache",
+ "initialPanel.mustache":
"resources/ext.quicksurveys.views/initialPanel.mustache"
+ },
+ "messages": [
+
"ext-quicksurveys-survey-privacy-policy-default-text",
+ "ext-quicksurveys-survey-confirm-msg",
+ "ext-quicksurveys-survey-positive",
+ "ext-quicksurveys-survey-negative",
+ "ext-quicksurveys-survey-neutral"
+ ],
+ "styles": [
+ "resources/ext.quicksurveys.views/styles.less"
+ ],
+ "scripts": [
+
"resources/ext.quicksurveys.views/QuickSurvey.js"
+ ]
+ },
+ "ext.quicksurveys.init": {
+ "position": "top",
+ "dependencies": [
+ "mediawiki.user",
+ "mediawiki.storage"
+ ],
+ "targets": [
+ "mobile",
+ "desktop"
+ ],
+ "styles": [
+ "resources/ext.quicksurveys.init/styles.less"
+ ],
+ "scripts": [
+ "resources/ext.quicksurveys.init/init.js"
+ ]
+ }
+ },
"AutoloadClasses": {
"QuickSurveys\\Hooks": "includes/QuickSurveys.hooks.php"
},
@@ -26,6 +76,9 @@
"Hooks": {
"ResourceLoaderGetConfigVars": [
"QuickSurveys\\Hooks::onResourceLoaderGetConfigVars"
+ ],
+ "BeforePageDisplay": [
+ "QuickSurveys\\Hooks::onBeforePageDisplay"
]
},
"config": {
diff --git a/i18n/en.json b/i18n/en.json
index f53bfb4..3160260 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -13,5 +13,10 @@
"ext-quicksurveys-example-internal-survey-answer-neutral": "Not sure",
"ext-quicksurveys-example-internal-survey-answer-negative": "No",
"ext-quicksurveys-example-external-survey-description": "This is the
description of the example external survey.",
- "ext-quicksurveys-example-external-survey-privacy-policy-text":
"Privacy Policy"
+ "ext-quicksurveys-example-external-survey-privacy-policy-text":
"Privacy Policy",
+ "ext-quicksurveys-survey-privacy-policy-default-text": "All submissions
are anonymous. See the [[Project:Privacy_policy|privacy policy]].",
+ "ext-quicksurveys-survey-confirm-msg": "Thanks for the feedback! We are
using it to make {{SITENAME}} even better!",
+ "ext-quicksurveys-survey-positive": "Yes",
+ "ext-quicksurveys-survey-negative": "No",
+ "ext-quicksurveys-survey-neutral": "Not sure"
}
diff --git a/i18n/qqq.json b/i18n/qqq.json
index 03c7a2a..f0509d3 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -14,5 +14,10 @@
"ext-quicksurveys-example-internal-survey-answer-neutral": "The neutral
answer for the example internal survey\n{{Identical|Not sure}}",
"ext-quicksurveys-example-internal-survey-answer-negative": "The
negative answer for the example internal survey\n{{Identical|No}}",
"ext-quicksurveys-example-external-survey-description": "description of
the example survey",
- "ext-quicksurveys-example-external-survey-privacy-policy-text": "text
of the privacy policy link\n{{Identical|Privacy policy}}"
+ "ext-quicksurveys-example-external-survey-privacy-policy-text": "text
of the privacy policy link\n{{Identical|Privacy policy}}",
+ "ext-quicksurveys-survey-privacy-policy-default-text": "Default
disclaimer about submitting surveys.",
+ "ext-quicksurveys-survey-confirm-msg": "Confirmation message thanking
user for their input.",
+ "ext-quicksurveys-survey-positive": "Default button label for user
replying in affirmative.",
+ "ext-quicksurveys-survey-negative": "Default button label for user
replying neutrally.",
+ "ext-quicksurveys-survey-neutral": "Default button label for user
replying negatively."
}
diff --git a/includes/QuickSurveys.hooks.php b/includes/QuickSurveys.hooks.php
index 65831cf..4e172b3 100644
--- a/includes/QuickSurveys.hooks.php
+++ b/includes/QuickSurveys.hooks.php
@@ -34,4 +34,17 @@
$vars['wgEnabledQuickSurveys'] = $enabledQuickSurveys;
return true;
}
+
+ /**
+ * BeforePageDisplay hook handler
+ * @see https://www.mediawiki.org/wiki/Manual:Hooks/BeforePageDisplay
+ *
+ * @param OutputPage $out
+ * @param Skin $sk
+ * @return bool
+ */
+ public static function onBeforePageDisplay( &$out, &$sk ) {
+ $out->addModules( 'ext.quicksurveys.init' );
+ return true;
+ }
}
diff --git a/resources/ext.quicksurveys.init/init.js
b/resources/ext.quicksurveys.init/init.js
new file mode 100644
index 0000000..aa0e168
--- /dev/null
+++ b/resources/ext.quicksurveys.init/init.js
@@ -0,0 +1,54 @@
+( function ( $ ) {
+ var survey, token, storageId, $bodyContent, $place,
+ $panel = $( '<div class="ext-qs-loader-bar
mw-ajax-loader"></div>' ),
+ availableSurveys = mw.config.get( 'wgEnabledQuickSurveys' ),
+ // https://phabricator.wikimedia.org/T109010
+ inSample = false,
+ isMainPage = mw.config.get( 'wgIsMainPage' ),
+ isArticle = mw.config.get( 'wgIsArticle' );
+
+ mw.extQuickSurveys = {
+ views: {}
+ };
+
+ if ( availableSurveys.length ) {
+ survey = availableSurveys[ Math.floor( Math.random() *
availableSurveys.length ) ];
+ storageId = 'ext-quicksurvey-' + survey.name;
+ token = mw.storage.get( storageId );
+
+ // local storage is supported in this case as value is not
false and when ~ it means it was dismissed
+ if ( token !== false && token !== '~' && !isMainPage &&
isArticle ) {
+
+ if ( !token ) {
+ token = mw.user.generateRandomSessionId();
+ // given token !== false we can safely run this
without exception:
+ mw.storage.set( storageId, token );
+ }
+
+ if ( inSample || mw.util.getParamValue( 'quicksurvey' )
) {
+ $bodyContent = $( '#bodyContent' );
+ $place = $bodyContent.find( 'h1, h2, h3, h4,
h5, h6' ).eq( 0 );
+
+ if ( $place.length ) {
+ $panel.insertBefore( $place );
+ } else {
+ $panel.appendTo( $bodyContent );
+ }
+ mw.loader.using( 'ext.quicksurveys.views'
).done( function () {
+ var panel;
+ panel = new
mw.extQuickSurveys.views.QuickSurvey( {
+ type: survey.type,
+ templateData: {
+ question:
survey.question,
+ description:
survey.description
+ }
+ } );
+ $panel.replaceWith( panel.$element );
+ panel.on( 'dismiss', function () {
+ mw.storage.set( storageId, '~'
);
+ } );
+ } );
+ }
+ }
+ }
+}( jQuery ) );
diff --git a/resources/ext.quicksurveys.init/styles.less
b/resources/ext.quicksurveys.init/styles.less
new file mode 100644
index 0000000..4455cea
--- /dev/null
+++ b/resources/ext.quicksurveys.init/styles.less
@@ -0,0 +1,12 @@
+@import "mediawiki.ui/variables";
+
+/* FIXME: Should be an ajax loader to give impression something is happening */
+.ext-qs-loader-bar {
+ display: block;
+ height: 100px;
+ background-color: @colorGrayLightest;
+ &.mw-ajax-loader {
+ // FIXME: Why is this not the default? Override it.
+ top: 0;
+ }
+}
diff --git a/resources/ext.quicksurveys.views/QuickSurvey.js
b/resources/ext.quicksurveys.views/QuickSurvey.js
new file mode 100644
index 0000000..dcc6be5
--- /dev/null
+++ b/resources/ext.quicksurveys.views/QuickSurvey.js
@@ -0,0 +1,156 @@
+( function ( $ ) {
+ /**
+ * Extends a class with new methods and member properties.
+ *
+ * @param {OO.Class} ParentClass to extend.
+ * @param {Object} prototype Prototype that should be incorporated into
the new Class.
+ * @ignore
+ * FIXME: Talk about upstreaming this to oojs ui as a utility function.
+ * @return {Class}
+ */
+ function extend( ChildClass, ParentClass, prototype ) {
+ var key;
+
+ OO.inheritClass( ChildClass, ParentClass );
+ for ( key in prototype ) {
+ ChildClass.prototype[key] = prototype[key];
+ }
+ return ChildClass;
+ }
+
+ /**
+ * @class QuickSurvey
+ * @inherit OO.ui.StackLayout
+ */
+ function QuickSurvey( config ) {
+ this.initialize( config );
+ }
+ extend( QuickSurvey, OO.ui.StackLayout, {
+ /**
+ * Specifies partials (sub-templates) for use by the widget
+ * @property {Object}
+ */
+ templatePartials: {
+ initialPanel: mw.template.get(
'ext.quicksurveys.views', 'initialPanel.mustache' ),
+ finalPanel: mw.template.get( 'ext.quicksurveys.views',
'finalPanel.mustache' )
+ },
+ /**
+ * A set of default options that are merged with config passed
into the initialize function.
+ * This is likely to change so currently no options are
documented.
+ * @cfg {Object} defaults Default options hash.
+ */
+ defaults: {
+ buttons: [
+ {
+ label: mw.msg(
'ext-quicksurveys-survey-positive' ),
+ data: {
+ answer: 1
+ }
+ },
+ {
+ label: mw.msg(
'ext-quicksurveys-survey-neutral' ),
+ data: {
+ answer: 0
+ }
+ },
+ {
+ label: mw.msg(
'ext-quicksurveys-survey-negative' ),
+ data: {
+ answer: -1
+ }
+ }
+ ],
+ templateData: {
+ finalHeading: mw.msg(
'ext-quicksurveys-survey-confirm-msg' ),
+ footer: mw.message(
'ext-quicksurveys-survey-privacy-policy-default-text' ).parse()
+ },
+ PanelLayout: {
+ expanded: false,
+ framed: false,
+ padded: true,
+ classes: [ 'message content' ]
+ },
+ scrollable: false,
+ expanded: false,
+ classes: [ 'panel panel-inline visible' ]
+ },
+ /**
+ * Initialise a widget.
+ * @param {Object} config
+ */
+ initialize: function ( config ) {
+ var buttonSelect, $btnContainer,
+ btns = [];
+
+ this.config = config || {};
+ $.extend( true, this.config, this.defaults );
+
+ // setup initial panel
+ this.initialPanel = this.widget( 'PanelLayout',
'initialPanel' );
+
+ // setup final panel
+ this.finalPanel = this.widget( 'PanelLayout',
'finalPanel' );
+
+ // Set the buttons
+ $btnContainer = this.initialPanel
+ .$element.find( '.survey-button-container' );
+
+ $.each( this.config.buttons, function () {
+ var btn = new OO.ui.ButtonOptionWidget( this );
+ btns.push( btn );
+ } );
+
+ buttonSelect = new OO.ui.ButtonSelectWidget( {
+ items: btns
+ } );
+ buttonSelect.connect( this, {
+ choose: 'onChoose'
+ } );
+ buttonSelect.$element.appendTo( $btnContainer );
+
+ // setup stack
+ QuickSurvey.super.call( this, $.extend( {}, config, {
+ items: [ this.initialPanel, this.finalPanel ]
+ } ) );
+ },
+ /**
+ * Make a brand spanking new oojs ui widget from a template
partial
+ * @param {String} widgetName a valid OOJS UI widget
+ * @param {String} [templatePartialName] name of a registered
template partial
+ * @param {Object} [options] further options to be passed to
the widget
+ */
+ widget: function ( widgetName, templatePartialName, options ) {
+ var template,
+ config = $.extend( {}, this.config[widgetName],
options );
+
+ if ( templatePartialName ) {
+ template =
this.templatePartials[templatePartialName];
+ if ( template ) {
+ config.$content = template.render(
this.config.templateData );
+ }
+ }
+ return new OO.ui[widgetName]( config );
+ },
+ /**
+ * @param {Number} answer
+ */
+ log: function () {
+ // Todo: T109009
+ },
+ /**
+ * Fired when one of the options are clicked.
+ * @param {OO.ui.ButtonOptionWidget} btn
+ */
+ onChoose: function ( btn ) {
+ this.log( btn.data.answer );
+ /**
+ * @event dismiss fired when any of the buttons in the
survey are selected.
+ */
+ this.emit( 'dismiss' );
+ this.setItem( this.finalPanel );
+ }
+ } );
+
+ // This always makes me sad... https://phabricator.wikimedia.org/T108655
+ mw.extQuickSurveys.views.QuickSurvey = QuickSurvey;
+}( jQuery ) );
diff --git a/resources/ext.quicksurveys.views/finalPanel.mustache
b/resources/ext.quicksurveys.views/finalPanel.mustache
new file mode 100644
index 0000000..299615f
--- /dev/null
+++ b/resources/ext.quicksurveys.views/finalPanel.mustache
@@ -0,0 +1,4 @@
+<strong>{{finalHeading}}</strong>
+<div class="completed image"></div>
+<div class="survey-footer">{{{footer}}}</div>
+
diff --git a/resources/ext.quicksurveys.views/heart.svg
b/resources/ext.quicksurveys.views/heart.svg
new file mode 100644
index 0000000..e74000a
--- /dev/null
+++ b/resources/ext.quicksurveys.views/heart.svg
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version:
6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 158.8 143.3" enable-background="new 0 0 158.8 143.3"
xml:space="preserve">
+<g>
+ <path fill="#F27072"
d="M79.5,140.1l-7-5.4C40.4,109.8,21.1,94.9,9.9,75C4,64.6-1.9,48.7,3.4,32.2C7,21.2,15,12.3,26,7.2
+
c5.6-2.6,11.8-4,18.2-4c8.3,0,16.5,2.2,23.6,6.4c4.6,2.7,8.5,6.1,11.6,9.9c3.2-3.9,7.1-7.3,11.6-9.9c7.2-4.2,15.3-6.4,23.6-6.4
+
c6.4,0,12.6,1.3,18.2,3.9c11,5.1,19,14,22.5,25c2.9,9.1,4.2,23.9-6.5,42.8c-11.2,19.9-30.7,35-63,60L79.5,140.1z"/>
+</g>
+</svg>
diff --git a/resources/ext.quicksurveys.views/initialPanel.mustache
b/resources/ext.quicksurveys.views/initialPanel.mustache
new file mode 100644
index 0000000..6af5825
--- /dev/null
+++ b/resources/ext.quicksurveys.views/initialPanel.mustache
@@ -0,0 +1,4 @@
+<strong>{{question}}</strong>
+<p>{{description}}</p>
+<div class="survey-button-container"></div>
+<div class="survey-footer">{{{footer}}}</div>
diff --git a/resources/ext.quicksurveys.views/styles.less
b/resources/ext.quicksurveys.views/styles.less
new file mode 100644
index 0000000..37304ca
--- /dev/null
+++ b/resources/ext.quicksurveys.views/styles.less
@@ -0,0 +1,24 @@
+@import "mediawiki.ui/variables";
+@import "mediawiki.ui/mixins";
+@import "mediawiki.mixins";
+
+.panel .survey-footer {
+ font-size: .8em;
+ margin-top: .5em;
+}
+
+.panel {
+ background-color: @colorGrayLightest;
+
+ .image {
+ max-width: 500px;
+ background-repeat: no-repeat;
+ .background-size( auto, 5em );
+ background-position: center 80%;
+ &.completed {
+ height: 6em;
+ // FIXME: No png
+ .background-image-svg( 'heart.svg', 'heart.svg' );
+ }
+ }
+}
--
To view, visit https://gerrit.wikimedia.org/r/232180
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Id5c32bb7a662dda8d153490f7c47e972cabc1efd
Gerrit-PatchSet: 3
Gerrit-Project: mediawiki/extensions/QuickSurveys
Gerrit-Branch: dev
Gerrit-Owner: Jdlrobson <[email protected]>
Gerrit-Reviewer: Phuedx <[email protected]>
Gerrit-Reviewer: Siebrand <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits