aboutsummaryrefslogtreecommitdiffhomepage
path: root/assets/default
diff options
context:
space:
mode:
authorArthurHoaro <arthur@hoa.ro>2018-02-24 18:18:33 +0100
committerArthurHoaro <arthur@hoa.ro>2018-03-28 19:01:17 +0200
commitb3375c7f86f35fce723185bb76d3b5f9c4ff7a07 (patch)
tree9add15148b2efbfa6dc25a883769f33da60f70a5 /assets/default
parent9b2bd66fb60ffd5a833480bf329062c7d57bc8c4 (diff)
downloadShaarli-b3375c7f86f35fce723185bb76d3b5f9c4ff7a07.tar.gz
Shaarli-b3375c7f86f35fce723185bb76d3b5f9c4ff7a07.tar.zst
Shaarli-b3375c7f86f35fce723185bb76d3b5f9c4ff7a07.zip
Webpack / Remove frontend dependencies from tpl/ & inc/ and move them to assets/
Diffstat (limited to 'assets/default')
-rw-r--r--assets/default/fonts/Roboto-Bold.woffbin0 -> 89584 bytes
-rw-r--r--assets/default/fonts/Roboto-Bold.woff2bin0 -> 63320 bytes
-rw-r--r--assets/default/fonts/Roboto-Regular.woffbin0 -> 89732 bytes
-rw-r--r--assets/default/fonts/Roboto-Regular.woff2bin0 -> 63412 bytes
-rw-r--r--assets/default/img/apple-touch-icon.pngbin0 -> 18276 bytes
-rw-r--r--assets/default/img/favicon.pngbin0 -> 41600 bytes
-rw-r--r--assets/default/img/icon.pngbin0 -> 530 bytes
-rw-r--r--assets/default/img/sad_star.pngbin0 -> 7099 bytes
-rw-r--r--assets/default/js/base.js664
-rw-r--r--assets/default/js/plugins-admin.js103
-rw-r--r--assets/default/scss/shaarli.scss1353
11 files changed, 2120 insertions, 0 deletions
diff --git a/assets/default/fonts/Roboto-Bold.woff b/assets/default/fonts/Roboto-Bold.woff
new file mode 100644
index 00000000..3d86753b
--- /dev/null
+++ b/assets/default/fonts/Roboto-Bold.woff
Binary files differ
diff --git a/assets/default/fonts/Roboto-Bold.woff2 b/assets/default/fonts/Roboto-Bold.woff2
new file mode 100644
index 00000000..bd05e2ea
--- /dev/null
+++ b/assets/default/fonts/Roboto-Bold.woff2
Binary files differ
diff --git a/assets/default/fonts/Roboto-Regular.woff b/assets/default/fonts/Roboto-Regular.woff
new file mode 100644
index 00000000..464d2062
--- /dev/null
+++ b/assets/default/fonts/Roboto-Regular.woff
Binary files differ
diff --git a/assets/default/fonts/Roboto-Regular.woff2 b/assets/default/fonts/Roboto-Regular.woff2
new file mode 100644
index 00000000..f9661967
--- /dev/null
+++ b/assets/default/fonts/Roboto-Regular.woff2
Binary files differ
diff --git a/assets/default/img/apple-touch-icon.png b/assets/default/img/apple-touch-icon.png
new file mode 100644
index 00000000..f29210ce
--- /dev/null
+++ b/assets/default/img/apple-touch-icon.png
Binary files differ
diff --git a/assets/default/img/favicon.png b/assets/default/img/favicon.png
new file mode 100644
index 00000000..4644321b
--- /dev/null
+++ b/assets/default/img/favicon.png
Binary files differ
diff --git a/assets/default/img/icon.png b/assets/default/img/icon.png
new file mode 100644
index 00000000..474edec3
--- /dev/null
+++ b/assets/default/img/icon.png
Binary files differ
diff --git a/assets/default/img/sad_star.png b/assets/default/img/sad_star.png
new file mode 100644
index 00000000..ed3bd158
--- /dev/null
+++ b/assets/default/img/sad_star.png
Binary files differ
diff --git a/assets/default/js/base.js b/assets/default/js/base.js
new file mode 100644
index 00000000..cf628e87
--- /dev/null
+++ b/assets/default/js/base.js
@@ -0,0 +1,664 @@
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
29window.onload = function () {
30
31 /**
32 * Retrieve an element up in the tree from its class name.
33 */
34 function getParentByClass(el, className) {
35 var p = el.parentNode;
36 if (p == null || p.classList.contains(className)) {
37 return p;
38 }
39 return getParentByClass(p, className);
40 }
41
42
43 /**
44 * Handle responsive menu.
45 * Source: http://purecss.io/layouts/tucked-menu-vertical/
46 */
47 (function (window, document) {
48 var menu = document.getElementById('shaarli-menu'),
49 WINDOW_CHANGE_EVENT = ('onorientationchange' in window) ? 'orientationchange':'resize';
50
51 function toggleHorizontal() {
52 [].forEach.call(
53 document.getElementById('shaarli-menu').querySelectorAll('.menu-transform'),
54 function(el){
55 el.classList.toggle('pure-menu-horizontal');
56 }
57 );
58 };
59
60 function toggleMenu() {
61 // set timeout so that the panel has a chance to roll up
62 // before the menu switches states
63 if (menu.classList.contains('open')) {
64 setTimeout(toggleHorizontal, 500);
65 }
66 else {
67 toggleHorizontal();
68 }
69 menu.classList.toggle('open');
70 document.getElementById('menu-toggle').classList.toggle('x');
71 };
72
73 function closeMenu() {
74 if (menu.classList.contains('open')) {
75 toggleMenu();
76 }
77 }
78
79 var menuToggle = document.getElementById('menu-toggle');
80 if (menuToggle != null) {
81 menuToggle.addEventListener('click', function (e) {
82 toggleMenu();
83 });
84 }
85
86 window.addEventListener(WINDOW_CHANGE_EVENT, closeMenu);
87 })(this, this.document);
88
89 /**
90 * Fold/Expand shaares description and thumbnail.
91 */
92 var foldAllButtons = document.getElementsByClassName('fold-all');
93 var foldButtons = document.getElementsByClassName('fold-button');
94
95 [].forEach.call(foldButtons, function (foldButton) {
96 // Retrieve description
97 var description = null;
98 var thumbnail = null;
99 var linklistItem = getParentByClass(foldButton, 'linklist-item');
100 if (linklistItem != null) {
101 description = linklistItem.querySelector('.linklist-item-description');
102 thumbnail = linklistItem.querySelector('.linklist-item-thumbnail');
103 if (description != null || thumbnail != null) {
104 foldButton.style.display = 'inline';
105 }
106 }
107
108 foldButton.addEventListener('click', function (event) {
109 event.preventDefault();
110 toggleFold(event.target, description, thumbnail);
111 });
112 });
113
114 if (foldAllButtons != null) {
115 [].forEach.call(foldAllButtons, function (foldAllButton) {
116 foldAllButton.addEventListener('click', function (event) {
117 event.preventDefault();
118 var state = foldAllButton.firstElementChild.getAttribute('class').indexOf('down') != -1 ? 'down' : 'up';
119 [].forEach.call(foldButtons, function (foldButton) {
120 if (foldButton.firstElementChild.classList.contains('fa-chevron-up') && state == 'down'
121 || foldButton.firstElementChild.classList.contains('fa-chevron-down') && state == 'up'
122 ) {
123 return;
124 }
125 // Retrieve description
126 var description = null;
127 var thumbnail = null;
128 var linklistItem = getParentByClass(foldButton, 'linklist-item');
129 if (linklistItem != null) {
130 description = linklistItem.querySelector('.linklist-item-description');
131 thumbnail = linklistItem.querySelector('.linklist-item-thumbnail');
132 if (description != null || thumbnail != null) {
133 foldButton.style.display = 'inline';
134 }
135 }
136
137 toggleFold(foldButton.firstElementChild, description, thumbnail);
138 });
139 foldAllButton.firstElementChild.classList.toggle('fa-chevron-down');
140 foldAllButton.firstElementChild.classList.toggle('fa-chevron-up');
141 foldAllButton.title = state === 'down'
142 ? document.getElementById('translation-fold-all').innerHTML
143 : document.getElementById('translation-expand-all').innerHTML
144 });
145 });
146 }
147
148 function toggleFold(button, description, thumb)
149 {
150 // Switch fold/expand - up = fold
151 if (button.classList.contains('fa-chevron-up')) {
152 button.title = document.getElementById('translation-expand').innerHTML;
153 if (description != null) {
154 description.style.display = 'none';
155 }
156 if (thumb != null) {
157 thumb.style.display = 'none';
158 }
159 }
160 else {
161 button.title = document.getElementById('translation-fold').innerHTML;
162 if (description != null) {
163 description.style.display = 'block';
164 }
165 if (thumb != null) {
166 thumb.style.display = 'block';
167 }
168 }
169 button.classList.toggle('fa-chevron-down');
170 button.classList.toggle('fa-chevron-up');
171 }
172
173 /**
174 * Confirmation message before deletion.
175 */
176 var deleteLinks = document.querySelectorAll('.confirm-delete');
177 [].forEach.call(deleteLinks, function(deleteLink) {
178 deleteLink.addEventListener('click', function(event) {
179 if(! confirm(document.getElementById('translation-delete-link').innerHTML)) {
180 event.preventDefault();
181 }
182 });
183 });
184
185 /**
186 * Close alerts
187 */
188 var closeLinks = document.querySelectorAll('.pure-alert-close');
189 [].forEach.call(closeLinks, function(closeLink) {
190 closeLink.addEventListener('click', function(event) {
191 var alert = getParentByClass(event.target, 'pure-alert-closable');
192 alert.style.display = 'none';
193 });
194 });
195
196 /**
197 * New version dismiss.
198 * Hide the message for one week using localStorage.
199 */
200 var newVersionDismiss = document.getElementById('new-version-dismiss');
201 var newVersionMessage = document.querySelector('.new-version-message');
202 if (newVersionMessage != null
203 && localStorage.getItem('newVersionDismiss') != null
204 && parseInt(localStorage.getItem('newVersionDismiss')) + 7*24*60*60*1000 > (new Date()).getTime()
205 ) {
206 newVersionMessage.style.display = 'none';
207 }
208 if (newVersionDismiss != null) {
209 newVersionDismiss.addEventListener('click', function () {
210 localStorage.setItem('newVersionDismiss', (new Date()).getTime());
211 });
212 }
213
214 var hiddenReturnurl = document.getElementsByName('returnurl');
215 if (hiddenReturnurl != null) {
216 hiddenReturnurl.value = window.location.href;
217 }
218
219 /**
220 * Autofocus text fields
221 */
222 var autofocusElements = document.querySelectorAll('.autofocus');
223 var breakLoop = false;
224 [].forEach.call(autofocusElements, function(autofocusElement) {
225 if (autofocusElement.value == '' && ! breakLoop) {
226 autofocusElement.focus();
227 breakLoop = true;
228 }
229 });
230
231 /**
232 * Handle sub menus/forms
233 */
234 var openers = document.getElementsByClassName('subheader-opener');
235 if (openers != null) {
236 [].forEach.call(openers, function(opener) {
237 opener.addEventListener('click', function(event) {
238 event.preventDefault();
239
240 var id = opener.getAttribute('data-open-id');
241 var sub = document.getElementById(id);
242
243 if (sub != null) {
244 [].forEach.call(document.getElementsByClassName('subheader-form'), function (element) {
245 if (element != sub) {
246 removeClass(element, 'open')
247 }
248 });
249
250 sub.classList.toggle('open');
251 }
252 });
253 });
254 }
255
256 function removeClass(element, classname) {
257 element.className = element.className.replace(new RegExp('(?:^|\\s)'+ classname + '(?:\\s|$)'), ' ');
258 }
259
260 /**
261 * Remove CSS target padding (for fixed bar)
262 */
263 if (location.hash != '') {
264 var anchor = document.getElementById(location.hash.substr(1));
265 if (anchor != null) {
266 var padsize = anchor.clientHeight;
267 this.window.scroll(0, this.window.scrollY - padsize);
268 anchor.style.paddingTop = 0;
269 }
270 }
271
272 /**
273 * Text area resizer
274 */
275 var description = document.getElementById('lf_description');
276 var observe = function (element, event, handler) {
277 element.addEventListener(event, handler, false);
278 };
279 function init () {
280 function resize () {
281 /* Fix jumpy resizing: https://stackoverflow.com/a/18262927/1484919 */
282 var scrollTop = window.pageYOffset ||
283 (document.documentElement || document.body.parentNode || document.body).scrollTop;
284
285 description.style.height = 'auto';
286 description.style.height = description.scrollHeight+10+'px';
287
288 window.scrollTo(0, scrollTop);
289 }
290 /* 0-timeout to get the already changed text */
291 function delayedResize () {
292 window.setTimeout(resize, 0);
293 }
294 observe(description, 'change', resize);
295 observe(description, 'cut', delayedResize);
296 observe(description, 'paste', delayedResize);
297 observe(description, 'drop', delayedResize);
298 observe(description, 'keydown', delayedResize);
299
300 resize();
301 }
302
303 if (description != null) {
304 init();
305 // Submit editlink form with CTRL + Enter in the text area.
306 description.addEventListener('keydown', function (event) {
307 if (event.ctrlKey && event.keyCode === 13) {
308 document.getElementById('button-save-edit').click();
309 }
310 });
311 }
312
313 /**
314 * Awesomplete trigger.
315 */
316 var tags = document.getElementById('lf_tags');
317 if (tags != null) {
318 awesompleteUniqueTag('#lf_tags');
319 }
320
321 /**
322 * bLazy trigger
323 */
324 var picwall = document.getElementById('picwall_container');
325 if (picwall != null) {
326 var bLazy = new Blazy();
327 }
328
329 /**
330 * Bookmarklet alert
331 */
332 var bookmarkletLinks = document.querySelectorAll('.bookmarklet-link');
333 var bkmMessage = document.getElementById('bookmarklet-alert');
334 [].forEach.call(bookmarkletLinks, function(link) {
335 link.addEventListener('click', function(event) {
336 event.preventDefault();
337 alert(bkmMessage.value);
338 });
339 });
340
341 /**
342 * Firefox Social
343 */
344 var ffButton = document.getElementById('ff-social-button');
345 if (ffButton != null) {
346 ffButton.addEventListener('click', function(event) {
347 activateFirefoxSocial(event.target);
348 });
349 }
350
351 /**
352 * Plugin admin order
353 */
354 var orderPA = document.querySelectorAll('.order');
355 [].forEach.call(orderPA, function(link) {
356 link.addEventListener('click', function(event) {
357 event.preventDefault();
358 if (event.target.classList.contains('order-up')) {
359 return orderUp(event.target.parentNode.parentNode.getAttribute('data-order'));
360 } else if (event.target.classList.contains('order-down')) {
361 return orderDown(event.target.parentNode.parentNode.getAttribute('data-order'));
362 }
363 });
364 });
365
366 var continent = document.getElementById('continent');
367 var city = document.getElementById('city');
368 if (continent != null && city != null) {
369 continent.addEventListener('change', function (event) {
370 hideTimezoneCities(city, continent.options[continent.selectedIndex].value, true);
371 });
372 hideTimezoneCities(city, continent.options[continent.selectedIndex].value, false);
373 }
374
375 /**
376 * Bulk actions
377 */
378 var linkCheckboxes = document.querySelectorAll('.delete-checkbox');
379 var bar = document.getElementById('actions');
380 [].forEach.call(linkCheckboxes, function(checkbox) {
381 checkbox.style.display = 'inline-block';
382 checkbox.addEventListener('click', function(event) {
383 var count = 0;
384 var linkCheckedCheckboxes = document.querySelectorAll('.delete-checkbox:checked');
385 [].forEach.call(linkCheckedCheckboxes, function(checkbox) {
386 count++;
387 });
388 if (count == 0 && bar.classList.contains('open')) {
389 bar.classList.toggle('open');
390 } else if (count > 0 && ! bar.classList.contains('open')) {
391 bar.classList.toggle('open');
392 }
393 });
394 });
395
396 var deleteButton = document.getElementById('actions-delete');
397 var token = document.querySelector('input[type="hidden"][name="token"]');
398 if (deleteButton != null && token != null) {
399 deleteButton.addEventListener('click', function(event) {
400 event.preventDefault();
401
402 var links = [];
403 var linkCheckedCheckboxes = document.querySelectorAll('.delete-checkbox:checked');
404 [].forEach.call(linkCheckedCheckboxes, function(checkbox) {
405 links.push({
406 'id': checkbox.value,
407 'title': document.querySelector('.linklist-item[data-id="'+ checkbox.value +'"] .linklist-link').innerHTML
408 });
409 });
410
411 var message = 'Are you sure you want to delete '+ links.length +' links?\n';
412 message += 'This action is IRREVERSIBLE!\n\nTitles:\n';
413 var ids = [];
414 links.forEach(function(item) {
415 message += ' - '+ item['title'] +'\n';
416 ids.push(item['id']);
417 });
418
419 if (window.confirm(message)) {
420 window.location = '?delete_link&lf_linkdate='+ ids.join('+') +'&token='+ token.value;
421 }
422 });
423 }
424
425 /**
426 * Tag list operations
427 *
428 * TODO: support error code in the backend for AJAX requests
429 */
430 var tagList = document.querySelector('input[name="taglist"]');
431 var existingTags = tagList ? tagList.value.split(' ') : [];
432 var awesomepletes = [];
433
434 // Display/Hide rename form
435 var renameTagButtons = document.querySelectorAll('.rename-tag');
436 [].forEach.call(renameTagButtons, function(rename) {
437 rename.addEventListener('click', function(event) {
438 event.preventDefault();
439 var block = findParent(event.target, 'div', {'class': 'tag-list-item'});
440 var form = block.querySelector('.rename-tag-form');
441 if (form.style.display == 'none' || form.style.display == '') {
442 form.style.display = 'block';
443 } else {
444 form.style.display = 'none';
445 }
446 block.querySelector('input').focus();
447 });
448 });
449
450 // Rename a tag with an AJAX request
451 var renameTagSubmits = document.querySelectorAll('.validate-rename-tag');
452 [].forEach.call(renameTagSubmits, function(rename) {
453 rename.addEventListener('click', function(event) {
454 event.preventDefault();
455 var block = findParent(event.target, 'div', {'class': 'tag-list-item'});
456 var input = block.querySelector('.rename-tag-input');
457 var totag = input.value.replace('/"/g', '\\"');
458 if (totag.trim() == '') {
459 return;
460 }
461 var fromtag = block.getAttribute('data-tag');
462 var token = document.getElementById('token').value;
463
464 xhr = new XMLHttpRequest();
465 xhr.open('POST', '?do=changetag');
466 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
467 xhr.onload = function() {
468 if (xhr.status !== 200) {
469 alert('An error occurred. Return code: '+ xhr.status);
470 location.reload();
471 } else {
472 block.setAttribute('data-tag', totag);
473 input.setAttribute('name', totag);
474 input.setAttribute('value', totag);
475 findParent(input, 'div', {'class': 'rename-tag-form'}).style.display = 'none';
476 block.querySelector('a.tag-link').innerHTML = htmlEntities(totag);
477 block.querySelector('a.tag-link').setAttribute('href', '?searchtags='+ encodeURIComponent(totag));
478 block.querySelector('a.rename-tag').setAttribute('href', '?do=changetag&fromtag='+ encodeURIComponent(totag));
479
480 // Refresh awesomplete values
481 for (var key in existingTags) {
482 if (existingTags[key] == fromtag) {
483 existingTags[key] = totag;
484 }
485 }
486 awesomepletes = updateAwesompleteList('.rename-tag-input', existingTags, awesomepletes);
487 }
488 };
489 xhr.send('renametag=1&fromtag='+ encodeURIComponent(fromtag) +'&totag='+ encodeURIComponent(totag) +'&token='+ token);
490 refreshToken();
491 });
492 });
493
494 // Validate input with enter key
495 var renameTagInputs = document.querySelectorAll('.rename-tag-input');
496 [].forEach.call(renameTagInputs, function(rename) {
497
498 rename.addEventListener('keypress', function(event) {
499 if (event.keyCode === 13) { // enter
500 findParent(event.target, 'div', {'class': 'tag-list-item'}).querySelector('.validate-rename-tag').click();
501 }
502 });
503 });
504
505 // Delete a tag with an AJAX query (alert popup confirmation)
506 var deleteTagButtons = document.querySelectorAll('.delete-tag');
507 [].forEach.call(deleteTagButtons, function(rename) {
508 rename.style.display = 'inline';
509 rename.addEventListener('click', function(event) {
510 event.preventDefault();
511 var block = findParent(event.target, 'div', {'class': 'tag-list-item'});
512 var tag = block.getAttribute('data-tag');
513 var token = document.getElementById('token').value;
514
515 if (confirm('Are you sure you want to delete the tag "'+ tag +'"?')) {
516 xhr = new XMLHttpRequest();
517 xhr.open('POST', '?do=changetag');
518 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
519 xhr.onload = function() {
520 block.remove();
521 };
522 xhr.send(encodeURI('deletetag=1&fromtag='+ tag +'&token='+ token));
523 refreshToken();
524 }
525 });
526 });
527
528 updateAwesompleteList('.rename-tag-input', existingTags, awesomepletes);
529};
530
531/**
532 * Find a parent element according to its tag and its attributes
533 *
534 * @param element Element where to start the search
535 * @param tagName Expected parent tag name
536 * @param attributes Associative array of expected attributes (name=>value).
537 *
538 * @returns Found element or null.
539 */
540function findParent(element, tagName, attributes)
541{
542 while (element) {
543 if (element.tagName.toLowerCase() == tagName) {
544 var match = true;
545 for (var key in attributes) {
546 if (! element.hasAttribute(key)
547 || (attributes[key] != '' && element.getAttribute(key).indexOf(attributes[key]) == -1)
548 ) {
549 match = false;
550 break;
551 }
552 }
553
554 if (match) {
555 return element;
556 }
557 }
558 element = element.parentElement;
559 }
560 return null;
561}
562
563/**
564 * Ajax request to refresh the CSRF token.
565 */
566function refreshToken()
567{
568 var xhr = new XMLHttpRequest();
569 xhr.open('GET', '?do=token');
570 xhr.onload = function() {
571 var token = document.getElementById('token');
572 token.setAttribute('value', xhr.responseText);
573 };
574 xhr.send();
575}
576
577/**
578 * Update awesomplete list of tag for all elements matching the given selector
579 *
580 * @param selector CSS selector
581 * @param tags Array of tags
582 * @param instances List of existing awesomplete instances
583 */
584function updateAwesompleteList(selector, tags, instances)
585{
586 // First load: create Awesomplete instances
587 if (instances.length == 0) {
588 var elements = document.querySelectorAll(selector);
589 [].forEach.call(elements, function (element) {
590 instances.push(new Awesomplete(
591 element,
592 {'list': tags}
593 ));
594 });
595 } else {
596 // Update awesomplete tag list
597 for (var key in instances) {
598 instances[key].list = tags;
599 }
600 }
601 return instances;
602}
603
604/**
605 * html_entities in JS
606 *
607 * @see http://stackoverflow.com/questions/18749591/encode-html-entities-in-javascript
608 */
609function htmlEntities(str)
610{
611 return str.replace(/[\u00A0-\u9999<>\&]/gim, function(i) {
612 return '&#'+i.charCodeAt(0)+';';
613 });
614}
615
616function activateFirefoxSocial(node) {
617 var loc = location.href;
618 var baseURL = loc.substring(0, loc.lastIndexOf("/") + 1);
619 var title = document.title;
620
621 // Keeping the data separated (ie. not in the DOM) so that it's maintainable and diffable.
622 var data = {
623 name: title,
624 description: document.getElementById('translation-delete-link').innerHTML,
625 author: "Shaarli",
626 version: "1.0.0",
627
628 iconURL: baseURL + "/images/favicon.ico",
629 icon32URL: baseURL + "/images/favicon.ico",
630 icon64URL: baseURL + "/images/favicon.ico",
631
632 shareURL: baseURL + "?post=%{url}&title=%{title}&description=%{text}&source=firefoxsocialapi",
633 homepageURL: baseURL
634 };
635 node.setAttribute("data-service", JSON.stringify(data));
636
637 var activate = new CustomEvent("ActivateSocialFeature");
638 node.dispatchEvent(activate);
639}
640
641/**
642 * Add the class 'hidden' to city options not attached to the current selected continent.
643 *
644 * @param cities List of <option> elements
645 * @param currentContinent Current selected continent
646 * @param reset Set to true to reset the selected value
647 */
648function hideTimezoneCities(cities, currentContinent) {
649 var first = true;
650 if (reset == null) {
651 reset = false;
652 }
653 [].forEach.call(cities, function (option) {
654 if (option.getAttribute('data-continent') != currentContinent) {
655 option.className = 'hidden';
656 } else {
657 option.className = '';
658 if (reset === true && first === true) {
659 option.setAttribute('selected', 'selected');
660 first = false;
661 }
662 }
663 });
664}
diff --git a/assets/default/js/plugins-admin.js b/assets/default/js/plugins-admin.js
new file mode 100644
index 00000000..4b55e0f3
--- /dev/null
+++ b/assets/default/js/plugins-admin.js
@@ -0,0 +1,103 @@
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
29/**
30 * Change the position counter of a row.
31 *
32 * @param elem Element Node to change.
33 * @param toPos int New position.
34 */
35function changePos(elem, toPos)
36{
37 var elemName = elem.getAttribute('data-line')
38
39 elem.setAttribute('data-order', toPos);
40 var hiddenInput = document.querySelector('[name="order_'+ elemName +'"]');
41 hiddenInput.setAttribute('value', toPos);
42}
43
44/**
45 * Move a row up or down.
46 *
47 * @param pos Element Node to move.
48 * @param move int Move: +1 (down) or -1 (up)
49 */
50function changeOrder(pos, move)
51{
52 var newpos = parseInt(pos) + move;
53 var lines = document.querySelectorAll('[data-order="'+ pos +'"]');
54 var changelines = document.querySelectorAll('[data-order="'+ newpos +'"]');
55
56 // If we go down reverse lines to preserve the rows order
57 if (move > 0) {
58 lines = [].slice.call(lines).reverse();
59 }
60
61 for (var i = 0 ; i < lines.length ; i++) {
62 var parent = changelines[0].parentNode;
63 changePos(lines[i], newpos);
64 changePos(changelines[i], parseInt(pos));
65 var changeItem = move < 0 ? changelines[0] : changelines[changelines.length - 1].nextSibling;
66 parent.insertBefore(lines[i], changeItem);
67 }
68
69}
70
71/**
72 * Move a row up in the table.
73 *
74 * @param pos int row counter.
75 *
76 * @returns false
77 */
78function orderUp(pos)
79{
80 if (pos == 0) {
81 return false;
82 }
83 changeOrder(pos, -1);
84 return false;
85}
86
87/**
88 * Move a row down in the table.
89 *
90 * @param pos int row counter.
91 *
92 * @returns false
93 */
94function orderDown(pos)
95{
96 var lastpos = document.querySelector('[data-order]:last-child').getAttribute('data-order');
97 if (pos == lastpos) {
98 return false;
99 }
100
101 changeOrder(pos, +1);
102 return false;
103}
diff --git a/assets/default/scss/shaarli.scss b/assets/default/scss/shaarli.scss
new file mode 100644
index 00000000..1e07a88e
--- /dev/null
+++ b/assets/default/scss/shaarli.scss
@@ -0,0 +1,1353 @@
1/**
2 * General
3 */
4body {
5 background: #d0d0d0;
6}
7
8.strong {
9 font-weight: bold;
10}
11
12.clear {
13 clear: both;
14}
15
16.center {
17 text-align: center;
18 margin: auto;
19}
20
21.label {
22 display: inline-block;
23 padding: .25em .4em;
24 font-size: 75%;
25 font-weight: 700;
26 line-height: 1;
27 text-align: center;
28 white-space: nowrap;
29 vertical-align: baseline;
30 border-radius: .25rem;
31}
32
33pre {
34 max-width: 100%;
35}
36
37@font-face {
38 font-family: 'Roboto';
39 font-weight: 400;
40 font-style: normal;
41 src:
42 local('Roboto'),
43 local('Roboto-Regular'),
44 url('../fonts/Roboto-Regular.woff2') format('woff2'),
45 url('../fonts/Roboto-Regular.woff') format('woff');
46}
47
48@font-face {
49 font-family: 'Roboto';
50 font-weight: 700;
51 font-style: normal;
52 src:
53 local('Roboto'),
54 local('Roboto-Bold'),
55 url('../fonts/Roboto-Bold.woff2') format('woff2'),
56 url('../fonts/Roboto-Bold.woff') format('woff');
57}
58
59body, .pure-g [class*="pure-u"] {
60 font-family: Roboto, Arial, sans-serif;
61}
62
63/**
64 * Extends Pure grids responsive to hide items.
65 * Use xx-0 to hide an item on xx screen.
66 * Display it at any level with xx-visible.
67 */
68.pure-u-0 { display: none !important; }
69@media screen and (min-width: 35.5em) {
70 .pure-u-sm-0 { display: none !important; }
71 .pure-u-sm-visible { display: inline-block !important; }
72}
73@media screen and (min-width: 48em) {
74 .pure-u-md-0 { display: none !important; }
75 .pure-u-md-visible { display: inline-block !important; }
76}
77@media screen and (min-width: 64em) {
78 .pure-u-lg-0 { display: none !important; }
79 .pure-u-lg-visible { display: inline-block !important; }
80}
81@media screen and (min-width: 80em) {
82 .pure-u-xl-0 { display: none !important; }
83 .pure-u-xl-visible { display: inline-block !important; }
84}
85
86/**
87 * Make pure-extras alert closable.
88 */
89.pure-alert-closable .fa-times {
90 float: right;
91}
92.pure-alert-close {
93 cursor: pointer;
94}
95
96.pure-alert-success {
97 background-color: #1b926c;
98}
99
100.anchor:target {
101 padding-top: 40px;
102}
103/**
104 * MENU
105 **/
106.shaarli-menu {
107 position: fixed;
108 top: 0;
109 width: 100%;
110 --height: 50px;
111 background: #1b926c;
112 -webkit-font-smoothing: antialiased;
113 /* Hack to transition with auto height: http://stackoverflow.com/a/8331169/1484919 */
114 max-height: 45px;
115 transition: max-height 0.5s;
116 overflow: hidden;
117 z-index: 999;
118}
119
120/* Chrome bugfix: with 100% height, it only displays the first element. */
121.pure-menu-item {
122 height: 45px;
123}
124
125.shaarli-menu.open {
126 max-height: 500px;
127 transition: max-height 0.75s;
128}
129
130.head-logo {
131 float: left;
132 margin: 0 5px 0 0;
133}
134
135.pure-menu-link,
136.pure-menu-link:visited,
137.pure-menu-selected .pure-menu-link,
138.pure-menu-selected .pure-menu-link:visited {
139 padding: 0.8em 1em;
140 color: #f5f5f5;
141}
142
143.pure-menu-link:hover, .pure-menu-link:focus,
144.pure-menu-selected .pure-menu-link:hover,
145.pure-menu-selected .pure-menu-link:focus {
146 color: #fff;
147 background: transparent;
148}
149
150.pure-menu-item:hover::after {
151 margin: -4px auto 0 auto;
152 display: block;
153 content:"";
154 background: #fff;
155 height: 4px;
156 width: 100%;
157}
158
159.menu-toggle {
160 width: 34px;
161 height: 45px;
162 position: absolute;
163 top: 5px;
164 right: 0;
165 display: none;
166}
167
168.menu-toggle .bar {
169 background-color: #b0ddce;
170 display: block;
171 width: 20px;
172 height: 2px;
173 border-radius: 100px;
174 position: absolute;
175 top: 18px;
176 right: 7px;
177 transition: all 0.5s;
178}
179
180.menu-toggle .bar:first-child {
181 transform: translateY(-6px);
182}
183
184.menu-toggle.x .bar {
185 transform: rotate(45deg);
186}
187
188.menu-toggle.x .bar:first-child {
189 transform: rotate(-45deg);
190}
191
192@media screen and (max-width: 64em) {
193 .menu-toggle {
194 display: block;
195 }
196}
197
198.header-buttons {
199 text-align: right;
200}
201
202.linkcount {
203 color: #252525;
204 font-size: 0.8em;
205}
206
207@media screen and (min-width: 64em) {
208 .linkcount {
209 position: absolute;
210 right: 5px;
211 }
212}
213
214#search, #search-linklist, #search-tagcloud {
215 text-align: center;
216 width: 100%;
217}
218
219#search input[type="text"], #search-linklist input[type="text"] {
220 padding: 0 5px;
221 height: 30px;
222 width: 260px;
223 background: #f5f5f5;
224 border: medium none currentColor;
225 box-shadow: 0 1px 0 rgba(255, 255, 255, 0.078), 0 1px 1px rgba(0, 0, 0, 0.298) inset;
226 border-radius: 2px;
227 color: #252525;
228}
229@media screen and (max-width: 64em) {
230 .searchform {
231 max-width: 260px;
232 margin: 0 auto;
233 }
234}
235
236/* because chrome */
237#search input[type="text"]::-webkit-input-placeholder,
238#search-linklist input[type="text"]::-webkit-input-placeholder {
239 color: #777777;
240}
241
242#search button,
243#search-tagcloud button,
244#search-linklist button {
245 padding: 4px 8px 6px 8px;
246 background-color: #1B926C;
247 color: #f5f5f5;
248 border: none;
249 border-radius: 2px;
250}
251
252#search-tagcloud button {
253 width: 90%;
254}
255
256@media screen and (max-width: 64em) {
257 #search-linklist button {
258 width: 100%;
259 }
260 #search-linklist .awesomplete {
261 margin: 5px 0;
262 }
263}
264
265#search button:hover,
266#search-linklist button:hover,
267#search-tagcloud button:hover {
268 color: #d0d0d0;
269}
270
271#search,
272#search-linklist {
273 padding: 6px 0;
274}
275
276@media screen and (max-width: 64em) {
277 #search, #search * {
278 visibility: hidden;
279 }
280}
281
282.subheader-form a.button {
283 color: #f5f5f5;
284 font-weight: bold;
285 text-decoration: none;
286 border: 2px solid #f5f5f5;
287 border-radius: 5px;
288 padding: 3px 10px;
289}
290
291.linklist-item-editbuttons .delete-checkbox {
292 display: none;
293}
294
295#header-login-form input[type="text"], #header-login-form input[type="password"] {
296 width: 200px;
297}
298
299/* because chrome */
300#header-login-form input[type="text"]::-webkit-input-placeholder,
301#header-login-form input[type="password"]::-webkit-input-placeholder {
302 color: #777777;
303}
304
305.subheader-form {
306 visibility: hidden;
307 position: fixed;
308 width: 100%;
309 text-align: center;
310 background: #1b926c;
311 display: block;
312 z-index: 999;
313 height: 30px;
314 padding: 5px 0;
315}
316
317@media screen and (min-width: 64em) {
318 .subheader-form.open, .subheader-form.open * {
319 visibility: visible;
320 }
321}
322
323.subheader-form input[type="text"], .subheader-form input[type="password"], .subheader-form .remember-me {
324 padding: 5px 5px 3px 15px;
325 height: 20px;
326 width: 20%;
327 background: #f5f5f5;
328 border: medium none currentColor;
329 border-radius: 2px;
330 box-shadow: 0 1px 0 rgba(255, 255, 255, 0.078), 0 1px 4px rgba(0, 0, 0, 0.298) inset;
331 color: #252525;
332}
333
334/* because chrome */
335.subheader-form input[type="text"]::-webkit-input-placeholder,
336.subheader-form input[type="password"]::-webkit-input-placeholder
337{
338 color: #252525;
339}
340
341.subheader-form .remember-me {
342 display: inline-block;
343 width: auto;
344 padding: 5px 20px 3px 20px;
345 cursor: pointer;
346}
347
348.subheader-form .remember-me label, .subheader-form .remember-me input {
349 cursor: pointer;
350}
351
352.subheader-form input[type="submit"] {
353 display: inline-block;
354 margin: 0 0 5px 0;
355 padding: 4px 0 4px 0;
356 height: 28px;
357 width: 100px;
358 background: #1b926c;
359 border: 1px solid #f5f5f5;
360 color: #f5f5f5;
361 border-radius: 2px;
362}
363
364.subheader-form input[type="submit"]:hover {
365 background: #f5f5f5;
366 color: #1b926c;
367}
368
369.new-version-message {
370 text-align: center;
371}
372
373.new-version-message a {
374 color: rgb(151, 96, 13);
375 font-weight: bold;
376}
377
378/**
379 * CONTENT - GENERAL
380 */
381#content {
382 position: relative;
383 z-index: 2;
384 margin-top: 45px;
385}
386
387/**
388 * Plugins additional forms
389 */
390.toolbar-plugin {
391 margin: 5px 0;
392 text-align: center;
393}
394
395.toolbar-plugin input[type="text"] {
396 padding: 0 5px;
397 height: 30px;
398 width: 300px;
399 background: #f5f5f5;
400 border: medium none currentColor;
401 box-shadow: 0 1px 0 rgba(255, 255, 255, 0.078), 0 1px 1px rgba(0, 0, 0, 0.298) inset;
402 border-radius: 2px;
403 color: #252525;
404}
405
406/* because chrome */
407.toolbar-plugin input[type="text"]::-webkit-input-placeholder {
408 color: #777777;
409}
410
411.toolbar-plugin input[type="submit"] {
412 padding: 0 10px;
413 height: 30px;
414 background: #f5f5f5;
415 border: medium none currentColor;
416 border-radius: 2px;
417 color: #252525;
418}
419
420.toolbar-plugin input[type="submit"]:hover {
421 background: #fff;
422}
423
424@media screen and (max-width: 64em) {
425 .toolbar-plugin input[type="text"] {
426 width: 70%;
427
428 }
429}
430
431/**
432 * CONTENT - LINKLIST PAGING
433 * 64em -> lg
434 */
435.linklist-filters {
436 margin: 5px 0;
437 color: #252525;
438 font-size: 0.9em;
439}
440
441.linklist-filters a {
442 padding: 5px 8px;
443 text-decoration: none;
444}
445
446.linklist-filters .filter-off {
447 color: #252525;
448 background: #f5f5f5;
449}
450
451.linklist-filters .filter-on {
452 color: #b0ddce;
453 background: #1b926c;
454}
455
456.linklist-filters .filter-block {
457 color: #f5f5f5;
458 background: #ac2925;
459}
460
461.linklist-pages {
462 margin: 5px 0;
463 color: #252525;
464 text-align: center;
465}
466
467.linklist-pages a {
468 color: #252525;
469 text-decoration: none;
470}
471
472.linklist-pages a:hover {
473 color: #fff;
474}
475
476.linksperpage {
477 margin: 5px 0;
478 text-align: right;
479 color: #252525;
480 font-size: 0.9em;
481}
482
483.linksperpage a {
484 padding: 5px 5px;
485 text-decoration: none;
486 color: #252525;
487 background: #f5f5f5;
488}
489
490.linksperpage a, .linksperpage input[type="text"] {
491 display: inline-block;
492 width: 20px;
493 text-align: center;
494}
495
496.linksperpage form {
497 display: inline;
498}
499
500.linksperpage input[type="text"] {
501 height: 20px;
502 margin: 0;
503 padding: 4px 5px 3px 8px;
504 background: #f5f5f5;
505 border: medium none currentColor;
506 color: #252525;
507 font-size: 0.8em;
508}
509
510/**
511 * CONTENT - LINKLIST ITEMS
512 */
513.linklist-item {
514 margin: 0 0 10px 0;
515 background: #f5f5f5;
516 box-shadow: 1px 1px 3px #797979;
517}
518
519.linklist-item-buttons {
520 background: transparent;
521 position: relative;
522 width: 23px;
523 z-index: 99;
524}
525
526.linklist-item-buttons-right {
527 float: right;
528 margin-right: -25px;
529}
530
531.linklist-item-buttons * {
532 display: block;
533 float: left;
534 width:100%;
535 margin: auto;
536 text-align: center;
537}
538
539.linklist-item-title, .linklist-item-title h2 {
540 margin: 0;
541 word-wrap: break-word;
542}
543
544.linklist-item-title {
545 position: relative;
546 background: #f5f5f5;
547}
548
549.linklist-item-title h2 {
550 padding: 3px 10px 0 10px;
551 line-height: 30px;
552}
553
554.linklist-item-title h2 a {
555 font-size: 0.7em;
556 color: #252525;
557 text-decoration: none;
558 vertical-align: middle;
559}
560
561.linklist-item-title .linklist-link {
562 font-size: 1.1em;
563 color: #1b926c;
564}
565
566.linklist-item-title h2 a:visited .linklist-link {
567 color: #2a4c41;
568}
569
570.linklist-item-title h2 a:hover, .linklist-item-title .linklist-link:hover{
571 color: #252525;
572}
573
574
575.linklist-item-title .label-private {
576 border: solid 1px #F89406;
577 font-family: Arial, sans-serif;
578 font-size: 0.65em;
579 color: #F89406;
580}
581
582.fold-button {
583 display: none;
584 color: #252525;
585}
586
587.linklist-item-editbuttons {
588 float: right;
589 padding: 8px 5px;
590}
591
592.linklist-item-editbuttons * {
593 display: block;
594 float: left;
595 margin: 0 1px;
596}
597
598.linklist-item-editbuttons a {
599 font-size: 1em;
600}
601
602.edit-link {
603 font-size: 1.2em;
604 color: #0b5ea6;
605}
606
607.delete-link {
608 font-size: 1.3em;
609 color: #ac2925 !important;
610}
611
612.linklist-item-description {
613 position: relative;
614 padding: 0 10px;
615 word-wrap: break-word;
616 color: #252525;
617 line-height: 1.3em;
618}
619
620.linklist-item-description a {
621 text-decoration: none;
622 color: #1b926c;
623}
624
625.linklist-item-description a:hover {
626 color: #252525;
627}
628
629.linklist-item-description a:visited {
630 color: #14553f;
631}
632
633.linklist-item-thumbnail {
634 position: relative;
635 padding: 0 0 0 5px;
636 margin: 0;
637 float: right;
638 z-index: 50;
639 height: 90px;
640}
641
642.linklist-item.private .linklist-item-title::before,
643.linklist-item.private .linklist-item-description::before {
644 position: absolute;
645 left: 3px;
646 top: 0;
647 display: block;
648 content:"";
649 background: #F89406;
650 height: 96%;
651 width: 2px;
652 z-index: 1;
653}
654
655.linklist-item.private .linklist-item-description::before {
656 height: 100%;
657}
658
659.linklist-item.private .linklist-item-title::before {
660 margin-top: 3px;
661}
662
663.linklist-item-infos {
664 padding: 4px 8px 4px 8px;
665 background: #ddd;
666 color: #252525;
667}
668
669.linklist-item-infos a {
670 color: #252525;
671 text-decoration: none;
672}
673
674.linklist-item-infos a:hover {
675 color: #000;
676}
677
678.linklist-item-infos .linklist-item-tags {
679 font-size: 0.8em;
680}
681
682.linklist-item-infos .label-tag {
683 font-size: 1em;
684}
685
686.linklist-item-infos-dateblock {
687 font-size: 0.9em;
688}
689
690.linklist-plugin-icon {
691 width: 13px;
692 height: 13px;
693}
694
695.linklist-item-infos-url {
696 text-align: right;
697 white-space: nowrap;
698 overflow: hidden;
699 text-overflow: ellipsis;
700 font-size: 0.8em;
701 height:23px;
702 line-height:23px;
703}
704
705.linklist-item-infos .mobile-buttons {
706 text-align: right;
707}
708
709.linklist-item-infos .linklist-plugin-icon {
710 display: inline-block;
711 margin: 0 2px;
712 width: 16px;
713 height: 16px;
714}
715
716.linklist-item-infos-controls-group {
717 display: inline-block;
718 border-right: 1px solid #5d5d5d;
719 padding-right: 6px;
720}
721
722.ctrl-edit {
723 margin: 0 7px;
724}
725
726/** 64em -> lg **/
727@media screen and (max-width: 64em) {
728 .linklist-item-infos-url {
729 text-align: left;
730 }
731}
732
733/**
734 * Footer
735 */
736#footer {
737 margin: 20px 0;
738 padding: 5px;
739 text-align: center;
740 color: #252525;
741}
742
743#footer:before {
744 display: block;
745 content:"";
746 background: linear-gradient(to right, #949393, #252525, #949393);
747 height: 1px;
748 width: 80%;
749 margin: 10px auto;
750}
751
752#footer a {
753 color: #252525;
754}
755
756/**
757 * PAGE FORM
758 */
759.page-form {
760 margin: 20px 0 0 0;
761 background: #f5f5f5;
762 box-shadow: 1px 1px 2px #797979;
763 color: #252525;
764 overflow: hidden;
765}
766
767.page-form .window-title {
768 margin: 0 0 10px 0;
769 padding: 10px 0;
770 width: 100%;
771 color: #1b926c;
772 background: #f5f5f5;
773 text-align: center;
774}
775
776.page-form .window-subtitle {
777 text-align: center;
778}
779
780.page-form a {
781 color: #1b926c;
782 font-weight: bold;
783 text-decoration: none;
784}
785
786.page-form p {
787 padding: 5px 10px;
788 margin: 0;
789}
790
791.page-form input[type="text"],
792.page-form input[type="password"],
793.page-form textarea {
794 box-sizing: border-box;
795 margin: 10px 0;
796 padding: 5px 5px 3px 15px;
797 height: 35px;
798 width: 90%;
799 background: #eeeeee;
800 border: solid 1px #d8d8d8;
801 border-radius: 2px;
802 color: #252525;
803}
804
805.page-form textarea {
806 min-height: 240px;
807 padding: 15px 5px 3px 15px;
808 resize: vertical;
809 overflow-y: auto;
810 word-wrap:break-word
811}
812
813/* because chrome */
814.page-form input[type="text"]::-webkit-input-placeholder,
815.page-form input[type="password"]::-webkit-input-placeholder {
816 color: #777777;
817}
818
819.page-form input[type="submit"], .page-form a.button {
820 margin: 15px 5px;
821 height: 35px;
822 line-height: 35px;
823 width: 150px;
824 background: #1b926c;
825 color: #f5f5f5;
826 border: none;
827 box-shadow: 1px 1px 1px #ddd, -1px -1px 6px #ddd, -1px 1px 2px #ddd, 1px -1px 2px #ddd;
828 font-size: 1.2em;
829 text-decoration: none;
830 vertical-align: center;
831 font-weight: normal;
832 display: inline-block;
833}
834
835
836.page-form .button.button-red {
837 background: #ac2925;
838}
839
840.page-form .submit-buttons {
841 margin-bottom: 10px;
842}
843
844@media screen and (min-width: 64em) {
845 .page-form .submit-buttons {
846 position: relative;
847 }
848
849 .page-form .submit-buttons .button.button-red {
850 position: absolute;
851 right: 5%;
852 }
853}
854
855@media screen and (max-width: 64em) {
856 .page-form .submit-buttons .button {
857 display: block;
858 margin: auto;
859 }
860}
861
862.page-form select {
863 color: #252525;
864}
865
866/**
867 * PAGE FORM - LIGHT
868 */
869.page-form-light div, .page-form-light p {
870 text-align: center;
871}
872
873/**
874 * PAGE FORM - COMPLETE
875 */
876.page-form-complete {
877 #background: #f5f5f5;
878}
879
880.page-form-complete div, .page-form-complete p {
881 color: #252525;
882}
883
884.page-form-complete .form-label, .page-form-complete .form-input {
885 position: relative;
886 height: 60px;
887}
888
889.page-form-complete .form-label label,
890.page-form-complete .form-input input,
891.page-form-complete .form-input select.align,
892.page-form-complete .timezone {
893 position: absolute;
894 top: 50%;
895 transform: translateY(-50%);
896}
897
898.page-form-complete .form-label label {
899 text-align: right;
900 right: 0;
901 padding: 0 20px;
902}
903
904.page-form-complete .label-name {
905 font-weight: bold;
906}
907
908.page-form-complete .label-desc {
909 font-size: 0.8em;
910}
911
912.page-form-complete input[type="text"],
913.page-form-complete input[type="password"],
914.page-form-complete textarea {
915 margin: 0;
916}
917
918.page-form section {
919 margin: 10px 0 25px 0;
920}
921
922.page-form table {
923 margin: auto;
924 width: 90%;
925}
926
927.page-form table .order {
928 text-decoration: none;
929 color: #252525;
930}
931
932.page-form table, .page-form th, .page-form td {
933 border-width: 1px 0;
934 border-style: solid;
935 border-color: #aaaaaa;
936}
937
938.page-form th, .page-form td {
939 padding: 5px;
940
941}
942
943/* Awesomeplete fix */
944div.awesomplete {
945 width: inherit;
946}
947
948div.awesomplete > input {
949 display: inherit;
950}
951
952div.awesomplete > ul {
953 z-index: 9999;
954}
955
956.page-form .awesomplete {
957 width: 90%;
958}
959
960.page-form .awesomplete input {
961 width: 100%;
962}
963
964.page-form div.awesomplete > ul {
965 color: black;
966}
967
968form[name="linkform"].page-form {
969 overflow: visible;
970}
971
972@media screen and (max-width: 64em) {
973 .page-form-complete .form-label {
974 height: inherit;
975 }
976
977 .page-form-complete .form-label label,
978 .page-form-complete .form-input input,
979 .page-form-complete .timezone {
980 position: inherit;
981 top: inherit;
982 transform: translateY(0);
983 }
984
985 .page-form-complete .form-input input[type="checkbox"] {
986 position: absolute;
987 top: 50%;
988 right: 50%;
989 transform: translateY(-50%);
990 }
991
992 .page-form-complete .form-input {
993 text-align: center;
994 }
995
996 .page-form-complete .form-label label {
997 display: block;
998 text-align: left;
999 margin: 10px 0 0 0;
1000 }
1001
1002 .timezone-continent:after {
1003 content:"\a\a";
1004 white-space: pre;
1005 }
1006
1007 .page-form-complete .radio-buttons {
1008 text-align: left;
1009 padding: 5px 15px;
1010 }
1011}
1012
1013/**
1014 * Page visitor (page form extended)
1015 */
1016.page-visitor {
1017 color: #252525;
1018}
1019
1020#page404 {
1021 color: #3f3f3f;
1022}
1023
1024/**
1025 * EDIT LINK
1026 */
1027#editlinkform .created-date {
1028 color: #767676;
1029 margin-bottom: 10px;
1030}
1031
1032/**
1033 * LOGIN
1034 */
1035#login-form .remember-me {
1036 margin: 5px 0;
1037}
1038
1039/**
1040 * Search results
1041 */
1042.search-result a {
1043 color: white;
1044 text-decoration: none;
1045}
1046
1047.search-result .label-tag {
1048 border-color: white;
1049}
1050
1051.search-result .label-tag .remove {
1052 border-left: white 1px solid;
1053 padding: 0 0 0 5px;
1054 margin: 0 0 0 5px;
1055}
1056
1057.search-result .label-private {
1058 border: 1px solid white;
1059}
1060
1061/**
1062 * TOOLS
1063 */
1064.tools-item {
1065 margin: 10px 0;
1066}
1067
1068.tools-item .pure-button:hover {
1069 background-image: none;
1070 background-color: #1b926c;
1071 color: #f5f5f5;
1072}
1073
1074/**
1075 * PLUGIN ADMIN
1076 */
1077#pluginform .mobile-row {
1078 font-size: 0.9em;
1079}
1080
1081#pluginform .more {
1082 margin-top: 10px;
1083}
1084
1085@media screen and (max-width: 64em) {
1086 #pluginform .main-row, #pluginform .main-row td {
1087 border-bottom-style: none;
1088 }
1089
1090 #pluginform .mobile-row, #pluginform .mobile-row td {
1091 border-top-style: none;
1092 }
1093}
1094
1095/**
1096 * IMPORT
1097 */
1098#import-field {
1099 margin: 15px 0;
1100}
1101
1102/**
1103 * TAG CLOUD
1104 */
1105#cloudtag {
1106 padding: 10px;
1107 text-align: center;
1108}
1109
1110#cloudtag, #cloudtag a {
1111 color: #252525;
1112 text-decoration: none;
1113}
1114
1115#cloudtag .count {
1116 color: #7f7f7f;
1117}
1118
1119/**
1120 * TAG LIST
1121 */
1122#taglist {
1123 padding: 0 10px;
1124}
1125
1126#taglist a {
1127 color: #252525;
1128 text-decoration: none;
1129}
1130
1131#taglist .count {
1132 display: inline-block;
1133 width: 35px;
1134 text-align: right;
1135 color: #7f7f7f;
1136}
1137
1138#taglist .rename-tag-form {
1139 display: none;
1140}
1141
1142#taglist .delete-tag {
1143 color: #ac2925;
1144 display: none;
1145}
1146
1147#taglist .rename-tag {
1148 color: #0b5ea6;
1149}
1150
1151#taglist .validate-rename-tag {
1152 color: #1b926c;
1153}
1154
1155/**
1156 * Picture wall CSS
1157 */
1158#picwall_container {
1159 margin: 0 10px 10px 10px;
1160 color: #252525;
1161 background-color: #f5f5f5;
1162 clear: both;
1163}
1164
1165.picwall_pictureframe {
1166 margin: 2px;
1167 background-color: #f5f5f5;
1168 z-index: 5;
1169 position: relative;
1170 display: table-cell;
1171 vertical-align: middle;
1172 width: 90px;
1173 height: 90px;
1174 overflow: hidden;
1175 text-align: center;
1176 float: left;
1177}
1178
1179.b-lazy {
1180 -webkit-transition: opacity 500ms ease-in-out;
1181 -moz-transition: opacity 500ms ease-in-out;
1182 -o-transition: opacity 500ms ease-in-out;
1183 transition: opacity 500ms ease-in-out;
1184 opacity: 0;
1185}
1186.b-lazy.b-loaded {
1187 opacity: 1;
1188}
1189
1190.picwall_pictureframe img {
1191 max-width: 100%;
1192 height: auto;
1193 color: transparent;
1194} /* Adapt the width of the image */
1195
1196.picwall_pictureframe a {
1197 text-decoration: none;
1198}
1199
1200/* CSS to show title when hovering an image - no javascript required. */
1201.picwall_pictureframe span.info {
1202 display: none;
1203 font-family: Arial, sans-serif;
1204}
1205
1206.picwall_pictureframe:hover span.info {
1207 display: block;
1208 position: absolute;
1209 top: 0;
1210 left: 0;
1211 width: 90px;
1212 height: 90px;
1213 font-weight: bold;
1214 font-size: 9pt;
1215 color: #f5f5f5;
1216 text-align: left;
1217 background-color: rgba(0, 0, 0, 0.8);
1218}
1219
1220/**
1221 * DAILY
1222 */
1223.daily-desc {
1224 color: #7f7f7f;
1225 font-size: 0.8em;
1226}
1227
1228.daily-about a {
1229 color: #343434;
1230 text-decoration: none;
1231}
1232
1233.daily-about a:hover {
1234 color: #7f7f7f;
1235}
1236
1237.daily-about h3:before, .daily-about h3:after {
1238 display: block;
1239 content:"";
1240 background: linear-gradient(to right, #d5d4d4, #252525, #d5d4d4);
1241 height: 1px;
1242 width: 90%;
1243 margin: 10px auto;
1244}
1245
1246.daily-entry {
1247 padding: 0 10px;
1248}
1249
1250.daily-entry .daily-entry-title:after {
1251 display: block;
1252 content:"";
1253 background: linear-gradient(to right, #fff, #515151, #fff);
1254 height: 1px;
1255 width: 70%;
1256 margin: 5px auto;
1257}
1258
1259.daily-entry .daily-entry-title {
1260 margin: 10px 0 0 0;
1261}
1262
1263.daily-entry .daily-entry-title a {
1264 color: #000;
1265 text-decoration: none;
1266}
1267
1268.daily-entry .daily-entry-description {
1269 padding: 5px 5px 0 5px;
1270 font-size: 0.9em;
1271 text-align: justify;
1272 word-wrap: break-word;
1273}
1274
1275.daily-entry .daily-entry-tags {
1276 padding: 0 5px 5px 5px;
1277 font-size: 0.8em;
1278}
1279
1280.daily-entry-thumbnail {
1281 float: left;
1282 margin: 15px 5px 5px 15px;
1283}
1284
1285.daily-entry-description a {
1286 text-decoration: none;
1287 color: #1b926c;
1288}
1289
1290.daily-entry-description a:hover {
1291 text-shadow: 1px 1px #ddd;
1292}
1293
1294.daily-entry-description a:visited {
1295 color: #20b988;
1296}
1297
1298/*
1299 * Fix empty bookmarklet name in Firefox
1300 */
1301.pure-button {
1302 -moz-user-select: auto;
1303}
1304
1305.tag-sort {
1306 margin-top: 30px;
1307 text-align: center;
1308}
1309
1310.tag-sort a {
1311 display: inline-block;
1312 margin: 0 15px;
1313 color: white;
1314 text-decoration: none;
1315 font-weight: bold;
1316}
1317
1318/**
1319 * Markdown
1320 */
1321.markdown p {
1322 margin: 0 !important;
1323}
1324
1325.markdown p + p {
1326 margin: 0.5em 0 0 0 !important;
1327}
1328
1329.markdown *:first-child {
1330 margin-top: 0 !important;
1331}
1332
1333.markdown *:last-child {
1334 margin-bottom: 5px !important;
1335}
1336
1337/**
1338 * Pure Button
1339 */
1340.pure-button-success,
1341.pure-button-error,
1342.pure-button-warning,
1343.pure-button-primary,
1344.pure-button-shaarli,
1345.pure-button-secondary {
1346 color: white !important;
1347 border-radius: 4px;
1348 text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
1349}
1350
1351.pure-button-shaarli {
1352 background-color: #1B926C;
1353}