diff options
author | Seb Sauvage <sebsauvage@sebsauvage.net> | 2011-11-17 21:46:34 +0100 |
---|---|---|
committer | Emilien Klein <emilien@klein.st> | 2011-11-17 21:46:34 +0100 |
commit | 6d946e78bfca94ac89494e84db3746473867c5ff (patch) | |
tree | 2ce5985de402510857a3556eade4fcd5ad13ab2d | |
parent | 2732de7c9ef82cee6b8eb8116e376c4be06425c3 (diff) | |
download | Shaarli-6d946e78bfca94ac89494e84db3746473867c5ff.tar.gz Shaarli-6d946e78bfca94ac89494e84db3746473867c5ff.tar.zst Shaarli-6d946e78bfca94ac89494e84db3746473867c5ff.zip |
Version 0.0.28 beta:
- Changed: New Shaarli theme and logo by Idle (http://www.idleman.fr/blog/?p=469)
- Changed: In picture wall, pictures point to Shaarli permalink instead of final URL. This way, users can read the description.
- Corrected: In RSS/ATOM feeds, guid and link URL of permalinks are now proper absolute URLs.
- Added: In RSS/ATOM feeds, URLs are now clickable.
- Changed: http_parse_headers() function renamed to http_parse_headers_shaarli() to prevent name collision with some php extensions.
- Corrected: Thumbnails removed for imgur.com/a/ URLs (Thumbnails are not available for albums on imgur).
- Corrected: Shaarli now correctly only tries to get thumbnails for vimeo video URLs.
- Corrected: A bug in imgur.com URLs handling would cause some thumbnails not to appear. This has been corrected. You should see more thumbnails now.
- Added: Thumbnail support for youtu.be URLs (YouTube short url service).
- Added: PubSubHub protocol support (from http://aldarone.fr/les-flux-rss-shaarli-et-pubsubhubbub/). Warning: This was not tested. You need to set your hub $
- Corrected: The search engine would not return a result if the word to search was the first in description.
- Corrected: Extracted title is now correct if the page has two title html tags.
- Added: RSS and ATOM feeds now also contain tags (in category tags, as per their respective specifications).
-rw-r--r-- | images/calendar.png | bin | 0 -> 675 bytes | |||
-rw-r--r-- | images/favicon.ico | bin | 0 -> 76949 bytes | |||
-rw-r--r-- | images/logo.png | bin | 0 -> 6253 bytes | |||
-rw-r--r-- | images/tag_blue.png | bin | 0 -> 586 bytes | |||
-rw-r--r-- | index.php | 197 | ||||
-rw-r--r-- | shaarli.css | 233 |
6 files changed, 335 insertions, 95 deletions
diff --git a/images/calendar.png b/images/calendar.png new file mode 100644 index 00000000..65891385 --- /dev/null +++ b/images/calendar.png | |||
Binary files differ | |||
diff --git a/images/favicon.ico b/images/favicon.ico new file mode 100644 index 00000000..c8b043b4 --- /dev/null +++ b/images/favicon.ico | |||
Binary files differ | |||
diff --git a/images/logo.png b/images/logo.png new file mode 100644 index 00000000..20989288 --- /dev/null +++ b/images/logo.png | |||
Binary files differ | |||
diff --git a/images/tag_blue.png b/images/tag_blue.png new file mode 100644 index 00000000..9757fc6e --- /dev/null +++ b/images/tag_blue.png | |||
Binary files differ | |||
@@ -1,5 +1,5 @@ | |||
1 | <?php | 1 | <?php |
2 | // Shaarli 0.0.27 beta - Shaare your links... | 2 | // Shaarli 0.0.28 beta - Shaare your links... |
3 | // The personal, minimalist, super-fast, no-database delicious clone. By sebsauvage.net | 3 | // The personal, minimalist, super-fast, no-database delicious clone. By sebsauvage.net |
4 | // http://sebsauvage.net/wiki/doku.php?id=php:shaarli | 4 | // http://sebsauvage.net/wiki/doku.php?id=php:shaarli |
5 | // Licence: http://www.opensource.org/licenses/zlib-license.php | 5 | // Licence: http://www.opensource.org/licenses/zlib-license.php |
@@ -20,7 +20,8 @@ $GLOBALS['config']['HIDE_TIMESTAMPS'] = false; // If true, the moment when links | |||
20 | $GLOBALS['config']['ENABLE_THUMBNAILS'] = true; // Enable thumbnails in links. | 20 | $GLOBALS['config']['ENABLE_THUMBNAILS'] = true; // Enable thumbnails in links. |
21 | $GLOBALS['config']['CACHEDIR'] = 'cache'; // Cache directory for thumbnails for SLOW services (like flickr) | 21 | $GLOBALS['config']['CACHEDIR'] = 'cache'; // Cache directory for thumbnails for SLOW services (like flickr) |
22 | $GLOBALS['config']['ENABLE_LOCALCACHE'] = true; // Enable Shaarli to store thumbnail in a local cache. Disable to reduce webspace usage. | 22 | $GLOBALS['config']['ENABLE_LOCALCACHE'] = true; // Enable Shaarli to store thumbnail in a local cache. Disable to reduce webspace usage. |
23 | 23 | $GLOBALS['config']['PUBSUBHUB_URL'] = ''; // PubSubHub support. Put an empty string to disable, or put your hub url here to enable. | |
24 | // Note: You must have publisher.php in the same directory as Shaarli index.php | ||
24 | // ----------------------------------------------------------------------------------------------- | 25 | // ----------------------------------------------------------------------------------------------- |
25 | // Program config (touch at your own risks !) | 26 | // Program config (touch at your own risks !) |
26 | $GLOBALS['config']['UPDATECHECK_FILENAME'] = $GLOBALS['config']['DATADIR'].'/lastupdatecheck.txt'; // For updates check of Shaarli. | 27 | $GLOBALS['config']['UPDATECHECK_FILENAME'] = $GLOBALS['config']['DATADIR'].'/lastupdatecheck.txt'; // For updates check of Shaarli. |
@@ -53,7 +54,7 @@ header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); | |||
53 | header("Cache-Control: no-store, no-cache, must-revalidate"); | 54 | header("Cache-Control: no-store, no-cache, must-revalidate"); |
54 | header("Cache-Control: post-check=0, pre-check=0", false); | 55 | header("Cache-Control: post-check=0, pre-check=0", false); |
55 | header("Pragma: no-cache"); | 56 | header("Pragma: no-cache"); |
56 | define('shaarli_version','0.0.27 beta'); | 57 | define('shaarli_version','0.0.28 beta'); |
57 | if (!is_dir($GLOBALS['config']['DATADIR'])) { mkdir($GLOBALS['config']['DATADIR'],0705); chmod($GLOBALS['config']['DATADIR'],0705); } | 58 | if (!is_dir($GLOBALS['config']['DATADIR'])) { mkdir($GLOBALS['config']['DATADIR'],0705); chmod($GLOBALS['config']['DATADIR'],0705); } |
58 | if (!is_file($GLOBALS['config']['DATADIR'].'/.htaccess')) { file_put_contents($GLOBALS['config']['DATADIR'].'/.htaccess',"Allow from none\nDeny from all\n"); } // Protect data files. | 59 | if (!is_file($GLOBALS['config']['DATADIR'].'/.htaccess')) { file_put_contents($GLOBALS['config']['DATADIR'].'/.htaccess',"Allow from none\nDeny from all\n"); } // Protect data files. |
59 | if ($GLOBALS['config']['ENABLE_LOCALCACHE']) | 60 | if ($GLOBALS['config']['ENABLE_LOCALCACHE']) |
@@ -94,7 +95,7 @@ function checkUpdate() | |||
94 | { | 95 | { |
95 | $version=shaarli_version; | 96 | $version=shaarli_version; |
96 | list($httpstatus,$headers,$data) = getHTTP('http://sebsauvage.net/files/shaarli_version.txt',2); | 97 | list($httpstatus,$headers,$data) = getHTTP('http://sebsauvage.net/files/shaarli_version.txt',2); |
97 | if (strpos($httpstatus,'200 OK')) $version=$data; | 98 | if (strpos($httpstatus,'200 OK')!==false) $version=$data; |
98 | // If failed, nevermind. We don't want to bother the user with that. | 99 | // If failed, nevermind. We don't want to bother the user with that. |
99 | file_put_contents($GLOBALS['config']['UPDATECHECK_FILENAME'],$version); // touch file date | 100 | file_put_contents($GLOBALS['config']['UPDATECHECK_FILENAME'],$version); // touch file date |
100 | } | 101 | } |
@@ -150,6 +151,23 @@ function autoLocale() | |||
150 | } | 151 | } |
151 | 152 | ||
152 | // ------------------------------------------------------------------------------------------ | 153 | // ------------------------------------------------------------------------------------------ |
154 | // PubSubHub protocol support (if enabled) [UNTESTED] | ||
155 | // (Source: http://aldarone.fr/les-flux-rss-shaarli-et-pubsubhubbub/ ) | ||
156 | if (!empty($GLOBALS['config']['PUBSUBHUB_URL'])) include './publisher.php'; | ||
157 | function pubsubhub() | ||
158 | { | ||
159 | if (!empty($GLOBALS['config']['PUBSUBHUB_URL'])) | ||
160 | { | ||
161 | $p = new Publisher($GLOBALS['config']['PUBSUBHUB_URL']); | ||
162 | $topic_url = array ( | ||
163 | serverUrl().$_SERVER['SCRIPT_NAME'].'?do=atom', | ||
164 | serverUrl().$_SERVER['SCRIPT_NAME'].'?do=rss' | ||
165 | ); | ||
166 | $p->publish_update($topic_url); | ||
167 | } | ||
168 | } | ||
169 | |||
170 | // ------------------------------------------------------------------------------------------ | ||
153 | // Session management | 171 | // Session management |
154 | define('INACTIVITY_TIMEOUT',3600); // (in seconds). If the user does not access any page within this time, his/her session is considered expired. | 172 | define('INACTIVITY_TIMEOUT',3600); // (in seconds). If the user does not access any page within this time, his/her session is considered expired. |
155 | ini_set('session.use_cookies', 1); // Use cookies to store session. | 173 | ini_set('session.use_cookies', 1); // Use cookies to store session. |
@@ -378,13 +396,13 @@ function linkdate2locale($linkdate) | |||
378 | } | 396 | } |
379 | 397 | ||
380 | // Parse HTTP response headers and return an associative array. | 398 | // Parse HTTP response headers and return an associative array. |
381 | function http_parse_headers( $headers ) | 399 | function http_parse_headers_shaarli( $headers ) |
382 | { | 400 | { |
383 | $res=array(); | 401 | $res=array(); |
384 | foreach($headers as $header) | 402 | foreach($headers as $header) |
385 | { | 403 | { |
386 | $i = strpos($header,': '); | 404 | $i = strpos($header,': '); |
387 | if ($i) | 405 | if ($i!==false) |
388 | { | 406 | { |
389 | $key=substr($header,0,$i); | 407 | $key=substr($header,0,$i); |
390 | $value=substr($header,$i+2,strlen($header)-$i-2); | 408 | $value=substr($header,$i+2,strlen($header)-$i-2); |
@@ -401,7 +419,7 @@ function http_parse_headers( $headers ) | |||
401 | [1] = associative array containing HTTP response headers (eg. echo getHTTP($url)[1]['Content-Type']) | 419 | [1] = associative array containing HTTP response headers (eg. echo getHTTP($url)[1]['Content-Type']) |
402 | [2] = data | 420 | [2] = data |
403 | Example: list($httpstatus,$headers,$data) = getHTTP('http://sebauvage.net/'); | 421 | Example: list($httpstatus,$headers,$data) = getHTTP('http://sebauvage.net/'); |
404 | if (strpos($httpstatus,'200 OK')) | 422 | if (strpos($httpstatus,'200 OK')!==false) |
405 | echo 'Data type: '.htmlspecialchars($headers['Content-Type']); | 423 | echo 'Data type: '.htmlspecialchars($headers['Content-Type']); |
406 | else | 424 | else |
407 | echo 'There was an error: '.htmlspecialchars($httpstatus) | 425 | echo 'There was an error: '.htmlspecialchars($httpstatus) |
@@ -415,7 +433,7 @@ function getHTTP($url,$timeout=30) | |||
415 | $data=file_get_contents($url,false,$context,-1, 4000000); // We download at most 4 Mb from source. | 433 | $data=file_get_contents($url,false,$context,-1, 4000000); // We download at most 4 Mb from source. |
416 | if (!$data) { $lasterror=error_get_last(); return array($lasterror['message'],array(),''); } | 434 | if (!$data) { $lasterror=error_get_last(); return array($lasterror['message'],array(),''); } |
417 | $httpStatus=$http_response_header[0]; // eg. "HTTP/1.1 200 OK" | 435 | $httpStatus=$http_response_header[0]; // eg. "HTTP/1.1 200 OK" |
418 | $responseHeaders=http_parse_headers($http_response_header); | 436 | $responseHeaders=http_parse_headers_shaarli($http_response_header); |
419 | return array($httpStatus,$responseHeaders,$data); | 437 | return array($httpStatus,$responseHeaders,$data); |
420 | } | 438 | } |
421 | catch (Exception $e) // getHTTP *can* fail silentely (we don't care if the title cannot be fetched) | 439 | catch (Exception $e) // getHTTP *can* fail silentely (we don't care if the title cannot be fetched) |
@@ -428,7 +446,7 @@ function getHTTP($url,$timeout=30) | |||
428 | // (Returns an empty string if not found.) | 446 | // (Returns an empty string if not found.) |
429 | function html_extract_title($html) | 447 | function html_extract_title($html) |
430 | { | 448 | { |
431 | return preg_match('!<title>(.*)</title>!is', $html, $matches) ? trim(str_replace("\n",' ', $matches[1])) : '' ; | 449 | return preg_match('!<title>(.*?)</title>!is', $html, $matches) ? trim(str_replace("\n",' ', $matches[1])) : '' ; |
432 | } | 450 | } |
433 | 451 | ||
434 | // ------------------------------------------------------------------------------------------ | 452 | // ------------------------------------------------------------------------------------------ |
@@ -574,7 +592,10 @@ class linkdb implements Iterator, Countable, ArrayAccess | |||
574 | $s = strtolower($searchterms); | 592 | $s = strtolower($searchterms); |
575 | foreach($this->links as $l) | 593 | foreach($this->links as $l) |
576 | { | 594 | { |
577 | $found=strpos(strtolower($l['title']),$s) || strpos(strtolower($l['description']),$s) || strpos(strtolower($l['url']),$s) || strpos(strtolower($l['tags']),$s); | 595 | $found= (strpos(strtolower($l['title']),$s)!==false) |
596 | || (strpos(strtolower($l['description']),$s)!==false) | ||
597 | || (strpos(strtolower($l['url']),$s)!==false) | ||
598 | || (strpos(strtolower($l['tags']),$s)!==false); | ||
578 | if ($found) $filtered[$l['linkdate']] = $l; | 599 | if ($found) $filtered[$l['linkdate']] = $l; |
579 | } | 600 | } |
580 | krsort($filtered); | 601 | krsort($filtered); |
@@ -644,16 +665,29 @@ function showRSS() | |||
644 | $pageaddr=htmlspecialchars(serverUrl().$_SERVER["SCRIPT_NAME"]); | 665 | $pageaddr=htmlspecialchars(serverUrl().$_SERVER["SCRIPT_NAME"]); |
645 | echo '<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">'; | 666 | echo '<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">'; |
646 | echo '<channel><title>'.htmlspecialchars($GLOBALS['title']).'</title><link>'.$pageaddr.'</link>'; | 667 | echo '<channel><title>'.htmlspecialchars($GLOBALS['title']).'</title><link>'.$pageaddr.'</link>'; |
647 | echo '<description>Shared links</description><language></language><copyright>'.$pageaddr.'</copyright>'."\n\n"; | 668 | echo '<description>Shared links</description><language>en-en</language><copyright>'.$pageaddr.'</copyright>'."\n\n"; |
669 | if (!empty($GLOBALS['config']['PUBSUBHUB_URL'])) | ||
670 | { | ||
671 | echo '<!-- PubSubHubbub Discovery -->'; | ||
672 | echo '<link rel="hub" href="'.htmlspecialchars($GLOBALS['config']['PUBSUBHUB_URL']).'" xmlns="http://www.w3.org/2005/Atom" />'; | ||
673 | echo '<link rel="self" href="'.htmlspecialchars($pageaddr).'?do=rss" xmlns="http://www.w3.org/2005/Atom" />'; | ||
674 | echo '<!-- End Of PubSubHubbub Discovery -->'; | ||
675 | } | ||
648 | $i=0; | 676 | $i=0; |
649 | $keys=array(); foreach($linksToDisplay as $key=>$value) { $keys[]=$key; } // No, I can't use array_keys(). | 677 | $keys=array(); foreach($linksToDisplay as $key=>$value) { $keys[]=$key; } // No, I can't use array_keys(). |
650 | while ($i<50 && $i<count($keys)) | 678 | while ($i<50 && $i<count($keys)) |
651 | { | 679 | { |
652 | $link = $linksToDisplay[$keys[$i]]; | 680 | $link = $linksToDisplay[$keys[$i]]; |
653 | $rfc822date = linkdate2rfc822($link['linkdate']); | 681 | $rfc822date = linkdate2rfc822($link['linkdate']); |
654 | echo '<item><title>'.htmlspecialchars($link['title']).'</title><guid>'.htmlspecialchars($link['url']).'</guid><link>'.htmlspecialchars($link['url']).'</link>'; | 682 | $absurl = htmlspecialchars($link['url']); |
655 | if (!$GLOBALS['config']['HIDE_TIMESTAMPS'] || isLoggedIn()) echo '<pubDate>'.htmlspecialchars($rfc822date).'</pubDate>'; | 683 | if (startsWith($absurl,'?')) $absurl=$pageaddr.$absurl; // make permalink URL absolute |
656 | echo '<description><![CDATA['.nl2br(htmlspecialchars($link['description'])).']]></description></item>'."\n"; | 684 | echo '<item><title>'.htmlspecialchars($link['title']).'</title><guid>'.$absurl.'</guid><link>'.$absurl.'</link>'; |
685 | if (!$GLOBALS['config']['HIDE_TIMESTAMPS'] || isLoggedIn()) echo '<pubDate>'.htmlspecialchars($rfc822date)."</pubDate>\n"; | ||
686 | if ($link['tags']!='') // Adding tags to each RSS entry (as mentioned in RSS specification) | ||
687 | { | ||
688 | foreach(explode(' ',$link['tags']) as $tag) { echo '<category domain="'.htmlspecialchars($pageaddr).'">'.htmlspecialchars($tag).'</category>'."\n"; } | ||
689 | } | ||
690 | echo '<description><![CDATA['.nl2br(text2clickable(htmlspecialchars($link['description']))).']]></description>'."\n</item>\n"; | ||
657 | $i++; | 691 | $i++; |
658 | } | 692 | } |
659 | echo '</channel></rss>'; | 693 | echo '</channel></rss>'; |
@@ -683,15 +717,29 @@ function showATOM() | |||
683 | $link = $linksToDisplay[$keys[$i]]; | 717 | $link = $linksToDisplay[$keys[$i]]; |
684 | $iso8601date = linkdate2iso8601($link['linkdate']); | 718 | $iso8601date = linkdate2iso8601($link['linkdate']); |
685 | $latestDate = max($latestDate,$iso8601date); | 719 | $latestDate = max($latestDate,$iso8601date); |
686 | $entries.='<entry><title>'.htmlspecialchars($link['title']).'</title><link href="'.htmlspecialchars($link['url']).'"/><id>'.htmlspecialchars($link['url']).'</id>'; | 720 | $absurl = htmlspecialchars($link['url']); |
721 | if (startsWith($absurl,'?')) $absurl=$pageaddr.$absurl; // make permalink URL absolute | ||
722 | $entries.='<entry><title>'.htmlspecialchars($link['title']).'</title><link href="'.$absurl.'" /><id>'.$absurl.'</id>'; | ||
687 | if (!$GLOBALS['config']['HIDE_TIMESTAMPS'] || isLoggedIn()) $entries.='<updated>'.htmlspecialchars($iso8601date).'</updated>'; | 723 | if (!$GLOBALS['config']['HIDE_TIMESTAMPS'] || isLoggedIn()) $entries.='<updated>'.htmlspecialchars($iso8601date).'</updated>'; |
688 | $entries.='<summary>'.nl2br(htmlspecialchars($link['description'])).'</summary></entry>'."\n"; | 724 | $entries.='<summary>'.nl2br(text2clickable(htmlspecialchars($link['description'])))."</summary>\n"; |
725 | if ($link['tags']!='') // Adding tags to each ATOM entry (as mentioned in ATOM specification) | ||
726 | { | ||
727 | foreach(explode(' ',$link['tags']) as $tag) | ||
728 | { $entries.='<category scheme="'.htmlspecialchars($pageaddr,ENT_QUOTES).'" term="'.htmlspecialchars($tag,ENT_QUOTES).'" />'."\n"; } | ||
729 | } | ||
730 | $entries.="</entry>\n"; | ||
689 | $i++; | 731 | $i++; |
690 | } | 732 | } |
691 | $feed='<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom">'; | 733 | $feed='<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom">'; |
692 | $feed.='<title>'.htmlspecialchars($GLOBALS['title']).'</title>'; | 734 | $feed.='<title>'.htmlspecialchars($GLOBALS['title']).'</title>'; |
693 | if (!$GLOBALS['config']['HIDE_TIMESTAMPS'] || isLoggedIn()) $feed.='<updated>'.htmlspecialchars($latestDate).'</updated>'; | 735 | if (!$GLOBALS['config']['HIDE_TIMESTAMPS'] || isLoggedIn()) $feed.='<updated>'.htmlspecialchars($latestDate).'</updated>'; |
694 | $feed.='<link href="'.htmlspecialchars($pageaddr).'" />'; | 736 | $feed.='<link rel="self" href="'.htmlspecialchars($pageaddr).'" />'; |
737 | if (!empty($GLOBALS['config']['PUBSUBHUB_URL'])) | ||
738 | { | ||
739 | $feed.='<!-- PubSubHubbub Discovery -->'; | ||
740 | $feed.='<link rel="hub" href="'.htmlspecialchars($GLOBALS['config']['PUBSUBHUB_URL']).'" />'; | ||
741 | $feed.='<!-- End Of PubSubHubbub Discovery -->'; | ||
742 | } | ||
695 | $feed.='<author><uri>'.htmlspecialchars($pageaddr).'</uri></author>'; | 743 | $feed.='<author><uri>'.htmlspecialchars($pageaddr).'</uri></author>'; |
696 | $feed.='<id>'.htmlspecialchars($pageaddr).'</id>'."\n\n"; // Yes, I know I should use a real IRI (RFC3987), but the site URL will do. | 744 | $feed.='<id>'.htmlspecialchars($pageaddr).'</id>'."\n\n"; // Yes, I know I should use a real IRI (RFC3987), but the site URL will do. |
697 | $feed.=$entries; | 745 | $feed.=$entries; |
@@ -747,13 +795,14 @@ function renderPage() | |||
747 | elseif (!empty($_GET['searchtags'])) $linksToDisplay = $LINKSDB->filterTags(trim($_GET['searchtags'])); | 795 | elseif (!empty($_GET['searchtags'])) $linksToDisplay = $LINKSDB->filterTags(trim($_GET['searchtags'])); |
748 | else $linksToDisplay = $LINKSDB; | 796 | else $linksToDisplay = $LINKSDB; |
749 | $body=''; | 797 | $body=''; |
798 | |||
750 | foreach($linksToDisplay as $link) | 799 | foreach($linksToDisplay as $link) |
751 | { | 800 | { |
752 | $thumb=thumbnail($link['url']); | 801 | $href='?'.htmlspecialchars(smallhash($link['linkdate']),ENT_QUOTES); |
802 | $thumb=thumbnail($link['url'],$href); | ||
753 | if ($thumb!='') | 803 | if ($thumb!='') |
754 | { | 804 | { |
755 | $url=htmlspecialchars($link['url'],ENT_QUOTES); | 805 | $body.='<div class="picwall_pictureframe">'.$thumb.'<a href="'.$href.'"><span class="info">'.htmlspecialchars($link['title']).'</span></a></div>'; |
756 | $body.='<div class="picwall_pictureframe">'.$thumb.'<a href="'.$url.'"><span class="info">'.htmlspecialchars($link['title']).'</span></a></div>'; | ||
757 | 806 | ||
758 | } | 807 | } |
759 | } | 808 | } |
@@ -831,15 +880,15 @@ function renderPage() | |||
831 | // Show login screen, then redirect to ?post=... | 880 | // Show login screen, then redirect to ?post=... |
832 | if (isset($_GET['post'])) | 881 | if (isset($_GET['post'])) |
833 | { | 882 | { |
834 | header('Location: ?do=login&post='.urlencode($_GET['post']).(isset($_GET['title'])?'&title='.urlencode($_GET['title']):'').(isset($_GET['source'])?'&source='.urlencode($_GET['source']):'')); // Redirect to login page, then back to post link. | 883 | header('Location: ?do=login&post='.urlencode($_GET['post']).(iset($_GET['title'])?'&title='.urlencode($_GET['title']):'').(isset($_GET['source'])?'&source='.urlencode($_GET['source']):'')); // Redirect to login page, then back to post link. |
835 | exit; | 884 | exit; |
836 | } | 885 | } |
837 | 886 | ||
838 | // Show search form and display list of links. | 887 | // Show search form and display list of links. |
839 | $searchform=<<<HTML | 888 | $searchform=<<<HTML |
840 | <div id="headerform" style="width:100%; white-space:nowrap;";> | 889 | <div id="headerform" style="width:100%; white-space:nowrap;";> |
841 | <form method="GET" name="searchform" style="display:inline;"><input type="text" name="searchterm" style="width:50%" value=""> <input type="submit" value="Search" class="bigbutton"></form> | 890 | <form method="GET" class="searchform" name="searchform" style="display:inline;"><input type="text" name="searchterm" style="width:30%" value=""> <input type="submit" value="Search" class="bigbutton"></form> |
842 | <form method="GET" name="tagfilter" style="display:inline;padding-left:24px;"><input type="text" name="searchtags" id="searchtags" style="width:20%" value=""> <input type="submit" value="Filter by tag" class="bigbutton"></form> | 891 | <form method="GET" class="tagfilter" name="tagfilter" style="display:inline;margin-left:24px;"><input type="text" name="searchtags" id="searchtags" style="width:10%" value=""> <input type="submit" value="Filter by tag" class="bigbutton"></form> |
843 | </div> | 892 | </div> |
844 | HTML; | 893 | HTML; |
845 | $data = array('pageheader'=>$searchform,'body'=>templateLinkList(),'onload'=>''); | 894 | $data = array('pageheader'=>$searchform,'body'=>templateLinkList(),'onload'=>''); |
@@ -856,13 +905,13 @@ HTML; | |||
856 | // The javascript code for the bookmarklet: | 905 | // The javascript code for the bookmarklet: |
857 | $changepwd = ($GLOBALS['config']['OPEN_SHAARLI'] ? '' : '<a href="?do=changepasswd"><b>Change password</b></a> - Change your password.<br><br>' ); | 906 | $changepwd = ($GLOBALS['config']['OPEN_SHAARLI'] ? '' : '<a href="?do=changepasswd"><b>Change password</b></a> - Change your password.<br><br>' ); |
858 | $toolbar= <<<HTML | 907 | $toolbar= <<<HTML |
859 | <div id="headerform"><br> | 908 | <div id="toolsdiv"><br> |
860 | {$changepwd} | 909 | {$changepwd} |
861 | <a href="?do=configure"><b>Configure your Shaarli</b></a> - Change Title, timezone...<br><br> | 910 | <a href="?do=configure"><b>Configure your Shaarli</b></a> - Change Title, timezone...<br><br> |
862 | <a href="?do=changetag"><b>Rename/delete tags</b></a> - Rename or delete a tag in all links.<br><br> | 911 | <a href="?do=changetag"><b>Rename/delete tags</b></a> - Rename or delete a tag in all links.<br><br> |
863 | <a href="?do=import"><b>Import</b></a> - Import Netscape html bookmarks (as exported from Firefox, Chrome, Opera, delicious...)<br><br> | 912 | <a href="?do=import"><b>Import</b></a> - Import Netscape html bookmarks (as exported from Firefox, Chrome, Opera, delicious...)<br><br> |
864 | <a href="?do=export"><b>Export</b></a> - Export Netscape html bookmarks (which can be imported in Firefox, Chrome, Opera, delicious...)<br><br> | 913 | <a href="?do=export"><b>Export</b></a> - Export Netscape html bookmarks (which can be imported in Firefox, Chrome, Opera, delicious...)<br><br> |
865 | <a class="smallbutton" style="color:black;" onclick="alert('Drag this link to your bookmarks toolbar, or right-click it and choose Bookmark This Link...');return false;" href="javascript:javascript:(function(){var%20url%20=%20location.href;var%20title%20=%20document.title%20||%20url;window.open('{$pageabsaddr}?post='%20+%20encodeURIComponent(url)+'&title='%20+%20encodeURIComponent(title)+'&source=bookmarklet','_blank','menubar=no,height=400,width=608,toolbar=no,scrollbars=no,status=no');})();">Shaare link</a> - Drag this link to your bookmarks toolbar (or right-click it and choose Bookmark This Link....). Then click "Shaare link" button in any page you want to share.<br><br> | 914 | <a class="smallbutton" onclick="alert('Drag this link to your bookmarks toolbar, or right-click it and choose Bookmark This Link...');return false;" href="javascript:javascript:(function(){var%20url%20=%20location.href;var%20title%20=%20document.title%20||%20url;window.open('{$pageabsaddr}?post='%20+%20encodeURIComponent(url)+'&title='%20+%20encodeURIComponent(title)+'&source=bookmarklet','_blank','menubar=no,height=400,width=608,toolbar=no,scrollbars=no,status=no');})();">Shaare link</a> - Drag this link to your bookmarks toolbar (or right-click it and choose Bookmark This Link....). Then click "Shaare link" button in any page you want to share.<br><br> |
866 | </div> | 915 | </div> |
867 | HTML; | 916 | HTML; |
868 | $data = array('pageheader'=>$toolbar,'body'=>'','onload'=>''); | 917 | $data = array('pageheader'=>$toolbar,'body'=>'','onload'=>''); |
@@ -892,7 +941,7 @@ HTML; | |||
892 | { | 941 | { |
893 | $token = getToken(); | 942 | $token = getToken(); |
894 | $changepwdform= <<<HTML | 943 | $changepwdform= <<<HTML |
895 | <form method="POST" action="" name="changepasswordform" style="padding:10 10 10 10;"> | 944 | <form method="POST" action="" name="changepasswordform" id="changepasswordform"> |
896 | Old password: <input type="password" name="oldpassword"> | 945 | Old password: <input type="password" name="oldpassword"> |
897 | New password: <input type="password" name="setpassword"> | 946 | New password: <input type="password" name="setpassword"> |
898 | <input type="hidden" name="token" value="{$token}"> | 947 | <input type="hidden" name="token" value="{$token}"> |
@@ -951,7 +1000,7 @@ HTML; | |||
951 | { | 1000 | { |
952 | $token = getToken(); | 1001 | $token = getToken(); |
953 | $changetagform = <<<HTML | 1002 | $changetagform = <<<HTML |
954 | <form method="POST" action="" name="changetag" style="padding:10 10 10 10;"> | 1003 | <form method="POST" action="" name="changetag" id="changetag"> |
955 | <input type="hidden" name="token" value="{$token}"> | 1004 | <input type="hidden" name="token" value="{$token}"> |
956 | Tag: <input type="text" name="fromtag" id="fromtag"> | 1005 | Tag: <input type="text" name="fromtag" id="fromtag"> |
957 | <input type="text" name="totag" style="margin-left:40px;"><input type="submit" name="renametag" value="Rename tag" class="bigbutton"> | 1006 | <input type="text" name="totag" style="margin-left:40px;"><input type="submit" name="renametag" value="Rename tag" class="bigbutton"> |
@@ -976,6 +1025,7 @@ HTML; | |||
976 | $LINKSDB[$key]=$value; | 1025 | $LINKSDB[$key]=$value; |
977 | } | 1026 | } |
978 | $LINKSDB->savedb(); // save to disk | 1027 | $LINKSDB->savedb(); // save to disk |
1028 | pubsubhub(); | ||
979 | invalidateCaches(); | 1029 | invalidateCaches(); |
980 | echo '<script language="JavaScript">alert("Tag was removed from '.count($linksToAlter).' links.");document.location=\'?\';</script>'; | 1030 | echo '<script language="JavaScript">alert("Tag was removed from '.count($linksToAlter).' links.");document.location=\'?\';</script>'; |
981 | exit; | 1031 | exit; |
@@ -1004,7 +1054,7 @@ HTML; | |||
1004 | if (startswith($_SERVER["QUERY_STRING"],'do=addlink')) | 1054 | if (startswith($_SERVER["QUERY_STRING"],'do=addlink')) |
1005 | { | 1055 | { |
1006 | $onload = 'onload="document.addform.post.focus();"'; | 1056 | $onload = 'onload="document.addform.post.focus();"'; |
1007 | $addform= '<div id="headerform"><form method="GET" action="" name="addform"><input type="text" name="post" style="width:70%;"> <input type="submit" value="Add link" class="bigbutton"></div>'; | 1057 | $addform= '<div id="headerform"><form method="GET" action="" name="addform" class="addform"><input type="text" name="post" style="width:50%;"> <input type="submit" value="Add link" class="bigbutton"></div>'; |
1008 | $data = array('pageheader'=>$addform,'body'=>'','onload'=>$onload); | 1058 | $data = array('pageheader'=>$addform,'body'=>'','onload'=>$onload); |
1009 | templatePage($data); | 1059 | templatePage($data); |
1010 | exit; | 1060 | exit; |
@@ -1075,9 +1125,9 @@ HTML; | |||
1075 | $url=$_GET['post']; | 1125 | $url=$_GET['post']; |
1076 | 1126 | ||
1077 | // We remove the annoying parameters added by FeedBurner and GoogleFeedProxy (?utm_source=...) | 1127 | // We remove the annoying parameters added by FeedBurner and GoogleFeedProxy (?utm_source=...) |
1078 | $i=strpos($url,'&utm_source='); if ($i) $url=substr($url,0,$i); | 1128 | $i=strpos($url,'&utm_source='); if ($i!==false) $url=substr($url,0,$i); |
1079 | $i=strpos($url,'?utm_source='); if ($i) $url=substr($url,0,$i); | 1129 | $i=strpos($url,'?utm_source='); if ($i!==false) $url=substr($url,0,$i); |
1080 | $i=strpos($url,'#xtor=RSS-'); if ($i) $url=substr($url,0,$i); | 1130 | $i=strpos($url,'#xtor=RSS-'); if ($i!==false) $url=substr($url,0,$i); |
1081 | 1131 | ||
1082 | $link_is_new = false; | 1132 | $link_is_new = false; |
1083 | $link = $LINKSDB->getLinkFromUrl($url); // Check if URL is not already in database (in this case, we will edit the existing link) | 1133 | $link = $LINKSDB->getLinkFromUrl($url); // Check if URL is not already in database (in this case, we will edit the existing link) |
@@ -1093,7 +1143,7 @@ HTML; | |||
1093 | { | 1143 | { |
1094 | list($status,$headers,$data) = getHTTP($url,4); // Short timeout to keep the application responsive. | 1144 | list($status,$headers,$data) = getHTTP($url,4); // Short timeout to keep the application responsive. |
1095 | // FIXME: Decode charset according to specified in either 1) HTTP response headers or 2) <head> in html | 1145 | // FIXME: Decode charset according to specified in either 1) HTTP response headers or 2) <head> in html |
1096 | if (strpos($status,'200 OK')) $title=html_entity_decode(html_extract_title($data),ENT_QUOTES,'UTF-8'); | 1146 | if (strpos($status,'200 OK')!==false) $title=html_entity_decode(html_extract_title($data),ENT_QUOTES,'UTF-8'); |
1097 | } | 1147 | } |
1098 | if ($url=='') $url='?'.smallHash($linkdate); // In case of empty URL, this is just a text (with a link that point to itself) | 1148 | if ($url=='') $url='?'.smallHash($linkdate); // In case of empty URL, this is just a text (with a link that point to itself) |
1099 | $link = array('linkdate'=>$linkdate,'title'=>$title,'url'=>$url,'description'=>$description,'tags'=>$tags,'private'=>0); | 1149 | $link = array('linkdate'=>$linkdate,'title'=>$title,'url'=>$url,'description'=>$description,'tags'=>$tags,'private'=>0); |
@@ -1110,7 +1160,7 @@ HTML; | |||
1110 | if (empty($_GET['what'])) | 1160 | if (empty($_GET['what'])) |
1111 | { | 1161 | { |
1112 | $toolbar= <<<HTML | 1162 | $toolbar= <<<HTML |
1113 | <div id="headerform"><br> | 1163 | <div id="toolsdiv"> |
1114 | <a href="?do=export&what=all"><b>Export all</b></a> - Export all links<br><br> | 1164 | <a href="?do=export&what=all"><b>Export all</b></a> - Export all links<br><br> |
1115 | <a href="?do=export&what=public"><b>Export public</b></a> - Export public links only<br><br> | 1165 | <a href="?do=export&what=public"><b>Export public</b></a> - Export public links only<br><br> |
1116 | <a href="?do=export&what=private"><b>Export private</b></a> - Export private links only<br><br> | 1166 | <a href="?do=export&what=private"><b>Export private</b></a> - Export private links only<br><br> |
@@ -1172,9 +1222,9 @@ HTML; | |||
1172 | $maxfilesize=getMaxFileSize(); | 1222 | $maxfilesize=getMaxFileSize(); |
1173 | $onload = 'onload="document.uploadform.filetoupload.focus();"'; | 1223 | $onload = 'onload="document.uploadform.filetoupload.focus();"'; |
1174 | $uploadform=<<<HTML | 1224 | $uploadform=<<<HTML |
1175 | <div id="headerform"> | 1225 | <div id="uploaddiv"> |
1176 | Import Netscape html bookmarks (as exported from Firefox/Chrome/Opera/delicious/diigo...) (Max: {$maxfilesize} bytes). | 1226 | Import Netscape html bookmarks (as exported from Firefox/Chrome/Opera/delicious/diigo...) (Max: {$maxfilesize} bytes). |
1177 | <form method="POST" action="?do=upload" enctype="multipart/form-data" name="uploadform"> | 1227 | <form method="POST" action="?do=upload" enctype="multipart/form-data" name="uploadform" id="uploadform"> |
1178 | <input type="hidden" name="token" value="{$token}"> | 1228 | <input type="hidden" name="token" value="{$token}"> |
1179 | <input type="file" name="filetoupload" size="80"> | 1229 | <input type="file" name="filetoupload" size="80"> |
1180 | <input type="hidden" name="MAX_FILE_SIZE" value="{$maxfilesize}"> | 1230 | <input type="hidden" name="MAX_FILE_SIZE" value="{$maxfilesize}"> |
@@ -1192,8 +1242,8 @@ HTML; | |||
1192 | // -------- Otherwise, simply display search form and links: | 1242 | // -------- Otherwise, simply display search form and links: |
1193 | $searchform=<<<HTML | 1243 | $searchform=<<<HTML |
1194 | <div id="headerform" style="width:100%; white-space:nowrap;";> | 1244 | <div id="headerform" style="width:100%; white-space:nowrap;";> |
1195 | <form method="GET" name="searchform" style="display:inline;"><input type="text" name="searchterm" style="width:50%" value=""> <input type="submit" value="Search" class="bigbutton"></form> | 1245 | <form method="GET" class="searchform" name="searchform"><input type="text" name="searchterm" style="width:30%" value=""> <input type="submit" value="Search" class="bigbutton"></form> |
1196 | <form method="GET" name="tagfilter" style="display:inline;padding-left:24px;"><input type="text" name="searchtags" id="searchtags" style="width:20%" value=""> <input type="submit" value="Filter by tag" class="bigbutton"></form> | 1246 | <form method="GET" class="tagfilter" name="tagfilter" style="margin-left:24px;"><input type="text" name="searchtags" id="searchtags" style="width:10%" value=""> <input type="submit" value="Filter by tag" class="bigbutton"></form> |
1197 | </div> | 1247 | </div> |
1198 | HTML; | 1248 | HTML; |
1199 | $data = array('pageheader'=>$searchform,'body'=>templateLinkList(),'onload'=>''); | 1249 | $data = array('pageheader'=>$searchform,'body'=>templateLinkList(),'onload'=>''); |
@@ -1362,7 +1412,8 @@ function templateLinkList() | |||
1362 | $link = $linksToDisplay[$keys[$i]]; | 1412 | $link = $linksToDisplay[$keys[$i]]; |
1363 | $description=text2clickable(htmlspecialchars($link['description'])); | 1413 | $description=text2clickable(htmlspecialchars($link['description'])); |
1364 | $title=$link['title']; | 1414 | $title=$link['title']; |
1365 | $classprivate = ($link['private']==0 ? '' : 'class="private"'); | 1415 | $classLi = $i%2!=0 ? '' : 'class="publicLinkHightLight"'; |
1416 | $classprivate = ($link['private']==0 ? $classLi : 'class="private"'); | ||
1366 | if (isLoggedIn()) $actions=' <form method="GET" class="buttoneditform"><input type="hidden" name="edit_link" value="'.$link['linkdate'].'"><input type="submit" value="Edit" class="smallbutton"></form>'; | 1417 | if (isLoggedIn()) $actions=' <form method="GET" class="buttoneditform"><input type="hidden" name="edit_link" value="'.$link['linkdate'].'"><input type="submit" value="Edit" class="smallbutton"></form>'; |
1367 | $tags=''; | 1418 | $tags=''; |
1368 | if ($link['tags']!='') | 1419 | if ($link['tags']!='') |
@@ -1389,19 +1440,24 @@ function templateLinkList() | |||
1389 | $linksperpage = <<<HTML | 1440 | $linksperpage = <<<HTML |
1390 | <div style="float:right; padding-right:5px;"> | 1441 | <div style="float:right; padding-right:5px;"> |
1391 | Links per page: <a href="?linksperpage=20">20</a> <a href="?linksperpage=50">50</a> <a href="?linksperpage=100">100</a> | 1442 | Links per page: <a href="?linksperpage=20">20</a> <a href="?linksperpage=50">50</a> <a href="?linksperpage=100">100</a> |
1392 | <form method="GET" style="display:inline;"><input type="text" name="linksperpage" size="2" style="height:15px;"></form></div> | 1443 | <form method="GET" style="display:inline;" class="linksperpage"><input type="text" name="linksperpage" size="2" style="height:15px;"></form></div> |
1393 | HTML; | 1444 | HTML; |
1394 | $paging = '<div class="paging">'.$linksperpage.$paging.'</div>'; | 1445 | $paging = '<div class="paging">'.$linksperpage.$paging.'</div>'; |
1395 | $linklist='<div id="linklist">'.$paging.$searched.'<ul>'.$linklist.'</ul>'.$paging.'</div>'; | 1446 | $linklist='<div id="linklist">'.$paging.$searched.'<ul>'.$linklist.'</ul>'.$paging.'</div>'; |
1396 | return $linklist; | 1447 | return $linklist; |
1397 | } | 1448 | } |
1398 | 1449 | ||
1399 | // Returns the HTML code to display a thumbnail for a link. | 1450 | // Returns the HTML code to display a thumbnail for a link |
1451 | // with a link to the original URL. | ||
1400 | // Understands various services (youtube.com...) | 1452 | // Understands various services (youtube.com...) |
1401 | function thumbnail($url) | 1453 | // Input: $url = url for which the thumbnail must be found. |
1454 | // $href = if provided, this URL will be followed instead of $url | ||
1455 | function thumbnail($url,$href=false) | ||
1402 | { | 1456 | { |
1403 | if (!$GLOBALS['config']['ENABLE_THUMBNAILS']) return ''; | 1457 | if (!$GLOBALS['config']['ENABLE_THUMBNAILS']) return ''; |
1404 | 1458 | ||
1459 | if ($href==false) $href=$url; | ||
1460 | |||
1405 | // For most hosts, the URL of the thumbnail can be easily deduced from the URL of the link. | 1461 | // For most hosts, the URL of the thumbnail can be easily deduced from the URL of the link. |
1406 | // (eg. http://www.youtube.com/watch?v=spVypYk4kto ---> http://img.youtube.com/vi/spVypYk4kto/default.jpg ) | 1462 | // (eg. http://www.youtube.com/watch?v=spVypYk4kto ---> http://img.youtube.com/vi/spVypYk4kto/default.jpg ) |
1407 | // ^^^^^^^^^^^ ^^^^^^^^^^^ | 1463 | // ^^^^^^^^^^^ ^^^^^^^^^^^ |
@@ -1409,26 +1465,32 @@ function thumbnail($url) | |||
1409 | if ($domain=='youtube.com' || $domain=='www.youtube.com') | 1465 | if ($domain=='youtube.com' || $domain=='www.youtube.com') |
1410 | { | 1466 | { |
1411 | parse_str(parse_url($url,PHP_URL_QUERY), $params); // Extract video ID and get thumbnail | 1467 | parse_str(parse_url($url,PHP_URL_QUERY), $params); // Extract video ID and get thumbnail |
1412 | if (!empty($params['v'])) return '<a href="'.htmlspecialchars($url).'"><img src="http://img.youtube.com/vi/'.htmlspecialchars($params['v']).'/default.jpg" width="120" height="90"></a>'; | 1468 | if (!empty($params['v'])) return '<a href="'.htmlspecialchars($href).'"><img src="http://img.youtube.com/vi/'.htmlspecialchars($params['v']).'/default.jpg" width="120" height="90"></a>'; |
1413 | } | 1469 | } |
1470 | if ($domain=='youtu.be') // Youtube short links | ||
1471 | { | ||
1472 | $path = parse_url($url,PHP_URL_PATH); | ||
1473 | return '<a href="'.htmlspecialchars($href).'"><img src="http://img.youtube.com/vi'.htmlspecialchars($path).'/default.jpg" width="120" height="90"></a>'; | ||
1474 | } | ||
1414 | if ($domain=='imgur.com') | 1475 | if ($domain=='imgur.com') |
1415 | { | 1476 | { |
1416 | $path = parse_url($url,PHP_URL_PATH); | 1477 | $path = parse_url($url,PHP_URL_PATH); |
1417 | if (strpos($path,'/r/')==0) return '<a href="'.htmlspecialchars($url).'"><img src="http://i.imgur.com/'.htmlspecialchars(basename($path)).'s.jpg" width="90" height="90"></a>'; | 1478 | if (startsWith($path,'/a/')) return ''; // Thumbnails for albums are not available. |
1418 | if (strpos($path,'/gallery/')==0) return '<a href="'.htmlspecialchars($url).'"><img src="http://i.imgur.com'.htmlspecialchars(substr($path,8)).'s.jpg" width="90" height="90"></a>'; | 1479 | if (startsWith($path,'/r/')) return '<a href="'.htmlspecialchars($href).'"><img src="http://i.imgur.com/'.htmlspecialchars(basename($path)).'s.jpg" width="90" height="90"></a>'; |
1419 | if (substr_count($path,'/')==1) return '<a href="'.htmlspecialchars($url).'"><img src="http://i.imgur.com/'.htmlspecialchars(substr($path,1)).'s.jpg" width="90" height="90"></a>'; | 1480 | if (startsWith($path,'/gallery/')) return '<a href="'.htmlspecialchars($href).'"><img src="http://i.imgur.com'.htmlspecialchars(substr($path,8)).'s.jpg" width="90" height="90"></a>'; |
1481 | if (substr_count($path,'/')==1) return '<a href="'.htmlspecialchars($href).'"><img src="http://i.imgur.com/'.htmlspecialchars(substr($path,1)).'s.jpg" width="90" height="90"></a>'; | ||
1420 | } | 1482 | } |
1421 | if ($domain=='i.imgur.com') | 1483 | if ($domain=='i.imgur.com') |
1422 | { | 1484 | { |
1423 | $pi = pathinfo(parse_url($url,PHP_URL_PATH)); | 1485 | $pi = pathinfo(parse_url($url,PHP_URL_PATH)); |
1424 | if (!empty($pi['filename'])) return '<a href="'.htmlspecialchars($url).'"><img src="http://i.imgur.com/'.htmlspecialchars($pi['filename']).'s.jpg" width="90" height="90"></a>'; | 1486 | if (!empty($pi['filename'])) return '<a href="'.htmlspecialchars($href).'"><img src="http://i.imgur.com/'.htmlspecialchars($pi['filename']).'s.jpg" width="90" height="90"></a>'; |
1425 | } | 1487 | } |
1426 | if ($domain=='dailymotion.com' || $domain=='www.dailymotion.com') | 1488 | if ($domain=='dailymotion.com' || $domain=='www.dailymotion.com') |
1427 | { | 1489 | { |
1428 | if (strpos($url,'dailymotion.com/video/')) | 1490 | if (strpos($url,'dailymotion.com/video/')!==false) |
1429 | { | 1491 | { |
1430 | $thumburl=str_replace('dailymotion.com/video/','dailymotion.com/thumbnail/video/',$url); | 1492 | $thumburl=str_replace('dailymotion.com/video/','dailymotion.com/thumbnail/video/',$url); |
1431 | return '<a href="'.htmlspecialchars($url).'"><img src="'.htmlspecialchars($thumburl).'" width="120" style="height:auto;"></a>'; | 1493 | return '<a href="'.htmlspecialchars($href).'"><img src="'.htmlspecialchars($thumburl).'" width="120" style="height:auto;"></a>'; |
1432 | } | 1494 | } |
1433 | } | 1495 | } |
1434 | if (endsWith($domain,'.imageshack.us')) | 1496 | if (endsWith($domain,'.imageshack.us')) |
@@ -1437,11 +1499,10 @@ function thumbnail($url) | |||
1437 | if ($ext=='jpg' || $ext=='jpeg' || $ext=='png' || $ext=='gif') | 1499 | if ($ext=='jpg' || $ext=='jpeg' || $ext=='png' || $ext=='gif') |
1438 | { | 1500 | { |
1439 | $thumburl = substr($url,0,strlen($url)-strlen($ext)).'th.'.$ext; | 1501 | $thumburl = substr($url,0,strlen($url)-strlen($ext)).'th.'.$ext; |
1440 | return '<a href="'.htmlspecialchars($url).'"><img src="'.htmlspecialchars($thumburl).'" width="120" style="height:auto;"></a>'; | 1502 | return '<a href="'.htmlspecialchars($href).'"><img src="'.htmlspecialchars($thumburl).'" width="120" style="height:auto;"></a>'; |
1441 | } | 1503 | } |
1442 | } | 1504 | } |
1443 | 1505 | ||
1444 | |||
1445 | // Some other hosts are SLOW AS HELL and usually require an extra HTTP request to get the thumbnail URL. | 1506 | // Some other hosts are SLOW AS HELL and usually require an extra HTTP request to get the thumbnail URL. |
1446 | // So we deport the thumbnail generation in order not to slow down page generation | 1507 | // So we deport the thumbnail generation in order not to slow down page generation |
1447 | // (and we also cache the thumbnail) | 1508 | // (and we also cache the thumbnail) |
@@ -1450,8 +1511,13 @@ function thumbnail($url) | |||
1450 | 1511 | ||
1451 | if ($domain=='flickr.com' || endsWith($domain,'.flickr.com') || $domain=='vimeo.com') | 1512 | if ($domain=='flickr.com' || endsWith($domain,'.flickr.com') || $domain=='vimeo.com') |
1452 | { | 1513 | { |
1514 | if ($domain=='vimeo.com') | ||
1515 | { // Make sure this vimeo url points to a video (/xxx... where xxx is numeric) | ||
1516 | $path = parse_url($url,PHP_URL_PATH); | ||
1517 | if (!preg_match('!/\d+.+?!',$path)) return ''; // This is not a single video URL. | ||
1518 | } | ||
1453 | $sign = hash_hmac('sha256', $url, $GLOBALS['salt']); // We use the salt to sign data (it's random, secret, and specific to each installation) | 1519 | $sign = hash_hmac('sha256', $url, $GLOBALS['salt']); // We use the salt to sign data (it's random, secret, and specific to each installation) |
1454 | return '<a href="'.htmlspecialchars($url).'"><img src="?do=genthumbnail&hmac='.htmlspecialchars($sign).'&url='.urlencode($url).'" width="120" style="height:auto;"></a>'; | 1520 | return '<a href="'.htmlspecialchars($href).'"><img src="?do=genthumbnail&hmac='.htmlspecialchars($sign).'&url='.urlencode($url).'" width="120" style="height:auto;"></a>'; |
1455 | } | 1521 | } |
1456 | 1522 | ||
1457 | // For all other, we try to make a thumbnail of links ending with .jpg/jpeg/png/gif | 1523 | // For all other, we try to make a thumbnail of links ending with .jpg/jpeg/png/gif |
@@ -1461,7 +1527,7 @@ function thumbnail($url) | |||
1461 | if ($ext=='jpg' || $ext=='jpeg' || $ext=='png' || $ext=='gif') | 1527 | if ($ext=='jpg' || $ext=='jpeg' || $ext=='png' || $ext=='gif') |
1462 | { | 1528 | { |
1463 | $sign = hash_hmac('sha256', $url, $GLOBALS['salt']); // We use the salt to sign data (it's random, secret, and specific to each installation) | 1529 | $sign = hash_hmac('sha256', $url, $GLOBALS['salt']); // We use the salt to sign data (it's random, secret, and specific to each installation) |
1464 | return '<a href="'.htmlspecialchars($url).'"><img src="?do=genthumbnail&hmac='.htmlspecialchars($sign).'&url='.urlencode($url).'" width="120" style="height:auto;"></a>'; | 1530 | return '<a href="'.htmlspecialchars($href).'"><img src="?do=genthumbnail&hmac='.htmlspecialchars($sign).'&url='.urlencode($url).'" width="120" style="height:auto;"></a>'; |
1465 | } | 1531 | } |
1466 | return ''; // No thumbnail. | 1532 | return ''; // No thumbnail. |
1467 | 1533 | ||
@@ -1527,12 +1593,13 @@ JS; | |||
1527 | <title>{$pagetitle}</title> | 1593 | <title>{$pagetitle}</title> |
1528 | <link rel="alternate" type="application/rss+xml" href="{$feedurl}?do=rss{$searchcrits}" title="{$filtered_feed}RSS Feed" /> | 1594 | <link rel="alternate" type="application/rss+xml" href="{$feedurl}?do=rss{$searchcrits}" title="{$filtered_feed}RSS Feed" /> |
1529 | <link rel="alternate" type="application/atom+xml" href="{$feedurl}?do=atom{$searchcrits}" title="{$filtered_feed}ATOM Feed" /> | 1595 | <link rel="alternate" type="application/atom+xml" href="{$feedurl}?do=atom{$searchcrits}" title="{$filtered_feed}ATOM Feed" /> |
1596 | <link href="./images/favicon.ico" rel="shortcut icon" type="image/x-icon" /> | ||
1530 | <link type="text/css" rel="stylesheet" href="shaarli.css?version={$version}" /> | 1597 | <link type="text/css" rel="stylesheet" href="shaarli.css?version={$version}" /> |
1531 | {$jsincludes} | 1598 | {$jsincludes} |
1532 | </head> | 1599 | </head> |
1533 | <body {$data['onload']}>{$newversion} | 1600 | <body {$data['onload']}>{$newversion} |
1534 | <div id="pageheader"><div style="float:right; font-style:italic; color:#bbb; text-align:right; padding:0 5 0 0;">Shaare your links...<br>{$linkcount} links</div> | 1601 | <div id="pageheader"><div id="logo" title="Share your links !"></div><div style="float:right; font-style:italic; color:#bbb; text-align:right; padding:0 5 0 0;">Shaare your links...<br>{$linkcount} links</div> |
1535 | <span id="shaarli_title"><a href="?">{$title}</a></span> - <a href="?">Home</a> {$menu} <a href="{$feedurl}?do=rss{$searchcrits}" style="padding-left:30px;">RSS Feed</a> <a href="{$feedurl}?do=atom{$searchcrits}" style="padding-left:10px;">ATOM Feed</a> | 1602 | <span id="shaarli_title"><a href="?">{$title}</a></span> - <a href="?">Home</a> {$menu} <a href="{$feedurl}?do=rss{$searchcrits}">RSS Feed</a> <a href="{$feedurl}?do=atom{$searchcrits}" style="padding-left:10px;">ATOM Feed</a> |
1536 | <a href="?do=tagcloud">Tag cloud</a> <a href="?do=picwall{$searchcrits}">Picture wall</a> | 1603 | <a href="?do=tagcloud">Tag cloud</a> <a href="?do=picwall{$searchcrits}">Picture wall</a> |
1537 | {$data['pageheader']} | 1604 | {$data['pageheader']} |
1538 | </div> | 1605 | </div> |
@@ -1540,7 +1607,7 @@ JS; | |||
1540 | 1607 | ||
1541 | HTML; | 1608 | HTML; |
1542 | $exectime = round(microtime(true)-$STARTTIME,4); | 1609 | $exectime = round(microtime(true)-$STARTTIME,4); |
1543 | echo '<div id="footer"><b><a href="http://sebsauvage.net/wiki/doku.php?id=php:shaarli">Shaarli '.shaarli_version.'</a></b> - The personal, minimalist, super-fast, no-database delicious clone. By sebsauvage.net<br>Who gives a shit that this page was generated in '.$exectime.' seconds ?</div>'; | 1610 | echo '<div id="footer"><b><a href="http://sebsauvage.net/wiki/doku.php?id=php:shaarli">Shaarli '.shaarli_version.'</a></b> - The personal, minimalist, super-fast, no-database delicious clone. By sebsauvage.net. Theme by idleman.fr.<br>Who gives a shit that this page was generated in '.$exectime.' seconds ?</div>'; |
1544 | if (isLoggedIn()) echo '<script language="JavaScript">function confirmDeleteLink() { var agree=confirm("Are you sure you want to delete this link ?"); if (agree) return true ; else return false ; }</script>'; | 1611 | if (isLoggedIn()) echo '<script language="JavaScript">function confirmDeleteLink() { var agree=confirm("Are you sure you want to delete this link ?"); if (agree) return true ; else return false ; }</script>'; |
1545 | echo $jsincludes_bottom.'</body></html>'; | 1612 | echo $jsincludes_bottom.'</body></html>'; |
1546 | } | 1613 | } |
@@ -1614,7 +1681,7 @@ function templateTZform($ptz=false) | |||
1614 | { | 1681 | { |
1615 | if ($tz=='UTC') $tz='UTC/UTC'; | 1682 | if ($tz=='UTC') $tz='UTC/UTC'; |
1616 | $spos = strpos($tz,'/'); | 1683 | $spos = strpos($tz,'/'); |
1617 | if ($spos) | 1684 | if ($spos!==false) |
1618 | { | 1685 | { |
1619 | $continent=substr($tz,0,$spos); $city=substr($tz,$spos+1); | 1686 | $continent=substr($tz,0,$spos); $city=substr($tz,$spos+1); |
1620 | $continents[$continent]=1; | 1687 | $continents[$continent]=1; |
@@ -1768,7 +1835,7 @@ function genThumbnail() | |||
1768 | else // this is a flickr page (html) | 1835 | else // this is a flickr page (html) |
1769 | { | 1836 | { |
1770 | list($httpstatus,$headers,$data) = getHTTP($url,20); // Get the flickr html page. | 1837 | list($httpstatus,$headers,$data) = getHTTP($url,20); // Get the flickr html page. |
1771 | if (strpos($httpstatus,'200 OK')) | 1838 | if (strpos($httpstatus,'200 OK')!==false) |
1772 | { | 1839 | { |
1773 | preg_match('!(http://farm\d+.static.flickr.com/\d+/\d+_\w+_)[^s].jpg!',$data,$matches); | 1840 | preg_match('!(http://farm\d+.static.flickr.com/\d+/\d+_\w+_)[^s].jpg!',$data,$matches); |
1774 | if (!empty($matches[1])) $imageurl=$matches[1].'m.jpg'; | 1841 | if (!empty($matches[1])) $imageurl=$matches[1].'m.jpg'; |
@@ -1777,7 +1844,7 @@ function genThumbnail() | |||
1777 | if ($imageurl!='') | 1844 | if ($imageurl!='') |
1778 | { // Let's download the image. | 1845 | { // Let's download the image. |
1779 | list($httpstatus,$headers,$data) = getHTTP($imageurl,10); // Image is 240x120, so 10 seconds to download should be enough. | 1846 | list($httpstatus,$headers,$data) = getHTTP($imageurl,10); // Image is 240x120, so 10 seconds to download should be enough. |
1780 | if (strpos($httpstatus,'200 OK')) | 1847 | if (strpos($httpstatus,'200 OK')!==false) |
1781 | { | 1848 | { |
1782 | file_put_contents($GLOBALS['config']['CACHEDIR'].'/'.$thumbname,$data); // Save image to cache. | 1849 | file_put_contents($GLOBALS['config']['CACHEDIR'].'/'.$thumbname,$data); // Save image to cache. |
1783 | header('Content-Type: image/jpeg'); | 1850 | header('Content-Type: image/jpeg'); |
@@ -1793,13 +1860,13 @@ function genThumbnail() | |||
1793 | // Maybe we should deport this to javascript ? Example: http://stackoverflow.com/questions/1361149/get-img-thumbnails-from-vimeo/4285098#4285098 | 1860 | // Maybe we should deport this to javascript ? Example: http://stackoverflow.com/questions/1361149/get-img-thumbnails-from-vimeo/4285098#4285098 |
1794 | $vid = substr(parse_url($url,PHP_URL_PATH),1); | 1861 | $vid = substr(parse_url($url,PHP_URL_PATH),1); |
1795 | list($httpstatus,$headers,$data) = getHTTP('http://vimeo.com/api/v2/video/'.htmlspecialchars($vid).'.php',5); | 1862 | list($httpstatus,$headers,$data) = getHTTP('http://vimeo.com/api/v2/video/'.htmlspecialchars($vid).'.php',5); |
1796 | if (strpos($httpstatus,'200 OK')) | 1863 | if (strpos($httpstatus,'200 OK')!==false) |
1797 | { | 1864 | { |
1798 | $t = unserialize($data); | 1865 | $t = unserialize($data); |
1799 | $imageurl = $t[0]['thumbnail_medium']; | 1866 | $imageurl = $t[0]['thumbnail_medium']; |
1800 | // Then we download the image and serve it to our client. | 1867 | // Then we download the image and serve it to our client. |
1801 | list($httpstatus,$headers,$data) = getHTTP($imageurl,10); | 1868 | list($httpstatus,$headers,$data) = getHTTP($imageurl,10); |
1802 | if (strpos($httpstatus,'200 OK')) | 1869 | if (strpos($httpstatus,'200 OK')!==false) |
1803 | { | 1870 | { |
1804 | file_put_contents($GLOBALS['config']['CACHEDIR'].'/'.$thumbname,$data); // Save image to cache. | 1871 | file_put_contents($GLOBALS['config']['CACHEDIR'].'/'.$thumbname,$data); // Save image to cache. |
1805 | header('Content-Type: image/jpeg'); | 1872 | header('Content-Type: image/jpeg'); |
@@ -1811,7 +1878,7 @@ function genThumbnail() | |||
1811 | 1878 | ||
1812 | // For all other domains, we try to download the image and make a thumbnail. | 1879 | // For all other domains, we try to download the image and make a thumbnail. |
1813 | list($httpstatus,$headers,$data) = getHTTP($url,30); // We allow 30 seconds max to download (and downloads are limited to 4 Mb) | 1880 | list($httpstatus,$headers,$data) = getHTTP($url,30); // We allow 30 seconds max to download (and downloads are limited to 4 Mb) |
1814 | if (strpos($httpstatus,'200 OK')) | 1881 | if (strpos($httpstatus,'200 OK')!==false) |
1815 | { | 1882 | { |
1816 | $filepath=$GLOBALS['config']['CACHEDIR'].'/'.$thumbname; | 1883 | $filepath=$GLOBALS['config']['CACHEDIR'].'/'.$thumbname; |
1817 | file_put_contents($filepath,$data); // Save image to cache. | 1884 | file_put_contents($filepath,$data); // Save image to cache. |
@@ -1841,9 +1908,9 @@ function resizeImage($filepath) | |||
1841 | // So we really try to open each image type whatever the extension is. | 1908 | // So we really try to open each image type whatever the extension is. |
1842 | $header=file_get_contents($filepath,false,NULL,0,256); // Read first 256 bytes and try to sniff file type. | 1909 | $header=file_get_contents($filepath,false,NULL,0,256); // Read first 256 bytes and try to sniff file type. |
1843 | $im=false; | 1910 | $im=false; |
1844 | if (strpos($header,'GIF8')==0) $im = imagecreatefromgif($filepath); // Well this is crude, but it should be enough. | 1911 | $i=strpos($header,'GIF8'); if (($i!==false) && ($i==0)) $im = imagecreatefromgif($filepath); // Well this is crude, but it should be enough. |
1845 | if (strpos($header,'PNG')==1) $im = imagecreatefrompng($filepath); | 1912 | $i=strpos($header,'PNG'); if (($i!==false) && ($i==1)) $im = imagecreatefrompng($filepath); |
1846 | if (strpos($header,'JFIF')) $im = imagecreatefromjpeg($filepath); | 1913 | $i=strpos($header,'JFIF'); if ($i!==false) $im = imagecreatefromjpeg($filepath); |
1847 | if (!$im) return false; // Unable to open image (corrupted or not an image) | 1914 | if (!$im) return false; // Unable to open image (corrupted or not an image) |
1848 | $w = imagesx($im); | 1915 | $w = imagesx($im); |
1849 | $h = imagesy($im); | 1916 | $h = imagesy($im); |
diff --git a/shaarli.css b/shaarli.css index e511e0eb..4fc40e5f 100644 --- a/shaarli.css +++ b/shaarli.css | |||
@@ -8,60 +8,221 @@ version: 2.8.2r1 | |||
8 | html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var,optgroup{font-style:inherit;font-weight:inherit;}del,ins{text-decoration:none;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:baseline;}sub{vertical-align:baseline;}legend{color:#000;}input,button,textarea,select,optgroup,option{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;}input,button,textarea,select{*font-size:100%;} | 8 | html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var,optgroup{font-style:inherit;font-weight:inherit;}del,ins{text-decoration:none;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:baseline;}sub{vertical-align:baseline;}legend{color:#000;}input,button,textarea,select,optgroup,option{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;}input,button,textarea,select{*font-size:100%;} |
9 | 9 | ||
10 | body { font-family: "Trebuchet MS",Verdana,Arial,Helvetica,sans-serif; font-size:10pt; background-color: #ffffff; } | 10 | body { font-family: "Trebuchet MS",Verdana,Arial,Helvetica,sans-serif; font-size:10pt; background-color: #ffffff; } |
11 | input { border: 1px solid #aaa; background-color:#F0F0FF; padding: 2 5 2 5; -moz-box-shadow: inset 2px 2px 3px #aaaaaa; -webkit-box-shadow: inset 2px 2px 3px #aaaaaa; box-shadow: inset 2px 2px 3px #aaaaaa; } | 11 | input, textarea { |
12 | textarea { border: 1px solid #aaa; background-color:#F0F0FF; padding: 2 5 2 5; -moz-box-shadow: inset 2px 2px 3px #B2B2C4; -webkit-box-shadow: inset 2px 2px 3px #B2B2C4; box-shadow: inset 2px 2px 3px #B2B2C4; } | 12 | |
13 | background-color: #dedede; | ||
14 | background: -webkit-gradient(linear, 0 0, 0 bottom, from(#dedede), to(#ffffff)); | ||
15 | background: -webkit-linear-gradient(#dedede, #ffffff); | ||
16 | background: -moz-linear-gradient(#dedede, #ffffff); | ||
17 | background: -ms-linear-gradient(#dedede, #ffffff); | ||
18 | background: -o-linear-gradient(#dedede, #ffffff); | ||
19 | background: linear-gradient(#dedede, #ffffff); | ||
20 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); | ||
21 | padding:5px; | ||
22 | border-radius: 5px 5px 5px 5px; | ||
23 | border: none; | ||
24 | color:#000; | ||
25 | |||
26 | } | ||
27 | |||
13 | h1 { font-size:20pt; font-weight:bold; font-style:italic; margin-bottom:20px; } | 28 | h1 { font-size:20pt; font-weight:bold; font-style:italic; margin-bottom:20px; } |
14 | /* I don't give a shit about IE. He can't understand selectors such as input[type='submit']. */ | 29 | /* I don't give a shit about IE. He can't understand selectors such as input[type='submit']. */ |
15 | 30 | ||
16 | /* Buttons */ | 31 | /* Buttons */ |
17 | .bigbutton {border-style:outset;border-width:2px;padding:3px 6px;background-color:rgb(212,212,212);font-family:Tahoma,Verdana,Arial,Helvetica,sans-serif;font-size:8pt;-moz-border-radius:0.5em;border-radius:0.5em;} | 32 | .bigbutton { |
18 | .smallbutton {border-style:outset;border-width:2px;padding:0px 4px;background-color:rgb(212,212,212);font-family:Tahoma,Verdana,Arial,Helvetica,sans-serif;font-size:8pt;-moz-border-radius:0.5em;border-radius:0.5em;} | 33 | background-color: #a0a0a0; |
34 | background: -webkit-gradient(linear, 0 0, 0 bottom, from(#a0a0a0), to(#d4d4d4)); | ||
35 | background: -webkit-linear-gradient(#a0a0a0, #d4d4d4); | ||
36 | background: -moz-linear-gradient(#a0a0a0, #d4d4d4); | ||
37 | background: -ms-linear-gradient(#a0a0a0, #d4d4d4); | ||
38 | background: -o-linear-gradient(#a0a0a0, #d4d4d4); | ||
39 | background: linear-gradient(#a0a0a0, #d4d4d4); | ||
40 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); | ||
41 | padding:0 5px 0 5px; | ||
42 | margin:5px 0 5px 0; | ||
43 | height:25px; | ||
19 | 44 | ||
45 | border-radius: 5px 5px 5px 5px; | ||
46 | -moz-border-radius:5px 5px 5px 5px; | ||
47 | cursor:pointer; | ||
48 | border:none; | ||
49 | border-style:outset; | ||
50 | border-width:2px; | ||
51 | } | ||
52 | .smallbutton { | ||
53 | background-color: #a0a0a0; | ||
54 | background: -webkit-gradient(linear, 0 0, 0 bottom, from(#a0a0a0), to(#d4d4d4)); | ||
55 | background: -webkit-linear-gradient(#a0a0a0, #d4d4d4); | ||
56 | background: -moz-linear-gradient(#a0a0a0, #d4d4d4); | ||
57 | background: -ms-linear-gradient(#a0a0a0, #d4d4d4); | ||
58 | background: -o-linear-gradient(#a0a0a0, #d4d4d4); | ||
59 | background: linear-gradient(#a0a0a0, #d4d4d4); | ||
60 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); | ||
61 | padding:0; | ||
62 | margin:5px 0 5px 0; | ||
63 | border-radius: 5px 5px 5px 5px; | ||
64 | -moz-border-radius:5px 5px 5px 5px; | ||
65 | cursor:pointer; | ||
66 | padding:0 3px 0 3px; | ||
67 | border-style:outset; | ||
68 | border-width:2px; | ||
69 | font-size:8pt; | ||
70 | } | ||
20 | 71 | ||
72 | #pageheader #logo{ | ||
73 | background-image: url('./images/logo.png'); | ||
74 | background-repeat: no-repeat; | ||
75 | float:left; | ||
76 | margin:0 10px 0 10px; | ||
77 | width:105px; | ||
78 | height:55px; | ||
79 | } | ||
21 | #pageheader | 80 | #pageheader |
22 | { | 81 | { |
23 | color:#eee; | 82 | |
24 | border-bottom: 1px solid #aaa; | 83 | background: -webkit-gradient(linear, 0 0, 0 bottom, from(#333333), to(#111111)); |
25 | background-color: #6A6A6A; | 84 | background: -webkit-linear-gradient(#333333, #111111); |
26 | background-image: -webkit-gradient(linear, left top, left bottom, from(#6A6A6A), to(#303030)); /* Saf4+, Chrome */ | 85 | background: -moz-linear-gradient(#333333, #111111); |
27 | background-image: -webkit-linear-gradient(top, #6A6A6A, #303030); /* Chrome 10+, Saf5.1+ */ | 86 | background: -ms-linear-gradient(#333333, #111111); |
28 | background-image: -moz-linear-gradient(top, #6A6A6A, #303030); /* FF3.6 */ | 87 | background: -o-linear-gradient(#333333, #111111); |
29 | background-image: -ms-linear-gradient(top, #6A6A6A, #303030); /* IE10 */ | 88 | background: linear-gradient(#333333, #111111); |
30 | background-image: -o-linear-gradient(top, #6A6A6A, #303030); /* Opera 11.10+ */ | 89 | |
31 | background-image: linear-gradient(top, #6A6A6A, #303030); | 90 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); |
32 | filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#6A6A6A', EndColorStr='#303030'); /* IE6-IE9 */ | 91 | padding:5px 0 5px 0; |
33 | padding: 0 10 5 10; | 92 | width: 100%; |
34 | margin: auto; | 93 | margin: auto; |
94 | } | ||
95 | |||
96 | #pageheader a | ||
97 | { | ||
98 | background: -webkit-gradient(linear, 0 0, 0 bottom, from(#333333), to(#000000)); | ||
99 | background: -webkit-linear-gradient(#333333, #000000); | ||
100 | background: -moz-linear-gradient(#333333, #000000); | ||
101 | background: -ms-linear-gradient(#333333, #000000); | ||
102 | background: -o-linear-gradient(#333333, #000000); | ||
103 | background: linear-gradient(#333333, #000000); | ||
104 | |||
105 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); | ||
106 | padding:5px; | ||
107 | border-radius: 5px 5px 5px 5px; | ||
108 | margin:10px 3px 3px 3px; | ||
109 | color:#A2DD42; | ||
110 | text-decoration:none; | ||
111 | } | ||
112 | |||
113 | .linksperpage,.tagfilter,.searchform,.addform { | ||
114 | background-color: #dedede; | ||
115 | background: -webkit-gradient(linear, 0 0, 0 bottom, from(#dedede), to(#ffffff)); | ||
116 | background: -webkit-linear-gradient(#dedede, #ffffff); | ||
117 | background: -moz-linear-gradient(#dedede, #ffffff); | ||
118 | background: -ms-linear-gradient(#dedede, #ffffff); | ||
119 | background: -o-linear-gradient(#dedede, #ffffff); | ||
120 | background: linear-gradient(#dedede, #ffffff); | ||
121 | display:inline; | ||
122 | |||
123 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); | ||
124 | padding:5px; | ||
125 | border: none; | ||
126 | border-radius: 5px 5px 5px 5px; | ||
127 | margin:10px 3px 3px 3px; | ||
128 | color:#cecece; | ||
129 | } | ||
130 | |||
131 | .linksperpage{ | ||
132 | box-shadow: 0 0 0 rgba(0, 0, 0, 0.5); | ||
133 | padding:3px; | ||
134 | } | ||
135 | |||
136 | .linksperpage input,.tagfilter input, .searchform input, .addform input{ | ||
137 | border:none; | ||
138 | color:#606060; | ||
139 | background:none; | ||
140 | box-shadow:none; | ||
141 | padding:5px; | ||
142 | } | ||
143 | |||
144 | .linksperpage input{ | ||
145 | padding:0; | ||
146 | } | ||
147 | |||
148 | .tagfilter input.bigbutton,.searchform input.bigbutton,.addform input.bigbutton{ | ||
149 | background: -webkit-gradient(linear, 0 0, 0 bottom, from(#dedede), to(#ffffff)); | ||
150 | background: -webkit-linear-gradient(#dedede, #ffffff); | ||
151 | background: -moz-linear-gradient(#dedede, #ffffff); | ||
152 | background: -ms-linear-gradient(#dedede, #ffffff); | ||
153 | background: -o-linear-gradient(#dedede, #ffffff); | ||
154 | background: linear-gradient(#dedede, #ffffff); | ||
155 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); | ||
156 | padding:0 5px 0 5px; | ||
157 | margin:5px 0 5px 0; | ||
158 | height:20px; | ||
159 | border-radius: 5px 5px 5px 5px; | ||
160 | cursor:pointer; | ||
35 | } | 161 | } |
162 | |||
36 | #shaarli_title { font-weight:bold; font-style:italic; } | 163 | #shaarli_title { font-weight:bold; font-style:italic; } |
37 | #shaarli_title a { color: #fff !important; } | 164 | #shaarli_title a { color: #fff !important; } |
38 | #pageheader a:link { color:#bbb; text-decoration:none;} | 165 | |
39 | #pageheader a:visited { color:#bbb; text-decoration:none;} | 166 | #pageheader a:visited { color:#bbb; text-decoration:none;} |
40 | #pageheader a:hover { color:#FFFFC9; text-decoration:none;} | 167 | #pageheader a:hover { color:#FFFFC9; text-decoration:none;} |
41 | #pageheader a:active { color:#bbb; text-decoration:none;} | 168 | #pageheader a:active { color:#bbb; text-decoration:none;} |
42 | #searchcriteria { padding: 4 0 5 5; font-weight:bold;} | 169 | #searchcriteria { padding: 4 0 5 5; font-weight:bold;} |
43 | .paging { background-color:#777; color:#ccc; text-align:center; padding:0 0 3 0; clear:both;} | 170 | .paging { padding:5px;background-color:#777; color:#ccc; text-align:center; clear:both;} |
44 | .paging a:link { color:#ccc; text-decoration:none;} | 171 | .paging a:link { color:#ccc; text-decoration:none;} |
45 | .paging a:visited { color:#ccc; } | 172 | .paging a:visited { color:#ccc; } |
46 | .paging a:hover { color:#FFFFC9; } | 173 | .paging a:hover { color:#FFFFC9; } |
47 | .paging a:active { color:#fff; } | 174 | .paging a:active { color:#fff; } |
48 | #headerform { padding:5 5 5 5; } | 175 | #headerform { color:#ffffff; padding:5 5 5 5; } |
49 | #editlinkform { padding:5 5 5 15px; width:80%; } | 176 | #toolsdiv { color:#ffffff; padding:5 5 5 5; clear:left; } |
50 | #linklist li { padding:4 10 8 20; border-top: 1px solid #bbb; clear:both; } | 177 | #uploaddiv { color:#ffffff; padding:5 5 5 5; clear:left; } |
178 | #editlinkform { color:#ffffff; padding:5 5 5 15px; width:80%; clear:left; } | ||
179 | #linklist li { | ||
180 | padding:4 10 15 20; border-top: 1px solid #bbb; clear:both; | ||
181 | background: -webkit-gradient(linear, 0 0, 0 bottom, from(#F2F2F2), to(#ffffff)); | ||
182 | background: -webkit-linear-gradient(#F2F2F2, #ffffff); | ||
183 | background: -moz-linear-gradient(#F2F2F2, #ffffff); | ||
184 | background: -ms-linear-gradient(#F2F2F2, #ffffff); | ||
185 | background: -o-linear-gradient(#F2F2F2, #ffffff); | ||
186 | background: linear-gradient(#F2F2F2, #ffffff); | ||
187 | } | ||
188 | |||
189 | |||
190 | #linklist li.publicLinkHightLight:hover,#linklist li:hover{ | ||
191 | background: #E9FFCE; | ||
192 | } | ||
51 | #linklist li.private { background-color: #ccc; border-left:8px solid #888; } | 193 | #linklist li.private { background-color: #ccc; border-left:8px solid #888; } |
52 | .linktitle { font-size:14pt; font-weight:bold; } | 194 | .linktitle { font-size:14pt; font-weight:bold; } |
53 | .linktitle a { text-decoration: none; color:#3465A4; } | 195 | .linktitle a { text-decoration: none; color:#80AD48; } |
54 | .linktitle a:hover { color:#F57900; } | 196 | .linktitle a:hover { color:#F57900; } |
55 | .linkdate { font-size:8pt; color:#888; } | 197 | .linkdate { font-size:8pt; color:#888; } |
56 | .linkdate a { text-decoration: none; color:#888; } | 198 | .linkdate a { background-image:url('./images/calendar.png');padding:2px 0 3px 20px;background-repeat:no-repeat;text-decoration: none; color:#E28E3F; } |
57 | .linkdate a:hover { color: #F57900 } | 199 | .linkdate a:hover { color: #F57900 } |
58 | .linkurl { font-size:8pt; color:#4BAA74; } | 200 | .linkurl { font-size:8pt; color:#4BAA74; } |
59 | .linkdescription { color:#000; margin-top:0px; margin-bottom:0px; font-weight:normal; } | 201 | .linkdescription { color:#000; margin-top:0; margin-bottom:0; font-weight:normal; } |
60 | .linkdescription a { text-decoration: none; color:#3465A4; } | 202 | .linkdescription a { text-decoration: none; color:#3465A4; } |
61 | .linkdescription a:hover { color:#F57900; } | 203 | .linkdescription a:hover { color:#F57900; } |
62 | .linktaglist { } | 204 | .linktaglist { padding-top:10px;} |
63 | .linktag { font-size:9pt; color:#777; background-color:#ddd; padding:0 6 0 6; -moz-box-shadow: inset 2px 2px 3px #ffffff; -webkit-box-shadow: inset 2px 2px 3px #ffffff; box-shadow: inset 2px 2px 3px ffffff; | 205 | .linktag { |
64 | border-bottom:1px solid #aaa; border-right:1px solid #aaa; border-radius: 0.3em; } | 206 | |
207 | font-size:9pt; | ||
208 | background: -webkit-gradient(linear, 0 0, 0 bottom, from(#F2F2F2), to(#ffffff)); | ||
209 | background: -webkit-linear-gradient(#F2F2F2, #ffffff); | ||
210 | background: -moz-linear-gradient(#F2F2F2, #ffffff); | ||
211 | background: -ms-linear-gradient(#F2F2F2, #ffffff); | ||
212 | background: -o-linear-gradient(#F2F2F2, #ffffff); | ||
213 | background: linear-gradient(#F2F2F2, #ffffff); | ||
214 | |||
215 | |||
216 | box-shadow: 0 0 2px rgba(0, 0, 0, 0.5); | ||
217 | padding:3px 3px 3px 20px; | ||
218 | height:20px; | ||
219 | border-radius: 3px 3px 3px 3px; | ||
220 | cursor:pointer; | ||
221 | background-image:url('./images/tag_blue.png'); | ||
222 | background-repeat:no-repeat; | ||
223 | background-position:3px center; | ||
224 | background-color:#ffffff; | ||
225 | } | ||
65 | .linktag:hover { border-color: #555573; color:#000; } | 226 | .linktag:hover { border-color: #555573; color:#000; } |
66 | .linktag a { color:#777; text-decoration:none; } | 227 | .linktag a { color:#777; text-decoration:none; } |
67 | .linkshort { font-size:8pt; color:#888; } | 228 | .linkshort { font-size:8pt; color:#888; } |
@@ -72,14 +233,20 @@ border-bottom:1px solid #aaa; border-right:1px solid #aaa; border-radius: 0.3em; | |||
72 | #newversion { background-color: #FFFFA0; color:#000; position:absolute; top:0;right:0; padding:2 7 2 7; font-size:9pt;} | 233 | #newversion { background-color: #FFFFA0; color:#000; position:absolute; top:0;right:0; padding:2 7 2 7; font-size:9pt;} |
73 | #cloudtag { padding-left:10%; padding-right:10%; } | 234 | #cloudtag { padding-left:10%; padding-right:10%; } |
74 | #cloudtag a { color:black; text-decoration:none; } | 235 | #cloudtag a { color:black; text-decoration:none; } |
75 | #installform td { font-size: 10pt; padding:10 5 10 5; } | 236 | #installform td { font-size: 10pt; padding:10 5 10 5; clear:left; } |
76 | #configform td { color:#ccc; font-size: 10pt; padding:10 5 10 5; } | 237 | #changepasswordform { color:#ccc; padding:10 5 10 5; clear:left; } |
238 | #changetag { color:#ccc; padding:10 5 10 5; clear:left; } | ||
239 | #configform td { color:#ccc; font-size: 10pt; padding:10 5 10 5; } | ||
240 | #configform { color:#ccc; padding:10 5 10 5; clear:left; } | ||
77 | .thumbnail { float:right; margin-left: 10px; } | 241 | .thumbnail { float:right; margin-left: 10px; } |
78 | /* If you want thumbnails on the left: | 242 | /* If you want thumbnails on the left: |
79 | .thumbnail { float:left; margin-right: 10px; } | 243 | .thumbnail { float:left; margin-right: 10px; } |
80 | .linkcontainer { position: static; margin-left:130px; } | 244 | .linkcontainer { position: static; margin-left:130px; } |
81 | */ | 245 | */ |
82 | 246 | ||
247 | |||
248 | |||
249 | |||
83 | /* --- Picture wall CSS --- */ | 250 | /* --- Picture wall CSS --- */ |
84 | #picwall_container { color:#fff; background-color:#000; } | 251 | #picwall_container { color:#fff; background-color:#000; } |
85 | .picwall_pictureframe { z-index:5; position:relative; display:table-cell; vertical-align:middle;width:90px; height:90px; overflow:hidden; text-align:center; float:left; } | 252 | .picwall_pictureframe { z-index:5; position:relative; display:table-cell; vertical-align:middle;width:90px; height:90px; overflow:hidden; text-align:center; float:left; } |
@@ -98,7 +265,7 @@ border-bottom:1px solid #aaa; border-right:1px solid #aaa; border-radius: 0.3em; | |||
98 | text-align: left; | 265 | text-align: left; |
99 | background-color: transparent; | 266 | background-color: transparent; |
100 | background-color: rgba(0, 0, 0, 0.4); /* FF3+, Saf3+, Opera 10.10+, Chrome, IE9 */ | 267 | background-color: rgba(0, 0, 0, 0.4); /* FF3+, Saf3+, Opera 10.10+, Chrome, IE9 */ |
101 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#66000000,endColorstr=#66000000); /* IE6–IE9 */ | 268 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#66000000,endColorstr=#66000000); /* IE6–IE9 */ |
102 | text-shadow:2px 2px 1px #000000; | 269 | text-shadow:2px 2px 1px #000000; |
103 | } | 270 | } |
104 | 271 | ||
@@ -106,6 +273,10 @@ text-shadow:2px 2px 1px #000000; | |||
106 | .ui-autocomplete { background-color:#fff; padding-left:5px;} | 273 | .ui-autocomplete { background-color:#fff; padding-left:5px;} |
107 | .ui-state-hover { background-color: #604dff; color:#fff; } | 274 | .ui-state-hover { background-color: #604dff; color:#fff; } |
108 | 275 | ||
276 | #linklist li.publicLinkHightLight{ | ||
277 | background: #ffffff; | ||
278 | } | ||
279 | |||
109 | @media print { | 280 | @media print { |
110 | html {border:none;background:#fff!important;color:#000!important;} | 281 | html {border:none;background:#fff!important;color:#000!important;} |
111 | body {font-size:12pt;width:auto!important;margin:auto!important;} | 282 | body {font-size:12pt;width:auto!important;margin:auto!important;} |
@@ -119,4 +290,6 @@ a {color:#000!important;text-decoration:none!important;} | |||
119 | .linkdescription { font-size:10pt;} | 290 | .linkdescription { font-size:10pt;} |
120 | .linktag { border: 1px solid black; font-style:italic; font-size:8pt;} | 291 | .linktag { border: 1px solid black; font-style:italic; font-size:8pt;} |
121 | 292 | ||
293 | |||
294 | |||
122 | } \ No newline at end of file | 295 | } \ No newline at end of file |