Merged with Santiago upstream.
143
COPYING
@ -20,10 +20,10 @@ In default form, Plinth incorporates FileDict, a Python module
|
||||
released under a "MIT/BSD/Python" license, as per [its blog
|
||||
page](https://erezsh.wordpress.com/2009/05/31/filedict-bug-fixes-and-updates/).
|
||||
|
||||
## GNU General Public License, Version 3
|
||||
## GNU Affero General Public License, Version 3
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
@ -31,17 +31,15 @@ page](https://erezsh.wordpress.com/2009/05/31/filedict-bug-fixes-and-updates/).
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
The GNU Affero General Public License is a free, copyleft license for
|
||||
software and other kinds of works, specifically designed to ensure
|
||||
cooperation with the community in the case of network server software.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
our General Public Licenses are intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
software for all its users.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
@ -50,44 +48,34 @@ them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
Developers that use our General Public Licenses protect your rights
|
||||
with two steps: (1) assert copyright on the software, and (2) offer
|
||||
you this License which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
A secondary benefit of defending all users' freedom is that
|
||||
improvements made in alternate versions of the program, if they
|
||||
receive widespread use, become available for other developers to
|
||||
incorporate. Many developers of free software are heartened and
|
||||
encouraged by the resulting cooperation. However, in the case of
|
||||
software used on network servers, this result may fail to come about.
|
||||
The GNU General Public License permits making a modified version and
|
||||
letting the public access it on a server without ever releasing its
|
||||
source code to the public.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
The GNU Affero General Public License is designed specifically to
|
||||
ensure that, in such cases, the modified source code becomes available
|
||||
to the community. It requires the operator of a network server to
|
||||
provide the source code of the modified version running there to the
|
||||
users of that server. Therefore, public use of a modified version, on
|
||||
a publicly accessible server, gives the public access to the source
|
||||
code of the modified version.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
An older license, called the Affero General Public License and
|
||||
published by Affero, was designed to accomplish similar goals. This is
|
||||
a different license, not a version of the Affero GPL, but Affero has
|
||||
released a new version of the Affero GPL which permits relicensing under
|
||||
this license.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
@ -96,7 +84,7 @@ modification follow.
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
@ -573,35 +561,45 @@ to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, if you modify the
|
||||
Program, your modified version must prominently offer all users
|
||||
interacting with it remotely through a computer network (if your version
|
||||
supports such interaction) an opportunity to receive the Corresponding
|
||||
Source of your version by providing access to the Corresponding Source
|
||||
from a network server at no charge, through some standard or customary
|
||||
means of facilitating copying of software. This Corresponding Source
|
||||
shall include the Corresponding Source for any work covered by version 3
|
||||
of the GNU General Public License that is incorporated pursuant to the
|
||||
following paragraph.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
under version 3 of the GNU General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
but the work with which it is combined will remain governed by version
|
||||
3 of the GNU General Public License.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
the GNU Affero General Public License from time to time. Such new versions
|
||||
will be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Program specifies that a certain numbered version of the GNU Affero General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
GNU Affero General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
versions of the GNU Affero General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
@ -659,44 +657,33 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
If your software can interact with users remotely through a computer
|
||||
network, you should also make sure that it provides a way for users to
|
||||
get its source. For example, if your program is a web application, its
|
||||
interface could display a "Source" link that leads users to an archive
|
||||
of the code. There are many ways you could offer source, and different
|
||||
solutions will be better for different programs; see section 13 for the
|
||||
specific requirements.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
|
||||
## Creative Commons Attribution-ShareAlike 3.0 Unported
|
||||
|
||||
License
|
||||
|
||||
24
NOTES
Normal file
@ -0,0 +1,24 @@
|
||||
% PLINTH
|
||||
%
|
||||
% February 2012
|
||||
|
||||
# Edits by seandiggity
|
||||
|
||||
## 2012-02-27 new theme based upon bootstrap
|
||||
|
||||
Added Bootstrap code from Twitter's Bootstrap http://twitter.github.com/bootstrap
|
||||
Additional images, css changes
|
||||
Consolidated Bootstrap, Boilerplate, HTML5-Reset code
|
||||
Edited text and forms for some modules (as a CMS, Plinth's fetching of text and forms from static files needs rethinking)
|
||||
Changed menu javascript to work with Bootstrap styles
|
||||
|
||||
## 2012-02-24 template and theme changes
|
||||
|
||||
Added HTML5-Reset code http://html5reset.org
|
||||
Removed robots.txt (we have "noindex,nofollow" in the template meta tags, do we need this?)
|
||||
Added meta noindex,nofollow,noarchive tags for specific robots (googlebot etc.)
|
||||
Removed extraneous meta tags useful only for indexing
|
||||
Removed HTML5-Reset "_" directory. Not sure why it's useful to add an ambiguous folder to the directory tree.
|
||||
Made sure no Google-y code wasn't included (analytics, remote copy of JQuery, etc.)
|
||||
Fixed symbolic link docs/style.css
|
||||
New favicon and iOS "web clip" button
|
||||
@ -12,7 +12,7 @@ santiago = os.path.join(data_dir, "santiago.sqlite3")
|
||||
|
||||
|
||||
product_name = "Plinth"
|
||||
box_name = "Freedom Plug"
|
||||
box_name = "FreedomBox"
|
||||
|
||||
port = 8000
|
||||
|
||||
|
||||
226
fabfile.py
vendored
Normal file
@ -0,0 +1,226 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# This is the fabric file I've been using to deploy things on my box
|
||||
# and my freedombox.
|
||||
#
|
||||
# fab install should take you from base freedom-maker install to
|
||||
# plinth box
|
||||
|
||||
import os,sys, subprocess
|
||||
import simplejson as json
|
||||
import fabric.api
|
||||
from fabric.api import local, env, cd, put, get, task
|
||||
|
||||
import cfg
|
||||
|
||||
fb_ip = "10.5.53.155"
|
||||
|
||||
BINDIR = "/usr/local/bin"
|
||||
|
||||
# defaults
|
||||
env.user = 'root'
|
||||
|
||||
@task
|
||||
def fb():
|
||||
"Use this to set host to our freedombox (e.g.: fab fb deploy)"
|
||||
env.hosts = [fb_ip]
|
||||
|
||||
@task
|
||||
def all_hosts():
|
||||
"Use this to set host to both localhost and freedombox"
|
||||
env.hosts = ["localhost", "192.168.2.115"]
|
||||
|
||||
def remote_dir():
|
||||
if env.host == fb_ip:
|
||||
return "/usr/local/share/plinth"
|
||||
else:
|
||||
return "/home/james/src/plinth"
|
||||
|
||||
def run(*args, **kwargs):
|
||||
if env.host == "localhost" or env.host=="127.0.0.1":
|
||||
return local(*args, **kwargs)
|
||||
else:
|
||||
return fabric.api.run(*args, **kwargs)
|
||||
|
||||
def sudo(*args, **kwargs):
|
||||
if env.host == "localhost" or env.host=="127.0.0.1":
|
||||
return run("sudo %s" % args[0], *args[1:], **kwargs)
|
||||
elif env.user == "root":
|
||||
return run(*args, **kwargs)
|
||||
else:
|
||||
return fabric.api.sudo(*args, **kwargs)
|
||||
|
||||
@task
|
||||
def get_remote_data_dir():
|
||||
with cd(remote_dir()):
|
||||
data_dir = run('python -c "import cfg; print cfg.data_dir"')
|
||||
env.remote_data_dir = os.path.join(remote_dir(), data_dir)
|
||||
sudo('mkdir -p %s' % env.remote_data_dir)
|
||||
return env.remote_data_dir
|
||||
|
||||
@task
|
||||
def move_data():
|
||||
"Move install's data dir to where cfg specifies it should be"
|
||||
get_remote_data_dir()
|
||||
with cd(remote_dir()):
|
||||
sudo('mv data %s' % os.path.split(env.remote_data_dir)[0])
|
||||
|
||||
@task
|
||||
def make():
|
||||
"Run the makefile, which generates docs and templates"
|
||||
with cd(remote_dir()):
|
||||
sudo('make')
|
||||
|
||||
def make_link_unless_exists(src, dest):
|
||||
sudo('test -f %s || ln -s %s %s' % (dest, src, dest))
|
||||
|
||||
def link(src, dest):
|
||||
sudo('ln -fs %s %s' % (src, dest))
|
||||
|
||||
@task
|
||||
def santiago():
|
||||
"Setup the Santiago port"
|
||||
santiago_port = 52854
|
||||
sudo('ifconfig lo up') # or else tor start fails
|
||||
sudo('apt-get install -y --no-install-recommends tor curl ntp')
|
||||
|
||||
# tor needs accurate clock
|
||||
sudo('date -s "%s"' % subprocess.check_output("date").rstrip())
|
||||
|
||||
# create tor hidden service dir
|
||||
santiago_dir = os.path.join(get_remote_data_dir(), "santiago", "tor")
|
||||
tor_dir = os.path.join(santiago_dir, "general")
|
||||
sudo("mkdir -p " + tor_dir)
|
||||
sudo("chown debian-tor:debian-tor " + tor_dir)
|
||||
|
||||
# ensure hidden service config is in torrc
|
||||
local("rm -rf __fab__torrc")
|
||||
get("/etc/tor/torrc", "__fab__torrc")
|
||||
with open ("__fab__torrc", 'r') as INF:
|
||||
rc = INF.read()
|
||||
local("rm -rf __fab__torrc")
|
||||
hidden_service_config = "HiddenServiceDir %s\nHiddenServicePort 80 127.0.0.1:%d" % (tor_dir, santiago_port)
|
||||
if not hidden_service_config in rc:
|
||||
sudo("echo '%s' >> /etc/tor/torrc" % hidden_service_config)
|
||||
|
||||
sudo('service tor restart')
|
||||
|
||||
def backslash_path(f):
|
||||
if not f.startswith('/'):
|
||||
f = os.path.abs(f)
|
||||
if f == '/':
|
||||
return ''
|
||||
path, ret = os.path.split(f)
|
||||
return backslash_path(path) + '\/' + ret
|
||||
|
||||
@task
|
||||
def apache():
|
||||
"configure apache to find reverse proxy for plinth"
|
||||
sudo('apt-get install --no-install-recommends -y apache2 libapache2-mod-proxy-html apache2-utils openssl ssl-cert')
|
||||
sudo('a2enmod proxy_http rewrite ssl')
|
||||
sudo('touch /var/log/apache2/rewrite.log')
|
||||
|
||||
## ssl key and cert
|
||||
ssl_target = "/etc/apache2/ssl/apache.pem"
|
||||
sudo('mkdir -p %s' % os.path.split(ssl_target)[0])
|
||||
sudo('test -f %s || echo "US\nNY\nNYC\nFBox\n\n\n" | openssl req -new -x509 -days 999 -nodes -out %s -keyout %s' % (ssl_target, ssl_target, ssl_target))
|
||||
|
||||
conf_path = os.path.join(remote_dir(), "share/apache2/plinth.conf")
|
||||
sudo("mkdir -p " + os.path.split(conf_path)[0])
|
||||
sudo("touch "+ conf_path)
|
||||
sudo(r"sed -i 's/\(\s*\)DocumentRoot.*/\1DocumentRoot %s/g' %s" % (
|
||||
backslash_path(os.path.join(remote_dir(), "static")),
|
||||
conf_path))
|
||||
link(conf_path, "/etc/apache2/sites-enabled/plinth.conf")
|
||||
sudo('rm -f /etc/apache2/sites-enabled/000-default')
|
||||
sudo('service apache2 restart')
|
||||
|
||||
@task
|
||||
def deps():
|
||||
"Basic plinth dependencies"
|
||||
sudo('apt-get install --no-install-recommends -y python make python-cheetah pandoc python-simplejson python-pyme')
|
||||
|
||||
@task
|
||||
def update():
|
||||
"Copy modified git-tracked files from this branch to remote"
|
||||
|
||||
with cd(remote_dir()):
|
||||
|
||||
## Get .fab contents
|
||||
sudo("touch .fab")
|
||||
fab = run("cat .fab")
|
||||
if not fab:
|
||||
fab = {}
|
||||
|
||||
## Make list of files to put
|
||||
try:
|
||||
fab = json.loads(fab)
|
||||
except:
|
||||
fab={}
|
||||
branch = [a[2:] for a in local("git branch", capture=True).split("\n") if a.startswith('*')][0]
|
||||
files = local("git ls-tree -r --name-only %s" % branch, capture=True).split("\n")
|
||||
else:
|
||||
files = local("git diff --stat " + fab['last_update_from_commit'], capture=True).split("\n")[:-1]
|
||||
files = [f.lstrip().split("|")[0].rstrip() for f in files]
|
||||
|
||||
## Put the files, one by one, respecting directories
|
||||
dirs = {}
|
||||
for pathspec in files:
|
||||
d,fname = os.path.split(pathspec)
|
||||
if not d in dirs.keys():
|
||||
dirs[d]=[]
|
||||
dirs[d].append(pathspec)
|
||||
if dirs:
|
||||
sudo('mkdir -p %s' % ' '.join([os.path.join(remote_dir(), d) for d in dirs.keys()]))
|
||||
for d in dirs:
|
||||
for f in dirs[d]:
|
||||
if os.path.islink(f):
|
||||
linked = local("ls -l %s" % f, capture=True).split("-> ")[1]
|
||||
#link(os.path.join(remote_dir(), linked), os.path.join(remote_dir(), d, os.path.basename(f)))
|
||||
put(f, os.path.join(remote_dir(), d),mirror_local_mode=True)
|
||||
if f.endswith(".py"):
|
||||
run("rm -f " + os.path.join(remote_dir(), d, os.path.basename)+"c")
|
||||
|
||||
## restart
|
||||
make()
|
||||
sudo('/etc/init.d/plinth restart')
|
||||
|
||||
## Record activity so we only put changed files next time
|
||||
commit = local("git log -n 1", capture=True).split("\n")[0].split(" ")[1]
|
||||
fab['last_update_from_commit'] = commit
|
||||
with open(".fab", 'w') as OUTF:
|
||||
OUTF.write(json.dumps(fab))
|
||||
put(".fab", os.path.join(remote_dir(),".fab"))
|
||||
local("rm -f .fab")
|
||||
|
||||
@task
|
||||
def link_bin():
|
||||
"Link executable and init.d script"
|
||||
# todo: set daemon to point to currect binary
|
||||
sudo('rm -rf ' + os.path.join(BINDIR, 'plinth.py'))
|
||||
link(os.path.join(remote_dir(), "plinth.py"), os.path.join(BINDIR, 'plinth.py'))
|
||||
sudo('rm -rf /etc/init.d/plinth')
|
||||
link(os.path.join(remote_dir(), "share/init.d/plinth"), "/etc/init.d/plinth")
|
||||
|
||||
@task
|
||||
def restart():
|
||||
"Run plinth"
|
||||
run('/etc/init.d/plinth restart')
|
||||
@task
|
||||
def stop():
|
||||
"Stop plinth"
|
||||
run('/etc/init.d/plinth stop')
|
||||
|
||||
@task
|
||||
def proxy():
|
||||
put("proxy_up.py", remote_dir())
|
||||
|
||||
@task
|
||||
def deploy():
|
||||
"Deploy plinth"
|
||||
deps()
|
||||
link_bin()
|
||||
santiago()
|
||||
update()
|
||||
apache()
|
||||
|
||||
19
menu.py
@ -5,11 +5,15 @@ import cfg
|
||||
|
||||
class Menu():
|
||||
"""One menu item."""
|
||||
def __init__(self, label="", url="#", order=50):
|
||||
def __init__(self, label="", icon="", url="#", order=50):
|
||||
"""label is the text that is displayed on the menu.
|
||||
|
||||
icon is the icon to be displayed next to the label.
|
||||
Choose from the Glyphicon set:
|
||||
http://twitter.github.com/bootstrap/base-css.html#icons
|
||||
|
||||
url is the url location that will be activated when the menu
|
||||
item is selected
|
||||
item is selected.
|
||||
|
||||
order is the numerical rank of this item within the menu.
|
||||
Lower order items appear closest to the top/left of the menu.
|
||||
@ -20,8 +24,9 @@ class Menu():
|
||||
"""
|
||||
|
||||
self.label = label
|
||||
self.order = order
|
||||
self.icon = icon
|
||||
self.url = url
|
||||
self.order = order
|
||||
self.items = []
|
||||
|
||||
def sort_items(self):
|
||||
@ -36,7 +41,7 @@ class Menu():
|
||||
if basehref and url.startswith("/"):
|
||||
url = cfg.base_href + url
|
||||
|
||||
item = Menu(label=label, url=url, order=order)
|
||||
item = Menu(label=label, icon=icon, url=url, order=order)
|
||||
self.items.append(item)
|
||||
self.sort_items()
|
||||
return item
|
||||
@ -61,7 +66,7 @@ class Menu():
|
||||
|
||||
so = []
|
||||
for item in self.items:
|
||||
i = { 'label':item.label, 'url':item.url}
|
||||
i = { 'label':item.label, 'icon':item.icon, 'url':item.url}
|
||||
if item.active_p():
|
||||
i['active']=True
|
||||
if item.items and render_subs:
|
||||
@ -74,7 +79,7 @@ class Menu():
|
||||
|
||||
if render_subs is True, we render submenus too"""
|
||||
|
||||
return ('<SCRIPT LANGUAGE="JavaScript">\n <!--\n var %s_items=' % name
|
||||
return ('<script type="text/javascript">\n <!--\n var %s_items=' % name
|
||||
#+ json.dumps(self.serializable(render_subs=render_subs), separators=(',',':')) # compact
|
||||
+ "\n"+ json.dumps(self.serializable(render_subs=render_subs), sort_keys=True, indent=4) # pretty print
|
||||
+ ';\n // -->\n </SCRIPT>')
|
||||
+ ';\n // -->\n </script>')
|
||||
|
||||
@ -7,8 +7,8 @@ class Apps(PagePlugin):
|
||||
def __init__(self, *args, **kwargs):
|
||||
PagePlugin.__init__(self, *args, **kwargs)
|
||||
self.register_page("apps")
|
||||
self.menu = cfg.main_menu.add_item("User Apps", "/apps", 80)
|
||||
self.menu.add_item("Photo Gallery", "/apps/photos", 35)
|
||||
self.menu = cfg.main_menu.add_item("Apps", "icon-download-alt", "/apps", 80)
|
||||
self.menu.add_item("Photo Gallery", "icon-picture", "/apps/photos", 35)
|
||||
|
||||
@cherrypy.expose
|
||||
def index(self):
|
||||
@ -27,7 +27,7 @@ class Apps(PagePlugin):
|
||||
@require()
|
||||
def photos(self):
|
||||
return self.fill_template(title="Open ID", main='', sidebar_right="""
|
||||
<h2>Photo Gallery</h2><p>Your photos might well be the most valuable
|
||||
<strong>Photo Gallery</strong><p>Your photos might well be the most valuable
|
||||
digital property you have, so why trust it to companies that have no
|
||||
investment in the sentimental value of your family snaps? Keep those
|
||||
photos local, backed up, easily accessed and free from the whims of
|
||||
|
||||
@ -8,12 +8,12 @@ class Help(PagePlugin):
|
||||
def __init__(self, *args, **kwargs):
|
||||
PagePlugin.__init__(self, *args, **kwargs)
|
||||
self.register_page("help")
|
||||
self.menu = cfg.main_menu.add_item(_("Documentation and FAQ"), "/help", 101)
|
||||
self.menu.add_item(_("Where to Get Help"), "/help/index", 5)
|
||||
self.menu.add_item(_("Developer's Manual"), "/help/view/plinth", 10)
|
||||
self.menu.add_item(_("FAQ"), "/help/view/faq", 20)
|
||||
self.menu.add_item(_("%s Wiki" % cfg.box_name), "http://wiki.debian.org/FreedomBox", 30)
|
||||
self.menu.add_item(_("About"), "/help/about", 100)
|
||||
self.menu = cfg.main_menu.add_item(_("Documentation"), "icon-book", "/help", 101)
|
||||
self.menu.add_item(_("Where to Get Help"), "icon-search", "/help/index", 5)
|
||||
self.menu.add_item(_("Developer's Manual"), "icon-info-sign", "/help/view/plinth", 10)
|
||||
self.menu.add_item(_("FAQ"), "icon-question-sign", "/help/view/faq", 20)
|
||||
self.menu.add_item(_("%s Wiki" % cfg.box_name), "icon-pencil", "http://wiki.debian.org/FreedomBox", 30)
|
||||
self.menu.add_item(_("About"), "icon-star", "/help/about", 100)
|
||||
|
||||
@cherrypy.expose
|
||||
def index(self):
|
||||
@ -27,7 +27,7 @@ class Help(PagePlugin):
|
||||
offer suggestions, edits, and screenshots for completing
|
||||
it!</p>
|
||||
|
||||
<p><a href="http://wiki.debian.org/FreedomBox">A section of
|
||||
<p><a href="http://wiki.debian.org/FreedomBox" target="_blank">A section of
|
||||
the Debian wiki</a> is devoted to the %(box)s. At some
|
||||
point the documentation in the wiki and the documentation in
|
||||
the manual should dovetail.</p>
|
||||
@ -48,8 +48,9 @@ class Help(PagePlugin):
|
||||
@cherrypy.expose
|
||||
def about(self):
|
||||
return self.fill_template(title=_("About the %s" % cfg.box_name), main="""
|
||||
<p> We live in a world where our use of the network is
|
||||
mediated by organizations that often do not have our best
|
||||
<img src="/static/theme/img/freedombox-logo-250px.png" class="main-graphic" />
|
||||
<p>We live in a world where our use of the network is
|
||||
mediated by those who often do not have our best
|
||||
interests at heart. By building software that does not rely on
|
||||
a central service, we can regain control and privacy. By
|
||||
keeping our data in our homes, we gain useful legal
|
||||
@ -62,14 +63,15 @@ class Help(PagePlugin):
|
||||
runs on must be cheap. The software it runs on must be easy to
|
||||
install and administrate by anybody. It must be easy to
|
||||
transition from existing services.</p>
|
||||
|
||||
<p>There are a number of projects working to realize a future
|
||||
<p><a class="btn btn-primary btn-large" href="http://wiki.debian.org/FreedomBox" target="_blank">Learn more »</a></p>""",
|
||||
sidebar_right=_("""<strong>Our Goal</strong><p>There are a number of projects working to realize a future
|
||||
of distributed services; we aim to bring them all together in
|
||||
a convenient package.</p>
|
||||
|
||||
<p>For more information about the Freedom Box project, see the
|
||||
<p>For more information about the FreedomBox project, see the
|
||||
<a href="http://wiki.debian.org/FreedomBox">Debian
|
||||
Wiki</a>.</p>""")
|
||||
Wiki</a>.</p>
|
||||
"""))
|
||||
|
||||
class View(PagePlugin):
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
||||
@ -50,9 +50,9 @@ class Form():
|
||||
quad = [0,0,0,0]
|
||||
self.text += """ <label>
|
||||
<span>%(label)s</span>
|
||||
<input type="text" class="inputtextnowidth" name="%(name)s0" id="%(id)s0" value="%(q0)s" maxlength="3" size="1"/><b>.</b>
|
||||
<input type="text" class="inputtextnowidth" name="%(name)s1" id="%(id)s1" value="%(q1)s" maxlength="3" size="1"/><b>.</b>
|
||||
<input type="text" class="inputtextnowidth" name="%(name)s2" id="%(id)s2" value="%(q2)s" maxlength="3" size="1"/><b>.</b>
|
||||
<input type="text" class="inputtextnowidth" name="%(name)s0" id="%(id)s0" value="%(q0)s" maxlength="3" size="1"/><strong>.</strong>
|
||||
<input type="text" class="inputtextnowidth" name="%(name)s1" id="%(id)s1" value="%(q1)s" maxlength="3" size="1"/><strong>.</strong>
|
||||
<input type="text" class="inputtextnowidth" name="%(name)s2" id="%(id)s2" value="%(q2)s" maxlength="3" size="1"/><strong>.</strong>
|
||||
<input type="text" class="inputtextnowidth" name="%(name)s3" id="%(id)s3" value="%(q3)s" maxlength="3" size="1"/>
|
||||
</label>""" % {'label':label, 'name':name, 'id':id, 'q0':quad[0], 'q1':quad[1], 'q2':quad[2], 'q3':quad[3]}
|
||||
|
||||
@ -77,7 +77,7 @@ class Form():
|
||||
self.text += """
|
||||
<div class="submit">
|
||||
<label><span></span>
|
||||
<input type="submit" class="button" value="%s" name="%s" id="%s" />
|
||||
<input type="submit" class="btn-primary" value="%s" name="%s" id="%s" />
|
||||
</label></div>\n""" % (label, name, id)
|
||||
def submit_row(self, buttons):
|
||||
"""buttons is a list of tuples, each containing label, name, id. Name and id are optional."""
|
||||
@ -99,7 +99,7 @@ class Form():
|
||||
|
||||
if button_text != '':
|
||||
button_text += " "
|
||||
button_text += '<input type="submit" class="button" value="%s" name="%s" id="%s" />\n' % (label, name, id)
|
||||
button_text += '<input type="submit" class="btn-primary" value="%s" name="%s" id="%s" />\n' % (label, name, id)
|
||||
self.text += '%s</div></label>' % button_text
|
||||
def name_or_id(self, name, id):
|
||||
if not name: name = id
|
||||
|
||||
@ -9,11 +9,11 @@ class Privacy(PagePlugin):
|
||||
def __init__(self, *args, **kwargs):
|
||||
PagePlugin.__init__(self, *args, **kwargs)
|
||||
self.register_page("privacy")
|
||||
self.menu = cfg.main_menu.add_item("Privacy Controls", "/privacy", 12)
|
||||
self.menu.add_item("General Config", "/privacy/config", 10)
|
||||
self.menu.add_item("Ad Blocking", "/privacy/adblock", 20)
|
||||
self.menu.add_item("TOR", "/privacy/TOR", 30)
|
||||
self.menu.add_item("HTTPS Everywhere", "/privacy/https_everywhere", 30)
|
||||
self.menu = cfg.main_menu.add_item("Privacy", "icon-eye-open", "/privacy", 12)
|
||||
self.menu.add_item("General Config", "icon-asterisk", "/privacy/config", 10)
|
||||
self.menu.add_item("Ad Blocking", "icon-ban-circle", "/privacy/adblock", 20)
|
||||
self.menu.add_item("TOR", "icon-eye-close", "/privacy/TOR", 30)
|
||||
self.menu.add_item("HTTPS Everywhere", "icon-lock", "/privacy/https_everywhere", 30)
|
||||
|
||||
@cherrypy.expose
|
||||
def index(self):
|
||||
@ -29,7 +29,7 @@ class Privacy(PagePlugin):
|
||||
is a founding consideration, not an afterthought.</p>
|
||||
"""
|
||||
return self.fill_template(title=_("Privacy Control Panel"), main=main,
|
||||
sidebar_right=_("""<h2>Statement of Principles</h2><p>When we say your
|
||||
sidebar_right=_("""<strong>Statement of Principles</strong><p>When we say your
|
||||
privacy is important, it's not just an empty pleasantry. We really
|
||||
mean it. Your privacy control panel should give you fine-grained
|
||||
control over exactly who can access your %s and the
|
||||
@ -37,6 +37,6 @@ information on it.</p>
|
||||
|
||||
<p>Your personal information should not leave this box without your
|
||||
knowledge and direction. And if companies or government wants this
|
||||
information, they have to ask <b>you</b> for it. This gives you a
|
||||
information, they have to ask <strong>you</strong> for it. This gives you a
|
||||
change to refuse and also tells you who wants your data.</p>
|
||||
""") % cfg.product_name)
|
||||
|
||||
@ -14,5 +14,5 @@ class Info(PagePlugin):
|
||||
@require()
|
||||
def index(self):
|
||||
return self.fill_template(title="Router Information", main="""
|
||||
<p> Eventually we will display a bunch of info, graphs and logs about the routing functions here.</p>
|
||||
<p>Eventually we will display a bunch of info, graphs and logs about the routing functions here.</p>
|
||||
""")
|
||||
|
||||
@ -11,11 +11,11 @@ class router(PagePlugin):
|
||||
order = 9 # order of running init in PagePlugins
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.register_page("router")
|
||||
self.menu = cfg.main_menu.add_item("Router Admin", "/router", 10)
|
||||
self.menu.add_item("Wireless", "/router/wireless", 12)
|
||||
self.menu.add_item("Firewall", "/router/firewall", 18)
|
||||
self.menu.add_item("Hotspot and Mesh", "/router/hotspot")
|
||||
self.menu.add_item("Info", "/router/info", 100)
|
||||
self.menu = cfg.main_menu.add_item("Router", "icon-retweet", "/router", 10)
|
||||
self.menu.add_item("Wireless", "icon-signal", "/router/wireless", 12)
|
||||
self.menu.add_item("Firewall", "icon-fire", "/router/firewall", 18)
|
||||
self.menu.add_item("Hotspot and Mesh", "icon-map-marker", "/router/hotspot")
|
||||
self.menu.add_item("Info", "icon-list-alt", "/router/info", 100)
|
||||
|
||||
@cherrypy.expose
|
||||
def index(self):
|
||||
@ -45,16 +45,16 @@ class router(PagePlugin):
|
||||
class setup(PagePlugin):
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.register_page("router.setup")
|
||||
self.menu = cfg.html_root.router.menu.add_item("General Setup", "/router/setup", 10)
|
||||
self.menu.add_item("Dynamic DNS", "/router/setup/ddns", 20)
|
||||
self.menu.add_item("MAC Address Clone", "/router/setup/mac_address", 30)
|
||||
self.menu = cfg.html_root.router.menu.add_item("General Setup", "icon-cog", "/router/setup", 10)
|
||||
self.menu.add_item("Dynamic DNS", "icon-flag", "/router/setup/ddns", 20)
|
||||
self.menu.add_item("MAC Address Clone", "icon-barcode", "/router/setup/mac_address", 30)
|
||||
|
||||
@cherrypy.expose
|
||||
@require()
|
||||
def index(self):
|
||||
parts = self.forms('/router/setup')
|
||||
parts['title'] = "General Router Setup"
|
||||
parts['sidebar_right']="""<h2>Introduction</h2><p>Your %s is a replacement for your
|
||||
parts['sidebar_right']="""<strong>Introduction</strong><p>Your %s is a replacement for your
|
||||
wireless router. By default, it should do everything your usual
|
||||
router does. With the addition of some extra modules, its abilities
|
||||
can rival those of high-end routers costing hundreds of dollars.</p>
|
||||
@ -88,7 +88,7 @@ class wan(FormPlugin, PagePlugin):
|
||||
url = ["/router/setup"]
|
||||
order = 10
|
||||
|
||||
js = """<script LANGUAGE="JavaScript">
|
||||
js = """<script type="text/javascript">
|
||||
<!--
|
||||
function hideshow_static() {
|
||||
var d = document.getElementById('connect_type');
|
||||
@ -105,7 +105,7 @@ class wan(FormPlugin, PagePlugin):
|
||||
def sidebar_right(self, *args, **kwargs):
|
||||
side=''
|
||||
if cfg.users.expert():
|
||||
side += """<h2>WAN Connection Type</h2>
|
||||
side += """<strong>WAN Connection Type</strong>
|
||||
<h3>DHCP</h3><p>DHCP allows your router to automatically
|
||||
connect with the upstream network. If you are unsure what
|
||||
option to choose, stick with DHCP. It is usually
|
||||
@ -150,7 +150,7 @@ class wan(FormPlugin, PagePlugin):
|
||||
form.dotted_quad("Static DNS 2", name="dns2", quad=[dns20, dns21, dns22, dns23])
|
||||
form.dotted_quad("Static DNS 3", name="dns3", quad=[dns30, dns31, dns32, dns33])
|
||||
form.html('</div>')
|
||||
form.html(""" <script LANGUAGE="JavaScript">
|
||||
form.html(""" <script type="text/javascript">
|
||||
<!--
|
||||
hideshow_static();
|
||||
// -->
|
||||
|
||||
@ -114,7 +114,7 @@ class Santiago(PagePlugin):
|
||||
class santiago(PagePlugin):
|
||||
def __init__(self, *args, **kwargs):
|
||||
PagePlugin.__init__(self, *args, **kwargs)
|
||||
self.menu = cfg.html_root.privacy.menu.add_item("Santiago", "/privacy/santiago", 10)
|
||||
self.menu = cfg.html_root.privacy.menu.add_item("Santiago", "icon-leaf", "/privacy/santiago", 10)
|
||||
self.register_page("privacy.santiago")
|
||||
|
||||
@cherrypy.expose
|
||||
|
||||
@ -8,8 +8,8 @@ class Services(PagePlugin):
|
||||
def __init__(self, *args, **kwargs):
|
||||
PagePlugin.__init__(self, *args, **kwargs)
|
||||
self.register_page("services")
|
||||
self.menu = cfg.main_menu.add_item("Other Services", "/services", 90)
|
||||
self.menu.add_item("Open ID", "/services/openid", 35)
|
||||
self.menu = cfg.main_menu.add_item("Services", "icon-list", "/services", 90)
|
||||
self.menu.add_item("Open ID", "icon-user", "/services/openid", 35)
|
||||
|
||||
@cherrypy.expose
|
||||
def index(self):
|
||||
@ -19,7 +19,7 @@ class Services(PagePlugin):
|
||||
@require()
|
||||
def openid(self):
|
||||
return self.fill_template(title="Open ID", main='', sidebar_right="""
|
||||
<h2>One Login for Every Site</h2><p>Your %s is also an OpenID
|
||||
<strong>One Login for Every Site</strong><p>Your %s is also an OpenID
|
||||
machine. It can generate credentials that allow you to log in to many
|
||||
websites without the need to remember or enter a separate username and
|
||||
password at each one.</p>
|
||||
|
||||
@ -7,7 +7,7 @@ class FileExplorer(PagePlugin):
|
||||
def __init__(self, *args, **kwargs):
|
||||
PagePlugin.__init__(self, *args, **kwargs)
|
||||
self.register_page("sharing.explorer")
|
||||
cfg.html_root.sharing.menu.add_item("File Explorer", "/sharing/explorer", 30)
|
||||
cfg.html_root.sharing.menu.add_item("File Explorer", "icon-folder-open", "/sharing/explorer", 30)
|
||||
|
||||
@cherrypy.expose
|
||||
@require()
|
||||
|
||||
@ -10,8 +10,8 @@ class Sharing(PagePlugin):
|
||||
def __init__(self, *args, **kwargs):
|
||||
PagePlugin.__init__(self, *args, **kwargs)
|
||||
self.register_page("sharing")
|
||||
self.menu = cfg.main_menu.add_item("Resource Sharing", "/sharing", 35)
|
||||
self.menu.add_item("File Server", "/sharing/files", 10)
|
||||
self.menu = cfg.main_menu.add_item("Sharing", "icon-share-alt", "/sharing", 35)
|
||||
self.menu.add_item("File Server", "icon-inbox", "/sharing/files", 10)
|
||||
|
||||
@cherrypy.expose
|
||||
def index(self):
|
||||
@ -25,7 +25,7 @@ class Sharing(PagePlugin):
|
||||
@require()
|
||||
def files(self):
|
||||
return self.fill_template(title="File Server", main='', sidebar_right=_("""
|
||||
<h2>Freedom NAS</h2><p> The %s can make your spare hard drives accessible to your
|
||||
<strong>Freedom NAS</strong><p> The %s can make your spare hard drives accessible to your
|
||||
local network, thus acting as a NAS server. We currently support
|
||||
sharing files via NFS and SMB.
|
||||
|
||||
@ -37,7 +37,7 @@ class PrinterSharing(PagePlugin):
|
||||
def __init__(self, *args, **kwargs):
|
||||
PagePlugin.__init__(self, *args, **kwargs)
|
||||
self.register_page("sharing.printer")
|
||||
cfg.html_root.sharing.menu.add_item("Printer Sharing", "/sharing/printer", 35)
|
||||
cfg.html_root.sharing.menu.add_item("Printer Sharing", "icon-print", "/sharing/printer", 35)
|
||||
|
||||
@cherrypy.expose
|
||||
@require()
|
||||
@ -47,7 +47,7 @@ class PrinterSharing(PagePlugin):
|
||||
<p>TODO: Setup and install CUPS</p>
|
||||
"""
|
||||
return self.fill_template(title="Printer Sharing", main=main, sidebar_right="""
|
||||
<h2>Share Your Printer</h2><p> The %s can share your printer via Samba and CUPS.</p>
|
||||
<strong>Share Your Printer</strong><p> The %s can share your printer via Samba and CUPS.</p>
|
||||
""" % cfg.box_name)
|
||||
|
||||
|
||||
|
||||
@ -64,7 +64,7 @@ class general(FormPlugin, PagePlugin):
|
||||
## only expert users are going to get deep enough to see any timestamps
|
||||
if not cfg.users.expert():
|
||||
return ''
|
||||
return _(#"""<h2>Time Zone</h2>
|
||||
return _(#"""<strong>Time Zone</strong>
|
||||
"""<p>Set your timezone to get accurate
|
||||
timestamps. %(product)s will use this information to set your
|
||||
%(box)s's systemwide timezone.</p>
|
||||
|
||||
@ -15,7 +15,7 @@ class experts(FormPlugin, PagePlugin):
|
||||
order = 10
|
||||
|
||||
def help(self, *args, **kwargs):
|
||||
side = _(#"""<h2>Expert Mode</h2>
|
||||
side = _(#"""<strong>Expert Mode</strong>
|
||||
"""
|
||||
<p>The %(box)s can be administered in two modes, 'basic'
|
||||
and 'expert'. Basic mode hides a lot of features and
|
||||
|
||||
@ -18,10 +18,10 @@ class Sys(PagePlugin):
|
||||
def __init__(self, *args, **kwargs):
|
||||
PagePlugin.__init__(self, *args, **kwargs)
|
||||
self.register_page("sys")
|
||||
self.menu = cfg.main_menu.add_item(_("%s System" % cfg.product_name), "/sys", 100)
|
||||
self.menu.add_item(_("Configure"), "/sys/config", 10)
|
||||
self.menu.add_item(_("Package Manager"), "/sys/packages", 20)
|
||||
self.menu.add_item(_("Users and Groups"), "/sys/users", 15)
|
||||
self.menu = cfg.main_menu.add_item(_("System"), "icon-cog", "/sys", 100)
|
||||
self.menu.add_item(_("Configure"), "icon-cog", "/sys/config", 10)
|
||||
self.menu.add_item(_("Package Manager"), "icon-gift", "/sys/packages", 20)
|
||||
self.menu.add_item(_("Users and Groups"), "icon-user", "/sys/users", 15)
|
||||
|
||||
@cherrypy.expose
|
||||
def index(self):
|
||||
@ -37,7 +37,7 @@ class Sys(PagePlugin):
|
||||
@require()
|
||||
def packages(self):
|
||||
side=_("""
|
||||
<h2>Help</h2>
|
||||
<strong>Help</strong>
|
||||
<p>On this page, you can add or remove %s plugins to your %s.</p>
|
||||
<p>Plugins are just Debian packages, so Debian's usual package management features should make this job fairly easy.</p>
|
||||
""" % (cfg.product_name, cfg.box_name))
|
||||
|
||||
@ -24,8 +24,8 @@ class add(FormPlugin, PagePlugin):
|
||||
order = 30
|
||||
|
||||
sidebar_left = ''
|
||||
sidebar_right = _("""<h2>Add User</h2><p>Adding a user via this
|
||||
administrative interface <b>might</b> create a system user.
|
||||
sidebar_right = _("""<strong>Add User</strong><p>Adding a user via this
|
||||
administrative interface <strong>might</strong> create a system user.
|
||||
For example, if you provide a user with ssh access, she will
|
||||
need a system account. If you don't know what that means,
|
||||
don't worry about it.</p>""")
|
||||
@ -70,16 +70,16 @@ class edit(FormPlugin, PagePlugin):
|
||||
order = 35
|
||||
|
||||
sidebar_left = ''
|
||||
sidebar_right = _("""<h2>Edit Users</h2><p>Click on a user's name to
|
||||
go to a screen for editing that user's account.</p><h2>Delete
|
||||
Users</h2><p>Check the box next to a users' names and then click
|
||||
sidebar_right = _("""<strong>Edit Users</strong><p>Click on a user's name to
|
||||
go to a screen for editing that user's account.</p><strong>Delete
|
||||
Users</strong><p>Check the box next to a users' names and then click
|
||||
"Delete User" to remove users from %s and the %s
|
||||
system.</p><p>Deleting users is permanent!</p>""" % (cfg.product_name, cfg.box_name))
|
||||
|
||||
def main(self, msg=''):
|
||||
users = cfg.users.keys()
|
||||
add_form = Form(title=_("Edit or Delete User"), action="/sys/users/edit", message=msg)
|
||||
add_form.html('<span class="indent"><b>Delete</b><br /></span>')
|
||||
add_form.html('<span class="indent"><strong>Delete</strong><br /></span>')
|
||||
for uname in sorted(users.keys()):
|
||||
add_form.html('<span class="indent"> %s ' %
|
||||
add_form.get_checkbox(name=uname) +
|
||||
@ -123,6 +123,6 @@ class edit(FormPlugin, PagePlugin):
|
||||
return self.fill_template(template="err", title=_("Unnown User"), main=main,
|
||||
sidebar_left=self.sidebar_left, sidebar_right=sidebar_right)
|
||||
|
||||
main = _("""<h2>Edit User '%s'</h2>""" % u['username'])
|
||||
main = _("""<strong>Edit User '%s'</strong>""" % u['username'])
|
||||
sidebar_right = ''
|
||||
return self.fill_template(title="", main=main, sidebar_left=self.sidebar_left, sidebar_right=sidebar_right)
|
||||
|
||||
@ -22,13 +22,13 @@ class wan(FormPlugin, PagePlugin):
|
||||
end will be reachable from the WAN. If your %(box)s
|
||||
connects you to the internet, that means you'll be able to log
|
||||
in to the front end from the internet. This might be
|
||||
convenient, but it is also <b>dangerous</b>, since it can
|
||||
convenient, but it is also <strong>dangerous</strong>, since it can
|
||||
enable attackers to gain access to your %(box)s from the
|
||||
outside world. All they'll need is your username and
|
||||
passphrase, which they might guess or they might simply try
|
||||
every posible combination of letters and numbers until they
|
||||
get in. If you enable the WAN administration option, you
|
||||
<b>must</b> use long and complex passphrases.</p>
|
||||
<strong>must</strong> use long and complex passphrases.</p>
|
||||
|
||||
<p>For security reasons, neither WAN Administration nor WAN
|
||||
SSH is available to the `admin` user account.</p>
|
||||
|
||||
@ -40,7 +40,7 @@ def error_page_500(status, message, traceback, version):
|
||||
cfg.log.error("500 Internal Server Error. Trackback is above.")
|
||||
more="""<p>This is an internal error and not something you caused
|
||||
or can fix. Please report the error on the <a
|
||||
href="https://github.com/jvasile/Plinth/issues">bug tracker</a> so
|
||||
href="https://github.com/seandiggity/Plinth/issues">bug tracker</a> so
|
||||
we can fix it.</p>"""
|
||||
return error_page(status, message, "<p>%s</p><pre>%s</pre>" % (more, "\n".join(traceback.split("\n"))))
|
||||
|
||||
@ -68,7 +68,7 @@ def load_modules():
|
||||
cfg.log("skipping %s" % name)
|
||||
|
||||
def parse_arguments():
|
||||
parser = argparse.ArgumentParser(description='Plinht web interface for the FreedomBox.')
|
||||
parser = argparse.ArgumentParser(description='Plinth web interface for the FreedomBox.')
|
||||
parser.add_argument('--pidfile', default="",
|
||||
help='specify a file in which the server may write its pid')
|
||||
args=parser.parse_args()
|
||||
|
||||
@ -5,27 +5,105 @@
|
||||
$default
|
||||
#end if
|
||||
#end def
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-GB">
|
||||
<!doctype html>
|
||||
<!--[if lt IE 7 ]> <html class="ie ie6 no-js" lang="en"> <![endif]-->
|
||||
<!--[if IE 7 ]> <html class="ie ie7 no-js" lang="en"> <![endif]-->
|
||||
<!--[if IE 8 ]> <html class="ie ie8 no-js" lang="en"> <![endif]-->
|
||||
<!--[if IE 9 ]> <html class="ie ie9 no-js" lang="en"> <![endif]-->
|
||||
<!--[if gt IE 9]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
|
||||
<!-- the "no-js" class is for Modernizr -->
|
||||
<head>
|
||||
<title>$default($title, "Plinth Front End to the Freedom Box")
|
||||
</title>
|
||||
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
|
||||
<meta name="description" content="Plint admin frontend for Freedom Box" />
|
||||
<meta name="robots" content="noindex, nofollow" />
|
||||
<link rel="shortcut icon" href="$basehref/favicon.ico" type="image/x-icon" />
|
||||
<link rel="stylesheet" type="text/css" href="$basehref/static/theme/style.tiny.css" media="screen" />
|
||||
$css
|
||||
<script type="text/javascript" src="$basehref/static/theme/menu.js"></script>
|
||||
<script type="text/javascript" src="$basehref/static/theme/plinth.js"></script>
|
||||
$js
|
||||
$main_menu_js
|
||||
$sub_menu_js
|
||||
<script LANGUAGE="JavaScript">
|
||||
<!--
|
||||
$onload
|
||||
// -->
|
||||
</script>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<!-- Always force latest IE rendering engine and Chrome Frame -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
|
||||
<!-- Mobile Viewport Fix http://j.mp/mobileviewport & http://davidbcalhoun.com/2010/viewport-metatag
|
||||
device-width : Occupy full width of the screen in its current orientation
|
||||
initial-scale = 1.0 retains dimensions instead of zooming out if page height > device height
|
||||
maximum-scale = 1.0 retains dimensions instead of zooming in if page width < device width
|
||||
-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
|
||||
<!-- R2D2, you know better than to trust a strange computer! -->
|
||||
<meta name="robots" content="noindex, nofollow, noarchive" />
|
||||
<meta name="googlebot" content="noindex, nofollow, noarchive, nosnippet, noodp, noimageindex, notranslate" />
|
||||
<meta name="msnbot" content="noindex, nofollow, noarchive, noodp" />
|
||||
<meta name="slurp" content="noindex, nofollow, noarchive, noodp, noydir" />
|
||||
|
||||
<meta name="title" content="$default($title, 'FreedomBox Dashboard')" />
|
||||
<meta name="description" content="Plinth administrative interface for the FreedomBox" />
|
||||
<title>$default($title, "FreedomBox Dashboard")</title>
|
||||
|
||||
<!-- This is the traditional favicon. Size: 16x16 or 32x32, transparency is OK -->
|
||||
<link rel="shortcut icon" href="$basehref/static/theme/img/favicon.ico" />
|
||||
|
||||
<!-- The is the icon for iOS's Web Clip. Size: 57x57 for older iPhones, 72x72 for iPads, 114x114 for iPhone4
|
||||
- To prevent iOS from applying its styles to the icon name it thusly: apple-touch-icon-precomposed.png
|
||||
- Transparency is not recommended (iOS will put a black BG behind the icon) -->
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="$basehref/static/theme/img/apple-touch-icon-57px-precomposed.png" />
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="$basehref/static/theme/img/apple-touch-icon-72px-precomposed.png" />
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="$basehref/static/theme/img/apple-touch-icon-114px-precomposed.png" />
|
||||
|
||||
<!-- Bootstrap base CSS -->
|
||||
<link rel="stylesheet" href="$basehref/static/theme/css/bootstrap.css" />
|
||||
<style type="text/css">
|
||||
/* custom styles, load before bootstrap responsive styles */
|
||||
body {
|
||||
padding-top:60px;
|
||||
padding-bottom:40px;
|
||||
}
|
||||
.sidebar-nav {
|
||||
padding: 9px 0;
|
||||
}
|
||||
</style>
|
||||
<!-- Bootstrap responsive CSS -->
|
||||
<link rel="stylesheet" href="$basehref/static/theme/css/bootstrap-responsive.css" />
|
||||
<style type="text/css">
|
||||
/* custom styles, load after all bootstrap styles */
|
||||
.super-hero {
|
||||
margin-top:25px;
|
||||
}
|
||||
.logo-top {
|
||||
float:left;
|
||||
padding-right:5px;
|
||||
}
|
||||
.brand {
|
||||
padding-top:8px;
|
||||
}
|
||||
.white {
|
||||
color:#fff;
|
||||
}
|
||||
.error-large {
|
||||
font-size:1.2em;
|
||||
padding:10px;
|
||||
}
|
||||
.main-graphic {
|
||||
float:right;
|
||||
padding:25px;
|
||||
}
|
||||
.nav-icon {
|
||||
margin-right:8px;
|
||||
}
|
||||
.sidenav-icon {
|
||||
margin-right:8px;
|
||||
padding-right:5px;
|
||||
}
|
||||
</style>
|
||||
<!-- CSS from previous Plinth template, not sure what to keep yet -->
|
||||
$css
|
||||
<!-- End Plinth CSS -->
|
||||
<!-- JS from previous Plinth template, not sure what to keep yet -->
|
||||
<script type="text/javascript" src="$basehref/static/theme/js/menu.js"></script>
|
||||
<script type="text/javascript" src="$basehref/static/theme/js/plinth.js"></script>
|
||||
$js
|
||||
$main_menu_js
|
||||
$sub_menu_js
|
||||
<script type="text/javascript">
|
||||
<!--
|
||||
$onload
|
||||
// -->
|
||||
</script>
|
||||
</head>
|
||||
<body onLoad="javascript:onload_handler();">
|
||||
<div id="header">
|
||||
@ -47,66 +125,110 @@
|
||||
#else
|
||||
<p id="layoutdims">Not logged in. <a href="$basehref/auth/login" title="Log in">Log in.</a></p>
|
||||
#end if
|
||||
|
||||
</div>
|
||||
<div class="colmask threecol">
|
||||
<div class="colmid">
|
||||
<div class="colleft">
|
||||
<div class="col1">
|
||||
<!-- Column 1 start -->
|
||||
<h2>
|
||||
#block title_block
|
||||
$title
|
||||
#end block title_block
|
||||
</h2>
|
||||
#block main_block
|
||||
$main
|
||||
#end block main_block
|
||||
<!-- Column 1 end -->
|
||||
</div>
|
||||
<div class="col2">
|
||||
<!-- Column 2 start -->
|
||||
#block nav_block
|
||||
$nav
|
||||
#end block nav_block
|
||||
#block sidebar_left_block
|
||||
$sidebar_left
|
||||
#end block sidebar_left_block
|
||||
<!-- Column 2 end -->
|
||||
</div>
|
||||
<div class="col3">
|
||||
<!-- Column 3 start -->
|
||||
<div id="ads">
|
||||
<!--<a href="http://matthewjamestaylor.com">
|
||||
<img src="mjt-125x125.gif" width="125" border="0" height="125" alt="Art and Design by Matthew James Taylor" />
|
||||
</a>
|
||||
-->
|
||||
</div>
|
||||
#block sidebar_right_block
|
||||
$sidebar_right
|
||||
#end block sidebar_right_block
|
||||
<!-- Column 3 end -->
|
||||
<div class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container-fluid">
|
||||
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</a>
|
||||
<a href="$basehref/" class="logo-top"><img src="$basehref/static/theme/img/freedombox-logo-32px.png" alt="FreedomBox" /></a><a class="brand" href="$basehref/">FreedomBox Dashboard</a>
|
||||
<div class="nav-collapse">
|
||||
<script type="text/javascript">
|
||||
<!--
|
||||
main_menu(main_menu_items);
|
||||
// -->
|
||||
</script>
|
||||
#if $username
|
||||
<p class="navbar-text pull-right"><i class="icon-user icon-white nav-icon"></i>Logged in as <a href="$username">$username</a>. <a href="$basehref/auth/logout" title="Log out">Log out</a>.</p>
|
||||
#else
|
||||
<p class="navbar-text pull-right">Not logged in. <i class="icon-user icon-white nav-icon"></i><a href="$basehref/auth/login" title="Log in">Log in</a>.</p>
|
||||
#end if
|
||||
</div><!--/.nav-collapse -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
#block footer_block
|
||||
<p>
|
||||
Plinth is copyright 2011 <a href="http://hackervisions.org">James Vasile</a>. It is
|
||||
free software offered to you under the terms of
|
||||
the <a href="http://www.gnu.org/licenses/agpl.html">GNU Affero General Public
|
||||
License</a>, Version 3 or later.
|
||||
</p>
|
||||
<!--<p>Current page: $current_url</p>-->
|
||||
<p>
|
||||
This page uses
|
||||
the <a href="http://matthewjamestaylor.com/blog/perfect-3-column.htm">Perfect
|
||||
'Holy Grail' 3 Column Liquid Layout</a>
|
||||
by <a href="http://matthewjamestaylor.com">Matthew James Taylor</a>.
|
||||
</p>
|
||||
#end block footer_block
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row-fluid">
|
||||
<div class="span3">
|
||||
<div class="well sidebar-nav">
|
||||
#block nav_block
|
||||
$nav
|
||||
#end block nav_block
|
||||
#block sidebar_left_block
|
||||
$sidebar_left
|
||||
#end block sidebar_left_block
|
||||
</div><!--/.well -->
|
||||
</div><!--/span-->
|
||||
<div class="span9">
|
||||
<div class="hero-unit">
|
||||
<h2>
|
||||
#block title_block
|
||||
$title
|
||||
#end block title_block
|
||||
</h2>
|
||||
#block main_block
|
||||
$main
|
||||
#end block main_block
|
||||
</div>
|
||||
|
||||
<div class="row-fluid">
|
||||
<div class="span8 alert alert-info">
|
||||
#block sidebar_right_block
|
||||
$sidebar_right
|
||||
#end block sidebar_right_block
|
||||
</div><!--/span-->
|
||||
</div><!--/row-->
|
||||
|
||||
</div><!--/span-->
|
||||
</div><!--/row-->
|
||||
|
||||
<hr>
|
||||
|
||||
<footer>
|
||||
<p>#block footer_block
|
||||
<p>
|
||||
Plinth is © Copyright 2012 <a href="http://hackervisions.org" target="_blank">James Vasile</a>. It is
|
||||
free software offered to you under the terms of
|
||||
the <a href="http://www.gnu.org/licenses/agpl.html" target="_blank">GNU Affero General Public
|
||||
License</a>, Version 3 or later. This Plinth theme was built by <a href="http://seandiggity.com" target="_blank">Sean "Diggity" O'Brien</a>.
|
||||
</p>
|
||||
<p>Current page: $current_url</p>
|
||||
<p>
|
||||
|
||||
</p>
|
||||
#end block footer_block</p>
|
||||
</footer>
|
||||
|
||||
</div><!--/.fluid-container-->
|
||||
|
||||
<!-- JavaScript <script> tags are placed at the end of the document to speed up initial page loads-->
|
||||
<!-- Local copy of HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
<!--[if lt IE 9]>
|
||||
<script type="text/javascript" src="$basehref/static/theme/js/libs/html5.js"></script>
|
||||
<![endif]-->
|
||||
<!-- Local copy of Modernizr -->
|
||||
<script type="text/javascript" src="$basehref/static/theme/js/libs/modernizr-2.5.3-respond-1.1.0.min.js"></script>
|
||||
<!-- Local copy of jQuery -->
|
||||
<script type="text/javascript" src="$basehref/static/theme/js/libs/jquery-1.7.1.min.js"></script>
|
||||
<!-- Bootstrap JS, most files commented out until we know what we need -->
|
||||
<!--<script type="text/javascript" src="$basehref/static/theme/js/libs/bootstrap/bootstrap.js"></script>-->
|
||||
<script type="text/javascript" src="$basehref/static/theme/js/libs/bootstrap/bootstrap-min.js"></script>
|
||||
<script type="text/javascript" src="$basehref/static/theme/js/libs/bootstrap/button.js"></script>
|
||||
<script type="text/javascript" src="$basehref/static/theme/js/libs/bootstrap/dropdown.js"></script>
|
||||
<script type="text/javascript" src="$basehref/static/theme/js/libs/bootstrap/collapse.js"></script>
|
||||
<!--<script type="text/javascript" src="$basehref/static/theme/js/libs/bootstrap/transition.js"></script>-->
|
||||
<!--<script type="text/javascript" src="$basehref/static/theme/js/libs/bootstrap/alert.js"></script>-->
|
||||
<!--<script type="text/javascript" src="$basehref/static/theme/js/libs/bootstrap/modal.js"></script>-->
|
||||
<!--<script type="text/javascript" src="$basehref/static/theme/js/libs/bootstrap/scrollspy.js"></script>-->
|
||||
<!--<script type="text/javascript" src="$basehref/static/theme/js/libs/bootstrap/tab.js"></script>-->
|
||||
<!--<script type="text/javascript" src="$basehref/static/theme/js/libs/bootstrap/tooltip.js"></script>-->
|
||||
<!--<script type="text/javascript" src="$basehref/static/theme/js/libs/bootstrap/popover.js"></script>-->
|
||||
<!--<script type="text/javascript" src="$basehref/static/theme/js/libs/bootstrap/carousel.js"></script>-->
|
||||
<!--<script type="text/javascript" src="$basehref/static/theme/js/libs/bootstrap/typeahead.js"></script>-->
|
||||
<!-- JS plugins -->
|
||||
<script type="text/javascript" src="$basehref/static/theme/js/plugins.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#extends templates.two_col
|
||||
|
||||
#def title_block
|
||||
<span class="err">Error: $title</span>
|
||||
<span class="label label-important error-large">Error: $title</span>
|
||||
<br />
|
||||
<br />
|
||||
#end def
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#extends templates.base
|
||||
|
||||
#def css
|
||||
<link rel="stylesheet" type="text/css" href="$basehref/static/theme/2col.tiny.css" media="screen" />
|
||||
<!-- CSS from previous template, not sure what to keep yet -->
|
||||
<!--<link rel="stylesheet" href="$basehref/static/theme/style-plinth-2col.css" />-->
|
||||
#end def
|
||||
|
||||
@ -1,30 +0,0 @@
|
||||
/* 2 Column settings */
|
||||
|
||||
.colright {
|
||||
float:left;
|
||||
width:0%; /* width of page */
|
||||
position:relative;
|
||||
}
|
||||
|
||||
.threecol .colmid {
|
||||
right:5%; /* width of the right column */
|
||||
}
|
||||
.threecol .colleft {
|
||||
right:70%; /* width of the middle column */
|
||||
}
|
||||
.threecol .col1 {
|
||||
width:66%; /* width of center column content (column width minus padding on either side) */
|
||||
left:102%; /* 100% plus left padding of center column */
|
||||
}
|
||||
.threecol .col2 {
|
||||
width:21%; /* Width of left column content (column width minus padding on either side) */
|
||||
left:11%; /* width of (right column) plus (center column left and right padding) plus (left column left padding) */
|
||||
}
|
||||
.threecol .col3 {
|
||||
width:21%; /* Width of right column content (column width minus padding on either side) */
|
||||
|
||||
/* Note this used to be 85%, but I subtracted 1% for padding to pull stuff closer to the margin */
|
||||
left:84%; /* Please make note of the brackets here:
|
||||
(100% - left column width) plus (center column left and right padding) plus (left column left and right padding) plus (right column left padding) */
|
||||
}
|
||||
|
||||
BIN
themes/default/FreedomBox-Identity-Manual.pdf
Normal file
BIN
themes/default/FreedomBox-Logo.7z
Normal file
581
themes/default/css/bootstrap-responsive.css
vendored
Normal file
@ -0,0 +1,581 @@
|
||||
/*!
|
||||
* Bootstrap Responsive v2.0.1
|
||||
*
|
||||
* Copyright 2012 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 @twitter by @mdo and @fat.
|
||||
*/
|
||||
.clearfix {
|
||||
*zoom: 1;
|
||||
}
|
||||
.clearfix:before, .clearfix:after {
|
||||
display: table;
|
||||
content: "";
|
||||
}
|
||||
.clearfix:after {
|
||||
clear: both;
|
||||
}
|
||||
.hidden {
|
||||
display: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
@media (max-width: 480px) {
|
||||
.nav-collapse {
|
||||
-webkit-transform: translate3d(0, 0, 0);
|
||||
}
|
||||
.page-header h1 small {
|
||||
display: block;
|
||||
line-height: 18px;
|
||||
}
|
||||
input[class*="span"],
|
||||
select[class*="span"],
|
||||
textarea[class*="span"],
|
||||
.uneditable-input {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-height: 28px;
|
||||
/* Make inputs at least the height of their button counterpart */
|
||||
|
||||
/* Makes inputs behave like true block-level elements */
|
||||
|
||||
-webkit-box-sizing: border-box;
|
||||
/* Older Webkit */
|
||||
|
||||
-moz-box-sizing: border-box;
|
||||
/* Older FF */
|
||||
|
||||
-ms-box-sizing: border-box;
|
||||
/* IE8 */
|
||||
|
||||
box-sizing: border-box;
|
||||
/* CSS3 spec*/
|
||||
|
||||
}
|
||||
.input-prepend input[class*="span"], .input-append input[class*="span"] {
|
||||
width: auto;
|
||||
}
|
||||
input[type="checkbox"], input[type="radio"] {
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
.form-horizontal .control-group > label {
|
||||
float: none;
|
||||
width: auto;
|
||||
padding-top: 0;
|
||||
text-align: left;
|
||||
}
|
||||
.form-horizontal .controls {
|
||||
margin-left: 0;
|
||||
}
|
||||
.form-horizontal .control-list {
|
||||
padding-top: 0;
|
||||
}
|
||||
.form-horizontal .form-actions {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
.modal {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
right: 10px;
|
||||
width: auto;
|
||||
margin: 0;
|
||||
}
|
||||
.modal.fade.in {
|
||||
top: auto;
|
||||
}
|
||||
.modal-header .close {
|
||||
padding: 10px;
|
||||
margin: -10px;
|
||||
}
|
||||
.carousel-caption {
|
||||
position: static;
|
||||
}
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
.container {
|
||||
width: auto;
|
||||
padding: 0 20px;
|
||||
}
|
||||
.row-fluid {
|
||||
width: 100%;
|
||||
}
|
||||
.row {
|
||||
margin-left: 0;
|
||||
}
|
||||
.row > [class*="span"], .row-fluid > [class*="span"] {
|
||||
float: none;
|
||||
display: block;
|
||||
width: auto;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
@media (min-width: 768px) and (max-width: 979px) {
|
||||
.row {
|
||||
margin-left: -20px;
|
||||
*zoom: 1;
|
||||
}
|
||||
.row:before, .row:after {
|
||||
display: table;
|
||||
content: "";
|
||||
}
|
||||
.row:after {
|
||||
clear: both;
|
||||
}
|
||||
[class*="span"] {
|
||||
float: left;
|
||||
margin-left: 20px;
|
||||
}
|
||||
.span1 {
|
||||
width: 42px;
|
||||
}
|
||||
.span2 {
|
||||
width: 104px;
|
||||
}
|
||||
.span3 {
|
||||
width: 166px;
|
||||
}
|
||||
.span4 {
|
||||
width: 228px;
|
||||
}
|
||||
.span5 {
|
||||
width: 290px;
|
||||
}
|
||||
.span6 {
|
||||
width: 352px;
|
||||
}
|
||||
.span7 {
|
||||
width: 414px;
|
||||
}
|
||||
.span8 {
|
||||
width: 476px;
|
||||
}
|
||||
.span9 {
|
||||
width: 538px;
|
||||
}
|
||||
.span10 {
|
||||
width: 600px;
|
||||
}
|
||||
.span11 {
|
||||
width: 662px;
|
||||
}
|
||||
.span12, .container {
|
||||
width: 724px;
|
||||
}
|
||||
.offset1 {
|
||||
margin-left: 82px;
|
||||
}
|
||||
.offset2 {
|
||||
margin-left: 144px;
|
||||
}
|
||||
.offset3 {
|
||||
margin-left: 206px;
|
||||
}
|
||||
.offset4 {
|
||||
margin-left: 268px;
|
||||
}
|
||||
.offset5 {
|
||||
margin-left: 330px;
|
||||
}
|
||||
.offset6 {
|
||||
margin-left: 392px;
|
||||
}
|
||||
.offset7 {
|
||||
margin-left: 454px;
|
||||
}
|
||||
.offset8 {
|
||||
margin-left: 516px;
|
||||
}
|
||||
.offset9 {
|
||||
margin-left: 578px;
|
||||
}
|
||||
.offset10 {
|
||||
margin-left: 640px;
|
||||
}
|
||||
.offset11 {
|
||||
margin-left: 702px;
|
||||
}
|
||||
.row-fluid {
|
||||
width: 100%;
|
||||
*zoom: 1;
|
||||
}
|
||||
.row-fluid:before, .row-fluid:after {
|
||||
display: table;
|
||||
content: "";
|
||||
}
|
||||
.row-fluid:after {
|
||||
clear: both;
|
||||
}
|
||||
.row-fluid > [class*="span"] {
|
||||
float: left;
|
||||
margin-left: 2.762430939%;
|
||||
}
|
||||
.row-fluid > [class*="span"]:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
.row-fluid > .span1 {
|
||||
width: 5.801104972%;
|
||||
}
|
||||
.row-fluid > .span2 {
|
||||
width: 14.364640883%;
|
||||
}
|
||||
.row-fluid > .span3 {
|
||||
width: 22.928176794%;
|
||||
}
|
||||
.row-fluid > .span4 {
|
||||
width: 31.491712705%;
|
||||
}
|
||||
.row-fluid > .span5 {
|
||||
width: 40.055248616%;
|
||||
}
|
||||
.row-fluid > .span6 {
|
||||
width: 48.618784527%;
|
||||
}
|
||||
.row-fluid > .span7 {
|
||||
width: 57.182320438000005%;
|
||||
}
|
||||
.row-fluid > .span8 {
|
||||
width: 65.74585634900001%;
|
||||
}
|
||||
.row-fluid > .span9 {
|
||||
width: 74.30939226%;
|
||||
}
|
||||
.row-fluid > .span10 {
|
||||
width: 82.87292817100001%;
|
||||
}
|
||||
.row-fluid > .span11 {
|
||||
width: 91.436464082%;
|
||||
}
|
||||
.row-fluid > .span12 {
|
||||
width: 99.999999993%;
|
||||
}
|
||||
input.span1, textarea.span1, .uneditable-input.span1 {
|
||||
width: 32px;
|
||||
}
|
||||
input.span2, textarea.span2, .uneditable-input.span2 {
|
||||
width: 94px;
|
||||
}
|
||||
input.span3, textarea.span3, .uneditable-input.span3 {
|
||||
width: 156px;
|
||||
}
|
||||
input.span4, textarea.span4, .uneditable-input.span4 {
|
||||
width: 218px;
|
||||
}
|
||||
input.span5, textarea.span5, .uneditable-input.span5 {
|
||||
width: 280px;
|
||||
}
|
||||
input.span6, textarea.span6, .uneditable-input.span6 {
|
||||
width: 342px;
|
||||
}
|
||||
input.span7, textarea.span7, .uneditable-input.span7 {
|
||||
width: 404px;
|
||||
}
|
||||
input.span8, textarea.span8, .uneditable-input.span8 {
|
||||
width: 466px;
|
||||
}
|
||||
input.span9, textarea.span9, .uneditable-input.span9 {
|
||||
width: 528px;
|
||||
}
|
||||
input.span10, textarea.span10, .uneditable-input.span10 {
|
||||
width: 590px;
|
||||
}
|
||||
input.span11, textarea.span11, .uneditable-input.span11 {
|
||||
width: 652px;
|
||||
}
|
||||
input.span12, textarea.span12, .uneditable-input.span12 {
|
||||
width: 714px;
|
||||
}
|
||||
}
|
||||
@media (max-width: 979px) {
|
||||
body {
|
||||
padding-top: 0;
|
||||
}
|
||||
.navbar-fixed-top {
|
||||
position: static;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
.navbar-fixed-top .navbar-inner {
|
||||
padding: 5px;
|
||||
}
|
||||
.navbar .container {
|
||||
width: auto;
|
||||
padding: 0;
|
||||
}
|
||||
.navbar .brand {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
margin: 0 0 0 -5px;
|
||||
}
|
||||
.navbar .nav-collapse {
|
||||
clear: left;
|
||||
}
|
||||
.navbar .nav {
|
||||
float: none;
|
||||
margin: 0 0 9px;
|
||||
}
|
||||
.navbar .nav > li {
|
||||
float: none;
|
||||
}
|
||||
.navbar .nav > li > a {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.navbar .nav > .divider-vertical {
|
||||
display: none;
|
||||
}
|
||||
.navbar .nav .nav-header {
|
||||
color: #999999;
|
||||
text-shadow: none;
|
||||
}
|
||||
.navbar .nav > li > a, .navbar .dropdown-menu a {
|
||||
padding: 6px 15px;
|
||||
font-weight: bold;
|
||||
color: #999999;
|
||||
-webkit-border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.navbar .dropdown-menu li + li a {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.navbar .nav > li > a:hover, .navbar .dropdown-menu a:hover {
|
||||
background-color: #222222;
|
||||
}
|
||||
.navbar .dropdown-menu {
|
||||
position: static;
|
||||
top: auto;
|
||||
left: auto;
|
||||
float: none;
|
||||
display: block;
|
||||
max-width: none;
|
||||
margin: 0 15px;
|
||||
padding: 0;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
-webkit-border-radius: 0;
|
||||
-moz-border-radius: 0;
|
||||
border-radius: 0;
|
||||
-webkit-box-shadow: none;
|
||||
-moz-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
.navbar .dropdown-menu:before, .navbar .dropdown-menu:after {
|
||||
display: none;
|
||||
}
|
||||
.navbar .dropdown-menu .divider {
|
||||
display: none;
|
||||
}
|
||||
.navbar-form, .navbar-search {
|
||||
float: none;
|
||||
padding: 9px 15px;
|
||||
margin: 9px 0;
|
||||
border-top: 1px solid #222222;
|
||||
border-bottom: 1px solid #222222;
|
||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
|
||||
-moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
.navbar .nav.pull-right {
|
||||
float: none;
|
||||
margin-left: 0;
|
||||
}
|
||||
.navbar-static .navbar-inner {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
.btn-navbar {
|
||||
display: block;
|
||||
}
|
||||
.nav-collapse {
|
||||
overflow: hidden;
|
||||
height: 0;
|
||||
}
|
||||
}
|
||||
@media (min-width: 980px) {
|
||||
.nav-collapse.collapse {
|
||||
height: auto !important;
|
||||
}
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
.row {
|
||||
margin-left: -30px;
|
||||
*zoom: 1;
|
||||
}
|
||||
.row:before, .row:after {
|
||||
display: table;
|
||||
content: "";
|
||||
}
|
||||
.row:after {
|
||||
clear: both;
|
||||
}
|
||||
[class*="span"] {
|
||||
float: left;
|
||||
margin-left: 30px;
|
||||
}
|
||||
.span1 {
|
||||
width: 70px;
|
||||
}
|
||||
.span2 {
|
||||
width: 170px;
|
||||
}
|
||||
.span3 {
|
||||
width: 270px;
|
||||
}
|
||||
.span4 {
|
||||
width: 370px;
|
||||
}
|
||||
.span5 {
|
||||
width: 470px;
|
||||
}
|
||||
.span6 {
|
||||
width: 570px;
|
||||
}
|
||||
.span7 {
|
||||
width: 670px;
|
||||
}
|
||||
.span8 {
|
||||
width: 770px;
|
||||
}
|
||||
.span9 {
|
||||
width: 870px;
|
||||
}
|
||||
.span10 {
|
||||
width: 970px;
|
||||
}
|
||||
.span11 {
|
||||
width: 1070px;
|
||||
}
|
||||
.span12, .container {
|
||||
width: 1170px;
|
||||
}
|
||||
.offset1 {
|
||||
margin-left: 130px;
|
||||
}
|
||||
.offset2 {
|
||||
margin-left: 230px;
|
||||
}
|
||||
.offset3 {
|
||||
margin-left: 330px;
|
||||
}
|
||||
.offset4 {
|
||||
margin-left: 430px;
|
||||
}
|
||||
.offset5 {
|
||||
margin-left: 530px;
|
||||
}
|
||||
.offset6 {
|
||||
margin-left: 630px;
|
||||
}
|
||||
.offset7 {
|
||||
margin-left: 730px;
|
||||
}
|
||||
.offset8 {
|
||||
margin-left: 830px;
|
||||
}
|
||||
.offset9 {
|
||||
margin-left: 930px;
|
||||
}
|
||||
.offset10 {
|
||||
margin-left: 1030px;
|
||||
}
|
||||
.offset11 {
|
||||
margin-left: 1130px;
|
||||
}
|
||||
.row-fluid {
|
||||
width: 100%;
|
||||
*zoom: 1;
|
||||
}
|
||||
.row-fluid:before, .row-fluid:after {
|
||||
display: table;
|
||||
content: "";
|
||||
}
|
||||
.row-fluid:after {
|
||||
clear: both;
|
||||
}
|
||||
.row-fluid > [class*="span"] {
|
||||
float: left;
|
||||
margin-left: 2.564102564%;
|
||||
}
|
||||
.row-fluid > [class*="span"]:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
.row-fluid > .span1 {
|
||||
width: 5.982905983%;
|
||||
}
|
||||
.row-fluid > .span2 {
|
||||
width: 14.529914530000001%;
|
||||
}
|
||||
.row-fluid > .span3 {
|
||||
width: 23.076923077%;
|
||||
}
|
||||
.row-fluid > .span4 {
|
||||
width: 31.623931624%;
|
||||
}
|
||||
.row-fluid > .span5 {
|
||||
width: 40.170940171000005%;
|
||||
}
|
||||
.row-fluid > .span6 {
|
||||
width: 48.717948718%;
|
||||
}
|
||||
.row-fluid > .span7 {
|
||||
width: 57.264957265%;
|
||||
}
|
||||
.row-fluid > .span8 {
|
||||
width: 65.81196581200001%;
|
||||
}
|
||||
.row-fluid > .span9 {
|
||||
width: 74.358974359%;
|
||||
}
|
||||
.row-fluid > .span10 {
|
||||
width: 82.905982906%;
|
||||
}
|
||||
.row-fluid > .span11 {
|
||||
width: 91.45299145300001%;
|
||||
}
|
||||
.row-fluid > .span12 {
|
||||
width: 100%;
|
||||
}
|
||||
input.span1, textarea.span1, .uneditable-input.span1 {
|
||||
width: 60px;
|
||||
}
|
||||
input.span2, textarea.span2, .uneditable-input.span2 {
|
||||
width: 160px;
|
||||
}
|
||||
input.span3, textarea.span3, .uneditable-input.span3 {
|
||||
width: 260px;
|
||||
}
|
||||
input.span4, textarea.span4, .uneditable-input.span4 {
|
||||
width: 360px;
|
||||
}
|
||||
input.span5, textarea.span5, .uneditable-input.span5 {
|
||||
width: 460px;
|
||||
}
|
||||
input.span6, textarea.span6, .uneditable-input.span6 {
|
||||
width: 560px;
|
||||
}
|
||||
input.span7, textarea.span7, .uneditable-input.span7 {
|
||||
width: 660px;
|
||||
}
|
||||
input.span8, textarea.span8, .uneditable-input.span8 {
|
||||
width: 760px;
|
||||
}
|
||||
input.span9, textarea.span9, .uneditable-input.span9 {
|
||||
width: 860px;
|
||||
}
|
||||
input.span10, textarea.span10, .uneditable-input.span10 {
|
||||
width: 960px;
|
||||
}
|
||||
input.span11, textarea.span11, .uneditable-input.span11 {
|
||||
width: 1060px;
|
||||
}
|
||||
input.span12, textarea.span12, .uneditable-input.span12 {
|
||||
width: 1160px;
|
||||
}
|
||||
.thumbnails {
|
||||
margin-left: -30px;
|
||||
}
|
||||
.thumbnails > li {
|
||||
margin-left: 30px;
|
||||
}
|
||||
}
|
||||
3496
themes/default/css/bootstrap.css
vendored
Normal file
|
Before Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 22 KiB |
BIN
themes/default/img/FreedomBox-logo-grayscale-negative.png
Executable file
|
After Width: | Height: | Size: 50 KiB |
144
themes/default/img/FreedomBox-logo-grayscale-negative.svg
Executable file
|
After Width: | Height: | Size: 14 KiB |
BIN
themes/default/img/FreedomBox-logo-grayscale.png
Executable file
|
After Width: | Height: | Size: 52 KiB |
166
themes/default/img/FreedomBox-logo-grayscale.svg
Executable file
|
After Width: | Height: | Size: 15 KiB |
BIN
themes/default/img/FreedomBox-logo-lineart-negative.png
Executable file
|
After Width: | Height: | Size: 36 KiB |
88
themes/default/img/FreedomBox-logo-lineart-negative.svg
Executable file
|
After Width: | Height: | Size: 14 KiB |
BIN
themes/default/img/FreedomBox-logo-lineart.png
Executable file
|
After Width: | Height: | Size: 38 KiB |
122
themes/default/img/FreedomBox-logo-lineart.svg
Executable file
|
After Width: | Height: | Size: 14 KiB |
BIN
themes/default/img/FreedomBox-logo-standard.png
Executable file
|
After Width: | Height: | Size: 66 KiB |
122
themes/default/img/FreedomBox-logo-standard.svg
Executable file
|
After Width: | Height: | Size: 14 KiB |
BIN
themes/default/img/apple-touch-icon-114px-precomposed.png
Normal file
|
After Width: | Height: | Size: 9.7 KiB |
BIN
themes/default/img/apple-touch-icon-57px-precomposed.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
themes/default/img/apple-touch-icon-72px-precomposed.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
BIN
themes/default/img/apple-touch-icon.xcf
Normal file
BIN
themes/default/img/favicon-32px.ico
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
themes/default/img/favicon.ico
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
themes/default/img/freedombox-logo-200px.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
themes/default/img/freedombox-logo-250px.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
themes/default/img/freedombox-logo-32px.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
BIN
themes/default/img/glyphicons-halflings-white.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
themes/default/img/glyphicons-halflings.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
23
themes/default/js/functions.js
Normal file
@ -0,0 +1,23 @@
|
||||
// remap jQuery to $
|
||||
(function($){})(window.jQuery);
|
||||
|
||||
|
||||
/* trigger when page is ready */
|
||||
$(document).ready(function (){
|
||||
|
||||
// your functions go here
|
||||
|
||||
});
|
||||
|
||||
|
||||
/* optional triggers
|
||||
|
||||
$(window).load(function() {
|
||||
|
||||
});
|
||||
|
||||
$(window).resize(function() {
|
||||
|
||||
});
|
||||
|
||||
*/
|
||||
91
themes/default/js/libs/bootstrap/alert.js
Normal file
@ -0,0 +1,91 @@
|
||||
/* ==========================================================
|
||||
* bootstrap-alert.js v2.0.0
|
||||
* http://twitter.github.com/bootstrap/javascript.html#alerts
|
||||
* ==========================================================
|
||||
* Copyright 2012 Twitter, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ========================================================== */
|
||||
|
||||
|
||||
!function( $ ){
|
||||
|
||||
"use strict"
|
||||
|
||||
/* ALERT CLASS DEFINITION
|
||||
* ====================== */
|
||||
|
||||
var dismiss = '[data-dismiss="alert"]'
|
||||
, Alert = function ( el ) {
|
||||
$(el).on('click', dismiss, this.close)
|
||||
}
|
||||
|
||||
Alert.prototype = {
|
||||
|
||||
constructor: Alert
|
||||
|
||||
, close: function ( e ) {
|
||||
var $this = $(this)
|
||||
, selector = $this.attr('data-target')
|
||||
, $parent
|
||||
|
||||
if (!selector) {
|
||||
selector = $this.attr('href')
|
||||
selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
|
||||
}
|
||||
|
||||
$parent = $(selector)
|
||||
$parent.trigger('close')
|
||||
|
||||
e && e.preventDefault()
|
||||
|
||||
$parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent())
|
||||
|
||||
$parent.removeClass('in')
|
||||
|
||||
function removeElement() {
|
||||
$parent.remove()
|
||||
$parent.trigger('closed')
|
||||
}
|
||||
|
||||
$.support.transition && $parent.hasClass('fade') ?
|
||||
$parent.on($.support.transition.end, removeElement) :
|
||||
removeElement()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* ALERT PLUGIN DEFINITION
|
||||
* ======================= */
|
||||
|
||||
$.fn.alert = function ( option ) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
, data = $this.data('alert')
|
||||
if (!data) $this.data('alert', (data = new Alert(this)))
|
||||
if (typeof option == 'string') data[option].call($this)
|
||||
})
|
||||
}
|
||||
|
||||
$.fn.alert.Constructor = Alert
|
||||
|
||||
|
||||
/* ALERT DATA-API
|
||||
* ============== */
|
||||
|
||||
$(function () {
|
||||
$('body').on('click.alert.data-api', dismiss, Alert.prototype.close)
|
||||
})
|
||||
|
||||
}( window.jQuery )
|
||||
1722
themes/default/js/libs/bootstrap/bootstrap.js
vendored
Normal file
1
themes/default/js/libs/bootstrap/bootstrap.min.js
vendored
Normal file
98
themes/default/js/libs/bootstrap/button.js
Normal file
@ -0,0 +1,98 @@
|
||||
/* ============================================================
|
||||
* bootstrap-button.js v2.0.0
|
||||
* http://twitter.github.com/bootstrap/javascript.html#buttons
|
||||
* ============================================================
|
||||
* Copyright 2012 Twitter, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ============================================================ */
|
||||
|
||||
!function( $ ){
|
||||
|
||||
"use strict"
|
||||
|
||||
/* BUTTON PUBLIC CLASS DEFINITION
|
||||
* ============================== */
|
||||
|
||||
var Button = function ( element, options ) {
|
||||
this.$element = $(element)
|
||||
this.options = $.extend({}, $.fn.button.defaults, options)
|
||||
}
|
||||
|
||||
Button.prototype = {
|
||||
|
||||
constructor: Button
|
||||
|
||||
, setState: function ( state ) {
|
||||
var d = 'disabled'
|
||||
, $el = this.$element
|
||||
, data = $el.data()
|
||||
, val = $el.is('input') ? 'val' : 'html'
|
||||
|
||||
state = state + 'Text'
|
||||
data.resetText || $el.data('resetText', $el[val]())
|
||||
|
||||
$el[val](data[state] || this.options[state])
|
||||
|
||||
// push to event loop to allow forms to submit
|
||||
setTimeout(function () {
|
||||
state == 'loadingText' ?
|
||||
$el.addClass(d).attr(d, d) :
|
||||
$el.removeClass(d).removeAttr(d)
|
||||
}, 0)
|
||||
}
|
||||
|
||||
, toggle: function () {
|
||||
var $parent = this.$element.parent('[data-toggle="buttons-radio"]')
|
||||
|
||||
$parent && $parent
|
||||
.find('.active')
|
||||
.removeClass('active')
|
||||
|
||||
this.$element.toggleClass('active')
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* BUTTON PLUGIN DEFINITION
|
||||
* ======================== */
|
||||
|
||||
$.fn.button = function ( option ) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
, data = $this.data('button')
|
||||
, options = typeof option == 'object' && option
|
||||
if (!data) $this.data('button', (data = new Button(this, options)))
|
||||
if (option == 'toggle') data.toggle()
|
||||
else if (option) data.setState(option)
|
||||
})
|
||||
}
|
||||
|
||||
$.fn.button.defaults = {
|
||||
loadingText: 'loading...'
|
||||
}
|
||||
|
||||
$.fn.button.Constructor = Button
|
||||
|
||||
|
||||
/* BUTTON DATA-API
|
||||
* =============== */
|
||||
|
||||
$(function () {
|
||||
$('body').on('click.button.data-api', '[data-toggle^=button]', function ( e ) {
|
||||
$(e.target).button('toggle')
|
||||
})
|
||||
})
|
||||
|
||||
}( window.jQuery )
|
||||
154
themes/default/js/libs/bootstrap/carousel.js
Normal file
@ -0,0 +1,154 @@
|
||||
/* ==========================================================
|
||||
* bootstrap-carousel.js v2.0.0
|
||||
* http://twitter.github.com/bootstrap/javascript.html#carousel
|
||||
* ==========================================================
|
||||
* Copyright 2012 Twitter, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ========================================================== */
|
||||
|
||||
|
||||
!function( $ ){
|
||||
|
||||
"use strict"
|
||||
|
||||
/* CAROUSEL CLASS DEFINITION
|
||||
* ========================= */
|
||||
|
||||
var Carousel = function (element, options) {
|
||||
this.$element = $(element)
|
||||
this.options = $.extend({}, $.fn.carousel.defaults, options)
|
||||
this.options.slide && this.slide(this.options.slide)
|
||||
}
|
||||
|
||||
Carousel.prototype = {
|
||||
|
||||
cycle: function () {
|
||||
this.interval = setInterval($.proxy(this.next, this), this.options.interval)
|
||||
return this
|
||||
}
|
||||
|
||||
, to: function (pos) {
|
||||
var $active = this.$element.find('.active')
|
||||
, children = $active.parent().children()
|
||||
, activePos = children.index($active)
|
||||
, that = this
|
||||
|
||||
if (pos > (children.length - 1) || pos < 0) return
|
||||
|
||||
if (this.sliding) {
|
||||
return this.$element.one('slid', function () {
|
||||
that.to(pos)
|
||||
})
|
||||
}
|
||||
|
||||
if (activePos == pos) {
|
||||
return this.pause().cycle()
|
||||
}
|
||||
|
||||
return this.slide(pos > activePos ? 'next' : 'prev', $(children[pos]))
|
||||
}
|
||||
|
||||
, pause: function () {
|
||||
clearInterval(this.interval)
|
||||
return this
|
||||
}
|
||||
|
||||
, next: function () {
|
||||
if (this.sliding) return
|
||||
return this.slide('next')
|
||||
}
|
||||
|
||||
, prev: function () {
|
||||
if (this.sliding) return
|
||||
return this.slide('prev')
|
||||
}
|
||||
|
||||
, slide: function (type, next) {
|
||||
var $active = this.$element.find('.active')
|
||||
, $next = next || $active[type]()
|
||||
, isCycling = this.interval
|
||||
, direction = type == 'next' ? 'left' : 'right'
|
||||
, fallback = type == 'next' ? 'first' : 'last'
|
||||
, that = this
|
||||
|
||||
this.sliding = true
|
||||
|
||||
isCycling && this.pause()
|
||||
|
||||
$next = $next.length ? $next : this.$element.find('.item')[fallback]()
|
||||
|
||||
if (!$.support.transition && this.$element.hasClass('slide')) {
|
||||
this.$element.trigger('slide')
|
||||
$active.removeClass('active')
|
||||
$next.addClass('active')
|
||||
this.sliding = false
|
||||
this.$element.trigger('slid')
|
||||
} else {
|
||||
$next.addClass(type)
|
||||
$next[0].offsetWidth // force reflow
|
||||
$active.addClass(direction)
|
||||
$next.addClass(direction)
|
||||
this.$element.trigger('slide')
|
||||
this.$element.one($.support.transition.end, function () {
|
||||
$next.removeClass([type, direction].join(' ')).addClass('active')
|
||||
$active.removeClass(['active', direction].join(' '))
|
||||
that.sliding = false
|
||||
setTimeout(function () { that.$element.trigger('slid') }, 0)
|
||||
})
|
||||
}
|
||||
|
||||
isCycling && this.cycle()
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* CAROUSEL PLUGIN DEFINITION
|
||||
* ========================== */
|
||||
|
||||
$.fn.carousel = function ( option ) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
, data = $this.data('carousel')
|
||||
, options = typeof option == 'object' && option
|
||||
if (!data) $this.data('carousel', (data = new Carousel(this, options)))
|
||||
if (typeof option == 'number') data.to(option)
|
||||
else if (typeof option == 'string' || (option = options.slide)) data[option]()
|
||||
else data.cycle()
|
||||
})
|
||||
}
|
||||
|
||||
$.fn.carousel.defaults = {
|
||||
interval: 5000
|
||||
}
|
||||
|
||||
$.fn.carousel.Constructor = Carousel
|
||||
|
||||
|
||||
/* CAROUSEL DATA-API
|
||||
* ================= */
|
||||
|
||||
$(function () {
|
||||
$('body').on('click.carousel.data-api', '[data-slide]', function ( e ) {
|
||||
var $this = $(this), href
|
||||
, $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
|
||||
, options = !$target.data('modal') && $.extend({}, $target.data(), $this.data())
|
||||
$target.carousel(options)
|
||||
e.preventDefault()
|
||||
})
|
||||
})
|
||||
|
||||
}( window.jQuery )
|
||||
136
themes/default/js/libs/bootstrap/collapse.js
Normal file
@ -0,0 +1,136 @@
|
||||
/* =============================================================
|
||||
* bootstrap-collapse.js v2.0.0
|
||||
* http://twitter.github.com/bootstrap/javascript.html#collapse
|
||||
* =============================================================
|
||||
* Copyright 2012 Twitter, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ============================================================ */
|
||||
|
||||
!function( $ ){
|
||||
|
||||
"use strict"
|
||||
|
||||
var Collapse = function ( element, options ) {
|
||||
this.$element = $(element)
|
||||
this.options = $.extend({}, $.fn.collapse.defaults, options)
|
||||
|
||||
if (this.options["parent"]) {
|
||||
this.$parent = $(this.options["parent"])
|
||||
}
|
||||
|
||||
this.options.toggle && this.toggle()
|
||||
}
|
||||
|
||||
Collapse.prototype = {
|
||||
|
||||
constructor: Collapse
|
||||
|
||||
, dimension: function () {
|
||||
var hasWidth = this.$element.hasClass('width')
|
||||
return hasWidth ? 'width' : 'height'
|
||||
}
|
||||
|
||||
, show: function () {
|
||||
var dimension = this.dimension()
|
||||
, scroll = $.camelCase(['scroll', dimension].join('-'))
|
||||
, actives = this.$parent && this.$parent.find('.in')
|
||||
, hasData
|
||||
|
||||
if (actives && actives.length) {
|
||||
hasData = actives.data('collapse')
|
||||
actives.collapse('hide')
|
||||
hasData || actives.data('collapse', null)
|
||||
}
|
||||
|
||||
this.$element[dimension](0)
|
||||
this.transition('addClass', 'show', 'shown')
|
||||
this.$element[dimension](this.$element[0][scroll])
|
||||
|
||||
}
|
||||
|
||||
, hide: function () {
|
||||
var dimension = this.dimension()
|
||||
this.reset(this.$element[dimension]())
|
||||
this.transition('removeClass', 'hide', 'hidden')
|
||||
this.$element[dimension](0)
|
||||
}
|
||||
|
||||
, reset: function ( size ) {
|
||||
var dimension = this.dimension()
|
||||
|
||||
this.$element
|
||||
.removeClass('collapse')
|
||||
[dimension](size || 'auto')
|
||||
[0].offsetWidth
|
||||
|
||||
this.$element.addClass('collapse')
|
||||
}
|
||||
|
||||
, transition: function ( method, startEvent, completeEvent ) {
|
||||
var that = this
|
||||
, complete = function () {
|
||||
if (startEvent == 'show') that.reset()
|
||||
that.$element.trigger(completeEvent)
|
||||
}
|
||||
|
||||
this.$element
|
||||
.trigger(startEvent)
|
||||
[method]('in')
|
||||
|
||||
$.support.transition && this.$element.hasClass('collapse') ?
|
||||
this.$element.one($.support.transition.end, complete) :
|
||||
complete()
|
||||
}
|
||||
|
||||
, toggle: function () {
|
||||
this[this.$element.hasClass('in') ? 'hide' : 'show']()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* COLLAPSIBLE PLUGIN DEFINITION
|
||||
* ============================== */
|
||||
|
||||
$.fn.collapse = function ( option ) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
, data = $this.data('collapse')
|
||||
, options = typeof option == 'object' && option
|
||||
if (!data) $this.data('collapse', (data = new Collapse(this, options)))
|
||||
if (typeof option == 'string') data[option]()
|
||||
})
|
||||
}
|
||||
|
||||
$.fn.collapse.defaults = {
|
||||
toggle: true
|
||||
}
|
||||
|
||||
$.fn.collapse.Constructor = Collapse
|
||||
|
||||
|
||||
/* COLLAPSIBLE DATA-API
|
||||
* ==================== */
|
||||
|
||||
$(function () {
|
||||
$('body').on('click.collapse.data-api', '[data-toggle=collapse]', function ( e ) {
|
||||
var $this = $(this), href
|
||||
, target = $this.attr('data-target')
|
||||
|| e.preventDefault()
|
||||
|| (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
|
||||
, option = $(target).data('collapse') ? 'toggle' : $this.data()
|
||||
$(target).collapse(option)
|
||||
})
|
||||
})
|
||||
|
||||
}( window.jQuery )
|
||||
92
themes/default/js/libs/bootstrap/dropdown.js
Normal file
@ -0,0 +1,92 @@
|
||||
/* ============================================================
|
||||
* bootstrap-dropdown.js v2.0.0
|
||||
* http://twitter.github.com/bootstrap/javascript.html#dropdowns
|
||||
* ============================================================
|
||||
* Copyright 2012 Twitter, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ============================================================ */
|
||||
|
||||
|
||||
!function( $ ){
|
||||
|
||||
"use strict"
|
||||
|
||||
/* DROPDOWN CLASS DEFINITION
|
||||
* ========================= */
|
||||
|
||||
var toggle = '[data-toggle="dropdown"]'
|
||||
, Dropdown = function ( element ) {
|
||||
var $el = $(element).on('click.dropdown.data-api', this.toggle)
|
||||
$('html').on('click.dropdown.data-api', function () {
|
||||
$el.parent().removeClass('open')
|
||||
})
|
||||
}
|
||||
|
||||
Dropdown.prototype = {
|
||||
|
||||
constructor: Dropdown
|
||||
|
||||
, toggle: function ( e ) {
|
||||
var $this = $(this)
|
||||
, selector = $this.attr('data-target')
|
||||
, $parent
|
||||
, isActive
|
||||
|
||||
if (!selector) {
|
||||
selector = $this.attr('href')
|
||||
selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
|
||||
}
|
||||
|
||||
$parent = $(selector)
|
||||
$parent.length || ($parent = $this.parent())
|
||||
|
||||
isActive = $parent.hasClass('open')
|
||||
|
||||
clearMenus()
|
||||
!isActive && $parent.toggleClass('open')
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function clearMenus() {
|
||||
$(toggle).parent().removeClass('open')
|
||||
}
|
||||
|
||||
|
||||
/* DROPDOWN PLUGIN DEFINITION
|
||||
* ========================== */
|
||||
|
||||
$.fn.dropdown = function ( option ) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
, data = $this.data('dropdown')
|
||||
if (!data) $this.data('dropdown', (data = new Dropdown(this)))
|
||||
if (typeof option == 'string') data[option].call($this)
|
||||
})
|
||||
}
|
||||
|
||||
$.fn.dropdown.Constructor = Dropdown
|
||||
|
||||
|
||||
/* APPLY TO STANDARD DROPDOWN ELEMENTS
|
||||
* =================================== */
|
||||
|
||||
$(function () {
|
||||
$('html').on('click.dropdown.data-api', clearMenus)
|
||||
$('body').on('click.dropdown.data-api', toggle, Dropdown.prototype.toggle)
|
||||
})
|
||||
|
||||
}( window.jQuery )
|
||||
209
themes/default/js/libs/bootstrap/modal.js
Normal file
@ -0,0 +1,209 @@
|
||||
/* =========================================================
|
||||
* bootstrap-modal.js v2.0.0
|
||||
* http://twitter.github.com/bootstrap/javascript.html#modals
|
||||
* =========================================================
|
||||
* Copyright 2012 Twitter, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ========================================================= */
|
||||
|
||||
|
||||
!function( $ ){
|
||||
|
||||
"use strict"
|
||||
|
||||
/* MODAL CLASS DEFINITION
|
||||
* ====================== */
|
||||
|
||||
var Modal = function ( content, options ) {
|
||||
this.options = $.extend({}, $.fn.modal.defaults, options)
|
||||
this.$element = $(content)
|
||||
.delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this))
|
||||
}
|
||||
|
||||
Modal.prototype = {
|
||||
|
||||
constructor: Modal
|
||||
|
||||
, toggle: function () {
|
||||
return this[!this.isShown ? 'show' : 'hide']()
|
||||
}
|
||||
|
||||
, show: function () {
|
||||
var that = this
|
||||
|
||||
if (this.isShown) return
|
||||
|
||||
$('body').addClass('modal-open')
|
||||
|
||||
this.isShown = true
|
||||
this.$element.trigger('show')
|
||||
|
||||
escape.call(this)
|
||||
backdrop.call(this, function () {
|
||||
var transition = $.support.transition && that.$element.hasClass('fade')
|
||||
|
||||
!that.$element.parent().length && that.$element.appendTo(document.body) //don't move modals dom position
|
||||
|
||||
that.$element
|
||||
.show()
|
||||
|
||||
if (transition) {
|
||||
that.$element[0].offsetWidth // force reflow
|
||||
}
|
||||
|
||||
that.$element.addClass('in')
|
||||
|
||||
transition ?
|
||||
that.$element.one($.support.transition.end, function () { that.$element.trigger('shown') }) :
|
||||
that.$element.trigger('shown')
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
, hide: function ( e ) {
|
||||
e && e.preventDefault()
|
||||
|
||||
if (!this.isShown) return
|
||||
|
||||
var that = this
|
||||
this.isShown = false
|
||||
|
||||
$('body').removeClass('modal-open')
|
||||
|
||||
escape.call(this)
|
||||
|
||||
this.$element
|
||||
.trigger('hide')
|
||||
.removeClass('in')
|
||||
|
||||
$.support.transition && this.$element.hasClass('fade') ?
|
||||
hideWithTransition.call(this) :
|
||||
hideModal.call(this)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* MODAL PRIVATE METHODS
|
||||
* ===================== */
|
||||
|
||||
function hideWithTransition() {
|
||||
var that = this
|
||||
, timeout = setTimeout(function () {
|
||||
that.$element.off($.support.transition.end)
|
||||
hideModal.call(that)
|
||||
}, 500)
|
||||
|
||||
this.$element.one($.support.transition.end, function () {
|
||||
clearTimeout(timeout)
|
||||
hideModal.call(that)
|
||||
})
|
||||
}
|
||||
|
||||
function hideModal( that ) {
|
||||
this.$element
|
||||
.hide()
|
||||
.trigger('hidden')
|
||||
|
||||
backdrop.call(this)
|
||||
}
|
||||
|
||||
function backdrop( callback ) {
|
||||
var that = this
|
||||
, animate = this.$element.hasClass('fade') ? 'fade' : ''
|
||||
|
||||
if (this.isShown && this.options.backdrop) {
|
||||
var doAnimate = $.support.transition && animate
|
||||
|
||||
this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
|
||||
.appendTo(document.body)
|
||||
|
||||
if (this.options.backdrop != 'static') {
|
||||
this.$backdrop.click($.proxy(this.hide, this))
|
||||
}
|
||||
|
||||
if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
|
||||
|
||||
this.$backdrop.addClass('in')
|
||||
|
||||
doAnimate ?
|
||||
this.$backdrop.one($.support.transition.end, callback) :
|
||||
callback()
|
||||
|
||||
} else if (!this.isShown && this.$backdrop) {
|
||||
this.$backdrop.removeClass('in')
|
||||
|
||||
$.support.transition && this.$element.hasClass('fade')?
|
||||
this.$backdrop.one($.support.transition.end, $.proxy(removeBackdrop, this)) :
|
||||
removeBackdrop.call(this)
|
||||
|
||||
} else if (callback) {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
function removeBackdrop() {
|
||||
this.$backdrop.remove()
|
||||
this.$backdrop = null
|
||||
}
|
||||
|
||||
function escape() {
|
||||
var that = this
|
||||
if (this.isShown && this.options.keyboard) {
|
||||
$(document).on('keyup.dismiss.modal', function ( e ) {
|
||||
e.which == 27 && that.hide()
|
||||
})
|
||||
} else if (!this.isShown) {
|
||||
$(document).off('keyup.dismiss.modal')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* MODAL PLUGIN DEFINITION
|
||||
* ======================= */
|
||||
|
||||
$.fn.modal = function ( option ) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
, data = $this.data('modal')
|
||||
, options = typeof option == 'object' && option
|
||||
if (!data) $this.data('modal', (data = new Modal(this, options)))
|
||||
if (typeof option == 'string') data[option]()
|
||||
else data.show()
|
||||
})
|
||||
}
|
||||
|
||||
$.fn.modal.defaults = {
|
||||
backdrop: true
|
||||
, keyboard: true
|
||||
}
|
||||
|
||||
$.fn.modal.Constructor = Modal
|
||||
|
||||
|
||||
/* MODAL DATA-API
|
||||
* ============== */
|
||||
|
||||
$(function () {
|
||||
$('body').on('click.modal.data-api', '[data-toggle="modal"]', function ( e ) {
|
||||
var $this = $(this), href
|
||||
, $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
|
||||
, option = $target.data('modal') ? 'toggle' : $.extend({}, $target.data(), $this.data())
|
||||
|
||||
e.preventDefault()
|
||||
$target.modal(option)
|
||||
})
|
||||
})
|
||||
|
||||
}( window.jQuery )
|
||||
95
themes/default/js/libs/bootstrap/popover.js
Normal file
@ -0,0 +1,95 @@
|
||||
/* ===========================================================
|
||||
* bootstrap-popover.js v2.0.0
|
||||
* http://twitter.github.com/bootstrap/javascript.html#popovers
|
||||
* ===========================================================
|
||||
* Copyright 2012 Twitter, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* =========================================================== */
|
||||
|
||||
|
||||
!function( $ ) {
|
||||
|
||||
"use strict"
|
||||
|
||||
var Popover = function ( element, options ) {
|
||||
this.init('popover', element, options)
|
||||
}
|
||||
|
||||
/* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js
|
||||
========================================== */
|
||||
|
||||
Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, {
|
||||
|
||||
constructor: Popover
|
||||
|
||||
, setContent: function () {
|
||||
var $tip = this.tip()
|
||||
, title = this.getTitle()
|
||||
, content = this.getContent()
|
||||
|
||||
$tip.find('.popover-title')[ $.type(title) == 'object' ? 'append' : 'html' ](title)
|
||||
$tip.find('.popover-content > *')[ $.type(content) == 'object' ? 'append' : 'html' ](content)
|
||||
|
||||
$tip.removeClass('fade top bottom left right in')
|
||||
}
|
||||
|
||||
, hasContent: function () {
|
||||
return this.getTitle() || this.getContent()
|
||||
}
|
||||
|
||||
, getContent: function () {
|
||||
var content
|
||||
, $e = this.$element
|
||||
, o = this.options
|
||||
|
||||
content = $e.attr('data-content')
|
||||
|| (typeof o.content == 'function' ? o.content.call($e[0]) : o.content)
|
||||
|
||||
content = content.toString().replace(/(^\s*|\s*$)/, "")
|
||||
|
||||
return content
|
||||
}
|
||||
|
||||
, tip: function() {
|
||||
if (!this.$tip) {
|
||||
this.$tip = $(this.options.template)
|
||||
}
|
||||
return this.$tip
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
|
||||
/* POPOVER PLUGIN DEFINITION
|
||||
* ======================= */
|
||||
|
||||
$.fn.popover = function ( option ) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
, data = $this.data('popover')
|
||||
, options = typeof option == 'object' && option
|
||||
if (!data) $this.data('popover', (data = new Popover(this, options)))
|
||||
if (typeof option == 'string') data[option]()
|
||||
})
|
||||
}
|
||||
|
||||
$.fn.popover.Constructor = Popover
|
||||
|
||||
$.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, {
|
||||
placement: 'right'
|
||||
, content: ''
|
||||
, template: '<div class="popover"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>'
|
||||
})
|
||||
|
||||
}( window.jQuery )
|
||||
125
themes/default/js/libs/bootstrap/scrollspy.js
Normal file
@ -0,0 +1,125 @@
|
||||
/* =============================================================
|
||||
* bootstrap-scrollspy.js v2.0.0
|
||||
* http://twitter.github.com/bootstrap/javascript.html#scrollspy
|
||||
* =============================================================
|
||||
* Copyright 2012 Twitter, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ============================================================== */
|
||||
|
||||
!function ( $ ) {
|
||||
|
||||
"use strict"
|
||||
|
||||
/* SCROLLSPY CLASS DEFINITION
|
||||
* ========================== */
|
||||
|
||||
function ScrollSpy( element, options) {
|
||||
var process = $.proxy(this.process, this)
|
||||
, $element = $(element).is('body') ? $(window) : $(element)
|
||||
, href
|
||||
this.options = $.extend({}, $.fn.scrollspy.defaults, options)
|
||||
this.$scrollElement = $element.on('scroll.scroll.data-api', process)
|
||||
this.selector = (this.options.target
|
||||
|| ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
|
||||
|| '') + ' .nav li > a'
|
||||
this.$body = $('body').on('click.scroll.data-api', this.selector, process)
|
||||
this.refresh()
|
||||
this.process()
|
||||
}
|
||||
|
||||
ScrollSpy.prototype = {
|
||||
|
||||
constructor: ScrollSpy
|
||||
|
||||
, refresh: function () {
|
||||
this.targets = this.$body
|
||||
.find(this.selector)
|
||||
.map(function () {
|
||||
var href = $(this).attr('href')
|
||||
return /^#\w/.test(href) && $(href).length ? href : null
|
||||
})
|
||||
|
||||
this.offsets = $.map(this.targets, function (id) {
|
||||
return $(id).position().top
|
||||
})
|
||||
}
|
||||
|
||||
, process: function () {
|
||||
var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
|
||||
, offsets = this.offsets
|
||||
, targets = this.targets
|
||||
, activeTarget = this.activeTarget
|
||||
, i
|
||||
|
||||
for (i = offsets.length; i--;) {
|
||||
activeTarget != targets[i]
|
||||
&& scrollTop >= offsets[i]
|
||||
&& (!offsets[i + 1] || scrollTop <= offsets[i + 1])
|
||||
&& this.activate( targets[i] )
|
||||
}
|
||||
}
|
||||
|
||||
, activate: function (target) {
|
||||
var active
|
||||
|
||||
this.activeTarget = target
|
||||
|
||||
this.$body
|
||||
.find(this.selector).parent('.active')
|
||||
.removeClass('active')
|
||||
|
||||
active = this.$body
|
||||
.find(this.selector + '[href="' + target + '"]')
|
||||
.parent('li')
|
||||
.addClass('active')
|
||||
|
||||
if ( active.parent('.dropdown-menu') ) {
|
||||
active.closest('li.dropdown').addClass('active')
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* SCROLLSPY PLUGIN DEFINITION
|
||||
* =========================== */
|
||||
|
||||
$.fn.scrollspy = function ( option ) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
, data = $this.data('scrollspy')
|
||||
, options = typeof option == 'object' && option
|
||||
if (!data) $this.data('scrollspy', (data = new ScrollSpy(this, options)))
|
||||
if (typeof option == 'string') data[option]()
|
||||
})
|
||||
}
|
||||
|
||||
$.fn.scrollspy.Constructor = ScrollSpy
|
||||
|
||||
$.fn.scrollspy.defaults = {
|
||||
offset: 10
|
||||
}
|
||||
|
||||
|
||||
/* SCROLLSPY DATA-API
|
||||
* ================== */
|
||||
|
||||
$(function () {
|
||||
$('[data-spy="scroll"]').each(function () {
|
||||
var $spy = $(this)
|
||||
$spy.scrollspy($spy.data())
|
||||
})
|
||||
})
|
||||
|
||||
}( window.jQuery )
|
||||
130
themes/default/js/libs/bootstrap/tab.js
Normal file
@ -0,0 +1,130 @@
|
||||
/* ========================================================
|
||||
* bootstrap-tab.js v2.0.0
|
||||
* http://twitter.github.com/bootstrap/javascript.html#tabs
|
||||
* ========================================================
|
||||
* Copyright 2012 Twitter, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ======================================================== */
|
||||
|
||||
|
||||
!function( $ ){
|
||||
|
||||
"use strict"
|
||||
|
||||
/* TAB CLASS DEFINITION
|
||||
* ==================== */
|
||||
|
||||
var Tab = function ( element ) {
|
||||
this.element = $(element)
|
||||
}
|
||||
|
||||
Tab.prototype = {
|
||||
|
||||
constructor: Tab
|
||||
|
||||
, show: function () {
|
||||
var $this = this.element
|
||||
, $ul = $this.closest('ul:not(.dropdown-menu)')
|
||||
, selector = $this.attr('data-target')
|
||||
, previous
|
||||
, $target
|
||||
|
||||
if (!selector) {
|
||||
selector = $this.attr('href')
|
||||
selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
|
||||
}
|
||||
|
||||
if ( $this.parent('li').hasClass('active') ) return
|
||||
|
||||
previous = $ul.find('.active a').last()[0]
|
||||
|
||||
$this.trigger({
|
||||
type: 'show'
|
||||
, relatedTarget: previous
|
||||
})
|
||||
|
||||
$target = $(selector)
|
||||
|
||||
this.activate($this.parent('li'), $ul)
|
||||
this.activate($target, $target.parent(), function () {
|
||||
$this.trigger({
|
||||
type: 'shown'
|
||||
, relatedTarget: previous
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
, activate: function ( element, container, callback) {
|
||||
var $active = container.find('> .active')
|
||||
, transition = callback
|
||||
&& $.support.transition
|
||||
&& $active.hasClass('fade')
|
||||
|
||||
function next() {
|
||||
$active
|
||||
.removeClass('active')
|
||||
.find('> .dropdown-menu > .active')
|
||||
.removeClass('active')
|
||||
|
||||
element.addClass('active')
|
||||
|
||||
if (transition) {
|
||||
element[0].offsetWidth // reflow for transition
|
||||
element.addClass('in')
|
||||
} else {
|
||||
element.removeClass('fade')
|
||||
}
|
||||
|
||||
if ( element.parent('.dropdown-menu') ) {
|
||||
element.closest('li.dropdown').addClass('active')
|
||||
}
|
||||
|
||||
callback && callback()
|
||||
}
|
||||
|
||||
transition ?
|
||||
$active.one($.support.transition.end, next) :
|
||||
next()
|
||||
|
||||
$active.removeClass('in')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* TAB PLUGIN DEFINITION
|
||||
* ===================== */
|
||||
|
||||
$.fn.tab = function ( option ) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
, data = $this.data('tab')
|
||||
if (!data) $this.data('tab', (data = new Tab(this)))
|
||||
if (typeof option == 'string') data[option]()
|
||||
})
|
||||
}
|
||||
|
||||
$.fn.tab.Constructor = Tab
|
||||
|
||||
|
||||
/* TAB DATA-API
|
||||
* ============ */
|
||||
|
||||
$(function () {
|
||||
$('body').on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
|
||||
e.preventDefault()
|
||||
$(this).tab('show')
|
||||
})
|
||||
})
|
||||
|
||||
}( window.jQuery )
|
||||
270
themes/default/js/libs/bootstrap/tooltip.js
Normal file
@ -0,0 +1,270 @@
|
||||
/* ===========================================================
|
||||
* bootstrap-tooltip.js v2.0.0
|
||||
* http://twitter.github.com/bootstrap/javascript.html#tooltips
|
||||
* Inspired by the original jQuery.tipsy by Jason Frame
|
||||
* ===========================================================
|
||||
* Copyright 2012 Twitter, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ========================================================== */
|
||||
|
||||
!function( $ ) {
|
||||
|
||||
"use strict"
|
||||
|
||||
/* TOOLTIP PUBLIC CLASS DEFINITION
|
||||
* =============================== */
|
||||
|
||||
var Tooltip = function ( element, options ) {
|
||||
this.init('tooltip', element, options)
|
||||
}
|
||||
|
||||
Tooltip.prototype = {
|
||||
|
||||
constructor: Tooltip
|
||||
|
||||
, init: function ( type, element, options ) {
|
||||
var eventIn
|
||||
, eventOut
|
||||
|
||||
this.type = type
|
||||
this.$element = $(element)
|
||||
this.options = this.getOptions(options)
|
||||
this.enabled = true
|
||||
|
||||
if (this.options.trigger != 'manual') {
|
||||
eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus'
|
||||
eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur'
|
||||
this.$element.on(eventIn, this.options.selector, $.proxy(this.enter, this))
|
||||
this.$element.on(eventOut, this.options.selector, $.proxy(this.leave, this))
|
||||
}
|
||||
|
||||
this.options.selector ?
|
||||
(this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
|
||||
this.fixTitle()
|
||||
}
|
||||
|
||||
, getOptions: function ( options ) {
|
||||
options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data())
|
||||
|
||||
if (options.delay && typeof options.delay == 'number') {
|
||||
options.delay = {
|
||||
show: options.delay
|
||||
, hide: options.delay
|
||||
}
|
||||
}
|
||||
|
||||
return options
|
||||
}
|
||||
|
||||
, enter: function ( e ) {
|
||||
var self = $(e.currentTarget)[this.type](this._options).data(this.type)
|
||||
|
||||
if (!self.options.delay || !self.options.delay.show) {
|
||||
self.show()
|
||||
} else {
|
||||
self.hoverState = 'in'
|
||||
setTimeout(function() {
|
||||
if (self.hoverState == 'in') {
|
||||
self.show()
|
||||
}
|
||||
}, self.options.delay.show)
|
||||
}
|
||||
}
|
||||
|
||||
, leave: function ( e ) {
|
||||
var self = $(e.currentTarget)[this.type](this._options).data(this.type)
|
||||
|
||||
if (!self.options.delay || !self.options.delay.hide) {
|
||||
self.hide()
|
||||
} else {
|
||||
self.hoverState = 'out'
|
||||
setTimeout(function() {
|
||||
if (self.hoverState == 'out') {
|
||||
self.hide()
|
||||
}
|
||||
}, self.options.delay.hide)
|
||||
}
|
||||
}
|
||||
|
||||
, show: function () {
|
||||
var $tip
|
||||
, inside
|
||||
, pos
|
||||
, actualWidth
|
||||
, actualHeight
|
||||
, placement
|
||||
, tp
|
||||
|
||||
if (this.hasContent() && this.enabled) {
|
||||
$tip = this.tip()
|
||||
this.setContent()
|
||||
|
||||
if (this.options.animation) {
|
||||
$tip.addClass('fade')
|
||||
}
|
||||
|
||||
placement = typeof this.options.placement == 'function' ?
|
||||
this.options.placement.call(this, $tip[0], this.$element[0]) :
|
||||
this.options.placement
|
||||
|
||||
inside = /in/.test(placement)
|
||||
|
||||
$tip
|
||||
.remove()
|
||||
.css({ top: 0, left: 0, display: 'block' })
|
||||
.appendTo(inside ? this.$element : document.body)
|
||||
|
||||
pos = this.getPosition(inside)
|
||||
|
||||
actualWidth = $tip[0].offsetWidth
|
||||
actualHeight = $tip[0].offsetHeight
|
||||
|
||||
switch (inside ? placement.split(' ')[1] : placement) {
|
||||
case 'bottom':
|
||||
tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
|
||||
break
|
||||
case 'top':
|
||||
tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
|
||||
break
|
||||
case 'left':
|
||||
tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
|
||||
break
|
||||
case 'right':
|
||||
tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
|
||||
break
|
||||
}
|
||||
|
||||
$tip
|
||||
.css(tp)
|
||||
.addClass(placement)
|
||||
.addClass('in')
|
||||
}
|
||||
}
|
||||
|
||||
, setContent: function () {
|
||||
var $tip = this.tip()
|
||||
$tip.find('.tooltip-inner').html(this.getTitle())
|
||||
$tip.removeClass('fade in top bottom left right')
|
||||
}
|
||||
|
||||
, hide: function () {
|
||||
var that = this
|
||||
, $tip = this.tip()
|
||||
|
||||
$tip.removeClass('in')
|
||||
|
||||
function removeWithAnimation() {
|
||||
var timeout = setTimeout(function () {
|
||||
$tip.off($.support.transition.end).remove()
|
||||
}, 500)
|
||||
|
||||
$tip.one($.support.transition.end, function () {
|
||||
clearTimeout(timeout)
|
||||
$tip.remove()
|
||||
})
|
||||
}
|
||||
|
||||
$.support.transition && this.$tip.hasClass('fade') ?
|
||||
removeWithAnimation() :
|
||||
$tip.remove()
|
||||
}
|
||||
|
||||
, fixTitle: function () {
|
||||
var $e = this.$element
|
||||
if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
|
||||
$e.attr('data-original-title', $e.attr('title') || '').removeAttr('title')
|
||||
}
|
||||
}
|
||||
|
||||
, hasContent: function () {
|
||||
return this.getTitle()
|
||||
}
|
||||
|
||||
, getPosition: function (inside) {
|
||||
return $.extend({}, (inside ? {top: 0, left: 0} : this.$element.offset()), {
|
||||
width: this.$element[0].offsetWidth
|
||||
, height: this.$element[0].offsetHeight
|
||||
})
|
||||
}
|
||||
|
||||
, getTitle: function () {
|
||||
var title
|
||||
, $e = this.$element
|
||||
, o = this.options
|
||||
|
||||
title = $e.attr('data-original-title')
|
||||
|| (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
|
||||
|
||||
title = title.toString().replace(/(^\s*|\s*$)/, "")
|
||||
|
||||
return title
|
||||
}
|
||||
|
||||
, tip: function () {
|
||||
return this.$tip = this.$tip || $(this.options.template)
|
||||
}
|
||||
|
||||
, validate: function () {
|
||||
if (!this.$element[0].parentNode) {
|
||||
this.hide()
|
||||
this.$element = null
|
||||
this.options = null
|
||||
}
|
||||
}
|
||||
|
||||
, enable: function () {
|
||||
this.enabled = true
|
||||
}
|
||||
|
||||
, disable: function () {
|
||||
this.enabled = false
|
||||
}
|
||||
|
||||
, toggleEnabled: function () {
|
||||
this.enabled = !this.enabled
|
||||
}
|
||||
|
||||
, toggle: function () {
|
||||
this[this.tip().hasClass('in') ? 'hide' : 'show']()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* TOOLTIP PLUGIN DEFINITION
|
||||
* ========================= */
|
||||
|
||||
$.fn.tooltip = function ( option ) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
, data = $this.data('tooltip')
|
||||
, options = typeof option == 'object' && option
|
||||
if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))
|
||||
if (typeof option == 'string') data[option]()
|
||||
})
|
||||
}
|
||||
|
||||
$.fn.tooltip.Constructor = Tooltip
|
||||
|
||||
$.fn.tooltip.defaults = {
|
||||
animation: true
|
||||
, delay: 0
|
||||
, selector: false
|
||||
, placement: 'top'
|
||||
, trigger: 'hover'
|
||||
, title: ''
|
||||
, template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
|
||||
}
|
||||
|
||||
}( window.jQuery )
|
||||
51
themes/default/js/libs/bootstrap/transition.js
Normal file
@ -0,0 +1,51 @@
|
||||
/* ===================================================
|
||||
* bootstrap-transition.js v2.0.0
|
||||
* http://twitter.github.com/bootstrap/javascript.html#transitions
|
||||
* ===================================================
|
||||
* Copyright 2012 Twitter, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ========================================================== */
|
||||
|
||||
!function( $ ) {
|
||||
|
||||
$(function () {
|
||||
|
||||
"use strict"
|
||||
|
||||
/* CSS TRANSITION SUPPORT (https://gist.github.com/373874)
|
||||
* ======================================================= */
|
||||
|
||||
$.support.transition = (function () {
|
||||
var thisBody = document.body || document.documentElement
|
||||
, thisStyle = thisBody.style
|
||||
, support = thisStyle.transition !== undefined || thisStyle.WebkitTransition !== undefined || thisStyle.MozTransition !== undefined || thisStyle.MsTransition !== undefined || thisStyle.OTransition !== undefined
|
||||
|
||||
return support && {
|
||||
end: (function () {
|
||||
var transitionEnd = "TransitionEnd"
|
||||
if ( $.browser.webkit ) {
|
||||
transitionEnd = "webkitTransitionEnd"
|
||||
} else if ( $.browser.mozilla ) {
|
||||
transitionEnd = "transitionend"
|
||||
} else if ( $.browser.opera ) {
|
||||
transitionEnd = "oTransitionEnd"
|
||||
}
|
||||
return transitionEnd
|
||||
}())
|
||||
}
|
||||
})()
|
||||
|
||||
})
|
||||
|
||||
}( window.jQuery )
|
||||
271
themes/default/js/libs/bootstrap/typeahead.js
Normal file
@ -0,0 +1,271 @@
|
||||
/* =============================================================
|
||||
* bootstrap-typeahead.js v2.0.0
|
||||
* http://twitter.github.com/bootstrap/javascript.html#typeahead
|
||||
* =============================================================
|
||||
* Copyright 2012 Twitter, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ============================================================ */
|
||||
|
||||
!function( $ ){
|
||||
|
||||
"use strict"
|
||||
|
||||
var Typeahead = function ( element, options ) {
|
||||
this.$element = $(element)
|
||||
this.options = $.extend({}, $.fn.typeahead.defaults, options)
|
||||
this.matcher = this.options.matcher || this.matcher
|
||||
this.sorter = this.options.sorter || this.sorter
|
||||
this.highlighter = this.options.highlighter || this.highlighter
|
||||
this.$menu = $(this.options.menu).appendTo('body')
|
||||
this.source = this.options.source
|
||||
this.shown = false
|
||||
this.listen()
|
||||
}
|
||||
|
||||
Typeahead.prototype = {
|
||||
|
||||
constructor: Typeahead
|
||||
|
||||
, select: function () {
|
||||
var val = this.$menu.find('.active').attr('data-value')
|
||||
this.$element.val(val)
|
||||
return this.hide()
|
||||
}
|
||||
|
||||
, show: function () {
|
||||
var pos = $.extend({}, this.$element.offset(), {
|
||||
height: this.$element[0].offsetHeight
|
||||
})
|
||||
|
||||
this.$menu.css({
|
||||
top: pos.top + pos.height
|
||||
, left: pos.left
|
||||
})
|
||||
|
||||
this.$menu.show()
|
||||
this.shown = true
|
||||
return this
|
||||
}
|
||||
|
||||
, hide: function () {
|
||||
this.$menu.hide()
|
||||
this.shown = false
|
||||
return this
|
||||
}
|
||||
|
||||
, lookup: function (event) {
|
||||
var that = this
|
||||
, items
|
||||
, q
|
||||
|
||||
this.query = this.$element.val()
|
||||
|
||||
if (!this.query) {
|
||||
return this.shown ? this.hide() : this
|
||||
}
|
||||
|
||||
items = $.grep(this.source, function (item) {
|
||||
if (that.matcher(item)) return item
|
||||
})
|
||||
|
||||
items = this.sorter(items)
|
||||
|
||||
if (!items.length) {
|
||||
return this.shown ? this.hide() : this
|
||||
}
|
||||
|
||||
return this.render(items.slice(0, this.options.items)).show()
|
||||
}
|
||||
|
||||
, matcher: function (item) {
|
||||
return ~item.toLowerCase().indexOf(this.query.toLowerCase())
|
||||
}
|
||||
|
||||
, sorter: function (items) {
|
||||
var beginswith = []
|
||||
, caseSensitive = []
|
||||
, caseInsensitive = []
|
||||
, item
|
||||
|
||||
while (item = items.shift()) {
|
||||
if (!item.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item)
|
||||
else if (~item.indexOf(this.query)) caseSensitive.push(item)
|
||||
else caseInsensitive.push(item)
|
||||
}
|
||||
|
||||
return beginswith.concat(caseSensitive, caseInsensitive)
|
||||
}
|
||||
|
||||
, highlighter: function (item) {
|
||||
return item.replace(new RegExp('(' + this.query + ')', 'ig'), function ($1, match) {
|
||||
return '<strong>' + match + '</strong>'
|
||||
})
|
||||
}
|
||||
|
||||
, render: function (items) {
|
||||
var that = this
|
||||
|
||||
items = $(items).map(function (i, item) {
|
||||
i = $(that.options.item).attr('data-value', item)
|
||||
i.find('a').html(that.highlighter(item))
|
||||
return i[0]
|
||||
})
|
||||
|
||||
items.first().addClass('active')
|
||||
this.$menu.html(items)
|
||||
return this
|
||||
}
|
||||
|
||||
, next: function (event) {
|
||||
var active = this.$menu.find('.active').removeClass('active')
|
||||
, next = active.next()
|
||||
|
||||
if (!next.length) {
|
||||
next = $(this.$menu.find('li')[0])
|
||||
}
|
||||
|
||||
next.addClass('active')
|
||||
}
|
||||
|
||||
, prev: function (event) {
|
||||
var active = this.$menu.find('.active').removeClass('active')
|
||||
, prev = active.prev()
|
||||
|
||||
if (!prev.length) {
|
||||
prev = this.$menu.find('li').last()
|
||||
}
|
||||
|
||||
prev.addClass('active')
|
||||
}
|
||||
|
||||
, listen: function () {
|
||||
this.$element
|
||||
.on('blur', $.proxy(this.blur, this))
|
||||
.on('keypress', $.proxy(this.keypress, this))
|
||||
.on('keyup', $.proxy(this.keyup, this))
|
||||
|
||||
if ($.browser.webkit || $.browser.msie) {
|
||||
this.$element.on('keydown', $.proxy(this.keypress, this))
|
||||
}
|
||||
|
||||
this.$menu
|
||||
.on('click', $.proxy(this.click, this))
|
||||
.on('mouseenter', 'li', $.proxy(this.mouseenter, this))
|
||||
}
|
||||
|
||||
, keyup: function (e) {
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
|
||||
switch(e.keyCode) {
|
||||
case 40: // down arrow
|
||||
case 38: // up arrow
|
||||
break
|
||||
|
||||
case 9: // tab
|
||||
case 13: // enter
|
||||
if (!this.shown) return
|
||||
this.select()
|
||||
break
|
||||
|
||||
case 27: // escape
|
||||
this.hide()
|
||||
break
|
||||
|
||||
default:
|
||||
this.lookup()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
, keypress: function (e) {
|
||||
e.stopPropagation()
|
||||
if (!this.shown) return
|
||||
|
||||
switch(e.keyCode) {
|
||||
case 9: // tab
|
||||
case 13: // enter
|
||||
case 27: // escape
|
||||
e.preventDefault()
|
||||
break
|
||||
|
||||
case 38: // up arrow
|
||||
e.preventDefault()
|
||||
this.prev()
|
||||
break
|
||||
|
||||
case 40: // down arrow
|
||||
e.preventDefault()
|
||||
this.next()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
, blur: function (e) {
|
||||
var that = this
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
setTimeout(function () { that.hide() }, 150)
|
||||
}
|
||||
|
||||
, click: function (e) {
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
this.select()
|
||||
}
|
||||
|
||||
, mouseenter: function (e) {
|
||||
this.$menu.find('.active').removeClass('active')
|
||||
$(e.currentTarget).addClass('active')
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* TYPEAHEAD PLUGIN DEFINITION
|
||||
* =========================== */
|
||||
|
||||
$.fn.typeahead = function ( option ) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
, data = $this.data('typeahead')
|
||||
, options = typeof option == 'object' && option
|
||||
if (!data) $this.data('typeahead', (data = new Typeahead(this, options)))
|
||||
if (typeof option == 'string') data[option]()
|
||||
})
|
||||
}
|
||||
|
||||
$.fn.typeahead.defaults = {
|
||||
source: []
|
||||
, items: 8
|
||||
, menu: '<ul class="typeahead dropdown-menu"></ul>'
|
||||
, item: '<li><a href="#"></a></li>'
|
||||
}
|
||||
|
||||
$.fn.typeahead.Constructor = Typeahead
|
||||
|
||||
|
||||
/* TYPEAHEAD DATA-API
|
||||
* ================== */
|
||||
|
||||
$(function () {
|
||||
$('body').on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) {
|
||||
var $this = $(this)
|
||||
if ($this.data('typeahead')) return
|
||||
e.preventDefault()
|
||||
$this.typeahead($this.data())
|
||||
})
|
||||
})
|
||||
|
||||
}( window.jQuery )
|
||||
3
themes/default/js/libs/html5.js
Normal file
@ -0,0 +1,3 @@
|
||||
/*! HTML5 Shiv pre3.5 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
|
||||
Uncompressed source: https://github.com/aFarkas/html5shiv */
|
||||
(function(a,b){function h(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function i(){var a=l.elements;return typeof a=="string"?a.split(" "):a}function j(a){var b={},c=a.createElement,f=a.createDocumentFragment,g=f();a.createElement=function(a){l.shivMethods||c(a);var f;return b[a]?f=b[a].cloneNode():e.test(a)?f=(b[a]=c(a)).cloneNode():f=c(a),f.canHaveChildren&&!d.test(a)?g.appendChild(f):f},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+i().join().replace(/\w+/g,function(a){return b[a]=c(a),g.createElement(a),'c("'+a+'")'})+");return n}")(l,g)}function k(a){var b;return a.documentShived?a:(l.shivCSS&&!f&&(b=!!h(a,"article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio{display:none}canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden]{display:none}audio[controls]{display:inline-block;*display:inline;*zoom:1}mark{background:#FF0;color:#000}")),g||(b=!j(a)),b&&(a.documentShived=b),a)}function p(a){var b,c=a.getElementsByTagName("*"),d=c.length,e=RegExp("^(?:"+i().join("|")+")$","i"),f=[];while(d--)b=c[d],e.test(b.nodeName)&&f.push(b.applyElement(q(b)));return f}function q(a){var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(n+":"+a.nodeName);while(d--)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function r(a){var b,c=a.split("{"),d=c.length,e=RegExp("(^|[\\s,>+~])("+i().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),f="$1"+n+"\\:$2";while(d--)b=c[d]=c[d].split("}"),b[b.length-1]=b[b.length-1].replace(e,f),c[d]=b.join("}");return c.join("{")}function s(a){var b=a.length;while(b--)a[b].removeNode()}function t(a){var b,c,d=a.namespaces,e=a.parentWindow;return!o||a.printShived?a:(typeof d[n]=="undefined"&&d.add(n),e.attachEvent("onbeforeprint",function(){var d,e,f,g=a.styleSheets,i=[],j=g.length,k=Array(j);while(j--)k[j]=g[j];while(f=k.pop())if(!f.disabled&&m.test(f.media)){for(d=f.imports,j=0,e=d.length;j<e;j++)k.push(d[j]);try{i.push(f.cssText)}catch(l){}}i=r(i.reverse().join("")),c=p(a),b=h(a,i)}),e.attachEvent("onafterprint",function(){s(c),b.removeNode(!0)}),a.printShived=!0,a)}var c=a.html5||{},d=/^<|^(?:button|form|map|select|textarea|object|iframe)$/i,e=/^<|^(?:a|b|button|code|div|fieldset|form|h1|h2|h3|h4|h5|h6|i|iframe|img|input|label|li|link|ol|option|p|param|q|script|select|span|strong|style|table|tbody|td|textarea|tfoot|th|thead|tr|ul)$/i,f,g;(function(){var c=b.createElement("a");c.innerHTML="<xyz></xyz>",f="hidden"in c,f&&typeof injectElementWithStyles=="function"&&injectElementWithStyles("#modernizr{}",function(b){b.hidden=!0,f=(a.getComputedStyle?getComputedStyle(b,null):b.currentStyle).display=="none"}),g=c.childNodes.length==1||function(){try{b.createElement("a")}catch(a){return!0}var c=b.createDocumentFragment();return typeof c.cloneNode=="undefined"||typeof c.createDocumentFragment=="undefined"||typeof c.createElement=="undefined"}()})();var l={elements:c.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:c.shivCSS!==!1,shivMethods:c.shivMethods!==!1,type:"default",shivDocument:k};a.html5=l,k(b);var m=/^$|\b(?:all|print)\b/,n="html5shiv",o=!g&&function(){var c=b.documentElement;return typeof b.namespaces!="undefined"&&typeof b.parentWindow!="undefined"&&typeof c.applyElement!="undefined"&&typeof c.removeNode!="undefined"&&typeof a.attachEvent!="undefined"}();l.type+=" print",l.shivPrint=t,t(b)})(this,document)
|
||||
4
themes/default/js/libs/jquery-1.7.1.min.js
vendored
Normal file
11
themes/default/js/libs/modernizr-2.5.3-respond-1.1.0.min.js
vendored
Normal file
67
themes/default/js/menu.js
Normal file
@ -0,0 +1,67 @@
|
||||
function main_menu(items) {
|
||||
output = '<ul class="nav">'
|
||||
for (item in items) {
|
||||
i = items[item];
|
||||
|
||||
// Handle active page
|
||||
if (i["active"]) {
|
||||
active = ' class="active"';
|
||||
} else {
|
||||
active = '';
|
||||
}
|
||||
|
||||
// Line break labels
|
||||
/*label = i["label"];
|
||||
if (label.search(" ") != -1) {
|
||||
label = label.replace(" ", "<br />");
|
||||
} else {
|
||||
label = " <br />" + label;
|
||||
}*/
|
||||
|
||||
// Add icon before labels
|
||||
icon = '<i class="' + i["icon"] + ' icon-white nav-icon"></i>';
|
||||
label = icon + i["label"];
|
||||
|
||||
output = output +'<li' + active + '><a href="' + i["url"] + '"' + active + '>' + label + "</a></li>";
|
||||
}
|
||||
output = output + "</ul>";
|
||||
document.write(output);
|
||||
}
|
||||
|
||||
function render_items(items) {
|
||||
output = '<ul class="nav nav-list"><li class="nav-header">Menu</li>';
|
||||
for (item in items) {
|
||||
i = items[item];
|
||||
|
||||
// Handle active page
|
||||
if (i["active"]) {
|
||||
active = ' class="active"';
|
||||
|
||||
// Add icon before labels
|
||||
icon = '<i class="' + i["icon"] + ' icon-white sidenav-icon"></i>';
|
||||
label = icon + i["label"];
|
||||
} else {
|
||||
active = '';
|
||||
|
||||
// Add icon before labels
|
||||
icon = '<i class="' + i["icon"] + ' sidenav-icon"></i>';
|
||||
label = icon + i["label"];
|
||||
}
|
||||
|
||||
output = output +'<li' + active + '><a href="' + i["url"] + '"' + active + '>' + label + "</a></li>";
|
||||
|
||||
if (i['subs']) {
|
||||
output += render_items(i['subs']);
|
||||
}
|
||||
}
|
||||
output = output + "</ul>";
|
||||
return output
|
||||
}
|
||||
|
||||
function side_menu(items) {
|
||||
if (items.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
output = render_items(items);
|
||||
document.write(output);
|
||||
}
|
||||
34
themes/default/js/plugins.js
Normal file
@ -0,0 +1,34 @@
|
||||
// usage: log('inside coolFunc', this, arguments);
|
||||
// paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
|
||||
window.log = function f(){ log.history = log.history || []; log.history.push(arguments); if(this.console) { var args = arguments, newarr; args.callee = args.callee.caller; newarr = [].slice.call(args); if (typeof console.log === 'object') log.apply.call(console.log, console, newarr); else console.log.apply(console, newarr);}};
|
||||
|
||||
// make it safe to use console.log always
|
||||
(function(a){function b(){}for(var c="assert,count,debug,dir,dirxml,error,exception,group,groupCollapsed,groupEnd,info,log,markTimeline,profile,profileEnd,time,timeEnd,trace,warn".split(","),d;!!(d=c.pop());){a[d]=a[d]||b;}})
|
||||
(function(){try{console.log();return window.console;}catch(a){return (window.console={});}}());
|
||||
|
||||
|
||||
// place any jQuery/helper plugins in here, instead of separate, slower script files.
|
||||
|
||||
// remap jQuery to $
|
||||
(function($){})(window.jQuery);
|
||||
|
||||
|
||||
/* trigger when page is ready */
|
||||
$(document).ready(function (){
|
||||
|
||||
// your functions go here
|
||||
|
||||
});
|
||||
|
||||
|
||||
/* optional triggers
|
||||
|
||||
$(window).load(function() {
|
||||
|
||||
});
|
||||
|
||||
$(window).resize(function() {
|
||||
|
||||
});
|
||||
|
||||
*/
|
||||
@ -1,54 +0,0 @@
|
||||
function main_menu(items) {
|
||||
output = "<ul>"
|
||||
for (item in items) {
|
||||
i = items[item];
|
||||
|
||||
// Handle active page
|
||||
if (i["active"]) {
|
||||
active = 'class = "active"';
|
||||
} else {
|
||||
active = '';
|
||||
}
|
||||
|
||||
// Line break labels
|
||||
label = i["label"];
|
||||
if (label.search(" ") != -1) {
|
||||
label = label.replace(" ", "<br />");
|
||||
} else {
|
||||
label = " <br />" + label;
|
||||
}
|
||||
|
||||
output = output +'<li><a href="' + i["url"] + '" ' + active + '>' + label + "</a></li>";
|
||||
}
|
||||
output = output + "</ul>";
|
||||
document.write(output);
|
||||
}
|
||||
|
||||
function render_items(items) {
|
||||
output = "<ul>";
|
||||
for (item in items) {
|
||||
i = items[item];
|
||||
|
||||
// Handle active page
|
||||
if (i["active"]) {
|
||||
active = 'class = "active"';
|
||||
} else {
|
||||
active = '';
|
||||
}
|
||||
|
||||
output = output +'<li><a href="' + i["url"] + '" ' + active + '>' + i['label'] + "</a></li>";
|
||||
if (i['subs']) {
|
||||
output += render_items(i['subs']);
|
||||
}
|
||||
}
|
||||
output = output + "</ul>";
|
||||
return output
|
||||
}
|
||||
|
||||
function side_menu(items) {
|
||||
if (items.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
output = "<h2>Menu</h2>" + render_items(items);
|
||||
document.write(output);
|
||||
}
|
||||
12
themes/default/readme.md
Normal file
@ -0,0 +1,12 @@
|
||||
# Plinth HTML5 Bootstrap Theme by Sean "Diggity" O'Brien (https://github.com/seandiggity/Plinth)
|
||||
|
||||
## Summary:
|
||||
|
||||
This theme is free software offered to you under the terms of the GNU Affero General Public License, Version 3 or later:
|
||||
http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
It is based upon Twitter's Bootstrap (http://twitter.github.com/bootstrap) Bootstrap is licensed under the Apache License v2.0.
|
||||
Icons from Bootstrap originate from Glyphicons Free, licensed under Creative Commons Attribution 3.0.
|
||||
|
||||
Refer to the Plinth documentation for information about editing themes and templates.
|
||||
|
||||
BIN
themes/default/screenshot.png
Normal file
|
After Width: | Height: | Size: 116 KiB |
@ -1,328 +0,0 @@
|
||||
body {
|
||||
margin:0;
|
||||
padding:0;
|
||||
border:0; /* This removes the border around the viewport in old versions of IE */
|
||||
width:100%;
|
||||
background:#EEE;
|
||||
min-width:600px; /* Minimum width of layout - remove line if not required */
|
||||
/* The min-width property does not work in old versions of Internet Explorer */
|
||||
font-size:90%;
|
||||
font-family:Arial, Helvetica, sans-serif;
|
||||
}
|
||||
a {
|
||||
color:#3D8FE2;
|
||||
text-decoration:none;
|
||||
}
|
||||
a:hover {
|
||||
color:#fff;
|
||||
background:#3D8FE2;
|
||||
text-decoration:none;
|
||||
}
|
||||
h1, h2, h3 {
|
||||
margin:.8em 0 .2em 0;
|
||||
padding:0;
|
||||
}
|
||||
p {
|
||||
margin:.4em 0 .8em 0;
|
||||
padding:0;
|
||||
}
|
||||
img {
|
||||
margin:10px 0 5px;
|
||||
}
|
||||
#ads img {
|
||||
display:block;
|
||||
padding-top:10px;
|
||||
}
|
||||
|
||||
/* Header styles */
|
||||
#header {
|
||||
clear:both;
|
||||
float:left;
|
||||
width:100%;
|
||||
border-bottom:1px solid #000;
|
||||
}
|
||||
|
||||
#headerleft {
|
||||
float: left;
|
||||
padding-left: 1em;
|
||||
}
|
||||
#headerleft a { color:#1D6FE2; text-decoration:none; outline: none;}
|
||||
|
||||
#headerright {
|
||||
float:left;
|
||||
}
|
||||
#headerright p,
|
||||
#headerright h1,
|
||||
#headerright h2 {
|
||||
padding:.4em 15px 0 15px;
|
||||
margin:0;
|
||||
}
|
||||
|
||||
#headerright h1 a,
|
||||
#headerright h2 a {color:black; text-decoration:none; outline: none;}
|
||||
#headerright ul {
|
||||
clear:left;
|
||||
float:left;
|
||||
width:100%;
|
||||
list-style:none;
|
||||
margin:10px 0 0 0;
|
||||
padding:0;
|
||||
}
|
||||
#headerright ul li {
|
||||
display:inline;
|
||||
list-style:none;
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
#headerright ul li a {
|
||||
display:block;
|
||||
float:left;
|
||||
margin:0 0 0 1px;
|
||||
padding:3px 10px;
|
||||
text-align:center;
|
||||
background:#EEE;
|
||||
color:#000;
|
||||
text-decoration:none;
|
||||
position:relative;
|
||||
left:15px;
|
||||
line-height:1.3em;
|
||||
}
|
||||
#headerright ul li a:hover {
|
||||
background:lightblue;
|
||||
color:#fff;
|
||||
}
|
||||
#headerright ul li a.active,
|
||||
#headerright ul li a.active:hover {
|
||||
color:#fff;
|
||||
background:#000;
|
||||
font-weight:bold;
|
||||
text-decoration:none;
|
||||
}
|
||||
#headerright ul li a span {
|
||||
display:block;
|
||||
}
|
||||
|
||||
/* 'widths' sub menu */
|
||||
#layoutdims {
|
||||
clear:both;
|
||||
background:#eee;
|
||||
background:lightblue;
|
||||
border-top:4px solid #000;
|
||||
margin:0;
|
||||
padding:6px 15px !important;
|
||||
text-align:right;
|
||||
}
|
||||
/* column container */
|
||||
.colmask {
|
||||
position:relative; /* This fixes the IE7 overflow hidden bug */
|
||||
clear:both;
|
||||
float:left;
|
||||
width:100%; /* width of whole page */
|
||||
overflow:hidden; /* This chops off any overhanging divs */
|
||||
}
|
||||
/* common column settings */
|
||||
.colright,
|
||||
.colmid,
|
||||
.colleft {
|
||||
float:left;
|
||||
width:100%; /* width of page */
|
||||
position:relative;
|
||||
}
|
||||
.col1,
|
||||
.col2,
|
||||
.col3 {
|
||||
float:left;
|
||||
position:relative;
|
||||
padding:0 0em 1em 0; /* no left and right padding on columns, we just make them narrower instead
|
||||
only padding top and bottom is included here, make it whatever value you need */
|
||||
overflow:hidden;
|
||||
}
|
||||
|
||||
.col2 h2,
|
||||
.col3 h2 {color:black;
|
||||
font-weight:bold;
|
||||
font-size:100%;
|
||||
text-align:center;
|
||||
background:cornflowerblue;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 0.4em;}
|
||||
.col2 h3,
|
||||
.col3 h3 {color:black;
|
||||
font-weight:bold;
|
||||
font-size:100%;
|
||||
text-align:left;
|
||||
padding-top: 0em;
|
||||
margin-top: 0em;
|
||||
margin-bottom: 0em;}
|
||||
.col3 p {
|
||||
margin: 0.4em 0.5em .8em 0.5em;
|
||||
padding:0;
|
||||
}
|
||||
.col2 li {padding-bottom: 0.2em;}
|
||||
.col2 a {padding-left: 0.2em;}
|
||||
.col2 a.active,
|
||||
.col2 a.active:hover {
|
||||
color:#fff;
|
||||
background:#000;
|
||||
font-weight:bold;
|
||||
text-decoration:none;
|
||||
padding: 0.2em;
|
||||
}
|
||||
|
||||
/* 3 Column settings */
|
||||
.threecol {
|
||||
background:#eee; /* right column background colour */
|
||||
background:#EEE;
|
||||
}
|
||||
.threecol .colmid {
|
||||
right:25%; /* width of the right column */
|
||||
background:lightblue;
|
||||
}
|
||||
.threecol .colleft {
|
||||
right:50%; /* width of the middle column */
|
||||
background:#f4f4f4; /* left column background colour */
|
||||
background:#EEE;
|
||||
}
|
||||
.threecol .col1 {
|
||||
width:46%; /* width of center column content (column width minus padding on either side) */
|
||||
left:102%; /* 100% plus left padding of center column */
|
||||
}
|
||||
.threecol .col2 {
|
||||
width:21%; /* Width of left column content (column width minus padding on either side) */
|
||||
left:31%; /* width of (right column) plus (center column left and right padding) plus (left column left padding) */
|
||||
}
|
||||
.threecol .col3 {
|
||||
width:21%; /* Width of right column content (column width minus padding on either side) */
|
||||
|
||||
/* Note this used to be 85%, but I subtracted 1% for padding to pull stuff closer to the margin */
|
||||
left:84%; /* Please make note of the brackets here:
|
||||
(100% - left column width) plus (center column left and right padding) plus (left column left and right padding) plus (right column left padding) */
|
||||
}
|
||||
/* Footer styles */
|
||||
#footer {
|
||||
clear:both;
|
||||
float:left;
|
||||
width:100%;
|
||||
border-top:1px solid #000;
|
||||
padding: 1em;
|
||||
font-size:75%;
|
||||
background:lightblue;
|
||||
}
|
||||
#footer p {
|
||||
margin:0;
|
||||
}
|
||||
|
||||
/* Form Styles */
|
||||
form.form {
|
||||
margin:0 auto;
|
||||
width:100%;
|
||||
background:#EEE;
|
||||
position:relative;
|
||||
margin-top:2em;
|
||||
}
|
||||
|
||||
form.form h2 {
|
||||
color:#ffffff;
|
||||
font-size:1.2em;
|
||||
background:lightblue;
|
||||
text-transform:uppercase;
|
||||
padding:0.5em 0em 0.5em 0.5em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
form.form h3 {
|
||||
color:red;
|
||||
font-weight:bold;
|
||||
font-size:1em;
|
||||
padding:0.5em 0 0.5em 0.5em;
|
||||
text-align:center;
|
||||
background:#EEE;
|
||||
}
|
||||
|
||||
form.form .line,
|
||||
form.form p {
|
||||
width:94%;
|
||||
display: block;
|
||||
background:#EEE;
|
||||
padding:0.5em 0em 1em 1em;
|
||||
|
||||
padding-right:0.5em;
|
||||
margin-left:0.5em;
|
||||
background:#1D6FE2;
|
||||
margin-top: 0em;
|
||||
margin-bottom: 0em;
|
||||
}
|
||||
form.form label {
|
||||
width:100%;
|
||||
display: block;
|
||||
background:#EEE;
|
||||
padding:1em 0 0.5em 0em;
|
||||
}
|
||||
|
||||
form.form .submit {
|
||||
text-align:left;
|
||||
}
|
||||
|
||||
form.form .indent {
|
||||
padding: 0px;
|
||||
padding-left: 0.75em;
|
||||
}
|
||||
|
||||
form.form label span {
|
||||
display: block;
|
||||
color:black;
|
||||
font-size:12px;
|
||||
float:left;
|
||||
width:30%;
|
||||
text-align:right;
|
||||
padding:0.5em 2em 0 0;
|
||||
}
|
||||
|
||||
form.form .inputtext {
|
||||
padding:0.2em 0.3em 0.2em 0.3em;
|
||||
background:#1D6FE2;
|
||||
border-bottom: 1px double #171717;
|
||||
border-top: 1px double #171717;
|
||||
border-left:1px double #333333;
|
||||
border-right:1px double #333333;
|
||||
}
|
||||
|
||||
form.form .checkbox { text-align: left;}
|
||||
|
||||
form.form .inputtextnowidth {
|
||||
padding:0.5em 0.5em 0em 0em;
|
||||
background:#1D6FE2;
|
||||
border-bottom: 1px double #171717;
|
||||
border-top: 1px double #171717;
|
||||
border-left:1px double #333333;
|
||||
border-right:1px double #333333;
|
||||
}
|
||||
|
||||
form.form .textbox{
|
||||
padding:7px 7px;
|
||||
width:60%;
|
||||
background:#1D6FE2;
|
||||
border-bottom: 1px double #171717;
|
||||
border-top: 1px double #171717;
|
||||
border-left:1px double #333333;
|
||||
border-right:1px double #333333;
|
||||
overflow:hidden;
|
||||
height:150px;
|
||||
}
|
||||
|
||||
form.form .button
|
||||
{
|
||||
margin:0 0 10px 0;
|
||||
padding:4px 7px;
|
||||
background:lightblue;
|
||||
border:0px;
|
||||
position: relative;
|
||||
top:10px;
|
||||
width:100px;
|
||||
border-bottom: 1px double lightblue;
|
||||
border-top: 1px double cornflowerblue;
|
||||
border-left:1px double lightblue;
|
||||
border-right:1px double cornflowerblue;
|
||||
}
|
||||
|
||||
.err {color:red;}
|
||||
1
themes/default/style.css
Symbolic link
@ -0,0 +1 @@
|
||||
css/bootstrap.css
|
||||
4
util.py
@ -79,11 +79,11 @@ def page_template(template='base', **kwargs):
|
||||
kwargs['current_url'] = cherrypy.url()
|
||||
kwargs['username'] = cherrypy.session.get(cfg.session_key)
|
||||
|
||||
if not kwargs['nav']: kwargs['nav'] = """ <SCRIPT LANGUAGE="JavaScript">
|
||||
if not kwargs['nav']: kwargs['nav'] = """ <script type="text/javascript">
|
||||
<!--
|
||||
side_menu(sub_menu_items);
|
||||
// -->
|
||||
</SCRIPT>"""
|
||||
</script>"""
|
||||
|
||||
return str(template(searchList=[kwargs]))
|
||||
|
||||
|
||||