summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBernhard Posselt <nukeawhale@gmail.com>2013-02-11 15:30:31 +0100
committerBernhard Posselt <nukeawhale@gmail.com>2013-02-11 15:30:55 +0100
commit5492e60510379add1523454f322def81167be8be (patch)
tree8fff208ff6492758cff1b17aae7ec02c797cd322
parente10d99e13da782e4c4bed03974bb10959ed333b4 (diff)
new style and style cleanup for the news app
-rw-r--r--coffee/controllers/addnewcontroller.coffee20
-rw-r--r--coffee/controllers/controllers.coffee11
-rw-r--r--coffee/controllers/feedcontroller.coffee55
-rw-r--r--coffee/controllers/settingscontroller.coffee82
-rw-r--r--coffee/directives/addfolderselect.coffee33
-rw-r--r--coffee/directives/droppable.coffee4
-rw-r--r--coffee/lib/owncloud.coffee4
-rw-r--r--controller/news.controller.php11
-rw-r--r--css/addnew.css25
-rw-r--r--css/feeds.css82
-rw-r--r--css/items.css299
-rw-r--r--css/owncloud.css259
-rw-r--r--css/settings.css11
-rw-r--r--css/showall.css19
-rw-r--r--js/app.js256
-rw-r--r--lib/api.php7
-rw-r--r--templates/main.php78
-rw-r--r--templates/part.addnew.php35
-rw-r--r--templates/part.feed.starred.php17
-rw-r--r--templates/part.feed.unread.php20
-rw-r--r--templates/part.listfeed.php17
-rw-r--r--templates/part.listfolder.php25
-rw-r--r--templates/part.settings.php123
-rw-r--r--templates/part.showall.php7
24 files changed, 1132 insertions, 368 deletions
diff --git a/coffee/controllers/addnewcontroller.coffee b/coffee/controllers/addnewcontroller.coffee
new file mode 100644
index 000000000..348b1ecb1
--- /dev/null
+++ b/coffee/controllers/addnewcontroller.coffee
@@ -0,0 +1,20 @@
+###
+# ownCloud news app
+#
+# @author Alessandro Cosentino
+# @author Bernhard Posselt
+# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
+# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
+#
+# This file is licensed under the Affero General Public License version 3 or
+# later.
+#
+# See the COPYING-README file
+#
+###
+angular.module('News').factory '_AddNewController',
+['Controller', (Controller) ->
+
+ class AddNewController extends Controller
+
+] \ No newline at end of file
diff --git a/coffee/controllers/controllers.coffee b/coffee/controllers/controllers.coffee
index 606ad9ac4..62476443f 100644
--- a/coffee/controllers/controllers.coffee
+++ b/coffee/controllers/controllers.coffee
@@ -18,9 +18,8 @@ angular.module('News').controller 'SettingsController',
'FolderModel', 'FeedModel', 'OPMLParser',
(_SettingsController, $scope, $rootScope, ShowAll, PersistenceNews,
FolderModel, FeedModel, OPMLParser) ->
- return new _SettingsController($scope, $rootScope, ShowAll,
- PersistenceNews, FolderModel, FeedModel,
- OPMLParser)
+ return new _SettingsController($scope, $rootScope, PersistenceNews,
+ OPMLParser)
]
angular.module('News').controller 'ItemController',
@@ -43,4 +42,10 @@ StarredCount, ShowAll, ItemModel, GarbageRegistry, $rootScope, Loading, Config)
ActiveFeed, PersistenceNews, StarredCount, ShowAll,
ItemModel, GarbageRegistry, $rootScope, Loading,
Config)
+]
+
+angular.module('News').controller 'AddNewController',
+['_AddNewController', '$scope',
+(_AddNewController, $scope) ->
+ return new _AddNewController($scope)
] \ No newline at end of file
diff --git a/coffee/controllers/feedcontroller.coffee b/coffee/controllers/feedcontroller.coffee
index 6ce5ef5c0..4717a6594 100644
--- a/coffee/controllers/feedcontroller.coffee
+++ b/coffee/controllers/feedcontroller.coffee
@@ -25,7 +25,62 @@ angular.module('News').factory '_FeedController', ['Controller', (Controller) ->
@$scope.feeds = @feedModel.getItems()
@$scope.folders = @folderModel.getItems()
@$scope.feedType = @feedType
+
+ @$scope.getShowAll = =>
+ return @showAll.showAll
+
+ @$scope.setShowAll = (value) =>
+ @showAll.showAll = value
+ @persistence.showAll(value)
+ @$rootScope.$broadcast('triggerHideRead')
+
+ @$scope.addFeed = (url, folder) =>
+ @$scope.feedEmptyError = false
+ @$scope.feedExistsError = false
+ @$scope.feedError = false
+ if url == undefined or url.trim() == ''
+ @$scope.feedEmptyError = true
+ else
+ url = url.trim()
+ for feed in @feedModel.getItems()
+ if url == feed.url # FIXME: can we really compare this
+ @$scope.feedExistsError = true
+
+ if not (@$scope.feedEmptyError or @$scope.feedExistsError)
+ if folder == undefined
+ folderId = 0
+ else
+ folderId = folder.id
+ @addingFeed = true
+ onSuccess = =>
+ @$scope.feedUrl = ''
+ @addingFeed = false
+ onError = =>
+ @$scope.feedError = true
+ @addingFeed = false
+ @persistence.createFeed(url, folderId, onSuccess, onError)
+
+
+ @$scope.addFolder = (name) =>
+ @$scope.folderEmptyError = false
+ @$scope.folderExistsError = false
+
+ if name == undefined or name.trim() == ''
+ @$scope.folderEmptyError = true
+ else
+ name = name.trim()
+ for folder in @folderModel.getItems()
+ if name.toLowerCase() == folder.name.toLowerCase()
+ @$scope.folderExistsError = true
+
+ if not (@$scope.folderEmptyError or @$scope.folderExistsError)
+ @addingFolder = true
+ onSuccess = =>
+ @$scope.folderName = ''
+ @addingFolder = false
+ @persistence.createFolder(name, onSuccess)
+
@$scope.toggleFolder = (folderId) =>
folder = @folderModel.getItemById(folderId)
folder.open = !folder.open
diff --git a/coffee/controllers/settingscontroller.coffee b/coffee/controllers/settingscontroller.coffee
index 38036f89f..9afda5407 100644
--- a/coffee/controllers/settingscontroller.coffee
+++ b/coffee/controllers/settingscontroller.coffee
@@ -18,94 +18,16 @@ angular.module('News').factory '_SettingsController', ['Controller',
class SettingsController extends Controller
- constructor: (@$scope, @$rootScope, @showAll, @persistence, @folderModel,
- @feedModel, @opmlParser) ->
+ constructor: (@$scope, @$rootScope, @persistence, @opmlParser) ->
@add = false
@settings = false
@addingFeed = false
@addingFolder = false
- @$scope.getFolders = =>
- return @folderModel.getItems()
-
- @$scope.getShowAll = =>
- return @showAll.showAll
-
- @$scope.setShowAll = (value) =>
- @showAll.showAll = value
- @persistence.showAll(value)
- @$rootScope.$broadcast('triggerHideRead')
-
- @$scope.toggleSettings = =>
- @settings = !@settings
-
- @$scope.toggleAdd = =>
- @add = !@add
-
- @$scope.addIsShown = =>
- return @add
-
- @$scope.settingsAreShown = =>
- return @settings
-
- @$scope.isAddingFeed = =>
- return @addingFeed
-
- @$scope.isAddingFolder = =>
- return @addingFolder
-
- @$scope.addFeed = (url, folder) =>
- @$scope.feedEmptyError = false
- @$scope.feedExistsError = false
- @$scope.feedError = false
-
- if url == undefined or url.trim() == ''
- @$scope.feedEmptyError = true
- else
- url = url.trim()
- for feed in @feedModel.getItems()
- if url == feed.url # FIXME: can we really compare this
- @$scope.feedExistsError = true
-
- if not (@$scope.feedEmptyError or @$scope.feedExistsError)
- if folder == undefined
- folderId = 0
- else
- folderId = folder.id
- @addingFeed = true
- onSuccess = =>
- @$scope.feedUrl = ''
- @addingFeed = false
- onError = =>
- @$scope.feedError = true
- @addingFeed = false
- @persistence.createFeed(url, folderId, onSuccess, onError)
-
-
- @$scope.addFolder = (name) =>
- @$scope.folderEmptyError = false
- @$scope.folderExistsError = false
-
- if name == undefined or name.trim() == ''
- @$scope.folderEmptyError = true
- else
- name = name.trim()
- for folder in @folderModel.getItems()
- if name.toLowerCase() == folder.name.toLowerCase()
- @$scope.folderExistsError = true
-
- if not (@$scope.folderEmptyError or @$scope.folderExistsError)
- @addingFolder = true
- onSuccess = =>
- @$scope.folderName = ''
- @addingFolder = false
- @persistence.createFolder(name, onSuccess)
-
@$scope.$on 'readFile', (scope, fileContent) =>
structure = @opmlParser.parseXML(fileContent)
- @parseOPMLStructure(structure)
-
+ @parseOPMLStructure(structure)
@$scope.$on 'hidesettings', =>
@add = false
diff --git a/coffee/directives/addfolderselect.coffee b/coffee/directives/addfolderselect.coffee
new file mode 100644
index 000000000..1aa77c556
--- /dev/null
+++ b/coffee/directives/addfolderselect.coffee
@@ -0,0 +1,33 @@
+###
+# ownCloud news app
+#
+# @author Alessandro Cosentino
+# @author Bernhard Posselt
+# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
+# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
+#
+# This file is licensed under the Affero General Public License version 3 or
+# later.
+#
+# See the COPYING-README file
+#
+###
+
+###
+Turns a normal select into a folder select with the ability to create new folders
+###
+angular.module('News').directive 'addFolderSelect', ['$rootScope', ->
+
+ return (scope, elm, attr) ->
+
+ options =
+ singleSelect: true
+ selectedFirst: true
+ createText: $(elm).data('create')
+ createdCallback: (selected, value) ->
+ console.log selected
+ console.log value
+
+ $(elm).multiSelect(options)
+
+] \ No newline at end of file
diff --git a/coffee/directives/droppable.coffee b/coffee/directives/droppable.coffee
index e00545d31..a9c134096 100644
--- a/coffee/directives/droppable.coffee
+++ b/coffee/directives/droppable.coffee
@@ -20,11 +20,11 @@ angular.module('News').directive 'droppable', ['$rootScope', ($rootScope) ->
details =
accept: '.feed'
- hoverClass: 'dnd_over'
+ hoverClass: 'drag-and-drop'
greedy: true
drop: (event, ui) ->
# in case jquery ui did something weird
- $('.dnd_over').removeClass('dnd_over')
+ $('.drag-and-drop').removeClass('drag-and-drop')
data =
folderId: parseInt($elem.data('id'), 10)
diff --git a/coffee/lib/owncloud.coffee b/coffee/lib/owncloud.coffee
index 537499135..aaed235a3 100644
--- a/coffee/lib/owncloud.coffee
+++ b/coffee/lib/owncloud.coffee
@@ -34,11 +34,11 @@ angular.module('OC', []).config ['$httpProvider', ($httpProvider) ->
return $.param(data)
]
-angular.module('OC').init ['$rootScope', 'Router', ($rootScope, Router) ->
+angular.module('OC').run ['$rootScope', 'Router', ($rootScope, Router) ->
init = ->
$rootScope.$broadcast('routesLoaded')
# this registers a callback that is executed once the routes have
# finished loading. Before this you cant really do request
- OC.Router.registerLoadedCallback(init)
+ Router.registerLoadedCallback(init)
] \ No newline at end of file
diff --git a/controller/news.controller.php b/controller/news.controller.php
index e13cfe979..127a05701 100644
--- a/controller/news.controller.php
+++ b/controller/news.controller.php
@@ -56,8 +56,15 @@ class NewsController extends Controller {
$this->api->add3rdPartyScript('angular-1.0.2/angular.min');
$this->api->add3rdPartyScript('moment.min');
$this->api->addScript('app');
- $this->api->addStyle('news');
-
+ $this->api->addScript('multiselect', 'core');
+
+ $this->api->addStyle('owncloud');
+ $this->api->addStyle('addnew');
+ $this->api->addStyle('feeds');
+ $this->api->addStyle('items');
+ $this->api->addStyle('settings');
+ $this->api->addStyle('addnew');
+ $this->api->addStyle('showall');
if($urlParams['feedid']){
$this->api->setUserValue('lastViewedFeed', $urlParams['feedid']);
diff --git a/css/addnew.css b/css/addnew.css
new file mode 100644
index 000000000..edcad6ec6
--- /dev/null
+++ b/css/addnew.css
@@ -0,0 +1,25 @@
+.add-new {
+ overflow: hidden;
+}
+
+.add-new > a {
+ background-image: url('%appswebroot%/news/img/add.svg');
+}
+
+.add-new-popup {
+ -moz-transition: padding-bottom 500ms ease 0s;
+ -o-transition: padding-bottom 500ms ease 0s;
+ -webkit-transition: padding-bottom 500ms ease 0s;
+ -ms-transition: padding-bottom 500ms ease 0s;
+ transition: height 500ms ease 0s;
+ height: 0;
+ padding: 0 15px;
+}
+
+.add-new-popup.open {
+ height: 170px;
+}
+
+.add-new-popup .personalblock:first-child legend {
+ padding-top: 15px;
+} \ No newline at end of file
diff --git a/css/feeds.css b/css/feeds.css
new file mode 100644
index 000000000..5ae430aec
--- /dev/null
+++ b/css/feeds.css
@@ -0,0 +1,82 @@
+.starred-icon {
+ background-image: url('%appswebroot%/news/img/starred.png');
+}
+
+.subscriptions-icon {
+ background-image: url('%appswebroot%/news/img/rss.svg');
+}
+
+.unread {
+ font-weight: bold;
+}
+
+#left-content .unread > a {
+ padding-right: 32px;
+}
+
+
+
+#left-content .utils {
+ position: absolute;
+ right: 0;
+ top: 0;
+ bottom: 0;
+ display: none;
+}
+
+#left-content .utils button {
+ margin: 5px 0 0 0;
+ background-position: center;
+ background-repeat: no-repeat;
+ background-color: transparent;
+ border: 0;
+ box-shadow: none;
+}
+
+.unread-counter {
+ padding: 6px 8px 5px;
+ position: absolute;
+ z-index: 5;
+ right: 0;
+ top: 0;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ text-align: center;
+ font-size: 9pt;
+ display: none;
+}
+
+#left-content li:hover .utils > .unread-counter {
+ display: none;
+}
+
+.unread .unread-counter {
+ display: block;
+}
+
+
+/* general */
+button.action {
+ opacity: .5;
+}
+
+button.action:hover {
+ opacity: 1;
+}
+
+
+#left-content li:hover > .utils {
+ display: block;
+}
+
+.delete-icon {
+ background-image: url('%webroot%/core/img/actions/delete.svg');
+}
+
+.edit-icon {
+ background-image: url('%webroot%/core/img/actions/rename.svg');
+}
+
+.mark-read-icon {
+ background-image: url('%appswebroot%/news/img/mark_read.svg');
+}
diff --git a/css/items.css b/css/items.css
new file mode 100644
index 000000000..3d13e8e57
--- /dev/null
+++ b/css/items.css
@@ -0,0 +1,299 @@
+#right-content:after {
+ content: '';
+ display: block;
+ height: 100%;
+}
+
+#right-content.loading {
+ background-image: url('%webroot%/core/img/loading.gif');
+ background-position: center;
+ background-repeat: no-repeat;
+}
+
+#right-content.loading > ul {
+ display: none;
+}
+
+
+/**
+ * Rules for a single feed item
+ */
+.feed_item {
+ border-top: 1px solid #ccc;
+ min-height: 100px;
+ background-image: linear-gradient(top, rgb(248,248,248) 0, rgb(255,255,255) 6em);
+ background-image: -o-linear-gradient(top, rgb(248,248,248) 0, rgb(255,255,255) 6em);
+ background-image: -moz-linear-gradient(top, rgb(248,248,248) 0, rgb(255,255,255) 6em);
+ background-image: -webkit-linear-gradient(top, rgb(248,248,248) 0, rgb(255,255,255) 6em);
+ background-image: -ms-linear-gradient(top, rgb(248,248,248) 0, rgb(255,255,255) 6em);
+ padding: 2.5em 0 0 0;
+ cursor: default;
+}
+
+.feed_item.viewed {
+ border-right: 5px solid #F28627;
+}
+
+
+.feed_item:first-child {
+ border-top: 0;
+}
+
+ /**
+ * Utils panel
+ */
+ .utils {
+ height: 2em;
+ margin: 0 0 0 1em;
+ float: left;
+ }
+
+ /**
+ * Primary feed utils which are always shown
+ */
+ .feed_item .primary_item_utils {
+ float: left;
+ }
+
+ .feed_item .primary_item_utils li {
+ display: inline-block;
+ line-height: 1.5em;
+ font-size: 1em;
+ color: #aaa;
+ float: left;
+ margin-left: ;
+ cursor: default;
+ }
+
+ .feed_item .primary_item_utils li:first-child { margin: 0}
+ .feed_item .primary_item_utils li.star {
+ background-image: url('%appswebroot%/news/img/inactive_star.svg');
+ background-repeat: no-repeat;
+ background-size: 1.5em 1.5em;
+ width: 1.5em;
+ height: 1.5em;
+ cursor: pointer;
+ }
+
+ .feed_item .primary_item_utils li.star.important,
+ .feed_item .primary_item_utils li.star:hover {
+ background-image: url('%appswebroot%/news/img/active_star.svg');
+ }
+
+ /**
+ * Feed title
+ */
+ .feed_item h1.item_title {
+ font-size: 1.5em;
+ margin: 0 13em 0 2.1em;
+ font-weight: bold;
+ word-break: break-all;
+ }
+
+ .feed_item h1.item_title a {
+ color: #222;
+ }
+ .feed_item h1.item_title a:hover {
+ color: #222;
+ text-decoration: underline;
+ }
+
+ /**
+ * Feed title when read
+ */
+ .feed_item.read h1.item_title {
+ font-weight: normal;
+ }
+
+ .feed_item.read h1.item_title a {
+ color: #888;
+ }
+
+ /**
+ * Title of the feed to which the item belongs
+ */
+ .feed_item h2.item_feed_title {
+ color: #aaa;
+ font-size: 1.1em;
+ margin-left: 3em;
+ }
+
+ /**
+ * Author of the item
+ */
+ .feed_item h2.item_author {
+ color: #aaa;
+ font-size: 1.1em;
+ margin: .2em 0 0 3em;
+ }
+
+ .feed_item h2.item_author a {
+ color: inherit;
+ }
+
+ .feed_item h2.item_author a:hover {
+ text-decoration: underline;
+ }
+
+ .timestamp {
+ display: none;
+ }
+
+ /**
+ * Feed timestamp
+ */
+ .timeago {
+ float: right;
+ color: #aaa;
+ margin: 0 1.2em 0 0;
+ font-size: 1.1em;
+ }
+
+ /**
+ * Body of the feed item
+ */
+ .feed_item .enclosure {
+ padding: 1em 3em 0 3.5em;
+ }
+
+ .feed_item div.body {
+ padding: .75em 3em 0 3em;
+ max-width: 55em;
+ font-size: 1.1em;
+ clear: both;
+ overflow: auto;
+ }
+
+ .feed_item div.body p {
+ line-height: 1.5;
+ margin: .5em 0 1em 0;
+ }
+
+ .feed_item div.body img, .feed_item div.body table {
+ max-width: 100%;
+ height: auto;
+ overflow: auto;
+ word-wrap: break-word;
+ }
+
+ .feed_item div.body > img:first-child {
+ padding: 0 1em 0 0;
+ float: left;
+ }
+
+ .feed_item div.body h1, .feed_item div.body h2 {
+ font-size: 1.25em;
+ font-weight: bold;
+ color: #222;
+ margin: 1.5em 0 0 0;
+ }
+
+ .feed_item div.body h3 {
+ font-size: 1.1em;
+ font-weight: bold;
+ color: #222;
+ margin: 1.5em 0 0 0;
+ text-decoration: underline;
+ }
+
+ .feed_item div.body > div {
+ margin: .5em 0;
+ }
+
+ .feed_item div.body a {
+ color: #0000ff;
+ text-decoration: underline;
+ }
+
+ .feed_item div.body ul {
+ margin: .5em 0;
+ padding-left: 1em;
+ list-style-type: disc;
+ }
+
+ .feed_item div.body ol {
+ margin: .5em 0;
+ padding-left: 1.5em;
+ }
+
+ .feed_item div.body ul li {
+ cursor: default;
+ line-height: 1.5em;
+ }
+
+ .feed_item div.body pre {
+ padding: .5em .5em .5em 1em;
+ background-color: #dadada;
+ border: 1px solid #ccc;
+ margin: .5em 0 1em 0;
+ background-image: linear-gradient(top, rgb(215,215,215) 0%, rgb(220,220,220) 100%);
+ background-image: -o-linear-gradient(top, rgb(215,215,215) 0%, rgb(220,220,220) 100%);
+ background-image: -moz-linear-gradient(top, rgb(215,215,215) 0%, rgb(220,220,220) 100%);
+ background-image: -webkit-linear-gradient(top, rgb(215,215,215) 0%, rgb(220,220,220) 100%);
+ background-image: -ms-linear-gradient(top, rgb(215,215,215) 0%, rgb(220,220,220) 100%);
+ overflow-y: auto;
+ }
+
+ .feed_item div.body pre code {
+ font-family: monospace;
+ font-size: 1.5em;
+ }
+ .feed_item div.body > *:last-child {
+ margin-bottom: 0;
+ }
+
+/**
+ * Line with utils at the bottom
+ */
+.bottom_utils {
+ width: 100%;
+ height: 2.5em;
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+}
+
+ /**
+ * Secondary feed items which are only shown on hover
+ */
+ .feed_item .secondary_item_utils {
+ float: right;
+ margin: 0 1.2em;
+ }
+
+
+ .feed_item .secondary_item_utils, .feed_item .secondary_item_utils a {
+ color: #000;
+ }
+
+ .feed_item:hover .secondary_item_utils li {
+ display: inline-block;
+ }
+
+ .feed_item .secondary_item_utils li {
+ padding-left: 25px;
+ display: none;
+ }
+
+ /**
+ * Secondary feed items which are only shown on hover
+ */
+ .feed_item .show_keep_unread .keep_unread{
+ display: block;
+ }
+
+ .feed_item li.share_link {
+ background-image: url('%webroot%/core/img/actions/share.svg');
+ background-repeat: no-repeat;
+ background-position: right center;
+ padding-right: 20px;
+ }
+
+ .feed_item:hover .secondary_item_utils li.keep_unread {
+ cursor: pointer;
+ }
+
+ .feed_item .secondary_item_utils li input[type=checkbox]{
+ margin-left: 5px;
+ }
diff --git a/css/owncloud.css b/css/owncloud.css
new file mode 100644
index 000000000..65ac19f70
--- /dev/null
+++ b/css/owncloud.css
@@ -0,0 +1,259 @@
+/**
+ * ownCloud
+ *
+ * @author Bernhard Posselt
+ * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/**
+ * Contains default left-content design stuff
+ */
+
+/* needed for angularjs */
+#app {
+ height: 100%;
+ width: 100%;
+}
+
+/* Basic layout */
+#left-content {
+ width: 250px;
+ height: 100%;
+ float: left;
+ -moz-box-sizing: border-box; box-sizing: border-box;
+ border-right: 1px solid #ccc;
+ background-color: #f8f8f8;
+ padding-bottom: 32px;
+}
+
+#right-content {
+ height: 100%;
+ overflow-y: auto;
+}
+
+/* left-content lists */
+#left-content > ul {
+ height: 100%;
+ overflow: auto;
+ -moz-box-sizing: border-box; box-sizing: border-box;
+}
+
+#left-content li {
+ width: 100%;
+ position: relative;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ text-shadow: 0 1px 0 rgba(255, 255, 255, .9);
+}
+
+#left-content li.active {
+ background-color: #d0d0d0;
+ text-shadow: 0 1px 0 rgba(255,255,255,.7);
+}
+
+
+#left-content > ul > li {
+ border-bottom: 1px solid #ddd;
+ border-top: 1px solid #fff;
+ background-color: #eee;
+}
+
+#left-content > ul > li.active {
+ border-bottom: 1px solid #ccc;
+ border-top: 1px solid #ddd;
+}
+
+#left-content ul.with-icon a {
+ background-size: 16px 16px;
+ background-repeat: no-repeat;
+ background-position: 10px center;
+ padding-left: 32px;
+}
+
+#left-content li > a {
+ width: 100%;
+ padding: 0 16px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ display: block;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ white-space: nowrap;
+ line-height: 32px;
+ color: #333;
+}