From 49583f381f498dbcf694193f88cd1fe7d836ef55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Guillot?= Date: Sat, 8 Feb 2014 14:13:14 -0500 Subject: [PATCH] Improve files organization --- assets/js/all.min.js | 21 + check_setup.php | 11 +- common.php | 22 +- controllers/bookmark.php | 37 + controllers/common.php | 33 +- controllers/config.php | 7 +- controllers/item.php | 30 + controllers/unread.php | 37 - cronjob.php | 4 +- examples/.htaccess | 1 - examples/api_client.php | 42 - examples/mytheme/css/app.css | 19 - examples/mytheme/fonts/Inconsolata-Bold.ttf | Bin 67724 -> 0 bytes .../mytheme/fonts/Inconsolata-Regular.ttf | Bin 84868 -> 0 bytes feed.php | 46 -- index.php | 28 +- jsonrpc.php | 4 +- models/config.php | 33 +- models/feed.php | 51 +- models/item.php | 63 +- schema.php => models/schema.php | 0 models/user.php | 11 +- .../api_client.sh => scripts/api-client.sh | 4 +- make-archive.sh => scripts/make-archive.sh | 4 +- scripts/make-js.sh | 16 + make-tag.sh => scripts/make-tag.sh | 2 +- templates/config.php | 4 +- templates/layout.php | 2 +- themes/bootstrap-light/less/alerts.less | 67 -- themes/bootstrap-light/less/bootstrap.less | 58 -- themes/bootstrap-light/less/buttons.less | 160 ---- themes/bootstrap-light/less/code.less | 56 -- themes/bootstrap-light/less/forms.less | 353 --------- themes/bootstrap-light/less/glyphicons.less | 232 ------ themes/bootstrap-light/less/grid.less | 346 --------- themes/bootstrap-light/less/input-groups.less | 127 --- .../bootstrap-light/less/miniflux-base.less | 336 -------- .../bootstrap-light/less/miniflux-theme.less | 39 - themes/bootstrap-light/less/mixins.less | 723 ------------------ themes/bootstrap-light/less/navs.less | 229 ------ themes/bootstrap-light/less/normalize.less | 396 ---------- themes/bootstrap-light/less/pager.less | 55 -- themes/bootstrap-light/less/pagination.less | 83 -- themes/bootstrap-light/less/panels.less | 148 ---- themes/bootstrap-light/less/print.less | 100 --- .../less/responsive-utilities.less | 220 ------ themes/bootstrap-light/less/scaffolding.less | 130 ---- themes/bootstrap-light/less/tables.less | 236 ------ themes/bootstrap-light/less/theme.less | 232 ------ themes/bootstrap-light/less/type.less | 238 ------ themes/bootstrap-light/less/utilities.less | 42 - themes/bootstrap-light/less/variables.less | 620 --------------- themes/bootswatch-cyborg/less/alerts.less | 67 -- themes/bootswatch-cyborg/less/bootstrap.less | 58 -- themes/bootswatch-cyborg/less/buttons.less | 160 ---- themes/bootswatch-cyborg/less/code.less | 56 -- themes/bootswatch-cyborg/less/forms.less | 353 --------- themes/bootswatch-cyborg/less/glyphicons.less | 232 ------ themes/bootswatch-cyborg/less/grid.less | 346 --------- .../bootswatch-cyborg/less/input-groups.less | 127 --- .../bootswatch-cyborg/less/miniflux-base.less | 336 -------- .../less/miniflux-theme.less | 50 -- themes/bootswatch-cyborg/less/mixins.less | 723 ------------------ themes/bootswatch-cyborg/less/navs.less | 229 ------ themes/bootswatch-cyborg/less/normalize.less | 396 ---------- themes/bootswatch-cyborg/less/pager.less | 55 -- themes/bootswatch-cyborg/less/pagination.less | 83 -- themes/bootswatch-cyborg/less/panels.less | 148 ---- themes/bootswatch-cyborg/less/print.less | 100 --- .../less/responsive-utilities.less | 220 ------ .../bootswatch-cyborg/less/scaffolding.less | 130 ---- themes/bootswatch-cyborg/less/tables.less | 236 ------ themes/bootswatch-cyborg/less/theme.less | 232 ------ themes/bootswatch-cyborg/less/type.less | 238 ------ themes/bootswatch-cyborg/less/utilities.less | 42 - themes/bootswatch-cyborg/less/variables.less | 620 --------------- vendor/JsonRPC/Client.php | 5 + vendor/JsonRPC/Server.php | 7 +- vendor/PicoDb/Database.php | 24 +- vendor/PicoFarad/Request.php | 31 +- vendor/PicoFarad/Response.php | 8 +- vendor/PicoFarad/Router.php | 73 +- vendor/PicoFarad/Session.php | 4 +- 83 files changed, 354 insertions(+), 10793 deletions(-) create mode 100644 assets/js/all.min.js delete mode 100644 controllers/unread.php delete mode 100644 examples/.htaccess delete mode 100644 examples/api_client.php delete mode 100644 examples/mytheme/css/app.css delete mode 100755 examples/mytheme/fonts/Inconsolata-Bold.ttf delete mode 100755 examples/mytheme/fonts/Inconsolata-Regular.ttf delete mode 100644 feed.php rename schema.php => models/schema.php (100%) rename examples/api_client.sh => scripts/api-client.sh (70%) rename make-archive.sh => scripts/make-archive.sh (89%) create mode 100755 scripts/make-js.sh rename make-tag.sh => scripts/make-tag.sh (87%) delete mode 100644 themes/bootstrap-light/less/alerts.less delete mode 100644 themes/bootstrap-light/less/bootstrap.less delete mode 100644 themes/bootstrap-light/less/buttons.less delete mode 100644 themes/bootstrap-light/less/code.less delete mode 100644 themes/bootstrap-light/less/forms.less delete mode 100644 themes/bootstrap-light/less/glyphicons.less delete mode 100644 themes/bootstrap-light/less/grid.less delete mode 100644 themes/bootstrap-light/less/input-groups.less delete mode 100644 themes/bootstrap-light/less/miniflux-base.less delete mode 100644 themes/bootstrap-light/less/miniflux-theme.less delete mode 100644 themes/bootstrap-light/less/mixins.less delete mode 100644 themes/bootstrap-light/less/navs.less delete mode 100644 themes/bootstrap-light/less/normalize.less delete mode 100644 themes/bootstrap-light/less/pager.less delete mode 100644 themes/bootstrap-light/less/pagination.less delete mode 100644 themes/bootstrap-light/less/panels.less delete mode 100644 themes/bootstrap-light/less/print.less delete mode 100644 themes/bootstrap-light/less/responsive-utilities.less delete mode 100644 themes/bootstrap-light/less/scaffolding.less delete mode 100644 themes/bootstrap-light/less/tables.less delete mode 100644 themes/bootstrap-light/less/theme.less delete mode 100644 themes/bootstrap-light/less/type.less delete mode 100644 themes/bootstrap-light/less/utilities.less delete mode 100644 themes/bootstrap-light/less/variables.less delete mode 100644 themes/bootswatch-cyborg/less/alerts.less delete mode 100644 themes/bootswatch-cyborg/less/bootstrap.less delete mode 100644 themes/bootswatch-cyborg/less/buttons.less delete mode 100644 themes/bootswatch-cyborg/less/code.less delete mode 100644 themes/bootswatch-cyborg/less/forms.less delete mode 100644 themes/bootswatch-cyborg/less/glyphicons.less delete mode 100644 themes/bootswatch-cyborg/less/grid.less delete mode 100644 themes/bootswatch-cyborg/less/input-groups.less delete mode 100644 themes/bootswatch-cyborg/less/miniflux-base.less delete mode 100644 themes/bootswatch-cyborg/less/miniflux-theme.less delete mode 100644 themes/bootswatch-cyborg/less/mixins.less delete mode 100644 themes/bootswatch-cyborg/less/navs.less delete mode 100644 themes/bootswatch-cyborg/less/normalize.less delete mode 100644 themes/bootswatch-cyborg/less/pager.less delete mode 100644 themes/bootswatch-cyborg/less/pagination.less delete mode 100644 themes/bootswatch-cyborg/less/panels.less delete mode 100644 themes/bootswatch-cyborg/less/print.less delete mode 100644 themes/bootswatch-cyborg/less/responsive-utilities.less delete mode 100644 themes/bootswatch-cyborg/less/scaffolding.less delete mode 100644 themes/bootswatch-cyborg/less/tables.less delete mode 100644 themes/bootswatch-cyborg/less/theme.less delete mode 100644 themes/bootswatch-cyborg/less/type.less delete mode 100644 themes/bootswatch-cyborg/less/utilities.less delete mode 100644 themes/bootswatch-cyborg/less/variables.less diff --git a/assets/js/all.min.js b/assets/js/all.min.js new file mode 100644 index 0000000..b3a8804 --- /dev/null +++ b/assets/js/all.min.js @@ -0,0 +1,21 @@ +var Miniflux={};Miniflux.App=function(){return{Run:function(){Miniflux.Event.ListenKeyboardEvents();Miniflux.Event.ListenMouseEvents()},MozillaAuth:function(e){navigator.id.watch({onlogin:function(a){var b=new XMLHttpRequest;b.open("POST","?action="+e+"&token="+a,!0);b.setRequestHeader("Connection","close");b.onload=function(){window.location.href=this.responseText};b.send("token="+a)},onlogout:function(){}});navigator.id.request()}}}(); +Miniflux.Feed=function(){function e(b){if(b=document.getElementById("loading-feed-"+b)){var a=document.createElement("img");a.src="assets/img/refresh.gif";b.appendChild(a)}}function a(){for(var a=document.getElementsByTagName("a"),d=0,e=a.length;dd.length;){var a=b.shift();d.push(a);Miniflux.Feed.Update(a,function(a){a=d.indexOf(a.feed_id);0<=a&&d.splice(a,1);0==b.length&&0==d.length&&(clearInterval(e),window.location.href="?action=unread")})}},100)}}}(); +Miniflux.Item=function(){function e(c){var b=document.getElementById("item-"+c);b||(b=document.getElementById("current-item"),b.getAttribute("data-item-id")!=c&&(b=!1));return b}function a(c){if((c=document.getElementById("bookmark-"+c))&&c.getAttribute("data-reverse-label")){var b=c.innerHTML;c.innerHTML=c.getAttribute("data-reverse-label");c.setAttribute("data-reverse-label",b)}}function b(c){if(c=document.getElementById("status-"+c)){var b=c.innerHTML;c.innerHTML=c.getAttribute("data-reverse-label"); +c.setAttribute("data-reverse-label",b)}}function d(c){Miniflux.Nav.SelectNextItem();c.parentNode.removeChild(c);if(c=document.getElementById("page-counter"))counter=parseInt(c.textContent.trim(),10)-1,0==counter?window.location="?action=unread":(c.textContent=counter+" ",document.title="miniflux ("+counter+")",document.getElementById("nav-counter").textContent="("+counter+")")}function f(c){var a=new XMLHttpRequest;a.onload=function(){if(Miniflux.Nav.IsListing()){var a=e(c);if(a)if(a.getAttribute("data-hide"))d(a); +else{a.setAttribute("data-item-status","read");b(c);if(a=document.getElementById("show-"+c)){a.className="read";var h=document.createElement("span");h.id="read-icon-"+c;h.appendChild(document.createTextNode("\u2611 "));a.parentNode.insertBefore(h,a)}(a=document.getElementById("status-"+c))&&a.setAttribute("data-action","mark-unread")}}};a.open("POST","?action=mark-item-read&id="+c,!0);a.send()}function k(c){var a=new XMLHttpRequest;a.onload=function(){if(Miniflux.Nav.IsListing()){var a=e(c);if(a)if(a.getAttribute("data-hide"))d(a); +else{a.setAttribute("data-item-status","unread");b(c);if(a=document.getElementById("show-"+c))a.className="";(a=document.getElementById("read-icon-"+c))&&a.parentNode.removeChild(a);(a=document.getElementById("status-"+c))&&a.setAttribute("data-action","mark-read")}}};a.open("POST","?action=mark-item-unread&id="+c,!0);a.send()}function l(c,b){var d=c.getAttribute("data-item-id"),e=new XMLHttpRequest;e.onload=function(){c.setAttribute("data-item-bookmark",b);if(b)if(Miniflux.Nav.IsListing()){if(g= +document.getElementById("show-"+d)){var e=document.createElement("span");e.id="bookmark-icon-"+d;e.appendChild(document.createTextNode("\u2605 "));g.parentNode.insertBefore(e,g)}a(d)}else{var g=document.getElementById("bookmark-"+d);g&&(g.innerHTML="\u2605")}else if(Miniflux.Nav.IsListing())(e=document.getElementById("bookmark-icon-"+d))&&e.parentNode.removeChild(e),a(d);else if(e=document.getElementById("bookmark-"+d))e.innerHTML="\u2606"};e.open("POST","?action=bookmark&id="+d+"&value="+b,!0);e.send()} +return{Get:e,MarkAsRead:f,MarkAsUnread:k,SwitchBookmark:function(c){"1"==c.getAttribute("data-item-bookmark")?l(c,0):l(c,1)},SwitchStatus:function(c){var a=c.getAttribute("data-item-id");c=c.getAttribute("data-item-status");"read"==c?k(a):"unread"==c&&f(a)},ChangeStatus:function(c,a){switch(a){case "read":f(c);break;case "unread":k(c)}},Show:function(c){(c=document.getElementById("show-"+c))&&c.click()},OpenOriginal:function(c){var a=document.getElementById("original-"+c);a&&("unread"==e(c).getAttribute("data-item-status")&& +f(c),a.removeAttribute("data-action"),a.click())},DownloadContent:function(){var a=document.getElementById("download-item");if(a){var b=a.getAttribute("data-item-id"),d=a.getAttribute("data-before-message"),e=document.createElement("img");e.src="./assets/img/refresh.gif";a.innerHTML="";a.className="downloading";a.appendChild(e);a.appendChild(document.createTextNode(" "+d));var f=new XMLHttpRequest;f.onload=function(){var b=JSON.parse(f.responseText);if(b.result){var d=document.getElementById("item-content"); +d&&(d.innerHTML=b.content);a&&(b=a.getAttribute("data-after-message"),a.innerHTML="",a.appendChild(document.createTextNode(" "+b)))}else a&&(b=a.getAttribute("data-failure-message"),a.innerHTML="",a.appendChild(document.createTextNode(" "+b)))};f.open("POST","?action=download-item&id="+b,!0);f.send()}},MarkListingAsRead:function(a){for(var b=document.getElementsByTagName("article"),d=[],e=0,f=b.length;ed-(a.offsetTop+a.offsetHeight)||d-a.offsetTop>document.documentElement.clientHeight)&&window.scrollTo(0,a.offsetTop-10)}function a(){return document.getElementById("listing")?!0:!1}return{GetCurrentItem:function(){return document.getElementById("current-item")},GetCurrentItemId:function(){var a=Miniflux.Nav.GetCurrentItem();return a?a.getAttribute("data-item-id"):null},OpenNextPage:function(){var a=document.getElementById("next-page"); +a&&a.click()},OpenPreviousPage:function(){var a=document.getElementById("previous-page");a&&a.click()},SelectNextItem:function(){var b=document.getElementById("next-item");if(b)b.click();else if(a())if(b=document.getElementsByTagName("article"),document.getElementById("current-item"))for(var d=0,f=b.length;d 'sqlite', diff --git a/controllers/bookmark.php b/controllers/bookmark.php index cae52e8..28c737b 100644 --- a/controllers/bookmark.php +++ b/controllers/bookmark.php @@ -1,5 +1,7 @@ t('Bookmarks').' ('.$nb_items.')' ))); }); + +// Display bookmark feeds +Router\get_action('bookmark-feed', function() { + + // Check token + $feed_token = Model\Config\get('feed_token'); + $request_token = Request\param('token'); + + if ($feed_token !== $request_token) { + Response\text('Access Forbidden', 403); + } + + // Build Feed + $writer = new PicoFeed\Writers\Atom; + $writer->title = t('Bookmarks').' - Miniflux'; + $writer->site_url = Helper\get_current_base_url(); + $writer->feed_url = $writer->site_url.'?action=bookmark-feed&token='.urlencode($feed_token); + + $bookmarks = Model\Item\get_bookmarks(); + + foreach ($bookmarks as $bookmark) { + + $article = Model\Item\get($bookmark['id']); + + $writer->items[] = array( + 'id' => $article['id'], + 'title' => $article['title'], + 'updated' => $article['updated'], + 'url' => $article['url'], + 'content' => $article['content'], + ); + } + + Response\xml($writer->execute()); +}); diff --git a/controllers/common.php b/controllers/common.php index b8c61af..f5fd2bc 100644 --- a/controllers/common.php +++ b/controllers/common.php @@ -1,29 +1,17 @@ 'more'))); diff --git a/controllers/config.php b/controllers/config.php index 06f979a..7599eda 100644 --- a/controllers/config.php +++ b/controllers/config.php @@ -5,6 +5,7 @@ use PicoFarad\Response; use PicoFarad\Request; use PicoFarad\Session; use PicoTools\Template; +use PicoDb\Database; // Re-generate tokens Router\get_action('generate-tokens', function() { @@ -16,7 +17,7 @@ Router\get_action('generate-tokens', function() { // Optimize the database manually Router\get_action('optimize-db', function() { - \PicoTools\singleton('db')->getConnection()->exec('VACUUM'); + Database::get('db')->getConnection()->exec('VACUUM'); Response\redirect('?action=config'); }); @@ -65,14 +66,14 @@ Router\post_action('config', function() { Response\html(Template\layout('config', array( 'errors' => $errors, - 'values' => $values, + 'values' => Model\Config\get_all(), 'db_size' => filesize(DB_FILENAME), 'languages' => Model\Config\get_languages(), 'autoflush_options' => Model\Config\get_autoflush_options(), 'paging_options' => Model\Config\get_paging_options(), 'theme_options' => Model\Config\get_themes(), 'sorting_options' => Model\Config\get_sorting_directions(), - 'redirect_nothing_to_read' => Model\Config\get_nothing_to_read_redirections(), + 'redirect_nothing_to_read_options' => Model\Config\get_nothing_to_read_redirections(), 'menu' => 'config', 'title' => t('Preferences') ))); diff --git a/controllers/item.php b/controllers/item.php index c80cf5e..188c164 100644 --- a/controllers/item.php +++ b/controllers/item.php @@ -6,6 +6,36 @@ use PicoFarad\Request; use PicoFarad\Session; use PicoTools\Template; +// Display unread items +Router\get_action('unread', function() { + + Model\Item\autoflush(); + + $order = Request\param('order', 'updated'); + $direction = Request\param('direction', Model\Config\get('items_sorting_direction')); + $offset = Request\int_param('offset', 0); + $items = Model\Item\get_all('unread', $offset, Model\Config\get('items_per_page'), $order, $direction); + $nb_items = Model\Item\count_by_status('unread'); + + if ($nb_items === 0) { + + $action = Model\Config\get('redirect_nothing_to_read'); + Response\redirect('?action='.$action.'¬hing_to_read=1'); + } + + Response\html(Template\layout('unread_items', array( + 'order' => $order, + 'direction' => $direction, + 'items' => $items, + 'nb_items' => $nb_items, + 'nb_unread_items' => $nb_items, + 'offset' => $offset, + 'items_per_page' => Model\Config\get('items_per_page'), + 'title' => 'Miniflux ('.$nb_items.')', + 'menu' => 'unread' + ))); +}); + // Show item Router\get_action('show', function() { diff --git a/controllers/unread.php b/controllers/unread.php deleted file mode 100644 index 79237f0..0000000 --- a/controllers/unread.php +++ /dev/null @@ -1,37 +0,0 @@ - $order, - 'direction' => $direction, - 'items' => $items, - 'nb_items' => $nb_items, - 'nb_unread_items' => $nb_items, - 'offset' => $offset, - 'items_per_page' => Model\Config\get('items_per_page'), - 'title' => 'Miniflux ('.$nb_items.')', - 'menu' => 'unread' - ))); -}); diff --git a/cronjob.php b/cronjob.php index 5620b8c..14393bd 100644 --- a/cronjob.php +++ b/cronjob.php @@ -1,6 +1,6 @@ = $call_interval) { - $feeds_count = \PicoTools\singleton('db')->table('feeds')->count(); + $feeds_count = PicoDb\Database::get('db')->table('feeds')->count(); $limit = ceil($feeds_count / ($update_interval / $call_interval)); } diff --git a/examples/.htaccess b/examples/.htaccess deleted file mode 100644 index 14249c5..0000000 --- a/examples/.htaccess +++ /dev/null @@ -1 +0,0 @@ -Deny from all \ No newline at end of file diff --git a/examples/api_client.php b/examples/api_client.php deleted file mode 100644 index 9ce12e8..0000000 --- a/examples/api_client.php +++ /dev/null @@ -1,42 +0,0 @@ -authentication('admin', 'EF8goVO/8YUxcyt'); - -$result = $client->execute('feed.create', array('url' => 'http://bbc.co.uk/news')); -var_dump($result); - -$result = $client->execute('feed.list'); -print_r($result); - -$feed_id = $result[0]['id']; - -$result = $client->execute('feed.update', array('feed_id' => $feed_id)); -var_dump($result); - -$result = $client->execute('feed.info', array('feed_id' => $feed_id)); -print_r($result); - -$result = $client->execute('feed.delete', array('feed_id' => $feed_id)); -var_dump($result); - -$result = $client->execute('item.list_read'); -print_r($result); - -$result = $client->execute('item.list_unread', array('offset' => 5, 'limit' => 2)); -print_r($result); - -if (count($result)) { - - $result = $client->execute('item.bookmark.create', array('item_id' => $result[0]['id'])); - var_dump($result); -} - -$result = $client->execute('item.bookmark.list'); -print_r($result); - -var_dump($client->execute('item.set_list_status', array('status' => 'read', 'items' => array('57cdb841', '8ef6744e')))); diff --git a/examples/mytheme/css/app.css b/examples/mytheme/css/app.css deleted file mode 100644 index daa6372..0000000 --- a/examples/mytheme/css/app.css +++ /dev/null @@ -1,19 +0,0 @@ -/* Basic example theme */ -/* Indentation: 4 spaces - Line Endings: Unix */ - -/* Import the original stylesheet if you want, it's up to you... */ -@import url("../../../assets/css/app.css"); - -@font-face { - font-family: Inconsolata; - src: url(../fonts/Inconsolata-Regular.ttf); -} - -body { - margin: 0; - max-width: 90%; - margin-left: 100px; - padding-left: 10px; - border-left: 5px solid #000; - font-family: 'Inconsolata', sans-serif; -} diff --git a/examples/mytheme/fonts/Inconsolata-Bold.ttf b/examples/mytheme/fonts/Inconsolata-Bold.ttf deleted file mode 100755 index 15eb5994509f445eae10409588c5ff24ba8c2442..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67724 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 V7^{kuOoD=?fL>(_J^Ui<{|Bv}^Zoz; diff --git a/feed.php b/feed.php deleted file mode 100644 index c467b0c..0000000 --- a/feed.php +++ /dev/null @@ -1,46 +0,0 @@ -title = t('Bookmarks').' - Miniflux'; -$writer->site_url = Helper\get_current_base_url(); -$writer->feed_url = $writer->site_url.'feed.php?token='.urlencode($feed_token); - -$bookmarks = Model\Item\get_bookmarks(); - -foreach ($bookmarks as $bookmark) { - - $article = Model\Item\get($bookmark['id']); - - $writer->items[] = array( - 'id' => $article['id'], - 'title' => $article['title'], - 'updated' => $article['updated'], - 'url' => $article['url'], - 'content' => $article['content'], - ); -} - -Response\xml($writer->execute()); diff --git a/index.php b/index.php index 75f9efc..240f11b 100644 --- a/index.php +++ b/index.php @@ -1,12 +1,20 @@ generate_token(), ); - return \PicoTools\singleton('db')->table('config')->update($values); + return Database::get('db')->table('config')->update($values); } // Save tokens for external authentication function save_auth_token($type, $value) { - return \PicoTools\singleton('db') + return Database::get('db') ->table('config') ->update(array( 'auth_'.$type.'_token' => $value @@ -154,7 +155,7 @@ function save_auth_token($type, $value) // Clear authentication tokens function remove_auth_token($type) { - \PicoTools\singleton('db') + Database::get('db') ->table('config') ->update(array( 'auth_'.$type.'_token' => '' @@ -167,7 +168,7 @@ function remove_auth_token($type) function get($name) { if (! isset($_SESSION)) { - return \PicoTools\singleton('db')->table('config')->findOneColumn($name); + return Database::get('db')->table('config')->findOneColumn($name); } else { @@ -186,7 +187,7 @@ function get($name) // Get all config parameters function get_all() { - return \PicoTools\singleton('db') + return Database::get('db') ->table('config') ->columns( 'username', @@ -261,8 +262,8 @@ function save(array $values) // If the user does not want content of feeds, remove it in previous ones if (isset($values['nocontent']) && (bool) $values['nocontent']) { - \PicoTools\singleton('db')->table('items')->update(array('content' => '')); + Database::get('db')->table('items')->update(array('content' => '')); } - return \PicoTools\singleton('db')->table('config')->update($values); + return Database::get('db')->table('config')->update($values); } diff --git a/models/feed.php b/models/feed.php index 9e53755..10ca05b 100644 --- a/models/feed.php +++ b/models/feed.php @@ -2,23 +2,24 @@ namespace Model\Feed; -require_once 'vendor/PicoFeed/Filter.php'; -require_once 'vendor/PicoFeed/Export.php'; -require_once 'vendor/PicoFeed/Import.php'; -require_once 'vendor/PicoFeed/Reader.php'; -require_once 'vendor/SimpleValidator/Validator.php'; -require_once 'vendor/SimpleValidator/Base.php'; -require_once 'vendor/SimpleValidator/Validators/Required.php'; +require_once __DIR__.'/../vendor/PicoFeed/Filter.php'; +require_once __DIR__.'/../vendor/PicoFeed/Export.php'; +require_once __DIR__.'/../vendor/PicoFeed/Import.php'; +require_once __DIR__.'/../vendor/PicoFeed/Reader.php'; +require_once __DIR__.'/../vendor/SimpleValidator/Validator.php'; +require_once __DIR__.'/../vendor/SimpleValidator/Base.php'; +require_once __DIR__.'/../vendor/SimpleValidator/Validators/Required.php'; use SimpleValidator\Validator; use SimpleValidator\Validators; +use PicoDb\Database; const LIMIT_ALL = -1; // Update feed information function update(array $values) { - return \PicoTools\singleton('db') + return Database::get('db') ->table('feeds') ->eq('id', $values['id']) ->save(array( @@ -43,7 +44,7 @@ function import_opml($content) if ($feeds) { - $db = \PicoTools\singleton('db'); + $db = Database::get('db'); $db->startTransaction(); foreach ($feeds as $feed) { @@ -95,7 +96,7 @@ function create($url, $grabber = false) return false; } - $db = \PicoTools\singleton('db'); + $db = Database::get('db'); if (! $db->table('feeds')->eq('feed_url', $reader->getUrl())->count()) { @@ -133,7 +134,7 @@ function refresh_all($limit = LIMIT_ALL) } // Auto-vacuum for people using the cronjob - \PicoTools\singleton('db')->getConnection()->exec('VACUUM'); + Database::get('db')->getConnection()->exec('VACUUM'); return true; } @@ -170,7 +171,7 @@ function refresh($feed_id) if ($feed['download_content']) { // Don't fetch previous items, only new one - $parser->grabber_ignore_urls = \PicoTools\singleton('db') + $parser->grabber_ignore_urls = Database::get('db') ->table('items') ->eq('feed_id', $feed_id) ->findAllByColumn('url'); @@ -202,7 +203,7 @@ function refresh($feed_id) // Get the list of feeds ID to refresh function get_ids($limit = LIMIT_ALL) { - $table_feeds = \PicoTools\singleton('db')->table('feeds') + $table_feeds = Database::get('db')->table('feeds') ->eq('enabled', 1) ->asc('last_checked'); @@ -216,7 +217,7 @@ function get_ids($limit = LIMIT_ALL) // Get feeds with no item function get_all_empty() { - $feeds = \PicoTools\singleton('db') + $feeds = Database::get('db') ->table('feeds') ->columns('feeds.id', 'feeds.title', 'COUNT(items.id) AS nb_items') ->join('items', 'feed_id', 'id') @@ -237,7 +238,7 @@ function get_all_empty() // Get all feeds function get_all() { - return \PicoTools\singleton('db') + return Database::get('db') ->table('feeds') ->asc('title') ->findAll(); @@ -246,7 +247,7 @@ function get_all() // Get one feed function get($feed_id) { - return \PicoTools\singleton('db') + return Database::get('db') ->table('feeds') ->eq('id', $feed_id) ->findOne(); @@ -255,13 +256,13 @@ function get($feed_id) // Update parsing error column function update_parsing_error($feed_id, $value) { - \PicoTools\singleton('db')->table('feeds')->eq('id', $feed_id)->save(array('parsing_error' => $value)); + Database::get('db')->table('feeds')->eq('id', $feed_id)->save(array('parsing_error' => $value)); } // Update last check date function update_last_checked($feed_id) { - \PicoTools\singleton('db') + Database::get('db') ->table('feeds') ->eq('id', $feed_id) ->save(array( @@ -272,7 +273,7 @@ function update_last_checked($feed_id) // Update Etag and last Modified columns function update_cache($feed_id, $last_modified, $etag) { - \PicoTools\singleton('db') + Database::get('db') ->table('feeds') ->eq('id', $feed_id) ->save(array( @@ -285,37 +286,37 @@ function update_cache($feed_id, $last_modified, $etag) function remove($feed_id) { // Items are removed by a sql constraint - return \PicoTools\singleton('db')->table('feeds')->eq('id', $feed_id)->remove(); + return Database::get('db')->table('feeds')->eq('id', $feed_id)->remove(); } // Remove all feeds function remove_all() { - return \PicoTools\singleton('db')->table('feeds')->remove(); + return Database::get('db')->table('feeds')->remove(); } // Enable a feed (activate refresh) function enable($feed_id) { - return \PicoTools\singleton('db')->table('feeds')->eq('id', $feed_id)->save((array('enabled' => 1))); + return Database::get('db')->table('feeds')->eq('id', $feed_id)->save((array('enabled' => 1))); } // Disable feed function disable($feed_id) { - return \PicoTools\singleton('db')->table('feeds')->eq('id', $feed_id)->save((array('enabled' => 0))); + return Database::get('db')->table('feeds')->eq('id', $feed_id)->save((array('enabled' => 0))); } // Enable content download function enable_grabber($feed_id) { - return \PicoTools\singleton('db')->table('feeds')->eq('id', $feed_id)->save((array('download_content' => 1))); + return Database::get('db')->table('feeds')->eq('id', $feed_id)->save((array('download_content' => 1))); } // Disable content download function disable_grabber($feed_id) { - return \PicoTools\singleton('db')->table('feeds')->eq('id', $feed_id)->save((array('download_content' => 0))); + return Database::get('db')->table('feeds')->eq('id', $feed_id)->save((array('download_content' => 0))); } // Validation for edit diff --git a/models/item.php b/models/item.php index 66480ae..1847fb2 100644 --- a/models/item.php +++ b/models/item.php @@ -2,14 +2,16 @@ namespace Model\Item; -require_once 'vendor/Readability/Readability.php'; -require_once 'vendor/PicoFeed/Grabber.php'; -require_once 'vendor/PicoFeed/Filter.php'; +require_once __DIR__.'/../vendor/Readability/Readability.php'; +require_once __DIR__.'/../vendor/PicoFeed/Grabber.php'; +require_once __DIR__.'/../vendor/PicoFeed/Filter.php'; + +use PicoDb\Database; // Get all items function get_all($status, $offset = null, $limit = null, $order_column = 'updated', $order_direction = 'desc') { - return \PicoTools\singleton('db') + return Database::get('db') ->table('items') ->columns( 'items.id', @@ -34,7 +36,7 @@ function get_all($status, $offset = null, $limit = null, $order_column = 'update // Get the number of items per status function count_by_status($status) { - return \PicoTools\singleton('db') + return Database::get('db') ->table('items') ->eq('status', $status) ->count(); @@ -43,7 +45,7 @@ function count_by_status($status) // Get the number of bookmarks function count_bookmarks() { - return \PicoTools\singleton('db') + return Database::get('db') ->table('items') ->eq('bookmark', 1) ->in('status', array('read', 'unread')) @@ -53,7 +55,7 @@ function count_bookmarks() // Get all bookmarks function get_bookmarks($offset = null, $limit = null) { - return \PicoTools\singleton('db') + return Database::get('db') ->table('items') ->columns( 'items.id', @@ -79,7 +81,7 @@ function get_bookmarks($offset = null, $limit = null) // Get the number of items per feed function count_by_feed($feed_id) { - return \PicoTools\singleton('db') + return Database::get('db') ->table('items') ->eq('feed_id', $feed_id) ->in('status', array('unread', 'read')) @@ -89,7 +91,7 @@ function count_by_feed($feed_id) // Get all items per feed function get_all_by_feed($feed_id, $offset = null, $limit = null, $order_column = 'updated', $order_direction = 'desc') { - return \PicoTools\singleton('db') + return Database::get('db') ->table('items') ->columns( 'items.id', @@ -114,7 +116,7 @@ function get_all_by_feed($feed_id, $offset = null, $limit = null, $order_column // Get one item by id function get($id) { - return \PicoTools\singleton('db') + return Database::get('db') ->table('items') ->eq('id', $id) ->findOne(); @@ -123,7 +125,7 @@ function get($id) // Get item naviguation (next/prev items) function get_nav($item, $status = array('unread'), $bookmark = array(1, 0), $feed_id = null) { - $query = \PicoTools\singleton('db') + $query = Database::get('db') ->table('items') ->columns('id', 'status', 'title', 'bookmark') ->neq('status', 'removed') @@ -183,7 +185,7 @@ function get_nav($item, $status = array('unread'), $bookmark = array(1, 0), $fee // Change item status to removed and clear content function set_removed($id) { - return \PicoTools\singleton('db') + return Database::get('db') ->table('items') ->eq('id', $id) ->save(array('status' => 'removed', 'content' => '')); @@ -192,7 +194,7 @@ function set_removed($id) // Change item status to read function set_read($id) { - return \PicoTools\singleton('db') + return Database::get('db') ->table('items') ->eq('id', $id) ->save(array('status' => 'read')); @@ -201,7 +203,7 @@ function set_read($id) // Change item status to unread function set_unread($id) { - return \PicoTools\singleton('db') + return Database::get('db') ->table('items') ->eq('id', $id) ->save(array('status' => 'unread')); @@ -212,7 +214,7 @@ function set_status($status, array $items) { if (! in_array($status, array('read', 'unread', 'removed'))) return false; - return \PicoTools\singleton('db') + return Database::get('db') ->table('items') ->in('id', $items) ->save(array('status' => $status)); @@ -221,7 +223,7 @@ function set_status($status, array $items) // Enable/disable bookmark flag function set_bookmark_value($id, $value) { - return \PicoTools\singleton('db') + return Database::get('db') ->table('items') ->eq('id', $id) ->save(array('bookmark' => $value)); @@ -230,7 +232,7 @@ function set_bookmark_value($id, $value) // Swap item status read <-> unread function switch_status($id) { - $item = \PicoTools\singleton('db') + $item = Database::get('db') ->table('items') ->columns('status') ->eq('id', $id) @@ -238,7 +240,7 @@ function switch_status($id) if ($item['status'] == 'unread') { - \PicoTools\singleton('db') + Database::get('db') ->table('items') ->eq('id', $id) ->save(array('status' => 'read')); @@ -247,7 +249,7 @@ function switch_status($id) } else { - \PicoTools\singleton('db') + Database::get('db') ->table('items') ->eq('id', $id) ->save(array('status' => 'unread')); @@ -261,7 +263,7 @@ function switch_status($id) // Mark all unread items as read function mark_all_as_read() { - return \PicoTools\singleton('db') + return Database::get('db') ->table('items') ->eq('status', 'unread') ->save(array('status' => 'read')); @@ -270,7 +272,7 @@ function mark_all_as_read() // Mark all read items to removed function mark_all_as_removed() { - return \PicoTools\singleton('db') + return Database::get('db') ->table('items') ->eq('status', 'read') ->eq('bookmark', 0) @@ -280,21 +282,20 @@ function mark_all_as_removed() // Mark only specified items as read function mark_items_as_read(array $items_id) { - \PicoTools\singleton('db')->startTransaction(); + Database::get('db')->startTransaction(); foreach ($items_id as $id) { set_read($id); } - \PicoTools\singleton('db')->closeTransaction(); + Database::get('db')->closeTransaction(); } // Mark all items of a feed as read function mark_feed_as_read($feed_id) { - return \PicoTools\singleton('db') + return Database::get('db') ->table('items') - ->columns('items.id') ->eq('status', 'unread') ->eq('feed_id', $feed_id) ->update(array('status' => 'read')); @@ -308,7 +309,7 @@ function autoflush() if ($autoflush > 0) { // Mark read items removed after X days - \PicoTools\singleton('db') + Database::get('db') ->table('items') ->eq('bookmark', 0) ->eq('status', 'read') @@ -318,7 +319,7 @@ function autoflush() else if ($autoflush === -1) { // Mark read items removed immediately - \PicoTools\singleton('db') + Database::get('db') ->table('items') ->eq('bookmark', 0) ->eq('status', 'read') @@ -332,7 +333,7 @@ function update_all($feed_id, array $items, $grabber = false) $nocontent = (bool) \Model\Config\get('nocontent'); $items_in_feed = array(); - $db = \PicoTools\singleton('db'); + $db = Database::get('db'); $db->startTransaction(); @@ -369,7 +370,7 @@ function update_all($feed_id, array $items, $grabber = false) // and not present inside the feed if (! empty($items_in_feed)) { - $removed_items = \PicoTools\singleton('db') + $removed_items = Database::get('db') ->table('items') ->columns('id') ->notin('id', $items_in_feed) @@ -386,7 +387,7 @@ function update_all($feed_id, array $items, $grabber = false) if (! empty($items_to_remove)) { - \PicoTools\singleton('db') + Database::get('db') ->table('items') ->in('id', $items_to_remove) ->eq('status', 'removed') @@ -443,7 +444,7 @@ function download_content_id($item_id) if (! \Model\Config\get('nocontent')) { // Save content - \PicoTools\singleton('db') + Database::get('db') ->table('items') ->eq('id', $item['id']) ->save(array('content' => $content)); diff --git a/schema.php b/models/schema.php similarity index 100% rename from schema.php rename to models/schema.php diff --git a/models/user.php b/models/user.php index ab8c408..5fcfbb3 100644 --- a/models/user.php +++ b/models/user.php @@ -2,18 +2,19 @@ namespace Model\User; -require_once 'vendor/SimpleValidator/Validator.php'; -require_once 'vendor/SimpleValidator/Base.php'; -require_once 'vendor/SimpleValidator/Validators/Required.php'; -require_once 'vendor/SimpleValidator/Validators/MaxLength.php'; +require_once __DIR__.'/../vendor/SimpleValidator/Validator.php'; +require_once __DIR__.'/../vendor/SimpleValidator/Base.php'; +require_once __DIR__.'/../vendor/SimpleValidator/Validators/Required.php'; +require_once __DIR__.'/../vendor/SimpleValidator/Validators/MaxLength.php'; use SimpleValidator\Validator; use SimpleValidator\Validators; +use PicoDb\Database; // Get a user by username function get($username) { - return \PicoTools\singleton('db') + return Database::get('db') ->table('config') ->columns('username', 'password', 'language') ->eq('username', $username) diff --git a/examples/api_client.sh b/scripts/api-client.sh similarity index 70% rename from examples/api_client.sh rename to scripts/api-client.sh index dfec15b..478da7a 100755 --- a/examples/api_client.sh +++ b/scripts/api-client.sh @@ -1,7 +1,7 @@ #!/bin/sh curl \ --u "demo:/EobxWLMrb+VO8G" \ +-u "admin:UkL1sN2xACNsySQ" \ -d '{"jsonrpc": "2.0", "method": "feed.create", "params": {"url": "http://images.apple.com/main/rss/hotnews/hotnews.rss"}, "id": 1}' \ -https://miniflux.net/demo/jsonrpc.php +http://127.0.0.1:8000/jsonrpc.php diff --git a/make-archive.sh b/scripts/make-archive.sh similarity index 89% rename from make-archive.sh rename to scripts/make-archive.sh index b9a0ea2..0750091 100755 --- a/make-archive.sh +++ b/scripts/make-archive.sh @@ -1,11 +1,11 @@ -#!/bin/bash +#!/bin/sh VERSION=$1 cd /tmp rm -rf /tmp/miniflux /tmp/miniflux-*.zip 2>/dev/null git clone git@github.com:fguillot/miniflux.git -rm -rf miniflux/data/*.sqlite miniflux/.git miniflux/.gitignore miniflux/*.sh miniflux/examples +rm -rf miniflux/data/*.sqlite miniflux/.git miniflux/.gitignore miniflux/scripts miniflux/examples sed -i.bak s/master/$VERSION/g miniflux/common.php && rm -f miniflux/*.bak zip -r miniflux-$VERSION.zip miniflux mv miniflux-*.zip ~/Devel/websites/miniflux diff --git a/scripts/make-js.sh b/scripts/make-js.sh new file mode 100755 index 0000000..0bf2ada --- /dev/null +++ b/scripts/make-js.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +in=assets/js/all.js +out=assets/js/all.min.js + +cat assets/js/app.js assets/js/feed.js assets/js/item.js assets/js/event.js assets/js/nav.js > $in +echo "Miniflux.App.Run();" >> $in + +curl -s \ +-d compilation_level=SIMPLE_OPTIMIZATIONS \ +-d output_format=text \ +-d output_info=compiled_code \ +--data-urlencode "js_code@${in}" \ +http://closure-compiler.appspot.com/compile > $out + +rm -f $in diff --git a/make-tag.sh b/scripts/make-tag.sh similarity index 87% rename from make-tag.sh rename to scripts/make-tag.sh index e702295..108444f 100755 --- a/make-tag.sh +++ b/scripts/make-tag.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh VERSION=$1 diff --git a/templates/config.php b/templates/config.php index ff253a8..5b0a9b7 100644 --- a/templates/config.php +++ b/templates/config.php @@ -68,7 +68,7 @@ ()
  • - +
  • @@ -89,7 +89,7 @@

    diff --git a/templates/layout.php b/templates/layout.php index 1d7d859..017947d 100644 --- a/templates/layout.php +++ b/templates/layout.php @@ -11,7 +11,7 @@ <?= isset($title) ? Helper\escape($title) : 'Miniflux' ?> - +
    diff --git a/themes/bootstrap-light/less/alerts.less b/themes/bootstrap-light/less/alerts.less deleted file mode 100644 index be09d18..0000000 --- a/themes/bootstrap-light/less/alerts.less +++ /dev/null @@ -1,67 +0,0 @@ -// -// Alerts -// -------------------------------------------------- - - -// Base styles -// ------------------------- - -.alert { - padding: @alert-padding; - margin-bottom: @line-height-computed; - border: 1px solid transparent; - border-radius: @alert-border-radius; - - // Headings for larger alerts - h4 { - margin-top: 0; - // Specified for the h4 to prevent conflicts of changing @headingsColor - color: inherit; - } - // Provide class for links that match alerts - .alert-link { - font-weight: @alert-link-font-weight; - } - - // Improve alignment and spacing of inner content - > p, - > ul { - margin-bottom: 0; - } - > p + p { - margin-top: 5px; - } -} - -// Dismissable alerts -// -// Expand the right padding and account for the close button's positioning. - -.alert-dismissable { - padding-right: (@alert-padding + 20); - - // Adjust close link position - .close { - position: relative; - top: -2px; - right: -21px; - color: inherit; - } -} - -// Alternate styles -// -// Generate contextual modifier classes for colorizing the alert. - -.alert-success { - .alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text); -} -.alert-info { - .alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text); -} -.alert-warning { - .alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text); -} -.alert-danger { - .alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text); -} diff --git a/themes/bootstrap-light/less/bootstrap.less b/themes/bootstrap-light/less/bootstrap.less deleted file mode 100644 index 12c6497..0000000 --- a/themes/bootstrap-light/less/bootstrap.less +++ /dev/null @@ -1,58 +0,0 @@ -/*! - * Bootstrap v3.0.0 - * - * Copyright 2013 Twitter, Inc - * Licensed under the Apache License v2.0 - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Designed and built with all the love in the world by @mdo and @fat. - */ - -// Core variables and mixins -@import "variables.less"; -@import "mixins.less"; - -// Reset -@import "normalize.less"; -@import "print.less"; - -// Core CSS -@import "scaffolding.less"; -@import "type.less"; -@import "code.less"; -@import "grid.less"; -@import "tables.less"; -@import "forms.less"; -@import "buttons.less"; - -// Components -//@import "component-animations.less"; -@import "glyphicons.less"; -//@import "dropdowns.less"; -//@import "button-groups.less"; -@import "input-groups.less"; -@import "navs.less"; -//@import "navbar.less"; -//@import "breadcrumbs.less"; -@import "pagination.less"; -@import "pager.less"; -//@import "labels.less"; -//@import "badges.less"; -//@import "jumbotron.less"; -//@import "thumbnails.less"; -@import "alerts.less"; -//@import "progress-bars.less"; -//@import "media.less"; -//@import "list-group.less"; -@import "panels.less"; -//@import "wells.less"; -//@import "close.less"; - -// Utility classes -@import "utilities.less"; -@import "responsive-utilities.less"; - -// Mixins for miniflux -@import "miniflux-base.less"; -// Theme for miniflux -@import "miniflux-theme.less"; \ No newline at end of file diff --git a/themes/bootstrap-light/less/buttons.less b/themes/bootstrap-light/less/buttons.less deleted file mode 100644 index 5d60d39..0000000 --- a/themes/bootstrap-light/less/buttons.less +++ /dev/null @@ -1,160 +0,0 @@ -// -// Buttons -// -------------------------------------------------- - - -// Base styles -// -------------------------------------------------- - -// Core styles -.btn { - display: inline-block; - padding: @padding-base-vertical @padding-base-horizontal; - margin-bottom: 0; // For input.btn - font-size: @font-size-base; - font-weight: @btn-font-weight; - line-height: @line-height-base; - text-align: center; - vertical-align: middle; - cursor: pointer; - border: 1px solid transparent; - border-radius: @border-radius-base; - white-space: nowrap; - .user-select(none); - - &:focus { - .tab-focus(); - } - - &:hover, - &:focus { - color: @btn-default-color; - text-decoration: none; - } - - &:active, - &.active { - outline: 0; - background-image: none; - .box-shadow(inset 0 3px 5px rgba(0,0,0,.125)); - } - - &.disabled, - &[disabled], - fieldset[disabled] & { - cursor: not-allowed; - pointer-events: none; // Future-proof disabling of clicks - .opacity(.65); - .box-shadow(none); - } - -} - - -// Alternate buttons -// -------------------------------------------------- - -.btn-default { - .button-variant(@btn-default-color; @btn-default-bg; @btn-default-border); -} -.btn-primary { - .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border); -} -// Warning appears as orange -.btn-warning { - .button-variant(@btn-warning-color; @btn-warning-bg; @btn-warning-border); -} -// Danger and error appear as red -.btn-danger { - .button-variant(@btn-danger-color; @btn-danger-bg; @btn-danger-border); -} -// Success appears as green -.btn-success { - .button-variant(@btn-success-color; @btn-success-bg; @btn-success-border); -} -// Info appears as blue-green -.btn-info { - .button-variant(@btn-info-color; @btn-info-bg; @btn-info-border); -} - - -// Link buttons -// ------------------------- - -// Make a button look and behave like a link -.btn-link { - color: @link-color; - font-weight: normal; - cursor: pointer; - border-radius: 0; - - &, - &:active, - &[disabled], - fieldset[disabled] & { - background-color: transparent; - .box-shadow(none); - } - &, - &:hover, - &:focus, - &:active { - border-color: transparent; - } - &:hover, - &:focus { - color: @link-hover-color; - text-decoration: underline; - background-color: transparent; - } - &[disabled], - fieldset[disabled] & { - &:hover, - &:focus { - color: @btn-link-disabled-color; - text-decoration: none; - } - } -} - - -// Button Sizes -// -------------------------------------------------- - -.btn-lg { - // line-height: ensure even-numbered height of button next to large input - .button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large); -} -.btn-sm, -.btn-xs { - // line-height: ensure proper height of button next to small input - .button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small); -} -.btn-xs { - padding: 1px 5px; -} - - -// Block button -// -------------------------------------------------- - -.btn-block { - display: block; - width: 100%; - padding-left: 0; - padding-right: 0; -} - -// Vertically space out multiple block buttons -.btn-block + .btn-block { - margin-top: 5px; -} - -// Specificity overrides -input[type="submit"], -input[type="reset"], -input[type="button"] { - &.btn-block { - width: 100%; - } -} diff --git a/themes/bootstrap-light/less/code.less b/themes/bootstrap-light/less/code.less deleted file mode 100644 index d6661d2..0000000 --- a/themes/bootstrap-light/less/code.less +++ /dev/null @@ -1,56 +0,0 @@ -// -// Code (inline and blocK) -// -------------------------------------------------- - - -// Inline and block code styles -code, -pre { - font-family: @font-family-monospace; -} - -// Inline code -code { - padding: 2px 4px; - font-size: 90%; - color: @code-color; - background-color: @code-bg; - white-space: nowrap; - border-radius: @border-radius-base; -} - -// Blocks of code -pre { - display: block; - padding: ((@line-height-computed - 1) / 2); - margin: 0 0 (@line-height-computed / 2); - font-size: (@font-size-base - 1); // 14px to 13px - line-height: @line-height-base; - word-break: break-all; - word-wrap: break-word; - color: @pre-color; - background-color: @pre-bg; - border: 1px solid @pre-border-color; - border-radius: @border-radius-base; - - // Make prettyprint styles more spaced out for readability - &.prettyprint { - margin-bottom: @line-height-computed; - } - - // Account for some code outputs that place code tags in pre tags - code { - padding: 0; - font-size: inherit; - color: inherit; - white-space: pre-wrap; - background-color: transparent; - border: 0; - } -} - -// Enable scrollable blocks of code -.pre-scrollable { - max-height: @pre-scrollable-max-height; - overflow-y: scroll; -} diff --git a/themes/bootstrap-light/less/forms.less b/themes/bootstrap-light/less/forms.less deleted file mode 100644 index f87b602..0000000 --- a/themes/bootstrap-light/less/forms.less +++ /dev/null @@ -1,353 +0,0 @@ -// -// Forms -// -------------------------------------------------- - - -// Normalize non-controls -// -// Restyle and baseline non-control form elements. - -fieldset { - padding: 0; - margin: 0; - border: 0; -} - -legend { - display: block; - width: 100%; - padding: 0; - margin-bottom: @line-height-computed; - font-size: (@font-size-base * 1.5); - line-height: inherit; - color: @legend-color; - border: 0; - border-bottom: 1px solid @legend-border-color; -} - -label { - display: inline-block; - margin-bottom: 5px; - font-weight: bold; -} - - -// Normalize form controls - -// Override content-box in Normalize (* isn't specific enough) -input[type="search"] { - .box-sizing(border-box); -} - -// Position radios and checkboxes better -input[type="radio"], -input[type="checkbox"] { - margin: 4px 0 0; - margin-top: 1px \9; /* IE8-9 */ - line-height: normal; -} - -// Set the height of select and file controls to match text inputs -input[type="file"] { - display: block; -} - -// Make multiple select elements height not fixed -select[multiple], -select[size] { - height: auto; -} - -// Fix optgroup Firefox bug per https://github.com/twbs/bootstrap/issues/7611 -select optgroup { - font-size: inherit; - font-style: inherit; - font-family: inherit; -} - -// Focus for select, file, radio, and checkbox -input[type="file"]:focus, -input[type="radio"]:focus, -input[type="checkbox"]:focus { - .tab-focus(); -} - -// Fix for Chrome number input -// Setting certain font-sizes causes the `I` bar to appear on hover of the bottom increment button. -// See https://github.com/twbs/bootstrap/issues/8350 for more. -input[type="number"] { - &::-webkit-outer-spin-button, - &::-webkit-inner-spin-button { - height: auto; - } -} - - -// Placeholder -// -// Placeholder text gets special styles because when browsers invalidate entire -// lines if it doesn't understand a selector/ -.form-control { - .placeholder(); -} - - -// Common form controls -// -// Shared size and type resets for form controls. Apply `.form-control` to any -// of the following form controls: -// -// select -// textarea -// input[type="text"] -// input[type="password"] -// input[type="datetime"] -// input[type="datetime-local"] -// input[type="date"] -// input[type="month"] -// input[type="time"] -// input[type="week"] -// input[type="number"] -// input[type="email"] -// input[type="url"] -// input[type="search"] -// input[type="tel"] -// input[type="color"] - -.form-control { - display: block; - width: 100%; - height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border) - padding: @padding-base-vertical @padding-base-horizontal; - font-size: @font-size-base; - line-height: @line-height-base; - color: @input-color; - vertical-align: middle; - background-color: @input-bg; - border: 1px solid @input-border; - border-radius: @input-border-radius; - .box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); - .transition(~"border-color ease-in-out .15s, box-shadow ease-in-out .15s"); - - // Customize the `:focus` state to imitate native WebKit styles. - .form-control-focus(); - - // Disabled and read-only inputs - // Note: HTML5 says that controls under a fieldset > legend:first-child won't - // be disabled if the fieldset is disabled. Due to implementation difficulty, - // we don't honor that edge case; we style them as disabled anyway. - &[disabled], - &[readonly], - fieldset[disabled] & { - cursor: not-allowed; - background-color: @input-bg-disabled; - } - - // Reset height for `textarea`s - textarea& { - height: auto; - } -} - - -// Form groups -// -// Designed to help with the organization and spacing of vertical forms. For -// horizontal forms, use the predefined grid classes. - -.form-group { - margin-bottom: 15px; -} - - -// Checkboxes and radios -// -// Indent the labels to position radios/checkboxes as hanging controls. - -.radio, -.checkbox { - display: block; - min-height: @line-height-computed; // clear the floating input if there is no label text - margin-top: 10px; - margin-bottom: 10px; - padding-left: 20px; - vertical-align: middle; - label { - display: inline; - margin-bottom: 0; - font-weight: normal; - cursor: pointer; - } -} -.radio input[type="radio"], -.radio-inline input[type="radio"], -.checkbox input[type="checkbox"], -.checkbox-inline input[type="checkbox"] { - float: left; - margin-left: -20px; -} -.radio + .radio, -.checkbox + .checkbox { - margin-top: -5px; // Move up sibling radios or checkboxes for tighter spacing -} - -// Radios and checkboxes on same line -.radio-inline, -.checkbox-inline { - display: inline-block; - padding-left: 20px; - margin-bottom: 0; - vertical-align: middle; - font-weight: normal; - cursor: pointer; -} -.radio-inline + .radio-inline, -.checkbox-inline + .checkbox-inline { - margin-top: 0; - margin-left: 10px; // space out consecutive inline controls -} - -// Apply same disabled cursor tweak as for inputs -// -// Note: Neither radios nor checkboxes can be readonly. -input[type="radio"], -input[type="checkbox"], -.radio, -.radio-inline, -.checkbox, -.checkbox-inline { - &[disabled], - fieldset[disabled] & { - cursor: not-allowed; - } -} - -// Form control sizing -.input-sm { - .input-size(@input-height-small; @padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small); -} - -.input-lg { - .input-size(@input-height-large; @padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large); -} - - -// Form control feedback states -// -// Apply contextual and semantic states to individual form controls. - -// Warning -.has-warning { - .form-control-validation(@state-warning-text; @state-warning-text; @state-warning-bg); -} -// Error -.has-error { - .form-control-validation(@state-danger-text; @state-danger-text; @state-danger-bg); -} -// Success -.has-success { - .form-control-validation(@state-success-text; @state-success-text; @state-success-bg); -} - - -// Static form control text -// -// Apply class to a `p` element to make any string of text align with labels in -// a horizontal form layout. - -.form-control-static { - margin-bottom: 0; // Remove default margin from `p` - padding-top: (@padding-base-vertical + 1); -} - - -// Help text -// -// Apply to any element you wish to create light text for placement immediately -// below a form control. Use for general help, formatting, or instructional text. - -.help-block { - display: block; // account for any element using help-block - margin-top: 5px; - margin-bottom: 10px; - color: lighten(@text-color, 25%); // lighten the text some for contrast -} - - - -// Inline forms -// -// Make forms appear inline(-block) by adding the `.form-inline` class. Inline -// forms begin stacked on extra small (mobile) devices and then go inline when -// viewports reach <768px. -// -// Requires wrapping inputs and labels with `.form-group` for proper display of -// default HTML form controls and our custom form controls (e.g., input groups). -// -// Heads up! This is mixin-ed into `.navbar-form` in navbars.less. - -.form-inline { - - // Kick in the inline - @media (min-width: @screen-tablet) { - // Inline-block all the things for "inline" - .form-group { - display: inline-block; - margin-bottom: 0; - vertical-align: middle; - } - - // In navbar-form, allow folks to *not* use `.form-group` - .form-control { - display: inline-block; - } - - // Remove default margin on radios/checkboxes that were used for stacking, and - // then undo the floating of radios and checkboxes to match (which also avoids - // a bug in WebKit: https://github.com/twbs/bootstrap/issues/1969). - .radio, - .checkbox { - display: inline-block; - margin-top: 0; - margin-bottom: 0; - padding-left: 0; - } - .radio input[type="radio"], - .checkbox input[type="checkbox"] { - float: none; - margin-left: 0; - } - } -} - - -// Horizontal forms -// -// Horizontal forms are built on grid classes and allow you to create forms with -// labels on the left and inputs on the right. - -.form-horizontal { - - // Consistent vertical alignment of labels, radios, and checkboxes - .control-label, - .radio, - .checkbox, - .radio-inline, - .checkbox-inline { - margin-top: 0; - margin-bottom: 0; - padding-top: (@padding-base-vertical + 1); // Default padding plus a border - } - - // Make form groups behave like rows - .form-group { - .make-row(); - } - - // Only right align form labels here when the columns stop stacking - @media (min-width: @screen-tablet) { - .control-label { - text-align: right; - } - } -} diff --git a/themes/bootstrap-light/less/glyphicons.less b/themes/bootstrap-light/less/glyphicons.less deleted file mode 100644 index 0e0ba98..0000000 --- a/themes/bootstrap-light/less/glyphicons.less +++ /dev/null @@ -1,232 +0,0 @@ -// -// Glyphicons for Bootstrap -// -// Since icons are fonts, they can be placed anywhere text is placed and are -// thus automatically sized to match the surrounding child. To use, create an -// inline element with the appropriate classes, like so: -// -// Star - -// Import the fonts -@font-face { - font-family: 'Glyphicons Halflings'; - src: url('@{icon-font-path}@{icon-font-name}.eot'); - src: url('@{icon-font-path}@{icon-font-name}.eot?#iefix') format('embedded-opentype'), - url('@{icon-font-path}@{icon-font-name}.woff') format('woff'), - url('@{icon-font-path}@{icon-font-name}.ttf') format('truetype'), - url('@{icon-font-path}@{icon-font-name}.svg#glyphicons-halflingsregular') format('svg'); -} - -// Catchall baseclass -.glyphicon { - position: relative; - top: 1px; - display: inline-block; - font-family: 'Glyphicons Halflings'; - font-style: normal; - font-weight: normal; - line-height: 1; - -webkit-font-smoothing: antialiased; -} - -// Individual icons -.glyphicon-asterisk { &:before { content: "\2a"; } } -.glyphicon-plus { &:before { content: "\2b"; } } -.glyphicon-euro { &:before { content: "\20ac"; } } -.glyphicon-minus { &:before { content: "\2212"; } } -.glyphicon-cloud { &:before { content: "\2601"; } } -.glyphicon-envelope { &:before { content: "\2709"; } } -.glyphicon-pencil { &:before { content: "\270f"; } } -.glyphicon-glass { &:before { content: "\e001"; } } -.glyphicon-music { &:before { content: "\e002"; } } -.glyphicon-search { &:before { content: "\e003"; } } -.glyphicon-heart { &:before { content: "\e005"; } } -.glyphicon-star { &:before { content: "\e006"; } } -.glyphicon-star-empty { &:before { content: "\e007"; } } -.glyphicon-user { &:before { content: "\e008"; } } -.glyphicon-film { &:before { content: "\e009"; } } -.glyphicon-th-large { &:before { content: "\e010"; } } -.glyphicon-th { &:before { content: "\e011"; } } -.glyphicon-th-list { &:before { content: "\e012"; } } -.glyphicon-ok { &:before { content: "\e013"; } } -.glyphicon-remove { &:before { content: "\e014"; } } -.glyphicon-zoom-in { &:before { content: "\e015"; } } -.glyphicon-zoom-out { &:before { content: "\e016"; } } -.glyphicon-off { &:before { content: "\e017"; } } -.glyphicon-signal { &:before { content: "\e018"; } } -.glyphicon-cog { &:before { content: "\e019"; } } -.glyphicon-trash { &:before { content: "\e020"; } } -.glyphicon-home { &:before { content: "\e021"; } } -.glyphicon-file { &:before { content: "\e022"; } } -.glyphicon-time { &:before { content: "\e023"; } } -.glyphicon-road { &:before { content: "\e024"; } } -.glyphicon-download-alt { &:before { content: "\e025"; } } -.glyphicon-download { &:before { content: "\e026"; } } -.glyphicon-upload { &:before { content: "\e027"; } } -.glyphicon-inbox { &:before { content: "\e028"; } } -.glyphicon-play-circle { &:before { content: "\e029"; } } -.glyphicon-repeat { &:before { content: "\e030"; } } -.glyphicon-refresh { &:before { content: "\e031"; } } -.glyphicon-list-alt { &:before { content: "\e032"; } } -.glyphicon-flag { &:before { content: "\e034"; } } -.glyphicon-headphones { &:before { content: "\e035"; } } -.glyphicon-volume-off { &:before { content: "\e036"; } } -.glyphicon-volume-down { &:before { content: "\e037"; } } -.glyphicon-volume-up { &:before { content: "\e038"; } } -.glyphicon-qrcode { &:before { content: "\e039"; } } -.glyphicon-barcode { &:before { content: "\e040"; } } -.glyphicon-tag { &:before { content: "\e041"; } } -.glyphicon-tags { &:before { content: "\e042"; } } -.glyphicon-book { &:before { content: "\e043"; } } -.glyphicon-print { &:before { content: "\e045"; } } -.glyphicon-font { &:before { content: "\e047"; } } -.glyphicon-bold { &:before { content: "\e048"; } } -.glyphicon-italic { &:before { content: "\e049"; } } -.glyphicon-text-height { &:before { content: "\e050"; } } -.glyphicon-text-width { &:before { content: "\e051"; } } -.glyphicon-align-left { &:before { content: "\e052"; } } -.glyphicon-align-center { &:before { content: "\e053"; } } -.glyphicon-align-right { &:before { content: "\e054"; } } -.glyphicon-align-justify { &:before { content: "\e055"; } } -.glyphicon-list { &:before { content: "\e056"; } } -.glyphicon-indent-left { &:before { content: "\e057"; } } -.glyphicon-indent-right { &:before { content: "\e058"; } } -.glyphicon-facetime-video { &:before { content: "\e059"; } } -.glyphicon-picture { &:before { content: "\e060"; } } -.glyphicon-map-marker { &:before { content: "\e062"; } } -.glyphicon-adjust { &:before { content: "\e063"; } } -.glyphicon-tint { &:before { content: "\e064"; } } -.glyphicon-edit { &:before { content: "\e065"; } } -.glyphicon-share { &:before { content: "\e066"; } } -.glyphicon-check { &:before { content: "\e067"; } } -.glyphicon-move { &:before { content: "\e068"; } } -.glyphicon-step-backward { &:before { content: "\e069"; } } -.glyphicon-fast-backward { &:before { content: "\e070"; } } -.glyphicon-backward { &:before { content: "\e071"; } } -.glyphicon-play { &:before { content: "\e072"; } } -.glyphicon-pause { &:before { content: "\e073"; } } -.glyphicon-stop { &:before { content: "\e074"; } } -.glyphicon-forward { &:before { content: "\e075"; } } -.glyphicon-fast-forward { &:before { content: "\e076"; } } -.glyphicon-step-forward { &:before { content: "\e077"; } } -.glyphicon-eject { &:before { content: "\e078"; } } -.glyphicon-chevron-left { &:before { content: "\e079"; } } -.glyphicon-chevron-right { &:before { content: "\e080"; } } -.glyphicon-plus-sign { &:before { content: "\e081"; } } -.glyphicon-minus-sign { &:before { content: "\e082"; } } -.glyphicon-remove-sign { &:before { content: "\e083"; } } -.glyphicon-ok-sign { &:before { content: "\e084"; } } -.glyphicon-question-sign { &:before { content: "\e085"; } } -.glyphicon-info-sign { &:before { content: "\e086"; } } -.glyphicon-screenshot { &:before { content: "\e087"; } } -.glyphicon-remove-circle { &:before { content: "\e088"; } } -.glyphicon-ok-circle { &:before { content: "\e089"; } } -.glyphicon-ban-circle { &:before { content: "\e090"; } } -.glyphicon-arrow-left { &:before { content: "\e091"; } } -.glyphicon-arrow-right { &:before { content: "\e092"; } } -.glyphicon-arrow-up { &:before { content: "\e093"; } } -.glyphicon-arrow-down { &:before { content: "\e094"; } } -.glyphicon-share-alt { &:before { content: "\e095"; } } -.glyphicon-resize-full { &:before { content: "\e096"; } } -.glyphicon-resize-small { &:before { content: "\e097"; } } -.glyphicon-exclamation-sign { &:before { content: "\e101"; } } -.glyphicon-gift { &:before { content: "\e102"; } } -.glyphicon-leaf { &:before { content: "\e103"; } } -.glyphicon-eye-open { &:before { content: "\e105"; } } -.glyphicon-eye-close { &:before { content: "\e106"; } } -.glyphicon-warning-sign { &:before { content: "\e107"; } } -.glyphicon-plane { &:before { content: "\e108"; } } -.glyphicon-random { &:before { content: "\e110"; } } -.glyphicon-comment { &:before { content: "\e111"; } } -.glyphicon-magnet { &:before { content: "\e112"; } } -.glyphicon-chevron-up { &:before { content: "\e113"; } } -.glyphicon-chevron-down { &:before { content: "\e114"; } } -.glyphicon-retweet { &:before { content: "\e115"; } } -.glyphicon-shopping-cart { &:before { content: "\e116"; } } -.glyphicon-folder-close { &:before { content: "\e117"; } } -.glyphicon-folder-open { &:before { content: "\e118"; } } -.glyphicon-resize-vertical { &:before { content: "\e119"; } } -.glyphicon-resize-horizontal { &:before { content: "\e120"; } } -.glyphicon-hdd { &:before { content: "\e121"; } } -.glyphicon-bullhorn { &:before { content: "\e122"; } } -.glyphicon-certificate { &:before { content: "\e124"; } } -.glyphicon-thumbs-up { &:before { content: "\e125"; } } -.glyphicon-thumbs-down { &:before { content: "\e126"; } } -.glyphicon-hand-right { &:before { content: "\e127"; } } -.glyphicon-hand-left { &:before { content: "\e128"; } } -.glyphicon-hand-up { &:before { content: "\e129"; } } -.glyphicon-hand-down { &:before { content: "\e130"; } } -.glyphicon-circle-arrow-right { &:before { content: "\e131"; } } -.glyphicon-circle-arrow-left { &:before { content: "\e132"; } } -.glyphicon-circle-arrow-up { &:before { content: "\e133"; } } -.glyphicon-circle-arrow-down { &:before { content: "\e134"; } } -.glyphicon-globe { &:before { content: "\e135"; } } -.glyphicon-tasks { &:before { content: "\e137"; } } -.glyphicon-filter { &:before { content: "\e138"; } } -.glyphicon-fullscreen { &:before { content: "\e140"; } } -.glyphicon-dashboard { &:before { content: "\e141"; } } -.glyphicon-heart-empty { &:before { content: "\e143"; } } -.glyphicon-link { &:before { content: "\e144"; } } -.glyphicon-phone { &:before { content: "\e145"; } } -.glyphicon-usd { &:before { content: "\e148"; } } -.glyphicon-gbp { &:before { content: "\e149"; } } -.glyphicon-sort { &:before { content: "\e150"; } } -.glyphicon-sort-by-alphabet { &:before { content: "\e151"; } } -.glyphicon-sort-by-alphabet-alt { &:before { content: "\e152"; } } -.glyphicon-sort-by-order { &:before { content: "\e153"; } } -.glyphicon-sort-by-order-alt { &:before { content: "\e154"; } } -.glyphicon-sort-by-attributes { &:before { content: "\e155"; } } -.glyphicon-sort-by-attributes-alt { &:before { content: "\e156"; } } -.glyphicon-unchecked { &:before { content: "\e157"; } } -.glyphicon-expand { &:before { content: "\e158"; } } -.glyphicon-collapse-down { &:before { content: "\e159"; } } -.glyphicon-collapse-up { &:before { content: "\e160"; } } -.glyphicon-log-in { &:before { content: "\e161"; } } -.glyphicon-flash { &:before { content: "\e162"; } } -.glyphicon-log-out { &:before { content: "\e163"; } } -.glyphicon-new-window { &:before { content: "\e164"; } } -.glyphicon-record { &:before { content: "\e165"; } } -.glyphicon-save { &:before { content: "\e166"; } } -.glyphicon-open { &:before { content: "\e167"; } } -.glyphicon-saved { &:before { content: "\e168"; } } -.glyphicon-import { &:before { content: "\e169"; } } -.glyphicon-export { &:before { content: "\e170"; } } -.glyphicon-send { &:before { content: "\e171"; } } -.glyphicon-floppy-disk { &:before { content: "\e172"; } } -.glyphicon-floppy-saved { &:before { content: "\e173"; } } -.glyphicon-floppy-remove { &:before { content: "\e174"; } } -.glyphicon-floppy-save { &:before { content: "\e175"; } } -.glyphicon-floppy-open { &:before { content: "\e176"; } } -.glyphicon-credit-card { &:before { content: "\e177"; } } -.glyphicon-transfer { &:before { content: "\e178"; } } -.glyphicon-cutlery { &:before { content: "\e179"; } } -.glyphicon-header { &:before { content: "\e180"; } } -.glyphicon-compressed { &:before { content: "\e181"; } } -.glyphicon-earphone { &:before { content: "\e182"; } } -.glyphicon-phone-alt { &:before { content: "\e183"; } } -.glyphicon-tower { &:before { content: "\e184"; } } -.glyphicon-stats { &:before { content: "\e185"; } } -.glyphicon-sd-video { &:before { content: "\e186"; } } -.glyphicon-hd-video { &:before { content: "\e187"; } } -.glyphicon-subtitles { &:before { content: "\e188"; } } -.glyphicon-sound-stereo { &:before { content: "\e189"; } } -.glyphicon-sound-dolby { &:before { content: "\e190"; } } -.glyphicon-sound-5-1 { &:before { content: "\e191"; } } -.glyphicon-sound-6-1 { &:before { content: "\e192"; } } -.glyphicon-sound-7-1 { &:before { content: "\e193"; } } -.glyphicon-copyright-mark { &:before { content: "\e194"; } } -.glyphicon-registration-mark { &:before { content: "\e195"; } } -.glyphicon-cloud-download { &:before { content: "\e197"; } } -.glyphicon-cloud-upload { &:before { content: "\e198"; } } -.glyphicon-tree-conifer { &:before { content: "\e199"; } } -.glyphicon-tree-deciduous { &:before { content: "\e200"; } } -.glyphicon-briefcase { &:before { content: "\1f4bc"; } } -.glyphicon-calendar { &:before { content: "\1f4c5"; } } -.glyphicon-pushpin { &:before { content: "\1f4cc"; } } -.glyphicon-paperclip { &:before { content: "\1f4ce"; } } -.glyphicon-camera { &:before { content: "\1f4f7"; } } -.glyphicon-lock { &:before { content: "\1f512"; } } -.glyphicon-bell { &:before { content: "\1f514"; } } -.glyphicon-bookmark { &:before { content: "\1f516"; } } -.glyphicon-fire { &:before { content: "\1f525"; } } -.glyphicon-wrench { &:before { content: "\1f527"; } } diff --git a/themes/bootstrap-light/less/grid.less b/themes/bootstrap-light/less/grid.less deleted file mode 100644 index 44e3899..0000000 --- a/themes/bootstrap-light/less/grid.less +++ /dev/null @@ -1,346 +0,0 @@ -// -// Grid system -// -------------------------------------------------- - - -// Set the container width, and override it for fixed navbars in media queries -.container { - .container-fixed(); -} - -// mobile first defaults -.row { - .make-row(); -} - -// Common styles for small and large grid columns -.col-xs-1, -.col-xs-2, -.col-xs-3, -.col-xs-4, -.col-xs-5, -.col-xs-6, -.col-xs-7, -.col-xs-8, -.col-xs-9, -.col-xs-10, -.col-xs-11, -.col-xs-12, -.col-sm-1, -.col-sm-2, -.col-sm-3, -.col-sm-4, -.col-sm-5, -.col-sm-6, -.col-sm-7, -.col-sm-8, -.col-sm-9, -.col-sm-10, -.col-sm-11, -.col-sm-12, -.col-md-1, -.col-md-2, -.col-md-3, -.col-md-4, -.col-md-5, -.col-md-6, -.col-md-7, -.col-md-8, -.col-md-9, -.col-md-10, -.col-md-11, -.col-md-12, -.col-lg-1, -.col-lg-2, -.col-lg-3, -.col-lg-4, -.col-lg-5, -.col-lg-6, -.col-lg-7, -.col-lg-8, -.col-lg-9, -.col-lg-10, -.col-lg-11, -.col-lg-12 { - position: relative; - // Prevent columns from collapsing when empty - min-height: 1px; - // Inner gutter via padding - padding-left: (@grid-gutter-width / 2); - padding-right: (@grid-gutter-width / 2); -} - - -// Extra small grid -// -// Grid classes for extra small devices like smartphones. No offset, push, or -// pull classes are present here due to the size of the target. -// -// Note that `.col-xs-12` doesn't get floated on purpose—there's no need since -// it's full-width. - -.col-xs-1, -.col-xs-2, -.col-xs-3, -.col-xs-4, -.col-xs-5, -.col-xs-6, -.col-xs-7, -.col-xs-8, -.col-xs-9, -.col-xs-10, -.col-xs-11 { - float: left; -} -.col-xs-1 { width: percentage((1 / @grid-columns)); } -.col-xs-2 { width: percentage((2 / @grid-columns)); } -.col-xs-3 { width: percentage((3 / @grid-columns)); } -.col-xs-4 { width: percentage((4 / @grid-columns)); } -.col-xs-5 { width: percentage((5 / @grid-columns)); } -.col-xs-6 { width: percentage((6 / @grid-columns)); } -.col-xs-7 { width: percentage((7 / @grid-columns)); } -.col-xs-8 { width: percentage((8 / @grid-columns)); } -.col-xs-9 { width: percentage((9 / @grid-columns)); } -.col-xs-10 { width: percentage((10/ @grid-columns)); } -.col-xs-11 { width: percentage((11/ @grid-columns)); } -.col-xs-12 { width: 100%; } - - -// Small grid -// -// Columns, offsets, pushes, and pulls for the small device range, from phones -// to tablets. -// -// Note that `.col-sm-12` doesn't get floated on purpose—there's no need since -// it's full-width. - -@media (min-width: @screen-tablet) { - .container { - max-width: @container-tablet; - } - - .col-sm-1, - .col-sm-2, - .col-sm-3, - .col-sm-4, - .col-sm-5, - .col-sm-6, - .col-sm-7, - .col-sm-8, - .col-sm-9, - .col-sm-10, - .col-sm-11 { - float: left; - } - .col-sm-1 { width: percentage((1 / @grid-columns)); } - .col-sm-2 { width: percentage((2 / @grid-columns)); } - .col-sm-3 { width: percentage((3 / @grid-columns)); } - .col-sm-4 { width: percentage((4 / @grid-columns)); } - .col-sm-5 { width: percentage((5 / @grid-columns)); } - .col-sm-6 { width: percentage((6 / @grid-columns)); } - .col-sm-7 { width: percentage((7 / @grid-columns)); } - .col-sm-8 { width: percentage((8 / @grid-columns)); } - .col-sm-9 { width: percentage((9 / @grid-columns)); } - .col-sm-10 { width: percentage((10/ @grid-columns)); } - .col-sm-11 { width: percentage((11/ @grid-columns)); } - .col-sm-12 { width: 100%; } - - // Push and pull columns for source order changes - .col-sm-push-1 { left: percentage((1 / @grid-columns)); } - .col-sm-push-2 { left: percentage((2 / @grid-columns)); } - .col-sm-push-3 { left: percentage((3 / @grid-columns)); } - .col-sm-push-4 { left: percentage((4 / @grid-columns)); } - .col-sm-push-5 { left: percentage((5 / @grid-columns)); } - .col-sm-push-6 { left: percentage((6 / @grid-columns)); } - .col-sm-push-7 { left: percentage((7 / @grid-columns)); } - .col-sm-push-8 { left: percentage((8 / @grid-columns)); } - .col-sm-push-9 { left: percentage((9 / @grid-columns)); } - .col-sm-push-10 { left: percentage((10/ @grid-columns)); } - .col-sm-push-11 { left: percentage((11/ @grid-columns)); } - - .col-sm-pull-1 { right: percentage((1 / @grid-columns)); } - .col-sm-pull-2 { right: percentage((2 / @grid-columns)); } - .col-sm-pull-3 { right: percentage((3 / @grid-columns)); } - .col-sm-pull-4 { right: percentage((4 / @grid-columns)); } - .col-sm-pull-5 { right: percentage((5 / @grid-columns)); } - .col-sm-pull-6 { right: percentage((6 / @grid-columns)); } - .col-sm-pull-7 { right: percentage((7 / @grid-columns)); } - .col-sm-pull-8 { right: percentage((8 / @grid-columns)); } - .col-sm-pull-9 { right: percentage((9 / @grid-columns)); } - .col-sm-pull-10 { right: percentage((10/ @grid-columns)); } - .col-sm-pull-11 { right: percentage((11/ @grid-columns)); } - - // Offsets - .col-sm-offset-1 { margin-left: percentage((1 / @grid-columns)); } - .col-sm-offset-2 { margin-left: percentage((2 / @grid-columns)); } - .col-sm-offset-3 { margin-left: percentage((3 / @grid-columns)); } - .col-sm-offset-4 { margin-left: percentage((4 / @grid-columns)); } - .col-sm-offset-5 { margin-left: percentage((5 / @grid-columns)); } - .col-sm-offset-6 { margin-left: percentage((6 / @grid-columns)); } - .col-sm-offset-7 { margin-left: percentage((7 / @grid-columns)); } - .col-sm-offset-8 { margin-left: percentage((8 / @grid-columns)); } - .col-sm-offset-9 { margin-left: percentage((9 / @grid-columns)); } - .col-sm-offset-10 { margin-left: percentage((10/ @grid-columns)); } - .col-sm-offset-11 { margin-left: percentage((11/ @grid-columns)); } -} - - -// Medium grid -// -// Columns, offsets, pushes, and pulls for the desktop device range. -// -// Note that `.col-md-12` doesn't get floated on purpose—there's no need since -// it's full-width. - -@media (min-width: @screen-desktop) { - .container { - max-width: @container-desktop; - } - .col-md-1, - .col-md-2, - .col-md-3, - .col-md-4, - .col-md-5, - .col-md-6, - .col-md-7, - .col-md-8, - .col-md-9, - .col-md-10, - .col-md-11 { - float: left; - } - .col-md-1 { width: percentage((1 / @grid-columns)); } - .col-md-2 { width: percentage((2 / @grid-columns)); } - .col-md-3 { width: percentage((3 / @grid-columns)); } - .col-md-4 { width: percentage((4 / @grid-columns)); } - .col-md-5 { width: percentage((5 / @grid-columns)); } - .col-md-6 { width: percentage((6 / @grid-columns)); } - .col-md-7 { width: percentage((7 / @grid-columns)); } - .col-md-8 { width: percentage((8 / @grid-columns)); } - .col-md-9 { width: percentage((9 / @grid-columns)); } - .col-md-10 { width: percentage((10/ @grid-columns)); } - .col-md-11 { width: percentage((11/ @grid-columns)); } - .col-md-12 { width: 100%; } - - // Push and pull columns for source order changes - .col-md-push-0 { left: auto; } - .col-md-push-1 { left: percentage((1 / @grid-columns)); } - .col-md-push-2 { left: percentage((2 / @grid-columns)); } - .col-md-push-3 { left: percentage((3 / @grid-columns)); } - .col-md-push-4 { left: percentage((4 / @grid-columns)); } - .col-md-push-5 { left: percentage((5 / @grid-columns)); } - .col-md-push-6 { left: percentage((6 / @grid-columns)); } - .col-md-push-7 { left: percentage((7 / @grid-columns)); } - .col-md-push-8 { left: percentage((8 / @grid-columns)); } - .col-md-push-9 { left: percentage((9 / @grid-columns)); } - .col-md-push-10 { left: percentage((10/ @grid-columns)); } - .col-md-push-11 { left: percentage((11/ @grid-columns)); } - - .col-md-pull-0 { right: auto; } - .col-md-pull-1 { right: percentage((1 / @grid-columns)); } - .col-md-pull-2 { right: percentage((2 / @grid-columns)); } - .col-md-pull-3 { right: percentage((3 / @grid-columns)); } - .col-md-pull-4 { right: percentage((4 / @grid-columns)); } - .col-md-pull-5 { right: percentage((5 / @grid-columns)); } - .col-md-pull-6 { right: percentage((6 / @grid-columns)); } - .col-md-pull-7 { right: percentage((7 / @grid-columns)); } - .col-md-pull-8 { right: percentage((8 / @grid-columns)); } - .col-md-pull-9 { right: percentage((9 / @grid-columns)); } - .col-md-pull-10 { right: percentage((10/ @grid-columns)); } - .col-md-pull-11 { right: percentage((11/ @grid-columns)); } - - // Offsets - .col-md-offset-0 { margin-left: 0; } - .col-md-offset-1 { margin-left: percentage((1 / @grid-columns)); } - .col-md-offset-2 { margin-left: percentage((2 / @grid-columns)); } - .col-md-offset-3 { margin-left: percentage((3 / @grid-columns)); } - .col-md-offset-4 { margin-left: percentage((4 / @grid-columns)); } - .col-md-offset-5 { margin-left: percentage((5 / @grid-columns)); } - .col-md-offset-6 { margin-left: percentage((6 / @grid-columns)); } - .col-md-offset-7 { margin-left: percentage((7 / @grid-columns)); } - .col-md-offset-8 { margin-left: percentage((8 / @grid-columns)); } - .col-md-offset-9 { margin-left: percentage((9 / @grid-columns)); } - .col-md-offset-10 { margin-left: percentage((10/ @grid-columns)); } - .col-md-offset-11 { margin-left: percentage((11/ @grid-columns)); } -} - - -// Large grid -// -// Columns, offsets, pushes, and pulls for the large desktop device range. -// -// Note that `.col-lg-12` doesn't get floated on purpose—there's no need since -// it's full-width. - -@media (min-width: @screen-lg-desktop) { - .container { - max-width: @container-lg-desktop; - } - - .col-lg-1, - .col-lg-2, - .col-lg-3, - .col-lg-4, - .col-lg-5, - .col-lg-6, - .col-lg-7, - .col-lg-8, - .col-lg-9, - .col-lg-10, - .col-lg-11 { - float: left; - } - .col-lg-1 { width: percentage((1 / @grid-columns)); } - .col-lg-2 { width: percentage((2 / @grid-columns)); } - .col-lg-3 { width: percentage((3 / @grid-columns)); } - .col-lg-4 { width: percentage((4 / @grid-columns)); } - .col-lg-5 { width: percentage((5 / @grid-columns)); } - .col-lg-6 { width: percentage((6 / @grid-columns)); } - .col-lg-7 { width: percentage((7 / @grid-columns)); } - .col-lg-8 { width: percentage((8 / @grid-columns)); } - .col-lg-9 { width: percentage((9 / @grid-columns)); } - .col-lg-10 { width: percentage((10/ @grid-columns)); } - .col-lg-11 { width: percentage((11/ @grid-columns)); } - .col-lg-12 { width: 100%; } - - // Push and pull columns for source order changes - .col-lg-push-0 { left: auto; } - .col-lg-push-1 { left: percentage((1 / @grid-columns)); } - .col-lg-push-2 { left: percentage((2 / @grid-columns)); } - .col-lg-push-3 { left: percentage((3 / @grid-columns)); } - .col-lg-push-4 { left: percentage((4 / @grid-columns)); } - .col-lg-push-5 { left: percentage((5 / @grid-columns)); } - .col-lg-push-6 { left: percentage((6 / @grid-columns)); } - .col-lg-push-7 { left: percentage((7 / @grid-columns)); } - .col-lg-push-8 { left: percentage((8 / @grid-columns)); } - .col-lg-push-9 { left: percentage((9 / @grid-columns)); } - .col-lg-push-10 { left: percentage((10/ @grid-columns)); } - .col-lg-push-11 { left: percentage((11/ @grid-columns)); } - - .col-lg-pull-0 { right: auto; } - .col-lg-pull-1 { right: percentage((1 / @grid-columns)); } - .col-lg-pull-2 { right: percentage((2 / @grid-columns)); } - .col-lg-pull-3 { right: percentage((3 / @grid-columns)); } - .col-lg-pull-4 { right: percentage((4 / @grid-columns)); } - .col-lg-pull-5 { right: percentage((5 / @grid-columns)); } - .col-lg-pull-6 { right: percentage((6 / @grid-columns)); } - .col-lg-pull-7 { right: percentage((7 / @grid-columns)); } - .col-lg-pull-8 { right: percentage((8 / @grid-columns)); } - .col-lg-pull-9 { right: percentage((9 / @grid-columns)); } - .col-lg-pull-10 { right: percentage((10/ @grid-columns)); } - .col-lg-pull-11 { right: percentage((11/ @grid-columns)); } - - // Offsets - .col-lg-offset-0 { margin-left: 0; } - .col-lg-offset-1 { margin-left: percentage((1 / @grid-columns)); } - .col-lg-offset-2 { margin-left: percentage((2 / @grid-columns)); } - .col-lg-offset-3 { margin-left: percentage((3 / @grid-columns)); } - .col-lg-offset-4 { margin-left: percentage((4 / @grid-columns)); } - .col-lg-offset-5 { margin-left: percentage((5 / @grid-columns)); } - .col-lg-offset-6 { margin-left: percentage((6 / @grid-columns)); } - .col-lg-offset-7 { margin-left: percentage((7 / @grid-columns)); } - .col-lg-offset-8 { margin-left: percentage((8 / @grid-columns)); } - .col-lg-offset-9 { margin-left: percentage((9 / @grid-columns)); } - .col-lg-offset-10 { margin-left: percentage((10/ @grid-columns)); } - .col-lg-offset-11 { margin-left: percentage((11/ @grid-columns)); } -} diff --git a/themes/bootstrap-light/less/input-groups.less b/themes/bootstrap-light/less/input-groups.less deleted file mode 100644 index 570f03f..0000000 --- a/themes/bootstrap-light/less/input-groups.less +++ /dev/null @@ -1,127 +0,0 @@ -// -// Input groups -// -------------------------------------------------- - -// Base styles -// ------------------------- -.input-group { - position: relative; // For dropdowns - display: table; - border-collapse: separate; // prevent input groups from inheriting border styles from table cells when placed within a table - - // Undo padding and float of grid classes - &.col { - float: none; - padding-left: 0; - padding-right: 0; - } - - .form-control { - width: 100%; - margin-bottom: 0; - } -} - -// Sizing options -// -// Remix the default form control sizing classes into new ones for easier -// manipulation. - -.input-group-lg > .form-control, -.input-group-lg > .input-group-addon, -.input-group-lg > .input-group-btn > .btn { .input-lg(); } -.input-group-sm > .form-control, -.input-group-sm > .input-group-addon, -.input-group-sm > .input-group-btn > .btn { .input-sm(); } - - -// Display as table-cell -// ------------------------- -.input-group-addon, -.input-group-btn, -.input-group .form-control { - display: table-cell; - - &:not(:first-child):not(:last-child) { - border-radius: 0; - } -} -// Addon and addon wrapper for buttons -.input-group-addon, -.input-group-btn { - width: 1%; - white-space: nowrap; - vertical-align: middle; // Match the inputs -} - -// Text input groups -// ------------------------- -.input-group-addon { - padding: @padding-base-vertical @padding-base-horizontal; - font-size: @font-size-base; - font-weight: normal; - line-height: 1; - text-align: center; - background-color: @input-group-addon-bg; - border: 1px solid @input-group-addon-border-color; - border-radius: @border-radius-base; - - // Sizing - &.input-sm { - padding: @padding-small-vertical @padding-small-horizontal; - font-size: @font-size-small; - border-radius: @border-radius-small; - } - &.input-lg { - padding: @padding-large-vertical @padding-large-horizontal; - font-size: @font-size-large; - border-radius: @border-radius-large; - } - - // Nuke default margins from checkboxes and radios to vertically center within. - input[type="radio"], - input[type="checkbox"] { - margin-top: 0; - } -} - -// Reset rounded corners -.input-group .form-control:first-child, -.input-group-addon:first-child, -.input-group-btn:first-child > .btn, -.input-group-btn:first-child > .dropdown-toggle, -.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle) { - .border-right-radius(0); -} -.input-group-addon:first-child { - border-right: 0; -} -.input-group .form-control:last-child, -.input-group-addon:last-child, -.input-group-btn:last-child > .btn, -.input-group-btn:last-child > .dropdown-toggle, -.input-group-btn:first-child > .btn:not(:first-child) { - .border-left-radius(0); -} -.input-group-addon:last-child { - border-left: 0; -} - -// Button input groups -// ------------------------- -.input-group-btn { - position: relative; - white-space: nowrap; -} -.input-group-btn > .btn { - position: relative; - // Jankily prevent input button groups from wrapping - + .btn { - margin-left: -4px; - } - // Bring the "active" button to the front - &:hover, - &:active { - z-index: 2; - } -} diff --git a/themes/bootstrap-light/less/miniflux-base.less b/themes/bootstrap-light/less/miniflux-base.less deleted file mode 100644 index 27e72c3..0000000 --- a/themes/bootstrap-light/less/miniflux-base.less +++ /dev/null @@ -1,336 +0,0 @@ -// Bootstrap 3 theme integration for miniflux -// -------------------------------------- - -// Form -.btn { - &:extend(.btn all, .btn-primary all); -} -.btn-blue { - &:extend(.btn all, .btn-info all); -} - -input[type="text"], -input[type="password"], -select { - &:extend(.form-control all); -} - -// Alerts -.alert-normal { - &:extend(.alert-success all); -} -.alert-info { - &:extend(.alert-info all); -} -.alert-error { - &:extend(.alert-danger all); -} - -// Icons -header > nav > ul a:before { - font-family:'Glyphicons Halflings'; - margin-right: 5px; -} -header > nav > ul li:nth-child(1) a:before {content:"\e043";} // Unread -header > nav > ul li:nth-child(2) a:before {content:"\1f516";} // Bookmarks -header > nav > ul li:nth-child(3) a:before {content:"\e023";} // History -header > nav > ul li:nth-child(4) a:before {content:"\e012";} // Subscriptions -header > nav > ul li:nth-child(5) a:before {content:"\1f527";} // Préférences -header > nav > ul li:nth-child(6) a:before {content:"\e017";} // Logout - -// Logo -.logo { - min-width: 100px; - min-height: 45px; - font-size: 18px; - transition: all 0.4s; - display: block; - text-align: center; -} -.logo:hover, .logo:focus { - text-decoration: none; - outline: medium none; - transition: all 0.4s -} -.logo span , -.logo:hover span { - transition: all 0.4s -} - -// Container -// -------------------------------------- -body { - .container-fixed(); -} - -// Menu -// -------------------------------------- -body > header { - position: fixed; - top: 10px; left: 10px; -} - -body > header > nav { -} - -body > header > nav > ul { - &:extend(.nav all, .nav-pills all, .nav-stacked all); -} - -body > header > nav > ul a { - min-width: 120px; - text-transform: capitalize; -} - -// Page -// -------------------------------------- -.page { - .clearfix(); - padding-left: 150px ; - padding-top: 10px ; -} - -// Page header -// -------------------------------------- -.page-header { - .make-row(); - margin-top: 0; -} - -.page-header h2 { - .make-sm-column(7); - margin-top: 0; -} - -.page-header ul { - .make-sm-column(5); - &:extend(.nav all, .nav-pills all, .nav-justified all); -} - -// Buttons for the secondary menu ? -// .page-header ul a { -// &:extend(.btn-primary all); -// } -// .page-header ul a:last-child { -// margin-left: 5px; -// } - -// Page footer -// -------------------------------------- -#bottom-menu, -#items-paging { - float: right; -} -#bottom-menu a, -#items-paging a { - &:extend(.btn all, .btn-primary all); - margin: 10px; -} - -// item pagination -.item nav { - &:extend(.pager all); - margin-bottom: 0; -} - -.item nav > span { - border-radius: 15px; - display: inline-block; - padding: 5px 14px; - border-radius: 4px; -} - -.item nav .nav-left { - float: left; -} -.item nav .nav-right { - float: right; -} - - -// Articles -// -------------------------------------- -.item h2 {font-size:18px} -.item h3 {font-size:16px} -.item h4 {font-size:15px} -.item h5 {font-size:14px} -.item h6 {font-size:12px} -.item blockquote p {font-size: 15px;} - -article img { - max-width: 100%; -} - -.items { - .clearfix(); -} - -article.item, -.items article { - .clearfix(); - &:extend(.panel all, .panel-default all); - position: relative; - padding: 10px; -} - -article.item h1, -.items article h2 { - margin-top: 0; - padding-top: 20px; - font-size: 18px; -} - -.items article .preview { - margin-bottom: 0; - text-align: justify; -} - -article p.infos, -.items article p:not(.preview) { //Lack of class... - position: absolute; - top: 5px; right: 10px; - margin-bottom: 0; -} - -article p.infos a, -.items article p:not(.preview) a { - &:extend(.btn all, .btn-primary all, .btn-xs all); -} - -.downloading { - &:extend(.text-muted all); -} - -// Subscriptions -// -------------------------------------- -.feed-last-checked { - font-size: 14px; - &:extend(.text-muted all); -} - -// Preferences -// -------------------------------------- -section form input, -section form select {max-width: 300px;} -section form .form-actions input { - &:extend(.btn-block all); -} - -section .alert ul { - list-style: square; -} - -// Login -// -------------------------------------- -#login-page .page { - margin: 0 auto; - max-width: 330px; - padding: 15px; -} -#form-username, -#form-password { - &:extend(.form-control all); -} -#login-page .btn { - margin-top: 15px; - &:extend(.btn-block all); -} - -// Help -// -------------------------------------- -#help-page .page { - padding-left: 0; -} - -// Responsive -// -------------------------------------- -@media (max-width: @screen-lg) { - .hide-mobile { - .visible-lg(); - } -} - -@media (max-width: @screen-sm) { - //.logo , - body > header > nav > ul a { - max-width: 45px; - min-width: 0; - width: 45px; - display: block; - overflow: hidden; - white-space:nowrap; - } - - .logo {display: none;} // Need a shorter version ? - // .logo { - // margin-left: 10px; - // min-height: 0; - // } - // .logo:before, - header > nav > ul a:before { - margin-right: 9999px; - } - // .logo:before { - // font-family:'Glyphicons Halflings'; - // content: ""; - // } - - .page { - padding-left: 55px ; - } - - .page-header h2 { - font-size: 18px; - text-align: center; - } - - article.item h1, - .items article h2 { - margin-top: 0; - padding-top: 0px; - font-size: 18px; - } - article p.infos , - .items article p:not(.preview) { - position: static; - font-size: 0; - } - article p.infos a, - .items article p:not(.preview) a { - display: block; - font-size: 12px; - margin-top: 3px; - } - - article p.infos { - margin-bottom: 10px; - } - - .items article .preview { - text-align: left; - } - - // pagination - .item nav > span, - .item nav > span a { - display: block; - } - .item nav .nav-left, - .item nav .nav-middle, - .item nav .nav-right { - float: none; - margin-top: 3px; - } - - #items-paging, - #bottom-menu { - float: none; - max-height: 20px; - } - #bottom-menu a, - #items-paging a { - display: block; - margin: 5px 0; - } - -} diff --git a/themes/bootstrap-light/less/miniflux-theme.less b/themes/bootstrap-light/less/miniflux-theme.less deleted file mode 100644 index 5bc6750..0000000 --- a/themes/bootstrap-light/less/miniflux-theme.less +++ /dev/null @@ -1,39 +0,0 @@ -// Colors and specificities for the theme -// --------------------------------------------- - -// Logo -.logo { - color: @gray-dark; -} - -.logo:hover, .logo:focus { - color: @brand-primary; -} - -.logo span { - color: @brand-primary; -} - -.logo:hover span { - color: @gray-dark; -} - -// Article -article.item, -.items article { - background: @gray-lighter; -} - -#current-item { - border-color: @brand-primary; - background-color: darken(@gray-lighter, 10%); -} - -.item nav > span { - background: @btn-primary-bg; - border: 1px solid @btn-primary-border; -} - -.item nav > span a { - color: @btn-success-color; -} \ No newline at end of file diff --git a/themes/bootstrap-light/less/mixins.less b/themes/bootstrap-light/less/mixins.less deleted file mode 100644 index 3f23020..0000000 --- a/themes/bootstrap-light/less/mixins.less +++ /dev/null @@ -1,723 +0,0 @@ -// -// Mixins -// -------------------------------------------------- - - -// Utilities -// ------------------------- - -// Clearfix -// Source: http://nicolasgallagher.com/micro-clearfix-hack/ -// -// For modern browsers -// 1. The space content is one way to avoid an Opera bug when the -// contenteditable attribute is included anywhere else in the document. -// Otherwise it causes space to appear at the top and bottom of elements -// that are clearfixed. -// 2. The use of `table` rather than `block` is only necessary if using -// `:before` to contain the top-margins of child elements. -.clearfix() { - &:before, - &:after { - content: " "; /* 1 */ - display: table; /* 2 */ - } - &:after { - clear: both; - } -} - -// Webkit-style focus -.tab-focus() { - // Default - outline: thin dotted #333; - // Webkit - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} - -// Center-align a block level element -.center-block() { - display: block; - margin-left: auto; - margin-right: auto; -} - -// Sizing shortcuts -.size(@width; @height) { - width: @width; - height: @height; -} -.square(@size) { - .size(@size; @size); -} - -// Placeholder text -.placeholder(@color: @input-color-placeholder) { - &:-moz-placeholder { color: @color; } // Firefox 4-18 - &::-moz-placeholder { color: @color; } // Firefox 19+ - &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+ - &::-webkit-input-placeholder { color: @color; } // Safari and Chrome -} - -// Text overflow -// Requires inline-block or block for proper styling -.text-overflow() { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -// CSS image replacement -// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757 -.hide-text() { - font: ~"0/0" a; - color: transparent; - text-shadow: none; - background-color: transparent; - border: 0; -} - - - -// CSS3 PROPERTIES -// -------------------------------------------------- - -// Single side border-radius -.border-top-radius(@radius) { - border-top-right-radius: @radius; - border-top-left-radius: @radius; -} -.border-right-radius(@radius) { - border-bottom-right-radius: @radius; - border-top-right-radius: @radius; -} -.border-bottom-radius(@radius) { - border-bottom-right-radius: @radius; - border-bottom-left-radius: @radius; -} -.border-left-radius(@radius) { - border-bottom-left-radius: @radius; - border-top-left-radius: @radius; -} - -// Drop shadows -.box-shadow(@shadow) { - -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1 - box-shadow: @shadow; -} - -// Transitions -.transition(@transition) { - -webkit-transition: @transition; - transition: @transition; -} -.transition-delay(@transition-delay) { - -webkit-transition-delay: @transition-delay; - transition-delay: @transition-delay; -} -.transition-duration(@transition-duration) { - -webkit-transition-duration: @transition-duration; - transition-duration: @transition-duration; -} -.transition-transform(@transition) { - -webkit-transition: -webkit-transform @transition; - -moz-transition: -moz-transform @transition; - -o-transition: -o-transform @transition; - transition: transform @transition; -} - -// Transformations -.rotate(@degrees) { - -webkit-transform: rotate(@degrees); - -ms-transform: rotate(@degrees); // IE9+ - transform: rotate(@degrees); -} -.scale(@ratio) { - -webkit-transform: scale(@ratio); - -ms-transform: scale(@ratio); // IE9+ - transform: scale(@ratio); -} -.translate(@x; @y) { - -webkit-transform: translate(@x, @y); - -ms-transform: translate(@x, @y); // IE9+ - transform: translate(@x, @y); -} -.skew(@x; @y) { - -webkit-transform: skew(@x, @y); - -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+ - transform: skew(@x, @y); -} -.translate3d(@x; @y; @z) { - -webkit-transform: translate3d(@x, @y, @z); - transform: translate3d(@x, @y, @z); -} - -// Backface visibility -// Prevent browsers from flickering when using CSS 3D transforms. -// Default value is `visible`, but can be changed to `hidden` -// See git pull https://github.com/dannykeane/bootstrap.git backface-visibility for examples -.backface-visibility(@visibility){ - -webkit-backface-visibility: @visibility; - -moz-backface-visibility: @visibility; - backface-visibility: @visibility; -} - -// Box sizing -.box-sizing(@boxmodel) { - -webkit-box-sizing: @boxmodel; - -moz-box-sizing: @boxmodel; - box-sizing: @boxmodel; -} - -// User select -// For selecting text on the page -.user-select(@select) { - -webkit-user-select: @select; - -moz-user-select: @select; - -ms-user-select: @select; // IE10+ - -o-user-select: @select; - user-select: @select; -} - -// Resize anything -.resizable(@direction) { - resize: @direction; // Options: horizontal, vertical, both - overflow: auto; // Safari fix -} - -// CSS3 Content Columns -.content-columns(@column-count; @column-gap: @grid-gutter-width) { - -webkit-column-count: @column-count; - -moz-column-count: @column-count; - column-count: @column-count; - -webkit-column-gap: @column-gap; - -moz-column-gap: @column-gap; - column-gap: @column-gap; -} - -// Optional hyphenation -.hyphens(@mode: auto) { - word-wrap: break-word; - -webkit-hyphens: @mode; - -moz-hyphens: @mode; - -ms-hyphens: @mode; // IE10+ - -o-hyphens: @mode; - hyphens: @mode; -} - -// Opacity -.opacity(@opacity) { - opacity: @opacity; - // IE8 filter - @opacity-ie: (@opacity * 100); - filter: ~"alpha(opacity=@{opacity-ie})"; -} - - - -// GRADIENTS -// -------------------------------------------------- - -#gradient { - - // Horizontal gradient, from left to right - // - // Creates two color stops, start and end, by specifying a color and position for each color stop. - // Color stops are not available in IE9 and below. - .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) { - background-image: -webkit-gradient(linear, @start-percent top, @end-percent top, from(@start-color), to(@end-color)); // Safari 4+, Chrome 2+ - background-image: -webkit-linear-gradient(left, color-stop(@start-color @start-percent), color-stop(@end-color @end-percent)); // Safari 5.1+, Chrome 10+ - background-image: -moz-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // FF 3.6+ - background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10 - background-repeat: repeat-x; - filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)",argb(@start-color),argb(@end-color))); // IE9 and down - } - - // Vertical gradient, from top to bottom - // - // Creates two color stops, start and end, by specifying a color and position for each color stop. - // Color stops are not available in IE9 and below. - .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) { - background-image: -webkit-gradient(linear, left @start-percent, left @end-percent, from(@start-color), to(@end-color)); // Safari 4+, Chrome 2+ - background-image: -webkit-linear-gradient(top, @start-color, @start-percent, @end-color, @end-percent); // Safari 5.1+, Chrome 10+ - background-image: -moz-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // FF 3.6+ - background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10 - background-repeat: repeat-x; - filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@start-color),argb(@end-color))); // IE9 and down - } - - .directional(@start-color: #555; @end-color: #333; @deg: 45deg) { - background-repeat: repeat-x; - background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1+, Chrome 10+ - background-image: -moz-linear-gradient(@deg, @start-color, @end-color); // FF 3.6+ - background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10 - } - .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) { - background-image: -webkit-gradient(left, linear, 0 0, 0 100%, from(@start-color), color-stop(@color-stop, @mid-color), to(@end-color)); - background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color); - background-image: -moz-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color); - background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color); - background-repeat: no-repeat; - filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback - } - .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) { - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(@start-color), color-stop(@color-stop, @mid-color), to(@end-color)); - background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color); - background-image: -moz-linear-gradient(top, @start-color, @mid-color @color-stop, @end-color); - background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color); - background-repeat: no-repeat; - filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback - } - .radial(@inner-color: #555; @outer-color: #333) { - background-image: -webkit-gradient(radial, center center, 0, center center, 460, from(@inner-color), to(@outer-color)); - background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color); - background-image: -moz-radial-gradient(circle, @inner-color, @outer-color); - background-image: radial-gradient(circle, @inner-color, @outer-color); - background-repeat: no-repeat; - } - .striped(@color: #555; @angle: 45deg) { - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, rgba(255,255,255,.15)), color-stop(.25, transparent), color-stop(.5, transparent), color-stop(.5, rgba(255,255,255,.15)), color-stop(.75, rgba(255,255,255,.15)), color-stop(.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); - } -} - -// Reset filters for IE -// -// When you need to remove a gradient background, do not forget to use this to reset -// the IE filter for IE9 and below. -.reset-filter() { - filter: e(%("progid:DXImageTransform.Microsoft.gradient(enabled = false)")); -} - - - -// Retina images -// -// Short retina mixin for setting background-image and -size - -.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) { - background-image: url("@{file-1x}"); - - @media - only screen and (-webkit-min-device-pixel-ratio: 2), - only screen and ( min--moz-device-pixel-ratio: 2), - only screen and ( -o-min-device-pixel-ratio: 2/1), - only screen and ( min-device-pixel-ratio: 2), - only screen and ( min-resolution: 192dpi), - only screen and ( min-resolution: 2dppx) { - background-image: url("@{file-2x}"); - background-size: @width-1x @height-1x; - } -} - - -// Responsive image -// -// Keep images from scaling beyond the width of their parents. - -.img-responsive(@display: block;) { - display: @display; - max-width: 100%; // Part 1: Set a maximum relative to the parent - height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching -} - - -// COMPONENT MIXINS -// -------------------------------------------------- - -// Horizontal dividers -// ------------------------- -// Dividers (basically an hr) within dropdowns and nav lists -.nav-divider(@color: #e5e5e5) { - height: 1px; - margin: ((@line-height-computed / 2) - 1) 0; - overflow: hidden; - background-color: @color; -} - -// Panels -// ------------------------- -.panel-variant(@border; @heading-text-color; @heading-bg-color; @heading-border;) { - border-color: @border; - & > .panel-heading { - color: @heading-text-color; - background-color: @heading-bg-color; - border-color: @heading-border; - + .panel-collapse .panel-body { - border-top-color: @border; - } - } - & > .panel-footer { - + .panel-collapse .panel-body { - border-bottom-color: @border; - } - } -} - -// Alerts -// ------------------------- -.alert-variant(@background; @border; @text-color) { - background-color: @background; - border-color: @border; - color: @text-color; - hr { - border-top-color: darken(@border, 5%); - } - .alert-link { - color: darken(@text-color, 10%); - } -} - -// Tables -// ------------------------- -.table-row-variant(@state; @background; @border) { - // Exact selectors below required to override `.table-striped` and prevent - // inheritance to nested tables. - .table > thead > tr, - .table > tbody > tr, - .table > tfoot > tr { - > td.@{state}, - > th.@{state}, - &.@{state} > td, - &.@{state} > th { - background-color: @background; - border-color: @border; - } - } - - // Hover states for `.table-hover` - // Note: this is not available for cells or rows within `thead` or `tfoot`. - .table-hover > tbody > tr { - > td.@{state}:hover, - > th.@{state}:hover, - &.@{state}:hover > td { - background-color: darken(@background, 5%); - border-color: darken(@border, 5%); - } - } -} - -// Button variants -// ------------------------- -// Easily pump out default styles, as well as :hover, :focus, :active, -// and disabled options for all buttons -.button-variant(@color; @background; @border) { - color: @color; - background-color: @background; - border-color: @border; - - &:hover, - &:focus, - &:active, - &.active, - .open .dropdown-toggle& { - color: @color; - background-color: darken(@background, 8%); - border-color: darken(@border, 12%); - } - &:active, - &.active, - .open .dropdown-toggle& { - background-image: none; - } - &.disabled, - &[disabled], - fieldset[disabled] & { - &, - &:hover, - &:focus, - &:active, - &.active { - background-color: @background; - border-color: @border - } - } -} - -// Button sizes -// ------------------------- -.button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) { - padding: @padding-vertical @padding-horizontal; - font-size: @font-size; - line-height: @line-height; - border-radius: @border-radius; -} - -// Pagination -// ------------------------- -.pagination-size(@padding-vertical; @padding-horizontal; @font-size; @border-radius) { - > li { - > a, - > span { - padding: @padding-vertical @padding-horizontal; - font-size: @font-size; - } - &:first-child { - > a, - > span { - .border-left-radius(@border-radius); - } - } - &:last-child { - > a, - > span { - .border-right-radius(@border-radius); - } - } - } -} - -// Labels -// ------------------------- -.label-variant(@color) { - background-color: @color; - &[href] { - &:hover, - &:focus { - background-color: darken(@color, 10%); - } - } -} - -// Navbar vertical align -// ------------------------- -// Vertically center elements in the navbar. -// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin. -.navbar-vertical-align(@element-height) { - margin-top: ((@navbar-height - @element-height) / 2); - margin-bottom: ((@navbar-height - @element-height) / 2); -} - -// Progress bars -// ------------------------- -.progress-bar-variant(@color) { - background-color: @color; - .progress-striped & { - #gradient > .striped(@color); - } -} - -// Responsive utilities -// ------------------------- -// More easily include all the states for responsive-utilities.less. -.responsive-visibility() { - display: block !important; - tr& { display: table-row !important; } - th&, - td& { display: table-cell !important; } -} - -.responsive-invisibility() { - display: none !important; - tr& { display: none !important; } - th&, - td& { display: none !important; } -} - -// Grid System -// ----------- - -// Centered container element -.container-fixed() { - margin-right: auto; - margin-left: auto; - padding-left: (@grid-gutter-width / 2); - padding-right: (@grid-gutter-width / 2); - .clearfix(); -} - -// Creates a wrapper for a series of columns -.make-row(@gutter: @grid-gutter-width) { - margin-left: (@gutter / -2); - margin-right: (@gutter / -2); - .clearfix(); -} - -// Generate the extra small columns -.make-xs-column(@columns; @gutter: @grid-gutter-width) { - position: relative; - float: left; - width: percentage((@columns / @grid-columns)); - // Prevent columns from collapsing when empty - min-height: 1px; - // Inner gutter via padding - padding-left: (@gutter / 2); - padding-right: (@gutter / 2); -} - -// Generate the small columns -.make-sm-column(@columns; @gutter: @grid-gutter-width) { - position: relative; - // Prevent columns from collapsing when empty - min-height: 1px; - // Inner gutter via padding - padding-left: (@gutter / 2); - padding-right: (@gutter / 2); - - // Calculate width based on number of columns available - @media (min-width: @screen-sm) { - float: left; - width: percentage((@columns / @grid-columns)); - } -} - -// Generate the small column offsets -.make-sm-column-offset(@columns) { - @media (min-width: @screen-sm) { - margin-left: percentage((@columns / @grid-columns)); - } -} -.make-sm-column-push(@columns) { - @media (min-width: @screen-sm) { - left: percentage((@columns / @grid-columns)); - } -} -.make-sm-column-pull(@columns) { - @media (min-width: @screen-sm) { - right: percentage((@columns / @grid-columns)); - } -} - -// Generate the medium columns -.make-md-column(@columns; @gutter: @grid-gutter-width) { - position: relative; - // Prevent columns from collapsing when empty - min-height: 1px; - // Inner gutter via padding - padding-left: (@gutter / 2); - padding-right: (@gutter / 2); - - // Calculate width based on number of columns available - @media (min-width: @screen-md) { - float: left; - width: percentage((@columns / @grid-columns)); - } -} - -// Generate the large column offsets -.make-md-column-offset(@columns) { - @media (min-width: @screen-md) { - margin-left: percentage((@columns / @grid-columns)); - } -} -.make-md-column-push(@columns) { - @media (min-width: @screen-md) { - left: percentage((@columns / @grid-columns)); - } -} -.make-md-column-pull(@columns) { - @media (min-width: @screen-md) { - right: percentage((@columns / @grid-columns)); - } -} - -// Generate the large columns -.make-lg-column(@columns; @gutter: @grid-gutter-width) { - position: relative; - // Prevent columns from collapsing when empty - min-height: 1px; - // Inner gutter via padding - padding-left: (@gutter / 2); - padding-right: (@gutter / 2); - - // Calculate width based on number of columns available - @media (min-width: @screen-lg) { - float: left; - width: percentage((@columns / @grid-columns)); - } -} - -// Generate the large column offsets -.make-lg-column-offset(@columns) { - @media (min-width: @screen-lg) { - margin-left: percentage((@columns / @grid-columns)); - } -} -.make-lg-column-push(@columns) { - @media (min-width: @screen-lg) { - left: percentage((@columns / @grid-columns)); - } -} -.make-lg-column-pull(@columns) { - @media (min-width: @screen-lg) { - right: percentage((@columns / @grid-columns)); - } -} - - -// Form validation states -// -// Used in forms.less to generate the form validation CSS for warnings, errors, -// and successes. - -.form-control-validation(@text-color: #555; @border-color: #ccc; @background-color: #f5f5f5) { - // Color the label and help text - .help-block, - .control-label { - color: @text-color; - } - // Set the border and box shadow on specific inputs to match - .form-control { - border-color: @border-color; - .box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work - &:focus { - border-color: darken(@border-color, 10%); - @shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten(@border-color, 20%); - .box-shadow(@shadow); - } - } - // Set validation states also for addons - .input-group-addon { - color: @text-color; - border-color: @border-color; - background-color: @background-color; - } -} - -// Form control focus state -// -// Generate a customized focus state and for any input with the specified color, -// which defaults to the `@input-focus-border` variable. -// -// We highly encourage you to not customize the default value, but instead use -// this to tweak colors on an as-needed basis. This aesthetic change is based on -// WebKit's default styles, but applicable to a wider range of browsers. Its -// usability and accessibility should be taken into account with any change. -// -// Example usage: change the default blue border and shadow to white for better -// contrast against a dark gray background. - -.form-control-focus(@color: @input-border-focus) { - @color-rgba: rgba(red(@color), green(@color), blue(@color), .6); - &:focus { - border-color: @color; - outline: 0; - .box-shadow(~"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px @{color-rgba}"); - } -} - -// Form control sizing -// -// Relative text size, padding, and border-radii changes for form controls. For -// horizontal sizing, wrap controls in the predefined grid classes. `` -// element gets special love because it's special, and that's a fact! - -.input-size(@input-height; @padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) { - height: @input-height; - padding: @padding-vertical @padding-horizontal; - font-size: @font-size; - line-height: @line-height; - border-radius: @border-radius; - - select& { - height: @input-height; - line-height: @input-height; - } - - textarea& { - height: auto; - } -} diff --git a/themes/bootswatch-cyborg/less/navs.less b/themes/bootswatch-cyborg/less/navs.less deleted file mode 100644 index 6002a8c..0000000 --- a/themes/bootswatch-cyborg/less/navs.less +++ /dev/null @@ -1,229 +0,0 @@ -// -// Navs -// -------------------------------------------------- - - -// Base class -// -------------------------------------------------- - -.nav { - margin-bottom: 0; - padding-left: 0; // Override default ul/ol - list-style: none; - .clearfix(); - - > li { - position: relative; - display: block; - - > a { - position: relative; - display: block; - padding: @nav-link-padding; - &:hover, - &:focus { - text-decoration: none; - background-color: @nav-link-hover-bg; - } - } - - // Disabled state sets text to gray and nukes hover/tab effects - &.disabled > a { - color: @nav-disabled-link-color; - - &:hover, - &:focus { - color: @nav-disabled-link-hover-color; - text-decoration: none; - background-color: transparent; - cursor: not-allowed; - } - } - } - - // Open dropdowns - .open > a { - &, - &:hover, - &:focus { - background-color: @nav-link-hover-bg; - border-color: @link-color; - } - } - - // Dividers (basically an hr) within the dropdown - .nav-divider { - .nav-divider(); - } - - // Prevent IE8 from misplacing imgs - // See https://github.com/h5bp/html5-boilerplate/issues/984#issuecomment-3985989 - > li > a > img { - max-width: none; - } -} - - -// Tabs -// ------------------------- - -// Give the tabs something to sit on -.nav-tabs { - border-bottom: 1px solid @nav-tabs-border-color; - > li { - float: left; - // Make the list-items overlay the bottom border - margin-bottom: -1px; - - // Actual tabs (as links) - > a { - margin-right: 2px; - line-height: @line-height-base; - border: 1px solid transparent; - border-radius: @border-radius-base @border-radius-base 0 0; - &:hover { - border-color: @nav-tabs-link-hover-border-color @nav-tabs-link-hover-border-color @nav-tabs-border-color; - } - } - - // Active state, and it's :hover to override normal :hover - &.active > a { - &, - &:hover, - &:focus { - color: @nav-tabs-active-link-hover-color; - background-color: @nav-tabs-active-link-hover-bg; - border: 1px solid @nav-tabs-active-link-hover-border-color; - border-bottom-color: transparent; - cursor: default; - } - } - } - // pulling this in mainly for less shorthand - &.nav-justified { - .nav-justified(); - .nav-tabs-justified(); - } -} - - -// Pills -// ------------------------- -.nav-pills { - > li { - float: left; - - // Links rendered as pills - > a { - border-radius: 5px; - } - + li { - margin-left: 2px; - } - - // Active state - &.active > a { - &, - &:hover, - &:focus { - color: @nav-pills-active-link-hover-color; - background-color: @nav-pills-active-link-hover-bg; - } - } - } -} - - -// Stacked pills -.nav-stacked { - > li { - float: none; - + li { - margin-top: 2px; - margin-left: 0; // no need for this gap between nav items - } - } -} - - -// Nav variations -// -------------------------------------------------- - -// Justified nav links -// ------------------------- - -.nav-justified { - width: 100%; - - > li { - float: none; - > a { - text-align: center; - } - } - - @media (min-width: @screen-sm) { - > li { - display: table-cell; - width: 1%; - } - } -} - -// Move borders to anchors instead of bottom of list -.nav-tabs-justified { - border-bottom: 0; - > li > a { - border-bottom: 1px solid @nav-tabs-justified-link-border-color; - - // Override margin from .nav-tabs - margin-right: 0; - } - > .active > a { - border-bottom-color: @nav-tabs-justified-active-link-border-color; - } -} - - -// Tabbable tabs -// ------------------------- - -// Clear any floats -.tabbable { - .clearfix(); -} - -// Show/hide tabbable areas -.tab-content > .tab-pane, -.pill-content > .pill-pane { - display: none; -} -.tab-content, -.pill-content { - > .active { - display: block; - } -} - - - -// Dropdowns -// ------------------------- - -// Make dropdown carets use link color in navs -.nav .caret { - border-top-color: @link-color; - border-bottom-color: @link-color; -} -.nav a:hover .caret { - border-top-color: @link-hover-color; - border-bottom-color: @link-hover-color; -} - -// Specific dropdowns -.nav-tabs .dropdown-menu { - // make dropdown border overlap tab border - margin-top: -1px; - // Remove the top rounded corners here since there is a hard edge above the menu - .border-top-radius(0); -} diff --git a/themes/bootswatch-cyborg/less/normalize.less b/themes/bootswatch-cyborg/less/normalize.less deleted file mode 100644 index a2e9c64..0000000 --- a/themes/bootswatch-cyborg/less/normalize.less +++ /dev/null @@ -1,396 +0,0 @@ -/*! normalize.css v2.1.0 | MIT License | git.io/normalize */ - -// ========================================================================== -// HTML5 display definitions -// ========================================================================== - -// -// Correct `block` display not defined in IE 8/9. -// - -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -main, -nav, -section, -summary { - display: block; -} - -// -// Correct `inline-block` display not defined in IE 8/9. -// - -audio, -canvas, -video { - display: inline-block; -} - -// -// Prevent modern browsers from displaying `audio` without controls. -// Remove excess height in iOS 5 devices. -// - -audio:not([controls]) { - display: none; - height: 0; -} - -// -// Address styling not present in IE 8/9. -// - -[hidden] { - display: none; -} - -// ========================================================================== -// Base -// ========================================================================== - -// -// 1. Set default font family to sans-serif. -// 2. Prevent iOS text size adjust after orientation change, without disabling -// user zoom. -// - -html { - font-family: sans-serif; // 1 - -webkit-text-size-adjust: 100%; // 2 - -ms-text-size-adjust: 100%; // 2 -} - -// -// Remove default margin. -// - -body { - margin: 0; -} - -// ========================================================================== -// Links -// ========================================================================== - -// -// Address `outline` inconsistency between Chrome and other browsers. -// - -a:focus { - outline: thin dotted; -} - -// -// Improve readability when focused and also mouse hovered in all browsers. -// - -a:active, -a:hover { - outline: 0; -} - -// ========================================================================== -// Typography -// ========================================================================== - -// -// Address variable `h1` font-size and margin within `section` and `article` -// contexts in Firefox 4+, Safari 5, and Chrome. -// - -h1 { - font-size: 2em; - margin: 0.67em 0; -} - -// -// Address styling not present in IE 8/9, Safari 5, and Chrome. -// - -abbr[title] { - border-bottom: 1px dotted; -} - -// -// Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome. -// - -b, -strong { - font-weight: bold; -} - -// -// Address styling not present in Safari 5 and Chrome. -// - -dfn { - font-style: italic; -} - -// -// Address differences between Firefox and other browsers. -// - -hr { - -moz-box-sizing: content-box; - box-sizing: content-box; - height: 0; -} - -// -// Address styling not present in IE 8/9. -// - -mark { - background: #ff0; - color: #000; -} - -// -// Correct font family set oddly in Safari 5 and Chrome. -// - -code, -kbd, -pre, -samp { - font-family: monospace, serif; - font-size: 1em; -} - -// -// Improve readability of pre-formatted text in all browsers. -// - -pre { - white-space: pre-wrap; -} - -// -// Set consistent quote types. -// - -q { - quotes: "\201C" "\201D" "\2018" "\2019"; -} - -// -// Address inconsistent and variable font size in all browsers. -// - -small { - font-size: 80%; -} - -// -// Prevent `sub` and `sup` affecting `line-height` in all browsers. -// - -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sup { - top: -0.5em; -} - -sub { - bottom: -0.25em; -} - -// ========================================================================== -// Embedded content -// ========================================================================== - -// -// Remove border when inside `a` element in IE 8/9. -// - -img { - border: 0; -} - -// -// Correct overflow displayed oddly in IE 9. -// - -svg:not(:root) { - overflow: hidden; -} - -// ========================================================================== -// Figures -// ========================================================================== - -// -// Address margin not present in IE 8/9 and Safari 5. -// - -figure { - margin: 0; -} - -// ========================================================================== -// Forms -// ========================================================================== - -// -// Define consistent border, margin, and padding. -// - -fieldset { - border: 1px solid #c0c0c0; - margin: 0 2px; - padding: 0.35em 0.625em 0.75em; -} - -// -// 1. Correct `color` not being inherited in IE 8/9. -// 2. Remove padding so people aren't caught out if they zero out fieldsets. -// - -legend { - border: 0; // 1 - padding: 0; // 2 -} - -// -// 1. Correct font family not being inherited in all browsers. -// 2. Correct font size not being inherited in all browsers. -// 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome. -// - -button, -input, -select, -textarea { - font-family: inherit; // 1 - font-size: 100%; // 2 - margin: 0; // 3 -} - -// -// Address Firefox 4+ setting `line-height` on `input` using `!important` in -// the UA stylesheet. -// - -button, -input { - line-height: normal; -} - -// -// Address inconsistent `text-transform` inheritance for `button` and `select`. -// All other form control elements do not inherit `text-transform` values. -// Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+. -// Correct `select` style inheritance in Firefox 4+ and Opera. -// - -button, -select { - text-transform: none; -} - -// -// 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` -// and `video` controls. -// 2. Correct inability to style clickable `input` types in iOS. -// 3. Improve usability and consistency of cursor style between image-type -// `input` and others. -// - -button, -html input[type="button"], // 1 -input[type="reset"], -input[type="submit"] { - -webkit-appearance: button; // 2 - cursor: pointer; // 3 -} - -// -// Re-set default cursor for disabled elements. -// - -button[disabled], -html input[disabled] { - cursor: default; -} - -// -// 1. Address box sizing set to `content-box` in IE 8/9. -// 2. Remove excess padding in IE 8/9. -// - -input[type="checkbox"], -input[type="radio"] { - box-sizing: border-box; // 1 - padding: 0; // 2 -} - -// -// 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome. -// 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome -// (include `-moz` to future-proof). -// - -input[type="search"] { - -webkit-appearance: textfield; // 1 - -moz-box-sizing: content-box; - -webkit-box-sizing: content-box; // 2 - box-sizing: content-box; -} - -// -// Remove inner padding and search cancel button in Safari 5 and Chrome -// on OS X. -// - -input[type="search"]::-webkit-search-cancel-button, -input[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; -} - -// -// Remove inner padding and border in Firefox 4+. -// - -button::-moz-focus-inner, -input::-moz-focus-inner { - border: 0; - padding: 0; -} - -// -// 1. Remove default vertical scrollbar in IE 8/9. -// 2. Improve readability and alignment in all browsers. -// - -textarea { - overflow: auto; // 1 - vertical-align: top; // 2 -} - -// ========================================================================== -// Tables -// ========================================================================== - -// -// Remove most spacing between table cells. -// - -table { - border-collapse: collapse; - border-spacing: 0; -} diff --git a/themes/bootswatch-cyborg/less/pager.less b/themes/bootswatch-cyborg/less/pager.less deleted file mode 100644 index 16993dd..0000000 --- a/themes/bootswatch-cyborg/less/pager.less +++ /dev/null @@ -1,55 +0,0 @@ -// -// Pager pagination -// -------------------------------------------------- - - -.pager { - padding-left: 0; - margin: @line-height-computed 0; - list-style: none; - text-align: center; - .clearfix(); - li { - display: inline; - > a, - > span { - display: inline-block; - padding: 5px 14px; - background-color: @pagination-bg; - border: 1px solid @pagination-border; - border-radius: @pager-border-radius; - } - - > a:hover, - > a:focus { - text-decoration: none; - background-color: @pagination-hover-bg; - } - } - - .next { - > a, - > span { - float: right; - } - } - - .previous { - > a, - > span { - float: left; - } - } - - .disabled { - > a, - > a:hover, - > a:focus, - > span { - color: @pager-disabled-color; - background-color: @pagination-bg; - cursor: not-allowed; - } - } - -} diff --git a/themes/bootswatch-cyborg/less/pagination.less b/themes/bootswatch-cyborg/less/pagination.less deleted file mode 100644 index b480b38..0000000 --- a/themes/bootswatch-cyborg/less/pagination.less +++ /dev/null @@ -1,83 +0,0 @@ -// -// Pagination (multiple pages) -// -------------------------------------------------- -.pagination { - display: inline-block; - padding-left: 0; - margin: @line-height-computed 0; - border-radius: @border-radius-base; - - > li { - display: inline; // Remove list-style and block-level defaults - > a, - > span { - position: relative; - float: left; // Collapse white-space - padding: @padding-base-vertical @padding-base-horizontal; - line-height: @line-height-base; - text-decoration: none; - background-color: @pagination-bg; - border: 1px solid @pagination-border; - margin-left: -1px; - } - &:first-child { - > a, - > span { - margin-left: 0; - .border-left-radius(@border-radius-base); - } - } - &:last-child { - > a, - > span { - .border-right-radius(@border-radius-base); - } - } - } - - > li > a, - > li > span { - &:hover, - &:focus { - background-color: @pagination-hover-bg; - } - } - - > .active > a, - > .active > span { - &, - &:hover, - &:focus { - z-index: 2; - color: @pagination-active-color; - background-color: @pagination-active-bg; - border-color: @pagination-active-bg; - cursor: default; - } - } - - > .disabled { - > span, - > a, - > a:hover, - > a:focus { - color: @pagination-disabled-color; - background-color: @pagination-bg; - border-color: @pagination-border; - cursor: not-allowed; - } - } -} - -// Sizing -// -------------------------------------------------- - -// Large -.pagination-lg { - .pagination-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @border-radius-large); -} - -// Small -.pagination-sm { - .pagination-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @border-radius-small); -} diff --git a/themes/bootswatch-cyborg/less/panels.less b/themes/bootswatch-cyborg/less/panels.less deleted file mode 100644 index 2343b25..0000000 --- a/themes/bootswatch-cyborg/less/panels.less +++ /dev/null @@ -1,148 +0,0 @@ -// -// Panels -// -------------------------------------------------- - - -// Base class -.panel { - margin-bottom: @line-height-computed; - background-color: @panel-bg; - border: 1px solid transparent; - border-radius: @panel-border-radius; - .box-shadow(0 1px 1px rgba(0,0,0,.05)); -} - -// Panel contents -.panel-body { - padding: 15px; - .clearfix(); -} - - -// List groups in panels -// -// By default, space out list group content from panel headings to account for -// any kind of custom content between the two. - -.panel { - > .list-group { - margin-bottom: 0; - - .list-group-item { - border-width: 1px 0; - - // Remove border radius for top one - &:first-child { - .border-top-radius(0); - } - // But keep it for the last one - &:last-child { - border-bottom: 0; - } - } - } -} -// Collapse space between when there's no additional content. -.panel-heading + .list-group { - .list-group-item:first-child { - border-top-width: 0; - } -} - - -// Tables in panels -// -// Place a non-bordered `.table` within a panel (not within a `.panel-body`) and -// watch it go full width. - -.panel { - > .table { - margin-bottom: 0; - } - > .panel-body + .table { - border-top: 1px solid @table-border-color; - } -} - - -// Optional heading -.panel-heading { - padding: 10px 15px; - border-bottom: 1px solid transparent; - .border-top-radius(@panel-border-radius - 1); -} - -// Within heading, strip any `h*` tag of it's default margins for spacing. -.panel-title { - margin-top: 0; - margin-bottom: 0; - font-size: ceil((@font-size-base * 1.125)); - > a { - color: inherit; - } -} - -// Optional footer (stays gray in every modifier class) -.panel-footer { - padding: 10px 15px; - background-color: @panel-footer-bg; - border-top: 1px solid @panel-inner-border; - .border-bottom-radius(@panel-border-radius - 1); -} - - -// Collapsable panels (aka, accordion) -// -// Wrap a series of panels in `.panel-group` to turn them into an accordion with -// the help of our collapse JavaScript plugin. - -.panel-group { - // Tighten up margin so it's only between panels - .panel { - margin-bottom: 0; - border-radius: @panel-border-radius; - overflow: hidden; // crop contents when collapsed - + .panel { - margin-top: 5px; - } - } - - .panel-heading { - border-bottom: 0; - + .panel-collapse .panel-body { - border-top: 1px solid @panel-inner-border; - } - } - .panel-footer { - border-top: 0; - + .panel-collapse .panel-body { - border-bottom: 1px solid @panel-inner-border; - } - } - - // New subcomponent for wrapping collapsable content for proper animations - .panel-collapse { - - } -} - - -// Contextual variations -.panel-default { - .panel-variant(@panel-default-border; @panel-default-text; @panel-default-heading-bg; @panel-default-border); -} -.panel-primary { - .panel-variant(@panel-primary-border; @panel-primary-text; @panel-primary-heading-bg; @panel-primary-border); -} -.panel-success { - .panel-variant(@panel-success-border; @panel-success-text; @panel-success-heading-bg; @panel-success-border); -} -.panel-warning { - .panel-variant(@panel-warning-border; @panel-warning-text; @panel-warning-heading-bg; @panel-warning-border); -} -.panel-danger { - .panel-variant(@panel-danger-border; @panel-danger-text; @panel-danger-heading-bg; @panel-danger-border); -} -.panel-info { - .panel-variant(@panel-info-border; @panel-info-text; @panel-info-heading-bg; @panel-info-border); -} diff --git a/themes/bootswatch-cyborg/less/print.less b/themes/bootswatch-cyborg/less/print.less deleted file mode 100644 index 1e4bffe..0000000 --- a/themes/bootswatch-cyborg/less/print.less +++ /dev/null @@ -1,100 +0,0 @@ -// -// Basic print styles -// -------------------------------------------------- -// Source: https://github.com/h5bp/html5-boilerplate/blob/master/css/main.css - -@media print { - - * { - text-shadow: none !important; - color: #000 !important; // Black prints faster: h5bp.com/s - background: transparent !important; - box-shadow: none !important; - } - - a, - a:visited { - text-decoration: underline; - } - - a[href]:after { - content: " (" attr(href) ")"; - } - - abbr[title]:after { - content: " (" attr(title) ")"; - } - - // Don't show links for images, or javascript/internal links - .ir a:after, - a[href^="javascript:"]:after, - a[href^="#"]:after { - content: ""; - } - - pre, - blockquote { - border: 1px solid #999; - page-break-inside: avoid; - } - - thead { - display: table-header-group; // h5bp.com/t - } - - tr, - img { - page-break-inside: avoid; - } - - img { - max-width: 100% !important; - } - - @page { - margin: 2cm .5cm; - } - - p, - h2, - h3 { - orphans: 3; - widows: 3; - } - - h2, - h3 { - page-break-after: avoid; - } - - // Bootstrap components - .navbar { - display: none; - } - .table { - td, - th { - background-color: #fff !important; - } - } - .btn, - .dropup > .btn { - > .caret { - border-top-color: #000 !important; - } - } - .label { - border: 1px solid #000; - } - - .table { - border-collapse: collapse !important; - } - .table-bordered { - th, - td { - border: 1px solid #ddd !important; - } - } - -} diff --git a/themes/bootswatch-cyborg/less/responsive-utilities.less b/themes/bootswatch-cyborg/less/responsive-utilities.less deleted file mode 100644 index c756b23..0000000 --- a/themes/bootswatch-cyborg/less/responsive-utilities.less +++ /dev/null @@ -1,220 +0,0 @@ -// -// Responsive: Utility classes -// -------------------------------------------------- - - -// IE10 Metro responsive -// Required for Windows 8 Metro split-screen snapping with IE10 -// -// Source: http://timkadlec.com/2012/10/ie10-snap-mode-and-responsive-design/ -@-ms-viewport{ - width: device-width; -} - -// IE10 on Windows Phone 8 -// IE10 on WP8 doesn't report CSS pixels, but actual device pixels. In -// other words, say on a Lumia, you'll get 768px as the device width, -// meaning users will see the tablet styles and not phone styles. -// -// Alternatively you can override this with JS (see source below), but -// we won't be doing that here given our limited scope. -// -// Source: http://timkadlec.com/2013/01/windows-phone-8-and-device-width/ -@media screen and (max-width: 400px) { - @-ms-viewport{ - width: 320px; - } -} - -// Hide from screenreaders and browsers -// Credit: HTML5 Boilerplate -.hidden { - display: none !important; - visibility: hidden !important; -} - -// Visibility utilities - -.visible-xs { - .responsive-invisibility(); - @media (max-width: @screen-xs-max) { - .responsive-visibility(); - } - &.visible-sm { - @media (min-width: @screen-sm) and (max-width: @screen-sm-max) { - .responsive-visibility(); - } - } - &.visible-md { - @media (min-width: @screen-md) and (max-width: @screen-md-max) { - .responsive-visibility(); - } - } - &.visible-lg { - @media (min-width: @screen-lg) { - .responsive-visibility(); - } - } -} -.visible-sm { - .responsive-invisibility(); - &.visible-xs { - @media (max-width: @screen-xs-max) { - .responsive-visibility(); - } - } - @media (min-width: @screen-sm) and (max-width: @screen-sm-max) { - .responsive-visibility(); - } - &.visible-md { - @media (min-width: @screen-md) and (max-width: @screen-md-max) { - .responsive-visibility(); - } - } - &.visible-lg { - @media (min-width: @screen-lg) { - .responsive-visibility(); - } - } -} -.visible-md { - .responsive-invisibility(); - &.visible-xs { - @media (max-width: @screen-xs-max) { - .responsive-visibility(); - } - } - &.visible-sm { - @media (min-width: @screen-sm) and (max-width: @screen-sm-max) { - .responsive-visibility(); - } - } - @media (min-width: @screen-md) and (max-width: @screen-md-max) { - .responsive-visibility(); - } - &.visible-lg { - @media (min-width: @screen-lg) { - .responsive-visibility(); - } - } -} -.visible-lg { - .responsive-invisibility(); - &.visible-xs { - @media (max-width: @screen-xs-max) { - .responsive-visibility(); - } - } - &.visible-sm { - @media (min-width: @screen-sm) and (max-width: @screen-sm-max) { - .responsive-visibility(); - } - } - &.visible-md { - @media (min-width: @screen-md) and (max-width: @screen-md-max) { - .responsive-visibility(); - } - } - @media (min-width: @screen-lg) { - .responsive-visibility(); - } -} - -.hidden-xs { - .responsive-visibility(); - @media (max-width: @screen-xs-max) { - .responsive-invisibility(); - } - &.hidden-sm { - @media (min-width: @screen-sm) and (max-width: @screen-sm-max) { - .responsive-invisibility(); - } - } - &.hidden-md { - @media (min-width: @screen-md) and (max-width: @screen-md-max) { - .responsive-invisibility(); - } - } - &.hidden-lg { - @media (min-width: @screen-lg) { - .responsive-invisibility(); - } - } -} -.hidden-sm { - .responsive-visibility(); - &.hidden-xs { - @media (max-width: @screen-xs-max) { - .responsive-invisibility(); - } - } - @media (min-width: @screen-sm) and (max-width: @screen-sm-max) { - .responsive-invisibility(); - } - &.hidden-md { - @media (min-width: @screen-md) and (max-width: @screen-md-max) { - .responsive-invisibility(); - } - } - &.hidden-lg { - @media (min-width: @screen-lg) { - .responsive-invisibility(); - } - } -} -.hidden-md { - .responsive-visibility(); - &.hidden-xs { - @media (max-width: @screen-xs-max) { - .responsive-invisibility(); - } - } - &.hidden-sm { - @media (min-width: @screen-sm) and (max-width: @screen-sm-max) { - .responsive-invisibility(); - } - } - @media (min-width: @screen-md) and (max-width: @screen-md-max) { - .responsive-invisibility(); - } - &.hidden-lg { - @media (min-width: @screen-lg) { - .responsive-invisibility(); - } - } -} -.hidden-lg { - .responsive-visibility(); - &.hidden-xs { - @media (max-width: @screen-xs-max) { - .responsive-invisibility(); - } - } - &.hidden-sm { - @media (min-width: @screen-sm) and (max-width: @screen-sm-max) { - .responsive-invisibility(); - } - } - &.hidden-md { - @media (min-width: @screen-md) and (max-width: @screen-md-max) { - .responsive-invisibility(); - } - } - @media (min-width: @screen-lg) { - .responsive-invisibility(); - } -} - -// Print utilities -.visible-print { - .responsive-invisibility(); -} - -@media print { - .visible-print { - .responsive-visibility(); - } - .hidden-print { - .responsive-invisibility(); - } -} diff --git a/themes/bootswatch-cyborg/less/scaffolding.less b/themes/bootswatch-cyborg/less/scaffolding.less deleted file mode 100644 index 53e1be5..0000000 --- a/themes/bootswatch-cyborg/less/scaffolding.less +++ /dev/null @@ -1,130 +0,0 @@ -// -// Scaffolding -// -------------------------------------------------- - - -// Reset the box-sizing - -*, -*:before, -*:after { - .box-sizing(border-box); -} - - -// Body reset - -html { - font-size: 62.5%; - -webkit-tap-highlight-color: rgba(0,0,0,0); -} - -body { - font-family: @font-family-base; - font-size: @font-size-base; - line-height: @line-height-base; - color: @text-color; - background-color: @body-bg; -} - -// Reset fonts for relevant elements -input, -button, -select, -textarea { - font-family: inherit; - font-size: inherit; - line-height: inherit; -} - -// Reset unusual Firefox-on-Android default style. -// -// See https://github.com/necolas/normalize.css/issues/214 - -button, -input, -select[multiple], -textarea { - background-image: none; -} - - -// Links - -a { - color: @link-color; - text-decoration: none; - - &:hover, - &:focus { - color: @link-hover-color; - text-decoration: underline; - } - - &:focus { - .tab-focus(); - } -} - - -// Images - -img { - vertical-align: middle; -} - -// Responsive images (ensure images don't scale beyond their parents) -.img-responsive { - .img-responsive(); -} - -// Rounded corners -.img-rounded { - border-radius: @border-radius-large; -} - -// Image thumbnails -// -// Heads up! This is mixin-ed into thumbnails.less for `.thumbnail`. -.img-thumbnail { - padding: @thumbnail-padding; - line-height: @line-height-base; - background-color: @thumbnail-bg; - border: 1px solid @thumbnail-border; - border-radius: @thumbnail-border-radius; - .transition(all .2s ease-in-out); - - // Keep them at most 100% wide - .img-responsive(inline-block); -} - -// Perfect circle -.img-circle { - border-radius: 50%; // set radius in percents -} - - -// Horizontal rules - -hr { - margin-top: @line-height-computed; - margin-bottom: @line-height-computed; - border: 0; - border-top: 1px solid @hr-border; -} - - -// Only display content to screen readers -// -// See: http://a11yproject.com/posts/how-to-hide-content/ - -.sr-only { - position: absolute; - width: 1px; - height: 1px; - margin: -1px; - padding: 0; - overflow: hidden; - clip: rect(0 0 0 0); - border: 0; -} diff --git a/themes/bootswatch-cyborg/less/tables.less b/themes/bootswatch-cyborg/less/tables.less deleted file mode 100644 index 7543b16..0000000 --- a/themes/bootswatch-cyborg/less/tables.less +++ /dev/null @@ -1,236 +0,0 @@ -// -// Tables -// -------------------------------------------------- - - -table { - max-width: 100%; - background-color: @table-bg; -} -th { - text-align: left; -} - - -// Baseline styles - -.table { - width: 100%; - margin-bottom: @line-height-computed; - // Cells - thead, - tbody, - tfoot { - > tr { - > th, - > td { - padding: @table-cell-padding; - line-height: @line-height-base; - vertical-align: top; - border-top: 1px solid @table-border-color; - } - } - } - // Bottom align for column headings - thead > tr > th { - vertical-align: bottom; - border-bottom: 2px solid @table-border-color; - } - // Remove top border from thead by default - caption + thead, - colgroup + thead, - thead:first-child { - tr:first-child { - th, td { - border-top: 0; - } - } - } - // Account for multiple tbody instances - tbody + tbody { - border-top: 2px solid @table-border-color; - } - - // Nesting - .table { - background-color: @body-bg; - } -} - - -// Condensed table w/ half padding - -.table-condensed { - thead, - tbody, - tfoot { - > tr { - > th, - > td { - padding: @table-condensed-cell-padding; - } - } - } -} - - -// Bordered version -// -// Add borders all around the table and between all the columns. - -.table-bordered { - border: 1px solid @table-border-color; - > thead, - > tbody, - > tfoot { - > tr { - > th, - > td { - border: 1px solid @table-border-color; - } - } - } - > thead { - > tr { - > th, - > td { - border-bottom-width: 2px; - } - } - } -} - - -// Zebra-striping -// -// Default zebra-stripe styles (alternating gray and transparent backgrounds) - -.table-striped { - > tbody { - > tr:nth-child(odd) { - > td, - > th { - background-color: @table-bg-accent; - } - } - } -} - - -// Hover effect -// -// Placed here since it has to come after the potential zebra striping - -.table-hover { - > tbody { - > tr:hover { - > td, - > th { - background-color: @table-bg-hover; - } - } - } -} - - -// Table cell sizing -// -// Reset default table behavior - -table col[class*="col-"] { - float: none; - display: table-column; -} -table { - td, - th { - &[class*="col-"] { - float: none; - display: table-cell; - } - } -} - - -// Table backgrounds -// -// Exact selectors below required to override `.table-striped` and prevent -// inheritance to nested tables. - -.table > thead > tr, -.table > tbody > tr, -.table > tfoot > tr { - > td.active, - > th.active, - &.active > td, - &.active > th { - background-color: @table-bg-active; - } -} - -// Generate the contextual variants -.table-row-variant(success; @state-success-bg; @state-success-border); -.table-row-variant(danger; @state-danger-bg; @state-danger-border); -.table-row-variant(warning; @state-warning-bg; @state-warning-border); - - -// Responsive tables -// -// Wrap your tables in `.table-scrollable` and we'll make them mobile friendly -// by enabling horizontal scrolling. Only applies <768px. Everything above that -// will display normally. - -@media (max-width: @screen-sm) { - .table-responsive { - width: 100%; - margin-bottom: 15px; - overflow-y: hidden; - overflow-x: scroll; - border: 1px solid @table-border-color; - - // Tighten up spacing and give a background color - > .table { - margin-bottom: 0; - background-color: #fff; - - // Ensure the content doesn't wrap - > thead, - > tbody, - > tfoot { - > tr { - > th, - > td { - white-space: nowrap; - } - } - } - } - - // Special overrides for the bordered tables - > .table-bordered { - border: 0; - - // Nuke the appropriate borders so that the parent can handle them - > thead, - > tbody, - > tfoot { - > tr { - > th:first-child, - > td:first-child { - border-left: 0; - } - > th:last-child, - > td:last-child { - border-right: 0; - } - } - > tr:last-child { - > th, - > td { - border-bottom: 0; - } - } - } - } - } -} diff --git a/themes/bootswatch-cyborg/less/theme.less b/themes/bootswatch-cyborg/less/theme.less deleted file mode 100644 index 92469c4..0000000 --- a/themes/bootswatch-cyborg/less/theme.less +++ /dev/null @@ -1,232 +0,0 @@ - -// -// Load core variables and mixins -// -------------------------------------------------- - -@import "variables.less"; -@import "mixins.less"; - - - -// -// Buttons -// -------------------------------------------------- - -// Common styles -.btn-default, -.btn-primary, -.btn-success, -.btn-info, -.btn-warning, -.btn-danger { - text-shadow: 0 -1px 0 rgba(0,0,0,.2); - @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075); - .box-shadow(@shadow); - - // Reset the shadow - &:active, - &.active { - .box-shadow(inset 0 3px 5px rgba(0,0,0,.125)); - } -} - -// Mixin for generating new styles -.btn-styles(@btn-color: #555;) { - #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 10%)); - border-color: darken(@btn-color, 12%); - - &:active, - &.active { - background-color: darken(@btn-color, 10%); - border-color: darken(@btn-color, 12%); - } -} - -// Common styles -.btn { - // Remove the gradient for the pressed/active state - &:active, - &.active { - background-image: none; - } -} - -// Apply the mixin to the buttons -.btn-default { .btn-styles(@btn-default-bg;); text-shadow: 0 1px 0 #fff; border-color: #ccc; } -.btn-primary { .btn-styles(@btn-primary-bg); } -.btn-success { .btn-styles(@btn-success-bg); } -.btn-warning { .btn-styles(@btn-warning-bg); } -.btn-danger { .btn-styles(@btn-danger-bg); } -.btn-info { .btn-styles(@btn-info-bg); } - - - -// -// Images -// -------------------------------------------------- - -.thumbnail, -.img-thumbnail { - .box-shadow(0 1px 2px rgba(0,0,0,.075)); -} - - - -// -// Dropdowns -// -------------------------------------------------- - -.dropdown-menu > li > a:hover, -.dropdown-menu > li > a:focus, -.dropdown-menu > .active > a, -.dropdown-menu > .active > a:hover, -.dropdown-menu > .active > a:focus { - #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%)); - background-color: darken(@dropdown-link-hover-bg, 5%); -} - - - -// -// Navbar -// -------------------------------------------------- - -// Basic navbar -.navbar { - #gradient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg;); - border-radius: @navbar-border-radius; - @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075); - .box-shadow(@shadow); - - .navbar-nav > .active > a { - background-color: @navbar-default-bg; - } -} -.navbar-brand, -.navbar-nav > li > a { - text-shadow: 0 1px 0 rgba(255,255,255,.25); -} - -// Inverted navbar -.navbar-inverse { - #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg;); - - .navbar-nav > .active > a { - background-color: @navbar-inverse-bg; - } - - .navbar-brand, - .navbar-nav > li > a { - text-shadow: 0 -1px 0 rgba(0,0,0,.25); - } -} - -// Undo rounded corners in static and fixed navbars -.navbar-static-top, -.navbar-fixed-top, -.navbar-fixed-bottom { - border-radius: 0; -} - - - -// -// Alerts -// -------------------------------------------------- - -// Common styles -.alert { - text-shadow: 0 1px 0 rgba(255,255,255,.2); - @shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05); - .box-shadow(@shadow); -} - -// Mixin for generating new styles -.alert-styles(@color) { - #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%)); - border-color: darken(@color, 15%); -} - -// Apply the mixin to the alerts -.alert-success { .alert-styles(@alert-success-bg); } -.alert-info { .alert-styles(@alert-info-bg); } -.alert-warning { .alert-styles(@alert-warning-bg); } -.alert-danger { .alert-styles(@alert-danger-bg); } - - - -// -// Progress bars -// -------------------------------------------------- - -// Give the progress background some depth -.progress { - #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg;) -} - -// Mixin for generating new styles -.progress-bar-styles(@color) { - #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%)); -} - -// Apply the mixin to the progress bars -.progress-bar { .progress-bar-styles(@progress-bar-bg); } -.progress-bar-success { .progress-bar-styles(@progress-bar-success-bg); } -.progress-bar-info { .progress-bar-styles(@progress-bar-info-bg); } -.progress-bar-warning { .progress-bar-styles(@progress-bar-warning-bg); } -.progress-bar-danger { .progress-bar-styles(@progress-bar-danger-bg); } - - - -// -// List groups -// -------------------------------------------------- - -.list-group { - border-radius: @border-radius-base; - .box-shadow(0 1px 2px rgba(0,0,0,.075)); -} -.list-group-item.active, -.list-group-item.active:hover, -.list-group-item.active:focus { - text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%); - #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-group-active-bg, 7.5%)); - border-color: darken(@list-group-active-border, 7.5%); -} - - - -// -// Panels -// -------------------------------------------------- - -// Common styles -.panel { - .box-shadow(0 1px 2px rgba(0,0,0,.05)); -} - -// Mixin for generating new styles -.panel-heading-styles(@color) { - #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%)); -} - -// Apply the mixin to the panel headings only -.panel-default > .panel-heading { .panel-heading-styles(@panel-default-heading-bg); } -.panel-primary > .panel-heading { .panel-heading-styles(@panel-primary-heading-bg); } -.panel-success > .panel-heading { .panel-heading-styles(@panel-success-heading-bg); } -.panel-info > .panel-heading { .panel-heading-styles(@panel-info-heading-bg); } -.panel-warning > .panel-heading { .panel-heading-styles(@panel-warning-heading-bg); } -.panel-danger > .panel-heading { .panel-heading-styles(@panel-danger-heading-bg); } - - - -// -// Wells -// -------------------------------------------------- - -.well { - #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg;); - border-color: darken(@well-bg, 10%); - @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1); - .box-shadow(@shadow); -} diff --git a/themes/bootswatch-cyborg/less/type.less b/themes/bootswatch-cyborg/less/type.less deleted file mode 100644 index c40a891..0000000 --- a/themes/bootswatch-cyborg/less/type.less +++ /dev/null @@ -1,238 +0,0 @@ -// -// Typography -// -------------------------------------------------- - - -// Body text -// ------------------------- - -p { - margin: 0 0 (@line-height-computed / 2); -} -.lead { - margin-bottom: @line-height-computed; - font-size: (@font-size-base * 1.15); - font-weight: 200; - line-height: 1.4; - - @media (min-width: 768px) { - font-size: (@font-size-base * 1.5); - } -} - - -// Emphasis & misc -// ------------------------- - -// Ex: 14px base font * 85% = about 12px -small { font-size: 85%; } - -// Undo browser default styling -cite { font-style: normal; } - -// Contextual emphasis -.text-muted { color: @text-muted; } -.text-primary { color: @brand-primary; } -.text-warning { color: @state-warning-text; } -.text-danger { color: @state-danger-text; } -.text-success { color: @state-success-text; } -.text-info { color: @state-info-text; } - -// Alignment -.text-left { text-align: left; } -.text-right { text-align: right; } -.text-center { text-align: center; } - - -// Headings -// ------------------------- - -h1, h2, h3, h4, h5, h6, -.h1, .h2, .h3, .h4, .h5, .h6 { - font-family: @headings-font-family; - font-weight: @headings-font-weight; - line-height: @headings-line-height; - small { - font-weight: normal; - line-height: 1; - color: @headings-small-color; - } -} - -h1, -h2, -h3 { - margin-top: @line-height-computed; - margin-bottom: (@line-height-computed / 2); -} -h4, -h5, -h6 { - margin-top: (@line-height-computed / 2); - margin-bottom: (@line-height-computed / 2); -} - -h1, .h1 { font-size: floor(@font-size-base * 2.60); } // ~36px -h2, .h2 { font-size: floor(@font-size-base * 2.15); } // ~30px -h3, .h3 { font-size: ceil(@font-size-base * 1.70); } // ~24px -h4, .h4 { font-size: ceil(@font-size-base * 1.25); } // ~18px -h5, .h5 { font-size: @font-size-base; } -h6, .h6 { font-size: ceil(@font-size-base * 0.85); } // ~12px - -h1 small, .h1 small { font-size: ceil(@font-size-base * 1.70); } // ~24px -h2 small, .h2 small { font-size: ceil(@font-size-base * 1.25); } // ~18px -h3 small, .h3 small, -h4 small, .h4 small { font-size: @font-size-base; } - - -// Page header -// ------------------------- - -.page-header { - padding-bottom: ((@line-height-computed / 2) - 1); - margin: (@line-height-computed * 2) 0 @line-height-computed; - border-bottom: 1px solid @page-header-border-color; -} - - - -// Lists -// -------------------------------------------------- - -// Unordered and Ordered lists -ul, -ol { - margin-top: 0; - margin-bottom: (@line-height-computed / 2); - ul, - ol{ - margin-bottom: 0; - } -} - -// List options - -// Unstyled keeps list items block level, just removes default browser padding and list-style -.list-unstyled { - padding-left: 0; - list-style: none; -} -// Inline turns list items into inline-block -.list-inline { - .list-unstyled(); - > li { - display: inline-block; - padding-left: 5px; - padding-right: 5px; - } -} - -// Description Lists -dl { - margin-bottom: @line-height-computed; -} -dt, -dd { - line-height: @line-height-base; -} -dt { - font-weight: bold; -} -dd { - margin-left: 0; // Undo browser default -} - -// Horizontal description lists -// -// Defaults to being stacked without any of the below styles applied, until the -// grid breakpoint is reached (default of ~768px). - -@media (min-width: @grid-float-breakpoint) { - .dl-horizontal { - dt { - float: left; - width: (@component-offset-horizontal - 20); - clear: left; - text-align: right; - .text-overflow(); - } - dd { - margin-left: @component-offset-horizontal; - .clearfix(); // Clear the floated `dt` if an empty `dd` is present - } - } -} - -// MISC -// ---- - -// Abbreviations and acronyms -abbr[title], -// Added data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257 -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted @abbr-border-color; -} -abbr.initialism { - font-size: 90%; - text-transform: uppercase; -} - -// Blockquotes -blockquote { - padding: (@line-height-computed / 2) @line-height-computed; - margin: 0 0 @line-height-computed; - border-left: 5px solid @blockquote-border-color; - p { - font-size: (@font-size-base * 1.25); - font-weight: 300; - line-height: 1.25; - } - p:last-child { - margin-bottom: 0; - } - small { - display: block; - line-height: @line-height-base; - color: @blockquote-small-color; - &:before { - content: '\2014 \00A0';// EM DASH, NBSP - } - } - - // Float right with text-align: right - &.pull-right { - padding-right: 15px; - padding-left: 0; - border-right: 5px solid @blockquote-border-color; - border-left: 0; - p, - small { - text-align: right; - } - small { - &:before { - content: ''; - } - &:after { - content: '\00A0 \2014';// NBSP, EM DASH - } - } - } -} - -// Quotes -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; -} - -// Addresses -address { - display: block; - margin-bottom: @line-height-computed; - font-style: normal; - line-height: @line-height-base; -} diff --git a/themes/bootswatch-cyborg/less/utilities.less b/themes/bootswatch-cyborg/less/utilities.less deleted file mode 100644 index 3d310e6..0000000 --- a/themes/bootswatch-cyborg/less/utilities.less +++ /dev/null @@ -1,42 +0,0 @@ -// -// Utility classes -// -------------------------------------------------- - - -// Floats -// ------------------------- - -.clearfix { - .clearfix(); -} -.pull-right { - float: right !important; -} -.pull-left { - float: left !important; -} - - -// Toggling content -// ------------------------- - -.hide { - display: none !important; -} -.show { - display: block !important; -} -.invisible { - visibility: hidden; -} -.text-hide { - .hide-text(); -} - - -// For Affix plugin -// ------------------------- - -.affix { - position: fixed; -} diff --git a/themes/bootswatch-cyborg/less/variables.less b/themes/bootswatch-cyborg/less/variables.less deleted file mode 100644 index 23ed64f..0000000 --- a/themes/bootswatch-cyborg/less/variables.less +++ /dev/null @@ -1,620 +0,0 @@ -// Cyborg 3.0.0 -// Variables -// -------------------------------------------------- - - -// Global values -// -------------------------------------------------- - -// Grays -// ------------------------- - -@gray-darker: #222; -@gray-dark: #282828; -@gray: #555; -@gray-light: #888; -@gray-lighter: #ADAFAE; // #eee - -// Brand colors -// ------------------------- - -@brand-primary: #2A9FD6; -@brand-success: #77B300; -@brand-warning: #FF8800; -@brand-danger: #CC0000; -@brand-info: #9933CC; - -// Scaffolding -// ------------------------- - -@body-bg: #060606; -@text-color: @gray-light; - -// Links -// ------------------------- - -@link-color: @brand-primary; -@link-hover-color: @link-color; - -// Typography -// ------------------------- - -@font-family-sans-serif: "Droid Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; -@font-family-serif: Georgia, "Times New Roman", Times, serif; -@font-family-monospace: Monaco, Menlo, Consolas, "Courier New", monospace; -@font-family-base: @font-family-sans-serif; - -@font-size-base: 14px; -@font-size-large: ceil(@font-size-base * 1.25); // ~18px -@font-size-small: ceil(@font-size-base * 0.85); // ~12px - -@line-height-base: 1.428571429; // 20/14 -@line-height-computed: floor(@font-size-base * @line-height-base); // ~20px - -@headings-font-family: @font-family-base; -@headings-font-weight: 500; -@headings-line-height: 1.1; - -// Iconography -// ------------------------- - -@icon-font-path: "../fonts/"; -@icon-font-name: "glyphicons-halflings-regular"; - - -// Components -// ------------------------- -// Based on 14px font-size and 1.428 line-height (~20px to start) - -@padding-base-vertical: 8px; -@padding-base-horizontal: 12px; - -@padding-large-vertical: 14px; -@padding-large-horizontal: 16px; - -@padding-small-vertical: 5px; -@padding-small-horizontal: 10px; - -@line-height-large: 1.33; -@line-height-small: 1.5; - -@border-radius-base: 4px; -@border-radius-large: 6px; -@border-radius-small: 3px; - -@component-active-bg: @brand-primary; - -@caret-width-base: 4px; -@caret-width-large: 5px; - -// Tables -// ------------------------- - -@table-cell-padding: 8px; -@table-condensed-cell-padding: 5px; - -@table-bg: darken(@gray-darker, 4%); // overall background-color -@table-bg-accent: darken(@table-bg, 6%); // for striping -@table-bg-hover: @gray-dark; -@table-bg-active: @table-bg-hover; - -@table-border-color: @gray-dark; // table and cell border - - -// Buttons -// ------------------------- - -@btn-font-weight: normal; - -@btn-default-color: #fff; -@btn-default-bg: lighten(@gray-dark, 10%); -@btn-default-border: @btn-default-bg; - -@btn-primary-color: @btn-default-color; -@btn-primary-bg: @brand-primary; -@btn-primary-border: @btn-primary-bg; - -@btn-success-color: @btn-default-color; -@btn-success-bg: @brand-success; -@btn-success-border: @btn-success-bg; - -@btn-warning-color: @btn-default-color; -@btn-warning-bg: @brand-warning; -@btn-warning-border: @btn-warning-bg; - -@btn-danger-color: @btn-default-color; -@btn-danger-bg: @brand-danger; -@btn-danger-border: @btn-danger-bg; - -@btn-info-color: @btn-default-color; -@btn-info-bg: @brand-info; -@btn-info-border: @btn-info-bg; - -@btn-link-disabled-color: @gray-light; - - -// Forms -// ------------------------- - -@input-bg: #fff; -@input-bg-disabled: @gray-lighter; - -@input-color: @text-color; -@input-border: @gray-dark; -@input-border-radius: @border-radius-base; -@input-border-focus: #66afe9; - -@input-color-placeholder: @gray-light; - -@input-height-base: (@line-height-computed + (@padding-base-vertical * 2) + 2); -@input-height-large: (ceil(@font-size-large * @line-height-base) + (@padding-large-vertical * 2) + 2); -@input-height-small: (ceil(@font-size-small * @line-height-base) + (@padding-small-vertical * 2) + 2); - -@legend-color: @text-color; -@legend-border-color: @gray-dark; - -@input-group-addon-bg: @gray-lighter; -@input-group-addon-border-color: @input-border; - - -// Dropdowns -// ------------------------- - -@dropdown-bg: @gray-darker; -@dropdown-border: rgba(255,255,255,0.1); -@dropdown-fallback-border: #444; -@dropdown-divider-bg: rgba(255,255,255,0.1); - -@dropdown-link-active-color: #fff; -@dropdown-link-active-bg: @component-active-bg; - -@dropdown-link-color: #fff; -@dropdown-link-hover-color: #fff; -@dropdown-link-hover-bg: @dropdown-link-active-bg; - -@dropdown-link-disabled-color: @text-muted; - -@dropdown-header-color: @text-muted; - -@dropdown-caret-color: #000; - - -// COMPONENT VARIABLES -// -------------------------------------------------- - - -// Z-index master list -// ------------------------- -// Used for a bird's eye view of components dependent on the z-axis -// Try to avoid customizing these :) - -@zindex-navbar: 1000; -@zindex-dropdown: 1000; -@zindex-popover: 1010; -@zindex-tooltip: 1030; -@zindex-navbar-fixed: 1030; -@zindex-modal-background: 1040; -@zindex-modal: 1050; - -// Media queries breakpoints -// -------------------------------------------------- - -// Extra small screen / phone -@screen-xs: 480px; -@screen-phone: @screen-xs; - -// Small screen / tablet -@screen-sm: 768px; -@screen-tablet: @screen-sm; - -// Medium screen / desktop -@screen-md: 992px; -@screen-desktop: @screen-md; - -// Large screen / wide desktop -@screen-lg: 1200px; -@screen-lg-desktop: @screen-lg; - -// So media queries don't overlap when required, provide a maximum -@screen-xs-max: (@screen-sm - 1); -@screen-sm-max: (@screen-md - 1); -@screen-md-max: (@screen-lg - 1); - - -// Grid system -// -------------------------------------------------- - -// Number of columns in the grid system -@grid-columns: 12; -// Padding, to be divided by two and applied to the left and right of all columns -@grid-gutter-width: 30px; -// Point at which the navbar stops collapsing -@grid-float-breakpoint: @screen-tablet; - - -// Navbar -// ------------------------- - -// Basics of a navbar -@navbar-height: 50px; -@navbar-margin-bottom: @line-height-computed; -@navbar-default-color: @text-color; -@navbar-default-bg: @body-bg; -@navbar-default-border: darken(@navbar-default-bg, 6.5%); -@navbar-border-radius: @border-radius-base; -@navbar-padding-horizontal: floor(@grid-gutter-width / 2); -@navbar-padding-vertical: ((@navbar-height - @line-height-computed) / 2); - -// Navbar links -@navbar-default-link-color: @text-color; -@navbar-default-link-hover-color: #fff; -@navbar-default-link-hover-bg: transparent; -@navbar-default-link-active-color: #fff; -@navbar-default-link-active-bg: transparent; -@navbar-default-link-disabled-color: @gray-light; -@navbar-default-link-disabled-bg: transparent; - -// Navbar brand label -@navbar-default-brand-color: #fff; -@navbar-default-brand-hover-color: #fff; -@navbar-default-brand-hover-bg: transparent; - -// Navbar toggle -@navbar-default-toggle-hover-bg: @gray-dark; -@navbar-default-toggle-icon-bar-bg: #ccc; -@navbar-default-toggle-border-color: @gray-dark; - - -// Inverted navbar -// -// Reset inverted navbar basics -@navbar-inverse-color: @gray-light; -@navbar-inverse-bg: @gray-darker; -@navbar-inverse-border: darken(@navbar-inverse-bg, 10%); - -// Inverted navbar links -@navbar-inverse-link-color: @gray-light; -@navbar-inverse-link-hover-color: #fff; -@navbar-inverse-link-hover-bg: transparent; -@navbar-inverse-link-active-color: @navbar-inverse-link-hover-color; -@navbar-inverse-link-active-bg: transparent; -@navbar-inverse-link-disabled-color: #aaa; -@navbar-inverse-link-disabled-bg: transparent; - -// Inverted navbar brand label -@navbar-inverse-brand-color: #fff; -@navbar-inverse-brand-hover-color: #fff; -@navbar-inverse-brand-hover-bg: transparent; - -// Inverted navbar search -// Normal navbar needs no special styles or vars -@navbar-inverse-search-bg: lighten(@navbar-inverse-bg, 25%); -@navbar-inverse-search-bg-focus: #fff; -@navbar-inverse-search-border: @navbar-inverse-bg; -@navbar-inverse-search-placeholder-color: #ccc; - -// Inverted navbar toggle -@navbar-inverse-toggle-hover-bg: #333; -@navbar-inverse-toggle-icon-bar-bg: #fff; -@navbar-inverse-toggle-border-color: #333; - - -// Navs -// ------------------------- - -@nav-link-padding: 10px 15px; -@nav-link-hover-bg: @gray-darker; - -@nav-disabled-link-color: @gray-light; -@nav-disabled-link-hover-color: @gray-light; - -@nav-open-link-hover-color: @gray-darker; -@nav-open-caret-border-color: #fff; - -// Tabs -@nav-tabs-border-color: @gray-dark; - -@nav-tabs-link-hover-border-color: transparent; - -@nav-tabs-active-link-hover-bg: @brand-primary; -@nav-tabs-active-link-hover-color: #fff; -@nav-tabs-active-link-hover-border-color: @gray-dark; - -@nav-tabs-justified-link-border-color: #ddd; -@nav-tabs-justified-active-link-border-color: @body-bg; - -// Pills -@nav-pills-active-link-hover-bg: @component-active-bg; -@nav-pills-active-link-hover-color: #fff; - - -// Pagination -// ------------------------- - -@pagination-bg: @gray-darker; -@pagination-border: @gray-dark; - -@pagination-hover-bg: @gray-lighter; - -@pagination-active-bg: @brand-primary; -@pagination-active-color: #fff; - -@pagination-disabled-color: @gray-light; - - -// Pager -// ------------------------- - -@pager-border-radius: 15px; -@pager-disabled-color: @gray-light; - - -// Jumbotron -// ------------------------- - -@jumbotron-padding: 30px; -@jumbotron-color: inherit; -@jumbotron-bg: darken(@gray-darker, 5%); - -@jumbotron-heading-color: inherit; - - -// Form states and alerts -// ------------------------- - -@state-warning-text: #fff; -@state-warning-bg: @brand-warning; -@state-warning-border: darken(spin(@state-warning-bg, -10), 3%); - -@state-danger-text: #fff; -@state-danger-bg: @brand-danger; -@state-danger-border: darken(spin(@state-danger-bg, -10), 3%); - -@state-success-text: #fff; -@state-success-bg: @brand-success; -@state-success-border: darken(spin(@state-success-bg, -10), 5%); - -@state-info-text: #fff; -@state-info-bg: @brand-info; -@state-info-border: darken(spin(@state-info-bg, -10), 7%); - - -// Tooltips -// ------------------------- -@tooltip-max-width: 200px; -@tooltip-color: #fff; -@tooltip-bg: rgba(0,0,0,.9); - -@tooltip-arrow-width: 5px; -@tooltip-arrow-color: @tooltip-bg; - - -// Popovers -// ------------------------- -@popover-bg: lighten(@body-bg, 10%); -@popover-max-width: 276px; -@popover-border-color: rgba(0,0,0,.2); -@popover-fallback-border-color: #999; - -@popover-title-bg: darken(@popover-bg, 3%); - -@popover-arrow-width: 10px; -@popover-arrow-color: @popover-bg; - -@popover-arrow-outer-width: (@popover-arrow-width + 1); -@popover-arrow-outer-color: rgba(0,0,0,.25); -@popover-arrow-outer-fallback-color: #999; - - -// Labels -// ------------------------- - -@label-default-bg: @btn-default-bg; -@label-primary-bg: @brand-primary; -@label-success-bg: @brand-success; -@label-info-bg: @brand-info; -@label-warning-bg: @brand-warning; -@label-danger-bg: @brand-danger; - -@label-color: #fff; -@label-link-hover-color: #fff; - - -// Modals -// ------------------------- -@modal-inner-padding: 20px; - -@modal-title-padding: 15px; -@modal-title-line-height: @line-height-base; - -@modal-content-bg: lighten(@body-bg, 10%); -@modal-content-border-color: rgba(0,0,0,.2); -@modal-content-fallback-border-color: #999; - -@modal-backdrop-bg: #000; -@modal-header-border-color: @gray-dark; -@modal-footer-border-color: @modal-header-border-color; - - -// Alerts -// ------------------------- -@alert-padding: 15px; -@alert-border-radius: @border-radius-base; -@alert-link-font-weight: bold; - -@alert-success-bg: @state-success-bg; -@alert-success-text: @state-success-text; -@alert-success-border: @state-success-border; - -@alert-info-bg: @state-info-bg; -@alert-info-text: @state-info-text; -@alert-info-border: @state-info-border; - -@alert-warning-bg: @state-warning-bg; -@alert-warning-text: @state-warning-text; -@alert-warning-border: @state-warning-border; - -@alert-danger-bg: @state-danger-bg; -@alert-danger-text: @state-danger-text; -@alert-danger-border: @state-danger-border; - - -// Progress bars -// ------------------------- -@progress-bg: @gray-darker; -@progress-bar-color: #fff; - -@progress-bar-bg: @brand-primary; -@progress-bar-success-bg: @brand-success; -@progress-bar-warning-bg: @brand-warning; -@progress-bar-danger-bg: @brand-danger; -@progress-bar-info-bg: @brand-info; - - -// List group -// ------------------------- -@list-group-bg: @gray-darker; -@list-group-border: @gray-dark; -@list-group-border-radius: @border-radius-base; - -@list-group-hover-bg: lighten(@list-group-bg, 15%); -@list-group-active-color: #fff; -@list-group-active-bg: @component-active-bg; -@list-group-active-border: @list-group-active-bg; - -@list-group-link-color: @text-color; -@list-group-link-heading-color: #fff; - - -// Panels -// ------------------------- -@panel-bg: @gray-darker; -@panel-inner-border: @gray-dark; -@panel-border-radius: @border-radius-base; -@panel-footer-bg: @panel-default-heading-bg; - -@panel-default-text: @gray-dark; -@panel-default-border: @panel-inner-border; -@panel-default-heading-bg: lighten(@gray-darker, 10%); - -@panel-primary-text: #fff; -@panel-primary-border: @brand-primary; -@panel-primary-heading-bg: @brand-primary; - -@panel-success-text: @state-success-text; -@panel-success-border: @state-success-border; -@panel-success-heading-bg: @state-success-bg; - -@panel-warning-text: @state-warning-text; -@panel-warning-border: @state-warning-border; -@panel-warning-heading-bg: @state-warning-bg; - -@panel-danger-text: @state-danger-text; -@panel-danger-border: @state-danger-border; -@panel-danger-heading-bg: @state-danger-bg; - -@panel-info-text: @state-info-text; -@panel-info-border: @state-info-border; -@panel-info-heading-bg: @state-info-bg; - - -// Thumbnails -// ------------------------- -@thumbnail-padding: 4px; -@thumbnail-bg: @body-bg; -@thumbnail-border: #ddd; -@thumbnail-border-radius: @border-radius-base; - -@thumbnail-caption-color: @text-color; -@thumbnail-caption-padding: 9px; - - -// Wells -// ------------------------- -@well-bg: darken(@gray-darker, 5%); - - -// Badges -// ------------------------- -@badge-color: #fff; -@badge-link-hover-color: #fff; -@badge-bg: @brand-primary; - -@badge-active-color: @brand-primary; -@badge-active-bg: #fff; - -@badge-font-weight: bold; -@badge-line-height: 1; -@badge-border-radius: 10px; - - -// Breadcrumbs -// ------------------------- -@breadcrumb-bg: @gray-darker; -@breadcrumb-color: #fff; -@breadcrumb-active-color: @text-color; - - -// Carousel -// ------------------------ - -@carousel-text-shadow: 0 1px 2px rgba(0,0,0,.6); - -@carousel-control-color: #fff; -@carousel-control-width: 15%; -@carousel-control-opacity: .5; -@carousel-control-font-size: 20px; - -@carousel-indicator-active-bg: #fff; -@carousel-indicator-border-color: #fff; - -@carousel-caption-color: #fff; - - -// Close -// ------------------------ -@close-color: #000; -@close-font-weight: bold; -@close-text-shadow: 0 1px 0 #fff; - - -// Code -// ------------------------ -@code-color: #c7254e; -@code-bg: #f9f2f4; - -@pre-bg: #f5f5f5; -@pre-color: @gray-dark; -@pre-border-color: #ccc; -@pre-scrollable-max-height: 340px; - -// Type -// ------------------------ -@text-muted: @gray-light; -@abbr-border-color: @gray-light; -@headings-small-color: @gray-light; -@blockquote-small-color: @gray; -@blockquote-border-color: @gray-dark; -@page-header-border-color: @gray-dark; - -// Miscellaneous -// ------------------------- - -// Hr border color -@hr-border: @gray-dark; - -// Horizontal forms & lists -@component-offset-horizontal: 180px; - - -// Container sizes -// -------------------------------------------------- - -// Small screen / tablet -@container-tablet: ((720px + @grid-gutter-width)); - -// Medium screen / desktop -@container-desktop: ((940px + @grid-gutter-width)); - -// Large screen / wide desktop -@container-lg-desktop: ((1140px + @grid-gutter-width)); diff --git a/vendor/JsonRPC/Client.php b/vendor/JsonRPC/Client.php index 4f90eea..14fe507 100644 --- a/vendor/JsonRPC/Client.php +++ b/vendor/JsonRPC/Client.php @@ -25,7 +25,12 @@ class Client $this->headers = array_merge($this->headers, $headers); } + public function __call($method, $params) + { + return $this->execute($method, $params); + } + public function authentication($username, $password) { $this->username = $username; diff --git a/vendor/JsonRPC/Server.php b/vendor/JsonRPC/Server.php index 418924c..24b52bd 100644 --- a/vendor/JsonRPC/Server.php +++ b/vendor/JsonRPC/Server.php @@ -30,7 +30,6 @@ class Server { // OVH workaround if (isset($_SERVER['REMOTE_USER'])) { - list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':', base64_decode(substr($_SERVER['REMOTE_USER'], 6))); } @@ -106,9 +105,9 @@ class Server if (isset($request_params[$name])) { $params[$name] = $request_params[$name]; - } - else { - + } else if ($p->isDefaultValueAvailable()) { + continue; + } else { return false; } } diff --git a/vendor/PicoDb/Database.php b/vendor/PicoDb/Database.php index 3ec302a..fa3d71b 100644 --- a/vendor/PicoDb/Database.php +++ b/vendor/PicoDb/Database.php @@ -4,6 +4,7 @@ namespace PicoDb; class Database { + private static $instances = array(); private $logs = array(); private $pdo; @@ -11,7 +12,6 @@ class Database public function __construct(array $settings) { if (! isset($settings['driver'])) { - throw new \LogicException('You must define a database driver.'); } @@ -30,6 +30,26 @@ class Database } + public static function bootstrap($name, callable $callback) + { + self::$instances[$name] = $callback; + } + + + public static function get($name) + { + if (! isset(self::$instances[$name])) { + throw new \LogicException('No database instance created with that name.'); + } + + if (is_callable(self::$instances[$name])) { + self::$instances[$name] = call_user_func(self::$instances[$name]); + } + + return self::$instances[$name]; + } + + public function setLogMessage($message) { $this->logs[] = $message; @@ -68,6 +88,7 @@ class Database } catch (\PDOException $e) { + if ($this->pdo->inTransaction()) $this->pdo->rollback(); $this->setLogMessage($e->getMessage()); return false; } @@ -94,6 +115,7 @@ class Database public function table($table_name) { + require_once __DIR__.'/Table.php'; return new Table($this, $table_name); } diff --git a/vendor/PicoFarad/Request.php b/vendor/PicoFarad/Request.php index 38774bf..46c82bc 100644 --- a/vendor/PicoFarad/Request.php +++ b/vendor/PicoFarad/Request.php @@ -32,7 +32,6 @@ function values() $result = json_decode(body(), true); if ($result) { - return $result; } @@ -46,12 +45,34 @@ function body() } -function file_content($name) +function file_content($field) { - if (isset($_FILES[$name])) { - - return file_get_contents($_FILES[$name]['tmp_name']); + if (isset($_FILES[$field])) { + return file_get_contents($_FILES[$field]['tmp_name']); } return ''; +} + + +function file_info($field) +{ + if (isset($_FILES[$field])) { + return array( + 'name' => $_FILES[$field]['name'], + 'mimetype' => $_FILES[$field]['type'], + 'size' => $_FILES[$field]['size'], + ); + } + + return false; +} + + +function file_move($field, $destination) +{ + if (isset($_FILES[$field]) && ! file_exists($destination)) { + @mkdir(dirname($destination), 0777, true); + move_uploaded_file($_FILES[$field]['tmp_name'], $destination); + } } \ No newline at end of file diff --git a/vendor/PicoFarad/Response.php b/vendor/PicoFarad/Response.php index dc54e01..cb01296 100644 --- a/vendor/PicoFarad/Response.php +++ b/vendor/PicoFarad/Response.php @@ -9,14 +9,18 @@ function force_download($filename) } +function content_type($mimetype) +{ + header('Content-Type: '.$mimetype); +} + + function status($status_code) { if (strpos(php_sapi_name(), 'apache') !== false) { - header('HTTP/1.0 '.$status_code); } else { - header('Status: '.$status_code); } } diff --git a/vendor/PicoFarad/Router.php b/vendor/PicoFarad/Router.php index 4f0bfff..f542f3e 100644 --- a/vendor/PicoFarad/Router.php +++ b/vendor/PicoFarad/Router.php @@ -2,84 +2,105 @@ namespace PicoFarad\Router; +// Load controllers: bootstrap('controllers', 'controller1', 'controller2') +function bootstrap() +{ + $files = \func_get_args(); + $base_path = array_shift($files); + foreach ($files as $file) { + require $base_path.'/'.$file.'.php'; + } +} + +// Execute a callback before each action function before($value = null) { static $before_callback = null; if (is_callable($value)) { - $before_callback = $value; } else if (is_callable($before_callback)) { - $before_callback($value); } } +// Execute a callback before a specific action +function before_action($name, $value = null) +{ + static $callbacks = array(); -function action($name, \Closure $callback) + if (is_callable($value)) { + $callbacks[$name] = $value; + } + else if (isset($callbacks[$name]) && is_callable($callbacks[$name])) { + $callbacks[$name]($value); + } +} + +// Execute an action +function action($name, callable $callback) { $handler = isset($_GET['action']) ? $_GET['action'] : 'default'; if ($handler === $name) { - - before($handler); + before($name); + before_action($name); $callback(); } } - -function post_action($name, \Closure $callback) +// Execute an action only for POST requests +function post_action($name, callable $callback) { if ($_SERVER['REQUEST_METHOD'] === 'POST') { - action($name, $callback); } } - -function get_action($name, \Closure $callback) +// Execute an action only for GET requests +function get_action($name, callable $callback) { if ($_SERVER['REQUEST_METHOD'] === 'GET') { - action($name, $callback); } } - -function notfound(\Closure $callback) +// Run when no action have been executed before +function notfound(callable $callback) { - before(); + before('notfound'); + before_action('notfound'); $callback(); } - -function get($url, \Closure $callback) +// Match a request like this one: GET /myhandler +function get($url, callable $callback) { find_route('GET', $url, $callback); } - -function post($url, \Closure $callback) +// Match a request like this one: POST /myhandler +function post($url, callable $callback) { find_route('POST', $url, $callback); } - -function put($url, \Closure $callback) +// Match a request like this one: PUT /myhandler +function put($url, callable $callback) { find_route('PUT', $url, $callback); } - -function delete($url, \Closure $callback) +// Match a request like this one: DELETE /myhandler +function delete($url, callable $callback) { find_route('DELETE', $url, $callback); } - -function find_route($method, $route, \Closure $callback) +// Define which callback to execute according to the URL and the HTTP verb +function find_route($method, $route, callable $callback) { if ($_SERVER['REQUEST_METHOD'] === $method) { @@ -103,7 +124,7 @@ function find_route($method, $route, \Closure $callback) } } - +// Parse url and find matches function url_match($route_uri, $request_uri, array &$params) { if ($request_uri === $route_uri) return true; @@ -135,4 +156,4 @@ function url_match($route_uri, $request_uri, array &$params) } return false; -} \ No newline at end of file +} diff --git a/vendor/PicoFarad/Session.php b/vendor/PicoFarad/Session.php index 77543a2..bac3e52 100644 --- a/vendor/PicoFarad/Session.php +++ b/vendor/PicoFarad/Session.php @@ -5,8 +5,10 @@ namespace PicoFarad\Session; const SESSION_LIFETIME = 2678400; -function open($base_path = '/') +function open($base_path = '/', $save_path = '') { + if ($save_path !== '') session_save_path($save_path); + session_set_cookie_params( SESSION_LIFETIME, $base_path,