From 7ca687a85c579e4ea42d6632587455b58d1758e3 Mon Sep 17 00:00:00 2001 From: Stefan Kalscheuer Date: Tue, 27 Aug 2019 19:45:40 +0200 Subject: [PATCH 01/26] include ESLint and stylelint checks in build scripts using Node --- .gitignore | 2 ++ .travis.yml | 4 ++- RoboFile.php | 24 +++++++++++-- composer.json | 29 +++++++--------- package-lock.json | 88 ----------------------------------------------- package.json | 7 ++-- 6 files changed, 44 insertions(+), 110 deletions(-) delete mode 100644 package-lock.json diff --git a/.gitignore b/.gitignore index 1ba8b01..2502359 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,9 @@ composer.lock +package-lock.json /vendor/ /node_modules/ /dist/ .idea +.phpunit.result.cache **/*.min.css **/*.min.js diff --git a/.travis.yml b/.travis.yml index ac604a3..b57a23a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,8 +9,10 @@ php: - '7.3' before_script: - composer install +- npm install script: -- composer test-all +- composer test +- composer lint-all notifications: slack: secure: "R40BhRCETuDule7lz4oGN+qyLvd7dBmuEu6hVELNhWg3DgCgYOXyrWR2dgxsWsAZ3sldpWGfTJKzSShdDanGCpygpYzuvXxjt23YYJ2ihrohYJwiGIhkR9c24LF2yvWBQDBNZaeLBQ3o6FSnbkTBsmRy5ShgKehfKCOQTKmI1yWHi3fvkMElTorrJc710O41yy/bRKBnoIYd4ZfpLMSSVGCPzR5lZPZy3EiGWXPgYdY7jGMI7ADsy+T5VWHyFqgSSJz/U2bcryKzF08FAry8pyu9lN3r61kXHfVCCJX+kcsFxW9yCfuPLnLu14O776y3U6zrX9is+8mEfkMuTXFaL5o8+iq32AmFjTIDQn6o9BKHsknfmppjwZiLgFTp1T7Z/XR6I4nyK9Z5HXDU2HS0eCUknbgXlMLhxWpKhkyx4rQELuvVlgD+u7yRYraawc3v1ycqaPj0S0G5QBFljSuxsZgNnX1hs8VmgafIvOq5qm4ZVVBhhbz+LgvW1m9COr8DDPVhWWdpcWzF8jtkqC3m4Q/1Ssc6T/MbJMgcXRq/C4DlfEs4aYGYfSl7gLtF2PwlEQCppKJwx0fEPkcbZZ1PjpzF+JMwwRmWS88R0oRyThOyCwlG50c+ktB94pJC+sP1aQZrLAd4WDKUPD9vJTas86V3XBjTUJPs8HQaBDFqFdg=" diff --git a/RoboFile.php b/RoboFile.php index ddce5a9..86ea3c7 100644 --- a/RoboFile.php +++ b/RoboFile.php @@ -26,6 +26,7 @@ class RoboFile extends Tasks { const OPT_SKIPTEST = 'skipTests'; const OPT_SKIPSTYLE = 'skipStyle'; const OPT_MINIFY = 'minify'; + const OPT_NODE = 'node'; /** * Version tag (read from composer.json). @@ -96,9 +97,25 @@ class RoboFile extends Tasks { * * @return void */ - public function testCS() { - $this->say( 'Executing PHPCS tests...' ); + public function testCS( + $opts = array( + self::OPT_TARGET => 'dist', + self::OPT_SKIPTEST => false, + self::OPT_SKIPSTYLE => false, + self::OPT_MINIFY => true, + self::OPT_NODE => false, + ) + ) { + $this->say( 'Executing PHPCS...' ); $this->_exec( __DIR__ . '/vendor/bin/phpcs --standard=phpcs.xml -s' ); + + if ( $opts[self::OPT_NODE] ) { + $this->say( 'Executing ESLint...' ); + $this->_exec( __DIR__ . '/node_modules/eslint/bin/eslint.js ' . __DIR__ . '/scripts/liveticker.js' ); + + $this->say( 'Executing StyleLint...' ); + $this->_exec( __DIR__ . '/node_modules/stylelint/bin/stylelint.js ' . __DIR__ . '/styles/liveticker.css' ); + } } /** @@ -114,6 +131,7 @@ class RoboFile extends Tasks { self::OPT_SKIPTEST => false, self::OPT_SKIPSTYLE => false, self::OPT_MINIFY => true, + self::OPT_NODE => false, ) ) { $this->clean( $opts ); @@ -125,7 +143,7 @@ class RoboFile extends Tasks { if ( isset( $opts[ self::OPT_SKIPSTYLE ] ) && true === $opts[ self::OPT_SKIPSTYLE ] ) { $this->say( 'Style checks skipped' ); } else { - $this->testCS(); + $this->testCS($opts); } $this->bundle(); } diff --git a/composer.json b/composer.json index e2f9550..5cc52a4 100644 --- a/composer.json +++ b/composer.json @@ -32,8 +32,7 @@ "wp-coding-standards/wpcs": "^2.1", "patchwork/jsqueeze": "^2.0", "natxet/cssmin": "^3.0", - "matthiasmullie/minify": "^1.3", - "npm-asset/eslint-config-wordpress": "^2.0" + "matthiasmullie/minify": "^1.3" }, "scripts": { "post-install-cmd": [ @@ -54,28 +53,26 @@ "@minify", "robo deploy:all" ], - "test-all": [ - "@test", - "@test-cs" - ], "test": [ "phpunit" ], - "test-cs": [ + "lint-all": [ + "@lint-php", + "@lint-css", + "@lint-js" + ], + "lint-php": [ "phpcs --standard=phpcs.xml -s" ], - "fix-cs": [ - "phpcbf --standard=phpcs.xml" + "lint-css": [ + "./node_modules/stylelint/bin/stylelint.js styles/liveticker.css" + ], + "lint-js": [ + "./node_modules/eslint/bin/eslint.js scripts/liveticker.js" ], "minify": [ "minifycss styles/liveticker.css > styles/liveticker.min.css", "minifyjs scripts/liveticker.js > scripts/liveticker.min.js" ] - }, - "repositories": [ - { - "type": "composer", - "url": "https://asset-packagist.org" - } - ] + } } diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index bd9221b..0000000 --- a/package-lock.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "name": "wp-liveticker2", - "version": "1.0.0-beta", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "cssesc": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-1.0.1.tgz", - "integrity": "sha512-S2hzrpWvE6G/rW7i7IxJfWBYn27QWfOIncUW++8Rbo1VB5zsJDSVPcnI+Q8z7rhxT6/yZeLOCja4cZnghJrNGA==" - }, - "indexes-of": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", - "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=" - }, - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" - }, - "postcss-media-query-parser": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", - "integrity": "sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ=" - }, - "postcss-resolve-nested-selector": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", - "integrity": "sha1-Kcy8fDfe36wwTp//C/FZaz9qDk4=" - }, - "postcss-selector-parser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-4.0.0.tgz", - "integrity": "sha512-5h+MvEjnzu1qy6MabjuoPatsGAjjDV9B24e7Cktjl+ClNtjVjmvAXjOFQr1u7RlWULKNGYaYVE4s+DIIQ4bOGA==", - "requires": { - "cssesc": "^1.0.1", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "stylelint-config-recommended": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-2.1.0.tgz", - "integrity": "sha512-ajMbivOD7JxdsnlS5945KYhvt7L/HwN6YeYF2BH6kE4UCLJR0YvXMf+2j7nQpJyYLZx9uZzU5G1ZOSBiWAc6yA==" - }, - "stylelint-config-recommended-scss": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-3.2.0.tgz", - "integrity": "sha512-M8BFHMRf8KNz5EQPKJd8nMCGmBd2o5coDEObfHVbEkyLDgjIf1V+U5dHjaGgvhm0zToUxshxN+Gc5wpbOOew4g==", - "requires": { - "stylelint-config-recommended": "^2.0.0" - } - }, - "stylelint-config-wordpress": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/stylelint-config-wordpress/-/stylelint-config-wordpress-13.1.0.tgz", - "integrity": "sha512-dpKj2/d3/XjDVoOvQzd54GoM8Rj5zldluOZKkVhBCc4JYMc6r1VYL5hpcgIjqy/i2Hyqg4Rh7zTafE/2AWq//w==", - "requires": { - "stylelint-config-recommended": "^2.1.0", - "stylelint-config-recommended-scss": "^3.2.0", - "stylelint-scss": "^3.3.0" - } - }, - "stylelint-scss": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-3.3.2.tgz", - "integrity": "sha512-0x+nD1heoMJYOfi3FfGcz3Hrwhcm+Qyq+BuvoBv5v9xrZZ1aziRXQauuhjwb87gWAa9MBzxhfUqBnvTUrHlLjA==", - "requires": { - "lodash": "^4.17.10", - "postcss-media-query-parser": "^0.2.3", - "postcss-resolve-nested-selector": "^0.1.1", - "postcss-selector-parser": "^4.0.0", - "postcss-value-parser": "^3.3.0" - } - }, - "uniq": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" - } - } -} diff --git a/package.json b/package.json index 1fc6eeb..d6448fe 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,10 @@ "description": "A simple Liveticker for Wordpress.", "author": "Stefan Kalscheuer", "license": "GPL-2.0+", - "dependencies": { - "stylelint-config-wordpress": "^13.1.0" + "devDependencies": { + "eslint": "^6", + "eslint-config-wordpress": "^2.0", + "stylelint": "^10.1", + "stylelint-config-wordpress": "^14.0" } } From b923d3494b783b48b4f71613e38d68efdf6fbde9 Mon Sep 17 00:00:00 2001 From: Stefan Kalscheuer Date: Tue, 27 Aug 2019 20:08:21 +0200 Subject: [PATCH 02/26] remove PHP 5.5 from CI matrix Dev dependencies start dropping support for PHP 5.5 now. Because the 5.2 to 5.4 are already missing in the CI matrix, we drop explicit 5.5 builds for now and rely on static compatibility checks. --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index b57a23a..b1359eb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,5 @@ language: php -dist: trusty php: -- '5.5' - '5.6' - '7.0' - '7.1' From 8acd840fc51131e597240ea93faae349db517498 Mon Sep 17 00:00:00 2001 From: Stefan Kalscheuer Date: Tue, 27 Aug 2019 20:12:27 +0200 Subject: [PATCH 03/26] update Drone CI configuration --- .drone.yml | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/.drone.yml b/.drone.yml index a9e824b..fcd3b2b 100644 --- a/.drone.yml +++ b/.drone.yml @@ -1,24 +1,16 @@ kind: pipeline name: default -clone: - disable: true - steps: -- name: clone - image: plugins/git - settings: - depth: 10 - skip_verify: true -- name: pre-build - image: composer - commands: - - composer install -- name: test - image: composer - commands: - - ./vendor/bin/robo test -- name: test-style - image: composer - commands: - - ./vendor/bin/robo test:cs + - name: pre-build + image: composer + commands: + - composer install + - name: test + image: composer + commands: + - composer test + - name: lint + image: composer + commands: + - composer lint-php From 2906d435d96fc151e81b05a568336049600dbe88 Mon Sep 17 00:00:00 2001 From: Stefan Kalscheuer Date: Tue, 27 Aug 2019 20:19:28 +0200 Subject: [PATCH 04/26] fix .eslintrc --- .eslintrc.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.eslintrc.json b/.eslintrc.json index 88304e7..4e02e7b 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,3 +1,3 @@ { - "extends": "./vendor/npm-asset/eslint-config-wordpress/index.js" + "extends": "eslint-config-wordpress" } From 0cab1a3580a5f3fdeaaf947c280b065bccff202f Mon Sep 17 00:00:00 2001 From: Stefan Kalscheuer Date: Wed, 28 Aug 2019 11:10:39 +0200 Subject: [PATCH 05/26] update JS code style to currently recommended conventions ES5 support is still present to not introduce breaking changes (dropped IE10 support) in minor updates. --- .eslintrc.json | 22 +++++++++++++++++++++- package.json | 2 +- scripts/liveticker.js | 8 +++----- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 4e02e7b..f008f76 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,3 +1,23 @@ { - "extends": "eslint-config-wordpress" + "env": { + "es6": false, + "browser": true + }, + "globals": { + "sclivetickerAjax": "readonly" + }, + "extends": [ + "plugin:@wordpress/eslint-plugin/recommended", + "plugin:@wordpress/eslint-plugin/es5" + ], + "overrides": [ + { + "files": [ + "*" + ], + "rules": { + "no-var": "off" + } + } + ] } diff --git a/package.json b/package.json index d6448fe..3aa6673 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "license": "GPL-2.0+", "devDependencies": { "eslint": "^6", - "eslint-config-wordpress": "^2.0", + "@wordpress/eslint-plugin": "^2.4", "stylelint": "^10.1", "stylelint-config-wordpress": "^14.0" } diff --git a/scripts/liveticker.js b/scripts/liveticker.js index 32edbbf..c2ba8f0 100644 --- a/scripts/liveticker.js +++ b/scripts/liveticker.js @@ -12,7 +12,6 @@ function scLiveticker() { * @return {void} */ scLiveticker.init = function() { - // Opt out if AJAX pobject not present. if ( 'undefined' === typeof sclivetickerAjax ) { return; @@ -31,7 +30,7 @@ scLiveticker.init = function() { s: elem.getAttribute( 'data-sclt-ticker' ), l: elem.getAttribute( 'data-sclt-limit' ), t: elem.getAttribute( 'data-sclt-last' ), - e: elem + e: elem, }; } ); @@ -44,7 +43,7 @@ scLiveticker.init = function() { w: elem.getAttribute( 'data-sclt-ticker' ), l: elem.getAttribute( 'data-sclt-limit' ), t: elem.getAttribute( 'data-sclt-last' ), - e: elem + e: elem, }; } ); @@ -61,7 +60,6 @@ scLiveticker.init = function() { * @return {void} */ scLiveticker.update = function() { - // Extract ticker-slug, limit and timestamp of last poll. var updateReq = 'action=sclt_update-ticks&_ajax_nonce=' + scLiveticker.nonce; var i, j; @@ -112,6 +110,7 @@ scLiveticker.update = function() { } setTimeout( scLiveticker.update, scLiveticker.pollInterval ); // Re-trigger update. } catch ( e ) { + // eslint-disable-next-line no-console console.warn( 'Liveticker AJAX update failed, stopping automatic updates.' ); } } @@ -131,7 +130,6 @@ scLiveticker.update = function() { * @return {void} */ scLiveticker.updateHTML = function( t, u ) { - // Prepend HTML of new ticks. t.e.innerHTML = u.h + t.e.innerHTML; t.e.setAttribute( 'data-sclt-last', u.t ); From 8103e78652d2cc38652bcfdfda8fecabf8a9d7f8 Mon Sep 17 00:00:00 2001 From: Stefan Kalscheuer Date: Wed, 13 Nov 2019 17:39:27 +0100 Subject: [PATCH 06/26] Declare compatibility with WP 5.3 [skip ci] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9321a45..0e5d07b 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ * Contributors: Stefan Kalscheuer * Tags: liveticker, feed, rss * Requires at least: 4.0 -* Tested up to: 5.2 +* Tested up to: 5.3 * Requires PHP: 5.2 * Stable tag: 1.0.0 * License: GPLv2 or later From e201d7c02f1ca4a64ecf80e3e981235e417eb1f7 Mon Sep 17 00:00:00 2001 From: Stefan Kalscheuer Date: Sun, 24 Nov 2019 14:42:43 +0100 Subject: [PATCH 07/26] use GMT timestamp for dynamic update Use real unix timestamps and do not rely on the system timezone. We now query the "post_date_gmt" field and use timestamps without zone bias. --- README.md | 4 ++++ includes/class-scliveticker-widget.php | 2 +- includes/class-scliveticker.php | 24 +++++++++++++++++++----- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 0e5d07b..e8ed146 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,10 @@ However the AJAX update will fetch the latest ticks and update cached tickers d ## Changelog +### 1.1.0 - unreleased + +* Use GMT for automatic updates + ### 1.0.0 - 2018-11-02 * Initial release diff --git a/includes/class-scliveticker-widget.php b/includes/class-scliveticker-widget.php index 04e1cc4..34e376a 100644 --- a/includes/class-scliveticker-widget.php +++ b/includes/class-scliveticker-widget.php @@ -73,7 +73,7 @@ class SCLiveticker_Widget extends WP_Widget { echo ' sclt-widget-ajax" ' . 'data-sclt-ticker="' . esc_attr( $category ) . '" ' . 'data-sclt-limit="' . esc_attr( $count ) . '" ' - . 'data-sclt-last="' . esc_attr( current_time( 'timestamp' ) ); + . 'data-sclt-last="' . esc_attr( current_datetime()->getTimestamp() ); } echo '">'; diff --git a/includes/class-scliveticker.php b/includes/class-scliveticker.php index d97b6d8..9173452 100644 --- a/includes/class-scliveticker.php +++ b/includes/class-scliveticker.php @@ -203,7 +203,7 @@ class SCLiveticker { $output .= ' sclt-ticker-ajax" ' . 'data-sclt-ticker="' . $ticker . '" ' . 'data-sclt-limit="' . $limit . '" ' - . 'data-sclt-last="' . current_time( 'timestamp' ); + . 'data-sclt-last="' . current_datetime()->getTimestamp(); } $output .= '">'; @@ -317,7 +317,13 @@ class SCLiveticker { } $limit = ( isset( $update_req['l'] ) ) ? intval( $update_req['l'] ) : - 1; - $last_poll = ( isset( $update_req['t'] ) ) ? intval( $update_req['t'] ) : 0; + $last_poll = explode( + ',', + gmdate( + 'Y,m,d,H,i,s', + ( isset( $update_req['t'] ) ) ? intval( $update_req['t'] ) : 0 + ) + ); // Query new ticks from DB. $query_args = array( @@ -331,7 +337,15 @@ class SCLiveticker { ), ), 'date_query' => array( - 'after' => date( 'c', $last_poll ), + 'column' => 'post_date_gmt', + 'after' => array( + 'year' => intval( $last_poll[0] ), + 'month' => intval( $last_poll[1] ), + 'day' => intval( $last_poll[2] ), + 'hour' => intval( $last_poll[3] ), + 'minute' => intval( $last_poll[4] ), + 'second' => intval( $last_poll[5] ), + ), ), ); @@ -351,13 +365,13 @@ class SCLiveticker { $res[] = array( 'w' => $slug, 'h' => $out, - 't' => current_time( 'timestamp' ), + 't' => current_datetime()->getTimestamp(), ); } else { $res[] = array( 's' => $slug, 'h' => $out, - 't' => current_time( 'timestamp' ), + 't' => current_datetime()->getTimestamp(), ); } } From 9ddcc41c6b3e3fdd25ee28ed6ca6375dc314dbc8 Mon Sep 17 00:00:00 2001 From: Stefan Kalscheuer Date: Sat, 23 Nov 2019 17:54:53 +0100 Subject: [PATCH 08/26] implement Gutenberg block to add liveticker without legacy shortcode * implement react-based JS block * refactor shortcode and widget to use the same syntax and classes --- .eslintrc.json | 6 +- composer.json | 4 ++ includes/class-scliveticker-admin.php | 31 +++++++++ includes/class-scliveticker-widget.php | 2 +- includes/class-scliveticker.php | 8 +-- scripts/block.js | 91 ++++++++++++++++++++++++++ scripts/liveticker.js | 24 +++++-- stklcode-liveticker.php | 3 + styles/block.css | 7 ++ styles/liveticker.css | 6 +- views/widget-form.php | 2 +- 11 files changed, 168 insertions(+), 16 deletions(-) create mode 100644 scripts/block.js create mode 100644 styles/block.css diff --git a/.eslintrc.json b/.eslintrc.json index f008f76..95e51b8 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -4,7 +4,8 @@ "browser": true }, "globals": { - "sclivetickerAjax": "readonly" + "sclivetickerAjax": "readonly", + "wp": "readonly" }, "extends": [ "plugin:@wordpress/eslint-plugin/recommended", @@ -16,7 +17,8 @@ "*" ], "rules": { - "no-var": "off" + "no-var": "off", + "object-shorthand": "off" } } ] diff --git a/composer.json b/composer.json index 5cc52a4..0894742 100644 --- a/composer.json +++ b/composer.json @@ -65,13 +65,17 @@ "phpcs --standard=phpcs.xml -s" ], "lint-css": [ + "./node_modules/stylelint/bin/stylelint.js styles/block.css", "./node_modules/stylelint/bin/stylelint.js styles/liveticker.css" ], "lint-js": [ + "./node_modules/eslint/bin/eslint.js scripts/block.js", "./node_modules/eslint/bin/eslint.js scripts/liveticker.js" ], "minify": [ + "minifycss styles/block.css > styles/block.min.css", "minifycss styles/liveticker.css > styles/liveticker.min.css", + "minifyjs scripts/block.js > scripts/block.min.js", "minifyjs scripts/liveticker.js > scripts/liveticker.min.js" ] } diff --git a/includes/class-scliveticker-admin.php b/includes/class-scliveticker-admin.php index 4a56989..ca0f1e1 100644 --- a/includes/class-scliveticker-admin.php +++ b/includes/class-scliveticker-admin.php @@ -202,4 +202,35 @@ class SCLiveticker_Admin extends SCLiveticker { return $result; } + + /** + * Register custom Gutenberg block type. + * + * @return void + * @since 1.1 + */ + public static function register_block() { + wp_register_script( + 'scliveticker-editor', + SCLIVETICKER_BASE . 'scripts/block.min.js', + array( 'wp-blocks', 'wp-element' ), + self::VERSION, + true + ); + + wp_register_style( + 'scliveticker-editor', + SCLIVETICKER_BASE . 'styles/block.min.css', + array(), + self::VERSION + ); + + register_block_type( + 'scliveticker-block/liveticker', + array( + 'editor_script' => 'scliveticker-editor', + 'editor_style' => 'scliveticker-editor', + ) + ); + } } diff --git a/includes/class-scliveticker-widget.php b/includes/class-scliveticker-widget.php index 34e376a..4e34012 100644 --- a/includes/class-scliveticker-widget.php +++ b/includes/class-scliveticker-widget.php @@ -70,7 +70,7 @@ class SCLiveticker_Widget extends WP_Widget { echo '
    '; + $output .= '">
      '; $args = array( 'post_type' => 'scliveticker_tick', @@ -226,7 +226,7 @@ class SCLiveticker { $output .= self::tick_html( get_the_time( 'd.m.Y H.i' ), get_the_title(), get_the_content() ); } - $output .= '
    '; + $output .= '
'; // Show RSS feed link, if configured. if ( $show_feed ) { diff --git a/scripts/block.js b/scripts/block.js new file mode 100644 index 0000000..5c28c72 --- /dev/null +++ b/scripts/block.js @@ -0,0 +1,91 @@ +/** + * stklcode-liveticker Gutenberg Block + * + * Gutenberg Block to integrate the liveticker widget without shortcode. + */ +( function() { + var { __ } = wp.i18n; + var { registerBlockType } = wp.blocks; + var el = wp.element.createElement; + + registerBlockType( 'scliveticker/ticker', { + title: __( 'Liveticker', 'stklcode-liveticker' ), + icon: 'rss', + category: 'widgets', + keywords: [ + __( 'Liveticker', 'stklcode-liveticker' ), + ], + attributes: { + ticker: { + type: 'string', + default: '', + }, + limit: { + type: 'number', + default: 5, + }, + unlimited: { + type: 'boolean', + default: false, + }, + }, + edit: function( props ) { + return el( + 'div', + { className: props.className + ' components-placeholder' }, + [ + el( + wp.components.TextControl, + { + label: [ + el( + wp.components.Dashicon, + { icon: 'rss' } + ), + __( 'Liveticker', 'stklcode-liveticker' ) ], + value: props.attributes.ticker, + onChange: function( val ) { + props.setAttributes( { ticker: val } ); + }, + } + ), + el( + wp.components.TextControl, + { + label: __( 'Number of Ticks', 'stklcode-liveticker' ), + type: 'number', + min: 1, + step: 1, + disabled: props.attributes.unlimited, + value: props.attributes.limit, + onChange: function( val ) { + props.setAttributes( { limit: val } ); + }, + } + ), + el( + wp.components.CheckboxControl, + { + label: __( 'unlimited', 'stklcode-liveticker' ), + checked: props.attributes.unlimited, + onChange: function( val ) { + props.setAttributes( { unlimited: val } ); + }, + } + ), + ], + ); + }, + save: function( props ) { + return el( + 'div', + { + className: props.className + ' sclt-ajax', + 'data-sclt-ticker': props.attributes.ticker, + 'data-sclt-limit': props.attributes.unlimited ? 0 : props.attributes.limit, + 'data-sclt-last': 0, + } + ); + }, + } ); +}() ); diff --git a/scripts/liveticker.js b/scripts/liveticker.js index c2ba8f0..f237e0e 100644 --- a/scripts/liveticker.js +++ b/scripts/liveticker.js @@ -1,7 +1,7 @@ /** * Contructor of the scLiveticker object. * - * @constructor + * @class */ function scLiveticker() { } @@ -24,26 +24,38 @@ scLiveticker.init = function() { // Get ticker elements. scLiveticker.ticker = [].map.call( - document.querySelectorAll( 'ul.sclt-ticker-ajax' ), + document.querySelectorAll( 'div.wp-block-scliveticker-ticker.sclt-ajax' ), function( elem ) { + var list = elem.querySelector( 'ul' ); + if ( ! list ) { + list = document.createElement( 'ul' ); + elem.appendChild( list ); + } + return { s: elem.getAttribute( 'data-sclt-ticker' ), l: elem.getAttribute( 'data-sclt-limit' ), t: elem.getAttribute( 'data-sclt-last' ), - e: elem, + e: list, }; } ); // Get widget elements. scLiveticker.widgets = [].map.call( - document.querySelectorAll( 'ul.sclt-widget-ajax' ), + document.querySelectorAll( 'div.wp-widget-scliveticker-ticker.sclt-ajax' ), function( elem ) { + var list = elem.querySelector( 'ul' ); + if ( ! list ) { + list = document.createElement( 'ul' ); + elem.appendChild( list ); + } + return { w: elem.getAttribute( 'data-sclt-ticker' ), l: elem.getAttribute( 'data-sclt-limit' ), t: elem.getAttribute( 'data-sclt-last' ), - e: elem, + e: list, }; } ); @@ -132,7 +144,7 @@ scLiveticker.update = function() { scLiveticker.updateHTML = function( t, u ) { // Prepend HTML of new ticks. t.e.innerHTML = u.h + t.e.innerHTML; - t.e.setAttribute( 'data-sclt-last', u.t ); + t.e.parentNode.setAttribute( 'data-sclt-last', u.t ); // Remove tail, if limit is set. if ( 0 < t.l ) { diff --git a/stklcode-liveticker.php b/stklcode-liveticker.php index 795c351..4d3aff3 100644 --- a/stklcode-liveticker.php +++ b/stklcode-liveticker.php @@ -55,6 +55,9 @@ add_shortcode( 'liveticker', array( 'SCLiveticker', 'shortcode_ticker_show' ) ); // Add Widget. add_action( 'widgets_init', array( 'SCLiveticker_Widget', 'register' ) ); +// Add Gutenberg block. +add_action( 'enqueue_block_editor_assets', array( 'SCLiveticker_Admin', 'register_block' ) ); + // Autoload. spl_autoload_register( 'scliveticker_autoload' ); diff --git a/styles/block.css b/styles/block.css new file mode 100644 index 0000000..16ec33a --- /dev/null +++ b/styles/block.css @@ -0,0 +1,7 @@ +div.wp-block-scliveticker-ticker div.components-base-control:first-child label { + font-weight: 600; +} + +div.wp-block-scliveticker-ticker div.components-base-control:first-child label > .dashicon { + margin-right: 8px; +} diff --git a/styles/liveticker.css b/styles/liveticker.css index d05aa07..cd25599 100644 --- a/styles/liveticker.css +++ b/styles/liveticker.css @@ -1,8 +1,10 @@ -ul.sclt-ticker { +div.wp-block-scliveticker-ticker ul, +div.wp-block-scliveticker-ajax-ticker ul { list-style-type: none; } -ul.sclt-ticker > li.sclt-tick { +div.wp-block-scliveticker-ticker ul > li.sclt-tick, +div.wp-block-scliveticker-ajax-ticker ul > li.sclt-tick { background-color: #f5f5f5; list-style-type: none; margin: 0.1em; diff --git a/views/widget-form.php b/views/widget-form.php index 598969c..aeda8eb 100644 --- a/views/widget-form.php +++ b/views/widget-form.php @@ -40,7 +40,7 @@ if ( ! defined( 'ABSPATH' ) ) { - +