From 97c134e3978f536f3d61447de5c434dd57c49bc9 Mon Sep 17 00:00:00 2001 From: Florian Date: Sun, 10 Jan 2016 18:58:21 +0100 Subject: [PATCH] Improve documentation of code and add test features (npm, composer) Also: Add license (MIT). Change-Id: Ia184b396b648ecb4ef30b40d13618e2ecf72294a --- .csslintrc | 13 +++++ .gitignore | 3 + .jscsrc | 21 +++++++ .jshintignore | 1 + .jshintrc | 23 ++++++++ CookieWarning.php | 4 +- Gruntfile.js | 56 +++++++++++++++++++ LICENSE | 21 +++++++ composer.json | 12 ++++ extension.json | 1 + i18n/de.json | 8 ++- i18n/en.json | 8 ++- i18n/qqq.json | 10 ++++ includes/CookieWarning.hooks.php | 40 +++++++++++-- package.json | 18 ++++++ phpcs.xml | 8 +++ .../ext.CookieWarning/ext.CookieWarning.js | 13 +++++ 17 files changed, 252 insertions(+), 8 deletions(-) create mode 100644 .csslintrc create mode 100644 .gitignore create mode 100644 .jscsrc create mode 100644 .jshintignore create mode 100644 .jshintrc create mode 100644 Gruntfile.js create mode 100644 LICENSE create mode 100644 composer.json create mode 100644 i18n/qqq.json create mode 100644 package.json create mode 100644 phpcs.xml diff --git a/.csslintrc b/.csslintrc new file mode 100644 index 0000000..68d60d2 --- /dev/null +++ b/.csslintrc @@ -0,0 +1,13 @@ +{ + "adjoining-classes": false, + "box-model": false, + "box-sizing": false, + "fallback-colors": false, + "important": false, + "outline-none": false, + "qualified-headings": false, + "unique-headings": false, + "universal-selector": false, + "unqualified-attributes": false, + "gradients": false +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f5fa505 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +vendor +composer.lock +node_modules \ No newline at end of file diff --git a/.jscsrc b/.jscsrc new file mode 100644 index 0000000..1959eea --- /dev/null +++ b/.jscsrc @@ -0,0 +1,21 @@ +{ + "preset": "wikimedia", + + "jsDoc": { + "checkAnnotations": { + "preset": "jsduck5", + "extra": { + "this": true, + "source": true, + "see": true + } + }, + "checkTypes": "strictNativeCase", + "checkParamNames": true, + "checkRedundantAccess": true, + "checkRedundantReturns": true, + "requireNewlineAfterDescription": true, + "requireParamTypes": true, + "requireReturnTypes": true + } +} diff --git a/.jshintignore b/.jshintignore new file mode 100644 index 0000000..b512c09 --- /dev/null +++ b/.jshintignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000..aea559a --- /dev/null +++ b/.jshintrc @@ -0,0 +1,23 @@ +{ + // Enforcing + "bitwise": true, + "eqeqeq": true, + "freeze": true, + "latedef": true, + "noarg": true, + "nonew": true, + "undef": true, + "unused": true, + "strict": false, + + // Relaxing + "es5": false, + + // Environment + "browser": true, + "jquery": true, + + "globals": { + "mw": false + } +} diff --git a/CookieWarning.php b/CookieWarning.php index 5f8d290..9382025 100644 --- a/CookieWarning.php +++ b/CookieWarning.php @@ -4,8 +4,8 @@ if ( function_exists( 'wfLoadExtension' ) ) { // Keep i18n globals so mergeMessageFileList.php doesn't break $wgMessagesDirs['CookieWarning'] = __DIR__ . '/i18n'; /* wfWarn( - 'Deprecated PHP entry point used for CookieWarning extension. Please use wfLoadExtension instead, ' . - 'see https://www.mediawiki.org/wiki/Extension_registration for more details.' + 'Deprecated PHP entry point used for CookieWarning extension. Please use wfLoadExtension' . + 'instead, see https://www.mediawiki.org/wiki/Extension_registration for more details.' ); */ return true; } else { diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100644 index 0000000..b1cedfd --- /dev/null +++ b/Gruntfile.js @@ -0,0 +1,56 @@ +/*! + * Grunt file + * + * @package CookieWarning + */ + +/*jshint node:true */ +module.exports = function ( grunt ) { + var conf = grunt.file.readJSON( 'extension.json' ); + + grunt.loadNpmTasks( 'grunt-banana-checker' ); + grunt.loadNpmTasks( 'grunt-jsonlint' ); + grunt.loadNpmTasks( 'grunt-contrib-jshint' ); + grunt.loadNpmTasks( 'grunt-contrib-csslint' ); + grunt.loadNpmTasks( 'grunt-jscs' ); + + grunt.initConfig( { + banana: conf.MessagesDirs, + jsonlint: { + all: [ + '**/*.json', + '!node_modules/**' + ] + }, + jshint: { + options: { + jshintrc: true + }, + all: [ + '*.js', + 'modules/**/*.js' + ] + }, + jscs: { + fix: { + options: { + fix: true + }, + src: '<%= jshint.all %>' + }, + main: { + src: '<%= jshint.all %>' + } + }, + csslint: { + options: { + csslintrc: '.csslintrc' + }, + all: 'resources/**/*.css' + } + } ); + + grunt.registerTask( 'lint', [ 'jshint', 'jscs:main', 'csslint', 'jsonlint', 'banana' ] ); + grunt.registerTask( 'test', [ 'lint', 'banana' ] ); + grunt.registerTask( 'default', 'test' ); +}; diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5556475 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Florian Schmidt + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..083767b --- /dev/null +++ b/composer.json @@ -0,0 +1,12 @@ +{ + "require-dev": { + "jakub-onderka/php-parallel-lint": "0.9.2", + "mediawiki/mediawiki-codesniffer": "0.5.1" + }, + "scripts": { + "test": [ + "parallel-lint . --exclude vendor", + "phpcs -p -s" + ] + } +} diff --git a/extension.json b/extension.json index b867bcd..722db7f 100644 --- a/extension.json +++ b/extension.json @@ -7,6 +7,7 @@ "url": "https://www.droidwiki.de", "descriptionmsg": "cookiewarning-desc", "type": "other", + "license-name": "MIT", "MessagesDirs": { "CookieWarning": [ "i18n" diff --git a/i18n/de.json b/i18n/de.json index 9895adc..e7d98e1 100644 --- a/i18n/de.json +++ b/i18n/de.json @@ -1,4 +1,10 @@ { + "@metadata": { + "authors": [ + "Florian Schmidt" + ] + }, "cookiewarning-info": "Cookies helfen uns bei der Bereitstellung von {{SITENAME}}. Durch die Nutzung von {{SITENAME}} erklären Sie sich damit einverstanden, dass wir Cookies setzen.", - "cookiewarning-desc": "Stellt einern Warnhinweis über die Vernwendung von Cookies beim Seitenbesuch zur Verfügung." + "cookiewarning-desc": "Stellt einern Warnhinweis über die Vernwendung von Cookies beim Seitenbesuch zur Verfügung.", + "cookiewarning-moreinfo-label": "Mehr Informationen" } diff --git a/i18n/en.json b/i18n/en.json index cc9cdac..ddbe41c 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -1,4 +1,10 @@ { + "@metadata": { + "authors": [ + "Florian Schmidt" + ] + }, "cookiewarning-info": "Cookies help us deliver our services. By using our services, you agree to our use of cookies.", - "cookiewarning-desc": "Provides a notice at the top of the page about cookies." + "cookiewarning-desc": "Provides a notice at the top of the page about cookies.", + "cookiewarning-moreinfo-label": "More information" } diff --git a/i18n/qqq.json b/i18n/qqq.json new file mode 100644 index 0000000..691a8c3 --- /dev/null +++ b/i18n/qqq.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "Florian Schmidt" + ] + }, + "cookiewarning-info": "Information message for visitors of the wiki, informing them that this wiki uses cookies.", + "cookiewarning-desc": "{{desc|name=CookieWarning|url=https://www.mediawiki.org/wiki/Extension:CookieWarning}}", + "cookiewarning-moreinfo-label": "Label for the \"More information\" link in the cookiewarning information bar." +} diff --git a/includes/CookieWarning.hooks.php b/includes/CookieWarning.hooks.php index 0e8b8cc..6826bd3 100644 --- a/includes/CookieWarning.hooks.php +++ b/includes/CookieWarning.hooks.php @@ -1,17 +1,32 @@ makeConfig( 'cookiewarning' ); $moreLink = ''; + // if a "more information" URL was configured, add a link to it in the cookiewarning + // information bar if ( $conf->get( 'CookieWarningMoreUrl' ) ) { $moreLink = Html::element( 'a', array( 'href' => $conf->get( 'CookieWarningMoreUrl' ) ), - 'Mehr Informationen' + $sk->msg( 'cookiewarning-moreinfo-label' )->text() ); } - if ( self::showWarning( $sk ) ) { + // if the cookiewarning should be visible to the user, append the element to + // the head data. + if ( self::showWarning( $sk->getContext() ) ) { $tpl->data['headelement'] .= Html::openElement( 'div', array( 'class' => 'mw-cookiewarning-container' ) @@ -36,19 +51,36 @@ class CookieWarningHooks { } } + /** + * BeforePageDisplay hook handler. + * + * Adds the required style and JS module, if cookiewarning is enabled. + * + * @param OutputPage $out + */ public static function onBeforePageDisplay( OutputPage $out ) { - if ( !$out->getRequest()->getCookie( 'cookiewarning_dismissed' ) ) { + if ( self::showWarning( $out->getContext() ) ) { $out->addModuleStyles( array( 'ext.CookieWarning.styles' ) ); $out->addModules( array( 'ext.CookieWarning' ) ); } } + /** + * Checks, if the CookieWarning information bar should be visible to this user on + * this page. + * + * @param IContextSource $context + * @return boolean Returns true, if the cookie warning should be visible, false otherwise. + */ private static function showWarning( IContextSource $context ) { $user = $context->getUser(); $conf = ConfigFactory::getDefaultInstance()->makeConfig( 'cookiewarning' ); if ( + // if enabled in LocalSettings.php $conf->get( 'CookieWarningEnabled' ) && + // if not already dismissed by this user (and saved in the user prefs) !$user->getBoolOption( 'cookiewarning_dismissed', false ) && + // if not already dismissed by this user (and saved in the browser cookies) !$context->getRequest()->getCookie( 'cookiewarning_dismissed' ) ) { return true; diff --git a/package.json b/package.json new file mode 100644 index 0000000..b887a81 --- /dev/null +++ b/package.json @@ -0,0 +1,18 @@ +{ + "name": "CookieWarning-dependencies", + "description": "Node.js dependencies used in CookieWarning", + "version": "0.0.1", + "private": true, + "scripts": { + "test": "grunt test" + }, + "devDependencies": { + "grunt": "0.4.5", + "grunt-cli": "0.1.13", + "grunt-banana-checker": "0.4.0", + "grunt-jsonlint": "1.0.7", + "grunt-contrib-csslint": "0.5.0", + "grunt-contrib-jshint": "0.11.3", + "grunt-jscs": "2.5.0" + } +} diff --git a/phpcs.xml b/phpcs.xml new file mode 100644 index 0000000..d81a292 --- /dev/null +++ b/phpcs.xml @@ -0,0 +1,8 @@ + + + + . + + + vendor + diff --git a/resources/ext.CookieWarning/ext.CookieWarning.js b/resources/ext.CookieWarning/ext.CookieWarning.js index dc9958c..c30b14a 100644 --- a/resources/ext.CookieWarning/ext.CookieWarning.js +++ b/resources/ext.CookieWarning/ext.CookieWarning.js @@ -1,21 +1,34 @@ ( function ( mw, $ ) { + /** + * Sets the cookie, that the cookiewarning is dismissed. Called, + * when the api query to save this information in the user preferences, + * failed for any reason. + */ function setCookie() { mw.cookie.set( 'cookiewarning_dismissed', true ); } + // Click handler for the "Ok" element in the cookiewarning information bar $( '.mw-cookiewarning-dismiss' ).on( 'click', function ( ev ) { + // an anonymous user doesn't have preferences, so don't try to save this in + // the user preferences. if ( !mw.user.isAnon() ) { + // try to save, that the cookiewarning was disabled, in the user preferences new mw.Api().postWithToken( 'options', { action: 'options', change: 'cookiewarning_dismissed=1' } ).fail( function ( code, result ) { + // if it fails, fall back to the cookie mw.log.warn( 'Failed to save dismissed CookieWarning: ' + code + '\n' + result.error + '. Using cookie now.' ); setCookie(); } ); } else { + // use cookies for anonymous users setCookie(); } + // always remove the cookiewarning element $( '.mw-cookiewarning-container' ).detach(); + ev.preventDefault(); } ); } )( mediaWiki, jQuery );