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
|
released under a "MIT/BSD/Python" license, as per [its blog
|
||||||
page](https://erezsh.wordpress.com/2009/05/31/filedict-bug-fixes-and-updates/).
|
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
|
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||||
Version 3, 29 June 2007
|
Version 3, 19 November 2007
|
||||||
|
|
||||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
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
|
Preamble
|
||||||
|
|
||||||
The GNU General Public License is a free, copyleft license for
|
The GNU Affero General Public License is a free, copyleft license for
|
||||||
software and other kinds of works.
|
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
|
The licenses for most software and other practical works are designed
|
||||||
to take away your freedom to share and change the works. By contrast,
|
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
|
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
|
software for all its users.
|
||||||
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.
|
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
When we speak of free software, we are referring to freedom, not
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
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
|
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.
|
free programs, and that you know you can do these things.
|
||||||
|
|
||||||
To protect your rights, we need to prevent others from denying you
|
Developers that use our General Public Licenses protect your rights
|
||||||
these rights or asking you to surrender the rights. Therefore, you have
|
with two steps: (1) assert copyright on the software, and (2) offer
|
||||||
certain responsibilities if you distribute copies of the software, or if
|
you this License which gives you legal permission to copy, distribute
|
||||||
you modify it: responsibilities to respect the freedom of others.
|
and/or modify the software.
|
||||||
|
|
||||||
For example, if you distribute copies of such a program, whether
|
A secondary benefit of defending all users' freedom is that
|
||||||
gratis or for a fee, you must pass on to the recipients the same
|
improvements made in alternate versions of the program, if they
|
||||||
freedoms that you received. You must make sure that they, too, receive
|
receive widespread use, become available for other developers to
|
||||||
or can get the source code. And you must show them these terms so they
|
incorporate. Many developers of free software are heartened and
|
||||||
know their rights.
|
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:
|
The GNU Affero General Public License is designed specifically to
|
||||||
(1) assert copyright on the software, and (2) offer you this License
|
ensure that, in such cases, the modified source code becomes available
|
||||||
giving you legal permission to copy, distribute and/or modify it.
|
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
|
An older license, called the Affero General Public License and
|
||||||
that there is no warranty for this free software. For both users' and
|
published by Affero, was designed to accomplish similar goals. This is
|
||||||
authors' sake, the GPL requires that modified versions be marked as
|
a different license, not a version of the Affero GPL, but Affero has
|
||||||
changed, so that their problems will not be attributed erroneously to
|
released a new version of the Affero GPL which permits relicensing under
|
||||||
authors of previous versions.
|
this license.
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
The precise terms and conditions for copying, distribution and
|
||||||
modification follow.
|
modification follow.
|
||||||
@ -96,7 +84,7 @@ modification follow.
|
|||||||
|
|
||||||
0. Definitions.
|
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
|
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||||
works, such as semiconductor masks.
|
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
|
the Program, the only way you could satisfy both those terms and this
|
||||||
License would be to refrain entirely from conveying the Program.
|
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
|
Notwithstanding any other provision of this License, you have
|
||||||
permission to link or combine any covered work with a work licensed
|
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
|
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,
|
License will continue to apply to the part which is the covered work,
|
||||||
but the special requirements of the GNU Affero General Public License,
|
but the work with which it is combined will remain governed by version
|
||||||
section 13, concerning interaction through a network will apply to the
|
3 of the GNU General Public License.
|
||||||
combination as such.
|
|
||||||
|
|
||||||
14. Revised Versions of this License.
|
14. Revised Versions of this License.
|
||||||
|
|
||||||
The Free Software Foundation may publish revised and/or new versions of
|
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
|
the GNU Affero General Public License from time to time. Such new versions
|
||||||
be similar in spirit to the present version, but may differ in detail to
|
will be similar in spirit to the present version, but may differ in detail to
|
||||||
address new problems or concerns.
|
address new problems or concerns.
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the
|
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
|
Public License "or any later version" applies to it, you have the
|
||||||
option of following the terms and conditions either of that numbered
|
option of following the terms and conditions either of that numbered
|
||||||
version or of any later version published by the Free Software
|
version or of any later version published by the Free Software
|
||||||
Foundation. If the Program does not specify a version number of the
|
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.
|
by the Free Software Foundation.
|
||||||
|
|
||||||
If the Program specifies that a proxy can decide which future
|
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
|
public statement of acceptance of a version permanently authorizes you
|
||||||
to choose that version for the Program.
|
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>
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
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/>.
|
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.
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
If the program does terminal interaction, make it output a short
|
If your software can interact with users remotely through a computer
|
||||||
notice like this when it starts in an interactive mode:
|
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
|
||||||
<program> Copyright (C) <year> <name of author>
|
interface could display a "Source" link that leads users to an archive
|
||||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
of the code. There are many ways you could offer source, and different
|
||||||
This is free software, and you are welcome to redistribute it
|
solutions will be better for different programs; see section 13 for the
|
||||||
under certain conditions; type `show c' for details.
|
specific requirements.
|
||||||
|
|
||||||
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".
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or school,
|
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.
|
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/>.
|
<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
|
## Creative Commons Attribution-ShareAlike 3.0 Unported
|
||||||
|
|
||||||
License
|
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"
|
product_name = "Plinth"
|
||||||
box_name = "Freedom Plug"
|
box_name = "FreedomBox"
|
||||||
|
|
||||||
port = 8000
|
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():
|
class Menu():
|
||||||
"""One menu item."""
|
"""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.
|
"""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
|
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.
|
order is the numerical rank of this item within the menu.
|
||||||
Lower order items appear closest to the top/left of the menu.
|
Lower order items appear closest to the top/left of the menu.
|
||||||
@ -20,8 +24,9 @@ class Menu():
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
self.label = label
|
self.label = label
|
||||||
self.order = order
|
self.icon = icon
|
||||||
self.url = url
|
self.url = url
|
||||||
|
self.order = order
|
||||||
self.items = []
|
self.items = []
|
||||||
|
|
||||||
def sort_items(self):
|
def sort_items(self):
|
||||||
@ -36,7 +41,7 @@ class Menu():
|
|||||||
if basehref and url.startswith("/"):
|
if basehref and url.startswith("/"):
|
||||||
url = cfg.base_href + url
|
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.items.append(item)
|
||||||
self.sort_items()
|
self.sort_items()
|
||||||
return item
|
return item
|
||||||
@ -61,7 +66,7 @@ class Menu():
|
|||||||
|
|
||||||
so = []
|
so = []
|
||||||
for item in self.items:
|
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():
|
if item.active_p():
|
||||||
i['active']=True
|
i['active']=True
|
||||||
if item.items and render_subs:
|
if item.items and render_subs:
|
||||||
@ -74,7 +79,7 @@ class Menu():
|
|||||||
|
|
||||||
if render_subs is True, we render submenus too"""
|
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
|
#+ 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"+ 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):
|
def __init__(self, *args, **kwargs):
|
||||||
PagePlugin.__init__(self, *args, **kwargs)
|
PagePlugin.__init__(self, *args, **kwargs)
|
||||||
self.register_page("apps")
|
self.register_page("apps")
|
||||||
self.menu = cfg.main_menu.add_item("User Apps", "/apps", 80)
|
self.menu = cfg.main_menu.add_item("Apps", "icon-download-alt", "/apps", 80)
|
||||||
self.menu.add_item("Photo Gallery", "/apps/photos", 35)
|
self.menu.add_item("Photo Gallery", "icon-picture", "/apps/photos", 35)
|
||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
def index(self):
|
def index(self):
|
||||||
@ -27,7 +27,7 @@ class Apps(PagePlugin):
|
|||||||
@require()
|
@require()
|
||||||
def photos(self):
|
def photos(self):
|
||||||
return self.fill_template(title="Open ID", main='', sidebar_right="""
|
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
|
digital property you have, so why trust it to companies that have no
|
||||||
investment in the sentimental value of your family snaps? Keep those
|
investment in the sentimental value of your family snaps? Keep those
|
||||||
photos local, backed up, easily accessed and free from the whims of
|
photos local, backed up, easily accessed and free from the whims of
|
||||||
|
|||||||
@ -8,12 +8,12 @@ class Help(PagePlugin):
|
|||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
PagePlugin.__init__(self, *args, **kwargs)
|
PagePlugin.__init__(self, *args, **kwargs)
|
||||||
self.register_page("help")
|
self.register_page("help")
|
||||||
self.menu = cfg.main_menu.add_item(_("Documentation and FAQ"), "/help", 101)
|
self.menu = cfg.main_menu.add_item(_("Documentation"), "icon-book", "/help", 101)
|
||||||
self.menu.add_item(_("Where to Get Help"), "/help/index", 5)
|
self.menu.add_item(_("Where to Get Help"), "icon-search", "/help/index", 5)
|
||||||
self.menu.add_item(_("Developer's Manual"), "/help/view/plinth", 10)
|
self.menu.add_item(_("Developer's Manual"), "icon-info-sign", "/help/view/plinth", 10)
|
||||||
self.menu.add_item(_("FAQ"), "/help/view/faq", 20)
|
self.menu.add_item(_("FAQ"), "icon-question-sign", "/help/view/faq", 20)
|
||||||
self.menu.add_item(_("%s Wiki" % cfg.box_name), "http://wiki.debian.org/FreedomBox", 30)
|
self.menu.add_item(_("%s Wiki" % cfg.box_name), "icon-pencil", "http://wiki.debian.org/FreedomBox", 30)
|
||||||
self.menu.add_item(_("About"), "/help/about", 100)
|
self.menu.add_item(_("About"), "icon-star", "/help/about", 100)
|
||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
def index(self):
|
def index(self):
|
||||||
@ -27,7 +27,7 @@ class Help(PagePlugin):
|
|||||||
offer suggestions, edits, and screenshots for completing
|
offer suggestions, edits, and screenshots for completing
|
||||||
it!</p>
|
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
|
the Debian wiki</a> is devoted to the %(box)s. At some
|
||||||
point the documentation in the wiki and the documentation in
|
point the documentation in the wiki and the documentation in
|
||||||
the manual should dovetail.</p>
|
the manual should dovetail.</p>
|
||||||
@ -48,8 +48,9 @@ class Help(PagePlugin):
|
|||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
def about(self):
|
def about(self):
|
||||||
return self.fill_template(title=_("About the %s" % cfg.box_name), main="""
|
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
|
<img src="/static/theme/img/freedombox-logo-250px.png" class="main-graphic" />
|
||||||
mediated by organizations that often do not have our best
|
<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
|
interests at heart. By building software that does not rely on
|
||||||
a central service, we can regain control and privacy. By
|
a central service, we can regain control and privacy. By
|
||||||
keeping our data in our homes, we gain useful legal
|
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
|
runs on must be cheap. The software it runs on must be easy to
|
||||||
install and administrate by anybody. It must be easy to
|
install and administrate by anybody. It must be easy to
|
||||||
transition from existing services.</p>
|
transition from existing services.</p>
|
||||||
|
<p><a class="btn btn-primary btn-large" href="http://wiki.debian.org/FreedomBox" target="_blank">Learn more »</a></p>""",
|
||||||
<p>There are a number of projects working to realize a future
|
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
|
of distributed services; we aim to bring them all together in
|
||||||
a convenient package.</p>
|
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
|
<a href="http://wiki.debian.org/FreedomBox">Debian
|
||||||
Wiki</a>.</p>""")
|
Wiki</a>.</p>
|
||||||
|
"""))
|
||||||
|
|
||||||
class View(PagePlugin):
|
class View(PagePlugin):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
|||||||
@ -50,9 +50,9 @@ class Form():
|
|||||||
quad = [0,0,0,0]
|
quad = [0,0,0,0]
|
||||||
self.text += """ <label>
|
self.text += """ <label>
|
||||||
<span>%(label)s</span>
|
<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)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"/><b>.</b>
|
<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"/><b>.</b>
|
<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"/>
|
<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]}
|
</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 += """
|
self.text += """
|
||||||
<div class="submit">
|
<div class="submit">
|
||||||
<label><span></span>
|
<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)
|
</label></div>\n""" % (label, name, id)
|
||||||
def submit_row(self, buttons):
|
def submit_row(self, buttons):
|
||||||
"""buttons is a list of tuples, each containing label, name, id. Name and id are optional."""
|
"""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 != '':
|
if button_text != '':
|
||||||
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
|
self.text += '%s</div></label>' % button_text
|
||||||
def name_or_id(self, name, id):
|
def name_or_id(self, name, id):
|
||||||
if not name: name = id
|
if not name: name = id
|
||||||
|
|||||||
@ -9,11 +9,11 @@ class Privacy(PagePlugin):
|
|||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
PagePlugin.__init__(self, *args, **kwargs)
|
PagePlugin.__init__(self, *args, **kwargs)
|
||||||
self.register_page("privacy")
|
self.register_page("privacy")
|
||||||
self.menu = cfg.main_menu.add_item("Privacy Controls", "/privacy", 12)
|
self.menu = cfg.main_menu.add_item("Privacy", "icon-eye-open", "/privacy", 12)
|
||||||
self.menu.add_item("General Config", "/privacy/config", 10)
|
self.menu.add_item("General Config", "icon-asterisk", "/privacy/config", 10)
|
||||||
self.menu.add_item("Ad Blocking", "/privacy/adblock", 20)
|
self.menu.add_item("Ad Blocking", "icon-ban-circle", "/privacy/adblock", 20)
|
||||||
self.menu.add_item("TOR", "/privacy/TOR", 30)
|
self.menu.add_item("TOR", "icon-eye-close", "/privacy/TOR", 30)
|
||||||
self.menu.add_item("HTTPS Everywhere", "/privacy/https_everywhere", 30)
|
self.menu.add_item("HTTPS Everywhere", "icon-lock", "/privacy/https_everywhere", 30)
|
||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
def index(self):
|
def index(self):
|
||||||
@ -29,7 +29,7 @@ class Privacy(PagePlugin):
|
|||||||
is a founding consideration, not an afterthought.</p>
|
is a founding consideration, not an afterthought.</p>
|
||||||
"""
|
"""
|
||||||
return self.fill_template(title=_("Privacy Control Panel"), main=main,
|
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
|
privacy is important, it's not just an empty pleasantry. We really
|
||||||
mean it. Your privacy control panel should give you fine-grained
|
mean it. Your privacy control panel should give you fine-grained
|
||||||
control over exactly who can access your %s and the
|
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
|
<p>Your personal information should not leave this box without your
|
||||||
knowledge and direction. And if companies or government wants this
|
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>
|
change to refuse and also tells you who wants your data.</p>
|
||||||
""") % cfg.product_name)
|
""") % cfg.product_name)
|
||||||
|
|||||||
@ -14,5 +14,5 @@ class Info(PagePlugin):
|
|||||||
@require()
|
@require()
|
||||||
def index(self):
|
def index(self):
|
||||||
return self.fill_template(title="Router Information", main="""
|
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
|
order = 9 # order of running init in PagePlugins
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.register_page("router")
|
self.register_page("router")
|
||||||
self.menu = cfg.main_menu.add_item("Router Admin", "/router", 10)
|
self.menu = cfg.main_menu.add_item("Router", "icon-retweet", "/router", 10)
|
||||||
self.menu.add_item("Wireless", "/router/wireless", 12)
|
self.menu.add_item("Wireless", "icon-signal", "/router/wireless", 12)
|
||||||
self.menu.add_item("Firewall", "/router/firewall", 18)
|
self.menu.add_item("Firewall", "icon-fire", "/router/firewall", 18)
|
||||||
self.menu.add_item("Hotspot and Mesh", "/router/hotspot")
|
self.menu.add_item("Hotspot and Mesh", "icon-map-marker", "/router/hotspot")
|
||||||
self.menu.add_item("Info", "/router/info", 100)
|
self.menu.add_item("Info", "icon-list-alt", "/router/info", 100)
|
||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
def index(self):
|
def index(self):
|
||||||
@ -45,16 +45,16 @@ class router(PagePlugin):
|
|||||||
class setup(PagePlugin):
|
class setup(PagePlugin):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.register_page("router.setup")
|
self.register_page("router.setup")
|
||||||
self.menu = cfg.html_root.router.menu.add_item("General Setup", "/router/setup", 10)
|
self.menu = cfg.html_root.router.menu.add_item("General Setup", "icon-cog", "/router/setup", 10)
|
||||||
self.menu.add_item("Dynamic DNS", "/router/setup/ddns", 20)
|
self.menu.add_item("Dynamic DNS", "icon-flag", "/router/setup/ddns", 20)
|
||||||
self.menu.add_item("MAC Address Clone", "/router/setup/mac_address", 30)
|
self.menu.add_item("MAC Address Clone", "icon-barcode", "/router/setup/mac_address", 30)
|
||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
@require()
|
@require()
|
||||||
def index(self):
|
def index(self):
|
||||||
parts = self.forms('/router/setup')
|
parts = self.forms('/router/setup')
|
||||||
parts['title'] = "General 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
|
wireless router. By default, it should do everything your usual
|
||||||
router does. With the addition of some extra modules, its abilities
|
router does. With the addition of some extra modules, its abilities
|
||||||
can rival those of high-end routers costing hundreds of dollars.</p>
|
can rival those of high-end routers costing hundreds of dollars.</p>
|
||||||
@ -88,7 +88,7 @@ class wan(FormPlugin, PagePlugin):
|
|||||||
url = ["/router/setup"]
|
url = ["/router/setup"]
|
||||||
order = 10
|
order = 10
|
||||||
|
|
||||||
js = """<script LANGUAGE="JavaScript">
|
js = """<script type="text/javascript">
|
||||||
<!--
|
<!--
|
||||||
function hideshow_static() {
|
function hideshow_static() {
|
||||||
var d = document.getElementById('connect_type');
|
var d = document.getElementById('connect_type');
|
||||||
@ -105,7 +105,7 @@ class wan(FormPlugin, PagePlugin):
|
|||||||
def sidebar_right(self, *args, **kwargs):
|
def sidebar_right(self, *args, **kwargs):
|
||||||
side=''
|
side=''
|
||||||
if cfg.users.expert():
|
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
|
<h3>DHCP</h3><p>DHCP allows your router to automatically
|
||||||
connect with the upstream network. If you are unsure what
|
connect with the upstream network. If you are unsure what
|
||||||
option to choose, stick with DHCP. It is usually
|
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 2", name="dns2", quad=[dns20, dns21, dns22, dns23])
|
||||||
form.dotted_quad("Static DNS 3", name="dns3", quad=[dns30, dns31, dns32, dns33])
|
form.dotted_quad("Static DNS 3", name="dns3", quad=[dns30, dns31, dns32, dns33])
|
||||||
form.html('</div>')
|
form.html('</div>')
|
||||||
form.html(""" <script LANGUAGE="JavaScript">
|
form.html(""" <script type="text/javascript">
|
||||||
<!--
|
<!--
|
||||||
hideshow_static();
|
hideshow_static();
|
||||||
// -->
|
// -->
|
||||||
|
|||||||
@ -114,7 +114,7 @@ class Santiago(PagePlugin):
|
|||||||
class santiago(PagePlugin):
|
class santiago(PagePlugin):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
PagePlugin.__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")
|
self.register_page("privacy.santiago")
|
||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
|
|||||||
@ -8,8 +8,8 @@ class Services(PagePlugin):
|
|||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
PagePlugin.__init__(self, *args, **kwargs)
|
PagePlugin.__init__(self, *args, **kwargs)
|
||||||
self.register_page("services")
|
self.register_page("services")
|
||||||
self.menu = cfg.main_menu.add_item("Other Services", "/services", 90)
|
self.menu = cfg.main_menu.add_item("Services", "icon-list", "/services", 90)
|
||||||
self.menu.add_item("Open ID", "/services/openid", 35)
|
self.menu.add_item("Open ID", "icon-user", "/services/openid", 35)
|
||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
def index(self):
|
def index(self):
|
||||||
@ -19,7 +19,7 @@ class Services(PagePlugin):
|
|||||||
@require()
|
@require()
|
||||||
def openid(self):
|
def openid(self):
|
||||||
return self.fill_template(title="Open ID", main='', sidebar_right="""
|
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
|
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
|
websites without the need to remember or enter a separate username and
|
||||||
password at each one.</p>
|
password at each one.</p>
|
||||||
|
|||||||
@ -7,7 +7,7 @@ class FileExplorer(PagePlugin):
|
|||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
PagePlugin.__init__(self, *args, **kwargs)
|
PagePlugin.__init__(self, *args, **kwargs)
|
||||||
self.register_page("sharing.explorer")
|
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
|
@cherrypy.expose
|
||||||
@require()
|
@require()
|
||||||
|
|||||||
@ -10,8 +10,8 @@ class Sharing(PagePlugin):
|
|||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
PagePlugin.__init__(self, *args, **kwargs)
|
PagePlugin.__init__(self, *args, **kwargs)
|
||||||
self.register_page("sharing")
|
self.register_page("sharing")
|
||||||
self.menu = cfg.main_menu.add_item("Resource Sharing", "/sharing", 35)
|
self.menu = cfg.main_menu.add_item("Sharing", "icon-share-alt", "/sharing", 35)
|
||||||
self.menu.add_item("File Server", "/sharing/files", 10)
|
self.menu.add_item("File Server", "icon-inbox", "/sharing/files", 10)
|
||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
def index(self):
|
def index(self):
|
||||||
@ -25,7 +25,7 @@ class Sharing(PagePlugin):
|
|||||||
@require()
|
@require()
|
||||||
def files(self):
|
def files(self):
|
||||||
return self.fill_template(title="File Server", main='', sidebar_right=_("""
|
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
|
local network, thus acting as a NAS server. We currently support
|
||||||
sharing files via NFS and SMB.
|
sharing files via NFS and SMB.
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ class PrinterSharing(PagePlugin):
|
|||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
PagePlugin.__init__(self, *args, **kwargs)
|
PagePlugin.__init__(self, *args, **kwargs)
|
||||||
self.register_page("sharing.printer")
|
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
|
@cherrypy.expose
|
||||||
@require()
|
@require()
|
||||||
@ -47,7 +47,7 @@ class PrinterSharing(PagePlugin):
|
|||||||
<p>TODO: Setup and install CUPS</p>
|
<p>TODO: Setup and install CUPS</p>
|
||||||
"""
|
"""
|
||||||
return self.fill_template(title="Printer Sharing", main=main, sidebar_right="""
|
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)
|
""" % cfg.box_name)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -64,7 +64,7 @@ class general(FormPlugin, PagePlugin):
|
|||||||
## only expert users are going to get deep enough to see any timestamps
|
## only expert users are going to get deep enough to see any timestamps
|
||||||
if not cfg.users.expert():
|
if not cfg.users.expert():
|
||||||
return ''
|
return ''
|
||||||
return _(#"""<h2>Time Zone</h2>
|
return _(#"""<strong>Time Zone</strong>
|
||||||
"""<p>Set your timezone to get accurate
|
"""<p>Set your timezone to get accurate
|
||||||
timestamps. %(product)s will use this information to set your
|
timestamps. %(product)s will use this information to set your
|
||||||
%(box)s's systemwide timezone.</p>
|
%(box)s's systemwide timezone.</p>
|
||||||
|
|||||||
@ -15,7 +15,7 @@ class experts(FormPlugin, PagePlugin):
|
|||||||
order = 10
|
order = 10
|
||||||
|
|
||||||
def help(self, *args, **kwargs):
|
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'
|
<p>The %(box)s can be administered in two modes, 'basic'
|
||||||
and 'expert'. Basic mode hides a lot of features and
|
and 'expert'. Basic mode hides a lot of features and
|
||||||
|
|||||||
@ -18,10 +18,10 @@ class Sys(PagePlugin):
|
|||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
PagePlugin.__init__(self, *args, **kwargs)
|
PagePlugin.__init__(self, *args, **kwargs)
|
||||||
self.register_page("sys")
|
self.register_page("sys")
|
||||||
self.menu = cfg.main_menu.add_item(_("%s System" % cfg.product_name), "/sys", 100)
|
self.menu = cfg.main_menu.add_item(_("System"), "icon-cog", "/sys", 100)
|
||||||
self.menu.add_item(_("Configure"), "/sys/config", 10)
|
self.menu.add_item(_("Configure"), "icon-cog", "/sys/config", 10)
|
||||||
self.menu.add_item(_("Package Manager"), "/sys/packages", 20)
|
self.menu.add_item(_("Package Manager"), "icon-gift", "/sys/packages", 20)
|
||||||
self.menu.add_item(_("Users and Groups"), "/sys/users", 15)
|
self.menu.add_item(_("Users and Groups"), "icon-user", "/sys/users", 15)
|
||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
def index(self):
|
def index(self):
|
||||||
@ -37,7 +37,7 @@ class Sys(PagePlugin):
|
|||||||
@require()
|
@require()
|
||||||
def packages(self):
|
def packages(self):
|
||||||
side=_("""
|
side=_("""
|
||||||
<h2>Help</h2>
|
<strong>Help</strong>
|
||||||
<p>On this page, you can add or remove %s plugins to your %s.</p>
|
<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>
|
<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))
|
""" % (cfg.product_name, cfg.box_name))
|
||||||
|
|||||||
@ -24,8 +24,8 @@ class add(FormPlugin, PagePlugin):
|
|||||||
order = 30
|
order = 30
|
||||||
|
|
||||||
sidebar_left = ''
|
sidebar_left = ''
|
||||||
sidebar_right = _("""<h2>Add User</h2><p>Adding a user via this
|
sidebar_right = _("""<strong>Add User</strong><p>Adding a user via this
|
||||||
administrative interface <b>might</b> create a system user.
|
administrative interface <strong>might</strong> create a system user.
|
||||||
For example, if you provide a user with ssh access, she will
|
For example, if you provide a user with ssh access, she will
|
||||||
need a system account. If you don't know what that means,
|
need a system account. If you don't know what that means,
|
||||||
don't worry about it.</p>""")
|
don't worry about it.</p>""")
|
||||||
@ -70,16 +70,16 @@ class edit(FormPlugin, PagePlugin):
|
|||||||
order = 35
|
order = 35
|
||||||
|
|
||||||
sidebar_left = ''
|
sidebar_left = ''
|
||||||
sidebar_right = _("""<h2>Edit Users</h2><p>Click on a user's name to
|
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><h2>Delete
|
go to a screen for editing that user's account.</p><strong>Delete
|
||||||
Users</h2><p>Check the box next to a users' names and then click
|
Users</strong><p>Check the box next to a users' names and then click
|
||||||
"Delete User" to remove users from %s and the %s
|
"Delete User" to remove users from %s and the %s
|
||||||
system.</p><p>Deleting users is permanent!</p>""" % (cfg.product_name, cfg.box_name))
|
system.</p><p>Deleting users is permanent!</p>""" % (cfg.product_name, cfg.box_name))
|
||||||
|
|
||||||
def main(self, msg=''):
|
def main(self, msg=''):
|
||||||
users = cfg.users.keys()
|
users = cfg.users.keys()
|
||||||
add_form = Form(title=_("Edit or Delete User"), action="/sys/users/edit", message=msg)
|
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()):
|
for uname in sorted(users.keys()):
|
||||||
add_form.html('<span class="indent"> %s ' %
|
add_form.html('<span class="indent"> %s ' %
|
||||||
add_form.get_checkbox(name=uname) +
|
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,
|
return self.fill_template(template="err", title=_("Unnown User"), main=main,
|
||||||
sidebar_left=self.sidebar_left, sidebar_right=sidebar_right)
|
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 = ''
|
sidebar_right = ''
|
||||||
return self.fill_template(title="", main=main, sidebar_left=self.sidebar_left, sidebar_right=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
|
end will be reachable from the WAN. If your %(box)s
|
||||||
connects you to the internet, that means you'll be able to log
|
connects you to the internet, that means you'll be able to log
|
||||||
in to the front end from the internet. This might be
|
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
|
enable attackers to gain access to your %(box)s from the
|
||||||
outside world. All they'll need is your username and
|
outside world. All they'll need is your username and
|
||||||
passphrase, which they might guess or they might simply try
|
passphrase, which they might guess or they might simply try
|
||||||
every posible combination of letters and numbers until they
|
every posible combination of letters and numbers until they
|
||||||
get in. If you enable the WAN administration option, you
|
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
|
<p>For security reasons, neither WAN Administration nor WAN
|
||||||
SSH is available to the `admin` user account.</p>
|
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.")
|
cfg.log.error("500 Internal Server Error. Trackback is above.")
|
||||||
more="""<p>This is an internal error and not something you caused
|
more="""<p>This is an internal error and not something you caused
|
||||||
or can fix. Please report the error on the <a
|
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>"""
|
we can fix it.</p>"""
|
||||||
return error_page(status, message, "<p>%s</p><pre>%s</pre>" % (more, "\n".join(traceback.split("\n"))))
|
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)
|
cfg.log("skipping %s" % name)
|
||||||
|
|
||||||
def parse_arguments():
|
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="",
|
parser.add_argument('--pidfile', default="",
|
||||||
help='specify a file in which the server may write its pid')
|
help='specify a file in which the server may write its pid')
|
||||||
args=parser.parse_args()
|
args=parser.parse_args()
|
||||||
|
|||||||
@ -5,27 +5,105 @@
|
|||||||
$default
|
$default
|
||||||
#end if
|
#end if
|
||||||
#end def
|
#end def
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
<!doctype html>
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-GB">
|
<!--[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>
|
<head>
|
||||||
<title>$default($title, "Plinth Front End to the Freedom Box")
|
<meta charset="utf-8" />
|
||||||
</title>
|
|
||||||
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
|
<!-- Always force latest IE rendering engine and Chrome Frame -->
|
||||||
<meta name="description" content="Plint admin frontend for Freedom Box" />
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||||
<meta name="robots" content="noindex, nofollow" />
|
|
||||||
<link rel="shortcut icon" href="$basehref/favicon.ico" type="image/x-icon" />
|
<!-- Mobile Viewport Fix http://j.mp/mobileviewport & http://davidbcalhoun.com/2010/viewport-metatag
|
||||||
<link rel="stylesheet" type="text/css" href="$basehref/static/theme/style.tiny.css" media="screen" />
|
device-width : Occupy full width of the screen in its current orientation
|
||||||
$css
|
initial-scale = 1.0 retains dimensions instead of zooming out if page height > device height
|
||||||
<script type="text/javascript" src="$basehref/static/theme/menu.js"></script>
|
maximum-scale = 1.0 retains dimensions instead of zooming in if page width < device width
|
||||||
<script type="text/javascript" src="$basehref/static/theme/plinth.js"></script>
|
-->
|
||||||
$js
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
$main_menu_js
|
|
||||||
$sub_menu_js
|
<!-- R2D2, you know better than to trust a strange computer! -->
|
||||||
<script LANGUAGE="JavaScript">
|
<meta name="robots" content="noindex, nofollow, noarchive" />
|
||||||
<!--
|
<meta name="googlebot" content="noindex, nofollow, noarchive, nosnippet, noodp, noimageindex, notranslate" />
|
||||||
$onload
|
<meta name="msnbot" content="noindex, nofollow, noarchive, noodp" />
|
||||||
// -->
|
<meta name="slurp" content="noindex, nofollow, noarchive, noodp, noydir" />
|
||||||
</script>
|
|
||||||
|
<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>
|
</head>
|
||||||
<body onLoad="javascript:onload_handler();">
|
<body onLoad="javascript:onload_handler();">
|
||||||
<div id="header">
|
<div id="header">
|
||||||
@ -47,66 +125,110 @@
|
|||||||
#else
|
#else
|
||||||
<p id="layoutdims">Not logged in. <a href="$basehref/auth/login" title="Log in">Log in.</a></p>
|
<p id="layoutdims">Not logged in. <a href="$basehref/auth/login" title="Log in">Log in.</a></p>
|
||||||
#end if
|
#end if
|
||||||
|
<div class="navbar navbar-fixed-top">
|
||||||
</div>
|
<div class="navbar-inner">
|
||||||
<div class="colmask threecol">
|
<div class="container-fluid">
|
||||||
<div class="colmid">
|
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||||
<div class="colleft">
|
<span class="icon-bar"></span>
|
||||||
<div class="col1">
|
<span class="icon-bar"></span>
|
||||||
<!-- Column 1 start -->
|
<span class="icon-bar"></span>
|
||||||
<h2>
|
</a>
|
||||||
#block title_block
|
<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>
|
||||||
$title
|
<div class="nav-collapse">
|
||||||
#end block title_block
|
<script type="text/javascript">
|
||||||
</h2>
|
<!--
|
||||||
#block main_block
|
main_menu(main_menu_items);
|
||||||
$main
|
// -->
|
||||||
#end block main_block
|
</script>
|
||||||
<!-- Column 1 end -->
|
#if $username
|
||||||
</div>
|
<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>
|
||||||
<div class="col2">
|
#else
|
||||||
<!-- Column 2 start -->
|
<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>
|
||||||
#block nav_block
|
#end if
|
||||||
$nav
|
</div><!--/.nav-collapse -->
|
||||||
#end block nav_block
|
</div>
|
||||||
#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>
|
</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>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#extends templates.two_col
|
#extends templates.two_col
|
||||||
|
|
||||||
#def title_block
|
#def title_block
|
||||||
<span class="err">Error: $title</span>
|
<span class="label label-important error-large">Error: $title</span>
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
#end def
|
#end def
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
#extends templates.base
|
#extends templates.base
|
||||||
|
|
||||||
#def css
|
#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
|
#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['current_url'] = cherrypy.url()
|
||||||
kwargs['username'] = cherrypy.session.get(cfg.session_key)
|
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);
|
side_menu(sub_menu_items);
|
||||||
// -->
|
// -->
|
||||||
</SCRIPT>"""
|
</script>"""
|
||||||
|
|
||||||
return str(template(searchList=[kwargs]))
|
return str(template(searchList=[kwargs]))
|
||||||
|
|
||||||
|
|||||||