aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md10
-rw-r--r--COPYING4
-rw-r--r--README.md2
-rw-r--r--application/NetscapeBookmarkUtils.php34
-rw-r--r--application/config/ConfigJson.php10
-rw-r--r--application/config/ConfigManager.php6
-rw-r--r--composer.json2
-rw-r--r--inc/awesomplete-multiple-tags.js28
-rw-r--r--inc/plugin_admin.js28
-rw-r--r--index.php2
-rw-r--r--plugins/piwik/piwik.html28
-rw-r--r--plugins/playvideos/youtube_playlist.js28
-rw-r--r--plugins/qrcode/shaarli-qrcode.js28
-rw-r--r--tests/NetscapeBookmarkUtils/BookmarkImportTest.php42
-rw-r--r--tests/config/ConfigJsonTest.php2
-rw-r--r--tests/utils/config/configJson.json.php2
-rw-r--r--tpl/default/configure.html15
-rw-r--r--tpl/default/css/shaarli.css5
-rw-r--r--tpl/default/editlink.html30
-rw-r--r--tpl/default/install.html13
-rw-r--r--tpl/default/js/shaarli.js130
-rw-r--r--tpl/default/linklist.html2
-rw-r--r--tpl/default/loginform.html11
-rw-r--r--tpl/default/page.footer.html6
-rw-r--r--tpl/default/page.header.html4
-rw-r--r--tpl/default/picwall.html5
-rw-r--r--tpl/default/pluginsadmin.html10
-rw-r--r--tpl/default/tools.html42
28 files changed, 379 insertions, 150 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1a87a8ca..f0813b97 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,10 +24,13 @@ configuration to enable URL rewriting, see:
24Theming: 24Theming:
25 - Introduce a new theme 25 - Introduce a new theme
26 - Allow selecting themes/templates from the configuration page 26 - Allow selecting themes/templates from the configuration page
27 - New/Edit link form can be submitted using CTRL+Enter in the textarea
28 - Shaarli version is displayed in the footer when logged in
27- Add plugin placeholders to Atom/RSS feed templates 29- Add plugin placeholders to Atom/RSS feed templates
28- Add OpenSearch to feed templates 30- Add OpenSearch to feed templates
29- Add `campaign_` to the URL cleanup pattern list 31- Add `campaign_` to the URL cleanup pattern list
30- Add an AUTHORS file and Makefile target to list authors from Git commit data 32- Add an AUTHORS file and Makefile target to list authors from Git commit data
33- Link imports are now logged in `data/` folder, and can be debug using `dev.debug=true` setting.
31 34
32### Changed 35### Changed
33- Docker: enable nginx URL rewriting for the REST API 36- Docker: enable nginx URL rewriting for the REST API
@@ -35,6 +38,8 @@ Theming:
35 - Move `user.css` to the `data` folder 38 - Move `user.css` to the `data` folder
36 - Move default template files to a subfolder (`default`) 39 - Move default template files to a subfolder (`default`)
37 - Rename the legacy theme to `vintage` 40 - Rename the legacy theme to `vintage`
41 - Private only filter is now displayed as a search parameter
42 - Autocomplete: pre-select the first element
38- Move PubSubHub to a dedicated plugin 43- Move PubSubHub to a dedicated plugin
39- Coding style: 44- Coding style:
40 - explicit method visibility 45 - explicit method visibility
@@ -42,6 +47,9 @@ Theming:
42 - remove unused variables 47 - remove unused variables
43- The updater now keeps custom theme preferences 48- The updater now keeps custom theme preferences
44- Simplify the COPYING information 49- Simplify the COPYING information
50- Improved client locale detection
51- Improved date time display depending on the locale
52- Partial namespace support for Shaarli classes
45 53
46### Removed 54### Removed
47- PHP < 5.5 compatibility 55- PHP < 5.5 compatibility
@@ -57,6 +65,8 @@ Theming:
57- Fix redirection after link deletion 65- Fix redirection after link deletion
58- Do not access LinkDB links by ID before the Updater applies migrations 66- Do not access LinkDB links by ID before the Updater applies migrations
59- Remove extra spaces in the bookmarklet's name 67- Remove extra spaces in the bookmarklet's name
68- Piwik plugin: Piwik URL protocol can now be set (http or https)
69- All inline JS has been moved to dedicated JS files
60 70
61### Security 71### Security
62- Markdown plugin: escape HTML entities by default 72- Markdown plugin: escape HTML entities by default
diff --git a/COPYING b/COPYING
index 4bbdf2b3..05202152 100644
--- a/COPYING
+++ b/COPYING
@@ -46,6 +46,10 @@ Files: plugins/wallabag/wallabag.png
46License: MIT License (http://opensource.org/licenses/MIT) 46License: MIT License (http://opensource.org/licenses/MIT)
47Copyright: (C) 2015 Nicolas Lœuillet - https://github.com/wallabag/wallabag 47Copyright: (C) 2015 Nicolas Lœuillet - https://github.com/wallabag/wallabag
48 48
49Files: tpl/default/sad_star.png
50License: MIT License (http://opensource.org/licenses/MIT)
51Copyright: (C) 2015 kalvn - https://github.com/kalvn/Shaarli-Material
52
49---------------------------------------------------- 53----------------------------------------------------
50ZLIB/LIBPNG LICENSE 54ZLIB/LIBPNG LICENSE
51 55
diff --git a/README.md b/README.md
index 21062b9b..db1b901f 100644
--- a/README.md
+++ b/README.md
@@ -20,7 +20,7 @@ _It is designed to be personal (single-user), fast and handy._
20- [Bugs/Feature requests/Discussion](https://github.com/shaarli/Shaarli/issues/) 20- [Bugs/Feature requests/Discussion](https://github.com/shaarli/Shaarli/issues/)
21 21
22### Demo 22### Demo
23You can use this [public demo instance of Shaarli](http://shaarlidemo.tuxfamily.org/Shaarli). 23You can use this [public demo instance of Shaarli](https://demo.shaarli.org).
24It runs the latest development version of Shaarli and is updated/reset daily. 24It runs the latest development version of Shaarli and is updated/reset daily.
25 25
26Login: `demo`; Password: `demo` 26Login: `demo`; Password: `demo`
diff --git a/application/NetscapeBookmarkUtils.php b/application/NetscapeBookmarkUtils.php
index e7148d00..ab346f81 100644
--- a/application/NetscapeBookmarkUtils.php
+++ b/application/NetscapeBookmarkUtils.php
@@ -1,7 +1,13 @@
1<?php 1<?php
2 2
3use Psr\Log\LogLevel;
4use Shaarli\Config\ConfigManager;
5use Shaarli\NetscapeBookmarkParser\NetscapeBookmarkParser;
6use Katzgrau\KLogger\Logger;
7
3/** 8/**
4 * Utilities to import and export bookmarks using the Netscape format 9 * Utilities to import and export bookmarks using the Netscape format
10 * TODO: Not static, use a container.
5 */ 11 */
6class NetscapeBookmarkUtils 12class NetscapeBookmarkUtils
7{ 13{
@@ -85,14 +91,14 @@ class NetscapeBookmarkUtils
85 /** 91 /**
86 * Imports Web bookmarks from an uploaded Netscape bookmark dump 92 * Imports Web bookmarks from an uploaded Netscape bookmark dump
87 * 93 *
88 * @param array $post Server $_POST parameters 94 * @param array $post Server $_POST parameters
89 * @param array $files Server $_FILES parameters 95 * @param array $files Server $_FILES parameters
90 * @param LinkDB $linkDb Loaded LinkDB instance 96 * @param LinkDB $linkDb Loaded LinkDB instance
91 * @param string $pagecache Page cache 97 * @param ConfigManager $conf instance
92 * 98 *
93 * @return string Summary of the bookmark import status 99 * @return string Summary of the bookmark import status
94 */ 100 */
95 public static function import($post, $files, $linkDb, $pagecache) 101 public static function import($post, $files, $linkDb, $conf)
96 { 102 {
97 $filename = $files['filetoupload']['name']; 103 $filename = $files['filetoupload']['name'];
98 $filesize = $files['filetoupload']['size']; 104 $filesize = $files['filetoupload']['size'];
@@ -119,10 +125,20 @@ class NetscapeBookmarkUtils
119 $defaultPrivacy = 0; 125 $defaultPrivacy = 0;
120 126
121 $parser = new NetscapeBookmarkParser( 127 $parser = new NetscapeBookmarkParser(
122 true, // nested tag support 128 true, // nested tag support
123 $defaultTags, // additional user-specified tags 129 $defaultTags, // additional user-specified tags
124 strval(1 - $defaultPrivacy) // defaultPub = 1 - defaultPrivacy 130 strval(1 - $defaultPrivacy), // defaultPub = 1 - defaultPrivacy
131 $conf->get('resource.data_dir') // log path, will be overridden
132 );
133 $logger = new Logger(
134 $conf->get('resource.data_dir'),
135 ! $conf->get('dev.debug') ? LogLevel::INFO : LogLevel::DEBUG,
136 [
137 'prefix' => 'import.',
138 'extension' => 'log',
139 ]
125 ); 140 );
141 $parser->setLogger($logger);
126 $bookmarks = $parser->parseString($data); 142 $bookmarks = $parser->parseString($data);
127 143
128 $importCount = 0; 144 $importCount = 0;
@@ -179,7 +195,7 @@ class NetscapeBookmarkUtils
179 $importCount++; 195 $importCount++;
180 } 196 }
181 197
182 $linkDb->save($pagecache); 198 $linkDb->save($conf->get('resource.page_cache'));
183 return self::importStatus( 199 return self::importStatus(
184 $filename, 200 $filename,
185 $filesize, 201 $filesize,
diff --git a/application/config/ConfigJson.php b/application/config/ConfigJson.php
index 30908d90..9ef2ef56 100644
--- a/application/config/ConfigJson.php
+++ b/application/config/ConfigJson.php
@@ -21,8 +21,14 @@ class ConfigJson implements ConfigIO
21 $data = str_replace(self::getPhpSuffix(), '', $data); 21 $data = str_replace(self::getPhpSuffix(), '', $data);
22 $data = json_decode($data, true); 22 $data = json_decode($data, true);
23 if ($data === null) { 23 if ($data === null) {
24 $error = json_last_error(); 24 $errorCode = json_last_error();
25 throw new \Exception('An error occurred while parsing JSON file: error code #'. $error); 25 $error = 'An error occurred while parsing JSON configuration file ('. $filepath .'): error code #';
26 $error .= $errorCode. '<br>➜ <code>' . json_last_error_msg() .'</code>';
27 if ($errorCode === JSON_ERROR_SYNTAX) {
28 $error .= '<br>Please check your JSON syntax (without PHP comment tags) using a JSON lint tool such as ';
29 $error .= '<a href="http://jsonlint.com/">jsonlint.com</a>.';
30 }
31 throw new \Exception($error);
26 } 32 }
27 return $data; 33 return $data;
28 } 34 }
diff --git a/application/config/ConfigManager.php b/application/config/ConfigManager.php
index c5eeda08..7bfbfc72 100644
--- a/application/config/ConfigManager.php
+++ b/application/config/ConfigManager.php
@@ -81,7 +81,11 @@ class ConfigManager
81 */ 81 */
82 protected function load() 82 protected function load()
83 { 83 {
84 $this->loadedConfig = $this->configIO->read($this->getConfigFileExt()); 84 try {
85 $this->loadedConfig = $this->configIO->read($this->getConfigFileExt());
86 } catch (\Exception $e) {
87 die($e->getMessage());
88 }
85 $this->setDefaultValues(); 89 $this->setDefaultValues();
86 } 90 }
87 91
diff --git a/composer.json b/composer.json
index 57851e53..792c43d3 100644
--- a/composer.json
+++ b/composer.json
@@ -11,7 +11,7 @@
11 "keywords": ["bookmark", "link", "share", "web"], 11 "keywords": ["bookmark", "link", "share", "web"],
12 "require": { 12 "require": {
13 "php": ">=5.5", 13 "php": ">=5.5",
14 "shaarli/netscape-bookmark-parser": "1.*", 14 "shaarli/netscape-bookmark-parser": "^2.0",
15 "erusev/parsedown": "1.6", 15 "erusev/parsedown": "1.6",
16 "slim/slim": "^3.0", 16 "slim/slim": "^3.0",
17 "pubsubhubbub/publisher": "dev-master" 17 "pubsubhubbub/publisher": "dev-master"
diff --git a/inc/awesomplete-multiple-tags.js b/inc/awesomplete-multiple-tags.js
index faecb417..c38dc38e 100644
--- a/inc/awesomplete-multiple-tags.js
+++ b/inc/awesomplete-multiple-tags.js
@@ -1,3 +1,31 @@
1/** @licstart The following is the entire license notice for the
2 * JavaScript code in this page.
3 *
4 * Copyright: (c) 2011-2015 Sébastien SAUVAGE <sebsauvage@sebsauvage.net>
5 * (c) 2011-2017 The Shaarli Community, see AUTHORS
6 *
7 * This software is provided 'as-is', without any express or implied warranty.
8 * In no event will the authors be held liable for any damages arising from
9 * the use of this software.
10 *
11 * Permission is granted to anyone to use this software for any purpose,
12 * including commercial applications, and to alter it and redistribute it
13 * freely, subject to the following restrictions:
14 *
15 * 1. The origin of this software must not be misrepresented; you must not
16 * claim that you wrote the original software. If you use this software
17 * in a product, an acknowledgment in the product documentation would
18 * be appreciated but is not required.
19 *
20 * 2. Altered source versions must be plainly marked as such, and must
21 * not be misrepresented as being the original software.
22 *
23 * 3. This notice may not be removed or altered from any source distribution.
24 *
25 * @licend The above is the entire license notice
26 * for the JavaScript code in this page.
27 */
28
1var awp = Awesomplete.$; 29var awp = Awesomplete.$;
2var autocompleteFields = document.querySelectorAll('input[data-multiple]'); 30var autocompleteFields = document.querySelectorAll('input[data-multiple]');
3[].forEach.call(autocompleteFields, function(autocompleteField) { 31[].forEach.call(autocompleteFields, function(autocompleteField) {
diff --git a/inc/plugin_admin.js b/inc/plugin_admin.js
index 055ac285..4b55e0f3 100644
--- a/inc/plugin_admin.js
+++ b/inc/plugin_admin.js
@@ -1,3 +1,31 @@
1/** @licstart The following is the entire license notice for the
2 * JavaScript code in this page.
3 *
4 * Copyright: (c) 2011-2015 Sébastien SAUVAGE <sebsauvage@sebsauvage.net>
5 * (c) 2011-2017 The Shaarli Community, see AUTHORS
6 *
7 * This software is provided 'as-is', without any express or implied warranty.
8 * In no event will the authors be held liable for any damages arising from
9 * the use of this software.
10 *
11 * Permission is granted to anyone to use this software for any purpose,
12 * including commercial applications, and to alter it and redistribute it
13 * freely, subject to the following restrictions:
14 *
15 * 1. The origin of this software must not be misrepresented; you must not
16 * claim that you wrote the original software. If you use this software
17 * in a product, an acknowledgment in the product documentation would
18 * be appreciated but is not required.
19 *
20 * 2. Altered source versions must be plainly marked as such, and must
21 * not be misrepresented as being the original software.
22 *
23 * 3. This notice may not be removed or altered from any source distribution.
24 *
25 * @licend The above is the entire license notice
26 * for the JavaScript code in this page.
27 */
28
1/** 29/**
2 * Change the position counter of a row. 30 * Change the position counter of a row.
3 * 31 *
diff --git a/index.php b/index.php
index 3c2bb1d2..cc7f3ca3 100644
--- a/index.php
+++ b/index.php
@@ -1528,7 +1528,7 @@ function renderPage($conf, $pluginManager, $LINKSDB)
1528 $_POST, 1528 $_POST,
1529 $_FILES, 1529 $_FILES,
1530 $LINKSDB, 1530 $LINKSDB,
1531 $conf->get('resource.page_cache') 1531 $conf
1532 ); 1532 );
1533 echo '<script>alert("'.$status.'");document.location=\'?do=' 1533 echo '<script>alert("'.$status.'");document.location=\'?do='
1534 .Router::$PAGE_IMPORT .'\';</script>'; 1534 .Router::$PAGE_IMPORT .'\';</script>';
diff --git a/plugins/piwik/piwik.html b/plugins/piwik/piwik.html
index 0881d7c8..f4bc358a 100644
--- a/plugins/piwik/piwik.html
+++ b/plugins/piwik/piwik.html
@@ -1,5 +1,33 @@
1<!-- Piwik --> 1<!-- Piwik -->
2<script type="text/javascript"> 2<script type="text/javascript">
3 /** @licstart The following is the entire license notice for the
4 * JavaScript code in this page.
5 *
6 * Copyright: (c) 2011-2015 Sébastien SAUVAGE <sebsauvage@sebsauvage.net>
7 * (c) 2011-2017 The Shaarli Community, see AUTHORS
8 *
9 * This software is provided 'as-is', without any express or implied warranty.
10 * In no event will the authors be held liable for any damages arising from
11 * the use of this software.
12 *
13 * Permission is granted to anyone to use this software for any purpose,
14 * including commercial applications, and to alter it and redistribute it
15 * freely, subject to the following restrictions:
16 *
17 * 1. The origin of this software must not be misrepresented; you must not
18 * claim that you wrote the original software. If you use this software
19 * in a product, an acknowledgment in the product documentation would
20 * be appreciated but is not required.
21 *
22 * 2. Altered source versions must be plainly marked as such, and must
23 * not be misrepresented as being the original software.
24 *
25 * 3. This notice may not be removed or altered from any source distribution.
26 *
27 * @licend The above is the entire license notice
28 * for the JavaScript code in this page.
29 */
30
3 var _paq = _paq || []; 31 var _paq = _paq || [];
4 _paq.push(['trackPageView']); 32 _paq.push(['trackPageView']);
5 _paq.push(['enableLinkTracking']); 33 _paq.push(['enableLinkTracking']);
diff --git a/plugins/playvideos/youtube_playlist.js b/plugins/playvideos/youtube_playlist.js
index be8d63af..3b608a5d 100644
--- a/plugins/playvideos/youtube_playlist.js
+++ b/plugins/playvideos/youtube_playlist.js
@@ -1,3 +1,31 @@
1/** @licstart The following is the entire license notice for the
2 * JavaScript code in this page.
3 *
4 * Copyright: (c) 2011-2015 Sébastien SAUVAGE <sebsauvage@sebsauvage.net>
5 * (c) 2011-2017 The Shaarli Community, see AUTHORS
6 *
7 * This software is provided 'as-is', without any express or implied warranty.
8 * In no event will the authors be held liable for any damages arising from
9 * the use of this software.
10 *
11 * Permission is granted to anyone to use this software for any purpose,
12 * including commercial applications, and to alter it and redistribute it
13 * freely, subject to the following restrictions:
14 *
15 * 1. The origin of this software must not be misrepresented; you must not
16 * claim that you wrote the original software. If you use this software
17 * in a product, an acknowledgment in the product documentation would
18 * be appreciated but is not required.
19 *
20 * 2. Altered source versions must be plainly marked as such, and must
21 * not be misrepresented as being the original software.
22 *
23 * 3. This notice may not be removed or altered from any source distribution.
24 *
25 * @licend The above is the entire license notice
26 * for the JavaScript code in this page.
27 */
28
1var run_playideos = (function () { 29var run_playideos = (function () {
2 var e, n, t, o, r, i = [].indexOf || function (e) { 30 var e, n, t, o, r, i = [].indexOf || function (e) {
3 for (var n = 0, t = this.length; n < t; n++) { 31 for (var n = 0, t = this.length; n < t; n++) {
diff --git a/plugins/qrcode/shaarli-qrcode.js b/plugins/qrcode/shaarli-qrcode.js
index 615f54c7..fe77c4cd 100644
--- a/plugins/qrcode/shaarli-qrcode.js
+++ b/plugins/qrcode/shaarli-qrcode.js
@@ -1,3 +1,31 @@
1/** @licstart The following is the entire license notice for the
2 * JavaScript code in this page.
3 *
4 * Copyright: (c) 2011-2015 Sébastien SAUVAGE <sebsauvage@sebsauvage.net>
5 * (c) 2011-2017 The Shaarli Community, see AUTHORS
6 *
7 * This software is provided 'as-is', without any express or implied warranty.
8 * In no event will the authors be held liable for any damages arising from
9 * the use of this software.
10 *
11 * Permission is granted to anyone to use this software for any purpose,
12 * including commercial applications, and to alter it and redistribute it
13 * freely, subject to the following restrictions:
14 *
15 * 1. The origin of this software must not be misrepresented; you must not
16 * claim that you wrote the original software. If you use this software
17 * in a product, an acknowledgment in the product documentation would
18 * be appreciated but is not required.
19 *
20 * 2. Altered source versions must be plainly marked as such, and must
21 * not be misrepresented as being the original software.
22 *
23 * 3. This notice may not be removed or altered from any source distribution.
24 *
25 * @licend The above is the entire license notice
26 * for the JavaScript code in this page.
27 */
28
1// Show the QR-Code of a permalink (when the QR-Code icon is clicked). 29// Show the QR-Code of a permalink (when the QR-Code icon is clicked).
2function showQrCode(caller,loading) 30function showQrCode(caller,loading)
3{ 31{
diff --git a/tests/NetscapeBookmarkUtils/BookmarkImportTest.php b/tests/NetscapeBookmarkUtils/BookmarkImportTest.php
index 0ca07eac..5925a8e1 100644
--- a/tests/NetscapeBookmarkUtils/BookmarkImportTest.php
+++ b/tests/NetscapeBookmarkUtils/BookmarkImportTest.php
@@ -2,6 +2,7 @@
2 2
3require_once 'application/NetscapeBookmarkUtils.php'; 3require_once 'application/NetscapeBookmarkUtils.php';
4 4
5use Shaarli\Config\ConfigManager;
5 6
6/** 7/**
7 * Utility function to load a file's metadata in a $_FILES-like array 8 * Utility function to load a file's metadata in a $_FILES-like array
@@ -43,6 +44,11 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
43 protected $pagecache = 'tests'; 44 protected $pagecache = 'tests';
44 45
45 /** 46 /**
47 * @var ConfigManager instance.
48 */
49 protected $conf;
50
51 /**
46 * @var string Save the current timezone. 52 * @var string Save the current timezone.
47 */ 53 */
48 protected static $defaultTimeZone; 54 protected static $defaultTimeZone;
@@ -65,6 +71,8 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
65 // start with an empty datastore 71 // start with an empty datastore
66 file_put_contents(self::$testDatastore, '<?php /* S7QysKquBQA= */ ?>'); 72 file_put_contents(self::$testDatastore, '<?php /* S7QysKquBQA= */ ?>');
67 $this->linkDb = new LinkDB(self::$testDatastore, true, false); 73 $this->linkDb = new LinkDB(self::$testDatastore, true, false);
74 $this->conf = new ConfigManager('tests/utils/config/configJson');
75 $this->conf->set('resource.page_cache', $this->pagecache);
68 } 76 }
69 77
70 public static function tearDownAfterClass() 78 public static function tearDownAfterClass()
@@ -81,7 +89,7 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
81 $this->assertEquals( 89 $this->assertEquals(
82 'File empty.htm (0 bytes) has an unknown file format.' 90 'File empty.htm (0 bytes) has an unknown file format.'
83 .' Nothing was imported.', 91 .' Nothing was imported.',
84 NetscapeBookmarkUtils::import(NULL, $files, NULL, NULL) 92 NetscapeBookmarkUtils::import(NULL, $files, NULL, $this->conf)
85 ); 93 );
86 $this->assertEquals(0, count($this->linkDb)); 94 $this->assertEquals(0, count($this->linkDb));
87 } 95 }
@@ -94,7 +102,7 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
94 $files = file2array('no_doctype.htm'); 102 $files = file2array('no_doctype.htm');
95 $this->assertEquals( 103 $this->assertEquals(
96 'File no_doctype.htm (350 bytes) has an unknown file format. Nothing was imported.', 104 'File no_doctype.htm (350 bytes) has an unknown file format. Nothing was imported.',
97 NetscapeBookmarkUtils::import(NULL, $files, NULL, NULL) 105 NetscapeBookmarkUtils::import(NULL, $files, NULL, $this->conf)
98 ); 106 );
99 $this->assertEquals(0, count($this->linkDb)); 107 $this->assertEquals(0, count($this->linkDb));
100 } 108 }
@@ -108,7 +116,7 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
108 $this->assertEquals( 116 $this->assertEquals(
109 'File internet_explorer_encoding.htm (356 bytes) was successfully processed:' 117 'File internet_explorer_encoding.htm (356 bytes) was successfully processed:'
110 .' 1 links imported, 0 links overwritten, 0 links skipped.', 118 .' 1 links imported, 0 links overwritten, 0 links skipped.',
111 NetscapeBookmarkUtils::import(array(), $files, $this->linkDb, $this->pagecache) 119 NetscapeBookmarkUtils::import(array(), $files, $this->linkDb, $this->conf)
112 ); 120 );
113 $this->assertEquals(1, count($this->linkDb)); 121 $this->assertEquals(1, count($this->linkDb));
114 $this->assertEquals(0, count_private($this->linkDb)); 122 $this->assertEquals(0, count_private($this->linkDb));
@@ -137,7 +145,7 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
137 $this->assertEquals( 145 $this->assertEquals(
138 'File netscape_nested.htm (1337 bytes) was successfully processed:' 146 'File netscape_nested.htm (1337 bytes) was successfully processed:'
139 .' 8 links imported, 0 links overwritten, 0 links skipped.', 147 .' 8 links imported, 0 links overwritten, 0 links skipped.',
140 NetscapeBookmarkUtils::import(array(), $files, $this->linkDb, $this->pagecache) 148 NetscapeBookmarkUtils::import(array(), $files, $this->linkDb, $this->conf)
141 ); 149 );
142 $this->assertEquals(8, count($this->linkDb)); 150 $this->assertEquals(8, count($this->linkDb));
143 $this->assertEquals(2, count_private($this->linkDb)); 151 $this->assertEquals(2, count_private($this->linkDb));
@@ -259,7 +267,7 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
259 $this->assertEquals( 267 $this->assertEquals(
260 'File netscape_basic.htm (482 bytes) was successfully processed:' 268 'File netscape_basic.htm (482 bytes) was successfully processed:'
261 .' 2 links imported, 0 links overwritten, 0 links skipped.', 269 .' 2 links imported, 0 links overwritten, 0 links skipped.',
262 NetscapeBookmarkUtils::import(array(), $files, $this->linkDb, $this->pagecache) 270 NetscapeBookmarkUtils::import(array(), $files, $this->linkDb, $this->conf)
263 ); 271 );
264 272
265 $this->assertEquals(2, count($this->linkDb)); 273 $this->assertEquals(2, count($this->linkDb));
@@ -304,7 +312,7 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
304 $this->assertEquals( 312 $this->assertEquals(
305 'File netscape_basic.htm (482 bytes) was successfully processed:' 313 'File netscape_basic.htm (482 bytes) was successfully processed:'
306 .' 2 links imported, 0 links overwritten, 0 links skipped.', 314 .' 2 links imported, 0 links overwritten, 0 links skipped.',
307 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache) 315 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf)
308 ); 316 );
309 $this->assertEquals(2, count($this->linkDb)); 317 $this->assertEquals(2, count($this->linkDb));
310 $this->assertEquals(1, count_private($this->linkDb)); 318 $this->assertEquals(1, count_private($this->linkDb));
@@ -348,7 +356,7 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
348 $this->assertEquals( 356 $this->assertEquals(
349 'File netscape_basic.htm (482 bytes) was successfully processed:' 357 'File netscape_basic.htm (482 bytes) was successfully processed:'
350 .' 2 links imported, 0 links overwritten, 0 links skipped.', 358 .' 2 links imported, 0 links overwritten, 0 links skipped.',
351 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache) 359 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf)
352 ); 360 );
353 $this->assertEquals(2, count($this->linkDb)); 361 $this->assertEquals(2, count($this->linkDb));
354 $this->assertEquals(0, count_private($this->linkDb)); 362 $this->assertEquals(0, count_private($this->linkDb));
@@ -372,7 +380,7 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
372 $this->assertEquals( 380 $this->assertEquals(
373 'File netscape_basic.htm (482 bytes) was successfully processed:' 381 'File netscape_basic.htm (482 bytes) was successfully processed:'
374 .' 2 links imported, 0 links overwritten, 0 links skipped.', 382 .' 2 links imported, 0 links overwritten, 0 links skipped.',
375 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache) 383 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf)
376 ); 384 );
377 $this->assertEquals(2, count($this->linkDb)); 385 $this->assertEquals(2, count($this->linkDb));
378 $this->assertEquals(2, count_private($this->linkDb)); 386 $this->assertEquals(2, count_private($this->linkDb));
@@ -398,7 +406,7 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
398 $this->assertEquals( 406 $this->assertEquals(
399 'File netscape_basic.htm (482 bytes) was successfully processed:' 407 'File netscape_basic.htm (482 bytes) was successfully processed:'
400 .' 2 links imported, 0 links overwritten, 0 links skipped.', 408 .' 2 links imported, 0 links overwritten, 0 links skipped.',
401 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache) 409 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf)
402 ); 410 );
403 $this->assertEquals(2, count($this->linkDb)); 411 $this->assertEquals(2, count($this->linkDb));
404 $this->assertEquals(2, count_private($this->linkDb)); 412 $this->assertEquals(2, count_private($this->linkDb));
@@ -418,7 +426,7 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
418 $this->assertEquals( 426 $this->assertEquals(
419 'File netscape_basic.htm (482 bytes) was successfully processed:' 427 'File netscape_basic.htm (482 bytes) was successfully processed:'
420 .' 2 links imported, 2 links overwritten, 0 links skipped.', 428 .' 2 links imported, 2 links overwritten, 0 links skipped.',
421 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache) 429 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf)
422 ); 430 );
423 $this->assertEquals(2, count($this->linkDb)); 431 $this->assertEquals(2, count($this->linkDb));
424 $this->assertEquals(0, count_private($this->linkDb)); 432 $this->assertEquals(0, count_private($this->linkDb));
@@ -444,7 +452,7 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
444 $this->assertEquals( 452 $this->assertEquals(
445 'File netscape_basic.htm (482 bytes) was successfully processed:' 453 'File netscape_basic.htm (482 bytes) was successfully processed:'
446 .' 2 links imported, 0 links overwritten, 0 links skipped.', 454 .' 2 links imported, 0 links overwritten, 0 links skipped.',
447 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache) 455 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf)
448 ); 456 );
449 $this->assertEquals(2, count($this->linkDb)); 457 $this->assertEquals(2, count($this->linkDb));
450 $this->assertEquals(0, count_private($this->linkDb)); 458 $this->assertEquals(0, count_private($this->linkDb));
@@ -465,7 +473,7 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
465 $this->assertEquals( 473 $this->assertEquals(
466 'File netscape_basic.htm (482 bytes) was successfully processed:' 474 'File netscape_basic.htm (482 bytes) was successfully processed:'
467 .' 2 links imported, 2 links overwritten, 0 links skipped.', 475 .' 2 links imported, 2 links overwritten, 0 links skipped.',
468 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache) 476 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf)
469 ); 477 );
470 $this->assertEquals(2, count($this->linkDb)); 478 $this->assertEquals(2, count($this->linkDb));
471 $this->assertEquals(2, count_private($this->linkDb)); 479 $this->assertEquals(2, count_private($this->linkDb));
@@ -489,7 +497,7 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
489 $this->assertEquals( 497 $this->assertEquals(
490 'File netscape_basic.htm (482 bytes) was successfully processed:' 498 'File netscape_basic.htm (482 bytes) was successfully processed:'
491 .' 2 links imported, 0 links overwritten, 0 links skipped.', 499 .' 2 links imported, 0 links overwritten, 0 links skipped.',
492 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache) 500 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf)
493 ); 501 );
494 $this->assertEquals(2, count($this->linkDb)); 502 $this->assertEquals(2, count($this->linkDb));
495 $this->assertEquals(0, count_private($this->linkDb)); 503 $this->assertEquals(0, count_private($this->linkDb));
@@ -499,7 +507,7 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
499 $this->assertEquals( 507 $this->assertEquals(
500 'File netscape_basic.htm (482 bytes) was successfully processed:' 508 'File netscape_basic.htm (482 bytes) was successfully processed:'
501 .' 0 links imported, 0 links overwritten, 2 links skipped.', 509 .' 0 links imported, 0 links overwritten, 2 links skipped.',
502 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache) 510 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf)
503 ); 511 );
504 $this->assertEquals(2, count($this->linkDb)); 512 $this->assertEquals(2, count($this->linkDb));
505 $this->assertEquals(0, count_private($this->linkDb)); 513 $this->assertEquals(0, count_private($this->linkDb));
@@ -518,7 +526,7 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
518 $this->assertEquals( 526 $this->assertEquals(
519 'File netscape_basic.htm (482 bytes) was successfully processed:' 527 'File netscape_basic.htm (482 bytes) was successfully processed:'
520 .' 2 links imported, 0 links overwritten, 0 links skipped.', 528 .' 2 links imported, 0 links overwritten, 0 links skipped.',
521 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache) 529 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf)
522 ); 530 );
523 $this->assertEquals(2, count($this->linkDb)); 531 $this->assertEquals(2, count($this->linkDb));
524 $this->assertEquals(0, count_private($this->linkDb)); 532 $this->assertEquals(0, count_private($this->linkDb));
@@ -545,7 +553,7 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
545 $this->assertEquals( 553 $this->assertEquals(
546 'File netscape_basic.htm (482 bytes) was successfully processed:' 554 'File netscape_basic.htm (482 bytes) was successfully processed:'
547 .' 2 links imported, 0 links overwritten, 0 links skipped.', 555 .' 2 links imported, 0 links overwritten, 0 links skipped.',
548 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache) 556 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf)
549 ); 557 );
550 $this->assertEquals(2, count($this->linkDb)); 558 $this->assertEquals(2, count($this->linkDb));
551 $this->assertEquals(0, count_private($this->linkDb)); 559 $this->assertEquals(0, count_private($this->linkDb));
@@ -570,7 +578,7 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
570 $this->assertEquals( 578 $this->assertEquals(
571 'File same_date.htm (453 bytes) was successfully processed:' 579 'File same_date.htm (453 bytes) was successfully processed:'
572 .' 3 links imported, 0 links overwritten, 0 links skipped.', 580 .' 3 links imported, 0 links overwritten, 0 links skipped.',
573 NetscapeBookmarkUtils::import(array(), $files, $this->linkDb, $this->pagecache) 581 NetscapeBookmarkUtils::import(array(), $files, $this->linkDb, $this->conf)
574 ); 582 );
575 $this->assertEquals(3, count($this->linkDb)); 583 $this->assertEquals(3, count($this->linkDb));
576 $this->assertEquals(0, count_private($this->linkDb)); 584 $this->assertEquals(0, count_private($this->linkDb));
diff --git a/tests/config/ConfigJsonTest.php b/tests/config/ConfigJsonTest.php
index 3527f83d..d237bc80 100644
--- a/tests/config/ConfigJsonTest.php
+++ b/tests/config/ConfigJsonTest.php
@@ -40,7 +40,7 @@ class ConfigJsonTest extends \PHPUnit_Framework_TestCase
40 * Read a non existent config file -> empty array. 40 * Read a non existent config file -> empty array.
41 * 41 *
42 * @expectedException \Exception 42 * @expectedException \Exception
43 * @expectedExceptionMessage An error occurred while parsing JSON file: error code #4 43 * @expectedExceptionMessageRegExp /An error occurred while parsing JSON configuration file \([\w\/\.]+\): error code #4/
44 */ 44 */
45 public function testReadInvalidJson() 45 public function testReadInvalidJson()
46 { 46 {
diff --git a/tests/utils/config/configJson.json.php b/tests/utils/config/configJson.json.php
index 13d38c66..9c9288f3 100644
--- a/tests/utils/config/configJson.json.php
+++ b/tests/utils/config/configJson.json.php
@@ -24,7 +24,7 @@
24 }, 24 },
25 "resource": { 25 "resource": {
26 "datastore": "tests\/utils\/config\/datastore.php", 26 "datastore": "tests\/utils\/config\/datastore.php",
27 "data_dir": "tests\/utils\/config", 27 "data_dir": "sandbox/",
28 "raintpl_tpl": "tpl/" 28 "raintpl_tpl": "tpl/"
29 }, 29 },
30 "plugins": { 30 "plugins": {
diff --git a/tpl/default/configure.html b/tpl/default/configure.html
index 2f54a085..d6536d47 100644
--- a/tpl/default/configure.html
+++ b/tpl/default/configure.html
@@ -55,7 +55,7 @@
55 </div> 55 </div>
56 <div class="pure-u-lg-{$ratioInput} pure-u-1"> 56 <div class="pure-u-lg-{$ratioInput} pure-u-1">
57 <div class="form-input"> 57 <div class="form-input">
58 <select name="theme" id="theme"> 58 <select name="theme" id="theme" class="align">
59 {loop="$theme_available"} 59 {loop="$theme_available"}
60 <option value="{$value}" 60 <option value="{$value}"
61 {if="$value===$theme"} 61 {if="$value===$theme"}
@@ -222,19 +222,6 @@
222</form> 222</form>
223 223
224{include="page.footer"} 224{include="page.footer"}
225
226<script>
227 (function (window, document) {
228 var toRemove = document.getElementById('timezone-remove');
229 var firstSelect = toRemove.getElementsByTagName('select')[0];
230 var secondSelect = toRemove.getElementsByTagName('select')[1];
231 toRemove.parentNode.removeChild(toRemove);
232 var toAdd = document.getElementById('timezone-add');
233 var newTimezone = '<span class="timezone-continent">Continent ' + firstSelect.outerHTML + '</span>';
234 newTimezone += ' <span class="timezone-country">Country ' + secondSelect.outerHTML + '</span>';
235 toAdd.innerHTML = newTimezone;
236 })(this, this.document);
237</script>
238</body> 225</body>
239</html> 226</html>
240 227
diff --git a/tpl/default/css/shaarli.css b/tpl/default/css/shaarli.css
index d33e9066..8fcd13af 100644
--- a/tpl/default/css/shaarli.css
+++ b/tpl/default/css/shaarli.css
@@ -832,6 +832,7 @@ pre {
832 832
833.page-form-complete .form-label label, 833.page-form-complete .form-label label,
834.page-form-complete .form-input input, 834.page-form-complete .form-input input,
835.page-form-complete .form-input select.align,
835.page-form-complete .timezone { 836.page-form-complete .timezone {
836 position: absolute; 837 position: absolute;
837 top: 50%; 838 top: 50%;
@@ -908,6 +909,10 @@ div.awesomplete > ul {
908 color: black; 909 color: black;
909} 910}
910 911
912form[name="linkform"].page-form {
913 overflow: visible;
914}
915
911@media screen and (max-width: 64em) { 916@media screen and (max-width: 64em) {
912 .page-form-complete .form-label { 917 .page-form-complete .form-label {
913 height: inherit; 918 height: inherit;
diff --git a/tpl/default/editlink.html b/tpl/default/editlink.html
index 2180c080..354499a4 100644
--- a/tpl/default/editlink.html
+++ b/tpl/default/editlink.html
@@ -4,11 +4,7 @@
4 {include="includes"} 4 {include="includes"}
5</head> 5</head>
6<body> 6<body>
7 {if="$source !== 'firefoxsocialapi' && $source !== 'bookmarklet'"} 7 {include="page.header"}
8 {include="page.header"}
9 {else}
10 <div class="center">Shaare to: {$shaarlititle}</div>
11 {/if}
12 <div id="editlinkform" class="pure-g"> 8 <div id="editlinkform" class="pure-g">
13 <div class="pure-u-lg-1-5 pure-u-1-24"></div> 9 <div class="pure-u-lg-1-5 pure-u-1-24"></div>
14 <form method="post" name="linkform" class="page-form pure-u-lg-3-5 pure-u-22-24 page-form page-form-light"> 10 <form method="post" name="linkform" class="page-form pure-u-lg-3-5 pure-u-22-24 page-form page-form-light">
@@ -21,26 +17,26 @@
21 <label for="lf_url">{'URL'|t}</label> 17 <label for="lf_url">{'URL'|t}</label>
22 </div> 18 </div>
23 <div> 19 <div>
24 <input type="text" name="lf_url" id="lf_url" value="{$link.url}" class="lf_input"> 20 <input type="text" name="lf_url" id="lf_url" value="{$link.url}" class="lf_input autofocus">
25 </div> 21 </div>
26 <div> 22 <div>
27 <label for="lf_title">{'Title'|t}</label> 23 <label for="lf_title">{'Title'|t}</label>
28 </div> 24 </div>
29 <div> 25 <div>
30 <input type="text" name="lf_title" id="lf_title" value="{$link.title}" class="lf_input"> 26 <input type="text" name="lf_title" id="lf_title" value="{$link.title}" class="lf_input autofocus">
31 </div> 27 </div>
32 <div> 28 <div>
33 <label for="lf_description">{'Description'|t}</label> 29 <label for="lf_description">{'Description'|t}</label>
34 </div> 30 </div>
35 <div> 31 <div>
36 <textarea name="lf_description" id="lf_description">{$link.description}</textarea> 32 <textarea name="lf_description" id="lf_description" class="autofocus">{$link.description}</textarea>
37 </div> 33 </div>
38 <div> 34 <div>
39 <label for="lf_tags">{'Tags'|t}</label> 35 <label for="lf_tags">{'Tags'|t}</label>
40 </div> 36 </div>
41 <div> 37 <div>
42 <input type="text" name="lf_tags" id="lf_tags" value="{$link.tags}" class="lf_input" 38 <input type="text" name="lf_tags" id="lf_tags" value="{$link.tags}" class="lf_input autofocus"
43 data-list="{loop="$tags"}{$key}, {/loop}" data-multiple autocomplete="off" > 39 data-list="{loop="$tags"}{$key}, {/loop}" data-multiple data-autofirst autocomplete="off" >
44 </div> 40 </div>
45 41
46 <div> 42 <div>
@@ -74,18 +70,6 @@
74 {/if} 70 {/if}
75 </form> 71 </form>
76 </div> 72 </div>
77 {if="$source !== 'firefoxsocialapi' && $source !== 'bookmarklet'"} 73 {include="page.footer"}
78 {include="page.footer"}
79 {/if}
80<script>
81 awesompleteUniqueTag('#lf_tags');
82 if (!document.linkform.lf_title.value) {
83 document.linkform.lf_title.focus();
84 } else if (!document.linkform.lf_description.value) {
85 document.linkform.lf_description.focus();
86 } else {
87 document.linkform.lf_tags.focus();
88 }
89</script>
90</body> 74</body>
91</html> 75</html>
diff --git a/tpl/default/install.html b/tpl/default/install.html
index 0bd8a635..33f8a453 100644
--- a/tpl/default/install.html
+++ b/tpl/default/install.html
@@ -105,18 +105,5 @@
105</div> 105</div>
106</form> 106</form>
107{include="page.footer"} 107{include="page.footer"}
108<script>
109 // FIXME!
110 (function (window, document) {
111 var toRemove = document.getElementById('timezone-remove');
112 var firstSelect = toRemove.getElementsByTagName('select')[0];
113 var secondSelect = toRemove.getElementsByTagName('select')[1];
114 toRemove.parentNode.removeChild(toRemove);
115 var toAdd = document.getElementById('timezone-add');
116 var newTimezone = '<span class="timezone-continent">Continent ' + firstSelect.outerHTML + '</span>';
117 newTimezone += ' <span class="timezone-country">Country ' + secondSelect.outerHTML + '</span>';
118 toAdd.innerHTML = newTimezone;
119 })(this, this.document);
120</script>
121</body> 108</body>
122</html> 109</html>
diff --git a/tpl/default/js/shaarli.js b/tpl/default/js/shaarli.js
index f7de0a49..30d8ed6f 100644
--- a/tpl/default/js/shaarli.js
+++ b/tpl/default/js/shaarli.js
@@ -1,3 +1,31 @@
1/** @licstart The following is the entire license notice for the
2 * JavaScript code in this page.
3 *
4 * Copyright: (c) 2011-2015 Sébastien SAUVAGE <sebsauvage@sebsauvage.net>
5 * (c) 2011-2017 The Shaarli Community, see AUTHORS
6 *
7 * This software is provided 'as-is', without any express or implied warranty.
8 * In no event will the authors be held liable for any damages arising from
9 * the use of this software.
10 *
11 * Permission is granted to anyone to use this software for any purpose,
12 * including commercial applications, and to alter it and redistribute it
13 * freely, subject to the following restrictions:
14 *
15 * 1. The origin of this software must not be misrepresented; you must not
16 * claim that you wrote the original software. If you use this software
17 * in a product, an acknowledgment in the product documentation would
18 * be appreciated but is not required.
19 *
20 * 2. Altered source versions must be plainly marked as such, and must
21 * not be misrepresented as being the original software.
22 *
23 * 3. This notice may not be removed or altered from any source distribution.
24 *
25 * @licend The above is the entire license notice
26 * for the JavaScript code in this page.
27 */
28
1window.onload = function () { 29window.onload = function () {
2 30
3 /** 31 /**
@@ -185,9 +213,13 @@ window.onload = function () {
185 /** 213 /**
186 * Autofocus text fields 214 * Autofocus text fields
187 */ 215 */
188 var autofocusElements = document.querySelector('.autofocus'); 216 // ES6 syntax
189 if (autofocusElements != null) { 217 let autofocusElements = document.querySelectorAll('.autofocus');
190 autofocusElements.focus(); 218 for (let autofocusElement of autofocusElements) {
219 if (autofocusElement.value == '') {
220 autofocusElement.focus();
221 break;
222 }
191 } 223 }
192 224
193 /** 225 /**
@@ -266,4 +298,96 @@ window.onload = function () {
266 } 298 }
267 }); 299 });
268 } 300 }
301
302 /**
303 * TimeZome select
304 * FIXME! way too hackish
305 */
306 var toRemove = document.getElementById('timezone-remove');
307 if (toRemove != null) {
308 var firstSelect = toRemove.getElementsByTagName('select')[0];
309 var secondSelect = toRemove.getElementsByTagName('select')[1];
310 toRemove.parentNode.removeChild(toRemove);
311 var toAdd = document.getElementById('timezone-add');
312 var newTimezone = '<span class="timezone-continent">Continent ' + firstSelect.outerHTML + '</span>';
313 newTimezone += ' <span class="timezone-country">Country ' + secondSelect.outerHTML + '</span>';
314 toAdd.innerHTML = newTimezone;
315 }
316
317 /**
318 * Awesomplete trigger.
319 */
320 var tags = document.getElementById('lf_tags');
321 if (tags != null) {
322 awesompleteUniqueTag('#lf_tags');
323 }
324
325 /**
326 * bLazy trigger
327 */
328 var picwall = document.getElementById('picwall_container');
329 if (picwall != null) {
330 var bLazy = new Blazy();
331 }
332
333 /**
334 * Bookmarklet alert
335 */
336 var bookmarkletLinks = document.querySelectorAll('.bookmarklet-link');
337 var bkmMessage = document.getElementById('bookmarklet-alert');
338 [].forEach.call(bookmarkletLinks, function(link) {
339 link.addEventListener('click', function(event) {
340 event.preventDefault();
341 alert(bkmMessage.value);
342 });
343 });
344
345 /**
346 * Firefox Social
347 */
348 var ffButton = document.getElementById('ff-social-button');
349 if (ffButton != null) {
350 ffButton.addEventListener('click', function(event) {
351 activateFirefoxSocial(event.target);
352 });
353 }
354
355 /**
356 * Plugin admin order
357 */
358 var orderPA = document.querySelectorAll('.order');
359 [].forEach.call(orderPA, function(link) {
360 link.addEventListener('click', function(event) {
361 event.preventDefault();
362 if (event.target.classList.contains('order-up')) {
363 return orderUp(event.target.parentNode.parentNode.getAttribute('data-order'));
364 } else if (event.target.classList.contains('order-down')) {
365 return orderDown(event.target.parentNode.parentNode.getAttribute('data-order'));
366 }
367 });
368 });
269}; 369};
370
371function activateFirefoxSocial(node) {
372 var loc = location.href;
373 var baseURL = loc.substring(0, loc.lastIndexOf("/"));
374
375 // Keeping the data separated (ie. not in the DOM) so that it's maintainable and diffable.
376 var data = {
377 name: "{$shaarlititle}",
378 description: "The personal, minimalist, super-fast, database free, bookmarking service by the Shaarli community.",
379 author: "Shaarli",
380 version: "1.0.0",
381
382 iconURL: baseURL + "/images/favicon.ico",
383 icon32URL: baseURL + "/images/favicon.ico",
384 icon64URL: baseURL + "/images/favicon.ico",
385
386 shareURL: baseURL + "{noparse}?post=%{url}&title=%{title}&description=%{text}&source=firefoxsocialapi{/noparse}",
387 homepageURL: baseURL
388 };
389 node.setAttribute("data-service", JSON.stringify(data));
390
391 var activate = new CustomEvent("ActivateSocialFeature");
392 node.dispatchEvent(activate);
393}
diff --git a/tpl/default/linklist.html b/tpl/default/linklist.html
index 94370203..57ef4567 100644
--- a/tpl/default/linklist.html
+++ b/tpl/default/linklist.html
@@ -34,7 +34,7 @@
34 {if="!empty($search_tags)"} 34 {if="!empty($search_tags)"}
35 value="{$search_tags}" 35 value="{$search_tags}"
36 {/if} 36 {/if}
37 autocomplete="off" data-multiple data-minChars="1" 37 autocomplete="off" data-multiple data-autofirst data-minChars="1"
38 data-list="{loop="$tags"}{$key}, {/loop}" 38 data-list="{loop="$tags"}{$key}, {/loop}"
39 > 39 >
40 <button type="submit" class="search-button"><i class="fa fa-search"></i></button> 40 <button type="submit" class="search-button"><i class="fa fa-search"></i></button>
diff --git a/tpl/default/loginform.html b/tpl/default/loginform.html
index 2ad3fe9c..eb6d8378 100644
--- a/tpl/default/loginform.html
+++ b/tpl/default/loginform.html
@@ -26,7 +26,7 @@
26 {if="!empty($username)"}value="{$username}"{/if} class="autofocus" tabindex="20"> 26 {if="!empty($username)"}value="{$username}"{/if} class="autofocus" tabindex="20">
27 </div> 27 </div>
28 <div> 28 <div>
29 <input type="password" name="password" placeholder="{'Password'|t}" tabindex="21"> 29 <input type="password" name="password" placeholder="{'Password'|t}" class="autofocus" tabindex="21">
30 </div> 30 </div>
31 <div class="remember-me"> 31 <div class="remember-me">
32 <input type="checkbox" name="longlastingsession" id="longlastingsessionform" 32 <input type="checkbox" name="longlastingsession" id="longlastingsessionform"
@@ -45,15 +45,6 @@
45{/if} 45{/if}
46 46
47{include="page.footer"} 47{include="page.footer"}
48<script>
49 {if="ban_canLogin($conf) && ! empty($username)"}
50 // Focus password on load if the username is set.
51 var passwords = document.getElementsByName('password');
52 if (passwords.length == 2) {
53 passwords[1].focus();
54 }
55 {/if}
56</script>
57</body> 48</body>
58</html> 49</html>
59 50
diff --git a/tpl/default/page.footer.html b/tpl/default/page.footer.html
index f7b80b68..77fc65dd 100644
--- a/tpl/default/page.footer.html
+++ b/tpl/default/page.footer.html
@@ -3,7 +3,11 @@
3<div class="pure-g"> 3<div class="pure-g">
4 <div class="pure-u-2-24"></div> 4 <div class="pure-u-2-24"></div>
5 <div id="footer" class="pure-u-20-24"> 5 <div id="footer" class="pure-u-20-24">
6 <strong><a href="https://github.com/shaarli/Shaarli">Shaarli</a></strong> &middot; 6 <strong><a href="https://github.com/shaarli/Shaarli">Shaarli</a></strong>
7 {if="isLoggedIn()===true"}
8 {$version}
9 {/if}
10 &middot;
7 The personal, minimalist, super-fast, database free, bookmarking service by the Shaarli community &middot; 11 The personal, minimalist, super-fast, database free, bookmarking service by the Shaarli community &middot;
8 <a href="doc/Home.html" rel="nofollow">Documentation</a> 12 <a href="doc/Home.html" rel="nofollow">Documentation</a>
9 {loop="$plugins_footer.text"} 13 {loop="$plugins_footer.text"}
diff --git a/tpl/default/page.header.html b/tpl/default/page.header.html
index 04f33ea2..9388ef79 100644
--- a/tpl/default/page.header.html
+++ b/tpl/default/page.header.html
@@ -2,7 +2,7 @@
2 <div class="pure-u-lg-0 pure-u-1"> 2 <div class="pure-u-lg-0 pure-u-1">
3 <div class="pure-menu"> 3 <div class="pure-menu">
4 <a href="{$titleLink}" class="pure-menu-link"> 4 <a href="{$titleLink}" class="pure-menu-link">
5 <i class="fa fa-home"></i> 5 <img src="img/icon.png" width="16" height="16" class="head-logo" alt="logo" />
6 {$shaarlititle} 6 {$shaarlititle}
7 </a> 7 </a>
8 <a href="#" class="menu-toggle" id="menu-toggle"><s class="bar"></s><s class="bar"></s></a> 8 <a href="#" class="menu-toggle" id="menu-toggle"><s class="bar"></s><s class="bar"></s></a>
@@ -114,7 +114,7 @@
114 {if="!empty($search_tags)"} 114 {if="!empty($search_tags)"}
115 value="{$search_tags}" 115 value="{$search_tags}"
116 {/if} 116 {/if}
117 autocomplete="off" data-multiple data-minChars="1" 117 autocomplete="off" data-multiple data-autofirst data-minChars="1"
118 data-list="{loop="$tags"}{$key}, {/loop}" 118 data-list="{loop="$tags"}{$key}, {/loop}"
119 > 119 >
120 <button type="submit" class="search-button"><i class="fa fa-search"></i></button> 120 <button type="submit" class="search-button"><i class="fa fa-search"></i></button>
diff --git a/tpl/default/picwall.html b/tpl/default/picwall.html
index b9ae2f2e..248e56df 100644
--- a/tpl/default/picwall.html
+++ b/tpl/default/picwall.html
@@ -40,11 +40,6 @@
40 40
41{include="page.footer"} 41{include="page.footer"}
42<script src="inc/blazy-1.3.1.min.js#"></script> 42<script src="inc/blazy-1.3.1.min.js#"></script>
43<script>
44 window.onload = function() {
45 var bLazy = new Blazy();
46 }
47</script>
48</body> 43</body>
49</html> 44</html>
50 45
diff --git a/tpl/default/pluginsadmin.html b/tpl/default/pluginsadmin.html
index 92af2eef..5cc1802f 100644
--- a/tpl/default/pluginsadmin.html
+++ b/tpl/default/pluginsadmin.html
@@ -48,14 +48,8 @@
48 <td><div class="pure-u-0 pure-u-lg-visible"><label for="{$key}">{$value.description}</label></div></td> 48 <td><div class="pure-u-0 pure-u-lg-visible"><label for="{$key}">{$value.description}</label></div></td>
49 <td class="center"> 49 <td class="center">
50 {if="count($enabledPlugins)>1"} 50 {if="count($enabledPlugins)>1"}
51 <a href="#" class="order" 51 <a href="#" class="order order-up">▲</a>
52 onclick="return orderUp(this.parentNode.parentNode.getAttribute('data-order'));"> 52 <a href="#" class="order order-down">▼</a>
53
54 </a>
55 <a href="#" class="order"
56 onclick="return orderDown(this.parentNode.parentNode.getAttribute('data-order'));">
57
58 </a>
59 {/if} 53 {/if}
60 <input type="hidden" name="order_{$key}" value="{$counter}"> 54 <input type="hidden" name="order_{$key}" value="{$counter}">
61 </td> 55 </td>
diff --git a/tpl/default/tools.html b/tpl/default/tools.html
index b9df32d9..baa033af 100644
--- a/tpl/default/tools.html
+++ b/tpl/default/tools.html
@@ -67,7 +67,7 @@
67 <div class="tools-item"> 67 <div class="tools-item">
68 <a title="{'Drag this link to your bookmarks toolbar or right-click it and Bookmark This Link'|t}, 68 <a title="{'Drag this link to your bookmarks toolbar or right-click it and Bookmark This Link'|t},
69 {'then click ✚Shaare link button in any page you want to share'|t}" 69 {'then click ✚Shaare link button in any page you want to share'|t}"
70 onclick="return alertBookmarklet();" 70 class="bookmarklet-link"
71 href="javascript:( 71 href="javascript:(
72 function(){ 72 function(){
73 var%20url%20=%20location.href; 73 var%20url%20=%20location.href;
@@ -86,8 +86,8 @@
86 <div class="tools-item"> 86 <div class="tools-item">
87 <a title="{'Drag this link to your bookmarks toolbar or right-click it and Bookmark This Link'|t}, 87 <a title="{'Drag this link to your bookmarks toolbar or right-click it and Bookmark This Link'|t},
88 {'Then click ✚Add Note button anytime to start composing a private Note (text post) to your Shaarli'|t}" 88 {'Then click ✚Add Note button anytime to start composing a private Note (text post) to your Shaarli'|t}"
89 onclick="return alertBookmarklet();" 89 href="?private=1&amp;post="
90 href="?private=1&amp;post="> 90 class="bookmarklet-link">
91 <span class="pure-button pure-u-lg-2-3 pure-u-3-4">✚ {'Add Note'|t}</span> 91 <span class="pure-button pure-u-lg-2-3 pure-u-3-4">✚ {'Add Note'|t}</span>
92 </a> 92 </a>
93 </div> 93 </div>
@@ -103,7 +103,7 @@
103 103
104 <div class="tools-item"> 104 <div class="tools-item">
105 <a title="{'Click on this button to add Shaarli to the 'Share this page' button in Firefox" 105 <a title="{'Click on this button to add Shaarli to the 'Share this page' button in Firefox"
106 onclick="activateFirefoxSocial(this)"> 106 id="ff-social-button">
107 <span class="pure-button pure-u-lg-2-3 pure-u-3-4">✚ {'Add to'|t} Firefox Social</span> 107 <span class="pure-button pure-u-lg-2-3 pure-u-3-4">✚ {'Add to'|t} Firefox Social</span>
108 </a> 108 </a>
109 </div> 109 </div>
@@ -142,38 +142,8 @@
142</div> 142</div>
143 143
144{include="page.footer"} 144{include="page.footer"}
145 145<input type="hidden" id="bookmarklet-alert"
146<script> 146 value="{'Drag this link to your bookmarks toolbar, or right-click it and choose Bookmark This Link'|t}">
147 {if="$sslenabled"}
148 function activateFirefoxSocial(node) {
149 var loc = location.href;
150 var baseURL = loc.substring(0, loc.lastIndexOf("/"));
151
152 // Keeping the data separated (ie. not in the DOM) so that it's maintainable and diffable.
153 var data = {
154 name: "{$shaarlititle}",
155 description: "The personal, minimalist, super-fast, database free, bookmarking service by the Shaarli community.",
156 author: "Shaarli",
157 version: "1.0.0",
158
159 iconURL: baseURL + "/images/favicon.ico",
160 icon32URL: baseURL + "/images/favicon.ico",
161 icon64URL: baseURL + "/images/favicon.ico",
162
163 shareURL: baseURL + "{noparse}?post=%{url}&title=%{title}&description=%{text}&source=firefoxsocialapi{/noparse}",
164 homepageURL: baseURL
165 };
166 node.setAttribute("data-service", JSON.stringify(data));
167
168 var activate = new CustomEvent("ActivateSocialFeature");
169 node.dispatchEvent(activate);
170 }
171 {/if}
172 function alertBookmarklet() {
173 alert({"'Drag this link to your bookmarks toolbar, or right-click it and choose Bookmark This Link'"|t});
174 return false;
175 }
176</script>
177</body> 147</body>
178</html> 148</html>
179 149